:root {
  /* Compact visible controls; 34px exceeds the WCAG 2.2 24px minimum and
     controls are separated by at least 6px. Do not turn every pill into a
     44px-high block on phones. */
  --cgd-control-min: 34px;
  /* A segmented button sits inside 3px of bank padding and a 1px border, so it
     must be 8px shorter than the bank for the bank to come out at the house
     control height. Declared once because it is set in two places (the base
     rule and the compact override) and they drifted apart. 26px still clears
     the 24px tap-target floor. */
  --cgd-control-inner: calc(var(--cgd-control-min) - 8px);
  --cgd-icon-target: 44px;
  --cgd-body-size: 14px;
  --cgd-secondary-size: 12px;
}

html,
body {
  width: 100%;
  min-width: 0;
  margin: 0;
  padding: 0;
  overflow-x: hidden;
  background: transparent;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

img,
svg,
canvas {
  max-width: 100%;
}

.viz-wrapper,
.remit-viz,
#flowExplorer,
#coverageExplorer {
  width: 100%;
  min-width: 0;
  margin-inline: auto;
  padding-inline: clamp(12px, 2.2vw, 20px);
}

.controls,
.remit-viz__controls {
  min-width: 0;
}

.control-label,
.control-group > label,
.remit-viz__control-label,
.remit-viz__control > label,
.combo__label,
.country-picker > label {
  font-size: 12px !important;
  line-height: 1.3 !important;
  white-space: normal !important;
  overflow: visible !important;
  text-overflow: clip !important;
}

button,
input,
select,
textarea,
.country-trigger,
.combo__button,
.select-trigger {
  font-size: var(--cgd-body-size);
}

/* Editable text fields are pinned to 16px at EVERY width, not just on phones.
 *
 * This rule used to force --cgd-body-size (14px) with !important and no media
 * query, so the 16px phone rule further down was the only thing keeping the
 * country search boxes out of iOS's zoom-jump — and nothing protected a tablet,
 * which is 768px wide and still zooms a sub-16px field on focus. Because the
 * declaration is !important, no figure could opt out of it either.
 *
 * Buttons and select triggers keep the body size: they are not text entry, so
 * enlarging them would change the look of every control bank in the set for no
 * accessibility gain. */
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="button"]),
textarea {
  font-size: 16px !important;
}

select,
.country-trigger,
.combo__button,
.select-trigger {
  font-size: var(--cgd-body-size) !important;
}

/* …but 16px is a defence against one specific thing — iOS zooming the page when
 * a text field is focused — and that cannot happen with a mouse. On a fine
 * pointer the rule had no purpose and one visible cost: a combobox input sat at
 * 16px next to a native select at 14px in the same control bank, so figure 1's
 * "Recipient" box read noticeably larger than "Countries shown" beside it.
 * Coarse pointers keep the floor; `qa/audit.py` emulates touch at the phone
 * widths so the floor is still tested rather than merely asserted. */
@media (pointer: fine) {
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]):not([type="button"]),
  textarea {
    font-size: var(--cgd-body-size) !important;
  }
}

/* One control height for the whole set.
 *
 * This block used to say `min-height: var(--cgd-control-min); height: auto`,
 * which left every control's height to its own font-size and padding. Because
 * those differ by control type, no two kinds of control lined up: at 1200px a
 * segmented toggle came out 42px (its buttons were forced to 34px, plus 3px
 * padding each side and the border), a search input 42px (16px text, 8px
 * padding), a native select 36px (14px text), a country trigger 34px, and
 * figure 7's combo input 34.4px. Nine of the twelve figures had two or three
 * different control heights sitting side by side.
 *
 * 34px is the documented house height and the one `.country-trigger` already
 * rendered at, so everything else comes to it. Single-line controls take a
 * fixed height with no vertical padding — a select, input and button all centre
 * their own text, so the 14px and 16px controls still align — and the segmented
 * pill bank keeps a min-height so it can still grow when it wraps to two rows
 * below 400px.
 */
select,
input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
.country-trigger,
.combo__button,
.select-trigger,
.pager-btn,
.zoom-btn {
  height: var(--cgd-control-min) !important;
  min-height: var(--cgd-control-min) !important;
  padding-block: 0 !important;
}

