/* ============================================================
   SERVICES · PRICING · ABOUT · CONTACT
   ============================================================ */

/* ------------------------------------------------------------
   SCROLL FOCUS
   js/focus.js writes --t on each line: 0 = you are reading this,
   1 = it is far from the reading line. Blur and fade follow.
   The filter lives on the line itself, never on a wrapper, so a
   whole block never blurs as one lump.
   ------------------------------------------------------------ */
.read {
  /* em, not ch: `ch` is measured from the font itself, so the column
     would resize the instant the webfont swapped in and reflow the
     whole page under the reader. */
  max-width: 18em;
  padding-block: clamp(0.5rem, 2vh, 1.5rem);
  font-size: clamp(1.3rem, 0.8rem + 2vw, 2.6rem);
  line-height: 1.14;
  letter-spacing: -0.015em;
  font-weight: 400;
}

.read__line {
  --t: 0;          /* sharp until JS says otherwise — never hide real copy */
  margin-bottom: 0.5em;
  filter: blur(calc(var(--t) * var(--t) * 7px));
  opacity: calc(1 - var(--t) * 0.76);
  will-change: filter, opacity;
}
.read__line:last-child { margin-bottom: 0; }

.read__line b {
  font-weight: 600;
  letter-spacing: -0.024em;
}

/* A list dropped into the reading flow: each item is its own
   .read__line, so it sharpens into focus individually as you scroll
   past it, exactly like a sentence would. */
.read__list {
  list-style: none;
  margin: 0 0 0.5em;
  padding: 0;
}
.read__list .read__line {
  position: relative;
  padding-left: 1.05em;
}
.read__list .read__line::before {
  content: "\2014";
  position: absolute;
  left: 0;
  top: 0;
  color: var(--hot);
}

.read__flag {
  --t: 0;
  font-family: var(--display);
  font-size: clamp(2.4rem, 1.4rem + 4.4vw, 5.6rem);
  line-height: 0.9;
  letter-spacing: 0.015em;
  text-transform: uppercase;
  margin-bottom: 0.28em;
  filter: blur(calc(var(--t) * var(--t) * 7px));
  opacity: calc(1 - var(--t) * 0.76);
}
.read__flag b { font-weight: 400; }

@media (prefers-reduced-motion: reduce) {
  .read__line, .read__flag { filter: none; opacity: 1; }
}


/* ------------------------------------------------------------
   ABOUT
   ------------------------------------------------------------ */
.quote {
  max-width: 16.5em;
  padding-block: clamp(0.5rem, 2vh, 1.5rem);
  font-size: clamp(1.3rem, 0.8rem + 2vw, 2.6rem);
  line-height: 1.14;
  letter-spacing: -0.015em;
}
.read__line--quote:first-child::before { content: "\201C"; margin-left: -0.42em; }
.read__line--quote:last-of-type::after  { content: "\201D"; }

.quote__by {
  --t: 0;
  display: block;
  filter: blur(calc(var(--t) * var(--t) * 7px));
  opacity: calc(1 - var(--t) * 0.76);
  margin-top: clamp(1.4rem, 2.6vw, 2.2rem);
  font-family: var(--mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-mid);
  text-transform: uppercase;
}
.quote__by::before {
  content: "";
  display: inline-block;
  vertical-align: middle;
  width: 34px; height: 1px;
  margin-right: 0.9rem;
  background: var(--hot);
}
.quote__by i { font-style: normal; color: var(--ink-faint); }
@media (prefers-reduced-motion: reduce) { .quote__by { filter: none; opacity: 1; } }

/* ------------------------------------------------------------
   REVIEWS
   ------------------------------------------------------------
   Two client quotes side by side on a wide screen, one under the
   other on a narrow one — auto-fit works fine here since there are
   only ever two of these (unlike the four pricing tickets, which
   need explicit column steps to avoid an orphaned row). Each card
   reuses .quote__by and the smart-quote
   marks from ABOUT rather than inventing its own attribution style,
   just at a size that lets two of these sit on a page together
   instead of the one big pull-quote About gets. */
.reviews {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr));
  gap: clamp(2.6rem, 5vw, 4.5rem) clamp(2.6rem, 6vw, 5.5rem);
  max-width: 1080px;
  margin-inline: auto;
}
.review { max-width: 30em; }
.review blockquote {
  font-size: clamp(1.05rem, 0.86rem + 0.7vw, 1.32rem);
  line-height: 1.42;
  letter-spacing: -0.012em;
}
.review .quote__by { margin-top: clamp(1.1rem, 2vw, 1.6rem); }

/* ------------------------------------------------------------
   PRICING
   ------------------------------------------------------------ */
.tickets {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(2.4rem, 5vw, 3rem) clamp(1.5rem, 4vw, 3rem);
  max-width: 640px;
  margin-inline: auto;
}
/* Explicit steps, not auto-fit: four items under auto-fit produce an
   ugly 3-then-1 orphan row across a chunk of the width range, since
   the browser packs as many min-width columns as fit with no idea
   there are exactly four. One column on a phone, a clean 2x2 once
   there's room, all four in a row once there's room for that too. */
@media (min-width: 560px) {
  .tickets { grid-template-columns: repeat(2, 1fr); max-width: 720px; }
}
@media (min-width: 980px) {
  .tickets { grid-template-columns: repeat(4, 1fr); max-width: 1080px; }
}

