// Days Left in Year Widget — Medium Size (Motivation Edition) — Dark Mode
const now = new Date();
const year = now.getFullYear();
const endOfYear = new Date(year, 11, 31);
// Calculate days
const msPerDay = 1000 * 60 * 60 * 24;
const daysLeft = Math.ceil((endOfYear - now) / msPerDay);
const dayOfYear = Math.floor((now - new Date(year, 0, 1)) / msPerDay) + 1;
const totalDays =
((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0)
? 366
: 365;
const progress = dayOfYear / totalDays;
const percentDone = Math.round(progress * 100);
// Month name
const monthNames = [
"January","February","March","April","May","June",
"July","August","September","October","November","December"
];
const monthName = monthNames[now.getMonth()];
const dateStr = `${monthName} ${now.getDate()}, ${year}`;
// Colors — Dark Mode
const bg = new Color("#141414");
const accentColor = new Color("#E8722A");
const textColor = new Color("#F0EDE8");
const subColor = new Color("#888580");
const trackColor = new Color("#2A2A2A");
// Widget
const widget = new ListWidget();
widget.backgroundColor = bg;
widget.setPadding(16, 18, 16, 18);
// Top row
const topRow = widget.addStack();
topRow.layoutHorizontally();
topRow.centerAlignContent();
const headerLabel = topRow.addText("📅 DAYS LEFT IN YEAR");
headerLabel.font = Font.boldMonospacedSystemFont(10);
headerLabel.textColor = subColor;
topRow.addSpacer();
const dateLabel = topRow.addText(dateStr);
dateLabel.font = Font.systemFont(10);
dateLabel.textColor = subColor;
widget.addSpacer(8);
// Main row
const mainRow = widget.addStack();
mainRow.layoutHorizontally();
mainRow.centerAlignContent();
// Left side
const leftStack = mainRow.addStack();
leftStack.layoutVertically();
const numText = leftStack.addText(String(daysLeft));
numText.font = Font.boldSystemFont(64);
numText.textColor = accentColor;
numText.minimumScaleFactor = 0.5;
const daysLabel = leftStack.addText("days remaining");
daysLabel.font = Font.systemFont(11);
daysLabel.textColor = subColor;
mainRow.addSpacer();
// Right side motivation
const rightStack = mainRow.addStack();
rightStack.layoutVertically();
const messages = [
{
title: "TIME IS LEAVING.",
subtitle: "YOU ARE NOT.",
bottom1: `${percentDone}% gone`,
bottom2: "won't come back"
},
{
title: "NOBODY IS COMING.",
subtitle: "START NOW.",
bottom1: `${daysLeft} days left`,
bottom2: "that's all"
},
{
title: "THE YEAR WON'T WAIT.",
subtitle: "WHY ARE YOU?",
bottom1: `Day ${dayOfYear}`,
bottom2: `of ${totalDays}`
},
{
title: "YOUR EXCUSES",
subtitle: "AGE TOO.",
bottom1: `${percentDone}% over`,
bottom2: "still waiting?"
},
{
title: "FUTURE YOU",
subtitle: "IS WATCHING.",
bottom1: `${daysLeft} days`,
bottom2: "to prove it"
},
{
title: "ANOTHER DAY",
subtitle: "IS GONE.",
bottom1: `${percentDone}% done`,
bottom2: "what changed?"
},
{
title: "COMFORT IS",
subtitle: "EXPENSIVE.",
bottom1: `${daysLeft} days`,
bottom2: "remaining"
},
{
title: "ONE DAY LESS.",
subtitle: "WHAT NOW?",
bottom1: `Day ${dayOfYear}`,
bottom2: "keep moving"
}
];
// New message every hour
const messageIndex =
Math.floor(Date.now() / (1000 * 60 * 60)) % messages.length;
const msg = messages[messageIndex];
const line1 = rightStack.addText(msg.title);
line1.font = Font.boldSystemFont(14);
line1.textColor = textColor;
line1.rightAlignText();
const line2 = rightStack.addText(msg.subtitle);
line2.font = Font.boldSystemFont(14);
line2.textColor = accentColor;
line2.rightAlignText();
rightStack.addSpacer(10);
const stat1 = rightStack.addText(msg.bottom1);
stat1.font = Font.boldSystemFont(16);
stat1.textColor = textColor;
stat1.rightAlignText();
const stat2 = rightStack.addText(msg.bottom2);
stat2.font = Font.systemFont(10);
stat2.textColor = subColor;
stat2.rightAlignText();
widget.addSpacer(10);
// Progress bar
const barBg = widget.addStack();
barBg.layoutHorizontally();
barBg.backgroundColor = trackColor;
barBg.cornerRadius = 5;
barBg.size = new Size(0, 8);
const filled = barBg.addStack();
filled.backgroundColor = accentColor;
filled.cornerRadius = 5;
const filledWidth = Math.max(
6,
Math.round(progress * 300)
);
filled.size = new Size(filledWidth, 8);
// Refresh every hour
widget.refreshAfterDate = new Date(
Date.now() + 60 * 60 * 1000
);
if (config.runsInWidget) {
Script.setWidget(widget);
} else {
widget.presentMedium();
}
Script.complete();