/* Space Retailing atoms. Class prefix .rt-. Values from
   src/components/common/{Button,IconButton,Pill,LinearLoader}/index.module.pcss
   and src/const/ComponentState.ts. Tokens live in tokens/ and are frozen. */

/* ---------- Button ---------- */
.rt-btn {
  height: var(--button-height);
  padding: 0 var(--s-8);
  border: 1px solid transparent;
  border-radius: var(--button-border-radius);
  text-align: center;
  overflow: hidden;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  font: var(--t-h5);
  font-family: var(--primary-font);
  text-transform: var(--cta-text-transform);
  transition: border-color 0.2s ease-out, background 0.2s ease-out;
}
.rt-btn--large { height: var(--h-control-large); }

.rt-btn--primary { background: var(--_primary-button-color); color: var(--_primary-button-text-color); }
.rt-btn--primary:hover, .rt-btn--primary.is-hover {
  background: var(--_primary-button-color-hover);
  border-color: var(--_primary-button-color-hover);
  color: var(--_primary-button-text-hover);
}
.rt-btn--secondary { background: var(--secondary-button-color); color: var(--secondary-button-text-color); }
.rt-btn--secondary:hover, .rt-btn--secondary.is-hover {
  background: var(--secondary-button-color-hover);
  border-color: var(--secondary-button-color-hover);
  color: var(--secondary-button-text-color-hover);
}
.rt-btn--tertiary { background: var(--tertiary-button-color); color: var(--tertiary-button-text-color); }
.rt-btn--tertiary:hover, .rt-btn--tertiary.is-hover {
  background: var(--tertiary-button-color-hover);
  border-color: var(--tertiary-button-color-hover);
  color: var(--tertiary-button-text-color-hover);
}

/* Disabled keeps the variant label color; only the box goes flat gray. */
.rt-btn:disabled, .rt-btn.is-disabled {
  background: var(--gray-4);
  border-color: var(--gray-4);
  pointer-events: none;
}

.rt-btn.is-pulsing { animation: rt-pulsing 1.5s infinite ease-in-out; }

/* ---------- LinearLoader (Button loading label) ---------- */
.rt-loader { display: flex; align-items: center; gap: var(--s-8); }
.rt-loader span {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--white);
  animation: rt-loader-dot 0.9s infinite ease-in-out;
}
.rt-loader span:nth-child(2) { animation-delay: 0.3s; }
.rt-loader span:nth-child(3) { animation-delay: 0.6s; }
@keyframes rt-loader-dot {
  0% { opacity: 0.25; }
  40% { opacity: 1; }
  80% { opacity: 0.25; }
  100% { opacity: 0.25; }
}

/* ---------- IconButton ---------- */
.rt-iconbtn {
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  padding: var(--s-4);
  border: 1px solid transparent;
  border-radius: var(--r-5);
  background: none;
  cursor: pointer;
  color: inherit;
  transition: all 0.05s ease-in-out;
}
.rt-iconbtn--md { width: var(--h-icon-button-md); height: var(--h-icon-button-md); }
.rt-iconbtn--lg { width: var(--h-icon-button-lg); height: var(--h-icon-button-lg); }
.rt-iconbtn > svg, .rt-iconbtn > i { width: 100%; height: 100%; font-size: inherit; }
.rt-iconbtn:hover, .rt-iconbtn.is-hover { border-color: var(--gray-5); }
.rt-iconbtn--no-border:hover, .rt-iconbtn--no-border.is-hover { border-color: transparent; }

/* ---------- Pill ---------- */
.rt-pill {
  position: relative;
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  min-height: var(--h-pill);
  padding: var(--s-8);
  border-radius: var(--r-5);
  box-sizing: border-box;
  overflow: hidden;
  font: var(--t-body4);
  font-family: var(--primary-font);
}
.rt-pill--default { color: var(--black); background: var(--gray-6); }
.rt-pill--primary { color: var(--white); background: var(--blue-1); }
.rt-pill--alert { color: var(--red-1); background: var(--red-2); }
.rt-pill--warning { color: var(--yellow-1); background: var(--yellow-2); }
.rt-pill--success { color: var(--green-1); background: var(--green-2); }

.rt-pill__icon { margin-right: var(--s-8); font-size: 0.875em; }
.rt-pill__icon--spin { animation: rt-spin 1s linear infinite; }
@keyframes rt-spin { to { transform: rotate(360deg); } }

.rt-pill--shimmer::after {
  content: '';
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  background: linear-gradient(90deg, transparent 0%, transparent 35%, var(--gray-6) 50%, transparent 65%, transparent 100%);
  background-size: 200% 100%;
  animation: rt-shimmer 2s linear infinite;
}
.rt-pill--shimmer.rt-pill--has-icon::after { left: 32px; }

/* ---------- Input ---------- */
.rt-input__container { position: relative; }

.rt-input input, .rt-input textarea {
  width: 100%;
  height: var(--input-height);
  padding: var(--s-4) var(--s-8);
  box-sizing: border-box;
  border: 1px solid var(--input-border-color);
  border-radius: var(--input-border-radius);
  background: var(--input-background-color);
  font-family: var(--primary-font);
  font-size: var(--input-font-size-mobile);
  color: var(--input-text-color);
}
@media (min-width: 768px) {
  .rt-input input, .rt-input textarea { font-size: var(--input-font-size); }
}
.rt-input textarea { resize: none; padding: var(--s-8); }
.rt-input--with-start-adornment input, .rt-input--with-start-adornment textarea { padding-left: 40px; }
.rt-input--with-end-adornment input, .rt-input--with-end-adornment textarea { padding-right: 40px; }
.rt-input input:hover, .rt-input textarea:hover { background-color: var(--blue-3); }
.rt-input input:active:not(:disabled), .rt-input input:focus:not(:disabled),
.rt-input textarea:active:not(:disabled), .rt-input textarea:focus:not(:disabled),
.rt-input input.is-focus, .rt-input textarea.is-focus { border-color: var(--input-focus-color); }
.rt-input input:disabled, .rt-input textarea:disabled {
  pointer-events: none;
  color: var(--gray-5);
  border-color: var(--gray-5);
}
/* PRESCRIPTIVE — not in the code. App.module.pcss declares
   --input-placeholder-text-color from the dealer's --form-input-placeholder-text-color,
   but no stylesheet consumes it, so the dealer's placeholder colour has no live effect.
   This rule shows what it would look like wired up. */
.rt-input input::placeholder, .rt-input textarea::placeholder { color: var(--input-placeholder-text-color); }

.rt-input__label {
  position: absolute;
  top: -9px;
  left: var(--s-8);
  padding: 0 var(--s-2);
  height: 18px;
  font-size: var(--input-font-size);
  font-weight: 500;
  line-height: 18px;
  color: var(--gray-0);
  transition: all 0.2s;
}
.rt-input__label::after {
  content: '';
  position: absolute;
  top: 9px;
  right: 0;
  bottom: 0;
  left: 0;
  display: block;
  background-color: var(--white);
  width: 100%;
  height: 1px;
  z-index: 1;
}
.rt-input__label label { position: relative; z-index: 2; }
.rt-input__label.is-disabled { color: var(--gray-4); }
.rt-input:focus-within:not(:disabled) .rt-input__label,
.rt-input.is-focus .rt-input__label { color: var(--primary-accent); }

.rt-input__start-adornment {
  position: absolute;
  font-size: var(--input-start-adornment-size);
  top: 50%;
  left: var(--s-16);
  transform: translateY(-50%);
}
.rt-input__end-adornment {
  position: absolute;
  top: 50%;
  right: var(--s-8);
  transform: translateY(-50%);
}
.rt-input__hide-icon { font-size: 12px; }

/* Error wins over focus and active. */
.rt-input--error .rt-input__label,
.rt-input--error:focus-within .rt-input__label,
.rt-input--error.is-focus .rt-input__label { color: var(--red-1); }
.rt-input--error input, .rt-input--error textarea,
.rt-input--error input:active, .rt-input--error input:focus,
.rt-input--error input.is-focus,
.rt-input--error textarea:active, .rt-input--error textarea:focus { border-color: var(--red-1); }

/* ---------- Select ---------- */
/* The source writes two values literally instead of through the input tokens:
   the label is 14px (not var(--input-font-size)) and the select is 16px/14px. */
.rt-select { position: relative; }

.rt-select select {
  width: 100%;
  height: var(--input-height);
  padding: var(--s-4) 40px var(--s-4) var(--s-8);
  box-sizing: border-box;
  border: 1px solid var(--input-border-color);
  border-radius: var(--input-border-radius);
  background: var(--input-background-color);
  font-family: var(--primary-font);
  font-size: 16px;
  color: var(--input-text-color);
  cursor: pointer;
  text-overflow: ellipsis;
  white-space: nowrap;
}
@media (min-width: 768px) {
  .rt-select select { font-size: 14px; }
}
.rt-select select:hover { background-color: var(--gray-7); }
.rt-select select:active:not(:disabled), .rt-select select:focus:not(:disabled),
.rt-select select.is-focus { border-color: var(--input-focus-color); }
.rt-select select option { background: var(--white); color: var(--gray-0); }
.rt-select--with-icon select { padding-left: 40px; }

.rt-select__label {
  position: absolute;
  top: -9px;
  left: var(--s-8);
  padding: 0 var(--s-2);
  height: 18px;
  font-size: 14px;
  font-weight: 500;
  line-height: 18px;
  color: var(--gray-0);
  transition: all 0.2s;
}
.rt-select__label::after {
  content: '';
  position: absolute;
  top: 9px;
  right: 0;
  bottom: 0;
  left: 0;
  display: block;
  background-color: var(--white);
  width: 100%;
  height: 1px;
  z-index: 1;
}
.rt-select__label label { position: relative; z-index: 2; }

.rt-select__chevron {
  position: absolute;
  top: 50%;
  right: var(--s-16);
  transform: translateY(-50%);
  display: flex;
  pointer-events: none;
  font-size: 12px;
  color: var(--gray-0);
  cursor: pointer;
}
.rt-select__end-adornment {
  position: absolute;
  top: 50%;
  right: var(--s-32);
  transform: translateY(-50%);
  display: flex;
  pointer-events: none;
}
.rt-select__status {
  position: absolute;
  font-size: 12px;
  top: 50%;
  left: var(--s-16);
  transform: translateY(-50%);
  z-index: 1;
}
.rt-select:focus-within .rt-select__label,
.rt-select.is-focus .rt-select__label { color: var(--primary-accent); }
.rt-select:focus-within .rt-select__chevron,
.rt-select.is-focus .rt-select__chevron { color: var(--blue-1); }

.rt-select.is-disabled { pointer-events: none; color: var(--gray-5); }
.rt-select.is-disabled select,
.rt-select.is-disabled .rt-select__label,
.rt-select.is-disabled .rt-select__chevron { color: var(--gray-5); }

.rt-select--error .rt-select__label,
.rt-select--error .rt-select__chevron,
.rt-select--error:focus-within .rt-select__label,
.rt-select--error:focus-within .rt-select__chevron,
.rt-select--error.is-focus .rt-select__label,
.rt-select--error.is-focus .rt-select__chevron { color: var(--red-1); }
.rt-select--error select,
.rt-select--error select:active, .rt-select--error select:focus { border-color: var(--red-1); }

/* Helper text: Input and Select both render it as Typography body6 in red-1,
   below the field. No layout or spacing style exists in the source. */
.rt-helper-text { font: var(--t-body6); font-family: var(--primary-font); color: var(--red-1); }

/* ---------- Checkbox ---------- */
/* The native input is display:none; the label element is the control. */
/* Stack gap={8}, default column direction — Checkbox/index.tsx, the outer <Stack>. */
.rt-checkbox { width: 100%; display: flex; flex-direction: column; gap: var(--s-8); }
.rt-checkbox input { display: none; padding: 0; }
.rt-checkbox.is-disabled { pointer-events: none; opacity: 0.5; }

.rt-checkbox__label {
  min-height: var(--h-control-large);
  display: flex;
  padding: var(--s-12) var(--s-16);
  box-sizing: border-box;
  background: var(--white);
  border: 1px solid var(--input-border-color);
  border-radius: var(--input-border-radius);
  overflow: hidden;
  cursor: pointer;
}
.rt-checkbox__label:hover, .rt-checkbox__label.is-hover { background: var(--gray-6); }
.rt-checkbox__label.is-checked { background-color: var(--blue-3); border-color: var(--blue-1); }
.rt-checkbox__label.rt-checkbox__label--small { min-height: var(--h-control); padding: 6px var(--s-16); }
.rt-checkbox:not(.is-disabled).rt-checkbox--error .rt-checkbox__label { border-color: var(--red-1); }
/* Stack flex={1} direction="row" alignItems="center" gap={8} — Checkbox/index.tsx, inside <label>. */
.rt-checkbox__row { display: flex; flex-direction: row; align-items: center; gap: var(--s-8); flex: 1; }
/* Typography variant="h5" flex={1} — Checkbox/index.tsx. */
.rt-checkbox__title { font: var(--t-h5); font-family: var(--primary-font); flex: 1; }

/* ---------- CheckboxMinor ---------- */
/* Borderless compact variant. No hover, no checked background, no min-height. */
/* Stack gap={8} — CheckboxMinor/index.tsx, the outer <Stack>. */
.rt-checkbox-minor { width: 100%; display: flex; flex-direction: column; gap: var(--s-8); }
.rt-checkbox-minor input { display: none; padding: 0; }
.rt-checkbox-minor.is-disabled { pointer-events: none; opacity: 0.5; }

.rt-checkbox-minor__label {
  display: flex;
  box-sizing: border-box;
  border: 1px solid transparent;
  overflow: hidden;
  padding: var(--s-8);
  cursor: pointer;
}
.rt-checkbox-minor:not(.is-disabled).rt-checkbox-minor--error .rt-checkbox-minor__label { border-color: var(--red-1); }
/* Stack flex={1} direction="row" gap={8} — CheckboxMinor/index.tsx. Note: no alignItems,
   unlike Checkbox's row. */
.rt-checkbox-minor__row { display: flex; flex-direction: row; gap: var(--s-8); flex: 1; }
/* Typography variant="body4" color={Color.Gray3} flex={1} — CheckboxMinor/index.tsx.
   Deliberately quieter than Checkbox's h5. */
.rt-checkbox-minor__text { font: var(--t-body4); font-family: var(--primary-font); color: var(--gray-3); flex: 1; }

/* ---------- Radio (Input) ---------- */
.rt-radio { width: 100%; position: relative; }
.rt-radio input { display: none; padding: 0; }
.rt-radio.is-disabled { pointer-events: none; opacity: 0.5; }

.rt-radio__label {
  display: flex;
  box-sizing: border-box;
  background: var(--white);
  border: 1px solid var(--input-border-color);
  border-radius: var(--input-border-radius);
  overflow: hidden;
  cursor: pointer;
}
.rt-radio__label:hover, .rt-radio__label.is-hover { background: var(--gray-6); }
.rt-radio__label.is-checked { background-color: var(--blue-3); border-color: var(--blue-1); }
.rt-radio__label.is-checked .rt-radio__inner-circle { opacity: 1; }
.rt-radio:not(.is-disabled).rt-radio--error .rt-radio__label { border-color: var(--red-1); }

/* Only a string label gets the row geometry; a JSX label is laid out by the caller. */
.rt-radio__label--string {
  min-height: var(--h-control-large);
  padding: var(--s-12) var(--s-16);
  gap: var(--s-8);
  justify-content: center;
  align-items: center;
}
.rt-radio__body { flex: 1; }
/* 14/24/600 written literally in the source — the h5 metrics. */
.rt-radio__title { color: var(--gray-0); font-size: 14px; line-height: 24px; font-weight: 600; margin: 0; }
/* Typography variant="body6" color={Color.Gray2} — Radio/Input/index.tsx, one per
   description line. `display: block` is INFERRED: Typography renders a block element,
   which is what keeps a multiline description array on separate lines; the variant's
   own stylesheet does not declare it. */
.rt-radio__description { display: block; font: var(--t-body6); font-family: var(--primary-font); color: var(--gray-2); }
/* Margin from .icon in index.module.pcss. The blue-1 is NOT in the stylesheet — it is
   color={Color.Blue1} on the FontAwesomeIcon in Radio/Input/index.tsx. */
.rt-radio__icon { margin: 0 18px 0 10px; color: var(--blue-1); }

.rt-radio__recommended {
  position: absolute;
  top: 0;
  right: 0;
  padding: var(--s-2) var(--s-4);
  border-radius: 0 var(--input-border-radius) 0 var(--r-3);
  background-color: var(--blue-1);
  /* color: var(--white) from .recommended in Radio/Input/index.module.pcss,
     right after background-color. Typography variant="body6" \u2014 Radio/Input/index.tsx. */
  color: var(--white);
  font: var(--t-body6);
  font-family: var(--primary-font);
}

.rt-radio__outer-circle {
  box-sizing: border-box;
  border: 1px solid var(--gray-0);
  border-radius: 12px;
  flex-shrink: 0;
  height: 12px;
  width: 12px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
}
.rt-radio__inner-circle {
  background: var(--gray-0);
  border-radius: 6px;
  height: 6px;
  width: 6px;
  opacity: 0;
}

