/*
 * ICPC Bolivia System - Cloudscape component layer (visual refresh, light mode).
 *
 * Loaded after /static/vendor/cloudscape/fonts.css and tokens.css (generated by
 * scripts/vendor_cloudscape.py). Rules:
 *   - every colour, spacing, radius, font size, shadow and motion value is a design token
 *     var(--...). A raw value appears only where Cloudscape itself hardcodes one; those are
 *     defined once in the "layout constants" block below or commented inline.
 *   - classes are prefixed cs- (components) or cs-u- (the few utilities). Templates never use
 *     style="" attributes; markup comes from app/templates/_cs.html (see docs/frontend.md).
 *   - focus rings use :focus-visible (Cloudscape shows them only after keyboard use).
 *
 * Sections: 1 constants  2 keyframes  3 base  4 app layout (top nav, toolbar, side nav,
 * content)  5 breadcrumbs  6 header  7 container  8 layout helpers (space between, columns)
 * 9 key-value pairs  10 icon + spinner  11 button  12 button dropdown + menu  13 status +
 * badge  14 alert + flashbar  15 form controls  16 tabs  17 expandable section  18 table
 * 19 split panel  20 wizard steps  21 confirmation box, empty state  22 code boxes + email
 * preview  23 utilities  24 reduced motion  25 pages (rules for one page only)
 */

/* =========================================================================================
   1. Layout constants (Cloudscape hardcodes these in its components; they are not tokens)
   ========================================================================================= */
:root {
  --cs-top-nav-height: 56px; /* Cloudscape: TopNavigation bar is 56px on wide screens, 48px <= 912px, 40px <= 688px (below) */
  --cs-top-nav-border: 1px; /* Cloudscape: top navigation bottom border */
  --cs-toolbar-height: 42px; /* Cloudscape: AppLayoutToolbar row incl. its 1px border */
  --cs-header-height: calc(var(--cs-top-nav-height) + var(--cs-top-nav-border) + var(--cs-toolbar-height));
  --cs-nav-width: 280px; /* Cloudscape: AppLayout navigationWidth default */
  --cs-nav-offset: calc(var(--cs-nav-width) + var(--border-width-layout-side-navigation));
  --cs-toolbar-trigger-size: 30px; /* Cloudscape: toolbar trigger buttons */
  --cs-content-max-width: 1620px; /* Cloudscape toolbar layout: default/form/details max width */
  --cs-dashboard-max-width: 1280px; /* Cloudscape: dashboard content type at >= 1401px */
  --cs-split-panel-height: 0px; /* set by app.js while a split panel is shown */
  --cs-split-panel-handle: 18px; /* Cloudscape: split panel resize handle strip */
  --cs-menu-min-width: 160px; /* Cloudscape: dropdown min width */
  --cs-dropdown-max-width: 464px; /* Cloudscape: dropdown max width */
  --cs-text-filter-max-width: 480px; /* filter input width of the reference renders */
  --cs-select-filter-width: 260px; /* select filter width of the reference renders (+ counts) */
  --cs-steps-width: 260px; /* Cloudscape: wizard navigation column */
  --cs-steps-circle: 10px; /* Cloudscape: wizard step circle */
  --cs-steps-ring: 2px; /* Cloudscape: width of the wizard circle's ring (future / visited / active) */
  --cs-steps-active-gap: 3px; /* Cloudscape: white gap between the active circle and its ring */
  --cs-confirmation-max-width: 820px; /* Cloudscape: modal size "large" */
  --cs-confirmation-medium-width: 600px; /* Cloudscape: modal size "medium" */
  --cs-email-preview-height: 34rem; /* app: HTML email preview frame */
  --cs-email-preview-mobile-height: 42rem; /* app: preview frame in "Mobile width" */
  --cs-email-preview-mobile-width: 375px; /* app: a typical phone viewport */
  --cs-table-wrap-width: 18rem; /* app: max width of wrapping table columns (names) */
  --cs-table-wrap-min-width: 13rem; /* app: min width of wrapping table columns */
  --cs-table-cell-max-width: 16rem; /* app: default max width of a truncated (ellipsis) cell */
  --cs-tooltip-max-width: 310px; /* Cloudscape: popover/tooltip size "medium" */
  --cs-popover-arrow-side: 8.5px; /* Cloudscape: 12px-wide popover arrow (a square of 12px / sqrt(2), rotated) */
  --cs-focus-ring-width: 2px; /* Cloudscape: focus ring (box-shadow spread / transparent outline) */
  --cs-sticky-offset: 0px; /* set by app.js: height of a stuck table header + column header */
  --cs-sticky-header-top: var(--cs-header-height); /* where a sticky table header sticks */
  /* Stacking order (Cloudscape keeps the same relations between these layers). */
  --cs-z-sticky-header: 799; /* cloned column header, below the side nav */
  --cs-z-nav: 830; /* side navigation */
  --cs-z-table-header: 835; /* sticky table header: over the side nav, under the split panel */
  --cs-z-split-panel: 840; /* bottom split panel: a maximised panel is never covered by the header */
  --cs-z-table-header-open: 850; /* sticky table header with an open menu: the menu opens over the panel */
  --cs-z-header: 1002; /* top navigation + toolbar */
  --cs-z-nav-overlay: 1003; /* mobile navigation overlay: covers the toolbar */
  --cs-z-dropdown: 2000; /* dropdown menus */
  --cs-z-tooltip: 2100; /* tooltips (disabled reasons), above menus */
  --cs-z-skip-link: 5000; /* the skip link, above everything */
}

@media (max-width: 912px) {
  :root {
    --cs-top-nav-height: 48px; /* Cloudscape: medium top navigation */
  }
}

@media (max-width: 688px) {
  :root {
    --cs-top-nav-height: 40px; /* Cloudscape: narrow top navigation (the toolbar stays 42px) */
  }
}

/* =========================================================================================
   2. Keyframes (names come from the --motion-keyframes-* tokens)
   ========================================================================================= */
@keyframes cs-fade-in {
  from { opacity: 0; }
  to { opacity: 1; }
}

@keyframes cs-status-icon-error {
  0% { transform: translateX(-5px); animation-timing-function: linear; }
  50% { transform: translateX(5px); }
  100% { transform: translateX(0); }
}

@keyframes cs-spinner-rotator {
  from { transform: rotate(0deg); }
  to { transform: rotate(360deg); }
}

@keyframes cs-spinner-line-left {
  0%, 100% { transform: rotate(0deg); }
  50% { transform: rotate(120deg); }
}

@keyframes cs-spinner-line-right {
  0%, 100% { transform: rotate(90deg); }
  50% { transform: rotate(-30deg); }
}

/* =========================================================================================
   3. Base
   ========================================================================================= */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  color-scheme: light; /* the app has no dark mode: native controls and scrollbars stay light */
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* In-page anchors (#main-content, #delivery-12) and focused elements scrolled into view stay
     clear of the sticky header (+ a stuck table header) and of the bottom split panel. */
  scroll-padding-top: calc(var(--cs-header-height) + var(--cs-sticky-offset) + var(--space-s));
  scroll-padding-bottom: calc(var(--cs-split-panel-height) + var(--space-s));
}

body {
  margin: 0;
  font-family: var(--font-family-base);
  font-size: var(--font-size-body-m);
  line-height: var(--line-height-body-m);
  font-weight: var(--font-weight-normal);
  color: var(--color-text-body-default);
  background: var(--color-background-layout-main);
  -webkit-font-smoothing: var(--font-smoothing-webkit);
  -moz-osx-font-smoothing: var(--font-smoothing-moz-osx);
}

h1, h2, h3, h4, h5 {
  margin: 0;
  color: var(--color-text-heading-default);
  font-family: var(--font-family-heading);
}

h1 { font-size: var(--font-size-heading-xl); line-height: var(--line-height-heading-xl); letter-spacing: var(--letter-spacing-heading-xl); font-weight: var(--font-weight-heading-xl); }
h2 { font-size: var(--font-size-heading-l); line-height: var(--line-height-heading-l); letter-spacing: var(--letter-spacing-heading-l); font-weight: var(--font-weight-heading-l); }
h3 { font-size: var(--font-size-heading-m); line-height: var(--line-height-heading-m); letter-spacing: var(--letter-spacing-heading-m); font-weight: var(--font-weight-heading-m); }
h4 { font-size: var(--font-size-heading-s); line-height: var(--line-height-heading-s); letter-spacing: var(--letter-spacing-heading-s); font-weight: var(--font-weight-heading-s); }
h5 { font-size: var(--font-size-heading-xs); line-height: var(--line-height-heading-xs); font-weight: var(--font-weight-heading-xs); }

p {
  margin: 0;
}

ul, ol {
  margin: var(--space-xs) 0;
  padding-left: var(--space-l);
}

b, strong {
  font-weight: var(--font-weight-bold);
}

small {
  display: inline-block;
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-s);
  letter-spacing: var(--letter-spacing-body-s);
  color: var(--color-text-small);
}

code, kbd, samp, pre {
  font-family: var(--font-family-monospace);
}

code {
  font-size: var(--font-size-body-s);
  line-height: inherit;
  overflow-wrap: anywhere;
}

pre {
  margin: 0;
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-s);
}

hr {
  border: none;
  border-top: var(--border-divider-section-width) solid var(--color-border-divider-default);
  margin: var(--space-l) 0;
}

/* Links: the Cloudscape "primary" link (underlined), the default inside text. */
a {
  color: var(--color-text-link-default);
  font-weight: inherit;
  text-decoration-line: underline;
  text-decoration-style: var(--font-decoration-style-link);
  text-decoration-thickness: var(--font-decoration-thickness-link);
  text-decoration-color: var(--color-text-link-decoration-default);
  text-underline-offset: 0.25em; /* Cloudscape: link underline offset */
  transition-property: color, text-decoration-color;
  transition-duration: var(--motion-duration-refresh-only-medium);
}

a:hover,
a:active {
  color: var(--color-text-link-hover);
}

a:focus {
  outline: none;
}

/* Focus recipe 2 (links, headings, side-nav links): a 2px ring with a 4px radius. */
a:focus-visible {
  outline: var(--cs-focus-ring-width) dotted transparent;
  outline-offset: var(--cs-focus-ring-width);
  border-radius: var(--border-radius-control-default-focus-ring);
  box-shadow: 0 0 0 var(--border-link-focus-ring-shadow-spread) var(--color-border-item-focused);
}

/* Shared focus rings (Cloudscape: shown only after keyboard use, :focus-visible). The dotted
   transparent outline is what Windows High Contrast (forced colours) draws instead of the
   box-shadow. Components add their own geometry (offsets, insets) in their sections. */
.cs-toolbar__trigger:focus,
.cs-button:focus,
.cs-sidenav__section-toggle:focus,
.cs-topnav__year-select:focus,
.cs-table__sort:focus,
.cs-split-panel__handle:focus,
.cs-expandable__header:focus,
.cs-control__input:focus,
.cs-file-input:focus,
.cs-table__wrapper:focus,
.cs-table__scroll:focus,
.cs-header__heading:focus {
  outline: none;
}

/* Ring around the element. */
.cs-sidenav__section-toggle:focus-visible,
.cs-expandable__header:focus-visible,
.email-html-frame:focus-visible,
.email-html-frame.is-focus-visible {
  outline: var(--cs-focus-ring-width) dotted transparent;
  border-radius: var(--border-radius-control-default-focus-ring);
  box-shadow: 0 0 0 var(--cs-focus-ring-width) var(--color-border-item-focused);
}

/* Ring inside the element (it fills its box, or it scrolls: an outer ring would be clipped). */
.cs-topnav__year-select:focus-visible,
.cs-table__sort:focus-visible,
.cs-split-panel__handle:focus-visible,
.cs-table__wrapper:focus-visible,
.cs-table__scroll:focus-visible {
  outline: var(--cs-focus-ring-width) dotted transparent;
  outline-offset: calc(-1 * var(--cs-focus-ring-width));
  border-radius: var(--border-radius-control-default-focus-ring);
  box-shadow: inset 0 0 0 var(--cs-focus-ring-width) var(--color-border-item-focused);
}

/* Ring drawn by a ::before with a gap around the element (buttons, triggers, tabs, segments). */
.cs-toolbar__trigger:focus-visible::before,
.cs-button:focus-visible::before,
.cs-tabs__tab:focus-visible::before,
.cs-segmented__input:focus-visible + .cs-segmented__segment::before {
  content: "";
  position: absolute;
  border-radius: var(--border-radius-control-default-focus-ring);
  box-shadow: 0 0 0 var(--cs-focus-ring-width) var(--color-border-item-focused);
  pointer-events: none;
}

/* A standalone link that is underlined only on hover (Cloudscape "secondary" link). */
.cs-link {
  text-decoration-line: var(--font-decoration-line-link-secondary);
}

.cs-link:hover {
  text-decoration-line: underline;
}

/* The "opens in a new tab" icon after a link's text (Cloudscape Link external):
   <a ... target="_blank">Text{{ cs.icon("external", size="small", label="(opens in a new tab)", class="cs-link__external") }}</a> */
.cs-link__external {
  margin-left: var(--space-xxxs);
}

/* A destructive text link (user decision, "subtle red accent"): error-red text and underline,
   darker red on hover / active. The a:focus-visible ring is unchanged. */
.cs-link--danger {
  color: var(--color-text-status-error);
  text-decoration-color: var(--color-text-status-error);
}

.cs-link--danger:hover,
.cs-link--danger:active {
  color: var(--color-error-800);
  text-decoration-color: var(--color-error-800);
}

button,
input,
select,
textarea {
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
}

[hidden] {
  display: none !important;
}

/* JavaScript gates: .js is set on <html> by app.js. */
.js .cs-no-js-only {
  display: none !important;
}

html:not(.js) .cs-js-only {
  display: none !important;
}

.cs-skip-link {
  position: absolute;
  top: var(--space-xs);
  left: var(--space-xs);
  z-index: var(--cs-z-skip-link);
  padding: var(--space-xxs) var(--space-s);
  background: var(--color-background-container-content);
  color: var(--color-text-link-default);
  font-weight: var(--font-weight-bold);
  border-radius: var(--border-radius-item);
  transform: translateY(-200%);
}

.cs-skip-link:focus,
.cs-skip-link:focus-visible {
  transform: none;
}

/* =========================================================================================
   4. App layout: top navigation, toolbar, side navigation, content area
   ========================================================================================= */
.cs-app {
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  background: var(--color-background-layout-main);
}

.cs-app__header {
  position: sticky;
  top: 0;
  z-index: var(--cs-z-header);
}

/* ---- Top navigation (dark context) ---- */
.cs-topnav {
  background: var(--color-background-container-content);
  border-bottom: var(--cs-top-nav-border) solid var(--color-border-divider-default);
  color: var(--color-text-body-default);
}

.cs-topnav__bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  height: var(--cs-top-nav-height);
  padding-left: var(--space-xxl);
  padding-right: var(--space-xs);
}

.cs-topnav__identity {
  min-width: 0;
  flex-shrink: 1;
}

.cs-topnav__identity-link {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  min-width: 0;
  color: var(--color-text-top-navigation-title);
  text-decoration: none;
}

.cs-topnav__identity-link:hover {
  color: var(--color-text-accent);
}

.cs-topnav__logo {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: var(--size-icon-big);
  height: var(--size-icon-big);
  border: var(--border-divider-section-width) solid var(--color-border-divider-default);
  border-radius: var(--border-radius-item);
  color: inherit;
}

.cs-topnav__title {
  font-family: var(--font-family-heading);
  font-size: var(--font-size-heading-m);
  line-height: var(--line-height-heading-m);
  letter-spacing: var(--letter-spacing-heading-m);
  font-weight: var(--font-weight-heading-m);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cs-topnav__utilities {
  display: flex;
  align-items: stretch;
  height: 100%;
  flex-shrink: 0;
}

.cs-topnav__utility {
  position: relative;
  display: flex;
  align-items: center;
  padding: 0 var(--space-m);
}

.cs-topnav__utility + .cs-topnav__utility::before {
  content: "";
  position: absolute;
  left: 0;
  top: var(--space-s);
  bottom: var(--space-s);
  border-left: var(--border-divider-section-width) solid var(--color-border-divider-default);
}

.cs-topnav__link,
.cs-topnav__env {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-xxs);
  font-size: var(--font-size-body-m);
  line-height: var(--line-height-body-m);
  font-weight: var(--font-weight-bold);
  letter-spacing: var(--font-button-letter-spacing);
  color: var(--color-text-interactive-default);
  text-decoration: none;
  white-space: nowrap;
}

.cs-topnav__link:hover,
.cs-topnav__link:active {
  color: var(--color-text-interactive-hover);
}

.cs-topnav__env--live {
  padding: 0 var(--space-xs);
  border-radius: var(--border-radius-badge);
  background: var(--color-background-badge-red);
  color: var(--color-text-badge-red);
}

.cs-topnav__year-form {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  height: 100%;
}

.cs-topnav__year {
  position: relative;
  display: flex;
  align-items: center;
  height: 100%;
  color: var(--color-text-interactive-default);
}

.cs-topnav__year:hover {
  color: var(--color-text-interactive-hover);
}

.cs-topnav__year > .cs-topnav__year-icon,
.cs-topnav__year > .cs-topnav__year-caret {
  position: absolute;
  pointer-events: none;
  top: calc(50% - var(--line-height-body-m) / 2);
}

.cs-topnav__year > .cs-topnav__year-icon {
  left: var(--space-xs);
}

