/* assets/rn/pages/brief.css — /brief.html (3-brief). Linked LAST on brief.html; unlayered, so it beats the legacy layer
   at any specificity. The brief is in the audit family: no signal hue, marks follow the text colour (ink on paper,
   paper on ink), and red appears only in the H1 phrase and in form errors.

    1. Page tokens                      7. Foot: fee guide, trust line, actions
    2. Hero                             8. Result box: sending, sent (toast + check), error
    3. Workspace and the form card      9. Aside: how this works, where I'd start
    4. Starting point and progress     10. Message form (ink)
    5. Steps                           11. Motion: reduced motion and the site pause
    6. Fields, pills and errors        12. Route-only copy, no-JS, header CTA

   The markup's hooks for site.js (initBriefing, initContactForm): .brief-step[data-brief-step], .brief-progress,
   [data-route-choice], [data-route-only], [data-brief-next|prev|submit], .rn-brief-foot[data-last], #briefResult,
   #contactResult. site.js sets .is-leaving (a step on its way out), .rn-brief-stage.is-swapping, .is-out on a form whose
   result box has taken over, the box's data-state and its layers (8), and .rn-brief-result-title (a card's heading: h2 in
   the brief, h3 in the message form). */

/* 1. Page tokens ─────────────────────────────────────────────────────────────────────────────────────────────── */
body.studio-brief-page {
  --bf-card: var(--rn-paper-hi);
  --bf-hair: var(--rn-line-on-paper);
  --bf-ring: rgba(9, 11, 13, 0.12);
  --bf-pill-ring: var(--rn-line-strong-on-paper);
  --bf-field-line: var(--rn-field-line-on-paper);
  --bf-placeholder: var(--rn-placeholder-on-paper);
  --bf-field-line-ink: var(--rn-field-line-on-ink);
  --bf-placeholder-ink: var(--rn-placeholder-on-ink);
  --bf-pill-ring-ink: rgba(241, 242, 239, 0.28);
  --bf-tab-h: 38px;                  /* the step track's pill height (the indicator's caps are this wide) */
  --bf-wrap: min(calc(100% - 2 * var(--rn-gutter)), var(--rn-max));
}

/* 2. Hero ─────────────────────────────────────────────────────────────────────────────────────────────────────
   One statement and the lede beside it, on ink with the hero's faint 88px grid. It stays short so the form starts
   in the first viewport at every size; the old live-read card, route strip and swipe cue are gone. */
.rn-brief-hero {
  position: relative;
  min-height: 0;
  padding: calc(var(--rn-header-clearance) + clamp(36px, 5vw, 80px)) 0 clamp(48px, 6vw, 88px);
  overflow: hidden;
  border-bottom: 0;
  background: var(--rn-ink);
  color: var(--rn-text-on-ink);
}

.rn-brief-hero::before {
  position: absolute;
  inset: 0;
  opacity: 1;
  background-image: linear-gradient(var(--rn-grid-line) 1px, transparent 1px), linear-gradient(90deg, var(--rn-grid-line) 1px, transparent 1px);
  background-position: center top;
  background-size: var(--rn-grid) var(--rn-grid);
  content: "";
  pointer-events: none;
  -webkit-mask-image: linear-gradient(180deg, black 30%, transparent 100%);
  mask-image: linear-gradient(180deg, black 30%, transparent 100%);
}

.rn-brief-hero-grid {
  position: relative;
  display: grid;
  grid-template-areas: "eyebrow eyebrow" "title side";
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  align-items: end;
  gap: 28px clamp(32px, 5vw, 80px);
  width: var(--bf-wrap);
  margin-inline: auto;
}

.rn-brief-eyebrow {
  grid-area: eyebrow;
  color: var(--rn-muted-on-ink);
}

.rn-brief-hero h1 {
  grid-area: title;
  max-width: 12ch;
  margin: 0;
  color: var(--rn-text-on-ink);
  text-wrap: balance;
}

.rn-brief-hero h1 em {
  font-style: normal;
}

.rn-brief-hero-side {
  display: grid;
  grid-area: side;
  gap: 24px;
  justify-items: start;
  padding-bottom: 0.35rem;
}

.rn-brief-lede {
  max-width: 42ch;
  margin: 0;
  color: var(--rn-muted-on-ink);
  font-size: var(--rn-fs-body-lg);
  line-height: var(--rn-lh-body);
  text-wrap: pretty;
}

.rn-brief-time {
  color: var(--rn-muted-on-ink);
  font: 500 var(--rn-fs-label)/1.3 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

/* 3. Workspace and the form card ──────────────────────────────────────────────────────────────────────────────
   The form (paper-hi, radius 20) leads; the aside sits beside it on desktop and follows it on phones. */
.rn-brief-workspace {
  padding: clamp(32px, 5vw, 72px) 0 var(--rn-section);
  background: var(--rn-paper);
  color: var(--rn-text-on-paper);
}

.rn-brief-grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(300px, 368px);
  align-items: start;
  gap: clamp(24px, 4vw, 56px);
  width: var(--bf-wrap);
  margin-inline: auto;
}

.rn-brief-main {
  min-width: 0;
}

.rn-brief-form {
  position: relative;
  padding: clamp(20px, 3.4vw, 48px);
  overflow: clip;
  overflow-clip-margin: 8px;
  border: 1px solid var(--bf-ring);
  border-radius: var(--rn-radius-card);
  background: var(--bf-card);
  box-shadow: none;
  color: var(--rn-text-on-paper);
}