/* Native selects were reserving 30px of right padding for a chevron they do not
 * draw. None of them sets `appearance: none` or a background arrow, so the
 * browser draws and reserves space for its own control — the 30px was 20px of
 * dead width on top of that, and it was enough to truncate the label: figure 3's
 * income filter read "All income g" at every width, with 113px of text in 97px
 * of room.
 *
 * These lists are all short (income groups, regions, a corridor count), so above
 * the compact breakpoint the select simply takes the width its widest option
 * needs and the control bank grows to suit. Below it the bank is a fixed grid,
 * where a wider select would overflow the row, so there it relies on the
 * recovered padding instead. qa/audit.py fails any select whose selected option
 * does not fit. */
.controls select,
.remit-viz__controls select {
  padding-inline: 9px 20px !important;
}

@media (min-width: 601px) {
  .controls select,
  .remit-viz__controls select {
    /* max-content, not fit-content: fit-content resolved against the available
       space here and left the select at 108px against 113px of text. The flex
       items carry min-width:0, so the floor has to come from the select. */
    min-width: max-content;
  }

  /* The group must not shrink below what its select needs, or min-width above
     just makes the select overflow its own group.
     `flex-basis`, not `min-width`: figure 10's bank is a GRID at these widths,
     and a grid item with min-width:max-content overflows its track and lands on
     top of its neighbour — which is exactly what happened. Grid ignores
     flex-basis and flex-shrink, so this reaches only the flex banks that need
     it, and figure 10's grid keeps its own column widths. */
  .controls > .control-group:has(select),
  .remit-viz__controls > *:has(select) {
    flex-basis: max-content;
    flex-shrink: 0;
  }
}


/* The pill bank is 34px overall: 26px buttons inside 3px of padding and a 1px
   border. 26px still clears the 24px tap-target floor that qa/audit.py checks. */
.segmented,
.remit-viz__toggle,
.toggle {
  min-height: var(--cgd-control-min);
}

.segmented button,
.remit-viz__toggle button,
.toggle button {
  min-height: var(--cgd-control-inner) !important;
  height: var(--cgd-control-inner) !important;
  padding: 0 9px;
  font-size: 13px !important;
  line-height: 1.2;
}

