/* ==========================================================================
   CDT Consulting — shared mechanics
   Layout primitives and interactive behaviour common to all three designs.
   Everything visual (colour, type, borders) comes from the per-option theme
   file via custom properties, so this file never needs editing to reskin.
   ========================================================================== */

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

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

body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  /* info@cdt-consulting.co.uk is a 25-character token with nowhere to break.
     At a large default font size on a small phone it is wider than the screen
     and forces the page to scroll sideways. This only ever breaks a word that
     could not otherwise fit, so ordinary prose is untouched. */
  overflow-wrap: break-word;
}

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

h1, h2, h3 { margin: 0; font-family: var(--font-display); text-wrap: balance; }
p { text-wrap: pretty; }

a { color: inherit; }

/* Visible focus for keyboard users on every interactive element. The designs
   were drawn without focus states; without these the checker and accordion
   are unusable without a mouse. */
:focus-visible {
  outline: 2px solid var(--focus);
  outline-offset: 3px;
}

.skip {
  position: absolute;
  left: -9999px;
  top: 0;
  z-index: 100;
  padding: 12px 20px;
  background: var(--ink);
  color: var(--bg);
  font-weight: 700;
  text-decoration: none;
}
.skip:focus { left: 0; }

/* --------------------------------------------------------------------------
   Content width

   The source designs were 1240px artboards. Sections stay full-bleed so their
   backgrounds reach the screen edge, but the content inside them is capped and
   centred — otherwise everything stretches on a large monitor.

   --pad-x    for a section that supplies its own horizontal padding.
   --center-x for a full-bleed grid whose children already pad themselves;
              no gutter minimum, or the two would stack and double up at 1240.
   -------------------------------------------------------------------------- */
:root {
  --pad-x: max(var(--gutter), (100% - var(--max)) / 2);
  --center-x: max(0px, (100% - var(--max)) / 2);
}

.wrap { max-width: var(--max, 1240px); margin: 0 auto; }
.pad { padding-inline: var(--pad-x); }

/* --------------------------------------------------------------------------
   Notifiability checker
   Each case is a real <button> carrying its verdict in the DOM. Without JS
   every verdict is visible (progressive enhancement); with JS they collapse
   into one panel revealed on selection.
   -------------------------------------------------------------------------- */

.checker-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--tile-gap, 14px);
}

.tile {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: var(--tile-pad, 20px);
  text-align: left;
  font: inherit;
  color: inherit;
  background: var(--tile-bg);
  border: 1px solid var(--tile-border);
  border-radius: var(--tile-radius, 0);
  box-shadow: var(--tile-shadow, none);
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}

.tile:hover { border-color: var(--tile-border-hover); }

.tile[aria-pressed="true"] {
  background: var(--tile-bg-on);
  color: var(--tile-ink-on);
  border-color: var(--tile-border-on);
  box-shadow: none;
}

.tile-n {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  border: 1px solid currentColor;
  border-radius: var(--tile-n-radius, 0);
  font-family: var(--font-tile-n, var(--font-display));
  font-size: 0.8125rem;
  font-weight: var(--tile-n-weight, 400);
  flex: none;
}

.tile-label { font-size: 0.9688rem; font-weight: 600; font-family: var(--font-tile-label, inherit); }
.tile-hint { font-size: 0.8125rem; line-height: 1.5; opacity: .66; }

.verdict {
  margin-top: var(--verdict-gap, 26px);
  padding: var(--verdict-pad, 28px 34px);
  display: flex;
  gap: 26px;
  align-items: flex-start;
  background: var(--verdict-bg);
  border: 1px solid var(--verdict-border);
  border-left: var(--verdict-rule, 1px solid var(--verdict-border));
  border-radius: var(--verdict-radius, 0);
}

.verdict-tag {
  flex: none;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: .12em;
  padding: 7px 12px;
  text-transform: uppercase;
  border-radius: var(--tag-radius, 0);
}
.verdict-tag[data-notifiable="yes"] { background: var(--tag-yes-bg); color: var(--tag-yes-ink); border: var(--tag-yes-border, none); }
.verdict-tag[data-notifiable="no"]  { background: var(--tag-no-bg, transparent); color: var(--tag-no-ink); border: 1px solid var(--tag-no-ink); }

