Files
3x-ui/frontend/src/styles/page-shell.css
T
MHSanaei 2fea71387b fix(ui): polish across routing, groups, inbounds, mobile sidebar
A bundle of small UI fixes that surfaced together while reviewing the
panel.

Routing rules — stale Edit after drag:
- Dragging a rule and then clicking its Edit button used to open the
  modal with the *previous* rule's content. Root cause: desktopColumns
  was memoized with [t, isMobile, rows.length] (rows.length doesn't
  change on reorder), so the cached render function kept handing AntD
  the openEdit closure that captured the pre-drag rules array. Fix is
  a rulesRef updated each render and read inside openEdit, so even the
  cached closure sees the live array.
- Mobile rule cards on the same page were hard to tell apart: bumped
  the inter-card gap, slightly stronger border, soft shadow, and a
  small centered divider line between adjacent cards.

Mobile drawer (dark / ultra):
- The AntD Menu inside the mobile drawer was rendering with its own
  darkItemBg (#15161a / #050507) while the drawer body used the
  lighter colorBgElevated, producing visible two-tone seams. Force
  the drawer-content / drawer-body to the same dark color that the
  desktop sider uses, and make the menus transparent so they inherit.

Row menus — visual grouping:
- Groups page row menu: moved Rename above the divider so the
  ordering reads safe → divider → destructive (Remove from group,
  Delete clients, Delete group only) instead of mixing the two
  groups.
- Inbounds page row menu: inserted a divider before delAllClients /
  delete so the destructive items sit visually separated from the
  earlier safe actions.

Dropdown affordances:
- Non-danger dropdown items had no perceivable hover state (default
  colorBgTextHover is too subtle, especially under the light theme).
  Apply the same primary-tint pattern the sider/drawer menu uses: 14%
  primary background and primary color on label + icon.
- ant-dropdown-menu-item-divider now uses var(--ant-color-border)
  (and an explicit rgba in dark) so the separator is actually visible
  in the light theme.

Clients toolbar — narrow-desktop wrap:
- Between 769px and 920px, the bulk-action bar (Attach / Detach /
  Add to group / Ungroup / more + Delete) wrapped to two rows with
  Delete stranded alone on the right. In that range, switch the
  toolbar buttons to icon-only, tighten gap to 6px and inline padding
  to 8px so everything stays on one line.
2026-05-28 13:25:43 +02:00

172 lines
3.7 KiB
CSS

.index-page,
.clients-page,
.inbounds-page,
.xray-page,
.settings-page,
.nodes-page,
.groups-page,
.api-docs-page {
--bg-page: #e6e8ec;
--bg-card: #ffffff;
min-height: 100vh;
background: var(--bg-page);
}
.index-page.is-dark,
.clients-page.is-dark,
.inbounds-page.is-dark,
.xray-page.is-dark,
.settings-page.is-dark,
.nodes-page.is-dark,
.groups-page.is-dark,
.api-docs-page.is-dark {
--bg-page: #1a1b1f;
--bg-card: #23252b;
}
.index-page.is-dark.is-ultra,
.clients-page.is-dark.is-ultra,
.inbounds-page.is-dark.is-ultra,
.xray-page.is-dark.is-ultra,
.settings-page.is-dark.is-ultra,
.nodes-page.is-dark.is-ultra,
.groups-page.is-dark.is-ultra,
.api-docs-page.is-dark.is-ultra {
--bg-page: #000;
--bg-card: #101013;
}
.index-page .ant-layout,
.index-page .ant-layout-content,
.clients-page .ant-layout,
.clients-page .ant-layout-content,
.inbounds-page .ant-layout,
.inbounds-page .ant-layout-content,
.xray-page .ant-layout,
.xray-page .ant-layout-content,
.settings-page .ant-layout,
.settings-page .ant-layout-content,
.nodes-page .ant-layout,
.nodes-page .ant-layout-content,
.groups-page .ant-layout,
.groups-page .ant-layout-content,
.api-docs-page .ant-layout,
.api-docs-page .ant-layout-content {
background: transparent;
}
.index-page .content-shell,
.clients-page .content-shell,
.inbounds-page .content-shell,
.xray-page .content-shell,
.settings-page .content-shell,
.nodes-page .content-shell,
.groups-page .content-shell,
.api-docs-page .content-shell {
background: transparent;
}
.index-page .content-area,
.clients-page .content-area,
.inbounds-page .content-area,
.xray-page .content-area,
.settings-page .content-area,
.nodes-page .content-area,
.groups-page .content-area {
padding: 24px;
}
@media (max-width: 768px) {
.clients-page .content-area,
.inbounds-page .content-area,
.nodes-page .content-area,
.groups-page .content-area {
padding: 8px;
}
}
.loading-spacer {
min-height: calc(100vh - 120px);
}
.ant-dropdown-menu-item:not(.ant-dropdown-menu-item-disabled):not(.ant-dropdown-menu-item-danger):hover,
.ant-dropdown-menu-item:not(.ant-dropdown-menu-item-disabled):not(.ant-dropdown-menu-item-danger):hover .ant-dropdown-menu-title-content,
.ant-dropdown-menu-item:not(.ant-dropdown-menu-item-disabled):not(.ant-dropdown-menu-item-danger):hover > .anticon {
color: var(--ant-color-primary) !important;
}
.ant-dropdown-menu-item:not(.ant-dropdown-menu-item-disabled):not(.ant-dropdown-menu-item-danger):hover {
background-color: color-mix(in srgb, var(--ant-color-primary) 14%, transparent) !important;
}
.ant-dropdown-menu-item-divider {
background-color: var(--ant-color-border) !important;
}
body.dark .ant-dropdown-menu-item-divider {
background-color: rgba(255, 255, 255, 0.12) !important;
}
.settings-page .header-row,
.xray-page .header-row {
display: flex;
flex-wrap: wrap;
align-items: center;
}
.settings-page .header-actions,
.xray-page .header-actions {
padding: 4px;
}
.settings-page .header-info,
.xray-page .header-info {
display: flex;
justify-content: flex-end;
}
.icons-only .ant-tabs-nav {
margin-bottom: 8px;
}
.icons-only .ant-tabs-nav-wrap {
width: 100%;
}
.icons-only .ant-tabs-nav-list {
display: flex;
width: 100%;
}
.icons-only .ant-tabs-tab {
flex: 1 1 0;
justify-content: center;
margin: 0;
padding: 10px 0;
}
.icons-only .ant-tabs-tab .anticon {
margin: 0;
font-size: 18px;
}
.icons-only .ant-tabs-nav-operations {
display: none;
}
.clients-page .summary-card,
.inbounds-page .summary-card,
.nodes-page .summary-card,
.groups-page .summary-card {
padding: 16px;
}
@media (max-width: 768px) {
.clients-page .summary-card,
.inbounds-page .summary-card,
.nodes-page .summary-card,
.groups-page .summary-card {
padding: 8px;
}
}