diff --git a/app/characters/page.tsx b/app/characters/page.tsx index 283bf59..61505b5 100644 --- a/app/characters/page.tsx +++ b/app/characters/page.tsx @@ -2,6 +2,8 @@ import { useState, useEffect, useMemo } from 'react'; import { useInventoryStore } from '@/store/useInventoryStore'; + +import shared from '../../styles/shared.module.css'; import styles from '../../styles/Characters.module.css'; type Character = { @@ -65,28 +67,28 @@ export default function CharactersPage() { }; const unlockedCount = store.unlockedCharacters.length; - return (
-
-
-

Characters

-

{unlockedCount} of {characters.length} unlocked

+ return (
+
+
+

Characters

+

{unlockedCount} of {characters.length} unlocked

-
+
setSearch(e.target.value)} /> -
+
{(['all', 'survivors', 'killers'] as RoleFilter[]).map(r => (
- + - {filtered.length} shown + {filtered.length} shown - - -
{filtered.length === 0 ? ( -
No characters match
+
No characters match
) : (
{filtered.map(char => { @@ -120,17 +122,17 @@ export default function CharactersPage() { return (
handleToggle(char.idx)} > {char.name} - {char.name} - + {char.name} + {killer ? 'Killer' : 'Survivor'}
diff --git a/styles/Characters.module.css b/styles/Characters.module.css index 13806d9..9e3d005 100644 --- a/styles/Characters.module.css +++ b/styles/Characters.module.css @@ -1,181 +1,3 @@ -.container { - padding: 3rem 4rem; - height: 100%; - display: flex; - flex-direction: column; - overflow: hidden; -} - -/* - header -*/ -.header { - display: flex; - align-items: flex-end; - justify-content: space-between; - margin-bottom: 2rem; - padding-bottom: 1.5rem; - border-bottom: 2px solid #1a1a1a; - flex-shrink: 0; -} - -.title { - font-size: 2.25rem; - text-transform: uppercase; - color: #ffffff; - letter-spacing: 0.05em; - margin: 0 0 0.25rem 0; - text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.8); -} - -.subtitle { - font-size: 0.8rem; - color: #555555; - text-transform: uppercase; - letter-spacing: 0.1em; - margin: 0; -} - -/* - toolbar -*/ -.toolbar { - display: flex; - align-items: center; - gap: 1rem; - margin-bottom: 1.5rem; - flex-shrink: 0; - flex-wrap: wrap; -} - -.searchInput { - background: #0d0d0d; - border: 1px solid #1a1a1a; - color: #c9c9c9; - padding: 0.6rem 1rem; - font-family: 'Roboto Condensed', sans-serif; - font-size: 0.85rem; - width: 240px; - transition: border-color 0.15s ease; -} - -.searchInput::placeholder { - color: #444444; -} - -.searchInput:focus { - outline: none; - border-color: #a30000; -} - -.roleFilter { - display: flex; - gap: 0; - border: 1px solid #1a1a1a; -} - -.roleBtn { - background: transparent; - border: none; - border-right: 1px solid #1a1a1a; - color: #555555; - padding: 0.6rem 1.1rem; - font-family: 'Oswald', sans-serif; - font-size: 0.75rem; - text-transform: uppercase; - letter-spacing: 0.08em; - cursor: pointer; - transition: all 0.15s ease; -} - -.roleBtn:last-child { - border-right: none; -} - -.roleBtn:hover { - color: #ffffff; - background: #1a0000; -} - -.roleBtnActive { - background: #1a0000; - color: #ffffff; - border-color: #a30000; - box-shadow: inset 3px 0 0 #a30000; -} - -.spacer { - flex: 1; -} - -.unlockAllBtn { - background: transparent; - border: 1px solid #4a0000; - color: #a30000; - padding: 0.6rem 1.25rem; - font-family: 'Oswald', sans-serif; - font-size: 0.8rem; - text-transform: uppercase; - letter-spacing: 0.08em; - cursor: pointer; - transition: all 0.2s ease; -} - -.unlockAllBtn:hover { - background: #a30000; - color: #ffffff; - border-color: #ff0000; - box-shadow: 0 0 12px rgba(163, 0, 0, 0.4); -} - -.lockAllBtn { - background: transparent; - border: 1px solid #3d3d3d; - color: #dddddd; - padding: 0.6rem 1.25rem; - font-family: 'Oswald', sans-serif; - font-size: 0.8rem; - text-transform: uppercase; - letter-spacing: 0.08em; - cursor: pointer; - transition: all 0.2s ease; -} -.lockAllBtn:hover { - background: #000000; - color: #ffffff; - border-color: #303030; - box-shadow: 0 0 12px rgba(165, 165, 165, 0.4); -} - -.clearBtn { - background: transparent; - border: 1px solid #1a1a1a; - color: #444444; - padding: 0.6rem 1.25rem; - font-family: 'Oswald', sans-serif; - font-size: 0.8rem; - text-transform: uppercase; - letter-spacing: 0.08em; - cursor: pointer; - transition: all 0.15s ease; -} - -.clearBtn:hover { - color: #888888; - border-color: #333333; -} - -.resultCount { - font-size: 0.75rem; - color: #444444; - text-transform: uppercase; - letter-spacing: 0.08em; - font-family: 'Oswald', sans-serif; -} - -/* - char stuff -*/ .grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); @@ -185,106 +7,3 @@ align-content: start; padding-right: 0.5rem; } - -.card { - background: #0d0d0d; - border: 1px solid #1a1a1a; - display: flex; - flex-direction: column; - align-items: center; - padding: 1rem 0.75rem 0.75rem; - gap: 0.5rem; - cursor: pointer; - transition: all 0.15s ease; - position: relative; - user-select: none; -} - -.card:hover { - border-color: #333333; - background: #111111; -} - -.cardUnlocked { - border-color: #a30000; - background: #0d0000; -} - -.cardUnlocked:hover { - border-color: #cc0000; - background: #110000; - box-shadow: 0 0 16px rgba(163, 0, 0, 0.2); -} - -.cardIcon { - width: 72px; - height: 72px; - object-fit: contain; - filter: grayscale(1) brightness(0.4); - transition: filter 0.15s ease; -} - -.cardUnlocked .cardIcon { - filter: none; -} - -.card:hover .cardIcon { - filter: grayscale(0.3) brightness(0.7); -} - -.cardUnlocked:hover .cardIcon { - filter: none; -} - -.cardName { - font-size: 0.72rem; - text-align: center; - color: #555555; - text-transform: uppercase; - letter-spacing: 0.04em; - line-height: 1.3; - transition: color 0.15s ease; -} - -.cardUnlocked .cardName { - color: #c9c9c9; -} - -.card:hover .cardName { - color: #888888; -} - -.cardUnlocked:hover .cardName { - color: #ffffff; -} - -.rolePip { - font-size: 0.6rem; - text-transform: uppercase; - letter-spacing: 0.1em; - font-family: 'Oswald', sans-serif; - color: #333333; -} - -.rolePipKiller { - color: #5a0000; -} - -.cardUnlocked .rolePip { - color: #444444; -} - -.cardUnlocked .rolePipKiller { - color: #7a0000; -} - -.empty { - display: flex; - align-items: center; - justify-content: center; - flex: 1; - color: #333333; - font-size: 0.9rem; - text-transform: uppercase; - letter-spacing: 0.12em; -} \ No newline at end of file diff --git a/styles/shared.module.css b/styles/shared.module.css new file mode 100644 index 0000000..0c37f90 --- /dev/null +++ b/styles/shared.module.css @@ -0,0 +1,376 @@ +/* + containers and stuff +*/ +.container { + padding: 3rem 4rem; + height: 100%; + display: flex; + flex-direction: column; + overflow: hidden; +} + +/* + header +*/ +.header { + display: flex; + align-items: flex-end; + justify-content: space-between; + margin-bottom: 1.5rem; + padding-bottom: 1.5rem; + border-bottom: 2px solid #1a1a1a; + flex-shrink: 0; +} + +.title { + font-size: 2.25rem; + text-transform: uppercase; + color: #ffffff; + letter-spacing: 0.05em; + margin: 0 0 0.25rem 0; + text-shadow: 2px 2px 5px rgba(0, 0, 0, 0.8); +} + +.subtitle { + font-size: 0.8rem; + color: #555555; + text-transform: uppercase; + letter-spacing: 0.1em; + margin: 0; +} + +/* + toolbar +*/ +.toolbar { + display: flex; + align-items: center; + gap: 1rem; + margin-bottom: 1.5rem; + flex-shrink: 0; + flex-wrap: wrap; +} + +.spacer { + flex: 1; +} + +.searchInput { + background: #0d0d0d; + border: 1px solid #1a1a1a; + color: #c9c9c9; + padding: 0.6rem 1rem; + font-family: 'Roboto Condensed', sans-serif; + font-size: 0.85rem; + width: 240px; + transition: border-color 0.15s ease; +} + +.searchInput::placeholder { + color: #444444; +} + +.searchInput:focus { + outline: none; + border-color: #a30000; +} + +/* + role stuff +*/ +.roleFilter { + display: flex; + border: 1px solid #1a1a1a; +} + +.roleBtn { + background: transparent; + border: none; + border-right: 1px solid #1a1a1a; + color: #555555; + padding: 0.6rem 1.1rem; + font-family: 'Oswald', sans-serif; + font-size: 0.75rem; + text-transform: uppercase; + letter-spacing: 0.08em; + cursor: pointer; + transition: all 0.15s ease; +} + +.roleBtn:last-child { + border-right: none; +} + +.roleBtn:hover { + color: #ffffff; + background: #1a0000; +} + +.roleBtnActive { + background: #1a0000; + color: #ffffff; + box-shadow: inset 3px 0 0 #a30000; +} + +/* + actions +*/ +.resultCount { + font-size: 0.75rem; + color: #444444; + text-transform: uppercase; + letter-spacing: 0.08em; + font-family: 'Oswald', sans-serif; +} + +.unlockAllBtn { + background: transparent; + border: 1px solid #4a0000; + color: #a30000; + padding: 0.6rem 1.25rem; + font-family: 'Oswald', sans-serif; + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.08em; + cursor: pointer; + transition: all 0.2s ease; +} + +.unlockAllBtn:hover { + background: #a30000; + color: #ffffff; + border-color: #ff0000; + box-shadow: 0 0 12px rgba(163, 0, 0, 0.4); +} + +.lockAllBtn { + background: transparent; + border: 1px solid #3d3d3d; + color: #dddddd; + padding: 0.6rem 1.25rem; + font-family: 'Oswald', sans-serif; + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.08em; + cursor: pointer; + transition: all 0.2s ease; +} + +.lockAllBtn:hover { + background: #000000; + color: #ffffff; + border-color: #303030; + box-shadow: 0 0 12px rgba(165, 165, 165, 0.4); +} + +.clearBtn { + background: transparent; + border: 1px solid #1a1a1a; + color: #444444; + padding: 0.6rem 1.25rem; + font-family: 'Oswald', sans-serif; + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.08em; + cursor: pointer; + transition: all 0.15s ease; +} + +.clearBtn:hover { + color: #888888; + border-color: #333333; +} + +/* + cards +*/ +.card { + background: #0d0d0d; + border: 1px solid #1a1a1a; + display: flex; + flex-direction: column; + align-items: center; + padding: 0.85rem 0.5rem 0.7rem; + gap: 0.45rem; + cursor: pointer; + transition: all 0.15s ease; + user-select: none; +} + +.card:hover { + border-color: #333333; + background: #111111; +} + +.cardUnlocked { + border-color: #a30000; + background: #0d0000; +} + +.cardUnlocked:hover { + border-color: #cc0000; + background: #110000; + box-shadow: 0 0 12px rgba(163, 0, 0, 0.2); +} + +.cardIcon { + width: 64px; + height: 64px; + object-fit: contain; + filter: grayscale(1) brightness(0.35); + transition: filter 0.15s ease; +} + +.cardUnlocked .cardIcon { + filter: none; +} + +.card:hover .cardIcon { + filter: grayscale(0.4) brightness(0.6); +} + +.cardUnlocked:hover .cardIcon { + filter: none; +} + +.cardName { + font-size: 0.62rem; + text-align: center; + color: #444444; + text-transform: uppercase; + letter-spacing: 0.04em; + line-height: 1.3; + transition: color 0.15s ease; +} + +.cardUnlocked .cardName { + color: #c9c9c9; +} + +.card:hover .cardName { + color: #666666; +} + +.cardUnlocked:hover .cardName { + color: #ffffff; +} + +.cardUnlocked { + border-color: #a30000; + background: #0d0000; +} + +.cardUnlocked:hover { + border-color: #cc0000; + background: #110000; + box-shadow: 0 0 16px rgba(163, 0, 0, 0.2); +} + +.cardUnlocked .cardIcon { + filter: none; +} + +.cardUnlocked:hover .cardIcon { + filter: none; +} + + +.cardUnlocked .cardName { + color: #c9c9c9; +} + +.cardUnlocked:hover .cardName { + color: #ffffff; +} + +/* + character page specific stuff but i have to place it here bc of the hashing +*/ + +.rolePip { + font-size: 0.6rem; + text-transform: uppercase; + letter-spacing: 0.1em; + font-family: 'Oswald', sans-serif; + color: #333333; +} + +.rolePipKiller { + color: #3b0000; +} + +.cardUnlocked .rolePip { + color: #5e5e5e; +} + +.cardUnlocked .rolePipKiller { + color: #7a0000; +} + +/* + pagination +*/ +.pagination { + display: flex; + align-items: center; + gap: 0.5rem; + justify-content: center; + padding: 1.25rem 0 0; + flex-shrink: 0; + border-top: 1px solid #1a1a1a; +} + +.pageBtn { + background: #0d0d0d; + border: 1px solid #1a1a1a; + color: #555555; + padding: 0.45rem 0.85rem; + font-family: 'Oswald', sans-serif; + font-size: 0.75rem; + cursor: pointer; + transition: all 0.15s ease; + min-width: 36px; + text-align: center; +} + +.pageBtn:hover { + color: #ffffff; + border-color: #333333; +} + +.pageBtn:hover { + color: #ffffff; + border-color: #333333; +} +.pageBtnActive { + background: #1a0000; + border-color: #a30000; + color: #ffffff; +} +.pageBtnDisabled { + opacity: 0.25; + cursor: default; + pointer-events: none; +} +.pageInfo { + font-size: 0.72rem; + color: #444444; + font-family: 'Oswald', sans-serif; + text-transform: uppercase; + letter-spacing: 0.06em; + padding: 0 0.5rem; +} + +/* + empty state +*/ +.empty { + display: flex; + align-items: center; + justify-content: center; + flex: 1; + color: #333333; + font-size: 0.9rem; + text-transform: uppercase; + letter-spacing: 0.12em; +} \ No newline at end of file