@leftoff/cli 0.9.8-beta.9 → 0.9.8

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
@@ -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; }
@@ -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,78 @@ 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
+ .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; }
2167
+ [data-theme="light"] .att-chip { background: #f6f7f9; }
2168
+ .att-chip.failed { border-color: color-mix(in srgb, var(--red) 60%, var(--line)); }
2169
+ .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); }
2170
+ .att-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
2171
+ .att-thumb .ic { width: 22px; height: 22px; }
2172
+ .att-thumb-pdf > * { grid-area: 1 / 1; }
2173
+ .att-thumb-pdf img { object-position: 50% 0; background: #fff; }
2174
+ .att-thumb-pdf img:not([src]) { visibility: hidden; }
2175
+ .att-meta { flex: 1 1 auto; min-width: 48px; max-width: 170px; display: flex; flex-direction: column; line-height: 1.25; }
2176
+ .att-name { font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
2177
+ .att-size { font-size: 12px; color: var(--muted); white-space: nowrap; }
2178
+ .att-chip.failed .att-size { color: var(--red); }
2179
+ .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; }
2180
+ .att-btn + .att-btn { margin-left: -14px; }
2181
+ .att-btn:hover { color: var(--text); }
2182
+ .att-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -6px; }
2183
+ .att-retry { font-size: 18px; color: var(--accent); }
2184
+ .att-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: color-mix(in srgb, var(--muted) 18%, transparent); }
2185
+ .att-bar > span { display: block; height: 100%; background: var(--accent); transition: width .15s; }
2186
+ .lv-atts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; justify-content: flex-end; }
2187
+ .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; }
2188
+ .lv-att-img { width: 132px; height: 132px; background: color-mix(in srgb, var(--muted) 12%, transparent); }
2189
+ .lv-att-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
2190
+ .lv-att-img img:not([src]) { visibility: hidden; }
2191
+ .lv-att-file { display: flex; align-items: center; gap: 8px; padding: 4px 12px 4px 4px; max-width: 240px; text-align: left; }
2192
+ .lv-att.gone { opacity: .55; }
2193
+ .lv-att:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
2194
+ .att-full { display: grid; place-items: center; }
2195
+ .att-full img { max-width: 100%; max-height: 72vh; height: auto; border-radius: 8px; }
2196
+ .att-full-actions { display: flex; justify-content: center; margin-top: 12px; }
2197
+ .att-text { white-space: pre-wrap; word-break: break-word; font-size: 13px; max-height: 70vh; overflow: auto; }
2198
+ @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; } }
2199
+ @media (prefers-reduced-motion: reduce) { .att-bar > span, .composer-clip { transition: none; } }
2128
2200
  /* Chat on a live card: straight to the Live box */
2129
2201
  .btn.chat-btn { position: relative; color: var(--green); border-color: color-mix(in srgb, var(--green) 40%, var(--btn-line)); font-weight: 600; }
2130
2202
  .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 +2284,20 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2212
2284
  main { padding-bottom: calc(var(--bar-h) + 40px + env(safe-area-inset-bottom)); }
2213
2285
  .toast { bottom: calc(var(--bar-h) + 14px + env(safe-area-inset-bottom)); }
2214
2286
  }
2287
+ /* Hide the nav on scroll (phones, 0.9.8): body.nav-hidden slides the top row up
2288
+ (its strip under the status bar stays, so nothing scrolls beneath the clock) and
2289
+ the bottom bar down. The top row keeps its place in the flow and main keeps the
2290
+ bar's padding, so nothing reflows. The top row is moved with `top`, not a
2291
+ transform: a transform would become the fixed bar's containing block. */
2292
+ @media (max-width: 699.98px) {
2293
+ .top { transition: top .2s ease; }
2294
+ .top .tabs { transition: transform .2s ease, visibility 0s linear 0s; }
2295
+ body.nav-hidden .top { top: calc(env(safe-area-inset-top) - var(--top-h, 60px)); }
2296
+ body.nav-hidden .top .tabs { transform: translateY(calc(100% + 2px)); visibility: hidden; transition: transform .2s ease, visibility 0s linear .2s; }
2297
+ }
2298
+ @media (max-width: 699.98px) and (prefers-reduced-motion: reduce) {
2299
+ .top, .top .tabs, body.nav-hidden .top .tabs { transition: none; }
2300
+ }
2215
2301
  /* More (phones): the rest of the sections, above the bar */
