/* Survey-only additions, loaded after styles.css.
 *
 * Everything the survey shares with the founding-customer application comes
 * from styles.css and is not repeated here: the whole .tf-* form system, the
 * button, the container, the brand lock-up, the type scale and the palette.
 * This file holds three things and nothing else: the components the survey
 * needs that the application never had (checkbox groups, the part chip, the
 * explain plate, the offer plate), the coloured grounds, and the motion.
 *
 * No hex values. Every colour is a brand token from :root in styles.css, so a
 * palette correction there reaches this file for free. A second copy of the
 * palette is a second thing to drift. */

/* ------------------------------------------------------------------ */
/* Grounds. One colour per screen, per strategy/design-direction.md.   */
/* Questions stay on paper because they carry detail; the welcome and  */
/* the thank-you get a field because they carry one idea each.         */
/* ------------------------------------------------------------------ */

.sv-body {
  transition: background-color .55s ease, color .55s ease;
}

/* Deliberately no position or z-index here. styles.css makes .header sticky at
   z-index 20 and this class would silently outrank it on source order, which
   would un-stick the header on this page alone. */
.sv-header {
  transition: background-color .55s ease, border-color .55s ease;
}

/* The welcome screen is the home page's hero: white ground, faint ink grid,
   the ordinary header. The literal rgba below is not a token by mistake, it is
   the exact value .grid-bg uses in styles.css, so the two grounds match rather
   than nearly match. */
body:has(.sv-welcome:not([hidden])) .sv {
  background-image:
    linear-gradient(rgba(17, 27, 37, .1) 1px, transparent 1px),
    linear-gradient(90deg, rgba(17, 27, 37, .1) 1px, transparent 1px);
  background-size: 64px 64px;
  animation: sv-drift-ink 60s linear infinite;
}

@keyframes sv-drift-ink {
  to { background-position: 64px 64px, 64px 64px; }
}

/* The thank-you keeps a field. It is the one screen carrying a single idea and
   nothing to read, and green is the brand's colour for the quieter beat. */
body:has(.sv-done:not([hidden])) {
  background-color: var(--green);
  color: var(--white);
}

body:has(.sv-done:not([hidden])) .sv-header {
  background: transparent;
  border-bottom-color: rgba(255, 255, 255, .22);
}

body:has(.sv-done:not([hidden])) .apply-tag {
  color: rgba(255, 255, 255, .72);
}

/* styles.css sets .header .brand to blue, which is close to invisible on the
   green field. The wordmark goes white and its accent goes yellow, because
   coral on green is unreadable and the brand guide bans it outright. */
body:has(.sv-done:not([hidden])) .header .brand {
  color: var(--white);
}

body:has(.sv-done:not([hidden])) .header .brand span {
  color: var(--yellow);
}

body:has(.sv-done:not([hidden])) .nav-links a,
body:has(.sv-done:not([hidden])) .nav-cta {
  color: var(--white);
}

body:has(.sv-done:not([hidden])) .menu i {
  background: var(--white);
}

body:has(.sv-done:not([hidden])) .tf-progress {
  background-color: rgba(255, 255, 255, .2);
}

body:has(.sv-done:not([hidden])) .sv {
  background-image:
    linear-gradient(rgba(255, 255, 255, .11) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, .11) 1px, transparent 1px);
  background-size: 72px 72px;
  animation: sv-drift 44s linear infinite;
}

@keyframes sv-drift {
  to { background-position: 72px 72px, 72px 72px; }
}

/* ------------------------------------------------------------------ */
/* Welcome                                                             */
/* ------------------------------------------------------------------ */

/* The welcome breaks out of the 760px form measure and uses the site's own
   1160px container. The questions want a narrow column; a headline does not,
   and at 760px this one wrapped after "Stop" and left "That AI Slop" stranded
   on a second line. */
body:has(.sv-welcome:not([hidden])) .sv .container,
body:has(.sv-optin:not([hidden])) .sv .container {
  width: min(1160px, calc(100% - 64px));
}

/* Much larger than the shared .tf-welcome size. That one was set for a 760px
   column; this headline has the full 1160px container and was leaving most of
   the screen empty. The ceiling is the largest size that still holds
   "How to Stop That AI Slop" on one line at 1160px. */
.sv-welcome h1 {
  max-width: none;
  font-size: clamp(42px, 8vw, 96px);
  line-height: .93;
  letter-spacing: -.055em;
  text-wrap: balance;
}

/* Yellow behind a heading is the one place the brand guide allows it as a
   field, and it does the work the type size was being asked to do on its own.
   box-decoration-break keeps the block intact when the line wraps on a phone,
   otherwise the highlight loses its padding on the second line. */
