/* =============================================================================
   Mold Free USA — the shared assessment form + the funnel page furniture.
   Loaded AFTER style.css on /is-it-mold/, /free-assessment/ and /thanks/.

   ONE implementation, two hosts. The markup block is byte-identical on the
   lander and on the form page; only the reveal wrapper around it differs, so
   every rule below has to hold on the cream band of the lander's closing
   section AND on the cream .page band of the form page. It does: the panel
   carries its own off-white ground.

   Palette: style.css tokens only, plus exactly one new colour (validation
   rust) and one hairline tint. Nothing here is a second design language.
   ========================================================================== */

:root {
  /* Amber-family rust: the same warm hue rotated to red, 6.45:1 on the
     off-white panel. Used ONLY for validation failure — never decoratively —
     and never as the only channel (aria-invalid + a written message carry it
     for anyone who cannot see the colour). */
  --c-err:  #a33a10;
  /* Control boundary. The first pass used #cfc7bb, which is 1.67:1 on white —
     fine as a decorative hairline, not enough for the thing that IS the
     affordance (the dashed photo zone has no other boundary). This warm tan
     measures 3.13:1 on white, clearing WCAG 1.4.11, and stays in the cream
     family rather than dropping a neutral grey into a warm palette. */
  --c-line: #a08f7a;
}

/* =============================================================================
   THE PANEL
   ========================================================================== */
.mf {
  max-width: 760px;
  margin: 0 auto;
  padding: 30px 32px 32px;
  border: 3px solid #1c1c1c;
  border-radius: 2px;
  background: var(--c-off);
  text-align: left;                  /* the lander's closing band is centred */
}

/* The numbered-pentagon progress rail (.mf__prog / .mf__pent / .mf__prog-n /
   .mf__prog-t) lived here. Deleted with the markup, not left behind: naming a
   "Photos" step before the first tap hands the visitor "I have no photos" as
   an objection, and dead styles are an invitation to put the rail back.
   Progress is announced to assistive tech by the live region and each step's
   aria-label instead. */

/* ---------- step ---------- */
.mf__step { display: block; }
.mf__step[hidden] { display: none; }

.mf__h {
  margin: 0;
  font: 700 26px/30px var(--ff-display);
  letter-spacing: .01em;
  text-transform: uppercase;
  color: #000;
}
.mf__h:focus { outline: none; }         /* focus moves here on step change; */
.mf__h:focus-visible {                  /* only keyboard users get the ring  */
  outline: 3px solid #1c1c1c;
  outline-offset: 4px;
}
.mf__h2 {
  margin: 26px 0 0;
  font: 700 20px/24px var(--ff-display);
  letter-spacing: .02em;
  text-transform: uppercase;
  color: #000;
}
/* The "optional" pill on the Photos step lived here. Deleted with the markup:
   the convention is to mark what is REQUIRED, and a badge that shouts OPTIONAL
   over a step's own heading is an instruction nobody asked for. */
