/* planner-cards.css — the golden card's skin. (B12a / ruling D5; S2 full extraction)
 *
 * THE SOURCE OF TRUTH NOW, no longer generated: S2 removed the golden page's
 * inline card block, so BOTH planners (pl/team-analyzer + team-analyzer) load
 * this one sheet — one skin, two pages, no fork possible. Edit HERE; the
 * static gate fails the build if either page grows an inline rule for any
 * card-chain class, and the visual gate holds the pixels at 0.000%.
 * (History: born as a harvest of the golden's inline rules — byte-equal at
 * the moment of the swap; scripts/planner-gates/harvest-card-css.js remains
 * as the tool that produced it.)
 */

.ta-myteam-bench .pp-bench-row { gap: 14px; flex-wrap: wrap; justify-content: center; }
.ta-ishirt .ini { font-weight: 800; color: #fff; font-size: 0.85rem; }
/* PA-V6 — 112px, not 100px. The action row is WC's (5 buttons × 18px + 4 × 2px
       gap = 98px) and WC sizes its box at 112px FOR THAT REASON (wc:1023-1027, and
       the comment at wc:2198). PL copied the buttons and kept a 100px box, so the
       end buttons spilled out of the dark lines panel on every player. */
    .ta-pitch-player { position: absolute; transform: translate(-50%,-50%); width: 112px; text-align: center; z-index: 2; cursor: pointer; }
/* The bench reuses the pitch player box but is laid out in FLOW, so it must drop
       the pitch's centring transform — without this every bench box is pulled half
       its own width/height up and to the side, which on the My-Team tab dragged the
       whole bench row up over the pitch's bottom edge. */
    .pp-bench-player { transform: none; }
.ta-pitch-player:hover .ta-pitch-shirt { filter: brightness(1.2); }
.ta-pitch-shirt { width: 52px; height: 52px; margin: 0 auto 4px; display: grid; place-items: center; border-radius: 12px;
      background: rgba(30,41,59,0.35); border: 1px solid rgba(255,255,255,0.18); overflow: visible; backdrop-filter: blur(2px);
      position: relative; transition: filter .15s; }
/* ABSOLUTE, not just width/height:100%. The shirt is a content-sized grid, so a
       percentage HEIGHT on the image is indefinite and resolves to `auto` — a 110x140
       FPL headshot then rendered 50x64 inside a 52x52 box and only the shirt's
       `overflow:hidden` was hiding it. The moment the shirt stopped clipping (so the
       armband badge could hang off its corner) the image bled 13px down THROUGH the
       name line. Pinning to the box makes the size real instead of clipped, which is
       the pattern `.ta-face img` in this same file already uses. */
    .ta-pitch-shirt img, .pp-bench-shirt img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; object-position: top center; border-radius: 11px; }
