/* ============================================================================
   playbooki-tiers.css — v2.2 tier UI refresh
   ----------------------------------------------------------------------------
   Scope rules for this file:

     * every selector starts with a `pb-tier-` class (or is nested inside one).
       Nothing here may match a bare `.form-control`, `.card`, `.btn` or any
       other stock Sponzy/Bootstrap class on its own;
     * tier colour arrives as a `pb-tier-c-<key>` class written by
       App\Services\Billing\TierPalette. No hex value is ever emitted into
       markup, and no style attribute carries a colour;
     * the accent is an ACCENT: a 1px border, a low-opacity glow close to the
       element, a badge, a marker. Panels stay dark and neutral.

   Loaded per page through @section('css'), the pattern the rest of the app
   uses. Adding it to a page cannot restyle anything that does not opt in.
   ========================================================================= */

/* ---------------------------------------------------------------- palette --
   One block per curated key. `--pb-tier-accent` is the hue, `--pb-tier-ink`
   is readable text on top of it for the few filled elements (a badge), and
   `--pb-tier-glow` is the accent at the low opacity the glow is allowed. */

/* Playbooki Default - the platform green itself, so a creator can keep the
   familiar site colour rather than choosing a tier colour. */
.pb-tier-c-playbooki { --pb-tier-accent: #00C800; --pb-tier-ink: #04140A; --pb-tier-rgb: 0,200,0; }

/* White. The accent is soft rather than pure so it does not bloom against the
   dark panel, and it is the one entry that dials the shared glow alphas down:
   every other accent is darker than the ring it sits inside, white is not. */
.pb-tier-c-white     { --pb-tier-accent: #E9EEF2; --pb-tier-ink: #0B0F12; --pb-tier-rgb: 233,238,242;
                       --pb-tier-a-glow: .26; --pb-tier-a-ring: .04; --pb-tier-a-border: .34; --pb-tier-a-select: .22; }

.pb-tier-c-steel     { --pb-tier-accent: #8FA3B8; --pb-tier-ink: #0A0F14; --pb-tier-rgb: 143,163,184; }
.pb-tier-c-jade      { --pb-tier-accent: #2DD4A7; --pb-tier-ink: #04120D; --pb-tier-rgb: 45,212,167; }
.pb-tier-c-sky       { --pb-tier-accent: #38BDF8; --pb-tier-ink: #04121A; --pb-tier-rgb: 56,189,248; }
.pb-tier-c-indigo    { --pb-tier-accent: #8B9CF7; --pb-tier-ink: #080B1A; --pb-tier-rgb: 139,156,247; }
.pb-tier-c-violet    { --pb-tier-accent: #C084FC; --pb-tier-ink: #140A1C; --pb-tier-rgb: 192,132,252; }
.pb-tier-c-magenta   { --pb-tier-accent: #E879C7; --pb-tier-ink: #180614; --pb-tier-rgb: 232,121,199; }

/* Two red-family and two orange-family entries. Each pair is separated on
   lightness AND saturation, not hue alone, so they stay tellable apart in a
   34px swatch: crimson is deep and saturated, coral is pale and pink; orange
   is a burnt vivid orange, amber is golden. The first pair separates by 0.25
   in lightness and the second by 0.15 - the portable suite asserts both, and
   caught an earlier pair that separated by only 0.06. crimson carries light
   ink because dark ink on it fails the 4.5:1 floor. */
.pb-tier-c-crimson   { --pb-tier-accent: #D91E36; --pb-tier-ink: #FFFFFF; --pb-tier-rgb: 217,30,54; }
.pb-tier-c-coral     { --pb-tier-accent: #FB7A85; --pb-tier-ink: #1A0607; --pb-tier-rgb: 251,122,133; }
.pb-tier-c-orange    { --pb-tier-accent: #E85D04; --pb-tier-ink: #1A0A02; --pb-tier-rgb: 232,93,4; }
.pb-tier-c-amber     { --pb-tier-accent: #F5B544; --pb-tier-ink: #1A1103; --pb-tier-rgb: 245,181,68; }

/* Shared surface tokens. Kept here rather than in the palette blocks so a
   colour change never accidentally changes a background. */
.pb-tier-editor,
.pb-tier-panel {
  --pb-tier-surface: #0F1113;
  --pb-tier-surface-2: #141719;
  --pb-tier-line: rgba(255,255,255,.08);
  --pb-tier-text: #E9EFE9;
  --pb-tier-muted: #9AA4AE;
  --pb-tier-radius: 12px;
}

/* ------------------------------------------------------- editor structure --
   One panel per tier, identical for every tier including rank 1. The rank-1
   tier used to be edited by an unlabelled legacy form at the top of the page
   and the others by bare inputs further down; both now render this panel. */

.pb-tier-editor { margin-top: 1.5rem; }

.pb-tier-panel {
  position: relative;
  background: var(--pb-tier-surface);
  border: 1px solid var(--pb-tier-line);
  border-radius: var(--pb-tier-radius);
  padding: 0;
  margin-bottom: 1.25rem;
  overflow: hidden;
}

/* The colour lives on a hairline down the leading edge and a soft, tight glow.
   No filled panel, no gradient wash. */
.pb-tier-panel[class*="pb-tier-c-"] {
  border-color: rgba(var(--pb-tier-rgb), var(--pb-tier-a-border, .28));
  box-shadow: 0 0 0 1px rgba(var(--pb-tier-rgb), var(--pb-tier-a-ring, .06)),
              0 6px 22px -14px rgba(var(--pb-tier-rgb), var(--pb-tier-a-glow, .55));
}

.pb-tier-panel::before {
  content: "";
  position: absolute;
  inset: 0 auto 0 0;
  width: 3px;
  background: var(--pb-tier-accent, #6b7280);
  opacity: .85;
}

.pb-tier-panel-head {
  display: flex;
  align-items: center;
  gap: .75rem;
  flex-wrap: wrap;
  padding: .95rem 1.15rem;
  background: var(--pb-tier-surface-2);
  border-bottom: 1px solid var(--pb-tier-line);
}

.pb-tier-panel-name {
  font-weight: 700;
  font-size: 1rem;
  color: var(--pb-tier-text);
  margin: 0;
  letter-spacing: 0;
}

/* Rank badge — the one place the accent is a fill, at badge size only. */
.pb-tier-rank-badge {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .18rem .55rem;
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  white-space: nowrap;
  color: var(--pb-tier-ink, #0b0b0b);
  background: var(--pb-tier-accent, #6b7280);
}

.pb-tier-state-badge {
  display: inline-flex;
  align-items: center;
  padding: .18rem .55rem;
  border-radius: 999px;
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .03em;
  text-transform: uppercase;
  color: var(--pb-tier-muted);
  border: 1px solid var(--pb-tier-line);
  background: transparent;
}

.pb-tier-panel-price {
  margin-left: auto;
  color: var(--pb-tier-muted);
  font-size: .85rem;
  white-space: nowrap;
}
.pb-tier-panel-price strong { color: var(--pb-tier-text); font-weight: 700; }

.pb-tier-panel-body { padding: 1.15rem; }

/* ------------------------------------------------------------ field rhythm --
   Scoped to the editor so the site's global form styling is untouched. */

.pb-tier-field { margin-bottom: 1rem; }

.pb-tier-field > label,
.pb-tier-label {
  display: block;
  margin-bottom: .35rem;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--pb-tier-muted);
}

.pb-tier-help {
  display: block;
  margin-top: .35rem;
  font-size: .8rem;
  line-height: 1.4;
  color: var(--pb-tier-muted);
}

/* The perk repeater. The "add another" control used to sit on the same line as
   the next label with a 0px gap; it is now a block of its own. */
.pb-tier-perks .form-control { margin-bottom: .4rem; }

.pb-tier-perk-add {
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  margin: .1rem 0 0;
  padding: .35rem .1rem;
  background: none;
  border: 0;
  color: var(--pb-tier-accent, #9AA4AE);
  font-size: .85rem;
  font-weight: 600;
  cursor: pointer;
}
.pb-tier-perk-add:hover { text-decoration: underline; }

.pb-tier-sep {
  height: 1px;
  background: var(--pb-tier-line);
  border: 0;
  margin: 1.25rem 0;
}

/* ----------------------------------------------------------- swatch picker --
   Radios with the input visually hidden. The label is the swatch, so the whole
   chip is the hit target and keyboard focus still lands somewhere visible. */

/* A grid rather than a wrapping flex row: with eleven swatches, flex-wrap
   drops an odd one onto a row of its own at some widths. The grid keeps the
   rows balanced and the chips a consistent size. */
.pb-tier-swatches {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: .5rem;
  margin-top: .1rem;
  /* 12 x ~43px + 11 x 8px gaps = 604px, inside a ~756px column: one orderly
     row with room to spare. */
  max-width: 604px;
}

.pb-tier-swatch { position: relative; line-height: 0; }

.pb-tier-swatch input {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  margin: 0;
}

.pb-tier-swatch label {
  display: block;
  width: 100%;
  aspect-ratio: 1 / 1;
  min-height: 34px;
  margin: 0;
  border-radius: 9px;
  cursor: pointer;
  background: var(--pb-tier-accent);
  border: 2px solid transparent;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.35);
  transition: transform .12s ease, box-shadow .12s ease;
}

.pb-tier-swatch label:hover { transform: translateY(-1px); }

.pb-tier-swatch input:checked + label {
  border-color: #E9EFE9;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.35),
              0 0 0 3px rgba(var(--pb-tier-rgb), var(--pb-tier-a-select, .32));
}

/* The selected ring is a near-white border. On a white chip that border is
   invisible, so White inverts it: a dark inner ring on the chip, with a soft
   light halo outside it. Same shape as every other selected swatch, readable
   on the one accent the shared treatment cannot serve. */
.pb-tier-swatch.pb-tier-c-white input:checked + label {
  border-color: #10161B;
  box-shadow: inset 0 0 0 1px rgba(0,0,0,.28),
              0 0 0 3px rgba(233,238,242,.5);
}

.pb-tier-swatch input:focus-visible + label {
  outline: 2px solid #E9EFE9;
  outline-offset: 3px;
}

/* --------------------------------------------------------- price grouping --
   Monthly is always sellable and has no switch, so it stays visible. The other
   five intervals move inside a disclosure. Every input stays in the DOM and in
   the form, so what the server receives is unchanged. */

.pb-tier-price-primary { margin-bottom: .35rem; }

.pb-tier-more { margin-top: .75rem; border-top: 1px solid var(--pb-tier-line); padding-top: .75rem; }

.pb-tier-more > summary {
  cursor: pointer;
  list-style: none;
  display: inline-flex;
  align-items: center;
  gap: .4rem;
  font-size: .82rem;
  font-weight: 600;
  color: var(--pb-tier-muted);
  padding: .2rem 0;
}
.pb-tier-more > summary::-webkit-details-marker { display: none; }
.pb-tier-more > summary::after { content: "\25BE"; font-size: .7em; opacity: .8; }
.pb-tier-more[open] > summary::after { content: "\25B4"; }
.pb-tier-more > summary:hover { color: var(--pb-tier-text); }
.pb-tier-more-body { padding-top: .85rem; }

.pb-tier-interval { margin-bottom: .85rem; }

/* ------------------------------------------------------------------ actions */

.pb-tier-actions {
  display: flex;
  align-items: center;
  gap: .5rem;
  flex-wrap: wrap;
  padding: .85rem 1.15rem;
  background: var(--pb-tier-surface-2);
  border-top: 1px solid var(--pb-tier-line);
}

.pb-tier-actions .pb-tier-save { margin-right: auto; }

/* Save stays the platform green: it is a platform action, not a tier accent. */
.pb-tier-btn {
  border-radius: 999px;
  font-weight: 700;
  padding: .5rem 1.15rem;
  border: 1px solid transparent;
  font-size: .88rem;
  line-height: 1.2;
  cursor: pointer;
}
.pb-tier-btn-primary { background: #00C800; color: #06210A; }
.pb-tier-btn-primary:hover { background: #00E000; color: #06210A; }
.pb-tier-btn-quiet {
  background: transparent;
  color: var(--pb-tier-muted);
  border-color: var(--pb-tier-line);
}
.pb-tier-btn-quiet:hover { color: var(--pb-tier-text); border-color: rgba(255,255,255,.22); }
.pb-tier-btn-danger { background: transparent; color: #FB7A85; border-color: rgba(251,122,133,.35); }
.pb-tier-btn-danger:hover { background: rgba(251,122,133,.1); }
.pb-tier-btn[disabled] { opacity: .5; cursor: not-allowed; }

.pb-tier-note { color: var(--pb-tier-muted); font-size: .8rem; margin: 0; }

/* ------------------------------------------------------------- empty slot --
   The "add a tier" panel, and the message shown when the ladder is full. */

.pb-tier-add-panel {
  border: 1px dashed rgba(255,255,255,.16);
  border-radius: var(--pb-tier-radius);
  background: rgba(255,255,255,.015);
}
.pb-tier-add-panel .pb-tier-panel-head { background: transparent; border-bottom-color: var(--pb-tier-line); }

.pb-tier-full {
  border: 1px dashed rgba(255,255,255,.14);
  border-radius: var(--pb-tier-radius);
  padding: 1rem 1.15rem;
  color: var(--pb-tier-muted);
  font-size: .88rem;
}

/* --------------------------------------------------------------- selects --
   Scoped repair for the clipped-text defect the audit measured: the theme
   forces `padding: 11px 14px !important` on `.form-control` while Bootstrap's
   `.custom-select` keeps a fixed 35px height, so the selected option was cut
   off. Fixed only inside tier UI — the global rule is left alone. */

.pb-tier-editor select.form-control,
.pb-tier-editor select.custom-select,
.pb-tier-panel select.form-control,
.pb-tier-panel select.custom-select {
  height: auto;
  min-height: 44px;
}

/* ------------------------------------------------------------------ mobile */

@media (max-width: 575.98px) {
  .pb-tier-panel-head { padding: .8rem .9rem; }
  .pb-tier-panel-body { padding: .9rem; }
  .pb-tier-actions { padding: .8rem .9rem; }
  .pb-tier-panel-price { margin-left: 0; width: 100%; }
  .pb-tier-actions .pb-tier-save { margin-right: 0; width: 100%; }
  /* Twelve swatches at 390px: six columns gives two balanced rows of six,
     chips around 48px square - above the 44px tap target and larger than
     they are on desktop. */
  .pb-tier-swatches {
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 8px;
    max-width: none;
  }
  .pb-tier-swatch label { min-height: 44px; }
}

/* ============================================================================
   STAGE 2 - the public tier board (profile), liquid-glass pass
   ----------------------------------------------------------------------------
   REUSES PLAYBOOKI'S OWN GLASS SYSTEM. The tokens below are declared on :root
   in public/css/playbooki.css, which the profile already loads:

     --pb-glass-bg / -bg-2   dark translucent surface
     --pb-glass-blur / -l    backdrop blur + saturation
     --pb-glass-shine        the inner highlight along the top edge
     --pb-glass-edge         the neutral hairline
     --pb-glass-depth / -l   the shadow underneath
     --pb-r-lg, --pb-r-pill  radii
     --pb-ease, --pb-mid     motion
     --pb-green, --pb-green-2

   The canonical composition is `.pb-glass` in playbooki.css:
     background + backdrop-filter + 1px edge + inset shine + depth.
   Every panel here is that composition with a tier-coloured glow added
   OUTSIDE it. Nothing redefines a token, and no rule here matches a bare
   .card, .btn or .form-control.

   THE COLOUR RULE
     tier accent  = identity. Glow, haze, perk ticks, "your plan" flag.
     Playbooki green = action. CTA, selected billing length, offer pills.
   The accent is never a large filled surface and never a hard border.
   ========================================================================= */

.pb-tier-board {
  --pb-tier-text: #F0F0F0;
  --pb-tier-muted: #9AA4AE;
  margin: 2rem auto 1.25rem;
  max-width: 1060px;
  text-align: left;
}

/* ── step 1: billing length ─────────────────────────────────────────────── */

.pb-tier-lengths { margin-bottom: 1.35rem; }

.pb-tier-lengths-label {
  display: block;
  margin-bottom: .55rem;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--pb-tier-muted);
}

/* The same glass as every other Playbooki panel. */
.pb-tier-lengths-track {
  display: flex;
  flex-wrap: wrap;
  gap: .3rem;
  padding: .35rem;
  background: var(--pb-glass-bg, rgba(14,14,14,.52));
  backdrop-filter: var(--pb-glass-blur, blur(22px) saturate(1.15));
  -webkit-backdrop-filter: var(--pb-glass-blur, blur(22px) saturate(1.15));
  border: 1px solid var(--pb-glass-edge, rgba(255,255,255,.07));
  border-radius: var(--pb-r-pill, 999px);
  box-shadow: inset 0 1px 0 var(--pb-glass-shine, rgba(255,255,255,.055)),
              var(--pb-glass-depth, 0 8px 32px rgba(0,0,0,.45));
}

.pb-tier-length {
  display: inline-flex;
  align-items: baseline;
  gap: .4rem;
  padding: .55rem 1rem;
  border: 1px solid transparent;
  border-radius: var(--pb-r-pill, 999px);
  background: transparent;
  color: var(--pb-tier-muted);
  font-size: .9rem;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--pb-mid, .25s) var(--pb-ease, ease),
              color var(--pb-mid, .25s) var(--pb-ease, ease),
              box-shadow var(--pb-mid, .25s) var(--pb-ease, ease),
              transform var(--pb-fast, .15s) var(--pb-ease, ease);
}
.pb-tier-length:hover { color: var(--pb-tier-text); background: rgba(255,255,255,.04); }

/* Raised and lit, so the choice is unmistakable without the other options
   competing with it. */
.pb-tier-length.is-active {
  color: #EAFFEA;
  background: linear-gradient(180deg, rgba(0,200,0,.20), rgba(0,200,0,.08));
  border-color: rgba(0,200,0,.42);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.14),
              0 0 16px rgba(0,200,0,.22),
              0 2px 10px rgba(0,0,0,.45);
  transform: translateY(-1px);
}
.pb-tier-length:focus-visible {
  outline: 2px solid rgba(0,200,0,.4);
  outline-offset: 2px;
}

/* Secondary by design: present, never competing with the selected pill. */
.pb-tier-length-save {
  font-size: .72rem;
  font-weight: 600;
  letter-spacing: .01em;
  color: #7FB98C;
}
.pb-tier-length.is-active .pb-tier-length-save { color: #9BFFB5; }

/* ── step 2: the cards ──────────────────────────────────────────────────── */

.pb-tier-grid-label {
  margin-bottom: .65rem;
  font-size: .72rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--pb-tier-muted);
}

.pb-tier-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 1.1rem;
  align-items: stretch;
}

/* Dark glass, neutral hairline, no coloured border anywhere. */
.pb-tier-card {
  display: flex;
  flex-direction: column;
  position: relative;
  isolation: isolate;
  padding: 1.35rem 1.25rem 1.25rem;
  border-radius: var(--pb-r-lg, 14px);
  border: 1px solid var(--pb-glass-edge, rgba(255,255,255,.07));
  background:
    /* upper region lighter, lower region darker - the glass reads as lit from
       above rather than as a flat fill. */
    linear-gradient(180deg, rgba(255,255,255,.045), rgba(255,255,255,0) 45%),
    linear-gradient(180deg, rgba(0,0,0,0) 52%, rgba(0,0,0,.26)),
    var(--pb-glass-bg, rgba(14,14,14,.52));
  backdrop-filter: var(--pb-glass-blur, blur(22px) saturate(1.15));
  -webkit-backdrop-filter: var(--pb-glass-blur, blur(22px) saturate(1.15));
  box-shadow: inset 0 1px 0 var(--pb-glass-shine, rgba(255,255,255,.055)),
              var(--pb-glass-depth, 0 8px 32px rgba(0,0,0,.45));
  text-align: left;
  transition: transform var(--pb-mid, .25s) var(--pb-ease, ease),
              box-shadow var(--pb-mid, .25s) var(--pb-ease, ease);
}

/* The tier haze inside the glass, gathered at the top. Carried on the
   background rather than a third pseudo-element so each card needs only two. */
.pb-tier-card[class*="pb-tier-c-"] {
  background:
    radial-gradient(125% 62% at 50% -16%,
      rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .20)) 0%,
      rgba(var(--pb-tier-rgb), 0) 64%),
    linear-gradient(180deg, rgba(255,255,255,.045), rgba(255,255,255,0) 45%),
    linear-gradient(180deg, rgba(0,0,0,0) 52%, rgba(0,0,0,.26)),
    var(--pb-glass-bg, rgba(14,14,14,.52));
}

/* The tier colour is LIGHT AROUND THE CARD, not a line on it: a soft outer
   glow plus a one-pixel tinted seat, both at low opacity. White dials its own
   alphas down through the Stage 1 variables, so it lights rather than blooms. */
/* Light bleeding around a glass surface, not one uniform halo: two offset
   casts at the upper corners, a wide even bleed at the sides, and a stronger
   pool at the base. Total perceived intensity is about a third above the
   previous single shadow, spread across four soft casts so it stays
   atmospheric rather than neon. White dials its own alphas down through the
   Stage 1 palette variables, so it lights instead of blooming. */
.pb-tier-card[class*="pb-tier-c-"] {
  box-shadow:
    inset 0 1px 0 var(--pb-glass-shine, rgba(255,255,255,.055)),
    0 0 0 1px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-ring, .06) * 1.8)),
    -16px -12px 38px -22px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .58)),
     16px -12px 38px -22px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .58)),
    0 4px 30px -14px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .52)),
    0 20px 46px -20px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .66)),
    var(--pb-glass-depth, 0 8px 32px rgba(0,0,0,.45));
}