.fullscreen-btn,
.popup-close,
.metric-info-close,
.info-btn,
.pager-btn,
.zoom-btn {
  min-width: var(--cgd-icon-target);
  min-height: var(--cgd-icon-target);
  width: var(--cgd-icon-target);
  height: var(--cgd-icon-target);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.zoom-btn.reset {
  width: auto;
  min-width: var(--cgd-control-min);
}

.notes,
.source,
.remit-viz__source,
.tooltip,
.popup-sub,
.descriptor-context {
  font-size: max(var(--cgd-secondary-size), 0.75rem);
  line-height: 1.4;
}

.descriptor-title {
  font-size: 12px !important;
}

.legend,
.legend-item,
.region-legend-item,
.remit-viz__legend,
.remit-viz__legend-item {
  font-size: 12px !important;
}

.country-menu,
.combo__list,
.country-options {
  max-width: calc(100vw - 24px);
}

.popup-card,
.modal-card {
  max-width: min(680px, calc(100vw - 24px));
  max-height: calc(100dvh - 24px);
  overflow: auto;
}

@media (max-width: 760px) {
  .controls,
  .remit-viz__controls {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: end;
    gap: 10px;
  }

  .controls > *,
  .remit-viz__controls > * {
    min-width: 0;
    width: 100%;
    max-width: none;
    flex: none;
  }

  .country-picker {
    grid-column: auto;
  }
}

@media (max-width: 520px) {
  .viz-wrapper h1,
  .remit-viz h1,
  #flowExplorer h1,
  #coverageExplorer h1 {
    font-size: clamp(20px, 5.8vw, 22px) !important;
    line-height: 1.14 !important;
  }

  .viz-wrapper,
  .remit-viz,
  #flowExplorer,
  #coverageExplorer {
    padding-inline: 12px;
  }

  .controls,
  .remit-viz__controls {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
    padding: 8px;
  }

  .country-picker {
    grid-column: 1 / -1;
  }

  .metric-control {
    grid-column: 1 / -1;
  }

  .segmented,
  .remit-viz__toggle,
  .toggle {
    width: 100%;
  }

  .segmented button,
  .remit-viz__toggle button,
  .toggle button {
    flex: 1 1 auto;
    min-width: 0;
    white-space: nowrap !important;
    overflow-wrap: normal !important;
    word-break: normal !important;
    hyphens: none !important;
    padding: 5px 7px !important;
    font-size: 12px !important;
  }

  /* Keep menus attached to their trigger. Fixed menus can appear far away after
     an iframe or mobile browser changes the visual viewport. */
  .country-menu,
  .combo__menu,
  .select-menu {
    position: absolute !important;
    inset-inline: 0 !important;
    top: calc(100% + 4px) !important;
    width: auto !important;
    max-height: min(48dvh, 360px) !important;
    overflow: auto !important;
    border-radius: 10px !important;
    padding: 4px !important;
  }

  .combo__list,
  .country-options {
    position: static !important;
    width: 100% !important;
    max-width: none !important;
    max-height: min(38dvh, 300px) !important;
    overflow: auto !important;
  }

  .combo__option,
  .country-option,
  .select-option {
    width: 100% !important;
    min-height: 36px !important;
    margin: 0 !important;
    border: 0 !important;
    border-radius: 6px !important;
    background: transparent !important;
    box-shadow: none !important;
    text-align: left !important;
    font-size: 14px !important;
  }

  .combo__option[aria-selected="true"],
  .country-option.selected,
  .select-option.active {
    background: #eef4f5 !important;
  }

  /* iOS Safari zooms the page when an editable control below 16px receives
     focus. Do not suppress user zoom in the viewport meta tag. */
  input,
  select,
  textarea,
  .combo__search,
  .country-search,
  .search-select input {
    font-size: 16px !important;
  }

  .descriptor-tabs {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: 4px;
  }

  .descriptor-tab {
    min-height: 0;
  }

  .descriptor-title {
    font-size: 12px !important;
  }

  .descriptor-value {
    font-size: 16px !important;
  }

  .descriptor-context {
    font-size: 12px !important;
  }

  .popup-backdrop,
  .modal-backdrop {
    align-items: flex-end !important;
    padding: 0 !important;
  }

  .popup-card,
  .modal-card {
    width: 100% !important;
    max-width: none !important;
    max-height: min(82dvh, 680px) !important;
    border-radius: 16px 16px 0 0 !important;
    padding: 14px !important;
    overscroll-behavior: contain;
  }

  .popup-top,
  .modal-top {
    position: sticky;
    top: -14px;
    z-index: 2;
    background: #fff;
    padding-top: 14px;
  }

  .map-shell,
  .chart-wrap,
  .scatter-wrap,
  .plot-wrap {
    min-width: 0;
  }

  #coverageExplorer .controls {
    display: grid !important;
    grid-template-columns: minmax(112px, 0.85fr) minmax(146px, 1.15fr) !important;
    align-items: end !important;
    gap: 10px 8px !important;
    padding: 10px !important;
  }

  #coverageExplorer .controls > .control-group {
    width: 100% !important;
    max-width: none !important;
    min-width: 0 !important;
    flex: none !important;
  }

  #coverageExplorer .segmented {
    width: 100% !important;
  }

  #coverageExplorer .control-label,
  #coverageExplorer .segmented button {
    overflow-wrap: normal !important;
    word-break: normal !important;
    hyphens: none !important;
  }

  #coverageExplorer .segmented button {
    overflow: visible !important;
    text-overflow: clip !important;
  }
}

/*
  Some iOS iframe contexts retain a desktop-like layout viewport and visually
  scale it down. cgd-embed.js therefore adds this class from visualViewport,
  which follows the width the reader actually sees.
*/
.cgd-mobile-embed .viz-wrapper h1,
.cgd-mobile-embed .remit-viz h1,
.cgd-mobile-embed #flowExplorer h1,
.cgd-mobile-embed #coverageExplorer h1 {
  font-size: clamp(20px, 5.8vw, 22px) !important;
  line-height: 1.14 !important;
}

.cgd-mobile-embed .viz-wrapper,
.cgd-mobile-embed .remit-viz,
.cgd-mobile-embed #flowExplorer,
.cgd-mobile-embed #coverageExplorer {
  padding-inline: 12px;
}

