/* ===========================================================================
   Playbooki v2.2 Stage 7 (rev2) — the post composer's audience control.

   SCOPE. Everything is under `.pb-aud`, or under `#formUpdateCreate` for the
   mobile compaction. This file styles the composer and must not reach the feed,
   the profile card or any shared control. Tier accents come from the
   `pb-tier-c-*` blocks in playbooki-tiers.css, which every page loading this
   file also loads — the palette stays single-sourced.

   WHY THE ROWS ARE LABELS. Each option is a <label> WRAPPING its own radio, so
   the whole row activates the input with no JavaScript, no `for`/`id` pairing to
   fall out of step, and native keyboard arrows and focus intact. Nothing here
   replaces the radio group with decorative buttons.

   SELECTED STATE IS NOT ONLY COLOUR. The radio's own filled dot carries the
   state; the ring and tint sit on top of it. Remove every colour from this file
   and the selection is still visible — which is also what makes the Public
   warning state safe to express in red.

   TWO STATES ON ONE ROW. Public carries an ordinary state and a warning state.
   Both icons and both descriptions are rendered by the server and CSS shows one
   of each pair from `:checked`, so the row cannot start out disagreeing with its
   own radio and the warning survives JavaScript being off.
   =========================================================================== */

.pb-aud {
  --pb-aud-line:   rgba(255,255,255,.10);
  --pb-aud-line-2: rgba(255,255,255,.16);
  --pb-aud-text:   #E8EDF2;
  --pb-aud-muted:  #97A3AE;
  --pb-aud-green:  #00C800;
  --pb-aud-red:    #FF6B6B;
  --pb-aud-fade:   .18s;
}

/* Every transition in this file goes through this one duration, so
   prefers-reduced-motion has a single place to switch them all off. */
@media (prefers-reduced-motion: reduce) {
  .pb-aud { --pb-aud-fade: 0s; }
}

/* The live region. Visually gone, still announced. `sr-only` exists in the
   site's Bootstrap, but this file cannot assume the cascade order, so the
   geometry is restated here rather than inherited. */
.pb-aud-live {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* The group's own caption. `span`, not a `<label>`: a label with no control is a
   label pointing at nothing, and the group is captioned by the radiogroup's
   aria-label. Uppercased HERE rather than in the language file — the strings are
   sentence case and it was the site's global text-transform that shouted. */
.pb-aud-legend {
  display: block;
  margin-bottom: .45rem;
  font-size: .72rem;
  font-weight: 800;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--pb-aud-muted);
}

.pb-aud-rows { display: grid; gap: .38rem; }

/* ── one option row ─────────────────────────────────────────────────────── */

.pb-aud-row {
  display: grid;
  grid-template-columns: auto auto 1fr auto;
  align-items: start;
  gap: .1rem .65rem;
  width: 100%;
  min-height: 44px;
  margin: 0;
  /* The row is taller than its own rows whenever `min-height` wins - which is
     every unselected row on mobile, where the description is collapsed away.
     Grid puts its row box at the START of the padded area by default, so the
     radio, icon, label and chevron all sat against the top of the pill with the
     leftover height dead below them. Centring the row track is the fix; on
     desktop, where the content already fills the box, it is a no-op. */
  align-content: center;
  padding: .55rem .7rem;
  border: 1px solid var(--pb-aud-line);
  border-radius: 12px;
  background-color: rgba(255,255,255,.02);
  cursor: pointer;
  transition:
    border-color var(--pb-aud-fade) ease,
    background-color var(--pb-aud-fade) ease,
    box-shadow var(--pb-aud-fade) ease;
}

.pb-aud-row:hover { border-color: var(--pb-aud-line-2); background-color: rgba(255,255,255,.04); }

/* The real radio. Opacity, not display:none — a display:none input is not
   focusable, and the keyboard has to reach this group. */
.pb-aud-input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}

.pb-aud-mark {
  grid-area: 1 / 1 / 3 / 2;
  align-self: center;
  width: 18px; height: 18px;
  border: 2px solid var(--pb-aud-line-2);
  border-radius: 50%;
  background: transparent;
  transition:
    border-color var(--pb-aud-fade) ease,
    box-shadow var(--pb-aud-fade) ease;
}

.pb-aud-input:checked + .pb-aud-mark {
  border-color: var(--pb-aud-green);
  box-shadow: inset 0 0 0 3px var(--pb-aud-green);
}

.pb-aud-input:focus-visible + .pb-aud-mark {
  outline: 2px solid #7FD37F;
  outline-offset: 2px;
}

.pb-aud-icon {
  grid-area: 1 / 2 / 3 / 3;
  align-self: center;
  display: block;
  width: 18px; height: 18px;
  font-size: 16px;
  line-height: 1.2;
  color: var(--pb-aud-muted);
  pointer-events: none;
  transition: color var(--pb-aud-fade) ease;
}

/* The site sizes bare `<i>` elements elsewhere; pin ours so the icon column
   cannot drift with an unrelated rule. */
