/* AWS Data Exchange — Data Grants Prototype
   Styled with current Cloudscape Design System tokens (cloudscape.design) */

:root {
  /* Color tokens (sampled from live Cloudscape site) */
  --color-text-heading: #0f141a;
  --color-text-body: #16191f;
  --color-text-body-secondary: #424650;
  --color-text-body-tertiary: #656871;
  --color-text-disabled: #b4b4bb;
  --color-text-link: #006ce0;
  --color-text-link-hover: #002b66;
  --color-text-inverted: #f9f9fa;
  --color-text-inverted-secondary: #c6c6cd;

  /* Verified against cloudscape.design/examples/react/product-detail-page.html
     (a live "high-contrast" hero header): heading/body text and link colors
     when placed directly on the #0f141a hero background specifically —
     these read lower-contrast than --color-text-inverted on a lighter
     surface, so they're their own tokens rather than reused ones. */
  --color-text-hero-heading: #ebebf0;
  --color-text-hero-body: #c6c6cd;
  --color-link-hero: #42b4ff;

  /* Verified 2026-08 against cloudscape.design/examples/react/table.html and
     dashboard.html via computed-style inspection of the live site: the page
     canvas and full-page table sections share the same near-white #fcfcfd —
     there is no grey-canvas/white-card split. Only "default" variant
     Containers (e.g. dashboard widgets) are pure white with a visible
     #c6c6cd border and 16px radius; full-page table sections have none. */
  --color-bg-layout: #fcfcfd;
  --color-bg-container: #ffffff;
  --color-bg-header: #161d26;
  --color-bg-header-hover: #232b36;
  --color-bg-input: #ffffff;
  --color-bg-table-header: #fcfcfd;
  --color-bg-row-hover: #f2fbff;
  --color-bg-row-selected: #f0fbff;

  --color-border: #dedee3;
  --color-border-strong: #c6c6cd;
  --color-border-divider: #ebebf0;
  --color-container-border: #c6c6cd;

  --color-blue: #006ce0;
  --color-blue-dark: #004a9e;
  --color-blue-tint: #f0fbff;

  --color-green: #00802f;
  --color-green-tint: #effff1;
  --color-green-border: #b5e8bf;

  --color-red: #db0000;
  --color-red-tint: #fff5f5;
  --color-red-border: #ffcfcf;

  --color-amber-text: #855900;
  --color-amber-tint: #fffef0;
  --color-amber-icon: #866300;

  --color-grey-text: #656871;

  /* "Amazon Ember" is AWS's internal console font and isn't served by the
     public cloudscape.design site itself — it ships Open Sans as the real
     typeface. Listed first here as a progressive enhancement for anyone
     with it installed locally; the fallback chain matches the live site
     exactly so rendered output is identical for everyone else. */
  --font-family: "Amazon Ember", "Open Sans", "Helvetica Neue", Roboto, Arial, sans-serif;

  --radius-button: 20px;
  --radius-input: 8px;
  --radius-panel: 16px;
  --radius-badge: 999px;

  --space-xxs: 4px;
  --space-xs: 8px;
  --space-s: 12px;
  --space-m: 16px;
  --space-l: 20px;
  --space-xl: 24px;
  --space-xxl: 32px;
}

* {
  box-sizing: border-box;
}

html,
body {
  margin: 0;
  padding: 0;
}

body {
  font-family: var(--font-family);
  font-size: 14px;
  color: var(--color-text-body);
  background: var(--color-bg-layout);
  -webkit-font-smoothing: antialiased;
}

a {
  color: var(--color-text-link);
  text-decoration: none;
}

a:hover {
  color: var(--color-text-link-hover);
  text-decoration: underline;
}

button {
  font-family: inherit;
}

/* inline-block (not block): inside a flex container this behaves
   identically to block (flex items ignore their own inline/block distinction),
   but it also lets an icon flow correctly inline within prose text — e.g. an
   external-link icon glued to the end of a link — without wrapping onto its
   own line the way a block-level child always would. Verified against every
   existing flex-based icon usage in this file with no regressions. */
svg {
  display: inline-block;
  vertical-align: -2px;
  flex-shrink: 0;
}

/* ============ TOP HEADER ============
   42px tall, per explicit spec: logo, 9-square Services icon, wide search
   box (5-6px vertical margin), then icon/divider/icon/divider/region/
   divider/user. */

.top-header {
  height: 42px;
  background: var(--color-bg-header);
  color: var(--color-text-inverted);
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: 0 var(--space-m);
  position: sticky;
  top: 0;
  z-index: 100;
}

.top-header__logo {
  display: flex;
  align-items: center;
  white-space: nowrap;
  flex-shrink: 0;
}

.top-header__logo svg {
  flex-shrink: 0;
}

.top-header__services {
  display: flex;
  align-items: center;
  gap: 6px;
  color: var(--color-text-inverted);
  font-size: 14px;
  cursor: pointer;
  padding: 6px 8px;
  border-radius: 4px;
  flex-shrink: 0;
}

.top-header__services:hover {
  background: var(--color-bg-header-hover);
}

.top-header__search {
  flex: 1;
  display: flex;
  align-items: center;
  background: #0f141a;
  border: 1px solid #424650;
  border-radius: 4px;
  padding: 0 var(--space-s);
  height: 31px;
  margin: 5px 0;
  color: var(--color-text-inverted-secondary);
  gap: var(--space-xs);
}

.top-header__search input {
  background: transparent;
  border: none;
  outline: none;
  color: var(--color-text-inverted);
  font-size: 14px;
  flex: 1;
  font-family: inherit;
}

.top-header__search input::placeholder {
  color: #8c8c94;
  font-style: italic;
}

.top-header__shortcut {
  font-size: 12px;
  color: #8c8c94;
  border: 1px solid #424650;
  border-radius: 3px;
  padding: 1px 5px;
}

.top-header__spacer {
  flex: 0 0 var(--space-s);
}

.top-header__icon-btn {
  width: 20px;
  height: 20px;
  min-width: 20px;
  min-height: 20px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--color-text-inverted);
  background: transparent;
  border: none;
  flex-shrink: 0;
}

.top-header__icon-btn svg {
  width: 20px;
  height: 20px;
}

/* No margin here — .top-header already sets a 12px flex `gap` between every
   child, so adding the divider's own margin on top of that was double-
   counting the spacing (24px instead of 12px on each side). */
.top-header__divider {
  width: 1px;
  height: 20px;
  background: #424650;
  flex-shrink: 0;
}

.top-header__region,
.top-header__user {
  display: flex;
  align-items: center;
  gap: 4px;
  cursor: pointer;
  color: var(--color-text-inverted);
  font-size: 13px;
  white-space: nowrap;
  flex-shrink: 0;
}

/* ============ TOOLBAR (breadcrumb panel) ============
   Cloudscape's AppLayout renders a full-bleed strip directly under the top
   header — menu toggle + breadcrumbs on the left, a global info trigger on
   the right — with its own bottom border. The side nav's vertical border
   begins at that strip's bottom edge, not at the very top, which is what
   produces the perpendicular join between the two borders. Verified against
   cloudscape.design/examples/react/table.html. */

.toolbar {
  height: 42px;
  flex-shrink: 0;
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: 0 var(--space-l);
  background: var(--color-bg-container);
  border-bottom: 1px solid var(--color-border-strong);
}

.toolbar__menu-toggle {
  width: 30px;
  height: 30px;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  background: transparent;
  cursor: pointer;
  flex-shrink: 0;
}

/* Four states, verified against reference screenshots:
   nav open + no hover  -> filled AWS-blue circle, white icon
   nav open + hover     -> darker blue circle
   nav closed + no hover -> no circle, dark icon
   nav closed + hover    -> grey circle, dark icon */
.toolbar__menu-circle {
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: var(--color-blue);
  color: #fff;
}

.toolbar__menu-toggle:hover .toolbar__menu-circle {
  background: var(--color-blue-dark);
}

.toolbar__menu-toggle.is-collapsed .toolbar__menu-circle {
  background: transparent;
  color: var(--color-text-body);
}

.toolbar__menu-toggle.is-collapsed:hover .toolbar__menu-circle {
  background: var(--color-border-divider);
}

.toolbar__spacer {
  flex: 1;
}

.toolbar__info-btn {
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-input);
  border: none;
  background: transparent;
  color: var(--color-text-body-secondary);
  cursor: pointer;
  flex-shrink: 0;
}

.toolbar__info-btn:hover {
  background: var(--color-bg-layout);
}

/* ============ APP LAYOUT ============ */

.app-layout {
  display: flex;
  align-items: stretch;
  min-height: calc(100vh - 42px - 42px);
  position: relative;
}

.app-layout.nav-collapsed .side-nav {
  display: none;
}

/* ============ SIDE NAV ============
   Spacing verified pixel-for-pixel against cloudscape.design/examples/react/
   table.html: nav content inset 20px left / 16px right, nav links sit flush
   with zero gap between them (28px row height from 4px/8px padding alone),
   ~8px between the last item of one section and the next section's header,
   and section headers are 16px/400 weight, not bold. */

.side-nav {
  width: 280px;
  height: 100%;
  box-sizing: border-box;
  flex-shrink: 0;
  background: var(--color-bg-container);
  border-right: 1px solid var(--color-border-strong);
  padding: var(--space-l) 16px var(--space-xxl) 20px;
}

.side-nav__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-m);
  /* Brings the title text inset to 28px from the nav's left edge (20px
     container padding + 8px here), matching Cloudscape's verified h2
     header padding (20px 56px 20px 28px) on cloudscape.design's own
     side-navigation demo. */
  padding-left: 8px;
}

.side-nav__title {
  font-size: 18px;
  font-weight: 700;
  color: var(--color-text-heading);
}

.side-nav__close {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-body-secondary);
  display: flex;
  padding: 4px;
  border-radius: 4px;
}

.side-nav__close:hover {
  background: var(--color-bg-layout);
}

/* Zero top margin — verified against cloudscape.design's own reference:
   there is no explicit gap between the last flat item and the next
   expandable group's header row; every row in the nav (flat, header, or
   nested) is a uniform 28px tall with nothing but that height carrying
   the rhythm. */
.side-nav__section {
  margin-top: 0;
}

