@leftoff/cli 0.9.8-beta.9 → 0.9.9-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ui/app.css CHANGED
@@ -525,8 +525,8 @@ h2 .count { color: var(--faint); font-weight: 500; }
525
525
  .need.k-permission .need-actions .btn, .need.k-permission .deny-form .btn { min-height: 44px; }
526
526
  .deny-form { display: flex; gap: 6px; flex-wrap: wrap; }
527
527
  .deny-form[hidden] { display: none; }
528
- .deny-form input, .need .qother, .reply-text { flex: 1 1 220px; min-width: 0; background: var(--field); border: 1px solid var(--line); border-radius: 8px; color: var(--text); padding: 7px 9px; font: inherit; font-size: 13px; }
529
- .deny-form input:focus, .need .qother:focus, .reply-text:focus { outline: 2px solid var(--focus); border-color: var(--accent); }
528
+ .deny-form input, .need .qother { flex: 1 1 220px; min-width: 0; background: var(--field); border: 1px solid var(--line); border-radius: 8px; color: var(--text); padding: 7px 9px; font: inherit; font-size: 13px; }
529
+ .deny-form input:focus, .need .qother:focus { outline: 2px solid var(--focus); border-color: var(--accent); }
530
530
  .need-q { display: grid; gap: 6px; }
531
531
  .need-q .qtext { font-size: 13.5px; font-weight: 500; }
532
532
  .need-q .qhead { display: inline-block; font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-right: 8px; }
@@ -535,8 +535,8 @@ h2 .count { color: var(--faint); font-weight: 500; }
535
535
  .btn.opt small { color: var(--muted); font-size: 11.5px; font-weight: 400; }
536
536
  .btn.opt[aria-pressed="true"] { border-color: var(--accent); background: var(--tint-accent); }
537
537
  .need-question { margin: 0; padding: 6px 10px; border-left: 3px solid var(--yellow); background: var(--subtle); color: var(--text2); font-size: 13.5px; white-space: pre-wrap; }
538
- .reply-row { display: flex; gap: 6px; align-items: flex-end; flex-wrap: wrap; }
539
- .reply-text { resize: vertical; min-height: 38px; }
538
+ /* 0.9.8 the Needs-you Reply box is the Live composer (.composer below) */
539
+ .need .reply-composer { margin-top: 8px; }
540
540
  .need-badge { display: flex; gap: 8px; align-items: baseline; font-size: 12.5px; padding: 6px 9px; border-radius: 8px; background: var(--tint-yellow); min-width: 0; }
541
541
  .need-badge.blocking { background: var(--tint-red); }
542
542
  .need-badge .nb-k { font-weight: 700; color: var(--yellow); flex: none; }
@@ -675,6 +675,14 @@ html { background: var(--bg); }
675
675
  .banner.restore .rs-actions { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
676
676
  .banner.restore .rs-note { color: var(--text2); font-size: 12.5px; flex: 1 1 280px; min-width: 0; }
677
677
  @media (pointer: coarse), (max-width: 600px) { .banner.restore .rs-actions .btn { min-height: 44px; } }
678
+ /* 0.9.8: the folded banner names its sessions; on a phone the sentence wraps and Restore… / ✕ stay 44px */
679
+ .banner.restore .grow { min-width: 0; overflow-wrap: anywhere; }
680
+ @media (pointer: coarse), (max-width: 600px) { .banner.restore > .btn, .banner.restore .rs-head .btn.x { min-height: 44px; } .banner.restore .btn.x { min-width: 44px; justify-content: center; } }
681
+ /* the ✕ buttons' styled tooltips (data-tip), never title= */
682
+ .banner.restore .btn.x[data-tip] { position: relative; }
683
+ .banner.restore .btn.x[data-tip]::after { content: attr(data-tip); position: absolute; top: calc(100% + 4px); right: 0; padding: 4px 8px; border-radius: 7px; background: var(--card2); border: 1px solid var(--line-strong); box-shadow: var(--toast-shadow); color: var(--text2); font-size: 12px; line-height: 1.3; font-weight: 500; white-space: nowrap; opacity: 0; transform: translateY(-3px); transition: opacity .12s, transform .12s; pointer-events: none; z-index: 5; }
684
+ @media (hover: hover) { .banner.restore .btn.x[data-tip]:hover::after { opacity: 1; transform: none; transition-delay: .35s; } }
685
+ .banner.restore .btn.x[data-tip]:focus-visible::after { opacity: 1; transform: none; }
678
686
  .banner .rs-cmds { margin: 8px 0 0; padding: 8px 10px; background: var(--bg2); border: 1px solid var(--line); border-radius: 8px; font: 12px/1.5 var(--mono); white-space: pre-wrap; overflow-wrap: anywhere; color: var(--text2); }
679
687
  .banner.restore .rs-result { margin: 10px 0 0; }
680
688
 
@@ -956,25 +964,15 @@ main img, main video { max-width: 100%; height: auto; }
956
964
  .md code { overflow-wrap: anywhere; word-break: break-word; }
957
965
  .md .where { color: var(--muted); font-family: var(--mono); font-size: 12px; }
958
966
  .md li .sub .k { color: var(--faint); font-weight: 600; font-size: 11.5px; text-transform: uppercase; letter-spacing: .4px; margin-right: 2px; }
959
- .dates a .d-short { display: none; }
960
967
  .rchip .rl { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
961
968
  .tlbar > * { min-width: 0; }
962
969
  .tl-head { flex-wrap: wrap; row-gap: 4px; min-width: 0; }
963
970
  .need-head > * { min-width: 0; }
964
971
  .need-head .need-title { max-width: calc(100% - 20px); } /* stays beside its dot when it wraps */
965
972
  @media (max-width: 900px) {
966
- /* past digests: one compact row that scrolls on its own, like Catch me up's */
967
- .digest-dates { flex-direction: row; gap: 6px; overflow-x: auto; scrollbar-width: none; -webkit-overflow-scrolling: touch; margin: 0 -16px; padding: 0 16px 2px; }
968
- .digest-dates::-webkit-scrollbar { display: none; }
969
- .digest-dates a { flex: none; display: flex; flex-direction: column; gap: 1px; padding: 6px 11px; font-family: inherit; font-size: 13px; line-height: 1.3; border: 1px solid var(--line); background: var(--card); }
970
- .digest-dates a.on { border-color: var(--accent); background: var(--tint-accent); }
971
- .digest-dates a .d-iso { display: none; }
972
- .digest-dates a .d-short { display: inline; }
973
- .digest-dates a .m { margin-left: 0; font-size: 11.5px; }
974
973
  .digest-wrap { gap: 12px; margin-top: 12px; }
975
974
  }
976
975
  @media (max-width: 640px) {
977
- .digest-dates { margin: 0 -14px; padding: 0 14px 2px; }
978
976
  .md { padding: 16px 16px 18px; }
979
977
  .md h1 { font-size: 19px; line-height: 1.3; }
980
978
  .md h2 { font-size: 15.5px; margin: 18px 0 6px; }
@@ -1367,7 +1365,7 @@ body.pairpage { background: var(--bg); color: var(--text); margin: 0; }
1367
1365
  .empty.login .codeform input { font-size: 22px !important; }
1368
1366
  .cmdk-field input, .pairbox input { font-size: 17px !important; }
1369
1367
  .addform input { padding: 5px 10px; }
1370
- .deny-form input, .need .qother, .reply-text { padding: 6px 9px; }
1368
+ .deny-form input, .need .qother { padding: 6px 9px; }
1371
1369
  .card .title input { padding: 2px 6px; }
1372
1370
  .standup-out textarea { line-height: 1.4; }
1373
1371
  }
@@ -1732,6 +1730,8 @@ html.dv-open .lo-menu { z-index: 62; }
1732
1730
  .syncdetails { margin: 0 0 14px; padding: 10px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--card); font-size: 13px; display: flex; flex-direction: column; gap: 8px; }
1733
1731
  .syncitem.red b { color: var(--red); }
1734
1732
  .stale-line { font-size: 12.5px; margin: -6px 0 12px; }
1733
+ .machine-only { font-size: 13px; margin: 12px 0 -4px; color: var(--text); display: flex; flex-wrap: wrap; align-items: center; gap: 0 6px; }
1734
+ .machine-only .linkish { min-height: 44px; font-weight: 600; }
1735
1735
  .chip.machine.stale { border-style: dashed; }
1736
1736
  .rchip .rx { margin-left: 4px; font-size: 11px; opacity: .7; }
1737
1737
  .syncdetails .joinline { margin-top: 4px; }
@@ -2076,6 +2076,7 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2076
2076
  .lv-md pre code { background: none; border: 0; padding: 0; }
2077
2077
  .lv-md a { color: var(--accent); text-decoration: underline; }
2078
2078
  .lv-md blockquote { margin: 6px 0; padding-left: 10px; border-left: 3px solid var(--line); color: var(--muted); }
2079
+ .lv-you .lv-md code, .lv-you .lv-md pre { background: color-mix(in srgb, var(--accent) 8%, var(--card)); border-color: color-mix(in srgb, var(--accent) 25%, var(--line)); }
2079
2080
  .lv-note { margin-top: 6px; font-size: 12px; color: var(--muted); }
2080
2081
  /* the status line under a message: Sent → Received → Working → Replied, with a spinner and the time */
2081
2082
  .lv-status { margin-top: 6px; font-size: 12px; color: var(--muted); }
@@ -2124,7 +2125,90 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2124
2125
  /* 0.9.8: another Mac's session whose Mac is offline */
2125
2126
  .owner-off { display: flex; gap: 10px; align-items: flex-start; margin: 12px 0; padding: 10px 12px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); color: var(--text); font-size: 14px; line-height: 1.45; }
