Files
com.gregkilmer.www/packages/ui/src/styles/elements.css
T
Claude 4614cd25a0 Add a dark and light mode toggle to the header
A sun and moon button at the end of the nav (and the Store's nav) swaps
the mode and remembers the choice in the browser. Until it is pressed the
site follows the device setting. A head script sets html[data-theme]
before first paint, so light styles now key off data-theme instead of a
media query, and motifs render both images with CSS showing one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aSbo2D1qP8cMFQCykf7kx
2026-10-18 19:57:05 +00:00

350 lines
8.2 KiB
CSS

/*
* The element rules Greg approved on 2026-10-11 (Element rules board, canvas
* version 17). Classes, not only components, so Markdown and the admin page
* can use them too.
*
* Gold is structure (frames, rules, active and favorite), teal is the action
* or a live state, violet only marks a star. Hover and focus changes take
* 150 to 200ms and never move text. Disabled is 40% opacity with no hover.
*/
/* I. Buttons: teal pill primary, gold hairline secondary, filament text link. */
.gk-btn {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 8px;
min-height: var(--gk-control);
padding: 0 24px;
border-radius: var(--gk-radius-pill);
font-family: var(--gk-font-body);
font-size: 14px;
font-weight: 700;
line-height: 1.2;
text-decoration: none;
white-space: nowrap;
cursor: pointer;
transition: background var(--gk-ease), border-color var(--gk-ease), box-shadow var(--gk-ease), color var(--gk-ease);
}
.gk-btn.gk-sm {
min-height: var(--gk-control-sm);
padding: 0 16px;
font-size: 13px;
}
.gk-pri {
background: var(--gk-teal);
color: var(--gk-sky);
border: 0;
}
.gk-pri:hover {
background: var(--gk-teal-bright);
color: var(--gk-sky);
box-shadow: 0 0 0 4px rgba(var(--gk-teal-rgb), 0.16);
}
/* On Starlight the deep teal carries white text (5.8:1); the lighter teal is too faint. */
:root[data-theme="light"] .gk-pri,
:root[data-theme="light"] .gk-pri:hover {
color: #fff;
}
:root[data-theme="light"] .gk-pri {
background: var(--gk-teal-bright);
}
:root[data-theme="light"] .gk-pri:hover {
background: #085e58;
}
.gk-sec {
background: transparent;
color: var(--gk-text);
border: 1px solid var(--gk-gold-line);
font-weight: 600;
}
.gk-sec:hover {
background: var(--gk-gold-tint);
border-color: var(--gk-gold);
color: var(--gk-text);
}
.gk-btn:disabled,
.gk-btn[aria-disabled="true"] {
opacity: 0.4;
pointer-events: none;
}
.gk-text {
color: var(--gk-teal-bright);
font-weight: 600;
text-decoration: none;
padding-bottom: 3px;
background: var(--gk-filament) no-repeat center bottom / 0 1.5px;
transition: background-size 0.2s, color var(--gk-ease);
}
.gk-text:hover {
background-size: 100% 1.5px;
color: var(--gk-text);
}
.gk-text.gk-quiet {
color: var(--gk-soft);
font-weight: 500;
}
.gk-text.gk-quiet:hover {
color: var(--gk-text);
}
/* II. Round pill is a state; square chip is a label. */
.gk-pill {
display: inline-flex;
align-items: center;
gap: 6px;
height: var(--gk-chip);
padding: 0 11px;
border-radius: var(--gk-radius-pill);
border: 1px solid var(--gk-lines-strong);
color: var(--gk-soft);
font-size: 12px;
font-weight: 600;
white-space: nowrap;
}
.gk-pill.live {
border-color: rgba(var(--gk-teal-rgb), 0.6);
color: var(--gk-teal-bright);
}
.gk-pill.live::before {
content: "";
flex: none;
width: 6px;
height: 6px;
border-radius: 50%;
background: var(--gk-teal-bright);
box-shadow: 0 0 6px rgba(var(--gk-teal-rgb), 0.8);
}
/* A state that is not happening now keeps the round pill without the lit dot. */
.gk-pill.state {
border-color: rgba(var(--gk-teal-rgb), 0.6);
color: var(--gk-teal-bright);
}
.gk-pill.cur {
border-color: var(--gk-gold-line);
color: var(--gk-gold-bright);
}
.gk-chip {
display: inline-flex;
align-items: center;
gap: 6px;
min-height: var(--gk-chip);
padding: 0 10px;
border-radius: var(--gk-radius-chip);
border: 1px solid var(--gk-lines);
color: var(--gk-soft);
font-size: 12px;
font-weight: 600;
text-decoration: none;
transition: border-color var(--gk-ease), color var(--gk-ease);
}
.gk-chip.core {
border-color: rgba(var(--gk-teal-rgb), 0.55);
color: var(--gk-text);
}
a.gk-chip:hover {
border-color: var(--gk-teal-bright);
color: var(--gk-text);
}
/* III. Filters: separate 36px pills; the active one gets gold and a star. */
.gk-filters {
display: flex;
flex-wrap: wrap;
gap: 8px;
margin: 0;
padding: 0;
list-style: none;
}
.gk-filter {
display: inline-flex;
align-items: center;
justify-content: center;
gap: 6px;
min-height: var(--gk-control-sm);
padding: 0 14px;
border-radius: var(--gk-radius-pill);
border: 1px solid var(--gk-lines);
background: transparent;
color: var(--gk-soft);
font-family: var(--gk-font-body);
font-size: 13px;
font-weight: 600;
text-decoration: none;
cursor: pointer;
transition: border-color var(--gk-ease), background var(--gk-ease), color var(--gk-ease);
}
.gk-filter:hover {
border-color: var(--gk-gold-line);
color: var(--gk-text);
}
.gk-filter.on,
.gk-filter[aria-current],
.gk-filter[aria-pressed="true"] {
border-color: var(--gk-gold);
background: var(--gk-gold-tint);
color: var(--gk-text);
}
.gk-filter .gk-fs {
display: none;
}
.gk-filter.on .gk-fs,
.gk-filter[aria-current] .gk-fs,
.gk-filter[aria-pressed="true"] .gk-fs {
display: inline-flex;
}
/* IV. Kickers are gold capitals over a tick scale; notices are a ledger note. */
.gk-kicker {
display: inline-flex;
flex-direction: column;
gap: 6px;
}
.gk-kicker-text {
display: inline-flex;
align-items: center;
gap: 8px;
color: var(--gk-gold-bright);
font-size: 11px;
font-weight: 600;
letter-spacing: 0.3em;
text-transform: uppercase;
}
.gk-note {
display: flex;
align-items: center;
gap: 12px;
padding: 12px 16px;
border-left: 2px solid var(--gk-gold);
border-radius: 0 var(--gk-radius) var(--gk-radius) 0;
background: rgba(var(--gk-gold-rgb), 0.08);
color: var(--gk-text);
font-size: 13px;
}
.gk-note b {
font-weight: 600;
}
/* V. Fields: 10px box; on focus a teal border and a filament across the base. */
.gk-label {
display: flex;
flex-direction: column;
gap: 6px;
}
.gk-label-text {
font-size: 12px;
font-weight: 600;
color: var(--gk-soft);
}
.gk-hint {
font-size: 12px;
color: var(--gk-muted);
}
.gk-field {
width: 100%;
padding: 0 14px;
border: 1px solid var(--gk-lines);
border-radius: var(--gk-radius);
background: var(--gk-sky) var(--gk-filament) no-repeat center bottom / 0 2px;
color: var(--gk-text);
font-family: var(--gk-font-body);
font-size: 14px;
transition: border-color var(--gk-ease), background-size 0.25s;
}
input.gk-field,
select.gk-field {
min-height: var(--gk-control);
}
textarea.gk-field {
padding: 12px 14px;
min-height: 120px;
resize: vertical;
}
.gk-field::placeholder {
color: var(--gk-placeholder);
}
.gk-field:hover,
.gk-search:hover {
border-color: var(--gk-lines-strong);
}
.gk-field:focus {
outline: none;
border-color: var(--gk-teal-bright);
background-size: 92% 2px;
}
.gk-field[aria-invalid="true"] {
border-color: var(--gk-danger);
}
.gk-search {
display: flex;
align-items: center;
gap: 8px;
padding: 0 14px;
min-height: var(--gk-control);
border: 1px solid var(--gk-lines);
border-radius: var(--gk-radius);
background: var(--gk-midnight) var(--gk-filament) no-repeat center bottom / 0 2px;
color: var(--gk-muted);
transition: border-color var(--gk-ease), background-size 0.25s;
}
.gk-search:focus-within {
border-color: var(--gk-teal-bright);
background-size: 92% 2px;
}
.gk-search input {
flex: 1;
min-width: 0;
min-height: 40px;
border: 0;
background: transparent;
color: var(--gk-text);
font: 14px var(--gk-font-body);
}
.gk-search input:focus {
outline: none;
}
.gk-search input::placeholder {
color: var(--gk-placeholder);
}
/* VI. Cards: a linked card turns gold and shows a tick scale on hover. */
.gk-card {
position: relative;
display: flex;
flex-direction: column;
gap: 6px;
padding: 16px;
border: 1px solid var(--gk-lines);
border-radius: var(--gk-radius);
background: var(--gk-midnight);
color: var(--gk-text);
text-decoration: none;
transition: border-color 0.2s;
}
.gk-card::before {
content: "";
position: absolute;
left: 16px;
right: 16px;
top: 0;
height: 7px;
background: url("../assets/ornaments/card-ticks.svg") repeat-x left top;
opacity: 0;
transition: opacity 0.2s;
pointer-events: none;
}
a.gk-card:hover,
.gk-card.gk-linked:hover {
border-color: rgba(var(--gk-gold-rgb), 0.55);
}
a.gk-card:hover::before,
.gk-card.gk-linked:hover::before {
opacity: 1;
}
.gk-featured {
position: relative;
border: 1px solid rgba(var(--gk-gold-rgb), 0.55);
border-radius: var(--gk-radius);
background: var(--gk-midnight);
}