/* ---------- Radio LargeButton ---------- */
/* Unchecked is blue-1; checked is green-1 + scale(1.02) and drops the border.
   The source keys the checked rule off the adjacent-sibling selector
   input:checked + label — which depends on RadioGroup's markup (the file
   says as much) — so this twin uses an explicit class instead. */
.rt-radio-large {
  background: var(--blue-1);
  text-align: center;
  padding: var(--s-24) var(--s-4);
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
.rt-radio-large.is-checked { background: var(--green-1); border: none; transform: scale(1.02); }
.rt-radio-large__icon {
  height: 60px;
  width: 60px;
  background-color: var(--icon-color, var(--green-1));
  border-radius: 60px;
  border: 2px solid var(--white);
  display: flex;
  align-items: center;
  justify-content: center;
  /* color={Color.White} on the FontAwesomeIcon — Radio/LargeButton/index.tsx. */
  color: var(--white);
  /* size="xl" on the FontAwesomeIcon — Radio/LargeButton/index.tsx. 1.5em is
     Font Awesome's own value for xl, not something in this repo. */
  font-size: 1.5em;
  box-sizing: border-box;
}
/* .labelText has no rule in the source stylesheet; the treatment comes from
   Typography variant="h2" color={Color.White} — Radio/LargeButton/index.tsx. */
.rt-radio-large__text { font: var(--t-h2); font-family: var(--primary-font); color: var(--white); }

/* ---------- RadioGroup ---------- */
/* RadioGroup has NO stylesheet of its own. All three rules below come from
   RadioGroup/index.tsx: outer <Stack gap={8}>, Typography variant="h5" for the
   label, and inner <Stack direction={row ? 'row' : 'column'} gap={16}>. */
.rt-radio-group { display: flex; flex-direction: column; gap: var(--s-8); }
.rt-radio-group__label { font: var(--t-h5); font-family: var(--primary-font); }
.rt-radio-group__items { display: flex; flex-direction: column; gap: var(--s-16); }
.rt-radio-group__items--row { flex-direction: row; }

/* ---------- SelectorButton ---------- */
/* The 7px radius is written literally in the source, not var(--border-radius). */
.rt-selector {
  min-height: var(--h-control-large);
  padding: var(--s-8);
  box-sizing: border-box;
  cursor: pointer;
  background-color: var(--gray-7);
  border: 1px solid var(--gray-5);
  border-radius: 7px;
  /* Stack direction="row" gap={8} alignItems="center" — SelectorButton/index.tsx,
   the outer <Stack>. Not in index.module.pcss. */
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--s-8);
}
.rt-selector:hover:not(.rt-selector--non-interactive),
.rt-selector.is-hover:not(.rt-selector--non-interactive) { background-color: var(--gray-6); }
.rt-selector--non-interactive { cursor: default; }
/* !important mirrors the source: it has to beat the :hover background. */
.rt-selector--active {
  border-color: var(--primary-accent);
  background-color: var(--blue-3) !important;
}
.rt-selector--active svg, .rt-selector--active .rt-selector__start-adornment,
.rt-selector--active .rt-selector__end-adornment { color: var(--primary-accent); }
.rt-selector--error {
  border-color: var(--red-1);
  background-color: var(--red-2) !important;
}
.rt-selector--error svg, .rt-selector--error .rt-selector__start-adornment,
.rt-selector--error .rt-selector__end-adornment { color: var(--red-1); }
.rt-selector--disabled { pointer-events: none; opacity: 0.5; }
.rt-selector--dashed { border-style: dashed; }
.rt-selector--white { background-color: var(--white); }

/* Margin from .startAdornment in index.module.pcss. The gray-0 is NOT in the
   stylesheet — it is color={Color.Gray0} on the FontAwesomeIcon in
   SelectorButton/index.tsx, and startAdornmentProps can override it. */
.rt-selector__start-adornment { margin: 0 18px 0 10px; color: var(--gray-0); }
.rt-selector__start-image {
  width: 96px;
  /* DEVIATION: the source sets height: 100% AND align-self: stretch. The two
     conflict — a percentage height is not `auto`, so stretch never applies, and
     the percentage resolves against the row's indefinite height, collapsing the
     well to 0. `auto` lets the declared stretch do the work the source intends. */
  height: auto;
  overflow: hidden;
  flex-shrink: 0;
  border-top-left-radius: 7px;
  border-bottom-left-radius: 7px;
  align-self: stretch;
  position: relative;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}
/* Absolute + inset so a tall image cannot stretch the row. */
.rt-selector__start-image img {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  width: 100%;
  height: 100%;
  /* DEVIATION: not in the source, which sets position, inset, width and height only.
     Without it a 100%/100% image is distorted to the well's aspect ratio; vehicle
     photos are the main use, so cover is almost certainly the intent. Drop this line
     for a literal mirror. */
  object-fit: cover;
}
/* Stack flex={1} overflow="hidden" — SelectorButton/index.tsx (default column). */
.rt-selector__body { flex: 1; overflow: hidden; display: flex; flex-direction: column; }
/* Typography variant="display3" — SelectorButton/index.tsx. The margin-bottom is
   display3's own trailing 4px, from Typography/index.module.pcss. */
.rt-selector__label { font: var(--t-display3); font-family: var(--primary-font); margin-bottom: var(--t-display3-margin-bottom); }
/* Typography variant="body6" — SelectorButton/index.tsx, string descriptions only. */
.rt-selector__description { font: var(--t-body6); font-family: var(--primary-font); }
/* .endAdornment in index.module.pcss sets display, justify, align, width and
   font-size. No colour: color={Color.Gray0} is on the FontAwesomeIcon INSIDE it and
   applies only when endAdornment is an IconDefinition — a JSX element gets no colour,
   so a rule here would be wrong. */
.rt-selector__end-adornment {
  display: flex;
  justify-content: center;
  align-items: center;
  width: 32px;
  font-size: 12px;
}

/* ---------- FormProgress ---------- */
.rt-progress {
  padding: var(--tray-body-padding) var(--tray-body-padding) 0;
  box-sizing: border-box;
  width: 100%;
}
.rt-progress__bar {
  border-radius: 6px;
  background-color: var(--gray-6);
  display: flex;
  gap: 2px;
  padding: 0 2px;
  box-sizing: border-box;
  width: 100%;
  align-items: center;
  overflow: visible;
}
.rt-progress__step {
  flex-grow: 1;
  height: 4px;
  background-color: var(--gray-5);
  border-radius: 2px;
  transition: background-color 0.2s ease;
}
.rt-progress__step--completed { background-color: var(--blue-1); }
.rt-progress__step--active {
  background: linear-gradient(70deg, var(--blue-1) 0%, var(--blue-1-shimmer) 50%, var(--blue-1) 100%);
  background-size: 200% 100%;
  animation: rt-progress-shimmer 4s infinite linear;
}
.rt-progress--large .rt-progress__step { height: 8px; border-radius: 3px; }
/* The source's own keyframes, distinct from the Pill shimmer's 0%→200% sweep. */
@keyframes rt-progress-shimmer {
  0% { background-position: -200% 0; }
  100% { background-position: 200% 0; }
}
@media (prefers-reduced-motion: reduce) {
  .rt-progress__step--active { animation: none !important; }
}

/* ---------- Spinner ---------- */
/* Not a border-based ring: a conic-gradient quadrant over a full-circle
   conic-gradient, punched out by a radial mask. The gradients and mask are
   inline in Spinner/index.tsx (they depend on the color and thickness props);
   only the rules below are in index.module.pcss. */
.rt-spinner {
  display: inline-block;
  border-radius: 50%;
  position: relative;
  box-sizing: border-box;
  animation: rt-spin 0.9s linear infinite;
  vertical-align: middle;
  line-height: 0;
}
@keyframes rt-spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) {
  .rt-spinner { animation: none !important; }
}

/* ---------- Skeleton ---------- */
/* Skeleton has no stylesheet: the 3px radius and --loading-bg are inline in
   Skeleton/index.tsx, and height/width default to 100%. */
.rt-skeleton { border-radius: var(--r-3); background: var(--loading-bg); }

/* ---------- Card shell (Module, ModuleCta, FormField) ----------
   The source repeats this recipe in three files with no shared class:
   Module/index.module.pcss, ModuleCta/index.module.pcss and
   FormFieldArray/FormField/index.module.pcss. One shell here with modifiers.
   Two real differences, NOT normalised away:
     - the header's bottom border is --gray-6 in Module but --gray-5 in FormField
     - the header title is h5 in Module and ModuleCta, but h4 in FormField
   ModuleCta is the shell with no header or content: the 48px height and the
   0 16px padding sit on the box itself. */
.rt-card {
  background: var(--white);
  box-sizing: border-box;
  border: 1px solid var(--gray-5);
  border-radius: var(--r-5);
}
/* Stack alignItems="center" justifyContent="space-between" direction="row" —
   Module/index.tsx and FormField/index.tsx. */
.rt-card__header {
  box-sizing: border-box;
  height: var(--h-control);
  padding: 0 var(--s-16);
  border-bottom: 1px solid var(--gray-6);
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}
.rt-card__header--strong-rule { border-bottom-color: var(--gray-5); }
/* Typography variant="h5" — Module/index.tsx, ModuleCta/index.tsx. */
.rt-card__title { font: var(--t-h5); font-family: var(--primary-font); }
/* Typography variant="h4" — FormField/index.tsx. */
.rt-card__title--h4 { font: var(--t-h4); font-family: var(--primary-font); }
.rt-card__content { padding: var(--s-16); }
/* Stack gap={16} on the content — FormField/index.tsx only. */
.rt-card__content--stack { display: flex; flex-direction: column; gap: var(--s-16); }
/* ModuleCta: Stack alignItems="center" justifyContent="space-between"
   direction="row" — ModuleCta/index.tsx. */
.rt-card--cta {
  height: var(--h-control);
  padding: 0 var(--s-16);
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}

/* ModuleStatus: a 24x24 single-cell grid stacking two SVGs. */
.rt-module-status {
  display: grid;
  justify-content: center;
  grid-template-columns: 24px;
  grid-template-rows: 24px;
  align-items: center;
  justify-items: center;
}
.rt-module-status > * { grid-column: 1; grid-row: 1; position: relative; }
.rt-module-status > *:last-child { z-index: 1; }
.rt-module-status--incomplete { align-items: flex-start; justify-items: flex-end; }
.rt-module-status--default { align-items: flex-start; }
.rt-module-status--default > *:last-child { left: 1px; }

/* ---------- ActionText ---------- */
/* Typography variant="h6" color={Color.Blue1} — ActionText/index.tsx. */
.rt-action-text {
  cursor: pointer;
  display: inline-block;
  vertical-align: middle;
  width: fit-content;
  font: var(--t-h6);
  font-family: var(--primary-font);
  color: var(--blue-1);
}

/* ---------- Divider ---------- */
.rt-divider { height: 1px; width: 100%; background-color: var(--gray-6); }

/* ---------- InfoBox ---------- */
/* Note --border-radius, not --input-border-radius: not dealer-facing. */
.rt-infobox {
  padding: var(--s-8);
  border: 1px solid var(--blue-1);
  border-radius: var(--border-radius);
}
/* Typography h5 then body3, both color={Color.Blue1} — InfoBox/index.tsx. */
.rt-infobox__primary { display: block; font: var(--t-h5); font-family: var(--primary-font); color: var(--blue-1); }
.rt-infobox__secondary { display: block; font: var(--t-body3); font-family: var(--primary-font); color: var(--blue-1); }

/* ---------- Disclaimer ---------- */
/* Typography variant="body4" color={Color.Gray3} — Disclaimer/index.tsx.
   align-content/flex-grow are from index.module.pcss: the disclaimer is a flex
   child that absorbs slack and pins its text to the bottom of a form step. */
.rt-disclaimer {
  align-content: flex-end;
  flex-grow: 1;
  font: var(--t-body4);
  font-family: var(--primary-font);
  color: var(--gray-3);
}
.rt-disclaimer a { color: var(--blue-1); }

/* ---------- Chip ---------- */
/* Lives at components/app/Chip, not components/common. */
.rt-chip {
  align-items: center;
  background: none;
  border: 1px solid var(--gray-5);
  border-radius: 8px;
  color: inherit;
  display: inline-flex;
  gap: var(--s-8);
  padding: var(--s-8) var(--s-12);
  text-align: left;
}
/* Typography variant="body3" component="span" — Chip/index.tsx. */
.rt-chip__label { font: var(--t-body3); font-family: var(--primary-font); }
.rt-chip--removable { cursor: pointer; }
.rt-chip--removable:hover, .rt-chip--removable.is-hover { border-color: var(--gray-3); }

/* ---------- ValueBox ----------
   OFF-PALETTE. #007aff, #3f9bff, #005abd, #e5f2ff and the #007affcc glow are
   literals in ValueBox/index.module.pcss and appear in no token file. The same
   blue family recurs on date day buttons, payment options and the range and
   credit-score sliders. A TOKENISATION CANDIDATE, not a twin deviation:
   copied verbatim because the code is the source of truth. */