/* The chevron (collapse toggle) and the group label (a real link to the
   feature's own landing page) are separate click targets living inside
   what used to be one combined clickable row. Verified against
   cloudscape.design's own expandable-link-group markup: the toggle button
   is absolutely positioned into the row's left gutter (Cloudscape does
   this with a negative margin instead, but the visual result is the
   same) so it never pushes the link text — the link keeps the exact same
   4px/8px padding as a plain .side-nav__link, landing its text at the
   same 28px inset as every other top-level item. */
.side-nav__section-title {
  position: relative;
  display: flex;
  align-items: center;
}

.side-nav__section-toggle {
  position: absolute;
  /* Icon's right edge sits 5px before the link text's own start (which is
     already inset 8px by the link's own padding) — verified pixel-for-
     pixel against cloudscape.design's expandable-link-group toggle. */
  left: -13px;
  top: 50%;
  transform: translateY(-50%);
  width: 16px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  color: var(--color-text-body-secondary);
  flex-shrink: 0;
}

/* Same size/weight/color as a plain .side-nav__link — Cloudscape verified:
   expandable-link-group triggers use the identical 14px/400 link style as
   every other nav item, not a larger "section header" style. */
.side-nav__section-link {
  display: flex;
  align-items: center;
  flex: 1;
  padding: 4px 8px;
  border-radius: 8px;
  font-size: 14px;
  line-height: 1.4;
  font-weight: 400;
  color: var(--color-text-body-secondary);
  user-select: none;
}

.side-nav__section-link:hover {
  background: var(--color-bg-layout);
  text-decoration: none;
}

.side-nav__section-link.active {
  color: var(--color-text-link);
  font-weight: 700;
}

.side-nav__section-title svg {
  transition: transform 0.15s ease;
  flex-shrink: 0;
}

.side-nav__section.collapsed .side-nav__section-title svg {
  transform: rotate(-90deg);
}

.side-nav__section.collapsed .side-nav__items {
  display: none;
}

.side-nav__items {
  list-style: none;
  margin: 0;
  /* Nested items sit 24px further right than their parent group's own
     28px inset — verified against cloudscape.design's expandable-link-
     group demo (top-level item text at 52px from nav edge, nested child
     text at 76px, i.e. +24px). */
  padding: 0 0 0 24px;
}

.side-nav__items li {
  margin: 0;
}

.side-nav__link {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 4px 8px;
  border-radius: 8px;
  color: var(--color-text-body-secondary);
  font-size: 14px;
  line-height: 1.4;
}

.side-nav__link:hover {
  background: var(--color-bg-layout);
  text-decoration: none;
}

.side-nav__link.active {
  color: var(--color-text-link);
  font-weight: 700;
}

/* Cloudscape's own guidance explicitly says not to use a badge for "new
   page" labels — plain bold text only. Verified against
   cloudscape.design/patterns/general/announcing-new-features/. */
.side-nav__badge {
  font-size: 12px;
  font-weight: 700;
  color: var(--color-blue);
  text-decoration: underline dotted;
  text-underline-offset: 2px;
}

.side-nav__divider {
  border: none;
  border-top: 1px solid var(--color-border-divider);
  margin: var(--space-m) 0;
}

.side-nav__external {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 4px 0;
  color: var(--color-text-link);
  font-size: 14px;
}

.side-nav__external svg {
  color: var(--color-text-body-tertiary);
}

/* ============ MAIN CONTENT ============ */

.main-content {
  flex: 1;
  min-width: 0;
  padding: 20px;
}

.breadcrumb {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
  min-width: 0;
}

/* Every segment but the current one keeps its natural width and never
   wraps — only the final (current-page) segment, which is the one most
   likely to be long, shrinks and truncates when space runs out. Without
   this, a flex row with no explicit sizing shrinks every segment
   equally, wrapping each one's text internally instead of just the
   last. */
.breadcrumb a,
.breadcrumb .sep,
.breadcrumb__ellipsis-trigger {
  flex-shrink: 0;
  white-space: nowrap;
}

.breadcrumb a {
  color: var(--color-text-link);
  font-size: 14px;
  text-decoration: underline;
}

.breadcrumb a:hover {
  color: var(--color-text-link-hover);
}

.breadcrumb .sep {
  color: var(--color-text-body-tertiary);
  display: flex;
}

.breadcrumb .current {
  color: var(--color-grey-text);
  font-weight: 700;
  /* Floor so it always shows at least a few truncated characters instead
     of shrinking to nothing when every other segment (flex-shrink:0
     above) has already claimed all the space it needs. */
  min-width: 80px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.breadcrumb-wrapper {
  display: flex;
  min-width: 0;
}

.breadcrumb--collapsed {
  display: none;
}

/* Matches Cloudscape's own BreadcrumbGroup collapse point (verified by
   resizing cloudscape.design/examples/react/edit.html down until its
   breadcrumb switched to the "..." control). */
@media (max-width: 700px) {
  .breadcrumb--full {
    display: none;
  }

  .breadcrumb--collapsed {
    display: flex;
    align-items: center;
    gap: 6px;
  }
}

.breadcrumb__ellipsis-trigger {
  background: none;
  border: none;
  cursor: pointer;
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-link);
  padding: 0;
}

.breadcrumb__ellipsis-trigger:hover {
  color: var(--color-text-link-hover);
}

.dropdown-menu a {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  font-size: 14px;
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--color-text-body);
  text-decoration: none;
}

.dropdown-menu a:hover {
  background: var(--color-bg-layout);
}

.page-header {
  display: flex;
  align-items: baseline;
  gap: var(--space-s);
  margin-bottom: var(--space-l);
}

.page-header h1 {
  font-size: 20px;
  font-weight: 700;
  color: var(--color-text-heading);
  margin: 0;
}

.info-link {
  font-size: 14px;
  font-weight: 400;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  color: var(--color-text-link);
}

.info-link:hover {
  text-decoration: underline;
}

/* ============ CONTAINER / CREATION STEPS ============ */

/* Cloudscape's "default"-variant Container: solid white, visible 1px
   #c6c6cd border, 16px radius, no shadow — verified against a dashboard
   widget on the live site. Used here only for the supplementary creation
   steps callout, not for primary full-page table sections (see below). */
.container {
  background: var(--color-bg-container);
  border: 1px solid var(--color-container-border);
  border-radius: var(--radius-panel);
  margin-bottom: var(--space-l);
}

.creation-steps {
  overflow: hidden;
}

.creation-steps__header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: var(--space-m) var(--space-l);
  cursor: pointer;
  user-select: none;
  border-bottom: 1px solid var(--color-border-divider);
  font-weight: 700;
  font-size: 16px;
  color: var(--color-text-heading);
}

.creation-steps__header svg {
  transition: transform 0.15s ease;
}

.creation-steps.collapsed .creation-steps__header {
  border-bottom: none;
}

.creation-steps.collapsed .creation-steps__header svg {
  transform: rotate(-90deg);
}

.creation-steps.collapsed .creation-steps__body {
  display: none;
}

.creation-steps__body {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  padding: var(--space-xl) var(--space-l);
  gap: var(--space-m);
}

/* flex-basis 250px (not the usual 0%) so the browser only wraps a step to
   the next line once it can no longer fit at least 250px — matching a
   fixed minimum readable width instead of shrinking indefinitely. */
.creation-steps__step {
  flex: 1 1 250px;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--space-s);
}

.creation-steps__icon {
  width: 64px;
  height: 64px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--color-text-heading);
}

/* The icons used across these steps come from very different native
   viewBox sizes (16px to 36px) — force a single rendered size here so
   every step's icon reads as visually the same weight. */
.creation-steps__icon svg {
  width: 32px;
  height: 32px;
}

.creation-steps__text {
  font-size: 14px;
  color: var(--color-text-body);
  line-height: 1.5;
}

.creation-steps__arrow {
  color: var(--color-border-strong);
  margin-top: 20px;
  flex-shrink: 0;
}

/* ============ TABS ============ */

/* Verified against cloudscape.design/components/tabs/: 16px/700 label text,
   tight "7px 4px 7px 3px" padding, and a full-width #c6c6cd bottom rule.
   Cloudscape's own computed value is exactly 1px, but on our pages the
   tabs sit on an open white canvas with no adjacent card border to give
   the eye contrast, so the same 1px/#c6c6cd line reads as effectively
   invisible — bumped to 2px (same color) so it reliably reads as a
   divider without going dark enough to look like a bold rule.
   gap:0 (not 16px) — Cloudscape's own <li> tabs sit flush adjacent with
   zero gap; the visual spacing between labels comes entirely from each
   button's own small padding plus the vertical divider below, not from
   a flex gap. Missed this on three earlier passes by only checking each
   element's own border (transparent on every side, as expected) and
   never checking for a ::before pseudo-element carrying a real
   border-right — that pseudo is exactly how Cloudscape draws the
   vertical divider between tabs, see .tab:not(:last-child)::before. */
.tabs {
  display: flex;
  gap: 0;
  border-bottom: 2px solid var(--color-border-strong);
  margin-bottom: var(--space-l);
}

/* Padding is 7px/12px/7px/10px, not 7px/4px/7px/3px — Cloudscape splits
   this across two nested elements (the button keeps 7px/4px/7px/3px, but
   its wrapping tabs-tab-header-container div adds its own 0/8px/0/7px on
   top), which our single-element .tab doesn't have a slot for. Folding
   both layers into one padding here reproduces the same measured
   14px text-to-divider / 13px divider-to-next-text gap. */
.tab {
  position: relative;
  background: none;
  border: none;
  cursor: pointer;
  font-size: 16px;
  font-weight: 700;
  color: var(--color-text-body-secondary);
  padding: 7px 12px 7px 10px;
}

.tab.active {
  color: var(--color-text-heading);
}

/* The vertical divider between adjacent tabs — verified against
   cloudscape.design's own tabs-tab-header-container::before rule
   (border-inline-end: 1px solid #c6c6cd, inset 8px top/bottom). Every
   tab except the last one gets it, since there's nothing to divide from
   after the final tab. */
.tab:not(:last-child)::before {
  content: "";
  position: absolute;
  top: 8px;
  bottom: 8px;
  right: 0;
  border-right: 1px solid var(--color-border-strong);
}

/* The active indicator is its own rounded-cap pill (::after), not a
   border — verified against cloudscape.design's own tab markup, which
   uses a 4px bar with a full 20px border-radius on every corner rather
   than a hard-edged border-bottom. The rounded ends are what keep a bar
   this tall from reading as "too thick": a sharp-cornered rectangle at
   the same height looks visibly heavier than a pill does. */