.cgd-mobile-embed .controls,
.cgd-mobile-embed .remit-viz__controls {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: end;
  gap: 6px;
  padding: 7px;
}

.cgd-mobile-embed .controls > *,
.cgd-mobile-embed .remit-viz__controls > * {
  min-width: 0;
  width: 100%;
  max-width: none;
  flex: none;
}

.cgd-mobile-embed .control-spacer {
  display: none !important;
}

.cgd-mobile-embed .country-picker,
.cgd-mobile-embed .metric-control {
  grid-column: 1 / -1;
}

.cgd-mobile-embed .segmented,
.cgd-mobile-embed .remit-viz__toggle,
.cgd-mobile-embed .toggle {
  width: 100%;
  min-height: var(--cgd-control-min) !important;
}

.cgd-mobile-embed .segmented button,
.cgd-mobile-embed .remit-viz__toggle button,
.cgd-mobile-embed .toggle button {
  flex: 1 1 0;
  min-width: 0;
  /* Was --cgd-control-min, i.e. the height of the whole bank, which pushed the
     bank itself to 40-42px on phones while every other control stayed at 34. */
  min-height: var(--cgd-control-inner) !important;
  height: var(--cgd-control-inner) !important;
  white-space: nowrap !important;
  overflow-wrap: normal !important;
  word-break: normal !important;
  hyphens: none !important;
  padding: 4px 6px !important;
  font-size: 12px !important;
  line-height: 1.15 !important;
}

.cgd-mobile-embed .country-menu,
.cgd-mobile-embed .combo__menu,
.cgd-mobile-embed .select-menu {
  position: absolute !important;
  inset-inline: 0 !important;
  top: calc(100% + 4px) !important;
  width: auto !important;
  max-height: min(48dvh, 360px) !important;
  overflow: auto !important;
  border-radius: 10px !important;
  padding: 4px !important;
  background: #fff !important;
  z-index: 1000 !important;
}

.cgd-mobile-embed .combo__list,
.cgd-mobile-embed .country-options {
  position: static !important;
  width: 100% !important;
  max-width: none !important;
  max-height: min(38dvh, 300px) !important;
  overflow: auto !important;
}

.cgd-mobile-embed .combo__option,
.cgd-mobile-embed .country-option,
.cgd-mobile-embed .select-option {
  display: block !important;
  width: 100% !important;
  min-height: 36px !important;
  margin: 0 !important;
  padding: 7px 9px !important;
  border: 0 !important;
  border-radius: 5px !important;
  background: transparent !important;
  box-shadow: none !important;
  text-align: left !important;
  font-size: 14px !important;
}

.cgd-mobile-embed .combo__option + .combo__option,
.cgd-mobile-embed .country-option + .country-option,
.cgd-mobile-embed .select-option + .select-option {
  border-top: 1px solid #edf2f3 !important;
}

.cgd-mobile-embed .combo__option[aria-selected="true"],
.cgd-mobile-embed .country-option.selected,
.cgd-mobile-embed .select-option.active {
  background: #eef4f5 !important;
}

.cgd-mobile-embed input,
.cgd-mobile-embed select,
.cgd-mobile-embed textarea,
.cgd-mobile-embed .combo__search,
.cgd-mobile-embed .country-search,
.cgd-mobile-embed .search-select input {
  font-size: 16px !important;
}

/* Axis and tick text on compact viewports.
 *
 * This was 9.5px, which put every tick on every chart in the set below the
 * readable floor — and because it is !important, no figure could opt out of it.
 * The house axis size is 10.5px and there is no reason a phone should get less:
 * too many ticks is fixed by thinning the ticks, not by shrinking the type until
 * they fit. qa/audit.py enforces the 10px floor. */
.cgd-mobile-embed .axis text,
.cgd-mobile-embed .tick text,
.cgd-mobile-embed .axis-label,
.cgd-mobile-embed svg text.axis,
.cgd-mobile-embed svg text.tick {
  font-size: 10.5px !important;
}

/* A three-way toggle ("2024 | 2021 | Change", "US$ | %") needs about 147px of
 * label at the floor type size, and at 320px it is given ~128px. The labels then
 * spill outside their own pills: on the selected pill the dark background stops
 * short and the white text carries on over the panel.
 *
 * Wrapping is the house answer — reflow, don't shrink. This is a no-op for a
 * toggle whose labels already fit, because flex only wraps when it must, so
 * every two-way toggle in the set is untouched. It needs !important because the
 * figures set `min-width: 0` on segmented buttons themselves. */