/* No panel, no card — a rule, a label and a very large number. The rule
   is the readout: it fills red, left to right, the moment the sum lands.
   (No backdrop-filter or transform here on purpose: a stacking context
   would cut the price text off from the page it inverts against.) */
.ticket {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  padding: clamp(1.4rem, 2vw, 2.1rem) clamp(1rem, 2vw, 2rem) clamp(1rem, 1.6vw, 1.6rem);
  border-top: 1px solid var(--line);
}

/* the fill */
.ticket::before {
  content: "";
  position: absolute;
  top: -1px;
  left: 0;
  width: 100%;
  height: 1px;
  background: var(--red);
  box-shadow: 0 0 12px rgba(229, 38, 28, 0.85);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 900ms var(--ease-out);
}
.ticket.is-locked::before { transform: scaleX(1); }

.ticket__kind {
  font-family: var(--mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-wide);
  text-transform: uppercase;
  color: var(--ink-soft);
}

.ticket__tape {
  font-family: var(--mono);
  font-size: 0.66rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-faint);
  min-height: 1.2em;      /* reserved, so locking never nudges the number */
}
.ticket.is-locked .ticket__tape { color: var(--hot-soft); }

.ticket__price {
  display: flex;
  align-items: flex-start;
  font-family: var(--display);
  font-size: clamp(4rem, 2rem + 8vw, 8.5rem);
  line-height: 0.86;
  letter-spacing: 0.005em;
  font-variant-numeric: tabular-nums;
  margin-block: 0.16em 0.1em;
}
.ticket__cur {
  font-size: 0.42em;
  margin-top: 0.16em;
  margin-right: 0.06em;
  color: var(--hot);
}
.ticket__num { display: inline-block; }

/* the settle */
.ticket.is-locked .ticket__num { animation: price-pop 620ms var(--ease-out) both; }
@keyframes price-pop {
  0%   { transform: scale(0.86) translateY(6px); }
  58%  { transform: scale(1.045) translateY(0); }
  100% { transform: scale(1); }
}
@media (prefers-reduced-motion: reduce) { .ticket.is-locked .ticket__num { animation: none; } }

/* what's included, not a caveat — each of the four packages is a
   flat rate now, so this line names the deal rather than hedging it
   with "estimated" the way it used to. */
.ticket__desc {
  max-width: 15em;
  font-family: var(--mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-mid);
  text-transform: lowercase;
  color: var(--ink-faint);
}

/* ------------------------------------------------------------
   CONTACT
   ------------------------------------------------------------ */
.wires {
  max-width: 940px;
  margin-inline: auto;
  border-top: 1px solid var(--line-soft);
}
.wire { border-bottom: 1px solid var(--line-soft); }

.wire__link {
  display: grid;
  grid-template-columns: minmax(0, 8.5rem) 1fr auto;
  align-items: baseline;
  gap: clamp(0.8rem, 2vw, 2rem);
  padding: clamp(1.1rem, 2.4vw, 1.9rem) clamp(0.4rem, 1.4vw, 1.2rem);
  transition: background var(--t-mid) var(--ease), box-shadow var(--t-mid) var(--ease);
}
.wire__tag {
  font-family: var(--mono);
  font-size: var(--step--2);
  letter-spacing: var(--tracking-mid);
  text-transform: uppercase;
  color: var(--ink-faint);
  transition: color var(--t-fast) var(--ease);
}
.wire__val {
  font-size: clamp(1.15rem, 0.7rem + 1.8vw, 2.3rem);
  font-weight: 500;
  letter-spacing: -0.015em;
  overflow-wrap: anywhere;
  transition: color var(--t-fast) var(--ease);
}
.wire__go {
  font-size: var(--step-0);
  color: var(--ink-faint);
  transition: color var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}

.wire__link:hover,
.wire__link:focus-visible {
  background: linear-gradient(90deg, rgba(255,45,31,0.13), rgba(255,45,31,0.03) 62%, transparent);
  box-shadow: inset 3px 0 0 var(--red-bright), 0 0 40px -12px rgba(255, 45, 31, 0.9);
}
.wire__link:hover .wire__val,
.wire__link:focus-visible .wire__val,
.wire__link:hover .wire__go,
.wire__link:focus-visible .wire__go { color: var(--hot); }
.wire__link:hover .wire__tag,
.wire__link:focus-visible .wire__tag { color: var(--ink-soft); }
.wire__link:hover .wire__go,
.wire__link:focus-visible .wire__go { transform: translate(3px, -3px); }

@media (max-width: 640px) {
  .wire__link { grid-template-columns: 1fr auto; }
  .wire__tag { grid-column: 1 / -1; }
}

/* ------------------------------------------------------------
   FOOTER
   ------------------------------------------------------------ */
.foot {
  display: flex;
  align-items: center;
  gap: clamp(0.9rem, 2vw, 1.8rem);
  margin-top: clamp(4rem, 8vw, 7rem);
}
.foot__mark {
  font-family: var(--display);
  font-size: var(--step-1);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  white-space: nowrap;
}
.foot__rule { flex: 1; height: 1px; background: var(--line-soft); }
.foot__by {
  font-family: var(--mono);
  font-size: var(--step--2);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-faint);
  text-align: right;
}
.foot__by b { font-weight: 400; }

@media (max-width: 620px) {
  .foot { flex-direction: column; align-items: flex-start; }
  .foot__rule { width: 100%; flex: none; }
  .foot__by { text-align: left; }
}