.pb-aud-icon > i { font-size: 16px; line-height: 1; vertical-align: middle; }

/* Public's two icons occupy the SAME cell and cross-fade, so the row height
   never depends on which one is showing. */
.pb-aud-icon-swap { position: relative; }
.pb-aud-icon-swap > i {
  position: absolute;
  inset: 0;
  display: block;
  transition: opacity var(--pb-aud-fade) ease;
}
.pb-aud-icon-swap > .pb-aud-ico-warn { opacity: 0; }
.pb-aud-icon-swap > .pb-aud-ico-calm { opacity: 1; }

/* The name and the description together occupy the text column.

   The description is a CHILD of this element, not a sibling in the row's own
   second track. Placed as a grid item it renders correctly on first paint and
   then stops responding - `grid-template-rows` no longer interpolates, so the
   collapse freezes at whatever the first paint chose. Measured in Chrome. */
.pb-aud-body { grid-area: 1 / 3 / 3 / 4; min-width: 0; }

.pb-aud-name {
  display: block;
  font-size: .95rem;
  font-weight: 700;
  line-height: 1.3;
  /* The site uppercases labels globally. These are sentence-case strings and
     they are meant to read as sentences. */
  text-transform: none;
  letter-spacing: normal;
  color: var(--pb-aud-text);
  overflow-wrap: anywhere;
}

/* Both descriptions share ONE grid cell, so swapping them cannot resize the
   row and the fade has something to fade between. */
/* One cell, shared by both descriptions, so swapping them cannot resize the row
   and the fade has something to fade between. The COLLAPSE is `max-height` in
   the narrow block below, not a row track:

   `grid-template-rows: 0fr <-> 1fr` is the tidier idiom and it renders the right
   thing on first paint, but measured in Chrome it does not follow a change --
   after selecting another audience the computed tracks stayed at their loaded
   values (the newly selected row read 0px, the deselected one 15.8px) and the
   descriptions froze inverted. `max-height` interpolates reliably; the bound is
   only an upper limit, so the real height stays content-driven. */
.pb-aud-help-stack { display: grid; }
.pb-aud-help-stack > * { grid-area: 1 / 1 / 2 / 2; min-height: 0; }

.pb-aud-help {
  display: block;
  margin-top: .1rem;
  font-size: .8rem;
  line-height: 1.4;
  /* Same reason as .pb-aud-name: the site uppercases label text globally and
     these are full sentences. Measured on /home before this line existed — the
     help copy rendered as shouted capitals. */
  text-transform: none;
  letter-spacing: normal;
  color: var(--pb-aud-muted);
  overflow-wrap: anywhere;
  transition: opacity var(--pb-aud-fade) ease, color var(--pb-aud-fade) ease;
}

/* Only one of a stacked pair is reachable at a time: `visibility` keeps the
   hidden one out of the accessibility tree, which `opacity: 0` alone would not
   do, while still allowing the fade. */
.pb-aud-help-warn,
.pb-aud-summary { opacity: 0; visibility: hidden; }

/* ── selected ───────────────────────────────────────────────────────────── */

/* v2.2.1 — ONE source of truth for "selected".

   The selected treatment used to be driven by BOTH `:has(:checked)` and the
   `.is-selected` class in one selector list. The class is maintained by
   app-functions.js, and any moment the two disagree — a browser restoring form
   state on back navigation after the first-paint sync had already run — two
   rows wear the ring at once. That is the double-selected composer the owner
   photographed: a checked Public radio in one row, a stale green `.is-selected`
   on the row beneath it.

   So the class is now a FALLBACK ONLY, applied where `:has()` is unsupported.
   In every engine that understands `:has()` the ring follows the radio and
   nothing else, and a stale class cannot paint a second selection. */
.pb-aud-row:has(.pb-aud-input:checked) {
  border-color: rgba(0,200,0,.45);
  background-color: rgba(0,200,0,.07);
  box-shadow: 0 0 0 1px rgba(0,200,0,.18);
}

.pb-aud-row:has(.pb-aud-input:checked) .pb-aud-icon { color: var(--pb-aud-green); }

@supports not selector(:has(*)) {
  .pb-aud-row.is-selected {
    border-color: rgba(0,200,0,.45);
    background-color: rgba(0,200,0,.07);
    box-shadow: 0 0 0 1px rgba(0,200,0,.18);
  }
  .pb-aud-row.is-selected .pb-aud-icon { color: var(--pb-aud-green); }
}

/* ── Public, selected: the caution lives IN the row, not ON it ──────────── */

/* v2.2.1: Public uses the requested red ring, tint, icon and warning text. */
.pb-aud-row.is-public:has(.pb-aud-input:checked) {
  border-color: rgba(255,107,107,.58);
  background-color: rgba(255,107,107,.09);
  box-shadow: 0 0 0 1px rgba(255,107,107,.16);
}

.pb-aud-row.is-public:has(.pb-aud-input:checked) .pb-aud-icon { color: var(--pb-aud-red); }

