diff --git a/README.md b/README.md index 86ced527..60c7a5dd 100644 --- a/README.md +++ b/README.md @@ -6,27 +6,30 @@ ## What is Compose? -Compose is a smart contract library that helps developers create smart contract systems using [ERC-2535 Diamonds](https://eips.ethereum.org/EIPS/eip-2535). +A smart contract development framework for building modular systems with [ERC-8153 Diamonds](https://eips.ethereum.org/EIPS/eip-2535). -**Compose provides:** +Compose gives you a clear way to split contract functionality into focused facets, reuse proven building blocks, and evolve your onchain application with ease. -- An on-chain standard library of facets (modular smart contracts) -- Building blocks for diamond-based smart contract systems -- Patterns and libraries to combine Compose facets with your custom logic +**The framework includes:** + +- A Solidity library of reusable facets and modules +- A CLI toolkit for projects with Foundry or Hardhat +- Design patterns for combining Compose components with custom logic +- Documentation for building, extending, and testing diamond systems The project actively evolves based on community input—[tell us](https://github.com/Perfect-Abstractions/Compose/discussions/108) what you'd like Compose to do for you. ## Why Compose is Different -**Forget traditional smart contract design patterns**—Compose takes a radically different approach. +Smart contracts are hard enough to audit and maintain. Compose keeps each piece small, explicit, and easy to read. -We build high-quality smart contracts by **intentionally restricting Solidity features** and following conventions designed specifically for smart contracts. This is **Smart Contract Oriented Programming (SCOP)**. +We use **intentional Solidity constraints** and conventions designed specifically for smart contracts. This is **Smart Contract Oriented Programming (SCOP)**. ### Core Philosophy - **Read First**: Code written to be understood, not just executed -- **Diamond-Native**: Built specifically for ERC-2535 diamond contracts +- **Diamond-Native**: Built specifically for ERC-2535 / ERC-8153 diamond contracts - **Composition Over Inheritance**: Combine facets instead of inheriting contracts - **Intentional Simplicity**: Banned features lead to clearer, safer code @@ -71,13 +74,9 @@ Please see the [documentation for contributing](https://compose.diamonds/docs/co
-**Compose is evolving with your help. Join us in building the future of smart contract development.** - -**-Nick & The Compose Community** - -### Made with 🩵 by the [Compose Community](https://github.com/Perfect-Abstractions/Compose/graphs/contributors) +### Made with more than 🩵 by the [Compose Community](https://github.com/Perfect-Abstractions/Compose/graphs/contributors) diff --git a/cli/README.md b/cli/README.md index 05a773b8..7510435f 100644 --- a/cli/README.md +++ b/cli/README.md @@ -1,6 +1,6 @@ # Compose CLI -Command-line toolkit for building, deploying, and managing diamond smart contracts using the Compose Library. Supports both [Foundry](https://book.getfoundry.sh/) and [Hardhat](https://hardhat.org/) frameworks. +The Compose CLI is the fastest way to start a modular smart contract project. Scaffold a facet-based diamond, choose your building blocks, and develop with [Foundry](https://book.getfoundry.sh/) or [Hardhat](https://hardhat.org/). ## Quick Start @@ -153,7 +153,7 @@ Please see the [documentation for contributing](https://compose.diamonds/docs/co
-**Compose is evolving with your help. Join us in building the future of smart contract development.** +**Start your next smart contract system with a structure you can understand and extend.** **-Nick & The Compose Community** diff --git a/cli/package.json b/cli/package.json index 1dd8a954..d632563a 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,7 +1,7 @@ { "name": "@perfect-abstractions/compose-cli", "version": "0.3.0", - "description": "CLI to scaffold Compose facet-based diamond projects", + "description": "CLI for scaffolding Compose smart contract projects with facet-based diamonds", "main": "dist/index.js", "bin": { "compose": "bin/compose.js" diff --git a/src/package.json b/src/package.json index 6eb2002d..aa65fb28 100644 --- a/src/package.json +++ b/src/package.json @@ -34,4 +34,4 @@ "bugs": { "url": "https://github.com/Perfect-Abstractions/Compose/issues" } -} \ No newline at end of file +} diff --git a/website/docs/contribution/documentation/all-components.mdx b/website/docs/contribution/documentation/all-components.mdx index dd9235f8..c4b3ac65 100644 --- a/website/docs/contribution/documentation/all-components.mdx +++ b/website/docs/contribution/documentation/all-components.mdx @@ -2026,13 +2026,22 @@ Your configuration has been saved successfully! This is a simple note without a custom title. + +Use for security-critical or irreversible-operation notices. + + + +Collapsible callouts keep long details out of the reading flow. + + #### Props @@ -2068,32 +2077,20 @@ This is a simple note without a custom title. ### CalloutBox -Alternative callout component with different styling. +Deprecated alias of [Callout](#callout), kept for backward compatibility with existing pages. Prefer `Callout` in new docs. Content Enhancement #### Live Example -CalloutBox offers an alternative styling to the standard Callout component. - - - -Always validate user input before processing. +CalloutBox renders identically to Callout. #### Props Same as Callout component. -#### Usage - -```jsx - - Content here - -``` - --- ## Icon Gallery diff --git a/website/docs/foundations/onchain-contract-library.mdx b/website/docs/foundations/onchain-contract-library.mdx index c0e82682..eac9f217 100644 --- a/website/docs/foundations/onchain-contract-library.mdx +++ b/website/docs/foundations/onchain-contract-library.mdx @@ -36,7 +36,7 @@ For your next project, instead of deploying new contracts, simply **use the exis -Compose is a general purpose **on-chain** smart contract library. +Compose is a general-purpose smart contract framework with a reusable **on-chain** library. diff --git a/website/docs/intro.mdx b/website/docs/intro.mdx index c7d42e25..fe3be19d 100644 --- a/website/docs/intro.mdx +++ b/website/docs/intro.mdx @@ -1,9 +1,9 @@ --- sidebar_position: 1 slug: / -title: "Smart Contract Library for ERC-2535 / ERC-8153 Diamonds" +title: "Smart Contract Development Framework for Diamonds" sidebar_label: "Introduction" -description: Compose is a smart contract library for building smart contract systems using the ERC-2535 Diamond standard. +description: Compose is a smart contract development framework for building modular, readable smart contract systems with ERC-2535 Diamonds. --- import DocSubtitle from '@site/src/components/docs/DocSubtitle'; @@ -14,24 +14,21 @@ import FeatureGrid, { FeatureGridItem } from '@site/src/components/features/Feat # Introduction to Compose -**Compose** is a smart contract library that helps developers build smart contract systems using the [ERC-2535 Diamond](https://eips.ethereum.org/EIPS/eip-2535) standard. It's designed from the ground up for **code clarity**, **reusability**, and **on-chain composability**. +**Compose** is the smart contract development framework for building modular systems with the [ERC-2535 Diamond](https://eips.ethereum.org/EIPS/eip-2535) standard. It brings together a reusable Solidity library, a project-scaffolding CLI, and design patterns for **clear, composable, upgradeable code**. ## The Vision -Imagine a verified, standard library of **on-chain smart contract components** — -each one small, self-contained, and reusable like LEGO blocks. +Smart contract systems grow faster than a single contract can stay understandable. Compose breaks functionality into **small, self-contained facets** and gives you the modules, CLI, and conventions to assemble them into a system. -Deployed once, trusted by all, and combined in endless ways to create new systems. - -That's **Compose** — where your unique value and functionality connects seamlessly with simple, transparent, on-chain building blocks. +That's **Compose**: a framework for shipping your unique protocol logic on top of simple, reusable building blocks. ## Why Choose Compose? ## Types of Smart Contract Systems -Compose is a general purpose smart contract library that can be used to build a wide variety of systems, including small, large, upgradeable and immutable smart contract systems. +Compose is a general-purpose framework for building small or large smart contract systems, including upgradeable and immutable systems. However Compose **shines** when building these types of systems: @@ -71,7 +68,7 @@ However Compose **shines** when building these types of systems: ## Perfect For -Our smart contract library is perfect for: +Compose is a strong fit for: - **DeFi Protocols**: Build financial products with composable, upgradeable components - **NFT Platforms**: Create custom marketplaces and collections with flexible, reusable logic - **DAO Governance**: Implement voting and proposal systems that can evolve over time @@ -131,4 +128,4 @@ Compose is built with 🩵 by a vibrant community of developers who care about t external={true} size="small" /> - \ No newline at end of file + diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index 2d2f93ca..f2601190 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -21,7 +21,7 @@ dotenv.config(); /** @type {import('@docusaurus/types').Config} */ const config = { title: 'Compose', - tagline: 'Smart Contract Oriented Programming for ERC-2535 Diamonds', + tagline: 'The smart contract development framework for modular diamond systems', favicon: 'img/favicon.ico', // Future flags, see https://docusaurus.io/docs/api/docusaurus-config#future @@ -117,7 +117,7 @@ const config = { '@type': 'WebSite', name: 'Compose', url: 'https://compose.diamonds/', - about: "Modular Smart Contract Library for ERC-2535 / ERC-8153 diamond proxies", + about: "Smart contract development framework for modular ERC-2535 / ERC-8153 diamond systems", author: "Perfect Abstractions & the Compose Community", potentialAction: { '@type': 'SearchAction', @@ -318,7 +318,7 @@ const config = { }, ], copyright: `Made with DELEGATECALL by the
Compose Community.
- Copyright © ${new Date().getFullYear()}`, + Copyright © ${new Date().getFullYear()} · An initiative of Perfect Abstractions & Sapient Labs`, }, prism: { theme: prismThemes.github, diff --git a/website/src/components/DiamondScene/FacetBadge.js b/website/src/components/DiamondScene/FacetBadge.js index 1e36fb2b..ef3925a7 100644 --- a/website/src/components/DiamondScene/FacetBadge.js +++ b/website/src/components/DiamondScene/FacetBadge.js @@ -1,13 +1,23 @@ import React from 'react'; +import Link from '@docusaurus/Link'; import styles from './facetBadge.module.css'; -export function FacetBadge({ name, visible }) { +export function FacetBadge({ facet, visible, onMouseEnter, onMouseLeave }) { return ( -
+
Active Facet
-
{name || '...'}
+ {facet && facet.path ? ( + + {facet.name} + + ) : ( +
{facet ? facet.name : '...'}
+ )}
); } - diff --git a/website/src/components/DiamondScene/facetBadge.module.css b/website/src/components/DiamondScene/facetBadge.module.css index daaee9cb..8f82c6b5 100644 --- a/website/src/components/DiamondScene/facetBadge.module.css +++ b/website/src/components/DiamondScene/facetBadge.module.css @@ -14,6 +14,7 @@ .visible { opacity: 1; transform: translateY(0); + pointer-events: auto; } .badgeLabel { @@ -27,6 +28,7 @@ } .badgeValue { + display: block; font-size: 1.25rem; font-weight: 700; color: #fff; @@ -34,6 +36,14 @@ background: linear-gradient(to right, #fff, #bfdbfe); -webkit-background-clip: text; -webkit-text-fill-color: transparent; + cursor: pointer; + text-decoration: none; + transition: filter 0.2s ease; +} + +.badgeValue:hover { + filter: drop-shadow(0 0 8px rgba(147, 197, 253, 0.9)); + text-decoration: underline; } .badgeLine { diff --git a/website/src/components/DiamondScene/index.js b/website/src/components/DiamondScene/index.js index 2ac230eb..75727495 100644 --- a/website/src/components/DiamondScene/index.js +++ b/website/src/components/DiamondScene/index.js @@ -4,7 +4,7 @@ import gsap from 'gsap'; import { DiamondShader, ParticleShader, FacetHighlightShader } from './shaders'; import { createDiamondGeometry, addFacetIds } from './geometry'; -export default function DiamondScene({ className, onHoverChange, inline = false }) { +export default function DiamondScene({ className, onHoverChange, onFacetClick, inline = false }) { const canvasContainerRef = useRef(null); useEffect(() => { @@ -180,6 +180,15 @@ export default function DiamondScene({ className, onHoverChange, inline = false window.addEventListener('mousemove', onMouseMove); + // Click a hovered facet to open its documentation page + const onClick = () => { + if (inline || window.innerWidth <= 1024) return; + if (currentHoverId !== -1 && onFacetClick) { + onFacetClick(currentHoverId); + } + }; + renderer.domElement.addEventListener('click', onClick); + // Time Uniform & Loop const clock = new THREE.Clock(); let animationId; @@ -234,6 +243,13 @@ export default function DiamondScene({ className, onHoverChange, inline = false } renderer.render(scene, camera); + + // Facet hover is driven by window mousemove; the canvas stays behind the + // hero overlays (which are pointer-events: none) and only accepts clicks + // while a facet is hovered. + const facetHovered = !inline && window.innerWidth > 1024 && currentHoverId !== -1; + renderer.domElement.style.cursor = facetHovered ? 'pointer' : 'default'; + renderer.domElement.style.pointerEvents = facetHovered ? 'auto' : 'none'; }; animate(); @@ -270,6 +286,7 @@ export default function DiamondScene({ className, onHoverChange, inline = false return () => { window.removeEventListener('resize', handleResize); window.removeEventListener('mousemove', onMouseMove); + renderer.domElement.removeEventListener('click', onClick); cancelAnimationFrame(animationId); if (container && renderer.domElement && container.contains(renderer.domElement)) { container.removeChild(renderer.domElement); @@ -280,7 +297,7 @@ export default function DiamondScene({ className, onHoverChange, inline = false particlesGeometry.dispose(); renderer.dispose(); }; - }, [onHoverChange, inline]); // Depend on callback and inline + }, [onHoverChange, onFacetClick, inline]); // Depend on callbacks and inline return
; } diff --git a/website/src/components/DiamondScene/useFacetBadges.js b/website/src/components/DiamondScene/useFacetBadges.js index b48c468d..62428e63 100644 --- a/website/src/components/DiamondScene/useFacetBadges.js +++ b/website/src/components/DiamondScene/useFacetBadges.js @@ -1,53 +1,84 @@ -import { useState, useCallback } from 'react'; - -// Contract filenames mirrored from `src/**` and converted to display names. -const FACET_NAMES = [ - "DiamondInspectFacet", - "DiamondUpgradeFacet", - "ERC165Facet", - "AccessControlDataFacet", - "AccessControlGrantFacet", - "AccessControlRevokeFacet", - "OwnerDataFacet", - "OwnerTransferFacet", - "OwnerRenounceFacet", - "ERC1155DataFacet", - "ERC1155MintFacet", - "ERC1155BurnFacet", - "ERC20DataFacet", - "ERC20MintFacet", - "ERC20BurnFacet", - "ERC20ApproveFacet", - "ERC20TransferFacet", - "ERC721DataFacet", - "ERC721MintFacet", - "ERC721BurnFacet", - "ERC721ApproveFacet", - "ERC721TransferFacet", - "ERC721MetadataFacet", +import { useState, useCallback, useRef } from 'react'; +import { useHistory } from '@docusaurus/router'; + +// Facets that currently have documentation pages under `website/docs/library`. +// Keep this list in sync when library docs are added or removed. +export const FACETS = [ + { name: "DiamondInspectFacet", path: "/docs/library/diamond/DiamondInspectFacet" }, + { name: "DiamondUpgradeFacet", path: "/docs/library/diamond/DiamondUpgradeFacet" }, + { name: "OwnerDataFacet", path: "/docs/library/access/Owner/Data/OwnerDataFacet" }, + { name: "OwnerRenounceFacet", path: "/docs/library/access/Owner/Renounce/OwnerRenounceFacet" }, + { name: "OwnerTransferFacet", path: "/docs/library/access/Owner/Transfer/OwnerTransferFacet" }, + { name: "OwnerTwoStepDataFacet", path: "/docs/library/access/Owner/TwoSteps/Data/OwnerTwoStepDataFacet" }, + { name: "OwnerTwoStepRenounceFacet", path: "/docs/library/access/Owner/TwoSteps/Renounce/OwnerTwoStepRenounceFacet" }, + { name: "OwnerTwoStepTransferFacet", path: "/docs/library/access/Owner/TwoSteps/Transfer/OwnerTwoStepTransferFacet" }, + { name: "ERC20DataFacet", path: "/docs/library/token/ERC20/Data/ERC20DataFacet" }, + { name: "ERC20MetadataFacet", path: "/docs/library/token/ERC20/Metadata/ERC20MetadataFacet" }, + { name: "ERC20ApproveFacet", path: "/docs/library/token/ERC20/Approve/ERC20ApproveFacet" }, + { name: "ERC20TransferFacet", path: "/docs/library/token/ERC20/Transfer/ERC20TransferFacet" }, + { name: "ERC20BurnFacet", path: "/docs/library/token/ERC20/Burn/ERC20BurnFacet" }, + { name: "ERC20PermitFacet", path: "/docs/library/token/ERC20/Permit/ERC20PermitFacet" }, + { name: "ERC20BridgeableFacet", path: "/docs/library/token/ERC20/Bridgeable/ERC20BridgeableFacet" }, ]; +const HIDE_DELAY_MS = 400; + export function useFacetBadges() { - const [activeFacetName, setActiveFacetName] = useState(null); - - // Map random names to IDs to keep them consistent during a session if we wanted, - // but for now we just pick a random one on hover entry if it's not already set. - const [facetMap] = useState(() => new Map()); + const history = useHistory(); + const [activeFacet, setActiveFacet] = useState(null); + const facetMapRef = useRef(new Map()); + const badgeHoveredRef = useRef(false); + const hideTimerRef = useRef(null); + + const clearHideTimer = useCallback(() => { + if (hideTimerRef.current) { + clearTimeout(hideTimerRef.current); + hideTimerRef.current = null; + } + }, []); + + const scheduleHide = useCallback(() => { + clearHideTimer(); + hideTimerRef.current = setTimeout(() => { + if (!badgeHoveredRef.current) setActiveFacet(null); + }, HIDE_DELAY_MS); + }, [clearHideTimer]); const handleHover = useCallback((facetId) => { if (facetId === -1) { - setActiveFacetName(null); + scheduleHide(); return; } - // If we haven't assigned a name to this ID yet, pick one randomly - if (!facetMap.has(facetId)) { - const randomName = FACET_NAMES[Math.floor(Math.random() * FACET_NAMES.length)]; - facetMap.set(facetId, randomName); + clearHideTimer(); + + // Assign a stable facet to each hovered geometry facet id + if (!facetMapRef.current.has(facetId)) { + const facet = FACETS[Math.floor(Math.random() * FACETS.length)]; + facetMapRef.current.set(facetId, facet); } - setActiveFacetName(facetMap.get(facetId)); - }, [facetMap]); + setActiveFacet(facetMapRef.current.get(facetId)); + }, [clearHideTimer, scheduleHide]); + + // Keep the badge alive while the pointer is on it so the link is clickable + const handleBadgeEnter = useCallback(() => { + badgeHoveredRef.current = true; + clearHideTimer(); + }, [clearHideTimer]); + + const handleBadgeLeave = useCallback(() => { + badgeHoveredRef.current = false; + setActiveFacet(null); + }, []); + + // Clicking a hovered facet on the 3D diamond opens its docs page + const handleFacetClick = useCallback((facetId) => { + const facet = facetMapRef.current.get(facetId); + if (facet) { + history.push(facet.path); + } + }, [history]); - return { activeFacetName, handleHover }; + return { activeFacet, handleHover, handleBadgeEnter, handleBadgeLeave, handleFacetClick }; } diff --git a/website/src/components/README.md b/website/src/components/README.md index e9238862..6952eb63 100644 --- a/website/src/components/README.md +++ b/website/src/components/README.md @@ -8,8 +8,8 @@ This directory contains all reusable React components for the Docusaurus documen Fundamental, reusable UI building blocks. - `Accordion` - Collapsible content sections - `Badge` - Status and category badges -- `Callout` - Informational callout boxes -- `CalloutBox` - Enhanced callout with icons +- `Callout` - Admonition-style callouts (7 types, collapsible variant) +- `CalloutBox` - Deprecated alias of `Callout` (kept for existing pages) - `GlassCard` - Card with glass morphism effect - `GradientButton` - Button with gradient styling - `GradientText` - Text with gradient effects diff --git a/website/src/components/api/ParameterTable/styles.module.css b/website/src/components/api/ParameterTable/styles.module.css index 86e77886..d7afec25 100644 --- a/website/src/components/api/ParameterTable/styles.module.css +++ b/website/src/components/api/ParameterTable/styles.module.css @@ -1,12 +1,12 @@ /* ParameterTable Component */ .parameterTable { - margin: 1.5rem 0; + margin: 1.25rem 0; } .tableTitle { - font-size: 1.25rem; + font-size: 1.125rem; font-weight: 700; - margin-bottom: 1rem; + margin-bottom: 0.75rem; color: var(--ifm-heading-color); } @@ -33,10 +33,10 @@ } .table th { - padding: 0.875rem 1rem; + padding: 0.625rem 0.875rem; text-align: left; font-weight: 600; - font-size: 0.875rem; + font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ifm-heading-color); @@ -49,10 +49,10 @@ } .table td { - padding: 0.875rem 1rem; + padding: 0.625rem 0.875rem; border-bottom: 1px solid var(--ifm-color-emphasis-200); color: var(--ifm-font-color-base); - font-size: 0.9375rem; + font-size: 0.875rem; } [data-theme='dark'] .table td { diff --git a/website/src/components/api/PropertyTable/styles.module.css b/website/src/components/api/PropertyTable/styles.module.css index c50a2be5..9ceb83aa 100644 --- a/website/src/components/api/PropertyTable/styles.module.css +++ b/website/src/components/api/PropertyTable/styles.module.css @@ -115,11 +115,11 @@ } .table th:first-child { - padding-left: 1.5rem; + padding-left: 1.125rem; } .table th:last-child { - padding-right: 1.5rem; + padding-right: 1.125rem; } /* Table Body */ @@ -145,7 +145,7 @@ } .table td { - padding: 1rem; + padding: 0.75rem; font-size: 0.875rem; color: var(--ifm-font-color-base); vertical-align: top; @@ -156,11 +156,11 @@ } .table td:first-child { - padding-left: 1.5rem; + padding-left: 1.125rem; } .table td:last-child { - padding-right: 1.5rem; + padding-right: 1.125rem; } /* Column Styles */ diff --git a/website/src/components/docs/DocCard/styles.module.css b/website/src/components/docs/DocCard/styles.module.css index b708e1dd..aeae5fbc 100644 --- a/website/src/components/docs/DocCard/styles.module.css +++ b/website/src/components/docs/DocCard/styles.module.css @@ -3,15 +3,15 @@ .docCard { display: flex; align-items: center; - gap: 1.25rem; - padding: 2rem; + gap: 1rem; + padding: 1.5rem; text-decoration: none; color: inherit; position: relative; overflow: hidden; isolation: isolate; cursor: pointer; - border-radius: 1.25rem; + border-radius: 0.75rem; background: linear-gradient(155deg, #ffffff 0%, #f1f5f9 55%, #f8fafc 100%); border: 1px solid rgba(15, 23, 42, 0.08); box-shadow: @@ -118,9 +118,9 @@ display: flex; align-items: center; justify-content: center; - width: 3.5rem; - height: 3.5rem; - border-radius: 0.75rem; + width: 2.75rem; + height: 2.75rem; + border-radius: 0.625rem; position: relative; z-index: 1; color: var(--compose-primary-500); @@ -143,7 +143,7 @@ } .iconEmoji { - font-size: 2rem; + font-size: 1.5rem; line-height: 1; } @@ -156,8 +156,8 @@ } .docCardTitle { - margin: 0 0 0.5rem 0; - font-size: 1.125rem; + margin: 0 0 0.3rem 0; + font-size: 1rem; font-weight: 750; letter-spacing: -0.025em; line-height: 1.22; @@ -166,8 +166,8 @@ .docCardDescription { margin: 0; - font-size: 0.96875rem; - line-height: 1.65; + font-size: 0.875rem; + line-height: 1.55; color: #334155; } @@ -286,117 +286,117 @@ /* Card Sizes */ .docCard--small { - padding: 1.25rem 1.5rem; - gap: 1rem; - border-radius: 1.125rem; + padding: 1rem 1.125rem; + gap: 0.875rem; + border-radius: 0.75rem; } .docCard--small .docCardIcon { - width: 2.5rem; - height: 2.5rem; - border-radius: 0.625rem; + width: 2.125rem; + height: 2.125rem; + border-radius: 0.5rem; } .docCard--small .iconEmoji { - font-size: 1.5rem; + font-size: 1.25rem; } .docCard--small .docCardTitle { - font-size: 1rem; + font-size: 0.9375rem; font-weight: 700; } .docCard--small .docCardDescription { - font-size: 0.9375rem; + font-size: 0.875rem; } .docCard--large { - padding: 2.5rem; - gap: 1.5rem; + padding: 1.75rem; + gap: 1.25rem; } .docCard--large .docCardIcon { - width: 4rem; - height: 4rem; + width: 3.25rem; + height: 3.25rem; } .docCard--large .iconEmoji { - font-size: 2.5rem; + font-size: 1.875rem; } .docCard--large .docCardTitle { - font-size: 1.3125rem; + font-size: 1.1875rem; } /* DocCardGrid — match homepage features grid rhythm */ .docCardGrid { display: grid; grid-template-columns: repeat(var(--grid-columns, 2), 1fr); - gap: 2rem; - margin: 2rem 0; + gap: 1rem; + margin: 1.25rem 0; } @media (min-width: 997px) and (max-width: 1200px) { .docCardGrid { - grid-template-columns: 1fr; - gap: 1.5rem; + grid-template-columns: repeat(var(--grid-columns, 2), 1fr); + gap: 1rem; } } @media (min-width: 1201px) and (max-width: 1400px) { .docCardGrid { grid-template-columns: repeat(var(--grid-columns, 2), 1fr); - gap: 1.5rem; + gap: 1.125rem; } } @media (min-width: 1401px) { .docCardGrid { grid-template-columns: repeat(var(--grid-columns, 2), 1fr); - gap: 2rem; + gap: 1.125rem; } } @media (max-width: 996px) { .docCardGrid { grid-template-columns: 1fr; - gap: 1.25rem; + gap: 0.875rem; } } @media (min-width: 997px) and (max-width: 1200px) { .docCard { - padding: 1.75rem; - gap: 1.125rem; + padding: 1.375rem; + gap: 0.875rem; } .docCardIcon { - width: 3.25rem; - height: 3.25rem; + width: 2.5rem; + height: 2.5rem; } } @media (max-width: 768px) { .docCard { - padding: 1.75rem 1.5rem 2rem; - gap: 1rem; + padding: 1.25rem; + gap: 0.875rem; } .docCardIcon { - width: 3rem; - height: 3rem; + width: 2.5rem; + height: 2.5rem; } .iconEmoji { - font-size: 1.75rem; + font-size: 1.375rem; } .docCardTitle { - font-size: 1.1875rem; + font-size: 1.0625rem; } .docCardDescription { - font-size: 0.9375rem; + font-size: 0.875rem; } } diff --git a/website/src/components/docs/DocHero/styles.module.css b/website/src/components/docs/DocHero/styles.module.css index 07bc4021..f3b32a2d 100644 --- a/website/src/components/docs/DocHero/styles.module.css +++ b/website/src/components/docs/DocHero/styles.module.css @@ -4,11 +4,11 @@ display: flex; align-items: center; justify-content: center; - padding: 4rem 2rem; + padding: 2.5rem 1.5rem; background: linear-gradient(135deg, #0a0a0a 0%, #1a1a1a 100%); overflow: hidden; - margin-bottom: 3rem; - border-radius: 1.5rem; + margin-bottom: 2rem; + border-radius: 1.25rem; } /* Background Image Support */ @@ -53,32 +53,32 @@ .docHeroTitle { font-family: var(--ifm-heading-font-family); - margin: 0 0 1.5rem 0; - font-size: 3rem; - font-weight: 800; + margin: 0 0 0.75rem 0; + font-size: 2.25rem; + font-weight: 700; letter-spacing: -0.02em; background: linear-gradient(180deg, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0.85) 100%) !important; -webkit-background-clip: text !important; -webkit-text-fill-color: transparent !important; background-clip: text !important; - line-height: 1.1; + line-height: 1.15; } .docHeroSubtitle { - margin: 0 auto 2rem auto; - font-size: 1.25rem; + margin: 0 auto 1rem auto; + font-size: 1rem; font-weight: 400; background: linear-gradient(180deg, rgba(255, 255, 255, 0.95) 0%, rgba(255, 255, 255, 0.7) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; - line-height: 1.6; + line-height: 1.5; max-width: 700px; } /* Button spacing in hero */ .docHeroContent > * + * { - margin-top: 2rem; + margin-top: 1rem; } /* Variants */ @@ -108,56 +108,56 @@ /* Height variants */ .docHero--small { - padding: 3rem 2rem; + padding: 1.75rem 1.25rem; } .docHero--small .docHeroTitle { - font-size: 2.25rem; + font-size: 1.625rem; } .docHero--small .docHeroSubtitle { - font-size: 1.125rem; + font-size: 0.9375rem; } .docHero--medium { - padding: 5rem 2rem; + padding: 2.5rem 1.25rem; } .docHero--large { - padding: 8rem 2rem; + padding: 3rem 1.25rem; } .docHero--large .docHeroTitle { - font-size: 3.5rem; + font-size: 2.5rem; } .docHero--large .docHeroSubtitle { - font-size: 1.5rem; + font-size: 1.0625rem; } .docHero--full { - min-height: 70vh; - padding: 6rem 2rem; + min-height: 40vh; + padding: 2.75rem 1.25rem; } .docHero--full .docHeroTitle { - font-size: 4rem; + font-size: 2.75rem; } .docHero--full .docHeroSubtitle { - font-size: 1.75rem; + font-size: 1.125rem; } /* DocHeroSection */ .docHeroSection { - padding: 3rem 0; + padding: 1.75rem 0; } .docHeroSectionTitle { text-align: center; - font-size: 2rem; + font-size: 1.5rem; font-weight: 700; - margin-bottom: 2.5rem; + margin-bottom: 1.25rem; color: var(--ifm-heading-color); } @@ -168,78 +168,78 @@ /* Responsive */ @media (max-width: 996px) { .docHero { - padding: 4rem 1.5rem; + padding: 2rem 1rem; } .docHeroTitle { - font-size: 2.5rem; + font-size: 1.875rem; } .docHeroSubtitle { - font-size: 1.125rem; + font-size: 0.9375rem; } .docHero--large { - padding: 6rem 1.5rem; + padding: 2.5rem 1rem; } .docHero--large .docHeroTitle { - font-size: 3rem; + font-size: 2.125rem; } .docHero--full { - min-height: 50vh; - padding: 5rem 1.5rem; + min-height: 35vh; + padding: 2.5rem 1rem; } .docHero--full .docHeroTitle { - font-size: 3rem; + font-size: 2.25rem; } } @media (max-width: 768px) { .docHero { - padding: 3rem 1.25rem; + padding: 1.5rem 0.875rem; } .docHeroTitle { - font-size: 2rem; + font-size: 1.625rem; } .docHeroSubtitle { - font-size: 1rem; + font-size: 0.875rem; } .docHero--small { - padding: 2rem 1.25rem; + padding: 1.25rem 0.875rem; } .docHero--small .docHeroTitle { - font-size: 1.75rem; + font-size: 1.4375rem; } .docHero--large { - padding: 4rem 1.25rem; + padding: 2rem 0.875rem; } .docHero--large .docHeroTitle { - font-size: 2.25rem; + font-size: 1.875rem; } .docHero--large .docHeroSubtitle { - font-size: 1.125rem; + font-size: 0.9375rem; } .docHero--full { - min-height: 40vh; + min-height: 32vh; } .docHero--full .docHeroTitle { - font-size: 2.5rem; + font-size: 1.875rem; } .docHero--full .docHeroSubtitle { - font-size: 1.125rem; + font-size: 0.9375rem; } } diff --git a/website/src/components/docs/DocPageAside/index.js b/website/src/components/docs/DocPageAside/index.js index cf79c429..a288fa48 100644 --- a/website/src/components/docs/DocPageAside/index.js +++ b/website/src/components/docs/DocPageAside/index.js @@ -26,7 +26,7 @@ export default function DocPageAside({ soloInSidebar = false }) { target="_blank" rel="noopener noreferrer" > - + Report issue ); diff --git a/website/src/components/docs/DocPageAside/styles.module.css b/website/src/components/docs/DocPageAside/styles.module.css index 3b177612..cd3cb14f 100644 --- a/website/src/components/docs/DocPageAside/styles.module.css +++ b/website/src/components/docs/DocPageAside/styles.module.css @@ -1,6 +1,6 @@ .aside { - margin-top: 1.25rem; - padding-top: 1.25rem; + margin-top: 1rem; + padding-top: 0.875rem; border-top: 1px solid var(--ifm-color-emphasis-200); } @@ -45,10 +45,10 @@ .reportLink { display: inline-flex; align-items: center; - gap: 0.375rem; - font-size: 0.8125rem; + gap: 0.3rem; + font-size: 0.75rem; font-weight: 500; - color: var(--ifm-color-emphasis-700); + color: var(--ifm-font-color-base); text-decoration: none; } @@ -57,10 +57,6 @@ text-decoration: none; } -[data-theme='dark'] .reportLink { - color: var(--ifm-color-emphasis-600); -} - [data-theme='dark'] .reportLink :global(img) { filter: brightness(0) invert(1); } diff --git a/website/src/components/docs/PackageImport/styles.module.css b/website/src/components/docs/PackageImport/styles.module.css index f67a4ae0..ca01d7b1 100644 --- a/website/src/components/docs/PackageImport/styles.module.css +++ b/website/src/components/docs/PackageImport/styles.module.css @@ -4,6 +4,7 @@ gap: 0.75rem; overflow-x: auto; padding-bottom: 1rem; + flex-wrap: nowrap; } .label { @@ -15,12 +16,16 @@ } .code { + flex: 1 1 auto; + min-width: 0; font-family: var(--ifm-font-family-monospace); font-size: 0.875rem; line-height: 1.6; white-space: pre; color: var(--ifm-color-primary-dark); - background-color: var(--ifm-background-surface-color); + background: transparent !important; + border: none !important; + padding: 0 !important; } .copyButton { @@ -61,11 +66,6 @@ color: var(--ifm-color-emphasis-600); } -[data-theme='dark'] .packageImport { - border-color: #1e293b; - background: #0f172a; -} - [data-theme='dark'] .label { color: #64748b; } @@ -83,7 +83,7 @@ @media (max-width: 768px) { .packageImport { border-radius: 0.375rem; - flex-wrap: wrap; + flex-wrap: nowrap; } .label { @@ -91,10 +91,6 @@ margin-bottom: -0.25rem; } - .code { - width: 100%; - } - .copyButton { margin-left: auto; } diff --git a/website/src/components/docs/WasThisHelpful/index.js b/website/src/components/docs/WasThisHelpful/index.js index 3f3a0f0b..5acaa4cd 100644 --- a/website/src/components/docs/WasThisHelpful/index.js +++ b/website/src/components/docs/WasThisHelpful/index.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useEffect, useState } from 'react'; import clsx from 'clsx'; import { useColorMode } from '@docusaurus/theme-common'; import Icon from '../../ui/Icon'; @@ -51,6 +51,18 @@ export default function WasThisHelpful({ const [feedback, setFeedback] = useState(null); const [comment, setComment] = useState(''); const [submitted, setSubmitted] = useState(false); + const [fadingOut, setFadingOut] = useState(false); + const [dismissed, setDismissed] = useState(false); + + useEffect(() => { + if (!submitted) return undefined; + const fadeTimer = setTimeout(() => setFadingOut(true), 4000); + const dismissTimer = setTimeout(() => setDismissed(true), 4450); + return () => { + clearTimeout(fadeTimer); + clearTimeout(dismissTimer); + }; + }, [submitted]); const thumbUpName = colorMode === 'dark' ? 'thumbs-up-dark' : 'thumbs-up'; const thumbDownName = colorMode === 'dark' ? 'thumbs-down-dark' : 'thumbs-down'; @@ -107,6 +119,13 @@ export default function WasThisHelpful({ }; if (submitted) { + if (dismissed) { + if (variant === 'aside' && asideEndSlot) { + return
{asideEndSlot}
; + } + return null; + } + const submittedBody = ( <> {submittedBody} @@ -144,7 +164,8 @@ export default function WasThisHelpful({
{submittedBody} @@ -161,7 +182,7 @@ export default function WasThisHelpful({ onClick={handleAsideYes} aria-label="Yes, this was helpful" > - + Yes
@@ -227,7 +248,7 @@ export default function WasThisHelpful({ > - Ready to build with Compose? + Build your next system one facet at a time.

- Install Compose and put together a diamond-based system you can grow one facet at a time. + Start with a working project, add reusable Solidity building blocks, and keep your custom logic easy to understand.

- Get started + Start Building - Installation + Read the Docs
diff --git a/website/src/components/home/FeaturesSection.js b/website/src/components/home/FeaturesSection.js index f5ec75f3..cd8b8f6f 100644 --- a/website/src/components/home/FeaturesSection.js +++ b/website/src/components/home/FeaturesSection.js @@ -5,39 +5,39 @@ export default function FeaturesSection() { const features = [ { kicker: 'Design principle', - title: 'Read First', - description: 'Code written to be understood first, not just executed. Every facet is self-contained and readable top-to-bottom.', + title: 'Readable by Design', + description: 'Keep each facet focused, self-contained, and understandable from top to bottom.', link: '/docs/design/written-to-be-read', }, { kicker: 'ERC-2535 / ERC-8153', title: 'Diamond-Native', - description: 'Deploy facets once, reuse them across multiple diamonds on chain.', + description: 'Build modular systems around the ERC-2535 Diamond architecture and its shared storage model.', link: '/docs/foundations/diamond-contracts', }, { kicker: 'Architecture', - title: 'Composition Over Inheritance', - description: 'Combine deployed facets instead of inheriting contracts. Build systems from simple, reusable pieces.', + title: 'Composable Architecture', + description: 'Assemble systems from focused facets and modules instead of coupling functionality through inheritance.', link: '/docs/design/design-for-composition', }, { - kicker: 'SCOP', - title: 'Intentional Simplicity', - description: 'Smart Contract Oriented Programming (SCOP) - designed specifically for smart contracts, not general software.', + kicker: 'Smart Contract Oriented Programming', + title: 'Domain-Specific Discipline', + description: 'Use deliberate Solidity constraints and conventions designed for the realities of smart contract development.', link: '/docs/design', }, { - kicker: 'Roadmap', - title: 'On-chain Standard Library', - description: '(In the future) Access verified, audited facets deployed on multiple blockchains.', - link: '/docs/foundations/onchain-contract-library', + kicker: 'Developer tooling', + title: 'A Structured Starting Point', + description: 'Scaffold a diamond project with the Compose CLI, then develop with the Foundry or Hardhat workflow you already use.', + link: '/docs/getting-started/installation', }, { - kicker: 'Ecosystem', - title: 'Community-Driven', - description: 'Built with love by the community. Join us in creating the standard library for ERC-2535 / ERC-8153 Diamonds.', - link: '/docs/contribution/how-to-contribute', + kicker: 'Extensibility', + title: 'Built to Evolve', + description: 'Add custom facets that work with Compose modules and shared diamond storage as your system develops.', + link: '/docs/foundations/custom-facets', }, ]; @@ -47,17 +47,10 @@ export default function FeaturesSection() {
Why Compose - Rethinking Smart Contract Development + Architecture onchain applications can rely on

- Forget traditional smart contract design patterns. Compose takes a radically - different approach with Smart Contract Oriented Programming (SCOP). -

-
-

- We focus on building small, independent, and easy-to-understand smart contracts called facets. - Each facet is designed to be deployed once, then reused and composed seamlessly with others to form - complete smart contract systems. + Compose gives teams a structured foundation for building, extending, and maintaining modular smart contract systems.

diff --git a/website/src/components/home/HomepageHeader.js b/website/src/components/home/HomepageHeader.js index f94473b7..9dd4cc65 100644 --- a/website/src/components/home/HomepageHeader.js +++ b/website/src/components/home/HomepageHeader.js @@ -10,14 +10,19 @@ import { FacetBadge } from '../DiamondScene/FacetBadge'; import { useIsMobile } from '../../hooks/useIsMobile'; export default function HomepageHeader() { - const { activeFacetName, handleHover } = useFacetBadges(); + const { + activeFacet, + handleHover, + handleBadgeEnter, + handleBadgeLeave, + handleFacetClick, + } = useFacetBadges(); const isMobile = useIsMobile(); const badgeAndTitle = ( <> - Build the future of
- Smart Contracts + Infrastructure for evolving
onchain systems
); @@ -26,14 +31,12 @@ export default function HomepageHeader() { <>

- On-chain infrastructure should be shared, not rebuilt. -
- Compose is the composition toolkit for modular on-chain systems. + A framework for modular, maintainable smart contracts.

- - Get Started + + Start Building - - Read Our Whitepaper + + Read the whitepaper
@@ -62,8 +65,17 @@ export default function HomepageHeader() {
{!isMobile && ( <> - - + + )} diff --git a/website/src/components/home/StatsSection.js b/website/src/components/home/StatsSection.js index 2911258f..ec3dd5d3 100644 --- a/website/src/components/home/StatsSection.js +++ b/website/src/components/home/StatsSection.js @@ -6,14 +6,14 @@ export default function StatsSection() { const {value: contributorsValue} = useGithubContributorsCount({ owner: 'Perfect-Abstractions', repo: 'Compose', - defaultValue: '17+', + defaultValue: '34+', }); const stats = [ - {label: 'Open Source', value: 'MIT', icon: 'scroll'}, - {label: 'Diamond Standard', value: 'ERC-2535/8153', icon: 'diamond'}, - {label: 'Contributors', value: contributorsValue, icon: 'community'}, - {label: 'Diamond Ecosystem TVL', value: 'Over $1B', icon: 'chart'}, + {label: 'Open-source license', value: 'MIT', icon: 'scroll'}, + {label: 'Diamond architecture', value: 'ERC-2535 + ERC-8153', icon: 'diamond'}, + {label: 'GitHub contributors', value: contributorsValue, icon: 'community'}, + {label: 'Supported workflows', value: 'Foundry + Hardhat', icon: 'package'}, ]; return ( diff --git a/website/src/components/home/codeShowcase.module.css b/website/src/components/home/codeShowcase.module.css index e26135f5..713c1ce1 100644 --- a/website/src/components/home/codeShowcase.module.css +++ b/website/src/components/home/codeShowcase.module.css @@ -1,13 +1,13 @@ /* Code Showcase Section */ -.showcaseSection { padding: 4rem 0; background: linear-gradient(180deg, #f8fafc 0%, #ffffff 100%); position: relative; overflow-x: clip; } +.showcaseSection { padding: 2.5rem 0; background: linear-gradient(180deg, #f8fafc 0%, #ffffff 100%); position: relative; overflow-x: clip; } /* minmax(0, 1fr) + min-width: 0 — without this, the code column's min-content width equals the longest pre line and blows out the grid on narrow / zoomed viewports. */ .showcaseGrid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); - gap: 4rem; + gap: 2.5rem; align-items: center; max-width: 1400px; margin: 0 auto; @@ -19,16 +19,16 @@ min-width: 0; } -.showcaseContent { padding: 0 2rem; text-align: center; display: flex; flex-direction: column; align-items: center; } -.showcaseBadge { display: inline-block; padding: 0.5rem 1rem; background: linear-gradient(135deg, rgba(59,130,246,0.1), rgba(96,165,250,0.1)); border: 1px solid rgba(59,130,246,0.2); border-radius: 9999px; color: var(--compose-primary-500); font-size: 0.875rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; margin-bottom: 1.5rem; } -.showcaseTitle { font-size: clamp(2rem, 4vw, 3rem); font-weight: 800; line-height: 1.2; letter-spacing: -0.03em; color: #0f172a; margin-bottom: 1.5rem; } -.showcaseDescription { font-size: 1.125rem; line-height: 1.8; color: #334155; margin-bottom: 2.5rem; } +.showcaseContent { padding: 0 1.5rem; text-align: center; display: flex; flex-direction: column; align-items: center; } +.showcaseBadge { display: inline-block; padding: 0.4rem 0.875rem; background: linear-gradient(135deg, rgba(59,130,246,0.1), rgba(96,165,250,0.1)); border: 1px solid rgba(59,130,246,0.2); border-radius: 9999px; color: var(--compose-primary-500); font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; margin-bottom: 1rem; } +.showcaseTitle { font-size: clamp(1.75rem, 3.5vw, 2.25rem); font-weight: 700; line-height: 1.2; letter-spacing: -0.03em; color: #0f172a; margin-bottom: 1rem; } +.showcaseDescription { font-size: 1rem; line-height: 1.55; color: #334155; margin-bottom: 1.5rem; } .showcaseFeatures { display: flex; flex-direction: column; - gap: 1.5rem; - margin-bottom: 2.5rem; + gap: 1.125rem; + margin-bottom: 1.5rem; width: 100%; max-width: 600px; align-self: stretch; @@ -42,11 +42,11 @@ position: relative; display: flex; align-items: flex-start; - gap: 1rem; + gap: 0.875rem; width: 100%; box-sizing: border-box; - padding: 1.5rem; - border-radius: 1rem; + padding: 1.125rem; + border-radius: 0.75rem; overflow: hidden; isolation: isolate; text-align: left; @@ -327,15 +327,15 @@ } } @media screen and (max-width: 768px) { - .showcaseSection { padding: 5rem 0; } + .showcaseSection { padding: 2rem 0; } .showcaseSection .container { padding-left: 0; padding-right: 0; margin-left: auto; margin-right: auto; width: 100%; } .showcaseGrid { grid-template-columns: 1fr; gap: .5rem; justify-items: stretch; margin: 0 auto; width: 100%; } .showcaseContent { padding: 0 1.5rem; width: 100%; max-width: 100%; margin: 0 auto; display: flex; flex-direction: column; align-items: center; text-align: center; } - .showcaseTitle { font-size: 1.875rem; text-align: center; } - .showcaseDescription { font-size: 1rem; margin-bottom: 2rem; text-align: center; } + .showcaseTitle { font-size: 1.625rem; text-align: center; } + .showcaseDescription { font-size: 0.9375rem; margin-bottom: 1.25rem; text-align: center; } .showcaseFeatures { gap: 1rem; width: 100%; max-width: 100%; margin-left: auto; margin-right: auto; display: flex; flex-direction: column; align-items: stretch; } .showcaseLink { margin-left: auto; margin-right: auto; } - .showcaseFeature { padding: 1.25rem; flex-direction: row; } + .showcaseFeature { padding: 1rem; flex-direction: row; } .showcaseFeature:hover { transform: translateX(4px); } .showcaseFeatureIcon { width: 40px; height: 40px; } .showcaseFeature h4 { font-size: 1rem; } @@ -348,11 +348,11 @@ } } @media screen and (max-width: 480px) { - .showcaseSection { padding: 3rem 0; } + .showcaseSection { padding: 2rem 0; } .showcaseSection .container { padding-left: 0; padding-right: 0; margin-left: auto; margin-right: auto; width: 100%; max-width: 100%; } - .showcaseGrid { display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 2.5rem; width: 100%; margin: 0 auto; padding: 0; } + .showcaseGrid { display: flex; flex-direction: column; align-items: stretch; justify-content: flex-start; gap: 2rem; width: 100%; margin: 0 auto; padding: 0; } .showcaseContent { padding: 0 1rem; width: 100%; max-width: 100%; margin: 0 auto; display: flex; flex-direction: column; align-items: center; text-align: center; } - .showcaseTitle { font-size: 1.5rem; text-align: center; } + .showcaseTitle { font-size: 1.375rem; text-align: center; } .showcaseDescription { font-size: 0.9375rem; text-align: center; } .showcaseFeatures { width: 100%; max-width: 100%; margin-left: auto; margin-right: auto; display: flex; flex-direction: column; align-items: stretch; } .showcaseFeature { width: 100%; max-width: 100%; } diff --git a/website/src/components/home/ctaSection.module.css b/website/src/components/home/ctaSection.module.css index 82c5dc62..13256735 100644 --- a/website/src/components/home/ctaSection.module.css +++ b/website/src/components/home/ctaSection.module.css @@ -3,7 +3,7 @@ .ctaSection { position: relative; /* No bottom padding — flows into stats on same --home-band-bg */ - padding: 2.5rem 0 2.5rem; + padding: 1.75rem 0 1.75rem; background: var(--home-band-bg); } @@ -15,8 +15,8 @@ .ctaBanner { position: relative; overflow: hidden; - border-radius: 2rem; - padding: clamp(2.5rem, 6vw, 3.75rem) clamp(1.5rem, 4vw, 3rem); + border-radius: 1.25rem; + padding: clamp(1.75rem, 4vw, 2.75rem) clamp(1.25rem, 3vw, 2rem); text-align: center; isolation: isolate; box-shadow: @@ -110,19 +110,19 @@ .ctaTitle { font-family: var(--ifm-font-family-base); - font-size: clamp(1.65rem, 4.2vw, 2.35rem); + font-size: clamp(1.5rem, 3.5vw, 2rem); font-weight: 700; line-height: 1.2; letter-spacing: -0.03em; color: #ffffff; - margin: 0 0 1rem; + margin: 0 0 0.75rem; text-wrap: balance; } .ctaDescription { - margin: 0 auto 1.75rem; - font-size: clamp(0.95rem, 2vw, 1.0625rem); - line-height: 1.65; + margin: 0 auto 1.25rem; + font-size: clamp(0.875rem, 1.8vw, 0.96875rem); + line-height: 1.55; color: rgba(255, 255, 255); max-width: 32rem; } @@ -132,16 +132,16 @@ flex-wrap: wrap; align-items: center; justify-content: center; - gap: 0.75rem 1rem; + gap: 0.625rem 0.875rem; } .ctaButton { display: inline-flex; align-items: center; justify-content: center; - gap: 0.5rem; - padding: 0.85rem 1.5rem; - font-size: 0.9375rem; + gap: 0.4rem; + padding: 0.75rem 1.25rem; + font-size: 0.875rem; font-weight: 600; font-family: var(--ifm-font-family-base); border-radius: 9999px; diff --git a/website/src/components/home/featuresSection.module.css b/website/src/components/home/featuresSection.module.css index cc8f0898..999dcd2a 100644 --- a/website/src/components/home/featuresSection.module.css +++ b/website/src/components/home/featuresSection.module.css @@ -1,7 +1,7 @@ /* Features Section — faceted glass cards */ .featuresSection { - padding: 1rem 0 4rem 0; + padding: 0.5rem 0 2.5rem 0; background: #ffffff; position: relative; isolation: isolate; @@ -10,42 +10,42 @@ .sectionHeader { text-align: center; max-width: 760px; - margin: 0 auto 5rem; + margin: 0 auto 2.5rem; position: relative; z-index: 1; } .sectionBadge { display: inline-block; - padding: 0.5rem 1rem; + padding: 0.4rem 0.875rem; background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(37, 99, 235, 0.1)); border: 1px solid rgba(59, 130, 246, 0.2); border-radius: 9999px; color: var(--compose-primary-500); - font-size: 0.875rem; + font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; - margin-bottom: 1.5rem; + margin-bottom: 1rem; } .sectionTitle { - font-size: clamp(2.25rem, 5vw, 2.5rem); - font-weight: 800; + font-size: clamp(1.75rem, 4vw, 2rem); + font-weight: 700; line-height: 1.2; letter-spacing: -0.03em; color: #0f172a; - margin-bottom: 1.5rem; + margin-bottom: 1rem; } .sectionSubtitle { - font-size: clamp(1rem, 2vw, 1.2rem); - line-height: 1.7; + font-size: clamp(0.9375rem, 1.8vw, 1.0625rem); + line-height: 1.55; color: #334155; margin: 0; } .featuresGrid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); - gap: 2rem; + grid-template-columns: repeat(3, 1fr); + gap: 1.5rem; max-width: 1280px; margin: 0 auto; position: relative; @@ -57,7 +57,12 @@ height: 100%; text-decoration: none; color: inherit; - border-radius: 1.25rem; + border-radius: 0.75rem; +} + +.featureCardLink:focus-visible { + outline: 2px solid var(--compose-primary-500); + outline-offset: 4px; } .featureCard { @@ -65,8 +70,8 @@ height: 100%; display: flex; flex-direction: column; - padding: 2rem 2rem 2.25rem; - border-radius: 1.25rem; + padding: 1.5rem 1.5rem 1.75rem; + border-radius: 0.75rem; overflow: hidden; isolation: isolate; /* Light: paper + crisp edge */ @@ -84,7 +89,7 @@ } .featureMeta { - margin-bottom: 1rem; + margin-bottom: 0.75rem; position: relative; z-index: 1; } @@ -101,22 +106,22 @@ .featureTitle { position: relative; z-index: 1; - font-size: 1.3125rem; + font-size: 1.1875rem; font-weight: 750; letter-spacing: -0.025em; line-height: 1.22; color: #0f172a; - margin: 0 0 0.65rem; + margin: 0 0 0.5rem; } .featureDescription { position: relative; z-index: 1; flex: 1; - font-size: 0.96875rem; - line-height: 1.65; + font-size: 0.9375rem; + line-height: 1.55; color: #334155; - margin: 0 0 1rem; + margin: 0 0 0.75rem; } .featureHint { @@ -201,18 +206,18 @@ /* Responsive */ @media screen and (max-width: 1024px) { - .featuresGrid { grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: 1.5rem; } + .featuresGrid { grid-template-columns: repeat(2, 1fr); gap: 1.25rem; } } @media screen and (max-width: 768px) { - .featuresSection { padding: 2rem 0 4rem 0; } - .sectionHeader { margin-bottom: 3rem; } - .sectionTitle { font-size: 2rem; margin-bottom: 1rem; } - .sectionSubtitle { font-size: 1rem; } - .featuresGrid { grid-template-columns: 1fr; gap: 1.25rem; } - .featureCard { padding: 1.75rem 1.5rem 2rem; } - .featureMeta { margin-bottom: 0.9rem; } - .featureTitle { font-size: 1.1875rem; } - .featureDescription { font-size: 0.9375rem; } + .featuresSection { padding: 1rem 0 2.5rem 0; } + .sectionHeader { margin-bottom: 2rem; } + .sectionTitle { font-size: 1.75rem; margin-bottom: 0.75rem; } + .sectionSubtitle { font-size: 0.9375rem; } + .featuresGrid { grid-template-columns: 1fr; gap: 1rem; } + .featureCard { padding: 1.25rem 1.125rem 1.5rem; } + .featureMeta { margin-bottom: 0.65rem; } + .featureTitle { font-size: 1.0625rem; } + .featureDescription { font-size: 0.875rem; } } /* Dark mode — higher contrast glass, visible facet edge */ diff --git a/website/src/components/home/homepageHeader.module.css b/website/src/components/home/homepageHeader.module.css index ca15f79b..7d0d6999 100644 --- a/website/src/components/home/homepageHeader.module.css +++ b/website/src/components/home/homepageHeader.module.css @@ -2,7 +2,7 @@ .heroBanner { position: relative; - padding: 10rem 0 14rem; + padding: 6.5rem 0rem 14rem 0rem; overflow: hidden; min-height: auto; display: flex; @@ -41,6 +41,16 @@ z-index: 1; /* Removed grid to allow full overlay */ width: 100%; + /* Click-through so the diamond canvas below stays clickable */ + pointer-events: none; +} + +.heroContent { + pointer-events: auto; +} + +.heroWave { + pointer-events: none; } /* Canvas container is now absolute and full width to allow particles everywhere */ @@ -54,8 +64,8 @@ } /* ----- Mobile: content around small centered diamond ----- */ -.heroBannerMobile { - padding: 3rem 0 4rem; + .heroBannerMobile { + padding: 2.25rem 0 3rem; align-items: flex-start; } @@ -66,6 +76,7 @@ width: 100%; max-width: 100%; text-align: center; + pointer-events: auto; } .heroContentTop { @@ -79,12 +90,12 @@ .diamondSlot { position: relative; width: 100%; - height: 260px; - min-height: 260px; + height: 200px; + min-height: 200px; display: flex; align-items: center; justify-content: center; - margin: 0.75rem 0; + margin: 0.5rem 0; } .diamondInline { @@ -104,21 +115,21 @@ margin-right: auto; /* Pushes content to the left side if container is flex, but block is fine */ } -.badgeWrapper { margin-bottom: 2rem; animation: fadeInDown var(--motion-duration-normal) var(--motion-ease-standard); } +.badgeWrapper { margin-bottom: 1.25rem; animation: fadeInDown var(--motion-duration-normal) var(--motion-ease-standard); } .badge { position: relative; display: inline-flex; align-items: center; - gap: 0.625rem; - padding: 0.75rem 1.5rem; + gap: 0.5rem; + padding: 0.5rem 1.125rem; background: rgba(255, 255, 255, 0.05); backdrop-filter: blur(16px); -webkit-backdrop-filter: blur(16px); border: 1px solid rgba(255, 255, 255, 0.1); border-radius: 9999px; color: rgba(255, 255, 255, 0.95); - font-size: 0.875rem; + font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.025em; box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15); @@ -126,12 +137,12 @@ .heroTitle { font-family: var(--ifm-heading-font-family); - font-size: clamp(2.5rem, 5vw, 4rem); /* Reduced max size from 5rem to 4rem */ - font-weight: 900; - line-height: 1.2; + font-size: clamp(2.25rem, 4.5vw, 3.25rem); + font-weight: 800; + line-height: 1.15; letter-spacing: -0.04em; color: white; - margin-bottom: 1.5rem; + margin-bottom: 1rem; animation: fadeInUp var(--motion-duration-normal) var(--motion-ease-standard) 0.2s both; } @@ -145,24 +156,24 @@ .heroDescriptionWrapper { position: relative; - margin-bottom: 3rem; + margin-bottom: 2rem; max-width: 640px; animation: fadeInUp var(--motion-duration-normal) var(--motion-ease-standard) 0.3s both; } .heroSubtitle { - font-size: clamp(1rem, 4vw, 1.3rem); + font-size: clamp(0.9375rem, 3vw, 1.125rem); color: #ffffff; font-weight: 600; - line-height: 1.6; - margin-bottom: 0.75rem; + line-height: 1.5; + margin-bottom: 0.5rem; } .heroDescription { - font-size: clamp(0.9375rem, 1.5vw, 1.0625rem); + font-size: clamp(0.875rem, 1.4vw, 0.96875rem); color: rgba(255, 255, 255, 0.9); font-weight: 500; - line-height: 1.6; + line-height: 1.55; max-width: 100%; margin: 0; padding: 0; @@ -172,9 +183,9 @@ display: flex; align-items: center; justify-content: flex-start; - gap: 0.75rem 1rem; + gap: 0.625rem 0.875rem; flex-wrap: wrap; - margin-bottom: 1.5rem; + margin-bottom: 1rem; animation: fadeInUp var(--motion-duration-normal) var(--motion-ease-standard) 0.5s both; } @@ -183,9 +194,9 @@ display: inline-flex; align-items: center; justify-content: center; - gap: 0.5rem; - padding: 0.85rem 1.5rem; - font-size: 0.9375rem; + gap: 0.4rem; + padding: 0.75rem 1.25rem; + font-size: 0.875rem; font-weight: 600; border-radius: 9999px; text-decoration: none; @@ -300,7 +311,7 @@ /* Responsive */ @media screen and (max-width: 1024px) { - .heroBanner:not(.heroBannerMobile) { padding: 8rem 0 10rem; min-height: 80vh; } + .heroBanner:not(.heroBannerMobile) { padding: 4.5rem 0 6rem; min-height: auto; } .heroContent { text-align: center; @@ -309,7 +320,7 @@ } .heroDescriptionWrapper { - margin: 0 auto 1.5rem; + margin: 0 auto 1.25rem; text-align: center; } @@ -333,13 +344,13 @@ /* Mobile grid layout uses heroBannerMobile; these refine non-mobile tablet only */ @media screen and (max-width: 768px) { - .heroBanner:not(.heroBannerMobile) { padding: 6rem 0 8rem; min-height: auto; } - .heroTitle { font-size: 2.5rem; margin-bottom: 1rem; } - .heroSubtitle { font-size: 1.125rem; margin-bottom: 1rem; } - .heroDescription { font-size: 1rem;} - .heroBanner:not(.heroBannerMobile) .heroCta { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 0.75rem; margin-bottom: 2rem; } + .heroBanner:not(.heroBannerMobile) { padding: 3.5rem 0 5rem; min-height: auto; } + .heroTitle { font-size: 2.125rem; margin-bottom: 0.75rem; } + .heroSubtitle { font-size: 1rem; margin-bottom: 0.5rem; } + .heroDescription { font-size: 0.9375rem;} + .heroBanner:not(.heroBannerMobile) .heroCta { flex-direction: row; flex-wrap: wrap; justify-content: center; gap: 0.625rem; margin-bottom: 1.25rem; } .heroBanner:not(.heroBannerMobile) .ctaButton { width: auto; flex: 0 1 auto; justify-content: center; } - .heroBanner:not(.heroBannerMobile) .heroLinks { flex-direction: column; gap: 0.75rem; } + .heroBanner:not(.heroBannerMobile) .heroLinks { flex-direction: column; gap: 0.625rem; } .heroBanner:not(.heroBannerMobile) .heroLink { width: 100%; max-width: 320px; justify-content: center; } } @@ -399,16 +410,16 @@ font-size: 0.8125rem; } .heroBannerMobile .diamondSlot { - height: 240px; - min-height: 240px; + height: 180px; + min-height: 180px; } } @media screen and (max-width: 480px) { - .heroBanner:not(.heroBannerMobile) { padding: 5rem 0 6rem; } - .heroTitle { font-size: 2rem; } - .heroSubtitle { font-size: 1rem; } - .badge { font-size: 0.8125rem; padding: 0.625rem 1.25rem; } + .heroBanner:not(.heroBannerMobile) { padding: 3rem 0 4rem; } + .heroTitle { font-size: 1.875rem; } + .heroSubtitle { font-size: 0.9375rem; } + .badge { font-size: 0.75rem; padding: 0.5rem 1rem; } .heroBannerMobile .heroTitle { font-size: 1.625rem; } @@ -425,8 +436,8 @@ height: 14px; } .heroBannerMobile .diamondSlot { - height: 200px; - min-height: 200px; + height: 160px; + min-height: 160px; } } diff --git a/website/src/components/home/statsSection.module.css b/website/src/components/home/statsSection.module.css index 1672fd7f..b1fbd776 100644 --- a/website/src/components/home/statsSection.module.css +++ b/website/src/components/home/statsSection.module.css @@ -13,7 +13,7 @@ position: relative; max-width: 1120px; margin: 0 auto; - padding: 2.5rem 0 2.75rem; + padding: 1.75rem 0 2rem; /* No top border / hairline — continues CTA band without demarcation */ } @@ -39,7 +39,7 @@ align-items: center; justify-content: flex-start; text-align: center; - padding: 1.75rem 1.25rem 1.5rem; + padding: 1.25rem 1rem 1rem; isolation: isolate; animation: statsFadeUp 0.65s var(--motion-ease-standard) both; } @@ -96,7 +96,7 @@ display: flex; align-items: center; justify-content: center; - margin-bottom: 1rem; + margin-bottom: 0.75rem; color: rgba(147, 197, 253, 0.92); opacity: 0.92; transition: @@ -112,20 +112,14 @@ } .statValue { - font-size: clamp(1.5rem, 2.1vw, 2.15rem); - font-weight: 800; + font-size: clamp(1.375rem, 1.9vw, 1.875rem); + font-weight: 700; line-height: 1.05; letter-spacing: -0.03em; - margin-bottom: 0.65rem; - background: linear-gradient( - 135deg, - #93c5fd 0%, - var(--compose-primary-500) 42%, - var(--compose-primary-600) 100% - ); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; + margin-bottom: 0.4rem; + color: #fff; + background: none; + -webkit-text-fill-color: #fff; white-space: nowrap; } @@ -170,35 +164,35 @@ @media screen and (max-width: 768px) { .statsSection { - padding: 0 0 3.5rem; + padding: 0 0 2.25rem; } [data-theme='light'] .statsSection { - padding: 0 0 3.25rem; + padding: 0 0 2.25rem; } .statsRail { - padding: 2rem 0 2.25rem; + padding: 1.5rem 0 1.5rem; } .statItem { - padding: 1.5rem 0.75rem 1.35rem; + padding: 1.125rem 0.75rem 0.875rem; } .statValue { - font-size: 1.5rem; + font-size: 1.375rem; } .statLabel { - font-size: 0.8rem; + font-size: 0.75rem; letter-spacing: 0.12em; } } /* Light theme — rail spacing only; bg stays --home-band-bg */ [data-theme='light'] .statsRail { - padding-top: 2.25rem; - padding-bottom: 2.25rem; + padding-top: 1.75rem; + padding-bottom: 1.75rem; } [data-theme='light'] .statItem:nth-child(-n + 2) { @@ -231,10 +225,11 @@ } [data-theme='light'] .statValue { - background: linear-gradient(180deg, #93c5fd 0%, #60a5fa 38%, #3b82f6 100%); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; + color: #0f172a; + background: none; + -webkit-background-clip: unset; + background-clip: unset; + -webkit-text-fill-color: #0f172a; } [data-theme='light'] .statLabel { diff --git a/website/src/components/newsletter/FooterNewsletterSignup/styles.module.css b/website/src/components/newsletter/FooterNewsletterSignup/styles.module.css index 87445760..6cc1673a 100644 --- a/website/src/components/newsletter/FooterNewsletterSignup/styles.module.css +++ b/website/src/components/newsletter/FooterNewsletterSignup/styles.module.css @@ -25,8 +25,8 @@ } .footerNewsletterDescription { - margin: 0 0 1rem 0; - font-size: 0.8125rem; + margin: 0 0 0.75rem 0; + font-size: 0.75rem; line-height: 1.5; color: rgba(255, 255, 255, 0.8); padding: 0; @@ -70,15 +70,15 @@ /* Larger desktop: maximize input field width */ @media (min-width: 997px) { .footerNewsletterInput { - min-width: 320px; - font-size: 1rem; - padding: 0.625rem 1rem; + min-width: 240px; + font-size: 0.875rem; + padding: 0.5rem 0.75rem; } - + .footerNewsletterButton { - min-width: 120px; - padding: 0.625rem 1.5rem; - font-size: 0.9375rem; + min-width: 100px; + padding: 0.5rem 1rem; + font-size: 0.875rem; } } @@ -209,7 +209,7 @@ display: flex; align-items: center; gap: 0.5rem; - font-size: 0.75rem; + font-size: 0.6875rem; color: rgba(255, 255, 255, 0.7); margin: 0.25rem 0 0 0; padding: 0; diff --git a/website/src/components/newsletter/NewsletterSignup/styles.module.css b/website/src/components/newsletter/NewsletterSignup/styles.module.css index 9914f653..917997d8 100644 --- a/website/src/components/newsletter/NewsletterSignup/styles.module.css +++ b/website/src/components/newsletter/NewsletterSignup/styles.module.css @@ -9,9 +9,9 @@ ============================================ */ .newsletterContainer { - margin: 4rem auto; - padding: 3rem; - border-radius: 1.25rem; + margin: 2.5rem auto; + padding: 1.75rem; + border-radius: 1rem; position: relative; overflow: hidden; @@ -74,7 +74,7 @@ .newsletterContent { display: flex; flex-direction: column; - gap: 2rem; + gap: 1.25rem; position: relative; z-index: 1; } @@ -99,9 +99,9 @@ display: inline-flex; align-items: center; justify-content: center; - width: 48px; - height: 48px; - border-radius: 0.75rem; + width: 40px; + height: 40px; + border-radius: 0.625rem; background: linear-gradient(135deg, rgba(59, 130, 246, 0.1) 0%, rgba(37, 99, 235, 0.15) 100%); flex-shrink: 0; transition: transform 0.3s ease; @@ -116,15 +116,15 @@ } .newsletterIcon { - width: 24px; - height: 24px; + width: 20px; + height: 20px; display: block; } .newsletterTitle { margin: 0; - font-size: 2rem; - font-weight: 800; + font-size: 1.5rem; + font-weight: 700; letter-spacing: -0.02em; line-height: 1.2; @@ -145,8 +145,8 @@ .newsletterDescription { margin: 0; color: var(--ifm-color-content-secondary); - font-size: 1.0625rem; - line-height: 1.7; + font-size: 1rem; + line-height: 1.55; font-weight: 400; } @@ -161,7 +161,7 @@ .newsletterForm { display: flex; flex-direction: column; - gap: 1.25rem; + gap: 0.875rem; } .newsletterRow { @@ -196,9 +196,9 @@ .newsletterInput { width: 100%; - padding: 1rem 1.25rem; + padding: 0.75rem 1rem; border: 2px solid var(--ifm-color-emphasis-300); - border-radius: 0.75rem; + border-radius: 0.625rem; font-size: 1rem; font-family: var(--ifm-font-family-base); font-weight: 500; @@ -255,12 +255,12 @@ .newsletterButton { position: relative; - padding: 1rem 2rem; + padding: 0.75rem 1.25rem; white-space: nowrap; - min-width: 140px; + min-width: 120px; font-weight: 700; - font-size: 1rem; - border-radius: 0.75rem; + font-size: 0.9375rem; + border-radius: 0.625rem; border: none; cursor: pointer; overflow: hidden; @@ -377,12 +377,12 @@ .newsletterMessage { display: flex; align-items: center; - gap: 0.75rem; - padding: 1rem 1.25rem; - border-radius: 0.75rem; - font-size: 0.9375rem; - margin-top: 0.5rem; - line-height: 1.5; + gap: 0.625rem; + padding: 0.75rem 1rem; + border-radius: 0.625rem; + font-size: 0.875rem; + margin-top: 0.25rem; + line-height: 1.45; font-weight: 500; animation: slideIn 0.3s ease-out; } @@ -441,31 +441,31 @@ @media (max-width: 768px) { .newsletterContainer { - margin: 2.5rem 1rem; - padding: 2rem 1.5rem; - border-radius: 1rem; + margin: 1.75rem 0.75rem; + padding: 1.375rem 1.125rem; + border-radius: 0.875rem; } .newsletterTitleRow { - gap: 0.75rem; + gap: 0.625rem; } .newsletterIconWrapper { - width: 40px; - height: 40px; + width: 34px; + height: 34px; } .newsletterIcon { - width: 20px; - height: 20px; + width: 18px; + height: 18px; } .newsletterTitle { - font-size: 1.75rem; + font-size: 1.375rem; } .newsletterDescription { - font-size: 1rem; + font-size: 0.9375rem; } .newsletterInput, @@ -475,21 +475,21 @@ } .newsletterButton { - padding: 1rem 1.5rem; + padding: 0.75rem 1.125rem; } } @media (max-width: 480px) { .newsletterContainer { - padding: 1.75rem 1.25rem; + padding: 1.25rem 1rem; } .newsletterTitle { - font-size: 1.5rem; + font-size: 1.25rem; } .newsletterContent { - gap: 1.5rem; + gap: 1.125rem; } } diff --git a/website/src/components/ui/AnnouncementBanner/index.js b/website/src/components/ui/AnnouncementBanner/index.js index 3b6a8567..22d5f9a4 100644 --- a/website/src/components/ui/AnnouncementBanner/index.js +++ b/website/src/components/ui/AnnouncementBanner/index.js @@ -100,7 +100,7 @@ export default function AnnouncementBanner({ className={styles.closeButton} onClick={handleDismiss} aria-label="Dismiss announcement"> - +
diff --git a/website/src/components/ui/AnnouncementBanner/styles.module.css b/website/src/components/ui/AnnouncementBanner/styles.module.css index f64dc8f5..f4abba07 100644 --- a/website/src/components/ui/AnnouncementBanner/styles.module.css +++ b/website/src/components/ui/AnnouncementBanner/styles.module.css @@ -5,8 +5,8 @@ display: flex; align-items: center; justify-content: center; - padding: 0.75rem 1rem; - gap: 0.75rem; + padding: 0.5rem 1rem; + gap: 0.5rem; /* Light mode: blend into navbar glass */ background: radial-gradient( circle at 50% 0%, @@ -18,7 +18,7 @@ border-bottom: 1px solid rgba(148, 163, 184, 0.22); color: #0f172a; text-shadow: 0 1px 2px rgba(255, 255, 255, 0.7); - font-size: 0.9rem; + font-size: 0.8125rem; font-weight: 600; overflow: hidden; } @@ -47,7 +47,7 @@ display: flex; align-items: center; justify-content: center; - gap: 0.75rem; + gap: 0.5rem; } .bannerInner::before { @@ -59,7 +59,7 @@ align-items: center; justify-content: center; flex-wrap: wrap; - gap: 0.5rem; + gap: 0.375rem; text-align: center; flex: 1; } @@ -76,11 +76,11 @@ } .closeButton { - border: none; - background: transparent; - color: inherit; - cursor: pointer; - padding: 0.15rem; + border: none; + background: transparent; + color: inherit; + cursor: pointer; + padding: 0.125rem; display: flex; align-items: center; justify-content: center; @@ -160,7 +160,7 @@ @media (max-width: 600px) { .banner { - font-size: 0.8rem; + font-size: 0.75rem; } .bannerInner { diff --git a/website/src/components/ui/Callout/index.js b/website/src/components/ui/Callout/index.js index 639d76e4..80b53731 100644 --- a/website/src/components/ui/Callout/index.js +++ b/website/src/components/ui/Callout/index.js @@ -1,47 +1,60 @@ import React from 'react'; import clsx from 'clsx'; -import Icon from '../Icon'; import styles from './styles.module.css'; +const TYPES = ['info', 'tip', 'warning', 'danger', 'success', 'note', 'important']; + /** * Callout Component - Enhanced admonition-style component - * - * @param {string} type - Callout type ('info', 'warning', 'danger', 'success', 'tip') + * + * @param {string} type - Callout type ('info', 'tip', 'warning', 'danger', 'success', 'note', 'important') * @param {string} title - Optional title * @param {ReactNode} children - Content - * @param {boolean} icon - Show icon (default: true) + * @param {boolean} collapsible - Render as expandable disclosure (default: false) + * @param {boolean} defaultOpen - Expanded by default (collapsible only, default: false) + * @param {string} className - Optional extra class */ -export default function Callout({ - type = 'info', - title, +export default function Callout({ + type = 'info', + title, children, - icon = true + collapsible = false, + defaultOpen = false, + className, }) { - const iconNames = { - info: 'lightbulb', - warning: 'warning', - danger: 'no-entry', - success: 'checkmark', - tip: 'lightbulb', - note: 'memo' - }; + const resolvedType = TYPES.includes(type) ? type : 'info'; + + const classes = clsx( + 'theme-admonition', + `theme-admonition-${resolvedType}`, + styles.callout, + collapsible && styles.calloutCollapsible, + className, + ); + + if (collapsible) { + const label = title || resolvedType.charAt(0).toUpperCase() + resolvedType.slice(1); + return ( + + ); + } return ( -
-
- {icon && ( - - - - )} - {title && ( +
+
+ )} +
{children}
+ ); } - diff --git a/website/src/components/ui/Callout/styles.module.css b/website/src/components/ui/Callout/styles.module.css index e28b4865..4b88bbcb 100644 --- a/website/src/components/ui/Callout/styles.module.css +++ b/website/src/components/ui/Callout/styles.module.css @@ -1,18 +1,35 @@ /* Callout Component */ +:where(.callout) { + --callout-accent: var(--ifm-color-primary); +} + .callout { margin: 1.5rem 0; padding: 1.25rem 1.5rem; - border-radius: 0.75rem; - border-left: 4px solid; - background: var(--ifm-background-surface-color); - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); + border-radius: 0 0.75rem 0.75rem 0; + border-left: 4px solid var(--callout-accent); + background-color: var(--ifm-background-color); + background-image: linear-gradient( + to right, + color-mix(in srgb, var(--callout-accent) 10%, transparent), + var(--ifm-background-color) + ); + box-shadow: none; + color: var(--ifm-font-color-base); } [data-theme='dark'] .callout { - background: #0f0f0f; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); + background-image: linear-gradient( + to right, + color-mix(in srgb, var(--callout-accent) 14%, transparent), + var(--ifm-background-color) + ); } +/* Type accents are defined globally in documentation.css + (.theme-admonition-) so Callout and native ::: admonitions + share one source of truth. */ + .calloutHeader { display: flex; align-items: center; @@ -20,9 +37,16 @@ margin-bottom: 0.75rem; } -.calloutIcon { - font-size: 1.5rem; - line-height: 1; +.calloutChevron { + flex-shrink: 0; + width: 1rem; + height: 1rem; + margin-left: auto; + transform: rotate(-90deg); + transition: transform 0.2s ease; + background-color: var(--callout-accent); + -webkit-mask: url('/icons/chevron-down.svg') no-repeat center / contain; + mask: url('/icons/chevron-down.svg') no-repeat center / contain; } .calloutTitle { @@ -32,7 +56,6 @@ } .calloutContent { - color: var(--ifm-font-color-base); line-height: 1.6; } @@ -44,64 +67,39 @@ margin-bottom: 0; } -/* Type variants */ -.callout--info { - border-left-color: #3b82f6; - background: linear-gradient(to right, rgba(59, 130, 246, 0.05), transparent); -} - -[data-theme='dark'] .callout--info { - border-left-color: #60a5fa; - background: linear-gradient(to right, rgba(96, 165, 250, 0.1), rgba(15, 15, 15, 1)); -} - -.callout--warning { - border-left-color: #f59e0b; - background: linear-gradient(to right, rgba(245, 158, 11, 0.05), transparent); +/* Collapsible variant */ +.calloutCollapsible summary { + cursor: pointer; + list-style: none; + user-select: none; } -[data-theme='dark'] .callout--warning { - border-left-color: #fbbf24; - background: linear-gradient(to right, rgba(251, 191, 36, 0.1), rgba(15, 15, 15, 1)); +.calloutCollapsible summary::-webkit-details-marker { + display: none; } -.callout--danger { - border-left-color: #ef4444; - background: linear-gradient(to right, rgba(239, 68, 68, 0.05), transparent); +.calloutCollapsible summary:focus-visible { + outline: 2px solid var(--callout-accent); + outline-offset: 3px; + border-radius: 0.25rem; } -[data-theme='dark'] .callout--danger { - border-left-color: #f87171; - background: linear-gradient(to right, rgba(248, 113, 113, 0.1), rgba(15, 15, 15, 1)); +.calloutCollapsible details[open] .calloutChevron { + transform: rotate(0deg); } -.callout--success { - border-left-color: #10b981; - background: linear-gradient(to right, rgba(16, 185, 129, 0.05), transparent); -} - -[data-theme='dark'] .callout--success { - border-left-color: #34d399; - background: linear-gradient(to right, rgba(52, 211, 153, 0.1), rgba(15, 15, 15, 1)); -} - -.callout--tip { - border-left-color: #3b82f6; - background: linear-gradient(to right, rgba(59, 130, 246, 0.05), transparent); -} - -[data-theme='dark'] .callout--tip { - border-left-color: #60a5fa; - background: linear-gradient(to right, rgba(59, 130, 246, 0.1), rgba(15, 15, 15, 1)); +.calloutCollapsible details:not([open]) .calloutHeader { + margin-bottom: 0; } -.callout--note { - border-left-color: #64748b; - background: linear-gradient(to right, rgba(100, 116, 139, 0.05), transparent); +@media (max-width: 768px) { + .callout { + padding: 1.25rem; + } } -[data-theme='dark'] .callout--note { - border-left-color: #94a3b8; - background: linear-gradient(to right, rgba(148, 163, 184, 0.1), rgba(15, 15, 15, 1)); +@media (prefers-reduced-motion: reduce) { + .calloutChevron { + transition: none; + } } - diff --git a/website/src/components/ui/CalloutBox/index.js b/website/src/components/ui/CalloutBox/index.js index 1720f2d5..472063fa 100644 --- a/website/src/components/ui/CalloutBox/index.js +++ b/website/src/components/ui/CalloutBox/index.js @@ -1,32 +1,10 @@ import React from 'react'; -import clsx from 'clsx'; -import Icon from '../Icon'; -import styles from './styles.module.css'; +import Callout from '../Callout'; -const iconNames = { - info: 'lightbulb', - tip: 'sparkles', - warning: 'warning', - danger: 'siren', - success: 'checkmark', - note: 'memo', -}; - -export default function CalloutBox({ children, type = 'info', title }) { - return ( -
-
- - - - - {title || type.charAt(0).toUpperCase() + type.slice(1)} - -
-
- {children} -
-
- ); +/** + * @deprecated Alias of `Callout`, kept for backward compatibility with + * existing docs pages. Prefer importing `Callout` directly. + */ +export default function CalloutBox(props) { + return ; } - diff --git a/website/src/components/ui/CalloutBox/styles.module.css b/website/src/components/ui/CalloutBox/styles.module.css deleted file mode 100644 index ffd8bfbb..00000000 --- a/website/src/components/ui/CalloutBox/styles.module.css +++ /dev/null @@ -1,117 +0,0 @@ -.callout { - border-radius: 0.75rem; - padding: 1.5rem; - margin: 2rem 0; - border-left: 4px solid; - background: var(--ifm-background-surface-color); - box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1); - transition: all 0.3s ease; -} - -.callout:hover { - transform: translateX(4px); - box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1); -} - -.calloutHeader { - display: flex; - align-items: center; - gap: 0.75rem; - margin-bottom: 0.75rem; -} - -.calloutIcon { - font-size: 1.5rem; - line-height: 1; -} - -.calloutTitle { - font-size: 1.125rem; - font-weight: 700; - text-transform: uppercase; - letter-spacing: 0.05em; -} - -.calloutContent { - font-size: 1rem; - line-height: 1.7; - color: var(--ifm-color-emphasis-800); -} - -.calloutContent > *:last-child { - margin-bottom: 0; -} - -/* Type variants */ -.callout.info { - border-left-color: #3b82f6; - background: linear-gradient(135deg, rgba(59, 130, 246, 0.05) 0%, transparent 100%); -} - -.callout.info .calloutTitle { - color: #3b82f6; -} - -.callout.tip { - border-left-color: #3b82f6; - background: linear-gradient(135deg, rgba(59, 130, 246, 0.05) 0%, transparent 100%); -} - -.callout.tip .calloutTitle { - color: #3b82f6; -} - -.callout.warning { - border-left-color: #f59e0b; - background: linear-gradient(135deg, rgba(245, 158, 11, 0.05) 0%, transparent 100%); -} - -.callout.warning .calloutTitle { - color: #f59e0b; -} - -.callout.danger { - border-left-color: #ef4444; - background: linear-gradient(135deg, rgba(239, 68, 68, 0.05) 0%, transparent 100%); -} - -.callout.danger .calloutTitle { - color: #ef4444; -} - -.callout.success { - border-left-color: #10b981; - background: linear-gradient(135deg, rgba(16, 185, 129, 0.05) 0%, transparent 100%); -} - -.callout.success .calloutTitle { - color: #10b981; -} - -.callout.note { - border-left-color: #3b82f6; - background: linear-gradient(135deg, rgba(59, 130, 246, 0.05) 0%, transparent 100%); -} - -.callout.note .calloutTitle { - color: #3b82f6; -} - -@media (max-width: 768px) { - .callout { - padding: 1.25rem; - } - - .calloutIcon { - font-size: 1.25rem; - } - - .calloutTitle { - font-size: 1rem; - } - - .calloutContent { - font-size: 0.95rem; - } -} - diff --git a/website/src/css/admonitions.css b/website/src/css/admonitions.css index 82084210..3122e5f5 100644 --- a/website/src/css/admonitions.css +++ b/website/src/css/admonitions.css @@ -1,45 +1,6 @@ /** * Admonition Component Styles - * Additional admonition styling beyond what's in documentation.css + * Canonical styling lives in documentation.css (ENHANCED ADMONITIONS), + * keyed on the global .theme-admonition / .theme-admonition- + * classes shared by native `:::` admonitions and the Callout component. */ - -/* Admonitions base */ - -.admonition { - border-radius: var(--ifm-global-radius); - border-left-width: 4px; - box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); -} - -/* Light mode admonitions */ -/* -.alert { - background: #f8fafc; - border-left-width: 4px; -} -*/ - -/* Dark mode admonitions */ -/* -[data-theme='dark'] .alert { - background: #1e293b; - border-left-color: #60a5fa; - color: #e0e0e0; -} - -[data-theme='dark'] .alert--info { - border-left-color: #60a5fa; -} - -[data-theme='dark'] .alert--warning { - border-left-color: #fbbf24; -} - -[data-theme='dark'] .alert--danger { - border-left-color: #ef4444; -} - -[data-theme='dark'] .alert--success { - border-left-color: #10b981; -} -*/ \ No newline at end of file diff --git a/website/src/css/blog-cards.css b/website/src/css/blog-cards.css index 7706bf81..4a3dd4d0 100644 --- a/website/src/css/blog-cards.css +++ b/website/src/css/blog-cards.css @@ -6,12 +6,12 @@ /* Override theme BlogPostItem/Header/Title (.title_xxxx) from 3rem to 2rem */ .theme-blog-wrapper [class*="title_"] { font-family: var(--ifm-heading-font-family); - font-size: 2.5rem !important; + font-size: 2rem !important; } @media (max-width: 576px) { .theme-blog-wrapper [class*="title_"] { - font-size: 2rem !important; + font-size: 1.625rem !important; } } diff --git a/website/src/css/blog-sidebar.css b/website/src/css/blog-sidebar.css index 4c78de83..326b0fb5 100644 --- a/website/src/css/blog-sidebar.css +++ b/website/src/css/blog-sidebar.css @@ -3,18 +3,18 @@ * Blog sidebar with timeline visualization */ -/* Target blog sidebar with more specific selectors */ -.theme-blog-wrapper .col--3, -.theme-blog-wrapper [class*="col--3"], -[class*="blog"] [class*="col--3"] { +/* Target blog sidebar with more specific selectors (left timeline only — not right ToC) */ +.theme-blog-wrapper .col--3:not(.blog-toc-col), +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col), +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) { position: relative; - padding: 1.5rem 0 1.5rem 2rem !important; + padding: 1.25rem 0 1.25rem 1.5rem !important; } /* Timeline vertical line (blog sidebar only) */ -.theme-blog-wrapper .col--3::before, -.theme-blog-wrapper [class*="col--3"]::before, -[class*="blog"] [class*="col--3"]::before { +.theme-blog-wrapper .col--3:not(.blog-toc-col)::before, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col)::before, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col)::before { content: ''; position: absolute; left: 0.625rem; @@ -29,9 +29,9 @@ z-index: 1; } -[data-theme='dark'] .theme-blog-wrapper .col--3::before, -[data-theme='dark'] .theme-blog-wrapper [class*="col--3"]::before, -[data-theme='dark'] [class*="blog"] [class*="col--3"]::before { +[data-theme='dark'] .theme-blog-wrapper .col--3:not(.blog-toc-col)::before, +[data-theme='dark'] .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col)::before, +[data-theme='dark'] [class*="blog"] [class*="col--3"]:not(.blog-toc-col)::before { background: linear-gradient(180deg, #60a5fa 0%, #93c5fd 10%, @@ -39,23 +39,43 @@ ); } +/* Right ToC column — same width + exact style as docs (col--3) */ +.theme-blog-wrapper > .blog-toc-col, +.theme-blog-wrapper .blog-toc-col { + position: relative; + padding: 0 !important; + margin-top: 0 !important; + border-top: none !important; +} + +.theme-blog-wrapper > .blog-toc-col::before, +.theme-blog-wrapper .blog-toc-col::before { + display: none !important; +} + +/* Keep timeline styles off the blog ToC column even if selectors match col--3 */ +.theme-blog-wrapper > .blog-toc-col [class*='table-of-contents'], +.theme-blog-wrapper .blog-toc-col [class*='table-of-contents'] { + border-left: none; +} + /* Sidebar title */ -.theme-blog-wrapper .col--3 h3, -.theme-blog-wrapper [class*="col--3"] h3, -[class*="blog"] [class*="col--3"] h3 { +.theme-blog-wrapper .col--3:not(.blog-toc-col) h3, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) h3, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) h3 { width: 65%; - font-size: 1.125rem; + font-size: 1rem; font-weight: 700; color: var(--ifm-color-emphasis-900); - margin-bottom: 1rem; - padding-bottom: 0.5rem; + margin-bottom: 0.75rem; + padding-bottom: 0.4rem; border-bottom: 2px solid var(--ifm-color-emphasis-200) } /* Blog sidebar list container */ -.theme-blog-wrapper .col--3 ul, -.theme-blog-wrapper [class*="col--3"] ul, -[class*="blog"] [class*="col--3"] ul { +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul { list-style: none !important; padding: 0; margin: 0; @@ -63,48 +83,48 @@ } /* Year group items */ -.theme-blog-wrapper .col--3 ul li, -.theme-blog-wrapper [class*="col--3"] ul li, -[class*="blog"] [class*="col--3"] ul li { +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul li, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li { position: relative; - margin-bottom: 1rem; + margin-bottom: 0.75rem; padding-left: 0; } -.theme-blog-wrapper .col--3 ul li:last-child, -.theme-blog-wrapper [class*="col--3"] ul li:last-child, -[class*="blog"] [class*="col--3"] ul li:last-child { +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul li:last-child, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li:last-child, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li:last-child { margin-bottom: 0; } /* Year heading with timeline dot */ -.theme-blog-wrapper .col--3 ul li strong, -.theme-blog-wrapper [class*="col--3"] ul li strong, -[class*="blog"] [class*="col--3"] ul li strong { +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul li strong, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li strong, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li strong { display: inline-block !important; - font-size: 1rem; + font-size: 0.9375rem; font-weight: 700; color: var(--ifm-color-emphasis-900); - margin-bottom: 0.5rem; + margin-bottom: 0.4rem; position: relative; padding-left: 0; - padding-bottom: 0.25rem; + padding-bottom: 0.2rem; border-bottom: 1px solid var(--ifm-color-emphasis-300) !important; max-width: 50% !important; width: 50% !important; } /* Timeline dot for years */ -.theme-blog-wrapper .col--3 ul li strong::before, -.theme-blog-wrapper [class*="col--3"] ul li strong::before, -[class*="blog"] [class*="col--3"] ul li strong::before { +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul li strong::before, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li strong::before, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li strong::before { content: ''; position: absolute; - left: -2.125rem; + left: -1.875rem; top: 50%; transform: translateY(-50%); - width: 1rem; - height: 1rem; + width: 0.75rem; + height: 0.75rem; border-radius: 50%; background: var(--ifm-color-primary); border: 3px solid var(--ifm-background-color); @@ -113,33 +133,33 @@ z-index: 2; } -[data-theme='dark'] .theme-blog-wrapper .col--3 ul li strong::before, -[data-theme='dark'] .theme-blog-wrapper [class*="col--3"] ul li strong::before, -[data-theme='dark'] [class*="blog"] [class*="col--3"] ul li strong::before { +[data-theme='dark'] .theme-blog-wrapper .col--3:not(.blog-toc-col) ul li strong::before, +[data-theme='dark'] .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li strong::before, +[data-theme='dark'] [class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li strong::before { background: #60a5fa; border-color: var(--ifm-background-color); box-shadow: 0 0 0 2px #60a5fa; } /* Older years - grey dots */ -.theme-blog-wrapper .col--3 ul li:not(:first-child) strong::before, -.theme-blog-wrapper [class*="col--3"] ul li:not(:first-child) strong::before, -[class*="blog"] [class*="col--3"] ul li:not(:first-child) strong::before { +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul li:not(:first-child) strong::before, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li:not(:first-child) strong::before, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li:not(:first-child) strong::before { background: var(--ifm-color-emphasis-300); box-shadow: 0 0 0 2px var(--ifm-color-emphasis-300); } -[data-theme='dark'] .theme-blog-wrapper .col--3 ul li:not(:first-child) strong::before, -[data-theme='dark'] .theme-blog-wrapper [class*="col--3"] ul li:not(:first-child) strong::before, -[data-theme='dark'] [class*="blog"] [class*="col--3"] ul li:not(:first-child) strong::before { +[data-theme='dark'] .theme-blog-wrapper .col--3:not(.blog-toc-col) ul li:not(:first-child) strong::before, +[data-theme='dark'] .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li:not(:first-child) strong::before, +[data-theme='dark'] [class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li:not(:first-child) strong::before { background: var(--ifm-color-emphasis-400); box-shadow: 0 0 0 2px var(--ifm-color-emphasis-400); } -/* Blog post links - timeline items */ -.theme-blog-wrapper .col--3 ul li a, -.theme-blog-wrapper [class*="col--3"] ul li a, -[class*="blog"] [class*="col--3"] ul li a { +/* Blog post links - timeline items (left rail only — not right ToC) */ +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a { display: block; color: var(--ifm-color-emphasis-600); font-size: 0.875rem; @@ -153,9 +173,9 @@ } /* Small dot for individual posts */ -.theme-blog-wrapper .col--3 ul li a::before, -.theme-blog-wrapper [class*="col--3"] ul li a::before, -[class*="blog"] [class*="col--3"] ul li a::before { +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a::before, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a::before, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a::before { content: ''; position: absolute; left: -2.125rem; @@ -169,97 +189,101 @@ z-index: 2; } -[data-theme='dark'] .theme-blog-wrapper .col--3 ul li a::before, -[data-theme='dark'] .theme-blog-wrapper [class*="col--3"] ul li a::before, -[data-theme='dark'] [class*="blog"] [class*="col--3"] ul li a::before { +[data-theme='dark'] .theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a::before, +[data-theme='dark'] .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a::before, +[data-theme='dark'] [class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a::before { background: var(--ifm-color-emphasis-400); } /* Active/hover state for posts */ -.theme-blog-wrapper .col--3 ul li a:hover, -.theme-blog-wrapper [class*="col--3"] ul li a:hover, -[class*="blog"] [class*="col--3"] ul li a:hover { +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a:hover, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a:hover, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a:hover { color: var(--ifm-color-primary); padding-left: 1rem; } -.theme-blog-wrapper .col--3 ul li a:hover::before, -.theme-blog-wrapper [class*="col--3"] ul li a:hover::before, -[class*="blog"] [class*="col--3"] ul li a:hover::before { +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a:hover::before, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a:hover::before, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a:hover::before { background: var(--ifm-color-primary); width: 0.625rem; height: 0.625rem; } -[data-theme='dark'] .theme-blog-wrapper .col--3 ul li a:hover, -[data-theme='dark'] .theme-blog-wrapper [class*="col--3"] ul li a:hover, -[data-theme='dark'] [class*="blog"] [class*="col--3"] ul li a:hover { +[data-theme='dark'] .theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a:hover, +[data-theme='dark'] .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a:hover, +[data-theme='dark'] [class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a:hover { color: #60a5fa; } -[data-theme='dark'] .theme-blog-wrapper .col--3 ul li a:hover::before, -[data-theme='dark'] .theme-blog-wrapper [class*="col--3"] ul li a:hover::before, -[data-theme='dark'] [class*="blog"] [class*="col--3"] ul li a:hover::before { +[data-theme='dark'] .theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a:hover::before, +[data-theme='dark'] .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a:hover::before, +[data-theme='dark'] [class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a:hover::before { background: #60a5fa; } /* Active blog post */ -.theme-blog-wrapper .col--3 ul li a[aria-current], -.theme-blog-wrapper [class*="col--3"] ul li a[aria-current], -[class*="blog"] [class*="col--3"] ul li a[aria-current] { +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a[aria-current], +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a[aria-current], +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a[aria-current] { color: var(--ifm-color-primary); font-weight: 600; } -.theme-blog-wrapper .col--3 ul li a[aria-current]::before, -.theme-blog-wrapper [class*="col--3"] ul li a[aria-current]::before, -[class*="blog"] [class*="col--3"] ul li a[aria-current]::before { +.theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a[aria-current]::before, +.theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a[aria-current]::before, +[class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a[aria-current]::before { background: var(--ifm-color-primary); width: 0.625rem; height: 0.625rem; } -[data-theme='dark'] .theme-blog-wrapper .col--3 ul li a[aria-current], -[data-theme='dark'] .theme-blog-wrapper [class*="col--3"] ul li a[aria-current], -[data-theme='dark'] [class*="blog"] [class*="col--3"] ul li a[aria-current] { +[data-theme='dark'] .theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a[aria-current], +[data-theme='dark'] .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a[aria-current], +[data-theme='dark'] [class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a[aria-current] { color: #60a5fa; } -[data-theme='dark'] .theme-blog-wrapper .col--3 ul li a[aria-current]::before, -[data-theme='dark'] .theme-blog-wrapper [class*="col--3"] ul li a[aria-current]::before, -[data-theme='dark'] [class*="blog"] [class*="col--3"] ul li a[aria-current]::before { +[data-theme='dark'] .theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a[aria-current]::before, +[data-theme='dark'] .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a[aria-current]::before, +[data-theme='dark'] [class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a[aria-current]::before { background: #60a5fa; } -/* Responsive adjustments */ + /* Responsive adjustments */ @media (max-width: 996px) { - .theme-blog-wrapper .col--3, - .theme-blog-wrapper [class*="col--3"], - [class*="blog"] [class*="col--3"] { + .theme-blog-wrapper .col--3:not(.blog-toc-col), + .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col), + [class*="blog"] [class*="col--3"]:not(.blog-toc-col) { padding-left: 0 !important; margin-top: 2rem; padding-top: 2rem; border-top: 2px solid var(--ifm-color-emphasis-200); } - .theme-blog-wrapper .col--3::before, - .theme-blog-wrapper [class*="col--3"]::before, - [class*="blog"] [class*="col--3"]::before { + .blog-toc-col { + display: none !important; + } + + .theme-blog-wrapper .col--3:not(.blog-toc-col)::before, + .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col)::before, + [class*="blog"] [class*="col--3"]:not(.blog-toc-col)::before { display: none; } - .theme-blog-wrapper .col--3 ul li strong::before, - .theme-blog-wrapper [class*="col--3"] ul li strong::before, - [class*="blog"] [class*="col--3"] ul li strong::before, - .theme-blog-wrapper .col--3 ul li a::before, - .theme-blog-wrapper [class*="col--3"] ul li a::before, - [class*="blog"] [class*="col--3"] ul li a::before { + .theme-blog-wrapper .col--3:not(.blog-toc-col) ul li strong::before, + .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li strong::before, + [class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li strong::before, + .theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a::before, + .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a::before, + [class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a::before { display: none; } - .theme-blog-wrapper .col--3 ul li a, - .theme-blog-wrapper [class*="col--3"] ul li a, - [class*="blog"] [class*="col--3"] ul li a { + .theme-blog-wrapper .col--3:not(.blog-toc-col) ul li a, + .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col) ul li a, + [class*="blog"] [class*="col--3"]:not(.blog-toc-col) ul li a { padding-left: 0; } } @@ -267,7 +291,8 @@ /* Desktop-only: hide blog sidebar for focus mode (toggle in BlogLayout) */ @media (min-width: 997px) { /* Collapsed left sidebar takes no space so content + ToC can fill the row */ - .blog-sidebar-hidden .theme-blog-wrapper > .col--3 { + .blog-sidebar-hidden .theme-blog-wrapper > .col--3:not(.blog-toc-col), + .blog-sidebar-hidden .theme-blog-wrapper > [class*="col--3"]:not(.blog-toc-col) { flex: 0 0 0 !important; width: 0 !important; min-width: 0 !important; @@ -278,8 +303,8 @@ transition: width var(--ifm-transition-fast) ease; } - .blog-sidebar-hidden .theme-blog-wrapper .col--3::before, - .blog-sidebar-hidden .theme-blog-wrapper [class*="col--3"]::before { + .blog-sidebar-hidden .theme-blog-wrapper .col--3:not(.blog-toc-col)::before, + .blog-sidebar-hidden .theme-blog-wrapper [class*="col--3"]:not(.blog-toc-col)::before { display: none; } @@ -294,15 +319,18 @@ var(--ifm-docs-sidebar-closed-padding-left, 2.5rem) !important; } - /* Main content grows to fill space; right ToC keeps fixed width */ + /* Main content grows to fill space; right ToC keeps docs width (col--3) */ .blog-sidebar-hidden .theme-blog-wrapper > main.col--9 { flex: 1 1 0 !important; min-width: 0; max-width: none !important; } - .blog-sidebar-hidden .theme-blog-wrapper > .col--2 { - flex: 0 0 calc(2 / 12 * 100%) !important; + .blog-sidebar-hidden .theme-blog-wrapper > .blog-toc-col, + .blog-sidebar-hidden .theme-blog-wrapper > .col--3.blog-toc-col { + flex: 0 0 calc(3 / 12 * 100%) !important; + max-width: calc(3 / 12 * 100%) !important; + width: calc(3 / 12 * 100%) !important; } } diff --git a/website/src/css/cards.css b/website/src/css/cards.css index b6d42bdc..1a436aa5 100644 --- a/website/src/css/cards.css +++ b/website/src/css/cards.css @@ -7,8 +7,8 @@ .feature-card { position: relative; height: 100%; - border-radius: 1.25rem; - padding: 2.5rem 2rem; + border-radius: 0.75rem; + padding: 1.5rem 1.25rem; overflow: hidden; isolation: isolate; background: linear-gradient(155deg, #ffffff 0%, #f1f5f9 55%, #f8fafc 100%); @@ -77,20 +77,20 @@ .feature-card h3 { position: relative; z-index: 1; - font-size: 1.25rem; + font-size: 1.125rem; font-weight: 700; letter-spacing: -0.025em; line-height: 1.22; - margin-top: 0.5rem; - margin-bottom: 1rem; + margin-top: 0.35rem; + margin-bottom: 0.65rem; color: #0f172a; } .feature-card p { position: relative; z-index: 1; - line-height: 1.65; - font-size: 0.96875rem; + line-height: 1.55; + font-size: 0.9375rem; color: #334155; margin: 0; } @@ -98,10 +98,10 @@ .feature-icon { position: relative; z-index: 1; - font-size: 3.5rem; + font-size: 2.5rem; line-height: 1; display: block; - margin-bottom: 1rem; + margin-bottom: 0.75rem; transition: transform var(--motion-duration-normal) var(--motion-ease-standard); } diff --git a/website/src/css/documentation.css b/website/src/css/documentation.css index 56051634..514596ed 100644 --- a/website/src/css/documentation.css +++ b/website/src/css/documentation.css @@ -9,27 +9,27 @@ /* Enhanced markdown content */ .markdown { - font-size: 1rem; - line-height: 1.75; + font-size: 0.96875rem; + line-height: 1.6; } .markdown > h1 { font-family: var(--ifm-heading-font-family); - font-size: 2.75rem; - font-weight: 800; + font-size: 2rem; + font-weight: 700; letter-spacing: -0.02em; margin-top: 0; - margin-bottom: 1.5rem; - line-height: 1.1; + margin-bottom: 0.75rem; + line-height: 1.2; } .markdown > h2 { - font-size: 2rem; + font-size: 1.5rem; font-weight: 700; letter-spacing: -0.015em; - margin-top: 3rem; - margin-bottom: 1.25rem; - padding-bottom: 0.75rem; + margin-top: 1.75rem; + margin-bottom: 0.75rem; + padding-bottom: 0.4rem; border-bottom: 2px solid var(--ifm-color-emphasis-200); } @@ -38,18 +38,18 @@ } .markdown > h3 { - font-size: 1.5rem; + font-size: 1.25rem; font-weight: 700; - margin-top: 2.5rem; - margin-bottom: 1rem; + margin-top: 1.5rem; + margin-bottom: 0.65rem; color: var(--ifm-heading-color); } .markdown > h4 { - font-size: 1.25rem; + font-size: 1.0625rem; font-weight: 600; - margin-top: 2rem; - margin-bottom: 0.875rem; + margin-top: 1.25rem; + margin-bottom: 0.6rem; color: var(--ifm-heading-color); } @@ -67,7 +67,7 @@ } .markdown > p { - margin-bottom: 1.5rem; + margin-bottom: 0.875rem; color: var(--ifm-color-emphasis-800); } @@ -99,23 +99,23 @@ /* Lists in documentation */ .markdown ul, .markdown ol { - margin-bottom: 1.5rem; - padding-left: 1.75rem; + margin-bottom: 0.875rem; + padding-left: 1.375rem; } .markdown li { - margin-bottom: 0.5rem; - line-height: 1.7; + margin-bottom: 0.3rem; + line-height: 1.55; } .markdown li > p { - margin-bottom: 0.5rem; + margin-bottom: 0.3rem; } /* Blockquotes */ .markdown blockquote { - margin: 1.5rem 0; - padding: 1rem 1.5rem; + margin: 0.875rem 0; + padding: 0.65rem 1rem; border-left: 4px solid var(--ifm-color-primary); background: var(--ifm-background-surface-color); border-radius: 0 0.5rem 0.5rem 0; @@ -207,10 +207,10 @@ } .markdown table th { - padding: 1rem 1.25rem; + padding: 0.625rem 0.875rem; text-align: left; font-weight: 700; - font-size: 0.95rem; + font-size: 0.8125rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ifm-heading-color); @@ -223,7 +223,7 @@ } .markdown table td { - padding: 1rem 1.25rem; + padding: 0.625rem 0.875rem; border-bottom: 1px solid var(--ifm-color-emphasis-200); } @@ -245,7 +245,7 @@ /* Horizontal rules */ .markdown hr { - margin: 3rem 0; + margin: 1.75rem 0; border: none; height: 1px; background: linear-gradient( @@ -257,63 +257,187 @@ } /* ============================================ - TABLE OF CONTENTS + TABLE OF CONTENTS (docs + whitepaper + blog share exact type scale) ============================================ */ -.table-of-contents { - font-size: 0.9rem; +.theme-doc-toc-desktop .table-of-contents, +.theme-doc-toc-desktop, +.table-of-contents, +.blog-toc-col .table-of-contents, +.blog-toc-rail .table-of-contents, +.theme-blog-wrapper .table-of-contents, +.blog-wrapper .table-of-contents, +.theme-blog-wrapper .blog-toc-col .table-of-contents, +.theme-blog-wrapper .blog-toc-rail .table-of-contents, +.theme-blog-wrapper .theme-doc-toc-desktop .table-of-contents { + font-size: var(--ifm-toc-font-size, 0.75rem) !important; + line-height: var(--ifm-toc-line-height, 1.45) !important; + font-family: inherit; +} + +.theme-doc-toc-desktop .table-of-contents ul, +.theme-doc-toc-desktop .table-of-contents li, +.blog-toc-col .table-of-contents ul, +.blog-toc-col .table-of-contents li, +.blog-toc-rail .table-of-contents ul, +.blog-toc-rail .table-of-contents li, +.theme-blog-wrapper .blog-toc-col .table-of-contents ul, +.theme-blog-wrapper .blog-toc-col .table-of-contents li, +.theme-blog-wrapper .blog-toc-rail .table-of-contents ul, +.theme-blog-wrapper .blog-toc-rail .table-of-contents li, +.theme-blog-wrapper .theme-doc-toc-desktop .table-of-contents ul, +.theme-blog-wrapper .theme-doc-toc-desktop .table-of-contents li { + font-size: var(--ifm-toc-font-size, 0.75rem) !important; + line-height: var(--ifm-toc-line-height, 1.45) !important; } .table-of-contents__heading { font-weight: 700; - font-size: 0.875rem; + font-size: 0.6875rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--ifm-color-emphasis-600); - margin-bottom: 0.75rem; + margin-bottom: 0.4rem; } [data-theme='dark'] .table-of-contents__heading { - color: #909090; -} - -.table-of-contents__link { + color: #94a3b8; +} + +.table-of-contents__link, +.theme-doc-toc-desktop .table-of-contents__link, +.blog-toc-col .table-of-contents__link, +.blog-toc-rail .table-of-contents__link, +.theme-blog-wrapper .table-of-contents__link, +.blog-wrapper .table-of-contents__link, +.theme-blog-wrapper .blog-toc-col .table-of-contents__link, +.theme-blog-wrapper .blog-toc-rail .table-of-contents__link, +.theme-blog-wrapper .theme-doc-toc-desktop .table-of-contents__link { display: block; - padding: 0 0 0 0.75rem; + font-size: var(--ifm-toc-font-size, 0.75rem) !important; + line-height: var(--ifm-toc-line-height, 1.45) !important; + font-family: inherit; + padding: 0.1rem 0 0.1rem 0.55rem !important; color: var(--ifm-color-emphasis-700); transition: all 0.2s ease; border-left: 2px solid transparent; - margin-left: -0.75rem; + margin-left: -0.55rem; + margin-right: 0; + margin-bottom: 0; } -.table-of-contents__link:hover { +.table-of-contents__link:hover, +.theme-doc-toc-desktop .table-of-contents__link:hover, +.blog-toc-col .table-of-contents__link:hover, +.blog-toc-rail .table-of-contents__link:hover { color: var(--ifm-color-primary); border-left-color: var(--ifm-color-primary); } -.table-of-contents__link--active { +.table-of-contents__link--active, +.theme-doc-toc-desktop .table-of-contents__link--active, +.blog-toc-col .table-of-contents__link--active, +.blog-toc-rail .table-of-contents__link--active { color: var(--ifm-color-primary); border-left-color: var(--ifm-color-primary); font-weight: 600; } -[data-theme='dark'] .table-of-contents__link { - color: #909090; +[data-theme='dark'] .table-of-contents__link, +[data-theme='dark'] .theme-doc-toc-desktop .table-of-contents__link, +[data-theme='dark'] .blog-toc-col .table-of-contents__link, +[data-theme='dark'] .blog-toc-rail .table-of-contents__link, +[data-theme='dark'] .theme-blog-wrapper .table-of-contents__link, +[data-theme='dark'] .blog-wrapper .table-of-contents__link { + color: #b6c2d9; } [data-theme='dark'] .table-of-contents__link:hover, -[data-theme='dark'] .table-of-contents__link--active { +[data-theme='dark'] .table-of-contents__link--active, +[data-theme='dark'] .theme-doc-toc-desktop .table-of-contents__link:hover, +[data-theme='dark'] .theme-doc-toc-desktop .table-of-contents__link--active, +[data-theme='dark'] .blog-toc-col .table-of-contents__link:hover, +[data-theme='dark'] .blog-toc-col .table-of-contents__link--active, +[data-theme='dark'] .blog-toc-rail .table-of-contents__link:hover, +[data-theme='dark'] .blog-toc-rail .table-of-contents__link--active { color: #60a5fa; border-left-color: #60a5fa; } +/* Mobile collapsible TOC (docs + whitepaper MDX) */ +.tocCollapsible { + margin: 0.75rem 0 !important; + border-radius: 0.5rem !important; +} + +.tocCollapsibleButton { + padding: 0.35rem 0.65rem !important; + font-size: 0.8125rem !important; +} + +.tocCollapsibleButton:after { + width: 0.9rem !important; + height: 0.9rem !important; + background-size: 0.9rem 0.9rem !important; +} + +.tocCollapsibleContent > ul { + padding: 0.15rem 0 !important; + font-size: var(--ifm-toc-font-size, 0.75rem) !important; + line-height: var(--ifm-toc-line-height, 1.45) !important; +} + +.tocCollapsibleContent ul li { + margin: 0.25rem 0.65rem !important; +} + +/* Blog ToC rail — same structure/classes as docs ToC */ +.blog-toc-col { + min-width: 0; +} + +.blog-toc-col .docTocRail, +.blog-toc-rail { + --doc-toc-footer-slot: 0rem; + position: sticky; + top: calc(var(--ifm-navbar-height) + 1rem); + align-self: flex-start; + display: flex; + flex-direction: column; + gap: 0; + width: 100%; +} + +.blog-toc-col .docTocRailScroll, +.blog-toc-rail .docTocRailScroll { + flex: 0 1 auto; + max-height: calc(100vh - var(--ifm-navbar-height) - 2rem); + min-height: 0; + overflow-x: hidden; + overflow-y: auto; +} + +.blog-toc-col .docTocRailScroll .theme-doc-toc-desktop, +.blog-toc-rail .docTocRailScroll .theme-doc-toc-desktop { + position: static !important; + max-height: none !important; + top: auto !important; + overflow: visible !important; +} + +/* Same dark left rail edge as docs */ +[data-theme='dark'] .blog-toc-col .theme-doc-toc-desktop, +[data-theme='dark'] .blog-toc-rail .theme-doc-toc-desktop { + border-left: 1px solid #334155; +} + /* ============================================ DOCUMENT NAVIGATION (Prev/Next) — minimal text rail ============================================ */ .pagination-nav { - margin-top: 1.5rem; - padding-top: 1.5rem; + margin-top: 1.25rem; + padding-top: 1.25rem; border-top: 1px solid var(--ifm-color-emphasis-200); } @@ -353,12 +477,12 @@ } .pagination-nav__sublabel { - font-size: 0.8125rem; + font-size: 0.75rem; text-transform: none; letter-spacing: normal; font-weight: 500; color: var(--ifm-color-emphasis-700); - margin-bottom: 0.35rem; + margin-bottom: 0.2rem; } [data-theme='dark'] .pagination-nav__sublabel { @@ -366,7 +490,7 @@ } .pagination-nav__label { - font-size: 1rem; + font-size: 0.9375rem; font-weight: 700; line-height: 1.35; color: var(--ifm-heading-color); @@ -416,129 +540,65 @@ /* ============================================ ENHANCED ADMONITIONS + Shared design with the Callout component: + flat square left edge under the 4px accent + bar, rounded right corners, full-width accent + fade. Type accents are the single source of + truth for both native `:::` admonitions and + (which emits the same + theme-admonition- classes). ============================================ */ -.admonition { +.theme-admonition { + --callout-accent: var(--ifm-color-primary); margin: 1.5rem 0; padding: 1.25rem 1.5rem; - border-radius: 0.75rem; - border-left: 4px solid; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); - background: var(--ifm-background-surface-color); -} - -[data-theme='dark'] .admonition { - background-color: #0f0f0f; - box-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); -} - -.admonition-heading { - display: flex; - align-items: center; - gap: 0.75rem; - margin-bottom: 0.75rem; - font-weight: 700; - font-size: 1rem; -} - -.admonition-icon { - font-size: 1.5rem; -} - -.admonition-content > p:last-child { - margin-bottom: 0; -} - -/* Admonition types */ -.alert--info, -.admonition-info { - border-left-color: #3b82f6; - background: linear-gradient(to right, rgba(59, 130, 246, 0.05), transparent); -} - -[data-theme='dark'] .alert--info, -[data-theme='dark'] .admonition-info { - border-left-color: #60a5fa; - background-image: linear-gradient( - 90deg, - rgba(96, 165, 250, 0.16) 0%, - rgba(96, 165, 250, 0.1) 28%, - rgba(96, 165, 250, 0.04) 58%, - rgba(96, 165, 250, 0) 100% - ); -} - -.alert--warning, -.admonition-warning { - border-left-color: #f59e0b; - background: linear-gradient(to right, rgba(245, 158, 11, 0.05), transparent); -} - -[data-theme='dark'] .alert--warning, -[data-theme='dark'] .admonition-warning { - border-left-color: #fbbf24; - background-image: linear-gradient( - 90deg, - rgba(251, 191, 36, 0.18) 0%, - rgba(251, 191, 36, 0.11) 28%, - rgba(251, 191, 36, 0.05) 58%, - rgba(251, 191, 36, 0) 100% - ); -} - -.alert--danger, -.admonition-danger { - border-left-color: #ef4444; - background: linear-gradient(to right, rgba(239, 68, 68, 0.05), transparent); -} - -[data-theme='dark'] .alert--danger, -[data-theme='dark'] .admonition-danger { - border-left-color: #f87171; + border: none; + border-left: 4px solid var(--callout-accent); + border-radius: 0 0.75rem 0.75rem 0; + background-color: var(--ifm-background-color); background-image: linear-gradient( - 90deg, - rgba(248, 113, 113, 0.17) 0%, - rgba(248, 113, 113, 0.1) 28%, - rgba(248, 113, 113, 0.04) 58%, - rgba(248, 113, 113, 0) 100% + to right, + color-mix(in srgb, var(--callout-accent) 10%, transparent), + var(--ifm-background-color) ); + box-shadow: none; + color: var(--ifm-font-color-base); } -.alert--success, -.admonition-success { - border-left-color: #10b981; - background: linear-gradient(to right, rgba(16, 185, 129, 0.05), transparent); -} - -[data-theme='dark'] .alert--success, -[data-theme='dark'] .admonition-success { - border-left-color: #34d399; +[data-theme='dark'] .theme-admonition { background-image: linear-gradient( - 90deg, - rgba(52, 211, 153, 0.17) 0%, - rgba(52, 211, 153, 0.1) 28%, - rgba(52, 211, 153, 0.04) 58%, - rgba(52, 211, 153, 0) 100% + to right, + color-mix(in srgb, var(--callout-accent) 14%, transparent), + var(--ifm-background-color) ); } -.alert--tip, -.admonition-tip { - border-left-color: #3b82f6; - background: linear-gradient(to right, rgba(59, 130, 246, 0.05), transparent); -} - -[data-theme='dark'] .alert--tip, -[data-theme='dark'] .admonition-tip { - border-left-color: #60a5fa; - background-image: linear-gradient( - 90deg, - rgba(59, 130, 246, 0.16) 0%, - rgba(59, 130, 246, 0.1) 28%, - rgba(59, 130, 246, 0.04) 58%, - rgba(59, 130, 246, 0) 100% - ); -} +/* Type icons are intentionally hidden: the accent bar + tint carry meaning */ +.theme-admonition [class*='admonitionIcon'] { + display: none; +} + +/* Type accents */ +.theme-admonition-info { --callout-accent: #3b82f6; } +.theme-admonition-tip, +.theme-admonition-secondary { --callout-accent: #0d9488; } +.theme-admonition-warning { --callout-accent: #d97706; } +.theme-admonition-danger, +.theme-admonition-caution { --callout-accent: #dc2626; } +.theme-admonition-success { --callout-accent: #059669; } +.theme-admonition-note { --callout-accent: #64748b; } +.theme-admonition-important { --callout-accent: #e11d48; } + +[data-theme='dark'] .theme-admonition-info { --callout-accent: #60a5fa; } +[data-theme='dark'] .theme-admonition-tip, +[data-theme='dark'] .theme-admonition-secondary { --callout-accent: #2dd4bf; } +[data-theme='dark'] .theme-admonition-warning { --callout-accent: #fbbf24; } +[data-theme='dark'] .theme-admonition-danger, +[data-theme='dark'] .theme-admonition-caution { --callout-accent: #f87171; } +[data-theme='dark'] .theme-admonition-success { --callout-accent: #34d399; } +[data-theme='dark'] .theme-admonition-note { --callout-accent: #94a3b8; } +[data-theme='dark'] .theme-admonition-important { --callout-accent: #fb7185; } /* ============================================ RESPONSIVE DOCUMENTATION @@ -546,45 +606,45 @@ @media (max-width: 996px) { .markdown > h1 { - font-size: 2.25rem; + font-size: 1.75rem; } .markdown > h2 { - font-size: 1.75rem; - margin-top: 2.5rem; + font-size: 1.375rem; + margin-top: 1.5rem; } .markdown > h3 { - font-size: 1.375rem; + font-size: 1.125rem; } } @media (max-width: 768px) { .markdown { - font-size: 0.95rem; + font-size: 0.9375rem; } .markdown > h1 { - font-size: 2rem; + font-size: 1.625rem; } .markdown > h2 { - font-size: 1.5rem; - margin-top: 2rem; + font-size: 1.25rem; + margin-top: 1.25rem; } .markdown > h3 { - font-size: 1.25rem; - margin-top: 1.75rem; + font-size: 1.0625rem; + margin-top: 1.125rem; } .markdown table { - font-size: 0.875rem; + font-size: 0.75rem; } .markdown table th, .markdown table td { - padding: 0.75rem 1rem; + padding: 0.5rem 0.625rem; } } diff --git a/website/src/css/footer.css b/website/src/css/footer.css index e26b54be..6723fd0e 100644 --- a/website/src/css/footer.css +++ b/website/src/css/footer.css @@ -28,11 +28,12 @@ letter-spacing: 0.06em; text-transform: uppercase; color: #94a3b8; - margin-bottom: 1rem; + margin-bottom: 0.5rem; } .footer__link-item { color: #e2e8f0; + line-height: 1.75; transition: color 160ms var(--ease-footer); } @@ -48,8 +49,8 @@ /* Space between link grid and meta row */ .footer__links { - margin-bottom: 2.5rem; - padding-bottom: 0.5rem; + margin-bottom: 1rem; + padding-bottom: 0.25rem; } /* Mobile: collapsible footer columns (native
) */ @@ -71,12 +72,12 @@ align-items: center; justify-content: space-between; gap: 1rem; - min-height: 2.75rem; - padding-block: 0.35rem; + min-height: 2.25rem; + padding-block: 0.3rem; cursor: pointer; list-style: none; transition: transform 160ms var(--ease-footer); - margin-bottom: 1rem; + margin-bottom: 0.75rem; } .footer__accordionSummary::-webkit-details-marker { @@ -147,7 +148,7 @@ .footer__bottom { margin-top: 0; - padding-top: 2rem; + padding-top: 0.875rem; border-top: 1px solid var(--footer-meta-border); } @@ -156,7 +157,7 @@ flex-direction: column; align-items: center; justify-content: center; - gap: 1.25rem; + gap: 1rem; } @media (min-width: 997px) { @@ -164,7 +165,7 @@ flex-direction: row; align-items: center; justify-content: space-between; - gap: 1.5rem; + gap: 0.75rem; } } @@ -185,7 +186,7 @@ .footer__copyrightCol .footer__copyright, .footer__copyright { - font-size: 0.9rem; + font-size: 0.8125rem; line-height: 1.6; color: #94a3b8; } @@ -256,14 +257,14 @@ .netlifyBadge a { display: inline-flex; align-items: center; - gap: 8px; - padding: 8px 16px; + gap: 6px; + padding: 6px 12px; background: var(--netlify-badge-bg-light); border: 1px solid var(--netlify-badge-color); border-radius: 9999px; color: #ffffff; text-decoration: none; - font-size: 0.875rem; + font-size: 0.75rem; font-weight: 500; transition: background-color 160ms var(--ease-footer), @@ -291,8 +292,8 @@ } .netlifyBadge .badgeDot { - width: 8px; - height: 8px; + width: 6px; + height: 6px; border-radius: 50%; background: var(--netlify-badge-color); flex-shrink: 0; @@ -327,11 +328,11 @@ } .footer__bottom { - padding-top: 1.75rem; + padding-top: 1.25rem; } .footer__metaRow { - gap: 1rem; + gap: 0.75rem; } } diff --git a/website/src/css/hero.css b/website/src/css/hero.css index fe957eb1..6acfd350 100644 --- a/website/src/css/hero.css +++ b/website/src/css/hero.css @@ -27,17 +27,17 @@ .hero__title { font-family: var(--ifm-heading-font-family); - font-size: 3.5rem; - font-weight: 800; + font-size: 2.5rem; + font-weight: 700; letter-spacing: -0.02em; color: white !important; } .hero__subtitle { - font-size: 1.5rem; + font-size: 1.125rem; color: rgba(255, 255, 255, 0.95) !important; font-weight: 400; max-width: 700px; - margin: 1.5rem auto; - line-height: 1.6; + margin: 0.75rem auto; + line-height: 1.5; } \ No newline at end of file diff --git a/website/src/css/navbar.css b/website/src/css/navbar.css index ddcd37b5..91cf2f58 100644 --- a/website/src/css/navbar.css +++ b/website/src/css/navbar.css @@ -8,7 +8,7 @@ ============================================ */ .navbar { - height: 70px; + height: 60px; background-color: rgba(255, 255, 255, 0.85) !important; border-bottom: 1px solid rgba(59, 130, 246, 0.1); box-shadow: 0 4px 20px rgba(0, 0, 0, 0.03); @@ -16,7 +16,7 @@ z-index: 100; position: sticky; top: 0; - padding: 0 2rem; + padding: 0 1.25rem; } /* Apply backdrop-filter only on desktop to avoid mobile z-index issues */ @@ -56,8 +56,8 @@ .navbar__brand { display: flex; align-items: center; - gap: 0.5rem; - margin-right: 2rem; + gap: 0.4rem; + margin-right: 1.25rem; transition: transform 0.3s ease; } @@ -67,7 +67,7 @@ .navbar__title { font-weight: 800; - font-size: 1.4rem; + font-size: 1.25rem; letter-spacing: -0.02em; line-height: 1.2; background: linear-gradient(135deg, #3b82f6 0%, #1e40af 100%); @@ -85,9 +85,9 @@ } .navbar__logo { - height: 2.4rem; - width: 2.4rem; - min-width: 2.4rem; + height: 2rem; + width: 2rem; + min-width: 2rem; transition: transform 0.3s ease; display: flex; align-items: center; @@ -125,9 +125,9 @@ } .navbar__link { - font-size: 0.95rem; + font-size: 0.875rem; font-weight: 500; - padding: 0.5rem 1rem; + padding: 0.4rem 0.75rem; border-radius: 0.5rem; color: #475569; transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1); @@ -168,8 +168,8 @@ content: ''; position: absolute; bottom: 0; - left: 1rem; - right: 1rem; + left: 0.75rem; + right: 0.75rem; height: 2px; background: linear-gradient(90deg, #3b82f6 0%, #60a5fa 100%); border-radius: 2px; @@ -196,14 +196,14 @@ ============================================ */ .dropdown__menu { - border-radius: 0.75rem; + border-radius: 0.625rem; backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px); background-color: rgba(255, 255, 255, 0.95) !important; border: 1px solid rgba(59, 130, 246, 0.1); box-shadow: 0 10px 40px rgba(0, 0, 0, 0.08); - padding: 0.5rem; - min-width: 200px; + padding: 0.4rem; + min-width: 180px; animation: dropdownSlide 0.2s ease-out; } @@ -225,7 +225,7 @@ } .dropdown__link { - padding: 0.5rem 1rem; + padding: 0.4rem 0.75rem; border-radius: 0.5rem; color: #475569; transition: all 0.2s ease; @@ -339,7 +339,7 @@ /* Mobile sidebar header */ .navbar-sidebar__brand { background: #f1f5f9; - padding: 1.25rem 1rem; + padding: 1rem 0.875rem; border-bottom: 1px solid #e2e8f0; box-shadow: 0 1px 3px rgba(15, 23, 42, 0.06); } @@ -370,8 +370,8 @@ /* Mobile menu links */ .navbar-sidebar .menu__link, .navbar-sidebar .navbar__link { - padding: 0.875rem 1rem; - border-radius: 0.5rem; + padding: 0.55rem 0.75rem; + border-radius: 0.4375rem; font-weight: 500; transition: all 0.2s ease; } diff --git a/website/src/css/responsive.css b/website/src/css/responsive.css index 6c79a0b3..5a222554 100644 --- a/website/src/css/responsive.css +++ b/website/src/css/responsive.css @@ -6,39 +6,39 @@ /* Feature card responsive adjustments */ @media (max-width: 1200px) { .feature-card { - padding: 2rem 1.5rem; + padding: 1.375rem 1.125rem; } } @media (max-width: 768px) { .hero__title { - font-size: 2.5rem; + font-size: 2.125rem; } .hero__subtitle { - font-size: 1.125rem; + font-size: 1.0625rem; } .feature-card { - padding: 2rem 1.5rem; + padding: 1.25rem 1.125rem; } .feature-icon { - font-size: 3rem; + font-size: 2.25rem; } .feature-card h3 { - font-size: 1.125rem; + font-size: 1.0625rem; } } @media (max-width: 480px) { .feature-card { - padding: 1.5rem 1.25rem; + padding: 1.125rem 1rem; } .feature-icon { - font-size: 2.5rem; + font-size: 2rem; } } @@ -46,20 +46,20 @@ @media (max-width: 996px) { /* Footer on mobile - make it more prominent */ .footer { - padding: 2rem 1rem; + padding: 1.5rem 1rem; } .footer__title { - font-size: 1rem; - margin-bottom: 1rem; + font-size: 0.875rem; + margin-bottom: 0.75rem; } .footer__item { - padding: 0.5rem 0; - font-size: 0.95rem; + padding: 0.35rem 0; + font-size: 0.9rem; } .footer__links { - margin-bottom: 2rem; + margin-bottom: 1.25rem; } } diff --git a/website/src/css/search.css b/website/src/css/search.css index c9b295cf..93484194 100644 --- a/website/src/css/search.css +++ b/website/src/css/search.css @@ -244,7 +244,7 @@ /* Empty state with concentric circles */ .DocSearch-NoResults, .DocSearch-StartScreen { - padding: 4rem 2rem; + padding: 2rem 1.5rem; text-align: center; position: relative; } @@ -709,7 +709,7 @@ /* Adjust search bar padding for mobile - lower the input */ .DocSearch-SearchBar { - padding: 3rem 1rem 0.75rem 1rem; + padding: 1.5rem 1rem 0.625rem 1rem; } /* Make Cancel button visible on mobile but styled */ @@ -726,7 +726,7 @@ /* Adjust empty state for mobile */ .DocSearch-NoResults, .DocSearch-StartScreen { - padding: 3rem 1.5rem; + padding: 2rem 1.25rem; } .DocSearch-NoResults::before, diff --git a/website/src/css/sidebar.css b/website/src/css/sidebar.css index c7574bda..0dd63c0e 100644 --- a/website/src/css/sidebar.css +++ b/website/src/css/sidebar.css @@ -34,48 +34,62 @@ } /* Menu links */ -.menu__link { +.theme-doc-sidebar-container .menu__link, +.theme-doc-sidebar-container .menu__caret { color: #475569; - border-radius: 0.375rem; + border-radius: 0.3125rem; font-size: 0.8125rem; - padding: 0.3rem 0.5rem; + padding: 0.225rem 0.4rem; + line-height: 1.4; transition: all 0.2s ease; } /* Top-level non-collapsible items (e.g. Introduction) */ -.menu__list-item > .menu__link { - font-size: 0.875rem; +.theme-doc-sidebar-container .menu__list-item > .menu__link { + font-size: 0.84375rem; } -.menu__list-item-collapsible > .menu__caret, -.menu__list-item-collapsible > .menu__link { - font-size: 0.875rem; - padding: 0.3rem 0.5rem; +.theme-doc-sidebar-container .menu__list-item-collapsible > .menu__caret, +.theme-doc-sidebar-container .menu__list-item-collapsible > .menu__link { + font-size: 0.84375rem; + padding: 0.225rem 0.4rem; } -.menu__link:hover { +.theme-doc-sidebar-container .menu__list-item-collapsible > .menu__caret:before, +.theme-doc-sidebar-container .menu__link--sublist-caret:after { + width: 0.95rem; + height: 0.95rem; + min-width: 0.95rem; + background-size: 0.95rem 0.95rem; +} + +.theme-doc-sidebar-container .menu__list-item:not(:first-child) { + margin-top: 0.125rem; +} + +.theme-doc-sidebar-container .menu__link:hover { background: #f1f5f9; color: #0f172a; } -.menu__link--active { +.theme-doc-sidebar-container .menu__link--active { background: rgba(59, 130, 246, 0.1); color: #3b82f6 !important; font-weight: 600; } -.menu__link:hover { +.theme-doc-sidebar-container .menu__link:hover { background: var(--ifm-color-emphasis-100); } -.menu__link--active:hover { +.theme-doc-sidebar-container .menu__link--active:hover { background: rgba(59, 130, 246, 0.15); color: #2563eb !important; } /* Dark mode menu */ [data-theme='dark'] .menu__list-item-collapsible { - border-radius: 0.375rem; + border-radius: 0.3125rem; } [data-theme='dark'] .menu__list-item-collapsible:hover { @@ -84,7 +98,7 @@ [data-theme='dark'] .menu__link { color: #a0a0a0; - border-radius: 0.375rem; + border-radius: 0.3125rem; } [data-theme='dark'] .menu__link:hover { diff --git a/website/src/css/variables.css b/website/src/css/variables.css index 8d9343fe..ca864efa 100644 --- a/website/src/css/variables.css +++ b/website/src/css/variables.css @@ -45,6 +45,16 @@ /* Spacing and borders */ --ifm-global-radius: 0.5rem; --ifm-button-border-radius: 0.5rem; + --doc-sidebar-width: 260px; + --doc-sidebar-hidden-width: 28px; + --ifm-toc-padding-vertical: 0.225rem; + --ifm-toc-padding-horizontal: 0.375rem; + --ifm-toc-font-size: 0.75rem; + --ifm-toc-line-height: 1.45; + + /* Footer padding — scaled down from Infima defaults (2rem) */ + --ifm-footer-padding-vertical: 1.25rem; + --ifm-footer-padding-horizontal: 1.5rem; /** Horizontal padding for main content when blog sidebar is closed */ --ifm-sidebar-content-margin-x: 2rem; @@ -207,22 +217,23 @@ main { /* Markdown typography variables */ .markdown { - --ifm-h1-font-size: 2.5rem; - --ifm-h2-font-size: 2rem; - --ifm-h3-font-size: 1.5rem; + --ifm-h1-font-size: 2rem; + --ifm-h2-font-size: 1.5rem; + --ifm-h3-font-size: 1.25rem; + --ifm-h4-font-size: 1.0625rem; } /* Markdown headings */ .markdown h1 { color: var(--ifm-heading-color); - margin-bottom: .5rem; + margin-bottom: .4rem; } .markdown h2 { border-bottom: 2px solid var(--ifm-color-emphasis-200); - padding-bottom: 0.5rem; - margin-top: 3rem; - margin-bottom: 1.5rem; + padding-bottom: 0.4rem; + margin-top: 1.75rem; + margin-bottom: 0.75rem; } /* Dark mode markdown */ diff --git a/website/src/pages/index.js b/website/src/pages/index.js index 35cec878..07a10e69 100644 --- a/website/src/pages/index.js +++ b/website/src/pages/index.js @@ -9,8 +9,8 @@ import CtaSection from '../components/home/CtaSection'; export default function Home() { return ( + title={`Smart Contract Development Framework for Diamonds`} + description="Compose is a framework for building modular, maintainable smart contract systems with reusable facets, shared modules, and ERC-2535 Diamonds.">
diff --git a/website/src/pages/index.module.css b/website/src/pages/index.module.css index 7c5954e3..37fca0fb 100644 --- a/website/src/pages/index.module.css +++ b/website/src/pages/index.module.css @@ -4,7 +4,7 @@ :where(.heroBanner) { position: relative; - padding: 6rem 0 14rem; + padding: 4rem 0 7rem; overflow: hidden; min-height: auto; display: flex; @@ -93,12 +93,12 @@ } :where(.heroTitle) { - font-size: clamp(3rem, 8vw, 5rem); - font-weight: 900; - line-height: 1.1; + font-size: clamp(2.25rem, 6vw, 3.5rem); + font-weight: 800; + line-height: 1.15; letter-spacing: -0.04em; color: var(--hero-text-strong); - margin-bottom: 1rem; + margin-bottom: 0.75rem; animation: fadeInUp 0.8s ease-out 0.2s both; } @@ -111,20 +111,20 @@ } :where(.heroSubtitle) { - font-size: clamp(1.125rem, 2.5vw, 1.5rem); + font-size: clamp(1rem, 2.2vw, 1.25rem); color: var(--hero-text-medium); font-weight: 500; - line-height: 1.6; - margin-bottom: 1rem; + line-height: 1.5; + margin-bottom: 0.75rem; animation: fadeInUp 0.8s ease-out 0.3s both; } :where(.heroDescription) { - font-size: clamp(1rem, 2vw, 1.125rem); + font-size: clamp(0.9375rem, 1.8vw, 1.0625rem); color: var(--hero-text-weak); - line-height: 1.8; + line-height: 1.55; max-width: 720px; - margin: 0 auto 2rem; + margin: 0 auto 1.25rem; animation: fadeInUp 0.8s ease-out 0.4s both; } @@ -132,9 +132,9 @@ display: flex; align-items: center; justify-content: center; - gap: 1rem; + gap: 0.875rem; flex-wrap: wrap; - margin-bottom: 2rem; + margin-bottom: 1.25rem; animation: fadeInUp 0.8s ease-out 0.5s both; } @@ -282,7 +282,7 @@ ======================================== */ .featuresSection { - padding: 8rem 0; + padding: 4rem 0; background: white; position: relative; } @@ -290,53 +290,53 @@ .sectionHeader { text-align: center; max-width: 760px; - margin: 0 auto 5rem; + margin: 0 auto 2.5rem; } .sectionBadge { display: inline-block; - padding: 0.5rem 1rem; + padding: 0.4rem 0.875rem; background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(37, 99, 235, 0.1)); border: 1px solid rgba(59, 130, 246, 0.2); border-radius: 9999px; color: #3b82f6; - font-size: 0.875rem; + font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; - margin-bottom: 1.5rem; + margin-bottom: 1rem; } .sectionTitle { - font-size: clamp(2.25rem, 5vw, 3.5rem); - font-weight: 800; + font-size: clamp(1.75rem, 4vw, 2.5rem); + font-weight: 700; line-height: 1.2; letter-spacing: -0.03em; color: #0f172a; - margin-bottom: 1.5rem; + margin-bottom: 1rem; } .sectionSubtitle { - font-size: clamp(1rem, 2vw, 1.25rem); - line-height: 1.7; + font-size: clamp(0.9375rem, 1.8vw, 1.0625rem); + line-height: 1.55; color: #64748b; margin: 0; } .featuresGrid { display: grid; - grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); - gap: 2rem; + grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); + gap: 1.5rem; max-width: 1280px; margin: 0 auto; } .featureCard { position: relative; - padding: 2.5rem; + padding: 1.5rem; background: white; border: 1px solid #e2e8f0; - border-radius: 1.25rem; + border-radius: 0.75rem; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); overflow: hidden; } @@ -367,33 +367,33 @@ } .featureIcon { - width: 56px; - height: 56px; + width: 48px; + height: 48px; display: flex; align-items: center; justify-content: center; background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(37, 99, 235, 0.1)); - border-radius: 1rem; - margin-bottom: 1.5rem; + border-radius: 0.75rem; + margin-bottom: 1rem; color: #3b82f6; } .featureIcon svg { - width: 28px; - height: 28px; + width: 24px; + height: 24px; } .featureTitle { - font-size: 1.375rem; + font-size: 1.1875rem; font-weight: 700; color: #0f172a; - margin: 0 0 1rem; - line-height: 1.3; + margin: 0 0 0.75rem; + line-height: 1.25; } .featureDescription { - font-size: 1rem; - line-height: 1.7; + font-size: 0.9375rem; + line-height: 1.55; color: #64748b; margin: 0; } @@ -403,7 +403,7 @@ ======================================== */ .showcaseSection { - padding: 8rem 0; + padding: 4rem 0; background: linear-gradient(180deg, #f8fafc 0%, #ffffff 100%); position: relative; overflow: hidden; @@ -412,14 +412,14 @@ .showcaseGrid { display: grid; grid-template-columns: 1fr 1fr; - gap: 4rem; + gap: 2.5rem; align-items: center; max-width: 1400px; margin: 0 auto; } .showcaseContent { - padding: 0 2rem; + padding: 0 1.5rem; text-align: center; display: flex; flex-direction: column; @@ -428,39 +428,39 @@ .showcaseBadge { display: inline-block; - padding: 0.5rem 1rem; + padding: 0.4rem 0.875rem; background: linear-gradient(135deg, rgba(59, 130, 246, 0.1), rgba(96, 165, 250, 0.1)); border: 1px solid rgba(59, 130, 246, 0.2); border-radius: 9999px; color: #3b82f6; - font-size: 0.875rem; + font-size: 0.8125rem; font-weight: 600; letter-spacing: 0.05em; text-transform: uppercase; - margin-bottom: 1.5rem; + margin-bottom: 1rem; } .showcaseTitle { - font-size: clamp(2rem, 4vw, 3rem); - font-weight: 800; + font-size: clamp(1.75rem, 3.5vw, 2.25rem); + font-weight: 700; line-height: 1.2; letter-spacing: -0.03em; color: #0f172a; - margin-bottom: 1.5rem; + margin-bottom: 1rem; } .showcaseDescription { - font-size: 1.125rem; - line-height: 1.8; + font-size: 1rem; + line-height: 1.55; color: #64748b; - margin-bottom: 2.5rem; + margin-bottom: 1.5rem; } .showcaseFeatures { display: flex; flex-direction: column; - gap: 1.5rem; - margin-bottom: 2.5rem; + gap: 1.125rem; + margin-bottom: 1.5rem; width: 100%; max-width: 600px; } @@ -468,11 +468,11 @@ .showcaseFeature { display: flex; align-items: flex-start; - gap: 1rem; - padding: 1.5rem; + gap: 0.875rem; + padding: 1.125rem; background: white; border: 1px solid #e2e8f0; - border-radius: 1rem; + border-radius: 0.75rem; transition: all 0.25s ease; text-align: left; } @@ -633,7 +633,7 @@ ======================================== */ .statsSection { - padding: 6rem 0; + padding: 3.5rem 0; background: #0f172a; position: relative; overflow: hidden; @@ -651,8 +651,8 @@ .statsGrid { position: relative; display: grid; - grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); - gap: 2rem; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); + gap: 1.5rem; max-width: 1200px; margin: 0 auto; } @@ -660,19 +660,19 @@ .statCard { position: relative; text-align: center; - padding: 3rem 2rem; + padding: 1.75rem 1.25rem; background: rgba(255, 255, 255, 0.03); backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px); border: 1px solid rgba(255, 255, 255, 0.08); - border-radius: 1.25rem; + border-radius: 0.75rem; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); overflow: hidden; display: flex; flex-direction: column; align-items: center; justify-content: center; - min-height: 220px; + min-height: 160px; } .statCard::before { @@ -699,8 +699,8 @@ } .statIcon { - font-size: 3rem; - margin-bottom: 1.25rem; + font-size: 2.25rem; + margin-bottom: 0.75rem; display: block; filter: grayscale(0); transition: transform 0.3s ease; @@ -711,20 +711,20 @@ } .statValue { - font-size: clamp(1.75rem, 2.2vw, 2.5rem); - font-weight: 900; + font-size: clamp(1.5rem, 2vw, 2rem); + font-weight: 700; background: linear-gradient(135deg, #60a5fa 0%, #3b82f6 50%, #2563eb 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; - margin-bottom: 0.75rem; + margin-bottom: 0.5rem; line-height: 1; white-space: nowrap; word-break: keep-all; } .statLabel { - font-size: 1rem; + font-size: 0.875rem; color: rgba(255, 255, 255, 0.7); font-weight: 600; letter-spacing: 0.025em; @@ -735,7 +735,7 @@ ======================================== */ .ctaSection { - padding: 8rem 0; + padding: 4rem 0; background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%); position: relative; } @@ -744,34 +744,34 @@ max-width: 800px; margin: 0 auto; text-align: center; - padding: 4rem 2rem; + padding: 2.5rem 1.5rem; background: white; border: 1px solid #e2e8f0; - border-radius: 2rem; + border-radius: 1.25rem; box-shadow: 0 20px 40px rgba(0, 0, 0, 0.08); } .ctaTitle { - font-size: clamp(2rem, 4vw, 3rem); - font-weight: 800; + font-size: clamp(1.75rem, 3.5vw, 2.25rem); + font-weight: 700; line-height: 1.2; letter-spacing: -0.03em; color: #0f172a; - margin-bottom: 1.5rem; + margin-bottom: 1rem; } .ctaDescription { - font-size: 1.125rem; - line-height: 1.7; + font-size: 1rem; + line-height: 1.55; color: #64748b; - margin-bottom: 2.5rem; + margin-bottom: 1.5rem; } .ctaButtons { display: flex; align-items: center; justify-content: center; - gap: 1rem; + gap: 0.75rem; flex-wrap: wrap; } @@ -808,13 +808,13 @@ /* Tablets (≤1024px) */ @media screen and (max-width: 1024px) { .heroBanner { - padding: 8rem 0 10rem; - min-height: 80vh; + padding: 4.5rem 0 6rem; + min-height: auto; } .showcaseGrid { grid-template-columns: 1fr; - gap: 3rem; + gap: 2rem; } .showcaseContent, @@ -823,37 +823,37 @@ } .featuresGrid { - grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); - gap: 1.5rem; + grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)); + gap: 1.25rem; } } /* Tablets and smaller (≤768px) */ @media screen and (max-width: 768px) { .heroBanner { - padding: 6rem 0 8rem; + padding: 3.5rem 0 5rem; min-height: auto; } .heroTitle { - font-size: 2.5rem; - margin-bottom: 1rem; + font-size: 2.125rem; + margin-bottom: 0.75rem; } .heroSubtitle { - font-size: 1.125rem; - margin-bottom: 1rem; + font-size: 1rem; + margin-bottom: 0.5rem; } .heroDescription { - font-size: 1rem; - margin-bottom: 2rem; + font-size: 0.9375rem; + margin-bottom: 1.25rem; } .heroCta { flex-direction: column; - gap: 0.75rem; - margin-bottom: 2rem; + gap: 0.625rem; + margin-bottom: 1.25rem; } .ctaButton { @@ -864,7 +864,7 @@ .heroLinks { flex-direction: column; - gap: 0.75rem; + gap: 0.625rem; } .heroLink { @@ -874,51 +874,51 @@ } .featuresSection { - padding: 5rem 0; + padding: 2.5rem 0; } .sectionHeader { - margin-bottom: 3rem; + margin-bottom: 2rem; } .sectionTitle { - font-size: 2rem; - margin-bottom: 1rem; + font-size: 1.75rem; + margin-bottom: 0.75rem; } .sectionSubtitle { - font-size: 1rem; + font-size: 0.9375rem; } .featuresGrid { grid-template-columns: 1fr; - gap: 1.25rem; + gap: 1rem; } .featureCard { - padding: 2rem; + padding: 1.25rem; } .featureIcon { - width: 48px; - height: 48px; + width: 40px; + height: 40px; } .featureIcon svg { - width: 24px; - height: 24px; + width: 20px; + height: 20px; } .featureTitle { - font-size: 1.25rem; + font-size: 1.0625rem; } .featureDescription { - font-size: 0.9375rem; + font-size: 0.875rem; } .showcaseSection { - padding: 5rem 0; + padding: 2.5rem 0; } /* Center container on tablets */ @@ -932,7 +932,7 @@ .showcaseGrid { grid-template-columns: 1fr; - gap: 2.5rem; + gap: 2rem; justify-items: center; margin: 0 auto; width: 100%; @@ -950,13 +950,13 @@ } .showcaseTitle { - font-size: 1.875rem; + font-size: 1.75rem; text-align: center; } .showcaseDescription { - font-size: 1rem; - margin-bottom: 2rem; + font-size: 0.9375rem; + margin-bottom: 1.25rem; text-align: center; } @@ -977,7 +977,7 @@ } .showcaseFeature { - padding: 1.25rem; + padding: 1rem; flex-direction: row; } @@ -1020,53 +1020,53 @@ } .statsSection { - padding: 4rem 0; + padding: 2.25rem 0; } .statsGrid { grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); - gap: 1.25rem; + gap: 1rem; } .statCard { - padding: 2rem 1rem; + padding: 1.25rem 0.875rem; } .statIcon { - font-size: 2.5rem; - margin-bottom: 1rem; + font-size: 2rem; + margin-bottom: 0.625rem; } .statValue { - font-size: 2rem; + font-size: 1.5rem; } .statLabel { - font-size: 0.875rem; + font-size: 0.8125rem; } .ctaSection { - padding: 5rem 0; + padding: 2.5rem 0; } .ctaContent { - padding: 3rem 1.5rem; - border-radius: 1.5rem; + padding: 1.75rem 1.25rem; + border-radius: 1rem; } .ctaTitle { - font-size: 1.875rem; - margin-bottom: 1rem; + font-size: 1.625rem; + margin-bottom: 0.75rem; } .ctaDescription { - font-size: 1rem; - margin-bottom: 2rem; + font-size: 0.9375rem; + margin-bottom: 1.25rem; } .ctaButtons { flex-direction: column; - gap: 0.75rem; + gap: 0.625rem; } .ctaButtons .ctaButton { @@ -1078,28 +1078,28 @@ /* Mobile phones (≤480px) */ @media screen and (max-width: 480px) { .heroBanner { - padding: 5rem 0 6rem; + padding: 3rem 0 4rem; } .heroTitle { - font-size: 2rem; + font-size: 1.875rem; } .heroSubtitle { - font-size: 1rem; + font-size: 0.9375rem; } .badge { - font-size: 0.8125rem; - padding: 0.625rem 1.25rem; + font-size: 0.75rem; + padding: 0.5rem 1rem; } .sectionTitle { - font-size: 1.75rem; + font-size: 1.625rem; } .showcaseSection { - padding: 3rem 0; + padding: 2rem 0; } /* Override Docusaurus container padding on mobile for proper centering */ @@ -1117,7 +1117,7 @@ flex-direction: column; align-items: center; justify-content: center; - gap: 2.5rem; + gap: 2rem; width: 100%; margin: 0 auto; padding: 0; @@ -1135,7 +1135,7 @@ } .showcaseTitle { - font-size: 1.5rem; + font-size: 1.375rem; text-align: center; } @@ -1211,7 +1211,7 @@ } .featureCard { - padding: 1.5rem; + padding: 1.25rem; } .statsGrid { @@ -1220,7 +1220,7 @@ } .ctaContent { - padding: 2.5rem 1.25rem; + padding: 1.5rem 1rem; } } diff --git a/website/src/theme/BlogLayout/index.js b/website/src/theme/BlogLayout/index.js index d6bfdaa2..8e6f2437 100644 --- a/website/src/theme/BlogLayout/index.js +++ b/website/src/theme/BlogLayout/index.js @@ -39,15 +39,23 @@ export default function BlogLayout(props) { {hasSidebar && }
{isBlogArticlePage && } {children}
- {toc &&
{toc}
} + {toc && ( +
+ {/* Same structure/classes as docs TOC rail so type scale matches exactly */} +
+
+
{toc}
+
+
+
+ )} diff --git a/website/src/theme/DocItem/Layout/styles.module.css b/website/src/theme/DocItem/Layout/styles.module.css index 85e5557e..558f498c 100644 --- a/website/src/theme/DocItem/Layout/styles.module.css +++ b/website/src/theme/DocItem/Layout/styles.module.css @@ -8,6 +8,7 @@ @media (min-width: 997px) { .docItemCol { + /* must leave 25% for the col--3 TOC rail, otherwise the row wraps below */ max-width: 75% !important; } diff --git a/website/src/theme/Footer/styles.module.css b/website/src/theme/Footer/styles.module.css index 84184a56..23ff987a 100644 --- a/website/src/theme/Footer/styles.module.css +++ b/website/src/theme/Footer/styles.module.css @@ -15,7 +15,7 @@ .footerWrapper :global(.footer__links) { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); - gap: 2rem; + gap: 1.5rem; } /* Newsletter section styling - appears as a footer column */ @@ -28,8 +28,8 @@ /* Desktop: Newsletter appears as rightmost column with larger width */ @media (min-width: 997px) { .footerWrapper :global(.footer__links) { - grid-template-columns: repeat(3, 1fr) 480px; - gap: 2rem; + grid-template-columns: repeat(3, 1fr) 320px; + gap: 1.5rem; } /* Newsletter is naturally last in DOM on desktop, no order needed */ diff --git a/website/src/theme/Layout/index.js b/website/src/theme/Layout/index.js index c61e8331..08d24ea2 100644 --- a/website/src/theme/Layout/index.js +++ b/website/src/theme/Layout/index.js @@ -3,8 +3,8 @@ import Layout from '@theme-original/Layout'; import AnnouncementBanner from '@site/src/components/ui/AnnouncementBanner'; const CURRENT_BANNER = { - id: '2026-q1-eip8153-draft-announcement', - message: ' EIP-8153: New Facet-Based Diamond Proposal', + id: '2026-q4-erc8153-last-call-announcement', + message: ' ERC-8153: Facet-Based Diamonds. Review before it goes final.', linkHref: 'https://eips.ethereum.org/EIPS/eip-8153', linkLabel: 'Read here', persistence: 'session', diff --git a/website/src/theme/MDXPage/index.js b/website/src/theme/MDXPage/index.js index 7e96a9e0..138692a2 100644 --- a/website/src/theme/MDXPage/index.js +++ b/website/src/theme/MDXPage/index.js @@ -82,7 +82,7 @@ function MDXPageAside({ title, soloInSidebar = false }) { className={styles.reportLink} target="_blank" rel="noopener noreferrer"> - + Report issue ); diff --git a/website/src/theme/MDXPage/styles.module.css b/website/src/theme/MDXPage/styles.module.css index 5eaa6a13..37561aa5 100644 --- a/website/src/theme/MDXPage/styles.module.css +++ b/website/src/theme/MDXPage/styles.module.css @@ -46,6 +46,7 @@ /* ---------- DocItem content / right rail ---------- */ @media (min-width: 997px) { .docItemCol { + /* must leave 25% for the col--3 TOC rail, otherwise the row wraps below */ max-width: 75% !important; } @@ -205,10 +206,10 @@ .reportLink { display: inline-flex; align-items: center; - gap: 0.375rem; - font-size: 0.8125rem; + gap: 0.3rem; + font-size: 0.75rem; font-weight: 500; - color: var(--ifm-color-emphasis-700); + color: var(--ifm-font-color-base); text-decoration: none; } @@ -217,10 +218,6 @@ text-decoration: none; } -[data-theme='dark'] .reportLink { - color: var(--ifm-color-emphasis-600); -} - [data-theme='dark'] .reportLink :global(img) { filter: brightness(0) invert(1); } diff --git a/website/src/theme/Navbar/Content/index.js b/website/src/theme/Navbar/Content/index.js index 99bcd92d..ae02b943 100644 --- a/website/src/theme/Navbar/Content/index.js +++ b/website/src/theme/Navbar/Content/index.js @@ -74,8 +74,8 @@ export default function NavbarContent() { className={styles.earlyStageLink} rel="noopener noreferrer"> - - Early Stage Development + Early Stage diff --git a/website/src/theme/Navbar/Content/styles.module.css b/website/src/theme/Navbar/Content/styles.module.css index 67495c86..aa4b6fb9 100644 --- a/website/src/theme/Navbar/Content/styles.module.css +++ b/website/src/theme/Navbar/Content/styles.module.css @@ -41,31 +41,114 @@ box-shadow: 0 4px 12px rgba(234, 179, 8, 0.2); } -/* Badge pulse animation */ +/* 3D rotating facet-orb indicator (EIP-2535 diamond motif): + gold facet texture sweeps across a sphere while static specular + highlight + limb darkening sell the volume. The roll is done with a + composited translate3d (GPU, sub-pixel) instead of background-position + (paint-only, snaps to whole device pixels = stutter). */ .badgeDot { - width: 8px; - height: 8px; - background: #eab308; + position: relative; + width: 13px; + height: 13px; + flex-shrink: 0; border-radius: 50%; - animation: pulse 2s ease-in-out infinite; + overflow: hidden; + box-shadow: 0 0 6px rgba(250, 204, 21, 0.5); + animation: orbBob 3.2s ease-in-out infinite; +} + +/* Oversized facet strip, one 8px period wide, translated by the compositor */ +.badgeDot::before { + content: ''; + position: absolute; + top: 0; + bottom: 0; + left: 0; + width: calc(100% + 8px); + /* Yellow flame ramp: pale-hot flash over deep amber embers */ + background: repeating-linear-gradient( + 90deg, + #fbbf24 0, + #fef9c3 2px, + #f59e0b 3.5px, + #fde047 5px, + #d97706 6.5px, + #fbbf24 8px + ); + animation: gemRoll 2.6s linear infinite; + will-change: transform; + backface-visibility: hidden; +} + +/* Static sphere shading: hot specular, ember bounce, blue flame core + at the base, red limb darkening */ +.badgeDot::after { + content: ''; + position: absolute; + inset: 0; + border-radius: 50%; + background: + radial-gradient(circle at 32% 28%, rgba(254, 252, 232, 0.95) 0%, rgba(254, 252, 232, 0) 45%), + radial-gradient(circle at 68% 80%, rgba(252, 211, 77, 0.5) 0%, rgba(252, 211, 77, 0) 40%), + radial-gradient(circle at 50% 92%, rgba(96, 165, 250, 0.3) 0%, rgba(96, 165, 250, 0) 34%), + radial-gradient(circle at 50% 50%, rgba(146, 64, 14, 0) 52%, rgba(146, 64, 14, 0.6) 100%); + box-shadow: inset 0 -1.5px 2px rgba(253, 224, 71, 0.5); + pointer-events: none; } [data-theme='dark'] .badgeDot { - background: #fde047; + box-shadow: 0 0 9px rgba(253, 224, 71, 0.5); +} + +[data-theme='dark'] .badgeDot::before { + background: repeating-linear-gradient( + 90deg, + #facc15 0, + #fef08a 2px, + #eab308 3.5px, + #fde047 5px, + #ca8a04 6.5px, + #facc15 8px + ); +} + +[data-theme='dark'] .badgeDot::after { + background: + radial-gradient(circle at 32% 28%, rgba(254, 253, 240, 0.85) 0%, rgba(254, 253, 240, 0) 45%), + radial-gradient(circle at 68% 80%, rgba(253, 224, 71, 0.45) 0%, rgba(253, 224, 71, 0) 40%), + radial-gradient(circle at 50% 92%, rgba(59, 130, 246, 0.38) 0%, rgba(59, 130, 246, 0) 34%), + radial-gradient(circle at 50% 50%, rgba(113, 63, 18, 0) 52%, rgba(113, 63, 18, 0.68) 100%); + box-shadow: inset 0 -1.5px 2px rgba(254, 240, 138, 0.5); } .badgeText { line-height: 1; } -@keyframes pulse { +@keyframes gemRoll { + from { + transform: translate3d(0, 0, 0); + } + + to { + transform: translate3d(-8px, 0, 0); + } +} + +@keyframes orbBob { 0%, 100% { - opacity: 1; - transform: scale(1); + transform: translateY(0); } + 50% { - opacity: 0.5; - transform: scale(1.2); + transform: translateY(-1px); + } +} + +@media (prefers-reduced-motion: reduce) { + .badgeDot, + .badgeDot::before { + animation: none; } }