.sv-mark {
  background: var(--yellow);
  padding: 0 .1em .04em;
  -webkit-box-decoration-break: clone;
  box-decoration-break: clone;
}

/* Runs to the same edges as the headline. At 620px it sat as a narrow column
   under a 1048px headline and read as though it had been cut off. The block is
   three short sentences, so a wide measure costs little and the alignment is
   worth more. */
.sv-lede {
  margin: 26px 0 0;
  /* 90 per cent of the column is where the headline text actually ends, since
     both it and the container scale off the same viewport width. Measured at
     1048px of a 1160px column, and it holds within a few per cent all the way
     down to the mobile breakpoint. Left at "none" the lede overran the
     headline's right edge by 88px, which looked as wrong as the narrow version
     did. */
  max-width: 90%;
  font-size: 20px;
  line-height: 1.5;
  color: var(--muted);
}

/* No rule down the side of each line. The bold lead-in already separates them
   and the bars were reading as decoration rather than structure. */
.sv-welcome .tf-deal {
  margin-top: 38px;
  gap: 18px;
  max-width: 90%;
}

.sv-welcome .tf-deal li {
  padding-left: 0;
  border-left: 0;
  font-size: 16px;
  line-height: 1.5;
}

.sv-welcome .tf-deal b {
  color: var(--ink);
}

/* ------------------------------------------------------------------ */
/* The part chip. Orientation on every screen, so eighteen questions   */
/* read as four chapters.                                              */
/* ------------------------------------------------------------------ */

.sv-part {
  display: inline-block;
  margin-left: 10px;
  padding-left: 11px;
  border-left: 1px solid var(--line);
  font: 10px var(--mono);
  font-weight: 400;
  letter-spacing: .09em;
  text-transform: uppercase;
  color: var(--muted);
  vertical-align: baseline;
}

.tf-q.is-newpart .sv-part {
  animation: sv-chip 1.5s ease both;
}

@keyframes sv-chip {
  0%   { color: var(--muted); border-left-color: var(--line); }
  18%  { color: var(--blue); border-left-color: var(--blue); }
  62%  { color: var(--blue); border-left-color: var(--blue); }
  100% { color: var(--muted); border-left-color: var(--line); }
}

/* Ticks on the progress rail at the three part boundaries: after questions
   4, 8 and 16 of the twenty steps the machine counts. */
.sv-progress {
  background-image:
    linear-gradient(90deg, transparent 21.05%, rgba(55, 55, 55, .38) 21.05%, rgba(55, 55, 55, .38) calc(21.05% + 1px), transparent calc(21.05% + 1px)),
    linear-gradient(90deg, transparent 42.11%, rgba(55, 55, 55, .38) 42.11%, rgba(55, 55, 55, .38) calc(42.11% + 1px), transparent calc(42.11% + 1px)),
    linear-gradient(90deg, transparent 84.21%, rgba(55, 55, 55, .38) 84.21%, rgba(55, 55, 55, .38) calc(84.21% + 1px), transparent calc(84.21% + 1px));
}

.sv-progress i {
  transition: width .42s cubic-bezier(.22, .61, .36, 1);
}

/* ------------------------------------------------------------------ */
/* Checkbox groups                                                     */
/* ------------------------------------------------------------------ */

/* Native checkboxes, recoloured, for the same reason styles.css keeps native
   radios: faking them with appearance:none is the biggest single source of
   a11y bugs in hand-rolled forms, and accent-color keeps group semantics and
   forced-colors support for free. */
.sv-multi .tf-choice input {
  border-radius: 0;
}

.sv-multi .tf-choice:has(:checked) b {
  background: var(--blue);
  border-color: var(--blue);
  color: var(--white);
}

.sv-count {
  margin: 14px 0 0;
  font: 11px var(--mono);
  letter-spacing: .04em;
  color: var(--muted);
  min-height: 1.2em;
}

.sv-count.is-full {
  color: var(--blue);
  font-weight: 500;
}

/* ------------------------------------------------------------------ */
/* Opt-in step                                                         */
/* ------------------------------------------------------------------ */

/* The explain plate is blue because it carries the argument, and it sits on
   the paper ground rather than flooding it, so the coral submit button below
   never lands on a coloured field. */
/* The two plates share a row on desktop. Stacked they pushed the form most of
   a screen down, which is the thing that was wrong with the first version of
   this step. Equal height by default, so the shorter yellow one squares off
   against the blue rather than floating. */
.sv-boxes {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 16px;
  margin: 0;
}

