JST --:--:--
arrow_back Widgets
Days Left In Year (Dark Mode)
Days Left In Year (Dark Mode)
Medium Widget · days-left-year
Medium Widget Scriptable
Stay motivated as you keep track of the days remaining in the year. This Dark Mode widget not only shows how many days are left but also provides inspiring quotes to encourage you to make the most of each day. Each hour, a new motivational message is displayed, along with a progress bar to visualize your progress through the year.
How to install
1
Download Scriptable from the App Store. It is free.
2
Tap Copy on the right, open Scriptable, tap +, paste the code, and tap Done.
3
Long press your home screen, add a Scriptable widget at Medium size, and pick this script.
Drag me!
// 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();