/* rr-network.css  Shared lead form, inventory grid and state styling.
   Every colour is a CSS custom property. This file hard-codes no colour value
   at all, so each site's palette drives it entirely. Define the --rr-* colour
   properties in the site stylesheet (see README.md); anything undefined here
   simply paints nothing rather than paints the wrong brand. */

/* A clause the kit switches off with [data-rr-when] must actually disappear,
   including inside a flex or grid parent, where `hidden` alone loses. */
[hidden] { display: none !important; }

/* ---------------------------------------------------------------- grid ---- */
.rr-grid,
[data-rr-inventory] {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--rr-card-min, 17rem), 1fr));
  gap: var(--rr-gap, 1.25rem);
  align-items: stretch;
  margin: 0;
  padding: 0;
  list-style: none;
}

.rr-card {
  display: flex;
  flex-direction: column;
  gap: var(--rr-gap-tight, 0.5rem);
  min-width: 0;
  padding: var(--rr-card-pad, 1rem);
  background: var(--rr-surface);
  color: var(--rr-text);
  border: var(--rr-border-width, 1px) solid var(--rr-border);
  border-radius: var(--rr-radius, 0.5rem);
  transition: border-color var(--rr-motion, 160ms) ease, transform var(--rr-motion, 160ms) ease;
}

.rr-card:hover,
.rr-card:focus-within {
  border-color: var(--rr-accent);
}

.rr-card-media {
  aspect-ratio: var(--rr-card-aspect, 3 / 2);
  overflow: hidden;
  border-radius: var(--rr-radius-inner, 0.375rem);
  background: var(--rr-surface-2);
}

.rr-card-img,
.rr-card-media img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.rr-card-title {
  margin: 0;
  font-family: var(--rr-font-display, inherit);
  font-size: var(--rr-title-size, 1.0625rem);
  line-height: 1.25;
  color: var(--rr-text);
}

.rr-card-title a,
.rr-card a[data-rr-link] {
  color: inherit;
  text-decoration-color: var(--rr-accent);
}

.rr-card-specs {
  display: flex;
  flex-wrap: wrap;
  gap: var(--rr-gap-tight, 0.5rem) var(--rr-gap, 1.25rem);
  margin: 0;
  font-size: var(--rr-small-size, 0.875rem);
  color: var(--rr-text-muted);
}

.rr-card-specs dt { color: var(--rr-text-muted); }
.rr-card-specs dd { margin: 0; color: var(--rr-text); }

.rr-card-price {
  margin: auto 0 0;
  font-family: var(--rr-font-display, inherit);
  font-size: var(--rr-price-size, 1.25rem);
  color: var(--rr-price);
}

.rr-card-per {
  font-size: var(--rr-small-size, 0.875rem);
  color: var(--rr-text-muted);
}

.rr-card-status {
  margin: 0;
  font-size: var(--rr-small-size, 0.875rem);
  color: var(--rr-text-muted);
  text-transform: var(--rr-status-transform, none);
  letter-spacing: var(--rr-status-tracking, normal);
}

.rr-card[data-rr-status="available"] .rr-card-status { color: var(--rr-ok); }
.rr-card[data-rr-status="rented"] .rr-card-status,
.rr-card[data-rr-status="maintenance"] .rr-card-status { color: var(--rr-warn); }

/* -------------------------------------------------------------- states ---- */
/* Server rendered inventory is real content, not a placeholder. It paints at
   full contrast in the state the page actually ships in, and it keeps that
   contrast for ever if JavaScript never runs.

   There is deliberately NO opacity rule on .rr-card in this file.

   The rule that used to live here,

     [data-rr-inventory].rr-is-loading .rr-card { opacity: var(--rr-loading-opacity, 0.9); }

   was the C5 reveal trap wearing a different hat. The build printed
   class="rr-is-loading" into the markup, this stylesheet dimmed it, and only
   rr-network.js ever took the class off. Script blocked, script 404, JS off,
   and the dim was permanent. Measured on the built pages with every <script>
   stripped, at the 0.55 alpha delivery once shipped, body copy on a card fell
   to 2.24:1 on delivery and 2.93:1 on value against a 4.5:1 floor.

   Lightening the dim does not fix that, it only moves the number. The fix is
   that server rendered content is never dimmed at all. `--rr-loading-opacity`
   is RETIRED: a site that still sets it has no effect.

   The pair below is a neutraliser, not decoration. It keeps the kit correct
   even if a build still stamps the class or a site stylesheet still carries a
   copy of the old rule. */