.pb-aud-row.is-public:has(.pb-aud-input:checked) .pb-aud-mark {
  border-color: var(--pb-aud-red);
  box-shadow: inset 0 0 0 3px var(--pb-aud-red);
}

.pb-aud-row.is-public:has(.pb-aud-input:checked) .pb-aud-ico-warn { opacity: 1; }
.pb-aud-row.is-public:has(.pb-aud-input:checked) .pb-aud-ico-calm { opacity: 0; }

.pb-aud-row.is-public:has(.pb-aud-input:checked) .pb-aud-help-calm { opacity: 0; visibility: hidden; }

.pb-aud-row.is-public:has(.pb-aud-input:checked) .pb-aud-help-warn {
  opacity: 1;
  visibility: visible;
  color: #FFB4B4;
}

@supports not selector(:has(*)) {
  .pb-aud-row.is-public.is-selected {
    border-color: rgba(255,107,107,.58);
    background-color: rgba(255,107,107,.09);
    box-shadow: 0 0 0 1px rgba(255,107,107,.16);
  }
  .pb-aud-row.is-public.is-selected .pb-aud-icon { color: var(--pb-aud-red); }
  .pb-aud-row.is-public.is-selected .pb-aud-mark {
    border-color: var(--pb-aud-red);
    box-shadow: inset 0 0 0 3px var(--pb-aud-red);
  }
  .pb-aud-row.is-public.is-selected .pb-aud-ico-warn { opacity: 1; }
  .pb-aud-row.is-public.is-selected .pb-aud-ico-calm { opacity: 0; }
  .pb-aud-row.is-public.is-selected .pb-aud-help-calm { opacity: 0; visibility: hidden; }
  .pb-aud-row.is-public.is-selected .pb-aud-help-warn {
    opacity: 1;
    visibility: visible;
    color: #FFB4B4;
  }
}

/* ── the specific-tier disclosure ───────────────────────────────────────── */

.pb-aud-tier-block { display: contents; }

.pb-aud-chev {
  grid-area: 1 / 4 / 3 / 5;
  align-self: center;
  display: block;
  width: 18px; height: 18px;
  font-size: 15px;
  line-height: 1;
  color: var(--pb-aud-muted);
  pointer-events: none;
  transform: rotate(0deg);
  transition: transform var(--pb-aud-fade) ease, color var(--pb-aud-fade) ease;
}

.pb-aud-row.is-open .pb-aud-chev { transform: rotate(180deg); color: var(--pb-aud-green); }

/* The read-back replaces the description once a tier is chosen, in the same
   stacked cell — so the row answers its own question without growing. */
/* v2.2.1 - `:has()` first, the class only where `:has()` is unsupported, for
   the same reason as the selected ring above: a stale `.is-selected` must not
   be able to blank this row's description while another row is checked. */
.pb-aud-row.is-tier:has(.pb-aud-input:checked) .pb-aud-help-calm { opacity: 0; visibility: hidden; }

.pb-aud-row.is-tier:has(.pb-aud-input:checked) .pb-aud-summary.is-shown {
  opacity: 1;
  visibility: visible;
  color: var(--pb-aud-text);
}

@supports not selector(:has(*)) {
  .pb-aud-row.is-tier.is-selected .pb-aud-help-calm { opacity: 0; visibility: hidden; }
  .pb-aud-row.is-tier.is-selected .pb-aud-summary.is-shown {
    opacity: 1;
    visibility: visible;
    color: var(--pb-aud-text);
  }
  /* Open wins over selected here too, or the fallback would paint the summary
     and the description in the same cell while the list is open. */
  .pb-aud-row.is-tier.is-open.is-selected .pb-aud-help-calm { opacity: 1; visibility: visible; }
  .pb-aud-row.is-tier.is-open.is-selected .pb-aud-summary.is-shown { opacity: 0; visibility: hidden; }
}

/* While the list is open the row shows the description again — the summary
   would just repeat the highlighted choice two lines below it. */
/* v2.2.1 - written with the `:has()` term so it OUTRANKS the checked-row rule
   above (a `:has()` carries its argument's specificity). Measured before: the
   open row showed neither the description nor the summary. */
.pb-aud-row.is-tier.is-open .pb-aud-help-calm,
.pb-aud-row.is-tier.is-open:has(.pb-aud-input:checked) .pb-aud-help-calm { opacity: 1; visibility: visible; }
.pb-aud-row.is-tier.is-open .pb-aud-summary,
.pb-aud-row.is-tier.is-open:has(.pb-aud-input:checked) .pb-aud-summary { opacity: 0; visibility: hidden; }

.pb-aud-summary {
  display: flex;
  align-items: center;
  gap: .4rem;
  font-weight: 600;
}

/* The palette classes in playbooki-tiers.css expose `--pb-tier-accent`; they do
   NOT set `color`. Measured in Chrome: with `currentColor` here every dot
   rendered the inherited grey, including sky and amber. The fallback keeps an
   unclassed swatch visible rather than invisible. */
.pb-aud-swatch {
  flex: 0 0 auto;
  width: 10px; height: 10px;
  border-radius: 50%;
  background-color: var(--pb-tier-accent, currentColor);
}