.cs-topnav__year > .cs-topnav__year-caret {
  right: var(--space-xs);
  transition: transform var(--motion-duration-rotate-180) var(--motion-easing-rotate-180);
}

.cs-topnav__year-select {
  appearance: none;
  -webkit-appearance: none;
  height: 100%;
  margin: 0;
  padding: 0 calc(var(--space-xs) * 2 + var(--size-icon-normal)) 0 calc(var(--space-xs) * 2 + var(--size-icon-normal));
  border: none;
  border-radius: 0;
  background: transparent;
  color: inherit;
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}

.cs-topnav__year-select option {
  background: var(--color-background-dropdown-item-default);
  color: var(--color-text-dropdown-item-default);
}

.cs-topnav__label {
  white-space: nowrap;
}

/* The logged-in user and the Log out button (a form: logging out is a POST). */
.cs-topnav__logout {
  display: inline-flex;
  align-items: center;
  gap: var(--space-m);
  margin: 0;
}

.cs-topnav__user {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-xxs);
  font-size: var(--font-size-body-m);
  line-height: var(--line-height-body-m);
  color: var(--color-text-top-navigation-title, inherit);
  white-space: nowrap;
}

.cs-topnav__button {
  padding: 0;
  border: 0;
  background: none;
  font-family: inherit;
  cursor: pointer;
}

/* ---- Login page (app/templates/login.html) ---- */
.login {
  box-sizing: border-box;
  width: 100%;
  max-width: 420px;
  margin: 0 auto;
  padding: var(--space-xxxl, 40px) var(--space-l) var(--space-l);
}

.login__brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-xs);
  margin-bottom: var(--space-l);
  font-size: var(--font-size-heading-l);
  line-height: var(--line-height-heading-l);
  font-weight: var(--font-weight-heading-l);
}

.login__form .cs-input {
  width: 100%;
  box-sizing: border-box;
}

/* ---- Toolbar (nav trigger + breadcrumbs + drawer triggers) ---- */
.cs-toolbar {
  display: flex;
  align-items: center;
  height: var(--cs-toolbar-height);
  background: var(--color-background-layout-toolbar);
  border-bottom: var(--border-divider-section-width) solid var(--color-border-layout);
}

.cs-toolbar__start {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  padding: 0 var(--space-xxs) 0 var(--space-s);
}

.cs-toolbar__breadcrumbs {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0 var(--space-xs);
}

.cs-toolbar__end {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex-shrink: 0;
  padding: 0 var(--space-s);
}

.cs-toolbar__trigger {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--cs-toolbar-trigger-size);
  height: var(--cs-toolbar-trigger-size);
  margin: 0;
  padding: 0;
  border: none;
  border-radius: var(--border-radius-button);
  background: transparent;
  color: var(--color-text-interactive-default);
  cursor: pointer;
}

.cs-toolbar__trigger:hover {
  background: var(--color-background-input-disabled);
  color: var(--color-text-interactive-hover);
}

.cs-toolbar__trigger:active {
  background: var(--color-background-control-disabled);
}

.cs-toolbar__trigger.is-selected {
  background: var(--color-background-layout-toggle-selected-default);
  color: var(--color-text-layout-toggle-selected);
}

.cs-toolbar__trigger.is-selected:hover {
  background: var(--color-background-layout-toggle-selected-hover);
}

.cs-toolbar__trigger:focus-visible {
  outline: var(--cs-focus-ring-width) dotted transparent;
  outline-offset: var(--cs-focus-ring-width);
}

.cs-toolbar__trigger:focus-visible::before {
  inset: calc(-1 * var(--space-xxxs) - 1px); /* Cloudscape: trigger focus gutter 3px (ring: section 3) */
}

/* ---- Layout row: side navigation + main ---- */
.cs-app__layout {
  flex: 1 0 auto;
  display: flex;
  align-items: stretch;
}

.cs-app__nav {
  flex: 0 0 var(--cs-nav-offset);
  width: var(--cs-nav-offset);
  position: sticky;
  top: var(--cs-header-height);
  align-self: flex-start;
  height: calc(100vh - var(--cs-header-height));
  overflow-y: auto;
  overscroll-behavior-y: contain;
  z-index: var(--cs-z-nav);
  background: var(--color-background-layout-panel-content);
  border-right: var(--border-width-layout-side-navigation) solid var(--color-border-layout-side-navigation);
}

html.cs-nav-closed .cs-app__nav {
  display: none;
}

.cs-app__main {
  flex: 1 1 auto;
  min-width: 0;
  padding: 0 var(--space-layout-content-horizontal) calc(var(--space-layout-content-bottom) + var(--cs-split-panel-height));
  outline: none;
}

.cs-app__content {
  max-width: var(--cs-content-max-width);
  margin: 0 auto;
}

.cs-app__content--table {
  max-width: none;
}

@media (min-width: 1401px) {
  .cs-app__content--dashboard {
    max-width: var(--cs-dashboard-max-width);
  }
}

.cs-app__notifications:not(:empty) {
  padding-top: var(--space-scaled-xs);
}

.cs-app__body {
  margin-top: var(--space-scaled-s);
}

/* Page header block above the content (Cloudscape ContentLayout header). */
.cs-page-header {
  padding-bottom: var(--space-content-header-padding-bottom);
}

/* ---- Side navigation ---- */
.cs-sidenav {
  font-size: var(--font-size-body-m);
  line-height: var(--line-height-body-m);
}

.cs-sidenav__header {
  position: relative;
  padding: var(--space-panel-header-vertical) calc(var(--space-xxl) + var(--space-xl)) var(--space-panel-header-vertical) var(--space-panel-nav-left);
}

.cs-sidenav__title {
  font-size: var(--font-panel-header-size);
  line-height: var(--font-panel-header-line-height);
  letter-spacing: var(--letter-spacing-heading-m);
  font-weight: var(--font-weight-heading-m);
}

.cs-sidenav__title-link {
  color: var(--color-text-heading-default);
  text-decoration: none;
}

.cs-sidenav__title-link:hover {
  color: var(--color-text-link-hover);
}

.cs-sidenav__header > .cs-sidenav__close {
  position: absolute;
  top: calc(var(--space-s) + var(--space-xxxs)); /* Cloudscape: 14px */
  right: var(--space-m);
}

.cs-sidenav__close .cs-sidenav__close-mobile {
  display: none;
}

.cs-sidenav__body {
  margin-top: calc(-1 * var(--space-xxs));
  padding-bottom: var(--space-xxxl);
}

.cs-sidenav__list {
  list-style: none;
  margin: 0;
  padding: 0 calc(var(--space-xl) - var(--space-xs)) 0 calc(var(--space-panel-nav-left) - var(--space-xs));
}

.cs-sidenav__list--section {
  padding: 0;
}

.cs-sidenav__item {
  margin: 0;
  padding: 0 var(--space-xs);
}

.cs-sidenav__list--section > .cs-sidenav__item {
  padding: 0;
}

.cs-sidenav__link {
  display: flex;
  min-height: var(--size-side-navigation-item-height);
  margin: 0 calc(-1 * var(--space-xs));
  padding: var(--space-xxs) var(--space-xs);
  border-radius: var(--border-radius-side-navigation-item);
  color: var(--color-text-side-navigation-item-default);
  font-weight: var(--font-weight-normal);
  text-decoration: none;
}

.cs-sidenav__link:hover {
  color: var(--color-text-side-navigation-item-active);
}

.cs-sidenav__link[aria-current="page"] {
  color: var(--color-text-side-navigation-item-active);
  font-weight: var(--font-wayfinding-link-active-weight);
  background: var(--color-background-side-navigation-item-active);
}

.cs-sidenav__section {
  margin: calc(var(--space-scaled-xs) - var(--border-divider-section-width)) 0;
}

.cs-sidenav__section-toggle {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xxs);
  width: calc(100% + var(--space-l));
  margin: 0 0 0 calc(-1 * var(--space-l));
  padding: var(--space-xxs) 0;
  border: var(--border-divider-section-width) solid transparent;
  background: transparent;
  color: var(--color-text-expandable-section-default);
  font-size: var(--font-size-heading-s);
  line-height: var(--line-height-heading-s);
  letter-spacing: var(--letter-spacing-heading-s);
  font-weight: var(--font-weight-bold);
  text-align: left;
  cursor: pointer;
}

.cs-sidenav__section-toggle:hover {
  color: var(--color-text-expandable-section-hover);
}

.cs-sidenav__caret {
  transition: transform var(--motion-duration-rotate-90) var(--motion-easing-rotate-90);
}

.cs-sidenav__section-toggle[aria-expanded="false"] .cs-sidenav__caret {
  transform: rotate(-90deg);
}

.cs-sidenav__section-toggle[aria-expanded="false"] + .cs-sidenav__list {
  display: none;
}

.cs-sidenav__divider {
  margin: var(--space-scaled-2x-l) var(--space-l);
  border: none;
  border-top: var(--border-divider-section-width) solid var(--color-border-divider-default);
}

/* ---- Mobile: the navigation is a full-screen overlay (<= 688px, Cloudscape mobile breakpoint) ---- */
@media (max-width: 688px) {
  .cs-topnav__bar {
    padding-left: var(--space-l);
    padding-right: var(--space-xxs);
    gap: var(--space-xs);
  }

  /* Cloudscape: icon-only utilities keep a 20px gutter (the year menu 12px). */
  .cs-topnav__utility {
    padding: 0 var(--space-l);
  }

  .cs-topnav__utility--year {
    padding: 0 var(--space-s);
  }

  .cs-topnav__logo {
    display: none;
  }

  .cs-toolbar__trigger.is-selected,
  .cs-toolbar__trigger.is-selected:hover {
    background: transparent;
    color: var(--color-text-interactive-default);
  }

  html.js .cs-app__nav {
    display: none;
  }

  html.js.cs-nav-mobile-open .cs-app__nav {
    display: block;
    position: fixed;
    align-self: auto; /* a self-aligned fixed box would shrink to its content */
    top: calc(var(--cs-top-nav-height) + var(--cs-top-nav-border));
    left: 0;
    right: 0;
    bottom: 0;
    width: auto;
    height: auto;
    z-index: var(--cs-z-nav-overlay); /* above the sticky header: it covers the toolbar, not the top navigation */
    border-right: none;
  }

  html.cs-nav-mobile-open {
    overflow: hidden;
  }

  html.js .cs-sidenav__header {
    border-bottom: var(--border-panel-header-width) solid var(--color-border-panel-header);
  }

  html.js .cs-sidenav__title-link {
    color: var(--color-text-link-default);
  }

  .cs-sidenav__close .cs-sidenav__close-mobile {
    display: inline-block;
  }

  .cs-sidenav__close .cs-sidenav__close-desktop {
    display: none;
  }

  html.js .cs-sidenav__body {
    margin-top: var(--space-l);
  }

  /* Without JavaScript the navigation simply comes first, above the content. */
  html:not(.js) .cs-app__layout {
    flex-direction: column;
  }

  html:not(.js) .cs-app__nav {
    position: static;
    align-self: stretch;
    width: auto;
    height: auto;
    flex-basis: auto;
    border-right: none;
    border-bottom: var(--border-divider-section-width) solid var(--color-border-layout);
  }
}

/* Top navigation utilities collapse to icons when the bar gets narrow (with the S3 badge, which
   adds a long label, a little earlier: the title never ends in an ellipsis while labels show). */