/* Spans, not <p>/<div> — the verdict lives inside a <button>, where flow
   content would be invalid. Blocked out explicitly here. */
.verdict-v { display: block; font-family: var(--font-display); font-size: 1.3125rem; font-weight: var(--verdict-v-weight, 500); }
.verdict-body { display: block; font-size: 0.9062rem; line-height: 1.65; color: var(--muted); margin: 8px 0 0; max-width: 72ch; }
.tile .verdict { white-space: normal; }

/* JS on: verdicts live in one panel, individual ones stay hidden. */
.js .tile .verdict { display: none; }
.js .verdict-live[hidden] { display: none; }
/* JS off: the panel is inert and each verdict shows under its tile. */
html:not(.js) .verdict-live { display: none; }
html:not(.js) .tile { cursor: default; }
html:not(.js) .tile .verdict { margin-top: 14px; }

/* --------------------------------------------------------------------------
   FAQ accordion — native <details>, styled per theme
   -------------------------------------------------------------------------- */

.faq { border-top: 1px solid var(--rule); padding: 18px 0; }
.faq > summary {
  list-style: none;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 20px;
}
.faq > summary::-webkit-details-marker { display: none; }
.faq-q { font-size: 0.9688rem; font-weight: 600; font-family: var(--font-faq-q, inherit); }
.faq-x {
  font-size: 1.25rem;
  color: var(--accent);
  transition: transform .2s;
  flex: none;
}
.faq[open] .faq-x { transform: rotate(45deg); }
.faq-a { font-size: 0.9062rem; line-height: 1.7; color: var(--muted); margin: 12px 0 0; max-width: 72ch; }

@media (prefers-reduced-motion: reduce) {
  * { transition-duration: .01ms !important; animation-duration: .01ms !important; }
}

/* --------------------------------------------------------------------------
   Enquiry form
   No backend: submitting composes a pre-filled mailto. See site.js.
   -------------------------------------------------------------------------- */

.field {
  width: 100%;
  padding: 13px 15px;
  font: inherit;
  font-size: 0.875rem;
  color: var(--field-ink, inherit);
  background: var(--field-bg);
  border: var(--field-border, none);
  border-radius: var(--field-radius, 0);
}
.field::placeholder { color: var(--field-placeholder, inherit); opacity: .75; }
textarea.field { resize: vertical; min-height: 96px; }

.btn {
  display: inline-block;
  padding: 14px 30px;
  font: inherit;
  font-size: 0.875rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-align: center;
  text-decoration: none;
  border: none;
  border-radius: var(--btn-radius, 0);
  cursor: pointer;
}

.form-note { font-size: 0.7812rem; line-height: 1.6; margin: 10px 0 0; opacity: .8; }

/* The answer from the Worker, rendered in place. role="status" on the element
   means a screen reader hears it without focus moving. */
.form-status { margin: 14px 0 0; font-size: 0.875rem; line-height: 1.6; }

.btn:disabled { cursor: default; opacity: .65; }

/* Honeypot. Positioned off-screen rather than display:none, which the better
   bots check for; tabindex="-1" and aria-hidden keep it away from anyone real. */
.hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* --------------------------------------------------------------------------
   Floating WhatsApp button

   A wide text pill parks itself on top of whatever is at the bottom-right of
   the viewport — a hero CTA, a heading, fee-card small print. Below 600px it
   collapses to an icon-only circle so it covers as little as possible, and
   each theme's footer gains clearance so the last line is never sat on.
   -------------------------------------------------------------------------- */
.wa svg { width: 20px; height: 20px; fill: currentColor; flex: none; }

@media (max-width: 600px) {
  .wa { padding: 14px; border-radius: 50%; gap: 0; }
  .wa .wa-label { display: none; }
}

/* --------------------------------------------------------------------------
   Running head

   The page is one document 7,800px tall on a phone, so the masthead — and
   with it every route to Chris — is gone after the first screen. Once it
   scrolls away this takes over, doing the job a formal report's continuation
   header does: name the practice, say which part you are reading, and keep
   the one action reachable.

   Phones only, and only with JS: initRunningHead in site.js drives it, so
   without JS it never appears and the page behaves exactly as it did.
   -------------------------------------------------------------------------- */

.runhead { display: none; }

@media (max-width: 700px) {
  html.js .runhead {
    position: fixed;
    inset: 0 0 auto;
    z-index: 60;
    display: flex;
    align-items: center;
    gap: 12px;
    padding: 8px var(--gutter);
    transform: translateY(-100%);
    visibility: hidden;
    transition: transform .18s ease-out, visibility .18s;
  }
  /* visibility, not opacity: the bar leaves the accessibility tree while it
     is parked, so the practice name is not announced twice at the top. */
  html.js .runhead.is-on { transform: none; visibility: visible; }

  /* The mark and the action never shrink; a long section label truncates
     instead, so the bar cannot fall onto a second line. */
  .runhead-mark {
    flex: none;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
  }
  /* The rooflines only. The full logo stacks mark over CDT over CONSULTING,
     and at the height of a bar that bottom line renders about 3px tall. */
  .runhead-mark img { width: 64px; height: auto; }
  .runhead-sec {
    flex: 0 1 auto;
    min-width: 0;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
  }
  .runhead-call {
    flex: none;
    margin-left: auto;
    display: inline-flex;
    align-items: center;
    min-height: 44px;
    padding: 0 18px;
  }

  /* Anchor targets clear the bar instead of landing underneath it. */
  main [id] { scroll-margin-top: 68px; }
}

/* A phone held sideways has ~375px of height to give; 61px of it is too
   much to spend on a running head. */
@media (max-width: 700px) and (max-height: 430px) {
  html.js .runhead { display: none; }
  main [id] { scroll-margin-top: 0; }
}

/* --------------------------------------------------------------------------
   Day / night / auto

   Three radios in a fieldset. Radios because the three options are mutually
   exclusive, which is exactly what a radio group means to a screen reader, and
   because arrow-key navigation then comes for free rather than being written.

   The whole control is hidden without JS: nothing it offers can work without
   somewhere to store the choice.
   -------------------------------------------------------------------------- */

.theme-switch { display: none; }

html.js .theme-switch {
  display: inline-flex;
  align-items: center;
  /* A fieldset brings a border, padding and a min-inline-size that will not
     shrink below its content. All three have to go. */
  min-inline-size: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

/* The input stays in the accessibility tree and keeps its keyboard behaviour;
   only its rendering is handed to the label. Not display:none, which would
   take it out of the tab order and out of the radio group. */
.theme-switch input {
  position: absolute;
  width: 1px;
  height: 1px;
  opacity: 0;
  pointer-events: none;
}

.theme-switch label {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 40px;
  min-height: 44px;
  cursor: pointer;
}

.theme-switch svg { width: 16px; height: 16px; }
.theme-switch svg circle,
.theme-switch svg path {
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
}
.theme-switch svg .fill { fill: currentColor; stroke: none; }

/* The focus ring has to follow the hidden input out to the label it controls,
   or keyboard users get no ring at all. */
.theme-switch input:focus-visible + label {
  outline: 2px solid var(--focus);
  outline-offset: -3px;
}

/* Collapsed to the option in force; the other two appear on hover or focus.
   The bar carries one icon instead of three, which also keeps it on one line
   at widths where three plus the email address did not fit.

   Two guards make that safe. It only applies where hovering is possible, so a
   touch device — which can never hover — keeps all three visible and reachable.
   And :focus-within expands it for the keyboard, so tabbing into the group
   never lands on a control that cannot be seen. */
@media (hover: hover) {
  html.js .theme-switch input:not(:checked) + label {
    min-width: 0;
    max-width: 0;
    overflow: hidden;
    opacity: 0;
    transition: max-width .18s ease, opacity .14s ease;
  }
  html.js .theme-switch:hover input:not(:checked) + label,
  html.js .theme-switch:focus-within input:not(:checked) + label {
    min-width: 40px;
    max-width: 40px;
    opacity: 1;
  }
}

/* Above phone widths the utility bar has its own padding for the 44px targets
   to overhang into, so the control does not make the bar taller. */
@media (min-width: 701px) {
  html.js .theme-switch { margin-block: -12px; }
}

/* --------------------------------------------------------------------------
   External links

   A link that leaves the site says so twice: with a mark for people who can
   see it, and with text for people who cannot. The mark is a mask rather than
   an image, so it takes currentColor and needs no second rule for night.

   Driven off target="_blank" rather than a class, so any future external link
   is marked without anyone remembering to do it. The floating WhatsApp button
   is the one exclusion — it already carries its own glyph and its own label.
   -------------------------------------------------------------------------- */

a[target="_blank"]:not(.wa)::after {
  content: "";
  display: inline-block;
  width: .68em;
  height: .68em;
  margin-left: .3em;
  vertical-align: -.02em;
  background-color: currentColor;
  -webkit-mask: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='M8 16 16 8'/><path d='M9.5 8H16v6.5'/></svg>") no-repeat center / contain;
  mask: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23000' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='M8 16 16 8'/><path d='M9.5 8H16v6.5'/></svg>") no-repeat center / contain;
}

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

/* --------------------------------------------------------------------------
   Notice deadline calculator

   Every statutory period lives in assets/js/deadlines.js, never here. The
   controls are revealed only once that script has bound (.calc.is-ready), so
   a reader with JavaScript off — or with a failed asset — gets the fallback
   line and the reference table rather than inputs that do nothing.
   -------------------------------------------------------------------------- */

.calc-form { display: none; }
.calc.is-ready .calc-form { display: block; }
.calc.is-ready .calc-fallback { display: none; }
.calc-fallback { margin: 0; }

.calc-mode {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  border: 0;
  margin: 0 0 22px;
  padding: 0;
}

/* The input covers the pill rather than being hidden, so the whole pill is
   the hit area and the native radio keeps its keyboard behaviour. */
.calc-pill { position: relative; }
.calc-pill input {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}
.calc-pill span {
  display: block;
  padding: 11px 18px;
  font-size: 0.875rem;
  font-weight: 600;
  border: 1px solid var(--tile-border);
  border-radius: var(--tile-radius, 0);
  transition: background .15s, color .15s, border-color .15s;
}
.calc-pill input:checked + span {
  background: var(--tile-bg-on);
  color: var(--tile-ink-on);
  border-color: var(--tile-border-on);
}
.calc-pill input:focus-visible + span {
  outline: 2px solid var(--focus);
  outline-offset: 2px;
}

.calc-fields {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 18px;
  align-items: end;
}
.calc-field { margin: 0; }
.calc-label { display: block; font-size: 0.8125rem; font-weight: 600; margin: 0 0 7px; }

.calc-hint { display: block; font-size: 0.8125rem; line-height: 1.5; color: var(--muted); margin-top: 7px; }
.calc-hint[hidden] { display: none; }

.calc-out { min-width: 0; }
.calc-rows { margin: 16px 0 0; }
.calc-row { padding: 12px 0; border-top: 1px solid var(--rule); }
.calc-row dt { font-size: 0.8125rem; font-weight: 600; opacity: .75; }
.calc-row dd { margin: 4px 0 0; }
.calc-date-out { display: block; font-family: var(--font-display); font-size: 1.0625rem; }

/* The section reference is the point of the tool, not a footnote, so it sits
   under every date rather than at the end of the panel. */
.calc-cite { display: block; font-size: 0.8125rem; line-height: 1.6; color: var(--muted); margin-top: 5px; max-width: 72ch; }
.verdict-v + .calc-cite { margin-top: 9px; }

.calc-note { font-size: 0.8438rem; line-height: 1.65; color: var(--muted); margin: 12px 0 0; max-width: 72ch; }
.calc-error { margin: 0; font-size: 0.9062rem; }

.calc-ref { margin-top: 26px; border-top: 1px solid var(--rule); }
.calc-ref > summary { cursor: pointer; padding: 15px 0; font-size: 0.875rem; font-weight: 600; }
.calc-ref > summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* The table is allowed to be wider than the column; the page is not. Focusable
   so a keyboard can reach the scroll, which is why it carries a role and a
   label as well. */
.calc-table-scroll { overflow-x: auto; }
.calc-table { width: 100%; border-collapse: collapse; font-size: 0.8438rem; }
.calc-table th,
.calc-table td {
  text-align: left;
  vertical-align: top;
  padding: 11px 18px 11px 0;
  border-top: 1px solid var(--rule);
  line-height: 1.55;
}
.calc-table thead th {
  border-top: 0;
  font-size: 0.6875rem;
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
}
.calc-table tbody th { font-weight: 600; padding-right: 26px; }
.calc-table td:last-child { white-space: nowrap; font-variant-numeric: tabular-nums; }
.calc-ref-note { font-size: 0.8438rem; line-height: 1.7; color: var(--muted); margin: 18px 0 0; max-width: 72ch; }

/* Two audiences, two fills. Months are the building owner's question and take
   the brand; days are the adjoining owner's and take gold — which is a light
   fill, so it carries dark ink, never white. */
.verdict-tag[data-period="months"] { background: var(--tag-yes-bg); color: var(--tag-yes-ink); }
.verdict-tag[data-period="days"] { background: var(--gold); color: var(--on-gold); }

/* --------------------------------------------------------------------------
   3 metre / 6 metre excavation check

   Same contract as the calculator: controls appear only once the script has
   bound, and the static paragraph carries the substance until then.
   -------------------------------------------------------------------------- */

.exc-form { display: none; }
.exc.is-ready .exc-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 18px; }
.exc.is-ready .exc-fallback { display: none; }
.exc-fallback { margin: 0; max-width: 72ch; font-size: 0.9062rem; line-height: 1.65; color: var(--muted); }
.exc-hint { grid-column: 1 / -1; margin-top: 0; }

/* The unit sits inside the field rather than in the label, so the number and
   its unit cannot be separated by a line break. */
.exc-input { position: relative; display: block; }
.exc-input .field { padding-right: 34px; }
.exc-unit {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  font-size: 0.8125rem;
  color: var(--muted);
  pointer-events: none;
}

.exc-units { grid-column: 1 / -1; margin-bottom: 0; }
.exc-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.exc-pair[hidden], .exc-input[hidden] { display: none; }

/* The trap sits outside the interactive block on purpose: readable without
   JavaScript, and indexable. */
.exc-trap {
  margin: 22px 0 0;
  padding: 16px 18px;
  max-width: 72ch;
  font-size: 0.8438rem;
  line-height: 1.7;
  color: var(--muted);
  background: var(--paper-3);
  border-left: 2px solid var(--gold);
}
.exc-trap b { color: var(--ink); }

.exc-answer[hidden] { display: none; }

/* The tag carries a section number here, not a word. .verdict-tag uppercases
   its text, which turns s.6(1) into S.6(1) — the Act's sections are lowercase
   throughout this site and in the Act itself. */
.exc-verdict .verdict-tag[data-period] { text-transform: none; letter-spacing: .04em; font-size: 0.75rem; }
.exc-unknown { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--rule); }
.exc-unknown-h { font-family: var(--font-display); font-size: 1.0625rem; font-weight: 500; margin: 0; }
.calc-note-lead { font-weight: 600; color: inherit; }
.exc-list { margin: 8px 0 0; padding-left: 20px; max-width: 72ch; }
.exc-list li { font-size: 0.8438rem; line-height: 1.65; color: var(--muted); margin-top: 7px; }

/* The diagram.
   Horizontal and vertical scales are forced equal in the script — a plane
   drawn at anything other than 45 degrees on screen would misrepresent the
   provision it illustrates. Nothing here may introduce a non-uniform scale. */