.ta-pitch-shirt-fallback { font-size: 24px; line-height: 1; }
/* faceHtml's initials fallback — the My-Team pitch styles `.ini` under `.ta-shirt`,
       so the planner pitch/bench need their own rule or the initials render unstyled. */
    .ta-pitch-shirt .ini, .pp-bench-shirt .ini, .tm-shirt .ini { font-weight: 800; color: #fff; font-size: 0.95rem; }
.tm-shirt .ini { font-size: 0.85rem; }
.ta-pitch-lines { background: rgba(15,23,42,0.88); border: 1px solid rgba(255,255,255,0.25); border-radius: 10px;
      padding: 4px 5px 5px; display: grid; gap: 0; line-height: 1; }
.ta-pitch-line { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; font-size: 0.75rem; color: #e2e8f0; text-align: center; margin: 0; padding: 0; }
/* ⚠ `min-height`, NOT the golden's fixed `height: 2.2em`. WC pins two rows so every
       player box is the same height, and that is right THERE: its names are Hebrew nation
       players and routinely wrap. FPL `web_name` is a bare surname — measured over the
       whole 568-player bootstrap, **0** wrap at the 102px desktop box and 20 (3.5%) at the
       52px mobile one — so the reserved second row was dead space under every name on
       desktop, always, and under 96.5% of them on mobile. The clamp STAYS: the 20 that do
       wrap still get their second line, they just no longer make every other box pay for
       it. Uniform height is preserved wherever it is actually observable (desktop, 0%). */
/* ⚠ 1.25, NOT 1.1 - THE ASCENDERS WERE BEING SHAVED (owner, 2026-08-18). This row
       is `overflow: hidden` for the two-line clamp, and at 1.1 the line box was
       SHORTER THAN THE FONT'S OWN CONTENT AREA: measured on the served page, a
       0.72rem name box rendered 12.67px around 14px of content on every card of
       every planner. Half-leading splits that overflow top and bottom, so the top
       ~1.3px was clipped - invisible on a bare Latin surname, but it cuts the flat
       top off a Hebrew lamed and the caps of names like Trafford, which is how it
       was spotted. Heebo needs ~1.22em; 1.25 clears it with a hair to spare.
       The `min-height` moves WITH the line-height, or the box stops being exactly
       one row tall and the clamp note above stops being true. */
    .ta-pitch-line.name { font-size: 0.72rem; font-weight: 700; white-space: normal; overflow: hidden; display: -webkit-box;
      -webkit-line-clamp: 2; -webkit-box-orient: vertical; line-height: 1.25; min-height: 1.25em; }
/* 0.56rem, not 0.6: the meta row now carries CLUB · vs OPP (venue) · price and the
       longest real case ("MUN · vs HUL (A) · £12.0") clipped by 6px inside the 100px
       content box. Measured down rather than guessed — 0.58 still clipped by 2px.
       ⚠ The box itself is NOT the lever: .ta-pitch-player is absolutely positioned and
       at a 900px viewport adjacent boxes already sit at a 0px gap, so widening it to fit
       the text starts overlapping players. (They ALREADY overlap at ~780px, at the
       shipped 112px — pre-existing, not from this line.) */
    .ta-pitch-line.meta { color: #cbd5e1; font-size: 0.56rem; line-height: 1.1; padding-bottom: 1px; }
/* The planner overrides `color` inline (per-xPts heat), so this default only
       ever paints the My-Team pitch — WC's accent points line (wc:1233-1234). */
    .ta-pitch-line.points { font-size: 0.95rem; font-weight: 800; line-height: 1; margin-top: 0; color: var(--vc-accent); }
.ta-pitch-line.eo { color: #94a3b8; font-weight: 600; font-size: 0.62rem; }
/* Price is a number the user actively scans while building a squad — it was the
       dimmest thing on the row (#94a3b8 at the meta size). Brighter and a step larger
       than its siblings, without touching .meta itself: that row is nowrap+ellipsis at
       a 100px content box, so raising the whole line's size clips it (measured — 0.58rem
       was already 2px over before the crest moved off this row). Only the price grows.
       `em`, not `rem`, so it scales with the mobile .meta override instead of fighting it. */
    .pp-meta-price { color: #dbe6f2; font-weight: 700; font-size: 1.12em; }
/* ⚠ THE PRICE MUST SURVIVE THE ELLIPSIS — and the ellipsis is what eats it.
       `.ta-pitch-line` truncates as ONE nowrap box, so on a card whose opponent is long
       everything after the club runs past the ellipsis and the price vanishes from the
       line entirely (it survives only on the shirt badge, a different and smaller
       affordance). Two cases, both measured: a 9 Fantasy DOUBLE round on IPL renders
       "נגד הפ' ר"ג (ח) + הפ' חיפה (ב)", and on the UCL planner two of fifteen desktop
       cards lost their price to a long club name (production, 2026-09-06, 1440px).
       Two flex items instead: the opponent box shrinks and ellipsises on its own, the
       price never does. `min-width: 0` is the load-bearing half — a flex item's default
       `min-width: auto` refuses to shrink below its content, so without it the box
       overflows the card instead of truncating and nothing is gained.
       ⛔ IT LIVES HERE, NOT ON A PAGE. The IPL planner solved this inline on 2026-08-22
       and the other two planners never got it — the exact fork this hub exists to stop.
       All three link this sheet; all three now mark the line `pp-meta-flex`. */
    .ta-pitch-line.meta.pp-meta-flex { display: flex; align-items: baseline; justify-content: center; }
    .pp-meta-flex .pp-meta-opp-box { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
    .pp-meta-flex .pp-meta-price { flex: 0 0 auto; white-space: nowrap; }
.pp-opp-prefix { opacity: 0.8; }
.pp-pts-unit { display: none; font-size: 0.78em; font-weight: 600; margin-inline-start: 2px; }
/* The slot PLSusp fills. Copied from wc:1232 — it was the one piece of WC's
       player box PA-V11 added to the MARKUP without adding to the CSS, which would
       have dropped the marker into the shirt's grid flow instead of its corner. */
    .pp-yc-badge { position: absolute; top: 3px; inset-inline-end: 3px; line-height: 0; z-index: 4; pointer-events: none; }
/* WC's fix, ported (wc:2233): the lock shares the yellow card's corner, so when both
       are present the lock drops BELOW it rather than one hiding the other — a locked
       at-risk player has to read as both. `:has()` re-evaluates when the marker injects
       `.pl-yc-warn` after render. The C/V badge and the bench position pill hold the
       opposite corner and never co-occur (the bench card draws no armband). */
    .ta-pitch-shirt:has(.pl-yc-warn) .pp-lock-flag,
    .pp-bench-shirt:has(.pl-yc-warn) .pp-lock-flag { top: 24px; }
/* Two steps down, plus a hair of negative tracking — enough for every name the pool
       has (worst case 69.3px into 58px) and small enough that a card with one long name
       beside a short one does not read as two different type sizes. `anywhere` is the last
       resort under it: a name that still will not fit breaks rather than being cut, and the
       two-line clamp already has room for the second line. */
    .ta-pitch-line.name.pp-name-fit { font-size: 0.84em; letter-spacing: -0.01em; overflow-wrap: anywhere; }
/* S2 QA repair — the extraction's comment-blind brace walker split a page comment
   here and SWALLOWED this rule into it (the owner's mobile find: with the badge
   base rule gone, the crest painted face-sized over the face and the price).
   Restored verbatim; comments in this sheet stay BRACE-FREE so a walker can
   never desync on quoted rule text again. */
.pp-price-badge { display: none; position: absolute; bottom: 2px; left: 50%; transform: translateX(-50%);
      background: rgba(15,23,42,0.86); color: #fff; font-size: 0.6rem; font-weight: 800; padding: 1px 5px; border-radius: 6px;
      white-space: nowrap; line-height: 1.15; pointer-events: none; border: 1px solid rgba(255,255,255,0.28); z-index: 2; }
/* PA-V6 — the badge hangs OFF the shirt's leading corner rather than sitting on
       it. WC's identical badge is placed inside the shirt at top-left, which is
       correct there because WC renders a KIT graphic; FPL publishes head-and-shoulders
       headshots cropped `object-position: top center`, so WC's placement lands the
       chip squarely on the player's head. The shirt therefore stops clipping its own
       children, and the image carries the rounding the shirt's overflow used to give it. */
    .ta-role-badge { position: absolute; top: -6px; inset-inline-start: -6px; min-width: 20px; height: 22px; padding: 0 6px; border-radius: 999px;
      display: grid; place-items: center; font-size: 0.76rem; font-weight: 900; line-height: 1; border: 1px solid rgba(71,85,105,0.4);
      box-shadow: 0 2px 6px rgba(0,0,0,0.3); z-index: 3; }
.ta-role-badge.captain { color: #4a2f00; background: linear-gradient(180deg,#fef08a 0%,#f59e0b 100%); border-color: rgba(146,64,14,0.35); }
.ta-role-badge.vice { color: #f8fafc; background: linear-gradient(180deg,#334155 0%,#1e293b 100%); border-color: rgba(148,163,184,0.45);
      letter-spacing: -0.02em; transform: scale(0.85); transform-origin: top left; }
.ta-role-badge.captain.cap-triple { color: #fff; background: linear-gradient(180deg,#c4b5fd 0%,#6d28d9 100%); border-color: rgba(76,29,149,0.6); }
.ta-role-badge .cap-coin { position: absolute; top: -5px; right: -5px; width: 14px; height: 14px; border-radius: 50%;
      background: #0f172a; color: #fde68a; border: 1px solid #fde68a; font-size: 0.58rem; font-weight: 900; line-height: 1;
      display: grid; place-items: center; z-index: 4; }
@media (prefers-reduced-motion: reduce) {
  .chip-electric, .pp-bench-row.pp-bench-boosted { animation: none; box-shadow: 0 0 0 2px #fde68a, 0 0 12px 3px rgba(125,211,252,0.6); }
}
.ta-pitch-player.pp-locked .ta-pitch-shirt, .pp-bench-player.pp-locked .pp-bench-shirt { box-shadow: 0 0 0 2px rgba(251,191,36,.85), 0 0 12px rgba(251,191,36,.28); }
.ta-pitch-player.pp-swap-source .ta-pitch-shirt { box-shadow: 0 0 0 3px var(--vc-accent), 0 0 12px rgba(219,181,128,.4); }
.ta-pitch-player.pp-swap-target .ta-pitch-shirt { box-shadow: 0 0 0 3px var(--vc-green), 0 0 12px rgba(95,217,122,.3); }
.ta-pitch-player.pp-swap-invalid { opacity: .28; pointer-events: none; }
.pp-bench-player.pp-swap-source .pp-bench-shirt { box-shadow: 0 0 0 3px var(--vc-accent); }
.pp-bench-player.pp-swap-target .pp-bench-shirt { box-shadow: 0 0 0 3px var(--vc-green); }
.pp-bench-player.pp-swap-invalid { opacity: .28; pointer-events: none; }
.ta-pitch-player.pp-new-in .ta-pitch-shirt, .pp-bench-player.pp-new-in .pp-bench-shirt { box-shadow: 0 0 0 4px #f59e0b, 0 0 18px rgba(245,158,11,.38); }
/* ── empty slot (removed player awaiting a replacement) ── */
    .pp-empty .ta-pitch-shirt, .pp-empty .pp-bench-shirt { background: rgba(148,163,184,.08); border: 2px dashed rgba(203,213,225,.5); cursor: pointer; }
.pp-empty .ta-pitch-shirt:hover, .pp-empty .pp-bench-shirt:hover { border-color: var(--vc-accent); background: rgba(219,181,128,.12); }
.pp-empty.pp-empty-shake .ta-pitch-shirt, .pp-empty.pp-empty-shake .pp-bench-shirt { border-color: var(--vc-red); background: rgba(255,82,82,.14); }
.pp-bench-row { display: flex; gap: 12px; flex-wrap: wrap; justify-content: center; }
.pp-bench-row.pp-bench-boosted { border-radius: 14px; padding: 12px 10px; background: rgba(125,211,252,.06); animation: chipElectric 1.25s ease-in-out infinite; }
.pp-bench-player { position: relative; text-align: center; width: 100px; cursor: pointer; }
.pp-bench-shirt { width: 52px; height: 52px; margin: 0 auto 5px; display: grid; place-items: center; border-radius: 12px;
      background: rgba(30,41,59,0.45); border: 1px solid rgba(255,255,255,0.18); overflow: visible; position: relative; }
.pp-bench-shirt-fallback { font-size: 24px; line-height: 1; }
/* ⚠ THE BENCH SLOT NUMBER LIVES IN THE GUTTER, NOT ON THE SHIRT. All four of the
       shirt's own corners are already spoken for - position pill top-start, suspension
       marker top-end, price chip bottom-center - and the card is 100px around a 52px
       avatar, so there are 24px of empty pitch either side of it doing nothing. The
       chip is pinned to the SHIRT (not the card) so it tracks the avatar's vertical
       centre instead of a magic offset measured off a card whose height changes with
       the lines box. Logical inset on purpose: this row renders RTL on the Hebrew
       pages, and a physical `left` here would pin the leading edge on one locale and
       the trailing edge on the other. */
    .pp-bench-num { position: absolute; top: 50%; inset-inline-start: -21px; transform: translateY(-50%);
      width: 18px; height: 18px; border-radius: 50%; display: grid; place-items: center;
      font-size: 0.62rem; font-weight: 900; line-height: 1; font-variant-numeric: tabular-nums;
      color: #dbe6f2; background: rgba(15,23,42,0.9); border: 1px solid rgba(255,255,255,0.3);
      z-index: 5; pointer-events: none; }
.pp-bench-lines { background: rgba(15,23,42,0.88); border: 1px solid rgba(255,255,255,0.25); border-radius: 10px; padding: 4px 5px 5px; display: grid; gap: 0; line-height: 1; }
@media (max-width: 768px) {
  /* My-Team bench wraps on a phone (5 boxes at 62px + gaps overflow 390) —
         the planner's nowrap row lives inside its own scroller, this one does not. */
      .ta-myteam-bench .pp-bench-row { flex-wrap: wrap; gap: 6px; }
  /* ⚠ THE CHIP LANE HAS TO BE RESTATED AT THIS SPECIFICITY FOR THE MY-TEAM BENCH.
     A consumer page carries its own two-class rule for this surface - the IPL
     analyzer sets .ta-myteam-bench .pp-bench-shirt with a 4px bottom margin -
     and two classes outrank the single-class .pp-bench-shirt lane rule below no
     matter what order the sheets load in. Without this line the lane opens on
     the pitch and the planner bench but NOT here, and the chip lands on the name
     box on exactly one surface. Matching the page's specificity and loading
     after it is what settles it. */
      .ta-myteam-bench .pp-bench-shirt { margin-bottom: 12px; }
  .ta-pitch-player { width: 62px; box-sizing: border-box; }
  /* ⚠ 46px, NOT 38 (owner: bigger faces on mobile). The card is 62px wide, so the
         face can take 46 and still leave 8px a side; height is what actually costs
         here — +8px per card against 4 pitch rows — and the pitch is 600px tall at this
         width with the rows placed by percentage, so they absorb it. The 11px radius
         the headshot rule applies still reads as a rounded square at this size. */
  /* ⚠ THE 12px BOTTOM MARGIN IS THE PRICE CHIP'S LANE, NOT SPACING (owner pick,
     2026-08-08 - option 4 of six). The chip is 52.5px wide on a 46px avatar and
     the seam between avatar and name box was 2px, so the chip HAD to overlap
     something: it grazed the face by 9.7px and the name by 3. Shrinking it or
     moving it onto the face were the alternatives; the owner bought it its own
     strip of card instead. 2px to 12px opens the lane, the badge rule drops into
     it, and the name box stops being touched at all. Costs 10px of card height -
     the pitch rows are placed by PERCENTAGE of a fixed-height pitch, so this is
     paid for out of the gap between rows, not by the pitch growing. See the
     .pp-price-badge and .pp-bench-shirt rules below - all three move together. */
      .ta-pitch-shirt { width: 46px; height: 46px; margin: 0 auto 12px; border-radius: 9px; }
  .ta-pitch-shirt-fallback { font-size: 23px; }
  /* Same reasoning as the desktop rule — min-height, not a pinned two rows. This is
         the width where the 3.5% that genuinely wrap live, and they still get their
         second line from the clamp; the other 96.5% stop reserving one. */
      /* ⚠ REVERTED. Bumping these to 0.72/0.62/0.95rem truncated the longer names and
         squeezed the club crest out of the row — the 62px card has no slack, and the
         readability win came out of the content. The room for bigger touch targets came
         from REMOVING buttons, not from the text. */
      /* Same clipped-ascender fix as the desktop rule (see its note): 1.04 gave the
         0.6rem name a 9.97px box around 11px of content, so every card lost the top
         of its tall letters. Sized to THIS font-size, not copied from desktop. */
      .ta-pitch-line.name { font-size: 0.6rem; min-height: 1.2em; line-height: 1.2; }
  /* And the row under it, for the same reason: at 1.1 the meta box measured 10.14px
     around 11px of content. It matters more in the clean view, where the fixture IS
     the second of only two lines. */
  .ta-pitch-line.meta { font-size: 0.52rem; line-height: 1.35; }
  .ta-pitch-line.points { font-size: 0.8rem; }
  /* ⚠ THE 4px SIDE PADDING WAS COSTING 8px OF NAME. A 62px card leaves 52px for the
         name row, and the longest names ran 2-7px over even after the crest moved out to
         the price pill. Trimming the sides to 1px buys 6px back — cheaper than shrinking
         the text, which is the thing that was just put back at the owner's request. */
      .ta-pitch-lines { padding: 2px 1px 3px; border-radius: 8px; }
  /* ⚠ `inset-inline-start`, NOT `left` — this is why the armband looked "huge".
         The base rule pins the badge with the LOGICAL `inset-inline-start: -6px`, which on
         an RTL page is the RIGHT edge. This override used the PHYSICAL `left`, so both
         edges ended up pinned and an absolutely-positioned box with two insets STRETCHES:
         measured 40px wide on a 38px shirt, i.e. the "C" pill spanned the whole player.
         It read as a styling choice and was a units mismatch. Logical on both sides now,
         so the badge is content-width (~13px) wherever the page's direction points. */
      .ta-role-badge { min-width: 13px; height: 14px; font-size: 0.5rem; padding: 0 3px; top: 2px; inset-inline-start: 2px; }
  .pp-bench-row { gap: 6px; flex-wrap: nowrap; }
  .pp-bench-player { width: 62px; }
  /* ⚠ THE BENCH NEEDS THE SAME LANE, AND THIS RULE IS WHY. One card builder
     renders both surfaces - planner-cards.js gives a bench card BOTH classes,
     so it already took .ta-pitch-shirt's 46px above - but this rule re-declares
     the margin AFTER it and therefore wins on the bench. Move the pitch rule
     alone and the bench chip keeps grazing exactly as before. */
  .pp-bench-shirt { width: 46px; height: 46px; margin: 0 auto 12px; }
  /* 62px card around a 46px avatar leaves an 8px gutter, so the chip shrinks to
     fit it rather than hanging off the card and getting clipped by the row's
     scroller: -8px + 13px lands its trailing edge 5px onto the avatar's rim,
     clear of the pill above it and the price chip below. */
  .pp-bench-num { inset-inline-start: -8px; width: 13px; height: 13px; font-size: 0.5rem; }
  .pp-bench-shirt-fallback { font-size: 19px; }
  /* The bench card is the same 62px and carries the same names — it needs the same
         side-padding trim, or the longest names ellipsise on the bench only. */
      .pp-bench-lines { padding: 2px 1px 3px; border-radius: 7px; }
  /* ⚠ STRADDLE THE SHIRT'S BOTTOM EDGE, do not sit inside it. WC keeps this chip fully
         inside the shirt (wc:1102), which is right THERE because WC draws a kit graphic —
         there is no face to cover. FPL publishes head-and-shoulders headshots cropped
         `object-position: top center`, so the same placement landed a 32x15 chip over the
         player's chin: measured 33% of a 38x38 shirt. Exactly the reasoning PA-V6 already
         applied to the role badge one rule up. Dropped to the boundary and shrunk to WC's
         0.54rem, it covers ~12% and clears the face entirely; the shirt is
         `overflow: visible` (see the base rule) so nothing clips it. */
      /* ⚠ THE CREST MOVES INTO THE PILL (owner). In a 62px box the name row was spending
         ~13px on a crest before a single letter; the pill has room beside the price and is
         already the thing the eye lands on. The pill widens to hold both. */
      /* ⚠ `direction: ltr` PINS THE ORDER IN BOTH LOCALES (owner: price left, crest right).
         A flex row follows the page direction, so DOM order alone would put the crest left
         on /en and right on /he — and the pill's content is a Latin currency figure and a
         club badge, neither of which reads right-to-left. `space-between` keeps the price
         against the leading edge if the pill is ever wider than its content. */
      /* ⚠ THE PILL IS ALWAYS THE TOP LAYER OF THE CARD (owner QA, 2026-08-08).
         At this width the meta-line price is hidden, so this chip IS the price:
         it hangs off the avatar's bottom edge and is deliberately a few px wider
         than the 44px avatar. That only reads as a chip if it paints above BOTH
         the face image and the name box below it — otherwise the overhang looks
         like something peeking out from behind the photo. `z-index` states it
         rather than relying on paint order (the name box is static today, but a
         future `position` on it would silently bury this). */
      /* ⚠ -13px DROPS THE CHIP INTO THE LANE the shirt margin just opened. It is
         measured off the avatar's bottom edge, so with a 12px lane below it the
         chip clears the face almost entirely and never reaches the name box.
         Overhanging the avatar SIDEWAYS by ~3px each side is expected and kept -
         the chip carries a price and a club crest and is genuinely wider than
         46px; that overhang is over pitch, not over content. */
      .pp-price-badge { display: inline-flex; align-items: center; justify-content: space-between;
        direction: ltr; gap: 4px; bottom: -13px; font-size: 0.58rem; padding: 1px 6px;
        z-index: 6; box-shadow: 0 2px 6px rgba(0,0,0,0.45); }
  .ta-pitch-line.name .pp-name-crest { display: none; }
  /* Ported from the WC golden (wc:1687), which PL had missed: with the price badge
         on the shirt, repeating it in the meta line printed the price TWICE at 390 and
         pushed the club off the end of a nowrap+ellipsis row. Dropping it here is what
         the pp-price-badge comment already claimed happened. */
      .pp-meta-price { display: none; }
  .pp-pts-unit { display: inline; }
  /* ⚠ THE VIEWED GAMEWEEK IS ALREADY THE HEADLINE (owner, 2026-08-08). Its chip
     repeats the big number two lines above, and at this width the third chip
     wraps onto a SECOND ROW — a whole row of card height spent on a duplicate.
     Dropping it leaves the two rounds the user cannot already see, on one row.
     Only pages that pass `viewed` (a per-GW headline) are affected; the IPL
     strip sits under a summary and keeps every chip. */
  .pp-gw-chip-viewed { display: none; }
  /* ⚠ THE TAB PILL TUCKS AWAY ON THE WAY DOWN (owner, 2026-08-08). The class is
     driven by VcPlannerCards.installTabBarAutoHide - see the long WHY there.
     translate, not `display`, so the pill keeps its layout box and slides; the
     percentage is off its OWN height, so it clears the safe-area offset without
     this rule having to know what that offset is. pointer-events off while it is
     gone, or a tucked pill still swallows taps meant for the bench under it. */
  /* ⚠ MATCHED ON `.ta-tab-sw` ALONE, deliberately: the two planners gate the SAME
     pill with DIFFERENT classes - PL shows it with `.on`, IPL keeps it always-on
     and marks it `.ta-tab-sw-docked` when it reparents to body on mobile. A rule
     written against either one silently covers one league only, which is exactly
     how the first version of this shipped working on PL and dead on IPL. */
  .ta-tab-sw { transition: transform 0.22s ease, opacity 0.22s ease; }
  .ta-tab-sw.ta-tab-sw-tucked { transform: translateY(150%); opacity: 0; pointer-events: none; }
}
@media (max-width: 768px) and (prefers-reduced-motion: reduce) {
  /* Same outcome, no travel - the pill still gets out of the way. */
  .ta-tab-sw { transition: none; }
}

/* ── CLEAN VIEW - the same card with the numbers taken off it ────────────────
   Owner, 2026-08-17. A second way to read the pitch, on all four planners
   (PL x FPL, PL x 9 Fantasy, IPL x Sport5, IPL x 9cat) and on both tabs of
   each. The clean card keeps only what identifies a player and what a build
   decision needs - NAME + CREST, OPPONENT, PRICE - and drops the points line
   and the EO line with it.

   IT IS A SKIN, NOT A SECOND CARD. planner-cards.js renders the SAME markup in
   both modes; the switch is one class on the document root
   (VcPlannerCards.installDensityToggle). Nothing re-renders, no page state is
   rebuilt, and with the class absent the card is byte-identical to the one the
   visual gate holds at 0.000%.

   THE CONTROL IS DELIBERATELY SMALL AND QUIET (owner, 2026-08-18). It wore the
   site's gold segmented capsule at first, up with the tab strip - and it read as
   a second navigation choice, competing with the GAME toggle two rows above it
   for the same kind of attention. It is not that: it is a preference about the
   thing directly under it. So it sits against the pitch it governs, one per
   pitch, in a hairline group at 0.7rem - the `.horizon-toggle` idiom the PL page
   already uses for its own small in-page switches, declared here so both pages
   share one copy.

   WHY `!important` ON THE GEOMETRY AND NOWHERE ELSE. Both pages carry
   ID-SCOPED skin rules for these exact boxes (`#pPitch .ta-pitch-shirt`,
   `#taPitch ...`), and an id outranks any class scope a shared sheet can
   write - a plain `.vc-cards-clean .ta-pitch-shirt` is silently a no-op on
   the IPL planner pitch. The two dropped lines need no such thing: nothing
   else on either page declares `display` for them. */
/* Sits on the pitch's leading edge - the side the eye starts from in either
   direction, and the side both pitches leave empty above their first row. */
.ta-view-sw { position: relative; display: flex; align-items: center; justify-content: flex-start; gap: 6px; margin: 0 0 6px; }
/* Names the control without competing with it - the same size as the pills it
   labels, one step down in weight and colour. */
.ta-view-label { font-size: 0.7rem; font-weight: 600; color: var(--vc-text-sub); line-height: 1.5; }
.ta-view-sw-group { display: inline-flex; border: 1px solid var(--vc-border); border-radius: 7px; overflow: hidden; background: transparent; }
.ta-view-btn {
  appearance: none; background: transparent; border: 0; color: var(--vc-text-sub);
  font-family: inherit; font-size: 0.7rem; font-weight: 700; line-height: 1.5;
  padding: 3px 10px; cursor: pointer; transition: color .12s, background .12s;
}
.ta-view-btn + .ta-view-btn { border-inline-start: 1px solid var(--vc-border); }
.ta-view-btn:hover:not(.is-on) { color: var(--vc-text); }
.ta-view-btn.is-on { background: var(--vc-surface2); color: var(--vc-text); }
.ta-view-btn:focus-visible { outline: 2px solid var(--vc-accent); outline-offset: -2px; }

/* ── the first-visit nudge ────────────────────────────────────────────────────
   Shown once, to someone who has never used the switch, and retired the moment
   they do (see the long WHY in planner-cards.js). It hangs BELOW the control,
   over the top of the pitch it is talking about, rather than above it where the
   page's own furniture already lives - and it is anchored to `.ta-view-sw`,
   whose ancestor chain on all three surfaces is `overflow: visible` end to end
   (checked, 2026-08-18: vc-card / ta-grid / vc-main / body). `pointer-events`
   stay on so the × is clickable, but the bubble is 30px tall and sits over
   pitch, not over a card. */
.ta-view-hint {
  position: absolute; top: calc(100% + 8px); inset-inline-start: 0; z-index: 6;
  display: flex; align-items: center; gap: 8px;
  max-width: min(280px, 78vw); padding: 6px 8px 6px 10px;
  border: 1px solid var(--vc-accent); border-radius: 8px;
  background: var(--vc-surface); color: var(--vc-text);
  font-size: 0.72rem; font-weight: 700; line-height: 1.35; text-align: start;
  box-shadow: 0 6px 18px rgba(0,0,0,.35);
  animation: vcViewHintIn .2s ease-out both;
}
/* The caret, pointing back up at the control that owns it. Two stacked
   triangles - border then fill - so it reads as part of the bordered bubble
   instead of a floating shape. */
.ta-view-hint::before,
.ta-view-hint::after {
  content: ''; position: absolute; bottom: 100%; inset-inline-start: 14px;
  border: 6px solid transparent;
}
.ta-view-hint::before { border-bottom-color: var(--vc-accent); }
.ta-view-hint::after { border-bottom-color: var(--vc-surface); margin-bottom: -1px; }
.ta-view-hint-txt { min-width: 0; }
.ta-view-hint-x {
  appearance: none; background: transparent; border: 0; cursor: pointer;
  color: var(--vc-text-sub); font-family: inherit; font-size: 0.95rem; font-weight: 700;
  line-height: 1; padding: 2px 4px; margin-inline-start: auto; border-radius: 5px;
}
.ta-view-hint-x:hover { color: var(--vc-text); }
.ta-view-hint-x:focus-visible { outline: 2px solid var(--vc-accent); outline-offset: 1px; }
@keyframes vcViewHintIn { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) { .ta-view-hint { animation: none; } }

.vc-cards-clean .ta-pitch-line.points,
.vc-cards-clean .ta-pitch-line.eo { display: none; }
/* The planner card carries a SECOND projection surface the My-Team card does
   not: gw-badges' per-round chip strip (xPts per gameweek, or the fixture run
   for a free viewer). It is the densest thing on the card, so a clean view that
   left it standing would not be one. `!important` because the module inline-
   styles the strip `display: flex` so it renders identically wherever it is
   dropped - an inline declaration is unreachable from a stylesheet otherwise. */
.vc-cards-clean .pp-gw-strip { display: none !important; }
/* The freed height goes back into the FACE. Two rows of type off a four-row
   card is ~24px, so a 16px bigger avatar still leaves the card SHORTER than the
   detailed one - the pitch rows are placed by percentage, so what is bought
   here is paid for out of the card, not out of the pitch. */
.vc-cards-clean .ta-pitch-shirt,
.vc-cards-clean .pp-bench-shirt { width: 68px !important; height: 68px !important; border-radius: 14px !important; }
/* Two lines in a box sized for four read as a label stuck to the bottom of the
   face - the padding is what makes the remaining pair look deliberate. */
.vc-cards-clean .ta-pitch-lines,
.vc-cards-clean .pp-bench-lines { padding: 6px 7px 7px !important; }
/* The bench is a flow row, so its own gap is the only spacing it has. */
.vc-cards-clean .pp-bench-row { gap: 18px; }
/* The legend explains a percentage this mode does not show. */
.vc-cards-clean .ta-pitch-eo-legend { display: none; }

@media (max-width: 768px) {
  /* 54px on a 62px card leaves 4px a side - the same trade the 46px default
     makes, one step up because two rows of type have gone. The 12px chip lane
     below the avatar (see the long note on the default rule) is untouched:
     the price chip still needs its own strip of card. */
  .vc-cards-clean .ta-pitch-shirt,
  .vc-cards-clean .pp-bench-shirt { width: 54px !important; height: 54px !important; border-radius: 11px !important; }
  .vc-cards-clean .ta-pitch-lines,
  .vc-cards-clean .pp-bench-lines { padding: 3px 2px 4px !important; }
  /* The phone bench is a nowrap scroller, not a wrapping row - a desktop-sized
     gap there costs a whole card of visible width. */
  .vc-cards-clean .pp-bench-row { gap: 8px; }
}

/* ── 9 FANTASY CONNECT (shared/ninecat-connect.js) ──────────────────────────
   The connector reuses the pages' existing .ta-card / .ta-connect-* furniture,
   so what is left here is only what it ADDS: the how-to list, the challenge
   target, and the two message tones. Both planner pages load this sheet, which
   is why the rules live here rather than twice inline. */
.nc-connect .nc-howto {
  margin: 12px 0 0;
  padding: 12px 14px;
  border-radius: 10px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.07);
}
.nc-connect .nc-howto h4 {
  margin: 0 0 6px;
  font-size: 0.9rem;
  font-weight: 800;
  color: var(--vc-text);
}
.nc-connect .nc-howto ol {
  margin: 0;
  padding-inline-start: 20px;
  color: var(--vc-text-sub);
  font-size: 0.88rem;
  line-height: 1.65;
}
.nc-connect .nc-howto li + li { margin-top: 2px; }
/* The challenge target is the ONE piece of the squad shown before ownership is
   proven, and the whole instruction turns on reading it correctly. */
.nc-connect .nc-target {
  color: var(--vc-accent);
  font-weight: 800;
  white-space: nowrap;
}
.nc-connect .nc-error,
.nc-connect .nc-warn {
  margin: 10px 0 0;
  padding: 8px 10px;
  border-radius: 8px;
  font-size: 0.86rem;
  line-height: 1.5;
}
/* "Not yet" is the expected state while the user is off in 9 Fantasy doing what
   we asked, so it must not read as a failure. */
.nc-connect .nc-error {
  background: rgba(255, 176, 32, 0.10);
  border: 1px solid rgba(255, 176, 32, 0.28);
  color: var(--vc-text);
}
.nc-connect .nc-warn {
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.10);
  color: var(--vc-text-sub);
}
.nc-connect .ta-connect-form input { flex: 1 1 auto; min-width: 0; }
@media (max-width: 768px) {
  .nc-connect .nc-howto { padding: 10px 12px; }
  .nc-connect .nc-howto ol { font-size: 0.84rem; }
}

/* The connect SHELL, for pages that do not already declare it inline.
   The PL planner has carried `.ta-connect-*` page-locally since PA-P1; the IPL
   planner never needed it, because until now it had nothing to connect. Rather
   than move PL's block (and repaint a surface this change has no business
   touching), these are scoped to `.nc-connect` — the connector's own root — so
   they reach the IPL page and are a no-op wherever the page already styles it.
   Values are PL's, deliberately: one connect card, two pages. */
/* ...AND THE CARD FRAME WITH THEM. The module emits `.ta-card.ta-connect`, but
   `.ta-card` is declared page-locally on pl/team-analyzer.html ONLY — the IPL page
   names its cards `.vc-card`. So the identical connector rendered there with no
   border, no background and no radius: a stack of text and buttons floating on the
   page. The four properties below are PL's `.ta-card` values verbatim, which is what
   makes this a no-op on the page that already has them. */
/* ⚠ THE TOP MARGIN IS LOAD-BEARING (owner, 2026-08-22). Inside `.ta-grid` a card's
   own bottom margin is reset to 0 and this card sits OUTSIDE the grid, so it landed
   flush under the bench — reading as one more row of the squad rather than a separate
   set of actions. 24px clears the grid's own 14px gap so the seam is unmistakable. */
.nc-connect.ta-connect { max-width: 560px; margin: 24px auto 18px; text-align: center; padding: 22px 18px;
  background: var(--vc-surface); border: 1px solid var(--vc-border); border-radius: 14px; }
.nc-connect .ta-connect-title { margin: 0 0 8px; font-size: 1.05rem; font-weight: 800; color: var(--vc-text); }
.nc-connect .ta-connect-body { margin: 0 0 14px; color: var(--vc-text-sub); font-size: 0.92rem; line-height: 1.55; }
.nc-connect .ta-connect-note { margin: 12px 0 0; color: var(--vc-text-muted, var(--vc-text-sub)); font-size: 0.82rem; line-height: 1.6; }
.nc-connect .ta-connect-form { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.nc-connect .ta-connect-form input {
  padding: 10px 14px; border-radius: 8px; border: 1px solid var(--vc-border);
  background: var(--vc-surface); color: var(--vc-text); font-family: inherit;
  font-size: 1rem; min-width: 200px; flex: 1 1 260px;
}
/* The paste path is the SECOND way in (join-capture is the headline), so its
   submit is bordered rather than filled — one gold button per screen, and it is
   the one above the "או". */
.nc-connect .ta-connect-form button {
  padding: 10px 20px; border-radius: 8px; border: 1px solid var(--vc-border);
  background: transparent; color: var(--vc-accent); font-weight: 800;
  font-size: 0.95rem; cursor: pointer;
}
.nc-connect .ta-connect-form button:hover { border-color: var(--vc-accent); }
.nc-connect .ta-connect-form button[disabled] { opacity: 0.6; cursor: default; }
.nc-connect .ta-connect-team {
  display: flex; align-items: baseline; justify-content: center; flex-wrap: wrap; gap: 8px;
  margin: 0 0 10px; font-weight: 800; font-size: 1.12rem; color: var(--vc-accent);
}
.nc-connect .ta-connect-actions { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; }
.nc-connect .ta-connect-btn {
  background: transparent; color: var(--vc-accent); border: 1px solid var(--vc-border);
  border-radius: 8px; padding: 7px 14px; font-size: 0.85rem; font-weight: 700;
  cursor: pointer; white-space: nowrap; text-decoration: none; display: inline-block;
}
.nc-connect .ta-connect-btn:hover { border-color: var(--vc-accent); }
.nc-connect .ta-connect-btn.primary { background: var(--vc-accent); color: var(--vc-surface); border-color: var(--vc-accent); }
/* The how-to is a left-to-right instruction list inside a right-to-left page;
   the list MARKERS have to follow the text or they detach from their steps. */
.nc-connect .nc-howto ol { text-align: start; }

/* The league member list — how a 9 Fantasy user identifies themselves, since the
   game shows them no id of their own. Names only; a tap starts the ownership
   challenge. Bounded and scrollable: a league can be 100 rows. */
.nc-connect .nc-pick-list { max-height: 260px; overflow-y: auto; margin: 10px 0 0; border: 1px solid var(--vc-border); border-radius: 10px; }
.nc-connect .nc-pick-row {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; padding: 9px 12px; background: transparent; border: 0;
  border-bottom: 1px solid rgba(255,255,255,.05); color: var(--vc-text);
  font-family: inherit; font-size: 0.9rem; font-weight: 700; cursor: pointer; text-align: start;
}
.nc-connect .nc-pick-row:last-child { border-bottom: 0; }
.nc-connect .nc-pick-row:hover { background: rgba(255,255,255,.05); color: var(--vc-accent); }
.nc-connect .nc-pick-rank { color: var(--vc-text-sub); font-weight: 700; font-size: 0.8rem; }

/* ── JOIN-CAPTURE ───────────────────────────────────────────────────────────
   The ask screen now offers two ways in, so the second one needs a visible
   demotion — otherwise the paste box reads as the instruction and the headline
   path reads as decoration. */
.nc-connect .nc-or {
  display: flex; align-items: center; gap: 10px;
  margin: 14px 0 10px; text-align: start;
}
.nc-connect .nc-or::before,
.nc-connect .nc-or::after { content: ''; flex: 1 1 auto; height: 1px; background: var(--vc-border); }
/* The invite code is meant to be READ OFF THE SCREEN and typed into another app,
   so it is monospaced, spaced out, and selectable as a unit. */
.nc-connect .nc-code {
  display: inline-block; font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-weight: 800; letter-spacing: 0.12em; color: var(--vc-accent);
  background: rgba(255, 255, 255, 0.05); border: 1px solid var(--vc-border);
  border-radius: 6px; padding: 2px 8px; user-select: all; direction: ltr;
}
/* An inline "do this instead" inside a sentence — a button because it acts, but
   it must not read as a third competing CTA next to the two real buttons. */
.nc-connect .nc-already { margin-top: 10px; }
.nc-connect .nc-linkbtn {
  background: transparent; border: 0; padding: 0; cursor: pointer;
  color: var(--vc-accent); font-family: inherit; font-size: inherit;
  font-weight: 700; text-decoration: underline;
}
.nc-connect .nc-linkbtn:hover { text-decoration: none; }
.nc-connect .nc-linkbtn[disabled] { opacity: 0.6; cursor: default; }
.nc-connect .nc-copy {
  background: transparent; border: 0; padding: 2px 4px; cursor: pointer;
  color: var(--vc-text-sub); font-family: inherit; font-size: 0.8rem;
  font-weight: 700; text-decoration: underline;
}
.nc-connect .nc-copy:hover { color: var(--vc-accent); }

/* ═══════════════════════════════════════════════════════════════════════════
   THE CORNER CONTROLS ON THE PLANNER PITCH — ONE CONTROL, FOUR CORNERS
   (owner, 2026-08-24: "make all 4 corner pitch planner buttons in all pl and
   ipl the same size and not overflowing anything".)

   WHY THIS MOVED HERE. Each page grew its own copy and they drifted into four
   different controls. Measured on the shipped pages before this block existed:

     control    PL @390        PL @1280      IPL @390        IPL @1280
     preset     91×23  50%−62  134×37 50%−72  91×23           134×37
     chips      66×22  50%−62   87×31 50%−72  66×56 (a BOX)    92×30
     reset      62×26  50%−14   83×36 50%−14  62×26            83×36
     optimise  129×22  50%−10  167×31 50%−14  66×56 (a BOX)   141×30

   Three separate defects fall out of that table:
     • the optimise GROUP capped at `50% − 10px` while its three siblings capped
       at `50% − 62px`, so at 390 it grew to 129px and sat 48px ON TOP of the
       forward card — the reported bug, and 59px at 360;
     • IPL's two `.pp-pitch-ctrl` buttons were still the legacy 66×56 BOX on a
       phone, because the pill-shape override lived inside a `min-width: 769px`
       block and the mobile rule cleared padding/font but never the width/height;
     • four different heights on every viewport.

   ⚠ THE OVERLAP IS VERTICAL, SO NO WIDTH CAP COULD HAVE FIXED IT. The mobile
   pitch was 640px and the forward row's card bottom landed at 623px, leaving
   17px under the last row for a pill that is 22–26px tall. `--pp-ctrl-band` is
   the answer: the pages reserve a strip at the FOOT of the pitch and grow the
   pitch by exactly that much, so the four rows keep the geometry they have
   always had (the span the percentages resolve against is unchanged) and the
   bottom pair sits in dead space no card can reach. Positions are emitted by
   the pages as `calc((100% - var(--pp-ctrl-band)) * P)`.

   Scoped to `#pPitch` — the PLANNER pitch. The My-Team pitch carries no corner
   controls and must not be touched (D4: the two tabs are different surfaces).
   Physical `left`/`right`, never logical: these controls deliberately do NOT
   mirror, so /he and /en agree — the rule the pages already stated twice.
   ═══════════════════════════════════════════════════════════════════════════ */
#pPitch { --pp-ctrl-band: 0px; }

#pPitch .pp-pitch-ctrl,
#pPitch .pp-pitch-reset,
#pPitch .pp-pitch-preset,
#pPitch .pp-ctrl-group {
  position: absolute; z-index: 4; box-sizing: border-box;
  display: inline-flex; flex-direction: row; align-items: center; justify-content: center;
  gap: 6px; width: auto; height: auto; min-height: 32px;
  padding: 6px 14px; border-radius: 999px;
  border: 1px solid var(--vc-accent); background: rgba(15, 23, 42, 0.82);
  color: var(--vc-accent); font-family: inherit; font-size: 0.8rem; font-weight: 700;
  line-height: 1.15; cursor: pointer; box-shadow: none;
  -webkit-backdrop-filter: blur(3px); backdrop-filter: blur(3px);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  /* ⚠ THE CAP IS A FUNCTION OF THE PITCH, NOT A FLAT PERCENT — every row's cards
     are CENTRED, so the free space beside a corner pill is (pitch − card)/2. 72px
     ≈ half a card plus a margin. ALL FOUR now share it; the two that did not are
     precisely the two that reached a card. */
  max-width: calc(50% - 72px);
  transform: none;
}
/* The four corners, on every viewport. (UCL ships three of them — no reset — and
   takes the same shape and the same three corners.) */
/* ⚠ `inset-inline` FIRST, THEN `left`/`right` — ORDER IS THE WHOLE RULE. A logical
   inset and a physical one that resolve to the same edge are settled by DECLARATION
   ORDER, not by which is more specific. Written the other way round (`left: 8px; …;
   inset-inline: auto`) the reset wins and every control falls back to auto insets, so
   all four stack at their static position in the top corner — measured: on desktop the
   reset and the optimise pill landed on top of each other in the same corner. The
   `inset-inline: auto` is still needed, because the rules being replaced positioned
   these logically and a stale `inset-inline-start` would otherwise survive under RTL. */
#pPitch .pp-pitch-preset { inset-inline: auto; top: 8px; bottom: auto; left: 8px; right: auto; }
#pPitch .pp-bonuses-btn  { inset-inline: auto; top: 8px; bottom: auto; left: auto; right: 8px; }
#pPitch .pp-pitch-reset  { inset-inline: auto; top: auto; bottom: 8px; left: 8px; right: auto; }
#pPitch .pp-optimize-btn,
#pPitch .pp-optimize-group { inset-inline: auto; top: auto; bottom: 8px; left: auto; right: 8px; }

#pPitch .pp-pitch-ctrl:hover:not(.pp-ctrl-disabled),
#pPitch .pp-pitch-reset:hover:not(:disabled),
#pPitch .pp-pitch-preset:hover:not(:disabled) { background: var(--vc-accent); color: #0b1622; border-color: var(--vc-accent); }
#pPitch .pp-pitch-ctrl:active:not(.pp-ctrl-disabled),
#pPitch .pp-pitch-reset:active:not(:disabled),
#pPitch .pp-pitch-preset:active:not(:disabled) { transform: scale(0.97); }
#pPitch .pp-ctrl-disabled { opacity: 0.45; cursor: not-allowed; }
#pPitch .pp-pitch-reset:disabled { opacity: 0.4; cursor: not-allowed; }
#pPitch .pp-pitch-preset:disabled { opacity: 0.55; cursor: progress; }
#pPitch .pp-ctrl-ic { flex-shrink: 0; }
/* One label, one line. IPL stacked its optimise label into two rows inside a box;
   in a pill it is a row like every other label, which is also what lets the four
   share a height. */
#pPitch .pp-ctrl-txt { display: inline-flex; flex-direction: row; gap: 4px; align-items: center; }
#pPitch .pp-pitch-reset-ic { font-size: 1.1rem; line-height: 1; }
#pPitch .pp-bonuses-btn.pp-bonuses-on { border-color: #fcd34d; color: #fcd34d; }
#pPitch .pp-bonuses-btn.pp-bonuses-on:hover:not(.pp-ctrl-disabled) { background: #fcd34d; color: #0b1622; }
#pPitch .pp-bonuses-badge {
  position: absolute; top: -7px; inset-inline-end: -7px; min-width: 17px; height: 17px; padding: 0 4px;
  display: grid; place-items: center; border-radius: 999px; background: #fcd34d;
  color: #3a2600; font-size: 0.62rem; font-weight: 900;
}
/* ⚠ THE GROUP CARRIES THE PILL — border, background, corner. Its children are
   borderless SEGMENTS, so the (i) reads as part of the control instead of a disc
   floating on top of it. It cannot be a CHILD of the action button: a disabled
   button swallows clicks on its own children, and a disabled control is exactly
   when "what does this do?" gets asked. */
#pPitch .pp-ctrl-group { padding: 0; gap: 0; align-items: stretch; overflow: hidden; }
#pPitch .pp-ctrl-group .pp-pitch-ctrl {
  position: static; border: none; background: transparent; border-radius: 0;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  max-width: none; min-width: 0; min-height: 0; box-shadow: none;
}
#pPitch .pp-ctrl-info {
  border: none; border-radius: 0; border-inline-start: 1px solid rgba(219, 181, 128, 0.45);
  background: transparent; color: var(--vc-accent); font-family: inherit; font-size: 0.78rem;
  font-weight: 800; font-style: italic; line-height: 1; cursor: pointer; padding: 0 11px;
  display: grid; place-items: center; flex: 0 0 auto;
}
#pPitch .pp-ctrl-info:hover { background: var(--vc-accent); color: #0b1622; }

@media (max-width: 768px) {
  #pPitch .pp-pitch-ctrl,
  #pPitch .pp-pitch-reset,
  #pPitch .pp-pitch-preset,
  #pPitch .pp-ctrl-group {
    min-height: 24px; padding: 3px 9px; font-size: 0.62rem; gap: 4px;
    /* ⚠ 44px, AND IT IS DERIVED, NOT PICKED. The pill starts 5px in from the pitch edge
       and must stop before the CENTRED card in its own band: that card's near edge is at
       (pitchW − 62)/2, i.e. 50% − 31px, so the pill may be 50% − 31 − 5 − gap. With an
       8px gap that is 50% − 44px. The old 62px was inherited from a desktop cap and cost
       ~18px the phone did not have to give: measured, it truncated "ספסל אופטימלי" on
       IPL at both 390 and 360 and "קבוצה בקליק" on UCL at 360. Nothing is bought back by
       being stingier — the BOTTOM pair now sits in `--pp-ctrl-band` where no card can
       reach it at all, so the keeper row is the only constraint left. */
    max-width: calc(50% - 44px);
  }
  #pPitch .pp-ctrl-group { padding: 0; }
  #pPitch .pp-ctrl-group .pp-pitch-ctrl { padding: 3px 9px; min-height: 0; }
  #pPitch .pp-ctrl-info { padding: 0 9px; font-size: 0.68rem; }
  #pPitch .pp-pitch-reset-ic { font-size: 0.9rem; }
  #pPitch .pp-pitch-preset { top: 5px; left: 5px; }
  #pPitch .pp-bonuses-btn  { top: 5px; right: 5px; }
  #pPitch .pp-pitch-reset  { bottom: 5px; left: 5px; }
  #pPitch .pp-optimize-btn,
  #pPitch .pp-optimize-group { bottom: 5px; right: 5px; }
}
