← Back to task

Commit 342385d7

commit 342385d7833567e647231efe2feca4e3df4338d9
Author: Coder Agent <coder@agents.omni>
Date:   Mon Feb 16 20:58:31 2026

    Improve mobile-first dark-mode cohesion across web UIs
    
    Align /tasks, /news, and /files shell spacing and nav behavior.
    
    Increase touch-target sizes and improve phone layout for filters and lists.
    
    Refine dark-mode nav/link contrast in News and Files.
    
    Task-Id: t-619

diff --git a/Omni/Newsreader/Web.hs b/Omni/Newsreader/Web.hs
index b36ecdcc..1ae74df1 100644
--- a/Omni/Newsreader/Web.hs
+++ b/Omni/Newsreader/Web.hs
@@ -370,8 +370,8 @@ css =
       ".brand { font-weight: 700; font-size: 1rem; color: var(--link); }",
       ".brand:hover { text-decoration: none; }",
       ".nav-links { display: flex; gap: 0.25rem; flex-wrap: wrap; font-size: 0.82rem; }",
-      ".nav-links a { color: #374151; padding: 0.25rem 0.6rem; border-radius: 2px; }",
-      ".nav-links a:hover { background: var(--hover); text-decoration: none; }",
+      ".nav-links a { color: var(--muted); padding: 0.25rem 0.6rem; border-radius: 2px; }",
+      ".nav-links a:hover { background: var(--hover); color: var(--fg); text-decoration: none; }",
       "",
       ".article-card { margin-bottom: 0.45rem; background: var(--card); border: 1px solid #e5e7eb; border-radius: 2px; padding: 0.6rem 0.7rem; }",
       ".article-card .title { font-size: 0.95rem; font-weight: 600; display: block; color: var(--link); }",
@@ -404,6 +404,17 @@ css =
       ".search-form input { width: 100%; padding: 0.45rem 0.5rem; font-size: 0.9rem;",
       "  border: 1px solid #d1d5db; background: var(--card); color: var(--fg); border-radius: 2px; }",
       "",
+      "@media (max-width: 700px) {",
+      "  body { font-size: 15px; padding: 0.5rem; }",
+      "  nav { padding: 0.5rem; }",
+      "  .nav-links { width: 100%; gap: 0.2rem; }",
+      "  .nav-links a { padding: 0.45rem 0.6rem; font-size: 0.9rem; }",
+      "  .article-card { padding: 0.7rem; }",
+      "  .article-card .title { font-size: 1rem; line-height: 1.3; }",
+      "  .article-card .meta { font-size: 0.82rem; }",
+      "  .article-card .snippet { font-size: 0.9rem; }",
+      "}",
+      "",
       "h1 { font-size: 1.15rem; margin-bottom: 0.6rem; }"
     ]
 
diff --git a/Omni/Serve.hs b/Omni/Serve.hs
index d1f5c05c..fe1415fd 100755
--- a/Omni/Serve.hs
+++ b/Omni/Serve.hs
@@ -223,11 +223,20 @@ css =
       "a:hover { text-decoration: underline; }",
       ".topnav { display: flex; gap: 0.5rem; align-items: center; flex-wrap: wrap;",
       "  background: var(--card); border-bottom: 1px solid var(--border); margin: 0 0 0.5rem; padding: 0.375rem 0.75rem; }",
-      ".topnav-link { color: #374151; font-size: 0.82rem; padding: 0.25rem 0.6rem; border-radius: 2px; }",
-      ".topnav-link:hover { background: var(--hover); color: #374151; text-decoration: none; }",
+      ".topnav-link { color: var(--muted); font-size: 0.82rem; padding: 0.25rem 0.6rem; border-radius: 2px; }",
+      ".topnav-link:hover { background: var(--hover); color: var(--fg); text-decoration: none; }",
       ".breadcrumb { font-size: 0.8rem; color: var(--muted); margin-bottom: 0.5rem; }",
       "h1 { font-size: 1.15rem; margin: 0 0 0.6rem; }",
       "",
+      "@media (max-width: 700px) {",
+      "  body { font-size: 15px; padding: 0.5rem; }",
+      "  .topnav { padding: 0.5rem; }",
+      "  .topnav-link { padding: 0.45rem 0.6rem; font-size: 0.9rem; }",
+      "  .listing td, .listing th { padding: 0.45rem 0.5rem; }",
+      "  .listing .size, .listing .modified { font-size: 0.78rem; }",
+      "  .markdown-body { padding: 0.6rem; font-size: 0.95rem; }",
+      "}",
+      "",
       "/* Directory listing */",
       ".listing { width: 100%; border-collapse: collapse; background: var(--card); border: 1px solid #e5e7eb; border-radius: 2px; overflow: hidden; }",
       ".listing th { text-align: left; border-bottom: 1px solid #e5e7eb;",
diff --git a/Omni/Task/Web/Style.hs b/Omni/Task/Web/Style.hs
index 0408be72..d89de5f0 100644
--- a/Omni/Task/Web/Style.hs
+++ b/Omni/Task/Web/Style.hs
@@ -774,7 +774,7 @@ buttonStyles = do
     <> ".review-link-btn"
     ? do
       display inlineBlock