/* The list. Indented to the option's own text column — the mark, the icon and
   their two gaps — so it reads as belonging to the row above rather than
   opening a third left edge. */
.pb-aud-tierlist {
  display: grid;
  gap: .25rem;
  margin: .3rem 0 .1rem;
  padding-left: calc(18px + 18px + 1.3rem + .7rem);
}

.pb-aud-tierlist.display-none { display: none !important; }

.pb-aud-tier {
  display: grid;
  grid-template-columns: auto 1fr auto;
  align-items: center;
  gap: .55rem;
  min-height: 44px;
  margin: 0;
  padding: .4rem .6rem;
  border: 1px solid var(--pb-aud-line);
  border-radius: 10px;
  background-color: rgba(255,255,255,.02);
  cursor: pointer;
  transition:
    border-color var(--pb-aud-fade) ease,
    background-color var(--pb-aud-fade) ease;
}

.pb-aud-tier:hover { border-color: var(--pb-aud-line-2); background-color: rgba(255,255,255,.05); }

.pb-aud-tier-input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  margin: 0;
  pointer-events: none;
}

.pb-aud-tier-dot {
  width: 10px; height: 10px;
  border-radius: 50%;
  background-color: var(--pb-tier-accent, currentColor);
}

.pb-aud-tier-name {
  min-width: 0;
  font-size: .88rem;
  font-weight: 600;
  line-height: 1.3;
  text-transform: none;
  letter-spacing: normal;
  color: var(--pb-aud-text);
  /* A creator can name a tier anything. It wraps; it never clips and never
     pushes the check mark off the row. */
  overflow-wrap: anywhere;
}

.pb-aud-tier-check {
  width: 16px; height: 16px;
  font-size: 14px;
  line-height: 1;
  color: var(--pb-aud-green);
  opacity: 0;
  transition: opacity var(--pb-aud-fade) ease;
}

/* The chosen tier is marked by the check AND by its own accent, so the identity
   of the choice and the fact of it being chosen are two separate signals. */
.pb-aud-tier:has(.pb-aud-tier-input:checked) {
  border-color: rgba(var(--pb-tier-rgb, 0,200,0), .55);
  background-color: rgba(var(--pb-tier-rgb, 0,200,0), .10);
}

.pb-aud-tier:has(.pb-aud-tier-input:checked) .pb-aud-tier-check { opacity: 1; }

.pb-aud-tier:has(.pb-aud-tier-input:focus-visible) {
  outline: 2px solid #7FD37F;
  outline-offset: 2px;
}

/* Advisory only — the server refuses a priced rank-2+ post regardless. */
.pb-aud-tier.is-blocked { opacity: .45; }

.pb-aud-picker-help,
.pbAudienceTierPpvNote,
.pb-aud-ppv {
  text-transform: none;
  letter-spacing: normal;
}

.pb-aud-picker-help { margin-top: .3rem; }
.pb-aud-ppv { margin-top: .5rem; }
.pb-aud-ppv.display-none,
.pbAudienceTierPpvNote.display-none { display: none !important; }

.pb-aud-row.is-preserve { border-style: dashed; }

/* ── the composer textarea ──────────────────────────────────────────────── */

/* The markup now says rows="2" so the autosize script measures a smaller empty
   box. This restores the original four-row height on every width that has room
   for it, so the change is invisible above the narrow breakpoint. Deliberately
   `min-height`: the script's inline `height` grows past it as the creator types,
   which it could not do against an `!important` height. */
#formUpdateCreate #updateDescription { min-height: 106px; }

/* ═══ narrow widths ═════════════════════════════════════════════════════ */

/* The whole initial posting workflow has to fit one viewport above the fixed
   mobile navigation: textarea, heading, three choices, toolbar, counter and
   Publish. Every reduction below is spacing or layout. No control is hidden, no
   tap target goes under 44px, and no font size is tied to the viewport. */

