/*
 * Modern CMS theme - "Warm Clarity" palette.
 *
 * Every rule is scoped to .cms-theme-modern so removing that body class is a
 * complete rollback. Application-provided calendar colors intentionally remain
 * outside this layer.
 *
 * Warm neutrals (a taupe-tinted page/border/text scale rather than the previous
 * cool blue-gray one) and a deep teal primary next to the brand's own vivid teal
 * accent (linguasmart-logo.svg is #00d8b5) - same brand family, not a new hue.
 * Radius and spacing both moved up a step for a roomier, less gridded feel;
 * system-ui/-apple-system reads sharper natively than Arial and needs nothing
 * loaded over the network.
 *
 * --cms-hue-brand IS THE CUSTOMER-FACING KNOB. accent and primary are both written as
 * hsl(var(--cms-hue-brand) ...) rather than as literal hex, precisely so that an
 * installation can retint the whole brand family by overriding this one number - see
 * cms_config::$cc_cms_theme_accent_hue and cms_template's CMSTHEMEHUE substitution.
 * Neutrals and the semantic danger/success/warning trio deliberately do NOT read this
 * variable: a customer picking their own brand colour must not also be relabelling
 * what "danger" means.
 */
.cms-theme-modern {
  --cms-hue-brand: 175;
  --cms-font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Arial, sans-serif;
  --cms-font-size: 14.5px;
  --cms-control-height: 38px;
  --cms-space-1: 5px;
  --cms-space-2: 9px;
  --cms-space-3: 14px;
  --cms-space-4: 20px;
  --cms-space-5: 28px;
  --cms-radius-control: 10px;
  --cms-radius-panel: 16px;
  --cms-color-page: #f6f4ef;
  --cms-color-canvas: #fefdfb;
  --cms-color-surface: #faf8f3;
  --cms-color-surface-hover: hsl(var(--cms-hue-brand) 31% 95%);
  --cms-color-border: #e6ded0;
  --cms-color-border-strong: #d3c6b0;
  --cms-color-text: #2c2a26;
  --cms-color-muted: #7c7365;
  --cms-color-muted-hover: hsl(var(--cms-hue-brand) 10% 90%);
  --cms-color-accent: hsl(var(--cms-hue-brand) 84% 32%);
  --cms-color-accent-hover: hsl(var(--cms-hue-brand) 84% 27%);
  --cms-color-primary: hsl(calc(var(--cms-hue-brand) - 6) 37% 17%);
  --cms-color-primary-hover: hsl(calc(var(--cms-hue-brand) - 5) 38% 13%);
  --cms-color-header: var(--cms-color-primary);
  --cms-color-danger: #b3401f;
  --cms-color-danger-hover: #952f14;
  --cms-color-success: #4a7a1f;
  --cms-color-warning: #9a6412;
  --cms-color-focus: hsl(var(--cms-hue-brand) 84% 32%);
  --cms-shadow-panel: 0 1px 2px rgba(44, 40, 32, .06), 0 12px 32px rgba(44, 40, 32, .08);
  margin: 0;
  background: var(--cms-color-page);
  color: var(--cms-color-text);
  font-family: var(--cms-font-family);
  font-size: var(--cms-font-size);
  line-height: 1.5;
}

.cms-theme-modern *,
.cms-theme-modern *::before,
.cms-theme-modern *::after {
  box-sizing: border-box;
}

.cms-theme-modern a {
  color: var(--cms-color-primary);
  text-decoration: none;
}

.cms-theme-modern a:hover {
  color: var(--cms-color-accent);
}

.cms-theme-modern :focus-visible {
  outline: 3px solid color-mix(in srgb, var(--cms-color-accent) 32%, transparent);
  outline-offset: 2px;
}

/* Application shell. The header owns its background here: it stopped encoding the
   environment (the standing environment pill does that now), and without a real
   background the forced white text used to sit on the near-white page colour
   whenever no customer tint was configured. Flex replaces the legacy floats -
   float is ignored on flex items, so order alone restores the old arrangement. */
.cms-theme-modern .toptop {
  display: flex;
  align-items: center;
  gap: var(--cms-space-4);
  min-height: 64px;
  padding: var(--cms-space-3) var(--cms-space-5);
  border-bottom: 1px solid rgba(255, 255, 255, .2);
  background: var(--cms-color-header);
  box-shadow: 0 2px 12px rgba(44, 40, 32, .16);
  color: #fff;
}

.cms-theme-modern .toptop .lang {
  order: 2;
  width: auto;
}

.cms-theme-modern .toptop .logout {
  order: 3;
}

.cms-theme-modern .toptop .clear {
  display: none;
}

.cms-theme-modern .toptop a,
.cms-theme-modern .toptop .exit,
.cms-theme-modern .toptop .lang {
  color: #fff;
}

.cms-theme-modern .toptop .logo img {
  max-height: 38px;
}

/* Standing messages: the header pills. Bigger and louder than the entry-status
   pills on purpose - these stand for as long as their condition holds. */
.cms-standing-messages {
  display: flex;
  flex: 1;
  flex-wrap: wrap;
  gap: var(--cms-space-2);
  align-items: center;
  justify-content: flex-end;
  /* Together with the header's own gap this keeps the pills clearly further from
     the language/logout cluster than they are from each other. */
  padding-right: var(--cms-space-4);
}

.cms-standing-pill {
  display: inline-flex;
  align-items: center;
  min-height: 30px;
  padding: 4px 14px;
  border: 0;
  border-radius: 999px;
  background: #e2e8f0;
  color: #334155;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.cms-standing-pill[data-tone="info"] {
  background: #dbeafe;
  color: #1e40af;
}

.cms-standing-pill[data-tone="warning"] {
  background: #fef3c7;
  color: #92400e;
}

/* Danger carries the weight the old full-width impersonation bar had: every edit
   made while it shows is recorded against the impersonated account, so it alone
   gets a saturated fill and a slow pulse. */
.cms-standing-pill[data-tone="danger"] {
  background: var(--cms-color-danger);
  color: #fff;
  animation: cms-standing-danger 2.4s ease-out infinite;
}

@keyframes cms-standing-danger {
  0% { box-shadow: 0 0 0 0 rgba(255, 255, 255, .55); }
  70%, 100% { box-shadow: 0 0 0 9px rgba(255, 255, 255, 0); }
}

.cms-theme-modern .main {
  align-items: flex-start;
}

.cms-theme-modern .left {
  /* This value is paired with .canvas's own margin-top further down (both must match,
     so .left-nav and the content card land on the same line) and with
     .cms-omnisearch's top (which must be the exact negative of this one, so the search
     bar's own top edge does not move when this does - only the gap between it and
     .left-nav's top changes). .right itself carries none of this any more: .taby (the
     LinguaSmart/Admin site switcher) is meant to sit level with the search bar, not
     with the nav card, so only .canvas - not .right - reserves the space. Three
     numbers, one relationship; change one, change all three. */
  position: relative;
  flex: 0 0 220px;
  width: 220px;
  margin-top: calc(64px + .4em);
  padding-left: var(--cms-space-4);
}

.cms-theme-modern .right {
  min-width: 0;
  width: calc(100% - 220px);
}

.cms-theme-modern .left-nav {
  overflow: hidden;
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-panel);
  background: var(--cms-color-canvas);
  box-shadow: var(--cms-shadow-panel);
}

.cms-theme-modern #menulewe {
  padding: var(--cms-space-4) var(--cms-space-3);
}

.cms-theme-modern .mm,
.cms-theme-modern .mml0,
.cms-theme-modern .mml1,
.cms-theme-modern .mml1f {
  margin-bottom: var(--cms-space-1);
}

.cms-theme-modern .mml0 {
  min-height: 34px;
  padding-left: 0;
  border-radius: var(--cms-radius-control);
  background-position: 8px center;
  background-size: 18px 18px;
  position: relative;
}

.cms-theme-modern .mm a,
.cms-theme-modern [class*="mml"] > a {
  display: block;
  min-height: 32px;
  padding: 7px var(--cms-space-2);
  border-radius: var(--cms-radius-control);
  line-height: 18px;
}

.cms-theme-modern .mml0 > a {
  padding-left: 34px;
}

.cms-theme-modern .mml0 > .ico {
  top: 50%;
  left: 8px;
  width: 18px;
  margin: 0;
  transform: translateY(-50%);
  line-height: 18px;
}

.cms-theme-modern .mm a:hover,
.cms-theme-modern [class*="mml"] > a:hover {
  background: var(--cms-color-surface-hover);
}

.cms-theme-modern .mml0:hover {
  background-color: var(--cms-color-surface-hover);
}

.cms-theme-modern .mml0 > a:hover {
  background: transparent;
}

/* The current item in the light navigation: a tint of the brand and the brand's own dark
   ink, written on the hue like every other accent here so cc_cms_theme_accent_hue reaches
   it. These were the two literals the retint missed (#dff1ee / #075f57 - the shipped teal at
   hue 175, which is what the expressions below give at that hue). */
.cms-theme-modern .mms > a,
.cms-theme-modern .mms > a:visited {
  background: transparent;
  color: hsl(var(--cms-hue-brand) 86% 20%) !important;
  font-weight: 600;
}

.cms-theme-modern .mms {
  background-color: hsl(var(--cms-hue-brand) 40% 91%);
  border-radius: var(--cms-radius-control);
  color: hsl(var(--cms-hue-brand) 86% 20%);
}

.cms-theme-modern .mms > .ico {
  color: var(--cms-color-accent) !important;
}

/* Every level below the root is one family - 13px, no icon column, the same hover box - and
   the levels tell apart by indent alone. master.css gives the third level and below the
   second level's type; here the third level is also a shade quieter than the second, so a
   deep tree reads as a tree and not as a list of equals, and the fourth level and below take
   the third level's look plus their indent. Step the indent on the item, not the link: the
   hover box then starts where the text does, as it does on the second level. */
.cms-theme-modern .mml1,
.cms-theme-modern .mml1f,
.cms-theme-modern .mml2,
.cms-theme-modern .mml2f,
.cms-theme-modern .mml3,
.cms-theme-modern .mml3f,
.cms-theme-modern .mml4,
.cms-theme-modern .mml4f,
.cms-theme-modern .mml5,
.cms-theme-modern .mml5f,
.cms-theme-modern .mml6,
.cms-theme-modern .mml6f,
.cms-theme-modern .mml7,
.cms-theme-modern .mml7f {
  margin-left: 26px;
  font-size: 13px;
}

.cms-theme-modern .mml2 > a,
.cms-theme-modern .mml2f > a,
.cms-theme-modern .mml3 > a,
.cms-theme-modern .mml3f > a,
.cms-theme-modern .mml4 > a,
.cms-theme-modern .mml4f > a,
.cms-theme-modern .mml5 > a,
.cms-theme-modern .mml5f > a,
.cms-theme-modern .mml6 > a,
.cms-theme-modern .mml6f > a,
.cms-theme-modern .mml7 > a,
.cms-theme-modern .mml7f > a {
  font-size: 12.5px;
  opacity: .88;
}

.cms-theme-modern .mml2,
.cms-theme-modern .mml2f { padding-left: 14px; }
.cms-theme-modern .mml3,
.cms-theme-modern .mml3f { padding-left: 28px; }
.cms-theme-modern .mml4,
.cms-theme-modern .mml4f { padding-left: 42px; }
.cms-theme-modern .mml5,
.cms-theme-modern .mml5f { padding-left: 56px; }
.cms-theme-modern .mml6,
.cms-theme-modern .mml6f { padding-left: 70px; }
.cms-theme-modern .mml7,
.cms-theme-modern .mml7f { padding-left: 84px; }

/* The link keeps clear of the chevron: the generic link rule above sets padding with the
   shorthand at a specificity master.css's own clearance cannot match. */
.cms-theme-modern .mm-branch > a {
  padding-right: 30px;
}

/* The fold chevron: visible from the first paint, a little quieter than the label, the
   accent when its branch is the current one - every colour a brand token, so an
   installation's hue reaches it (cms_config::$cc_cms_theme_accent_hue) - and never a
   second hover box competing with the link's. The box is restated here because this theme
   paints EVERY <button> as a filled accent control (the generic rule above) and that rule
   outranks master.css's plain .mm-toggle; the header's user-menu toggle escapes it the
   same way. */