@media (max-width: 400px) {
  .segmented:has(button:nth-child(3)) {
    flex-wrap: wrap !important;
    row-gap: 2px !important;
  }

  .segmented:has(button:nth-child(3)) button {
    min-width: max-content !important;
  }
}

.cgd-mobile-embed .fullscreen-btn {
  display: none !important;
}

.cgd-mobile-embed .popup-backdrop,
.cgd-mobile-embed .modal-backdrop {
  align-items: flex-end !important;
  padding: 0 !important;
}

.cgd-mobile-embed .popup-card,
.cgd-mobile-embed .modal-card {
  width: 100% !important;
  max-width: none !important;
  max-height: min(82dvh, 680px) !important;
  border-radius: 16px 16px 0 0 !important;
  padding: 14px !important;
  overscroll-behavior: contain;
}

.cgd-mobile-embed #coverageExplorer .controls {
  grid-template-columns: minmax(108px, 0.85fr) minmax(138px, 1.15fr) !important;
  gap: 6px !important;
  padding: 7px !important;
}

.cgd-mobile-embed #coverageExplorer .controls > .control-group {
  width: 100% !important;
  max-width: none !important;
  min-width: 0 !important;
  flex: none !important;
}

.cgd-mobile-embed #coverageExplorer .segmented {
  width: 100% !important;
}

/* Chart-specific compact control maps. Every occupied mobile row must be
   complete: no singleton half-row and no unexplained blank cell. */
/* The map's View toggle now takes a full row, because "Countries |
   Intra-regional" cannot fit a half-width track at 320px. That leaves the
   country picker as the singleton half-row the note above forbids, so it takes
   a full row too. */
[data-cgd-interactive-name="bilateral-remittances-map"].cgd-mobile-embed .country-picker {
  grid-column: 1 / -1;
}

[data-cgd-interactive-name="bilateral-remittances-model-v-world-bank"].cgd-mobile-embed .remit-viz__controls {
  grid-template-columns: minmax(94px, .95fr) minmax(112px, 1.15fr) minmax(82px, .8fr);
}

[data-cgd-interactive-name="bilateral-remittances-regions-matrix"].cgd-mobile-embed .year-control,
[data-cgd-interactive-name="bilateral-remittances-income-matrix"].cgd-mobile-embed .year-control {
  grid-column: 1;
}

[data-cgd-interactive-name="bilateral-remittances-regions-matrix"].cgd-mobile-embed .metric-control,
[data-cgd-interactive-name="bilateral-remittances-income-matrix"].cgd-mobile-embed .metric-control {
  grid-column: 2;
}

/* Below ~360px, pairing the two controls on one row leaves the display toggle a
   49px track, which is not enough for two options plus the inline "Display"
   label — they overflow their pills. The three-option Year toggle needs the wide
   track more, so the display toggle takes a full row of its own, which is what
   the generic .metric-control rule above already does for every other figure. */
@media (max-width: 380px) {
  [data-cgd-interactive-name="bilateral-remittances-regions-matrix"].cgd-mobile-embed .year-control,
  [data-cgd-interactive-name="bilateral-remittances-income-matrix"].cgd-mobile-embed .year-control,
  [data-cgd-interactive-name="bilateral-remittances-regions-matrix"].cgd-mobile-embed .metric-control,
  [data-cgd-interactive-name="bilateral-remittances-income-matrix"].cgd-mobile-embed .metric-control {
    grid-column: 1 / -1;
  }
}

[data-cgd-interactive-name="bilateral-remittances-regions-matrix"].cgd-mobile-embed .controls,
[data-cgd-interactive-name="bilateral-remittances-income-matrix"].cgd-mobile-embed .controls {
  grid-template-columns: minmax(0, 1.26fr) minmax(0, .74fr) !important;
}

[data-cgd-interactive-name="bilateral-remittances-regions-matrix"].cgd-mobile-embed .year-control,
[data-cgd-interactive-name="bilateral-remittances-regions-matrix"].cgd-mobile-embed .metric-control,
[data-cgd-interactive-name="bilateral-remittances-income-matrix"].cgd-mobile-embed .year-control,
[data-cgd-interactive-name="bilateral-remittances-income-matrix"].cgd-mobile-embed .metric-control {
  display: grid !important;
  grid-template-columns: max-content minmax(0, 1fr);
  align-items: center;
  gap: 6px !important;
}

