update 2026-10-25 02:32:31

This commit is contained in:
action committed 2026-10-25 02:32:31 +08:00
1 parent 852fced2b3
commit 97b4bdf8c8
84 files changed
+16197 -2

No files matched your search

@@ -0,0 +1,203 @@
@layer base {
/* Forms: input types, .cbi-value row layout, focus/disabled/readonly/invalid states. */
fieldset {
margin-bottom: var(--fs-space-2);
padding-top: var(--fs-space-2);
}
/* size + ink: theme/30-tables.css (legend) — absorbed */
fieldset legend {
display: block;
line-height: 1;
padding-top: var(--fs-space-5);
}
/* Stays in BASE: docs/css.md "Forms: control typography stays in base, on purpose". select is
* excluded, and an input's size is theme/60-inputs.css's --fs-type-field. */
label,
input,
button {
font-family: var(--fs-font-sans);
font-size: var(--fs-type);
font-weight: var(--fs-weight-normal);
line-height: normal;
}
.cbi-value {
display: flex;
flex-wrap: wrap;
align-items: baseline;
}
.cbi-value-field {
margin-inline-start: var(--fs-space-5); /* logical: LuCI ships four RTL languages */
flex: 1;
min-width: 0; /* else a nested table or one long value pushes the row out of the card */
}
/* size + ink: theme/60-inputs.css (.cbi-value-title) — absorbed. Left: label column geometry. */
.cbi-value label.cbi-value-title {
padding-top: var(--fs-space-1); /* lands the label's first baseline on the field's */
flex: 0 0 180px; /* column WIDTH (longest option label), not on the 4px step scale */
text-align: end; /* towards the field — not base/95-luci.css's physical .left/.right/.center */
/* docs/css.md "Forms: the label column's min-width: 0 survives the responsive layer" —
* stated here, not in theme/90-responsive.css. */
min-width: 0;
}
.cbi-value > .cbi-section,
.cbi-value > .cbi-tblsection {
width: 100%;
}
label > input[type="checkbox"],
label > input[type="radio"] {
vertical-align: text-top;
}
label[for] {
cursor: pointer;
}
/* Shared field box (210px x control-height, #localtime widening, per-widget escapes):
* theme/60-inputs.css — absorbed whole, in-layer, or it loses to a theme rule by layer. */
.cbi-dynlist {
height: auto;
display: inline-flex;
flex-direction: column;
}
/* item paint: theme/60-inputs.css — absorbed. Left: drag-and-drop machinery (UIDynamicList). */
.cbi-dynlist > .item {
padding-block: var(--fs-space-1);
padding-inline: var(--fs-space-2) 2em;
position: relative;
pointer-events: auto;
overflow: hidden;
word-break: break-all;
cursor: move;
user-select: text;
}
/* plate paint: theme/60-inputs.css — absorbed. Left: pins the × to the chip. */
.cbi-dynlist > .item::after {
content: "×";
position: absolute;
align-items: center;
top: -1px;
inset-inline-end: -1px;
bottom: -1px;
font-weight: var(--fs-weight-bold);
pointer-events: auto;
}
/* drop indicator (.drag-over): theme/60-inputs.css — a base rule lost to the theme border shorthands by layer */
.cbi-dynlist > .item.dragging {
opacity: .5;
}
.cbi-dynlist > .item > span {
pointer-events: none;
}
.cbi-dynlist > .add-item {
display: flex;
}
.cbi-dynlist > .add-item > input,
.cbi-dynlist > .add-item > button {
/* flex: theme/60-inputs.css — absorbed */
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.cbi-value-field > .cbi-checkbox,
.cbi-value-field > div > .cbi-radio {
height: var(--fs-control-h); /* lines a toggle up with the field above it */
display: inline-flex;
align-items: center;
}
.cbi-radio {
cursor: pointer;
gap: var(--fs-space-1);
}
/* .cbi-select and the checkbox/radio drawing: theme/60-inputs.css — absorbed whole. Do not
* re-add an option rule here either: layer beats specificity, so theme's bare `option`
* outranks even `.cbi-select select option:checked`. */
/* --fs-placeholder, not --fs-dim: a placeholder carries the option's DEFAULT and must not read
* as a value the reader typed (03-palettes.css has the numbers). */
::placeholder {
color: var(--fs-placeholder);
}
/* Transitions and the focus/hover ring: the theme's one ring token
* (--fs-focus-ring/--fs-focus-ring-invalid). No generic glow here. */
input[disabled],
button[disabled],
select[disabled],
textarea[disabled],
.cbi-dropdown[disabled]:not(.btn):not(.cbi-button) {
opacity: var(--fs-disabled-opacity);
pointer-events: none;
cursor: default;
}
/* readonly border fade: theme/60-inputs.css — absorbed with the generic box */
.cbi-optionals,
.cbi-section-create {
padding-block: 0 var(--fs-space-3);
padding-inline: var(--fs-space-3) 0;
}
.cbi-section-create {
display: inline-flex;
align-items: center;
gap: var(--fs-space-2); /* not a negative-margin pair — that trick predates flex gap, leaks */
}
.cbi-section-create > * {
flex: 1 1 auto;
}
/* the input's cell-filling width: theme/60-inputs.css — absorbed with the generic box */
/* .cbi-page-actions paint: theme/55-buttons.css — absorbed. .actions has no theme override, so
* it stays: some luci-app-* still emits it. */
.actions {
background: var(--fs-panel2);
margin-bottom: var(--fs-space-4);
padding: var(--fs-card-pad); /* a plate, so it takes the card's own gutter on every side */
border-top: var(--fs-hairline);
border-radius: 0 0 var(--fs-radius-lg) var(--fs-radius-lg);
text-align: end;
}
/* Physical, hand-mirrored: docs/css.md "Widgets: .actions .secondary-action still floats, and
* needs a hand RTL mirror". */
.actions .secondary-action {
float: right;
}
:root[dir="rtl"] .actions .secondary-action { float: left; }
.actions .secondary-action a,
.cbi-page-actions .secondary-action a {
line-height: var(--fs-control-h);
}
.actions .secondary-action a:hover,
.cbi-page-actions .secondary-action a:hover {
text-decoration: underline;
}
.cbi-page-actions > form {
display: inline;
margin: 0;
}
}