.tab.active::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: -2px;
  height: 4px;
  background: var(--color-blue);
  border-radius: 20px;
}

.tab-panel {
  display: none;
}

.tab-panel.active {
  display: block;
}

/* ============ TABLE PANEL ============ */

/* Verified on the live "table view" / "table property filter" demos: the
   primary full-page table section carries no border, background fill, or
   shadow of its own — it sits flush on the page canvas (both #fcfcfd) and
   is separated purely by whitespace and the table's own row hairlines. */
.table-panel {
  background: transparent;
  border: none;
  padding: 0;
}

.table-panel__header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-m);
  margin-bottom: var(--space-m);
}

.table-panel__title-group h2 {
  font-size: 18px;
  font-weight: 700;
  margin: 0 0 4px;
  color: var(--color-text-heading);
}

.table-panel__count {
  font-weight: 400;
  color: var(--color-text-body-secondary);
}

.table-panel__subtitle {
  font-size: 14px;
  color: var(--color-text-body-secondary);
  margin: 0;
}

.table-panel__actions {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  flex-shrink: 0;
}

.toggle {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--color-text-body);
  cursor: pointer;
  user-select: none;
}

.toggle input {
  display: none;
}

.toggle__track {
  width: 34px;
  height: 18px;
  border-radius: 999px;
  background: var(--color-border-strong);
  position: relative;
  transition: background 0.15s ease;
  flex-shrink: 0;
}

.toggle__track::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.15s ease;
}

.toggle input:checked + .toggle__track {
  background: var(--color-blue);
}

.toggle input:checked + .toggle__track::after {
  transform: translateX(16px);
}

/* Buttons */

.btn {
  height: 32px;
  padding: 0 var(--space-l);
  border-radius: var(--radius-button);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  border: 2px solid transparent;
}

/* Manual-refresh button: 32px circle, blue border + blue icon on white —
   verified against cloudscape.design/patterns/general/loading-and-refreshing/ */
.btn-icon {
  width: 32px;
  height: 32px;
  padding: 0;
  justify-content: center;
  border-radius: 50%;
  border: 2px solid var(--color-blue);
  background: var(--color-bg-container);
  color: var(--color-blue);
}

.btn-icon:hover {
  background: var(--color-bg-layout);
  color: var(--color-blue);
}

/* When a .btn is an <a> (e.g. a wizard-entry button that's really a link),
   the generic `a:hover` rule elsewhere in this file has higher specificity
   than a plain `.btn-primary`/`.btn-normal` color declaration, so hovering
   would otherwise silently repaint the label with the link-hover color and
   underline it — verified against cloudscape.design/components/button/,
   where a primary button's hover only darkens the fill; the label stays
   put. Restated per variant below so this can't regress the same way. */
.btn:hover {
  text-decoration: none;
}

/* Normal/secondary button border is AWS blue, not grey — verified against
   the "with action buttons" table example on cloudscape.design. */
.btn-normal {
  background: var(--color-bg-container);
  border-color: var(--color-blue);
  color: var(--color-blue);
}

.btn-normal:hover {
  background: var(--color-bg-layout);
  color: var(--color-blue);
}

.btn-normal:disabled {
  color: var(--color-text-body-tertiary);
  border-color: var(--color-border);
  cursor: not-allowed;
  background: var(--color-bg-layout);
}

.btn-primary {
  background: var(--color-blue);
  border-color: var(--color-blue);
  color: #fff;
}

.btn-primary:hover {
  background: var(--color-blue-dark);
  border-color: var(--color-blue-dark);
  color: #fff;
}

.btn-primary:disabled {
  background: #d9d9de;
  border-color: #d9d9de;
  color: #8c8c94;
  cursor: not-allowed;
}

.btn-dropdown {
  position: relative;
}

.dropdown-menu {
  position: absolute;
  top: calc(100% + 4px);
  right: 0;
  background: var(--color-bg-container);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-input);
  box-shadow: 0 4px 20px rgba(15, 20, 26, 0.15);
  min-width: 180px;
  padding: 4px;
  z-index: 20;
  display: none;
}

.dropdown-menu.open {
  display: block;
}

.dropdown-menu button {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  font-size: 14px;
  padding: 8px 10px;
  border-radius: 6px;
  cursor: pointer;
  color: var(--color-text-body);
}

.dropdown-menu button:hover {
  background: var(--color-bg-layout);
}

.dropdown-menu button:disabled {
  color: var(--color-text-body-tertiary);
  cursor: not-allowed;
}

/* Search + pagination row */

/* Verified against cloudscape.design/components/table/ (common-table
   example, viewed at full desktop width — a narrow embedded preview frame
   understates this): search/filters and pagination+preferences share one
   row, with the latter pushed to the far right via margin-left:auto.
   flex-wrap only drops the controls to their own row once the row actually
   runs out of horizontal space (i.e. down at mobile width), never before. */
.table-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  margin-bottom: var(--space-m);
  flex-wrap: wrap;
}

.table-toolbar__controls {
  display: flex;
  align-items: center;
  margin-left: auto;
}

.search-input {
  flex: 1;
  display: flex;
  align-items: center;
  gap: 8px;
  height: 32px;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-input);
  padding: 0 var(--space-s);
  color: var(--color-text-body-tertiary);
  background: var(--color-bg-input);
}

.search-input input {
  border: none;
  outline: none;
  flex: 1;
  font-size: 14px;
  font-family: inherit;
  color: var(--color-text-body);
  background: transparent;
}

.search-input svg {
  flex-shrink: 0;
  color: var(--color-text-body-tertiary);
}

/* Verified against cloudscape.design/components/pagination/: page-number
   buttons are plain text (no box/pill), 20x24, current page is bold
   near-black, others grey, disabled lighter grey. Hover only darkens text —
   no background. The preferences trigger is a separate borderless icon
   button (20px gap from the pagination group) that only darkens on hover. */
.pagination {
  display: flex;
  align-items: center;
  gap: 4px;
  flex-shrink: 0;
}

.page-btn {
  box-sizing: border-box;
  width: 20px;
  height: 24px;
  border: 2px solid transparent;
  background: none;
  border-radius: 0;
  cursor: pointer;
  color: var(--color-text-body-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
}

.page-btn:hover:not(:disabled) {
  color: var(--color-text-heading);
}

.page-btn:disabled {
  color: var(--color-text-disabled);
  cursor: not-allowed;
}

.page-btn.current {
  color: var(--color-text-heading);
  font-weight: 700;
}

/* Divider drawn as a ::before rather than a border on the button itself —
   the button's own border-radius:20px pill shape would clip a real
   border-left into a curved sliver instead of a straight line. Verified
   pixel-for-pixel against cloudscape.design/examples/react/table.html:
   the divider is 1px solid var(--color-border-strong) (their computed
   rgb(198,198,205), not the lighter --color-border-divider token), sits
   exactly 8px after the pagination group, 8px before the button, and is
   inset to align with the 24px-tall pagination row it sits next to —
   NOT the .page-settings button's own taller 32px hit target, which
   would otherwise overshoot visibly above/below the pagination. */
.page-settings {
  position: relative;
  margin-left: 17px;
  width: 28px;
  height: 32px;
  border: none;
  border-radius: 20px;
  background: none;
  color: var(--color-text-body-secondary);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}

.page-settings::before {
  content: "";
  position: absolute;
  left: -9px;
  top: 4px;
  bottom: 4px;
  width: 1px;
  background: var(--color-border-strong);
}

.page-settings:hover {
  color: var(--color-text-heading);
}

/* Table — no wrapping border/radius: on the live full-page table demos the
   table sits directly on the page canvas, structured only by row hairlines. */

.table-scroll {
  overflow-x: auto;
}

/* border-collapse:separate + border-spacing:0 is the verified live-
   Cloudscape recipe — it lets each cell own an independent border (needed
   for per-cell selection radius) without the collapsed-border merging that
   caused row selection to shift the whole table by 1px, and without
   changing row height when a cell's border color/width changes on
   selection (verified directly against the live table: selecting a row
   does not move any other row by even 1px). table-layout stays auto since
   our columns rely on content-based sizing, not the live demo's fixed
   layout. */
table.data-table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: 14px;
}

.data-table thead th {
  position: relative;
  background: var(--color-bg-table-header);
  color: var(--color-text-body-secondary);
  font-weight: 700;
  text-align: left;
  padding: 9px 20px;
  border-bottom: 1px solid var(--color-border-divider);
  white-space: nowrap;
  cursor: pointer;
  user-select: none;
}

.data-table thead th.no-sort {
  cursor: default;
}

/* The vertical divider between header cells — found only after
   discovering (the same way as the tabs divider) that it isn't a border
   on the th or a pseudo-element at all: Cloudscape renders it as an
   actual <span class="divider"> sibling inside every th but the last
   one, with a 1px #c6c6cd border-inline-start inset ~9px top/bottom.
   We don't have that sibling span, so a ::after pseudo-element
   reproduces the same measured inset instead. */
.data-table thead th:not(:last-child)::after {
  content: "";
  position: absolute;
  top: 9px;
  bottom: 9px;
  right: 0;
  border-right: 1px solid var(--color-border-strong);
}

/* The active sort column's icon (sortAsc/sortDesc) is solid-filled,
   unlike the hollow sortNeutral icon every other sortable column shows —
   both use currentColor, so darkening the whole header's text color to
   match cloudscape.design's own active-sort color is enough to recolor
   the icon too. */
.data-table thead th.sorted {
  color: var(--color-text-heading);
}

.data-table thead th .th-inner {
  display: flex;
  align-items: center;
  gap: 6px;
}

.data-table thead th svg {
  flex-shrink: 0;
}

/* Every cell always reserves the same border widths it would have when
   selected (1px top / 1px bottom / 2px left+right on edge columns) —
   selection only ever changes color, never width, which is what makes the
   live Cloudscape table immune to any layout shift on selection. */
.data-table tbody td {
  padding: 9px 20px;
  border-top: 2px solid transparent;
  border-bottom: 2px solid var(--color-border-divider);
  color: var(--color-text-body);
  vertical-align: middle;
  white-space: nowrap;
}

/* Table cell links are always underlined, unlike nav/button links which
   only underline on hover. */
