Commit fcb9a94079110eb467da6f280812998d4efe33d4

Authored by yibo
1 parent 72be2914

Add a click-to-enter splash screen (infiniteslop.ai's unmute trick)

The video autoplays muted underneath a full-screen splash — logo, play icon,
slogan and a credit line, matching infiniteslop.ai's own splash. Clicking it
is the user gesture that lets the browser allow unmuted playback, so desktop
viewers land with sound instead of the silent-until-you-find-the-mute-button
experience from the previous change. Mobile stays muted after entry, same as
infiniteslop.ai, since unmuted autoplay-adjacent playback is unreliable there.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0144MiJ2cLjMd9jWaeEpVfUJ
library.json
@@ -79,7 +79,7 @@ @@ -79,7 +79,7 @@
79 "likes": 0, 79 "likes": 0,
80 "createdAt": 1788192915845, 80 "createdAt": 1788192915845,
81 "promptEn": "scholar watches the room warily", 81 "promptEn": "scholar watches the room warily",
82 - "lastPlayedAt": 1788251736825 82 + "lastPlayedAt": 1788253865811
83 }, 83 },
84 { 84 {
85 "id": "e8cbb73560ef", 85 "id": "e8cbb73560ef",
@@ -154,7 +154,7 @@ @@ -154,7 +154,7 @@
154 "likes": 0, 154 "likes": 0,
155 "createdAt": 1788192913886, 155 "createdAt": 1788192913886,
156 "promptEn": "taoist panics, freaked out", 156 "promptEn": "taoist panics, freaked out",
157 - "lastPlayedAt": 1788250312031 157 + "lastPlayedAt": 1788253751763
158 }, 158 },
159 { 159 {
160 "id": "45c1136d1e05", 160 "id": "45c1136d1e05",
@@ -214,7 +214,7 @@ @@ -214,7 +214,7 @@
214 "likes": 0, 214 "likes": 0,
215 "createdAt": 1788192912912, 215 "createdAt": 1788192912912,
216 "promptEn": "taoist charmed, hesitating", 216 "promptEn": "taoist charmed, hesitating",
217 - "lastPlayedAt": 1788251760826 217 + "lastPlayedAt": 1788253947848
218 }, 218 },
219 { 219 {
220 "id": "f8da9934c823", 220 "id": "f8da9934c823",
@@ -319,7 +319,7 @@ @@ -319,7 +319,7 @@
319 "likes": 0, 319 "likes": 0,
320 "createdAt": 1788188423583, 320 "createdAt": 1788188423583,
321 "promptEn": "woman in white scared, dodging", 321 "promptEn": "woman in white scared, dodging",
322 - "lastPlayedAt": 1788251198437 322 + "lastPlayedAt": 1788253953855
323 }, 323 },
324 { 324 {
325 "id": "1597db4be561", 325 "id": "1597db4be561",
@@ -348,7 +348,7 @@ @@ -348,7 +348,7 @@
348 "partition": "ref2va", 348 "partition": "ref2va",
349 "likes": 0, 349 "likes": 0,
350 "createdAt": 1788186218619, 350 "createdAt": 1788186218619,
351 - "lastPlayedAt": 1788252471153, 351 + "lastPlayedAt": 1788253885823,
352 "promptEn": "woman in white evading, scared" 352 "promptEn": "woman in white evading, scared"
353 }, 353 },
354 { 354 {
@@ -499,7 +499,7 @@ @@ -499,7 +499,7 @@
499 "likes": 0, 499 "likes": 0,
500 "createdAt": 1788153988474, 500 "createdAt": 1788153988474,
501 "promptEn": "astronaut at a martian canyon, visor reflecting alien ruins, then aerial view of the city", 501 "promptEn": "astronaut at a martian canyon, visor reflecting alien ruins, then aerial view of the city",
502 - "lastPlayedAt": 1788251428589 502 + "lastPlayedAt": 1788253845801
503 }, 503 },
504 { 504 {
505 "id": "194fc2b56cb5", 505 "id": "194fc2b56cb5",
@@ -514,7 +514,7 @@ @@ -514,7 +514,7 @@
514 "likes": 0, 514 "likes": 0,
515 "createdAt": 1788138492364, 515 "createdAt": 1788138492364,
516 "promptEn": "astronaut on a Martian canyon, helmet reflecting an alien ruined city", 516 "promptEn": "astronaut on a Martian canyon, helmet reflecting an alien ruined city",
517 - "lastPlayedAt": 1788251558701 517 + "lastPlayedAt": 1788253805777
518 }, 518 },
519 { 519 {
520 "id": "f84b8f044ec5", 520 "id": "f84b8f044ec5",
@@ -679,7 +679,7 @@ @@ -679,7 +679,7 @@
679 "likes": 0, 679 "likes": 0,
680 "createdAt": 1788026876886, 680 "createdAt": 1788026876886,
681 "promptEn": "apartment manager in an eerie corridor, red elevator light flickering, holding out a key", 681 "promptEn": "apartment manager in an eerie corridor, red elevator light flickering, holding out a key",
682 - "lastPlayedAt": 1788250332049 682 + "lastPlayedAt": 1788253825788
683 }, 683 },
684 { 684 {
685 "id": "cdd03cca8461", 685 "id": "cdd03cca8461",
@@ -709,7 +709,7 @@ @@ -709,7 +709,7 @@
709 "likes": 0, 709 "likes": 0,
710 "createdAt": 1788026569123, 710 "createdAt": 1788026569123,
711 "promptEn": "pale dream demon in a suit, reaching out a hand inside a dream train car", 711 "promptEn": "pale dream demon in a suit, reaching out a hand inside a dream train car",
712 - "lastPlayedAt": 1788252102983 712 + "lastPlayedAt": 1788253611671
713 }, 713 },
714 { 714 {
715 "id": "bd6e2b264243", 715 "id": "bd6e2b264243",
@@ -889,7 +889,7 @@ @@ -889,7 +889,7 @@
889 "likes": 0, 889 "likes": 0,
890 "createdAt": 1788025620717, 890 "createdAt": 1788025620717,
891 "promptEn": "alien tyrant holding a glowing energy sphere, sneering on a rocky green battlefield", 891 "promptEn": "alien tyrant holding a glowing energy sphere, sneering on a rocky green battlefield",
892 - "lastPlayedAt": 1788252495168 892 + "lastPlayedAt": 1788253757767
893 }, 893 },
894 { 894 {
895 "id": "9db41d807330", 895 "id": "9db41d807330",
@@ -934,7 +934,7 @@ @@ -934,7 +934,7 @@
934 "likes": 0, 934 "likes": 0,
935 "createdAt": 1788024900966, 935 "createdAt": 1788024900966,
936 "promptEn": "player 101 blocking the path on a high glass bridge, threatening you", 936 "promptEn": "player 101 blocking the path on a high glass bridge, threatening you",
937 - "lastPlayedAt": 1788251722799 937 + "lastPlayedAt": 1788253797782
938 }, 938 },
939 { 939 {
940 "id": "d6aab3fce63d", 940 "id": "d6aab3fce63d",
@@ -964,7 +964,7 @@ @@ -964,7 +964,7 @@
964 "likes": 0, 964 "likes": 0,
965 "createdAt": 1788024491625, 965 "createdAt": 1788024491625,
966 "promptEn": "prince signs an execution order in the trial hall, points at the guillotine", 966 "promptEn": "prince signs an execution order in the trial hall, points at the guillotine",
967 - "lastPlayedAt": 1788251928912 967 + "lastPlayedAt": 1788253737754
968 }, 968 },
969 { 969 {
970 "id": "8a933feb52c4", 970 "id": "8a933feb52c4",
@@ -994,7 +994,7 @@ @@ -994,7 +994,7 @@
994 "likes": 0, 994 "likes": 0,
995 "createdAt": 1788016668421, 995 "createdAt": 1788016668421,
996 "promptEn": "pirate negotiation, catching Barbossa's flaw and turning the tables", 996 "promptEn": "pirate negotiation, catching Barbossa's flaw and turning the tables",
997 - "lastPlayedAt": 1788250676206 997 + "lastPlayedAt": 1788253829791
998 }, 998 },
999 { 999 {
1000 "id": "e3b18b5dfd8e", 1000 "id": "e3b18b5dfd8e",
@@ -1024,7 +1024,7 @@ @@ -1024,7 +1024,7 @@
1024 "likes": 0, 1024 "likes": 0,
1025 "createdAt": 1788016203093, 1025 "createdAt": 1788016203093,
1026 "promptEn": "pirate negotiation, held the goal but paid a price", 1026 "promptEn": "pirate negotiation, held the goal but paid a price",
1027 - "lastPlayedAt": 1788250906296 1027 + "lastPlayedAt": 1788253859804
1028 }, 1028 },
1029 { 1029 {
1030 "id": "18aa882cbd0b", 1030 "id": "18aa882cbd0b",
@@ -1249,7 +1249,7 @@ @@ -1249,7 +1249,7 @@
1249 "likes": 0, 1249 "likes": 0,
1250 "createdAt": 1788012917294, 1250 "createdAt": 1788012917294,
1251 "promptEn": "standing on the glass bridge, facing off with player 101", 1251 "promptEn": "standing on the glass bridge, facing off with player 101",
1252 - "lastPlayedAt": 1788251642756 1252 + "lastPlayedAt": 1788253839798
1253 }, 1253 },
1254 { 1254 {
1255 "id": "8f23de61904f", 1255 "id": "8f23de61904f",
@@ -1324,7 +1324,7 @@ @@ -1324,7 +1324,7 @@
1324 "likes": 0, 1324 "likes": 0,
1325 "createdAt": 1788012202708, 1325 "createdAt": 1788012202708,
1326 "promptEn": "facing Vecna, went in head-on and got seen through", 1326 "promptEn": "facing Vecna, went in head-on and got seen through",
1327 - "lastPlayedAt": 1788248276792 1327 + "lastPlayedAt": 1788253713746
1328 }, 1328 },
1329 { 1329 {
1330 "id": "40ccb04f76e9", 1330 "id": "40ccb04f76e9",
@@ -1369,7 +1369,7 @@ @@ -1369,7 +1369,7 @@
1369 "likes": 0, 1369 "likes": 0,
1370 "createdAt": 1788011488775, 1370 "createdAt": 1788011488775,
1371 "promptEn": "graveyard standoff, exploiting a flaw to counter Voldemort", 1371 "promptEn": "graveyard standoff, exploiting a flaw to counter Voldemort",
1372 - "lastPlayedAt": 1788252403130 1372 + "lastPlayedAt": 1788253875818
1373 }, 1373 },
1374 { 1374 {
1375 "id": "24845be71ea0", 1375 "id": "24845be71ea0",
@@ -1399,7 +1399,7 @@ @@ -1399,7 +1399,7 @@
1399 "likes": 0, 1399 "likes": 0,
1400 "createdAt": 1788011251158, 1400 "createdAt": 1788011251158,
1401 "promptEn": "facing Voldemort, held the goal but paid a price", 1401 "promptEn": "facing Voldemort, held the goal but paid a price",
1402 - "lastPlayedAt": 1788251207183 1402 + "lastPlayedAt": 1788253835799
1403 }, 1403 },
1404 { 1404 {
1405 "id": "58f68b111429", 1405 "id": "58f68b111429",
@@ -1504,7 +1504,7 @@ @@ -1504,7 +1504,7 @@
1504 "likes": 0, 1504 "likes": 0,
1505 "createdAt": 1788009586293, 1505 "createdAt": 1788009586293,
1506 "promptEn": "facing Thanos, stayed passive and got cornered", 1506 "promptEn": "facing Thanos, stayed passive and got cornered",
1507 - "lastPlayedAt": 1788249207456 1507 + "lastPlayedAt": 1788253869815
1508 }, 1508 },
1509 { 1509 {
1510 "id": "438c98cf4973", 1510 "id": "438c98cf4973",
@@ -1639,7 +1639,7 @@ @@ -1639,7 +1639,7 @@
1639 "likes": 0, 1639 "likes": 0,
1640 "createdAt": 1788007441156, 1640 "createdAt": 1788007441156,
1641 "promptEn": "battlefield in Jaku city, the city in ruins, heroes in crisis", 1641 "promptEn": "battlefield in Jaku city, the city in ruins, heroes in crisis",
1642 - "lastPlayedAt": 1788251770832 1642 + "lastPlayedAt": 1788253771767
1643 }, 1643 },
1644 { 1644 {
1645 "id": "68219d6b68c8", 1645 "id": "68219d6b68c8",
@@ -1759,7 +1759,7 @@ @@ -1759,7 +1759,7 @@
1759 "likes": 0, 1759 "likes": 0,
1760 "createdAt": 1788005541640, 1760 "createdAt": 1788005541640,
1761 "promptEn": "facing Frieza, went in head-on and got seen through", 1761 "promptEn": "facing Frieza, went in head-on and got seen through",
1762 - "lastPlayedAt": 1788246977682 1762 + "lastPlayedAt": 1788253741753
1763 }, 1763 },
1764 { 1764 {
1765 "id": "574b47b00316", 1765 "id": "574b47b00316",
@@ -1864,7 +1864,7 @@ @@ -1864,7 +1864,7 @@
1864 "likes": 0, 1864 "likes": 0,
1865 "createdAt": 1788004115612, 1865 "createdAt": 1788004115612,
1866 "promptEn": "facing Mahito, stayed passive and got cornered", 1866 "promptEn": "facing Mahito, stayed passive and got cornered",
1867 - "lastPlayedAt": 1788252553190 1867 + "lastPlayedAt": 1788253899831
1868 }, 1868 },
1869 { 1869 {
1870 "id": "f4a2870386c6", 1870 "id": "f4a2870386c6",
@@ -1969,7 +1969,7 @@ @@ -1969,7 +1969,7 @@
1969 "likes": 0, 1969 "likes": 0,
1970 "createdAt": 1788002455066, 1970 "createdAt": 1788002455066,
1971 "promptEn": "facing Reiner, went in head-on and got seen through", 1971 "promptEn": "facing Reiner, went in head-on and got seen through",
1972 - "lastPlayedAt": 1788251886889 1972 + "lastPlayedAt": 1788253879816
1973 }, 1973 },
1974 { 1974 {
1975 "id": "5846d645e870", 1975 "id": "5846d645e870",
@@ -2014,7 +2014,7 @@ @@ -2014,7 +2014,7 @@
2014 "likes": 0, 2014 "likes": 0,
2015 "createdAt": 1788001508988, 2015 "createdAt": 1788001508988,
2016 "promptEn": "in the ruins of Konoha, exploiting a flaw to counter Pain", 2016 "promptEn": "in the ruins of Konoha, exploiting a flaw to counter Pain",
2017 - "lastPlayedAt": 1788252503166 2017 + "lastPlayedAt": 1788253801782
2018 }, 2018 },
2019 { 2019 {
2020 "id": "79304c061606", 2020 "id": "79304c061606",
@@ -2074,7 +2074,7 @@ @@ -2074,7 +2074,7 @@
2074 "likes": 0, 2074 "likes": 0,
2075 "createdAt": 1788000812932, 2075 "createdAt": 1788000812932,
2076 "promptEn": "facing Pain, went in head-on and got seen through", 2076 "promptEn": "facing Pain, went in head-on and got seen through",
2077 - "lastPlayedAt": 1788252529179 2077 + "lastPlayedAt": 1788253905836
2078 }, 2078 },
2079 { 2079 {
2080 "id": "f691ac021df0", 2080 "id": "f691ac021df0",
@@ -2119,7 +2119,7 @@ @@ -2119,7 +2119,7 @@
2119 "likes": 0, 2119 "likes": 0,
2120 "createdAt": 1788000105889, 2120 "createdAt": 1788000105889,
2121 "promptEn": "facing Sakazuki, exploiting a flaw to counter him", 2121 "promptEn": "facing Sakazuki, exploiting a flaw to counter him",
2122 - "lastPlayedAt": 1788250850269 2122 + "lastPlayedAt": 1788253821783
2123 }, 2123 },
2124 { 2124 {
2125 "id": "c9be7c07b793", 2125 "id": "c9be7c07b793",
@@ -2164,7 +2164,7 @@ @@ -2164,7 +2164,7 @@
2164 "likes": 0, 2164 "likes": 0,
2165 "createdAt": 1787999633670, 2165 "createdAt": 1787999633670,
2166 "promptEn": "facing Sakazuki, went in head-on and got seen through", 2166 "promptEn": "facing Sakazuki, went in head-on and got seen through",
2167 - "lastPlayedAt": 1788251129144 2167 + "lastPlayedAt": 1788253777771
2168 }, 2168 },
2169 { 2169 {
2170 "id": "a8b8b4430ee3", 2170 "id": "a8b8b4430ee3",
@@ -2179,7 +2179,7 @@ @@ -2179,7 +2179,7 @@
2179 "likes": 0, 2179 "likes": 0,
2180 "createdAt": 1787999397097, 2180 "createdAt": 1787999397097,
2181 "promptEn": "facing Sakazuki, stayed passive and got cornered", 2181 "promptEn": "facing Sakazuki, stayed passive and got cornered",
2182 - "lastPlayedAt": 1788252397128 2182 + "lastPlayedAt": 1788253761764
2183 }, 2183 },
2184 { 2184 {
2185 "id": "88923aaf57f3", 2185 "id": "88923aaf57f3",
@@ -2269,7 +2269,7 @@ @@ -2269,7 +2269,7 @@
2269 "likes": 0, 2269 "likes": 0,
2270 "createdAt": 1787831362083, 2270 "createdAt": 1787831362083,
2271 "promptEn": "constable promises to get her out safely if she trusts him", 2271 "promptEn": "constable promises to get her out safely if she trusts him",
2272 - "lastPlayedAt": 1788251652757 2272 + "lastPlayedAt": 1788253719743
2273 }, 2273 },
2274 { 2274 {
2275 "id": "5ede61c01b22", 2275 "id": "5ede61c01b22",
@@ -2344,7 +2344,7 @@ @@ -2344,7 +2344,7 @@
2344 "likes": 0, 2344 "likes": 0,
2345 "createdAt": 1787762224218, 2345 "createdAt": 1787762224218,
2346 "promptEn": "constable stands under the lamp, holding her gaze through the screen, not backing away", 2346 "promptEn": "constable stands under the lamp, holding her gaze through the screen, not backing away",
2347 - "lastPlayedAt": 1788252377122 2347 + "lastPlayedAt": 1788253631690
2348 }, 2348 },
2349 { 2349 {
2350 "id": "f2e70205766b", 2350 "id": "f2e70205766b",
@@ -2404,7 +2404,7 @@ @@ -2404,7 +2404,7 @@
2404 "likes": 0, 2404 "likes": 0,
2405 "createdAt": 1787730331663, 2405 "createdAt": 1787730331663,
2406 "promptEn": "constable steps in from the rainy night, spots her, introduces himself with a cover story", 2406 "promptEn": "constable steps in from the rainy night, spots her, introduces himself with a cover story",
2407 - "lastPlayedAt": 1788249111414 2407 + "lastPlayedAt": 1788253781772
2408 }, 2408 },
2409 { 2409 {
2410 "id": "84e8337de242", 2410 "id": "84e8337de242",
@@ -2554,7 +2554,7 @@ @@ -2554,7 +2554,7 @@
2554 "likes": 0, 2554 "likes": 0,
2555 "createdAt": 1787708646888, 2555 "createdAt": 1787708646888,
2556 "promptEn": "constable studies her through the screen growing suspicious, hand drifting to his sword", 2556 "promptEn": "constable studies her through the screen growing suspicious, hand drifting to his sword",
2557 - "lastPlayedAt": 1788251602734 2557 + "lastPlayedAt": 1788253697730
2558 }, 2558 },
2559 { 2559 {
2560 "id": "1c0c203cfb3b", 2560 "id": "1c0c203cfb3b",
@@ -2839,7 +2839,7 @@ @@ -2839,7 +2839,7 @@
2839 "likes": 0, 2839 "likes": 0,
2840 "createdAt": 1787674609636, 2840 "createdAt": 1787674609636,
2841 "promptEn": "constable silently watches her through the screen gaps, camera slowly zooming in on her face", 2841 "promptEn": "constable silently watches her through the screen gaps, camera slowly zooming in on her face",
2842 - "lastPlayedAt": 1788249261479 2842 + "lastPlayedAt": 1788253983858
2843 }, 2843 },
2844 { 2844 {
2845 "id": "5e53f7f5fe9b", 2845 "id": "5e53f7f5fe9b",
@@ -2899,7 +2899,7 @@ @@ -2899,7 +2899,7 @@
2899 "likes": 0, 2899 "likes": 0,
2900 "createdAt": 1787674351536, 2900 "createdAt": 1787674351536,
2901 "promptEn": "constable searches an old house at night, candle flickering, woman hiding behind the screen", 2901 "promptEn": "constable searches an old house at night, candle flickering, woman hiding behind the screen",
2902 - "lastPlayedAt": 1788250201967 2902 + "lastPlayedAt": 1788253615680
2903 }, 2903 },
2904 { 2904 {
2905 "id": "dc13e4f165dc", 2905 "id": "dc13e4f165dc",
@@ -2914,7 +2914,7 @@ @@ -2914,7 +2914,7 @@
2914 "likes": 0, 2914 "likes": 0,
2915 "createdAt": 1787672849330, 2915 "createdAt": 1787672849330,
2916 "promptEn": "constable cautiously follows her silent gesture, hand near his sword, tracking her movement", 2916 "promptEn": "constable cautiously follows her silent gesture, hand near his sword, tracking her movement",
2917 - "lastPlayedAt": 1788252175018 2917 + "lastPlayedAt": 1788253645695
2918 }, 2918 },
2919 { 2919 {
2920 "id": "feb4df69e1a2", 2920 "id": "feb4df69e1a2",
@@ -3319,7 +3319,7 @@ @@ -3319,7 +3319,7 @@
3319 "likes": 0, 3319 "likes": 0,
3320 "createdAt": 1787577878370, 3320 "createdAt": 1787577878370,
3321 "promptEn": "man barges into the old house apologizing, woman in white behind the screen", 3321 "promptEn": "man barges into the old house apologizing, woman in white behind the screen",
3322 - "lastPlayedAt": 1788250294012 3322 + "lastPlayedAt": 1788253661702
3323 }, 3323 },
3324 { 3324 {
3325 "id": "0e75ef71c3d0", 3325 "id": "0e75ef71c3d0",
@@ -3438,7 +3438,7 @@ @@ -3438,7 +3438,7 @@
3438 "partition": "text", 3438 "partition": "text",
3439 "likes": 0, 3439 "likes": 0,
3440 "createdAt": 1787576358982, 3440 "createdAt": 1787576358982,
3441 - "lastPlayedAt": 1788246088963, 3441 + "lastPlayedAt": 1788253923842,
3442 "promptEn": "man apologizes, says something outside was chasing him" 3442 "promptEn": "man apologizes, says something outside was chasing him"
3443 }, 3443 },
3444 { 3444 {
@@ -3469,7 +3469,7 @@ @@ -3469,7 +3469,7 @@
3469 "likes": 0, 3469 "likes": 0,
3470 "createdAt": 1787575790848, 3470 "createdAt": 1787575790848,
3471 "promptEn": "man apologizes, says something outside was chasing him", 3471 "promptEn": "man apologizes, says something outside was chasing him",
3472 - "lastPlayedAt": 1788247283936 3472 + "lastPlayedAt": 1788253927842
3473 }, 3473 },
3474 { 3474 {
3475 "id": "5e6dcf2c8cfd", 3475 "id": "5e6dcf2c8cfd",
@@ -3589,7 +3589,7 @@ @@ -3589,7 +3589,7 @@
3589 "likes": 0, 3589 "likes": 0,
3590 "createdAt": 1787497396594, 3590 "createdAt": 1787497396594,
3591 "promptEn": "otome game male lead showcase PV", 3591 "promptEn": "otome game male lead showcase PV",
3592 - "lastPlayedAt": 1788250885690 3592 + "lastPlayedAt": 1788253932562
3593 }, 3593 },
3594 { 3594 {
3595 "id": "36ac12f2f29e", 3595 "id": "36ac12f2f29e",
@@ -3619,7 +3619,7 @@ @@ -3619,7 +3619,7 @@
3619 "likes": 0, 3619 "likes": 0,
3620 "createdAt": 1787493303602, 3620 "createdAt": 1787493303602,
3621 "promptEn": "game menu UI, character swaps out a mechanical arm", 3621 "promptEn": "game menu UI, character swaps out a mechanical arm",
3622 - "lastPlayedAt": 1788252523177 3622 + "lastPlayedAt": 1788253767768
3623 }, 3623 },
3624 { 3624 {
3625 "id": "e1fd99e4ab97", 3625 "id": "e1fd99e4ab97",
@@ -3889,7 +3889,7 @@ @@ -3889,7 +3889,7 @@
3889 "likes": 0, 3889 "likes": 0,
3890 "createdAt": 1787444313690, 3890 "createdAt": 1787444313690,
3891 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 3891 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
3892 - "lastPlayedAt": 1788250484120 3892 + "lastPlayedAt": 1788253967852
3893 }, 3893 },
3894 { 3894 {
3895 "id": "e56962bd770f", 3895 "id": "e56962bd770f",
@@ -3904,7 +3904,7 @@ @@ -3904,7 +3904,7 @@
3904 "likes": 0, 3904 "likes": 0,
3905 "createdAt": 1787442174982, 3905 "createdAt": 1787442174982,
3906 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 3906 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
3907 - "lastPlayedAt": 1788249819782 3907 + "lastPlayedAt": 1788253909828
3908 }, 3908 },
3909 { 3909 {
3910 "id": "18105bc2900b", 3910 "id": "18105bc2900b",
@@ -3934,7 +3934,7 @@ @@ -3934,7 +3934,7 @@
3934 "likes": 0, 3934 "likes": 0,
3935 "createdAt": 1787436029475, 3935 "createdAt": 1787436029475,
3936 "promptEn": "protagonist leaps across rooftops fleeing pursuers", 3936 "promptEn": "protagonist leaps across rooftops fleeing pursuers",
3937 - "lastPlayedAt": 1788243140456 3937 + "lastPlayedAt": 1788253665707
3938 }, 3938 },
3939 { 3939 {
3940 "id": "896859e59dae", 3940 "id": "896859e59dae",
@@ -4279,7 +4279,7 @@ @@ -4279,7 +4279,7 @@
4279 "likes": 0, 4279 "likes": 0,
4280 "createdAt": 1787367454065, 4280 "createdAt": 1787367454065,
4281 "promptEn": "golden portal opens, man in green jacket throws a glowing spear", 4281 "promptEn": "golden portal opens, man in green jacket throws a glowing spear",
4282 - "lastPlayedAt": 1788250848268 4282 + "lastPlayedAt": 1788253735749
4283 }, 4283 },
4284 { 4284 {
4285 "id": "e6c241be377f", 4285 "id": "e6c241be377f",
@@ -4324,7 +4324,7 @@ @@ -4324,7 +4324,7 @@
4324 "likes": 0, 4324 "likes": 0,
4325 "createdAt": 1787332996051, 4325 "createdAt": 1787332996051,
4326 "promptEn": "golden portal opens, man in green jacket throws a glowing spear", 4326 "promptEn": "golden portal opens, man in green jacket throws a glowing spear",
4327 - "lastPlayedAt": 1788250762247 4327 + "lastPlayedAt": 1788253717746
4328 }, 4328 },
4329 { 4329 {
4330 "id": "bf7d973d02a3", 4330 "id": "bf7d973d02a3",
@@ -4474,7 +4474,7 @@ @@ -4474,7 +4474,7 @@
4474 "likes": 0, 4474 "likes": 0,
4475 "createdAt": 1787290119529, 4475 "createdAt": 1787290119529,
4476 "promptEn": "misty Jiangnan old town at dawn, woman walking with an oil-paper umbrella", 4476 "promptEn": "misty Jiangnan old town at dawn, woman walking with an oil-paper umbrella",
4477 - "lastPlayedAt": 1788251302490 4477 + "lastPlayedAt": 1788253747759
4478 }, 4478 },
4479 { 4479 {
4480 "id": "06bb43196c46", 4480 "id": "06bb43196c46",
live.css
@@ -351,6 +351,57 @@ body { @@ -351,6 +351,57 @@ body {
351 .chat-input-row button:disabled { opacity: .5; cursor: not-allowed; } 351 .chat-input-row button:disabled { opacity: .5; cursor: not-allowed; }
352 .say-hint { padding: 2px 4px 0; font-size: 11.5px; font-weight: bold; color: var(--muted); min-height: 1.4em; } 352 .say-hint { padding: 2px 4px 0; font-size: 11.5px; font-weight: bold; color: var(--muted); min-height: 1.4em; }
353 353
  354 +/* ---- click-to-enter splash: branding + the gesture that unlocks sound ---- */
  355 +.splash {
  356 + position: fixed;
  357 + inset: 0;
  358 + z-index: 50;
  359 + display: flex;
  360 + align-items: center;
  361 + justify-content: center;
  362 + cursor: pointer;
  363 + background: radial-gradient(ellipse at center, rgba(0, 0, 0, .55), rgba(0, 0, 0, .35));
  364 +}
  365 +.splash-inner { text-align: center; padding: 20px; }
  366 +.splash-logo {
  367 + font-family: "Shrikhand", "Cooper Black", serif;
  368 + font-weight: 400;
  369 + font-size: min(64px, 11vw);
  370 + line-height: 1.2;
  371 + color: #fff;
  372 + -webkit-text-stroke: 3px #000;
  373 + paint-order: stroke fill;
  374 + text-shadow: 1px 1px 0 #000, 2px 2px 0 #000, 3px 3px 0 #000, 4px 4px 0 #000, 5px 5px 0 #000;
  375 + margin-bottom: 20px;
  376 +}
  377 +.splash-play {
  378 + width: 76px;
  379 + height: 76px;
  380 + margin: 0 auto 20px;
  381 + display: flex;
  382 + align-items: center;
  383 + justify-content: center;
  384 + border-radius: 50%;
  385 + background: #fff;
  386 + border: 3px solid #000;
  387 + box-shadow: var(--shadow);
  388 + font-size: 26px;
  389 + color: var(--ink);
  390 + padding-left: 5px;
  391 +}
  392 +.splash-sub {
  393 + font: bold 15px Tahoma, sans-serif;
  394 + color: #fff;
  395 + line-height: 1.6;
  396 + text-shadow: 0 1px 4px #000, 0 0 12px rgba(0, 0, 0, .8);
  397 +}
  398 +.splash-credit {
  399 + margin-top: 16px;
  400 + font: bold 13px Tahoma, sans-serif;
  401 + color: var(--accent);
  402 + text-shadow: 0 1px 4px #000;
  403 +}
  404 +
354 /* ---- nickname modal ---- */ 405 /* ---- nickname modal ---- */
355 .nickname-modal { 406 .nickname-modal {
356 position: fixed; 407 position: fixed;
live.html
@@ -65,6 +65,15 @@ @@ -65,6 +65,15 @@
65 </div> 65 </div>
66 </div> 66 </div>
67 67
  68 +<div class="splash" id="splash">
  69 + <div class="splash-inner">
  70 + <div class="splash-logo">AI 短剧频道</div>
  71 + <div class="splash-play">▶</div>
  72 + <div class="splash-sub">一个永不停播的 AI 生成短剧频道<br />弹幕决定下一集演什么</div>
  73 + <div class="splash-credit">🍋 AI 短剧频道 出品</div>
  74 + </div>
  75 +</div>
  76 +
68 <div class="nickname-modal" id="nicknameModal" hidden> 77 <div class="nickname-modal" id="nicknameModal" hidden>
69 <div class="nickname-box"> 78 <div class="nickname-box">
70 <div class="nickname-title">先起个昵称才能发言</div> 79 <div class="nickname-title">先起个昵称才能发言</div>
@@ -107,6 +116,7 @@ const nicknameConfirmBtn = document.getElementById(&quot;nicknameConfirmBtn&quot;); @@ -107,6 +116,7 @@ const nicknameConfirmBtn = document.getElementById(&quot;nicknameConfirmBtn&quot;);
107 const chatIdentityRow = document.getElementById("chatIdentityRow"); 116 const chatIdentityRow = document.getElementById("chatIdentityRow");
108 const changeNameBtn = document.getElementById("changeNameBtn"); 117 const changeNameBtn = document.getElementById("changeNameBtn");
109 const currentNickname = document.getElementById("currentNickname"); 118 const currentNickname = document.getElementById("currentNickname");
  119 +const splash = document.getElementById("splash");
110 const clientId = Math.random().toString(36).slice(2); 120 const clientId = Math.random().toString(36).slice(2);
111 121
112 muteBtn.addEventListener("click", () => { 122 muteBtn.addEventListener("click", () => {
@@ -125,6 +135,23 @@ function tryPlay() { @@ -125,6 +135,23 @@ function tryPlay() {
125 }); 135 });
126 } 136 }
127 137
  138 +// Click-to-enter splash (same trick as infiniteslop.ai): the video is already
  139 +// autoplaying muted underneath, and this click is the user gesture that lets
  140 +// us switch it to unmuted playback — the one reliable way around the browser's
  141 +// no-unmuted-autoplay-without-a-gesture policy. Also doubles as a branding
  142 +// moment (logo/slogan/credit) instead of a bare "click to unmute" prompt.
  143 +// Phones stay muted after entry — unmuted autoplay-adjacent playback on
  144 +// mobile Safari/Chrome is unreliable and feels intrusive.
  145 +splash.addEventListener("click", () => {
  146 + splash.remove();
  147 + const desktop = matchMedia("(min-width: 769px)").matches;
  148 + player.muted = !desktop;
  149 + player.play().catch(() => {
  150 + player.muted = true;
  151 + });
  152 + muteBtn.textContent = player.muted ? "🔇 静音" : "🔈 有声";
  153 +});
  154 +
128 let chatClosed = false; 155 let chatClosed = false;
129 chatToggleBtn.addEventListener("click", () => { 156 chatToggleBtn.addEventListener("click", () => {
130 chatClosed = !chatClosed; 157 chatClosed = !chatClosed;