/* ==========================================================================
   Dactyl Websites — the home page on a phone (October 2026, mobile redesign)

   Loaded only below 820px (index.html, media attribute), so nothing here can
   reach the desktop layout. It sits over home.css.

     The index       the five questions as a list of jumps, each with its
                     feature icon, under "Before deciding".
     The chapters    the five questions, each with one picture that shows
                     its answer, and no two laid out alike:
                       1  linen   question, phone, answer
                       2  linen   search result and AI answer, then question
                       3  umber   a full-width band: the usual form beside
                                  the Smart Form stepping through itself
                       4  sand    three example tiles, then question
                       5  linen   a month on Pro
                     3, 4 and 5 are sheets: each comes up over the one before
                     with the panel radius on its leading corners.
     Read more       the answer's headline and first lines; the rest opens
                     under a button (asks.js).
     The locals      one full-width photograph, held while its line scrolls
                     up over it; John's section rises over it after.
     The price card  the question and the price on one umber card.

   The pictures, Read more and the deed live in asks-shared.css (loaded
   at every width, after this file), so the wide layout uses them too.

   Motion (asks.js) waits for html.asks-motion, so with no script, or with
   reduced motion, every picture is simply there in its finished state.

   Contrast, measured: ink-2 on linen 9.6:1, on sand 8.4:1, on white 10.3:1;
   accent-ink on linen 5.33:1, sand 4.62:1, white 5.9:1; ivory on umber
   15.6:1; white 75% on umber 9.2:1; accent-lit-ink on umber 6.3:1.
   ========================================================================== */

/* Hidden until this stylesheet shows them (home.css hides them for wide
   screens). */
.qindex, .ask__vis, .locals, .ask__toggle { display: block; }

/* ------------------------------------------------------------ Before deciding */
.asks { padding: 5rem 0 0; }
.asks__copy { display: none; }

/* ---------------------------------------------------------------- The deck
   The five questions as tall photo cards, one local trade each, in a row
   that runs to the screen's edges with the next card peeking in. A rail
   under it fills as it moves. Ordinarily a swipeable row with the browser's
   own snapping; while it holds the screen on the first pass (asks.js adds
   is-pinned and the section's height), the scroll moves it instead, so the
   snapping is off. Ivory on the cards' foot shade 11:1. */
/* A long breath under the deck before the first question's sheet. */
.qdeck { position: relative; margin: 2.4rem 0 9.5rem; }
.qdeck.is-pinned .qdeck__pin { position: sticky; top: var(--pin-top, 18svh); }
.qdeck__track {
  display: flex;
  gap: .7rem;
  margin: 0 calc(var(--gutter) * -1);
  padding: 0 var(--gutter) .2rem;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scroll-snap-type: x mandatory;
  scroll-padding-left: var(--gutter);
  scrollbar-width: none;
  -webkit-overflow-scrolling: touch;
}
.qdeck__track::-webkit-scrollbar { display: none; }
.qdeck.is-pinned .qdeck__track { scroll-snap-type: none; }
.qcard {
  position: relative;
  flex: 0 0 72%;
  aspect-ratio: 3 / 4;
  overflow: hidden;
  border-radius: 22px;
  scroll-snap-align: start;
  background: var(--umber);
  color: var(--ivory);
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
}
main .qdeck a.qcard { color: var(--ivory); }
.qcard img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; transition: transform 1.1s var(--glide); }
.qcard:active img { transform: scale(1.05); }
.qcard::after {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(rgba(9, 9, 9, .08) 28%, rgba(9, 9, 9, .85));
}
.qcard__n {
  position: absolute;
  top: .9rem;
  left: 1rem;
  z-index: 1;
  font-family: var(--display);
  font-size: 2.6rem;
  font-weight: 300;
  line-height: 1;
  text-shadow: 0 2px 16px rgba(9, 9, 9, .4);
}
.qcard__t {
  position: absolute;
  left: 1rem;
  right: 1rem;
  bottom: 1.6rem;
  z-index: 1;
  font-family: var(--display);
  font-size: 1.42rem;
  line-height: 1.12;
  letter-spacing: -.012em;
  text-wrap: balance;
}
.qcard__t small {
  display: block;
  margin-top: .55rem;
  font-family: var(--sans);
  font-size: .78rem;
  font-weight: 600;
  letter-spacing: .02em;
  color: var(--accent-lit-ink);
}
.qdeck__rail { height: 2px; margin-top: 1.1rem; overflow: hidden; border-radius: 2px; background: var(--hair-2); }
.qdeck__rail i { display: block; width: 100%; height: 100%; background: var(--accent); transform: scaleX(.2); transform-origin: left center; }
/* The cards come up one after another as the deck arrives. */
.asks-motion .qcard { opacity: 0; transform: translateY(24px); transition: opacity .7s var(--ease), transform 1s var(--glide); }
.asks-motion .qdeck.is-in .qcard { opacity: 1; transform: none; }
.asks-motion .qdeck.is-in .qcard:nth-child(2) { transition-delay: .08s; }
.asks-motion .qdeck.is-in .qcard:nth-child(3) { transition-delay: .16s; }