@media (max-width: 912px) {
  .cs-topnav__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

@media (max-width: 950px) {
  .cs-topnav:has(.cs-topnav__utility--sync) .cs-topnav__label {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

/* Mobile with a fuller bar (live mode and/or the S3 badge): the phone layout below starts at
   688px instead of 465px - "All years" leaves for the side navigation and the year menu shows
   only its icon; in live mode the logo stands in for the title, so "LIVE: AWS SES" stays whole
   and the page never scrolls sideways. */
@media (max-width: 688px) {
  .cs-topnav--live .cs-topnav__utility--years,
  .cs-topnav:has(.cs-topnav__utility--sync) .cs-topnav__utility--years {
    display: none;
  }

  .cs-topnav--live .cs-topnav__year-select,
  .cs-topnav:has(.cs-topnav__utility--sync) .cs-topnav__year-select {
    width: calc(var(--size-icon-normal) + 2 * var(--space-xs));
    padding: 0;
    color: transparent;
  }

  .cs-topnav--live .cs-topnav__year > .cs-topnav__year-caret,
  .cs-topnav:has(.cs-topnav__utility--sync) .cs-topnav__year > .cs-topnav__year-caret {
    display: none;
  }

  .cs-topnav--live .cs-topnav__logo {
    display: inline-flex;
  }

  .cs-topnav--live .cs-topnav__title {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

/* Phones: the title keeps its size; "All years" is in the side navigation ("Competition
   years"), and the year menu shows only its icon: its value stays in the breadcrumbs, whose
   second item (the year) never collapses (section 5). */
@media (max-width: 465px) {
  .cs-topnav__utility--years {
    display: none;
  }

  .cs-topnav__year-select {
    width: calc(var(--size-icon-normal) + 2 * var(--space-xs));
    padding: 0;
    color: transparent;
  }

  .cs-topnav__year > .cs-topnav__year-caret {
    display: none;
  }

  /* Live mode: "LIVE: AWS SES" must stay whole, so the title gives way to the logo. */
  .cs-topnav--live .cs-topnav__logo {
    display: inline-flex;
  }

  .cs-topnav--live .cs-topnav__title {
    position: absolute;
    width: 1px;
    height: 1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }
}

/* With the S3 badge (one more icon cell), phones up to 395px already give the icon-only
   utilities the 8px gutter, so the title is not cut to "ICPC Invitati..." at 375-395px. */
@media (max-width: 395px) {
  .cs-topnav:has(.cs-topnav__utility--sync) .cs-topnav__utility,
  .cs-topnav:has(.cs-topnav__utility--sync) .cs-topnav__utility--year {
    padding: 0 var(--space-xs);
  }
}

/* Phones narrower than 375px (needed only there: live mode with the S3 badge; without it,
   375 and 390 keep Cloudscape's 56px utility cells): the icon-only utilities get an 8px gutter, and the
   LIVE badge may end in an ellipsis as a last resort (its text stays whole in the DOM:
   screen readers and tests read "LIVE: AWS SES"). */
@media (max-width: 374px) {
  .cs-topnav__bar {
    padding-left: var(--space-s);
  }

  .cs-topnav__utility,
  .cs-topnav__utility--year {
    padding: 0 var(--space-xs);
  }

  .cs-topnav__utilities,
  .cs-topnav__utility--env {
    min-width: 0;
    flex-shrink: 1;
  }

  .cs-topnav__env--live {
    min-width: 0;
    max-width: 100%;
  }

  .cs-topnav__env--live > span:last-child {
    min-width: 0;
    overflow: hidden;
    text-overflow: ellipsis;
  }
}

/* Short viewports (landscape phones, 200%-400% zoom): the app header scrolls away with the page
   instead of covering a third of the screen; the table header and the cloned column header do
   not stick either (section 18, app.js). */
@media (max-height: 559px) {
  .cs-app__header {
    position: static;
  }

  html {
    scroll-padding-top: calc(var(--cs-sticky-offset) + var(--space-s));
  }

  .cs-app__nav {
    top: 0;
    height: 100vh;
  }

  /* The mobile overlay then covers the whole window (the top navigation may have scrolled away). */
  html.js.cs-nav-mobile-open .cs-app__nav {
    top: 0;
  }
}

/* =========================================================================================
   5. Breadcrumbs
   ========================================================================================= */
.cs-breadcrumbs {
  padding: var(--space-xxs) 0;
  min-width: 0;
}

.cs-breadcrumbs__list {
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  list-style: none;
  margin: 0;
  padding: 0;
  min-width: 0;
}

.cs-breadcrumbs__item {
  display: flex;
  align-items: center;
  min-width: 0;
  flex-shrink: 0;
}

.cs-breadcrumbs__item:last-child {
  flex-shrink: 1;
}

/* Every crumb but the kept second one (the year) can end in an ellipsis, the root first and
   the current page next, so the toolbar never scrolls sideways (320px wide). */
.cs-breadcrumbs__link,
.cs-breadcrumbs__current {
  display: block;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

@media (max-width: 465px) {
  .cs-breadcrumbs__item {
    flex-shrink: 1;
  }

  .cs-breadcrumbs__item:first-child {
    flex-shrink: 4;
  }

  .cs-breadcrumbs__item:last-child {
    flex-shrink: 2;
  }
}

/* The second item (the year, or Settings) never shrinks: on phones the year menu of the top
   navigation shows only its icon, so this is where the year stays readable. */
.cs-breadcrumbs__item.cs-breadcrumbs__item--keep {
  flex-shrink: 0;
}

.cs-breadcrumbs__link {
  color: var(--color-text-link-default);
}

.cs-breadcrumbs__current {
  color: var(--color-text-breadcrumb-current);
  font-weight: var(--font-weight-breadcrumb-current);
  cursor: default;
}

.cs-breadcrumbs .cs-breadcrumbs__separator {
  margin: 0 var(--space-xs);
  color: var(--color-text-breadcrumb-icon); /* more specific than .cs-icon { color: inherit } */
}

/* Overflow (Cloudscape): on narrow screens the section items of a long trail (the ones between
   the kept year and the current page) collapse into an ellipsis menu ("Show path"), so the
   root, the year and the current page keep readable widths. Three-item trails never collapse. */
.cs-breadcrumbs__item--ellipsis {
  display: none;
}

/* Its trigger is Cloudscape's blue "..." text (no border, no background), with the usual
   inline-icon focus ring. */
.cs-breadcrumbs__item--ellipsis .cs-dropdown__trigger {
  padding: 0 var(--space-xxxs);
  color: var(--color-text-link-default);
}

.cs-breadcrumbs__item--ellipsis .cs-dropdown__trigger:hover,
.cs-breadcrumbs__item--ellipsis .cs-dropdown__trigger:active {
  color: var(--color-text-link-hover);
}

.cs-dropdown__trigger-text {
  display: block;
  font-weight: var(--font-weight-normal);
  line-height: var(--line-height-body-m);
}

@media (max-width: 688px) {
  .cs-breadcrumbs--long .cs-breadcrumbs__item--middle {
    display: none;
  }

  .cs-breadcrumbs--long .cs-breadcrumbs__item--ellipsis {
    display: flex;
  }
}

/* =========================================================================================
   6. Header (h1 / h2 / h3 + counter + description + actions)
   ========================================================================================= */
.cs-header {
  display: flex;
  flex-direction: column;
  row-gap: var(--space-scaled-xxs);
  width: 100%;
}

.cs-header__main {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  column-gap: var(--space-xs);
  row-gap: var(--space-scaled-xxs);
}

.cs-header__title {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  min-width: 0;
  overflow-wrap: anywhere;
}

.cs-header__heading {
  display: inline;
  margin: 0;
}

/* Typography comes from the base h1 / h2 / h3 rules (the heading tag follows the variant). */
.cs-header--h1.cs-header--with-actions .cs-header__title {
  padding-top: 1px; /* Cloudscape: centres the 30px title with the 32px actions */
}

/* Cloudscape (visual refresh): an h2 title always sits 4px down in its 28px box, with or
   without actions, so a container header is 48px tall. */
.cs-header--h2 .cs-header__title {
  padding-top: var(--space-xxs);
}

.cs-header--h3.cs-header--with-actions .cs-header__title {
  padding-top: calc(var(--space-xxs) + 1px);
}

/* header(icon_name=...): a 16px icon before the title text, centred on the heading's line
   (its box is one heading line tall, the svg centred in it by the padding). */
.cs-header__heading > .cs-header__icon {
  margin-right: var(--space-xs);
  --cs-header-icon-line: var(--line-height-heading-l);
  height: var(--cs-header-icon-line);
  padding: calc((var(--cs-header-icon-line) - var(--size-icon-normal)) / 2) 0;
}

.cs-header--h1 .cs-header__heading > .cs-header__icon { --cs-header-icon-line: var(--line-height-heading-xl); }
.cs-header--h3 .cs-header__heading > .cs-header__icon { --cs-header-icon-line: var(--line-height-heading-m); }

.cs-header__counter {
  color: var(--color-text-counter);
  font-weight: var(--font-weight-normal);
}

.cs-header__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
  min-height: var(--size-vertical-input);
}

.cs-header__description {
  min-width: 0;
  margin: 0;
  overflow-wrap: anywhere; /* a long unbroken team name never widens the page */
  color: var(--color-text-heading-secondary);
  font-size: var(--font-header-h2-description-size);
  line-height: var(--font-header-h2-description-line-height);
}

/* =========================================================================================
   7. Container
   ========================================================================================= */
.cs-container {
  position: relative;
  min-width: 0;
  overflow-wrap: break-word;
  background: var(--color-background-container-content);
  border: var(--border-divider-section-width) solid var(--color-border-divider-default);
  border-radius: var(--border-radius-container);
}

.cs-container__header {
  padding: var(--space-container-header-top) var(--space-container-horizontal) var(--space-container-header-bottom);
  background: var(--color-background-container-header);
  border-radius: var(--border-radius-container) var(--border-radius-container) 0 0;
}

.cs-container__content {
  padding: var(--space-scaled-l) var(--space-container-horizontal);
}

.cs-container__header + .cs-container__content {
  padding-top: var(--space-container-content-top);
}

.cs-container__footer {
  padding: var(--space-scaled-s) var(--space-container-horizontal);
  border-top: var(--border-divider-section-width) solid var(--color-border-divider-default);
}

/* A "Danger zone" container (user decision, "subtle red accent"): error-red border, same
   width and radius, and a red header icon (container(icon_name="status-warning")). */
.danger-zone {
  border-color: var(--color-border-status-error);
}

.danger-zone .cs-header__icon {
  color: var(--color-text-status-error);
}

/* Cloudscape: no container chrome inside a split panel; the detail-page containers shown
   there lose their border and background. */
.cs-split-panel__content .cs-container {
  border: none;
  border-radius: 0;
  background: transparent;
}

.cs-split-panel__content .cs-container > .cs-container__header,
.cs-split-panel__content .cs-container > .cs-container__content,
.cs-split-panel__content .cs-container > .cs-container__footer {
  background: transparent;
  padding-left: 0;
  padding-right: 0;
}

/* =========================================================================================
   8. Layout helpers: space between, column layout
   ========================================================================================= */
.cs-space-between {
  display: flex;
}

/* Empty slots take no gap (Cloudscape SpaceBetween skips empty children). Void and
   replaced elements always match :empty, so they are excluded: an <input>, <iframe> or
   empty <textarea> placed directly in a space_between stays visible. */
.cs-space-between > :empty:not(input, textarea, select, iframe, img, hr, progress, svg, canvas, video, audio, object, embed) {
  display: none;
}

.cs-space-between--vertical {
  flex-direction: column;
}

.cs-space-between--vertical > * {
  min-width: 0;
}

.cs-space-between--horizontal {
  flex-wrap: wrap;
  align-items: flex-start;
}

.cs-space-between--xxs { gap: var(--space-xxs); }
.cs-space-between--xs { gap: var(--space-xs); }
.cs-space-between--s { gap: var(--space-s); }
.cs-space-between--m { gap: var(--space-m); }
.cs-space-between--l { gap: var(--space-l); }

.cs-space-between--vertical.cs-space-between--s { gap: var(--space-scaled-s); }
.cs-space-between--vertical.cs-space-between--m { gap: var(--space-scaled-m); }
.cs-space-between--vertical.cs-space-between--l { gap: var(--space-scaled-l); }

.cs-columns {
  container-type: inline-size;
  display: grid;
  grid-template-columns: repeat(var(--cs-columns, 2), minmax(0, 1fr));
  gap: var(--space-grid-gutter);
}

.cs-columns--1 { --cs-columns: 1; }
.cs-columns--2 { --cs-columns: 2; }
.cs-columns--3 { --cs-columns: 3; }
.cs-columns--4 { --cs-columns: 4; }

@media (max-width: 688px) {
  .cs-columns--3,
  .cs-columns--4 { --cs-columns: 2; }
}

@media (max-width: 465px) {
  .cs-columns { --cs-columns: 1; }
}

.cs-columns--borders-horizontal > * + * {
  border-top: var(--border-divider-section-width) solid var(--color-border-divider-default);
  padding-top: var(--space-grid-gutter);
}

.cs-columns--borders-horizontal {
  grid-template-columns: minmax(0, 1fr);
}

/* borders="vertical": a divider between columns (Cloudscape ColumnLayout borders="vertical").
   The macro wraps it in .cs-columns-wrap so the first column's divider falls in the clipped
   gutter. */
.cs-columns--borders-vertical {
  column-gap: 0;
  margin: 0 calc(-1 * var(--space-grid-gutter) / 2);
}

.cs-columns--borders-vertical > * {
  position: relative;
  padding: 0 calc(var(--space-grid-gutter) / 2);
}

.cs-columns--borders-vertical > *::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-left: var(--border-divider-section-width) solid var(--color-border-divider-default);
}

/* Clips the first column's divider (see .cs-kv-wrap). */
.cs-columns-wrap {
  overflow-x: clip;
  overflow-clip-margin: var(--space-xxs);
}

/* =========================================================================================
   9. Key-value pairs (Cloudscape KeyValuePairs = ColumnLayout text-grid)
   ========================================================================================= */
.cs-kv-wrap {
  container-type: inline-size;
  /* Every pair draws a left divider; the ones of the first column fall in the clipped
     gutter, so dividers only show between columns, whatever the column count or wide rows. */
  overflow-x: clip;
  overflow-clip-margin: var(--space-xxs);
}

.cs-kv {
  --cs-kv-columns: 3;
  display: grid;
  grid-template-columns: repeat(var(--cs-kv-columns), minmax(0, 1fr));
  margin: calc(-1 * var(--space-grid-gutter) / 2) calc(-1 * var(--space-l));
  padding: 0;
}

.cs-kv--1 { --cs-kv-columns: 1; }
.cs-kv--2 { --cs-kv-columns: 2; }
.cs-kv--3 { --cs-kv-columns: 3; }
.cs-kv--4 { --cs-kv-columns: 4; }

/* Cloudscape KeyValuePairs: as many columns as fit at a minimum width of 150px each. */
@container (max-width: 599px) {
  .cs-kv--4 { --cs-kv-columns: 3; }
}

@container (max-width: 449px) {
  .cs-kv--3,
  .cs-kv--4 { --cs-kv-columns: 2; }
}

@container (max-width: 299px) {
  .cs-kv { --cs-kv-columns: 1; }
}

.cs-kv__pair {
  position: relative;
  min-width: 0;
  margin: calc(var(--space-grid-gutter) / 2) 0;
  padding: 0 var(--space-l);
  overflow-wrap: anywhere;
}

.cs-kv__pair::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  border-left: var(--border-divider-section-width) solid var(--color-border-divider-default);
}

.cs-kv__pair--wide {
  grid-column: 1 / -1;
}

.cs-kv__key {
  margin: 0;
  color: var(--color-text-label);
  font-size: var(--font-size-key-value-pairs-label);
  line-height: var(--line-height-key-value-pairs-label);
  font-weight: var(--font-weight-key-value-pairs-label);
}

.cs-kv__value {
  margin: var(--space-key-value-gap) 0 0;
  color: var(--color-text-key-value-pairs-value);
}

.cs-kv__value--large {
  font-size: var(--font-size-display-l);
  line-height: var(--line-height-display-l);
  letter-spacing: var(--letter-spacing-display-l);
  font-weight: var(--font-weight-display-l);
}

/* A status line under a large value (dashboard counters: the count, then "Needs attention"). */
.cs-kv__value--large > .cs-status {
  display: block;
  margin-top: var(--space-xxs);
  font-size: var(--font-size-body-m);
  line-height: var(--line-height-body-m);
  letter-spacing: normal; /* Cloudscape: body-m has no letter spacing token */
  font-weight: var(--font-weight-normal);
}

/* A small second line under a value (key-value pairs, table cells). */
.cs-kv__secondary,
.cs-table__secondary {
  display: block;
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-s);
  letter-spacing: var(--letter-spacing-body-s);
  color: var(--color-text-body-secondary);
}

/* =========================================================================================
   10. Icon + spinner
   ========================================================================================= */
.cs-icon {
  position: relative;
  display: inline-block;
  vertical-align: top;
  flex-shrink: 0;
  width: var(--size-icon-normal);
  height: var(--line-height-body-m);
  padding: calc((var(--line-height-body-m) - var(--size-icon-normal)) / 2) 0;
  color: inherit;
}

.cs-icon > svg {
  display: block;
  width: 100%;
  height: 100%;
  fill: none;
  stroke: currentColor;
  stroke-width: var(--border-width-icon-normal);
  pointer-events: none;
}

.cs-icon--small {
  height: var(--size-icon-normal);
  padding: 0;
}

.cs-icon--medium {
  width: var(--size-icon-medium);
  height: calc(var(--size-icon-medium) + var(--space-xxs));
  padding: var(--space-xxxs) 0;
}

.cs-icon--medium > svg {
  stroke-width: calc(var(--border-width-icon-medium) * 0.8); /* Cloudscape: 1.6 units at 20px = 2px */
}

.cs-icon--subtle { color: var(--color-text-icon-subtle); }

.cs-spinner {
  display: inline-block;
  vertical-align: top;
  line-height: 0;
  flex-shrink: 0;
  color: currentColor;
  animation: cs-spinner-rotator 0.7s linear infinite; /* Cloudscape: fixed spinner timing */
}

.cs-spinner--normal {
  width: var(--size-icon-normal);
  height: var(--size-icon-normal);
  padding: var(--space-xxxs);
  margin: calc((var(--line-height-body-m) - var(--size-icon-normal)) / 2) 0;
}

.cs-spinner__circle {
  position: relative;
  display: inline-block;
  width: 50%;
  height: 100%;
  overflow: hidden;
}

.cs-spinner__circle::after {
  content: "";
  position: absolute;
  top: 0;
  left: 0;
  width: 200%;
  height: 100%;
  border: var(--border-width-icon-normal) solid;
  border-right-color: transparent;
  border-bottom-color: transparent;
  border-radius: 50%;
  animation: 1.5s ease-in-out infinite; /* Cloudscape: fixed spinner timing */
}

.cs-spinner__circle--left::after {
  animation-name: cs-spinner-line-left;
}

.cs-spinner__circle--right::after {
  left: -100%;
  animation-name: cs-spinner-line-right;
}

/* =========================================================================================
   11. Button
   ========================================================================================= */
.cs-button {
  position: relative;
  display: inline-block;
  margin: 0;
  padding: var(--space-button-vertical) var(--space-button-horizontal);
  border: var(--border-width-button) solid var(--color-border-button-normal-default);
  border-radius: var(--border-radius-button);
  background: var(--color-background-button-normal-default);
  color: var(--color-text-button-normal-default);
  font-family: var(--font-family-base);
  font-size: var(--font-size-body-m);
  line-height: var(--line-height-body-m);
  font-weight: var(--font-weight-button);
  letter-spacing: var(--font-button-letter-spacing);
  text-align: center;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
  -webkit-appearance: none;
  appearance: none;
}

.cs-button:hover {
  background: var(--color-background-button-normal-hover);
  border-color: var(--color-border-button-normal-hover);
  color: var(--color-text-button-normal-hover);
  text-decoration: none;
}

.cs-button:active {
  background: var(--color-background-button-normal-active);
  border-color: var(--color-border-button-normal-active);
  color: var(--color-text-button-normal-active);
}

.cs-button:focus-visible {
  outline: var(--cs-focus-ring-width) dotted transparent;
  outline-offset: calc(var(--space-button-focus-outline-gutter) - 1px);
  border-radius: var(--border-radius-button); /* a link-button keeps its pill (not a:focus-visible's 4px) */
  box-shadow: none;
}

.cs-button:focus-visible::before {
  /* the ring itself: section 3 */
  top: calc(-1 * var(--space-button-focus-outline-gutter));
  left: calc(-1 * var(--space-button-focus-outline-gutter));
  width: calc(100% + 2 * var(--space-button-focus-outline-gutter));
  height: calc(100% + 2 * var(--space-button-focus-outline-gutter));
}

.cs-button--primary {
  background: var(--color-background-button-primary-default);
  border-color: var(--color-border-button-primary-default);
  color: var(--color-text-button-primary-default);
}

.cs-button--primary:hover {
  background: var(--color-background-button-primary-hover);
  border-color: var(--color-border-button-primary-hover);
  color: var(--color-text-button-primary-hover);
}

.cs-button--primary:active {
  background: var(--color-background-button-primary-active);
  border-color: var(--color-border-button-primary-active);
  color: var(--color-text-button-primary-active);
}

.cs-button--link {
  background: var(--color-background-button-link-default);
  border-color: transparent;
  color: var(--color-text-link-button-normal-default);
}

.cs-button--link:hover {
  background: var(--color-background-button-link-hover);
  border-color: var(--color-background-button-link-hover);
  color: var(--color-text-link-button-normal-hover);
}

.cs-button--link:active {
  background: var(--color-background-button-link-active);
  border-color: var(--color-background-button-link-active);
  color: var(--color-text-link-button-normal-active);
}

/* Destructive actions (user decision, "subtle red accent"; Cloudscape has no danger variant):
   class="cs-button--danger" on a normal or primary button gives error-red text and border on
   a white background (never a red fill), darker red on hover / active. The focus ring is the
   shared one. Disabled and busy buttons are excluded, so they keep the disabled look below. */
.cs-button--danger:not(:disabled):not([aria-disabled="true"]) {
  background: var(--color-background-button-normal-default);
  border-color: var(--color-border-status-error);
  color: var(--color-text-status-error);
}

.cs-button--danger:not(:disabled):not([aria-disabled="true"]):hover {
  background: var(--color-background-status-error);
  border-color: var(--color-error-800);
  color: var(--color-error-800);
}

.cs-button--danger:not(:disabled):not([aria-disabled="true"]):active {
  background: var(--color-background-status-error);
  border-color: var(--color-error-900);
  color: var(--color-error-900);
}

.cs-button--icon,
.cs-button--inline-icon {
  padding: var(--space-button-vertical) var(--space-xxs);
  border-color: transparent;
  background: transparent;
  color: var(--color-text-interactive-default);
}

.cs-button--icon:hover,
.cs-button--icon:active {
  border-color: transparent;
  background: transparent;
  color: var(--color-text-button-icon-hover);
}

.cs-button--inline-icon {
  padding: 0 var(--space-xxs);
  border-width: 0;
  color: var(--color-text-button-inline-icon-default);
}

.cs-button--inline-icon:hover,
.cs-button--inline-icon:active {
  background: transparent;
  color: var(--color-text-button-inline-icon-hover);
}

.cs-button--icon:focus-visible::before {
  top: calc(-1 * var(--space-button-icon-focus-outline-gutter-vertical));
  height: calc(100% + 2 * var(--space-button-icon-focus-outline-gutter-vertical));
}

.cs-button--inline-icon:focus-visible::before {
  top: calc(-1 * var(--space-button-inline-icon-focus-outline-gutter));
  left: calc(-1 * var(--space-button-inline-icon-focus-outline-gutter));
  width: calc(100% + 2 * var(--space-button-inline-icon-focus-outline-gutter));
  height: calc(100% + 2 * var(--space-button-inline-icon-focus-outline-gutter));
}

/* A normal / primary button with only an icon: 32 x 32. */
.cs-button--normal.cs-button--icon-only,
.cs-button--primary.cs-button--icon-only {
  padding-left: var(--space-button-icon-only-horizontal);
  padding-right: var(--space-button-icon-only-horizontal);
}

.cs-button__icon--left {
  position: relative;
  left: calc(-1 * var(--space-xxs));
  margin-right: var(--space-xxs);
}

.cs-button__icon--right {
  position: relative;
  right: calc(-1 * var(--space-xxs));
  margin-left: var(--space-xxs);
}

.cs-button--icon-only .cs-button__icon--left,
.cs-button--icon .cs-button__icon--left,
.cs-button--inline-icon .cs-button__icon--left {
  left: 0;
  margin-right: 0;
}

/* Disabled and busy (app.js: disabled + data-busy) states. */
.cs-button:disabled,
.cs-button[aria-disabled="true"] {
  cursor: default;
  background: var(--color-background-button-normal-disabled);
  border-color: var(--color-border-button-normal-disabled);
  color: var(--color-text-button-normal-disabled);
}

.cs-button--primary:disabled,
.cs-button--primary[aria-disabled="true"] {
  background: var(--color-background-button-primary-disabled);
  border-color: var(--color-border-button-primary-disabled);
  color: var(--color-text-button-primary-disabled);
}

.cs-button--link:disabled,
.cs-button--link[aria-disabled="true"] {
  background: transparent;
  border-color: transparent;
  color: var(--color-text-interactive-disabled);
}

.cs-button--icon:disabled,
.cs-button--icon[aria-disabled="true"],
.cs-button--inline-icon:disabled,
.cs-button--inline-icon[aria-disabled="true"] {
  background: transparent;
  border-color: transparent;
  color: var(--color-text-button-icon-disabled);
}

/* app.js busy state: a spinner replaces the left icon, the label reads "Working..." (or the
   button's data-busy-text). An icon-only trigger (row "..." menu) shows only the spinner. */
.cs-button[data-busy] .cs-icon.cs-button__icon--left,
.cs-button--icon-only[data-busy] > .cs-icon {
  display: none;
}

.cs-button .cs-spinner.cs-button__icon--left,
.cs-menu__action .cs-spinner {
  color: var(--color-text-status-inactive);
}

/* A row of buttons (Cloudscape SpaceBetween horizontal xs); also the form actions. */
.cs-button-row,
.cs-form__secondary {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
  min-height: var(--size-vertical-input);
}

/* Forms that hold a single button inline (row actions). */
.cs-inline-form {
  display: inline;
  margin: 0;
}

/* =========================================================================================
   12. Button dropdown + menu (a <details> element; app.js adds keyboard support)
   ========================================================================================= */
.cs-dropdown {
  position: relative;
  display: inline-block;
  vertical-align: top;
}

.cs-dropdown__details > summary {
  list-style: none;
}

.cs-dropdown__details > summary::-webkit-details-marker {
  display: none;
}

.cs-dropdown__caret {
  transition: transform var(--motion-duration-rotate-180) var(--motion-easing-rotate-180);
}

.cs-dropdown__details[open] .cs-dropdown__caret {
  transform: rotate(-180deg);
}

.cs-dropdown__menu {
  position: absolute;
  top: calc(100% + var(--space-xxs));
  left: 0;
  z-index: var(--cs-z-dropdown);
  min-width: max(100%, var(--cs-menu-min-width));
  max-width: min(var(--cs-dropdown-max-width), calc(100vw - 2 * var(--space-xs)));
  width: max-content;
  background: var(--color-background-dropdown-item-default);
  border-radius: var(--border-radius-dropdown);
  box-shadow: var(--shadow-dropdown);
  animation: var(--motion-keyframes-fade-in) var(--motion-duration-show-quick) var(--motion-easing-show-quick);
}

.cs-dropdown__menu::after {
  content: "";
  position: absolute;
  inset: 0;
  border: var(--border-width-dropdown) solid var(--color-border-dropdown-container);
  border-radius: var(--border-radius-dropdown);
  pointer-events: none;
}

.cs-dropdown--end .cs-dropdown__menu {
  left: auto;
  right: 0;
}

.cs-dropdown__menu.is-fixed {
  position: fixed;
  min-width: var(--cs-menu-min-width); /* 100% would be the viewport */
}

.cs-dropdown__menu.is-dropup {
  top: auto;
  bottom: calc(100% + var(--space-xxs));
}

.cs-menu,
.cs-menu__group-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.cs-menu {
  padding: var(--space-xxxs) 0;
}

.cs-menu__item {
  position: relative;
  margin-top: calc(-1 * var(--border-item-width));
  border: var(--border-item-width) solid transparent;
  border-radius: var(--border-radius-item);
}

.cs-menu__item:first-child {
  margin-top: 0;
}

.cs-menu__form {
  margin: 0;
}

/* Label and external icon share the first line; a description takes a line of its own. */
.cs-menu__action {
  display: flex;
  flex-flow: row wrap;
  align-items: center;
  width: 100%;
  margin: 0;
  padding: var(--space-option-padding-vertical) var(--space-option-padding-horizontal);
  border: none;
  background: transparent;
  color: var(--color-text-dropdown-item-default);
  font-weight: var(--font-weight-normal);
  text-align: left;
  text-decoration: none;
  cursor: pointer;
}

.cs-menu__action:hover {
  color: var(--color-text-dropdown-item-highlighted);
}

.cs-menu__label {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-xxs);
}

.cs-menu__external {
  margin-left: var(--space-xxs);
}

.cs-menu__description {
  display: block;
  flex-basis: 100%;
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-s);
  letter-spacing: var(--letter-spacing-body-s);
  color: var(--color-text-dropdown-item-secondary);
}