.sv-boxes .sv-explain,
.sv-boxes .sv-seats {
  max-width: none;
  margin: 0;
}

/* The fields keep their own measure even though the step is now wide. A 1160px
   text input is unusable. */
.sv-optin .tf-ask,
.sv-optin .tf-help,
.sv-optin .tf-pair,
.sv-opts {
  max-width: 720px;
}

.sv-explain {
  margin: 0;
  max-width: 640px;
  padding: 26px 28px;
  background: var(--blue);
  color: var(--white);
}

.sv-explain .eyebrow {
  color: var(--yellow);
}

.sv-explain p {
  margin: 12px 0 0;
  font-size: 14.5px;
  line-height: 1.55;
  color: rgba(255, 255, 255, .86);
}

.sv-explain-lead {
  font-size: 17px !important;
  font-weight: 700;
  color: var(--white) !important;
}

/* White rather than yellow, so the only yellow on this screen is the offer
   block below it. Two yellows a paragraph apart read as one thing in two
   places, and the rule and the offer are not the same thing. */
.sv-explain-limit {
  margin-top: 16px !important;
  padding-top: 14px;
  border-top: 1px solid rgba(255, 255, 255, .28);
  color: var(--white) !important;
  font-weight: 600;
}

/* The offer, on a yellow section field. Yellow is legal behind a block of copy
   and never as a whole asset, and it keeps the offer visually separate from the
   blue plate above it: that one says what the product is, this one says what is
   being offered. Coral stays out of both, so the submit button below is the
   only coral on the screen. */
.sv-seats {
  margin: 18px 0 0;
  max-width: 640px;
  padding: 22px 24px;
  background: var(--yellow);
  color: var(--ink);
}

.sv-seats .eyebrow {
  color: var(--ink);
  opacity: .7;
}

.sv-seats p {
  margin: 11px 0 0;
  font-size: 14.5px;
  line-height: 1.55;
}

.sv-seats-link {
  margin-top: 16px !important;
}

.sv-optin .tf-ask {
  margin-top: 44px;
}

.sv-optin .tf-help {
  margin-top: 12px;
}

.sv-optin .tf-pair + .tf-pair {
  margin-top: 14px;
}

.sv-optin .tf-pair {
  margin-top: 16px;
  max-width: 640px;
}

.sv-opts {
  margin: 22px 0 0;
  max-width: 640px;
  display: grid;
  gap: 2px;
}

.sv-opt {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 13px;
  align-items: start;
  padding: 13px 15px;
  border: 1px solid var(--line);
  background: var(--white);
  font-size: 14.5px;
  line-height: 1.4;
  cursor: pointer;
  transition: border-color .15s, box-shadow .15s;
}

.sv-opt input {
  accent-color: var(--blue);
  width: 18px;
  height: 18px;
  margin: 1px 0 0;
}

.sv-opt:hover { border-color: var(--ink); }
.sv-opt:has(:checked) { border-color: var(--blue); box-shadow: 3px 3px 0 var(--blue); }
.sv-opt:has(:focus-visible) { outline: 2px solid var(--blue); outline-offset: 2px; }

/* ------------------------------------------------------------------ */
/* Thank-you and the offer                                             */
/* ------------------------------------------------------------------ */

.sv-done p {
  color: rgba(255, 255, 255, .86);
  max-width: 560px;
}

.sv-done .eyebrow {
  color: var(--yellow);
}

/* The paper plate that lets a coral button exist on a green ground. */
.sv-offer {
  margin: 38px 0 0;
  max-width: 640px;
  padding: 30px 30px 32px;
  background: var(--white);
  color: var(--ink);
}

.sv-offer .eyebrow { color: var(--muted); }

.sv-offer h3 {
  margin: 12px 0 0;
  font-size: clamp(21px, 3.4vw, 27px);
  line-height: 1.12;
  letter-spacing: -.035em;
  font-weight: 900;
}

.sv-offer p {
  margin: 13px 0 0;
  max-width: none;
  font-size: 14.5px;
  line-height: 1.55;
  color: var(--muted);
}

.sv-offer-nav {
  margin-top: 24px;
  display: flex;
  align-items: center;
  gap: 22px;
  flex-wrap: wrap;
}

/* ------------------------------------------------------------------ */
/* Motion                                                              */
/* ------------------------------------------------------------------ */

/* Choices arrive behind the question rather than as a block. Delays are
   written per position rather than driven by a custom property, because the
   markup is static and this keeps the JS free of presentation. */
.tf-q.is-active .tf-choice,
.tf-q.is-active .sv-opt {
  animation: sv-rise .38s cubic-bezier(.22, .61, .36, 1) both;
}

