/* ============================================================
   Resonance — the Fast Friends room (WO9, + the August fix batch).
   One page per pair, reached from the match card, the person page
   and the message thread. Sits on assets/style.css + member.css and
   speaks the July 29 mockup's vocabulary (mockups/mockup-fast-friends
   .html): a charcoal night-sky room at the top, dealt questions as
   quoted cards, a sealed amber waiting state, and the reveal — two
   answers side by side under one question.

   THE FIX BATCH added: the any-two-of-three cues, hearts per answer,
   the round's chat, the loud Two of You card, and one pulse rule
   (.ff-pulse) for everything that is actually new — Matt, August:
   "stop being so quiet with everything". The retired trade's styles
   went out with the mechanic.

   Phone first: the primary review target is 390px wide. The reveal
   opens into two columns from 720px up, exactly as the mockup does.
   No counts, no meters, no scores anywhere in this file.
   ============================================================ */

.ff-wrap { max-width: 960px; margin: 0 auto; padding: 0 20px 70px; }

/* ---------- the room: two people, one dark sky ---------- */
.ff-room { position: relative; overflow: hidden; margin-top: 22px; border-radius: 24px; background: var(--charcoal); color: var(--white); border: 1px solid rgba(255,253,248,.07); box-shadow: 0 24px 58px rgba(20,20,20,.30); }
.ff-room::before { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(110% 100% at 74% 12%, rgba(240,166,60,.17) 0%, rgba(240,166,60,.05) 36%, rgba(20,20,20,0) 70%); }
.ff-room::after { content: ""; position: absolute; inset: 0; pointer-events: none; background: radial-gradient(150% 130% at 50% 120%, rgba(0,0,0,.5) 0%, rgba(0,0,0,0) 60%); }
.ff-sky { position: absolute; inset: 0; z-index: 1; pointer-events: none; }
.ff-sky i { position: absolute; border-radius: 50%; background: rgba(255,253,248,.55); }
.ff-room-inner { position: relative; z-index: 2; padding: 30px 22px 26px; }
.ff-room h1 { color: var(--white); font-size: clamp(1.8rem, 7vw, 2.7rem); margin-bottom: 4px; }
.ff-room .ff-sub { font-family: var(--font-display); font-style: italic; font-size: 1.05rem; color: rgba(240,166,60,.92); }
.ff-room .ff-line { margin-top: 14px; color: rgba(255,253,248,.66); font-size: .95rem; max-width: 52ch; }
.ff-faces { display: flex; align-items: center; margin-bottom: 16px; }
.ff-face { width: 54px; height: 54px; border-radius: 50%; flex: none; display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-size: 1.4rem; color: #fff; box-shadow: 0 0 0 3px rgba(20,20,20,.9), 0 10px 26px rgba(0,0,0,.5); }
.ff-face.me { background: linear-gradient(150deg, #6A6350, #211D16); }
.ff-face.them { background: var(--ff-them-face, radial-gradient(circle at 34% 28%, #E0A183 0%, #C4744F 55%, #8E4A2B 100%)); margin-left: -14px; }
.ff-roomlinks { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 18px; }
/* WO99 (#43) — THE ROOM'S FOOTER ROW REACHES 44px. R3 measured this row at 18px: it is a
   line of pills at the bottom of the dark room header carrying "Message <them>", "Your
   network" and, for an invitee, the accept. 7px of padding on a 13px line came to 35px. The
   pills are the same pills — same radius, same hairline, same colour, same words — with
   twelve pixels of vertical padding and a floor under them, and they centre their own label
   so nothing moves sideways.
   WO272 (August 16 2026) CHANGED THE SECOND PILL'S WORDS AND NOTHING ELSE ABOUT THIS ROW:
   "Your network" is "Get Shared Reports" now (assets/fast-friends.js, roomHTML). It is the
   same <a> in the same flex row, so the 44px floor above is untouched and still the measured
   one — the row wraps at 390px exactly as it did, because that is what `flex-wrap` is for. */
.ff-roomlinks a { font-size: .84rem; font-weight: 600; padding: 12px 15px; border-radius: 999px; border: 1.5px solid rgba(255,253,248,.18); color: rgba(255,253,248,.74); text-decoration: none;
  display: inline-flex; align-items: center; min-height: 44px; }
.ff-roomlinks a:hover { border-color: var(--orange); color: var(--orange); text-decoration: none; }
.ff-roomlinks a:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); }

/* ---------- round banding ---------- */
.ff-round { margin-top: 34px; }
.ff-roundhead { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; margin-bottom: 12px; }
.ff-roundhead .n { font-family: var(--font-display); font-size: .8rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--orange-deep); }
.ff-roundhead .t { font-family: var(--font-display); font-size: 1.26rem; font-weight: 600; }
.ff-rule { height: 1px; background: linear-gradient(to right, rgba(33,29,22,.16), rgba(33,29,22,0)); margin-bottom: 20px; }
.ff-note { font-size: .9rem; color: var(--ink-soft); max-width: 58ch; margin-bottom: 18px; }

/* ---------- the dealt hand, and the private composer ---------- */
.ff-hand { display: grid; gap: 14px; }
.ff-q { position: relative; background: var(--white); border-radius: 18px; border: 1px solid rgba(33,29,22,.07); box-shadow: var(--shadow); padding: 20px 18px 16px; }
.ff-qmark { font-family: var(--font-display); font-size: 2.6rem; line-height: .6; height: .5em; color: rgba(240,166,60,.45); margin-bottom: 14px; }
.ff-qtext { font-family: var(--font-display); font-size: 1.12rem; line-height: 1.34; color: var(--ink); max-width: 34ch; }
.ff-compose { margin-top: 14px; }
.ff-compose textarea { width: 100%; font: inherit; font-size: 1rem; line-height: 1.6; color: var(--ink); background: var(--cream); border: 1.5px solid rgba(33,29,22,.14); border-radius: 14px; padding: 12px 14px; min-height: 108px; resize: vertical; }
.ff-compose textarea:focus { outline: none; border-color: var(--orange); box-shadow: 0 0 0 4px var(--ring); }
.ff-qfoot { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; margin-top: 12px; padding-top: 12px; border-top: 1px dashed rgba(33,29,22,.12); }
.ff-status { font-size: .82rem; color: #A79E8D; }
.ff-hint { margin-top: 8px; font-size: .86rem; color: var(--orange-deep); }
.ff-hint[hidden] { display: none; }
.ff-cap { margin-top: 8px; font-size: .82rem; color: #A0522D; }
.ff-cap[hidden] { display: none; }


.ff-handfoot { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 18px; }
.ff-handfoot .btn { border: none; cursor: pointer; font: inherit; font-weight: 700; }
.ff-handfoot .btn[disabled] { opacity: .5; cursor: default; box-shadow: none; transform: none; }
.ff-handfoot .btn[disabled]:hover { transform: none; }

/* ---------- sealed: both written, nothing open ---------- */
.ff-waiting { position: relative; overflow: hidden; background: linear-gradient(158deg, #FDF3E4 0%, #FCEBD2 60%, #F8DFBC 100%); border: 1.5px solid rgba(217,142,31,.34); border-radius: 22px; padding: 24px 20px; box-shadow: 0 16px 40px rgba(217,142,31,.14); }
.ff-waiting .inner { display: grid; grid-template-columns: auto 1fr; gap: 18px; align-items: center; }
.ff-sealed { width: 70px; height: 70px; flex: none; border-radius: 20px; background: var(--white); border: 1.5px solid rgba(217,142,31,.3); display: flex; align-items: center; justify-content: center; box-shadow: 0 10px 24px rgba(217,142,31,.16); }
.ff-waiting h3 { font-size: 1.2rem; margin-bottom: 6px; }
.ff-waiting p { color: #6B5F45; font-size: .96rem; max-width: 44ch; }
.ff-waiting .ff-dots { display: inline-flex; gap: 5px; vertical-align: middle; margin-left: 8px; }
.ff-waiting .ff-dots i { width: 6px; height: 6px; border-radius: 50%; background: rgba(217,142,31,.55); display: block; }
.ff-waiting .ff-dots i:nth-child(2) { opacity: .66; }
.ff-waiting .ff-dots i:nth-child(3) { opacity: .36; }
@media (max-width: 560px) { .ff-waiting .inner { grid-template-columns: 1fr; } }

/* ---------- the reveal: the signature moment ---------- */
.ff-revealbar { display: flex; align-items: center; gap: 14px; margin-bottom: 20px; }
.ff-glow { flex: none; width: 40px; height: 40px; border-radius: 50%; background: radial-gradient(circle at 50% 42%, #F7C173 0%, #F0A63C 44%, #D98E1F 74%, #9C6415 100%); box-shadow: 0 0 0 7px rgba(240,166,60,.16), 0 10px 26px rgba(217,142,31,.3); }
.ff-revealbar .txt { font-family: var(--font-display); font-size: 1.08rem; font-style: italic; color: var(--ink); }

.ff-pair { background: var(--white); border-radius: 20px; border: 1px solid rgba(33,29,22,.06); box-shadow: var(--shadow); overflow: hidden; margin-bottom: 16px; }
.ff-ph { padding: 18px 20px 14px; border-bottom: 1px solid rgba(33,29,22,.07); background: linear-gradient(180deg, rgba(252,235,210,.42), rgba(255,253,248,0)); }
.ff-ph .kicker { display: block; margin-bottom: 6px; color: #6E685A; font-size: .74rem; }
.ff-ph .ff-qtext { max-width: 40ch; }
.ff-answers { display: grid; grid-template-columns: 1fr; }
.ff-ans { padding: 18px 20px; }
.ff-ans + .ff-ans { border-top: 1px dashed rgba(33,29,22,.13); }
.ff-ans.me { border-left: 3px solid rgba(33,29,22,.45); }
.ff-ans.them { border-left: 3px solid var(--ff-them, #C4744F); }
.ff-who { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
.ff-who .av { width: 28px; height: 28px; border-radius: 50%; flex: none; display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-size: .84rem; color: #fff; }
.ff-who .av.me { background: linear-gradient(150deg, #6A6350, #211D16); }
.ff-who .av.them { background: var(--ff-them-face, radial-gradient(circle at 34% 28%, #E0A183 0%, #C4744F 60%, #8E4A2B 100%)); }
/* WO123 (finding 4): the miniature profile picture, where there is one — the same
   crop-to-fill rule the room's hero circles keep, at answer size. Initial stays the
   fallback and keeps every rule above. */
.ff-who .av.hasphoto { background: #211D16; overflow: hidden; padding: 0; }
.ff-who .av.hasphoto img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ff-who .nm { font-weight: 700; font-size: .94rem; }
.ff-ans .body { font-size: 1rem; line-height: 1.62; color: var(--ink); overflow-wrap: break-word; }
.ff-ans .body p + p { margin-top: .7em; }
.ff-quietans { font-size: .95rem; color: #A79E8D; font-style: italic; }
@media (min-width: 720px) {
  .ff-answers { grid-template-columns: 1fr 1fr; }
  .ff-ans + .ff-ans { border-top: none; }
}

/* ---------- hearts, per answer ----------
   One heart per member per answer, and only ever on the OTHER person's words — so what it
   says is "this moved me", never "this scored well".

   THE HEART SAYS IT ON ITS OWN (Matt, August 2026). It used to be a heart followed by a
   caption, and a symbol that needs a caption is not doing its job. The control on their
   answer is the glyph and nothing else; under your own answer, a filled heart and the
   name of whoever it moved — the only tally this product has ever allowed. */
.ff-heartrow { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 12px; }
.ff-heart { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; font: inherit; color: #A79E8D; background: transparent; border: 1.5px solid rgba(33,29,22,.14); border-radius: 999px; cursor: pointer; transition: transform .16s, border-color .16s, background .16s; }
.ff-heart:hover { border-color: var(--orange-deep); color: var(--orange-deep); transform: scale(1.06); }
.ff-heart:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); }
.ff-heart[aria-pressed="true"] { background: var(--orange-soft); border-color: rgba(217,142,31,.45); }
.ff-heart .heart { flex: none; }
/* under your OWN answer: not a control, a small piece of good news */
.ff-hearted { display: inline-flex; align-items: center; gap: 8px; font-size: .86rem; font-weight: 700; color: var(--orange-deep); background: var(--orange-soft); border: 1px solid rgba(217,142,31,.34); border-radius: 999px; padding: 5px 14px 5px 12px; }
.ff-hearted .heart { flex: none; }
/* a prompt only one of you took reads as one column ON A PHONE; from 720px it keeps the
   two-column grid and THE ANSWER STAYS IN ITS OWN COLUMN (WO123, finding 5 — Matt: a
   question only one person answered "must NOT span both columns with a big video").
   Sender's content left, receiver's right, exactly as a both-answered prompt sits. The
   nobody-took-this-one line is the exception and spans, because it is one sentence about
   the pair, not one person's answer. */
.ff-pair.solo .ff-answers { grid-template-columns: 1fr; }
.ff-ans.none { padding: 16px 20px; }
@media (min-width: 720px) {
  .ff-pair.solo .ff-answers { grid-template-columns: 1fr 1fr; }
  .ff-pair.solo .ff-ans.me { grid-column: 1; }
  .ff-pair.solo .ff-ans.them { grid-column: 2; }
  .ff-pair.solo .ff-ans.none { grid-column: 1 / -1; }
}

/* THE ROUND-TAG CONTROL ("Say something about this round") — REMOVED BY WO123, August 11
   2026 (finding 7), with the control itself. The chip a tagged line wears (.ff-aboutchip)
   and the tagbar above the composer stay: lines already said about a round keep saying so. */

/* ---------- the pair's ONE conversation, in the room ----------
   Not a second chat: the Messages thread through another door, so it borrows that page's
   own bubbles, composer and Muted marker from messages.css (loaded by fast-friends.html)
   and only the frame around them lives here. */
.ff-chat { background: var(--white); border: 1px solid rgba(33,29,22,.07); border-radius: var(--radius); box-shadow: var(--shadow); margin-top: 30px; overflow: hidden; }
.ff-chathead { display: flex; align-items: center; gap: 10px; padding: 13px 16px; border-bottom: 1px solid rgba(33,29,22,.08); font-size: .72rem; letter-spacing: .13em; text-transform: uppercase; font-weight: 700; color: #6E685A; }
.ff-chathead > span:first-child { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* WO123 (finding 7) — the head's two lines, in Matt's spec: the title at normal size (so
   it escapes the head row's small caps), and under it, small and sans-serif, "Say anything
   you want." The row's own small-caps treatment still styles the Muted word beside it. */
.ff-chathead .ff-chattitle { font-size: 1rem; letter-spacing: 0; text-transform: none;
  color: var(--ink); white-space: normal; }
.ff-chathead .ff-chatsub { display: block; font-family: var(--font-body, inherit);
  font-size: .8rem; font-weight: 400; letter-spacing: 0; text-transform: none;
  color: #8A8177; margin-top: 2px; }
/* WO99 (#43) — "Open in Messages", named in the order as one of the targets under 44px.
   It is the one door out of this room's chat card and it was a 19px line of small caps.
   Padding only: the head row is a flex row with its own 13px of padding, so the card head
   grows by a few pixels and the label stays exactly where it was. */
.ff-chatelse { flex: none; font-size: .72rem; font-weight: 700; letter-spacing: .06em; text-transform: none; color: var(--orange-deep); text-decoration: none;
  display: inline-flex; align-items: center; min-height: 44px; padding: 12px 2px; }
.ff-chatelse:hover { text-decoration: underline; }
.ff-chatscroll { max-height: 420px; min-height: 120px; }
/* the small quiet chip on a line said ABOUT a round */
.ff-aboutchip { display: block; font-size: .68rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 700; margin-bottom: 5px; opacity: .75; }
.msg-bubble.them .ff-aboutchip { color: var(--orange-deep); }
.msg-bubble.mine .ff-aboutchip { color: rgba(240,166,60,.9); }
/* the removable tag above the composer */
.ff-tagbar { display: flex; align-items: center; gap: 8px; padding: 8px 16px; background: var(--orange-soft); border-top: 1px solid rgba(217,142,31,.28); font-size: .84rem; color: #6B5F45; }
.ff-tagbar[hidden] { display: none; }
.ff-tagbar b { color: var(--orange-deep); }
.ff-tagx { margin-left: auto; flex: none; font: inherit; font-size: 1.1rem; line-height: 1; background: none; border: none; cursor: pointer; color: #6E685A; padding: 2px 6px; border-radius: 999px; }
.ff-tagx:hover { color: var(--ink); }
.ff-tagx:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }
.ff-chatcap { padding: 0 16px 10px; font-size: .82rem; color: #A0522D; }
.ff-chatcap[hidden] { display: none; }

/* ---------- WO69 #5: THE ROOM'S SEND, WHEN IT DOES NOT GO ----------
   R6 pressed Send in this box and met a 409 in total silence. The line and the control live
   here now, under the composer, in the same shape and the same words the Messages composer
   uses — one conversation, two doors, one apology. */
.ff-chatnote { margin: 0; padding: 0 16px 12px; font-size: .84rem; color: var(--ink-soft); }
.ff-chatnote[hidden] { display: none; }
.ff-chatretry { font: inherit; font-size: .84rem; font-weight: 700; color: var(--charcoal);
  background: var(--orange); border: none; border-radius: 999px; padding: 5px 13px; cursor: pointer; }
.ff-chatretry:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }
/* the same quiet draft counter the Messages composer carries (#45) — the member's own words,
   nobody else's, amber only in the last hundred characters */
.ff-chatcount { padding: 0 16px 10px; margin-top: -4px; text-align: right;
  font-size: .76rem; color: #A79E8D; font-variant-numeric: tabular-nums; }
.ff-chatcount.near { color: #A0522D; font-weight: 700; }
.ff-chatcount[hidden] { display: none; }
.ff-chatpaste { padding: 0 16px 10px; font-size: .82rem; line-height: 1.5; color: #A0522D; }
.ff-chatpaste[hidden] { display: none; }

/* ---------- the Fast Friends home list (no ?with) ----------
   Rows in the Messages list's shape, because they are the same kind of object: a person,
   and one line saying where the two of you are. Attention rows are lit and come first —
   the endpoint decides both, the page only paints. */
.ff-homehead { padding: 40px 0 6px; max-width: 620px; }
.ff-homehead h1 { font-size: clamp(1.9rem, 6vw, 2.8rem); }
.ff-homehead .lead { margin-top: 12px; font-size: 1.06rem; color: var(--ink-soft); }
.ff-homeempty { margin-top: 26px; background: var(--white); border: 1.5px dashed rgba(33,29,22,.16); border-radius: var(--radius); padding: 24px 22px; color: var(--ink-soft); max-width: 560px; }
.ff-homeempty p { margin: 0 0 14px; }
.ff-homeempty p:last-child { margin: 0; }
.ff-rows { display: flex; flex-direction: column; gap: 10px; margin-top: 26px; max-width: 640px; }
.ff-row { display: flex; align-items: center; gap: 13px; background: var(--white); border: 1px solid rgba(33,29,22,.07); border-left: 3px solid var(--charcoal); border-radius: 14px; padding: 12px 15px; box-shadow: var(--shadow); text-decoration: none; color: var(--ink); transition: transform .18s, box-shadow .18s; }
.ff-row:hover { transform: translateY(-1px); box-shadow: var(--shadow-lg); text-decoration: none; }
.ff-row.hot { border-left-color: var(--orange); background: linear-gradient(180deg, #FFFDF8 0%, #FEF7EA 100%); }
.ff-rowav { flex: none; width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center; justify-content: center; font-family: var(--font-display); font-size: .95rem; color: #fff; background: linear-gradient(150deg, #6A6350, #211D16); }
.ff-row.hot .ff-rowav { background: radial-gradient(circle at 34% 28%, #F7C173, #F0A63C 60%, #B4762A); color: var(--charcoal); }
.ff-rowmain { flex: 1; min-width: 0; }
.ff-rowmain .who { display: block; font-weight: 700; }
.ff-rowmain .line { display: block; font-size: .86rem; color: var(--ink-soft); margin-top: 1px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ff-row.hot .ff-rowmain .line { color: var(--orange-deep); font-weight: 600; }
.ff-rowspark { flex: none; color: var(--orange); font-size: .7rem; }

/* ---------- THE NEXT-ROUND PANEL — RETIRED BY WO123, August 11 2026 (finding 9) ----------
   The charcoal "Ready for another?" card and its .ff-next rules lived here. Matt called it
   "the barely-visible black card at the very end" and ordered it removed; the anchor pills
   below carry the start control now. The .ff-next SELECTOR itself is not dead product-wide:
   the shared layer (style.css) still names it as a known dark ground for the click-flash
   and the WO120 pulse, and those rules stay where they are — only this page's card and its
   styles are gone. */

/* ---------- WO123 — THE TWO ANCHOR SLOTS ----------
   One pill vocabulary for the page's what-to-do-next alerts: slot A directly under the
   dark room header, slot B directly under the newest revealed answers. The pills are the
   rate pill's old shape (44px, orange, pill-radius) so nothing here invents a second
   orange; the pulse is the WO120 shared mechanism, applied per state by fast-friends.js
   and never here. */
.ff-anchor { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.ff-anchor-a { margin: 18px 0 0; }
.ff-anchor-b { margin: 18px 0 4px; }
.ff-anchorpill { display: inline-flex; align-items: center; min-height: 44px; font: inherit;
  font-size: .92rem; font-weight: 700; padding: 11px 22px; border-radius: 999px; border: none;
  background: var(--orange); color: #211D16; cursor: pointer; box-shadow: var(--shadow);
  text-decoration: none; }
.ff-anchorpill:hover { text-decoration: none; }
.ff-anchorpill:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); }
a.ff-anchorpill { color: #211D16; }

.ff-card { background: var(--white); border-radius: var(--radius); border: 1px solid rgba(33,29,22,.06); box-shadow: var(--shadow); padding: 24px 20px; margin-top: 24px; max-width: 640px; }
.ff-card h2 { font-size: clamp(1.4rem, 4.5vw, 1.9rem); margin-bottom: 10px; }
.ff-card p { color: var(--ink-soft); }
.ff-card p + p { margin-top: 12px; }
.ff-card .ff-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 20px; }
.ff-card .ff-actions .btn { border: none; cursor: pointer; font: inherit; font-weight: 700; }
.ff-card .ff-actions .btn[disabled] { opacity: .5; cursor: default; }
/* the invitation's attached question — a hello with a question on it */
.ff-attached { margin-top: 18px; background: linear-gradient(180deg, rgba(252,235,210,.5), rgba(255,253,248,0)); border: 1px solid rgba(217,142,31,.28); border-radius: 16px; padding: 16px 18px; }
.ff-attached .kicker { display: block; margin-bottom: 6px; font-size: .74rem; color: #6E685A; }
.ff-attached .ff-qtext { max-width: 36ch; }

/* dormancy: warm, and never about the other person */
.ff-revive { background: var(--orange-soft); border: 1px solid rgba(217,142,31,.35); border-radius: 16px; padding: 14px 16px; margin-bottom: 18px; font-size: .96rem; color: #6B5F45; max-width: 58ch; }

/* ---------- THE ROUND-ONE NOTE (WO51) — RETIRED BY WO94, August 10 2026 ----------
   `.ff-firstnote` was the round-one restatement of the length advice, and it is one of the
   four copies WO94 (#39) took out: the room says the advice once, in `.ff-floorsays` below,
   which now sits in this position on every round. The rule is kept and empty of nothing —
   it is simply gone, because a class no element carries is a class the next reader will
   spend five minutes looking for. */

/* ---------- THE LENGTH ADVICE, ONCE (WO33 §5, MOVED BY WO94) ----------
   It used to sit inside `.ff-compose`, above each of the three boxes. It sits in the round's
   intro now, above the loud orange "answer any two" bar, and must read as advice rather than
   as a second instruction competing with it — which is exactly the treatment `.ff-firstnote`
   carried, so it inherits that treatment along with the position. */
.ff-floorsays { max-width: 58ch; margin: 0 0 12px; line-height: 1.55; font-size: .9rem;
  color: var(--ink-soft); }

/* ---------- ANY TWO OF THREE (August fix batch) ----------
   The mechanic has to be self-evident before anybody reads a word, so the instruction is
   loud, and a card you have started writing in visibly becomes one of your two. */
.ff-anytwo { background: var(--orange-soft); border: 1px solid rgba(217,142,31,.35); border-radius: 14px; padding: 12px 15px; margin-bottom: 14px; font-size: .97rem; color: #6B5F45; max-width: 58ch; }
.ff-anytwo strong { color: var(--ink); }
.ff-q.ff-chosen { border-color: rgba(217,142,31,.5); box-shadow: 0 0 0 3px rgba(240,166,60,.14), var(--shadow); }
.ff-yours { font-size: .76rem; letter-spacing: .1em; text-transform: uppercase; font-weight: 700; color: var(--orange-deep); }
.ff-yours[hidden] { display: none; }
.ff-theirdone strong { color: var(--ink); }

/* ---------- ATTENTION (Matt, August: stop being so quiet) ----------
   Three pulses on arrival, then still — the same treatment and the same keyframe shape
   the network page's received-hello card uses, and off entirely for anybody who has
   asked their system for less motion. */
@keyframes ff-pulse-ring {
  0%, 100% { box-shadow: 0 0 0 0 rgba(232, 89, 12, 0), var(--shadow); }
  50%      { box-shadow: 0 0 0 5px rgba(232, 89, 12, .5), var(--shadow); }
}
.ff-pulse { animation: ff-pulse-ring 1.2s ease-in-out 3; }
@media (prefers-reduced-motion: reduce) { .ff-pulse { animation: none; } }

/* ---------- WO33: THE FLASHING TEXT VARIANT ----------
   The same discipline for a line of words rather than a card: three beats and then still,
   and under prefers-reduced-motion no movement at all — the emphasis is carried by the
   colour and the weight, which are on the element the whole time and not in the keyframe.
   Principle 19: attention is guided, never assumed, and never on a loop. */
@keyframes ff-pulse-text {
  0%, 100% { opacity: 1; }
  50%      { opacity: .35; }
}
.ff-pulse-text { animation: ff-pulse-text 1.1s ease-in-out 3; }
@media (prefers-reduced-motion: reduce) { .ff-pulse-text { animation: none; } }

/* THE MODALITY NUDGE (WO33 §8), in burnt sienna.
   THE SHADE IS NOT #A0522D. True burnt sienna measures 4.0:1 against the room's card
   cream (#FFFDF8), which fails WCAG 2.2 AA for body text; #8C3F1D is the nearest
   neighbour that clears it (5.6:1) and is what ships. The VPAT work (WO30c) is the
   standing obligation this answers, and Matt is told in the to-do document. */
.ffmode-nudge { margin: 10px 0 2px; color: #8C3F1D; font-weight: 600; font-size: .95rem;
  line-height: 1.45; max-width: 52ch; }

/* THE ONE-TIME COMFORT QUESTION, and the statement it becomes afterwards (WO33 §4) */
.ffopt-once { border-color: rgba(232,89,12,.4); }
.ffopt-later { background: transparent; border: none; box-shadow: none; padding: 0; margin-top: 12px; }
.ffopt-later h3 { font-size: .8rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: #6E685A; margin-bottom: 4px; }
.ffopt-later .ffopt-lead { font-size: .9rem; color: var(--ink-soft); margin: 0; }

/* THE INVITEE'S ACCEPT, IN THE DARK CARD (WO33 §3). It sits in the same row as the two
   links and is styled as one of them, in the orange that means "this is the thing". */
.ff-roomlinks button.ff-roomaccept { font: inherit; font-size: .84rem; font-weight: 700;
  padding: 12px 15px; border-radius: 999px; border: 1.5px solid var(--orange);
  background: var(--orange); color: #211D16; cursor: pointer;
  /* WO99 (#43): the same 44px as the two links it stands beside — it is one of them */
  display: inline-flex; align-items: center; min-height: 44px; }
.ff-roomlinks button.ff-roomaccept:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); }
.ff-passrow { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 22px; }

/* PHOTOGRAPHS IN THE TWO CIRCLES (WO33 §1). Cropped to fill, never distorted; the initial
   remains the fallback and keeps every rule it already had. */
.ff-face.hasphoto { background: #211D16; overflow: hidden; padding: 0; }
.ff-face.hasphoto img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* THE WORD FLOOR, COUNTED LIVE (WO33 §5). The advice itself moved to the round intro with
   WO94 — see `.ff-floorsays` above; the live count stays under the box it is counting. */
.ff-count { margin-top: 8px; font-size: .86rem; min-height: 1.2em; }

/* ---------- WO94 (#12): AN ANSWER THAT DID NOT SAVE ----------
   The same shape and the same treatment `.ff-chatnote` carries under the chat composer, for
   the same reason it does: one apology, one control, in one product. It does not animate and
   it does not move — a member reading "what you wrote is still here" while the page shifts
   under them is being told two different things. */
.ff-savefail { margin: 10px 0 0; font-size: .86rem; color: var(--ink-soft); }
.ff-savefail[hidden] { display: none; }
.ff-saveretry { font: inherit; font-size: .84rem; font-weight: 700; color: var(--charcoal);
  background: var(--orange); border: none; border-radius: 999px; padding: 5px 13px; cursor: pointer; }
.ff-saveretry:focus-visible { outline: none; box-shadow: 0 0 0 3px var(--ring); }
.ff-count.short { color: var(--orange-deep); }
.ff-count.done { color: #4C7A46; }

/* "START NEXT ROUND" (WO33 §7), beside the round's name */
.ff-nextpill { font: inherit; font-size: .82rem; font-weight: 700; padding: 6px 14px;
  border-radius: 999px; border: none; background: var(--orange); color: #211D16;
  cursor: pointer; margin-left: auto; }
.ff-nextpill:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); }
.ff-nextpill.off { background: rgba(33,29,22,.08); color: #7C7466; cursor: default;
  display: inline-flex; align-items: baseline; gap: 8px; }
.ff-nextwhy { font-weight: 500; font-size: .74rem; color: #8B8375; }
/* WO70 #47 — THE REASON IS A CONTROL WHEN THERE IS SOMETHING BEHIND IT.
   "Rate your compatibility first" was a span with nothing wired to it, sitting beside a
   pill that could not be pressed: R8's "looks tappable but is inert". It is a button now,
   and it has to LOOK like one — underlined, in the room's own link colour, and reaching
   4.5:1 where the grey #8B8375 never did. --orange-deep (#B54800) is the same value WO67
   measured at 5.3:1 on cream and is what .ff-blocked's link already uses, so this is the
   room's existing link treatment rather than a second one invented here.
   The other reason — "Once this round has opened" — keeps the grey span, because it is a
   fact about time passing with nothing to open. */
button.ff-nextwhy { font: inherit; font-weight: 600; font-size: .74rem;
  color: var(--orange-deep); background: none; border: none; padding: 0; cursor: pointer;
  text-decoration: underline; text-underline-offset: 3px; }
button.ff-nextwhy:hover { color: var(--ink); }
button.ff-nextwhy:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); border-radius: 6px; }

/* WO70 #12 — THE ROOM THAT WILL NOT OPEN. It used to be six words of body text in #boot
   ("That room is not available.") with nothing under them. It is a card with a way out of
   it now, and the anchor beside the button is the same quiet treatment the room's own
   buttons carry — .ff-quiet was written for <button> and needs one line to sit on an <a>. */
.ff-roomfail { max-width: 520px; margin: 40px auto; }
.ff-roomfail h2 { margin-bottom: 8px; }
.ff-roomfail p { color: var(--ink-soft); }
a.ff-quiet { display: inline-block; text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: rgba(138,130,113,.45); }
a.ff-quiet:hover { color: var(--ink); }

/* "RATE YOUR COMPATIBILITY" (WO33 §12) — SUPERSEDED BY WO123, August 11 2026 (finding 9):
   the rate pill is one of the anchor pills now (.ff-anchorpill above, same shape this rule
   established), drawn in both slots by the state machine, and the card it opens moved to
   just under the top black card. .ff-raterow and .ff-ratepill are drawn by nothing. */
/* `.ff-gatefree` was the gate card's "your Two of You report is not behind this" paragraph.
   WO94 (August 10 2026, #32) took the paragraph out — a gate card should not raise the one
   thing it does not hold in order to deny it — so the rule goes with it. */

/* THE TWO OF YOU, WAITING ON THE SECOND YES (WO33 §11) */
.ff-waitpill { display: inline-block; font-size: .92rem; font-weight: 700; padding: 11px 20px;
  border-radius: 999px; background: rgba(240,166,60,.18); color: #7A5518;
  border: 1.5px solid rgba(217,142,31,.34); }
.ff-bothin { margin: 10px 0; color: var(--ink); font-size: .95rem; }
.ff-report-coming { background: linear-gradient(180deg, #FFFDF8 0%, #FBF6EC 100%); }

/* THE ONE-TIME DESCRIPTION CARD (WO33 §3). No links, no controls — that is the whole
   specification, and it is why this rule has nothing to say about either. */
.ff-introcard { border-top: 3px solid rgba(240,166,60,.5); }

/* WO41 (c)'s first-round depth nudge had its own card here — RETIRED BY WO94, August 10
   2026 (#39). It was one of five printings of the length advice on one screen; the room now
   states that advice once, in the round intro (`.ff-floorsays`). Nothing draws
   `.ff-depthcard` any more, so nothing styles it. */

/* WO33 §6's chat-head round-tag control was removed by WO123 (finding 7); its rules went
   with it — a class no element carries is a class the next reader hunts for. */

/* an invitation waiting on you is the loudest thing this room ever gets */
.ff-invitecard { border-top: 3px solid var(--orange); background: linear-gradient(180deg, #FFFDF8 0%, #FEF7EA 100%); }

/* THE TWO OF YOU, from this room (WO9 g + the fix batch).
   Two shapes for five server states. `locked` is one greyed line — the same promise the
   network page's just-connected banner makes, in the same tone; `available` and
   `update-available` are one card, loud, with a way to say not now; `ready` is the same
   card, calm, with a link; `unavailable` draws nothing at all, so the room never implies
   a door where consent said no. */
.ff-locked { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 26px; max-width: 62ch; font-size: .9rem; line-height: 1.55; color: #6E685A; }
.ff-locked .n-pilltag { font-size: .68rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase; background: #EEE7DC; color: #8A8177; border-radius: 999px; padding: 4px 11px; }
.ff-report { background: linear-gradient(180deg, #FFFDF8 0%, #FEF7EA 100%); border: 1px solid rgba(240,166,60,.4); border-top: 3px solid var(--orange); border-radius: var(--radius); box-shadow: var(--shadow); padding: 24px 20px; margin-top: 30px; max-width: 620px; }
.ff-report .kicker { display: block; }
.ff-report h2 { font-size: clamp(1.35rem, 4.4vw, 1.8rem); margin-bottom: 8px; }
.ff-report p { color: var(--ink-soft); }
.ff-report .ff-actions { display: flex; align-items: center; gap: 14px; flex-wrap: wrap; margin-top: 18px; }
.ff-report .ff-actions .btn { border: none; cursor: pointer; font: inherit; font-weight: 700; text-decoration: none; }
.ff-report .ff-actions .btn[disabled] { opacity: .5; cursor: default; }

/* ---------- the two summit offers (Work Order 10) ----------
   We-met and graduation. Asked once, warmly, and never twice. They share the report
   card's shape so the room has one vocabulary for "here is a moment", and they are
   deliberately NOT pulsed: a barrier is a thing you must do, and these are two things
   you may. */
.ff-met, .ff-grad { background: var(--white); border: 1px solid rgba(33,29,22,.08); border-left: 3px solid var(--orange); border-radius: var(--radius); box-shadow: var(--shadow); padding: 22px 20px; margin-top: 28px; max-width: 620px; }
.ff-met .kicker, .ff-grad .kicker { display: block; }
.ff-met h2, .ff-grad h2 { font-size: clamp(1.3rem, 4.2vw, 1.7rem); margin-bottom: 8px; }
.ff-met p, .ff-grad p { color: var(--ink-soft); }
.ff-metnote { margin-top: 12px; font-size: .9rem; }
/* WO99 (#43) — "meeting someone in person", the third of the named targets, and the only
   one of them that lives INSIDE A SENTENCE. WCAG 2.5.8 exempts a link in a block of text
   from the 44px minimum for the obvious reason: a link in prose cannot be made 44px tall
   without either opening the line spacing around it or overlapping the line above. So this
   is the version that costs nothing — the anchor stays inline, so vertical padding grows
   the HIT REGION without touching the line box or moving one word on the page, and the
   thumb gets 44px on the one link in this product that a person taps when they are about
   to go and meet a stranger. Nothing here has a background, so nothing is drawn any bigger
   than it was. The same link in prose on how-meeting-works.html and safety.html is left as
   prose: those are sentences on a page being read, not a control beside a decision. */
.ff-metnote a { padding: 12px 0; }
.ff-met .m-invlab, .ff-grad .m-invlab { margin-top: 14px; line-height: 1.4; text-transform: none; letter-spacing: 0; font-size: .95rem; color: var(--ink); }
.ff-met .ff-actions, .ff-grad .ff-actions { margin-top: 18px; display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.ff-met .ff-actions .btn, .ff-grad .ff-actions .btn { border: none; cursor: pointer; font: inherit; font-weight: 700; }
.ff-met .ff-actions .btn[disabled], .ff-grad .ff-actions .btn[disabled] { opacity: .5; cursor: default; }
/* the answered state of either: one warm line with a small sun, and never a second ask */
.ff-met-done { display: flex; align-items: flex-start; gap: 12px; margin-top: 28px; max-width: 60ch; padding: 16px 18px; border-radius: 18px; background: linear-gradient(158deg, #FDF3E4 0%, #FCEBD2 100%); border: 1px solid rgba(217,142,31,.34); color: #6B5F45; font-size: .96rem; line-height: 1.55; }
.ff-met-glow { flex: none; width: 26px; height: 26px; margin-top: 1px; border-radius: 50%; background: radial-gradient(circle at 50% 42%, #F7C173 0%, #F0A63C 44%, #D98E1F 74%, #9C6415 100%); box-shadow: 0 0 0 5px rgba(240,166,60,.16); }

/* MATT'S SENTENCE, AND WHAT SURVIVES SAYING NO TO IT (August 7, 2026).
   `.ff-gradq` is the plainly-worded question — a paragraph rather than a heading, because
   it is a question put to somebody rather than a title over a section.
   `.ff-gradquiet` is what is left after "leave them with my matches": a few grey words that
   continue to give the member the option, for good. It sheds the card's frame entirely —
   Matt asked for a small grey line, not a second card asking the same thing more quietly.
   #6E685A is the site's quiet ink (5.5:1 on this page's background — AA at any size),
   because a control nobody can read is not an option anybody has. */
.ff-grad .ff-gradq { font-size: 1.05rem; color: var(--ink); margin-bottom: 10px; }
.ff-grad.ff-gradquiet { border: none; border-left: none; box-shadow: none; background: none;
  padding: 0; margin-top: 20px; }
.ff-gradmove { font: inherit; font-size: .84rem; color: #6E685A; background: none; border: none;
  cursor: pointer; padding: 4px 2px; text-decoration: underline; text-underline-offset: 3px;
  text-decoration-color: rgba(138,130,113,.45); }
.ff-gradmove:hover { color: var(--ink); }
.ff-gradmove:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); border-radius: 8px; }

/* the assessment card — two research items, and it says out loud what answering opens */
.ff-assess { background: linear-gradient(180deg, #FFFDF8 0%, #FEF7EA 100%); border: 1px solid rgba(240,166,60,.4); border-top: 3px solid var(--orange); border-radius: var(--radius); box-shadow: var(--shadow); padding: 24px 20px; margin-top: 30px; max-width: 620px; }
.ff-assess .kicker { display: block; }
.ff-assess h2 { font-size: clamp(1.35rem, 4.4vw, 1.8rem); margin-bottom: 8px; }
.ff-assesslede { color: var(--ink-soft); margin-bottom: 6px; }
.ff-assesslede em { font-style: italic; }
.ff-assess .m-invlab { margin-top: 14px; line-height: 1.4; text-transform: none; letter-spacing: 0; font-size: .95rem; color: var(--ink); }
.ff-assess .ff-actions { margin-top: 18px; display: flex; gap: 12px; flex-wrap: wrap; align-items: center; }
.ff-assess .ff-actions .btn { border: none; cursor: pointer; font: inherit; font-weight: 700; }
.ff-assess .ff-actions .btn[disabled] { opacity: .5; cursor: default; }
.ff-assess:focus { outline: none; box-shadow: 0 0 0 5px var(--ring), var(--shadow); }
.m-input.ff-needs { border-color: var(--orange-deep); box-shadow: 0 0 0 4px rgba(240,166,60,.2); }

/* THE BARRIER'S REASON LINE. Every control the barrier greys carries one of these, and it
   names the way out and links to it. A disabled control that says nothing is a bug in a
   grey coat — and this one also has to say, in the same breath, that the other person is
   not waiting on anything (nobody here is penalised for somebody else's inaction). */
/* block, not flex: the line is one run of prose with a link inside it, and a flex box
   would make that link its own column */
.ff-blocked { display: block; position: relative; max-width: 60ch; margin: 0 0 16px;
  padding: 11px 14px 11px 30px; border-radius: 14px; background: var(--orange-soft);
  border: 1px solid rgba(217,142,31,.35); color: #6B5F45; font-size: .9rem; line-height: 1.5; }
.ff-blocked::before { content: ""; position: absolute; left: 13px; top: 1.02em; width: 7px; height: 7px;
  border-radius: 50%; background: var(--orange-deep); box-shadow: 0 0 0 3px rgba(240,166,60,.22); }
.ff-blocked a { color: var(--orange-deep); font-weight: 700; text-decoration: underline;
  text-underline-offset: 3px; }
.ff-blocked a:hover { color: var(--ink); }
.ff-blocked a:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); border-radius: 6px; }
/* The dark-surface variant of the blocked line and the next-round card's disabled-button
   rules went with the card itself — WO123 (finding 9). The blocked line now only ever
   draws on the room's cream, which the base rule above already handles. */
/* a composer the barrier has paused: legible, obviously not typeable, never a grey slab */
.ff-compose textarea[disabled] { background: #F5F1E8; color: #6E685A; cursor: default;
  border-style: dashed; }
.ff-err { margin-top: 10px; font-size: .88rem; color: #A0522D; }
.ff-err[hidden] { display: none; }

/* the quiet control — the same understatement as the network page's .n-quiet, defined
   here because this page does not load network.css */
.ff-quiet { font: inherit; font-size: .88rem; color: #6E685A; background: none; border: none; cursor: pointer; padding: 6px 4px; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: rgba(138,130,113,.45); }
.ff-quiet:hover { color: var(--ink); }
.ff-quiet:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); border-radius: 8px; }

/* ---------- loading, empty and error, in the messages page's voice ---------- */
.ff-loading { padding: 40px 0; text-align: center; color: var(--ink-soft); }
.ff-privacy { margin-top: 26px; font-size: .86rem; color: #6E685A; max-width: 60ch; }

@media (min-width: 700px) {
  .ff-room-inner { padding: 34px 30px 30px; }
  .ff-q { padding: 22px 22px 18px; }
  .ff-card { padding: 26px 26px; }
}

/* ============================================================
   WO11 — answering by voice or camera: the pull-down, the comfort
   setting, the players, the recorder sheet and the bridge out.
   Same vocabulary as everything above: cream cards, the orange
   spark for the thing being offered, charcoal for the stage.
   390px first; the recorder is a full-height sheet on a phone.
   ============================================================ */

/* ---------- the pull-down, the mutual line, and the comfort setting (WO11 bonus) ----------
   One small bar above the rounds: what you are answering in right now, one warm sentence
   about the two of you, and the way in to the setting behind it. Phone-first — the bar is
   a single column at 390px and never asks for a sideways look. */
.ffmode { background: var(--white); border: 1px solid rgba(33,29,22,.08); border-left: 3px solid var(--orange); border-radius: 18px; padding: 15px 16px 14px; margin-bottom: 18px; box-shadow: var(--shadow); }
.ffmode-pick { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.ffmode-pick label { font-size: .72rem; letter-spacing: .13em; text-transform: uppercase; font-weight: 700; color: #6E685A; }
.ffmode-pick select { font: inherit; font-weight: 600; font-size: .95rem; color: var(--ink); background: var(--cream); border: 1.5px solid rgba(33,29,22,.16); border-radius: 12px; padding: 9px 13px; min-height: 44px; cursor: pointer; }
.ffmode-pick select:focus-visible { outline: none; border-color: var(--orange-deep); box-shadow: 0 0 0 4px var(--ring); }
/* THE ONE LINE ABOUT THE TWO OF YOU. Said about the pair, never about either of them. */
.ffmode-shared { margin-top: 11px; font-family: var(--font-display); font-style: italic; font-size: 1.02rem; line-height: 1.45; color: var(--orange-deep); max-width: 52ch; }
.ffmode-free { margin-top: 8px; max-width: 52ch; }
.ffmode-more { display: inline-block; margin-top: 10px; }
@media (min-width: 560px) { .ffmode-pick label { flex: none; } }

/* ---------- the comfort setting: "what are you comfortable with?" ---------- */
.ffopt { background: var(--white); border: 1px solid rgba(217,142,31,.30); border-radius: 16px; padding: 16px 16px 14px; margin-top: 14px; }
.ffmode .ffopt { box-shadow: none; }
.ffopt h3 { font-size: 1.1rem; margin-bottom: 6px; }
.ffopt-lead { font-size: .93rem; color: var(--ink-soft); max-width: 52ch; }
.ffopt-rows { display: flex; flex-wrap: wrap; gap: 10px; margin: 14px 0 10px; }
.ffopt-row { position: relative; display: inline-flex; align-items: center; gap: 9px; padding: 10px 15px; min-height: 44px; border: 1.5px solid rgba(33,29,22,.14); border-radius: 999px; background: var(--cream); cursor: pointer; font-weight: 600; font-size: .93rem; }
/* the box itself is the label's own square; the input stays in the layer under it so it
   keeps its keyboard focus, its name and its checked state */
.ffopt-row input { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; opacity: 0; cursor: pointer; }
.ffopt-row.fixed input { cursor: default; }
.ffopt-mark { width: 17px; height: 17px; flex: none; border-radius: 6px; border: 1.5px solid rgba(33,29,22,.26); background: var(--white); position: relative; }
.ffopt-row input:checked + .ffopt-mark { background: var(--orange); border-color: var(--orange-deep); }
.ffopt-row input:checked + .ffopt-mark::after { content: ""; position: absolute; left: 5px; top: 1px; width: 4px; height: 9px; border: solid var(--charcoal); border-width: 0 2px 2px 0; transform: rotate(42deg); }
.ffopt-row input:focus-visible + .ffopt-mark { box-shadow: 0 0 0 4px var(--ring); }
.ffopt-row:has(input:checked) { border-color: var(--orange-deep); background: var(--orange-soft); }
.ffopt-row.fixed { cursor: default; opacity: .92; }
.ffopt [data-optsaved][hidden] { display: none; }

/* ---------- an earlier round, folded to one line ---------- */
.ff-folded { padding: 0; }
.ff-foldrow { display: flex; align-items: center; gap: 10px; width: 100%; font: inherit; text-align: left; background: var(--white); border: 1px solid rgba(33,29,22,.08); border-radius: 16px; padding: 14px 16px; min-height: 52px; cursor: pointer; box-shadow: var(--shadow); }
.ff-foldrow:hover { border-color: rgba(217,142,31,.4); }
.ff-foldrow:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); }
.ff-foldchev { flex: none; width: 8px; height: 8px; border-right: 2px solid var(--orange-deep); border-bottom: 2px solid var(--orange-deep); transform: rotate(-45deg); margin-left: 3px; }
.ff-foldname { flex: 1; min-width: 0; font-weight: 700; font-size: .95rem; color: var(--ink); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ff-foldgo { flex: none; font-size: .8rem; font-weight: 700; color: var(--orange-deep); }
.ff-foldup { flex: none; }

/* ---------- the engagement line: what putting in leads to, and no numbers ---------- */
.ff-nudge { margin: 14px 0 18px; padding: 13px 16px; border-radius: 14px; background: var(--orange-soft); border: 1px solid rgba(217,142,31,.28); font-size: .93rem; line-height: 1.55; color: var(--ink); max-width: 62ch; }
.ff-nudge a { color: var(--orange-deep); font-weight: 700; }

/* the box itself is the label's own square; the input stays in the layer under it so it
   keeps its keyboard focus, its name and its checked state */


/* ---------- a recorded answer, in the hand and in the reveal ---------- */
.ff-reccompose { margin-top: 14px; }
.ff-recbtn { display: inline-flex; align-items: center; gap: 8px; cursor: pointer; }
.ff-recfoot { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 10px; }
.ff-player { width: 100%; display: block; border-radius: 14px; background: var(--charcoal); border: 1px solid rgba(33,29,22,.12); }
/* ---------- WO124 (August 11 2026) — A VIDEO RENDERS IN ITS RECORDED ORIENTATION ----------
   This rule used to be `aspect-ratio: 16 / 9; object-fit: cover`, which is the whole of the
   fault Matt reported: a portrait phone take was cropped to a horizontal slice, and because
   object-fit rides the element into fullscreen, "expanding" it on a desktop still showed "a
   third of the original video". Matt: "it should show you the video in the orientation that
   the video was taken in" — orientation fidelity beats visual uniformity, his words.
   So: CONTAIN, never cover — before the video's own dimensions are known the box is a 16:9
   default that letterboxes rather than crops, and the moment metadata lands fast-friends.js
   sets the element's real aspect-ratio inline (orientPlayer), so the box becomes the frame.
   A portrait clip gets a bounded height and centres itself instead of towering full-width.
   The profile page's player (member.css .m-ff-player) has used contain all along — this
   brings the room to the house precedent, not to a new idea. */
.ff-player:not(.audio) { aspect-ratio: 16 / 9; object-fit: contain; }
.ff-player.ff-portrait { width: auto; max-width: 100%; max-height: 520px; margin: 0 auto; }
.ff-player.audio { height: 44px; background: transparent; border: none; }
.ff-stale { margin-top: 10px; font-size: .86rem; color: #6E685A; font-style: italic; }
.ff-err { margin-top: 8px; font-size: .88rem; color: #A0522D; }
.ff-err[hidden] { display: none; }

/* ---------- the one bridge out: promote a take to the profile ---------- */
.ff-promote { margin-top: 12px; background: linear-gradient(180deg, rgba(252,235,210,.6), rgba(255,253,248,0)); border: 1px solid rgba(217,142,31,.30); border-radius: 14px; padding: 13px 15px; }
.ff-promotehead { font-family: var(--font-display); font-size: 1.02rem; font-weight: 600; margin-bottom: 5px; }
.ff-promote p { font-size: .89rem; color: var(--ink-soft); max-width: 46ch; }
.ff-promote .ff-actions { margin-top: 11px; display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }
.ff-promote .m-btn-small { cursor: pointer; }
.ff-promoted { margin-top: 10px; font-size: .86rem; color: #6E685A; }

/* ---------- the recorder sheet ---------- */
body.ffr-on { overflow: hidden; }
.ffr { position: fixed; inset: 0; z-index: 260; background: rgba(20,20,20,.72); display: flex; align-items: flex-start; justify-content: center; overflow-y: auto; padding: 16px; }
.ffr-sheet { background: var(--cream); border-radius: 22px; width: 100%; max-width: 560px; padding: 18px; box-shadow: var(--shadow-lg); }
.ffr-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.ffr-head .kicker { margin: 0; }
.ffr-x { font: inherit; font-size: .9rem; font-weight: 700; padding: 8px 15px; border-radius: 999px; border: 1.5px solid rgba(33,29,22,.16); background: var(--white); cursor: pointer; color: var(--ink); }
.ffr-x:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); }
.ffr-prompt { font-family: var(--font-display); font-size: 1.12rem; line-height: 1.34; margin: 10px 0 14px; max-width: 34ch; }
.ffr-stage { position: relative; border-radius: 18px; overflow: hidden; background: var(--charcoal); aspect-ratio: 3 / 4; display: flex; align-items: center; justify-content: center; }
.ffr-stage.voice { aspect-ratio: 16 / 7; }
.ffr-stage.rec { box-shadow: 0 0 0 3px rgba(217,142,31,.55); }
.ffr-video { width: 100%; height: 100%; object-fit: cover; display: block; background: var(--charcoal); }
/* THE LIVE PREVIEW IS MIRRORED, AND ONLY THE LIVE PREVIEW (WO12 bonus item 5, Aug 4).
   A camera hands you the scene as it is, so moving your head left moved the preview
   right — which is not how a person has ever seen their own face, and it is what a
   member is watching the whole time they record. Every video chat and every phone
   camera mirrors the preview for exactly this reason. The class rides ONLY the
   [data-stage] element, which is the one that carries the live stream; the take being
   played back after recording is built without it, because a recorded take has to show
   what the file actually contains. Same rule, same class name and same shape as
   member.css's .m-ff-stage video.mirror, which does this for the profile recorder. */
.ffr-stage video.mirror { transform: scaleX(-1); }
.ffr-audio { width: 92%; }
.ffr-voice { display: flex; align-items: flex-end; gap: 7px; height: 46px; }
.ffr-voice i { display: block; width: 7px; border-radius: 999px; background: rgba(240,166,60,.75); height: 16px; }
.ffr-stage.rec .ffr-voice i { animation: ffr-bounce 1s ease-in-out infinite; }
.ffr-voice i:nth-child(2) { animation-delay: .12s; } .ffr-voice i:nth-child(3) { animation-delay: .24s; }
.ffr-voice i:nth-child(4) { animation-delay: .36s; } .ffr-voice i:nth-child(5) { animation-delay: .48s; }
@keyframes ffr-bounce { 0%,100% { height: 14px; } 50% { height: 42px; } }
@media (prefers-reduced-motion: reduce) { .ffr-stage.rec .ffr-voice i { animation: none; } }
/* the allowance is an arc that closes — never a clock, never a digit */
.ffr-ring { position: absolute; top: 12px; right: 12px; width: 34px; height: 34px; transform: rotate(-90deg); }
.ffr-ring[hidden] { display: none; }
.ffr-ring .bg { fill: none; stroke: rgba(255,253,248,.25); stroke-width: 3; }
.ffr-ring .arc { fill: none; stroke: var(--orange); stroke-width: 3; stroke-linecap: round; }
.ffr-ring.low .arc { stroke: #E06C3B; }
.ffr-live { position: absolute; top: 14px; left: 14px; font-size: .68rem; letter-spacing: .14em; text-transform: uppercase; font-weight: 700; color: #fff; background: rgba(224,108,59,.92); border-radius: 999px; padding: 3px 10px; }
.ffr-live[hidden] { display: none; }
.ffr-controls { display: flex; align-items: center; gap: 14px; margin-top: 14px; }
.ffr-rec { flex: none; width: 58px; height: 58px; border-radius: 50%; border: 3px solid rgba(33,29,22,.18); background: var(--white); cursor: pointer; display: flex; align-items: center; justify-content: center; }
.ffr-rec span { display: block; width: 26px; height: 26px; border-radius: 50%; background: #E06C3B; transition: border-radius .18s, width .18s, height .18s; }
.ffr-rec.on span { border-radius: 5px; width: 20px; height: 20px; }
.ffr-rec:focus-visible { outline: none; box-shadow: 0 0 0 4px var(--ring); }
.ffr-note { font-size: .88rem; color: var(--ink-soft); }
.ffr-bar { height: 5px; border-radius: 999px; background: rgba(33,29,22,.10); margin-top: 14px; overflow: hidden; }
.ffr-bar[hidden] { display: none; }
.ffr-barfill { display: block; height: 100%; width: 0; border-radius: 999px; background: var(--orange); transition: width .2s; }
.ffr-actions { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; margin-top: 14px; min-height: 20px; }
.ffr-actions .btn { border: none; cursor: pointer; font: inherit; font-weight: 700; }
.ffr-quiet { font: inherit; font-size: .88rem; color: #6E685A; background: none; border: none; cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }
.ffr-quiet:hover { color: var(--ink); }
.ffr-hintline, .ffr-saving { font-size: .88rem; color: var(--ink-soft); }
.ffr-tip { margin-top: 14px; font-size: .85rem; color: #6E685A; max-width: 52ch; }
@media (max-width: 520px) { .ffr { padding: 0; } .ffr-sheet { border-radius: 0; min-height: 100%; } }
/* the modality chip on ONE ANSWER — how that answer was given, never whose idea it was.
   It moved off the round header when rounds became mixed (WO11 bonus). */

/* ---------- THE GATE SAYS IT IS A GATE (WO10 bonus, item 3) ----------
   One plain sentence above the two items, in the card's loudest non-heading weight, so a
   member who reads nothing else reads this one. It is not a warning colour: the barrier is
   an ordinary part of going further with somebody, not a telling-off. */
.ff-gateline { margin: 2px 0 12px; padding: 11px 14px; border-radius: 14px;
  background: var(--orange-soft); border: 1px solid rgba(217,142,31,.34);
  color: #6B5F45; font-size: .98rem; line-height: 1.5; }
.ff-gateline strong { color: var(--ink); }

/* ---------- WHAT JUST OPENED (WO10 bonus, item 4) ----------
   The barrier card's reply. Same footprint so nothing jumps, opposite temperature: the
   card that was holding the room is now the card that opened it. */
.ff-unlocked { border-style: solid; border-color: rgba(217,142,31,.42);
  background: linear-gradient(178deg, #FFFDF8 0%, #FEF7EA 62%, #FCEBD2 100%);
  box-shadow: 0 16px 40px rgba(217,142,31,.16); animation: none; }
.ff-unlocked:focus { outline: none; }
.ff-unlocked .kicker { color: var(--orange-deep); }
.ff-unlocked .ff-actions { display: flex; gap: 12px; flex-wrap: wrap; align-items: center; margin-top: 18px; }
.ff-unlocked .ff-actions .btn { border: none; cursor: pointer; font: inherit; font-weight: 700; text-decoration: none; }
.ff-unlocked .ff-actions a.btn { display: inline-block; }

/* ---------- AN ANSWER THAT WAS TAKEN DOWN (WO10 bonus, item 10) ----------
   A placeholder, not a hole: the question keeps its place and the space says plainly that
   something was there and its author removed it. Quiet on purpose — this is not an
   incident, and the partner is owed a fact rather than a drama. */
.ff-gone { font-size: .96rem; font-style: italic; color: #A79E8D; }
.ff-ansgone .body { opacity: .95; }
/* the owner's own small door, and the confirmation that replaces it in place */
.ff-delrow { margin-top: 10px; }
.ff-delrow .m-btn-small { cursor: pointer; }

/* ============================================================
   THE ONE QUIET LINE (WO61 §5) — the foot of the room.

   It is set at the same weight as .ff-privacy directly above it, deliberately: those two
   sentences are the only things on this page that are not about the two people in the room,
   and they should read as the same kind of quiet footnote. No card, no border, no kicker,
   no motion — the room's pulse means something happened between two people, and nothing
   has happened here.
   ============================================================ */
.ff-fbline { margin-top: 14px; font-size: .86rem; color: #6E685A; max-width: 60ch; line-height: 1.6; }
.ff-fbline a { color: var(--orange-deep); }
.ff-fbline span { margin: 0 6px; opacity: .5; }
.ff-fbno { background: none; border: none; padding: 0; font: inherit; color: #6E685A;
  text-decoration: underline; cursor: pointer; }
.ff-fbno:hover { color: var(--ink); }
.ff-fbno:focus-visible { outline: 2px solid var(--orange-deep); outline-offset: 2px; border-radius: 4px; }

/* ============================================================
   ROUND ZERO — THE VESTIBULE (WO152 "Fast Friends round zero", August 12-13 2026)

   The two prefab answers, side by side, once, above the rounds. It wears .ff-card so it
   belongs to the room, and everything below is about making it read as a THRESHOLD rather
   than as a round: no border colour of its own, no pulse, no keyframes (this file adds
   none), and a lead line small enough that the two answers are what the eye lands on.

   SIDE BY SIDE IS A GRID AND ONE COLUMN IS THE PHONE. At 390px two columns of prose would
   be two unreadable ribbons, so the grid collapses and the two sides read one after the
   other, in source order — the member's own first, then their partner's. An asymmetric
   pair (one side has no prefab) renders ONE side, which fills the row and needs no special
   case: there is nothing on the card to suggest a second one was expected.
   ============================================================ */
.ff-zero { margin-bottom: 20px; }
.ff-zero-lead { margin: 6px 0 16px; font-size: .9rem; color: #6E685A; max-width: 62ch; line-height: 1.6; }
.ff-zero-grid { display: grid; grid-template-columns: 1fr; gap: 18px; }
@media (min-width: 720px) { .ff-zero-grid { grid-template-columns: 1fr 1fr; gap: 26px; } }
.ff-zero-side { min-width: 0; }
.ff-zero-who { font-size: .74rem; letter-spacing: .14em; text-transform: uppercase;
  font-weight: 700; color: var(--orange-deep); margin-bottom: 8px; }
.ff-zero-q { font-family: 'Fraunces', Georgia, serif; font-size: 1.02rem; font-style: italic;
  color: var(--ink); margin-bottom: 10px; line-height: 1.45; }
.ff-zero-a { font-size: .97rem; line-height: 1.65; color: var(--ink); }
.ff-zero-a p { margin: 0 0 10px; }
.ff-zero-a p:last-child { margin-bottom: 0; }

/* ============================================================
   THE LEGACY NUDGE (WO152 §6) — the Fast Friends home page, above the rooms.

   Quiet by construction, because a member who joined before this order is not being asked
   for anything they owe: no card border, no pulse, no orange fill, no dismissal control.
   It is one paragraph at the weight of .ff-nudge directly above it, and it disappears on
   its own the moment there is an answer.
   ============================================================ */
.ff-legacy { margin: 12px 0 18px; padding: 12px 14px; border-radius: 12px;
  background: rgba(240, 166, 60, .07); }
.ff-legacy p { margin: 0; font-size: .9rem; line-height: 1.6; color: #4A4436; max-width: 66ch; }
.ff-legacy a { color: var(--orange-deep); font-weight: 700; }