/* 4. Starting point and progress ──────────────────────────────────────────────────────────────────────────────
   Step 1 shows the starting points as a radio group of pills. Later steps fold them into one status pill with a
   Change button. The step track is the hero's tab row: an ink pill (the indicator) travels to the current step on
   the two-edge spring (site.js briefIndicator), and the step names turn paper where it covers them. Under it, an
   honest count of required answers with a hairline that fills as they are answered. No percentage anywhere. */
.rn-brief-top {
  display: grid;
  gap: 20px;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--bf-hair);
}

.rn-brief-routes[hidden],
.rn-brief-picked[hidden] {
  display: none;
}

.rn-brief-label {
  margin: 0 0 12px;
  color: var(--rn-muted-on-paper);
  font: 500 var(--rn-fs-label)/1.3 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

.rn-brief-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.rn-brief-chip,
.rn-brief-pill > span {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--rn-target);
  padding: 0 18px;
  border: 1px solid var(--bf-pill-ring);
  border-radius: var(--rn-radius-pill);
  background: transparent;
  color: var(--rn-text-on-paper);
  font: 600 0.875rem/1.1 var(--rn-font-body);
  letter-spacing: 0;
  white-space: nowrap;
  transition: background-color var(--rn-dur-snap) var(--rn-ease-snap), border-color var(--rn-dur-snap) var(--rn-ease-snap), color var(--rn-dur-snap) var(--rn-ease-snap);
}

.rn-brief-chip {
  cursor: pointer;
}

.rn-brief-chip[aria-checked="true"],
.rn-brief-pill > input:checked + span,
html[data-brief-preset="ad-audit"] .rn-brief-form:not(.is-ready) [data-route-choice="ad-audit"],
html[data-brief-preset="prototype"] .rn-brief-form:not(.is-ready) [data-route-choice="prototype"],
html[data-brief-preset="brand"] .rn-brief-form:not(.is-ready) [data-route-choice="brand"],
html[data-brief-preset="website"] .rn-brief-form:not(.is-ready) [data-route-choice="website"],
html[data-brief-preset="video"] .rn-brief-form:not(.is-ready) [data-route-choice="video"],
html[data-brief-preset="workshop"] .rn-brief-form:not(.is-ready) [data-route-choice="workshop"] {
  border-color: var(--rn-ink);
  background: var(--rn-ink);
  color: var(--rn-paper);
}

@media (hover: hover) {
  .rn-brief-chip:not([aria-checked="true"]):hover,
  .rn-brief-pill > input:not(:checked):hover + span {
    border-color: var(--rn-ink);
  }
}

.rn-brief-picked {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 12px;
}

.rn-brief-change {
  min-height: var(--rn-target);
  padding: 0 4px;
  border: 0;
  background: none;
  color: var(--rn-text-on-paper);
  font: 600 var(--rn-fs-small)/1 var(--rn-font-body);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  cursor: pointer;
}

.rn-brief-progress {
  display: grid;
  gap: 12px;
}

.rn-brief-track {
  position: relative;
  padding: 3px;
  isolation: isolate;
  border-radius: var(--rn-radius-pill);
  background: var(--rn-paper);
  box-shadow: inset 0 0 0 1px var(--bf-ring);
}

.rn-brief-tabs {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  margin: 0;
  padding: 0;
  list-style: none;
}

/* The legacy .brief-progress span squares (site.css, studio.css) never reach the step names. */
:where(.rn-brief-tabs) span {
  display: inline;
  width: auto;
  height: auto;
  place-items: normal;
  border: 0;
  border-radius: 0;
  background: none;
  color: inherit;
  font: inherit;
}

.rn-brief-tabs > li {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 0;
  height: var(--bf-tab-h);
  margin: 0;
}

.rn-brief-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: var(--rn-muted-on-paper);
  font: 500 var(--rn-fs-label)/1 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
  white-space: nowrap;
}

.rn-brief-tab b {
  font-weight: 500;
}

.rn-brief-tab.is-inv {
  position: absolute;
  z-index: 2;
  inset: 0;
  justify-content: center;
  color: var(--rn-paper);
  opacity: 0;
  pointer-events: none;
}

/* Before site.js runs; after that it sets each label's opacity itself (so a step change restyles less). */
.rn-brief-form:not(.is-ready) .rn-brief-tabs > li[aria-current="step"] > .rn-brief-tab.is-inv {
  opacity: 1;
}

/* A finished step reads in ink with a check where its number was. */
.rn-brief-tabs > li.is-done > .rn-brief-tab:not(.is-inv) {
  color: var(--rn-text-on-paper);
}

.rn-brief-tabs > li.is-done > .rn-brief-tab:not(.is-inv) b {
  display: inline-block;
  width: 10px;
  height: 6px;
  overflow: hidden;
  border-bottom: 1.5px solid currentColor;
  border-left: 1.5px solid currentColor;
  color: inherit;
  font-size: 0;
  transform: translateY(-2px) rotate(-45deg);
}

.rn-brief-ind {
  position: absolute;
  z-index: 1;
  top: 3px;
  bottom: 3px;
  left: 3px;
  width: calc((100% - 6px) / 4);
  pointer-events: none;
}