.cms-theme-modern .mm-toggle {
  width: 24px;
  height: 24px;
  min-height: 0;
  padding: 0;
  border: 0;
  border-radius: var(--cms-radius-control);
  background-color: transparent;
  box-shadow: none;
  color: var(--cms-color-text);
  opacity: .75;
  transition: background-color .18s ease, opacity .18s ease;
}
.cms-theme-modern .mm-toggle:hover,
.cms-theme-modern .mm-toggle:focus-visible {
  border-color: transparent;
  background-color: var(--cms-color-surface-hover);
  color: var(--cms-color-text);
  opacity: 1;
}
.cms-theme-modern .mms > .mm-toggle,
.cms-theme-modern .mms > .mm-toggle:hover {
  color: var(--cms-color-accent);
  opacity: 1;
}

.cms-theme-modern .taby {
  position: relative;
  display: flex;
  align-items: flex-start;
  gap: var(--cms-space-4);
  min-height: 48px;
  padding: var(--cms-space-3) var(--cms-space-5) var(--cms-space-2);
}

.cms-theme-modern #sajty {
  flex: 0 0 auto;
  margin-left: auto;
  gap: var(--cms-space-1);
  font-size: 14px;
}

.cms-theme-modern .cms-visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.cms-theme-modern .cms-omnisearch {
  position: absolute;
  z-index: 2000;
  top: calc(-64px - .4em);
  right: 0;
  left: var(--cms-space-4);
  width: auto;
  margin: var(--cms-space-3) 0 calc(var(--cms-space-2) + .4em);
}

.cms-theme-modern .cms-omnisearch-control {
  display: flex;
  align-items: center;
  min-height: 34px;
  padding: 0 9px;
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  background: rgba(255, 255, 255, .82);
  box-shadow: 0 1px 2px rgba(44, 40, 32, .06);
}

.cms-theme-modern .cms-omnisearch-control:focus-within {
  background: #fff;
  border-color: var(--cms-color-primary);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cms-color-accent) 14%, transparent);
}

.cms-theme-modern .cms-omnisearch-control:focus-within .cms-omnisearch-icon {
  border-color: var(--cms-color-primary);
}

.cms-theme-modern .cms-omnisearch-control:focus-within .cms-omnisearch-icon::after {
  background: var(--cms-color-primary);
}

.cms-theme-modern .cms-omnisearch-icon {
  width: 14px;
  height: 14px;
  margin-right: 9px;
  border: 2px solid var(--cms-color-muted);
  border-radius: 50%;
}

.cms-theme-modern .cms-omnisearch-icon::after {
  content: '';
  display: block;
  width: 6px;
  height: 2px;
  margin: 10px 0 0 9px;
  transform: rotate(45deg);
  background: var(--cms-color-muted);
}

.cms-theme-modern #cms-omnisearch-input {
  flex: 1 1 auto;
  min-width: 80px;
  height: 32px;
  padding: 0;
  border: 0;
  outline: 0;
  background: transparent;
  color: var(--cms-color-text);
  font: inherit;
}

.cms-theme-modern #cms-omnisearch-input:focus {
  border: 0;
  outline: 0;
  box-shadow: none;
}

/* Placeholder text - italic and muted, like an inactive row (tr[data-row-state="protected"]/
   .inactive td below), so anything shown this way reads as a hint rather than a value already
   sitting in the field. */
.cms-theme-modern #cms-omnisearch-input::placeholder,
.cms-theme-modern .ajaxtable-filter input::placeholder {
  color: var(--cms-color-muted);
  font-style: italic;
  font-weight: 400;
}

/* A shortcut, spelled out, next to the field it reaches - the persistent kind of hint, as
   opposed to cms_ui_flash_hint's one-time nudge. Shared between omnisearch's kbd and the
   first ajaxtable filter's own pair (jquery-ajaxtable.js), so both read as one system. */
.cms-theme-modern .cms-hotkey-badge {
  display: inline-flex;
  align-items: center;
  padding: 1px 5px;
  border: 1px solid var(--cms-color-border);
  border-radius: 4px;
  background: rgba(0, 0, 0, .04);
  color: var(--cms-color-muted);
  font: 11px/1.4 -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  white-space: nowrap;
}

.cms-theme-modern .cms-omnisearch-control .cms-hotkey-badge {
  margin-left: 6px;
}

/* .ajaxtable-filter-hints lays these over the input's own right edge (master.css does the
   grid placement) rather than sharing a row with it, so they run smaller than the base badge
   to leave room inside a filter box roughly a third the width of the omnisearch control. */
.cms-theme-modern .ajaxtable-filter-hints .cms-hotkey-badge {
  padding: 0 4px;
  font-size: 10px;
  background: var(--cms-color-canvas);
}

.cms-theme-modern .cms-omnisearch-panel {
  position: absolute;
  z-index: 2147483600;
  top: calc(100% + 6px);
  left: 0;
  width: min(620px, calc(100vw - 32px));
  max-height: min(520px, calc(100vh - 150px));
  overflow-y: auto;
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-panel);
  background: var(--cms-color-canvas);
  box-shadow: 0 16px 42px rgba(44, 40, 32, .22);
}

.cms-theme-modern .cms-omnisearch-status {
  padding: 9px 12px;
  color: var(--cms-color-muted);
  font-size: 12px;
}

.cms-theme-modern .cms-omnisearch-status:empty {
  display: none;
}

.cms-theme-modern .cms-omnisearch-result {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) auto;
  width: 100%;
  min-height: 44px;
  padding: 7px 10px;
  border: 0;
  border-top: 1px solid var(--cms-color-border);
  border-radius: 0;
  background: var(--cms-color-canvas);
  color: var(--cms-color-text);
  text-align: left;
  cursor: pointer;
}

.cms-theme-modern .cms-omnisearch-result:hover,
.cms-theme-modern .cms-omnisearch-result.is-selected {
  background: var(--cms-color-surface-hover);
  color: var(--cms-color-text);
}

.cms-theme-modern .cms-omnisearch-result:hover .cms-omnisearch-result-name,
.cms-theme-modern .cms-omnisearch-result.is-selected .cms-omnisearch-result-name {
  color: var(--cms-color-text);
}

.cms-theme-modern .cms-omnisearch-result-name {
  overflow: hidden;
  font-weight: 600;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cms-theme-modern .cms-omnisearch-result-mark {
  display: inline-flex;
  font-weight: 500;
  min-height: 18px;
  margin-left: 0.5em;
  padding: 0px 5px 0px;
  border-radius: 999px;
  background: var(--cms-color-surface-hover);
  color: var(--cms-color-muted);
  font-size: 11px;
  line-height: 18px;
}

.cms-theme-modern .cms-omnisearch-result-marks {
  justify-self: end;
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-top: 2px;
  margin-right: -1px;
}

.cms-theme-modern .cms-omnisearch-result-detail,
.cms-theme-modern .cms-omnisearch-result-path {
  color: var(--cms-color-muted);
  font-size: 12px;
}

.cms-theme-modern .cms-omnisearch-result-detail {
  margin-left: 14px;
  text-align: right;
  padding-top: 0px;
  padding-bottom: 3px;
  align-self: flex-start;
}

.cms-theme-modern .cms-omnisearch-result-path {
  /* grid-column: 1 / -1; */
  margin-top: 3px;
  font-family: monospace;
}

.cms-theme-modern #sajty > div {
  padding: 7px 10px;
  border-radius: var(--cms-radius-control);
}

.cms-theme-modern #sajty > div:hover {
  background: rgba(255, 255, 255, .7);
}

.cms-theme-modern .canvas {
  padding: 0 var(--cms-space-5) var(--cms-space-5) var(--cms-space-4);
  /* .left's own reserved strip (64px + .4em) minus .taby's actual rendered height above
     it - so .canvas-content's top lands level with .left-nav's, while .taby itself
     stays where it already was: level with the search bar. Measured live, not derived
     from .taby's own CSS (its flex/min-height combination does not simply add up). */
  margin-top: calc(6px + .4em);
}

.cms-theme-modern .canvas-content {
  /* The fallback is the old constant, for the moment before the first measurement and for
     any page that never runs the panel's JS. 120px was never this card's real top offset -
     the header, .canvas's margin-top above and .canvas's padding-bottom below are three
     moving numbers (see .left, and the note there), and this was a fourth that did not
     follow them, so the card ran off the bottom of the screen. cms_ui_publish_viewport_fill()
     measures it instead. */
  min-height: var(--cms-viewport-fill, calc(100vh - 120px));
  padding: var(--cms-space-5);
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-panel);
  background: var(--cms-color-canvas);
  box-shadow: var(--cms-shadow-panel);
}

.cms-theme-modern .entry-head {
  align-items: center;
  margin-bottom: var(--cms-space-2);
}

.cms-theme-modern .entry-head h1 {
  margin: 0;
  color: var(--cms-color-primary);
  font-family: var(--cms-font-family);
  font-size: 24px;
  font-weight: 600;
  letter-spacing: -.02em;
}

.cms-theme-modern .entry-head .title {
  display: flex;
  align-items: center;
  min-width: 0;
}

.cms-theme-modern .cms-entry-pills {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 6px;
  margin-left: 10px;
  padding-left: 0;
}

.cms-theme-modern .metadata,
.cms-theme-modern .metadata > div {
  white-space: nowrap;
}

.cms-theme-modern .breadcrumbs {
  margin-bottom: var(--cms-space-4);
  padding: var(--cms-space-2) var(--cms-space-3);
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-surface);
  color: var(--cms-color-muted);
}

.cms-theme-modern #breadcrumb,
.cms-theme-modern #breadcrumb a {
  color: var(--cms-color-muted);
  font-size: 13px;
}

.cms-theme-modern #breadcrumb .currentItem {
  color: var(--cms-color-text);
  font-weight: 600;
}

.cms-theme-modern .metadata {
  color: var(--cms-color-muted);
  font-size: 12px;
}

.cms-theme-modern .metadata strong {
  color: var(--cms-color-text);
}

/* Two siblings, not three: the name/slug pair stacks in its own box on the left,
   buttons held to the right, vertically centered against the pair as a whole. Before
   showslug existed this row was a plain flex pair and fit easily; a third top-level
   child made every row wrap onto itself once "Adres strony (slug)" ran out of room,
   which is what made it feel busy - stacking name-over-slug inside one wrapper
   restores a two-child row. */
.cms-theme-modern .top-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  column-gap: var(--cms-space-5);
  margin-bottom: var(--cms-space-4);
}

/* CSS tables, not flex or grid: the name row and the slug row are independent flex
   containers (two separate .item-name divs), so nothing about ordinary layout keeps
   their labels the same width - "Nazwa elementu" and "Adres strony (slug)" differ, so
   the inputs after them landed at different x-offsets. A shared table body is the one
   layout mode where two sibling rows' cells size against each other automatically:
   the label column always widens to fit whichever label is longer, in either row, with
   no fixed pixel guess to keep in sync by hand - and white-space: nowrap on the label
   cell means a longer translation still never wraps, it just widens its own column. */
.cms-theme-modern .top-row .item-name-stack {
  display: table;
  border-collapse: collapse;
  min-width: 0;
}

.cms-theme-modern .top-row .item-name {
  display: table-row;
  line-height: normal;
}

.cms-theme-modern .top-row .item-name > .name-label {
  display: table-cell;
  padding-right: var(--cms-space-2);
  white-space: nowrap;
  vertical-align: middle;
  width: 1%;
}

.cms-theme-modern .top-row .item-name > span {
  display: table-cell;
  vertical-align: middle;
}

/* Pulled out of item-name-stack rather than left as a table-cell inside it: a table
   cell only centers against its own row, but this pill needs to sit level with the
   save button - i.e. against the name+slug pair as a whole. entry-identity is the
   plain flex row that makes that possible; margin-left is reset because its own gap
   already provides the (deliberately roomy, not huge) spacing from the stack. */
.cms-theme-modern .top-row .entry-identity {
  display: flex;
  align-items: center;
  min-width: 0;
  gap: var(--cms-space-4);
}

.cms-theme-modern .top-row .entry-identity .cms-entry-pills {
  margin-left: 0;
}

.cms-theme-modern .top-row .item-name.t-slug-visible > * {
  padding-top: var(--cms-space-1);
}

.cms-theme-modern #t-name {
  width: 260px;
}

/* The slug row: a permalink line under the title, not a second title - smaller,
   unbolded, muted label, so "Nazwa strony" keeps the visual weight and "Adres strony
   (slug)" reads as the detail under it. */
.cms-theme-modern .top-row .item-name.t-slug-visible .name-label {
  font-size: 12px;
  font-weight: 600;
  color: var(--cms-color-muted);
}

.cms-theme-modern .top-row .item-name.t-slug-visible input {
  height: 30px;
  max-width: 220px;
  font-size: 13px;
}

/* Tabs */
.cms-theme-modern .cms-tab-strip {
  gap: var(--cms-space-1);
  margin-bottom: var(--cms-space-3);
  border-bottom: 1px solid var(--cms-color-border);
}

