
  :root {
    --paper: #FBFAF7;
    --paper-dim: #F3F1EB;
    --ink: #18160F;
    --ink-soft: #4A4738;
    --mute: #837F6E;
    --lime: #A6FF00;
    --lime-deep: #7ED000;
    --moss: #48583A;
    --stone: #E7E3D6;
    --line: #DEDACB;
    --radius: 2px;
  }

  * { box-sizing: border-box; }

  html, body {
    margin: 0;
    padding: 0;
    background: var(--paper);
    color: var(--ink);
    font-family: Fraunces, serif;
    -webkit-font-smoothing: antialiased;
  }

  body {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    padding: 48px 24px 80px;
  }

  .wrap {
    width: 100%;
    max-width: 640px;
  }

  /* ---------- Header ---------- */
  .brand-header {
    display: flex;
    flex-direction: column;
    align-items: center;
    margin-bottom: 40px;
  }

  .brand-header img {
    width: 176px;
    height: auto;
    margin-bottom: 18px;
  }

  .welcome-eyebrow {
    font-family: 'Fraunces', serif;
    font-weight: 450;
    font-size: 30px;
    color: var(--ink);
    margin-bottom: 14px;
  }

  .brand-name {
    font-family: Fraunces, serif;
    font-size: clamp(15px, 5.6vw, 28px);
    letter-spacing: 0.06em;
    text-transform: uppercase;
    color: var(--ink);
    font-weight: 450;
    white-space: nowrap;
    text-align: center;
  }
  .brand-name .amp {
    font-family: 'IM Fell English SC', serif;
    font-weight: 400;
  }

  .brand-name .lead-in {
    font-size: 11px;
    letter-spacing: 0.1em;
    text-transform: uppercase;
    color: var(--mute);
    margin-right: 6px;
  }

  /* ---------- Vine divider (signature element) ---------- */
  .vine-divider {
    width: 100%;
    height: 14px;
    margin: 28px 0;
    opacity: 0.85;
  }
  .vine-divider svg { width: 100%; height: 100%; display: block; }

  /* ---------- Eyebrow / rustic labels ---------- */
  .eyebrow {
    font-family: 'IM Fell English SC', serif;
    font-size: 16px;
    letter-spacing: 0.08em;
    color: var(--moss);
    text-align: center;
    margin-bottom: 10px;
  }

  h1 {
    font-family: 'Fraunces', serif;
    font-weight: 450;
    font-size: 32px;
    line-height: 1.25;
    text-align: center;
    margin: 0 0 14px;
    letter-spacing: -0.01em;
  }

  .lede {
    text-align: center;
    color: var(--ink-soft);
    font-size: 16px;
    line-height: 1.6;
    max-width: 480px;
    margin: 0 auto 40px;
  }

  /* ---------- Rate gate ---------- */
  /* CC-W25: the rate boxes are smaller. They are now a block of context at the top
     of the project page rather than a screen of their own, so they must not be the
     loudest thing on it. Figure 28 -> 20, card padding 22 -> 12, label 14 -> 12.
     The three tier LABELS are untouched. */
  .rate-tiers {
    display: flex;
    gap: 8px;
    margin-bottom: 14px;
  }
  .tier-card {
    flex: 1;
    background: var(--paper-dim);
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 12px 8px;
    text-align: center;
  }
  .tier-figure {
    font-family: 'Fraunces', serif;
    font-weight: 450;
    font-size: 20px;
    line-height: 1;
    color: var(--ink);
  }
  .tier-figure .accent { color: var(--moss); }
  .tier-label {
    font-family: 'IM Fell English SC', serif;
    font-size: 12px;
    letter-spacing: 0.04em;
    color: var(--mute);
    margin-top: 5px;
    line-height: 1.3;
  }

  .materials-note {
    font-size: 13px;
    color: var(--mute);
    text-align: center;
    line-height: 1.6;
    margin: 0 auto 28px;
    max-width: 460px;
    font-style: italic;
  }

  .reassurance {
    font-size: 14px;
    color: var(--mute);
    text-align: center;
    line-height: 1.7;
    margin: 0 auto 36px;
    max-width: 460px;
  }

  /* Consultation copy: same look as .reassurance, tighter so the three
     paragraphs read as one block rather than three separate notes. */
  .reassurance.consult-copy { margin-bottom: 14px; }
  .reassurance.consult-copy.last { margin-bottom: 30px; }

  /* The start-preference chips reuse the form's .choice pattern verbatim;
     this only centres them inside the centred rate gate. */
  .gate-choice {
    margin: 0 auto 32px;
    max-width: 460px;
  }
  .gate-choice .choice-grid { justify-content: center; }
  /* ---------- About section ---------- */
  .about-photo {
    display: block;
    width: 100%;
      /* ⚠ height:auto IS REQUIRED. The img carries width/height attributes (they reserve the box and stop layout shift), and those become a presentational height that makes BOTH dimensions definite - which silently disables aspect-ratio. Without this the hero rendered 242x1205 instead of 242x182. Measured on a draft. */
      height: auto;
    aspect-ratio: 4 / 3;
    object-fit: cover;
      /* CC-W66: the slot is the photograph's own 4:3, so nothing is cropped. These two stay so a NARROWER slot still biases right and down - right for the iris, down for the planting. */
      object-position: 72% 55%;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    margin-bottom: 32px;
  }

  .about-mission {
    font-size: 16px;
    line-height: 1.7;
    color: var(--ink-soft);
    text-align: center;
    max-width: 500px;
    margin: 0 auto 40px;
  }

  /* 🗃 .services-eyebrow's rule was here. Removed CC-W95 with its only user:
     "Our Services" was a <div> styled as a small moss label, and Brandon is right
     that it was already doing the job of the page's title. A div cannot BE a page
     title, so it did not get styled into looking like one — it became the same
     <h1 class="page-title"> /home/ and /work/ already carry, which is also how
     /services/ stopped being the one page in the site with no <h1> at all.
     The class had exactly one user in the whole repo; nothing else changes. */

  .services-list {
    list-style: none;
    margin: 0 0 44px;
    padding: 0;
  }
  .services-list li {
    padding: 18px 0;
    border-bottom: 1px solid var(--line);
    display: grid;
    grid-template-columns: 190px 1fr;
    gap: 20px;
  }
  .services-list li:first-child {
    border-top: 1px solid var(--line);
  }
  .services-list .service-name {
    font-family: 'Fraunces', serif;
    font-weight: 450;
    font-size: 16px;
    color: var(--ink);
    line-height: 1.4;
  }
  .services-list .service-desc {
    font-size: 14px;
    color: var(--mute);
    line-height: 1.5;
  }

  @media (max-width: 480px) {
    .services-list li {
      grid-template-columns: 1fr;
      gap: 4px;
    }
  }

  .btn-row {
    display: flex;
    flex-direction: column;
    gap: 12px;
    max-width: 340px;
    margin: 0 auto;
  }

  button {
    font-family: Fraunces, serif;
    font-size: 15px;
    font-weight: 600;
    padding: 16px 24px;
    border-radius: var(--radius);
    border: none;
    cursor: pointer;
    transition: transform 0.15s ease, background 0.15s ease;
  }
  button:active { transform: scale(0.98); }

  /* CC-W25: INVERTED - lime fill, dark text. The lime is the intake's OWN --lime
     (#A6FF00) and the deep stop is the intake's OWN --lime-deep (#7ED000). The FIELD
     APP's brand lime is deliberately NOT introduced here: unifying the palettes is
     separate work and must not arrive by way of a button. (The brand hex is not even
     written in this comment - a check that the file does not contain it would find
     the comment saying so, which is a false positive this project has hit before.) */
  .btn-primary {
    background: linear-gradient(180deg, #C2FF4D 0%, var(--lime) 55%, var(--lime-deep) 100%);
    color: var(--ink);
    position: relative;
    border: 1px solid rgba(24,22,15,0.30);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.45), inset 0 -1px 0 rgba(0,0,0,0.16), 0 1px 2px rgba(0,0,0,0.18);
    text-shadow: 0 1px 0 rgba(255,255,255,0.30);
    letter-spacing: 0.06em;
    font-variant: small-caps;
    align-self: center;
    width: auto;
    min-width: 180px;
    padding: 14px 36px;
    clip-path: polygon(10px 0, calc(100% - 10px) 0, 100% 10px, 100% calc(100% - 10px), calc(100% - 10px) 100%, 10px 100%, 0 calc(100% - 10px), 0 10px);
  }
  .btn-primary:hover {
    background: linear-gradient(180deg, #D0FF73 0%, #B4FF33 55%, #8FE000 100%);
  }

  .btn-secondary {
    background: linear-gradient(180deg, #efece3 0%, var(--stone) 55%, #d9d4c2 100%);
    color: var(--ink-soft);
    border: 1px solid var(--line);
    box-shadow: inset 0 1px 0 rgba(255,255,255,0.6), inset 0 -1px 0 rgba(0,0,0,0.08);
    text-shadow: 0 1px 0 rgba(255,255,255,0.5);
    letter-spacing: 0.04em;
    font-variant: small-caps;
  }
  .btn-secondary:hover {
    background: linear-gradient(180deg, #f5f3ec 0%, var(--paper-dim) 55%, #cfc9b4 100%);
  }

  /* ---------- Questionnaire ---------- */
  .progress-track {
    width: 100%;
    height: 2px;
    background: var(--stone);
    margin-bottom: 8px;
    position: relative;
    overflow: hidden;
  }
  .progress-fill {
    position: absolute;
    top: 0; left: 0; bottom: 0;
    background: var(--lime-deep);
    width: 0%;
    transition: width 0.4s ease;
  }
  .progress-label {
    font-family: 'IM Fell English SC', serif;
    font-size: 14px;
    letter-spacing: 0.05em;
    color: var(--mute);
    margin-bottom: 36px;
    text-align: right;
  }

  .section { display: none; }
  .section.active { display: block; animation: fadeIn 0.35s ease; }
  @keyframes fadeIn {
    from { opacity: 0; transform: translateY(6px); }
    to { opacity: 1; transform: translateY(0); }
  }

  .section h2 {
    font-family: 'Fraunces', serif;
    font-weight: 450;
    font-size: 24px;
    margin: 0 0 6px;
  }

  .section .section-note {
    font-size: 14px;
    color: var(--mute);
    margin: 0 0 28px;
  }

  .field {
    margin-bottom: 24px;
  }

  .field-row {
    display: flex;
    gap: 12px;
  }
  .field-row .subfield { flex: 1; min-width: 0; }
  .field-row .subfield.narrow { flex: 0 0 30%; }
  .field-row .subfield label {
    display: block;
    font-family: Fraunces, serif;
    font-size: 12px;
    letter-spacing: 0.02em;
    color: var(--mute);
    margin-bottom: 6px;
  }

  .field label {
    display: block;
    font-family: 'IM Fell English SC', serif;
    font-size: 15px;
    letter-spacing: 0.04em;
    color: var(--moss);
    margin-bottom: 8px;
  }

  .field .hint {
    font-family: Fraunces, serif;
    font-size: 13px;
    color: var(--mute);
    text-transform: none;
    letter-spacing: 0;
    margin-top: 6px;
  }

  .field .hint a {
    color: var(--moss);
    text-decoration: underline;
    text-decoration-color: var(--lime);
    text-underline-offset: 2px;
  }

  .consent-row {
    display: flex;
    align-items: flex-start;
    gap: 10px;
    margin-top: 4px;
  }
  .consent-row input[type="checkbox"] {
    flex: none;
    width: 18px;
    height: 18px;
    margin: 1px 0 0;
    accent-color: var(--moss);
    cursor: pointer;
  }
  .field .consent-row label.consent-label {
    display: inline;
    font-family: Fraunces, serif;
    font-size: 15px;
    letter-spacing: 0;
    text-transform: none;
    color: var(--ink);
    margin: 0;
    cursor: pointer;
    line-height: 1.45;
  }

  .contact-explainer {
    font-family: Fraunces, serif;
    font-size: 15px;
    color: var(--ink-soft);
    line-height: 1.6;
    margin: 0 0 10px;
  }

  input[type="text"],
  input[type="email"],
  input[type="tel"],
  input[type="date"],
  textarea,
  select {
    width: 100%;
    font-family: Fraunces, serif;
    font-size: 15px;
    color: var(--ink);
    background: #fff;
    border: 1px solid var(--line);
    border-radius: var(--radius);
    padding: 13px 14px;
    outline: none;
  }

  textarea { resize: vertical; min-height: 90px; }

  input:focus, textarea:focus, select:focus {
    border-color: var(--moss);
    box-shadow: 0 0 0 3px rgba(166,255,0,0.25);
  }

  .choice-grid {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
  }

  .choice {
    padding: 10px 16px;
    border: 1px solid var(--line);
    border-radius: 999px;
    font-size: 14px;
    cursor: pointer;
    user-select: none;
    background: #fff;
    color: var(--ink-soft);
    transition: all 0.15s ease;
  }
  .choice.selected {
    background: var(--ink);
    color: var(--lime);
    border-color: var(--ink);
  }

  /* ---------- Availability grid ---------- */
  .avail-note {
    font-family: Fraunces, serif;
    font-size: 13px;
    color: var(--mute);
    margin: 0 0 10px;
  }
  .avail-grid {
    display: grid;
    grid-template-columns: 48px repeat(5, 1fr);
    gap: 6px;
    align-items: center;
    max-width: 460px;
  }
  .avail-head {
    font-family: 'IM Fell English SC', serif;
    font-size: 13px;
    letter-spacing: 0.04em;
    color: var(--moss);
    text-align: center;
  }
  .avail-rowlabel {
    font-family: Fraunces, serif;
    font-size: 12px;
    color: var(--mute);
    text-align: right;
    padding-right: 4px;
  }
  .avail-cell {
    height: 32px;
    border: 1px solid var(--line);
    border-radius: 8px;
    background: #fff;
    cursor: pointer;
    user-select: none;
    position: relative;
    transition: all 0.15s ease;
  }
  .avail-cell.selected {
    background: var(--ink);
    border-color: var(--ink);
  }
  .avail-cell.selected::after {
    content: "\2713";
    position: absolute;
    inset: 0;
    display: flex;
    align-items: center;
    justify-content: center;
    color: var(--lime);
    font-size: 15px;
  }

  /* ---------- File upload ---------- */
  .upload-zone {
    border: 1px dashed var(--line);
    border-radius: var(--radius);
    padding: 24px;
    text-align: center;
    background: var(--paper-dim);
    cursor: pointer;
    transition: border-color 0.15s ease;
  }
  .upload-zone:hover { border-color: var(--moss); }
  .upload-zone input { display: none; }
  .upload-actions {
    display: flex;
    gap: 10px;
    justify-content: center;
    margin-top: 14px;
  }
  .upload-btn {
    font-family: Fraunces, serif;
    font-size: 13px;
    font-weight: 600;
    padding: 10px 16px;
    border-radius: var(--radius);
    border: 1px solid var(--line);
    background: var(--paper);
    color: var(--ink-soft);
    cursor: pointer;
  }
  .upload-btn:active { transform: scale(0.98); }
  @media (min-width: 601px) {
    #camera-btn { display: none; }
  }
  .upload-zone .upload-label {
    font-size: 14px;
    color: var(--ink-soft);
  }
  .upload-zone .upload-sub {
    font-size: 12px;
    color: var(--mute);
    margin-top: 4px;
  }
  .file-list {
    display: flex;
    flex-wrap: wrap;
    gap: 8px;
    margin-top: 12px;
  }
  .file-chip {
    font-size: 12px;
    background: var(--stone);
    color: var(--ink-soft);
    padding: 6px 10px;
    border-radius: 999px;
  }
  .photo-thumb {
    position: relative;
    width: 72px;
    height: 72px;
    border-radius: var(--radius);
    overflow: hidden;
    border: 1px solid var(--line);
  }
  .photo-thumb img {
    width: 100%;
    height: 100%;
    object-fit: cover;
    display: block;
  }
  .photo-thumb .thumb-x {
    position: absolute;
    top: 2px;
    right: 2px;
    width: 20px;
    height: 20px;
    border-radius: 50%;
    background: rgba(20,20,16,0.75);
    color: #fff;
    font-size: 13px;
    line-height: 20px;
    text-align: center;
    cursor: pointer;
  }
  /* CC-W42: each photo now shows its own state and carries its own note. A single
     spinner over forty uploads reads as frozen, and a client on two bars needs to see
     which picture is stuck, not that "something" is. */
  .photo-item { display: flex; flex-direction: column; gap: 4px; width: 92px; }
  .photo-thumb.st-uploading img { opacity: .45; }
  .photo-thumb.st-failed img { opacity: .35; filter: grayscale(1); }
  .photo-state {
    font-size: 10px; line-height: 1.3; letter-spacing: .04em; text-align: center;
    min-height: 13px; color: #6b6f5e;
  }
  .photo-state.st-done { color: #4b7f2a; }
  .photo-state.st-failed { color: #a3341f; font-weight: 600; }
  .photo-note {
    width: 100%; box-sizing: border-box; font: inherit; font-size: 11px;
    padding: 4px 6px; border: 1px solid #d8d6c8; border-radius: 3px;
    background: #fff; color: inherit; resize: none; min-height: 30px;
  }
  .photo-note::placeholder { color: #9b9d8d; font-size: 10.5px; }
  .photo-retry {
    font: inherit; font-size: 10px; padding: 2px 6px; cursor: pointer;
    border: 1px solid #a3341f; background: #fff; color: #a3341f; border-radius: 3px;
  }
  .upload-zone.at-limit {
    opacity: 0.5;
    pointer-events: none;
  }

  .nav-row {
    display: grid;
    grid-template-columns: 1fr auto 1fr;
    align-items: center;
    margin-top: 44px;
  }

  .nav-row .nav-back { justify-self: start; }
  .nav-back {
    background: none;
    border: none;
    color: var(--mute);
    font-size: 12px;
    padding: 8px 4px;
  }
  .nav-back:hover { color: var(--ink); }

  #nav-next:disabled { opacity: 0.6; cursor: wait; }

  /* ---------- Confirmation ---------- */
  .confirm-wrap { text-align: center; padding: 40px 0; }
  .confirm-wrap h1 { margin-bottom: 18px; }

  /* ---------- Decline ---------- */
  .decline-wrap { text-align: center; padding: 40px 0; }

  @media (max-width: 480px) {
    h1 { font-size: 26px; }
  }  /* ---------- Decorative frame: intact art nouveau frame, rails elongate with page ---------- */
  .wrap {
    position: relative;
    --u:      min(308px, 92vw);          /* THE scale. S = u/1400 = 22% */
    --cw:     calc(var(--u) * .43214);   /* 605/1400 */
    --ch:     calc(var(--u) * .64071);   /* 897/1400 */
    --barbox: calc(var(--u) * .04286);   /* 60/1400  */
    --railL:  calc(var(--u) * .06786);   /* 95/1400   left slice window  */
    --railR:  calc(var(--u) * .04643);   /* 65/1400   right slice window */
    --railw:  calc(var(--u) * .02857);   /* 40/1400  */
  }
  .page-body {
    padding: calc(var(--ch) * .92) calc(var(--railL) + 30px);
    /* the aspect-ratio that used to sit here existed to hold short pages at the
       PNG frame's proportion. The corners are a fixed size now and the rails
       stretch, so a short page simply makes a shorter frame. A floor is still
       needed so the rails never compute a negative length. */
    min-height: calc(var(--ch) * 2.5);
  }
  /* FOUR MIRRORED CORNERS, FOUR BARS - all one traced drawing, inlined once and
     cropped eight ways with <use>. Zero image requests for the frame.
     ONE control: --u, the width the whole 1400-unit drawing would occupy.
     S = u/1400 = 22%. Every number is a fixed fraction of the ARTWORK:
       corner 605 -> .43214u    corner 897 -> .64071u
       BAR 20 -> .01429u        STEM 23 -> .01643u   (kept different on purpose)
       bar box 60 -> .04286u    rail box 40 -> .02857u
     The bottom corners are the top corners with scaleY(-1), so their stems land
     at the same x and the rails run straight down.
     The rails are top/bottom anchored, so they run the FULL height of .wrap and
     grow with the real content.
     NO mix-blend-mode: that existed only because the PNGs were black on opaque
     white. Vector has real transparency and there is nothing left to hide.
     NO padding percentages: 64.07% / 60.93% were hand-tuned to the PNGs' aspect
     ratios and now point at nothing.
     NO stroke, border, taper or drawn line anywhere - every visible line is a
     crop of the drawing. */
  .fpc { position: absolute; pointer-events: none; overflow: hidden; }
  .fpc > svg { display: block; width: 100%; height: 100%; }
  .f-tl { left: 0;  top: 0;    width: var(--cw); height: var(--ch); }
  .f-tr { right: 0; top: 0;    width: var(--cw); height: var(--ch); }
  .f-bl { left: 0;  bottom: 0; width: var(--cw); height: var(--ch); transform: scaleY(-1); }
  .f-br { right: 0; bottom: 0; width: var(--cw); height: var(--ch); transform: scaleY(-1); }
  .f-bt { left: var(--cw); right: var(--cw); top: 0;    height: var(--barbox); }
  .f-bb { left: var(--cw); right: var(--cw); bottom: 0; height: var(--barbox); transform: scaleY(-1); }
  .f-rl { left:  var(--railL); top: var(--ch); bottom: var(--ch); width: var(--railw); }
  .f-rr { right: var(--railR); top: var(--ch); bottom: var(--ch); width: var(--railw); }

  /* ---------- Mobile refinements: keep content clear of the rails ---------- */
  @media (max-width: 600px) {
    .page-body { padding-left: 13%; padding-right: 13%; }
    .rate-tiers { flex-direction: column; gap: 8px; }
    .tier-card {
      display: flex;
      align-items: baseline;
      justify-content: center;
      gap: 10px;
      padding: 9px 12px;
    }
    .tier-label { margin-top: 0; }
    .nav-row {
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 12px;
    }
    .nav-row .nav-back {
      order: 2;
      justify-self: auto;
    }
    .nav-row .btn-primary { order: 1; }
  }



  /* 🗃 THE GALLERY'S RULES USED TO LIVE HERE. THEY DO NOT ANY MORE — the live
     ones are in the CC-W87 block further down. Two comments were left standing
     over them and both had gone false, so they are replaced by this one:

     · CC-W66 said the rules were kept, unused, "so photo two is a paste rather
       than a rebuild". CC-W85 did paste photographs in, and CC-W87 rewrote the
       layout — so they stopped being a spare and became a second, live copy.
     · CC-W87's own comment then described a column layout the page did not
       have. 🔴 ITS column-count NEVER APPLIED: display:grid survived here, and
       column-count does not apply to a grid container. Measured on the CC-W88
       draft at 1280px — display "grid", and 573px of dead space below the
       short photographs, which is exactly the failure CC-W87 wrote itself to
       avoid. Removed CC-W89.

     ⭐ THE ONE THING WORTH KEEPING FROM CC-W66, because it was measured and it
        is still true: the content column is 242px on a 375px phone, so any
        min-width for a gallery track has to be min(260px,100%) — a bare 260px
        makes the track wider than its container and the image juts out. */


  /* CC-W67 — THE RATES AS PLAIN TEXT, NOT CARDS.
     Brandon has worried since day one that the pricing is what puts people off. A
     bordered, filled card makes a number announce itself; a sentence lets someone read
     past it. So: no box, no fill, no border, no oversized figure - the same serif, the
     same size and the same colour as the prose around it, just a list.
     ⚠ STILL FINDABLE AND LEGIBLE, WHICH IS THE OTHER HALF OF THE INSTRUCTION. It keeps
        its own "Our Hourly Rates" heading, it sits exactly where it always did, and it
        uses --ink-soft (the body-copy colour) rather than --mute, so quiet is not the
        same as faint.
     🚫 The wording is untouched. The ids rate-1p/2p/3p are load-bearing - the URL-param
        rate override writes into them by id - so they survive verbatim. */
  .rate-list{list-style:none;margin:0 auto 26px;padding:0;max-width:460px;
    text-align:center;font-family:Fraunces,serif;font-size:16px;line-height:2;
    color:var(--ink-soft);}
  .rate-list li{margin:0;}
  @media (max-width:460px){.rate-list{font-size:15px;line-height:1.9;}}


  /* CC-W68 (1) — the tagline is now the HEADING for the paragraph under it, so it is
     bound to that paragraph by proximity: less space below it than above it. That is
     what makes photo -> heading -> description read as one movement rather than three
     stacked fragments.
     🚫 The type SIZE is deliberately not changed. Brandon asked for it to be moved and
        to work as a heading, not resized, and at 32/26px above a 16px paragraph it
        already reads as the heading of that block. Resizing is one line if he wants it. */
  .about-heading{margin:26px 0 8px;}

  /* CC-W68 (4) — the consultation copy takes the SAME treatment as the .lede sentence
     above the rates. All three properties, not just size:
        size   14px -> 16px      (matching .lede)
        colour --mute -> --ink-soft   ← this is the half that "too light" was about
        line-height 1.7 -> 1.6   (matching .lede)
     ⚠ WEIGHT NEEDED NO CHANGE and that is measured, not skipped: neither .lede nor
       .reassurance sets font-weight, so both already inherit the same one. */
  .reassurance.consult-copy{font-size:16px;color:var(--ink-soft);line-height:1.6;}

  /* CC-W68 (5) — the selected choice pill is INVERTED: lime fill, black text.
     Contrast of --ink #18160F on --lime #A6FF00 is 14.7:1, far past AA and AAA.
     🚫 SCOPED TO .choice ONLY. The footer Instagram pill and every other rounded thing
        on the page is untouched — .ig-link is not in this selector. */
  .choice.selected{background:var(--lime);color:var(--ink);border-color:var(--lime-deep);}
  .choice.selected:hover{background:var(--lime-deep);color:var(--ink);}

  /* CC-W68 (6) — a forward arrow in the Proceed button.
     ⭐ THE SAME CHARACTER FAMILY AS THE BACK LINK'S "←" (U+2190 / U+2192), inheriting
        the label's weight and colour, rather than a second arrow style.
     ⚠ IT DISPLACES NOTHING: the button keeps its width, colour, shape and position, and
        the label simply re-centres — so "Proceed" sits slightly left of centre, which
        is what was asked for.
     📌 IT IS MARKUP, NOT A ::after, ON PURPOSE. #nav-next's label is rewritten by JS in
        four places ('Submit', 'Sending…', 'Submitting…'), and textContent replaces the
        span — so the arrow disappears exactly when the button stops saying Proceed,
        which is the behaviour you want. A pseudo-element would have survived and put a
        forward arrow on "Sending…". */
  .btn-arrow{margin-left:.45em;}


  /* CC-W70 (1) — THE SECOND, NON-COLOUR CUE ON A SELECTED PILL, PAINT ONLY.
     🚫 NOT font-weight. A heavier face widens the label, and CC-W69 measured
        that widening tipping two groups into a reflow on TAP: the consultation
        gate jumped 18px at 344px and the services group jumped 50px at 320px.
     ⭐ A zero-blur offset pair thickens the strokes without touching layout,
        because text-shadow is a paint-only property. Measured by rendering the
        label and counting ink:
            real font-weight 600   +23.6% ink   mid-tone fraction 0.171
            THIS (.2px offsets)    +33.7% ink   mid-tone fraction 0.165
            plain 400 (reference)       —       mid-tone fraction 0.203
        So it is HEAVIER than the bold we wanted and has FEWER soft edge pixels
        than the plain label — thicker and crisper, not smeared.
     🚫 A BLURRED shadow was rejected on the same measurement: 0 0 .35px twice
        gave less thickening (+30.3%) and pushed mid-tones to 0.278, i.e. it
        muddied the label. Do not "simplify" this back to a blur.
     🚫 .choice.selected ONLY — the availability calendar and the Instagram
        pill are untouched, asserted byte-identical at build time. */
  .choice.selected{text-shadow:.2px 0 currentColor,-.2px 0 currentColor;}

  /* CC-W70 (2) — HEADROOM FOR THE CONSULTATION PILL.
     "Book a consultation — $200" measured 218.02px inside a 219.06px row at
     344px: 1.04px of slack, with no bold involved. A device rendering the face
     a hair wider already wraps it. This is the most consequential control on
     the page, so it should not sit on a rounding error.
     🚫 THE WORDS ARE UNCHANGED. This buys room by narrowing the pill's own side
        padding on small screens only, which is the smallest lever that helps:
        it leaves the page gutters, the type, the fill and the row alone.
     ⚠ THE REAL CONSTRAINT IS ELSEWHERE AND IS NOT TOUCHED HERE: .page-body
       carries 13% horizontal padding, so at 344px a 296px body becomes a 219px
       row — 26% of the width spent on gutters. Relaxing that is the big lever
       and would change every screen's margins, so it needs Brandon's eyes
       rather than a quiet edit. */
  @media (max-width:420px){
    .gate-choice .choice{padding-left:12px;padding-right:12px;}
  }


  /* CC-W56/57: the site footer + the top policy links. The footer is a sibling of
     .wrap, so the art-nouveau frame is untouched; body is already a centring flex
     column, so both centre with the card. */
  .legal-links-top{margin:20px 0 30px;text-align:center;font-family:Fraunces,serif;
    font-size:13px;color:var(--mute);}
  .legal-links-top a{display:inline-block;padding:10px 4px;color:var(--moss);
    text-decoration:underline;text-decoration-color:var(--lime);text-underline-offset:2px;}
  .legal-links-top .sep{color:var(--line);padding:0 8px;}
  .site-footer{width:100%;max-width:640px;margin:34px auto 0;padding:0 24px;
    box-sizing:border-box;text-align:center;font-family:Fraunces,serif;
    font-size:13px;line-height:2;color:var(--mute);}
  .site-footer .fname{font-family:'IM Fell English SC',serif;font-size:15px;
    letter-spacing:.06em;color:var(--moss);}
  .site-footer a{color:var(--moss);text-decoration:underline;
    text-decoration-color:var(--lime);text-underline-offset:2px;}
  .site-footer .sep{color:var(--line);padding:0 8px;}
  .site-footer .hours{font-size:13px;color:var(--mute);}
  /* the Instagram invitation: a real tap target, in the page's own palette.
     🚫 deliberately NOT Instagram's brand gradient. */
  .site-footer .ig-row{margin:10px 0 4px;line-height:1;}
  .site-footer .ig-link{display:inline-flex;align-items:center;gap:10px;min-height:44px;
    padding:11px 20px;border:1px solid var(--line);border-radius:999px;
    color:var(--moss);text-decoration:none;font-size:14px;letter-spacing:.01em;
    transition:background .18s ease,border-color .18s ease;}
  .site-footer .ig-link:hover,.site-footer .ig-link:focus-visible{
    background:var(--paper-dim);border-color:var(--moss);}
  .site-footer .ig-link svg{width:19px;height:19px;flex:none;}
  @media (max-width:460px){.site-footer .sep{display:none;}
    .site-footer .pair a{display:block;}}

/* ===== CC-W87: the site nav, the Start buttons, and the marketing pages ===== */
/* ⭐ START IS THE ONLY LIME BUTTON IN THE HEADER, on every page that has a nav.
   The questionnaire has no nav at all - once someone is answering, a menu is an
   invitation to wander off mid-form. Its way back is the logo, which links home
   on every page. */
.site-nav{display:flex;flex-wrap:wrap;justify-content:center;align-items:center;
  gap:6px 18px;margin:0 0 26px;}
.site-nav a{font-family:Fraunces,serif;font-size:15px;color:var(--ink-soft);
  text-decoration:none;padding:8px 2px;min-height:44px;display:inline-flex;
  align-items:center;border-bottom:1px solid transparent;}
.site-nav a:hover,.site-nav a:focus-visible{color:var(--ink);
  border-bottom-color:var(--lime-deep);}
.site-nav a[aria-current="page"]{color:var(--ink);border-bottom-color:var(--ink);}
/* 🗃 .nav-start's rules were here. Removed CC-W90 with the button itself:
   every marketing page ends with Get Started, so the menu pill was a second
   route to the same place. Deleted rather than left dangling — an unreferenced
   rule for a removed control is the next reader's wild goose chase. */
.brand-logo-link{display:block;line-height:0;}
.brand-logo-link img{width:176px;height:auto;margin-bottom:18px;}
/* the marketing pages reuse the card, but NOT .section - that class is the
   questionnaire's step machinery and is display:none by default. */
.page-lead{margin:0 0 26px;}
.page-title{font-family:Fraunces,serif;font-weight:450;font-size:26px;
  margin:0 0 14px;color:var(--ink);}
.start-row{display:flex;justify-content:center;margin:34px 0 8px;}

/* ===== CC-W87: the gallery (CC-W85's rules, unchanged in behaviour) =====
   ⚠⚠ COLUMNS, NOT A GRID, AND THAT IS THE LAYOUT DECISION. The seven are four
      different shapes. A grid row is as tall as its tallest item, so a landscape
      beside a portrait leaves dead space under it, and the only way to make a grid
      tidy is to crop everything to one box - which throws away the composition each
      photograph was chosen for. Columns flow instead of aligning: no cropping, no
      forced aspect ratio, no ragged gaps.
   ⚠ THE COST: column flow reads DOWN then ACROSS. With no captions and no required
     order that is fine; it would not be if these had to be read in sequence.
   ⭐ column-count is 1 until 560px because the content column is 242px on a 375px
      phone - two columns cannot fit there.
   📌 .gcap is kept and DELIBERATELY UNUSED. Brandon has written no captions and none
      may be invented, so the slot exists and every figure leaves it empty. */
.gallery{margin:10px 0 30px;}
.gallery-grid{column-count:1;column-gap:14px;}
@media (min-width:560px){.gallery-grid{column-count:2;}}
.gallery figure{margin:0 0 14px;break-inside:avoid;-webkit-column-break-inside:avoid;}
.gallery img{display:block;width:100%;height:auto;border-radius:2px;
  background:var(--paper-dim);}
.gallery .gcap{margin-top:8px;font-family:Fraunces,serif;font-size:13px;
  color:var(--mute);line-height:1.5;}

/* ===== CC-W88: the marketing call to action =====
   🔴 THE UNDERLINE WAS A DEFECT, NOT A CHOICE. .btn-primary was written for a
      <button>, which never underlines its label. The marketing CTA is an <a>
      going to another page, so the browser's default link underline showed
      straight through the button face. Fixed HERE, on the class, so any anchor
      that ever uses .btn-primary is covered — not patched per instance.
   📌 The header's Start needed nothing: .site-nav a already sets
      text-decoration:none. Measured on the draft before changing anything —
      it read "none" there and "underline" on the bottom CTA. */
a.btn-primary{text-decoration:none;}

/* ===== CC-W89: click a photograph to see it large. /work/ only. =====
   🔴 NOTHING THAT HAS TO BE SEEN IS ANIMATED FROM INVISIBLE, AND THAT COST TWO
      ATTEMPTS TO GET RIGHT. First a transition from opacity:0, then an
      animation from opacity:0 — and MEASURED IN A HIDDEN PANE BOTH SAT AT
      ZERO, for the full 1.2s the probe watched, because a hidden document does
      not advance either one. The viewer was then a black rectangle covering
      and blocking the page. The motion is now a 1.5% scale: if it never runs,
      the photograph is at scale 0.985, which nobody can tell from 1. The rule
      that falls out is general — animate something whose UNPLAYED state is
      still correct, never opacity on the thing the user came to look at.
   ⭐ SMALL IN THE GRID, LARGE ONLY ON DEMAND. The grid keeps the 1000px copies;
      the 1600px copy is fetched when somebody opens one. Browsing costs exactly
      what it did before this existed.
   ⭐ AND IT OPENS ON THE COPY ALREADY IN THE CACHE — the one just tapped — so
      there is never a blank screen, which is the failure that reads as broken.
      "Loading…" shows only if the large copy is slower than 600ms.
   ⚠ THE BACKDROP IS 0.97, NOT 0.94. At 0.94 the grid ghosted through clearly
     enough that I read my own screenshot as a bug — I thought the overlay had
     failed to cover the page, and only sampling the pixels showed it had. If it
     fooled the person who built it, it reads as a rendering fault to everyone
     else. 3% keeps the hint of an overlay without the distraction.
   ⚠ NO CROPPING. object-fit:contain with a max in BOTH axes, because the seven
     are four different shapes — three portrait, three landscape and one 9:16.
     A fixed box would crop whichever axis it did not fit.
   ⚠ THE ARROWS ARE FOR A MOUSE. Hidden by default and shown only under
     (hover:hover) and (pointer:fine); a touch device swipes, as the client
     gallery does. */
.gphoto{display:block;width:100%;padding:0;border:0;background:none;
  font:inherit;color:inherit;cursor:zoom-in;border-radius:var(--radius);
  -webkit-appearance:none;appearance:none;}
.gphoto:focus-visible{outline:2px solid var(--moss);outline-offset:3px;}
.gphoto img{transition:opacity .18s ease;}
@media (hover:hover){.gphoto:hover img{opacity:.86;}}

html.lb-locked,html.lb-locked body{overflow:hidden;}

.lightbox{position:fixed;inset:0;z-index:80;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:16px;padding:18px;
  background:rgba(24,22,15,0.97);overscroll-behavior:contain;touch-action:none;}
.lightbox[hidden]{display:none;}
@keyframes lb-in{from{transform:scale(0.985);}}

.lb-stage{margin:0;position:relative;flex:1 1 auto;min-height:0;
  display:flex;align-items:center;justify-content:center;}
.lb-img{display:block;width:auto;height:auto;max-width:92vw;max-height:78vh;
  object-fit:contain;border-radius:var(--radius);background:var(--paper-dim);
  touch-action:pinch-zoom;animation:lb-in .22s ease;}
.lb-wait{position:absolute;margin:0;font-family:Fraunces,serif;font-size:13px;
  letter-spacing:.06em;color:rgba(251,250,247,0.85);
  background:rgba(24,22,15,0.55);padding:6px 12px;border-radius:var(--radius);}
.lb-wait[hidden]{display:none;}
.lb-pos{margin:0;flex:0 0 auto;font-family:Fraunces,serif;font-size:13px;
  letter-spacing:.10em;color:rgba(251,250,247,0.70);}

.lb-btn{position:absolute;padding:0;cursor:pointer;font-family:Fraunces,serif;
  line-height:1;display:flex;align-items:center;justify-content:center;
  color:var(--paper);background:rgba(251,250,247,0.10);
  border:1px solid rgba(251,250,247,0.28);border-radius:var(--radius);
  -webkit-appearance:none;appearance:none;}
.lb-btn:focus-visible{outline:2px solid var(--lime);outline-offset:2px;}
.lb-btn[disabled]{opacity:.25;cursor:default;}
@media (hover:hover){.lb-btn:not([disabled]):hover{background:rgba(251,250,247,0.20);}}
.lb-close{top:14px;right:14px;width:44px;height:44px;font-size:24px;}
.lb-prev,.lb-next{display:none;top:50%;transform:translateY(-50%);
  width:44px;height:66px;font-size:28px;}
.lb-prev{left:12px;}
.lb-next{right:12px;}
@media (hover:hover) and (pointer:fine){.lb-prev,.lb-next{display:flex;}}


/* ===== THE REDUCED-MOTION BLOCK LIVES AT THE END, AND THAT IS THE FIX =====
   🔴 IT WAS AT LINE 844 AND IT DID NOT WORK ON THE VIEWER. A media query adds
      NO SPECIFICITY, so .lb-img{animation:lb-in} — written later in the file —
      simply won, and someone with the setting on still got the animation.
      MEASURED, not reasoned: a headless probe with --force-prefers-reduced-motion
      reported animationName "lb-in" in both the normal and the reduced run.
   ⭐ Moved to the end, where an override layer belongs. It is still ONE block —
      the file has only ever had one — and it still covers .section.active,
      because the only two animations in this stylesheet are fadeIn (line ~341)
      and lb-in (~1024) and this now sits after both. Checked by enumerating
      every animation and @keyframes declaration in the file, not by assuming.
   📌 THE GENERAL FORM, worth keeping: putting a rule inside @media does not make
      it stronger. "Extend the existing block" is only true if the block can
      still reach what you added to it. */
  /* CC-W75 — THE STEP FADE JOINS THE REDUCED-MOTION RULE.
   `.section.active` runs `fadeIn 0.35s ease` on EVERY step change, forward and
   back — the same frequency as the wipe, the same full-screen motion, the same
   people affected. Suppressing one and keeping the other was half a job.
   ✅ THE REVEAL IS NOT CARRIED BY THE ANIMATION, WHICH IS WHY THIS IS SAFE:
      `.section` is `display:none` and `.section.active` is `display:block`,
      so the step is shown by the DISPLAY change. fadeIn only adds opacity
      0->1 and a 6px rise on top. Turning it off leaves display:block, opacity
      at its initial 1 and no transform — visible, just not animated. Removing
      an animation that also carried the reveal is the classic way to ship a
      blank screen; this one does not, and it is asserted both ways below.
   🚫 NOTHING CHANGES WITHOUT THE SETTING. @keyframes fadeIn and the
      `.section.active` rule itself are untouched; this only overrides it
      inside the media query.
   📌 AND IT STOPS HERE. The button, choice, avail-cell, upload-zone,
      progress-fill and ig-link transitions are small local control feedback
      and stay — reduced motion is about vestibular triggers, not about
      stripping every transition off the page. */
@media (prefers-reduced-motion: reduce){
  .section.active{animation:none;}
  /* CC-W89: and the viewer opens and moves without the fade. The JS reads the
     same media query, so its "a move is running" hold becomes 0ms to match —
     one mechanism, not two that can disagree. */
  .lb-img{animation:none;}
}

/* ===== CC-W90: the exit link, and the menu that lost its Start =====
   ⭐ IT SITS UNDER THE PAGE NUMBERS, AT THE TOP — which is also what keeps it
      away from Proceed. Proceed is a lime pill at the BOTTOM of the page; this
      is 12px muted text at the top. They are never in the same glance, so the
      brief's "must not compete with Proceed" is answered by position, not by
      making the link so faint nobody finds it.
   ⚠ THE TAP TARGET IS 10px OF PADDING AROUND 12px TEXT, deliberately modest —
     and it is the CONFIRM, not the size, that protects a half-filled form. A
     target small enough to be safe from a mis-tap would be too small to use. */
.exit-row{margin:-9px 0 9px;text-align:center;}
/* ⚠⚠ CC-W93: THE PADDING GREW WHEN THE WORD SHRANK, ON PURPOSE. "Exit
      questionnaire" was 139x31 — modest, but wide enough that the width was
      never the problem. "Exit" is four characters, and at the old padding the
      target would have collapsed to roughly 48x31: still over WCAG 2.5.8's
      24x24 floor, but a small thing to hit on a moving bus.
   ⭐ PADDING, NOT A BIGGER FONT — Brandon's instruction, and the right one: the
      link has to stay visually quiet at 12px so it reads as a way out rather
      than as a control. The target grows; the ink does not.
   📌 IT CAN AFFORD TO BE GENEROUS BECAUSE NOTHING ELSE IS NEAR IT. It sits alone
      in a centred row; the policy links are ~50px below and Proceed is thousands
      of pixels down the page. A wide target here cannot steal a tap from another
      control — and the confirm still catches the one it might steal from
      nobody. */
.exit-link{display:inline-block;padding:15px 26px;font-family:Fraunces,serif;
  font-size:12px;letter-spacing:.05em;color:var(--mute);
  text-decoration:underline;text-decoration-color:var(--line);
  text-underline-offset:3px;}
.exit-link:hover,.exit-link:focus-visible{color:var(--ink-soft);
  text-decoration-color:var(--mute);}

/* ===== CC-W92: the questionnaire's title =====
   ⭐ IT IS A REAL <h1>, AND THE SCREENS YOU FILL IN HAD NONE — which is
      exactly what Brandon noticed. Checked rather than assumed: the page did
      already carry two h1s, but BOTH are on the END screens, "We've got
      everything we need for now" and "Thanks for your time", and both are
      display:none until you finish. So every screen a person actually reads
      had a wordmark, a progress bar and a question, and nothing saying what the
      page WAS. This is a document-structure fix as much as a visual one.
   ⭐ ONE PLACE, THREE SCREENS. It lives in the form's chrome above the three
      sections, so it appears on every page of the form by construction. It is
      not written three times and cannot drift between them.
   ⚠ FRAUNCES AT 22px, NOT THE .eyebrow FACE. The eyebrow (IM Fell English SC,
     16px, moss) is used repeatedly INSIDE the form for section headings —
     "Before We Begin", "Our Hourly Rates". Borrowing it would have made the
     page's title read as one more section heading. Fraunces in ink is the
     language the site already uses for a page title, so this reads as the same
     class of thing as "Our Work", one size down for a denser stack.
   📌 The hierarchy it slots into, measured: wordmark 28 > THIS 22 > eyebrow 16
      > page counter 14 > exit link 12. */
.form-title{font-family:Fraunces,serif;font-weight:450;font-size:22px;
  line-height:1.25;letter-spacing:.01em;color:var(--ink);text-align:center;
  margin:0 0 12px;}