.rn-brief-ind > i {
  position: absolute;
  top: 0;
  bottom: 0;
  background: var(--rn-ink);
  will-change: transform;
}

.rn-brief-ind > i:first-child,
.rn-brief-ind > i:last-child {
  width: var(--bf-tab-h);
  border-radius: 50%;
}

.rn-brief-ind > i:first-child {
  left: 0;
  clip-path: inset(0 50% 0 0);
}

.rn-brief-ind > i:last-child {
  right: 0;
  clip-path: inset(0 0 0 50%);
}

/* The middle runs 1px under each cap, so no antialiased seam shows where they meet. */
.rn-brief-ind > i:nth-child(2) {
  right: calc(var(--bf-tab-h) / 2 - 1px);
  left: calc(var(--bf-tab-h) / 2 - 1px);
  transform-origin: 0 50%;
}

.rn-brief-count {
  display: flex;
  align-items: center;
  gap: 14px;
  margin: 0;
  color: var(--rn-muted-on-paper);
  font: 500 var(--rn-fs-label)/1.3 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
  white-space: nowrap;
}

.rn-brief-bar {
  position: relative;
  flex: 1;
  height: 2px;
  overflow: hidden;
  border-radius: 2px;
  background: var(--bf-hair);
}

.rn-brief-bar > i {
  position: absolute;
  inset: 0;
  background: var(--rn-ink);
  transform: scaleX(0);
  transform-origin: 0 50%;
  transition: transform var(--rn-dur-ui) var(--rn-ease-ui);
}

/* 5. Steps ──────────────────────────────────────────────────────────────────────────────────────────────────────
   One step shows at a time, and the card is the current step's height. A step that is leaving is taken out of flow
   (.is-leaving: absolute over the stage's top, aria-hidden, no pointer events) while it fades out, so the card takes
   the new step's height in the frame of the tap; meanwhile the stage clips vertically (.is-swapping), so a taller old
   step never spills over the foot. The legacy 420ms CSS entrance is off: site.js animates the change. */
/* The steps share one grid cell. Waiting steps are content-visibility: hidden: skipped, out of the tab order and the
   accessibility tree. site.js renders each one once, invisibly, while the page is idle (.is-warming), so showing it
   later reuses its styles instead of a first style pass over its fields, which the legacy stylesheets make slow on a
   phone (measured at 4x CPU: about a fifth of the cost). It also measures them. On phones only, from the first step
   change (never at load), the stage keeps the tallest step's height (an inline min-height), so Back and Next stay
   under the thumb; wider screens never reserve space, so a short step leaves no empty hole in the card. */
.rn-brief-stage {
  position: relative;
  display: grid;
}

.rn-brief-stage.is-swapping {
  overflow-x: visible;
  overflow-y: clip;
}

/* The exit animation runs over this (it fills nothing), so a finished or cut-short exit rests invisible here until
   site.js clears the class; nothing it leaves behind can hold a step at opacity 0 once it shows again. */
.rn-brief-form .brief-step.is-leaving {
  position: absolute;
  inset: 0 0 auto 0;
  opacity: 0;
}

.rn-brief-form .brief-step {
  display: block;
  grid-area: 1 / 1;
  align-self: start;
  min-width: 0;
  min-height: 0;
  padding: 28px 0 4px;
  animation: none;
}

.rn-brief-form .brief-step:not(.is-active) {
  pointer-events: none;
}

.rn-brief-form .brief-step:not(.is-active, .is-leaving) {
  content-visibility: hidden;
}

.rn-brief-form .brief-step.is-warming:not(.is-active, .is-leaving) {
  content-visibility: visible;
  opacity: 0;
}

@supports not (content-visibility: hidden) {
  .rn-brief-form .brief-step:not(.is-active, .is-leaving) {
    visibility: hidden;
  }
}

/* The route variants are spans; base.css mutes an H2's direct spans (its emphasis pattern), which these are not. */
.rn-brief-form .brief-step h2 > span {
  color: inherit;
}

.rn-brief-form .brief-step h2 {
  max-width: 24ch;
  margin: 0 0 24px;
  color: var(--rn-text-on-paper);
  font-family: var(--rn-font-display);
  font-size: var(--rn-fs-h2-sm);
  font-weight: var(--rn-weight-display);
  line-height: 1.02;
  letter-spacing: var(--rn-track-display);
  text-wrap: balance;
}

/* 6. Fields, pills and errors ──────────────────────────────────────────────────────────────────────────────────
   Underline fields (radius 0) with a 13px label above and a muted hint under it. Focus is ink: the underline
   thickens and the site's ring sits 4px out. An error turns the underline red and puts red text (#c8352c, 4.7:1 on
   white) under the field; it is linked by aria-describedby and clears once the answer is good. */
.rn-brief-fields {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 24px 20px;
}

.rn-brief-field {
  display: grid;
  align-content: start;
  gap: 6px;
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
}

.rn-brief-field.is-wide {
  grid-column: 1 / -1;
}

.rn-brief-field > label,
.rn-brief-field > legend {
  padding: 0;
  color: var(--rn-text);
  font: 600 0.875rem/1.35 var(--rn-font-body);
  letter-spacing: 0;
}

.rn-brief-pills > legend {
  float: left;
  width: 100%;
  margin-bottom: 10px;
}