-      minHeight (px 32)
+      minHeight (px 36)
       padding (px 6) (px 12) (px 6) (px 12)
       borderRadius (px 2) (px 2) (px 2) (px 2)
       border (px 0) none transparent
@@ -814,7 +814,7 @@ buttonStyles = do
   ".reject-btn" # hover ? backgroundColor "#dc2626"
   ".clear-btn" ? do
     display inlineBlock
-    minHeight (px 32)
+    minHeight (px 36)
     padding (px 6) (px 10) (px 6) (px 10)
     backgroundColor "#6b7280"
     color white
@@ -853,7 +853,7 @@ formStyles = do
     fontWeight (weight 500)
     whiteSpace nowrap
   ".filter-select" <> ".filter-input" <> ".status-select" ? do
-    minHeight (px 32)
+    minHeight (px 36)
     padding (px 6) (px 10) (px 6) (px 10)
     border (px 1) solid "#d1d5db"
     borderRadius (px 2) (px 2) (px 2) (px 2)
@@ -870,7 +870,7 @@ formStyles = do
   ".reject-notes" ? do
     Stylesheet.key "flex" ("1" :: Text)
     minWidth (px 160)
-    minHeight (px 32)
+    minHeight (px 36)
     padding (px 6) (px 10) (px 6) (px 10)
     border (px 1) solid "#d1d5db"
     borderRadius (px 2) (px 2) (px 2) (px 2)
@@ -1883,10 +1883,10 @@ compactToolStyles = do
 responsiveStyles :: Css
 responsiveStyles = do
   query Media.screen [Media.maxWidth (px 600)] <| do
-    body ? fontSize (px 13)
-    ".container" ? padding (px 6) (px 8) (px 6) (px 8)
+    body ? fontSize (px 15)
+    ".container" ? padding (px 8) (px 10) (px 8) (px 10)
     ".navbar" ? do
-      padding (px 6) (px 8) (px 6) (px 8)
+      padding (px 8) (px 10) (px 8) (px 10)
       flexWrap Flexbox.wrap
     ".navbar-hamburger" ? do
       display flex
@@ -1902,14 +1902,14 @@ responsiveStyles = do
     ".navbar-toggle-checkbox" # checked |+ ".navbar-hamburger" |+ ".navbar-links" ? do
       display flex
     ".navbar-link" ? do
-      padding (px 8) (px 6) (px 8) (px 6)
-      fontSize (px 13)
+      padding (px 10) (px 8) (px 10) (px 8)
+      fontSize (px 14)
       width (pct 100)
     ".navbar-dropdown" ? do
       width (pct 100)
     ".navbar-dropdown-btn" ? do
-      padding (px 8) (px 6) (px 8) (px 6)
-      fontSize (px 13)
+      padding (px 10) (px 8) (px 10) (px 8)
+      fontSize (px 14)
       width (pct 100)
       textAlign (alignSide sideLeft)
     ".navbar-dropdown-content" ? do
@@ -1918,8 +1918,8 @@ responsiveStyles = do
       paddingLeft (px 12)
       backgroundColor transparent
     ".navbar-dropdown-item" ? do
-      padding (px 6) (px 10) (px 6) (px 10)
-      fontSize (px 12)
+      padding (px 8) (px 10) (px 8) (px 10)
+      fontSize (px 13)
     ".nav-content" ? do
       flexDirection column
       alignItems flexStart
@@ -1930,11 +1930,17 @@ responsiveStyles = do
       Stylesheet.key "gap" ("2px" :: Text)
     ".detail-label" ? width auto
     ".filter-row" ? do
-      flexWrap Flexbox.wrap
+      flexDirection column
+      alignItems stretch
+      Stylesheet.key "gap" ("10px" :: Text)
     ".filter-group" ? do
-      width auto
-      flexWrap Flexbox.nowrap
-    ".filter-select" <> ".filter-input" ? minWidth (px 80)
+      width (pct 100)
+      flexDirection column
+      alignItems flexStart
+      Stylesheet.key "gap" ("4px" :: Text)
+    ".filter-select" <> ".filter-input" ? do
+      minWidth (px 0)
+      width (pct 100)
     ".review-actions" ? do
       flexDirection column
     ".reject-form" ? do
@@ -1943,6 +1949,20 @@ responsiveStyles = do
     ".reject-notes" ? width (pct 100)
     ".actions" ? flexDirection column
     ".action-btn" ? width (pct 100)
+    ".list-group-item" ? do
+      alignItems flexStart
+      padding (px 10) (px 10) (px 10) (px 10)
+      flexWrap Flexbox.wrap
+    ".list-group-item-content" ? do
+      width (pct 100)
+      alignItems flexStart
+    ".list-group-item-title" ? do
+      whiteSpace normal
+      Stylesheet.key "text-overflow" ("clip" :: Text)
+    ".list-group-item-meta" ? do
+      width (pct 100)
+      justifyContent spaceBetween
+      marginTop (px 4)
 
 darkModeStyles :: Css
 darkModeStyles =