Files
small-packages/luci-theme-footstrap/styles/base/30-forms.css
T
2026-10-02 07:38:12 +08:00

221 lines
6.0 KiB
CSS
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
@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: theme/30-tables.css (legend) — absorbed */
fieldset legend {
display: block;
line-height: 1;
color: var(--fs-text);
padding-top: var(--fs-space-5);
}
/* Stays in BASE: docs/css.md "Forms: control typography stays in base, on purpose". select is
* excluded — face/size/leading live in theme/60-inputs.css. */
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;
margin-bottom: var(--fs-space-4);
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;
margin: 0;
}
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 {
margin-bottom: var(--fs-space-1);
padding: var(--fs-space-1) 2em var(--fs-space-1) var(--fs-space-2);
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;
}
.cbi-dynlist > .item.drag-over {
border-top: 1px solid var(--fs-text);
}
.cbi-dynlist > .item.dragging {
opacity: .5;
}
.cbi-dynlist > .item > span {
pointer-events: none;
}
.cbi-dynlist > .add-item {
display: flex;
}
.cbi-dynlist > .add-item > .cbi-input-text.drag-over {
border-top: 1px solid var(--fs-text);
}
.cbi-dynlist > .add-item > .cbi-button-add.drag-over {
border-top: 1px solid var(--fs-text);
}
.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),
input[type="checkbox"][disabled]::before,
input[type="checkbox"][disabled]::after,
input[type="radio"][disabled]::before,
input[type="radio"][disabled]::after {
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: 0 0 var(--fs-space-3) var(--fs-space-3);
}
.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;
}
}