.cs-menu__item:hover:not(.cs-menu__item--disabled),
.cs-menu__item:focus-within:not(.cs-menu__item--disabled) {
  z-index: 2; /* Cloudscape: the highlighted item's border overlaps its neighbours' */
  background: var(--color-background-dropdown-item-hover);
  border-color: var(--color-border-dropdown-item-hover);
}

.cs-menu__item:focus-within {
  border-color: var(--color-border-dropdown-item-focused);
}

.cs-menu__action:focus,
.cs-menu__action:focus-visible {
  outline: none;
  box-shadow: none;
}

/* Destructive items (class="cs-menu__item--danger", section 15b of the design decisions):
   error-red label text, darker while highlighted; a disabled one stays grey (below). */
.cs-menu__item--danger:not(.cs-menu__item--disabled) > .cs-menu__action,
.cs-menu__item--danger:not(.cs-menu__item--disabled) > .cs-menu__form > .cs-menu__action {
  color: var(--color-text-status-error);
}

.cs-menu__item--danger:not(.cs-menu__item--disabled):hover > .cs-menu__action,
.cs-menu__item--danger:not(.cs-menu__item--disabled):focus-within > .cs-menu__action,
.cs-menu__item--danger:not(.cs-menu__item--disabled):hover > .cs-menu__form > .cs-menu__action,
.cs-menu__item--danger:not(.cs-menu__item--disabled):focus-within > .cs-menu__form > .cs-menu__action {
  color: var(--color-error-800);
}

.cs-menu__item--disabled .cs-menu__action,
.cs-menu__action:disabled,
.cs-menu__action[aria-disabled="true"] {
  color: var(--color-text-dropdown-item-disabled);
  cursor: default;
}

.cs-menu__item--disabled:hover,
.cs-menu__item--disabled:focus-within {
  z-index: 2; /* as above */
  border-color: var(--color-border-dropdown-item-hover);
}

/* The disabled reason: read with the item by screen readers, shown as a tooltip (app.js)
   on hover / focus, as Cloudscape's disabledReason. */
.cs-menu__item--disabled .cs-menu__description {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

/* Windows High Contrast: every item gets a forced border, so mark the focused one. */
@media (forced-colors: active) {
  .cs-menu__item {
    border-color: Canvas;
  }

  .cs-menu__item:focus-within {
    outline: var(--cs-focus-ring-width) solid Highlight;
    outline-offset: calc(-1 * var(--cs-focus-ring-width));
  }
}

/* Tooltip (Cloudscape Tooltip = a small popover): one shared element positioned by app.js.
   It takes the pointer (WCAG 1.4.13: moving onto it keeps it open) and Esc dismisses it. */
.cs-tooltip {
  position: fixed;
  z-index: var(--cs-z-tooltip);
  max-width: min(var(--cs-tooltip-max-width), calc(100vw - 2 * var(--space-xs)));
  padding: var(--space-xs) var(--space-s);
  border: var(--border-width-popover) solid var(--color-border-popover);
  border-radius: var(--border-radius-popover);
  background: var(--color-background-popover);
  box-shadow: var(--shadow-popover);
  color: var(--color-text-body-default);
  font-size: var(--font-size-body-m);
  line-height: var(--line-height-body-m);
  pointer-events: auto;
  animation: var(--motion-keyframes-fade-in) var(--motion-duration-tooltip-enter) var(--motion-easing-tooltip-enter);
}

/* Last-resort placement over other menu items (no room beside the item nor outside the
   menu): it lets taps and clicks through to the items beneath it. */
.cs-tooltip--passive {
  pointer-events: none;
}

/* Its arrow faces the item (app.js sets data-placement and --cs-tooltip-arrow-at, the
   arrow's position along that edge): a rotated square whose two outer sides carry the
   border; its inner half covers the tooltip's own border where they meet. */
.cs-tooltip::before {
  content: "";
  position: absolute;
  width: var(--cs-popover-arrow-side);
  height: var(--cs-popover-arrow-side);
  border: var(--border-width-popover) solid var(--color-border-popover);
  background: var(--color-background-popover);
  transform: rotate(45deg);
}

.cs-tooltip[data-placement="right"]::before,
.cs-tooltip[data-placement="left"]::before {
  top: calc(var(--cs-tooltip-arrow-at, 50%) - var(--cs-popover-arrow-side) / 2);
}

.cs-tooltip[data-placement="right"]::before {
  left: calc(-1 * var(--border-width-popover) - var(--cs-popover-arrow-side) / 2);
  border-top-color: transparent;
  border-right-color: transparent;
}

.cs-tooltip[data-placement="left"]::before {
  right: calc(-1 * var(--border-width-popover) - var(--cs-popover-arrow-side) / 2);
  border-bottom-color: transparent;
  border-left-color: transparent;
}

.cs-tooltip[data-placement="bottom"]::before,
.cs-tooltip[data-placement="top"]::before {
  left: calc(var(--cs-tooltip-arrow-at, 50%) - var(--cs-popover-arrow-side) / 2);
}

.cs-tooltip[data-placement="bottom"]::before {
  top: calc(-1 * var(--border-width-popover) - var(--cs-popover-arrow-side) / 2);
  border-right-color: transparent;
  border-bottom-color: transparent;
}

.cs-tooltip[data-placement="top"]::before {
  bottom: calc(-1 * var(--border-width-popover) - var(--cs-popover-arrow-side) / 2);
  border-top-color: transparent;
  border-left-color: transparent;
}

/* Placed below or above the whole menu (phones, app.js): every item shares the menu's edge,
   so an arrow there would point at the first or last item, not at the one it explains. */
.cs-tooltip--detached::before {
  display: none;
}

.cs-menu__group-label {
  display: block;
  padding: calc(var(--space-xxs) + 1px) calc(var(--space-l) + var(--space-xxxs));
  color: var(--color-text-dropdown-group-label);
  font-weight: var(--font-weight-bold);
}

.cs-menu__group-label + .cs-menu__group-list .cs-menu__action {
  padding-left: calc(var(--space-l) + var(--space-xs));
}

.cs-menu__group + .cs-menu__group,
.cs-menu__group + .cs-menu__item,
.cs-menu__item + .cs-menu__group {
  border-top: var(--border-item-width) solid var(--color-border-dropdown-group);
}

.cs-menu__item + .cs-menu__group,
.cs-menu__group + .cs-menu__item {
  margin-top: 0;
}

/* =========================================================================================
   13. Status indicator + badge
   ========================================================================================= */
.cs-status {
  display: inline-block;
  color: var(--cs-status-color, var(--color-text-status-inactive));
  border-radius: var(--border-radius-status-indicator);
}

.cs-status__icon {
  display: inline-block;
  vertical-align: top;
  padding-right: var(--space-xxs);
}

.cs-status--nowrap {
  white-space: nowrap;
}

.cs-status--success { --cs-status-color: var(--color-text-status-success); }
.cs-status--error { --cs-status-color: var(--color-text-status-error); }
.cs-status--warning { --cs-status-color: var(--color-text-status-warning); }
.cs-status--info { --cs-status-color: var(--color-text-status-info); }
.cs-status--stopped,
.cs-status--pending,
.cs-status--in-progress,
.cs-status--loading,
.cs-status--not-started { --cs-status-color: var(--color-text-status-inactive); }

/* Cloudscape shakes only a freshly shown form-field error, never status indicators. */
.cs-form-field__error > .cs-icon {
  animation: var(--motion-keyframes-status-icon-error) var(--motion-duration-expressive) linear;
}

.cs-status-code {
  margin-left: var(--space-xxs);
  color: var(--color-text-body-secondary);
}

.cs-badge {
  display: inline-block;
  vertical-align: top;
  padding: 0 var(--space-xs);
  border: var(--border-width-badge) solid var(--color-border-badge);
  border-radius: var(--border-radius-badge);
  background: var(--color-background-badge-grey);
  color: var(--color-text-badge-grey);
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-m);
  letter-spacing: var(--letter-spacing-body-s);
  white-space: nowrap;
}

/* In a key-value pair (narrow columns on phones) a long badge wraps instead of running into
   the next column. */
.cs-kv__value .cs-badge {
  max-width: 100%;
  white-space: normal;
}

/* Domain status flags under an email status (m.status_flags): small coloured texts, " · ". */
.status-flags {
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-s);
  letter-spacing: var(--letter-spacing-body-s);
  white-space: normal;
}

.status-flags span + span::before {
  content: " · ";
  color: var(--color-text-body-secondary);
}

.status-flag--error { color: var(--color-text-status-error); }
.status-flag--warning { color: var(--color-text-status-warning); }
.status-flag--muted { color: var(--color-text-status-inactive); }

.cs-status + .cs-badge,
.cs-status-code + .cs-badge {
  margin-left: var(--space-xxs);
}

.cs-badge--red { background: var(--color-background-badge-red); color: var(--color-text-badge-red); }

/* =========================================================================================
   14. Alert + flashbar
   ========================================================================================= */
.cs-alert {
  display: flex;
  align-items: flex-start;
  padding: var(--space-alert-vertical) var(--space-alert-horizontal);
  border: var(--border-width-alert) solid var(--cs-alert-border, var(--color-border-status-info));
  border-radius: var(--border-radius-alert);
  background: var(--cs-alert-background, var(--color-background-status-info));
  color: var(--color-text-alert-default);
  overflow-wrap: break-word;
  animation: var(--motion-keyframes-fade-in) var(--motion-duration-show-paced) var(--motion-easing-show-paced);
}

.cs-alert--info { --cs-alert-border: var(--color-border-status-info); --cs-alert-background: var(--color-background-status-info); --cs-alert-icon: var(--color-text-status-info); }
.cs-alert--success { --cs-alert-border: var(--color-border-status-success); --cs-alert-background: var(--color-background-status-success); --cs-alert-icon: var(--color-text-status-success); }
.cs-alert--warning { --cs-alert-border: var(--color-border-status-warning); --cs-alert-background: var(--color-background-status-warning); --cs-alert-icon: var(--color-text-status-warning); }
.cs-alert--error { --cs-alert-border: var(--color-border-status-error); --cs-alert-background: var(--color-background-status-error); --cs-alert-icon: var(--color-text-status-error); }

.cs-alert__icon {
  flex-shrink: 0;
  margin: var(--space-xxs) 0;
  color: var(--cs-alert-icon);
}

.cs-alert__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  column-gap: var(--space-s);
}

.cs-alert__message {
  flex: 1 1 70%;
  min-width: 0;
  margin: var(--space-xxs) var(--space-alert-message-right) var(--space-xxs) var(--space-xs);
}

.cs-alert__header {
  font-weight: var(--font-weight-alert-header);
}

.cs-alert__content > :first-child { margin-top: 0; }
.cs-alert__content > :last-child { margin-bottom: 0; }

.cs-alert__content ul,
.cs-alert__content ol {
  margin: var(--space-xxs) 0;
}

.cs-alert__action {
  white-space: nowrap;
  margin: var(--space-xxs) 0;
}

.cs-alert__dismiss {
  flex-shrink: 0;
  margin: 0 calc(-1 * var(--space-xxs)) 0 var(--space-s);
}

