/* ============================================================
   THE TRACE - assessment interface, light
   A chart recorder, not a sci-fi console. Real instruments draw
   ink on paper: EKG, seismograph, polygraph. So the ground is
   warm paper with a faint chart grid and the trace is ink.
   Real client dog photos, never AI ones. Exactly one dark
   moment in the whole flow, and it is the reveal.
   Self-contained on purpose: index.html loads this INSTEAD of
   app.css, which still belongs to plan.html and the course.
   ============================================================ */

:root {
  --t-paper:    #f4f1e8;
  --t-panel:    #ebe5d5;
  --t-grid:     #ddd6c2;
  --t-rule:     #cfc7b2;
  --t-ink:      #23261f;
  --t-ink-2:    #575c4f;
  --t-ink-3:    #696a58;   /* 5.2:1 on inputs, 4.9:1 on paper */
  --t-sage:     #6f7d59;
  --t-sage-btn: #66744f;   /* button ground: 4.8:1 against its own label */
  --t-line:     #4a5a38;
  --t-signal:   #ab4f2c;
  --t-dark:     #23261f;

  --t-mono: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
  --t-disp: "Barlow Condensed", "Avenir Next Condensed", Oswald, sans-serif;
  --t-body: Bitter, Georgia, serif;

  --t-gut: 22px;
  --t-max: 540px;
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  overflow-x: hidden;
  background: var(--t-paper);
  color: var(--t-ink);
  font-family: var(--t-body);
  -webkit-font-smoothing: antialiased;
  -webkit-text-size-adjust: 100%;
}

/* Paper has tooth. Two very faint washes so it never reads as a flat beige
   field, which is the other way to be depressing. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: 0;
  background:
    radial-gradient(120% 80% at 50% -10%, rgba(255, 253, 246, 0.9), transparent 60%),
    radial-gradient(90% 60% at 100% 100%, rgba(206, 196, 172, 0.32), transparent 70%);
}

#app {
  position: relative;
  z-index: 1;
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
}

.scr {
  position: relative;
  overflow: hidden;
  flex: 1;
  width: 100%;
  max-width: var(--t-max);
  margin: 0 auto;
  padding: 18px var(--t-gut) calc(22px + env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
}

/* ---------- instrument furniture ---------- */

.rail {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
  min-height: 42px;
  /* The badge was sitting right on the progress bar. */
  margin-top: 18px;
}

.rail-l { display: flex; align-items: center; gap: 10px; }

.tag {
  font-family: var(--t-mono);
  font-size: 10px;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--t-ink-3);
  margin: 0;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.tag.on { color: var(--t-sage); }

/* The badge, in the corner of every screen. Brand presence without a
   photograph that has to justify itself sixteen times. Sized to actually read
   as the logo rather than as a favicon. */
.mark {
  width: 42px;
  height: 42px;
  display: block;
  flex: none;
}

.hero .badge {
  width: 66px;
  height: 66px;
  display: block;
  margin: 0 0 16px;
}

/* Progress, because a quiz with no visible finish line is a chore. Sits at the
   very top edge where a phone browser's own progress bar would be. */
.prog {
  height: 3px;
  background: var(--t-rule);
  margin: 0 calc(var(--t-gut) * -1);
}
.prog i {
  display: block;
  height: 100%;
  background: var(--t-sage);
  width: 0;
  transition: width 0.5s cubic-bezier(0.22, 1, 0.36, 1);
}

/* ---------- the chart ---------- */

.trace-wrap {
  margin: 12px 0 0;
  position: relative;
  background: var(--t-panel);
  border: 1px solid var(--t-rule);
  padding: 8px 10px 6px;
}

/* Chart paper, drawn rather than loaded. */
.trace-wrap::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background-image:
    repeating-linear-gradient(to right, var(--t-grid) 0 1px, transparent 1px 22px),
    repeating-linear-gradient(to bottom, var(--t-grid) 0 1px, transparent 1px 22px);
  opacity: 0.5;
}

canvas.trace {
  display: block;
  position: relative;
  z-index: 1;
  width: 100%;
  height: 92px;
}

.axis {
  display: flex;
  justify-content: space-between;
  font-family: var(--t-mono);
  font-size: 9px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--t-ink-3);
  margin-top: 6px;
}

/* ---------- question ---------- */

