{"id":22657,"date":"2026-05-04T14:16:01","date_gmt":"2026-05-04T14:16:01","guid":{"rendered":"https:\/\/drpascalmensah.com\/trouvez-votre-fenetre-alimentaire-alignee-sur-le-soleil\/"},"modified":"2026-05-05T14:14:03","modified_gmt":"2026-05-05T14:14:03","slug":"trouvez-votre-fenetre-alimentaire-alignee-sur-le-soleil","status":"publish","type":"post","link":"https:\/\/drpascalmensah.com\/fr\/trouvez-votre-fenetre-alimentaire-alignee-sur-le-soleil\/","title":{"rendered":"Trouvez votre fen\u00eatre alimentaire align\u00e9e sur le soleil"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-post\" data-elementor-id=\"22657\" class=\"elementor elementor-22657 elementor-22615\" data-elementor-post-type=\"post\">\n\t\t\t\t<div class=\"elementor-element elementor-element-39e4a74 e-flex e-con-boxed e-con e-parent\" data-id=\"39e4a74\" 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-56b3f59 elementor-widget elementor-widget-html\" data-id=\"56b3f59\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t\t<div>\n\n\n<meta charset=\"UTF-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Heure des repas \u2014 fen\u00eatre d'alimentation circadienne<\/title>\n<style>\n  :root {\n    --panel:#163A5F;\n    --panel-2: #6A94B9;\n    --ink: #E6ECF1C4;\n    --ink-dim: #E6ECF1C4;\n    --ink-soft: #E6ECF1C4;\n    --gold: #e3b341;\n    --gold-dim: #b88a2a;\n    --rust: #c45a2a;\n    --moon: #d8d2bf;\n    --line: #2c2718;\n    --good: #6fbf73;\n  }\n  * { box-sizing: border-box; }\n  html, body {\n    margin: 0; padding: 0;\n    background: radial-gradient(circle at 20% -10%, #2a200f 0%, var(--bg) 55%) fixed;\n    color: var(--ink);\n    font-family: -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Helvetica Neue\", Arial, sans-serif;\n    -webkit-font-smoothing: antialiased;\n    min-height: 100vh;\n  }\n  .container {\n    max-width: 880px;\n    margin: 0 auto;\n    padding: 32px 22px 80px;\n  }\n  header h1 {\n    font-size: 28px;\n    margin: 0 0 4px;\n    font-weight: 600;\n    letter-spacing: -0.01em;\n    color: #F8FAFB !important;\n  }\n  header p {\n    margin: 0 0 24px;\n    color: var(--ink-dim);\n    font-size: 14px;\n  }\n  .panel {\n    background: var(--panel);\n    border: 1px solid var(--line);\n    border-radius: 12px;\n    padding: 18px 20px;\n    margin-bottom: 18px;\n  }\n  .row {\n    display: flex;\n    flex-wrap: wrap;\n    gap: 8px;\n    align-items: center;\n  }\n  .row > * { flex: 0 0 auto; }\n  input[type=\"text\"], input[type=\"number\"], input[type=\"date\"] {\n    background: var(--panel-2);\n    color: var(--ink);\n    border: 1px solid var(--line);\n    border-radius: 8px;\n    padding: 9px 12px;\n    font-size: 14px;\n    font-family: inherit;\n    outline: none;\n  }\n  input[type=\"text\"]:focus, input[type=\"number\"]:focus, input[type=\"date\"]:focus {\n    border-color: var(--gold-dim);\n  }\n  input::placeholder { color: var(--ink-soft); }\n  button {\n    background: var(--gold);\n    color: #1a1408;\n    border: 0;\n    border-radius: 8px;\n    padding: 9px 14px;\n    font-size: 14px;\n    font-weight: 600;\n    cursor: pointer;\n    font-family: inherit;\n  }\n  button:hover { background: #f0c05a; }\n  button.ghost {\n    background: transparent;\n    color: var(--ink);\n    border: 1px solid var(--line);\n  }\n  button.ghost:hover { border-color: var(--gold-dim); color: var(--gold); }\n  .sep { color: var(--ink-soft); font-size: 13px; padding: 0 6px; }\n  #city { width: 200px; }\n  #lat, #lon { width: 110px; }\n  #date-input { margin-left: auto; }\n  #status {\n    font-size: 13px;\n    color: var(--ink-soft);\n    margin-top: 10px;\n    min-height: 18px;\n  }\n  #status.error { color: var(--rust); }\n\n  \/* Astronomy summary *\/\n  .astro {\n    display: grid;\n    grid-template-columns: repeat(4, 1fr);\n    gap: 12px;\n  }\n  .astro-cell {\n    background: var(--panel-2);\n    border-radius: 10px;\n    padding: 14px;\n  }\n  .astro-cell .label {\n    font-size: 11px;\n    text-transform: uppercase;\n    letter-spacing: 0.08em;\n    color: var(--ink-soft);\n    margin-bottom: 6px;\n  }\n  .astro-cell .value {\n    font-size: 20px;\n    font-weight: 600;\n    color: var(--ink);\n  }\n  .astro-cell .sub {\n    font-size: 12px;\n    color: var(--ink-dim);\n    margin-top: 2px;\n  }\n  .moon-row {\n    display: flex;\n    align-items: center;\n    gap: 10px;\n  }\n  .moon-glyph {\n    width: 28px; height: 28px;\n    border-radius: 50%;\n    background: var(--panel);\n    position: relative;\n    overflow: hidden;\n    flex-shrink: 0;\n    border: 1px solid var(--line);\n  }\n  .moon-glyph .lit {\n    position: absolute;\n    top: 0; bottom: 0;\n    background: var(--moon);\n  }\n\n  .location-name {\n    font-size: 14px;\n    color: var(--ink-dim);\n    margin-bottom: 12px;\n  }\n  .location-name strong { color: var(--ink); font-weight: 600; }\n\n  \/* Schedule *\/\n  h2.section-title {\n    font-size: 13px;\n    text-transform: uppercase;\n    letter-spacing: 0.1em;\n    color: var(--ink-soft);\n    margin: 24px 0 10px;\n    font-weight: 600;\n  }\n  .meal {\n    background: var(--panel);\n    border: 1px solid var(--line);\n    border-left: 3px solid var(--gold-dim);\n    border-radius: 12px;\n    padding: 16px 20px;\n    margin-bottom: 12px;\n  }\n  .meal.snack { border-left-color: var(--ink-soft); }\n  .meal.fast { border-left-color: var(--rust); opacity: 0.95; }\n  .meal-head {\n    display: flex;\n    align-items: baseline;\n    gap: 14px;\n    margin-bottom: 6px;\n  }\n  .meal-time {\n    font-variant-numeric: tabular-nums;\n    font-weight: 600;\n    color: var(--gold);\n    font-size: 16px;\n  }\n  .meal-name {\n    font-weight: 600;\n    font-size: 16px;\n    color:#F8FAFB;\n  }\n  .meal-tag {\n    font-size: 11px;\n    text-transform: uppercase;\n    letter-spacing: 0.08em;\n    color: var(--ink-soft);\n  }\n  .meal-body {\n    font-size: 14px;\n    line-height: 1.55;\n    color: var(--ink-dim);\n  }\n  .meal-body strong { color: var(--ink); font-weight: 600; }\n\n  .light-list {\n    list-style: none;\n    margin: 0;\n    padding: 0;\n  }\n  .light-list li {\n    display: flex;\n    justify-content: space-between;\n    padding: 8px 0;\n    border-bottom: 1px solid var(--line);\n    font-size: 14px;\n  }\n  .light-list li:last-child { border-bottom: 0; }\n  .light-list .lt {\n    color: var(--ink-dim);\n  }\n  .light-list .lv {\n    font-variant-numeric: tabular-nums;\n    color: var(--gold);\n    font-weight: 600;\n  }\n\n  footer {\n    color: var(--ink-soft);\n    font-size: 12px;\n    margin-top: 30px;\n    line-height: 1.5;\n  }\n  footer a { color: var(--gold-dim); }\n\n  \/* Edit-mode UI *\/\n  .meal-body[contenteditable=\"true\"], .meal-body[contenteditable=\"plaintext-only\"] {\n    outline: 1px dashed var(--gold-dim);\n    outline-offset: 6px;\n    border-radius: 6px;\n    cursor: text;\n  }\n  .meal-body[contenteditable=\"true\"]:focus, .meal-body[contenteditable=\"plaintext-only\"]:focus {\n    outline-color: var(--gold);\n    outline-style: solid;\n  }\n  .meal-actions {\n    display: none;\n    margin-top: 12px;\n    font-size: 12px;\n    gap: 14px;\n    align-items: center;\n  }\n  .meal.editing .meal-actions { display: flex; }\n  .meal-actions a {\n    color: var(--ink-soft);\n    cursor: pointer;\n    text-decoration: none;\n    border-bottom: 1px dotted var(--ink-soft);\n  }\n  .meal-actions a:hover { color: var(--gold); border-bottom-color: var(--gold-dim); }\n  .meal-actions .modified-tag {\n    color: var(--gold-dim);\n    font-style: italic;\n  }\n  .meal-badge {\n    margin-top: 10px;\n    font-size: 12px;\n    color: var(--ink-soft);\n  }\n  .meal-badge .v {\n    color: var(--gold);\n    font-variant-numeric: tabular-nums;\n    font-weight: 600;\n  }\n  .section-title-row {\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n    margin: 24px 0 10px;\n  }\n  .section-title-row h2.section-title { margin: 0; }\n  .edit-toggle {\n    background: transparent;\n    color: var(--ink-dim);\n    border: 1px solid var(--line);\n    border-radius: 6px;\n    padding: 5px 12px;\n    font-size: 12px;\n    cursor: pointer;\n    font-family: inherit;\n    font-weight: 500;\n  }\n  .edit-toggle:hover { color: var(--gold); border-color: var(--gold-dim); }\n  .edit-toggle.active {\n    color: var(--gold);\n    border-color: var(--gold);\n    background: rgba(227, 179, 65, 0.08);\n  }\n  .modified-dot {\n    display: inline-block;\n    width: 6px; height: 6px;\n    border-radius: 50%;\n    background: var(--gold);\n    margin-left: 8px;\n    vertical-align: middle;\n  }\n\n  @media (max-width: 600px) {\n    .astro { grid-template-columns: repeat(2, 1fr); }\n    #city { width: 100%; }\n    #lat, #lon { width: calc(50% - 4px); }\n    #date-input { margin-left: 0; width: 100%; }\n    .row { flex-direction: column; align-items: stretch; }\n    .row > * { width: 100%; }\n    .row > .sep { text-align: center; padding: 4px 0; }\n  }\n<\/style>\n\n\n<div class=\"container\">\n  <header>\n    <h1>Heure des repas<\/h1>\n    <p>Trouvez le meilleur moment pour manger gr\u00e2ce \u00e0 une fen\u00eatre alimentaire circadienne align\u00e9e sur le soleil. Entrez une localisation et une date. <\/p>\n  <\/header>\n\n  <div class=\"panel\">\n    <div class=\"row\">\n      <input type=\"text\" id=\"city\" placeholder=\"Ville (ex. Madrid)\">\n      <button id=\"city-btn\">Rechercher<\/button>\n<span class=\"sep\">ou<\/span>\n<input type=\"number\" id=\"lat\" placeholder=\"Latitude\" step=\"0.0001\">\n<input type=\"number\" id=\"lon\" placeholder=\"Longitude\" step=\"0.0001\">\n<button id=\"coords-btn\">Utiliser des coordonn\u00e9es<\/button>\n<button class=\"ghost\" id=\"gps-btn\">Utiliser ma position<\/button>\n      <input type=\"date\" id=\"date-input\">\n    <\/div>\n    <div id=\"status\">D\u00e9tection de votre position\u2026<\/div>\n  <\/div>\n\n  <div class=\"panel\">\n    <div class=\"location-name\" id=\"loc-name\">\u2014<\/div>\n    <div class=\"astro\">\n      <div class=\"astro-cell\">\n        <div class=\"label\">LEVER DU SOLEIL<\/div>\n        <div class=\"value\" id=\"sunrise-v\">\u2014<\/div>\n      <\/div>\n      <div class=\"astro-cell\">\n        <div class=\"label\">MIDI SOLAIRE<\/div>\n        <div class=\"value\" id=\"noon-v\">\u2014<\/div>\n      <\/div>\n      <div class=\"astro-cell\">\n        <div class=\"label\">COUCHER DU SOLEIL<\/div>\n        <div class=\"value\" id=\"sunset-v\">\u2014<\/div>\n      <\/div>\n      <div class=\"astro-cell\">\n        <div class=\"label\">LUNE<\/div>\n        <div class=\"moon-row\">\n          <div class=\"moon-glyph\"><div class=\"lit\" id=\"moon-lit\"><\/div><\/div>\n          <div>\n            <div class=\"value\" id=\"moon-name\" style=\"font-size:15px;\">\u2014<\/div>\n            <div class=\"sub\" id=\"moon-illum\">\u2014<\/div>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <div class=\"section-title-row\">\n    <h2 class=\"section-title\">FEN\u00caTRE ALIMENTAIRE<\/h2>\n    <button class=\"edit-toggle\" id=\"edit-toggle\">Modifier le menu<\/button>\n  <\/div>\n\n  <div class=\"meal\" data-meal-card=\"breakfast\">\n    <div class=\"meal-head\">\n      <div class=\"meal-time\" id=\"t-breakfast\">\u2014<\/div>\n      <div class=\"meal-name\">Petit-d\u00e9jeuner<\/div>\n      <div class=\"meal-tag\">~35 G DE PROT\u00c9INES<\/div>\n    <\/div>\n    <div class=\"meal-body\" data-meal=\"breakfast\">3 \u0153ufs cuits dans de l\u2019huile d\u2019olive extra vierge ; 150 g de yaourt grec entier avec chia, lin, zeste de citron et huile d\u2019olive ; roquette, tomate, olives et \u00bd avocat ; pain au levain optionnel avec tomate et huile d\u2019olive. Caf\u00e9 ou th\u00e9 vert. <\/div>\n    <div class=\"meal-badge\">Derni\u00e8re caf\u00e9ine avant <span class=\"v\" id=\"t-caffeine\">\u2014<\/span><\/div>\n    <div class=\"meal-actions\">\n      <a class=\"reset-link\">R\u00e9initialiser la suggestion<\/a>\n<span class=\"modified-tag\" hidden=\"\">modifi\u00e9 pour cette date<\/span>\n    <\/div>\n  <\/div>\n\n  <div class=\"meal\" data-meal-card=\"comida\">\n    <div class=\"meal-head\">\n      <div class=\"meal-time\" id=\"t-comida\">\u2014<\/div>\n      <div class=\"meal-name\">D\u00e9jeuner<\/div>\n      <div class=\"meal-tag\">REPAS PRINCIPAL \u00b7 CENTR\u00c9 SUR LE MIDI SOLAIRE<\/div>\n    <\/div>\n    <div class=\"meal-body\" data-meal=\"comida\">180 \u00e0 220 g de poisson blanc grill\u00e9 (daurade \/ lotte) ou c\u00f4telettes d\u2019agneau ; 1 tasse de riz noir ou pommes de terre nouvelles, \u00e0 consommer apr\u00e8s les l\u00e9gumes ; grande salade avec asperges grill\u00e9es \/ artichauts \/ piquillos, huile d\u2019olive extra vierge et vinaigre de X\u00e9r\u00e8s ; amandes ou 30 g de fromage Mah\u00f3n ; eau p\u00e9tillante avec citron ; 100 mL de vin rouge optionnels pendant le repas. Marche de 10 \u00e0 15 minutes \u00e0 la lumi\u00e8re du jour imm\u00e9diatement apr\u00e8s. <\/div>\n    <div class=\"meal-actions\">\n      <a class=\"reset-link\">R\u00e9initialiser la suggestion<\/a>\n<span class=\"modified-tag\" hidden=\"\">modifi\u00e9 pour cette date<\/span>\n    <\/div>\n  <\/div>\n\n  <div class=\"meal snack\" data-meal-card=\"snack\">\n    <div class=\"meal-head\">\n      <div class=\"meal-time\" id=\"t-snack\">\u2014<\/div>\n      <div class=\"meal-name\">Collation optionnelle<\/div>\n      <div class=\"meal-tag\">UNIQUEMENT EN CAS D\u2019ENTRA\u00ceNEMENT OU DE FAIM R\u00c9ELLE<\/div>\n    <\/div>\n    <div class=\"meal-body\" data-meal=\"snack\">\u0152uf dur et 20 g de noix ; yaourt grec avec cannelle ; ou 10 g de chocolat noir 85 % avec tisane. Sauter la collation est pr\u00e9f\u00e9rable car cela favorise l\u2019autophagie. <\/div>\n    <div class=\"meal-actions\">\n      <a class=\"reset-link\">R\u00e9initialiser la suggestion<\/a>\n<span class=\"modified-tag\" hidden=\"\">modifi\u00e9 pour cette date<\/span>\n    <\/div>\n  <\/div>\n\n  <div class=\"meal\" data-meal-card=\"dinner\">\n    <div class=\"meal-head\">\n      <div class=\"meal-time\" id=\"t-dinner\">\u2014<\/div>\n      <div class=\"meal-name\">D\u00eener<\/div>\n      <div class=\"meal-tag\">L\u00c9GER \u00b7 FAIBLE INDEX GLYC\u00c9MIQUE \u00b7 SE TERMINE 2 H AVANT LE COUCHER DU SOLEIL<\/div>\n    <\/div>\n    <div class=\"meal-body\" data-meal=\"dinner\">Gaspacho ou bouillon d\u2019os clair ; 120 \u00e0 150 g de poisson gras (sardines \/ anchois \/ saumon) ; l\u00e9gumes pauvres en amidon vapeur ou r\u00f4tis avec huile d\u2019olive extra vierge et ail ; environ \u00bd tasse de lentilles ou pois chiches ; camomille ou tisane de m\u00e9lisse. Pas de sucres simples, pas d\u2019alcool. <\/div>\n    <div class=\"meal-actions\">\n      <a class=\"reset-link\">R\u00e9initialiser la suggestion<\/a>\n<span class=\"modified-tag\" hidden=\"\">modifi\u00e9 pour cette date<\/span>\n    <\/div>\n  <\/div>\n\n  <div class=\"meal fast\" id=\"meal-fast\">\n    <div class=\"meal-head\">\n      <div class=\"meal-time\" id=\"t-fast\">\u2014<\/div>\n      <div class=\"meal-name\">Fen\u00eatre de je\u00fbne<\/div>\n      <div class=\"meal-tag\">EAU OU TISANE NON SUCR\u00c9E<\/div>\n    <\/div>\n    <div class=\"meal-body\">\n Je\u00fbne nocturne depuis la fin du d\u00eener jusqu\u2019au petit-d\u00e9jeuner du lendemain.\n    <\/div>\n  <\/div>\n\n  <h2 class=\"section-title\">HYGI\u00c8NE LUMINEUSE<\/h2>\n  <div class=\"panel\">\n    <ul class=\"light-list\">\n      <li><span class=\"lt\">Marche au coucher du soleil<\/span><span class=\"lv\" id=\"t-golden\">\u2014<\/span><\/li>\n      <li><span class=\"lt\">\u00c9clairage int\u00e9rieur &lt; 50 lux \u00e0 partir de<\/span><span class=\"lv\" id=\"t-lux50\">\u2014<\/span><\/li>\n      <li><span class=\"lt\">Arr\u00eat de la lumi\u00e8re bleue<\/span><span class=\"lv\" id=\"t-blue\">\u2014<\/span><\/li>\n      <li><span class=\"lt\">\u00c9clairage &lt; 10 lux \u00e0 partir de<\/span><span class=\"lv\" id=\"t-lux10\">\u2014<\/span><\/li>\n      <li><span class=\"lt\">Extinction des lumi\u00e8res<\/span><span class=\"lv\" id=\"t-lights\">\u2014<\/span><\/li>\n    <\/ul>\n  <\/div>\n\n  <footer>\n Position du soleil calcul\u00e9e via l\u2019algorithme NOAA Solar Position Algorithm (m\u00e9thode SunCalc, licence BSD-2-Clause, pr\u00e9cision &lt; 1 minute). Phase lunaire calcul\u00e9e via un cycle synodique r\u00e9f\u00e9renc\u00e9 \u00e0 la nouvelle lune du 06\/01\/2000. Recherche de villes via le g\u00e9ocodage <a href=\"https:\/\/open-meteo.com\/\" target=\"_blank\" rel=\"noopener\">Open-Meteo<\/a> (gratuit, sans cl\u00e9 API). \nToutes les heures sont affich\u00e9es dans le fuseau horaire local de la localisation s\u00e9lectionn\u00e9e.\n  <\/footer>\n<\/div>\n\n<script>\n\/* ============================================================\n   Sun-position math \u2014 SunCalc by Vladimir Agafonkin, BSD-2-Clause\n   https:\/\/github.com\/mourner\/suncalc  (trimmed to what we need)\n   ============================================================ *\/\n(function() {\n  const PI = Math.PI;\n  const rad = PI \/ 180;\n  const dayMs = 86400000;\n  const J1970 = 2440588;\n  const J2000 = 2451545;\n\n  function toJulian(date) { return date.valueOf() \/ dayMs - 0.5 + J1970; }\n  function fromJulian(j)  { return new Date((j + 0.5 - J1970) * dayMs); }\n  function toDays(date)   { return toJulian(date) - J2000; }\n\n  const e = rad * 23.4397;\n\n  function solarMeanAnomaly(d) { return rad * (357.5291 + 0.98560028 * d); }\n  function eclipticLongitude(M) {\n    const C = rad * (1.9148 * Math.sin(M) + 0.02 * Math.sin(2*M) + 0.0003 * Math.sin(3*M));\n    const P = rad * 102.9372;\n    return M + C + P + PI;\n  }\n  function declination(l, b) {\n    return Math.asin(Math.sin(b) * Math.cos(e) + Math.cos(b) * Math.sin(e) * Math.sin(l));\n  }\n  function julianCycle(d, lw) { return Math.round(d - 0.0009 - lw \/ (2 * PI)); }\n  function approxTransit(Ht, lw, n) { return 0.0009 + (Ht + lw) \/ (2 * PI) + n; }\n  function solarTransitJ(ds, M, L) { return J2000 + ds + 0.0053 * Math.sin(M) - 0.0069 * Math.sin(2 * L); }\n  function hourAngle(h, phi, d) {\n    const cosH = (Math.sin(h) - Math.sin(phi) * Math.sin(d)) \/ (Math.cos(phi) * Math.cos(d));\n    if (cosH > 1)  return null;   \/\/ sun never rises\n    if (cosH < -1) return null;   \/\/ sun never sets\n    return Math.acos(cosH);\n  }\n  function getSetJ(h, lw, phi, dec, n, M, L) {\n    const w = hourAngle(h, phi, dec);\n    if (w === null) return null;\n    const a = approxTransit(w, lw, n);\n    return solarTransitJ(a, M, L);\n  }\n\n  window.getSunTimes = function(date, lat, lng) {\n    const lw  = rad * -lng;\n    const phi = rad *  lat;\n    const d   = toDays(date);\n    const n   = julianCycle(d, lw);\n    const ds  = approxTransit(0, lw, n);\n    const M   = solarMeanAnomaly(ds);\n    const L   = eclipticLongitude(M);\n    const dec = declination(L, 0);\n    const Jnoon = solarTransitJ(ds, M, L);\n    const Jset  = getSetJ(-0.833 * rad, lw, phi, dec, n, M, L);  \/\/ standard sunrise\/sunset altitude\n    const Jrise = (Jset === null) ? null : Jnoon - (Jset - Jnoon);\n    return {\n      solarNoon: fromJulian(Jnoon),\n      sunrise:   Jrise === null ? null : fromJulian(Jrise),\n      sunset:    Jset  === null ? null : fromJulian(Jset)\n    };\n  };\n})();\n\n\/* ============================================================\n   Moon phase \u2014 Conway \/ synodic-month method\n   ============================================================ *\/\nfunction getMoonPhase(date) {\n  const newMoonRef = Date.UTC(2000, 0, 6, 18, 14, 0);\n  const synodic = 29.530588853;\n  const days = (date.getTime() - newMoonRef) \/ 86400000;\n  let phase = (days % synodic) \/ synodic;\n  if (phase < 0) phase += 1;\n  const illumination = (1 - Math.cos(2 * Math.PI * phase)) \/ 2;\n  let name, symbol;\n  if      (phase < 0.0625) { name = 'New Moon';        symbol = '\ud83c\udf11'; }\n  else if (phase < 0.1875) { name = 'Waxing Crescent'; symbol = '\ud83c\udf12'; }\n  else if (phase < 0.3125) { name = 'First Quarter';   symbol = '\ud83c\udf13'; }\n  else if (phase < 0.4375) { name = 'Waxing Gibbous';  symbol = '\ud83c\udf14'; }\n  else if (phase < 0.5625) { name = 'Full Moon';       symbol = '\ud83c\udf15'; }\n  else if (phase < 0.6875) { name = 'Waning Gibbous';  symbol = '\ud83c\udf16'; }\n  else if (phase < 0.8125) { name = 'Last Quarter';    symbol = '\ud83c\udf17'; }\n  else if (phase < 0.9375) { name = 'Waning Crescent'; symbol = '\ud83c\udf18'; }\n  else                     { name = 'New Moon';        symbol = '\ud83c\udf11'; }\n  const waxing = phase < 0.5;\n  return { name, symbol, phase, illumination, waxing };\n}\n\n\/* ============================================================\n   State + rendering\n   ============================================================ *\/\nconst state = {\n  lat: null,\n  lon: null,\n  label: '',\n  timezone: null,   \/\/ IANA tz string for location, or null = browser local\n  dateISO: null,    \/\/ YYYY-MM-DD (in location-local sense)\n};\n\nconst offsetsMin = {\n  \/\/ all in minutes, relative to anchor\n  breakfastStart:  60,            \/\/ sunrise + 1h\n  breakfastEnd:    120,           \/\/ sunrise + 2h\n  caffeineCutoff:  240,           \/\/ sunrise + 4h\n  comidaStart:    -45,            \/\/ solar noon - 45m\n  comidaEnd:       45,            \/\/ solar noon + 45m\n  snack:           148,           \/\/ solar noon + 2h28m\n  dinnerStart:    -180,           \/\/ sunset - 3h\n  dinnerEnd:      -120,           \/\/ sunset - 2h\n  goldenStart:    -37,            \/\/ sunset - 37m\n  goldenEnd:       18,            \/\/ sunset + 18m\n  lux50:          -60,            \/\/ sunset - 1h\n  blueLight:      -30,            \/\/ sunset - 30m\n  lux10:           107,           \/\/ sunset + 1h47m\n  lightsOut:       167,           \/\/ sunset + 2h47m\n};\n\nfunction addMinutes(date, m) { return new Date(date.getTime() + m * 60000); }\n\nfunction fmtTime(date) {\n  if (!date || isNaN(date.getTime())) return '\u2014';\n  const opts = { hour: '2-digit', minute: '2-digit', hour12: false };\n  if (state.timezone) opts.timeZone = state.timezone;\n  return new Intl.DateTimeFormat('en-GB', opts).format(date);\n}\n\nfunction fmtRange(a, b) {\n  return fmtTime(a) + ' \u2013 ' + fmtTime(b);\n}\n\n\/* Get the \"local noon\" UTC instant for a YYYY-MM-DD date string in the\n   location's timezone \u2014 this gives SunCalc a stable date to compute against. *\/\nfunction localNoonUTC(dateISO, tz) {\n  \/\/ Build a Date at noon local-to-tz. We use the trick of sampling Intl format\n  \/\/ to figure out the offset. Simpler approach: assume noon UTC then nudge.\n  \/\/ For the precision we need (within ~1 day), noon UTC of the date is fine.\n  return new Date(dateISO + 'T12:00:00Z');\n}\n\nfunction setStatus(msg, isError) {\n  const el = document.getElementById('status');\n  el.textContent = msg || '';\n  el.classList.toggle('error', !!isError);\n}\n\nfunction compute() {\n  loadMenusForDate();\n  if (state.lat == null || state.lon == null || !state.dateISO) return;\n\n  const refDate = localNoonUTC(state.dateISO, state.timezone);\n  const sun = getSunTimes(refDate, state.lat, state.lon);\n  const moon = getMoonPhase(refDate);\n\n  \/\/ Header summary\n  document.getElementById('loc-name').innerHTML =\n    `<strong>${state.label || (state.lat.toFixed(3) + ', ' + state.lon.toFixed(3))}<\/strong>` +\n    (state.timezone ? ` \u00b7 ${state.timezone}` : '');\n  document.getElementById('sunrise-v').textContent = fmtTime(sun.sunrise);\n  document.getElementById('noon-v').textContent    = fmtTime(sun.solarNoon);\n  document.getElementById('sunset-v').textContent  = fmtTime(sun.sunset);\n  document.getElementById('moon-name').textContent = `${moon.symbol} ${moon.name}`;\n  document.getElementById('moon-illum').textContent =\n    `${(moon.illumination * 100).toFixed(0)}% illuminated \u00b7 ${moon.waxing ? 'waxing' : 'waning'}`;\n\n  \/\/ Moon glyph fill\n  const lit = document.getElementById('moon-lit');\n  const pct = moon.illumination * 100;\n  if (moon.waxing) {\n    lit.style.left = (50 - pct\/2) + '%';\n    lit.style.right = '0';\n  } else {\n    lit.style.left = '0';\n    lit.style.right = (50 - pct\/2) + '%';\n  }\n\n  \/\/ Edge case: no sunrise\/sunset (polar)\n  if (!sun.sunrise || !sun.sunset) {\n    setStatus('Polar day or night at this location\/date \u2014 schedule cannot be derived from solar events.', true);\n    ['t-breakfast','t-caffeine','t-comida','t-snack','t-dinner','t-fast',\n     't-golden','t-lux50','t-blue','t-lux10','t-lights'].forEach(id => {\n      document.getElementById(id).textContent = '\u2014';\n    });\n    return;\n  }\n\n  const sunrise = sun.sunrise, noon = sun.solarNoon, sunset = sun.sunset;\n\n  const breakfastStart = addMinutes(sunrise, offsetsMin.breakfastStart);\n  const breakfastEnd   = addMinutes(sunrise, offsetsMin.breakfastEnd);\n  const caffeineCut    = addMinutes(sunrise, offsetsMin.caffeineCutoff);\n  const comidaStart    = addMinutes(noon,    offsetsMin.comidaStart);\n  const comidaEnd      = addMinutes(noon,    offsetsMin.comidaEnd);\n  const snack          = addMinutes(noon,    offsetsMin.snack);\n  const dinnerStart    = addMinutes(sunset,  offsetsMin.dinnerStart);\n  const dinnerEnd      = addMinutes(sunset,  offsetsMin.dinnerEnd);\n  const goldenStart    = addMinutes(sunset,  offsetsMin.goldenStart);\n  const goldenEnd      = addMinutes(sunset,  offsetsMin.goldenEnd);\n  const lux50          = addMinutes(sunset,  offsetsMin.lux50);\n  const blue           = addMinutes(sunset,  offsetsMin.blueLight);\n  const lux10          = addMinutes(sunset,  offsetsMin.lux10);\n  const lights         = addMinutes(sunset,  offsetsMin.lightsOut);\n\n  document.getElementById('t-breakfast').textContent = fmtRange(breakfastStart, breakfastEnd);\n  document.getElementById('t-caffeine').textContent  = fmtTime(caffeineCut);\n  document.getElementById('t-comida').textContent    = fmtRange(comidaStart, comidaEnd);\n  document.getElementById('t-snack').textContent     = fmtTime(snack);\n  document.getElementById('t-dinner').textContent    = fmtRange(dinnerStart, dinnerEnd);\n  document.getElementById('t-fast').textContent      = fmtTime(dinnerEnd) + ' \u2192 ' + fmtTime(breakfastStart) + ' (next day)';\n  document.getElementById('t-golden').textContent    = fmtRange(goldenStart, goldenEnd);\n  document.getElementById('t-lux50').textContent     = fmtTime(lux50);\n  document.getElementById('t-blue').textContent      = fmtTime(blue);\n  document.getElementById('t-lux10').textContent     = fmtTime(lux10);\n  document.getElementById('t-lights').textContent    = fmtTime(lights);\n\n  setStatus('');\n  saveLast();\n}\n\n\/* ============================================================\n   Location handlers\n   ============================================================ *\/\nasync function searchCity(name) {\n  setStatus('Searching for \"' + name + '\"\u2026');\n  try {\n    const url = 'https:\/\/geocoding-api.open-meteo.com\/v1\/search?name='\n      + encodeURIComponent(name) + '&count=1&language=en&format=json';\n    const r = await fetch(url);\n    if (!r.ok) throw new Error('Network error');\n    const data = await r.json();\n    if (!data.results || !data.results.length) {\n      setStatus('No match for \"' + name + '\". Try a more specific name or use coordinates.', true);\n      return;\n    }\n    const hit = data.results[0];\n    state.lat = hit.latitude;\n    state.lon = hit.longitude;\n    state.label = [hit.name, hit.admin1, hit.country].filter(Boolean).join(', ');\n    state.timezone = hit.timezone || null;\n    document.getElementById('lat').value = state.lat.toFixed(4);\n    document.getElementById('lon').value = state.lon.toFixed(4);\n    compute();\n  } catch (err) {\n    setStatus('Search failed: ' + err.message + '. Try entering coordinates directly.', true);\n  }\n}\n\nfunction useCoords(lat, lon) {\n  if (isNaN(lat) || isNaN(lon)) {\n    setStatus('Enter valid latitude and longitude.', true);\n    return;\n  }\n  if (Math.abs(lat) > 90 || Math.abs(lon) > 180) {\n    setStatus('Out-of-range coordinates.', true);\n    return;\n  }\n  state.lat = lat;\n  state.lon = lon;\n  state.label = lat.toFixed(3) + ', ' + lon.toFixed(3);\n  \/\/ Keep existing timezone if any, otherwise use browser local\n  if (!state.timezone) {\n    state.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n  }\n  compute();\n}\n\nfunction useGPS() {\n  if (!navigator.geolocation) {\n    setStatus('Geolocation not supported. Use city or coordinates.', true);\n    return;\n  }\n  setStatus('Asking your browser for location\u2026');\n  navigator.geolocation.getCurrentPosition(\n    (pos) => {\n      state.lat = pos.coords.latitude;\n      state.lon = pos.coords.longitude;\n      state.label = 'Your location';\n      state.timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;\n      document.getElementById('lat').value = state.lat.toFixed(4);\n      document.getElementById('lon').value = state.lon.toFixed(4);\n      compute();\n    },\n    (err) => {\n      setStatus('Location denied or unavailable (' + err.message + '). Enter a city or coordinates.', true);\n    },\n    { timeout: 10000, maximumAge: 600000 }\n  );\n}\n\n\/* ============================================================\n   Persistence + boot\n   ============================================================ *\/\nfunction saveLast() {\n  try {\n    localStorage.setItem('eatingTimeLast', JSON.stringify({\n      lat: state.lat, lon: state.lon, label: state.label, timezone: state.timezone\n    }));\n  } catch (e) { \/* ignore *\/ }\n}\nfunction loadLast() {\n  try {\n    const raw = localStorage.getItem('eatingTimeLast');\n    if (!raw) return null;\n    return JSON.parse(raw);\n  } catch (e) { return null; }\n}\n\n\/* ============================================================\n   Per-date menu editing\n   ============================================================ *\/\nconst MENU_DEFAULTS = {};\nlet editMode = false;\n\nfunction captureMenuDefaults() {\n  document.querySelectorAll('.meal-body[data-meal]').forEach(el => {\n    MENU_DEFAULTS[el.dataset.meal] = el.textContent.trim();\n  });\n}\n\nfunction getStoredMenu(dateISO, mealKey) {\n  try {\n    const raw = localStorage.getItem('eatingTimeMenu:' + dateISO);\n    if (!raw) return null;\n    const obj = JSON.parse(raw);\n    return obj[mealKey] != null ? obj[mealKey] : null;\n  } catch (e) { return null; }\n}\n\nfunction setStoredMenu(dateISO, mealKey, text) {\n  try {\n    const k = 'eatingTimeMenu:' + dateISO;\n    const raw = localStorage.getItem(k);\n    const obj = raw ? JSON.parse(raw) : {};\n    if (text == null) delete obj[mealKey];\n    else obj[mealKey] = text;\n    if (Object.keys(obj).length === 0) localStorage.removeItem(k);\n    else localStorage.setItem(k, JSON.stringify(obj));\n  } catch (e) { \/* ignore *\/ }\n}\n\nfunction loadMenusForDate() {\n  if (!state.dateISO) return;\n  Object.keys(MENU_DEFAULTS).forEach(key => {\n    const el = document.querySelector('.meal-body[data-meal=\"' + key + '\"]');\n    if (!el) return;\n    const stored = getStoredMenu(state.dateISO, key);\n    el.textContent = stored != null ? stored : MENU_DEFAULTS[key];\n    const card = el.closest('.meal');\n    const tag = card && card.querySelector('.modified-tag');\n    if (tag) tag.hidden = stored == null;\n  });\n}\n\nfunction setEditMode(on) {\n  editMode = on;\n  const btn = document.getElementById('edit-toggle');\n  btn.textContent = on ? 'Done editing' : 'Edit menu';\n  btn.classList.toggle('active', on);\n  document.querySelectorAll('.meal[data-meal-card]').forEach(card => {\n    card.classList.toggle('editing', on);\n    const body = card.querySelector('.meal-body[data-meal]');\n    if (body) body.contentEditable = on ? 'plaintext-only' : 'false';\n  });\n  if (on) setStatus('Editing menu \u2014 click outside a meal to save. Edits are saved per date.');\n  else setStatus('');\n}\n\nfunction bindMenuEditing() {\n  document.querySelectorAll('.meal-body[data-meal]').forEach(body => {\n    body.addEventListener('blur', () => {\n      const key = body.dataset.meal;\n      const txt = body.textContent.trim();\n      if (txt === '') {\n        body.textContent = MENU_DEFAULTS[key];\n        setStoredMenu(state.dateISO, key, null);\n      } else if (txt === MENU_DEFAULTS[key]) {\n        setStoredMenu(state.dateISO, key, null);\n      } else {\n        setStoredMenu(state.dateISO, key, txt);\n      }\n      const card = body.closest('.meal');\n      const tag = card && card.querySelector('.modified-tag');\n      if (tag) tag.hidden = (getStoredMenu(state.dateISO, key) == null);\n    });\n  });\n  document.querySelectorAll('.reset-link').forEach(link => {\n    link.addEventListener('click', (ev) => {\n      ev.preventDefault();\n      const card = link.closest('.meal');\n      const body = card.querySelector('.meal-body[data-meal]');\n      const key = body.dataset.meal;\n      body.textContent = MENU_DEFAULTS[key];\n      setStoredMenu(state.dateISO, key, null);\n      const tag = card.querySelector('.modified-tag');\n      if (tag) tag.hidden = true;\n    });\n  });\n  document.getElementById('edit-toggle').addEventListener('click', () => {\n    setEditMode(!editMode);\n  });\n}\n\nfunction todayISO() {\n  const d = new Date();\n  const y = d.getFullYear();\n  const m = String(d.getMonth() + 1).padStart(2, '0');\n  const day = String(d.getDate()).padStart(2, '0');\n  return `${y}-${m}-${day}`;\n}\n\nfunction init() {\n  captureMenuDefaults();\n  bindMenuEditing();\n\n  const dateInput = document.getElementById('date-input');\n  state.dateISO = todayISO();\n  dateInput.value = state.dateISO;\n  dateInput.addEventListener('change', () => {\n    state.dateISO = dateInput.value || todayISO();\n    compute();\n  });\n\n  document.getElementById('city-btn').addEventListener('click', () => {\n    const v = document.getElementById('city').value.trim();\n    if (v) searchCity(v);\n  });\n  document.getElementById('city').addEventListener('keydown', (e) => {\n    if (e.key === 'Enter') document.getElementById('city-btn').click();\n  });\n  document.getElementById('coords-btn').addEventListener('click', () => {\n    const lat = parseFloat(document.getElementById('lat').value);\n    const lon = parseFloat(document.getElementById('lon').value);\n    state.timezone = null;  \/\/ recompute from coords\n    useCoords(lat, lon);\n  });\n  document.getElementById('gps-btn').addEventListener('click', useGPS);\n\n  \/\/ Boot: try last saved, then GPS, then leave empty\n  const last = loadLast();\n  if (last && last.lat != null) {\n    state.lat = last.lat;\n    state.lon = last.lon;\n    state.label = last.label || '';\n    state.timezone = last.timezone || Intl.DateTimeFormat().resolvedOptions().timeZone;\n    document.getElementById('lat').value = state.lat.toFixed(4);\n    document.getElementById('lon').value = state.lon.toFixed(4);\n    setStatus('Loaded last location. You can change it above.');\n    compute();\n  } else {\n    useGPS();\n  }\n}\n\nwindow.addEventListener('DOMContentLoaded', init);\n<\/script>\n\n\n<\/div>\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>Quelles sont les meilleures heures pour manger selon votre localisation ? Calculez votre fen\u00eatre alimentaire circadienne personnalis\u00e9e \u00e0 partir des donn\u00e9es de lever du soleil, midi solaire et coucher du soleil selon votre position g\u00e9ographique. <\/p>\n","protected":false},"author":1,"featured_media":22781,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[129],"tags":[222,227],"class_list":["post-22657","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-nutrition","tag-fasting","tag-style-de-vie"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/drpascalmensah.com\/fr\/wp-json\/wp\/v2\/posts\/22657","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/drpascalmensah.com\/fr\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/drpascalmensah.com\/fr\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/drpascalmensah.com\/fr\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/drpascalmensah.com\/fr\/wp-json\/wp\/v2\/comments?post=22657"}],"version-history":[{"count":1,"href":"https:\/\/drpascalmensah.com\/fr\/wp-json\/wp\/v2\/posts\/22657\/revisions"}],"predecessor-version":[{"id":22658,"href":"https:\/\/drpascalmensah.com\/fr\/wp-json\/wp\/v2\/posts\/22657\/revisions\/22658"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/drpascalmensah.com\/fr\/wp-json\/wp\/v2\/media\/22781"}],"wp:attachment":[{"href":"https:\/\/drpascalmensah.com\/fr\/wp-json\/wp\/v2\/media?parent=22657"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/drpascalmensah.com\/fr\/wp-json\/wp\/v2\/categories?post=22657"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/drpascalmensah.com\/fr\/wp-json\/wp\/v2\/tags?post=22657"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}