.data-table tbody td a {
  text-decoration: underline;
}

.data-table tbody td:first-child {
  border-left: 2px solid transparent;
}

.data-table tbody td:last-child {
  border-right: 2px solid transparent;
}

/* Two tables sharing one card, separated by a divider (e.g. "All products"
   above "Selected products"): the top table's last row already draws its
   own bottom border, which doubles up visually right next to the divider
   below it. Suppress it (unless that row is selected, which still needs
   its blue border) so only the divider's single line shows between the
   two tables. */
div:has(+ hr.side-nav__divider) .data-table tbody tr:last-child:not(.selected) td {
  border-bottom-color: transparent;
}

.data-table th.checkbox-col,
.data-table th.radio-col,
.data-table td.checkbox-col,
.data-table td.radio-col {
  padding: 1px;
  text-align: center;
}

/* Verified against cloudscape.design/components/table/?example=simple:
   a table with no selection column has its first column's cell edge
   (not just its text) land flush with the card's own title above it —
   apply .simple to any <table class="data-table"> that has no checkbox-
   or radio-col. */
.data-table.simple thead th:first-child,
.data-table.simple tbody td:first-child {
  padding-left: 0;
}

.data-table tbody td.wrap-col {
  white-space: normal;
  max-width: 320px;
}

.data-table tbody tr:hover {
  background: var(--color-bg-row-hover);
}

/* Selected row: verified against the live table — border-color switches to
   blue and border-top/bottom-width switches 1px->2px (Cloudscape's own
   selected cells measure the same way and still don't shift the table).
   Corner radius is conditional: a row only rounds an edge that isn't
   shared with an equally-selected neighbor, so a contiguous block of
   selected rows rounds only its outer corners, matching the live table. */
.data-table tbody tr.selected {
  background: var(--color-bg-row-selected);
}

.data-table tbody tr.selected td {
  border-top-color: var(--color-blue);
  border-bottom-color: var(--color-blue);
}

/* With border-collapse:separate every row draws its own border, so at the
   shared boundary between two contiguously-selected rows the row above's
   bottom border AND the row below's top border would both render blue,
   doubling that line to 4px vs. 2px everywhere else. Only the top row
   "owns" that shared line — the bottom row suppresses its own top border
   there so exactly one 2px line renders, same as every other edge. */
.data-table tbody tr.selected:not(.selected--top) td {
  border-top-color: transparent;
}

.data-table tbody tr.selected td:first-child {
  border-left-color: var(--color-blue);
}

.data-table tbody tr.selected td:last-child {
  border-right-color: var(--color-blue);
}

.data-table tbody tr.selected.selected--top td:first-child {
  border-top-left-radius: 8px;
}

.data-table tbody tr.selected.selected--top td:last-child {
  border-top-right-radius: 8px;
}

.data-table tbody tr.selected.selected--bottom td:first-child {
  border-bottom-left-radius: 8px;
}

.data-table tbody tr.selected.selected--bottom td:last-child {
  border-bottom-right-radius: 8px;
}

.data-table .checkbox-col,
.data-table .radio-col {
  width: 40px;
  min-width: 40px;
  box-sizing: border-box;
}

/* Custom checkbox matching cloudscape.design/components/checkbox/ exactly:
   16x16, rx 3, 1px #8c8c94 stroke unchecked; solid AWS-blue + white
   checkmark when checked. Native control hidden via appearance:none. */
.data-table input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  margin: 0;
  border-radius: 3px;
  border: 1px solid #8c8c94;
  background: #fff;
  cursor: pointer;
  position: relative;
  flex-shrink: 0;
}

/* Glyphs are the exact <polyline> shapes cloudscape.design's own checkbox
   SVG draws in its 16x16 viewBox (points="3.5,8 7,11 12,4" checked;
   "3.5,8 12.5,8" indeterminate) — reproduced as a background-image so they
   paint from the input's border-box (its full visible 16x16 footprint),
   the same coordinate space Cloudscape's own SVG uses, rather than the
   14x14 content-box a ::after pseudo-element would be confined to. That
   mismatch was the root cause of the checkmark looking oversized and
   vertically off-center. */
.data-table input[type="checkbox"]:checked {
  background: var(--color-blue)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpolyline points='3.5,8 7,11 12,4' fill='none' stroke='white' stroke-width='2'/%3E%3C/svg%3E")
    no-repeat center / 16px 16px;
  border-color: var(--color-blue);
}

/* Header "select all" checkbox when some but not all rows are selected —
   set via JS (input.indeterminate = true), matching the live Cloudscape
   table's minus-glyph treatment instead of an empty or fully-checked box. */
.data-table input[type="checkbox"]:indeterminate {
  background: var(--color-blue)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpolyline points='3.5,8 12.5,8' fill='none' stroke='white' stroke-width='2'/%3E%3C/svg%3E")
    no-repeat center / 16px 16px;
  border-color: var(--color-blue);
}

.data-table input[type="radio"] {
  width: 16px;
  height: 16px;
  accent-color: var(--color-blue);
  cursor: pointer;
  flex-shrink: 0;
}

.data-table .empty-row td {
  text-align: center;
  padding: var(--space-xxl) var(--space-m);
}

.empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-m);
  color: var(--color-text-body-secondary);
}

/* status badges */

.status {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 14px;
}

.status svg {
  flex-shrink: 0;
}

.status--pending {
  color: var(--color-grey-text);
}

.status--accepted {
  color: var(--color-green);
}

.status--expired {
  color: var(--color-amber-text);
}

.status--live {
  color: var(--color-green);
}

.status--notlive {
  color: var(--color-grey-text);
}

.status--processing {
  color: var(--color-text-body-secondary);
}

.status--completed {
  color: var(--color-green);
}

.status--error {
  color: var(--color-red);
}

.status--cancelled {
  color: var(--color-grey-text);
}

.status--inprogress {
  color: var(--color-grey-text);
}

.status--succeeded {
  color: var(--color-green);
}

/* ---- Badge (verified against cloudscape.design/components/badge/?example=blue
   via computed style: rgb(0,108,224) fill — same value as --color-blue —
   4px radius (not a pill), 12px/400 text, "0 8px" padding, 20px line-height). ---- */
/* Standardized to a fixed 22px height with flex-centered text — the
   previous line-height-only sizing rendered 20px for the solid .badge--pmp
   variant but 24px for .badge--outline (its 2px border added on top of
   line-height, since border wasn't included in the sizing), and neither
   was actually vertically centering its text within that height. */
.badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  height: 22px;
  padding: 0 8px;
  border-radius: 4px;
  font-size: 12px;
  font-weight: 400;
  line-height: 1;
  color: var(--color-text-inverted);
}

/* PMP's own brand color for the "Approved for purchase" badge — not one of
   Cloudscape's stock badge colors, so it's applied the same way as
   cloudscape.design/components/badge/?example=with-custom-style: same
   structural Badge shape/type as .badge, just a custom fill. */
.badge--pmp {
  background: #3759ce;
}

/* "Free trial" badge — verified via computed style against a live AWS
   Marketplace search result card: white fill, 2px solid teal border,
   dark (near-black) text, 6px radius — a transparent/outline Badge
   variant, distinct from .badge--pmp's solid fill. */
.badge--outline {
  background: #fff;
  border: 2px solid #2ea597;
  border-radius: 6px;
  color: var(--color-text-heading);
}

/* ---- Collapsible card: Cloudscape's ExpandableSection, variant="container"
   (cloudscape.design/components/expandable-section/?example=container-with-interactive-header-elements),
   verified via computed style — no divider between header and body in this
   variant (unlike a plain .container + border-bottom split), 20px/700
   heading, 20px icon. A .container is the outer chrome (border+radius
   already match Cloudscape's root exactly), toggled via the shared
   data-collapsible/data-collapse-toggle wiring in app.js's initCollapsibles(). ---- */
.collapsible-card__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-s);
  padding: var(--space-m) var(--space-l);
  cursor: pointer;
  user-select: none;
}

.collapsible-card__header-left {
  display: flex;
  align-items: center;
  gap: 8px;
}

.collapsible-card__header-left svg {
  width: 20px;
  height: 20px;
  transition: transform 0.15s ease;
  flex-shrink: 0;
}

.collapsible-card.collapsed .collapsible-card__header-left svg {
  transform: rotate(-90deg);
}

.collapsible-card__header-left h2 {
  font-size: 20px;
  font-weight: 700;
  margin: 0;
  color: var(--color-text-heading);
}

.collapsible-card.collapsed .collapsible-card__body {
  display: none;
}

.collapsible-card__body {
  padding: 4px 20px 20px;
  font-size: 14px;
  line-height: 1.6;
  color: var(--color-text-body);
}

.collapsible-card__body p {
  margin: 0;
}

.spin {
  animation: spin 1.2s linear infinite;
}

@keyframes spin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

/* ============ FLASHBAR / ALERT ============ */

.flashbar {
  margin-bottom: var(--space-m);
}

/* No flash showing: the div is still in the layout (so a flash can be
   prepended into it later) but shouldn't reserve its margin — otherwise
   every page shows a dead gap between the breadcrumbs and the page header. */
.flashbar:empty {
  margin-bottom: 0;
}

/* Verified against cloudscape.design/components/flashbar/: 12px radius,
   "8px 16px" padding, white icon/text on info/success/error, but dark
   text+icon on the yellow warning variant for contrast. */
.flash {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: 8px 16px;
  border-radius: 12px;
  color: #f9f9fa;
  font-size: 14px;
  margin-bottom: var(--space-s);
  min-height: 32px;
}

.flash svg {
  flex-shrink: 0;
}

.flash__content {
  flex: 1;
}

.flash__action {
  height: 32px;
  padding: 0 20px;
  border-radius: var(--radius-button);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  background: transparent;
  border: 2px solid currentColor;
  color: inherit;
  flex-shrink: 0;
  white-space: nowrap;
}

.flash__action:hover {
  background: rgba(255, 255, 255, 0.15);
}

.flash__dismiss {
  background: none;
  border: none;
  color: inherit;
  cursor: pointer;
  opacity: 0.85;
  flex-shrink: 0;
  display: flex;
}

.flash__dismiss:hover {
  opacity: 1;
}

.flash--info {
  background: var(--color-blue);
}

.flash--success {
  background: var(--color-green);
}

.flash--error {
  background: var(--color-red);
}