/* The question sits in the room between the chart and the answers, centred.
   Pinned to the top it clung to the ceiling on the short qualifier screens and
   left a hole underneath; pinned to the bottom it floated away from its chart.
   Centred in the remaining space is right at both extremes. */
.q-zone {
  flex: 1;
  display: flex;
  align-items: center;
  padding: 22px 0;
  min-height: 132px;
}

.q {
  font-family: var(--t-disp);
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(27px, 7.2vw, 38px);
  line-height: 1.03;
  letter-spacing: 0.005em;
  text-wrap: balance;
  margin: 0;
  color: var(--t-ink);
}

/* ---------- setup screens ---------- */

/* No chart here. Nothing is being measured until the questions start, and a
   flat instrument at the top of a form only made the form look colder. */
.setup .setup-head {
  position: relative;
  margin-top: 26px;
  padding-bottom: 20px;
  min-height: clamp(88px, 21vw, 118px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

/* The setup headings run long once a dog's name is in them, so they sit a size
   below the question headings rather than shouting across three lines. */
.setup .setup-head .q { font-size: clamp(25px, 6.4vw, 34px); }

.setup .setup-head .q { position: relative; z-index: 1; }

.setup .sub {
  position: relative;
  z-index: 1;
  font-size: 16.5px;
  line-height: 1.55;
  color: var(--t-ink-2);
  margin: 14px 0 0;
  max-width: 34ch;
}

.setup .fields { margin-top: 28px; }
.setup .back { margin-top: 22px; align-self: center; }
.setup .btn { margin-top: 6px; }

/* The badge, very light, holding the right corner. Bleeds past the edge on
   purpose so it reads as a watermark on the page rather than a picture placed
   on it. */
.watermark {
  position: absolute;
  right: -20%;
  top: -7%;
  width: clamp(250px, 72vw, 400px);
  height: auto;
  opacity: 0.026;
  pointer-events: none;
  user-select: none;
  z-index: 0;
}

.setup > *:not(.watermark) { position: relative; z-index: 1; }

/* Said back to them before the screen moves, so it lands as an answer rather
   than a field that got filled. */
.confirm {
  font-family: var(--t-body);
  font-style: italic;
  font-size: 16px;
  color: var(--t-sage);
  margin: 20px 0 0;
  animation: t-rise 0.3s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.confirm[hidden] { display: none; }

/* ---------- a field that tells you it is done ---------- */

/* Real labels. Three reasons: the placeholder vanished the moment anyone typed,
   a placeholder reading "Dog's name" is exactly the token iOS AutoFill looks
   for when deciding a field wants a person's name, and four labelled fields
   have rhythm where four bare boxes are a wall. */
.field { position: relative; }

.flabel {
  display: block;
  font-family: var(--t-mono);
  font-size: 10px;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--t-ink-3);
  margin: 0 0 6px 1px;
}

.field .input { padding-right: 46px; }

/* Four identical rectangles is a wall. Each one confirming itself turns the
   same four fields into four small wins on the way to the button. */
.field .tick {
  position: absolute;
  right: 15px;
  /* Measured from the bottom, because the label sits above the input now. */
  bottom: 18px;
  width: 17px;
  height: 17px;
  pointer-events: none;
  opacity: 0;
  transform: scale(0.7);
  transition: opacity 0.22s cubic-bezier(0.22, 1, 0.36, 1),
              transform 0.22s cubic-bezier(0.22, 1, 0.36, 1);
}
.field .tick path {
  stroke: var(--t-sage);
  stroke-width: 2.4;
  stroke-linecap: round;
  stroke-linejoin: round;
  fill: none;
  stroke-dasharray: 22;
  stroke-dashoffset: 22;
}
.field.done .tick { opacity: 1; transform: scale(1); }
.field.done .tick path { animation: t-draw 0.34s cubic-bezier(0.22, 1, 0.36, 1) forwards; }
.field.done .input { border-color: var(--t-sage); }

@keyframes t-draw { to { stroke-dashoffset: 0; } }

/* The button waits until it can actually do something, then wakes up. */
.btn.waiting {
  background: transparent;
  color: var(--t-ink-3);
  border: 1px solid var(--t-rule);
  box-shadow: none;
}
.btn.waiting::after { display: none; }
.btn.waiting:hover { background: transparent; transform: none; box-shadow: none; }

@media (prefers-reduced-motion: reduce) {
  .field .tick { transition: none; }
  .field.done .tick path { animation: none; stroke-dashoffset: 0; }
}

/* ---------- age and size, as chips ---------- */

/* Two native selects on a phone is two full-screen system pickers for what is
   really seven choices. These are seven buttons. */
/* Centred in the room left over, so the screen is not all weight at the top
   with a hole under it. */
/* One block with the heading, not a group floating in the middle of the screen.
   The slack belongs at the bottom, not between the title and the controls. */
.chip-groups {
  display: grid;
  gap: 24px;
  margin-top: 4px;
}

.chip-label {
  font-family: var(--t-mono);
  font-size: 10px;
  letter-spacing: 0.19em;
  text-transform: uppercase;
  color: var(--t-ink-3);
  margin: 0 0 11px;
}

/* Grids, not wrap. Four ages wrapping three-then-one looked like an accident
   rather than a layout. */
.chips { display: grid; gap: 8px; }
.chips.age { grid-template-columns: repeat(2, 1fr); }
.chips.size { grid-template-columns: repeat(3, 1fr); }
.chips.size .chip { min-height: 84px; padding-top: 11px; }

.chip {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  font-family: var(--t-body);
  color: var(--t-ink);
  background: #fdfcf7;
  border: 1px solid var(--t-rule);
  border-radius: 3px;
  padding: 13px 14px;
  min-height: 66px;
  text-align: left;
  cursor: pointer;
  transition: background 0.15s ease, border-color 0.15s ease, transform 0.12s ease, box-shadow 0.15s ease;
}

.chip-word { font-size: 16.5px; line-height: 1.15; }
.chip-qual {
  font-family: var(--t-mono);
  font-size: 10px;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: var(--t-ink-3);
}
.chip.on .chip-qual { color: rgba(251, 249, 243, 0.82); }

/* The dot is the size, so the control shows the answer instead of only naming
   it. Encodes information; it is not an icon for decoration. */
.chip-dot {
  width: var(--d);
  height: var(--d);
  border-radius: 50%;
  background: var(--t-sage);
  /* Pushes the dot to the top so the three labels sit on one line. Without
     this the bigger dot shunts its own label down and the row reads crooked. */
  margin-bottom: auto;
  transition: background 0.15s ease;
}
.chip.on .chip-dot { background: #fbf9f3; }
.chip:hover { border-color: var(--t-sage); box-shadow: 0 2px 8px rgba(35, 38, 31, 0.08); }
.chip:active { transform: scale(0.98); }
.chip:focus-visible { outline: 2px solid var(--t-sage); outline-offset: 2px; }
.chip.on {
  background: var(--t-sage);
  border-color: var(--t-sage);
  color: #fbf9f3;
  box-shadow: 0 4px 14px rgba(111, 125, 89, 0.32);
}

.q-zone { position: relative; }

.q-zone .q { position: relative; z-index: 1; }

/* The dog's name carries the brand colour wherever it appears in a heading. */
.q em {
  font-style: normal;
  color: var(--t-sage);
}

/* Fires once, on the first letter of the name. */
@keyframes t-pop {
  0%   { transform: scale(1); }
  45%  { transform: scale(1.035); }
  100% { transform: scale(1); }
}
.q.pop {
  animation: t-pop 0.42s cubic-bezier(0.22, 1, 0.36, 1);
  transform-origin: left center;
}

/* ---------- options ---------- */

/* These are buttons, so they look like buttons. As hairline rows on a phone
   they read as a list of statements and it was not obvious they were tappable.
   Raised cards, big tap targets, and a chip carrying the reading. */
.opts {
  display: grid;
  gap: 9px;
  margin-top: auto;
  padding-top: 26px;
}

.opt {
  display: block;
  width: 100%;
  min-height: 62px;
  text-align: left;
  background: #fdfcf7;
  color: var(--t-ink);
  border: 1px solid var(--t-rule);
  border-left: 3px solid var(--t-rule);
  border-radius: 3px;
  padding: 13px 42px 14px 14px;
  font-family: var(--t-body);
  font-size: 16.5px;
  line-height: 1.34;
  cursor: pointer;
  position: relative;
  box-shadow: 0 1px 0 rgba(35, 38, 31, 0.06);
  transition: border-left-color 0.16s ease, background 0.16s ease,
              transform 0.12s ease, box-shadow 0.16s ease;
}

/* The chevron is always visible now, not a hover reveal. On a phone there is
   no hover, so a hover-only affordance is no affordance. */
.opt::after {
  content: "";
  position: absolute;
  right: 17px;
  top: 50%;
  width: 8px;
  height: 8px;
  border-right: 2px solid var(--t-sage);
  border-top: 2px solid var(--t-sage);
  transform: translateY(-50%) rotate(45deg);
  opacity: 0.55;
  transition: opacity 0.16s ease, right 0.16s ease;
}

.opt:hover {
  background: #fff;
  border-left-color: var(--t-sage);
  box-shadow: 0 3px 10px rgba(35, 38, 31, 0.09);
}
.opt:hover::after { opacity: 1; right: 14px; }
.opt:focus-visible { outline: 2px solid var(--t-sage); outline-offset: 2px; }
.opt:active { transform: scale(0.988); box-shadow: 0 1px 0 rgba(35, 38, 31, 0.06); }

/* The answer you picked lights up and holds while the line draws. */
.opt.chosen {
  background: var(--t-sage);
  border-color: var(--t-sage);
  border-left-color: var(--t-ink);
  color: #fbf9f3;
  box-shadow: 0 4px 14px rgba(111, 125, 89, 0.34);
  transform: translateX(3px);
}
.opt.chosen .lv { background: rgba(251, 249, 243, 0.22); color: #fbf9f3; }
.opt.chosen::after { border-color: #fbf9f3; opacity: 1; right: 14px; }

/* Everything you did not pick steps back. */
.opts.locked .opt:not(.chosen) { opacity: 0.4; }
.opts.locked .opt { pointer-events: none; }

.opt .txt { display: block; }

.opt .lv {
  display: inline-block;
  font-family: var(--t-mono);
  font-size: 9px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--t-sage);
  background: rgba(111, 125, 89, 0.13);
  padding: 3px 7px;
  border-radius: 2px;
  margin-bottom: 8px;
  transition: background 0.16s ease, color 0.16s ease;
}

.back {
  align-self: flex-start;
  margin-top: 14px;
  background: none;
  border: 0;
  color: var(--t-ink-3);
  font-family: var(--t-mono);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  padding: 10px 2px;
  cursor: pointer;
}
.back:hover { color: var(--t-ink); }

/* ---------- inputs ---------- */

.input {
  width: 100%;
  background: #fbf9f3;
  border: 1px solid var(--t-rule);
  color: var(--t-ink);
  font-family: var(--t-body);
  font-size: 18px;
  padding: 14px;
  border-radius: 0;
  appearance: none;
}
.input::placeholder { color: var(--t-ink-3); }
.input:focus { outline: 0; border-color: var(--t-sage); box-shadow: inset 0 0 0 1px var(--t-sage); }

select.input {
  background-image: linear-gradient(45deg, transparent 50%, var(--t-sage) 50%),
                    linear-gradient(135deg, var(--t-sage) 50%, transparent 50%);
  background-position: right 16px center, right 10px center;
  background-size: 6px 6px, 6px 6px;
  background-repeat: no-repeat;
}

.fields { display: grid; gap: 8px; margin-top: 22px; }

.note {
  font-family: var(--t-body);
  font-size: 14px;
  color: var(--t-ink-3);
  line-height: 1.55;
  margin: 16px 0 2px;
  max-width: 46ch;
}

/* ---------- buttons ---------- */

.btn {
  background: var(--t-sage-btn);
  color: #fbf9f3;
  border: 0;
  width: 100%;
  min-height: 58px;
  padding: 18px;
  font-family: var(--t-disp);
  font-weight: 800;
  text-transform: uppercase;
  letter-spacing: 0.11em;
  font-size: 18px;
  cursor: pointer;
  border-radius: 3px;
  box-shadow: 0 4px 14px rgba(111, 125, 89, 0.3);
  transition: background 0.16s ease, transform 0.12s ease, box-shadow 0.16s ease;
}
.btn:hover { background: #57643f; box-shadow: 0 8px 24px rgba(111, 125, 89, 0.42); transform: translateY(-1px); }
.btn:active { transform: translateY(1px) scale(0.994); box-shadow: 0 2px 8px rgba(111, 125, 89, 0.3); }

/* A quiet sheen that crosses the button once on arrival. One flourish, on the
   one control that matters. */
.btn { position: relative; overflow: hidden; }
.btn::after {
  content: "";
  position: absolute;
  top: 0;
  bottom: 0;
  width: 42%;
  left: -50%;
  background: linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.22), transparent);
  transform: skewX(-18deg);
  animation: t-sheen 2.6s cubic-bezier(0.22, 1, 0.36, 1) 0.5s 1 forwards;
}
@keyframes t-sheen {
  0%   { left: -50%; }
  55%  { left: 120%; }
  100% { left: 120%; }
}
.btn:disabled { background: var(--t-rule); color: #fbf9f3; box-shadow: none; cursor: default; }
.btn:focus-visible { outline: 2px solid var(--t-ink); outline-offset: 3px; }

/* The second option, quieter than the first. Outline against the filled
   primary, so the plan stays the obvious move and the consult is there for
   somebody who would rather just talk to a person. */
.btn-2 {
  display: flex;
  align-items: center;
  justify-content: center;
  background: transparent;
  color: var(--t-ink);
  border: 1px solid var(--t-ink);
  box-shadow: none;
  text-decoration: none;
  font-size: 16px;
}
.btn-2::after { display: none; }
.btn-2:hover {
  background: var(--t-ink);
  color: var(--t-paper);
  box-shadow: none;
  transform: translateY(-1px);
}

/* A rule with the word sitting in it, rather than a floating "or". */
.or {
  display: flex;
  align-items: center;
  gap: 12px;
  margin: 20px 0 16px;
  font-family: var(--t-mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--t-ink-3);
}
.or::before, .or::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--t-rule);
}

/* ---------- photographs ---------- */

.photo {
  display: block;
  width: 100%;
  object-fit: cover;
  border: 1px solid var(--t-rule);
}

/* One photograph in the whole flow, on the capture panel. Framed on the
   faces: the source is a tall portrait and a centred crop cuts them out. */
.photo.band { height: clamp(150px, 32vw, 210px); }
.photo.tall {
  height: clamp(210px, 50vw, 300px);
  object-position: center 34%;
}

/* ---------- hero ---------- */

/* Centred, and actually centred: the old one hung high with the weight all in
   the top half. Everything is on the middle axis now, badge included. */
.hero {
  justify-content: center;
  align-items: center;
  text-align: center;
  gap: 0;
  padding-top: 32px;
  padding-bottom: 32px;
}

.hero .badge {
  width: 76px;
  height: 76px;
  display: block;
  margin: 0 0 26px;
}

.hero h1 {
  font-family: var(--t-disp);
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(36px, 9.6vw, 56px);
  line-height: 0.96;
  letter-spacing: 0.005em;
  text-wrap: balance;
  margin: 0;
}
.hero h1 em { font-style: normal; color: var(--t-sage); }

.hero .lead {
  font-size: 16.5px;
  line-height: 1.58;
  color: var(--t-ink-2);
  margin: 18px auto 0;
  max-width: 40ch;
}

.hero .trace-wrap { width: 100%; margin-top: 24px; }
.hero canvas.trace { height: 78px; }

.hero .btn { margin-top: 22px; }

.hero .meta {
  font-family: var(--t-mono);
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--t-ink-3);
  margin: 14px 0 0;
}

@media (max-height: 760px) {
  .hero .badge { width: 62px; height: 62px; margin-bottom: 18px; }
  .hero canvas.trace { height: 62px; }
  .hero .trace-wrap { margin-top: 18px; }
  .hero .lead { margin-top: 14px; }
}

/* ---------- result: the one dark moment ---------- */

.rev .verdict {
  background: var(--t-dark);
  color: #f4f1e8;
  padding: 26px 22px 28px;
  margin: 18px calc(var(--t-gut) * -1) 0;
}

.rev .verdict .tag { color: #a6b48c; }

.rev h1 {
  font-family: var(--t-disp);
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(30px, 8vw, 44px);
  line-height: 0.98;
  text-wrap: balance;
  margin: 10px 0 0;
  color: #f4f1e8;
}
.rev h1 em { font-style: normal; color: #a6b48c; }

.bars { display: grid; gap: 10px; margin: 22px 0 0; }

.brow {
  display: grid;
  grid-template-columns: 1fr auto;
  align-items: baseline;
  font-family: var(--t-mono);
  font-size: 10px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: rgba(244, 241, 232, 0.62);
  font-variant-numeric: tabular-nums;
}
.brow.lead-row { color: #a6b48c; }

.btrack {
  grid-column: 1 / -1;
  height: 3px;
  background: rgba(244, 241, 232, 0.17);
  margin-top: 5px;
}
.bval {
  display: block;
  height: 100%;
  background: rgba(244, 241, 232, 0.45);
  width: 0;
  transition: width 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}
.brow.lead-row .bval { background: #a6b48c; }

.rev p.serif {
  font-size: 16.5px;
  line-height: 1.62;
  color: var(--t-ink-2);
  margin: 18px 0 0;
  max-width: 48ch;
}
.rev p.close {
  font-size: 16.5px;
  line-height: 1.62;
  color: var(--t-ink);
  margin: 18px 0 0;
  max-width: 48ch;
}

/* ---------- clients ---------- */

/* Ten real clients, crossfading. Fixed aspect so the panel never jumps when a
   photograph of a different shape comes round. */
.slides {
  position: relative;
  width: 100%;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--t-rule);
  border: 1px solid var(--t-rule);
  border-radius: 3px;
}

.slide {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  opacity: 0;
  transition: opacity 0.9s ease;
}
.slide.on { opacity: 1; }

.slide-dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 9px;
  display: flex;
  justify-content: center;
  gap: 5px;
}
.slide-dots i {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: rgba(251, 249, 243, 0.45);
  box-shadow: 0 0 3px rgba(35, 38, 31, 0.4);
  transition: background 0.3s ease;
}
.slide-dots i.on { background: #fbf9f3; }

.slide-cap {
  font-family: var(--t-body);
  font-style: italic;
  font-size: 15px;
  line-height: 1.45;
  color: var(--t-ink-2);
  margin: 12px 0 0;
  min-height: 2.9em;
}

/* ---------- capture ---------- */

.capture {
  margin-top: 30px;
  padding: 24px 22px 26px;
  background: var(--t-panel);
  border: 1px solid var(--t-rule);
}

.capture .slides { margin-bottom: 0; }

.capture h2 {
  font-family: var(--t-disp);
  font-weight: 800;
  text-transform: uppercase;
  font-size: clamp(24px, 6.4vw, 32px);
  line-height: 1.02;
  margin: 10px 0 0;
  text-wrap: balance;
}

.capture p {
  font-size: 15.5px;
  line-height: 1.56;
  color: var(--t-ink-2);
  margin: 12px 0 0;
  max-width: 44ch;
}

/* Was 10px uppercase mono, same as the setup note used to be. Cold, and hard
   to read for a line whose job is telling somebody where their plan is going. */
.capture .note {
  font-family: var(--t-body);
  font-size: 14px;
  color: var(--t-ink-3);
  line-height: 1.55;
  margin-top: 14px;
}

.capture .btn { margin-top: 20px; }

.err {
  color: var(--t-signal);
  font-family: var(--t-mono);
  font-size: 11px;
  letter-spacing: 0.06em;
  line-height: 1.5;
  margin: 12px 0 0;
}
.err[hidden] { display: none; }

/* ---------- motion ---------- */

@keyframes t-rise {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}
.q, .opts, .rev .verdict, .capture, .hero .badge {
  animation: t-rise 0.34s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.opts { animation-delay: 0.05s; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.001ms !important;
    transition-duration: 0.001ms !important;
  }
}

@media (max-width: 380px) {
  .chips.size { grid-template-columns: 1fr; }
  .chip { min-height: 58px; }
}

@media (max-height: 760px) {
  canvas.trace { height: 74px; }
  .q-zone { padding-top: 18px; }
  .opts { padding-top: 18px; gap: 7px; }
  .opt { min-height: 56px; padding-top: 11px; padding-bottom: 12px; }
  .scr { padding-top: 12px; }
  .rail { margin-top: 14px; }
  .mark { width: 36px; height: 36px; }
}

@media (min-width: 560px) {
  .scr { padding-top: 30px; padding-bottom: 34px; }
  canvas.trace { height: 108px; }
  .hero canvas.trace { height: 86px; }
}