@media (max-width: 575.98px) {
  .pb-aud { margin-top: .5rem !important; margin-bottom: .25rem !important; }
  .pb-aud-legend { margin-bottom: .3rem; font-size: .68rem; }
  .pb-aud-rows { gap: .3rem; }
  .pb-aud-row { padding: .45rem .6rem; gap: .05rem .55rem; }
  .pb-aud-name { font-size: .9rem; }
  .pb-aud-help { font-size: .78rem; line-height: 1.35; }

  /* UNSELECTED rows collapse their supporting copy - the icon and the label
     stay, which is what identifies the choice. The selected row keeps its
     description, because that is the one whose consequence matters. The row
     keeps its 44px minimum either way.

     `0fr` rather than `display: none`: the track animates, so the row expands
     and collapses smoothly instead of snapping, and a collapsed track has no
     height at all - there is no reserved gap where the description would have
     been. `overflow: hidden` clips the text out of the zero track, and the
     child's `min-height: 0` is what lets the track reach zero. Under
     prefers-reduced-motion --pb-aud-fade is 0s and this becomes an instant
     swap. */
  /* CLOSED is the default and OPEN is the exception, rather than the other way
     round. Written negatively -- `:not(.is-selected):not(:has(:checked))` -- the
     selector matched correctly (verified with element.matches() after each
     change) but Chrome did not restyle: the descriptions froze at whatever the
     first paint chose and stayed there through every selection. `:has()` used
     positively invalidates fine; it is the `:not(:has())` form that does not.

     `.is-selected` is the same state, maintained by app-functions.js and
     rendered by the server, so the two selectors agree at every moment -- and
     the class alone would carry it if `:has()` were unavailable. */
  .pb-aud-help-stack {
    overflow: hidden;
    max-height: 0;
  }
  /* TWO rules, not one selector list. Combined, the class half never re-matched:
     the classes updated on every change (verified) while the computed max-height
     stayed at its loaded value, because a list containing `:has()` is invalidated
     as a unit and the `:has()` half does not re-run for this change. Split, the
     class rule invalidates normally.

     An upper bound, not a height: three lines of description at 320px is about
     3.6rem, so this never clips and never pads. */
  /* v2.2.1 - the checked radio decides; the class is the no-`:has()` fallback
     only, so a stale class cannot hold a second description open. Verified in
     Chromium: a standalone `:has(:checked)` rule restyles on every change. */
  .pb-aud-row:has(.pb-aud-input:checked) .pb-aud-help-stack { max-height: 6rem; }

  @supports not selector(:has(*)) {
    .pb-aud-row.is-selected .pb-aud-help-stack { max-height: 6rem; }
  }

  /* The description's own top margin does NOT collapse with the track: a
     margin is part of the track's automatic minimum, so `0fr` still resolved to
     1.6px of dead height - measured in Chrome. The gap moves onto the STACK,
     outside the track, where it can be animated to zero alongside it. */
  .pb-aud-help { margin-top: 0; }
  .pb-aud-help-stack { margin-top: 0; }
  .pb-aud-row:has(.pb-aud-input:checked) .pb-aud-help-stack { margin-top: .1rem; }
  @supports not selector(:has(*)) {
    .pb-aud-row.is-selected .pb-aud-help-stack { margin-top: .1rem; }
  }

  /* NO transition on the box.
     Measured in Chrome, three ways: with `transition: max-height` present -- a
     literal duration or a var(), it made no difference -- the computed
     max-height froze at whatever the first paint chose and never moved again,
     so the descriptions stopped following the selection entirely. Removing it,
     or transitioning opacity instead, and the value tracks correctly every
     time. `grid-template-rows: 0fr <-> 1fr` failed the same way.

     So the HEIGHT snaps and the TEXT fades: `.pb-aud-help` already transitions
     opacity through --pb-aud-fade, which prefers-reduced-motion zeroes. That is
     the smooth part that this engine will actually run. */
  .pb-aud-help-stack { transition: none; }

  .pb-aud-tierlist {
    gap: .2rem;
    margin: .25rem 0 .05rem;
    padding-left: calc(18px + 18px + 1.1rem + .6rem);
  }
  .pb-aud-tier { padding: .35rem .5rem; gap: .45rem; }
  .pb-aud-picker-help { display: none; }
}

/* 320px is the binding case: a 320x568 screen leaves the least room between the
   fixed header and the fixed navigation, and the selected row's description
   wraps to two lines at this width where it fits on one at 390px. Measured
   there, these last reductions are what turn a 9px clearance under Publish into
   a comfortable one. Spacing only. */
/* 320px is the binding width for height, not just for wrapping: with Public
   selected its warning takes three lines here, and measured at 320x568 that put
   Publish 1px under the fixed navigation. These trims are spacing only - no
   control is hidden, no font size is tied to the viewport, and every row keeps
   its 44px minimum. */
@media (max-width: 374.98px) {
  .pb-aud { margin-top: .35rem !important; margin-bottom: .15rem !important; }
  .pb-aud-legend { margin-bottom: .2rem; }
  .pb-aud-rows { gap: .2rem; }
  .pb-aud-row { padding: .4rem .5rem; gap: .05rem .45rem; }
  .pb-aud-help { font-size: .76rem; line-height: 1.3; }
  .pb-aud-tierlist { padding-left: calc(18px + 18px + .9rem + .5rem); }

}

/* ── the composer shell, narrow only ────────────────────────────────────── */

/* Scoped to the CREATE composer by id. The edit form, the profile card and
   every other consumer of form-post.blade.php are untouched: this is about the
   one screen where Publish was falling below the fixed navigation. */