/* ------------------------------------------------------------ The chapters
   Every question is a sheet of its own: full width, its own surface, and
   it comes up over the one before with the panel radius and a soft shadow
   on its leading edge, so where one question ends and the next begins is
   never in doubt. Surfaces in turn: sand, linen, umber, sand, linen.
   Inside, always the same order: the question, its picture, our answer. */
.asks__list { gap: 0; margin: 3.25rem 0 0; }
.ask {
  --sheet: var(--linen);
  position: relative;
  display: flex;
  flex-direction: column;
  margin: calc(var(--r-xl) * -1) calc(var(--gutter) * -1) 0;
  padding: 3.6rem var(--gutter) calc(5rem + var(--r-xl));
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  background: var(--sheet);
  box-shadow: 0 -1px 0 rgba(40, 24, 8, .05), 0 -26px 44px -34px rgba(40, 24, 8, .45);
  scroll-margin-top: 0;
}
.ask:first-child { margin-top: 0; }
.ask:last-child { padding-bottom: 5.5rem; }
.ask:nth-child(1) { z-index: 1; --sheet: var(--sand); }
.ask:nth-child(2) { z-index: 2; }
.ask:nth-child(3) { z-index: 3; }
.ask:nth-child(4) { z-index: 4; --sheet: var(--sand); }
.ask:nth-child(5) { z-index: 5; }
.ask__head { order: 1; }
.ask__vis { order: 2; }
.ask__a { order: 3; }

/* The opener: the number set large in the serif, and beside it, on a rule
   that runs to the edge, "Question 2 of 5". The first thing on every
   sheet, so a new question announces itself before anything else. */