/* Flashbar: solid notifications at the top of the content. */
.cs-flashbar {
  display: flex;
  flex-direction: column;
  gap: var(--space-xxxs);
}

.cs-flashbar:empty {
  display: none;
}

.cs-flash {
  display: flex;
  align-items: flex-start;
  padding: var(--space-flashbar-vertical) var(--space-flashbar-horizontal);
  border-radius: var(--border-radius-flashbar);
  background: var(--cs-flash-background, var(--color-background-flashbar-info));
  color: var(--color-text-notification-default);
  box-shadow: var(--shadow-flash-sticky);
  overflow-wrap: break-word;
  animation: var(--motion-keyframes-fade-in) var(--motion-duration-show-paced) var(--motion-easing-show-paced);
}

.cs-flash--success { --cs-flash-background: var(--color-background-flashbar-success); }
.cs-flash--error { --cs-flash-background: var(--color-background-flashbar-error); }
.cs-flash--info { --cs-flash-background: var(--color-background-flashbar-info); }
.cs-flash--warning { --cs-flash-background: var(--color-background-flashbar-warning); color: var(--color-text-notification-yellow); }

.cs-flash__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
}

.cs-flash__icon {
  flex-shrink: 0;
  margin: var(--space-xxxs) 0;
  padding: var(--space-xxs) var(--space-xxs) var(--space-xxs) 0;
}

.cs-flash__message {
  flex: 1 1 70%;
  min-width: 0;
  margin: var(--space-xxxs) 0;
  padding: var(--space-xxs);
}

.cs-flash a {
  color: inherit;
}

.cs-flash code {
  font-size: inherit;
}

.cs-flash__dismiss {
  flex-shrink: 0;
  margin: 0 calc(-1 * var(--space-xxs)) 0 var(--space-s);
}

.cs-flash .cs-button--icon {
  color: var(--color-text-interactive-inverted-default);
}

.cs-flash .cs-button--icon:hover {
  color: var(--color-text-interactive-inverted-hover);
}

.cs-flash--warning .cs-button--icon {
  color: var(--color-text-interactive-default);
}

.cs-flash--warning .cs-button--icon:hover {
  color: var(--color-text-interactive-hover);
}

/* =========================================================================================
   15. Form controls: form, form field, input, textarea, select, checkbox, radio,
       segmented control, file input, text filter
   ========================================================================================= */
.cs-form__header {
  margin-bottom: var(--space-content-header-padding-bottom);
}

.cs-form__error {
  margin-top: var(--space-scaled-l);
}

.cs-form__footer {
  margin-top: var(--space-scaled-l);
  display: flex;
  flex-direction: row-reverse;
  flex-wrap: wrap;
  justify-content: space-between;
  gap: var(--space-m);
}

.cs-form__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-xs);
}

.cs-form-field {
  container-type: inline-size;
  min-width: 0;
}

.cs-form-field__label-wrap {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
}

.cs-form-field__label {
  display: inline;
  margin-right: var(--space-xs);
  color: var(--color-text-form-label);
  font-size: var(--font-size-form-label);
  line-height: var(--line-height-form-label);
  font-weight: var(--font-weight-form-label);
}

.cs-form-field__label:only-child {
  margin-right: 0;
}

.cs-form-field__optional {
  font-style: italic;
}

.cs-form-field__description,
.cs-form-field__constraint,
.cs-form-field__controls {
  padding-top: var(--space-xxs);
}

/* Cloudscape: the description (under the label) and the constraint (under the control) are
   small secondary text. */
.cs-form-field__description,
.cs-form-field__constraint {
  color: var(--color-text-form-secondary);
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-s);
  letter-spacing: var(--letter-spacing-body-s);
}

/* Cloudscape: non-stretched controls span 8 of 12 grid columns on wide fields. */
@container (min-width: 689px) {
  .cs-form-field:not(.cs-form-field--stretch) > .cs-form-field__controls {
    width: calc((100% + var(--space-grid-gutter)) * 8 / 12 - var(--space-grid-gutter));
  }
}

.cs-form-field__hints {
  padding-top: var(--space-xxs);
}

.cs-form-field__error {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xxs);
  color: var(--color-text-status-error);
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-s);
  letter-spacing: var(--letter-spacing-body-s);
}

.cs-form-field__error + .cs-form-field__constraint {
  padding-top: var(--space-xxs);
}

/* Input, textarea, select share the field box. */
.cs-input,
.cs-textarea,
.cs-select__control {
  display: block;
  width: 100%;
  min-height: var(--size-vertical-input);
  margin: 0;
  padding: var(--space-field-vertical) var(--space-field-horizontal);
  border: var(--border-width-field) solid var(--color-border-input-default);
  border-radius: var(--border-radius-input);
  background: var(--color-background-input-default);
  color: var(--color-text-body-default);
  font-size: var(--font-size-body-m);
  line-height: var(--line-height-body-m);
}

.cs-input::placeholder,
.cs-textarea::placeholder {
  color: var(--color-text-input-placeholder);
  font-style: italic;
  opacity: 1;
}

.cs-input:focus,
.cs-textarea:focus,
.cs-select__control:focus {
  outline: var(--cs-focus-ring-width) dotted transparent;
  border-color: var(--color-border-input-focused);
  box-shadow: 0 0 0 var(--border-control-focus-ring-shadow-spread) var(--color-border-item-focused);
}

.cs-input:disabled,
.cs-textarea:disabled,
.cs-select__control:disabled {
  background: var(--color-background-input-disabled);
  border-color: var(--color-border-input-disabled);
  color: var(--color-text-input-disabled);
  cursor: default;
}

.cs-input[readonly],
.cs-textarea[readonly] {
  background: var(--color-background-input-default);
  border-color: var(--color-border-input-disabled);
}

.cs-input--invalid,
.cs-textarea--invalid,
.cs-input[aria-invalid="true"],
.cs-textarea[aria-invalid="true"] {
  color: var(--color-text-status-error);
  border-color: var(--color-text-status-error);
  border-left-width: var(--border-invalid-width);
  padding-left: calc(var(--space-field-horizontal) - (var(--border-invalid-width) - var(--border-width-field)));
}

.cs-input--invalid:focus,
.cs-textarea--invalid:focus,
.cs-input[aria-invalid="true"]:focus,
.cs-textarea[aria-invalid="true"]:focus {
  box-shadow: 0 0 0 var(--border-control-invalid-focus-ring-shadow-spread) var(--color-border-item-focused);
}

.cs-input[type="number"] {
  -moz-appearance: textfield;
}

.cs-textarea {
  resize: vertical;
  white-space: pre-wrap;
}

/* Text read as code (Jinja templates, one address per line): the monospace face. */
.cs-textarea--monospace {
  font-family: var(--font-family-monospace);
}

.cs-input-wrap {
  position: relative;
  display: block;
}

.cs-input-wrap__icon {
  position: absolute;
  left: var(--space-field-horizontal);
  top: calc(50% - var(--line-height-body-m) / 2);
  pointer-events: none;
}

.cs-input-wrap--icon .cs-input {
  padding-left: var(--space-field-icon-offset);
}

/* Native <select> with the Cloudscape trigger look. */
.cs-select {
  position: relative;
  display: block;
}

.cs-select__control {
  -webkit-appearance: none;
  appearance: none;
  padding-right: var(--space-field-icon-offset);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
}

.cs-select__arrow {
  position: absolute;
  right: var(--space-field-horizontal);
  top: calc(50% - var(--line-height-body-m) / 2);
  pointer-events: none;
  color: var(--color-text-button-inline-icon-default);
}

.cs-select:hover .cs-select__arrow {
  color: var(--color-text-button-inline-icon-hover);
}

/* Select with an inline label on its top border (Cloudscape inlineLabelText). */
.cs-select-inline {
  position: relative;
  display: block;
  padding-top: calc(var(--space-xs) + 1px);
}

.cs-select-inline__label {
  position: absolute;
  top: 0;
  left: calc(var(--space-xs) + 1px);
  z-index: 1; /* local stacking: above its sibling within this component */
  padding: 0 var(--space-xxs) var(--space-xxxs);
  border-radius: var(--space-xxxs); /* Cloudscape: inline label corners */
  background: var(--color-background-input-default);
  color: var(--color-text-form-label);
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-heading-xs);
  letter-spacing: var(--letter-spacing-body-s);
  font-weight: var(--font-weight-bold);
}

/* Checkbox / radio: a native input over a Cloudscape SVG (keyboard + forms stay native). */
.cs-control {
  position: relative;
  display: inline-block;
  vertical-align: top;
  flex-shrink: 0;
  width: var(--size-control);
  height: var(--size-control);
}

.cs-control__input {
  position: absolute;
  inset: 0;
  z-index: 1; /* local stacking: above its sibling within this component */
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.cs-control__input:disabled {
  cursor: default;
}

.cs-control__svg {
  display: block;
  width: var(--size-control);
  height: var(--size-control);
}

.cs-control__box {
  fill: var(--color-background-control-default);
  stroke: var(--color-border-control-default);
  stroke-width: var(--border-width-field);
  transition: fill var(--motion-duration-transition-quick) var(--motion-easing-transition-quick);
}

.cs-control__check,
.cs-control__dash {
  fill: none;
  stroke: var(--color-foreground-control-default);
  stroke-width: var(--border-width-icon-normal);
  opacity: 0;
}

.cs-control__input:checked ~ .cs-control__svg .cs-control__box,
.cs-control__input:indeterminate ~ .cs-control__svg .cs-control__box {
  fill: var(--color-background-control-checked);
  stroke: var(--color-background-control-checked);
}

.cs-control__input:checked:not(:indeterminate) ~ .cs-control__svg .cs-control__check {
  opacity: 1;
}

.cs-control__input:indeterminate ~ .cs-control__svg .cs-control__dash {
  opacity: 1;
}

.cs-control__input:disabled ~ .cs-control__svg .cs-control__box {
  fill: var(--color-background-control-disabled);
  stroke: var(--color-background-control-disabled);
}

.cs-control__ring {
  fill: var(--color-background-control-default);
  stroke: var(--color-border-control-default);
  stroke-width: 6.25px; /* Cloudscape: radio ring in a 100-unit viewBox */
}

.cs-control__dot {
  fill: var(--color-background-control-default);
  stroke: var(--color-background-control-checked);
  stroke-width: 30px; /* Cloudscape: the checked ring in a 100-unit viewBox */
  opacity: 0;
  transition: opacity var(--motion-duration-transition-quick) var(--motion-easing-transition-quick);
}

.cs-control__input:checked ~ .cs-control__svg .cs-control__dot {
  opacity: 1;
}

.cs-control__input:disabled ~ .cs-control__svg .cs-control__ring {
  fill: var(--color-background-control-disabled);
  stroke: var(--color-background-control-disabled);
}

.cs-control__input:disabled:checked ~ .cs-control__svg .cs-control__dot {
  stroke: var(--color-background-control-disabled);
}

.cs-control__outline {
  position: absolute;
  inset: calc(-1 * var(--space-xxxs));
  border-radius: var(--border-radius-control-default-focus-ring);
  pointer-events: none;
}

.cs-control__input:focus-visible ~ .cs-control__outline {
  outline: var(--cs-focus-ring-width) dotted transparent; /* forced colors */
  outline-offset: var(--cs-focus-ring-width);
  box-shadow: 0 0 0 var(--cs-focus-ring-width) var(--color-border-item-focused);
}

.cs-checkbox {
  display: inline-flex;
  align-items: flex-start;
}

.cs-checkbox > .cs-control {
  margin-top: var(--space-xxxs);
}

.cs-checkbox__content {
  display: flex;
  flex-direction: column;
  padding-left: var(--space-xs);
}

.cs-checkbox__label {
  color: var(--color-text-form-default);
  cursor: pointer;
}

.cs-checkbox--disabled .cs-checkbox__label {
  color: var(--color-text-control-disabled);
  cursor: default;
}

.cs-checkbox__description {
  color: var(--color-text-form-secondary);
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-s);
  letter-spacing: var(--letter-spacing-body-s);
}

.cs-radio-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-xxs);
}

/* Segmented control (radio-based, works without JS): only the HTML preview's width toggle
   (_macros.html html_preview) uses it, written by hand. */
.cs-segmented {
  display: inline-flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--space-xxs);
  min-height: var(--size-vertical-input);
  padding: var(--border-width-field) var(--space-xxxs);
  border: var(--border-width-field) solid var(--color-border-segment-wrapper);
  border-radius: var(--border-radius-button);
  background: var(--color-background-segment-wrapper);
}

.cs-segmented__input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}

.cs-segmented__segment {
  position: relative;
  display: inline-block;
  padding: var(--space-xxs) var(--space-m);
  border-radius: calc(var(--border-radius-button) - var(--space-xxxs) - var(--border-width-field));
  background: var(--color-background-segment-default);
  color: var(--color-text-segment-default);
  font-weight: var(--font-weight-button);
  letter-spacing: var(--font-button-letter-spacing);
  line-height: var(--line-height-body-m);
  white-space: nowrap;
  text-decoration: none;
  cursor: pointer;
}

.cs-segmented__segment:hover {
  background: var(--color-background-segment-hover);
  color: var(--color-text-segment-hover);
}

.cs-segmented__input:checked + .cs-segmented__segment {
  background: var(--color-background-segment-active);
  color: var(--color-text-segment-active);
}

/* Focus: a ring with a gap around the segment (a ring touching the blue checked segment
   would not show). The ring itself: section 3. */
.cs-segmented__input:focus-visible + .cs-segmented__segment {
  outline: var(--cs-focus-ring-width) dotted transparent; /* forced colours */
}

.cs-segmented__input:focus-visible + .cs-segmented__segment::before {
  inset: calc(-1 * (var(--cs-focus-ring-width) + var(--space-xxxs)));
  border-radius: calc(var(--border-radius-button) - var(--border-width-field)); /* the segment's + the gap */
}

/* File input: the native control, its button styled as a Cloudscape normal button. */
.cs-file-input {
  display: block;
  max-width: 100%;
  font-size: var(--font-size-body-m);
  line-height: var(--line-height-body-m);
  color: var(--color-text-body-secondary);
}

.cs-file-input::file-selector-button {
  margin-right: var(--space-s);
  padding: var(--space-button-vertical) var(--space-button-horizontal);
  border: var(--border-width-button) solid var(--color-border-button-normal-default);
  border-radius: var(--border-radius-button);
  background: var(--color-background-button-normal-default);
  color: var(--color-text-button-normal-default);
  font-family: var(--font-family-base);
  font-weight: var(--font-weight-button);
  letter-spacing: var(--font-button-letter-spacing);
  cursor: pointer;
}

.cs-file-input::file-selector-button:hover {
  background: var(--color-background-button-normal-hover);
  border-color: var(--color-border-button-normal-hover);
  color: var(--color-text-button-normal-hover);
}

.cs-file-input:focus-visible::file-selector-button {
  outline: var(--cs-focus-ring-width) dotted transparent;
  /* Cloudscape: a 2px gap, then the 2px ring */
  box-shadow: 0 0 0 var(--cs-focus-ring-width) var(--color-background-container-content), 0 0 0 calc(2 * var(--cs-focus-ring-width)) var(--color-border-item-focused);
}

.cs-file-input--invalid::file-selector-button {
  border-color: var(--color-text-status-error);
}

/* Text filter: search input with icon, clear button and the result count. */
.cs-text-filter {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 auto;
  width: 100%;
  max-width: var(--cs-text-filter-max-width);
}

.cs-text-filter .cs-input-wrap {
  flex: 1 1 auto;
}

.cs-text-filter .cs-input {
  padding-right: var(--space-field-icon-offset);
}

.cs-text-filter .cs-input::-webkit-search-cancel-button {
  display: none;
}