.flash--warning {
  background: #ffe347;
  color: #0f141a;
}

.flash--in-progress {
  background: var(--color-blue);
}

/* ============ HELP PANEL (right side drawer) ============ */

.help-panel-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 20, 26, 0.3);
  z-index: 200;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.help-panel-overlay.open {
  opacity: 1;
  pointer-events: auto;
}

.help-panel {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  width: 360px;
  background: var(--color-bg-container);
  box-shadow: -4px 0 20px rgba(15, 20, 26, 0.2);
  z-index: 201;
  transform: translateX(100%);
  transition: transform 0.2s ease;
  display: flex;
  flex-direction: column;
}

.help-panel.open {
  transform: translateX(0);
}

.help-panel__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-l);
  border-bottom: 1px solid var(--color-border-divider);
}

.help-panel__header h2 {
  font-size: 18px;
  margin: 0;
  color: var(--color-text-heading);
}

.help-panel__close {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-body-secondary);
  padding: 4px;
  border-radius: 4px;
}

.help-panel__close:hover {
  background: var(--color-bg-layout);
}

.help-panel__body {
  padding: var(--space-l);
  overflow-y: auto;
  font-size: 14px;
  line-height: 1.6;
  color: var(--color-text-body);
}

.help-panel__body h3 {
  font-size: 14px;
  color: var(--color-text-heading);
  margin: var(--space-l) 0 var(--space-xs);
}

.help-panel__body h3:first-child {
  margin-top: 0;
}

.help-panel__body ul {
  margin: 0 0 var(--space-m);
  padding-left: 18px;
}

.help-panel__body li {
  margin-bottom: 6px;
}

.help-panel__links {
  margin-top: var(--space-l);
  padding-top: var(--space-l);
  border-top: 1px solid var(--color-border-divider);
}

.help-panel__links h3 {
  margin-top: 0;
}

.help-panel__links a {
  display: block;
  margin-bottom: var(--space-xs);
}

/* ============ FOOTER ============ */

.app-footer {
  background: var(--color-bg-header);
  color: var(--color-text-inverted-secondary);
  font-size: 12px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-s) var(--space-xl);
}

.app-footer a {
  color: var(--color-text-inverted-secondary);
  margin-left: var(--space-m);
}

.app-footer a:hover {
  color: #fff;
}

/* Truncated cell text */
.truncate {
  max-width: 260px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  display: inline-block;
  vertical-align: bottom;
}

@media (max-width: 900px) {
  .side-nav {
    display: none;
  }
  .creation-steps__body {
    flex-direction: column;
  }
  .creation-steps__arrow {
    transform: rotate(90deg);
    margin: 0;
  }
}

/* ============ PRIVATE MARKETPLACE ADDITIONS ============ */

/* Verified against cloudscape.design/patterns/general/service-navigation/
   side-navigation/#nesting-with-expandable-link-groups: only items NESTED
   under an expandable group indent (handled by plain .side-nav__items
   above); top-level flat items sit flush with the nav title and section
   headers — no extra indent. */
.side-nav__items--flat {
  padding: 0;
}

/* ---- Page header with action buttons ---- */

.page-header-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-m);
  margin-bottom: 4px;
}

.page-header-row .page-header {
  margin-bottom: 0;
}

.page-header__actions {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  flex-shrink: 0;
}

.page-subtitle {
  font-size: 14px;
  color: var(--color-text-body-secondary);
  margin: 0 0 var(--space-l);
  max-width: 900px;
}

/* ---- Governance / info card (label-value grid inside a bordered container) ---- */

.info-card {
  padding: var(--space-l);
}

.info-card__header {
  display: flex;
  align-items: baseline;
  gap: var(--space-s);
  margin-bottom: var(--space-m);
}

.info-card__header h2 {
  font-size: 18px;
  font-weight: 700;
  margin: 0;
  color: var(--color-text-heading);
}

.info-card__grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-l) var(--space-xxl);
}

/* An alternative to .info-card__grid for cards whose fields group into
   independent vertical stacks side by side (e.g. Change set details:
   Status+ID, ARN alone, Start+End time, Error code+description) rather
   than a single left-to-right/top-to-bottom grid — each .info-card__column
   is its own <dl>, so a long-wrapping value in one column never shoves
   fields in the next column out of alignment. */
.info-card__columns {
  display: flex;
}

.info-card__column {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
}

/* A divider between columns instead of a plain flex gap — matches the
   design's vertical rules separating each key-value group. 16px on
   each side of the line (not 32px hugging one side of it, which is what
   this looked like before) keeps the same ~32px total distance between
   columns as the plain .info-card__grid's own column gap, but centers
   the divider in that gap instead of crowding it against whichever
   column's text happens to be on the left. Divider itself goes on the
   left of every column but the first (rather than the right of every
   column but the last) so that hiding the actual last column — e.g.
   Change set details' error column when there's no error — never
   leaves a dangling divider trailing off into empty space;
   :not(:first-child) only cares about what's before it. */
.info-card__column:not(:last-child) {
  padding-right: var(--space-m);
}

.info-card__column:not(:first-child) {
  padding-left: var(--space-m);
  border-left: 1px solid var(--color-border-divider);
}

.info-card__field dt {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-heading);
  margin-bottom: 4px;
}

.info-card__field dd {
  font-size: 14px;
  color: var(--color-text-body);
  margin: 0;
}

/* Verified against cloudscape.design/components/link/?example=external-link:
   the Link component is always underlined (not just on hover, which is all
   the site's default `a` gets), and its trailing icon is glued to the last
   word with a non-breaking space so the two never split across a line wrap.
   .link is the general-purpose class for any prose anchor that should read
   as a real Cloudscape Link rather than a plain in-page navigation link;
   .info-card__field dd a covers the key-value-pair case specifically. */
.info-card__field dd a,
.link {
  text-decoration: underline;
}

/* ---- Org structure tree table ---- */

.tree-cell {
  display: flex;
  align-items: center;
  gap: 6px;
}

.tree-toggle {
  width: 16px;
  height: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-body-secondary);
  flex-shrink: 0;
  transition: transform 0.15s ease;
}

.tree-toggle.expanded {
  transform: rotate(90deg);
}

/* Icons.triangleDown (the same filled, rounded-corner triangle used in
   the left nav's expandable groups) points down by default, unlike the
   plain chevron .tree-toggle otherwise uses which points right by
   default — so this variant needs the opposite rotation logic: rotated
   -90deg (pointing right) when collapsed, and back to its natural
   down-pointing orientation when expanded. */
.tree-toggle--triangle {
  transform: rotate(-90deg);
}

.tree-toggle--triangle.expanded {
  transform: rotate(0deg);
}

.tree-toggle-spacer {
  width: 16px;
  flex-shrink: 0;
}

.tree-icon {
  color: var(--color-text-body-secondary);
  flex-shrink: 0;
}

.tree-row-hidden {
  display: none;
}

/* ---- Radio-tile selector (e.g. "Add products separately" / "Bulk add") ---- */

.radio-tile-group {
  display: flex;
  gap: var(--space-m);
}

.radio-tile {
  flex: 1;
  display: flex;
  align-items: flex-start;
  gap: var(--space-s);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-input);
  padding: var(--space-m);
  cursor: pointer;
}

.radio-tile input[type="radio"] {
  margin-top: 2px;
  accent-color: var(--color-blue);
  width: 16px;
  height: 16px;
  flex-shrink: 0;
}

.radio-tile__title {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-heading);
  margin-bottom: 2px;
}

.radio-tile__desc {
  font-size: 14px;
  color: var(--color-text-body-secondary);
}

.radio-tile.selected {
  border: 2px solid var(--color-blue);
  padding: calc(var(--space-m) - 1px);
  background: var(--color-blue-tint);
}

/* ---- Form fields ---- */

.form-field {
  margin-bottom: var(--space-l);
}

.form-field:last-child {
  margin-bottom: 0;
}

/* :not(.form-radio) — otherwise this descendant selector's specificity
   (class + type) beats .form-radio's own rules (class only) and silently
   forces every radio option's label to this block/bold/heading-color
   styling instead of its own flex/400-weight/body-color one. */
.form-field label:not(.form-radio) {
  display: block;
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-heading);
  margin-bottom: 2px;
}

.form-field__hint {
  font-size: 14px;
  color: var(--color-text-body-secondary);
  margin: 0 0 6px;
}

.form-field__help {
  font-size: 14px;
  color: var(--color-text-body-secondary);
  margin: 6px 0 0;
}

.form-field input[type="text"],
.form-field input[type="email"],
.form-field textarea {
  width: 100%;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-input);
  padding: 6px var(--space-s);
  font-size: 14px;
  font-family: inherit;
  color: var(--color-text-body);
  background: var(--color-bg-input);
}

.form-field input[type="text"]:focus,
.form-field input[type="email"]:focus,
.form-field textarea:focus {
  outline: 2px solid var(--color-blue);
  outline-offset: -1px;
}

.form-field textarea {
  min-height: 72px;
  resize: vertical;
}