.rn-brief-pills > legend + * {
  clear: both;
}

.rn-brief-opt {
  margin-left: 6px;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
  white-space: nowrap;
}

.rn-brief-hint {
  margin: 0;
  color: var(--rn-muted);
  font-size: var(--rn-fs-small);
  line-height: 1.45;
}

.rn-brief-field :is(input:not([type="radio"]), select, textarea) {
  display: block;
  width: 100%;
  min-height: 48px;
  margin: 0;
  padding: 10px 0;
  border: 0;
  border-bottom: 1px solid var(--bf-field-line);
  border-radius: var(--rn-radius-input);
  outline-offset: 4px;
  background: transparent;
  box-shadow: none;
  color: var(--rn-text);
  font: 400 1rem/1.5 var(--rn-font-body);
  transition: border-color var(--rn-dur-snap) var(--rn-ease-snap), box-shadow var(--rn-dur-snap) var(--rn-ease-snap);
}

.rn-brief-field textarea {
  min-height: 116px;
  resize: vertical;
}

.rn-brief-field select {
  padding-right: 28px;
  appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1.5l5 5 5-5' fill='none' stroke='%23090b0d' stroke-width='1.6'/%3E%3C/svg%3E");
  background-position: right 4px center;
  background-repeat: no-repeat;
  background-size: 12px 8px;
  cursor: pointer;
}

.rn-brief-field :is(input, textarea)::placeholder {
  color: var(--bf-placeholder);
  opacity: 1;
}

.rn-brief-field :is(input:not([type="radio"]), select, textarea):focus {
  border-bottom-color: var(--rn-text);
  box-shadow: 0 1px 0 var(--rn-text);
}

.rn-brief-field :is(input:not([type="radio"]), select, textarea):focus-visible {
  outline: 2px solid var(--rn-text);
  outline-offset: 4px;
  box-shadow: 0 1px 0 var(--rn-text);
}

.rn-brief-pill-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.rn-brief-pill {
  position: relative;
  display: inline-flex;
  max-width: 100%;
}

.rn-brief-pill > input {
  position: absolute;
  z-index: 1;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.rn-brief-pill > input:focus-visible + span {
  outline: var(--rn-focus-outline);
  outline-offset: var(--rn-focus-offset);
  box-shadow: var(--rn-focus-band);
}

.field-error {
  margin: 2px 0 0;
  color: var(--rn-red-text);
  font: 600 var(--rn-fs-small)/1.4 var(--rn-font-body);
}

.rn-brief-field.is-invalid :is(input:not([type="radio"]), select, textarea) {
  border-bottom-color: var(--rn-red);
  box-shadow: 0 1px 0 var(--rn-red);
}

.rn-brief-field.is-invalid .rn-brief-pill > input:not(:checked) + span {
  border-color: var(--rn-red);
}

/* 7. Foot: fee guide, trust line, actions ─────────────────────────────────────────────────────────────────────
   The trust line sits right above the buttons. On an audit brief's last step, phones (where the aside comes after
   the form) also get the fee guide there: a guide, never a price list (TOM.md round 4). */
.rn-brief-foot {
  display: grid;
  gap: 16px;
  margin-top: 28px;
  padding-top: 20px;
  border-top: 1px solid var(--bf-hair);
}

.rn-brief-fee {
  display: none;
  max-width: 60ch;
  margin: 0;
  color: var(--rn-text);
  font-size: 0.9375rem;
  line-height: 1.5;
}

.rn-brief-trust {
  max-width: 62ch;
  margin: 0;
  color: var(--rn-muted);
  font-size: var(--rn-fs-small);
  line-height: 1.5;
}

.rn-brief-trust a,
.rn-brief-contact-mail a {
  color: var(--rn-text);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}

.rn-brief-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  padding: 0;
  border: 0;
}

.rn-brief-actions [data-brief-prev] {
  margin-right: auto;
}

/* Send only on the last step, Next only before it; Back keeps its slot on step 1 but is hidden. site.js sets
   data-last on the foot rather than a class on the form, so a step change restyles the foot, not the whole form.
   hotfix.css 3 still hides Send unless the form has the old .is-final class, so the Send rule outranks it (0,6,1 over
   0,5,1); that section can go in 4-consolidation. */
.rn-brief-foot[data-last="false"] [data-brief-submit],
.rn-brief-foot[data-last="true"] [data-brief-next] {
  display: none;
}

body.studio-brief-page .rn-brief-form > .rn-brief-foot[data-last="true"] .rn-brief-actions > [data-brief-submit] {
  display: inline-flex;
}

/* On step 1 Back keeps its slot but is hidden; it does not fade in from the disabled opacity. */
.rn-brief-actions [data-brief-prev]:disabled {
  visibility: hidden;
  opacity: 1;
}

@media (hover: hover) and (prefers-reduced-motion: no-preference) {
  .rn-brief-actions [data-brief-prev]:hover > [aria-hidden="true"] {
    transform: translateX(-3px);
  }
}