.cms-theme-modern #omenu {
  gap: 2px;
}

.cms-theme-modern .otab,
.cms-theme-modern .tab_a,
.cms-theme-modern .tab_p {
  height: 34px;
  min-height: 34px;
  margin-left: 0;
  padding: 0;
  border: 1px solid transparent;
  border-bottom: 0;
  border-radius: var(--cms-radius-control) var(--cms-radius-control) 0 0;
  background: transparent;
  color: var(--cms-color-muted);
}

.cms-theme-modern .otab > div,
.cms-theme-modern .tab_a > div,
.cms-theme-modern .tab_p > div {
  display: flex;
  align-items: center;
  height: 33px;
  padding: 0 12px;
  background: none;
  color: inherit;
  font-size: 13px;
  font-weight: 600;
}

.cms-theme-modern .tab_a {
  border-color: var(--cms-color-border);
  background: var(--cms-color-canvas);
  color: var(--cms-color-primary);
}

.cms-theme-modern .tab_p:hover {
  background: var(--cms-color-surface-hover);
  color: var(--cms-color-accent);
}

.cms-theme-modern .cms-tab-scroll {
  align-self: flex-end;
  width: 34px;
  height: 34px;
  min-height: 34px;
  padding: 0;
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-canvas);
  color: var(--cms-color-primary);
}

/* Forms and actions. Deliberately no width rules for general fields.
 *
 * The :not(.input_button) matters more than it looks. A button rendered as
 * <input type="button"> otherwise matches this selector, whose four :not() arguments push it
 * to a specificity no button rule below can reach - so the same button came out looking like
 * a text field wearing button colours, and looked different again when rendered as <button>.
 * Buttons are covered by the .input_button branch of this very selector, so excluding them
 * from the input branch changes nothing except which later rule is allowed to win. */
.cms-theme-modern input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="image"]):not(.input_button),
.cms-theme-modern select,
.cms-theme-modern button,
.cms-theme-modern .input_button,
.cms-theme-modern .formSubmit {
  min-height: var(--cms-control-height);
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  font: 500 14px/1.2 var(--cms-font-family);
}

/* Text-entry geometry and colours - deliberately not applied to buttons. */
.cms-theme-modern input:not([type="checkbox"]):not([type="radio"]):not([type="file"]):not([type="image"]):not(.input_button),
.cms-theme-modern select {
  padding: 6px 10px;
  background-color: var(--cms-color-canvas);
  color: var(--cms-color-text);
}

/* The one exception to the padding above: filterInputs[0] leaves room on its right for the
   badge pair overlaid there (master.css does the grid placement). The generic rule two blocks
   up is deliberately high-specificity (five :not() clauses) so no later rule outranks it by
   accident - !important is the only way to carve out this one narrow case without touching
   that rule's own reach. */
.cms-theme-modern .ajaxtable-filter-has-hints > input {
  padding-right: 118px !important;
}

.cms-theme-modern textarea {
  padding: var(--cms-space-2) var(--cms-space-3);
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-canvas);
  color: var(--cms-color-text);
  font: 14px/1.45 var(--cms-font-family);
}

.cms-theme-modern input:hover,
.cms-theme-modern select:hover,
.cms-theme-modern textarea:hover {
  border-color: var(--cms-color-border-strong);
}

.cms-theme-modern input:focus,
.cms-theme-modern select:focus,
.cms-theme-modern textarea:focus {
  border-color: var(--cms-color-focus);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cms-color-accent) 14%, transparent);
  outline: 0;
}

/* An <input type="button"> is permanently :read-only as far as CSS is concerned - it is not
   an editable field - so without the exclusion every such button would be painted as a greyed
   out one. */
.cms-theme-modern input:read-only:not(.input_button),
.cms-theme-modern .input_readonly {
  background: var(--cms-color-surface);
  color: var(--cms-color-muted);
}

.cms-theme-modern input:disabled,
.cms-theme-modern select:disabled,
.cms-theme-modern textarea:disabled,
.cms-theme-modern button:disabled {
  cursor: not-allowed;
  background: var(--cms-color-surface);
  color: var(--cms-color-muted);
}

.cms-theme-modern .fielderror,
.cms-theme-modern [aria-invalid="true"] {
  border-color: var(--cms-color-danger) !important;
}

.cms-theme-modern .fielderrortxt,
.cms-theme-modern .field-validation {
  color: var(--cms-color-danger);
  font-size: 12px;
  font-weight: 600;
}

/* background-COLOR, not the `background` shorthand. These two rules mean "the default
   button is accent green", but the shorthand also resets background-image, -repeat,
   -position and -size - so every icon button below had to restate all of them in every
   state, and each state that forgot one produced its own artefact: no icon (image reset),
   an icon sliding across the button on hover (position reset, animated by master.css's
   `transition: all`), and an icon tiled across the whole background (repeat reset). Naming
   the property that is actually meant removes the entire class of them. */
.cms-theme-modern button,
.cms-theme-modern .input_button,
.cms-theme-modern .formSubmit,
.cms-theme-modern .input_file_but {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 7px 12px;
  border-color: var(--cms-color-accent);
  background-color: var(--cms-color-accent);
  color: #fff;
  cursor: pointer;
  font-weight: 600;
}

.cms-theme-modern button:hover,
.cms-theme-modern .input_button:hover,
.cms-theme-modern .formSubmit:hover,
.cms-theme-modern .input_file_but:hover {
  border-color: var(--cms-color-accent-hover);
  background-color: var(--cms-color-accent-hover);
  color: #fff;
}

/* The one element that was relying on the shorthand above to drop an icon: master.css
   gives the "Usuń" button beside an uploaded file a black bin on a transparent ground,
   which this theme paints accent green over. Stated rather than left to a side effect, so
   the button looks exactly as it did - putting the icon back on a green button is a design
   decision and not a thing to change while fixing something else. */
.cms-theme-modern .delete-link {
  background-image: none;
  padding-left: 12px;
}

/* The `secret` state line and the ordinary field note, on the theme's own tokens rather
   than the fixed greys of master.css. */
.cms-theme-modern .file-state,
.cms-theme-modern .secret-state,
.cms-theme-modern .field-note {
  color: var(--cms-color-muted);
  font-size: var(--cms-font-size-small, 12px);
}
.cms-theme-modern .secret-empty,
.cms-theme-modern .file-empty {
  color: var(--cms-color-muted);
}
.cms-theme-modern .field-count {
  color: var(--cms-color-muted);
  font-size: var(--cms-font-size-small, 12px);
  opacity: 0.85;
}
.cms-theme-modern .field-count-full {
  color: var(--cms-color-text);
  font-weight: 600;
  opacity: 1;
}
.cms-theme-modern .secret-nokey {
  color: var(--cms-color-warning, #9a6b00);
}
.cms-theme-modern .secret-pending-delete,
.cms-theme-modern .file-pending-delete,
.cms-theme-modern .file-pending-delete a {
  color: var(--cms-color-danger);
}

.cms-theme-modern .item-update,
.cms-theme-modern .button-login {
  min-height: var(--cms-control-height);
  padding: 7px 12px 7px 36px;
  border: 1px solid var(--cms-color-accent);
  border-radius: var(--cms-radius-control);
  background-color: var(--cms-color-accent);
  color: #fff;
  font-size: 14px;
}

.cms-theme-modern .item-update,
.cms-theme-modern .t-preview-visible {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  line-height: 18px;
  background-position: 11px center;
}

.cms-theme-modern .item-update:hover,
.cms-theme-modern .button-login:hover {
  border-color: var(--cms-color-accent-hover);
  background-color: var(--cms-color-accent-hover);
  color: #fff;
}

/* "Podgląd" is the secondary of the pair it sits in - the primary next to it is "Zapisz
   zmiany" - so it is the one on a white ground with a dark label. Same shape as
   .item-update otherwise, and like it, it names its icon once. */
.cms-theme-modern .t-preview-visible {
  min-height: var(--cms-control-height);
  padding: 7px 12px 7px 36px;
  border: 1px solid var(--cms-color-border-strong);
  border-radius: var(--cms-radius-control);
  background-color: #fff;
  background-image: url("../images/preview.svg");
  background-repeat: no-repeat;
  background-size: 19px auto;
  color: var(--cms-color-text);
  font-size: 14px;
  /* master.css asks this button for `transition: all .3s`, and "all" covers properties
     that have no business animating - background-position among them. Only what differs
     between the two states. */
  transition: background-color .2s ease, border-color .2s ease, color .2s ease;
}

.cms-theme-modern .t-preview-visible:hover {
  border-color: var(--cms-color-primary);
  background-color: var(--cms-color-surface);
  color: var(--cms-color-primary);
}

.cms-theme-modern .item-update {
  background-image: url("../images/save.svg");
  background-repeat: no-repeat;
  background-size: 19px auto;
}

.cms-theme-modern .delete-item,
.cms-theme-modern .btn-delete {
  border-color: var(--cms-color-danger);
  background-color: var(--cms-color-danger);
  border-radius: var(--cms-radius-control);
  color: #fff;
}

.cms-theme-modern .delete-item {
  display: flex;
  align-items: center;
  height: var(--cms-control-height);
  min-height: var(--cms-control-height);
  padding: 0;
  background-image: none;
  line-height: 18px;
}

.cms-theme-modern .item-buttons,
.cms-theme-modern .update-preview {
  align-items: center;
}

.cms-theme-modern .t-new-sibling-visible,
.cms-theme-modern .t-new-child-visible,
.cms-theme-modern .t-new-sibling-visible > div,
.cms-theme-modern .t-new-child-visible > div {
  display: flex;
  align-items: center;
}

.cms-theme-modern .t-new-sibling-visible > div,
.cms-theme-modern .t-new-child-visible > div {
  height: var(--cms-control-height);
  min-height: var(--cms-control-height);
  overflow: hidden;
  border-radius: var(--cms-radius-control);
}

.cms-theme-modern .t-new-sibling-visible > div > a,
.cms-theme-modern .t-new-child-visible > div > a {
  display: inline-flex;
  align-items: center;
  height: var(--cms-control-height);
  padding: 0 11px;
  color: #fff;
  line-height: 18px;
}

.cms-theme-modern .t-new-sibling-visible .addleft,
.cms-theme-modern .t-new-sibling-visible .addright,
.cms-theme-modern .t-new-child-visible .addleft,
.cms-theme-modern .t-new-child-visible .addright {
  padding: 0;
  font-size: 14px;
  line-height: 18px;
}

.cms-theme-modern .t-new-sibling-visible .addleft,
.cms-theme-modern .t-new-child-visible .addleft {
  margin-right: 4px;
}

.cms-theme-modern .delete-item,
.cms-theme-modern .item-update,
.cms-theme-modern .t-preview-visible {
  height: var(--cms-control-height);
  max-height: var(--cms-control-height);
}

.cms-theme-modern .delete-item .btn-delete {
  display: inline-flex;
  align-items: center;
  height: 100%;
  padding: 0 10px 0 32px;
  border: 0;
  background-color: transparent;
  background-image: url("../images/delete.svg");
  background-position: 10px center;
  background-repeat: no-repeat;
  background-size: 14px auto;
  line-height: 18px;
}

.cms-theme-modern .delete-item .btn-delete:hover {
  background-color: transparent;
  background-image: url("../images/delete.svg");
}

.cms-theme-modern .cl_ftd .input_button {
  border: 1px solid var(--cms-color-border-strong);
  background: var(--cms-color-canvas);
  box-shadow: inset 4px 0 0 var(--cms-color-accent);
  color: var(--cms-color-text);
  transition: background-color .18s ease, border-color .18s ease, box-shadow .18s ease, color .18s ease;
}

.cms-theme-modern .cl_ftd .input_button:hover,
.cms-theme-modern .cl_ftd .input_button:focus-visible {
  border-color: var(--cms-color-accent-hover);
  background: var(--cms-color-surface-hover);
  box-shadow: inset 6px 0 0 var(--cms-color-accent-hover);
  color: var(--cms-color-accent-hover);
}

.cms-theme-modern .cl_ftd .input_button.del {
  border-color: var(--cms-color-danger);
  box-shadow: inset 4px 0 0 var(--cms-color-danger);
  color: var(--cms-color-danger);
}

.cms-theme-modern .cl_ftd .input_button.del:hover,
.cms-theme-modern .cl_ftd .input_button.del:focus-visible {
  background: #fcecef;
  box-shadow: inset 6px 0 0 var(--cms-color-danger);
  color: var(--cms-color-danger);
}

.cms-theme-modern .delete-item:hover,
.cms-theme-modern .btn-delete:hover {
  background-color: var(--cms-color-danger-hover);
  color: #fff;
}

/* master.css's own 4px, left over from the pre-theme radius scale everything else here
   moved off. */
.cms-theme-modern .cms-ui-progress {
  border-radius: var(--cms-radius-control);
}

.cms-theme-modern .cl_ftrs {
  padding: var(--cms-space-4) var(--cms-space-4) 0;
  border-color: var(--cms-color-border);
  border-radius: var(--cms-radius-panel) var(--cms-radius-panel) 0 0;
  background: var(--cms-color-surface);
}

.cms-theme-modern .cl_fss {
  padding-bottom: var(--cms-space-3);
  border-color: var(--cms-color-border-strong);
  color: var(--cms-color-primary);
  font-size: 16px;
}

.cms-theme-modern .cl_ftr {
  padding: var(--cms-space-3) var(--cms-space-4) 0;
  border-color: var(--cms-color-border);
}

.cms-theme-modern .cl_fth {
  flex: 0 0 200px;
  width: 200px;
  padding: 0px var(--cms-space-4) var(--cms-space-3) 0;
  border-color: var(--cms-color-border);
  color: var(--cms-color-text);
  font-size: 13px;
  font-weight: 600;
}

.cms-theme-modern .cl_fth.last,
.cms-theme-modern .cl_ftd.last {
  border-bottom: none;
  margin-bottom: calc(-1 * var(--cms-space-2));
}

.cms-theme-modern .cl_ftd {
  width: calc(100% - 200px);
  padding: 0 0 var(--cms-space-3) var(--cms-space-4);
  border-color: var(--cms-color-border);
}

.cms-theme-modern .cl_ftre {
  height: 12px;
  margin-bottom: var(--cms-space-4);
  border-color: var(--cms-color-border);
  border-radius: 0 0 var(--cms-radius-panel) var(--cms-radius-panel);
}

/* Tables and feedback */
.cms-theme-modern table {
  color: var(--cms-color-text);
  font-family: var(--cms-font-family);
  font-size: 13px;
  background-color: none;
}

.cms-theme-modern th, .cms-theme-modern td {
  border-color: var(--cms-color-border);
  background-color: none;
}

.cms-theme-modern table.dbe,
.cms-theme-modern .dbe_table,
.cms-theme-modern .ajaxtable {
  border-collapse: separate;
  border-spacing: 0;
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-panel);
  background: var(--cms-color-canvas);
}

