From a8f17cc6c7407fecc0e2764b5b63878b0d3ca55a Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Thu, 21 Aug 2025 20:10:46 -0600 Subject: [PATCH 01/27] Fix Storybook fonts --- .storybook/main.js | 4 ---- .storybook/preview.js | 22 ++++++++++++++++++++++ .storybook/preview.local.js | 22 ++++++++++++++++++++++ 3 files changed, 44 insertions(+), 4 deletions(-) diff --git a/.storybook/main.js b/.storybook/main.js index 7afbb5d..6e3993d 100644 --- a/.storybook/main.js +++ b/.storybook/main.js @@ -16,11 +16,7 @@ const config = { options: {}, }, staticDirs: ["../public"], - managerHead: (head) => `${head}`, - previewHead: (head) => `${head}`, async viteFinal(cfg) { - // IMPORTANT: Set base path for GitHub Pages sub-path hosting - cfg.base = "/communityrulestorybook/"; // Ensure esbuild treats .js as JSX during dep pre-bundling cfg.optimizeDeps ??= {}; cfg.optimizeDeps.esbuildOptions ??= {}; diff --git a/.storybook/preview.js b/.storybook/preview.js index 1fd25df..59394fb 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,5 +1,20 @@ import "../app/globals.css"; +// Import Google Fonts for Storybook +import { Inter, Bricolage_Grotesque } from "next/font/google"; + +const inter = Inter({ + subsets: ["latin"], + weight: ["400", "500"], + variable: "--font-inter", +}); + +const bricolageGrotesque = Bricolage_Grotesque({ + subsets: ["latin"], + weight: ["400", "500"], + variable: "--font-bricolage-grotesque", +}); + /** @type { import('@storybook/react').Preview } */ const preview = { parameters: { @@ -11,6 +26,13 @@ const preview = { }, }, }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], }; export default preview; diff --git a/.storybook/preview.local.js b/.storybook/preview.local.js index 1fd25df..59394fb 100644 --- a/.storybook/preview.local.js +++ b/.storybook/preview.local.js @@ -1,5 +1,20 @@ import "../app/globals.css"; +// Import Google Fonts for Storybook +import { Inter, Bricolage_Grotesque } from "next/font/google"; + +const inter = Inter({ + subsets: ["latin"], + weight: ["400", "500"], + variable: "--font-inter", +}); + +const bricolageGrotesque = Bricolage_Grotesque({ + subsets: ["latin"], + weight: ["400", "500"], + variable: "--font-bricolage-grotesque", +}); + /** @type { import('@storybook/react').Preview } */ const preview = { parameters: { @@ -11,6 +26,13 @@ const preview = { }, }, }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], }; export default preview; From a9557ddedf1e392cf77a156c6d96f8b89a1ea35e Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Fri, 22 Aug 2025 13:57:56 -0600 Subject: [PATCH 02/27] Rule Stack Start --- app/components/RuleCard.js | 40 +++++++++++++++ app/components/RuleStack.js | 75 +++++++++++++++++++++++++++++ app/components/SectionHeader.js | 18 +++++-- app/globals.css | 5 ++ app/layout.js | 14 ++++-- app/page.js | 2 + public/assets/Icon_Consensus.svg | 10 ++++ public/assets/Icon_ElectedBoard.svg | 9 ++++ public/assets/Icon_Petition.svg | 13 +++++ public/assets/Icon_Sociocracy.svg | 3 ++ 10 files changed, 183 insertions(+), 6 deletions(-) create mode 100644 app/components/RuleCard.js create mode 100644 app/components/RuleStack.js create mode 100644 public/assets/Icon_Consensus.svg create mode 100644 public/assets/Icon_ElectedBoard.svg create mode 100644 public/assets/Icon_Petition.svg create mode 100644 public/assets/Icon_Sociocracy.svg diff --git a/app/components/RuleCard.js b/app/components/RuleCard.js new file mode 100644 index 0000000..aaa94f4 --- /dev/null +++ b/app/components/RuleCard.js @@ -0,0 +1,40 @@ +"use client"; + +const RuleCard = ({ + title, + description, + icon, + backgroundColor = "bg-[var(--color-community-teal-100)]", + className = "", +}) => { + return ( +
+ {/* Header Container */} +
+ {/* Icon Container */} + {icon && ( +
+ {icon} +
+ )} + {/* Title Container */} + {title && ( +
+

+ {title} +

+
+ )} +
+ {description && ( +

+ {description} +

+ )} +
+ ); +}; + +export default RuleCard; diff --git a/app/components/RuleStack.js b/app/components/RuleStack.js new file mode 100644 index 0000000..a6d67d6 --- /dev/null +++ b/app/components/RuleStack.js @@ -0,0 +1,75 @@ +"use client"; + +import SectionHeader from "./SectionHeader"; +import RuleCard from "./RuleCard"; +import Image from "next/image"; + +const RuleStack = ({ children, className = "" }) => { + return ( +
+ +
+ + } + backgroundColor="bg-[var(--color-community-kiwi-200)]" + /> + + } + backgroundColor="bg-[var(--color-community-red-200)]" + /> + + } + backgroundColor="bg-[var(--color-surface-default-brand-accent)]" + /> + + } + backgroundColor="bg-[var(--color-community-blue-300)]" + /> +
+
+ ); +}; + +export default RuleStack; diff --git a/app/components/SectionHeader.js b/app/components/SectionHeader.js index e6dfe6c..0009f7d 100644 --- a/app/components/SectionHeader.js +++ b/app/components/SectionHeader.js @@ -1,11 +1,17 @@ "use client"; -const SectionHeader = ({ title, subtitle, titleLg }) => { +const SectionHeader = ({ title, subtitle, titleLg, variant = "default" }) => { return (
{/* Title Container - Left side (lg breakpoint) */}
-

+

{title} {titleLg || title}

@@ -13,7 +19,13 @@ const SectionHeader = ({ title, subtitle, titleLg }) => { {/* Subtitle Container */}
-

+

{subtitle}

diff --git a/app/globals.css b/app/globals.css index bdc4871..a8c908b 100644 --- a/app/globals.css +++ b/app/globals.css @@ -12,6 +12,11 @@ -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; } +.font-space-grotesk { + font-family: var(--font-space-grotesk), ui-sans-serif, system-ui, + -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial; +} + /* Set default body text face */ html, body { diff --git a/app/layout.js b/app/layout.js index 18e97dc..34589a7 100644 --- a/app/layout.js +++ b/app/layout.js @@ -1,4 +1,4 @@ -import { Inter, Bricolage_Grotesque } from "next/font/google"; +import { Inter, Bricolage_Grotesque, Space_Grotesk } from "next/font/google"; import "./globals.css"; import HomeHeader from "./components/HomeHeader"; import Footer from "./components/Footer"; @@ -11,14 +11,22 @@ const inter = Inter({ const bricolageGrotesque = Bricolage_Grotesque({ subsets: ["latin"], - weight: ["400", "500"], + weight: ["400", "500", "700"], variable: "--font-bricolage-grotesque", }); +const spaceGrotesk = Space_Grotesk({ + subsets: ["latin"], + weight: ["400", "500", "700"], + variable: "--font-space-grotesk", +}); + export default function RootLayout({ children }) { return ( - +
{children}
diff --git a/app/page.js b/app/page.js index 5e07816..e6a48ad 100644 --- a/app/page.js +++ b/app/page.js @@ -1,6 +1,7 @@ import NumberedCards from "./components/NumberedCards"; import HeroBanner from "./components/HeroBanner"; import LogoWall from "./components/LogoWall"; +import RuleStack from "./components/RuleStack"; export default function Page() { const heroBannerData = { @@ -39,6 +40,7 @@ export default function Page() { +
); } diff --git a/public/assets/Icon_Consensus.svg b/public/assets/Icon_Consensus.svg new file mode 100644 index 0000000..0bcac3e --- /dev/null +++ b/public/assets/Icon_Consensus.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/assets/Icon_ElectedBoard.svg b/public/assets/Icon_ElectedBoard.svg new file mode 100644 index 0000000..1e4405c --- /dev/null +++ b/public/assets/Icon_ElectedBoard.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/public/assets/Icon_Petition.svg b/public/assets/Icon_Petition.svg new file mode 100644 index 0000000..ba2d443 --- /dev/null +++ b/public/assets/Icon_Petition.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/public/assets/Icon_Sociocracy.svg b/public/assets/Icon_Sociocracy.svg new file mode 100644 index 0000000..85fc35f --- /dev/null +++ b/public/assets/Icon_Sociocracy.svg @@ -0,0 +1,3 @@ + + + From ff14e39f2167e53ef4a9683433b21fc885081b1a Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Fri, 22 Aug 2025 16:27:34 -0600 Subject: [PATCH 03/27] Update Tailwind CSS --- app/components/Avatar.js | 6 +- app/components/AvatarContainer.js | 4 +- app/components/HeaderTab.js | 2 +- app/components/HeroBanner.js | 2 +- app/components/NavigationItem.js | 2 +- app/components/NumberedCards.js | 2 +- app/components/RuleStack.js | 8 +- app/components/SectionHeader.js | 12 +- app/components/SectionNumber.js | 4 +- app/tailwind.css | 1152 ++++++++++++++++++++++++----- 10 files changed, 990 insertions(+), 204 deletions(-) diff --git a/app/components/Avatar.js b/app/components/Avatar.js index 2abbefe..fbb366a 100644 --- a/app/components/Avatar.js +++ b/app/components/Avatar.js @@ -6,10 +6,10 @@ export default function Avatar({ ...props }) { const sizeStyles = { - small: "w-[16px] h-[16px]", + small: "w-[var(--spacing-scale-016)] h-[var(--spacing-scale-016)]", medium: "w-[18px] h-[18px]", - large: "w-[24px] h-[24px]", - xlarge: "w-[32px] h-[32px]", + large: "w-[var(--spacing-scale-024)] h-[var(--spacing-scale-024)]", + xlarge: "w-[var(--spacing-scale-032)] h-[var(--spacing-scale-032)]", }; const baseStyles = `rounded-[var(--radius-measures-radius-full)] object-cover ${sizeStyles[size]} ${className}`; diff --git a/app/components/AvatarContainer.js b/app/components/AvatarContainer.js index 55ecfff..128775d 100644 --- a/app/components/AvatarContainer.js +++ b/app/components/AvatarContainer.js @@ -5,9 +5,9 @@ export default function AvatarContainer({ ...props }) { const sizeStyles = { - small: "flex -space-x-2", + small: "flex -space-x-[var(--spacing-scale-008)]", medium: "flex -space-x-[9px]", - large: "flex -space-x-[10px]", + large: "flex -space-x-[var(--spacing-scale-010)]", xlarge: "flex -space-x-[13px]", }; diff --git a/app/components/HeaderTab.js b/app/components/HeaderTab.js index 1a1f7c3..6e1e18a 100644 --- a/app/components/HeaderTab.js +++ b/app/components/HeaderTab.js @@ -10,7 +10,7 @@ export default function HeaderTab({ return (
{children} diff --git a/app/components/HeroBanner.js b/app/components/HeroBanner.js index 419f16c..e68f3c7 100644 --- a/app/components/HeroBanner.js +++ b/app/components/HeroBanner.js @@ -8,7 +8,7 @@ const HeroBanner = ({ title, subtitle, description, ctaText, ctaHref }) => {
{/* Frame container for content */} -
+
{/* DECORATIONS (behind content) */} { dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaData) }} />
-
+
{/* Section Header */}
diff --git a/app/components/RuleStack.js b/app/components/RuleStack.js index a6d67d6..42d3ce9 100644 --- a/app/components/RuleStack.js +++ b/app/components/RuleStack.js @@ -26,7 +26,7 @@ const RuleStack = ({ children, className = "" }) => { height={40} /> } - backgroundColor="bg-[var(--color-community-kiwi-200)]" + backgroundColor="bg-[var(--color-surface-default-brand-lime)]" /> { height={40} /> } - backgroundColor="bg-[var(--color-community-red-200)]" + backgroundColor="bg-[var(--color-surface-default-brand-rust)]" /> { height={40} /> } - backgroundColor="bg-[var(--color-surface-default-brand-accent)]" + backgroundColor="bg-[var(--color-surface-default-brand-red)]" /> { height={40} /> } - backgroundColor="bg-[var(--color-community-blue-300)]" + backgroundColor="bg-[var(--color-surface-default-brand-teal)]" />
diff --git a/app/components/SectionHeader.js b/app/components/SectionHeader.js index 0009f7d..f32d2ee 100644 --- a/app/components/SectionHeader.js +++ b/app/components/SectionHeader.js @@ -4,12 +4,12 @@ const SectionHeader = ({ title, subtitle, titleLg, variant = "default" }) => { return (
{/* Title Container - Left side (lg breakpoint) */} -
+

{title} @@ -18,12 +18,12 @@ const SectionHeader = ({ title, subtitle, titleLg, variant = "default" }) => {

{/* Subtitle Container */} -
+

{subtitle} diff --git a/app/components/SectionNumber.js b/app/components/SectionNumber.js index 14d5f4d..cee6814 100644 --- a/app/components/SectionNumber.js +++ b/app/components/SectionNumber.js @@ -15,14 +15,14 @@ const SectionNumber = ({ number }) => { }; return ( -

+
{`Section
- + {number}
diff --git a/app/tailwind.css b/app/tailwind.css index 6cb9b11..2942914 100644 --- a/app/tailwind.css +++ b/app/tailwind.css @@ -1,8 +1,3 @@ -/** - * This file was generated by Supernova.io and should not be changed manually. - * To modify the format or content of this file, please contact your design system team. - */ - @import "tailwindcss"; /* Make sure Tailwind scans stories and .storybook files */ @@ -18,7 +13,7 @@ --breakpoint-lg: 1024px; --breakpoint-xl: 1440px; - /* Reset default Tailwind configuration */ + /* Reset Tailwind color defaults to avoid collisions */ --color-*: initial; /* Dimension */ @@ -44,8 +39,10 @@ --spacing-scale-076: 76px; --spacing-scale-096: 96px; --spacing-scale-120: 120px; + --spacing-scale-160: 160px; --spacing-scale-260: 260px; --spacing-scale-290: 290px; + --spacing-measures-sizing-008: var(--spacing-scale-008); --spacing-measures-sizing-010: var(--spacing-scale-010); --spacing-measures-sizing-012: var(--spacing-scale-012); @@ -60,11 +57,14 @@ --spacing-measures-sizing-064: var(--spacing-scale-064); --spacing-measures-sizing-076: var(--spacing-scale-076); --spacing-measures-sizing-096: var(--spacing-scale-096); - --spacing-measures-spacing-000: var(--spacing-scale-000); --spacing-measures-sizing-120: var(--spacing-scale-120); + + /* Spacing aliases */ + --spacing-measures-spacing-000: var(--spacing-scale-000); --spacing-measures-spacing-001: var(--spacing-scale-001); --spacing-measures-spacing-002: var(--spacing-scale-002); --spacing-measures-spacing-004: var(--spacing-scale-004); + --spacing-measures-spacing-006: var(--spacing-scale-006); --spacing-measures-spacing-008: var(--spacing-scale-008); --spacing-measures-spacing-010: var(--spacing-scale-010); --spacing-measures-spacing-012: var(--spacing-scale-012); @@ -80,196 +80,982 @@ --spacing-measures-spacing-076: var(--spacing-scale-076); --spacing-measures-spacing-096: var(--spacing-scale-096); --spacing-measures-spacing-120: var(--spacing-scale-120); + --spacing-measures-spacing-160: var(--spacing-scale-160); + --spacing-measures-spacing-260: var(--spacing-scale-260); - /* BorderRadius */ + /* Border radius */ --radius-measures-radius-none: var(--spacing-scale-000); - --radius-measures-radius-small: var(--spacing-scale-002); - --radius-measures-radius-medium: var(--spacing-scale-004); - --radius-measures-radius-large: var(--spacing-scale-008); - --radius-measures-radius-xlarge: var(--spacing-scale-012); - --radius-measures-radius-full: var(--spacing-scale-120); + --radius-measures-radius-xsmall: var(--spacing-scale-006); + --radius-measures-radius-small: var(--spacing-scale-012); + --radius-measures-radius-medium: var(--spacing-scale-016); + --radius-measures-radius-large: var(--spacing-scale-024); + --radius-measures-radius-xlarge: var(--spacing-scale-032); + --radius-measures-radius-full: 9999px; - /* BorderWidth */ - --border-measures-stroke-large: var(--spacing-scale-003); - --border-measures-stroke-medium: var(--spacing-scale-002); + /* Border widths */ --border-measures-stroke-small: var(--spacing-scale-001); + --border-measures-stroke-medium: var(--spacing-scale-002); + --border-measures-stroke-large: var(--spacing-scale-003); - /* Color */ - --color-community-yellow-100: oklch(98.48% 0.055 105.21); - --color-community-yellow-200: oklch(94.76% 0.083 103.43); - --color-community-yellow-300: oklch(90.22% 0.095 102.92); - --color-community-yellow-400: oklch(84.34% 0.097 101.09); - --color-community-yellow-500: oklch(76.71% 0.094 100.01); - --color-community-yellow-600: oklch(66.85% 0.083 99.46); - --color-community-yellow-700: oklch(55.29% 0.069 98.1); - --color-community-yellow-800: oklch(42.89% 0.054 98.59); - --color-community-yellow-900: oklch(30.32% 0.036 99.23); - --color-community-teal-050: oklch(95.63% 0.022 13.86); - --color-community-orange-050: oklch(98.55% 0.017 201.66); - --color-community-mauve-050: oklch(98.1% 0.009 100.14); - --color-community-orange-100: oklch(95.43% 0.06 198.83); - --color-community-orange-200: oklch(83.58% 0.121 198.44); - --color-community-orange-300: oklch(69.29% 0.124 217.83); - --color-community-orange-400: oklch(50.04% 0.102 233.41); - --color-community-orange-500: oklch(39.59% 0.091 242.29); - --color-community-orange-600: oklch(31.94% 0.096 255.01); - --color-community-orange-700: oklch(20.28% 0.053 252.69); - --color-community-blue-050: oklch(39.46% 0.149 259.87); - --color-community-kiwi-050: oklch(97.77% 0.031 127.13); - --color-community-pink-050: oklch(95.93% 0.032 321.01); - --color-community-pink-100: oklch(90.78% 0.072 319.41); - --color-community-pink-200: oklch(85.82% 0.091 318.38); - --color-community-pink-300: oklch(81.18% 0.096 318.17); - --color-community-pink-400: oklch(75.77% 0.097 317.51); - --color-community-pink-500: oklch(68.84% 0.092 316.79); - --color-community-pink-600: oklch(60.22% 0.08 316.45); - --color-community-pink-700: oklch(50.08% 0.065 315.63); - --color-community-pink-800: oklch(38.98% 0.049 315.23); - --color-community-pink-900: oklch(27.83% 0.03 314.26); - --color-community-red-050: oklch(96.51% 0.014 22.47); - --color-yellow-opacity-000: oklch(30.32% 0.036 99.23 / 0%); - --color-yellow-opacity-001: oklch(30.32% 0.036 99.23 / 1%); - --color-yellow-opacity-050: oklch(30.32% 0.036 99.23 / 5%); - --color-yellow-opacity-100: oklch(30.32% 0.036 99.23 / 10%); - --color-yellow-opacity-200: oklch(42.89% 0.054 98.59 / 20%); - --color-yellow-opacity-300: oklch(55.29% 0.069 98.1 / 30%); - --color-yellow-opacity-400: oklch(66.85% 0.083 99.46 / 40%); - --color-yellow-opacity-500: oklch(76.71% 0.094 100.01 / 50%); - --color-yellow-opacity-600: oklch(84.34% 0.097 101.09 / 60%); - --color-yellow-opacity-700: oklch(90.22% 0.095 102.92 / 70%); - --color-yellow-opacity-800: oklch(94.76% 0.083 103.43 / 80%); - --color-yellow-opacity-900: oklch(98.48% 0.055 105.21 / 90%); - --color-opacity-000: oklch(97.31% 0 263.28 / 0%); - --color-opacity-001: oklch(97.31% 0 263.28 / 1%); - --color-opacity-050: oklch(97.31% 0 263.28 / 50%); - --color-opacity-100: oklch(94.91% 0 263.28 / 50%); - --color-opacity-200: oklch(91.28% 0 263.28 / 50%); - --color-opacity-300: oklch(84.21% 0 263.28 / 50%); - --color-opacity-400: oklch(75.4% 0 263.28 / 50%); - --color-opacity-500: oklch(56.24% 0 263.28 / 50%); - --color-opacity-600: oklch(44.59% 0 263.28 / 50%); - --color-opacity-700: oklch(32.11% 0 263.28 / 50%); - --color-opacity-800: oklch(23.93% 0 263.28 / 50%); - --color-opacity-900: oklch(19.13% 0 263.28 / 50%); - --color-gray-000: oklch(100% 0 263.28); - --color-gray-050: oklch(97.31% 0 263.28); - --color-gray-100: oklch(92.19% 0 263.28); - --color-gray-200: oklch(86.38% 0 263.28); - --color-gray-300: oklch(76.99% 0 263.28); - --color-gray-400: oklch(65% 0 263.28); - --color-gray-500: oklch(51.03% 0 263.28); - --color-gray-600: oklch(39.42% 0 263.28); - --color-gray-700: oklch(29.72% 0 263.28); - --color-gray-800: oklch(23.93% 0 263.28); - --color-gray-900: oklch(19.13% 0 263.28); - --color-gray-1000: oklch(0% 0 0); - --color-community-blue-100: oklch(94.43% 0.038 211.19); - --color-community-blue-200: oklch(91.44% 0.048 211.24); - --color-community-blue-300: oklch(87.85% 0.052 210.11); - --color-community-blue-400: oklch(82.74% 0.054 206.72); - --color-community-blue-500: oklch(75.92% 0.052 204.06); - --color-community-blue-600: oklch(66.92% 0.047 201.57); - --color-community-blue-700: oklch(55.72% 0.04 200.59); - --color-community-blue-800: oklch(43.34% 0.03 199.27); - --color-community-blue-900: oklch(30.78% 0.02 196.24); - --color-community-red-100: oklch(86.1% 0.051 359.55); - --color-community-red-200: oklch(82% 0.065 0.21); - --color-community-red-300: oklch(77.79% 0.072 359.58); - --color-community-red-400: oklch(73.06% 0.073 359.79); - --color-community-red-500: oklch(66.82% 0.07 359.71); - --color-community-red-600: oklch(58.65% 0.062 357.88); - --color-community-red-700: oklch(49.14% 0.05 359.07); - --color-community-red-800: oklch(38.48% 0.039 356.54); - --color-community-red-900: oklch(28.01% 0.024 356.91); - --color-community-orange-800: oklch(40.58% 0.027 46.54); - --color-community-orange-900: oklch(29.05% 0.017 48.05); - --color-community-mauve-100: oklch(88.23% 0.059 282.99); - --color-community-mauve-200: oklch(82.9% 0.074 281.26); - --color-community-mauve-300: oklch(78.02% 0.08 281.18); - --color-community-mauve-400: oklch(72.83% 0.08 280.17); - --color-community-mauve-500: oklch(66.39% 0.075 278.85); - --color-community-mauve-600: oklch(58.34% 0.063 277.78); - --color-community-mauve-700: oklch(48.68% 0.052 277.4); - --color-community-mauve-800: oklch(38.09% 0.038 276.43); - --color-community-mauve-900: oklch(27.24% 0.024 277.83); - --color-green0: oklch(98.15% 0.028 155.49); - --color-community-teal-100: oklch(96.1% 0.059 157.85); - --color-community-teal-200: oklch(92.78% 0.075 157.69); - --color-community-teal-300: oklch(88.65% 0.079 158.06); - --color-community-teal-400: oklch(83.47% 0.079 158.61); - --color-community-teal-500: oklch(76.31% 0.074 159.02); - --color-community-teal-600: oklch(66.77% 0.064 159.89); - --color-community-teal-700: oklch(55.57% 0.052 160.52); - --color-community-teal-800: oklch(43.12% 0.039 160.72); - --color-community-teal-900: oklch(30.48% 0.025 161.27); - --color-community-kiwi-100: oklch(92.3% 0.055 122.16); - --color-community-kiwi-200: oklch(89.94% 0.07 122.82); - --color-community-kiwi-300: oklch(86.7% 0.077 122.51); - --color-community-kiwi-400: oklch(81.99% 0.078 123.36); - --color-community-kiwi-500: oklch(75.31% 0.074 122.9); - --color-community-kiwi-600: oklch(66.25% 0.066 123.19); - --color-community-kiwi-700: oklch(55.28% 0.055 123.2); - --color-community-kiwi-800: oklch(43.14% 0.041 122.55); - --color-community-kiwi-900: oklch(31.14% 0.027 122.95); - --color-content-default-utility-positive: oklch(55.09% 0.151 143.2); - --color-content-default-utility-negative: oklch(58.87% 0.184 29.83); - --color-content-default-utility-info: oklch(55.14% 0.217 260.1); - --color-content-inverse-utility-positive: oklch(70.5% 0.146 138.3); - --color-content-inverse-utility-warning: oklch(79.77% 0.155 89.66); - --color-content-inverse-utility-negative: oklch(69.63% 0.149 28.39); - --color-content-inverse-utility-info: oklch(61.97% 0.194 258.88); - --color-surface-default-utility-info: oklch(55.14% 0.217 260.1); - --color-surface-default-utility-negative: oklch(58.87% 0.184 29.83); - --color-surface-default-utility-warning: oklch(57.3% 0.12 74.7); - --color-surface-default-utility-positive: oklch(55.09% 0.151 143.2); - --color-surface-default-brand-accent: oklch(79.17% 0.121 16.33); - --color-surface-inverse-utility-info: oklch(61.97% 0.194 258.88); - --color-surface-inverse-utility-negative: oklch(69.63% 0.149 28.39); - --color-surface-inverse-utility-warning: oklch(79.77% 0.155 89.66); - --color-surface-inverse-utility-positive: oklch(70.5% 0.146 138.3); - --border-color-default-utility-info: oklch(61.97% 0.194 258.88); - --border-color-default-utility-negative: oklch(69.63% 0.149 28.39); - --border-color-default-utility-warning: oklch(79.77% 0.155 89.66); - --border-color-default-utility-positive: oklch(70.5% 0.146 138.3); - --border-color-inverse-brandaccent: oklch(62.78% 0.234 25.05); - --color-content-default-utility-warning: var(--color-community-yellow-500); + /* Compatibility aliases */ + --measures-radius-none: var(--radius-measures-radius-none); + --measures-radius-xsmall: var(--radius-measures-radius-xsmall); + --measures-radius-small: var(--radius-measures-radius-small); + --measures-radius-medium: var(--radius-measures-radius-medium); + --measures-radius-large: var(--radius-measures-radius-large); + --measures-radius-xlarge: var(--radius-measures-radius-xlarge); + --measures-radius-full: var(--radius-measures-radius-full); + --measures-stroke-small: var(--border-measures-stroke-small); + --measures-stroke-medium: var(--border-measures-stroke-medium); + --measures-stroke-large: var(--border-measures-stroke-large); + --measures-sizing-008: var(--spacing-measures-sizing-008); + --measures-sizing-010: var(--spacing-measures-sizing-010); + --measures-sizing-012: var(--spacing-measures-sizing-012); + --measures-sizing-016: var(--spacing-measures-sizing-016); + --measures-sizing-020: var(--spacing-measures-sizing-020); + --measures-sizing-024: var(--spacing-measures-sizing-024); + --measures-sizing-032: var(--spacing-measures-sizing-032); + --measures-sizing-040: var(--spacing-measures-sizing-040); + --measures-sizing-048: var(--spacing-measures-sizing-048); + --measures-sizing-056: var(--spacing-measures-sizing-056); + --measures-sizing-060: var(--spacing-measures-sizing-060); + --measures-sizing-064: var(--spacing-measures-sizing-064); + --measures-sizing-076: var(--spacing-measures-sizing-076); + --measures-sizing-096: var(--spacing-measures-sizing-096); + --measures-sizing-120: var(--spacing-measures-sizing-120); + --measures-spacing-000: var(--spacing-measures-spacing-000); + --measures-spacing-001: var(--spacing-measures-spacing-001); + --measures-spacing-002: var(--spacing-measures-spacing-002); + --measures-spacing-004: var(--spacing-measures-spacing-004); + --measures-spacing-006: var(--spacing-measures-spacing-006); + --measures-spacing-008: var(--spacing-measures-spacing-008); + --measures-spacing-010: var(--spacing-measures-spacing-010); + --measures-spacing-012: var(--spacing-measures-spacing-012); + --measures-spacing-016: var(--spacing-measures-spacing-016); + --measures-spacing-020: var(--spacing-measures-spacing-020); + --measures-spacing-024: var(--spacing-measures-spacing-024); + --measures-spacing-032: var(--spacing-measures-spacing-032); + --measures-spacing-040: var(--spacing-measures-spacing-040); + --measures-spacing-048: var(--spacing-measures-spacing-048); + --measures-spacing-056: var(--spacing-measures-spacing-056); + --measures-spacing-060: var(--spacing-measures-spacing-060); + --measures-spacing-064: var(--spacing-measures-spacing-064); + --measures-spacing-076: var(--spacing-measures-spacing-076); + --measures-spacing-096: var(--spacing-measures-spacing-096); + --measures-spacing-120: var(--spacing-measures-spacing-120); + --measures-spacing-160: var(--spacing-measures-spacing-160); + --measures-spacing-260: var(--spacing-measures-spacing-260); + + /* Grays & alpha */ + --color-gray-000: #ffffff; + --color-gray-050: #f6f6f6; + --color-gray-100: #e5e5e5; + --color-gray-200: #d2d2d2; + --color-gray-300: #b4b4b4; + --color-gray-400: #8f8f8f; + --color-gray-500: #666666; + --color-gray-600: #464646; + --color-gray-700: #2d2d2d; + --color-gray-800: #1f1f1f; + --color-gray-900: #141414; + --color-gray-1000: #000000; + + --color-opacity-000: #00000000; + --color-opacity-001: #00000003; + --color-opacity-050: #0000000d; + --color-opacity-100: #0000001a; + --color-opacity-200: #00000033; + --color-opacity-300: #0000004d; + --color-opacity-400: #00000066; + --color-opacity-500: #00000080; + --color-opacity-600: #00000099; + --color-opacity-700: #000000b2; + --color-opacity-800: #000000cc; + --color-opacity-900: #000000e5; + + /* Kiwi */ + --color-kiwi-kiwi0: #ebfff2; + --color-kiwi-kiwi50: #c9fedf; + --color-kiwi-kiwi100: #a8fdcd; + --color-kiwi-kiwi150: #8cf9bd; + --color-kiwi-kiwi200: #6ff6ae; + --color-kiwi-kiwi300: #45ea97; + --color-kiwi-kiwi400: #29d984; + --color-kiwi-kiwi500: #16c472; + --color-kiwi-kiwi600: #0ba960; + --color-kiwi-kiwi700: #058c4e; + --color-kiwi-kiwi800: #016c3c; + --color-kiwi-kiwi900: #004d2b; + --color-kiwi-kiwi1000: #00331c; + + /* Lavender */ + --color-lavender-lavender0: #f0ebff; + --color-lavender-lavender50: #e8defe; + --color-lavender-lavender100: #e0d1fd; + --color-lavender-lavender150: #d7c3f9; + --color-lavender-lavender200: #ceb5f6; + --color-lavender-lavender300: #bb97ea; + --color-lavender-lavender400: #a578d9; + --color-lavender-lavender500: #8d5ac4; + --color-lavender-lavender600: #743ea9; + --color-lavender-lavender700: #5a278c; + --color-lavender-lavender800: #41146c; + --color-lavender-lavender900: #2b074d; + --color-lavender-lavender1000: #1a0033; + + /* Lime */ + --color-lime-lime0: #fbffeb; + --color-lime-lime50: #f2fec9; + --color-lime-lime100: #e7fda8; + --color-lime-lime150: #daf98c; + --color-lime-lime200: #ccf66f; + --color-lime-lime300: #b1ea45; + --color-lime-lime400: #98d929; + --color-lime-lime500: #80c416; + --color-lime-lime600: #6aa90b; + --color-lime-lime700: #548c05; + --color-lime-lime800: #406c01; + --color-lime-lime900: #2d4d00; + --color-lime-lime1000: #1e3300; + + /* Magenta */ + --color-magenta-magenta0: #ffebf0; + --color-magenta-magenta50: #fedee7; + --color-magenta-magenta100: #fdd1dd; + --color-magenta-magenta150: #f9c3d2; + --color-magenta-magenta200: #f6b5c7; + --color-magenta-magenta300: #ea97ad; + --color-magenta-magenta400: #d97892; + --color-magenta-magenta500: #c45a76; + --color-magenta-magenta600: #a93e5b; + --color-magenta-magenta700: #8c2742; + --color-magenta-magenta800: #6c142b; + --color-magenta-magenta900: #4d071a; + --color-magenta-magenta1000: #33000e; + + /* Red */ + --color-red-red0: #ffebf1; + --color-red-red50: #fec9d6; + --color-red-red100: #fda8b7; + --color-red-red150: #f98c98; + --color-red-red200: #f66f78; + --color-red-red300: #ea4845; + --color-red-red400: #d93529; + --color-red-red500: #c42916; + --color-red-red600: #a9200b; + --color-red-red700: #8c1905; + --color-red-red800: #6c1301; + --color-red-red900: #4d0d00; + --color-red-red1000: #330800; + + /* Royal Blue */ + --color-royal-blue-royal-blue0: #ebecff; + --color-royal-blue-royal-blue50: #c9cdfe; + --color-royal-blue-royal-blue100: #a8adfd; + --color-royal-blue-royal-blue150: #8c91f9; + --color-royal-blue-royal-blue200: #6f74f6; + --color-royal-blue-royal-blue300: #4548ea; + --color-royal-blue-royal-blue400: #2b29d9; + --color-royal-blue-royal-blue500: #1c16c4; + --color-royal-blue-royal-blue600: #140ba9; + --color-royal-blue-royal-blue700: #0f058c; + --color-royal-blue-royal-blue800: #0c016c; + --color-royal-blue-royal-blue900: #0a004d; + --color-royal-blue-royal-blue1000: #080033; + + /* Rust */ + --color-rust-rust0: #ffedeb; + --color-rust-rust50: #fed8d4; + --color-rust-rust100: #fdc4bd; + --color-rust-rust150: #f9b0a6; + --color-rust-rust200: #f69c8f; + --color-rust-rust300: #ea7a65; + --color-rust-rust400: #d96043; + --color-rust-rust500: #c44e29; + --color-rust-rust600: #a94417; + --color-rust-rust700: #8c3d0b; + --color-rust-rust800: #6c3604; + --color-rust-rust900: #4d2c01; + --color-rust-rust1000: #332100; + + /* Teal */ + --color-teal-teal0: #ebfffc; + --color-teal-teal50: #c9fef9; + --color-teal-teal100: #a8fdf8; + --color-teal-teal150: #8cf9f8; + --color-teal-teal200: #6ff2f6; + --color-teal-teal300: #45dcea; + --color-teal-teal400: #29c3d9; + --color-teal-teal500: #16a9c4; + --color-teal-teal600: #0b8ea9; + --color-teal-teal700: #05728c; + --color-teal-teal800: #01576c; + --color-teal-teal900: #003e4d; + --color-teal-teal1000: #002933; + + /* Yellow */ + --color-yellow-yellow0: #fffeeb; + --color-yellow-yellow50: #fefcc9; + --color-yellow-yellow100: #fdfaa8; + --color-yellow-yellow150: #f9f58c; + --color-yellow-yellow200: #f6f06f; + --color-yellow-yellow300: #eae345; + --color-yellow-yellow400: #d9d129; + --color-yellow-yellow500: #c4bb16; + --color-yellow-yellow600: #a9a20b; + --color-yellow-yellow700: #8c8505; + --color-yellow-yellow800: #6c6701; + --color-yellow-yellow900: #4d4a00; + --color-yellow-yellow1000: #333000; + + /* Border */ + --color-border-default-brand-accent: var(--color-yellow-yellow300); + --color-border-default-brand-primary: var(--color-yellow-yellow100); + --color-border-default-brand-secondary: var(--color-rust-rust100); + --color-border-default-primary: var(--color-gray-900); + --color-border-default-secondary: var(--color-gray-800); + --color-border-default-tertiary: var(--color-gray-600); + --color-border-default-utility-info: var(--color-royal-blue-royal-blue300); + --color-border-default-utility-negative: var(--color-red-red300); + --color-border-default-utility-positive: var(--color-kiwi-kiwi300); + --color-border-default-utility-warning: var(--color-yellow-yellow300); + + --color-border-inverse-brand-accent: var(--color-yellow-yellow50); + --color-border-inverse-brand-primary: var(--color-yellow-yellow800); + --color-border-inverse-brand-secondary: var(--color-rust-rust800); + --color-border-inverse-primary: var(--color-gray-000); + --color-border-inverse-secondary: var(--color-opacity-200); + --color-border-inverse-tertiary: var(--color-opacity-300); + --color-border-inverse-utility-info: var(--color-royal-blue-royal-blue300); + --color-border-inverse-utility-negative: var(--color-red-red300); + --color-border-inverse-utility-positive: var(--color-kiwi-kiwi400); + --color-border-inverse-utility-warning: var(--color-yellow-yellow400); + + /* Content */ + --color-content-brand-darker-accent-2: var(--color-yellow-yellow200); + --color-content-brand-kiwi: var(--color-kiwi-kiwi600); + --color-content-brand-lavender: var(--color-lavender-lavender500); + --color-content-brand-lighter-accent-2: var(--color-yellow-yellow100); + --color-content-brand-lime: var(--color-lime-lime500); + --color-content-brand-primary: var(--color-yellow-yellow50); + --color-content-brand-red: var(--color-red-red400); + --color-content-brand-royal: var(--color-royal-blue-royal-blue400); + --color-content-brand-rust: var(--color-rust-rust400); + --color-content-brand-teal: var(--color-teal-teal500); + + --color-content-default-brand-accent: var(--color-opacity-700); + --color-content-default-brand-primary: var(--color-yellow-yellow100); + --color-content-default-brand-secondary: var(--color-rust-rust400); --color-content-default-primary: var(--color-gray-000); --color-content-default-secondary: var(--color-gray-200); --color-content-default-tertiary: var(--color-gray-300); - --color-content-default-brand-primary: var(--color-community-yellow-100); - --color-content-default-brand-secondary: var(--color-community-orange-400); - --color-content-default-brand-accent: var(--color-yellow-opacity-700); + --color-content-default-utility-info: var(--color-royal-blue-royal-blue500); + --color-content-default-utility-negative: var(--color-red-red400); + --color-content-default-utility-positive: var(--color-lime-lime400); + --color-content-default-utility-warning: var(--color-yellow-yellow500); + + --color-content-inverse-brand-accent: var(--color-yellow-yellow700); + --color-content-inverse-brand-primary: var(--color-yellow-yellow900); + --color-content-inverse-brand-secondary: var(--color-rust-rust800); --color-content-inverse-primary: var(--color-gray-1000); --color-content-inverse-secondary: var(--color-gray-800); --color-content-inverse-tertiary: var(--color-gray-700); - --color-content-inverse-brand-primary: var(--color-community-yellow-900); - --color-content-inverse-brand-secondary: var(--color-community-orange-300); - --color-content-inverse-brand-accent: var(--color-yellow-opacity-400); - --color-surface-default-brand-primary: var(--color-community-yellow-100); - --color-surface-default-brand-secondary: var(--color-community-yellow-900); + --color-content-inverse-utility-info: var(--color-royal-blue-royal-blue300); + --color-content-inverse-utility-negative: var(--color-red-red300); + --color-content-inverse-utility-positive: var(--color-kiwi-kiwi300); + --color-content-inverse-utility-warning: var(--color-yellow-yellow300); + + /* Surface */ + --color-surface-default-brand-red: var(--color-red-red100); + --color-surface-default-brand-darker-accent: var(--color-yellow-yellow200); + --color-surface-default-brand-kiwi: var(--color-kiwi-kiwi200); + --color-surface-default-brand-lavender: var(--color-lavender-lavender200); + --color-surface-default-brand-lighter-accent: var(--color-yellow-yellow100); + --color-surface-default-brand-lime: var(--color-lime-lime100); + --color-surface-default-brand-primary: var(--color-yellow-yellow50); + --color-surface-default-brand-royal: var(--color-royal-blue-royal-blue50); + --color-surface-default-brand-rust: var(--color-rust-rust100); + --color-surface-default-brand-teal: var(--color-teal-teal50); + --color-surface-default-primary: var(--color-gray-1000); --color-surface-default-secondary: var(--color-gray-900); - --color-surface-inverse-primary: var(--color-gray-000); + --color-surface-default-semi-opaque: var(--color-opacity-050); --color-surface-default-tertiary: var(--color-gray-800); + --color-surface-default-transparent: var(--color-opacity-000); + + --color-surface-default-utility-info: var(--color-royal-blue-royal-blue400); + --color-surface-default-utility-negative: var(--color-red-red400); + --color-surface-default-utility-positive: var(--color-kiwi-kiwi500); + --color-surface-default-utility-warning: var(--color-yellow-yellow500); + + --color-surface-inverse-brand-accent: var(--color-yellow-yellow100); + --color-surface-inverse-brand-primary: var(--color-yellow-yellow100); + --color-surface-inverse-brand-secondary: var(--color-rust-rust300); + --color-surface-inverse-primary: var(--color-gray-000); --color-surface-inverse-secondary: var(--color-gray-100); --color-surface-inverse-tertiary: var(--color-gray-200); - --color-surface-inverse-brand-primary: var(--color-community-yellow-100); - --color-surface-inverse-brand-secondary: var(--color-community-orange-300); - --color-surface-inverse-brand-accent: var(--color-yellow-opacity-100); - --border-color-default-primary: var(--color-gray-900); - --border-color-inverse-utility-info: var(--color-community-blue-300); - --border-color-inverse-primary: var(--color-gray-000); - --border-color-default-secondary: var(--color-gray-800); - --border-color-inverse-secondary: var(--color-opacity-200); - --border-color-inverse-tertiary: var(--color-opacity-300); - --border-color-default-tertiary: var(--color-gray-600); - --border-color-inverse-utility-negative: var(--color-community-red-300); - --border-color-default-brandprimary: var(--color-community-yellow-100); - --border-color-inverse-utility-warning: var(--color-community-yellow-400); - --border-color-inverse-utility-positive: var(--color-community-kiwi-400); - --border-color-default-brandsecondary: var(--color-community-orange-400); - --border-color-default-brandaccent: var(--color-yellow-opacity-300); - --border-color-inverse-brandprimary: var(--color-community-yellow-800); - --border-color-inverse-brandsecondary: var(--color-community-orange-300); - --color-surface-default-transparent: var(--color-opacity-000); + --color-surface-inverse-utility-info: var(--color-royal-blue-royal-blue300); + --color-surface-inverse-utility-negative: var(--color-red-red300); + --color-surface-inverse-utility-positive: var(--color-kiwi-kiwi300); + --color-surface-inverse-utility-warning: var(--color-yellow-yellow300); + + /* Color */ + --color-config-europe-morning-magenta: oklch(66.27% 0.264 321.73); + /* white */ + --bg-color-light-primary: oklch(100% 0 263.28); + + /* Shadow */ + --shadow-focus-default: 0px 0px 10px 1px oklch(98.01% 0.065 105.71); + --shadow-subtle: 0px 0px 48px 0px oklch(0% 0 0 / 10%); + --shadow-minimal-shadow: 0px 0px 8px 0px oklch(0% 0 0 / 15%); + --shadow-focus-inverse: 0px 0px 10px 1px oklch(23.93% 0 263.28); + --shadow-subtle: 0px 0px 48px 0px oklch(0% 0 0 / 10%); + /* Use this shadow most of the time */ + --shadow-shallow-below: 0px 4px 16px 0px oklch(0% 0 0 / 12%); + --shadow-default: 0px 4px 6px 0px oklch(0% 0 0 / 9%); + + /* Typography */ + --text-xx-large-display: 96px; + --text-xx-large-display--line-height: 110%; + --text-xx-large-display--letter-spacing: 0px; + --text-xx-large-display--font-weight: 400; + + --text-xx-large-heading: 40px; + --text-xx-large-heading--line-height: 52px; + --text-xx-large-heading--letter-spacing: 0px; + --text-xx-large-heading--font-weight: 700; + + --text-x-large-heading: 36px; + --text-x-large-heading--line-height: 44px; + --text-x-large-heading--letter-spacing: 0px; + --text-x-large-heading--font-weight: 800; + + --text-large-heading: 32px; + --text-large-heading--line-height: 40px; + --text-large-heading--letter-spacing: 0px; + --text-large-heading--font-weight: 700; + + --text-medium-heading: 28px; + --text-medium-heading--line-height: 36px; + --text-medium-heading--letter-spacing: 0px; + --text-medium-heading--font-weight: 700; + + --text-small-heading: 24px; + --text-small-heading--line-height: 32px; + --text-small-heading--letter-spacing: 0px; + --text-small-heading--font-weight: 700; + + --text-x-small-heading: 20px; + --text-x-small-heading--line-height: 28px; + --text-x-small-heading--letter-spacing: 0px; + --text-x-small-heading--font-weight: 700; + + --text-large-label: 18px; + --text-large-label--line-height: 24px; + --text-large-label--letter-spacing: 0px; + --text-large-label--font-weight: 500; + + --text-medium-label: 16px; + --text-medium-label--line-height: 20px; + --text-medium-label--letter-spacing: 0px; + --text-medium-label--font-weight: 500; + + --text-small-label: 14px; + --text-small-label--line-height: 16px; + --text-small-label--letter-spacing: 0px; + --text-small-label--font-weight: 500; + + /* Regular 400 */ + --text-large-paragraph: 18px; + --text-large-paragraph--line-height: 130%; + --text-large-paragraph--letter-spacing: 0px; + --text-large-paragraph--font-weight: 400; + + --text-medium-paragraph: 16px; + --text-medium-paragraph--line-height: 24px; + --text-medium-paragraph--letter-spacing: 0px; + --text-medium-paragraph--font-weight: 400; + + --text-small-paragraph: 14px; + --text-small-paragraph--line-height: 20px; + --text-small-paragraph--letter-spacing: 0px; + --text-small-paragraph--font-weight: 400; + + --text-x-small-paragraph: 12px; + --text-x-small-paragraph--line-height: 16px; + --text-x-small-paragraph--letter-spacing: 0px; + --text-x-small-paragraph--font-weight: 400; + + --text-xx-small-label: 10px; + --text-xx-small-label--line-height: 12px; + --text-xx-small-label--letter-spacing: 0px; + --text-xx-small-label--font-weight: 500; + + --text-xx-small-paragraph: 10px; + --text-xx-small-paragraph--line-height: 14px; + --text-xx-small-paragraph--letter-spacing: 0px; + --text-xx-small-paragraph--font-weight: 400; + + --text-xx-small-italic: 10px; + --text-xx-small-italic--line-height: 14px; + --text-xx-small-italic--letter-spacing: 0px; + --text-xx-small-italic--font-weight: 400; + + --text-x-large-label: 24px; + --text-x-large-label--line-height: 28px; + --text-x-large-label--letter-spacing: 0px; + --text-x-large-label--font-weight: 400; + + --text-x-large-paragraph: 24px; + --text-x-large-paragraph--line-height: 32px; + --text-x-large-paragraph--letter-spacing: 0px; + --text-x-large-paragraph--font-weight: 400; + + --text-xx-large-paragraph: 32px; + --text-xx-large-paragraph--line-height: 40px; + --text-xx-large-paragraph--letter-spacing: 0px; + --text-xx-large-paragraph--font-weight: 400; + + --text-xx-large-label: 32px; + --text-xx-large-label--line-height: 36px; + --text-xx-large-label--letter-spacing: 0px; + --text-xx-large-label--font-weight: 400; + + --text-x-small-underline: 12px; + --text-x-small-underline--line-height: 14px; + --text-x-small-underline--letter-spacing: 0px; + --text-x-small-underline--font-weight: 400; + + --text-small-underline: 14px; + --text-small-underline--line-height: 16px; + --text-small-underline--letter-spacing: 0px; + --text-small-underline--font-weight: 400; + + --text-medium-underline: 16px; + --text-medium-underline--line-height: 20px; + --text-medium-underline--letter-spacing: 0px; + --text-medium-underline--font-weight: 400; + + --text-large-underline: 18px; + --text-large-underline--line-height: 24px; + --text-large-underline--letter-spacing: 0px; + --text-large-underline--font-weight: 400; + + --text-x-large-underline: 24px; + --text-x-large-underline--line-height: 28px; + --text-x-large-underline--letter-spacing: 0px; + --text-x-large-underline--font-weight: 400; + + --text-x-small-label: 12px; + --text-x-small-label--line-height: 14px; + --text-x-small-label--letter-spacing: 0px; + --text-x-small-label--font-weight: 500; + + --text-x-small-label-caps: 10px; + --text-x-small-label-caps--line-height: 12px; + --text-x-small-label-caps--letter-spacing: 0px; + --text-x-small-label-caps--font-weight: 500; + + --text-xx-small-heading: 16px; + --text-xx-small-heading--line-height: 22px; + --text-xx-small-heading--letter-spacing: 0px; + --text-xx-small-heading--font-weight: 700; + + --text-x-small-display: 24px; + --text-x-small-display--line-height: 24px; + --text-x-small-display--letter-spacing: 0px; + --text-x-small-display--font-weight: 400; + + --text-x-large-uppercase: 24px; + --text-x-large-uppercase--line-height: 120%; + --text-x-large-uppercase--letter-spacing: 0.48px; + --text-x-large-uppercase--font-weight: 400; + + --text-xx-large-uppercase: 32px; + --text-xx-large-uppercase--line-height: 120%; + --text-xx-large-uppercase--letter-spacing: 0.64px; + --text-xx-large-uppercase--font-weight: 400; + + --text-x-large-display: 64px; + --text-x-large-display--line-height: 110%; + --text-x-large-display--letter-spacing: 0px; + --text-x-large-display--font-weight: 400; + + --text-large-display: 52px; + --text-large-display--line-height: 110%; + --text-large-display--letter-spacing: 0px; + --text-large-display--font-weight: 400; + + --text-medium-display: 44px; + --text-medium-display--line-height: 110%; + --text-medium-display--letter-spacing: 0px; + --text-medium-display--font-weight: 400; + + --text-xx-small-display: 18px; + --text-xx-small-display--line-height: 120%; + --text-xx-small-display--letter-spacing: 0px; + --text-xx-small-display--font-weight: 400; + + --text-x-small-uppercase: 12px; + --text-x-small-uppercase--line-height: 120%; + --text-x-small-uppercase--letter-spacing: 0.24px; + --text-x-small-uppercase--font-weight: 400; + + --text-large-uppercase: 18px; + --text-large-uppercase--line-height: 120%; + --text-large-uppercase--letter-spacing: 0.36px; + --text-large-uppercase--font-weight: 400; + + --text-small-display: 36px; + --text-small-display--line-height: 110%; + --text-small-display--letter-spacing: 0px; + --text-small-display--font-weight: 400; +} + +@layer utilities { + .text-x-small-heading { + font-size: var(--text-x-small-heading); + line-height: var(--text-x-small-heading--line-height); + font-weight: var(--text-x-small-heading--font-weight); + letter-spacing: var(--text-x-small-heading--letter-spacing); + } + .text-x-small-paragraph { + font-size: var(--text-x-small-paragraph); + line-height: var(--text-x-small-paragraph--line-height); + font-weight: var(--text-x-small-paragraph--font-weight); + letter-spacing: var(--text-x-small-paragraph--letter-spacing); + } +} + +@layer components { + .xx-large-display { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-xx-large-display); + font-weight: var(--text-xx-large-display--font-weight); + line-height: var(--text-xx-large-display--line-height); + letter-spacing: var(--text-xx-large-display--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .xx-large-heading { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-xx-large-heading); + font-weight: var(--text-xx-large-heading--font-weight); + line-height: var(--text-xx-large-heading--line-height); + letter-spacing: var(--text-xx-large-heading--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-large-heading { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-x-large-heading); + font-weight: var(--text-x-large-heading--font-weight); + line-height: var(--text-x-large-heading--line-height); + letter-spacing: var(--text-x-large-heading--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .large-heading { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-large-heading); + font-weight: var(--text-large-heading--font-weight); + line-height: var(--text-large-heading--line-height); + letter-spacing: var(--text-large-heading--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .medium-heading { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-medium-heading); + font-weight: var(--text-medium-heading--font-weight); + line-height: var(--text-medium-heading--line-height); + letter-spacing: var(--text-medium-heading--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .small-heading { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-small-heading); + font-weight: var(--text-small-heading--font-weight); + line-height: var(--text-small-heading--line-height); + letter-spacing: var(--text-small-heading--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-small-heading { + font-family: var(--font-space-grotesk); + font-size: var(--text-x-small-heading); + font-weight: var(--text-x-small-heading--font-weight); + line-height: var(--text-x-small-heading--line-height); + letter-spacing: var(--text-x-small-heading--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .large-label { + font-family: var(--font-inter); + font-size: var(--text-large-label); + font-weight: var(--text-large-label--font-weight); + line-height: var(--text-large-label--line-height); + letter-spacing: var(--text-large-label--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .medium-label { + font-family: var(--font-inter); + font-size: var(--text-medium-label); + font-weight: var(--text-medium-label--font-weight); + line-height: var(--text-medium-label--line-height); + letter-spacing: var(--text-medium-label--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .small-label { + font-family: var(--font-inter); + font-size: var(--text-small-label); + font-weight: var(--text-small-label--font-weight); + line-height: var(--text-small-label--line-height); + letter-spacing: var(--text-small-label--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + /* Regular 400 */ + .large-paragraph { + font-family: var(--font-inter); + font-size: var(--text-large-paragraph); + font-weight: var(--text-large-paragraph--font-weight); + line-height: var(--text-large-paragraph--line-height); + letter-spacing: var(--text-large-paragraph--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .medium-paragraph { + font-family: var(--font-inter); + font-size: var(--text-medium-paragraph); + font-weight: var(--text-medium-paragraph--font-weight); + line-height: var(--text-medium-paragraph--line-height); + letter-spacing: var(--text-medium-paragraph--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .small-paragraph { + font-family: var(--font-inter); + font-size: var(--text-small-paragraph); + font-weight: var(--text-small-paragraph--font-weight); + line-height: var(--text-small-paragraph--line-height); + letter-spacing: var(--text-small-paragraph--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-small-paragraph { + font-family: var(--font-inter); + font-size: var(--text-x-small-paragraph); + font-weight: var(--text-x-small-paragraph--font-weight); + line-height: var(--text-x-small-paragraph--line-height); + letter-spacing: var(--text-x-small-paragraph--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .xx-small-label { + font-family: var(--font-inter); + font-size: var(--text-xx-small-label); + font-weight: var(--text-xx-small-label--font-weight); + line-height: var(--text-xx-small-label--line-height); + letter-spacing: var(--text-xx-small-label--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .xx-small-paragraph { + font-family: var(--font-inter); + font-size: var(--text-xx-small-paragraph); + font-weight: var(--text-xx-small-paragraph--font-weight); + line-height: var(--text-xx-small-paragraph--line-height); + letter-spacing: var(--text-xx-small-paragraph--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .xx-small-italic { + font-family: var(--font-inter); + font-size: var(--text-xx-small-italic); + font-weight: var(--text-xx-small-italic--font-weight); + line-height: var(--text-xx-small-italic--line-height); + letter-spacing: var(--text-xx-small-italic--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-large-label { + font-family: var(--font-inter); + font-size: var(--text-x-large-label); + font-weight: var(--text-x-large-label--font-weight); + line-height: var(--text-x-large-label--line-height); + letter-spacing: var(--text-x-large-label--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-large-paragraph { + font-family: var(--font-inter); + font-size: var(--text-x-large-paragraph); + font-weight: var(--text-x-large-paragraph--font-weight); + line-height: var(--text-x-large-paragraph--line-height); + letter-spacing: var(--text-x-large-paragraph--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .xx-large-paragraph { + font-family: var(--font-inter); + font-size: var(--text-xx-large-paragraph); + font-weight: var(--text-xx-large-paragraph--font-weight); + line-height: var(--text-xx-large-paragraph--line-height); + letter-spacing: var(--text-xx-large-paragraph--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .xx-large-label { + font-family: var(--font-inter); + font-size: var(--text-xx-large-label); + font-weight: var(--text-xx-large-label--font-weight); + line-height: var(--text-xx-large-label--line-height); + letter-spacing: var(--text-xx-large-label--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-small-underline { + font-family: var(--font-inter); + font-size: var(--text-x-small-underline); + font-weight: var(--text-x-small-underline--font-weight); + line-height: var(--text-x-small-underline--line-height); + letter-spacing: var(--text-x-small-underline--letter-spacing); + text-decoration: underline; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .small-underline { + font-family: var(--font-inter); + font-size: var(--text-small-underline); + font-weight: var(--text-small-underline--font-weight); + line-height: var(--text-small-underline--line-height); + letter-spacing: var(--text-small-underline--letter-spacing); + text-decoration: underline; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .medium-underline { + font-family: var(--font-inter); + font-size: var(--text-medium-underline); + font-weight: var(--text-medium-underline--font-weight); + line-height: var(--text-medium-underline--line-height); + letter-spacing: var(--text-medium-underline--letter-spacing); + text-decoration: underline; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .large-underline { + font-family: var(--font-inter); + font-size: var(--text-large-underline); + font-weight: var(--text-large-underline--font-weight); + line-height: var(--text-large-underline--line-height); + letter-spacing: var(--text-large-underline--letter-spacing); + text-decoration: underline; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-large-underline { + font-family: var(--font-inter); + font-size: var(--text-x-large-underline); + font-weight: var(--text-x-large-underline--font-weight); + line-height: var(--text-x-large-underline--line-height); + letter-spacing: var(--text-x-large-underline--letter-spacing); + text-decoration: underline; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-small-label { + font-family: var(--font-inter); + font-size: var(--text-x-small-label); + font-weight: var(--text-x-small-label--font-weight); + line-height: var(--text-x-small-label--line-height); + letter-spacing: var(--text-x-small-label--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-small-label-caps { + font-family: var(--font-inter); + font-size: var(--text-x-small-label-caps); + font-weight: var(--text-x-small-label-caps--font-weight); + line-height: var(--text-x-small-label-caps--line-height); + letter-spacing: var(--text-x-small-label-caps--letter-spacing); + text-decoration: none; + text-transform: uppercase; + text-indent: 0px; + margin-bottom: 0px; + } + .xx-small-heading { + font-family: var(--font-inter); + font-size: var(--text-xx-small-heading); + font-weight: var(--text-xx-small-heading--font-weight); + line-height: var(--text-xx-small-heading--line-height); + letter-spacing: var(--text-xx-small-heading--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-small-display { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-x-small-display); + font-weight: var(--text-x-small-display--font-weight); + line-height: var(--text-x-small-display--line-height); + letter-spacing: var(--text-x-small-display--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-large-uppercase { + font-family: var(--font-inter); + font-size: var(--text-x-large-uppercase); + font-weight: var(--text-x-large-uppercase--font-weight); + line-height: var(--text-x-large-uppercase--line-height); + letter-spacing: var(--text-x-large-uppercase--letter-spacing); + text-decoration: none; + text-transform: uppercase; + text-indent: 0px; + margin-bottom: 0px; + } + .xx-large-uppercase { + font-family: var(--font-inter); + font-size: var(--text-xx-large-uppercase); + font-weight: var(--text-xx-large-uppercase--font-weight); + line-height: var(--text-xx-large-uppercase--line-height); + letter-spacing: var(--text-xx-large-uppercase--letter-spacing); + text-decoration: none; + text-transform: uppercase; + text-indent: 0px; + margin-bottom: 0px; + } + .x-large-display { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-x-large-display); + font-weight: var(--text-x-large-display--font-weight); + line-height: var(--text-x-large-display--line-height); + letter-spacing: var(--text-x-large-display--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .large-display { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-large-display); + font-weight: var(--text-large-display--font-weight); + line-height: var(--text-large-display--line-height); + letter-spacing: var(--text-large-display--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .medium-display { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-medium-display); + font-weight: var(--text-medium-display--font-weight); + line-height: var(--text-medium-display--line-height); + letter-spacing: var(--text-medium-display--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .xx-small-display { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-xx-small-display); + font-weight: var(--text-xx-small-display--font-weight); + line-height: var(--text-xx-small-display--line-height); + letter-spacing: var(--text-xx-small-display--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } + .x-small-uppercase { + font-family: var(--font-inter); + font-size: var(--text-x-small-uppercase); + font-weight: var(--text-x-small-uppercase--font-weight); + line-height: var(--text-x-small-uppercase--line-height); + letter-spacing: var(--text-x-small-uppercase--letter-spacing); + text-decoration: none; + text-transform: uppercase; + text-indent: 0px; + margin-bottom: 0px; + } + .large-uppercase { + font-family: var(--font-inter); + font-size: var(--text-large-uppercase); + font-weight: var(--text-large-uppercase--font-weight); + line-height: var(--text-large-uppercase--line-height); + letter-spacing: var(--text-large-uppercase--letter-spacing); + text-decoration: none; + text-transform: uppercase; + text-indent: 0px; + margin-bottom: 0px; + } + .small-display { + font-family: var(--font-bricolage-grotesque); + font-size: var(--text-small-display); + font-weight: var(--text-small-display--font-weight); + line-height: var(--text-small-display--line-height); + letter-spacing: var(--text-small-display--letter-spacing); + text-decoration: none; + text-transform: none; + text-indent: 0px; + margin-bottom: 0px; + } } From 6f5279cf7df18e2bb447c321b445c5cc1f04d8a7 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Fri, 22 Aug 2025 16:43:57 -0600 Subject: [PATCH 04/27] Update NumberedCards.js --- app/components/NumberedCards.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/app/components/NumberedCards.js b/app/components/NumberedCards.js index e7a09fc..dcf6b45 100644 --- a/app/components/NumberedCards.js +++ b/app/components/NumberedCards.js @@ -33,7 +33,14 @@ const NumberedCards = ({ title, subtitle, cards }) => { + How
+ CommunityRule +
+ helps + + } />
From 8113658d8b4b1c42e16b8369e64eeccf43d509a2 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Fri, 22 Aug 2025 16:51:22 -0600 Subject: [PATCH 05/27] Fix Section Header --- app/components/NumberedCards.js | 11 ++--------- app/components/SectionHeader.js | 10 +++++----- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/app/components/NumberedCards.js b/app/components/NumberedCards.js index dcf6b45..ac196d7 100644 --- a/app/components/NumberedCards.js +++ b/app/components/NumberedCards.js @@ -26,21 +26,14 @@ const NumberedCards = ({ title, subtitle, cards }) => { dangerouslySetInnerHTML={{ __html: JSON.stringify(schemaData) }} />
-
+
{/* Section Header */}
- How
- CommunityRule -
- helps - - } + titleLg="How CommunityRule helps" />
diff --git a/app/components/SectionHeader.js b/app/components/SectionHeader.js index f32d2ee..7345db5 100644 --- a/app/components/SectionHeader.js +++ b/app/components/SectionHeader.js @@ -8,8 +8,8 @@ const SectionHeader = ({ title, subtitle, titleLg, variant = "default" }) => {

{title} @@ -18,12 +18,12 @@ const SectionHeader = ({ title, subtitle, titleLg, variant = "default" }) => {

{/* Subtitle Container */} -
+

{subtitle} From eb1bfcfe8d2a879ec61bd272c0d989ae676d82ad Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Fri, 22 Aug 2025 17:00:28 -0600 Subject: [PATCH 06/27] Update tailwind.css --- app/tailwind.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/tailwind.css b/app/tailwind.css index 2942914..a05ba7e 100644 --- a/app/tailwind.css +++ b/app/tailwind.css @@ -344,7 +344,7 @@ --color-content-brand-teal: var(--color-teal-teal500); --color-content-default-brand-accent: var(--color-opacity-700); - --color-content-default-brand-primary: var(--color-yellow-yellow100); + --color-content-default-brand-primary: var(--color-yellow-yellow50); --color-content-default-brand-secondary: var(--color-rust-rust400); --color-content-default-primary: var(--color-gray-000); --color-content-default-secondary: var(--color-gray-200); From a8efb34d63f1c93d9fed70905aaef962cb667213 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Fri, 22 Aug 2025 17:01:05 -0600 Subject: [PATCH 07/27] Update SectionNumber.js --- app/components/SectionNumber.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/components/SectionNumber.js b/app/components/SectionNumber.js index cee6814..14d5f4d 100644 --- a/app/components/SectionNumber.js +++ b/app/components/SectionNumber.js @@ -15,14 +15,14 @@ const SectionNumber = ({ number }) => { }; return ( -

+
{`Section
- + {number}
From d428bf0c0938ee4342698db5e5356c117905db98 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Sat, 23 Aug 2025 16:38:37 -0600 Subject: [PATCH 08/27] Brand color changes --- app/components/HeaderTab.js | 2 +- app/components/HeroBanner.js | 2 +- app/tailwind.css | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/components/HeaderTab.js b/app/components/HeaderTab.js index 6e1e18a..0756504 100644 --- a/app/components/HeaderTab.js +++ b/app/components/HeaderTab.js @@ -10,7 +10,7 @@ export default function HeaderTab({ return (
{children} diff --git a/app/components/HeroBanner.js b/app/components/HeroBanner.js index e68f3c7..af595c9 100644 --- a/app/components/HeroBanner.js +++ b/app/components/HeroBanner.js @@ -8,7 +8,7 @@ const HeroBanner = ({ title, subtitle, description, ctaText, ctaHref }) => {
{/* Frame container for content */} -
+
{/* DECORATIONS (behind content) */} +
Hero illustration { return ( diff --git a/app/tailwind.css b/app/tailwind.css index df97465..90f379a 100644 --- a/app/tailwind.css +++ b/app/tailwind.css @@ -4,6 +4,7 @@ @source "../stories/**/*"; @source "../app/**/*"; @source "../.storybook/**/*"; +@source "./**/*"; @theme inline { /* Custom breakpoints */ @@ -16,6 +17,14 @@ /* Reset Tailwind color defaults to avoid collisions */ --color-*: initial; + /* Font families */ + --font-sans: var(--font-inter), ui-sans-serif, system-ui, -apple-system, + "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + --font-display: var(--font-bricolage-grotesque), ui-sans-serif, system-ui, + -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + --font-mono: var(--font-space-grotesk), ui-monospace, SFMono-Regular, + "SF Mono", Consolas, "Liberation Mono", Menlo, monospace; + /* Dimension */ --spacing-scale-000: 0px; --spacing-scale-001: 1px; @@ -409,7 +418,6 @@ --shadow-subtle: 0px 0px 48px 0px oklch(0% 0 0 / 10%); --shadow-minimal-shadow: 0px 0px 8px 0px oklch(0% 0 0 / 15%); --shadow-focus-inverse: 0px 0px 10px 1px oklch(23.93% 0 263.28); - --shadow-subtle: 0px 0px 48px 0px oklch(0% 0 0 / 10%); /* Use this shadow most of the time */ --shadow-shallow-below: 0px 4px 16px 0px oklch(0% 0 0 / 12%); --shadow-default: 0px 4px 6px 0px oklch(0% 0 0 / 9%); From 0bbf30e85fa357ff91510bf13c93ab1d28313526 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Sat, 23 Aug 2025 17:46:09 -0600 Subject: [PATCH 11/27] Rule Stack default breakpoint added --- app/components/RuleCard.js | 2 +- app/components/RuleStack.js | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/components/RuleCard.js b/app/components/RuleCard.js index aaa94f4..5da073e 100644 --- a/app/components/RuleCard.js +++ b/app/components/RuleCard.js @@ -9,7 +9,7 @@ const RuleCard = ({ }) => { return (
{/* Header Container */}
diff --git a/app/components/RuleStack.js b/app/components/RuleStack.js index 42d3ce9..2efc5b9 100644 --- a/app/components/RuleStack.js +++ b/app/components/RuleStack.js @@ -2,6 +2,7 @@ import SectionHeader from "./SectionHeader"; import RuleCard from "./RuleCard"; +import Button from "./Button"; import Image from "next/image"; const RuleStack = ({ children, className = "" }) => { @@ -68,6 +69,13 @@ const RuleStack = ({ children, className = "" }) => { backgroundColor="bg-[var(--color-surface-default-brand-teal)]" />
+ + {/* See all templates button */} +
+ +
); }; From 661b3c6e058343e651793964d9ad59a791e0f8ff Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Sat, 23 Aug 2025 22:25:57 -0600 Subject: [PATCH 12/27] Rule Stack md breakpoint --- app/components/RuleCard.js | 12 ++++++------ app/components/RuleStack.js | 8 ++++++-- app/components/SectionHeader.js | 8 ++++---- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/app/components/RuleCard.js b/app/components/RuleCard.js index 5da073e..b70bcd7 100644 --- a/app/components/RuleCard.js +++ b/app/components/RuleCard.js @@ -9,27 +9,27 @@ const RuleCard = ({ }) => { return (
{/* Header Container */} -
+
{/* Icon Container */} {icon && ( -
+
{icon}
)} {/* Title Container */} {title && ( -
-

+
+

{title}

)}

{description && ( -

+

{description}

)} diff --git a/app/components/RuleStack.js b/app/components/RuleStack.js index 2efc5b9..d1c5dd0 100644 --- a/app/components/RuleStack.js +++ b/app/components/RuleStack.js @@ -8,12 +8,12 @@ import Image from "next/image"; const RuleStack = ({ children, className = "" }) => { return (
{ alt="Sociocracy" width={40} height={40} + className="md:w-[56px] md:h-[56px]" /> } backgroundColor="bg-[var(--color-surface-default-brand-lime)]" @@ -38,6 +39,7 @@ const RuleStack = ({ children, className = "" }) => { alt="Consensus" width={40} height={40} + className="md:w-[56px] md:h-[56px]" /> } backgroundColor="bg-[var(--color-surface-default-brand-rust)]" @@ -51,6 +53,7 @@ const RuleStack = ({ children, className = "" }) => { alt="Elected Board" width={40} height={40} + className="md:w-[56px] md:h-[56px]" /> } backgroundColor="bg-[var(--color-surface-default-brand-red)]" @@ -64,6 +67,7 @@ const RuleStack = ({ children, className = "" }) => { alt="Petition" width={40} height={40} + className="md:w-[56px] md:h-[56px]" /> } backgroundColor="bg-[var(--color-surface-default-brand-teal)]" diff --git a/app/components/SectionHeader.js b/app/components/SectionHeader.js index 7345db5..11ab930 100644 --- a/app/components/SectionHeader.js +++ b/app/components/SectionHeader.js @@ -7,8 +7,8 @@ const SectionHeader = ({ title, subtitle, titleLg, variant = "default" }) => {

@@ -21,8 +21,8 @@ const SectionHeader = ({ title, subtitle, titleLg, variant = "default" }) => {

From 75bc8af749be5bbaa1ee428d285512799c860cf0 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Sun, 24 Aug 2025 20:26:19 -0600 Subject: [PATCH 13/27] Rule Stack xmd breakpoint --- app/components/RuleStack.js | 4 ++-- app/tailwind.css | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/components/RuleStack.js b/app/components/RuleStack.js index d1c5dd0..674efde 100644 --- a/app/components/RuleStack.js +++ b/app/components/RuleStack.js @@ -8,14 +8,14 @@ import Image from "next/image"; const RuleStack = ({ children, className = "" }) => { return (

-
+
Date: Sun, 24 Aug 2025 20:58:19 -0600 Subject: [PATCH 14/27] Rule Stack lg breakpoint --- app/components/RuleCard.js | 12 ++++++------ app/components/RuleStack.js | 12 ++++++------ app/components/SectionHeader.js | 4 ++-- 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/app/components/RuleCard.js b/app/components/RuleCard.js index b70bcd7..245e7ac 100644 --- a/app/components/RuleCard.js +++ b/app/components/RuleCard.js @@ -9,27 +9,27 @@ const RuleCard = ({ }) => { return (
{/* Header Container */} -
+
{/* Icon Container */} {icon && ( -
+
{icon}
)} {/* Title Container */} {title && ( -
-

+
+

{title}

)}

{description && ( -

+

{description}

)} diff --git a/app/components/RuleStack.js b/app/components/RuleStack.js index 674efde..6e4d97c 100644 --- a/app/components/RuleStack.js +++ b/app/components/RuleStack.js @@ -8,14 +8,14 @@ import Image from "next/image"; const RuleStack = ({ children, className = "" }) => { return (
-
+
{ alt="Sociocracy" width={40} height={40} - className="md:w-[56px] md:h-[56px]" + className="md:w-[56px] md:h-[56px] lg:w-[90px] lg:h-[90px]" /> } backgroundColor="bg-[var(--color-surface-default-brand-lime)]" @@ -39,7 +39,7 @@ const RuleStack = ({ children, className = "" }) => { alt="Consensus" width={40} height={40} - className="md:w-[56px] md:h-[56px]" + className="md:w-[56px] md:h-[56px] lg:w-[90px] lg:h-[90px]" /> } backgroundColor="bg-[var(--color-surface-default-brand-rust)]" @@ -53,7 +53,7 @@ const RuleStack = ({ children, className = "" }) => { alt="Elected Board" width={40} height={40} - className="md:w-[56px] md:h-[56px]" + className="md:w-[56px] md:h-[56px] lg:w-[90px] lg:h-[90px]" /> } backgroundColor="bg-[var(--color-surface-default-brand-red)]" @@ -67,7 +67,7 @@ const RuleStack = ({ children, className = "" }) => { alt="Petition" width={40} height={40} - className="md:w-[56px] md:h-[56px]" + className="md:w-[56px] md:h-[56px] lg:w-[90px] lg:h-[90px]" /> } backgroundColor="bg-[var(--color-surface-default-brand-teal)]" diff --git a/app/components/SectionHeader.js b/app/components/SectionHeader.js index 11ab930..feb9c72 100644 --- a/app/components/SectionHeader.js +++ b/app/components/SectionHeader.js @@ -8,7 +8,7 @@ const SectionHeader = ({ title, subtitle, titleLg, variant = "default" }) => {

@@ -22,7 +22,7 @@ const SectionHeader = ({ title, subtitle, titleLg, variant = "default" }) => {

From 6ac3f0801066e7311f2fab59c6aa15f5b8229f13 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Sun, 24 Aug 2025 21:41:16 -0600 Subject: [PATCH 15/27] Rule Stack xl breakpoint --- app/components/RuleStack.js | 2 +- app/components/SectionHeader.js | 30 ++++++++++++++++++++++++------ 2 files changed, 25 insertions(+), 7 deletions(-) diff --git a/app/components/RuleStack.js b/app/components/RuleStack.js index 6e4d97c..c0d6fbf 100644 --- a/app/components/RuleStack.js +++ b/app/components/RuleStack.js @@ -8,7 +8,7 @@ import Image from "next/image"; const RuleStack = ({ children, className = "" }) => { return (

{ return ( -
+
{/* Title Container - Left side (lg breakpoint) */} -
+

{title} @@ -18,11 +30,17 @@ const SectionHeader = ({ title, subtitle, titleLg, variant = "default" }) => {

{/* Subtitle Container */} -
+

From 1ff5d13d2ecee93b9f94602a75e6dff18ce61a17 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Sun, 24 Aug 2025 21:47:48 -0600 Subject: [PATCH 16/27] Update SectionHeader.js --- app/components/SectionHeader.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/components/SectionHeader.js b/app/components/SectionHeader.js index 0ce0000..6be3c1b 100644 --- a/app/components/SectionHeader.js +++ b/app/components/SectionHeader.js @@ -13,8 +13,8 @@ const SectionHeader = ({ title, subtitle, titleLg, variant = "default" }) => {

{

Date: Sun, 24 Aug 2025 21:54:04 -0600 Subject: [PATCH 17/27] Rule Stack interactive states and analytics --- app/components/RuleCard.js | 35 ++++++++++++++++++++++++++++++++++- app/components/RuleStack.js | 10 ++++++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/app/components/RuleCard.js b/app/components/RuleCard.js index 245e7ac..291b90f 100644 --- a/app/components/RuleCard.js +++ b/app/components/RuleCard.js @@ -6,10 +6,43 @@ const RuleCard = ({ icon, backgroundColor = "bg-[var(--color-community-teal-100)]", className = "", + onClick, }) => { + const handleClick = () => { + // Basic analytics event tracking + if (typeof window !== "undefined" && window.gtag) { + window.gtag("event", "template_selected", { + template_name: title, + template_type: "governance_pattern", + }); + } + + // Custom analytics event for other tracking systems + if (typeof window !== "undefined" && window.analytics) { + window.analytics.track("Template Selected", { + templateName: title, + templateType: "governance_pattern", + }); + } + + if (onClick) onClick(); + }; + + const handleKeyDown = (event) => { + if (event.key === "Enter" || event.key === " ") { + event.preventDefault(); + handleClick(); + } + }; + return (

{/* Header Container */}
diff --git a/app/components/RuleStack.js b/app/components/RuleStack.js index c0d6fbf..c85fb1d 100644 --- a/app/components/RuleStack.js +++ b/app/components/RuleStack.js @@ -6,6 +6,12 @@ import Button from "./Button"; import Image from "next/image"; const RuleStack = ({ children, className = "" }) => { + const handleTemplateClick = (templateName) => { + console.log(`Template selected: ${templateName}`); + // This would typically navigate to template details or open a modal + // For now, we'll just log the selection + }; + return (
{ /> } backgroundColor="bg-[var(--color-surface-default-brand-lime)]" + onClick={() => handleTemplateClick("Consensus clusters")} /> { /> } backgroundColor="bg-[var(--color-surface-default-brand-rust)]" + onClick={() => handleTemplateClick("Consensus")} /> { /> } backgroundColor="bg-[var(--color-surface-default-brand-red)]" + onClick={() => handleTemplateClick("Elected Board")} /> { /> } backgroundColor="bg-[var(--color-surface-default-brand-teal)]" + onClick={() => handleTemplateClick("Petition")} />
From f22cde728a392bdbd1d8b1c33d8d13b6e6dea7ea Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Sun, 24 Aug 2025 22:01:52 -0600 Subject: [PATCH 18/27] Rule Stack storyboard --- stories/RuleCard.stories.js | 176 +++++++++++++++++++++++++++++++ stories/RuleStack.stories.js | 39 +++++++ stories/SectionHeader.stories.js | 47 ++++++++- 3 files changed, 261 insertions(+), 1 deletion(-) create mode 100644 stories/RuleCard.stories.js create mode 100644 stories/RuleStack.stories.js diff --git a/stories/RuleCard.stories.js b/stories/RuleCard.stories.js new file mode 100644 index 0000000..5d42faf --- /dev/null +++ b/stories/RuleCard.stories.js @@ -0,0 +1,176 @@ +import RuleCard from "../app/components/RuleCard"; +import Image from "next/image"; + +export default { + title: "Components/RuleCard", + component: RuleCard, + parameters: { + layout: "centered", + docs: { + description: { + component: + "An interactive card component that displays governance templates and decision-making patterns. Features hover states, keyboard navigation, analytics tracking, and accessibility support. Use Tab key to test focus indicators and Enter/Space to activate.", + }, + }, + }, + argTypes: { + title: { + control: { type: "text" }, + description: "The title of the governance template", + }, + description: { + control: { type: "text" }, + description: "The description of the governance pattern", + }, + backgroundColor: { + control: { type: "select" }, + options: [ + "bg-[var(--color-surface-default-brand-lime)]", + "bg-[var(--color-surface-default-brand-rust)]", + "bg-[var(--color-surface-default-brand-red)]", + "bg-[var(--color-surface-default-brand-teal)]", + "bg-[var(--color-community-teal-100)]", + ], + description: "The background color variant for the card", + }, + onClick: { action: "clicked" }, + }, + tags: ["autodocs"], +}; + +export const Default = { + args: { + title: "Consensus clusters", + description: + "Units called Circles have the ability to decide and act on matters in their domains, which their members agree on through a Council.", + backgroundColor: "bg-[var(--color-surface-default-brand-lime)]", + icon: ( + Sociocracy + ), + }, +}; + +export const AllVariants = { + render: (args) => ( +
+ + } + onClick={() => console.log("Consensus clusters selected")} + /> + + } + onClick={() => console.log("Consensus selected")} + /> + + } + onClick={() => console.log("Elected Board selected")} + /> + + } + onClick={() => console.log("Petition selected")} + /> +
+ ), + parameters: { + docs: { + description: { + story: + "All four governance template variants with their respective colors and icons. Test hover states, focus indicators, and click interactions.", + }, + }, + }, +}; + +export const InteractiveStates = { + args: { + title: "Interactive Demo", + description: + "Hover over this card to see the scale and shadow effects. Use Tab to focus and Enter/Space to activate.", + backgroundColor: "bg-[var(--color-community-teal-100)]", + icon: ( +
+ ? +
+ ), + }, + parameters: { + docs: { + description: { + story: + "Demonstrates interactive states including hover effects, focus indicators, and keyboard navigation. Test with mouse hover and keyboard Tab/Enter/Space.", + }, + }, + }, +}; + +export const AccessibilityTest = { + args: { + title: "Accessibility Demo", + description: + "This card is designed for accessibility testing. Use Tab to focus, Enter/Space to activate, and screen readers to test ARIA labels.", + backgroundColor: "bg-[var(--color-surface-default-brand-teal)]", + icon: ( +
+ ♿ +
+ ), + }, + parameters: { + docs: { + description: { + story: + "Specifically designed for testing accessibility features including keyboard navigation, screen reader support, and focus management.", + }, + }, + }, +}; diff --git a/stories/RuleStack.stories.js b/stories/RuleStack.stories.js new file mode 100644 index 0000000..c5bca40 --- /dev/null +++ b/stories/RuleStack.stories.js @@ -0,0 +1,39 @@ +import RuleStack from "../app/components/RuleStack"; + +export default { + title: "Components/RuleStack", + component: RuleStack, + parameters: { + layout: "fullscreen", + docs: { + description: { + component: + "A complete template library component that displays governance patterns in a responsive grid layout. Includes SectionHeader with multi-line variant, interactive RuleCard components, and a call-to-action button. Features comprehensive accessibility, analytics tracking, and responsive design across all breakpoints.\n\n" + + "**Testing Scenarios:**\n" + + "- **Responsive Testing**: Resize browser window to test layout adaptation from single column on mobile to 2x2 grid on larger screens\n" + + "- **Interactive Testing**: Hover over cards to see effects, use Tab to navigate between cards, and click to see analytics events in console\n" + + "- **Accessibility Testing**: Use screen readers to test ARIA labels, keyboard navigation to move between cards, and verify focus indicators\n" + + "- **Custom Styling**: Add className prop to customize background or other styling", + }, + }, + }, + argTypes: { + className: { + control: { type: "text" }, + description: "Additional CSS classes for custom styling", + }, + }, + tags: ["autodocs"], +}; + +export const Default = { + args: {}, + parameters: { + docs: { + description: { + story: + "The complete RuleStack component with all four governance templates, responsive grid layout, and interactive features. Test hover states, keyboard navigation, and responsive behavior across different screen sizes.", + }, + }, + }, +}; diff --git a/stories/SectionHeader.stories.js b/stories/SectionHeader.stories.js index 40bf7b0..a821b94 100644 --- a/stories/SectionHeader.stories.js +++ b/stories/SectionHeader.stories.js @@ -8,7 +8,7 @@ export default { docs: { description: { component: - "A section header component that displays a title and subtitle with responsive typography and layout. Supports different title text for large breakpoints and maintains consistent spacing across all screen sizes.", + "A section header component that displays a title and subtitle with responsive typography and layout. Supports different title text for large breakpoints and maintains consistent spacing across all screen sizes. Includes 'default' and 'multi-line' variants with different layout behaviors.", }, }, }, @@ -26,6 +26,12 @@ export default { description: "The title text for lg and xl breakpoints (optional, falls back to title)", }, + variant: { + control: { type: "select" }, + options: ["default", "multi-line"], + description: + "The layout variant - 'default' for traditional layout, 'multi-line' for 50/50 split layout", + }, }, tags: ["autodocs"], }; @@ -35,6 +41,24 @@ export const Default = { title: "How CommunityRule works", subtitle: "Here's a quick overview of the process, from start to finish.", titleLg: "How CommunityRule helps", + variant: "default", + }, +}; + +export const MultiLine = { + args: { + title: "Popular templates", + subtitle: + "These are popular patterns for making decisions in mutual aid and open source communities. You can use them as they are or as a starting place for customizing your own CommunityRule.", + variant: "multi-line", + }, + parameters: { + docs: { + description: { + story: + "The multi-line variant creates a 50/50 split layout at lg and xl breakpoints, with the title on the left and subtitle on the right. This variant is used in the RuleStack component.", + }, + }, }, }; @@ -44,6 +68,7 @@ export const CustomContent = { subtitle: "We're dedicated to helping communities thrive through better decision-making processes and transparent governance structures.", titleLg: "Building Better Communities", + variant: "default", }, parameters: { docs: { @@ -61,6 +86,7 @@ export const LongSubtitle = { subtitle: "This is a much longer subtitle that demonstrates how the component handles extended text content across different breakpoints and layout configurations.", titleLg: "Complex Process Simplified", + variant: "default", }, parameters: { docs: { @@ -78,6 +104,7 @@ export const ResponsiveTest = { subtitle: "Test the responsive behavior by resizing your browser window or using the viewport controls in Storybook.", titleLg: "Responsive Design Test", + variant: "default", }, parameters: { docs: { @@ -94,6 +121,7 @@ export const WithoutTitleLg = { title: "Simple Header", subtitle: "This example doesn't specify a titleLg prop, so it will use the same title text across all breakpoints.", + variant: "default", }, parameters: { docs: { @@ -104,3 +132,20 @@ export const WithoutTitleLg = { }, }, }; + +export const MultiLineResponsive = { + args: { + title: "Multi-line Responsive Test", + subtitle: + "This multi-line variant demonstrates the 50/50 split layout at larger breakpoints. Resize your browser to see how the layout adapts from stacked on mobile to side-by-side on desktop.", + variant: "multi-line", + }, + parameters: { + docs: { + description: { + story: + "Test the responsive behavior of the multi-line variant. The layout changes from stacked on mobile to 50/50 split on lg and xl breakpoints.", + }, + }, + }, +}; From e76fcc620628f8e04a7307e197a66622f15d6e8a Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Sun, 24 Aug 2025 22:10:27 -0600 Subject: [PATCH 19/27] Update Rule Stack storybook image paths --- app/components/RuleStack.js | 8 ++++---- stories/RuleCard.stories.js | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/components/RuleStack.js b/app/components/RuleStack.js index c85fb1d..0e43a6b 100644 --- a/app/components/RuleStack.js +++ b/app/components/RuleStack.js @@ -27,7 +27,7 @@ const RuleStack = ({ children, className = "" }) => { description="Units called Circles have the ability to decide and act on matters in their domains, which their members agree on through a Council." icon={ Sociocracy { description="Decisions that affect the group collectively should involve participation of all participants." icon={ Consensus { description="An elected board determines policies and organizes their implementation." icon={ Elected Board { description="All participants can propose and vote on proposals for the group." icon={ Petition Date: Mon, 25 Aug 2025 15:52:39 -0600 Subject: [PATCH 20/27] Quote Block default breakpoint added --- app/components/QuoteBlock.js | 49 ++++++++++++++++++++++++++++++++++ app/components/QuoteDecor.js | 42 +++++++++++++++++++++++++++++ app/components/RuleStack.js | 32 +++++++++++++--------- app/page.js | 2 ++ public/assets/Quote_Avatar.svg | 9 +++++++ 5 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 app/components/QuoteBlock.js create mode 100644 app/components/QuoteDecor.js create mode 100644 public/assets/Quote_Avatar.svg diff --git a/app/components/QuoteBlock.js b/app/components/QuoteBlock.js new file mode 100644 index 0000000..50149af --- /dev/null +++ b/app/components/QuoteBlock.js @@ -0,0 +1,49 @@ +"use client"; + +import React from "react"; +import Image from "next/image"; +import QuoteDecor from "./QuoteDecor"; + +const QuoteBlock = ({ className = "" }) => { + return ( +
+ {/* DECORATIONS (behind content) */} + + +
+
+ Quote Avatar +
+

+ "The rules of decision-making must be open and + available to everyone, and this can happen only if they are + formalized." +

+
+
+
+

+ Jo Freeman +

+

+ "The Tyranny of Structurelessness" +

+
+
+
+ ); +}; + +export default QuoteBlock; diff --git a/app/components/QuoteDecor.js b/app/components/QuoteDecor.js new file mode 100644 index 0000000..6d7b9e9 --- /dev/null +++ b/app/components/QuoteDecor.js @@ -0,0 +1,42 @@ +"use client"; + +const QuoteDecor = ({ className = "" }) => { + return ( + + ); +}; + +export default QuoteDecor; diff --git a/app/components/RuleStack.js b/app/components/RuleStack.js index 0e43a6b..f5b9733 100644 --- a/app/components/RuleStack.js +++ b/app/components/RuleStack.js @@ -1,26 +1,32 @@ "use client"; -import SectionHeader from "./SectionHeader"; +import React from "react"; +import Image from "next/image"; import RuleCard from "./RuleCard"; import Button from "./Button"; -import Image from "next/image"; -const RuleStack = ({ children, className = "" }) => { +const RuleStack = ({ className = "" }) => { const handleTemplateClick = (templateName) => { - console.log(`Template selected: ${templateName}`); - // This would typically navigate to template details or open a modal - // For now, we'll just log the selection + // Basic analytics tracking + if (typeof window !== "undefined") { + if (window.gtag) { + window.gtag("event", "template_click", { + template_name: templateName, + }); + } + if (window.analytics) { + window.analytics.track("Template Clicked", { + templateName: templateName, + }); + } + } + console.log(`${templateName} template clicked`); }; return ( -
-
{ See all templates
-
+

); }; diff --git a/app/page.js b/app/page.js index e6a48ad..ac8d1fd 100644 --- a/app/page.js +++ b/app/page.js @@ -2,6 +2,7 @@ import NumberedCards from "./components/NumberedCards"; import HeroBanner from "./components/HeroBanner"; import LogoWall from "./components/LogoWall"; import RuleStack from "./components/RuleStack"; +import QuoteBlock from "./components/QuoteBlock"; export default function Page() { const heroBannerData = { @@ -41,6 +42,7 @@ export default function Page() { +
); } diff --git a/public/assets/Quote_Avatar.svg b/public/assets/Quote_Avatar.svg new file mode 100644 index 0000000..50c8704 --- /dev/null +++ b/public/assets/Quote_Avatar.svg @@ -0,0 +1,9 @@ + + + + + + + + + From ccee34f5c866bc3634b67cf6b4aecde56e261e28 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Mon, 25 Aug 2025 18:45:13 -0600 Subject: [PATCH 21/27] Quote Block md breakpoint --- app/components/QuoteBlock.js | 64 ++++++++++++++------------- app/components/QuoteDecor.js | 85 ++++++++++++++++++++++++------------ 2 files changed, 92 insertions(+), 57 deletions(-) diff --git a/app/components/QuoteBlock.js b/app/components/QuoteBlock.js index 50149af..04c57dd 100644 --- a/app/components/QuoteBlock.js +++ b/app/components/QuoteBlock.js @@ -7,39 +7,43 @@ import QuoteDecor from "./QuoteDecor"; const QuoteBlock = ({ className = "" }) => { return (
- {/* DECORATIONS (behind content) */} - +
+ {/* DECORATIONS (behind content) */} + -
-
- Quote Avatar -
-

- "The rules of decision-making must be open and - available to everyone, and this can happen only if they are - formalized." +

+
+ Quote Avatar +
+

+ "The rules of decision-making must be open and + available to everyone, and this can happen only if they are + formalized." +

+
+
+
+

+ Jo Freeman

-
-
-
-

- Jo Freeman -

-

- "The Tyranny of Structurelessness" -

+

+ "The Tyranny of Structurelessness" +

+
diff --git a/app/components/QuoteDecor.js b/app/components/QuoteDecor.js index 6d7b9e9..e1b8ccb 100644 --- a/app/components/QuoteDecor.js +++ b/app/components/QuoteDecor.js @@ -3,37 +3,68 @@ const QuoteDecor = ({ className = "" }) => { return ( ); From f1dbfbfdacd5d9880a99e755087f7c18beeca479 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Mon, 25 Aug 2025 19:17:41 -0600 Subject: [PATCH 22/27] Quote Block lg breakpoint --- app/components/QuoteBlock.js | 16 ++++++++-------- app/components/QuoteDecor.js | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/components/QuoteBlock.js b/app/components/QuoteBlock.js index 04c57dd..5ec7549 100644 --- a/app/components/QuoteBlock.js +++ b/app/components/QuoteBlock.js @@ -7,10 +7,10 @@ import QuoteDecor from "./QuoteDecor"; const QuoteBlock = ({ className = "" }) => { return (
{/* DECORATIONS (behind content) */} { w-full h-full" /> -
-
+
+
Quote Avatar
-

+

"The rules of decision-making must be open and available to everyone, and this can happen only if they are formalized." @@ -37,10 +37,10 @@ const QuoteBlock = ({ className = "" }) => {

-

+

Jo Freeman

-

+

"The Tyranny of Structurelessness"

diff --git a/app/components/QuoteDecor.js b/app/components/QuoteDecor.js index e1b8ccb..04cec01 100644 --- a/app/components/QuoteDecor.js +++ b/app/components/QuoteDecor.js @@ -3,7 +3,7 @@ const QuoteDecor = ({ className = "" }) => { return (
-
+
+
Quote Avatar
-

- "The rules of decision-making must be open and - available to everyone, and this can happen only if they are - formalized." +

+ The rules of decision-making must be open and available to + everyone, and this can happen only if they are formalized.

-
-

+

+

Jo Freeman

-

- "The Tyranny of Structurelessness" +

+ The Tyranny of Structurelessness

diff --git a/app/components/QuoteDecor.js b/app/components/QuoteDecor.js index 04cec01..cd2a5f4 100644 --- a/app/components/QuoteDecor.js +++ b/app/components/QuoteDecor.js @@ -3,7 +3,7 @@ const QuoteDecor = ({ className = "" }) => { return (
+
{/* DECORATIONS (behind content) */} - + {config.showDecor && ( + + )} -
-
+
+
Quote Avatar
-

- The rules of decision-making must be open and available to - everyone, and this can happen only if they are formalized. +

+ {quote}

-

- Jo Freeman +

+ {author}

-

- The Tyranny of Structurelessness +

+ {source}

From 28b788c584470598bf342cab406b4b70a56ad936 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:14:05 -0600 Subject: [PATCH 25/27] Quote Block accessibility and error handling --- app/components/QuoteBlock.js | 141 +++++++++++++++++++++++++++++------ 1 file changed, 120 insertions(+), 21 deletions(-) diff --git a/app/components/QuoteBlock.js b/app/components/QuoteBlock.js index ac373fe..8341a6e 100644 --- a/app/components/QuoteBlock.js +++ b/app/components/QuoteBlock.js @@ -1,6 +1,6 @@ "use client"; -import React from "react"; +import React, { useState } from "react"; import Image from "next/image"; import QuoteDecor from "./QuoteDecor"; @@ -11,7 +11,13 @@ const QuoteBlock = ({ author = "Jo Freeman", source = "The Tyranny of Structurelessness", avatarSrc = "assets/Quote_Avatar.svg", + id, + fallbackAvatarSrc = "assets/Quote_Avatar.svg", // Fallback avatar + onError, // Error callback }) => { + const [imageError, setImageError] = useState(false); + const [imageLoading, setImageLoading] = useState(true); + // Variant configurations const variants = { compact: { @@ -63,8 +69,60 @@ const QuoteBlock = ({ const config = variants[variant] || variants.standard; + // Use provided ID or generate a stable one based on content + const baseId = id || `quote-${author.toLowerCase().replace(/\s+/g, "-")}`; + const quoteId = `${baseId}-content`; + const authorId = `${baseId}-author`; + + // Error handling functions + const handleImageError = (error) => { + console.warn( + `QuoteBlock: Failed to load avatar image for ${author}:`, + error + ); + setImageError(true); + setImageLoading(false); + + // Call error callback if provided + if (onError) { + onError({ + type: "image_load_error", + message: `Failed to load avatar for ${author}`, + author, + avatarSrc, + error, + }); + } + }; + + const handleImageLoad = () => { + setImageLoading(false); + setImageError(false); + }; + + // Validate required props + if (!quote || !author) { + console.error("QuoteBlock: Missing required props (quote or author)"); + if (onError) { + onError({ + type: "missing_props", + message: "QuoteBlock requires quote and author props", + quote: !!quote, + author: !!author, + }); + } + return null; // Don't render if missing required props + } + + // Determine which avatar to use + const currentAvatarSrc = imageError ? fallbackAvatarSrc : avatarSrc; + return ( -
+
@@ -74,19 +132,57 @@ const QuoteBlock = ({ className="pointer-events-none absolute z-0 left-0 top-0 w-full h-full" + aria-hidden="true" /> )}
- {`${author} -
+ {/* Avatar with error handling */} +
+ {`Portrait + + {/* Loading state */} + {imageLoading && ( +
+ )} + + {/* Error state - show initials */} + {imageError && !imageLoading && ( +
+ + {author + .split(" ") + .map((n) => n[0]) + .join("") + .toUpperCase()} + +
+ )} +
+ +

@@ -94,21 +190,24 @@ const QuoteBlock = ({

-
-

+ {author} -

-

- {source} -

-
+ + {source && ( +

+ {source} +

+ )} +
-
+
); }; From ac05f33705e8f4502e6c3402e328588b3aaacc9e Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:40:51 -0600 Subject: [PATCH 26/27] Quote Block storybook implemented --- .storybook/preview.js | 19 ++++- .storybook/preview.local.js | 19 ++++- app/components/QuoteBlock.js | 60 +++++++++----- stories/QuoteBlock.stories.js | 146 ++++++++++++++++++++++++++++++++++ 4 files changed, 218 insertions(+), 26 deletions(-) create mode 100644 stories/QuoteBlock.stories.js diff --git a/.storybook/preview.js b/.storybook/preview.js index 59394fb..8b6689a 100644 --- a/.storybook/preview.js +++ b/.storybook/preview.js @@ -1,18 +1,27 @@ import "../app/globals.css"; // Import Google Fonts for Storybook -import { Inter, Bricolage_Grotesque } from "next/font/google"; +import { Inter, Bricolage_Grotesque, Space_Grotesk } from "next/font/google"; const inter = Inter({ subsets: ["latin"], - weight: ["400", "500"], + weight: ["400", "500", "600", "700"], variable: "--font-inter", + display: "swap", }); const bricolageGrotesque = Bricolage_Grotesque({ subsets: ["latin"], - weight: ["400", "500"], + weight: ["400", "500", "700", "800"], variable: "--font-bricolage-grotesque", + display: "swap", +}); + +const spaceGrotesk = Space_Grotesk({ + subsets: ["latin"], + weight: ["400", "500", "700"], + variable: "--font-space-grotesk", + display: "swap", }); /** @type { import('@storybook/react').Preview } */ @@ -28,7 +37,9 @@ const preview = { }, decorators: [ (Story) => ( -
+
), diff --git a/.storybook/preview.local.js b/.storybook/preview.local.js index 59394fb..8b6689a 100644 --- a/.storybook/preview.local.js +++ b/.storybook/preview.local.js @@ -1,18 +1,27 @@ import "../app/globals.css"; // Import Google Fonts for Storybook -import { Inter, Bricolage_Grotesque } from "next/font/google"; +import { Inter, Bricolage_Grotesque, Space_Grotesk } from "next/font/google"; const inter = Inter({ subsets: ["latin"], - weight: ["400", "500"], + weight: ["400", "500", "600", "700"], variable: "--font-inter", + display: "swap", }); const bricolageGrotesque = Bricolage_Grotesque({ subsets: ["latin"], - weight: ["400", "500"], + weight: ["400", "500", "700", "800"], variable: "--font-bricolage-grotesque", + display: "swap", +}); + +const spaceGrotesk = Space_Grotesk({ + subsets: ["latin"], + weight: ["400", "500", "700"], + variable: "--font-space-grotesk", + display: "swap", }); /** @type { import('@storybook/react').Preview } */ @@ -28,7 +37,9 @@ const preview = { }, decorators: [ (Story) => ( -
+
), diff --git a/app/components/QuoteBlock.js b/app/components/QuoteBlock.js index 8341a6e..3598a2f 100644 --- a/app/components/QuoteBlock.js +++ b/app/components/QuoteBlock.js @@ -140,30 +140,32 @@ const QuoteBlock = ({
{/* Avatar with error handling */}
- {`Portrait + {!imageError ? ( + {`Portrait + ) : null} {/* Loading state */} - {imageLoading && ( + {imageLoading && !imageError && (
)} {/* Error state - show initials */} - {imageError && !imageLoading && ( + {imageError && (
@@ -184,7 +186,20 @@ const QuoteBlock = ({ className="relative" >

{quote}

@@ -199,7 +214,16 @@ const QuoteBlock = ({ {source && (

{source}

diff --git a/stories/QuoteBlock.stories.js b/stories/QuoteBlock.stories.js new file mode 100644 index 0000000..3b4f0f6 --- /dev/null +++ b/stories/QuoteBlock.stories.js @@ -0,0 +1,146 @@ +import QuoteBlock from "../app/components/QuoteBlock"; + +export default { + title: "Components/QuoteBlock", + component: QuoteBlock, + parameters: { + layout: "fullscreen", + docs: { + description: { + component: ` +A responsive quote section component that displays inspirational governance quotes with author attribution and decorative geometric elements. + +## Features +- **Three variants**: compact, standard, and extended layouts +- **Responsive design**: Adapts across all breakpoints +- **Error handling**: Graceful fallbacks for image loading failures +- **Accessibility**: WCAG 2.1 AA compliant with proper ARIA labels +- **Design system integration**: Uses design tokens for consistent styling + +## Usage +\`\`\`jsx + +\`\`\` + `, + }, + }, + }, + argTypes: { + variant: { + control: { type: "select" }, + options: ["compact", "standard", "extended"], + description: "Layout variant for different use cases", + }, + quote: { + control: { type: "text" }, + description: "The quote text to display", + }, + author: { + control: { type: "text" }, + description: "Author name for attribution", + }, + source: { + control: { type: "text" }, + description: "Source title (book, article, etc.)", + }, + avatarSrc: { + control: { type: "text" }, + description: "Path to author avatar image", + }, + fallbackAvatarSrc: { + control: { type: "text" }, + description: "Fallback avatar image path", + }, + onError: { + action: "error", + description: "Error callback function", + }, + }, +}; + +// Default story +export const Default = { + args: { + variant: "standard", + quote: + "The rules of decision-making must be open and available to everyone, and this can happen only if they are formalized.", + author: "Jo Freeman", + source: "The Tyranny of Structurelessness", + avatarSrc: "assets/Quote_Avatar.svg", + }, +}; + +// All variants comparison +export const AllVariants = { + render: () => ( +
+
+

Compact Variant

+ +
+ +
+

Standard Variant

+ +
+ +
+

Extended Variant

+ +
+
+ ), + parameters: { + docs: { + description: { + story: + "Side-by-side comparison of all three variants to show the differences in layout, typography, and spacing.", + }, + }, + }, +}; + +// Error state simulation +export const ErrorState = { + args: { + variant: "standard", + quote: + "The rules of decision-making must be open and available to everyone, and this can happen only if they are formalized.", + author: "Jo Freeman", + source: "The Tyranny of Structurelessness", + avatarSrc: "invalid-image-path.jpg", // This will trigger error state + onError: (error) => console.log("QuoteBlock error:", error), + }, + parameters: { + docs: { + description: { + story: + "Error state when avatar image fails to load. Shows initials fallback and error handling.", + }, + }, + }, +}; From 3609501fea3d4146f730b6368febfa0e256ff345 Mon Sep 17 00:00:00 2001 From: adilallo <39313955+adilallo@users.noreply.github.com> Date: Tue, 26 Aug 2025 10:45:20 -0600 Subject: [PATCH 27/27] Fix github pages storybook fonts --- .storybook/preview.github.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/.storybook/preview.github.js b/.storybook/preview.github.js index 1fd25df..8b6689a 100644 --- a/.storybook/preview.github.js +++ b/.storybook/preview.github.js @@ -1,5 +1,29 @@ import "../app/globals.css"; +// Import Google Fonts for Storybook +import { Inter, Bricolage_Grotesque, Space_Grotesk } from "next/font/google"; + +const inter = Inter({ + subsets: ["latin"], + weight: ["400", "500", "600", "700"], + variable: "--font-inter", + display: "swap", +}); + +const bricolageGrotesque = Bricolage_Grotesque({ + subsets: ["latin"], + weight: ["400", "500", "700", "800"], + variable: "--font-bricolage-grotesque", + display: "swap", +}); + +const spaceGrotesk = Space_Grotesk({ + subsets: ["latin"], + weight: ["400", "500", "700"], + variable: "--font-space-grotesk", + display: "swap", +}); + /** @type { import('@storybook/react').Preview } */ const preview = { parameters: { @@ -11,6 +35,15 @@ const preview = { }, }, }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], }; export default preview;