/* The pool of light UNDER the card. Wider than the card, sitting below its
   base, heavily blurred and fading out - so the card reads as a glass object
   floating over its own tier-coloured light rather than as a rectangle with a
   shadow. One blurred pseudo-element per card; nothing animates. */
.pb-tier-card[class*="pb-tier-c-"]::before {
  content: "";
  position: absolute;
  z-index: -1;
  left: -7%;
  right: -7%;
  bottom: -30px;
  height: 62%;
  border-radius: 50%;
  background: radial-gradient(58% 100% at 50% 100%,
    rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .46)) 0%,
    rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .16)) 45%,
    rgba(var(--pb-tier-rgb), 0) 72%);
  filter: blur(28px);
  pointer-events: none;
}

/* A hairline of the accent along the very top edge - one pixel, faded at the
   ends, so it reads as a highlight rather than a border. */
.pb-tier-card[class*="pb-tier-c-"]::after {
  content: "";
  position: absolute;
  top: 0; left: 12%; right: 12%;
  height: 1px;
  border-radius: 1px;
  background: linear-gradient(90deg,
    rgba(var(--pb-tier-rgb), 0),
    rgba(var(--pb-tier-rgb), .55),
    rgba(var(--pb-tier-rgb), 0));
  pointer-events: none;
}

.pb-tier-card:hover {
  transform: translateY(-3px);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.10),
    0 0 0 1px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-ring, .06) * 2.6)),
    -18px -14px 44px -22px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .74)),
     18px -14px 44px -22px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .74)),
    0 26px 56px -20px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .82)),
    0 18px 52px rgba(0,0,0,.55);
}

.pb-tier-card.is-current {
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.10),
    0 0 0 1px rgba(var(--pb-tier-rgb), .30),
    0 12px 34px -12px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .7)),
    var(--pb-glass-depth, 0 8px 32px rgba(0,0,0,.45));
}

/* ── the offer hero ─────────────────────────────────────────────────────── */

.pb-tier-card-head {
  position: relative;
  display: flex;
  /* flex-start, not center: the name and the pill are both anchored to the
     TOP of the head, so a one-pill card and a two-pill card put their badge on
     the same line as the title rather than floating it down the middle. */
  align-items: flex-start;
  gap: .5rem;
  /* nowrap, deliberately. With wrapping on, a long tier name does not squeeze
     the title - flexbox drops the whole cluster onto a second line instead,
     which un-anchors it from the corner and pushes that one card's price out
     of line with its neighbours. It showed up in the 992-1199px band, where
     the container narrows to 960px while the grid is still three across.
     nowrap makes the TITLE give way instead: it wraps to a second line, the
     cluster stays in the corner, and two lines of title (49.6px) still fit
     inside the reserved head height, so the price line holds. */
  flex-wrap: nowrap;
  /* One pill's height, not two. The countdown moved down to the price row, so
     the head no longer reserves a second pill's worth of space above the
     number - and because this height is the same with or without a badge, a
     row of cards still starts every price on one line. */
  min-height: 26px;
  margin-bottom: .38rem;
}

/* The badge is anchored to the card's top-right corner by margin-left:auto -
   it takes whatever space is left between the name and the card's inner edge,
   so it sits flush right at every card width without a single absolute
   position. The countdown on the price row below uses the same trick, which is
   what lines the two up as one right-hand column. */
.pb-tier-card-head .pb-tier-promo {
  margin-left: auto;
  flex: none;
}
.pb-tier-promo[hidden] { display: none; }

/* Price left, countdown flush right and top-aligned so it sits directly under
   the badge rather than beside the middle of a 34px number.

   The row wraps, and the min() is what decides WHAT wraps. A discounted price
   line - struck original, current figure, period - needs 241px of a 252px
   desktop card, so the 60px pill cannot share that line at every width. Giving
   the price `min-width: min(100%, max-content)` means it claims its own
   one-line width whenever the card can spare it, so the pill is what drops to
   the next line (still flush right, still the card's right-hand column) rather
   than the price breaking across two lines. The 100% cap is the safety valve:
   a price too long for the card falls back to wrapping inside itself instead
   of overflowing. On a phone the card is wide enough that nothing wraps at
   all and the pill sits beside the price, which is the arrangement this pass
   is really after. */
.pb-tier-price-row {
  display: flex;
  align-items: flex-start;
  flex-wrap: wrap;
  gap: .25rem .5rem;
}
.pb-tier-price-row .pb-tier-price {
  flex: 0 1 auto;
  min-width: min(100%, max-content);
}
.pb-tier-price-row .pb-tier-promo-ends { margin-left: auto; flex: none; }

/* Lifted over the bloom below, which paints on top of the card surface. */
.pb-tier-card-head > * { position: relative; z-index: 1; }

/* A contained bloom behind the title, not a band across the card.

   The previous version was a percentage-sized rectangle at z-index -1. Sitting
   BEHIND the card's own background meant the only part of it that showed at
   full strength was the part hanging outside the card - which is exactly what
   produced the pale rectangular slabs beside each title.

   This one is fixed in pixels, sized to stay inside the card's padding on
   every width, reaches zero alpha at its own edges (closest-side, so the stops
   land on the ellipse rather than on a box corner), and paints ABOVE the card
   surface with the head's own children lifted over it. Nothing to clip, and
   nothing to bleed. */
