page.css 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440
  1. /**
  2. * Page breadcrumb
  3. */
  4. .bx-menu-breadcrumb li:first-child {
  5. display: none;
  6. }
  7. .bx-menu-breadcrumb li a {
  8. margin: 0;
  9. }
  10. .bx-menu-breadcrumb li a span {
  11. font-size: 1rem;
  12. font-weight: normal;
  13. color: rgba(255, 255, 255, 0.7);
  14. }
  15. /**
  16. * Inlined Blocks Styles
  17. */
  18. div.bx-std-blocks-line {
  19. position: relative;
  20. }
  21. div.bx-std-blocks-line .bx-std-block-wrp {
  22. display: block;
  23. float: left;
  24. width: 100%;
  25. }
  26. /**
  27. * Block Styles
  28. */
  29. div.bx-std-block {
  30. position: relative; /* the overlay scrollbar is drawn over the block */
  31. display: flex;
  32. flex-direction: column;
  33. min-height: 0;
  34. }
  35. /*
  36. * Overlay scrollbar (bx_std_scrollbar in studio/js/page.js): the scroll box hides its native bar, and an SVG drawn over the block runs a
  37. * thumb down the right edge and round the 24px bottom corner (the top one too when nothing sits above the scroll box), like a bar that
  38. * follows the panel's shape; the thumb shows while the pointer is over the block or the content scrolls.
  39. */
  40. div.bx-std-block-content {
  41. scrollbar-width: none;
  42. }
  43. div.bx-std-block-content::-webkit-scrollbar {
  44. display: none;
  45. }
  46. svg.bx-std-scrollbar {
  47. position: absolute;
  48. inset: 0;
  49. z-index: 2;
  50. width: 100%;
  51. height: 100%;
  52. overflow: visible;
  53. pointer-events: none;
  54. opacity: 0;
  55. transition: opacity 0.3s;
  56. }
  57. div.bx-std-block:hover > svg.bx-std-scrollbar,
  58. div.bx-std-block.bx-std-scrolling > svg.bx-std-scrollbar {
  59. opacity: 1;
  60. }
  61. svg.bx-std-scrollbar path {
  62. fill: none;
  63. stroke-width: 4;
  64. stroke-linecap: round;
  65. }
  66. svg.bx-std-scrollbar .bx-std-scrollbar-track {
  67. stroke: rgba(0, 0, 0, 0.05);
  68. }
  69. svg.bx-std-scrollbar .bx-std-scrollbar-thumb {
  70. stroke: rgba(0, 0, 0, 0.25);
  71. }
  72. .dark svg.bx-std-scrollbar .bx-std-scrollbar-track {
  73. stroke: rgba(255, 255, 255, 0.05);
  74. }
  75. .dark svg.bx-std-scrollbar .bx-std-scrollbar-thumb {
  76. stroke: rgba(255, 255, 255, 0.25);
  77. }
  78. @media (prefers-reduced-motion: reduce) {
  79. svg.bx-std-scrollbar {
  80. transition: none;
  81. }
  82. }
  83. div.bx-std-block-caption,
  84. div.bx-std-block-panel-top,
  85. div.bx-std-block-panel-bottom {
  86. flex: none;
  87. }
  88. div.bx-std-block-caption {
  89. position: relative;
  90. display: -webkit-flex;
  91. display: flex;
  92. -webkit-align-items: center;
  93. align-items: center;
  94. z-index: 1;
  95. gap: 0.75rem;
  96. padding: 1rem; /* 16px around a 32px row, like the header bar: a 64px caption with its icon, buttons and tabs on the block's 16px content line */
  97. box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.05); /* hairline divider drawn outside the box, so it adds no height */
  98. }
  99. .dark div.bx-std-block-caption {
  100. box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.025);
  101. }
  102. /* Optional title icon: a flat gray 32px square, 8px radius (no plate, ring or shadow: a label, not a button) with a 20px glyph. */
  103. div.bx-std-block-caption .bx-std-bcap-icon {
  104. flex: none;
  105. display: flex;
  106. align-items: center;
  107. justify-content: center;
  108. width: 2rem;
  109. height: 2rem;
  110. border-radius: 0.5rem;
  111. background: rgb(0 0 0 / 0.1); /* the same plate as the dashboard row icons */
  112. color: rgb(75 85 99);
  113. }
  114. .dark div.bx-std-block-caption .bx-std-bcap-icon {
  115. background: rgb(255 255 255 / 0.05);
  116. color: rgb(156 163 175);
  117. }
  118. div.bx-std-block-caption .bx-std-bcap-icon .sys-icon {
  119. color: rgb(0 0 0); /* black at 80% through the element's opacity (white in the dark scheme), not the site-wide accent that .sys-icon carries */
  120. opacity: 0.8;
  121. font-size: 1.25rem;
  122. line-height: 1.25rem;
  123. }
  124. .dark div.bx-std-block-caption .bx-std-bcap-icon .sys-icon {
  125. color: rgb(255 255 255);
  126. }
  127. div.bx-std-block-caption .bx-std-bcap-icon svg {
  128. width: 1.25rem;
  129. height: 1.25rem;
  130. }
  131. /* A segmented switcher in the caption sits on the right; its 32px frame is the row's height. */
  132. div.bx-std-block-caption > .bx-std-segmented {
  133. flex: none;
  134. }
  135. /* A button in the caption (the Cache block's "Clear all caches") keeps its width beside the flexible title. */
  136. div.bx-std-block-caption > .bx-btn {
  137. flex: none;
  138. }
  139. .bx-std-bcap-text {
  140. -webkit-flex: 1 1 auto;
  141. -ms-flex: 1 1 auto;
  142. flex: 1 1 auto;
  143. line-height: 2rem; /* the row is 32px with or without an icon, so every caption is the same height */
  144. font-weight: 600;
  145. font-size: 1.25rem;
  146. }
  147. /* Button loader (dashboard.js loadingButton): the launcher's tile wave (loading-double.svg, 40x10, its own keyframes) stands in for a pressed
  148. button's label, at the button's width, until its request ends; the button is disabled meanwhile and takes no clicks (an <a> button has no disabled state). */
  149. .bx-std-btn-loading {
  150. display: inline-block;
  151. width: 40px;
  152. height: 10px;
  153. vertical-align: middle;
  154. background: url(../images/loading-double.svg) center / 40px 10px no-repeat;
  155. }
  156. .bx-btn.bx-btn-loading {
  157. pointer-events: none;
  158. }
  159. div.bx-std-bcap-actions {
  160. position: relative;
  161. -webkit-flex: 0 2 auto;
  162. -ms-flex: 0 2 auto;
  163. flex: 0 2 auto;
  164. max-width: 80%;
  165. font-size: 0.875rem;
  166. }
  167. div.bx-std-bcap-action,
  168. div.bx-std-bcap-action-div {
  169. position: relative;
  170. float: left;
  171. line-height: 25px;
  172. }
  173. div.bx-std-bcap-action-div:first-child {
  174. display: none;
  175. }
  176. /* Top panel (the Pages builder's selects): the same toolbar as a grid header, 64px with 16px sides and a hairline below it;
  177. under a caption the 16px between them is split 8 / 8 like the grid toolbar. Its fields are spaced by an 8px gap alone. */
  178. div.bx-std-block-panel-top {
  179. padding: 1rem;
  180. box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.05);
  181. }
  182. .dark div.bx-std-block-panel-top {
  183. box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.025);
  184. }
  185. div.bx-std-block-caption:has(+ div.bx-std-block-panel-top) {
  186. padding-bottom: 0.5rem;
  187. box-shadow: none; /* the panel below draws the only separator, as the sticky grid toolbar does by painting over the caption's */
  188. }
  189. div.bx-std-block-caption + div.bx-std-block-panel-top {
  190. padding-top: 0.5rem;
  191. }
  192. div.bx-std-block-panel-top .bx-std-pt-cnt {
  193. padding: 0;
  194. }
  195. div.bx-std-block-panel-top .bx-std-pt-cnt > .flex {
  196. gap: 0.5rem;
  197. }
  198. div.bx-std-block-panel-top .bx-std-pt-cnt > .flex > * {
  199. margin: 0;
  200. }
  201. div.bx-std-block-panel-top .bx-form-element-wrapper {
  202. margin: 0;
  203. }
  204. div.bx-std-block-content {
  205. flex: 1 1 auto;
  206. min-height: 0;
  207. overflow-y: auto;
  208. border-radius: 0 0 1.5rem 1.5rem; /* the scroll box clips to the block's 24px corners instead of squaring them off */
  209. padding: 0.5rem;
  210. }
  211. div.bx-std-block-content:not(:last-child) {
  212. border-radius: 0; /* a bottom panel follows and owns the corners */
  213. }
  214. div.bx-std-block-content:first-child {
  215. border-top-left-radius: 1.5rem; /* no caption above: the scroll box owns the top corners too */
  216. border-top-right-radius: 1.5rem;
  217. }
  218. /* A grid wider than its block scrolls sideways inside the block (grid.css hides the overflow, which cuts off the action column on narrower desktops). */
  219. div.bx-std-block-content .bx-grid-table-wrapper {
  220. overflow-x: auto;
  221. }
  222. div.bx-std-block-content div.bx-grid-header {
  223. margin-top: 0px;
  224. }
  225. /* Content inset: the block's 8px plus 8px from the content root itself, 16px in all. Forms, the designer's template list and
  226. builder cells add theirs here; product lists do the same in store.css, agent cards in agents.css. Options forms and grids are
  227. laid out as a header / scroller / footer stack below and own their inset there. */
  228. div.bx-std-block-content > .bx-form-advanced:not([name="adm-settings-form"]),
  229. div.bx-std-block-content > .bx-dsg-templates,
  230. div.bx-std-block-content > .adm-bp-cell,
  231. div.bx-std-block-content > .bx-layout-wrapper {
  232. padding: 0.5rem;
  233. }
  234. /**
  235. * Header / scroller / footer stack.
  236. * A block whose content is an options form (BxDolStudioOptions, name="adm-settings-form") or a grid keeps its caption fixed, scrolls
  237. * the middle, and pins a 64px footer: 16px around the 32px buttons, like the caption, hairline drawn outside the box.
  238. * The form footer is the form's last section (the Save button, BxBaseStudioOptions always puts it in a section of its own); the grid
  239. * footer is the grid's own footer (bulk actions, paging). Grid rows run edge to edge with 16px inside the first and last cell.
  240. */
  241. div.bx-std-block-content:has(> form[name="adm-settings-form"]),
  242. div.bx-std-block-content:has(> [id^="bx-grid-wrap-"]) {
  243. display: flex;
  244. flex-direction: column;
  245. padding: 0;
  246. overflow: hidden;
  247. }
  248. /* Options forms */
  249. div.bx-std-block-content > form[name="adm-settings-form"] {
  250. --bx-std-inset: 1rem; /* the scroller's inset: 16px for fields and for the accordion cards alike */
  251. position: relative;
  252. display: flex;
  253. flex-direction: column;
  254. flex: 1 1 auto;
  255. min-height: 0;
  256. padding: 0;
  257. }
  258. form[name="adm-settings-form"] > .bx-form-advanced-wrapper {
  259. display: flex; /* a column, so the footer can drop to the bottom (margin-top: auto) when the content does not fill the block */
  260. flex-direction: column;
  261. flex: 1 1 auto;
  262. min-height: 0;
  263. overflow-y: auto;
  264. padding: var(--bx-std-inset) var(--bx-std-inset) 0; /* no bottom inset: sticky elements stop at the scroller's padding edge */
  265. }
  266. form[name="adm-settings-form"] > .bx-form-advanced-wrapper > .bx-form-section-wrapper {
  267. flex: none; /* sections overflow the scroller instead of shrinking into it */
  268. margin: 0 0 0.5rem; /* overrides the my-4 emitted by BxBaseFormView::getOpenSection */
  269. padding: 0;
  270. }
  271. /* Plain form: the fields section is a bare divider section; its scaffolding adds no inset of its own. */
  272. form#adm-settings-form > .bx-form-advanced-wrapper > .bx-form-section-wrapper:not(:last-child) > .bx-form-section-divider > .bx-form-section-content {
  273. padding: 0 0 0.5rem;
  274. }
  275. /* Footer: the last section, holding the Save button. */
  276. form[name="adm-settings-form"] > .bx-form-advanced-wrapper > .bx-form-section-wrapper:last-child:not(:first-child) {
  277. position: sticky;
  278. bottom: 0;
  279. z-index: 1;
  280. display: flex;
  281. align-items: center;
  282. width: auto;
  283. height: 4rem;
  284. margin: auto calc(-1 * var(--bx-std-inset)) 0; /* spans the block edge to edge over the scroller's inset; auto pushes it down */
  285. padding: 1rem;
  286. border-radius: 0 0 1.5rem 1.5rem;
  287. background-color: #f5f5f7; /* gray-200 page + the block's white/60, so the sticky row matches the block around it */
  288. box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.05);
  289. }
  290. form[name="adm-settings-form"] > .bx-form-advanced-wrapper > .bx-form-section-wrapper:last-child:not(:first-child) .bx-form-section-content {
  291. padding: 0;
  292. }
  293. form[name="adm-settings-form"] > .bx-form-advanced-wrapper > .bx-form-section-wrapper:last-child:not(:first-child) .bx-form-element-wrapper {
  294. margin: 0;
  295. }
  296. /* Grids */
  297. div.bx-std-block-content > [id^="bx-grid-wrap-"] {
  298. display: flex;
  299. flex-direction: column;
  300. flex: 1 1 auto;
  301. min-height: 0;
  302. overflow-y: auto;
  303. padding: 0;
  304. }
  305. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-header {
  306. position: sticky; /* the filter / add toolbar stays under the caption, 64px like it */
  307. top: 0;
  308. z-index: 2;
  309. flex: none;
  310. margin: 0;
  311. padding: 1rem;
  312. background-color: #f5f5f7; /* gray-200 page + the block's white/60, so the sticky row matches the block around it */
  313. box-shadow: 0 1px 0 0 rgba(0, 0, 0, 0.05);
  314. }
  315. /* Under a caption the toolbar is the caption's second row: the 16px between them is split 8 / 8 so the half inside the
  316. toolbar (which is the top of the scroll box) leaves room for the buttons' hover and focus rings instead of clipping them. */
  317. div.bx-std-block-caption:has(+ div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-header) {
  318. padding-bottom: 0.5rem;
  319. }
  320. div.bx-std-block-caption + div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-header {
  321. padding-top: 0.5rem;
  322. }
  323. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-header .bx-grid-header-cnt {
  324. padding: 0;
  325. }
  326. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-header .bx-form-element-wrapper {
  327. margin: 0; /* the filter fields are spaced by the toolbar's gap alone */
  328. }
  329. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-header .bx-grid-header-controls-filter,
  330. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-header .bx-grid-header-controls-independent {
  331. column-gap: 1rem; /* 16px between toolbar fields and buttons */
  332. }
  333. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-table-wrapper2 {
  334. flex: none;
  335. }
  336. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-footer {
  337. position: sticky;
  338. bottom: 0;
  339. z-index: 2;
  340. flex: none;
  341. display: flex;
  342. align-items: center;
  343. margin: auto 0 0;
  344. padding: 1rem;
  345. border-radius: 0 0 1.5rem 1.5rem;
  346. background-color: #f5f5f7; /* gray-200 page + the block's white/60, so the sticky row matches the block around it */
  347. box-shadow: 0 -1px 0 0 rgba(0, 0, 0, 0.05);
  348. }
  349. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-footer > hr.bx-def-hr {
  350. display: none; /* the hairline above replaces it */
  351. }
  352. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-footer > .bx-grid-footer-cnt {
  353. flex: 1 1 auto;
  354. display: flex;
  355. align-items: center;
  356. justify-content: space-between;
  357. margin: 0;
  358. padding: 0;
  359. }
  360. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-footer > .bx-grid-footer-cnt > div {
  361. float: none;
  362. display: flex;
  363. align-items: center;
  364. flex-wrap: wrap;
  365. gap: 0.5rem;
  366. margin: 0;
  367. }
  368. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-footer > .bx-grid-footer-cnt > div > .bx-btn,
  369. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-footer > .bx-grid-footer-cnt > div .bx-paginate {
  370. margin: 0;
  371. white-space: nowrap;
  372. }
  373. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-footer > .bx-grid-footer-cnt::before,
  374. div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-footer > .bx-grid-footer-cnt::after {
  375. display: none; /* the bx-clearfix pseudo-elements would be empty flex items and push the actions and the pager inward */
  376. }
  377. div.bx-std-block-content > [id^="bx-grid-wrap-"] .bx-grid-table th:first-child,
  378. div.bx-std-block-content > [id^="bx-grid-wrap-"] .bx-grid-table td:first-child {
  379. padding-left: 1rem;
  380. }
  381. div.bx-std-block-content > [id^="bx-grid-wrap-"] .bx-grid-table th:last-child,
  382. div.bx-std-block-content > [id^="bx-grid-wrap-"] .bx-grid-table td:last-child {
  383. padding-right: 1rem;
  384. }
  385. .dark form[name="adm-settings-form"] > .bx-form-advanced-wrapper > .bx-form-section-wrapper:last-child:not(:first-child),
  386. .dark div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-header,
  387. .dark div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-footer {
  388. background-color: #1a1a1a; /* black page + the block's white/10, so the sticky row matches the block around it */
  389. }
  390. .dark form[name="adm-settings-form"] > .bx-form-advanced-wrapper > .bx-form-section-wrapper:last-child:not(:first-child),
  391. .dark div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-footer {
  392. box-shadow: 0 -1px 0 0 rgba(255, 255, 255, 0.025);
  393. }
  394. .dark div.bx-std-block-content > [id^="bx-grid-wrap-"] > .bx-grid-header {
  395. box-shadow: 0 1px 0 0 rgba(255, 255, 255, 0.025);
  396. }
  397. div.bx-std-block-panel-bottom {}
  398. div.bx-std-block-panel-bottom .bx-std-pt-cnt {
  399. padding: 0 1rem 1rem 1rem;
  400. }
  401. /**
  402. * Builder based blocks
  403. */
  404. .bx-layout-wrapper {
  405. padding-top: 0.75rem; /* the same 12px gap below the header as the sidebar pages */
  406. padding-bottom: 0;
  407. }
  408. /* Phones: the caption stays one row in a 343px block (icon, title, tabs), so the segmented tabs go compact and the title truncates. */
  409. @media (max-width: 767px) {
  410. div.bx-std-block-caption {
  411. gap: 0.5rem;
  412. }
  413. div.bx-std-block-caption > .bx-std-segmented .bx-std-segment {
  414. padding: 0 0.5rem;
  415. font-size: 0.75rem;
  416. }
  417. div.bx-std-block-caption .bx-std-bcap-text {
  418. min-width: 0;
  419. overflow: hidden;
  420. white-space: nowrap;
  421. text-overflow: ellipsis;
  422. }
  423. }