diff --git a/index.html b/index.html
index b462f82..a6108dd 100644
--- a/index.html
+++ b/index.html
@@ -236,11 +236,12 @@
- spiral
+ spiral
-
-
+
+
@@ -262,8 +263,10 @@
-
-
+
+
@@ -293,25 +296,25 @@
-
+
-
+
-
-
+
+
-
+
-
+
@@ -328,12 +331,12 @@
-
-
+
+
-
+
@@ -355,6 +358,21 @@
brin
+
+
+ clip
+
+
+
+
+
+
+
+
+
+
diff --git a/script/run.ts b/script/run.ts
index 6450e21..659d2ac 100644
--- a/script/run.ts
+++ b/script/run.ts
@@ -260,9 +260,29 @@ namespace Flat {
export function fadeTo(newPane: Pane): void {
for (const pane of allPanes) {
- const here = pane == newPane;
- document.getElementById(pane)!.dataset.selected = `${here}`;
- if (here) { history.replaceState(null, '🦎', `#${pane}`); }
+ const elem = document.getElementById(pane)!;
+ if (pane == newPane) {
+ // show new pane
+ //
+ // - "entering" state is displayed and z-index 1, but opacity 0
+ // - "active" state is fully showing
+ //
+ // "entering" exists because firefox doesn't animate a
+ // transition out of `display: none`
+ elem.dataset.state = 'entering';
+ setTimeout(() => elem.dataset.state = 'active');
+ history.replaceState(null, '🦎', `#${pane}`);
+ } else if (elem.dataset.state == 'active') {
+ // hide old pane
+ //
+ // - "leaving" is z-index -1 and opacity 0
+ // - "hidden" is `display: none`
+ //
+ // separate for the same reason as above
+ function hide() { elem.dataset.state = 'hidden'; }
+ elem.addEventListener('transitionend', hide, {once: true});
+ elem.dataset.state = 'leaving';
+ }
}
}
@@ -294,6 +314,9 @@ function setup(): void {
Cube.instantMoveTo(pane);
Flat.fadeTo(pane);
box.checked = true;
+ } else {
+ const elem = document.getElementById(pane)!;
+ elem.dataset.state = 'hidden';
}
}
}
diff --git a/script/shuffle.ts b/script/shuffle.ts
index 0d4d489..1ec208f 100644
--- a/script/shuffle.ts
+++ b/script/shuffle.ts
@@ -1,3 +1,18 @@
+function shuffle(subject: A[]): A[] {
+ let res = Array.from(subject);
+
+ for (let i = 0; i < res.length - 1; ++i) {
+ const j = i + Math.floor(Math.random() * (res.length - i));
+ if (i != j) {
+ const k = res[i]!;
+ res[i] = res[j]!;
+ res[j] = k;
+ }
+ }
+
+ return res;
+}
+
function group(subject: A[], keepTogether: A[][]): A[][] {
type Value = {array: A[], added: boolean};
@@ -14,7 +29,7 @@ function group(subject: A[], keepTogether: A[][]): A[][] {
if (group?.added) { continue; }
else if (group) {
group.added = true;
- res.push(group.array);
+ res.push(shuffle(group.array));
} else {
res.push([x]);
}
@@ -23,28 +38,12 @@ function group(subject: A[], keepTogether: A[][]): A[][] {
return res;
}
-function shuffle(subject: A[]): A[] {
- let res = Array.from(subject);
-
- for (let i = 0; i < res.length - 2; ++i) {
- const j = i + Math.floor(Math.random() * (res.length - i));
- if (i != j) {
- const k = res[i]!;
- res[i] = res[j]!;
- res[j] = k;
- }
- }
-
- return res;
-}
-
function groupedShuffle(subject: A[], keepTogether: A[][]): A[] {
- let groups = group(subject, keepTogether);
- return shuffle(groups).flat();
+ return shuffle(group(subject, keepTogether)).flat();
}
function shuffleAll() {
- let groups = [group('myno', 'abyss')];
+ let groups = [group('myno', 'abyss'), group('clip', 'cervine')];
for (const elem of Array.from(document.getElementsByClassName('shuffle'))) {
let shuffled = groupedShuffle(Array.from(elem.children), groups);
diff --git a/style/base.css b/style/base.css
index 8576d25..9ce7dd1 100644
--- a/style/base.css
+++ b/style/base.css
@@ -482,6 +482,7 @@ strong { font-weight: 700; }
#friends #codl a { background: #87261f; color: #edb970; }
#friends #violet a { background: #8c2bd8; color: #dddddd; }
#friends #brin a { background: #1e1e1e; color: #ff4400; }
+#friends #clip a { background: #2f2a2b; color: #e8d057; }
#nissbuttons {
margin: 2em auto 0;
diff --git a/style/flat.css b/style/flat.css
index 92fcc30..5ddebd7 100644
--- a/style/flat.css
+++ b/style/flat.css
@@ -98,17 +98,25 @@ body {
transition: background 0.1s ease-in;
}
-#cube > section[data-selected=true] {
+#cube > :is(section[data-state=entering], #a) {
+ z-index: 1;
+ opacity: 0;
+}
+
+#cube > :is(section[data-state=active], #a) {
z-index: 1;
opacity: 1;
transition: opacity 0.1s ease-in;
}
-#cube > section[data-selected=false] {
+#cube > :is(section[data-state=leaving], #a) {
z-index: -1;
opacity: 0;
transition: opacity 0s 0.1s ease-in;
}
-/* todo make sure this works ok with screen readers */
+
+#cube > :is(section[data-state=hidden], #a) {
+ display: none;
+}
}