Theme guide
A theme is a folder with a theme.json file and, optionally, images and fonts. It controls everything a clock draws: the card behind it, the digital and analog faces, the hands, ticks and numbers, and the region-name and UTC-offset labels.
Quick start
- Open Settings → Themes → New theme from template. This creates
Documents\Zoneline\Themes\my-theme\and selects itstheme.jsonin Explorer. - Open
theme.jsonin any text editor (Notepad, VS Code). - Right-click a clock → Theme → My Theme (Custom).
- Edit and save. The clock redraws as soon as the file is saved. Errors appear under the theme's card in Settings → Themes.
The template lists every setting with its default value and a comment. Delete what you don't need: anything missing keeps its default. The smallest useful theme is a few lines:
{
"name": "Orange",
"digital": { "font": { "color": "#FF8800" } },
"labels": { "name": { "color": "#FF8800" } }
}
File rules
- File name
theme.json, UTF-8. Comments (//,/* */) and trailing commas are allowed. Key names are case-insensitive. - The folder name is the theme's id. Rename the folder and clocks using it fall back to the default theme.
- Folders whose names start with
_or.are ignored (handy for drafts). - Images and fonts are looked up relative to the theme folder. Paths that leave the folder (
../) are ignored. - Unknown keys are ignored, so a theme written for a newer version still loads.
Values
| Kind | How to write it |
|---|---|
| Colour | "#RRGGBB", "#AARRGGBB" (AA is opacity: 00 transparent to FF solid), a colour name ("white"), "transparent", or null to draw nothing |
| Gradient | { "type": "linear", "angle": 90, "stops": [ { "color": "#FF0000", "offset": 0 }, { "color": "#0000FF", "offset": 1 } ] }. Angle 0 runs left to right, 90 top to bottom. "type": "radial" spreads from the centre |
| Font | { "family": "Segoe UI", "size": 14, "weight": "SemiBold", "style": "Normal", "color": "#FFFFFF" }. List fallbacks with commas: "Cascadia Mono, Consolas" |
| Weight | Thin, ExtraLight, Light, Normal, Medium, SemiBold, Bold, ExtraBold, Black, or a number 1–999 |
| Size | Pixels at 100% clock size. The clock's Size option scales everything together |
| Fraction | Analog lengths and radii are fractions of the dial radius: 0.5 reaches halfway to the rim |
Bundling a font
Put the .ttf or .otf next to theme.json, set file to its name and family to the font's family name (the name Windows shows when you open the font file), not the file name. Check the font's licence before sharing a theme that bundles it.
"font": { "file": "Orbitron-Bold.ttf", "family": "Orbitron", "size": 36 }
gadget: the card
| Key | Default | Notes |
|---|---|---|
background | "#D9161A20" | Colour or gradient. null for no card |
backgroundImage | null | Image file, drawn over the background colour and clipped to the rounded card |
backgroundImageStretch | "uniformToFill" | fill, uniform, uniformToFill, none |
cornerRadius | 14 | |
border, borderThickness | "#26FFFFFF", 1 | null for no border |
padding | 14 | Space between the card edge and its content |
spacing | 8 | Gap between the clock and its labels |
shadow | on, black, 0.45, blur 14, depth 3 | { "show", "color", "opacity", "blur", "depth" }. Also works without a card: it then shadows the text and hands |
digital
| Key | Default | Notes |
|---|---|---|
font | Segoe UI Variable Display, 40, SemiBold, white | Hours and minutes |
use24Hour, showSeconds | true, true | Defaults only; each clock can override them from its menu |
secondsScale | 0.55 | Seconds size relative to the hours. 1 draws 12:34:56 all at one size |
secondsColor | null | null = same as the font colour |
showAmPm, amPmScale | true, 0.4 | 12-hour mode only. Uses the UI language's AM/PM words |
blinkColon | false | Hides the separator on odd seconds |
separator | ":" | |
showDate, datePosition | true, "below" | above or below the time |
dateFormat | "auto" | auto picks a format for the UI language. Otherwise a .NET date format such as "yyyy-MM-dd" or "ddd d MMM" |
dateFont, dateSpacing, uppercaseDate | 13 px, 6, false |
Digits are laid out on a fixed grid, so the card does not change width as the seconds tick.
analog
| Key | Default | Notes |
|---|---|---|
diameter | 140 | |
face, faceImage | dark grey, null | The image is clipped to the circle; square images work best |
faceBorder, faceBorderThickness | "#FF3A424D", 2 | |
majorTicks | 12 hour marks | { "show", "color", "width", "length", "shape": "line" | "dot", "inset" } |
minorTicks | 48 minute marks | Same keys |
numbers | hidden | { "show", "style": "arabic" | "roman", "quartersOnly", "radius", "font" } |
hourHand, minuteHand, secondHand | { "show", "color", "width", "length", "tail", "cap": "round" | "flat" | "square" } | |
smoothSeconds | false | Sweeping second hand (redraws 20 times a second) |
center | white, radius 4 | The cap over the hands |
showDate, dateFormat, dateFont | false, "d" | Small date inside the dial, below the centre |
Image hands
A hand can be a picture instead of a line. Draw it pointing straight up (12 o'clock) on a transparent background, then:
"minuteHand": { "image": "minute.png", "length": 0.8, "tail": 0.15, "pivotX": 0.5, "pivotY": 0.84 }
The picture is scaled so its height equals length + tail times the dial radius. pivotX and pivotY mark the point it rotates around, as fractions of the image's width and height (here: centred horizontally, 84% of the way down).
labels
| Key | Default | Notes |
|---|---|---|
name | 14 px SemiBold, 90% white | The region name. Each clock sets the text and whether it sits on top, bottom, left, right or nowhere |
offset | 12 px, 60% white | The UTC offset |
uppercaseName | false | |
offsetFormat | "UTC{sign}{h}{:mm}" | {sign}, {h} hours, {hh} two-digit hours, {mm} minutes, {:mm} ":30" only when minutes are not zero. Gives UTC+9, UTC−3:30, UTC+5:45 |
minusSign | "−" | U+2212. Use "-" for a plain hyphen |
Daylight saving time is applied: New York shows UTC−5 in winter and UTC−4 in summer.
timeline: the timeline gadget
A vertical axis of this PC's local time: the recent past above the now line, the future below it. Each timeline gadget chooses its own range (how many hours back and ahead) and length; the theme decides how it looks. The card (gadget) and shadow are shared with the clocks.
| Key | Default | Notes |
|---|---|---|
width | 300 | Content width at 100% size |
showHeader, headerFont, headerTimeFont, headerSpacing | true, 14 px, 14 px, 10 | "Timeline" and the current time at the top |
axisX | 52 | Distance from the left edge to the axis. Tick labels sit to its left |
axisColor, axisWidth | "#40FFFFFF", 2 | |
pastBackground | "#0FFFFFFF" | Shade over the part that is already past. null for none |
showTicks, tickColor, tickFont, tickMinGap | true, "#33FFFFFF", 11 px, 34 | Local-time ticks. The step (15 min to 1 week) is the smallest that keeps tickMinGap pixels between labels. Midnight shows the date |
nowColor, nowWidth, nowFont | red, 2, 11 px SemiBold | The now line and its label. null colour hides it |
eventColor, pastEventColor | "#FF4EA8FF", "#59FFFFFF" | Default reminder colour (each reminder can pick its own) and the colour of reminders that are over |
dotRadius, rangeWidth | 5, 6 | The dot at a reminder's start, and the bar along the axis for reminders with an end time |
leaderColor | "#33FFFFFF" | Line from the axis to a label that had to move to avoid another |
titleFont, countdownFont, detailFont | 13 px SemiBold, 11 px SemiBold blue, 11 px | The three lines of a label: title, countdown ("in 1 h 21 min"), and the local time with the reminder's own zone time |
labelSpacing | 6 | Gap between the axis and the labels, and between stacked labels |
Labels never overlap: when reminders are close together, the labels stack and a leader line points back to the moment. Labels that do not fit are counted at the bottom ("+3").
market: the market gadget
One row per market: name and state chip (LIVE, pre-market, lunch, closed, holiday), the countdown to the open or close, the regular hours on this PC's clock, and a bar of today (00–24 on this PC) with every session coloured in. Each market gadget chooses which markets it lists.
| Key | Default | Notes |
|---|---|---|
width | 340 | Content width at 100% size |
showHeader, headerFont, headerTimeFont, headerSpacing | true, 14 px, 14 px, 10 | "Markets" and the current time at the top |
nameFont, statusFont, countdownFont, detailFont | 14 px SemiBold, 11 px Bold, 12 px SemiBold, 11 px | Market name, chip text, countdown, regular hours and extended-session notes |
liveColor | "#FF2FD27A" | LIVE chip, regular sessions on the bar, the countdown while live |
extendedColor | "#FFFFC24B" | Pre-market, after-hours, overnight, auctions |
breakColor, closedColor, holidayColor | blue, grey, orange | Lunch, closed and holiday chips |
futuresColor | "#FFB48CFF" | Futures night sessions (when turned on for a market) |
noticeColor | "#FFFFC24B" | Daylight-saving change notices and holiday-data notes |
barBackground, barHeight, barNowColor, barLabelFont | "#1FFFFFFF", 6, white, 10 px | The 24-hour bar, the now marker and the 00/06/12/18/24 labels |
rowSpacing, separator | 12, "#14FFFFFF" | Space and line between markets (null for no line) |
Sharing a theme
Zip the theme folder. The person you send it to unzips it into Documents\Zoneline\Themes\ (Settings → Themes → Open themes folder). Only include images and fonts you are allowed to share.
Troubleshooting
- The clock uses the default look. The theme failed to load. The error, with line and column, is shown under the theme in Settings → Themes.
- A colour or image does not show. Settings → Themes lists warnings for colours that cannot be read and files that are missing.
- My font is ignored.
familymust be the font's family name, not the file name. Windows falls back to the next family in the list. - Changes don't appear. Make sure you saved the file. If your editor saves somewhere unusual, press Reload in Settings → Themes.
테마 제작 가이드
테마는 theme.json 파일 하나와, 필요하면 이미지와 글꼴을 담은 폴더입니다. 시계가 그리는 모든 것을 테마가 정합니다. 뒤의 카드, 디지털·아날로그 문자판, 바늘과 눈금과 숫자, 지역명과 UTC 표기 라벨까지요.
빠르게 시작하기
- 설정 → 테마 → 템플릿으로 새 테마를 누릅니다.
문서\Zoneline\Themes\my-theme\폴더가 생기고 탐색기에서theme.json이 선택됩니다. theme.json을 아무 텍스트 편집기(메모장, VS Code)로 엽니다.- 시계를 오른쪽 클릭 → 테마 → My Theme (사용자)를 고릅니다.
- 고치고 저장합니다. 저장하는 즉시 시계가 다시 그려집니다. 오류는 설정 → 테마의 해당 테마 아래에 나옵니다.
템플릿에는 모든 설정이 기본값, 설명과 함께 들어 있습니다. 필요 없는 줄은 지워도 됩니다. 빠진 설정은 기본값을 씁니다. 그래서 몇 줄짜리 테마도 됩니다.
{
"name": "Orange",
"digital": { "font": { "color": "#FF8800" } },
"labels": { "name": { "color": "#FF8800" } }
}
파일 규칙
- 파일 이름은
theme.json, UTF-8입니다. 주석(//,/* */)과 끝 쉼표를 써도 됩니다. 키 이름은 대소문자를 가리지 않습니다. - 폴더 이름이 테마 ID입니다. 폴더 이름을 바꾸면 그 테마를 쓰던 시계는 기본 테마로 돌아갑니다.
- 이름이
_나.로 시작하는 폴더는 무시합니다(초안 보관용). - 이미지와 글꼴은 테마 폴더 기준 상대 경로로 찾습니다. 폴더 밖을 가리키는 경로(
../)는 무시합니다. - 모르는 키는 무시하므로, 새 버전용으로 만든 테마도 불러올 수 있습니다.
값 쓰는 법
| 종류 | 쓰는 법 |
|---|---|
| 색 | "#RRGGBB", "#AARRGGBB"(AA는 불투명도, 00 투명부터 FF 불투명까지), 색 이름("white"), "transparent", 아무것도 그리지 않으려면 null |
| 그라데이션 | { "type": "linear", "angle": 90, "stops": [ { "color": "#FF0000", "offset": 0 }, { "color": "#0000FF", "offset": 1 } ] }. 각도 0은 왼쪽에서 오른쪽, 90은 위에서 아래. "type": "radial"은 가운데에서 퍼집니다 |
| 글꼴 | { "family": "Segoe UI", "size": 14, "weight": "SemiBold", "style": "Normal", "color": "#FFFFFF" }. 대체 글꼴은 쉼표로 이어 씁니다: "Cascadia Mono, Consolas" |
| 굵기 | Thin, ExtraLight, Light, Normal, Medium, SemiBold, Bold, ExtraBold, Black, 또는 1~999 숫자 |
| 크기 | 시계 크기 100% 기준 픽셀. 시계의 크기 옵션이 전체를 함께 키우고 줄입니다 |
| 비율 | 아날로그의 길이와 반지름은 문자판 반지름에 대한 비율입니다. 0.5면 테두리까지의 절반 |
글꼴 함께 넣기
.ttf나 .otf를 theme.json 옆에 두고, file에는 파일 이름을, family에는 글꼴의 패밀리 이름(글꼴 파일을 열면 Windows가 보여 주는 이름)을 씁니다. 파일 이름이 아닙니다. 글꼴을 넣은 테마를 공유하기 전에 글꼴 라이선스를 확인하세요.
"font": { "file": "Orbitron-Bold.ttf", "family": "Orbitron", "size": 36 }
gadget: 카드
| 키 | 기본값 | 설명 |
|---|---|---|
background | "#D9161A20" | 색 또는 그라데이션. 카드를 없애려면 null |
backgroundImage | null | 이미지 파일. 배경색 위에 그리고 둥근 카드 모양으로 자릅니다 |
backgroundImageStretch | "uniformToFill" | fill, uniform, uniformToFill, none |
cornerRadius | 14 | |
border, borderThickness | "#26FFFFFF", 1 | 테두리를 없애려면 null |
padding | 14 | 카드 가장자리와 내용 사이 여백 |
spacing | 8 | 시계와 라벨 사이 간격 |
shadow | 켬, 검정, 0.45, 흐림 14, 거리 3 | { "show", "color", "opacity", "blur", "depth" }. 카드가 없어도 동작하며, 이때는 글자와 바늘에 그림자가 생깁니다 |
digital
| 키 | 기본값 | 설명 |
|---|---|---|
font | Segoe UI Variable Display, 40, SemiBold, 흰색 | 시와 분 |
use24Hour, showSeconds | true, true | 기본값일 뿐이며 시계마다 메뉴에서 바꿀 수 있습니다 |
secondsScale | 0.55 | 시 대비 초의 크기. 1이면 12:34:56을 같은 크기로 |
secondsColor | null | null이면 글꼴 색과 같음 |
showAmPm, amPmScale | true, 0.4 | 12시간제에서만. UI 언어의 오전/오후 표기를 씁니다 |
blinkColon | false | 홀수 초마다 구분자를 숨김 |
separator | ":" | |
showDate, datePosition | true, "below" | 시간 위(above) 또는 아래(below) |
dateFormat | "auto" | auto는 UI 언어에 맞는 형식을 고릅니다. 아니면 "yyyy-MM-dd", "M월 d일 (ddd)" 같은 .NET 날짜 형식 |
dateFont, dateSpacing, uppercaseDate | 13 px, 6, false |
숫자는 고정 폭으로 배치하므로 초가 바뀌어도 카드 폭이 흔들리지 않습니다.
analog
| 키 | 기본값 | 설명 |
|---|---|---|
diameter | 140 | |
face, faceImage | 짙은 회색, null | 이미지는 원 모양으로 자릅니다. 정사각형 이미지가 잘 맞습니다 |
faceBorder, faceBorderThickness | "#FF3A424D", 2 | |
majorTicks | 시 눈금 12개 | { "show", "color", "width", "length", "shape": "line" | "dot", "inset" } |
minorTicks | 분 눈금 48개 | 키는 같습니다 |
numbers | 숨김 | { "show", "style": "arabic" | "roman", "quartersOnly", "radius", "font" } |
hourHand, minuteHand, secondHand | { "show", "color", "width", "length", "tail", "cap": "round" | "flat" | "square" } | |
smoothSeconds | false | 초침이 미끄러지듯 움직임(초당 20번 다시 그림) |
center | 흰색, 반지름 4 | 바늘 위 가운데 점 |
showDate, dateFormat, dateFont | false, "d" | 문자판 안, 가운데 아래의 작은 날짜 |
이미지 바늘
바늘을 선 대신 그림으로 그릴 수 있습니다. 투명 배경에 12시 방향(위쪽)을 가리키도록 그린 뒤 이렇게 씁니다.
"minuteHand": { "image": "minute.png", "length": 0.8, "tail": 0.15, "pivotX": 0.5, "pivotY": 0.84 }
그림의 높이가 문자판 반지름 × (length + tail)이 되도록 늘리고 줄입니다. pivotX, pivotY는 회전 중심을 그림의 너비와 높이에 대한 비율로 나타냅니다(위 예는 가로 가운데, 위에서 84% 지점).
labels
| 키 | 기본값 | 설명 |
|---|---|---|
name | 14 px SemiBold, 흰색 90% | 지역명. 글자와 위치(위, 아래, 왼쪽, 오른쪽, 숨김)는 시계마다 정합니다 |
offset | 12 px, 흰색 60% | UTC 표기 |
uppercaseName | false | |
offsetFormat | "UTC{sign}{h}{:mm}" | {sign} 부호, {h} 시, {hh} 두 자리 시, {mm} 분, {:mm}은 분이 0이 아닐 때만 ":30". 결과는 UTC+9, UTC−3:30, UTC+5:45 |
minusSign | "−" | U+2212. 일반 하이픈을 쓰려면 "-" |
서머타임을 반영합니다. 뉴욕은 겨울에 UTC−5, 여름에 UTC−4로 나옵니다.
timeline: 타임라인 가젯
이 PC 시각의 세로 축입니다. 지금 선 위는 조금 전, 아래는 앞으로의 시간입니다. 범위(몇 시간 전부터 몇 시간 뒤까지)와 길이는 타임라인 가젯마다 정하고, 모양은 테마가 정합니다. 카드(gadget)와 그림자는 시계와 같이 씁니다.
| 키 | 기본값 | 설명 |
|---|---|---|
width | 300 | 크기 100% 기준 내용 너비 |
showHeader, headerFont, headerTimeFont, headerSpacing | true, 14 px, 14 px, 10 | 맨 위의 "타임라인"과 현재 시각 |
axisX | 52 | 왼쪽 끝에서 축까지 거리. 눈금 글자는 축 왼쪽에 놓입니다 |
axisColor, axisWidth | "#40FFFFFF", 2 | |
pastBackground | "#0FFFFFFF" | 이미 지난 부분의 음영. 없애려면 null |
showTicks, tickColor, tickFont, tickMinGap | true, "#33FFFFFF", 11 px, 34 | PC 시각 눈금. 간격(15분 ~ 1주)은 글자 사이가 tickMinGap 픽셀 이상 되는 가장 작은 값으로 정합니다. 자정에는 날짜를 씁니다 |
nowColor, nowWidth, nowFont | 빨강, 2, 11 px SemiBold | 지금 선과 그 글자. 색을 null로 하면 숨깁니다 |
eventColor, pastEventColor | "#FF4EA8FF", "#59FFFFFF" | 알림 기본 색(알림마다 따로 고를 수 있음)과 끝난 알림의 색 |
dotRadius, rangeWidth | 5, 6 | 시작 시점의 점, 종료 시각이 있는 알림을 축 위에 그리는 막대 굵기 |
leaderColor | "#33FFFFFF" | 겹치지 않으려고 자리를 옮긴 글자에서 축으로 이어지는 선 |
titleFont, countdownFont, detailFont | 13 px SemiBold, 11 px SemiBold 파랑, 11 px | 글자 세 줄: 제목, 남은 시간("1시간 21분 후"), PC 시각과 알림 시간대의 시각 |
labelSpacing | 6 | 축과 글자 사이, 쌓인 글자끼리의 간격 |
글자는 겹치지 않습니다. 알림이 몰려 있으면 글자를 차례로 쌓고 가는 선으로 원래 시점을 가리킵니다. 들어가지 못한 알림은 맨 아래에 개수로 표시합니다("+3").
market: 시장 가젯
시장마다 한 줄: 이름과 상태 칩(LIVE, 프리장, 점심 휴장, 장 마감, 휴장일), 개장이나 마감까지 남은 시간, 이 PC 시각의 정규장 시간, 그리고 오늘(이 PC 기준 00~24시)의 세션을 색으로 칠한 막대. 어떤 시장을 보여 줄지는 시장 가젯마다 정합니다.
| 키 | 기본값 | 설명 |
|---|---|---|
width | 340 | 크기 100% 기준 내용 너비 |
showHeader, headerFont, headerTimeFont, headerSpacing | true, 14 px, 14 px, 10 | 맨 위의 "시장"과 현재 시각 |
nameFont, statusFont, countdownFont, detailFont | 14 px SemiBold, 11 px Bold, 12 px SemiBold, 11 px | 시장 이름, 칩 글자, 남은 시간, 정규장 시간과 확장 세션 설명 |
liveColor | "#FF2FD27A" | LIVE 칩, 막대의 정규장, 장 중일 때 남은 시간 글자 |
extendedColor | "#FFFFC24B" | 프리장, 애프터장, 오버나이트, 동시호가 |
breakColor, closedColor, holidayColor | 파랑, 회색, 주황 | 점심 휴장, 마감, 휴장일 칩 |
futuresColor | "#FFB48CFF" | 선물 야간 세션(시장별로 켰을 때만) |
noticeColor | "#FFFFC24B" | 서머타임 변경 예고, 휴장일 데이터 범위 안내 |
barBackground, barHeight, barNowColor, barLabelFont | "#1FFFFFFF", 6, 흰색, 10 px | 24시간 막대, 현재 위치 표시, 아래의 00/06/12/18/24 글자 |
rowSpacing, separator | 12, "#14FFFFFF" | 시장 사이 간격과 구분선(null이면 없음) |
테마 공유하기
테마 폴더를 zip으로 묶어 보내면, 받는 사람이 문서\Zoneline\Themes\(설정 → 테마 → 테마 폴더 열기)에 풀면 됩니다. 공유해도 되는 이미지와 글꼴만 넣으세요.
문제 해결
- 시계가 기본 모양으로 나와요. 테마를 불러오지 못한 것입니다. 설정 → 테마의 해당 테마 아래에 오류와 줄·열 번호가 나옵니다.
- 색이나 이미지가 안 보여요. 읽을 수 없는 색과 없는 파일은 설정 → 테마에 경고로 나옵니다.
- 글꼴이 적용되지 않아요.
family는 파일 이름이 아니라 글꼴의 패밀리 이름이어야 합니다. 못 찾으면 목록의 다음 글꼴을 씁니다. - 바꾼 내용이 안 보여요. 파일을 저장했는지 확인하세요. 편집기가 특이한 방식으로 저장한다면 설정 → 테마에서 다시 불러오기를 누르세요.