/* PickMyMate — application UI (signup, browse, profile, admin).
   Layers on top of style.css and reuses its tokens. */

.flash {
  background: #fbeeda; border: 1px solid var(--line); color: var(--ink);
  padding: 14px 18px; border-radius: var(--radius); margin: 20px 0;
}
.flash-err { background: #fbe6d5; border-color: #e2b183; }

/* A flash sits above .section, which carries up to 104px of top padding —
   together that left a canyon between "Vote counted" and the heading below.
   When a flash is showing, the section tucks up under it. */
.flashbar .flash { margin-bottom: 0; }
.flashbar + .section { padding-top: 32px; }

.backlink { color: var(--muted); font-size: .92rem; }
.backlink:hover { color: var(--orange); }

.hint { font-size: .86rem; color: var(--muted); margin: 6px 0 0; }
.err  { font-size: .86rem; color: var(--orange-dk); font-weight: 600; margin: 6px 0 0; }

/* ---------------- filters ---------------- */
.filters { display: flex; gap: 10px; flex-wrap: wrap; margin: 20px 0 32px; }
.filter {
  padding: 8px 18px; border-radius: 999px; font-size: .9rem; font-weight: 600;
  border: 1px solid var(--line); background: #fff; color: var(--body);
}
.filter:hover  { border-color: var(--orange); color: var(--orange); }
.filter.is-on  { background: var(--orange); border-color: var(--orange); color: #fff; }

/* ---------------- browse grid ---------------- */
.grid {
  display: grid; gap: 22px;
  grid-template-columns: repeat(auto-fill, minmax(210px, 1fr));
}
.ucard {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden; box-shadow: var(--shadow); display: block;
  transition: transform .18s ease, box-shadow .18s ease;
}
.ucard:hover { transform: translateY(-4px); box-shadow: var(--shadow-lg); }
.ucard-photo {
  aspect-ratio: 4 / 5; background: #f1e7d4;
  display: grid; place-items: center; overflow: hidden;
}
.ucard-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ucard-noimg { color: var(--muted); font-size: .85rem; }
.ucard-body { padding: 14px 16px 18px; }
.ucard-body h3 { font-size: 1.05rem; margin-bottom: 2px; }
/* The name is a link on the Vote tab, but should read as a heading. */
.ucard-link { color: inherit; text-decoration: none; }
.ucard-link:hover { color: var(--orange); }
.ucard-meta { font-size: .82rem; color: var(--muted); margin: 0; }

/* ---------------- profile ---------------- */
.pgrid {
  display: grid; grid-template-columns: 1fr 1fr; gap: 16px; margin: 28px 0;
}
.pphoto {
  width: 100%; border-radius: var(--radius); display: block;
  box-shadow: var(--shadow); background: #f1e7d4;
}
.qa { display: grid; gap: 16px; }
.qa-item {
  background: #fff; border: 1px solid var(--line);
  border-radius: var(--radius); padding: 20px 22px; box-shadow: var(--shadow);
}
.qa-q { font-size: .82rem; font-weight: 700; letter-spacing: .04em;
        text-transform: uppercase; color: var(--orange); margin-bottom: 8px; }
.qa-a { margin: 0; color: var(--ink); font-size: 1.05rem; line-height: 1.6; }

/* Her question, above a man's answer to it — blue so the question and the
   reply read as two different voices. */
.qa-ask { color: var(--blue); font-weight: 650; }

/* "Your answer" on a woman's profile, marking his own words back to him. */
.qa-mine-label {
  margin: 12px 0 4px; font-size: .78rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase; color: var(--blue);
}

/* Face beside the name heading each man's set of answers. */
.qa-who { display: flex; align-items: center; gap: 10px; }

/* "Ladies you've answered" heads a whole card of Q&A, so it carries a
   bigger face than the one-line rows that share .pthumb elsewhere. */
.qa-who-lg { gap: 14px; }
.qa-who-lg .pthumb { width: 68px; height: 68px; }
.qa-who-lg .pthumb-none { font-size: 1.5rem; }

/* The woman the ballot is for: both her photos and her name above the men. */
.owner-card { margin: 20px 0 28px; }
/* Capped rather than full width, but comfortably readable — roughly the
   same photo size as each man below. */
.owner-pics {
  display: grid; grid-template-columns: 1fr 1fr; gap: 12px;
  max-width: 440px;
}
.owner-pics img {
  width: 100%; aspect-ratio: 4 / 5; object-fit: cover;
  border-radius: var(--radius); border: 1px solid var(--line);
  display: block;
}
.owner-name {
  margin: 12px 0 0; font-size: 1.15rem; font-weight: 700; color: var(--blue);
}

/* Face beside each name in the Full result tally. */
.tallywho { display: flex; align-items: center; gap: 10px; min-width: 0; }

/* The winner, beside his result rather than above it. Wraps to stacked on
   a narrow screen so the photo never squeezes the name. */
.winner { display: flex; align-items: center; gap: 22px; flex-wrap: wrap; }
.winner > div { min-width: 0; flex: 1 1 260px; }
.winner-photo {
  flex: none; width: 132px; height: 132px; object-fit: cover;
  border-radius: 50%; border: 3px solid var(--gold);
  display: block;
}
.winner h1 { margin-bottom: .5rem; }

/* ---------------- forms ---------------- */
.fform { margin-top: 28px; max-width: 640px; }
.field { margin-bottom: 20px; }
.field-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.field label { display: block; font-weight: 650; color: var(--ink); margin-bottom: 6px; font-size: .95rem; }

/* password was missing here, so it fell back to browser defaults and sat at a
   different height and radius to every field beside it. */
.fform input[type=text], .fform input[type=email], .fform input[type=number],
.fform input[type=password], .fform input[type=search], .fform input[type=tel],
.fform input:not([type]), .fform select, .fform textarea, .qbox input, .qbox select, .qbox textarea {
  width: 100%; padding: 12px 16px; font-size: 1rem; font-family: inherit;
  color: var(--ink); background: #fff;
  border: 1.5px solid var(--line); border-radius: 12px;
  transition: border-color .15s, box-shadow .15s;
}
.fform textarea, .qbox textarea { resize: vertical; line-height: 1.55; }
.fform input:focus, .fform select:focus, .fform textarea:focus,
.qbox input:focus, .qbox select:focus, .qbox textarea:focus {
  outline: none; border-color: var(--orange);
  box-shadow: 0 0 0 4px rgba(178,76,14,.14);
}
.fform input[type=file] {
  width: 100%; padding: 10px; font-size: .92rem;
  border: 1.5px dashed var(--line); border-radius: 12px; background: #fff;
}
.field-check label {
  display: flex; gap: 10px; align-items: flex-start;
  font-weight: 400; font-size: .93rem; color: var(--body); line-height: 1.5;
}
.field-check input { margin-top: 3px; flex: none; }

.qbox {
  border: 1px solid var(--line); border-radius: var(--radius);
  padding: 18px 20px 20px; margin: 0 0 16px; background: #fff;
}
.qbox legend { font-weight: 700; color: var(--ink); font-size: .9rem; padding: 0 6px; }
.qbox select, .qbox input { margin-bottom: 10px; }

/* ---------------- admin ---------------- */
.atable { width: 100%; border-collapse: collapse; font-size: .92rem; margin-top: 8px; }
.atable th {
  text-align: left; font-size: .76rem; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); padding: 10px 12px; border-bottom: 1px solid var(--line);
}
.atable td { padding: 10px 12px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.atable tr:hover td { background: var(--bg-alt); }
.athumb { width: 44px; height: 54px; object-fit: cover; border-radius: 8px; display: block; }
.dim { color: var(--muted); font-size: .84rem; }
.arow { display: flex; gap: 6px; flex-wrap: wrap; }
.arow form { margin: 0; }

.mini {
  font-family: inherit; font-size: .8rem; font-weight: 600; cursor: pointer;
  padding: 6px 12px; border-radius: 999px;
  border: 1px solid var(--line); background: #fff; color: var(--body);
}
.mini:hover     { border-color: var(--muted); }
.mini-ok        { background: #eaf0e2; border-color: #bcd0ab; color: #43703a; }
.mini-ok:hover  { background: #dde8d2; }
.mini-del       { background: #fbeeda; border-color: #e2b183; color: var(--orange-dk); }
.mini-del:hover { background: #f7e0c6; }

/* The payoff link on a closed poll — solid orange so it reads as the thing
   to click in a row of grey metadata. White on --orange is 5.34:1. */
.mini-answers       { background: var(--orange); border-color: var(--orange); color: #fff; }
.mini-answers:hover { background: var(--orange-dk); border-color: var(--orange-dk); }

.badge {
  font-size: .74rem; font-weight: 700; padding: 4px 10px; border-radius: 999px;
  text-transform: uppercase; letter-spacing: .05em;
}
.badge-pending  { background: #faedd2; color: #8c3c0a; }
.badge-approved { background: #eaf0e2; color: #43703a; }
.badge-hidden   { background: #efe8dc; color: var(--muted); }

@media (max-width: 620px) {
  .field-row, .pgrid { grid-template-columns: 1fr; }
  .atable thead { display: none; }
  .atable td { display: block; border: 0; padding: 4px 0; }
  .atable tr { display: block; border-bottom: 1px solid var(--line); padding: 14px 0; }
}

/* ---------------- question responses ---------------- */
.qa-count {
  font-size: .82rem; color: var(--muted); margin: 10px 0 0;
}
.rlist { margin-top: 14px; border-top: 1px solid var(--line); padding-top: 12px; }
.rlist summary {
  cursor: pointer; font-size: .86rem; font-weight: 650; color: var(--orange);
  list-style: none;
}
.rlist summary::-webkit-details-marker { display: none; }
.rlist summary::before { content: "▸ "; }
.rlist[open] summary::before { content: "▾ "; }
.ritem {
  border-left: 2px solid var(--line); padding: 10px 0 10px 14px; margin-top: 12px;
}
.rwho { font-size: .86rem; font-weight: 650; margin: 0 0 4px; }
.rwho a { color: var(--ink); }
.rwho a:hover { color: var(--orange); }
.rtext { margin: 0; font-size: .96rem; line-height: 1.6; color: var(--body); }

/* ---------------- auth ---------------- */
.navlink-plain { font-size: .95rem; font-weight: 600; color: var(--body); }
.navlink-plain:hover { color: var(--orange); }
/* A rule and a block rather than a filled panel. The panel's 26px of
   horizontal padding indented its button, so it never lined up with the
   submit button above it; without the padding both sit on the same left edge
   as the form fields. Width matches .fform so the two sections agree. */
.altbox {
  margin-top: 2.5rem; padding: 26px 0 0;
  max-width: 640px;
  border-top: 1px solid var(--line);
}
.altbox h2 { font-size: 1.15rem; margin-bottom: .4rem; }
.altbox p  { font-size: .95rem; margin-bottom: 1rem; }
.rform { margin-top: 14px; }
.rform textarea {
  width: 100%; padding: 12px 16px; font-family: inherit; font-size: .98rem;
  line-height: 1.55; color: var(--ink); background: #fff;
  border: 1.5px solid var(--line); border-radius: 12px; resize: vertical;
  margin-bottom: 10px;
}
.rform textarea:focus {
  outline: none; border-color: var(--orange);
  box-shadow: 0 0 0 4px rgba(178,76,14,.14);
}

/* ---------------- swipe deck ---------------- */
.swipe-section { padding-top: 32px; }
.deck-head { display: flex; justify-content: center; margin-bottom: 18px; }

/* X on the left, photo in the middle, check on the right. */
.swipe-stage {
  display: grid;
  grid-template-columns: auto minmax(0, 360px) auto;   /* 10% smaller card */
  align-items: center;
  justify-content: center;
  gap: clamp(16px, 4vw, 48px);
}
.side { display: flex; flex-direction: column; align-items: center; gap: 8px; margin: 0; }
.choice {
  width: clamp(64px, 9vw, 88px); height: clamp(64px, 9vw, 88px);
  border-radius: 50%; cursor: pointer; border: 3px solid currentColor;
  background: #fff; font-size: clamp(1.8rem, 3.4vw, 2.4rem); line-height: 1;
  display: grid; place-items: center;
  box-shadow: var(--shadow);
  transition: transform .15s ease, box-shadow .15s ease, background .15s ease;
}
.choice:hover  { transform: scale(1.09); box-shadow: var(--shadow-lg); }
.choice:active { transform: scale(.97); }
.choice-no  { color: #a8372a; }
.choice-no:hover  { background: #a8372a; color: #fff; }
.choice-yes { color: #4a7c3f; }
.choice-yes:hover { background: #4a7c3f; color: #fff; }
.choice-label {
  font-size: .82rem; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--muted);
}

.scard {
  --stamp: 0;
  position: relative; width: 100%;
  background: #fff; border-radius: var(--radius-lg);
  box-shadow: var(--shadow-lg); overflow: hidden;
  cursor: grab; user-select: none; touch-action: pan-y;
}
.scard:active { cursor: grabbing; }

.scard-photos { position: relative; aspect-ratio: 4 / 5; background: #f1e7d4; }
.scard-photo {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; opacity: 0; transition: opacity .2s ease;
}
.scard-photo.is-on { opacity: 1; }

.scard-nav {
  position: absolute; top: 50%; transform: translateY(-50%);
  width: 38px; height: 38px; border-radius: 50%;
  border: 0; background: rgba(20,14,24,.42); color: #fff;
  font-size: 1.4rem; line-height: 1; cursor: pointer; backdrop-filter: blur(4px);
}
.scard-nav:hover { background: rgba(20,14,24,.66); }
.scard-prev { left: 10px; } .scard-next { right: 10px; }
.scard-dots {
  position: absolute; bottom: 12px; left: 0; right: 0;
  display: flex; gap: 6px; justify-content: center;
}
.scard-dots .dot { width: 7px; height: 7px; border-radius: 50%; background: rgba(255,255,255,.5); }
.scard-dots .dot.is-on { background: #fff; }

.scard-body { padding: 18px 22px 24px; }
.scard-body h2 { font-size: 1.5rem; margin-bottom: 4px; }
.scard-hint { font-size: .88rem; color: var(--muted); margin: 0; }

.scard-stamp {
  position: absolute; top: 22px; z-index: 4;
  font-size: 1.4rem; font-weight: 800; letter-spacing: .04em;
  text-transform: uppercase; padding: 8px 18px; border-radius: 12px;
  border: 4px solid currentColor; opacity: 0; pointer-events: none;
}
.scard-nope { left: 20px; color: #a8372a; transform: rotate(-16deg); }
.scard-yes  { right: 20px; color: #4a7c3f; transform: rotate(14deg); }
.scard.show-nope .scard-nope { opacity: var(--stamp); }
.scard.show-yes  .scard-yes  { opacity: var(--stamp); }

/* Now / Later prompt after a match */
.modal-back {
  position: fixed; inset: 0; z-index: 200;
  background: rgba(16,10,20,.62);
  display: grid; place-items: center; padding: 24px;
  backdrop-filter: blur(3px);
}
.modal {
  background: #fff; border-radius: var(--radius-lg);
  padding: 32px 34px; max-width: 480px; width: 100%;
  box-shadow: var(--shadow-lg); text-align: center;
}
.modal h2 { font-size: 1.35rem; margin-bottom: .6rem; }
.modal-actions {
  display: flex; gap: 12px; justify-content: center;
  align-items: center; margin: 22px 0 14px; flex-wrap: wrap;
}
.btn-ghost {
  display: inline-block; padding: 14px 28px; border-radius: 999px;
  font-weight: 650; font-size: 1rem; cursor: pointer;
  border: 1.5px solid var(--line); background: #fff; color: var(--body);
  transition: border-color .15s ease, color .15s ease;
}
.btn-ghost:hover { border-color: var(--orange); color: var(--orange); }

/* Saved matches */
.mlist { display: grid; gap: 12px; margin-top: 16px; }
.mitem {
  display: flex; align-items: center; gap: 14px;
  padding: 12px 16px; background: #fff;
  border: 1px solid var(--line); border-radius: var(--radius);
}
.mthumb { width: 54px; height: 68px; object-fit: cover; border-radius: 10px; display: block; background: #f1e7d4; }
.mbody { flex: 1; min-width: 0; }
.mbody strong { color: var(--ink); }
.mbody p { margin: 2px 0 0; }

/* Keep X-left / photo-centre / check-right at every width; just scale it
   down. Reflowing the buttons under the card on mobile loses the left-means-
   reject, right-means-match mapping that the whole screen is built around. */
@media (max-width: 720px) {
  .swipe-stage { gap: 10px; }
  .choice { width: 56px; height: 56px; font-size: 1.5rem; border-width: 2px; }
  .choice-label { display: none; }
  .scard-body { padding: 14px 16px 18px; }
  .scard-body h2 { font-size: 1.25rem; }
}
@media (max-width: 380px) {
  .swipe-stage { gap: 6px; }
  .choice { width: 48px; height: 48px; font-size: 1.25rem; }
}

/* ---------------- answer page ---------------- */
.answer-who {
  display: flex; align-items: center; gap: 14px; margin: 22px 0 8px;
  padding: 14px 16px; background: var(--bg-alt);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.answer-thumb { width: 56px; height: 70px; object-fit: cover; border-radius: 10px; }

/* ---------------- interest list ---------------- */
.ilist { display: grid; gap: 10px; margin-top: 12px; }
.iitem {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
  padding: 12px 16px; background: #fff;
  border: 1px solid var(--line); border-radius: var(--radius);
}
.iitem .done { color: #43703a; font-weight: 650; font-size: .85rem; }
.iitem .waiting { color: var(--muted); font-size: .85rem; }

/* Past polls: who stood, as a row of small faces above the date line. */
.pastmain { min-width: 0; }
.pthumbs { display: flex; flex-wrap: wrap; gap: 5px; margin-bottom: 7px; }
.pthumb {
  flex: none; width: 34px; height: 34px; border-radius: 50%;
  overflow: hidden; background: var(--bg-alt); border: 1px solid var(--line);
}
.pthumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pthumb-none {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%;
  font-size: .82rem; font-weight: 800; color: var(--blue);
}

@media (prefers-reduced-motion: reduce) {
  .scard, .swipe-btn { transition: none !important; }
}

/* ---------------- the vote (her side) ---------------- */
.vbox {
  padding: 24px 26px; background: var(--bg-alt);
  border: 1px solid var(--line); border-radius: var(--radius); margin-top: 12px;
}
.vcount { font-size: 1.15rem; color: var(--ink); margin-bottom: .4rem; }
.vcount strong { font-size: 2rem; color: var(--orange); }
.vlive { margin-top: 18px; }
.vstatus { font-weight: 700; color: var(--ink); margin-bottom: .6rem; }
.linkrow { display: flex; gap: 8px; margin: 6px 0 14px; }
.linkrow input {
  flex: 1; padding: 10px 14px; font-family: inherit; font-size: .9rem;
  border: 1.5px solid var(--line); border-radius: 10px; background: #fff;
  color: var(--body);
}

/* ---------------- the ballot ---------------- */
.cands { display: grid; gap: 20px; margin-top: 2rem; }
.cand {
  display: block; cursor: pointer; position: relative;
  background: #fff; border: 2px solid var(--line);
  border-radius: var(--radius); padding: 20px 22px;
  transition: border-color .15s ease, box-shadow .15s ease;
}
.cand:hover { border-color: var(--orange); box-shadow: var(--shadow); }
.cand:has(input:checked) {
  border-color: var(--orange);
  box-shadow: 0 0 0 4px rgba(178,76,14,.14);
}
.cand.is-chosen { border-color: #43703a; background: #f2f6ec; }
.cand input[type=radio] { position: absolute; top: 22px; right: 22px; width: 20px; height: 20px; }

.cand-head { display: flex; gap: 16px; align-items: center; margin-bottom: 16px;
             flex-wrap: wrap; }
.cand-head h2 { font-size: 1.25rem; margin: 0; }
.cand-pics { display: flex; gap: 10px; flex: none; }
.cand-pics img {
  width: 178px; height: 222px; object-fit: cover; border-radius: 12px;
  background: #f1e7d4;
}
/* Two 178px photos plus the name won't sit on one line on a narrow screen;
   step them down rather than letting the name wrap under them. */
@media (max-width: 700px) {
  .cand-pics img { width: 132px; height: 165px; }
}
@media (max-width: 520px) {
  .cand-pics img { width: 104px; height: 130px; }
}
.cand-answers { display: grid; gap: 10px; }
.cand-answers .qa-item { border: 0; background: var(--bg-alt); padding: 14px 16px; }
.cand-answers .qa-a { font-size: .98rem; }

/* ---------------- results ---------------- */
.bar {
  display: inline-block; width: 90px; height: 8px; border-radius: 4px;
  background: var(--line); margin-right: 10px; vertical-align: middle;
  position: relative; overflow: hidden;
}
.bar::after {
  content: ""; position: absolute; inset: 0; width: var(--pct, 0%);
  background: linear-gradient(90deg, var(--gold), var(--orange));
}

@media (max-width: 620px) {
  .cand-head { flex-direction: column; align-items: flex-start; }
  .linkrow { flex-direction: column; }
}

/* ---------------- messaging ---------------- */
.badge-unread {
  display: inline-block; min-width: 20px; padding: 2px 7px;
  border-radius: 999px; background: var(--orange); color: #fff;
  font-size: .74rem; font-weight: 700; text-align: center; line-height: 1.5;
}

/* ===================== Conversations ========================
   The inbox and the chat, built to read like a messaging app rather than
   an email client.

   No timestamps anywhere. A date on every line is noise you learn to skip;
   what you actually want to know is whether the other person has read you,
   and that is one word. It only became answerable with migration 020, when
   "read" stopped being a timestamp — which could not tell two messages in
   the same second apart — and became a message id.
   ============================================================ */

/* ---- the list ---- */
.clist { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 10px; }

/* Each conversation is its own card. Without an outline a list of rows on a
   cream page is just text at different heights — you cannot see where one
   person stops and the next starts, and the row now carries three things to
   aim at rather than one. */
.citem {
  display: flex; align-items: center; gap: 10px;
  padding: 12px 14px;
  background: #fff;
  border: 1px solid var(--line); border-radius: var(--radius);
  transition: border-color .15s ease, box-shadow .15s ease;
}
.citem:hover { border-color: var(--orange); box-shadow: var(--shadow); }

/* Something waiting gets a spine down the left, so it is findable at a
   glance down a column of otherwise identical cards. */
.citem.is-unread { border-left: 3px solid var(--orange); }

.clink {
  display: flex; align-items: center; gap: 14px;
  flex: 1; min-width: 0; color: inherit; text-decoration: none;
}

.cface {
  position: relative; flex: none;
  width: 56px; height: 56px; border-radius: 50%;
  overflow: visible; background: var(--bg-alt);
}
.cface img {
  width: 100%; height: 100%; object-fit: cover;
  border-radius: 50%; display: block;
}
.cface-none, .chat-avatar-none {
  display: flex; align-items: center; justify-content: center;
  width: 100%; height: 100%; border-radius: 50%;
  background: var(--bg-alt); color: var(--blue);
  font-weight: 800; font-size: 1.2rem;
}
/* The unread mark rides on the face, as it does in every messaging app —
   it is about the person, not about a column of metadata. */
.cdot {
  position: absolute; right: -1px; bottom: -1px;
  width: 15px; height: 15px; border-radius: 50%;
  background: var(--orange);
  /* Rings the card's white, not the page's cream — the row is a card now. */
  border: 2.5px solid #fff;
}

.cmain { min-width: 0; flex: 1; display: flex; flex-direction: column; gap: 2px; }
.cname { color: var(--ink); font-weight: 650; }
.csnip {
  font-size: .9rem; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cyou { color: var(--muted); }

/* Unread rows carry their weight in the type, like Messenger: the name and
   the line go solid, so a glance down the list finds them without needing a
   colour to be noticed. */
.citem.is-unread .cname { font-weight: 800; }
.citem.is-unread .csnip { color: var(--ink); font-weight: 600; }

.cstatus { flex: none; display: flex; align-items: center; }

/* New, with a skate rolling in front of it. White on the orange is 5.34:1. */
.cnew {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 11px 4px 8px; border-radius: 999px;
  background: var(--orange); color: #fff;
  font-size: .76rem; font-weight: 800; letter-spacing: .02em;
  white-space: nowrap;
}
.cnew-skate {
  width: 17px; height: 16px; flex: none;
  background: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%3Cpath%20d%3D%22M6.5%206h7.2a2.8%202.8%200%200%201%202.8%202.8v5.4l5.9%202.2A3.6%203.6%200%200%201%2024.7%2020H6.5a2%202%200%200%201-2-2V8a2%202%200%200%201%202-2z%22%20fill%3D%22%23fcf6ea%22%2F%3E%3Crect%20x%3D%224.5%22%20y%3D%229.2%22%20width%3D%2212%22%20height%3D%221.8%22%20fill%3D%22%23b24c0e%22%2F%3E%3Crect%20x%3D%224.5%22%20y%3D%2212.1%22%20width%3D%2212%22%20height%3D%221.8%22%20fill%3D%22%23e0a12e%22%2F%3E%3Crect%20x%3D%224.5%22%20y%3D%2220.3%22%20width%3D%2221.5%22%20height%3D%222.6%22%20rx%3D%221.3%22%20fill%3D%22%23fcf6ea%22%2F%3E%3Cpath%20d%3D%22M26.2%2020.6h1.6a1.6%201.6%200%200%201%201.6%201.6v2.2a1.8%201.8%200%200%201-1.8%201.8h-1.4z%22%20fill%3D%22%23fcf6ea%22%2F%3E%3Ccircle%20cx%3D%229.4%22%20cy%3D%2225.8%22%20r%3D%223.3%22%20fill%3D%22%23e0a12e%22%20stroke%3D%22%23fcf6ea%22%20stroke-width%3D%221.4%22%2F%3E%3Ccircle%20cx%3D%2220.8%22%20cy%3D%2225.8%22%20r%3D%223.3%22%20fill%3D%22%23e0a12e%22%20stroke%3D%22%23fcf6ea%22%20stroke-width%3D%221.4%22%2F%3E%3C%2Fsvg%3E") center/contain no-repeat;
}

.cactions { flex: none; display: flex; align-items: center; gap: 6px; }
.clocked {
  font-size: .74rem; font-weight: 700; color: var(--muted);
  background: var(--bg-alt); border-radius: 999px; padding: 3px 10px;
}
/* Report and Delete. Both are last resorts, so both stay quiet until you go
   looking — and they colour differently on hover, because one of them cannot
   be undone and the other can. */
.cact {
  border: 0; background: none; cursor: pointer; font: inherit;
  font-size: .78rem; font-weight: 600; color: var(--muted);
  padding: 6px 9px; border-radius: 8px; text-decoration: none;
  white-space: nowrap;
}
.cact-report:hover { color: var(--blue); background: rgba(28,91,134,.08); }
.cact-delete:hover { color: var(--orange); background: rgba(178,76,14,.08); }
.cact:focus-visible { outline: 2px solid var(--blue); outline-offset: 1px; }

/* ---- the chat ---- */
.section-chat { padding-bottom: 2rem; }

.chat-top {
  display: flex; align-items: center; gap: 12px;
  padding-bottom: 14px; border-bottom: 1px solid var(--line);
}
.chat-back {
  flex: none; width: 36px; height: 36px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  color: var(--ink); font-size: 1.2rem; line-height: 1;
}
.chat-back:hover { background: var(--bg-alt); }
.chat-who {
  display: flex; align-items: center; gap: 10px;
  flex: 1; min-width: 0; color: inherit; text-decoration: none;
}
.chat-avatar {
  flex: none; width: 40px; height: 40px; border-radius: 50%;
  object-fit: cover; background: var(--bg-alt);
}
.chat-name {
  font-weight: 700; color: var(--ink);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-report { flex: none; font-size: .78rem; color: var(--muted); }
.chat-report:hover { color: var(--orange); }

.chat { margin: 20px 0 16px; display: flex; flex-direction: column; }

/* On a desktop the message list holds a fixed height and scrolls inside
   itself. That is what makes a new message push the old ones up while the
   page stays exactly where it is: the document never gets taller, so the
   window has no reason to move and the composer does not travel down the
   screen.
   
   Every earlier attempt moved the WINDOW instead — scrolling it to an
   anchor, or by the height just added — and moving the window is the jump.
   
   Only above 940px. Phones keep the plain scrolling page they have now;
   the viewport there has an address bar and a keyboard that resize it
   underneath you, and this is not the place to find that out again.
   
   max-height, not height: a short conversation stays short and gets no
   scrollbar, so nothing changes until there is enough to scroll. */
/* Everything below the desktop breakpoint — phones and small tablets. The
   same mechanism the desktop uses: the list holds a height and scrolls
   inside itself, so a new message pushes the old ones up and the page stays
   where it is. Nothing else about the page changes — no body surgery, no
   hidden footer, no reshaping the document. That was what went wrong the
   last two times, not this.

   svh, not vh. On a phone vh is the height with the address bar HIDDEN, so
   a vh-based list is taller than what you can actually see and the composer
   ends up below the fold. svh is the height with the bar SHOWING — so it
   fits whichever state the bar is in, erring on the side of a slightly
   short list rather than a composer you have to scroll to. The vh line
   above is the fallback for anything too old to know svh.

   Matched to 940px, the same point the nav collapses, so there is no band
   of screen widths between the two rules with neither. */
@media (max-width: 940px) {
  /* A conversation ends at the box you type in. Below it sat the footer:
     56px of padding above a stacked column of links, all of it on --ink,
     a warm near-black that reads as dark brown — then "Privacy & cookies"
     at the bottom of it. On a phone that is a screenful of nothing under
     every chat, and no messaging app has it.

     Hidden, not restructured. The page still scrolls exactly as it does
     now; it simply stops after the composer. The privacy link is in the
     footer of every other page. */
  body.chat-page .footer { display: none; }
  body.chat-page .section-chat { padding-bottom: 10px; }

  .chat {
    max-height: calc(100vh - 330px);
    max-height: calc(100svh - 330px);
    min-height: 180px;
    overflow-y: auto;
    scroll-behavior: auto;
  }
}

@media (min-width: 941px) {
  .chat {
    max-height: calc(100vh - 360px);
    min-height: 220px;
    overflow-y: auto;
    /* html sets scroll-behavior: smooth, which is right for the front
       page's anchor links and wrong here — it would glide to each new
       message instead of it simply being there. */
    scroll-behavior: auto;
    padding-right: 4px;
  }
}
.chat-empty { text-align: center; color: var(--muted); padding: 2.5rem 0; }

/* A row is one message. The avatar column is always there on their side,
   even when empty, so bubbles in a run stay on one left edge instead of
   stepping in and out as the avatar appears and disappears. */
.row { display: flex; align-items: flex-end; gap: 8px; margin-top: 2px; }
.row-start { margin-top: 10px; }
.row-mine  { justify-content: flex-end; }
.row-avatar { flex: none; width: 28px; height: 28px; }
.row-avatar img {
  width: 100%; height: 100%; border-radius: 50%; object-fit: cover; display: block;
}
.row-avatar .chat-avatar-none { font-size: .8rem; }

.bubble {
  margin: 0; max-width: min(72%, 32rem);
  padding: 10px 15px;
  font-size: .98rem; line-height: 1.5;
  white-space: pre-wrap; overflow-wrap: anywhere;
  border-radius: 20px;
}
/* Both sides wear the same tan. Which is why the bubble can never run the
   full width: with no colour to tell them apart, the gutter on the opposite
   side IS the signal for who said it, together with the avatar that only
   ever appears on theirs.

   The fill is only 1.08:1 against the cream page, so the border and the
   shadow are what make a bubble read as a bubble at all. That is not a
   failing of this palette — Messenger's own grey-on-white sits at about
   1.1:1 — but it does mean the outline is load-bearing here rather than
   decorative, now that colour no longer separates the two sides. Text on
   the fill is 13.52:1, which is where the contrast that matters lives. */
.row-theirs .bubble,
.row-mine .bubble {
  background: var(--bg-alt);
  color: var(--ink);
  border: 1px solid var(--line);
  box-shadow: 0 1px 2px rgba(43,33,24,.05);
}

/* Square off the inner corners of a run so consecutive messages read as one
   block of speech rather than a stack of separate cards. */
.row-theirs:not(.row-start) .bubble { border-top-left-radius: 6px; }
.row-theirs:not(.row-end)   .bubble { border-bottom-left-radius: 6px; }
.row-mine:not(.row-start)   .bubble { border-top-right-radius: 6px; }
.row-mine:not(.row-end)     .bubble { border-bottom-right-radius: 6px; }

/* Read / Unread, under the last of your own run only. Repeating it beneath
   every bubble adds nothing and reads as anxious. */
.row-status {
  margin: 3px 2px 0; text-align: right;
  font-size: .72rem; font-weight: 700; letter-spacing: .02em;
}
.row-status.is-read   { color: var(--muted); }
.row-status.is-unread { color: var(--blue); }

/* ---- the composer ---- */
.composer {
  display: flex; align-items: flex-end; gap: 10px;
  padding-top: 14px; border-top: 1px solid var(--line);
}
.composer textarea {
  flex: 1; min-height: 46px; max-height: 40vh;
  padding: 12px 18px;
  font-family: inherit; font-size: .98rem; line-height: 1.5;
  border: 1.5px solid var(--line); border-radius: 23px;
  background: #fff; color: var(--ink); resize: vertical;
}
.composer textarea:focus {
  outline: none; border-color: var(--orange);
  box-shadow: 0 0 0 4px rgba(178,76,14,.14);
}
.composer-send {
  flex: none; width: 46px; height: 46px; border-radius: 50%;
  border: 0; cursor: pointer;
  background: linear-gradient(135deg, var(--orange), var(--orange-dk));
  color: #fff; font-size: 1.05rem; line-height: 1;
  box-shadow: 0 6px 18px rgba(178,76,14,.32);
  transition: transform .15s ease;
}
.composer-send:hover { transform: translateY(-2px); }
.composer-send:focus-visible { outline: 3px solid var(--blue); outline-offset: 3px; }

@media (max-width: 620px) {
  /* Narrower than it was when the two sides were different colours: on a
     phone the gutter is the only thing saying which way a message points. */
  .bubble { max-width: 76%; }

  /* Three actions plus a face and a name will not sit on one phone line, so
     the card becomes two: the conversation on top, what you can do about it
     underneath, pushed right and separated by a rule. */
  .citem { flex-wrap: wrap; padding: 12px; gap: 8px; }
  .clink { flex: 1 1 100%; }
  .cface { width: 50px; height: 50px; }
  .cactions {
    flex: 1 1 100%; justify-content: flex-end;
    padding-top: 8px; border-top: 1px solid var(--line);
  }
  /* Full tap targets down here, where there is room for them. */
  .cact { padding: 9px 12px; }
}
@media (prefers-reduced-motion: reduce) {
  .composer-send:hover { transform: none; }
}

/* Saved Matches heading — smaller than a normal h1 but still heavy, in the
   site's text-safe orange (4.96:1 on cream, so it clears AA at this size). */
.saved-head {
  font-size: clamp(1.5rem, 3.2vw, 2rem);
  font-weight: 800;
  color: var(--orange);
  line-height: 1.2;
}

/* "Saved Matches" in the site blue (6.89:1 on cream, 7.27:1 on white). */
.eyebrow-blue { color: var(--blue); }
.link-blue { color: var(--blue); font-weight: 650; }
.link-blue:hover { color: var(--blue-dk); }
.btn-ghost-blue { border-color: var(--blue); color: var(--blue); }
.btn-ghost-blue:hover { border-color: var(--blue-dk); color: var(--blue-dk); background: #eaf1f6; }

/* Two steps up the scale from the default .78rem eyebrow. Letter-spacing is
   eased off slightly: .12em is tuned for small caps and reads too loose once
   the type gets bigger. */
.eyebrow-lg {
  font-size: 1.05rem;
  letter-spacing: .08em;
}

/* ---------------- completed match actions ---------------- */
.mactions { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; align-items: center; }
.minline { margin: 0; }

.mbtn {
  font-family: inherit; font-size: .82rem; font-weight: 700;
  letter-spacing: .02em; padding: 7px 15px; border-radius: 999px;
  border: 1.5px solid transparent; cursor: pointer; line-height: 1.4;
  display: inline-block; white-space: nowrap;
  transition: transform .12s ease, box-shadow .12s ease, filter .12s ease;
}
.mbtn:not(:disabled):hover { transform: translateY(-1px); box-shadow: var(--shadow); }

/* Inactive: still legible, clearly not available. Kept at a readable grey
   rather than a faint tint, so a disabled control can still be read. */
.mbtn:disabled {
  background: #ece2cf; border-color: #ded0b6; color: #8b7a63;
  cursor: default; box-shadow: none;
}

/* 1 — vote ongoing (orange). Never pressable; lights up while her vote runs. */
.mbtn-vote.is-live:disabled {
  background: var(--orange); border-color: var(--orange); color: #fff;
  cursor: default;
}

/* 2 — message (mustard) */
.mbtn-msg  { background: var(--gold); border-color: var(--gold); color: var(--ink); }
.mbtn-msg:hover { color: var(--ink); }

/* 3 — delete (blue) */
.mbtn-del  { background: var(--blue); border-color: var(--blue); color: #fff; }

@media (max-width: 620px) {
  .mactions { width: 100%; }
  .mbtn { flex: 1 1 auto; text-align: center; }
}

/* Awaiting Vote — she hasn't opened one yet. Deliberately neutral rather than
   a fourth brand colour: it's the absence of a state, not a state of its own,
   and a dashed edge reads as "not yet" without competing with the lit orange. */
.mbtn-wait:disabled {
  background: transparent;
  border: 1.5px dashed #cdbb9c;
  color: #8b7a63;
}

/* ---------------- voting quota ---------------- */
.quota {
  margin: 18px 0 24px; padding: 16px 20px; max-width: 560px;
  background: var(--bg-alt); border: 1px solid var(--line);
  border-radius: var(--radius);
}
.quota.is-met { border-color: #bcd0ab; background: #eaf0e2; }
.quota-line { margin: 0 0 8px; color: var(--ink); }
.quota-line strong { font-size: 1.3rem; color: var(--blue); }
.quota.is-met .quota-line strong { color: #43703a; }
.quota-bar {
  height: 8px; border-radius: 4px; background: var(--line); overflow: hidden;
}
.quota-bar span {
  display: block; height: 100%; width: var(--pct, 0%);
  background: linear-gradient(90deg, var(--gold), var(--orange));
}
.quota.is-met .quota-bar span { background: #43703a; }

/* ================= intro video ================= */
.intro[hidden] { display: none; }

.intro {
  position: fixed; inset: 0; z-index: 9999;
  background: #1a140e;
  display: grid; place-items: center;
  opacity: 0; transition: opacity .45s ease;
}
.intro.is-active  { opacity: 1; }
.intro.is-leaving { opacity: 0; pointer-events: none; }
.intro-open, .intro-open body { overflow: hidden; }

/* The clip is 9:16. Contained, it would sit in black bars on any desktop;
   a blurred blow-up of the poster fills the rest so the screen reads as one
   image rather than a phone video pasted onto black. */
.intro-backdrop {
  position: absolute; inset: 0;
  background: url("intro-poster.jpg") center / cover no-repeat;
  filter: blur(38px) brightness(.42) saturate(1.15);
  transform: scale(1.15);          /* hides the soft edge blur leaves */
}

.intro-video {
  position: relative;
  max-width: 100%; max-height: 100%;
  width: auto; height: 100%;
  object-fit: contain;
  box-shadow: 0 30px 90px rgba(0,0,0,.55);
}

.intro-bar {
  position: absolute; left: 0; right: 0; bottom: 0;
  height: 3px; background: rgba(255,255,255,.18); z-index: 2;
}
.intro-bar-fill {
  display: block; width: 0; height: 100%;
  background: linear-gradient(90deg, var(--gold), var(--orange));
  transition: width .2s linear;
}

.intro-controls {
  position: absolute; right: 22px; bottom: 26px; z-index: 3;
  display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
}
.intro-skip, .intro-sound {
  font-family: inherit; font-size: .92rem; font-weight: 650;
  padding: 11px 22px; border-radius: 999px; cursor: pointer;
  border: 1px solid rgba(255,255,255,.34);
  background: rgba(26,20,14,.6); color: #fff;
  backdrop-filter: blur(8px);
  transition: background .15s ease, transform .15s ease, border-color .15s ease;
}
.intro-skip:hover, .intro-sound:hover {
  background: rgba(26,20,14,.85); border-color: rgba(255,255,255,.7);
  transform: translateY(-1px);
}
/* The sound control is the loud one: the clip has audio, but no browser will
   autoplay it, so this has to be noticed to be used. */
.intro-sound {
  background: var(--gold); color: var(--ink); border-color: transparent;
  font-weight: 750;
}
.intro-sound:hover { background: #eeb043; color: var(--ink); }
.intro-sound.is-on {
  background: rgba(26,20,14,.6); color: #fff;
  border-color: rgba(255,255,255,.34);
}
.intro-skip {
  background: linear-gradient(135deg, var(--orange), var(--orange-dk));
  border-color: transparent;
  box-shadow: 0 6px 18px rgba(178,76,14,.45);
}
.intro-skip:focus-visible, .intro-sound:focus-visible {
  outline: 3px solid #fff; outline-offset: 3px;
}

@media (max-width: 620px) {
  .intro-controls { left: 14px; right: 14px; bottom: 18px; justify-content: space-between; }
  .intro-skip, .intro-sound { padding: 10px 16px; font-size: .86rem; }
}

/* No `.intro { display: none }` for reduced motion any more. That rule was
   written when the overlay only ever AUTOPLAYED, where suppressing it was
   right. Now the skate is a button on most pages, and hiding the overlay
   outright turned every one of those into a button that did nothing for
   these visitors. The preference says "don't move things at me unbidden",
   and a press is bidden — so clip.js refuses the autoplay and allows the
   click, which is the distinction the preference is actually about. */

/* Poll screenshot inside the phone mock. The frame keeps its own padding for
   the card mock; a screenshot should run edge to edge instead. */
.phone-screen--shot { padding: 0; }
.phone-shot {
  width: 100%; height: 100%;
  object-fit: cover; object-position: top;
  display: block; border-radius: 34px;
}

/* Section heading in the site blue (6.75:1 on cream, comfortably AA). */
.h2-blue { color: var(--blue); }

/* Section labels on the dashboard. The base h2 runs up to 2.6rem, which is
   page-title weight — too loud for a list header repeated four times. */
.h2-sec { font-size: 1.35rem; font-weight: 750; }

/* ---------------- swapping your own photos ---------------- */
.pslot { display: flex; flex-direction: column; gap: 10px; }
.pphoto-empty {
  display: flex; align-items: center; justify-content: center;
  aspect-ratio: 4 / 5; background: var(--bg-alt);
  border: 1px dashed var(--line); color: var(--muted); font-size: .9rem;
}
.pswap { margin: 0; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* The real file input is hidden inside its own label, so the label IS the
   button — no JS needed to open the picker. */
.pswap-pick { cursor: pointer; display: inline-block; }
.pswap-pick input[type=file] {
  position: absolute; width: 1px; height: 1px;
  opacity: 0; overflow: hidden; clip: rect(0 0 0 0);
}
.pswap-pick:focus-within { outline: 2px solid var(--blue); outline-offset: 2px; }
.pswap-name {
  font-size: .8rem; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 12ch;
}

/* "Rule" label. Mustard as a filled badge with dark text rather than mustard
   text: #e0a12e on white is about 2:1, unreadable at this size, while ink on
   mustard is 6.98:1. Same colour, legible. */
.rule-tag {
  display: inline-block;
  background: var(--gold); color: var(--ink);
  font-size: .72rem; font-weight: 800; letter-spacing: .08em;
  text-transform: uppercase;
  padding: 3px 9px; border-radius: 6px;
  margin-right: 7px; vertical-align: 1px;
}

/* ---------------- homepage cartoon strip ---------------- */
/* Cream rather than the old gradient band: the panels are greyscale line art
   and sat badly on a saturated blue-to-orange wash. */
.strip-band { background: var(--bg-alt); border-block: 1px solid var(--line); }

.strip {
  display: grid;
  grid-template-columns: 1fr 1fr;   /* reading order: 1 2 / 3 4 */
  gap: 18px;
  max-width: 1000px;
  margin: 0 auto;
}
.strip-panel { margin: 0; }
.strip-panel img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--line);
  border-radius: var(--radius);
  box-shadow: var(--shadow);
  background: #fff;
}

/* One column below the fold width — two 16:9 panels side by side get too
   small to read the speech bubbles on a phone. */
@media (max-width: 760px) {
  .strip { grid-template-columns: 1fr; gap: 14px; }
}

/* Sign-in heading: two steps above the eyebrow beneath it, so the page has a
   clear title again without returning to the full h1 scale. Letter-spacing
   eases off as the type grows — .08em is tuned for small caps. */
.h1-match {
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -.01em;
  text-transform: none;
  color: var(--orange);
  margin-bottom: 1.2rem;
}

/* "New here?" in the site orange (4.96:1 on cream — clears AA). */
.altbox h2 { color: var(--orange); }

/* Signup heading: smaller than the default h1 scale but bold, in the site
   orange. Matches .h1-match on the sign-in page in size and weight, with the
   colours swapped. */
.h1-soft {
  font-size: 1.9rem;
  font-weight: 800;
  letter-spacing: -.01em;
  color: var(--orange);
}

/* .hint carries no bottom margin — deliberately, since it usually sits tight
   under the field it explains. Some hints instead stand between two blocks:
   introducing the one below, or closing off the one above. None of .qbox,
   .field-row or .field has a top margin to supply the gap, so those hints
   need it themselves. .hint-spaced marks that case and leaves field-level
   hints hugging their inputs. */
.hint-spaced { margin-bottom: 20px; }

/* Each .field carries 20px of bottom margin, which pushed the format note a
   long way clear of the upload boxes it describes. Dropping it on this row
   leaves only the hint's own 6px, so the note reads as a caption on the
   inputs rather than as a floating remark. */
.field-row-tight .field { margin-bottom: 0; }

/* Question picker: the dropdown and the write-your-own box are both visible,
   so each needs its own label and a divider to show they're alternatives. */
.qlabel {
  display: block; font-size: .8rem; font-weight: 700;
  letter-spacing: .04em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 6px;
}
.qor {
  margin: 4px 0 10px; font-size: .82rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .08em; color: var(--muted);
  display: flex; align-items: center; gap: 10px;
}
.qor::before, .qor::after {
  content: ""; flex: 1; height: 1px; background: var(--line);
}
.qbox .hint { margin-top: 8px; }

/* Name and age at the top of a profile, in the site blue (6.75:1 on cream). */
.h1-name { color: var(--blue); }

/* "<Name> asks" above her questions, in the site orange (4.96:1 on cream). */
.h2-orange { color: var(--orange); }

/* The messaged-you line: count in orange (inherited from .vcount strong),
   the words beside it in blue. */
.c-blue { color: var(--blue); }

/* ---------------- destructive actions ---------------- */
/* Red, and only ever on something irreversible — if it were used for
   ordinary actions it would stop meaning anything. */
.mini-danger {
  background: #fff; border-color: #a8331f; color: #a8331f; font-weight: 700;
}
.mini-danger:hover { background: #a8331f; border-color: #a8331f; color: #fff; }
.btn-danger { background: #a8331f; border-color: #a8331f; color: #fff; }
.btn-danger:hover { background: #8a2717; border-color: #8a2717; }

/* Report link. Deliberately quiet — it must be findable when needed without
   suggesting everyone is a suspect. */
.mini-report       { border-color: #d8c6ae; color: var(--muted); background: #fff; }
.mini-report:hover { border-color: var(--orange); color: var(--orange-dk); }
.reportline        { margin-top: 1.5rem; }

/* The way to write to someone, directly under their photos. .mbtn is an
   inline-flex pill built for the card grids, so it needs a line of its own
   here to sit under a full-width photo pair rather than hugging the left of
   a paragraph. Sized up a little: on a card it is one of several, here it is
   the only thing being asked for. */
.msgline           { margin-top: 1.5rem; }
.msgline .mbtn     { font-size: 1rem; padding: 12px 22px; }

/* ---------------- the skate that lands on Conversations ---------------- */
/* Shown only while something is unread. It is positioned against this
   wrapper rather than the nav, so it tracks the word wherever the row
   reflows instead of being pinned to a guessed offset. */
.nav-msg {
  position: relative;
  /* inline-flex, so the tab sits on the same centre line as its neighbours
     rather than on the text baseline of an inline-block. */
  display: inline-flex;
  align-items: center;
}

/* Sits above and slightly left of the C, tipped back as though it has just
   rolled up and stopped. Small — 22px against a 30px header skate — because
   this one is a notification, not the brand. */
.nav-skate {
  position: absolute;
  top: -15px;
  left: -11px;
  width: 22px;
  height: 21px;
  padding: 0;
  border: 0;
  background: url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2032%2032%22%3E%3Cpath%20d%3D%22M6.5%206h7.2a2.8%202.8%200%200%201%202.8%202.8v5.4l5.9%202.2A3.6%203.6%200%200%201%2024.7%2020H6.5a2%202%200%200%201-2-2V8a2%202%200%200%201%202-2z%22%20fill%3D%22%231c5b86%22%2F%3E%3Crect%20x%3D%224.5%22%20y%3D%229.2%22%20width%3D%2212%22%20height%3D%221.8%22%20fill%3D%22%23b24c0e%22%2F%3E%3Crect%20x%3D%224.5%22%20y%3D%2212.1%22%20width%3D%2212%22%20height%3D%221.8%22%20fill%3D%22%23e0a12e%22%2F%3E%3Crect%20x%3D%224.5%22%20y%3D%2220.3%22%20width%3D%2221.5%22%20height%3D%222.6%22%20rx%3D%221.3%22%20fill%3D%22%232b2118%22%2F%3E%3Cpath%20d%3D%22M26.2%2020.6h1.6a1.6%201.6%200%200%201%201.6%201.6v2.2a1.8%201.8%200%200%201-1.8%201.8h-1.4z%22%20fill%3D%22%23b24c0e%22%2F%3E%3Ccircle%20cx%3D%229.4%22%20cy%3D%2225.8%22%20r%3D%223.3%22%20fill%3D%22%23e0a12e%22%20stroke%3D%22%232b2118%22%20stroke-width%3D%221.4%22%2F%3E%3Ccircle%20cx%3D%2220.8%22%20cy%3D%2225.8%22%20r%3D%223.3%22%20fill%3D%22%23e0a12e%22%20stroke%3D%22%232b2118%22%20stroke-width%3D%221.4%22%2F%3E%3C%2Fsvg%3E") center/contain no-repeat;
  appearance: none;
  -webkit-appearance: none;
  animation: skate-float 2.4s ease-in-out infinite;
  transform-origin: 60% 90%;
}
button.nav-skate { cursor: pointer; }
button.nav-skate:hover { animation-play-state: paused; transform: translateY(-3px) rotate(-8deg) scale(1.12); }
button.nav-skate:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 2px;
  border-radius: 4px;
}

/* A bob with a little roll in it, so it reads as hovering rather than as a
   sticker that failed to load. Deliberately slow and small: this sits in
   peripheral vision on every page, and anything livelier becomes something
   to escape rather than to press. */
@keyframes skate-float {
  0%, 100% { transform: translateY(0)     rotate(-6deg); }
  50%      { transform: translateY(-4px)  rotate(-11deg); }
}

/* Motion is the whole point of this one, so for a visitor who has asked for
   less of it the skate stays — it is how they know a message is waiting —
   and simply holds still. */
@media (prefers-reduced-motion: reduce) {
  .nav-skate { animation: none; transform: rotate(-6deg); }
  button.nav-skate:hover { transform: rotate(-6deg) scale(1.12); }
}

/* ---------------- your profile: one warm ground ---------------- */
/* The dashboard had white cards sitting inside a page whose main panel
   (.vbox) is tan, so the sections below it looked like a different site.
   Scoped to .me-page because .iitem and .qa-item are shared with the results
   page, the ballot and admin, where white cards are still right. */
.me-page .iitem,
.me-page .qa-item {
  background: var(--bg-alt);
}

/* ---------------- your account: one panel, not three cards ---------------- */
/* Your details / Go Dormant / Delete Profile are one decision area, so they
   share a box and are divided by hairlines rather than floating apart. */
.acct-box {
  background: var(--bg-alt);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
  margin-top: 12px;
}
.acct-row {
  display: flex; align-items: center; justify-content: space-between;
  gap: 14px; padding: 16px 20px;
  border-top: 1px solid var(--line);
  flex-wrap: wrap;
}
/* :first-child, not a class — the dormant row only exists for women, so the
   top row differs by page and hardcoding it would be wrong half the time. */
.acct-row:first-child { border-top: 0; }
.acct-label { color: var(--orange); }

/* Denim blue reads fine straight onto the light button — 6.90:1 on white —
   so unlike the gold it needs no inversion: blue words, blue outline. */
.mini-blue {
  background: #fff;
  border-color: var(--blue);
  color: var(--blue);
}
.mini-blue:hover {
  border-color: var(--blue-dk);
  color: var(--blue-dk);
  background: #eaf1f6;
}

/* All four account buttons the same width with the label centred, so the
   right-hand edge of the panel is a straight line rather than a ragged one.
   min-width rather than width: it grows if a label ever gets longer instead
   of clipping it. inline-block so the width applies to the <a>s as well as
   the <button>s. */
.acct-row .mini {
  display: inline-block;
  box-sizing: border-box;
  min-width: 156px;
  text-align: center;
}
.acct-row .minline { flex: none; }

/* ---------------- the header skate ---------------- */
/* On the front page the skate is a <button> that replays the intro. It must
   look exactly like the plain <span> it replaces elsewhere, so every browser
   default a button brings has to be undone. */
.brand-skate {
  padding: 0;
  border: 0;
  background-color: transparent;
  cursor: pointer;
  appearance: none;
  -webkit-appearance: none;
  /* The skate graphic is a background-image on .brand-mark; this keeps it. */
  display: block;
}
.brand-skate:hover { transform: translateX(2px); }
.brand-skate { transition: transform .15s ease; }
.brand-skate:focus-visible {
  outline: 2px solid var(--blue);
  outline-offset: 3px;
  border-radius: 4px;
}
@media (prefers-reduced-motion: reduce) {
  .brand-skate { transition: none; }
  .brand-skate:hover { transform: none; }
}

/* The wordmark carries the link home; .brand is now a plain container. */
.brand-word { color: inherit; text-decoration: none; }
.brand-word:hover { color: var(--orange); }

/* The two entry requirements at the top of signup — who may join at all.
   Not .hint, which is muted grey: these are conditions, not asides. Blue on
   the cream ground is 6.24:1. */
.signup-rule {
  color: var(--blue);
  font-weight: 700;
  /* Generous gap below: the Age and I-am fields sat almost against it, so the
     rule read as a label for them rather than as a condition of entry. */
  margin: 18px 0 26px;
}