2126
2127
  .owner-off .ic { flex: none; width: 18px; height: 18px; margin-top: 1px; color: var(--muted); }
2127
- .live-row .live-text { min-height: 44px; }
2128
+ /* 0.9.8 the Live composer: one rounded box, a textarea that starts at one line
2129
+ and grows to 8 (then scrolls inside), a round ↑ in the corner. The focus ring
2130
+ is the box's. The button is 44px to hit with a 32px dot inside. */
2131
+ .composer { position: relative; display: flex; align-items: flex-end; gap: 2px; margin-top: 10px; padding: 3px 3px 3px 14px; border: 1px solid var(--line-strong); border-radius: 22px; background: var(--card2); box-shadow: 0 1px 2px rgba(0,0,0,.18); cursor: text; transition: border-color .15s, box-shadow .15s; }
2132
+ [data-theme="light"] .composer { background: #fff; box-shadow: 0 1px 3px rgba(22,26,36,.07), 0 1px 1px rgba(22,26,36,.04); }
2133
+ .composer:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
2134
+ .composer.off { opacity: .6; cursor: default; }
2135
+ .composer .composer-input { flex: 1 1 auto; min-width: 0; display: block; box-sizing: border-box; height: 44px; min-height: 0; max-height: none; margin: 0; padding: 11px 0; border: 0; border-radius: 0; background: transparent; color: var(--text); font: inherit; font-size: 16px; line-height: 22px; resize: none; overflow-y: hidden; outline: none; box-shadow: none; -webkit-appearance: none; appearance: none; scrollbar-width: thin; }
2136
+ .composer .composer-input:focus, .composer .composer-input:focus-visible { outline: none; border: 0; box-shadow: none; }
2137
+ .composer .composer-input::placeholder { color: var(--muted); opacity: 1; }
2138
+ .composer .composer-input:disabled { cursor: not-allowed; }
2139
+ .composer-send { flex: none; position: relative; width: 44px; height: 44px; margin: 0; padding: 0; border: 0; background: transparent; display: grid; place-items: center; cursor: pointer; color: var(--on-accent); -webkit-tap-highlight-color: transparent; }
2140
+ .composer-dot { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; background: var(--accent); color: var(--on-accent); transition: background-color .15s, color .15s, transform .1s; }
2141
+ .composer-dot .ic { width: 18px; height: 18px; }
2142
+ .composer-send:hover:not(:disabled) .composer-dot { background: color-mix(in srgb, var(--accent) 86%, var(--text)); }
2143
+ .composer-send:active:not(:disabled) .composer-dot { transform: scale(.92); }
2144
+ .composer-send:disabled { cursor: default; }
2145
+ .composer-send:disabled .composer-dot { background: color-mix(in srgb, var(--muted) 22%, transparent); color: var(--faint); }
2146
+ .composer-send:focus { outline: none; }
2147
+ .composer-send:focus-visible .composer-dot { outline: 2px solid var(--accent); outline-offset: 2px; }
2148
+ .composer-send.sending .composer-dot { background: var(--accent); color: var(--on-accent); opacity: .55; }
2149
+ .composer-send.sending .composer-dot .ic { animation: composer-up 1s ease-in-out infinite; }
2150
+ @keyframes composer-up { 0%, 100% { transform: translateY(1px); } 50% { transform: translateY(-2px); } }
2151
+ @media (prefers-reduced-motion: reduce) { .composer, .composer-dot { transition: none; } .composer-send.sending .composer-dot .ic { animation: none; } }
2152
+
2153
+ /* 0.9.8 attachments: a paperclip beside ↑, chips above the words inside the box, thumbnails in your bubble */
2154
+ .composer { flex-wrap: wrap; }
2155
+ .composer .att-chips { flex: 0 0 100%; order: -1; display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 8px 2px 0; margin-left: -6px; }
2156
+ .composer .att-chips[hidden] { display: none; }
2157
+ .composer.att-drop { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); background: color-mix(in srgb, var(--accent) 7%, var(--card2)); }
2158
+ .att-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; overflow: hidden; clip: rect(0 0 0 0); }
2159
+ .composer-attach { flex: none; width: 44px; height: 44px; margin: 0; padding: 0; border: 0; background: transparent; display: grid; place-items: center; cursor: pointer; color: var(--muted); -webkit-tap-highlight-color: transparent; }
2160
+ .composer-clip { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; transition: background-color .15s, color .15s; }
2161
+ .composer-clip .ic { width: 19px; height: 19px; }
2162
+ .composer-attach:hover:not(:disabled) .composer-clip { background: color-mix(in srgb, var(--muted) 16%, transparent); color: var(--text); }
2163
+ .composer-attach:focus { outline: none; }
2164
+ .composer-attach:focus-visible .composer-clip { outline: 2px solid var(--accent); outline-offset: 2px; }
2165
+ .composer-attach:disabled { cursor: default; opacity: .5; }
2166
+ /* 0.9.8 styled tooltips (data-tip, never title=) for the composer's 📎 and ↑
2167
+ (Live and the Needs-you Reply box), the Needs-you card's controls and Go ↗.
2168
+ Hover with a mouse, or keyboard focus; display:none otherwise, so a tip
2169
+ never widens a phone page. aria-label carries the words for a screen reader. */
2170
+ :where(.composer-attach[data-tip], .composer-send[data-tip], .need [data-tip], .btn.go[data-tip]) { position: relative; }
2171
+ .composer-attach[data-tip]::after, .composer-send[data-tip]::after, .need [data-tip]::after, .btn.go[data-tip]::after { content: attr(data-tip); display: none; position: absolute; top: calc(100% + 4px); right: 0; width: max-content; max-width: min(260px, 70vw); padding: 4px 8px; border-radius: 7px; background: var(--card2); border: 1px solid var(--line-strong); box-shadow: var(--toast-shadow); color: var(--text2); font-size: 12px; line-height: 1.3; font-weight: 500; font-style: normal; text-align: left; white-space: normal; letter-spacing: normal; pointer-events: none; z-index: 20; }
2172
+ .composer-attach[data-tip]::after, .composer-send[data-tip]::after { top: auto; bottom: calc(100% + 4px); }
2173
+ .composer-attach[data-tip]::after { right: auto; left: 0; }
2174
+ @media (hover: hover) { .composer-attach[data-tip]:hover::after, .composer-send[data-tip]:hover::after, .need [data-tip]:hover::after, .btn.go[data-tip]:hover::after { display: block; animation: tip-in .12s ease-out .35s both; } }
2175
+ .composer-attach[data-tip]:focus-visible::after, .composer-send[data-tip]:focus-visible::after, .need [data-tip]:focus-visible::after, .btn.go[data-tip]:focus-visible::after { display: block; animation: tip-in .12s ease-out both; }
2176
+ @keyframes tip-in { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; transform: none; } }
2177
+ @media (prefers-reduced-motion: reduce) { .composer-attach[data-tip]::after, .composer-send[data-tip]::after, .need [data-tip]::after, .btn.go[data-tip]::after { animation: none !important; } }
2178
+ .att-chip { position: relative; display: flex; align-items: center; gap: 8px; max-width: 100%; min-width: 0; width: auto; flex: 0 1 auto; height: 52px; padding: 4px 0 4px 4px; border: 1px solid var(--line); border-radius: 12px; background: var(--card); overflow: hidden; cursor: default; }
2179
+ [data-theme="light"] .att-chip { background: #f6f7f9; }
2180
+ .att-chip.failed { border-color: color-mix(in srgb, var(--red) 60%, var(--line)); }
2181
+ .att-thumb { flex: none; width: 42px; height: 42px; border-radius: 8px; overflow: hidden; display: grid; place-items: center; background: color-mix(in srgb, var(--muted) 14%, transparent); color: var(--muted); }
2182
+ .att-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
2183
+ .att-thumb .ic { width: 22px; height: 22px; }
2184
+ .att-thumb-pdf > * { grid-area: 1 / 1; }
2185
+ .att-thumb-pdf img { object-position: 50% 0; background: #fff; }
2186
+ .att-thumb-pdf img:not([src]) { visibility: hidden; }
2187
+ .att-meta { flex: 1 1 auto; min-width: 48px; max-width: 170px; display: flex; flex-direction: column; line-height: 1.25; }
2188
+ .att-name { font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
2189
+ .att-size { font-size: 12px; color: var(--muted); white-space: nowrap; }
2190
+ .att-chip.failed .att-size { color: var(--red); }
2191
+ .att-btn { flex: none; width: 44px; height: 44px; margin: 0 -4px 0 -10px; padding: 0; border: 0; background: transparent; color: var(--muted); font-size: 20px; line-height: 1; cursor: pointer; display: grid; place-items: center; border-radius: 50%; -webkit-tap-highlight-color: transparent; }
2192
+ .att-btn + .att-btn { margin-left: -14px; }
2193
+ .att-btn:hover { color: var(--text); }
2194
+ .att-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -6px; }
2195
+ .att-retry { font-size: 18px; color: var(--accent); }
2196
+ .att-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: color-mix(in srgb, var(--muted) 18%, transparent); }
2197
+ .att-bar > span { display: block; height: 100%; background: var(--accent); transition: width .15s; }
2198
+ .lv-atts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; justify-content: flex-end; }
2199
+ .lv-att { padding: 0; border: 1px solid var(--line); border-radius: 12px; background: var(--card); cursor: pointer; overflow: hidden; color: inherit; font: inherit; min-height: 44px; min-width: 44px; }
2200
+ .lv-att-img { width: 132px; height: 132px; background: color-mix(in srgb, var(--muted) 12%, transparent); }
2201
+ .lv-att-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
2202
+ .lv-att-img img:not([src]) { visibility: hidden; }
2203
+ .lv-att-file { display: flex; align-items: center; gap: 8px; padding: 4px 12px 4px 4px; max-width: 240px; text-align: left; }
2204
+ .lv-att.gone { opacity: .55; }
2205
+ .lv-att:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
2206
+ .att-full { display: grid; place-items: center; }
2207
+ .att-full img { max-width: 100%; max-height: 72vh; height: auto; border-radius: 8px; }
2208
+ .att-full-actions { display: flex; justify-content: center; margin-top: 12px; }
2209
+ .att-text { white-space: pre-wrap; word-break: break-word; font-size: 13px; max-height: 70vh; overflow: auto; }
2210
+ @media (max-width: 700px) { .att-chip { gap: 6px; padding-left: 3px; } .att-chip .att-thumb { width: 36px; height: 36px; } .att-chip .att-btn { margin-left: -12px; margin-right: -6px; } .lv-att-img { width: 112px; height: 112px; } }
2211
+ @media (prefers-reduced-motion: reduce) { .att-bar > span, .composer-clip { transition: none; } }
2128
2212
  /* Chat on a live card: straight to the Live box */