.pb-tier-card[class*="pb-tier-c-"] .pb-tier-card-head::before {
  content: "";
  position: absolute;
  z-index: 0;
  left: -.4rem;
  /* Anchored to the TITLE's line, not to the middle of the head: the head is
     now as tall as the two-pill cluster, and a bloom centred on it would drift
     below the name it belongs to. 13px is the title row's own centre. */
  top: 13px;
  width: 200px;
  height: 58px;
  margin-top: -29px;
  background: radial-gradient(closest-side,
    rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .30)) 0%,
    rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .12)) 52%,
    rgba(var(--pb-tier-rgb), 0) 100%);
  pointer-events: none;
}

/* The name stays white for readability; the tier colour arrives as light
   around the letterforms, not as the letterforms. Two shadow radii - a close
   one for definition, a wide one for atmosphere. */
/* The weight carries an !important because playbooki.css:1605 sets
   `h1..h6 { font-weight: 800 !important }` globally, which a plain class
   cannot outrank. Overriding it here - inside a pb-tier- scoped selector on a
   pb-tier- element - keeps the global rule untouched and cannot affect any
   other heading on the site. */
.pb-tier-board .pb-tier-card .pb-tier-card-name {
  margin: 0;
  font-family: var(--pb-fh, 'Barlow Condensed', sans-serif);
  font-size: 1.52rem;
  font-weight: 900 !important;
  line-height: 1.02;
  letter-spacing: .005em;
  color: var(--pb-tier-text);
  /* A name long enough to need two lines gets them, and they stay tight
     enough to read as one block; a single unbreakable word breaks rather than
     escaping the card. */
  overflow-wrap: break-word;
}

.pb-tier-card[class*="pb-tier-c-"] .pb-tier-card-name {
  text-shadow: 0 0 10px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .55)),
               0 0 26px rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .32));
}