.mf__note {
  margin: 10px 0 0;
  font: 400 15px/22px var(--ff-body);
  color: var(--c-body);
}
.mf__note b { font-weight: 600; color: #1c1c1c; }

/* ---------- tap-select chips ----------
   A real radio behind every chip: native arrow-key navigation inside the
   group, native checked semantics, native required-ness. The input is clipped
   rather than display:none so it stays focusable — and clip-path also clips
   the global focus ring's box-shadow, which would otherwise paint an amber
   blob at a 1px box. */
/* 180px floor rather than 158: inside the 690px panel that resolves to three
   columns, so six options land as 3+3 and five as 3+2. At four columns the
   rows ended 2 and 3 chips short and read as a broken grid. */
.mf__opts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px;
  margin: 14px 0 0;
  padding: 0;
  border: 0;
}
.mf__opt { display: block; margin: 0; }
.mf__opt input {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  clip-path: inset(50%);
}
.mf__opt span {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 54px;
  height: 100%;
  padding: 10px 14px;
  border: 2px solid var(--c-line);
  border-radius: 2px;
  background: #fff;
  color: #222;
  font: 600 17px/20px var(--ff-display);
  letter-spacing: .03em;
  text-transform: uppercase;
  text-align: center;
  cursor: pointer;
  transition: background-color .18s var(--ease), border-color .18s var(--ease),
              color .18s var(--ease), transform .18s var(--ease);
}
.mf__opt:hover span { border-color: #1c1c1c; }
.mf__opt:active span { transform: translateY(1px); }
.mf__opt input:checked + span {
  border-color: var(--c-amber);
  background: var(--c-amber);
  color: #000;
}
.mf__opt input:focus-visible + span {
  outline: 3px solid #1c1c1c;
  outline-offset: 2px;
  box-shadow: 0 0 0 6px rgba(233, 169, 34, .85),
              0 0 0 8px rgba(255, 255, 255, .9);
}
.mf__opts[aria-invalid="true"] span { border-color: var(--c-err); }

/* ---------- the honeypot ----------
   Off screen but RENDERED. `display:none` and `visibility:hidden` are the two
   things a form-filling bot tests for, so hiding it either of those ways hides
   it from the only visitor it exists to catch. It is LABELLED rather than
   aria-hidden: a screen reader that reaches it in browse mode is told to leave
   it alone, which is true and actionable, where a focusable field inside an
   aria-hidden container is neither. `tabindex="-1"` keeps it out of the tab
   order, so no keyboard visitor ever lands on it by accident.

   Self-contained on purpose — it repeats the .sr-only declarations rather than
   borrowing them, because a form whose spam guard depends on another
   stylesheet having loaded is a form that fails open in exactly the case
   nobody notices. */
.mf__hp {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ---------- photo drop / tap zone ---------- */
.mf__file {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  clip-path: inset(50%);
}
.mf__drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 10px;
  margin-top: 16px;
  padding: 30px 20px;
  border: 2px dashed var(--c-line);
  border-radius: 2px;
  background: #fff;
  text-align: center;
  cursor: pointer;
  transition: border-color .18s var(--ease), background-color .18s var(--ease);
}
.mf__drop:hover { border-color: #1c1c1c; }
.mf__drop[data-drag] { border-color: var(--c-amber); background: #fffaf0; }
.mf__file:focus-visible + .mf__drop {
  outline: 3px solid #1c1c1c;
  outline-offset: 2px;
  box-shadow: 0 0 0 6px rgba(233, 169, 34, .85),
              0 0 0 8px rgba(255, 255, 255, .9);
}
.mf__drop svg {
  width: 56px;
  height: 53px;
  flex-shrink: 0;
  color: var(--c-amber);
  fill: none;
  stroke: currentColor;
  stroke-width: 3;
  stroke-linejoin: miter;
}
.mf__drop b {
  font: 700 19px/23px var(--ff-display);
  letter-spacing: .02em;
  text-transform: uppercase;
  color: #000;
}
.mf__drop i {
  font: 400 15px/21px var(--ff-body);
  font-style: normal;
  color: var(--c-badge);
}
/* What we take. Set in the display face at badge weight so it reads as a
   specification and not as a second instruction competing with the <b>. */
.mf__lim {
  font: 600 13px/18px var(--ff-display);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--c-badge);
}

/* Ten photos are on the list: the zone is no longer an affordance, so it stops
   looking like one. The dashes go solid, the amber drains out of the pictogram
   and the drag hint — an instruction that would now do nothing — is removed. */
.mf__drop[data-full] {
  border-style: solid;
  border-color: #cfc7bb;
  background: #f4f1ec;
  cursor: default;
}
.mf__drop[data-full]:hover { border-color: #cfc7bb; }
.mf__drop[data-full] svg { color: #cfc7bb; }
.mf__drop[data-full] b { color: var(--c-badge); }
.mf__drop[data-full] i { display: none; }

/* =============================================================================
   UPLOAD PROGRESS
   One bar component, two hosts: the per-file row and the aggregate strip. The
   fill is a transform, never a width — width animation is a layout on every
   frame, and this bar moves continuously while ten of them are on screen.
   ========================================================================== */
.mf__bar {
  display: block;
  overflow: hidden;
  height: 12px;
  border: 2px solid #1c1c1c;
  border-radius: 2px;
  background: #fff;
}
.mf__bar i {
  display: block;
  height: 100%;
  background: var(--c-amber);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform .2s linear;
}

/* small hard-framed button — "try again", on a row and on the strip */
.mf__retry {
  justify-self: end;
  flex-shrink: 0;
  padding: 7px 13px;
  border: 2px solid #1c1c1c;
  border-radius: 2px;
  background: #fff;
  color: #1c1c1c;
  font: 700 14px/16px var(--ff-display);
  letter-spacing: .06em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color .18s var(--ease), color .18s var(--ease),
              transform .18s var(--ease);
}
.mf__retry:hover { background: #1c1c1c; color: var(--c-off); }
.mf__retry:active { transform: translateY(1px); }
.mf__retry[hidden] { display: none; }

/* HELD: the server named a wait and the button is counting it down. It stays on
   screen, keeps its frame and its place in the row, and reads as a label rather
   than an invitation — a control that vanished and reappeared would be a layout
   jump on a timer, and one that looked pressable would be a lie with a number
   in it. The hover and press states are cancelled with it; nothing here
   animates, so there is no motion on the tick. */
.mf__retry:disabled {
  border-color: #b7ada0;
  color: #6f675d;
  background: #f6f2ec;
  cursor: default;
  letter-spacing: .04em;
}
.mf__retry:disabled:hover { background: #f6f2ec; color: #6f675d; }
.mf__retry:disabled:active { transform: none; }

/* ---------- the aggregate strip ("8 of 10 uploaded") ----------
   Present on the photo step AND on the details step, so a visitor who walked on
   while the bars were still moving can still see where they got to. */
.mf__up {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 9px 14px;
  margin: 14px 0 0;
  padding: 12px 14px;
  border: 2px solid var(--c-line);
  border-radius: 2px;
  background: #fff;
}
.mf__up[hidden] { display: none; }
.mf__up-t {
  margin: 0;
  font: 600 14px/19px var(--ff-display);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--c-badge);
}
/* Placed, not auto-flowed: left to itself the button lands on a third row under
   the bar and the strip grows a floor nobody asked for. */
.mf__up > .mf__up-t  { grid-column: 1; grid-row: 1; }
.mf__up > .mf__retry { grid-column: 2; grid-row: 1; }
.mf__up > .mf__bar   { grid-column: 1 / -1; grid-row: 2; }
.mf__up[data-tone="done"] { border-color: #1c1c1c; }
.mf__up[data-tone="done"] .mf__up-t { color: #1c1c1c; }
.mf__up[data-tone="bad"] { border-color: var(--c-err); }
.mf__up[data-tone="bad"] .mf__up-t { color: var(--c-err); }
.mf__up[data-tone="bad"] .mf__bar i { background: var(--c-err); }
/* The TRACK too, not just the frame around the strip. Without this the rows
   below carry rust-framed tinted tracks while the strip that summarises them
   keeps a black frame on white — one failure drawn two ways, eight pixels
   apart. */
.mf__up[data-tone="bad"] .mf__bar { border-color: var(--c-err); background: #f7e6de; }
/* on the details step it is a status line the visitor passes, not a control */
.mf__up--3 { margin-top: 18px; }

/* =============================================================================
   THE FILE LIST
   A row, not a tile: a tile has nowhere to put a name, a size, a bar and a
   state, and every one of those is something the visitor needs while the file
   is still on its way.
   ========================================================================== */
.mf__thumbs {
  display: grid;
  gap: 8px;
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
}
.mf__thumbs:empty { display: none; }

.mf__item {
  display: grid;
  grid-template-columns: 62px minmax(0, 1fr) auto;
  grid-template-areas:
    "thumb body acts"
    "thumb bar  acts";
  align-items: center;
  column-gap: 12px;
  row-gap: 7px;
  margin: 0;
  padding: 8px 10px 8px 8px;
  border: 2px solid var(--c-line);
  border-radius: 2px;
  background: #fff;
}
.mf__item > .mf__item-t { grid-area: thumb; }
.mf__item > .mf__item-b { grid-area: body; align-self: end; }
.mf__item > .mf__bar    { grid-area: bar; align-self: start; }
.mf__item > .mf__item-a { grid-area: acts; }
.mf__item[data-state="done"] { border-color: #1c1c1c; }
.mf__item[data-state="failed"] { border-color: var(--c-err); background: #fdf6f3; }

/* The preview port. HEIC and every RAW format are undecodable in a browser —
   precisely the files this form was widened to accept — so the port has to look
   deliberate when there is no picture in it. */
.mf__item-t {
  display: grid;
  place-items: center;
  overflow: hidden;
  width: 62px;
  height: 62px;
  border: 2px solid #1c1c1c;
  border-radius: 2px;
  background: var(--c-cream);
}
.mf__item-t img { display: block; width: 100%; height: 100%; object-fit: cover; }
.mf__item-ext {
  font: 700 13px/16px var(--ff-display);
  letter-spacing: .06em;
  color: var(--c-badge);
}

.mf__item-b { display: block; min-width: 0; }
.mf__item-n {
  display: block;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  font: 600 15px/20px var(--ff-body);
  color: #1c1c1c;
}
.mf__item-m {
  display: block;
  margin: 1px 0 0;
  font: 600 12.5px/16px var(--ff-display);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--c-badge);
}
.mf__item[data-state="done"] .mf__item-m { color: #1c1c1c; }
/* A failure reason is a SENTENCE, not a label — uppercase display type with
   letter-spacing is unreadable at that length, so this one state drops to the
   body face. */
.mf__item[data-state="failed"] .mf__item-m {
  font: 400 13.5px/18px var(--ff-body);
  letter-spacing: 0;
  text-transform: none;
  color: var(--c-err);
}
.mf__item[data-state="queued"] .mf__bar { background: #f1ece4; }
/* Nothing was kept, so the track is empty and framed in the failure colour —
   an empty rust track, never a full one. */
.mf__item[data-state="failed"] .mf__bar {
  border-color: var(--c-err);
  background: #f7e6de;
}
.mf__item .mf__bar { height: 10px; }

.mf__item-a { display: flex; align-items: center; gap: 8px; }
.mf__retry--row { padding: 6px 10px; font-size: 13px; }
.mf__item-x {
  display: grid;
  place-items: center;
  flex-shrink: 0;
  width: 30px;
  height: 30px;
  border: 2px solid #1c1c1c;
  border-radius: 2px;
  background: var(--c-amber);
  color: #000;
  cursor: pointer;
  transition: background-color .18s var(--ease), transform .18s var(--ease);
}
.mf__item-x:hover { background: var(--c-amber-hi); }
.mf__item-x:active { transform: translateY(1px); }
.mf__item-x svg {
  width: 12px;
  height: 12px;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: square;
}

/* ---------- text fields ---------- */
.mf__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 16px;
  margin-top: 18px;
}
.mf__field { display: block; min-width: 0; }
.mf__field--wide { grid-column: 1 / -1; }
.mf__field label {
  display: block;
  margin-bottom: 6px;
  font: 600 14px/18px var(--ff-display);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: #1c1c1c;
}
/* The required marker. Not --c-err: that rust is reserved for validation
   failure, and a field that has not been filled in yet has not failed. The
   `required` attribute carries the meaning to assistive tech, so the asterisk
   is aria-hidden and purely a visual echo of the "* Required" line above. */
.mf__req { color: var(--c-badge); }
.mf__field input {
  width: 100%;
  height: 50px;
  padding: 0 14px;
  border: 2px solid var(--c-line);
  border-radius: 2px;
  background: #fff;
  color: #222;
  font: 400 17px/50px var(--ff-body);
  transition: border-color .18s var(--ease);
}
.mf__field input::placeholder { color: #9a948b; }
.mf__field input:hover { border-color: #8d867c; }
.mf__field input[aria-invalid="true"] { border-color: var(--c-err); }

/* ---------- the description box (step 2) ----------
   Same frame, same border tokens, same hover as the text inputs — it is the
   same control taking a different shape, not a second kind of field. It sits
   OUTSIDE .mf__grid, so it does not inherit the two-column rule and does not
   need a --wide modifier to escape one.

   FOUR LINES, NOT ONE. A one-line box is an instruction to keep it short, and
   the whole reason this exists is the sentence that does not fit in a radio
   button. min-height carries that floor everywhere; `field-sizing: content`
   then grows the box with the text in the browsers that have it and is simply
   ignored by the ones that do not, which keep the four lines and scroll. That
   is the entire auto-grow: no script, no resize observer, no height written
   from JavaScript.

   AND A CEILING. Left to grow, a long description pushes Back and Continue off
   a 390px screen — the visitor is typing and the way forward has silently gone.
   max-height stops it and hands the overflow to the box's own scrollbar. */
.mf__field--note { margin-top: 14px; }
.mf__field textarea {
  display: block;
  width: 100%;
  min-height: 118px;
  max-height: 340px;
  padding: 11px 14px;
  border: 2px solid var(--c-line);
  border-radius: 2px;
  background: #fff;
  color: #222;
  font: 400 17px/26px var(--ff-body);
  /* vertical only: `both` (the UA default) lets a drag widen the box past the
     panel and take the whole page into a horizontal scroll. */
  resize: vertical;
  field-sizing: content;
  transition: border-color .18s var(--ease);
}
.mf__field textarea:hover { border-color: #8d867c; }
/* The one state in which it DOES turn rust. The countdown above is a warning
   about something that has not happened yet; aria-invalid is only ever set by
   fieldFailure(), which means the server refused the submission and named this
   field. That is a failure, and it takes the same frame every other refused
   field takes. Cleared on the next keystroke by the hygiene handler. */
.mf__field textarea[aria-invalid="true"] { border-color: var(--c-err); }

/* The countdown under it. Typographically .mf__err — same size, same weight,
   same rhythm — because it is the same kind of remark, and only the COLOUR
   moves with severity: badge while it is counting down, rust once a limit is
   actually past.

   IT NEVER SHARES THE SPACE WITH THE RULE ABOVE. The countdown and a refusal
   say the same thing about the same field, so paintCount() and fieldFailure()
   swap: a server verdict hides the count and puts its own sentence in
   #mf-e-message, and the first keystroke afterwards clears the verdict and
   brings the count back. Two rust sentences an inch apart, both about the
   length of one box, is the reader working out that they are one problem. */
.mf__count {
  margin: 8px 0 0;
  font: 600 14px/19px var(--ff-body);
  color: var(--c-badge);
}
.mf__count[hidden] { display: none; }
.mf__count[data-over] { color: var(--c-err); }

/* ---------- consent ----------
   No checkbox: the consent rides on the submit itself, so the affirmative act
   is the tap the visitor already came to make. Kept at body size on purpose —
   shrinking a disclosure is what makes one look evasive. */
.mf__consent {
  margin: 16px 0 0;
  font: 400 14px/20px var(--ff-body);
  color: var(--c-body);
}
.mf__consent b { font-weight: 700; color: #1c1c1c; }
.mf__consent a { color: #8a6a10; font-weight: 600; text-underline-offset: 3px; }
.mf__consent a:hover { color: #000; }

/* ---------- errors ---------- */
.mf__err {
  margin: 8px 0 0;
  font: 600 14px/19px var(--ff-body);
  color: var(--c-err);
}
.mf__err:empty { display: none; }
/* Several files can be refused by one pick — a video, an oversized RAW and a
   PDF in the same drop — and each gets its own named sentence. */
.mf__err p { margin: 5px 0 0; }
.mf__err p:first-child { margin-top: 0; }

/* =============================================================================
   THE SUBMIT-TIME ALERT
   Every failure the button can meet appears HERE and nowhere else: a photo that
   is still uploading, a photo that failed, a field the server rejected, a dead
   connection, a PHP fatal. One box, one voice, two tones.
   ========================================================================== */
.mf__alert {
  margin: 20px 0 0;
  padding: 15px 18px 16px;
  border: 2px solid var(--c-err);
  border-left-width: 6px;
  border-radius: 2px;
  background: #fdf6f3;
}
.mf__alert[hidden] { display: none; }
/* "still uploading" is not a failure — nothing has gone wrong, so it does not
   get the rust frame that means something has. */
.mf__alert[data-tone="wait"] { border-color: #1c1c1c; background: #fffaf0; }

.mf__alert-t {
  margin: 0;
  font: 700 17px/24px var(--ff-body);
  color: #1c1c1c;
}
.mf__alert-t:focus { outline: none; }     /* focus lands here to carry the news */
.mf__alert-t:focus-visible {
  outline: 3px solid #1c1c1c;
  outline-offset: 3px;
}
.mf__alert-list { margin-top: 9px; font-weight: 400; }
.mf__alert-list[hidden] { display: none; }
.mf__alert-c {
  margin: 11px 0 0;
  font: 400 14px/20px var(--ff-body);
  color: var(--c-body);
}
.mf__alert-c a {
  color: #8a6a10;
  font-weight: 700;
  text-underline-offset: 3px;
  white-space: nowrap;
}
.mf__alert-c a:hover { color: #000; }

.mf__alert-do {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 14px;
}
.mf__alert-do[hidden] { display: none; }
.mf__alert-b {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  padding: 9px 18px;
  border: 2px solid #1c1c1c;
  border-radius: 2px;
  background: var(--c-amber);
  color: #000;
  font: 700 16px/18px var(--ff-display);
  letter-spacing: .03em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color .18s var(--ease), color .18s var(--ease),
              transform .18s var(--ease), opacity .18s var(--ease);
}
.mf__alert-b:hover { background: var(--c-amber-hi); }
.mf__alert-b:active { transform: translateY(1px); }
.mf__alert-b--ghost { background: transparent; }
.mf__alert-b--ghost:hover { background: #1c1c1c; color: var(--c-off); }
.mf__alert-b:disabled { opacity: .66; cursor: default; }
.mf__alert-b:disabled:hover { background: var(--c-amber); color: #000; }
.mf__alert-b:disabled:active { transform: none; }

/* The server's log reference. Mono and quiet: it is for the phone call that
   follows, not for the visitor to read. */
.mf__alert-code {
  margin: 11px 0 0;
  font: 400 12px/16px ui-monospace, "SF Mono", "SFMono-Regular", Menlo, Consolas, monospace;
  letter-spacing: .04em;
  color: var(--c-badge);
}
.mf__alert-code:empty { display: none; }

/* The button is doing something. It says what, and it cannot be pressed twice. */
.btn:disabled { opacity: .6; cursor: default; }
.btn:disabled:hover { background: var(--c-amber); }
.btn:disabled:active { transform: none; }

/* ---------- step footer ---------- */
.mf__nav {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 14px;
  margin-top: 26px;
}
.mf__back {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  flex-shrink: 0;
  padding: 10.4px 20px;
  border: 2px solid #1c1c1c;
  border-radius: 2px;
  background: transparent;
  color: #1c1c1c;
  font: 700 20px/20px var(--ff-display);
  letter-spacing: .02em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color .18s var(--ease), color .18s var(--ease),
              transform .18s var(--ease);
}
.mf__back:hover { background: #1c1c1c; color: var(--c-off); }
.mf__back:active { transform: translateY(1px); }
.mf__back svg {
  width: 9px;
  height: 15px;
  flex-shrink: 0;
  fill: none;
  stroke: currentColor;
  stroke-width: 2.6;
  stroke-linecap: square;
}
.mf__call {
  margin: 16px 0 0;
  font: 400 15px/21px var(--ff-body);
  color: var(--c-body);
}
.mf__call a {
  font-weight: 700;
  color: #8a6a10;
  text-underline-offset: 3px;
  white-space: nowrap;          /* never break a phone number across lines */
}
.mf__call a:hover { color: #000; }

/* =============================================================================
   THE REVEAL (lander only — the wrapper that is the ONLY difference between
   the two copies of the block)
   ========================================================================== */
.mf-reveal { margin-top: 34px; }
.mf-reveal__open { display: block; }
.mf-reveal__open .btn { font-size: 24px; padding: 14px 34px; }
.mf-reveal__open[hidden] { display: none; }
/* the element is selected by attribute, not class — the old .mf-reveal__body rule
   matched nothing, so hiding rested entirely on the UA sheet */
[data-reveal-body][hidden] { display: none; }

/* =============================================================================
   FUNNEL PAGE FURNITURE — /free-assessment/ and /thanks/
   ========================================================================== */
/* the band itself is style.css's own `.page` — only the two blocks under the
   form are new */
.fnl__after { max-width: 760px; margin: 34px auto 0; }
.fnl__after p {
  margin: 0;
  font: 400 17px/26px var(--ff-body);
  color: var(--c-body);
}
.fnl__after p + p { margin-top: 12px; }
.fnl__after b { font-weight: 700; color: #000; }
.fnl__after a { color: #8a6a10; text-underline-offset: 3px; font-weight: 600; }
.fnl__after a:hover { color: #000; }

/* the call alternative — a hard-framed strip, the site's own frame device */
.fnl__call {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px 22px;
  max-width: 760px;
  margin: 26px auto 0;
  padding: 20px 24px;
  border: 3px solid #1c1c1c;
  border-radius: 2px;
  background: var(--c-ink);
}
.fnl__call p {
  margin: 0;
  font: 400 16px/23px var(--ff-body);
  color: rgba(251, 250, 248, .9);
}
.fnl__call .btn { margin-left: auto; }

/* ---------- /thanks/ ----------
   A confirmation page is a TRUST page: compact full-width blocks, no 760px
   prose column. The first pass put a 760 column in a 1352 wrap and left the
   right half of the band empty. */
/* `.tnx__lead` ("Nothing else is needed from you.") lived here. It has moved up
   into the page head, where it replaced a line that only repeated the H1 —
   deleted rather than left behind, so nobody puts the duplicate back. */

/* THE ONE THING ON THIS PAGE THAT IS NOT A SENTENCE.
   The visitor arrives wanting a single fact — it went through — and a page that
   opens with the ordinary dark header, a nav and a ZIP box reads as an invitation
   to go do something else at the exact moment they want "done". The tick is the
   affirmative the words cannot carry on their own.
   It is the brand's OWN tick, `#ico-tick`, the same path the house mark draws,
   defined once in this page's <defs> so the shape can never drift from the logo
   in the header above it. The house is not repeated — that is the logo, and it is
   already on screen; alone, the check is the success glyph. */
.pagehead--done > .wrap {
  display: flex;
  align-items: center;
  gap: clamp(20px, 3vw, 36px);
}
/* min-width:0 or a long H1 refuses to wrap and pushes the row wider than the
   wrap; flex-shrink:0 keeps the tick from being squeezed to a sliver instead. */
.tnx__said { min-width: 0; }
.tnx__tick {
  flex-shrink: 0;
  width: clamp(58px, 8.5vw, 104px);
  height: auto;
  fill: none;
  stroke: var(--c-amber);
  stroke-width: 13;
  stroke-linecap: square;
  stroke-linejoin: miter;
}
/* Beside a heading that wraps to three lines on a phone the tick is cramped and
   the H1 loses its measure. Stack instead — same markup, no second copy. */
@media (max-width: 640px) {
  .pagehead--done > .wrap { flex-direction: column; align-items: flex-start; gap: 16px; }
}

.tnx__list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 0;
  margin: 34px 0 0;
  padding: 28px 0 0;
  border-top: 3px solid #1c1c1c;
  list-style: none;
}
.tnx__list li { padding-inline: 30px; }
.tnx__list li:first-child { padding-left: 0; }
.tnx__list li:last-child { padding-right: 0; }
.tnx__list li + li { border-left: 1px solid #d0c6b9; }
.tnx__list svg {
  width: 46px;
  height: 45px;
  margin-bottom: 14px;
  fill: var(--c-amber);
  stroke: #1c1c1c;
  stroke-width: 3.4;
  stroke-linejoin: miter;
}
/* the numeral: every other pentagon on the site carries a number or a pictogram,
   so a bare amber blob read as a missing icon */
.tnx__list svg .tnx__n {
  fill: #1c1c1c;
  stroke: none;
  font: 700 21px/1 var(--ff-display);
}
/* Same floor as the lander's ladder: one of the three headings wraps and the
   other two do not, which left the bodies on three different baselines. */
.tnx__list b {
  display: block;
  min-height: 50px;
  font: 700 21px/25px var(--ff-display);
  letter-spacing: .02em;
  text-transform: uppercase;
  color: #000;
}
.tnx__list span {
  display: block;
  margin-top: 7px;
  font: 400 16.5px/24px var(--ff-body);
  color: var(--c-body);
}
.tnx .fnl__call { max-width: none; margin-top: 40px; }
.tnx__back { margin: 26px 0 0; max-width: 900px;
             font: 400 17px/25px var(--ff-body); color: var(--c-body); }
.tnx__back a { color: #8a6a10; font-weight: 600; text-underline-offset: 3px; }
.tnx__back a:hover { color: #000; }

/* =============================================================================
   RESPONSIVE — one markup, CSS only
   ========================================================================== */
@media (max-width: 700px) {
  .mf { padding: 24px 18px 26px; border-width: 2px; }
  .mf__h { font-size: 23px; line-height: 27px; }
  .mf__opts { grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 8px; }
  .mf__opt span { min-height: 50px; font-size: 16px; padding: 9px 10px; }
  .mf__grid { grid-template-columns: minmax(0, 1fr); gap: 14px; }
  /* A 340px box on an 812px screen leaves the step footer below the fold while
     somebody is still typing into it. Roughly a third of the viewport is the
     most it may take before the scrollbar takes over. */
  .mf__field textarea { min-height: 106px; max-height: 230px; }
  .mf__drop { padding: 24px 16px; }
  .mf__nav { gap: 10px; }
  .mf__nav .btn { flex: 1 1 auto; }
  .mf-reveal__open .btn { width: 100%; font-size: 21px; padding: 13px 20px; }

  .fnl__call { padding: 18px 18px; }
  .fnl__call .btn { margin-left: 0; width: 100%; }
}

/* ---------- the file row on a phone ----------
   Same markup. On a 390px screen a thumbnail, a name, a bar, a "try again" and
   a remove button in one line leaves about 100px for the name, so the bar takes
   its own full-width row underneath and the name gets the space back. */
@media (max-width: 560px) {
  .mf__item {
    grid-template-columns: 52px minmax(0, 1fr) auto;
    grid-template-areas:
      "thumb body acts"
      "bar   bar  bar";
    column-gap: 10px;
    row-gap: 9px;
    padding: 8px;
  }
  .mf__item > .mf__item-b { align-self: center; }
  .mf__item-t { width: 52px; height: 52px; }
  .mf__item-n { font-size: 14.5px; }

  /* A failed row carries a REASON and a second button. Left in the three-column
     layout that leaves the middle column about 130px wide: the file name
     truncates to nothing and the sentence shatters over three lines. The buttons
     drop to their own row and the sentence gets the width back.

     ONLY when the retry button is actually there. A hard failure — a video, a
     format we cannot read, a file over the limit — offers no retry, so the same
     rule spent a whole third row of the card on one 30px remove button sitting
     alone at the right edge. With just the × in the column there is no 130px
     to reclaim, so that row keeps the ordinary three-column layout. */
  .mf__item[data-state="failed"]:has(.mf__retry--row:not([hidden])) {
    grid-template-columns: 52px minmax(0, 1fr);
    grid-template-areas:
      "thumb body"
      "bar   bar"
      "acts  acts";
  }
  .mf__item[data-state="failed"]:has(.mf__retry--row:not([hidden])) > .mf__item-a {
    justify-content: flex-end;
  }

  /* Same reasoning one level up: the count line and a 150px button do not fit
     side by side here, so the strip stacks and the button goes full width. */
  .mf__up { grid-template-columns: minmax(0, 1fr); padding: 11px 12px; }
  .mf__up > .mf__up-t  { grid-column: 1; grid-row: 1; }
  .mf__up > .mf__bar   { grid-column: 1; grid-row: 2; }
  .mf__up > .mf__retry { grid-column: 1; grid-row: 3; justify-self: stretch; }
  .mf__up-t { font-size: 13px; letter-spacing: .05em; }

  /* The format list cannot fit one line at this width. Capped, it breaks between
     the limits and the formats instead of splitting the list itself. */
  .mf__lim { max-width: 13.2em; }

  /* Two side-by-side choices do not fit at this width; wrapped, they read as a
     ragged pile. Stacked full-width, they read as two answers to one question. */
  .mf__alert { padding: 14px 15px 15px; }
  .mf__alert-do { flex-direction: column; gap: 9px; }
  .mf__alert-b { width: 100%; }
}

/* the three-across "what happens next" row stacks with the rest of the site */
@media (max-width: 900px) {
  .tnx__list {
    grid-template-columns: minmax(0, 1fr);
    margin-top: 28px;
    padding-top: 0;
    border-top: 0;
  }
  .tnx__list b { min-height: 0; }      /* stacked: nothing to align across */
  .tnx__list li { padding: 18px 0; border-top: 2px solid #1c1c1c; }
  .tnx__list li:last-child { border-bottom: 2px solid #1c1c1c; }
  .tnx__list li + li { border-left: 0; }
  .tnx__list svg { margin-bottom: 10px; }
  .tnx .fnl__call { margin-top: 30px; }
}

@media (max-width: 380px) {
  .mf__opts { grid-template-columns: minmax(0, 1fr); }
}