.rt-valuebox {
  max-width: 236px;
  box-sizing: border-box;
  border-radius: 10px;
  min-height: var(--h-control-large);
  background: radial-gradient(100% 685.61% at 100% 52.63%, #007aff 0%, #3f9bff 45.83%, #005abd 100%),
    linear-gradient(0deg, #e5f2ff, #e5f2ff);
  border: 1px solid var(--blue-2);
  box-shadow: 0px 0px 32px 0px #007affcc;
  width: 100%;
  padding: var(--s-16) 0;
  z-index: 1;
  /* Stack alignItems="center" justifyContent="center" — ValueBox/index.tsx. */
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}
/* Typography h3 / h6 / h4, all color={Color.White} — ValueBox/index.tsx. */
.rt-valuebox__amount { font: var(--t-h3); font-family: var(--primary-font); color: var(--white); }
.rt-valuebox__description { font: var(--t-h6); font-family: var(--primary-font); color: var(--white); }
.rt-valuebox__pending { font: var(--t-h4); font-family: var(--primary-font); color: var(--white); }

/* ---------- Container (the step frame) ---------- */
/* Every form screen in the widget renders through this. Only four rules are in
   Container/index.module.pcss; the rest of the geometry is Stack props in
   Container/index.tsx, cited per rule below. */

/* Stack flex={1} gap={8} (default column direction) — Container/index.tsx.
   overflow-x: clip is from index.module.pcss, with a source comment: it stops a
   horizontal scrollbar during the slide animation without clipping box shadows. */
.rt-step-container {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: var(--s-8);
  overflow-x: clip;
}
.rt-step-container--blurred { filter: blur(4px); pointer-events: none; }

/* size="large" injects these four as an inline style object on the container
   element — Container/index.tsx, largeStyleProps. Declared here on an attribute
   scope rather than a class, because they are a scoped override of existing
   tokens (not new tokens and not a theme): regular steps set no attribute and
   keep the :root values, exactly as the source passes style={undefined}. */
[data-rt-step-size="large"] {
  --input-height: 60px;
  --input-font-size-mobile: 20px;
  --input-font-size: 20px;
  --input-start-adornment-size: 16px;
}

/* MotionStack flex={1} gap={16} overflow="auto" — Container/index.tsx.
   padding is from .stepContent in index.module.pcss. */
.rt-step-content {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: var(--s-16);
  overflow: auto;
  padding: var(--tray-body-padding);
}

/* Stack direction="row" gap={8} — Container/index.tsx.
   padding is from .buttons: top 0, sides and bottom var(--tray-body-padding). */
.rt-step-buttons {
  display: flex;
  flex-direction: row;
  gap: var(--s-8);
  padding-top: 0;
  padding-left: var(--tray-body-padding);
  padding-right: var(--tray-body-padding);
  padding-bottom: var(--tray-body-padding);
}

/* .withoutPadding is applied to BOTH .stepContent and .buttons, and only on one
   step: stepId === FinanceStepId.CalculatorPreview — Container/index.tsx. */
.rt-step-content--without-padding, .rt-step-buttons--without-padding { padding: 0; }

/* .nextButton in StepContainer/index.module.pcss — the whole file is this one rule.
   Back and Skip size themselves; Continue/Submit takes the remaining width. */
.rt-step-next { flex: 1; }

/* ---------- Header ---------- */
/* Stack direction="column" with no gap prop — Header/index.tsx, so the gap is 0
   and the type's own line-heights carry the spacing. */
.rt-header { display: flex; flex-direction: column; }
/* .minHeight is applied unless withoutMinHeight — Header/index.tsx. */
.rt-header--min-height { min-height: 88px; }
/* .large from Header/index.module.pcss, !important included: it has to beat the
   inline gap Stack writes. Note the gap gets SMALLER on wider screens. */
.rt-header--large { gap: var(--s-16) !important; margin-bottom: var(--s-16); }
@media (min-width: 768px) {
  .rt-header--large { gap: var(--s-8) !important; }
}
/* Variants and alignment from StepStyle in const/defaults/step.ts:
   regular = h3 + body1, left; large = display1 + display2, centred. */
.rt-header__title { font: var(--t-h3); font-family: var(--primary-font); text-align: left; }
.rt-header__subtitle { font: var(--t-body1); font-family: var(--primary-font); text-align: left; }
.rt-header--large .rt-header__title { font: var(--t-display1); text-align: center; }
.rt-header--large .rt-header__subtitle { font: var(--t-display2); text-align: center; }

/* Step slide: the leftRight preset from const/animations.ts, applied by
   MotionStack. withAnimation={false} passes transition={{duration: 0}}. */
.rt-step-content--enter-right { animation: rt-slide-in-right var(--motion-left-right-duration) var(--motion-left-right-ease); }
.rt-step-content--enter-left { animation: rt-slide-in-left var(--motion-left-right-duration) var(--motion-left-right-ease); }
@media (prefers-reduced-motion: reduce) {
  .rt-step-content--enter-right, .rt-step-content--enter-left { animation: none; }
}

/* ================= Shared step screens =================
   src/lead-forms/common/steps/*. Only the steps that HAVE an index.module.pcss
   contribute CSS here; the rest are pure composition of the locked atoms and add
   nothing. Step titles are not in the step files: StepContainer reads them from
   the stepper's step config, so the twin passes them as props. */

/* ---------- Address ---------- */
/* Address/index.module.pcss — .address, .country. The 3-column grid is what gives
   every address variant its shape; children claim spans from the country file. */
.rt-step-address {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  row-gap: var(--s-16);
  column-gap: var(--s-8);
}
.rt-step-address__country { grid-column: span 3; }

/* Address/US/index.module.pcss */
.rt-address-us__street { grid-column: span 2; position: relative; }
.rt-address-us__street-input { width: 100%; }
.rt-address-us__phone { grid-column: span 3; }

/* Address/CA/index.module.pcss — a different span map, not a different grid:
   street spans 3, unit 2, city 1, province 2, postal code 1. */
.rt-address-ca__street { grid-column: span 3; position: relative; }
.rt-address-ca__unit { grid-column: span 2; }
.rt-address-ca__city { grid-column: span 1; }
.rt-address-ca__province { grid-column: span 2; }
.rt-address-ca__postal-code { grid-column: span 1; }

/* Google Places autocomplete dropdown. Identical in the US and CA files.
   Note the off-token values: 8px radius (not --r-7), --gray-4 border (not --gray-5),
   and a one-off shadow. */
.rt-address-suggestions {
  position: absolute;
  top: calc(100% + var(--s-4));
  left: 0;
  right: 0;
  z-index: 3;
  display: flex;
  flex-direction: column;
  border: 1px solid var(--gray-4);
  border-radius: 8px;
  background: var(--white);
  box-shadow: 0 8px 20px rgb(19 31 57 / 12%);
  max-height: 220px;
  overflow-y: auto;
}
.rt-address-suggestion {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  width: 100%;
  padding: 10px var(--s-12);
  border: none;
  border-bottom: 1px solid var(--gray-5);
  background: var(--white);
  text-align: left;
  cursor: pointer;
  font-family: var(--primary-font);
}
.rt-address-suggestion:last-child { border-bottom: none; }
.rt-address-suggestion:hover,
.rt-address-suggestion[data-active='true'],
.rt-address-suggestion:focus-visible { background: var(--blue-3); }
.rt-address-suggestion__primary { color: var(--gray-0); font-size: 14px; }
.rt-address-suggestion__secondary { color: var(--gray-2); font-size: 12px; }
.rt-address-suggestion-status { padding: 10px var(--s-12); color: var(--gray-2); font-size: 12px; }

/* AddressVerification/index.module.pcss — the whole file is this one rule. The
   unverified address is shown as a Radio purely as a display surface. */
.rt-address-unverified { pointer-events: none; }

/* ---------- PersonalInformation ---------- */
/* PersonalInformation/index.module.pcss — the whole file. A 65/35 split inside a
   Stack direction="row" gap={8}, so DL number and DL state share one row. */
.rt-pi__dl-number { width: 65%; }
.rt-pi__dl-state { width: 35%; }

/* ---------- Schedule ---------- */
/* Schedule/index.module.pcss. The same card recipe as Module (white, 1px gray-5,
   5px radius, 48px header, 16px content) written out again locally — a fourth
   copy of that recipe in the codebase. */
.rt-schedule__module {
  height: 100%;
  background: var(--white);
  box-sizing: border-box;
  border: 1px solid var(--gray-5);
  border-radius: var(--r-5);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.rt-schedule__title {
  flex-shrink: 0;
  box-sizing: border-box;
  height: 48px;
  padding: 0 var(--s-16);
  border-bottom: 1px solid var(--gray-6);
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
}
.rt-schedule__content { flex: 1; overflow-y: auto; padding: var(--s-16); }
/* .times reshapes the RadioGroup's rows from the outside, all !important: 48px
   instead of 64px, 0/16 padding, a 7px radius, a 16px gap and weight 500. */
.rt-schedule__times .rt-radio__label {
  align-items: center !important;
  gap: var(--s-16);
  border-radius: var(--r-7) !important;
  min-height: 48px !important;
  padding: 0 var(--s-16) !important;
}
.rt-schedule__times .rt-radio__label p { font-weight: 500 !important; }

/* Schedule/TimeSlotLabel/index.module.pcss */
.rt-time-slot { width: 100%; display: flex; flex-direction: row; align-items: center; gap: var(--s-8); }
.rt-time-slot__icon { flex-shrink: 0; color: var(--blue-1); }
.rt-time-slot__label { flex: 1; font: var(--t-body4); font-family: var(--primary-font); color: var(--gray-0); }
/* tabular-nums so the 5-minute hold countdown does not jitter as it ticks. */
.rt-time-slot__countdown {
  flex-shrink: 0;
  font-variant-numeric: tabular-nums;
  font: var(--t-body4);
  font-family: var(--primary-font);
  color: var(--blue-1);
}

/* ---------- SalespersonAndMessage ---------- */
/* SalespersonAndMessage/index.module.pcss — the whole file. Lets the message
   textarea grow to fill whatever height the step has left. */
.rt-message-input { display: flex; flex: 1; }
.rt-message-input-container { display: flex; flex-direction: column; flex: 1; }
.rt-message-input-container textarea { flex: 1; }

/* ---------- Vehicle ---------- */
/* Vehicle/index.module.pcss — the mode switcher. Overrides the RadioGroup's 16px
   gap down to 8px and shrinks the row padding, because these are tabs, not choices. */
.rt-vehicle__radio { gap: var(--s-8) !important; }
.rt-vehicle__radio .rt-radio__label { align-items: center; padding-right: var(--s-8); }
.rt-vehicle__radio .rt-vehicle__label { padding: var(--s-8) !important; }
@media (min-width: 768px) {
  .rt-vehicle__radio .rt-vehicle__label { padding: var(--s-12) var(--s-8) !important; }
}

/* Vehicle/VIN/index.module.pcss — the decoded-vehicle confirmation row. Note it
   uses var(--border-radius), unlike SelectorButton's literal 7px. */
.rt-vin__vehicle {
  height: var(--input-height);
  padding: var(--s-16) var(--s-12) var(--s-16) var(--s-16);
  box-sizing: border-box;
  background-color: var(--gray-6);
  border-radius: var(--border-radius);
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--s-8);
}

/* Vehicle/Search/index.module.pcss. More off-token values: 12px radius and a
   --gray-4 border on the list, --gray-6 on hover, a 120ms transition. */
.rt-search__meta { margin-top: -8px; }
.rt-search__status-row { display: flex; flex-direction: row; gap: var(--s-8); align-items: center; }
.rt-search__status-text { margin: 0; }
.rt-search__suggestions {
  max-height: 280px;
  overflow: auto;
  border: 1px solid var(--gray-4);
  border-radius: 12px;
  background: var(--white);
}
.rt-search__suggestion {
  width: 100%;
  padding: var(--s-12) var(--s-16);
  border: 0;
  border-bottom: 1px solid var(--gray-5);
  background: transparent;
  text-align: left;
  cursor: pointer;
  transition: background-color 120ms ease-in-out;
  font: var(--t-body3);
  font-family: var(--primary-font);
  color: var(--black);
}
.rt-search__suggestion:last-child { border-bottom: 0; }
.rt-search__suggestion:hover, .rt-search__suggestion:focus-visible { background: var(--gray-6); outline: none; }

/* ================= Tray shell and launcher =================
   src/components/app/{Tray,Tray/TrayHeader,Tray/FooterNavigation,TriggerButton,
   ChatTriggerPreview}. The chrome the step frame lives in. */

/* ---------- Tray ---------- */
/* Tray/index.module.pcss. The two max-height declarations are deliberate and
   carry a source comment: dvh follows the iOS Safari visual viewport so the tray
   shrinks when the URL bar moves and the close button stays reachable; the vh
   line is the fallback for browsers that ignore dvh. */
.rt-tray {
  position: absolute;
  width: 100%;
  max-width: var(--tray-max-width);
  right: var(--s-32);
  bottom: var(--s-32);
  border-radius: var(--r-15);
  min-height: 600px;
  max-height: 100vh;
  max-height: 100dvh;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background-color: var(--gray-7);
  transition: var(--transition-all);
  box-shadow: var(--glass-shadow);
  /* height comes from the tsx: var(--tray-default-height), or 80vh when large. */
  height: var(--tray-default-height);
}
.rt-tray__body { flex: 1; display: flex; flex-direction: column; overflow: auto; }

/* Mobile: bottom-docked and centred by transform, not by left/right.
   The tsx additionally zeroes the two bottom corner radii at this size. */
@media screen and (max-width: 767px) {
  .rt-tray {
    bottom: 0;
    right: 50%;
    transform: translateX(50%);
  }
}
.rt-tray--mobile {
  bottom: 0;
  right: 50%;
  transform: translateX(50%);
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

/* modal.layout === 'large' && screenSize !== 'mobile' — every one of these is an
   inline style in Tray/index.tsx, not a class. Never applies on mobile. */
.rt-tray--large {
  height: 80vh;
  width: 80vw;
  max-width: 80vw;
  min-height: 80vh;
  max-height: 80vh;
  top: 50%;
  left: 50%;
  right: auto;
  bottom: auto;
  transform: translate(-50%, -50%);
}

/* ---------- TrayHeader ---------- */
/* TrayHeader/index.module.pcss. Stack direction="row" gap={8} alignItems="center"
   — TrayHeader/index.tsx. */
.rt-tray-header {
  height: 48px;
  padding: 0 var(--s-8);
  box-shadow: 0px 0px 16px rgba(30, 30, 30, 0.16);
  background: var(--white);
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--s-8);
  box-sizing: border-box;
  flex-shrink: 0;
}
/* .vehicle — note it also removes the left padding, so SelectedVehicle's image
   can sit flush against the tray edge. */
.rt-tray-header--vehicle { height: 80px; padding-left: 0; }
/* Stack gap={8} flex={1} direction="row" alignItems="center" — TrayHeader/index.tsx. */
.rt-tray-header__content {
  min-width: 0;
  overflow: hidden;
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: var(--s-8);
  flex: 1;
}
.rt-tray-header__close { flex-shrink: 0; }
/* TrayCommonHeader/index.module.pcss */
.rt-tray-header__logo { height: 100%; max-height: 32px; max-width: 132px; object-fit: contain; }
/* Typography variant="h5" flex={1} — TrayCommonHeader and TrayHeaderGoBack. */
.rt-tray-header__title { font: var(--t-h5); font-family: var(--primary-font); flex: 1; }

/* ---------- FooterNavigation ---------- */
/* FooterNavigation/index.module.pcss. Stack (default column) — index.tsx. */
.rt-footer-nav {
  background-color: var(--white);
  border-top: 1px solid var(--gray-6);
  box-shadow: 0px 0px 25px rgba(0, 0, 0, 0.05);
  box-sizing: border-box;
  flex-shrink: 0;
  width: 100%;
  display: flex;
  flex-direction: column;
}
/* Stack direction="row" — index.tsx. Collapses to 0 while the chat input is
   focused on mobile (chatInputFocused && screenSize === 'mobile'). */
.rt-footer-tabs {
  box-sizing: border-box;
  flex-shrink: 0;
  height: 76px;
  width: 100%;
  transition: height 0.15s ease-in-out;
  display: flex;
  flex-direction: row;
}
.rt-footer-tabs--minimized { height: 0; overflow: hidden; }

/* The non-retailing alternative: the whole strip becomes one Done button.
   Stack direction="row" gap={16} — index.tsx. */
.rt-footer-done {
  box-sizing: border-box;
  padding: var(--s-16);
  width: 100%;
  display: flex;
  flex-direction: row;
  gap: var(--s-16);
}
.rt-footer-done .rt-btn { width: 100%; }

/* Each tab is an ActionBox. Hover greys to gray-2; the active tab is blue-1. */
.rt-footer-tab {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  color: var(--gray-0);
  cursor: pointer;
  width: 100%;
  transition: color 0.2s ease-in-out;
  background: none;
  border: 0;
  font-family: var(--primary-font);
}
.rt-footer-tab:hover { color: var(--gray-2); }
.rt-footer-tab--active { color: var(--blue-1); }
.rt-footer-tab__icons { height: 24px; position: relative; }
/* The badge is centred on the icon box's origin by a -50%/-50% translate, so it
   sits over the icon's top-left corner. */
.rt-footer-tab__badge { position: absolute; transform: translate(-50%, -50%); z-index: 1; }
/* 14/24/600 written literally — the h5 metrics inlined a third time (Radio's
   title and Container's buttons do the same). Not tokenized in the source. */
.rt-footer-tab__title { font-size: 14px; line-height: 24px; font-weight: 600; margin: 0; }
/* FooterNextStep/index.module.pcss — the whole file is this one rule. */
.rt-footer-next-step { margin: var(--s-16) var(--s-16) var(--s-8); }

/* ---------- TriggerButton ---------- */
/* TriggerButton/index.module.pcss. Colours, radius, position, margin, z-index and
   scale are ALL dealer config (display.trigger) applied inline in the tsx; the
   class owns only the box and the reveal. Padding is 0 8px, or 0 8px 0 0 when the
   icon shows. */
.rt-trigger {
  box-shadow: 0px 2px 32px 0px #00000029;
  border-width: 1px;
  border-style: solid;
  height: 32px;
  width: auto;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  line-height: 24px;
  cursor: pointer;
  font-family: var(--primary-font);
  animation: rt-reveal-trigger 180ms ease-out both;
  /* Defaults from const/defaults/widgetConfig.ts → display.trigger. */
  background-color: var(--gray-0);
  border-color: var(--white);
  color: var(--white);
  border-radius: 7px;
  padding: 0 var(--s-8) 0 0;
}
.rt-trigger--no-icon { padding: 0 var(--s-8); }
/* unreadMessages && !isPreviewTriggerActive — red-2 fill, red-1 icon and label. */
.rt-trigger--unread { background-color: var(--red-2); border-color: var(--red-1); color: var(--red-1); }
.rt-trigger__icon { width: 32px; height: 32px; display: flex; align-items: center; justify-content: center; }
@media (prefers-reduced-motion: reduce) {
  .rt-trigger { animation: none; }
}
@keyframes rt-reveal-trigger {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ---------- ChatTriggerPreview ---------- */
/* ChatTriggerPreview/index.module.pcss. Width, height, radius, background, accent
   and position are dealer config (display.chatPreview); defaults below. */
.rt-chat-preview {
  box-shadow: var(--glass-shadow);
  overflow: hidden;
  max-width: calc(100vw - var(--s-32));
  cursor: pointer;
  display: flex;
  flex-direction: column;
  animation: rt-reveal-chat-preview 180ms ease-out both;
  /* display.chatPreview defaults */
  width: 488px;
  height: 192px;
  border-radius: var(--r-15);
  background-color: var(--gray-7);
}
@media (prefers-reduced-motion: reduce) {
  .rt-chat-preview { animation: none; }
}
/* Stack direction="row" justifyContent="space-between" alignItems="center". Note
   the asymmetric padding: 24px on the left, 16px on the right. */
.rt-chat-preview__header {
  position: relative;
  min-height: 40px;
  padding: 0 var(--s-16) 0 var(--s-24);
  border-bottom: 1px solid var(--gray-6);
  background-color: var(--white);
  overflow: hidden;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  box-sizing: border-box;
}
/* The auto-dismiss timer is the header's own background draining left to right —
   a scaleX transform, not a width animation. animationDuration is set inline
   from activeTriggerPreviewAutoDismissMs (default 10000). */
.rt-chat-preview__timer {
  position: absolute;
  inset: 0;
  background-color: var(--gray-6);
  transform-origin: left;
  animation-name: rt-preview-timer;
  animation-timing-function: linear;
  animation-fill-mode: forwards;
  animation-duration: 10000ms;
}
/* Typography variant="h6" color={accentColor || Color.Black} — index.tsx. */
.rt-chat-preview__title { position: relative; z-index: 1; font: var(--t-h6); font-family: var(--primary-font); color: var(--black); }
.rt-chat-preview__close { position: relative; z-index: 1; margin-right: -8px; }
/* Stack gap={8}. The 40px subtracted here is the header's min-height. */
.rt-chat-preview__body {
  height: calc(100% - 40px);
  padding: var(--s-16) var(--s-32) var(--s-24);
  display: flex;
  flex-direction: column;
  gap: var(--s-8);
  box-sizing: border-box;
}
/* Stack gap={4}. The Module recipe again, but with a gray-6 border and 7px. */
.rt-chat-preview__card {
  padding: var(--s-16);
  border: 1px solid var(--gray-6);
  border-radius: var(--r-7);
  background-color: var(--white);
  display: flex;
  flex-direction: column;
  gap: var(--s-4);
}
/* Typography variant="body4" color={Color.Gray0} — index.tsx. */
.rt-chat-preview__assistant { font: var(--t-body4); font-family: var(--primary-font); color: var(--gray-0); }
/* Typography variant="body3"; pre-line so a welcome message keeps its newlines. */
.rt-chat-preview__message { white-space: pre-line; font: var(--t-body3); font-family: var(--primary-font); color: var(--black); }
/* Typography variant="caption" color={Color.Gray2} — introductionSubtitle. */
.rt-chat-preview__subtitle { font: var(--t-caption); font-family: var(--primary-font); color: var(--gray-2); }
@keyframes rt-preview-timer {
  from { transform: scaleX(1); }
  to { transform: scaleX(0); }
}
@keyframes rt-reveal-chat-preview {
  from { opacity: 0; transform: translateY(8px); }
  to { opacity: 1; transform: translateY(0); }
}

/* ================= Finished-screen pieces =================
   src/components/common/{SelectedVehicle,EditSection},
   src/components/app/{Toast,OverlayLayer,SubmitResult,Menu,Body}. */

/* ---------- Body ---------- */
/* Body/index.module.pcss plus Stack gap={16} flex={1} — Body/index.tsx.
   The non-stepper counterpart to Container: same 16px padding, same overflow-x
   clip with the same source comment, but no button row and no progress bar. */
.rt-body {
  display: flex;
  flex-direction: column;
  flex: 1;
  gap: var(--s-16);
  padding: var(--s-16);
  overflow-x: clip;
}

/* ---------- EditSection ---------- */
/* EditSection/index.module.pcss is only min-width/overflow; the rest is
   EditSection/index.tsx — Stack direction="row" gap={8} alignItems="center"
   minWidth={0}, an h5 noWrap primary, then body4 gray-2 noWrap lines. */
.rt-edit-section { min-width: 0; overflow: hidden; }
.rt-edit-section__row { display: flex; flex-direction: row; align-items: center; gap: var(--s-8); min-width: 0; }
.rt-edit-section__primary {
  font: var(--t-h5);
  font-family: var(--primary-font);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rt-edit-section__secondary {
  display: block;
  font: var(--t-body4);
  font-family: var(--primary-font);
  color: var(--gray-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
/* ActionText: an h6 in blue-1. */
.rt-action-text {
  font: var(--t-h6);
  font-family: var(--primary-font);
  color: var(--blue-1);
  cursor: pointer;
  background: none;
  border: 0;
  padding: 0;
  text-align: left;
  align-self: flex-start;
}
.rt-action-text:hover { color: var(--blue-4); }

/* ---------- SelectedVehicle ---------- */
/* SelectedVehicle/index.module.pcss. Gap is a Stack prop and differs by
   direction: 8 in row, 16 in column — SelectedVehicle/index.tsx. */
.rt-selected-vehicle { width: 100%; display: flex; }
.rt-selected-vehicle--row { height: 100%; align-items: center; flex-direction: row; gap: var(--s-8); }
.rt-selected-vehicle--column { flex-direction: column; gap: var(--s-16); }
.rt-selected-vehicle--row .rt-selected-vehicle__photo {
  width: 104px;
  min-width: 0;
  flex-shrink: 1;
  height: 100%;
  overflow: hidden;
}
/* The 80px cap carries the source comment "Tray header height" — the image is
   sized to the chrome it sits in, which is why the row mode has no radius. */
.rt-selected-vehicle--row .rt-selected-vehicle__photo img {
  width: 100%;
  height: 100%;
  max-height: 80px;
  display: block;
}
.rt-selected-vehicle--column .rt-selected-vehicle__photo {
  width: 100%;
  height: auto;
  overflow: hidden;
  /* The source's 4px is off the radius scale (--r-3/5/7/15), so this is a
     deliberate literal rather than a new token. */
  border-radius: 4px;
}
.rt-selected-vehicle--column .rt-selected-vehicle__photo img { width: 100%; height: 100%; }
.rt-selected-vehicle__info { flex: 1; min-width: 0; }

/* ---------- Toast ---------- */
/* Toast/index.module.pcss. Stack gap={16} — Toast/index.tsx; the list is
   reversed before rendering, so the newest toast sits on top. */
.rt-toast-bar {
  position: absolute;
  top: 0;
  right: 0;
  width: 100%;
  box-sizing: border-box;
  padding: var(--s-16);
  z-index: 9;
  display: flex;
  flex-direction: column;
  gap: var(--s-16);
}
/* An ActionBox, so the whole toast is the button. Note it starts at
   translateY(-100%) with opacity 0 and the animation's forwards fill holds the
   end state — the transition covers the dismissal. */
.rt-toast {
  color: var(--white);
  border: none;
  box-shadow: 0px 2px 8px 0px #3333334d;
  min-height: 40px;
  border-radius: var(--r-7);
  display: flex;
  justify-content: center;
  align-items: center;
  width: 100%;
  box-sizing: border-box;
  padding: var(--s-8);
  transition: opacity 0.2s, transform 0.2s, height 0.2s;
  transform: translateY(-100%);
  animation: rt-slide-in-from-top 0.2s ease-out forwards;
  opacity: 0;
  outline: none;
  margin: 0;
  gap: var(--s-8);
  cursor: pointer;
  font: var(--t-body3);
  font-family: var(--primary-font);
}
.rt-toast--dismissed { opacity: 0; height: 0; padding: 0; min-height: 0; transform: translateY(0); }
.rt-toast--success { background: var(--green-1); }
.rt-toast--error { background: var(--red-1); }
.rt-toast--info { background: var(--blue-1); }
.rt-toast__message { flex-grow: 1; text-align: left; }
.rt-toast__action-text { flex-shrink: 1; text-decoration: underline; padding-left: var(--s-8); }
@keyframes rt-slide-in-from-top {
  from { transform: translateY(-100%); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

/* ---------- OverlayLayer ---------- */
/* OverlayLayer/index.module.pcss. The layer itself is pointer-events: none and
   each overlay re-enables them, so a closed stack never blocks the page. */
.rt-overlay-layer { position: fixed; inset: 0; pointer-events: none; }
.rt-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  box-sizing: border-box;
  padding: var(--s-24);
  padding-top: 48px;
  background-color: rgba(51, 51, 51, 0.8);
  pointer-events: auto;
  /* Source comment: lock the cross-axis size so the panel's % max-height
     resolves predictably. dvh follows the mobile visual viewport; vh is the
     fallback for browsers that ignore it. */
  height: 100vh;
  max-height: 100vh;
  height: 100dvh;
  max-height: 100dvh;
}
.rt-overlay__panel {
  position: relative;
  box-sizing: border-box;
  flex: 0 1 auto;
  width: 100%;
  max-width: min(720px, 100%);
  min-height: 0;
  max-height: calc(100vh - 72px);
  max-height: calc(100dvh - 72px);
  overflow-x: hidden;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background: var(--white);
  border-radius: var(--border-radius);
  padding: var(--s-24);
  box-shadow: var(--box-shadow);
}
.rt-overlay__close { position: absolute; top: var(--s-12); right: var(--s-12); }

/* ---------- SubmitResult ---------- */
/* SubmitResult/index.module.pcss — the whole file is these two rules. */
.rt-submit-result { position: relative; }
/* Source comment: don't block click events for item cards. The confetti canvas
   is skipped entirely under prefers-reduced-motion (checked in the tsx, not CSS). */
.rt-submit-result__confetti {
  pointer-events: none;
  display: block;
  margin: auto;
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  z-index: 1;
  height: 300px;
  width: 100%;
}

/* ================= Finance surfaces =================
   src/lead-forms/Finance/steps/{FinanceCalculator,FinanceCreditScore}/**,
   src/components/app/{PaymentSummary,ProtectedSummary},
   src/components/common/NestedSection. */

/* ---------- PaymentOptions (Figma calls this "Matrix") ---------- */
.rt-matrix-container { position: relative; width: 100%; }

/* PaymentOptions/index.module.pcss. --payment-option-height is LOCAL to this
   component, not a design-system token: 92px by default, 70px in preview. The
   source declares it on the .matrix / .matrix.preview classes; this twin moves
   it to a data-attribute scope on the same element so the compiler registers it
   with its scope rather than treating a component class as a theme. Note the
   grid rows are written as literal 92px rather than through the variable, so
   the variable only reaches the Option placeholders (loading / contact). */
[data-rt-matrix] { --payment-option-height: 92px; }
[data-rt-matrix="preview"] { --payment-option-height: 70px; }

.rt-matrix {
  box-sizing: border-box;
  display: grid;
  grid-area: content;
  grid-template-rows: 92px 92px;
  grid-template-columns: 1fr 1fr;
  gap: var(--s-16);
  /* Source comment: "Fixed position styles to prevent overflow clipping" — the
     checked option's 32px glow would be cut off by the scrolling step content.
     The cost is that the matrix takes no flow space, which the calculator
     compensates for with a 200px spacer. */
  position: fixed;
  width: calc(100% - var(--tray-body-padding) * 2);
  max-width: calc(var(--tray-max-width) - var(--tray-body-padding) * 2);
}
.rt-matrix--disabled { opacity: 0.5; pointer-events: none; }
/* Cash has a single result, in first position. */
.rt-matrix--cash { grid-template-columns: 1fr; grid-template-rows: 92px; }
/* Preview is the embedded single-option variant: static, full width, 70px. */
.rt-matrix--preview {
  grid-template-columns: 1fr;
  grid-template-rows: 70px;
  /* Source comment: "without padding the box shadow overflow is clipped by container" */
  width: 100%;
  max-width: var(--tray-max-width);
  position: static;
}
.rt-matrix--preview.rt-matrix--reverse { display: flex; flex-direction: column-reverse; }

/* The 200px reservations in FinanceCalculator/index.module.pcss, both carrying
   source comments: two 92px rows plus the 16px gap. */
.rt-calculator__fixed-container { margin-top: 200px; }
.rt-calculator__disclaimer-spacer { padding-top: 200px; }

/* ---------- PaymentOption ---------- */
.rt-payment-option { width: 100%; position: relative; }
.rt-payment-option input { display: none; padding: 0; }
.rt-payment-option--disabled { pointer-events: none; opacity: 0.5; }

.rt-payment-option__label {
  background: var(--white);
  border: 1px solid var(--gray-6);
  box-sizing: border-box;
  /* 10px is off the radius scale (--r-3/5/7/15), as is ValueBox's 10px. */
  border-radius: 10px;
  color: var(--gray-0);
  cursor: pointer;
  min-height: var(--h-control-large);
  /* Source comment: "this height determines fixed position matrix height" */
  height: 92px;
  width: 100%;
  padding: var(--s-16) var(--s-8) var(--s-8) var(--s-16);
  position: relative;
  margin: 0;
  display: flex;
  align-items: flex-start;
  transition: background-color 0.2s ease-out;
}
.rt-payment-option__label:hover, .rt-payment-option__label.is-hover {
  background: var(--gray-6);
  box-shadow: 0px 0px 24px 0px #33333314;
}
/* The off-token blue gradient family. Same stops as ValueBox, the date day
   buttons and the sliders; none of these hexes is a token. */
.rt-payment-option__label--checked {
  background: radial-gradient(100% 685.61% at 100% 52.63%, #007aff 0%, #3f9bff 45.83%, #005abd 100%),
    linear-gradient(0deg, #e5f2ff, #e5f2ff);
  border: 1px solid var(--blue-2);
  box-shadow: 0px 0px 32px 0px #007affcc;
  transition: box-shadow 0.5s ease-out;
  z-index: 1;
}
/* A locked deal turns the same gradient green — its own off-token family. */
.rt-payment-option__label--locked {
  background: radial-gradient(100% 685.61% at 100% 52.63%, #34c759 0%, #24eb56 45.83%, #00ac2b 100%),
    linear-gradient(0deg, #e5f2ff, #e5f2ff);
  border: 1px solid var(--blue-2);
  box-shadow: 0px 0px 32px 0px #34c759cc;
}
.rt-payment-option__label--disabled { opacity: 0.5; pointer-events: none; }
.rt-payment-option__label--cash { align-items: center; padding: var(--s-8) var(--s-24); }
.rt-payment-option__label--preview {
  align-items: center;
  padding: var(--s-8) var(--s-8) var(--s-8) var(--s-16);
  height: 70px;
  box-shadow: none;
}
.rt-payment-option--error:not(.rt-payment-option--disabled) .rt-payment-option__label { border-color: var(--red-1); }

.rt-payment-option__text { flex-grow: 1; position: relative; text-align: left; z-index: 1; }
.rt-payment-option__price-row { display: flex; }
/* The line-height carries a source comment: "Don't remove - fixes height of
   animated text". tabular-nums keeps the rolling digits from reflowing. */
.rt-payment-option__price {
  display: flex;
  height: 28px;
  line-height: 28px;
  font-variant-numeric: tabular-nums;
}
/* 3px is off the spacing scale (2, 4, 8, 12…) — literal, per the source. */
.rt-payment-option__term { padding: 0 3px; position: relative; top: 10px; }
.rt-payment-option__subtitle { display: inline-flex !important; }

/* Option — the shared placeholder shell for Loading and Contact. This is the
   only consumer of --payment-option-height, plus Stack gap={2}. */
.rt-option {
  background: var(--white);
  border-radius: var(--r-7);
  border: 1px solid var(--gray-6);
  padding: 0 var(--s-16);
  box-sizing: border-box;
  height: var(--payment-option-height);
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: var(--s-2);
}

/* ---------- PriceCounter ---------- */
/* The rolling-digit odometer. Each digit is a column 0..n translated up by
   28px per row over 0.5s — so a higher digit takes the same time to arrive. */
.rt-price-counter-row { display: flex; height: 28px; overflow: hidden; }
.rt-price-counter-row--active { background: transparent; }
.rt-price-counter { display: flex; flex-direction: column; position: relative; transition: top 0.5s ease-out; }

/* ---------- PriceSticker ---------- */
/* The whole stylesheet is this one rule. Typography body1 gray-0 over
   body4 gray-2 — PriceSticker/index.tsx. */
.rt-price-sticker { margin-bottom: var(--s-16); }
.rt-price-sticker__label { display: block; font: var(--t-body1); font-family: var(--primary-font); color: var(--gray-0); }
.rt-price-sticker__name { display: block; font: var(--t-body4); font-family: var(--primary-font); color: var(--gray-2); }

/* ---------- DeskingStatus ---------- */
/* Stack column alignItems/justifyContent center gap={16} — DeskingStatus/index.tsx. */
.rt-desking-status {
  height: 100%;
  width: 100%;
  box-sizing: border-box;
  padding: var(--s-16);
  text-align: center;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--s-16);
}
.rt-desking-status__title { font: var(--t-h3); font-family: var(--primary-font); color: var(--gray-0); }
.rt-desking-status__subtitle { font: var(--t-body1); font-family: var(--primary-font); color: var(--gray-2); }

/* ---------- CreditScoreBand ---------- */
/* Five segments, each coloured from CreditScoreBands in const/CreditScore.ts.
   Borders collapse by zeroing border-right except on the last item. */
.rt-credit-band { display: flex; align-items: center; width: 100%; box-sizing: border-box; }
.rt-credit-band__item {
  align-items: center;
  border: 1px solid var(--white);
  border-right-width: 0;
  display: flex;
  height: 24px;
  justify-content: center;
  text-align: center;
  flex: 1;
  font: var(--t-body5);
  font-family: var(--primary-font);
}
.rt-credit-band__item:first-of-type { border-radius: var(--r-5) 0 0 var(--r-5); }
.rt-credit-band__item:last-of-type { border-right-width: 1px; border-radius: 0 var(--r-5) var(--r-5) 0; }

/* ---------- CreditScoreSlider ---------- */
.rt-slider-holder { width: 100%; box-sizing: border-box; opacity: 1; transition: all 0.1s ease; }
/* Applied when the score is below MIN_CREDIT_SCORE (300) — i.e. not yet entered. */
.rt-slider-holder--disabled { opacity: 0.5; pointer-events: none; }

.rt-slider { margin-top: var(--s-16); position: relative; }
.rt-slider--disabled { opacity: 0.5; pointer-events: none; }
/* The track is a linear-gradient written inline from the progress percentage,
   blue-1 up to the thumb and gray-6 after — Slider/index.tsx. */
.rt-slider input[type='range'] {
  width: 100%;
  margin: 2.5px 0;
  height: var(--h-pill);
  background-color: transparent;
  border-radius: var(--r-7);
  box-shadow: inset 0px 0px 4px -2px var(--gray-0);
  appearance: none;
  -webkit-appearance: none;
}
.rt-slider input[type='range']:focus { outline: none; }
.rt-slider input[type='range']::-webkit-slider-runnable-track {
  background: transparent;
  width: 100%;
  height: var(--h-pill);
  cursor: pointer;
}
/* The thumb's 2px outline and its focus glow are raw #007AFF80 / #007aff —
   the off-token blue family again. */
.rt-slider input[type='range']::-webkit-slider-thumb {
  margin-top: -2.7px;
  width: 36px;
  height: 36px;
  background: var(--blue-1);
  border: 5px solid var(--white);
  outline: 2px solid #007AFF80;
  box-sizing: border-box;
  border-radius: 36px;
  cursor: pointer;
  -webkit-appearance: none;
}
.rt-slider input[type='range']::-webkit-slider-thumb:active,
.rt-slider input[type='range']:active::-webkit-slider-thumb,
.rt-slider input[type='range']:focus::-webkit-slider-thumb {
  background: var(--blue-4);
  transform: scale(1.1);
  box-shadow: 0px 0px 8px 0px #007aff;
}
.rt-slider input[type='range']::-moz-range-track {
  background: transparent;
  width: 100%;
  height: var(--h-pill);
  cursor: pointer;
}
.rt-slider input[type='range']::-moz-range-thumb {
  width: 36px;
  height: 36px;
  background: var(--blue-1);
  border: 5px solid var(--white);
  box-shadow: 0 0 0 2px #007AFF80;
  box-sizing: border-box;
  border-radius: 36px;
  cursor: pointer;
  -moz-appearance: none;
}
.rt-slider input[type='range']::-moz-range-thumb:active,
.rt-slider input[type='range']::-moz-range-thumb:focus {
  background: var(--blue-4);
  transform: scale(1.1);
  box-shadow: 0px 0px 8px 0px #007aff;
}
/* The value label is hidden until hover or focus, then scales in. Its left is
   written inline as calc(-1px + progress * (100% - 36px) / 100) — the 36px is
   the thumb width and the -1px is the outline. */
.rt-slider__value-label {
  position: absolute;
  bottom: calc(100% + 17px);
  font-size: 13px;
  border-radius: var(--r-7);
  line-height: 16px;
  background-color: var(--blue-1);
  color: var(--white);
  padding: var(--s-4) var(--s-8);
  white-space: nowrap;
  pointer-events: none;
  opacity: 0;
  transform: scale(0);
  transition: opacity 0.1s ease-out, transform 0.1s ease-out;
  z-index: 3;
  font-family: var(--primary-font);
}
.rt-slider input:hover ~ .rt-slider__value-label,
.rt-slider input:focus ~ .rt-slider__value-label,
.rt-slider--label-on .rt-slider__value-label { opacity: 1; transform: scale(1); }
.rt-slider__value-label::after {
  content: '';
  position: absolute;
  top: 100%;
  left: 49%;
  transform: translateX(-49%);
  width: 0;
  height: 0;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 4px solid var(--blue-1);
}

/* ---------- NestedSection ---------- */
/* NestedSection/index.module.pcss plus Row's own file (min-height 32px only). */
.rt-nested-section {
  box-sizing: border-box;
  padding: var(--s-4) 0;
  border-bottom: 1px solid var(--gray-5);
  display: flex;
  flex-direction: column;
}
/* Stack direction="row" justifyContent="space-between" alignItems="center" — Row/index.tsx. */
.rt-nested-row {
  /* 32px literal, per Row/index.tsx — a row height, not a Pill. */
  min-height: 32px;
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  gap: var(--s-8);
}
.rt-nested-row__header { font: var(--t-h5); font-family: var(--primary-font); color: var(--gray-0); }
.rt-nested-row__item { font: var(--t-body4); font-family: var(--primary-font); color: var(--gray-2); }
.rt-nested-indented { padding-left: var(--s-16); }
.rt-nested-strikethrough { text-decoration: line-through; }

/* ---------- PaymentSummary ---------- */
/* PaymentSummary/index.module.pcss — four one-line rules. */
.rt-payment-summary { flex-grow: 1; }
.rt-payment-summary__column { flex-grow: 1; display: flex; flex-direction: column; }
.rt-payment-summary__list { margin-top: var(--s-8); }
.rt-payment-summary__row {
  margin-top: var(--s-16);
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
}

/* ================= Account and request panels =================
   src/components/app/{Verification,Documents,CreditApp/Applications,References,
   Appointments,VehicleRequests,Profile,TradeIn/Result},
   src/components/common/UploadDocument. */

/* ---------- Verification code entry ---------- */
/* Verification/index.module.pcss — and byte-for-byte the same file again at
   Verification/Email/index.module.pcss and Verification/Phone/index.module.pcss.
   Three identical copies; only the Email and Phone ones are actually imported.
   The container is react-otp-input's containerStyle, so the gap is 4px, not 8. */
.rt-code-input { display: flex; gap: var(--s-4); }
.rt-code-input__container { position: relative; }
.rt-code-input input {
  width: 100%;
  height: 56px;
  padding: 0;
  margin: 0;
  box-sizing: border-box;
  border: 1px solid var(--input-border-color);
  border-radius: var(--input-border-radius);
  background: var(--input-background-color);
  color: var(--input-text-color);
  flex-grow: 1;
  text-align: center;
  text-transform: uppercase;
  /* Source comment: "Input text styles". 20/56/600 is its own scale — the type
     tokens have no 20px, and the line-height doubles as the box height. */
  font-size: 20px;
  font-weight: 600;
  line-height: 56px;
  font-family: var(--primary-font);
}
.rt-code-input input:disabled { pointer-events: none; color: var(--gray-5); }
.rt-code-input input:hover { background-color: var(--blue-3); }
.rt-code-input input:active, .rt-code-input input:focus { border-color: var(--input-focus-color); }
/* Kills the selection highlight so retyping a digit does not flash blue. */
.rt-code-input input::selection { background: none; }

/* ---------- FileLabel ---------- */
/* UploadDocument/FileLabel/index.module.pcss. Radius 5px and the asymmetric
   2px 4px 2px 8px padding (tighter on the right, where the trash button sits).
   Stack direction="row" gap={4} alignItems="center" minWidth={0} — FileLabel/index.tsx,
   whose source note says minWidth is required to make text ellipsis work. */
.rt-file-label {
  display: inline-flex;
  flex-direction: row;
  align-items: center;
  gap: var(--s-4);
  min-width: 0;
  box-sizing: border-box;
  border: 1px solid var(--gray-4);
  border-radius: var(--r-5);
  padding: 2px 4px 2px 8px;
  min-height: 30px;
  cursor: pointer;
}
.rt-file-label:hover { background: var(--white); }
.rt-file-label__name {
  font: var(--t-body4);
  font-family: var(--primary-font);
  color: var(--gray-2);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.rt-file-label__icon { flex-shrink: 0; }
/* The Popover's media fallback when a file has no image preview. */
.rt-file-fallback { padding: var(--s-16); display: flex; flex-direction: column; align-items: center; gap: var(--s-8); }

/* CreditApp/Applications/index.module.pcss. The source comment says it outright:
   "Visual recipe copied from UploadDocument/FileLabel so the co-signer action
   chips match the document file labels rendered in the same view." Same border,
   radius, padding, min-height and hover — a deliberate duplicate, not drift.
   It is NOT the Chip component (8px radius, 8px 12px padding). */
.rt-app-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--s-4);
  width: fit-content;
  box-sizing: border-box;
  border: 1px solid var(--gray-4);
  border-radius: var(--r-5);
  padding: 2px 4px 2px 8px;
  min-height: 30px;
  font: var(--t-body4);
  font-family: var(--primary-font);
  color: var(--gray-2);
  background: none;
}
.rt-app-chip:hover { background: var(--white); }
.rt-app-chip--action { cursor: pointer; }

/* ---------- Appointments ---------- */
/* Appointments/index.module.pcss. The Module recipe a fifth time, but on a
   gray-6 border rather than gray-5. Past appointments drop to a transparent
   fill at half opacity with pointer-events off. */
.rt-appointment-card {
  background-color: var(--white);
  border: 1px solid var(--gray-6);
  border-radius: var(--r-5);
  box-sizing: border-box;
  padding: var(--s-16);
  width: 100%;
}
.rt-appointment-card--past { background-color: transparent; pointer-events: none; opacity: 0.5; }

/* ---------- TradeIn result ---------- */
/* TradeIn/Result/index.module.pcss — the whole file. The ValueBox is pulled out
   of flow and laid OVER the graph: .result is absolute at left 0, full width,
   z-index 1, inside a relative Stack gap={32} that carries margin: 32px 0.
   So the 32px appears twice, as gap and as outer margin. */
.rt-trade-result { position: relative; margin: var(--s-32) 0; display: flex; flex-direction: column; gap: var(--s-32); }
.rt-trade-result__value { position: absolute; left: 0; width: 100%; z-index: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; }

/* ================= Embedded surfaces =================
   src/embedded-forms/**, src/embedded-search/**,
   src/components/app/Search/{SearchResults,SrpVehicleCard},
   src/components/app/VehicleFilters/FilterRail.
   These render inside the DEALER'S OWN PAGE, so the host contract stops being
   theoretical: host CSS and host config both reach in. */

/* ---------- Embedded form ---------- */
/* EmbeddedForm/index.module.pcss is only these three rules — every dimension
   the brief describes (padding 16, transparent, min-height 600, max-width 528,
   margin auto) is CONFIG, applied as an inline style from widgetConfig
   (EmbeddedForm/index.tsx + the JSDoc defaults on EmbeddedFormContainerProps).
   The twin declares them as fallbacks here so a bare mount still looks right. */
.rt-embedded-form {
  margin: 0;
  flex: 1;
  display: flex;
  flex-direction: column;
  height: 100%;
  width: 100%;
  /* config defaults, applied inline in the source */
  max-width: 528px;
  margin: auto;
  contain: layout;
  position: relative;
}
/* stepperKey === EmbeddedFormStepperKey.Finance — the tsx swaps BOTH the
   height property and the position value for this one form:
   heightKey 'minHeight' vs 'height', position 'static' vs 'relative'.
   Marked TEMP in the source. */
.rt-embedded-form--finance { min-height: 600px; height: auto; position: static; }
.rt-embedded-form:not(.rt-embedded-form--finance) { height: 600px; }

.rt-embedded-form__container {
  box-sizing: border-box;
  display: flex;
  flex: 1;
  flex-direction: column;
  overflow: auto;
  width: 100%;
  /* config defaults, applied inline */
  padding: var(--s-16);
  background: transparent;
}
/* Only when this form's own submit result is showing. */
.rt-embedded-form__container--with-result { gap: var(--s-16); }

/* EmbeddedFormHeader/index.module.pcss is the whole file: three declarations.
   background, borderRadius, color and borderColor are inline props; their
   documented defaults are transparent, 0px, --gray-0 and --gray-6. Note the
   0px radius default — an embedded header is square even though the tray's
   is 15px, because it sits inside the dealer's own card. */
.rt-embedded-form__header {
  height: 48px;
  padding: 0 var(--s-8);
  border-bottom: 1px solid var(--gray-6);
  display: flex;
  flex-direction: row;
  align-items: center;
  box-sizing: border-box;
  border-radius: 0px;
  color: var(--gray-0);
}
.rt-embedded-form__header-title { font: var(--t-h5); font-family: var(--primary-font); flex: 1; }

/* ---------- Embedded search shell ---------- */
/* EmbeddedSearch/index.module.pcss. This surface renders into the LIGHT DOM —
   no shadow root, unlike every other embedded surface — because third-party SRP
   vendors (TradePending, CapitalOne, CarGurus) find their mount points by
   scanning the document, and a scan cannot pierce a shadow boundary. The source
   says so at length. Consequence: host CSS cascades in, which is why the file
   opens with a box-sizing reset and a margin reset on headings and p. */
.rt-srp, .rt-srp *, .rt-srp *::before, .rt-srp *::after { box-sizing: border-box; }
.rt-srp {
  --srp-trim-color: var(--gray-6);
  --srp-top-height: 60px;
  /* Measured at runtime by a ResizeObserver in index.tsx, not set in CSS.
     Declared here with the source's own fallbacks so the twin renders standalone:
       --srp-shell-height       viewport − shell offsetTop, floored at 480px
       --srp-topbar-height      the results top bar's measured height
       --srp-mobile-toolbar-height  the HOST theme's fixed bottom toolbar
                                    (.mtb-v2-wrapper / .global-bar-mobile) */
  color: var(--black);
  contain: layout;
  line-height: normal;
  position: relative;
  text-align: left;
}
.rt-srp h1, .rt-srp h2, .rt-srp h3, .rt-srp h4, .rt-srp h5, .rt-srp h6, .rt-srp p { margin: 0; }

/* The shell never scrolls; the panes inside it do. */
.rt-srp__layout { display: flex; height: var(--srp-shell-height, 100dvh); position: relative; }
.rt-srp__rail { display: flex; flex-direction: column; flex-shrink: 0; height: 100%; overflow: hidden; width: 240px; }
.rt-srp__rail-scroll { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.rt-srp__main { background: var(--gray-7); display: flex; flex: 1; flex-direction: column; min-height: 0; min-width: 0; }
/* Shares --srp-top-height with the results top bar so the two sit on one line. */
.rt-srp__rail-header {
  align-items: center;
  background: var(--white);
  border-bottom: 1px solid var(--srp-trim-color);
  display: flex;
  flex: none;
  gap: var(--s-8);
  height: var(--srp-top-height);
  padding: var(--s-12);
}
.rt-srp__rail-header-icon { font-size: 14px; }
.rt-srp__rail-header-title { font-size: 16px; font-weight: 600; }
.rt-srp__rail-close { background: none; border: none; color: var(--gray-2); cursor: pointer; display: none; font-size: 18px; margin-left: auto; padding: var(--s-8); }
.rt-srp__apply {
  background: var(--primary-accent);
  border: none;
  border-radius: var(--button-radius);
  color: var(--white);
  cursor: pointer;
  display: none;
  font-size: 15px;
  font-weight: 600;
  padding: 14px var(--s-16);
}

@media (max-width: 767px) {
  /* The rail becomes a bottom sheet between the results top bar and the host's
     own fixed toolbar. Note visibility is transitioned with a 0.25s DELAY on
     close so the slide-down is visible before it is hidden. */
  .rt-srp__rail {
    background: var(--white);
    bottom: 0;
    height: auto;
    left: 0;
    position: absolute;
    top: var(--srp-topbar-height, var(--srp-top-height));
    transform: translateY(100%);
    transition: transform 0.25s ease, visibility 0s linear 0.25s;
    visibility: hidden;
    width: 100%;
    z-index: 9;
  }
  .rt-srp__rail--open { transform: translateY(0); transition: transform 0.25s ease; visibility: visible; }
  /* The results top bar owns the toggle, so the panel's own header would
     just repeat it. */
  .rt-srp__rail-header { display: none; }
  .rt-srp__rail-scroll { padding-bottom: var(--srp-mobile-toolbar-height, 0px); }
  /* Source comment: NOT position: fixed — the open panel's transform would
     make fixed resolve against the panel. */
  .rt-srp__rail--open .rt-srp__apply {
    display: block;
    flex: none;
    margin: var(--s-8) var(--s-16) calc(var(--srp-mobile-toolbar-height, 0px) + 12px);
  }
  .rt-srp__main { width: 100%; }
}

/* ---------- FilterRail ---------- */
/* FilterRail/index.module.pcss. 12px is the website's row inset, used for both
   the header row and the content block. */
.rt-filter-rail { background: var(--white); display: flex; flex-direction: column; }
.rt-filter-rail__section { border-bottom: 1px solid var(--srp-trim-color); }
.rt-filter-rail__header {
  align-items: center;
  background: none;
  border: none;
  cursor: pointer;
  display: flex;
  gap: var(--s-8);
  padding: var(--s-12);
  text-align: left;
  width: 100%;
  font-family: var(--primary-font);
}
.rt-filter-rail__header:hover, .rt-filter-rail__header:active, .rt-filter-rail__header:focus { background: none; border: none; }
.rt-filter-rail__header-title { font: var(--t-h5); font-family: var(--primary-font); flex: 1; }
.rt-filter-rail__icon { color: var(--black); }
.rt-filter-rail__chevron { color: var(--black); transition: transform 0.15s ease; }
.rt-filter-rail__chevron--expanded { color: var(--black); transform: rotate(180deg); }
.rt-filter-rail__content { padding: 0 var(--s-12) var(--s-12); }

/* ---------- SearchResults ---------- */
/* SearchResults/index.module.pcss. --gutter is component-local (16px) and does
   double duty as the grid gap and the outer padding, so the gutter is even on
   all four sides. NOTE --srp-text-color is consumed three times below and is
   defined NOWHERE — not in the widget, not on the site. It resolves to nothing
   today; recorded in the readme's upstream list. Mirrored as written. */
[data-rt-results] { --gutter: 16px; }
.rt-results { display: flex; flex: 1; flex-direction: column; min-height: 0; min-width: 0; }

/* Source comment: a fixed toolbar that is a SIBLING of the scrolling region
   rather than a sticky child of it, so it cannot move at all and needs no
   background mask to hide content passing beneath. */
.rt-results__top-bar {
  box-sizing: border-box;
  align-items: center;
  background: var(--white);
  border-bottom: 1px solid var(--srp-trim-color);
  height: var(--srp-top-height);
  display: flex;
  flex: none;
  gap: var(--s-16);
  justify-content: space-between;
  padding: var(--s-8) var(--gutter);
  position: relative;
  z-index: 8;
}
/* The SRP's only scrolling region. overscroll-behavior stops a wheel that
   reaches the end of the results from chaining out to the host page. */
.rt-results__scroller { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.rt-results__top-left { align-items: center; display: flex; flex: 1; flex-wrap: wrap; gap: var(--s-8); min-width: 0; }
.rt-results__top-right { align-items: center; display: flex; flex: none; gap: var(--s-16); }
.rt-results__total { white-space: nowrap; }
.rt-results__clear-all { background: none; border: none; color: var(--blue-1); cursor: pointer; flex: none; font-size: 13px; font-weight: 600; padding: var(--s-4) 0; font-family: var(--primary-font); }

/* Mobile filters toggle: 48x48, hidden on desktop. The count badge is a 10px
   radius pill that hides itself at zero via [data-count='0']. */
.rt-results__filters-mob {
  align-items: center;
  background: none;
  border: none;
  color: var(--black);
  cursor: pointer;
  display: none;
  flex: none;
  font-size: 16px;
  height: 48px;
  justify-content: center;
  position: relative;
  width: 48px;
}
.rt-results__filter-count {
  background: var(--primary-accent);
  border-radius: 10px;
  color: var(--white);
  font-size: 11px;
  font-weight: 600;
  line-height: 16px;
  min-width: 16px;
  position: absolute;
  right: 2px;
  top: var(--s-4);
  text-align: center;
  font-family: var(--primary-font);
}
.rt-results__filter-count[data-count='0'] { display: none; }

.rt-results__sort-mob { position: relative; }
.rt-results__sort-mob-button {
  align-items: center;
  background: none;
  border: none;
  color: var(--black);
  cursor: pointer;
  display: flex;
  font-size: 14px;
  gap: 6px;
  height: 48px;
  justify-content: center;
  padding: 0 var(--s-8);
  white-space: nowrap;
  font-family: var(--primary-font);
}
.rt-results__sort-mob-button:hover, .rt-results__sort-mob-button:focus { background: none; border: none; color: var(--srp-text-color); }
.rt-results__sort-mob-menu {
  background: var(--white);
  border: 1px solid var(--gray-5);
  border-radius: 6px;
  box-shadow: var(--light-box-shadow);
  max-height: 80vh;
  max-width: calc(100vw - 32px);
  overflow-y: auto;
  position: absolute;
  right: 0;
  top: 100%;
  width: 280px;
  z-index: 20;
}
.rt-results__sort-mob-option {
  background: none;
  border: none;
  border-radius: 0;
  box-sizing: border-box;
  color: var(--srp-text-color);
  cursor: pointer;
  display: block;
  font-size: 14px;
  padding: var(--s-12) var(--s-16);
  text-align: left;
  width: 100%;
  font-family: var(--primary-font);
}
.rt-results__sort-mob-option--active { color: var(--primary-accent); font-weight: 600; }

@media (max-width: 767px) {
  /* Two stacked rows — [filters][count][sort] first, then the chips strip with
     horizontal scroll. The shared height token is released here, which is why
     --srp-topbar-height has to be measured rather than assumed. */
  .rt-results__top-bar { align-items: stretch; flex-direction: column; gap: 0; height: auto; }
  .rt-results__top-left { flex-wrap: nowrap; order: 1; overflow-x: auto; padding: var(--s-4) 0; }
  .rt-results__top-right { order: 0; justify-content: flex-start; }
  .rt-results__filters-mob { display: flex; }
  .rt-results__total { flex: 1; padding: 0 var(--s-12); }
  /* The host theme's fixed bottom toolbar overlays the scroll area. */
  .rt-results__scroller { padding-bottom: var(--srp-mobile-toolbar-height, 0px); }
}

.rt-results__grid {
  display: grid;
  gap: var(--gutter);
  grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
  padding: var(--gutter);
}
@media (min-width: 768px) {
  .rt-results__grid { grid-template-columns: repeat(auto-fill, minmax(340px, 1fr)); }
}
.rt-results__empty { display: flex; flex-direction: column; gap: var(--s-4); padding: var(--s-32) 0; text-align: center; }
.rt-results__pagination { align-items: center; display: flex; gap: var(--s-16); justify-content: center; padding: var(--s-8) 0; }

/* ---------- SrpVehicleCard ---------- */
/* SrpVehicleCard/index.module.pcss. The most HOST-COUPLED component in the
   widget. Three distinct coupling mechanisms:
     1. It reads --primary-color and --primary-button-text-color straight off
        the dealer's site (the customizer's :root), with the widget's own tokens
        only as fallbacks — see .rt-srp-card__cta--primary.
     2. It takes --retail-label, --ext-color and --int-color as INLINE values
        from vehicle data / config.
     3. Its DOM carries unhashed website class names as deliberate hooks for
        Command Center per-site CSS injections and vendor scripts. Those are
        unstyled here, exactly as in the source.
   The source's own comment: "Layout mirrors the website v5 card." */
.rt-srp-card {
  background: var(--white);
  border: 1px solid var(--gray-6);
  border-radius: var(--border-radius);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  position: relative;
  transition: box-shadow 0.25s ease;
}
.rt-srp-card:hover { box-shadow: var(--light-box-shadow); }

.rt-srp-card__images { aspect-ratio: 4 / 3; overflow: hidden; position: relative; width: 100%; }
.rt-srp-card__image { display: block; height: 100%; object-fit: cover; width: 100%; }
/* Arrows are invisible until the image area is hovered. */
.rt-srp-card__slide-button {
  align-items: center;
  background: rgb(255 255 255 / 85%);
  border: none;
  border-radius: 50%;
  cursor: pointer;
  display: flex;
  height: 32px;
  justify-content: center;
  opacity: 0;
  position: absolute;
  top: calc(50% - 16px);
  transition: opacity 0.15s ease;
  width: 32px;
  z-index: 2;
}
.rt-srp-card__images:hover .rt-srp-card__slide-button { opacity: 1; }
.rt-srp-card__slide-prev { left: var(--s-8); }
.rt-srp-card__slide-next { right: var(--s-8); }
.rt-srp-card__tag-badges { bottom: var(--s-8); display: flex; flex-wrap: wrap; gap: var(--s-8); left: var(--s-8); pointer-events: none; position: absolute; z-index: 2; }
/* #e0f634 is a hard-coded acid yellow-green, in no token anywhere, and 24px is
   the only pill radius in the system. */
.rt-srp-card__tag-badge { background: #e0f634; border-radius: 24px; color: var(--black); font-size: 12px; font-weight: 600; padding: var(--s-4) 10px; font-family: var(--primary-font); }

.rt-srp-card__details { display: flex; flex: 1; flex-direction: column; gap: var(--s-8); padding: var(--s-24); position: relative; z-index: 2; }
/* A full-card link UNDER everything at z-index 1, so the whole card is clickable
   while each interactive child lifts itself to z-index 2. */
.rt-srp-card__bottom-link { inset: 0; position: absolute; z-index: 1; }
.rt-srp-card__title-flex { align-items: flex-start; display: flex; gap: var(--s-8); }
.rt-srp-card__title-wrap { color: inherit; flex: 1; min-width: 0; position: relative; text-decoration: none; z-index: 2; }
.rt-srp-card__condition-mileage { align-items: center; color: var(--gray-2); display: flex; flex-wrap: wrap; font-size: 13px; gap: var(--s-8); }
.rt-srp-card__condition { text-transform: capitalize; }
/* 4px is off the radius scale (3/5/7/15) — literal, as the source writes it. */
.rt-srp-card__in-transit { background: var(--blue-2); border-radius: 4px; color: var(--blue-4); font-size: 11px; font-weight: 600; padding: 2px 6px; }
.rt-srp-card__title { color: var(--black); font-size: 16px; font-weight: 600; line-height: 24px; margin: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rt-srp-card__title-trim { color: var(--gray-2); font-size: 13px; }
.rt-srp-card__fave { align-items: center; background: none; border: none; color: var(--gray-3); cursor: pointer; display: flex; flex: none; font-size: 18px; height: 32px; justify-content: center; position: relative; width: 32px; z-index: 2; }
.rt-srp-card__fave--favorited { color: var(--red-1); }
.rt-srp-card__stock-line { color: var(--gray-2); font-size: 13px; }

.rt-srp-card__price-row { align-items: center; display: flex; justify-content: space-between; min-height: 42px; position: relative; z-index: 2; }
.rt-srp-card__price { display: flex; flex-direction: column; }
/* 18/700 — the only 700 weight in the widget. Inter is loaded 400/500/600, so
   this renders as a synthesised bold. */
.rt-srp-card__price-val { color: var(--black); font-size: 18px; font-weight: 700; }
.rt-srp-card__ask-for-price { color: var(--blue-1); font-size: 16px; font-weight: 600; }
.rt-srp-card__payment { color: var(--gray-2); font-size: 13px; }
/* Source comment: element text nodes carry the NUMBER ONLY; these
   pseudo-elements supply the $ / Save $ / % / Incentive(s) exactly like
   srp-v5.css, so the DOM text and the visible text both match the website. */
.rt-srp-card__price-val.dol-sign::before { content: '$'; }
.rt-srp-card__savings { color: var(--green-1); font-size: 13px; font-weight: 600; }
.rt-srp-card__savings.dollar-sign::before { content: 'Save $'; }
.rt-srp-card__savings.percent::before { content: 'Save '; }
.rt-srp-card__savings.percent::after { content: '%'; }
.rt-srp-card__apr-offer, .rt-srp-card__rebates-count { color: var(--blue-1); font-size: 12px; font-weight: 600; }
.rt-srp-card__rebates-count::after { content: ' Incentives'; }
.rt-srp-card__rebates-count[data-count='1']::after { content: ' Incentive'; }
/* The MSRP label is an EMPTY span; the word comes from --retail-label, which
   config feeds, so per-site .retail-lbl:before injections keep working. */
.rt-srp-card__cell .retail-lbl::before { content: var(--retail-label, 'Retail Price'); }
.rt-srp-card__cell .vehicle-msrp-val.dol-sign::before { content: '$'; }

.rt-srp-card__breakdown { border-top: 1px solid var(--gray-6); font-size: 13px; padding-top: var(--s-8); position: relative; z-index: 2; }
.rt-srp-card__breakdown-ymm { font-size: 14px; font-weight: 600; margin-bottom: var(--s-8); }
.rt-srp-card__breakdown-row { display: flex; justify-content: space-between; padding: 2px 0; }
.rt-srp-card__breakdown-label { color: var(--gray-2); }
.rt-srp-card__breakdown-value { color: var(--gray-1); font-weight: 500; }
.rt-srp-card__strikethrough { text-decoration: line-through; }
.rt-srp-card__disclaimer-toggle { background: none; border: none; color: var(--gray-3); cursor: pointer; font-size: 11px; padding: 0; text-decoration: underline; font-family: var(--primary-font); }
.rt-srp-card__disclaimer-content { color: var(--gray-3); font-size: 11px; margin-top: var(--s-4); }

.rt-srp-card__colors { position: relative; }
/* A 135deg split disc: exterior colour on one half, interior on the other,
   both passed inline from vehicle data. */
.rt-srp-card__color-circle {
  background: linear-gradient(135deg, var(--ext-color) 0 50%, var(--int-color) 50% 100%);
  border: 1px solid var(--gray-5);
  border-radius: 50%;
  height: 28px;
  width: 28px;
}
.rt-srp-card__color-tooltip {
  background: var(--white);
  border: 1px solid var(--gray-5);
  border-radius: 6px;
  bottom: calc(100% + var(--s-4));
  box-shadow: var(--light-box-shadow);
  display: none;
  font-size: 12px;
  padding: var(--s-8) 10px;
  position: absolute;
  right: 0;
  white-space: nowrap;
  z-index: 3;
}
.rt-srp-card__colors:hover .rt-srp-card__color-tooltip { display: block; }

.rt-srp-card__details-flex { display: flex; font-size: 13px; gap: var(--s-8); position: relative; z-index: 2; }
.rt-srp-card__details-flex > * { flex: 1; min-width: 0; }
.rt-srp-card__cell { color: inherit; text-decoration: none; }
.rt-srp-card__cell-label { color: var(--gray-3); font-size: 12px; }
.rt-srp-card__cell-value { color: var(--gray-1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rt-srp-card__stock-vin-row { color: inherit; display: flex; font-size: 13px; gap: var(--s-16); position: relative; text-decoration: none; z-index: 2; }
.rt-srp-card__location-row { color: var(--gray-2); font-size: 13px; position: relative; text-decoration: none; z-index: 2; }

.rt-srp-card__cta-group { display: flex; flex-direction: column; gap: var(--s-8); margin-top: auto; padding-top: var(--s-8); position: relative; z-index: 2; }
.rt-srp-card__cta-group > * { flex: 1; }
/* 40px min-height — off the 32/48/64 control scale, and the radius falls back
   through var(--border-radius) to var(--button-radius). Hover is opacity, not
   a colour change, because the fill may be any dealer colour. */
.rt-srp-card__cta {
  align-items: center;
  border: none;
  border-radius: var(--border-radius, var(--button-radius));
  cursor: pointer;
  display: flex;
  font-size: 14px;
  font-weight: 600;
  justify-content: center;
  min-height: 40px;
  padding: var(--s-8) var(--s-12);
  text-align: center;
  text-decoration: none;
  transition: opacity 0.15s ease;
  font-family: var(--primary-font);
}
.rt-srp-card__cta:hover { opacity: 0.9; }
.rt-srp-card__cta:disabled { cursor: default; opacity: 0.6; }
/* Source comment: host-page brand tokens FIRST (customizer :root), widget
   defaults as fallback — the same bridge the VDP's .btn-primary uses, so SRP
   cards and the VDP agree on the brand colour on takeover pages. Note these are
   --primary-color and --primary-button-text-color: NOT the host contract's
   --primary-button-color. A fourth host variable, read only here. */
.rt-srp-card__cta--primary { background: var(--primary-color, var(--primary-accent)); color: var(--primary-button-text-color, var(--white)); }
.rt-srp-card__cta--secondary { background: var(--white); border: 1px solid var(--gray-5); color: var(--black); }

/* ================= VDP overlay =================
   src/components/app/Vdp/VdpExperience/index.module.pcss (~1,500 lines, 38KB) —
   a visual port of the website's vdp-fullscreen.css, and the single largest
   concentration of untokenized values in the widget. Every raw hex, 700/800
   weight, unitless line-height and letter-spacing below is MIRRORED, not
   tokenized; see the VDP palette audit in readme.md for the full count.
   The unhashed fs-vdp-* / vdp-v5-* classes on the same nodes are the unstyled
   website contract for per-site CSS injections. */

/* ---------- Overlay shell ---------- */
/* Portaled to <body> in light DOM: third-party scripts scan the document, and
   a page-content ancestor with a transform would break position: fixed. */
.rt-vdp-scrim { backdrop-filter: blur(2px); background: rgb(51 51 51 / 55%); inset: 0; position: fixed; z-index: 10010; }
.rt-vdp-flex-wrap { inset: 0; overflow-y: auto; overscroll-behavior: contain; position: fixed; -webkit-overflow-scrolling: touch; z-index: 10011; }
/* #fbfafa — the VDP's page colour, in no token. Not --gray-7 (#f9f9f9). */
.rt-vdp-flex { background: #fbfafa; box-shadow: 0 0 48px rgb(0 0 0 / 25%); margin: 0 auto; max-width: 1440px; min-height: 100%; width: 100%; }
.rt-vdp-col-left { width: 100%; }

/* --body-font-color is a SIXTH host variable, read only on this surface —
   the website's own body colour, with --black as fallback. */
.rt-vdp-layout { background: #fbfafa; color: var(--body-font-color, var(--black)); min-height: 100%; padding-bottom: 48px; }
/* Note max-width 1920 here vs 1440 on the shell: the shell caps the overlay,
   these cap the content inside it. */
.rt-vdp-header-area { display: flex; flex-direction: column; margin: 0 auto; max-width: 1920px; padding: 0 40px; }
.rt-vdp-body { display: flex; gap: 48px; margin: 0 auto; max-width: 1920px; padding: 32px 40px 60px; }
.rt-vdp-content { flex: 1; min-width: 0; }

/* ---------- Breadcrumb ---------- */
.rt-vdp-top-bar { padding: 20px 0 4px; }
.rt-vdp-breadcrumb { align-items: center; display: flex; font-size: 13px; gap: 10px; }
.rt-vdp-breadcrumb__link { color: var(--gray-2); text-decoration: none; white-space: nowrap; }
.rt-vdp-breadcrumb__link:hover { color: var(--primary-color, #333); text-decoration: underline; }
.rt-vdp-breadcrumb__sep { color: var(--gray-4); font-size: 11px; }

/* ---------- Title row ---------- */
.rt-vdp-title-row { align-items: flex-start; display: flex; gap: var(--s-24); justify-content: space-between; padding: 12px 0 4px; }
.rt-vdp-title-col { min-width: 0; }
/* 30px / 800 / 1.15 — the largest type anywhere in the widget, and an 800
   weight Inter is not loaded at (400/500/600), so it renders synthesised. */
.rt-vdp-title { color: var(--body-font-color, var(--black)); font-size: 30px; font-weight: 800; line-height: 1.15; margin: 0; }
.rt-vdp-subtitle { align-items: center; color: var(--gray-2); display: flex; flex-wrap: wrap; font-size: 14px; gap: 6px 10px; margin-top: 6px; }
.rt-vdp-subtitle-row { align-items: center; display: inline-flex; flex-wrap: wrap; gap: 6px 10px; }
/* Dot separators are generated, not authored — a middot before every span
   except the first, exactly as the website does it. */
.rt-vdp-subtitle > span + span::before,
.rt-vdp-subtitle-row > span + span::before { color: var(--gray-4); content: '·'; margin-right: 10px; }
.rt-vdp-subtitle-row > span:first-child::before { content: none; }
/* 4px is off the radius scale (3/5/7/15) — literal, as the source writes it.
   The !important cancels the generated middot on this one span. */
.rt-vdp-in-transit { background: var(--blue-2); border-radius: 4px; color: var(--blue-4); font-size: 11px; font-weight: 600; padding: 2px 6px; position: relative; }
.rt-vdp-in-transit::before { content: none !important; }
.rt-vdp-in-transit__tooltip { background: var(--white); border: 1px solid var(--gray-5); border-radius: 6px; box-shadow: var(--light-box-shadow); color: var(--gray-1); display: none; font-size: 12px; font-weight: 400; left: 0; padding: var(--s-8) 10px; position: absolute; top: calc(100% + 4px); white-space: nowrap; z-index: 3; }
.rt-vdp-in-transit:hover .rt-vdp-in-transit__tooltip { display: block; }
/* #c0392b, 24px radius, 700, 0.04em — four off-scale values in one rule. */
.rt-vdp-sold { background: #c0392b; border-radius: 24px; color: #fff; display: inline-block; font-size: 12px; font-weight: 700; letter-spacing: 0.04em; margin-top: 10px; padding: 4px 14px; text-transform: uppercase; }

.rt-vdp-actions-col { align-items: flex-end; display: flex; flex: none; flex-direction: column; gap: 10px; }
.rt-vdp-actions { display: flex; gap: var(--s-8); }
.rt-vdp-action-button { align-items: center; background: var(--white); border: 1px solid var(--gray-5); border-radius: var(--border-radius); color: var(--gray-1); cursor: pointer; display: flex; font-size: 13px; font-weight: 600; gap: var(--s-8); padding: var(--s-8) 14px; transition: border-color 0.15s ease; font-family: var(--primary-font); }
.rt-vdp-action-button:hover { border-color: var(--gray-3); }
/* #e53e3e — a THIRD red in the system, next to --red-1 and #c0392b. */
.rt-vdp-action-button.faved { color: #e53e3e; }
.rt-vdp-action-label { white-space: nowrap; }
.rt-vdp-meta { display: flex; gap: var(--s-12); }
.rt-vdp-meta-chip { background: none; border: none; color: var(--gray-3); cursor: pointer; font-size: 12px; padding: 0; font-family: var(--primary-font); }
.rt-vdp-meta-chip:hover { color: var(--gray-1); }
/* #2bb594 — a second green, next to --green-1 and #22c55e. */
.rt-vdp-meta-chip.fs-copied { color: #2bb594; }

/* ---------- Pricing bar ---------- */
.rt-vdp-pricing-bar { padding: 14px 0 18px; }
.rt-vdp-pricing-bar__inner { align-items: center; display: flex; flex-wrap: wrap; gap: var(--s-16) 40px; }
.rt-vdp-pricing-price { min-width: 0; }
/* column-reverse so the DOM reads value-then-label while the eye reads
   label-above-value — the label is the accessible name for the price. */
.rt-vdp-price-wrap { cursor: pointer; display: flex; flex-direction: column-reverse; }
.rt-vdp-price-label { color: var(--gray-2); font-size: 13px; }
.rt-vdp-price-val { color: var(--body-font-color, var(--black)); font-size: 28px; font-weight: 800; line-height: 1.1; }
.rt-vdp-price-val.dol-sign::before { content: '$'; }
.rt-vdp-ask-for-price { color: var(--blue-1); font-size: 20px; font-weight: 700; }
.rt-vdp-msrp { color: var(--gray-3); font-size: 14px; text-decoration: line-through; }
.rt-vdp-msrp .vehicle-msrp-val.dol-sign::before { content: '$'; }
.rt-vdp-savings-rebates { align-items: center; display: flex; gap: var(--s-12); }
.rt-vdp-savings { color: var(--green-1); font-size: 13px; font-weight: 600; }
.rt-vdp-savings.dollar-sign::before { content: 'Save $'; }
.rt-vdp-savings.percent::before { content: 'Save '; }
.rt-vdp-savings.percent::after { content: '%'; }
.rt-vdp-rebates-count { color: var(--blue-1); font-size: 12px; font-weight: 600; }
.rt-vdp-rebates-count::after { content: ' Incentives'; }
.rt-vdp-rebates-count[data-count='1']::after { content: ' Incentive'; }
.rt-vdp-pricing-payment { border-left: 1px solid var(--gray-5); padding-left: 40px; }
.rt-vdp-pricing-payment__val { color: var(--body-font-color, var(--black)); font-size: 20px; font-weight: 700; }
.rt-vdp-pricing-payment__val span { color: var(--gray-2); font-size: 13px; font-weight: 500; }
.rt-vdp-pricing-payment__terms { color: var(--gray-2); font-size: 13px; margin-top: 2px; }
/* rgb(245 254 250) + #c8e9da + #2bb594: a mint palette used nowhere else. */
.rt-vdp-prequal { align-items: center; background: rgb(245 254 250); border: 1px solid #c8e9da; border-radius: var(--border-radius); cursor: pointer; display: flex; gap: var(--s-12); margin-left: auto; padding: var(--s-12) 18px; }
.rt-vdp-prequal__icon { color: #2bb594; font-size: 20px; }
.rt-vdp-prequal__text { font-size: 13px; }
.rt-vdp-prequal__text > span:last-child { color: var(--gray-2); }
.rt-vdp-prequal__link { color: var(--primary-color, #333); font-weight: 700; text-decoration: underline; }

/* ---------- Shipping ---------- */
.rt-vdp-shipping { position: relative; }
.rt-vdp-shipping__summary { cursor: pointer; }
/* .shippingLoading — omitted on the first pass. VdpShipping stacks its two
   shimmer bars in a column at a 6px gap while the estimate resolves. */
.rt-vdp-shipping__loading { display: flex; flex-direction: column; gap: 6px; }
.rt-vdp-shipping__val { color: var(--body-font-color, var(--black)); font-size: 20px; font-weight: 700; }
.rt-vdp-shipping__label { color: var(--gray-2); font-size: 13px; margin-top: 2px; }
.rt-vdp-shimmer-text, .rt-vdp-shimmer-text--sm { animation: rt-vdp-shimmer 1.2s ease-in-out infinite; background: linear-gradient(270deg, #eaecee 0%, #e5e5e7 100%); border-radius: 4px; display: block; height: 18px; width: 84px; }
.rt-vdp-shimmer-text--sm { height: 12px; width: 64px; }
/* 10px radius — the ValueBox/PaymentOption value, off the scale again. */
.rt-vdp-shipping__tooltip { background: var(--white); border: 1px solid var(--gray-5); border-radius: 10px; box-shadow: var(--light-box-shadow); display: none; left: 0; padding: 14px var(--s-16); position: absolute; top: calc(100% + 8px); width: 320px; z-index: 6; }
.rt-vdp-shipping__tooltip.show { display: block; }
.rt-vdp-shipping__tooltip-header { align-items: center; display: flex; font-size: 14px; font-weight: 700; justify-content: space-between; margin-bottom: var(--s-8); }
.rt-vdp-shipping__row { display: flex; font-size: 13px; gap: var(--s-12); justify-content: space-between; padding: 4px 0; }
.rt-vdp-shipping__row-label { color: var(--gray-2); }
.rt-vdp-shipping__row-value { color: var(--gray-1); font-weight: 600; text-align: right; }
.rt-vdp-shipping__total { border-top: 1px solid var(--gray-6); margin-top: 4px; padding-top: var(--s-8); }
.rt-vdp-shipping__disclaimer { color: var(--gray-3); font-size: 11px; margin-top: var(--s-8); }

/* ---------- Gallery ---------- */
/* 12px radius on the main image, 10px on the grid cells — two more off-scale
   radii, and they differ from each other by 2px. */
.rt-vdp-gallery { display: flex; gap: var(--s-12); padding-bottom: var(--s-8); }
.rt-vdp-gallery[data-grid-images='0'] .rt-vdp-gallery__grid { display: none; }
.rt-vdp-gallery__main { border-radius: 12px; cursor: pointer; flex: 1; min-width: 0; overflow: hidden; position: relative; }
.rt-vdp-gallery__main-image { aspect-ratio: 16 / 9; display: block; height: 100%; max-height: 620px; object-fit: cover; width: 100%; }
.rt-vdp-gallery__grid { display: grid; flex: 0 0 34%; gap: var(--s-12); grid-template-columns: 1fr 1fr; grid-template-rows: repeat(3, 1fr); }
.rt-vdp-grid-cell { border-radius: 10px; cursor: pointer; overflow: hidden; position: relative; }
.rt-vdp-grid-cell img { display: block; height: 100%; object-fit: cover; width: 100%; }
.rt-vdp-photo-count { align-items: center; background: rgb(0 0 0 / 65%); border-radius: var(--s-8); bottom: var(--s-8); color: #fff; display: flex; font-size: 13px; font-weight: 600; gap: 6px; padding: 6px 10px; position: absolute; right: var(--s-8); }
/* The video branch — omitted on the first pass. The play affordance is a
   centred 64px glyph over the main image; once playing, a black container
   fills the frame and carries its own round close button. faCirclePlay is
   pro-SOLID, one of the few solid icons in the widget. */
.rt-vdp-video-play-overlay { align-items: center; color: rgb(255 255 255 / 92%); cursor: pointer; display: flex; filter: drop-shadow(0 2px 8px rgb(0 0 0 / 45%)); font-size: 64px; inset: 0; justify-content: center; position: absolute; z-index: 2; }
.rt-vdp-video-container { background: #000; inset: 0; position: absolute; z-index: 3; }
.rt-vdp-video-frame { border: none; height: 100%; width: 100%; }
.rt-vdp-video-embed { height: 100%; width: 100%; }
.rt-vdp-video-embed iframe, .rt-vdp-video-embed video { border: none; height: 100%; width: 100%; }
.rt-vdp-video-close { align-items: center; background: rgb(0 0 0 / 65%); border: none; border-radius: 50%; color: #fff; cursor: pointer; display: flex; font-size: 16px; height: 36px; justify-content: center; position: absolute; right: var(--s-12); top: var(--s-12); width: 36px; z-index: 4; }

.rt-vdp-tag-badges { bottom: var(--s-12); display: flex; flex-wrap: wrap; gap: var(--s-8); left: var(--s-12); pointer-events: none; position: absolute; z-index: 2; }
/* Same #e0f634 / 24px as the SRP card's badge — the only two uses of either. */
.rt-vdp-tag-badge { background: #e0f634; border-radius: 24px; color: #1e1e1e; font-size: 12px; font-weight: 600; padding: 4px 10px; }
@keyframes rt-vdp-shimmer { 0%, 100% { opacity: 1; } 50% { opacity: 0.55; } }

/* ---------- Sidebar ---------- */
/* 360px fixed; #ececec is the VDP's card border everywhere, replacing
   --gray-5/--gray-6, and 12px is its card radius, replacing --r-7. */
.rt-vdp-sidebar { align-self: flex-start; flex: 0 0 360px; }
/* top is written inline by a ResizeObserver: 12px when the sidebar fits the
   viewport, else window.innerHeight − contentHeight − 80 so its END is
   reachable — a bottom-anchored sticky, not a top-anchored one. */
.rt-vdp-sidebar__inner { display: flex; flex-direction: column; gap: var(--s-16); position: sticky; top: 12px; }
.rt-vdp-dealer-card { background: var(--white); border: 1px solid #ececec; border-radius: 12px; display: flex; flex-direction: column; gap: var(--s-8); padding: 20px; }
/* 11px / 700 / 0.08em uppercase — the widget's only letter-spaced label. */
.rt-vdp-info-label { color: var(--gray-3); font-size: 11px; font-weight: 700; letter-spacing: 0.08em; }
.rt-vdp-dealer-name { color: var(--body-font-color, var(--black)); font-size: 18px; font-weight: 700; }
.rt-vdp-dealer-detail { align-items: baseline; color: var(--gray-2); display: flex; font-size: 13px; gap: 10px; }
.rt-vdp-dealer-detail a { color: var(--gray-1); font-weight: 600; text-decoration: none; }
.rt-vdp-dealer-detail a:hover { text-decoration: underline; }

/* ---------- Fulfillment tabs ---------- */
.rt-vdp-fulfillment { background: var(--white); border: 1px solid #ececec; border-radius: 12px; overflow: hidden; }
.rt-vdp-fulfillment__tabs { border-bottom: 1px solid #ececec; display: flex; }
.rt-vdp-fulfillment__tab { background: none; border: none; border-bottom: 2px solid transparent; color: var(--gray-2); cursor: pointer; display: flex; flex: 1; flex-direction: column; font-size: 16px; gap: 2px; padding: var(--s-12) var(--s-8) 10px; text-align: center; font-family: var(--primary-font); }
.rt-vdp-fulfillment__tab svg { margin: 0 auto 2px; }
/* #5b4ccc — an indigo fallback that matches NOTHING in the token set
   (--indigo-1 is #7078c7). Three rules use it: this, the highlight icon and
   the feature category icon. It only shows when the host sets no
   --primary-color, so on a bare mount the VDP's accent is purple. */
.rt-vdp-fulfillment__tab.active { border-bottom-color: var(--primary-color, #5b4ccc); color: var(--body-font-color, var(--black)); }
.rt-vdp-tab-label { font-size: 13px; font-weight: 600; }
.rt-vdp-tab-sub { color: var(--gray-3); font-size: 11px; }
.rt-vdp-fulfillment__body { padding: var(--s-16) 20px; }
.rt-vdp-fulfillment__panel { animation: rt-vdp-panel-fade 0.25s ease; }
.rt-vdp-fulfillment__heading { font-size: 15px; font-weight: 700; }
.rt-vdp-fulfillment__detail { color: var(--gray-2); font-size: 13px; margin-top: 4px; }
.rt-vdp-fulfillment__sub { color: var(--gray-3); font-size: 12px; margin-top: 4px; }
@keyframes rt-vdp-panel-fade { from { opacity: 0; } to { opacity: 1; } }

/* ---------- CTA stack ---------- */
.rt-vdp-sidebar-ctas { display: flex; flex-direction: column; gap: 10px; }
.rt-vdp-module-wrap, .rt-vdp-button-wrap { width: 100%; }
/* 44px min-height — a FOURTH control height, next to the SRP card's 40px and
   the system's 32/48/64. */
.rt-vdp-cta-button { align-items: center; border: none; border-radius: var(--button-radius); cursor: pointer; display: flex; font-size: 14px; font-weight: 600; justify-content: center; min-height: 44px; padding: 10px var(--s-16); text-align: center; text-decoration: none; transition: opacity 0.15s ease; width: 100%; font-family: var(--primary-font); }
.rt-vdp-cta-button:hover { opacity: 0.9; }
.rt-vdp-cta-button.btn-primary { background: var(--primary-color, var(--primary-accent)); color: var(--primary-button-text-color, #fff); }
.rt-vdp-cta-button.btn-secondary { background: var(--white); border: 1px solid var(--gray-5); color: var(--body-font-color, var(--black)); }
.rt-vdp-breakdown-module { background: var(--white); border: 1px solid #ececec; border-radius: 12px; padding: var(--s-16); position: relative; }
.rt-vdp-breakdown-module.is-collapsed .rt-vdp-breakdown-module__inner { max-height: 180px; overflow: hidden; }
.rt-vdp-breakdown-fade { background: linear-gradient(rgb(255 255 255 / 0%), var(--white)); bottom: 40px; height: 56px; left: 0; pointer-events: none; position: absolute; right: 0; }
.rt-vdp-breakdown-toggle { background: none; border: none; color: var(--primary-color, #333); cursor: pointer; display: block; font-size: 13px; font-weight: 600; margin-top: var(--s-8); padding: 4px 0; text-decoration: underline; width: 100%; font-family: var(--primary-font); }

/* ---------- Sections ---------- */
/* Sections start hidden and reveal on scroll via a .fs-revealed class an
   IntersectionObserver adds (useSectionReveal). Honoured by the
   prefers-reduced-motion block at the end of this file. */
.rt-vdp-section { opacity: 0; padding: var(--s-24) 0; transform: translateY(12px); transition: opacity 0.5s ease, transform 0.5s ease; }
.rt-vdp-section.fs-revealed { opacity: 1; transform: none; }
/* 22px / 800 — the section heading. h2 is 24/32/600 in the tray; nothing here
   goes through the type tokens. */
.rt-vdp-section__header h2 { color: var(--body-font-color, var(--black)); font-size: 22px; font-weight: 800; margin: 0 0 var(--s-16); }

.rt-vdp-highlights-grid { display: grid; gap: var(--s-12); grid-template-columns: repeat(3, 1fr); }
.rt-vdp-highlight-card { align-items: center; background: var(--white); border: 1px solid #ececec; border-radius: 12px; display: flex; gap: 14px; padding: var(--s-16); position: relative; }
.rt-vdp-highlight-icon { color: var(--primary-color, #5b4ccc); font-size: 22px; }
.rt-vdp-highlight-title { color: var(--body-font-color, var(--black)); font-size: 16px; font-weight: 700; }
.rt-vdp-highlight-sub { color: var(--gray-2); font-size: 12px; }
/* #222 — a near-black used only here, where --gray-0 (#272727) would do. */
.rt-vdp-highlight-tooltip { background: #222; border-radius: var(--s-8); bottom: calc(100% + 6px); color: #fff; display: none; font-size: 12px; left: 0; padding: var(--s-8) 10px; position: absolute; width: max-content; max-width: 260px; z-index: 3; }
.rt-vdp-highlight-card[data-tooltip]:hover .rt-vdp-highlight-tooltip { display: block; }

.rt-vdp-epa-history-row { display: flex; gap: var(--s-24); }
.rt-vdp-epa-history-duo > * { flex: 1; min-width: 0; }
.rt-vdp-epa-panel, .rt-vdp-history-panel { min-width: 0; width: 100%; }
.rt-vdp-epa-content { background: var(--white); border: 1px solid #ececec; border-radius: 12px; padding: var(--s-24); }
.rt-vdp-epa-electric { align-items: center; display: flex; flex-direction: column; gap: var(--s-12); }
/* The range dial animates by stroke-dashoffset 565 → 0 over 1.2s once
   .fs-animated lands. Under reduced motion the offset resets to 141, not 0:
   the ring still shows a partial arc rather than snapping full. */
.rt-vdp-range-circle { height: 200px; position: relative; width: 200px; }
.rt-vdp-range-circle svg { height: 100%; width: 100%; }
.rt-vdp-range-circle circle:last-child { transition: stroke-dashoffset 1.2s ease; }
.rt-vdp-range-circle:not(.fs-animated) circle:last-child { stroke-dashoffset: 565; }
.rt-vdp-range-text { align-items: center; display: flex; flex-direction: column; inset: 0; justify-content: center; position: absolute; }
.rt-vdp-range-num { color: var(--body-font-color, var(--black)); font-size: 34px; font-weight: 800; line-height: 1.05; }
.rt-vdp-range-unit { color: var(--gray-2); font-size: 13px; }
.rt-vdp-epa-disclaimer { color: var(--gray-3); font-size: 12px; text-align: center; }
.rt-vdp-history-card { background: var(--white); border: 1px solid #ececec; border-radius: 12px; display: flex; gap: var(--s-24); padding: var(--s-24); }
.rt-vdp-history-highlights { display: flex; flex: 1; flex-direction: column; gap: 10px; }
.rt-vdp-history-highlight { align-items: baseline; color: var(--gray-1); display: flex; font-size: 14px; gap: 10px; }
/* #22c55e — a third green, next to --green-1 (#39d262) and #2bb594. */
.rt-vdp-history-highlight svg { color: #22c55e; }
.rt-vdp-history-carfax { align-items: flex-start; display: flex; flex: 1; flex-direction: column; gap: 10px; }
.rt-vdp-carfax-logo { max-height: 32px; }
.rt-vdp-carfax-desc { color: var(--gray-2); font-size: 13px; margin: 0; }
.rt-vdp-carfax-button { align-items: center; background: var(--white); border: 1px solid var(--gray-5); border-radius: var(--button-radius); color: var(--body-font-color, var(--black)); display: inline-flex; font-size: 13px; font-weight: 600; gap: var(--s-8); padding: var(--s-8) var(--s-16); text-decoration: none; }
.rt-vdp-carfax-button:hover { border-color: var(--gray-3); }

/* 1.7 unitless line-height on a 14px body — 23.8px, where body3 would be 24. */
.rt-vdp-description-body { color: var(--gray-1); font-size: 14px; line-height: 1.7; max-width: 900px; }
.rt-vdp-description-body p { margin: 0 0 var(--s-12); }
.rt-vdp-desc-intro { margin-bottom: var(--s-12); }

.rt-vdp-features-card { background: var(--white); border: 1px solid #ececec; border-radius: 12px; display: flex; flex-direction: column; gap: var(--s-24); padding: var(--s-24); }
.rt-vdp-feature-category-title { align-items: center; color: var(--body-font-color, var(--black)); display: flex; font-size: 15px; font-weight: 700; gap: 10px; margin: 0 0 var(--s-12); }
.rt-vdp-feature-category-title svg { color: var(--primary-color, #5b4ccc); }
.rt-vdp-features-list { display: grid; gap: var(--s-8) var(--s-24); grid-template-columns: repeat(2, 1fr); }
.rt-vdp-feature-row { align-items: baseline; color: var(--gray-1); display: flex; font-size: 13px; gap: 10px; }
.rt-vdp-feature-row svg { color: #22c55e; flex: none; }
.rt-vdp-view-all-button { background: none; border: none; color: var(--primary-color, #333); cursor: pointer; font-size: 13px; font-weight: 600; margin-top: 10px; padding: 0; text-decoration: underline; font-family: var(--primary-font); }

.rt-vdp-packages-list { background: var(--white); border: 1px solid #ececec; border-radius: 12px; padding: var(--s-8) 20px; }
/* #f0f0f0 — a lighter divider than #ececec, 4 shades of grey apart. */
.rt-vdp-package-row { border-bottom: 1px solid #f0f0f0; padding: var(--s-12) 0; }
.rt-vdp-package-row:last-child { border-bottom: none; }
.rt-vdp-package-name-wrap { align-items: center; display: flex; gap: var(--s-12); }
.rt-vdp-package-name { color: var(--gray-1); flex: 1; font-size: 14px; }
.rt-vdp-package-name.weight-strong { font-weight: 600; }
.rt-vdp-package-msrp { color: var(--gray-1); font-size: 14px; font-weight: 600; }
.rt-vdp-package-toggle { background: none; border: none; cursor: pointer; padding: 4px; }
.rt-vdp-package-toggle:disabled { cursor: default; opacity: 0; }
/* A CSS-drawn chevron: two borders on a square, rotated. Not an icon — the
   one place the VDP draws a glyph instead of using Font Awesome. */
.rt-vdp-chevron { border-right: 2px solid var(--gray-3); border-top: 2px solid var(--gray-3); display: block; height: var(--s-8); transform: rotate(135deg); transition: transform 0.15s ease; width: var(--s-8); }
.rt-vdp-package-row.open .rt-vdp-chevron,
.rt-vdp-package-toggle[aria-expanded='true'] .rt-vdp-chevron { transform: rotate(-45deg); }
.rt-vdp-package-children { padding: var(--s-8) 0 0 var(--s-8); }
.rt-vdp-package-option { color: var(--gray-2); font-size: 13px; padding: 4px 0; }

.rt-vdp-specs-card { background: var(--white); border: 1px solid #ececec; border-radius: 12px; padding: var(--s-24); }
.rt-vdp-specs-grid { display: grid; gap: 20px var(--s-24); grid-template-columns: repeat(3, 1fr); }
.rt-vdp-spec-value { color: var(--body-font-color, var(--black)); font-size: 14px; font-weight: 600; overflow-wrap: anywhere; }
.rt-vdp-spec-label { color: var(--gray-3); font-size: 12px; }

/* Two fixed paragraphs, always last, plus an optional dealer one. */
.rt-vdp-disclaimer { color: var(--gray-3); font-size: 12px; line-height: 1.6; padding: var(--s-24) 0 var(--s-8); }
.rt-vdp-disclaimer p { margin: 0 0 var(--s-8); }

/* ---------- Recommended carousel ---------- */
.rt-vdp-recommended { margin: 0 auto; max-width: 1920px; padding: 0 40px 60px; }
.rt-vdp-recommended__heading { font-size: 22px; font-weight: 700; margin: 0 0 20px; }
/* 280px minimum and a 24px gap — the SRP grid is 300/340 at a 16px gutter. */
.rt-vdp-recommended__grid { display: grid; gap: var(--s-24); grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); }

/* ---------- Lightbox ---------- */
.rt-vdp-lightbox { align-items: center; background: rgb(0 0 0 / 90%); display: flex; flex-direction: column; inset: 0; position: fixed; z-index: 10020; }
.rt-vdp-lightbox__close { background: none; border: none; color: #fff; cursor: pointer; font-size: 24px; padding: var(--s-12); position: absolute; right: var(--s-16); top: var(--s-12); z-index: 3; }
.rt-vdp-lightbox__back { align-items: center; background: none; border: none; color: rgb(255 255 255 / 85%); cursor: pointer; display: flex; font-size: 14px; font-weight: 600; gap: var(--s-8); left: var(--s-16); padding: var(--s-12); position: absolute; top: var(--s-12); z-index: 3; font-family: var(--primary-font); }
.rt-vdp-lightbox__title { color: #fff; font-size: 15px; font-weight: 600; margin-top: 18px; }
.rt-vdp-lightbox__image-container { align-items: center; display: flex; flex: 1; justify-content: center; min-height: 0; position: relative; width: 100%; }
.rt-vdp-lightbox__image { max-height: calc(100vh - 180px); max-width: min(92vw, 1400px); object-fit: contain; }
.rt-vdp-lightbox__nav { align-items: center; background: rgb(255 255 255 / 12%); border: none; border-radius: 50%; color: #fff; cursor: pointer; display: flex; font-size: 20px; height: 48px; justify-content: center; position: absolute; top: calc(50% - 24px); width: 48px; z-index: 2; }
.rt-vdp-lightbox__nav--prev { left: var(--s-24); }
.rt-vdp-lightbox__nav--next { right: var(--s-24); }
.rt-vdp-lightbox__counter { color: rgb(255 255 255 / 85%); font-size: 14px; padding: 10px 0 var(--s-16); }
.rt-vdp-lightbox__cta { border: none; border-radius: var(--button-radius); cursor: pointer; font-size: 15px; font-weight: 600; margin-bottom: var(--s-24); min-height: 44px; padding: 10px 28px; font-family: var(--primary-font); }
.rt-vdp-lightbox__grid-content { flex: 1; overflow-y: auto; padding: 64px var(--s-24) var(--s-24); width: 100%; }
.rt-vdp-lightbox__grid { display: grid; gap: var(--s-12); grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); margin: 0 auto; max-width: 1400px; }
.rt-vdp-lightbox__grid-image { border-radius: var(--s-8); cursor: pointer; display: block; width: 100%; }

/* ---------- Responsive ---------- */
/* Tablet: the body stacks and the sidebar unsticks. Note top: auto !important
   — it has to beat the inline top the sticky observer writes. */
@media (max-width: 1024px) {
  .rt-vdp-body { flex-direction: column; gap: var(--s-32); }
  .rt-vdp-sidebar { flex: none; width: 100%; }
  .rt-vdp-sidebar__inner { position: static; top: auto !important; }
  .rt-vdp-epa-history-row { flex-direction: column; }
  .rt-vdp-features-list { grid-template-columns: 1fr; }
  .rt-vdp-specs-grid { grid-template-columns: repeat(2, 1fr); }
  .rt-vdp-highlights-grid { grid-template-columns: repeat(2, 1fr); }
}

/* Mobile: the header is reordered purely with CSS order — breadcrumb(1),
   gallery(2), title row(3), pricing bar(4). The DOM order stays
   breadcrumb, title row, pricing bar, gallery, so the gallery jumps two
   places up and the title row becomes column-reverse (actions above title). */
@media (max-width: 767px) {
  .rt-vdp-header-area, .rt-vdp-body { padding-left: var(--s-16); padding-right: var(--s-16); }
  .rt-vdp-top-bar { order: 1; }
  .rt-vdp-gallery { order: 2; }
  .rt-vdp-title-row { flex-direction: column-reverse; gap: var(--s-12); order: 3; }
  .rt-vdp-pricing-bar { order: 4; }
  .rt-vdp-pricing-bar__inner { align-items: flex-start; flex-direction: column; gap: var(--s-12); }
  .rt-vdp-pricing-payment { border-left: none; padding-left: 0; }
  /* The pre-qual block is DROPPED on mobile, not restacked. */
  .rt-vdp-prequal { display: none; }
  .rt-vdp-title { font-size: 24px; }
  .rt-vdp-actions-col { align-items: flex-start; width: 100%; }
  .rt-vdp-action-label { display: none; }
  .rt-vdp-meta { display: none; }
  /* Mobile gallery: main image above a flex thumbnail row, 4 cells visible,
     8px radii (fixed — no longer the site radius token) and a 4px gap. */
  .rt-vdp-gallery { flex-direction: column; gap: 4px; }
  .rt-vdp-gallery__main { border-radius: var(--s-8); flex: 1 1 70%; }
  .rt-vdp-gallery__main-image { aspect-ratio: 4 / 3; }
  .rt-vdp-gallery__grid { display: flex; flex: 0 0 28%; gap: 4px; }
  .rt-vdp-grid-cell { border-radius: var(--s-8); }
  .rt-vdp-gallery__grid .rt-vdp-grid-cell:nth-child(n + 5) { display: none; }
  .rt-vdp-history-card { flex-direction: column; }
  .rt-vdp-shipping__tooltip { max-width: 360px; width: calc(100vw - 48px); }
  .rt-vdp-lightbox__nav--prev { left: var(--s-8); }
  .rt-vdp-lightbox__nav--next { right: var(--s-8); }
}

@media (max-width: 480px) {
  .rt-vdp-highlights-grid, .rt-vdp-specs-grid { grid-template-columns: 1fr; }
  .rt-vdp-tab-sub { display: none; }
}

/* The Hyundai window-sticker modal, and ONLY it, breaks at max-width 768 —
   one pixel off every other breakpoint in the file (1024 / 767 / 480), so
   between 768 and 767 the sheet is already full-bleed while the rest of the
   VDP is still on its desktop layout. Mirrored verbatim; it looks like a typo
   for 767 but is load-bearing for nobody, so leave it until engineering says. */
.rt-vdp-sheet-modal { align-items: center; display: flex; inset: 0; justify-content: center; position: fixed; z-index: 10020; }
.rt-vdp-sheet-modal__overlay { background: rgb(0 0 0 / 85%); cursor: pointer; inset: 0; position: absolute; }
.rt-vdp-sheet-modal__content { background: #fff; border-radius: var(--s-8); box-shadow: 0 25px 50px -12px rgb(0 0 0 / 50%); display: flex; flex-direction: column; height: 95vh; max-width: 1200px; overflow: hidden; position: relative; width: 95vw; z-index: 1; }
.rt-vdp-sheet-modal__header { background: #fafafa; border-bottom: 1px solid #e5e5e5; color: #1a1a1a; flex-shrink: 0; font-size: 16px; font-weight: 600; padding: 14px 20px; }
.rt-vdp-sheet-modal__close { align-items: center; background: #e8e8e8; border: none; border-radius: 50%; color: #666; cursor: pointer; display: flex; font-size: 16px; height: 32px; justify-content: center; position: absolute; right: var(--s-12); top: 10px; width: 32px; z-index: 2; }
.rt-vdp-sheet-modal__close:hover { background: #d0d0d0; color: #333; }
@media (max-width: 768px) {
  .rt-vdp-sheet-modal__content { border-radius: 0; height: 100%; width: 100%; }
}

/* ---------- Assistant ---------- */
/* Note the hard-coded #3491f7 on the response: the accent value written as a
   literal rather than var(--blue-1), so it will not follow a theme. */
.rt-vdp-assistant-input-wrap { background: #fff; border: 1px solid #e8e8e8; border-radius: var(--border-radius); position: relative; }
.rt-vdp-assistant-input { appearance: none; background: #fff; border: none; border-radius: var(--border-radius); color: #272727; font-size: 14px; font-weight: 400; line-height: 48px; outline: none; padding: 0 var(--s-16); width: 100%; font-family: var(--primary-font); }
.rt-vdp-assistant-input::placeholder { color: #a4a4a8; }
.rt-vdp-assistant-response { background: #fff; border-radius: 0 0 5px 5px; color: #3491f7; font-size: 14px; font-weight: 400; position: relative; transition: 0.4s min-height ease-in-out; }
.rt-vdp-assistant-response:not(:empty) { border: 1px solid #e8e8e8; border-top: none; padding: var(--s-12) var(--s-16); }

@media (prefers-reduced-motion: reduce) {
  .rt-vdp-shimmer-text, .rt-vdp-shimmer-text--sm, .rt-vdp-fulfillment__panel { animation: none; }
  .rt-vdp-section { opacity: 1; transform: none; transition: none; }
  .rt-vdp-range-circle circle:last-child { transition: none; }
  .rt-vdp-range-circle:not(.fs-animated) circle:last-child { stroke-dashoffset: 141; }
}

/* The VDP is the only surface with print rules. */
@media print {
  .rt-vdp-scrim, .rt-vdp-lightbox, .rt-vdp-top-bar, .rt-vdp-actions, .rt-vdp-sidebar, .rt-vdp-gallery__grid { display: none !important; }
}
