{"id":258,"date":"2025-08-22T04:59:07","date_gmt":"2025-08-22T04:59:07","guid":{"rendered":"https:\/\/bioskinetics.com.au\/?page_id=258"},"modified":"2025-08-22T05:18:33","modified_gmt":"2025-08-22T05:18:33","slug":"sleep-tracker-world-clock","status":"publish","type":"page","link":"https:\/\/bioskinetics.com.au\/?page_id=258","title":{"rendered":"Sleep Tracker World Clock"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\"><\/h2>\n\n\n\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\" \/>\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" \/>\n<title>Which City Are You?<\/title>\n<style>\n  :root {\n    --bg: #0f1222;\n    --card: #171a2b;\n    --ink: #e7ecf7;\n    --muted: #a5b0c6;\n    --accent: #7dd3fc;\n    --good: #22c55e;\n    --warn: #f59e0b;\n    --bad: #ef4444;\n    --lock: #94a3b8;\n  }\n  *{box-sizing:border-box}\n  body{\n    margin:0; font-family:system-ui,-apple-system,Segoe UI,Roboto,Inter,Arial;\n    color:var(--ink); background:radial-gradient(1200px 600px at 80% -20%,#1b1f3b 10%,#0f1222 60%);\n  }\n  header{\n    padding:32px 16px 16px; text-align:center;\n  }\n  h1{margin:0 0 6px; font-size:clamp(26px,4.5vw,40px)}\n  p.sub{margin:0; color:var(--muted)}\n  .wrap{max-width:1200px; margin:0 auto; padding:16px}\n  .grid{display:grid; gap:16px; grid-template-columns:1.4fr .9fr}\n  @media (max-width: 980px){ .grid{grid-template-columns:1fr; } }\n  .card{\n    background:linear-gradient(180deg, #1a1e35 0%, #111427 100%);\n    border:1px solid #232746; border-radius:16px; overflow:hidden; box-shadow:0 10px 30px rgba(0,0,0,.35)\n  }\n  .card h2{margin:0; padding:16px 18px; border-bottom:1px solid #232746; font-size:18px}\n  .card .body{padding:16px 18px}\n  #map{height:540px; width:100%}\n  .legend{display:flex; gap:8px; align-items:center; font-size:12px; color:var(--muted)}\n  .badge{padding:2px 8px; border-radius:999px; border:1px solid #2b3054; background:#141733}\n  .row{display:flex; gap:12px; flex-wrap:wrap; align-items:center}\n  .stats{display:grid; grid-template-columns:repeat(3,1fr); gap:12px}\n  .stat{padding:12px; border:1px solid #232746; background:#12152b; border-radius:12px; text-align:center}\n  .stat .k{font-size:22px; font-weight:700}\n  .muted{color:var(--muted)}\n  .pill{display:inline-flex; align-items:center; gap:8px; background:#12152b; border:1px solid #232746; padding:10px 12px; border-radius:12px}\n  .btn{\n    display:inline-flex; align-items:center; justify-content:center; gap:8px;\n    padding:12px 16px; border-radius:12px; border:1px solid #2b3054; background:#101333; color:var(--ink);\n    text-decoration:none; cursor:pointer; transition:.2s transform, .2s box-shadow\n  }\n  .btn:hover{transform:translateY(-1px); box-shadow:0 6px 20px rgba(0,0,0,.25)}\n  .btn.primary{background:linear-gradient(90deg,#22d3ee,#3b82f6); border:none; color:white}\n  .btn.ghost{background:transparent}\n  .lock{color:var(--lock)}\n  .paid-block{\n    border:1px dashed #334; border-radius:14px; padding:16px; position:relative; background:linear-gradient(180deg,#10132a, #0d1126)\n  }\n  .paid-block .overlay{\n    position:absolute; inset:0; display:flex; align-items:center; justify-content:center;\n    background:linear-gradient(180deg, rgba(16,19,42,.0), rgba(16,19,42,.8) 60% 100%);\n    pointer-events:none\n  }\n  .paid-block h3{margin:0 0 8px}\n  .list{margin:0; padding-left:18px; color:var(--muted)}\n  .footnote{font-size:12px; color:var(--muted)}\n  \/* Modal *\/\n  .modal{position:fixed; inset:0; display:none; align-items:center; justify-content:center; background:rgba(4,6,15,.72); z-index:9999}\n  .modal.open{display:flex}\n  .modal .sheet{width:min(680px,95vw); background:#0f1224; border:1px solid #232746; border-radius:16px; overflow:hidden; box-shadow:0 20px 60px rgba(0,0,0,.6)}\n  .sheet header{padding:14px 16px; border-bottom:1px solid #232746; text-align:left}\n  .sheet header h3{margin:0}\n  .sheet .content{padding:16px}\n  .q{margin-bottom:14px}\n  .q label{display:block; margin-bottom:8px}\n  .q .opts{display:grid; gap:8px}\n  .radio{display:flex; gap:8px; align-items:center}\n  .x{position:absolute; right:14px; top:10px; background:transparent; border:none; color:#98a2b3; font-size:20px; cursor:pointer}\n  .hr{height:1px; background:#232746; margin:16px 0}\n  .charts{height:220px}\n  .spark{height:120px; width:100%; display:block}\n  .table{width:100%; border-collapse:collapse; font-size:14px}\n  .table th, .table td{border-bottom:1px solid #232746; padding:8px 6px; text-align:left}\n  .tag{font-size:12px; padding:3px 8px; border-radius:999px; background:#0f1538; border:1px solid #253056; color:#bcd}\n<\/style>\n\n<!-- Leaflet + HeatLayer -->\n<link rel=\"stylesheet\" href=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.css\"\/>\n<script src=\"https:\/\/unpkg.com\/leaflet@1.9.4\/dist\/leaflet.js\"><\/script>\n<script src=\"https:\/\/unpkg.com\/leaflet.heat\/dist\/leaflet-heat.js\"><\/script>\n\n<!-- Stripe Buy Button (client-only, no server needed) -->\n<script async src=\"https:\/\/js.stripe.com\/v3\/buy-button.js\"><\/script>\n<\/head>\n<body>\n\n<header>\n  <h1>Sleep Tracker World Clock<\/h1>\n  <p class=\"sub\">Live global map of sleep &amp; wake cycles across major cities \u2014 and how you compare.<\/p>\n<\/header>\n\n<div class=\"wrap\">\n  <div class=\"grid\">\n    <!-- MAP CARD -->\n    <section class=\"card\">\n      <h2>Real-Time Sleep\/Wake Heatmap<\/h2>\n      <div class=\"body\">\n        <div id=\"map\"><\/div>\n        <div class=\"row\" style=\"margin-top:10px; justify-content:space-between;\">\n          <div class=\"legend\">\n            <span class=\"badge\">Now<\/span>\n            <span class=\"muted\">Blue = more people asleep \u00b7 Gold = waking \u00b7 Red = active<\/span>\n          <\/div>\n          <div class=\"row\">\n            <button class=\"btn\" id=\"btnQuiz\">\u201cHow normal is my sleep?\u201d<\/button>\n            <a class=\"btn ghost\" id=\"btnRefresh\">Refresh Data<\/a>\n          <\/div>\n        <\/div>\n      <\/div>\n    <\/section>\n\n    <!-- INSIGHTS CARD -->\n    <section class=\"card\">\n      <h2>Today\u2019s Snapshot<\/h2>\n      <div class=\"body\">\n        <div class=\"stats\">\n          <div class=\"stat\">\n            <div class=\"k\" id=\"kCities\">\u2013<\/div>\n            <div class=\"muted\">Cities Tracked<\/div>\n          <\/div>\n          <div class=\"stat\">\n            <div class=\"k\" id=\"kBed\">\u2013<\/div>\n            <div class=\"muted\">Avg Bedtime<\/div>\n          <\/div>\n          <div class=\"stat\">\n            <div class=\"k\" id=\"kWake\">\u2013<\/div>\n            <div class=\"muted\">Avg Wake<\/div>\n          <\/div>\n        <\/div>\n\n        <div class=\"hr\"><\/div>\n\n        <div class=\"row\">\n          <span class=\"pill\"><span class=\"tag\">Free<\/span> City bedtime\/wake-up tables<\/span>\n          <span class=\"pill\"><span class=\"tag\">Free<\/span> Real-time heatmap<\/span>\n          <span class=\"pill\"><span class=\"tag\">Pro<\/span> Personalized coaching<\/span>\n        <\/div>\n\n        <div class=\"hr\"><\/div>\n\n        <!-- Paid blocks (locked preview) -->\n        <div class=\"paid-block\" style=\"margin-bottom:12px\">\n          <h3 class=\"lock\">\ud83d\udd12 Personalized Sleep Recommendations<\/h3>\n          <p class=\"muted\">AI-guided habits tailored to your chronotype, jet lag risk, and schedule.<\/p>\n          <!-- Stripe Buy Button (replace attributes with your own) -->\n          <stripe-buy-button\n              buy-button-id=\"buy_btn_XXXXdemo\"\n              data-publishable-key=pk_live_51QlMNxRqoS6Xq886zs3ibMrRlyEVhNdv0b9fOkPXNTeS9uUk6l2tuxTOMpLyifXf7TTdlRH5RrhKiauUcu2WLdpp00zAZxnBUZ\n          ><\/stripe-buy-button>\n          <!-- If you prefer Payment Link instead, uncomment: \n          <a class=\"btn primary\" href=\"https:\/\/buy.stripe.com\/your_payment_link\" target=\"_blank\" rel=\"noopener\">Unlock Pro \u2013 $7<\/a>\n          -->\n        <\/div>\n\n        <div class=\"paid-block\" style=\"margin-bottom:12px\">\n          <h3 class=\"lock\">\ud83d\udd12 Historical Trend Data by City<\/h3>\n          <p class=\"muted\">Track how bedtime and wake times shift across seasons and events.<\/p>\n          <stripe-buy-button\n              buy-button-id=\"buy_btn_XXXXdemo\"\n              data-publishable-key=pk_live_51QlMNxRqoS6Xq886zs3ibMrRlyEVhNdv0b9fOkPXNTeS9uUk6l2tuxTOMpLyifXf7TTdlRH5RrhKiauUcu2WLdpp00zAZxnBUZ\n          ><\/stripe-buy-button>\n        <\/div>\n\n        <div class=\"paid-block\">\n          <h3 class=\"lock\">\ud83d\udd12 Exportable Charts &amp; CSV<\/h3>\n          <p class=\"muted\">Download graphs and datasets for your health app or clinician.<\/p>\n          <stripe-buy-button\n              buy-button-id=\"buy_btn_XXXXdemo\"\n              data-publishable-key=pk_live_51QlMNxRqoS6Xq886zs3ibMrRlyEVhNdv0b9fOkPXNTeS9uUk6l2tuxTOMpLyifXf7TTdlRH5RrhKiauUcu2WLdpp00zAZxnBUZ\n          ><\/stripe-buy-button>\n          <p class=\"footnote\">Your purchase unlocks Pro content instantly after checkout.<\/p>\n        <\/div>\n      <\/div>\n    <\/section>\n\n    <!-- TABLES CARD -->\n    <section class=\"card\">\n      <h2>Average Bedtime &amp; Wake-Up by City (Local Time)<\/h2>\n      <div class=\"body\" style=\"overflow:auto; max-height:420px\">\n        <table class=\"table\" id=\"cityTable\">\n          <thead><tr><th>City<\/th><th>Bedtime<\/th><th>Wake-Up<\/th><th>Status<\/th><\/tr><\/thead>\n          <tbody><\/tbody>\n        <\/table>\n      <\/div>\n    <\/section>\n\n    <!-- HOW IT WORKS CARD -->\n    <section class=\"card\">\n      <h2>How It Works<\/h2>\n      <div class=\"body\">\n        <p>We aggregate anonymized signals (e.g., wearable\/app check-ins, local activity proxies) to estimate when a city is mostly asleep, waking, or active.<\/p>\n        <ul class=\"list\">\n          <li>Auto-updates every 15 minutes (or press <em>Refresh<\/em>).<\/li>\n          <li>Times displayed in each city\u2019s local timezone.<\/li>\n          <li>No personal data collected on this page.<\/li>\n        <\/ul>\n        <div class=\"hr\"><\/div>\n        <div class=\"row\">\n          <a class=\"btn\" id=\"btnShare\">Share<\/a>\n          <a class=\"btn\" id=\"btnCopy\">Copy Link<\/a>\n        <\/div>\n      <\/div>\n    <\/section>\n  <\/div>\n<\/div>\n\n<!-- QUIZ MODAL -->\n<div class=\"modal\" id=\"quizModal\" aria-hidden=\"true\">\n  <div class=\"sheet\">\n    <header>\n      <h3>How Normal Is Your Sleep?<\/h3>\n      <button class=\"x\" id=\"xQuiz\" aria-label=\"Close\">\u00d7<\/button>\n    <\/header>\n    <div class=\"content\">\n      <form id=\"quizForm\">\n        <div class=\"q\">\n          <label>What time do you usually go to bed?<\/label>\n          <div class=\"opts\">\n            <label class=\"radio\"><input type=\"radio\" name=\"bed\" value=\"early\" required> Before 10:30 pm<\/label>\n            <label class=\"radio\"><input type=\"radio\" name=\"bed\" value=\"mid\"> 10:30 pm \u2013 12:30 am<\/label>\n            <label class=\"radio\"><input type=\"radio\" name=\"bed\" value=\"late\"> After 12:30 am<\/label>\n          <\/div>\n        <\/div>\n        <div class=\"q\">\n          <label>How long does it take to fall asleep?<\/label>\n          <div class=\"opts\">\n            <label class=\"radio\"><input type=\"radio\" name=\"latency\" value=\"ok\" required> 10\u201320 min<\/label>\n            <label class=\"radio\"><input type=\"radio\" name=\"latency\" value=\"warn\"> 20\u201345 min<\/label>\n            <label class=\"radio\"><input type=\"radio\" name=\"latency\" value=\"bad\"> 45+ min<\/label>\n          <\/div>\n        <\/div>\n        <div class=\"q\">\n          <label>Do you wake during the night?<\/label>\n          <div class=\"opts\">\n            <label class=\"radio\"><input type=\"radio\" name=\"wake\" value=\"rare\" required> Rarely<\/label>\n            <label class=\"radio\"><input type=\"radio\" name=\"wake\" value=\"some\"> 1\u20132 times<\/label>\n            <label class=\"radio\"><input type=\"radio\" name=\"wake\" value=\"often\"> 3+ times<\/label>\n          <\/div>\n        <\/div>\n        <div class=\"q\">\n          <label>How refreshed do you feel in the morning?<\/label>\n          <div class=\"opts\">\n            <label class=\"radio\"><input type=\"radio\" name=\"ref\" value=\"good\" required> Refreshed<\/label>\n            <label class=\"radio\"><input type=\"radio\" name=\"ref\" value=\"meh\"> Meh<\/label>\n            <label class=\"radio\"><input type=\"radio\" name=\"ref\" value=\"poor\"> Tired<\/label>\n          <\/div>\n        <\/div>\n        <div class=\"q\">\n          <label>Average total sleep time?<\/label>\n          <div class=\"opts\">\n            <label class=\"radio\"><input type=\"radio\" name=\"dur\" value=\"ok\" required> 7\u20139 hours<\/label>\n            <label class=\"radio\"><input type=\"radio\" name=\"dur\" value=\"warn\"> 6\u20137 or 9\u201310<\/label>\n            <label class=\"radio\"><input type=\"radio\" name=\"dur\" value=\"bad\"> &lt;6 or &gt;10<\/label>\n          <\/div>\n        <\/div>\n        <div class=\"row\" style=\"justify-content:flex-end; gap:8px\">\n          <button type=\"button\" class=\"btn\" id=\"btnCancelQuiz\">Cancel<\/button>\n          <button type=\"submit\" class=\"btn primary\">See Result<\/button>\n        <\/div>\n      <\/form>\n      <div id=\"quizResult\" style=\"display:none\">\n        <div class=\"hr\"><\/div>\n        <h3 id=\"qrTitle\">Your Sleep Score<\/h3>\n        <p class=\"muted\" id=\"qrText\"><\/p>\n        <div class=\"row\" style=\"gap:8px\">\n          <stripe-buy-button\n              buy-button-id=\"buy_btn_XXXXdemo\"\n              data-publishable-key=pk_live_51QlMNxRqoS6Xq886zs3ibMrRlyEVhNdv0b9fOkPXNTeS9uUk6l2tuxTOMpLyifXf7TTdlRH5RrhKiauUcu2WLdpp00zAZxnBUZ\n          ><\/stripe-buy-button>\n          <!-- Or Payment Link:\n          <a class=\"btn primary\" href=\"https:\/\/buy.stripe.com\/your_payment_link\" target=\"_blank\">Unlock Personalized Plan<\/a>\n          -->\n        <\/div>\n      <\/div>\n    <\/div>\n  <\/div>\n<\/div>\n\n<script>\n\/* ------------------------------\n   CONFIG\n--------------------------------*\/\nconst DATA_SHEET_URL = \"\"; \n\/\/ Paste a public CSV URL from a published Google Sheet with columns:\n\/\/ City,Lat,Lng,AvgBedtime,AvgWake,Status   (Status = asleep|waking|active)\n\/\/ Leave blank to use demo data.\n\nconst AUTO_REFRESH_MS = 15 * 60 * 1000;\n\n\/* ------------------------------\n   MAP + HEAT\n--------------------------------*\/\nlet map, heatLayer;\nconst statusColor = s => s === 'asleep' ? '#60a5fa' : s === 'waking' ? '#f59e0b' : '#ef4444';\n\nfunction initMap(){\n  map = L.map('map',{worldCopyJump:true, zoomControl:false}).setView([20,0], 2);\n  L.tileLayer('https:\/\/{s}.tile.openstreetmap.org\/{z}\/{x}\/{y}.png',{\n    attribution:'&copy; OpenStreetMap'\n  }).addTo(map);\n  heatLayer = L.heatLayer([], {radius: 20, blur: 24, maxZoom: 6}).addTo(map);\n}\n\nfunction toHeatPoints(rows){\n  \/\/ asleep low intensity (cool), waking mid, active high\n  return rows.map(r => {\n    const w = r.Status === 'asleep' ? 0.2 : r.Status === 'waking' ? 0.5 : 0.9;\n    return [parseFloat(r.Lat), parseFloat(r.Lng), w];\n  });\n}\n\nfunction renderMarkers(rows){\n  \/\/ Simple colored circle markers by status\n  rows.forEach(r=>{\n    const circle = L.circleMarker([r.Lat, r.Lng], {\n      radius:6, weight:1, color:'#0b1028', fillColor: statusColor(r.Status), fillOpacity:.9\n    }).addTo(map);\n    circle.bindPopup(`<b>${r.City}<\/b><br>Bed: ${r.AvgBedtime}<br>Wake: ${r.AvgWake}<br>Status: ${r.Status}`);\n  });\n}\n\n\/* ------------------------------\n   DATA FETCH \/ PARSE\n--------------------------------*\/\nfunction csvToRows(csv){\n  const [head, ...lines] = csv.trim().split(\/\\r?\\n\/);\n  const keys = head.split(',').map(s=>s.trim());\n  return lines.map(line=>{\n    const cells = line.split(',').map(s=>s.trim());\n    const obj = {};\n    keys.forEach((k,i)=> obj[k] = cells[i]);\n    return obj;\n  });\n}\n\nasync function fetchData(){\n  if(!DATA_SHEET_URL){\n    \/\/ Demo dataset (you can replace with a Sheet)\n    return [\n\/\/ Oceania\n    {City:\"Melbourne\",Lat:-37.8136,Lng:144.9631,AvgBedtime:\"11:08 pm\",AvgWake:\"6:54 am\",Status:localStatus(10)},\n    {City:\"Sydney\",Lat:-33.8688,Lng:151.2093,AvgBedtime:\"10:56 pm\",AvgWake:\"6:38 am\",Status:localStatus(10)},\n    {City:\"Auckland\",Lat:-36.8485,Lng:174.7633,AvgBedtime:\"11:22 pm\",AvgWake:\"7:05 am\",Status:localStatus(12)},\n\n    \/\/ East Asia\n    {City:\"Tokyo\",Lat:35.6762,Lng:139.6503,AvgBedtime:\"12:10 am\",AvgWake:\"7:22 am\",Status:localStatus(9)},\n    {City:\"Beijing\",Lat:39.9042,Lng:116.4074,AvgBedtime:\"11:45 pm\",AvgWake:\"7:00 am\",Status:localStatus(8)},\n    {City:\"Shanghai\",Lat:31.2304,Lng:121.4737,AvgBedtime:\"11:40 pm\",AvgWake:\"7:10 am\",Status:localStatus(8)},\n    {City:\"Hong Kong\",Lat:22.3193,Lng:114.1694,AvgBedtime:\"12:00 am\",AvgWake:\"7:20 am\",Status:localStatus(8)},\n    {City:\"Seoul\",Lat:37.5665,Lng:126.9780,AvgBedtime:\"12:10 am\",AvgWake:\"7:15 am\",Status:localStatus(9)},\n\n    \/\/ South Asia\n    {City:\"Delhi\",Lat:28.7041,Lng:77.1025,AvgBedtime:\"11:30 pm\",AvgWake:\"6:45 am\",Status:localStatus(5.5)},\n    {City:\"Mumbai\",Lat:19.0760,Lng:72.8777,AvgBedtime:\"11:50 pm\",AvgWake:\"7:20 am\",Status:localStatus(5.5)},\n    {City:\"Bangalore\",Lat:12.9716,Lng:77.5946,AvgBedtime:\"11:40 pm\",AvgWake:\"7:05 am\",Status:localStatus(5.5)},\n    {City:\"Dhaka\",Lat:23.8103,Lng:90.4125,AvgBedtime:\"11:45 pm\",AvgWake:\"7:15 am\",Status:localStatus(6)},\n\n    \/\/ Middle East\n    {City:\"Dubai\",Lat:25.276987,Lng:55.296249,AvgBedtime:\"12:15 am\",AvgWake:\"7:45 am\",Status:localStatus(4)},\n    {City:\"Riyadh\",Lat:24.7136,Lng:46.6753,AvgBedtime:\"12:30 am\",AvgWake:\"8:00 am\",Status:localStatus(3)},\n    {City:\"Istanbul\",Lat:41.0082,Lng:28.9784,AvgBedtime:\"12:00 am\",AvgWake:\"7:15 am\",Status:localStatus(3)},\n\n    \/\/ Africa\n    {City:\"Cairo\",Lat:30.0444,Lng:31.2357,AvgBedtime:\"12:10 am\",AvgWake:\"7:20 am\",Status:localStatus(2)},\n    {City:\"Lagos\",Lat:6.5244,Lng:3.3792,AvgBedtime:\"11:30 pm\",AvgWake:\"6:30 am\",Status:localStatus(1)},\n    {City:\"Johannesburg\",Lat:-26.2041,Lng:28.0473,AvgBedtime:\"11:15 pm\",AvgWake:\"6:45 am\",Status:localStatus(2)},\n\n    \/\/ Europe\n    {City:\"London\",Lat:51.5072,Lng:-0.1276,AvgBedtime:\"11:34 pm\",AvgWake:\"7:05 am\",Status:localStatus(0)},\n    {City:\"Paris\",Lat:48.8566,Lng:2.3522,AvgBedtime:\"11:40 pm\",AvgWake:\"7:15 am\",Status:localStatus(1)},\n    {City:\"Berlin\",Lat:52.5200,Lng:13.4050,AvgBedtime:\"11:47 pm\",AvgWake:\"7:12 am\",Status:localStatus(1)},\n    {City:\"Madrid\",Lat:40.4168,Lng:-3.7038,AvgBedtime:\"12:30 am\",AvgWake:\"8:15 am\",Status:localStatus(1)},\n    {City:\"Rome\",Lat:41.9028,Lng:12.4964,AvgBedtime:\"12:05 am\",AvgWake:\"7:30 am\",Status:localStatus(1)},\n    {City:\"Amsterdam\",Lat:52.3676,Lng:4.9041,AvgBedtime:\"11:55 pm\",AvgWake:\"7:10 am\",Status:localStatus(1)},\n    {City:\"Moscow\",Lat:55.7558,Lng:37.6173,AvgBedtime:\"12:10 am\",AvgWake:\"7:25 am\",Status:localStatus(3)},\n\n    \/\/ North America\n    {City:\"New York\",Lat:40.7128,Lng:-74.0060,AvgBedtime:\"12:03 am\",AvgWake:\"7:18 am\",Status:localStatus(-5)},\n    {City:\"Los Angeles\",Lat:34.0522,Lng:-118.2437,AvgBedtime:\"11:58 pm\",AvgWake:\"7:20 am\",Status:localStatus(-8)},\n    {City:\"Chicago\",Lat:41.8781,Lng:-87.6298,AvgBedtime:\"12:02 am\",AvgWake:\"7:10 am\",Status:localStatus(-6)},\n    {City:\"Toronto\",Lat:43.6532,Lng:-79.3832,AvgBedtime:\"11:58 pm\",AvgWake:\"7:11 am\",Status:localStatus(-5)},\n    {City:\"Mexico City\",Lat:19.4326,Lng:-99.1332,AvgBedtime:\"11:50 pm\",AvgWake:\"7:10 am\",Status:localStatus(-6)},\n\n    \/\/ South America\n    {City:\"S\u00e3o Paulo\",Lat:-23.5505,Lng:-46.6333,AvgBedtime:\"12:20 am\",AvgWake:\"7:40 am\",Status:localStatus(-3)},\n    {City:\"Buenos Aires\",Lat:-34.6037,Lng:-58.3816,AvgBedtime:\"12:30 am\",AvgWake:\"8:00 am\",Status:localStatus(-3)},\n    {City:\"Bogot\u00e1\",Lat:4.7110,Lng:-74.0721,AvgBedtime:\"11:45 pm\",AvgWake:\"7:10 am\",Status:localStatus(-5)},\n    {City:\"Lima\",Lat:-12.0464,Lng:-77.0428,AvgBedtime:\"11:50 pm\",AvgWake:\"7:20 am\",Status:localStatus(-5)},\n    {City:\"Santiago\",Lat:-33.4489,Lng:-70.6693,AvgBedtime:\"12:00 am\",AvgWake:\"7:30 am\",Status:localStatus(-4)}\n    ];\n  }\n  const res = await fetch(DATA_SHEET_URL);\n  const csv = await res.text();\n  return csvToRows(csv);\n}\n\n\/\/ crude local-time status helper: shift hour by offset, classify\nfunction localStatus(utcOffsetHours){\n  const now = new Date();\n  const utc = now.getUTCHours() + now.getUTCMinutes()\/60;\n  const local = (utc + utcOffsetHours + 24) % 24;\n  if(local >= 23 || local < 6) return 'asleep';\n  if(local >= 6 && local < 8) return 'waking';\n  return 'active';\n}\n\n\/* ------------------------------\n   RENDER UI\n--------------------------------*\/\nfunction fillTable(rows){\n  const tbody = document.querySelector('#cityTable tbody');\n  tbody.innerHTML = '';\n  rows.forEach(r=>{\n    const tr = document.createElement('tr');\n    const statusEmoji = r.Status==='asleep'?'\ud83d\ude34':r.Status==='waking'?'\ud83c\udf05':'\ud83d\udcbc';\n    tr.innerHTML = `<td>${r.City}<\/td><td>${r.AvgBedtime}<\/td><td>${r.AvgWake}<\/td><td>${statusEmoji} ${r.Status}<\/td>`;\n    tbody.appendChild(tr);\n  });\n}\n\nfunction updateStats(rows){\n  document.getElementById('kCities').textContent = rows.length;\n  \/\/ simple averages from strings like \"11:08 pm\"\n  const toMin = s=>{\n    const [hmm, ampm] = s.split(' ');\n    let [h,m] = hmm.split(':').map(Number);\n    if(ampm.toLowerCase()==='pm' && h!==12) h+=12;\n    if(ampm.toLowerCase()==='am' && h===12) h=0;\n    return h*60+m;\n  };\n  const avg = arr => Math.round(arr.reduce((a,b)=>a+b,0)\/arr.length);\n  const fmt = mins=>{\n    const h = Math.floor(mins\/60)%24, m = mins%60;\n    const ampm = h>=12?'pm':'am'; const h12 = ((h+11)%12)+1;\n    return `${h12}:${String(m).padStart(2,'0')} ${ampm}`;\n  };\n  const beds = rows.map(r=>toMin(r.AvgBedtime));\n  const wakes = rows.map(r=>toMin(r.AvgWake));\n  document.getElementById('kBed').textContent = fmt(avg(beds));\n  document.getElementById('kWake').textContent = fmt(avg(wakes));\n}\n\n\/* ------------------------------\n   QUIZ\n--------------------------------*\/\nconst modal = document.getElementById('quizModal');\ndocument.getElementById('btnQuiz').onclick = ()=> modal.classList.add('open');\ndocument.getElementById('xQuiz').onclick = ()=> modal.classList.remove('open');\ndocument.getElementById('btnCancelQuiz').onclick = ()=> modal.classList.remove('open');\n\ndocument.getElementById('quizForm').addEventListener('submit', e=>{\n  e.preventDefault();\n  const v = name=> (new FormData(e.target)).get(name);\n  let score = 0;\n  score += (v('bed')==='mid') ? 2 : (v('bed')==='early'?3:1);\n  score += (v('latency')==='ok') ? 3 : (v('latency')==='warn'?2:1);\n  score += (v('wake')==='rare') ? 3 : (v('wake')==='some'?2:1);\n  score += (v('ref')==='good') ? 3 : (v('ref')==='meh'?2:1);\n  score += (v('dur')==='ok') ? 3 : (v('dur')==='warn'?2:1);\n  const max=15;\n  const pct = Math.round(100*score\/max);\n  const title = pct>=80?'Great Sleep Hygiene':\n                pct>=60?'Decent, Needs Tweaks':'Let\u2019s Fix Your Sleep';\n  const text  = pct>=80?'You\u2019re aligned with healthy sleep ranges. Keep a steady schedule and protect that routine.':\n                pct>=60?'A few small adjustments (consistent wake time, dim evenings, earlier caffeine cutoff) could lift your energy fast.':\n                'Let\u2019s start with anchors: same wake time daily, bright morning light, & wind-down routine. Personalized plan inside Pro.';\n  document.getElementById('qrTitle').textContent = `${title} \u2014 ${pct}%`;\n  document.getElementById('qrText').textContent = text;\n  document.getElementById('quizResult').style.display='block';\n});\n\n\/* ------------------------------\n   SHARE\/COPY\n--------------------------------*\/\ndocument.getElementById('btnShare').onclick = async ()=>{\n  try{\n    await navigator.share({title:document.title, url:location.href});\n  }catch{\n    navigator.clipboard.writeText(location.href);\n    alert('Link copied!');\n  }\n};\ndocument.getElementById('btnCopy').onclick = async ()=>{\n  await navigator.clipboard.writeText(location.href);\n  alert('Link copied!');\n};\n\n\/* ------------------------------\n   BOOT\n--------------------------------*\/\nasync function boot(){\n  initMap();\n  const rows = await fetchData();\n  \/\/ refresh layers\n  heatLayer.setLatLngs(toHeatPoints(rows));\n  renderMarkers(rows);\n  fillTable(rows);\n  updateStats(rows);\n}\nboot();\ndocument.getElementById('btnRefresh').onclick = boot;\nsetInterval(boot, AUTO_REFRESH_MS);\n<\/script>\nsleep tracker, world sleep clock, global sleep patterns, city bedtime tracker, live sleep map, international sleep schedule, average bedtime by city, wake up times around the world, sleep cycle map, sleep statistics, \u201cAm I normal?\u201d sleep quiz, how the world sleeps, when do people go to bed in Tokyo?, sleep comparison by country, why do I wake up tired?, best time to sleep globally, sleep culture differences, night owls vs early birds worldwide, healthiest sleep habits, jet lag recovery hacks, personalized sleep recommendations, exportable sleep data for health tracking, sleep chart generator, sleep coaching online, track my sleep vs world average, health optimization with sleep, sleep trends by city 2025, compare your sleep with the world, sleep app alternative free, global circadian rhythm tracker, #SleepTracker, #WorldSleep, #GlobalClock, #SleepPatterns, #HowTheWorldSleeps, #CircadianRhythm, #SleepQuiz, #HealthHack, #SleepOptimization, #WellnessTech\n\n<\/body>\n<\/html>\n","protected":false},"excerpt":{"rendered":"<p>Which City Are You? Sleep Tracker World Clock Live global map of sleep &amp; wake cycles across major cities \u2014 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"blank-slate-template.php","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"","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":"","footer-sml-layout":"","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-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":"","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-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":"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":""},"mobile":{"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":""}},"_glsr_average":0,"_glsr_ranking":0,"_glsr_reviews":0,"footnotes":""},"class_list":["post-258","page","type-page","status-publish","hentry"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/bioskinetics.com.au\/index.php?rest_route=\/wp\/v2\/pages\/258","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/bioskinetics.com.au\/index.php?rest_route=\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/bioskinetics.com.au\/index.php?rest_route=\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/bioskinetics.com.au\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/bioskinetics.com.au\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=258"}],"version-history":[{"count":5,"href":"https:\/\/bioskinetics.com.au\/index.php?rest_route=\/wp\/v2\/pages\/258\/revisions"}],"predecessor-version":[{"id":270,"href":"https:\/\/bioskinetics.com.au\/index.php?rest_route=\/wp\/v2\/pages\/258\/revisions\/270"}],"wp:attachment":[{"href":"https:\/\/bioskinetics.com.au\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=258"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}