ui(guide): 💄 Refactor guide system UI components including ClimateOverviewPage, ClimateTerrainPage, ExpansionsPage, HomePage, LeyLinesPage, and SurvivalGuidePage
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
This commit is contained in:
parent
287e17a1d5
commit
003bb65b64
6 changed files with 19 additions and 139 deletions
|
|
@ -130,17 +130,11 @@ const FEEDBACK_LOOPS = [
|
|||
cycle: 'Dead coasts → less evaporation → drought → more death',
|
||||
desc: 'When too many coastal tiles die, evaporation plummets. Inland regions dry out, forests wither, and the collapse accelerates.',
|
||||
},
|
||||
{
|
||||
icon: '🟣', accent: '#7040a0', name: 'Corruption Creep',
|
||||
cycle: 'Corruption → pressure on neighbors → spreads → more pressure',
|
||||
desc: 'Death ley lines triple the spread rate. Life and Nature ley lines cut it in half. Control the ley network to contain corruption.',
|
||||
},
|
||||
]
|
||||
|
||||
const MAGIC_EFFECTS = [
|
||||
{ title: 'Weather Spells', accent: '#4080c0', desc: 'Inject heat or moisture directly, pushing tiles past climate tipping points. A drought spell turns farmland to desert; a rain spell grows forests.' },
|
||||
{ title: 'Ley Lines', accent: '#c9a84c', desc: 'Project school-aligned energy across the map. Life supports fertility, Death spreads corruption, Nature boosts forests, Chaos destabilizes.' },
|
||||
{ title: 'Corruption', accent: '#7040a0', desc: 'Spreads through ley lines and terrain. Left unchecked, it devours entire continents. Life and Nature magic are the primary defenses.' },
|
||||
{ title: 'Ley Lines', accent: '#c9a84c', desc: 'Project school-aligned energy across the map. Life supports fertility, Death brings stagnant heat, Nature boosts forests, Chaos destabilizes.' },
|
||||
{ title: 'Terrain Reshaping', accent: '#40a050', desc: 'Sustained magical influence reshapes terrain faster than nature. An Archon casting weather spells for 20 turns can transform a region.' },
|
||||
]
|
||||
|
||||
|
|
@ -152,8 +146,8 @@ export default function ClimateOverviewPage(): ReactElement {
|
|||
<PageTitle>
|
||||
<Heading as="h1" size="2xl" marginBottom="xs">The Living World</Heading>
|
||||
<Text color="muted" size="sm">
|
||||
Your world changes every turn — terrain shifts, rivers form, storms rage,
|
||||
and corruption spreads. Understanding these forces gives you a strategic edge.
|
||||
Your world changes every turn — terrain shifts, rivers form, and storms rage.
|
||||
Understanding these forces gives you a strategic edge.
|
||||
</Text>
|
||||
</PageTitle>
|
||||
|
||||
|
|
@ -221,9 +215,9 @@ export default function ClimateOverviewPage(): ReactElement {
|
|||
<Section>
|
||||
<SectionHeading>Magic & Climate</SectionHeading>
|
||||
<Prose>
|
||||
Magic is the most powerful lever for reshaping the world. Spells, ley lines,
|
||||
and corruption all interact with the climate simulation — sometimes in ways
|
||||
that cascade far beyond the initial effect.
|
||||
Magic is the most powerful lever for reshaping the world. Spells and ley lines
|
||||
interact with the climate simulation — sometimes in ways that cascade far
|
||||
beyond the initial effect.
|
||||
</Prose>
|
||||
<MagicGrid>
|
||||
{MAGIC_EFFECTS.map((m) => (
|
||||
|
|
|
|||
|
|
@ -3,10 +3,9 @@ import styled from 'styled-components'
|
|||
import { FadeIn } from '@magic-civ/guide-engine'
|
||||
import { Heading, Text } from '@lilith/ui-typography'
|
||||
import { PageTitle, Section, SectionHeading, Prose, Callout, CalloutText } from '@magic-civ/guide-engine'
|
||||
import { QualityLadder, RainShadowDiagram, CorruptionSpread } from '@magic-civ/guide-engine'
|
||||
import { QualityLadder, RainShadowDiagram } from '@magic-civ/guide-engine'
|
||||
import { EncyclopediaCallout } from '@magic-civ/guide-engine'
|
||||
import {
|
||||
leyChanneling, corruptionTerrainModifiers,
|
||||
qualityUpThreshold, qualityDownThreshold, mountainRainShadowBlock,
|
||||
} from '@/data'
|
||||
|
||||
|
|
@ -157,40 +156,6 @@ const SourceWhere = styled.p`
|
|||
margin: 0;
|
||||
`
|
||||
|
||||
// ─── Ley Effect Cards ───────────────────────────────────────────────────────
|
||||
|
||||
const LeyGrid = styled.div`
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
|
||||
gap: 0.625rem;
|
||||
margin-top: 0.5rem;
|
||||
`
|
||||
|
||||
const LeyCard = styled.div<{ $accent: string }>`
|
||||
background: ${({ theme }) => theme.colors.surface};
|
||||
border: 1px solid ${({ theme }) => theme.colors.border.default};
|
||||
border-left: 3px solid ${({ $accent }) => $accent};
|
||||
border-radius: 6px;
|
||||
padding: 0.625rem 0.875rem;
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
`
|
||||
|
||||
const LeyName = styled.span`
|
||||
font-size: 0.75rem;
|
||||
font-weight: 600;
|
||||
color: ${({ theme }) => theme.colors.text.secondary};
|
||||
`
|
||||
|
||||
const LeyRate = styled.span<{ $color: string }>`
|
||||
font-size: 0.75rem;
|
||||
font-weight: 700;
|
||||
color: ${({ $color }) => $color};
|
||||
white-space: nowrap;
|
||||
`
|
||||
|
||||
// ─── Data ───────────────────────────────────────────────────────────────────
|
||||
|
||||
const blockPct = Math.round(mountainRainShadowBlock * 100)
|
||||
|
|
@ -209,35 +174,6 @@ const RIVER_SOURCES = [
|
|||
{ icon: '🧊', accent: '#5090c0', name: 'Glacial', where: 'Snow and ice at high elevations' },
|
||||
]
|
||||
|
||||
// Ley channeling data from climate_spec.json
|
||||
const LEY_ACCENTS: Record<string, { accent: string; color: string }> = {
|
||||
death_ley: { accent: '#7040a0', color: '#c060d0' },
|
||||
on_ley_generic: { accent: '#c09030', color: '#d0a040' },
|
||||
off_ley: { accent: '#666', color: '#999' },
|
||||
nature_life_ley: { accent: '#40a050', color: '#60c070' },
|
||||
}
|
||||
|
||||
function formatLeyMult(mult: number): string {
|
||||
if (mult === 1.0) return 'Normal'
|
||||
if (mult > 1.0) return `${mult}x faster`
|
||||
return `${Math.round(1 / mult)}x slower`
|
||||
}
|
||||
|
||||
const LEY_LABELS: Record<string, string> = {
|
||||
death_ley: 'Death ley line',
|
||||
on_ley_generic: 'Any other ley line',
|
||||
off_ley: 'No ley line',
|
||||
nature_life_ley: 'Life / Nature ley line',
|
||||
}
|
||||
|
||||
const LEY_ORDER = ['death_ley', 'on_ley_generic', 'off_ley', 'nature_life_ley'] as const
|
||||
|
||||
const LEY_EFFECTS = LEY_ORDER.map((key) => ({
|
||||
name: LEY_LABELS[key],
|
||||
rate: formatLeyMult(leyChanneling[key]),
|
||||
...(LEY_ACCENTS[key] ?? { accent: '#666', color: '#999' }),
|
||||
}))
|
||||
|
||||
const RIVER_WIDTHS = [
|
||||
{ width: 3, label: 'Stream' },
|
||||
{ width: 6, label: 'River' },
|
||||
|
|
@ -253,7 +189,7 @@ export default function ClimateTerrainPage(): ReactElement {
|
|||
<PageTitle>
|
||||
<Heading as="h1" size="2xl" marginBottom="xs">Terrain & Rivers</Heading>
|
||||
<Text color="muted" size="sm">
|
||||
How the landscape evolves, where rivers form, and how corruption reshapes the world.
|
||||
How the landscape evolves, where rivers form, and how the climate reshapes the world.
|
||||
</Text>
|
||||
</PageTitle>
|
||||
|
||||
|
|
@ -393,7 +329,7 @@ export default function ClimateTerrainPage(): ReactElement {
|
|||
<FamilyHeading>Fixed Terrain</FamilyHeading>
|
||||
<Prose>These terrain types never evolve via the climate system:</Prose>
|
||||
<FixedGrid>
|
||||
{['Ocean', 'Coast', 'Lake', 'Inland Sea', 'Volcano', 'Corrupted Land'].map((t) => (
|
||||
{['Ocean', 'Coast', 'Lake', 'Inland Sea', 'Volcano'].map((t) => (
|
||||
<FixedBadge key={t}>{t}</FixedBadge>
|
||||
))}
|
||||
</FixedGrid>
|
||||
|
|
@ -448,59 +384,11 @@ export default function ClimateTerrainPage(): ReactElement {
|
|||
<RainShadowDiagram steps={RAIN_SHADOW_STEPS} />
|
||||
<Prose>
|
||||
Healthy oceans supply the evaporation that feeds everything downstream. When
|
||||
coastal tiles die from corruption, evaporation drops, drying out inland regions
|
||||
coastal reef health declines, evaporation drops, drying out inland regions
|
||||
and potentially triggering a continental drought spiral.
|
||||
</Prose>
|
||||
</Section>
|
||||
|
||||
<Section>
|
||||
<SectionHeading>Corruption</SectionHeading>
|
||||
<Prose>
|
||||
Corrupted land radiates pressure outward to its neighbors every turn. When
|
||||
pressure builds past a threshold, the neighbor flips — and begins spreading
|
||||
corruption further. Water tiles (ocean, lake, coast) never flip to corrupted
|
||||
land, but corruption degrades their marine ecosystem instead.
|
||||
</Prose>
|
||||
<CorruptionSpread caption="Corruption pressure radiates outward — strongest at the source, weakening with distance" />
|
||||
<Prose>
|
||||
Ley lines are the biggest factor in how fast corruption spreads:
|
||||
</Prose>
|
||||
<LeyGrid>
|
||||
{LEY_EFFECTS.map((l) => (
|
||||
<LeyCard key={l.name} $accent={l.accent}>
|
||||
<LeyName>{l.name}</LeyName>
|
||||
<LeyRate $color={l.color}>{l.rate}</LeyRate>
|
||||
</LeyCard>
|
||||
))}
|
||||
</LeyGrid>
|
||||
<Prose style={{ marginTop: '0.75rem' }}>
|
||||
Life and Nature ley lines don't just slow corruption — they actively drain
|
||||
corruption pressure each turn, healing the land over time.
|
||||
</Prose>
|
||||
{corruptionTerrainModifiers.length > 0 && (
|
||||
<>
|
||||
<Prose>
|
||||
Some terrain types also affect how fast corruption radiates from a source tile:
|
||||
</Prose>
|
||||
<LeyGrid>
|
||||
{corruptionTerrainModifiers.map((t) => (
|
||||
<LeyCard key={t.id} $accent={t.modifier > 1 ? '#c04020' : '#40a050'}>
|
||||
<LeyName>{t.name}</LeyName>
|
||||
<LeyRate $color={t.modifier > 1 ? '#e06040' : '#60c070'}>
|
||||
{t.modifier > 1 ? `${t.modifier}x faster` : `${t.modifier}x (resists)`}
|
||||
</LeyRate>
|
||||
</LeyCard>
|
||||
))}
|
||||
</LeyGrid>
|
||||
</>
|
||||
)}
|
||||
<Prose style={{ marginTop: '0.75rem' }}>
|
||||
High moisture on the receiving tile also dampens corruption — wet terrain like
|
||||
jungle naturally resists, while dry terrain is more vulnerable. City protection
|
||||
buildings can further reduce spread within their radius. Controlling ley lines
|
||||
near corruption sources is one of the most critical late-game decisions.
|
||||
</Prose>
|
||||
</Section>
|
||||
</FadeIn>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ export default function ExpansionsPage(): ReactElement {
|
|||
Expand beyond a single world. Discover and colonize other planets through
|
||||
late-game Aether magic or mundane orbital technology. Each planet has its own
|
||||
climate system, terrain, resources, and native creatures — a full second (or
|
||||
third) map with independent weather, corruption, and ley networks.
|
||||
third) map with independent weather and ley networks.
|
||||
</CardText>
|
||||
<FeatureList>
|
||||
<li>Multiple planet maps with independent climate and ecology</li>
|
||||
|
|
|
|||
|
|
@ -203,7 +203,7 @@ const FEATURES = [
|
|||
},
|
||||
{
|
||||
title: 'Living World',
|
||||
desc: 'Dynamic climate with temperature, moisture, wind, and corruption. Ley lines connect magical nodes, projecting school-aligned energy that shapes terrain and empowers spells.',
|
||||
desc: 'Dynamic climate with temperature, moisture, and wind. Ley lines connect magical nodes, projecting school-aligned energy that shapes terrain and empowers spells.',
|
||||
},
|
||||
{
|
||||
title: 'Playable World Poles',
|
||||
|
|
@ -261,7 +261,7 @@ export default function HomePage(): ReactElement {
|
|||
The world you find yourself in is molded by ages past — strange substances
|
||||
and untamed nature that transform the landscape with raw magical power.
|
||||
Mana nodes pulse with school-aligned energy: Life's radiance heals the
|
||||
land, Death's corruption withers it, Chaos scorches, Nature overgrows,
|
||||
land, Death's influence withers it, Chaos scorches, Nature overgrows,
|
||||
and Aether crystallizes reality itself.
|
||||
</LoreParagraph>
|
||||
<LoreParagraph>
|
||||
|
|
|
|||
|
|
@ -179,7 +179,7 @@ const CLIMATE_EFFECTS = [
|
|||
{ school: 'life', effect: '+moisture', detail: 'Fertile rainfall, accelerated growth' },
|
||||
{ school: 'nature', effect: '+moisture', detail: 'Verdant humidity, forest spread' },
|
||||
{ school: 'chaos', effect: '+heat', detail: 'Volcanic warmth, storm pressure' },
|
||||
{ school: 'death', effect: '+heat, +corruption', detail: 'Stagnant warmth, corruption bleed' },
|
||||
{ school: 'death', effect: '+heat', detail: 'Stagnant warmth, withering decay' },
|
||||
{ school: 'aether', effect: '−heat', detail: 'Crystalline cold, thinned atmosphere' },
|
||||
]
|
||||
|
||||
|
|
@ -207,9 +207,9 @@ export default function LeyLinesPage(): ReactElement {
|
|||
<Text>
|
||||
Ley lines form through resonance between natural wonders sharing compatible magic schools.
|
||||
Wonders with allied schools on the color wheel (e.g., Life + Nature) create strong resonant
|
||||
connections; enemy schools (e.g., Life vs Death) generate disruption zones of heat and
|
||||
corruption instead. They alter climate, feed mana pools, and shape the magical character
|
||||
of the land they cross.
|
||||
connections; enemy schools (e.g., Life vs Death) generate disruption zones of heat
|
||||
instead. They alter climate, feed mana pools, and shape the magical character of
|
||||
the land they cross.
|
||||
</Text>
|
||||
</PageTitle>
|
||||
|
||||
|
|
@ -323,8 +323,8 @@ export default function LeyLinesPage(): ReactElement {
|
|||
<RuleHeading $variant="disruption">Disruption</RuleHeading>
|
||||
<RuleBody>
|
||||
Only enemy school pairs (affinity = 0) → no ley line forms. Instead, the hex path
|
||||
between them suffers heat pressure and corruption bleed proportional to the
|
||||
weaker wonder's strength.
|
||||
between them suffers heat pressure proportional to the weaker wonder's
|
||||
strength.
|
||||
</RuleBody>
|
||||
</RuleCard>
|
||||
<RuleCard $variant="silent">
|
||||
|
|
|
|||
|
|
@ -348,7 +348,6 @@ export default function SurvivalGuidePage(): ReactElement {
|
|||
</Text>
|
||||
</PageTitle>
|
||||
|
||||
<EncyclopediaCallout entryId="corruption" />
|
||||
|
||||
{/* Section 1: Cascade Model */}
|
||||
<Section>
|
||||
|
|
@ -439,7 +438,6 @@ export default function SurvivalGuidePage(): ReactElement {
|
|||
<TileValue>{getEffectValue(arcaneDome, 'aerosol_mitigation')}% aerosol reduction</TileValue>
|
||||
<TileSub>
|
||||
Costs {(arcaneDome as any).mana_upkeep?.amount} {(arcaneDome as any).mana_upkeep?.school} mana/turn.
|
||||
Also grants {getEffectValue(arcaneDome, 'corruption_resistance')}% corruption resistance.
|
||||
</TileSub>
|
||||
</InfoTile>
|
||||
)}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue