/* One Call Handyman - the /quote/ five-step wizard.
 *
 * Follows site/styles.css so /q/ and /quote/ read as one business: the same
 * .btn, .field, .help and .err recipes, the same focus ring, the same
 * capture zone and thumbnail grid.
 *
 * Every colour is a brand/tokens.css variable. There is not a single
 * literal colour in this file, including in these comments, and that is
 * enforced by a grep in the task brief. If a colour is needed that no token
 * carries, it does not belong on this page.
 *
 * The brand rules the tokens encode, because they are accessibility rules
 * rather than taste:
 *   --brand        identity only. Decorative rules and icon fills. Never
 *                  text, never a button fill.
 *   --brand-deep   brand colour that is readable as text.
 *   --action       the primary action colour. Continue, Send, Try again.
 *   --cta          the phone number button, and nothing else on this page.
 *   --danger       validation errors.
 *   --success      the in-area confirmation.
 *
 * Dark mode needs no rules here: the tokens swap themselves on
 * prefers-color-scheme.
 */

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

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-size: var(--text-base);
  line-height: var(--leading-normal);
  -webkit-font-smoothing: antialiased;
  /* 320px up with nothing poking out sideways. */
  overflow-x: hidden;
}

img { max-width: 100%; display: block; }

h1, h2, h3 {
  font-family: var(--font-heading);
  color: var(--text-heading);
  margin: 0;
  overflow-wrap: break-word;
}
p, ul { margin: 0; }
ul { padding: 0; list-style: none; }

[hidden] { display: none !important; }

:focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
  border-radius: var(--radius-sm);
}

/* Headings and panels take focus on a step change. They are programmatic
   targets, so they get no ring of their own: the heading is announced and
   the ring would read as a control the customer can operate. */
.step__h:focus,
.panel__h:focus { outline: none; }

.vis-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.skip-link {
  position: absolute;
  left: var(--space-3);
  top: -100px;
  z-index: var(--z-toast);
  background: var(--action);
  color: var(--action-text);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-sm);
  font: 600 var(--text-base)/1 var(--font-heading);
  text-decoration: none;
  transition: top var(--dur-fast) var(--ease-out);
}
.skip-link:focus { top: var(--space-3); }

/* ---- buttons (same recipe as site/styles.css) ------------------------ */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--control-h);
  min-width: var(--tap-min);
  padding: 0 var(--space-6);
  border-radius: var(--radius-pill);
  font: 600 var(--text-base)/1 var(--font-heading);
  letter-spacing: var(--tracking-wide);
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  border: 1px solid transparent;
  transition: background var(--dur-fast) var(--ease-out),
              color var(--dur-fast) var(--ease-out);
}

.btn-primary       { background: var(--action); color: var(--action-text); }
.btn-primary:hover { background: var(--action-hover); }

/* The only --cta on this page, on both phone number buttons and nothing
   else. Adding a third use is the accessibility rule broken. */
.btn-cta       { background: var(--cta); color: var(--cta-text); }
.btn-cta:hover { background: var(--cta-hover); }

.btn-ghost {
  background: transparent;
  color: var(--action);
  border-color: var(--border-strong);
}
.btn-ghost:hover { background: var(--bg-subtle); }

.btn[disabled],
.btn[aria-disabled="true"] { opacity: 0.45; cursor: not-allowed; }

/* ---- masthead -------------------------------------------------------- */

.masthead {
  background: var(--surface);
  border-bottom: var(--border-width) solid var(--border);
}

.masthead__in {
  max-width: var(--measure-container);
  margin: 0 auto;
  padding: var(--space-3) var(--gutter);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
}

.masthead__logo { display: inline-flex; flex: none; }
.masthead__logo img { width: 132px; height: auto; }
.masthead__call { flex: none; }

.trust {
  max-width: var(--measure-container);
  margin: 0 auto;
  padding: 0 var(--gutter) var(--space-3);
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-2) var(--space-5);
}

.trust__item {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font: 600 var(--text-sm)/1.4 var(--font-heading);
  color: var(--text-muted);
}

.trust__icon { flex: none; color: var(--brand-deep); }

@media (max-width: 26rem) {
  .masthead__logo img { width: 108px; }
  .masthead__call { padding: 0 var(--space-4); }
  .masthead__call span { font-size: var(--text-sm); }
  .trust { gap: var(--space-1) var(--space-4); }
  .trust__item { font-size: var(--text-xs); }
}

/* ---- hero ------------------------------------------------------------ */

.hero {
  background: var(--bg-subtle);
  border-bottom: var(--border-width) solid var(--border);
}

.hero__in {
  max-width: var(--measure-container);
  margin: 0 auto;
  padding: var(--section-y) var(--gutter);
}

.hero__h {
  font-size: var(--text-4xl);
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  letter-spacing: var(--tracking-tight);
  margin-bottom: var(--space-3);
}

.hero__sub {
  font-size: var(--text-lg);
  line-height: var(--leading-relaxed);
  color: var(--text-muted);
  max-width: var(--measure);
}

/* ---- why ------------------------------------------------------------- */

.why {
  max-width: var(--measure-container);
  margin: 0 auto;
  padding: var(--space-10) var(--gutter) 0;
}

.why__list {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-5);
}

@media (min-width: 40rem) {
  .why__list { grid-template-columns: 1fr 1fr; gap: var(--space-6); }
}

.why__item {
  display: grid;
  grid-template-columns: auto 1fr;
  column-gap: var(--space-3);
  align-items: start;
}

.why__icon {
  flex: none;
  color: var(--brand-deep);
  grid-row: 1 / span 2;
  margin-top: 2px;
}

.why__t {
  font: 600 var(--text-base)/1.4 var(--font-heading);
  color: var(--text-heading);
}

.why__d {
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: var(--leading-relaxed);
}

/* ---- wizard shell ---------------------------------------------------- */

.wizard {
  max-width: var(--measure-container);
  margin: var(--space-10) auto 0;
  padding: var(--space-6) var(--gutter) var(--space-8);
  background: var(--surface);
  border: var(--border-width) solid var(--border);
  border-radius: var(--radius-lg);
}

@media (min-width: 48rem) {
  .wizard {
    padding: var(--space-8);
    box-shadow: var(--shadow-md);
  }
}

.wizard__head { margin-bottom: var(--space-6); }

.wizard__head h2 {
  font-size: var(--text-2xl);
  font-weight: var(--weight-bold);
  line-height: var(--leading-snug);
}

.wizard__sub {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin-bottom: var(--space-4);
}

/* ---- progress -------------------------------------------------------- */

/* A decorative rule, which is the one place --brand is allowed to carry a
   fill. It never carries information on its own: the step count and the
   step name sit underneath it in text. */
.progress {
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--border);
  overflow: hidden;
}

.progress__fill {
  height: 100%;
  width: 20%;
  background: var(--brand);
  border-radius: var(--radius-pill);
  transition: width var(--dur-base) var(--ease-out);
}

.progress__label {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  margin-top: var(--space-2);
  font: 600 var(--text-sm)/1.4 var(--font-heading);
  color: var(--text-muted);
}

/* ---- notice ---------------------------------------------------------- */

.notice {
  border: var(--border-width) solid var(--border-strong);
  border-left: 4px solid var(--brand-deep);
  border-radius: var(--radius-sm);
  background: var(--surface-subtle);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
  font-size: var(--text-sm);
  display: flex;
  gap: var(--space-2);
  align-items: flex-start;
}

.notice svg { flex: none; margin-top: 3px; }

/* The live region is never toggled with the hidden attribute after load,
   because a screen reader can miss a change made to a region that was
   hidden a moment ago. It stays in the tree and collapses when it has
   nothing to say. */
.notice:empty { display: none; }

/* Announced, not drawn. The step count and step name are already on screen
   in the progress label. */
.notice--sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

.notice--error {
  border-color: var(--danger);
  border-left-color: var(--danger);
  color: var(--danger);
  font-weight: var(--weight-semibold);
}

/* ---- steps ----------------------------------------------------------- */

#quoteForm.is-sizing {
  overflow: hidden;
  transition: height var(--dur-base) var(--ease-out);
}

.step__h,
.panel__h {
  font-size: var(--text-xl);
  font-weight: var(--weight-semibold);
  line-height: var(--leading-snug);
  margin-bottom: var(--space-2);
}

.step > .help,
.panel__sub { margin-bottom: var(--space-5); }

.step { animation: stepIn var(--dur-base) var(--ease-out); }

@keyframes stepIn {
  from { opacity: 0; transform: translateY(6px); }
}

/* ---- option cards ---------------------------------------------------- */

.opts {
  display: grid;
  grid-template-columns: 1fr;
  gap: var(--space-3);
}

@media (min-width: 34rem) {
  .opts { grid-template-columns: 1fr 1fr; }
}

.opt {
  position: relative;
  display: block;
  width: 100%;
  min-height: var(--tap-min);
  padding: var(--space-4) var(--space-10) var(--space-4) var(--space-4);
  text-align: left;
  background: var(--surface);
  color: var(--text);
  border: 2px solid var(--border-strong);
  border-radius: var(--radius-md);
  cursor: pointer;
  font-family: var(--font-body);
  transition: border-color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}

.opt:hover { border-color: var(--brand-deep); background: var(--bg-subtle); }