2129
2213
  .btn.chat-btn { position: relative; color: var(--green); border-color: color-mix(in srgb, var(--green) 40%, var(--btn-line)); font-weight: 600; }
2130
2214
  .chat-btn .unread-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--accent); position: absolute; top: -3px; right: -3px; box-shadow: 0 0 0 2px var(--card); }
@@ -2212,6 +2296,20 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2212
2296
  main { padding-bottom: calc(var(--bar-h) + 40px + env(safe-area-inset-bottom)); }
2213
2297
  .toast { bottom: calc(var(--bar-h) + 14px + env(safe-area-inset-bottom)); }
2214
2298
  }
2299
+ /* Hide the nav on scroll (phones, 0.9.8): body.nav-hidden slides the top row up
2300
+ (its strip under the status bar stays, so nothing scrolls beneath the clock) and
2301
+ the bottom bar down. The top row keeps its place in the flow and main keeps the
2302
+ bar's padding, so nothing reflows. The top row is moved with `top`, not a
2303
+ transform: a transform would become the fixed bar's containing block. */
2304
+ @media (max-width: 699.98px) {
2305
+ .top { transition: top .2s ease; }
2306
+ .top .tabs { transition: transform .2s ease, visibility 0s linear 0s; }
2307
+ body.nav-hidden .top { top: calc(env(safe-area-inset-top) - var(--top-h, 60px)); }
2308
+ body.nav-hidden .top .tabs { transform: translateY(calc(100% + 2px)); visibility: hidden; transition: transform .2s ease, visibility 0s linear .2s; }
2309
+ }
2310
+ @media (max-width: 699.98px) and (prefers-reduced-motion: reduce) {
2311
+ .top, .top .tabs, body.nav-hidden .top .tabs { transition: none; }
2312
+ }
2215
2313
  /* More (phones): the rest of the sections, above the bar */
2216
2314
  .moremenu { position: fixed; z-index: 45; right: max(8px, env(safe-area-inset-right)); bottom: calc(var(--bar-h) + 8px + env(safe-area-inset-bottom)); width: 230px; max-width: calc(100vw - 16px);
2217
2315
  display: flex; flex-direction: column; padding: 6px; background: var(--card); color: var(--text); border: 1px solid var(--line); border-radius: 14px; box-shadow: 0 16px 40px rgba(15, 20, 35, .18), 0 2px 6px rgba(15, 20, 35, .08); animation: lo-in .12s ease-out; }
@@ -2297,7 +2395,8 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2297
2395
  @media (max-width: 640px) {
2298
2396
  /* a phone: the buttons are a row under the title that wraps, each part of a row sharing its width */
2299
2397
  .pagehead.s-head > .s-actions { flex: 1 1 100%; }
2300
- .s-actions > .btn, .s-actions > .split { flex: 1 1 auto; }
2398
+ .s-actions > .btn, .s-actions > .split { flex: 1 1 calc(50% - 4px); min-width: 0; } /* two equal halves per row */
2399
+ .s-actions > .btn.icon-btn { flex: none; }
2301
2400
  .s-actions .split .split-main { flex: 1 1 auto; }
2302
2401
  .s-actions > .more-wrap { flex: none; }
2303
2402
  }
@@ -2336,6 +2435,9 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2336
2435
  .tabstrip, .openrow, .tabpager { display: none; }