[data-rr-inventory] .rr-card,
[data-rr-inventory].rr-is-loading .rr-card { opacity: 1; }

/* The refresh cue ADDS a row of text instead of subtracting contrast from the
   grid, so there is nothing left for a contrast gate to fail on. It is gated
   twice:

     `.rr-js` on <html>, the same gate the reveal below uses. It is written by
       the head snippet in README section 6 and taken off again by that
       snippet's own watchdog if the kit never claims it, so a page whose
       script did not run can never enter a loading state.
     `.rr-is-loading`, which only rr-network.js writes, never the build.

   A ::before with no `content` does not generate a box, so the shared styling
   here is inert until one of the three content rules below applies. The
   message paints --rr-text-muted on --rr-surface-2, the same pair the stale
   and empty rows already use and that tests/contrast.mjs already measures. */
[data-rr-inventory].rr-is-loading::before,
[data-rr-inventory].rr-is-error::before,
[data-rr-inventory].rr-is-empty::before {
  grid-column: 1 / -1;
  display: block;
  padding: var(--rr-card-pad, 1rem);
  font-size: var(--rr-small-size, 0.875rem);
  color: var(--rr-text-muted);
  background: var(--rr-surface-2);
  border: var(--rr-border-width, 1px) solid var(--rr-border);
  border-radius: var(--rr-radius, 0.5rem);
}

.rr-js [data-rr-inventory].rr-is-loading::before {
  content: var(--rr-msg-loading, "Checking today's prices and availability.");
}

[data-rr-inventory].rr-is-error::before {
  content: var(--rr-msg-stale, "Showing the last saved inventory.");
}

[data-rr-inventory].rr-is-empty::before {
  content: var(--rr-msg-empty, "No vehicles match right now.");
}

@media (prefers-reduced-motion: reduce) {
  .rr-card { transition: none; }
}

/* -------------------------------------------------------------- reveal ---- */
/* C5. Reveal is an enhancement, never a precondition for visibility.
   Content is visible in this file's base state. The hidden state is scoped to
   `.rr-js` on <html>, which is added by the head snippet in README section 6
   and removed again by that snippet's own watchdog if the kit never claims it.
   So a missing, blocked, or broken rr-network.js paints a full page, and the
   worst case is a page that arrives without animation.
   Do NOT reintroduce a bare `.rise { opacity: 0 }` in a site stylesheet. That
   rule is the trap: it hides content on a CSS file that always loads, keyed to
   a JS file that sometimes does not. */
[data-rr-reveal],
.rise {
  opacity: 1;
  transform: none;
  transition:
    opacity var(--rr-reveal-motion, 420ms) ease var(--rr-reveal-delay, 0ms),
    transform var(--rr-reveal-motion, 420ms) ease var(--rr-reveal-delay, 0ms);
}

.rr-js [data-rr-reveal]:not(.rr-shown),
.rr-js .rise:not(.rr-shown) {
  opacity: 0;
  transform: translate3d(0, var(--rr-reveal-shift, 0.75rem), 0);
}

/* Reduced motion and print both get the finished state immediately. */
@media (prefers-reduced-motion: reduce) {
  .rr-js [data-rr-reveal]:not(.rr-shown),
  .rr-js .rise:not(.rr-shown) { opacity: 1; transform: none; }
  [data-rr-reveal],
  .rise { transition: none; }
}

@media print {
  .rr-js [data-rr-reveal]:not(.rr-shown),
  .rr-js .rise:not(.rr-shown) { opacity: 1; transform: none; }
}

