diff --git a/README.md b/README.md
index ae7ea53..184c00b 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,28 @@
# work-timerer
-Simple web app that shows time left to work and some more things
\ No newline at end of file
+Simple web app that shows time left to work and some more things
+
+### Installation
+
+You can run the app running just `index.html` or you using docker compose.
+
+Just copy this compose.yml file:
+```yml
+services:
+ work-timerer:
+ image: git.frik.su/Beesquit/work-timerer:latest
+ container_name: work-timerer
+ ports:
+ 4000:80
+ restart: unless stopped
+```
+
+The application should be available at the `localhost:4000`
+
+### Todo:
+-[ ] Make travel time customizable with env
+
+### Limitations:
+- The app is linked to the system time
+- If you live in a different timezone than your office the app will not work correctly
+
diff --git a/compose.yml b/compose.yml
new file mode 100644
index 0000000..e69de29
diff --git a/src/index.css b/src/index.css
new file mode 100644
index 0000000..8be49b9
--- /dev/null
+++ b/src/index.css
@@ -0,0 +1,98 @@
+body {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 0;
+ overflow: hidden;
+ background-color: #1f1f1f;
+ color: #ffffff;
+}
+
+H1 {
+ text-align: center
+}
+
+
+.jetbrains-mono {
+ font-family: 'JetBrains Mono Nerd Font', monospace;
+ font-optical-sizing: auto;
+ font-weight: 300;
+}
+
+
+.parent {
+ width: 100%;
+ height: 100%;
+ position: absolute;
+ top: 0;
+ left: 0;
+ overflow: auto;
+ justify-content: space-between;
+ flex-direction: column;
+}
+
+.vblock {
+ display: flex;
+ margin: auto;
+ justify-content: space-between;
+ flex-direction: row;
+ padding: 10px;
+}
+
+.hblock {
+ margin: auto;
+}
+
+.time-blocks {
+ display: flex;
+ gap: 20px;
+ flex-wrap: wrap;
+ justify-content: center;
+ align-items: flex-start;
+}
+
+.time-block {
+ padding: 10px 15px;
+ background-color: #2a2a2a;
+ border-radius: 5px;
+ min-width: 60px;
+ text-align: center;
+ flex-shrink: 0;
+}
+
+.label-block {
+ background-color: #2a2a2a;
+ min-width: 16px;
+ flex-shrink: 0;
+ font-weight: 450;
+}
+
+.multi-rows-container {
+ display: flex;
+ flex-direction: column;
+ gap: 10px;
+ align-items: center;
+}
+
+.time-row {
+ display: flex;
+ gap: 20px;
+ justify-content: center;
+}
+
+#currentTime {
+ font-size: 3em;
+ margin: 20px 0;
+}
+
+
+@media (max-width: 768px) {
+ .time-blocks {
+ gap: 10px;
+ }
+
+ .time-block {
+ padding: 8px 12px;
+ min-width: 50px;
+ }
+}
diff --git a/src/index.html b/src/index.html
new file mode 100644
index 0000000..771158c
--- /dev/null
+++ b/src/index.html
@@ -0,0 +1,43 @@
+
+
+
+
+
+
+
+
+
+ w-timerer
+
+
+
+
+
+
+
+
+
diff --git a/src/index.js b/src/index.js
new file mode 100644
index 0000000..2d80301
--- /dev/null
+++ b/src/index.js
@@ -0,0 +1,118 @@
+function updateTimes() {
+ const travelTime = 1; // in hours
+
+ const now = new Date();
+ const currentHours = now.getHours();
+ const currentMinutes = now.getMinutes();
+ const currentSeconds = now.getSeconds();
+
+ const currentTimeElement = document.getElementById('currentTime');
+ currentTimeElement.textContent = `${currentHours.toString().padStart(2, '0')}:${currentMinutes.toString().padStart(2, '0')}:${currentSeconds.toString().padStart(2, '0')}`;
+
+ const targetTimesElement = document.getElementById('targetTimes');
+ const leaveTimesElement = document.getElementById('leaveTimes');
+ const timeDifferencesElement = document.getElementById('timeDifferences');
+
+ targetTimesElement.innerHTML = '';
+ leaveTimesElement.innerHTML = '';
+ timeDifferencesElement.innerHTML = '';
+
+ const ttBlock = document.createElement('span');
+ ttBlock.className = 'time-block label-block';
+ ttBlock.textContent = 'TT';
+ targetTimesElement.appendChild(ttBlock);
+
+ const ltBlock = document.createElement('span');
+ ltBlock.className = 'time-block label-block';
+ ltBlock.textContent = 'LT';
+ leaveTimesElement.appendChild(ltBlock);
+
+ const tdBlock = document.createElement('span');
+ tdBlock.className = 'time-block label-block';
+ tdBlock.textContent = 'TD';
+ timeDifferencesElement.appendChild(tdBlock);
+
+ const targetTimeBlocks = [];
+ const leaveTimeBlocks = [];
+ const diffTimeBlocks = [];
+
+ for (let hour = 13; hour <= 22; hour++) {
+ let leaveHour = hour - travelTime;
+
+ const timeBlock = document.createElement('span');
+ timeBlock.className = 'time-block';
+ timeBlock.textContent = `${hour.toString().padStart(2, '0')}:00`;
+ targetTimeBlocks.push(timeBlock);
+
+ const leaveTimeBlock = document.createElement('span');
+ leaveTimeBlock.className = 'time-block';
+ leaveTimeBlock.textContent = `${(leaveHour).toString().padStart(2, '0')}:00`;
+ leaveTimeBlocks.push(leaveTimeBlock);
+
+ const targetTime = new Date();
+ targetTime.setHours(leaveHour, 0, 0, 0);
+
+ const diffBlock = document.createElement('span');
+ diffBlock.className = 'time-block';
+
+ const diffMs = targetTime - now;
+ if (diffMs < 0) {
+ const diffHours = -1 * Math.ceil(diffMs / (1000 * 60 * 60));
+ const diffMinutes = -1 * Math.ceil((diffMs % (1000 * 60 * 60)) / (1000 * 60));
+ diffBlock.textContent = `-${diffHours.toString().padStart(2, '0')}:${diffMinutes.toString().padStart(2, '0')}`;
+ } else {
+ const diffHours = Math.floor(diffMs / (1000 * 60 * 60));
+ const diffMinutes = Math.ceil((diffMs % (1000 * 60 * 60)) / (1000 * 60));
+ diffBlock.textContent = `${diffHours.toString().padStart(2, '0')}:${diffMinutes.toString().padStart(2, '0')}`;
+ }
+
+ diffTimeBlocks.push(diffBlock);
+ }
+
+ distributeBlocks(targetTimesElement, targetTimeBlocks);
+ distributeBlocks(leaveTimesElement, leaveTimeBlocks);
+ distributeBlocks(timeDifferencesElement, diffTimeBlocks);
+}
+
+
+function distributeBlocks(container, blocks) {
+ const screenWidth = window.innerWidth;
+ const blockWidth = 120;
+ const labelWidth = 40;
+
+ const availableWidth = screenWidth - labelWidth;
+ const blocksPerRow = Math.floor(availableWidth / blockWidth);
+
+ if (blocksPerRow > blocks.length) {
+ blocks.forEach(block => container.appendChild(block));
+ return;
+ }
+
+ const totalBlocks = blocks.length;
+ const halfBlocks = Math.ceil(totalBlocks / 2);
+
+ const rowsContainer = document.createElement('div');
+ rowsContainer.className = 'multi-rows-container';
+
+ const topRow = document.createElement('div');
+ topRow.className = 'time-row';
+ for (let i = 0; i < halfBlocks; i++) {
+ topRow.appendChild(blocks[i]);
+ }
+ rowsContainer.appendChild(topRow);
+
+ const bottomRow = document.createElement('div');
+ bottomRow.className = 'time-row';
+ for (let i = halfBlocks; i < totalBlocks; i++) {
+ bottomRow.appendChild(blocks[i]);
+ }
+ rowsContainer.appendChild(bottomRow);
+
+ const label = container.firstChild;
+ container.appendChild(rowsContainer);
+}
+
+
+updateTimes();
+setInterval(updateTimes, 200);
+window.addEventListener('resize', updateTimes);