.ask .ask__n {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  align-items: end;
  column-gap: .85rem;
  margin: 0 0 1.5rem;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .14em;
  line-height: 1;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.ask__n-big {
  display: block;
  font-family: var(--display);
  font-size: clamp(4.4rem, 21vw, 5.6rem);
  font-weight: 300;
  font-style: normal;
  line-height: .74;
  letter-spacing: -.05em;
  text-transform: none;
  color: var(--accent);                   /* a large mark: 3.6 on sand */
  font-variant-numeric: lining-nums;
}
.ask__n-k {
  display: block;
  padding-bottom: .6rem;
  border-bottom: 1px solid var(--hair-2);
}
.ask__n-of { display: inline; color: var(--ink-3); }
.ask__q {
  font-size: clamp(1.85rem, 8.4vw, 2.4rem);
  line-height: 1.1;
  letter-spacing: -.024em;
}

/* Our answer. It is the payoff, so it is marked as ours: a short terracotta
   rule and a label, as the enquiry email sets its own, the headline in ink a size under the
   question (the question stays the largest thing on the sheet), and what
   it comes with as a pill straight under it. The body stays quiet. */
.ask__a.panel {
  display: flex;
  flex-direction: column;
  margin-top: 2.6rem;
  padding: 0;
  background: none;
  border-radius: 0;
}
.ask__a.panel::before {
  content: "Our answer";
  order: 0;
  margin: 0 0 .75rem;
  padding-left: 2rem;
  background: linear-gradient(var(--accent), var(--accent)) 0 50% / 1.4rem 1.5px no-repeat;
  font-family: var(--mono);
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent-ink);
}
.ask__ans {
  order: 1;
  margin: 0;
  padding: 0;
  border: 0;
  font-size: clamp(1.5rem, 6.6vw, 1.8rem);
  font-weight: 500;
  line-height: 1.16;
  letter-spacing: -.022em;
  color: var(--ink);
}
.ask__a > .ask__tag,
.ask__a > .ask__tags { order: 2; }
.ask__tags { display: flex; flex-wrap: wrap; gap: .45rem; margin-top: 1rem; }
.ask__tags .ask__tag { margin: 0; }
.ask__a > .ask__body { order: 3; margin-top: 1.6rem; }
.ask__a > .ask__toggle { order: 4; }
.ask__body { gap: 1.35rem; }
.ask__body p { font-size: 1.0625rem; line-height: 1.62; }
.ask__body a { color: var(--accent-ink); }

/* What it comes with: a pill, not a line under a rule, so it reads as
   part of the answer. A step off the sheet's own surface. */
.ask__tag {
  align-self: flex-start;
  align-items: center;
  gap: .5rem;
  margin: 1rem 0 0;
  padding: .5rem .85rem .5rem .6rem;
  border: 0;
  border-radius: 14px;
  font-family: var(--sans);
  font-size: .86rem;
  font-style: normal;
  font-weight: 500;
  line-height: 1.35;
  color: var(--ink-2);
}
.ask__tag { background: var(--sand); }
.ask:nth-child(1) .ask__tag,
.ask:nth-child(4) .ask__tag { background: var(--linen); }
.ask__tag .ask__tick { width: 1.15rem; height: 1.15rem; margin-top: 0; }

/* ====================================================== 3  The Smart Form
   A full-width umber band, the page's one dark chapter before the price.
   The usual form, small, tilted and dim, with its one vague message; and
   over it the Smart Form, on the page's linen, stepping through a
   plumber's questions by itself and ending as the email the business
   gets (asks.js). Measured on umber: ivory 15.6:1, white 75% 9.2:1,
   white 62% 6.4:1, accent-lit-ink 6.3:1. */
.ask.ask--form {
  background:
    radial-gradient(120% 60% at 50% 0%, var(--umber-lamp) 0%, rgba(30, 30, 30, 0) 70%),
    linear-gradient(to bottom, var(--umber) 0%, var(--umber-deep) 100%);
  color: var(--ivory);
}
.ask--form .ask__n { color: var(--accent-lit-ink); }
.ask--form .ask__n-big { color: var(--accent-lit); }
.ask--form .ask__n-k { border-bottom-color: rgba(255, 255, 255, .18); }
.ask--form .ask__n-of { color: var(--on-navy-2); }
.ask--form .ask__a.panel::before {
  color: var(--accent-lit-ink);
  background-image: linear-gradient(var(--accent-lit), var(--accent-lit));
}
.ask--form .ask__q { color: var(--ivory); }
.ask--form .ask__ans { color: var(--ivory); }
.ask--form .ask__body p { color: var(--on-navy); }
.ask--form .ask__body a { color: var(--accent-lit-ink); }
.ask--form .ask__tag { background: rgba(255, 255, 255, .08); color: var(--ivory); }
.ask--form .ask__tick { stroke: var(--accent-lit); }
.ask--form .ask__toggle { color: var(--ivory); }