2337
2436
  .tabstrip[hidden], .openrow[hidden], .tabpager[hidden] { display: none !important; }
2338
2437
  .tab-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2438
+ .strip-tip { position: fixed; z-index: 70; left: 0; top: 0; padding: 4px 8px; border-radius: 7px; background: var(--card2); border: 1px solid var(--line-strong); box-shadow: var(--toast-shadow); color: var(--text2); font-size: 12px; line-height: 1.3; font-weight: 500; white-space: nowrap; pointer-events: none; opacity: 0; visibility: hidden; transform: translateY(-3px); transition: opacity .12s, transform .12s, visibility 0s .12s; }
2439
+ .strip-tip.on { opacity: 1; visibility: visible; transform: none; transition: opacity .12s, transform .12s; }
2440
+ @media (prefers-reduced-motion: reduce) { .strip-tip, .strip-tip.on { transition: none; transform: none; } }
2339
2441
  .preview .tab-t, .tab-s.preview .tab-t, .ochip.preview .tab-t { font-style: italic; }
2340
2442
  .tab-live, .tab-need { flex: none; width: 8px; height: 8px; border-radius: 50%; position: relative; }
2341
2443
  .tab-live { background: var(--green); animation: live-pulse 1.6s ease-in-out infinite; }
@@ -2365,6 +2467,7 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2365
2467
  .tab-keep .ic { width: 12px; height: 12px; }
2366
2468
  .tab-keep { opacity: 0; }
2367
2469
  .tab-cell:hover .tab-keep, .tab-keep:focus-visible, .tab-cell.on .tab-keep { opacity: 1; }
2470
+ .tab-cell.preview { min-width: 164px; } /* the pin and the ×, with room for the title */
2368
2471
  .tab-cell.dragging { opacity: .5; }
2369
2472
  .tab-cell.drop-before { box-shadow: inset 2px 0 0 var(--accent); }
2370
2473
  .tab-all { flex: none; width: 44px; min-height: 44px; display: flex; align-items: center; justify-content: center; border: 0; border-left: 1px solid var(--line); background: var(--bg); color: var(--muted); cursor: pointer; }
@@ -2391,7 +2494,7 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2391
2494
  .ochip-cell { flex: none; display: flex; align-items: stretch; max-width: 62vw; border: 1px solid var(--line); border-radius: 22px; background: var(--card); scroll-snap-align: start; }
2392
2495
  .ochip-cell.preview { border-style: dashed; }
2393
2496
  .ochip { display: flex; align-items: center; gap: 7px; min-height: 44px; min-width: 44px; padding: 0 14px; color: var(--text); text-decoration: none; font-size: 15px; max-width: 100%; min-width: 0; }
2394
- .ochip-cell:not(.preview) .ochip { padding-right: 2px; }
2497
+ .ochip-cell .ochip { padding-right: 2px; }
2395
2498
  .ochip-x { flex: none; width: 44px; min-height: 44px; border: 0; background: none; color: var(--muted); display: flex; align-items: center; justify-content: center; padding: 0; border-radius: 22px; }
2396
2499
  .ochip-x .ic { width: 15px; height: 15px; }
2397
2500
  .tabpager { padding: 4px max(8px, env(safe-area-inset-left)) 0; }
@@ -2406,3 +2509,340 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2406
2509
  .swipe-prev main { animation: lo-page-back .18s ease-out; }
2407
2510
  }
2408
2511
  @media (prefers-reduced-motion: reduce) { .swipe-next main, .swipe-prev main { animation: none !important; } }
