diff options
Diffstat (limited to 'web/src/styles.css')
| -rw-r--r-- | web/src/styles.css | 181 |
1 files changed, 178 insertions, 3 deletions
diff --git a/web/src/styles.css b/web/src/styles.css index f7879e6..6a04db2 100644 --- a/web/src/styles.css +++ b/web/src/styles.css @@ -2538,7 +2538,7 @@ body::-webkit-scrollbar, .app::-webkit-scrollbar, #root::-webkit-scrollbar { by how much. */ .mp-standings { width: 100%; - max-width: 460px; + max-width: 560px; margin: 1.75rem auto 0 auto; display: flex; flex-direction: column; @@ -2556,7 +2556,7 @@ body::-webkit-scrollbar, .app::-webkit-scrollbar, #root::-webkit-scrollbar { .mp-standings-row { display: grid; - grid-template-columns: 1.75rem 1fr auto auto; + grid-template-columns: 1.75rem 1fr 3rem 3rem 4rem; align-items: center; gap: 0.75rem; padding: 0.4rem 0.75rem; @@ -2585,9 +2585,30 @@ body::-webkit-scrollbar, .app::-webkit-scrollbar, #root::-webkit-scrollbar { } .mp-standings-wpm, -.mp-standings-acc { +.mp-standings-acc, +.mp-standings-time { font-family: 'JetBrains Mono', monospace; white-space: nowrap; + text-align: right; +} + +/* Column labels, so the three numeric columns are readable without guessing + which is which. */ +.mp-standings-head { + font-size: 0.65rem; + text-transform: uppercase; + letter-spacing: 1px; + color: var(--sub-color); + padding-bottom: 0.15rem; + border: none; +} + +.mp-standings-head span:nth-child(n+3) { + text-align: right; +} + +.mp-standings-max-width { + max-width: 560px; } /* Still typing: no place yet, so the row shows how far along they are. */ @@ -2745,3 +2766,157 @@ body::-webkit-scrollbar, .app::-webkit-scrollbar, #root::-webkit-scrollbar { .stats-screen { position: relative; } + +/* The per-key weakness data Practice mode is built on. It drove text + generation but was never shown, so nobody could see what it had learned + about their typing. */ +.weak-key-list { + display: flex; + flex-wrap: wrap; + justify-content: center; + gap: 0.5rem; + width: 100%; +} + +.weak-key { + display: flex; + flex-direction: column; + align-items: center; + gap: 0.15rem; + min-width: 3.25rem; + padding: 0.5rem 0.4rem; + border: 1px solid var(--neutral-color); + border-radius: 6px; +} + +.weak-key-char { + font-family: 'JetBrains Mono', monospace; + font-size: 1.15rem; + color: var(--primary-color); +} + +.weak-key-err { + font-size: 0.7rem; + color: var(--error-color); +} + +.weak-key-lat { + font-size: 0.65rem; + color: var(--sub-color); +} + +/* Recent form against the lifetime average. */ +.stat-trend { + font-size: 0.7rem; + margin-left: 0.3rem; + vertical-align: middle; +} + +.stat-trend.up { color: var(--primary-color); } +.stat-trend.down { color: var(--error-color); } + +/* Marks a leaderboard row as a practice opponent rather than a human result. + The board is seeded so a new player has something to measure against, and + saying so is the difference between seeding it and faking it. */ +.leaderboard-bot-badge { + font-size: 0.65rem; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--sub-color); + border: 1px solid var(--neutral-color); + border-radius: 4px; + padding: 0.1rem 0.35rem; +} + +.leaderboard-name:disabled { + cursor: default; + opacity: 1; +} + +/* A longer body than a one-line placeholder: keep its line breaks and give it + a readable measure. */ +.stats-placeholder.prose { + white-space: pre-wrap; + text-align: left; + max-width: 46rem; + line-height: 1.6; +} + +/* Source, privacy and share, at the foot of the menu. One line rather than a + page: there is little to say and a whole screen would overstate it. */ +.site-footer { + position: fixed; + bottom: 1rem; + left: 50%; + transform: translateX(-50%); + z-index: 90; + display: flex; + align-items: center; + gap: 0.6rem; + font-size: 0.75rem; + color: var(--sub-color); +} + +.site-footer-link { + background: none; + border: none; + padding: 0.25rem; + font-family: inherit; + font-size: 0.75rem; + color: var(--sub-color); + text-decoration: none; + cursor: pointer; + border-radius: 4px; + transition: color 0.15s ease; +} + +.site-footer-link:hover { + color: var(--primary-color); +} + +.site-footer-sep, +.site-footer-version { + opacity: 0.6; +} + +/* ---- Button hierarchy ------------------------------------------------- + Everything was .menu-button, .menu-button.small or .menu-button.ghost -- + three variants that all render as an outlined box of roughly equal weight. + A screen's one real action, a settings toggle and a filter chip were + indistinguishable at a glance. + + Three tiers instead: + .primary the single action a screen exists for. Filled. + (default) supporting actions. Outlined. + .quiet toggles and filters, which are settings rather than actions. + No border until hovered or active. */ +.menu-button.primary { + background: var(--primary-color); + color: var(--background-color); + border-color: var(--primary-color); + font-weight: 700; +} + +.menu-button.primary:hover:not(:disabled) { + background: var(--secondary-color); + border-color: var(--secondary-color); + color: var(--background-color); +} + +.menu-button.quiet { + border-color: transparent; + color: var(--sub-color); + min-width: 0; +} + +.menu-button.quiet:hover:not(:disabled) { + background: none; + color: var(--text-color); + border-color: color-mix(in srgb, var(--primary-color) 35%, transparent); +} + +/* A toggle that is currently on reads as selected, not as pressable. */ +.menu-button.quiet.active { + color: var(--primary-color); + border-color: var(--primary-color); +} |