From eb7e9df4eecd4c3887afa1850b60cd36fb557985 Mon Sep 17 00:00:00 2001 From: CJ Rivas Date: Wed, 15 Jul 2026 10:14:35 -0400 Subject: [PATCH 1/2] TKW: Arcane steampunk redesign replaces parchment theme - new token system in `styles/globals.scss`: iron/coal ground, `--brass`, `--hextech`, `--shimmer`, `--gaslight` ramp, retuned `--region-color-*` tints - fonts swapped in `app/layout.tsx`: Girassol, Poiret One, Spectral, Barlow Condensed replace Cinzel, Cormorant Unicase, EB Garamond, Alegreya Sans - `FiligreeRule`/`FiligreeFlourish` redrawn as hextech crystal rail and cog conduit with reduced-motion-aware pulse - every SCSS module restyled: gunmetal plates, `corner-shape: bevel` chamfers, brass hover, hextech focus/active states - `SiteMenu` renders `sectionGlyphs` line art for every entry; raster `menu-icons` no longer referenced - `MapMarker` pins retinted to surveyor teal and chart ink; `MapMarker.test.tsx` hexes updated - fix swapped class homes: `.infobox`/`.sigil`/`.sigilFill`/`.rows` move to `HouseInfobox.module.scss`, `.row`/`.note` to `Infobox.module.scss` so entity infobox styles resolve - `FilteredHouseList` controls grid names a `search` area for the shared `listSearch.input` `grid-area` - `/design` catalogues the new palette, type roles, spacing, and control bench - `color-scheme: dark` for native pickers; global hextech `:focus-visible` and scrollbar styling --- app/battles/[slug]/page.module.scss | 9 +- app/battles/page.module.scss | 32 +- app/characters/[slug]/page.module.scss | 107 ++++--- app/design/page.module.scss | 293 ++++++++++-------- app/design/page.tsx | 72 +++-- app/dragons/[slug]/page.module.scss | 5 +- app/events/[slug]/page.module.scss | 5 +- app/houses/[slug]/page.module.scss | 28 +- app/layout.tsx | 35 ++- app/timeline/page.module.scss | 5 +- app/weapons/[slug]/page.module.scss | 14 +- components/Accordion/Accordion.module.scss | 42 ++- .../CharacterSearchInput.module.scss | 19 +- .../ComingSoonPage/ComingSoonPage.module.scss | 7 +- components/DropCap/DropCap.module.scss | 4 +- components/FamilyTree/FamilyTree.module.scss | 62 ++-- .../FamilyTreeChart.module.scss | 54 ++-- components/Filigree/Filigree.module.scss | 36 ++- components/Filigree/Filigree.tsx | 50 ++- .../FilteredCharacterList.module.scss | 62 ++-- .../FilteredDragonList.module.scss | 63 ++-- .../FilteredHouseList.module.scss | 101 +++--- .../FilteredWeaponList.module.scss | 25 +- .../HouseInfobox/HouseInfobox.module.scss | 22 +- components/Infobox/Infobox.module.scss | 27 +- .../MainMenuTile/MainMenuTile.module.scss | 76 +++-- .../MapLayerToggle/MapLayerToggle.module.scss | 31 +- components/MapMarker/MapMarker.module.scss | 21 +- components/MapMarker/MapMarker.test.tsx | 10 +- components/MapMarker/MapMarker.tsx | 20 +- components/MapStage/MapStage.module.scss | 25 +- .../PageHeading/PageHeading.module.scss | 9 +- .../ParchmentLayout.module.scss | 27 +- components/SiteFooter/SiteFooter.module.scss | 48 +-- components/SiteHeader/SiteHeader.module.scss | 86 ++--- components/SiteMenu/SiteMenu.module.scss | 117 ++++--- components/SiteMenu/SiteMenu.tsx | 29 +- components/SortToggle/SortToggle.module.scss | 32 +- components/Sources/Sources.module.scss | 4 +- .../TimelineChart/TimelineChart.module.scss | 82 ++--- .../TimelineCluster.module.scss | 40 +-- .../TimelineExplorer.module.scss | 43 +-- .../TimelineMinimap.module.scss | 30 +- components/ViewToggle/ViewToggle.module.scss | 32 +- components/WorldMap/WorldMap.module.scss | 56 ++-- components/listSearch.module.scss | 91 +++--- styles/globals.scss | 246 +++++++++++---- 47 files changed, 1397 insertions(+), 937 deletions(-) diff --git a/app/battles/[slug]/page.module.scss b/app/battles/[slug]/page.module.scss index 4d3c7666..fa2494d9 100644 --- a/app/battles/[slug]/page.module.scss +++ b/app/battles/[slug]/page.module.scss @@ -62,7 +62,9 @@ display: block; width: 100%; height: auto; - border-radius: 0.25rem; + border: 1px solid var(--edge-strong); + border-radius: var(--bevel); + corner-shape: bevel; } .back { @@ -70,14 +72,15 @@ padding-bottom: 3rem; font-family: var(--font-ui); font-size: 0.9rem; + letter-spacing: 0.06em; text-align: center; a { - color: var(--ink-faded); + color: var(--gaslight-faint); text-decoration: none; &:hover { - color: var(--gold-leaf); + color: var(--hextech); } } } diff --git a/app/battles/page.module.scss b/app/battles/page.module.scss index 3174c87f..789720a4 100644 --- a/app/battles/page.module.scss +++ b/app/battles/page.module.scss @@ -22,8 +22,9 @@ .warName { font-family: var(--font-character-name); font-size: 1.5rem; - color: var(--ink); - border-bottom: 1px solid var(--gold-leaf); + color: var(--gaslight); + letter-spacing: 0.04em; + border-bottom: 1px solid var(--edge-brass); padding-bottom: 0.35rem; } @@ -46,45 +47,54 @@ gap: 1rem; align-items: baseline; padding: 0.5rem 0.75rem; - border-radius: 0.25rem; + border-radius: var(--bevel-sm); + corner-shape: bevel; text-decoration: none; - color: var(--ink); + color: var(--gaslight); transition: background-color 0.15s ease; &:hover { - background-color: rgba(212, 162, 89, 0.16); + background-color: rgba(199, 154, 63, 0.08); + } + + @media (prefers-reduced-motion: reduce) { + transition: none; } } .name { - display: inline-flex; + display: inline-grid; + grid-auto-flow: column; align-items: center; + justify-content: start; gap: 0.5rem; font-family: var(--font-ui); font-size: 1.05rem; } +// A charged node marks a battle with a full account behind it. .indicator { - flex: none; width: 0.5rem; height: 0.5rem; border-radius: 50%; - background-color: var(--gold-leaf); + background-color: var(--hextech); + box-shadow: 0 0 6px rgba(54, 214, 198, 0.55); } .when { font-family: var(--font-ui); font-size: 0.9rem; - color: var(--ink-faded); + color: var(--gaslight-faint); white-space: nowrap; + font-variant-numeric: tabular-nums; } .legend { margin-top: 2rem; font-family: var(--font-ui); font-size: 0.85rem; - color: var(--ink-faded); - font-style: italic; + color: var(--gaslight-faint); + letter-spacing: 0.04em; @media (max-width: bp.$md) { padding-left: 1.5rem; diff --git a/app/characters/[slug]/page.module.scss b/app/characters/[slug]/page.module.scss index 832cf891..0fe7cf5b 100644 --- a/app/characters/[slug]/page.module.scss +++ b/app/characters/[slug]/page.module.scss @@ -7,30 +7,38 @@ } .heading { - display: flex; + display: grid; + grid-auto-flow: column; + grid-auto-columns: max-content; align-items: center; justify-content: center; gap: 0.85rem; - flex-wrap: wrap; width: 100%; h1 { font-family: var(--font-character-name); - font-variant: normal; - font-weight: 600; - letter-spacing: 1px; + text-transform: none; + font-weight: 400; + letter-spacing: 0.06em; font-size: 2.6rem; line-height: 1.1; } + // Stack on small screens with the name above the sigil. @media (max-width: bp.$md) { - flex-direction: column-reverse; + grid-auto-flow: row; + grid-auto-columns: auto; + justify-items: center; gap: 0.5rem; + + > h1 { + order: -1; + } } } .sigilLink { - display: inline-flex; + display: inline-grid; border-radius: 2px; &:hover, @@ -41,12 +49,12 @@ .alias { font-family: var(--font-body); - font-variant: normal; + text-transform: none; font-style: italic; font-weight: 400; letter-spacing: 0; font-size: 0.6em; - color: var(--ink-faded); + color: var(--gaslight-dim); text-align: left; @media (max-width: bp.$md) { @@ -59,14 +67,15 @@ } .portrait { - display: flex; - justify-content: center; + display: grid; + justify-items: center; width: 100%; max-width: 1100px; - border-radius: 30px; - corner-shape: scoop; + border-radius: 24px; + corner-shape: bevel; overflow: hidden; - border: 1px solid var(--ink-faded); + border: 1px solid var(--edge-strong); + box-shadow: var(--shadow-raised); @media (max-width: bp.$md) { width: 100vw; @@ -79,7 +88,7 @@ } } -// Regional border tints for `.portrait` — colours live in `globals.scss` +// Regional border tints for `.portrait`; colours live in `globals.scss` // as `--region-color-*` tokens (shared with `FilteredHouseList`). .portraitNorth { border-color: var(--region-color-north); @@ -119,24 +128,25 @@ gap: 0.6rem 1.5rem; width: 100%; padding: 1rem 1.25rem; - background: rgba(248, 236, 208, 0.5); - border: 1px solid rgba(107, 68, 35, 0.2); - border-radius: 2px; + background: rgba(16, 23, 32, 0.55); + border: 1px solid var(--edge); + border-radius: var(--bevel-sm); + corner-shape: bevel; font-family: var(--font-ui); - font-size: 0.9rem; + font-size: 0.95rem; + letter-spacing: 0.03em; dt { - flex: 0 0 auto; - color: var(--ink-faded); + color: var(--brass); font-family: var(--font-sans); + font-weight: 500; text-transform: uppercase; - letter-spacing: 1px; + letter-spacing: 0.12em; font-size: 0.72rem; - font-weight: 500; } dd { - color: var(--ink); + color: var(--gaslight); margin: 0; padding: 0; } @@ -170,14 +180,14 @@ .unaffiliated { font-style: italic; - color: var(--ink-faded); + color: var(--gaslight-dim); } .titles { list-style: none; padding: 0; - display: flex; - flex-direction: column; + display: grid; + grid-template-columns: 1fr; gap: 0.15rem; } @@ -187,31 +197,28 @@ .relations { padding: 1rem 1.25rem; - background: rgba(248, 236, 208, 0.4); - border: 1px solid rgba(107, 68, 35, 0.15); - border-radius: 2px; + background: rgba(16, 23, 32, 0.45); + border: 1px solid var(--edge); + border-radius: var(--bevel-sm); + corner-shape: bevel; font-family: var(--font-ui); - font-size: 0.92rem; - display: flex; - flex-direction: column; + font-size: 0.95rem; + letter-spacing: 0.03em; + display: grid; + grid-template-columns: 1fr; gap: 0.5rem; dt { - flex: 0 0 5.5rem; - color: var(--ink-faded); + color: var(--brass); font-family: var(--font-sans); + font-weight: 500; text-transform: uppercase; - letter-spacing: 1px; + letter-spacing: 0.12em; font-size: 0.72rem; - font-weight: 500; - - @media (max-width: bp.$sm) { - flex-basis: 100%; - } } dd { - color: var(--ink); + color: var(--gaslight); } @media (max-width: bp.$md) { @@ -221,14 +228,19 @@ } .relationsRow { - display: flex; + display: grid; + grid-template-columns: 5.5rem 1fr; gap: 0.6rem; align-items: baseline; - flex-wrap: wrap; + + @media (max-width: bp.$sm) { + grid-template-columns: 1fr; + gap: 0.15rem; + } } .placeholder { - color: var(--ink-faded); + color: var(--gaslight-dim); font-style: italic; } @@ -243,14 +255,15 @@ .back { font-family: var(--font-ui); font-size: 0.9rem; + letter-spacing: 0.06em; text-align: center; a { - color: var(--ink-faded); + color: var(--gaslight-faint); text-decoration: none; &:hover { - color: var(--gold-leaf); + color: var(--hextech); } } } diff --git a/app/design/page.module.scss b/app/design/page.module.scss index 55d3d503..39fb76f0 100644 --- a/app/design/page.module.scss +++ b/app/design/page.module.scss @@ -14,36 +14,37 @@ .sectionIntro { font-family: var(--font-body); - font-size: 1rem; + font-size: 1.05rem; font-style: italic; - color: var(--ink-faded); + color: var(--gaslight-dim); max-width: 62ch; } .divider { width: min(320px, 60%); - color: var(--ink-faded); - opacity: 0.7; + color: var(--brass); + opacity: 0.85; } .code { - font-family: var(--font-sans); - font-size: 0.85em; + font-family: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace; + font-size: 0.8em; font-style: normal; - color: var(--ink); - background: rgba(139, 26, 26, 0.08); - border: 1px solid rgba(107, 68, 35, 0.2); - border-radius: 2px; + color: var(--hextech); + background: var(--well); + border: 1px solid var(--edge); + border-radius: 3px; padding: 0.1em 0.4em; } -// The shared small-caps caption idiom used for every token/spec label. +// The shared engraved caption idiom used for every token/spec label. .specLabel { font-family: var(--font-ui); - font-variant: small-caps; - font-size: 0.85rem; - letter-spacing: 1.5px; - color: var(--ink-faded); + font-weight: 500; + text-transform: uppercase; + font-size: 0.75rem; + letter-spacing: 0.16em; + color: var(--gaslight-faint); } // ------------------------------------------------------------------ colour @@ -64,11 +65,12 @@ .swatchChip { height: 76px; - border-radius: 2px; - border: 1px solid rgba(61, 40, 23, 0.25); + border-radius: var(--bevel-sm); + corner-shape: bevel; + border: 1px solid var(--edge-strong); box-shadow: - inset 0 0 0 1px rgba(248, 236, 208, 0.25), - 0 1px 3px rgba(61, 40, 23, 0.18); + inset 0 1px 0 rgba(255, 255, 255, 0.07), + var(--shadow-soft); } .swatchMeta { @@ -79,15 +81,16 @@ .swatchName { font-family: var(--font-ui); font-size: 1rem; - color: var(--ink); + letter-spacing: 0.03em; + color: var(--gaslight); } .swatchToken, .swatchHex { - font-family: var(--font-sans); - font-size: 0.75rem; - color: var(--ink-faded); - letter-spacing: 0.3px; + font-family: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace; + font-size: 0.7rem; + color: var(--gaslight-faint); + letter-spacing: 0.02em; } .swatchHex { @@ -107,7 +110,7 @@ gap: 1.25rem; align-items: baseline; padding-bottom: 1.25rem; - border-bottom: 1px dashed rgba(107, 68, 35, 0.22); + border-bottom: 1px dashed var(--edge); @media (max-width: bp.$sm) { grid-template-columns: 1fr; @@ -138,7 +141,7 @@ .fontSample { font-size: 1.6rem; - color: var(--ink); + color: var(--gaslight); line-height: 1.3; } @@ -159,18 +162,19 @@ align-items: center; } +// Each step runs from brass to hextech, metal charged along its length. .spaceBar { height: 18px; min-width: 4px; border-radius: 2px; - background: linear-gradient(90deg, var(--wax-seal), var(--rose-madder)); + background: linear-gradient(90deg, var(--brass), var(--hextech)); justify-self: start; } .spacePx { - font-family: var(--font-sans); - font-size: 0.75rem; - color: var(--ink-faded); + font-family: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace; + font-size: 0.7rem; + color: var(--gaslight-faint); } .spaceDemos { @@ -189,9 +193,9 @@ .padBox { display: grid; padding: 1.5rem; - border: 1px dashed rgba(107, 68, 35, 0.4); - border-radius: 2px; - background: rgba(212, 162, 89, 0.12); + border: 1px dashed var(--edge-strong); + border-radius: 3px; + background: rgba(199, 154, 63, 0.08); } .padInner { @@ -199,7 +203,7 @@ min-width: 120px; height: 40px; border-radius: 2px; - background: var(--gold-leaf); + background: var(--brass); } .gapRow { @@ -213,7 +217,7 @@ .gapBox { height: 40px; border-radius: 2px; - background: var(--gold-leaf); + background: var(--brass); } // ---------------------------------------------------------------- controls @@ -226,17 +230,20 @@ .group { display: grid; gap: 1.1rem; - border: 1px solid rgba(107, 68, 35, 0.25); - border-radius: 3px; + border: 1px solid var(--edge-strong); + border-radius: var(--bevel); + corner-shape: bevel; padding: 1.4rem 1.5rem 1.6rem; - background: rgba(248, 236, 208, 0.28); + background: rgba(16, 23, 32, 0.45); + box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03); } .groupLegend { font-family: var(--font-heading); - font-size: 1.05rem; - letter-spacing: 1px; - color: var(--ink-faded); + font-size: 0.95rem; + text-transform: uppercase; + letter-spacing: 0.14em; + color: var(--brass); padding: 0 0.5rem; } @@ -255,32 +262,36 @@ .fieldLabel { font-family: var(--font-ui); - font-variant: small-caps; - font-size: 0.95rem; - letter-spacing: 1px; - color: var(--ink-faded); + font-weight: 500; + text-transform: uppercase; + font-size: 0.8rem; + letter-spacing: 0.14em; + color: var(--gaslight-dim); } .fieldHint { - font-family: var(--font-sans); - font-size: 0.75rem; + font-family: var(--font-body); + font-size: 0.8rem; font-style: italic; - color: var(--ink-faded); + color: var(--gaslight-faint); } -// The canonical text control: the same parchment field used by the list -// search input, sized for regular forms. +// The canonical text control: a gunmetal well that charges hextech on +// focus. The list search input is the same field at display size. .control { appearance: none; -webkit-appearance: none; width: 100%; font-family: var(--font-ui); font-size: 1rem; + letter-spacing: 0.03em; padding: 0.6rem 0.75rem; - background: rgba(248, 236, 208, 0.55); - color: var(--ink); - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; + background: var(--well); + color: var(--gaslight); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.4); outline: none; transition: border-color 150ms ease, @@ -288,30 +299,33 @@ box-shadow 150ms ease; &::placeholder { - color: var(--ink-faded); - font-style: italic; + color: var(--gaslight-faint); } &:focus-visible { - border-color: var(--gold-leaf); - background: rgba(248, 236, 208, 0.9); - box-shadow: 0 0 0 2px rgba(212, 162, 89, 0.18); + border-color: rgba(54, 214, 198, 0.6); + background: rgba(7, 12, 18, 0.8); + box-shadow: + inset 0 1px 4px rgba(0, 0, 0, 0.4), + var(--focus-glow); } &:disabled { - opacity: 0.55; + opacity: 0.5; cursor: not-allowed; - background: rgba(248, 236, 208, 0.3); + background: rgba(7, 12, 18, 0.35); } &[readonly] { - background: rgba(248, 236, 208, 0.3); - color: var(--ink-faded); + background: rgba(7, 12, 18, 0.35); + color: var(--gaslight-dim); } &[aria-invalid="true"] { - border-color: var(--wax-seal); - box-shadow: 0 0 0 2px rgba(139, 26, 26, 0.14); + border-color: var(--ember); + box-shadow: + inset 0 1px 4px rgba(0, 0, 0, 0.4), + 0 0 0 2px rgba(226, 96, 78, 0.18); } @media (prefers-reduced-motion: reduce) { @@ -319,13 +333,13 @@ } } -// A select needs the hand-drawn chevron the native arrow can't match. +// A select needs the engraved chevron the native arrow can't match. select.control { cursor: pointer; padding-right: 2rem; background-image: - linear-gradient(45deg, transparent 50%, rgba(107, 68, 35, 0.55) 50%), - linear-gradient(135deg, rgba(107, 68, 35, 0.55) 50%, transparent 50%); + linear-gradient(45deg, transparent 50%, rgba(199, 154, 63, 0.75) 50%), + linear-gradient(135deg, rgba(199, 154, 63, 0.75) 50%, transparent 50%); background-position: calc(100% - 1.1rem) 55%, calc(100% - 0.8rem) 55%; @@ -355,14 +369,14 @@ select.control { } option:checked { - background: rgba(212, 162, 89, 0.4); - color: var(--ink); + background: rgba(54, 214, 198, 0.2); + color: var(--gaslight); } } .range { width: 100%; - accent-color: var(--gold-leaf); + accent-color: var(--hextech); cursor: pointer; } @@ -370,34 +384,39 @@ select.control { width: 100%; height: 3rem; padding: 0.2rem; - background: rgba(248, 236, 208, 0.55); - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; + background: var(--well); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; cursor: pointer; &:focus-visible { - border-color: var(--gold-leaf); + border-color: rgba(54, 214, 198, 0.6); outline: none; - box-shadow: 0 0 0 2px rgba(212, 162, 89, 0.18); + box-shadow: var(--focus-glow); } } .file { width: 100%; - font-family: var(--font-sans); + font-family: var(--font-ui); font-size: 0.85rem; - color: var(--ink-faded); + letter-spacing: 0.04em; + color: var(--gaslight-faint); &::file-selector-button { font-family: var(--font-ui); + font-weight: 500; font-size: 0.85rem; - letter-spacing: 0.5px; + text-transform: uppercase; + letter-spacing: 0.08em; margin-right: 0.75rem; padding: 0.45rem 0.9rem; - background: rgba(248, 236, 208, 0.6); - color: var(--ink); - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; + background: var(--plate); + color: var(--gaslight); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; cursor: pointer; transition: border-color 120ms ease, @@ -405,8 +424,8 @@ select.control { } &::file-selector-button:hover { - border-color: var(--gold-leaf); - color: var(--gold-leaf); + border-color: var(--edge-brass); + color: var(--brass-bright); } } @@ -415,18 +434,20 @@ select.control { .optionSet { display: grid; gap: 0.65rem; - border: 1px solid rgba(107, 68, 35, 0.3); - border-radius: 2px; + border: 1px solid var(--edge); + border-radius: var(--bevel-sm); + corner-shape: bevel; padding: 1rem 1.2rem 1.15rem; - background: rgba(248, 236, 208, 0.4); + background: rgba(13, 19, 27, 0.4); } .optionLegend { font-family: var(--font-ui); - font-variant: small-caps; - font-size: 0.9rem; - letter-spacing: 1px; - color: var(--ink-faded); + font-weight: 500; + text-transform: uppercase; + font-size: 0.8rem; + letter-spacing: 0.14em; + color: var(--gaslight-dim); padding: 0 0.4rem; } @@ -437,18 +458,18 @@ select.control { align-items: center; font-family: var(--font-body); font-size: 1.05rem; - color: var(--ink); + color: var(--gaslight); cursor: pointer; } .check { width: 1.15rem; height: 1.15rem; - accent-color: var(--gold-leaf); + accent-color: var(--hextech); cursor: pointer; &:focus-visible { - outline: 2px solid var(--gold-leaf); + outline: 2px solid var(--hextech); outline-offset: 2px; } } @@ -463,7 +484,7 @@ select.control { cursor: pointer; font-family: var(--font-body); font-size: 1.05rem; - color: var(--ink); + color: var(--gaslight); } // Visually hidden but focusable and in the tab order; the track/thumb render @@ -483,10 +504,11 @@ select.control { height: 26px; padding: 2px; border-radius: 13px; - border: 1px solid rgba(107, 68, 35, 0.35); - background: rgba(107, 68, 35, 0.28); + border: 1px solid var(--edge-strong); + background: rgba(7, 12, 18, 0.7); transition: background 150ms ease, + border-color 150ms ease, box-shadow 150ms ease; } @@ -494,14 +516,17 @@ select.control { width: 18px; height: 18px; border-radius: 50%; - background: var(--vellum); - box-shadow: 0 1px 2px rgba(61, 40, 23, 0.4); + background: var(--gaslight); + box-shadow: 0 1px 3px rgba(4, 8, 13, 0.6); transform: translateX(0); transition: transform 150ms ease; } +// Thrown on, the switch runs charged. .switchInput:checked ~ .switchTrack { - background: var(--gold-leaf); + background: var(--hextech-dim); + border-color: rgba(54, 214, 198, 0.5); + box-shadow: inset 0 0 8px rgba(54, 214, 198, 0.3); } .switchInput:checked ~ .switchTrack .switchThumb { @@ -509,8 +534,8 @@ select.control { } .switchInput:focus-visible ~ .switchTrack { - border-color: var(--gold-leaf); - box-shadow: 0 0 0 2px rgba(212, 162, 89, 0.35); + border-color: rgba(54, 214, 198, 0.6); + box-shadow: var(--focus-glow); } @media (prefers-reduced-motion: reduce) { @@ -538,23 +563,31 @@ select.control { .btn { appearance: none; font-family: var(--font-ui); - font-size: 0.95rem; - letter-spacing: 0.5px; + font-weight: 500; + font-size: 0.9rem; + text-transform: uppercase; + letter-spacing: 0.1em; padding: 0.6rem 1.3rem; - border-radius: 2px; - border: 1px solid rgba(107, 68, 35, 0.35); - background: rgba(248, 236, 208, 0.6); - color: var(--ink); + border-radius: var(--bevel-sm); + corner-shape: bevel; + border: 1px solid var(--edge-strong); + background: var(--plate); + color: var(--gaslight); cursor: pointer; transition: border-color 120ms ease, background 120ms ease, - color 120ms ease; + color 120ms ease, + box-shadow 120ms ease; + + &:hover:not(:disabled) { + border-color: var(--edge-brass); + color: var(--brass-bright); + } - &:hover:not(:disabled), &:focus-visible:not(:disabled) { - border-color: var(--gold-leaf); - color: var(--gold-leaf); + border-color: rgba(54, 214, 198, 0.6); + box-shadow: var(--focus-glow); outline: none; } @@ -568,22 +601,40 @@ select.control { } } +// The one loud control on the bench: a machined brass plate with an +// engraved label. .btnPrimary { @extend .btn; - background: var(--wax-seal); - border-color: var(--wax-seal); - color: var(--vellum); + font-weight: 600; + background: linear-gradient( + 180deg, + var(--brass-bright) 0%, + var(--brass) 55%, + #a87f30 100% + ); + border-color: var(--brass-dark); + color: #201503; + + &:hover:not(:disabled) { + filter: brightness(1.07); + border-color: var(--brass-dark); + color: #201503; + box-shadow: var(--brass-glow); + } - &:hover:not(:disabled), &:focus-visible:not(:disabled) { - color: var(--vellum); - border-color: var(--wax-seal); - filter: brightness(1.12); - box-shadow: 0 0 0 2px rgba(212, 162, 89, 0.3); + color: #201503; + box-shadow: var(--focus-glow); } } .btnGhost { @extend .btn; background: transparent; + border-color: rgba(199, 154, 63, 0.4); + color: var(--brass-bright); + + &:hover:not(:disabled) { + background: rgba(199, 154, 63, 0.08); + } } diff --git a/app/design/page.tsx b/app/design/page.tsx index 333754ab..27be9787 100644 --- a/app/design/page.tsx +++ b/app/design/page.tsx @@ -9,7 +9,7 @@ import styles from "@/app/design/page.module.scss"; export const metadata: Metadata = { title: "Design System · Atlas of the Known World", description: - "The visual grammar of the Known World: type, colour, spacing, and the full roll of form controls.", + "The visual grammar of the Known World: colour, type, spacing, and every control on the bench.", }; type Swatch = { token: string; hex: string; name: string }; @@ -18,32 +18,37 @@ type Swatch = { token: string; hex: string; name: string }; // tokens declared in `styles/globals.scss`. This page is the living catalogue // of those tokens; keep it in step when a token is added or renamed there. const CORE_PALETTE: Swatch[] = [ - { token: "--parchment-light", hex: "#f4e4c1", name: "Parchment Light" }, - { token: "--parchment-dark", hex: "#e8d3a0", name: "Parchment Dark" }, - { token: "--vellum", hex: "#f8ecd0", name: "Vellum" }, - { token: "--ink", hex: "#3d2817", name: "Ink" }, - { token: "--ink-faded", hex: "#6b4423", name: "Ink Faded" }, - { token: "--ink-slate", hex: "#2e3a55", name: "Ink Slate" }, - { token: "--ink-rose", hex: "#6a3142", name: "Ink Rose" }, - { token: "--wax-seal", hex: "#8b1a1a", name: "Wax Seal" }, - { token: "--gold-leaf", hex: "#d4a259", name: "Gold Leaf" }, - { token: "--rose-madder", hex: "#a85a6b", name: "Rose Madder" }, + { token: "--coal", hex: "#0a0e15", name: "Coal" }, + { token: "--iron", hex: "#111923", name: "Iron" }, + { token: "--gunmetal", hex: "#1a2530", name: "Gunmetal" }, + { token: "--gunmetal-raised", hex: "#223040", name: "Raised Gunmetal" }, + { token: "--steel", hex: "#2e3d4e", name: "Steel" }, + { token: "--brass", hex: "#c79a3f", name: "Brass" }, + { token: "--brass-bright", hex: "#ecca7d", name: "Bright Brass" }, + { token: "--brass-dark", hex: "#8a6828", name: "Dark Brass" }, + { token: "--hextech", hex: "#36d6c6", name: "Hextech" }, + { token: "--hextech-dim", hex: "#17756d", name: "Deep Hextech" }, + { token: "--shimmer", hex: "#b660e8", name: "Shimmer" }, + { token: "--gaslight", hex: "#eee6d3", name: "Gaslight" }, + { token: "--gaslight-dim", hex: "#b0a893", name: "Dim Gaslight" }, + { token: "--gaslight-faint", hex: "#7e8798", name: "Faint Gaslight" }, + { token: "--ember", hex: "#e2604e", name: "Ember" }, ]; const REGION_PALETTE: Swatch[] = [ - { token: "--region-color-north", hex: "#5d6f7f", name: "North" }, - { token: "--region-color-vale", hex: "#4d7caa", name: "Vale" }, - { token: "--region-color-riverlands", hex: "#3d5a7c", name: "Riverlands" }, - { token: "--region-color-westerlands", hex: "#b13a3a", name: "Westerlands" }, - { token: "--region-color-reach", hex: "#6f8336", name: "Reach" }, - { token: "--region-color-stormlands", hex: "#c89a31", name: "Stormlands" }, - { token: "--region-color-dorne", hex: "#c7693a", name: "Dorne" }, + { token: "--region-color-north", hex: "#8ba7bb", name: "North" }, + { token: "--region-color-vale", hex: "#6ca6d9", name: "Vale" }, + { token: "--region-color-riverlands", hex: "#5d86b5", name: "Riverlands" }, + { token: "--region-color-westerlands", hex: "#d15954", name: "Westerlands" }, + { token: "--region-color-reach", hex: "#96b054", name: "Reach" }, + { token: "--region-color-stormlands", hex: "#dcb14e", name: "Stormlands" }, + { token: "--region-color-dorne", hex: "#d98550", name: "Dorne" }, { token: "--region-color-iron-islands", - hex: "#2f4a44", + hex: "#62918a", name: "Iron Islands", }, - { token: "--region-color-crownlands", hex: "#5a2a30", name: "Crownlands" }, + { token: "--region-color-crownlands", hex: "#b25a66", name: "Crownlands" }, ]; type FontRole = { family: string; label: string; sample: string }; @@ -51,22 +56,22 @@ type FontRole = { family: string; label: string; sample: string }; const FONT_ROLES: FontRole[] = [ { family: "var(--font-heading)", - label: "Cinzel · Headings", + label: "Girassol · Headings", sample: "The Known World", }, { family: "var(--font-character-name)", - label: "Cormorant Unicase · Character names", + label: "Poiret One · Nameplates", sample: "Eddard Stark", }, { family: "var(--font-body)", - label: "EB Garamond · Body & UI", + label: "Spectral · Body", sample: "The night is dark and full of terrors.", }, { family: "var(--font-sans)", - label: "Alegreya Sans · Data & captions", + label: "Barlow Condensed · Labels & data", sample: "298 AC · 42 houses · 9 regions", }, ]; @@ -210,7 +215,7 @@ export default function DesignSystemPage() { {/* ---------------------------------------------------------------- */} @@ -265,8 +270,9 @@ export default function DesignSystemPage() {

