{"id":4859,"date":"2025-10-30T11:26:24","date_gmt":"2025-10-30T09:26:24","guid":{"rendered":"https:\/\/northwindlapland.com\/?page_id=4859"},"modified":"2026-07-06T15:57:04","modified_gmt":"2026-07-06T12:57:04","slug":"northern-light-alert","status":"publish","type":"page","link":"https:\/\/northwindlapland.com\/fr\/northern-light-alert\/","title":{"rendered":"ALERTE AURORES BOR\u00c9ALES YLL\u00c4S"},"content":{"rendered":"\t\t<div data-elementor-type=\"wp-page\" data-elementor-id=\"4859\" class=\"elementor elementor-4859\" data-elementor-post-type=\"page\">\n\t\t\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-17034839 elementor-section-boxed elementor-section-height-default elementor-section-height-default\" data-id=\"17034839\" data-element_type=\"section\" data-e-type=\"section\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-ea6803c\" data-id=\"ea6803c\" data-element_type=\"column\" data-e-type=\"column\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<section class=\"elementor-section elementor-top-section elementor-element elementor-element-092ab9b elementor-section-full_width elementor-section-height-default elementor-section-height-default\" data-id=\"092ab9b\" data-element_type=\"section\" data-e-type=\"section\">\n\t\t\t\t\t\t<div class=\"elementor-container elementor-column-gap-default\">\n\t\t\t\t\t<div class=\"elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-0157841\" data-id=\"0157841\" data-element_type=\"column\" data-e-type=\"column\" data-settings=\"{&quot;background_background&quot;:&quot;classic&quot;}\">\n\t\t\t<div class=\"elementor-widget-wrap elementor-element-populated\">\n\t\t\t\t\t\t<div class=\"elementor-element elementor-element-793b822 elementor-widget elementor-widget-html\" data-id=\"793b822\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!--\n  NORTH WIND LAPLAND \u2014 AURORA ALERT EMAIL CAPTURE\n  \n  Paste this into an Elementor HTML widget on your \/northern-light-alert\/ page.\n  \n  HOW IT WORKS:\n  1. Guest enters their email (and optionally name + travel dates)\n  2. Form submits to your WordPress site\n  3. The companion plugin (nwl-aurora-signup.php) saves the subscriber\n     and sends you a notification email\n  4. You can later connect MailerLite or Mailchimp for automated sequences\n  \n  BILINGUAL: auto-detects \/fr\/ pages like the availability widget\n-->\n\n<style>\n.aurora-cta{\n  font-family:'Poppins',sans-serif;\n  max-width:1200px;margin:32px auto;padding:0;\n  background:rgba(27,51,80,.92);\n  border:1px solid rgba(186,252,248,.2);\n  border-radius:16px;\n  box-shadow:0 24px 60px -20px rgba(0,0,0,.5);\n  backdrop-filter:blur(8px);\n  overflow:hidden;\n  -webkit-tap-highlight-color:transparent;\n}\n.aurora-head{\n  position:relative;padding:32px 28px 24px;text-align:center;\n  background:\n    radial-gradient(ellipse 80% 60% at 30% -10%, rgba(186,252,248,.18), transparent 60%),\n    radial-gradient(ellipse 60% 50% at 75% 0%, rgba(100,200,180,.12), transparent 50%);\n}\n.aurora-head h3{\n  font-family:'Akatab',sans-serif;font-size:20px;font-weight:800;\n  letter-spacing:.14em;text-transform:uppercase;color:#BAFCF8;margin:0 0 10px;\n}\n.aurora-head p{\n  font-size:14px;color:rgba(255,255,255,.72);line-height:1.6;max-width:44ch;margin:0 auto;\n}\n.aurora-head .icon{font-size:32px;display:block;margin-bottom:12px}\n.aurora-form{padding:0 28px 28px}\n.aurora-row{margin-bottom:12px}\n.aurora-row label{\n  display:block;font-size:10px;letter-spacing:.14em;text-transform:uppercase;\n  color:#BAFCF8;font-weight:600;margin-bottom:5px;\n}\n.aurora-row input{\n  width:100%;padding:12px 14px;border-radius:9px;border:1px solid rgba(186,252,248,.2);\n  background:rgba(255,255,255,.06);color:#fff;font-family:'Poppins',sans-serif;\n  font-size:14px;font-weight:500;transition:border-color .2s;\n}\n.aurora-row input:focus{outline:none;border-color:#BAFCF8;box-shadow:0 0 0 3px rgba(186,252,248,.2)}\n.aurora-row input::placeholder{color:rgba(255,255,255,.35)}\n.aurora-row.half{display:grid;grid-template-columns:1fr 1fr;gap:10px}\n.aurora-consent{\n  display:flex;align-items:flex-start;gap:10px;margin:16px 0 18px;\n  font-size:11.5px;color:rgba(255,255,255,.55);line-height:1.5;\n}\n.aurora-consent input[type=checkbox]{\n  margin-top:2px;accent-color:#BAFCF8;width:16px;height:16px;flex:none;cursor:pointer;\n}\n.aurora-consent a{color:#BAFCF8;text-decoration:none}\n.aurora-btn{\n  width:100%;padding:14px;border:none;border-radius:9px;\n  background:#BAFCF8;color:#06343a;\n  font-family:'Akatab',sans-serif;font-weight:800;font-size:14px;\n  letter-spacing:.1em;text-transform:uppercase;cursor:pointer;\n  transition:filter .15s,transform .12s;\n  -webkit-tap-highlight-color:transparent;\n}\n.aurora-btn:hover,.aurora-btn:active,.aurora-btn:focus{\n  background:#BAFCF8;color:#06343a;filter:brightness(1.08);outline:none;\n}\n.aurora-btn:disabled{opacity:.5;cursor:not-allowed}\n.aurora-success{\n  text-align:center;padding:36px 28px;\n}\n.aurora-success .check{font-size:40px;display:block;margin-bottom:12px}\n.aurora-success h4{\n  font-family:'Akatab',sans-serif;font-size:18px;font-weight:700;\n  color:#BAFCF8;margin:0 0 8px;letter-spacing:.06em;\n}\n.aurora-success p{font-size:13.5px;color:rgba(255,255,255,.65);line-height:1.6}\n.aurora-error{\n  font-size:12px;color:#ffb38a;margin-top:8px;display:none;\n}\n.aurora-note{\n  text-align:center;font-size:11px;color:rgba(255,255,255,.35);\n  margin-top:12px;padding:0 28px 20px;\n}\n@media(max-width:480px){\n  .aurora-cta{margin:16px 8px;border-radius:12px}\n  .aurora-head{padding:24px 20px 18px}\n  .aurora-head h3{font-size:17px;letter-spacing:.1em}\n  .aurora-head p{font-size:13px}\n  .aurora-form{padding:0 20px 20px}\n  .aurora-row.half{grid-template-columns:1fr}\n}\n<\/style>\n\n<div class=\"aurora-cta\" id=\"auroraCta\">\n  <div class=\"aurora-head\">\n    <span class=\"icon\">\ud83c\udf0c<\/span>\n    <h3 id=\"acTitle\"><\/h3>\n    <p id=\"acDesc\"><\/p>\n  <\/div>\n  <form class=\"aurora-form\" id=\"auroraForm\">\n    <div class=\"aurora-row\">\n      <label id=\"acLbEmail\"><\/label>\n      <input type=\"email\" id=\"acEmail\" required placeholder=\"\">\n    <\/div>\n    <div class=\"aurora-row\">\n      <label id=\"acLbName\"><\/label>\n      <input type=\"text\" id=\"acName\" placeholder=\"\">\n    <\/div>\n    <div class=\"aurora-row half\">\n      <div>\n        <label id=\"acLbArr\"><\/label>\n        <input type=\"text\" id=\"acArr\" placeholder=\"\" readonly\n          onfocus=\"this.type='date';this.removeAttribute('readonly')\"\n          onblur=\"if(!this.value){this.type='text';this.setAttribute('readonly','')}\">\n      <\/div>\n      <div>\n        <label id=\"acLbDep\"><\/label>\n        <input type=\"text\" id=\"acDep\" placeholder=\"\" readonly\n          onfocus=\"this.type='date';this.removeAttribute('readonly')\"\n          onblur=\"if(!this.value){this.type='text';this.setAttribute('readonly','')}\">\n      <\/div>\n    <\/div>\n    <div class=\"aurora-consent\">\n      <input type=\"checkbox\" id=\"acConsent\" required>\n      <span id=\"acConsentText\"><\/span>\n    <\/div>\n    <button class=\"aurora-btn\" type=\"submit\" id=\"acBtn\"><\/button>\n    <div class=\"aurora-error\" id=\"acError\"><\/div>\n  <\/form>\n  <div class=\"aurora-success\" id=\"acSuccess\" style=\"display:none\">\n    <span class=\"check\">\u2728<\/span>\n    <h4 id=\"acSuccessTitle\"><\/h4>\n    <p id=\"acSuccessDesc\"><\/p>\n  <\/div>\n  <div class=\"aurora-note\" id=\"acNote\"><\/div>\n<\/div>\n\n<script>\n\/* \u2500\u2500 CONFIG \u2500\u2500 *\/\nconst AURORA_CONFIG = {\n  endpoint: '\/wp-json\/nwl\/v1\/aurora-signup'  \/* companion plugin handles this *\/\n};\n\n\/* \u2500\u2500 LANGUAGE \u2500\u2500 *\/\nconst AL = (function(){\n  if(window.location.pathname.indexOf('\/fr\/')===0) return 'fr';\n  const h=document.documentElement.lang||'';\n  return h.toLowerCase().indexOf('fr')===0?'fr':'en';\n})();\n\nconst AT = {\n  en:{\n    title:'Get Aurora Alerts for Yll\u00e4s',\n    desc:'We\\'ll notify you when Northern Lights conditions look promising over Yll\u00e4s \u2014 plus send you our insider guide to the best viewing spots. Free, no spam, unsubscribe anytime.',\n    lbEmail:'Your email',phEmail:'name@example.com',\n    lbName:'Your name (optional)',phName:'',\n    lbArr:'Arrival in Yll\u00e4s (optional)',phArr:'Select a date',\n    lbDep:'Departure (optional)',phDep:'Select a date',\n    consent:'I agree to receive aurora alerts and occasional travel tips from North Wind Lapland. <a href=\"\/privacy-policy\/\" target=\"_blank\">Privacy policy<\/a>.',\n    btn:'Sign up for Aurora Alerts',\n    sending:'Sending...',\n    successTitle:'You\\'re on the list!',\n    successDesc:'We\\'ll email you when the sky lights up over Yll\u00e4s. In the meantime, check our Northern Lights experiences \u2014 spots fill fast in aurora season.',\n    errorRequired:'Please fill in your email and accept the privacy policy.',\n    errorServer:'Something went wrong \u2014 please try again or email us at info@northwindlapland.com.',\n    note:'Your data is stored securely and never shared. You can unsubscribe at any time.'\n  },\n  fr:{\n    title:'Alertes Aurores Bor\u00e9ales \u00e0 Yll\u00e4s',\n    desc:'Nous vous pr\u00e9venons quand les conditions sont favorables pour observer les aurores bor\u00e9ales \u00e0 Yll\u00e4s \u2014 et nous vous envoyons notre guide des meilleurs spots. Gratuit, sans spam.',\n    lbEmail:'Votre email',phEmail:'nom@exemple.com',\n    lbName:'Votre nom (facultatif)',phName:'',\n    lbArr:'Arriv\u00e9e \u00e0 Yll\u00e4s (facultatif)',phArr:'Choisir une date',\n    lbDep:'D\u00e9part (facultatif)',phDep:'Choisir une date',\n    consent:'J\\'accepte de recevoir des alertes aurores et des conseils voyage de North Wind Lapland. <a href=\"\/fr\/privacy-policy\/\" target=\"_blank\">Politique de confidentialit\u00e9<\/a>.',\n    btn:'S\\'inscrire aux alertes aurores',\n    sending:'Envoi en cours...',\n    successTitle:'Vous \u00eates inscrit(e) !',\n    successDesc:'Nous vous \u00e9crirons quand le ciel s\\'illuminera au-dessus de Yll\u00e4s. En attendant, d\u00e9couvrez nos exp\u00e9riences Aurores Bor\u00e9ales.',\n    errorRequired:'Veuillez remplir votre email et accepter la politique de confidentialit\u00e9.',\n    errorServer:'Une erreur s\\'est produite \u2014 r\u00e9essayez ou \u00e9crivez-nous \u00e0 info@northwindlapland.com.',\n    note:'Vos donn\u00e9es sont stock\u00e9es en s\u00e9curit\u00e9 et jamais partag\u00e9es. D\u00e9sinscription possible \u00e0 tout moment.'\n  }\n};\nconst L = AT[AL] || AT.en;\n\n\/* \u2500\u2500 APPLY LABELS \u2500\u2500 *\/\nconst $a=s=>document.querySelector(s);\n$a('#acTitle').textContent=L.title;\n$a('#acDesc').textContent=L.desc;\n$a('#acLbEmail').textContent=L.lbEmail; $a('#acEmail').placeholder=L.phEmail;\n$a('#acLbName').textContent=L.lbName; $a('#acName').placeholder=L.phName;\n$a('#acLbArr').textContent=L.lbArr; $a('#acArr').placeholder=L.phArr;\n$a('#acLbDep').textContent=L.lbDep; $a('#acDep').placeholder=L.phDep;\n$a('#acConsentText').innerHTML=L.consent;\n$a('#acBtn').textContent=L.btn;\n$a('#acSuccessTitle').textContent=L.successTitle;\n$a('#acSuccessDesc').textContent=L.successDesc;\n$a('#acNote').textContent=L.note;\n\n\/* \u2500\u2500 SUBMIT \u2500\u2500 *\/\n$a('#auroraForm').addEventListener('submit', async function(e){\n  e.preventDefault();\n  const err=$a('#acError');err.style.display='none';\n  const email=$a('#acEmail').value.trim();\n  const consent=$a('#acConsent').checked;\n  if(!email||!consent){err.textContent=L.errorRequired;err.style.display='block';return;}\n\n  const btn=$a('#acBtn');btn.disabled=true;btn.textContent=L.sending;\n  const data={\n    email:email,\n    name:$a('#acName').value.trim(),\n    arrival:$a('#acArr').value||'',\n    departure:$a('#acDep').value||'',\n    lang:AL\n  };\n  try{\n    const r=await fetch(AURORA_CONFIG.endpoint,{\n      method:'POST',headers:{'Content-Type':'application\/json'},body:JSON.stringify(data)\n    });\n    if(!r.ok) throw 0;\n    $a('#auroraForm').style.display='none';\n    $a('#acSuccess').style.display='block';\n  }catch(e){\n    err.textContent=L.errorServer;err.style.display='block';\n    btn.disabled=false;btn.textContent=L.btn;\n  }\n});\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t<div class=\"elementor-element elementor-element-5b01750 elementor-widget elementor-widget-html\" data-id=\"5b01750\" data-element_type=\"widget\" data-e-type=\"widget\" data-widget_type=\"html.default\">\n\t\t\t\t<div class=\"elementor-widget-container\">\n\t\t\t\t\t<!--\n  NORTH WIND LAPLAND \u2014 LIVE NORTHERN LIGHTS DASHBOARD\n  \n  Paste this into a NEW Elementor HTML widget BELOW your existing signup form\n  on \/northern-light-alert\/.\n  \n  All CSS is scoped to .nwl-instance so it won't affect the rest of the page.\n  All JS is self-contained. No external dependencies except FontAwesome\n  (loaded from CDN inline below).\n-->\n\n<link rel=\"stylesheet\" href=\"https:\/\/cdnjs.cloudflare.com\/ajax\/libs\/font-awesome\/6.5.0\/css\/all.min.css\">\n\n<style>\n.nwl-instance{\n  --primary:#1a365d;--highlight:#63b3ed;\n  --text:#e2e8f0;--success:#48bb78;--warning:#ed8936;--danger:#f56565;\n  font-family:'Segoe UI',Tahoma,Geneva,Verdana,sans-serif;\n  color:var(--text);\n  margin:40px auto 0;\n  max-width:1200px;\n  padding:20px;\n  background:linear-gradient(135deg,#0f172a,#1e293b,#334155);\n  border-radius:20px;\n}\n.nwl-instance *{box-sizing:border-box}\n.nwl-instance .nwl-header{display:flex;justify-content:space-between;align-items:center;padding:20px 0;border-bottom:1px solid rgba(255,255,255,.1);margin-bottom:26px;flex-wrap:wrap;gap:15px}\n.nwl-instance .nwl-logo-row{display:flex;align-items:center;gap:14px}\n.nwl-instance .nwl-logo{width:60px;height:60px;border-radius:50%;background:linear-gradient(135deg,var(--highlight),#90cdf4);display:flex;align-items:center;justify-content:center;font-weight:900;color:var(--primary);font-size:24px;box-shadow:0 4px 10px rgba(99,179,237,.3)}\n.nwl-instance .nwl-brand-name{font-size:24px;font-weight:900}\n.nwl-instance .nwl-powered{font-size:14px;opacity:.85}\n.nwl-instance .nwl-powered a{color:var(--highlight);text-decoration:none}\n.nwl-instance .nwl-powered a:hover{text-decoration:underline}\n.nwl-instance .nwl-time{font-size:1.05rem;background:rgba(255,255,255,.05);padding:10px 14px;border-radius:10px;border:1px solid rgba(255,255,255,.1)}\n.nwl-instance .nwl-hero{text-align:center;padding:18px 0 26px;margin-bottom:10px}\n.nwl-instance .nwl-hero h1{font-size:2.45rem;margin:0 0 12px;background:linear-gradient(to right,#a8edea,#fed6e3);-webkit-background-clip:text;background-clip:text;color:transparent}\n.nwl-instance .nwl-hero p{font-size:1.15rem;max-width:900px;margin:0 auto 14px;opacity:.92}\n.nwl-instance .nwl-location{display:flex;justify-content:center;align-items:center;gap:8px;margin-top:8px;opacity:.85}\n.nwl-instance .nwl-btn{background:linear-gradient(to right,var(--highlight),#90cdf4);color:var(--primary);border:none;padding:12px 22px;border-radius:10px;font-weight:900;cursor:pointer;transition:.2s;display:inline-flex;align-items:center;gap:10px;justify-content:center;text-decoration:none;font-size:14px}\n.nwl-instance .nwl-btn:hover{transform:translateY(-2px);box-shadow:0 5px 15px rgba(99,179,237,.35)}\n.nwl-instance .nwl-btn:disabled{opacity:.6;cursor:not-allowed;transform:none;box-shadow:none}\n.nwl-instance .nwl-dashboard{display:grid;grid-template-columns:1fr;gap:22px;margin-bottom:24px}\n@media(min-width:769px){.nwl-instance .nwl-dashboard{grid-template-columns:1fr}}\n.nwl-instance .nwl-card{background:rgba(255,255,255,.05);border-radius:16px;padding:22px;box-shadow:0 10px 30px rgba(0,0,0,.2);backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.1);transition:.2s}\n.nwl-instance .nwl-card:hover{transform:translateY(-3px);box-shadow:0 15px 35px rgba(0,0,0,.3)}\n.nwl-instance .nwl-card h2{font-size:1.45rem;margin:0 0 16px;color:var(--highlight);display:flex;align-items:center;gap:10px}\n.nwl-instance .nwl-status{display:flex;align-items:center;gap:10px;margin-bottom:14px}\n.nwl-instance .nwl-dot{width:12px;height:12px;border-radius:50%}\n.nwl-instance .nwl-dot.active{background:var(--success);box-shadow:0 0 10px var(--success);animation:nwl-pulse 2s infinite}\n.nwl-instance .nwl-dot.inactive{background:var(--danger)}\n@keyframes nwl-pulse{0%{opacity:1}50%{opacity:.5}100%{opacity:1}}\n.nwl-instance .nwl-meter{height:30px;background:rgba(255,255,255,.1);border-radius:16px;overflow:hidden;position:relative;margin:14px 0}\n.nwl-instance .nwl-fill{height:100%;width:0%;background:linear-gradient(to right,var(--warning),var(--success));border-radius:16px;transition:width 1s}\n.nwl-instance .nwl-meter-text{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-weight:900;color:#fff;text-shadow:0 1px 3px rgba(0,0,0,.5)}\n.nwl-instance .nwl-aurora{height:190px;border-radius:12px;margin-top:14px;position:relative;overflow:hidden;background:linear-gradient(135deg,#0f2027,#2c5364);display:flex;align-items:center;justify-content:center}\n.nwl-instance .nwl-aurora::before{content:\"\";position:absolute;inset:-60%;background:linear-gradient(45deg,rgba(72,187,120,.2) 0%,rgba(99,179,237,.3) 25%,rgba(147,51,234,.2) 50%,rgba(236,72,153,.3) 75%,rgba(239,68,68,.2) 100%);animation:nwl-aurora 10s linear infinite;opacity:.75}\n@keyframes nwl-aurora{0%{transform:translate(-25%,-25%)}100%{transform:translate(25%,25%)}}\n.nwl-instance .nwl-aurora-msg{position:relative;z-index:1;font-weight:900;opacity:.95}\n.nwl-instance .nwl-factors{display:grid;grid-template-columns:1fr 1fr 1fr;gap:12px;margin-top:16px}\n@media(max-width:768px){.nwl-instance .nwl-factors{grid-template-columns:1fr}.nwl-instance .nwl-header{flex-direction:column;text-align:center}.nwl-instance .nwl-logo-row{justify-content:center}.nwl-instance .nwl-hero h1{font-size:2rem}}\n.nwl-instance .nwl-factor{background:rgba(255,255,255,.05);border-radius:12px;padding:14px;transition:.2s}\n.nwl-instance .nwl-factor:hover{background:rgba(255,255,255,.08)}\n.nwl-instance .nwl-factor.good{border-left:4px solid var(--success)}\n.nwl-instance .nwl-factor.moderate{border-left:4px solid var(--warning)}\n.nwl-instance .nwl-factor.poor{border-left:4px solid var(--danger)}\n.nwl-instance .nwl-factor h3{display:flex;align-items:center;gap:10px;font-size:1.05rem;margin:0}\n.nwl-instance .nwl-factor-value{font-size:1.55rem;font-weight:900;margin:8px 0}\n.nwl-instance .nwl-factor-status{font-size:.95rem;opacity:.9}\n.nwl-instance .nwl-source{font-size:.8rem;opacity:.6;margin-top:6px}\n.nwl-instance .nwl-history{margin-top:18px}\n.nwl-instance .nwl-item{display:flex;justify-content:space-between;align-items:center;gap:12px;padding:14px;background:rgba(255,255,255,.05);border-radius:12px;margin-bottom:12px;border-left:4px solid var(--highlight)}\n.nwl-instance .nwl-item-title{font-weight:900}\n.nwl-instance .nwl-item-time{font-size:.9rem;opacity:.8}\n.nwl-instance .nwl-item-meta{font-size:.82rem;opacity:.72;margin-top:4px}\n.nwl-instance .nwl-item-prob{font-weight:900;color:var(--highlight)}\n.nwl-instance .nwl-footer{text-align:center;padding:18px 0 12px;margin-top:18px;border-top:1px solid rgba(255,255,255,.1);opacity:.9}\n.nwl-instance .nwl-footer a{color:var(--highlight);text-decoration:none}\n.nwl-instance .nwl-footer a:hover{text-decoration:underline}\n.nwl-instance .nwl-footer a.nwl-book{font-family:'Akatab',sans-serif;font-size:2em;font-weight:900;color:#BAFCF8;text-decoration:none;display:inline-block;margin-top:16px;letter-spacing:.06em}\n.nwl-toast{position:fixed;top:20px;right:20px;max-width:520px;z-index:999999;padding:14px 16px;border-radius:10px;color:#fff;background:#48bb78;box-shadow:0 5px 15px rgba(0,0,0,.25);transform:translateX(150%);transition:transform .25s ease;display:flex;align-items:center;gap:10px;font-family:'Segoe UI',Tahoma,sans-serif}\n.nwl-toast.show{transform:translateX(0)}\n.nwl-toast.error{background:#f56565}\n.nwl-toast.warning{background:#ed8936}\n<\/style>\n\n<div class=\"nwl-instance\">\n  <header class=\"nwl-header\">\n    <div class=\"nwl-logo-row\">\n      <div class=\"nwl-logo\">NWL<\/div>\n      <div>\n        <div class=\"nwl-brand-name\">North Wind Lapland<\/div>\n        <div class=\"nwl-powered\">Powered by <a href=\"https:\/\/northwindlapland.com\" target=\"_blank\" rel=\"noopener\">northwindlapland.com<\/a><\/div>\n      <\/div>\n    <\/div>\n    <div class=\"nwl-time\" data-nwl=\"time\">--<\/div>\n  <\/header>\n\n  <section class=\"nwl-hero\">\n    <h1>Northern Lights Alert System<\/h1>\n    <p>Live aurora conditions over Yll\u00e4s, Finland \u2014 updated automatically every 15 minutes.<\/p>\n    <div class=\"nwl-location\"><i class=\"fa-solid fa-location-dot\"><\/i><span>Yll\u00e4s, Finnish Lapland<\/span><\/div>\n    <button class=\"nwl-btn\" type=\"button\" data-nwl=\"updateBtn\" style=\"margin-top:14px\">\n      <i class=\"fa-solid fa-rotate\"><\/i><span>Update Data<\/span>\n    <\/button>\n  <\/section>\n\n  <div class=\"nwl-dashboard\">\n    <div class=\"nwl-card\">\n      <h2><i class=\"fa-solid fa-chart-column\"><\/i> Current Probability<\/h2>\n      <div class=\"nwl-status\">\n        <div class=\"nwl-dot inactive\" data-nwl=\"dot\"><\/div>\n        <span data-nwl=\"status\">Loading data...<\/span>\n      <\/div>\n      <div class=\"nwl-meter\">\n        <div class=\"nwl-fill\" data-nwl=\"fill\"><\/div>\n        <div class=\"nwl-meter-text\" data-nwl=\"prob\">0%<\/div>\n      <\/div>\n      <p data-nwl=\"desc\">Calculating probability based on current conditions...<\/p>\n      <div class=\"nwl-aurora\">\n        <div class=\"nwl-aurora-msg\" data-nwl=\"auroraMsg\">Aurora conditions visualization<\/div>\n      <\/div>\n      <div class=\"nwl-factors\">\n        <div class=\"nwl-factor\" data-nwl=\"kpFactor\">\n          <h3><i class=\"fa-solid fa-chart-line\"><\/i> Kp Index<\/h3>\n          <div class=\"nwl-factor-value\" data-nwl=\"kpValue\">--<\/div>\n          <div class=\"nwl-factor-status\" data-nwl=\"kpStatus\">Loading...<\/div>\n          <div class=\"nwl-source\">NOAA Space Weather<\/div>\n        <\/div>\n        <div class=\"nwl-factor\" data-nwl=\"speedFactor\">\n          <h3><i class=\"fa-solid fa-wind\"><\/i> Solar Wind<\/h3>\n          <div class=\"nwl-factor-value\" data-nwl=\"speedValue\">-- km\/s<\/div>\n          <div class=\"nwl-factor-status\" data-nwl=\"speedStatus\">Loading...<\/div>\n          <div class=\"nwl-source\">DSCOVR Satellite<\/div>\n        <\/div>\n        <div class=\"nwl-factor\" data-nwl=\"cloudsFactor\">\n          <h3><i class=\"fa-solid fa-cloud\"><\/i> Cloud Coverage<\/h3>\n          <div class=\"nwl-factor-value\" data-nwl=\"cloudsValue\">--%<\/div>\n          <div class=\"nwl-factor-status\" data-nwl=\"cloudsStatus\">Loading...<\/div>\n          <div class=\"nwl-source\">Open-Meteo API<\/div>\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n\n  <div class=\"nwl-card nwl-history\">\n    <h2><i class=\"fa-solid fa-clock-rotate-left\"><\/i> Recent Updates<\/h2>\n    <div data-nwl=\"history\"><\/div>\n    <div style=\"margin-top:10px;opacity:.85\" data-nwl=\"last\">Last update: --<\/div>\n  <\/div>\n\n  <div class=\"nwl-footer\">\n    \u00a9 2026 North Wind Lapland | Yll\u00e4s, Finland |\n    <a href=\"https:\/\/northwindlapland.com\" target=\"_blank\" rel=\"noopener\">northwindlapland.com<\/a>\n    <div style=\"margin-top:10px;opacity:.75;font-size:.92rem\">\n      This service provides probability estimates based on available data. Actual aurora visibility may vary.\n    <\/div>\n    <a class=\"nwl-book\" href=\"https:\/\/northwindlapland.com\/northern-lights-experiences\/\" target=\"_blank\" rel=\"noopener\">\n      BOOK YOUR NORTHERN LIGHTS ADVENTURE HERE\n    <\/a>\n  <\/div>\n<\/div>\n\n<div class=\"nwl-toast\" data-nwl=\"toast\" aria-live=\"polite\">\n  <i class=\"fa-solid fa-bell\"><\/i>\n  <div data-nwl=\"toastMsg\">Notification<\/div>\n<\/div>\n\n<script>\n(function(){\n  \"use strict\";\n\n  var LAT = 67.567, LON = 24.25, TZ = \"Europe\/Helsinki\";\n  var SWPC_KP       = \"https:\/\/services.swpc.noaa.gov\/products\/noaa-planetary-k-index.json\";\n  var DSCOVR_PLASMA = \"\/wp-json\/nwl\/v1\/noaa-proxy?feed=plasma\";\n  var DSCOVR_MAG    = \"\/wp-json\/nwl\/v1\/noaa-proxy?feed=mag\";\n  var METEO = \"https:\/\/api.open-meteo.com\/v1\/forecast?latitude=\"+LAT+\"&longitude=\"+LON+\"&hourly=cloud_cover&timezone=\"+encodeURIComponent(TZ);\n  var SUN   = \"https:\/\/api.sunrise-sunset.org\/json?lat=\"+LAT+\"&lng=\"+LON+\"&formatted=0\";\n\n  var ALERT_THRESHOLD = 50;\n  var REFRESH_MS = 15 * 60 * 1000;\n\n  function fetchJson(url){\n    var u = url + (url.indexOf(\"?\")>=0?\"&\":\"?\")+\"_=\"+Date.now();\n    return fetch(u,{cache:\"no-store\"}).then(function(r){if(!r.ok)throw new Error(\"HTTP \"+r.status);return r.json();});\n  }\n\n  function lastNumericRow(arr,col){\n    if(!Array.isArray(arr))return null;\n    for(var i=arr.length-1;i>=0;i--){var row=arr[i];if(!Array.isArray(row)||row.length<=col)continue;var v=parseFloat(row[col]);if(isFinite(v))return row;}\n    return null;\n  }\n\n  function nearestHourIndex(times){\n    var now=Date.now(),best=0,diff=1e18;\n    for(var i=0;i<times.length;i++){var d=Math.abs(new Date(times[i]).getTime()-now);if(d<diff){diff=d;best=i;}}\n    return best;\n  }\n\n  function computeProb(data){\n    var kp=isFinite(data.kp)?data.kp:0, r=Math.round(kp);\n    var kpScore=r<=0?5:r===1?25:r===2?45:r===3?55:r===4?76:r===5?85:r===6?90:95;\n    var cloud=isFinite(data.cloudPct)?data.cloudPct:50;\n    var cf=cloud<=10?1:cloud<=30?.95:cloud<=50?.85:cloud<=70?.7:cloud<=90?.55:.4;\n    var df=data.isNight?1:.45;\n    return Math.round(Math.min(98,Math.max(5,kpScore*cf*df)));\n  }\n\n  function descProb(p){\n    if(p<15)return\"Aurora chance around \"+p+\"% \u2013 Very low, but not impossible.\";\n    if(p<35)return\"Aurora chance around \"+p+\"% \u2013 Low, but worth a quick look if the sky opens.\";\n    if(p<60)return\"Aurora chance around \"+p+\"% \u2013 Moderate. Go out during the clearest periods.\";\n    if(p<85)return\"Aurora chance around \"+p+\"% \u2013 High. Conditions are favorable; plan time outside.\";\n    return\"Aurora chance around \"+p+\"% \u2013 Very high. Strong auroras likely if skies are at least partly clear.\";\n  }\n\n  function descCloud(c){\n    if(!isFinite(c)||c==null)return\"Cloud cover data not available.\";\n    var r=Math.round(c);\n    if(r<=10)return\"Clear sky. Excellent visibility.\";\n    if(r<=30)return\"Mostly clear. Very good visibility.\";\n    if(r<=50)return\"Partly cloudy. Wait for gaps.\";\n    if(r<=70)return\"Many clouds. Watch for breaks.\";\n    if(r<=90)return\"Mostly cloudy. Only visible through breaks.\";\n    return\"Overcast. Unlikely to see from the ground.\";\n  }\n\n  function setFactor(factorEl,valueEl,statusEl,value,type){\n    var cls=\"poor\";\n    if(value==null||!isFinite(value)){\n      valueEl.textContent=type===\"speed\"?\"\u2013 km\/s\":type===\"clouds\"?\"--%\":\"\u2013\";\n      statusEl.textContent=\"No data\"; factorEl.className=\"nwl-factor\"; return;\n    }\n    if(type===\"kp\"){\n      valueEl.textContent=value.toFixed(1);\n      cls=value>=3?\"good\":value>=2?\"moderate\":\"poor\";\n      statusEl.textContent=value>=5?\"Excellent\":value>=3?\"Good\":value>=2?\"Moderate\":\"Poor\";\n    } else if(type===\"speed\"){\n      valueEl.textContent=Math.round(value)+\" km\/s\";\n      cls=value>=450?\"good\":value>=300?\"moderate\":\"poor\";\n      statusEl.textContent=value>=600?\"Excellent\":value>=450?\"Good\":value>=300?\"Moderate\":\"Poor\";\n    } else {\n      valueEl.textContent=Math.round(value)+\"%\";\n      cls=value<50?\"good\":value<80?\"moderate\":\"poor\";\n      statusEl.textContent=descCloud(value);\n    }\n    statusEl.style.color=cls===\"good\"?\"var(--success)\":cls===\"moderate\"?\"var(--warning)\":\"var(--danger)\";\n    factorEl.className=\"nwl-factor \"+cls;\n  }\n\n  function toast(state,msg,type){\n    type=type||\"success\";\n    state.toastMsg.textContent=msg;\n    state.toast.className=\"nwl-toast show\"+(type!==\"success\"?\" \"+type:\"\");\n    clearTimeout(state._tt);\n    state._tt=setTimeout(function(){state.toast.classList.remove(\"show\");},7000);\n  }\n\n  function addHistory(state,prob,data){\n    var timeStr=new Date().toLocaleTimeString(\"en-FI\",{hour:\"2-digit\",minute:\"2-digit\",timeZone:TZ});\n    var item=document.createElement(\"div\"); item.className=\"nwl-item\";\n    var left=document.createElement(\"div\");\n    left.innerHTML='<div class=\"nwl-item-title\">Probability update<\/div>'\n      +'<div class=\"nwl-item-time\">Today, '+timeStr+'<\/div>'\n      +'<div class=\"nwl-item-meta\">Kp: '+(data.kp!=null&&isFinite(data.kp)?data.kp.toFixed(1):\"\u2013\")\n      +' | Wind: '+(data.speed!=null&&isFinite(data.speed)?Math.round(data.speed):\"\u2013\")+' km\/s'\n      +' | Clouds: '+(data.cloudPct!=null&&isFinite(data.cloudPct)?Math.round(data.cloudPct):\"\u2013\")+'%<\/div>';\n    var right=document.createElement(\"div\"); right.className=\"nwl-item-prob\"; right.textContent=prob+\"%\";\n    item.appendChild(left); item.appendChild(right);\n    state.history.insertBefore(item,state.history.firstChild);\n    while(state.history.children.length>5)state.history.removeChild(state.history.lastChild);\n  }\n\n  function setUpdating(state,on){\n    state.updateBtn.disabled=on;\n    state.updateBtn.innerHTML=(on?'<i class=\"fa-solid fa-spinner fa-spin\"><\/i><span>Updating...<\/span>'\n      :'<i class=\"fa-solid fa-rotate\"><\/i><span>Update Data<\/span>');\n  }\n\n  function updateClock(state){\n    try{state.time.textContent=new Date().toLocaleString(\"en-FI\",{weekday:\"long\",year:\"numeric\",month:\"long\",day:\"numeric\",hour:\"2-digit\",minute:\"2-digit\",second:\"2-digit\",timeZone:TZ});}\n    catch(e){state.time.textContent=new Date().toString();}\n  }\n\n  function fetchAll(){\n    return Promise.all([\n      fetchJson(SWPC_KP).catch(function(){return null;}),\n      fetchJson(DSCOVR_PLASMA).catch(function(){return null;}),\n      fetchJson(DSCOVR_MAG).catch(function(){return null;}),\n      fetchJson(METEO).catch(function(){return null;}),\n      fetchJson(SUN).catch(function(){return null;})\n    ]).then(function(res){\n      var kpD=res[0],plasma=res[1],mag=res[2],meteo=res[3],sun=res[4];\n      var kp=null,speed=null,bz=null,cloudPct=null,isNight=true;\n\n      \/\/ Kp \u2014 handles both new object format {Kp: 3.33} and legacy array format\n      if(Array.isArray(kpD)){\n        for(var i=kpD.length-1;i>=0;i--){\n          var row=kpD[i], v=null;\n          if(row && typeof row===\"object\" && !Array.isArray(row)){\n            v = parseFloat(row.Kp!=null ? row.Kp : row.kp_index);\n          } else if(Array.isArray(row) && row.length>1){\n            v = parseFloat(row[1]);\n          }\n          if(isFinite(v)){ kp=v; break; }\n        }\n      }\n\n      \/\/ Solar wind speed \u2014 new NOAA format is array of objects, newest first\nif(Array.isArray(plasma)){\n  for(var i=0;i<plasma.length;i++){\n    var row=plasma[i];\n    if(row && row.proton_speed!=null && isFinite(row.proton_speed)){\n      speed=parseFloat(row.proton_speed); break;\n    }\n  }\n}\n\n\/\/ Bz \u2014 same new object format\nif(Array.isArray(mag)){\n  for(var j=0;j<mag.length;j++){\n    var rowM=mag[j];\n    if(rowM){\n      var bzVal = rowM.bz_gsm!=null ? rowM.bz_gsm : (rowM.bz!=null ? rowM.bz : null);\n      if(bzVal!=null && isFinite(bzVal)){ bz=parseFloat(bzVal); break; }\n    }\n  }\n}\n\n      if(meteo&&meteo.hourly&&Array.isArray(meteo.hourly.time)){\n        var idx=nearestHourIndex(meteo.hourly.time);\n        cloudPct=meteo.hourly.cloud_cover[idx];\n      }\n      if(sun&&sun.status===\"OK\"&&sun.results){\n        var now=new Date(), sr=new Date(sun.results.sunrise), ss=new Date(sun.results.sunset);\n        isNight=(now<sr||now>ss);\n      }\n      return{kp:kp,speed:speed,bz:bz,cloudPct:cloudPct,isNight:isNight};\n    });\n  }\n\n  function updateUI(state,prob,data){\n    state.fill.style.width=prob+\"%\";\n    state.prob.textContent=prob+\"%\";\n    state.desc.textContent=descProb(prob);\n    if(prob>=ALERT_THRESHOLD){\n      state.dot.className=\"nwl-dot active\";\n      state.status.textContent=\"High probability of Northern Lights!\";\n      state.status.style.color=\"var(--success)\";\n      state.auroraMsg.textContent=\"High Aurora Activity Expected\";\n    } else {\n      state.dot.className=\"nwl-dot inactive\";\n      state.status.textContent=\"Lower probability of Northern Lights at the moment\";\n      state.status.style.color=\"var(--text)\";\n      state.auroraMsg.textContent=\"Lower Aurora Activity Expected\";\n    }\n    setFactor(state.kpFactor,state.kpValue,state.kpStatus,data.kp,\"kp\");\n    setFactor(state.speedFactor,state.speedValue,state.speedStatus,data.speed,\"speed\");\n    setFactor(state.cloudsFactor,state.cloudsValue,state.cloudsStatus,data.cloudPct,\"clouds\");\n    addHistory(state,prob,data);\n    state.last.textContent=\"Last update: \"+new Date().toLocaleString(undefined,{timeZone:TZ});\n  }\n\n  function runUpdate(state){\n    setUpdating(state,true);\n    toast(state,\"Fetching live data\u2026\");\n    return fetchAll().then(function(data){\n      var prob=computeProb(data);\n      updateUI(state,prob,data);\n      toast(state,\"Data updated successfully!\");\n    }).catch(function(err){\n      toast(state,\"Update failed: \"+(err&&err.message?err.message:\"Unknown error\"),\"error\");\n    }).finally(function(){setUpdating(state,false);});\n  }\n\n  var root=document.querySelector(\".nwl-instance\");\n  var state={\n    time:root.querySelector('[data-nwl=\"time\"]'),\n    dot:root.querySelector('[data-nwl=\"dot\"]'),\n    status:root.querySelector('[data-nwl=\"status\"]'),\n    fill:root.querySelector('[data-nwl=\"fill\"]'),\n    prob:root.querySelector('[data-nwl=\"prob\"]'),\n    desc:root.querySelector('[data-nwl=\"desc\"]'),\n    auroraMsg:root.querySelector('[data-nwl=\"auroraMsg\"]'),\n    updateBtn:root.querySelector('[data-nwl=\"updateBtn\"]'),\n    kpFactor:root.querySelector('[data-nwl=\"kpFactor\"]'),\n    kpValue:root.querySelector('[data-nwl=\"kpValue\"]'),\n    kpStatus:root.querySelector('[data-nwl=\"kpStatus\"]'),\n    speedFactor:root.querySelector('[data-nwl=\"speedFactor\"]'),\n    speedValue:root.querySelector('[data-nwl=\"speedValue\"]'),\n    speedStatus:root.querySelector('[data-nwl=\"speedStatus\"]'),\n    cloudsFactor:root.querySelector('[data-nwl=\"cloudsFactor\"]'),\n    cloudsValue:root.querySelector('[data-nwl=\"cloudsValue\"]'),\n    cloudsStatus:root.querySelector('[data-nwl=\"cloudsStatus\"]'),\n    history:root.querySelector('[data-nwl=\"history\"]'),\n    last:root.querySelector('[data-nwl=\"last\"]'),\n    toast:document.querySelector('[data-nwl=\"toast\"]'),\n    toastMsg:document.querySelector('[data-nwl=\"toastMsg\"]')\n  };\n\n  updateClock(state);\n  setInterval(function(){updateClock(state);},1000);\n\n  state.updateBtn.addEventListener(\"click\",function(){runUpdate(state);});\n\n  runUpdate(state);\n  setInterval(function(){runUpdate(state);},REFRESH_MS);\n})();\n<\/script>\t\t\t\t<\/div>\n\t\t\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/div>\n\t\t\t\t\t<\/div>\n\t\t<\/section>\n\t\t\t\t<\/div>\n\t\t","protected":false},"excerpt":{"rendered":"<p>\ud83c\udf0c \u2728 NWL North Wind Lapland Powered by northwindlapland.com &#8212; Northern Lights Alert System Live aurora conditions over Yll\u00e4s, Finland \u2014 updated automatically every 15 minutes. Yll\u00e4s, Finnish Lapland Update Data Current Probability Loading data&#8230; 0% Calculating probability based on current conditions&#8230; Aurora conditions visualization Kp Index &#8212; Loading&#8230; NOAA Space Weather Solar Wind &#8212; [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":4862,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"elementor_header_footer","meta":{"_acf_changed":false,"footnotes":""},"class_list":["post-4859","page","type-page","status-publish","has-post-thumbnail","hentry"],"acf":[],"_links":{"self":[{"href":"https:\/\/northwindlapland.com\/fr\/wp-json\/wp\/v2\/pages\/4859","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/northwindlapland.com\/fr\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/northwindlapland.com\/fr\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/northwindlapland.com\/fr\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/northwindlapland.com\/fr\/wp-json\/wp\/v2\/comments?post=4859"}],"version-history":[{"count":181,"href":"https:\/\/northwindlapland.com\/fr\/wp-json\/wp\/v2\/pages\/4859\/revisions"}],"predecessor-version":[{"id":7695,"href":"https:\/\/northwindlapland.com\/fr\/wp-json\/wp\/v2\/pages\/4859\/revisions\/7695"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/northwindlapland.com\/fr\/wp-json\/wp\/v2\/media\/4862"}],"wp:attachment":[{"href":"https:\/\/northwindlapland.com\/fr\/wp-json\/wp\/v2\/media?parent=4859"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}