/* Interactive pseudo-classes */
a:link { color: blue; }
a:visited { color: purple; }
a:hover { text-decoration: underline; }
a:active { color: red; }
a:focus { outline: 2px solid orange; }
import { useEffect, useRef, useState } from "react";
export type AsyncState<T> =
| { status: "loading" }
| { status: "error"; error: Error }
| { status: "success"; data: T };
web: bin/rails server
css: bin/rails tailwindcss:watch
// Theme switching with CSS variables
const themeToggle = document.getElementById('theme-toggle');
const root = document.documentElement;
// Load saved theme
const savedTheme = localStorage.getItem('theme') || 'light';
.turbo-progress-bar {
height: 4px;
background: linear-gradient(
90deg,
var(--progress-start, #6366f1),
var(--progress-end, #ec4899)
/* Basic flexbox container */
.flex-container {
display: flex;
/* flex-direction: row | row-reverse | column | column-reverse */
flex-direction: row; /* default */
/* Basic transitions */
.button {
background-color: blue;
color: white;
padding: 1rem 2rem;
transition: background-color 0.3s ease;
/* Container Queries */
.card-container {
container-type: inline-size; /* Creates query container */
container-name: card;
}
/* Basic grid container */
.grid-container {
display: grid;
/* Define columns: 3 equal columns */
grid-template-columns: 1fr 1fr 1fr;
/* Specificity: 0,0,0,1 - Element selector */
p {
color: black;
}
/* Specificity: 0,0,1,0 - Class selector */
/* Mobile-first base styles (no media query needed) */
.container {
width: 100%;
padding: 1rem;
margin: 0 auto;
}
/* BEM - Block Element Modifier */
/* BLOCK - Independent component */
.card {
padding: 1rem;
border: 1px solid #ddd;