.opt__t {
  display: block;
  font: 600 var(--text-base)/1.3 var(--font-heading);
  color: var(--text-heading);
}

.opt__d {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--text-muted);
  line-height: var(--leading-normal);
}

/* Selected state carries a border weight, a fill AND a tick, so colour is
   never the only signal. The tick is drawn from two borders rather than a
   glyph, so no screen reader reads a stray character. */
.opt[aria-checked="true"] {
  border-color: var(--action);
  background: var(--bg-subtle);
}

.opt[aria-checked="true"]::after {
  content: "";
  position: absolute;
  right: var(--space-5);
  top: 50%;
  width: 7px;
  height: 13px;
  margin-top: -9px;
  border-right: 3px solid var(--action);
  border-bottom: 3px solid var(--action);
  transform: rotate(45deg);
}

.opts[aria-invalid="true"] .opt { border-color: var(--danger); }

/* ---- fields (same recipe as site/styles.css) ------------------------- */

.field { margin-bottom: var(--field-gap); }
.fieldset { margin-bottom: var(--field-gap); }

.field > label,
.label {
  display: block;
  font: 600 var(--text-sm)/1.4 var(--font-heading);
  color: var(--text);
  margin-bottom: var(--label-gap);
}

.req,
.opt-tag {
  font: 700 var(--text-xs)/1 var(--font-heading);
  text-transform: uppercase;
  letter-spacing: var(--tracking-wide);
  color: var(--text-muted);
  margin-left: var(--space-2);
}

.field input,
.field textarea {
  width: 100%;
  min-height: var(--control-h);
  background: var(--field-bg);
  color: var(--field-text);
  border: var(--border-width) solid var(--field-border);
  border-radius: var(--field-radius);
  padding: 0 var(--control-px);
  /* 16px literal, not --text-base: iOS zooms the viewport below 16px. */
  font: 400 16px/1.4 var(--font-body);
  transition: border-color var(--dur-fast) var(--ease-out),
              box-shadow var(--dur-fast) var(--ease-out);
}

.field textarea {
  min-height: 128px;
  padding: var(--space-3) var(--control-px);
  resize: vertical;
}

.field input:focus-visible,
.field textarea:focus-visible { border-color: var(--brand-deep); }

.field ::placeholder { color: var(--text-muted); opacity: 1; }

.field--short input { max-width: 9rem; }

.help {
  font-size: var(--text-sm);
  color: var(--text-muted);
  margin-top: 6px;
}

.err {
  font: 600 var(--text-sm)/1.4 var(--font-body);
  color: var(--danger);
  margin-top: 6px;
  display: flex;
  gap: 6px;
  align-items: flex-start;
}

.err[hidden] { display: none !important; }
.err svg { flex: none; margin-top: 3px; }

.field.invalid input,
.field.invalid textarea {
  border-color: var(--danger);
  box-shadow: 0 0 0 1px var(--danger);
}

/* ---- service area messages ------------------------------------------- */

.area__ok,
.area__warn {
  margin-top: 6px;
  display: flex;
  gap: 6px;
  align-items: flex-start;
  font-size: var(--text-sm);
  line-height: var(--leading-normal);
  max-width: var(--measure);
}

.area__ok { color: var(--success); font-weight: var(--weight-semibold); }
.area__warn { color: var(--text); }

.area__ok svg,
.area__warn svg { flex: none; margin-top: 4px; }
.area__warn svg { color: var(--danger); }

/* ---- capture zone (same recipe as site/styles.css) ------------------- */

.capture { margin-bottom: var(--space-4); }

.capture input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  overflow: hidden;
}

.capture__zone {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--space-1);
  min-height: 12.5rem;
  padding: var(--space-6);
  background: var(--surface-subtle);
  border: 2px dashed var(--border-strong);
  border-radius: var(--radius-md);
  text-align: center;
  cursor: pointer;
  color: var(--text);
  transition: border-color var(--dur-fast) var(--ease-out),
              background var(--dur-fast) var(--ease-out);
}

.capture__zone:hover,
.capture__zone.is-over {
  border-style: solid;
  border-color: var(--brand-deep);
  background: var(--bg-subtle);
}

.capture input:focus-visible + .capture__zone {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

.capture__icon {
  width: 3rem;
  color: var(--brand-deep);
  margin-bottom: var(--space-1);
}

.capture__title {
  font: 600 var(--text-xl)/1.3 var(--font-heading);
  color: var(--text-heading);
}
.capture__hint { color: var(--text-muted); font-size: var(--text-sm); }

/* ---- thumbnails (same recipe as site/styles.css) -------------------- */

.shots {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(5rem, 1fr));
  gap: var(--space-2);
  margin: 0 0 var(--space-4);
}

.shots:empty { margin-bottom: 0; }

