/**
* 03-components.css
* UI component patterns (buttons, forms, nav, dialog, details)
* Part of: Agentic Semantic Web
*
* Ported from: Pico CSS v2.1.1
* License: MIT
*
* Modernizations:
* - Uses `accent-color` for checkbox/radio (simpler than background-image)
* - Drops class-based button variants (.secondary, .contrast, .outline)
*/
/* ── Buttons ───────────────────────────────────────────────────────────*/
button {
margin: 0;
overflow: visible;
font-family: inherit;
text-transform: none;
}
button,
[type=submit],
[type=reset],
[type=button],
[role=button] {
display: inline-block;
padding: var(--input-py) var(--input-px);
border: var(--border-width) solid var(--border);
border-radius: var(--radius-md);
outline: none;
background-color: var(--surface);
color: var(--text);
font-weight: var(--font-weight-4);
font-size: var(--text-base);
line-height: var(--leading);
text-align: center;
text-decoration: none;
cursor: pointer;
user-select: none;
transition: background-color var(--ease),
border-color var(--ease),
color var(--ease);
}
button:is(:hover, :active, :focus-visible),
[type=submit]:is(:hover, :active, :focus-visible),
[type=reset]:is(:hover, :active, :focus-visible),
[type=button]:is(:hover, :active, :focus-visible),
[role=button]:is(:hover, :active, :focus-visible) {
background-color: var(--surface-hover);
border-color: var(--border);
color: var(--text);
}
button:focus-visible,
[type=submit]:focus-visible,
[type=reset]:focus-visible,
[type=button]:focus-visible,
[role=button]:focus-visible {
box-shadow: 0 0 0 var(--outline-width) var(--accent-focus);
}
button[disabled],
[type=submit][disabled],
[type=reset][disabled],
[type=button][disabled],
[role=button][disabled] {
opacity: 0.5;
pointer-events: none;
}
/* ── Form Elements ─────────────────────────────────────────────────────*/
input,
optgroup,
select,
textarea {
margin: 0;
font-size: var(--text-base);
line-height: var(--leading);
font-family: inherit;
letter-spacing: inherit;
}
fieldset {
width: 100%;
margin: 0;
margin-bottom: var(--space-4);
padding: 0;
border: 0;
}
fieldset legend,
label {
display: block;
margin-bottom: calc(var(--space-4) * 0.375);
color: var(--text);
font-weight: var(--font-weight-4);
}
input:not([type=checkbox], [type=radio], [type=range], [type=file]),
select,
textarea {
width: 100%;
padding: var(--input-py) var(--input-px);
border: var(--border-width) solid var(--input-border);
border-radius: var(--radius-md);
outline: none;
background-color: var(--input-bg);
color: var(--text);
font-weight: var(--font-weight-4);
transition: background-color var(--ease),
border-color var(--ease),
color var(--ease);
}
input:not([type=checkbox], [type=radio], [type=range], [type=file], [readonly]):is(:active, :focus-visible),
select:not([readonly]):is(:active, :focus-visible),
textarea:not([readonly]):is(:active, :focus-visible) {
border-color: var(--accent);
background-color: var(--input-active-bg);
}
input:not([type=checkbox], [type=radio], [type=range], [type=file], [readonly]):focus-visible,
select:not([readonly]):focus-visible,
textarea:not([readonly]):focus-visible {
box-shadow: 0 0 0 var(--outline-width) var(--accent);
}
input:not([type=checkbox], [type=radio], [type=range], [type=file])[disabled],
select[disabled],
textarea[disabled] {
opacity: var(--disabled-opacity);
pointer-events: none;
}
input::placeholder,
textarea::placeholder,
select:invalid {
color: var(--text-3);
opacity: 1;
}
input:not([type=checkbox], [type=radio]),
select,
textarea {
margin-bottom: var(--space-4);
}
/* ── Select Dropdown ───────────────────────────────────────────────────*/
select:not([multiple], [size]) {
padding-right: calc(var(--input-px) + 1.5rem);
background-image: var(--icon-chevron);
background-position: center right 0.75rem;
background-size: 1rem auto;
background-repeat: no-repeat;
}
select[multiple] option:checked {
background: var(--input-selected);
color: var(--text);
}
/* ── Textarea ──────────────────────────────────────────────────────────*/
textarea {
display: block;
resize: vertical;
}
/* ── Checkboxes & Radios (Modern CSS) ──────────────────────────────────*/
label:has([type=checkbox], [type=radio]) {
width: fit-content;
cursor: pointer;
}
[type=checkbox],
[type=radio] {
width: 1.25em;
height: 1.25em;
margin-top: -0.125em;
margin-right: 0.5em;
vertical-align: middle;
cursor: pointer;
/* Modern CSS: use browser's native styling with our accent color */
accent-color: var(--accent);
}
[type=checkbox] ~ label,
[type=radio] ~ label {
display: inline-block;
margin-bottom: 0;
cursor: pointer;
}
[type=checkbox] ~ label:not(:last-of-type),
[type=radio] ~ label:not(:last-of-type) {
margin-right: 1em;
}
/* ── Validation States ─────────────────────────────────────────────────*/
input[aria-invalid=false],
select[aria-invalid=false],
textarea[aria-invalid=false] {
border-color: var(--accent);
}
input[aria-invalid=false]:is(:active, :focus-visible),
select[aria-invalid=false]:is(:active, :focus-visible),
textarea[aria-invalid=false]:is(:active, :focus-visible) {
border-color: var(--accent-hover);
box-shadow: 0 0 0 var(--outline-width) var(--accent-focus) !important;
}
input[aria-invalid=true],
select[aria-invalid=true],
textarea[aria-invalid=true] {
border-color: var(--error);
}
input[aria-invalid=true]:is(:active, :focus-visible),
select[aria-invalid=true]:is(:active, :focus-visible),
textarea[aria-invalid=true]:is(:active, :focus-visible) {
border-color: var(--error-active);
box-shadow: 0 0 0 var(--outline-width) var(--error-focus) !important;
}
/* ── Helper Text ───────────────────────────────────────────────────────*/
:where(input, select, textarea, fieldset) + small {
display: block;
width: 100%;
margin-top: calc(var(--space-4) * -0.75);
margin-bottom: var(--space-4);
color: var(--text-3);
}
:where(input, select, textarea, fieldset)[aria-invalid=false] + small {
color: var(--accent);
}
:where(input, select, textarea, fieldset)[aria-invalid=true] + small {
color: var(--accent-red);
}
label > :where(input, select, textarea) {
margin-top: calc(var(--space-4) * 0.25);
}
/* ── Navigation ────────────────────────────────────────────────────────*/
/* Semantic nav: */
body > nav {
display: flex;
justify-content: space-between;
align-items: center;
padding-top: var(--space-5);
padding-bottom: var(--space-5);
margin-bottom: var(--space-6);
border-bottom: var(--border-width) solid var(--border);
}
body > nav strong {
font-family: var(--font-mono);
font-weight: 700;
font-size: var(--text-base);
letter-spacing: -0.03em;
}
body > nav ul {
list-style: none;
display: flex;
gap: 0;
margin: 0;
padding: 0;
font-family: var(--font-mono);
font-size: var(--text-sm);
}
body > nav ul li {
list-style: none;
margin: 0;
padding: 0;
}
body > nav ul li + li::before {
content: "|";
color: var(--text-dim);
margin: 0 0.75rem;
}
body > nav a {
color: var(--text-2);
text-decoration: none;
transition: color var(--ease);
}
body > nav a:hover,
body > nav a[aria-current="page"] {
color: var(--text);
}
/* Medium screens: allow links to wrap */
@media (--nav-compact) {
body > nav ul {
flex-wrap: wrap;
gap: 0.25rem 0;
}
}
/* Small screens: stack brand above links */
@media (--md-n-below) {
body > nav {
flex-direction: column;
align-items: flex-start;
gap: var(--space-2);
}
body > nav ul:last-child {
flex-wrap: wrap;
}
body > nav ul:last-child li + li::before {
display: none;
}
}
/* ── Nav Dropdown ──────────────────────────────────────────────────────*/
/* inside