2216
2302
  .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
2303
  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 +2383,8 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2297
2383
  @media (max-width: 640px) {
2298
2384
  /* a phone: the buttons are a row under the title that wraps, each part of a row sharing its width */
2299
2385
  .pagehead.s-head > .s-actions { flex: 1 1 100%; }
2300
- .s-actions > .btn, .s-actions > .split { flex: 1 1 auto; }
2386
+ .s-actions > .btn, .s-actions > .split { flex: 1 1 calc(50% - 4px); min-width: 0; } /* two equal halves per row */
2387
+ .s-actions > .btn.icon-btn { flex: none; }
2301
2388
  .s-actions .split .split-main { flex: 1 1 auto; }
2302
2389
  .s-actions > .more-wrap { flex: none; }
2303
2390
  }
@@ -2336,6 +2423,9 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2336
2423
  .tabstrip, .openrow, .tabpager { display: none; }
2337
2424
  .tabstrip[hidden], .openrow[hidden], .tabpager[hidden] { display: none !important; }
2338
2425
  .tab-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2426
+ .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; }
2427
+ .strip-tip.on { opacity: 1; visibility: visible; transform: none; transition: opacity .12s, transform .12s; }
2428
+ @media (prefers-reduced-motion: reduce) { .strip-tip, .strip-tip.on { transition: none; transform: none; } }
2339
2429
  .preview .tab-t, .tab-s.preview .tab-t, .ochip.preview .tab-t { font-style: italic; }
2340
2430
  .tab-live, .tab-need { flex: none; width: 8px; height: 8px; border-radius: 50%; position: relative; }
2341
2431
  .tab-live { background: var(--green); animation: live-pulse 1.6s ease-in-out infinite; }
@@ -2365,6 +2455,7 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2365
2455
  .tab-keep .ic { width: 12px; height: 12px; }
2366
2456
  .tab-keep { opacity: 0; }
2367
2457
  .tab-cell:hover .tab-keep, .tab-keep:focus-visible, .tab-cell.on .tab-keep { opacity: 1; }
2458
+ .tab-cell.preview { min-width: 164px; } /* the pin and the ×, with room for the title */
2368
2459
  .tab-cell.dragging { opacity: .5; }
2369
2460
  .tab-cell.drop-before { box-shadow: inset 2px 0 0 var(--accent); }
2370
2461
  .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 +2482,7 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2391
2482
  .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
2483
  .ochip-cell.preview { border-style: dashed; }
2393
2484
  .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; }
2485
+ .ochip-cell .ochip { padding-right: 2px; }
2395
2486
  .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
2487
  .ochip-x .ic { width: 15px; height: 15px; }
2397
2488
  .tabpager { padding: 4px max(8px, env(safe-area-inset-left)) 0; }
@@ -2406,3 +2497,340 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
2406
2497
  .swipe-prev main { animation: lo-page-back .18s ease-out; }
2407
2498
  }
2408
2499
  @media (prefers-reduced-motion: reduce) { .swipe-next main, .swipe-prev main { animation: none !important; } }
2500
+
2501
+ /* 0.9.8: a tapped card shows it's opening at once; the session page's shell
2502
+ (title from the card) stands in while its data loads. */
2503
+ .card[data-href]:active { transform: scale(.985); }
2504
+ .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); }
2505
+ .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; }
2506
+ .s-skel { display: flex; flex-direction: column; gap: 12px; margin-top: 18px; }
2507
+ .s-skel-note { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 14px; }
2508
+ .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; }
2509
+ .skel-line { height: 14px; width: 100%; }
2510
+ .skel-line.short { width: 60%; }
2511
+ .skel-block { height: 160px; }
2512
+ .skel-title { height: 26px; width: 70%; margin: 4px 0; }
2513
+ @keyframes skel { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
2514
+ @media (prefers-reduced-motion: reduce) { .skel-line, .skel-block, .card.opening::after { animation: none; } .card.opening, .card[data-href]:active { transform: none; } }
2515
+ /* 0.9.8: a running bubble whose data is stale says so instead of counting. */
2516
+ .lvs-hint { color: var(--muted); font-style: italic; }
2517
+ .lv-reconnecting .lvs-time, .lv-reconnecting .lvs-sep, .lv-reconnecting .lvs-label { display: none; }
2518
+ .lv-reconnecting .lv-spin { animation-duration: 2.4s; opacity: .5; }
2519
+
2520
+ /* 0.9.8: the image preview (ui/lightbox.js): full screen, dark, the picture fit
2521
+ inside the safe areas; a top bar that fades when left alone; edge arrows on a
2522
+ desktop. Pinch, pan and swipe are ours (touch-action: none) — only here: the
2523
+ page itself keeps the browser's zoom. */
2524
+ .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; }
2525
+ .lightbox[hidden] { display: none; }
2526
+ .lightbox.lb-in { opacity: 1; transition: opacity 180ms ease-out; }
2527
+ .lightbox.lb-out { opacity: 0; transition: opacity 160ms ease-in; }
2528
+ html.lb-open, html.lb-open body { overflow: hidden; }
2529
+ .lb-back { position: absolute; inset: 0; background: rgba(0, 0, 0, .97); }
2530
+ .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; }
2531
+ .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; }
2532
+ .lb-img:not([src]) { visibility: hidden; }
2533
+ .lightbox.lb-zoomed .lb-img { cursor: grab; }
2534
+ .lightbox.lb-zoomed .lb-img:active { cursor: grabbing; }
2535
+ .lightbox.lb-anim .lb-img { transition: transform 220ms cubic-bezier(.2, .8, .2, 1); }
2536
+ .lb-img.lb-loading { filter: blur(12px); }
2537
+ .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; }
2538
+ .lb-spin[hidden] { display: none; }
2539
+ .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; }
2540
+ .lb-err[hidden] { display: none; }
2541
+ .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; }
2542
+ .lb-meta { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
2543
+ .lb-name { font-weight: 600; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
2544
+ .lb-sub { display: flex; gap: 8px; font-size: 12.5px; color: rgba(255, 255, 255, .72); font-variant-numeric: tabular-nums; }
2545
+ .lb-size:empty, .lb-count:empty, .lb-count[hidden] { display: none; }
2546
+ .lb-size:not(:empty) + .lb-count:not(:empty)::before { content: "·"; margin-right: 8px; }
2547
+ .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; }
2548
+ .lb-btn .ic { width: 22px; height: 22px; }
2549
+ .lb-x { width: 44px; padding: 0; }
2550
+ .lb-btn:hover { background: rgba(255, 255, 255, .14); }
2551
+ .lb-btn:focus-visible, .lb-nav:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
2552
+ .lb-dl[aria-disabled="true"] { opacity: .45; cursor: default; }
2553
+ .lb-dl[hidden] { display: none; }
2554
+ .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; }
2555
+ .lb-nav .ic { width: 24px; height: 24px; }
2556
+ .lb-nav:hover { background: rgba(60, 60, 60, .8); }
2557
+ .lb-prev { left: calc(14px + env(safe-area-inset-left)); }
2558
+ .lb-next { right: calc(14px + env(safe-area-inset-right)); }
2559
+ .lightbox.lb-fine .lb-nav:not([hidden]) { display: inline-flex; }
2560
+ .lightbox.lb-idle .lb-bar, .lightbox.lb-idle .lb-nav { opacity: 0; pointer-events: none; }
2561
+ .lightbox.lb-idle .lb-stage { cursor: none; }
2562
+ .lb-live { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
2563
+ @media (max-width: 699.98px) { .lb-dl-label { display: none; } .lb-dl { width: 44px; padding: 0; } }
2564
+ @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; } }
2565
+
2566
+ /* 0.9.8: the PDF preview (ui/pdfview.js): the image preview's family (dark,
2567
+ a top bar with name, size, "page 3 of 12", Download, ×); the pages stacked
2568
+ and scrolled under it, fit to the width. One finger scrolls (the browser's
2569
+ own); two pinch (ours, so the page underneath never zooms). */
2570
+ .pdfview { position: fixed; inset: 0; z-index: 70; color: #fff; background: #121214; outline: none; overscroll-behavior: contain; -webkit-tap-highlight-color: transparent; opacity: 0; }
2571
+ .pdfview[hidden] { display: none; }
2572
+ .pdfview.pv-in { opacity: 1; transition: opacity 160ms ease-out; }
2573
+ .pdfview.pv-out { opacity: 0; transition: opacity 150ms ease-in; }
2574
+ html.pv-open, html.pv-open body { overflow: hidden; }
2575
+ .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); }
2576
+ .pv-scroll:focus-visible { box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .5); }
2577
+ .pv-stack { position: relative; transform-origin: 0 0; will-change: transform; }
2578
+ .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; }
2579
+ .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; }
2580
+ .pv-page.pv-failed::after { display: none; }
2581
+ .pv-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
2582
+ .pdfview.pv-zoomed .pv-scroll { cursor: zoom-out; }
2583
+ .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); }
2584
+ .pv-zoom { display: none; width: 44px; padding: 0; }
2585
+ .pdfview.pv-fine .pv-zoom { display: inline-flex; }
2586
+ .pv-zoom:disabled { opacity: .35; cursor: default; background: transparent; }
2587
+ .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; }
2588
+ .pv-msg[hidden], .pv-spin[hidden], .pv-msg-dl[hidden] { display: none; }
2589
+ .pv-spin { width: 28px; height: 28px; border-color: rgba(255, 255, 255, .25); border-top-color: #fff; }
2590
+ .pv-msg-dl { background: rgba(255, 255, 255, .14); padding: 0 16px; }
2591
+ @media (prefers-reduced-motion: reduce) { .pdfview.pv-in, .pdfview.pv-out { transition: none; } .pv-spin, .pv-page:not(.pv-drawn)::after { animation: none; } }
2592
+ /* a chip in the box opens its preview (its × and ↻ stay their own buttons) */
2593
+ .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; }
2594
+ .att-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
2595
+
2596
+ /* "Leftoff updated · Refresh" (0.9.8, ui/update-bar.js): a pill at the top,
2597
+ above the header and the phone's bars (it doesn't move with nav-hide) and
2598
+ under menus, sheets and the previews. Never covers the bottom nav or the composer. */
2599
+ .updatebar { position: fixed; z-index: 35; left: 50%; top: calc(env(safe-area-inset-top) + 8px); transform: translate(-50%, -12px); opacity: 0;
2600
+ 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;
2601
+ 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);
2602
+ font-size: 14px; line-height: 1.3; transition: opacity .2s ease, transform .2s ease; }
2603
+ .updatebar.in { opacity: 1; transform: translate(-50%, 0); }
2604
+ .updatebar[hidden] { display: none; }
2605
+ .updatebar .ub-icon { display: inline-flex; color: var(--accent); flex: none; }
2606
+ .updatebar .ub-icon svg { width: 16px; height: 16px; }
2607
+ .updatebar .ub-text { flex: 1 1 auto; min-width: 0; font-weight: 600; padding: 0 6px 0 4px; overflow-wrap: anywhere; }
2608
+ .updatebar.confirm .ub-text { font-weight: 500; font-size: 13px; color: var(--text2, var(--text)); }
2609
+ .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; }
2610
+ .updatebar .ub-go:disabled { opacity: .7; cursor: default; }
2611
+ .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; }
2612
+ .updatebar .ub-x svg { width: 18px; height: 18px; }
2613
+ .updatebar .ub-x:hover { color: var(--text); background: var(--bg2); }
2614
+ .updatebar .ub-go:focus-visible, .updatebar .ub-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
2615
+ @media (min-width: 700px) { .updatebar { left: calc(50% + var(--rail-w, 0px) / 2); } }
2616
+ @media (prefers-reduced-motion: reduce) { .updatebar { transition: none; } }
2617
+
2618
+ /* 0.9.8: a non-Live session's Live box offers the Live resume command */
2619
+ .live-box.off .live-resume-row { position: relative; margin-top: 6px; }
2620
+ .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); }
2621
+ .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; }
2622
+ .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; }
2623
+ .live-box.off .live-resume-row .copy-float svg { position: relative; width: 16px; height: 16px; }
2624
+ .live-box.off .live-resume-row .copy-float:hover { color: var(--text); }
2625
+ .live-box.off .live-resume-row .copy-float:hover::before { background: var(--bg2); border-color: var(--line); }
2626
+ .live-box.off .live-resume-row .copy-float:focus-visible::before { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
2627
+ .live-box.off .live-resume-row .copy-float.copied { color: var(--accent); }
2628
+ .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; }
2629
+ @media (hover: hover) { .live-box.off .live-resume-row .copy-float:hover::after { opacity: 1; transform: none; transition-delay: .35s; } }
2630
+ .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; }
2631
+
2632
+ /* 0.9.8: the digest reads as a brief: Yesterday / Today, Start here, a sentence per session, Finished folded */
2633
+ .md p.lede { color: var(--text); font-size: 15px; line-height: 1.5; margin: 8px 0 0; }
2634
+ .md p.lede b { font-weight: 650; }
2635
+ .md p.lede + p.lede { margin-top: 4px; }
2636
+ .md section.start-sec { margin: 16px 0 4px; padding: 10px 14px 4px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg2); }
2637
+ .md section.start-sec h2 { margin: 2px 0 2px; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
2638
+ .md ol.start { list-style: none; margin: 0; padding: 0; counter-reset: sh; }
2639
+ .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); }
2640
+ .md ol.start > li:first-child { border-top: 0; }
2641
+ .md ol.start > li[hidden] { display: none; }
2642
+ .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; }
2643
+ .md .sh-main { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
2644
+ .md .sh-step { color: var(--text); font-weight: 600; line-height: 1.4; }
2645
+ .md .sh-sess { font-size: 12.5px; color: var(--muted); }
2646
+ .md .sh-sess a { color: inherit; text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 2px; }
2647
+ .md .sh-sess a:hover { color: var(--text); }
2648
+ .md .sh-repo { color: var(--faint); white-space: nowrap; }
2649
+ .md .sh-repo::before { content: '· '; }
2650
+ .md .sh-act { flex: none; display: flex; }
2651
+ .md .sh-act .btn { min-height: 44px; min-width: 64px; padding: 0 14px; justify-content: center; font-size: 13px; }
2652
+ .md .sh-act .go-off .why { display: none; }
2653
+ .md ul:has(> li.bi) { padding-left: 0; }
2654
+ .md li.bi { list-style: none; margin: 12px 0; }
2655
+ .md .bi-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 10px; }
2656
+ .md .bi-title { color: var(--text); font-weight: 600; text-decoration: none; padding: 2px 0; }
2657
+ .md .bi-title:hover { text-decoration: underline; text-underline-offset: 2px; }
2658
+ .md .bi-tag { color: var(--faint); font-size: 12px; }
2659
+ .md section.start-sec + .digest-hint, .md p.lede + .digest-hint { margin-top: 14px; }
2660
+ .md section.start-sec ~ #digestSpaces { margin-top: 16px; }
2661
+ .md .bi-say { display: block; color: var(--text2); line-height: 1.45; margin-top: 1px; }
2662
+ .md details.fin { margin: 10px 0 4px; }
2663
+ .md details.fin[hidden] { display: none; }
2664
+ .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; }
2665
+ .md details.fin > summary::-webkit-details-marker { display: none; }
2666
+ .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; }
2667
+ .md details.fin[open] > summary::before { transform: rotate(45deg); }
2668
+ .md details.fin > summary:hover { color: var(--text); }
2669
+ .md details.fin > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
2670
+ .md details.fin > ul { margin-top: -4px; }
2671
+ @media (prefers-reduced-motion: reduce) { .md details.fin > summary::before, .digest-cal .cal-fold .ic { transition: none; } }
2672
+ @media (max-width: 600px) {
2673
+ .md p.lede { font-size: 15px; }
2674
+ .md section.start-sec { padding: 8px 12px 2px; margin-left: -4px; margin-right: -4px; }
2675
+ .md li.bi { margin: 14px 0; }
2676
+ }
2677
+
2678
+ /* 0.9.8: past digests as a month calendar (left column; a compact month above the digest on phones) */
2679
+ .digest-wrap:has(> .digest-cal) { grid-template-columns: 252px minmax(0, 1fr); }
2680
+ .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; }
2681
+ .digest-cal .cal-head { display: flex; align-items: center; justify-content: space-between; gap: 4px; }
2682
+ .digest-cal .cal-month { font-weight: 600; font-size: 14px; color: var(--text); }
2683
+ .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; }
2684
+ .digest-cal .cal-nav:hover:not(:disabled) { background: var(--card2); color: var(--text); }
2685
+ .digest-cal .cal-nav:disabled { opacity: .3; cursor: default; }
2686
+ .digest-cal .cal-nav:focus { outline: none; }
2687
+ .digest-cal .cal-nav:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
2688
+ .digest-cal .cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
2689
+ .digest-cal .cal-wd { text-align: center; font-size: 11px; font-weight: 600; color: var(--faint); padding: 2px 0 4px; }
2690
+ .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); }
2691
+ .digest-cal .cal-day.pad { visibility: hidden; }
2692
+ .digest-cal a.cal-day { color: var(--text); font-weight: 600; text-decoration: none; }
2693
+ .digest-cal a.cal-day:hover { background: var(--card2); }
2694
+ .digest-cal a.cal-day:focus { outline: none; }
2695
+ .digest-cal a.cal-day:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
2696
+ .digest-cal .cal-day .dot { position: absolute; bottom: 4px; left: 50%; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--accent); }
2697
+ .digest-cal .cal-day.today { box-shadow: inset 0 0 0 1.5px var(--accent); }
2698
+ .digest-cal a.cal-day.on { background: var(--accent); color: var(--on-accent); }
2699
+ .digest-cal a.cal-day.on .dot { background: var(--on-accent); }
2700
+ .digest-cal a.cal-day.on.today { box-shadow: inset 0 0 0 2px var(--accent), inset 0 0 0 3.5px var(--card); }
2701
+ .digest-cal .cal-none { text-align: center; font-size: 12.5px; color: var(--muted); padding: 8px 4px 2px; }
2702
+ @media (pointer: coarse) { .digest-cal .cal-day { height: 44px; } }
2703
+ .digest-cal .cal-fold { display: none; }
2704
+ @media (max-width: 900px) {
2705
+ /* folded to the picked day's week until the month is opened */
2706
+ .digest-cal .cal-head > span.cal-month { display: none; }
2707
+ .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; }
2708
+ .digest-cal .cal-fold .ic { width: 16px; height: 16px; color: var(--muted); transition: transform .15s; }
2709
+ .digest-cal .cal-fold[aria-expanded="true"] .ic { transform: rotate(180deg); }
2710
+ .digest-cal .cal-fold:focus { outline: none; }
2711
+ .digest-cal .cal-fold:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
2712
+ .digest-cal .cal-grid:not(.open) > .cal-day:not(.wk) { display: none; }
2713
+ .digest-wrap:has(> .digest-cal) { grid-template-columns: minmax(0, 1fr); }
2714
+ .digest-cal { position: static; width: 100%; max-width: 420px; padding: 2px 6px 6px; box-shadow: none; }
2715
+ .digest-cal .cal-day { height: 44px; font-size: 14px; }
2716
+ .digest-cal .cal-wd { padding: 0 0 2px; }
2717
+ }
2718
+ /* 0.9.8: an Unfinished session: its sentence, with Resume beside it */
2719
+ .md li.bi.unf { display: flex; align-items: center; gap: 12px; }
2720
+ .md li.bi.unf .bi-body { flex: 1 1 auto; min-width: 0; }
2721
+ .md li.bi.unf[hidden] { display: none; }
2722
+
2723
+
2724
+ /* 0.9.8 What it did: the last tools and the folder's changes, folded on the session page */
2725
+ .wid { margin: 18px 0 6px; }
2726
+ .wid-head { display: flex; align-items: center; gap: 4px; }
2727
+ .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; }
2728
+ .wid-toggle h2 { margin: 0; }
2729
+ .wid-chev { flex: none; display: inline-grid; place-items: center; width: 22px; height: 22px; color: var(--muted); }
2730
+ .wid-chev svg { width: 16px; height: 16px; }
2731
+ .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; }
2732
+ .wid-refresh svg { width: 18px; height: 18px; }
2733
+ .wid-refresh:hover { color: var(--text); background: var(--bg2); }
2734
+ .wid-refresh:disabled { opacity: .5; cursor: default; }
2735
+ .wid-sub { display: flex; align-items: baseline; flex-wrap: wrap; gap: 4px 10px; margin: 14px 0 6px; }
2736
+ .wid-sub h3 { margin: 0; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); font-weight: 650; }
2737
+ .wid-meta { font-size: 13px; color: var(--muted); }
2738
+ .wid-list { list-style: none; margin: 0; padding: 0; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); overflow: hidden; }
2739
+ .wid-item + .wid-item { border-top: 1px solid var(--line); }
2740
+ .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; }
2741
+ .wid-row:hover { background: var(--bg2); }
2742
+ .wid-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
2743
+ .wid-label { overflow-wrap: anywhere; }
2744
+ .wid-what { font-size: 12.5px; color: var(--muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
2745
+ .wid-bad { font-size: 12px; font-weight: 650; color: var(--red); }
2746
+ .wid-run { font-size: 12px; font-weight: 650; color: var(--accent); }
2747
+ .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); }
2748
+ .wid-st.st-added, .wid-st.st-untracked { color: var(--green); }
2749
+ .wid-st.st-deleted { color: var(--red); }
2750
+ .wid-path { flex: 1; min-width: 0; font-size: 13px; overflow-wrap: anywhere; }
2751
+ .wid-counts { flex: none; font-size: 12.5px; font-family: var(--mono); white-space: nowrap; }
2752
+ .wid-add, .wid .tk-add { color: var(--green); }
2753
+ .wid-del, .wid .tk-del { color: var(--red); }
2754
+ .wid-n { color: var(--muted); }
2755
+ .wid-out { padding: 0 12px 12px; }
2756
+ .wid-note { margin: 4px 0 0; font-size: 13.5px; color: var(--muted); }
2757
+ .wid-foot { margin: 8px 2px 0; font-size: 12.5px; color: var(--muted); }
2758
+ .wid-pre-wrap { position: relative; }
2759
+ .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); }
2760
+ .wid-pre code { background: none; padding: 0; color: inherit; font-size: inherit; }
2761
+ .wid-more { margin-top: 8px; min-height: 44px; }
2762
+ .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; }
2763
+ .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; }
2764
+ .wid .copy-float svg { position: relative; width: 16px; height: 16px; }
2765
+ .wid .copy-float:hover { color: var(--text); }
2766
+ .wid .copy-float:hover::before { background: var(--bg2); border-color: var(--line); }
2767
+ .wid .copy-float.copied { color: var(--accent); }
2768
+ /* styled tooltips (data-tip), never title= */
2769
+ .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; }
2770
+ .wid-st::after { left: 0; right: auto; }
2771
+ @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; } }
2772
+ .wid .copy-float.copied::after { opacity: 1; transform: none; transition-delay: 0s; }
2773
+ /* the focus ring only for the keyboard */
2774
+ .wid-toggle:focus-visible, .wid-row:focus-visible, .wid-refresh:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
2775
+ .wid .copy-float:focus-visible::before { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
2776
+ .wid .copy-float:focus-visible::after, .wid-refresh:focus-visible::after { opacity: 1; transform: none; transition-delay: 0s; }
2777
+ @media (prefers-reduced-motion: reduce) { .wid .copy-float::after, .wid-refresh::after, .wid-st::after { transition: none; } }
2778
+
2779
+ /* 0.9.8 What it did: a file's changes drawn like GitHub's unified view
2780
+ (ui/diff-view.js). Gutters old | new, a +/− column, then the line; long
2781
+ lines wrap inside the last column, so a wrap starts past the gutters. */
2782
+ .wid-list { overflow: clip; } /* (hidden would stop the file header sticking) */
2783
+ .wid-dir { color: var(--muted); }
2784
+ .wid-base { font-weight: 650; color: var(--text); }
2785
+ .gd-bar { display: inline-flex; gap: 1px; margin-left: 6px; vertical-align: -1px; }
2786
+ .gd-bar i { width: 8px; height: 8px; border-radius: 2px; background: var(--line-strong); }
2787
+ .gd-bar i.gd-ba { background: var(--green); }
2788
+ .gd-bar i.gd-bd { background: var(--red); }
2789
+ .wid-item.open > .wid-file { position: sticky; top: var(--wid-sticky, 56px); z-index: 3; background: var(--card); border-bottom: 1px solid var(--line); }
2790
+ .wid-item.open > .wid-file:hover { background: var(--bg2); }
2791
+ .wid-item.open > .wid-out:has(.gd-wrap) { padding: 0; }
2792
+ .gd-wrap .copy-float { top: 0; right: 0; z-index: 2; }
2793
+ .gd {
2794
+ --gd-add: color-mix(in srgb, var(--green) 13%, transparent);
2795
+ --gd-add-gut: color-mix(in srgb, var(--green) 26%, transparent);
2796
+ --gd-add-word: color-mix(in srgb, var(--green) 40%, transparent);
2797
+ --gd-del: color-mix(in srgb, var(--red) 12%, transparent);
2798
+ --gd-del-gut: color-mix(in srgb, var(--red) 24%, transparent);
2799
+ --gd-del-word: color-mix(in srgb, var(--red) 38%, transparent);
2800
+ --gd-gw: 3.6ch;
2801
+ font-family: var(--mono); font-size: 12px; line-height: 20px; color: var(--text); background: var(--card2);
2802
+ }
2803
+ .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; }
2804
+ .gd-row { display: grid; grid-template-columns: var(--gd-gw) var(--gd-gw) 2ch minmax(0, 1fr); min-width: 0; }
2805
+ .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; }
2806
+ .gd-o { border-left: 0; }
2807
+ .gd-n { border-right: 1px solid var(--line); }
2808
+ .gd-m { text-align: center; color: var(--muted); -webkit-user-select: none; user-select: none; }
2809
+ .gd-c { min-width: 0; padding-right: 10px; white-space: pre-wrap; overflow-wrap: anywhere; word-break: normal; tab-size: 4; }
2810
+ .gd-span { grid-column: 1 / 3; border-right: 1px solid var(--line); text-align: center; padding: 0; }
2811
+ .gd-hunk .gd-c, .gd-gap .gd-c, .gd-note .gd-c { grid-column: 3 / 5; padding-left: 8px; }
2812
+ .gd-add { background: var(--gd-add); }
2813
+ .gd-add .gd-gut { background: var(--gd-add-gut); color: var(--text2); }
2814
+ .gd-add .gd-m { color: var(--green); }
2815
+ .gd-del { background: var(--gd-del); }
2816
+ .gd-del .gd-gut { background: var(--gd-del-gut); color: var(--text2); }
2817
+ .gd-del .gd-m { color: var(--red); }
2818
+ .gd-x { text-decoration: none; border-radius: 3px; padding: 1px 0; color: inherit; }
2819
+ ins.gd-x { background: var(--gd-add-word); }
2820
+ del.gd-x { background: var(--gd-del-word); }
2821
+ .gd-hunk { background: var(--tint-accent); color: var(--muted); }
2822
+ .gd-hunk .gd-gut { background: color-mix(in srgb, var(--accent) 14%, transparent); }
2823
+ .gd-range { color: var(--muted); }
2824
+ .gd-ctx { color: var(--text2); }
2825
+ .gd-gap { background: var(--bg2); color: var(--muted); font-family: inherit; }
2826
+ .gd-gap .gd-gut { color: var(--muted); }
2827
+ .gd-note { color: var(--muted); font-style: italic; }
2828
+ .gd-row:first-child .gd-c { padding-right: 48px; }
2829
+ .gd-doc { border: 1px solid var(--line); border-radius: 8px; overflow: hidden; overflow: clip; }
2830
+ .gd-doc .gd-row:first-child .gd-c { padding-right: 10px; } /* room for the floating copy */
2831
+
2832
+ /* 0.9.8 What it did: a finished tool in Live's "Ran 3 commands" opens its output */
2833
+ .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; }
2834
+ .lv-tools .lv-tool-open::after { content: '›'; position: absolute; right: 8px; top: 0; color: var(--faint); font-size: 14px; }
2835
+ .lv-tools .lv-tool-open:hover { background: var(--bg2); color: var(--text); }
2836
+ .lv-tools .lv-tool-open:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }