samagotchi 0.136.0 → 0.136.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -1
- data/docs/cli.md +3 -2
- data/docs/internals/web-frontend.md +1 -1
- data/lib/samagotchi/bundles/system/manifest.yml +1 -1
- data/lib/samagotchi/version.rb +1 -1
- data/lib/samagotchi/web/public/answer_fold.js +21 -10
- data/lib/samagotchi/web/public/app.js +5 -0
- data/lib/samagotchi/web/public/details_motion.js +74 -0
- data/lib/samagotchi/web/public/index.html +15 -17
- metadata +2 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: a5dbc0c078bedf4518127ba59fef2277480193f98de99dcbd8983bb79a3802d2
|
|
4
|
+
data.tar.gz: e352d50d3b09a5e2f2a3ddd8dda3b79461e76c7e4743c306fc885e78fa670100
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c48493b22b5916b579d1f1fd386f0169f8a26ea71a29f5c77a567045e422f115b8b3ec421cb6f0499e0fc584da7e08840eeebf2650ad5d9bd75a61c41dc34c89
|
|
7
|
+
data.tar.gz: b9e9e2c78d869fe803ac6dbf54fcacc305b60c4b4ccd354d78b0967d340ad54cbf3f18357bb24c26050d96e4cff3899e90755857979fd9ec6680cc9fd730f46a
|
data/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and commands may change between minor versions. How releases are made:
|
|
|
7
7
|
[docs/releasing.md](docs/releasing.md).
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.136.1] - 2026-10-30
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Web: collapsibles keep their shape. A steps block, a thinking block, the recap and a long answer's fold are the
|
|
15
|
+
same box open or closed (the bar, the border, the width); a click changes the height, animated unless the system
|
|
16
|
+
prefers reduced motion. A closed answer fold is its box's one line, "▸ first line · N lines"; open, the row is the
|
|
17
|
+
box's top edge, "▾ N lines", and no longer repeats the answer's first line above the answer (a delegate report's
|
|
18
|
+
likewise, in the report's tint).
|
|
19
|
+
|
|
20
|
+
Update with `chi update`, then restart `chi web`. `chi home doctor` says what else to do.
|
|
21
|
+
|
|
10
22
|
## [0.136.0] - 2026-10-30
|
|
11
23
|
|
|
12
24
|
### Changed
|
|
@@ -5218,7 +5230,8 @@ and long-lived sessions.
|
|
|
5218
5230
|
- A macOS desktop helper (`chi desktop install`): a "Send to chi" Service and a
|
|
5219
5231
|
hotkey panel that send selected text or the clipboard to your sessions.
|
|
5220
5232
|
|
|
5221
|
-
[Unreleased]: https://github.com/dm1try/samagotchi/compare/v0.136.
|
|
5233
|
+
[Unreleased]: https://github.com/dm1try/samagotchi/compare/v0.136.1...HEAD
|
|
5234
|
+
[0.136.1]: https://github.com/dm1try/samagotchi/compare/v0.136.0...v0.136.1
|
|
5222
5235
|
[0.136.0]: https://github.com/dm1try/samagotchi/compare/v0.135.0...v0.136.0
|
|
5223
5236
|
[0.135.0]: https://github.com/dm1try/samagotchi/compare/v0.134.0...v0.135.0
|
|
5224
5237
|
[0.134.0]: https://github.com/dm1try/samagotchi/compare/v0.133.0...v0.134.0
|
data/docs/cli.md
CHANGED
|
@@ -1026,8 +1026,9 @@ copies its Markdown source, not the rendered text; a code block copies just
|
|
|
1026
1026
|
its code; a prompt copies the text as you typed it.
|
|
1027
1027
|
|
|
1028
1028
|
A long answer (over 25 lines or 2,000 characters of its text) can be folded
|
|
1029
|
-
by hand: a
|
|
1030
|
-
|
|
1029
|
+
by hand: a "▾ N lines" row is its top edge once its turn has ended. Click
|
|
1030
|
+
it and the answer closes to one line in its own box,
|
|
1031
|
+
"▸ its first line · N lines" (the
|
|
1031
1032
|
first line of what a hook presented in its place, else its first heading,
|
|
1032
1033
|
else its first line); click again to unfold. A delegate report's reply
|
|
1033
1034
|
folds the same way. Folding is this browser's choice, kept per session in
|
|
@@ -17,7 +17,7 @@ on an existing module, imported by a new version of another, then finds the old
|
|
|
17
17
|
page. A factory dep a new version stops passing is the same hazard the other way round: the store's redraws took
|
|
18
18
|
`updateInfoBar` and the chip controls out of `stream_handlers.js`'s deps (and `updateInfoBar`/`updateComposerMode`
|
|
19
19
|
out of `send_turn.js`, `session_actions.js` and `lists_view.js`); a page loaded before keeps all its old modules
|
|
20
|
-
until a reload, so the risk is a mixed cache, not an open tab. `answer_fold.js`,
|
|
20
|
+
until a reload, so the risk is a mixed cache, not an open tab. `answer_fold.js`, `details_motion.js`,
|
|
21
21
|
`turn_range.js`, `history_reveal.js`, `latest.js`, `session_payload.js`, `method_api.js`, `session_store.js`,
|
|
22
22
|
`session_fields.js`, `feature_gates.js`, `revise_stack.js` and `shell_command.js` are new modules for that reason.
|
|
23
23
|
|
data/lib/samagotchi/version.rb
CHANGED
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
// gets a fold row: a sibling just before the bubble, never inside it (the
|
|
4
4
|
// bubble's copy text, its claims and a live end's innerHTML stay the
|
|
5
5
|
// bubble's own). Folded, the bubble has the class `.folded` (CSS hides it;
|
|
6
|
-
// no inline style)
|
|
7
|
-
//
|
|
8
|
-
//
|
|
6
|
+
// no inline style) and the row is the answer's box closed: "▸ ‹first
|
|
7
|
+
// line› · N lines" in the bubble's shape; unfolded, the row is that box's
|
|
8
|
+
// top edge, "▾ N lines", the bubble its rest (CSS joins the two). The box
|
|
9
|
+
// never changes shape, a click changes its height, animated
|
|
10
|
+
// (details_motion.js animateHeight) unless the viewer prefers no motion.
|
|
9
11
|
//
|
|
10
12
|
// A delegate report (a user line chi brought in, data-source
|
|
11
13
|
// "delegate_report") gets the same row, folded by default (it is written
|
|
@@ -30,6 +32,7 @@
|
|
|
30
32
|
// A module of its own: static JS is cached at unversioned URLs, and a new
|
|
31
33
|
// export on an old module would blank the page.
|
|
32
34
|
import { bubbleCopyText } from "./copy.js";
|
|
35
|
+
import { animateHeight, canAnimate } from "./details_motion.js";
|
|
33
36
|
import { clip } from "./format.js";
|
|
34
37
|
import { readStored, removeStored, storedKeys, writeStored } from "./storage.js";
|
|
35
38
|
|
|
@@ -80,12 +83,13 @@ export function foldLabel(text, { display = false } = {}) {
|
|
|
80
83
|
return clip(plainLine(heading ?? texts[0] ?? ""), LABEL_CHARS);
|
|
81
84
|
}
|
|
82
85
|
|
|
83
|
-
// The row's words
|
|
84
|
-
// the
|
|
85
|
-
//
|
|
86
|
-
export function foldRowText(text, { display = false, label = foldLabel(text, { display }) } = {}) {
|
|
86
|
+
// The row's words: folded, the label and the size; unfolded, the size
|
|
87
|
+
// alone (the content is right under it). +label+: the row's own (a
|
|
88
|
+
// report's, reportLabel), else the answer's.
|
|
89
|
+
export function foldRowText(text, { display = false, folded = true, label = foldLabel(text, { display }) } = {}) {
|
|
87
90
|
const n = lineCount(text);
|
|
88
91
|
const size = `${n} line${n === 1 ? "" : "s"}`;
|
|
92
|
+
if (!folded) return { label: "", size };
|
|
89
93
|
return { label, size: label ? `\u00a0\u00b7 ${size}` : size };
|
|
90
94
|
}
|
|
91
95
|
|
|
@@ -205,7 +209,7 @@ function drawRow(row, bubble) {
|
|
|
205
209
|
const text = answerText(bubble);
|
|
206
210
|
const report = isReport(bubble);
|
|
207
211
|
const own = report ? { label: reportLabel(text, bubble.querySelector(":scope > .origin-label")?.textContent || "") } : {};
|
|
208
|
-
const { label, size } = foldRowText(text, { display: bubble.hasAttribute("data-answer-display"), ...own });
|
|
212
|
+
const { label, size } = foldRowText(text, { display: bubble.hasAttribute("data-answer-display"), folded, ...own });
|
|
209
213
|
const what = report ? "report" : "answer";
|
|
210
214
|
row.setAttribute("aria-expanded", folded ? "false" : "true");
|
|
211
215
|
row.title = folded ? `Show the ${what}` : `Fold the ${what}`;
|
|
@@ -245,8 +249,9 @@ export function keepRowInView(scroller, row, mutate) {
|
|
|
245
249
|
// @param historyEl the history (#history), also its scroller
|
|
246
250
|
// @param sessionId () => the open session's id
|
|
247
251
|
// @param projectRoot () => the open session's project root, or null
|
|
252
|
+
// @param motion (bubble) => whether a fold or unfold animates (canAnimate)
|
|
248
253
|
// @return {decorate(root)} (the observer runs it; specs call it)
|
|
249
|
-
export function installAnswerFold({ historyEl, sessionId, projectRoot = () => null }) {
|
|
254
|
+
export function installAnswerFold({ historyEl, sessionId, projectRoot = () => null, motion = canAnimate }) {
|
|
250
255
|
// Each bubble's row, and each row's bubble.
|
|
251
256
|
const rows = new WeakMap();
|
|
252
257
|
const bubbleOf = new WeakMap();
|
|
@@ -318,10 +323,16 @@ export function installAnswerFold({ historyEl, sessionId, projectRoot = () => nu
|
|
|
318
323
|
if (!bubble) return;
|
|
319
324
|
e.preventDefault();
|
|
320
325
|
const folded = !bubble.classList.contains("folded");
|
|
321
|
-
keepRowInView(historyEl, row, () => {
|
|
326
|
+
const settle = () => keepRowInView(historyEl, row, () => {
|
|
322
327
|
bubble.classList.toggle("folded", folded);
|
|
323
328
|
drawRow(row, bubble);
|
|
324
329
|
});
|
|
330
|
+
if (!motion(bubble)) settle();
|
|
331
|
+
else if (folded) animateHeight(bubble, bubble.offsetHeight, 0, { fade: true }).then(settle);
|
|
332
|
+
else {
|
|
333
|
+
settle();
|
|
334
|
+
animateHeight(bubble, 0, bubble.offsetHeight, { fade: true });
|
|
335
|
+
}
|
|
325
336
|
// An answer's choice is its fold, a report's its unfold (D2: the default differs).
|
|
326
337
|
if (isReport(bubble)) writeOpened(sessionId(), answerKey(bubble), !folded, { root: projectRoot() });
|
|
327
338
|
else writeFold(sessionId(), answerKey(bubble), folded, { root: projectRoot() });
|
|
@@ -72,6 +72,7 @@ import { OWNER_FINAL, verifyTurnOf } from "./verify_target.js";
|
|
|
72
72
|
import { actionLine, annotationActions, composerWithAction } from "./annotate_actions.js";
|
|
73
73
|
import { copyText, installCopy } from "./copy.js";
|
|
74
74
|
import { installAnswerFold, sweepAnswerFolds } from "./answer_fold.js";
|
|
75
|
+
import { installDetailsMotion } from "./details_motion.js";
|
|
75
76
|
import { answerLabel, installReviseStacks, reviseChipTemplate, reviseWorkerUnavailable } from "./revise_stack.js";
|
|
76
77
|
import { createQuestionCards } from "./question_cards.js";
|
|
77
78
|
import { splitSnapshotCards } from "./card.js";
|
|
@@ -2085,6 +2086,10 @@ historyEl.addEventListener("click", (e) => {
|
|
|
2085
2086
|
});
|
|
2086
2087
|
turnDom.scrollEl.addEventListener("scroll", annotateBar.schedule, true);
|
|
2087
2088
|
turnRoots().forEach((root) => installCopy(root));
|
|
2089
|
+
// A steps block, a thinking block and the recap open and close by hand
|
|
2090
|
+
// with their height animated (details_motion.js), in the history and on
|
|
2091
|
+
// the stage.
|
|
2092
|
+
installDetailsMotion({ root: document.body, selector: ".turn-work, .bubble.thinking, .bubble.recap" });
|
|
2088
2093
|
// Long answers fold by hand (answer_fold.js), per viewer and session.
|
|
2089
2094
|
installAnswerFold({
|
|
2090
2095
|
historyEl,
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
// Collapsibles keep their shape: a steps block, a thinking block, the recap
|
|
2
|
+
// and the answer fold are the same box open or closed (the bar, the border,
|
|
3
|
+
// the width), and a click only changes the height. This module is the
|
|
4
|
+
// motion: a click on one of their summaries animates the height between the
|
|
5
|
+
// two states (Web Animations, MOTION_MS) instead of snapping, and the
|
|
6
|
+
// answer fold borrows animateHeight for its bubble. Nothing moves when the
|
|
7
|
+
// viewer prefers reduced motion or the element cannot animate (an old
|
|
8
|
+
// engine, a spec's DOM): the click is the native toggle then.
|
|
9
|
+
//
|
|
10
|
+
// Only a hand's click animates: the page's own opens and closes (a turn's
|
|
11
|
+
// end closing a block, a reload drawing the outline) stay instant, as they
|
|
12
|
+
// are not a change the viewer watches.
|
|
13
|
+
//
|
|
14
|
+
// A module of its own: static JS is cached at unversioned URLs, and a new
|
|
15
|
+
// export on an old module would blank the page.
|
|
16
|
+
|
|
17
|
+
export const MOTION_MS = 220;
|
|
18
|
+
|
|
19
|
+
// Whether +el+ can animate for this viewer.
|
|
20
|
+
export function canAnimate(el) {
|
|
21
|
+
if (typeof el?.animate !== "function") return false;
|
|
22
|
+
const win = el.ownerDocument?.defaultView;
|
|
23
|
+
return !win?.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// Animates +el+'s height from +from+ to +to+ (px), its overflow clipped
|
|
27
|
+
// meanwhile; +fade+ fades it with the height. Resolves when the animation
|
|
28
|
+
// is over (or canceled).
|
|
29
|
+
export async function animateHeight(el, from, to, { fade = false, ms = MOTION_MS } = {}) {
|
|
30
|
+
const at = (h, o) => (fade ? { height: `${h}px`, opacity: String(o) } : { height: `${h}px` });
|
|
31
|
+
const anim = el.animate([at(from, from ? 1 : 0), at(to, to ? 1 : 0)], { duration: ms, easing: "ease" });
|
|
32
|
+
el.style.overflow = "hidden";
|
|
33
|
+
try {
|
|
34
|
+
await anim.finished;
|
|
35
|
+
} catch {
|
|
36
|
+
// canceled: the element is where its class puts it
|
|
37
|
+
} finally {
|
|
38
|
+
el.style.overflow = "";
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// A <details>' height closed: its summary and its own padding and borders.
|
|
43
|
+
function closedHeight(details, summary) {
|
|
44
|
+
const win = details.ownerDocument?.defaultView;
|
|
45
|
+
const cs = win?.getComputedStyle?.(details);
|
|
46
|
+
const px = (v) => Number.parseFloat(v) || 0;
|
|
47
|
+
const frame = cs ? px(cs.paddingTop) + px(cs.paddingBottom) + px(cs.borderTopWidth) + px(cs.borderBottomWidth) : 0;
|
|
48
|
+
return summary.offsetHeight + frame;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Installs the motion on +root+ for the <details> matching +selector+ whose
|
|
52
|
+
// own summary is clicked. +motion+: whether to animate +el+ (canAnimate).
|
|
53
|
+
export function installDetailsMotion({ root, selector, motion = canAnimate }) {
|
|
54
|
+
const busy = new WeakSet();
|
|
55
|
+
root.addEventListener("click", (e) => {
|
|
56
|
+
const summary = e.target.closest?.("summary");
|
|
57
|
+
const details = summary?.parentElement;
|
|
58
|
+
if (!details || !details.matches?.(selector) || summary.parentElement !== details) return;
|
|
59
|
+
if (e.target.closest("a, button, input, label") !== null && e.target !== summary) return;
|
|
60
|
+
if (!motion(details)) return;
|
|
61
|
+
e.preventDefault();
|
|
62
|
+
if (busy.has(details)) return;
|
|
63
|
+
busy.add(details);
|
|
64
|
+
const done = () => busy.delete(details);
|
|
65
|
+
if (details.open) {
|
|
66
|
+
const from = details.offsetHeight;
|
|
67
|
+
animateHeight(details, from, closedHeight(details, summary)).then(() => { details.open = false; done(); });
|
|
68
|
+
} else {
|
|
69
|
+
const from = closedHeight(details, summary);
|
|
70
|
+
details.open = true;
|
|
71
|
+
animateHeight(details, from, details.offsetHeight).then(done);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
}
|
|
@@ -57,24 +57,25 @@ main{flex:1;display:flex;flex-direction:column;gap:16px;padding:16px;overflow:au
|
|
|
57
57
|
/* A generation opens its answer bubble empty: hidden until text streams (the thinking box shows progress meanwhile). */
|
|
58
58
|
.bubble.output.streaming:empty{display:none}
|
|
59
59
|
/* The answer's pop: the promoted bubble is held at the narration box's height (inline max-height, scrolled to its tail) until the rendered markdown lands, then grows to its content while the content fades in; both classes go 400 ms later. */
|
|
60
|
-
/* A long answer folded by hand (answer_fold.js): the row is the bubble's sibling just before it,
|
|
60
|
+
/* A long answer folded by hand (answer_fold.js): the row is the bubble's sibling just before it, in the bubble's own shape. Folded, the row is the answer's box closed ("▸ first line · N lines") and the bubble is hidden; unfolded, the row is that box's top edge ("▾ N lines") and the bubble its rest, the two one block. The shape never changes; a click changes the height (details_motion.js). */
|
|
61
61
|
/* Folded: the bubble hidden, an answer or a delegate report (#history's: outranks .bubble.user's display). */
|
|
62
62
|
#history>.bubble.folded{display:none}
|
|
63
|
-
.answer-fold{display:flex;align-items:baseline;gap:0;align-self:
|
|
64
|
-
.answer-fold:hover{
|
|
63
|
+
.answer-fold{display:flex;align-items:baseline;gap:0;align-self:stretch;max-width:100%;min-width:0;margin:0;padding:12px 14px;font:inherit;font-size:13px;font-weight:600;line-height:1.5;color:var(--text-muted);text-align:left;cursor:pointer;user-select:none;background:var(--bg-panel);border:1px solid var(--border);border-left:3px solid var(--accent-strong);border-radius:12px}
|
|
64
|
+
.answer-fold:hover .answer-fold-size{color:var(--text-2)}
|
|
65
65
|
.answer-fold:focus-visible{outline:2px solid var(--accent-ring);outline-offset:1px}
|
|
66
66
|
.answer-fold::before{content:"▾\00a0";color:var(--accent);flex:none}
|
|
67
67
|
.answer-fold.folded::before{content:"▸\00a0"}
|
|
68
|
-
/* Open: the
|
|
69
|
-
.answer-fold:not(.folded){margin-bottom:-12px;border-bottom-left-radius:0}
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
.
|
|
68
|
+
/* Open: the box's top edge (-12px: #history's gap), the bubble under it its rest. */
|
|
69
|
+
.answer-fold:not(.folded){margin-bottom:-12px;padding-bottom:0;border-bottom:0;border-bottom-left-radius:0;border-bottom-right-radius:0}
|
|
70
|
+
.answer-fold:not(.folded)+.bubble{border-top:0;border-top-left-radius:0;border-top-right-radius:0;padding-top:8px}
|
|
71
|
+
/* A delegate report's row: the report's box (right, its tint, the user accent; dashed when merged mid-turn), closed or
|
|
72
|
+
its top edge. */
|
|
73
|
+
.answer-fold.report{align-self:flex-end;width:85%;background:var(--accent-bg);border-left-color:var(--accent)}
|
|
73
74
|
.answer-fold.report.steered{border-left-style:dashed}
|
|
74
|
-
.answer-fold.report:not(.folded)
|
|
75
|
+
.answer-fold.report:not(.folded)+.bubble.user{width:85%}
|
|
75
76
|
.answer-fold-label{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--text-2);font-size:13px}
|
|
76
77
|
.answer-fold-label:empty{display:none}
|
|
77
|
-
.answer-fold-size{flex:none;white-space:nowrap;font-variant-numeric:tabular-nums}
|
|
78
|
+
.answer-fold-size{flex:none;white-space:nowrap;font-variant-numeric:tabular-nums;transition:color .12s ease}
|
|
78
79
|
/* Revise stacks (revise_stack.js): a superseded version folds to its stub; the Revise row under a final answer
|
|
79
80
|
(zero height: its button sits on the bubble's bottom edge, clear of the copy button, shown on hover) and a stack
|
|
80
81
|
top's version chip. */
|
|
@@ -320,11 +321,10 @@ button.system-one-wrong:hover:not(:disabled){background:var(--bg-hover);color:va
|
|
|
320
321
|
.activity-row>.activity-command{margin-left:0}
|
|
321
322
|
}
|
|
322
323
|
.bubble.thinking{border-left:3px solid var(--think);background:color-mix(in srgb,var(--think) 6%,var(--bg-panel));padding:8px 12px}
|
|
323
|
-
.bubble.
|
|
324
|
-
.bubble.thinking:not([open]){border-left-color:var(--think)}
|
|
324
|
+
.bubble.activity:not([open]){padding:3px 10px;background:transparent;border-color:transparent;align-self:flex-start;border-radius:6px;transition:background .12s ease}
|
|
325
325
|
.bubble.activity:not([open]){border-left-color:var(--accent)}
|
|
326
|
-
.bubble.
|
|
327
|
-
.bubble.
|
|
326
|
+
.bubble.activity:not([open]):hover{background:var(--bg-panel)}
|
|
327
|
+
.bubble.activity:not([open])>summary{font-size:12px;font-weight:500}
|
|
328
328
|
.bubble.thinking>summary{cursor:pointer;color:var(--text-muted);font-size:13px;font-weight:600;font-style:italic;user-select:none;list-style:none}
|
|
329
329
|
.bubble.thinking>summary::-webkit-details-marker{display:none}
|
|
330
330
|
.bubble.thinking>summary::before{content:"▸ ";color:var(--think)}
|
|
@@ -336,9 +336,7 @@ button.system-one-wrong:hover:not(:disabled){background:var(--bg-hover);color:va
|
|
|
336
336
|
.turn-work>summary::-webkit-details-marker{display:none}
|
|
337
337
|
.turn-work>summary::before{content:"▸ ";color:var(--accent)}
|
|
338
338
|
.turn-work[open]>summary::before{content:"▾ "}
|
|
339
|
-
|
|
340
|
-
.turn-work:not([open]):hover{background:var(--bg-panel)}
|
|
341
|
-
.turn-work:not([open])>summary{font-size:12px;font-weight:500}
|
|
339
|
+
/* Closed, a block keeps its box (the bar, the border, the width): a click changes its height only (details_motion.js); thinking and the recap the same. */
|
|
342
340
|
/* A step's body (thinking, narration, rows, cards) sits --step-indent right of its summary, so the thinking
|
|
343
341
|
chevron and the row marks share one column under the step's own chevron. The summary takes it back with a
|
|
344
342
|
negative margin: a child's own margin shorthand can't undo the padding. */
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: samagotchi
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.136.
|
|
4
|
+
version: 0.136.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Dmitry Dedov
|
|
@@ -802,6 +802,7 @@ files:
|
|
|
802
802
|
- lib/samagotchi/web/public/ctx.js
|
|
803
803
|
- lib/samagotchi/web/public/data.js
|
|
804
804
|
- lib/samagotchi/web/public/delivery_line.js
|
|
805
|
+
- lib/samagotchi/web/public/details_motion.js
|
|
805
806
|
- lib/samagotchi/web/public/diff_view.js
|
|
806
807
|
- lib/samagotchi/web/public/dock_reserve.js
|
|
807
808
|
- lib/samagotchi/web/public/families_view.js
|