.cms-theme-modern table.dbe th,
.cms-theme-modern .dbe_table th,
.cms-theme-modern .ajaxtable th,
.cms-theme-modern .tablehead {
  position: sticky;
  top: 0;
  z-index: 1;
  padding: 9px 10px;
  border-bottom: 1px solid var(--cms-color-border);
  background: var(--cms-color-surface);
  color: var(--cms-color-primary);
  font-weight: 600;
  text-align: left;
}

.cms-theme-modern table.dbe td,
.cms-theme-modern .dbe_table td,
.cms-theme-modern .ajaxtable td {
  height: 44px;
  padding: 4px 10px;
  border-bottom: 1px solid var(--cms-color-border);
  white-space: nowrap;
}

.cms-theme-modern table.dbe tr:hover td,
.cms-theme-modern .dbe_table tr:hover td,
.cms-theme-modern .ajaxtable tr:hover td {
  background: var(--cms-color-surface-hover);
}

.cms-theme-modern .ajaxtable .stdtable tbody tr:not(.ajaxtable-spacer) {
  height: 44px;
}

/* A row that goes somewhere says so before it is clicked. The hover highlight above is
 * shared by every row in every list, so on its own it reads as "this row is under the
 * pointer" rather than "this row is a link". */
.cms-theme-modern .ajaxtable tr.ajaxtable-linked {
  cursor: pointer;
}
.cms-theme-modern .ajaxtable tr.ajaxtable-linked:focus-visible {
  outline: 2px solid var(--cms-color-focus, currentColor);
  outline-offset: -2px;
}

/* Row actions in list tables.
 *
 * One rule for two render paths that had drifted apart: the built-in buttons are
 * <input type="button"> (DBE lists, panel users) and the declarative ones are <button>
 * (the site register). Each picked up a different mix of the generic control rules above -
 * inputs match the `input:not([type=checkbox])...` block, buttons do not - so the same
 * "Edytuj" came out chunky in one table and small and differently coloured in the next.
 * Every property that decides size and colour is therefore stated here rather than left to
 * the cascade, and both selectors are listed so neither element type can drift again.
 *
 * The look is the panel's ordinary button (.cl_ftd .input_button): a quiet outlined control
 * with an accent bar down its left edge, not the solid accent-filled block these used to be,
 * which shouted louder than the real actions on the screen. Smaller than a form button
 * because a table row is not a form. */

.cms-theme-modern tr[data-row-state="protected"] td {
  font-style: italic;
}

.cms-theme-modern tr[data-row-state="disabled"] td,
.cms-theme-modern .ajaxtable tr.inactive td {
  color:  var(--cms-color-muted);
}

.cms-theme-modern div.delete-file {
  margin-top: var(--cms-space-1);
}

.cms-theme-modern .cms-sgroup .cl_ftd button.delete-link,
.cms-theme-modern .ajaxtable .stdtable .actions .input_button,
.cms-theme-modern .stdtable .actions .input_button,
.cms-theme-modern .stdtable .actions button.ajaxtable-action {
  min-height: 26px;
  padding: 3px 10px;
  border: 1px solid var(--cms-color-border-strong);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-canvas);
  box-shadow: inset 3px 0 0 var(--cms-color-accent);
  color: var(--cms-color-text);
  font: 500 13px/1.2 var(--cms-font-family);
  /* master.css fades these to half opacity until the row is hovered. That was survivable on
     a solid block; on an outlined control it reads as disabled. */
  opacity: 1;
  transition: background-color .18s ease, border-color .18s ease, box-shadow .18s ease, color .18s ease;
}

/* They are appended with no whitespace between them, so nothing separates them by default. */
.cms-theme-modern .stdtable .actions .input_button + .input_button,
.cms-theme-modern .stdtable .actions .input_button + button.ajaxtable-action,
.cms-theme-modern .stdtable .actions button.ajaxtable-action + .input_button {
  margin-left: var(--cms-space-2);
}

.cms-theme-modern .stdtable .actions .input_button:hover,
.cms-theme-modern .stdtable .actions .input_button:focus-visible {
  border-color: var(--cms-color-accent-hover);
  background: var(--cms-color-surface-hover);
  box-shadow: inset 5px 0 0 var(--cms-color-accent-hover);
  color: var(--cms-color-accent-hover);
}

/* Destructive actions arrive as .del from the built-in path and .danger from the declarative
   one; both mean the same thing and must look the same. */
.cms-theme-modern .stdtable .actions .input_button.del,
.cms-theme-modern .stdtable .actions .input_button.danger {
  border-color: var(--cms-color-danger);
  box-shadow: inset 3px 0 0 var(--cms-color-danger);
  color: var(--cms-color-danger);
}

.cms-theme-modern .stdtable .actions .input_button.del:hover,
.cms-theme-modern .stdtable .actions .input_button.del:focus-visible,
.cms-theme-modern .stdtable .actions .input_button.danger:hover,
.cms-theme-modern .stdtable .actions .input_button.danger:focus-visible {
  border-color: var(--cms-color-danger);
  background: #fcecef;
  box-shadow: inset 5px 0 0 var(--cms-color-danger);
  color: var(--cms-color-danger);
}

.cms-theme-modern tr.inactive,
.cms-theme-modern .inactive-row {
  color: var(--cms-color-muted);
  background: var(--cms-color-surface);
}

.cms-theme-modern .ajaxtable tr.inactive:hover,
.cms-theme-modern .ajaxtable tr.inactive:hover td {
  background-color: var(--cms-color-surface-hover) !important;
}

.cms-theme-modern .ajaxtable-toolbar {
  margin: 0;
  padding: var(--cms-space-3);
  border-bottom: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-panel) var(--cms-radius-panel) 0 0;
  background: var(--cms-color-surface);
}

.cms-theme-modern .ajaxtable table.stdtable {
  margin-top: 0;
  margin-bottom: 0;
}

.cms-theme-modern div.advrel_box .advrel_area2 li {
    background-color: var(--cms-color-primary);
}

.cms-theme-modern div.advrel_box .advrel_area li {
    background-color: var(--cms-color-accent);
}


/* master.css's own zebra stripe (#f8f8f8) is a plain, undyed grey - the one colour in
   the table that never got a warm equivalent, which is what read as "doesn't match"
   next to an off-white .inactive row on one side and pure white on the other.
   --cms-color-surface sits only 4-8 units from --cms-color-canvas (both are near-white
   card tones), so mixing between them was imperceptible - the stripe needs a tone with
   real separation from white, short of the muted --cms-color-surface an .inactive row
   uses. --cms-color-page is that tone already: it is what distinguishes the app
   background from a white card elsewhere on the same screen. */
.cms-theme-modern .stdtable tr:nth-child(even) {
  background: var(--cms-color-page);
}

/* master.css's own tr:hover (#e5f6f3, a plain teal literal untied from the brand hue)
   loses to the rule above on even rows: both reach 3 classes + 1 type once
   .cms-theme-modern and .stdtable are counted, so it's source order that decides, and the
   nth-child(even) rule above sits later in this same file. Restated here, after it, so
   hover wins on every row regardless of parity, and pointed at --cms-color-surface-hover
   so it retints along with everything else when an installation picks its own hue. */
.cms-theme-modern .stdtable tr:hover {
  background: var(--cms-color-surface-hover);
}

.cms-theme-modern .ajaxtable-filter-controls {
  padding-top: var(--cms-space-1);
}

.cms-theme-modern .ajaxtable-more-filters,
.cms-theme-modern .ajaxtable-clear-filters {
  min-height: 30px;
  padding: 5px 10px;
  border: 1px solid var(--cms-color-border);
  background: var(--cms-color-canvas);
  color: var(--cms-color-muted);
}

.cms-theme-modern .ajaxtable-more-filters:hover,
.cms-theme-modern .ajaxtable-clear-filters:hover {
  border-color: var(--cms-color-accent);
  background: var(--cms-color-surface-hover);
  color: var(--cms-color-accent);
}

.cms-theme-modern td.actions a,
.cms-theme-modern .actioncell a {
  opacity: 1;
  border-radius: var(--cms-radius-control);
}

.cms-theme-modern td.actions a:hover,
.cms-theme-modern td.actions a:focus-visible,
.cms-theme-modern .actioncell a:hover,
.cms-theme-modern .actioncell a:focus-visible {
  background-color: var(--cms-color-surface-hover);
}

.cms-theme-modern .msg_ok,
.cms-theme-modern .msg_fail,
.cms-theme-modern .msg_info,
.cms-theme-modern .cms-ui-operation-unknown {
  padding: 10px 12px;
  border: 1px solid;
  border-radius: var(--cms-radius-control);
  text-align: left;
  font-weight: 600;
}

.cms-theme-modern .msg_ok {
  border-color: #a4d5be;
  background: #e8f6ef;
  color: #145b3e;
}

.cms-theme-modern .msg_fail {
  border-color: #e6aab1;
  background: #fcecef;
  color: #8d1d2a;
}

/* Info was rendered green, indistinguishable from success, so "pokazano stan zapisany"
   read as good news. Its own colour, and its own glyph from master.css. */
.cms-theme-modern .msg_info {
  border-color: #a8c4dd;
  background: #eaf2fa;
  color: #1c4a72;
}

.cms-theme-modern .input_file,
.cms-theme-modern .cms-native-uploader {
  padding: var(--cms-space-4);
  border: 1px dashed var(--cms-color-border-strong);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-surface);
}

.cms-theme-modern input[type="checkbox"],
.cms-theme-modern input[type="radio"] {
  accent-color: var(--cms-color-accent);
}

/* Legacy photo, graph and attachment templates. */
.cms-theme-modern .phototable,
.cms-theme-modern .photoadd-table {
  width: min(100%, 760px);
  margin: 0 0 var(--cms-space-3);
  padding: 0;
  overflow: hidden;
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-panel);
  border-spacing: 0;
  background: var(--cms-color-canvas);
  box-shadow: 0 1px 2px rgba(44, 40, 32, .05);
}

.cms-theme-modern .phototable td,
.cms-theme-modern .photoadd-table td {
  padding: var(--cms-space-3);
  border: 0;
  background: var(--cms-color-canvas);
  vertical-align: middle;
}

.cms-theme-modern .phototable tr + tr td {
  border-top: 1px solid var(--cms-color-border);
}