2512
+
2513
+ /* 0.9.8: a tapped card shows it's opening at once; the session page's shell
2514
+ (title from the card) stands in while its data loads. */
2515
+ .card[data-href]:active { transform: scale(.985); }
2516
+ .card.opening { border-color: color-mix(in srgb, var(--accent) 60%, transparent); box-shadow: 0 0 0 1px color-mix(in srgb, var(--accent) 35%, transparent) inset, var(--card-shadow); transform: scale(.985); }
2517
+ .card.opening::after { content: ''; position: absolute; top: 12px; right: 12px; width: 14px; height: 14px; border-radius: 50%; border: 2px solid color-mix(in srgb, var(--accent) 25%, transparent); border-top-color: var(--accent); animation: spin .8s linear infinite; }
2518
+ .s-skel { display: flex; flex-direction: column; gap: 12px; margin-top: 18px; }
2519
+ .s-skel-note { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 14px; }
2520
+ .skel-line, .skel-block { border-radius: 8px; background: linear-gradient(90deg, var(--line) 0%, color-mix(in srgb, var(--line) 40%, transparent) 50%, var(--line) 100%); background-size: 200% 100%; animation: skel 1.2s ease-in-out infinite; }
2521
+ .skel-line { height: 14px; width: 100%; }
2522
+ .skel-line.short { width: 60%; }
2523
+ .skel-block { height: 160px; }
2524
+ .skel-title { height: 26px; width: 70%; margin: 4px 0; }
2525
+ @keyframes skel { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
2526
+ @media (prefers-reduced-motion: reduce) { .skel-line, .skel-block, .card.opening::after { animation: none; } .card.opening, .card[data-href]:active { transform: none; } }
2527
+ /* 0.9.8: a running bubble whose data is stale says so instead of counting. */
2528
+ .lvs-hint { color: var(--muted); font-style: italic; }
2529
+ .lv-reconnecting .lvs-time, .lv-reconnecting .lvs-sep, .lv-reconnecting .lvs-label { display: none; }
2530
+ .lv-reconnecting .lv-spin { animation-duration: 2.4s; opacity: .5; }
2531
+
2532
+ /* 0.9.8: the image preview (ui/lightbox.js): full screen, dark, the picture fit
2533
+ inside the safe areas; a top bar that fades when left alone; edge arrows on a
2534
+ desktop. Pinch, pan and swipe are ours (touch-action: none) — only here: the
2535
+ page itself keeps the browser's zoom. */
2536
+ .lightbox { position: fixed; inset: 0; z-index: 70; color: #fff; outline: none; touch-action: none; overscroll-behavior: contain; -webkit-user-select: none; user-select: none; -webkit-tap-highlight-color: transparent; opacity: 0; }
2537
+ .lightbox[hidden] { display: none; }
2538
+ .lightbox.lb-in { opacity: 1; transition: opacity 180ms ease-out; }
2539
+ .lightbox.lb-out { opacity: 0; transition: opacity 160ms ease-in; }
2540
+ html.lb-open, html.lb-open body { overflow: hidden; }
2541
+ .lb-back { position: absolute; inset: 0; background: rgba(0, 0, 0, .97); }
2542
+ .lb-stage { position: absolute; inset: 0; overflow: hidden; touch-action: none; padding: env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); cursor: default; }
2543
+ .lb-img { position: absolute; left: 50%; top: 50%; max-width: none; max-height: none; transform-origin: 50% 50%; will-change: transform; -webkit-user-drag: none; user-select: none; cursor: zoom-in; image-rendering: auto; }
2544
+ .lb-img:not([src]) { visibility: hidden; }
2545
+ .lightbox.lb-zoomed .lb-img { cursor: grab; }
2546
+ .lightbox.lb-zoomed .lb-img:active { cursor: grabbing; }
2547
+ .lightbox.lb-anim .lb-img { transition: transform 220ms cubic-bezier(.2, .8, .2, 1); }
2548
+ .lb-img.lb-loading { filter: blur(12px); }
2549
+ .lb-spin { position: absolute; left: 50%; top: 50%; width: 28px; height: 28px; margin: -14px 0 0 -14px; border-color: rgba(255, 255, 255, .25); border-top-color: #fff; }
2550
+ .lb-spin[hidden] { display: none; }
2551
+ .lb-err { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -50%); max-width: 80vw; text-align: center; color: rgba(255, 255, 255, .8); font-size: 15px; }
2552
+ .lb-err[hidden] { display: none; }
2553
+ .lb-bar { position: absolute; left: 0; right: 0; top: 0; display: flex; align-items: center; gap: 4px; padding: calc(6px + env(safe-area-inset-top)) calc(6px + env(safe-area-inset-right)) 18px calc(14px + env(safe-area-inset-left)); background: linear-gradient(to bottom, rgba(0, 0, 0, .62), rgba(0, 0, 0, .28) 70%, transparent); transition: opacity 220ms ease; }
2554
+ .lb-meta { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
2555
+ .lb-name { font-weight: 600; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2556
+ .lb-sub { display: flex; gap: 8px; font-size: 12.5px; color: rgba(255, 255, 255, .72); font-variant-numeric: tabular-nums; }
2557
+ .lb-size:empty, .lb-count:empty, .lb-count[hidden] { display: none; }
2558
+ .lb-size:not(:empty) + .lb-count:not(:empty)::before { content: "·"; margin-right: 8px; }
2559
+ .lb-btn { flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-width: 44px; height: 44px; padding: 0 10px; border: 0; border-radius: 22px; background: transparent; color: #fff; font: inherit; font-size: 14px; text-decoration: none; cursor: pointer; }
2560
+ .lb-btn .ic { width: 22px; height: 22px; }
2561
+ .lb-x { width: 44px; padding: 0; }
2562
+ .lb-btn:hover { background: rgba(255, 255, 255, .14); }
2563
+ .lb-btn:focus-visible, .lb-nav:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
2564
+ .lb-dl[aria-disabled="true"] { opacity: .45; cursor: default; }
2565
+ .lb-dl[hidden] { display: none; }
2566
+ .lb-nav { position: absolute; top: 50%; width: 48px; height: 48px; margin-top: -24px; border: 0; border-radius: 50%; display: none; align-items: center; justify-content: center; background: rgba(30, 30, 30, .62); color: #fff; cursor: pointer; transition: opacity 220ms ease, background 120ms; }
2567
+ .lb-nav .ic { width: 24px; height: 24px; }
2568
+ .lb-nav:hover { background: rgba(60, 60, 60, .8); }
2569
+ .lb-prev { left: calc(14px + env(safe-area-inset-left)); }
2570
+ .lb-next { right: calc(14px + env(safe-area-inset-right)); }
2571
+ .lightbox.lb-fine .lb-nav:not([hidden]) { display: inline-flex; }
2572
+ .lightbox.lb-idle .lb-bar, .lightbox.lb-idle .lb-nav { opacity: 0; pointer-events: none; }
2573
+ .lightbox.lb-idle .lb-stage { cursor: none; }
2574
+ .lb-live { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
2575
+ @media (max-width: 699.98px) { .lb-dl-label { display: none; } .lb-dl { width: 44px; padding: 0; } }
2576
+ @media (prefers-reduced-motion: reduce) { .lightbox.lb-in, .lightbox.lb-out, .lightbox.lb-anim .lb-img, .lb-bar, .lb-nav { transition: none; } .lb-spin { animation: none; } }
2577
+
2578
+ /* 0.9.8: the PDF preview (ui/pdfview.js): the image preview's family (dark,
2579
+ a top bar with name, size, "page 3 of 12", Download, ×); the pages stacked
2580
+ and scrolled under it, fit to the width. One finger scrolls (the browser's
2581
+ own); two pinch (ours, so the page underneath never zooms). */
2582
+ .pdfview { position: fixed; inset: 0; z-index: 70; color: #fff; background: #121214; outline: none; overscroll-behavior: contain; -webkit-tap-highlight-color: transparent; opacity: 0; }
2583
+ .pdfview[hidden] { display: none; }
2584
+ .pdfview.pv-in { opacity: 1; transition: opacity 160ms ease-out; }
2585
+ .pdfview.pv-out { opacity: 0; transition: opacity 150ms ease-in; }
2586
+ html.pv-open, html.pv-open body { overflow: hidden; }
2587
+ .pv-scroll { position: absolute; inset: 0; overflow: auto; -webkit-overflow-scrolling: touch; overscroll-behavior: contain; touch-action: pan-x pan-y; outline: none; padding: 0 env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left); }
2588
+ .pv-scroll:focus-visible { box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .5); }
2589
+ .pv-stack { position: relative; transform-origin: 0 0; will-change: transform; }
2590
+ .pv-page { position: absolute; background: #fff; border-radius: 2px; box-shadow: 0 1px 3px rgba(0, 0, 0, .5), 0 6px 24px rgba(0, 0, 0, .35); overflow: hidden; }
2591
+ .pv-page:not(.pv-drawn)::after { content: ""; position: absolute; left: 50%; top: 50%; width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%; border: 2px solid rgba(0, 0, 0, .12); border-top-color: rgba(0, 0, 0, .45); animation: spin .8s linear infinite; }
2592
+ .pv-page.pv-failed::after { display: none; }
2593
+ .pv-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
2594
+ .pdfview.pv-zoomed .pv-scroll { cursor: zoom-out; }
2595
+ .pv-bar { position: absolute; z-index: 2; left: 0; right: 0; top: 0; display: flex; align-items: center; gap: 2px; padding: calc(6px + env(safe-area-inset-top)) calc(6px + env(safe-area-inset-right)) 6px calc(14px + env(safe-area-inset-left)); background: rgba(10, 10, 12, .82); -webkit-backdrop-filter: blur(12px); backdrop-filter: blur(12px); border-bottom: 1px solid rgba(255, 255, 255, .08); }
2596
+ .pv-zoom { display: none; width: 44px; padding: 0; }
2597
+ .pdfview.pv-fine .pv-zoom { display: inline-flex; }
2598
+ .pv-zoom:disabled { opacity: .35; cursor: default; background: transparent; }
2599
+ .pv-msg { position: absolute; z-index: 1; left: 50%; top: 50%; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; gap: 14px; max-width: 80vw; text-align: center; color: rgba(255, 255, 255, .85); font-size: 15px; }
2600
+ .pv-msg[hidden], .pv-spin[hidden], .pv-msg-dl[hidden] { display: none; }
2601
+ .pv-spin { width: 28px; height: 28px; border-color: rgba(255, 255, 255, .25); border-top-color: #fff; }
2602
+ .pv-msg-dl { background: rgba(255, 255, 255, .14); padding: 0 16px; }
2603
+ @media (prefers-reduced-motion: reduce) { .pdfview.pv-in, .pdfview.pv-out { transition: none; } .pv-spin, .pv-page:not(.pv-drawn)::after { animation: none; } }
2604
+ /* a chip in the box opens its preview (its × and ↻ stay their own buttons) */
2605
+ .att-open { display: flex; align-items: center; gap: inherit; min-width: 0; flex: 1 1 auto; min-height: 44px; padding: 0; margin: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; border-radius: 9px; }
2606
+ .att-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
2607
+
2608
+ /* "Leftoff updated · Refresh" (0.9.8, ui/update-bar.js): a pill at the top,
2609
+ above the header and the phone's bars (it doesn't move with nav-hide) and
2610
+ under menus, sheets and the previews. Never covers the bottom nav or the composer. */
2611
+ .updatebar { position: fixed; z-index: 35; left: 50%; top: calc(env(safe-area-inset-top) + 8px); transform: translate(-50%, -12px); opacity: 0;
2612
+ display: flex; align-items: center; gap: 4px; max-width: min(520px, calc(100vw - 16px - env(safe-area-inset-left) - env(safe-area-inset-right))); width: max-content;
2613
+ padding: 4px 4px 4px 14px; border-radius: 26px; background: var(--card2); color: var(--text); border: 1px solid var(--line-strong); box-shadow: var(--toast-shadow);
2614
+ font-size: 14px; line-height: 1.3; transition: opacity .2s ease, transform .2s ease; }
2615
+ .updatebar.in { opacity: 1; transform: translate(-50%, 0); }
2616
+ .updatebar[hidden] { display: none; }
2617
+ .updatebar .ub-icon { display: inline-flex; color: var(--accent); flex: none; }
2618
+ .updatebar .ub-icon svg { width: 16px; height: 16px; }
2619
+ .updatebar .ub-text { flex: 1 1 auto; min-width: 0; font-weight: 600; padding: 0 6px 0 4px; overflow-wrap: anywhere; }
2620
+ .updatebar.confirm .ub-text { font-weight: 500; font-size: 13px; color: var(--text2, var(--text)); }
2621
+ .updatebar .ub-go { flex: none; min-height: 44px; padding: 0 16px; border-radius: 22px; border: 0; background: var(--accent); color: var(--on-accent); font: inherit; font-weight: 700; cursor: pointer; white-space: nowrap; }
2622
+ .updatebar .ub-go:disabled { opacity: .7; cursor: default; }
2623
+ .updatebar .ub-x { flex: none; display: inline-flex; align-items: center; justify-content: center; width: 44px; height: 44px; border-radius: 22px; border: 0; background: none; color: var(--muted); cursor: pointer; }
2624
+ .updatebar .ub-x svg { width: 18px; height: 18px; }
2625
+ .updatebar .ub-x:hover { color: var(--text); background: var(--bg2); }
2626
+ .updatebar .ub-go:focus-visible, .updatebar .ub-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
2627
+ @media (min-width: 700px) { .updatebar { left: calc(50% + var(--rail-w, 0px) / 2); } }
2628
+ @media (prefers-reduced-motion: reduce) { .updatebar { transition: none; } }
2629
+
2630
+ /* 0.9.8: a non-Live session's Live box offers the Live resume command */
2631
+ .live-box.off .live-resume-row { position: relative; margin-top: 6px; }
2632
+ .live-box.off .live-resume-row code { display: block; min-width: 0; overflow-wrap: anywhere; font-size: 12.5px; line-height: 1.5; padding: 12px 52px 12px 12px; min-height: 44px; box-sizing: border-box; border-radius: 8px; background: var(--card2); border: 1px solid var(--line); }
2633
+ .live-box.off .live-resume-row .copy-float { position: absolute; top: 50%; right: 2px; transform: translateY(-50%); width: 44px; height: 44px; display: grid; place-items: center; padding: 0; border: 0; background: transparent; color: var(--muted); cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; }
2634
+ .live-box.off .live-resume-row .copy-float::before { content: ''; position: absolute; inset: 7px; border-radius: 7px; border: 1px solid transparent; transition: background .12s, border-color .12s; }
2635
+ .live-box.off .live-resume-row .copy-float svg { position: relative; width: 16px; height: 16px; }
2636
+ .live-box.off .live-resume-row .copy-float:hover { color: var(--text); }
2637
+ .live-box.off .live-resume-row .copy-float:hover::before { background: var(--bg2); border-color: var(--line); }
2638
+ .live-box.off .live-resume-row .copy-float:focus-visible::before { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
2639
+ .live-box.off .live-resume-row .copy-float.copied { color: var(--accent); }
2640
+ .live-box.off .live-resume-row .copy-float::after { content: attr(data-tip); position: absolute; bottom: calc(100% - 2px); right: 4px; padding: 4px 8px; border-radius: 7px; background: var(--card2); border: 1px solid var(--line-strong); box-shadow: var(--toast-shadow); color: var(--text2); font-size: 12px; line-height: 1.3; font-weight: 500; white-space: nowrap; opacity: 0; transform: translateY(3px); transition: opacity .12s, transform .12s; pointer-events: none; }
2641
+ @media (hover: hover) { .live-box.off .live-resume-row .copy-float:hover::after { opacity: 1; transform: none; transition-delay: .35s; } }
2642
+ .live-box.off .live-resume-row .copy-float:focus-visible::after, .live-box.off .live-resume-row .copy-float.copied::after { opacity: 1; transform: none; transition-delay: 0s; }
2643
+
2644
+ /* 0.9.8: the digest reads as a brief: Yesterday / Today, Start here, a sentence per session, Finished folded */
2645
+ .md p.lede { color: var(--text); font-size: 15px; line-height: 1.5; margin: 8px 0 0; }
2646
+ .md p.lede b { font-weight: 650; }
2647
+ .md p.lede + p.lede { margin-top: 4px; }
2648
+ .md section.start-sec { margin: 16px 0 4px; padding: 10px 14px 4px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg2); }
2649
+ .md section.start-sec h2 { margin: 2px 0 2px; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
2650
+ .md ol.start { list-style: none; margin: 0; padding: 0; counter-reset: sh; }
2651
+ .md ol.start > li { counter-increment: sh; display: flex; align-items: center; gap: 10px 12px; padding: 9px 0; margin: 0; border-top: 1px solid var(--line); color: var(--text2); }
2652
+ .md ol.start > li:first-child { border-top: 0; }
2653
+ .md ol.start > li[hidden] { display: none; }
2654
+ .md ol.start > li::before { content: counter(sh); flex: none; align-self: flex-start; width: 22px; height: 22px; margin-top: 1px; border-radius: 50%; background: var(--tint-accent); color: var(--accent); font-size: 12px; font-weight: 700; display: grid; place-items: center; }
2655
+ .md .sh-main { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
2656
+ .md .sh-step { color: var(--text); font-weight: 600; line-height: 1.4; }
2657
+ .md .sh-sess { font-size: 12.5px; color: var(--muted); }
2658
+ .md .sh-sess a { color: inherit; text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 2px; }
2659
+ .md .sh-sess a:hover { color: var(--text); }
2660
+ .md .sh-repo { color: var(--faint); white-space: nowrap; }
2661
+ .md .sh-repo::before { content: '· '; }
2662
+ .md .sh-act { flex: none; display: flex; }
2663
+ .md .sh-act .btn { min-height: 44px; min-width: 64px; padding: 0 14px; justify-content: center; font-size: 13px; }
2664
+ .md .sh-act .go-off .why { display: none; }
2665
+ .md ul:has(> li.bi) { padding-left: 0; }
2666
+ .md li.bi { list-style: none; margin: 12px 0; }
2667
+ .md .bi-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 10px; }
2668
+ .md .bi-title { color: var(--text); font-weight: 600; text-decoration: none; padding: 2px 0; }
2669
+ .md .bi-title:hover { text-decoration: underline; text-underline-offset: 2px; }
2670
+ .md .bi-tag { color: var(--faint); font-size: 12px; }
2671
+ .md section.start-sec + .digest-hint, .md p.lede + .digest-hint { margin-top: 14px; }
2672
+ .md section.start-sec ~ #digestSpaces { margin-top: 16px; }
2673
+ .md .bi-say { display: block; color: var(--text2); line-height: 1.45; margin-top: 1px; }
2674
+ .md details.fin { margin: 10px 0 4px; }
2675
+ .md details.fin[hidden] { display: none; }
2676
+ .md details.fin > summary { list-style: none; cursor: pointer; min-height: 44px; display: flex; align-items: center; gap: 8px; font-size: 13px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); border-radius: 8px; }
2677
+ .md details.fin > summary::-webkit-details-marker { display: none; }
2678
+ .md details.fin > summary::before { content: ''; width: 7px; height: 7px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg); transition: transform .15s; margin: 0 2px 0 1px; }
2679
+ .md details.fin[open] > summary::before { transform: rotate(45deg); }
2680
+ .md details.fin > summary:hover { color: var(--text); }
2681
+ .md details.fin > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
2682
+ .md details.fin > ul { margin-top: -4px; }
2683
+ @media (prefers-reduced-motion: reduce) { .md details.fin > summary::before, .digest-cal .cal-fold .ic { transition: none; } }
2684
+ @media (max-width: 600px) {
2685
+ .md p.lede { font-size: 15px; }
2686
+ .md section.start-sec { padding: 8px 12px 2px; margin-left: -4px; margin-right: -4px; }
2687
+ .md li.bi { margin: 14px 0; }
2688
+ }
2689
+
2690
+ /* 0.9.8: past digests as a month calendar (left column; a compact month above the digest on phones) */
2691
+ .digest-wrap:has(> .digest-cal) { grid-template-columns: 252px minmax(0, 1fr); }
2692
+ .digest-cal { align-self: start; position: sticky; top: 64px; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--card-shadow); padding: 6px 8px 8px; }
2693
+ .digest-cal .cal-head { display: flex; align-items: center; justify-content: space-between; gap: 4px; }
2694
+ .digest-cal .cal-month { font-weight: 600; font-size: 14px; color: var(--text); }
2695
+ .digest-cal .cal-nav { flex: none; width: 44px; height: 44px; display: grid; place-items: center; border: 0; padding: 0; background: transparent; color: var(--muted); border-radius: 8px; cursor: pointer; }
2696
+ .digest-cal .cal-nav:hover:not(:disabled) { background: var(--card2); color: var(--text); }
2697
+ .digest-cal .cal-nav:disabled { opacity: .3; cursor: default; }
2698
+ .digest-cal .cal-nav:focus { outline: none; }
2699
+ .digest-cal .cal-nav:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
2700
+ .digest-cal .cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
2701
+ .digest-cal .cal-wd { text-align: center; font-size: 11px; font-weight: 600; color: var(--faint); padding: 2px 0 4px; }
2702
+ .digest-cal .cal-day { position: relative; height: 34px; display: grid; place-items: center; border-radius: 8px; font-size: 13px; font-variant-numeric: tabular-nums; color: var(--faint); }
2703
+ .digest-cal .cal-day.pad { visibility: hidden; }
2704
+ .digest-cal a.cal-day { color: var(--text); font-weight: 600; text-decoration: none; }
2705
+ .digest-cal a.cal-day:hover { background: var(--card2); }
2706
+ .digest-cal a.cal-day:focus { outline: none; }
2707
+ .digest-cal a.cal-day:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
2708
+ .digest-cal .cal-day .dot { position: absolute; bottom: 4px; left: 50%; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--accent); }
2709
+ .digest-cal .cal-day.today { box-shadow: inset 0 0 0 1.5px var(--accent); }
2710
+ .digest-cal a.cal-day.on { background: var(--accent); color: var(--on-accent); }
2711
+ .digest-cal a.cal-day.on .dot { background: var(--on-accent); }
2712
+ .digest-cal a.cal-day.on.today { box-shadow: inset 0 0 0 2px var(--accent), inset 0 0 0 3.5px var(--card); }
2713
+ .digest-cal .cal-none { text-align: center; font-size: 12.5px; color: var(--muted); padding: 8px 4px 2px; }
2714
+ @media (pointer: coarse) { .digest-cal .cal-day { height: 44px; } }
2715
+ .digest-cal .cal-fold { display: none; }
2716
+ @media (max-width: 900px) {
2717
+ /* folded to the picked day's week until the month is opened */
2718
+ .digest-cal .cal-head > span.cal-month { display: none; }
2719
+ .digest-cal .cal-fold { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 12px; border: 0; background: transparent; color: var(--text); font: inherit; font-weight: 600; font-size: 15px; border-radius: 8px; cursor: pointer; }
2720
+ .digest-cal .cal-fold .ic { width: 16px; height: 16px; color: var(--muted); transition: transform .15s; }
2721
+ .digest-cal .cal-fold[aria-expanded="true"] .ic { transform: rotate(180deg); }
2722
+ .digest-cal .cal-fold:focus { outline: none; }
2723
+ .digest-cal .cal-fold:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
2724
+ .digest-cal .cal-grid:not(.open) > .cal-day:not(.wk) { display: none; }
2725
+ .digest-wrap:has(> .digest-cal) { grid-template-columns: minmax(0, 1fr); }
2726
+ .digest-cal { position: static; width: 100%; max-width: 420px; padding: 2px 6px 6px; box-shadow: none; }
2727
+ .digest-cal .cal-day { height: 44px; font-size: 14px; }
2728
+ .digest-cal .cal-wd { padding: 0 0 2px; }
2729
+ }
2730
+ /* 0.9.8: an Unfinished session: its sentence, with Resume beside it */
2731
+ .md li.bi.unf { display: flex; align-items: center; gap: 12px; }
2732
+ .md li.bi.unf .bi-body { flex: 1 1 auto; min-width: 0; }
2733
+ .md li.bi.unf[hidden] { display: none; }
2734
+
2735
+
2736
+ /* 0.9.8 What it did: the last tools and the folder's changes, folded on the session page */
2737
+ .wid { margin: 18px 0 6px; }
2738
+ .wid-head { display: flex; align-items: center; gap: 4px; }
2739
+ .wid-toggle { flex: 1; min-width: 0; display: flex; align-items: center; gap: 6px; min-height: 44px; padding: 0 4px 0 0; border: 0; background: none; color: var(--text); font: inherit; text-align: left; cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; border-radius: 8px; }
2740
+ .wid-toggle h2 { margin: 0; }
2741
+ .wid-chev { flex: none; display: inline-grid; place-items: center; width: 22px; height: 22px; color: var(--muted); }
2742
+ .wid-chev svg { width: 16px; height: 16px; }
2743
+ .wid-refresh { position: relative; flex: none; width: 44px; height: 44px; display: grid; place-items: center; border: 0; border-radius: 22px; background: none; color: var(--muted); cursor: pointer; outline: none; }
2744
+ .wid-refresh svg { width: 18px; height: 18px; }
2745
+ .wid-refresh:hover { color: var(--text); background: var(--bg2); }
2746
+ .wid-refresh:disabled { opacity: .5; cursor: default; }
2747
+ .wid-sub { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; margin: 14px 0 6px; }
2748
+ .wid-sub h3 { margin: 0; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 650; }
2749
+ .wid-meta { font-size: 13px; color: var(--muted); }
2750
+ .wid-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); overflow: hidden; }
2751
+ .wid-item + .wid-item { border-top: 1px solid var(--line); }
2752
+ .wid-row { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 44px; box-sizing: border-box; padding: 8px 12px 8px 8px; border: 0; background: none; color: var(--text); font: inherit; font-size: 14px; text-align: left; cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; }
2753
+ .wid-row:hover { background: var(--bg2); }
2754
+ .wid-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
2755
+ .wid-label { overflow-wrap: anywhere; }
2756
+ .wid-what { font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
2757
+ .wid-bad { font-size: 12px; font-weight: 650; color: var(--red); }
2758
+ .wid-run { font-size: 12px; font-weight: 650; color: var(--accent); }
2759
+ .wid-st { position: relative; flex: none; display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 6px; font-size: 12px; font-weight: 700; font-family: var(--mono); background: var(--bg2); color: var(--muted); }
2760
+ .wid-st.st-added, .wid-st.st-untracked { color: var(--green); }
2761
+ .wid-st.st-deleted { color: var(--red); }
2762
+ .wid-path { flex: 1; min-width: 0; font-size: 13px; overflow-wrap: anywhere; }
2763
+ .wid-counts { flex: none; font-size: 12.5px; font-family: var(--mono); white-space: nowrap; }
2764
+ .wid-add, .wid .tk-add { color: var(--green); }
2765
+ .wid-del, .wid .tk-del { color: var(--red); }
2766
+ .wid-n { color: var(--muted); }
2767
+ .wid-out { padding: 0 12px 12px; }
2768
+ .wid-note { margin: 4px 0 0; font-size: 13.5px; color: var(--muted); }
2769
+ .wid-foot { margin: 8px 2px 0; font-size: 12.5px; color: var(--muted); }
2770
+ .wid-pre-wrap { position: relative; }
2771
+ .wid-pre { margin: 0; max-height: 60vh; overflow: auto; -webkit-overflow-scrolling: touch; padding: 10px 48px 10px 12px; border-radius: 8px; background: var(--card2); border: 1px solid var(--line); font-family: var(--mono); font-size: 12.5px; line-height: 1.5; white-space: pre; color: var(--text); }
2772
+ .wid-pre code { background: none; padding: 0; color: inherit; font-size: inherit; }
2773
+ .wid-more { margin-top: 8px; min-height: 44px; }
2774
+ .wid .copy-float { position: absolute; top: 2px; right: 2px; width: 44px; height: 44px; display: grid; place-items: center; padding: 0; border: 0; background: transparent; color: var(--muted); cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; }
2775
+ .wid .copy-float::before { content: ''; position: absolute; inset: 7px; border-radius: 7px; border: 1px solid transparent; background: var(--card2); transition: background .12s, border-color .12s; }
2776
+ .wid .copy-float svg { position: relative; width: 16px; height: 16px; }
2777
+ .wid .copy-float:hover { color: var(--text); }
2778
+ .wid .copy-float:hover::before { background: var(--bg2); border-color: var(--line); }
2779
+ .wid .copy-float.copied { color: var(--accent); }
2780
+ /* styled tooltips (data-tip), never title= */
2781
+ .wid .copy-float::after, .wid-refresh::after, .wid-st::after { content: attr(data-tip); position: absolute; bottom: calc(100% + 2px); right: 4px; padding: 4px 8px; border-radius: 7px; background: var(--card2); border: 1px solid var(--line-strong); box-shadow: var(--toast-shadow); color: var(--text2); font-size: 12px; line-height: 1.3; font-weight: 500; white-space: nowrap; opacity: 0; transform: translateY(3px); transition: opacity .12s, transform .12s; pointer-events: none; z-index: 5; }
2782
+ .wid-st::after { left: 0; right: auto; }
2783
+ @media (hover: hover) { .wid .copy-float:hover::after, .wid-refresh:hover::after, .wid-row:hover .wid-st::after { opacity: 1; transform: none; transition-delay: .35s; } }
2784
+ .wid .copy-float.copied::after { opacity: 1; transform: none; transition-delay: 0s; }
2785
+ /* the focus ring only for the keyboard */
2786
+ .wid-toggle:focus-visible, .wid-row:focus-visible, .wid-refresh:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
2787
+ .wid .copy-float:focus-visible::before { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
2788
+ .wid .copy-float:focus-visible::after, .wid-refresh:focus-visible::after { opacity: 1; transform: none; transition-delay: 0s; }
2789
+ @media (prefers-reduced-motion: reduce) { .wid .copy-float::after, .wid-refresh::after, .wid-st::after { transition: none; } }
2790
+
2791
+ /* 0.9.8 What it did: a file's changes drawn like GitHub's unified view
2792
+ (ui/diff-view.js). Gutters old | new, a +/− column, then the line; long
2793
+ lines wrap inside the last column, so a wrap starts past the gutters. */
2794
+ .wid-list { overflow: clip; } /* (hidden would stop the file header sticking) */
2795
+ .wid-dir { color: var(--muted); }
2796
+ .wid-base { font-weight: 650; color: var(--text); }
2797
+ .gd-bar { display: inline-flex; gap: 1px; margin-left: 6px; vertical-align: -1px; }
2798
+ .gd-bar i { width: 8px; height: 8px; border-radius: 2px; background: var(--line-strong); }
2799
+ .gd-bar i.gd-ba { background: var(--green); }
2800
+ .gd-bar i.gd-bd { background: var(--red); }
2801
+ .wid-item.open > .wid-file { position: sticky; top: var(--wid-sticky, 56px); z-index: 3; background: var(--card); border-bottom: 1px solid var(--line); }
2802
+ .wid-item.open > .wid-file:hover { background: var(--bg2); }
2803
+ .wid-item.open > .wid-out:has(.gd-wrap) { padding: 0; }
2804
+ .gd-wrap .copy-float { top: 0; right: 0; z-index: 2; }
2805
+ .gd {
2806
+ --gd-add: color-mix(in srgb, var(--green) 13%, transparent);
2807
+ --gd-add-gut: color-mix(in srgb, var(--green) 26%, transparent);
2808
+ --gd-add-word: color-mix(in srgb, var(--green) 40%, transparent);
2809
+ --gd-del: color-mix(in srgb, var(--red) 12%, transparent);
2810
+ --gd-del-gut: color-mix(in srgb, var(--red) 24%, transparent);
2811
+ --gd-del-word: color-mix(in srgb, var(--red) 38%, transparent);
2812
+ --gd-gw: 3.6ch;
2813
+ font-family: var(--mono); font-size: 12px; line-height: 20px; color: var(--text); background: var(--card2);
2814
+ }
2815
+ .gd.gd-w2 { --gd-gw: 3.6ch; } .gd.gd-w3 { --gd-gw: 4.6ch; } .gd.gd-w4 { --gd-gw: 5.6ch; } .gd.gd-w5 { --gd-gw: 6.6ch; } .gd.gd-w6 { --gd-gw: 7.6ch; }
2816
+ .gd-row { display: grid; grid-template-columns: var(--gd-gw) var(--gd-gw) 2ch minmax(0, 1fr); min-width: 0; }
2817
+ .gd-gut { padding: 0 6px 0 0; text-align: right; color: var(--faint); font-size: 11.5px; -webkit-user-select: none; user-select: none; font-variant-numeric: tabular-nums; }
2818
+ .gd-o { border-left: 0; }
2819
+ .gd-n { border-right: 1px solid var(--line); }
2820
+ .gd-m { text-align: center; color: var(--muted); -webkit-user-select: none; user-select: none; }
2821
+ .gd-c { min-width: 0; padding-right: 10px; white-space: pre-wrap; overflow-wrap: anywhere; word-break: normal; tab-size: 4; }
2822
+ .gd-span { grid-column: 1 / 3; border-right: 1px solid var(--line); text-align: center; padding: 0; }
2823
+ .gd-hunk .gd-c, .gd-gap .gd-c, .gd-note .gd-c { grid-column: 3 / 5; padding-left: 8px; }
2824
+ .gd-add { background: var(--gd-add); }
2825
+ .gd-add .gd-gut { background: var(--gd-add-gut); color: var(--text2); }
2826
+ .gd-add .gd-m { color: var(--green); }
2827
+ .gd-del { background: var(--gd-del); }
2828
+ .gd-del .gd-gut { background: var(--gd-del-gut); color: var(--text2); }
2829
+ .gd-del .gd-m { color: var(--red); }
2830
+ .gd-x { text-decoration: none; border-radius: 3px; padding: 1px 0; color: inherit; }
2831
+ ins.gd-x { background: var(--gd-add-word); }
2832
+ del.gd-x { background: var(--gd-del-word); }
2833
+ .gd-hunk { background: var(--tint-accent); color: var(--muted); }
2834
+ .gd-hunk .gd-gut { background: color-mix(in srgb, var(--accent) 14%, transparent); }
2835
+ .gd-range { color: var(--muted); }
2836
+ .gd-ctx { color: var(--text2); }
2837
+ .gd-gap { background: var(--bg2); color: var(--muted); font-family: inherit; }
2838
+ .gd-gap .gd-gut { color: var(--muted); }
2839
+ .gd-note { color: var(--muted); font-style: italic; }
2840
+ .gd-row:first-child .gd-c { padding-right: 48px; }
2841
+ .gd-doc { border: 1px solid var(--line); border-radius: 8px; overflow: hidden; overflow: clip; }
2842
+ .gd-doc .gd-row:first-child .gd-c { padding-right: 10px; } /* room for the floating copy */
2843
+
2844
+ /* 0.9.8 What it did: a finished tool in Live's "Ran 3 commands" opens its output */
2845
+ .lv-tools .lv-tool-open { position: relative; display: block; width: 100%; min-height: 44px; line-height: 44px; margin: 0; padding: 0 24px 0 8px; box-sizing: border-box; border: 0; border-radius: 8px; background: none; color: var(--text2); font-family: var(--mono); font-size: 12px; text-align: left; cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
2846
+ .lv-tools .lv-tool-open::after { content: '›'; position: absolute; right: 8px; top: 0; color: var(--faint); font-size: 14px; }
2847
+ .lv-tools .lv-tool-open:hover { background: var(--bg2); color: var(--text); }
2848
+ .lv-tools .lv-tool-open:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }