@leftoff/cli 0.9.8-beta.2 → 0.9.8-beta.21
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/CHANGELOG.md +43 -2
- package/bin/leftoff.js +423 -392
- package/docs/peer-protocol.md +2 -0
- package/mod/.claude-plugin/plugin.json +1 -1
- package/mod/hooks/core.js +24 -4
- package/mod/hooks/register.js +1 -1
- package/package.json +1 -1
- package/ui/app.css +492 -22
- package/ui/app.js +1200 -93
- package/ui/attach.js +211 -0
- package/ui/composer.js +46 -0
- package/ui/index.html +4 -0
- package/ui/lightbox.js +452 -0
- package/ui/live-status.js +17 -9
- package/ui/live-view.js +229 -12
- package/ui/live-wake.js +96 -0
- package/ui/navhide.js +35 -0
- package/ui/pdfview.js +510 -0
- package/ui/prs.js +10 -5
- package/ui/push.js +140 -0
- package/ui/relay-client.js +70 -5
- package/ui/sw.js +52 -5
- package/ui/tabs.js +216 -0
- package/ui/tour.css +63 -0
- package/ui/tour.js +364 -0
- package/ui/update-bar.js +158 -0
- package/ui/vendor/PDFJS-LICENSE.txt +179 -0
- package/ui/vendor/pdfjs/pdf.min.js +27 -0
- package/ui/vendor/pdfjs/pdf.worker.min.js +27 -0
package/ui/app.css
CHANGED
|
@@ -120,7 +120,7 @@ h2 .count { color: var(--faint); font-weight: 500; }
|
|
|
120
120
|
.card:hover { border-color: var(--line-strong); }
|
|
121
121
|
.card.needs_input { border-color: color-mix(in srgb, var(--red) 45%, transparent); box-shadow: 0 0 0 1px var(--tint-red) inset, var(--card-shadow); }
|
|
122
122
|
.card .row1 { display: flex; align-items: flex-start; gap: 10px; }
|
|
123
|
-
.card .title { font-size: 15px; font-weight: 600; line-height: 1.35; flex: 1; }
|
|
123
|
+
.card .title { font-size: 15px; font-weight: 600; line-height: 1.35; flex: 1; min-width: 0; overflow-wrap: break-word; } /* breaks at the <wbr> after a "/" and at spaces first; inside a word only when one word is wider than the card */
|
|
124
124
|
.card .title a:hover { text-decoration: underline; text-decoration-color: var(--faint); }
|
|
125
125
|
.s-title { display: flex; align-items: center; gap: 6px; min-width: 0; }
|
|
126
126
|
.s-title h1 { min-width: 0; }
|
|
@@ -956,25 +956,15 @@ main img, main video { max-width: 100%; height: auto; }
|
|
|
956
956
|
.md code { overflow-wrap: anywhere; word-break: break-word; }
|
|
957
957
|
.md .where { color: var(--muted); font-family: var(--mono); font-size: 12px; }
|
|
958
958
|
.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
959
|
.rchip .rl { max-width: 22ch; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
|
|
961
960
|
.tlbar > * { min-width: 0; }
|
|
962
961
|
.tl-head { flex-wrap: wrap; row-gap: 4px; min-width: 0; }
|
|
963
962
|
.need-head > * { min-width: 0; }
|
|
964
963
|
.need-head .need-title { max-width: calc(100% - 20px); } /* stays beside its dot when it wraps */
|
|
965
964
|
@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
965
|
.digest-wrap { gap: 12px; margin-top: 12px; }
|
|
975
966
|
}
|
|
976
967
|
@media (max-width: 640px) {
|
|
977
|
-
.digest-dates { margin: 0 -14px; padding: 0 14px 2px; }
|
|
978
968
|
.md { padding: 16px 16px 18px; }
|
|
979
969
|
.md h1 { font-size: 19px; line-height: 1.3; }
|
|
980
970
|
.md h2 { font-size: 15.5px; margin: 18px 0 6px; }
|
|
@@ -2038,6 +2028,13 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
|
|
|
2038
2028
|
|
|
2039
2029
|
/* 0.9.8 Live link: the Live badge, and the session page's message box with its delivery states */
|
|
2040
2030
|
.pill.live-pill { color: var(--green); background: var(--tint-green); font-weight: 600; } /* not .live: that class is the open/closed dot */
|
|
2031
|
+
/* Its dot pulses while Claude is running a turn (a soft ring growing out of it); idle, it stays still. The text doesn't blink. */
|
|
2032
|
+
.pill.live-pill.working::before { animation: live-pulse 1.6s ease-in-out infinite; }
|
|
2033
|
+
@keyframes live-pulse {
|
|
2034
|
+
0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--green) 55%, transparent); }
|
|
2035
|
+
80%, 100% { box-shadow: 0 0 0 5px color-mix(in srgb, var(--green) 0%, transparent); }
|
|
2036
|
+
}
|
|
2037
|
+
@media (prefers-reduced-motion: reduce) { .pill.live-pill.working::before, .s-active::before { animation: none; } }
|
|
2041
2038
|
.live-box { margin: 16px 0 18px; border: 1px solid color-mix(in srgb, var(--green) 35%, var(--line)); background: linear-gradient(180deg, var(--tint-green), transparent 70%), var(--card); border-radius: var(--radius); padding: 12px 14px 14px; }
|
|
2042
2039
|
.live-box.off { border-color: var(--line); background: var(--card); }
|
|
2043
2040
|
.live-box.off p { margin: 4px 0 0; font-size: 13px; line-height: 1.5; }
|
|
@@ -2069,6 +2066,7 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
|
|
|
2069
2066
|
.lv-md pre code { background: none; border: 0; padding: 0; }
|
|
2070
2067
|
.lv-md a { color: var(--accent); text-decoration: underline; }
|
|
2071
2068
|
.lv-md blockquote { margin: 6px 0; padding-left: 10px; border-left: 3px solid var(--line); color: var(--muted); }
|
|
2069
|
+
.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)); }
|
|
2072
2070
|
.lv-note { margin-top: 6px; font-size: 12px; color: var(--muted); }
|
|
2073
2071
|
/* the status line under a message: Sent → Received → Working → Replied, with a spinner and the time */
|
|
2074
2072
|
.lv-status { margin-top: 6px; font-size: 12px; color: var(--muted); }
|
|
@@ -2086,12 +2084,109 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
|
|
|
2086
2084
|
.lvs-time { margin-left: auto; font-variant-numeric: tabular-nums; color: var(--muted); }
|
|
2087
2085
|
.lv-spin { width: 12px; height: 12px; flex: none; border-radius: 50%; border: 2px solid color-mix(in srgb, var(--accent) 25%, transparent); border-top-color: var(--accent); animation: spin .8s linear infinite; }
|
|
2088
2086
|
@media (prefers-reduced-motion: reduce) { .lv-spin { animation: none; border-top-color: color-mix(in srgb, var(--accent) 25%, transparent); background: var(--accent); transform: scale(.6); } }
|
|
2087
|
+
.lv-earlier { list-style: none; display: flex; justify-content: center; margin: 2px 0 10px; }
|
|
2088
|
+
.live-earlier { min-height: 44px; font-size: 13px; }
|
|
2089
|
+
.lv-terminal { width: fit-content; max-width: 88%; margin-left: auto; background: color-mix(in srgb, var(--tint-accent) 50%, var(--card)); border-color: color-mix(in srgb, var(--accent) 18%, var(--line)); }
|
|
2090
|
+
.lv-tick { margin-top: 4px; font-size: 11.5px; color: var(--muted); text-align: right; }
|
|
2091
|
+
.lv-tick.got span { color: var(--accent); letter-spacing: -2px; padding-right: 2px; }
|
|
2092
|
+
.lv-tick.bad { color: var(--red); text-align: left; }
|
|
2093
|
+
.lv-working .lvs-line { margin-top: 0; }
|
|
2094
|
+
.lv-pending .lv-working { margin-top: 4px; }
|
|
2095
|
+
.lvs-sep { color: var(--faint); }
|
|
2096
|
+
.lv-working .lvs-time { margin-left: 0; }
|
|
2097
|
+
.lv-tool { font-size: 12px; line-height: 1.45; color: var(--text2); margin-top: 3px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
|
|
2098
|
+
.lv-tool.done { color: var(--faint); }
|
|
2099
|
+
.lv-tool.now { color: var(--text); }
|
|
2100
|
+
.lv-tools { margin-top: 6px; font-size: 12px; color: var(--muted); }
|
|
2101
|
+
.lv-tools > summary { cursor: pointer; min-height: 32px; display: inline-flex; align-items: center; gap: 4px; list-style: none; }
|
|
2102
|
+
.lv-tools > summary::-webkit-details-marker { display: none; }
|
|
2103
|
+
.lv-tools > summary::before { content: '▸'; font-size: 10px; color: var(--faint); transition: transform .15s; }
|
|
2104
|
+
.lv-tools[open] > summary::before { transform: rotate(90deg); }
|
|
2105
|
+
@media (prefers-reduced-motion: reduce) { .lv-tools > summary::before { transition: none; } }
|
|
2106
|
+
.lv-tools > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px; }
|
|
2107
|
+
.lv-tools[open] > summary { margin-bottom: 2px; }
|
|
2108
|
+
.lv-none { color: var(--muted); font-style: italic; }
|
|
2109
|
+
.lv-pending { width: fit-content; min-width: min(260px, 100%); }
|
|
2089
2110
|
.live-jump { position: absolute; left: 50%; bottom: 10px; transform: translateX(-50%); min-height: 44px; padding: 0 16px; border-radius: 22px; border: 1px solid var(--btn-line); background: var(--card); color: var(--text); font: inherit; font-size: 13px; font-weight: 600; box-shadow: 0 4px 14px rgba(0,0,0,.18); cursor: pointer; z-index: 2; }
|
|
2090
2111
|
.live-jump:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
2091
2112
|
.live-jump-n { font-weight: 500; color: var(--muted); }
|
|
2092
2113
|
.live-empty { margin: 6px 0 10px; font-size: 13px; }
|
|
2093
2114
|
.live-err { color: var(--red); font-size: 13px; }
|
|
2094
|
-
|
|
2115
|
+
/* 0.9.8: another Mac's session whose Mac is offline */
|
|
2116
|
+
.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; }
|
|
2117
|
+
.owner-off .ic { flex: none; width: 18px; height: 18px; margin-top: 1px; color: var(--muted); }
|
|
2118
|
+
/* 0.9.8 the Live composer: one rounded box, a textarea that starts at one line
|
|
2119
|
+
and grows to 8 (then scrolls inside), a round ↑ in the corner. The focus ring
|
|
2120
|
+
is the box's. The button is 44px to hit with a 32px dot inside. */
|
|
2121
|
+
.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; }
|
|
2122
|
+
[data-theme="light"] .composer { background: #fff; box-shadow: 0 1px 3px rgba(22,26,36,.07), 0 1px 1px rgba(22,26,36,.04); }
|
|
2123
|
+
.composer:focus-within { border-color: var(--accent); box-shadow: 0 0 0 3px var(--focus); }
|
|
2124
|
+
.composer.off { opacity: .6; cursor: default; }
|
|
2125
|
+
.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; }
|
|
2126
|
+
.composer .composer-input:focus, .composer .composer-input:focus-visible { outline: none; border: 0; box-shadow: none; }
|
|
2127
|
+
.composer .composer-input::placeholder { color: var(--muted); opacity: 1; }
|
|
2128
|
+
.composer .composer-input:disabled { cursor: not-allowed; }
|
|
2129
|
+
.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; }
|
|
2130
|
+
.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; }
|
|
2131
|
+
.composer-dot .ic { width: 18px; height: 18px; }
|
|
2132
|
+
.composer-send:hover:not(:disabled) .composer-dot { background: color-mix(in srgb, var(--accent) 86%, var(--text)); }
|
|
2133
|
+
.composer-send:active:not(:disabled) .composer-dot { transform: scale(.92); }
|
|
2134
|
+
.composer-send:disabled { cursor: default; }
|
|
2135
|
+
.composer-send:disabled .composer-dot { background: color-mix(in srgb, var(--muted) 22%, transparent); color: var(--faint); }
|
|
2136
|
+
.composer-send:focus { outline: none; }
|
|
2137
|
+
.composer-send:focus-visible .composer-dot { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
2138
|
+
.composer-send.sending .composer-dot { background: var(--accent); color: var(--on-accent); opacity: .55; }
|
|
2139
|
+
.composer-send.sending .composer-dot .ic { animation: composer-up 1s ease-in-out infinite; }
|
|
2140
|
+
@keyframes composer-up { 0%, 100% { transform: translateY(1px); } 50% { transform: translateY(-2px); } }
|
|
2141
|
+
@media (prefers-reduced-motion: reduce) { .composer, .composer-dot { transition: none; } .composer-send.sending .composer-dot .ic { animation: none; } }
|
|
2142
|
+
|
|
2143
|
+
/* 0.9.8 attachments: a paperclip beside ↑, chips above the words inside the box, thumbnails in your bubble */
|
|
2144
|
+
.composer { flex-wrap: wrap; }
|
|
2145
|
+
.composer .att-chips { flex: 0 0 100%; order: -1; display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 8px 2px 0; margin-left: -6px; }
|
|
2146
|
+
.composer .att-chips[hidden] { display: none; }
|
|
2147
|
+
.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)); }
|
|
2148
|
+
.att-input { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; overflow: hidden; clip: rect(0 0 0 0); }
|
|
2149
|
+
.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; }
|
|
2150
|
+
.composer-clip { width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; transition: background-color .15s, color .15s; }
|
|
2151
|
+
.composer-clip .ic { width: 19px; height: 19px; }
|
|
2152
|
+
.composer-attach:hover:not(:disabled) .composer-clip { background: color-mix(in srgb, var(--muted) 16%, transparent); color: var(--text); }
|
|
2153
|
+
.composer-attach:focus { outline: none; }
|
|
2154
|
+
.composer-attach:focus-visible .composer-clip { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
2155
|
+
.composer-attach:disabled { cursor: default; opacity: .5; }
|
|
2156
|
+
.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; }
|
|
2157
|
+
[data-theme="light"] .att-chip { background: #f6f7f9; }
|
|
2158
|
+
.att-chip.failed { border-color: color-mix(in srgb, var(--red) 60%, var(--line)); }
|
|
2159
|
+
.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); }
|
|
2160
|
+
.att-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
2161
|
+
.att-thumb .ic { width: 22px; height: 22px; }
|
|
2162
|
+
.att-thumb-pdf > * { grid-area: 1 / 1; }
|
|
2163
|
+
.att-thumb-pdf img { object-position: 50% 0; background: #fff; }
|
|
2164
|
+
.att-thumb-pdf img:not([src]) { visibility: hidden; }
|
|
2165
|
+
.att-meta { flex: 1 1 auto; min-width: 48px; max-width: 170px; display: flex; flex-direction: column; line-height: 1.25; }
|
|
2166
|
+
.att-name { font-size: 13px; color: var(--text); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
|
|
2167
|
+
.att-size { font-size: 12px; color: var(--muted); white-space: nowrap; }
|
|
2168
|
+
.att-chip.failed .att-size { color: var(--red); }
|
|
2169
|
+
.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; }
|
|
2170
|
+
.att-btn + .att-btn { margin-left: -14px; }
|
|
2171
|
+
.att-btn:hover { color: var(--text); }
|
|
2172
|
+
.att-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: -6px; }
|
|
2173
|
+
.att-retry { font-size: 18px; color: var(--accent); }
|
|
2174
|
+
.att-bar { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; background: color-mix(in srgb, var(--muted) 18%, transparent); }
|
|
2175
|
+
.att-bar > span { display: block; height: 100%; background: var(--accent); transition: width .15s; }
|
|
2176
|
+
.lv-atts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; justify-content: flex-end; }
|
|
2177
|
+
.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; }
|
|
2178
|
+
.lv-att-img { width: 132px; height: 132px; background: color-mix(in srgb, var(--muted) 12%, transparent); }
|
|
2179
|
+
.lv-att-img img { width: 100%; height: 100%; object-fit: cover; display: block; }
|
|
2180
|
+
.lv-att-img img:not([src]) { visibility: hidden; }
|
|
2181
|
+
.lv-att-file { display: flex; align-items: center; gap: 8px; padding: 4px 12px 4px 4px; max-width: 240px; text-align: left; }
|
|
2182
|
+
.lv-att.gone { opacity: .55; }
|
|
2183
|
+
.lv-att:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
2184
|
+
.att-full { display: grid; place-items: center; }
|
|
2185
|
+
.att-full img { max-width: 100%; max-height: 72vh; height: auto; border-radius: 8px; }
|
|
2186
|
+
.att-full-actions { display: flex; justify-content: center; margin-top: 12px; }
|
|
2187
|
+
.att-text { white-space: pre-wrap; word-break: break-word; font-size: 13px; max-height: 70vh; overflow: auto; }
|
|
2188
|
+
@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; } }
|
|
2189
|
+
@media (prefers-reduced-motion: reduce) { .att-bar > span, .composer-clip { transition: none; } }
|
|
2095
2190
|
/* Chat on a live card: straight to the Live box */
|
|
2096
2191
|
.btn.chat-btn { position: relative; color: var(--green); border-color: color-mix(in srgb, var(--green) 40%, var(--btn-line)); font-weight: 600; }
|
|
2097
2192
|
.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); }
|
|
@@ -2101,16 +2196,17 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
|
|
|
2101
2196
|
@media (pointer: coarse), (max-width: 600px) {
|
|
2102
2197
|
.live-row .btn, .restore-ask .btn, .btn.chat-btn { min-height: 44px; min-width: 44px; }
|
|
2103
2198
|
.need-actions .btn, .deny-form .btn { min-height: 44px; } /* Allow / Deny from the phone */
|
|
2199
|
+
.lv-tools > summary { min-height: 44px; }
|
|
2104
2200
|
.live-box { padding: 10px; margin-left: -4px; margin-right: -4px; }
|
|
2105
|
-
.lv-you, .lv-event { max-width: 92%; }
|
|
2201
|
+
.lv-you, .lv-event, .lv-terminal { max-width: 92%; }
|
|
2106
2202
|
.live-log { max-height: 60vh; max-height: 60dvh; }
|
|
2107
2203
|
}
|
|
2108
2204
|
|
|
2109
2205
|
/* ------------------------------------------------------------ the sidebar rail (0.9.8)
|
|
2110
|
-
From
|
|
2206
|
+
From 700px up (0.9.8 tabs: was 820): a narrow rail on the left. The Leftoff mark at the top, then
|
|
2111
2207
|
the sections as an icon over a small label, the current one in a soft pill,
|
|
2112
2208
|
a red count on Needs you; search, What's new, Settings and this Mac's status
|
|
2113
|
-
(the Mac switcher) at the bottom. Under
|
|
2209
|
+
(the Mac switcher) at the bottom; 700–1099px it shows icons only. Under 700px: the mark, search and status in
|
|
2114
2210
|
a slim top row, and a bottom tab bar (Board, Needs you, Lists, PRs, More). */
|
|
2115
2211
|
:root { --rail-w: 84px; --rail-on: color-mix(in srgb, var(--accent) 13%, transparent); --bar-h: 58px; }
|
|
2116
2212
|
.tab-more { display: none; }
|
|
@@ -2119,7 +2215,7 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
|
|
|
2119
2215
|
.moredot[hidden] { display: none; }
|
|
2120
2216
|
.iconbtn .lbl { display: none; }
|
|
2121
2217
|
.tabs a, .tab-more { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
|
|
2122
|
-
@media (min-width:
|
|
2218
|
+
@media (min-width: 700px) {
|
|
2123
2219
|
body { padding-left: calc(var(--rail-w) + env(safe-area-inset-left)); }
|
|
2124
2220
|
.top { position: fixed !important; top: 0; bottom: 0; left: 0; width: calc(var(--rail-w) + env(safe-area-inset-left)); z-index: 20; /* !important: the rail never joins the page flow */
|
|
2125
2221
|
flex-direction: column; flex-wrap: nowrap; align-items: stretch; justify-content: flex-start; gap: 6px; min-height: 0;
|
|
@@ -2147,11 +2243,11 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
|
|
|
2147
2243
|
.newdot, .topdot { top: 8px; right: calc(50% - 15px); box-shadow: 0 0 0 2px var(--bg); }
|
|
2148
2244
|
.set-nav { top: 24px; }
|
|
2149
2245
|
}
|
|
2150
|
-
@media (min-width:
|
|
2246
|
+
@media (min-width: 700px) and (max-height: 640px) {
|
|
2151
2247
|
.tabs a, .topright .searchbtn, .topright .iconbtn, .topright .health { min-height: 46px; padding: 4px 2px; gap: 2px; }
|
|
2152
2248
|
.brand { padding-bottom: 4px; }
|
|
2153
2249
|
}
|
|
2154
|
-
@media (max-width:
|
|
2250
|
+
@media (max-width: 699.98px) {
|
|
2155
2251
|
.top { flex-wrap: nowrap; gap: 8px; min-height: 52px; padding-top: max(6px, env(safe-area-inset-top)); padding-bottom: 6px; background: var(--bg); -webkit-backdrop-filter: none; backdrop-filter: none; }
|
|
2156
2252
|
.brand { order: 1; }
|
|
2157
2253
|
.topright { order: 2; margin-left: auto; gap: 2px; }
|
|
@@ -2178,6 +2274,20 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
|
|
|
2178
2274
|
main { padding-bottom: calc(var(--bar-h) + 40px + env(safe-area-inset-bottom)); }
|
|
2179
2275
|
.toast { bottom: calc(var(--bar-h) + 14px + env(safe-area-inset-bottom)); }
|
|
2180
2276
|
}
|
|
2277
|
+
/* Hide the nav on scroll (phones, 0.9.8): body.nav-hidden slides the top row up
|
|
2278
|
+
(its strip under the status bar stays, so nothing scrolls beneath the clock) and
|
|
2279
|
+
the bottom bar down. The top row keeps its place in the flow and main keeps the
|
|
2280
|
+
bar's padding, so nothing reflows. The top row is moved with `top`, not a
|
|
2281
|
+
transform: a transform would become the fixed bar's containing block. */
|
|
2282
|
+
@media (max-width: 699.98px) {
|
|
2283
|
+
.top { transition: top .2s ease; }
|
|
2284
|
+
.top .tabs { transition: transform .2s ease, visibility 0s linear 0s; }
|
|
2285
|
+
body.nav-hidden .top { top: calc(env(safe-area-inset-top) - var(--top-h, 60px)); }
|
|
2286
|
+
body.nav-hidden .top .tabs { transform: translateY(calc(100% + 2px)); visibility: hidden; transition: transform .2s ease, visibility 0s linear .2s; }
|
|
2287
|
+
}
|
|
2288
|
+
@media (max-width: 699.98px) and (prefers-reduced-motion: reduce) {
|
|
2289
|
+
.top, .top .tabs, body.nav-hidden .top .tabs { transition: none; }
|
|
2290
|
+
}
|
|
2181
2291
|
/* More (phones): the rest of the sections, above the bar */
|
|
2182
2292
|
.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);
|
|
2183
2293
|
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; }
|
|
@@ -2190,7 +2300,7 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
|
|
|
2190
2300
|
.moremenu a.on { background: var(--rail-on); }
|
|
2191
2301
|
.moremenu a.on .ic { color: var(--accent); }
|
|
2192
2302
|
.moremenu .newdot, .moremenu .topdot { position: static; margin-left: auto; box-shadow: none; }
|
|
2193
|
-
@media (min-width:
|
|
2303
|
+
@media (min-width: 700px) { .moremenu { display: none !important; } }
|
|
2194
2304
|
/* Quick look on Needs you (0.9.8) */
|
|
2195
2305
|
.quicklook { position: fixed; z-index: 45; width: 360px; max-width: calc(100vw - 16px); max-height: calc(100vh - 16px); overflow-y: auto; overscroll-behavior: contain;
|
|
2196
2306
|
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); padding: 12px 12px 8px; font-size: 13.5px; animation: lo-in .12s ease-out; }
|
|
@@ -2220,8 +2330,8 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
|
|
|
2220
2330
|
.ql-foot { display: flex; align-items: center; justify-content: flex-end; gap: 6px; min-height: 44px; padding: 0 6px; margin-top: 2px; color: var(--accent); font-weight: 600; text-decoration: none; border-radius: 8px; }
|
|
2221
2331
|
.ql-foot:hover { text-decoration: underline; }
|
|
2222
2332
|
.ql-foot:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
2223
|
-
@media (pointer: coarse), (max-width:
|
|
2224
|
-
@media (max-width:
|
|
2333
|
+
@media (pointer: coarse), (max-width: 699.98px) { .ql-actions .btn { min-height: 44px; min-width: 64px; } .ql-main { min-height: 44px; justify-content: center; } }
|
|
2334
|
+
@media (max-width: 699.98px) { .quicklook { left: max(8px, env(safe-area-inset-left)); right: max(8px, env(safe-area-inset-right)); width: auto; max-width: none; bottom: calc(var(--bar-h) + 8px + env(safe-area-inset-bottom)); max-height: calc(100vh - var(--bar-h) - 80px); } }
|
|
2225
2335
|
@media (prefers-reduced-motion: reduce) { .quicklook, .moremenu { animation: none; } }
|
|
2226
2336
|
|
|
2227
2337
|
/* Pull to refresh (phones, 0.9.8): the spinner comes down from under the top row */
|
|
@@ -2233,6 +2343,366 @@ mark.tx, .co-snip mark, .tx-snip mark, .tx-msg-text mark { background: var(--tx-
|
|
|
2233
2343
|
.ptr-ring svg { width: 19px; height: 19px; }
|
|
2234
2344
|
.ptr.armed { color: var(--accent); }
|
|
2235
2345
|
.ptr.busy .ptr-ring { animation: spin .8s linear infinite; }
|
|
2236
|
-
@media (pointer: coarse) and (max-width:
|
|
2346
|
+
@media (pointer: coarse) and (max-width: 699.98px) { html, body { overscroll-behavior-y: contain; } }
|
|
2237
2347
|
@media (prefers-reduced-motion: reduce) { .ptr-ring { transform: none; } .ptr.busy .ptr-ring { animation: lo-pulse 1.2s ease-in-out infinite; } }
|
|
2238
2348
|
@keyframes lo-pulse { 50% { opacity: .35; } }
|
|
2349
|
+
|
|
2350
|
+
/* 0.9.8: the session page's header. The title takes the room that's left and
|
|
2351
|
+
breaks at " · " and after "/" (titleHtml's <wbr>), never mid-word unless one
|
|
2352
|
+
word is wider than the page; the buttons are one group that drops under the
|
|
2353
|
+
title as a whole when it doesn't fit beside it. Every button: one line, 44px,
|
|
2354
|
+
an icon and a short label; the primary ones (Checkpoint, Resume) are tinted,
|
|
2355
|
+
not filled, so they don't shout over the rest. */
|
|
2356
|
+
.pagehead.s-head { flex-wrap: wrap; align-items: flex-start; column-gap: 20px; row-gap: 12px; }
|
|
2357
|
+
.pagehead.s-head > .s-head-main { flex: 1 1 28rem; min-width: 0; } /* under ~28rem beside the buttons, the buttons move down instead */
|
|
2358
|
+
.s-head h1 { overflow-wrap: break-word; line-height: 1.3; }
|
|
2359
|
+
.pagehead.s-head > .s-actions { margin-left: 0; flex: 0 1 auto; display: flex; flex-wrap: wrap; align-items: center; gap: 8px; max-width: 100%; }
|
|
2360
|
+
.s-actions .btn { height: 44px; min-height: 44px; padding: 0 14px; gap: 7px; font-size: 13.5px; line-height: 1; white-space: nowrap; flex: none; justify-content: center; }
|
|
2361
|
+
.s-actions .btn .ic { width: 16px; height: 16px; flex: none; margin: 0; }
|
|
2362
|
+
.s-actions .btn.icon-btn { width: 44px; padding: 0; }
|
|
2363
|
+
.s-actions .more-wrap { display: inline-flex; }
|
|
2364
|
+
.s-actions .btn.primary { background: var(--tint-accent); color: var(--accent); border-color: color-mix(in srgb, var(--accent) 45%, var(--btn-line)); }
|
|
2365
|
+
.s-actions .btn.primary:hover { filter: none; background: color-mix(in srgb, var(--accent) 16%, transparent); color: var(--accent); border-color: var(--accent); }
|
|
2366
|
+
.s-actions .btn.primary:active { filter: none; background: color-mix(in srgb, var(--accent) 22%, transparent); }
|
|
2367
|
+
.s-actions .split { flex: none; display: inline-flex; align-items: stretch; height: 44px; }
|
|
2368
|
+
.s-actions .split .btn { height: 44px; }
|
|
2369
|
+
.s-actions .split .btn.split-more { width: 38px; min-width: 38px; padding: 0; margin-left: 0; border-left: 1px solid color-mix(in srgb, var(--accent) 30%, var(--btn-line)); }
|
|
2370
|
+
.s-actions .split .btn.split-main { border-right-width: 0; }
|
|
2371
|
+
.s-actions .split.is-writing .btn:disabled { opacity: .85; border-style: solid; background: var(--tint-accent); color: var(--accent); border-color: color-mix(in srgb, var(--accent) 35%, var(--btn-line)); }
|
|
2372
|
+
.s-actions .split.is-writing .spin { border-color: color-mix(in srgb, var(--accent) 30%, transparent); border-top-color: var(--accent); }
|
|
2373
|
+
@media (max-width: 640px) {
|
|
2374
|
+
/* a phone: the buttons are a row under the title that wraps, each part of a row sharing its width */
|
|
2375
|
+
.pagehead.s-head > .s-actions { flex: 1 1 100%; }
|
|
2376
|
+
.s-actions > .btn, .s-actions > .split { flex: 1 1 calc(50% - 4px); min-width: 0; } /* two equal halves per row */
|
|
2377
|
+
.s-actions > .btn.icon-btn { flex: none; }
|
|
2378
|
+
.s-actions .split .split-main { flex: 1 1 auto; }
|
|
2379
|
+
.s-actions > .more-wrap { flex: none; }
|
|
2380
|
+
}
|
|
2381
|
+
|
|
2382
|
+
/* 0.9.8: a card's row (Go, Chat, copy, ⋯) and Catch me up's row: one line each,
|
|
2383
|
+
all the same height (44px on touch). */
|
|
2384
|
+
.card > .actions-row > .btn, .card > .actions-row > .go-off > .btn, .cu-s .actions-row > .btn { white-space: nowrap; height: 30px; min-height: 30px; padding-top: 0; padding-bottom: 0; line-height: 28px; }
|
|
2385
|
+
.card > .actions-row > .btn.icon-btn { width: 32px; line-height: 1; }
|
|
2386
|
+
.card > .actions-row > .btn.chat-btn { min-width: 0; display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; padding-top: 0; padding-bottom: 0; overflow: visible; }
|
|
2387
|
+
.cu-s .actions-row > .btn { display: inline-flex; align-items: center; }
|
|
2388
|
+
@media (pointer: coarse), (max-width: 600px) {
|
|
2389
|
+
.card > .actions-row > .btn, .card > .actions-row > .go-off > .btn, .cu-s .actions-row > .btn { height: 44px; min-height: 44px; line-height: 42px; }
|
|
2390
|
+
.card > .actions-row > .btn.icon-btn { width: 44px; }
|
|
2391
|
+
.card > .actions-row > .btn:not(.icon-btn) { min-width: 44px; }
|
|
2392
|
+
}
|
|
2393
|
+
|
|
2394
|
+
/* Phone notifications (0.9.8): the one per-device button, in More and Settings → General */
|
|
2395
|
+
.push-slot[hidden] { display: none; }
|
|
2396
|
+
.push-box { display: flex; gap: 10px; align-items: flex-start; }
|
|
2397
|
+
.push-box > .ic { width: 20px; height: 20px; flex: none; margin-top: 2px; color: var(--muted); }
|
|
2398
|
+
.push-main { min-width: 0; flex: 1; }
|
|
2399
|
+
.push-line { margin: 0; font-size: 14px; line-height: 1.4; color: var(--text2); }
|
|
2400
|
+
.push-line strong { color: var(--text); font-weight: 600; }
|
|
2401
|
+
.push-acts { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
|
|
2402
|
+
.push-acts .btn { min-height: 44px; padding: 0 14px; font-size: 14px; white-space: nowrap; justify-content: center; }
|
|
2403
|
+
.push-note { margin: 8px 0 0; font-size: 13px; line-height: 1.4; color: var(--muted); }
|
|
2404
|
+
.push-note.bad { color: var(--red, #c0392b); }
|
|
2405
|
+
.moremenu .push-slot { border-top: 1px solid var(--line); margin-top: 6px; padding: 12px 8px 6px; }
|
|
2406
|
+
.moremenu:has(.push-slot:not([hidden])) { width: 270px; }
|
|
2407
|
+
.form .push-slot { grid-column: 1 / -1; padding: 12px 14px; border: 1px solid var(--line); border-radius: 10px; background: var(--card2, transparent); margin-top: 4px; }
|
|
2408
|
+
|
|
2409
|
+
/* ------------------------------------------------------------ tabs for sessions (0.9.8)
|
|
2410
|
+
By width, never by device. Under 700px: no strip; an Open row on the board
|
|
2411
|
+
and "‹ 2 of 4 ›" on a session page (swipe works too). 700–1099px: the strip,
|
|
2412
|
+
the rail as icons. From 1100px: the full rail and the strip. */
|
|
2413
|
+
.tabstrip, .openrow, .tabpager { display: none; }
|
|
2414
|
+
.tabstrip[hidden], .openrow[hidden], .tabpager[hidden] { display: none !important; }
|
|
2415
|
+
.tab-t { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2416
|
+
.preview .tab-t, .tab-s.preview .tab-t, .ochip.preview .tab-t { font-style: italic; }
|
|
2417
|
+
.tab-live, .tab-need { flex: none; width: 8px; height: 8px; border-radius: 50%; position: relative; }
|
|
2418
|
+
.tab-live { background: var(--green); animation: live-pulse 1.6s ease-in-out infinite; }
|
|
2419
|
+
.tab-need { background: var(--red); }
|
|
2420
|
+
@media (prefers-reduced-motion: reduce) { .tab-live { animation: none; } }
|
|
2421
|
+
@media (min-width: 700px) {
|
|
2422
|
+
.tabstrip { display: flex; position: sticky; top: 0; z-index: 15; align-items: stretch; height: 44px; background: var(--bg); border-bottom: 1px solid var(--line); padding-top: env(safe-area-inset-top); }
|
|
2423
|
+
.tabstrip-in { flex: 1; min-width: 0; display: flex; align-items: stretch; }
|
|
2424
|
+
.tab-scroll { flex: 1; min-width: 0; display: flex; align-items: stretch; overflow-x: auto; overflow-y: hidden; scrollbar-width: none; overscroll-behavior-x: contain; }
|
|
2425
|
+
.tab-scroll::-webkit-scrollbar { display: none; }
|
|
2426
|
+
.tab { display: flex; align-items: center; gap: 7px; min-height: 44px; padding: 0 12px; color: var(--muted); text-decoration: none; font-size: 13px; font-weight: 500; white-space: nowrap; }
|
|
2427
|
+
.tab .ic { width: 16px; height: 16px; flex: none; }
|
|
2428
|
+
.tab:hover { color: var(--text); }
|
|
2429
|
+
.tab:focus-visible, .tab-x:focus-visible, .tab-all:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
2430
|
+
.tab-board { flex: none; border-right: 1px solid var(--line); }
|
|
2431
|
+
.tab-cell { position: relative; flex: 0 1 200px; min-width: 120px; display: flex; align-items: stretch; border-right: 1px solid var(--line); }
|
|
2432
|
+
.tab-s { flex: 1; min-width: 0; padding-right: 0; }
|
|
2433
|
+
.tab.on, .tab-cell.on { color: var(--text); background: var(--card); }
|
|
2434
|
+
.tab-board.on, .tab-cell.on { box-shadow: inset 0 -2px 0 var(--accent); }
|
|
2435
|
+
.tab-x { flex: none; width: 44px; min-height: 44px; display: flex; align-items: center; justify-content: center; border: 0; background: none; color: var(--muted); cursor: pointer; padding: 0; border-radius: 8px; }
|
|
2436
|
+
.tab-x .ic { width: 14px; height: 14px; }
|
|
2437
|
+
.tab-x { position: relative; }
|
|
2438
|
+
.tab-x::before { content: ''; position: absolute; left: 50%; top: 50%; width: 24px; height: 24px; margin: -12px 0 0 -12px; border-radius: 50%; background: transparent; transition: background .12s; }
|
|
2439
|
+
.tab-x .ic { position: relative; }
|
|
2440
|
+
.tab-x:hover { color: var(--text); background: none; }
|
|
2441
|
+
.tab-x:hover::before { background: color-mix(in srgb, var(--text) 9%, transparent); }
|
|
2442
|
+
.tab-keep .ic { width: 12px; height: 12px; }
|
|
2443
|
+
.tab-keep { opacity: 0; }
|
|
2444
|
+
.tab-cell:hover .tab-keep, .tab-keep:focus-visible, .tab-cell.on .tab-keep { opacity: 1; }
|
|
2445
|
+
.tab-cell.dragging { opacity: .5; }
|
|
2446
|
+
.tab-cell.drop-before { box-shadow: inset 2px 0 0 var(--accent); }
|
|
2447
|
+
.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; }
|
|
2448
|
+
.tab-all .ic { width: 18px; height: 18px; }
|
|
2449
|
+
.tab-all:hover, .tab-all[aria-expanded="true"] { color: var(--text); background: var(--bg2); }
|
|
2450
|
+
.tab-all[hidden] { display: none; }
|
|
2451
|
+
}
|
|
2452
|
+
@media (min-width: 700px) and (pointer: coarse) { .tab-keep { opacity: 1; } }
|
|
2453
|
+
/* the rail as icons (700–1099px): the labels stay for screen readers */
|
|
2454
|
+
@media (min-width: 700px) and (max-width: 1099.98px) {
|
|
2455
|
+
:root { --rail-w: 64px; }
|
|
2456
|
+
.tabs a .lbl, .topright .lbl, .topright .sb-lbl, .topright .health .label { position: absolute !important; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; }
|
|
2457
|
+
.tabs a, .topright .searchbtn, .topright .iconbtn, .topright .health { min-height: 48px; padding: 6px 2px; }
|
|
2458
|
+
.navcount { left: calc(50% + 2px); }
|
|
2459
|
+
}
|
|
2460
|
+
/* phones (under 700px): the Open row on the board, ‹ N of M › on a session page */
|
|
2461
|
+
@media (max-width: 699.98px) {
|
|
2462
|
+
body[data-route="board"] .openrow { display: block; }
|
|
2463
|
+
body[data-route="s"] .tabpager { display: block; }
|
|
2464
|
+
.openrow { padding: 8px 0 0; }
|
|
2465
|
+
.openrow-h { display: flex; gap: 8px; align-items: baseline; padding: 0 max(16px, env(safe-area-inset-left)); font-size: 12px; font-weight: 600; letter-spacing: .02em; text-transform: uppercase; color: var(--muted); }
|
|
2466
|
+
.openrow-chips { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; padding: 8px max(16px, env(safe-area-inset-left)) 6px; scroll-snap-type: x proximity; overscroll-behavior-x: contain; }
|
|
2467
|
+
.openrow-chips::-webkit-scrollbar { display: none; }
|
|
2468
|
+
.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; }
|
|
2469
|
+
.ochip-cell.preview { border-style: dashed; }
|
|
2470
|
+
.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; }
|
|
2471
|
+
.ochip-cell:not(.preview) .ochip { padding-right: 2px; }
|
|
2472
|
+
.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; }
|
|
2473
|
+
.ochip-x .ic { width: 15px; height: 15px; }
|
|
2474
|
+
.tabpager { padding: 4px max(8px, env(safe-area-inset-left)) 0; }
|
|
2475
|
+
.pager-in { display: flex; align-items: center; gap: 6px; }
|
|
2476
|
+
.pager-b { flex: none; width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; border-radius: 22px; color: var(--text); text-decoration: none; }
|
|
2477
|
+
.pager-b .ic { width: 22px; height: 22px; }
|
|
2478
|
+
.pager-b.off { opacity: .25; }
|
|
2479
|
+
.pager-b:not(.off):active { background: var(--bg2); }
|
|
2480
|
+
.pager-n { flex: 1; text-align: center; font-size: 14px; color: var(--muted); font-variant-numeric: tabular-nums; }
|
|
2481
|
+
.pager-keep { flex: none; min-height: 44px; }
|
|
2482
|
+
.swipe-next main { animation: lo-page-fwd .18s ease-out; }
|
|
2483
|
+
.swipe-prev main { animation: lo-page-back .18s ease-out; }
|
|
2484
|
+
}
|
|
2485
|
+
@media (prefers-reduced-motion: reduce) { .swipe-next main, .swipe-prev main { animation: none !important; } }
|
|
2486
|
+
|
|
2487
|
+
/* 0.9.8: a tapped card shows it's opening at once; the session page's shell
|
|
2488
|
+
(title from the card) stands in while its data loads. */
|
|
2489
|
+
.card[data-href]:active { transform: scale(.985); }
|
|
2490
|
+
.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); }
|
|
2491
|
+
.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; }
|
|
2492
|
+
.s-skel { display: flex; flex-direction: column; gap: 12px; margin-top: 18px; }
|
|
2493
|
+
.s-skel-note { display: flex; align-items: center; gap: 8px; color: var(--muted); font-size: 14px; }
|
|
2494
|
+
.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; }
|
|
2495
|
+
.skel-line { height: 14px; width: 100%; }
|
|
2496
|
+
.skel-line.short { width: 60%; }
|
|
2497
|
+
.skel-block { height: 160px; }
|
|
2498
|
+
.skel-title { height: 26px; width: 70%; margin: 4px 0; }
|
|
2499
|
+
@keyframes skel { 0% { background-position: 100% 0; } 100% { background-position: -100% 0; } }
|
|
2500
|
+
@media (prefers-reduced-motion: reduce) { .skel-line, .skel-block, .card.opening::after { animation: none; } .card.opening, .card[data-href]:active { transform: none; } }
|
|
2501
|
+
/* 0.9.8: a running bubble whose data is stale says so instead of counting. */
|
|
2502
|
+
.lvs-hint { color: var(--muted); font-style: italic; }
|
|
2503
|
+
.lv-reconnecting .lvs-time, .lv-reconnecting .lvs-sep, .lv-reconnecting .lvs-label { display: none; }
|
|
2504
|
+
.lv-reconnecting .lv-spin { animation-duration: 2.4s; opacity: .5; }
|
|
2505
|
+
|
|
2506
|
+
/* 0.9.8: the image preview (ui/lightbox.js): full screen, dark, the picture fit
|
|
2507
|
+
inside the safe areas; a top bar that fades when left alone; edge arrows on a
|
|
2508
|
+
desktop. Pinch, pan and swipe are ours (touch-action: none) — only here: the
|
|
2509
|
+
page itself keeps the browser's zoom. */
|
|
2510
|
+
.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; }
|
|
2511
|
+
.lightbox[hidden] { display: none; }
|
|
2512
|
+
.lightbox.lb-in { opacity: 1; transition: opacity 180ms ease-out; }
|
|
2513
|
+
.lightbox.lb-out { opacity: 0; transition: opacity 160ms ease-in; }
|
|
2514
|
+
html.lb-open, html.lb-open body { overflow: hidden; }
|
|
2515
|
+
.lb-back { position: absolute; inset: 0; background: rgba(0, 0, 0, .97); }
|
|
2516
|
+
.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; }
|
|
2517
|
+
.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; }
|
|
2518
|
+
.lb-img:not([src]) { visibility: hidden; }
|
|
2519
|
+
.lightbox.lb-zoomed .lb-img { cursor: grab; }
|
|
2520
|
+
.lightbox.lb-zoomed .lb-img:active { cursor: grabbing; }
|
|
2521
|
+
.lightbox.lb-anim .lb-img { transition: transform 220ms cubic-bezier(.2, .8, .2, 1); }
|
|
2522
|
+
.lb-img.lb-loading { filter: blur(12px); }
|
|
2523
|
+
.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; }
|
|
2524
|
+
.lb-spin[hidden] { display: none; }
|
|
2525
|
+
.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; }
|
|
2526
|
+
.lb-err[hidden] { display: none; }
|
|
2527
|
+
.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; }
|
|
2528
|
+
.lb-meta { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; line-height: 1.25; }
|
|
2529
|
+
.lb-name { font-weight: 600; font-size: 15px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
|
2530
|
+
.lb-sub { display: flex; gap: 8px; font-size: 12.5px; color: rgba(255, 255, 255, .72); font-variant-numeric: tabular-nums; }
|
|
2531
|
+
.lb-size:empty, .lb-count:empty, .lb-count[hidden] { display: none; }
|
|
2532
|
+
.lb-size:not(:empty) + .lb-count:not(:empty)::before { content: "·"; margin-right: 8px; }
|
|
2533
|
+
.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; }
|
|
2534
|
+
.lb-btn .ic { width: 22px; height: 22px; }
|
|
2535
|
+
.lb-x { width: 44px; padding: 0; }
|
|
2536
|
+
.lb-btn:hover { background: rgba(255, 255, 255, .14); }
|
|
2537
|
+
.lb-btn:focus-visible, .lb-nav:focus-visible { outline: 2px solid #fff; outline-offset: -2px; }
|
|
2538
|
+
.lb-dl[aria-disabled="true"] { opacity: .45; cursor: default; }
|
|
2539
|
+
.lb-dl[hidden] { display: none; }
|
|
2540
|
+
.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; }
|
|
2541
|
+
.lb-nav .ic { width: 24px; height: 24px; }
|
|
2542
|
+
.lb-nav:hover { background: rgba(60, 60, 60, .8); }
|
|
2543
|
+
.lb-prev { left: calc(14px + env(safe-area-inset-left)); }
|
|
2544
|
+
.lb-next { right: calc(14px + env(safe-area-inset-right)); }
|
|
2545
|
+
.lightbox.lb-fine .lb-nav:not([hidden]) { display: inline-flex; }
|
|
2546
|
+
.lightbox.lb-idle .lb-bar, .lightbox.lb-idle .lb-nav { opacity: 0; pointer-events: none; }
|
|
2547
|
+
.lightbox.lb-idle .lb-stage { cursor: none; }
|
|
2548
|
+
.lb-live { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
|
|
2549
|
+
@media (max-width: 699.98px) { .lb-dl-label { display: none; } .lb-dl { width: 44px; padding: 0; } }
|
|
2550
|
+
@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; } }
|
|
2551
|
+
|
|
2552
|
+
/* 0.9.8: the PDF preview (ui/pdfview.js): the image preview's family (dark,
|
|
2553
|
+
a top bar with name, size, "page 3 of 12", Download, ×); the pages stacked
|
|
2554
|
+
and scrolled under it, fit to the width. One finger scrolls (the browser's
|
|
2555
|
+
own); two pinch (ours, so the page underneath never zooms). */
|
|
2556
|
+
.pdfview { position: fixed; inset: 0; z-index: 70; color: #fff; background: #121214; outline: none; overscroll-behavior: contain; -webkit-tap-highlight-color: transparent; opacity: 0; }
|
|
2557
|
+
.pdfview[hidden] { display: none; }
|
|
2558
|
+
.pdfview.pv-in { opacity: 1; transition: opacity 160ms ease-out; }
|
|
2559
|
+
.pdfview.pv-out { opacity: 0; transition: opacity 150ms ease-in; }
|
|
2560
|
+
html.pv-open, html.pv-open body { overflow: hidden; }
|
|
2561
|
+
.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); }
|
|
2562
|
+
.pv-scroll:focus-visible { box-shadow: inset 0 0 0 2px rgba(255, 255, 255, .5); }
|
|
2563
|
+
.pv-stack { position: relative; transform-origin: 0 0; will-change: transform; }
|
|
2564
|
+
.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; }
|
|
2565
|
+
.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; }
|
|
2566
|
+
.pv-page.pv-failed::after { display: none; }
|
|
2567
|
+
.pv-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
|
|
2568
|
+
.pdfview.pv-zoomed .pv-scroll { cursor: zoom-out; }
|
|
2569
|
+
.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); }
|
|
2570
|
+
.pv-zoom { display: none; width: 44px; padding: 0; }
|
|
2571
|
+
.pdfview.pv-fine .pv-zoom { display: inline-flex; }
|
|
2572
|
+
.pv-zoom:disabled { opacity: .35; cursor: default; background: transparent; }
|
|
2573
|
+
.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; }
|
|
2574
|
+
.pv-msg[hidden], .pv-spin[hidden], .pv-msg-dl[hidden] { display: none; }
|
|
2575
|
+
.pv-spin { width: 28px; height: 28px; border-color: rgba(255, 255, 255, .25); border-top-color: #fff; }
|
|
2576
|
+
.pv-msg-dl { background: rgba(255, 255, 255, .14); padding: 0 16px; }
|
|
2577
|
+
@media (prefers-reduced-motion: reduce) { .pdfview.pv-in, .pdfview.pv-out { transition: none; } .pv-spin, .pv-page:not(.pv-drawn)::after { animation: none; } }
|
|
2578
|
+
/* a chip in the box opens its preview (its × and ↻ stay their own buttons) */
|
|
2579
|
+
.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; }
|
|
2580
|
+
.att-open:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
2581
|
+
|
|
2582
|
+
/* "Leftoff updated · Refresh" (0.9.8, ui/update-bar.js): a pill at the top,
|
|
2583
|
+
above the header and the phone's bars (it doesn't move with nav-hide) and
|
|
2584
|
+
under menus, sheets and the previews. Never covers the bottom nav or the composer. */
|
|
2585
|
+
.updatebar { position: fixed; z-index: 35; left: 50%; top: calc(env(safe-area-inset-top) + 8px); transform: translate(-50%, -12px); opacity: 0;
|
|
2586
|
+
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;
|
|
2587
|
+
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);
|
|
2588
|
+
font-size: 14px; line-height: 1.3; transition: opacity .2s ease, transform .2s ease; }
|
|
2589
|
+
.updatebar.in { opacity: 1; transform: translate(-50%, 0); }
|
|
2590
|
+
.updatebar[hidden] { display: none; }
|
|
2591
|
+
.updatebar .ub-icon { display: inline-flex; color: var(--accent); flex: none; }
|
|
2592
|
+
.updatebar .ub-icon svg { width: 16px; height: 16px; }
|
|
2593
|
+
.updatebar .ub-text { flex: 1 1 auto; min-width: 0; font-weight: 600; padding: 0 6px 0 4px; overflow-wrap: anywhere; }
|
|
2594
|
+
.updatebar.confirm .ub-text { font-weight: 500; font-size: 13px; color: var(--text2, var(--text)); }
|
|
2595
|
+
.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; }
|
|
2596
|
+
.updatebar .ub-go:disabled { opacity: .7; cursor: default; }
|
|
2597
|
+
.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; }
|
|
2598
|
+
.updatebar .ub-x svg { width: 18px; height: 18px; }
|
|
2599
|
+
.updatebar .ub-x:hover { color: var(--text); background: var(--bg2); }
|
|
2600
|
+
.updatebar .ub-go:focus-visible, .updatebar .ub-x:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
2601
|
+
@media (min-width: 700px) { .updatebar { left: calc(50% + var(--rail-w, 0px) / 2); } }
|
|
2602
|
+
@media (prefers-reduced-motion: reduce) { .updatebar { transition: none; } }
|
|
2603
|
+
|
|
2604
|
+
/* 0.9.8: a non-Live session's Live box offers the Live resume command */
|
|
2605
|
+
.live-box.off .live-resume-row { position: relative; margin-top: 6px; }
|
|
2606
|
+
.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); }
|
|
2607
|
+
.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; }
|
|
2608
|
+
.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; }
|
|
2609
|
+
.live-box.off .live-resume-row .copy-float svg { position: relative; width: 16px; height: 16px; }
|
|
2610
|
+
.live-box.off .live-resume-row .copy-float:hover { color: var(--text); }
|
|
2611
|
+
.live-box.off .live-resume-row .copy-float:hover::before { background: var(--bg2); border-color: var(--line); }
|
|
2612
|
+
.live-box.off .live-resume-row .copy-float:focus-visible::before { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
|
|
2613
|
+
.live-box.off .live-resume-row .copy-float.copied { color: var(--accent); }
|
|
2614
|
+
.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; }
|
|
2615
|
+
@media (hover: hover) { .live-box.off .live-resume-row .copy-float:hover::after { opacity: 1; transform: none; transition-delay: .35s; } }
|
|
2616
|
+
.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; }
|
|
2617
|
+
|
|
2618
|
+
/* 0.9.8: the digest reads as a brief: Yesterday / Today, Start here, a sentence per session, Finished folded */
|
|
2619
|
+
.md p.lede { color: var(--text); font-size: 15px; line-height: 1.5; margin: 8px 0 0; }
|
|
2620
|
+
.md p.lede b { font-weight: 650; }
|
|
2621
|
+
.md p.lede + p.lede { margin-top: 4px; }
|
|
2622
|
+
.md section.start-sec { margin: 16px 0 4px; padding: 10px 14px 4px; border: 1px solid var(--line); border-radius: var(--radius); background: var(--bg2); }
|
|
2623
|
+
.md section.start-sec h2 { margin: 2px 0 2px; font-size: 13px; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
|
|
2624
|
+
.md ol.start { list-style: none; margin: 0; padding: 0; counter-reset: sh; }
|
|
2625
|
+
.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); }
|
|
2626
|
+
.md ol.start > li:first-child { border-top: 0; }
|
|
2627
|
+
.md ol.start > li[hidden] { display: none; }
|
|
2628
|
+
.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; }
|
|
2629
|
+
.md .sh-main { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
|
|
2630
|
+
.md .sh-step { color: var(--text); font-weight: 600; line-height: 1.4; }
|
|
2631
|
+
.md .sh-sess { font-size: 12.5px; color: var(--muted); }
|
|
2632
|
+
.md .sh-sess a { color: inherit; text-decoration: underline; text-decoration-color: var(--line); text-underline-offset: 2px; }
|
|
2633
|
+
.md .sh-sess a:hover { color: var(--text); }
|
|
2634
|
+
.md .sh-repo { color: var(--faint); white-space: nowrap; }
|
|
2635
|
+
.md .sh-repo::before { content: '· '; }
|
|
2636
|
+
.md .sh-act { flex: none; display: flex; }
|
|
2637
|
+
.md .sh-act .btn { min-height: 44px; min-width: 64px; padding: 0 14px; justify-content: center; font-size: 13px; }
|
|
2638
|
+
.md .sh-act .go-off .why { display: none; }
|
|
2639
|
+
.md ul:has(> li.bi) { padding-left: 0; }
|
|
2640
|
+
.md li.bi { list-style: none; margin: 12px 0; }
|
|
2641
|
+
.md .bi-head { display: flex; align-items: baseline; flex-wrap: wrap; gap: 2px 10px; }
|
|
2642
|
+
.md .bi-title { color: var(--text); font-weight: 600; text-decoration: none; padding: 2px 0; }
|
|
2643
|
+
.md .bi-title:hover { text-decoration: underline; text-underline-offset: 2px; }
|
|
2644
|
+
.md .bi-tag { color: var(--faint); font-size: 12px; }
|
|
2645
|
+
.md section.start-sec + .digest-hint, .md p.lede + .digest-hint { margin-top: 14px; }
|
|
2646
|
+
.md section.start-sec ~ #digestSpaces { margin-top: 16px; }
|
|
2647
|
+
.md .bi-say { display: block; color: var(--text2); line-height: 1.45; margin-top: 1px; }
|
|
2648
|
+
.md details.fin { margin: 10px 0 4px; }
|
|
2649
|
+
.md details.fin[hidden] { display: none; }
|
|
2650
|
+
.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; }
|
|
2651
|
+
.md details.fin > summary::-webkit-details-marker { display: none; }
|
|
2652
|
+
.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; }
|
|
2653
|
+
.md details.fin[open] > summary::before { transform: rotate(45deg); }
|
|
2654
|
+
.md details.fin > summary:hover { color: var(--text); }
|
|
2655
|
+
.md details.fin > summary:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
|
|
2656
|
+
.md details.fin > ul { margin-top: -4px; }
|
|
2657
|
+
@media (prefers-reduced-motion: reduce) { .md details.fin > summary::before, .digest-cal .cal-fold .ic { transition: none; } }
|
|
2658
|
+
@media (max-width: 600px) {
|
|
2659
|
+
.md p.lede { font-size: 15px; }
|
|
2660
|
+
.md section.start-sec { padding: 8px 12px 2px; margin-left: -4px; margin-right: -4px; }
|
|
2661
|
+
.md li.bi { margin: 14px 0; }
|
|
2662
|
+
}
|
|
2663
|
+
|
|
2664
|
+
/* 0.9.8: past digests as a month calendar (left column; a compact month above the digest on phones) */
|
|
2665
|
+
.digest-wrap:has(> .digest-cal) { grid-template-columns: 252px minmax(0, 1fr); }
|
|
2666
|
+
.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; }
|
|
2667
|
+
.digest-cal .cal-head { display: flex; align-items: center; justify-content: space-between; gap: 4px; }
|
|
2668
|
+
.digest-cal .cal-month { font-weight: 600; font-size: 14px; color: var(--text); }
|
|
2669
|
+
.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; }
|
|
2670
|
+
.digest-cal .cal-nav:hover:not(:disabled) { background: var(--card2); color: var(--text); }
|
|
2671
|
+
.digest-cal .cal-nav:disabled { opacity: .3; cursor: default; }
|
|
2672
|
+
.digest-cal .cal-nav:focus { outline: none; }
|
|
2673
|
+
.digest-cal .cal-nav:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
2674
|
+
.digest-cal .cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
|
|
2675
|
+
.digest-cal .cal-wd { text-align: center; font-size: 11px; font-weight: 600; color: var(--faint); padding: 2px 0 4px; }
|
|
2676
|
+
.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); }
|
|
2677
|
+
.digest-cal .cal-day.pad { visibility: hidden; }
|
|
2678
|
+
.digest-cal a.cal-day { color: var(--text); font-weight: 600; text-decoration: none; }
|
|
2679
|
+
.digest-cal a.cal-day:hover { background: var(--card2); }
|
|
2680
|
+
.digest-cal a.cal-day:focus { outline: none; }
|
|
2681
|
+
.digest-cal a.cal-day:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
|
|
2682
|
+
.digest-cal .cal-day .dot { position: absolute; bottom: 4px; left: 50%; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%; background: var(--accent); }
|
|
2683
|
+
.digest-cal .cal-day.today { box-shadow: inset 0 0 0 1.5px var(--accent); }
|
|
2684
|
+
.digest-cal a.cal-day.on { background: var(--accent); color: var(--on-accent); }
|
|
2685
|
+
.digest-cal a.cal-day.on .dot { background: var(--on-accent); }
|
|
2686
|
+
.digest-cal a.cal-day.on.today { box-shadow: inset 0 0 0 2px var(--accent), inset 0 0 0 3.5px var(--card); }
|
|
2687
|
+
.digest-cal .cal-none { text-align: center; font-size: 12.5px; color: var(--muted); padding: 8px 4px 2px; }
|
|
2688
|
+
@media (pointer: coarse) { .digest-cal .cal-day { height: 44px; } }
|
|
2689
|
+
.digest-cal .cal-fold { display: none; }
|
|
2690
|
+
@media (max-width: 900px) {
|
|
2691
|
+
/* folded to the picked day's week until the month is opened */
|
|
2692
|
+
.digest-cal .cal-head > span.cal-month { display: none; }
|
|
2693
|
+
.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; }
|
|
2694
|
+
.digest-cal .cal-fold .ic { width: 16px; height: 16px; color: var(--muted); transition: transform .15s; }
|
|
2695
|
+
.digest-cal .cal-fold[aria-expanded="true"] .ic { transform: rotate(180deg); }
|
|
2696
|
+
.digest-cal .cal-fold:focus { outline: none; }
|
|
2697
|
+
.digest-cal .cal-fold:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
|
|
2698
|
+
.digest-cal .cal-grid:not(.open) > .cal-day:not(.wk) { display: none; }
|
|
2699
|
+
.digest-wrap:has(> .digest-cal) { grid-template-columns: minmax(0, 1fr); }
|
|
2700
|
+
.digest-cal { position: static; width: 100%; max-width: 420px; padding: 2px 6px 6px; box-shadow: none; }
|
|
2701
|
+
.digest-cal .cal-day { height: 44px; font-size: 14px; }
|
|
2702
|
+
.digest-cal .cal-wd { padding: 0 0 2px; }
|
|
2703
|
+
}
|
|
2704
|
+
/* 0.9.8: an Unfinished session: its sentence, with Resume beside it */
|
|
2705
|
+
.md li.bi.unf { display: flex; align-items: center; gap: 12px; }
|
|
2706
|
+
.md li.bi.unf .bi-body { flex: 1 1 auto; min-width: 0; }
|
|
2707
|
+
.md li.bi.unf[hidden] { display: none; }
|
|
2708
|
+
|