/* A 24px-high target (WCAG 2.5.8) centred in the 32px input; the 16px icon stays put. */
.cs-text-filter__clear {
  position: absolute;
  right: var(--space-xs);
  top: calc(50% - 12px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 24px;
}

/* =========================================================================================
   16. Tabs (links without JS, ARIA tabs with app.js)
   ========================================================================================= */
.cs-tabs__header {
  display: flex;
  border-bottom: var(--border-divider-section-width) solid var(--color-border-tabs-divider);
}

.cs-tabs__list {
  display: flex;
  margin: 0;
  padding: 0;
  list-style: none;
  overflow-x: auto;
  scrollbar-width: none;
}

.cs-tabs__list::-webkit-scrollbar {
  display: none;
}

/* Scroll buttons at both ends of an overflowing tab strip (Cloudscape pagination buttons):
   app.js shows them only while the tabs overflow and disables the one at an end. */
.cs-tabs__scroll {
  display: flex;
  align-items: center;
  flex-shrink: 0;
  margin: var(--space-xs) 0;
  padding: 0 var(--space-xxxs);
}

.cs-tabs__scroll--left {
  border-right: var(--border-divider-section-width) solid var(--color-border-tabs-divider);
}

.cs-tabs__scroll--right {
  margin-left: auto;
  border-left: var(--border-divider-section-width) solid var(--color-border-tabs-divider);
}

.cs-tabs__item {
  position: relative;
  flex-shrink: 0;
  margin: 0 0 0 calc(-1 * var(--border-divider-section-width));
  padding: 0 var(--space-xs);
  border: var(--border-divider-section-width) solid transparent;
}

.cs-tabs__item:first-child {
  margin-left: var(--border-divider-section-width);
  padding-left: calc(var(--space-xs) - var(--border-divider-section-width));
}

.cs-tabs__item:last-child {
  padding-right: calc(var(--space-xs) - var(--border-divider-section-width));
}

.cs-tabs__item:not(:last-child)::before {
  content: "";
  position: absolute;
  right: 0;
  top: var(--space-xs);
  bottom: var(--space-xs);
  border-right: var(--border-divider-section-width) solid var(--color-border-tabs-divider);
}

.cs-tabs__tab {
  position: relative;
  display: flex;
  padding: calc(var(--space-scaled-xs) - var(--border-divider-section-width)) var(--space-xxs) calc(var(--space-scaled-xs) - var(--border-divider-section-width)) calc(var(--space-xxs) - var(--border-divider-section-width));
  border: var(--border-divider-section-width) solid transparent;
  background: transparent;
  color: var(--color-text-interactive-default);
  font-size: var(--font-size-tabs);
  line-height: var(--line-height-tabs);
  font-weight: var(--font-weight-tabs);
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.cs-tabs__tab:hover {
  color: var(--color-text-accent);
}

.cs-tabs__tab,
.cs-sidenav__link,
.cs-breadcrumbs__link {
  transition: none;
}

.cs-tabs__label {
  padding: var(--space-tabs-vertical) var(--space-xs);
}

.js [data-cs-tabs] .cs-tabs__tab.is-active,
.cs-tabs__tab[aria-selected="true"],
.cs-tabs--links .cs-tabs__tab[aria-current="page"] {
  color: var(--color-text-accent);
}

.js [data-cs-tabs] .cs-tabs__tab.is-active::after,
.cs-tabs__tab[aria-selected="true"]::after,
.cs-tabs--links .cs-tabs__tab[aria-current="page"]::after {
  content: "";
  position: absolute;
  /* Cloudscape draws it on the tab's header container: 7px beyond the label on both sides. */
  left: calc(var(--border-divider-section-width) - var(--space-xs));
  right: calc(var(--border-divider-section-width) - var(--space-xs));
  bottom: calc(-1 * var(--border-item-width)); /* Cloudscape: over the 1px divider + the tab border */
  height: var(--border-active-width);
  border-radius: var(--border-radius-button);
  background: var(--color-border-tabs-underline);
  animation: var(--motion-keyframes-fade-in) var(--motion-duration-refresh-only-medium) var(--motion-easing-refresh-only-a);
}

.cs-tabs__tab:focus {
  outline: none;
  box-shadow: none;
}

.cs-tabs__tab:focus-visible {
  outline: var(--cs-focus-ring-width) dotted transparent; /* forced colors */
}

.cs-tabs__tab:focus-visible::before {
  inset: calc(-1 * var(--space-tabs-focus-outline-gutter)); /* the ring: section 3 */
}

.cs-tabs__panel {
  padding: var(--space-scaled-m) 0;
}

.cs-tabs__panel:focus {
  outline: none;
}

.cs-tabs__panel:focus-visible {
  outline: var(--cs-focus-ring-width) dotted transparent;
  border-radius: var(--border-radius-container);
  box-shadow: 0 0 0 var(--cs-focus-ring-width) var(--color-border-item-focused);
}

/* With JS, only the active panel shows (before app.js runs: only the first one). */
.js [data-cs-tabs]:not([data-cs-ready]) > .cs-tabs__panel ~ .cs-tabs__panel {
  display: none;
}

/* Without JS every panel shows, one after the other: give them room. */
html:not(.js) .cs-tabs__panel + .cs-tabs__panel {
  border-top: var(--border-divider-section-width) solid var(--color-border-tabs-divider);
}

/* =========================================================================================
   17. Expandable section (<details>)
   ========================================================================================= */
.cs-expandable > summary {
  list-style: none;
}

.cs-expandable > summary::-webkit-details-marker {
  display: none;
}

.cs-expandable__header {
  display: flex;
  align-items: flex-start;
  gap: var(--space-xxs);
  padding: var(--space-xxs) 0;
  color: var(--color-text-expandable-section-default);
  font-size: var(--font-size-expandable-heading);
  line-height: var(--line-height-heading-s);
  letter-spacing: var(--letter-spacing-heading-s);
  font-weight: var(--font-weight-bold);
  cursor: pointer;
}

.cs-expandable__header:hover {
  color: var(--color-text-expandable-section-hover);
}

.cs-expandable__icon {
  transform: rotate(-90deg);
  transition: transform var(--motion-duration-rotate-90) var(--motion-easing-rotate-90);
}

.cs-expandable[open] > summary .cs-expandable__icon {
  transform: rotate(0deg);
}

.cs-expandable--default[open] > .cs-expandable__header {
  border-bottom: var(--border-divider-section-width) solid var(--color-border-expandable-section-default);
}

.cs-expandable__content {
  padding: var(--space-scaled-xs) 0;
  animation: var(--motion-keyframes-fade-in) var(--motion-duration-expandable-content-enter) var(--motion-easing-expandable-content-enter);
}

/* variant="footer" (Cloudscape: inside a container footer): a body-size header, no divider. */
.cs-expandable--footer > .cs-expandable__header {
  font-size: var(--font-size-body-m);
  line-height: var(--line-height-body-m);
  letter-spacing: normal;
}

.cs-expandable--footer > .cs-expandable__content {
  padding-top: var(--space-scaled-xxs);
}

/* A secondary line under the header (Cloudscape headerDescription): description= of the macro. */
.cs-expandable__heading {
  display: flex;
  flex-direction: column;
  gap: var(--space-xxxs);
  min-width: 0;
}

.cs-expandable__description {
  display: block;
  color: var(--color-text-heading-secondary);
  font-size: var(--font-size-body-m);
  line-height: var(--line-height-body-m);
  letter-spacing: normal;
  font-weight: var(--font-weight-normal);
  overflow-wrap: anywhere;
}

/* Bordered surfaces: a container-variant expandable and a container table. */
.cs-expandable--container,
.cs-table--container {
  border: var(--border-divider-section-width) solid var(--color-border-divider-default);
  border-radius: var(--border-radius-container);
  background: var(--color-background-container-content);
}

.cs-expandable--container > .cs-expandable__header {
  padding: var(--space-container-header-top) var(--space-container-horizontal);
  font-size: var(--font-size-heading-l);
  line-height: var(--line-height-heading-l);
  letter-spacing: var(--letter-spacing-heading-l);
  color: var(--color-text-heading-default);
}

.cs-expandable--container[open] > .cs-expandable__header {
  padding-bottom: var(--space-container-header-bottom);
}

.cs-expandable--container > .cs-expandable__content {
  padding: var(--space-container-content-top) var(--space-container-horizontal) var(--space-scaled-l);
}

/* =========================================================================================
   18. Table
   ========================================================================================= */
.cs-table {
  position: relative;
  min-width: 0;
}

.cs-table--container > .cs-table__header {
  padding: var(--space-container-header-top) var(--space-container-horizontal) var(--space-container-header-bottom);
}

.cs-table--container > .cs-table__wrapper {
  padding: 0 var(--space-table-horizontal) var(--space-table-content-bottom);
}

.cs-table--full-page > .cs-table__header {
  padding-bottom: var(--space-scaled-s);
}

/* Sticky header of a full-page table (Cloudscape stickyHeader): the title, actions and filter
   stay under the app header while the rows scroll; app.js adds .is-stuck (the title shrinks
   to the h2 size) and shows the cloned column header right below. Not on phones or short
   viewports, where it would hide the rows. */
@media (min-width: 689px) and (min-height: 560px) {
  .js .cs-table--full-page[data-cs-sticky-header] > .cs-table__header {
    position: sticky;
    top: var(--cs-sticky-header-top);
    z-index: var(--cs-z-table-header);
    background: var(--color-background-layout-main);
  }

  /* An open header menu (Actions, filters) shows over the split panel. */
  .js .cs-table--full-page[data-cs-sticky-header] > .cs-table__header:has(details[open]) {
    z-index: var(--cs-z-table-header-open);
  }

  /* The background also covers the content gutters on both sides. */
  .js .cs-table--full-page[data-cs-sticky-header] > .cs-table__header::before {
    content: "";
    position: absolute;
    inset: 0 calc(-1 * var(--space-layout-content-horizontal));
    z-index: -1;
    background: var(--color-background-layout-main);
  }

  .cs-table__header.is-stuck {
    padding-top: var(--space-scaled-s);
  }

  .cs-table__header.is-stuck .cs-header--h1 .cs-header__heading {
    font-size: var(--font-size-heading-l);
    line-height: var(--line-height-heading-l);
    letter-spacing: var(--letter-spacing-heading-l);
  }
}

.cs-table__tools {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-xs) var(--space-m);
  padding-top: var(--space-xs); /* Cloudscape: 8px between the description and the filter */
}

/* The filter controls align on their top edge: a select with an inline label sits lower
   (its label rides on its top border) without pushing the text filter down. */
.cs-table__filter {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: var(--space-xs) var(--space-m);
  flex: 1 1 auto;
  margin: 0;
}

.cs-table__filter .cs-text-filter {
  flex: 1 1 var(--cs-select-filter-width);
}

.cs-table__filter .cs-select-inline {
  flex: 0 0 var(--cs-select-filter-width);
}

/* "Needs attention: Failed (1) · ..." under the filter: quick filters with their counts. */
.cs-table__attention {
  flex: 1 1 100%;
  margin: 0;
  color: var(--color-text-body-secondary);
}

.cs-table__attention a[aria-current="page"] {
  font-weight: var(--font-weight-bold);
}

/* Phones: the strip would take several lines; the Status filter offers the same choices. */
@media (max-width: 688px) {
  .cs-table__attention {
    display: none;
  }
}

.cs-table__matches {
  display: inline-flex;
  align-items: flex-start;
  gap: var(--space-xxs);
  min-height: var(--size-vertical-input);
  padding: var(--space-field-vertical) 0;
  color: var(--color-text-form-label);
  white-space: nowrap;
}

.cs-table__wrapper {
  position: relative;
  overflow-x: auto;
}

/* A wrapper that scrolls sideways is a focusable region (app.js adds tabindex="0", role
   "region" and its name only while it overflows: WCAG 2.1.1), so keyboard users can scroll
   it; its ring is drawn inside (section 3). */

.cs-table__table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
}

.cs-table__th {
  position: relative;
  padding: var(--space-scaled-xxs) var(--space-xs);
  border-bottom: var(--border-divider-section-width) solid var(--color-border-divider-default);
  background: var(--color-background-table-header);
  color: var(--color-text-column-header);
  font-weight: var(--font-weight-bold);
  text-align: left;
  vertical-align: bottom;
  white-space: nowrap;
}

.cs-table--full-page .cs-table__th {
  background: var(--color-background-layout-main);
}

.cs-table__th:not(:last-child)::after {
  content: "";
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  margin: auto 0;
  min-height: var(--line-height-heading-xs);
  max-height: calc(100% - var(--line-height-heading-xs));
  border-left: var(--border-divider-list-width) solid var(--color-border-divider-default);
}

.cs-table__th-content,
.cs-table__sort {
  position: relative;
  display: block;
  padding: var(--space-scaled-xxs) var(--space-s);
}

.cs-table__th-text {
  display: block;
  padding: var(--border-divider-list-width) 0; /* Cloudscape: 1px above and below the label */
  line-height: var(--line-height-heading-xs);
  overflow: hidden;
  text-overflow: ellipsis;
}

.cs-table__sort {
  width: 100%;
  margin: 0;
  padding-right: calc(var(--space-l) + var(--space-xs));
  border: none;
  background: transparent;
  color: inherit;
  font-weight: inherit;
  text-align: left;
  cursor: pointer;
}

.cs-table__sort-icon {
  position: absolute;
  right: var(--space-xxs);
  top: 50%;
  transform: translateY(-50%);
  color: var(--color-text-column-sorting-icon);
}

.cs-table__th[aria-sort="none"] .cs-table__sort-icon--ascending,
.cs-table__th[aria-sort="none"] .cs-table__sort-icon--descending,
.cs-table__th[aria-sort="ascending"] .cs-table__sort-icon--none,
.cs-table__th[aria-sort="ascending"] .cs-table__sort-icon--descending,
.cs-table__th[aria-sort="descending"] .cs-table__sort-icon--none,
.cs-table__th[aria-sort="descending"] .cs-table__sort-icon--ascending {
  display: none;
}

.cs-table__sort:hover,
.cs-table__th[aria-sort="ascending"],
.cs-table__th[aria-sort="descending"] {
  color: var(--color-text-interactive-active);
}

.cs-table__sort:hover .cs-table__sort-icon,
.cs-table__th[aria-sort="ascending"] .cs-table__sort-icon,
.cs-table__th[aria-sort="descending"] .cs-table__sort-icon {
  color: var(--color-text-interactive-active);
}

/* Without JavaScript the columns do not sort: the macro renders a plain header text there
   (.cs-table__th-content.cs-no-js-only) and hides the sort button. */

/* Body cells (Cloudscape geometry: a 39px row for one line of text). */
.cs-table__td {
  padding: 0;
  border-top: var(--border-divider-list-width) solid transparent;
  border-bottom: var(--border-divider-list-width) solid var(--color-border-divider-secondary);
  vertical-align: middle;
  overflow-wrap: break-word;
}

.cs-table__td:first-child {
  border-left: var(--border-item-width) solid transparent;
}

/* Cloudscape: without a selection column the first column sits flush with the table edge. */
.cs-table__th:first-child:not(.cs-table__th--selection) {
  padding-left: var(--space-xxxs);
}

.cs-table__th:first-child:not(.cs-table__th--selection) > .cs-table__th-content,
.cs-table__th:first-child:not(.cs-table__th--selection) > .cs-table__sort,
.cs-table__td:first-child:not(.cs-table__td--selection) > .cs-table__cell {
  padding-left: 0;
}

.cs-table__td:last-child {
  border-right: var(--border-item-width) solid transparent;
}

/* Cloudscape: the first row has a 2px top border and the last row a 2px bottom border (so a
   one-line row is 39px, the first and the last 40px). Selected, they keep their height. */
.cs-table__table > tbody > tr:first-child > .cs-table__td {
  border-top-width: var(--border-item-width);
}

.cs-table__table > tbody > tr:last-child > .cs-table__td,
.cs-table__table > tbody > tr:has(+ .cs-table__meta:last-child) > .cs-table__td {
  border-bottom-color: transparent;
  border-bottom-width: var(--border-item-width);
}

.cs-table__table > tbody > tr.is-selected:first-child > .cs-table__td > .cs-table__cell {
  padding-top: var(--space-scaled-xs);
}

.cs-table__table > tbody > tr.is-selected:last-child > .cs-table__td > .cs-table__cell,
.cs-table__table > tbody > tr.is-selected:has(+ .cs-table__meta:last-child) > .cs-table__td > .cs-table__cell {
  padding-bottom: calc(var(--space-scaled-xs) + var(--border-divider-list-width));
}

/* One line per cell (Cloudscape wrapLines=false). A cell given a title (cs.td(title=...))
   ends in an ellipsis at its column's max width (--cs-table-cell-max-width by default). */
.cs-table__cell {
  display: block;
  padding: var(--space-scaled-xs) var(--space-l) calc(var(--space-scaled-xs) + var(--border-divider-list-width));
  white-space: nowrap;
}

/* Inline code (ids, file names) must not make its row taller than a text row. */
.cs-table__cell code {
  line-height: 1;
}

.cs-table__cell[title] {
  max-width: var(--cs-cell-max-width, var(--cs-table-cell-max-width));
  overflow: hidden;
  text-overflow: ellipsis;
}

.cs-table__td--wrap > .cs-table__cell {
  min-width: var(--cs-table-wrap-min-width);
  max-width: var(--cs-table-wrap-width);
  white-space: normal;
  overflow-wrap: anywhere;
}

.cs-table__td--top {
  vertical-align: top;
}

.cs-table__muted {
  color: var(--color-text-body-secondary);
}

/* Selection column */
.cs-table__th--selection,
.cs-table__td--selection {
  position: relative;
  width: var(--size-table-selection-horizontal);
  min-width: var(--size-table-selection-horizontal);
  max-width: var(--size-table-selection-horizontal);
  padding: 0;
}

.cs-table__selection {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding-bottom: var(--space-xxs);
  cursor: pointer;
}

.cs-table__td--selection .cs-table__selection {
  padding-bottom: 0;
}

/* A form-field selection cell (td_selection field=true) wraps its control in a <span>, not a
   <label> (the row's visible label names it): the invisible input itself grows to the cell,
   so a click anywhere in the cell still ticks it. */
.cs-table__td--selection-field .cs-control__input {
  inset: calc(-1 * (var(--size-table-selection-horizontal) - var(--size-control)) / 2);
  width: auto;
  height: auto;
}

/* Rows that wrap are taller than the cell is wide: the input reaches one selection-column
   width further up and down (enough for a wrapped row), and the span clips it to the cell,
   so the top and bottom of the cell tick it too. */
.cs-table__td--selection-field .cs-table__selection {
  overflow: hidden;
}

.cs-table__td--selection-field .cs-control__input {
  top: calc(-1 * var(--size-table-selection-horizontal));
  bottom: calc(-1 * var(--size-table-selection-horizontal));
}

html:not(.js) .cs-table__th--selection,
html:not(.js) .cs-table__td--selection {
  display: none;
}

/* A selection column whose checkboxes are form fields (th/td_selection field=true) stays
   visible without JavaScript (only its select-all needs JS). */
