srdusr
aboutsummaryrefslogtreecommitdiffstats
path: root/web/src/styles.css
diff options
context:
space:
mode:
Diffstat (limited to 'web/src/styles.css')
-rw-r--r--web/src/styles.css181
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);
+}