The config-grid toggle box used the input's 12px vertical padding, but its 24px pill made it render 48px tall vs the inputs' 44px, so it sat too tall to read as inline. Trim vertical padding to 10px so the box is 44px. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> Signed-off-by: librelad <librelad@digitalangels.vip>
1048 lines
25 KiB
CSS
1048 lines
25 KiB
CSS
|
|
|
|
/* Form fields, inputs, checkboxes/tickboxes, input groups. Extracted from style.css. */
|
|
|
|
/* Form Fields */
|
|
.form-field {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 6px;
|
|
min-width: 0;
|
|
}
|
|
|
|
.form-label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
font-weight: 500;
|
|
color: var(--text-primary, #fff);
|
|
font-size: 13px;
|
|
}
|
|
|
|
.required {
|
|
color: var(--danger-color);
|
|
font-weight: bold;
|
|
}
|
|
|
|
.help-icon {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 14px;
|
|
height: 14px;
|
|
background: var(--primary-color);
|
|
color: var(--text-primary);
|
|
border-radius: 50%;
|
|
font-size: 9px;
|
|
font-weight: bold;
|
|
cursor: help;
|
|
position: relative;
|
|
}
|
|
|
|
.help-icon:hover::after {
|
|
content: attr(title);
|
|
position: absolute;
|
|
bottom: 100%;
|
|
left: 50%;
|
|
transform: translateX(-50%);
|
|
background: var(--tooltip-bg);
|
|
color: var(--tooltip-text);
|
|
padding: 4px 8px;
|
|
border-radius: 4px;
|
|
font-size: 11px;
|
|
white-space: nowrap;
|
|
z-index: 1000;
|
|
margin-bottom: 6px;
|
|
min-width: 180px;
|
|
text-align: center;
|
|
font-weight: normal;
|
|
}
|
|
|
|
.form-input,
|
|
.form-select,
|
|
.form-textarea {
|
|
width: 100%;
|
|
padding: 10px;
|
|
border: 1px solid var(--border-color);
|
|
border-radius: 6px;
|
|
color: var(--text-primary, #fff);
|
|
font-size: 13px;
|
|
transition: all 0.2s ease;
|
|
}
|
|
|
|
.form-input:focus,
|
|
.form-select:focus,
|
|
.form-textarea:focus {
|
|
outline: none;
|
|
border-color: var(--primary-color);
|
|
box-shadow: 0 0 0 2px rgba(74, 144, 226, 0.1);
|
|
}
|
|
|
|
.form-textarea {
|
|
resize: vertical;
|
|
min-height: 80px;
|
|
font-family: inherit;
|
|
}
|
|
|
|
.form-help {
|
|
color: var(--text-secondary, #ccc);
|
|
font-size: 11px;
|
|
font-style: italic;
|
|
margin-top: 4px;
|
|
}
|
|
|
|
.checkbox-label.disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.checkbox-label.disabled .checkbox-custom {
|
|
background: var(--hover-bg);
|
|
border-color: var(--border-color);
|
|
opacity: 0.5;
|
|
}
|
|
|
|
.checkbox-label.disabled .checkbox-text {
|
|
color: var(--text-secondary, #ccc);
|
|
}
|
|
|
|
.form-label.disabled {
|
|
color: var(--text-secondary, #ccc);
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.form-input.disabled {
|
|
background: var(--hover-bg);
|
|
border-color: var(--border-color);
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* Input Group for Number + Unit */
|
|
.input-group {
|
|
display: flex;
|
|
align-items: stretch;
|
|
}
|
|
|
|
.input-group .form-control {
|
|
border-top-right-radius: 0;
|
|
border-bottom-right-radius: 0;
|
|
border-right: none;
|
|
}
|
|
|
|
.input-group .form-control:focus {
|
|
border-right: none;
|
|
border-color: var(--primary-color);
|
|
box-shadow: 0 0 0 0.2rem rgba(var(--accent-rgb), 0.25);
|
|
}
|
|
|
|
.input-group-text {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 10px 12px;
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
line-height: 1.5;
|
|
color: var(--text-color);
|
|
text-align: center;
|
|
white-space: nowrap;
|
|
background-color: var(--input-bg);
|
|
border: 1px solid var(--border-color);
|
|
border-top-right-radius: 6px;
|
|
border-bottom-right-radius: 6px;
|
|
min-width: 50px;
|
|
justify-content: center;
|
|
}
|
|
|
|
.master-toggle .checkbox-label,
|
|
.git-master-toggle .checkbox-label {
|
|
display: flex;
|
|
align-items: center;
|
|
font-weight: 600;
|
|
font-size: 16px;
|
|
cursor: pointer;
|
|
width: 100%;
|
|
}
|
|
|
|
/* .master-toggle and .git-master-toggle are section-enable controls
|
|
(e.g. backup remote 1, mail config). They inherit the default toggle
|
|
visual from .checkbox-custom — no overrides needed here. The
|
|
.git-master-toggle block lower in this file remains for legacy
|
|
layout (font-weight/sizing on the surrounding label). */
|
|
|
|
.section-content.disabled .field-group {
|
|
opacity: 0.6;
|
|
}
|
|
|
|
/* Themed <select> dropdown. Native rendering on Linux/Firefox honors
|
|
the OS dark theme and paints the control black regardless of our
|
|
CSS, so we strip the native appearance and supply our own glass
|
|
surface + chevron. */
|
|
select.form-control {
|
|
-webkit-appearance: none;
|
|
-moz-appearance: none;
|
|
appearance: none;
|
|
background-color: rgba(var(--text-rgb), 0.06);
|
|
color: var(--text-primary);
|
|
border: 1px solid rgba(var(--text-rgb), 0.20);
|
|
/* Inline SVG chevron, recoloured via theme text-rgb so it stays
|
|
readable on every theme. */
|
|
background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='rgba(255,255,255,0.7)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'><polyline points='6 9 12 15 18 9'/></svg>");
|
|
background-repeat: no-repeat;
|
|
background-position: right 14px center;
|
|
background-size: 16px 16px;
|
|
padding-right: 40px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* <option> elements are drawn by the OS popup, not the page surface.
|
|
We can only nudge their colors; the popup chrome itself is platform-
|
|
native. Use the theme's solid surface so options stay readable. */
|
|
select.form-control option {
|
|
background-color: var(--surface-bg-solid);
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
select.form-control:hover {
|
|
border-color: rgba(var(--accent-rgb), 0.40);
|
|
}
|
|
|
|
select.form-control:focus {
|
|
outline: none;
|
|
border-color: var(--accent);
|
|
background-color: rgba(var(--text-rgb), 0.10);
|
|
box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.20);
|
|
}
|
|
|
|
.field-group {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
.field-group label {
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
color: var(--text-secondary, #ccc);
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.form-control {
|
|
width: 100%;
|
|
padding: 12px 16px;
|
|
border: 1px solid rgba(var(--text-rgb), 0.2);
|
|
border-radius: 8px;
|
|
background: rgba(var(--text-rgb), 0.05);
|
|
color: var(--text-primary, #fff);
|
|
font-size: 14px;
|
|
font-family: inherit;
|
|
transition: all 0.2s ease;
|
|
resize: vertical;
|
|
min-height: 44px;
|
|
}
|
|
|
|
.form-control:focus {
|
|
outline: none;
|
|
border-color: var(--primary-color, var(--accent));
|
|
background: rgba(var(--text-rgb), 0.08);
|
|
box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.1);
|
|
}
|
|
|
|
.form-control::placeholder {
|
|
color: var(--text-secondary, #ccc);
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.password-field .form-control {
|
|
padding-right: 48px;
|
|
}
|
|
|
|
.field-group label {
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
color: var(--text-secondary, #ccc);
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
/* Git Configuration Master Toggle */
|
|
|
|
/* INSTALL_MODE dropdown: narrower than full-width. Both selectors
|
|
below are needed because the custom-select.js component wraps the
|
|
native <select> in a .custom-select div — we have to constrain the
|
|
wrapper (which is what's visually rendered) AND the native select
|
|
(which is what's there when JS hasn't enhanced it yet, or when
|
|
custom-select is opted out via data-no-enhance). */
|
|
.git-master-toggle select.form-control,
|
|
.git-master-toggle .custom-select {
|
|
width: auto !important;
|
|
max-width: 33%;
|
|
}
|
|
|
|
.git-master-toggle .checkbox-text {
|
|
font-weight: 600;
|
|
font-size: 16px;
|
|
margin-left: 8px;
|
|
}
|
|
|
|
.git-master-toggle .checkbox-label {
|
|
display: flex;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
padding: 0;
|
|
border-radius: 0;
|
|
transition: none;
|
|
background: transparent;
|
|
}
|
|
|
|
.git-master-toggle .checkbox-label:hover {
|
|
background: transparent;
|
|
}
|
|
|
|
/* Toggle Switch Design - Complete override */
|
|
.git-master-toggle .checkbox-label input[type="checkbox"] {
|
|
display: none !important;
|
|
opacity: 0 !important;
|
|
position: absolute !important;
|
|
}
|
|
|
|
.git-master-toggle .checkbox-custom {
|
|
position: relative;
|
|
width: 48px;
|
|
height: 24px;
|
|
background: var(--border-strong);
|
|
border-radius: 24px;
|
|
margin-right: 12px;
|
|
transition: all 0.3s ease;
|
|
cursor: pointer;
|
|
border: none !important;
|
|
}
|
|
|
|
.git-master-toggle .checkbox-custom::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 2px;
|
|
left: 2px;
|
|
width: 20px;
|
|
height: 20px;
|
|
background: white;
|
|
border-radius: 50%;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.git-master-toggle .checkbox-label input[type="checkbox"]:checked + .checkbox-custom {
|
|
background: var(--primary-color) !important;
|
|
border-color: var(--primary-color) !important;
|
|
}
|
|
|
|
.git-master-toggle .checkbox-label input[type="checkbox"]:checked + .checkbox-custom::before {
|
|
transform: translateX(24px);
|
|
}
|
|
|
|
.git-master-toggle .checkbox-label input[type="checkbox"]:hover + .checkbox-custom {
|
|
}
|
|
|
|
.git-master-toggle .checkbox-text {
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
color: var(--text-primary);
|
|
line-height: 1.4;
|
|
user-select: none;
|
|
}
|
|
|
|
/* Config page checkboxes — mirror the .form-control field box (same radius,
|
|
fill and border) so a toggle reads as the same field surface as the inputs
|
|
beside it instead of a lighter, slightly-off box. Vertical padding is 10px
|
|
(not the input's 12px): the 24px toggle pill is taller than input text, so
|
|
the trimmed padding keeps the box at the inputs' 44px height (24 + 10 + 10)
|
|
instead of overshooting to 48px. */
|
|
.checkbox-label {
|
|
display: flex;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
padding: 10px 16px;
|
|
min-height: 44px;
|
|
border-radius: 8px;
|
|
transition: background 0.18s ease, border-color 0.18s ease;
|
|
background: rgba(var(--text-rgb), 0.05);
|
|
border: 1px solid rgba(var(--text-rgb), 0.20);
|
|
}
|
|
|
|
/* In a multi-column config row the toggle cell only contains the
|
|
toggle (no label/help text above it like the input cells do), so
|
|
it sits at the top of the row while the inputs underneath their
|
|
labels run lower. align-self: end drops the toggle to the bottom
|
|
of the grid row so its row aligns with the inputs' row, not the
|
|
inputs' labels. */
|
|
.config-fields > .checkbox-field {
|
|
align-self: end;
|
|
}
|
|
|
|
.checkbox-label:hover {
|
|
background: rgba(var(--text-rgb), 0.07);
|
|
border-color: rgba(var(--accent-rgb), 0.35);
|
|
}
|
|
|
|
.checkbox-label.disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
background: transparent;
|
|
border-color: var(--border-color);
|
|
}
|
|
|
|
.checkbox-label.disabled .checkbox-custom {
|
|
background: var(--hover-bg);
|
|
border-color: var(--border-color);
|
|
}
|
|
|
|
.checkbox-label input[type="checkbox"] {
|
|
display: none !important;
|
|
opacity: 0 !important;
|
|
position: absolute !important;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* ------------------------------------------------------------------
|
|
Default checkbox visual = TOGGLE SWITCH.
|
|
Most app/config options are binary data settings (Enable X, Auto-Y)
|
|
for which a sliding switch reads as "on/off".
|
|
|
|
The TICKBOX variant (square with check) lives further down, scoped
|
|
to .toggle-section and .advanced-toggle-field — those host the
|
|
"Show Advanced / Show Unused" UI preferences where a tickbox better
|
|
signals "this affects what you see, not the data".
|
|
------------------------------------------------------------------ */
|
|
.checkbox-custom {
|
|
position: relative;
|
|
width: 48px;
|
|
height: 24px;
|
|
flex-shrink: 0;
|
|
margin-right: 12px;
|
|
background: rgba(var(--text-rgb), 0.20);
|
|
border: none;
|
|
border-radius: 24px;
|
|
cursor: pointer;
|
|
transition: background 0.18s ease, box-shadow 0.18s ease;
|
|
}
|
|
|
|
.checkbox-custom::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 2px;
|
|
left: 2px;
|
|
width: 20px;
|
|
height: 20px;
|
|
background: var(--text-primary);
|
|
border-radius: 50%;
|
|
transition: transform 0.18s ease;
|
|
}
|
|
|
|
.checkbox-label input[type="checkbox"]:hover + .checkbox-custom {
|
|
box-shadow: 0 0 0 4px rgba(var(--accent-rgb), 0.10);
|
|
}
|
|
|
|
.checkbox-label input[type="checkbox"]:checked + .checkbox-custom {
|
|
background: var(--accent);
|
|
}
|
|
|
|
.checkbox-label input[type="checkbox"]:checked + .checkbox-custom::before {
|
|
transform: translateX(24px);
|
|
}
|
|
|
|
/* ------------------------------------------------------------------
|
|
TICKBOX variant — used for "this changes what you see" preferences
|
|
like Show Advanced Options / Show Unused Options / Show advanced
|
|
settings. Scoped by parent class so the toggle stays the default
|
|
everywhere else.
|
|
------------------------------------------------------------------ */
|
|
.toggle-section .checkbox-custom,
|
|
.advanced-toggle-field .checkbox-custom {
|
|
width: 20px;
|
|
height: 20px;
|
|
margin-right: 10px;
|
|
background: rgba(var(--text-rgb), 0.05);
|
|
border: 1.5px solid rgba(var(--text-rgb), 0.40);
|
|
border-radius: 4px;
|
|
box-shadow: none;
|
|
}
|
|
|
|
.toggle-section .checkbox-custom::before,
|
|
.advanced-toggle-field .checkbox-custom::before {
|
|
content: none;
|
|
}
|
|
|
|
.toggle-section .checkbox-custom::after,
|
|
.advanced-toggle-field .checkbox-custom::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 2px;
|
|
left: 6px;
|
|
width: 5px;
|
|
height: 10px;
|
|
border: solid var(--text-on-accent, #ffffff);
|
|
border-width: 0 2px 2px 0;
|
|
transform: rotate(45deg);
|
|
opacity: 0;
|
|
transition: opacity 0.15s ease;
|
|
}
|
|
|
|
.toggle-section .checkbox-label input[type="checkbox"]:hover + .checkbox-custom,
|
|
.advanced-toggle-field .checkbox-label input[type="checkbox"]:hover + .checkbox-custom {
|
|
border-color: var(--accent);
|
|
box-shadow: none;
|
|
}
|
|
|
|
.toggle-section .checkbox-label input[type="checkbox"]:checked + .checkbox-custom,
|
|
.advanced-toggle-field .checkbox-label input[type="checkbox"]:checked + .checkbox-custom {
|
|
background: var(--accent);
|
|
border-color: var(--accent);
|
|
}
|
|
|
|
.toggle-section .checkbox-label input[type="checkbox"]:checked + .checkbox-custom::after,
|
|
.advanced-toggle-field .checkbox-label input[type="checkbox"]:checked + .checkbox-custom::after {
|
|
opacity: 1;
|
|
}
|
|
|
|
.checkbox-text {
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
color: var(--text-primary);
|
|
line-height: 1.4;
|
|
user-select: none;
|
|
}
|
|
|
|
.group-fields .form-field {
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.group-fields .form-field:last-child {
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.app-config .form-field {
|
|
margin-bottom: 16px;
|
|
}
|
|
|
|
.app-config .form-label {
|
|
display: block;
|
|
margin-bottom: 6px;
|
|
font-weight: 500;
|
|
color: var(--text-color);
|
|
font-size: 14px;
|
|
}
|
|
|
|
/* App-config inputs share the .form-control recipe used by the standard
|
|
config page — translucent theme-aware border + glass fill — so app
|
|
config fields stop reading as a near-black slab against the nebula
|
|
gradient. */
|
|
.app-config .form-input,
|
|
.app-config .form-select,
|
|
.app-config .config-input,
|
|
.config-input {
|
|
width: 100%;
|
|
padding: 10px 12px;
|
|
border: 1px solid rgba(var(--text-rgb), 0.20);
|
|
border-radius: 8px;
|
|
background: rgba(var(--text-rgb), 0.05);
|
|
color: var(--text-primary, #fff);
|
|
font-size: 14px;
|
|
font-family: inherit;
|
|
transition: border-color 0.2s ease, background 0.2s ease;
|
|
}
|
|
|
|
.app-config .form-input:focus,
|
|
.app-config .form-select:focus,
|
|
.app-config .config-input:focus,
|
|
.config-input:focus {
|
|
outline: none;
|
|
border-color: var(--accent);
|
|
background: rgba(var(--text-rgb), 0.08);
|
|
}
|
|
|
|
.app-config .form-input::placeholder,
|
|
.app-config .config-input::placeholder,
|
|
.config-input::placeholder {
|
|
color: var(--text-secondary, #ccc);
|
|
opacity: 0.7;
|
|
}
|
|
|
|
.app-config .form-help {
|
|
display: block;
|
|
margin-top: 4px;
|
|
font-size: 12px;
|
|
color: var(--text-muted);
|
|
line-height: 1.4;
|
|
}
|
|
|
|
/* App Config Checkboxes - EXACT copy of global toggle switch styling */
|
|
.app-config .checkbox-label {
|
|
display: flex;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
padding: 4px;
|
|
border-radius: 6px;
|
|
transition: all 0.2s ease;
|
|
background: #0000;
|
|
border: 1px solid transparent;
|
|
}
|
|
|
|
.app-config .checkbox-label:hover {
|
|
/* background: rgba(var(--text-rgb),0.05); */
|
|
}
|
|
|
|
.app-config .checkbox-label.disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
background: transparent;
|
|
border-color: var(--border-color);
|
|
}
|
|
|
|
.app-config .checkbox-label.disabled .checkbox-custom {
|
|
background: var(--hover-bg);
|
|
border-color: var(--border-color);
|
|
}
|
|
|
|
.app-config .checkbox-label.disabled .checkbox-text {
|
|
color: var(--text-secondary, #ccc);
|
|
}
|
|
|
|
.app-config .checkbox-label:hover .checkbox-text {
|
|
color: var(--text-primary);
|
|
}
|
|
|
|
.app-config .checkbox-text {
|
|
font-size: 14px;
|
|
font-weight: 500;
|
|
color: var(--text-primary);
|
|
line-height: 1.4;
|
|
user-select: none;
|
|
}
|
|
|
|
.app-config .checkbox-label input[type="checkbox"] {
|
|
display: none !important;
|
|
opacity: 0 !important;
|
|
position: absolute !important;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.app-config .checkbox-custom {
|
|
position: relative;
|
|
width: 48px;
|
|
height: 24px;
|
|
background: var(--border-strong);
|
|
border-radius: 24px;
|
|
margin-right: 12px;
|
|
transition: all 0.3s ease;
|
|
cursor: pointer;
|
|
border: none;
|
|
}
|
|
|
|
.app-config .checkbox-custom::before {
|
|
content: '';
|
|
position: absolute;
|
|
top: 2px;
|
|
left: 2px;
|
|
width: 20px;
|
|
height: 20px;
|
|
background: white;
|
|
border-radius: 50%;
|
|
transition: all 0.3s ease;
|
|
}
|
|
|
|
.app-config .checkbox-label input[type="checkbox"]:hover + .checkbox-custom {
|
|
}
|
|
|
|
.app-config .checkbox-label input[type="checkbox"]:checked + .checkbox-custom {
|
|
background: var(--primary-color);
|
|
border-color: var(--primary-color);
|
|
}
|
|
|
|
.app-config .checkbox-label input[type="checkbox"]:checked + .checkbox-custom::before {
|
|
transform: translateX(24px);
|
|
}
|
|
|
|
/* Field Group Styling for Domain Blocks */
|
|
.domain-building-block .field-group {
|
|
margin: 0;
|
|
width: 100%;
|
|
display: flex;
|
|
flex-direction: column;
|
|
}
|
|
|
|
.domain-building-block .field-label {
|
|
display: block;
|
|
margin-bottom: 6px;
|
|
font-weight: 500;
|
|
color: var(--text-color);
|
|
font-size: 14px;
|
|
}
|
|
|
|
.domain-building-block .form-control {
|
|
width: 100%;
|
|
padding: 8px 12px;
|
|
border: 1px solid var(--border-color);
|
|
border-radius: 4px;
|
|
background: var(--input-bg);
|
|
color: var(--text-color);
|
|
font-size: 14px;
|
|
transition: border-color 0.3s ease;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.domain-building-block .form-control:focus {
|
|
outline: none;
|
|
border-color: var(--primary-color, var(--accent));
|
|
box-shadow: 0 0 0 2px rgba(var(--accent-rgb), 0.25);
|
|
}
|
|
|
|
/* Toggle-specific spacing */
|
|
.checkbox-label.master-toggle {
|
|
padding: 20px;
|
|
}
|
|
|
|
/* Enhanced field styling */
|
|
.form-field {
|
|
position: relative;
|
|
}
|
|
|
|
.form-label {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 6px;
|
|
font-weight: 500;
|
|
margin-bottom: 6px;
|
|
}
|
|
|
|
.required {
|
|
color: var(--error-color);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.help-icon {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
width: 16px;
|
|
height: 16px;
|
|
background: var(--primary-color);
|
|
color: var(--text-primary);
|
|
border-radius: 50%;
|
|
font-size: 10px;
|
|
font-weight: bold;
|
|
cursor: help;
|
|
margin-left: 4px;
|
|
}
|
|
|
|
.form-help {
|
|
display: block;
|
|
margin-top: 4px;
|
|
font-size: 11px;
|
|
color: var(--text-secondary);
|
|
font-style: italic;
|
|
}
|
|
|
|
/* "Show Advanced / Show Unused" UI-preference wrapper. Glass card that
|
|
reads on every theme — replaces an older recipe that hardcoded
|
|
var(--surface-bg-solid) (solid dark navy on nebula) plus a near-white
|
|
#f9f9f9 hover, which made the label invisible on dark themes. */
|
|
.toggle-section .checkbox-label {
|
|
display: flex;
|
|
align-items: flex-start;
|
|
cursor: pointer;
|
|
width: 100%;
|
|
padding: 14px 16px;
|
|
background: rgba(var(--text-rgb), 0.05);
|
|
border: 1px solid rgba(var(--text-rgb), 0.10);
|
|
border-radius: 10px;
|
|
box-shadow: inset 0 1px 0 rgba(var(--text-rgb), 0.04);
|
|
transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
|
|
}
|
|
|
|
.toggle-section .checkbox-label:hover {
|
|
background: rgba(var(--text-rgb), 0.08);
|
|
border-color: rgba(var(--accent-rgb), 0.40);
|
|
box-shadow: inset 0 1px 0 rgba(var(--text-rgb), 0.06);
|
|
}
|
|
|
|
/* .toggle-section .checkbox-custom intentionally NOT redefined here.
|
|
The shared tickbox styling earlier in this file already scopes the
|
|
square-check visual to .toggle-section, so adding another rule here
|
|
would just override it. */
|
|
|
|
.toggle-section .checkbox-text {
|
|
font-weight: 600;
|
|
color: var(--text-primary);
|
|
font-size: 16px;
|
|
margin-bottom: 4px;
|
|
}
|
|
|
|
.toggle-section .checkbox-description {
|
|
font-size: 13px;
|
|
color: var(--text-secondary);
|
|
line-height: 1.4;
|
|
}
|
|
|
|
/* Red-flash highlight for required-but-empty fields when the user clicks
|
|
Install. Cleared on the next input/change. Native title attribute on the
|
|
element provides the "Required" tooltip on hover. */
|
|
.field-required-error {
|
|
border: 1.5px solid var(--status-danger) !important;
|
|
box-shadow: 0 0 0 3px rgba(var(--status-danger-rgb), 0.20);
|
|
animation: requiredFlash 0.6s ease-in-out 2;
|
|
background: rgba(var(--status-danger-rgb), 0.06) !important;
|
|
}
|
|
|
|
/* ============================================================
|
|
Custom <select> component (js/system/custom-select.js).
|
|
|
|
Native <select> popups are drawn by the OS and ignore CSS for the
|
|
popup chrome. This component visually replaces the native select
|
|
while keeping it in the DOM for form submission / change events.
|
|
============================================================ */
|
|
.custom-select {
|
|
position: relative;
|
|
width: 100%;
|
|
display: inline-block;
|
|
}
|
|
|
|
/* The native <select> stays in the DOM (so forms submit + JS reading
|
|
.value continues to work) but is hidden behind the styled button. */
|
|
.custom-select-native {
|
|
position: absolute;
|
|
inset: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
opacity: 0;
|
|
pointer-events: none;
|
|
z-index: -1;
|
|
}
|
|
|
|
.custom-select-button {
|
|
width: 100%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
gap: 12px;
|
|
padding: 12px 16px;
|
|
background: rgba(var(--text-rgb), 0.06);
|
|
border: 1px solid rgba(var(--text-rgb), 0.20);
|
|
border-radius: 8px;
|
|
color: var(--text-primary);
|
|
font-size: 14px;
|
|
font-family: inherit;
|
|
text-align: left;
|
|
cursor: pointer;
|
|
transition: background 0.18s ease, border-color 0.18s ease, box-shadow 0.18s ease;
|
|
}
|
|
|
|
.custom-select-button:hover:not(:disabled) {
|
|
border-color: rgba(var(--accent-rgb), 0.40);
|
|
}
|
|
|
|
.custom-select-button:disabled {
|
|
opacity: 0.6;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
.custom-select.is-open .custom-select-button {
|
|
border-color: var(--accent);
|
|
background: rgba(var(--text-rgb), 0.10);
|
|
box-shadow: 0 0 0 3px rgba(var(--accent-rgb), 0.20);
|
|
}
|
|
|
|
.custom-select-label {
|
|
flex: 1;
|
|
text-align: left;
|
|
overflow: hidden;
|
|
text-overflow: ellipsis;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.custom-select-arrow {
|
|
display: inline-flex;
|
|
flex-shrink: 0;
|
|
color: rgba(var(--text-rgb), 0.70);
|
|
transition: transform 0.18s ease;
|
|
}
|
|
|
|
.custom-select.is-open .custom-select-arrow {
|
|
transform: rotate(180deg);
|
|
color: var(--accent);
|
|
}
|
|
|
|
/* Popup — fixed-positioned (top/left/width set by JS in
|
|
custom-select.js > positionPopup) so the dropdown escapes any
|
|
ancestor with overflow: hidden, e.g. .eo-modal-content. z-index
|
|
is above eo-modal (1100) so it floats over modals too. */
|
|
.custom-select-popup {
|
|
position: fixed;
|
|
z-index: 1200;
|
|
max-height: 280px;
|
|
overflow-y: auto;
|
|
padding: 6px;
|
|
background: var(--surface-bg-solid, var(--bg-primary));
|
|
border: 1px solid rgba(var(--text-rgb), 0.16);
|
|
border-radius: 10px;
|
|
box-shadow: 0 12px 32px rgba(0, 0, 0, 0.35), inset 0 1px 0 rgba(var(--text-rgb), 0.06);
|
|
backdrop-filter: blur(14px) saturate(140%);
|
|
-webkit-backdrop-filter: blur(14px) saturate(140%);
|
|
animation: customSelectIn 0.12s ease-out;
|
|
}
|
|
|
|
.custom-select-popup.flip-up {
|
|
transform-origin: bottom center;
|
|
}
|
|
|
|
@keyframes customSelectIn {
|
|
from { opacity: 0; transform: translateY(-4px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
.custom-select-popup.flip-up {
|
|
animation-name: customSelectInUp;
|
|
}
|
|
|
|
@keyframes customSelectInUp {
|
|
from { opacity: 0; transform: translateY(4px); }
|
|
to { opacity: 1; transform: translateY(0); }
|
|
}
|
|
|
|
.custom-select-option {
|
|
padding: 9px 12px;
|
|
border-radius: 6px;
|
|
cursor: pointer;
|
|
color: var(--text-primary);
|
|
font-size: 14px;
|
|
line-height: 1.3;
|
|
user-select: none;
|
|
transition: background 0.12s ease, color 0.12s ease;
|
|
position: relative;
|
|
}
|
|
|
|
.custom-select-option:hover,
|
|
.custom-select-option.is-focused {
|
|
background: rgba(var(--accent-rgb), 0.15);
|
|
color: var(--accent);
|
|
}
|
|
|
|
.custom-select-option.is-selected {
|
|
background: rgba(var(--accent-rgb), 0.22);
|
|
color: var(--accent);
|
|
font-weight: 600;
|
|
}
|
|
|
|
.custom-select-option.is-selected::after {
|
|
content: '';
|
|
position: absolute;
|
|
top: 50%;
|
|
right: 12px;
|
|
width: 4px;
|
|
height: 8px;
|
|
margin-top: -6px;
|
|
border: solid var(--accent);
|
|
border-width: 0 2px 2px 0;
|
|
transform: rotate(45deg);
|
|
}
|
|
|
|
.custom-select-option.is-disabled {
|
|
opacity: 0.4;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* Themed scrollbar for the popup. */
|
|
.custom-select-popup::-webkit-scrollbar {
|
|
width: 8px;
|
|
}
|
|
.custom-select-popup::-webkit-scrollbar-track {
|
|
background: transparent;
|
|
}
|
|
.custom-select-popup::-webkit-scrollbar-thumb {
|
|
background: rgba(var(--text-rgb), 0.20);
|
|
border-radius: 4px;
|
|
}
|
|
.custom-select-popup::-webkit-scrollbar-thumb:hover {
|
|
background: rgba(var(--accent-rgb), 0.40);
|
|
}
|
|
|
|
/* ============================================================
|
|
Custom number stepper (js/system/custom-number.js).
|
|
|
|
Replaces the OS spin-buttons on <input type="number"> with themed
|
|
up/down chevrons that read consistently across browsers/themes.
|
|
============================================================ */
|
|
|
|
/* Hide native browser spin buttons. */
|
|
.custom-number-input::-webkit-outer-spin-button,
|
|
.custom-number-input::-webkit-inner-spin-button {
|
|
-webkit-appearance: none;
|
|
margin: 0;
|
|
}
|
|
.custom-number-input {
|
|
-moz-appearance: textfield;
|
|
}
|
|
|
|
.custom-number {
|
|
position: relative;
|
|
display: inline-flex;
|
|
width: 100%;
|
|
align-items: stretch;
|
|
}
|
|
|
|
/* The input itself stretches to fill, leaving room for the controls. */
|
|
.custom-number .custom-number-input {
|
|
flex: 1;
|
|
min-width: 0;
|
|
padding-right: 36px;
|
|
}
|
|
|
|
.custom-number.is-disabled {
|
|
opacity: 0.6;
|
|
}
|
|
|
|
.custom-number-controls {
|
|
position: absolute;
|
|
top: 4px;
|
|
right: 4px;
|
|
bottom: 4px;
|
|
display: flex;
|
|
flex-direction: column;
|
|
width: 24px;
|
|
border-radius: 6px;
|
|
overflow: hidden;
|
|
background: rgba(var(--text-rgb), 0.05);
|
|
}
|
|
|
|
.custom-number-btn {
|
|
flex: 1;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
background: transparent;
|
|
border: none;
|
|
color: rgba(var(--text-rgb), 0.65);
|
|
cursor: pointer;
|
|
padding: 0;
|
|
margin: 0;
|
|
transition: background 0.12s ease, color 0.12s ease;
|
|
}
|
|
|
|
.custom-number-btn:hover:not(:disabled) {
|
|
background: rgba(var(--accent-rgb), 0.20);
|
|
color: var(--accent);
|
|
}
|
|
|
|
.custom-number-btn:active:not(:disabled) {
|
|
background: rgba(var(--accent-rgb), 0.35);
|
|
}
|
|
|
|
.custom-number-btn:disabled,
|
|
.custom-number-btn.is-disabled {
|
|
opacity: 0.30;
|
|
cursor: not-allowed;
|
|
}
|
|
|
|
/* Subtle divider between up/down. */
|
|
.custom-number-up {
|
|
border-bottom: 1px solid rgba(var(--text-rgb), 0.08);
|
|
}
|