/* ---------------------------------------------------------------- form ---- */
.rr-form,
[data-rr-lead-form] {
  display: grid;
  gap: var(--rr-gap, 1.25rem);
  max-width: var(--rr-form-width, 34rem);
  padding: var(--rr-form-pad, 1.5rem);
  background: var(--rr-surface);
  color: var(--rr-text);
  border: var(--rr-border-width, 1px) solid var(--rr-border);
  border-radius: var(--rr-radius, 0.5rem);
}

.rr-field {
  display: grid;
  gap: var(--rr-gap-tight, 0.5rem);
}

.rr-label {
  font-size: var(--rr-small-size, 0.875rem);
  color: var(--rr-text);
}

.rr-req { color: var(--rr-accent); }

.rr-input,
[data-rr-lead-form] input:not([type="checkbox"]):not([type="radio"]):not(.rr-hp),
[data-rr-lead-form] select,
[data-rr-lead-form] textarea {
  width: 100%;
  min-height: var(--rr-control-height, 2.75rem);
  padding: var(--rr-control-pad, 0.625rem 0.75rem);
  font: inherit;
  color: var(--rr-input-text);
  background: var(--rr-input-bg);
  border: var(--rr-border-width, 1px) solid var(--rr-input-border);
  border-radius: var(--rr-radius-inner, 0.375rem);
  appearance: none;
}

[data-rr-lead-form] textarea {
  min-height: var(--rr-textarea-height, 7rem);
  resize: vertical;
}

.rr-input::placeholder,
[data-rr-lead-form] textarea::placeholder {
  color: var(--rr-placeholder);
}

.rr-input:focus-visible,
[data-rr-lead-form] :focus-visible {
  outline: var(--rr-focus-width, 2px) solid var(--rr-focus);
  outline-offset: var(--rr-focus-offset, 2px);
  border-color: var(--rr-focus);
}

.rr-input:user-invalid,
[data-rr-lead-form] input:user-invalid,
[data-rr-lead-form] textarea:user-invalid {
  border-color: var(--rr-danger);
}

.rr-hint {
  font-size: var(--rr-small-size, 0.875rem);
  color: var(--rr-text-muted);
}

/* Honeypot. Off screen rather than display:none so bots still fill it, and
   never reachable by keyboard or by a screen reader. */
.rr-hp {
  position: absolute !important;
  left: -9999px !important;
  width: 1px !important;
  height: 1px !important;
  opacity: 0 !important;
  pointer-events: none !important;
}

.rr-button,
[data-rr-lead-form] [type="submit"] {
  min-height: var(--rr-control-height, 2.75rem);
  padding: var(--rr-button-pad, 0.75rem 1.25rem);
  font: inherit;
  font-family: var(--rr-font-display, inherit);
  color: var(--rr-button-text);
  background: var(--rr-button-bg);
  border: var(--rr-border-width, 1px) solid var(--rr-button-border);
  border-radius: var(--rr-radius-inner, 0.375rem);
  cursor: pointer;
  transition: background-color var(--rr-motion, 160ms) ease;
}

.rr-button:hover,
[data-rr-lead-form] [type="submit"]:hover {
  background: var(--rr-button-bg-hover);
}

.rr-button:disabled,
[data-rr-lead-form] [type="submit"]:disabled {
  opacity: var(--rr-disabled-opacity, 0.6);
  cursor: progress;
}

/* --------------------------------------------------------- form states ---- */
[data-rr-status] {
  min-height: 1.25em;
  font-size: var(--rr-small-size, 0.875rem);
  color: var(--rr-text-muted);
}

[data-rr-status][data-rr-state="sending"] { color: var(--rr-text-muted); }
[data-rr-status][data-rr-state="success"] { color: var(--rr-ok); }
[data-rr-status][data-rr-state="error"] { color: var(--rr-danger); }

.rr-is-sending [data-rr-status]::before,
.rr-is-success [data-rr-status]::before,
.rr-is-error [data-rr-status]::before {
  margin-right: 0.5ch;
}

.rr-is-success [data-rr-status]::before { content: var(--rr-mark-success, "\2713"); }
.rr-is-error [data-rr-status]::before { content: var(--rr-mark-error, "\0021"); }

.rr-is-success { border-color: var(--rr-ok); }
.rr-is-error { border-color: var(--rr-danger); }
