blob: 8bdaaeecd88c7201da5eb7b058391b2250d8d075 [file]
/* The open row group (SettingsSection variant='rows'). The Astryx settings
idiom — the CLI's settings/settings-dialog templates and `astryx docs
layout` — is edge-to-edge rows split by hairline dividers, with NO card
chrome ("no stacked full-width Cards as page structure"). The former
`.settingsRows` Card is gone; this is a plain block that owns only the
row track and the divider rhythm. */
.settingsRows {
display: grid;
/* Explicit track (#1362): the implicit `auto` track sizes to the widest
child's max-content, so one wide row (an English SegmentedControl, a
long input placeholder) would push every row past the content column.
minmax(0,1fr) pins the track and lets rows wrap instead of clip. */
grid-template-columns: minmax(0, 1fr);
gap: 0;
container: settings-rows / inline-size;
}
/* Hairline between neighboring rows — the templates' own row-then-Divider
idiom, owned by the group so call sites can't forget it. */
.settingsRows > * + *,
.settingsRowsGroup > * + * {
border-block-start: var(--border-width-hairline) solid var(--border);
}
/* …and the row must be square for that hairline to read as one line.
Astryx's Item ships `border-radius: 10px` for its standalone use — a
rounded chip that highlights on hover. Our divider is a border on the Item
itself, and a border follows its element's corners, so the line curved
down at both ends: a straight middle with two hooks, which reads as two
different divider systems meeting. (Reported by owner; measured at
runtime as radius 10px + border-block-start 1px on `.astryx-item`.)
In an edge-to-edge row group the row is not a chip — it spans the column,
so its hover highlight should span it too. Zeroing the radius is therefore
the whole fix: do NOT wrap the row to preserve rounded hover, which would
reintroduce the chip the open idiom removed. */
.settingsRows > .astryx-item,
.settingsRowsGroup > .astryx-item {
border-radius: 0;
}
/* Form blocks inside a row group (SettingsField / SettingsActions): block
padding only — the open idiom has no inline inset, so fields stay flush
with the section heading and the Item rows around them. */
.settingsRows > .settingsFieldRow,
.settingsRowsGroup > .settingsFieldRow {
padding-block: var(--space-3);
}
/* Not on .settingsActionRow — that one stays the flex cluster from form.css
(grid would stretch each button to a full-width stacked bar). */
.settingsRows > .settingsFieldRow:not(.settingsActionRow),
.settingsRowsGroup > .settingsFieldRow:not(.settingsActionRow) {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: var(--space-3);
}
/* A semantic wrapper (role="group" + aria-label) around consecutive rows in
a group. Lays out exactly like the group itself so its rows keep the
shared track and divider rhythm. */
.settingsRowsGroup {
display: grid;
grid-template-columns: minmax(0, 1fr);
}
.settingsReadOnlyValue {
min-width: 0;
max-width: var(--settings-row-end-cap);
color: var(--foreground-secondary);
font: var(--maka-text-body);
font-variant-numeric: tabular-nums;
overflow-wrap: anywhere;
text-align: end;
}
.settingsFormRowControlCluster {
display: inline-flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
gap: var(--space-2);
}
.settingsReadOnlyValue[data-mono="true"] {
/* Machine text renders as its own full-width line under the description
(see SettingRow) — never as a right-anchored ragged block. */
display: block;
max-width: 100%;
font: var(--maka-text-code);
text-align: start;
word-break: break-all;
}
/* A multi-button flow rendered under a row's description (Permission Center
grant cluster). Breathing room from the text above; buttons are real
interactive children so the description stays plain supporting text. */
.settingsRowActionsUnder {
margin-block-start: var(--space-2);
}
/* A quiet subgroup label inside a row group (health layers, palette groups):
more air above than below so it binds to the rows it introduces. */
.settingsRows > .settingsRowsSubheading {
padding-block: var(--space-3) var(--space-1);
}
/* StatusDot + text, the quiet status idiom shared by health / permission /
memory / web-search rows. */
.settingsStatus {
display: inline-flex;
align-items: center;
gap: var(--space-1-5);
color: var(--foreground-secondary);
font: var(--maka-text-body);
white-space: nowrap;
}
/* The row's end slot (SettingsRow `end`): right-aligned, allowed to wrap,
and capped so a wide control shrinks/wraps before it crushes the label. */
.settingsRowEnd {
display: inline-flex;
align-items: center;
justify-content: flex-end;
flex-wrap: wrap;
gap: var(--space-2);
min-width: 0;
max-width: var(--settings-row-end-cap);
}
/* A Selector layer is min-width: anchor-size(width), but its intrinsic option
width may still make it wider than the right-aligned end slot. The selected
font decides that intrinsic width, so a label that fits on macOS can push
the left-aligned top-layer popover past the page edge on Linux. The setting
row owns the available inline space: cap its listbox layers to their anchor
and let the Selector's Item truncate long labels inside that stable width. */
.settingsRowEnd [popover]:has([role="listbox"]) {
max-width: anchor-size(width);
}
@container settings-rows (max-width: 460px) {
.settingsReadOnlyValue,
.settingsRowEnd {
max-width: 100%;
text-align: start;
}
.settingsActionRow > button {
flex-shrink: 1;
height: auto;
min-height: 2rem;
}
}
/* The expanded half of SettingsExpandableRow: the editor the caller supplies,
then its Save / Cancel pair. A grid rather than margins so the gap is the
row group's own rhythm and the editor keeps the field block's full width. */
.settingsExpandableEditor {
display: grid;
grid-template-columns: minmax(0, 1fr);
gap: var(--space-3);
}
.settingsExpandableField {
padding-block: var(--space-3);
}
.requestHeaderRow {
display: grid;
grid-template-columns: minmax(0, 5fr) minmax(0, 7fr) auto;
align-items: start;
gap: var(--space-2);
}
.requestHeaderName,
.requestHeaderValue {
min-width: 0;
}
.requestHeaderRemove {
display: flex;
align-items: center;
min-height: 2.5rem;
}
@container settings-rows (max-width: 460px) {
.requestHeaderRow {
grid-template-columns: minmax(0, 1fr) auto;
}
.requestHeaderName {
grid-column: 1 / -1;
}
}
/* The group's own corners (visual system 2.0, T4).
DESIGN.md §6 keeps `border-radius: 0` legal on these rows — they are true
full-bleed rows, flush with the group on both inline edges — but the GROUP
still has to end somewhere. Without corners a hovered or selected first row
paints a square fill into the page, so a bounded list reads as if it were
bleeding off its own container. §6 puts list containers on the card tier.
Rounded on the outer corners of the end rows rather than by clipping the
group, and that is the load-bearing part: the row carries its focus ring as
`outline: 2px solid` at `outline-offset: 2px`, i.e. 4px OUTSIDE its border
box (measured, not assumed). `overflow: hidden` on the group would cut that
ring off on exactly the first and last rows — a keyboard-visibility
regression in return for a cosmetic corner. `overflow: clip` with an
`overflow-clip-margin` big enough to spare the ring would push the clip edge
out past the corner it was supposed to round, which defeats the point.
Rounding the end rows clips nothing at all.
Only the OUTER corners move, so the divider rhythm above is untouched: the
hairline is a `border-block-start` on rows 2..n, and neither the first row's
top edge nor the last row's bottom edge carries one. The "straight middle
with two hooks" this file already documents cannot come back.
Keyed on `> *` rather than `> .astryx-item` because a group can end on a
form block (`.settingsFieldRow` / `.settingsActionRow`), and the corner
belongs to whatever is actually last. Placed after the `radius: 0` rule
above: equal specificity, so source order decides. */
.settingsRows > *:first-child,
.settingsRowsGroup > *:first-child {
border-start-start-radius: var(--radius-surface);
border-start-end-radius: var(--radius-surface);
}
.settingsRows > *:last-child,
.settingsRowsGroup > *:last-child {
border-end-start-radius: var(--radius-surface);
border-end-end-radius: var(--radius-surface);
}