/* 8. Result box ─────────────────────────────────────────────────────────────────────────────────────────────────
   The moment Send is pressed the form keeps only its result box (.is-out), and the box already holds every outcome,
   stacked in one grid cell: the "Sending" pill where the toast will sit, the sent card and the error card. The cell is
   the taller card's height from that first frame, inside the press's input window, so a reply that takes seconds
   changes nothing but opacity and transforms (site.js briefDeliver). data-state shows one of them; the others keep
   their room, unseen. Sent: a toast with the hero's check, the heading (focused), the email the reply goes to and what
   happens next (the message form: what was sent). Error: the reason by a red bar, Try again, Edit my answers, Copy my
   answers (the brief only) and the fallback email, then as much of the answers as fits. */
.rn-brief-result[hidden] {
  display: none;
}

.rn-brief-result {
  display: grid;
}

.rn-brief-result > * {
  grid-area: 1 / 1;
  min-width: 0;
}

.rn-brief-form.is-out :is(.rn-brief-top, .rn-brief-stage, .rn-brief-foot),
.rn-brief-contact-form.is-out :is(.rn-brief-fields, .rn-brief-foot) {
  display: none;
}

.rn-brief-result[data-state="sending"] > .rn-brief-layer,
.rn-brief-result[data-state="sent"] > [data-layer="error"],
.rn-brief-result[data-state="error"] > [data-layer="sent"],
.rn-brief-result:not([data-state="sending"]) > .rn-brief-pending {
  visibility: hidden;
}

.rn-brief-layer {
  display: grid;
  align-content: start;
  justify-items: start;
  gap: 14px;
}

