@charset "UTF-8";
/* =============================================================
   Boiler Quote — Extras Layout - 2608251427
   -------------------------------------------------------------
   REPLACES boiler-quote-extras-layout-2608251419.scss — delete that one
   first.

   CHANGE IN THIS VERSION
     The selected-card rule no longer matches .is-selected.

     That class is written by PHP at render time and never changes, so a
     default card kept it after the customer clicked an upgrade and BOTH
     cards showed as selected. Selecting the default again looked correct,
     which is why it read as working one way and not the other.

     :has(:checked) alone is right: the PHP already sets the checked
     attribute on the input, so it covers the initial state and every
     click after it. One selector, one source of truth.

   PAIRED WITH: boiler-quote-extras-2608251410.php, which outputs the
   markup this styles.

   LAYOUT AND STRUCTURE ONLY. Automatic.css owns colour, type scale,
   radii and button appearance. This file only does what ACSS cannot:
   the arrangement of a set of classes it has never heard of.

   ---------------------------------------------------------------
   COLOURS ARE DECLARED ONCE, AT THE TOP, AS HEX
   ---------------------------------------------------------------
   Every colour used below is a custom property in the block that
   follows, and nothing further down uses a literal hex. Swap the hex
   for an ACSS token in one place and the whole file follows:

       --bq-x-accent: var(--action);

   The names are deliberately generic — accent, ink, muted, line —
   rather than named after what they happen to style, so a token can
   be swapped without the name becoming a lie.
   ============================================================= */
.bq-extras {
  /* ---- Colours: replace these hex values with ACSS tokens ---- */
  --bq-x-accent:      #2b7a4b;
  /* selected state, price, button      */
  --bq-x-accent-soft: #eef6f1;
  /* selected card background           */
  --bq-x-on-accent:   #ffffff;
  /* text on the button                 */
  --bq-x-ink:         #1c1c1c;
  /* headings and names                 */
  --bq-x-muted:       #6b6b6b;
  /* descriptions, 'Included'           */
  --bq-x-line:        #e2e2e2;
  /* card borders and rules             */
  --bq-x-surface:     #ffffff;
  /* card background                    */
  --bq-x-well:        #f6f6f6;
  /* image well behind a product photo  */
  /* ---- Everything else ---- */
  --bq-x-radius: .5rem;
  --bq-x-gap: 1rem;
  max-inline-size: 60rem;
  margin-inline: auto;
}
/* ---------- Sections ---------- */
.bq-extras-section {
  margin-block-end: 2.5rem;
}
.bq-extras-heading {
  margin-block: 0 0.75rem;
  font-size: var(--h4, 1.25rem);
  color: var(--bq-x-ink);
}
/* ---------- The option grid ---------- */
/* auto-fit rather than a fixed column count, so two upgrades sit side by
   side and five wrap sensibly — with no breakpoint to maintain as a
   plumber adds items. */
.bq-extras-options {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  gap: var(--bq-x-gap);
}
/* ---------- One card ---------- */
/* The whole card is a <label> wrapping its input, so tapping anywhere on
   it selects the option. On a phone that is the difference between an easy
   tap and a fiddly one. */
.bq-extra {
  display: flex;
  flex-direction: column;
  gap: 0.75rem;
  padding: 1rem;
  border: 1px solid var(--bq-x-line);
  border-radius: var(--bq-x-radius);
  background: var(--bq-x-surface);
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.bq-extra:hover {
  border-color: var(--bq-x-accent);
}
/* ---------- Selected ---------- */
/* :has() reads the input's live checked state, so the card responds to a
   click with no JavaScript.

   NOT .is-selected. That class is written by PHP at render time and never
   changes, so matching it left the default card looking selected after the
   customer chose an upgrade. The checked attribute is already on the input
   when the page loads, so this one selector covers both. */
.bq-extra:has(.bq-extra-input:checked) {
  border-color: var(--bq-x-accent);
  background: var(--bq-x-accent-soft);
}
/* ---------- The radio itself ---------- */
/* Kept visible and put top-left. Hiding it entirely would mean the only
   signal of what is selected is the card's colour — which fails for anyone
   who cannot distinguish it, and removes the affordance that says 'these
   are choices, pick one'. */
.bq-extra-input {
  align-self: flex-start;
  margin: 0;
  accent-color: var(--bq-x-accent);
  cursor: pointer;
}
/* Keyboard focus has to be visible on the CARD, since that is what the eye
   is on — the input alone is small and easily missed. */
.bq-extra:has(.bq-extra-input:focus-visible) {
  outline: 2px solid var(--bq-x-accent);
  outline-offset: 2px;
}
/* ---------- Product image ---------- */
/* A definite block-size on the wrapper, and the image constrained to it.
   max-block-size alone caps a height without creating one, so the image
   would overflow — the same lesson as the results card and the summary.
   Product shots arrive at whatever size the supplier published. */
.bq-extra-image {
  display: flex;
  align-items: center;
  justify-content: center;
  block-size: 9rem;
  padding: 0.5rem;
  border-radius: calc(var(--bq-x-radius) - 2px);
  background: var(--bq-x-well);
  overflow: hidden;
}
.bq-extra-image img {
  max-inline-size: 100%;
  max-block-size: 100%;
  inline-size: auto;
  block-size: auto;
  object-fit: contain;
}
/* ---------- Card text ---------- */
/* A column, with the price pushed to the bottom by margin-block-start:auto,
   so prices line up across cards whatever length the descriptions are. */
.bq-extra-detail {
  display: flex;
  flex-direction: column;
  gap: 0.35rem;
  flex: 1;
}
.bq-extra-name {
  font-weight: 500;
  color: var(--bq-x-ink);
}
.bq-extra-description {
  font-size: var(--text-s, 0.875rem);
  line-height: 1.5;
  color: var(--bq-x-muted);
}
.bq-extra-price {
  margin-block-start: auto;
  padding-block-start: 0.5rem;
  font-weight: 500;
  color: var(--bq-x-accent);
}
/* ---------- Continue ---------- */
/* One button, deliberately. Continuing with nothing changed is already one
   click because the defaults are pre-selected, so a separate 'no thanks'
   would only make the customer work out which one applies to them. */
.bq-extras-actions {
  padding-block-start: 1.5rem;
  border-block-start: 1px solid var(--bq-x-line);
}
.bq-extras-continue {
  display: block;
  inline-size: 100%;
  padding: 0.9rem 1rem;
  border: 0;
  border-radius: var(--bq-x-radius);
  background: var(--bq-x-accent);
  color: var(--bq-x-on-accent);
  font-size: var(--text-m, 1rem);
  font-weight: 500;
  cursor: pointer;
}
.bq-extras-continue:hover {
  filter: brightness(0.94);
}
/* ---------- Missing quote ---------- */
.bq-extras-missing {
  max-inline-size: 60rem;
  margin-inline: auto;
  padding: 1.5rem;
  border-radius: var(--bq-x-radius);
  background: var(--bq-x-well);
}
/* ---------- Narrow screens ---------- */
/* One card per row, and a shorter image well — a 9rem photo plus text uses
   most of a phone screen for a single option, which makes a list of five
   feel much longer than it is. */
@media (max-width: 30rem) {
  .bq-extras-options {
    grid-template-columns: 1fr;
  }
  .bq-extra-image {
    block-size: 7rem;
  }
  .bq-extras-section {
    margin-block-end: 2rem;
  }
}