html:not(.js) .cs-table__th--selection-field,
html:not(.js) .cs-table__td--selection-field {
  display: table-cell;
}

/* Selected rows: light blue fill with a 2px blue outline around the row. */
.cs-table__row.is-selected > .cs-table__td {
  background: var(--color-background-item-selected);
  border-top: var(--border-item-width) solid var(--color-border-item-selected);
  border-bottom: var(--border-item-width) solid var(--color-border-item-selected);
}

.cs-table__row.is-selected > .cs-table__td > .cs-table__cell {
  padding-top: calc(var(--space-scaled-xs) - var(--border-divider-list-width));
  padding-bottom: var(--space-scaled-xs);
}

.cs-table__row.is-selected > .cs-table__td:first-child {
  border-left-color: var(--color-border-item-selected);
  border-top-left-radius: var(--border-radius-item);
  border-bottom-left-radius: var(--border-radius-item);
}

.cs-table__row.is-selected > .cs-table__td:last-child {
  border-right-color: var(--color-border-item-selected);
  border-top-right-radius: var(--border-radius-item);
  border-bottom-right-radius: var(--border-radius-item);
}

.cs-table__row:has(+ .cs-table__row.is-selected) > .cs-table__td {
  border-bottom-color: transparent;
}

/* Consecutive selected rows merge into one outlined block. */
.cs-table__row.is-selected + .cs-table__row.is-selected > .cs-table__td {
  border-top-width: 0;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
}

.cs-table__row.is-selected + .cs-table__row.is-selected > .cs-table__td > .cs-table__cell {
  padding-top: calc(var(--space-scaled-xs) + var(--border-divider-list-width));
}

.cs-table__row.is-selected:has(+ .cs-table__row.is-selected) > .cs-table__td {
  border-bottom-width: var(--border-divider-list-width);
  border-bottom-color: var(--color-border-item-placeholder);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

.cs-table__row.is-selected:has(+ .cs-table__row.is-selected) > .cs-table__td > .cs-table__cell {
  padding-bottom: calc(var(--space-scaled-xs) + var(--border-divider-list-width));
}

/* Empty / no match / loading: one merged cell. */
.cs-table__td--merged {
  padding: 0;
  text-align: center;
  color: var(--color-text-empty);
}

/* The width it may use: --cs-table-visible-width (set on the wrapper by app.js) or, without
   app.js, the wrapper's own width (100cqi): a wrapper holding the empty row is a size
   container (only then, so tables with rows keep their intrinsic sizing). */
.cs-table__wrapper:has(> .cs-table__table > tbody > .cs-table__empty-row) {
  container-type: inline-size;
}

.cs-table__empty {
  position: sticky; /* stays in the visible part of a table that scrolls sideways */
  left: 0;
  max-width: var(--cs-table-visible-width, 100cqi);
  padding: var(--space-scaled-m) var(--space-l) var(--space-scaled-l);
}

.cs-table__empty-row > .cs-table__td {
  border-bottom-color: transparent;
}

.cs-table[aria-busy="true"] .cs-table__table > tbody {
  opacity: 0.5; /* Cloudscape: dims stale rows while reloading */
  transition: opacity var(--motion-duration-refresh-only-fast) var(--motion-easing-refresh-only-a);
}

/* Sticky last column (Cloudscape stickyColumns: { last: 1 }): on a table wider than its
   container the row actions stay in view; app.js adds .has-hidden-end to the wrapper (and
   the cloned header) while columns are hidden under it, which shows the column's shadow. */
.cs-table__th--sticky-end,
.cs-table__td--sticky-end {
  position: sticky;
  right: 0;
  z-index: 1; /* local stacking: above the cells scrolling under it */
  background: var(--color-background-container-content);
}

/* A sticky cell is a stacking context: while its row menu is open it is lifted to the menu
   layer, or the next rows, the cloned header and the split panel would cover the menu. */
.cs-table__td--sticky-end:has(details[open]) {
  z-index: var(--cs-z-dropdown);
}

.cs-table--full-page .cs-table__th--sticky-end,
.cs-table--full-page .cs-table__td--sticky-end {
  background: var(--color-background-layout-main);
}

/* The shadow is drawn by a pseudo-element (clipping the cell itself would also clip its open
   row menu). */
.has-hidden-end .cs-table__th--sticky-end::before,
.has-hidden-end .cs-table__td--sticky-end::before {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  width: var(--border-divider-list-width);
  z-index: -1;
  box-shadow: var(--shadow-sticky-column-last);
  clip-path: inset(0 0 0 calc(-1 * var(--space-l))); /* only the left edge of the shadow */
}

/* Row actions: a compact ellipsis menu per row (the column title is for screen readers:
   .cs-table__th--actions .cs-table__th-text shares .cs-u-visually-hidden, section 23). */
.cs-table__td--actions > .cs-table__cell {
  padding-top: var(--space-xxs);
  padding-bottom: var(--space-xxs);
}

/* Without JS a row menu cannot escape the scrolling wrapper: it opens towards the left,
   over the row's other cells, so the last column never clips it. */
html:not(.js) .cs-table .cs-dropdown__menu {
  left: auto;
  right: 0;
  min-width: var(--cs-menu-min-width);
}

/* Sticky column header: app.js clones the header row while the real one is scrolled away. */
.cs-table__sticky {
  position: fixed; /* top, left and width are set by app.js */
  top: var(--cs-header-height);
  z-index: var(--cs-z-sticky-header);
  overflow: hidden;
  background: var(--color-background-layout-main);
  box-shadow: var(--shadow-sticky);
  clip-path: inset(0 0 calc(-1 * var(--space-l)) 0); /* only the bottom edge of the shadow shows */
}

.cs-table--container .cs-table__sticky {
  background: var(--color-background-container-content);
  box-shadow: var(--shadow-sticky-embedded);
}

/* The clone covers the wrapper's box, so it takes the wrapper's side padding too (container
   tables: the columns sit 20px in); otherwise every cloned column would be offset. */
.cs-table--container > .cs-table__sticky {
  padding: 0 var(--space-table-horizontal);
}

.cs-table__sticky .cs-table__table {
  table-layout: fixed;
}

.cs-table__sticky:not(.is-visible) {
  display: none;
}

/* Embedded tables (inside a container or a split panel): no outer chrome. */
.cs-table--embedded .cs-table__th {
  background: transparent;
}

/* Simple tables whose markup tests pin as bare <th>/<td> (e.g. <th>Generated</th><td>2</td>):
   <table class="cs-table--simple"> styles its cells without classes. Header cells in thead
   look like column headers; a th in tbody is a row label (bold). */
.cs-table--simple {
  border-collapse: separate;
  border-spacing: 0;
}

.cs-table--simple > thead > tr > th,
.cs-table--simple > tbody > tr > th,
.cs-table--simple > tbody > tr > td,
.cs-table--simple > tr > th,
.cs-table--simple > tr > td {
  padding: var(--space-scaled-xs) var(--space-l) calc(var(--space-scaled-xs) + var(--border-divider-list-width));
  border-bottom: var(--border-divider-list-width) solid var(--color-border-divider-secondary);
  text-align: left;
  vertical-align: top;
  overflow-wrap: break-word;
}

.cs-table--simple > thead > tr > th {
  padding-top: var(--space-scaled-xxs);
  padding-bottom: var(--space-scaled-xxs);
  border-bottom-color: var(--color-border-divider-default);
  color: var(--color-text-column-header);
  font-weight: var(--font-weight-bold);
  vertical-align: bottom;
  white-space: nowrap;
}

.cs-table--simple > tbody > tr > th,
.cs-table--simple > tr > th {
  color: var(--color-text-label);
  font-weight: var(--font-weight-bold);
}

.cs-table--simple > tbody > tr > :first-child,
.cs-table--simple > thead > tr > :first-child,
.cs-table--simple > tr > :first-child {
  padding-left: 0;
}

.cs-table--simple > tbody > tr:last-child > *,
.cs-table--simple > tr:last-child > * {
  border-bottom-color: transparent;
}

/* Simple-table helpers: .cs-table--simple-full spans its container; .cs-table__scroll wraps
   a simple table so it scrolls sideways on phones instead of widening the page. */
.cs-table--simple-full {
  width: 100%;
}

.cs-table__scroll {
  overflow-x: auto; /* focusable while it overflows, like .cs-table__wrapper (app.js) */
}

/* Table footer (Cloudscape Table footer slot, container tables): a centred "View all" link
   under a divider: <div class="cs-table__footer"><a href="...">View ...</a></div>. */
.cs-table__footer {
  padding: var(--space-scaled-s) var(--space-container-horizontal);
  border-top: var(--border-divider-section-width) solid var(--color-border-divider-default);
  text-align: center;
}

/* Without JavaScript a row menu (<details>) opens inside the scrolling wrapper, which would
   clip it on the last rows: while one is open the wrapper lets it overflow (with JS, app.js
   positions menus fixed instead). */
html:not(.js) .cs-table__wrapper:has(.cs-dropdown__details[open]) {
  overflow: visible;
}


/* =========================================================================================
   19. Split panel (bottom)
   ========================================================================================= */
.cs-split-panel {
  position: fixed;
  left: var(--cs-nav-offset);
  right: 0;
  bottom: 0;
  z-index: var(--cs-z-split-panel);
  display: flex;
  flex-direction: column;
  height: var(--cs-split-panel-height);
  background: var(--color-background-layout-panel-content);
  border-top: var(--border-panel-top-width) solid var(--color-border-divider-panel-bottom);
}

html.cs-nav-closed .cs-split-panel {
  left: 0;
}

@media (max-width: 688px) {
  .cs-split-panel {
    left: 0;
  }
}

.cs-split-panel__handle {
  position: absolute;
  top: 0;
  left: 50%;
  z-index: 1; /* local stacking: above its sibling within this component */
  display: flex;
  align-items: center;
  justify-content: center;
  width: calc(var(--size-icon-normal) * 3);
  height: var(--cs-split-panel-handle);
  transform: translateX(-50%);
  cursor: ns-resize;
  touch-action: none;
}

.cs-split-panel__grip {
  width: var(--size-icon-normal);
  height: var(--border-width-icon-normal);
  border-radius: var(--border-width-icon-normal);
  background: var(--color-text-interactive-default);
}

.cs-split-panel__handle:hover .cs-split-panel__grip {
  background: var(--color-text-interactive-hover);
}

.cs-split-panel:not(.is-open) .cs-split-panel__handle {
  display: none;
}

.cs-split-panel__header {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  flex-shrink: 0;
  padding: 0 var(--space-xl);
  margin: calc(var(--space-s) + var(--space-xxxs)) 0; /* Cloudscape toolbar layout: 14px */
}

.cs-split-panel:not(.is-open) .cs-split-panel__header {
  cursor: pointer;
}

.cs-split-panel:not(.is-open):hover {
  background: var(--color-background-layout-panel-hover);
}

.cs-split-panel__title {
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--font-panel-header-size);
  line-height: var(--font-panel-header-line-height);
  letter-spacing: var(--letter-spacing-heading-m);
  font-weight: var(--font-weight-heading-m);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.cs-split-panel__actions {
  display: flex;
  align-items: center;
  gap: var(--space-xs);
  min-height: var(--size-vertical-input);
}

.cs-split-panel__buttons {
  display: flex;
  align-items: center;
  margin-left: var(--space-xs);
}

.cs-split-panel__divider {
  align-self: stretch;
  margin: var(--space-xxs) var(--space-xs);
  border-left: var(--border-divider-section-width) solid var(--color-border-divider-default);
}

.cs-split-panel__body {
  flex: 1 1 auto;
  min-height: 0;
  overflow-y: auto;
  padding: 0 var(--space-xl) var(--space-panel-split-bottom);
  outline: none;
}

.cs-split-panel:not(.is-open) .cs-split-panel__body {
  display: none;
}

.cs-split-panel__empty,
.cs-split-panel__loading {
  color: var(--color-text-empty);
}

.cs-split-panel__loading {
  display: flex;
  gap: var(--space-xxs);
}

.cs-split-panel__selection-list {
  margin: var(--space-xs) 0 0;
  padding-left: var(--space-l);
}

.cs-split-panel__bulk {
  margin-top: var(--space-m);
}

/* Cloudscape: no containers inside a split panel; detail-page containers lose their chrome,
   and a container marked data-split-panel-flat also loses its header (the panel title says it). */
.cs-split-panel__content [data-split-panel-flat] > .cs-container__header {
  display: none;
}

.cs-split-panel__content [data-split-panel-flat] > .cs-container__content {
  padding-top: 0;
}

/* (Containers inside the panel lose their chrome: see section 7.) */

.cs-split-panel__content .cs-table--container {
  border: none;
}

.cs-split-panel__content .cs-table--container > .cs-table__header,
.cs-split-panel__content .cs-table--container > .cs-table__wrapper {
  padding-left: 0;
  padding-right: 0;
}

@media (max-width: 688px) {
  .cs-split-panel__header,
  .cs-split-panel__body {
    padding-left: var(--space-l);
    padding-right: var(--space-l);
  }

  /* Phones: "View details" becomes an icon button (its accessible name, set by app.js,
     names the row), so the title keeps the width. */
  .cs-split-panel__details.cs-button {
    padding-left: var(--space-button-icon-only-horizontal);
    padding-right: var(--space-button-icon-only-horizontal);
  }

  .cs-split-panel__details .cs-button__label {
    position: absolute;
    width: 1px;
    height: 1px;
    margin: -1px;
    overflow: hidden;
    clip: rect(0 0 0 0);
    white-space: nowrap;
  }

  .cs-split-panel__details .cs-button__icon--left {
    left: 0;
    margin-right: 0;
  }
}

/* Short viewports: with nothing selected the collapsed bar is left out (app.js gives it no
   height); the toolbar's split-panel toggle still opens it. */
@media (max-height: 559px) {
  .cs-split-panel.is-empty:not(.is-open) {
    display: none;
  }
}

/* Wider screens: "View details" is a text button (its icon is for phones). */
@media (min-width: 689px) {
  .cs-split-panel__details .cs-button__icon {
    display: none;
  }
}

/* =========================================================================================
   20. Wizard steps (left column; "Step 2 of 3" on narrow screens)
   ========================================================================================= */
.cs-wizard {
  display: grid;
  grid-template-columns: var(--cs-steps-width) minmax(0, 1fr);
  column-gap: var(--space-xl);
  row-gap: var(--space-xxs);
  align-items: start;
}

.cs-steps__summary {
  display: none;
  color: var(--color-text-small);
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-s);
}

.cs-steps__list {
  list-style: none;
  margin: 0;
  padding: var(--space-s) 0 0;
}

.cs-steps__item {
  position: relative;
}

.cs-steps__item + .cs-steps__item {
  margin-top: var(--space-m);
}

.cs-steps__number {
  display: block;
  padding-left: calc(var(--space-l) + var(--space-xs));
  color: var(--color-text-small);
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-m); /* Cloudscape: the "Step N" line is 20px high */
  letter-spacing: var(--letter-spacing-body-s);
}

.cs-steps__line {
  display: grid;
  grid-template-columns: var(--space-l) minmax(0, 1fr);
  column-gap: var(--space-xs);
  align-items: center;
}

.cs-steps__circle {
  justify-self: center;
  width: var(--cs-steps-circle);
  height: var(--cs-steps-circle);
  border-radius: 50%;
  background: var(--color-background-container-content);
  box-shadow: 0 0 0 var(--cs-steps-ring) var(--color-border-control-disabled);
}

/* The line joining one circle to the next (circle centre: label line + half a text line). */
.cs-steps__item:not(:last-child)::after {
  content: "";
  position: absolute;
  left: calc(var(--space-l) / 2 - 1px);
  top: calc(var(--line-height-body-m) + var(--line-height-body-m) / 2 + var(--cs-steps-circle) / 2 + var(--space-xxxs));
  bottom: calc(-1 * (var(--space-m) + var(--line-height-body-m) + var(--line-height-body-m) / 2 - var(--cs-steps-circle) / 2 - var(--space-xxxs)));
  border-left: var(--border-width-icon-normal) solid var(--color-border-divider-default);
}

.cs-steps__title {
  color: var(--color-text-small);
}

.cs-steps__item--visited .cs-steps__circle {
  background: var(--color-text-interactive-default);
  box-shadow: 0 0 0 var(--cs-steps-ring) var(--color-text-interactive-default), 0 0 0 calc(2 * var(--cs-steps-ring)) var(--color-background-container-content);
}

.cs-steps__item--visited .cs-steps__title {
  color: var(--color-text-interactive-default);
}

a.cs-steps__title {
  text-decoration: none;
}

a.cs-steps__title:hover {
  color: var(--color-text-accent);
  text-decoration: underline;
}

.cs-steps__item--active .cs-steps__circle {
  background: var(--color-text-accent);
  box-shadow:
    0 0 0 var(--cs-steps-active-gap) var(--color-background-container-content),
    0 0 0 calc(var(--cs-steps-active-gap) + var(--cs-steps-ring)) var(--color-text-accent),
    0 0 0 calc(var(--cs-steps-active-gap) + 2 * var(--cs-steps-ring)) var(--color-background-container-content);
}

.cs-steps__item--active .cs-steps__title {
  color: var(--color-text-accent);
  font-weight: var(--font-weight-bold);
}

.cs-wizard__form > .cs-page-header {
  padding-top: var(--space-scaled-s);
}