@media (max-width: 575.98px) {
  #formUpdateCreate .card { margin-bottom: .75rem !important; }
  #formUpdateCreate .card-body { padding: .75rem .8rem 0; }
  #formUpdateCreate .card-footer { padding: .35rem .8rem .6rem; }

  #formUpdateCreate .media { margin-bottom: .1rem; }

  /* The avatar is decoration in the composer — the creator knows who they are.
     It is not an interactive target, so shrinking it costs nothing. */
  #formUpdateCreate .media > .rounded-circle { margin-right: .65rem !important; }
  #formUpdateCreate .avatarUser { width: 38px !important; height: 38px !important; }

  /* Two empty rows instead of four. The site's own autosize still grows the box
     as the creator writes, because it writes an inline `height` and this is a
     `min-height`. */
  #formUpdateCreate #updateDescription { min-height: 64px; }

  #formUpdateCreate .card-footer .w-100.mb-2 { margin-bottom: 0 !important; }

  /* The character counter.
     `#the-count` floats right INSIDE the Publish wrapper, and Publish is full
     width on mobile (`w-100-mobile`), so the counter wrapped onto its own line
     below the button -- a 39px block that pushed the end of the card under the
     fixed navigation. It moves to the empty right-hand end of the toolbar row,
     which is the same information in space that was already there. The toolbar
     reserves that corner so an icon can never land under it. */
  #formUpdateCreate .card-footer { position: relative; }

  /* The Publish wrapper carries `position-relative`, so it -- not the footer --
     was the offset parent and the counter landed on top of Publish instead of
     on the toolbar row. Nothing inside it is positioned against it (the blocked
     overlay uses the inner span's own `position-relative`), so it is static
     here and the footer becomes the containing block. */
  /* Bootstrap's `.position-relative` utility carries !important, so this does
     too. Measured without it: the rule matched, both media queries matched,
     and the computed position stayed `relative`, which left the counter
     pinned inside the Publish wrapper instead of on the toolbar row. */
  #formUpdateCreate .card-footer > div > .d-inline-block.float-right.position-relative { position: static !important; }

  #formUpdateCreate .card-footer > .justify-content-between { padding-right: 3.4rem; }
  #formUpdateCreate #the-count {
    position: absolute;
    top: .55rem;
    right: .8rem;
    float: none;
    margin: 0 !important;
  }

  /* `mt-3` above Publish was sized for a layout that had the counter beneath
     it. */
  #formUpdateCreate #the-count + *,
  #formUpdateCreate .card-footer .d-inline-block.float-right.mt-3 { margin-top: .4rem !important; }

  /* Empty preview slots reserve height for files that are not there yet. */
  #formUpdateCreate .card-footer .w-100.mb-2:empty,
  #formUpdateCreate #previewImage:empty,
  #formUpdateCreate #previewEpub:empty { display: none; }

  /* The toolbar buttons keep a 44px target; only the padding around the strip
     comes down. */
  #formUpdateCreate .btn-post { min-width: 44px; min-height: 44px; }

  /* Publish is `btn-sm`, which measured 32px tall on both narrow widths -- the
     primary action of the screen, below the 44px floor. Raised here only; the
     desktop button keeps the size it has always had. */
  #formUpdateCreate #btnCreateUpdate {
    min-height: 44px;
    padding-top: .5rem;
    padding-bottom: .5rem;
  }
}

/* ═══ v2.2.1: simple audience mode ═══ */

/* A normal simple creator gets one toolbar toggle. The segmented control below
   remains only for the exceptional edit case where an archived tier audience
   must be preserved explicitly.

   Scoped under `.pb-aud.is-simple` so the three-card layout above is untouched
   for creators who do use tiers. */