.form-radio-group {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.form-radio {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 400;
  color: var(--color-text-body);
  cursor: pointer;
}

.form-radio input[type="radio"] {
  width: 16px;
  height: 16px;
  accent-color: var(--color-blue);
}

.form-field-row {
  display: flex;
  gap: var(--space-l);
}

.form-field-row .form-field {
  flex: 1;
}

/* ---- Wizard shell ---- */

.wizard-layout {
  display: flex;
  gap: var(--space-xxl);
  align-items: flex-start;
}

.wizard-nav {
  width: 220px;
  flex-shrink: 0;
}

/* Verified against cloudscape.design/examples/react/wizard.html: each step
   is a flex row of [rail: dot + connector] and [text: "Step N" + title].
   The rail is itself a flex column stretched (by the row's default
   align-items:stretch) to the text column's natural height, so its
   flex:1 connector always fills exactly to the next dot — whether the
   title wraps to 1 line or 2 — without any manual height math. */
.wizard-nav__step {
  display: flex;
}

.wizard-nav__rail {
  width: 10px;
  margin-right: 12px;
  display: flex;
  flex-direction: column;
  align-items: center;
  flex-shrink: 0;
}

.wizard-nav__circle {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
  background: #fff;
  box-shadow: 0 0 0 2px var(--color-text-disabled), 0 0 0 4px var(--color-bg-container);
}

.wizard-nav__step.complete .wizard-nav__circle {
  background: var(--color-text-body-secondary);
  box-shadow: 0 0 0 2px var(--color-text-body-secondary), 0 0 0 4px var(--color-bg-container);
}

.wizard-nav__step.active .wizard-nav__circle {
  background: var(--color-blue);
  box-shadow: 0 0 0 3px var(--color-bg-container), 0 0 0 5px var(--color-blue), 0 0 0 7px var(--color-bg-container);
}

/* 10px, not 7px: the active step's circle has a box-shadow halo that
   extends 7px beyond its own edge (vs. 4px for complete/incomplete
   steps) — at a 7px margin that halo touched the connector with zero
   clearance, while other steps kept a visible 3px gap, making the active
   step look more cramped. 10px gives complete/incomplete steps a uniform
   6px of clear space (10 - 4px halo). */
.wizard-nav__connector {
  width: 2px;
  flex: 1;
  background: var(--color-border-strong);
  margin: 10px 0;
}

/* The connector directly below the active circle needs a taller top
   margin to clear that circle's larger 7px halo by the same 6px as
   everywhere else (13 - 7px halo = 6px, matching 10 - 4px above). */
.wizard-nav__step.active .wizard-nav__connector {
  margin-top: 13px;
}

.wizard-nav__text {
  padding-bottom: 16px;
}

.wizard-nav__label {
  font-size: 12px;
  color: var(--color-text-body-tertiary);
}

.wizard-nav__title {
  font-size: 14px;
  font-weight: 400;
  color: var(--color-text-body-tertiary);
  margin-top: 2px;
}

.wizard-nav__step.complete .wizard-nav__title {
  color: var(--color-text-body-secondary);
}

.wizard-nav__step.active .wizard-nav__title {
  color: var(--color-blue);
  font-weight: 700;
}

.wizard-content {
  flex: 1;
  min-width: 0;
}

.wizard-panel {
  display: none;
}

.wizard-panel.active {
  display: block;
}

.wizard-footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-m);
  margin-top: var(--space-l);
}

.link-btn {
  background: none;
  border: none;
  color: var(--color-text-link);
  font-size: 14px;
  font-weight: 700;
  cursor: pointer;
  padding: 4px 0;
}

.link-btn:hover {
  text-decoration: underline;
}

/* ---- Review step (read-only summary) ---- */

.review-section {
  margin-bottom: var(--space-l);
}

.review-section__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--space-s);
}

.review-section__header h3 {
  font-size: 16px;
  font-weight: 700;
  margin: 0;
  color: var(--color-text-heading);
}

.review-card {
  padding: var(--space-m) var(--space-l);
  margin-bottom: var(--space-s);
}

.review-card dt {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-heading);
  margin-bottom: 2px;
}

.review-card dd {
  font-size: 14px;
  color: var(--color-text-body);
  margin: 0 0 var(--space-s);
}

.review-card dd:last-child {
  margin-bottom: 0;
}

/* ---- Inline validation alert (verified against
   cloudscape.design/components/alert/?example=error: 2px solid #db0000
   border, #fff5f5 fill, 12px radius, red icon, near-black body text) ---- */

.inline-alert {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  padding: 8px var(--space-m);
  border-radius: 12px;
  font-size: 14px;
  color: var(--color-text-body);
  margin-top: var(--space-m);
}

.inline-alert svg {
  flex-shrink: 0;
}

.inline-alert--error {
  background: var(--color-red-tint);
  border: 2px solid var(--color-red);
}

.inline-alert--error svg {
  color: var(--color-red);
}

.inline-alert--warning {
  background: var(--color-amber-tint);
  border: 2px solid var(--color-amber-icon);
}

.inline-alert--warning svg {
  color: var(--color-amber-icon);
}

/* ---- Toggle switch (e.g. table preferences column visibility) ---- */

.toggle-switch {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--color-text-body);
  cursor: pointer;
  user-select: none;
}

.toggle-switch input {
  display: none;
}

.toggle-switch__track {
  width: 34px;
  height: 18px;
  border-radius: 999px;
  background: var(--color-border-strong);
  position: relative;
  transition: background 0.15s ease;
  flex-shrink: 0;
}

.toggle-switch__track::after {
  content: "";
  position: absolute;
  top: 2px;
  left: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: #fff;
  transition: transform 0.15s ease;
}

.toggle-switch input:checked + .toggle-switch__track {
  background: var(--color-blue);
}

.toggle-switch input:checked + .toggle-switch__track::after {
  transform: translateX(16px);
}

/* ---- Table preferences modal (cloudscape.design/components/collection-preferences/) ---- */

.modal-overlay {
  position: fixed;
  inset: 0;
  background: rgba(15, 20, 26, 0.3);
  z-index: 300;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.2s ease;
}

.modal-overlay.open {
  opacity: 1;
  pointer-events: auto;
}

.prefs-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.97);
  width: 820px;
  max-width: calc(100vw - 40px);
  max-height: calc(100vh - 40px);
  background: var(--color-bg-container);
  border-radius: 12px;
  box-shadow: 0 8px 40px rgba(15, 20, 26, 0.3);
  z-index: 301;
  display: flex;
  flex-direction: column;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.prefs-modal.open {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}

.prefs-modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-l);
  border-bottom: 1px solid var(--color-border-divider);
  flex-shrink: 0;
}

.prefs-modal__header h2 {
  font-size: 20px;
  margin: 0;
  color: var(--color-text-heading);
}

.prefs-modal__body {
  display: flex;
  gap: var(--space-xxl);
  padding: var(--space-l);
  overflow-y: auto;
}

.prefs-modal__col {
  flex: 1;
  min-width: 0;
}

.prefs-modal__col h3 {
  font-size: 16px;
  margin: 0 0 var(--space-m);
  color: var(--color-text-heading);
}

.prefs-modal__hint {
  font-size: 12px;
  color: var(--color-text-body-secondary);
  margin: -8px 0 var(--space-s);
}

.prefs-modal__divider {
  width: 1px;
  background: var(--color-border-divider);
  flex-shrink: 0;
}

.prefs-checkbox {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  margin-top: var(--space-m);
  cursor: pointer;
}

.prefs-checkbox input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  margin: 1px 0 0;
  border-radius: 3px;
  border: 1px solid #8c8c94;
  background: #fff;
  cursor: pointer;
  position: relative;
  flex-shrink: 0;
}

.prefs-checkbox input[type="checkbox"]:checked {
  background: var(--color-blue)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpolyline points='3.5,8 7,11 12,4' fill='none' stroke='white' stroke-width='2'/%3E%3C/svg%3E")
    no-repeat center / 16px 16px;
  border-color: var(--color-blue);
}

.prefs-checkbox__title {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-heading);
}

.prefs-checkbox__desc {
  font-size: 12px;
  color: var(--color-text-body-secondary);
  margin-top: 2px;
}

/* ---- Checkbox group with labels and descriptions: styled like Cloudscape's
   RadioGroup "with labels and descriptions" example, but with checkboxes in
   place of radio buttons (cloudscape.design/components/radio-group/?example=with-labels-and-descriptions,
   verified via computed style — 14px/400 label, NOT bold like .prefs-checkbox's
   title, 12px/400 tertiary-color description, 8px vertical gap between
   items). Reuses .prefs-checkbox's own checkbox square/check-fill styling,
   since that was already verified separately against Cloudscape's Checkbox
   component. ---- */
.checkbox-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.checkbox-item {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  cursor: pointer;
}

.checkbox-item input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  margin: 2px 0 0;
  border-radius: 3px;
  border: 1px solid #8c8c94;
  background: #fff;
  cursor: pointer;
  position: relative;
  flex-shrink: 0;
}

.checkbox-item input[type="checkbox"]:checked {
  background: var(--color-blue)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpolyline points='3.5,8 7,11 12,4' fill='none' stroke='white' stroke-width='2'/%3E%3C/svg%3E")
    no-repeat center / 16px 16px;
  border-color: var(--color-blue);
}

.checkbox-item__label {
  font-size: 14px;
  font-weight: 400;
  color: var(--color-text-heading);
}

.checkbox-item__desc {
  font-size: 12px;
  color: var(--color-text-body-tertiary);
  margin-top: 0;
}

.prefs-col-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 10px 0;
  border-bottom: 1px solid var(--color-border-divider);
  font-size: 14px;
  color: var(--color-text-body);
}

.prefs-col-row__handle {
  color: var(--color-text-body-tertiary);
  cursor: grab;
  flex-shrink: 0;
  display: flex;
}

.prefs-col-row__label {
  flex: 1;
}

.prefs-modal__footer {
  display: flex;
  justify-content: flex-end;
  gap: var(--space-m);
  padding: var(--space-l);
  border-top: 1px solid var(--color-border-divider);
  flex-shrink: 0;
}

/* ---- Table preference modifiers, applied by the preferences modal ---- */

.data-table.wrap-lines td {
  white-space: normal;
}

.data-table.striped tbody tr:not(.selected):nth-child(even) {
  background: var(--color-bg-layout);
}

.data-table.compact th,
.data-table.compact td {
  padding-top: 4px;
  padding-bottom: 4px;
}

.data-table.hide-col-1 > thead > tr > :nth-child(1),
.data-table.hide-col-1 > tbody > tr > :nth-child(1) { display: none; }
.data-table.hide-col-2 > thead > tr > :nth-child(2),
.data-table.hide-col-2 > tbody > tr > :nth-child(2) { display: none; }
.data-table.hide-col-3 > thead > tr > :nth-child(3),
.data-table.hide-col-3 > tbody > tr > :nth-child(3) { display: none; }
.data-table.hide-col-4 > thead > tr > :nth-child(4),
.data-table.hide-col-4 > tbody > tr > :nth-child(4) { display: none; }
.data-table.hide-col-5 > thead > tr > :nth-child(5),
.data-table.hide-col-5 > tbody > tr > :nth-child(5) { display: none; }
.data-table.hide-col-6 > thead > tr > :nth-child(6),
.data-table.hide-col-6 > tbody > tr > :nth-child(6) { display: none; }

/* ============ PRIVATE MARKETPLACE HOMEPAGE (hero header) ============
   Verified against cloudscape.design/patterns/general/hero-header/ and its
   product-detail-page demo: the breadcrumb toolbar stays in its normal
   light styling (Cloudscape never darkens the global toolbar/breadcrumb
   bar itself) and only the hero block below it goes dark; the white "Get
   started" panel is the pattern's "Secondary header" block, which per the
   spec "is always displayed in a light visual context, independent of the
   styling of the main header" — i.e. never dark, even though it sits on
   the dark hero. */

