@ryanhelsing/ry-ui
Version:
Framework-agnostic, Light DOM web components. CSS is the source of truth.
241 lines (198 loc) • 9.23 kB
CSS
/**
* ry-ui Layout Primitives
*
* Pure CSS layout components.
* No JavaScript required.
*/
/* ═══════════════════════════════════════════════════════════════
PAGE
═══════════════════════════════════════════════════════════════ */
ry-page {
display: flex;
flex-direction: column;
min-height: 100vh;
min-height: 100dvh;
}
/* ═══════════════════════════════════════════════════════════════
HEADER
═══════════════════════════════════════════════════════════════ */
ry-header {
display: flex;
align-items: center;
justify-content: space-between;
gap: var(--ry-space-4);
padding: var(--ry-space-4) var(--ry-space-6);
background-color: var(--ry-color-bg);
border-bottom: var(--ry-border-width) solid var(--ry-color-border);
}
/* ═══════════════════════════════════════════════════════════════
MAIN
═══════════════════════════════════════════════════════════════ */
ry-main {
flex: 1;
width: 100%;
max-width: 1200px;
margin: 0 auto;
padding: var(--ry-space-8) var(--ry-space-6);
}
/* ═══════════════════════════════════════════════════════════════
FOOTER
═══════════════════════════════════════════════════════════════ */
ry-footer {
padding: var(--ry-space-6);
background-color: var(--ry-color-bg-subtle);
border-top: var(--ry-border-width) solid var(--ry-color-border);
text-align: center;
color: var(--ry-color-text-muted);
}
/* ═══════════════════════════════════════════════════════════════
SECTION
═══════════════════════════════════════════════════════════════ */
ry-section {
margin-bottom: var(--ry-space-12);
}
ry-section:last-child {
margin-bottom: 0;
}
/* ═══════════════════════════════════════════════════════════════
GRID
═══════════════════════════════════════════════════════════════ */
ry-grid {
display: grid;
gap: var(--ry-space-4);
}
/* Column variants */
ry-grid[cols="1"] { grid-template-columns: 1fr; }
ry-grid[cols="2"] { grid-template-columns: repeat(2, 1fr); }
ry-grid[cols="3"] { grid-template-columns: repeat(3, 1fr); }
ry-grid[cols="4"] { grid-template-columns: repeat(4, 1fr); }
ry-grid[cols="5"] { grid-template-columns: repeat(5, 1fr); }
ry-grid[cols="6"] { grid-template-columns: repeat(6, 1fr); }
/* Responsive: stack on small screens */
@media (max-width: 640px) {
ry-grid[cols="2"],
ry-grid[cols="3"],
ry-grid[cols="4"],
ry-grid[cols="5"],
ry-grid[cols="6"] {
grid-template-columns: 1fr;
}
}
@media (min-width: 641px) and (max-width: 1024px) {
ry-grid[cols="3"],
ry-grid[cols="4"],
ry-grid[cols="5"],
ry-grid[cols="6"] {
grid-template-columns: repeat(2, 1fr);
}
}
/* ═══════════════════════════════════════════════════════════════
STACK (vertical)
═══════════════════════════════════════════════════════════════ */
ry-stack {
display: flex;
flex-direction: column;
gap: var(--ry-space-4);
}
ry-stack[gap="sm"] { gap: var(--ry-space-2); }
ry-stack[gap="md"] { gap: var(--ry-space-4); }
ry-stack[gap="lg"] { gap: var(--ry-space-6); }
ry-stack[gap="xl"] { gap: var(--ry-space-8); }
/* ═══════════════════════════════════════════════════════════════
CLUSTER (horizontal, wraps)
═══════════════════════════════════════════════════════════════ */
ry-cluster {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: var(--ry-space-3);
}
ry-cluster[gap="sm"] { gap: var(--ry-space-2); }
ry-cluster[gap="md"] { gap: var(--ry-space-3); }
ry-cluster[gap="lg"] { gap: var(--ry-space-4); }
/* ═══════════════════════════════════════════════════════════════
SPLIT (two columns: content + sidebar)
═══════════════════════════════════════════════════════════════ */
ry-split {
display: flex;
gap: var(--ry-space-6);
}
ry-split > :first-child {
flex: 1;
}
ry-split > :last-child {
flex-shrink: 0;
width: 300px;
}
@media (max-width: 768px) {
ry-split {
flex-direction: column;
}
ry-split > :last-child {
width: 100%;
}
}
/* ═══════════════════════════════════════════════════════════════
CENTER
═══════════════════════════════════════════════════════════════ */
ry-center {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
}
/* ═══════════════════════════════════════════════════════════════
NAV
═══════════════════════════════════════════════════════════════ */
ry-nav {
display: flex;
align-items: center;
gap: var(--ry-space-4);
}
ry-nav a {
color: var(--ry-color-text-muted);
text-decoration: none;
font-size: var(--ry-text-sm);
font-weight: var(--ry-font-medium);
transition: color var(--ry-duration-fast) var(--ry-ease);
}
ry-nav a:hover {
color: var(--ry-color-text);
}
ry-nav a[aria-current="page"] {
color: var(--ry-color-primary);
}
/* ═══════════════════════════════════════════════════════════════
LOGO
═══════════════════════════════════════════════════════════════ */
ry-logo {
display: inline-flex;
align-items: center;
font-size: var(--ry-text-xl);
font-weight: var(--ry-font-bold);
color: var(--ry-color-text);
}
/* ═══════════════════════════════════════════════════════════════
ACTIONS (button group)
═══════════════════════════════════════════════════════════════ */
ry-actions {
display: flex;
align-items: center;
gap: var(--ry-space-2);
}
/* ═══════════════════════════════════════════════════════════════
DIVIDER
═══════════════════════════════════════════════════════════════ */
ry-divider {
display: block;
height: 1px;
margin: var(--ry-space-4) 0;
background-color: var(--ry-color-border);
}
ry-divider[vertical] {
width: 1px;
height: auto;
align-self: stretch;
margin: 0 var(--ry-space-4);
}