/* Sending: the toast's shape as a ring, with the hero's loader arc (two beats a turn) where the check will be drawn. */
.rn-brief-pending {
  display: inline-flex;
  align-items: center;
  align-self: start;
  justify-self: start;
  gap: 10px;
  min-height: 44px;
  margin: 0;
  padding: 0 18px 0 14px;
  border-radius: var(--rn-radius-pill);
  box-shadow: inset 0 0 0 1px var(--bf-pill-ring);
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

.rn-brief-pending:focus {
  outline: 0;
}

.rn-brief-pending:focus-visible {
  outline: 2px solid var(--rn-text);
  outline-offset: 4px;
}

.rn-brief-spin {
  display: block;
  flex: none;
  width: 16px;
  height: 16px;
  border: 1.5px solid color-mix(in srgb, currentColor 28%, transparent);
  border-top-color: var(--rn-text);
  border-radius: 50%;
}

.rn-brief-result[data-state="sending"] .rn-brief-spin {
  animation: rn-brief-spin 1111ms linear infinite;
}

@keyframes rn-brief-spin {
  to {
    transform: rotate(360deg);
  }
}

.rn-brief-result-title {
  margin: 6px 0 0;
  color: var(--rn-text);
  font: var(--rn-weight-title) var(--rn-fs-h3)/1.15 var(--rn-font-body);
  letter-spacing: var(--rn-track-title);
}

.rn-brief-result-title:focus:not(:focus-visible) {
  outline: 0;
  box-shadow: none;
}

/* Focus moves here after a send; from the keyboard it shows as a soft ring rather than a hard box. */
.rn-brief-result-title:focus-visible {
  border-radius: 6px;
  outline: 2px solid var(--rn-text);
  outline-offset: 6px;
  box-shadow: none;
}

.rn-brief-result p {
  max-width: 56ch;
  margin: 0;
  color: var(--rn-muted);
  line-height: 1.55;
}

.rn-brief-result-lead strong {
  color: var(--rn-text);
  font-weight: 600;
  overflow-wrap: anywhere;
}

.rn-brief-result .rn-actions {
  margin-top: 6px;
}

/* The message form's sent card shows what went: the subject and the message, two lines at most. */
.rn-brief-recap {
  display: grid;
  gap: 6px;
  width: 100%;
  margin-top: 4px;
  padding: 2px 0 2px 16px;
  box-shadow: inset 1px 0 0 var(--rn-line);
}

.rn-brief-result p.rn-brief-recap-label {
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1.3 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

.rn-brief-result p.rn-brief-recap-text {
  display: -webkit-box;
  overflow: hidden;
  color: var(--rn-text);
  overflow-wrap: anywhere;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 2;
  line-clamp: 2;
}

/* The error card: its head (marked by the red bar of the form's errors) at its own height, then a look at the answers
   in whatever room the sent card leaves. The look is a size container, so it adds nothing to the box's height: it
   fills the rest (flex 1 from 0), fades at the foot and is left out when there is room for less than a few lines. */
.rn-brief-failed {
  display: flex;
  flex-direction: column;
  gap: 28px;
}

.rn-brief-failed-head {
  display: grid;
  justify-items: start;
  gap: 14px;
  padding-left: 20px;
  box-shadow: inset 3px 0 0 var(--rn-red);
}

.rn-brief-peek {
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
  container-type: size;
  -webkit-mask-image: linear-gradient(black calc(100% - 56px), transparent);
  mask-image: linear-gradient(black calc(100% - 56px), transparent);
}

.rn-brief-peek-in {
  display: grid;
  gap: 10px;
  padding-top: 18px;
  border-top: 1px solid var(--rn-line);
}

@container (max-height: 96px) {
  .rn-brief-peek-in {
    display: none;
  }
}

.rn-brief-peek-list {
  display: grid;
  gap: 12px;
  margin: 0;
}

.rn-brief-peek-list dt {
  color: var(--rn-muted);
  font-size: var(--rn-fs-small);
  line-height: 1.4;
}

.rn-brief-peek-list dd,
.rn-brief-result p.rn-brief-peek-text {
  margin: 0;
  color: var(--rn-text);
  font-size: 0.9375rem;
  line-height: 1.5;
  overflow-wrap: anywhere;
  white-space: pre-line;
}

.rn-brief-failed .rn-brief-result-title {
  margin-top: 0;
  font-size: var(--rn-fs-title);
}

.rn-brief-reason strong {
  color: var(--rn-text);
  font-weight: 600;
}

.rn-brief-copied:empty {
  display: none;
}

.rn-brief-copied {
  color: var(--rn-text) !important;
  font-size: var(--rn-fs-small);
}

.rn-brief-toast {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 18px 0 8px;
  border-radius: var(--rn-radius-pill);
  background: var(--rn-text);
  color: var(--rn-on-text) !important;
  font: 500 var(--rn-fs-label)/1 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

.rn-brief-check {
  position: relative;
  display: inline-grid;
  flex: none;
  place-items: center;
  width: 28px;
  height: 28px;
  overflow: hidden;
  border-radius: 50%;
  background: var(--rn-on-text);
  color: var(--rn-text);
}

.rn-brief-check svg {
  display: block;
  width: 28px;
  height: 28px;
}

/* The cover the check is drawn from (ran-morph.js checkCover): at rest it has slid off. */
.rn-brief-check > i {
  position: absolute;
  inset: 6px;
  background: var(--rn-on-text);
  transform: scaleX(0);
  transform-origin: 100% 50%;
}

.rn-brief-next {
  display: grid;
  width: 100%;
  margin: 6px 0 0;
  padding: 0;
  border-top: 1px solid var(--rn-line);
  list-style: none;
}

.rn-brief-next > li {
  display: grid;
  grid-template-columns: 36px minmax(0, 1fr);
  gap: 12px;
  padding: 16px 0;
  border-bottom: 1px solid var(--rn-line);
}

.rn-brief-next b {
  padding-top: 3px;
  color: var(--rn-muted);
  font: 500 var(--rn-fs-label)/1.4 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
}

.rn-brief-next p {
  display: grid;
  gap: 4px;
}

.rn-brief-next strong {
  color: var(--rn-text);
  font: 700 1rem/1.35 var(--rn-font-body);
}

.rn-brief-next span {
  font-size: 0.9375rem;
}

/* 9. Aside ──────────────────────────────────────────────────────────────────────────────────────────────────────
   "How this works" is an ink card (ink-soft, the 1px ring, the faint grid): the real flow (an audit: brief → discovery
   call → quote → the audit; a project: brief → my reply → the first version → the work), the current stage marked by
   a paper dot in a paper ring (never red). It is a labelled group, not an <aside>: a complementary landmark may not
   sit inside <main>. "Where I'd start" is a
   paper card that follows the route. Beside the form on desktop, after it on phones. It is sticky only where the
   whole of it fits under the header (up to 833px tall, at 1024-1180px wide on the audit route, plus the 116px
   clearance); on a laptop a stuck aside would hold "Where I'd start" below the fold, so there it scrolls with the
   form. */
.rn-brief-aside {
  position: sticky;
  top: calc(var(--rn-header-clearance) + 4px);
  display: grid;
  gap: 16px;
  min-width: 0;
}

@media (max-height: 960px) {
  .rn-brief-aside {
    position: static;
  }
}

.rn-brief-how {
  position: relative;
  padding: 24px;
  overflow: hidden;
  isolation: isolate;
  border-radius: var(--rn-radius-card);
  background: var(--rn-ink-soft);
  box-shadow: inset 0 0 0 1px var(--rn-ring);
  color: var(--rn-text-on-ink);
}

.rn-brief-how::before {
  position: absolute;
  z-index: -1;
  inset: 0;
  background-image: linear-gradient(var(--rn-grid-line) 1px, transparent 1px), linear-gradient(90deg, var(--rn-grid-line) 1px, transparent 1px);
  background-size: var(--rn-grid) var(--rn-grid);
  content: "";
}

.rn-brief-how-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}

.rn-brief-how .rn-chip.is-status {
  border-color: var(--rn-ring);
  color: var(--rn-text-on-ink);
}

.rn-brief-how-list {
  position: relative;
  display: grid;
  margin: 0;
  padding: 0;
  list-style: none;
}

.rn-brief-how-list::before {
  position: absolute;
  top: 22px;
  bottom: 22px;
  left: 9.5px;
  width: 1px;
  background: var(--rn-ring);
  content: "";
}

.rn-brief-how-list > li {
  display: grid;
  grid-template-columns: 20px 26px minmax(0, 1fr);
  gap: 0 10px;
  padding: 12px 0;
}

.rn-brief-how-mark {
  position: relative;
  display: grid;
  place-items: center;
  width: 20px;
  height: 20px;
}

.rn-brief-how-mark::before {
  width: 7px;
  height: 7px;
  border-radius: 50%;
  background: var(--rn-ink-soft);
  box-shadow: inset 0 0 0 1.5px var(--rn-muted-on-ink), 0 0 0 4px var(--rn-ink-soft);
  content: "";
}

.rn-brief-how-list > li[aria-current="step"] .rn-brief-how-mark::before {
  width: 8px;
  height: 8px;
  background: var(--rn-paper);
  box-shadow: 0 0 0 4px var(--rn-ink-soft), 0 0 0 5.5px var(--rn-paper);
}

.rn-brief-how-list > li.is-done .rn-brief-how-mark::before {
  width: 9px;
  height: 5px;
  border-bottom: 1.5px solid var(--rn-paper);
  border-left: 1.5px solid var(--rn-paper);
  border-radius: 0;
  background: none;
  box-shadow: 0 0 0 5px var(--rn-ink-soft);
  transform: translateY(-1px) rotate(-45deg);
}

.rn-brief-how-list b {
  padding-top: 3px;
  color: var(--rn-muted-on-ink);
  font: 500 var(--rn-fs-label)/1.4 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
}

.rn-brief-how-list p {
  display: grid;
  gap: 2px;
  margin: 0;
}

.rn-brief-how-list strong {
  color: var(--rn-text-on-ink);
  font: 600 0.9375rem/1.4 var(--rn-font-body);
}

.rn-brief-how-list p > span {
  color: var(--rn-muted-on-ink);
  font-size: var(--rn-fs-small);
  line-height: 1.5;
}

/* Once the brief is sent, "You’re here." goes but keeps its line: the aside may be on screen when a slow reply lands. */
[data-brief-how-note].is-past {
  visibility: hidden;
}

.rn-brief-read {
  padding: 24px;
  border-radius: var(--rn-radius-card);
  background: var(--bf-card);
  box-shadow: inset 0 0 0 1px var(--bf-ring);
  color: var(--rn-text-on-paper);
}

.rn-brief-read .rn-eyebrow {
  color: var(--rn-muted-on-paper);
}

.rn-brief-read-route {
  margin: 12px 0 6px;
  color: var(--rn-text-on-paper);
  font: var(--rn-weight-title) var(--rn-fs-title)/var(--rn-lh-title) var(--rn-font-body);
  letter-spacing: var(--rn-track-title);
}

.rn-brief-read-move {
  margin: 0;
  color: var(--rn-muted-on-paper);
  font-size: 0.9375rem;
  line-height: 1.55;
}

.rn-brief-read-list {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 16px 0 0;
  padding: 0;
  list-style: none;
}

.rn-brief-read-list > li {
  padding: 7px 11px;
  border-radius: var(--rn-radius-pill);
  box-shadow: inset 0 0 0 1px var(--bf-ring);
  color: var(--rn-text-on-paper);
  font: 500 var(--rn-fs-label)/1 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

.rn-brief-read-next {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 4px 16px;
  margin: 18px 0 0;
  padding-top: 14px;
  border-top: 1px solid var(--bf-hair);
}

.rn-brief-read-next dt {
  color: var(--rn-muted-on-paper);
  font: 500 var(--rn-fs-label)/1.3 var(--rn-font-mono);
  letter-spacing: var(--rn-track-label);
  text-transform: uppercase;
}

.rn-brief-read-next dd {
  margin: 0;
  color: var(--rn-text-on-paper);
  font: 600 0.875rem/1.35 var(--rn-font-body);
}

/* 10. Message form (ink) ───────────────────────────────────────────────────────────────────────────────────────
   The short route: an ink-soft card with the same fields and pills, inverted. Errors on ink use #ff4e45 (5.6:1 on
   ink-soft); #c8352c would fail there. */
.rn-brief-contact {
  padding: var(--rn-section) 0;
  border: 0;
  background: var(--rn-ink);
  color: var(--rn-text-on-ink);
}

.rn-brief-contact-grid {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: start;
  gap: clamp(32px, 5vw, 80px);
  width: var(--bf-wrap);
  margin-inline: auto;
}

.rn-brief-contact-copy h2 {
  max-width: 12ch;
  margin: 16px 0 0;
  color: var(--rn-text-on-ink);
  font-size: var(--rn-fs-h2-sm);
  text-wrap: balance;
}

.rn-brief-contact-copy p:not(.rn-eyebrow) {
  max-width: 40ch;
  margin: 16px 0 0;
  color: var(--rn-muted-on-ink);
  font-size: var(--rn-fs-body-lg);
  line-height: var(--rn-lh-body);
}

.rn-brief-contact-copy .rn-eyebrow {
  color: var(--rn-muted-on-ink);
}

.rn-brief-contact-mail a {
  overflow-wrap: anywhere;
}

.rn-brief-contact-form {
  padding: clamp(20px, 3vw, 36px);
  border-radius: var(--rn-radius-card);
  background: var(--rn-ink-soft);
  box-shadow: inset 0 0 0 1px var(--rn-ring);
  color: var(--rn-text-on-ink);
}

.rn-brief-contact-form .rn-brief-field :is(input:not([type="radio"]), select, textarea) {
  border-bottom-color: var(--bf-field-line-ink);
}

.rn-brief-contact-form .rn-brief-field :is(input, textarea)::placeholder {
  color: var(--bf-placeholder-ink);
}

.rn-brief-contact-form .rn-brief-pill > span {
  border-color: var(--bf-pill-ring-ink);
  color: var(--rn-text-on-ink);
}

.rn-brief-contact-form .rn-brief-pill > input:checked + span {
  border-color: var(--rn-paper);
  background: var(--rn-paper);
  color: var(--rn-ink);
}

@media (hover: hover) {
  .rn-brief-contact-form .rn-brief-pill > input:not(:checked):hover + span {
    border-color: var(--rn-paper);
  }
}

/* On ink the site ring's ink half disappears: the ring is paper here. */
.rn-brief-contact-form .rn-brief-field :is(input:not([type="radio"]), select, textarea):focus-visible {
  outline-color: var(--rn-paper);
  box-shadow: 0 1px 0 var(--rn-paper);
}

.rn-brief-contact-form .rn-brief-pill > input:focus-visible + span,
.rn-brief-contact-form :is(a, button):focus-visible {
  outline-color: var(--rn-paper);
  box-shadow: 0 0 0 2px var(--rn-ink);
}

.rn-brief-contact-form .field-error {
  color: var(--rn-red);
}

.rn-brief-contact-form .rn-brief-pending {
  box-shadow: inset 0 0 0 1px var(--bf-pill-ring-ink);
}

.rn-brief-contact-form .rn-brief-pending:focus-visible {
  outline-color: var(--rn-paper);
}

/* 11. Motion ────────────────────────────────────────────────────────────────────────────────────────────────────
   site.js drives the indicator, the step change and the landing with WAAPI and skips them when RNMotion.isStill();
   the answer bar and the sending arc are CSS, and stop here. */
@media (prefers-reduced-motion: reduce) {
  .rn-brief-bar > i,
  .rn-brief-chip,
  .rn-brief-pill > span,
  .rn-brief-field :is(input, select, textarea) {
    transition: none;
  }

  .rn-brief-result[data-state="sending"] .rn-brief-spin {
    animation: none;
  }
}

html[data-motion="paused"] .rn-brief-bar > i {
  transition: none;
}

/* 12. Route-only copy, no-JS, the header CTA ────────────────────────────────────────────────────────────────────
   Copy and questions that belong to one route carry data-route-only; brief-route.js sets the route on <html> before
   the page paints, so the right variant shows from the first frame (site.js also disables the other route's
   questions). Without JavaScript the forms can't send, so they give way to the email address. */
[data-route-only][hidden],
html[data-initial-brief-route="ad-audit"] [data-route-only="project"],
html:not([data-initial-brief-route="ad-audit"]) [data-route-only="ad-audit"] {
  display: none !important; /* stylelint-disable-line declaration-no-important -- a hiding utility beats every display rule */
}

.rn-brief-nojs {
  display: none;
}

html:not(.js) .rn-brief-nojs {
  display: block;
  margin: 0;
  padding: 24px;
  border-radius: var(--rn-radius-card);
  background: var(--bf-card);
  box-shadow: inset 0 0 0 1px var(--bf-ring);
  color: var(--rn-text-on-paper);
}

html:not(.js) .rn-brief-contact .rn-brief-nojs {
  background: var(--rn-ink-soft);
  box-shadow: inset 0 0 0 1px var(--rn-ring);
  color: var(--rn-text-on-ink);
}

html:not(.js) .rn-brief-nojs a {
  color: inherit;
}

html:not(.js) :is(.rn-brief-form, .rn-brief-contact-form) {
  display: none;
}

/* On the audit route the header's "Brief an audit" is the current page: it wears the header's current-page pill
   (ink-soft with the ring) instead of the paper fill. */
body.studio-brief-page .nav-action[aria-current="page"] {
  background: var(--rn-ink-soft);
  box-shadow: inset 0 0 0 1px var(--rn-ring);
  color: var(--rn-text-on-ink);
}

body.studio-brief-page .nav-action[aria-current="page"]:is(:hover, :focus-visible) {
  background: var(--rn-paper);
  box-shadow: none;
  color: var(--rn-ink);
}

/* Responsive ────────────────────────────────────────────────────────────────────────────────────────────────── */
@media (max-width: 1180px) {
  .rn-brief-grid {
    grid-template-columns: minmax(0, 1fr) minmax(280px, 320px);
  }
}

@media (max-width: 900px) {
  .rn-brief-hero-grid {
    grid-template-areas: "eyebrow" "title" "side";
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
  }

  .rn-brief-hero h1 {
    max-width: 14ch;
  }

  .rn-brief-grid,
  .rn-brief-contact-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .rn-brief-aside {
    position: static;
  }

  .rn-brief-foot[data-last="true"] .rn-brief-fee {
    display: block;
  }
}

@media (max-width: 640px) {
  .rn-brief-hero {
    padding-top: calc(var(--rn-header-clearance) + 24px);
    padding-bottom: 40px;
  }

  .rn-brief-hero-side {
    gap: 20px;
  }

  .rn-brief-workspace {
    padding-top: 20px;
  }

  .rn-brief-fields {
    grid-template-columns: minmax(0, 1fr);
    gap: 20px;
  }

  .rn-brief-form .brief-step {
    padding-top: 24px;
  }

  .rn-brief-top {
    gap: 16px;
    padding-bottom: 20px;
  }

  .rn-brief-chips {
    gap: 6px;
  }

  .rn-brief-chip {
    padding: 0 15px;
  }

  .rn-brief-actions {
    justify-content: space-between;
  }

  .rn-brief-how,
  .rn-brief-read {
    padding: 20px;
  }
}

@media (max-width: 400px) {
  .rn-brief-tab b {
    display: none;
  }

  .rn-brief-tabs > li.is-done > .rn-brief-tab:not(.is-inv) b {
    display: inline-block;
  }
}
