/* ==========================================================================
   Instant quote builder
   The item picker is a working surface; the summary is an instrument panel.
   Volume is the thing being sold, so the yard bar sits above the price — you
   see the space fill, then the number that follows from it.
   ========================================================================== */

.qhead {
  padding: clamp(2rem, 5vw, 3.2rem) 0 clamp(1.4rem, 3vw, 2rem);
  border-bottom: 1px solid var(--rule);
}
.qhead .h2 { margin-bottom: .5rem; }

/* the published formula, stated once at the top */
.formula {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: .5rem 1.1rem;
  margin-top: 1.5rem; padding: 1.1rem 1.3rem;
  background: var(--panel-deep-wide); border-radius: var(--r-lg);
  box-shadow: var(--lift);
}
.formula__bit { color: var(--paper); font-size: var(--step--1); }
.formula__bit strong {
  font-family: var(--mono); font-weight: 600; font-size: var(--step-1);
  margin-right: .3rem; letter-spacing: -.02em;
  background: linear-gradient(180deg, #F5A99C 0%, var(--mark) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* #ADB2AE, not the darker greys these used against a flat --ink — the
   lightest corner of --panel-deep-wide (#123c67) is lighter than flat
   --ink was, and the old greys measured under 3:1 against it. */
.formula__op { font-family: var(--mono); color: #ADB2AE; font-size: var(--step--1); }
.formula__note { flex-basis: 100%; font-size: .82rem; color: #ADB2AE; margin-top: .3rem; }

.qfilter {
  display: block; width: 100%; max-width: 420px; margin-top: 1.4rem;
  font-family: var(--text); font-size: 1rem;
  border: 1.5px solid var(--rule); border-radius: var(--r);
  padding: .7rem .9rem; background: var(--paper); color: var(--ink);
}
.qfilter:focus { outline: 3px solid var(--sorted); outline-offset: 1px; border-color: var(--ink); }

.qsec { padding-top: clamp(1.8rem, 4vw, 2.6rem); }
.qlayout { display: grid; grid-template-columns: 1fr 360px; gap: 2.5rem; align-items: start; }

.qgroup { margin-bottom: 2rem; }
.qgroup__title {
  font-size: var(--step-1); padding-bottom: .5rem; margin-bottom: .9rem;
  border-bottom: 2px solid var(--ink);
}
/* Requested red for the category headings on the item-picker pages
   specifically (By the load / Furniture / Electrical / General waste /
   Access) -- scoped to .qgroup so book.html's own .bgroup headings, which
   already carry their own speed/eco border colours, are untouched. #B3261E
   is this site's existing alarm red (.warnbox), reused rather than a new
   colour; 6.31:1 on the page background, comfortably AA. */
.qgroup .qgroup__title { color: #B3261E; }
.qgroup__hint { margin: -.4rem 0 .9rem; font-size: var(--step--1); color: var(--quiet); }

.qitems { display: grid; grid-template-columns: repeat(2, 1fr); gap: .6rem; }

.qitem {
  display: flex; align-items: center; gap: .8rem;
  border: 1px solid var(--rule); border-radius: var(--r);
  padding: .7rem .85rem; background: var(--paper);
  transition: border-color .15s ease, box-shadow .15s ease;
}
/* Selected rows carry a measurement mark, not a colour wash. */
.qitem.is-on {
  border-color: var(--ink);
  box-shadow: inset 3px 0 0 var(--mark);
}
.qitem__emoji { font-size: 1.35rem; line-height: 1; filter: grayscale(.15); }
.qitem__body { flex: 1; min-width: 0; }
.qitem__name {
  display: block; font-weight: 600; font-size: var(--step-0);
  color: var(--ink); line-height: 1.2; letter-spacing: -.012em;
}
.qitem__price {
  font-family: var(--mono); font-size: var(--step--1); color: var(--graphite);
  display: flex; align-items: baseline; gap: .5rem;
}
.qitem__yards { color: var(--quiet); font-size: .72rem; }

.stepper { display: flex; align-items: center; gap: .25rem; }
.stepper button {
  width: 32px; height: 32px; flex: none;
  border-radius: 7px; border: 1px solid var(--rule); background: var(--sheet);
  font-size: 1.05rem; font-weight: 600; color: var(--ink);
  cursor: pointer; line-height: 1;
  transition: background .12s ease, border-color .12s ease, color .12s ease;
}
.stepper button:hover:not(:disabled) { background: var(--mark); border-color: var(--mark); color: #fff; }
.stepper button:disabled { opacity: .3; cursor: default; }
.stepper output {
  min-width: 24px; text-align: center;
  font-family: var(--mono); font-weight: 600; font-size: var(--step-0); color: var(--ink);
}

.qextras { display: grid; gap: .5rem; }
.qcheck {
  display: flex; align-items: center; gap: .7rem;
  border: 1px solid var(--rule); border-radius: var(--r);
  padding: .75rem .9rem; cursor: pointer; background: var(--paper);
}
.qcheck:has(input:checked) { border-color: var(--ink); box-shadow: inset 3px 0 0 var(--mark); }
.qcheck input { width: 18px; height: 18px; accent-color: var(--mark); flex: none; }
.qcheck span { display: flex; justify-content: space-between; width: 100%; gap: 1rem; align-items: baseline; }
.qcheck strong { font-weight: 550; color: var(--ink-2); font-size: var(--step--1); }
.qcheck em { font-style: normal; font-family: var(--mono); color: var(--ink); font-size: var(--step--1); }

.qfree {
  margin: 0; border: 1px solid var(--sorted); background: var(--sorted-wash);
  border-radius: var(--r); padding: .75rem .9rem;
}
.qfree strong { display: block; font-weight: 650; color: var(--sorted); font-size: var(--step-0); }
.qfree span { font-size: var(--step--1); color: var(--ink-2); }

/* ------------------------------------------------- the instrument panel --- */

.qsummary { position: sticky; top: 88px; }
.qsummary__inner {
  background: var(--paper); border: 1.5px solid var(--ink);
  border-radius: var(--r-lg); padding: 1.3rem; box-shadow: var(--lift);
}
.qsummary__label {
  font-family: var(--mono); font-size: .72rem; letter-spacing: .12em;
  text-transform: uppercase; color: var(--quiet); margin: 0 0 .8rem;
}
.qsummary__cap { font-size: .8rem; color: var(--quiet); margin: .45rem 0 1rem; }
.qsummary__cap--over { color: var(--mark-ink); }
.qsummary__yardhint {
  font-size: .78rem; color: var(--graphite); background: var(--paper-dim, #F4F1EA);
  border-radius: var(--r); padding: .55rem .75rem; margin: -.5rem 0 1rem;
}

.qtotal {
  font-family: var(--mono); font-weight: 600; font-size: clamp(2.4rem, 7vw, 3.1rem);
  line-height: 1; margin: 0 0 .25rem; letter-spacing: -.04em;
  background: linear-gradient(180deg, var(--ink) 0%, var(--ink-deep) 100%);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.qtotal__note { font-size: var(--step--1); margin: 0 0 1rem; color: var(--graphite); }

.qlines { list-style: none; margin: 0 0 .7rem; padding: 0; }
.qlines li {
  display: flex; justify-content: space-between; gap: 1rem;
  font-size: var(--step--1); padding: .28rem 0;
  border-bottom: 1px solid var(--rule);
}
.qlines strong { color: var(--ink-2); }

.qbreak { border-top: 1px solid var(--rule); margin: .7rem 0 1.1rem; padding-top: .5rem; }
.qbreak > div { display: flex; justify-content: space-between; padding: .35rem .5rem; font-size: var(--step--1); }
/* Real bug, caught live 2026-09-11: this rule's own `display: flex` beats
   the browser's built-in `[hidden] { display: none }` (an author-stylesheet
   rule always wins over the UA default, even at equal specificity), so
   q-min-row/q-pops-row/q-extras-row were rendering visible — "Minimum
   charge top-up £0" and "Upholstery (POPs) disposal £0" showing on every
   booking regardless of whether either actually applied — despite
   JS correctly setting `.hidden = true` on them. */
.qbreak > div[hidden] { display: none; }
.qbreak__label {
  margin: 0 0 .3rem; font-family: var(--mono); font-size: .68rem;
  letter-spacing: .12em; text-transform: uppercase; color: var(--quiet);
}
.qroute { border-radius: 6px; color: var(--quiet); }
.qroute strong { color: var(--quiet) !important; font-weight: 500; }
.qroute.is-charged { background: var(--mark-wash); color: var(--ink-2); }
.qroute.is-charged strong { color: var(--mark-ink) !important; font-weight: 600; }
.qroute.is-charged span::after {
  content: " — you pay this"; font-size: .75rem; color: var(--mark-ink); opacity: .8;
}

.qsummary .btn { margin-bottom: .5rem; }
.qreset {
  display: block; width: 100%; background: none; border: 0; padding: .35rem 0;
  color: var(--quiet); font-family: var(--text); font-size: .82rem;
  text-decoration: underline; cursor: pointer;
}
.qsummary__fine { font-size: .76rem; color: var(--quiet); margin: .7rem 0 0; }

@media (max-width: 960px) {
  .qlayout { grid-template-columns: 1fr; }
  /* On a phone the panel sticks to the bottom instead of the side. */
  .qsummary { position: sticky; top: auto; bottom: 0; z-index: 50; }
  .qsummary__inner { border-radius: var(--r-lg) var(--r-lg) 0 0; }
}

@media (max-width: 620px) {
  .qitems { grid-template-columns: 1fr; }
  .qsec { padding-bottom: 84px; }
  .qsummary { position: static; }
}

/* Item icons, drawn at true relative scale — a fridge really is four times a
   TV, because it takes four times the space. The picture does two jobs:
   identify the item, and teach the volume pricing. */
.qitem__icon {
  width: 42px; height: 42px; flex: none;
  display: grid; place-items: center;
  color: var(--ink);
}
.qitem__icon svg { width: 100%; height: 100%; }
.qitem.is-on .qitem__icon { color: var(--mark-ink); }

/* ---------------------------------------------------- graphic room picker */
/* Shared by /waste-calculator.html and /house-clearance.html's "Pick a
   room" section — one illustrated room per tab, with clickable hotspots
   that just trigger the matching .qitem's own "+" button (quote.js still
   owns all real basket/price state; a hotspot is a shortcut, not a second
   source of truth). */
.roomtabs__banner {
  background: var(--sorted); color: #fff; font-weight: 600;
  border-radius: var(--r); padding: .8rem 1.1rem; margin: 1.4rem 0 0;
  font-size: var(--step--1);
}
.roomtabs { display: flex; gap: .5rem; margin: 1.2rem 0 1.6rem; flex-wrap: wrap; }
.roomtab {
  border: 2px solid var(--ink); background: var(--paper); border-radius: 999px;
  padding: .5rem 1.1rem; font: inherit; font-weight: 600; cursor: pointer;
  color: var(--ink);
}
.roomtab.is-on { background: var(--mark); border-color: var(--mark); color: #fff; }
.isoroom-pane[hidden] { display: none; }
.isoroom-wrap {
  margin-bottom: .6rem; border-radius: 12px; overflow: hidden;
  border: 2px solid var(--ink); background: #fff; max-width: 640px;
}
.isoroom-wrap svg { width: 100%; height: auto; display: block; }
.hotspot { cursor: pointer; }
.hotspot__ring {
  fill: #fff; stroke: var(--mark); stroke-width: 3;
  transition: transform .15s ease, fill .15s ease;
  transform-origin: center; transform-box: fill-box;
}
.hotspot__plus { font: 700 18px/1 inherit; fill: var(--mark); pointer-events: none; }
.hotspot:hover .hotspot__ring, .hotspot:focus-visible .hotspot__ring { fill: var(--mark); transform: scale(1.15); }
.hotspot:hover .hotspot__plus, .hotspot:focus-visible .hotspot__plus { fill: #fff; }
.hotspot:focus-visible { outline: none; }
.isoroom-hint { font-size: .85rem; color: var(--quiet); margin: .3rem 0 0; }
.isoroom-hint a { color: var(--mark-ink); font-weight: 600; }

/* Hotspot click pop-up — names the item and its price before it's added,
   rather than the total silently changing somewhere below the fold.
   [hidden] is spelled out explicitly here: a plain author-stylesheet rule
   giving this class its own `display` always beats the browser's built-in
   `[hidden] { display: none }`, even at equal selector specificity, since
   the UA stylesheet is always the lowest-priority tier — without this
   line the popup stays laid out (and keeps intercepting clicks across the
   whole viewport via its fixed positioning) regardless of the hidden
   attribute's real value. Found live: `elementFromPoint` at a hotspot's
   own coordinates was returning the popup's own child, not the hotspot,
   while `.hidden` read true — the popup was invisibly still there. */
.hotspot-popup {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(7,29,51,.45);
  display: flex; align-items: center; justify-content: center;
  padding: 1rem;
}
.hotspot-popup[hidden] { display: none; }
.hotspot-popup__card {
  position: relative; width: 100%; max-width: 300px;
  background: var(--paper); border-radius: var(--r-lg);
  box-shadow: var(--lift-lg); padding: 1.6rem 1.4rem 1.4rem;
  text-align: center;
}
.hotspot-popup__close {
  position: absolute; top: .6rem; right: .7rem; border: 0; background: none;
  font-size: 1.4rem; line-height: 1; color: var(--quiet); cursor: pointer; padding: .2rem;
}
.hotspot-popup__name { font-weight: 700; font-size: var(--step-1); color: var(--ink); margin: 0 0 .3rem; }
.hotspot-popup__meta { font-family: var(--mono); font-size: var(--step--1); color: var(--graphite); margin: 0 0 1rem; }
.hotspot-popup__stepper { display: flex; align-items: center; justify-content: center; gap: .9rem; }
.hotspot-popup__stepper button {
  width: 40px; height: 40px; border-radius: 50%; border: 1.5px solid var(--ink);
  background: var(--paper); font-size: 1.3rem; font-weight: 600; color: var(--ink);
  cursor: pointer; line-height: 1;
}
.hotspot-popup__stepper button:hover:not(:disabled) { background: var(--mark); border-color: var(--mark); color: #fff; }
.hotspot-popup__stepper button:disabled { opacity: .3; cursor: default; }
.hotspot-popup__stepper output {
  min-width: 32px; font-family: var(--mono); font-weight: 700; font-size: var(--step-2); color: var(--ink);
}
.hotspot-popup__added { margin: .9rem 0 0; font-size: var(--step--1); color: var(--sorted); font-weight: 600; }