[data-cgd-interactive-name="bilateral-remittances-regions-matrix"].cgd-mobile-embed .segmented,
[data-cgd-interactive-name="bilateral-remittances-income-matrix"].cgd-mobile-embed .segmented {
  width: 100% !important;
  min-width: 0 !important;
}

[data-cgd-interactive-name="bilateral-remittances-regions-matrix"].cgd-mobile-embed .segmented button,
[data-cgd-interactive-name="bilateral-remittances-income-matrix"].cgd-mobile-embed .segmented button {
  padding-inline: 2px !important;
}

[data-cgd-interactive-name="bilateral-remittances-migrant-stock-gni"].cgd-mobile-embed .metric-control {
  grid-column: 1 / -1;
}

[data-cgd-interactive-name="bilateral-remittances-migrant-stock-gni"].cgd-mobile-embed .region-control {
  grid-column: 1;
}

[data-cgd-interactive-name="bilateral-remittances-migrant-stock-gni"].cgd-mobile-embed .country-control {
  grid-column: 2;
}

[data-cgd-interactive-name="bilateral-remittances-oda-fdi"].cgd-mobile-embed .income-filter-group {
  grid-column: 1;
}

[data-cgd-interactive-name="bilateral-remittances-oda-fdi"].cgd-mobile-embed .country-picker {
  grid-column: 2;
}

[data-cgd-interactive-name="bilateral-remittances-total-gni"].cgd-mobile-embed .short-control {
  grid-column: 1;
}

[data-cgd-interactive-name="bilateral-remittances-total-gni"].cgd-mobile-embed .country-control {
  grid-column: 2;
}

[data-cgd-interactive-name="bilateral-remittances-corridors-gni"].cgd-mobile-embed .role-control {
  grid-column: 1;
  grid-row: 1;
}

[data-cgd-interactive-name="bilateral-remittances-corridors-gni"].cgd-mobile-embed .limit-control {
  grid-column: 2;
  grid-row: 1;
}

[data-cgd-interactive-name="bilateral-remittances-corridors-gni"].cgd-mobile-embed .country-control {
  grid-column: 1 / -1;
  grid-row: 2;
}

[hidden] {
  display: none !important;
}

/* Fullscreen inside an embedded visual is unreliable or redundant on phones.
   Hide the control for coarse pointers while leaving desktop support intact. */
@media (hover: none) and (pointer: coarse), (max-width: 520px) {
  .fullscreen-btn {
    display: none !important;
  }
}

@media (max-width: 360px) {
  .controls,
  .remit-viz__controls {
    padding-inline: 8px;
  }

  #coverageExplorer .controls {
    grid-template-columns: minmax(106px, 0.82fr) minmax(140px, 1.18fr) !important;
    gap: 8px 6px !important;
    padding-inline: 8px !important;
  }
}

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

/* One control per row below ~420px.
 *
 * Half of a 320px control bank is about 136px. A native select showing
 * "All income groups" needs ~160px, because selects keep 16px text on phones so
 * that iOS does not zoom the page when one is focused — so at these widths the
 * two-column pairings above cannot hold without truncating a label.
 *
 * Giving only the select a full row left its partner alone in a half row, which
 * is the "singleton half-row" the note further up forbids. So every control gets
 * the full width instead: nothing is truncated, every occupied row is complete,
 * and each control is comfortably tappable. It costs vertical space on the
 * narrowest phones, which is the right trade against an unreadable filter.
 *
 * !important and last in the file because the per-figure rules above pin
 * individual groups to a column with a specificity a generic selector cannot
 * beat. */
@media (max-width: 420px) {
  .cgd-mobile-embed .controls > *,
  .cgd-mobile-embed .remit-viz__controls > * {
    grid-column: 1 / -1 !important;
    /* grid-row too: figure 12 pins two of its groups to `grid-row: 1`, so
       widening both to the full row put them on top of each other. Letting the
       rows auto-place restores one control per row. */
    grid-row: auto !important;
  }
}
