Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 18 additions & 23 deletions src/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function App() {
const isStatePage = selectedState && !isBillPage;

return (
<div style={{ minHeight: "100vh" }}>
<div className="app-shell" style={{ minHeight: "100vh" }}>
{/* Header */}
<header
className="header-accent"
Expand All @@ -119,9 +119,9 @@ function App() {
zIndex: 50,
}}
>
<div style={{ maxWidth: "1400px", margin: "0 auto", padding: `${spacing.xl} ${spacing["2xl"]}` }}>
<div style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
<div style={{ display: "flex", alignItems: "center", gap: spacing.lg }}>
<div className="app-header-inner" style={{ maxWidth: "1400px", margin: "0 auto", padding: `${spacing.xl} ${spacing["2xl"]}` }}>
<div className="app-header-row" style={{ display: "flex", alignItems: "center", justifyContent: "space-between" }}>
<div className="app-header-brand" style={{ display: "flex", alignItems: "center", gap: spacing.lg }}>
<a href="https://policyengine.org" target="_blank" rel="noopener noreferrer">
<img
src="/policyengine-favicon.svg"
Expand Down Expand Up @@ -156,7 +156,7 @@ function App() {
</header>

{/* Main Content */}
<main style={{ maxWidth: "1400px", margin: "0 auto", padding: `${spacing["2xl"]} ${spacing["2xl"]} ${spacing["4xl"]}` }}>
<main className="app-main" style={{ maxWidth: "1400px", margin: "0 auto", padding: `${spacing["2xl"]} ${spacing["2xl"]} ${spacing["4xl"]}` }}>

{/* === Bill Page === */}
{isBillPage && (
Expand All @@ -170,7 +170,6 @@ function App() {
<ReformAnalyzer
reformConfig={activeBill.reformConfig}
stateAbbr={selectedState}
billUrl={activeBill.url}
bill={activeBill}
/>
</div>
Expand All @@ -185,7 +184,6 @@ function App() {
/>
<StatePanel
stateAbbr={selectedState}
onNavigateHome={handleNavigateHome}
onBillSelect={(id) => handleBillSelect(selectedState, id)}
/>
</div>
Expand Down Expand Up @@ -218,19 +216,16 @@ function App() {
</p>
</div>

{/* Two-column layout: Map + sidebar */}
<div style={{
<div className="app-home-grid" style={{
display: "grid",
gridTemplateColumns: "minmax(0, 1fr) 340px",
gap: spacing.lg,
alignItems: "start",
marginBottom: spacing["2xl"],
}}>
{/* Left column: Map + chips + quick links */}
<div style={{ display: "flex", flexDirection: "column", gap: spacing.lg }}>
{/* Map */}
<div
className="animate-fade-in-up"
className="app-map-card animate-fade-in-up"
style={{
backgroundColor: colors.white,
borderRadius: spacing.radius["2xl"],
Expand All @@ -240,15 +235,14 @@ function App() {
transition: "box-shadow 0.3s ease",
}}
>
<div style={{ display: "flex", alignItems: "flex-start" }}>
<div className="app-map-layout" style={{ display: "flex", alignItems: "flex-start" }}>
<div style={{ flex: 1 }}>
<USMap
selectedState={selectedState}
onStateSelect={handleStateSelect}
/>
</div>
{/* Legend */}
<div style={{
<div className="app-map-legend" style={{
display: "flex",
flexDirection: "column",
gap: spacing.sm,
Expand All @@ -265,7 +259,6 @@ function App() {
</div>
</div>

{/* State chips by region */}
{activeStates.length > 0 && (
<div style={{
marginTop: spacing.lg,
Expand All @@ -289,8 +282,11 @@ function App() {
)}
</div>

{/* Quick Links */}
<div style={{
<div className="animate-fade-in-up app-recent-activity-mobile">
<RecentActivitySidebar onStateSelect={handleStateSelect} onBillSelect={handleBillSelect} />
</div>

<div className="app-quick-links" style={{
display: "grid",
gridTemplateColumns: "repeat(3, 1fr)",
gap: spacing.md,
Expand All @@ -313,8 +309,7 @@ function App() {
</div>
</div>

{/* Right column: Recent Activity */}
<div className="animate-fade-in-up" style={{ position: "sticky", top: "80px" }}>
<div className="animate-fade-in-up app-sidebar-sticky app-recent-activity-desktop" style={{ position: "sticky", top: "80px" }}>
<RecentActivitySidebar onStateSelect={handleStateSelect} onBillSelect={handleBillSelect} />
</div>
</div>
Expand All @@ -338,7 +333,7 @@ function App() {
height: "3px",
background: "linear-gradient(90deg, #2C7A7B 0%, #38B2AC 50%, #0EA5E9 100%)",
}} />
<div style={{
<div className="app-footer-inner" style={{
maxWidth: "1400px",
margin: "0 auto",
padding: `${spacing["2xl"]} ${spacing["2xl"]}`,
Expand All @@ -354,7 +349,7 @@ function App() {
}}>
© {new Date().getFullYear()} PolicyEngine. Open-source tax and benefit policy simulation.
</p>
<div style={{ display: "flex", gap: spacing.lg }}>
<div className="app-footer-links" style={{ display: "flex", gap: spacing.lg }}>
<FooterLink href="https://github.com/policyengine">GitHub</FooterLink>
<FooterLink href="https://policyengine.org">PolicyEngine.org</FooterLink>
</div>
Expand Down Expand Up @@ -429,7 +424,7 @@ function RegionChips({ states, onSelect }) {
.filter((r) => r.states.length > 0);

return (
<div style={{
<div className="region-chips-grid" style={{
display: "grid",
gridTemplateColumns: `repeat(${regions.length}, 1fr)`,
gap: spacing.lg,
Expand Down
2 changes: 1 addition & 1 deletion src/components/Breadcrumb.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const ChevronRight = () => (
export default function Breadcrumb({ stateAbbr, billLabel, onNavigateHome, onNavigateState }) {
const onBack = billLabel ? onNavigateState : onNavigateHome;
return (
<nav style={{
<nav className="breadcrumb-nav" style={{
display: "flex",
alignItems: "center",
gap: spacing.sm,
Expand Down
8 changes: 4 additions & 4 deletions src/components/StatePanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ function SectionHeader({ children }) {
);
}

const StatePanel = memo(({ stateAbbr, onNavigateHome, onBillSelect }) => {
const StatePanel = memo(({ stateAbbr, onBillSelect }) => {
const state = stateData[stateAbbr];
const { getBillsForState, getResearchForState } = useData();
const { bills: pipelineBills } = useProcessedBills(stateAbbr);
Expand Down Expand Up @@ -83,7 +83,7 @@ const StatePanel = memo(({ stateAbbr, onNavigateHome, onBillSelect }) => {
return (
<div className="animate-fade-in">
{/* Header */}
<div style={{
<div className="state-panel-header" style={{
padding: `${spacing.lg} ${spacing["2xl"]}`,
background: `linear-gradient(135deg, ${colors.primary[600]} 0%, ${colors.primary[700]} 100%)`,
borderRadius: `${spacing.radius["2xl"]} ${spacing.radius["2xl"]} 0 0`,
Expand Down Expand Up @@ -135,7 +135,7 @@ const StatePanel = memo(({ stateAbbr, onNavigateHome, onBillSelect }) => {
</div>

{/* Content */}
<div style={{
<div className="state-panel-content" style={{
padding: spacing["2xl"],
backgroundColor: colors.white,
borderRadius: `0 0 ${spacing.radius["2xl"]} ${spacing.radius["2xl"]}`,
Expand All @@ -147,7 +147,7 @@ const StatePanel = memo(({ stateAbbr, onNavigateHome, onBillSelect }) => {
{(bills.length > 0 || state.taxChanges?.length > 0) && (
<div style={{ marginBottom: spacing["2xl"] }}>
<SectionHeader>2026 Legislative Activity</SectionHeader>
<div style={{ display: "grid", gridTemplateColumns: bills.length > 3 ? "1fr 1fr" : "1fr", gap: spacing.sm }}>
<div className="state-panel-activity-grid" style={{ display: "grid", gridTemplateColumns: bills.length > 3 ? "1fr 1fr" : "1fr", gap: spacing.sm }}>
{state.taxChanges?.map((change, i) => (
<a
key={i}
Expand Down
4 changes: 3 additions & 1 deletion src/components/StateSearchCombobox.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ export default function StateSearchCombobox({ onSelect, statesWithBills }) {
const billCount = (abbr) => statesWithBills[abbr] || 0;

return (
<div ref={containerRef} style={{ position: "relative" }}>
<div ref={containerRef} className="state-search" style={{ position: "relative" }}>
<div
className="state-search-input-wrap"
style={{
display: "flex",
alignItems: "center",
Expand Down Expand Up @@ -169,6 +170,7 @@ export default function StateSearchCombobox({ onSelect, statesWithBills }) {
listStyle: "none",
zIndex: 100,
}}
className="state-search-listbox"
>
{filtered.length === 0 ? (
<li
Expand Down
2 changes: 2 additions & 0 deletions src/components/USMap.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,13 @@ const USMap = memo(({ selectedState, onStateSelect }) => {
return (
<div
ref={containerRef}
className="us-map-shell"
style={{ position: "relative", width: "100%" }}
onWheel={handleWheel}
>
<ComposableMap
projection="geoAlbersUsa"
className="us-map-svg"
style={{ width: "100%", height: "auto", maxHeight: "500px" }}
>
<ZoomableGroup
Expand Down
15 changes: 5 additions & 10 deletions src/components/reform/AggregateImpacts.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,6 @@ const formatCurrency = (value) => {
return `${sign}$${absValue.toFixed(0)}`;
};

const formatPercent = (value, decimals = 1) => {
if (value === null || value === undefined) return "N/A";
return `${(value * 100).toFixed(decimals)}%`;
};

const formatPctChange = (value, decimals = 1) => {
if (value === null || value === undefined) return "N/A";
const sign = value > 0 ? "+" : "";
Expand Down Expand Up @@ -83,7 +78,7 @@ export default function AggregateImpacts({ impacts, billTitle }) {
overflow: "hidden",
}}>
{/* Header */}
<div style={{
<div className="aggregate-impacts-header" style={{
padding: `${spacing.md} ${spacing.xl}`,
borderBottom: `1px solid ${colors.border.light}`,
backgroundColor: colors.background.secondary,
Expand All @@ -105,7 +100,7 @@ export default function AggregateImpacts({ impacts, billTitle }) {

{/* Year Tabs for multi-year reforms */}
{hasMultipleYears ? (
<div style={{
<div className="aggregate-year-tabs" style={{
display: "flex",
gap: spacing.xs,
}}>
Expand Down Expand Up @@ -146,11 +141,11 @@ export default function AggregateImpacts({ impacts, billTitle }) {
</div>

{/* Budgetary Impact */}
<div style={{
<div className="aggregate-budget-row" style={{
padding: spacing.xl,
borderBottom: `1px solid ${colors.border.light}`,
}}>
<div style={{
<div className="aggregate-budget-metric" style={{
display: "flex",
alignItems: "baseline",
gap: spacing.sm,
Expand Down Expand Up @@ -182,7 +177,7 @@ export default function AggregateImpacts({ impacts, billTitle }) {
</div>

{/* Poverty Metrics - Side by Side */}
<div style={{
<div className="aggregate-poverty-grid" style={{
display: "grid",
gridTemplateColumns: "1fr 1fr",
borderBottom: `1px solid ${colors.border.light}`,
Expand Down
2 changes: 1 addition & 1 deletion src/components/reform/AggregateStats.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export default function AggregateStats({ stats }) {
)}
</div>

<div style={{
<div className="aggregate-stats-grid" style={{
display: "grid",
gridTemplateColumns: "1fr 1fr 1fr",
gap: spacing.md,
Expand Down
15 changes: 8 additions & 7 deletions src/components/reform/ReformAnalyzer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ const TABS = [
{ id: "household", label: "Your Household", icon: UserIcon },
];

export default function ReformAnalyzer({ reformConfig, stateAbbr, billUrl, bill }) {
export default function ReformAnalyzer({ reformConfig, stateAbbr, bill }) {
const { compareReform, loading, error, apiVersion } = usePolicyEngineAPI();
const { getImpact } = useData();
const [activeTab, setActiveTab] = useState("overview");
Expand Down Expand Up @@ -166,7 +166,7 @@ export default function ReformAnalyzer({ reformConfig, stateAbbr, billUrl, bill
}}
>
{/* Header */}
<div style={{
<div className="reform-header" style={{
padding: `${spacing.lg} ${spacing["2xl"]}`,
borderBottom: `1px solid ${colors.border.light}`,
display: "flex",
Expand All @@ -187,7 +187,7 @@ export default function ReformAnalyzer({ reformConfig, stateAbbr, billUrl, bill
</div>

{/* Tabs */}
<div style={{
<div className="reform-tabs" style={{
display: "flex",
gap: spacing.xs,
padding: `0 ${spacing["2xl"]}`,
Expand All @@ -208,6 +208,7 @@ export default function ReformAnalyzer({ reformConfig, stateAbbr, billUrl, bill
setActiveTab(tab.id);
track("tab_switched", { tab_id: tab.id, reform_id: reformConfig.id, state_abbr: stateAbbr });
}}
className="reform-tab"
style={{
display: "flex",
alignItems: "center",
Expand All @@ -234,7 +235,7 @@ export default function ReformAnalyzer({ reformConfig, stateAbbr, billUrl, bill
</div>

{/* Content */}
<div style={{
<div className="reform-content" style={{
padding: spacing["2xl"],
...(activeTab === "districts" ? { display: "flex", flexDirection: "column" } : {}),
}}>
Expand All @@ -250,7 +251,7 @@ export default function ReformAnalyzer({ reformConfig, stateAbbr, billUrl, bill

{/* Districts Tab */}
{activeTab === "districts" && (
<div style={{ height: "70vh", display: "flex", flexDirection: "column" }}>
<div className="reform-districts-panel" style={{ height: "70vh", display: "flex", flexDirection: "column" }}>
<DistrictMap
stateAbbr={stateAbbr}
reformId={reformConfig.id}
Expand All @@ -261,7 +262,7 @@ export default function ReformAnalyzer({ reformConfig, stateAbbr, billUrl, bill

{/* Household Tab */}
{activeTab === "household" && (
<div style={{
<div className="reform-household-grid" style={{
display: "grid",
gridTemplateColumns: "1fr 1fr",
gap: spacing["3xl"],
Expand Down Expand Up @@ -367,7 +368,7 @@ export default function ReformAnalyzer({ reformConfig, stateAbbr, billUrl, bill
</div>

{/* Footer */}
<div style={{
<div className="reform-footer" style={{
padding: `${spacing.sm} ${spacing["2xl"]}`,
borderTop: `1px solid ${colors.border.light}`,
backgroundColor: colors.background.secondary,
Expand Down
2 changes: 1 addition & 1 deletion src/components/reform/ResultsDisplay.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ export default function ResultsDisplay({ baseline, reform, error }) {
</div>

{/* Breakdown */}
<div style={{
<div className="results-breakdown-grid" style={{
display: "grid",
gridTemplateColumns: "1fr 1fr 1fr",
gap: spacing.md,
Expand Down
Loading