/* TrashTalk — Phase 2a skeleton styling.
   APPROXIMATION of the described identity (navy banner, gold bar, woven bg, serif content,
   card layout). The faithful fidelity pass replaces these with the real assets/colors/font. */

/* Self-hosted (no Google Fonts CDN — offline-safe, no third-party request from a private board) */
@font-face {
  font-family: 'Cinzel';
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: url('/static/fonts/cinzel-700.woff2') format('woff2');
}
/* Body serif: native Baskerville on Apple (what Scott matches to); Libre Baskerville elsewhere. */
@font-face {
  font-family: 'Libre Baskerville'; font-style: normal; font-weight: 400; font-display: swap;
  src: url('/static/fonts/libre-baskerville-400.woff2') format('woff2');
}
@font-face {
  font-family: 'Libre Baskerville'; font-style: normal; font-weight: 700; font-display: swap;
  src: url('/static/fonts/libre-baskerville-700.woff2') format('woff2');
}
@font-face {
  font-family: 'Libre Baskerville'; font-style: italic; font-weight: 400; font-display: swap;
  src: url('/static/fonts/libre-baskerville-400-italic.woff2') format('woff2');
}

:root {
  --navy: #21386f;        /* eyedropped from banner.png */
  --gold: #d2a32e;
  --panel: #ffffff;
  --ink: #1a1a1a;
  --muted: #6b6b6b;
  --card-border: #d8d8d8;
  --footer-bg: #f0f0f0;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  background: #efe9db url('/static/img/woven.png') repeat;
  font-family: Helvetica, Arial, sans-serif;
  color: var(--ink);
  overscroll-behavior-y: contain;   /* suppress the browser's native full-reload pull (we do our own) */
}

/* Pull-to-refresh indicator (mobile) — fixed strip at the very top; grows as you pull, spins while it
   re-fetches the wall list (same "refresh the wall" intent as an empty Post). Inert on non-touch. */
.ptr {
  position: fixed; top: 0; left: 0; right: 0; z-index: 950;
  height: 0; overflow: hidden; pointer-events: none;
  display: flex; align-items: center; justify-content: center;
  background: #fff; transition: height 0.18s ease;
}
.ptr-spinner {
  width: 22px; height: 22px; border-radius: 50%;
  border: 2px solid var(--card-border); border-top-color: var(--navy);
}
.ptr.ready .ptr-spinner { border-top-color: var(--gold); }   /* past threshold → release to refresh */
.ptr.loading .ptr-spinner { animation: ptr-spin 0.7s linear infinite; }
@keyframes ptr-spin { to { transform: rotate(360deg); } }

/* Lean, code-drawn banner — navy bar + gold accent + Cinzel wordmark (engraved small-caps). */
.banner {
  background: var(--navy);
  color: #fff;
  display: flex;
  align-items: center;
  gap: 14px;
  padding: 14px 22px;
  border-bottom: 3px solid var(--gold);
}
.brand-accent {
  width: 6px;
  align-self: stretch;
  background: var(--gold);
  border-radius: 1px;
}
.wordmark {
  font-family: 'Cinzel', Georgia, serif;
  font-weight: 700;
  font-size: 28px;
  letter-spacing: 1.5px;
  line-height: 1;
}

/* Sub-banner — the page's section identity, sized to the panel (smaller than the full-width league
   banner above). Echoes the masthead's gold accent + Cinzel wordmark. Text is per-page. */
.subbanner {
  background: var(--navy);               /* full-width page-section banner, detached (Option 1, detached) */
  border-radius: 8px;
  padding: 9px 18px;
  margin: 0 0 12px;                      /* detached — a gap to the composer/form below */
}
.subbanner-text {
  font-family: Helvetica, Arial, sans-serif;   /* same face as the datebar — quieter than Cinzel */
  font-weight: 400; font-size: 16px; letter-spacing: 0.5px;   /* thinner stroke than the masthead */
  color: #fff; line-height: 1.2;
}

.panel {
  max-width: 760px;
  margin: 22px auto;
  background: var(--panel);
  border-radius: 10px;
  padding: 18px 26px;            /* side breathing room slightly > top/bottom (outside the cards) */
  box-shadow: 0 2px 10px rgba(0,0,0,0.15);
}