.pb-tier-card-flag {
  flex: none;
  padding: .18rem .55rem;
  border-radius: var(--pb-r-pill, 999px);
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .05em;
  text-transform: uppercase;
  color: var(--pb-tier-ink, #0b0b0b);
  background: var(--pb-tier-accent, #6b7280);
}

/* One pill system. The offer badge (now on the title row) and the countdown
   (now under the price) are different in colour and in job, not in shape: same
   height, same radius, same padding, same weight. Sizing lives here once, so
   the two can never drift apart, and the head row's min-height is keyed to the
   same 26px. */
.pb-tier-promo,
.pb-tier-promo-ends {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 26px;
  padding: 0 .6rem;
  border-radius: var(--pb-r-pill, 999px);
  font-size: .74rem;
  font-weight: 800;
  line-height: 1;
  letter-spacing: .04em;
  white-space: nowrap;
}


/* The offer capsule now carries the TIER's colour, not the platform green.
   A white overlay raises the accent's luminance so a neutral tier still reads
   as lit rather than as a disabled grey tag - and because the overlay only
   lightens the surface, the dark ink the palette validated at 4.5:1 against
   the pure accent gains contrast rather than losing it. Smaller than the CTA
   by design. */
.pb-tier-promo {
  text-transform: uppercase;
  color: var(--pb-tier-ink, #001A00);
  background:
    linear-gradient(180deg, rgba(255,255,255,.30), rgba(255,255,255,0) 62%),
    var(--pb-tier-accent, #00C800);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.55),
              0 0 18px rgba(var(--pb-tier-rgb, 0,200,0), .42),
              0 2px 8px rgba(0,0,0,.42);
}

/* The offer clock. Deliberately NOT the tier's colour and NOT the platform
   green: this is the one element on the card whose job is time pressure, so it
   gets its own register. The red is the palette's crimson family (#D91E36),
   the same hue as the struck original price, held at low saturation on a
   tinted glass pill so it reads as a countdown rather than as an error. */
.pb-tier-promo-ends {
  gap: .32rem;
  color: #FF9AA2;
  background: linear-gradient(180deg, rgba(217,30,54,.24), rgba(217,30,54,.10));
  border: 1px solid rgba(217,30,54,.40);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.09),
              0 0 14px rgba(217,30,54,.22);
}

.pb-tier-promo-ends i {
  font-size: .86em;
  line-height: 1;
  opacity: .95;
}

.pb-tier-price { display: flex; align-items: baseline; gap: .4rem; flex-wrap: wrap; }

.pb-tier-amount {
  font-size: 2.1rem;
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -.015em;
  color: var(--pb-tier-text);
}

/* The struck original, beside the amount actually due. */
/* Muted, not the site's danger red (--pb-red #e05252): this is "the old
   price", not an error. Desaturated so it sits inside the dark palette, and
   held at secondary size so the current price stays the focal point. */
.pb-tier-was {
  font-size: 1rem;
  font-weight: 600;
  color: #C2707A;
  text-decoration: line-through;
  text-decoration-color: rgba(194,112,122,.8);
  text-decoration-thickness: 2px;
}

.pb-tier-period { font-size: .86rem; color: var(--pb-tier-muted); }

.pb-tier-then {
  margin-top: .2rem;
  font-size: .85rem;
  color: var(--pb-tier-text);
  opacity: .82;
}

.pb-tier-equiv,
.pb-tier-note {
  margin-top: .25rem;
  font-size: .78rem;
  line-height: 1.4;
  color: var(--pb-tier-muted);
}

.pb-tier-unavailable {
  padding: .45rem 0 .2rem;
  font-size: .86rem;
  color: var(--pb-tier-muted);
}

/* Reserved space, so a one-line description and a three-line one do not push
   the benefit lists to different heights. */
.pb-tier-card-desc {
  margin: .85rem 0 0;
  min-height: 2.4em;
  font-size: .86rem;
  line-height: 1.45;
  color: var(--pb-tier-muted);
}

.pb-tier-card-perks { margin-top: .85rem; }

/* The label is a <button> so the phone can use the whole row as a disclosure
   control. Up here it is dressed as the label it has always been - same size,
   same weight, same colour, no chevron - and pointer-events are off so the
   desktop card gains no interaction it did not have before. */
.pb-tier-perks-label {
  display: block;
  width: 100%;
  padding: 0;
  margin-bottom: .4rem;
  border: 0;
  background: none;
  text-align: left;
  font-family: inherit;
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--pb-tier-muted);
  pointer-events: none;
}
.pb-tier-perks-chevron { display: none; }
.pb-tier-perks-label:focus-visible {
  outline: 2px solid rgba(var(--pb-tier-rgb, 0,200,0), .55);
  outline-offset: 3px;
}

.pb-tier-card-perks ul { list-style: none; margin: 0; padding: 0; }

.pb-tier-card-perks li {
  display: flex;
  align-items: flex-start;
  gap: .5rem;
  margin-bottom: .32rem;
  font-size: .86rem;
  line-height: 1.42;
  color: var(--pb-tier-text);
}

.pb-tier-card-perks li i {
  color: var(--pb-tier-accent, #6b7280);
  font-size: .9rem;
  line-height: 1.5;
  filter: drop-shadow(0 0 5px rgba(var(--pb-tier-rgb), .35));
}

/* mt-auto is what holds the three buttons on one baseline however much
   content sits above them. */
.pb-tier-card-action { margin-top: auto; padding-top: 1.15rem; }

/* ── the action: Playbooki green, never a tier colour ───────────────────── */

/* The Subscribe button is the tier's colour. Ink comes from the palette's own
   validated pairing (TierPalette::ink), which the portable suite asserts at
   4.5:1 or better against every one of the twelve accents - so no creator
   choice can produce an unreadable button. The white overlay only lightens the
   surface, which raises that contrast rather than lowering it. */
.pb-tier-cta {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .45rem;
  width: 100%;
  padding: .78rem 1rem;
  border: 1px solid rgba(var(--pb-tier-rgb, 0,200,0), .55);
  border-radius: var(--pb-r-pill, 999px);
  background:
    linear-gradient(180deg, rgba(255,255,255,.24), rgba(255,255,255,0) 58%),
    var(--pb-tier-accent, #00C800);
  color: var(--pb-tier-ink, #06210A);
  font-size: .95rem;
  font-weight: 800;
  letter-spacing: .01em;
  line-height: 1.2;
  text-align: center;
  cursor: pointer;
  white-space: nowrap;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.40),
              0 0 22px rgba(var(--pb-tier-rgb, 0,200,0), .30),
              0 6px 18px rgba(0,0,0,.45);
  transition: transform var(--pb-fast, .15s) var(--pb-ease, ease),
              box-shadow var(--pb-mid, .25s) var(--pb-ease, ease),
              filter var(--pb-fast, .15s) var(--pb-ease, ease);
}
.pb-tier-cta:hover {
  color: var(--pb-tier-ink, #06210A);
  text-decoration: none;
  transform: translateY(-1px);
  filter: brightness(1.07);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.5),
              0 0 30px rgba(var(--pb-tier-rgb, 0,200,0), .42),
              0 10px 26px rgba(0,0,0,.5);
}
.pb-tier-cta:active {
  transform: translateY(1px);
  filter: brightness(.97);
  box-shadow: inset 0 2px 6px rgba(0,0,0,.35),
              0 0 14px rgba(var(--pb-tier-rgb, 0,200,0), .22);
}
.pb-tier-cta:focus-visible { outline: 2px solid rgba(var(--pb-tier-rgb, 0,200,0), .65); outline-offset: 2px; }

.pb-tier-cta.is-secondary {
  background: rgba(255,255,255,.035);
  color: var(--pb-tier-text);
  border-color: rgba(var(--pb-tier-rgb), .45);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.07),
              0 0 14px rgba(var(--pb-tier-rgb), .12);
}
.pb-tier-cta.is-secondary:hover {
  background: rgba(var(--pb-tier-rgb), .12);
  color: var(--pb-tier-text);
  filter: none;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.09),
              0 0 20px rgba(var(--pb-tier-rgb), .2);
}

.pb-tier-cta.is-held,
.pb-tier-cta.is-disabled {
  background: rgba(255,255,255,.03);
  color: var(--pb-tier-muted);
  border-color: var(--pb-glass-edge, rgba(255,255,255,.07));
  box-shadow: inset 0 1px 0 rgba(255,255,255,.04);
  cursor: not-allowed;
}
.pb-tier-cta.is-held:hover,
.pb-tier-cta.is-disabled:hover { transform: none; filter: none; }

/* ── stage 3: one statement of the offer, not four ───────────────────────
   The modal was built for a single monthly plan and says the offer three more
   times: a per-interval price list, a note under every subscribe button, and a
   bullet list repeating what the trial costs and when it ends. With a tier
   board above it choosing the length, the confirmation panel and the one line
   under the button already say all of it, for the length actually chosen. The
   rest is quietened - only while a tier checkout is on screen, and only by a
   marker class this file's own script puts there. The card requirement and the
   wallet fine print stay: those are the payment note, not the offer. */
.pb-tier-checkout .pb-promo-btnnote { display: none !important; }
.pb-tier-checkout .pb-trial-points { display: none; }

.pb-tier-cta-note {
  font-size: .78rem;
  line-height: 1.35;
  opacity: .74;
  text-align: center;
}

/* Hiding that actually hides. See setBundles() in playbooki-tiers.js: an
   element carrying Bootstrap's `d-block` cannot be hidden by adding `d-none`,
   because the two utilities are equally weighted and `d-block` is declared
   later. This file loads after Bootstrap, so this rule wins. */
.pb-tier-hide { display: none !important; }

/* ── stage 3: the selected-tier confirmation ─────────────────────────────
   This one lives in the checkout modal rather than on the board, which is the
   only place in this stylesheet that is not guaranteed to be on a dark
   surface: the modal follows the viewer's light/dark setting. So the panel is
   built from translucent neutrals and `currentColor` rather than from the
   board's fixed palette - it tints whatever it is dropped onto instead of
   fighting it. The tier's own colour arrives as a class on the box and is used
   for the edge and the pill, the two places identity belongs. */

.pb-tier-confirm {
  margin: 0 0 1.1rem;
  padding: .75rem .85rem;
  border: 1px solid rgba(127,127,127,.26);
  border-left: 3px solid rgba(var(--pb-tier-rgb, 0,200,0), .85);
  border-radius: var(--pb-r-lg, 14px);
  background: rgba(127,127,127,.08);
  text-align: left;
}

.pb-tier-confirm-label {
  display: block;
  margin-bottom: .3rem;
  font-size: .66rem;
  font-weight: 700;
  letter-spacing: .06em;
  text-transform: uppercase;
  opacity: .62;
}

.pb-tier-confirm-row {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: .45rem;
}

.pb-tier-confirm-row + .pb-tier-confirm-row { margin-top: .15rem; }

.pb-tier-confirm-name {
  font-family: var(--pb-fh, 'Barlow Condensed', sans-serif);
  font-size: 1.18rem;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: .005em;
  /* The card's own title is uppercased by the site's heading rule. The name a
     visitor pressed should read the same when they see it again at checkout,
     so it is uppercased here rather than left in whatever case the creator
     typed. */
  text-transform: uppercase;
}

/* The offer pill is the card's own component, reused verbatim so the badge a
   visitor pressed is the badge they see again at checkout. */
.pb-tier-confirm .pb-tier-confirm-offer { align-self: center; }

.pb-tier-confirm-price {
  font-size: 1.35rem;
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -.01em;
}

.pb-tier-confirm-period { font-size: .84rem; opacity: .72; }

.pb-tier-confirm-equiv,
.pb-tier-confirm-terms {
  margin-top: .2rem;
  font-size: .76rem;
  line-height: 1.35;
  opacity: .66;
}

/* ── responsive ─────────────────────────────────────────────────────────── */

/* Two across from here down, not from 992px.

   Between 992px and 1199px Bootstrap drops its container to 960px while the
   grid was still three across, which left each card 195px of content - the
   narrowest a card ever got, and too narrow for the composition to survive:
   a discounted price needs 241px, so it broke onto three lines; a long name
   could not share its line with a 97px badge, so it wrapped; and the
   countdown ended up stranded most of a card below the badge it belongs to.
   Every one of those was the card being asked to do a job at 195px that it
   does comfortably at 320. Two columns in this band give each card ~323px -
   wider than the 252px it gets at 1440 - and the whole band then behaves like
   the layout that was already approved, with no band-specific typography and
   no reserved head height propping it up. */
@media (max-width: 1199.98px) {
  /* Two cards per row, expressed as four half-columns rather than two whole
     ones. The arithmetic is identical - a card spanning two of four tracks is
     exactly as wide as one of two tracks, gap included - but the finer grid
     buys the half-column of offset that a lone last card needs to sit centred
     under the pair above it instead of parking in the left cell and leaving an
     empty quadrant.

     The offset applies only when the last card is also an odd-numbered one,
     so it is the three-tier case (and five, and one) that centres; a creator
     with two or four tiers fills its rows and nothing moves. */
  .pb-tier-grid { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .pb-tier-grid > .pb-tier-card { grid-column: span 2; }
  .pb-tier-grid > .pb-tier-card:last-child:nth-child(odd) { grid-column: 2 / span 2; }
}

@media (max-width: 767.98px) {
  .pb-tier-board { margin-top: 1.25rem; }
  /* One card per row. The span above would otherwise conjure a second,
     implicit column out of a single-column grid. */
  .pb-tier-grid { grid-template-columns: minmax(0, 1fr); gap: .7rem; }
  .pb-tier-grid > .pb-tier-card,
  .pb-tier-grid > .pb-tier-card:last-child:nth-child(odd) { grid-column: auto; }

  /* ── the length control becomes a swipeable carousel ──────────────────── */

  /* Scrolls rather than wrapping into a tall stack of pills, so step 1 never
     pushes step 2 off the first screen. overflow-x lives on the track, not on
     the page, so the glow cannot cause a horizontal scrollbar. */
  .pb-tier-lengths-track {
    flex-wrap: nowrap;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* proximity rather than mandatory. With centre alignment a mandatory
       container cannot rest at either extreme - the first pill's centre lies
       left of scrollLeft 0 and the last pill's lies right of the maximum - so
       the two end options would sit permanently half-clipped, which is the
       exact fault this pass exists to remove. proximity settles the swipe on
       a pill when it stops near one and stays out of the way otherwise. */
    scroll-snap-type: x proximity;
    scroll-padding: 0 .35rem;
    /* A swipe that runs off the end stays inside the control instead of
       chaining to the page or to the browser's back gesture. */
    overscroll-behavior-x: contain;
  }
  /* The native bar is hidden, not the affordance: the pills are real buttons,
     so tabbing to one still scrolls it into view, and the edge fades below
     say the row continues. */
  .pb-tier-lengths-track::-webkit-scrollbar { display: none; }
  .pb-tier-length { padding: .6rem .9rem; scroll-snap-align: center; }

  /* The fades belong to the WRAPPER, not the track: a pseudo-element inside a
     scrolling box scrolls away with its content, and masking the track itself
     would eat the glass edge and the pill radius with it. They paint only when
     there is really something past that edge - playbooki-tiers.js sets the
     classes on scroll - so a control that fits shows no fade at all. */
  .pb-tier-lengths-scroll { position: relative; }

  .pb-tier-lengths-scroll::before,
  .pb-tier-lengths-scroll::after {
    content: "";
    position: absolute;
    top: 1px;
    bottom: 1px;
    width: 30px;
    z-index: 2;
    opacity: 0;
    pointer-events: none;
    transition: opacity var(--pb-mid, .25s) var(--pb-ease, ease);
  }
  .pb-tier-lengths-scroll::before {
    left: 1px;
    border-radius: var(--pb-r-pill, 999px) 0 0 var(--pb-r-pill, 999px);
    background: linear-gradient(90deg, rgba(10,11,12,.72), rgba(10,11,12,0));
  }
  .pb-tier-lengths-scroll::after {
    right: 1px;
    border-radius: 0 var(--pb-r-pill, 999px) var(--pb-r-pill, 999px) 0;
    background: linear-gradient(270deg, rgba(10,11,12,.72), rgba(10,11,12,0));
  }
  .pb-tier-lengths-scroll.pb-has-start::before,
  .pb-tier-lengths-scroll.pb-has-end::after { opacity: 1; }

  .pb-tier-amount { font-size: 1.95rem; }
  /* Matches the specificity of the base rule above, which had to be raised
     to outrank the global h1..h6 weight. */
  .pb-tier-board .pb-tier-card .pb-tier-card-name { font-size: 1.42rem; }
  .pb-tier-card { padding: 1.2rem 1.05rem 1.15rem; }

  /* On a phone the card is already nearly the full viewport width, so a pool
     wider than the card pushes past the right edge - measured as real body
     overflow, which the site's `overflow-x: hidden` would have hidden rather
     than prevented. Inset it instead, and trim the blur radius: less work per
     frame on a phone, same effect at this size. */
  .pb-tier-card[class*="pb-tier-c-"]::before {
    left: 5%;
    right: 5%;
    bottom: -22px;
    height: 52%;
    filter: blur(22px);
  }
  /* Stacked cards size to their own content; reserving description space
     would only add dead air. */
  .pb-tier-card-desc { min-height: 0; margin-top: .55rem; line-height: 1.4; }
  .pb-tier-cta { padding: .85rem 1rem; }

  /* ── vertical rhythm ──────────────────────────────────────────────────── */

  /* Stacked cards are read one at a time, so the space that gives three
     side-by-side cards room to breathe just becomes scrolling here. Every
     value below is a trim of an existing one - nothing is removed, and the
     card keeps a full rem of padding on every edge. */
  /* wrap-reverse, not wrap. The pill still sits beside the price whenever the
     card can hold both - the arrangement this design is built around - but on
     the narrowest phones a discounted price claims the whole line, and the
     pill has to go somewhere. Reversing the cross axis sends it UP, directly
     under the badge it belongs with, instead of stranding it below the price
     with the badge floating a line and a half above. Content decides, so
     there is no extra breakpoint to keep in sync; align-items flips to
     flex-end because wrap-reverse puts cross-start at the bottom, and
     flex-end is what now means "top". Mobile only: on a desktop the cards
     sit in a row and the pill dropping BELOW the price is what keeps all
     three prices on one line. */
  .pb-tier-price-row {
    flex-wrap: wrap-reverse;
    align-items: flex-end;
  }

  .pb-tier-card { padding: .95rem .95rem .9rem; }
  .pb-tier-card-head { margin-bottom: .3rem; }
  .pb-tier-card-perks { margin-top: .6rem; }
  .pb-tier-card-perks li { margin-bottom: .28rem; line-height: 1.38; }

  /* ── Includes becomes a disclosure ────────────────────────────────────── */

  /* Everything below is gated on `is-collapsible`, which playbooki-tiers.js
     adds. If that file fails to load the list simply stays open, the way it is
     today, rather than collapsing with nothing able to open it again.

     The whole row is the control, not the chevron: a 44px target running the
     full width of the card, which is what the thumb actually aims at. The
     button gets its interaction back here (it is pointer-events:none on a
     desktop, where this is just a label). */
  .pb-tier-card-perks.is-collapsible .pb-tier-perks-label {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: .5rem;
    min-height: 44px;
    margin-bottom: 0;
    padding: 0;
    pointer-events: auto;
    cursor: pointer;
    -webkit-tap-highlight-color: transparent;
  }
  .pb-tier-card-perks.is-collapsible .pb-tier-perks-chevron {
    display: block;
    font-size: 1rem;
    line-height: 1;
    color: var(--pb-tier-muted);
    transition: transform var(--pb-mid, .25s) var(--pb-ease, ease);
  }
  .pb-tier-card-perks.is-collapsible.is-open .pb-tier-perks-chevron { transform: rotate(180deg); }

  /* 0fr -> 1fr animates the height without anyone having to measure it, and
     without the easing artefact a large max-height gives. visibility is what
     actually takes the collapsed list out of the accessibility tree; it flips
     at the end of the collapse and at the start of the open. */
  .pb-tier-card-perks.is-collapsible .pb-tier-perks-body {
    display: grid;
    grid-template-rows: 0fr;
    visibility: hidden;
    overflow: hidden;
    transition: grid-template-rows var(--pb-mid, .25s) var(--pb-ease, ease),
                visibility 0s linear var(--pb-mid, .25s);
  }
  .pb-tier-card-perks.is-collapsible .pb-tier-perks-body > * { min-height: 0; }

  .pb-tier-card-perks.is-collapsible.is-open .pb-tier-perks-body {
    grid-template-rows: 1fr;
    visibility: visible;
    transition: grid-template-rows var(--pb-mid, .25s) var(--pb-ease, ease),
                visibility 0s;
  }
  .pb-tier-card-perks.is-collapsible.is-open .pb-tier-perks-body ul { padding-top: .35rem; }

  /* mt-auto still holds the button to the bottom of the card; only the space
     above it is trimmed. */
  .pb-tier-card-action { padding-top: .7rem; }

  /* The supporting lines under a trial or a discount - what renews, when, the
     card-and-cancellation sentence. Still 12px and still full sentences; the
     leading is what tightens, so the offer above stays dominant. */
  .pb-tier-then { margin-top: .15rem; font-size: .82rem; line-height: 1.32; }
  .pb-tier-equiv,
  .pb-tier-note { margin-top: .2rem; font-size: .75rem; line-height: 1.35; }

  /* The pill system is the same 26px at every width, so nothing to restate.
     Only the countdown's glow is lifted here. */
  .pb-tier-promo-ends {
    box-shadow: inset 0 1px 0 rgba(255,255,255,.09),
                0 0 18px rgba(217,30,54,.28);
  }

  /* Stacked, each title holds its own against the card above it rather than
     against two siblings, so the bloom comes up a little - and narrows, since
     the card is narrower and it must still clear the card's padding. */
  .pb-tier-card[class*="pb-tier-c-"] .pb-tier-card-head::before {
    width: 176px;
    height: 54px;
    margin-top: -27px;
    background: radial-gradient(closest-side,
      rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .38)) 0%,
      rgba(var(--pb-tier-rgb), calc(var(--pb-tier-a-glow, .55) * .15)) 52%,
      rgba(var(--pb-tier-rgb), 0) 100%);
  }
}

/* Motion is decoration here; the layout does not depend on it. */
@media (prefers-reduced-motion: reduce) {
  .pb-tier-card,
  .pb-tier-cta,
  .pb-tier-length,
  .pb-tier-perks-body,
  .pb-tier-perks-chevron { transition: none; }
  .pb-tier-card:hover,
  .pb-tier-cta:hover,
  .pb-tier-cta:active { transform: none; }
}

/* ═══════════════════════════════════════════════════════════════════════
   v2.2 Stage 4 polish — one board, whatever the viewer's state

   The board is no longer a flex item inside the profile action row, so it
   takes the container's width like any block. These rules make that explicit
   and stop a signed-in board from being narrower than a logged-out one.
   ═══════════════════════════════════════════════════════════════════════ */

.pb-tier-board {
  width: 100%;
  margin-left: auto;
  margin-right: auto;
}

/* The current plan reads from the card itself: the flag, a quieter edge, and
   a held button. It does not need a separate status column beside it. */
.pb-tier-card.is-current {
  box-shadow: 0 0 0 1px rgba(0, 255, 0, .22), 0 8px 28px rgba(0, 255, 0, .10);
}

/* "Your plan" and "Change plan" are the same control as Subscribe in every
   dimension — same height, same padding, same centring — so a subscribed
   board is the same component with different words in it. */
.pb-tier-cta,
.pb-tier-cta.is-held,
.pb-tier-cta.is-secondary,
.pb-tier-cta.is-disabled {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .4rem;
  width: 100%;
  max-width: 100%;
  min-width: 0;
  box-sizing: border-box;
  padding-left: .75rem;
  padding-right: .75rem;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.pb-tier-cta i {
  flex: 0 0 auto;
  margin: 0 !important;
}

.pb-tier-cta.is-held {
  opacity: 1;
  cursor: default;
  border: 1px solid rgba(0, 255, 0, .30);
  background: rgba(0, 255, 0, .10);
}

/* ═══════════════════════════════════════════════════════════════════════
   v2.2 Stage 4 polish — the billing length bar, sized to its own content

   The track was a full-width flex row with the default `justify-content`,
   so six pills needing about 830px sat left-aligned inside 930px of bar and
   the leftover hundred pixels collected on the right. That is what read as
   stretched and off-centre: not the pills' spacing, the slack behind them.

   The bar is now as wide as the options it holds and centred in the board,
   and it behaves the way the phone version already did at every width — one
   row that scrolls rather than wrapping, with the same edge fades. No
   colours, no selected state, no savings text changed.
   ═══════════════════════════════════════════════════════════════════════ */

/* The BAR is what centres; its heading is not dragged along with it.
   "BILLING LENGTH" and "CHOOSE YOUR LEVEL" are the page's two section
   headings and they share a left margin — indenting one of them to follow a
   centred control breaks a stronger rule than it satisfies. */
.pb-tier-lengths-scroll {
  position: relative;
  width: -moz-fit-content;
  width: fit-content;
  max-width: 100%;
  margin-left: auto;
  margin-right: auto;
}

.pb-tier-lengths-track {
  flex-wrap: nowrap;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
  scrollbar-width: none;
  overscroll-behavior-x: contain;
  /* `safe` matters: a plain `center` on an overflowing flex row pushes the
     first pill past the scroll origin, where nothing can reach it. With
     `safe` the row centres while it fits and falls back to the start edge the
     moment it does not. */
  justify-content: safe center;
  gap: .35rem;
  padding: .35rem .45rem;
}

.pb-tier-lengths-track::-webkit-scrollbar { display: none; }

/* The fades were defined only inside the phone breakpoint. The script that
   drives them has always run at every width, so lifting them here needs no
   JavaScript change — and they only paint when there is genuinely something
   past that edge. */
.pb-tier-lengths-scroll::before,
.pb-tier-lengths-scroll::after {
  content: "";
  position: absolute;
  top: 1px;
  bottom: 1px;
  width: 30px;
  z-index: 2;
  opacity: 0;
  pointer-events: none;
  transition: opacity var(--pb-mid, .25s) var(--pb-ease, ease);
}

.pb-tier-lengths-scroll::before {
  left: 1px;
  border-radius: var(--pb-r-pill, 999px) 0 0 var(--pb-r-pill, 999px);
  background: linear-gradient(90deg, rgba(10,11,12,.72), rgba(10,11,12,0));
}

.pb-tier-lengths-scroll::after {
  right: 1px;
  border-radius: 0 var(--pb-r-pill, 999px) var(--pb-r-pill, 999px) 0;
  background: linear-gradient(270deg, rgba(10,11,12,.72), rgba(10,11,12,0));
}

.pb-tier-lengths-scroll.pb-has-start::before,
.pb-tier-lengths-scroll.pb-has-end::after { opacity: 1; }

/* Desktop only: the heading centres over the bar it labels.
   
   The bar is only inset from the board's edges once the board is wider than
   the options need — 992px up, where the board is 930 and the bar 838. Below
   that the bar fills the width and becomes the scrolling strip, and a centred
   heading would float in the middle of a full-width control while "CHOOSE
   YOUR LEVEL" stayed at the edge. So the rule starts exactly where the inset
   does. Typography, size, weight, tracking and the gap to the bar are
   untouched; only the text's alignment inside its own block changes. */
@media (min-width: 992px) {
  .pb-tier-lengths-label {
    text-align: center;
  }
}

/* ═══════════════════════════════════════════════════════════════════════════
   v2.2 Stage 6 (rev2) — the locked-content panel.

   WHAT CHANGED FROM REV1, AND WHY

   Rev1 treated the tier colour as an accent on a plain panel: a hairline
   border, a small badge, a green button. Reviewed as "too stripped down", and
   correctly — the original locked panel was a PIECE OF DESIGN, and rev1 had
   quietly replaced it with a notice. This restores the original's proportions
   — the big lock ring, the display heading, the large luminous pill, the type
   chip — and then lets the required tier own the whole composition rather than
   just decorate it.

   So the rule from the change-membership page is deliberately INVERTED here,
   and that is not an inconsistency. There, three tiers sit side by side and
   the colour's job is to tell them apart, so it stays a hairline. Here there
   is exactly one tier on screen and its job is to say WHICH DOOR THIS IS — so
   the colour carries the panel, the ring, the glyph and the button. The
   platform green does not appear in this panel at all when a tier resolves;
   the CTA inherits the tier's identity instead, which is what makes an amber
   Inner Circle lock read differently from a sky Homies lock at a glance.

   Everything still arrives as `pb-tier-c-<key>` from TierPalette. No value is
   written into the markup, and the accents are the same ones defined at the
   top of this file — this section only spends them.
   ═════════════════════════════════════════════════════════════════════════ */

.pb-locked-panel[class*="pb-tier-c-"] {
  position: relative;
  isolation: isolate;
  overflow: hidden;
  border-radius: 18px;
  /* `!important` on the border, and only the border. The site's shared panel
     rule paints this element a low-alpha PLATFORM GREEN and wins on
     specificity — measured, not assumed. A green border around an amber tier
     is the one thing this panel must never show. Scoped to the class PAIR, so
     it cannot reach any other panel on the site. */
  border: 1px solid rgba(var(--pb-tier-rgb, 143,163,184), .34) !important;
  /* `!important` here for the same measured reason as the border: without it
     the computed shadow was the site's own `rgba(0,0,0,.34) 0 14px 34px`, so
     the panel kept a neutral drop shadow and the tier glow never rendered at
     all. The border was overridden and the glow was not — half the treatment
     landed, which is worse than neither. */
  box-shadow:
    0 0 0 1px rgba(var(--pb-tier-rgb, 143,163,184), .06),
    0 18px 48px -24px rgba(var(--pb-tier-rgb, 143,163,184), .55),
    inset 0 1px 0 rgba(255,255,255,.05) !important;
}

/* The glass ground and the diagonal weave, as ONE overlay.

   It has to be a pseudo-element rather than a background on the panel itself:
   the blurred post preview is an inline `background:` shorthand (built
   server-side from the post's own media id, untouched by this stage) and would
   overwrite anything set here. Layering above it keeps the preview visible
   under the texture instead of fighting it. */
.pb-locked-panel[class*="pb-tier-c-"]::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background:
    repeating-linear-gradient(
      135deg,
      rgba(var(--pb-tier-rgb, 143,163,184), .055) 0 1px,
      transparent 1px 13px
    ),
    radial-gradient(
      120% 90% at 50% 0%,
      rgba(var(--pb-tier-rgb, 143,163,184), .13) 0%,
      rgba(var(--pb-tier-rgb, 143,163,184), .04) 45%,
      transparent 72%
    ),
    linear-gradient(180deg, rgba(8,10,12,.88) 0%, rgba(8,10,12,.94) 100%);
}

/* White is as bright as the ring it sits inside; every alpha it touches is
   dialled back, the same exception the palette makes everywhere else. */
.pb-locked-panel.pb-tier-c-white {
  box-shadow:
    0 0 0 1px rgba(233,238,242,.05),
    0 16px 40px -26px rgba(233,238,242,.35),
    inset 0 1px 0 rgba(255,255,255,.05) !important;
}

.pb-locked-panel.pb-tier-c-white::before {
  background:
    repeating-linear-gradient(135deg, rgba(233,238,242,.04) 0 1px, transparent 1px 13px),
    radial-gradient(120% 90% at 50% 0%, rgba(233,238,242,.08) 0%, transparent 70%),
    linear-gradient(180deg, rgba(8,10,12,.88) 0%, rgba(8,10,12,.94) 100%);
}

/* Everything the panel contains sits above the overlay. */
.pb-locked-panel[class*="pb-tier-c-"] > * {
  position: relative;
  z-index: 1;
}

/* ── the lock ───────────────────────────────────────────────────────────────
   A ring, not a disc. At feed scale a filled circle in the tier colour is a
   coloured blob; a ring with a faint wash inside reads as a lock and lets the
   glyph carry the hue. */

/* THE RING IS THE WRAPPER, NOT THE GLYPH.

   Measured, after two wrong guesses. The `<i>` carries `.ico-no-result`, whose
   site rules set its display, size and radius more specifically than anything
   scoped sanely here: every non-`!important` declaration aimed at the `<i>` —
   width, height, border-radius, display — computed away to 27x27 with square
   corners, while only the `!important` colour and background survived. The
   circle that looked right in the first pass was never the glyph's; it was the
   WRAPPER's own 58x58 ring, which the site paints PLATFORM GREEN.

   So the wrapper becomes the ring, at the size the original design used, in the
   tier's colour — and the `<i>` goes back to being just a glyph. One element
   owns the shape, one owns the mark, and neither is fighting the other. */
.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-icon {
  display: inline-flex !important;
  align-items: center !important;
  justify-content: center !important;
  /* min/max as well as width: a site rule pins this element to 58px with its
     own !important, and `width` alone lost to it — the ring came out 58 wide
     and 108 tall. Measured, not guessed. */
  width: 108px !important;
  min-width: 108px !important;
  max-width: 108px !important;
  height: 108px !important;
  margin: 0 auto 1.15rem !important;
  border-radius: 50% !important;
  border: 1px solid rgba(var(--pb-tier-rgb, 143,163,184), .38) !important;
  background:
    radial-gradient(circle at 50% 45%,
      rgba(var(--pb-tier-rgb, 143,163,184), .16) 0%,
      rgba(var(--pb-tier-rgb, 143,163,184), .05) 55%,
      transparent 72%) !important;
  box-shadow:
    0 0 0 10px rgba(var(--pb-tier-rgb, 143,163,184), .045),
    0 0 34px -6px rgba(var(--pb-tier-rgb, 143,163,184), .40),
    inset 0 0 22px -8px rgba(var(--pb-tier-rgb, 143,163,184), .55) !important;
}

.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-icon i {
  border: 0 !important;
  background: none !important;
  box-shadow: none !important;
  font-size: 2.5rem !important;
  line-height: 1 !important;
  color: var(--pb-tier-accent, #8FA3B8) !important;
}

/* ── heading and copy ───────────────────────────────────────────────────── */

.pb-locked-panel .pb-locked-title {
  font-size: 1.75rem;
  line-height: 1.1;
  letter-spacing: .01em;
  margin: 0 0 .55rem;
  color: #FFFFFF;
  text-shadow: 0 2px 18px rgba(0,0,0,.55);
}

.pb-locked-sub {
  max-width: 32rem;
  margin: 0 auto 1.35rem;
  font-size: .98rem;
  line-height: 1.5;
  color: rgba(233,238,242,.82);
  overflow-wrap: anywhere;
}

/* ── the required-tier badge ────────────────────────────────────────────────
   Informational, and the one filled use of the accent at badge size. It names
   the level; the button no longer has to. */

.pb-locked-tier {
  display: inline-flex;
  align-items: center;
  gap: .34rem;
  max-width: 100%;
  margin: 0 0 .7rem;
  padding: .26rem .68rem;
  border-radius: 999px;
  font-size: .66rem;
  font-weight: 800;
  letter-spacing: .12em;
  text-transform: uppercase;
  line-height: 1.25;
  color: var(--pb-tier-ink, #0B0B0B);
  background: var(--pb-tier-accent, #8FA3B8);
  box-shadow: 0 4px 16px -6px rgba(var(--pb-tier-rgb, 143,163,184), .8);
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: left;
}

.pb-locked-tier i { flex: 0 0 auto; font-size: .72rem; }

/* ── the CTA ────────────────────────────────────────────────────────────────
   The original's proportions — a large luminous pill — inheriting the tier's
   colour instead of the platform green. `!important` is needed throughout
   because this is a `.btn.btn-primary` and Bootstrap's own rules are more
   specific than anything scoped sanely; the override is confined to
   `.pb-locked-cta`, which exists only inside this panel. */

.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: .55rem;
  width: auto !important;
  min-width: min(19rem, 100%);
  max-width: 100%;
  min-height: 58px;
  padding: .85rem 2.1rem !important;
  border: 0 !important;
  border-radius: 999px !important;
  /* THE RECTANGLE LEAK, AND ITS ACTUAL SOURCE.
     The site's `.btn` carries
       clip-path: polygon(0 0, calc(100% - 6px) 0, 100% 6px, 100% 100%,
                          6px 100%, 0 calc(100% - 6px));
     — a chamfered RECTANGLE. `clip-path` clips everything the element paints,
     box-shadow included, so the tier glow was being chopped off square around
     a pill-shaped button: a hard rectangular edge sitting behind the rounded
     silhouette. It was never a wrapper, a background layer or a stray
     pseudo-element, and covering it with another layer would have left the
     clip in place.
     Cleared here only, on this one CTA. `overflow: hidden` stays, because it
     clips the button's hover shine to the rounded shape and does NOT affect
     shadows. */
  clip-path: none !important;
  font-size: 1.06rem;
  font-weight: 800;
  letter-spacing: .005em;
  line-height: 1.25;
  white-space: normal;
  overflow-wrap: anywhere;
  color: var(--pb-tier-ink, #0B0B0B) !important;
  /* Split rather than a shorthand. `background: <gradient>, var(--accent)`
     looks valid but the custom property is parsed as an IMAGE layer, resolves
     to `none`, and the button loses its fill entirely — computed
     `background-image` read "…, none" until this was separated. The colour
     belongs to `background-color`. */
  background-color: var(--pb-tier-accent, #8FA3B8) !important;
  background-image: linear-gradient(
      180deg,
      rgba(255,255,255,.22) 0%,
      rgba(255,255,255,0) 42%
    ) !important;
  box-shadow:
    0 10px 30px -10px rgba(var(--pb-tier-rgb, 143,163,184), .75),
    0 0 46px -14px rgba(var(--pb-tier-rgb, 143,163,184), .55),
    inset 0 1px 0 rgba(255,255,255,.35),
    inset 0 -1px 0 rgba(0,0,0,.18);
  transition: filter .15s ease, transform .15s ease, box-shadow .15s ease;
}

.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn:hover,
.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn:focus {
  filter: brightness(1.06);
  color: var(--pb-tier-ink, #0B0B0B) !important;
  box-shadow:
    0 12px 34px -10px rgba(var(--pb-tier-rgb, 143,163,184), .85),
    0 0 54px -12px rgba(var(--pb-tier-rgb, 143,163,184), .6),
    inset 0 1px 0 rgba(255,255,255,.4),
    inset 0 -1px 0 rgba(0,0,0,.18);
}

.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn:active { transform: translateY(1px); }

.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn:focus-visible {
  outline: 2px solid var(--pb-tier-accent, #8FA3B8);
  outline-offset: 3px;
}

.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn i { font-size: 1.05rem; }

/* The hover shine is a skewed bar the site positions outside the button and
   sweeps across. It is transparent at rest and `overflow: hidden` keeps it
   inside the pill — but it is given the pill's own radius as well, so nothing
   it does can ever square off a corner. */
.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn::before,
.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn::after {
  border-radius: inherit;
  clip-path: none;
}

/* A disabled CTA (creator sells nothing) keeps the shape and drops the light,
   so it reads as unavailable rather than as a different control. */
.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn.disabled,
.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn:disabled {
  background: rgba(255,255,255,.07) !important;
  color: rgba(233,238,242,.62) !important;
  box-shadow: none;
}

/* ── the neutral "level withdrawn" message ──────────────────────────────────
   No accent and no action: it is not an offer. */

.pb-locked-note {
  display: inline-block;
  max-width: 32rem;
  padding: .65rem .95rem;
  border: 1px solid rgba(255,255,255,.14);
  border-radius: 12px;
  background: rgba(0,0,0,.4);
  font-size: .88rem;
  line-height: 1.5;
  color: rgba(233,238,242,.82);
  overflow-wrap: anywhere;
}

/* ── the content-type chips ─────────────────────────────────────────────── */

.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-media {
  margin-top: 1.15rem !important;
  margin-bottom: 0 !important;
}

.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-media .list-inline-item {
  display: inline-flex;
  align-items: center;
  gap: .35rem;
  padding: .3rem .75rem;
  border: 1px solid rgba(255,255,255,.12);
  border-radius: 999px;
  background: rgba(255,255,255,.05);
  font-size: .78rem;
  font-weight: 600;
  color: rgba(233,238,242,.78);
}

.pb-locked-panel[class*="pb-tier-c-"] .pb-locked-media .list-inline-item i {
  color: var(--pb-tier-accent, #8FA3B8);
}

/* ═══ narrow widths ═══════════════════════════════════════════════════════
   "Subscribe to Unlock" and "Upgrade to Unlock" are short enough to hold one
   line at 320px, which is the point of dropping the tier name from the button
   — the badge above carries it instead. */

@media (max-width: 575.98px) {
  .pb-locked-panel[class*="pb-tier-c-"] .pb-locked-icon {
    width: 88px !important;
    min-width: 88px !important;
    max-width: 88px !important;
    height: 88px !important;
    box-shadow:
      0 0 0 8px rgba(var(--pb-tier-rgb, 143,163,184), .04),
      0 0 26px -6px rgba(var(--pb-tier-rgb, 143,163,184), .38),
      inset 0 0 18px -8px rgba(var(--pb-tier-rgb, 143,163,184), .55) !important;
  }

  .pb-locked-panel[class*="pb-tier-c-"] .pb-locked-icon i { font-size: 2.05rem !important; }

  .pb-locked-panel .pb-locked-title { font-size: 1.45rem; }
  .pb-locked-sub { font-size: .92rem; margin-bottom: 1.15rem; }

  .pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn {
    min-height: 54px;
    min-width: min(17rem, 100%);
    padding: .8rem 1.5rem !important;
    font-size: 1rem;
  }
}

/* 375px, not 400px. A 390px phone is the common case and should get the
   roomier treatment; only the genuinely narrow 320px class needs the tighter
   one. At 400 the breakpoint was catching 390 and shrinking a panel that had
   plenty of room. */
@media (max-width: 374.98px) {
  .pb-locked-panel[class*="pb-tier-c-"] { border-radius: 16px; }

  .pb-locked-panel[class*="pb-tier-c-"] .pb-locked-icon {
    width: 76px !important;
    min-width: 76px !important;
    max-width: 76px !important;
    height: 76px !important;
  }

  .pb-locked-panel[class*="pb-tier-c-"] .pb-locked-icon i { font-size: 1.8rem !important; }

  .pb-locked-panel .pb-locked-title { font-size: 1.3rem; }
  .pb-locked-tier { font-size: .61rem; letter-spacing: .1em; }
  .pb-locked-sub { font-size: .88rem; }

  .pb-locked-panel[class*="pb-tier-c-"] .pb-locked-cta.btn {
    min-height: 50px;
    min-width: 0;
    width: 100% !important;
    padding: .75rem 1rem !important;
    font-size: .95rem;
    gap: .4rem;
  }
}


/* v2.2.5 — visible refusal reasons and the free first tier.
   Owner safeguard 5: a disabled tier-board action states WHY as text beneath
   it, on every screen size (a title attribute is never shown on a phone).
   Scoped to pb-tier- like everything else in this sheet. */
.pb-tier-cta-reason {
  margin: .45rem 0 0;
  font-size: .8rem;
  line-height: 1.35;
  color: var(--pb-tier-muted);
  text-align: center;
  overflow-wrap: anywhere;
}
.pb-tier-cta-reason a {
  color: inherit;
  text-decoration: underline;
}
.pb-tier-card.is-free .pb-tier-amount { letter-spacing: .02em; }
.pb-tier-free-audience { display: block; margin-top: .35rem; }