mirror of
https://github.com/wekan/wekan.git
synced 2026-11-08 03:22:32 -05:00
The accessibility audit made the quiet text greys dark for every theme, and old rules never followed the dark themes: Card Settings drew white text on light grey blocks, popup items, the sidebar's shortcuts row, quiet buttons and sidebar labels were black on dark, and an !important list header beat each theme's own. The quiet text is a variable with a light value on the dark surfaces; Card Settings' sections, popup items and the other rules follow the theme. axe-core finds no colour contrast failure in cleandark, moderndark, dark and exodark on the board, sidebar, Card Settings, an opened card and the custom fields popup. Thanks to Samunosuke and xet7 ! Fixes #6863,
1022 lines
42 KiB
CSS
1022 lines
42 KiB
CSS
.flex,
|
|
.setting-content .content-body .side-menu ul li a,
|
|
.option {
|
|
display: -webkit-box;
|
|
display: -moz-box;
|
|
display: -webkit-flex;
|
|
display: -moz-flex;
|
|
display: -ms-flexbox;
|
|
display: flex;
|
|
height: 100%;
|
|
}
|
|
.setting-content {
|
|
color: var(--wekan-quiet-text, #5a5c61);
|
|
background: #dedede;
|
|
width: 100%;
|
|
height: 100%;
|
|
position: absolute;
|
|
}.setting-content .content-body {
|
|
display: flex;
|
|
/* Always keep the menu (left) and content (right) side by side, even on
|
|
narrow windows. The side menu has a fixed basis and the main body fills
|
|
the rest, so both stay visible without switching to a stacked layout. */
|
|
flex-direction: row;
|
|
flex-wrap: nowrap;
|
|
/* No padding above the ROW: it put grey between the header and the top of the
|
|
side menu, and the menu is meant to run from directly under the header to
|
|
the bottom of the window. The main body keeps its breathing room below -
|
|
see `.main-body` - because that IS content and content is not flush to a
|
|
bar. docs/Features/All-Boards/Left-Menu.md */
|
|
padding-top: 0;
|
|
height: 100%;
|
|
gap: 18px;
|
|
/* The width grip is positioned against this ROW rather than against the menu:
|
|
the menu is its own scroll area, and a handle inside it would scroll away
|
|
with the entries. docs/Features/All-Boards/Left-Menu.md */
|
|
position: relative;
|
|
}
|
|
|
|
/* ── How wide the left menu is ───────────────────────────────────────────────
|
|
ONE number, read by everything that needs it: the Admin Panel's menu, the All
|
|
Boards one (boardsList.css), and the grip that changes it, which has to sit
|
|
exactly on the menu's inner edge.
|
|
A reader who drags the grip gets it as an inline property on <html>, which
|
|
beats every rule here - so the declarations below are DEFAULTS, and the
|
|
breakpoints that want a different default (layouts.css) override the variable
|
|
instead of the width, or a dragged width would be overridden right back.
|
|
docs/Features/All-Boards/Left-Menu.md */
|
|
:root {
|
|
--wekan-left-menu-width: 260px;
|
|
}
|
|
.setting-content .content-body .side-menu {
|
|
background-color: #f7f7f7;
|
|
/* Flush on three sides - it starts at the window's left edge, directly under
|
|
the header, and runs to the bottom - so it has a border and a corner only
|
|
on the side that faces the page. A rounded corner on a flush edge shows the
|
|
grey behind it, which is exactly the gap this removes. */
|
|
border: 1px solid #f0f0f0;
|
|
border-inline-start: 0;
|
|
border-top: 0;
|
|
border-bottom: 0;
|
|
border-radius: 0;
|
|
/* The shared width above, so this menu and the All Boards one are one menu at
|
|
one width - and so dragging either changes both. It replaces a
|
|
`min(250px, 32vw)` that only ever resolved to 250px above the 800px
|
|
breakpoint, below which the menu is full width anyway. */
|
|
width: var(--wekan-left-menu-width);
|
|
/* Never let the menu be squeezed away on narrow windows; keep it visible. */
|
|
flex: 0 0 auto;
|
|
/* No X offset: an inset shadow offset sideways is a PHYSICAL direction and does
|
|
not mirror under dir=rtl, so it shaded the wrong inner edge once the menu moved
|
|
to the right. See docs/Features/All-Boards/Left-Menu.md. */
|
|
box-shadow: inset 0 -2px 4px rgba(0,0,0,0.05);
|
|
/* A long menu SCROLLS inside the panel instead of spilling out of it.
|
|
The menu is a flex item stretched to the row's height, so its box - and with it
|
|
its background, border and rounded corners - stops at the bottom of the page.
|
|
With the default `overflow: visible` the entries kept rendering past that edge,
|
|
which is why Admin Panel / Problems, the longest menu, showed its last four
|
|
entries sitting on the page's grey with no panel behind them.
|
|
min-height:0 because a flex item will not shrink below its content otherwise, and
|
|
an overflow that never engages leaves the spill exactly as it was. */
|
|
overflow-y: auto;
|
|
min-height: 0;
|
|
}
|
|
.setting-content .content-body .side-menu ul li {
|
|
margin: 2px 4px;
|
|
}
|
|
.setting-content .content-body .side-menu ul li.active {
|
|
box-shadow: 0 2px 3px rgba(0,0,0,0.15);
|
|
}
|
|
/* The entry you are on is filled with the theme colour and its label and icon go
|
|
white - the same treatment the selected tab gets in the Admin Panel bar above
|
|
(settingHeader.css: `.setting-header-btn.active`, white text on the header's own
|
|
colour). One selected-thing look in both places.
|
|
The colour is the per-user theme accent (Member Settings -> Change color sets
|
|
--theme-accent on :root); the fallback is the WeKan header blue, so with no chosen
|
|
colour the menu matches the bar exactly. See docs/Features/All-Boards/Left-Menu.md.
|
|
`:hover` is listed too: `li:hover` below sets a white background at the SAME
|
|
specificity as `li.active`, and being later in the file it would otherwise wash the
|
|
selected entry back to white as soon as the pointer crossed it. */
|
|
.setting-content .content-body .side-menu ul li.active,
|
|
.setting-content .content-body .side-menu ul li.active:hover {
|
|
background: var(--theme-accent, #2573a7);
|
|
}
|
|
|
|
/* …and when a THEME is active, the row is painted by that theme's own #header rule
|
|
instead (boardColors.css names this selector in every theme's header rule), so the
|
|
selected row and the second header bar are the same colour - and the same colour
|
|
SLIDE, for a theme like clearblue whose bar is a gradient. The rule above stays as
|
|
the answer for an instance with no theme at all. */
|
|
.setting-content .content-body .side-menu ul li.active > a,
|
|
.setting-content .content-body .side-menu ul li.active > a i {
|
|
/* Not `inherit`: that is what made the selected entry the same grey as every
|
|
unselected one, on a background that is now dark. */
|
|
color: #fff;
|
|
}
|
|
.setting-content .content-body .side-menu ul li:hover {
|
|
background: #fff;
|
|
box-shadow: 0 2px 3px rgba(0,0,0,0.15);
|
|
}
|
|
/* Two rows that are NOT entries: the rule between groups, and the title above a
|
|
group. Neither is clickable, so both opt out of the hover treatment below -
|
|
`li:hover` would otherwise light them up like a row you can open. The heading
|
|
is quieter and smaller than an entry: it names the group, it is not one of them.
|
|
(The Problems page used to style its separator from adminProblems.css with a
|
|
class the shared menu does not render, so the rule never applied at all.) */
|
|
/* No list bullets. In the column they fell outside the menu's edge and were
|
|
hidden; in the phone's wrapping row they showed as a dot after every entry. */
|
|
.setting-content .content-body .side-menu ul {
|
|
list-style: none;
|
|
}
|
|
.setting-content .content-body .side-menu ul li.left-menu-separator {
|
|
margin: 6px 4px;
|
|
}
|
|
.setting-content .content-body .side-menu ul li.left-menu-separator hr {
|
|
margin: 0;
|
|
border: 0;
|
|
border-top: 1px solid rgba(0, 0, 0, 0.15);
|
|
}
|
|
.setting-content .content-body .side-menu ul li.left-menu-heading {
|
|
padding-block: 8px 4px;
|
|
padding-inline-start: 18px;
|
|
font-size: calc(12px * var(--wekan-ui-font-scale, 1));
|
|
font-weight: 700;
|
|
text-transform: uppercase;
|
|
letter-spacing: 0.04em;
|
|
opacity: 0.6;
|
|
cursor: default;
|
|
}
|
|
.setting-content .content-body .side-menu ul li.left-menu-separator:hover,
|
|
.setting-content .content-body .side-menu ul li.left-menu-heading:hover {
|
|
background: transparent;
|
|
box-shadow: none;
|
|
}
|
|
|
|
.setting-content .content-body .side-menu ul li a {
|
|
/* Logical, so the indent follows the reading direction instead of staying on
|
|
the left when the menu mirrors to the right. */
|
|
padding-block: 12px;
|
|
padding-inline-start: 18px;
|
|
padding-inline-end: 0;
|
|
width: 95%;
|
|
}
|
|
.setting-content .content-body .side-menu ul li a span {
|
|
font-size: calc(13px * var(--wekan-ui-font-scale, 1));
|
|
}
|
|
.setting-content .content-body .side-menu ul li a i {
|
|
margin-inline-end: 20px;
|
|
}
|
|
.setting-content .content-body .main-body {
|
|
/* The row lost its top padding so the side menu can start under the header;
|
|
the content keeps it, because content is not meant to be flush against a
|
|
bar. */
|
|
padding-block-start: 18px;
|
|
-webkit-user-select: text;
|
|
-moz-user-select: text;
|
|
-ms-user-select: text;
|
|
user-select: text;
|
|
max-height: 100%;
|
|
/* auto, not scroll: a page whose content fits - which every shared table page now
|
|
does - showed a horizontal scrollbar with nothing to scroll to. The wide admin
|
|
tables (GridFS stats, Version, Translation) still get one when they need it, and
|
|
scrollbar-gutter keeps the layout from jumping as it appears. */
|
|
overflow-x: auto !important;
|
|
overflow-y: scroll !important;
|
|
scrollbar-gutter: stable;
|
|
/* Grow into the space left next to the side menu. flex-basis MUST be 0 here: this
|
|
element can hold a min-width:1200px table, so a content-based (auto) basis is
|
|
huge and, as an overflow flex item, resolves unpredictably (collapsing the
|
|
panel). Basis 0 + grow makes the width = container - side menu,
|
|
deterministically. min-width:0 lets it shrink so the side menu is never pushed
|
|
out on narrow windows. */
|
|
flex: 1 1 0;
|
|
min-width: 0;
|
|
}
|
|
|
|
/* Ensure scrollbars are always visible with proper styling for all admin pages */
|
|
.setting-content .content-body .main-body::-webkit-scrollbar {
|
|
width: 12px;
|
|
height: 12px;
|
|
display: block !important;
|
|
visibility: visible !important;
|
|
}
|
|
|
|
.setting-content .content-body .main-body::-webkit-scrollbar-track {
|
|
background: #f1f1f1;
|
|
border-radius: 6px;
|
|
display: block !important;
|
|
visibility: visible !important;
|
|
}
|
|
|
|
.setting-content .content-body .main-body::-webkit-scrollbar-thumb {
|
|
background: #888;
|
|
border-radius: 6px;
|
|
display: block !important;
|
|
visibility: visible !important;
|
|
}
|
|
|
|
.setting-content .content-body .main-body::-webkit-scrollbar-thumb:hover {
|
|
background: #555;
|
|
}
|
|
|
|
.setting-content .content-body .main-body::-webkit-scrollbar-corner {
|
|
background: #f1f1f1;
|
|
}
|
|
|
|
/* NO admin table is forced wider than the panel any more.
|
|
|
|
These rules used to be the opposite: `min-width: 1200px !important` with
|
|
`width: max-content` and nowrap cells, to GUARANTEE a horizontal scrollbar for
|
|
the wide data tables. What that guaranteed in practice was a table whose right
|
|
part is off screen - reported on Domains, and just as true on Admin Panel /
|
|
Version, a two-column table where "WeKan ® Version" and its value sat ~1000px
|
|
apart with the value cut off at the window edge. A 1200px floor is not a
|
|
property of the DATA; it was a property of the browser window someone had open.
|
|
The phone-width exception that used to undo it (at ≤ 800px) is now simply the
|
|
rule at every width.
|
|
|
|
So: fit the panel, wrap the text, and let a genuinely wide table scroll inside
|
|
`.main-body`, which keeps `overflow-x: auto` for exactly that. The shared table
|
|
page (docs/Features/General/Table-Page.md) already does this for itself - width:100% +
|
|
table-layout:fixed with equal, wrapping columns - and is excluded so its equal
|
|
columns are not turned back into content-sized ones. */
|
|
.setting-content .content-body .main-body table:not(.table-page-table) {
|
|
width: 100%;
|
|
max-width: 100%;
|
|
table-layout: auto;
|
|
}
|
|
|
|
/* Long unbroken values - version strings, paths, URLs, ids - break inside their
|
|
cell instead of widening the column and pushing the table off screen again. */
|
|
.setting-content .content-body .main-body table:not(.table-page-table) td,
|
|
.setting-content .content-body .main-body table:not(.table-page-table) th {
|
|
white-space: normal;
|
|
overflow-wrap: anywhere;
|
|
word-break: break-word;
|
|
}
|
|
|
|
/* #6465: headers may wrap — nowrap on long header labels (e.g. the org/team
|
|
feature columns) blew the column widths up to the whole label length. */
|
|
.setting-content .content-body .main-body table:not(.table-page-table) th {
|
|
max-width: 240px;
|
|
}
|
|
|
|
/* Ensure there's enough content to trigger vertical scrolling */
|
|
.setting-content .content-body .main-body {
|
|
min-height: calc(100vh - 200px);
|
|
padding-bottom: 50px;
|
|
}
|
|
|
|
/* Folded: the menu is GONE, not narrowed - no column and no strip - and the pane
|
|
beside it takes the whole width. See boardsList.css for the All Boards twin:
|
|
the two menus fold the same way because they are one menu. The way back is the
|
|
caret on the pane title below. */
|
|
.setting-content .content-body .side-menu.collapsed {
|
|
display: none;
|
|
}
|
|
|
|
/* ── The caret that folds the left menu ──────────────────────────────────────
|
|
The same control a LIST has on a board: pointing DOWN while the menu is open
|
|
and RIGHT once it is folded. It is the collapse gesture WeKan already has, so
|
|
there is nothing new to learn.
|
|
It is styled here rather than beside one page's menu because it appears on
|
|
both pages and, folded, in a third place: the pane title.
|
|
docs/Features/All-Boards/Left-Menu.md */
|
|
.left-menu-collapse-indicator {
|
|
display: flex;
|
|
align-items: center;
|
|
/* The rows' own inline start, so the caret sits on the line the row icons
|
|
start on rather than hanging to their left. */
|
|
padding: 6px 10px 6px 18px;
|
|
color: inherit;
|
|
text-decoration: none;
|
|
cursor: pointer;
|
|
opacity: 0.7;
|
|
}
|
|
.left-menu-collapse-indicator:hover {
|
|
opacity: 1;
|
|
}
|
|
|
|
/* Folded, the caret rides at the inline start of the PANE TITLE and the two are
|
|
one target - the heading itself is what brings the menu back, so it is as easy
|
|
to hit as the menu was wide. It keeps the heading's own size and weight: it IS
|
|
the heading, with a caret in front of it, not a control that happens to sit
|
|
near one. The padding the caret carries inside the menu would push the title
|
|
off the line every other pane's title starts on, so it goes. */
|
|
.admin-pane-title-folded > .left-menu-collapse-indicator {
|
|
display: inline-flex;
|
|
gap: 8px;
|
|
padding: 0;
|
|
font: inherit;
|
|
color: inherit;
|
|
opacity: 1;
|
|
}
|
|
.admin-pane-title-folded > .left-menu-collapse-indicator:hover .left-menu-collapse-title {
|
|
text-decoration: underline;
|
|
}
|
|
/* Keyboard focus has to be visible: the caret is an anchor with no href, which
|
|
the browser would otherwise leave with no ring of its own. */
|
|
.left-menu-collapse-indicator:focus-visible {
|
|
outline: 2px solid currentColor;
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* ── The grip that changes the menu's width ──────────────────────────────────
|
|
The same control the right board sidebar has on its own inner edge
|
|
(sidebar.css): a 6px strip straddling the edge, invisible until pointed at,
|
|
dragged to resize.
|
|
It sits on the menu's INNER edge - `inset-inline-start`, so under a
|
|
right-to-left language, where the whole row is mirrored and the menu is on
|
|
the right, the grip mirrors with it and needs no second rule.
|
|
It is positioned against the row/grid around the menu rather than inside the
|
|
menu, because the menu scrolls its own entries and a handle within it would
|
|
scroll away with them. Being absolutely positioned, it is neither a flex item
|
|
nor a grid item: it adds no column and no gap.
|
|
docs/Features/All-Boards/Left-Menu.md */
|
|
.left-menu-resize-handle {
|
|
position: absolute;
|
|
top: 0;
|
|
bottom: 0;
|
|
inset-inline-start: calc(var(--wekan-left-menu-width) - 3px);
|
|
width: 6px;
|
|
cursor: col-resize;
|
|
z-index: 10;
|
|
background: transparent;
|
|
transition: background-color 0.2s ease;
|
|
}
|
|
.left-menu-resize-handle:hover {
|
|
background: rgba(0, 123, 255, 0.4);
|
|
box-shadow: 0 0 4px rgba(0, 123, 255, 0.3);
|
|
}
|
|
.left-menu-resize-handle:active {
|
|
background: rgba(0, 123, 255, 0.6);
|
|
box-shadow: 0 0 6px rgba(0, 123, 255, 0.4);
|
|
}
|
|
/* Folded there is no edge to drag, and on a phone the menu is full width above
|
|
the content, so a width would mean nothing there either. `.collapsed` is on
|
|
the menu in the Admin Panel and on the grid on All Boards - see the folding
|
|
rules above - so both are named. */
|
|
.side-menu.collapsed ~ .left-menu-resize-handle,
|
|
.boards-layout.collapsed > .left-menu-resize-handle {
|
|
display: none;
|
|
}
|
|
@media screen and (max-width: 800px) {
|
|
.left-menu-resize-handle {
|
|
display: none;
|
|
}
|
|
}
|
|
/* While dragging, the whole page shows the resize cursor and stops selecting
|
|
text - otherwise the drag selects every label it passes over. The same pair
|
|
`body.sidebar-resizing-active` uses for the right sidebar. */
|
|
body.left-menu-resizing-active {
|
|
user-select: none;
|
|
cursor: col-resize;
|
|
}
|
|
|
|
/* The pane title: ONE size and weight for the heading at the top of every Admin
|
|
Panel pane, whether that pane is a shared table page (Domains, People, the
|
|
Problems reports - their h1 carries this class too, see tablePage.jade) or a form
|
|
(Login, Announcement, Accessibility, PWA). Before this, only the table pages had a
|
|
title at all, so half the panes opened with no heading and the other half with an
|
|
unstyled browser-default h1 twice the size of anything around it.
|
|
Sized in rem so it follows the user's browser font size, and `color: inherit` so
|
|
it stays readable on a dark theme. */
|
|
.admin-pane-title {
|
|
margin: 0;
|
|
font-size: 1.25rem;
|
|
font-weight: 700;
|
|
line-height: 1.3;
|
|
color: inherit;
|
|
}
|
|
|
|
/* A pane that is not a table page has no row gap of its own, so the heading brings
|
|
its own space below it. The shared table page is a flex column with a 12px gap,
|
|
which is why the rule is scoped to a title that IS the direct child. */
|
|
.setting-content .content-body .main-body > .admin-pane-title {
|
|
margin-bottom: 12px;
|
|
}
|
|
|
|
/* ── Checkboxes ──────────────────────────────────────────────────────────────
|
|
ONE checkbox for the whole Admin Panel: the same one the rest of WeKan draws
|
|
(`.materialCheckBox`, forms.css), which is what Admin Panel / Settings /
|
|
Announcement shows for "Active System-Wide Announcement".
|
|
|
|
Two problems this fixes at once.
|
|
|
|
1. Some panes - the storage Read toggles, the Organizations and Teams feature
|
|
columns, the Backup checkboxes, Attachments / Limits / Avatars, the Problems
|
|
summary - use a NATIVE <input type="checkbox">. forms.css hides every native
|
|
checkbox app-wide (WeKan draws its own), so those either did not show at all,
|
|
or were re-enabled pane by pane and then drawn by the BROWSER: on Ubuntu a big
|
|
orange box, which has nothing to do with the chosen theme (it was orange even
|
|
under clearblue) and matched nothing else on the page.
|
|
2. Each pane that re-enabled them picked its own size, so no two agreed.
|
|
|
|
The declarations below are `.materialCheckBox` and `.materialCheckBox.is-checked`
|
|
applied to the input itself - the SAME grey square when unchecked, the SAME morph
|
|
into a green tick when checked, and the same `transition: 0.2s` that animates
|
|
between them. Not a tick drawn over the box with a pseudo-element: that gets the
|
|
checked state right and loses both the unchecked square and the animation.
|
|
|
|
`appearance: none` is the one addition, to take the browser's own rendering out
|
|
of it. If these panes ever move to the `.materialCheckBox` markup, this whole
|
|
block can go. */
|
|
.setting-content input[type="checkbox"] {
|
|
/* Beat the app-wide "hide the native checkbox" rule for the Admin Panel only.
|
|
* That rule hides in three ways at once - display, visibility, AND a
|
|
* `inset-inline-start: -9999px` offset - so all three have to be undone. Undoing
|
|
* two of them leaves the box on screen but 9999px to the side: invisible when
|
|
* unchecked, and visible when checked ONLY because the checked state below sets
|
|
* its own -3px offset. That is exactly what "only the tick shows" was. */
|
|
visibility: visible;
|
|
display: inline-block;
|
|
inset-inline-start: auto;
|
|
top: auto;
|
|
appearance: none;
|
|
-webkit-appearance: none;
|
|
box-sizing: content-box;
|
|
/* forms.css styles every input that is not a file input as a FORM FIELD:
|
|
* `min-height: 41px`, a grey background, a 6px radius, 9px padding and a 14px
|
|
* bottom margin. Everything but the min-height is overridden by the material
|
|
* declarations below - but a 41px floor turns a 13px box into a tall rectangle,
|
|
* and stretches the tick it becomes. `input[type="radio"]` resets it the same way
|
|
* a few lines further down that file, for the same reason. */
|
|
min-height: 0;
|
|
min-width: 0;
|
|
/* …then exactly .materialCheckBox. */
|
|
position: relative;
|
|
width: 13px;
|
|
height: 13px;
|
|
z-index: 0;
|
|
border: 2px solid #5a5a5a;
|
|
border-radius: 1px;
|
|
transition: 0.2s;
|
|
margin: 0;
|
|
padding: 0;
|
|
background: transparent;
|
|
/* Written as forms.css writes it: `flex-shrink: 0` and `flex: none` mean the
|
|
same thing here, and tests/adminCheckboxStyle.test.cjs compares the two
|
|
rules declaration by declaration - so saying it differently would read as a
|
|
difference between the Admin Panel's checkbox and everybody else's. */
|
|
flex: none;
|
|
vertical-align: middle;
|
|
cursor: pointer;
|
|
}
|
|
|
|
/* …and exactly .materialCheckBox.is-checked: the square becomes the tick, which is
|
|
what the transition above animates. */
|
|
/* #6465: THE FOCUS RING MUST NOT BE DRAWN ON THE ROTATED BOX.
|
|
The checked state below turns the square into a tick by making two borders
|
|
transparent and rotating the element 40deg. A browser draws its focus ring
|
|
around the element as it is - rotated - so a checkbox that is both checked and
|
|
focused (which is exactly what a checkbox you just clicked is) comes out as a
|
|
blue DIAMOND sitting where the tick should be. That is the glitch reported on
|
|
the Problems page.
|
|
|
|
The ring is not simply removed: keyboard users need to see where they are. It
|
|
moves to the row that CONTAINS the checkbox, which is not rotated - every one
|
|
of these lives inside a label (problemsSummary.jade: `label.admin-problem-item
|
|
> input.js-problem-check`) - so the indicator is a normal rectangle around the
|
|
whole row, which is easier to see than a 13px box anyway.
|
|
|
|
`:focus-visible` rather than `:focus`, so clicking with a mouse does not leave
|
|
a ring behind; `:focus-within` is the fallback where :has() is not supported,
|
|
and lands on the same element. */
|
|
.setting-content input[type="checkbox"]:focus,
|
|
.setting-content input[type="checkbox"]:focus-visible {
|
|
outline: none;
|
|
}
|
|
|
|
.setting-content label:has(> input[type="checkbox"]:focus-visible) {
|
|
outline: 2px solid #2573a7;
|
|
outline-offset: 2px;
|
|
border-radius: 3px;
|
|
}
|
|
|
|
.setting-content input[type="checkbox"]:checked {
|
|
top: -4px;
|
|
left: -3px;
|
|
width: 7px;
|
|
height: 15px;
|
|
margin-right: 6px;
|
|
border-top: 2px solid transparent;
|
|
border-left: 2px solid transparent;
|
|
border-bottom: 2px solid #3cb500;
|
|
border-right: 2px solid #3cb500;
|
|
border-radius: 0;
|
|
transform: rotate(40deg);
|
|
-webkit-backface-visibility: hidden;
|
|
backface-visibility: hidden;
|
|
transform-origin: 100% 100%;
|
|
}
|
|
|
|
.setting-content input[type="checkbox"]:focus-visible {
|
|
outline: 2px solid var(--theme-accent, #2573a7);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
.setting-content input[type="checkbox"]:disabled {
|
|
cursor: default;
|
|
opacity: 0.6;
|
|
}
|
|
|
|
/* A checkbox written as `label > input + text` (Attachments / Limits / Avatars,
|
|
the Backup checkboxes) needs the gap the `.materialCheckBox` markup gets from its
|
|
own layout, or the box and its words touch. The checked state adds its own
|
|
margin - the same one the material checkbox adds - so this is the unchecked one. */
|
|
.setting-content label > input[type="checkbox"] {
|
|
margin-inline-end: 6px;
|
|
}
|
|
|
|
/* Admin Panel / Attachments / Backup, the schedule's day: buttons, not a field.
|
|
The weekly one is seven days in the reader's own language - the text field it
|
|
replaces only ever accepted an English day name typed exactly right. The monthly
|
|
one is the 28 dates a monthly backup can safely run on - a spin control made you
|
|
click 27 times to reach the end of the month, and never showed that the 29th to
|
|
the 31st are not offered at all (they would skip February).
|
|
Both wrap onto further lines rather than squeezing, and the chosen one is filled
|
|
with the theme colour, the way the selected left-menu entry and the selected tab
|
|
are. */
|
|
.setting-content .schedule-day-buttons {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 6px;
|
|
}
|
|
|
|
.setting-content .schedule-day-btn {
|
|
display: inline-block;
|
|
padding: 6px 12px;
|
|
border: 1px solid rgba(0, 0, 0, 0.2);
|
|
border-radius: 3px;
|
|
background: #fff;
|
|
color: inherit;
|
|
cursor: pointer;
|
|
text-decoration: none;
|
|
line-height: 1.3;
|
|
white-space: nowrap;
|
|
}
|
|
|
|
.setting-content .schedule-day-btn:hover {
|
|
background: #f2f2f2;
|
|
text-decoration: none;
|
|
}
|
|
|
|
.setting-content .schedule-day-btn.active {
|
|
background: var(--theme-accent, #2573a7);
|
|
border-color: var(--theme-accent, #2573a7);
|
|
color: #fff;
|
|
}
|
|
|
|
.setting-content .schedule-day-btn:focus-visible {
|
|
outline: 2px solid var(--theme-accent, #2573a7);
|
|
outline-offset: 2px;
|
|
}
|
|
|
|
/* The 28 dates are a grid of equal squares, so the numbers line up in columns
|
|
instead of drifting with their own width. */
|
|
.setting-content .schedule-day-numbers .schedule-day-btn {
|
|
min-width: 2.4em;
|
|
padding-inline: 6px;
|
|
text-align: center;
|
|
}
|
|
|
|
/* Several such checkboxes side by side - Attachments / Backup's "Attachments,
|
|
Avatars, Data" - are one row, each label holding its box and its words together.
|
|
Inline labels would let a label wrap away from its own checkbox, and the checked
|
|
box shifts a few pixels as it turns into the tick, which unaligned text follows. */
|
|
.setting-content .checkbox-row {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
gap: 6px 18px;
|
|
}
|
|
|
|
/* One item of that row: a label around a native checkbox, or - since #6465 - the
|
|
`a.flex > .materialCheckBox + span` the rest of WeKan uses. Both keep their box
|
|
and their words together, so a row can wrap between items and never inside one. */
|
|
.setting-content .checkbox-row label,
|
|
.setting-content .checkbox-row a.flex {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
margin: 0;
|
|
cursor: pointer;
|
|
/* The anchor is one item of the row, not a full-height column: `.flex` gives it
|
|
`height: 100%`, which stretched the box away from its words. */
|
|
height: auto;
|
|
}
|
|
|
|
/* A GROUP title inside a pane - "All Boards", "URL", "Product name", "Logo" on
|
|
Visibility. Deliberately smaller than the pane title above it, so the page reads
|
|
as one heading with groups under it rather than as several pages stacked. */
|
|
.admin-pane-group-title {
|
|
margin: 0;
|
|
font-size: 1rem;
|
|
font-weight: 700;
|
|
line-height: 1.3;
|
|
color: inherit;
|
|
}
|
|
|
|
/* Admin Panel / Settings / Visibility / Wait Spinner: the dropdown and a live
|
|
preview of the spinner it names, side by side - and the preview drops BELOW the
|
|
dropdown when there is not enough room for both. flex-wrap does that on its own,
|
|
at whatever width the pane happens to have, so no breakpoint has to be guessed. */
|
|
.spinner-select-row {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
gap: 12px;
|
|
}
|
|
|
|
.spinner-select-row > select {
|
|
flex: 0 1 auto;
|
|
max-width: 100%;
|
|
}
|
|
|
|
/* A fixed box the spinner is centred in, so switching between spinners of different
|
|
sizes does not move the dropdown. The spinners are written for a full-page
|
|
loading screen (`margin: 100px auto 0`, up to 70px wide), so their margin is
|
|
dropped and the whole thing scaled down to fit beside a form field. */
|
|
.spinner-select-row .spinner-preview {
|
|
flex: 0 0 auto;
|
|
width: 72px;
|
|
height: 44px;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.spinner-select-row .spinner-preview .sk-spinner {
|
|
margin: 0 auto !important;
|
|
transform: scale(0.5);
|
|
transform-origin: center center;
|
|
}
|
|
|
|
/* A SUB-title under a group title - one line saying what that group's setting
|
|
reaches (Visibility / Change color says the site admin's colour is what every
|
|
Organization without one of its own inherits). Smaller and quieter than the group
|
|
title above it, so it reads as a note, not as another group. */
|
|
.admin-pane-subgroup-title {
|
|
margin: 2px 0 0;
|
|
font-size: 0.85rem;
|
|
font-weight: 400;
|
|
line-height: 1.3;
|
|
opacity: 0.75;
|
|
color: inherit;
|
|
}
|
|
|
|
/* The first group starts right under the pane title; every later one needs air
|
|
above it, and the rule between two groups is the pane's own, not a menu rule. */
|
|
.setting-detail li + li > .admin-pane-group-title {
|
|
margin-top: 14px;
|
|
}
|
|
|
|
.setting-detail li.admin-pane-group-separator {
|
|
margin: 14px 0 0;
|
|
}
|
|
|
|
.setting-detail li.admin-pane-group-separator hr {
|
|
margin: 0;
|
|
border: 0;
|
|
border-top: 1px solid rgba(0, 0, 0, 0.15);
|
|
}
|
|
|
|
/* ── Save ────────────────────────────────────────────────────────────────────
|
|
One Save button look for the whole Admin Panel: the panes' own Save (People /
|
|
Login, People / E-mail, Visibility, …) and the Save inside every Admin Panel
|
|
popup - Edit and New for User, Organization, Team and Translation.
|
|
|
|
The panes' Save is a `button.primary`, which forms.css themes. A popup's is an
|
|
`input[type=submit].primary.wide` sitting in a flex `.buttonsContainer` - and
|
|
`.wide` never reached it, because the rule for it in forms.css is written as a
|
|
DESCENDANT selector (`input[type="submit"] .wide`), which matches nothing: an
|
|
input has no children. So a popup's Save was the same colour but a different,
|
|
cramped size, wherever it landed in the row.
|
|
|
|
Both are listed here with the same declarations, taken from what the panes' Save
|
|
already looks like, so the two cannot drift apart again. The popups are named one
|
|
by one on purpose: `.buttonsContainer` is board-sidebar and member-menu markup
|
|
too, and those are not Admin Panel buttons. */
|
|
.setting-content .content-body .main-body .setting-detail button.primary,
|
|
.pop-over[data-popup='editUserPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='editOrgPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='editTeamPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='newUserPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='newOrgPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='newTeamPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='editTranslationPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='newTranslationPopup'] .buttonsContainer input[type="submit"].primary {
|
|
background: var(--theme-accent, #005377);
|
|
color: #fff;
|
|
border: none;
|
|
font-weight: 700;
|
|
line-height: 1.3;
|
|
padding: 9px 35px;
|
|
cursor: pointer;
|
|
}
|
|
|
|
.setting-content .content-body .main-body .setting-detail button.primary:hover,
|
|
.setting-content .content-body .main-body .setting-detail button.primary:focus,
|
|
.pop-over[data-popup='editUserPopup'] .buttonsContainer input[type="submit"].primary:hover,
|
|
.pop-over[data-popup='editOrgPopup'] .buttonsContainer input[type="submit"].primary:hover,
|
|
.pop-over[data-popup='editTeamPopup'] .buttonsContainer input[type="submit"].primary:hover,
|
|
.pop-over[data-popup='newUserPopup'] .buttonsContainer input[type="submit"].primary:hover,
|
|
.pop-over[data-popup='newOrgPopup'] .buttonsContainer input[type="submit"].primary:hover,
|
|
.pop-over[data-popup='newTeamPopup'] .buttonsContainer input[type="submit"].primary:hover,
|
|
.pop-over[data-popup='editTranslationPopup'] .buttonsContainer input[type="submit"].primary:hover,
|
|
.pop-over[data-popup='newTranslationPopup'] .buttonsContainer input[type="submit"].primary:hover,
|
|
.pop-over[data-popup='editUserPopup'] .buttonsContainer input[type="submit"].primary:focus,
|
|
.pop-over[data-popup='editOrgPopup'] .buttonsContainer input[type="submit"].primary:focus,
|
|
.pop-over[data-popup='editTeamPopup'] .buttonsContainer input[type="submit"].primary:focus,
|
|
.pop-over[data-popup='newUserPopup'] .buttonsContainer input[type="submit"].primary:focus,
|
|
.pop-over[data-popup='newOrgPopup'] .buttonsContainer input[type="submit"].primary:focus,
|
|
.pop-over[data-popup='newTeamPopup'] .buttonsContainer input[type="submit"].primary:focus,
|
|
.pop-over[data-popup='editTranslationPopup'] .buttonsContainer input[type="submit"].primary:focus,
|
|
.pop-over[data-popup='newTranslationPopup'] .buttonsContainer input[type="submit"].primary:focus {
|
|
background: var(--theme-accent, #004766);
|
|
color: #fff;
|
|
}
|
|
|
|
.setting-content .content-body .main-body .setting-detail button.primary:active,
|
|
.pop-over[data-popup='editUserPopup'] .buttonsContainer input[type="submit"].primary:active,
|
|
.pop-over[data-popup='editOrgPopup'] .buttonsContainer input[type="submit"].primary:active,
|
|
.pop-over[data-popup='editTeamPopup'] .buttonsContainer input[type="submit"].primary:active,
|
|
.pop-over[data-popup='newUserPopup'] .buttonsContainer input[type="submit"].primary:active,
|
|
.pop-over[data-popup='newOrgPopup'] .buttonsContainer input[type="submit"].primary:active,
|
|
.pop-over[data-popup='newTeamPopup'] .buttonsContainer input[type="submit"].primary:active,
|
|
.pop-over[data-popup='editTranslationPopup'] .buttonsContainer input[type="submit"].primary:active,
|
|
.pop-over[data-popup='newTranslationPopup'] .buttonsContainer input[type="submit"].primary:active {
|
|
background: var(--theme-accent, #01628c);
|
|
color: #fff;
|
|
}
|
|
|
|
/* A popup's Save is the only thing in its row, so it takes the row - which is what
|
|
`.wide` was for. It stops well short of a wide popup's full width so it stays a
|
|
button rather than a bar. */
|
|
.pop-over[data-popup='editUserPopup'] .buttonsContainer,
|
|
.pop-over[data-popup='editOrgPopup'] .buttonsContainer,
|
|
.pop-over[data-popup='editTeamPopup'] .buttonsContainer,
|
|
.pop-over[data-popup='newUserPopup'] .buttonsContainer,
|
|
.pop-over[data-popup='newOrgPopup'] .buttonsContainer,
|
|
.pop-over[data-popup='newTeamPopup'] .buttonsContainer,
|
|
.pop-over[data-popup='editTranslationPopup'] .buttonsContainer,
|
|
.pop-over[data-popup='newTranslationPopup'] .buttonsContainer {
|
|
margin-top: 6px;
|
|
}
|
|
|
|
.pop-over[data-popup='editUserPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='editOrgPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='editTeamPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='newUserPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='newOrgPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='newTeamPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='editTranslationPopup'] .buttonsContainer input[type="submit"].primary,
|
|
.pop-over[data-popup='newTranslationPopup'] .buttonsContainer input[type="submit"].primary {
|
|
flex: 1 1 auto;
|
|
max-width: 320px;
|
|
}
|
|
|
|
/* Admin panel buttons should use theme darker color */
|
|
.setting-content .content-body .main-body .setting-detail button.btn {
|
|
background: var(--theme-accent, #005377);
|
|
color: #fff;
|
|
border: none;
|
|
}
|
|
|
|
.setting-content .content-body .main-body .setting-detail button.btn:hover,
|
|
.setting-content .content-body .main-body .setting-detail button.btn:focus {
|
|
background: var(--theme-accent, #004766);
|
|
color: #fff;
|
|
}
|
|
|
|
.setting-content .content-body .main-body .setting-detail button.btn:active {
|
|
background: var(--theme-accent, #01628c);
|
|
color: #fff;
|
|
}
|
|
|
|
/* Force horizontal scrollbar to always be visible at bottom */
|
|
.setting-content .content-body .main-body {
|
|
position: relative;
|
|
}
|
|
|
|
/* Add invisible content to force horizontal scrolling when needed */
|
|
.setting-content .content-body .main-body::after {
|
|
content: '';
|
|
display: block;
|
|
/* 100%, not 100vw: this is absolutely positioned INSIDE .main-body, so a
|
|
viewport-wide hairline stuck out past it and made the page scroll sideways. */
|
|
width: 100%;
|
|
height: 1px;
|
|
position: absolute;
|
|
bottom: 0;
|
|
inset-inline-start: 0;
|
|
pointer-events: none;
|
|
}
|
|
.setting-content .content-body .main-body ul li {
|
|
padding: 0.5rem 0.5rem;
|
|
}
|
|
.setting-content .content-body .main-body ul li a .is-checked {
|
|
border-bottom: 2px solid #3cb500;
|
|
border-right: 2px solid #3cb500;
|
|
}
|
|
.setting-content .content-body .main-body ul li a span {
|
|
padding: 0 0.5rem;
|
|
}
|
|
.setting-content .content-body .main-body ul li .admin-announcement,
|
|
.setting-content .content-body .main-body ul li .admin-accessibility,
|
|
.setting-content .content-body .main-body ul li .invite-people,
|
|
.setting-content .content-body .main-body ul li .layout {
|
|
padding-inline-start: 20px;
|
|
}
|
|
.setting-content .content-body .main-body ul li .admin-announcement li,
|
|
.setting-content .content-body .main-body ul li .admin-accessibility li,
|
|
.setting-content .content-body .main-body ul li .invite-people li,
|
|
.setting-content .content-body .main-body ul li .layout li {
|
|
min-width: 500px;
|
|
}
|
|
.setting-content .content-body .main-body ul li .admin-announcement li ul.no-margin-bottom,
|
|
.setting-content .content-body .main-body ul li .admin-accessibility li ul.no-margin-bottom,
|
|
.setting-content .content-body .main-body ul li .invite-people li ul.no-margin-bottom,
|
|
.setting-content .content-body .main-body ul li .layout li ul.no-margin-bottom {
|
|
margin-bottom: 0;
|
|
}
|
|
.setting-content .content-body .main-body ul li .admin-announcement li .bg-white a,
|
|
.setting-content .content-body .main-body ul li .admin-accessibility li .bg-white a,
|
|
.setting-content .content-body .main-body ul li .invite-people li .bg-white a,
|
|
.setting-content .content-body .main-body ul li .layout li .bg-white a {
|
|
background: #f7f7f7;
|
|
}
|
|
.setting-content .content-body .main-body ul li .admin-announcement li .bg-white a.is-checked,
|
|
.setting-content .content-body .main-body ul li .admin-accessibility li .bg-white a.is-checked,
|
|
.setting-content .content-body .main-body ul li .invite-people li .bg-white a.is-checked,
|
|
.setting-content .content-body .main-body ul li .layout li .bg-white a.is-checked {
|
|
background: #fff;
|
|
}
|
|
.setting-content .content-body .main-body ul li input[type=radio] {
|
|
margin: 4px;
|
|
}
|
|
.option {
|
|
-webkit-border-radius: 3px;
|
|
border-radius: 3px;
|
|
background: #fff;
|
|
text-decoration: none;
|
|
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
|
box-shadow: 0 1px 2px rgba(0,0,0,0.2);
|
|
margin-top: 5px;
|
|
padding: 5px;
|
|
}
|
|
.title {
|
|
font-weight: 700;
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.description {
|
|
margin-bottom: 0.5rem;
|
|
}
|
|
.bg-white {
|
|
background: #f9fbfc;
|
|
}
|
|
.wekan-form-control.has-error {
|
|
border-color: #a94442;
|
|
box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
|
|
}
|
|
li.has-error {
|
|
color: #a94442;
|
|
}
|
|
li.has-error .form-group .wekan-form-control {
|
|
border-color: #a94442;
|
|
box-shadow: inset 0 1px 1px rgba(0,0,0,0.075);
|
|
}
|
|
|
|
/* Constrain textarea elements with balanced left/right spacing */
|
|
.setting-content .content-body .main-body textarea.wekan-form-control {
|
|
width: calc(100% - 20px);
|
|
margin: 0 10px;
|
|
max-width: calc(100vw - 320px);
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
/* For nested custom head/manifest/assetlinks sections */
|
|
.setting-content .content-body .main-body .custom-head-settings textarea.wekan-form-control,
|
|
.setting-content .content-body .main-body .custom-manifest-settings textarea.wekan-form-control,
|
|
.setting-content .content-body .main-body .custom-assetlinks-settings textarea.wekan-form-control {
|
|
width: calc(100% - 20px);
|
|
margin-inline-start: 0;
|
|
margin-inline-end: 10px;
|
|
max-width: calc(100vw - 240px);
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
.setting-content .content-body .main-body .attachment-limit-row {
|
|
display: flex;
|
|
align-items: center;
|
|
gap: 10px;
|
|
max-width: 560px;
|
|
}
|
|
|
|
.setting-content .content-body .main-body .attachment-limit-row input.wekan-form-control {
|
|
flex: 1;
|
|
min-width: 200px;
|
|
}
|
|
|
|
.setting-content .content-body .main-body .attachment-limit-row select.wekan-form-control {
|
|
width: 120px;
|
|
min-width: 120px;
|
|
}
|
|
|
|
/* #6419: on phones the admin settings forced a side-by-side menu+content layout
|
|
(flex-direction: row "even on narrow windows"), so the ~127px side menu and the
|
|
content were crammed together and the long (e.g. Finnish) menu labels overflowed
|
|
the menu box rightward, visually overlapping the content. Stack them on small
|
|
screens: a full-width compact menu on top, full-width content below. */
|
|
@media screen and (max-width: 800px) {
|
|
.setting-content {
|
|
position: relative;
|
|
height: auto;
|
|
min-height: 100%;
|
|
}
|
|
.setting-content .content-body {
|
|
flex-direction: column;
|
|
flex-wrap: nowrap;
|
|
gap: 8px;
|
|
height: auto;
|
|
padding-top: 9px;
|
|
}
|
|
.setting-content .content-body .side-menu {
|
|
width: 100%;
|
|
flex: 0 0 auto;
|
|
border-radius: 6px;
|
|
}
|
|
/* Menu items as a wrapping horizontal row so the menu stays compact on top. */
|
|
.setting-content .content-body .side-menu ul {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 4px;
|
|
padding: 4px;
|
|
}
|
|
.setting-content .content-body .side-menu ul li {
|
|
flex: 0 0 auto;
|
|
margin: 0;
|
|
}
|
|
/* In the wrapping row a rule between groups shrank to a short dash beside an
|
|
entry, and a group title sat mid-row. Each takes a whole line instead, so
|
|
every group starts on a row of its own - the same grouping as the column. */
|
|
.setting-content .content-body .side-menu ul li.left-menu-separator,
|
|
.setting-content .content-body .side-menu ul li.left-menu-heading {
|
|
flex: 0 0 100%;
|
|
}
|
|
.setting-content .content-body .side-menu ul li a {
|
|
width: auto;
|
|
white-space: nowrap;
|
|
padding: 10px 12px;
|
|
}
|
|
.setting-content .content-body .main-body {
|
|
width: 100%;
|
|
flex: 1 1 auto;
|
|
min-height: 540px;
|
|
overflow-x: auto !important;
|
|
}
|
|
}
|
|
|
|
/* ── Admin tables on a phone ─────────────────────────────────────────────────
|
|
"Fit the width, wrap the text" is the rule at EVERY width now (see the table
|
|
rules above), so this block no longer has to undo a 1200px floor. What is still
|
|
phone-specific is the label column: on a narrow screen a two-column table like
|
|
Admin Panel / Version needs its label side pinned to a share of the width, or a
|
|
long value squeezes the labels down to one character per line. */
|
|
@media screen and (max-width: 800px) {
|
|
.setting-content .content-body .main-body table:not(.table-page-table) th {
|
|
width: 45%;
|
|
max-width: none;
|
|
}
|
|
}
|
|
|
|
/* ── Admin Panel / LDAP override source badges ───────────────────────────────
|
|
"Clearly visible, is in use environment variable or admin panel setting"
|
|
(see client/components/settings/settingBody.js's ldapSourceLabelFor). */
|
|
.ldap-source-badge {
|
|
color: #767676;
|
|
font-size: 0.85em;
|
|
font-style: italic;
|
|
}
|
|
|
|
.ldap-test-success {
|
|
color: #2e7d32;
|
|
}
|
|
|
|
.ldap-test-error {
|
|
color: #c62828;
|
|
}
|
|
|
|
/* #6736: Admin Panel / Settings / Visibility / Features - a feature's short
|
|
description under its checkbox, and the marker of a feature that arrived
|
|
with an update and waits for approval. */
|
|
#tableVisibilityMode-setting .feature-desc {
|
|
margin: 0 0 0.5em 2.2em;
|
|
opacity: 0.75;
|
|
font-size: 0.9em;
|
|
}
|
|
#tableVisibilityMode-setting .feature-awaiting-approval {
|
|
margin-inline-start: 0.5em;
|
|
font-weight: bold;
|
|
}
|