From 986f62462065a18a7e7a4a8577f160aca6c6c36c Mon Sep 17 00:00:00 2001 From: Abby Skofield Date: Sun, 30 Aug 2026 16:29:13 -0400 Subject: [PATCH 1/4] Update logo to use 3x3 grid of options to better fit square icon aspect ratio --- .../AppIcon.appiconset/Contents.json | 2 +- .../AppIcon.appiconset/loglist_logo.png | Bin 31142 -> 0 bytes .../AppIcon.appiconset/loglist_logo_square.png | Bin 0 -> 27354 bytes 3 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 ios/Loglist/Loglist/Assets.xcassets/AppIcon.appiconset/loglist_logo.png create mode 100644 ios/Loglist/Loglist/Assets.xcassets/AppIcon.appiconset/loglist_logo_square.png diff --git a/ios/Loglist/Loglist/Assets.xcassets/AppIcon.appiconset/Contents.json b/ios/Loglist/Loglist/Assets.xcassets/AppIcon.appiconset/Contents.json index 1ec1685..da148fe 100644 --- a/ios/Loglist/Loglist/Assets.xcassets/AppIcon.appiconset/Contents.json +++ b/ios/Loglist/Loglist/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "loglist_logo.png", + "filename" : "loglist_logo_square.png", "idiom" : "universal", "platform" : "ios", "size" : "1024x1024" diff --git a/ios/Loglist/Loglist/Assets.xcassets/AppIcon.appiconset/loglist_logo.png b/ios/Loglist/Loglist/Assets.xcassets/AppIcon.appiconset/loglist_logo.png deleted file mode 100644 index d360ecb0ec41735f511df2ed63f4903278005554..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 31142 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

