style.css 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721
  1. #container {
  2. --base-color: white;
  3. --highlight-color: red;
  4. --contrast-color: black;
  5. --base-font-size: 16px;
  6. position: relative;
  7. color: var(--base-color);
  8. font-family: sans;
  9. }
  10. #container:-webkit-full-screen {
  11. width: 100%;
  12. height: 100%;
  13. }
  14. #container div {
  15. pointer-events: none;
  16. user-select: none;
  17. }
  18. /* components {{{ */
  19. /* background switcher {{{ */
  20. #background {
  21. background-color: black;
  22. }
  23. #background div {
  24. position: absolute;
  25. height: 100%;
  26. width: 100%;
  27. opacity: 0;
  28. transition: opacity 0.5s linear;
  29. background-size: cover;
  30. }
  31. #background div.image {
  32. filter: brightness(70%) contrast(70%);
  33. }
  34. #background div.show {
  35. opacity: 1;
  36. }
  37. #background div#video {
  38. transition: none;
  39. height: 200%;
  40. bottom: -50%;
  41. right: 0;
  42. }
  43. #background div#video.settled {
  44. transition: none;
  45. pointer-events: auto;
  46. height: 70%;
  47. width: 70%;
  48. bottom: 0.5em;
  49. right: 0.5em;
  50. box-sizing: content-box;
  51. padding: 1px;
  52. border: solid 1px white;
  53. }
  54. /* }}} */
  55. /* progress bar {{{ */
  56. .progress-bar {
  57. position: relative;
  58. height: 0.3125em;
  59. }
  60. .progress-bar .bg {
  61. position: absolute;
  62. width: 100%;
  63. height: 0.3125em;
  64. background-color: var(--base-color);
  65. opacity: 0.5;
  66. }
  67. .progress-bar .shade {
  68. position: absolute;
  69. height: 0.3125em;
  70. background-color: var(--base-color);
  71. }
  72. /* }}} */
  73. /* }}} */
  74. /* main layout {{{ */
  75. /* base {{{ */
  76. #container {
  77. display: grid;
  78. grid-template-columns: [start] 18.75em [left] auto [right] 18.75em [end];
  79. grid-template-rows: [top] 3.125em [header] auto [game] 12.5em [bottom];
  80. font-size: var(--base-font-size);
  81. height: 450px;
  82. width: 800px;
  83. margin: 0 auto;
  84. overflow: hidden;
  85. }
  86. #container > div {
  87. overflow: hidden;
  88. position: relative;
  89. transition: top 0.5s, left 0.5s, opacity 0.5s;
  90. opacity: 0;
  91. }
  92. #container #background {
  93. opacity: 1;
  94. grid-column: start / end;
  95. grid-row: top / bottom;
  96. }
  97. #loading {
  98. grid-column: start / end;
  99. grid-row: top / bottom;
  100. align-self: center;
  101. justify-self: center;
  102. }
  103. #song-info {
  104. grid-column: start / right;
  105. grid-row: top / bottom;
  106. left: -31.25em;
  107. }
  108. #container #song-info div {
  109. /* override default */
  110. pointer-events: auto;
  111. }
  112. #song-list {
  113. grid-column: right / end;
  114. grid-row: top / bottom;
  115. left: 18.75em;
  116. }
  117. #container div#song-list {
  118. /* override default */
  119. pointer-events: auto;
  120. }
  121. #folder-info {
  122. grid-column: start / left;
  123. grid-row: top / header;
  124. left: -31.25em;
  125. }
  126. #game {
  127. top: 11.25em;
  128. grid-column: start / end;
  129. grid-row: game / bottom;
  130. }
  131. #score {
  132. grid-column: start / left;
  133. grid-row: header / bottom;
  134. left: -18.75em;
  135. }
  136. #loader {
  137. top: -3.125em;
  138. grid-column: right / end;
  139. grid-row: top / header;
  140. }
  141. #ready {
  142. grid-column: start / end;
  143. grid-row: top / bottom;
  144. align-self: center;
  145. justify-self: center;
  146. }
  147. /* }}} */
  148. /* loading {{{ */
  149. #container.loading #loading {
  150. opacity: 1;
  151. }
  152. #container.loading #loading.finished {
  153. opacity: 0;
  154. }
  155. #container.loading #song-info,
  156. #container.loading #folder-info {
  157. top: 3.125em;
  158. left: 0;
  159. }
  160. #container.loading #song-list {
  161. left: 3.125em;
  162. }
  163. /* }}} */
  164. /* select {{{ */
  165. #container.select #song-info,
  166. #container.select #folder-info {
  167. opacity: 1;
  168. top: 0;
  169. left: 0;
  170. }
  171. #container.select #song-list {
  172. opacity: 1;
  173. left: 0;
  174. }
  175. /* }}} */
  176. /* game {{{ */
  177. #container.game #folder-info {
  178. opacity: 1;
  179. top: 0;
  180. left: -31.25em;
  181. }
  182. #container.game #song-info {
  183. opacity: 1;
  184. top: -9.375em;
  185. left: 0;
  186. }
  187. #container.game.game-loading #loader {
  188. opacity: 1;
  189. top: 0;
  190. }
  191. #container.game.game-loading #ready {
  192. opacity: 1;
  193. }
  194. #container.game.game-playing #game {
  195. opacity: 1;
  196. top: 0;
  197. }
  198. #container.game.game-finished #score {
  199. opacity: 1;
  200. left: 0;
  201. }
  202. #container.game.game-finished #background div#video {
  203. transition: height 0.5s, width 0.5s, bottom 0.5s, right 0.5s;
  204. height: 70%;
  205. width: 70%;
  206. bottom: 0.5em;
  207. right: 0.5em;
  208. box-sizing: content-box;
  209. padding: 1px;
  210. border: solid 1px white;
  211. }
  212. /* }}} */
  213. /* }}} */
  214. /* sub layouts {{{ */
  215. /* select-screen {{{ */
  216. /* folder-info {{{ */
  217. #folder-info {
  218. display: flex;
  219. flex-direction: row;
  220. align-items: center;
  221. }
  222. #folder-info .left,
  223. #folder-info .right {
  224. /* override default */
  225. pointer-events: auto;
  226. }
  227. #folder-info .left:hover,
  228. #folder-info .right:hover {
  229. text-shadow: 0em 0em 0.3125em var(--base-color);
  230. }
  231. #folder-info .material-icons {
  232. font-size: 1.5em;
  233. }
  234. /* }}} */
  235. /* song-info {{{ */
  236. #song-info {
  237. margin-top: 9.5em;
  238. margin-left: 1.25em;
  239. }
  240. .song-info {
  241. text-shadow: 0em 0em 0.3125em var(--contrast-color);
  242. }
  243. .song-info div {
  244. white-space: nowrap;
  245. overflow: hidden;
  246. text-overflow: ellipsis;
  247. }
  248. .song-info .genre {
  249. font-size: 0.75em;
  250. height: 1.5em;
  251. }
  252. .song-info .creator {
  253. font-size: 1.25em;
  254. height: 1.5em;
  255. }
  256. .song-info .title {
  257. font-size: 1.875em;
  258. height: 1.5em;
  259. }
  260. .song-info .link a {
  261. color: var(--base-color);
  262. }
  263. /* }}} */
  264. /* song-list {{{ */
  265. .song-list {
  266. margin-left: 1.25em;
  267. transition: margin-top 0.2s;
  268. }
  269. .song-item {
  270. height: 2.5em;
  271. display: grid;
  272. grid-template-columns: 2.5em auto;
  273. grid-template-rows: 1em 1.5em;
  274. grid-template-areas:
  275. 'diff creator'
  276. 'diff title';
  277. transition: margin-left 0.2s;
  278. }
  279. #container div.song-item {
  280. /* override default */
  281. pointer-events: auto;
  282. }
  283. .song-item div {
  284. white-space: nowrap;
  285. overflow: hidden;
  286. text-overflow: ellipsis;
  287. line-height: 1;
  288. }
  289. .song-item .difficulty {
  290. grid-area: diff;
  291. align-self: end;
  292. justify-self: end;
  293. margin-bottom: 0.375em;
  294. margin-right: 0.375em;
  295. font-style: italic;
  296. font-weight: bold;
  297. text-shadow: none;
  298. }
  299. .song-item .difficulty-bg {
  300. grid-area: diff;
  301. align-self: center;
  302. justify-self: center;
  303. height: 1.875em;
  304. width: 1.875em;
  305. background: radial-gradient(
  306. circle at 10% 10%,
  307. rgba(0, 255, 255, 1),
  308. transparent
  309. );
  310. border-radius: 20%;
  311. opacity: 0;
  312. transition: opacity 0.2s ease-in-out;
  313. }
  314. .song-item .difficulty-bg.normal {
  315. background: radial-gradient(
  316. circle at 10% 10%,
  317. rgba(255, 255, 255, 0.6),
  318. transparent
  319. );
  320. opacity: 1;
  321. }
  322. .song-item:hover {
  323. text-shadow: 0em 0em 0.3125em var(--base-color);
  324. }
  325. .song-item.selected {
  326. margin-left: -0.625em;
  327. text-shadow: 0em 0em 0.3125em var(--base-color);
  328. }
  329. .song-item.selected .difficulty-bg {
  330. opacity: 1;
  331. box-shadow: -0.0625em -0.0625em 0.625em -0.125em var(--base-color);
  332. }
  333. .song-item.selected .difficulty-bg.normal {
  334. opacity: 0;
  335. }
  336. .song-item .creator {
  337. grid-area: creator;
  338. font-size: 0.75em;
  339. }
  340. .song-item .title {
  341. grid-area: title;
  342. font-size: 1.25em;
  343. }
  344. /* }}} */
  345. /* }}} */
  346. /* game-screen {{{ */
  347. /* loading-screen {{{ */
  348. #loader {
  349. display: flex;
  350. flex-direction: column;
  351. justify-content: center;
  352. align-items: center;
  353. }
  354. #loader .progress-bar {
  355. width: 80%;
  356. }
  357. #loader .progress-bar .shade {
  358. transition: width 0.2s;
  359. }
  360. #ready {
  361. display: flex;
  362. flex-direction: column;
  363. align-items: center;
  364. }
  365. #ready .status {
  366. font-size: 1.875em;
  367. }
  368. #ready .message {
  369. font-size: 0.875em;
  370. }
  371. /* }}} */
  372. /* track-progress {{{ */
  373. .track-progress {
  374. display: grid;
  375. grid-template-columns: max-content auto;
  376. grid-template-rows: 50% 50%;
  377. grid-template-areas:
  378. 'tl tb'
  379. 'il ib';
  380. grid-gap: 0em 0.625em;
  381. align-items: center;
  382. align-self: end;
  383. }
  384. .track-progress .total-label,
  385. .track-progress .interval-label {
  386. justify-self: right;
  387. font-variant-caps: small-caps;
  388. font-size: 0.75em;
  389. }
  390. .track-progress .total-label {
  391. grid-area: tl;
  392. }
  393. .track-progress .interval-label {
  394. grid-area: il;
  395. justify-self: right;
  396. }
  397. .track-progress .total {
  398. grid-area: tb;
  399. }
  400. .track-progress .interval {
  401. grid-area: ib;
  402. }
  403. /* }}} */
  404. /* typing area {{{ */
  405. #game {
  406. display: grid;
  407. grid-template-columns: 3.125em 3.125em auto;
  408. grid-template-rows: 2.5em 1.5em 0.75em 1.875em auto 1.375em;
  409. grid-template-areas:
  410. '. . track'
  411. 'score score score'
  412. '. . kana'
  413. '. . kanji'
  414. 'romaji-first romaji romaji'
  415. 'skip skip stats';
  416. grid-row-gap: 0.125em;
  417. padding: 1.25em 1.25em 0.125em 1.25em;
  418. background: linear-gradient(transparent, rgba(0, 0, 0, 0.8));
  419. }
  420. #game .track-progress {
  421. grid-area: track;
  422. }
  423. #game .score-line {
  424. grid-area: score;
  425. }
  426. #game .kana-line {
  427. grid-area: kana;
  428. margin-left: 0.9375em;
  429. }
  430. #game .kanji-line {
  431. grid-area: kanji;
  432. padding-left: 0.3125em;
  433. border-bottom: solid 0.125em rgba(255, 255, 255, 0.5);
  434. border-left: solid 0.625em rgba(255, 255, 255, 0.5);
  435. border-radius: 0em 0em 0em 0.625em;
  436. }
  437. #game .stats-line {
  438. grid-area: stats;
  439. }
  440. #game .romaji-first,
  441. #game .romaji-line {
  442. text-transform: uppercase;
  443. align-self: baseline;
  444. line-height: 1;
  445. }
  446. #game .romaji-first {
  447. grid-area: romaji-first;
  448. justify-self: right;
  449. font-size: 2.25em;
  450. padding: 0em 0.05ex;
  451. }
  452. #game .romaji-line {
  453. grid-area: romaji;
  454. font-size: 1.25em;
  455. }
  456. #game .romaji-first.error {
  457. animation: pulse 0.2s;
  458. }
  459. #game .skip-notice {
  460. grid-area: skip;
  461. opacity: 0;
  462. font-size: 0.875em;
  463. }
  464. #game.skippable .skip-notice {
  465. animation: 1.5s flash 0s 2;
  466. }
  467. /* }}} */
  468. /* score area {{{ */
  469. .score-line {
  470. display: flex;
  471. }
  472. .score-line .pair,
  473. .stats-line .pair {
  474. margin: 0em 0.25em;
  475. border-bottom: solid 0.125em rgba(255, 255, 255, 0.5);
  476. border-radius: 0.125em;
  477. }
  478. .score-line .pair span,
  479. .stats-line .pair span {
  480. text-align: right;
  481. padding: 0em 0.25em;
  482. }
  483. .score-line .combo {
  484. flex: none;
  485. width: 6.25em;
  486. text-align: left;
  487. }
  488. .score-line .pair {
  489. flex: 1;
  490. display: flex;
  491. }
  492. .stats-line {
  493. display: flex;
  494. justify-content: flex-end;
  495. }
  496. .stats-line .pair span {
  497. font-size: 0.875em;
  498. }
  499. .stats-line .pair .value {
  500. display: inline-block;
  501. min-width: 3.125em;
  502. }
  503. /* }}} */
  504. /* score screen {{{ */
  505. #score {
  506. display: grid;
  507. grid-template-columns: max-content auto;
  508. align-items: baseline;
  509. align-content: end;
  510. grid-gap: 0.3125em;
  511. padding: 1.25em;
  512. }
  513. #score .class,
  514. #score .score {
  515. text-shadow: 0em 0em 0.3125em var(--highlight-color);
  516. }
  517. #score .class {
  518. font-size: 2.5em;
  519. }
  520. #score .score {
  521. font-size: 1.5em;
  522. }
  523. /* }}} */
  524. .kana {
  525. display: inline-block;
  526. position: relative;
  527. white-space: pre;
  528. font-size: 0.75em;
  529. }
  530. .kana::after {
  531. display: inline-block;
  532. content: attr(data-text);
  533. position: absolute;
  534. left: 0;
  535. top: 0;
  536. color: var(--highlight-color);
  537. font-weight: bold;
  538. overflow: hidden;
  539. width: 0em;
  540. transition: width 0.1s;
  541. }
  542. .kana.half::after {
  543. width: 50%;
  544. }
  545. .kana.full::after {
  546. width: 100%;
  547. }
  548. @keyframes pulse {
  549. 0% {
  550. color: var(--base-color);
  551. }
  552. 50% {
  553. color: red;
  554. }
  555. 100% {
  556. color: var(--base-color);
  557. }
  558. }
  559. @keyframes flash {
  560. 0% {
  561. opacity: 0;
  562. }
  563. 50% {
  564. opacity: 1;
  565. }
  566. 100% {
  567. opacity: 0;
  568. }
  569. }
  570. #game.waiting .kana-line,
  571. #game.waiting .kanji-line {
  572. opacity: 0.5;
  573. }
  574. #game.waiting .romaji-first,
  575. #game.waiting .romaji-line {
  576. color: transparent;
  577. }
  578. /* }}} */
  579. /* }}} */