/* ===================================================== 4  How it's going
   A sand sheet over the umber. Three tiles, labelled as an example: the
   enquiries across the top on ink (the one dark tile), calls and emails
   under it on linen. Two columns, the wide tile spanning both: 2 + 1 + 1
   cells, two full rows, nothing left over. The figures count up from
   nought once (asks.js); they are counts, not prices. */
.ask--pulse .ask__body p,
.ask--pulse .ticks li { color: var(--ink-2); }
/* ============================================================== The locals
   The three businesses as a film: the section is a screen and most of
   another tall, and the picture and its line hold the screen (sticky)
   while the scroll runs the film (film.js; the still under it until the
   frames arrive). The scrim deepens to solid umber at the foot, so the
   film ends in the same dark that John's photograph opens out of: one dark
   passage from the businesses to the person who builds for them, with no
   pale strip between. Ivory on the scrim measures 9:1 or better where the
   words sit. */
.locals {
  position: relative;
  height: 185vh;
  height: 185svh;
  background: var(--umber-deep);
}
.locals__pin {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}
.locals__photo { position: absolute; inset: 0; transform-origin: 50% 40%; }
.locals__photo img,
.locals__film {
  position: absolute;
  inset: 0;
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}
.locals__film { opacity: 0; transition: opacity .8s var(--ease); pointer-events: none; }
.locals__film.is-on { opacity: 1; }
.locals__photo::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to bottom,
      rgba(9, 9, 9, .32) 0%,
      rgba(9, 9, 9, 0) 16%,
      rgba(9, 9, 9, .1) 40%,
      rgba(9, 9, 9, .7) 66%,
      rgba(9, 9, 9, .94) 88%,
      var(--umber-deep) 100%);
  pointer-events: none;
}
.locals__copy {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 11svh;
  z-index: 2;
}
.locals__h {
  margin: 0 0 1.1rem;
  font-size: clamp(3rem, 15vw, 4.2rem);
  font-weight: 400;
  line-height: .96;
  letter-spacing: -.032em;
  color: var(--ivory);
  text-shadow: 0 2px 30px rgba(9, 9, 9, .45);
}
.locals__h em { font-style: italic; color: var(--accent-lit); }
.locals__p {
  max-width: 21rem;
  margin: 0;
  font-size: 1.08rem;
  line-height: 1.55;
  color: rgba(255, 249, 240, .9);
  text-shadow: 0 1px 16px rgba(9, 9, 9, .5);
  text-wrap: pretty;
}

/* ==================================================================== John
   The photograph opens out of the umber the film ended on (home.js, JOHN,
   unchanged: from an inset frame to the full width): the umber runs behind
   it, exactly its height. Then the rest of John's section comes up over
   the photograph's foot as a linen sheet. */
.john { position: relative; padding: 0 0 4rem; background: var(--linen); }
.john::before {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 125vw;                          /* the photo: full width, 4:5 */
  background: var(--umber-deep);
}
.john__in { position: relative; z-index: 1; }
/* While the photograph loads, its frame is the same umber, never a pale
   sand box with the monogram on it. */
.john__photo { background: var(--umber); }
.john__mono { color: rgba(255, 255, 255, .06); }
.john__copy > .john__h { margin-bottom: 4.4rem; }
.john__body {
  position: relative;
  z-index: 3;
  margin: calc(var(--r-xl) * -1) calc(var(--gutter) * -1) 0;
  padding: 4rem var(--gutter) 0;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  background: var(--linen);
}

.john__own {
  margin-top: 3.8rem;
  padding: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}
/* ========================================================== The price band
   No stage on a phone (ui.js, priceStage, stands down for data-phone-card)
   and no card: the price is a full-width umber band that comes up over the
   linen as a sheet, with the question, the price, what websites usually
   cost and the line into the packages, in that order, so the $2,500 is on
   the same screen as the question. The packages come back up over it on
   linen, the same way. */
