fuzzyworld

north-star / commit

added clean mode and fixed some issues in dark mode

65034d4e98b73a6b9af90ce0b498022bc40db272 · Pavel Safronov · 2026-03-15 23:33:56 -0700 · parents dd42032c1ed2

added clean mode and fixed some issues in dark mode
 src/app.ts     |  16 +++++++
 src/index.html |   1 +
 src/style.css  | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 3 files changed, 147 insertions(+), 3 deletions(-)

diff --git a/src/app.ts b/src/app.ts
index bbafe8f..71ee111 100644
--- a/src/app.ts
+++ b/src/app.ts
@@ -22,6 +22,7 @@ const roomCurrent = document.getElementById('room-current');
 const inviteRoomQrList = document.getElementById('invite-room-qr-list');
 const calibrateHeadingLink = document.getElementById('calibrate-heading-link');
 const darkModeToggle = document.getElementById('dark-mode-toggle');
+const cleanModeToggle = document.getElementById('clean-mode-toggle');
 const createRoomLink = document.getElementById('create-room-link');
 const roomLinks = document.getElementById('room-links');
 const friendsPanel = document.getElementById('friends-panel');
@@ -67,6 +68,21 @@ let previousRemoteFriendCount = 0;
 initDarkMode(darkModeToggle);
 const { requestWakeLock } = createWakeLockManager();
 
+const setCleanMode = (enabled: boolean) => {
+    document.body.classList.toggle('clean-mode', enabled);
+    if (cleanModeToggle instanceof HTMLButtonElement) {
+        cleanModeToggle.textContent = enabled ? 'Full' : 'Clean';
+        cleanModeToggle.setAttribute('aria-pressed', String(enabled));
+        cleanModeToggle.setAttribute('aria-label', enabled ? 'Switch to full mode' : 'Switch to clean mode');
+    }
+};
+
+if (cleanModeToggle instanceof HTMLButtonElement) {
+    cleanModeToggle.addEventListener('click', () => {
+        setCleanMode(!document.body.classList.contains('clean-mode'));
+    });
+}
+
 try {
     const commitModule = await import('./commit.js');
     GIT_COMMIT = commitModule.GIT_COMMIT;
diff --git a/src/index.html b/src/index.html
index 2672e2b..e5e56d3 100644
--- a/src/index.html
+++ b/src/index.html
@@ -39,6 +39,7 @@
             <input id="self-color-input" name="selfColor" type="color" />
             <button id="dark-mode-toggle" class="dark-mode-toggle" type="button"
                 aria-label="Toggle dark mode">🌙</button>
+            <button id="clean-mode-toggle" class="clean-mode-toggle" type="button" aria-pressed="false">Clean</button>
         </div>
         <div class="controls-row controls-row-secondary">
             <button id="calibrate-heading-link" class="friends-toggle" type="button">Compass</button>
diff --git a/src/style.css b/src/style.css
index 4222790..20aa40c 100644
--- a/src/style.css
+++ b/src/style.css
@@ -280,11 +280,77 @@ body.dark .app-icon {
     cursor: pointer;
 }
 
+.clean-mode-toggle {
+    flex: 0 0 auto;
+    min-width: 72px;
+    height: 44px;
+    padding: 0 10px;
+    border: 1px solid #64748b;
+    border-radius: 10px;
+    background: rgba(248, 250, 252, 0.96);
+    color: #0f172a;
+    font-size: 13px;
+    font-weight: 800;
+    cursor: pointer;
+}
+
 body.dark .dark-mode-toggle {
     background: #0f172a;
     border-color: #475569;
 }
 
+body.dark .clean-mode-toggle {
+    background: #0f172a;
+    border-color: #475569;
+    color: #f1f5f9;
+}
+
+body.clean-mode {
+    gap: 0;
+    padding: 0;
+}
+
+body.clean-mode .app-title,
+body.clean-mode .room-header,
+body.clean-mode #room-links,
+body.clean-mode #debug-info,
+body.clean-mode #friends-panel,
+body.clean-mode #lobby-buttons {
+    display: none !important;
+}
+
+body.clean-mode #name-form {
+    position: fixed;
+    top: max(8px, env(safe-area-inset-top));
+    right: 8px;
+    margin: 0;
+    padding: 0;
+    width: auto;
+    border: 0;
+    background: transparent;
+    box-shadow: none;
+    backdrop-filter: none;
+    z-index: 10;
+}
+
+body.clean-mode .controls-row-main {
+    gap: 0;
+}
+
+body.clean-mode .controls-row-main > :not(.clean-mode-toggle),
+body.clean-mode .controls-row-secondary {
+    display: none !important;
+}
+
+body.clean-mode #content {
+    width: 100vw;
+    min-height: 100dvh;
+}
+
+body.clean-mode .arrow {
+    width: min(98cqw, 98cqh);
+}
+
 #content {
     position: relative;
     width: 100%;
@@ -592,6 +658,35 @@ body.dark .dark-mode-toggle {
     font-size: clamp(12px, 1.8vmin, 14px);
 }
 
+#debug {
+    margin: 0;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    gap: 10px;
+    flex-wrap: wrap;
+    font-size: inherit;
+    font-weight: 400;
+    line-height: 1.35;
+}
+
+#attributions {
+    margin: 4px 0 0;
+    font-size: inherit;
+    font-weight: 400;
+    line-height: 1.35;
+}
+
+#debug a {
+    text-decoration: underline;
+    text-underline-offset: 0.15em;
+}
+
+#attributions a {
+    text-decoration: underline;
+    text-underline-offset: 0.15em;
+}
+
 .hint {
     position: fixed;
     bottom: 16px;
@@ -651,8 +746,27 @@ body.dark .name-form input[type="color"] {
 
 body.dark .friends-toggle {
     background: rgba(30, 41, 59, 0.96);
-    border-color: #334155;
+    border-color: #94a3b8;
     color: #f1f5f9;
+    box-shadow: inset 0 0 0 1px rgba(148, 163, 184, 0.3);
+}
+
+body.dark #friends-toggle {
+    background: linear-gradient(180deg, #1d4ed8 0%, #1e3a8a 100%);
+    border: 2px solid #93c5fd;
+    color: #eff6ff;
+    box-shadow: 0 0 0 1px rgba(147, 197, 253, 0.35), 0 8px 18px rgba(30, 58, 138, 0.45);
+}
+
+body.dark #friends-toggle:active {
+    transform: translateY(1px);
+}
+
+body.dark.clean-mode .clean-mode-toggle {
+    background: #f8fafc;
+    border: 2px solid #38bdf8;
+    color: #0f172a;
+    box-shadow: 0 6px 18px rgba(15, 23, 42, 0.45);
 }
 
 body.dark .friends-toggle.compass-error {
@@ -681,9 +795,22 @@ body.dark .friend-drag-handle {
 }
 
 body.dark #debug {
-    background: rgba(30, 41, 59, 0.96);
+    background: transparent;
     color: #94a3b8;
-    border-color: #334155;
+    border: 0;
+    box-shadow: none;
+}
+
+body.dark #debug a {
+    color: #60a5fa;
+    outline: none;
+    box-shadow: none;
+}
+
+body.dark #debug a:focus-visible {
+    outline: 2px solid #38bdf8;
+    outline-offset: 2px;
+    border-radius: 4px;
 }
 
 body.dark .arrow-img {