50Wc!~8*;Ok zbh-ow>(!~=VH8(K&>BuuRdFSK{}of|QuWF+q2HAJR2ik4c&`^E&c%gLL;7)3JU^8o zZ!qT)ePomdpoK;NS}26(fx@o=h-R>itOid13($tF#C6|SJ2{obn12{8x+a4<<6fL= zWW1X;P}wSVN)cctKBB~uV}x+U;PlLruGqWD7Xh%@%306S3Tuu?zWDxr>sZT~KqG|4 zMu5qw?KmpLJ9rm^v+izsma4=;_hVwow&0{dl)gcK_3h|gp}~!-;TKoTa{OEvc8vPb ztTO=cd59vs?%|{AnG-oye)v@tY&?HK5Dqt|BdGbZ5Mz? zcyucE+Zyfn0)%1i4_EU}x1R$7EMX&K)p+OS?~vdqMc_bkxN-LbaGbUjWR4^CW2g0n&TU%z+j zGHz4cw}D-jQGIY0LLRE&MrgyqDUn6B0Qj<^u1dc z)e-C|86$P|I9k#K%k7$aI5wEr0siH7Ik>gLr??lcDeEO@2r!A@5))O<@QE0P-l<^9 z7NiZj?#1NYoD`|P7?i94QRFib>5ykwcW;MV@4-}S*aM&ov9F>S_rdKX9Vs%_+W2ud z^Wf$*)J*}vFbjuuzU<(zPw{EjQ(>@pGwvU7G_Cd4x?;w1jcu9S@sW!%HTW|+DbUl( zvMzqR08>g2luExTt=$n0Zfi-<;n4**p$I@H42@R=e+w!pkY`N3t(@^UuVXCfyF>KiH?$?p5MV z9Q&yhq%#~@g5ANndf+QSY1;WV-U4ARR~DxaO-}IM=U{N2lM(9HALGo|-vd_9G1097Y z5qRc^>|hy#k%x>p#_zGkmp9d?>I2|sQuc?f3EqWvblu3@r(J&Sdc*R%dj5<=`!RD& z>nMAm`mZ}-bY6nsS|FvQ0k3cS-;n z=j{rxMOdU@a5S?0i_wkI*p5+u;>Irs3P7tipTzyBGic~q@)-bH!3`<=9^%l)4%U*1 zHMS`JI(2*{(5D?7#8v;FVeSqMPn z5z)s#;R|cz{Hc15Oo6x-oYO0eKi(>9QoR(qn!zWJW!dAp0C?>V=N&|I9aT%3eA(h~ zllSS++m_Pt?Zi>T&7TJv&BH!;qGANDLwkVD{0U3=Q8gSpy-J5E>iFKv0OYC8dG-TL zSC0W2E4WGqQ-?i7fGD<@+B%1`hU0m8!fp&E6^79{5|@SnwEv#KfmFMh((x6g{RRxB zV$707Ra)lZz3nW{-tnF$X#hV=H6wYptMW|gO^CPIJ!Yyhedd<@vt*ib+2nXJMt0E~ zCnSrjPaUTTt}ZI~CMFaCH``Gp_0Op$Q(`VB0e}0~)kS4pxTd?dd}2qx*gyRq=2WZz z^^Uu38A#;0PKJxwm@-eU$agpe(8sGtd!sG$T3y@AgtrF$?QI3E&1S=_>JzX#%AAUe z{voyXJuaC|FM*YC2d>IkltreR5fgZ5W+E7mDP;CMjT2g7V@=`9+;0Iyp^fx|DLRbMI1z*!URi98xbZKO684Q+ z){O$dL#r~jgFkhi%DQG-9ZpVLVA19@@g$BJR1;idLX8z-@HIBFx`O(I*#5-;p$O3Y zlldzbfGdWI7(p~6Mg6S;;9{=e(kkBSQJ(Azx6uzl@34x5+lS&tp6av8|Kcq5dL}?6 za&|ZQk>K-VrQAEqcUz*tv8&P`5D4&d6cWGvXlLB~b+M5>1|AHhWe_F*B0G z2C*qlm(6ndZ2VoC;`t|LBpSG&=@7W!=+mpvu+m=AFI*zi>R7`m`_Z<#+*N6$;8%x> z)s>!JPjm=3y6eOQ_jY{%cMjR<0X}ktFviu1T26c;MejI{x9q3NLUVS)s_LIzrdn7( zx{1`!(_pM`^-?K?ZK3_bTaMT?OfJA-{*Jmnc&gX&lBCXj6M*s=SUkfT;SthF%W|Kv z9xShx^>@&;P!GXlG9H7whp>F9#MDXHggJ=}Na}+>RSCku*#}BK6a~A|we>92b@fIE zL8vD@WFWZnC_xn*dT}b??dZBC2>qU|KQV<+d_>F8UdK{Y7T#kt32J~jR8N49%pI<> z)ecX8e)0ZP`PTfEqj~C6XK8>obui8)pL@Q$>swAdIEql5wZi?vmDpMVdYNx#fx5p9;OlKX}Aq#S23W%&z`iqd$egMt%3j^Ms1tzRd8093x7XDJo$2oTwdQ@0xl zZ!`kRZ2Ak}7)HnL9Y6bdD?p?O0K=RN8O>LGsrQ}()|1Xk^G|_`;5^eX##g11<*Gd?)iSxWcwu-V-~N0UNlQtlyrjWZXNU+ibCY0Z7VZq4f& z=Xp)vA07>WUu}JJ_2z+zQqIdva|VYO-1qA2D6fxG%*NhHE0ZTfD?qAh1$5>XLZxyC z^e9-eVuN_{YseyIA+#|`_{<1wn@bYnouLE6!e<(_&{GZQ(^_%#H8;UC!eL4DWkmA& zmCzAA;j@3YLz@;tJ8PgDUxm*cZzC*DK~E1#5|)yM&r%i==8L0Ew+osRJo}G@|D^Dr zF8pT^|M>-h$NWzU|4HG$nexAQ;s2DVsWNU9b&vPdB<*|0B~rzfx0`EjYs>- zNww5$SBK2}Yi2%rC|<9x|2Ak-y#en{YxK+fYnCDD^{CO9*4WJ%50CSs3sR*arhCuW z^(F@y?d2eb4U+%#z^)|IVYtS|wq1+!@NsWp@H;YUwCT8V+U6`h4e;b~P#+gQgx}q9 zav|a2V0+L9T-)Q`b3Kzwhq+d zulO|QQ=oIPc7@pS$0l`WhJ!Kp`B|W*|8iVFuWvi1gCBhXHNnaMty6x0!i*9>8$v2NgSOm3nl2DwS*t^Xs(eNmEMVsID zT4^_X;I);BVOc%$nBU{O& z+XIE|s2x1(&fun+)*{2d$H#+`5^?EW{?(Wd<*Bl!MYREt%iHJ+KAD+01Cviuxd6=t9zn_;vp?GNT zGm_{k4DO38g|amPyXsMBdl4gaVghvt^*0JLJXu~?XuzpDzy!TMO}By_20yQ%elEwd z1{Bvc+m`w$>2Uj-qCdL2L2o>Irys&2kh&=k3r}yy7oxDZf2ubuuaao*CwG8ojoAY27udv#T+dkGaS{FX? zE_T&s@0ZI`*zX#%4xtQ4@7GkrXZ!0f=3#DWQrPTz4jr!hQSIib0lhZ!DII#^$%w}q zJ!)zHfWiNK=1)z)`GWe7Wt8>u&;D$0lCAgD1rkLC+a^3s%L*Y^CryCOJhwUx==cF=ib%W7V z%CY3Qei6h2a;@b Date: Sun, 30 Aug 2026 16:29:49 -0400 Subject: [PATCH 2/4] Update legacy action button on list detail view. Clean up css to use better names and limited set of tokens. --- web/design-system.html | 26 ++++++++++---------- web/screens/history.js | 26 ++++++++++---------- web/screens/lists.js | 49 +++++++++++++++++++++----------------- web/screens/track.js | 6 ++--- web/styles.css | 54 ++++++++++++++++++++++++++---------------- 5 files changed, 89 insertions(+), 72 deletions(-) diff --git a/web/design-system.html b/web/design-system.html index dd385b9..460dac2 100644 --- a/web/design-system.html +++ b/web/design-system.html @@ -860,16 +860,16 @@

Screen Header

Main Page

-
+
-
@@ -891,7 +891,7 @@

-
@@ -983,7 +983,7 @@

Secondary

>
- `; - const sortToggle = container.querySelector('.history-sort-toggle'); + const sortToggle = container.querySelector('[data-header-action="sort"]'); if (sortToggle) { sortToggle.addEventListener('click', async (e) => { e.stopPropagation(); @@ -639,7 +639,7 @@ }); } - container.querySelectorAll('.sort-option').forEach((option) => { + container.querySelectorAll('.menu-option').forEach((option) => { option.addEventListener('click', async (e) => { e.stopPropagation(); sortMode = option.getAttribute('data-sort') || 'recent'; @@ -838,13 +838,13 @@ ${detailNameMarkup}
- - -
@@ -931,14 +931,14 @@ }); } - const shareButton = container.querySelector('.history-detail-share'); + const shareButton = container.querySelector('[data-header-action="share"]'); if (shareButton) { shareButton.addEventListener('click', () => { shareSessionCsv(session); }); } - const deleteButton = container.querySelector('.history-detail-delete'); + const deleteButton = container.querySelector('[data-header-action="delete"]'); if (deleteButton) { deleteButton.addEventListener('click', async () => { const label = getSessionName(session, 'session'); diff --git a/web/screens/lists.js b/web/screens/lists.js index 7d63781..e6c81bb 100644 --- a/web/screens/lists.js +++ b/web/screens/lists.js @@ -168,10 +168,10 @@ controls.className = 'header-controls'; const sortWrap = document.createElement('div'); - sortWrap.className = 'sort-menu-wrap'; + sortWrap.className = 'header-menu-wrap'; const sortToggle = document.createElement('button'); - sortToggle.className = 'sort-toggle'; + sortToggle.className = 'header-button-secondary'; sortToggle.setAttribute('type', 'button'); sortToggle.setAttribute( 'aria-label', @@ -183,15 +183,15 @@ if (sortMenuOpen) { const menu = document.createElement('div'); - menu.className = 'sort-menu'; + menu.className = 'header-menu'; menu.innerHTML = ` - - - `; @@ -200,7 +200,7 @@ // create add button and place it inside the header so it aligns vertically with the title const add = document.createElement('button'); - add.className = 'add-button'; + add.className = 'header-button-primary'; add.setAttribute('aria-label', 'Add list'); add.innerHTML = ''; @@ -229,7 +229,7 @@ await rerenderFromRepository(); }); - document.querySelectorAll('.sort-option').forEach((option) => { + document.querySelectorAll('.menu-option').forEach((option) => { option.addEventListener('click', async (e) => { e.stopPropagation(); sortMode = option.getAttribute('data-sort') || 'default'; @@ -294,19 +294,31 @@ `; + const headerControls = document.createElement('div'); + headerControls.className = 'header-controls detail-header-controls'; + if (canEditItems) { const add = document.createElement('button'); - add.className = 'add-button'; + add.className = 'header-button-secondary detail-add-item'; + add.type = 'button'; add.setAttribute('aria-label', 'Add list item'); add.innerHTML = ''; - header.appendChild(add); + headerControls.appendChild(add); } + const count = Array.isArray(list.items) ? list.items.length : 0; + const startButton = document.createElement('button'); + startButton.className = 'header-button-primary detail-start-session'; + startButton.type = 'button'; + startButton.setAttribute('aria-label', 'Start session for this list'); + startButton.disabled = count === 0; + startButton.innerHTML = ''; + headerControls.appendChild(startButton); + header.appendChild(headerControls); + const card = document.createElement('div'); card.className = 'list-detail-card lists-container'; - const count = Array.isArray(list.items) ? list.items.length : 0; - const itemsContainer = document.createElement('div'); itemsContainer.className = 'list-detail-items'; const items = Array.isArray(list.items) ? list.items : []; @@ -361,16 +373,9 @@ const footer = document.createElement('div'); footer.className = 'list-detail-footer'; - footer.innerHTML = ` -
${count} item${ + footer.innerHTML = `
${count} item${ count === 1 ? '' : 's' - }
- - `; + }
`; container.appendChild(header); container.appendChild(card); @@ -436,7 +441,7 @@ }); } - const detailAdd = container.querySelector('.screen-header .add-button'); + const detailAdd = container.querySelector('.detail-add-item'); if (detailAdd) { detailAdd.addEventListener('click', async () => { const nextList = list; diff --git a/web/screens/track.js b/web/screens/track.js index c316e06..d15666b 100644 --- a/web/screens/track.js +++ b/web/screens/track.js @@ -418,13 +418,13 @@ ${breadcrumbSessionNameMarkup}
- - -
diff --git a/web/styles.css b/web/styles.css index c458467..726e1c4 100644 --- a/web/styles.css +++ b/web/styles.css @@ -23,6 +23,11 @@ --border-color: rgba(0, 0, 0, 0.08); --border: 1px solid var(--border-color); + /* Shadow and overlay tokens */ + --shadow-sm: 0 8px 18px rgba(17, 24, 39, 0.08); + --shadow-md: 0 10px 24px rgba(38, 42, 52, 0.35); + --overlay-backdrop: rgba(0, 0, 0, 0.28); + /* Bottom nav layer treatment */ --nav-bg: color-mix(in srgb, var(--surface) 85%, var(--accent) 15%); --nav-border-top: rgba(0, 0, 0, 0.12); @@ -47,6 +52,11 @@ html[data-theme='dark'] { --border-color: hsla(0, 0%, 100%, 0.06); --border: 1px solid var(--border-color); + /* Shadow and overlay tokens for dark */ + --shadow-sm: 0 10px 24px rgba(0, 0, 0, 0.35); + --shadow-md: 0 12px 26px rgba(0, 0, 0, 0.42); + --overlay-backdrop: rgba(0, 0, 0, 0.42); + /* Bottom nav layer treatment for dark */ --nav-bg: color-mix(in srgb, var(--surface) 90%, var(--accent) 10%); --nav-border-top: hsla(0, 0%, 100%, 0.12); @@ -123,12 +133,12 @@ body { gap: 8px; } -.screen-header .sort-menu-wrap { +.screen-header .header-menu-wrap { position: relative; display: inline-flex; } -.screen-header .sort-toggle { +.screen-header .header-button-secondary { width: 32px; min-width: 32px; height: 32px; @@ -142,37 +152,39 @@ body { transition: background-color 140ms ease; } -.screen-header .sort-toggle:hover { +.screen-header .header-button-secondary:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); } -.screen-header .sort-toggle[aria-expanded='true'] { +.screen-header .header-button-secondary[aria-expanded='true'] { background: color-mix(in srgb, var(--accent) 10%, transparent); } -.screen-header .sort-toggle[aria-expanded='true']:hover { +.screen-header .header-button-secondary[aria-expanded='true']:hover { background: color-mix(in srgb, var(--accent) 10%, transparent); } -html[data-theme='dark'] .screen-header .sort-toggle:hover { +html[data-theme='dark'] .screen-header .header-button-secondary:hover { background: color-mix(in srgb, var(--accent) 24%, var(--surface) 76%); } -html[data-theme='dark'] .screen-header .sort-toggle[aria-expanded='true'], html[data-theme='dark'] .screen-header - .sort-toggle[aria-expanded='true']:hover { + .header-button-secondary[aria-expanded='true'], +html[data-theme='dark'] + .screen-header + .header-button-secondary[aria-expanded='true']:hover { background: color-mix(in srgb, var(--accent) 30%, var(--surface) 70%); } -.screen-header .sort-toggle svg.feather { +.screen-header .header-button-secondary svg.feather { width: 30px; height: 30px; stroke: currentColor; stroke-width: 1.5; } -.screen-header .sort-menu { +.screen-header .header-menu { position: absolute; top: calc(100% + 2px); right: 0; @@ -181,19 +193,19 @@ html[data-theme='dark'] border-radius: 0; border: none; background: color-mix(in srgb, var(--accent) 10%, var(--bg) 90%); - box-shadow: 0 8px 18px rgba(0, 0, 0, 0.08); + box-shadow: var(--shadow-sm); display: flex; flex-direction: column; gap: 5px; z-index: 80; } -html[data-theme='dark'] .screen-header .sort-menu { +html[data-theme='dark'] .screen-header .header-menu { background: color-mix(in srgb, var(--accent) 24%, var(--surface) 76%); - box-shadow: 0 10px 24px rgba(0, 0, 0, 0.35); + box-shadow: var(--shadow-md); } -.screen-header .sort-option { +.screen-header .menu-option { border: none; background: transparent; color: var(--text); @@ -204,17 +216,17 @@ html[data-theme='dark'] .screen-header .sort-menu { cursor: pointer; } -.screen-header .sort-option:hover { +.screen-header .menu-option:hover { background: color-mix(in srgb, var(--accent) 8%, transparent); } -.screen-header .sort-option.active { +.screen-header .menu-option.active { color: var(--accent); background: color-mix(in srgb, var(--accent) 14%, transparent); } /* Position add button inside the header and make it round and match header height */ -.screen-header .add-button { +.screen-header .header-button-primary { flex: 0 0 36px; width: 36px; min-width: 36px; @@ -232,7 +244,7 @@ html[data-theme='dark'] .screen-header .sort-menu { z-index: 60; align-self: flex-end; } -.screen-header .add-button svg.feather { +.screen-header .header-button-primary svg.feather { width: 18px; height: 18px; display: block; @@ -810,7 +822,7 @@ html[data-theme='dark'] .list-drawer { border: var(--border); border-radius: var(--radius); background: var(--surface-bg); - box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08); + box-shadow: var(--shadow-sm); padding: 6px; display: flex; flex-direction: column; @@ -821,7 +833,7 @@ html[data-theme='dark'] .list-drawer { } html[data-theme='dark'] .track-picker-menu { - box-shadow: 0 8px 22px rgba(0, 0, 0, 0.35); + box-shadow: var(--shadow-md); } .track-picker-option { @@ -1041,7 +1053,7 @@ html[data-theme='dark'] .track-picker-menu { .session-exit-backdrop { position: fixed; inset: 0; - background: rgba(0, 0, 0, 0.28); + background: var(--overlay-backdrop); display: flex; align-items: center; justify-content: center; From ed5b13f0280e8de28e95939605d4272df4980527 Mon Sep 17 00:00:00 2001 From: Abby Skofield Date: Sun, 30 Aug 2026 16:58:44 -0400 Subject: [PATCH 3/4] Bump up sizes of fonts, icons and hit areas a little to improve mobile experience. --- web/design-system.html | 73 ++++++++++++++++++++++++------------------ web/styles.css | 59 +++++++++++++++++----------------- 2 files changed, 72 insertions(+), 60 deletions(-) diff --git a/web/design-system.html b/web/design-system.html index 460dac2..4e0e3e5 100644 --- a/web/design-system.html +++ b/web/design-system.html @@ -193,7 +193,7 @@ background: var(--surface); border: 1px solid var(--border-color); border-radius: var(--radius); - box-shadow: var(--shadow-soft); + box-shadow: var(--shadow-sm); padding: 20px; margin-bottom: 20px; } @@ -672,15 +672,15 @@

Icons

  • In standard buttons, the icon should use the same color as the text in the control and should be relatively small - sized to fit - the control's height. These buttons always include a label to the - right of the icon. + the control's height (--icon-size-sm). These buttons generally include a label to the + right of the icon, with the exception of the small delete option on selected list items.
  • Header action buttons are icon-only controls without labels, and - therefore use somewhat larger icons. + therefore use somewhat larger icons (--icon-size-lg).
  • - Bottom navigation items pair a somewhat larger icon with a small + Bottom navigation items pair a somewhat larger icon (--icon-size-md) with a small text label below.
  • @@ -829,21 +829,20 @@

    Fonts

    • - --fs-base: 15px - Global app text size + --fs-base: 17px - Global app text size applied on html, body.
    • - --fs-md: 14px - Used for the names of - list items and other row names. + --fs-md: 16px - Used for list item + names, row labels, and most medium-weight content.
    • - --fs-sm: 12px - Used for labels in the - bottom navigation bar and secondary buttons. + --fs-sm: 14px - Used for supporting + text, menu items, and secondary controls.
    • - --fs-xs: 11px - Reserved for metadata - and support text (for example badges, counts, and footer summary - text). + --fs-xs: 12px - Reserved for metadata, + badges, counts, and footer summary text.
    @@ -857,7 +856,7 @@

    Screen Header


    -

    Main Page

    +

    Example Header

    @@ -869,7 +868,11 @@

    Main Page

    -
    @@ -885,13 +888,17 @@

    Main Page

    - Main Page + Example Header > Detail Page

    -
    @@ -1076,7 +1083,7 @@

    Dropdown

    -

    History

    +

    Example

    - @@ -1147,7 +1158,7 @@

    Progress Tracker

    - Observed: 4 + Example Observed: 4 (40%) @@ -1267,23 +1278,23 @@

    Item Grid

    @@ -1320,15 +1331,15 @@

    Rename Affordance

    - Lists + Example > - Trip Ideas + Renamable Text

    -
    Weekend list
    +
    Renamable Item
    4 items
    diff --git a/web/styles.css b/web/styles.css index 726e1c4..fbb374b 100644 --- a/web/styles.css +++ b/web/styles.css @@ -10,10 +10,17 @@ --on-accent: #ffffff; /* Typography sizes (semantic) */ - --fs-base: 15px; /* slightly smaller than browser default */ - --fs-md: 14px; - --fs-sm: 12px; - --fs-xs: 11px; + --fs-base: 17px; /* mobile-first reading size */ + --fs-md: 16px; + --fs-sm: 14px; + --fs-xs: 12px; + + /* Shared sizing tokens for touch targets and icons */ + --hit-target-sm: 36px; + --hit-target-md: 40px; + --icon-size-sm: 18px; + --icon-size-md: 20px; + --icon-size-lg: 32px; /* Semantic surface tokens (single source of truth for components) */ --surface-bg: var(--surface); @@ -139,9 +146,9 @@ body { } .screen-header .header-button-secondary { - width: 32px; - min-width: 32px; - height: 32px; + width: var(--hit-target-sm); + min-width: var(--hit-target-sm); + height: var(--hit-target-sm); border: none; background: transparent; color: var(--accent); @@ -178,8 +185,8 @@ html[data-theme='dark'] } .screen-header .header-button-secondary svg.feather { - width: 30px; - height: 30px; + width: var(--icon-size-lg); + height: var(--icon-size-lg); stroke: currentColor; stroke-width: 1.5; } @@ -227,10 +234,10 @@ html[data-theme='dark'] .screen-header .header-menu { /* Position add button inside the header and make it round and match header height */ .screen-header .header-button-primary { - flex: 0 0 36px; - width: 36px; - min-width: 36px; - height: 36px; + flex: 0 0 var(--hit-target-md); + width: var(--hit-target-md); + min-width: var(--hit-target-md); + height: var(--hit-target-md); box-sizing: border-box; padding: 0; border-radius: 50%; /* make it round */ @@ -245,8 +252,8 @@ html[data-theme='dark'] .screen-header .header-menu { align-self: flex-end; } .screen-header .header-button-primary svg.feather { - width: 18px; - height: 18px; + width: var(--icon-size-sm); + height: var(--icon-size-sm); display: block; stroke: currentColor; stroke-width: 1.8; @@ -290,8 +297,8 @@ html[data-theme='dark'] .screen-header .header-menu { } .bottom-nav .nav-button svg.feather { - width: 20px; - height: 20px; + width: var(--icon-size-md); + height: var(--icon-size-md); flex-shrink: 0; } @@ -466,12 +473,6 @@ html[data-theme='dark'] .screen-header .header-menu { justify-content: space-between; } -@media (max-width: 560px) { - .history-session-actions-row .drawer-action { - flex: 1 1 0; - } -} - .list-item:last-child .list-drawer { border-bottom-left-radius: 12px; border-bottom-right-radius: 12px; @@ -491,8 +492,8 @@ html[data-theme='dark'] .screen-header .header-menu { } .drawer-action svg.feather { - width: var(--fs-md); - height: var(--fs-md); + width: var(--icon-size-sm); + height: var(--icon-size-sm); flex: 0 0 auto; stroke: currentColor; stroke-width: 2; @@ -587,8 +588,8 @@ html[data-theme='dark'] .list-drawer { .row-delete svg.feather, .detail-item-grip svg.feather, .detail-item-delete svg.feather { - width: var(--fs-md); - height: var(--fs-md); + width: var(--icon-size-sm); + height: var(--icon-size-sm); stroke: currentColor; stroke-width: 2; } @@ -807,8 +808,8 @@ html[data-theme='dark'] .list-drawer { } .track-picker-selected-right svg.feather { - width: 16px; - height: 16px; + width: var(--icon-size-sm); + height: var(--icon-size-sm); stroke: var(--accent); stroke-width: 2.2; } From e0b42d5074ecd6613400cc6867bf46d8bdc8bd09 Mon Sep 17 00:00:00 2001 From: Abby Skofield Date: Sun, 30 Aug 2026 17:09:36 -0400 Subject: [PATCH 4/4] Allow for lists to be either ordered alphabetically or in a custom order. --- docs/DataModel.md | 2 + web/screens/lists.js | 184 ++++++++++++++++++++++++++++++++++++++----- 2 files changed, 167 insertions(+), 19 deletions(-) diff --git a/docs/DataModel.md b/docs/DataModel.md index b3fc636..ff031b9 100644 --- a/docs/DataModel.md +++ b/docs/DataModel.md @@ -13,6 +13,7 @@ Fields: - id: string - name: string - builtIn: boolean +- displayOrderMode: string, either `alphabetical` or `custom` for custom lists; omitted for built-in lists - items: array of Item objects Example: @@ -35,6 +36,7 @@ Notes: - Built-in lists are seeded from `web/data/builtins.json`. - Custom lists are stored alongside built-ins in `localStorage` under the `ot_lists_v1` key. - A custom list is created by duplicating a built-in list and marking the new item as `builtIn: false`. +- Custom lists default to `displayOrderMode: "alphabetical"`, where item names are shown and inserted alphabetically case-insensitively. In `custom` mode, manual item ordering is preserved and new items are appended. ### Item diff --git a/web/screens/lists.js b/web/screens/lists.js index e6c81bb..4ff4c4e 100644 --- a/web/screens/lists.js +++ b/web/screens/lists.js @@ -12,6 +12,7 @@ let viewMode = 'lists'; let sortMode = 'default'; let sortMenuOpen = false; + let displayOrderMenuOpen = false; function normalizeRenameValue(rawValue) { if (typeof nameHelpers.normalizeRenameValue === 'function') { @@ -30,6 +31,63 @@ .toLocaleLowerCase(); } + function getListDisplayOrderMode(list) { + if (!list || list.builtIn) return 'alphabetical'; + return list.displayOrderMode === 'custom' ? 'custom' : 'alphabetical'; + } + + function areSameListItem(a, b) { + if (a === b) return true; + if (typeof a === 'string' && typeof b === 'string') return a === b; + if (typeof a === 'object' && a && typeof b === 'object' && b) { + const aId = a.id ?? a.name ?? ''; + const bId = b.id ?? b.name ?? ''; + if (aId && bId) return String(aId) === String(bId); + return String(a.name ?? '') === String(b.name ?? ''); + } + return String(a ?? '') === String(b ?? ''); + } + + function getItemName(item) { + return String(typeof item === 'string' ? item : item?.name || '').trim(); + } + + function compareItemNames(a, b) { + return getItemName(a).localeCompare(getItemName(b), undefined, { + sensitivity: 'base', + }); + } + + function sortListItemsForDisplay(list) { + if (!Array.isArray(list?.items)) return []; + const items = [...list.items]; + if (getListDisplayOrderMode(list) !== 'alphabetical') return items; + return items.sort(compareItemNames); + } + + function insertItemInDisplayOrder(list, item) { + if (!list || list.builtIn) return item; + const nextItems = Array.isArray(list.items) ? [...list.items] : []; + const nextItem = + item && typeof item === 'object' && !Array.isArray(item) + ? { ...item } + : item; + if (getListDisplayOrderMode(list) !== 'alphabetical') { + nextItems.push(nextItem); + list.items = nextItems; + return nextItem; + } + + const insertionIndex = nextItems.findIndex( + (current) => compareItemNames(current, nextItem) > 0 + ); + if (insertionIndex === -1) nextItems.push(nextItem); + else nextItems.splice(insertionIndex, 0, nextItem); + + list.items = nextItems; + return nextItem; + } + function hasDuplicateListName(lists, candidateName, excludeId) { const targetKey = normalizeNameKey(candidateName); return (Array.isArray(lists) ? lists : []).some( @@ -258,6 +316,7 @@ id: 'custom-' + Date.now(), name, builtIn: false, + displayOrderMode: 'alphabetical', items: [], }; window.repository.saveList(newList); @@ -298,6 +357,66 @@ headerControls.className = 'header-controls detail-header-controls'; if (canEditItems) { + const displayOrderWrap = document.createElement('div'); + displayOrderWrap.className = 'header-menu-wrap'; + + const displayOrderToggle = document.createElement('button'); + displayOrderToggle.className = + 'header-button-secondary detail-display-order-toggle'; + displayOrderToggle.type = 'button'; + displayOrderToggle.setAttribute( + 'aria-label', + `Display order mode (${getListDisplayOrderMode(list)})` + ); + displayOrderToggle.setAttribute( + 'aria-expanded', + displayOrderMenuOpen ? 'true' : 'false' + ); + displayOrderToggle.innerHTML = ''; + displayOrderWrap.appendChild(displayOrderToggle); + + if (displayOrderMenuOpen) { + const menu = document.createElement('div'); + menu.className = 'header-menu'; + const currentMode = getListDisplayOrderMode(list); + menu.innerHTML = ` + + + `; + displayOrderWrap.appendChild(menu); + } + + displayOrderToggle.addEventListener('click', (e) => { + e.stopPropagation(); + displayOrderMenuOpen = !displayOrderMenuOpen; + renderDetailView(container, list); + }); + + const menuLinks = displayOrderWrap.querySelectorAll('.menu-option'); + menuLinks.forEach((option) => { + option.addEventListener('click', async (e) => { + e.stopPropagation(); + const nextMode = + option.getAttribute('data-display-order') || 'alphabetical'; + const refreshed = await window.repository.loadLists(); + const nextList = refreshed.find((x) => x.id === detailListId); + if (!nextList || nextList.builtIn) return; + nextList.displayOrderMode = nextMode; + if (nextMode === 'alphabetical') { + nextList.items = sortListItemsForDisplay(nextList); + } + await window.repository.saveList(nextList); + displayOrderMenuOpen = false; + render(await window.repository.loadLists()); + }); + }); + + headerControls.appendChild(displayOrderWrap); + const add = document.createElement('button'); add.className = 'header-button-secondary detail-add-item'; add.type = 'button'; @@ -321,7 +440,7 @@ const itemsContainer = document.createElement('div'); itemsContainer.className = 'list-detail-items'; - const items = Array.isArray(list.items) ? list.items : []; + const items = sortListItemsForDisplay(list); if (!items.length) { const empty = document.createElement('div'); @@ -334,34 +453,44 @@ itemsContainer.appendChild(empty); } else { items.forEach((item, index) => { - const selected = selectedDetailItemIndex === index; - const editing = editingDetailItemIndex === index && canEditItems; + const itemIndex = Array.isArray(list.items) + ? list.items.findIndex((candidate) => + areSameListItem(candidate, item) + ) + : index; + const resolvedIndex = itemIndex >= 0 ? itemIndex : index; + const selected = selectedDetailItemIndex === resolvedIndex; + const editing = + editingDetailItemIndex === resolvedIndex && canEditItems; const label = typeof item === 'string' ? item : item.name || ''; + const isCustomOrder = getListDisplayOrderMode(list) === 'custom'; const row = document.createElement('div'); row.className = `list-detail-item${selected ? ' selected' : ''}`; - row.setAttribute('data-item-index', String(index)); + row.setAttribute('data-item-index', String(resolvedIndex)); row.setAttribute('draggable', 'false'); row.innerHTML = ` ${ - canEditItems - ? `` + canEditItems && isCustomOrder + ? `` : '' }
    ${ editing - ? `` : `${escapeHtml(label)}` + }" data-item-index="${resolvedIndex}">${escapeHtml( + label + )}` }
    ${ canEditItems && selected - ? `` + ? `` : '' } `; @@ -466,10 +595,15 @@ name, }; - nextList.items = existingItems.concat(newItem); + insertItemInDisplayOrder(nextList, newItem); + if (getListDisplayOrderMode(nextList) === 'alphabetical') { + nextList.items = sortListItemsForDisplay(nextList); + } window.repository.saveList(nextList); - selectedDetailItemIndex = nextList.items.length - 1; - editingDetailItemIndex = nextList.items.length - 1; + selectedDetailItemIndex = nextList.items.findIndex((item) => + areSameListItem(item, newItem) + ); + editingDetailItemIndex = selectedDetailItemIndex; renderDetailView(container, nextList); }); } @@ -505,6 +639,9 @@ id: 'item-' + Date.now() + '-' + index, name, })); + if (getListDisplayOrderMode(nextList) === 'alphabetical') { + nextList.items = sortListItemsForDisplay(nextList); + } await window.repository.saveList(nextList); selectedDetailItemIndex = null; editingDetailItemIndex = null; @@ -589,6 +726,7 @@ function initializeDetailSorting(container, list, canEditItems) { if (!canEditItems) return; + if (getListDisplayOrderMode(list) !== 'custom') return; if (!Array.isArray(list.items) || list.items.length < 2) return; const itemsContainer = container.querySelector('.list-detail-items'); @@ -693,7 +831,10 @@ if (!normalized.ok) return normalized; const lists = await window.repository.loadLists(); const nextList = lists.find((x) => x.id === detailListId); - if (nextList && hasDuplicateItemName(nextList.items, normalized.value, index)) { + if ( + nextList && + hasDuplicateItemName(nextList.items, normalized.value, index) + ) { return { ok: false, message: 'Item name must be unique within this list.', @@ -704,14 +845,19 @@ save: async (nextName) => { const lists = await window.repository.loadLists(); const nextList = lists.find((x) => x.id === detailListId); - if (!nextList || nextList.builtIn || !Array.isArray(nextList.items)) return; + if (!nextList || nextList.builtIn || !Array.isArray(nextList.items)) + return; const nextItems = [...nextList.items]; const existing = nextItems[index]; - if (typeof existing === 'string') nextItems[index] = nextName; - else if (existing && typeof existing === 'object') { - nextItems[index] = { ...existing, name: nextName }; - } - nextList.items = nextItems; + const renamed = + typeof existing === 'string' + ? nextName + : { ...existing, name: nextName }; + nextItems[index] = renamed; + nextList.items = + getListDisplayOrderMode(nextList) === 'alphabetical' + ? sortListItemsForDisplay({ ...nextList, items: nextItems }) + : nextItems; await window.repository.saveList(nextList); }, rerender: async () => {