{"id":11134,"date":"2024-05-29T12:42:05","date_gmt":"2024-05-29T12:42:05","guid":{"rendered":"https:\/\/https:\/\/africaresearchconnects.com\/decouvrez\/"},"modified":"2026-09-15T09:30:35","modified_gmt":"2026-09-15T09:30:35","slug":"decouvrez","status":"publish","type":"page","link":"https:\/\/africaresearchconnects.com\/fr\/decouvrez\/","title":{"rendered":"D\u00e9couvrez"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"11134\" class=\"elementor elementor-11134 elementor-9555\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b44f1bb e-flex e-con-boxed e-con e-parent\" data-id=\"b44f1bb\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t<div class=\"elementor-element elementor-element-9c1e958 e-flex e-con-boxed e-con e-child\" data-id=\"9c1e958\" data-element_type=\"container\" data-e-type=\"container\">\n\t\t\t\t\t<div class=\"e-con-inner\">\n\t\t\t\t<div class=\"elementor-element elementor-element-d67b227 elementor-widget__width-inherit elementor-widget elementor-widget-shortcode\" data-id=\"d67b227\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"shortcode.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t\t\t<div class=\"elementor-shortcode\">\r\n<script>\r\nconst PROFILES_AUTHOR_ENABLED      = false;\r\nconst PROFILES_INSTITUTION_ENABLED = false;\r\nconst PROFILES_SPONSOR_ENABLED     = false;\r\n<\/script>\r\n\r\n<style>\r\n\/* \u2550\u2550\u2550 Discover page \u2014 modernized \u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 *\/\r\n\r\n\/* Brand palette (per project memory: primary #0a3d47, accent #79ba3a) *\/\r\n:root {\r\n\t--arc-primary:      #0a3d47;\r\n\t--arc-primary-alt:  #0d5561;\r\n\t--arc-accent:       #79ba3a;\r\n\t--arc-accent-dark:  #5f9328;\r\n\t--arc-surface:      #ffffff;\r\n\t--arc-surface-alt:  #f6f8f9;\r\n\t--arc-border:       #e6eaec;\r\n\t--arc-muted:        #6c757d;\r\n\t--arc-text:         #1a1a1a;\r\n\t--arc-radius:       12px;\r\n\t--arc-shadow-sm:    0 1px 2px rgba(10, 61, 71, .04);\r\n\t--arc-shadow-md:    0 6px 20px rgba(10, 61, 71, .08);\r\n\t--arc-shadow-lg:    0 14px 40px rgba(10, 61, 71, .14);\r\n}\r\n\r\n\/* \u2500\u2500 Controls bar (tabs \u2192 search \u2192 mode chips) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n#arc-disc-controls-bar {\r\n\tmax-width: 780px;\r\n\tmargin: .35rem auto .9rem;\r\n\tpadding: 0 1rem;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\tgap: .65rem;\r\n}\r\n\r\n\/* \u2500\u2500 Type tabs (Authors \/ Institutions \/ Sponsors) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n#arc-disc-tabs {\r\n\tdisplay: flex;\r\n\tgap: .35rem;\r\n\tborder-bottom: 1px solid var(--arc-border);\r\n}\r\n.arc-disc-tab {\r\n\tbackground: transparent;\r\n\tborder: none;\r\n\tcolor: var(--arc-muted);\r\n\tpadding: .55rem .9rem;\r\n\tfont-size: .9rem;\r\n\tfont-weight: 500;\r\n\tcursor: pointer;\r\n\ttransition: color .15s, border-color .15s;\r\n\twhite-space: nowrap;\r\n\tdisplay: inline-flex;\r\n\talign-items: center;\r\n\tgap: .4rem;\r\n\tborder-bottom: 2px solid transparent;\r\n\tmargin-bottom: -1px;\r\n}\r\n.arc-disc-tab i { font-size: .75rem; }\r\n.arc-disc-tab:hover:not(.active) { color: var(--arc-primary); }\r\n.arc-disc-tab.active {\r\n\tcolor: var(--arc-primary);\r\n\tfont-weight: 600;\r\n\tborder-bottom-color: var(--arc-accent);\r\n}\r\n\r\n\/* \u2500\u2500 Search bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n#arc-disc-search-row {\r\n\tdisplay: flex;\r\n\talign-items: stretch;\r\n\tposition: relative;\r\n}\r\n.arc-disc-search-wrapper { position: relative; flex: 1; }\r\n.arc-disc-search-wrapper .arc-disc-search-icon {\r\n\tposition: absolute;\r\n\tleft: .95rem;\r\n\ttop: 50%;\r\n\ttransform: translateY(-50%);\r\n\tcolor: #98a4a7;\r\n\tpointer-events: none;\r\n\tfont-size: .9rem;\r\n\tz-index: 1;\r\n}\r\n#arc-discover-search {\r\n\twidth: 100%;\r\n\theight: 44px;\r\n\tpadding: 0 1rem 0 2.55rem;\r\n\tfont-size: .95rem;\r\n\tborder: 1px solid var(--arc-border);\r\n\tborder-right: none;\r\n\tborder-radius: 8px 0 0 8px;\r\n\tbackground: #fff;\r\n\toutline: none;\r\n\tcolor: var(--arc-text);\r\n\ttransition: border-color .15s, box-shadow .15s;\r\n}\r\n#arc-discover-search::placeholder { color: #98a4a7; }\r\n#arc-discover-search:focus {\r\n\tborder-color: var(--arc-primary);\r\n\tbox-shadow: 0 0 0 3px rgba(10,61,71,.08);\r\n}\r\n#arc-discover-btn {\r\n\theight: 44px;\r\n\tpadding: 0 1.15rem;\r\n\tfont-size: .88rem;\r\n\tfont-weight: 500;\r\n\tbackground: var(--arc-primary);\r\n\tborder: 1px solid var(--arc-primary);\r\n\tborder-radius: 0 8px 8px 0;\r\n\tcolor: #fff;\r\n\tcursor: pointer;\r\n\ttransition: background-color .15s, border-color .15s;\r\n\twhite-space: nowrap;\r\n\tflex-shrink: 0;\r\n\tdisplay: inline-flex;\r\n\talign-items: center;\r\n\tgap: .45rem;\r\n}\r\n#arc-discover-btn:hover,\r\n#arc-discover-btn:focus {\r\n\tbackground: #0d5561;\r\n\tborder-color: #0d5561;\r\n\toutline: none;\r\n}\r\n\r\n\/* \u2500\u2500 Mode chips + sort \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n#arc-disc-controls {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tgap: .55rem;\r\n\tflex-wrap: wrap;\r\n}\r\n.arc-disc-mode-label {\r\n\tfont-size: .72rem;\r\n\tfont-weight: 600;\r\n\tcolor: var(--arc-muted);\r\n\ttext-transform: uppercase;\r\n\tletter-spacing: .08em;\r\n}\r\n#arc-disc-controls .btn-group { gap: .35rem; background: none; }\r\n#arc-disc-controls .btn-group .btn {\r\n\tfont-size: .78rem;\r\n\tfont-weight: 500;\r\n\tbackground: #fff;\r\n\tborder: 1px solid var(--arc-border);\r\n\tcolor: var(--arc-muted);\r\n\tpadding: .28rem .8rem;\r\n\tborder-radius: 999px;\r\n\ttransition: background-color .15s, color .15s, border-color .15s;\r\n}\r\n#arc-disc-controls .btn-check:checked + .btn {\r\n\tbackground: rgba(10,61,71,.06);\r\n\tborder-color: var(--arc-primary);\r\n\tcolor: var(--arc-primary);\r\n\tfont-weight: 600;\r\n}\r\n#arc-disc-controls .btn-group .btn:not(.active):hover {\r\n\tcolor: var(--arc-primary);\r\n\tborder-color: var(--arc-primary);\r\n}\r\n#arc-disc-controls .arc-disc-sort-spacer { flex: 1; }\r\n#arc-disc-controls .arc-disc-sort {\r\n\tdisplay: inline-flex;\r\n\talign-items: center;\r\n\tgap: .4rem;\r\n}\r\n#arc-disc-sort-select {\r\n\tfont-size: .78rem;\r\n\tcolor: var(--arc-primary);\r\n\tbackground: #fff;\r\n\tborder: 1px solid var(--arc-border);\r\n\tborder-radius: 999px;\r\n\tpadding: .28rem 1.9rem .28rem .8rem;\r\n\tcursor: pointer;\r\n\tappearance: none;\r\n\t-webkit-appearance: none;\r\n\tbackground-image: url(\"data:image\/svg+xml;utf8,<svg xmlns='http:\/\/www.w3.org\/2000\/svg' width='10' height='6' viewBox='0 0 10 6'><path fill='%230a3d47' d='M5 6 0 0h10z'\/><\/svg>\");\r\n\tbackground-repeat: no-repeat;\r\n\tbackground-position: right .7rem center;\r\n\ttransition: border-color .15s;\r\n}\r\n#arc-disc-sort-select:hover, #arc-disc-sort-select:focus {\r\n\tborder-color: var(--arc-primary);\r\n\toutline: none;\r\n}\r\n\r\n\/* \u2500\u2500 Body container (results area) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n#arc-disc-body {\r\n\tmax-width: 1180px;\r\n\tmargin: 0 auto;\r\n\tpadding: 0 1rem 3rem;\r\n}\r\n\r\n\/* \u2500\u2500 Summary bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n#arc-discover-summary {\r\n\tfont-size: .92rem;\r\n\tcolor: var(--arc-muted);\r\n\tpadding: .6rem 0 1rem;\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: space-between;\r\n\tflex-wrap: wrap;\r\n\tgap: .5rem;\r\n}\r\n#arc-discover-summary strong { color: var(--arc-primary); font-weight: 600; }\r\n#arc-discover-summary .summary-count-pill {\r\n\tbackground: rgba(121,186,58,.14);\r\n\tcolor: var(--arc-accent-dark);\r\n\tpadding: .2rem .75rem;\r\n\tborder-radius: 999px;\r\n\tfont-size: .82rem;\r\n\tfont-weight: 600;\r\n}\r\n\r\n\/* \u2500\u2500 Result grid \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n#arc-discover-results {\r\n\tdisplay: grid;\r\n\tgrid-template-columns: 1fr;\r\n\tgap: .9rem;\r\n}\r\n@media (min-width: 720px)  { #arc-discover-results { grid-template-columns: repeat(2, 1fr); } }\r\n@media (min-width: 1100px) { #arc-discover-results { grid-template-columns: repeat(3, 1fr); } }\r\n\r\n\/* \u2500\u2500 Result cards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n.arc-disc-card {\r\n\tdisplay: flex;\r\n\tgap: 1rem;\r\n\tpadding: 1.1rem 1.15rem;\r\n\tbackground: var(--arc-surface);\r\n\tborder: 1px solid var(--arc-border);\r\n\tborder-radius: var(--arc-radius);\r\n\tbox-shadow: var(--arc-shadow-sm);\r\n\ttransition: transform .18s, box-shadow .18s, border-color .18s;\r\n\tposition: relative;\r\n\toverflow: hidden;\r\n}\r\n.arc-disc-card::before {\r\n\tcontent: '';\r\n\tposition: absolute;\r\n\tinset: 0 auto 0 0;\r\n\twidth: 3px;\r\n\tbackground: var(--arc-accent);\r\n\topacity: .35;\r\n\ttransition: opacity .18s;\r\n}\r\n.arc-disc-card:hover {\r\n\ttransform: translateY(-2px);\r\n\tbox-shadow: var(--arc-shadow-md);\r\n\tborder-color: rgba(10, 61, 71, .18);\r\n}\r\n.arc-disc-card:hover::before { opacity: 1; }\r\n.arc-disc-card.is-claimed::before { opacity: 1; }\r\n\r\n\/* Avatar *\/\r\n.arc-disc-avatar {\r\n\twidth: 52px; height: 52px;\r\n\tmin-width: 52px;\r\n\tborder-radius: 14px;\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tfont-size: 1.25rem;\r\n\tfont-weight: 700;\r\n\tcolor: #fff;\r\n\tbackground: linear-gradient(135deg, var(--arc-primary) 0%, var(--arc-primary-alt) 100%);\r\n\tbox-shadow: 0 4px 10px rgba(10,61,71,.18);\r\n\tletter-spacing: -.02em;\r\n}\r\n\/* Claimants who uploaded a profile photo get it in place of the initial.\r\n   Same 52px box so card height and alignment are unchanged. *\/\r\n.arc-disc-avatar.has-photo {\r\n\tbackground: none;\r\n\toverflow: hidden;\r\n\tbox-shadow: 0 4px 10px rgba(10,61,71,.18);\r\n}\r\n.arc-disc-avatar.has-photo img {\r\n\twidth: 100%;\r\n\theight: 100%;\r\n\tobject-fit: cover;\r\n\tdisplay: block;\r\n}\r\n.arc-disc-avatar.is-institution {\r\n\tbackground: linear-gradient(135deg, #4a7a2c 0%, var(--arc-accent) 100%);\r\n\tbox-shadow: 0 4px 10px rgba(74,122,44,.22);\r\n}\r\n.arc-disc-avatar.is-sponsor {\r\n\tbackground: linear-gradient(135deg, #1f497d 0%, #3872b8 100%);\r\n\tbox-shadow: 0 4px 10px rgba(31,73,125,.22);\r\n}\r\n.arc-disc-avatar i { font-size: 1.1rem; }\r\n\r\n\/* Card body *\/\r\n.arc-disc-body-inner {\r\n\tflex: 1;\r\n\tmin-width: 0;\r\n\tdisplay: flex;\r\n\tflex-direction: column;\r\n\tgap: .28rem;\r\n}\r\n.arc-disc-name {\r\n\tfont-size: 1rem;\r\n\tfont-weight: 600;\r\n\tcolor: var(--arc-text);\r\n\tmargin: 0;\r\n\tline-height: 1.3;\r\n\tdisplay: -webkit-box;\r\n\t-webkit-line-clamp: 2;\r\n\t-webkit-box-orient: vertical;\r\n\toverflow: hidden;\r\n}\r\n.arc-disc-name a { color: inherit; text-decoration: none; }\r\n.arc-disc-name a:hover { color: var(--arc-primary); }\r\n\/* Claimed-profile badge. Sits on its own line under the name rather than\r\n   inside it: .arc-disc-name is a 2-line clamped -webkit-box, and an inline\r\n   child would be clipped along with the text. *\/\r\n.arc-disc-claimed {\r\n\tdisplay: inline-flex;\r\n\talign-items: center;\r\n\tgap: .3rem;\r\n\tmargin-top: .3rem;\r\n\tpadding: .1rem .45rem;\r\n\tborder-radius: 999px;\r\n\tbackground: rgba(121,186,58,.16);\r\n\tcolor: var(--arc-accent-dark);\r\n\tfont-size: .72rem;\r\n\tfont-weight: 600;\r\n\tline-height: 1.5;\r\n\twhite-space: nowrap;\r\n}\r\n.arc-disc-claimed i { font-size: .72rem; }\r\n.arc-disc-location {\r\n\tfont-size: .8rem;\r\n\tcolor: var(--arc-muted);\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tgap: .35rem;\r\n}\r\n.arc-disc-location i { color: #b8c1c4; font-size: .7rem; }\r\n.arc-disc-metrics {\r\n\tdisplay: flex;\r\n\tflex-wrap: wrap;\r\n\tgap: .55rem .95rem;\r\n\tfont-size: .78rem;\r\n\tcolor: var(--arc-muted);\r\n\tmargin-top: .15rem;\r\n}\r\n.arc-disc-metrics .metric {\r\n\tdisplay: inline-flex;\r\n\talign-items: center;\r\n\tgap: .3rem;\r\n}\r\n.arc-disc-metrics .metric i { color: var(--arc-accent); font-size: .7rem; }\r\n.arc-disc-metrics .metric strong { color: var(--arc-text); font-weight: 600; font-variant-numeric: tabular-nums; }\r\n.arc-disc-match-tag {\r\n\tdisplay: inline-flex;\r\n\talign-items: center;\r\n\tgap: .3rem;\r\n\tfont-size: .72rem;\r\n\tpadding: .16rem .55rem;\r\n\tborder-radius: 4px;\r\n\tbackground: #f1f3f5;\r\n\tcolor: #6c757d;\r\n\tline-height: 1.4;\r\n\tmargin-top: .3rem;\r\n\twidth: fit-content;\r\n\tfont-weight: 500;\r\n}\r\n.arc-disc-match-tag i { font-size: .65rem; }\r\n.arc-disc-match-tag.is-keyword {\r\n\tbackground: rgba(121,186,58,.12);\r\n\tcolor: var(--arc-accent-dark);\r\n}\r\n.arc-disc-match-tag.is-both {\r\n\tbackground: rgba(10,61,71,.08);\r\n\tcolor: var(--arc-primary);\r\n}\r\n\r\n\/* View action (kept as small text-link at bottom-right of card) *\/\r\n.arc-disc-action {\r\n\tposition: absolute;\r\n\tright: 1.1rem;\r\n\tbottom: 1rem;\r\n\topacity: 0;\r\n\ttransition: opacity .18s, transform .18s;\r\n\ttransform: translateX(4px);\r\n}\r\n.arc-disc-card:hover .arc-disc-action { opacity: 1; transform: translateX(0); }\r\n.arc-disc-action .btn-view {\r\n\tfont-size: .75rem;\r\n\tfont-weight: 600;\r\n\tcolor: var(--arc-primary);\r\n\ttext-decoration: none;\r\n\tdisplay: inline-flex;\r\n\talign-items: center;\r\n\tgap: .3rem;\r\n}\r\n.arc-disc-action .btn-view i { transition: transform .18s; }\r\n.arc-disc-action .btn-view:hover i { transform: translateX(3px); }\r\n\r\n\/* Full-card link cover \u2014 the whole card is clickable when a profile URL exists *\/\r\n.arc-disc-card.is-linked { cursor: pointer; }\r\n\r\n\/* \u2500\u2500 States (empty \/ loading \/ error) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n.arc-disc-state {\r\n\tgrid-column: 1 \/ -1;\r\n\ttext-align: center;\r\n\tpadding: 3.5rem 1rem;\r\n\tcolor: var(--arc-muted);\r\n\tbackground: var(--arc-surface-alt);\r\n\tborder-radius: var(--arc-radius);\r\n\tborder: 1px dashed var(--arc-border);\r\n}\r\n.arc-disc-state i { font-size: 2.4rem; display: block; margin-bottom: .8rem; color: #b8c1c4; }\r\n.arc-disc-state p { margin: 0; font-size: .95rem; }\r\n.arc-disc-state.is-error i { color: #dc3545; }\r\n.arc-disc-state.is-error { color: #a02937; }\r\n\r\n.arc-disc-skeleton {\r\n\tbackground: linear-gradient(90deg, #eef1f2 25%, #f6f8f9 50%, #eef1f2 75%);\r\n\tbackground-size: 200% 100%;\r\n\tanimation: arcShimmer 1.4s ease-in-out infinite;\r\n\tborder-radius: var(--arc-radius);\r\n\theight: 96px;\r\n}\r\n@keyframes arcShimmer { 0% { background-position: 200% 0; } 100% { background-position: -200% 0; } }\r\n\r\n\/* \u2500\u2500 Pagination \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n#arc-discover-pagination {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tjustify-content: center;\r\n\tgap: .5rem;\r\n\tmargin-top: 2rem;\r\n}\r\n#arc-discover-pagination .btn-pg {\r\n\theight: 38px;\r\n\tpadding: 0 1rem;\r\n\tfont-size: .85rem;\r\n\tfont-weight: 500;\r\n\tcolor: var(--arc-primary);\r\n\tborder: 1px solid var(--arc-border);\r\n\tborder-radius: 8px;\r\n\tbackground: #fff;\r\n\tcursor: pointer;\r\n\ttransition: all .15s;\r\n\tdisplay: inline-flex;\r\n\talign-items: center;\r\n\tgap: .35rem;\r\n}\r\n#arc-discover-pagination .btn-pg:not(:disabled):hover {\r\n\tborder-color: var(--arc-primary);\r\n\tbackground: var(--arc-primary);\r\n\tcolor: #fff;\r\n}\r\n#arc-discover-pagination .btn-pg:disabled { opacity: .35; cursor: default; }\r\n#arc-discover-pagination .pg-info {\r\n\tpadding: 0 1rem;\r\n\tfont-size: .82rem;\r\n\tcolor: var(--arc-muted);\r\n\tfont-variant-numeric: tabular-nums;\r\n}\r\n\r\n\/* \u2500\u2500 Suggestion dropdown \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n.arc-disc-suggest {\r\n\tposition: absolute;\r\n\ttop: calc(100% + 8px);\r\n\tleft: 6px;\r\n\tright: 6px;\r\n\tz-index: 100;\r\n\tbackground: #fff;\r\n\tborder: 1px solid var(--arc-border);\r\n\tborder-radius: var(--arc-radius);\r\n\tbox-shadow: var(--arc-shadow-lg);\r\n\tmax-height: 380px;\r\n\toverflow-y: auto;\r\n}\r\n.arc-disc-suggest-item {\r\n\tdisplay: flex;\r\n\talign-items: center;\r\n\tgap: .7rem;\r\n\tpadding: .7rem 1.1rem;\r\n\tcursor: pointer;\r\n\ttransition: background-color .12s;\r\n}\r\n.arc-disc-suggest-item:hover,\r\n.arc-disc-suggest-item.is-active {\r\n\tbackground-color: rgba(121,186,58,.10);\r\n}\r\n.arc-disc-suggest-item + .arc-disc-suggest-item {\r\n\tborder-top: 1px solid #f1f3f5;\r\n}\r\n.arc-disc-suggest-name {\r\n\tfont-size: .92rem;\r\n\tfont-weight: 500;\r\n\tcolor: var(--arc-text);\r\n\tflex: 1;\r\n\tmin-width: 0;\r\n\toverflow: hidden;\r\n\ttext-overflow: ellipsis;\r\n\twhite-space: nowrap;\r\n}\r\n.arc-disc-suggest-name mark {\r\n\tbackground: rgba(121,186,58,.28);\r\n\tcolor: inherit;\r\n\tpadding: 0 2px;\r\n\tborder-radius: 2px;\r\n}\r\n.arc-disc-suggest-meta {\r\n\tfont-size: .76rem;\r\n\tcolor: var(--arc-muted);\r\n\twhite-space: nowrap;\r\n\tflex-shrink: 0;\r\n}\r\n.arc-disc-suggest-hint {\r\n\tpadding: .55rem 1.1rem;\r\n\tfont-size: .74rem;\r\n\tcolor: #adb5bd;\r\n\ttext-align: center;\r\n\tbackground: var(--arc-surface-alt);\r\n\tborder-top: 1px solid var(--arc-border);\r\n}\r\n\r\n\/* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\r\n@media (max-width: 720px) {\r\n\t.arc-disc-tab { padding: .5rem .7rem; font-size: .82rem; }\r\n\t.arc-disc-tab i { display: none; }\r\n\t#arc-discover-btn span.btn-label { display: none; }\r\n\t#arc-discover-btn { padding: 0 .95rem; }\r\n\t.arc-disc-action { position: static; opacity: 1; transform: none; margin-top: .35rem; }\r\n}\r\n<\/style>\r\n\r\n<div id=\"arc-discover-container\"><\/div>\r\n\r\n<script>\r\njQuery(function ($) {\r\n\r\n\t\/\/ \u2500\u2500 State \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\tlet currentType   = 'author';\r\n\tlet currentMode   = 'name';\r\n\tlet currentSort   = 'recommended';\r\n\tlet currentSearch = '';\r\n\tlet currentPage   = 1;\r\n\tlet perPage       = 25;\r\n\tlet totalResults  = 0;\r\n\r\n\tconst ajaxUrl = 'https:\/\/africaresearchconnects.com\/wp-admin\/admin-ajax.php';\r\n\r\n\t\/\/ First page of the default view, rendered server-side into the document.\r\n\t\/\/ Null when render_discover() could not build it, in which case the page\r\n\t\/\/ behaves exactly as before and fetches over AJAX.\r\n\tconst BOOTSTRAP = {\"total\":601954,\"items\":[{\"id\":1000036090,\"uid\":\"9bb6e52f66d3fc5a3d2533f55483a1cf\",\"name\":\"Ahmed M. Eldosouky\",\"papers\":108,\"citations\":1266,\"hindex\":31,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\",\"photo\":\"https:\\\/\\\/africaresearchconnects.com\\\/wp-content\\\/uploads\\\/2026\\\/07\\\/Image-Jun-14-2026-03_19_54-PM-150x150.png\"},{\"id\":1000133071,\"uid\":\"011b14890b3f5321cceee5f79829c976\",\"name\":\"Francis Kwame Padi\",\"papers\":87,\"citations\":883,\"hindex\":19,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1034986031,\"uid\":\"b17204a9-7381-573f-8709-7849cefb142c\",\"name\":\"Kedir Hussein Abegaz\",\"papers\":64,\"citations\":30884,\"hindex\":26,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1021277748,\"uid\":\"b3d06194bba2aee3333744fe3ee5788ed2a83c288b7e66ca9453d489de50cbf1\",\"name\":\"J\\u00e9r\\u00f4me Chenal\",\"papers\":57,\"citations\":508,\"hindex\":11,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1000028197,\"uid\":\"5b5e9c04175e30b2de13cafb40faf69a\",\"name\":\"Christine Wamunyima Kanyengo\",\"papers\":48,\"citations\":188,\"hindex\":27,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1000554414,\"uid\":\"1036eec28c5e0b156376760da8660b87\",\"name\":\"Wilfred Ouma Otambo\",\"papers\":48,\"citations\":272,\"hindex\":7,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1000112454,\"uid\":\"60320abe4eaf9b85f930c82a319a3d67\",\"name\":\"Prosper Eguono Ovuoraye\",\"papers\":40,\"citations\":126,\"hindex\":14,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1000103283,\"uid\":\"5629f858731876a6864ca093e2b865d6\",\"name\":\"Justice Kanor Tetteh\",\"papers\":37,\"citations\":185,\"hindex\":11,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\",\"photo\":\"https:\\\/\\\/africaresearchconnects.com\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/88557-150x150.jpg\"},{\"id\":1006151288,\"uid\":\"48789a8e86e202b49cea12265f1c7a859d144d7dda424d8f9bcd546ab6b6acf2\",\"name\":\"Lawrence Mwenge\",\"papers\":37,\"citations\":796,\"hindex\":21,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\",\"photo\":\"https:\\\/\\\/africaresearchconnects.com\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/image_df0ff155-1-150x150.png\"},{\"id\":1000585924,\"uid\":\"d1670d9bed173faad4c99f5a15d5975591ca10834259c04920e8587256436206\",\"name\":\"Elatikpo, Safiyanu Muhammad\",\"papers\":22,\"citations\":158,\"hindex\":9,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035275649,\"uid\":\"1fe490fb-8730-50ff-a64d-b9972b690f28\",\"name\":\"Dick Chune Midamba\",\"papers\":17,\"citations\":47,\"hindex\":2,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\",\"photo\":\"https:\\\/\\\/africaresearchconnects.com\\\/wp-content\\\/uploads\\\/2026\\\/09\\\/2x2-150x150.jpg\"},{\"id\":1000468709,\"uid\":\"a4add0c5172ce94f0c4da833cb2c0026b24e890bc962d8a42c2298c382039277\",\"name\":\"Okwesili, Obinna R.\",\"papers\":14,\"citations\":49,\"hindex\":4,\"claimed\":true,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\",\"photo\":\"https:\\\/\\\/africaresearchconnects.com\\\/wp-content\\\/uploads\\\/2026\\\/08\\\/My-Passport-1-150x150.jpeg\"},{\"id\":1035269016,\"uid\":\"1479936f-ffca-58b1-ae36-72b537c739d9\",\"name\":\"Joshua Kimani\",\"papers\":619,\"citations\":25357,\"hindex\":72,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035277263,\"uid\":\"88ab197f-c2b2-5800-9fd3-e27a91c7f637\",\"name\":\"Rodomiro Ortiz\",\"papers\":532,\"citations\":18190,\"hindex\":0,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035422695,\"uid\":\"4300046d-0dfb-50fc-a28a-faa788004f24\",\"name\":\"John Changalucha\",\"papers\":280,\"citations\":12947,\"hindex\":2,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035269633,\"uid\":\"868432b7-5496-5dff-9464-1431897ab4f8\",\"name\":\"Victor Ongoma\",\"papers\":263,\"citations\":5076,\"hindex\":36,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035475945,\"uid\":\"3c227fbb-089d-5318-9236-405185cd0493\",\"name\":\"Wasswa SHAFIK\",\"papers\":238,\"citations\":1872,\"hindex\":0,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035311793,\"uid\":\"49ef3ef8-d56b-58f6-8d2e-71a2313b0670\",\"name\":\"Shuaib Lwasa\",\"papers\":206,\"citations\":7523,\"hindex\":39,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035410556,\"uid\":\"c054ffd5-75aa-5865-8db9-13f6e887b573\",\"name\":\"Neoline Nakasujja\",\"papers\":196,\"citations\":6554,\"hindex\":0,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035273209,\"uid\":\"8c512979-6039-5929-8e6e-8b429a59a677\",\"name\":\"Philip Bejon\",\"papers\":186,\"citations\":4215,\"hindex\":1,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035457363,\"uid\":\"4abee08d-dab1-5960-a03c-822ddb17d169\",\"name\":\"Ruan Kruger\",\"papers\":120,\"citations\":3788,\"hindex\":26,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035281243,\"uid\":\"c4c418cb-8c69-59ac-9072-1bc25dd7e240\",\"name\":\"Ginenus Fekadu\",\"papers\":119,\"citations\":2500,\"hindex\":23,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035284673,\"uid\":\"fe4b7b21-a8da-520b-8ab1-9a8349579f2e\",\"name\":\"Mike English\",\"papers\":119,\"citations\":2180,\"hindex\":3,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035282065,\"uid\":\"b771c386-0040-5ac8-8c41-80318a190140\",\"name\":\"Yoseph Beyene\",\"papers\":108,\"citations\":4811,\"hindex\":38,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"},{\"id\":1035285456,\"uid\":\"db8842d9-47f6-5dc4-a89b-e9cf187b9f38\",\"name\":\"Adewale Oluwaseun Fadaka\",\"papers\":108,\"citations\":2499,\"hindex\":33,\"claimed\":false,\"name_match\":false,\"relevant_papers\":0,\"type\":\"author\"}]};\r\n\tlet bootstrapUsed = false;\r\n\r\n\t\/\/ Only the pristine default state may be served from the inlined payload.\r\n\t\/\/ Anything restored from the URL (a search, a page, a different tab or\r\n\t\/\/ sort) does not match what the server precomputed.\r\n\tfunction canUseBootstrap(q) {\r\n\t\treturn !bootstrapUsed\r\n\t\t\t&& BOOTSTRAP && Array.isArray(BOOTSTRAP.items)\r\n\t\t\t&& currentType === 'author'\r\n\t\t\t&& currentMode === 'name'\r\n\t\t\t&& currentSort === 'recommended'\r\n\t\t\t&& currentPage === 1\r\n\t\t\t&& perPage === 25\r\n\t\t\t&& !q;\r\n\t}\r\n\r\n\t\/\/ Sort options per type. Keep the keys in sync with discover_order_by()\r\n\t\/\/ in class-arc-extensions-public.php \u2014 the backend whitelists these.\r\n\tconst SORT_OPTIONS = {\r\n\t\tauthor: [\r\n\t\t\t{ v: 'recommended',    l: 'Recommended' },\r\n\t\t\t{ v: 'recent_desc',    l: 'Recently updated' },\r\n\t\t\t{ v: 'papers_desc',    l: 'Most publications' },\r\n\t\t\t{ v: 'citations_desc', l: 'Most citations' },\r\n\t\t\t{ v: 'hindex_desc',    l: 'Highest h-index' },\r\n\t\t\t{ v: 'name_asc',       l: 'Name (A\u2013Z)' },\r\n\t\t\t{ v: 'name_desc',      l: 'Name (Z\u2013A)' },\r\n\t\t\t{ v: 'papers_asc',     l: 'Fewest publications' },\r\n\t\t],\r\n\t\tinstitution: [\r\n\t\t\t{ v: 'recommended',    l: 'Recommended' },\r\n\t\t\t{ v: 'recent_desc',    l: 'Recently updated' },\r\n\t\t\t{ v: 'papers_desc',    l: 'Most publications' },\r\n\t\t\t{ v: 'citations_desc', l: 'Most citations' },\r\n\t\t\t{ v: 'authors_desc',   l: 'Most authors' },\r\n\t\t\t{ v: 'name_asc',       l: 'Name (A\u2013Z)' },\r\n\t\t\t{ v: 'name_desc',      l: 'Name (Z\u2013A)' },\r\n\t\t\t{ v: 'papers_asc',     l: 'Fewest publications' },\r\n\t\t],\r\n\t\tsponsor: [\r\n\t\t\t{ v: 'papers_desc',    l: 'Most papers funded' },\r\n\t\t\t{ v: 'citations_desc', l: 'Most citations' },\r\n\t\t\t{ v: 'name_asc',       l: 'Name (A\u2013Z)' },\r\n\t\t\t{ v: 'name_desc',      l: 'Name (Z\u2013A)' },\r\n\t\t\t{ v: 'papers_asc',     l: 'Fewest papers funded' },\r\n\t\t],\r\n\t};\r\n\r\n\t\/\/ \u2500\u2500 Helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\r\n\tfunction getProfileUrl(type, id) {\r\n\t\tif (typeof arGetPageUrl === 'function') return arGetPageUrl(type, id);\r\n\t\tconst bases = { author: '\/author\/', institution: '\/institution\/', sponsor: '\/sponsor\/' };\r\n\t\treturn (bases[type] || ('\/' + type + '\/')) + id + '\/';\r\n\t}\r\n\r\n\t\/\/ HTML-escape a value for interpolation into a template string. The other\r\n\t\/\/ templates in this plugin define the same helper; this one did not, and a\r\n\t\/\/ call to it threw at render time and took every card down with it.\r\n\tfunction esc(s) { return $('<span>').text(s == null ? '' : s).html(); }\r\n\r\n\tfunction fmtNum(n) {\r\n\t\tn = Number(n);\r\n\t\tif (isNaN(n)) return '0';\r\n\t\tif (n >= 1000000) return (n \/ 1000000).toFixed(1).replace(\/\\.0$\/, '') + 'M';\r\n\t\tif (n >= 1000)    return (n \/ 1000).toFixed(1).replace(\/\\.0$\/, '') + 'k';\r\n\t\treturn n.toString();\r\n\t}\r\n\r\n\t\/\/ ISO-2 \u2192 country name (African countries)\r\n\tconst CC = {\r\n\t\tDZ:'Algeria',AO:'Angola',BJ:'Benin',BW:'Botswana',BF:'Burkina Faso',\r\n\t\tBI:'Burundi',CV:'Cabo Verde',CM:'Cameroon',CF:'Central African Republic',\r\n\t\tTD:'Chad',KM:'Comoros',CG:'Congo',CD:'DR Congo',CI:\"C\u00f4te d'Ivoire\",\r\n\t\tDJ:'Djibouti',EG:'Egypt',GQ:'Equatorial Guinea',ER:'Eritrea',\r\n\t\tSZ:'Eswatini',ET:'Ethiopia',GA:'Gabon',GM:'Gambia',GH:'Ghana',\r\n\t\tGN:'Guinea',GW:'Guinea-Bissau',KE:'Kenya',LS:'Lesotho',LR:'Liberia',\r\n\t\tLY:'Libya',MG:'Madagascar',MW:'Malawi',ML:'Mali',MR:'Mauritania',\r\n\t\tMU:'Mauritius',MA:'Morocco',MZ:'Mozambique',NA:'Namibia',NE:'Niger',\r\n\t\tNG:'Nigeria',RW:'Rwanda',ST:'S\u00e3o Tom\u00e9 & Pr\u00edncipe',SN:'Senegal',\r\n\t\tSL:'Sierra Leone',SO:'Somalia',ZA:'South Africa',SS:'South Sudan',\r\n\t\tSD:'Sudan',TZ:'Tanzania',TG:'Togo',TN:'Tunisia',UG:'Uganda',\r\n\t\tZM:'Zambia',ZW:'Zimbabwe',\r\n\t};\r\n\tfunction countryName(cc) { return CC[cc] || cc || ''; }\r\n\r\n\tfunction getQueryParams() {\r\n\t\tconst qs = window.location.search.replace(\/%2B\/gi, '+');\r\n\t\treturn Object.fromEntries(new URLSearchParams(qs));\r\n\t}\r\n\r\n\tfunction pushState() {\r\n\t\tconst params = new URLSearchParams({\r\n\t\t\ttype:     currentType,\r\n\t\t\tmode:     currentMode,\r\n\t\t\tsort:     currentSort,\r\n\t\t\tsearch:   currentSearch,\r\n\t\t\tper_page: perPage,\r\n\t\t\tpag:      currentPage,\r\n\t\t});\r\n\t\thistory.replaceState(null, '', '?' + params.toString());\r\n\t}\r\n\r\n\t\/\/ Refresh the sort <select> options for the current type. Called on\r\n\t\/\/ initial render and every time the user switches type tab. If the\r\n\t\/\/ active sort key is valid for the new type it's kept; otherwise we\r\n\t\/\/ fall back to that type's first option (which is always papers_desc).\r\n\tfunction renderSortSelect() {\r\n\t\tconst opts = SORT_OPTIONS[currentType] || SORT_OPTIONS.author;\r\n\t\tconst validKeys = opts.map(o => o.v);\r\n\t\tif (!validKeys.includes(currentSort)) {\r\n\t\t\tcurrentSort = opts[0].v;\r\n\t\t}\r\n\t\tconst $sel = $('#arc-disc-sort-select');\r\n\t\t$sel.empty();\r\n\t\topts.forEach(o => {\r\n\t\t\t$sel.append(`<option value=\"${o.v}\"${o.v === currentSort ? ' selected' : ''}>${o.l}<\/option>`);\r\n\t\t});\r\n\t}\r\n\r\n\t\/\/ \u2500\u2500 Build layout \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\tfunction buildLayout() {\r\n\t\t$('#arc-discover-container').html(`\r\n\t\t\t<div id=\"arc-disc-controls-bar\">\r\n\t\t\t\t<!-- Type tabs -->\r\n\t\t\t\t<div id=\"arc-disc-tabs\" role=\"tablist\" aria-label=\"Discover category\">\r\n\t\t\t\t\t<button class=\"arc-disc-tab active\" data-type=\"author\" role=\"tab\" aria-selected=\"true\">\r\n\t\t\t\t\t\t<i class=\"fa-solid fa-user\"><\/i> Auteurs\t\t\t\t\t<\/button>\r\n\t\t\t\t\t<button class=\"arc-disc-tab\" data-type=\"institution\" role=\"tab\" aria-selected=\"false\">\r\n\t\t\t\t\t\t<i class=\"fa-solid fa-building\"><\/i> Institutions\t\t\t\t\t<\/button>\r\n\t\t\t\t\t<button class=\"arc-disc-tab\" data-type=\"sponsor\" role=\"tab\" aria-selected=\"false\">\r\n\t\t\t\t\t\t<i class=\"fa-solid fa-hand-holding-dollar\"><\/i> Sponsors\t\t\t\t\t<\/button>\r\n\t\t\t\t<\/div>\r\n\r\n\t\t\t\t<!-- Search bar -->\r\n\t\t\t\t<div id=\"arc-disc-search-row\">\r\n\t\t\t\t\t<div class=\"arc-disc-search-wrapper\">\r\n\t\t\t\t\t\t<i class=\"fa-solid fa-magnifying-glass arc-disc-search-icon\"><\/i>\r\n\t\t\t\t\t\t<input type=\"text\" id=\"arc-discover-search\"\r\n\t\t\t\t\t\t\t   placeholder=\"Rechercher des auteurs par nom\u2026\" autocomplete=\"off\"\r\n\t\t\t\t\t\t\t   aria-label=\"Rechercher\">\r\n\t\t\t\t\t<\/div>\r\n\t\t\t\t\t<button id=\"arc-discover-btn\" type=\"button\">\r\n\t\t\t\t\t\t<i class=\"fa-solid fa-magnifying-glass\"><\/i>\r\n\t\t\t\t\t\t<span class=\"btn-label\">Rechercher<\/span>\r\n\t\t\t\t\t<\/button>\r\n\t\t\t\t<\/div>\r\n\r\n\t\t\t\t<!-- Mode chips + sort -->\r\n\t\t\t\t<div id=\"arc-disc-controls\">\r\n\t\t\t\t\t<span class=\"arc-disc-mode-label\">Match le<\/span>\r\n\t\t\t\t\t<div class=\"btn-group btn-group-sm\" role=\"group\">\r\n\t\t\t\t\t\t<input type=\"radio\" class=\"btn-check\" name=\"arc-mode\" id=\"arc-mode-name\"    value=\"name\"    autocomplete=\"off\" checked>\r\n\t\t\t\t\t\t<label class=\"btn\" for=\"arc-mode-name\">Nom<\/label>\r\n\t\t\t\t\t\t<input type=\"radio\" class=\"btn-check\" name=\"arc-mode\" id=\"arc-mode-keyword\" value=\"keyword\" autocomplete=\"off\">\r\n\t\t\t\t\t\t<label class=\"btn\" for=\"arc-mode-keyword\">Sujet de recherche<\/label>\r\n\t\t\t\t\t<\/div>\r\n\t\t\t\t\t<span class=\"arc-disc-sort-spacer\"><\/span>\r\n\t\t\t\t\t<span class=\"arc-disc-sort\">\r\n\t\t\t\t\t\t<span class=\"arc-disc-mode-label\">Trier<\/span>\r\n\t\t\t\t\t\t<select id=\"arc-disc-sort-select\" aria-label=\"Trier par\"><\/select>\r\n\t\t\t\t\t<\/span>\r\n\t\t\t\t<\/div>\r\n\t\t\t<\/div>\r\n\r\n\t\t\t<div id=\"arc-disc-body\">\r\n\t\t\t\t<!-- Result summary -->\r\n\t\t\t\t<div id=\"arc-discover-summary\" style=\"display:none;\"><\/div>\r\n\r\n\t\t\t\t<!-- Results grid -->\r\n\t\t\t\t<div id=\"arc-discover-results\"><\/div>\r\n\r\n\t\t\t\t<!-- Pagination -->\r\n\t\t\t\t<div id=\"arc-discover-pagination\" style=\"display:none;\"><\/div>\r\n\t\t\t<\/div>\r\n\t\t`);\r\n\t}\r\n\r\n\t\/\/ \u2500\u2500 Suggest \/ typeahead \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\tlet suggestXhr   = null;\r\n\tlet suggestTimer = null;\r\n\tlet suggestIdx   = -1;\r\n\t\/\/ Per-prefix cache, keyed by `${type}:${term.toLowerCase()}`. Once a\r\n\t\/\/ request resolves, every retype of that exact prefix renders without\r\n\t\/\/ hitting the network \u2014 feels instant on backspace\/retype interactions.\r\n\tconst suggestCache = new Map();\r\n\r\n\tfunction highlightTerm(text, term) {\r\n\t\tif (!term) return text;\r\n\t\tconst esc = term.replace(\/[.*+?^${}()|[\\]\\\\]\/g, '\\\\$&');\r\n\t\treturn text.replace(new RegExp('(' + esc + ')', 'gi'), '<mark>$1<\/mark>');\r\n\t}\r\n\r\n\tfunction showSuggestions(items, term) {\r\n\t\tconst $row = $('#arc-disc-search-row');\r\n\t\t$row.find('.arc-disc-suggest').remove();\r\n\t\tif (!items.length) { suggestIdx = -1; return; }\r\n\r\n\t\tlet html = '';\r\n\t\titems.forEach(function (it, i) {\r\n\t\t\tconst meta = [fmtNum(it.papers) + ' papers'];\r\n\t\t\tif (it.country) meta.push(countryName(it.country));\r\n\t\t\thtml += `<div class=\"arc-disc-suggest-item\" data-index=\"${i}\" data-id=\"${it.id}\" data-name=\"${$('<span>').text(it.name).html()}\">\r\n\t\t\t\t<span class=\"arc-disc-suggest-name\">${highlightTerm($('<span>').text(it.name).html(), term)}<\/span>\r\n\t\t\t\t<span class=\"arc-disc-suggest-meta\">${meta.join(' \u00b7 ')}<\/span>\r\n\t\t\t<\/div>`;\r\n\t\t});\r\n\t\thtml += '<div class=\"arc-disc-suggest-hint\">Click to open profile \u00b7 Enter to search<\/div>';\r\n\r\n\t\tconst $dd = $('<div class=\"arc-disc-suggest\"><\/div>').html(html);\r\n\t\t$row.append($dd);\r\n\t\tsuggestIdx = -1;\r\n\r\n\t\t$dd.on('click', '.arc-disc-suggest-item', function () {\r\n\t\t\tconst id  = $(this).data('id');\r\n\t\t\tconst url = getProfileUrl(currentType, id);\r\n\t\t\tcloseSuggestions();\r\n\t\t\twindow.location.href = url;\r\n\t\t});\r\n\t}\r\n\r\n\tfunction closeSuggestions() {\r\n\t\t$('.arc-disc-suggest').remove();\r\n\t\tsuggestIdx = -1;\r\n\t}\r\n\r\n\tfunction navigateSuggestions(dir) {\r\n\t\tconst $items = $('.arc-disc-suggest-item');\r\n\t\tif (!$items.length) return;\r\n\t\tsuggestIdx = Math.max(-1, Math.min($items.length - 1, suggestIdx + dir));\r\n\t\t$items.removeClass('is-active');\r\n\t\tif (suggestIdx >= 0) {\r\n\t\t\t$items.eq(suggestIdx).addClass('is-active');\r\n\t\t}\r\n\t}\r\n\r\n\tfunction fetchSuggestions() {\r\n\t\tconst q = $('#arc-discover-search').val().trim();\r\n\t\tif (q.length < 2) { closeSuggestions(); return; }\r\n\r\n\t\tconst cacheKey = currentType + ':' + q.toLowerCase();\r\n\t\tconst cached   = suggestCache.get(cacheKey);\r\n\t\tif (cached) {\r\n\t\t\t\/\/ Render straight from cache \u2014 no network round-trip. Cancels any\r\n\t\t\t\/\/ in-flight request to avoid a stale response overwriting us.\r\n\t\t\tif (suggestXhr) { suggestXhr.abort(); suggestXhr = null; }\r\n\t\t\tshowSuggestions(cached, q);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tif (suggestXhr) suggestXhr.abort();\r\n\t\tsuggestXhr = $.ajax({\r\n\t\t\turl:    ajaxUrl,\r\n\t\t\tmethod: 'GET',\r\n\t\t\tdata:   { action: 'arc_ext_discover_suggest', type: currentType, search: q },\r\n\t\t\tsuccess: function (res) {\r\n\t\t\t\tconst items = res.items || [];\r\n\t\t\t\tsuggestCache.set(cacheKey, items);\r\n\t\t\t\tshowSuggestions(items, q);\r\n\t\t\t},\r\n\t\t});\r\n\t}\r\n\r\n\t\/\/ \u2500\u2500 Placeholder text \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\tfunction updatePlaceholder() {\r\n\t\tconst suffix = currentMode === 'keyword' ? 'research topic' : 'name';\r\n\t\tconst labels = {\r\n\t\t\tauthor:      `Search authors by ${suffix}\u2026`,\r\n\t\t\tinstitution: `Search institutions by ${suffix}\u2026`,\r\n\t\t\tsponsor:     `Search sponsors by ${suffix}\u2026`,\r\n\t\t};\r\n\t\t$('#arc-discover-search').attr('placeholder', labels[currentType] || `Search by ${suffix}\u2026`);\r\n\t}\r\n\r\n\t\/\/ \u2500\u2500 Match tag (only shown when actively searching) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\t\/\/ Name-only matches show no tag \u2014 the card itself is the match signal.\r\n\t\/\/ Only surface a tag when there are keyword-matched papers to report.\r\n\tfunction matchTag(item) {\r\n\t\tif (!currentSearch || currentSearch.length < 3) return '';\r\n\t\tif (item.name_match && item.relevant_papers > 0) {\r\n\t\t\treturn `<span class=\"arc-disc-match-tag is-both\"><i class=\"fa-solid fa-check-double\"><\/i>Name + ${fmtNum(item.relevant_papers)} papers<\/span>`;\r\n\t\t}\r\n\t\tif (item.relevant_papers > 0) {\r\n\t\t\treturn `<span class=\"arc-disc-match-tag is-keyword\"><i class=\"fa-solid fa-flask\"><\/i>${fmtNum(item.relevant_papers)} matching papers<\/span>`;\r\n\t\t}\r\n\t\treturn '';\r\n\t}\r\n\r\n\t\/\/ \u2500\u2500 Render cards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\t\/\/ Small helper: build a metric pill row.\r\n\tfunction metric(icon, label, value) {\r\n\t\tif (!value && value !== 0) return '';\r\n\t\treturn `<span class=\"metric\"><i class=\"fa-solid ${icon}\"><\/i><strong>${fmtNum(value)}<\/strong> ${label}<\/span>`;\r\n\t}\r\n\r\n\tfunction renderAuthor(item) {\r\n\t\tconst profileEnabled = (typeof PROFILES_AUTHOR_ENABLED !== 'undefined') && !!PROFILES_AUTHOR_ENABLED;\r\n\t\tconst url  = getProfileUrl('author', item.id);\r\n\t\tconst init = (item.name || '?').charAt(0).toUpperCase();\r\n\r\n\t\tconst nameHtml = profileEnabled\r\n\t\t\t? `<a href=\"${url}\">${item.name}<\/a>`\r\n\t\t\t: item.name;\r\n\r\n\t\t\/\/ Claimed = a researcher verified ownership of this profile (ORCID).\r\n\t\t\/\/ A claimant-uploaded photo replaces the initial. Built with jQuery so the\r\n\t\t\/\/ URL is attribute-encoded rather than concatenated into markup.\r\n\t\tconst avatarHtml = item.photo\r\n\t\t\t? $('<div class=\"arc-disc-avatar has-photo\"><\/div>')\r\n\t\t\t\t.append($('<img alt=\"\" loading=\"lazy\">').attr('src', item.photo))\r\n\t\t\t\t.prop('outerHTML')\r\n\t\t\t: '<div class=\"arc-disc-avatar\">' + esc(init) + '<\/div>';\r\n\r\n\t\tconst claimedBadge = item.claimed\r\n\t\t\t? `<span class=\"arc-disc-claimed\" title=\"This profile has been claimed and verified by the researcher\"><i class=\"fa-solid fa-circle-check\" aria-hidden=\"true\"><\/i>D\u00e9clar\u00e9<\/span>`\r\n\t\t\t: '';\r\n\r\n\t\tconst metrics = [\r\n\t\t\tmetric('fa-file-lines', 'papers',    item.papers),\r\n\t\t\tmetric('fa-quote-right', 'r\u00e9f\u00e9rences', item.citations),\r\n\t\t\titem.hindex > 0 ? `<span class=\"metric\"><i class=\"fa-solid fa-chart-line\"><\/i>H-index <strong>${item.hindex}<\/strong><\/span>` : '',\r\n\t\t].filter(Boolean).join('');\r\n\r\n\t\treturn `\r\n\t\t\t<div class=\"arc-disc-card${profileEnabled ? ' is-linked' : ''}${item.claimed ? ' is-claimed' : ''}\" ${profileEnabled ? `data-url=\"${url}\"` : ''}>\r\n\t\t\t\t${avatarHtml}\r\n\t\t\t\t<div class=\"arc-disc-body-inner\">\r\n\t\t\t\t\t<h3 class=\"arc-disc-name\">${nameHtml}<\/h3>\r\n\t\t\t\t\t${claimedBadge}\r\n\t\t\t\t\t<div class=\"arc-disc-metrics\">${metrics}<\/div>\r\n\t\t\t\t\t${matchTag(item)}\r\n\t\t\t\t<\/div>\r\n\t\t\t\t${profileEnabled ? `<div class=\"arc-disc-action\"><a href=\"${url}\" class=\"btn-view\">Consulter le profil <i class=\"fa-solid fa-arrow-right\"><\/i><\/a><\/div>` : ''}\r\n\t\t\t<\/div>`;\r\n\t}\r\n\r\n\tfunction renderInstitution(item) {\r\n\t\tconst profileEnabled = (typeof PROFILES_INSTITUTION_ENABLED !== 'undefined') && !!PROFILES_INSTITUTION_ENABLED;\r\n\t\tconst url      = getProfileUrl('institution', item.id);\r\n\t\tconst location = [countryName(item.country), item.city].filter(Boolean).join(', ');\r\n\r\n\t\tconst nameHtml = profileEnabled ? `<a href=\"${url}\">${item.name}<\/a>` : item.name;\r\n\r\n\t\tconst metrics = [\r\n\t\t\tmetric('fa-file-lines',  'papers',    item.papers),\r\n\t\t\tmetric('fa-quote-right', 'r\u00e9f\u00e9rences', item.citations),\r\n\t\t\titem.authors > 0 ? metric('fa-users', 'auteurs', item.authors) : '',\r\n\t\t].filter(Boolean).join('');\r\n\r\n\t\treturn `\r\n\t\t\t<div class=\"arc-disc-card${profileEnabled ? ' is-linked' : ''}\" ${profileEnabled ? `data-url=\"${url}\"` : ''}>\r\n\t\t\t\t<div class=\"arc-disc-avatar is-institution\">\r\n\t\t\t\t\t<i class=\"fa-solid fa-building\"><\/i>\r\n\t\t\t\t<\/div>\r\n\t\t\t\t<div class=\"arc-disc-body-inner\">\r\n\t\t\t\t\t<h3 class=\"arc-disc-name\">${nameHtml}<\/h3>\r\n\t\t\t\t\t${location ? `<div class=\"arc-disc-location\"><i class=\"fa-solid fa-location-dot\"><\/i>${location}<\/div>` : ''}\r\n\t\t\t\t\t<div class=\"arc-disc-metrics\">${metrics}<\/div>\r\n\t\t\t\t\t${matchTag(item)}\r\n\t\t\t\t<\/div>\r\n\t\t\t\t${profileEnabled ? `<div class=\"arc-disc-action\"><a href=\"${url}\" class=\"btn-view\">Consulter le profil <i class=\"fa-solid fa-arrow-right\"><\/i><\/a><\/div>` : ''}\r\n\t\t\t<\/div>`;\r\n\t}\r\n\r\n\tfunction renderSponsor(item) {\r\n\t\tconst profileEnabled = (typeof PROFILES_SPONSOR_ENABLED !== 'undefined') && !!PROFILES_SPONSOR_ENABLED;\r\n\t\tconst url     = getProfileUrl('sponsor', item.id);\r\n\t\tconst nameHtml = profileEnabled ? `<a href=\"${url}\">${item.name}<\/a>` : item.name;\r\n\r\n\t\tconst metrics = [\r\n\t\t\tmetric('fa-file-lines',  'papers funded', item.papers),\r\n\t\t\tmetric('fa-quote-right', 'r\u00e9f\u00e9rences',     item.citations),\r\n\t\t].filter(Boolean).join('');\r\n\r\n\t\treturn `\r\n\t\t\t<div class=\"arc-disc-card${profileEnabled ? ' is-linked' : ''}\" ${profileEnabled ? `data-url=\"${url}\"` : ''}>\r\n\t\t\t\t<div class=\"arc-disc-avatar is-sponsor\">\r\n\t\t\t\t\t<i class=\"fa-solid fa-hand-holding-dollar\"><\/i>\r\n\t\t\t\t<\/div>\r\n\t\t\t\t<div class=\"arc-disc-body-inner\">\r\n\t\t\t\t\t<h3 class=\"arc-disc-name\">${nameHtml}<\/h3>\r\n\t\t\t\t\t<div class=\"arc-disc-metrics\">${metrics}<\/div>\r\n\t\t\t\t\t${matchTag(item)}\r\n\t\t\t\t<\/div>\r\n\t\t\t\t${profileEnabled ? `<div class=\"arc-disc-action\"><a href=\"${url}\" class=\"btn-view\">Consulter le profil <i class=\"fa-solid fa-arrow-right\"><\/i><\/a><\/div>` : ''}\r\n\t\t\t<\/div>`;\r\n\t}\r\n\r\n\tfunction renderItem(item) {\r\n\t\tif (item.type === 'institution') return renderInstitution(item);\r\n\t\tif (item.type === 'sponsor')     return renderSponsor(item);\r\n\t\treturn renderAuthor(item);\r\n\t}\r\n\r\n\t\/\/ \u2500\u2500 Pagination \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\tfunction renderPagination() {\r\n\t\tconst totalPages = Math.ceil(totalResults \/ perPage);\r\n\t\tif (totalPages <= 1) { $('#arc-discover-pagination').hide(); return; }\r\n\r\n\t\tconst prev = currentPage > 1;\r\n\t\tconst next = currentPage < totalPages;\r\n\r\n\t\t$('#arc-discover-pagination').html(`\r\n\t\t\t<button class=\"btn-pg\" id=\"arc-pg-prev\" ${prev ? '' : 'disabled'}>\r\n\t\t\t\t<i class=\"fa-solid fa-chevron-left fa-xs\"><\/i> Prev\r\n\t\t\t<\/button>\r\n\t\t\t<span class=\"pg-info\">Page ${currentPage} of ${totalPages.toLocaleString()}<\/span>\r\n\t\t\t<button class=\"btn-pg\" id=\"arc-pg-next\" ${next ? '' : 'disabled'}>\r\n\t\t\t\tNext <i class=\"fa-solid fa-chevron-right fa-xs\"><\/i>\r\n\t\t\t<\/button>\r\n\t\t`).show();\r\n\r\n\t\t$('#arc-pg-prev').on('click', function () {\r\n\t\t\tif (currentPage > 1) { currentPage--; doSearch(false); }\r\n\t\t});\r\n\t\t$('#arc-pg-next').on('click', function () {\r\n\t\t\tif (currentPage < totalPages) { currentPage++; doSearch(false); }\r\n\t\t});\r\n\t}\r\n\r\n\t\/\/ \u2500\u2500 Rendering \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\t\/\/ Split out of the AJAX success handler so the server-inlined first page\r\n\t\/\/ can render through exactly the same path.\r\n\tfunction renderResults(results, q) {\r\n\t\tconst items = results?.items || [];\r\n\t\ttotalResults = results?.total || 0;\r\n\r\n\t\tconst typeLabel = { author: 'author', institution: 'institution', sponsor: 'sponsor' }[currentType] || 'result';\r\n\t\tconst plural    = totalResults !== 1 ? typeLabel + 's' : typeLabel;\r\n\t\tconst prefix    = q.length >= 3 ? 'Found' : 'Showing';\r\n\t\tconst totalPages = Math.max(1, Math.ceil(totalResults \/ perPage));\r\n\t\tconst pageInfo   = totalPages > 1 ? ` <span class=\"summary-count-pill\">Page ${currentPage} of ${totalPages.toLocaleString()}<\/span>` : '';\r\n\t\t$('#arc-discover-summary')\r\n\t\t\t.html(`\r\n\t\t\t\t<span>${prefix} <strong>${totalResults.toLocaleString()}<\/strong> ${plural}${q.length >= 3 ? ` for \u201c${$('<span>').text(q).html()}\u201d` : ''}<\/span>\r\n\t\t\t\t${pageInfo}\r\n\t\t\t`)\r\n\t\t\t.show();\r\n\r\n\t\tif (items.length === 0) {\r\n\t\t\t$('#arc-discover-results').html(`\r\n\t\t\t\t<div class=\"arc-disc-state\">\r\n\t\t\t\t\t<i class=\"fa-regular fa-compass\"><\/i>\r\n\t\t\t\t\t<p><strong>No matches yet.<\/strong><br>Try a different name, broaden the search, or switch between name and research topic.<\/p>\r\n\t\t\t\t<\/div>`);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\tlet html = '';\r\n\t\titems.forEach(item => { html += renderItem(item); });\r\n\t\t$('#arc-discover-results').html(html);\r\n\t\trenderPagination();\r\n\t}\r\n\r\n\t\/\/ \u2500\u2500 AJAX \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\tfunction doSearch(resetPage) {\r\n\t\tconst q = $('#arc-discover-search').val().trim();\r\n\r\n\t\tif (resetPage) currentPage = 1;\r\n\t\tcurrentSearch = q;\r\n\t\tif (q.length > 0) pushState();\r\n\r\n\t\t\/\/ Server-inlined first page: render straight away and skip the round\r\n\t\t\/\/ trip entirely. Only valid for the untouched default view, and only\r\n\t\t\/\/ once \u2014 every later interaction goes through AJAX as normal.\r\n\t\tif (canUseBootstrap(q)) {\r\n\t\t\tbootstrapUsed = true;\r\n\t\t\trenderResults(BOOTSTRAP, q);\r\n\t\t\treturn;\r\n\t\t}\r\n\r\n\t\t\/\/ Skeleton loading tiles \u2014 a soft grid rather than a bare spinner. Keeps\r\n\t\t\/\/ the layout stable so cards don't visibly re-flow when data arrives.\r\n\t\tconst skeletonCount = Math.min(perPage, 9);\r\n\t\tlet skeletonHtml = '';\r\n\t\tfor (let i = 0; i < skeletonCount; i++) { skeletonHtml += '<div class=\"arc-disc-skeleton\"><\/div>'; }\r\n\t\t$('#arc-discover-results').html(skeletonHtml);\r\n\t\t$('#arc-discover-pagination').hide();\r\n\r\n\t\tconst reqData = {\r\n\t\t\taction:   'arc_ext_discover',\r\n\t\t\ttype:     currentType,\r\n\t\t\tmode:     currentMode,\r\n\t\t\tsort:     currentSort,\r\n\t\t\tper_page: perPage,\r\n\t\t\tpag:      currentPage,\r\n\t\t};\r\n\t\tif (q.length >= 3) reqData.search = q;\r\n\r\n\t\t$.ajax({\r\n\t\t\turl:    ajaxUrl,\r\n\t\t\tmethod: 'GET',\r\n\t\t\tdata:   reqData,\r\n\t\t\tsuccess: function (res) {\r\n\t\t\t\tif (!res || res.status !== 200) {\r\n\t\t\t\t\t$('#arc-discover-results').html(\r\n\t\t\t\t\t\t'<div class=\"arc-disc-state is-error\"><i class=\"fa-regular fa-circle-xmark\"><\/i><p>Search failed. Please try again.<\/p><\/div>'\r\n\t\t\t\t\t);\r\n\t\t\t\t\treturn;\r\n\t\t\t\t}\r\n\r\n\t\t\t\trenderResults(res.results, q);\r\n\t\t\t},\r\n\t\t\terror: function () {\r\n\t\t\t\t$('#arc-discover-results').html(\r\n\t\t\t\t\t'<div class=\"arc-disc-state is-error\"><i class=\"fa-solid fa-triangle-exclamation\"><\/i><p><strong>Connection error.<\/strong><br>Please check your network and try again.<\/p><\/div>'\r\n\t\t\t\t);\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t\/\/ Make the whole card clickable \u2014 but let inner <a> and <button> clicks\r\n\t\/\/ bubble to their own handlers so keyboard nav and open-in-new-tab still\r\n\t\/\/ work naturally.\r\n\t$(document).on('click', '.arc-disc-card.is-linked', function (e) {\r\n\t\tif ($(e.target).closest('a, button').length) return;\r\n\t\tconst url = $(this).data('url');\r\n\t\tif (url) window.location.href = url;\r\n\t});\r\n\r\n\t\/\/ \u2500\u2500 Event bindings \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\tfunction bindEvents() {\r\n\r\n\t\t\/\/ Type tab click \u2014 reload results for the new type. Always snap\r\n\t\t\/\/ currentSort back to the new type's default so switching tabs feels\r\n\t\t\/\/ consistent (and Sponsors, which don't support \"Recommended\", don't\r\n\t\t\/\/ leak a papers_desc fallback back into Authors after a round-trip).\r\n\t\t$(document).on('click', '.arc-disc-tab', function () {\r\n\t\t\t$('.arc-disc-tab').removeClass('active').attr('aria-selected', 'false');\r\n\t\t\t$(this).addClass('active').attr('aria-selected', 'true');\r\n\t\t\tcurrentType = $(this).data('type');\r\n\t\t\tconst opts  = SORT_OPTIONS[currentType] || SORT_OPTIONS.author;\r\n\t\t\tcurrentSort = opts[0].v;\r\n\t\t\trenderSortSelect();\r\n\t\t\tupdatePlaceholder();\r\n\t\t\tcloseSuggestions();\r\n\t\t\tdoSearch(true);\r\n\t\t});\r\n\r\n\t\t\/\/ Mode toggle\r\n\t\t$(document).on('change', 'input[name=\"arc-mode\"]', function () {\r\n\t\t\tcurrentMode = $(this).val();\r\n\t\t\tupdatePlaceholder();\r\n\t\t});\r\n\r\n\t\t\/\/ Sort dropdown\r\n\t\t$(document).on('change', '#arc-disc-sort-select', function () {\r\n\t\t\tcurrentSort = $(this).val();\r\n\t\t\tdoSearch(true);\r\n\t\t});\r\n\r\n\t\t\/\/ Search button\r\n\t\t$('#arc-discover-btn').on('click', function () { closeSuggestions(); doSearch(true); });\r\n\r\n\t\t\/\/ Typeahead on input. 100ms debounce balances \"instant\" feel against\r\n\t\t\/\/ firing one request per micro-keystroke; backend is prefix-indexed\r\n\t\t\/\/ + transient-cached so each request is sub-100ms once warm, and a\r\n\t\t\/\/ client-side per-prefix cache (suggestCache) makes retypes free.\r\n\t\t$('#arc-discover-search').on('input', function () {\r\n\t\t\tclearTimeout(suggestTimer);\r\n\t\t\tsuggestTimer = setTimeout(fetchSuggestions, 100);\r\n\t\t});\r\n\r\n\t\t\/\/ Keyboard: Enter, Escape, ArrowUp\/Down\r\n\t\t$('#arc-discover-search').on('keydown', function (e) {\r\n\t\t\tconst $items = $('.arc-disc-suggest-item');\r\n\t\t\tif (e.key === 'ArrowDown') {\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tnavigateSuggestions(1);\r\n\t\t\t} else if (e.key === 'ArrowUp') {\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\tnavigateSuggestions(-1);\r\n\t\t\t} else if (e.key === 'Enter') {\r\n\t\t\t\te.preventDefault();\r\n\t\t\t\t\/\/ If a suggestion is highlighted, open its profile (matches click behavior).\r\n\t\t\t\t\/\/ Otherwise, run a normal search against the typed term.\r\n\t\t\t\tif (suggestIdx >= 0 && $items.length) {\r\n\t\t\t\t\tconst id  = $items.eq(suggestIdx).data('id');\r\n\t\t\t\t\tconst url = getProfileUrl(currentType, id);\r\n\t\t\t\t\tcloseSuggestions();\r\n\t\t\t\t\twindow.location.href = url;\r\n\t\t\t\t} else {\r\n\t\t\t\t\tcloseSuggestions();\r\n\t\t\t\t\tdoSearch(true);\r\n\t\t\t\t}\r\n\t\t\t} else if (e.key === 'Escape') {\r\n\t\t\t\tcloseSuggestions();\r\n\t\t\t}\r\n\t\t});\r\n\r\n\t\t\/\/ Close suggestions on outside click\r\n\t\t$(document).on('mousedown', function (e) {\r\n\t\t\tif (!$(e.target).closest('#arc-disc-search-row').length) {\r\n\t\t\t\tcloseSuggestions();\r\n\t\t\t}\r\n\t\t});\r\n\t}\r\n\r\n\t\/\/ \u2500\u2500 Restore from URL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\tfunction restoreFromUrl() {\r\n\t\tconst p = getQueryParams();\r\n\r\n\t\tif (p.type && ['author','institution','sponsor'].includes(p.type)) {\r\n\t\t\tcurrentType = p.type;\r\n\t\t\t$('.arc-disc-tab').removeClass('active').attr('aria-selected', 'false');\r\n\t\t\t$(`.arc-disc-tab[data-type=\"${currentType}\"]`).addClass('active').attr('aria-selected', 'true');\r\n\t\t}\r\n\t\tif (p.mode && ['name','keyword'].includes(p.mode)) {\r\n\t\t\tcurrentMode = p.mode;\r\n\t\t\t$(`input[name=\"arc-mode\"][value=\"${currentMode}\"]`).prop('checked', true);\r\n\t\t}\r\n\t\tif (p.sort) {\r\n\t\t\t\/\/ Trust only whitelisted keys \u2014 renderSortSelect() below will\r\n\t\t\t\/\/ reset to the type's default if the URL key isn't valid.\r\n\t\t\tcurrentSort = p.sort;\r\n\t\t}\r\n\t\trenderSortSelect();\r\n\t\tif (p.per_page) perPage = Math.min(Math.max(parseInt(p.per_page, 10) || 25, 1), 100);\r\n\t\tif (p.pag)      currentPage = Math.max(parseInt(p.pag, 10) || 1, 1);\r\n\t\tif (p.search && p.search.length >= 3) {\r\n\t\t\t$('#arc-discover-search').val(p.search);\r\n\t\t}\r\n\t\tupdatePlaceholder();\r\n\t\tdoSearch(false);\r\n\t}\r\n\r\n\t\/\/ \u2500\u2500 Init \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\r\n\tbuildLayout();\r\n\tbindEvents();\r\n\tupdatePlaceholder();\r\n\trestoreFromUrl();\r\n\r\n});\r\n<\/script>\r\n<\/div>\n\t\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>D\u00e9couvrez les profils des institutions, des auteurs et des sponsors.<\/p>\n","protected":false},"author":2,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"_acf_changed":false,"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"class_list":["post-11134","page","type-page","status-publish","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/africaresearchconnects.com\/fr\/wp-json\/wp\/v2\/pages\/11134","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/africaresearchconnects.com\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/africaresearchconnects.com\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/africaresearchconnects.com\/fr\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/africaresearchconnects.com\/fr\/wp-json\/wp\/v2\/comments?post=11134"}],"version-history":[{"count":4,"href":"https:\/\/africaresearchconnects.com\/fr\/wp-json\/wp\/v2\/pages\/11134\/revisions"}],"predecessor-version":[{"id":15977,"href":"https:\/\/africaresearchconnects.com\/fr\/wp-json\/wp\/v2\/pages\/11134\/revisions\/15977"}],"wp:attachment":[{"href":"https:\/\/africaresearchconnects.com\/fr\/wp-json\/wp\/v2\/media?parent=11134"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}