.pb-aud.is-simple .pb-aud-seg {
  display: grid;
  /* minmax(0, 1fr), not 1fr: a bare 1fr track has an `auto` minimum, so a long
     translated label would widen the track past the viewport instead of
     wrapping inside it. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: .3rem;
  padding: .25rem;
  border: 1px solid var(--pb-aud-line);
  border-radius: 999px;
  background-color: rgba(255,255,255,.03);
}

/* One option only (free posts disabled site-wide): a single full-width pill. */
.pb-aud.is-simple .pb-aud-seg:has(.pb-aud-seg-opt:only-child) { grid-template-columns: 1fr; }

.pb-aud.is-simple .pb-aud-seg-opt {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  min-height: 42px;
  margin: 0;
  padding: .45rem .8rem;
  border: 1px solid transparent;
  border-radius: 999px;
  background-color: transparent;
  box-shadow: none;
  cursor: pointer;
  transition:
    border-color var(--pb-aud-fade) ease,
    background-color var(--pb-aud-fade) ease,
    box-shadow var(--pb-aud-fade) ease;
}

.pb-aud.is-simple .pb-aud-seg-opt:hover { border-color: var(--pb-aud-line-2); background-color: rgba(255,255,255,.04); box-shadow: none; }

/* The segment's own parts are flex items, not grid cells. */
.pb-aud.is-simple .pb-aud-seg-opt .pb-aud-mark,
.pb-aud.is-simple .pb-aud-seg-opt .pb-aud-icon,
.pb-aud.is-simple .pb-aud-seg-opt .pb-aud-body { grid-area: auto; flex: 0 0 auto; align-self: center; }

.pb-aud.is-simple .pb-aud-seg-opt .pb-aud-mark { width: 16px; height: 16px; }

/* The body may SHRINK (flex-shrink 1, min-width 0) so a long label wraps inside
   its pill; the mark and icon keep their fixed size. */
.pb-aud.is-simple .pb-aud-seg-opt .pb-aud-body { flex: 0 1 auto; min-width: 0; }
.pb-aud.is-simple .pb-aud-seg-opt .pb-aud-name { font-size: .9rem; line-height: 1.2; text-align: center; overflow-wrap: anywhere; }

/* SELECTED: exactly one green pill. `:has()` decides; the class is the
   fallback only, as everywhere else in this file. */
.pb-aud.is-simple .pb-aud-seg-opt:has(.pb-aud-input:checked) {
  border-color: rgba(0,200,0,.55);
  background-color: rgba(0,200,0,.12);
  box-shadow: 0 0 0 1px rgba(0,200,0,.18);
}
.pb-aud.is-simple .pb-aud-seg-opt:has(.pb-aud-input:checked) .pb-aud-name { color: #fff; }
.pb-aud.is-simple .pb-aud-seg-opt:has(.pb-aud-input:checked) .pb-aud-icon { color: var(--pb-aud-green); }

/* Public is red here too; this path appears only on a legacy edit. */
.pb-aud.is-simple .pb-aud-seg-opt.is-public:has(.pb-aud-input:checked) {
  border-color: rgba(255,107,107,.58);
  background-color: rgba(255,107,107,.09);
  box-shadow: 0 0 0 1px rgba(255,107,107,.16);
}
.pb-aud.is-simple .pb-aud-seg-opt.is-public:has(.pb-aud-input:checked) .pb-aud-icon { color: var(--pb-aud-red); }

@supports not selector(:has(*)) {
  .pb-aud.is-simple .pb-aud-seg-opt.is-selected {
    border-color: rgba(0,200,0,.55);
    background-color: rgba(0,200,0,.12);
    box-shadow: 0 0 0 1px rgba(0,200,0,.18);
  }
  .pb-aud.is-simple .pb-aud-seg-opt.is-selected .pb-aud-name { color: #fff; }
  .pb-aud.is-simple .pb-aud-seg-opt.is-selected .pb-aud-icon { color: var(--pb-aud-green); }
  .pb-aud.is-simple .pb-aud-seg-opt.is-public.is-selected {
    border-color: rgba(255,107,107,.58);
    background-color: rgba(255,107,107,.09);
    box-shadow: 0 0 0 1px rgba(255,107,107,.16);
  }
  .pb-aud.is-simple .pb-aud-seg-opt.is-public.is-selected .pb-aud-icon { color: var(--pb-aud-red); }
}

/* The preserve row, if it appears in simple mode, spans the control and keeps
   its ordinary card layout — and the container drops its stadium radius, or
   the 12px card corners would poke through the curved ends. `has-preserve` is
   set by the server; the `:has()` form covers the same case without it. */
.pb-aud.is-simple .pb-aud-seg .pb-aud-row.is-preserve { grid-column: 1 / -1; }
.pb-aud.is-simple.has-preserve .pb-aud-seg,
.pb-aud.is-simple .pb-aud-seg:has(.pb-aud-row.is-preserve) { border-radius: 14px; }

/* ── the one help line under the segments ─────────────────────────────── */

/* Every sentence is in the markup; exactly one is shown. The wrapper's
   `data-pb-aud-current` is written by the server and kept in step by
   app-functions.js, and `:has(:checked)` covers the no-JavaScript path.
   Public uses the same red caution language as the full tier selector. */
.pb-aud.is-simple .pb-aud-seg-help {
  display: grid;
  margin-top: .4rem;
  padding: 0 .35rem;
}
.pb-aud.is-simple .pb-aud-seg-help > * { grid-area: 1 / 1 / 2 / 2; }

.pb-aud.is-simple .pb-aud-seg-note {
  display: block;
  margin: 0;
  font-size: .8rem;
  line-height: 1.4;
  color: var(--pb-aud-muted);
  opacity: 0;
  visibility: hidden;
  transition: opacity var(--pb-aud-fade) ease;
}

.pb-aud.is-simple .pb-aud-seg-note-public { color: #FFB4B4; }
.pb-aud.is-simple .pb-aud-seg-note-ico { color: var(--pb-aud-red); font-size: 13px; vertical-align: -1px; }

.pb-aud.is-simple[data-pb-aud-current="public"] .pb-aud-seg-note-public,
.pb-aud.is-simple[data-pb-aud-current="members"] .pb-aud-seg-note-members,
.pb-aud.is-simple:has(.pb-aud-input[value="public"]:checked) .pb-aud-seg-note-public,
.pb-aud.is-simple:has(.pb-aud-input[value="members"]:checked) .pb-aud-seg-note-members { opacity: 1; visibility: visible; }

/* If the two disagree (attribute stale, radio authoritative), the radio wins:
   the note for the attribute's audience is suppressed when that radio is NOT
   the checked one. */
.pb-aud.is-simple:has(.pb-aud-input[value="members"]:checked) .pb-aud-seg-note-public,
.pb-aud.is-simple:has(.pb-aud-input[value="public"]:checked) .pb-aud-seg-note-members { opacity: 0; visibility: hidden; }

/* Preserve is selected: neither note applies. */
.pb-aud.is-simple:has(.pb-aud-input[value="preserve"]:checked) .pb-aud-seg-note { opacity: 0; visibility: hidden; }

/* Normal simple mode occupies no large selector space. The hidden radios keep
   the exact request contract; the button itself is pushed beside Emoji by the
   Blade partial. Only the Public warning takes visible space. */
.pb-aud.is-toolbar {
  min-height: 0;
  margin-top: 0 !important;
  margin-bottom: 0 !important;
}

.pb-aud-simple-inputs {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
}

.pb-aud-toolbar-warning {
  display: none;
  align-items: flex-start;
  gap: .35rem;
  margin: .45rem 0 0;
  font-size: .8rem;
  line-height: 1.4;
  color: #FFB4B4;
  text-transform: none;
  letter-spacing: normal;
}

.pb-aud-toolbar-warning > i {
  flex: 0 0 auto;
  margin-top: .08rem;
  color: var(--pb-aud-red);
}

.pb-aud.is-toolbar[data-pb-aud-current="public"] .pb-aud-toolbar-warning,
.pb-aud.is-toolbar:has(.pb-aud-input[value="public"]:checked) .pb-aud-toolbar-warning {
  display: flex;
}

/* If history restoration leaves the data attribute stale, the checked radio
   remains authoritative and suppresses the wrong warning before JS re-syncs. */
.pb-aud.is-toolbar:has(.pb-aud-input[value="members"]:checked) .pb-aud-toolbar-warning {
  display: none;
}

#formUpdateCreate .pbAudienceSimpleToggle,
#formUpdateEdit .pbAudienceSimpleToggle {
  min-width: 44px;
  min-height: 44px;
}

#formUpdateCreate .pbAudienceSimpleToggle.is-public,
#formUpdateEdit .pbAudienceSimpleToggle.is-public {
  color: #FF6B6B !important;
}

#formUpdateCreate .pbAudienceSimpleToggle.is-public:hover,
#formUpdateCreate .pbAudienceSimpleToggle.is-public:focus,
#formUpdateCreate .pbAudienceSimpleToggle.is-public:focus-visible,
#formUpdateEdit .pbAudienceSimpleToggle.is-public:hover,
#formUpdateEdit .pbAudienceSimpleToggle.is-public:focus,
#formUpdateEdit .pbAudienceSimpleToggle.is-public:focus-visible {
  color: #FF8A8A !important;
  background-color: rgba(255,107,107,.08);
  outline-color: rgba(255,107,107,.68);
}

@media (max-width: 575.98px) {
  .pb-aud.is-simple .pb-aud-seg-opt { min-height: 44px; padding: .4rem .5rem; }
  .pb-aud.is-simple .pb-aud-seg-opt .pb-aud-name { font-size: .86rem; }
  .pb-aud.is-simple .pb-aud-seg-help { margin-top: .3rem; }
}

/* 320px: spacing only. Nothing is hidden - the icon stays, the gaps and the
   pill padding come down, and the label wraps rather than clips if a
   translation is long. */
@media (max-width: 374.98px) {
  .pb-aud.is-simple .pb-aud-seg { gap: .2rem; padding: .2rem; }
  .pb-aud.is-simple .pb-aud-seg-opt { gap: .3rem; padding: .4rem .3rem; }
  .pb-aud.is-simple .pb-aud-seg-opt .pb-aud-name { font-size: .82rem; }
  .pb-aud.is-simple .pb-aud-seg-note { font-size: .76rem; }
}

/* ── the composer shell at 320px ────────────────────────────────────────── */

/* LAST in the file on purpose. These declarations and the 575.98px ones above
   have the same specificity, so the later block wins. In the earlier revision
   they sat in a 374.98px block placed BEFORE the wider one and every overlapping
   declaration silently lost. */

@media (max-width: 374.98px) {
  /* Trimmed again after measuring the Public case: its warning takes three
     lines at this width, and the card's last 2px of padding sat under the fixed
     navigation. Publish itself was already clear; this clears the card too. */
  #formUpdateCreate .card-body { padding: .55rem .6rem 0; }
  #formUpdateCreate .card-footer { padding: .2rem .6rem .15rem; }
  #formUpdateCreate .card-footer .d-inline-block.float-right.mt-3 { margin-top: .25rem !important; }
  .pb-aud { margin-bottom: .05rem !important; }
  #formUpdateCreate #updateDescription { min-height: 58px; }

  /* 320px has no room to reserve a corner: measured there, a 3.4rem gutter
     pushed the fifth toolbar button onto a second row and cost more height than
     the counter had ever occupied. The icons end well short of the counter at
     this width, so the corner is shared rather than reserved -- and the absence
     of overlap is asserted, not assumed. */
  #formUpdateCreate .card-footer > .justify-content-between { padding-right: 0; }
  #formUpdateCreate #the-count { right: .65rem; }
}