.tf-q.is-active .tf-choice:nth-child(1),  .tf-q.is-active .sv-opt:nth-child(1)  { animation-delay: .06s; }
.tf-q.is-active .tf-choice:nth-child(2),  .tf-q.is-active .sv-opt:nth-child(2)  { animation-delay: .09s; }
.tf-q.is-active .tf-choice:nth-child(3),  .tf-q.is-active .sv-opt:nth-child(3)  { animation-delay: .12s; }
.tf-q.is-active .tf-choice:nth-child(4)  { animation-delay: .15s; }
.tf-q.is-active .tf-choice:nth-child(5)  { animation-delay: .18s; }
.tf-q.is-active .tf-choice:nth-child(6)  { animation-delay: .21s; }
.tf-q.is-active .tf-choice:nth-child(7)  { animation-delay: .24s; }
.tf-q.is-active .tf-choice:nth-child(8)  { animation-delay: .27s; }
.tf-q.is-active .tf-choice:nth-child(9)  { animation-delay: .30s; }
.tf-q.is-active .tf-choice:nth-child(10) { animation-delay: .33s; }
.tf-q.is-active .tf-choice:nth-child(11) { animation-delay: .36s; }

@keyframes sv-rise {
  from { opacity: 0; transform: translateY(9px); }
  to   { opacity: 1; transform: none; }
}

/* A press state on top of the hover and :has(:checked) treatment already in
   styles.css, so a tap on a phone acknowledges itself before the screen
   changes. */
.tf-choice:active,
.sv-opt:active {
  transform: translate(1px, 1px);
}

.sv-welcome .tf-deal li {
  animation: sv-rise .42s cubic-bezier(.22, .61, .36, 1) both;
}

.sv-welcome .tf-deal li:nth-child(1) { animation-delay: .10s; }
.sv-welcome .tf-deal li:nth-child(2) { animation-delay: .16s; }
.sv-welcome .tf-deal li:nth-child(3) { animation-delay: .22s; }

.sv-offer {
  animation: sv-rise .5s cubic-bezier(.22, .61, .36, 1) both;
  animation-delay: .2s;
}

@media (prefers-reduced-motion: reduce) {
  .sv-body,
  .sv-header,
  body:has(.sv-welcome:not([hidden])) .sv,
  body:has(.sv-done:not([hidden])) .sv,
  .sv-progress i,
  .tf-q.is-active .tf-choice,
  .tf-q.is-active .sv-opt,
  .tf-q.is-newpart .sv-part,
  .sv-welcome .tf-deal li,
  .sv-offer {
    animation: none !important;
    transition: none !important;
  }
  .tf-choice:active,
  .sv-opt:active {
    transform: none;
  }
}

/* ------------------------------------------------------------------ */
/* Mobile                                                              */
/* ------------------------------------------------------------------ */

@media (max-width: 800px) {
  .sv-part {
    display: block;
    margin: 8px 0 0;
    padding: 0;
    border-left: 0;
  }

  .tf-q.is-newpart .sv-part {
    animation-name: sv-chip-flat;
  }

  @keyframes sv-chip-flat {
    0%   { color: var(--muted); }
    18%  { color: var(--blue); }
    62%  { color: var(--blue); }
    100% { color: var(--muted); }
  }

  /* Measured, not guessed. At 375px the column is 311px and the longest line
     of the two-line set, "That AI Slop", wraps above 54px. 13.5vw stays under
     that at every phone width from 320 up (43px at 320, 54px at 400, 58px at
     430) with roughly 8 per cent to spare. 14vw already wraps at 320. */
  .sv-welcome h1 {
    font-size: clamp(38px, 13.5vw, 62px);
    line-height: .92;
  }

  .sv-boxes { grid-template-columns: 1fr; gap: 14px; }
  /* The phone column is already narrow; capping it again just reintroduces the
     ragged right edge. */
  .sv-lede { margin-top: 22px; font-size: 16px; max-width: none; }
  .sv-welcome .tf-deal { max-width: none; }
  .sv-welcome .tf-deal { margin-top: 30px; gap: 16px; }
  .sv-welcome .tf-deal li { font-size: 15.5px; }
  .sv-explain { padding: 22px; }
  .sv-optin .tf-pair { grid-template-columns: 1fr; }
  .sv-offer { padding: 24px 22px 26px; }
  .sv-offer-nav { gap: 16px; }
  body:has(.sv-welcome:not([hidden])) .sv,
  body:has(.sv-done:not([hidden])) .sv { background-size: 56px 56px; }
}
