TSX Component Development Guide
This guide provides comprehensive standards for creating custom TSX components for ColivingLiguria pages, ensuring consistency, maintainability, and aesthetic excellence.
IMPORTANT
Read this document before creating any new custom page component
This guide is based on proven patterns from
NewHome.tsxandElectricalSystem.tsx. Following these standards ensures your pages maintain the siteโs visual identity and professional quality.
Table of Contents
- Color Palette & Theme
- Component Structure
- Styling Conventions
- Common Patterns
- Responsive Design
- Accessibility
- Code Examples
- Internationalization (Bilingual Support)
- Page Layout Configuration
- Code Examples
Page Layout Configuration
IMPORTANT
No Backlinks or Graph View on TSX Pages
Custom TSX pages (like the Homepage) are designed to be standalone experiences. You MUST disable the standard Quartz sidebar features (Backlinks, Graph View, Explorer) for these pages to prevent clutter and maintain visual focus.
How to disable in
quartz.layout.tsx: Ensure your custom pageโs layout configuration excludesComponent.Backlinks(),Component.Graph(), andComponent.Explorer().
Color Palette & Theme
Core Color Variables
Always use CSS variables - never hardcode colors. Our palette is defined in quartz.config.ts and available via CSS variables:
// Light Mode Colors
--light: "#F7F5F3" // Warm Alabaster (backgrounds)
--lightgray: "#E5E0D8" // Light Sand (secondary backgrounds)
--gray: "#948C84" // Stone (muted text, borders)
--darkgray: "#4E4B42" // Bark (secondary text)
--dark: "#2C2A24" // Deep Peat (primary text)
--secondary: "#4A6741" // Deep Moss Green (CTAs, highlights)
--tertiary: "#A67B5B" // Raw Sienna/Clay (accents)
// Dark Mode Colors (auto-transforms)
--light: "#0F0E0B" // Deep Earth Black
--lightgray: "#26231E" // Dark Soil
--gray: "#857F75" // Warm Stone
--darkgray: "#D6D1C9" // Bone/Light Sand
--dark: "#F0ECE6" // Off-white
--secondary: "#8FA876" // Light Moss/Sage
--tertiary: "#D4A373" // Buff/SandstoneUsage Examples
// โ
CORRECT - Using CSS variables
<div style="background: var(--lightgray); color: var(--dark);">
<h2 style="color: var(--secondary);">Title</h2>
</div>
// โ WRONG - Hardcoded colors
<div style="background: #E5E0D8; color: #2C2A24;">
<h2 style="color: #4A6741;">Title</h2>
</div>Color Application Rules
| Element | Color Variable | Usage |
|---|---|---|
| Page Background | var(--light) | Main page background |
| Section Background (Alt) | var(--lightgray) | Alternating sections for visual rhythm |
| Cards/Boxes | white in light mode, var(--lightgray) in dark | Elevated content containers |
| Primary Text | var(--dark) | Headings, important text |
| Secondary Text | var(--gray) | Body text, descriptions |
| Borders | var(--lightgray) | Subtle borders (2px max) |
| CTAs/Buttons | var(--secondary) background | Primary action buttons |
| Highlights | var(--secondary) or var(--tertiary) | Emphasis, badges, icons |
TIP
Dark Mode Compatibility
Never use pure
whiteor#FFFFFFfor backgrounds - usevar(--light). This ensures proper dark mode transformation.
CAUTION
CRITICAL: Light/Dark Mode Color Correspondence Validation
You MUST scrupulously verify that all colors work correctly in BOTH light mode and dark mode. Each color variable transforms automatically, and you need to ensure:
- Text remains readable in both modes
- Background/foreground contrast is sufficient in both modes
- Accent colors (
--secondary,--tertiary) are visible against their backgrounds in both modesBefore publishing any component, test it in:
- Light mode (default)
- Dark mode (toggle in browser)
Palette-Only Rule
WARNING
ONLY Use Palette Colors - NEVER Custom Colors
You are STRICTLY PROHIBITED from using any colors outside the defined palette. This means:
- โ
var(--light),var(--lightgray),var(--gray),var(--darkgray),var(--dark)- โ
var(--secondary),var(--tertiary)- โ
white(only for card backgrounds in light mode)- โ NO custom hex codes like
#FF5733or#123456- โ NO custom RGB values like
rgb(255, 100, 50)- โ NO named colors like
red,blue,greenIf you need a new color, request an update to the palette in quartz.config.ts first.
Light/Dark Mode Color Correspondence Table
This table shows how each color variable transforms between modes:
| Variable | Light Mode | Dark Mode | Purpose |
|---|---|---|---|
--light | F7F5F3 (Warm Alabaster) | 0F0E0B (Deep Earth Black) | Backgrounds |
--lightgray | E5E0D8 (Light Sand) | 26231E (Dark Soil) | Alt backgrounds, borders |
--gray | 948C84 (Stone) | 857F75 (Warm Stone) | Secondary text |
--darkgray | 4E4B42 (Bark) | D6D1C9 (Bone) | Secondary text |
--dark | 2C2A24 (Deep Peat) | F0ECE6 (Off-white) | Primary text |
--secondary | 4A6741 (Deep Moss Green) | 8FA876 (Light Moss) | CTAs, buttons |
--tertiary | A67B5B (Raw Sienna) | D4A373 (Buff) | Accents |
Notice: The correspondence is designed so that light mode backgrounds become dark mode backgrounds, and light mode text becomes dark mode text. Always verify your component respects this mapping.
Component Structure
File Organization
Every custom page component requires two files:
quartz/
โโโ components/
โ โโโ YourComponent.tsx // Component logic
โ โโโ styles/
โ โโโ yourcomponent.scss // Component styles
Basic Component Template
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
import style from "./styles/yourcomponent.scss"
export default (() => {
const YourComponent: QuartzComponent = ({ displayClass }: QuartzComponentProps) => {
return (
<div class={`your-component-page ${displayClass ?? ""}`}>
{/* Content goes here */}
</div>
)
}
YourComponent.css = style
return YourComponent
}) satisfies QuartzComponentConstructorRegistering the Component
- Add to
components/index.ts:
// Import
import { default as YourComponent } from "./YourComponent"
// Export
export {
// ... other exports
YourComponent,
}- Create content routing page:
---
title: Your Page Title
---The component is automatically rendered based on matching routes.
Styling Conventions
SCSS Best Practices
Use Nested Selectors
.your-component-page {
width: 100%;
max-width: 100%;
margin: 0;
padding: 0;
section {
padding: 4rem 2rem;
max-width: 1200px;
margin: 0 auto;
@media (max-width: 768px) {
padding: 2rem 1rem;
}
}
}Consistent Spacing Scale
Use multiples of 0.5rem for consistent spacing:
// Spacing scale
// 0.5rem, 1rem, 1.5rem, 2rem, 2.5rem, 3rem, 4rem, 6rem
.card {
padding: 2rem; // Standard card padding
margin-bottom: 2rem; // Standard vertical spacing
gap: 1.5rem; // Grid/flex gaps
}
.section {
padding: 4rem 2rem; // Section vertical/horizontal padding
}Typography Hierarchy
h1 {
font-size: 3rem; // Hero titles
line-height: 1.2;
font-weight: bold;
@media (max-width: 768px) {
font-size: 2rem;
}
}
h2 {
font-size: 2.5rem; // Section titles
margin: 0 0 1rem 0;
@media (max-width: 768px) {
font-size: 2rem;
}
}
h3 {
font-size: 1.8rem; // Subsection titles
margin: 0 0 1rem 0;
}
p {
font-size: 1rem; // Body text
line-height: 1.7; // Comfortable reading
color: var(--gray);
}Border Radius Standards
// Border radius scale
border-radius: 8px; // Small elements (badges, tags)
border-radius: 12px; // Medium elements (small cards)
border-radius: 16px; // Standard cards
border-radius: 24px; // Large cards, sections
border-radius: 50px; // Pills, buttonsBox Shadow Standards
// Subtle elevation
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.05);
// Medium elevation
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
// Strong elevation (cards)
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
// Colored shadows (use sparingly)
box-shadow: 0 8px 24px rgba(74, 103, 65, 0.15); // Secondary color shadowCommon Patterns
Hero Section
<section class="hero">
<div class="hero-content">
<div class="hero-badge">โจ Featured Project</div>
<h1>Your Amazing Title</h1>
<p class="hero-subtitle">
Compelling subtitle that explains what this page is about.
</p>
<div class="cta-group">
<a href="/link" class="cta-button primary">Primary Action</a>
<a href="/link" class="cta-button secondary">Secondary Action</a>
</div>
</div>
</section>SCSS:
.hero {
text-align: center;
padding: 6rem 2rem 4rem;
background: linear-gradient(135deg, var(--lightgray) 0%, var(--light) 100%);
.hero-badge {
display: inline-block;
background: var(--secondary);
color: white;
padding: 0.5rem 1.5rem;
border-radius: 50px;
font-size: 0.9rem;
font-weight: 600;
margin-bottom: 1.5rem;
}
h1 {
font-size: 3rem;
color: var(--dark);
margin: 0 0 1rem 0;
line-height: 1.2;
}
.hero-subtitle {
font-size: 1.2rem;
color: var(--gray);
max-width: 800px;
margin: 0 auto 2rem;
line-height: 1.7;
}
.cta-group {
display: flex;
gap: 1rem;
justify-content: center;
flex-wrap: wrap;
}
.cta-button {
padding: 1rem 2rem;
border-radius: 50px;
text-decoration: none;
font-weight: 600;
transition: transform 0.2s, box-shadow 0.2s;
&:hover {
transform: translateY(-2px);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
}
&.primary {
background: var(--secondary);
color: white;
}
&.secondary {
background: white;
color: var(--secondary);
border: 2px solid var(--secondary);
}
}
}Grid Layouts
<section class="features-section">
<h2 class="section-title">Key Features</h2>
<div class="features-grid">
<div class="feature-card">
<div class="feature-icon">โก</div>
<h3>Feature Title</h3>
<p>Feature description goes here.</p>
</div>
{/* Repeat for each feature */}
</div>
</section>SCSS:
.features-section {
.section-title {
text-align: center;
font-size: 2.5rem;
color: var(--dark);
margin: 0 0 3rem 0;
}
.features-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
@media (max-width: 768px) {
grid-template-columns: 1fr;
}
.feature-card {
background: white;
border-radius: 16px;
padding: 2rem;
border: 2px solid var(--lightgray);
transition: transform 0.3s, box-shadow 0.3s;
&:hover {
transform: translateY(-5px);
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
}
.feature-icon {
font-size: 3rem;
margin-bottom: 1rem;
}
h3 {
color: var(--dark);
margin: 0 0 1rem 0;
font-size: 1.5rem;
}
p {
color: var(--gray);
line-height: 1.6;
margin: 0;
}
}
}
}Highlighted Info Boxes
<div class="info-box">
<div class="info-header">
<div class="info-icon">๐ก</div>
<h3>Important Information</h3>
</div>
<p>Your informational content here.</p>
</div>SCSS:
.info-box {
background: var(--lightgray);
border-radius: 16px;
padding: 2rem;
border-left: 4px solid var(--secondary);
margin: 2rem 0;
.info-header {
display: flex;
align-items: center;
gap: 1rem;
margin-bottom: 1rem;
.info-icon {
font-size: 2rem;
}
h3 {
margin: 0;
color: var(--dark);
}
}
p {
margin: 0;
color: var(--gray);
line-height: 1.7;
}
}Alternating Background Sections
<section class="section-light">
{/* Content */}
</section>
<section class="section-gray">
{/* Content */}
</section>
<section class="section-light">
{/* Content */}
</section>SCSS:
.section-light {
background: var(--light);
padding: 4rem 2rem;
}
.section-gray {
background: var(--lightgray);
padding: 4rem 2rem;
}Responsive Design
Breakpoints
Use these standard breakpoints:
// Mobile
@media (max-width: 480px) {
// Stacked layouts, larger touch targets
}
// Tablet
@media (max-width: 768px) {
// Most responsive adjustments happen here
grid-template-columns: 1fr; // Single column grids
padding: 2rem 1rem; // Reduced padding
font-size: 2rem; // Smaller headings
}
// Desktop
@media (min-width: 769px) {
// Default desktop styles
}Mobile-First Pattern
// Start with mobile styles
.card {
padding: 1rem;
font-size: 1rem;
}
// Add desktop enhancements
@media (min-width: 769px) {
.card {
padding: 2rem;
font-size: 1.1rem;
}
}
---
## Internationalization (Bilingual Support)
> [!IMPORTANT]
>
> **All New Pages MUST Be Bilingual (English & Italian)**
>
> Every custom TSX page must support both English and Italian. We use a CSS-based toggle system where the `<html>` tag receives a `data-lang="en"` or `data-lang="it"` attribute.
### How It Works
We toggle visibility using CSS classes:
- `.lang-en`: Visible when `data-lang="en"` (Hidden when "it")
- `.lang-it`: Visible when `data-lang="it"` (Hidden when "en")
### The `Translate` Helper Component
To make this easy AND reusable, we use a helper component `Translate`.
**Import:**
```tsx
import Translate from "./Translate"
Usage:
// Simple Text
<p>
<Translate
en="Welcome to our community."
it="Benvenuti nella nostra comunitร ."
/>
</p>
// Inside Headers
<h2>
<Translate
en="Our Features"
it="Le Nostre Caratteristiche"
/>
</h2>
// Inside Links
<a href="/apply">
<Translate
en="Apply Now"
it="Candidati Ora"
/>
</a>Manual Implementation (Raw Spans)
If you cannot use the helper for some reason (e.g. complex nested HTML), use the raw spans:
<p>
<span class="lang-en">English text here.</span>
<span class="lang-it">Testo italiano qui.</span>
</p>Accessibility
Semantic HTML
// โ
CORRECT - Semantic structure
<section class="features">
<h2>Features</h2>
<article class="feature-card">
<h3>Feature Title</h3>
<p>Description</p>
</article>
</section>
// โ WRONG - Generic divs everywhere
<div class="features">
<div>Features</div>
<div class="feature-card">
<div>Feature Title</div>
<div>Description</div>
</div>
</div>Link Accessibility
// โ
CORRECT - Descriptive link text
<a href="/properties/casa-del-forno">Explore Casa del Forno โ</a>
// โ WRONG - Generic "click here"
<a href="/properties/casa-del-forno">Click here</a>Case-Sensitive Internal Links
CRITICAL
Internal links in TSX components are CASE-SENSITIVE!
Quartz generates URLs that preserve the original casing of file and folder names. You MUST match the exact path casing or links will result in 404 errors.
// โ
CORRECT - Match folder/file casing exactly
<a href="/Advertising/Offers/Internship-Offer">Internship Offer</a>
<a href="/Rules/Policies/Standard-Visa-Procedure">Standard Visa Procedure</a>
<a href="/Financials/Business-Segments/Visa-Consultancy/Premium-Visa-Assistance">Premium Visa Assistance</a>
// โ WRONG - Lowercase will cause 404
<a href="/advertising/offers/internship-offer">Internship Offer</a>
<a href="/rules/policies/standard-visa-procedure">Standard Visa Procedure</a>How to derive the correct URL:
- Find the file in
content/: e.g.,content/Advertising/Offers/Internship Offer.md - Preserve folder casing:
Advertising,Offersstay capitalized - Replace spaces with hyphens:
Internship OfferโInternship-Offer - Remove
.mdextension: Final link is/Advertising/Offers/Internship-Offer
| File Path | Correct URL |
|---|---|
content/Advertising/Offers/Work with Us.md | /Advertising/Offers/Work-with-Us |
content/Rules/Policies/Standard Visa Procedure.md | /Rules/Policies/Standard-Visa-Procedure |
content/Financials/Business Segments/Visa Consultancy/Visa Consultancy.md | /Financials/Business-Segments/Visa-Consultancy/Visa-Consultancy |
Internal Linking Requirements
IMPORTANT
Link to Related Content as Much as Possible
Every time you mention content that exists in another note or page, you MUST link to that page. This creates a well-connected knowledge network and improves navigation.
Rules:
- Maximize links: If content exists elsewhere, link to it
- Verify links work: Test every link after creating it
- Use correct paths: Follow case-sensitivity rules above
- Descriptive text: Use meaningful link text, not โclick hereโ
When to Link
Link whenever you mention:
| Content Type | Example | Link Requirement |
|---|---|---|
| Properties | โCasa del Fornoโ | โ MUST link to Casa del Forno |
| Apartments | โSub 5โ | โ MUST link to Sub 5 |
| Rooms | โPrivate Double Bedroomโ | โ MUST link to room page |
| Technical Systems | โHydraulic Systemโ | โ MUST link to system page |
| Policies | โStandard Visa Procedureโ | โ MUST link to policy |
| People/Roles | โVolunteersโ | โ SHOULD link to relevant offer |
| General concepts | โColivingโ | Optional |
Link Verification Checklist
Before publishing, verify each link:
- Path is correct (case-sensitive, hyphens for spaces)
- Link works (test by clicking in preview)
- Target page exists (no 404 errors)
- Link text is descriptive (not โclick hereโ)
Examples
// โ
CORRECT - Rich linking
<p>
Our <a href="/Houses/Chiappella/Properties/Casa-del-Forno/Casa-del-Forno">Casa del Forno</a> property
features three apartments: <a href="/Houses/Chiappella/Properties/Casa-del-Forno/Sub-5/Sub-5">Sub 5</a>
(8 people), <a href="/Houses/Chiappella/Properties/Casa-del-Forno/Sub-6/Sub-6">Sub 6</a> (4 people),
and <a href="/Houses/Chiappella/Properties/Casa-del-Forno/Sub-7/Sub-7">Sub 7</a> (5 people).
</p>
// โ WRONG - Missing links
<p>
Our Casa del Forno property features three apartments: Sub 5 (8 people),
Sub 6 (4 people), and Sub 7 (5 people).
</p>TIP
Finding the Correct Path
Use the file explorer or search in your editor to find the exact file path, then convert it to a URL:
- Remove
content/prefix- Replace spaces with hyphens
- Remove
.mdextension- Preserve original folder casing
Color Contrast
CRITICAL
TEXT MUST ALWAYS BE READABLE
It happens far too often that text is placed on a background where it is not sufficiently readable. You MUST carefully verify that when you pair text color with a textbox/card/section background, the contrast is sufficient for comfortable reading.
Common Mistakes to AVOID:
- Light gray text on light background โ UNREADABLE
- Dark text on dark background โ UNREADABLE
- Colored text on similarly-colored background โ UNREADABLE
If in doubt, increase the contrast!
Minimum Contrast Ratios
Ensure minimum 4.5:1 contrast ratio for body text:
// โ
CORRECT - High contrast
color: var(--dark); // #2C2A24 on var(--light) #F7F5F3 = 11.8:1
background: var(--light);
// โ ๏ธ CHECK - Medium contrast (still acceptable)
color: var(--gray); // #948C84 on var(--light) #F7F5F3 = 4.8:1
background: var(--light);
// โ WRONG - Low contrast (UNREADABLE!)
color: var(--lightgray); // Too low contrast
background: var(--light);Safe Color Pairings
Use these proven combinations for readable text:
| Background | Text Color | Contrast | Status |
|---|---|---|---|
var(--light) | var(--dark) | 11.8:1 | โ Excellent |
var(--light) | var(--gray) | 4.8:1 | โ ๏ธ Acceptable |
var(--lightgray) | var(--dark) | High | โ Excellent |
var(--secondary) | white | High | โ Excellent (buttons) |
var(--secondary) | var(--light) | High | โ Excellent (buttons) |
var(--tertiary) | var(--dark) | High | โ Good (accents) |
Dangerous Pairings to AVOID
// โ NEVER DO THIS
color: var(--lightgray);
background: var(--light); // Almost invisible!
// โ NEVER DO THIS
color: var(--gray);
background: var(--lightgray); // Very hard to read!
// โ NEVER DO THIS (in dark mode)
color: var(--darkgray);
background: var(--lightgray); // Check dark mode!WARNING
Always Test in Both Modes
A color combination that works in light mode may fail in dark mode and vice versa. Test every text/background pairing in BOTH modes before publishing.
Code Examples
Complete Mini Component
// YourComponent.tsx
import { QuartzComponent, QuartzComponentConstructor, QuartzComponentProps } from "./types"
import style from "./styles/yourcomponent.scss"
export default (() => {
const YourComponent: QuartzComponent = ({ displayClass }: QuartzComponentProps) => {
return (
<div class={`your-component-page ${displayClass ?? ""}`}>
{/* Hero */}
<section class="hero">
<div class="hero-content">
<h1>Welcome to Our Page</h1>
<p class="subtitle">Discover amazing things here.</p>
</div>
</section>
{/* Features */}
<section class="features">
<h2 class="section-title">What We Offer</h2>
<div class="features-grid">
<div class="feature-card">
<div class="icon">๐ฏ</div>
<h3>Precision</h3>
<p>Carefully crafted experiences.</p>
</div>
<div class="feature-card">
<div class="icon">โก</div>
<h3>Speed</h3>
<p>Lightning-fast performance.</p>
</div>
<div class="feature-card">
<div class="icon">๐ก๏ธ</div>
<h3>Security</h3>
<p>Your safety is our priority.</p>
</div>
</div>
</section>
</div>
)
}
YourComponent.css = style
return YourComponent
}) satisfies QuartzComponentConstructor// yourcomponent.scss
@use "../../styles/variables.scss" as *;
.your-component-page {
width: 100%;
max-width: 100%;
margin: 0;
padding: 0;
section {
padding: 4rem 2rem;
max-width: 1200px;
margin: 0 auto;
@media (max-width: 768px) {
padding: 2rem 1rem;
}
}
// Hero
.hero {
text-align: center;
background: linear-gradient(135deg, var(--lightgray) 0%, var(--light) 100%);
h1 {
font-size: 3rem;
color: var(--dark);
margin: 0 0 1rem 0;
@media (max-width: 768px) {
font-size: 2rem;
}
}
.subtitle {
font-size: 1.2rem;
color: var(--gray);
max-width: 600px;
margin: 0 auto;
}
}
// Features
.features {
background: var(--light);
.section-title {
text-align: center;
font-size: 2.5rem;
color: var(--dark);
margin: 0 0 3rem 0;
}
.features-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 2rem;
@media (max-width: 768px) {
grid-template-columns: 1fr;
}
.feature-card {
background: white;
border-radius: 16px;
padding: 2rem;
text-align: center;
border: 2px solid var(--lightgray);
.icon {
font-size: 3rem;
margin-bottom: 1rem;
}
h3 {
color: var(--dark);
margin: 0 0 0.5rem 0;
}
p {
color: var(--gray);
margin: 0;
}
}
}
}
}Common Pitfalls & Troubleshooting
Problem: Component Created But Page Shows Only Title
Symptom: Your TSX component exists, builds successfully, but the page only shows the title with empty content below.
Cause: Component not registered in quartz.layout.tsx routing configuration.
Solution: Add your component to the layout configuration file.
Step-by-Step Fix
-
Open
quartz.layout.tsxin the project root -
Add ConditionalRender for your component in the
beforeBodyarray:
Component.ConditionalRender({
component: Component.YourComponent(),
condition: (page) => page.fileData.slug?.toLowerCase().endsWith("your-page-slug") ?? false,
}),- Add exclusions for standard page elements (ArticleTitle, ContentMeta, TagList):
// In ArticleTitle condition (around line 49)
slug.endsWith("your-page-slug")
// In ContentMeta condition (around line 77)
slug.endsWith("your-page-slug")
// In TagList condition (around line 95)
slug.endsWith("your-page-slug")- Complete example:
// In quartz.layout.tsx, around line 48
Component.ConditionalRender({
component: Component.ArticleTitle(),
condition: (page) => {
const slug = page.fileData.slug?.toLowerCase() ?? ""
return !(
slug === "index" ||
slug.endsWith("digital-nomad-offer") ||
slug.endsWith("volunteer-offer") ||
slug.endsWith("your-page-slug") // ADD THIS
)
},
}),
// Later in beforeBody array, around line 140
Component.ConditionalRender({
component: Component.YourComponent(),
condition: (page) => page.fileData.slug?.toLowerCase().endsWith("your-page-slug") ?? false,
}),- Rebuild:
npx quartz build
Why This Happens
Quartz uses conditional rendering to determine which components display on which pages. Without a ConditionalRender entry, your component never gets invoked, even though it exists and is imported.
The exclusions (ArticleTitle, etc.) prevent standard page chrome from appearing on your custom component pages, giving you full control over the layout.
Checklist Before Publishing
Use this checklist every time you create a new page component:
Colors & Contrast
- Palette Only: All colors use CSS variables (no hardcoded hex, RGB, or named colors)
- Dark Mode Tested: Component tested in dark mode (toggle browser)
- Light Mode Tested: Component tested in light mode
- Text Readable: All text has sufficient contrast against its background
- No White Backgrounds: No pure
whiteor#FFFFFFfor backgrounds
Layout & Design
- Responsive: Tested on mobile (< 768px) and desktop
- Spacing: Uses consistent spacing scale (0.5rem multiples)
- Typography: Proper hierarchy (h1 > h2 > h3 > p)
Links & Accessibility
- Links Correct: All internal links use correct case-sensitive paths
- Links Verified: Each link tested and working
- Maximum Linking: All related content mentioned is linked
- Semantic HTML: Uses proper HTML elements (section, article, etc.)
- Descriptive Links: No โclick hereโ links
Technical
- Registered: Component added to
components/index.ts - Styled: SCSS file created in
styles/folder - Tested: Build completes without errors (
npx quartz build)
Quick Reference
CSS Variables Cheatsheet
// Backgrounds
var(--light) // Main page background
var(--lightgray) // Alt sections
white // Elevated cards (light mode)
// Text
var(--dark) // Primary headings
var(--darkgray) // Secondary headings
var(--gray) // Body text
// Interactive
var(--secondary) // Buttons, CTAs, links
var(--tertiary) // Accents, highlights
// Borders
var(--lightgray) // Most borders (2px max)
var(--secondary) // Emphasized borders (left border, etc.)Common Class Patterns
.section-title // Centered, 2.5rem section titles
.hero // Full-width hero sections
.cta-button // Call-to-action buttons
.feature-card // Grid item cards
.info-box // Highlighted information boxesResources
- Reference Components:
NewHome.tsx,ElectricalSystem.tsx - Color Palette:
quartz.config.ts - Markdown Guide:
Markdown Style Guide.md - Build Command:
npx quartz build
Remember: Consistency is key. When in doubt, reference existing components and follow established patterns.