.hero {
  background: var(--color-text-heading);
  padding: var(--space-xxl) var(--space-xxl) 48px;
  display: flex;
  gap: var(--space-xxl);
  align-items: flex-start;
  flex-wrap: wrap;
}

.hero__main {
  flex: 1 1 480px;
  min-width: 0;
}

.hero__heading,
.hero__subheading {
  font-size: 40px;
  line-height: 1.2;
  margin: 0;
  color: var(--color-text-hero-heading);
}

.hero__heading {
  font-weight: 700;
}

.hero__subheading {
  font-weight: 300;
  margin-bottom: var(--space-l);
}

.hero__description {
  font-size: 16px;
  line-height: 1.6;
  color: var(--color-text-hero-body);
  max-width: 640px;
}

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

.hero__secondary {
  flex: 0 0 320px;
  background: var(--color-bg-container);
  border-radius: 16px;
  padding: var(--space-l);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.3);
}

.hero__secondary h2 {
  font-size: 18px;
  margin: 0 0 var(--space-xs);
  color: var(--color-text-heading);
}

.hero__secondary p {
  font-size: 14px;
  color: var(--color-text-body-secondary);
  line-height: 1.5;
  margin: 0 0 var(--space-m);
}

.pmp-home {
  display: flex;
  gap: var(--space-xxl);
  align-items: flex-start;
  padding: var(--space-xxl);
}

.pmp-home__main {
  flex: 1 1 600px;
  min-width: 0;
}

.pmp-home__side {
  flex: 0 0 320px;
  display: flex;
  flex-direction: column;
  gap: var(--space-l);
}

.pmp-home__side .container {
  padding: var(--space-l);
}

.pmp-home__side h2 {
  font-size: 16px;
  margin: 0 0 var(--space-s);
  color: var(--color-text-heading);
}

.pmp-home__side ul {
  margin: 0;
  padding: 0;
  list-style: none;
}

.pmp-home__side li {
  margin-bottom: var(--space-xs);
}

.pmp-home__side li:last-child {
  margin-bottom: 0;
}

.pmp-home-section {
  margin-bottom: 40px;
}

.pmp-home-section:last-child {
  margin-bottom: 0;
}

.pmp-home-section h2 {
  font-size: 24px;
  font-weight: 700;
  margin: 0 0 var(--space-m);
  color: var(--color-text-heading);
}

.pmp-home-section p {
  font-size: 14px;
  color: var(--color-text-body);
  line-height: 1.6;
  max-width: 760px;
}

.pmp-home-section .container {
  padding: var(--space-l) var(--space-xxl);
}

.pmp-home-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-l) var(--space-xxl);
}

.pmp-home-grid h3 {
  font-size: 16px;
  font-weight: 700;
  margin: 0 0 4px;
  color: var(--color-text-heading);
}

.pmp-home-grid p {
  font-size: 14px;
  color: var(--color-text-body-secondary);
  line-height: 1.5;
  margin: 0;
  max-width: none;
}

.pmp-video-thumb {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  aspect-ratio: 16 / 9;
  background: var(--color-text-heading);
  border-radius: var(--radius-input);
  color: #fff;
  cursor: pointer;
  border: none;
  padding: 0;
  font: inherit;
}

.pmp-video-caption {
  font-size: 13px;
  color: var(--color-text-body-secondary);
  margin: var(--space-xs) 0 0;
}

.pmp-diagram {
  padding: var(--space-l);
}

.pmp-quote {
  font-size: 14px;
  font-style: italic;
  color: var(--color-text-body);
  line-height: 1.6;
  margin: 0 0 var(--space-m);
}

.pmp-quote-name {
  font-size: 13px;
  font-weight: 700;
  color: var(--color-text-heading);
}

.pmp-quote-title {
  font-size: 13px;
  color: var(--color-text-body-secondary);
}

@media (max-width: 900px) {
  .hero,
  .pmp-home {
    flex-direction: column;
  }
  .hero__secondary,
  .pmp-home__side {
    flex: 1 1 auto;
    width: 100%;
  }
}

/* ============ EXPERIENCE / CHANGE SET DETAIL PAGES ============ */

/* An .info-card__header with a trailing action button (e.g. "Edit")
   pushed to the far right, instead of the plain h2+info-link layout. */
.info-card__header--actions {
  justify-content: space-between;
}

/* ---- Destructive-action confirm modal (Archive experience, etc.) ----
   Reuses .modal-overlay; sized narrower than .prefs-modal to match
   Cloudscape's own confirm-dialog proportions. */
.confirm-modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%) scale(0.97);
  width: 600px;
  max-width: calc(100vw - 40px);
  max-height: calc(100vh - 40px);
  background: var(--color-bg-container);
  border-radius: 12px;
  box-shadow: 0 8px 40px rgba(15, 20, 26, 0.3);
  z-index: 301;
  display: flex;
  flex-direction: column;
  opacity: 0;
  pointer-events: none;
  transition: opacity 0.15s ease, transform 0.15s ease;
}

.confirm-modal.open {
  opacity: 1;
  pointer-events: auto;
  transform: translate(-50%, -50%) scale(1);
}

.confirm-modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-l);
  border-bottom: 1px solid var(--color-border-divider);
  flex-shrink: 0;
}

.confirm-modal__header h2 {
  font-size: 20px;
  margin: 0;
  color: var(--color-text-heading);
}

.confirm-modal__close {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-body-secondary);
  display: flex;
  padding: 4px;
  border-radius: 4px;
}

.confirm-modal__close:hover {
  background: var(--color-bg-layout);
}

.confirm-modal__body {
  padding: var(--space-l);
  overflow-y: auto;
}

.confirm-modal__body p {
  margin: 0 0 var(--space-m);
}

.confirm-modal__body label {
  display: block;
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-heading);
  margin-bottom: 8px;
}

.confirm-modal__footer {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--space-m);
  padding: var(--space-l);
  border-top: 1px solid var(--color-border-divider);
  flex-shrink: 0;
}

/* ---- ARN / ID row with a copy-to-clipboard button ---- */
.copy-row {
  display: flex;
  align-items: flex-start;
  gap: 6px;
}

.copy-row__text {
  word-break: break-all;
}

.copy-btn {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-link);
  display: flex;
  padding: 2px;
  border-radius: 4px;
  flex-shrink: 0;
}

.copy-btn:hover {
  background: var(--color-bg-layout);
}

/* ---- JSON/code viewer (Change details) ---- */
.code-block {
  background: var(--color-bg-layout);
  border: 1px solid var(--color-border-divider);
  border-radius: var(--radius-input);
  padding: var(--space-m);
  font-family: "SFMono-Regular", Consolas, "Liberation Mono", Menlo, monospace;
  font-size: 13px;
  line-height: 1.6;
  color: var(--color-text-body);
  white-space: pre-wrap;
  word-break: break-word;
  overflow-x: auto;
}

/* ============ DISCOVER PRODUCTS ============ */

.discover-layout {
  display: flex;
  gap: 20px;
  align-items: flex-start;
  max-width: 1050px;
  margin: 0 auto;
}

.refine-panel {
  width: 275px;
  flex-shrink: 0;
  padding-bottom: var(--space-s);
}

.refine-panel__header {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: var(--space-m) var(--space-l);
  cursor: pointer;
  user-select: none;
  border-bottom: 1px solid var(--color-border-divider);
}

.refine-panel.collapsed .refine-panel__header {
  border-bottom: none;
}

.refine-panel__header svg {
  transition: transform 0.15s ease;
  flex-shrink: 0;
}

.refine-panel.collapsed .refine-panel__header svg {
  transform: rotate(-90deg);
}

.refine-panel__header h2 {
  font-size: 18px;
  font-weight: 700;
  margin: 0;
  color: var(--color-text-heading);
}

.refine-panel.collapsed .refine-panel__body {
  display: none;
}

.refine-panel__body {
  padding: var(--space-m) var(--space-l) 0;
}

.refine-panel__clear-all {
  display: inline-block;
  margin-bottom: var(--space-m);
}

.filter-group {
  border-top: 1px solid var(--color-border-divider);
  padding: var(--space-s) 0;
}

.filter-group__header {
  display: flex;
  align-items: center;
  gap: 6px;
  width: 100%;
  background: none;
  border: none;
  cursor: pointer;
  padding: 4px 0;
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-heading);
  text-align: left;
}

.filter-group__header svg {
  transition: transform 0.15s ease;
  flex-shrink: 0;
  color: var(--color-text-body-secondary);
}

.filter-group.collapsed .filter-group__header svg {
  transform: rotate(-90deg);
}

.filter-group.collapsed .filter-group__body {
  display: none;
}

.filter-group__body {
  padding-top: 4px;
}

.filter-group__clear {
  display: inline-block;
  margin-bottom: 6px;
}

.filter-link-list,
.filter-checkbox-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.filter-link-list a {
  font-size: 14px;
  text-decoration: none;
}

.filter-link-list a:hover {
  text-decoration: underline;
}

.filter-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  color: var(--color-text-body);
  cursor: pointer;
}

.filter-checkbox input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 16px;
  height: 16px;
  margin: 0;
  border-radius: 3px;
  border: 1px solid #8c8c94;
  background: #fff;
  cursor: pointer;
  position: relative;
  flex-shrink: 0;
}

.filter-checkbox input[type="checkbox"]:checked {
  background: var(--color-blue)
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpolyline points='3.5,8 7,11 12,4' fill='none' stroke='white' stroke-width='2'/%3E%3C/svg%3E")
    no-repeat center / 16px 16px;
  border-color: var(--color-blue);
}