.pricing[data-phone-card] { padding: 3.5rem 0 4.5rem; }
.pricing[data-phone-card] .price-run { height: auto; }
.pricing[data-phone-card] .price-stage {
  position: relative;
  padding: 3.6rem var(--gutter) calc(3rem + var(--r-xl));
  overflow: hidden;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  background:
    radial-gradient(110% 55% at 18% 0%, var(--umber-lamp) 0%, rgba(30, 30, 30, 0) 70%),
    linear-gradient(to bottom, var(--umber) 0%, var(--umber-deep) 100%);
  color: var(--ivory);
  box-shadow: 0 -26px 44px -34px rgba(20, 17, 13, .45);
}
.pricing[data-phone-card] .price-stage .wrap { padding-inline: 0; }
.pricing[data-phone-card] .price-stage__q { text-align: left; }
.pricing[data-phone-card] .price-stage__q .display {
  font-size: clamp(2.2rem, 10vw, 2.8rem);
  font-weight: 400;
  line-height: 1.04;
  letter-spacing: -.026em;
  color: var(--ivory);
}
.pricing[data-phone-card] .price-stage__fit { display: flex; flex-direction: column; }
.pricing[data-phone-card] .price.panel--dark {
  order: 1;
  margin: 2.8rem 0 0;
  padding: 0;
  background: none;
  border-radius: 0;
}
.pricing[data-phone-card] .price__fig { color: var(--ivory); }
.pricing[data-phone-card] .price__for { color: var(--ivory); }
.pricing[data-phone-card] .price__note { color: var(--on-navy); }
/* What websites usually cost comes first, so $2,500 is read against it:
   the sentence, the range set large, then the one price. */
