{"id":465,"date":"2026-02-06T14:36:44","date_gmt":"2026-02-06T13:36:44","guid":{"rendered":"https:\/\/ingilog.com\/sugardelta_dev\/?page_id=465"},"modified":"2026-02-20T17:41:51","modified_gmt":"2026-02-20T16:41:51","slug":"mes-e-qsls","status":"publish","type":"page","link":"https:\/\/ingilog.com\/sugardelta_dev\/mes-e-qsls\/","title":{"rendered":"Mes E-QSLs"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"465\" class=\"elementor elementor-465\">\n\t\t\t\t<div class=\"elementor-element elementor-element-f6063de e-flex e-con-boxed wpr-particle-no wpr-jarallax-no wpr-parallax-no wpr-sticky-section-no wpr-column-slider-no wpr-equal-height-no e-con e-parent\" data-id=\"f6063de\" 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-593d7b4 elementor-widget elementor-widget-html\" data-id=\"593d7b4\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!-- ============================================================\n  eQSL \u2013 PAGE PRIV\u00c9E (utilisateurs connect\u00e9s)\n  \u00c0 coller dans un widget Elementor \"HTML\"\n  Requiert : PHP WPCode charg\u00e9, jQuery, eqslVars disponible\n============================================================ -->\n\n<style>\n\/* \u2500\u2500\u2500 Variables \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n:root {\n  --eq-bg:        #0d1117;\n  --eq-surface:   #161b22;\n  --eq-border:    #30363d;\n  --eq-accent:    #238636;\n  --eq-accent2:   #1f6feb;\n  --eq-danger:    #da3633;\n  --eq-text:      #e6edf3;\n  --eq-muted:     #8b949e;\n  --eq-radius:    8px;\n  --eq-shadow:    0 4px 24px rgba(0,0,0,0.4);\n}\n\n\/* \u2500\u2500\u2500 Reset scoped \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n#eqsl-private * { box-sizing: border-box; margin: 0; padding: 0; }\n\n#eqsl-private {\n  font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;\n  background: var(--eq-bg);\n  color: var(--eq-text);\n  min-height: 400px;\n  border-radius: var(--eq-radius);\n  padding: 24px;\n}\n\n\/* \u2500\u2500\u2500 En-t\u00eate \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.eqp-header {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  flex-wrap: wrap;\n  gap: 12px;\n  margin-bottom: 24px;\n  padding-bottom: 16px;\n  border-bottom: 1px solid var(--eq-border);\n}\n.eqp-header h2 {\n  font-size: 1.35rem;\n  font-weight: 600;\n  display: flex;\n  align-items: center;\n  gap: 10px;\n}\n.eqp-header h2 .dot {\n  width: 10px; height: 10px;\n  background: var(--eq-accent);\n  border-radius: 50%;\n  animation: pulse 2s infinite;\n}\n@keyframes pulse {\n  0%,100% { opacity:1; }\n  50%      { opacity:.3; }\n}\n\n\/* \u2500\u2500\u2500 Boutons \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.eqbtn {\n  display: inline-flex;\n  align-items: center;\n  gap: 7px;\n  padding: 8px 18px;\n  border-radius: var(--eq-radius);\n  border: none;\n  cursor: pointer;\n  font-size: .9rem;\n  font-weight: 500;\n  transition: filter .15s, transform .1s;\n}\n.eqbtn:active { transform: scale(.97); }\n.eqbtn:hover  { filter: brightness(1.12); }\n.eqbtn-primary  { background: var(--eq-accent);  color: #fff; }\n.eqbtn-blue     { background: var(--eq-accent2); color: #fff; }\n.eqbtn-danger   { background: var(--eq-danger);  color: #fff; }\n.eqbtn-ghost    { background: transparent; color: var(--eq-text); border: 1px solid var(--eq-border); }\n.eqbtn-sm       { padding: 5px 12px; font-size: .8rem; }\n\n\/* \u2500\u2500\u2500 Tableau liste \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.eqp-table-wrap {\n  overflow-x: auto;\n  border-radius: var(--eq-radius);\n  border: 1px solid var(--eq-border);\n}\n.eqp-table {\n  width: 100%;\n  border-collapse: collapse;\n  font-size: .88rem;\n}\n.eqp-table th {\n  background: var(--eq-surface);\n  color: var(--eq-muted);\n  font-weight: 500;\n  text-transform: uppercase;\n  font-size: .73rem;\n  letter-spacing: .05em;\n  padding: 10px 14px;\n  text-align: left;\n  border-bottom: 1px solid var(--eq-border);\n}\n.eqp-table td {\n  padding: 11px 14px;\n  border-bottom: 1px solid var(--eq-border);\n  vertical-align: middle;\n}\n.eqp-table tr:last-child td { border-bottom: none; }\n.eqp-table tbody tr {\n  cursor: pointer;\n  transition: background .12s;\n}\n.eqp-table tbody tr:hover { background: rgba(255,255,255,.04); }\n\n\/* Badges statut *\/\n.eqbadge {\n  display: inline-block;\n  padding: 3px 9px;\n  border-radius: 20px;\n  font-size: .75rem;\n  font-weight: 600;\n}\n.eqbadge-pending   { background: rgba(210,153,34,.2);  color: #d29922; border: 1px solid rgba(210,153,34,.4); }\n.eqbadge-completed { background: rgba(35,134,54,.2);   color: #3fb950; border: 1px solid rgba(35,134,54,.4); }\n\n\/* \u2500\u2500\u2500 Message vide \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.eqp-empty {\n  text-align: center;\n  padding: 48px 24px;\n  color: var(--eq-muted);\n  font-size: .95rem;\n}\n.eqp-empty svg { margin-bottom: 16px; opacity: .4; }\n\n\/* \u2500\u2500\u2500 Loading spinner \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.eqp-loading {\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  gap: 12px;\n  padding: 40px;\n  color: var(--eq-muted);\n}\n.eqp-spinner {\n  width: 22px; height: 22px;\n  border: 2px solid var(--eq-border);\n  border-top-color: var(--eq-accent);\n  border-radius: 50%;\n  animation: spin .7s linear infinite;\n}\n@keyframes spin { to { transform: rotate(360deg); } }\n\n\/* \u2500\u2500\u2500 Toast notification \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.eqp-toast {\n  position: fixed;\n  bottom: 28px;\n  right: 28px;\n  z-index: 99999;\n  max-width: 340px;\n  padding: 14px 20px;\n  border-radius: var(--eq-radius);\n  font-size: .88rem;\n  font-weight: 500;\n  box-shadow: var(--eq-shadow);\n  animation: slideIn .3s ease;\n  transition: opacity .3s;\n}\n.eqp-toast-success { background: #238636; color: #fff; }\n.eqp-toast-error   { background: #da3633; color: #fff; }\n@keyframes slideIn { from { transform: translateY(20px); opacity: 0; } }\n\n\/* \u2500\u2500\u2500 Modal overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.eqp-overlay {\n  position: fixed;\n  inset: 0;\n  background: rgba(0,0,0,.75);\n  backdrop-filter: blur(3px);\n  z-index: 9999;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  padding: 20px;\n  overflow-y: auto;\n}\n.eqp-overlay.hidden { display: none; }\n\n.eqp-modal {\n  background: var(--eq-surface);\n  border: 1px solid var(--eq-border);\n  border-radius: 12px;\n  width: 100%;\n  max-width: 620px;\n  box-shadow: var(--eq-shadow);\n  display: flex;\n  flex-direction: column;\n  max-height: 90vh;\n  overflow-y: auto;\n}\n.eqp-modal-lg { max-width: 820px; }\n\n.eqp-modal-head {\n  display: flex;\n  align-items: center;\n  justify-content: space-between;\n  padding: 18px 24px;\n  border-bottom: 1px solid var(--eq-border);\n  position: sticky;\n  top: 0;\n  background: var(--eq-surface);\n  z-index: 1;\n}\n.eqp-modal-head h3 { font-size: 1.05rem; font-weight: 600; }\n.eqp-modal-close {\n  background: none;\n  border: none;\n  color: var(--eq-muted);\n  cursor: pointer;\n  font-size: 1.4rem;\n  line-height: 1;\n  padding: 2px 6px;\n  border-radius: 4px;\n  transition: color .15s;\n}\n.eqp-modal-close:hover { color: var(--eq-text); }\n\n.eqp-modal-body { padding: 24px; }\n.eqp-modal-foot {\n  padding: 16px 24px;\n  border-top: 1px solid var(--eq-border);\n  display: flex;\n  gap: 10px;\n  justify-content: flex-end;\n  flex-wrap: wrap;\n  position: sticky;\n  bottom: 0;\n  background: var(--eq-surface);\n}\n\n\/* \u2500\u2500\u2500 Formulaire cr\u00e9ation eQSL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.eqp-form { display: flex; flex-direction: column; gap: 18px; }\n.eqp-form-row { display: grid; gap: 14px; }\n.eqp-form-row.cols-2 { grid-template-columns: 1fr 1fr; }\n.eqp-form-row.cols-3 { grid-template-columns: 1fr 1fr 1fr; }\n\n.eqp-field { display: flex; flex-direction: column; gap: 5px; }\n.eqp-field label {\n  font-size: .78rem;\n  font-weight: 500;\n  color: var(--eq-muted);\n  text-transform: uppercase;\n  letter-spacing: .05em;\n}\n.eqp-field input,\n.eqp-field select,\n.eqp-field textarea {\n  background: var(--eq-bg);\n  border: 1px solid var(--eq-border);\n  border-radius: var(--eq-radius);\n  color: var(--eq-text);\n  padding: 9px 12px;\n  font-size: .9rem;\n  outline: none;\n  transition: border-color .15s;\n  width: 100%;\n}\n.eqp-field input:focus,\n.eqp-field select:focus { border-color: var(--eq-accent2); box-shadow: 0 0 0 3px rgba(31,111,235,.2); }\n\n\/* \u2500\u2500\u2500 Grille de s\u00e9lection de template \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n.eqp-tpl-tabs {\n  display: flex;\n  gap: 4px;\n  margin-bottom: 14px;\n  background: var(--eq-bg);\n  padding: 4px;\n  border-radius: var(--eq-radius);\n  border: 1px solid var(--eq-border);\n}\n.eqp-tpl-tab {\n  flex: 1;\n  padding: 7px 12px;\n  background: none;\n  border: none;\n  color: var(--eq-muted);\n  cursor: pointer;\n  border-radius: 6px;\n  font-size: .83rem;\n  font-weight: 500;\n  transition: all .15s;\n}\n.eqp-tpl-tab.active {\n  background: var(--eq-surface);\n  color: var(--eq-text);\n  border: 1px solid var(--eq-border);\n}\n\n.eqp-tpl-grid {\n  display: grid;\n  grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));\n  gap: 12px;\n  max-height: 260px;\n  overflow-y: auto;\n  padding: 2px;\n}\n.eqp-tpl-item {\n  cursor: pointer;\n  border: 2px solid var(--eq-border);\n  border-radius: var(--eq-radius);\n  overflow: hidden;\n  transition: border-color .15s, box-shadow .15s;\n  position: relative;\n}\n.eqp-tpl-item:hover { border-color: var(--eq-accent2); }\n.eqp-tpl-item.selected { border-color: var(--eq-accent); box-shadow: 0 0 0 3px rgba(35,134,54,.3); }\n.eqp-tpl-item img {\n  width: 100%;\n  height: 100px;\n  object-fit: cover;\n  display: block;\n}\n.eqp-tpl-item .tpl-name {\n  padding: 6px 8px;\n  font-size: .75rem;\n  color: var(--eq-muted);\n  background: var(--eq-bg);\n  white-space: nowrap;\n  overflow: hidden;\n  text-overflow: ellipsis;\n}\n.eqp-tpl-item .tpl-del {\n  position: absolute;\n  top: 4px;\n  right: 4px;\n  background: rgba(218,54,51,.85);\n  color: #fff;\n  border: none;\n  border-radius: 4px;\n  width: 22px;\n  height: 22px;\n  font-size: .8rem;\n  cursor: pointer;\n  opacity: 0;\n  transition: opacity .15s;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n.eqp-tpl-item:hover .tpl-del { opacity: 1; }\n.eqp-tpl-item.selected::after {\n  content: '\u2713';\n  position: absolute;\n  top: 4px;\n  left: 4px;\n  background: var(--eq-accent);\n  color: #fff;\n  width: 22px;\n  height: 22px;\n  border-radius: 4px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  font-size: .8rem;\n  font-weight: 700;\n}\n\n\/* Upload zone *\/\n.eqp-upload-zone {\n  border: 2px dashed var(--eq-border);\n  border-radius: var(--eq-radius);\n  padding: 32px;\n  text-align: center;\n  cursor: pointer;\n  transition: border-color .15s, background .15s;\n}\n.eqp-upload-zone:hover {\n  border-color: var(--eq-accent2);\n  background: rgba(31,111,235,.05);\n}\n.eqp-upload-zone input { display: none; }\n\n\/* Aper\u00e7u de l'eQSL dans la popup de d\u00e9tail *\/\n.eqp-preview-wrap {\n  width: 100%;\n  border-radius: var(--eq-radius);\n  overflow: hidden;\n  border: 1px solid var(--eq-border);\n  margin-bottom: 16px;\n  background: var(--eq-bg);\n  min-height: 160px;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n.eqp-preview-wrap img { width: 100%; display: block; }\n\n\/* Info grid dans le d\u00e9tail *\/\n.eqp-info-grid {\n  display: grid;\n  grid-template-columns: 1fr 1fr;\n  gap: 10px 20px;\n  font-size: .88rem;\n  margin-bottom: 16px;\n}\n.eqp-info-grid dt { color: var(--eq-muted); font-size: .75rem; text-transform: uppercase; margin-bottom: 2px; }\n.eqp-info-grid dd { font-weight: 500; }\n\n\/* S\u00e9parateur section *\/\n.eqp-divider {\n  border: none;\n  border-top: 1px solid var(--eq-border);\n  margin: 16px 0;\n}\n\n@media (max-width:520px) {\n  .eqp-form-row.cols-2,\n  .eqp-form-row.cols-3 { grid-template-columns: 1fr; }\n  .eqp-info-grid { grid-template-columns: 1fr; }\n}\n<\/style>\n\n<div id=\"eqsl-private\">\n  <!-- En-t\u00eate -->\n  <div class=\"eqp-header\">\n    <h2><span class=\"dot\"><\/span>Mes eQSL<\/h2>\n    <button class=\"eqbtn eqbtn-primary\" id=\"eqp-btn-new\">\n      <svg width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path d=\"M12 5v14M5 12h14\"\/><\/svg>\n      \u00c9change d'eQSL\n    <\/button>\n  <\/div>\n\n  <!-- Corps liste -->\n  <div id=\"eqp-list-wrap\">\n    <div class=\"eqp-loading\">\n      <div class=\"eqp-spinner\"><\/div>Chargement...\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- \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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n     MODAL 1 \u2014 Cr\u00e9er une eQSL\n\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n<div class=\"eqp-overlay hidden\" id=\"eqp-overlay-create\">\n  <div class=\"eqp-modal eqp-modal-lg\">\n    <div class=\"eqp-modal-head\">\n      <h3>\ud83d\udce1 Nouvel \u00e9change d'eQSL<\/h3>\n      <button class=\"eqp-modal-close\" data-close=\"eqp-overlay-create\">\u00d7<\/button>\n    <\/div>\n    <div class=\"eqp-modal-body\">\n      <div class=\"eqp-form\">\n\n        <!-- Indicatif destinataire -->\n        <div class=\"eqp-field\">\n          <label>Indicatif du destinataire *<\/label>\n          <input type=\"text\" id=\"eqp-c-recipient\" placeholder=\"F4ABC\" style=\"text-transform:uppercase\">\n        <\/div>\n\n        <!-- S\u00e9lection template -->\n        <div>\n          <label style=\"font-size:.78rem;font-weight:500;color:var(--eq-muted);text-transform:uppercase;letter-spacing:.05em;display:block;margin-bottom:8px\">Template QSL *<\/label>\n          <div class=\"eqp-tpl-tabs\">\n            <button class=\"eqp-tpl-tab active\" data-tab=\"tpl-library\">\ud83d\udcc2 Mes templates<\/button>\n            <button class=\"eqp-tpl-tab\" data-tab=\"tpl-upload\">\u2b06 Ajouter un template<\/button>\n          <\/div>\n\n          <!-- Onglet biblioth\u00e8que -->\n          <div id=\"tpl-library\">\n            <div id=\"eqp-tpl-grid\" class=\"eqp-tpl-grid\">\n              <div class=\"eqp-loading\"><div class=\"eqp-spinner\"><\/div><\/div>\n            <\/div>\n            <p id=\"eqp-tpl-empty\" style=\"display:none;color:var(--eq-muted);font-size:.85rem;padding:16px 0\">\n              Aucun template. Uploadez-en un via l'onglet \"Ajouter\".\n            <\/p>\n          <\/div>\n\n          <!-- Onglet upload -->\n          <div id=\"tpl-upload\" style=\"display:none\">\n            <div class=\"eqp-form-row cols-2\" style=\"margin-bottom:12px\">\n              <div class=\"eqp-field\">\n                <label>Nom du template<\/label>\n                <input type=\"text\" id=\"eqp-new-tpl-name\" placeholder=\"Ma QSL 2024\">\n              <\/div>\n            <\/div>\n            <div class=\"eqp-upload-zone\" id=\"eqp-tpl-drop\">\n              <input type=\"file\" id=\"eqp-tpl-file\" accept=\"image\/jpeg,image\/png,image\/gif\">\n              <svg width=\"36\" height=\"36\" fill=\"none\" stroke=\"var(--eq-muted)\" stroke-width=\"1.5\" viewBox=\"0 0 24 24\"><path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M17 8l-5-5-5 5M12 3v12\"\/><\/svg>\n              <p style=\"color:var(--eq-muted);margin-top:10px;font-size:.88rem\">Glissez votre image ici ou <strong style=\"color:var(--eq-accent2)\">cliquez<\/strong><\/p>\n              <p style=\"color:var(--eq-muted);font-size:.76rem;margin-top:4px\">JPEG \u00b7 PNG \u00b7 GIF \u00b7 Max 5 Mo<\/p>\n              <p id=\"eqp-tpl-selected-name\" style=\"color:var(--eq-text);font-weight:500;margin-top:8px;display:none\"><\/p>\n            <\/div>\n            <button class=\"eqbtn eqbtn-blue\" style=\"margin-top:12px\" id=\"eqp-btn-upload-tpl\">\u2b06 Uploader ce template<\/button>\n          <\/div>\n\n          <input type=\"hidden\" id=\"eqp-c-template-id\" value=\"\">\n        <\/div>\n\n        <!-- Infos QSO -->\n        <div class=\"eqp-form-row cols-3\">\n          <div class=\"eqp-field\">\n            <label>Date *<\/label>\n            <input type=\"text\" id=\"eqp-c-date\" placeholder=\"DD\/MM\/YYYY\" maxlength=\"10\">\n          <\/div>\n          <div class=\"eqp-field\">\n            <label>Heure (HH:MM) *<\/label>\n            <input type=\"text\" id=\"eqp-c-time\" placeholder=\"14:32\" maxlength=\"5\">\n          <\/div>\n          <div class=\"eqp-field\">\n            <label>Fuseau *<\/label>\n            <select id=\"eqp-c-tz\">\n              <option value=\"UTC\">UTC<\/option>\n              <option value=\"UTC+1\">UTC+1<\/option>\n              <option value=\"UTC+2\">UTC+2<\/option>\n              <option value=\"UTC-1\">UTC-1<\/option>\n              <option value=\"UTC-5\">UTC-5<\/option>\n            <\/select>\n          <\/div>\n        <\/div>\n        <div class=\"eqp-form-row cols-3\">\n          <div class=\"eqp-field\">\n            <label>Fr\u00e9quence (MHz) *<\/label>\n            <input type=\"text\" id=\"eqp-c-freq\" placeholder=\"14.225\">\n          <\/div>\n          <div class=\"eqp-field\">\n            <label>Mode *<\/label>\n            <select id=\"eqp-c-mode\">\n              <option>SSB<\/option><option>CW<\/option><option>FT8<\/option><option>FT4<\/option>\n              <option>PSK31<\/option><option>RTTY<\/option><option>AM<\/option><option>FM<\/option>\n              <option>DMR<\/option><option>C4FM<\/option><option>DSTAR<\/option><option>Autre<\/option>\n            <\/select>\n          <\/div>\n          <div class=\"eqp-field\">\n            <label>Report RST *<\/label>\n            <input type=\"text\" id=\"eqp-c-report\" placeholder=\"59 \/ 599\">\n          <\/div>\n        <\/div>\n\n      <\/div>\n    <\/div>\n    <div class=\"eqp-modal-foot\">\n      <button class=\"eqbtn eqbtn-ghost\" data-close=\"eqp-overlay-create\">Annuler<\/button>\n      <button class=\"eqbtn eqbtn-ghost eqbtn-blue\" id=\"eqp-btn-generate-dl\">\n        <svg width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><path d=\"M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3\"\/><\/svg>\n        G\u00e9n\u00e9rer & T\u00e9l\u00e9charger\n      <\/button>\n      <button class=\"eqbtn eqbtn-primary\" id=\"eqp-btn-publish\">\n        <svg width=\"13\" height=\"13\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" viewBox=\"0 0 24 24\"><circle cx=\"12\" cy=\"12\" r=\"10\"\/><path d=\"M12 8v4l3 3\"\/><\/svg>\n        Mettre \u00e0 disposition\n      <\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<!-- \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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\n     MODAL 2 \u2014 D\u00e9tail d'une eQSL\n\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550 -->\n<div class=\"eqp-overlay hidden\" id=\"eqp-overlay-detail\">\n  <div class=\"eqp-modal eqp-modal-lg\">\n    <div class=\"eqp-modal-head\">\n      <h3 id=\"eqp-det-title\">D\u00e9tail eQSL<\/h3>\n      <button class=\"eqp-modal-close\" data-close=\"eqp-overlay-detail\">\u00d7<\/button>\n    <\/div>\n    <div class=\"eqp-modal-body\">\n      <div class=\"eqp-preview-wrap\" id=\"eqp-det-preview\">\n        <div class=\"eqp-spinner\"><\/div>\n      <\/div>\n      <dl class=\"eqp-info-grid\" id=\"eqp-det-info\"><\/dl>\n      <hr class=\"eqp-divider\" id=\"eqp-det-received-divider\" style=\"display:none\">\n      <div id=\"eqp-det-received-section\" style=\"display:none\">\n        <p style=\"font-size:.85rem;color:var(--eq-muted);margin-bottom:12px\">\n          \ud83d\udcec eQSL re\u00e7ue de <strong id=\"eqp-det-recv-callsign\"><\/strong> \u2014 expire le <strong id=\"eqp-det-recv-expires\"><\/strong>\n        <\/p>\n        <div style=\"display:flex;gap:10px;flex-wrap:wrap\">\n          <button class=\"eqbtn eqbtn-blue eqbtn-sm\" id=\"eqp-btn-dl-received\">\u2b07 T\u00e9l\u00e9charger l'eQSL re\u00e7ue<\/button>\n          <button class=\"eqbtn eqbtn-danger eqbtn-sm\" id=\"eqp-btn-del-received\">\ud83d\uddd1 Supprimer<\/button>\n        <\/div>\n      <\/div>\n    <\/div>\n    <div class=\"eqp-modal-foot\">\n      <button class=\"eqbtn eqbtn-danger eqbtn-sm\" id=\"eqp-btn-del-card\">\ud83d\uddd1 Supprimer cette eQSL<\/button>\n      <button class=\"eqbtn eqbtn-ghost\" data-close=\"eqp-overlay-detail\">Fermer<\/button>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n(function($) {\n  'use strict';\n\n  \/\/ Variables WP inject\u00e9es par PHP\n  const AJAX = (typeof eqslVars !== 'undefined') ? eqslVars.ajaxUrl : '\/wp-admin\/admin-ajax.php';\n  const NONCE = (typeof eqslVars !== 'undefined') ? eqslVars.nonce : '';\n\n  let selectedTemplateId = null;\n  let currentCardId      = null;\n  let currentCard        = null;\n  let templatesCache     = null;\n\n  \/* \u2500\u2500 Utilitaires \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  function toast(msg, type='success') {\n    const el = $('<div class=\"eqp-toast eqp-toast-'+ type +'\">' + msg + '<\/div>').appendTo('body');\n    setTimeout(() => el.animate({opacity:0}, 300, () => el.remove()), 3500);\n  }\n\n  function openModal(id)  { $('#'+id).removeClass('hidden'); $('body').css('overflow','hidden'); }\n  function closeModal(id) { $('#'+id).addClass('hidden');    $('body').css('overflow',''); }\n\n  function formatDate(dateStr) {\n    \/\/ YYYY-MM-DD \u2192 DD\/MM\/YYYY\n    if (!dateStr) return '';\n    const p = dateStr.split('-');\n    return p.length === 3 ? p[2]+'\/'+p[1]+'\/'+p[0] : dateStr;\n  }\n\n  \/* \u2500\u2500 Fermer modals \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  $(document).on('click', '[data-close]', function() {\n    closeModal($(this).data('close'));\n  });\n  $(document).on('click', '.eqp-overlay', function(e) {\n    if ($(e.target).hasClass('eqp-overlay')) closeModal($(this).attr('id'));\n  });\n\n  \/* \u2500\u2500 Onglets template \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  $(document).on('click', '.eqp-tpl-tab', function() {\n    const tab = $(this).data('tab');\n    $('.eqp-tpl-tab').removeClass('active');\n    $(this).addClass('active');\n    $('#tpl-library, #tpl-upload').hide();\n    $('#'+tab).show();\n  });\n\n  \/* \u2500\u2500 Charger la liste des eQSL \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  function loadMyCards() {\n    $('#eqp-list-wrap').html('<div class=\"eqp-loading\"><div class=\"eqp-spinner\"><\/div> Chargement...<\/div>');\n    $.post(AJAX, { action:'eqsl_get_my_cards', nonce:NONCE }, function(r) {\n      if (!r.success) { $('#eqp-list-wrap').html('<p style=\"color:var(--eq-danger);padding:20px\">Erreur de chargement<\/p>'); return; }\n      const cards = r.data;\n      if (!cards.length) {\n        $('#eqp-list-wrap').html(`\n          <div class=\"eqp-empty\">\n            <svg width=\"48\" height=\"48\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"1.2\" viewBox=\"0 0 24 24\"><rect x=\"4\" y=\"4\" width=\"16\" height=\"12\" rx=\"2\"\/><path d=\"M8 20h8M12 16v4\"\/><\/svg>\n            <p>Vous n'avez pas encore envoy\u00e9 d'eQSL.<br>Cliquez sur \"\u00c9change d'eQSL\" pour commencer.<\/p>\n          <\/div>`);\n        return;\n      }\n      let rows = '';\n      cards.forEach(c => {\n        const badge = c.status === 'completed'\n          ? '<span class=\"eqbadge eqbadge-completed\">\u2713 Compl\u00e9t\u00e9<\/span>'\n          : '<span class=\"eqbadge eqbadge-pending\">\u23f3 En attente<\/span>';\n        rows += `<tr data-id=\"${c.id}\">\n          <td><strong>${c.recipient_callsign}<\/strong><\/td>\n          <td>${formatDate(c.qso_date)} ${c.qso_time} ${c.timezone}<\/td>\n          <td>${c.frequency} MHz<\/td>\n          <td>${c.mode}<\/td>\n          <td>${c.report}<\/td>\n          <td>${badge}<\/td>\n        <\/tr>`;\n      });\n      $('#eqp-list-wrap').html(`\n        <div class=\"eqp-table-wrap\">\n          <table class=\"eqp-table\">\n            <thead><tr>\n              <th>Destinataire<\/th><th>Date \/ Heure<\/th><th>Fr\u00e9quence<\/th>\n              <th>Mode<\/th><th>RST<\/th><th>Statut<\/th>\n            <\/tr><\/thead>\n            <tbody>${rows}<\/tbody>\n          <\/table>\n        <\/div>`);\n    });\n  }\n\n  \/* \u2500\u2500 Charger les templates \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  function loadTemplates(forceRefresh) {\n    if (templatesCache && !forceRefresh) { renderTemplates(templatesCache); return; }\n    $('#eqp-tpl-grid').html('<div class=\"eqp-loading\"><div class=\"eqp-spinner\"><\/div><\/div>');\n    $.post(AJAX, { action:'eqsl_get_templates', nonce:NONCE }, function(r) {\n      if (!r.success) return;\n      templatesCache = r.data;\n      renderTemplates(r.data);\n    });\n  }\n\n  function renderTemplates(templates) {\n    if (!templates.length) {\n      $('#eqp-tpl-grid').hide();\n      $('#eqp-tpl-empty').show();\n      return;\n    }\n    $('#eqp-tpl-empty').hide();\n    $('#eqp-tpl-grid').show();\n    let html = '';\n    templates.forEach(t => {\n      html += `<div class=\"eqp-tpl-item\" data-id=\"${t.id}\">\n        <img decoding=\"async\" src=\"${t.preview_url}\" alt=\"${t.name}\" loading=\"lazy\">\n        <div class=\"tpl-name\">${t.name}<\/div>\n        <button class=\"tpl-del\" data-del-tpl=\"${t.id}\" title=\"Supprimer\">\u2715<\/button>\n      <\/div>`;\n    });\n    $('#eqp-tpl-grid').html(html);\n    \/\/ Re-s\u00e9lectionner si un template \u00e9tait s\u00e9lectionn\u00e9\n    if (selectedTemplateId) {\n      $('#eqp-tpl-grid [data-id=\"'+selectedTemplateId+'\"]').addClass('selected');\n    }\n  }\n\n  \/* \u2500\u2500 S\u00e9lection template \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  $(document).on('click', '.eqp-tpl-item', function(e) {\n    if ($(e.target).closest('.tpl-del').length) return;\n    selectedTemplateId = $(this).data('id');\n    $('#eqp-c-template-id').val(selectedTemplateId);\n    $('.eqp-tpl-item').removeClass('selected');\n    $(this).addClass('selected');\n  });\n\n  \/* \u2500\u2500 Supprimer template \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  $(document).on('click', '.tpl-del', function(e) {\n    e.stopPropagation();\n    const id = $(this).data('del-tpl');\n    if (!confirm('Supprimer ce template ?')) return;\n    $.post(AJAX, { action:'eqsl_delete_template', nonce:NONCE, id:id }, function(r) {\n      if (r.success) {\n        templatesCache = null;\n        if (selectedTemplateId == id) {\n          selectedTemplateId = null;\n          $('#eqp-c-template-id').val('');\n        }\n        loadTemplates(true);\n        toast('Template supprim\u00e9');\n      } else {\n        toast(r.data || 'Erreur', 'error');\n      }\n    });\n  });\n\n  \/* \u2500\u2500 Zone drag & drop upload template \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  $('#eqp-tpl-drop').on('click', function(e) {\n    \/\/ \u00c9viter la r\u00e9cursion infinie : le clic sur l'input remonte sur le div\n    if ($(e.target).is('input[type=\"file\"]')) return;\n    e.stopPropagation();\n    document.getElementById('eqp-tpl-file').click();\n  });\n  $('#eqp-tpl-drop').on('dragover', function(e) { e.preventDefault(); $(this).css('border-color','var(--eq-accent)'); });\n  $('#eqp-tpl-drop').on('dragleave', function() { $(this).css('border-color','var(--eq-border)'); });\n  $('#eqp-tpl-drop').on('drop', function(e) {\n    e.preventDefault();\n    $(this).css('border-color','var(--eq-border)');\n    const file = e.originalEvent.dataTransfer.files[0];\n    if (file) {\n      const dt = new DataTransfer();\n      dt.items.add(file);\n      document.getElementById('eqp-tpl-file').files = dt.files;\n      $('#eqp-tpl-selected-name').text('\ud83d\udcce '+file.name).show();\n    }\n  });\n  $('#eqp-tpl-file').on('change', function() {\n    if (this.files[0]) $('#eqp-tpl-selected-name').text('\ud83d\udcce '+this.files[0].name).show();\n  });\n\n  \/* \u2500\u2500 Upload nouveau template (XHR natif \u2014 \u00e9vite les\n       interf\u00e9rences de jQuery\/Elementor avec FormData) \u2500\u2500 *\/\n  $('#eqp-btn-upload-tpl').on('click', function() {\n    const fileInput = document.getElementById('eqp-tpl-file');\n    const file      = fileInput.files[0];\n    if (!file) { toast('S\u00e9lectionnez un fichier image', 'error'); return; }\n    const name = $('#eqp-new-tpl-name').val().trim() || file.name.replace(\/\\.[^.]+$\/, '');\n    const btn  = $(this).text('\u23f3 Upload...').prop('disabled', true);\n\n    const fd = new FormData();\n    fd.append('action',        'eqsl_upload_template');\n    fd.append('nonce',         NONCE);\n    fd.append('template_name', name);\n    fd.append('template_file', file, file.name);\n\n    const xhr = new XMLHttpRequest();\n    xhr.open('POST', AJAX, true);\n    xhr.withCredentials = true;\n\n    xhr.onload = function() {\n      btn.text('\u2b06 Uploader ce template').prop('disabled', false);\n      try {\n        const r = JSON.parse(xhr.responseText);\n        if (r.success) {\n          templatesCache = null;\n          toast('Template \"' + name + '\" ajout\u00e9 !');\n          $('#eqp-new-tpl-name').val('');\n          fileInput.value = '';\n          $('#eqp-tpl-selected-name').hide();\n          $('.eqp-tpl-tab[data-tab=\"tpl-library\"]').click();\n          loadTemplates(true);\n        } else {\n          toast(r.data || 'Erreur upload', 'error');\n        }\n      } catch(err) {\n        \/\/ Afficher les 200 premiers caract\u00e8res de la r\u00e9ponse pour debug\n        toast('R\u00e9ponse inattendue : ' + xhr.responseText.substring(0, 200), 'error');\n      }\n    };\n\n    xhr.onerror = function() {\n      btn.text('\u2b06 Uploader ce template').prop('disabled', false);\n      toast('Erreur r\u00e9seau', 'error');\n    };\n\n    xhr.send(fd);\n  });\n\n  \/* \u2500\u2500 Ouvrir modal cr\u00e9ation \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  $('#eqp-btn-new').on('click', function() {\n    selectedTemplateId = null;\n    $('#eqp-c-template-id').val('');\n    $('#eqp-c-recipient').val('');\n    $('#eqp-c-date,#eqp-c-time,#eqp-c-freq,#eqp-c-report').val('');\n    openModal('eqp-overlay-create');\n    loadTemplates(false);\n  });\n\n  \/* \u2500\u2500 Soumission formulaire (g\u00e9n\u00e9rer ou publier) \u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  function getFormData() {\n    return {\n      recipient_callsign: $('#eqp-c-recipient').val().trim().toUpperCase(),\n      template_id: $('#eqp-c-template-id').val(),\n      qso_date: $('#eqp-c-date').val().trim(),\n      qso_time: $('#eqp-c-time').val().trim(),\n      timezone:  $('#eqp-c-tz').val(),\n      frequency: $('#eqp-c-freq').val().trim(),\n      mode:      $('#eqp-c-mode').val(),\n      report:    $('#eqp-c-report').val().trim(),\n    };\n  }\n\n  function validateForm(d) {\n    if (!d.recipient_callsign) return 'Indicatif destinataire manquant';\n    if (!d.template_id)       return 'S\u00e9lectionnez un template QSL';\n    if (!\/^\\d{2}\\\/\\d{2}\\\/\\d{4}$\/.test(d.qso_date)) return 'Date invalide (DD\/MM\/YYYY)';\n    if (!\/^\\d{2}:\\d{2}$\/.test(d.qso_time)) return 'Heure invalide (HH:MM)';\n    if (!d.frequency) return 'Fr\u00e9quence manquante';\n    if (!d.report)    return 'Report manquant';\n    return null;\n  }\n\n  \/\/ G\u00e9n\u00e9rer & t\u00e9l\u00e9charger\n  $('#eqp-btn-generate-dl').on('click', function() {\n    const d = getFormData();\n    const err = validateForm(d);\n    if (err) { toast(err, 'error'); return; }\n    const btn = $(this).text('\u23f3 G\u00e9n\u00e9ration...').prop('disabled', true);\n    $.post(AJAX, { action:'eqsl_create_card', nonce:NONCE, ...d, action_type:'download' }, function(r) {\n      btn.text('\u2b07 G\u00e9n\u00e9rer & T\u00e9l\u00e9charger').prop('disabled', false);\n      if (r.success && r.data.download) {\n        \/\/ D\u00e9clencher le t\u00e9l\u00e9chargement\n        const a = document.createElement('a');\n        a.href = 'data:image\/jpeg;base64,' + r.data.image_b64;\n        a.download = r.data.filename;\n        a.click();\n        toast('eQSL g\u00e9n\u00e9r\u00e9e et t\u00e9l\u00e9charg\u00e9e !');\n      } else {\n        toast(r.data || 'Erreur de g\u00e9n\u00e9ration', 'error');\n      }\n    }).fail(() => { btn.text('\u2b07 G\u00e9n\u00e9rer & T\u00e9l\u00e9charger').prop('disabled', false); toast('Erreur r\u00e9seau', 'error'); });\n  });\n\n  \/\/ Mettre \u00e0 disposition\n  $('#eqp-btn-publish').on('click', function() {\n    const d = getFormData();\n    const err = validateForm(d);\n    if (err) { toast(err, 'error'); return; }\n    const btn = $(this).text('\u23f3 Publication...').prop('disabled', true);\n    $.post(AJAX, { action:'eqsl_create_card', nonce:NONCE, ...d, action_type:'publish' }, function(r) {\n      btn.text('Mettre \u00e0 disposition').prop('disabled', false);\n      if (r.success) {\n        toast('eQSL mise \u00e0 disposition ! \u2713');\n        closeModal('eqp-overlay-create');\n        loadMyCards();\n      } else {\n        toast(r.data || 'Erreur', 'error');\n      }\n    }).fail(() => { btn.text('Mettre \u00e0 disposition').prop('disabled', false); toast('Erreur r\u00e9seau', 'error'); });\n  });\n\n  \/* \u2500\u2500 Clic sur ligne \u2192 modal d\u00e9tail \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  $(document).on('click', '.eqp-table tbody tr', function() {\n    currentCardId = parseInt($(this).data('id'));\n    openDetailModal(currentCardId);\n  });\n\n  function openDetailModal(cardId) {\n    \/\/ Chercher la carte dans les donn\u00e9es charg\u00e9es\n    $.post(AJAX, { action:'eqsl_get_my_cards', nonce:NONCE }, function(r) {\n      if (!r.success) return;\n      const card = r.data.find(c => c.id == cardId);\n      if (!card) return;\n      currentCard = card;\n\n      $('#eqp-det-title').text('\ud83d\udce1 eQSL \u2192 ' + card.recipient_callsign);\n\n      \/\/ Aper\u00e7u image\n      const previewUrl = AJAX + '?action=eqsl_preview&card_id='+cardId+'&nonce='+NONCE;\n      $('#eqp-det-preview').html('<img decoding=\"async\" src=\"'+ previewUrl +'\" alt=\"Aper\u00e7u eQSL\">');\n\n      \/\/ Infos\n      $('#eqp-det-info').html(`\n        <div><dt>Destinataire<\/dt><dd>${card.recipient_callsign}<\/dd><\/div>\n        <div><dt>Date<\/dt><dd>${formatDate(card.qso_date)}<\/dd><\/div>\n        <div><dt>Heure<\/dt><dd>${card.qso_time} ${card.timezone}<\/dd><\/div>\n        <div><dt>Fr\u00e9quence<\/dt><dd>${card.frequency} MHz<\/dd><\/div>\n        <div><dt>Mode<\/dt><dd>${card.mode}<\/dd><\/div>\n        <div><dt>Report<\/dt><dd>${card.report}<\/dd><\/div>\n        <div><dt>Statut<\/dt><dd>${card.status === 'completed'\n          ? '<span class=\"eqbadge eqbadge-completed\">\u2713 Compl\u00e9t\u00e9<\/span>'\n          : '<span class=\"eqbadge eqbadge-pending\">\u23f3 En attente<\/span>'}<\/dd><\/div>\n        <div><dt>Envoy\u00e9 le<\/dt><dd>${card.created_at ? card.created_at.split(' ')[0] : ''}<\/dd><\/div>\n      `);\n\n      \/\/ Section eQSL re\u00e7ue\n      if (card.status === 'completed' && card.received_id) {\n        const exp = card.expires_at ? formatDate(card.expires_at.split(' ')[0]) : 'N\/A';\n        $('#eqp-det-recv-callsign').text(card.recipient_callsign);\n        $('#eqp-det-recv-expires').text(exp);\n        $('#eqp-det-received-divider, #eqp-det-received-section').show();\n      } else {\n        $('#eqp-det-received-divider, #eqp-det-received-section').hide();\n      }\n\n      openModal('eqp-overlay-detail');\n    });\n  }\n\n  \/\/ T\u00e9l\u00e9charger eQSL re\u00e7ue\n  $('#eqp-btn-dl-received').on('click', function() {\n    if (!currentCardId) return;\n    window.location.href = AJAX + '?action=eqsl_download_received&card_id='+currentCardId+'&nonce='+NONCE;\n  });\n\n  \/\/ Supprimer eQSL re\u00e7ue\n  $('#eqp-btn-del-received').on('click', function() {\n    if (!confirm('Supprimer l\\'eQSL re\u00e7ue ? L\\'\u00e9change repassera en \"En attente\".')) return;\n    $.post(AJAX, { action:'eqsl_delete_received', nonce:NONCE, card_id:currentCardId }, function(r) {\n      if (r.success) {\n        toast('eQSL re\u00e7ue supprim\u00e9e');\n        closeModal('eqp-overlay-detail');\n        loadMyCards();\n      } else toast(r.data || 'Erreur', 'error');\n    });\n  });\n\n  \/\/ Supprimer l'eQSL \u00e9mise\n  $('#eqp-btn-del-card').on('click', function() {\n    if (!confirm('Supprimer d\u00e9finitivement cette eQSL ? Elle ne sera plus accessible par le destinataire.')) return;\n    $.post(AJAX, { action:'eqsl_delete_card', nonce:NONCE, card_id:currentCardId }, function(r) {\n      if (r.success) {\n        toast('eQSL supprim\u00e9e');\n        closeModal('eqp-overlay-detail');\n        loadMyCards();\n      } else toast(r.data || 'Erreur', 'error');\n    });\n  });\n\n  \/* \u2500\u2500 Auto-format date DD\/MM\/YYYY \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  $('#eqp-c-date').on('input', function() {\n    let v = $(this).val().replace(\/\\D\/g,'');\n    if (v.length > 2) v = v.slice(0,2)+'\/'+v.slice(2);\n    if (v.length > 5) v = v.slice(0,5)+'\/'+v.slice(5,9);\n    $(this).val(v);\n  });\n\n  \/* \u2500\u2500 Auto-format heure HH:MM \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 *\/\n  $('#eqp-c-time').on('input', function() {\n    let v = $(this).val().replace(\/\\D\/g,'');\n    if (v.length > 2) v = v.slice(0,2)+':'+v.slice(2,4);\n    $(this).val(v);\n  });\n\n  \/* \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 *\/\n  $(document).ready(function() {\n    if (typeof eqslVars !== 'undefined' && eqslVars.isLoggedIn === '1') {\n      loadMyCards();\n    } else {\n      $('#eqp-list-wrap').html('<div class=\"eqp-empty\"><p>\ud83d\udd12 Vous devez \u00eatre connect\u00e9 pour acc\u00e9der \u00e0 cette page.<\/p><\/div>');\n      $('#eqp-btn-new').hide();\n    }\n  });\n\n})(jQuery);\n<\/script>\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>Mes eQSL \u00c9change d&#8217;eQSL Chargement&#8230; \ud83d\udce1 Nouvel \u00e9change d&#8217;eQSL \u00d7 Indicatif du destinataire * Template QSL * \ud83d\udcc2 Mes templates \u2b06 Ajouter un template Aucun template. Uploadez-en un via l&#8217;onglet &#8220;Ajouter&#8221;. Nom du template Glissez votre image ici ou cliquez JPEG \u00b7 PNG \u00b7 GIF \u00b7 Max 5 Mo \u2b06 Uploader ce template Date * Heure (HH:MM) * Fuseau * UTCUTC+1UTC+2UTC-1UTC-5 Fr\u00e9quence (MHz) * Mode * SSBCWFT8FT4PSK31RTTYAMFMDMRC4FMDSTARAutre Report RST * Annuler G\u00e9n\u00e9rer &#038; T\u00e9l\u00e9charger Mettre \u00e0 disposition D\u00e9tail eQSL \u00d7 \ud83d\udcec eQSL re\u00e7ue de \u2014 expire le \u2b07 T\u00e9l\u00e9charger l&#8217;eQSL re\u00e7ue \ud83d\uddd1 Supprimer \ud83d\uddd1 Supprimer cette eQSL Fermer<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-465","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ingilog.com\/sugardelta_dev\/wp-json\/wp\/v2\/pages\/465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ingilog.com\/sugardelta_dev\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ingilog.com\/sugardelta_dev\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ingilog.com\/sugardelta_dev\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ingilog.com\/sugardelta_dev\/wp-json\/wp\/v2\/comments?post=465"}],"version-history":[{"count":23,"href":"https:\/\/ingilog.com\/sugardelta_dev\/wp-json\/wp\/v2\/pages\/465\/revisions"}],"predecessor-version":[{"id":540,"href":"https:\/\/ingilog.com\/sugardelta_dev\/wp-json\/wp\/v2\/pages\/465\/revisions\/540"}],"wp:attachment":[{"href":"https:\/\/ingilog.com\/sugardelta_dev\/wp-json\/wp\/v2\/media?parent=465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}