.cms-theme-modern .phototable .PLABEL,
.cms-theme-modern .phototable .LABEL,
.cms-theme-modern .phototable .DLABEL {
  color: var(--cms-color-primary);
  font-weight: 600;
}

.cms-theme-modern .phototable .PLINK > span {
  display: inline-flex !important;
  float: none !important;
  align-items: center;
  justify-content: center;
  margin: 0 var(--cms-space-3) var(--cms-space-2) 0 !important;
  padding: var(--cms-space-1) !important;
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-surface);
}

.cms-theme-modern .phototable .PMINI,
.cms-theme-modern .phototable .DIMAGE {
  max-width: 160px;
  max-height: 120px;
  border: 0;
  border-radius: 4px;
  object-fit: contain;
}

.cms-theme-modern .phototable .DESC {
  max-width: 100%;
  margin-left: 0 !important;
}

.cms-theme-modern .photo-actions {
  min-width: 132px;
  text-align: right;
}

.cms-theme-modern .photo-actions .SEQ {
  float: none;
  margin-bottom: var(--cms-space-2);
  padding: 0;
  color: var(--cms-color-muted);
  font-size: 12px;
  font-weight: 600;
}

.cms-theme-modern .media-action,
.cms-theme-modern .photo-add-action,
.cms-theme-modern #uploadFilesButton {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--cms-control-height);
  padding: 7px 11px;
  border: 1px solid var(--cms-color-border-strong);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-canvas);
  color: var(--cms-color-primary);
  cursor: pointer;
  font-weight: 600;
  transition: background-color .18s ease, border-color .18s ease, color .18s ease;
}

.cms-theme-modern .media-action:hover,
.cms-theme-modern .photo-add-action:hover,
.cms-theme-modern #uploadFilesButton:hover {
  border-color: var(--cms-color-accent);
  background: var(--cms-color-surface-hover);
  color: var(--cms-color-accent);
}

.cms-theme-modern .media-action-delete {
  border-color: #e2afb5;
  color: var(--cms-color-danger);
}

.cms-theme-modern .media-action-upload,
.cms-theme-modern .photo-add-action,
.cms-theme-modern #uploadFilesButton {
  border-color: var(--cms-color-accent);
  color: var(--cms-color-accent);
}

.cms-theme-modern #outerUploaderContainer {
  padding: var(--cms-space-3);
  border: 1px dashed var(--cms-color-border-strong);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-surface);
}

.cms-theme-modern #filenames {
  width: 100%;
  margin-top: var(--cms-space-3);
  border-collapse: collapse;
}

.cms-theme-modern #filenames th,
.cms-theme-modern #filenames td {
  padding: var(--cms-space-2) var(--cms-space-3);
  border-bottom: 1px solid var(--cms-color-border);
  text-align: left;
}

.cms-theme-modern .cms-native-uploader.cms-dragover {
  border-color: var(--cms-color-accent);
  background: var(--cms-color-surface-hover);
}

.cms-theme-modern .cms-empty-image,
.cms-theme-modern .advrel_box,
.cms-theme-modern .relation-box {
  border-color: var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-surface);
  color: var(--cms-color-muted);
}

/* The legacy relation picker used fixed 1000/470/440px dimensions. */
.cms-theme-modern div.advrel_box {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 44px minmax(0, 1fr);
  width: 100%;
  max-width: none;
  height: auto;
  min-height: 350px;
  padding-bottom: 1px;
  overflow: hidden;
}

.cms-theme-modern div.advrel_box > .clear {
  display: none;
}

.cms-theme-modern div.advrel_box .adv_side {
  float: none;
  width: auto;
  height: auto;
  min-width: 0;
}

.cms-theme-modern div.advrel_box .between_adv {
  float: none;
  width: 44px;
  height: auto;
}

.cms-theme-modern div.advrel_box .box {
  float: none;
  width: 100%;
  border-color: var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-surface);
}

.cms-theme-modern div.advrel_box ul.dlist,
.cms-theme-modern div.advrel_box ul.slist {
  float: none;
  width: auto;
  padding: var(--cms-space-2);
}

.cms-theme-modern div.advrel_box .box li {
  min-height: 32px;
  height: auto;
  margin-bottom: var(--cms-space-1);
  padding-top: 7px;
  padding-bottom: 7px;
  /* border: 1px solid rgba(44, 40, 32, .12); */
  border-radius: 5px;
  color: #fff;
  font-size: 13px;
  line-height: 16px;
}

.cms-theme-modern div.advrel_box .fright {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--cms-space-2);
  height: 51px;
  padding: var(--cms-space-2) 0;
}

.cms-theme-modern div.advrel_box .fright input {
  width: min(220px, 65%);
  margin: 0;
}

/* Component libraries: overrides only. */
.cms-theme-modern .choices {
  font-family: var(--cms-font-family);
  font-size: 14px;
}

.cms-theme-modern .choices__inner {
  min-height: var(--cms-control-height);
  padding: 5px 9px;
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-canvas);
  color: var(--cms-color-text);
  font-size: 14px;
}

.cms-theme-modern .choices.is-focused .choices__inner,
.cms-theme-modern .choices.is-open .choices__inner {
  border-color: var(--cms-color-focus);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--cms-color-accent) 14%, transparent);
}

.cms-theme-modern .choices__list--dropdown,
.cms-theme-modern .choices__list[aria-expanded] {
  border-color: var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  box-shadow: var(--cms-shadow-panel);
}

.cms-theme-modern .choices__item--choice.is-highlighted {
  background: var(--cms-color-surface-hover);
}

.cms-theme-modern .choices__item--selectable.is-highlighted,
.cms-theme-modern .choices__list--multiple .choices__item {
  border-color: var(--cms-color-accent);
  background: var(--cms-color-accent);
}

.cms-theme-modern .flatpickr-calendar {
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-panel);
  box-shadow: var(--cms-shadow-panel);
  font-family: var(--cms-font-family);
}

/* Flatpickr owns these controls; generic CMS form geometry must not leak in. */
.cms-theme-modern .flatpickr-calendar .flatpickr-months,
.cms-theme-modern .flatpickr-calendar .flatpickr-month,
.cms-theme-modern .flatpickr-calendar .flatpickr-current-month {
  min-height: 34px;
  padding: 0;
  border: 0;
  line-height: 34px;
}

/* One line, one font: flatpickr sets the month at 135% weight 300 and leaves the year at the
   input's own size, so the two read as different controls. Both inherit from here. */
.cms-theme-modern .flatpickr-calendar .flatpickr-current-month {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  font-family: var(--cms-font-family);
  font-size: 15px;
  font-weight: 500;
  color: var(--cms-color-text);
}

/* The month switchers: flatpickr draws each as a 34px box with 10px of padding around an
   inline SVG that the header's 34px line-height then drops to the bottom edge. Sized and
   centred like the year box, with the same rest/hover treatment as its arrows. */
.cms-theme-modern .flatpickr-calendar .flatpickr-months .flatpickr-prev-month,
.cms-theme-modern .flatpickr-calendar .flatpickr-months .flatpickr-next-month {
  top: 3px;
  width: 28px;
  height: 28px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--cms-radius-control);
  color: var(--cms-color-text);
  fill: currentColor;
  opacity: 0.6;
}

.cms-theme-modern .flatpickr-calendar .flatpickr-months .flatpickr-prev-month:hover,
.cms-theme-modern .flatpickr-calendar .flatpickr-months .flatpickr-next-month:hover {
  opacity: 1;
  color: var(--cms-color-text);
  background: var(--cms-color-border);
}

.cms-theme-modern .flatpickr-calendar .flatpickr-months .flatpickr-prev-month svg,
.cms-theme-modern .flatpickr-calendar .flatpickr-months .flatpickr-next-month svg,
.cms-theme-modern .flatpickr-calendar .flatpickr-months .flatpickr-prev-month:hover svg,
.cms-theme-modern .flatpickr-calendar .flatpickr-months .flatpickr-next-month:hover svg {
  display: block;
  width: 14px;
  height: 14px;
  fill: currentColor;
}

.cms-theme-modern .flatpickr-calendar .flatpickr-monthDropdown-months,
.cms-theme-modern .flatpickr-calendar input.cur-year {
  width: auto !important;
  height: auto !important;
  min-height: 0 !important;
  margin: 0 !important;
  padding: 0 0.5ch !important;
  border: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  line-height: inherit !important;
  font-family: inherit !important;
  font-size: inherit !important;
  font-weight: inherit !important;
  color: inherit !important;
}

/* The year box. Flatpickr draws its two year steppers as empty spans sized 50% of the
   wrapper, so a "height: auto" here left them 0px tall - a triangle floating above the
   header with nothing to click on - and the "width: auto" the input shares with the month
   dropdown let the year run far past its box. The box gets the month dropdown's height,
   the input a width of four digits plus the room the arrows take, and the arrows a real
   hit area, faintly visible until hovered so that they can be found. */
.cms-theme-modern .flatpickr-calendar .numInputWrapper {
  position: relative;
  display: inline-block;
  width: auto;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: var(--cms-radius-control);
  overflow: hidden;
  background: transparent;
  line-height: 28px;
}

.cms-theme-modern .flatpickr-calendar .numInputWrapper:hover {
  background: var(--cms-color-surface-hover);
}

.cms-theme-modern .flatpickr-calendar .numInputWrapper input.cur-year {
  display: block !important;
  box-sizing: content-box !important;
  width: 4.4ch !important;
  height: 28px !important;
  padding: 0 24px 0 0.5ch !important;
  line-height: 28px !important;
}

.cms-theme-modern .flatpickr-calendar .numInputWrapper span {
  position: absolute;
  right: 0;
  width: 24px;
  height: 50%;
  padding: 0;
  border: 0;
  opacity: 0.6;
  background: transparent;
  cursor: pointer;
}

.cms-theme-modern .flatpickr-calendar .numInputWrapper:hover span {
  opacity: 0.8;
}

.cms-theme-modern .flatpickr-calendar .numInputWrapper span:hover {
  opacity: 1;
  background: var(--cms-color-border);
}

.cms-theme-modern .flatpickr-calendar .numInputWrapper span.arrowUp {
  top: 0;
}

.cms-theme-modern .flatpickr-calendar .numInputWrapper span.arrowDown {
  top: 50%;
}

.cms-theme-modern .flatpickr-calendar .numInputWrapper span:after {
  left: 50%;
  top: 50%;
  margin: -2px 0 0 -4px;
}

.cms-theme-modern .flatpickr-calendar .numInputWrapper span.arrowUp:after {
  border-bottom-color: currentColor;
}

.cms-theme-modern .flatpickr-calendar .numInputWrapper span.arrowDown:after {
  border-top-color: currentColor;
}

.cms-theme-modern .flatpickr-calendar .flatpickr-weekdays,
.cms-theme-modern .flatpickr-calendar .flatpickr-days {
  clear: both;
}

.cms-ui-confirm[hidden],
.cms-user-popover[hidden],
.cms-entry-status[hidden] {
  display: none !important;
}

.cms-ui-confirm {
  position: fixed;
  z-index: 250000;
  inset: 0;
  display: grid;
  place-items: center;
}

.cms-ui-confirm-backdrop {
  position: absolute;
  inset: 0;
  background: rgb(15 23 42 / 55%);
}

.cms-ui-confirm-dialog {
  position: relative;
  width: min(440px, calc(100vw - 32px));
  padding: 24px;
  border-radius: var(--cms-radius-panel);
  background: var(--cms-color-surface);
  box-shadow: var(--cms-shadow-panel);
}

/* THE BLANK LINE IN A CONFIRMATION IS MEANT. These messages were written for alert(), which
   honours "\n\n", and most of them use it to put the consequence on its own line - "Plik zniknie
   po zapisaniu formularza", "Po zapisaniu formularza wartości nie da się odzyskać". The dialog
   sets them with textContent, where a newline is ordinary whitespace, so all of that arrived as
   one run-on sentence and the warning was buried in the middle of it.

   pre-line rather than splitting the text into <p> elements, because textContent is what keeps
   this safe: the strings pass through __() and some are built by concatenation, and the dialog is
   not a place to start accepting markup. */
#cms-ui-confirm-message {
  white-space: pre-line;
}

.cms-ui-confirm-actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
}

.cms-ui-confirm-danger .cms-ui-confirm-accept {
  border-color: #b42318;
  background: #b42318;
  color: #fff;
}

/* Standing-message dialog: shares the confirm shell; the body is the panel's one
   deliberate HTML door, so give its markup breathing room. */
.cms-ui-standing-body {
  margin: var(--cms-space-3) 0 var(--cms-space-4);
}

.cms-ui-standing-body p {
  margin: 0 0 var(--cms-space-2);
}

.cms-ui-standing-body p:last-child {
  margin-bottom: 0;
}

.cms-ui-standing-cta {
  border-color: var(--cms-color-primary);
  background: var(--cms-color-primary);
  color: #fff;
}

.cms-ui-standing-cta:hover {
  border-color: var(--cms-color-primary-hover);
  background: var(--cms-color-primary-hover);
}

.cms-ui-standing-danger h2 {
  color: var(--cms-color-danger);
}

/* PHP diagnostics carried in the payload. Development only: the server omits the key
   when display_errors is off, so none of this is ever reachable in production. */
.cms-ui-diagnostics {
  position: fixed;
  z-index: 10000;
  right: 16px;
  bottom: 16px;
  display: flex;
  max-width: 420px;
  align-items: center;
  gap: 10px;
  padding: 10px 12px;
  border: 1px solid #d9a441;
  border-radius: var(--cms-radius-control);
  background: #fff8e8;
  box-shadow: var(--cms-shadow-panel);
  font-size: 13px;
}

/* When the "operation unknown" banner is also up, this one is lifted clear of it by
   cms_ui_diagnostics_reposition(), which measures that banner rather than guessing: CSS
   can neither observe another element's visibility nor its wrapped height. The corner
   offset above is the resting position and the one that applies on its own. */

.cms-ui-diagnostics-fatal {
  border-color: #b42318;
  background: #fdf1f0;
}

.cms-ui-diagnostics-summary {
  flex: 1;
}

.cms-ui-diagnostics-dismiss {
  border: 0;
  background: none;
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.cms-ui-diagnostics-log {
  position: fixed;
  z-index: 250001;
  inset: 0;
  display: grid;
  place-items: center;
}

.cms-ui-diagnostics-log[hidden] {
  display: none !important;
}

.cms-ui-diagnostics-dialog {
  position: relative;
  display: flex;
  width: min(780px, calc(100vw - 32px));
  max-height: min(70vh, 720px);
  flex-direction: column;
  padding: 24px;
  border-radius: var(--cms-radius-panel);
  background: var(--cms-color-surface);
  box-shadow: var(--cms-shadow-panel);
}

.cms-ui-diagnostics-body {
  overflow: auto;
  flex: 1;
  margin: 12px 0;
}

.cms-ui-diagnostics-item {
  padding: 8px 10px;
  border-left: 3px solid #d9a441;
  margin-bottom: 8px;
  background: var(--cms-color-canvas);
}

.cms-ui-diagnostics-item.cms-ui-diagnostics-fatal {
  border-left-color: #b42318;
}

.cms-ui-diagnostics-item-head {
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: .06em;
  opacity: .75;
}

.cms-ui-diagnostics-item-message {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace;
  font-size: 12px;
  overflow-wrap: anywhere;
}

.cms-ui-diagnostics-item-where {
  margin-top: 2px;
  font-size: 11px;
  opacity: .7;
  overflow-wrap: anywhere;
}

.cms-user-menu {
  position: relative;
}

.cms-theme-modern .cms-user-menu-toggle {
  gap: 8px;
  min-height: var(--cms-control-height);
  padding: 6px 10px;
  border: 1px solid rgb(255 255 255 / 45%);
  border-radius: var(--cms-radius-control);
  background: rgb(255 255 255 / 10%);
  color: #fff;
}

.cms-theme-modern .cms-user-menu-toggle:hover,
.cms-theme-modern .cms-user-menu-toggle[aria-expanded="true"] {
  border-color: rgb(255 255 255 / 75%);
  background: rgb(255 255 255 / 20%);
}

.cms-user-menu-toggle .icon-user {
  font-size: 17px;
}

.cms-user-menu-chevron {
  display: inline-flex;
  width: 16px;
  height: 16px;
  align-items: center;
  justify-content: center;
  transform-origin: 50% 50%;
  transition: transform .15s ease;
}

.cms-user-menu-chevron svg {
  display: block;
  width: 16px;
  height: 16px;
  fill: none;
  stroke: currentColor;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 1.75;
}

.cms-user-menu-toggle[aria-expanded="true"] .cms-user-menu-chevron {
  transform: rotate(180deg);
}

.cms-user-popover {
  position: absolute;
  z-index: 1000;
  top: calc(100% + 8px);
  right: 0;
  min-width: 320px;
  padding: 0;
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-panel);
  background: var(--cms-color-surface);
  box-shadow: var(--cms-shadow-panel);
  color: var(--cms-color-text);
  overflow: hidden;
  text-align: left;
}

.cms-user-popover-title {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 14px 16px;
  border-bottom: 1px solid var(--cms-color-border);
  color: var(--cms-color-primary);
  font-size: 15px;
}

.cms-user-login-times {
  margin: 0;
  padding: 6px 16px;
}

.cms-user-login-times > div {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 16px;
  align-items: baseline;
  padding: 9px 0;
}

.cms-user-login-times dt {
  color: var(--cms-color-muted);
  font-size: 12px;
}

.cms-user-login-times dd {
  margin: 0;
  color: var(--cms-color-text);
  font-size: 12px;
  font-weight: 600;
  white-space: nowrap;
}

.cms-user-popover-footer {
  display: flex;
  justify-content: flex-end;
  padding: 10px 16px 14px;
  border-top: 1px solid var(--cms-color-border);
  background: var(--cms-color-canvas);
}

.cms-theme-modern .cms-user-popover .exit {
  min-height: 32px;
  padding: 5px 12px;
  border-color: var(--cms-color-danger);
  background: var(--cms-color-danger);
  color: #fff;
}

.cms-save-state,
.cms-entry-status {
  display: inline-flex;
  align-items: center;
  min-height: 24px;
  margin-left: 0;
  padding: 2px 9px;
  border-radius: 999px;
  background: var(--cms-color-surface-hover);
  color: var(--cms-color-muted);
  font-size: 12px;
}

.cms-save-state[data-state="dirty"],
.cms-entry-status[data-tone="warning"] {
  color: #92400e;
  background: #fef3c7;
}

/* "Wymaga poprawy" used to share the amber of "Niezapisane zmiany", which made the one
   state that stops a save look like the one that invites it. Red, and the same red as
   `unknown`, because both mean "do not walk away from this screen yet". */
.cms-save-state[data-state="validation"] {
  color: #991b1b;
  background: #fee2e2;
  /* And only in this state is the pill a control: clicking it goes to the first failing
     field (tpl.js). Every other state keeps the default cursor, because there is nowhere
     for a click to take anyone. */
  cursor: pointer;
}

.cms-save-state[data-state="saved"],
.cms-entry-status[data-tone="positive"] {
  color: #065f46;
  background: #d1fae5;
}

.cms-save-state[data-state="unknown"] {
  color: #991b1b;
  background: #fee2e2;
}

/* The save's little ceremony: one ring outward from the pill's border when the server
   confirms a write the operator explicitly asked for (proc.js, cms_ui_save_celebrate).
   currentColor, so it rings in whatever tone the pill is actually showing; it ends
   invisible, so the class staying behind costs nothing, and proc.js restarts it by
   re-adding the class after a reflow. */
.cms-save-state {
  position: relative;
}

.cms-save-state.cms-save-pop::after {
  content: '';
  position: absolute;
  inset: -3px;
  border-radius: inherit;
  border: 2px solid currentColor;
  pointer-events: none;
  opacity: 0;
  animation: cms-save-pop 0.55s ease-out;
}

@keyframes cms-save-pop {
  0% {
    transform: scale(1);
    opacity: 0.75;
  }
  100% {
    transform: scale(1.55);
    opacity: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .cms-save-state.cms-save-pop::after {
    animation: none;
  }
}

/* The same ring, generalised: any hotkey that moves focus somewhere non-obvious (the "/"
   search leader, Ctrl/Cmd+Shift+F, Ctrl/Cmd+K) pumps its target once so the eye finds it.
   cms_ui_pump() in tpl.js removes and re-adds the class after a reflow, exactly like
   cms_ui_save_celebrate restarts .cms-save-pop, so a second pump in the same spot still
   rings.
   box-shadow, not a ::after ring: the targets are <input> elements, and generated content
   does not paint on replaced elements - a ::after here would be correct CSS that silently
   never renders. box-shadow has no such restriction, and .cms-omnisearch-control:focus-within
   above already builds its (static) halo the same way, with the same color-mix. */
.cms-ui-pump {
  animation: cms-ui-pump 0.35s ease-out;
}

/* Unlike .cms-save-pop, the eye is not already on the target - focus can land anywhere on
   the screen - so the ring holds near its initial state for its first third before expanding
   and fading, rather than starting the fade immediately. Same instinct, tuned for "found it"
   over "confirmed it" - just lighter-touch than the first pass: half the spread, half the
   opacity, so the accent does not shout. */
@keyframes cms-ui-pump {
  0% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--cms-color-accent) 50%, transparent);
  }
  30% {
    box-shadow: 0 0 0 1.5px color-mix(in srgb, var(--cms-color-accent) 50%, transparent);
  }
  100% {
    box-shadow: 0 0 0 9px color-mix(in srgb, var(--cms-color-accent) 0%, transparent);
  }
}

@media (prefers-reduced-motion: reduce) {
  .cms-ui-pump {
    animation: none;
  }
}

/* Standing facts about the entry, under its code in the metadata block. Quieter than the
   header pills on purpose: a pill announces something that just happened and wants to be
   read once, whereas these describe a state that was already true when the screen opened
   and will still be true when it closes. Read-only is the first of them, and on the screens
   where it is the norm it must not shout. */
/* Layout - the wrap, the right-alignment, the line of their own - belongs to master.css
   with the rest of the metadata block. What is themed here is only how they look. */
.cms-theme-modern .entry-notes {
  gap: var(--cms-space-2);
  margin-top: 2px;
}

.cms-theme-modern .entry-note {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  color: var(--cms-color-muted);
}

.cms-theme-modern .entry-note [class^="icon-"],
.cms-theme-modern .entry-note [class*=" icon-"] {
  font-size: 12px;
  line-height: 1;
}

.cms-theme-modern .entry-note[data-tone="warning"] {
  color: #92400e;
}

.cms-theme-modern .entry-note[data-tone="positive"] {
  color: #065f46;
}

.cms-theme-modern .flatpickr-day.selected,
.cms-theme-modern .flatpickr-day.startRange,
.cms-theme-modern .flatpickr-day.endRange {
  border-color: var(--cms-color-accent);
  background: var(--cms-color-accent);
}

.cms-theme-modern .jodit-container {
  --jd-border-radius-default: var(--cms-radius-control);
  border-color: var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  font-family: var(--cms-font-family);
}

.cms-theme-modern .jodit-toolbar__box:not(:empty) {
  border-color: var(--cms-color-border);
  background: var(--cms-color-surface);
}

/* Generic CMS button rules must not recolor Jodit's icon controls. */
.cms-theme-modern .jodit-container button,
.cms-theme-modern .jodit-container .jodit-toolbar-button__button,
.cms-theme-modern .jodit-container .jodit-toolbar-select__button,
.cms-theme-modern .jodit-container .jodit-toolbar-button,
.cms-theme-modern .jodit-container .jodit-toolbar-select,
.cms-theme-modern .jodit-popup button,
.cms-theme-modern .jodit-dialog button {
  min-height: 0 !important;
  padding: 0 !important;
  border-color: transparent !important;
  background-color: transparent !important;
  box-shadow: none !important;
  color: inherit !important;
}

.cms-theme-modern .jodit-container button:hover,
.cms-theme-modern .jodit-container .jodit-toolbar-button__button:hover,
.cms-theme-modern .jodit-container .jodit-toolbar-select__button:hover,
.cms-theme-modern .jodit-container .jodit-toolbar-button:hover,
.cms-theme-modern .jodit-container .jodit-toolbar-select:hover,
.cms-theme-modern .jodit-popup button:hover,
.cms-theme-modern .jodit-dialog button:hover {
  border-color: transparent !important;
  background-color: var(--cms-color-surface-hover) !important;
  color: inherit !important;
}

.cms-theme-modern .CodeMirror {
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  color: var(--cms-color-text);
  font-size: 13px;
}

.cms-theme-modern .cms-media-dialog {
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-panel);
  color: var(--cms-color-text);
  box-shadow: 0 18px 60px rgba(44, 40, 32, .28);
}

.cms-theme-modern .cms-media-upload,
.cms-theme-modern .cms-media-more {
  border-color: var(--cms-color-accent);
  background: var(--cms-color-accent);
  color: #fff;
}

.cms-theme-modern .cms-media-item {
  border-color: var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-surface);
}

.cms-theme-modern .cms-media-item:hover,
.cms-theme-modern .cms-media-item:focus {
  border-color: var(--cms-color-accent);
  background: var(--cms-color-surface-hover);
}

/* Calendar chrome only: event and legend backgrounds stay application-owned. */
.cms-theme-modern .fc {
  color: var(--cms-color-text);
  font-family: var(--cms-font-family);
  font-size: 13px;
}

.cms-theme-modern .fc .fc-toolbar {
  gap: var(--cms-space-3);
  margin-bottom: var(--cms-space-4);
}

.cms-theme-modern .ajaxtable-resizer::before {
  background: var(--cms-color-border-strong);
}

.cms-theme-modern .ajaxtable-resizer:hover::before {
  background: var(--cms-color-accent);
}

.cms-theme-modern .ajaxtable-corner {
  color: var(--cms-color-border-strong);
}

.cms-theme-modern .ajaxtable-corner:hover,
.cms-theme-modern .ajaxtable-corner-active {
  color: var(--cms-color-accent);
}

.cms-theme-modern .ajaxtable-colmenu {
  background: var(--cms-color-canvas);
  border-color: var(--cms-color-border);
  border-radius: var(--cms-radius-panel);
  box-shadow: var(--cms-shadow-panel);
}

/* The same shape as a row action, and for the same reason: `.cms-theme-modern button` paints
   EVERY button accent-on-white, which on a menu item gave a pale teal block with dark text on
   it. These are choices in a list, not calls to action, so they wear the outlined form - an
   inset bar on the leading edge that thickens and takes the accent on hover. */
.cms-theme-modern .ajaxtable-colmenu button {
  /* `.cms-theme-modern button` is inline-flex, centred - which is right for a call to action
     and wrong for a list of choices: it centred the labels, and it sized each item to its own
     content instead of to the menu, so the menu's width moved every time an item came or went.
     Block and left, like the list it is. */
  display: block;
  width: 100%;
  text-align: left;
  /* The same box as a row action, so the menu reads as part of the same family. */
  min-height: 26px;
  padding: 3px 10px;
  border: 1px solid transparent;
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-canvas);
  box-shadow: inset 3px 0 0 var(--cms-color-accent);
  color: var(--cms-color-text);
  font: 500 13px/1.2 var(--cms-font-family);
  font-weight: 500;
  transition: background-color .18s ease, border-color .18s ease, box-shadow .18s ease, color .18s ease;
}

.cms-theme-modern .ajaxtable-colmenu button:hover,
.cms-theme-modern .ajaxtable-colmenu button:focus-visible {
  border-color: var(--cms-color-accent-hover);
  background: var(--cms-color-surface-hover);
  box-shadow: inset 5px 0 0 var(--cms-color-accent-hover);
  color: var(--cms-color-accent-hover);
}

/* On its own class, not through .ajaxtable: while dragging, the helper is a child of <body>. */
.cms-theme-modern .ajaxtable-dragging {
  background: var(--cms-color-canvas);
  border-color: var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  color: var(--cms-color-text);
  box-shadow: var(--cms-shadow-panel);
}

.cms-theme-modern .ajaxtable th.ajaxtable-drop {
  background: var(--cms-color-surface, #eef4f3);
}

.cms-theme-modern .fc-cms-style-toggle {
  color: var(--cms-color-muted);
  font-size: 12px;
}

.cms-theme-modern .fc .fc-toolbar-title {
  color: var(--cms-color-primary);
  font-size: 20px;
  font-weight: 600;
}

.cms-theme-modern .fc .fc-button-primary {
  min-height: var(--cms-control-height);
  border-color: var(--cms-color-border-strong);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-canvas);
  color: var(--cms-color-primary);
  box-shadow: none;
}

.cms-theme-modern .fc .fc-button-primary:hover,
.cms-theme-modern .fc .fc-button-primary:not(:disabled).fc-button-active {
  border-color: var(--cms-color-accent);
  background: var(--cms-color-accent);
  color: #fff;
}

.cms-theme-modern .fc .fc-scrollgrid,
.cms-theme-modern .fc td,
.cms-theme-modern .fc th {
  border-color: var(--cms-color-border);
}

.cms-theme-modern .fc .fc-scrollgrid {
  overflow: hidden;
  border-radius: var(--cms-radius-panel);
}

.cms-theme-modern .fc .fc-view-harness {
  border-radius: var(--cms-radius-panel);
}

.cms-theme-modern .toptop a.exit {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  height: var(--cms-control-height);
  min-height: var(--cms-control-height);
  padding: 0 11px;
  border-color: var(--cms-color-danger);
  border-radius: var(--cms-radius-control);
  background-color: var(--cms-color-danger);
  line-height: 18px;
}

.cms-theme-modern .toptop #t-logged-user {
  margin-left: 5px;
}

.cms-theme-modern .toptop a.exit:hover {
  background-color: var(--cms-color-danger-hover);
  color: #fff;
}

.cms-theme-modern .fc .fc-col-header-cell {
  background: var(--cms-color-surface);
}

.cms-theme-modern .fc .fc-event,
.cms-theme-modern .legend-label {
  border-radius: 5px;
}

.cms-theme-modern .legend-label {
  min-height: 22px;
  padding: 5px 9px;
  border: 1px solid rgba(0, 0, 0, .12);
  line-height: 1;
  vertical-align: middle;
}

/* Login, OTP and password change */
.cms-theme-modern.cms-login-page {
  display: grid;
  min-height: 100vh;
  place-items: start center;
  padding: clamp(56px, 18vh, 180px) var(--cms-space-5) var(--cms-space-5);
  background: linear-gradient(145deg, #efe9dd, #f9f7f2);
}

.cms-theme-modern .login-form {
  position: static;
  inset: auto;
  transform: none;
  width: min(390px, 100%);
  /* master.css pins this to a fixed 400px, which the login form fits and a notice page
     does not - its text ran straight out of the card. min-height keeps the login card
     exactly the size it has always been while letting taller content grow it. */
  height: auto;
  min-height: 400px;
  margin: 0;
  padding: 28px;
  border: 1px solid var(--cms-color-border);
  border-radius: 12px;
  background: var(--cms-color-canvas);
  box-shadow: 0 18px 50px rgba(44, 40, 32, .14);
}

.cms-theme-modern .login-form .logo {
  margin-bottom: var(--cms-space-5);
  text-align: center;
}

.cms-theme-modern .login-form .logo img {
  max-width: 220px;
  max-height: 60px;
}

.cms-theme-modern .login-form .loginInput,
.cms-theme-modern .login-form .formSubmit {
  width: 100%;
  min-height: 42px;
  margin: 0 0 var(--cms-space-3);
}

.cms-theme-modern .login-form .formSubmit {
  border-color: var(--cms-color-accent);
  background: var(--cms-color-accent);
  color: #fff;
}

/* The password field greys out - a short fade, not a jump - once the address typed above
   makes it unnecessary (login.js disables it), and its placeholder then carries an
   instruction, so it has to stay legible on the disabled surface: browsers dim a disabled
   placeholder further on their own. */
.cms-theme-modern .login-form .loginInput {
  transition: background-color .15s ease, border-color .15s ease, color .15s ease;
}

.cms-theme-modern .login-form .ipass:disabled::placeholder {
  color: var(--cms-color-muted);
  font-style: italic;
  opacity: 1;
}

.cms-theme-modern .login-form .button-genotp {
  border-color: var(--cms-color-accent);
  background: var(--cms-color-accent);
}

.cms-theme-modern .login-form .button-password-change {
  border-color: var(--cms-color-accent);
  background: var(--cms-color-accent);
}

.cms-theme-modern .login-form #lo-tresce {
  padding: 0;
}

/* Notice pages (404 and anything else the layout hosts instead of the login form) */
.cms-theme-modern .login-form .notice {
  text-align: center;
}

/* The 400px floor exists to keep the login card the size it has always been. A notice is
   shorter and would sit in a half-empty box, so it sizes to its own content. Browsers
   without :has() simply keep the floor - extra whitespace, nothing broken. */
.cms-theme-modern .login-form:has(.notice) {
  min-height: 0;
}

.cms-theme-modern .login-form .notice-art {
  display: block;
  width: min(240px, 100%);
  height: auto;
  margin: var(--cms-space-3) auto var(--cms-space-5);
  /* The drawing is stroked in currentColor, so it follows the theme rather than carrying
     its own palette - and it stays crisp at any density, which the ascii version did not. */
  color: var(--cms-color-primary);
}

.cms-theme-modern .login-form .notice-title {
  margin: 0 0 var(--cms-space-3);
  font-size: 18px;
  letter-spacing: normal;
  text-transform: none;
}

.cms-theme-modern .login-form .notice-text {
  margin: 0;
}

/* One save/preview cluster on screen, without nested scrolling.
   The bottom cluster is the standby: it is hidden while any part of the top one is still in
   view, and takes over once that has scrolled away. Hidden rather than removed, so the form's
   height does not change under the operator as they scroll. */
.cms-theme-modern #cmsmasteredit.cms-top-actions-visible .bottom-row .update-preview {
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .2s ease, visibility 0s linear .2s;
}

.cms-theme-modern .bottom-row .update-preview {
  opacity: 1;
  visibility: visible;
  transition: opacity .2s ease, visibility 0s linear 0s;
}

@media (prefers-reduced-motion: reduce) {
  .cms-theme-modern *,
  .cms-theme-modern *::before,
  .cms-theme-modern *::after {
    scroll-behavior: auto !important;
    transition-duration: .01ms !important;
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
  }
}

@media (max-width: 1100px) {
  .cms-theme-modern .cms-omnisearch-control kbd {
    display: none;
  }

  .cms-theme-modern .canvas {
    padding-right: var(--cms-space-3);
  }

  .cms-theme-modern .canvas-content {
    padding: var(--cms-space-4);
  }
}

/*
 * A/B: dark left navigation.
 *
 * Additive and independent of .cms-theme-modern - add "cms-nav-dark" alongside it on
 * <body> to try this, remove it to go back to the light sidebar above. Nothing else on
 * the page changes either way.
 *
 * The nav icons (images/*.svg) are baked-in near-black fills (#222222), not
 * currentColor/mask icons, so they cannot be recoloured with `color` - brightness(0)
 * invert(1) forces them to a flat white silhouette instead, which is what every one of
 * them actually is under the colour.
 */
.cms-nav-dark .left-nav {
  border-color: var(--cms-color-primary);
  background: var(--cms-color-primary);
  box-shadow: 0 1px 2px rgba(0, 0, 0, .18), 0 10px 24px rgba(0, 0, 0, .22);
}

.cms-nav-dark .mm a,
.cms-nav-dark [class*="mml"] > a {
  color: #eef1ef;
  opacity: .82;
}

.cms-nav-dark .mml0 > .ico {
  filter: brightness(0) invert(1);
  opacity: .82;
}

/* The other seven icons (home/clients/teachers/inventory/tests/conditions/reports/
   other) are not a child .ico at all - master.css paints them as .mml0's OWN
   background-image, so a mask on .mml0 itself does not just recolour the icon, it
   masks .mml0's entire rendered box - including the link text sitting next to the
   icon inside it, which is why that text went missing the first time this was tried.
   Painted on a ::before instead: a stencil-shaped pseudo-element of its own, sized and
   positioned exactly where the background-image used to sit, so nothing else in .mml0
   is touched. */
.cms-nav-dark .mml0.menu-icon--home,
.cms-nav-dark .mml0.menu-icon--clients,
.cms-nav-dark .mml0.menu-icon--teachers,
.cms-nav-dark .mml0.menu-icon--inventory,
.cms-nav-dark .mml0.menu-icon--tests,
.cms-nav-dark .mml0.menu-icon--conditions,
.cms-nav-dark .mml0.menu-icon--reports,
.cms-nav-dark .mml0.menu-icon--other {
  background-image: none;
}

.cms-nav-dark .mml0.menu-icon--home::before,
.cms-nav-dark .mml0.menu-icon--clients::before,
.cms-nav-dark .mml0.menu-icon--teachers::before,
.cms-nav-dark .mml0.menu-icon--inventory::before,
.cms-nav-dark .mml0.menu-icon--tests::before,
.cms-nav-dark .mml0.menu-icon--conditions::before,
.cms-nav-dark .mml0.menu-icon--reports::before,
.cms-nav-dark .mml0.menu-icon--other::before {
  content: "";
  position: absolute;
  left: 8px;
  top: 50%;
  width: 18px;
  height: 18px;
  transform: translateY(-50%);
  mask-repeat: no-repeat;
  mask-position: center;
  mask-size: 18px 18px;
  -webkit-mask-repeat: no-repeat;
  -webkit-mask-position: center;
  -webkit-mask-size: 18px 18px;
  background-color: #eef1ef;
  opacity: .82;
  pointer-events: none;
}