.pricing[data-phone-card] .price-stage__eyebrow.price__ctx {
  order: 0;
  max-width: none;
  margin: 1.6rem 0 0;
  font-size: 1rem;
  text-align: left;
  color: var(--on-navy);
}
.pricing[data-phone-card] .price__ctx > span { display: block; }
.pricing[data-phone-card] .price__lead {
  font-family: var(--display);
  font-size: 1.22rem;
  line-height: 1.36;
  letter-spacing: -.01em;
  text-wrap: pretty;
}
.pricing[data-phone-card] .price__range {
  margin-top: .5rem;
  font-family: var(--display);
  font-size: clamp(2.3rem, 11vw, 2.9rem);
  line-height: 1.05;
  letter-spacing: -.03em;
  color: var(--ivory);
  font-variant-numeric: tabular-nums;
  transition: color .8s var(--ease);
}
.pricing[data-phone-card] .price__to { font-family: var(--sans); font-size: .38em; letter-spacing: 0; color: var(--on-navy); vertical-align: .35em; }
.pricing[data-phone-card] .price__stop { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
.pricing[data-phone-card] .price__tail { margin-top: 1rem; font-size: 1.05rem; line-height: 1.5; color: var(--ivory); }
.pricing[data-phone-card] .price__guide { margin-top: 1rem; font-size: .9rem; line-height: 1.5; color: var(--on-navy-2); }
.pricing[data-phone-card] .price__ctx a { color: var(--accent-lit-ink); }
/* Once it has been read the range steps back to the body copy's tone
   (white 62%, 6.41:1 at the lamp) and the price comes in. */
.pricing[data-phone-card].is-read .price__range { color: var(--on-navy-2); }

/* The reading (asks.js, PRICE): each word lights from 30% as the scroll
   reaches it. Dim words are a passing state; every word ends at full
   contrast. Then the price arrives in parts: the figure out of its own
   window, what it buys, the rule drawn, the deposit, the line on. */
.asks-motion .pricing.is-reading .price__ctx .pw-r { opacity: .3; transition: opacity .35s var(--ease); }
.asks-motion .pricing.is-reading .price__ctx .pw-r.is-lit { opacity: 1; }
.asks-motion .pricing.is-reading .price__guide { opacity: 0; transition: opacity .6s var(--ease) .2s; }
.asks-motion .pricing.is-reading .price__fig,
.asks-motion .pricing.is-reading .price__for,
.asks-motion .pricing.is-reading .price__note,
.asks-motion .pricing.is-reading .price-stage__next {
  opacity: 0;
  transform: translateY(18px);
  transition: opacity .6s var(--ease), transform .9s var(--glide);
}
.asks-motion .pricing.is-reading .price__fig {
  clip-path: inset(0 0 100% 0);
  transform: translateY(40%);
  transition: clip-path .9s var(--glide) .25s, transform .9s var(--glide) .25s, opacity .2s linear .25s;
}
.asks-motion .pricing.is-reading .price__rule { transform: scaleX(0); transition: transform .7s var(--glide) .6s; }
.asks-motion .pricing.is-reading.is-read .price__guide { opacity: 1; }
.asks-motion .pricing.is-reading.is-read .price__fig { opacity: 1; clip-path: inset(-10% -5% -10% -5%); transform: none; }
.asks-motion .pricing.is-reading.is-read .price__for { opacity: 1; transform: none; transition-delay: .4s; }
.asks-motion .pricing.is-reading.is-read .price__rule { transform: scaleX(1); }
.asks-motion .pricing.is-reading.is-read .price__note { opacity: 1; transform: none; transition-delay: .7s; }
.asks-motion .pricing.is-reading.is-read .price-stage__next { opacity: 1; transform: none; transition-delay: .95s; }
.pricing.is-setting, .pricing.is-setting * { transition: none !important; }
.pricing[data-phone-card] .price-stage__next {
  order: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  margin-top: 2rem;
  text-align: left;
}
.pricing[data-phone-card] .plans__h {
  margin: 0;
  font-size: 1.45rem;
  font-weight: 400;
  line-height: 1.15;
  color: var(--ivory);
}
.pricing[data-phone-card] .price-stage__cue {
  display: block;
  flex: none;
  margin: 0;
  opacity: 1;
  color: var(--accent-lit);
  animation: wheel-nudge 1.8s var(--ease) infinite;
}

/* ============================================================ The packages
   Not a box: the table straight on the linen sheet, and Pro as a lane, its
   gold head running down into a pale gold column to the foot, so the eye
   reads down Pro and across to Essential. */
.pricing[data-phone-card] .plans {
  --lane: #f3e7cb;
  position: relative;
  z-index: 1;
  margin-top: calc(var(--r-xl) * -1);
  padding-top: 3rem;
  border-radius: var(--r-xl) var(--r-xl) 0 0;
  background: var(--linen);
}
/* The wide screen's three package cards (desk.css); a phone has the table. */
.dplans { display: none; }
.pricing[data-phone-card] .duo { padding: 0; border-radius: 0; background: none; }
.pricing[data-phone-card] .duo__table thead tr { margin-bottom: 0; }
.pricing[data-phone-card] .duo__table thead th { border-radius: 1.1rem; }
.pricing[data-phone-card] .duo__table thead .duo__pro { border-radius: 1.1rem 1.1rem 0 0; }
.pricing[data-phone-card] .duo__table tbody tr {
  background: linear-gradient(90deg, transparent calc(50% + .3rem), var(--lane) calc(50% + .3rem));
}
.pricing[data-phone-card] .duo__table tbody tr:first-child th { padding-top: 1.3rem; }
.pricing[data-phone-card] .duo__table tbody td:nth-child(3) { box-shadow: none; color: var(--ink); }
.pricing[data-phone-card] .duo__table tbody::after {
  content: "";
  display: block;
  height: 1.1rem;
  margin-left: calc(50% + .3rem);
  border-radius: 0 0 1.1rem 1.1rem;
  background: var(--lane);
}


@media (prefers-reduced-motion: reduce) {
  .pricing[data-phone-card] .price-stage__cue { animation: none; }
}
