mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-10-27 01:42:52 +08:00
221 lines
6.0 KiB
CSS
221 lines
6.0 KiB
CSS
@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;
|
||
}
|
||
}
|