{"id":12,"date":"2026-09-18T14:54:28","date_gmt":"2026-09-18T14:54:28","guid":{"rendered":"https:\/\/ribo.my-sit.fr\/?page_id=12"},"modified":"2026-09-18T15:34:21","modified_gmt":"2026-09-18T15:34:21","slug":"home","status":"publish","type":"page","link":"https:\/\/ribo.my-sit.fr\/","title":{"rendered":"Home"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"12\" class=\"elementor elementor-12\" data-elementor-post-type=\"page\">\n\t\t\t\t<div class=\"elementor-element elementor-element-b2d25c4 e-con e-atomic-element e-flexbox-base e-25ff6b7 \" data-id=\"b2d25c4\" data-element_type=\"e-flexbox\" data-e-type=\"e-flexbox\" data-interaction-id=\"b2d25c4\" data-e-type=\"e-flexbox\" data-id=\"b2d25c4\">\n    \t\t<div class=\"elementor-element elementor-element-374fd6e elementor-widget elementor-widget-html\" data-id=\"374fd6e\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<!DOCTYPE html>\n<html lang=\"fr\">\n<head>\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n<title>Ribeauvill\u00e9 \u00b7 Riquewihr \u2014 Circuits & d\u00e9couvertes<\/title>\n<link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/leaflet\/1.9.4\/leaflet.min.css\" \/>\n<style>\n  :root{\n    --bg:#faf8f2;\n    --surface:#ffffff;\n    --ink:#262220;\n    --ink-soft:#5b5650;\n    --border:#e4dfd4;\n    --wine:#7a2e3a; --wine-soft:#f3e6e8;\n    --vine:#4f6d45; --vine-soft:#e7ede2;\n    --gold:#a8781f; --gold-soft:#f4ead4;\n    --slate:#3f5b67; --slate-soft:#e2ebed;\n    --trace:#2563eb;\n    --radius:20px;\n  }\n  *{box-sizing:border-box;}\n  html,body{margin:0;padding:0;}\n  body{\n    background:var(--bg);\n    color:var(--ink);\n    font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif;\n    line-height:1.5;\n  }\n  h1,h2{ font-family:\"Iowan Old Style\",\"Palatino Linotype\",Georgia,serif; font-weight:600; margin:0; }\n  .wrap{ max-width:760px; margin:0 auto; padding:22px 16px 40px; }\n  .intro{ margin-bottom:14px; }\n  .intro h1{ font-size:22px; }\n  .intro p{ margin:4px 0 0; font-size:13.5px; color:var(--ink-soft); }\n\n  .appshell{\n    background:var(--surface);\n    border:1px solid var(--border);\n    border-radius:var(--radius);\n    box-shadow:0 12px 32px rgba(38,34,32,.10);\n    overflow:hidden;\n    display:flex;\n    flex-direction:column;\n    height:clamp(560px, 82vh, 740px);\n  }\n\n  .app-header{ padding:14px 16px 10px; border-bottom:1px solid var(--border); }\n  .search-row{ position:relative; }\n  .search-row svg{ position:absolute; left:13px; top:50%; transform:translateY(-50%); width:17px; height:17px; color:var(--ink-soft); pointer-events:none; }\n  .search-row input{\n    width:100%; padding:10px 14px 10px 38px; border-radius:999px; border:1px solid var(--border);\n    background:var(--bg); font-size:14px; color:var(--ink); font-family:inherit;\n  }\n  .search-row input:focus{ outline:2px solid var(--wine); outline-offset:1px; }\n\n  .pills{ display:flex; gap:8px; overflow-x:auto; margin-top:10px; padding-bottom:2px; scrollbar-width:none; }\n  .pills::-webkit-scrollbar{ display:none; }\n  .pill{\n    flex:0 0 auto; display:inline-flex; align-items:center; gap:6px;\n    border:1px solid var(--border); background:var(--surface); color:var(--ink-soft);\n    padding:7px 14px 7px 10px; border-radius:999px; font-size:13.5px; cursor:pointer;\n    transition:background .15s, border-color .15s, color .15s;\n  }\n  .pill svg{ width:16px; height:16px; flex:0 0 auto; }\n  .pill:hover{ border-color:var(--ink-soft); }\n  .pill.active{ color:#fff; border-color:transparent; }\n\n  .stage{ position:relative; flex:1; overflow:hidden; background:#eee; }\n  .stage-map{ position:absolute; inset:0; display:none; }\n  .stage.mode-map .stage-map{ display:block; }\n  #map{ height:100%; width:100%; }\n\n  .stage-list{ position:absolute; inset:0; overflow-y:auto; padding:14px 16px 96px; background:var(--surface); display:none; }\n  .stage.mode-list .stage-list{ display:block; }\n\n  .map-empty{\n    position:absolute; inset:0; display:none; align-items:center; justify-content:center;\n    background:rgba(250,248,242,.92); z-index:350; text-align:center; padding:0 30px;\n  }\n  .map-empty.visible{ display:flex; }\n  .map-empty p{ margin:0; font-size:13.5px; color:var(--ink-soft); max-width:280px; }\n\n  .pin{ border-radius:50%; border:2px solid #fff; box-shadow:0 1px 5px rgba(0,0,0,.4); display:flex; align-items:center; justify-content:center; }\n  .pin svg{ width:60%; height:60%; color:#fff; }\n  .leaflet-popup-content-wrapper{ border-radius:10px; }\n\n  .locate-btn{\n    position:absolute; right:14px; bottom:70px; width:40px; height:40px; border-radius:50%;\n    background:var(--surface); border:1px solid var(--border); box-shadow:0 4px 10px rgba(0,0,0,.12);\n    display:flex; align-items:center; justify-content:center; cursor:pointer; z-index:390; color:var(--ink);\n  }\n  .locate-btn svg{ width:18px; height:18px; }\n\n  .mode-toggle{\n    position:absolute; left:50%; bottom:18px; transform:translateX(-50%);\n    background:var(--ink); color:#fff; border:none; border-radius:999px; padding:10px 16px 10px 14px;\n    display:flex; align-items:center; gap:8px; font-size:13.5px; cursor:pointer;\n    box-shadow:0 8px 20px rgba(38,34,32,.28); z-index:400;\n  }\n  .mode-toggle svg{ width:16px; height:16px; }\n  .mode-toggle .count{ background:rgba(255,255,255,.2); padding:1px 8px; border-radius:999px; font-size:12px; }\n\n  .card{\n    display:flex; gap:12px; background:var(--surface); border:1px solid var(--border);\n    border-radius:14px; padding:10px; cursor:pointer; margin-bottom:10px;\n    transition:border-color .15s;\n  }\n  .card:hover{ border-color:var(--ink-soft); }\n  .thumb{\n    flex:0 0 72px; width:72px; height:72px; border-radius:10px; color:#fff;\n    display:flex; align-items:center; justify-content:center;\n  }\n  .thumb svg{ width:26px; height:26px; }\n  .card-body{ flex:1; min-width:0; }\n  .card-body h3{ font-size:14.5px; font-family:inherit; font-weight:600; margin:0; line-height:1.3; display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }\n  .card-body .desc{ margin:4px 0 0; font-size:12.5px; color:var(--ink-soft); display:-webkit-box; -webkit-line-clamp:2; -webkit-box-orient:vertical; overflow:hidden; }\n  .card-body .meta{ margin-top:6px; font-size:11.5px; color:var(--ink-soft); }\n\n  .empty-state{ padding:28px 20px; text-align:center; color:var(--ink-soft); font-size:13.5px; border:1px dashed var(--border); border-radius:14px; }\n\n  .sheet{\n    position:absolute; left:0; right:0; bottom:0; max-height:80%;\n    background:var(--surface); border-radius:20px 20px 0 0; box-shadow:0 -10px 28px rgba(0,0,0,.18);\n    transform:translateY(100%); transition:transform .3s ease; z-index:500;\n    display:flex; flex-direction:column;\n  }\n  .sheet.open{ transform:translateY(0); }\n  .sheet.peek{ transform:translateY(calc(100% - 54px)); }\n  .sheet-peek-label{\n    display:none; align-items:center; justify-content:center; gap:8px;\n    position:absolute; top:0; left:0; right:0; height:54px; padding:0 20px;\n    cursor:pointer; font-size:13px; color:var(--ink-soft); font-weight:600;\n  }\n  .sheet.peek .sheet-peek-label{ display:flex; }\n  .sheet.peek .sheet-handle, .sheet.peek .sheet-close, .sheet.peek .sheet-body{ opacity:0; pointer-events:none; }\n  .sheet-handle{ width:36px; height:4px; background:var(--border); border-radius:2px; margin:10px auto 0; flex:0 0 auto; }\n  .sheet-close{\n    position:absolute; top:10px; right:12px; width:30px; height:30px; border-radius:50%;\n    background:var(--bg); border:1px solid var(--border); display:flex; align-items:center; justify-content:center;\n    cursor:pointer; color:var(--ink); z-index:2;\n  }\n  .sheet-close svg{ width:16px; height:16px; }\n  .sheet-body{ overflow-y:auto; padding:6px 20px 26px; }\n  .sheet-body .tag{ display:inline-block; font-size:11.5px; padding:3px 10px; border-radius:999px; margin-top:10px; }\n  .sheet-body h2{ font-size:19px; margin-top:8px; }\n  .sheet-body .meta-line{ font-size:12.5px; color:var(--ink-soft); margin-top:4px; }\n  .sheet-body .desc{ font-size:14px; color:var(--ink); margin-top:14px; line-height:1.6; }\n  .sheet-body .links{ display:flex; flex-wrap:wrap; gap:8px; margin-top:16px; }\n  .sheet-body .links a{\n    display:inline-flex; align-items:center; gap:6px; font-size:13px; color:var(--ink);\n    border:1px solid var(--border); padding:8px 13px; border-radius:999px; text-decoration:none;\n  }\n  .sheet-body .links a:hover{ border-color:var(--ink-soft); }\n  .gpx-actions{ display:flex; flex-direction:column; gap:8px; margin-top:16px; }\n  .btn-primary{\n    display:block; width:100%; text-align:center; background:var(--slate); color:#fff; border:none;\n    padding:12px; border-radius:12px; font-size:14px; font-weight:600; cursor:pointer; font-family:inherit;\n  }\n  .btn-secondary{\n    display:block; width:100%; text-align:center; background:var(--surface); color:var(--ink);\n    border:1px solid var(--border); padding:11px; border-radius:12px; font-size:13.5px; text-decoration:none;\n    box-sizing:border-box;\n  }\n  .contact-row{ display:flex; align-items:center; gap:8px; margin-top:14px; flex-wrap:wrap; }\n  .icon-btn{\n    width:38px; height:38px; border-radius:50%; border:1px solid var(--border); background:var(--surface);\n    display:flex; align-items:center; justify-content:center; color:var(--ink); flex:0 0 auto; text-decoration:none;\n  }\n  .icon-btn svg{ width:17px; height:17px; }\n  .itinerary-btn{\n    display:inline-flex; align-items:center; gap:6px; background:var(--wine); color:#fff; border:none;\n    padding:9px 16px; border-radius:999px; font-size:13px; font-weight:600; text-decoration:none; flex:0 0 auto;\n  }\n  .itinerary-btn svg{ width:14px; height:14px; }\n  .chips-row{ display:flex; flex-wrap:wrap; gap:8px; margin-top:12px; }\n  .chip-info{ border:1px solid var(--border); border-radius:999px; padding:6px 12px; font-size:12.5px; color:var(--ink-soft); }\n  .sheet-body .desc{ white-space:pre-line; }\n\n  .tag.circuit{ background:var(--vine-soft); color:var(--vine); }\n  .tag.vtt{ background:var(--slate-soft); color:var(--slate); }\n  .tag.hebergements{ background:var(--gold-soft); color:var(--gold); }\n  .tag.manifestations{ background:var(--wine-soft); color:var(--wine); }\n\n  @media (max-width:640px){\n    .wrap{ max-width:100%; padding:0; margin:0; }\n    .intro{ display:none; }\n    .appshell{\n      border:none; border-radius:0; box-shadow:none;\n      height:100vh; height:100dvh;\n    }\n  }\n<\/style>\n<\/head>\n<body>\n<div class=\"wrap\">\n  <div class=\"intro\">\n    <h1>Ribeauvill\u00e9 \u00b7 Riquewihr<\/h1>\n    <p>Circuits, balades et d\u00e9couvertes du territoire.<\/p>\n  <\/div>\n\n  <div class=\"appshell\">\n    <header class=\"app-header\">\n      <div class=\"search-row\">\n        <svg viewBox=\"0 0 24 24\" fill=\"none\"><circle cx=\"11\" cy=\"11\" r=\"6.5\" stroke=\"currentColor\" stroke-width=\"1.8\"\/><path d=\"M20 20l-4.5-4.5\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"\/><\/svg>\n        <input type=\"text\" id=\"searchInput\" placeholder=\"Rechercher un circuit, un village\u2026\">\n      <\/div>\n      <div class=\"pills\" id=\"pills\"><\/div>\n    <\/header>\n\n    <div class=\"stage mode-map\" id=\"stage\">\n      <div class=\"stage-map\" id=\"stageMap\">\n        <div id=\"map\"><\/div>\n        <div class=\"map-empty\" id=\"mapEmpty\"><p>Aucune donn\u00e9e pour cette rubrique dans ce prototype.<\/p><\/div>\n        <button class=\"locate-btn\" id=\"locateBtn\" aria-label=\"Me localiser\">\n          <svg viewBox=\"0 0 24 24\" fill=\"none\"><circle cx=\"12\" cy=\"12\" r=\"3\" stroke=\"currentColor\" stroke-width=\"1.8\"\/><path d=\"M12 2v3M12 19v3M2 12h3M19 12h3\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"\/><\/svg>\n        <\/button>\n      <\/div>\n      <div class=\"stage-list\" id=\"stageList\"><\/div>\n\n      <button class=\"mode-toggle\" id=\"modeToggle\">\n        <svg id=\"modeToggleIcon\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M8 6h12M8 12h12M8 18h12M4 6h.01M4 12h.01M4 18h.01\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\/><\/svg>\n        <span id=\"modeToggleLabel\">Voir la liste<\/span>\n        <span class=\"count\" id=\"modeToggleCount\">0<\/span>\n      <\/button>\n\n      <div class=\"sheet\" id=\"sheet\">\n        <div class=\"sheet-peek-label\" id=\"sheetPeekLabel\">\n          <svg viewBox=\"0 0 24 24\" fill=\"none\" width=\"14\" height=\"14\"><path d=\"M6 15l6-6 6 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg>\n          Revenir \u00e0 la fiche\n        <\/div>\n        <div class=\"sheet-handle\"><\/div>\n        <button class=\"sheet-close\" id=\"sheetClose\" aria-label=\"Fermer\">\n          <svg viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 9l6 6 6-6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg>\n        <\/button>\n        <div class=\"sheet-body\" id=\"sheetBody\"><\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script src=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/leaflet\/1.9.4\/leaflet.min.js\"><\/script>\n<script>\nconst ICONS = {\n  pedestre: '<svg viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M3 20c2-4 4-6 6-6s3 3 5 3 4-3 7-9\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\/><\/svg>',\n  vtt: '<svg viewBox=\"0 0 24 24\" fill=\"none\"><circle cx=\"5.5\" cy=\"17.5\" r=\"3.5\" stroke=\"currentColor\" stroke-width=\"1.8\"\/><circle cx=\"18.5\" cy=\"17.5\" r=\"3.5\" stroke=\"currentColor\" stroke-width=\"1.8\"\/><path d=\"M5.5 17.5L10 8h6l3 9.5M10 8l3 5.5h5.5M10 8l-2 4\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg>',\n  hebergements: '<svg viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M4 11.5L12 4l8 7.5\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><path d=\"M6 10v9h12v-9\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\" stroke-linejoin=\"round\"\/><\/svg>',\n  manifestations: '<svg viewBox=\"0 0 24 24\" fill=\"none\"><rect x=\"4\" y=\"5.5\" width=\"16\" height=\"15\" rx=\"2\" stroke=\"currentColor\" stroke-width=\"1.8\"\/><path d=\"M4 10h16M8 3.5v3M16 3.5v3\" stroke=\"currentColor\" stroke-width=\"1.8\" stroke-linecap=\"round\"\/><\/svg>'\n};\nconst ICON_MAP = '<svg viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M9 4L4 6v14l5-2 6 2 5-2V4l-5 2-6-2z\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linejoin=\"round\"\/><path d=\"M9 4v14M15 6v14\" stroke=\"currentColor\" stroke-width=\"1.6\"\/><\/svg>';\nconst ICON_LIST = '<svg viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M8 6h12M8 12h12M8 18h12M4 6h.01M4 12h.01M4 18h.01\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"\/><\/svg>';\nconst ICON_PHONE = '<svg viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6.6 10.8c1.4 2.8 3.8 5.1 6.6 6.6l2.2-2.2c.3-.3.7-.4 1-.2 1.1.4 2.3.6 3.5.6.6 0 1 .4 1 1V20c0 .6-.4 1-1 1C10.5 21 3 13.5 3 4c0-.6.4-1 1-1h3.4c.6 0 1 .4 1 1 0 1.2.2 2.4.6 3.5.1.4 0 .8-.2 1L6.6 10.8z\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linejoin=\"round\"\/><\/svg>';\nconst ICON_GLOBE = '<svg viewBox=\"0 0 24 24\" fill=\"none\"><circle cx=\"12\" cy=\"12\" r=\"9\" stroke=\"currentColor\" stroke-width=\"1.6\"\/><path d=\"M3 12h18M12 3c2.5 2.5 4 5.7 4 9s-1.5 6.5-4 9c-2.5-2.5-4-5.7-4-9s1.5-6.5 4-9z\" stroke=\"currentColor\" stroke-width=\"1.6\"\/><\/svg>';\nconst ICON_DIRECTION = '<svg viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M12 2l3 7-3 3-3-3 3-7z\" fill=\"currentColor\"\/><path d=\"M12 13v9\" stroke=\"currentColor\" stroke-width=\"1.6\" stroke-linecap=\"round\"\/><\/svg>';\n\nconst CATEGORIES = {\n  pedestre:       { label: \"P\u00e9destre\",       color: \"#4f6d45\" },\n  vtt:             { label: \"VTT\",            color: \"#3f5b67\" },\n  hebergements:    { label: \"H\u00e9bergements\",   color: \"#a8781f\" },\n  manifestations:  { label: \"Manifestations\", color: \"#7a2e3a\" }\n};\n\nconst DATA = {\n  hebergements: [],\n  manifestations: [],\n  vtt: [\n    { id:\"229005967\", titre:\"Ch\u00e2teaux et Grands Crus\", commune:\"Ribeauvill\u00e9\", lat:48.1929106350369, lon:7.32429972866127,\n      desc:`D\u00e9part \u00e0 Ribeauvill\u00e9, ville domin\u00e9e par les vestiges des trois ch\u00e2teaux des Ribeaupierre. Passage par Bergheim, cit\u00e9 viticole fortifi\u00e9e, mont\u00e9e vers Thannenkirch, puis retour par l'ancienne voie romaine.`,\n      kml:\"https:\/\/apps.tourisme-alsace.info\/traces\/229005967.kml\", gpx:\"https:\/\/apps.tourisme-alsace.info\/traces\/229005967.gpx\", difficulte:\"3\", tel:\"03 89 73 23 23\", site:\"www.ribeauville-riquewihr.com\",\n      trace:[[48.19298,7.32438],[48.19232,7.32843],[48.19292,7.33127],[48.19470,7.33386],[48.19474,7.33813],[48.19498,7.34260],[48.19537,7.34642],[48.19666,7.34727],[48.19752,7.34920],[48.19904,7.35202],[48.20190,7.35367],[48.20411,7.35569],[48.20512,7.35686],[48.20677,7.35321],[48.20809,7.34651],[48.21308,7.33899],[48.21998,7.32763],[48.22186,7.31859],[48.22446,7.31408],[48.22705,7.31127],[48.22874,7.30817],[48.22696,7.30453],[48.23028,7.30259],[48.23347,7.30655],[48.23538,7.31503],[48.23792,7.31736],[48.23942,7.31981],[48.24098,7.32511],[48.24485,7.32949],[48.24475,7.33806],[48.24420,7.34361],[48.24403,7.35093],[48.24245,7.34894],[48.24147,7.35389],[48.24118,7.35593],[48.24079,7.35786],[48.23299,7.36475],[48.22785,7.37972],[48.22245,7.38472],[48.21487,7.38170],[48.20552,7.37287],[48.19720,7.36526],[48.19543,7.34335],[48.19362,7.33239],[48.19301,7.32442]] },\n    { id:\"228002067\", titre:\"Circuit VTT n\u00b008 \u2014 Le tertre de la Fille Morte\", commune:\"Ribeauvill\u00e9 (d\u00e9part Col Haut)\", lat:48.1950496524573, lon:7.31895852936646,\n      desc:`Niveau difficile, 18 km, 573 m de d\u00e9nivel\u00e9 positif. Circuit court et technique, en grande partie sur la commune d'Aubure, la plus haute d'Alsace, avec de beaux points de vue sur la plaine.`,\n      kml:\"https:\/\/carto.tourisme-alsace.info\/traces\/228002067.kml\", gpx:\"https:\/\/carto.tourisme-alsace.info\/traces\/228002067.gpx\", distance_km:\"18\", denivele_m:\"573\", tel:\"03 89 58 80 50\", site:\"www.valdargent-tourisme.fr\",\n      trace:[[48.22680,7.23166],[48.22890,7.23109],[48.22888,7.23466],[48.22911,7.23696],[48.22763,7.23731],[48.22489,7.23922],[48.22074,7.24044],[48.21583,7.24356],[48.21838,7.23853],[48.21961,7.23627],[48.21846,7.23142],[48.21791,7.22689],[48.21582,7.23214],[48.21197,7.23395],[48.21027,7.22857],[48.21363,7.22777],[48.21294,7.22204],[48.21347,7.22061],[48.21288,7.21666],[48.21189,7.21069],[48.21085,7.20749],[48.20697,7.21310],[48.20296,7.21236],[48.20282,7.21162],[48.20607,7.20697],[48.20840,7.20109],[48.21183,7.19714],[48.21030,7.19644],[48.20693,7.19513],[48.20970,7.18932],[48.21320,7.19133],[48.21641,7.19305],[48.22078,7.19058],[48.22021,7.19623],[48.21890,7.20069],[48.22140,7.20211],[48.22169,7.20581],[48.22623,7.21230],[48.22947,7.21605],[48.23160,7.21880],[48.22995,7.22008],[48.22933,7.22414],[48.22756,7.22523],[48.22659,7.22815],[48.22678,7.23164]] },\n    { id:\"228002068\", titre:\"Circuit VTT n\u00b009 \u2014 Tour du Taennchel\", commune:\"Ribeauvill\u00e9\", lat:48.1933403416888, lon:7.32345391167541,\n      desc:`Niveau difficile, 19 km, 479 m de d\u00e9nivel\u00e9 positif. Circuit vari\u00e9 \u00e0 flanc de montagne autour du massif prot\u00e9g\u00e9 du Taennchel, avec vue sur le Val d'Argent et la plaine d'Alsace.`,\n      kml:\"https:\/\/carto.tourisme-alsace.info\/traces\/228002068.kml\", gpx:\"https:\/\/carto.tourisme-alsace.info\/traces\/228002068.gpx\", distance_km:\"19\", denivele_m:\"479\", tel:\"03 89 58 80 50\", site:\"www.valdargent-tourisme.fr\" },\n    { id:\"229007042\", titre:\"Circuit VTT raccourci : Les ch\u00e2teaux au d\u00e9part de Ribeauvill\u00e9\", commune:\"Pays de Ribeauvill\u00e9-Riquewihr\", lat:48.1945552136822, lon:7.32495599746705,\n      desc:`Version raccourcie du circuit des ch\u00e2teaux, au d\u00e9part de Ribeauvill\u00e9.`,\n      kml:\"https:\/\/carto.tourisme-alsace.info\/traces\/229007042.kml\", gpx:\"https:\/\/carto.tourisme-alsace.info\/traces\/229007042.gpx\", tel:\"03 89 73 23 23\", site:\"www.ribeauville-riquewihr.com\" },\n    { id:\"229007043\", titre:\"Circuit VTT raccourci : Riquewihr c\u00f4t\u00e9 pile et face\", commune:\"Pays de Ribeauvill\u00e9-Riquewihr\", lat:48.1937327411545, lon:7.31375509262086,\n      desc:`Version raccourcie du circuit autour de Riquewihr, entre vignoble et villages voisins.`,\n      kml:\"https:\/\/apps.tourisme-alsace.info\/traces\/229007043.kml\", gpx:\"https:\/\/apps.tourisme-alsace.info\/traces\/229007043.gpx\", tel:\"03 89 73 23 23\", site:\"www.ribeauville-riquewihr.com\" },\n    { id:\"229005941\", titre:\"Parcours v\u00e9lo : Escapade en for\u00eat entre le Taennchel et le Haut-K\u0153nigsbourg\", commune:\"Thannenkirch\", lat:48.2363888888889, lon:7.30666666666667,\n      desc:`Circuit en for\u00eat au d\u00e9part de Thannenkirch, les premi\u00e8res pentes du massif du Taennchel puis l'incontournable ch\u00e2teau du Haut-K\u0153nigsbourg avant une descente rapide sur Thannenkirch et ses fontaines.`,\n      kml:\"https:\/\/apps.tourisme-alsace.info\/traces\/229005941.kml\", gpx:\"https:\/\/apps.tourisme-alsace.info\/traces\/229005941.gpx\", tel:\"03 89 73 23 23\" },\n    { id:\"229005964\", titre:\"Parcours v\u00e9lo : Le massif du Taennchel au d\u00e9part de Ribeauvill\u00e9\", commune:\"Ribeauvill\u00e9\", lat:48.1980555555556, lon:7.32583333333333,\n      desc:`\u00c0 la d\u00e9couverte du massif du Taennchel et de ses l\u00e9gendes, avec une pause au panorama qu'offrent les ruines des trois ch\u00e2teaux de Ribeauvill\u00e9 sur la ville et la plaine d'Alsace.`,\n      kml:\"https:\/\/apps.tourisme-alsace.info\/traces\/229005964.kml\", gpx:\"https:\/\/apps.tourisme-alsace.info\/traces\/229005964.gpx\", tel:\"03 89 73 23 23\" },\n    { id:\"229005961\", titre:\"Parcours v\u00e9lo : Le massif du Taennchel au d\u00e9part de Ribeauvill\u00e9 (raccourci)\", commune:\"Ribeauvill\u00e9\", lat:48.1980555555556, lon:7.32583333333333,\n      desc:`Version raccourcie du parcours du massif du Taennchel, entre l\u00e9gendes et panorama sur les trois ch\u00e2teaux de Ribeauvill\u00e9.`,\n      kml:\"https:\/\/apps.tourisme-alsace.info\/traces\/229005961.kml\", gpx:\"https:\/\/apps.tourisme-alsace.info\/traces\/229005961.gpx\", difficulte:\"4\", tel:\"03 89 73 23 23\" },\n    { id:\"229005940\", titre:\"Parcours v\u00e9lo : Les ch\u00e2teaux au d\u00e9part de Ribeauvill\u00e9\", commune:\"Ribeauvill\u00e9\", lat:48.1980555555556, lon:7.32583333333333,\n      desc:`Parcours au fort d\u00e9nivel\u00e9 entre vignoble, Thannenkirch et massif du Taennchel, jusqu'aux ch\u00e2teaux du Saint-Ulrich et du Girsberg.`,\n      kml:\"https:\/\/apps.tourisme-alsace.info\/traces\/229005940.kml\", gpx:\"https:\/\/apps.tourisme-alsace.info\/traces\/229005940.gpx\", difficulte:\"4\", tel:\"03 89 73 23 23\" }\n  ],\n  pedestre: [\n    { id:\"229006001\", titre:`Autour d'Aubure`, commune:\"Aubure\", lat:48.1973198120599, lon:7.22134422001084,\n      desc:`Promenade au d\u00e9part d'Aubure, village le plus haut d'Alsace, avec vues sur les ch\u00e2teaux de Ribeauvill\u00e9, les ruines du Bilstein et les vall\u00e9es de Sainte-Marie-aux-Mines et Fr\u00e9land.`, tel:\"03 89 73 23 23\" },\n    { id:\"229006003\", titre:\"Autour de Thannenkirch\", commune:\"Thannenkirch\", lat:48.2354957673178, lon:7.30937467332473,\n      desc:`Circuit accessible au d\u00e9part de Thannenkirch, panorama sur la plaine d'Alsace et la For\u00eat-Noire, \u00e0 la d\u00e9couverte du village et de la nature environnante.`, tel:\"03 89 73 23 23\" },\n    { id:\"229009899\", titre:\"Balade ludique \u00e0 Illhaeusern\", commune:\"Illhaeusern\", lat:48.1844726579179, lon:7.43357062339783,\n      desc:`Parcours d'\u00e9nigmes en famille dans cet ancien village de p\u00eacheurs. Livret de jeu disponible \u00e0 l'office de tourisme, adapt\u00e9 de 4 \u00e0 12 ans.`, tel:\"03 89 73 23 23\" },\n    { id:\"229009900\", titre:\"Balade Ludique G\u00e9ovino \u2013 Hunawihr\", commune:\"Hunawihr\", lat:48.1803195877697, lon:7.31274247866197,\n      desc:`Suivez la mascotte Storickela \u00e0 la d\u00e9couverte du vignoble de Hunawihr et de sa biodiversit\u00e9, \u00e0 travers un parcours d'\u00e9nigmes en famille.`, tel:\"03 89 73 23 23\" },\n    { id:\"229009901\", titre:\"Balade Ludique G\u00e9ovino \u2013 Rodern\", commune:\"Rodern\", lat:48.2250014414571, lon:7.3535281419754,\n      desc:`Balade en famille \u00e0 la d\u00e9couverte du vignoble de Rodern et des vigneronnes et vignerons qui le cultivent.`, tel:\"03 89 73 23 23\" },\n    { id:\"229009902\", titre:\"Balade Ludique G\u00e9ovino \u2013 Saint-Hippolyte\", commune:\"Saint Hippolyte\", lat:48.2332276988436, lon:7.36797451972962,\n      desc:`Parcours ludique \u00e0 la d\u00e9couverte du vignoble de Saint-Hippolyte, avec \u00e9nigmes \u00e0 r\u00e9soudre en chemin.`, tel:\"03 89 73 23 23\" },\n    { id:\"405000006\", titre:\"Chemin des ch\u00e2teaux-forts d'Alsace (partie 3)\", commune:\"Ribeauvill\u00e9\", lat:48.1980555555556, lon:7.32583333333333,\n      desc:`Troisi\u00e8me tron\u00e7on, de Dambach-la-Ville \u00e0 Turckheim, du chemin qui relie 80 ch\u00e2teaux d'Alsace sur plus de 450 km, balis\u00e9 par le Club Vosgien.`,\n      site:\"https:\/\/www.outdooractive.com\/fr\/route\/grande-randonnee-et-trekking\/alsace\/le-chemin-des-chateaux-forts-d-alsace\/39803901\/\", tel:\"03 89 73 23 23\" },\n    { id:\"229004863\", titre:\"Chemin du bien-\u00eatre \u00e0 Aubure\", commune:\"Aubure\", lat:48.1959853358307, lon:7.21753624598182,\n      desc:`Parcours jalonn\u00e9 de 14 bornes de shiatsu invitant \u00e0 se faire du bien, chacune associ\u00e9e au portrait sonore et vid\u00e9o d'un habitant d'Aubure.`,\n      pdf:\"https:\/\/apps.tourisme-alsace.info\/photos\/ribeau\/photos\/229004863_d1.pdf\", tel:\"03 89 73 23 23\" },\n    { id:\"229006189\", titre:\"Chemin vers Ribeauvill\u00e9\", commune:\"Hunawihr\", lat:48.180077, lon:7.308283,\n      desc:`25 minutes de marche entre les vignes depuis Hunawihr jusqu'\u00e0 la ville haute de Ribeauvill\u00e9, puis 15 minutes \u00e0 travers la vieille ville.`, tel:\"03 89 73 23 23\" },\n    { id:\"229006188\", titre:\"Chemin vers Riquewihr\", commune:\"Hunawihr\", lat:48.179533, lon:7.307371,\n      desc:`25 minutes de marche entre les vignes depuis Hunawihr jusqu'\u00e0 la Porte Haute de Riquewihr, puis 15 minutes \u00e0 travers la vieille ville.`, tel:\"03 89 73 23 23\" },\n    { id:\"228003718\", titre:\"Circuit : le Chemin du Bien-\u00eatre\", commune:\"Aubure\", lat:48.2061111111111, lon:7.22416666666667,\n      desc:`Circuit de 17 km au d\u00e9part d'Aubure, village le plus haut d'Alsace, jalonn\u00e9 de 14 points d'information sur les bienfaits du shiatsu.`,\n      pdf:\"https:\/\/apps.tourisme-alsace.info\/photos\/argent\/photos\/228003718_d1.pdf\", tel:\"03 89 73 23 23\" },\n    { id:\"229010010\", titre:\"Circuit bleu (moyen) \u2013 Colline des amandiers\", commune:\"Mittelwihr\", lat:48.152466027531, lon:7.32140064239502,\n      desc:`Circuit de 4 km tout public sur la colline des amandiers \u00e0 Mittelwihr. \u00c0 privil\u00e9gier d\u00e9but mars, lors de leur floraison.`, tel:\"03 89 73 23 23\" },\n    { id:\"229006925\", titre:\"Circuit de d\u00e9couverte de Beblenheim\", commune:\"Beblenheim\", lat:48.1584137735179, lon:7.32650756835938,\n      desc:`Balade \u00e0 la d\u00e9couverte de Beblenheim, village viticole mentionn\u00e9 d\u00e8s 1128, qui traversa les grandes heures de l'histoire alsacienne.`,\n      pdf:\"https:\/\/apps.tourisme-alsace.info\/photos\/ribeau\/photos\/229001743_d1.pdf\", tel:\"03 89 73 23 23\" },\n    { id:\"229006929\", titre:\"Circuit de d\u00e9couverte de Bennwihr\", commune:\"Bennwihr\", lat:48.1439833921273, lon:7.32513427734375,\n      desc:`Circuit \u00e0 la d\u00e9couverte de Bennwihr, village enti\u00e8rement d\u00e9truit lors des combats de la Poche de Colmar en 1944-45 et reconstruit dans les ann\u00e9es 1950.`, tel:\"03 89 73 23 23\" },\n    { id:\"229006918\", titre:\"Circuit de d\u00e9couverte de Bergheim\", commune:\"Bergheim\", lat:48.2058028900654, lon:7.35854387283325,\n      desc:`Bergheim, cit\u00e9 viticole m\u00e9di\u00e9vale prot\u00e9g\u00e9e par ses remparts, compte deux Grands Crus (Kanzlerberg et Altenberg) et de belles maisons de vignerons.`,\n      pdf:\"https:\/\/apps.tourisme-alsace.info\/photos\/ribeau\/photos\/229001745_d1.pdf\", tel:\"03 89 73 23 23\" },\n    { id:\"229006926\", titre:\"Circuit de d\u00e9couverte de Gu\u00e9mar\", commune:\"Guemar\", lat:48.1896656797153, lon:7.3978328704834,\n      desc:`Ancien village de p\u00eacheurs et d'agriculteurs sur la Fecht, Gu\u00e9mar conserve fermes \u00e0 pans de bois, remparts transform\u00e9s en promenade et jardins potagers.`, tel:\"03 89 73 23 23\" },\n    { id:\"229006922\", titre:\"Circuit de d\u00e9couverte de Mittelwihr\", commune:\"Mittelwihr\", lat:48.1519444444444, lon:7.32833333333333,\n      desc:`Village viticole surnomm\u00e9 le \u00ab Midi de l'Alsace \u00bb pour son microclimat propice aux amandiers, qui fleurissent sur la colline du Mandelberg.`, tel:\"03 89 73 23 23\" },\n    { id:\"229006930\", titre:\"Circuit de d\u00e9couverte de Ribeauvill\u00e9\", commune:\"Ribeauville\", lat:48.192941447532, lon:7.32459783554077,\n      desc:`Ancienne cit\u00e9 des seigneurs de Ribeaupierre, Ribeauvill\u00e9 compte trois Grands Crus et accueille chaque ann\u00e9e la f\u00eate des M\u00e9n\u00e9triers.`, tel:\"03 89 73 23 23\" },\n    { id:\"229006927\", titre:\"Circuit de d\u00e9couverte de Riquewihr\", commune:\"Riquewihr\", lat:48.1667151299985, lon:7.2974967956543,\n      desc:`Cit\u00e9 m\u00e9di\u00e9vale class\u00e9e parmi les \u00ab Plus Beaux Villages de France \u00bb, Riquewihr marie depuis des si\u00e8cles son architecture \u00e0 colombages \u00e0 la qualit\u00e9 de ses vins.`,\n      pdf:\"https:\/\/apps.tourisme-alsace.info\/photos\/ribeau\/photos\/229006927_d1.pdf\", tel:\"03 89 73 23 23\" },\n    { id:\"229006924\", titre:\"Circuit de d\u00e9couverte de Saint Hippolyte\", commune:\"Saint Hippolyte\", lat:48.2335349964809, lon:7.36787796020508,\n      desc:`Commune viticole de la Route des Vins connue pour son Pinot Noir, le \u00ab Rouge de Saint-Hippolyte \u00bb, avec \u00e9glise gothique et vestiges des remparts.`, tel:\"03 89 73 23 23\" }\n  ]\n};\n\n\n\/\/ --- Carte ---\nconst map = L.map('map', { scrollWheelZoom: true, zoomControl: false }).setView([48.183, 7.31], 12);\nL.control.zoom({ position: 'bottomleft' }).addTo(map);\nL.tileLayer('https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png', {\n  attribution: '&copy; OpenStreetMap contributors',\n  maxZoom: 18\n}).addTo(map);\n\nlet markerLayer = L.layerGroup().addTo(map);\nlet markersById = {};\nlet activeTab = 'pedestre';\nlet activeTrace = null;\nlet searchQuery = '';\nlet viewMode = 'map';\n\nfunction makeIcon(categorie){\n  const color = CATEGORIES[categorie].color;\n  return L.divIcon({\n    className: '',\n    html: `<div class=\"pin\" style=\"width:30px;height:30px;background:${color};\">${ICONS[categorie]}<\/div>`,\n    iconSize: [30, 30],\n    iconAnchor: [15, 15]\n  });\n}\n\nfunction matchesSearch(item){\n  if (!searchQuery) return true;\n  const q = searchQuery.toLowerCase();\n  return item.titre.toLowerCase().includes(q) || item.commune.toLowerCase().includes(q);\n}\n\nfunction currentItems(){\n  return DATA[activeTab].filter(matchesSearch);\n}\n\nfunction renderPills(){\n  const el = document.getElementById('pills');\n  el.innerHTML = '';\n  Object.entries(CATEGORIES).forEach(([key, cat]) => {\n    const btn = document.createElement('button');\n    btn.className = 'pill' + (key === activeTab ? ' active' : '');\n    btn.innerHTML = ICONS[key] + '<span>' + cat.label + '<\/span>';\n    if (key === activeTab) btn.style.background = cat.color;\n    btn.addEventListener('click', () => {\n      activeTab = key;\n      closeSheet();\n      renderPills();\n      renderMap();\n      renderList();\n      updateToggleCount();\n    });\n    el.appendChild(btn);\n  });\n}\n\nfunction renderMap(){\n  markerLayer.clearLayers();\n  markersById = {};\n  activeTrace = null;\n  const items = currentItems();\n\n  items.forEach(item => {\n    const marker = L.marker([item.lat, item.lon], { icon: makeIcon(activeTab) });\n    marker.on('click', () => selectItem(item.id));\n    marker.addTo(markerLayer);\n    markersById[item.id] = marker;\n  });\n\n  document.getElementById('mapEmpty').classList.toggle('visible', items.length === 0);\n\n  if (items.length > 0){\n    const bounds = L.featureGroup(Object.values(markersById)).getBounds();\n    map.fitBounds(bounds, { padding: [30, 30], maxZoom: 14 });\n  }\n}\n\nfunction renderList(){\n  const el = document.getElementById('stageList');\n  const items = currentItems();\n  const color = CATEGORIES[activeTab].color;\n  el.innerHTML = '';\n\n  if (items.length === 0){\n    el.innerHTML = `<div class=\"empty-state\">Aucun r\u00e9sultat${searchQuery ? ' pour cette recherche' : ' pour cette rubrique dans ce prototype'}.<\/div>`;\n    return;\n  }\n\n  items.forEach(item => {\n    const card = document.createElement('div');\n    card.className = 'card';\n    card.innerHTML = `\n      <div class=\"thumb\" style=\"background:${color};\">${ICONS[activeTab]}<\/div>\n      <div class=\"card-body\">\n        <h3>${item.titre}<\/h3>\n        <p class=\"desc\">${item.desc || ''}<\/p>\n        <div class=\"meta\">${item.commune}${item.difficulte ? ' \u00b7 difficult\u00e9 ' + item.difficulte : ''}<\/div>\n      <\/div>\n    `;\n    card.addEventListener('click', () => { setMode('map'); selectItem(item.id); });\n    el.appendChild(card);\n  });\n}\n\nfunction updateToggleCount(){\n  document.getElementById('modeToggleCount').textContent = currentItems().length;\n}\n\nfunction setMode(mode){\n  viewMode = mode;\n  const stage = document.getElementById('stage');\n  stage.classList.toggle('mode-map', mode === 'map');\n  stage.classList.toggle('mode-list', mode === 'list');\n  document.getElementById('modeToggleLabel').textContent = mode === 'map' ? 'Voir la liste' : 'Voir la carte';\n  document.getElementById('modeToggleIcon').outerHTML = (mode === 'map' ? ICON_LIST : ICON_MAP).replace('<svg ', '<svg id=\"modeToggleIcon\" ');\n  if (mode === 'map') setTimeout(() => map.invalidateSize(), 50);\n}\n\ndocument.getElementById('modeToggle').addEventListener('click', () => setMode(viewMode === 'map' ? 'list' : 'map'));\n\ndocument.getElementById('searchInput').addEventListener('input', (e) => {\n  searchQuery = e.target.value.trim();\n  renderMap();\n  renderList();\n  updateToggleCount();\n});\n\n\/\/ --- Fiche d\u00e9tail (bottom sheet) ---\nconst sheet = document.getElementById('sheet');\n\nfunction selectItem(id){\n  const item = DATA[activeTab].find(x => x.id === id);\n  const marker = markersById[id];\n  if (!item) return;\n\n  if (activeTrace){ markerLayer.removeLayer(activeTrace); activeTrace = null; }\n\n  if (marker){\n    map.flyTo([item.lat, item.lon], Math.max(map.getZoom(), 14), { duration: 0.6 });\n    marker.openPopup && marker.openPopup();\n  }\n\n  renderSheetBody(item);\n  sheet.classList.remove('peek');\n  sheet.classList.add('open');\n}\n\nfunction difficulteLabel(d){\n  const n = parseFloat(d);\n  if (isNaN(n)) return null;\n  if (n <= 1.5) return 'Facile';\n  if (n <= 3) return 'Moyen';\n  if (n <= 4) return 'Difficile';\n  return 'Tr\u00e8s difficile';\n}\n\nfunction normalizeUrl(url){\n  return \/^https?:\\\/\\\/\/i.test(url) ? url : 'https:\/\/' + url;\n}\n\nfunction renderSheetBody(item){\n  const contact = [];\n  if (item.tel) contact.push(`<a class=\"icon-btn\" href=\"tel:${item.tel.replace(\/\\s+\/g,'')}\" aria-label=\"T\u00e9l\u00e9phone\">${ICON_PHONE}<\/a>`);\n  if (item.site) contact.push(`<a class=\"icon-btn\" href=\"${normalizeUrl(item.site)}\" target=\"_blank\" rel=\"noopener\" aria-label=\"Site web\">${ICON_GLOBE}<\/a>`);\n  contact.push(`<a class=\"itinerary-btn\" href=\"https:\/\/www.google.com\/maps\/dir\/?api=1&destination=${item.lat},${item.lon}\" target=\"_blank\" rel=\"noopener\">${ICON_DIRECTION}Itin\u00e9raire<\/a>`);\n\n  const chips = [];\n  const diffLabel = difficulteLabel(item.difficulte);\n  if (diffLabel) chips.push(diffLabel);\n  if (item.distance_km) chips.push(item.distance_km + ' km');\n  if (item.denivele_m) chips.push(item.denivele_m + ' m D+');\n\n  const liens = [];\n  if (item.pdf) liens.push(`<a href=\"${item.pdf}\" target=\"_blank\" rel=\"noopener\">Topo-guide (PDF)<\/a>`);\n  if (!item.trace){\n    if (item.kml) liens.push(`<a href=\"${item.kml}\" target=\"_blank\" rel=\"noopener\">Trac\u00e9 (KML)<\/a>`);\n    if (item.gpx) liens.push(`<a href=\"${item.gpx}\" target=\"_blank\" rel=\"noopener\">Trac\u00e9 (GPX)<\/a>`);\n  }\n\n  document.getElementById('sheetBody').innerHTML = `\n    <span class=\"tag ${activeTab}\">${CATEGORIES[activeTab].label}<\/span>\n    <h2>${item.titre}<\/h2>\n    <div class=\"meta-line\">${item.commune}<\/div>\n    <div class=\"contact-row\">${contact.join('')}<\/div>\n    ${chips.length ? `<div class=\"chips-row\">${chips.map(c => `<span class=\"chip-info\">${c}<\/span>`).join('')}<\/div>` : ''}\n    <p class=\"desc\">${item.desc || ''}<\/p>\n    ${item.trace ? `\n      <div class=\"gpx-actions\">\n        <button class=\"btn-primary\" id=\"showGpxBtn\">Afficher le trac\u00e9 sur la carte<\/button>\n        ${item.gpx ? `<a class=\"btn-secondary\" href=\"${item.gpx}\" target=\"_blank\" rel=\"noopener\" download>T\u00e9l\u00e9charger le GPX<\/a>` : ''}\n      <\/div>` : ''}\n    ${liens.length ? `<div class=\"links\">${liens.join('')}<\/div>` : ''}\n  `;\n\n  if (item.trace){\n    document.getElementById('showGpxBtn').addEventListener('click', () => showTrace(item));\n  }\n}\n\nfunction showTrace(item){\n  \/\/ Dessine le trac\u00e9 et fait redescendre la fiche en bandeau pour lib\u00e9rer\n  \/\/ toute la carte, comme demand\u00e9.\n  if (activeTrace){ markerLayer.removeLayer(activeTrace); }\n  activeTrace = L.polyline(item.trace, { color: \"#2563eb\", weight: 4, opacity: 0.85 });\n  activeTrace.addTo(markerLayer);\n  map.flyToBounds(activeTrace.getBounds(), { padding: [30, 30], duration: 0.6 });\n  sheet.classList.remove('open');\n  sheet.classList.add('peek');\n}\n\ndocument.getElementById('sheetPeekLabel').addEventListener('click', () => {\n  sheet.classList.remove('peek');\n  sheet.classList.add('open');\n});\n\nfunction closeSheet(){\n  sheet.classList.remove('open');\n  sheet.classList.remove('peek');\n  if (activeTrace){ markerLayer.removeLayer(activeTrace); activeTrace = null; }\n}\ndocument.getElementById('sheetClose').addEventListener('click', closeSheet);\n\n\/\/ --- Me localiser ---\nwindow.addEventListener('resize', () => { if (viewMode === 'map') map.invalidateSize(); });\n\ndocument.getElementById('locateBtn').addEventListener('click', () => {\n  if (!navigator.geolocation) return;\n  navigator.geolocation.getCurrentPosition(\n    pos => map.flyTo([pos.coords.latitude, pos.coords.longitude], 14, { duration: 0.6 }),\n    () => {}\n  );\n});\n\nrenderPills();\nrenderMap();\nrenderList();\nupdateToggleCount();\n<\/script>\n<\/body>\n<\/html>\n\t\t\t\t<\/div>\n\t\t\n<\/div>\n\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>Ribeauvill\u00e9 \u00b7 Riquewihr \u2014 Circuits &#038; d\u00e9couvertes Ribeauvill\u00e9 \u00b7 Riquewihr Circuits, balades et d\u00e9couvertes du territoire. Aucune donn\u00e9e pour cette rubrique dans ce prototype. Voir la liste 0 Revenir \u00e0 la fiche<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"footnotes":""},"class_list":["post-12","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/ribo.my-sit.fr\/index.php\/wp-json\/wp\/v2\/pages\/12","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ribo.my-sit.fr\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/ribo.my-sit.fr\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/ribo.my-sit.fr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/ribo.my-sit.fr\/index.php\/wp-json\/wp\/v2\/comments?post=12"}],"version-history":[{"count":13,"href":"https:\/\/ribo.my-sit.fr\/index.php\/wp-json\/wp\/v2\/pages\/12\/revisions"}],"predecessor-version":[{"id":34,"href":"https:\/\/ribo.my-sit.fr\/index.php\/wp-json\/wp\/v2\/pages\/12\/revisions\/34"}],"wp:attachment":[{"href":"https:\/\/ribo.my-sit.fr\/index.php\/wp-json\/wp\/v2\/media?parent=12"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}