website-htmx-rustelo-code/site/public/styles/htmx-components.css

494 lines
13 KiB
CSS
Raw Normal View History

2026-07-10 03:44:13 +01:00
/* HTMX Component Classes
* Semantic component classes used by Minijinja (j2) templates.
* All values reference CSS custom properties from design-system.css.
*/
/* ─── Layout: Page Structure ─────────────────────────────────────────────── */
.ds-page-header {
padding: var(--space-12, 3rem) 0 var(--space-8, 2rem);
}
.ds-page-body {
padding: var(--space-8, 2rem) 0;
}
/* ─── Layout: Sections ────────────────────────────────────────────────────── */
.ds-hero {
padding: var(--space-20, 5rem) 0;
background-color: var(--color-neutral-50);
text-align: center;
}
.dark .ds-hero {
background-color: var(--color-neutral-950);
}
.ds-section {
padding: var(--space-16, 4rem) 0;
background-color: var(--color-neutral-50);
}
.dark .ds-section {
background-color: var(--color-neutral-950);
}
.ds-section-alt {
background-color: var(--color-neutral-100);
}
.dark .ds-section-alt {
background-color: var(--color-neutral-900);
}
.ds-section-cta {
background-color: var(--color-brand-primary);
color: var(--color-neutral-50);
}
.ds-section-cta .ds-text-lead,
.ds-section-cta .ds-text-muted {
color: color-mix(in srgb, var(--color-neutral-50) 85%, transparent);
}
/* ─── Layout: Grid ────────────────────────────────────────────────────────── */
.ds-grid {
display: grid;
gap: var(--space-6, 1.5rem);
}
.ds-grid-2 {
grid-template-columns: repeat(1, 1fr);
}
.ds-grid-3 {
grid-template-columns: repeat(1, 1fr);
}
@media (min-width: 768px) {
.ds-grid-2 {
grid-template-columns: repeat(2, 1fr);
}
.ds-grid-3 {
grid-template-columns: repeat(2, 1fr);
}
}
@media (min-width: 1024px) {
.ds-grid-3 {
grid-template-columns: repeat(3, 1fr);
}
}
/* ─── Layout: Alignment helpers ──────────────────────────────────────────── */
.ds-align-center {
align-items: center;
}
.ds-justify-center {
justify-content: center;
}
.ds-justify-between {
justify-content: space-between;
}
.ds-text-center {
text-align: center;
}
.ds-w-full {
width: 100%;
}
/* ─── Typography ─────────────────────────────────────────────────────────── */
.ds-heading-xl {
font-size: var(--text-4xl, 2.25rem);
font-weight: var(--font-bold, 700);
color: var(--color-neutral-900);
line-height: 1.2;
margin-bottom: var(--space-4, 1rem);
}
.dark .ds-heading-xl {
color: var(--color-neutral-50);
}
.ds-heading-lg {
font-size: var(--text-3xl, 1.875rem);
font-weight: var(--font-semibold, 600);
color: var(--color-neutral-900);
line-height: 1.25;
margin-bottom: var(--space-4, 1rem);
}
.dark .ds-heading-lg {
color: var(--color-neutral-50);
}
.ds-heading-sm {
font-size: var(--text-xl, 1.25rem);
font-weight: var(--font-semibold, 600);
color: var(--color-neutral-900);
line-height: 1.4;
margin-bottom: var(--space-2, 0.5rem);
}
.dark .ds-heading-sm {
color: var(--color-neutral-50);
}
.ds-tagline {
font-size: var(--text-sm, 0.875rem);
font-weight: var(--font-semibold, 600);
text-transform: uppercase;
letter-spacing: 0.08em;
color: var(--color-brand-primary);
margin-bottom: var(--space-3, 0.75rem);
}
.ds-text-lead {
font-size: var(--text-lg, 1.125rem);
color: var(--color-neutral-600);
line-height: 1.7;
margin-bottom: var(--space-4, 1rem);
}
.dark .ds-text-lead {
color: var(--color-neutral-400);
}
/* ─── Buttons ─────────────────────────────────────────────────────────────── */
.ds-button {
display: inline-flex;
align-items: center;
justify-content: center;
gap: var(--space-2, 0.5rem);
padding: var(--space-2, 0.5rem) var(--space-5, 1.25rem);
font-size: var(--text-sm, 0.875rem);
font-weight: var(--font-medium, 500);
border-radius: var(--radius-md, 0.375rem);
border: 1px solid transparent;
cursor: pointer;
text-decoration: none;
transition: background-color 0.15s, border-color 0.15s, color 0.15s;
white-space: nowrap;
}
.ds-button-primary {
background-color: var(--color-brand-primary, #3b82f6);
color: var(--color-neutral-50, #f9fafb);
border-color: var(--color-brand-primary, #3b82f6);
}
.ds-button-primary:hover {
background-color: color-mix(in srgb, var(--color-brand-primary) 85%, black);
}
.ds-button-secondary {
background-color: var(--color-neutral-200, #e5e7eb);
color: var(--color-neutral-900, #111827);
border-color: var(--color-neutral-200, #e5e7eb);
}
.ds-button-secondary:hover {
background-color: var(--color-neutral-300, #d1d5db);
}
.dark .ds-button-secondary {
background-color: var(--color-neutral-700, #374151);
color: var(--color-neutral-50, #f9fafb);
border-color: var(--color-neutral-700, #374151);
}
.dark .ds-button-secondary:hover {
background-color: var(--color-neutral-600, #4b5563);
}
.ds-button-outline {
background-color: transparent;
color: var(--color-brand-primary, #3b82f6);
border-color: var(--color-brand-primary, #3b82f6);
}
.ds-button-outline:hover {
background-color: var(--color-brand-primary, #3b82f6);
color: var(--color-neutral-50, #f9fafb);
}
.ds-button-sm {
padding: var(--space-1, 0.25rem) var(--space-3, 0.75rem);
font-size: var(--text-xs, 0.75rem);
}
.ds-button-group {
display: flex;
flex-wrap: wrap;
gap: var(--space-3, 0.75rem);
align-items: center;
}
/* ─── Nav: control group (theme · lang · login) ──────────────────────────── */
/* The three nav controls ship with different framework sizings: the theme
toggle and login use .ds-btn-ghost-sm (padding ~28-32px tall), the language
selector's <summary> carries daisyUI's .btn-sm (height:2rem 32px). Unify
them to a 24px footprint. Scoped to .nav-ctl-group so the dashboard's
.ds-btn-ghost-sm delete buttons are untouched. box-sizing:border-box is
global, so 1.5rem == the full 24px box. */
.nav-ctl-group > .ds-btn-ghost-sm,
.nav-ctl-group > .language-selector > summary {
height: 1.5rem;
min-height: 1.5rem;
padding-top: 0;
padding-bottom: 0;
}
/* Icon-only controls square 24×24. The login button keeps content width (it
holds text) but inherits the 24px height above. */
.nav-ctl-group > .ds-btn-ghost-sm[data-theme],
.nav-ctl-group > .language-selector > summary {
width: 1.5rem;
padding-left: 0;
padding-right: 0;
}
/* ─── List ────────────────────────────────────────────────────────────────── */
.ds-list {
list-style: none;
padding: 0;
margin: var(--space-3, 0.75rem) 0;
display: flex;
flex-direction: column;
gap: var(--space-2, 0.5rem);
}
.ds-list li {
color: var(--color-neutral-600);
font-size: var(--text-sm, 0.875rem);
padding-left: var(--space-4, 1rem);
position: relative;
}
.dark .ds-list li {
color: var(--color-neutral-400);
}
.ds-list li::before {
content: "→";
position: absolute;
left: 0;
color: var(--color-brand-primary);
font-size: 0.75rem;
line-height: 1.6;
}
/* ─── Link ────────────────────────────────────────────────────────────────── */
.ds-link {
display: inline-flex;
align-items: center;
gap: var(--space-1, 0.25rem);
color: var(--color-brand-primary);
font-size: var(--text-sm, 0.875rem);
font-weight: var(--font-medium, 500);
text-decoration: none;
margin-top: var(--space-3, 0.75rem);
transition: color 0.15s;
}
.ds-link:hover {
color: color-mix(in srgb, var(--color-brand-primary) 75%, black);
text-decoration: underline;
}
/* ─── Product Page ────────────────────────────────────────────────────────── */
.ds-product-page {
max-width: 72rem;
margin: 0 auto;
padding: var(--space-8, 2rem) var(--space-4, 1rem);
}
.ds-product-actions {
display: flex;
flex-wrap: wrap;
gap: var(--space-3, 0.75rem);
margin: var(--space-6, 1.5rem) 0;
}
/* ─── Forms ───────────────────────────────────────────────────────────────── */
.ds-form {
display: flex;
flex-direction: column;
gap: var(--space-4, 1rem);
max-width: 32rem;
}
.ds-auth-form {
display: flex;
flex-direction: column;
gap: var(--space-4, 1rem);
max-width: 24rem;
margin: 0 auto;
}
.ds-form-group {
display: flex;
flex-direction: column;
gap: var(--space-1, 0.25rem);
}
.ds-form-row {
display: flex;
gap: var(--space-3, 0.75rem);
align-items: flex-end;
}
.ds-label {
display: block;
font-size: var(--text-sm, 0.875rem);
font-weight: var(--font-medium, 500);
color: var(--color-neutral-700);
margin-bottom: var(--space-1, 0.25rem);
}
.dark .ds-label {
color: var(--color-neutral-300);
}
.ds-checkbox {
width: 1rem;
height: 1rem;
accent-color: var(--color-brand-primary);
cursor: pointer;
}
.ds-checkbox-label {
display: inline-flex;
align-items: center;
gap: var(--space-2, 0.5rem);
font-size: var(--text-sm, 0.875rem);
color: var(--color-neutral-700);
cursor: pointer;
}
.dark .ds-checkbox-label {
color: var(--color-neutral-300);
}
/* ─── Layout: Container ───────────────────────────────────────────────────── */
.ds-container {
margin-left: auto;
margin-right: auto;
padding-left: var(--space-4, 1rem);
padding-right: var(--space-4, 1rem);
max-width: 80rem;
}
.ds-container-sm {
margin-left: auto;
margin-right: auto;
padding-left: var(--space-4, 1rem);
padding-right: var(--space-4, 1rem);
max-width: 42rem;
}
.ds-container-md {
margin-left: auto;
margin-right: auto;
padding-left: var(--space-4, 1rem);
padding-right: var(--space-4, 1rem);
max-width: 56rem;
}
/* ─── Background ─────────────────────────────────────────────────────────── */
.ds-bg-page {
background-color: var(--color-neutral-100);
}
.dark .ds-bg-page {
background-color: var(--color-neutral-900);
}
/* ─── Typography: Body Text ──────────────────────────────────────────────── */
.ds-text {
color: var(--color-neutral-900);
}
.dark .ds-text {
color: var(--color-neutral-50);
}
.ds-text-muted {
color: var(--color-neutral-500);
font-size: var(--text-base, 1rem);
line-height: 1.6;
margin-bottom: var(--space-4, 1rem);
}
/* ─── Card ───────────────────────────────────────────────────────────────── */
.ds-card {
background-color: var(--color-neutral-50);
border-radius: var(--radius-lg, 0.5rem);
box-shadow: var(--shadow-sm, 0 1px 2px 0 rgb(0 0 0 / 0.05));
border: 1px solid var(--color-neutral-200);
padding: var(--space-6, 1.5rem);
}
.dark .ds-card {
background-color: var(--color-neutral-800);
border-color: var(--color-neutral-600);
}
/* ─── Badge ──────────────────────────────────────────────────────────────── */
.ds-badge {
display: inline-flex;
align-items: center;
padding: 0.125rem 0.625rem;
border-radius: 9999px;
font-size: var(--text-xs, 0.75rem);
font-weight: var(--font-medium, 500);
background-color: var(--color-brand-primary);
color: var(--color-neutral-50);
margin-bottom: var(--space-3, 0.75rem);
}
/* ─── Input ──────────────────────────────────────────────────────────────── */
.ds-input {
width: 100%;
padding: var(--space-2, 0.5rem) var(--space-3, 0.75rem);
font-size: var(--text-sm, 0.875rem);
color: var(--color-neutral-900);
background-color: var(--color-neutral-50);
border: 1px solid var(--color-neutral-300);
border-radius: var(--radius-md, 0.375rem);
transition: border-color 0.15s, box-shadow 0.15s;
outline: none;
}
.ds-input:focus {
border-color: var(--color-brand-primary);
box-shadow: 0 0 0 2px color-mix(in srgb, var(--color-brand-primary) 20%, transparent);
}
.dark .ds-input {
color: var(--color-neutral-50);
background-color: var(--color-neutral-800);
border-color: var(--color-neutral-600);
}