/* Compose — the dual Post ritual. Shares the card grid: a 52px avatar gutter + a content column
   capped to the SAME measure as a post. Frameless, but the box model matches .card (transparent
   border + matching padding) so the write-box edges line up with the read-box (Candidate 2). */
.compose {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  background: #f3f6fb;             /* distinct "composer" surface — anchored & special, not floating */
  border: 1px solid #d2dcea;       /* soft navy-tinted frame; still a 1px box like .card → alignment holds */
  border-radius: 12px;             /* detached sub-banner above; composer keeps its full rounding */
  padding: 14px 22px;              /* horizontal 22 matches .card so the textarea == a post's measure */
  margin: 0 0 16px;                /* the sub-banner now sits above and leads the eye in */
}
.compose-avatar {
  flex: 0 0 auto;
  position: relative; left: -4px;   /* same nudge as the post mug shot */
  width: 52px; height: 52px;
  border-radius: 6px; object-fit: cover; background: #e2e2e2;
}
.compose-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 8px; }
.compose-text {
  width: 100%;
  font-family: Baskerville, 'Libre Baskerville', Georgia, serif;
  font-size: 17px; line-height: 1.3;
  padding: 12px 14px;
  border: 1px solid var(--card-border);
  border-radius: 10px;
  resize: vertical;        /* drag to enlarge — PRESERVE */
  min-height: 92px;
  outline: none;
}
.compose-text:focus { border-color: var(--navy); }
.compose-actions { display: flex; gap: 8px; align-items: center; }
.compose-author {
  flex: 0 0 auto; width: 170px;        /* right-sized — it only holds a name (Candidate 2) */
  font-size: 14px; padding: 8px 11px;
  border: 1px solid var(--card-border); border-radius: 8px; outline: none;
}
.compose-author:focus { border-color: var(--navy); }
.compose .btn { flex: 0 0 auto; padding: 10px 20px; font-size: 15px; }   /* a touch smaller in compose */

/* Mobile composer chrome (Phase 2e): bottom bar + full-screen modal. On desktop, compose-body is
   transparent (display:contents) so the avatar-gutter layout is unchanged, and the header + bar hide. */
