From 6ddc3985ae9c4c9aa623a06a2d933b13dc22c937 Mon Sep 17 00:00:00 2001
From: Kalle <38327916+Sendouc@users.noreply.github.com>
Date: Thu, 17 Sep 2026 17:34:36 +0300
Subject: [PATCH] Initial
---
AGENTS.md | 1 +
app/components/InfoPopover.module.css | 6 ++
app/components/IngameNameInput.module.css | 6 +-
app/components/MobileNav.module.css | 49 ++++++++++---
app/components/Pagination.module.css | 21 +++---
app/components/RankTable.module.css | 6 +-
app/components/SideNav.module.css | 1 +
app/components/SortableTableHeader.module.css | 19 +++--
app/components/StreamListItems.module.css | 10 ++-
app/components/SubNav.module.css | 15 ++++
app/components/Table.module.css | 4 --
app/components/Table.tsx | 15 +---
app/components/elements/Button.module.css | 72 +++++++++++++------
app/components/elements/Calendar.module.css | 24 ++++---
app/components/elements/ChipRadio.module.css | 18 +++++
app/components/elements/Menu.module.css | 5 +-
app/components/elements/Select.module.css | 12 ++++
app/components/elements/Switch.module.css | 18 ++++-
app/components/elements/Tabs.module.css | 13 +++-
app/components/elements/Toast.module.css | 4 --
.../filter-bar/FilterBar.module.css | 25 +++++--
app/components/layout/ChatSidebar.module.css | 30 ++++++--
app/components/layout/Footer.module.css | 2 +
app/components/layout/GlobalSearch.module.css | 3 +-
.../layout/NotificationPopover.module.css | 6 +-
.../layout/SearchResults.module.css | 1 +
app/components/layout/TopNavMenus.module.css | 1 +
app/components/layout/WeaponSearch.module.css | 7 +-
app/components/layout/index.module.css | 22 +++++-
.../match-page/MatchActionTab.module.css | 4 +-
.../match-page/MatchRosterTab.module.css | 2 +-
.../match-page/MatchTimeline.module.css | 9 ++-
.../match-page/WeaponPool.module.css | 10 +++
.../art/components/ArtGrid.module.css | 7 +-
.../components/ScheduleTracks.module.css | 11 ++-
.../WeekAvailabilityEditor.module.css | 7 +-
.../build-analyzer/routes/analyzer.module.css | 4 +-
.../components/TournamentCard.module.css | 7 +-
.../calendar/routes/calendar.module.css | 15 ++++
app/features/chat/components/Chat.module.css | 2 +-
.../components/DamageComboBar.module.css | 41 ++++++++---
.../components/RangeVisualization.module.css | 10 ++-
.../components/SelectedWeapons.module.css | 10 ++-
.../components/WeaponGrid.module.css | 15 ++--
app/features/info/routes/support.module.css | 3 +-
app/features/info/routes/welcome.module.css | 12 +++-
.../lfg/components/LFGPost.module.css | 1 +
.../map-planner/components/Planner.module.css | 12 +++-
.../components/NotificationList.module.css | 8 ++-
.../object-damage-calculator.module.css | 6 ++
.../params/components/WeaponKits.module.css | 11 ++-
.../components/WeaponParamsTable.module.css | 5 +-
.../components/FixturesPage.module.css | 5 ++
.../scanner/components/FrameThumb.module.css | 9 ++-
.../scanner/components/LivePage.module.css | 6 ++
.../scanner/components/MatchCard.module.css | 13 ++--
.../scanner/components/ScannerApp.module.css | 7 +-
.../components/ScannerChrome.module.css | 6 +-
.../scanner/components/VodPage.module.css | 7 +-
.../components/ScrimAvailability.module.css | 4 --
.../scrims/components/ScrimCard.module.css | 6 +-
.../sendouq/components/GroupCard.module.css | 5 +-
app/features/sendouq/routes/q.module.css | 6 +-
.../components/ModeMapPoolPicker.module.css | 6 +-
.../PreferenceRadioGroup.module.css | 11 +--
.../team/routes/t.$customUrl.index.module.css | 1 +
.../team/routes/t.$customUrl.module.css | 1 +
.../components/ItemPool.module.css | 11 +--
.../components/TierRow.module.css | 27 ++++---
.../tier-list-maker/components/TierRow.tsx | 6 +-
.../routes/to.$id.admin.seeds.module.css | 8 ++-
.../components/Bracket/Match.module.css | 9 +--
.../BracketMapListDialog.module.css | 5 +-
.../components/CustomFlowBuilder.module.css | 7 +-
.../routes/to.$id.divisions.module.css | 1 +
.../components/BannedPlayersList.module.css | 6 +-
.../routes/org.$slug.module.css | 1 +
.../components/TournamentNav.module.css | 10 ++-
.../routes/to.$id.results.module.css | 1 +
.../tournament/routes/to.$id.results.tsx | 2 +-
.../TournamentSummaryRow.module.css | 5 +-
.../components/MutualFriends.module.css | 1 +
.../components/SubPageHeader.module.css | 8 ++-
.../components/UserPageIconNav.module.css | 8 ++-
.../user-page/components/Widget.module.css | 23 ++++--
.../u.$identifier.seasons.index.module.css | 6 +-
app/styles/common.css | 4 ++
app/styles/front.module.css | 70 ++++++++++++------
.../2026-09-16-consistent-hover-feedback.md | 8 +++
docs/dev/styling.md | 19 +++++
90 files changed, 707 insertions(+), 260 deletions(-)
create mode 100644 changelog/2026-09-16-consistent-hover-feedback.md
create mode 100644 docs/dev/styling.md
diff --git a/AGENTS.md b/AGENTS.md
index 71ba99c07..83a992c95 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -56,6 +56,7 @@
## Styling
- use CSS modules
+- hover/focus/selected state rules are in [styling.md](./docs/dev/styling.md)
- one file containing React code should have a matching CSS module file e.g. `Component.tsx` should have a file with the same root name i.e. `Component.module.css`
- prefer using [CSS variables](./app/styles/vars.css) for theming
- for any CSS variable used, make sure it is defined either locally or in the `vars.css` file
diff --git a/app/components/InfoPopover.module.css b/app/components/InfoPopover.module.css
index d56d2ad05..7902db0d3 100644
--- a/app/components/InfoPopover.module.css
+++ b/app/components/InfoPopover.module.css
@@ -10,6 +10,12 @@
display: flex;
align-items: center;
justify-content: center;
+ transition: background-color 0.15s;
+
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
+ }
&:focus-visible {
outline: var(--focus-ring);
diff --git a/app/components/IngameNameInput.module.css b/app/components/IngameNameInput.module.css
index e58e3574b..677679a1c 100644
--- a/app/components/IngameNameInput.module.css
+++ b/app/components/IngameNameInput.module.css
@@ -47,9 +47,11 @@
color: var(--color-text);
font-size: var(--font-sm);
cursor: pointer;
+ transition: background-color 0.15s;
- &:hover {
- background-color: var(--color-bg-higher);
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
}
&:focus-visible {
diff --git a/app/components/MobileNav.module.css b/app/components/MobileNav.module.css
index dd94c3f57..2b8620c64 100644
--- a/app/components/MobileNav.module.css
+++ b/app/components/MobileNav.module.css
@@ -51,14 +51,21 @@
font-weight: var(--weight-semi);
cursor: pointer;
text-decoration: none;
- transition: color 0.15s;
+ transition:
+ background-color 0.15s,
+ color 0.15s;
+
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
+ color: var(--color-text);
+ }
&:focus-visible {
outline: var(--focus-ring);
outline-offset: -1px;
}
- &:hover,
&[data-active="true"] {
color: var(--color-text-accent);
}
@@ -235,10 +242,16 @@
aspect-ratio: 1 / 1;
border-radius: var(--radius-field);
margin-inline-start: auto;
+ transition: background-color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-higher);
}
+
+ &:focus-visible {
+ outline: var(--focus-ring);
+ }
}
.panelIconContainer {
@@ -278,10 +291,6 @@
font-size: var(--font-xs);
font-weight: var(--weight-semi);
text-align: center;
-
- &:hover {
- color: var(--color-text-accent);
- }
}
.navItemImage {
@@ -291,6 +300,16 @@
background-color: var(--color-bg-higher);
display: grid;
place-items: center;
+ transition: background-color 0.15s;
+
+ .navItem:hover &,
+ .navItem:focus-visible & {
+ background-color: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
+ }
}
.youPanelUserRow {
@@ -309,8 +328,10 @@
text-decoration: none;
color: var(--color-text);
border-radius: var(--radius-field);
+ transition: background-color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-high);
}
}
@@ -329,8 +350,12 @@
border-radius: var(--radius-field);
height: var(--field-size);
aspect-ratio: 1 / 1;
+ transition:
+ background-color 0.15s,
+ color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-high);
color: var(--color-text);
}
@@ -361,12 +386,16 @@
padding: 0 var(--s-3);
background-color: var(--color-bg-high);
border-radius: var(--radius-selector);
+ transition:
+ background-color 0.15s,
+ color 0.15s;
& svg {
stroke-width: 3;
}
- &:hover {
+ &:hover,
+ &:focus-visible {
color: var(--color-text);
background-color: var(--color-bg-higher);
}
diff --git a/app/components/Pagination.module.css b/app/components/Pagination.module.css
index 84eda0246..eccef8681 100644
--- a/app/components/Pagination.module.css
+++ b/app/components/Pagination.module.css
@@ -21,10 +21,11 @@
color: var(--color-text);
cursor: pointer;
border-radius: var(--radius-full);
- transition: opacity 0.15s ease;
+ transition: background-color 0.15s;
- &:hover:not(:disabled) {
- opacity: 0.7;
+ &:hover:not(:disabled),
+ &:focus-visible {
+ background-color: var(--color-bg-high);
}
&:disabled {
@@ -47,10 +48,11 @@
font-weight: var(--weight-semi);
cursor: pointer;
border-radius: var(--radius-full);
- transition: background-color 0.15s ease;
+ transition: background-color 0.15s;
- &:hover:not(.pageActive) {
- background-color: var(--color-bg-higher);
+ &:hover:not(.pageActive),
+ &:focus-visible:not(.pageActive) {
+ background-color: var(--color-bg-high);
}
}
@@ -74,10 +76,11 @@
background: transparent;
cursor: pointer;
border-radius: var(--radius-full);
- transition: background-color 0.15s ease;
+ transition: background-color 0.15s;
- &:hover {
- background-color: var(--color-bg-higher);
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
}
}
diff --git a/app/components/RankTable.module.css b/app/components/RankTable.module.css
index bf078d0ee..37de04aa7 100644
--- a/app/components/RankTable.module.css
+++ b/app/components/RankTable.module.css
@@ -18,8 +18,9 @@
align-items: center;
justify-content: space-between;
color: var(--color-text);
- transition: 0.1s ease-in-out background-color;
+ transition: background-color 0.15s;
border-radius: 0;
+ text-decoration: none;
&:first-of-type {
border-radius: var(--radius-box) var(--radius-box) 0 0;
@@ -53,7 +54,8 @@
font-size: var(--font-xs);
}
-a.row:hover {
+a.row:hover,
+a.row:focus-visible {
background-color: var(--color-bg-higher);
}
diff --git a/app/components/SideNav.module.css b/app/components/SideNav.module.css
index cf0b2cf18..f59710179 100644
--- a/app/components/SideNav.module.css
+++ b/app/components/SideNav.module.css
@@ -218,6 +218,7 @@
& a {
color: var(--color-text-high);
text-decoration: none;
+ transition: color 0.15s;
&:hover {
color: var(--color-text);
diff --git a/app/components/SortableTableHeader.module.css b/app/components/SortableTableHeader.module.css
index 9cadb766b..1ba688c7d 100644
--- a/app/components/SortableTableHeader.module.css
+++ b/app/components/SortableTableHeader.module.css
@@ -4,11 +4,23 @@
gap: var(--s-1);
background: none;
border: none;
- padding: 0;
+ padding: 0 var(--s-1);
+ margin-inline: calc(-1 * var(--s-1));
+ border-radius: var(--radius-field);
font: inherit;
color: inherit;
cursor: pointer;
text-transform: inherit;
+ transition: background-color 0.15s;
+
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
+ }
+
+ &:focus-visible {
+ outline: var(--focus-ring);
+ }
}
.sortIcon {
@@ -18,9 +30,4 @@
.sortIconInactive {
opacity: 0.4;
-
- .sortHeader:hover &,
- .sortHeader:focus-visible & {
- opacity: 0.85;
- }
}
diff --git a/app/components/StreamListItems.module.css b/app/components/StreamListItems.module.css
index 83eb80e81..7d73901e9 100644
--- a/app/components/StreamListItems.module.css
+++ b/app/components/StreamListItems.module.css
@@ -50,9 +50,17 @@
height: var(--selector-size-sm);
aspect-ratio: 1 / 1;
border-radius: var(--radius-selector);
+ transition:
+ background-color 0.15s,
+ color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
color: var(--color-text);
background-color: var(--color-bg-higher);
}
+
+ &:focus-visible {
+ outline: var(--focus-ring);
+ }
}
diff --git a/app/components/SubNav.module.css b/app/components/SubNav.module.css
index 25182e85a..b608f84bc 100644
--- a/app/components/SubNav.module.css
+++ b/app/components/SubNav.module.css
@@ -19,6 +19,7 @@
align-items: center;
color: var(--color-text);
gap: var(--s-1-5);
+ text-decoration: none;
&.active {
color: var(--color-text-accent);
@@ -39,6 +40,14 @@
font-size: var(--font-xs);
text-align: center;
white-space: nowrap;
+ transition:
+ background-color 0.15s,
+ color 0.15s;
+
+ .linkContainer:hover &,
+ .linkContainer:focus-visible & {
+ background-color: var(--color-bg-higher);
+ }
}
.linkSecondary {
@@ -48,6 +57,12 @@
font-size: var(--font-xs);
color: var(--color-text-high);
background-color: transparent;
+
+ .linkContainer:hover &,
+ .linkContainer:focus-visible & {
+ background-color: var(--color-bg-high);
+ color: var(--color-text);
+ }
}
.borderGuy {
diff --git a/app/components/Table.module.css b/app/components/Table.module.css
index dedb97e4f..3527d9dff 100644
--- a/app/components/Table.module.css
+++ b/app/components/Table.module.css
@@ -17,10 +17,6 @@
font-size: var(--font-2xs);
}
- &:not(.noRowHover) tbody tr:hover {
- background-color: var(--color-bg-high);
- }
-
& > thead > tr > th {
padding: var(--s-2);
}
diff --git a/app/components/Table.tsx b/app/components/Table.tsx
index 8a6e937c1..11b174d68 100644
--- a/app/components/Table.tsx
+++ b/app/components/Table.tsx
@@ -1,20 +1,9 @@
-import clsx from "clsx";
import styles from "./Table.module.css";
-export function Table({
- children,
- noRowHover,
-}: {
- children: React.ReactNode;
- noRowHover?: boolean;
-}) {
+export function Table({ children }: { children: React.ReactNode }) {
return (
);
}
diff --git a/app/components/elements/Button.module.css b/app/components/elements/Button.module.css
index 9b9196da7..c7f491e8a 100644
--- a/app/components/elements/Button.module.css
+++ b/app/components/elements/Button.module.css
@@ -1,4 +1,11 @@
.button {
+ --button-bg: var(--color-text-accent);
+ --button-hover-bg: color-mix(
+ in oklch,
+ var(--button-bg) 85%,
+ var(--color-text)
+ );
+ --button-hover-border: var(--button-hover-bg);
display: flex;
width: auto;
align-items: center;
@@ -6,7 +13,7 @@
border: var(--border-style-accent);
border-radius: var(--radius-field);
appearance: none;
- background: var(--color-text-accent);
+ background: var(--button-bg);
color: var(--color-text-inverse);
cursor: pointer;
font-size: var(--font-sm);
@@ -16,6 +23,16 @@
outline-color: var(--color-text-accent);
height: var(--field-size);
white-space: nowrap;
+ text-decoration: none;
+ transition:
+ background-color 0.15s,
+ border-color 0.15s;
+
+ &:hover:not(:disabled):not([data-pending]),
+ &:focus-visible {
+ background-color: var(--button-hover-bg);
+ border-color: var(--button-hover-border);
+ }
&:focus-visible {
outline-style: solid;
@@ -36,20 +53,26 @@
}
.outlined {
- background-color: transparent;
+ --button-bg: transparent;
+ --button-hover-bg: var(--color-bg-high);
+ --button-hover-border: var(--color-text-accent);
color: var(--color-text-accent);
}
.outlinedSuccess {
+ --button-bg: transparent;
+ --button-hover-bg: var(--color-bg-high);
+ --button-hover-border: var(--color-success);
border-color: var(--color-success);
- background-color: transparent;
color: var(--color-success);
outline-color: var(--color-success);
}
.outlinedDestructive {
+ --button-bg: transparent;
+ --button-hover-bg: var(--color-bg-high);
+ --button-hover-border: var(--color-error);
border-color: var(--color-error);
- background-color: transparent;
color: var(--color-error);
outline-color: var(--color-error);
}
@@ -69,21 +92,11 @@
height: var(--field-size-lg);
}
-.square {
- aspect-ratio: 1 / 1;
- padding: 0;
-}
-
-.circle {
- border-radius: 50%;
- aspect-ratio: 1 / 1;
- padding: 0;
-}
-
.minimal {
- padding: 0;
+ --button-bg: transparent;
+ --button-hover-bg: var(--color-bg-high);
+ padding: 0 var(--s-1);
border: none;
- background-color: transparent;
color: var(--color-text-accent);
outline: initial;
@@ -93,34 +106,47 @@
}
.minimalSuccess {
- padding: 0;
+ --button-bg: transparent;
+ --button-hover-bg: var(--color-bg-high);
+ padding: 0 var(--s-1);
border: none;
- background-color: transparent;
color: var(--color-success);
outline-color: var(--color-success);
}
.success {
+ --button-bg: var(--color-success);
border-color: var(--color-success);
- background-color: var(--color-success);
outline-color: var(--color-success);
}
.destructive {
+ --button-bg: var(--color-error);
border-color: var(--color-error);
- background-color: var(--color-error);
color: var(--color-text-inverse);
outline-color: var(--color-error);
}
.minimalDestructive {
- padding: 0;
+ --button-bg: transparent;
+ --button-hover-bg: var(--color-bg-high);
+ padding: 0 var(--s-1);
border: none;
- background-color: transparent;
color: var(--color-error);
outline-color: var(--color-error);
}
+.square {
+ aspect-ratio: 1 / 1;
+ padding: 0;
+}
+
+.circle {
+ border-radius: 50%;
+ aspect-ratio: 1 / 1;
+ padding: 0;
+}
+
.buttonIcon {
min-width: 20px;
max-width: 20px;
diff --git a/app/components/elements/Calendar.module.css b/app/components/elements/Calendar.module.css
index 586112629..d079d1c4e 100644
--- a/app/components/elements/Calendar.module.css
+++ b/app/components/elements/Calendar.module.css
@@ -60,6 +60,12 @@
color: var(--color-text);
cursor: pointer;
margin: 0 auto;
+ transition: background-color 0.15s;
+
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
+ }
&:focus-visible {
outline: var(--focus-ring);
@@ -67,13 +73,9 @@
}
&[data-selected] {
- background-color: var(--color-bg-high);
+ background-color: var(--color-bg-higher);
color: var(--color-text-accent);
- }
-
- &:hover {
- background-color: var(--color-bg-high);
- outline: initial;
+ font-weight: var(--weight-bold);
}
}
@@ -83,11 +85,14 @@
border-spacing: 0;
}
- & tr:hover td,
- & tr:has([data-selected]) td {
+ & tr:hover td {
background-color: var(--color-bg-high);
}
+ & tr:has([data-selected]) td {
+ background-color: var(--color-bg-higher);
+ }
+
& tr:hover td:first-child,
& tr:has([data-selected]) td:first-child {
border-start-start-radius: var(--radius-field);
@@ -101,7 +106,8 @@
}
& .cell {
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: transparent;
}
diff --git a/app/components/elements/ChipRadio.module.css b/app/components/elements/ChipRadio.module.css
index 069b3aa13..5e356287a 100644
--- a/app/components/elements/ChipRadio.module.css
+++ b/app/components/elements/ChipRadio.module.css
@@ -49,4 +49,22 @@
background-color: var(--color-text-accent);
color: var(--color-text-inverse);
}
+
+ &:not(:checked) + .label:hover,
+ &:not(:checked):focus-visible + .label {
+ background-color: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
+ }
+
+ &:checked + .label:hover,
+ &:checked:focus-visible + .label {
+ background-color: color-mix(
+ in oklch,
+ var(--color-text-accent) 85%,
+ var(--color-text)
+ );
+ }
}
diff --git a/app/components/elements/Menu.module.css b/app/components/elements/Menu.module.css
index 196354e1e..ac40fc75d 100644
--- a/app/components/elements/Menu.module.css
+++ b/app/components/elements/Menu.module.css
@@ -47,6 +47,7 @@
}
.item {
+ text-decoration: none;
display: flex;
align-items: center;
font-weight: var(--weight-bold);
@@ -64,8 +65,8 @@
transition: background-color 0.15s;
cursor: pointer;
- &:hover,
- &:focus {
+ &:hover:not(.itemDisabled),
+ &:focus:not(.itemDisabled) {
background-color: var(--color-bg-higher);
}
}
diff --git a/app/components/elements/Select.module.css b/app/components/elements/Select.module.css
index 8933b9775..d500f0226 100644
--- a/app/components/elements/Select.module.css
+++ b/app/components/elements/Select.module.css
@@ -29,6 +29,12 @@
width: 100%;
cursor: pointer;
text-align: start;
+ transition: background-color 0.15s;
+
+ &:hover:not(:disabled),
+ &:focus-visible {
+ background-color: var(--color-bg-high);
+ }
&:focus-visible,
&[aria-expanded="true"] {
@@ -187,6 +193,12 @@
padding: 0;
cursor: pointer;
color: var(--color-text-high);
+ transition: color 0.15s;
+
+ &:hover,
+ &:focus-visible {
+ color: var(--color-text);
+ }
}
.searchField[data-empty] .searchClearButton {
diff --git a/app/components/elements/Switch.module.css b/app/components/elements/Switch.module.css
index abd257faa..70f93caca 100644
--- a/app/components/elements/Switch.module.css
+++ b/app/components/elements/Switch.module.css
@@ -8,7 +8,9 @@
display: inline-grid;
justify-items: center;
grid-template-columns: 0fr 1fr 1fr;
- transition: grid-template-columns 200ms;
+ transition:
+ grid-template-columns 200ms,
+ background-color 0.15s;
&:before {
content: "";
@@ -50,6 +52,20 @@
outline-offset: 1px;
}
+ &:hover:not(:has(> .input:disabled)) .indicator,
+ &:has(> .input:focus-visible) .indicator {
+ background: var(--color-bg-high);
+ }
+
+ &:hover:not(:has(> .input:disabled)):has(> .input:checked) .indicator,
+ &:has(> .input:focus-visible:checked) .indicator {
+ background: color-mix(
+ in oklch,
+ var(--color-text-accent) 85%,
+ var(--color-text)
+ );
+ }
+
&:has(> .input:disabled) {
cursor: not-allowed;
diff --git a/app/components/elements/Tabs.module.css b/app/components/elements/Tabs.module.css
index 4b0ccf063..70c8dc67b 100644
--- a/app/components/elements/Tabs.module.css
+++ b/app/components/elements/Tabs.module.css
@@ -22,9 +22,12 @@
.tabContainer {
min-width: fit-content;
margin-bottom: -2px;
+ text-decoration: none;
& .tabButton {
- background-color: transparent;
+ --button-bg: transparent;
+ --button-hover-bg: transparent;
+ --button-hover-border: var(--color-border-high);
border: none;
font-size: var(--font-xs);
border-radius: 0;
@@ -33,6 +36,9 @@
white-space: nowrap;
flex: 1;
transform: none !important;
+ transition:
+ border-color 0.15s,
+ color 0.15s;
& img {
min-width: 16px;
@@ -41,12 +47,17 @@
}
}
+ &:hover:not([data-selected]) .tabButton {
+ color: var(--color-text);
+ }
+
&:focus-visible {
outline: var(--focus-ring);
outline-offset: -2px;
}
&[data-selected] .tabButton {
+ --button-hover-border: var(--color-text-accent);
border-color: var(--color-text-accent);
color: var(--color-text);
}
diff --git a/app/components/elements/Toast.module.css b/app/components/elements/Toast.module.css
index d8c06e341..32ef32b0e 100644
--- a/app/components/elements/Toast.module.css
+++ b/app/components/elements/Toast.module.css
@@ -89,10 +89,6 @@
color: inherit;
opacity: 0.75;
- &:hover {
- opacity: 1;
- }
-
& svg {
width: 1rem;
}
diff --git a/app/components/filter-bar/FilterBar.module.css b/app/components/filter-bar/FilterBar.module.css
index 66f042b2f..446cfab20 100644
--- a/app/components/filter-bar/FilterBar.module.css
+++ b/app/components/filter-bar/FilterBar.module.css
@@ -17,8 +17,13 @@
background-color: var(--color-bg-higher);
transition: background-color 0.15s;
- &:has(.trigger:hover) {
- background-color: var(--color-bg-high);
+ &:has(.trigger:hover),
+ &:has(.trigger:focus-visible) {
+ background-color: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
}
}
@@ -56,14 +61,23 @@
background-color: transparent;
color: var(--color-text-high);
cursor: pointer;
+ transition:
+ background-color 0.15s,
+ color 0.15s;
& > svg {
width: 14px;
height: 14px;
}
- &:hover {
- color: var(--color-error);
+ &:hover,
+ &:focus-visible {
+ background-color: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
+ color: var(--color-text);
}
&:focus-visible {
@@ -94,7 +108,8 @@
background-color 0.15s,
color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-high);
color: var(--color-text);
}
diff --git a/app/components/layout/ChatSidebar.module.css b/app/components/layout/ChatSidebar.module.css
index 60d448a43..cb091afd5 100644
--- a/app/components/layout/ChatSidebar.module.css
+++ b/app/components/layout/ChatSidebar.module.css
@@ -42,14 +42,20 @@
padding: 0;
border-radius: var(--radius-field);
margin-inline-start: auto;
+ transition: background-color 0.15s;
@media screen and (min-width: 600px) {
height: var(--field-size-sm);
}
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-higher);
}
+
+ &:focus-visible {
+ outline: var(--focus-ring);
+ }
}
.roomList {
@@ -81,9 +87,18 @@
letter-spacing: 0.04em;
color: var(--color-text-high);
border-radius: var(--radius-field);
+ transition:
+ background-color 0.15s,
+ color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-higher);
+ color: var(--color-text);
+ }
+
+ &:focus-visible {
+ outline: var(--focus-ring);
}
}
@@ -133,10 +148,16 @@
height: var(--field-size-sm);
aspect-ratio: 1 / 1;
border-radius: var(--radius-field);
+ transition: background-color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-higher);
}
+
+ &:focus-visible {
+ outline: var(--focus-ring);
+ }
}
.backButtonBadge {
@@ -175,7 +196,8 @@
border-radius: var(--radius-field);
transition: background-color 0.15s;
- &:is(a):hover {
+ &:is(a):hover,
+ &:is(a):focus-visible {
background-color: var(--color-bg-higher);
}
}
diff --git a/app/components/layout/Footer.module.css b/app/components/layout/Footer.module.css
index b0e7cb34d..ba16ba322 100644
--- a/app/components/layout/Footer.module.css
+++ b/app/components/layout/Footer.module.css
@@ -113,6 +113,7 @@
}
.chip {
+ text-decoration: none;
display: block;
max-width: 250px;
overflow: hidden;
@@ -150,6 +151,7 @@
}
.card {
+ text-decoration: none;
display: flex;
align-items: center;
min-width: 10.5rem;
diff --git a/app/components/layout/GlobalSearch.module.css b/app/components/layout/GlobalSearch.module.css
index 2badedcb2..ace76708e 100644
--- a/app/components/layout/GlobalSearch.module.css
+++ b/app/components/layout/GlobalSearch.module.css
@@ -13,7 +13,8 @@
height: var(--field-size-sm);
transition: background-color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-high);
}
diff --git a/app/components/layout/NotificationPopover.module.css b/app/components/layout/NotificationPopover.module.css
index f13773c2a..472b1c398 100644
--- a/app/components/layout/NotificationPopover.module.css
+++ b/app/components/layout/NotificationPopover.module.css
@@ -52,12 +52,16 @@
height: var(--selector-size);
background-color: var(--color-bg-high);
border-radius: var(--radius-field);
+ transition:
+ background-color 0.15s,
+ color 0.15s;
& svg {
stroke-width: 3;
}
- &:hover {
+ &:hover,
+ &:focus-visible {
color: var(--color-text);
background-color: var(--color-bg-higher);
}
diff --git a/app/components/layout/SearchResults.module.css b/app/components/layout/SearchResults.module.css
index 5428cefca..d919597a8 100644
--- a/app/components/layout/SearchResults.module.css
+++ b/app/components/layout/SearchResults.module.css
@@ -14,6 +14,7 @@
outline: none;
color: inherit;
text-decoration: none;
+ transition: background-color 0.15s;
&:hover,
&:focus {
diff --git a/app/components/layout/TopNavMenus.module.css b/app/components/layout/TopNavMenus.module.css
index f1263d362..ee0fced25 100644
--- a/app/components/layout/TopNavMenus.module.css
+++ b/app/components/layout/TopNavMenus.module.css
@@ -118,6 +118,7 @@
}
.previewIcon {
+ text-decoration: none;
display: flex;
flex-shrink: 0;
padding: var(--s-1);
diff --git a/app/components/layout/WeaponSearch.module.css b/app/components/layout/WeaponSearch.module.css
index 49316b988..e5d35ae92 100644
--- a/app/components/layout/WeaponSearch.module.css
+++ b/app/components/layout/WeaponSearch.module.css
@@ -19,9 +19,14 @@
cursor: pointer;
transition: background-color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-high);
}
+
+ &:focus-visible {
+ outline: var(--focus-ring);
+ }
}
.selectedWeaponName {
diff --git a/app/components/layout/index.module.css b/app/components/layout/index.module.css
index d63a23a31..68bc0d19c 100644
--- a/app/components/layout/index.module.css
+++ b/app/components/layout/index.module.css
@@ -48,9 +48,18 @@
color: var(--color-text-inverse);
text-decoration: none;
flex-shrink: 0;
- transition: background-color 0.2s;
+ transition: background-color 0.15s;
line-height: 1;
+ &:hover,
+ &:focus-visible {
+ background-color: color-mix(
+ in oklch,
+ var(--color-text-accent) 85%,
+ var(--color-text)
+ );
+ }
+
&:focus-visible {
outline: var(--focus-ring);
outline-offset: 1px;
@@ -375,8 +384,10 @@ shown, so the popover's user agent styles are reset here.
margin-left: calc(-1 * var(--s-1));
flex: 1;
min-width: 0;
+ transition: background-color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-high);
}
}
@@ -405,8 +416,13 @@ shown, so the popover's user agent styles are reset here.
border-radius: var(--radius-field);
color: var(--color-text-high);
cursor: pointer;
+ text-decoration: none;
+ transition:
+ background-color 0.15s,
+ color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-high);
color: var(--color-text);
}
diff --git a/app/components/match-page/MatchActionTab.module.css b/app/components/match-page/MatchActionTab.module.css
index 870054a45..7af1a2662 100644
--- a/app/components/match-page/MatchActionTab.module.css
+++ b/app/components/match-page/MatchActionTab.module.css
@@ -174,8 +174,8 @@
transition: background-color 0.15s;
height: 100%;
- &:hover .checkCircle {
- border-color: var(--color-accent-high);
+ &:hover {
+ background-color: var(--color-bg-higher);
}
@container (max-width: 599px) {
diff --git a/app/components/match-page/MatchRosterTab.module.css b/app/components/match-page/MatchRosterTab.module.css
index dbc9e7f92..b9b00f70b 100644
--- a/app/components/match-page/MatchRosterTab.module.css
+++ b/app/components/match-page/MatchRosterTab.module.css
@@ -84,7 +84,7 @@
width: 24px;
height: 24px;
border-radius: 100%;
- background-color: var(--color-bg-higher);
+ --button-bg: var(--color-bg-higher);
border: none;
padding: 0;
cursor: pointer;
diff --git a/app/components/match-page/MatchTimeline.module.css b/app/components/match-page/MatchTimeline.module.css
index 1970f427b..47a00e75e 100644
--- a/app/components/match-page/MatchTimeline.module.css
+++ b/app/components/match-page/MatchTimeline.module.css
@@ -159,6 +159,13 @@
font-weight: var(--weight-semi);
text-transform: uppercase;
letter-spacing: 0.05em;
+ color: var(--color-text-high);
+ transition: color 0.15s;
+
+ &:hover,
+ &:focus-visible {
+ color: var(--color-text);
+ }
&::before,
&::after {
@@ -320,7 +327,6 @@
width: auto;
padding: 0;
border: none;
- background: transparent;
color: inherit;
font-size: inherit;
font-weight: inherit;
@@ -433,7 +439,6 @@
display: flex;
align-items: center;
gap: var(--s-2);
- background: transparent;
border: none;
padding: var(--s-0-5) var(--s-1);
border-radius: var(--radius-field);
diff --git a/app/components/match-page/WeaponPool.module.css b/app/components/match-page/WeaponPool.module.css
index f91b85002..f927b08d5 100644
--- a/app/components/match-page/WeaponPool.module.css
+++ b/app/components/match-page/WeaponPool.module.css
@@ -6,6 +6,16 @@
border-radius: var(--radius-full);
padding: var(--s-0-5) var(--s-1-5);
cursor: pointer;
+ transition: background-color 0.15s;
+
+ &:hover,
+ &:focus-visible {
+ background-color: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
+ }
@container weapon-pool (max-width: 150px) {
display: grid;
diff --git a/app/features/art/components/ArtGrid.module.css b/app/features/art/components/ArtGrid.module.css
index 8a0578f54..53b2f5346 100644
--- a/app/features/art/components/ArtGrid.module.css
+++ b/app/features/art/components/ArtGrid.module.css
@@ -1,13 +1,9 @@
.thumbnail {
cursor: pointer;
- transition: all 0.2s ease;
-
- &:hover {
- scale: 1.025;
- }
}
.dialogTag {
+ text-decoration: none;
background-color: #fff;
border-radius: var(--radius-box);
color: #000;
@@ -17,6 +13,7 @@
}
.dialogTagUser {
+ text-decoration: none;
background-color: var(--color-accent);
}
diff --git a/app/features/availability/components/ScheduleTracks.module.css b/app/features/availability/components/ScheduleTracks.module.css
index 64f74a5c7..d35f6a665 100644
--- a/app/features/availability/components/ScheduleTracks.module.css
+++ b/app/features/availability/components/ScheduleTracks.module.css
@@ -30,16 +30,23 @@
align-items: center;
gap: 2px;
align-self: end;
- padding: 0;
+ padding: 0 var(--s-1);
+ margin-inline: calc(-1 * var(--s-1));
background: none;
border: none;
+ border-radius: var(--radius-field);
font-size: var(--font-3xs);
line-height: 1rem;
color: var(--color-text-high);
white-space: nowrap;
cursor: pointer;
+ transition:
+ background-color 0.15s,
+ color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
color: var(--color-text);
}
diff --git a/app/features/availability/components/WeekAvailabilityEditor.module.css b/app/features/availability/components/WeekAvailabilityEditor.module.css
index 923b5afd3..4124076a7 100644
--- a/app/features/availability/components/WeekAvailabilityEditor.module.css
+++ b/app/features/availability/components/WeekAvailabilityEditor.module.css
@@ -118,8 +118,13 @@
border-radius: var(--radius-field);
color: var(--color-text-high);
cursor: pointer;
+ transition:
+ background-color 0.15s,
+ color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
color: var(--color-text);
}
diff --git a/app/features/build-analyzer/routes/analyzer.module.css b/app/features/build-analyzer/routes/analyzer.module.css
index 9151f9998..fc9c66a29 100644
--- a/app/features/build-analyzer/routes/analyzer.module.css
+++ b/app/features/build-analyzer/routes/analyzer.module.css
@@ -71,6 +71,7 @@
}
.noticeableLink {
+ text-decoration: none;
display: flex;
width: 100%;
align-items: center;
@@ -174,11 +175,12 @@
}
.statCardPopoverTrigger {
+ --button-bg: transparent;
+ --button-hover-bg: var(--color-bg-high);
display: inline;
height: 1rem;
padding: 0;
border: none;
- background-color: transparent;
color: var(--color-accent);
font-size: var(--font-md);
font-weight: var(--weight-bold);
diff --git a/app/features/calendar/components/TournamentCard.module.css b/app/features/calendar/components/TournamentCard.module.css
index 9f683c2b3..9a2211a52 100644
--- a/app/features/calendar/components/TournamentCard.module.css
+++ b/app/features/calendar/components/TournamentCard.module.css
@@ -24,9 +24,12 @@
height: 100%;
min-width: var(--card-width);
max-width: var(--card-width);
+ text-decoration: none;
+ transition: background-color 0.15s;
- &:hover .avatarImg {
- outline: 6px solid var(--color-bg-higher);
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-higher);
}
}
diff --git a/app/features/calendar/routes/calendar.module.css b/app/features/calendar/routes/calendar.module.css
index f7ee5ab37..908d8ffc9 100644
--- a/app/features/calendar/routes/calendar.module.css
+++ b/app/features/calendar/routes/calendar.module.css
@@ -34,6 +34,7 @@
all: unset;
background-color: var(--color-bg-higher);
border: var(--border-style);
+ transition: background-color 0.15s;
display: flex;
align-items: center;
gap: var(--s-2);
@@ -47,11 +48,25 @@
outline: var(--focus-ring);
}
+ &:hover,
+ &:focus-visible {
+ background-color: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
+ }
+
&:not(.navigateArrowButton) {
justify-content: center;
flex-basis: 100%;
background-color: var(--color-bg);
min-height: 30px;
+
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
+ }
}
& svg {
diff --git a/app/features/chat/components/Chat.module.css b/app/features/chat/components/Chat.module.css
index e6531da48..0451f7ae0 100644
--- a/app/features/chat/components/Chat.module.css
+++ b/app/features/chat/components/Chat.module.css
@@ -154,8 +154,8 @@
position: absolute;
font-size: var(--font-2xs);
font-weight: var(--weight-bold);
+ --button-bg: var(--color-bg-higher);
border-radius: var(--radius-field);
- background-color: var(--color-bg-higher);
border: none;
color: var(--color-text);
bottom: 60px;
diff --git a/app/features/comp-analyzer/components/DamageComboBar.module.css b/app/features/comp-analyzer/components/DamageComboBar.module.css
index 279ce9a69..bb0df57f3 100644
--- a/app/features/comp-analyzer/components/DamageComboBar.module.css
+++ b/app/features/comp-analyzer/components/DamageComboBar.module.css
@@ -20,9 +20,15 @@
color: var(--color-text);
width: 100%;
text-align: left;
+ transition: background-color 0.15s;
- &:hover {
- background: var(--color-bg-high);
+ &:hover,
+ &:focus-visible {
+ background: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
}
}
@@ -105,9 +111,14 @@
border: 1px solid transparent;
border-radius: var(--radius-selector);
cursor: pointer;
+ transition:
+ background-color 0.15s,
+ color 0.15s;
- &:hover {
- text-decoration: line-through;
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
+ color: var(--color-text);
}
}
@@ -190,10 +201,15 @@
font-size: var(--font-xs);
color: var(--color-text);
cursor: pointer;
- transition: background-color 0.15s ease;
+ transition: background-color 0.15s;
- &:hover:not(:disabled) {
- background: var(--color-bg-high);
+ &:hover:not(:disabled),
+ &:focus-visible {
+ background: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
}
&:disabled {
@@ -222,10 +238,15 @@
font-size: var(--font-xs);
color: var(--color-text-high);
cursor: pointer;
- transition: background-color 0.15s ease;
+ transition: background-color 0.15s;
- &:hover {
- background: var(--color-bg-high);
+ &:hover,
+ &:focus-visible {
+ background: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
}
}
diff --git a/app/features/comp-analyzer/components/RangeVisualization.module.css b/app/features/comp-analyzer/components/RangeVisualization.module.css
index e106a21ce..4eacdd7d4 100644
--- a/app/features/comp-analyzer/components/RangeVisualization.module.css
+++ b/app/features/comp-analyzer/components/RangeVisualization.module.css
@@ -20,9 +20,15 @@
color: var(--color-text);
width: 100%;
text-align: left;
+ transition: background-color 0.15s;
- &:hover {
- background: var(--color-bg-high);
+ &:hover,
+ &:focus-visible {
+ background: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
}
}
diff --git a/app/features/comp-analyzer/components/SelectedWeapons.module.css b/app/features/comp-analyzer/components/SelectedWeapons.module.css
index 144e3bbfd..5944e5722 100644
--- a/app/features/comp-analyzer/components/SelectedWeapons.module.css
+++ b/app/features/comp-analyzer/components/SelectedWeapons.module.css
@@ -99,9 +99,15 @@
line-height: 1;
color: var(--color-text-high);
flex-shrink: 0;
+ border-radius: var(--radius-field);
+ transition:
+ background-color 0.15s,
+ color 0.15s;
- &:hover {
- color: var(--color-error);
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
+ color: var(--color-text);
}
}
diff --git a/app/features/comp-analyzer/components/WeaponGrid.module.css b/app/features/comp-analyzer/components/WeaponGrid.module.css
index 95a9f594b..9b6171ba6 100644
--- a/app/features/comp-analyzer/components/WeaponGrid.module.css
+++ b/app/features/comp-analyzer/components/WeaponGrid.module.css
@@ -82,19 +82,20 @@
border: 2px solid transparent;
border-radius: var(--radius-box);
cursor: pointer;
- transition: border-color 0.1s;
+ transition: background-color 0.15s;
- &:hover {
- border-color: var(--color-text-accent);
+ &:hover:not(:disabled),
+ &:focus-visible {
+ background-color: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
}
&:disabled {
opacity: 0.6;
cursor: not-allowed;
-
- &:hover {
- border-color: transparent;
- }
}
}
diff --git a/app/features/info/routes/support.module.css b/app/features/info/routes/support.module.css
index 9b4eaf54b..0f17b4c63 100644
--- a/app/features/info/routes/support.module.css
+++ b/app/features/info/routes/support.module.css
@@ -12,11 +12,12 @@
}
.popoverTrigger {
+ --button-bg: transparent;
+ --button-hover-bg: var(--color-bg-high);
display: inline;
height: 1rem;
padding: 0;
border: none;
- background-color: transparent;
color: var(--color-text-accent);
font-size: var(--font-md);
font-weight: var(--weight-bold);
diff --git a/app/features/info/routes/welcome.module.css b/app/features/info/routes/welcome.module.css
index 5580551f8..d474560e6 100644
--- a/app/features/info/routes/welcome.module.css
+++ b/app/features/info/routes/welcome.module.css
@@ -50,9 +50,15 @@
font-size: var(--font-xs);
font-weight: var(--weight-semi);
vertical-align: middle;
- transition: background-color 0.15s ease-out;
+ text-decoration: none;
+ transition: background-color 0.15s;
- &:hover {
- background-color: var(--color-bg-high);
+ &:hover,
+ &:focus-visible {
+ background-color: color-mix(
+ in oklch,
+ var(--color-bg-higher) 85%,
+ var(--color-text)
+ );
}
}
diff --git a/app/features/lfg/components/LFGPost.module.css b/app/features/lfg/components/LFGPost.module.css
index 638741b4c..73f91b854 100644
--- a/app/features/lfg/components/LFGPost.module.css
+++ b/app/features/lfg/components/LFGPost.module.css
@@ -101,6 +101,7 @@
}
.editButton {
+ text-decoration: none;
font-size: var(--font-2xs);
font-weight: var(--weight-semi);
border-radius: var(--radius-selector);
diff --git a/app/features/map-planner/components/Planner.module.css b/app/features/map-planner/components/Planner.module.css
index 07edab0cb..cc57b5283 100644
--- a/app/features/map-planner/components/Planner.module.css
+++ b/app/features/map-planner/components/Planner.module.css
@@ -48,8 +48,10 @@
border-radius: 0 0 var(--radius-selector) var(--radius-selector);
background-color: var(--color-bg);
cursor: pointer;
+ transition: background-color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-high);
}
}
@@ -123,8 +125,10 @@
border-radius: 0 var(--radius-selector) var(--radius-selector) 0;
background-color: var(--color-bg);
cursor: pointer;
+ transition: background-color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-high);
}
}
@@ -177,8 +181,10 @@
background: transparent;
cursor: grab;
touch-action: none;
+ transition: background-color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-high);
}
}
diff --git a/app/features/notifications/components/NotificationList.module.css b/app/features/notifications/components/NotificationList.module.css
index f0b26b59a..0445885df 100644
--- a/app/features/notifications/components/NotificationList.module.css
+++ b/app/features/notifications/components/NotificationList.module.css
@@ -24,9 +24,13 @@
column-gap: var(--s-2);
padding-block: var(--s-3);
color: var(--color-text);
+ border-radius: var(--radius-field);
+ text-decoration: none;
+ transition: background-color 0.15s;
- &:hover .imageContainer {
- outline: 3px solid var(--color-bg-higher);
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
}
&:focus-within .imageContainer {
diff --git a/app/features/object-damage-calculator/routes/object-damage-calculator.module.css b/app/features/object-damage-calculator/routes/object-damage-calculator.module.css
index c35059a70..3d7f45a45 100644
--- a/app/features/object-damage-calculator/routes/object-damage-calculator.module.css
+++ b/app/features/object-damage-calculator/routes/object-damage-calculator.module.css
@@ -71,6 +71,12 @@
border-radius: var(--radius-field);
width: var(--field-size);
height: var(--field-size);
+ transition: background-color 0.15s;
+
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
+ }
&:focus-visible {
outline: var(--focus-ring);
diff --git a/app/features/params/components/WeaponKits.module.css b/app/features/params/components/WeaponKits.module.css
index 15faf19f2..428b70830 100644
--- a/app/features/params/components/WeaponKits.module.css
+++ b/app/features/params/components/WeaponKits.module.css
@@ -36,9 +36,14 @@
.gearLink {
display: inline-flex;
align-items: center;
- border-radius: var(--radius-rounded);
+ padding: var(--s-0-5);
+ margin: calc(-1 * var(--s-0-5));
+ border-radius: var(--radius-field);
+ text-decoration: none;
+ transition: background-color 0.15s;
- &:hover {
- filter: brightness(1.2);
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
}
}
diff --git a/app/features/params/components/WeaponParamsTable.module.css b/app/features/params/components/WeaponParamsTable.module.css
index b1c3e22e4..142ee7849 100644
--- a/app/features/params/components/WeaponParamsTable.module.css
+++ b/app/features/params/components/WeaponParamsTable.module.css
@@ -51,10 +51,6 @@
text-align: left;
& tbody {
- & tr:hover {
- background-color: var(--color-bg-high);
- }
-
& td {
padding: var(--s-2) var(--s-3);
border-bottom: 1px solid var(--color-border);
@@ -125,6 +121,7 @@
.expandableRow .paramName {
cursor: pointer;
+ transition: background-color 0.15s;
&:hover {
background-color: var(--color-bg-high);
diff --git a/app/features/scanner/components/FixturesPage.module.css b/app/features/scanner/components/FixturesPage.module.css
index 945e6001b..5c1519a9e 100644
--- a/app/features/scanner/components/FixturesPage.module.css
+++ b/app/features/scanner/components/FixturesPage.module.css
@@ -204,6 +204,11 @@ button.cardToggle {
cursor: pointer;
font-size: var(--font-2xs);
color: var(--color-text-high);
+ transition: color 0.15s;
+
+ &:hover {
+ color: var(--color-text);
+ }
}
.json {
diff --git a/app/features/scanner/components/FrameThumb.module.css b/app/features/scanner/components/FrameThumb.module.css
index 0b8a86b61..72ca50a75 100644
--- a/app/features/scanner/components/FrameThumb.module.css
+++ b/app/features/scanner/components/FrameThumb.module.css
@@ -1,14 +1,17 @@
/* an unstyled button so the image itself is the target */
button.thumbButton {
height: auto;
- padding: 0;
border: none;
background: none;
margin-inline-start: auto;
+ margin-block: -2px;
+ padding: 2px;
border-radius: var(--radius-field);
+ transition: background-color 0.15s;
- &:hover {
- filter: brightness(1.2);
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
}
}
diff --git a/app/features/scanner/components/LivePage.module.css b/app/features/scanner/components/LivePage.module.css
index 12ceb84e4..8c452a82c 100644
--- a/app/features/scanner/components/LivePage.module.css
+++ b/app/features/scanner/components/LivePage.module.css
@@ -12,6 +12,7 @@
background-repeat: no-repeat;
color: var(--color-text);
cursor: pointer;
+ transition: background-color 0.15s;
font-family: inherit;
font-size: var(--font-xs);
height: var(--field-size-sm);
@@ -31,6 +32,11 @@
cursor: not-allowed;
opacity: 0.5;
}
+
+ &:hover:not(:disabled),
+ &:focus-visible {
+ background-color: var(--color-bg-high);
+ }
}
.preview {
diff --git a/app/features/scanner/components/MatchCard.module.css b/app/features/scanner/components/MatchCard.module.css
index 27da672b3..abc485e18 100644
--- a/app/features/scanner/components/MatchCard.module.css
+++ b/app/features/scanner/components/MatchCard.module.css
@@ -268,14 +268,18 @@ button.expand {
background: color-mix(in oklab, var(--color-bg) 55%, transparent);
backdrop-filter: blur(8px);
color: var(--color-text-high);
- transition: transform 0.25s cubic-bezier(0.16, 1, 0.3, 1);
+ transition:
+ transform 0.25s cubic-bezier(0.16, 1, 0.3, 1),
+ background-color 0.15s,
+ color 0.15s;
& svg {
width: var(--field-size-icon);
height: var(--field-size-icon);
}
- &:hover {
+ &:hover,
+ &:focus-visible {
color: var(--color-text);
background: color-mix(in oklab, var(--color-bg) 78%, transparent);
}
@@ -338,12 +342,7 @@ button.expand {
& a {
color: inherit;
- text-decoration: underline;
text-underline-offset: 2px;
-
- &:hover {
- color: var(--color-text-high);
- }
}
}
diff --git a/app/features/scanner/components/ScannerApp.module.css b/app/features/scanner/components/ScannerApp.module.css
index db78a0520..e16172b16 100644
--- a/app/features/scanner/components/ScannerApp.module.css
+++ b/app/features/scanner/components/ScannerApp.module.css
@@ -69,8 +69,13 @@ from sendou.ink's app/styles/vars.css.
text-decoration: none;
padding: var(--s-1) var(--s-2-5);
border-radius: var(--radius-field);
+ transition:
+ background-color 0.15s,
+ color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
color: var(--color-text);
}
diff --git a/app/features/scanner/components/ScannerChrome.module.css b/app/features/scanner/components/ScannerChrome.module.css
index eefbf2edc..d80aa5ecc 100644
--- a/app/features/scanner/components/ScannerChrome.module.css
+++ b/app/features/scanner/components/ScannerChrome.module.css
@@ -6,14 +6,10 @@ button.iconMenu {
height: var(--field-size-sm);
border-radius: var(--radius-field);
padding: 0;
+ --button-bg: var(--color-bg-higher);
border: var(--border-style);
- background: var(--color-bg-higher);
color: var(--color-text);
- &:hover {
- color: var(--color-text-accent);
- }
-
& > svg {
width: var(--field-size-icon);
height: var(--field-size-icon);
diff --git a/app/features/scanner/components/VodPage.module.css b/app/features/scanner/components/VodPage.module.css
index 12cc92a8b..f053b86fb 100644
--- a/app/features/scanner/components/VodPage.module.css
+++ b/app/features/scanner/components/VodPage.module.css
@@ -61,8 +61,8 @@
button.vodDelete {
width: var(--field-size-sm);
padding: 0;
+ --button-bg: var(--color-error);
border-color: var(--color-error);
- background: var(--color-error);
outline-color: var(--color-error);
}
@@ -73,6 +73,11 @@ button.vodDelete {
& summary {
cursor: pointer;
+ transition: color 0.15s;
+
+ &:hover {
+ color: var(--color-text);
+ }
}
& table {
diff --git a/app/features/scrims/components/ScrimAvailability.module.css b/app/features/scrims/components/ScrimAvailability.module.css
index e6e2b52d5..d7909ba02 100644
--- a/app/features/scrims/components/ScrimAvailability.module.css
+++ b/app/features/scrims/components/ScrimAvailability.module.css
@@ -10,10 +10,6 @@
border-radius: 0;
font-size: var(--font-2xs);
font-weight: var(--weight-semi);
-
- &:hover {
- background-color: var(--color-bg-high);
- }
}
.stripeTeam {
diff --git a/app/features/scrims/components/ScrimCard.module.css b/app/features/scrims/components/ScrimCard.module.css
index c3cd176d2..443db5d08 100644
--- a/app/features/scrims/components/ScrimCard.module.css
+++ b/app/features/scrims/components/ScrimCard.module.css
@@ -108,10 +108,10 @@
font-weight: var(--weight-semi);
padding: 0;
text-align: left;
- text-decoration: underline;
- &:hover {
- opacity: 0.8;
+ &:hover,
+ &:focus-visible {
+ text-decoration: underline;
}
}
diff --git a/app/features/sendouq/components/GroupCard.module.css b/app/features/sendouq/components/GroupCard.module.css
index 922623b36..461f68ce4 100644
--- a/app/features/sendouq/components/GroupCard.module.css
+++ b/app/features/sendouq/components/GroupCard.module.css
@@ -82,8 +82,8 @@
}
.extraInfoButton {
+ --button-bg: var(--color-bg);
font-size: var(--font-xs);
- background-color: var(--color-bg);
border-radius: var(--radius-box);
padding: var(--s-0-5) var(--s-1-5);
width: max-content;
@@ -126,7 +126,8 @@
}
.popoverButton {
- background-color: transparent;
+ --button-bg: transparent;
+ --button-hover-bg: var(--color-bg-higher);
color: var(--color-text-high);
font-size: var(--font-xs);
padding: 0;
diff --git a/app/features/sendouq/routes/q.module.css b/app/features/sendouq/routes/q.module.css
index 89360c54c..dfb360358 100644
--- a/app/features/sendouq/routes/q.module.css
+++ b/app/features/sendouq/routes/q.module.css
@@ -31,9 +31,11 @@
display: flex;
align-items: center;
gap: var(--s-3);
- transition: background-color 0.2s;
+ text-decoration: none;
+ transition: background-color 0.15s;
- &:hover {
+ &:hover,
+ &:focus-visible {
background-color: var(--color-bg-higher);
}
}
diff --git a/app/features/settings/components/ModeMapPoolPicker.module.css b/app/features/settings/components/ModeMapPoolPicker.module.css
index 435d0db55..e228b6a06 100644
--- a/app/features/settings/components/ModeMapPoolPicker.module.css
+++ b/app/features/settings/components/ModeMapPoolPicker.module.css
@@ -123,6 +123,7 @@
border: var(--border-style);
border-radius: var(--radius-full);
background-color: transparent;
+ transition: background-color 0.15s;
& img {
filter: grayscale(100%);
@@ -132,8 +133,9 @@
opacity 0.2s;
}
- &:hover img {
- opacity: 0.8;
+ &:hover,
+ &:focus-visible {
+ background-color: var(--color-bg-high);
}
&:focus-visible {
diff --git a/app/features/settings/components/PreferenceRadioGroup.module.css b/app/features/settings/components/PreferenceRadioGroup.module.css
index 1307d6588..25e38b7c4 100644
--- a/app/features/settings/components/PreferenceRadioGroup.module.css
+++ b/app/features/settings/components/PreferenceRadioGroup.module.css
@@ -10,11 +10,16 @@
align-items: center;
gap: var(--s-1);
cursor: pointer;
+ transition: background-color 0.15s;
+
+ &:hover {
+ background-color: var(--color-bg-higher);
+ }
}
.emoji {
filter: grayscale(100%);
- transition: all 0.2s;
+ transition: filter 0.2s;
}
.checked {
@@ -29,7 +34,3 @@
.focusVisible {
outline: var(--focus-ring);
}
-
-.radio:hover .emoji {
- scale: 1.1;
-}
diff --git a/app/features/team/routes/t.$customUrl.index.module.css b/app/features/team/routes/t.$customUrl.index.module.css
index ae517617b..447aff51b 100644
--- a/app/features/team/routes/t.$customUrl.index.module.css
+++ b/app/features/team/routes/t.$customUrl.index.module.css
@@ -7,6 +7,7 @@
}
.results {
+ text-decoration: none;
background-color: var(--color-bg-higher);
max-width: 32rem;
margin: 0 auto;
diff --git a/app/features/team/routes/t.$customUrl.module.css b/app/features/team/routes/t.$customUrl.module.css
index 20efdc73b..bd82274b4 100644
--- a/app/features/team/routes/t.$customUrl.module.css
+++ b/app/features/team/routes/t.$customUrl.module.css
@@ -43,6 +43,7 @@
}
.bskyLink {
+ text-decoration: none;
padding: var(--s-1);
border: 1px solid;
border-radius: 50%;
diff --git a/app/features/tier-list-maker/components/ItemPool.module.css b/app/features/tier-list-maker/components/ItemPool.module.css
index e3c887004..f0d435a33 100644
--- a/app/features/tier-list-maker/components/ItemPool.module.css
+++ b/app/features/tier-list-maker/components/ItemPool.module.css
@@ -7,14 +7,17 @@
.clickableItem {
min-height: 50px;
- padding: 0;
+ padding: var(--s-0-5);
+ margin: calc(-1 * var(--s-0-5));
border: none;
+ border-radius: var(--radius-field);
background: transparent;
cursor: pointer;
- transition: transform 0.1s;
+ transition: background-color 0.15s;
- &:hover:not(:disabled) {
- transform: scale(1.1);
+ &:hover:not(:disabled),
+ &:focus-visible {
+ background-color: var(--color-bg-high);
}
&:disabled {
diff --git a/app/features/tier-list-maker/components/TierRow.module.css b/app/features/tier-list-maker/components/TierRow.module.css
index 0c22e8791..4c0647d27 100644
--- a/app/features/tier-list-maker/components/TierRow.module.css
+++ b/app/features/tier-list-maker/components/TierRow.module.css
@@ -17,11 +17,17 @@
color: var(--color-text);
border-radius: var(--radius-field);
cursor: pointer;
- transition: opacity 0.2s;
+ background-color: var(--tier-color);
+ transition: background-color 0.15s;
border: none;
- &:hover {
- opacity: 0.9;
+ &:hover,
+ &:focus-visible {
+ background-color: color-mix(
+ in oklch,
+ var(--tier-color) 85%,
+ var(--color-text)
+ );
}
}
@@ -57,7 +63,7 @@
border-radius: var(--radius-field) 0 0 var(--radius-field);
align-items: center;
align-content: center;
- transition: background 0.2s;
+ transition: background-color 0.15s;
}
.targetZoneOver {
@@ -109,10 +115,11 @@
background: var(--color-bg-high);
border: none;
cursor: pointer;
- transition: opacity 0.2s;
+ transition: background-color 0.15s;
- &:hover:not(:disabled) {
- opacity: 0.8;
+ &:hover:not(:disabled),
+ &:focus-visible {
+ background: var(--color-bg-higher);
}
&:disabled {
@@ -147,11 +154,11 @@
border-radius: 50%;
border: 2px solid transparent;
cursor: pointer;
- transition: all 0.2s;
+ transition: border-color 0.15s;
padding: 0;
- &:hover {
- transform: scale(1.1);
+ &:hover,
+ &:focus-visible {
border-color: var(--color-text-high);
}
}
diff --git a/app/features/tier-list-maker/components/TierRow.tsx b/app/features/tier-list-maker/components/TierRow.tsx
index 34a19f768..083935cc9 100644
--- a/app/features/tier-list-maker/components/TierRow.tsx
+++ b/app/features/tier-list-maker/components/TierRow.tsx
@@ -5,7 +5,7 @@ import {
} from "@dnd-kit/sortable";
import clsx from "clsx";
import { ChevronDown, ChevronUp, Plus, Trash } from "lucide-react";
-import type { KeyboardEvent } from "react";
+import type { CSSProperties, KeyboardEvent } from "react";
import { useLayoutEffect, useRef } from "react";
import { useTranslation } from "react-i18next";
import { SendouButton } from "~/components/elements/Button";
@@ -89,9 +89,7 @@ export function TierRow({ tier }: TierRowProps) {