Typography

- Headings are set in Cinzel; body copy in EB Garamond. The scale below - renders each element exactly as the global stylesheet styles it. + Headings are engraved in Girassol; body copy is set in Spectral. The + scale below renders each element exactly as the global stylesheet + styles it.

@@ -304,8 +310,8 @@ export default function DesignSystemPage() {

Words can carry bold weight or an{" "} italic aside, and a{" "} - cross-reference links onward in ink - and gold. + cross-reference links onward in brass + and hextech.

@@ -380,9 +386,9 @@ export default function DesignSystemPage() {

Form controls

- Every native control, dressed in parchment and ink. Try them: the - fields hold their own state, and Reset fields restores the - defaults. + Every native control, machined in gunmetal and brass and charged with + hextech. Try them: the fields hold their own state, and{" "} + Reset fields restores the defaults.

@@ -441,7 +447,7 @@ export default function DesignSystemPage() { id="df-color" className={styles.colorInput} type="color" - defaultValue="#8b1a1a" + defaultValue="#36d6c6" /> diff --git a/app/dragons/[slug]/page.module.scss b/app/dragons/[slug]/page.module.scss index e9e7deb0..31a6964a 100644 --- a/app/dragons/[slug]/page.module.scss +++ b/app/dragons/[slug]/page.module.scss @@ -59,14 +59,15 @@ padding-bottom: 3rem; font-family: var(--font-ui); font-size: 0.9rem; + letter-spacing: 0.06em; text-align: center; a { - color: var(--ink-faded); + color: var(--gaslight-faint); text-decoration: none; &:hover { - color: var(--gold-leaf); + color: var(--hextech); } } } diff --git a/app/events/[slug]/page.module.scss b/app/events/[slug]/page.module.scss index b0058306..761c5cf7 100644 --- a/app/events/[slug]/page.module.scss +++ b/app/events/[slug]/page.module.scss @@ -48,14 +48,15 @@ padding-bottom: 3rem; font-family: var(--font-ui); font-size: 0.9rem; + letter-spacing: 0.06em; text-align: center; a { - color: var(--ink-faded); + color: var(--gaslight-faint); text-decoration: none; &:hover { - color: var(--gold-leaf); + color: var(--hextech); } } } diff --git a/app/houses/[slug]/page.module.scss b/app/houses/[slug]/page.module.scss index 954a36b8..c4003e82 100644 --- a/app/houses/[slug]/page.module.scss +++ b/app/houses/[slug]/page.module.scss @@ -40,12 +40,11 @@ h1 { font-family: var(--font-character-name); + text-transform: none; font-size: 2.7rem; - letter-spacing: 0.04em; + letter-spacing: 0.05em; line-height: 1.05; - text-shadow: - 0 1px 0 rgba(255, 250, 235, 0.5), - 0 2px 5px rgba(61, 40, 23, 0.12); + text-shadow: 0 2px 10px rgba(4, 8, 13, 0.6); @media (max-width: bp.$sm) { font-size: 2.1rem; @@ -57,7 +56,7 @@ padding-bottom: 0; font-size: 1.2rem; letter-spacing: 0.02em; - color: var(--ink-faded); + color: var(--gaslight-dim); } } @@ -116,9 +115,9 @@ li { padding: 0.4rem 0.75rem; - background: rgba(248, 236, 208, 0.6); - border: 1px solid rgba(107, 68, 35, 0.15); - border-radius: 2px; + background: rgba(16, 23, 32, 0.55); + border: 1px solid var(--edge); + border-radius: 3px; line-height: 1.45; } } @@ -126,7 +125,7 @@ .notableName { font-family: var(--font-body); font-weight: 600; - color: var(--ink); + color: var(--gaslight); } a.notableName { @@ -135,9 +134,9 @@ a.notableName { &:hover, &:focus-visible { - color: var(--gold-leaf); + color: var(--hextech); text-decoration: underline; - text-decoration-color: rgba(212, 162, 89, 0.45); + text-decoration-color: rgba(54, 214, 198, 0.45); outline: none; } @@ -148,7 +147,7 @@ a.notableName { .notableNote { font-family: var(--font-body); - color: var(--ink-faded); + color: var(--gaslight-dim); } .back { @@ -156,14 +155,15 @@ a.notableName { padding-bottom: 3rem; font-family: var(--font-ui); font-size: 0.9rem; + letter-spacing: 0.06em; text-align: center; a { - color: var(--ink-faded); + color: var(--gaslight-faint); text-decoration: none; &:hover { - color: var(--gold-leaf); + color: var(--hextech); } } } diff --git a/app/layout.tsx b/app/layout.tsx index 0f57b32c..396b2453 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,9 +1,9 @@ import type { Metadata, Viewport } from "next"; import { - Alegreya_Sans, - Cinzel, - Cormorant_Unicase, - EB_Garamond, + Barlow_Condensed, + Girassol, + Poiret_One, + Spectral, } from "next/font/google"; import { NuqsAdapter } from "nuqs/adapters/next/app"; import "../styles/globals.scss"; @@ -11,25 +11,26 @@ import { SiteHeader } from "@/components/SiteHeader"; import { SiteMenu } from "@/components/SiteMenu"; import { SiteFooter } from "@/components/SiteFooter"; -const cinzel = Cinzel({ +const girassol = Girassol({ subsets: ["latin"], - variable: "--font-cinzel", - weight: ["400", "600", "700"], + variable: "--font-girassol", + weight: "400", }); -const cormorantUnicase = Cormorant_Unicase({ +const poiretOne = Poiret_One({ subsets: ["latin"], - variable: "--font-cormorant-unicase", - weight: ["500", "600", "700"], + variable: "--font-poiret-one", + weight: "400", }); -const ebGaramond = EB_Garamond({ +const spectral = Spectral({ subsets: ["latin"], - variable: "--font-eb-garamond", - weight: ["400", "500", "600"], + variable: "--font-spectral", + weight: ["300", "400", "500", "600"], + style: ["normal", "italic"], }); -const alegreyaSans = Alegreya_Sans({ +const barlowCondensed = Barlow_Condensed({ subsets: ["latin"], - variable: "--font-alegreya-sans", - weight: ["400", "500", "700"], + variable: "--font-barlow-condensed", + weight: ["400", "500", "600"], }); export const metadata: Metadata = { @@ -54,7 +55,7 @@ export default function RootLayout({ return ( diff --git a/app/timeline/page.module.scss b/app/timeline/page.module.scss index b653c6f8..714ca8d7 100644 --- a/app/timeline/page.module.scss +++ b/app/timeline/page.module.scss @@ -9,10 +9,11 @@ margin-top: 2rem; font-family: var(--font-ui); font-size: 0.85rem; - color: var(--ink-faded); - font-style: italic; + color: var(--gaslight-faint); + letter-spacing: 0.04em; @media (max-width: bp.$md) { padding-left: 1.5rem; + padding-right: 1.5rem; } } diff --git a/app/weapons/[slug]/page.module.scss b/app/weapons/[slug]/page.module.scss index 98b31bd8..893624c5 100644 --- a/app/weapons/[slug]/page.module.scss +++ b/app/weapons/[slug]/page.module.scss @@ -57,9 +57,12 @@ display: grid; width: 100%; overflow: hidden; - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 4px; - box-shadow: 0 2px 12px rgba(40, 25, 10, 0.12); + border: 1px solid var(--edge-brass); + border-radius: var(--bevel); + corner-shape: bevel; + box-shadow: + inset 0 0 30px rgba(4, 8, 13, 0.35), + var(--shadow-soft); margin: 0; img { @@ -85,14 +88,15 @@ padding-bottom: 3rem; font-family: var(--font-ui); font-size: 0.9rem; + letter-spacing: 0.06em; text-align: center; a { - color: var(--ink-faded); + color: var(--gaslight-faint); text-decoration: none; &:hover { - color: var(--gold-leaf); + color: var(--hextech); } } } diff --git a/components/Accordion/Accordion.module.scss b/components/Accordion/Accordion.module.scss index 5c29f859..f102373c 100644 --- a/components/Accordion/Accordion.module.scss +++ b/components/Accordion/Accordion.module.scss @@ -1,7 +1,8 @@ .accordion { - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; - background: rgba(248, 236, 208, 0.35); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel); + corner-shape: bevel; + background: rgba(13, 19, 27, 0.5); overflow: hidden; } @@ -18,10 +19,10 @@ align-items: center; gap: 0.75rem; padding: 0.9rem 1.1rem; - background: rgba(248, 236, 208, 0.55); + background: var(--plate); border: 0; cursor: pointer; - color: var(--ink); + color: var(--gaslight); font-family: var(--font-character-name); font-size: 1.3rem; text-align: left; @@ -31,23 +32,31 @@ &:hover, &:focus-visible { - background: rgba(248, 236, 208, 0.9); - color: var(--gold-leaf); + background: linear-gradient(180deg, #283a4d 0%, var(--gunmetal) 100%); + color: var(--brass-bright); outline: none; } + + @media (prefers-reduced-motion: reduce) { + transition: none; + } } .chevron { - color: var(--ink-faded); - transition: transform 150ms ease; + color: var(--gaslight-faint); + transition: + transform 150ms ease, + color 150ms ease; @media (prefers-reduced-motion: reduce) { transition: none; } } +// An open drawer is a live circuit: the chevron turns and charges. .chevronOpen { transform: rotate(90deg); + color: var(--hextech); } .title { @@ -56,16 +65,17 @@ .count { font-family: var(--font-ui); - font-size: 0.9rem; - color: var(--ink-faded); - font-variant: small-caps; - letter-spacing: 1px; + font-size: 0.8rem; + font-weight: 500; + color: var(--gaslight-faint); + text-transform: uppercase; + letter-spacing: 0.12em; } .panel { - display: flex; - flex-direction: column; + display: grid; + grid-template-columns: 1fr; gap: 1rem; padding: 1rem 1.1rem 1.25rem; - border-top: 1px solid rgba(107, 68, 35, 0.2); + border-top: 1px solid var(--edge); } diff --git a/components/CharacterSearchInput/CharacterSearchInput.module.scss b/components/CharacterSearchInput/CharacterSearchInput.module.scss index ffe87173..99762dae 100644 --- a/components/CharacterSearchInput/CharacterSearchInput.module.scss +++ b/components/CharacterSearchInput/CharacterSearchInput.module.scss @@ -26,26 +26,29 @@ gap: 0.15rem; max-height: 18rem; overflow-y: auto; - background: rgba(248, 236, 208, 0.97); - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; - box-shadow: 0 8px 24px rgba(31, 18, 8, 0.22); + background: #1c2836; + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + box-shadow: var(--shadow-raised); } .option { - display: flex; + display: grid; + grid-template-columns: auto 1fr; align-items: baseline; gap: 0.5rem; padding: 0.55rem 0.7rem; border-radius: 2px; cursor: pointer; - color: var(--ink); + color: var(--gaslight); font-family: var(--font-character-name); font-size: 1.4rem; } +// The keyboard-active row runs charged. .optionActive { - background: rgba(212, 162, 89, 0.22); + background: rgba(54, 214, 198, 0.14); } .optionName { @@ -56,5 +59,5 @@ font-family: var(--font-body); font-style: italic; font-size: 0.95rem; - color: var(--ink-faded); + color: var(--gaslight-dim); } diff --git a/components/ComingSoonPage/ComingSoonPage.module.scss b/components/ComingSoonPage/ComingSoonPage.module.scss index 873096d1..fb1cd279 100644 --- a/components/ComingSoonPage/ComingSoonPage.module.scss +++ b/components/ComingSoonPage/ComingSoonPage.module.scss @@ -2,12 +2,13 @@ text-align: center; font-family: var(--font-ui); font-size: 0.8rem; - letter-spacing: 1px; + font-weight: 500; + letter-spacing: 0.16em; text-transform: uppercase; - color: var(--ink-faded); + color: var(--gaslight-faint); } .caption a { text-decoration: none; - color: var(--ink-faded); + color: var(--gaslight-faint); } diff --git a/components/DropCap/DropCap.module.scss b/components/DropCap/DropCap.module.scss index 7aab0b44..b8532f6e 100644 --- a/components/DropCap/DropCap.module.scss +++ b/components/DropCap/DropCap.module.scss @@ -3,6 +3,6 @@ font-size: 3.2rem; line-height: 1; padding: 0.15rem 0.5rem 0 0; - color: var(--ink-faded); - font-weight: 600; + color: var(--brass); + font-weight: 400; } diff --git a/components/FamilyTree/FamilyTree.module.scss b/components/FamilyTree/FamilyTree.module.scss index 9150d777..cf29598d 100644 --- a/components/FamilyTree/FamilyTree.module.scss +++ b/components/FamilyTree/FamilyTree.module.scss @@ -23,13 +23,14 @@ display: grid; gap: 0.2rem; + // Descent lines are pipework: cold steel rails between generations. &::before { content: ""; position: absolute; left: 0.4rem; top: 0; bottom: 0; - border-left: 1px solid rgba(107, 68, 35, 0.35); + border-left: 1px solid var(--edge-strong); } &::after { @@ -38,7 +39,7 @@ left: 0.4rem; top: 0.85rem; width: 1rem; - border-top: 1px solid rgba(107, 68, 35, 0.35); + border-top: 1px solid var(--edge-strong); } &:last-child::before { @@ -56,29 +57,35 @@ } .row { - display: flex; + display: grid; + grid-auto-flow: column; + grid-auto-columns: max-content; + justify-content: start; align-items: baseline; - flex-wrap: wrap; gap: 0.4rem 0.6rem; padding: 0.25rem 0.6rem; width: fit-content; max-width: 100%; - background: rgba(248, 236, 208, 0.6); - border: 1px solid rgba(107, 68, 35, 0.15); - border-radius: 2px; + background: rgba(16, 23, 32, 0.55); + border: 1px solid var(--edge); + border-radius: 3px; @media (max-width: bp.$sm) { + grid-auto-flow: row; + justify-items: start; padding: 0.4rem 0.6rem; } } .rowPlaceholder { background: transparent; - border: 1px dotted rgba(107, 68, 35, 0.55); + border: 1px dotted var(--edge-strong); } .person { - display: flex; + display: grid; + grid-auto-flow: column; + grid-auto-columns: max-content; align-items: baseline; gap: 0.45rem; } @@ -86,7 +93,7 @@ .name { font-family: var(--font-body); font-size: 1rem; - color: var(--ink); + color: var(--gaslight); font-weight: 500; } @@ -97,9 +104,9 @@ a.name { &:hover, &:focus-visible { - color: var(--gold-leaf); + color: var(--hextech); text-decoration: underline; - text-decoration-color: rgba(212, 162, 89, 0.45); + text-decoration-color: rgba(54, 214, 198, 0.45); outline: none; } @@ -109,29 +116,30 @@ a.name { } .nameM { - color: var(--ink-slate); + color: var(--tint-male); } .nameF { - color: var(--ink-rose); + color: var(--tint-female); } .nameExternal { - color: var(--ink-faded); + color: var(--gaslight-dim); font-style: italic; } .namePlaceholder { - color: var(--ink-faded); + color: var(--gaslight-dim); font-style: italic; opacity: 0.8; } .lifespan { font-family: var(--font-ui); - font-size: 0.72rem; - color: var(--ink-faded); - letter-spacing: 0.5px; + font-size: 0.75rem; + color: var(--gaslight-faint); + letter-spacing: 0.05em; + font-variant-numeric: tabular-nums; } .alias { @@ -139,17 +147,19 @@ a.name { font-style: italic; font-weight: 400; font-size: 0.78rem; - color: var(--ink-faded); + color: var(--gaslight-dim); } .spouse { - display: flex; + display: grid; + grid-auto-flow: column; + grid-auto-columns: max-content; align-items: baseline; gap: 0.3rem; } .cross { - color: var(--gold-leaf); + color: var(--brass); font-size: 0.95rem; } @@ -159,22 +169,22 @@ a.name { } .genderM { - color: var(--gold-leaf); + color: var(--tint-male); } .genderF { - color: var(--rose-madder); + color: var(--tint-female); } .king { font-size: 0.85rem; - color: var(--gold-leaf); + color: var(--brass-bright); padding-right: 0.15rem; } .empty { font-style: italic; - color: var(--ink-faded); + color: var(--gaslight-dim); text-align: center; padding: 2rem 1rem; } diff --git a/components/FamilyTreeChart/FamilyTreeChart.module.scss b/components/FamilyTreeChart/FamilyTreeChart.module.scss index 0df23dc6..d23199a7 100644 --- a/components/FamilyTreeChart/FamilyTreeChart.module.scss +++ b/components/FamilyTreeChart/FamilyTreeChart.module.scss @@ -3,9 +3,10 @@ width: 100%; height: clamp(500px, 75vh, 900px); overflow: hidden; - border: 1px solid rgba(107, 68, 35, 0.25); - border-radius: 2px; - background: rgba(248, 236, 208, 0.45); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel); + corner-shape: bevel; + background: rgba(13, 19, 27, 0.5); touch-action: none; user-select: none; } @@ -22,8 +23,8 @@ } .dot { - fill: rgba(248, 236, 208, 0.85); - stroke: rgba(107, 68, 35, 0.6); + fill: var(--gunmetal-raised); + stroke: rgba(126, 152, 180, 0.65); stroke-width: 1.5; } @@ -39,26 +40,28 @@ .label { font-family: var(--font-ui); font-size: 9px; - fill: var(--ink-faded); + fill: var(--gaslight-dim); text-anchor: middle; pointer-events: none; } +// Solid backing that approximates the canvas colour so labels mask the +// edges passing beneath them. .labelBg { - fill: #f8ecd0; + fill: #141d27; pointer-events: none; } .cross { font-family: var(--font-body); font-size: 10px; - fill: var(--gold-leaf); + fill: var(--brass); text-anchor: middle; pointer-events: none; } .edge { - stroke: rgba(107, 68, 35, 0.5); + stroke: rgba(126, 152, 180, 0.4); stroke-width: 1; fill: none; } @@ -69,7 +72,7 @@ width: 100%; height: 100%; font-style: italic; - color: var(--ink-faded); + color: var(--gaslight-dim); padding: 2rem 1rem; text-align: center; } @@ -81,15 +84,17 @@ display: grid; gap: 0.25rem; padding: 0.4rem; - background: rgba(248, 236, 208, 0.92); - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; + background: rgba(20, 29, 40, 0.92); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; font-family: var(--font-ui); z-index: 1; } .controlRow { - display: flex; + display: grid; + grid-auto-flow: column; gap: 0.2rem; justify-content: center; } @@ -97,28 +102,31 @@ .controlButton { appearance: none; background: transparent; - border: 1px solid rgba(107, 68, 35, 0.25); + border: 1px solid var(--edge); border-radius: 2px; font-size: 0.7rem; + letter-spacing: 0.04em; padding: 0.15rem 0.4rem; min-width: 1.5rem; - color: var(--ink-faded); + color: var(--gaslight-dim); cursor: pointer; transition: background 120ms ease, - color 120ms ease; + color 120ms ease, + border-color 120ms ease; &:hover, &:focus-visible { - color: var(--gold-leaf); - background: rgba(212, 162, 89, 0.18); + color: var(--brass-bright); + background: rgba(199, 154, 63, 0.1); outline: none; } + // The engaged mode runs charged. &[aria-pressed="true"] { - color: var(--ink); - background: rgba(212, 162, 89, 0.28); - border-color: rgba(212, 162, 89, 0.55); + color: var(--hextech); + background: rgba(54, 214, 198, 0.12); + border-color: rgba(54, 214, 198, 0.45); } @media (prefers-reduced-motion: reduce) { @@ -138,5 +146,5 @@ z-index: 1000; border: 0; border-radius: 0; - background: rgb(248, 236, 208); + background: var(--iron); } diff --git a/components/Filigree/Filigree.module.scss b/components/Filigree/Filigree.module.scss index 17a3efc1..f3c92314 100644 --- a/components/Filigree/Filigree.module.scss +++ b/components/Filigree/Filigree.module.scss @@ -1,9 +1,9 @@ .flourish { display: grid; align-items: center; - color: var(--gold-leaf); + color: var(--brass); line-height: 0; - opacity: 0.85; + opacity: 0.9; pointer-events: none; svg { @@ -20,9 +20,9 @@ .rule { display: grid; justify-items: center; - color: var(--gold-leaf); + color: var(--brass); line-height: 0; - opacity: 0.9; + opacity: 0.95; pointer-events: none; -webkit-mask-image: linear-gradient( 90deg, @@ -45,3 +45,31 @@ height: auto; } } + +// The crystal itself: charged hextech, softly breathing. The one moving +// part of the whole page furniture. +.gem { + fill: var(--hextech); + filter: drop-shadow(0 0 4px rgba(54, 214, 198, 0.65)); + animation: gem-breathe 4.5s ease-in-out infinite; + + @media (prefers-reduced-motion: reduce) { + animation: none; + } +} + +.gemFacet { + stroke: var(--coal); + stroke-width: 0.8; + opacity: 0.45; +} + +@keyframes gem-breathe { + 0%, + 100% { + opacity: 0.78; + } + 50% { + opacity: 1; + } +} diff --git a/components/Filigree/Filigree.tsx b/components/Filigree/Filigree.tsx index 3c1bb6d3..d1eec33f 100644 --- a/components/Filigree/Filigree.tsx +++ b/components/Filigree/Filigree.tsx @@ -6,6 +6,8 @@ type FlourishProps = { className?: string; }; +// A short conduit: an engraved rail feeding a cogwheel, ending in a charged +// spark. Reads left to right; `mirrored` flips it for the right-hand side. export function FiligreeFlourish({ mirrored = false, className, @@ -16,17 +18,21 @@ export function FiligreeFlourish({ aria-hidden="true" > - - - - + + + + + + + + + + + + + ); @@ -36,18 +42,32 @@ type RuleProps = { className?: string; }; +// The atlas signature: a hextech crystal set into an engraved rail, ringed +// by cog collars. It underlines every page title and divides long pages. export function FiligreeRule({ className }: RuleProps) { return ( ); diff --git a/components/FilteredCharacterList/FilteredCharacterList.module.scss b/components/FilteredCharacterList/FilteredCharacterList.module.scss index 9076d9e2..ac77ebe1 100644 --- a/components/FilteredCharacterList/FilteredCharacterList.module.scss +++ b/components/FilteredCharacterList/FilteredCharacterList.module.scss @@ -2,7 +2,7 @@ // `ParchmentLayout`'s `.page` uses `justify-items: center` so the `h1` // and `.subtitle` size to their content. `justify-self: stretch` opts -// this grid back out so it fills the full parchment column. +// this grid back out so it fills the full page column. .list { list-style: none; padding: 0; @@ -14,7 +14,7 @@ } // Make the `
  • ` a single-cell grid so the inner `` stretches to -// fill the row's auto height — otherwise the tallest card in a row +// fill the row's auto height; otherwise the tallest card in a row // (one with an alias) leaves its shorter neighbours visually short. .item { margin: 0; @@ -29,21 +29,24 @@ "name" "alias"; align-content: start; - background: var(--vellum); - border: 2px solid rgba(107, 68, 35, 0.25); - border-radius: 2px; - color: var(--ink); + background: var(--plate); + border: 2px solid var(--edge-strong); + border-radius: var(--bevel); + corner-shape: bevel; + color: var(--gaslight); text-decoration: none; text-align: center; overflow: hidden; - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.04); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.04), + var(--shadow-soft); transition: border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease; } -// Regional border tints — colours live in `globals.scss` as +// Regional border tints; colours live in `globals.scss` as // `--region-color-*` tokens (shared with `FilteredHouseList`). .cardNorth { border-color: var(--region-color-north); @@ -76,10 +79,13 @@ a.card { &:hover, &:focus-visible { - border-color: var(--gold-leaf); - transform: scale(1.01); - box-shadow: 0 2px 12px rgba(212, 162, 89, 0.18); - color: var(--ink); + border-color: var(--brass-bright); + transform: translateY(-2px); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.04), + var(--shadow-raised), + var(--brass-glow); + color: var(--gaslight); outline: none; } } @@ -100,8 +106,7 @@ a.card { // Sigil overlays the top-right corner of the portrait in grid view. // Both `.portrait` and `.sigil` claim `grid-area: portrait`, layering // the sigil over the image; `place-self` parks it in the corner. -// `aspect-ratio: 1` keeps the badge square even if flex would otherwise -// shrink its main axis. +// `aspect-ratio: 1` keeps the badge square regardless of intrinsic size. .sigil { grid-area: portrait; place-self: start end; @@ -117,23 +122,23 @@ a.card { .name { grid-area: name; font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 2px; - font-size: 1.05rem; - font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.08em; + font-size: 1rem; + font-weight: 400; line-height: 1.2; - padding: 1rem 0; + padding: 1rem 0.5rem; } .alias { grid-area: alias; font-family: var(--font-body); - font-variant: normal; + text-transform: none; font-style: italic; font-weight: 400; letter-spacing: 0; font-size: 0.85rem; - color: var(--ink-faded); + color: var(--gaslight-dim); padding: 0; min-height: 2.5rem; align-content: center; @@ -147,7 +152,10 @@ a.card { --bleed-max: 1280px; .card { - display: flex; + display: grid; + grid-auto-flow: column; + grid-auto-columns: max-content; + justify-content: start; align-items: center; gap: 0.85rem; min-height: 5.75rem; @@ -156,7 +164,7 @@ a.card { border-width: 1px; @media (max-width: bp.$sm) { - display: grid; + grid-auto-flow: row; grid-template-columns: auto 1fr; grid-template-areas: "portrait name" @@ -174,9 +182,8 @@ a.card { } .portrait { - flex: 0 0 auto; - display: flex; - align-items: center; + display: grid; + align-content: center; img { height: 5.75rem; @@ -192,7 +199,6 @@ a.card { } .sigil { - flex: 0 0 3.25rem; place-self: auto; width: 3.25rem; aspect-ratio: auto; @@ -209,7 +215,7 @@ a.card { .name { padding: 0; - font-size: 1.1rem; + font-size: 1.05rem; @media (max-width: bp.$sm) { grid-area: name; diff --git a/components/FilteredDragonList/FilteredDragonList.module.scss b/components/FilteredDragonList/FilteredDragonList.module.scss index 5ad5521a..8472763a 100644 --- a/components/FilteredDragonList/FilteredDragonList.module.scss +++ b/components/FilteredDragonList/FilteredDragonList.module.scss @@ -1,6 +1,6 @@ // `ParchmentLayout`'s `.page` uses `justify-items: center` so the `h1` // and `.subtitle` size to their content. `justify-self: stretch` opts -// this grid back out so it fills the full parchment column. +// this grid back out so it fills the full page column. .list { list-style: none; padding: 0; @@ -13,34 +13,41 @@ .item { margin: 0; + display: grid; } .card { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; + display: grid; + grid-template-columns: 1fr; + justify-items: center; + align-content: center; gap: 0.85rem; min-height: 10.5rem; padding: 1rem; - background: var(--vellum); - border: 2px solid rgba(107, 68, 35, 0.25); - border-radius: 2px; - color: var(--ink); + background: var(--plate); + border: 2px solid var(--edge-strong); + border-radius: var(--bevel); + corner-shape: bevel; + color: var(--gaslight); text-decoration: none; text-align: center; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.04), + var(--shadow-soft); transition: border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease; - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.04); &:hover, &:focus-visible { - border-color: var(--gold-leaf); - transform: scale(1.01); - box-shadow: 0 2px 12px rgba(212, 162, 89, 0.18); - color: var(--ink); + border-color: var(--brass-bright); + transform: translateY(-2px); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.04), + var(--shadow-raised), + var(--brass-glow); + color: var(--gaslight); } @media (prefers-reduced-motion: reduce) { @@ -53,7 +60,7 @@ } } -// Regional border tints — colours live in `globals.scss` as +// Regional border tints; colours live in `globals.scss` as // `--region-color-*` tokens (shared with `FilteredCharacterList`). .cardNorth { border-color: var(--region-color-north); @@ -85,26 +92,28 @@ .name { font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 2px; - font-size: 1.2rem; - font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.08em; + font-size: 1.1rem; + font-weight: 400; } +// Wild dragons answer to no house: they carry the shimmer, the arcane +// violet reserved for the unbound. .cardWild { - border-color: var(--ink-faded); + border-color: rgba(182, 96, 232, 0.45); } .wildBadge { - display: inline-flex; - align-items: center; - justify-content: center; + display: inline-grid; + place-items: center; width: 6rem; height: 6rem; font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 2px; - color: var(--ink-faded); - border: 1px dashed rgba(107, 68, 35, 0.35); + text-transform: uppercase; + letter-spacing: 0.1em; + font-size: 0.85rem; + color: var(--shimmer); + border: 1px dashed rgba(182, 96, 232, 0.5); border-radius: 50%; } diff --git a/components/FilteredHouseList/FilteredHouseList.module.scss b/components/FilteredHouseList/FilteredHouseList.module.scss index 19e39182..971842c1 100644 --- a/components/FilteredHouseList/FilteredHouseList.module.scss +++ b/components/FilteredHouseList/FilteredHouseList.module.scss @@ -1,33 +1,50 @@ @use "breakpoints" as bp; +// The shared `listSearch.input` pins itself to a `search` grid area, so the +// controls grid names its tracks rather than relying on auto-placement. .controls { - display: flex; - flex-wrap: wrap; + display: grid; + grid-template-columns: minmax(16rem, 1fr) auto; + grid-template-areas: "search toggles"; align-items: center; gap: 1rem; width: 100%; + + @media (max-width: bp.$md) { + grid-template-columns: 1fr; + grid-template-areas: + "search" + "toggles"; + justify-items: stretch; + } } .searchInput { - flex: 1 1 16rem; min-width: 0; } .toggles { - display: flex; + grid-area: toggles; + display: grid; + grid-auto-flow: column; align-items: center; gap: 1rem; - margin-left: auto; + justify-self: end; + + @media (max-width: bp.$md) { + justify-self: center; + } } .rankFilter { - display: flex; + display: grid; + grid-auto-flow: column; align-items: center; gap: 0.4rem; font-family: var(--font-ui); font-size: 0.85rem; - color: var(--ink-faded); - letter-spacing: 0.5px; + color: var(--gaslight-faint); + letter-spacing: 0.06em; // Match the 50px height of the sibling `SortToggle` / `ViewToggle` // buttons and enlarge the option text. Scoped here so the shared @@ -40,8 +57,8 @@ } .rankLabel { - font-variant: small-caps; - letter-spacing: 1.5px; + text-transform: uppercase; + letter-spacing: 0.12em; } .regions { @@ -51,6 +68,9 @@ } .regionSearch { + // The shared `listSearch.input` claims `grid-area: search`; inside the + // accordion panel's plain grid that area does not exist, so opt back out. + grid-area: auto; font-size: 1.1rem; padding: 0.6rem 0.75rem; @@ -61,7 +81,7 @@ // `ParchmentLayout`'s `.page` uses `justify-items: center` so the `h1` // and `.subtitle` size to their content. `justify-self: stretch` opts -// this grid back out so it fills the full parchment column. +// this grid back out so it fills the full page column. .list { list-style: none; padding: 0; @@ -94,35 +114,41 @@ .item { margin: 0; + display: grid; } .card { - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; + display: grid; + grid-template-columns: 1fr; + justify-items: center; + align-content: center; gap: 0; min-height: 10.5rem; padding: 0.5rem; - background: var(--vellum); - border: 2px solid white; - border-radius: 2px; - color: var(--ink); + background: var(--plate); + border: 2px solid var(--edge-strong); + border-radius: var(--bevel); + corner-shape: bevel; + color: var(--gaslight); text-decoration: none; text-align: center; - border-radius: 8px; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.04), + var(--shadow-soft); transition: border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease; - box-shadow: 0 0 0 0 rgba(0, 0, 0, 0); &:hover, &:focus-visible { - border-color: white; - transform: scale(1.01); - box-shadow: 0 0 5px 0 rgba(0, 0, 0, 0.25); - color: var(--ink); + border-color: var(--brass-bright); + transform: translateY(-2px); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.04), + var(--shadow-raised), + var(--brass-glow); + color: var(--gaslight); } @media (prefers-reduced-motion: reduce) { @@ -135,8 +161,10 @@ } } -// Regional border tints — colours live in `globals.scss` as +// Regional border tints; colours live in `globals.scss` as // `--region-color-*` tokens (shared with `FilteredCharacterList`). +// On the house index the tint answers the hover, so the resting grid +// stays quiet metal and the region flares when a crest is engaged. .cardNorth { &:hover, &:focus-visible { @@ -194,10 +222,10 @@ .name { font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 0.5px; - font-size: 1rem; - font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + font-size: 0.95rem; + font-weight: 400; min-height: 60px; align-content: center; } @@ -212,6 +240,7 @@ .card { display: grid; grid-template-columns: 4.5rem 1fr auto; + justify-items: start; align-items: center; gap: 1rem; min-height: 0; @@ -221,8 +250,8 @@ } .name { - font-size: 1.5rem; - letter-spacing: 1px; + font-size: 1.4rem; + letter-spacing: 0.06em; min-height: 0; } } @@ -230,8 +259,10 @@ .region { font-family: var(--font-ui); font-size: 0.78rem; - font-variant: small-caps; - letter-spacing: 1.5px; - color: var(--ink-faded); + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.14em; + color: var(--gaslight-faint); text-align: right; + justify-self: end; } diff --git a/components/FilteredWeaponList/FilteredWeaponList.module.scss b/components/FilteredWeaponList/FilteredWeaponList.module.scss index 7ad16782..f3bd54dc 100644 --- a/components/FilteredWeaponList/FilteredWeaponList.module.scss +++ b/components/FilteredWeaponList/FilteredWeaponList.module.scss @@ -1,7 +1,7 @@ @use "breakpoints" as bp; // `ParchmentLayout`'s `.page` uses `justify-items: center`, so `justify-self: -// stretch` opts this grid back out to fill the full parchment column. Mirrors +// stretch` opts this grid back out to fill the full page column. Mirrors // the row style on the `/battles` index. .list { display: grid; @@ -23,36 +23,43 @@ gap: 1rem; align-items: center; padding: 0.5rem 0.75rem; - border-radius: 0.25rem; + border-radius: var(--bevel-sm); + corner-shape: bevel; text-decoration: none; - color: var(--ink); + color: var(--gaslight); transition: background-color 0.15s ease; &:hover { - background-color: rgba(212, 162, 89, 0.16); + background-color: rgba(199, 154, 63, 0.08); + } + + @media (prefers-reduced-motion: reduce) { + transition: none; } } .name { - display: inline-flex; + display: inline-grid; + grid-auto-flow: column; align-items: center; + justify-content: start; gap: 0.5rem; font-family: var(--font-ui); font-size: 1.05rem; } +// A charged node marks an entry with a full article behind it. .indicator { - flex: none; width: 0.5rem; height: 0.5rem; border-radius: 50%; - background-color: var(--gold-leaf); + background-color: var(--hextech); + box-shadow: 0 0 6px rgba(54, 214, 198, 0.55); } // Keep the sigil small so it never grows the row taller than the name's // line box. .sigil { - display: inline-flex; + display: inline-grid; align-items: center; - flex: none; } diff --git a/components/HouseInfobox/HouseInfobox.module.scss b/components/HouseInfobox/HouseInfobox.module.scss index 198ced17..b94d468d 100644 --- a/components/HouseInfobox/HouseInfobox.module.scss +++ b/components/HouseInfobox/HouseInfobox.module.scss @@ -1,18 +1,24 @@ @use "breakpoints" as bp; +// The infobox shell shared by every entity infobox (house, battle, weapon, +// dragon): the aside plate, the sigil stage, and the definition-list stack. +// The per-row `dt`/`dd` treatment lives in `Infobox.module.scss`. .infobox { display: grid; grid-template-columns: 1fr; width: 100%; padding: 0 0 1.25rem; overflow: hidden; - background: rgba(248, 236, 208, 0.6); - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 4px; - box-shadow: 0 2px 12px rgba(40, 25, 10, 0.12); + background: var(--plate); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel); + corner-shape: bevel; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.05), + var(--shadow-soft); font-family: var(--font-ui); - font-size: 0.82rem; - color: var(--ink); + font-size: 0.9rem; + color: var(--gaslight); justify-items: stretch; gap: 0; @@ -40,8 +46,8 @@ } .rows { - display: flex; - flex-direction: column; + display: grid; + grid-template-columns: 1fr; gap: 0.55rem; padding: 1rem 1rem 0; } diff --git a/components/Infobox/Infobox.module.scss b/components/Infobox/Infobox.module.scss index 8262ec95..0e86ae28 100644 --- a/components/Infobox/Infobox.module.scss +++ b/components/Infobox/Infobox.module.scss @@ -1,5 +1,8 @@ @use "breakpoints" as bp; +// The single infobox row: an engraved brass label plate beside its value. +// Used by `InfoRow` and by every entity infobox; the aside shell around +// these rows lives in `HouseInfobox.module.scss`. .row { display: grid; grid-template-columns: 6.5rem 1fr; @@ -8,33 +11,35 @@ dt { font-family: var(--font-sans); - font-size: 0.7rem; - text-transform: uppercase; - letter-spacing: 1px; - color: var(--ink-faded); + font-size: 0.72rem; font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.12em; + color: var(--brass); } dd { - color: var(--ink); + color: var(--gaslight); line-height: 1.35; font-size: 1rem; + margin: 0; } ul { list-style: none; padding: 0; - display: flex; - flex-direction: column; + margin: 0; + display: grid; + grid-template-columns: 1fr; gap: 0.15rem; } a { - color: var(--ink); - text-decoration-color: rgba(107, 68, 35, 0.35); + color: var(--gaslight); + text-decoration-color: rgba(199, 154, 63, 0.35); &:hover { - color: var(--gold-leaf); + color: var(--hextech); } } @@ -44,7 +49,7 @@ } .note { - color: var(--ink-faded); + color: var(--gaslight-dim); font-style: italic; font-size: 0.92em; } diff --git a/components/MainMenuTile/MainMenuTile.module.scss b/components/MainMenuTile/MainMenuTile.module.scss index ae84c3d4..b25c815e 100644 --- a/components/MainMenuTile/MainMenuTile.module.scss +++ b/components/MainMenuTile/MainMenuTile.module.scss @@ -1,28 +1,41 @@ .tile { position: relative; - display: flex; - flex-direction: column; - align-items: center; + display: grid; + grid-template-columns: 1fr; + justify-items: center; + align-content: start; text-align: center; - gap: 0.6rem; - padding: 1.6rem 1.2rem 2.2rem; - background: var(--vellum); - border: 1px solid rgba(107, 68, 35, 0.25); - border-radius: 2px; - color: var(--ink); + gap: 0.7rem; + padding: 1.75rem 1.25rem 2.1rem; + background: var(--plate); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel); + corner-shape: bevel; + color: var(--gaslight); text-decoration: none; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.05), + var(--shadow-soft); transition: border-color 150ms ease, transform 150ms ease, box-shadow 150ms ease; - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.04); &:hover, &:focus-visible { - border-color: var(--gold-leaf); - transform: scale(1.01); - box-shadow: 0 2px 12px rgba(212, 162, 89, 0.18); - color: var(--ink); + border-color: var(--edge-brass); + transform: translateY(-2px); + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.05), + var(--shadow-raised), + var(--brass-glow); + color: var(--gaslight); + + .glyph { + color: var(--hextech); + border-color: rgba(54, 214, 198, 0.5); + box-shadow: 0 0 14px rgba(54, 214, 198, 0.25); + } } @media (prefers-reduced-motion: reduce) { @@ -35,23 +48,44 @@ } } +// Each section glyph sits in a round instrument bezel; the dial lights +// hextech when the tile is engaged. .glyph { - color: var(--gold-leaf); + display: grid; + place-items: center; + width: 3.6rem; + height: 3.6rem; + color: var(--brass); line-height: 0; + border: 1px solid var(--edge-brass); + border-radius: 50%; + background: radial-gradient( + circle at 50% 30%, + rgba(199, 154, 63, 0.14), + rgba(10, 14, 21, 0.5) 75% + ); + transition: + color 150ms ease, + border-color 150ms ease, + box-shadow 150ms ease; + + @media (prefers-reduced-motion: reduce) { + transition: none; + } } .title { font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 2px; - font-size: 1.4rem; - font-weight: 600; - color: var(--ink); + text-transform: uppercase; + letter-spacing: 0.12em; + font-size: 1.35rem; + font-weight: 400; + color: var(--gaslight); } .subtitle { font-family: var(--font-body); font-style: italic; - color: var(--ink-faded); + color: var(--gaslight-dim); font-size: 1rem; } diff --git a/components/MapLayerToggle/MapLayerToggle.module.scss b/components/MapLayerToggle/MapLayerToggle.module.scss index 787b530e..c21b51f1 100644 --- a/components/MapLayerToggle/MapLayerToggle.module.scss +++ b/components/MapLayerToggle/MapLayerToggle.module.scss @@ -1,23 +1,28 @@ .toggle { position: relative; - display: flex; - flex-wrap: wrap; + display: grid; + grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr)); + justify-content: center; gap: 0.75rem; padding: 0.75rem 1rem; width: fit-content; max-width: 100%; justify-self: center; - background: var(--vellum); - border: 1px solid rgba(107, 68, 35, 0.4); - border-radius: 4px; + background: var(--plate); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + box-shadow: var(--shadow-soft); font-family: var(--font-ui); font-size: 0.85rem; + letter-spacing: 0.04em; label { - display: flex; + display: grid; + grid-template-columns: auto 1fr; align-items: center; gap: 0.4rem; - color: var(--ink); + color: var(--gaslight); cursor: pointer; text-transform: capitalize; } @@ -26,18 +31,24 @@ appearance: none; width: 14px; height: 14px; - border: 1.5px solid var(--ink-faded); + border: 1.5px solid var(--gaslight-faint); border-radius: 2px; - background: transparent; + background: var(--well); cursor: pointer; position: relative; + // A checked layer runs charged. + &:checked { + border-color: rgba(54, 214, 198, 0.7); + } + &:checked::after { content: ""; position: absolute; inset: 2px; - background: var(--wax-seal); + background: var(--hextech); border-radius: 1px; + box-shadow: 0 0 5px rgba(54, 214, 198, 0.6); } } } diff --git a/components/MapMarker/MapMarker.module.scss b/components/MapMarker/MapMarker.module.scss index b47d9748..5cfd2fb5 100644 --- a/components/MapMarker/MapMarker.module.scss +++ b/components/MapMarker/MapMarker.module.scss @@ -10,15 +10,30 @@ &:focus .label { opacity: 1; } + + @media (prefers-reduced-motion: reduce) { + transition: none; + + &:hover { + transform: none; + } + } } +// Labels render on the parchment map artwork itself, so they keep the +// chart-ink dark regardless of the interface theme around the glass. .label { - font-family: var(--font-heading); + font-family: var(--font-ui); + font-weight: 600; font-size: 11px; - fill: var(--ink); - font-variant: small-caps; + fill: #26303c; + text-transform: uppercase; letter-spacing: 1px; pointer-events: none; opacity: 0; transition: opacity 0.15s; + + @media (prefers-reduced-motion: reduce) { + transition: none; + } } diff --git a/components/MapMarker/MapMarker.test.tsx b/components/MapMarker/MapMarker.test.tsx index 09518125..25947dcd 100644 --- a/components/MapMarker/MapMarker.test.tsx +++ b/components/MapMarker/MapMarker.test.tsx @@ -47,7 +47,7 @@ describe("MapMarker", () => { expect(text?.getAttribute("y")).toBe("64"); }); - it("renders a large red circle for `castle`", () => { + it("renders a large teal circle for `castle`", () => { const { container } = renderMarker({ slug: "x", name: "X", @@ -55,14 +55,14 @@ describe("MapMarker", () => { }); const circle = container.querySelector("circle"); expect(circle?.getAttribute("r")).toBe("6"); - expect(circle?.getAttribute("fill")).toBe("#8b1a1a"); + expect(circle?.getAttribute("fill")).toBe("#0e7c74"); }); - it("renders a small parchment circle for `town`", () => { + it("renders a small chart-cream circle for `town`", () => { const { container } = renderMarker({ slug: "x", name: "X", type: "town" }); const circle = container.querySelector("circle"); expect(circle?.getAttribute("r")).toBe("4"); - expect(circle?.getAttribute("fill")).toBe("#f8ecd0"); + expect(circle?.getAttribute("fill")).toBe("#f4ead0"); }); it("renders a two-line cross for `ruin`", () => { @@ -89,6 +89,6 @@ describe("MapMarker", () => { }); const rects = container.querySelectorAll("rect"); expect(rects).toHaveLength(1); - expect(rects[0]?.getAttribute("fill")).toBe("#8b1a1a"); + expect(rects[0]?.getAttribute("fill")).toBe("#0e7c74"); }); }); diff --git a/components/MapMarker/MapMarker.tsx b/components/MapMarker/MapMarker.tsx index 36bf3dd5..d4530219 100644 --- a/components/MapMarker/MapMarker.tsx +++ b/components/MapMarker/MapMarker.tsx @@ -41,8 +41,8 @@ function Glyph({ cx={cx} cy={cy} r={6} - fill="#8b1a1a" - stroke="#3d2817" + fill="#0e7c74" + stroke="#26303c" strokeWidth={1.5} /> ); @@ -52,8 +52,8 @@ function Glyph({ cx={cx} cy={cy} r={4} - fill="#f8ecd0" - stroke="#3d2817" + fill="#f4ead0" + stroke="#26303c" strokeWidth={1.5} /> ); @@ -65,7 +65,7 @@ function Glyph({ y1={cy - 5} x2={cx + 5} y2={cy + 5} - stroke="#3d2817" + stroke="#26303c" strokeWidth={2} /> @@ -81,8 +81,8 @@ function Glyph({ case "watchtower": return ( - - + + ); case "holdfast": @@ -92,8 +92,8 @@ function Glyph({ y={cy - 5} width={10} height={10} - fill="#8b1a1a" - stroke="#3d2817" + fill="#0e7c74" + stroke="#26303c" strokeWidth={1.5} /> ); diff --git a/components/MapStage/MapStage.module.scss b/components/MapStage/MapStage.module.scss index 56c71598..0716b7ed 100644 --- a/components/MapStage/MapStage.module.scss +++ b/components/MapStage/MapStage.module.scss @@ -3,24 +3,19 @@ max-width: 720px; margin: 0 auto; aspect-ratio: 4 / 7; - border: 1px solid rgba(107, 68, 35, 0.4); - border-radius: 6px; + border: 1px solid var(--edge-brass); + border-radius: var(--bevel); + corner-shape: bevel; background: radial-gradient( - ellipse at top left, - rgba(180, 140, 90, 0.18), - transparent 60% + ellipse at 50% 20%, + rgba(199, 154, 63, 0.08), + transparent 65% ), - radial-gradient( - ellipse at bottom right, - rgba(120, 80, 40, 0.15), - transparent 60% - ), - linear-gradient( - 180deg, - var(--parchment-light) 0%, - var(--parchment-dark) 100% - ); + linear-gradient(180deg, #1e2a37 0%, #141d28 100%); + box-shadow: + inset 0 0 40px rgba(4, 8, 13, 0.45), + var(--shadow-soft); position: relative; overflow: hidden; } diff --git a/components/PageHeading/PageHeading.module.scss b/components/PageHeading/PageHeading.module.scss index 23280009..8df92b0d 100644 --- a/components/PageHeading/PageHeading.module.scss +++ b/components/PageHeading/PageHeading.module.scss @@ -7,7 +7,7 @@ width: 100%; text-align: center; - // The ornamental `FiligreeRule` underlines the title in place of the plain + // The hextech `FiligreeRule` underlines the title in place of the plain // border the subtitle carries by default. :global(.subtitle) { border-bottom: none; @@ -16,17 +16,18 @@ // Seat the section glyph on the title baseline, sized to the cap height. h1 { - display: inline-flex; + display: inline-grid; + grid-auto-flow: column; align-items: center; gap: 0.5rem; } } .icon { - display: inline-flex; + display: inline-grid; width: 1.1em; height: 1.1em; - color: currentColor; + color: var(--brass); svg { width: 100%; diff --git a/components/ParchmentLayout/ParchmentLayout.module.scss b/components/ParchmentLayout/ParchmentLayout.module.scss index 7f30e51d..59ef315b 100644 --- a/components/ParchmentLayout/ParchmentLayout.module.scss +++ b/components/ParchmentLayout/ParchmentLayout.module.scss @@ -27,30 +27,17 @@ } } +// A reading lamp over the working surface: one soft pool of warm light +// behind the page column, fading before the fold. .page::before { content: ""; position: absolute; inset: 0; pointer-events: none; - background-image: - radial-gradient( - circle at 18% 22%, - rgba(80, 50, 20, 0.06) 1px, - transparent 2px - ), - radial-gradient( - circle at 74% 58%, - rgba(80, 50, 20, 0.05) 1px, - transparent 2px - ), - radial-gradient( - circle at 42% 80%, - rgba(80, 50, 20, 0.06) 1px, - transparent 2px - ); - background-size: - 90px 90px, - 110px 110px, - 130px 130px; + background: radial-gradient( + 56% 30% at 50% 0%, + rgba(231, 197, 120, 0.05), + transparent 100% + ); z-index: 0; } diff --git a/components/SiteFooter/SiteFooter.module.scss b/components/SiteFooter/SiteFooter.module.scss index 29073eb8..36918ba6 100644 --- a/components/SiteFooter/SiteFooter.module.scss +++ b/components/SiteFooter/SiteFooter.module.scss @@ -1,11 +1,11 @@ @use "breakpoints" as bp; .footer { - border-top: 1px solid rgba(107, 68, 35, 0.3); + border-top: 1px solid rgba(199, 154, 63, 0.28); background: linear-gradient( 0deg, - rgba(248, 236, 208, 0.55) 0%, - rgba(232, 211, 160, 0.25) 100% + rgba(13, 19, 27, 0.95) 0%, + rgba(17, 25, 35, 0.35) 100% ); position: relative; @@ -19,11 +19,11 @@ background: linear-gradient( 90deg, transparent 0%, - var(--gold-leaf) 18%, - var(--gold-leaf) 82%, + var(--brass) 18%, + var(--brass) 82%, transparent 100% ); - opacity: 0.65; + opacity: 0.6; } } @@ -37,44 +37,50 @@ .credit { font-family: var(--font-ui); - font-size: 0.7rem; - color: var(--ink-faded); - letter-spacing: 0.5px; - display: flex; - flex-wrap: wrap; + font-size: 0.8rem; + color: var(--gaslight-faint); + letter-spacing: 0.06em; + display: grid; + grid-auto-flow: column; justify-content: center; align-items: center; gap: 0.5rem; @media (max-width: bp.$xs) { - font-size: 0.65rem; + font-size: 0.72rem; gap: 0.4rem; } } .name { font-family: var(--font-character-name); - color: var(--ink); - font-weight: 600; - letter-spacing: 1px; + color: var(--gaslight); + font-size: 0.95em; + letter-spacing: 0.08em; } .separator { - color: var(--gold-leaf); - font-weight: 700; + color: var(--brass); + font-weight: 600; } .link { font-family: var(--font-ui); - color: var(--ink-faded); + color: var(--gaslight-faint); text-decoration: none; - display: inline-flex; + display: inline-grid; + grid-auto-flow: column; align-items: center; gap: 0.35rem; + transition: color 140ms ease; &:hover, &:focus-visible { - color: var(--gold-leaf); + color: var(--hextech); + } + + @media (prefers-reduced-motion: reduce) { + transition: none; } } @@ -85,6 +91,6 @@ .version { font-family: var(--font-ui); - color: var(--ink-faded); + color: var(--gaslight-faint); font-variant-numeric: tabular-nums; } diff --git a/components/SiteHeader/SiteHeader.module.scss b/components/SiteHeader/SiteHeader.module.scss index 633913de..2fd59b28 100644 --- a/components/SiteHeader/SiteHeader.module.scss +++ b/components/SiteHeader/SiteHeader.module.scss @@ -5,30 +5,33 @@ top: 0; z-index: 50; isolation: isolate; - border-bottom: 1px solid rgba(107, 68, 35, 0.28); + border-bottom: 1px solid rgba(199, 154, 63, 0.28); background: linear-gradient( 180deg, - rgba(248, 236, 208, 0.97) 0%, - rgba(236, 217, 170, 0.94) 60%, - rgba(228, 205, 156, 0.93) 100% + rgba(26, 37, 48, 0.94) 0%, + rgba(18, 26, 36, 0.92) 100% ); - backdrop-filter: blur(6px); - -webkit-backdrop-filter: blur(6px); - box-shadow: 0 1px 0 rgba(248, 236, 208, 0.6) inset; + backdrop-filter: blur(8px); + -webkit-backdrop-filter: blur(8px); + box-shadow: 0 1px 0 rgba(255, 255, 255, 0.05) inset; + // Brushed-steel grain: hairline verticals at whisper opacity. &::before { content: ""; position: absolute; inset: 0; - background-image: url("/patterns/floral-pattern.avif"); - background-repeat: repeat; - background-size: 150px auto; - opacity: 0.1; - mix-blend-mode: difference; + background: repeating-linear-gradient( + 90deg, + rgba(140, 165, 190, 0.05) 0, + rgba(140, 165, 190, 0.05) 1px, + transparent 1px, + transparent 7px + ); pointer-events: none; z-index: 0; } + // The brass edge-light along the underside of the plate. &::after { content: ""; position: absolute; @@ -39,8 +42,8 @@ background: linear-gradient( 90deg, transparent 0%, - var(--gold-leaf) 20%, - var(--gold-leaf) 80%, + var(--brass) 20%, + var(--brass) 80%, transparent 100% ); opacity: 0.7; @@ -78,27 +81,30 @@ &:hover, &:focus-visible { .title { - color: var(--ink-faded); - } + color: var(--hextech); - .flourish { - opacity: 1; + @supports (background-clip: text) or (-webkit-background-clip: text) { + background: linear-gradient( + 180deg, + var(--brass-bright) 10%, + var(--brass) 55%, + var(--brass-bright) 100% + ); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + } } } &:focus-visible { - outline: 2px solid var(--gold-leaf); + outline: 2px solid var(--hextech); outline-offset: 6px; border-radius: 2px; } -} - -.flourish { - width: clamp(54px, 9vw, 104px); - transition: opacity 200ms ease; - @media (max-width: bp.$sm) { - display: none; + @media (prefers-reduced-motion: reduce) { + transition: none; } } @@ -106,23 +112,33 @@ margin: 0; padding: 0; font-family: var(--font-heading); - font-weight: 600; - font-size: clamp(1.45rem, 4.4vw, 2.1rem); - letter-spacing: 0.14em; - color: var(--ink); + font-weight: 400; + font-size: clamp(1.4rem, 4.2vw, 1.95rem); + letter-spacing: 0.16em; + text-transform: uppercase; + color: var(--brass-bright); text-align: center; line-height: 1; white-space: nowrap; - text-shadow: - 0 1px 0 rgba(255, 250, 235, 0.55), - 0 1px 3px rgba(61, 40, 23, 0.18); + + @supports (background-clip: text) or (-webkit-background-clip: text) { + background: linear-gradient( + 180deg, + var(--brass-bright) 18%, + var(--brass) 60%, + var(--brass-dark) 100% + ); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + } @media (max-width: bp.$md) { letter-spacing: 0.16em; } @media (max-width: bp.$xs) { - font-size: 1.2rem; - letter-spacing: 0.08em; + font-size: 1.15rem; + letter-spacing: 0.1em; } } diff --git a/components/SiteMenu/SiteMenu.module.scss b/components/SiteMenu/SiteMenu.module.scss index 20b4a357..481c4dfe 100644 --- a/components/SiteMenu/SiteMenu.module.scss +++ b/components/SiteMenu/SiteMenu.module.scss @@ -10,25 +10,28 @@ width: 2.5rem; height: 2.5rem; padding: 0; - background: transparent; - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; - color: var(--ink); + background: rgba(18, 26, 36, 0.7); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + color: var(--gaslight-dim); cursor: pointer; transition: color 150ms ease, border-color 150ms ease, - background 150ms ease; + background 150ms ease, + box-shadow 150ms ease; &:hover, &:focus-visible { - color: var(--gold-leaf); - border-color: var(--gold-leaf); - background: rgba(248, 236, 208, 0.6); + color: var(--hextech); + border-color: var(--edge-brass); + background: rgba(26, 37, 48, 0.9); + box-shadow: var(--focus-glow); } &:focus-visible { - outline: 2px solid var(--gold-leaf); + outline: 2px solid var(--hextech); outline-offset: 2px; } @@ -45,7 +48,7 @@ .backdrop { position: fixed; inset: 0; - background: rgba(45, 30, 15, 0.45); + background: rgba(4, 8, 13, 0.6); opacity: 0; pointer-events: none; transition: opacity 220ms ease; @@ -67,13 +70,9 @@ bottom: 0; left: 0; width: min(20rem, 86vw); - background: linear-gradient( - 180deg, - var(--vellum) 0%, - var(--parchment-light) 100% - ); - border-right: 1px solid rgba(107, 68, 35, 0.35); - box-shadow: 8px 0 24px rgba(45, 30, 15, 0.18); + background: linear-gradient(180deg, #1c2836 0%, #141d28 100%); + border-right: 1px solid rgba(199, 154, 63, 0.3); + box-shadow: var(--shadow-raised); transform: translateX(-100%); transition: transform 240ms ease; z-index: 100; @@ -91,8 +90,8 @@ background: linear-gradient( 180deg, transparent 0%, - var(--gold-leaf) 18%, - var(--gold-leaf) 82%, + var(--brass) 18%, + var(--brass) 82%, transparent 100% ); opacity: 0.55; @@ -117,16 +116,17 @@ grid-template-columns: 1fr auto; align-items: center; padding: 1rem 1.1rem; - border-bottom: 1px solid rgba(107, 68, 35, 0.25); + border-bottom: 1px solid var(--edge); gap: 0.5rem; } .panelLabel { - font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 4px; - font-size: 0.95rem; - color: var(--ink-faded); + font-family: var(--font-ui); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.3em; + font-size: 0.8rem; + color: var(--brass); } .close { @@ -137,8 +137,9 @@ padding: 0; background: transparent; border: 1px solid transparent; - border-radius: 2px; - color: var(--ink-faded); + border-radius: var(--bevel-sm); + corner-shape: bevel; + color: var(--gaslight-faint); cursor: pointer; transition: color 150ms ease, @@ -146,12 +147,12 @@ &:hover, &:focus-visible { - color: var(--gold-leaf); - border-color: var(--gold-leaf); + color: var(--hextech); + border-color: var(--edge-brass); } &:focus-visible { - outline: 2px solid var(--gold-leaf); + outline: 2px solid var(--hextech); outline-offset: 2px; } @@ -180,13 +181,13 @@ grid-template-columns: auto 1fr; align-items: center; gap: 0.85rem; - padding: 0.7rem 1.5rem; - font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 3px; - font-size: 1.05rem; + padding: 0.75rem 1.5rem; + font-family: var(--font-ui); font-weight: 500; - color: var(--ink-faded); + text-transform: uppercase; + letter-spacing: 0.16em; + font-size: 1rem; + color: var(--gaslight-dim); text-decoration: none; border-left: 3px solid transparent; transition: @@ -196,16 +197,16 @@ &:hover, &:focus-visible { - color: var(--ink); - background: rgba(212, 162, 89, 0.12); - border-left-color: var(--gold-leaf); + color: var(--gaslight); + background: rgba(199, 154, 63, 0.08); + border-left-color: var(--brass); } @media (max-width: bp.$xs) { - padding: 0.7rem 1.25rem; + padding: 0.75rem 1.25rem; gap: 0.75rem; - font-size: 1rem; - letter-spacing: 2.5px; + font-size: 0.95rem; + letter-spacing: 0.14em; } @media (prefers-reduced-motion: reduce) { @@ -219,29 +220,19 @@ width: 1.25rem; height: 1.25rem; overflow: hidden; - border-radius: 2px; - transition: border-color 150ms ease; - - img { - width: 100%; - height: 100%; - object-fit: cover; - display: block; - } + color: var(--brass); + transition: + color 150ms ease, + filter 150ms ease; - // Section glyphs render as inline SVG rather than a raster image; scale them - // to the icon box so they sit centred alongside the PNG icons. + // Section glyphs render as inline SVG in currentColor; scale them to the + // icon box so every row carries the same weight of line. svg { width: 100%; height: 100%; display: block; } - .link:hover &, - .link:focus-visible & { - border-color: var(--gold-leaf); - } - @media (prefers-reduced-motion: reduce) { transition: none; } @@ -251,12 +242,14 @@ display: block; } +// The open section runs charged: hextech rail, lit glyph. .linkActive { - color: var(--ink); - border-left-color: var(--gold-leaf); - background: rgba(212, 162, 89, 0.18); + color: var(--gaslight); + border-left-color: var(--hextech); + background: rgba(54, 214, 198, 0.07); .linkIcon { - border-color: var(--gold-leaf); + color: var(--hextech); + filter: drop-shadow(0 0 4px rgba(54, 214, 198, 0.5)); } } diff --git a/components/SiteMenu/SiteMenu.tsx b/components/SiteMenu/SiteMenu.tsx index 410da603..344dfb57 100644 --- a/components/SiteMenu/SiteMenu.tsx +++ b/components/SiteMenu/SiteMenu.tsx @@ -1,6 +1,5 @@ "use client"; -import Image from "next/image"; import Link from "next/link"; import { usePathname } from "next/navigation"; import { type ReactNode, useEffect, useId, useRef, useState } from "react"; @@ -12,53 +11,53 @@ import styles from "@/components/SiteMenu/SiteMenu.module.scss"; type MenuItem = { href: string; label: string; - icon: string; - glyph?: ReactNode; + glyph: ReactNode; visible: boolean; }; +// Every entry uses its section's line-art glyph so the drawer stays +// monochrome metal; the raster menu icons belonged to the parchment era. const ITEMS: MenuItem[] = [ { href: "/maps/", label: "Maps", - icon: "/menu-icons/map.png", + glyph: sectionGlyphs.maps, visible: true, }, { href: "/timeline/", label: "Timeline", - icon: "/menu-icons/timeline.png", + glyph: sectionGlyphs.timeline, visible: true, }, { href: "/houses/", label: "Houses", - icon: "/menu-icons/houses.png", + glyph: sectionGlyphs.houses, visible: true, }, { href: "/characters/", label: "Characters", - icon: "/menu-icons/characters.png", + glyph: sectionGlyphs.characters, visible: true, }, { href: "/weapons/", label: "Weapons", - icon: "/menu-icons/weapons.png", + glyph: sectionGlyphs.weapons, visible: true, }, { href: "/battles/", label: "Battles", - icon: "/menu-icons/battles.png", glyph: sectionGlyphs.battles, visible: true, }, { href: "/dragons/", label: "Dragons", - icon: "/menu-icons/dragons.png", + glyph: sectionGlyphs.dragons, visible: false, }, ]; @@ -190,15 +189,7 @@ export function SiteMenu() { tabIndex={isOpen ? 0 : -1} > {item.label} diff --git a/components/SortToggle/SortToggle.module.scss b/components/SortToggle/SortToggle.module.scss index 44843d1e..350852a5 100644 --- a/components/SortToggle/SortToggle.module.scss +++ b/components/SortToggle/SortToggle.module.scss @@ -1,11 +1,13 @@ @use "breakpoints" as bp; .toggle { - display: flex; - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; + display: grid; + grid-auto-flow: column; + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; overflow: hidden; - background: rgba(248, 236, 208, 0.55); + background: var(--well); width: 100px; height: 50px; @@ -19,31 +21,33 @@ background: transparent; border: 0; padding: 0; - display: flex; - align-items: center; + display: grid; + place-items: center; width: 50px; height: 50px; - justify-content: center; - color: var(--ink-faded); + color: var(--gaslight-faint); cursor: pointer; transition: background 120ms ease, - color 120ms ease; + color 120ms ease, + box-shadow 120ms ease; & + & { - border-left: 1px solid rgba(107, 68, 35, 0.35); + border-left: 1px solid var(--edge); } &:hover, &:focus-visible { - color: var(--gold-leaf); + color: var(--brass-bright); outline: none; - background: rgba(248, 236, 208, 0.9); + background: rgba(199, 154, 63, 0.08); } + // The engaged switch runs charged. &[aria-pressed="true"] { - color: var(--ink); - background: rgba(212, 162, 89, 0.18); + color: var(--hextech); + background: rgba(54, 214, 198, 0.1); + box-shadow: inset 0 0 10px rgba(54, 214, 198, 0.12); } @media (prefers-reduced-motion: reduce) { diff --git a/components/Sources/Sources.module.scss b/components/Sources/Sources.module.scss index 53dacd5b..0e62a6b2 100644 --- a/components/Sources/Sources.module.scss +++ b/components/Sources/Sources.module.scss @@ -1,8 +1,8 @@ .sources { padding: 1.5rem; - border-top: 1px solid rgba(107, 68, 35, 0.3); + border-top: 1px solid var(--edge); font-family: var(--font-ui); font-size: 0.85rem; - color: var(--ink-faded); + color: var(--gaslight-faint); width: 100%; } diff --git a/components/TimelineChart/TimelineChart.module.scss b/components/TimelineChart/TimelineChart.module.scss index 0b8de9a5..a320261e 100644 --- a/components/TimelineChart/TimelineChart.module.scss +++ b/components/TimelineChart/TimelineChart.module.scss @@ -23,7 +23,7 @@ .header { padding-block: 0.5rem 0.75rem; - border-bottom: 1px solid rgba(107, 68, 35, 0.25); + border-bottom: 1px solid var(--edge); } .axisSpacer { @@ -33,12 +33,12 @@ .columnHeading { margin: 0; font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 2px; - font-size: 1.15rem; - font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.1em; + font-size: 1.05rem; + font-weight: 400; text-align: center; - color: var(--ink); + color: var(--gaslight); &:nth-of-type(1) { grid-area: westeros; @@ -64,12 +64,12 @@ .axisRail { grid-area: axis; - border-right: 1px solid rgba(107, 68, 35, 0.25); + border-right: 1px solid var(--edge-strong); } %column { position: relative; - border-right: 1px dashed rgba(107, 68, 35, 0.12); + border-right: 1px dashed rgba(126, 152, 180, 0.12); &:last-of-type { border-right: none; @@ -102,21 +102,24 @@ display: grid; grid-template-areas: "label"; justify-items: start; - border-top: 1px dashed rgba(107, 68, 35, 0.18); + border-top: 1px dashed rgba(126, 152, 180, 0.16); } +// Year labels along the axis: instrument figures on the dial. .tickLabel { grid-area: label; width: calc(var(--axis-width) - var(--era-width)); padding-right: 1.25rem; text-align: right; transform: translateY(-50%); - background: var(--parchment-light); - font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 2px; - font-size: 1.15rem; - color: var(--ink); + background: var(--iron); + font-family: var(--font-ui); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.1em; + font-size: 0.95rem; + color: var(--gaslight-dim); + font-variant-numeric: tabular-nums; } .era { @@ -129,20 +132,22 @@ grid-template-columns: var(--era-width) 1fr; align-items: center; justify-items: center; - background: rgba(212, 162, 89, 0.07); - border-top: 1px solid rgba(212, 162, 89, 0.22); - border-bottom: 1px solid rgba(212, 162, 89, 0.22); + background: rgba(199, 154, 63, 0.05); + border-top: 1px solid rgba(199, 154, 63, 0.2); + border-bottom: 1px solid rgba(199, 154, 63, 0.2); } .eraLabel { grid-area: label; writing-mode: vertical-rl; transform: rotate(180deg); - font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 4px; - font-size: 1rem; - color: var(--ink-faded); + font-family: var(--font-ui); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.32em; + font-size: 0.85rem; + color: var(--brass); + opacity: 0.85; } .node { @@ -168,20 +173,21 @@ column-gap: 0.5rem; row-gap: 0.1rem; padding: 0.3rem 0.55rem; - background: var(--vellum); - border: 1px solid rgba(107, 68, 35, 0.25); - border-radius: 2px; - color: var(--ink); + background: var(--plate); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + color: var(--gaslight); text-decoration: none; - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.04); + box-shadow: var(--shadow-soft); transition: border-color 150ms ease, box-shadow 150ms ease; &:hover, &:focus-visible { - border-color: var(--gold-leaf); - box-shadow: 0 2px 12px rgba(212, 162, 89, 0.18); + border-color: var(--edge-brass); + box-shadow: var(--shadow-soft), var(--brass-glow); } @media (prefers-reduced-motion: reduce) { @@ -189,14 +195,16 @@ } } +// Every event is a charged node on the conduit of years. .marker { grid-area: marker; align-self: center; width: 0.5rem; height: 0.5rem; - background: var(--gold-leaf); - border: 1px solid rgba(107, 68, 35, 0.4); + background: var(--hextech); + border: 1px solid rgba(23, 117, 109, 0.9); border-radius: 50%; + box-shadow: 0 0 6px rgba(54, 214, 198, 0.55); } .eventName { @@ -209,7 +217,7 @@ grid-area: when; font-style: italic; font-size: 0.8rem; - color: var(--ink-faded); + color: var(--gaslight-dim); } @media (max-width: bp.$md) { @@ -219,13 +227,13 @@ } .columnHeading { - font-size: 1rem; - letter-spacing: 1px; + font-size: 0.95rem; + letter-spacing: 0.06em; } .tickLabel { padding-right: 0.75rem; - letter-spacing: 1px; - font-size: 0.9rem; + letter-spacing: 0.06em; + font-size: 0.85rem; } } diff --git a/components/TimelineCluster/TimelineCluster.module.scss b/components/TimelineCluster/TimelineCluster.module.scss index 714b9054..1a0f3aa5 100644 --- a/components/TimelineCluster/TimelineCluster.module.scss +++ b/components/TimelineCluster/TimelineCluster.module.scss @@ -10,24 +10,25 @@ align-items: baseline; gap: 0.5rem; padding: 0.3rem 0.75rem; - background: var(--vellum); - border: 1px solid rgba(107, 68, 35, 0.35); + background: var(--plate); + border: 1px solid var(--edge-strong); border-radius: 999px; - font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 1px; + font-family: var(--font-ui); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.08em; font-size: 0.85rem; - color: var(--wax-seal); + color: var(--brass-bright); cursor: pointer; - box-shadow: 0 1px 0 rgba(0, 0, 0, 0.04); + box-shadow: var(--shadow-soft); transition: border-color 150ms ease, box-shadow 150ms ease; &:hover, &:focus-visible { - border-color: var(--gold-leaf); - box-shadow: 0 2px 12px rgba(212, 162, 89, 0.18); + border-color: var(--edge-brass); + box-shadow: var(--shadow-soft), var(--brass-glow); } @media (prefers-reduced-motion: reduce) { @@ -42,10 +43,10 @@ .when { font-family: var(--font-body); font-style: italic; - font-variant: normal; + text-transform: none; letter-spacing: 0; font-size: 0.8rem; - color: var(--ink-faded); + color: var(--gaslight-dim); } .list { @@ -61,10 +62,11 @@ padding: 0.35rem; margin: 0; list-style: none; - background: var(--vellum); - border: 1px solid var(--gold-leaf); - border-radius: 2px; - box-shadow: 0 4px 18px rgba(61, 40, 23, 0.25); + background: #1c2836; + border: 1px solid var(--edge-brass); + border-radius: var(--bevel-sm); + corner-shape: bevel; + box-shadow: var(--shadow-raised); } .item { @@ -78,14 +80,14 @@ align-items: baseline; gap: 0.75rem; padding: 0.35rem 0.5rem; - color: var(--ink); + color: var(--gaslight); text-decoration: none; border-radius: 2px; &:hover, &:focus-visible { - background: rgba(212, 162, 89, 0.16); - color: var(--ink); + background: rgba(199, 154, 63, 0.1); + color: var(--gaslight); } } @@ -100,6 +102,6 @@ font-family: var(--font-body); font-style: italic; font-size: 0.8rem; - color: var(--ink-faded); + color: var(--gaslight-dim); white-space: nowrap; } diff --git a/components/TimelineExplorer/TimelineExplorer.module.scss b/components/TimelineExplorer/TimelineExplorer.module.scss index e74c134d..8f431a01 100644 --- a/components/TimelineExplorer/TimelineExplorer.module.scss +++ b/components/TimelineExplorer/TimelineExplorer.module.scss @@ -8,7 +8,7 @@ display: grid; } -// Floating pill in the lower-right, clear of the sticky site header and the +// Floating pod in the lower-right, clear of the sticky site header and the // vertically-centred minimap. Fixed so it stays reachable down the long chart. .zoom { position: fixed; @@ -19,12 +19,13 @@ justify-items: center; gap: 0.25rem; padding: 0.35rem; - background: rgba(248, 236, 208, 0.94); - border: 1px solid rgba(107, 68, 35, 0.3); - border-radius: 2px; - box-shadow: 0 2px 12px rgba(61, 40, 23, 0.15); - backdrop-filter: blur(3px); - -webkit-backdrop-filter: blur(3px); + background: rgba(20, 29, 40, 0.92); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + box-shadow: var(--shadow-raised); + backdrop-filter: blur(4px); + -webkit-backdrop-filter: blur(4px); } .zoomButton { @@ -34,12 +35,13 @@ width: 2.25rem; height: 2.25rem; padding: 0; - background: rgba(248, 236, 208, 0.6); - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; - color: var(--ink); - font-family: var(--font-heading); - font-size: 1.4rem; + background: var(--plate); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + color: var(--gaslight-dim); + font-family: var(--font-ui); + font-size: 1.35rem; line-height: 1; cursor: pointer; transition: @@ -49,9 +51,8 @@ &:hover:not(:disabled), &:focus-visible:not(:disabled) { - border-color: var(--gold-leaf); - color: var(--gold-leaf); - background: rgba(248, 236, 208, 0.9); + border-color: var(--edge-brass); + color: var(--brass-bright); outline: none; } @@ -67,10 +68,12 @@ .zoomLevel { min-width: 2.25rem; - font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 1px; + font-family: var(--font-ui); + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.08em; font-size: 0.85rem; - color: var(--ink-faded); + color: var(--gaslight-faint); text-align: center; + font-variant-numeric: tabular-nums; } diff --git a/components/TimelineMinimap/TimelineMinimap.module.scss b/components/TimelineMinimap/TimelineMinimap.module.scss index 31e78bd4..3512fe32 100644 --- a/components/TimelineMinimap/TimelineMinimap.module.scss +++ b/components/TimelineMinimap/TimelineMinimap.module.scss @@ -9,10 +9,11 @@ max-height: 82vh; overflow-y: auto; padding: 0.5rem 0.25rem; - background: rgba(248, 236, 208, 0.92); - border: 1px solid rgba(107, 68, 35, 0.3); - border-radius: 2px; - box-shadow: 0 2px 12px rgba(61, 40, 23, 0.15); + background: rgba(20, 29, 40, 0.92); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + box-shadow: var(--shadow-soft); @media (max-width: bp.$lg) { display: none; @@ -37,16 +38,25 @@ border: none; text-align: right; cursor: pointer; - font-family: var(--font-heading); - font-variant: small-caps; - letter-spacing: 1px; + font-family: var(--font-ui); + font-weight: 500; + text-transform: uppercase; + letter-spacing: 0.08em; font-size: 0.75rem; - color: var(--ink-faded); + color: var(--gaslight-faint); border-radius: 2px; + font-variant-numeric: tabular-nums; + transition: + color 120ms ease, + background 120ms ease; &:hover, &:focus-visible { - color: var(--wax-seal); - background: rgba(212, 162, 89, 0.16); + color: var(--hextech); + background: rgba(54, 214, 198, 0.08); + } + + @media (prefers-reduced-motion: reduce) { + transition: none; } } diff --git a/components/ViewToggle/ViewToggle.module.scss b/components/ViewToggle/ViewToggle.module.scss index 9e2f9881..a75979c2 100644 --- a/components/ViewToggle/ViewToggle.module.scss +++ b/components/ViewToggle/ViewToggle.module.scss @@ -1,11 +1,13 @@ @use "breakpoints" as bp; .toggle { - display: flex; - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; + display: grid; + grid-auto-flow: column; + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; overflow: hidden; - background: rgba(248, 236, 208, 0.55); + background: var(--well); height: 50px; @media (max-width: bp.$md) { @@ -18,31 +20,33 @@ background: transparent; border: 0; padding: 0; - display: flex; - align-items: center; + display: grid; + place-items: center; width: 50px; height: 50px; - justify-content: center; - color: var(--ink-faded); + color: var(--gaslight-faint); cursor: pointer; transition: background 120ms ease, - color 120ms ease; + color 120ms ease, + box-shadow 120ms ease; & + & { - border-left: 1px solid rgba(107, 68, 35, 0.35); + border-left: 1px solid var(--edge); } &:hover, &:focus-visible { - color: var(--gold-leaf); + color: var(--brass-bright); outline: none; - background: rgba(248, 236, 208, 0.9); + background: rgba(199, 154, 63, 0.08); } + // The engaged view runs charged. &[aria-pressed="true"] { - color: var(--ink); - background: rgba(212, 162, 89, 0.18); + color: var(--hextech); + background: rgba(54, 214, 198, 0.1); + box-shadow: inset 0 0 10px rgba(54, 214, 198, 0.12); } @media (prefers-reduced-motion: reduce) { diff --git a/components/WorldMap/WorldMap.module.scss b/components/WorldMap/WorldMap.module.scss index e5384a0b..e9d75e95 100644 --- a/components/WorldMap/WorldMap.module.scss +++ b/components/WorldMap/WorldMap.module.scss @@ -8,6 +8,8 @@ justify-items: center; } +// The chart table: the parchment map is an exhibit under glass, held in a +// brass instrument bezel; the chrome around it stays cold metal. .stage { position: relative; width: 100%; @@ -19,24 +21,28 @@ height: auto; aspect-ratio: 1 / 1; } - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; - background: rgba(248, 236, 208, 0.55); + border: 1px solid var(--edge-brass); + border-radius: var(--bevel); + corner-shape: bevel; + background: var(--well); + box-shadow: + inset 0 0 40px rgba(4, 8, 13, 0.5), + var(--shadow-soft); overflow: hidden; display: grid; grid-template-areas: "canvas"; &:focus-visible { - outline: 2px solid var(--gold-leaf); + outline: 2px solid var(--hextech); outline-offset: 2px; } &::before { - content: "Unfurling the map…"; + content: "Focusing the lens…"; grid-area: canvas; place-self: center; font-style: italic; - color: var(--ink-faded); + color: var(--gaslight-dim); } &:fullscreen { @@ -56,8 +62,8 @@ cursor: pointer; circle { - fill: rgba(212, 162, 89, 0); - stroke: rgba(212, 162, 89, 0); + fill: rgba(54, 214, 198, 0); + stroke: rgba(54, 214, 198, 0); stroke-width: 3; transition: fill 120ms ease, @@ -66,8 +72,8 @@ &:hover circle, &:focus-visible circle { - fill: rgba(212, 162, 89, 0.18); - stroke: var(--gold-leaf); + fill: rgba(54, 214, 198, 0.15); + stroke: var(--hextech); } &:focus-visible { @@ -89,10 +95,11 @@ grid-template-columns: auto auto; gap: 0.15rem 0.5rem; padding: 0.5rem 0.75rem; - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; - background: rgba(248, 236, 208, 0.85); - color: var(--ink-faded); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + background: rgba(20, 29, 40, 0.9); + color: var(--gaslight-dim); font-size: 0.85rem; font-variant-numeric: tabular-nums; pointer-events: none; @@ -157,19 +164,22 @@ width: 44px; height: 44px; padding: 0; - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; - background: rgba(248, 236, 208, 0.85); - color: var(--ink-faded); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + background: rgba(20, 29, 40, 0.88); + color: var(--gaslight-dim); cursor: pointer; transition: background 120ms ease, - color 120ms ease; + color 120ms ease, + border-color 120ms ease; &:hover, &:focus-visible { - color: var(--gold-leaf); - background: rgba(248, 236, 208, 0.95); + color: var(--hextech); + border-color: rgba(54, 214, 198, 0.5); + background: rgba(20, 29, 40, 0.96); outline: none; } @@ -179,8 +189,8 @@ } .hint { - font-size: 1rem; + font-size: 0.95rem; font-style: italic; text-align: center; - color: var(--ink-faded); + color: var(--gaslight-faint); } diff --git a/components/listSearch.module.scss b/components/listSearch.module.scss index e547a446..3beca2f6 100644 --- a/components/listSearch.module.scss +++ b/components/listSearch.module.scss @@ -7,11 +7,12 @@ font-family: var(--font-character-name); font-size: 1.8rem; padding: 1rem; - background: rgba(248, 236, 208, 0.55); - color: var(--ink); - // height: 50px; - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; + background: var(--well); + color: var(--gaslight); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.35); outline: none; transition: border-color 150ms ease, @@ -19,15 +20,16 @@ box-shadow 150ms ease; &::placeholder { - color: var(--ink-faded); - font-style: italic; + color: var(--gaslight-faint); } &:focus, &:focus-visible { - border-color: var(--gold-leaf); - background: rgba(248, 236, 208, 0.9); - box-shadow: 0 0 0 2px rgba(212, 162, 89, 0.18); + border-color: rgba(54, 214, 198, 0.6); + background: rgba(7, 12, 18, 0.8); + box-shadow: + inset 0 2px 6px rgba(0, 0, 0, 0.35), + var(--focus-glow); } @media (prefers-reduced-motion: reduce) { @@ -42,7 +44,7 @@ .empty { font-style: italic; - color: var(--ink-faded); + color: var(--gaslight-dim); text-align: center; padding: 2.5rem 1rem; } @@ -50,23 +52,25 @@ .count { margin: 0; font-family: var(--font-ui); - font-size: 0.85rem; - color: var(--ink-faded); - letter-spacing: 1.5px; - font-variant: small-caps; + font-size: 0.8rem; + font-weight: 500; + color: var(--gaslight-faint); + letter-spacing: 0.16em; + text-transform: uppercase; } .pagination { - display: flex; + display: grid; + grid-auto-flow: column; align-items: center; justify-content: center; gap: 1rem; font-family: var(--font-ui); font-size: 0.9rem; - color: var(--ink-faded); + color: var(--gaslight-dim); @media (max-width: bp.$sm) { - display: grid; + grid-auto-flow: row; grid-template-columns: auto 1fr auto; grid-template-areas: "prev status next" @@ -98,7 +102,7 @@ } } -// `.paginationTop` / `.paginationBottom` are marker classes — they carry no +// `.paginationTop` / `.paginationBottom` are marker classes. They carry no // styles, but their presence on the element lets tests identify the top // vs bottom pagination nav by `classList.contains(...)`. .paginationTop { @@ -108,14 +112,17 @@ .button { appearance: none; - background: rgba(248, 236, 208, 0.6); - color: var(--ink); - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; - padding: 0.4rem 0.85rem; + background: var(--plate); + color: var(--gaslight-dim); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; + padding: 0.45rem 0.9rem; font-family: var(--font-ui); + font-weight: 500; font-size: 0.85rem; - letter-spacing: 0.5px; + letter-spacing: 0.08em; + text-transform: uppercase; cursor: pointer; transition: border-color 120ms ease, @@ -124,8 +131,8 @@ &:hover:not(:disabled), &:focus-visible:not(:disabled) { - border-color: var(--gold-leaf); - color: var(--gold-leaf); + border-color: var(--edge-brass); + color: var(--brass-bright); outline: none; } @@ -140,35 +147,37 @@ } .status { - font-variant: small-caps; - letter-spacing: 1.5px; + text-transform: uppercase; + letter-spacing: 0.12em; } .pageSize { - display: flex; + display: grid; + grid-auto-flow: column; align-items: center; gap: 0.4rem; font-family: var(--font-ui); font-size: 0.85rem; - color: var(--ink-faded); - letter-spacing: 0.5px; + color: var(--gaslight-faint); + letter-spacing: 0.06em; } .pageSizeSelect { appearance: none; -webkit-appearance: none; - background: rgba(248, 236, 208, 0.6); - color: var(--ink); - border: 1px solid rgba(107, 68, 35, 0.35); - border-radius: 2px; + background: var(--well); + color: var(--gaslight); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel-sm); + corner-shape: bevel; padding: 0.3rem 1.6rem 0.3rem 0.55rem; font-family: var(--font-ui); font-size: 0.85rem; - letter-spacing: 0.5px; + letter-spacing: 0.06em; cursor: pointer; background-image: - linear-gradient(45deg, transparent 50%, rgba(107, 68, 35, 0.55) 50%), - linear-gradient(135deg, rgba(107, 68, 35, 0.55) 50%, transparent 50%); + linear-gradient(45deg, transparent 50%, rgba(199, 154, 63, 0.75) 50%), + linear-gradient(135deg, rgba(199, 154, 63, 0.75) 50%, transparent 50%); background-position: calc(100% - 0.85rem) 55%, calc(100% - 0.55rem) 55%; @@ -183,8 +192,8 @@ &:hover, &:focus-visible { - border-color: var(--gold-leaf); - color: var(--gold-leaf); + border-color: var(--edge-brass); + color: var(--brass-bright); outline: none; } diff --git a/styles/globals.scss b/styles/globals.scss index d7ea618a..3cffdeb0 100644 --- a/styles/globals.scss +++ b/styles/globals.scss @@ -1,23 +1,70 @@ @use "breakpoints" as bp; :root { - --parchment-light: #f4e4c1; - --parchment-dark: #e8d3a0; - --vellum: #f8ecd0; - --ink: #3d2817; - --ink-faded: #6b4423; - --ink-slate: #2e3a55; - --ink-rose: #6a3142; - --wax-seal: #8b1a1a; - --gold-leaf: #d4a259; - --rose-madder: #a85a6b; - - --font-heading: var(--font-cinzel), Georgia, serif; - --font-character-name: var(--font-cormorant-unicase), Georgia, serif; - --font-body: var(--font-eb-garamond), Georgia, serif; - --font-ui: var(--font-eb-garamond), Georgia, serif; + // Tell the browser this is a dark interface so native widgets (date + // pickers, scrollbars, form indicators) render in their dark forms. + color-scheme: dark; + + // Structural darks, cool iron blues that read as machined metal, not void. + --coal: #0a0e15; + --iron: #111923; + --gunmetal: #1a2530; + --gunmetal-raised: #223040; + --steel: #2e3d4e; + + // Metals. Brass is the primary accent, the resting identity of the atlas. + --brass: #c79a3f; + --brass-bright: #ecca7d; + --brass-dark: #8a6828; + + // The hextech charge. Reserved for interaction: focus, hover, live state. + --hextech: #36d6c6; + --hextech-dim: #17756d; + + // Shimmer, the rare arcane violet. Kept for the exceptional, never routine. + --shimmer: #b660e8; + + // Gaslight text ramp, warm lamplight on cold metal. + --gaslight: #eee6d3; + --gaslight-dim: #b0a893; + --gaslight-faint: #7e8798; + + // Signal red for errors and invalid states. + --ember: #e2604e; + + // Genealogy tints, used by the family tree to mark lines of descent. + --tint-male: #9fc0dc; + --tint-female: #d9a1b4; + + // Hairlines and composed surfaces. + --edge: rgba(126, 152, 180, 0.22); + --edge-strong: rgba(126, 152, 180, 0.38); + --edge-brass: rgba(199, 154, 63, 0.45); + --well: rgba(7, 12, 18, 0.6); + --plate: linear-gradient( + 180deg, + var(--gunmetal-raised) 0%, + var(--gunmetal) 100% + ); + + // Shadows and glows. + --shadow-soft: 0 2px 10px rgba(4, 8, 13, 0.4); + --shadow-raised: 0 10px 28px rgba(4, 8, 13, 0.5); + --focus-glow: + 0 0 0 2px rgba(54, 214, 198, 0.28), 0 0 14px rgba(54, 214, 198, 0.2); + --brass-glow: 0 2px 14px rgba(199, 154, 63, 0.18); + + // Chamfered plate corners; browsers without `corner-shape` fall back to + // plain rounding at the same radius. + --bevel: 10px; + --bevel-sm: 5px; + + --font-heading: var(--font-girassol), Georgia, serif; + --font-character-name: var(--font-poiret-one), "Avenir Next", sans-serif; + --font-body: var(--font-spectral), Georgia, serif; + --font-ui: var(--font-barlow-condensed), "Arial Narrow", sans-serif; --font-sans: - var(--font-alegreya-sans), -apple-system, BlinkMacSystemFont, sans-serif; + var(--font-barlow-condensed), -apple-system, BlinkMacSystemFont, sans-serif; --bp-xs: 480px; --bp-sm: 640px; @@ -25,22 +72,22 @@ --bp-lg: 1024px; --bp-xl: 1280px; - // Regional palette — heraldic border tints used by both the house and - // character list cards. Kept as design tokens so the two list modules - // don't each carry the same nine hex values. Add a new region here, not - // in the module files. - --region-color-north: #5d6f7f; - --region-color-vale: #4d7caa; - --region-color-riverlands: #3d5a7c; - --region-color-westerlands: #b13a3a; - --region-color-reach: #6f8336; - --region-color-stormlands: #c89a31; - --region-color-dorne: #c7693a; - --region-color-iron-islands: #2f4a44; - --region-color-crownlands: #5a2a30; -} - -// Desktop-first breakpoints — default styles target xl. Each @media rule + // Regional palette, heraldic border tints used by both the house and + // character list cards, retuned to stay luminous on the iron ground. + // Kept as design tokens so the two list modules don't each carry the + // same nine hex values. Add a new region here, not in the module files. + --region-color-north: #8ba7bb; + --region-color-vale: #6ca6d9; + --region-color-riverlands: #5d86b5; + --region-color-westerlands: #d15954; + --region-color-reach: #96b054; + --region-color-stormlands: #dcb14e; + --region-color-dorne: #d98550; + --region-color-iron-islands: #62918a; + --region-color-crownlands: #b25a66; +} + +// Desktop-first breakpoints, default styles target xl. Each @media rule // overrides at the named breakpoint AND below. The SCSS breakpoint // variables in `styles/_breakpoints.scss` (`bp.$xs`, `bp.$sm`, ...) are // the source of truth; the `--bp-*` CSS custom properties above are @@ -56,28 +103,42 @@ html, body { margin: 0; padding: 0; + // Layered atmosphere: a warm lamp above, a faint hextech seep below, + // and a surveyor's grid etched into the iron. background: radial-gradient( - ellipse at top left, - rgba(180, 140, 90, 0.15), - transparent 60% + 60% 42% at 50% -2%, + rgba(231, 197, 120, 0.07), + transparent 70% ), radial-gradient( - ellipse at bottom right, - rgba(120, 80, 40, 0.18), - transparent 60% + 50% 40% at 88% 104%, + rgba(54, 214, 198, 0.05), + transparent 65% ), - linear-gradient( - 180deg, - var(--parchment-light) 0%, - var(--parchment-dark) 100% - ); + repeating-linear-gradient( + 0deg, + rgba(120, 148, 178, 0.035) 0, + rgba(120, 148, 178, 0.035) 1px, + transparent 1px, + transparent 56px + ), + repeating-linear-gradient( + 90deg, + rgba(120, 148, 178, 0.035) 0, + rgba(120, 148, 178, 0.035) 1px, + transparent 1px, + transparent 56px + ), + linear-gradient(180deg, var(--iron) 0%, var(--coal) 100%); background-attachment: fixed; - color: var(--ink); + color: var(--gaslight); font-family: var(--font-body); font-size: 16px; + font-weight: 300; line-height: 1.65; min-height: 100vh; + scrollbar-color: var(--steel) transparent; @media (max-width: bp.$md) { font-size: 20px; @@ -100,8 +161,8 @@ h6 { padding: 0; display: grid; font-family: var(--font-heading); - color: var(--ink); - font-weight: 600; + color: var(--gaslight); + font-weight: 400; letter-spacing: 1px; } @@ -111,19 +172,45 @@ p { font-size: 1.25rem; } +strong { + font-weight: 600; +} + h1 { - font-size: 2.2rem; - font-variant: small-caps; - letter-spacing: 2px; + font-size: 2.3rem; + text-transform: uppercase; + letter-spacing: 0.09em; text-align: center; + color: var(--brass-bright); + + @supports (background-clip: text) or (-webkit-background-clip: text) { + background: linear-gradient( + 180deg, + var(--brass-bright) 18%, + var(--brass) 58%, + var(--brass-dark) 100% + ); + -webkit-background-clip: text; + background-clip: text; + -webkit-text-fill-color: transparent; + } } + h2 { - font-size: 1.4rem; - border-bottom: 1px solid rgba(107, 68, 35, 0.3); + font-size: 1.35rem; + text-transform: uppercase; + letter-spacing: 0.08em; + border-bottom: 1px solid var(--edge); + padding-bottom: 0.25rem; } + h3 { - font-size: 1.15rem; - color: var(--ink-faded); + font-family: var(--font-ui); + font-size: 0.95rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.16em; + color: var(--brass); } @media (max-width: bp.$sm) { @@ -136,25 +223,64 @@ h3 { } // Typographic primitive: italic page lede under the `h1`. Used by every -// `ParchmentLayout` page (`app/page.tsx`, houses, castles, not-found, etc.) -// — kept global alongside the heading rules above so consumers don't each +// `ParchmentLayout` page (`app/page.tsx`, houses, castles, not-found, etc.), +// kept global alongside the heading rules above so consumers don't each // import a typography module. .subtitle { display: grid; text-align: center; font-style: italic; - color: var(--ink-faded); + color: var(--gaslight-dim); padding: 0 0 1rem 0; margin: 0; - border-bottom: 1px solid rgba(107, 68, 35, 0.3); + border-bottom: 1px solid var(--edge); } a { - color: var(--ink-faded); + color: var(--brass-bright); text-decoration: underline; - text-decoration-color: rgba(107, 68, 35, 0.4); + text-decoration-color: rgba(199, 154, 63, 0.4); + transition: + color 140ms ease, + text-decoration-color 140ms ease; &:hover { - color: var(--gold-leaf); + color: var(--hextech); + text-decoration-color: rgba(54, 214, 198, 0.5); } + + @media (prefers-reduced-motion: reduce) { + transition: none; + } +} + +:focus-visible { + outline: 2px solid var(--hextech); + outline-offset: 2px; +} + +::selection { + background: rgba(54, 214, 198, 0.28); + color: var(--gaslight); +} + +::-webkit-scrollbar { + width: 10px; + height: 10px; +} + +::-webkit-scrollbar-thumb { + background: var(--steel); + border-radius: 5px; + border: 2px solid transparent; + background-clip: padding-box; + + &:hover { + background-color: var(--brass-dark); + background-clip: padding-box; + } +} + +::-webkit-scrollbar-track { + background: transparent; } From fead017cb0b25c99b926ab9c5c5adc4f49f10b87 Mon Sep 17 00:00:00 2001 From: CJ Rivas Date: Wed, 15 Jul 2026 16:24:54 -0400 Subject: [PATCH 2/2] TKW: generic steampunk redesign replaces Arcane theme MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - palette retuned warm in `styles/globals.scss`: soot/umber grounds, `--hextech`/`--shimmer` renamed to `--verdigris`/`--copper`, matte interaction states replace neon glows, lithograph-muted `--region-color-*` tints - fonts swapped in `app/layout.tsx`: Bevan, Graduate, Old Standard TT, Oswald replace Girassol, Poiret One, Spectral, Barlow Condensed - homepage rebuilt as atlas contents ledger: `app/page.module.scss` masthead + `MainMenu` bound case, `MainMenuTile` rows numbered Plate I–VI with riveted glyph plaques - section order now Maps, Houses, Characters, Timeline, Battles, Weapons in `MainMenu` and `SiteMenu`; tests updated - `SiteHeader` recut as left-aligned bolted nameplate rail with rivet seam and right tagline; `SiteFooter` matches with riveted baseplate - `FiligreeRule` crystal redrawn as pressure gauge with drifting needle; `FiligreeFlourish` gem replaced by hex nut - LED-style indicator dots in timeline, weapon, battle, map-layer modules become matte enamel studs - `MapMarker` glyphs retinted brass/umber; `MapMarker.test.tsx` hexes updated - body background swaps surveyor grid for rivet-head dot grid - `/design` catalogue updated to new palette, type roles, and copy --- app/battles/[slug]/page.module.scss | 2 +- app/battles/page.module.scss | 8 +- app/characters/[slug]/page.module.scss | 6 +- app/design/page.module.scss | 60 +++--- app/design/page.tsx | 72 +++---- app/dragons/[slug]/page.module.scss | 2 +- app/events/[slug]/page.module.scss | 2 +- app/houses/[slug]/page.module.scss | 10 +- app/layout.tsx | 27 +-- app/page.module.scss | 75 +++++++ app/page.tsx | 16 +- app/weapons/[slug]/page.module.scss | 4 +- components/Accordion/Accordion.module.scss | 6 +- .../CharacterSearchInput.module.scss | 4 +- components/FamilyTree/FamilyTree.module.scss | 6 +- .../FamilyTreeChart.module.scss | 18 +- components/Filigree/Filigree.module.scss | 32 +-- components/Filigree/Filigree.tsx | 61 +++--- .../FilteredDragonList.module.scss | 10 +- .../FilteredWeaponList.module.scss | 8 +- components/Infobox/Infobox.module.scss | 4 +- components/MainMenu/MainMenu.module.scss | 57 ++--- components/MainMenu/MainMenu.test.tsx | 36 ++-- components/MainMenu/MainMenu.tsx | 35 ++-- .../MainMenuTile/MainMenuTile.module.scss | 195 ++++++++++++++---- components/MainMenuTile/MainMenuTile.test.tsx | 19 +- components/MainMenuTile/MainMenuTile.tsx | 27 ++- .../MapLayerToggle/MapLayerToggle.module.scss | 8 +- components/MapMarker/MapMarker.module.scss | 2 +- components/MapMarker/MapMarker.test.tsx | 4 +- components/MapMarker/MapMarker.tsx | 18 +- components/MapStage/MapStage.module.scss | 6 +- .../PageHeading/PageHeading.module.scss | 2 +- .../ParchmentLayout.module.scss | 2 +- components/SiteFooter/SiteFooter.module.scss | 28 +-- components/SiteHeader/SiteHeader.module.scss | 160 +++++++------- components/SiteHeader/SiteHeader.tsx | 1 + components/SiteMenu/SiteMenu.module.scss | 29 ++- components/SiteMenu/SiteMenu.test.tsx | 10 +- components/SiteMenu/SiteMenu.tsx | 20 +- components/SortToggle/SortToggle.module.scss | 8 +- .../TimelineChart/TimelineChart.module.scss | 18 +- .../TimelineCluster.module.scss | 4 +- .../TimelineExplorer.module.scss | 2 +- .../TimelineMinimap.module.scss | 6 +- components/ViewToggle/ViewToggle.module.scss | 8 +- components/WorldMap/WorldMap.module.scss | 24 +-- components/listSearch.module.scss | 8 +- styles/globals.scss | 176 +++++++--------- 49 files changed, 788 insertions(+), 558 deletions(-) create mode 100644 app/page.module.scss diff --git a/app/battles/[slug]/page.module.scss b/app/battles/[slug]/page.module.scss index fa2494d9..247f7e1b 100644 --- a/app/battles/[slug]/page.module.scss +++ b/app/battles/[slug]/page.module.scss @@ -80,7 +80,7 @@ text-decoration: none; &:hover { - color: var(--hextech); + color: var(--verdigris); } } } diff --git a/app/battles/page.module.scss b/app/battles/page.module.scss index 789720a4..e7284634 100644 --- a/app/battles/page.module.scss +++ b/app/battles/page.module.scss @@ -54,7 +54,7 @@ transition: background-color 0.15s ease; &:hover { - background-color: rgba(199, 154, 63, 0.08); + background-color: rgba(176, 129, 58, 0.08); } @media (prefers-reduced-motion: reduce) { @@ -77,8 +77,10 @@ width: 0.5rem; height: 0.5rem; border-radius: 50%; - background-color: var(--hextech); - box-shadow: 0 0 6px rgba(54, 214, 198, 0.55); + background-color: var(--verdigris); + box-shadow: + inset 0 1px 1px rgba(255, 255, 255, 0.28), + 0 1px 2px rgba(8, 5, 2, 0.5); } .when { diff --git a/app/characters/[slug]/page.module.scss b/app/characters/[slug]/page.module.scss index 0fe7cf5b..1a962f18 100644 --- a/app/characters/[slug]/page.module.scss +++ b/app/characters/[slug]/page.module.scss @@ -128,7 +128,7 @@ gap: 0.6rem 1.5rem; width: 100%; padding: 1rem 1.25rem; - background: rgba(16, 23, 32, 0.55); + background: rgba(22, 17, 12, 0.55); border: 1px solid var(--edge); border-radius: var(--bevel-sm); corner-shape: bevel; @@ -197,7 +197,7 @@ .relations { padding: 1rem 1.25rem; - background: rgba(16, 23, 32, 0.45); + background: rgba(22, 17, 12, 0.45); border: 1px solid var(--edge); border-radius: var(--bevel-sm); corner-shape: bevel; @@ -263,7 +263,7 @@ text-decoration: none; &:hover { - color: var(--hextech); + color: var(--verdigris); } } } diff --git a/app/design/page.module.scss b/app/design/page.module.scss index 39fb76f0..11e81abb 100644 --- a/app/design/page.module.scss +++ b/app/design/page.module.scss @@ -30,7 +30,7 @@ font-family: ui-monospace, "SF Mono", "Cascadia Mono", Menlo, monospace; font-size: 0.8em; font-style: normal; - color: var(--hextech); + color: var(--verdigris); background: var(--well); border: 1px solid var(--edge); border-radius: 3px; @@ -162,12 +162,12 @@ align-items: center; } -// Each step runs from brass to hextech, metal charged along its length. +// Each step runs from brass to verdigris, polished metal into patina. .spaceBar { height: 18px; min-width: 4px; border-radius: 2px; - background: linear-gradient(90deg, var(--brass), var(--hextech)); + background: linear-gradient(90deg, var(--brass), var(--verdigris)); justify-self: start; } @@ -195,7 +195,7 @@ padding: 1.5rem; border: 1px dashed var(--edge-strong); border-radius: 3px; - background: rgba(199, 154, 63, 0.08); + background: rgba(176, 129, 58, 0.08); } .padInner { @@ -234,7 +234,7 @@ border-radius: var(--bevel); corner-shape: bevel; padding: 1.4rem 1.5rem 1.6rem; - background: rgba(16, 23, 32, 0.45); + background: rgba(22, 17, 12, 0.45); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.03); } @@ -276,8 +276,8 @@ color: var(--gaslight-faint); } -// The canonical text control: a gunmetal well that charges hextech on -// focus. The list search input is the same field at display size. +// The canonical text control: a gunmetal well that takes a verdigris +// seal on focus. The list search input is the same field at display size. .control { appearance: none; -webkit-appearance: none; @@ -303,8 +303,8 @@ } &:focus-visible { - border-color: rgba(54, 214, 198, 0.6); - background: rgba(7, 12, 18, 0.8); + border-color: rgba(121, 164, 140, 0.6); + background: rgba(15, 10, 5, 0.8); box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.4), var(--focus-glow); @@ -313,11 +313,11 @@ &:disabled { opacity: 0.5; cursor: not-allowed; - background: rgba(7, 12, 18, 0.35); + background: rgba(15, 10, 5, 0.35); } &[readonly] { - background: rgba(7, 12, 18, 0.35); + background: rgba(15, 10, 5, 0.35); color: var(--gaslight-dim); } @@ -325,7 +325,7 @@ border-color: var(--ember); box-shadow: inset 0 1px 4px rgba(0, 0, 0, 0.4), - 0 0 0 2px rgba(226, 96, 78, 0.18); + 0 0 0 2px rgba(208, 90, 62, 0.18); } @media (prefers-reduced-motion: reduce) { @@ -338,8 +338,8 @@ select.control { cursor: pointer; padding-right: 2rem; background-image: - linear-gradient(45deg, transparent 50%, rgba(199, 154, 63, 0.75) 50%), - linear-gradient(135deg, rgba(199, 154, 63, 0.75) 50%, transparent 50%); + linear-gradient(45deg, transparent 50%, rgba(176, 129, 58, 0.75) 50%), + linear-gradient(135deg, rgba(176, 129, 58, 0.75) 50%, transparent 50%); background-position: calc(100% - 1.1rem) 55%, calc(100% - 0.8rem) 55%; @@ -369,14 +369,14 @@ select.control { } option:checked { - background: rgba(54, 214, 198, 0.2); + background: rgba(121, 164, 140, 0.2); color: var(--gaslight); } } .range { width: 100%; - accent-color: var(--hextech); + accent-color: var(--verdigris); cursor: pointer; } @@ -391,7 +391,7 @@ select.control { cursor: pointer; &:focus-visible { - border-color: rgba(54, 214, 198, 0.6); + border-color: rgba(121, 164, 140, 0.6); outline: none; box-shadow: var(--focus-glow); } @@ -438,7 +438,7 @@ select.control { border-radius: var(--bevel-sm); corner-shape: bevel; padding: 1rem 1.2rem 1.15rem; - background: rgba(13, 19, 27, 0.4); + background: rgba(18, 14, 9, 0.4); } .optionLegend { @@ -465,11 +465,11 @@ select.control { .check { width: 1.15rem; height: 1.15rem; - accent-color: var(--hextech); + accent-color: var(--verdigris); cursor: pointer; &:focus-visible { - outline: 2px solid var(--hextech); + outline: 2px solid var(--verdigris); outline-offset: 2px; } } @@ -505,7 +505,7 @@ select.control { padding: 2px; border-radius: 13px; border: 1px solid var(--edge-strong); - background: rgba(7, 12, 18, 0.7); + background: rgba(15, 10, 5, 0.7); transition: background 150ms ease, border-color 150ms ease, @@ -517,16 +517,16 @@ select.control { height: 18px; border-radius: 50%; background: var(--gaslight); - box-shadow: 0 1px 3px rgba(4, 8, 13, 0.6); + box-shadow: 0 1px 3px rgba(8, 5, 2, 0.6); transform: translateX(0); transition: transform 150ms ease; } -// Thrown on, the switch runs charged. +// Thrown on, the switch shows its patina. .switchInput:checked ~ .switchTrack { - background: var(--hextech-dim); - border-color: rgba(54, 214, 198, 0.5); - box-shadow: inset 0 0 8px rgba(54, 214, 198, 0.3); + background: var(--verdigris-dim); + border-color: rgba(121, 164, 140, 0.5); + box-shadow: inset 0 0 8px rgba(121, 164, 140, 0.3); } .switchInput:checked ~ .switchTrack .switchThumb { @@ -534,7 +534,7 @@ select.control { } .switchInput:focus-visible ~ .switchTrack { - border-color: rgba(54, 214, 198, 0.6); + border-color: rgba(121, 164, 140, 0.6); box-shadow: var(--focus-glow); } @@ -586,7 +586,7 @@ select.control { } &:focus-visible:not(:disabled) { - border-color: rgba(54, 214, 198, 0.6); + border-color: rgba(121, 164, 140, 0.6); box-shadow: var(--focus-glow); outline: none; } @@ -631,10 +631,10 @@ select.control { .btnGhost { @extend .btn; background: transparent; - border-color: rgba(199, 154, 63, 0.4); + border-color: rgba(176, 129, 58, 0.4); color: var(--brass-bright); &:hover:not(:disabled) { - background: rgba(199, 154, 63, 0.08); + background: rgba(176, 129, 58, 0.08); } } diff --git a/app/design/page.tsx b/app/design/page.tsx index 27be9787..82ce82d9 100644 --- a/app/design/page.tsx +++ b/app/design/page.tsx @@ -18,37 +18,37 @@ type Swatch = { token: string; hex: string; name: string }; // tokens declared in `styles/globals.scss`. This page is the living catalogue // of those tokens; keep it in step when a token is added or renamed there. const CORE_PALETTE: Swatch[] = [ - { token: "--coal", hex: "#0a0e15", name: "Coal" }, - { token: "--iron", hex: "#111923", name: "Iron" }, - { token: "--gunmetal", hex: "#1a2530", name: "Gunmetal" }, - { token: "--gunmetal-raised", hex: "#223040", name: "Raised Gunmetal" }, - { token: "--steel", hex: "#2e3d4e", name: "Steel" }, - { token: "--brass", hex: "#c79a3f", name: "Brass" }, - { token: "--brass-bright", hex: "#ecca7d", name: "Bright Brass" }, - { token: "--brass-dark", hex: "#8a6828", name: "Dark Brass" }, - { token: "--hextech", hex: "#36d6c6", name: "Hextech" }, - { token: "--hextech-dim", hex: "#17756d", name: "Deep Hextech" }, - { token: "--shimmer", hex: "#b660e8", name: "Shimmer" }, - { token: "--gaslight", hex: "#eee6d3", name: "Gaslight" }, - { token: "--gaslight-dim", hex: "#b0a893", name: "Dim Gaslight" }, - { token: "--gaslight-faint", hex: "#7e8798", name: "Faint Gaslight" }, - { token: "--ember", hex: "#e2604e", name: "Ember" }, + { token: "--coal", hex: "#14100a", name: "Coal" }, + { token: "--iron", hex: "#1d1712", name: "Iron" }, + { token: "--gunmetal", hex: "#271f16", name: "Gunmetal" }, + { token: "--gunmetal-raised", hex: "#322818", name: "Raised Gunmetal" }, + { token: "--steel", hex: "#4a3b2b", name: "Steel" }, + { token: "--brass", hex: "#b0813a", name: "Brass" }, + { token: "--brass-bright", hex: "#e4bf78", name: "Bright Brass" }, + { token: "--brass-dark", hex: "#77571f", name: "Dark Brass" }, + { token: "--verdigris", hex: "#79a48c", name: "Verdigris" }, + { token: "--verdigris-dim", hex: "#435f4e", name: "Deep Verdigris" }, + { token: "--copper", hex: "#c1704a", name: "Copper" }, + { token: "--gaslight", hex: "#f0e7d2", name: "Gaslight" }, + { token: "--gaslight-dim", hex: "#bfb096", name: "Dim Gaslight" }, + { token: "--gaslight-faint", hex: "#8f8069", name: "Faint Gaslight" }, + { token: "--ember", hex: "#d05a3e", name: "Ember" }, ]; const REGION_PALETTE: Swatch[] = [ - { token: "--region-color-north", hex: "#8ba7bb", name: "North" }, - { token: "--region-color-vale", hex: "#6ca6d9", name: "Vale" }, - { token: "--region-color-riverlands", hex: "#5d86b5", name: "Riverlands" }, - { token: "--region-color-westerlands", hex: "#d15954", name: "Westerlands" }, - { token: "--region-color-reach", hex: "#96b054", name: "Reach" }, - { token: "--region-color-stormlands", hex: "#dcb14e", name: "Stormlands" }, - { token: "--region-color-dorne", hex: "#d98550", name: "Dorne" }, + { token: "--region-color-north", hex: "#92a6b0", name: "North" }, + { token: "--region-color-vale", hex: "#7ba3c4", name: "Vale" }, + { token: "--region-color-riverlands", hex: "#6b89a8", name: "Riverlands" }, + { token: "--region-color-westerlands", hex: "#c25c50", name: "Westerlands" }, + { token: "--region-color-reach", hex: "#93a854", name: "Reach" }, + { token: "--region-color-stormlands", hex: "#d3a94e", name: "Stormlands" }, + { token: "--region-color-dorne", hex: "#cd7f4b", name: "Dorne" }, { token: "--region-color-iron-islands", - hex: "#62918a", + hex: "#6d9186", name: "Iron Islands", }, - { token: "--region-color-crownlands", hex: "#b25a66", name: "Crownlands" }, + { token: "--region-color-crownlands", hex: "#ad5c62", name: "Crownlands" }, ]; type FontRole = { family: string; label: string; sample: string }; @@ -56,22 +56,22 @@ type FontRole = { family: string; label: string; sample: string }; const FONT_ROLES: FontRole[] = [ { family: "var(--font-heading)", - label: "Girassol · Headings", + label: "Bevan · Headings", sample: "The Known World", }, { family: "var(--font-character-name)", - label: "Poiret One · Nameplates", + label: "Graduate · Nameplates", sample: "Eddard Stark", }, { family: "var(--font-body)", - label: "Spectral · Body", + label: "Old Standard TT · Body", sample: "The night is dark and full of terrors.", }, { family: "var(--font-sans)", - label: "Barlow Condensed · Labels & data", + label: "Oswald · Labels & data", sample: "298 AC · 42 houses · 9 regions", }, ]; @@ -270,22 +270,22 @@ export default function DesignSystemPage() {

    Typography

    - Headings are engraved in Girassol; body copy is set in Spectral. The + Headings are struck in Bevan; body copy is set in Old Standard TT. The scale below renders each element exactly as the global stylesheet styles it.

    - H1 · 2.2rem + H1 · 2rem

    Winter Is Coming

    - H2 · 1.4rem + H2 · 1.2rem

    The Great Houses

    - H3 · 1.15rem + H3 · 0.9rem

    Wardens of the North

    @@ -311,7 +311,7 @@ export default function DesignSystemPage() { Words can carry bold weight or an{" "} italic aside, and a{" "} cross-reference links onward in brass - and hextech. + and verdigris.

    @@ -386,8 +386,8 @@ export default function DesignSystemPage() {

    Form controls

    - Every native control, machined in gunmetal and brass and charged with - hextech. Try them: the fields hold their own state, and{" "} + Every native control, machined in gunmetal and brass and sealed with + verdigris. Try them: the fields hold their own state, and{" "} Reset fields restores the defaults.

    @@ -447,7 +447,7 @@ export default function DesignSystemPage() { id="df-color" className={styles.colorInput} type="color" - defaultValue="#36d6c6" + defaultValue="#79a48c" /> diff --git a/app/dragons/[slug]/page.module.scss b/app/dragons/[slug]/page.module.scss index 31a6964a..75843354 100644 --- a/app/dragons/[slug]/page.module.scss +++ b/app/dragons/[slug]/page.module.scss @@ -67,7 +67,7 @@ text-decoration: none; &:hover { - color: var(--hextech); + color: var(--verdigris); } } } diff --git a/app/events/[slug]/page.module.scss b/app/events/[slug]/page.module.scss index 761c5cf7..b3790170 100644 --- a/app/events/[slug]/page.module.scss +++ b/app/events/[slug]/page.module.scss @@ -56,7 +56,7 @@ text-decoration: none; &:hover { - color: var(--hextech); + color: var(--verdigris); } } } diff --git a/app/houses/[slug]/page.module.scss b/app/houses/[slug]/page.module.scss index c4003e82..aa7e3d4a 100644 --- a/app/houses/[slug]/page.module.scss +++ b/app/houses/[slug]/page.module.scss @@ -44,7 +44,7 @@ font-size: 2.7rem; letter-spacing: 0.05em; line-height: 1.05; - text-shadow: 0 2px 10px rgba(4, 8, 13, 0.6); + text-shadow: 0 2px 10px rgba(8, 5, 2, 0.6); @media (max-width: bp.$sm) { font-size: 2.1rem; @@ -115,7 +115,7 @@ li { padding: 0.4rem 0.75rem; - background: rgba(16, 23, 32, 0.55); + background: rgba(22, 17, 12, 0.55); border: 1px solid var(--edge); border-radius: 3px; line-height: 1.45; @@ -134,9 +134,9 @@ a.notableName { &:hover, &:focus-visible { - color: var(--hextech); + color: var(--verdigris); text-decoration: underline; - text-decoration-color: rgba(54, 214, 198, 0.45); + text-decoration-color: rgba(121, 164, 140, 0.45); outline: none; } @@ -163,7 +163,7 @@ a.notableName { text-decoration: none; &:hover { - color: var(--hextech); + color: var(--verdigris); } } } diff --git a/app/layout.tsx b/app/layout.tsx index 396b2453..c821f7fd 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -1,35 +1,30 @@ import type { Metadata, Viewport } from "next"; -import { - Barlow_Condensed, - Girassol, - Poiret_One, - Spectral, -} from "next/font/google"; +import { Bevan, Graduate, Old_Standard_TT, Oswald } from "next/font/google"; import { NuqsAdapter } from "nuqs/adapters/next/app"; import "../styles/globals.scss"; import { SiteHeader } from "@/components/SiteHeader"; import { SiteMenu } from "@/components/SiteMenu"; import { SiteFooter } from "@/components/SiteFooter"; -const girassol = Girassol({ +const bevan = Bevan({ subsets: ["latin"], - variable: "--font-girassol", + variable: "--font-bevan", weight: "400", }); -const poiretOne = Poiret_One({ +const graduate = Graduate({ subsets: ["latin"], - variable: "--font-poiret-one", + variable: "--font-graduate", weight: "400", }); -const spectral = Spectral({ +const oldStandard = Old_Standard_TT({ subsets: ["latin"], - variable: "--font-spectral", - weight: ["300", "400", "500", "600"], + variable: "--font-old-standard", + weight: ["400", "700"], style: ["normal", "italic"], }); -const barlowCondensed = Barlow_Condensed({ +const oswald = Oswald({ subsets: ["latin"], - variable: "--font-barlow-condensed", + variable: "--font-oswald", weight: ["400", "500", "600"], }); @@ -55,7 +50,7 @@ export default function RootLayout({ return ( diff --git a/app/page.module.scss b/app/page.module.scss new file mode 100644 index 00000000..62d29b08 --- /dev/null +++ b/app/page.module.scss @@ -0,0 +1,75 @@ +@use "breakpoints" as bp; + +// The homepage spread: masthead column on the left, contents ledger on the +// right, like the title page of a bound atlas facing its index. +.contents { + display: grid; + grid-template-areas: "masthead ledger"; + grid-template-columns: minmax(240px, 320px) minmax(0, 1fr); + gap: 3.5rem; + align-items: start; + width: 100%; + max-width: 1080px; + padding-top: 2.5rem; + + > :last-child { + grid-area: ledger; + } + + @media (max-width: bp.$lg) { + grid-template-areas: + "masthead" + "ledger"; + grid-template-columns: minmax(0, 1fr); + gap: 2.5rem; + max-width: 720px; + padding-top: 1rem; + } +} + +.masthead { + grid-area: masthead; + display: grid; + justify-items: start; + gap: 1rem; + position: sticky; + top: 7.5rem; + + @media (max-width: bp.$lg) { + position: static; + justify-items: center; + text-align: center; + gap: 0.85rem; + } +} + +.eyebrow { + font-family: var(--font-ui); + font-weight: 400; + font-size: 0.8rem; + text-transform: uppercase; + letter-spacing: 0.32em; + color: var(--brass); +} + +.title { + text-align: left; + font-size: 2.4rem; + line-height: 1.15; + + @media (max-width: bp.$lg) { + text-align: center; + font-size: 2rem; + } +} + +.rule { + width: min(260px, 100%); +} + +.lede { + font-style: italic; + font-size: 1.1rem; + color: var(--gaslight-dim); + max-width: 34ch; +} diff --git a/app/page.tsx b/app/page.tsx index 14d61548..86e3a239 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -1,11 +1,23 @@ import { ParchmentLayout } from "@/components/ParchmentLayout"; import { MainMenu } from "@/components/MainMenu"; +import { FiligreeRule } from "@/components/Filigree"; +import styles from "@/app/page.module.scss"; export default function Home() { return ( -

    Choose a path.

    - +
    +
    +

    A Song of Ice and Fire

    +

    Table of Plates

    + +

    + The realm surveyed from the Wall to the Summer Sea, engraved plate + by plate. Open one to begin. +

    +
    + +
    ); } diff --git a/app/weapons/[slug]/page.module.scss b/app/weapons/[slug]/page.module.scss index 893624c5..58751630 100644 --- a/app/weapons/[slug]/page.module.scss +++ b/app/weapons/[slug]/page.module.scss @@ -61,7 +61,7 @@ border-radius: var(--bevel); corner-shape: bevel; box-shadow: - inset 0 0 30px rgba(4, 8, 13, 0.35), + inset 0 0 30px rgba(8, 5, 2, 0.35), var(--shadow-soft); margin: 0; @@ -96,7 +96,7 @@ text-decoration: none; &:hover { - color: var(--hextech); + color: var(--verdigris); } } } diff --git a/components/Accordion/Accordion.module.scss b/components/Accordion/Accordion.module.scss index f102373c..66989308 100644 --- a/components/Accordion/Accordion.module.scss +++ b/components/Accordion/Accordion.module.scss @@ -2,7 +2,7 @@ border: 1px solid var(--edge-strong); border-radius: var(--bevel); corner-shape: bevel; - background: rgba(13, 19, 27, 0.5); + background: rgba(18, 14, 9, 0.5); overflow: hidden; } @@ -32,7 +32,7 @@ &:hover, &:focus-visible { - background: linear-gradient(180deg, #283a4d 0%, var(--gunmetal) 100%); + background: linear-gradient(180deg, #4a3b2b 0%, var(--gunmetal) 100%); color: var(--brass-bright); outline: none; } @@ -56,7 +56,7 @@ // An open drawer is a live circuit: the chevron turns and charges. .chevronOpen { transform: rotate(90deg); - color: var(--hextech); + color: var(--verdigris); } .title { diff --git a/components/CharacterSearchInput/CharacterSearchInput.module.scss b/components/CharacterSearchInput/CharacterSearchInput.module.scss index 99762dae..1cacfd70 100644 --- a/components/CharacterSearchInput/CharacterSearchInput.module.scss +++ b/components/CharacterSearchInput/CharacterSearchInput.module.scss @@ -26,7 +26,7 @@ gap: 0.15rem; max-height: 18rem; overflow-y: auto; - background: #1c2836; + background: #2b2217; border: 1px solid var(--edge-strong); border-radius: var(--bevel-sm); corner-shape: bevel; @@ -48,7 +48,7 @@ // The keyboard-active row runs charged. .optionActive { - background: rgba(54, 214, 198, 0.14); + background: rgba(121, 164, 140, 0.14); } .optionName { diff --git a/components/FamilyTree/FamilyTree.module.scss b/components/FamilyTree/FamilyTree.module.scss index cf29598d..9485c955 100644 --- a/components/FamilyTree/FamilyTree.module.scss +++ b/components/FamilyTree/FamilyTree.module.scss @@ -66,7 +66,7 @@ padding: 0.25rem 0.6rem; width: fit-content; max-width: 100%; - background: rgba(16, 23, 32, 0.55); + background: rgba(22, 17, 12, 0.55); border: 1px solid var(--edge); border-radius: 3px; @@ -104,9 +104,9 @@ a.name { &:hover, &:focus-visible { - color: var(--hextech); + color: var(--verdigris); text-decoration: underline; - text-decoration-color: rgba(54, 214, 198, 0.45); + text-decoration-color: rgba(121, 164, 140, 0.45); outline: none; } diff --git a/components/FamilyTreeChart/FamilyTreeChart.module.scss b/components/FamilyTreeChart/FamilyTreeChart.module.scss index d23199a7..df072b19 100644 --- a/components/FamilyTreeChart/FamilyTreeChart.module.scss +++ b/components/FamilyTreeChart/FamilyTreeChart.module.scss @@ -6,7 +6,7 @@ border: 1px solid var(--edge-strong); border-radius: var(--bevel); corner-shape: bevel; - background: rgba(13, 19, 27, 0.5); + background: rgba(18, 14, 9, 0.5); touch-action: none; user-select: none; } @@ -24,7 +24,7 @@ .dot { fill: var(--gunmetal-raised); - stroke: rgba(126, 152, 180, 0.65); + stroke: rgba(190, 158, 110, 0.65); stroke-width: 1.5; } @@ -48,7 +48,7 @@ // Solid backing that approximates the canvas colour so labels mask the // edges passing beneath them. .labelBg { - fill: #141d27; + fill: #1b1510; pointer-events: none; } @@ -61,7 +61,7 @@ } .edge { - stroke: rgba(126, 152, 180, 0.4); + stroke: rgba(190, 158, 110, 0.4); stroke-width: 1; fill: none; } @@ -84,7 +84,7 @@ display: grid; gap: 0.25rem; padding: 0.4rem; - background: rgba(20, 29, 40, 0.92); + background: rgba(27, 21, 16, 0.92); border: 1px solid var(--edge-strong); border-radius: var(--bevel-sm); corner-shape: bevel; @@ -118,15 +118,15 @@ &:hover, &:focus-visible { color: var(--brass-bright); - background: rgba(199, 154, 63, 0.1); + background: rgba(176, 129, 58, 0.1); outline: none; } // The engaged mode runs charged. &[aria-pressed="true"] { - color: var(--hextech); - background: rgba(54, 214, 198, 0.12); - border-color: rgba(54, 214, 198, 0.45); + color: var(--verdigris); + background: rgba(121, 164, 140, 0.12); + border-color: rgba(121, 164, 140, 0.45); } @media (prefers-reduced-motion: reduce) { diff --git a/components/Filigree/Filigree.module.scss b/components/Filigree/Filigree.module.scss index f3c92314..f22fc777 100644 --- a/components/Filigree/Filigree.module.scss +++ b/components/Filigree/Filigree.module.scss @@ -46,30 +46,30 @@ } } -// The crystal itself: charged hextech, softly breathing. The one moving -// part of the whole page furniture. -.gem { - fill: var(--hextech); - filter: drop-shadow(0 0 4px rgba(54, 214, 198, 0.65)); - animation: gem-breathe 4.5s ease-in-out infinite; +// The gauge needle wanders its dial like a boiler under uneven draught. +// The one moving part of the whole page furniture. +.needle { + color: var(--brass-bright); + transform-origin: 120px 12px; + transform-box: view-box; + animation: needle-drift 9s ease-in-out infinite alternate; @media (prefers-reduced-motion: reduce) { animation: none; } } -.gemFacet { - stroke: var(--coal); - stroke-width: 0.8; - opacity: 0.45; +// The hex nut that caps the flourish's pipework. +.nut { + fill: currentColor; + opacity: 0.9; } -@keyframes gem-breathe { - 0%, - 100% { - opacity: 0.78; +@keyframes needle-drift { + 0% { + transform: rotate(-14deg); } - 50% { - opacity: 1; + 100% { + transform: rotate(30deg); } } diff --git a/components/Filigree/Filigree.tsx b/components/Filigree/Filigree.tsx index d1eec33f..dea2ddbe 100644 --- a/components/Filigree/Filigree.tsx +++ b/components/Filigree/Filigree.tsx @@ -6,8 +6,9 @@ type FlourishProps = { className?: string; }; -// A short conduit: an engraved rail feeding a cogwheel, ending in a charged -// spark. Reads left to right; `mirrored` flips it for the right-hand side. +// A short run of pipework: an engraved rail feeding a cogwheel, closed off +// with a hex nut. Reads left to right; `mirrored` flips it for the +// right-hand side. export function FiligreeFlourish({ mirrored = false, className, @@ -32,7 +33,10 @@ export function FiligreeFlourish({ - + ); @@ -42,32 +46,41 @@ type RuleProps = { className?: string; }; -// The atlas signature: a hextech crystal set into an engraved rail, ringed -// by cog collars. It underlines every page title and divides long pages. +// The atlas signature: a pressure gauge set into an engraved rail, its +// needle wandering the dial. It underlines every page title and divides +// long pages. export function FiligreeRule({ className }: RuleProps) { return ( ); diff --git a/components/FilteredDragonList/FilteredDragonList.module.scss b/components/FilteredDragonList/FilteredDragonList.module.scss index 8472763a..5412d9ef 100644 --- a/components/FilteredDragonList/FilteredDragonList.module.scss +++ b/components/FilteredDragonList/FilteredDragonList.module.scss @@ -98,10 +98,10 @@ font-weight: 400; } -// Wild dragons answer to no house: they carry the shimmer, the arcane -// violet reserved for the unbound. +// Wild dragons answer to no house: they carry raw copper, the warm +// accent reserved for the unbound. .cardWild { - border-color: rgba(182, 96, 232, 0.45); + border-color: rgba(193, 112, 74, 0.45); } .wildBadge { @@ -113,7 +113,7 @@ text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.85rem; - color: var(--shimmer); - border: 1px dashed rgba(182, 96, 232, 0.5); + color: var(--copper); + border: 1px dashed rgba(193, 112, 74, 0.5); border-radius: 50%; } diff --git a/components/FilteredWeaponList/FilteredWeaponList.module.scss b/components/FilteredWeaponList/FilteredWeaponList.module.scss index f3bd54dc..b270ad81 100644 --- a/components/FilteredWeaponList/FilteredWeaponList.module.scss +++ b/components/FilteredWeaponList/FilteredWeaponList.module.scss @@ -30,7 +30,7 @@ transition: background-color 0.15s ease; &:hover { - background-color: rgba(199, 154, 63, 0.08); + background-color: rgba(176, 129, 58, 0.08); } @media (prefers-reduced-motion: reduce) { @@ -53,8 +53,10 @@ width: 0.5rem; height: 0.5rem; border-radius: 50%; - background-color: var(--hextech); - box-shadow: 0 0 6px rgba(54, 214, 198, 0.55); + background-color: var(--verdigris); + box-shadow: + inset 0 1px 1px rgba(255, 255, 255, 0.28), + 0 1px 2px rgba(8, 5, 2, 0.5); } // Keep the sigil small so it never grows the row taller than the name's diff --git a/components/Infobox/Infobox.module.scss b/components/Infobox/Infobox.module.scss index 0e86ae28..09ab5eea 100644 --- a/components/Infobox/Infobox.module.scss +++ b/components/Infobox/Infobox.module.scss @@ -36,10 +36,10 @@ a { color: var(--gaslight); - text-decoration-color: rgba(199, 154, 63, 0.35); + text-decoration-color: rgba(176, 129, 58, 0.35); &:hover { - color: var(--hextech); + color: var(--verdigris); } } diff --git a/components/MainMenu/MainMenu.module.scss b/components/MainMenu/MainMenu.module.scss index 203a2248..44db8268 100644 --- a/components/MainMenu/MainMenu.module.scss +++ b/components/MainMenu/MainMenu.module.scss @@ -1,48 +1,15 @@ -@use "breakpoints" as bp; - +// The bound case around the contents ledger. Rows draw their own seams; +// the case supplies the plate, the chamfered corners, and the well. .menu { display: grid; - grid-template-columns: repeat(6, 1fr); - grid-template-areas: - "maps maps timeline timeline houses houses" - "characters characters weapons weapons dragons dragons"; - gap: 1.5rem; - - > :nth-child(1) { - grid-area: maps; - } - > :nth-child(2) { - grid-area: timeline; - } - > :nth-child(3) { - grid-area: houses; - } - > :nth-child(4) { - grid-area: characters; - } - > :nth-child(5) { - grid-area: weapons; - } - > :nth-child(6) { - grid-area: dragons; - } - - @media (max-width: bp.$lg) { - grid-template-columns: repeat(2, 1fr); - grid-template-areas: - "maps timeline" - "houses characters" - "weapons dragons"; - } - - @media (max-width: bp.$md) { - grid-template-columns: 1fr; - grid-template-areas: - "maps" - "timeline" - "houses" - "characters" - "weapons" - "dragons"; - } + align-content: start; + width: 100%; + background: var(--well); + border: 1px solid var(--edge-strong); + border-radius: var(--bevel); + corner-shape: bevel; + box-shadow: + inset 0 1px 0 rgba(255, 255, 255, 0.04), + var(--shadow-soft); + overflow: hidden; } diff --git a/components/MainMenu/MainMenu.test.tsx b/components/MainMenu/MainMenu.test.tsx index 9d905ff8..a98d09e6 100644 --- a/components/MainMenu/MainMenu.test.tsx +++ b/components/MainMenu/MainMenu.test.tsx @@ -3,7 +3,7 @@ import { render, screen } from "@testing-library/react"; import { MainMenu } from "@/components/MainMenu"; describe("MainMenu", () => { - it("renders only visible tiles in order: Maps, Timeline, Houses, Characters, Weapons, Battles", () => { + it("renders only visible entries in plate order: Maps, Houses, Characters, Timeline, Battles, Weapons", () => { render(); const links = screen.getAllByRole("link"); expect(links).toHaveLength(6); @@ -11,23 +11,33 @@ describe("MainMenu", () => { expect(links[0].textContent).toContain("Maps"); expect(links[0].getAttribute("href")).toBe("/maps/"); - expect(links[1].textContent).toContain("Timeline"); - expect(links[1].getAttribute("href")).toBe("/timeline/"); + expect(links[1].textContent).toContain("Houses"); + expect(links[1].getAttribute("href")).toBe("/houses/"); - expect(links[2].textContent).toContain("Houses"); - expect(links[2].getAttribute("href")).toBe("/houses/"); + expect(links[2].textContent).toContain("Characters"); + expect(links[2].getAttribute("href")).toBe("/characters/"); - expect(links[3].textContent).toContain("Characters"); - expect(links[3].getAttribute("href")).toBe("/characters/"); + expect(links[3].textContent).toContain("Timeline"); + expect(links[3].getAttribute("href")).toBe("/timeline/"); - expect(links[4].textContent).toContain("Weapons"); - expect(links[4].getAttribute("href")).toBe("/weapons/"); + expect(links[4].textContent).toContain("Battles"); + expect(links[4].getAttribute("href")).toBe("/battles/"); - expect(links[5].textContent).toContain("Battles"); - expect(links[5].getAttribute("href")).toBe("/battles/"); + expect(links[5].textContent).toContain("Weapons"); + expect(links[5].getAttribute("href")).toBe("/weapons/"); }); - it("does not render hidden tiles (Dragons)", () => { + it("numbers the visible entries as plates I through VI", () => { + render(); + const links = screen.getAllByRole("link"); + const numerals = ["I", "II", "III", "IV", "V", "VI"]; + links.reduce((expected, link) => { + expect(link.textContent).toContain(`Plate${expected[0]}`); + return expected.slice(1); + }, numerals); + }); + + it("does not render hidden entries (Dragons)", () => { render(); const hrefs = screen .getAllByRole("link") @@ -35,7 +45,7 @@ describe("MainMenu", () => { expect(hrefs).not.toContain("/dragons/"); }); - it('wraps tiles in a nav landmark labelled "Atlas sections"', () => { + it('wraps entries in a nav landmark labelled "Atlas sections"', () => { render(); expect( screen.getByRole("navigation", { name: /atlas sections/i }), diff --git a/components/MainMenu/MainMenu.tsx b/components/MainMenu/MainMenu.tsx index 5007a1be..6f1ce735 100644 --- a/components/MainMenu/MainMenu.tsx +++ b/components/MainMenu/MainMenu.tsx @@ -2,46 +2,55 @@ import { MainMenuTile } from "@/components/MainMenuTile"; import { sectionGlyphs } from "@/components/SectionGlyphs/SectionGlyphs"; import styles from "@/components/MainMenu/MainMenu.module.scss"; +// The contents ledger: every section of the atlas bound in one case, each +// entry numbered as an engraved plate. export function MainMenu() { return (
    ); diff --git a/components/SiteMenu/SiteMenu.module.scss b/components/SiteMenu/SiteMenu.module.scss index 481c4dfe..17c0631f 100644 --- a/components/SiteMenu/SiteMenu.module.scss +++ b/components/SiteMenu/SiteMenu.module.scss @@ -10,7 +10,7 @@ width: 2.5rem; height: 2.5rem; padding: 0; - background: rgba(18, 26, 36, 0.7); + background: rgba(29, 23, 18, 0.7); border: 1px solid var(--edge-strong); border-radius: var(--bevel-sm); corner-shape: bevel; @@ -24,14 +24,14 @@ &:hover, &:focus-visible { - color: var(--hextech); + color: var(--verdigris); border-color: var(--edge-brass); - background: rgba(26, 37, 48, 0.9); + background: rgba(39, 31, 22, 0.9); box-shadow: var(--focus-glow); } &:focus-visible { - outline: 2px solid var(--hextech); + outline: 2px solid var(--verdigris); outline-offset: 2px; } @@ -48,7 +48,7 @@ .backdrop { position: fixed; inset: 0; - background: rgba(4, 8, 13, 0.6); + background: rgba(8, 5, 2, 0.6); opacity: 0; pointer-events: none; transition: opacity 220ms ease; @@ -70,8 +70,8 @@ bottom: 0; left: 0; width: min(20rem, 86vw); - background: linear-gradient(180deg, #1c2836 0%, #141d28 100%); - border-right: 1px solid rgba(199, 154, 63, 0.3); + background: linear-gradient(180deg, #2b2217 0%, #1b1510 100%); + border-right: 1px solid rgba(176, 129, 58, 0.3); box-shadow: var(--shadow-raised); transform: translateX(-100%); transition: transform 240ms ease; @@ -147,12 +147,12 @@ &:hover, &:focus-visible { - color: var(--hextech); + color: var(--verdigris); border-color: var(--edge-brass); } &:focus-visible { - outline: 2px solid var(--hextech); + outline: 2px solid var(--verdigris); outline-offset: 2px; } @@ -198,7 +198,7 @@ &:hover, &:focus-visible { color: var(--gaslight); - background: rgba(199, 154, 63, 0.08); + background: rgba(176, 129, 58, 0.08); border-left-color: var(--brass); } @@ -242,14 +242,13 @@ display: block; } -// The open section runs charged: hextech rail, lit glyph. +// The open section wears verdigris: the oxidised rail marks where you are. .linkActive { color: var(--gaslight); - border-left-color: var(--hextech); - background: rgba(54, 214, 198, 0.07); + border-left-color: var(--verdigris); + background: rgba(121, 164, 140, 0.07); .linkIcon { - color: var(--hextech); - filter: drop-shadow(0 0 4px rgba(54, 214, 198, 0.5)); + color: var(--verdigris); } } diff --git a/components/SiteMenu/SiteMenu.test.tsx b/components/SiteMenu/SiteMenu.test.tsx index 61460884..82f3a745 100644 --- a/components/SiteMenu/SiteMenu.test.tsx +++ b/components/SiteMenu/SiteMenu.test.tsx @@ -19,7 +19,7 @@ describe("SiteMenu", () => { expect(links).toHaveLength(0); }); - it("reveals only the visible primary nav items (Maps, Timeline, Houses, Characters, Weapons, Battles) when opened", () => { + it("reveals only the visible primary nav items in plate order (Maps, Houses, Characters, Timeline, Battles, Weapons) when opened", () => { render(); fireEvent.click(screen.getByRole("button", { name: /open menu/i })); @@ -30,19 +30,19 @@ describe("SiteMenu", () => { const hrefs = links.map((l) => l.getAttribute("href") ?? ""); expect(hrefs).toEqual([ "/maps/", - "/timeline/", "/houses/", "/characters/", - "/weapons/", + "/timeline/", "/battles/", + "/weapons/", ]); expect(links.map((l) => l.textContent?.trim())).toEqual([ "Maps", - "Timeline", "Houses", "Characters", - "Weapons", + "Timeline", "Battles", + "Weapons", ]); }); diff --git a/components/SiteMenu/SiteMenu.tsx b/components/SiteMenu/SiteMenu.tsx index 344dfb57..ed01b6e6 100644 --- a/components/SiteMenu/SiteMenu.tsx +++ b/components/SiteMenu/SiteMenu.tsx @@ -16,7 +16,7 @@ type MenuItem = { }; // Every entry uses its section's line-art glyph so the drawer stays -// monochrome metal; the raster menu icons belonged to the parchment era. +// monochrome metal, listed in the same plate order as the homepage ledger. const ITEMS: MenuItem[] = [ { href: "/maps/", @@ -24,12 +24,6 @@ const ITEMS: MenuItem[] = [ glyph: sectionGlyphs.maps, visible: true, }, - { - href: "/timeline/", - label: "Timeline", - glyph: sectionGlyphs.timeline, - visible: true, - }, { href: "/houses/", label: "Houses", @@ -43,9 +37,9 @@ const ITEMS: MenuItem[] = [ visible: true, }, { - href: "/weapons/", - label: "Weapons", - glyph: sectionGlyphs.weapons, + href: "/timeline/", + label: "Timeline", + glyph: sectionGlyphs.timeline, visible: true, }, { @@ -54,6 +48,12 @@ const ITEMS: MenuItem[] = [ glyph: sectionGlyphs.battles, visible: true, }, + { + href: "/weapons/", + label: "Weapons", + glyph: sectionGlyphs.weapons, + visible: true, + }, { href: "/dragons/", label: "Dragons", diff --git a/components/SortToggle/SortToggle.module.scss b/components/SortToggle/SortToggle.module.scss index 350852a5..0b680d3f 100644 --- a/components/SortToggle/SortToggle.module.scss +++ b/components/SortToggle/SortToggle.module.scss @@ -40,14 +40,14 @@ &:focus-visible { color: var(--brass-bright); outline: none; - background: rgba(199, 154, 63, 0.08); + background: rgba(176, 129, 58, 0.08); } // The engaged switch runs charged. &[aria-pressed="true"] { - color: var(--hextech); - background: rgba(54, 214, 198, 0.1); - box-shadow: inset 0 0 10px rgba(54, 214, 198, 0.12); + color: var(--verdigris); + background: rgba(121, 164, 140, 0.1); + box-shadow: inset 0 0 10px rgba(121, 164, 140, 0.12); } @media (prefers-reduced-motion: reduce) { diff --git a/components/TimelineChart/TimelineChart.module.scss b/components/TimelineChart/TimelineChart.module.scss index a320261e..fc847647 100644 --- a/components/TimelineChart/TimelineChart.module.scss +++ b/components/TimelineChart/TimelineChart.module.scss @@ -69,7 +69,7 @@ %column { position: relative; - border-right: 1px dashed rgba(126, 152, 180, 0.12); + border-right: 1px dashed rgba(190, 158, 110, 0.12); &:last-of-type { border-right: none; @@ -102,7 +102,7 @@ display: grid; grid-template-areas: "label"; justify-items: start; - border-top: 1px dashed rgba(126, 152, 180, 0.16); + border-top: 1px dashed rgba(190, 158, 110, 0.16); } // Year labels along the axis: instrument figures on the dial. @@ -132,9 +132,9 @@ grid-template-columns: var(--era-width) 1fr; align-items: center; justify-items: center; - background: rgba(199, 154, 63, 0.05); - border-top: 1px solid rgba(199, 154, 63, 0.2); - border-bottom: 1px solid rgba(199, 154, 63, 0.2); + background: rgba(176, 129, 58, 0.05); + border-top: 1px solid rgba(176, 129, 58, 0.2); + border-bottom: 1px solid rgba(176, 129, 58, 0.2); } .eraLabel { @@ -201,10 +201,12 @@ align-self: center; width: 0.5rem; height: 0.5rem; - background: var(--hextech); - border: 1px solid rgba(23, 117, 109, 0.9); + background: var(--verdigris); + border: 1px solid rgba(67, 95, 78, 0.9); border-radius: 50%; - box-shadow: 0 0 6px rgba(54, 214, 198, 0.55); + box-shadow: + inset 0 1px 1px rgba(255, 255, 255, 0.28), + 0 1px 2px rgba(8, 5, 2, 0.5); } .eventName { diff --git a/components/TimelineCluster/TimelineCluster.module.scss b/components/TimelineCluster/TimelineCluster.module.scss index 1a0f3aa5..6fa1fcf4 100644 --- a/components/TimelineCluster/TimelineCluster.module.scss +++ b/components/TimelineCluster/TimelineCluster.module.scss @@ -62,7 +62,7 @@ padding: 0.35rem; margin: 0; list-style: none; - background: #1c2836; + background: #2b2217; border: 1px solid var(--edge-brass); border-radius: var(--bevel-sm); corner-shape: bevel; @@ -86,7 +86,7 @@ &:hover, &:focus-visible { - background: rgba(199, 154, 63, 0.1); + background: rgba(176, 129, 58, 0.1); color: var(--gaslight); } } diff --git a/components/TimelineExplorer/TimelineExplorer.module.scss b/components/TimelineExplorer/TimelineExplorer.module.scss index 8f431a01..ea3268f0 100644 --- a/components/TimelineExplorer/TimelineExplorer.module.scss +++ b/components/TimelineExplorer/TimelineExplorer.module.scss @@ -19,7 +19,7 @@ justify-items: center; gap: 0.25rem; padding: 0.35rem; - background: rgba(20, 29, 40, 0.92); + background: rgba(27, 21, 16, 0.92); border: 1px solid var(--edge-strong); border-radius: var(--bevel-sm); corner-shape: bevel; diff --git a/components/TimelineMinimap/TimelineMinimap.module.scss b/components/TimelineMinimap/TimelineMinimap.module.scss index 3512fe32..1ae70033 100644 --- a/components/TimelineMinimap/TimelineMinimap.module.scss +++ b/components/TimelineMinimap/TimelineMinimap.module.scss @@ -9,7 +9,7 @@ max-height: 82vh; overflow-y: auto; padding: 0.5rem 0.25rem; - background: rgba(20, 29, 40, 0.92); + background: rgba(27, 21, 16, 0.92); border: 1px solid var(--edge-strong); border-radius: var(--bevel-sm); corner-shape: bevel; @@ -52,8 +52,8 @@ &:hover, &:focus-visible { - color: var(--hextech); - background: rgba(54, 214, 198, 0.08); + color: var(--verdigris); + background: rgba(121, 164, 140, 0.08); } @media (prefers-reduced-motion: reduce) { diff --git a/components/ViewToggle/ViewToggle.module.scss b/components/ViewToggle/ViewToggle.module.scss index a75979c2..74d7abc0 100644 --- a/components/ViewToggle/ViewToggle.module.scss +++ b/components/ViewToggle/ViewToggle.module.scss @@ -39,14 +39,14 @@ &:focus-visible { color: var(--brass-bright); outline: none; - background: rgba(199, 154, 63, 0.08); + background: rgba(176, 129, 58, 0.08); } // The engaged view runs charged. &[aria-pressed="true"] { - color: var(--hextech); - background: rgba(54, 214, 198, 0.1); - box-shadow: inset 0 0 10px rgba(54, 214, 198, 0.12); + color: var(--verdigris); + background: rgba(121, 164, 140, 0.1); + box-shadow: inset 0 0 10px rgba(121, 164, 140, 0.12); } @media (prefers-reduced-motion: reduce) { diff --git a/components/WorldMap/WorldMap.module.scss b/components/WorldMap/WorldMap.module.scss index e9d75e95..3b3c9368 100644 --- a/components/WorldMap/WorldMap.module.scss +++ b/components/WorldMap/WorldMap.module.scss @@ -9,7 +9,7 @@ } // The chart table: the parchment map is an exhibit under glass, held in a -// brass instrument bezel; the chrome around it stays cold metal. +// brass instrument bezel; the chrome around it stays oiled iron. .stage { position: relative; width: 100%; @@ -26,14 +26,14 @@ corner-shape: bevel; background: var(--well); box-shadow: - inset 0 0 40px rgba(4, 8, 13, 0.5), + inset 0 0 40px rgba(8, 5, 2, 0.5), var(--shadow-soft); overflow: hidden; display: grid; grid-template-areas: "canvas"; &:focus-visible { - outline: 2px solid var(--hextech); + outline: 2px solid var(--verdigris); outline-offset: 2px; } @@ -62,8 +62,8 @@ cursor: pointer; circle { - fill: rgba(54, 214, 198, 0); - stroke: rgba(54, 214, 198, 0); + fill: rgba(121, 164, 140, 0); + stroke: rgba(121, 164, 140, 0); stroke-width: 3; transition: fill 120ms ease, @@ -72,8 +72,8 @@ &:hover circle, &:focus-visible circle { - fill: rgba(54, 214, 198, 0.15); - stroke: var(--hextech); + fill: rgba(121, 164, 140, 0.15); + stroke: var(--verdigris); } &:focus-visible { @@ -98,7 +98,7 @@ border: 1px solid var(--edge-strong); border-radius: var(--bevel-sm); corner-shape: bevel; - background: rgba(20, 29, 40, 0.9); + background: rgba(27, 21, 16, 0.9); color: var(--gaslight-dim); font-size: 0.85rem; font-variant-numeric: tabular-nums; @@ -167,7 +167,7 @@ border: 1px solid var(--edge-strong); border-radius: var(--bevel-sm); corner-shape: bevel; - background: rgba(20, 29, 40, 0.88); + background: rgba(27, 21, 16, 0.88); color: var(--gaslight-dim); cursor: pointer; transition: @@ -177,9 +177,9 @@ &:hover, &:focus-visible { - color: var(--hextech); - border-color: rgba(54, 214, 198, 0.5); - background: rgba(20, 29, 40, 0.96); + color: var(--verdigris); + border-color: rgba(121, 164, 140, 0.5); + background: rgba(27, 21, 16, 0.96); outline: none; } diff --git a/components/listSearch.module.scss b/components/listSearch.module.scss index 3beca2f6..466f5171 100644 --- a/components/listSearch.module.scss +++ b/components/listSearch.module.scss @@ -25,8 +25,8 @@ &:focus, &:focus-visible { - border-color: rgba(54, 214, 198, 0.6); - background: rgba(7, 12, 18, 0.8); + border-color: rgba(121, 164, 140, 0.6); + background: rgba(15, 10, 5, 0.8); box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.35), var(--focus-glow); @@ -176,8 +176,8 @@ letter-spacing: 0.06em; cursor: pointer; background-image: - linear-gradient(45deg, transparent 50%, rgba(199, 154, 63, 0.75) 50%), - linear-gradient(135deg, rgba(199, 154, 63, 0.75) 50%, transparent 50%); + linear-gradient(45deg, transparent 50%, rgba(176, 129, 58, 0.75) 50%), + linear-gradient(135deg, rgba(176, 129, 58, 0.75) 50%, transparent 50%); background-position: calc(100% - 0.85rem) 55%, calc(100% - 0.55rem) 55%; diff --git a/styles/globals.scss b/styles/globals.scss index 3cffdeb0..5d173427 100644 --- a/styles/globals.scss +++ b/styles/globals.scss @@ -5,66 +5,68 @@ // pickers, scrollbars, form indicators) render in their dark forms. color-scheme: dark; - // Structural darks, cool iron blues that read as machined metal, not void. - --coal: #0a0e15; - --iron: #111923; - --gunmetal: #1a2530; - --gunmetal-raised: #223040; - --steel: #2e3d4e; + // Structural darks: soot and oiled iron, warmed by lamplight rather + // than cooled by void. The whole atlas sits on these. + --coal: #14100a; + --iron: #1d1712; + --gunmetal: #271f16; + --gunmetal-raised: #322818; + --steel: #4a3b2b; // Metals. Brass is the primary accent, the resting identity of the atlas. - --brass: #c79a3f; - --brass-bright: #ecca7d; - --brass-dark: #8a6828; + --brass: #b0813a; + --brass-bright: #e4bf78; + --brass-dark: #77571f; - // The hextech charge. Reserved for interaction: focus, hover, live state. - --hextech: #36d6c6; - --hextech-dim: #17756d; + // Verdigris, oxidised copper. Reserved for interaction: focus, hover, + // live state. Matte, never luminous. + --verdigris: #79a48c; + --verdigris-dim: #435f4e; - // Shimmer, the rare arcane violet. Kept for the exceptional, never routine. - --shimmer: #b660e8; + // Raw copper, the rare warm accent. Kept for the exceptional, never routine. + --copper: #c1704a; - // Gaslight text ramp, warm lamplight on cold metal. - --gaslight: #eee6d3; - --gaslight-dim: #b0a893; - --gaslight-faint: #7e8798; + // Gaslight text ramp, warm lamplight on dark metal. + --gaslight: #f0e7d2; + --gaslight-dim: #bfb096; + --gaslight-faint: #8f8069; // Signal red for errors and invalid states. - --ember: #e2604e; + --ember: #d05a3e; // Genealogy tints, used by the family tree to mark lines of descent. - --tint-male: #9fc0dc; - --tint-female: #d9a1b4; + --tint-male: #9db6c8; + --tint-female: #d4a3b0; // Hairlines and composed surfaces. - --edge: rgba(126, 152, 180, 0.22); - --edge-strong: rgba(126, 152, 180, 0.38); - --edge-brass: rgba(199, 154, 63, 0.45); - --well: rgba(7, 12, 18, 0.6); + --edge: rgba(190, 158, 110, 0.2); + --edge-strong: rgba(190, 158, 110, 0.34); + --edge-brass: rgba(176, 129, 58, 0.5); + --well: rgba(15, 10, 5, 0.55); --plate: linear-gradient( 180deg, var(--gunmetal-raised) 0%, var(--gunmetal) 100% ); - // Shadows and glows. - --shadow-soft: 0 2px 10px rgba(4, 8, 13, 0.4); - --shadow-raised: 0 10px 28px rgba(4, 8, 13, 0.5); - --focus-glow: - 0 0 0 2px rgba(54, 214, 198, 0.28), 0 0 14px rgba(54, 214, 198, 0.2); - --brass-glow: 0 2px 14px rgba(199, 154, 63, 0.18); + // Shadows and sheens. Depth comes from soot shadow and a faint warm + // lamplight catch on brass; nothing glows of its own accord. + --shadow-soft: 0 2px 10px rgba(8, 5, 2, 0.4); + --shadow-raised: 0 10px 28px rgba(8, 5, 2, 0.5); + --focus-glow: 0 0 0 2px rgba(121, 164, 140, 0.4); + --brass-glow: 0 2px 12px rgba(176, 129, 58, 0.16); // Chamfered plate corners; browsers without `corner-shape` fall back to // plain rounding at the same radius. --bevel: 10px; --bevel-sm: 5px; - --font-heading: var(--font-girassol), Georgia, serif; - --font-character-name: var(--font-poiret-one), "Avenir Next", sans-serif; - --font-body: var(--font-spectral), Georgia, serif; - --font-ui: var(--font-barlow-condensed), "Arial Narrow", sans-serif; + --font-heading: var(--font-bevan), "Rockwell", Georgia, serif; + --font-character-name: var(--font-graduate), "Copperplate", serif; + --font-body: var(--font-old-standard), Georgia, serif; + --font-ui: var(--font-oswald), "Arial Narrow", sans-serif; --font-sans: - var(--font-barlow-condensed), -apple-system, BlinkMacSystemFont, sans-serif; + var(--font-oswald), -apple-system, BlinkMacSystemFont, sans-serif; --bp-xs: 480px; --bp-sm: 640px; @@ -73,18 +75,19 @@ --bp-xl: 1280px; // Regional palette, heraldic border tints used by both the house and - // character list cards, retuned to stay luminous on the iron ground. - // Kept as design tokens so the two list modules don't each carry the - // same nine hex values. Add a new region here, not in the module files. - --region-color-north: #8ba7bb; - --region-color-vale: #6ca6d9; - --region-color-riverlands: #5d86b5; - --region-color-westerlands: #d15954; - --region-color-reach: #96b054; - --region-color-stormlands: #dcb14e; - --region-color-dorne: #d98550; - --region-color-iron-islands: #62918a; - --region-color-crownlands: #b25a66; + // character list cards, desaturated to sit like hand-tinted lithograph + // inks on the soot ground. Kept as design tokens so the two list modules + // don't each carry the same nine hex values. Add a new region here, not + // in the module files. + --region-color-north: #92a6b0; + --region-color-vale: #7ba3c4; + --region-color-riverlands: #6b89a8; + --region-color-westerlands: #c25c50; + --region-color-reach: #93a854; + --region-color-stormlands: #d3a94e; + --region-color-dorne: #cd7f4b; + --region-color-iron-islands: #6d9186; + --region-color-crownlands: #ad5c62; } // Desktop-first breakpoints, default styles target xl. Each @media rule @@ -103,39 +106,25 @@ html, body { margin: 0; padding: 0; - // Layered atmosphere: a warm lamp above, a faint hextech seep below, - // and a surveyor's grid etched into the iron. + // Layered atmosphere: one warm lamp above and a grid of rivet heads + // punched into the soot-dark plating. background: radial-gradient( - 60% 42% at 50% -2%, - rgba(231, 197, 120, 0.07), + 58% 40% at 50% -4%, + rgba(228, 191, 120, 0.06), transparent 70% ), - radial-gradient( - 50% 40% at 88% 104%, - rgba(54, 214, 198, 0.05), - transparent 65% - ), - repeating-linear-gradient( - 0deg, - rgba(120, 148, 178, 0.035) 0, - rgba(120, 148, 178, 0.035) 1px, - transparent 1px, - transparent 56px - ), - repeating-linear-gradient( - 90deg, - rgba(120, 148, 178, 0.035) 0, - rgba(120, 148, 178, 0.035) 1px, - transparent 1px, - transparent 56px - ), + radial-gradient(circle, rgba(190, 158, 110, 0.05) 1px, transparent 1.5px), linear-gradient(180deg, var(--iron) 0%, var(--coal) 100%); + background-size: + auto, + 34px 34px, + auto; background-attachment: fixed; color: var(--gaslight); font-family: var(--font-body); font-size: 16px; - font-weight: 300; + font-weight: 400; line-height: 1.65; min-height: 100vh; scrollbar-color: var(--steel) transparent; @@ -163,7 +152,7 @@ h6 { font-family: var(--font-heading); color: var(--gaslight); font-weight: 400; - letter-spacing: 1px; + letter-spacing: 0.01em; } p { @@ -173,43 +162,28 @@ p { } strong { - font-weight: 600; + font-weight: 700; } h1 { - font-size: 2.3rem; - text-transform: uppercase; - letter-spacing: 0.09em; + font-size: 2rem; text-align: center; color: var(--brass-bright); - - @supports (background-clip: text) or (-webkit-background-clip: text) { - background: linear-gradient( - 180deg, - var(--brass-bright) 18%, - var(--brass) 58%, - var(--brass-dark) 100% - ); - -webkit-background-clip: text; - background-clip: text; - -webkit-text-fill-color: transparent; - } + line-height: 1.2; } h2 { - font-size: 1.35rem; - text-transform: uppercase; - letter-spacing: 0.08em; - border-bottom: 1px solid var(--edge); - padding-bottom: 0.25rem; + font-size: 1.2rem; + border-bottom: 3px double var(--edge-strong); + padding-bottom: 0.35rem; } h3 { font-family: var(--font-ui); - font-size: 0.95rem; + font-size: 0.9rem; font-weight: 600; text-transform: uppercase; - letter-spacing: 0.16em; + letter-spacing: 0.18em; color: var(--brass); } @@ -239,14 +213,14 @@ h3 { a { color: var(--brass-bright); text-decoration: underline; - text-decoration-color: rgba(199, 154, 63, 0.4); + text-decoration-color: rgba(176, 129, 58, 0.4); transition: color 140ms ease, text-decoration-color 140ms ease; &:hover { - color: var(--hextech); - text-decoration-color: rgba(54, 214, 198, 0.5); + color: var(--verdigris); + text-decoration-color: rgba(121, 164, 140, 0.5); } @media (prefers-reduced-motion: reduce) { @@ -255,12 +229,12 @@ a { } :focus-visible { - outline: 2px solid var(--hextech); + outline: 2px solid var(--verdigris); outline-offset: 2px; } ::selection { - background: rgba(54, 214, 198, 0.28); + background: rgba(176, 129, 58, 0.35); color: var(--gaslight); }