.exc-svg {
  display: block;
  width: 100%;
  height: auto;
  max-width: 640px;
  margin: 20px 0 4px;
  /* Hard stop. The drawing window is bounded in the script, but nothing here
     may let a stray coordinate paint outside the panel. */
  overflow: hidden;
}
.exc-ground { stroke: var(--ink); stroke-width: 1.25; }
.exc-wall { fill: var(--paper-2); stroke: var(--ink); stroke-width: 1.25; }
.exc-founding { stroke: var(--ink); stroke-width: 1.25; }
.exc-plane { stroke: var(--brand); stroke-width: 1.75; stroke-dasharray: 6 4; }
.exc-marker { stroke: var(--rule-dark); stroke-width: 1; }
.exc-dig { fill: var(--gold); fill-opacity: .32; stroke: var(--gold-ink); stroke-width: 1.25; }
.exc-tear { fill: none; stroke: var(--gold-ink); stroke-width: 1.25; }
.exc-marker-label, .exc-label, .exc-attrib {
  font-family: var(--font-body);
  fill: var(--muted);
}
.exc-marker-label { font-size: 11px; }
.exc-label { font-size: 11.5px; }
.exc-label-unknown { font-style: italic; }
.exc-attrib { font-size: 9.5px; opacity: .6; }

/* --------------------------------------------------------------------------
   Responsive — the canvas designs are fixed 1240px; these are the rules that
   make them work on a phone, which is where most enquiries will come from.
   -------------------------------------------------------------------------- */

@media (max-width: 1000px) {
  .checker-grid { grid-template-columns: repeat(2, 1fr); }
  .split-2 { grid-template-columns: 1fr !important; }
  .split-side { grid-template-columns: 1fr !important; }
  .aside-grid { grid-template-columns: minmax(0, 1fr) !important; gap: 32px !important; }
}

@media (max-width: 700px) {
  .checker-grid { grid-template-columns: 1fr; }
  .verdict { flex-direction: column; gap: 14px; }
  .calc-fields { grid-template-columns: 1fr; }
  .exc.is-ready .exc-form { grid-template-columns: 1fr; }
  /* A radio pill per row beats two cramped ones: the labels are sentences. */
  .calc-mode { display: grid; grid-template-columns: 1fr; gap: 8px; }

  /* A three-column table of prose does not shrink to 335px, it just gets
     narrower and taller until a row header is one word per line. Give it a
     floor and let the wrapper scroll — that is what the wrapper is for. */
  .calc-table { min-width: 34rem; }
  .calc-table th,
  .calc-table td { padding-right: 14px; }
  .stat-strip { grid-template-columns: repeat(2, 1fr) !important; }
  .process-6 { grid-template-columns: 1fr !important; }
  .fees-4 { grid-template-columns: 1fr !important; }
  .quotes-3 { grid-template-columns: 1fr !important; }
  .faq-cols { columns: 1 !important; }
  .footer-3 { grid-template-columns: 1fr !important; gap: 28px !important; }
  .form-2 { grid-template-columns: 1fr !important; }

  /* Padding drawn for a 1240px artboard costs a fifth of the width at 375px:
     the verdict panel's 34px sides left 267px for the text inside them. */
  .tile { padding: 16px; }
  .verdict { padding: 20px; }

  /* iOS Safari zooms the whole page in when a focused field's text is under
     16px, and never zooms back out. Desktop keeps the 14px field; the phone
     gets the size that stops the zoom. */
  .field { font-size: 1rem; }

  /* A 32px summary is below the 44px touch minimum. Moving the padding off
     .faq and onto the row keeps the closed row exactly as tall as before —
     18+32+18 becomes 12+44+12 — but now all of it is tappable. */
  .faq { padding: 12px 0; }
  .faq > summary { min-height: 44px; }
}

@media (max-width: 600px) {
  /* Thumb width, not label width. */
  .btn { display: block; width: 100%; }
}
