{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"flip-clock","type":"registry:component","title":"Flip Clock","description":"Split-flap clock with timezone selection, in Notion's typography.","author":"Notion Arena","categories":["dashboards"],"tags":["widget","free","clock","time","timezone","dashboard"],"meta":{"kind":"widget","tier":"free","version":"1.3.0","updatedAt":"2026-10-02","notionPlan":"Free","emoji":"🕰️","delivery":["embed","html-block","download"],"capabilities":{"interactive":true,"offlineSafe":true,"persistsLocally":true,"writesToNotion":false,"needsNetwork":false},"embedUrl":"https://notionarena.vercel.app/embed/flip-clock","fileUrl":"https://notionarena.vercel.app/widgets/flip-clock.html","downloadUrl":"https://notionarena.vercel.app/api/widget/flip-clock","height":190,"minHeight":150,"maxHeight":320,"params":[{"key":"tz","label":"Timezone","type":"text","default":"","help":"IANA name, e.g. Asia/Karachi. Blank = viewer's local time."},{"key":"h24","label":"24-hour","type":"boolean","default":false},{"key":"date","label":"Show date","type":"boolean","default":true},{"key":"accent","label":"Accent","type":"color","default":"#2383e2"},{"key":"theme","label":"Theme","type":"select","default":"auto","options":[{"value":"auto","label":"Match Notion"},{"value":"light","label":"Light"},{"value":"dark","label":"Dark"}]}]},"files":[{"path":"widgets/flip-clock.html","type":"registry:file","target":"notion/widgets/flip-clock.html","content":"<!doctype html>\n<html lang=\"en\" data-theme=\"auto\">\n<head>\n<meta charset=\"utf-8\" />\n<meta name=\"viewport\" content=\"width=device-width,initial-scale=1\" />\n<title>Flip Clock</title>\n<style>\n:root{--bg:#ffffff;--fg:#37352f;--muted:#787774;--surface:#f7f7f5;--border:#e9e9e7;--accent:#2383e2;--card:#fbfbfa;\n--font:ui-sans-serif,-apple-system,BlinkMacSystemFont,\"Segoe UI\",Helvetica,Arial,sans-serif}\nhtml[data-theme=\"dark\"]{--bg:#191919;--fg:#e6e6e4;--muted:#9b9a97;--surface:#252525;--border:#2f2f2f;--card:#202020}\n@media (prefers-color-scheme:dark){html[data-theme=\"auto\"]{--bg:#191919;--fg:#e6e6e4;--muted:#9b9a97;--surface:#252525;--border:#2f2f2f;--card:#202020}}\n*{box-sizing:border-box}html,body{margin:0;height:100%}\nbody{background:var(--bg);color:var(--fg);font-family:var(--font);-webkit-font-smoothing:antialiased;overflow:hidden}\n.wrap{height:100%;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:10px;padding:16px}\n.clock{display:flex;align-items:center;gap:6px}\n.card{position:relative;min-width:56px;height:74px;border-radius:9px;background:var(--card);border:1px solid var(--border);\nbox-shadow:0 1px 2px rgba(15,15,15,.05);display:flex;align-items:center;justify-content:center;overflow:hidden}\n.card::after{content:\"\";position:absolute;left:0;right:0;top:50%;height:1px;background:color-mix(in oklab,var(--fg) 10%,transparent)}\n.card b{font-size:38px;font-weight:600;letter-spacing:-.04em;font-variant-numeric:tabular-nums;line-height:1}\n.card.flip b{animation:flip .28s ease-out}\n@keyframes flip{0%{transform:rotateX(0);opacity:1}45%{transform:rotateX(-72deg);opacity:.35}100%{transform:rotateX(0);opacity:1}}\n.colon{font-size:30px;font-weight:600;color:var(--muted);opacity:.7;transform:translateY(-2px)}\n.meta{display:flex;align-items:center;gap:10px;font-size:12px;color:var(--muted)}\n.date{font-weight:500}\n.tz{padding:2px 8px;border:1px solid var(--border);border-radius:99px;background:var(--surface);font-size:11px;font-weight:600;letter-spacing:.02em}\n.suffix{font-size:14px;font-weight:600;color:var(--accent);align-self:flex-start;margin-top:14px}\n.ampm{display:flex}\n@media (max-width:400px){.card{min-width:44px;height:60px}.card b{font-size:29px}.colon{font-size:23px}}\n@media (prefers-reduced-motion:reduce){.card.flip b{animation:none}}\n</style>\n</head>\n<body>\n<div class=\"wrap\">\n  <div class=\"clock\" id=\"clock\">\n    <div class=\"card\" id=\"h1\"><b>0</b></div>\n    <div class=\"card\" id=\"h2\"><b>0</b></div>\n    <div class=\"colon\" id=\"c1\">:</div>\n    <div class=\"card\" id=\"m1\"><b>0</b></div>\n    <div class=\"card\" id=\"m2\"><b>0</b></div>\n    <div class=\"colon\" id=\"c2\" style=\"display:none\">:</div>\n    <div class=\"card\" id=\"s1\" style=\"display:none\"><b>0</b></div>\n    <div class=\"card\" id=\"s2\" style=\"display:none\"><b>0</b></div>\n    <div class=\"suffix\" id=\"suffix\" style=\"display:none\">AM</div>\n  </div>\n  <div class=\"meta\">\n    <span class=\"date\" id=\"date\"></span>\n    <span class=\"tz\" id=\"tz\" style=\"display:none\"></span>\n  </div>\n</div>\n<script>\n(function(){\n  var cfgEl=document.getElementById('bk-config'),base={};\n  try{base=cfgEl?JSON.parse(cfgEl.textContent||'{}'):{};}catch(e){}\n  var q=new URLSearchParams(location.search),c={};for(var k in base)c[k]=base[k];\n  q.forEach(function(v,k){c[k]=v;});\n  function bool(k,d){var v=c[k];return v===undefined?d:(v===true||v==='true'||v==='1');}\n\n  var ACCENT=c.accent||'#2383e2';\n  if(c.theme)document.documentElement.setAttribute('data-theme',c.theme);\n  document.documentElement.style.setProperty('--accent',ACCENT);\n\n  var H24=bool('h24',false), SHOWDATE=bool('date',true), SHOWSEC=bool('seconds',false);\n  var TZ=(c.tz||'').trim();\n  var fmtOpts={hour:'2-digit',minute:'2-digit',hour12:!H24};\n  if(SHOWSEC)fmtOpts.second='2-digit';\n  var dateOpts={weekday:'long',month:'long',day:'numeric',year:'numeric'};\n  var locale=navigator.language||'en-US';\n  if(TZ){fmtOpts.timeZone=TZ;dateOpts.timeZone=TZ;\n    var tzEl=document.getElementById('tz');tzEl.style.display='';tzEl.textContent=TZ.split('/').pop().replace(/_/g,' ');}\n  if(!SHOWDATE)document.querySelector('.meta').style.display='none';\n  if(SHOWSEC){['c2','s1','s2'].forEach(function(i){document.getElementById(i).style.display='';});}\n\n  var ids=['h1','h2','m1','m2','s1','s2'];\n  var els={};ids.forEach(function(i){els[i]=document.getElementById(i);});\n  var suffix=document.getElementById('suffix');\n  if(!H24)suffix.style.display='';\n  var last='';\n\n  function setCard(id,ch){\n    var el=els[id],b=el.firstElementChild;\n    if(b.textContent!==ch){b.textContent=ch;el.classList.remove('flip');void el.offsetWidth;el.classList.add('flip');}\n  }\n  function paint(){\n    var now=new Date();\n    var parts;\n    try{parts=new Intl.DateTimeFormat(locale,fmtOpts).formatToParts(now);}\n    catch(e){parts=new Intl.DateTimeFormat('en-US',fmtOpts).formatToParts(now);}\n    var get=function(t){for(var i=0;i<parts.length;i++)if(parts[i].type===t)return parts[i].value;return '';};\n    var h=get('hour'),m=get('minute'),s=get('second')||'00',dp=get('dayPeriod');\n    if(h.length<2)h='0'+h;\n    if(!H24&&dp)suffix.textContent=dp.toUpperCase();\n    var sig=h+m+(SHOWSEC?s:'');\n    if(sig===last)return;\n    var changed=last!=='';\n    last=sig;\n    setCard('h1',h[0]);setCard('h2',h[1]);setCard('m1',m[0]);setCard('m2',m[1]);\n    if(SHOWSEC){setCard('s1',s[0]);setCard('s2',s[1]);}\n    if(changed){\n      try{document.getElementById('date').textContent=new Intl.DateTimeFormat(locale,dateOpts).format(now);}catch(e){}\n    }\n  }\n  try{document.getElementById('date').textContent=new Intl.DateTimeFormat(locale,dateOpts).format(new Date());}catch(e){}\n  paint();setInterval(paint,250);\n})();\n</script>\n</body>\n</html>\n"}]}