.shot {
  position: relative;
  aspect-ratio: 1;
  border-radius: var(--radius-md);
  overflow: hidden;
  background: var(--surface-subtle);
  border: var(--border-width) solid var(--border);
  animation: pop var(--dur-base) var(--ease-out);
}

.shot img { width: 100%; height: 100%; object-fit: cover; }

/* 44px tap target on a 28px visual button, per --tap-min. */
.shot__drop {
  position: absolute;
  top: 0;
  right: 0;
  width: var(--tap-min);
  height: var(--tap-min);
  display: grid;
  place-items: center;
  border: 0;
  background: transparent;
  color: var(--text-invert);
  cursor: pointer;
  padding: 0;
}

.shot__drop::before {
  content: "";
  position: absolute;
  width: 1.75rem;
  height: 1.75rem;
  border-radius: var(--radius-pill);
  background: var(--action);
}

.shot__drop svg { position: relative; }

@keyframes pop { from { transform: scale(0.88); opacity: 0; } }

/* ---- photo hints and skip -------------------------------------------- */

.hints {
  margin-bottom: var(--space-5);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.hints li {
  display: flex;
  gap: var(--space-2);
  align-items: baseline;
  line-height: var(--leading-relaxed);
}

.hints li::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--brand);
}

.btn-skip { width: 100%; }

/* ---- terminal panels -------------------------------------------------- */

.panel {
  border: var(--border-width) solid var(--border);
  border-left: 4px solid var(--border-strong);
  border-radius: var(--radius-md);
  background: var(--surface-subtle);
  padding: var(--space-6) var(--space-5);
}

.panel--done { border-color: var(--success); border-left-color: var(--success); }
.panel--done .panel__h { color: var(--success); }

.panel--fail { border-color: var(--danger); border-left-color: var(--danger); }
.panel--fail .panel__h { color: var(--danger); }

.next {
  display: grid;
  gap: var(--space-2);
  font-size: var(--text-sm);
  color: var(--text);
}

.next li {
  display: flex;
  gap: var(--space-2);
  align-items: baseline;
  line-height: var(--leading-relaxed);
}

.next li::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--brand);
}

.ref {
  margin-top: var(--space-5);
  padding-top: var(--space-4);
  border-top: var(--border-width) solid var(--border);
  font: 600 var(--text-sm)/1.4 var(--font-heading);
  color: var(--text-muted);
}

.fail__body {
  margin: var(--space-5) 0;
  font-size: var(--text-sm);
  color: var(--text-muted);
}

.fail__body dl {
  margin: var(--space-2) 0 0;
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-1) var(--space-3);
}

.fail__body dt { font-weight: var(--weight-semibold); color: var(--text); }
.fail__body dd { margin: 0; overflow-wrap: anywhere; }

.fail__acts {
  display: grid;
  gap: var(--space-3);
}

@media (min-width: 34rem) {
  .fail__acts { grid-auto-flow: column; grid-auto-columns: 1fr; }
}

/* ---- nav -------------------------------------------------------------- */

.nav {
  display: flex;
  gap: var(--space-3);
  margin-top: var(--space-6);
}

.nav .btn { flex: 1 1 auto; min-height: var(--control-h-lg); }
#btnBack { flex: 0 1 8rem; }

.fineprint {
  margin-top: var(--space-4);
  font-size: var(--text-sm);
  color: var(--text-muted);
  text-align: center;
}

/* ---- stats ------------------------------------------------------------ */

.stats {
  max-width: var(--measure-container);
  margin: var(--space-12) auto 0;
  padding: 0 var(--gutter);
}

.stats__list {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--space-5);
  text-align: center;
}

@media (min-width: 40rem) {
  .stats__list { grid-template-columns: repeat(4, 1fr); }
}

.stats__n {
  display: block;
  font: 700 var(--text-2xl)/1.1 var(--font-heading);
  color: var(--brand-deep);
}

.stats__l {
  display: block;
  margin-top: var(--space-1);
  font-size: var(--text-sm);
  color: var(--text-muted);
}

/* ---- footer ----------------------------------------------------------- */

.footer {
  margin-top: var(--space-12);
  padding: var(--space-8) var(--gutter);
  background: var(--bg-invert);
  color: var(--text-on-invert-muted);
  text-align: center;
  font-size: var(--text-sm);
}

/* ---- motion ------------------------------------------------------------
 * The height animation on the form, the step entrance and the progress
 * fill are the only movement on the page. All three come off for anyone
 * who has asked their system for less. */

@media (prefers-reduced-motion: reduce) {
  #quoteForm.is-sizing { transition: none; }
  .step { animation: none; }
  .shot { animation: none; }
  .progress__fill { transition: none; }
  .skip-link { transition: none; }
}