.compose-body { display: contents; }
.compose-mhead, .compose-bar { display: none; }
.compose-mtitle { font-weight: 600; font-size: 16px; color: var(--ink); }
.compose-cancel { background: none; border: none; color: var(--navy); font-size: 15px; cursor: pointer; padding: 4px 2px; }
.compose-bar-avatar { width: 32px; height: 32px; border-radius: 6px; object-fit: cover; background: #e2e2e2; flex: 0 0 auto; }
.compose-bar-text { flex: 1 1 auto; color: var(--muted); font-size: 15px; }
.compose-bar-icon { color: var(--navy); flex: 0 0 auto; }

/* "On This Day" — the seam between compose and the wall. A distinct gold-tinted inset with the
   brand accent strip; reads as a memory feature, NOT a wall post. Present only when a memory
   exists; per-session dismissible (the × ). */
.onthisday {
  display: flex; gap: 12px; align-items: flex-start;
  background: #faf3e0; border: 1px solid #e6cf94; border-radius: 10px;
  padding: 12px 16px; margin-bottom: 16px;
}
.otd-accent { width: 5px; align-self: stretch; background: var(--gold); border-radius: 1px; flex: 0 0 auto; }
.otd-body { flex: 1 1 auto; min-width: 0; }
.otd-label {
  font-family: 'Cinzel', Georgia, serif; font-weight: 700; font-size: 14px;
  letter-spacing: 1px; text-transform: uppercase; color: #8a5a12; margin-bottom: 10px;
}
.otd-text {
  font-family: Baskerville, 'Libre Baskerville', Georgia, serif;
  font-size: 16px; line-height: 1.3; color: var(--ink);
}
.otd-byline {
  display: block; margin-top: 6px; text-align: right;
  font-style: italic; font-size: 18px; color: #8a5a12;   /* OTD gold, ties the attribution to the inset */
  text-transform: capitalize;   /* display-only — names read better capitalized (author stays byte-original) */
}
.otd-dismiss {
  flex: 0 0 auto; background: none; border: none; padding: 2px; cursor: pointer;
  color: #b08a2e; line-height: 0; align-self: flex-start;
}
.otd-dismiss:hover { color: #8a5a12; }

/* Separator that REPLACES On This Day when it's dismissed — a thicker bar in OTD's gold palette
   (distinct from the grey card borders), so the composer and the stream stay cleanly divided
   without adding yet another thin grey line to a page already full of them. */
.wall-sep {
  height: 4px;                          /* border-box: 2px cream center + 1px gold top/bottom = 4px */
  background: #faf3e0;                  /* OTD background (cream) in the middle */
  border-top: 1px solid #e6cf94;        /* OTD border gold, top + bottom — a soft striated ribbon */
  border-bottom: 1px solid #e6cf94;
  margin: 0 0 18px;
}

/* Cascading refresh: after a Post-refresh / pull-to-refresh swaps #postlist, each card fades in with a
   small staggered delay — a quick "wave" that makes the refresh felt (psychological receipt for the action).
   Gated on .refreshing (added in JS post-swap) so it does NOT fire on initial load or reaction/edit swaps.
   Stagger capped at 12 so the off-screen tail doesn't drag the wave out. Tune --card duration/45ms here. */
@keyframes card-rise { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
#postlist.refreshing > .card {
  animation: card-rise 340ms ease-out backwards;
  animation-delay: calc(min(var(--card-i, 0), 12) * 45ms);
}

.card {
  display: flex;
  gap: 12px;
  border: 1px solid var(--card-border);
  border-radius: 10px;
  padding: 16px 22px;            /* inside: left/right a touch more than top/bottom */
  margin-bottom: 18px;           /* outside: vertical gap between cards */
}

.avatar {
  flex: 0 0 auto;
  position: relative; left: -4px;   /* nudge the mug shot slightly left */
  width: 52px; height: 52px;
  border-radius: 6px;
  object-fit: cover;
  background: #e2e2e2;   /* shown only while the image loads */
}

.body { flex: 1 1 auto; min-width: 0; }

/* Mobile-only post header (avatar + author/timestamp). Hidden on desktop; shown at the phone breakpoint. */
.card-mhead { display: none; }

/* Serif body font is part of the identity (matches the original: Baskerville 17px / 1.3 / #111) */
.content {
  font-family: Baskerville, 'Libre Baskerville', Georgia, serif;
  font-size: 17px;
  line-height: 1.3;
  color: #111;
  word-wrap: break-word;
}
.content img { max-width: 100%; height: auto; }

/* OG link preview — Facebook-style: navy domain bar, thumbnail + title/desc; opens new window.
   Reflows on narrow screens (thumbnail stacks above the text) for mobile. */
.oglink {
  display: block; margin: 10px 0 2px; max-width: 540px;
  border: 1px solid var(--card-border); border-radius: 10px; overflow: hidden;
  background: #fff; text-decoration: none; color: inherit;
}
.oglink:hover { border-color: var(--navy); }
.og-domain {
  background: var(--navy); color: #fff; font-size: 12px; padding: 5px 12px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.og-body { display: flex; gap: 12px; padding: 10px 12px; align-items: flex-start; }
.og-thumb { width: 96px; height: 96px; object-fit: cover; border-radius: 6px; flex: 0 0 auto; }
.og-text { min-width: 0; }
.og-title {
  font-weight: 600; font-size: 15px; color: var(--ink); line-height: 1.25; margin-bottom: 4px;
}
.og-desc {
  font-size: 13px; color: var(--muted); line-height: 1.35;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
@media (max-width: 480px) {
  .og-body { flex-direction: column; }       /* thumbnail stacks above text on phones */
  .og-thumb { width: 100%; height: 160px; }
}
#og-preview .oglink { animation: ogfade 0.3s ease; }   /* fade-in on paste (PRESERVE) */
@keyframes ogfade { from { opacity: 0; transform: translateY(-3px); } to { opacity: 1; } }

.footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 10px;
  margin-top: 10px;
  padding: 6px 10px;
  background: var(--footer-bg);
  border-radius: 6px;
  font-size: 12px;
  color: var(--muted);
}
.byline { color: #9a9a9a; }   /* background info — smaller + lighter than the reaction counts */

/* Reaction buttons — "coaster chip": square token + corner count badge (both-at-once allowed).
   Chip is 26px (≤ the old 28px pill) so the footer stays tight; the count badge is absolutely
   positioned (out of flow) so it never adds to the footer line height. */
.reactions { display: inline-flex; gap: 9px; flex: 0 0 auto; }
.rx {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 26px; height: 26px; padding: 0;
  background: #fff;
  border: 1px solid var(--card-border);
  border-radius: 7px;
  color: #41506e;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: border-color .12s, background .12s;
}
.rx-ic { width: 16px; height: 16px; display: block; fill: currentColor; }
.rx-ct {
  position: absolute; top: -6px; right: -6px;
  min-width: 16px; height: 15px; box-sizing: border-box; padding: 0 4px;
  background: var(--navy); color: #fff;
  font-family: Georgia, serif; font-size: 10px; font-weight: 700; line-height: 15px;
  text-align: center; border-radius: 8px; font-variant-numeric: tabular-nums;
}
.rx[data-rxtype="like"] .rx-ct:not(.zero) { background: #3f8f4f; }    /* thumbs up → green */
.rx[data-rxtype="finger"] .rx-ct:not(.zero) { background: #c0392b; }  /* the finger → red */
.rx-ct.zero { background: #c2c7d0; }    /* no reactions yet — present but muted (counts always visible) */
.rx:hover { border-color: var(--navy); }
.rx.on { background: #eef3fb; border-color: var(--navy); color: var(--navy); }
.rx.go { animation: rx-squish .42s cubic-bezier(.34,1.56,.64,1); }
@keyframes rx-squish {
  0% { transform: scale(1,1); }
  30% { transform: scale(1.18,.84); }
  58% { transform: scale(.9,1.1); }
  100% { transform: scale(1,1); }
}

/* Footer right group: EDIT control sits to the LEFT of the reactions (PRESERVE) */
.footer-right { display: inline-flex; align-items: center; gap: 12px; }
.editlink {
  display: inline-flex; align-items: center; gap: 4px;
  background: #fff; border: 1px solid var(--card-border); border-radius: 14px;
  padding: 2px 11px 2px 9px; font-size: 12px; line-height: 1.7;
  color: var(--muted); cursor: pointer;
}
.editlink svg { width: 12px; height: 12px; }
.editlink:hover { border-color: var(--navy); color: var(--navy); }

/* Inline 5-minute silent edit — only the content region swaps; tinted "editing" cue */
.edit-text {
  width: 100%;
  font-family: Baskerville, 'Libre Baskerville', Georgia, serif;
  font-size: 17px; line-height: 1.3;
  background: #f4f8ee;                 /* pale green/cream editing cue — PRESERVE */
  border: 1px solid #cdd8c5; border-radius: 8px;
  padding: 10px 12px; resize: vertical; min-height: 72px; outline: none;
}
.edit-text:focus { border-color: #4a90c2; }   /* blue focus border */
.edit-actions { display: flex; gap: 8px; margin-top: 8px; }
.btn-sm { padding: 7px 16px; font-size: 14px; border-radius: 7px; }
.btn-grey { background: #8a8a8a; }
.btn-grey:hover { background: #757575; }
.empty { color: var(--muted); font-style: italic; }

/* Top-right nav in the banner */
.topnav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 14px;
  color: #cdd6e6;
}
.topnav .who { color: #fff; font-weight: 600; }
.topnav a { color: #cdd6e6; text-decoration: none; }
.topnav a:hover { color: #fff; }
/* Search promoted to a discoverable pill (magnifier + label) — it's navigation, lives in the nav */
.nav-search {
  display: inline-flex; align-items: center; gap: 5px;
  color: #fff; border: 1px solid #5b6e9c; border-radius: 14px; padding: 3px 11px;
}
.nav-search:hover { border-color: #fff; }
.topnav form { margin: 0; display: inline; }
.linklike {
  background: none; border: none; padding: 0; cursor: pointer;
  color: #cdd6e6; font: inherit;
}
.linklike:hover { color: #fff; text-decoration: underline; }

/* Clean, flat, relabelable buttons (no Bootstrap gloss) */
.btn {
  background: var(--navy);
  color: #fff;
  border: none;
  border-radius: 8px;
  padding: 12px 24px;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
}
.btn:hover { background: #2c4a8c; }

/* Secondary action (Upload Photo) — subordinate to the sacred Post button: outline, lighter weight */
.btn-secondary {
  display: inline-flex; align-items: center; gap: 6px;
  background: #fff; color: var(--navy);
  border: 1px solid #b9c2d6; border-radius: 8px;
  padding: 9px 13px; font-size: 14px; font-weight: 600; cursor: pointer;
  flex: 0 0 auto;
}
.btn-secondary:hover { border-color: var(--navy); background: #f5f8fc; }

/* Login form */
.loginform { max-width: 340px; margin: 8px auto; display: flex; flex-direction: column; gap: 14px; }
.loginform h1 { font-family: 'Cinzel', Georgia, serif; font-size: 22px; margin: 4px 0 6px; }
.loginform label { display: flex; flex-direction: column; gap: 5px; font-size: 14px; color: var(--muted); }
.loginform input {
  font-size: 16px; padding: 11px 12px; border: 1px solid var(--card-border);
  border-radius: 8px; outline: none;
}
.loginform input:focus { border-color: var(--navy); }
.formerror { color: #b3261e; font-size: 14px; margin: 0; }

/* Search */
.searchform {
  display: flex; flex-direction: column; gap: 12px;
  background: #f3f6fb;             /* same anchored "input" surface as the composer (app-wide consistency) */
  border: 1px solid #d2dcea;
  border-radius: 12px;             /* detached sub-banner above; form keeps its full rounding */
  padding: 14px 22px;
  margin: 0 0 16px;               /* the sub-banner now sits above and leads the eye to the controls */
}
.field { display: flex; flex-direction: column; gap: 5px; font-size: 14px; color: var(--muted); }
.field input {
  font-size: 16px; padding: 10px 12px; border: 1px solid var(--card-border);
  border-radius: 8px; outline: none;
}
.field input:focus { border-color: var(--navy); }
.search-dates { display: flex; gap: 12px; }
.search-dates .field { flex: 1; }
.search-controls { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.searchform .btn { padding: 10px 20px; font-size: 15px; }   /* match the composer's Post button */
.sort-toggle { display: inline-flex; gap: 14px; font-size: 14px; color: var(--ink); }
.sort-toggle label { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.search-count { font-size: 13px; color: var(--muted); margin: 0 0 14px; }

.search-help { color: var(--ink); }
.search-help h2 { font-family: 'Cinzel', Georgia, serif; font-size: 20px; margin: 6px 0 4px; }
.search-help-lead { color: var(--muted); margin: 0 0 12px; }
.search-help ul { padding-left: 20px; line-height: 1.6; }
.search-help li { margin-bottom: 6px; }
.search-help code {
  background: #f0f2f5; border: 1px solid #e0e3e8; border-radius: 4px;
  padding: 1px 5px; font-size: 13px;
}

/* ── Mobile (Phase 2e) — foundation reflow. "Ease of use is king": reclaim width, bigger touch
   targets on reactions + Edit, stack the composer/search controls. Card stays avatar-left for now
   (the full §5 avatar+author stack is a pending decision). Composer stays top-anchored (§5 fallback;
   the bottom slim-bar → modal composer is the pending decision). Verified at ~390px. */
@media (max-width: 600px) {
  /* Panel: reclaim horizontal space on small screens */
  .panel { margin: 12px auto; padding: 14px 14px; border-radius: 8px; }

  /* Masthead: shrink the wordmark; nav drops to its own full-width row */
  .banner { flex-wrap: wrap; gap: 8px 10px; padding: 12px 16px; }
  .wordmark { font-size: 20px; letter-spacing: 1px; }
  .topnav { width: 100%; margin-left: 0; flex-wrap: wrap; gap: 10px 14px; }

  /* Composer: author fills the row with Photo tucked to its right; Post drops full-width below. */
  .compose { padding: 12px 14px; gap: 10px; }
  .compose-actions { flex-wrap: wrap; align-items: center; }
  .compose-author { flex: 1 1 auto; width: auto; min-width: 0; }
  .compose .btn { padding: 12px 22px; }
  .btn-secondary { padding: 11px 16px; }

  /* Cards → §5 stack (layout A): avatar+author header on top, content full-width, actions footer.
     The desktop left-gutter avatar + footer byline are hidden; a mobile header carries them, with
     author + timestamp stacked so the mug shot is balanced by two lines (not one). Footer = Edit +
     reactions, with fat-finger targets. */
  .card { display: block; padding: 14px 16px; }
  .card > .avatar { display: none; }
  .card-mhead { display: flex; align-items: center; gap: 10px; margin-bottom: 10px; }
  .mhead-avatar { width: 44px; height: 44px; border-radius: 6px; object-fit: cover; background: #e2e2e2; flex: 0 0 auto; }
  .mhead-meta { display: flex; flex-direction: column; line-height: 1.25; min-width: 0; }
  .mhead-author { font-family: Helvetica, Arial, sans-serif; font-weight: 600; font-size: 15px; color: var(--ink); }
  .mhead-ts { font-size: 12px; color: var(--muted); }
  .card .byline { display: none; }                /* author + timestamp now live in the header */
  .footer { padding: 8px 10px; }
  /* Reactions anchored hard right; Edit takes a fixed slot on the left (margin-right:auto). The
     reaction icons never move whether or not Edit is present. */
  .footer-right { display: flex; width: 100%; align-items: center; justify-content: flex-end; gap: 14px; }
  .footer-right .editlink { margin-right: auto; }
  .rx { width: 40px; height: 40px; border-radius: 9px; }   /* bigger chip — its own footer row, fat-finger target */
  .rx-ic { width: 22px; height: 22px; }
  .rx-ct { min-width: 18px; height: 17px; font-size: 11px; line-height: 17px; top: -7px; right: -7px; }
  .editlink { padding: 7px 13px; font-size: 14px; border-radius: 16px; }
  .editlink svg { width: 14px; height: 14px; }
  .otd-dismiss { padding: 6px; }

  /* Search: stack the date range and the controls; full-width Search button */
  .search-dates { flex-direction: column; gap: 12px; }
  .search-controls { flex-direction: column; align-items: stretch; gap: 14px; }
  .search-controls .btn { width: 100%; padding: 13px 20px; }

  /* Composer → slim bottom bar that opens a full-screen modal (§5). The same form is reused, so the
     dual-Post ritual, idempotency, OG fetch, and live avatar preview all carry over unchanged. */
  /* The composer is parked as a fixed full-height sheet below the screen; tapping the bar slides it
     up (bottom-up entrance). Kept full-height (not a partial sheet) so the keyboard never fights it. */
  .compose {
    display: flex; flex-direction: column; align-items: stretch;  /* reset base flex-start so header/body span full width */
    position: fixed; inset: 0; z-index: 1000;
    margin: 0; padding: 0; border: none; border-radius: 0;
    background: #fff; overflow-y: auto;
    transform: translateY(100%); visibility: hidden;
    transition: transform 0.28s ease, visibility 0s 0.28s;
  }
  .compose-bar {
    display: flex; align-items: center; gap: 10px;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 900;
    background: #fff; border: none; border-top: 1px solid var(--card-border);
    padding: 10px 14px; text-align: left; cursor: pointer;
  }
  body { padding-bottom: 66px; }                    /* clearance so the fixed bar never covers the last post */
  body.compose-open { overflow: hidden; }           /* lock the wall behind the modal */
  body.compose-open .compose-bar { display: none; }
  body.compose-open .compose {
    transform: translateY(0); visibility: visible;
    transition: transform 0.28s ease, visibility 0s 0s;
  }
  /* Header: Cancel anchored left, "New post" truly centered (no Post button up here anymore). */
  .compose-mhead {
    display: flex; align-items: center; justify-content: center; gap: 12px;
    position: sticky; top: 0; background: #fff; z-index: 1;
    padding: 12px 16px; border-bottom: 1px solid var(--card-border);
  }
  .compose-mhead .compose-cancel { position: absolute; left: 14px; top: 50%; transform: translateY(-50%); }
  body.compose-open .compose-body { display: flex; flex-direction: row; gap: 12px; padding: 14px; }
  body.compose-open .compose-text { min-height: 200px; }
  /* Post now lives BELOW the form: full-width primary button, big thumb target, last in the stack. */
  body.compose-open .compose-actions { flex-wrap: wrap; }
  body.compose-open .compose-actions .btn {
    order: 3; flex: 1 1 100%; width: 100%;
    margin-top: 6px; padding: 15px; font-size: 16px;
  }
}