.cms-nav-dark .mml0.menu-icon--home:hover::before,
.cms-nav-dark .mml0.menu-icon--clients:hover::before,
.cms-nav-dark .mml0.menu-icon--teachers:hover::before,
.cms-nav-dark .mml0.menu-icon--inventory:hover::before,
.cms-nav-dark .mml0.menu-icon--tests:hover::before,
.cms-nav-dark .mml0.menu-icon--conditions:hover::before,
.cms-nav-dark .mml0.menu-icon--reports:hover::before,
.cms-nav-dark .mml0.menu-icon--other:hover::before {
  opacity: 1;
}

.cms-nav-dark .mml0.menu-icon--home::before { mask-image: url("../images/home.svg"); -webkit-mask-image: url("../images/home.svg"); }
.cms-nav-dark .mml0.menu-icon--clients::before { mask-image: url("../images/client.svg"); -webkit-mask-image: url("../images/client.svg"); }
.cms-nav-dark .mml0.menu-icon--teachers::before { mask-image: url("../images/teachers.svg"); -webkit-mask-image: url("../images/teachers.svg"); }
.cms-nav-dark .mml0.menu-icon--inventory::before { mask-image: url("../images/inventory.svg"); -webkit-mask-image: url("../images/inventory.svg"); }
.cms-nav-dark .mml0.menu-icon--tests::before { mask-image: url("../images/tests.svg"); -webkit-mask-image: url("../images/tests.svg"); }
.cms-nav-dark .mml0.menu-icon--conditions::before { mask-image: url("../images/conditions.svg"); -webkit-mask-image: url("../images/conditions.svg"); }
.cms-nav-dark .mml0.menu-icon--reports::before { mask-image: url("../images/reports.svg"); -webkit-mask-image: url("../images/reports.svg"); }
.cms-nav-dark .mml0.menu-icon--other::before { mask-image: url("../images/other.svg"); -webkit-mask-image: url("../images/other.svg"); }

.cms-nav-dark .mm a:hover,
.cms-nav-dark [class*="mml"] > a:hover,
.cms-nav-dark .mml0:hover {
  background-color: rgba(255, 255, 255, .08);
}

.cms-nav-dark .mm a:hover,
.cms-nav-dark [class*="mml"] > a:hover {
  opacity: 1;
}

.cms-nav-dark .mml0 > a:hover {
  background: transparent;
}

.cms-nav-dark .mm-toggle {
  color: #eef1ef;
  opacity: .82;
}
.cms-nav-dark .mm-toggle:hover,
.cms-nav-dark .mm-toggle:focus-visible {
  background-color: rgba(255, 255, 255, .12);
  color: #ffffff;
  opacity: 1;
}
.cms-nav-dark .mms > .mm-toggle,
.cms-nav-dark .mms > .mm-toggle:hover {
  color: #ffffff;
  opacity: 1;
}

/* The current-item highlight: light-on-dark instead of the light theme's teal-tinted
   card, same accent hue so it still reads as "this is the active one, in this brand". */
.cms-nav-dark .mms {
  background-color: color-mix(in srgb, var(--cms-color-accent) 28%, transparent);
}

.cms-nav-dark .mms.mml2,
.cms-nav-dark .mms.mml2f {
  padding-left: 0px;
  margin-left: 40px;
}

.cms-nav-dark .mms > a,
.cms-nav-dark .mms > a:visited {
  color: #ffffff !important;
  opacity: 1;
}

.cms-nav-dark .mms > .ico {
  filter: brightness(0) invert(1);
  opacity: 1;
}

/* ---------------------------------------------------------------------------------------
   Charts.

   Every colour here is a token, and the series colours are not here at all - charts.js
   derives those from --cms-hue-brand at draw time (see the head of that file). A literal
   colour in this block would be the one thing that stops a chart following the
   installation's accent, so there are none.

   The canvas needs a height in CSS: Chart.js with maintainAspectRatio:false sizes itself
   to its container, and a container that sizes itself to its content collapses to nothing.
   --------------------------------------------------------------------------------------- */
.cms-chart {
  background: var(--cms-color-canvas);
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-panel);
  padding: var(--cms-space-3);
  margin: var(--cms-space-2) 0;
}

.cms-chart-wide {
  margin: var(--cms-space-3) 0;
}

.cms-chart-head {
  display: flex;
  align-items: center;
  gap: var(--cms-space-2);
  margin-bottom: var(--cms-space-2);
}

.cms-chart-title {
  color: var(--cms-color-text);
  font-size: 1.02em;
  flex: 1 1 auto;
}

.cms-chart-controls {
  display: flex;
  gap: var(--cms-space-1);
}

.cms-chart-control {
  height: var(--cms-control-height);
  border: 1px solid var(--cms-color-border-strong);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-surface);
  color: var(--cms-color-text);
  padding: 0 var(--cms-space-2);
}

.cms-chart-refresh {
  flex: 0 0 auto;
  width: var(--cms-control-height);
  height: var(--cms-control-height);
  border: 1px solid var(--cms-color-border-strong);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-surface);
  color: var(--cms-color-accent);
  cursor: pointer;
  font-size: 1.1em;
  line-height: 1;
}

.cms-chart-refresh:hover {
  background: var(--cms-color-surface-hover);
  border-color: var(--cms-color-accent);
}

.cms-chart-refresh:focus-visible {
  outline: 2px solid var(--cms-color-focus);
  outline-offset: 1px;
}

.cms-chart-canvas {
  position: relative;
  height: 240px;
}

.cms-chart-wide .cms-chart-canvas {
  height: 320px;
}

.cms-chart-canvas canvas {
  max-width: 100%;
}

.cms-chart-status {
  margin-top: var(--cms-space-2);
  color: var(--cms-color-muted);
  font-size: 0.9em;
  min-height: 1.2em;
}

/* ---------------------------------------------------------------------------------------
   Repeated groups (spacergroup)

   A master/detail editor for a group that used to be N copies of the same form stacked down
   the page. The list is capped rather than fixed - it shrinks to its rows and stops at 40% of
   the viewport, so a group of three does not reserve the height of a group of a hundred and a
   group of a hundred does not push the form off the screen.

   Colours are tokens, never literals: --cms-hue-brand is the customer-facing knob and a hex
   here would be a colour that stops following it.
   --------------------------------------------------------------------------------------- */

.cms-theme-modern .cms-sgroup {
  display: flex;
  gap: var(--cms-space-3);
  align-items: flex-start;
}

.cms-theme-modern .cms-sgroup-list {
  flex: 0 0 20%;
  min-width: 140px;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--cms-color-border);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-surface);
  overflow: hidden;
}

/* ONE HEIGHT, ALWAYS, and it belongs to the BOX rather than to the rows. Not a floor and a
   cap: a list that grows as rows are added moves the whole card under the operator's hands,
   and one that shrinks when a group is emptied does it again. It scrolls past this height and
   reserves it when there is nothing in it.

   The "nothing here" note lives inside this box for the same reason. Beside it, it added its
   own height while the group was empty and gave it back on the first row - so the list got
   shorter as it gained something, which is the one direction nobody expects. */
.cms-theme-modern .cms-sgroup-scroll {
  height: 25vh;
  overflow-y: auto;
}

.cms-theme-modern .cms-sgroup-items {
  margin: 0;
  padding: 0;
  list-style: none;
}

.cms-theme-modern .cms-sgroup-items li {
  padding: var(--cms-space-2) var(--cms-space-3);
  cursor: pointer;
  border-bottom: 1px solid var(--cms-color-border);
  /* A label is one line however long the value is; the form beside it shows the whole thing. */
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cms-theme-modern .cms-sgroup-items li:last-child { border-bottom: 0; }
.cms-theme-modern .cms-sgroup-items li:hover { background: var(--cms-color-surface-hover); }

.cms-theme-modern .cms-sgroup-items li.is-selected {
  background: var(--cms-color-canvas);
  /* The selected row is marked on the leading edge, the way the row-action buttons are, so
     the two read as the same kind of "this one" rather than as two different affordances. */
  box-shadow: inset 3px 0 0 var(--cms-color-accent);
  font-weight: 600;
}

.cms-theme-modern .cms-sgroup-empty {
  display: none;
  padding: var(--cms-space-3);
  color: var(--cms-color-muted);
  font-style: italic;
}

.cms-theme-modern .cms-sgroup-tools {
  display: flex;
  gap: var(--cms-space-1);
  padding: var(--cms-space-2);
  border-top: 1px solid var(--cms-color-border);
  background: var(--cms-color-canvas);
}

/* The same control the dbe list's row actions are, down to the numbers: outlined on the
   canvas with the accent as a bar on the leading edge, thickening on hover. Reused rather
   than re-invented - these do the same KIND of thing (act on the row you are pointing at)
   and two shapes for one meaning is how a panel stops looking like one panel.

   .cms-theme-modern button is otherwise an accent-filled inline-flex that centres its label,
   so display and justification have to be said here or the glyph sits in a solid teal pill. */
.cms-theme-modern .cms-sgroup-tools button {
  display: block;
  flex: 1 1 0;
  min-width: 0;
  min-height: 26px;
  padding: 3px 10px;
  border: 1px solid var(--cms-color-border-strong);
  border-radius: var(--cms-radius-control);
  background: var(--cms-color-canvas);
  box-shadow: inset 3px 0 0 var(--cms-color-accent);
  color: var(--cms-color-text);
  font: 500 13px/1.2 var(--cms-font-family);
  cursor: pointer;
  transition: background-color .18s ease, border-color .18s ease, box-shadow .18s ease, color .18s ease;
}

.cms-theme-modern .cms-sgroup-tools button:hover:not(:disabled),
.cms-theme-modern .cms-sgroup-tools button:focus-visible {
  border-color: var(--cms-color-accent-hover);
  background: var(--cms-color-surface-hover);
  box-shadow: inset 5px 0 0 var(--cms-color-accent-hover);
  color: var(--cms-color-accent-hover);
}

/* Removing a row is destructive, and the row actions already have a colour for that. */
.cms-theme-modern .cms-sgroup-tools .cms-sgroup-del {
  border-color: var(--cms-color-danger);
  box-shadow: inset 3px 0 0 var(--cms-color-danger);
  color: var(--cms-color-danger);
}

.cms-theme-modern .cms-sgroup-tools .cms-sgroup-sort {
  border-color: var(--cms-color-muted);
  box-shadow: inset 3px 0 0 var(--cms-color-muted);
  color: var(--cms-color-muted);
}

.cms-theme-modern .cms-sgroup-tools .cms-sgroup-sort:hover:not(:disabled),
.cms-theme-modern .cms-sgroup-tools .cms-sgroup-sort:focus-visible {
  box-shadow: inset 5px 0 0 var(--cms-color-muted);
  border-color: var(--cms-color-muted);
  color: var(--cms-color-muted);
  background: var(--cms-color-muted-hover);
}

.cms-theme-modern .cms-sgroup-tools .cms-sgroup-del:hover:not(:disabled),
.cms-theme-modern .cms-sgroup-tools .cms-sgroup-del:focus-visible {
  border-color: var(--cms-color-danger);
  background: #fcecef;
  box-shadow: inset 5px 0 0 var(--cms-color-danger);
  color: var(--cms-color-danger);
}

/* master.css fades row actions to half opacity until their row is hovered; these have no row
   to hover, and on an outlined control that reads as disabled rather than as idle. */
.cms-theme-modern .cms-sgroup-tools button:disabled {
  opacity: .45;
  cursor: default;
  box-shadow: inset 3px 0 0 var(--cms-color-border-strong);
  border-color: var(--cms-color-border-strong);
  color: var(--cms-color-muted);
}

.cms-theme-modern .cms-sgroup-detail {
  flex: 1 1 auto;
  /* A member field is an ordinary field in an ordinary group shell, so it can be as wide as
     any other - but it must not push the list narrower than its own basis. */
  min-width: 0;
  /* THE SPACE IS RESERVED, NOT DISCOVERED. Two numbers, and the larger wins: an estimate from
     the member count, which the widget sets before anything is painted and which is all there
     is to go on while a group is empty, and the height a row actually needed once one has
     been. Without the first the card jumps on the first add; without the second it jumps
     again the first time a textarea member is shown. --cms-sgroup-members defaults to 1 so a
     stylesheet loaded without the script still reserves something rather than nothing. */
  min-height: max(
    calc(var(--cms-sgroup-members, 1) * (var(--cms-control-height) + var(--cms-space-4))),
    var(--cms-sgroup-detail-min, 0px)
  );
}