.filter-group__nested {
  margin: 4px 0 0 24px;
  padding-top: 4px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.filter-group__show-all {
  margin-top: 4px;
}

.filter-rating-list {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.filter-rating {
  display: flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  padding: 0;
  cursor: pointer;
  font-size: 14px;
  color: var(--color-text-link);
}

.filter-rating svg {
  color: #ff9900;
}

/* ---- Results panel ---- */

.discover-results {
  flex: 1;
  min-width: 0;
  max-width: 755px;
}

.discover-results__panel {
  padding: var(--space-xl) 0;
}

.discover-results h1 {
  font-size: 24px;
  margin: 0 var(--space-xxl) var(--space-m);
  color: var(--color-text-heading);
}

.discover-results .search-input {
  height: 40px;
  margin: 0 var(--space-xxl) var(--space-l);
}

.discover-results .search-input input::placeholder {
  font-style: italic;
}

.discover-results__toolbar {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin: 0 var(--space-xxl) var(--space-l);
}

.discover-results__toolbar-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.discover-results__count {
  font-size: 14px;
  color: var(--color-text-body);
}

.discover-results__count span {
  color: var(--color-text-body-secondary);
}

.sort-dropdown-trigger {
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--color-bg-container);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-input);
  padding: 6px var(--space-s);
  font-size: 14px;
  color: var(--color-text-body);
  cursor: pointer;
}

.product-list {
  display: flex;
  flex-direction: column;
  border-top: 1px solid var(--color-border-divider);
  margin: 0 60px;
}

.product-card {
  display: flex;
  gap: var(--space-m);
  padding: var(--space-l) 0;
  border-bottom: 1px solid var(--color-border-divider);
}

.product-card:last-child {
  border-bottom: none;
}

.product-card__icon {
  width: 64px;
  height: 64px;
  flex-shrink: 0;
  border-radius: var(--radius-input);
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
  font-weight: 700;
  font-size: 22px;
}

.product-card__content {
  flex: 1;
  min-width: 0;
}

.product-card__title {
  font-size: 16px;
  font-weight: 700;
  color: var(--color-text-link);
  text-decoration: underline;
}

.product-card__meta {
  font-size: 14px;
  color: var(--color-text-body-secondary);
  margin: 4px 0 8px;
}

.product-card__meta a {
  text-decoration: underline;
}

.product-card__badges {
  display: flex;
  gap: var(--space-xs);
}

.product-card__desc {
  font-size: 14px;
  color: var(--color-text-body);
  line-height: 1.5;
  margin: 8px 0 0;
}

/* ============ PRODUCT DETAIL PAGE ============ */

.pdp-page {
  max-width: 1040px;
  margin: 0 auto;
}

/* The header and the tabs strip below it read as one seamless plane — no
   divider between them — with a soft shadow cast onto the scrollable
   content below, so that content reads as sitting on a lower plane. */
/* Full-bleed: cancels .main-content's own 20px side padding so this plane
   spans the entire content-area width, while .pdp-header-block__inner
   re-applies that 20px as padding and caps/centers the actual header
   content at 1040px, same as .pdp-page below it. */
.pdp-header-block {
  box-shadow: 0 4px 8px -4px rgba(15, 20, 26, 0.15);
  margin: 0 -20px var(--space-l);
  padding: 0 20px;
}

.pdp-header-block__inner {
  max-width: 1040px;
  margin: 0 auto;
}

.pdp-header-block .tabs {
  margin-bottom: 0;
  /* The plane's own box-shadow already marks this edge — the tabs
     component's usual hard divider directly beneath the active tab pill
     would just double up on top of it. */
  border-bottom: none;
}

.pdp-header {
  display: flex;
  gap: var(--space-l);
  padding-bottom: var(--space-l);
}

.pdp-header__icon {
  width: 72px;
  height: 72px;
  flex-shrink: 0;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-input);
  display: flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: 26px;
  color: #fff;
}

.pdp-header__content {
  flex: 1;
  min-width: 0;
}

.pdp-header__content h1 {
  font-size: 22px;
  margin: 0;
  color: var(--color-text-heading);
  display: inline;
}

.pdp-header__sold-by {
  font-size: 14px;
  color: var(--color-text-body);
  margin: 4px 0 var(--space-s);
}

.pdp-header__badges {
  display: flex;
  gap: var(--space-xs);
  margin-bottom: var(--space-s);
}

.pdp-header__desc {
  font-size: 14px;
  color: var(--color-text-body);
  line-height: 1.5;
  margin: 0;
}

.pdp-header__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
  flex-shrink: 0;
  width: 200px;
}

.pdp-header__actions .btn {
  width: 100%;
  justify-content: center;
}

/* Anchor-jump tabs reuse .tabs/.tab as-is; this offset keeps a jumped-to
   section's heading from landing flush against the viewport top. */
.pdp-section {
  scroll-margin-top: var(--space-l);
  margin-top: 40px;
}

.pdp-section:first-of-type {
  margin-top: var(--space-xl);
}

.pdp-section > h2 {
  font-size: 20px;
  margin: 0 0 var(--space-m);
  color: var(--color-text-heading);
}

.pdp-columns {
  display: flex;
  gap: var(--space-l);
  align-items: flex-start;
}

/* Support's two cards should match height (unlike Overview's main/sidebar
   columns, which are meant to size to their own content). */
.pdp-columns--equal {
  align-items: stretch;
}

.pdp-columns--equal > .pdp-columns__main {
  display: flex;
}

.pdp-columns--equal .pdp-card {
  flex: 1;
}

.pdp-columns__main {
  flex: 2;
  min-width: 0;
}

.pdp-columns__side {
  flex: 1;
  min-width: 260px;
  display: flex;
  flex-direction: column;
  gap: var(--space-m);
}

/* .pdp-card here is also a .container (margin-bottom) and a
   .pdp-card + .pdp-card sibling (margin-top) — both of those were
   stacking on top of this flex gap, tripling the actual spacing. The
   flex gap alone should drive it. Three classes (not two) so this
   reliably outweighs .pdp-card + .pdp-card's equal-specificity rule
   regardless of source order. */
.pdp-columns__side .container.pdp-card {
  margin: 0;
}

.pdp-highlights {
  margin: 0;
  padding-left: 18px;
}

.pdp-highlights li {
  font-size: 14px;
  color: var(--color-text-body);
  line-height: 1.5;
  margin-bottom: var(--space-m);
}

.pdp-highlights li:last-child {
  margin-bottom: 0;
}

.pdp-prose p {
  font-size: 14px;
  color: var(--color-text-body);
  line-height: 1.6;
  margin: 0 0 var(--space-m);
}

.pdp-prose p:last-of-type {
  margin-bottom: 0;
}

.show-more-link {
  display: inline-block;
  margin-top: var(--space-s);
  font-size: 14px;
}

.pdp-card + .pdp-card {
  margin-top: var(--space-l);
}

.pdp-card__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-s);
  margin-bottom: var(--space-s);
}

/* Some card headers pair a heading with just an Info link — that link
   should sit right next to the heading text, not pushed to the far
   right by the default space-between (which is meant for a heading vs.
   a trailing action button/CTA, e.g. Free trial's "Try for free"). */
.pdp-card__header--inline {
  justify-content: flex-start;
}

.pdp-card__header h3 {
  font-size: 16px;
  margin: 0;
  color: var(--color-text-heading);
}

.pdp-card p {
  font-size: 14px;
  color: var(--color-text-body);
  line-height: 1.6;
  margin: 0;
}

.form-select {
  appearance: none;
  -webkit-appearance: none;
  width: 100%;
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-input);
  padding: 6px 32px 6px var(--space-s);
  font-size: 14px;
  font-family: inherit;
  color: var(--color-text-body);
  background: var(--color-bg-input) url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 14 14'%3E%3Cpath d='M3 5.5 7 9.5l4-4' fill='none' stroke='%23424650' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E") no-repeat right 10px center / 14px 14px;
  cursor: pointer;
}

/* .pdp-card p (a class+type selector, specificity 0,1,1) otherwise beats
   a bare .pdp-usage-table-title (0,1,0) regardless of source order and
   silently zeroes out this margin — qualify with .pdp-card so the two
   classes (0,2,0) win instead. */
.pdp-card .pdp-usage-table-title {
  font-size: 16px;
  font-weight: 700;
  color: var(--color-text-heading);
  margin: var(--space-xl) 0 var(--space-s);
}

.dotted-underline {
  text-decoration: underline dotted;
  text-underline-offset: 2px;
  cursor: help;
}

.kv-pairs {
  display: flex;
  flex-direction: column;
}

.kv-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-m);
  padding: var(--space-s) 0;
  border-bottom: 1px solid var(--color-border-divider);
}

.kv-row:last-child {
  border-bottom: none;
  padding-bottom: 0;
}

.kv-row:first-child {
  padding-top: 0;
}

.kv-key {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-heading);
}

.kv-value {
  font-size: 14px;
  color: var(--color-text-body);
}

.kv-value a {
  text-decoration: underline;
}

.pdp-instructions p {
  font-size: 14px;
  color: var(--color-text-body);
  line-height: 1.6;
  margin: 0 0 var(--space-m);
}

.pdp-instructions p:last-child {
  margin-bottom: 0;
}

.vendor-resource-links {
  display: flex;
  flex-direction: column;
  gap: var(--space-s);
}

/* ============ SUBSCRIBE / PROCUREMENT PAGE ============ */

.procure-page {
  max-width: 1280px;
  margin: 0 auto;
}

.procure-header__desc {
  font-size: 14px;
  color: var(--color-text-body);
  margin: var(--space-s) 0 0;
}

.procure-card {
  padding: 20px;
}

.procure-card + .procure-card {
  margin-top: var(--space-l);
}

.procure-card__title {
  font-size: 18px;
  margin: 0;
  color: var(--color-text-heading);
}

.procure-card__hint {
  font-size: 14px;
  color: var(--color-text-body);
  margin: 4px 0 0;
}

.procure-card__subhead {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-heading);
  margin: var(--space-l) 0 2px;
}

.badge--green {
  background: var(--color-green);
}

.offer-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-m);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-input);
  padding: var(--space-m);
  margin-top: var(--space-m);
}

.offer-row__title {
  font-size: 14px;
  font-weight: 700;
  color: var(--color-text-heading);
}

.offer-row__meta {
  font-size: 12px;
  color: var(--color-text-body-secondary);
  margin-top: 2px;
}

.offer-row__details {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-m);
  font-size: 12px;
  color: var(--color-text-body-secondary);
  margin-top: 4px;
}

.offer-row__side {
  display: flex;
  align-items: center;
  gap: var(--space-s);
  flex-shrink: 0;
}

.offer-row__toggle {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--color-text-body-secondary);
  display: flex;
  padding: 2px;
}

.procure-footer {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-m);
  margin-top: var(--space-l);
}