/* Cloudscape collapses the step navigation to "Step N of M" when the WIZARD is 688px wide or
   less. The wizard fills the content area: viewport - 48px gutters (2 x
   --space-layout-content-horizontal), - 281px more while the navigation is open
   (--cs-nav-offset). Media queries (not a container query, which would re-anchor the
   position:fixed menus inside it): 688 + 48 = 736px, and 736 + 281 = 1017px. */
@media (max-width: 736px) {
  .cs-wizard {
    grid-template-columns: minmax(0, 1fr);
  }

  .cs-steps__summary {
    display: block;
  }

  .cs-steps__list {
    display: none;
  }
}

@media (max-width: 1017px) {
  html:not(.cs-nav-closed) .cs-wizard {
    grid-template-columns: minmax(0, 1fr);
  }

  html:not(.cs-nav-closed) .cs-steps__summary {
    display: block;
  }

  html:not(.cs-nav-closed) .cs-steps__list {
    display: none;
  }
}

/* =========================================================================================
   21. Confirmation box (modal-like, page version), empty state
   ========================================================================================= */
.cs-confirmation {
  max-width: var(--cs-confirmation-max-width);
  background: var(--color-background-container-content);
  border: var(--border-divider-section-width) solid var(--color-border-divider-default);
  border-radius: var(--border-radius-container);
}

.cs-confirmation--medium {
  max-width: var(--cs-confirmation-medium-width);
}

.cs-confirmation__header {
  padding: var(--space-container-header-top) var(--space-modal-horizontal) var(--space-container-header-bottom);
}

.cs-confirmation__title {
  font-size: var(--font-size-heading-l);
  line-height: var(--line-height-heading-l);
  letter-spacing: var(--letter-spacing-heading-l);
}

.cs-confirmation__content {
  padding: var(--space-container-content-top) var(--space-modal-horizontal) var(--space-modal-content-bottom);
}

.cs-confirmation__footer {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-xs);
  padding: var(--space-scaled-s) var(--space-modal-horizontal);
  border-top: var(--border-divider-section-width) solid var(--color-border-divider-default);
}

.cs-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-xxs);
  color: var(--color-text-empty);
  text-align: center;
}

.cs-empty__title {
  font-weight: var(--font-weight-bold);
}

.cs-empty__description {
  margin: 0;
}

.cs-empty__actions {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-xs);
  margin-top: var(--space-s);
}

/* =========================================================================================
   22. Code boxes + email preview
   ========================================================================================= */
/* Email bodies and team notes are shown exactly as stored, line breaks included. */
.email-body {
  margin: 0;
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-family: var(--font-family-base);
}

.cs-code-box,
.log-excerpt {
  margin: 0;
  padding: var(--space-xs) var(--space-s);
  border: var(--border-divider-list-width) solid var(--color-border-divider-secondary);
  border-radius: var(--border-radius-item);
  background: var(--color-background-cell-shaded);
  color: var(--color-text-body-default);
}

.log-excerpt {
  white-space: pre-wrap;
  overflow-wrap: anywhere;
  font-family: var(--font-family-monospace);
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-s);
  max-height: calc(var(--line-height-body-s) * 30);
  overflow: auto;
}

/* Cloudscape Box variant="code": a plain monospace run (no shaded background), the same look
   as a bare <code>. */
.cs-inline-code {
  font-family: var(--font-family-monospace);
  font-size: var(--font-size-body-s);
}

/* The HTML part of an email, previewed in a sandboxed frame (see _macros.html html_preview). */
.email-html-preview__bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs) var(--space-m);
  margin-bottom: var(--space-xs);
}

.email-html-frame {
  display: block;
  width: 100%;
  height: var(--cs-email-preview-height);
  background: var(--color-background-container-content);
  border: var(--border-divider-list-width) solid var(--color-border-divider-default);
  border-radius: var(--border-radius-item);
  resize: vertical;
  overflow: auto;
}

/* (Its keyboard focus ring: section 3; app.js adds .is-focus-visible while the keyboard focus
   is inside the frame, which :focus-visible does not match.) */

/* "Mobile width": a typical phone viewport, to check line length and wrapping. */
.email-html-preview:has(.html-width-mobile:checked) .email-html-frame {
  width: var(--cs-email-preview-mobile-width);
  max-width: 100%;
  height: var(--cs-email-preview-mobile-height);
}

/* =========================================================================================
   23. Utilities
   ========================================================================================= */
.cs-u-visually-hidden,
.cs-table__th--actions .cs-table__th-text {
  position: absolute !important;
  width: 1px !important;
  height: 1px !important;
  margin: -1px !important;
  padding: 0 !important;
  overflow: hidden !important;
  clip: rect(0 0 0 0) !important;
  white-space: nowrap !important;
  border: 0 !important;
}

.cs-u-secondary { color: var(--color-text-body-secondary); }
.cs-u-small {
  font-size: var(--font-size-body-s);
  line-height: var(--line-height-body-s);
  letter-spacing: var(--letter-spacing-body-s);
}

/* =========================================================================================
   24. Reduced motion (the motion tokens already drop to 0ms in tokens.css)
   ========================================================================================= */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    scroll-behavior: auto !important;
  }

  .cs-form-field__error > .cs-icon {
    animation: none;
  }
}

/* =========================================================================================
   25. Pages: rules for one page only, prefixed with the page's hook class. Everything that
       two pages share lives in the component sections above (move a rule up as soon as a
       second page needs it).
   ========================================================================================= */

/* --- Teams (teams/list.html, teams/_rows.html, teams/detail.html) --- */
:root {
  --team-table-name-width: 12rem; /* app: Team name column of the teams table (ellipsis past it) */
  --team-table-institution-width: 12rem; /* app: Institution column of the teams table */
  --team-table-site-width: 8rem; /* app: Site column of the teams table (short site names) */
  --team-table-email-min-width: 12rem; /* app: Email status column's floor, so the status, badge and flags do not wrap to 3-4 lines once the table scrolls sideways */
  --deliveries-table-reason-width: 12rem; /* app: Reason column of the team page's deliveries table */
  --delivery-error-width: 12rem; /* app: "Error:" / "Staff note:" line under a status (deliveries table) */
}

/* A team that is not in the latest import is shown dimmed. */
.team-row--missing > .cs-table__td:not(.cs-table__td--selection) {
  color: var(--color-text-body-secondary);
}

.team-table .cs-table__cell {
  vertical-align: middle;
}

/* Long names end in an ellipsis (the full text is in the cell's title). When the table is
   wider than the content area, its Actions column is sticky (see the table section). */
.team-table .team-table__name { --cs-cell-max-width: var(--team-table-name-width); }
.team-table .team-table__institution { --cs-cell-max-width: var(--team-table-institution-width); }
.team-table .team-table__site { --cs-cell-max-width: var(--team-table-site-width); }

.team-table .team-table__email .status-flags {
  max-width: var(--cs-table-wrap-min-width);
}

/* When space is short, the "simulated" badge and the flags go under the status instead of
   widening the column (rows with a PDF are two lines high anyway). The column keeps a
   floor width: squeezing it to its min-content wraps every row to 3-4 lines and gains
   nothing once the table scrolls sideways (12rem still fits at 1440 with the nav open). */
.team-table .team-table__email > .cs-table__cell {
  white-space: normal;
  min-width: var(--team-table-email-min-width);
}

.team-table .team-table__email .cs-status {
  white-space: nowrap;
}

/* Column fit: all ten columns need about 1380px of content width. Below that the Site
   column, then the Last sent column, are left out (both stay in the split panel and on the
   team page: Team details), so the table fits at 1440px with the navigation open; closing
   the navigation brings them back. Content width = viewport - 48px gutters (- 281px nav). */
@media (max-width: 1708px) {
  html:not(.cs-nav-closed) .team-table .team-table__site { display: none; }
}

@media (max-width: 1582px) {
  html:not(.cs-nav-closed) .team-table .team-table__last-sent { display: none; }
}

@media (max-width: 1427px) {
  .team-table .team-table__site { display: none; }
}

@media (max-width: 1301px) {
  .team-table .team-table__last-sent { display: none; }
}

/* Deliveries table (team page): long reasons and errors end in an ellipsis (the full error
   is in the title, the delivery's page and its full record), so the compact table fits. */
.deliveries-table__reason { --cs-cell-max-width: var(--deliveries-table-reason-width); }

/* The "Error:" (or "Staff note:") line under a delivery's status. Shared by two tables of
   these blocks: the team page's deliveries table (_macros.html deliveries_table) and the
   delivery history table (history/list.html, which narrows it below). */
.delivery-error {
  max-width: var(--delivery-error-width);
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}

/* --- Delivery history (history/list.html, history/detail.html, the delivery macros) --- */
:root {
  --history-table-team-width: 12rem; /* app: Team column of the history table (ellipsis past it) */
  --history-table-team-narrow-width: 8rem; /* app: the Team column when space is short (media queries below) */
  --history-table-subject-width: 12rem; /* app: Subject column of the history table */
  --history-filter-select-width: 13.5rem; /* app: each filter select, as wide as "Simulated (development)" */
}

/* Team and subject end in an ellipsis (the full text is in the cell's title). */
.history-table .history-table__team { --cs-cell-max-width: var(--history-table-team-width); }
.history-table .history-table__subject { --cs-cell-max-width: var(--history-table-subject-width); }

/* A failed or unconfirmed delivery's error, under its status: it never widens the Status
   column (width 0, then the column's width), so the column fit below stays true; the full
   text is in its title, the split panel and the delivery's page. */
.history-table .delivery-error {
  width: 0;
  min-width: 100%;
  max-width: none;
}

/* The filter: batch box, three selects and Apply on one row at 1440px with the navigation
   open (the selects are as wide as their longest option, "Simulated (development)"). */
.history-filter .cs-select-inline {
  flex: 0 0 var(--history-filter-select-width);
}

/* Column fit (like the teams table): all eleven columns need about 1511px of content width
   (with 16px to spare for longer ids). Below that Subject and Batch, then SES Message ID, are
   left out (all three stay in the split panel and on the delivery's page), and last the Team
   column narrows, so Status and Recipients always show from 1280px with the navigation open.
   Closing the navigation brings them back. Content width = viewport - 48px gutters (- 281px
   navigation). */
@media (max-width: 1855px) {
  html:not(.cs-nav-closed) .history-table .history-table__subject,
  html:not(.cs-nav-closed) .history-table .history-table__batch { display: none; }
}

@media (max-width: 1565px) {
  html:not(.cs-nav-closed) .history-table .history-table__message-id { display: none; }
}

@media (max-width: 1350px) {
  html:not(.cs-nav-closed) .history-table .history-table__team { --cs-cell-max-width: var(--history-table-team-narrow-width); }
}

@media (max-width: 1574px) {
  .history-table .history-table__subject,
  .history-table .history-table__batch { display: none; }
}

@media (max-width: 1284px) {
  .history-table .history-table__message-id { display: none; }
}

@media (max-width: 1069px) {
  .history-table .history-table__team { --cs-cell-max-width: var(--history-table-team-narrow-width); }
}

/* An unconfirmed delivery's alert: "in the form below" on the delivery's page, "on this
   delivery's page" when the same record shows in the history table's split panel. */
.delivery-alert__panel { display: none; }
.cs-split-panel .delivery-alert__here { display: none; }
.cs-split-panel .delivery-alert__panel { display: inline; }

/* --- Deletion (cleanup/*.html) --- */
/* The result page's next steps sit in the header actions: one flex row with them. */
.next-links { display: contents; }

/* --- Dashboard (dashboard.html) and competition years (years.html) --- */
:root {
  --dashboard-team-max-width: 20rem; /* app: Recent activity "Team" column, ellipsis beyond */
}

/* Next steps: the status text and its action button on one row (stacked on a phone). */
.dashboard-step {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-xs) var(--space-m);
}

@media (max-width: 688px) {
  .dashboard-step {
    flex-direction: column;
    align-items: flex-start;
  }
}

/* Next steps: rows divided by lines, tighter than the default column gutter. */
.dashboard-steps.cs-columns--borders-horizontal {
  row-gap: var(--space-scaled-xs);
}

.dashboard-steps.cs-columns--borders-horizontal > * + * {
  padding-top: var(--space-scaled-xs);
}

.dashboard-empty {
  margin: 0;
}

.recent-activity__team { --cs-cell-max-width: var(--dashboard-team-max-width); }

/* Years table: the row's action links stay on one line (the table scrolls sideways on a
   phone, like every Cloudscape table). */
.years-table__actions .cs-space-between {
  flex-wrap: nowrap;
  white-space: nowrap;
}

/* --- Import and generate (imports/*.html, generate/*.html) --- */
:root {
  --generate-name-max-width: 20rem; /* app: Invitations table "Team name" column, ellipsis beyond */
  --generate-need-min-width: 22rem; /* app: min width of a "Teams that need a PDF" grid column */
  --import-diff-field-width: 30%; /* app: "Field" column of the import preview's Old | New table */
}

.generate-result__hint {
  margin-top: var(--space-xxs);
}

.generate-table__name { --cs-cell-max-width: var(--generate-name-max-width); }

/* Invalid rows: one error status indicator per problem. */
.import-preview__problems {
  display: flex;
  flex-direction: column;
  gap: var(--space-xxs);
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Generate: "Teams that need a PDF", one team per line (status, then the linked team);
   long names wrap instead of widening the page. */
.generate-need__list {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, var(--generate-need-min-width)), 1fr));
  gap: var(--space-xs) var(--space-l);
  margin: 0;
  padding: 0;
  list-style: none;
}

.generate-need__item {
  min-width: 0;
  overflow-wrap: anywhere;
}

.generate-need__item > .cs-status {
  margin-right: var(--space-xxs);
}

/* Import preview, changed teams: one expandable per team holding a Field | Old | New table.
   Fixed columns that wrap anywhere, so long emails never widen the page on a phone. */
.import-diff__team .cs-expandable__title {
  overflow-wrap: anywhere;
}

.import-diff__fields {
  table-layout: fixed;
}

.import-diff__fields > thead > tr > th:first-child {
  width: var(--import-diff-field-width);
}

.import-diff__fields > tbody > tr > td {
  overflow-wrap: anywhere;
}

.import-diff__none {
  margin: 0;
}

@media (max-width: 688px) {
  .import-diff__fields > thead > tr > th,
  .import-diff__fields > tbody > tr > td {
    padding-right: var(--space-xs);
    padding-left: var(--space-xs);
  }

  .import-diff__fields > thead > tr > :first-child,
  .import-diff__fields > tbody > tr > :first-child {
    padding-left: 0;
  }
}

/* --- Per-team send and resend (send/confirm, result, resend_form, resend_confirm and the
   blockers_alert macro) --- */
/* Compose: "Already uploaded: <file>" above the file input. */
.resend-form__uploaded {
  margin: 0 0 var(--space-xs);
}

/* The way-out buttons under the blocker list. */
.blockers__actions {
  margin-top: var(--space-xs);
}

/* --- Bulk send (send/bulk, bulk_resend, dry_run, bulk_confirm, bulk_result) --- */
/* Team columns end in an ellipsis (full text in the title); reasons and messages wrap freely.
   The resend selection's Team cell wraps instead (cs.td(wrap=true)): the name is what you tick. */
.bulk-send .bulk-table__name,
.bulk-send .bulk-table__institution,
.bulk-send .bulk-table__team,
.bulk-send .bulk-table__attachment { --cs-cell-max-width: var(--cs-table-wrap-width); }
.resend-teams .bulk-table__institution { --cs-cell-max-width: var(--cs-table-wrap-min-width); }

/* Eligible teams (send/bulk) has three long texts in five columns. Where the content area is
   narrower than the table (1440px with the navigation open: about 825px for about 1060px of
   single-line content), the team name, institution and attachment file name wrap instead of
   widening the table past it (the file name may break anywhere); each keeps at least
   --bulk-table-wrap-min-width, and on a wide content area they stay on one line. */
:root {
  --bulk-table-wrap-min-width: 8rem; /* app: narrowest a wrapping Eligible teams column gets */
}

.eligible-teams .bulk-table__name > .cs-table__cell,
.eligible-teams .bulk-table__institution > .cs-table__cell,
.eligible-teams .bulk-table__attachment > .cs-table__cell {
  min-width: var(--bulk-table-wrap-min-width);
  white-space: normal;
  overflow-wrap: anywhere;
}

.bulk-send .bulk-table__reason > .cs-table__cell,
.bulk-send .bulk-table__message > .cs-table__cell {
  min-width: var(--cs-table-wrap-width);
  max-width: none;
}

.bulk-send .bulk-table__email .status-flags {
  max-width: var(--cs-table-wrap-min-width);
}

/* Resend selection: a click on a team's name ticks its row; the "tick at least one team"
   error sits in the table header. */
.resend-teams__label {
  cursor: pointer;
}

.resend-teams__error {
  padding-top: var(--space-xxs);
}

/* Dry run: the READY status in a team's header description, then its recipients. */
.dry-run-team .cs-expandable__description > .cs-status {
  margin-right: var(--space-xs);
}

/* Confirm: the execute form follows the page's containers. */
.bulk-execute {
  margin-top: var(--space-l);
}

/* Result: the counters ("Successfully sent: 2" ...) at heading size. */
.bulk-summary .cs-status {
  font-size: var(--font-size-heading-m);
  line-height: var(--line-height-heading-m);
  letter-spacing: var(--letter-spacing-heading-m);
  font-weight: var(--font-weight-bold);
}
