/* assets/ffa-ladder.css - THE NINE-RUNG LADDER, ONE SOURCE. Built 2026-09-06 (patch_ui1.py).
   HER ITEM 4: "The homepage ladder must be the exact same ladder as the Locker Room's."
   These rules were MOVED here out of locker.html (inline <style>, lines 956-989, 1014-1041,
   the 2026-08-15 dot-gradient <style>, and the .ladder-h override) and out of
   assets/ffm-locker-fix.css (items 17, 18, the 1024px stack, the z-index rules and the dot
   size). Nothing was copied, so /locker and / cannot drift apart. Both pages link this file.
   Cascade order inside the file is the order the rules had on the page. */

/* ---- from locker.html, inline style, 956-989 ---- */
.ladder{margin:6px auto 4px;max-width:980px;padding-bottom:26px;border-bottom:1px solid var(--cream-border);}  /* her order ~14:15: flattened */
/* her ruling 2026-08-21: the round heading BIGGER, so it can be seen */
.ladder-h{font:800 19px var(--ui);letter-spacing:.16em;text-transform:uppercase;color:var(--green-dark);text-align:center;margin-bottom:16px;}
.ladder-track{position:relative;}
.ladder-steps{position:relative;display:grid;grid-template-columns:repeat(6,1fr);gap:8px;}
/* HER ORDER 2026-09-03: the ladder stopped spilling off the right edge.
   MEASURED cause: `1fr` carries an automatic min-content floor, so the nine rung
   tracks grew to fit 'Club Champion' and '200 golf balls' and the grid ran 1021px
   inside a 960px box, pushing the golf-ball basket 60.7px past the edge.
   CORRECTED 2026-09-04 after she caught it on screen: equal minmax(0,1fr) tracks made
   'Club Champion' spill 9.4px into 'Board Member', because line 2973 pins every rung name
   to white-space:nowrap (her 'no orphans' rule, 2026-08-15) so they cannot wrap.
   MEASURED: the nine rungs need 1002px of content inside a 960px box, so 42px had to be
   found before proportional tracks could work. Taken from the gaps (6->3px, 27px) and one
   point of type on the three long names (16->15px, ~20px). Tracks now carry a min-content
   floor again, so each rung asks for exactly what its name and pill need and the leftover
   is shared. The basket keeps its own column beside rung nine. */
/* HER ORDER 2026-09-06 ~16:00: "Move the basket to the right, out of the way, so that the nine tiles of the
   front nine end exactly where the top pill band is." The basket no longer owns a tenth column: the nine rungs
   fill the track, edge to edge with the strip above, and the basket sits OUTSIDE the track on the right. */
.ladder-steps--nine{grid-template-columns:repeat(9,minmax(min-content,1fr));gap:3px;margin-top:22px;}
@media (min-width:1300px){
  .ladder-track{position:relative;}
  .ladder-steps--nine .ffa-bucket-wrap.L{position:absolute;left:100%;top:0;width:118px;margin-left:14px;}
}
/* MEASURED 2026-09-06 16:05 at 1100 wide: outside the track the basket fell off the screen (right edge 1155 on
   an 1100 viewport, sideways scroll). Where there is no room outside, it takes its own row under the rungs,
   flush with their right edge - still out of the way, still aligned. */
@media (min-width:1025px) and (max-width:1299px){
  .ladder-steps--nine .ffa-bucket-wrap.L{grid-column:1 / -1;justify-self:end;width:118px;margin-top:10px;}
}
/* THE THREE MEMBERSHIP TIERS, her ruling 2026-08-21: Junior, Elite, Legend over the
   rung groups. A faint band tint, a small label on each band's first rung, and the
   member's current tier reads at a glance (band-now, set by paintScore). No clutter. */
.lstep{position:relative;border-radius:0;text-align:center;} /* her order 2026-09-08: the pills sit centred under the rung on the homepage too */
.lstep.t1,.lstep.t2,.lstep.t3{background:rgba(47,122,60,.05);}
.lstep.t4,.lstep.t5,.lstep.t6{background:rgba(201,162,39,.07);}
.lstep.t7,.lstep.t8,.lstep.t9{background:rgba(168,132,42,.11);}
.lstep.t1,.lstep.t4,.lstep.t7{border-radius:12px 0 0 12px;}
.lstep.t3,.lstep.t6,.lstep.t9{border-radius:0 12px 12px 0;}
.lstep.t1::before,.lstep.t4::before,.lstep.t7::before{position:absolute;top:-19px;left:2px;font:800 10px var(--ui);letter-spacing:.22em;color:#b3ab97;white-space:nowrap;}
.lstep.t1::before{content:'JUNIOR';}
.lstep.t4::before{content:'ELITE';}
.lstep.t7::before{content:'LEGEND';}
.lstep.band-now.t1::before,.lstep.band-now.t4::before,.lstep.band-now.t7::before{color:var(--green);font-size:11px;}
@media (max-width:700px){.lstep.t1::before,.lstep.t4::before,.lstep.t7::before{top:-15px;}}
.ladder-line{right:12%;}

/* ---- from locker.html, inline style, 1014-1041 ---- */
.ladder-line{position:absolute;top:56px;left:5.5%;right:5.5%;height:7px;background:#3E9350;border-radius:4px;}
.lstep-mark{height:30px;display:flex;align-items:center;justify-content:center;position:relative;cursor:pointer;z-index:2;}
.lstep-dot{width:17px;height:17px;border-radius:50%;background:#EAE4D2;border:3px solid #F7F3E8;box-shadow:0 0 0 2px #CDC7B2;}.lstep.t1 .lstep-dot{background:#1F6FB2;box-shadow:0 0 0 2px #7FB3DC;}.lstep.t2 .lstep-dot{background:#2F7A3C;box-shadow:0 0 0 2px #8FC79A;}.lstep.t3 .lstep-dot{background:#C8871B;box-shadow:0 0 0 2px #EEC77A;}.lstep.t4 .lstep-dot{background:#C41E3A;box-shadow:0 0 0 2px #EC9AA8;}.lstep.t5 .lstep-dot{background:#7B2D8E;box-shadow:0 0 0 2px #C79AD4;}.lstep.t6 .lstep-dot{background:#0E7C86;box-shadow:0 0 0 2px #7FC4CA;}.lstep.t7 .lstep-dot{background:#B0532A;box-shadow:0 0 0 2px #E0A488;}.lstep.t8 .lstep-dot{background:#4A5568;box-shadow:0 0 0 2px #A7B2C2;}.lstep.t9 .lstep-dot{background:#1E5631;box-shadow:0 0 0 2px #D9A93C;}
.lstep.is-done .lstep-dot{background:#3E8E4E;box-shadow:0 0 0 1.5px #3E8E4E;}
.lstep-ball{width:29px;height:29px;border-radius:50%;background:#fff;border:2.5px solid var(--green);background-image:radial-gradient(circle, rgba(0,0,0,.08) 1.1px, transparent 1.3px);background-size:7px 7px;box-shadow:0 0 0 5px rgba(62,142,78,.15), 0 2px 8px rgba(47,122,60,.35);display:inline-flex;align-items:center;justify-content:center;font:800 12px var(--ui);color:#1f4d27;position:relative;z-index:2;transition:transform .5s ease;}
.lstep b{display:block;font:700 13.5px var(--ui);color:#8a8574;margin-top:10px;}
.lstep i{display:block;font-family:var(--serif);font-style:normal;font-size:12px;line-height:1.45;color:#6f6a5f;margin-top:3px;text-wrap:balance;}
.lpill{display:inline-block;font:800 10px var(--ui);letter-spacing:.02em;color:#fff;border-radius:20px;padding:3px 8px;margin-top:9px;border:1.5px solid transparent;white-space:nowrap;}
.lpill.p1{background:#1F6FB2;border-color:#7FB3DC;}
.lpill.p2{background:#2F7A3C;border-color:#8FC79A;}
.lpill.p3{background:#9d6608;border-color:#EEC77A;} /* 2026-09-15 Ruth: white text was 3.03:1 on #C8871B; now 4.84:1 (AA) */
.lpill.p4{background:#C41E3A;border-color:#EC9AA8;}
.lpill.p5{background:#7B2D8E;border-color:#C79AD4;}
.lpill.p6{background:#0E7C86;border-color:#7FC4CA;}
.lpill.p7{background:#B0532A;border-color:#E0A488;}
.lpill.p8{background:#4A5568;border-color:#A7B2C2;}
.lpill.p9{background:#1E5631;border-color:#D9A93C;}
.lstep-name{display:flex;align-items:flex-end;justify-content:center;min-height:38px;font-family:var(--display);font-weight:700;font-size:16px;line-height:1.15;color:var(--green-dark);margin:0 0 7px;text-wrap:balance;text-align:center;}
.lstep.is-now .lstep-name{color:#2a6b3c;} /* 2026-09-13: 4.27:1 on the band -> 5.19:1 (AA) */
.lstep-name.hof{color:#6f5614;} /* 2026-09-15 Ruth: was #A8926A, 2.24:1 on the band; now 5.19:1 (AA) */
.lstep.is-done b,.lstep.is-now b{color:var(--green-dark);}
.lstep.is-now b{color:var(--green);}
.lstep.is-done i,.lstep.is-now i{color:#6f6a5f;}
  .lstep em{display:block;font-family:var(--serif);font-style:italic;font-size:11.5px;line-height:1.4;color:#9a927f;margin-top:3px;text-wrap:balance;}

.lstep.is-done .lstep.is-done b,.lstep.is-now b{color:var(--green-dark);}
.lstep.is-now b{font-size:13.5px;}
.lstep.is-done i,.lstep.is-now i{color:#7c766a;}

/* ---- from locker.html, the 2026-08-15 dot-gradient <style> ---- */
/* ladder golf-ball dots 2026-08-15 */.ladder .ladder-steps .lstep .lstep-dot{background:#fff;background-image:radial-gradient(circle,rgba(0,0,0,.17) .7px,transparent 1.05px),radial-gradient(circle at 34% 28%,#ffffff 0 24%,#f7f5ec 58%,#e8e5d6 100%);background-size:4px 4px,100% 100%;border:3px solid #C9C3AE;box-shadow:0 1px 2px rgba(0,0,0,.16);}.ladder .ladder-steps .lstep.t1 .lstep-dot{background:#fff;background-image:radial-gradient(circle,rgba(0,0,0,.17) .7px,transparent 1.05px),radial-gradient(circle at 34% 28%,#ffffff 0 24%,#f7f5ec 58%,#e8e5d6 100%);background-size:4px 4px,100% 100%;border-color:#1F6FB2;box-shadow:0 1px 2px rgba(0,0,0,.16);}.ladder .ladder-steps .lstep.t2 .lstep-dot{background:#fff;background-image:radial-gradient(circle,rgba(0,0,0,.17) .7px,transparent 1.05px),radial-gradient(circle at 34% 28%,#ffffff 0 24%,#f7f5ec 58%,#e8e5d6 100%);background-size:4px 4px,100% 100%;border-color:#2F7A3C;box-shadow:0 1px 2px rgba(0,0,0,.16);}.ladder .ladder-steps .lstep.t3 .lstep-dot{background:#fff;background-image:radial-gradient(circle,rgba(0,0,0,.17) .7px,transparent 1.05px),radial-gradient(circle at 34% 28%,#ffffff 0 24%,#f7f5ec 58%,#e8e5d6 100%);background-size:4px 4px,100% 100%;border-color:#C8871B;box-shadow:0 1px 2px rgba(0,0,0,.16);}.ladder .ladder-steps .lstep.t4 .lstep-dot{background:#fff;background-image:radial-gradient(circle,rgba(0,0,0,.17) .7px,transparent 1.05px),radial-gradient(circle at 34% 28%,#ffffff 0 24%,#f7f5ec 58%,#e8e5d6 100%);background-size:4px 4px,100% 100%;border-color:#C41E3A;box-shadow:0 1px 2px rgba(0,0,0,.16);}.ladder .ladder-steps .lstep.t5 .lstep-dot{background:#fff;background-image:radial-gradient(circle,rgba(0,0,0,.17) .7px,transparent 1.05px),radial-gradient(circle at 34% 28%,#ffffff 0 24%,#f7f5ec 58%,#e8e5d6 100%);background-size:4px 4px,100% 100%;border-color:#7B2D8E;box-shadow:0 1px 2px rgba(0,0,0,.16);}.ladder .ladder-steps .lstep.t6 .lstep-dot{background:#fff;background-image:radial-gradient(circle,rgba(0,0,0,.17) .7px,transparent 1.05px),radial-gradient(circle at 34% 28%,#ffffff 0 24%,#f7f5ec 58%,#e8e5d6 100%);background-size:4px 4px,100% 100%;border-color:#0E7C86;box-shadow:0 1px 2px rgba(0,0,0,.16);}.ladder .ladder-steps .lstep.t7 .lstep-dot{background:#fff;background-image:radial-gradient(circle,rgba(0,0,0,.17) .7px,transparent 1.05px),radial-gradient(circle at 34% 28%,#ffffff 0 24%,#f7f5ec 58%,#e8e5d6 100%);background-size:4px 4px,100% 100%;border-color:#B0532A;box-shadow:0 1px 2px rgba(0,0,0,.16);}.ladder .ladder-steps .lstep.t8 .lstep-dot{background:#fff;background-image:radial-gradient(circle,rgba(0,0,0,.17) .7px,transparent 1.05px),radial-gradient(circle at 34% 28%,#ffffff 0 24%,#f7f5ec 58%,#e8e5d6 100%);background-size:4px 4px,100% 100%;border-color:#4A5568;box-shadow:0 1px 2px rgba(0,0,0,.16);}.ladder .ladder-steps .lstep.t9 .lstep-dot{background:#fff;background-image:radial-gradient(circle,rgba(0,0,0,.17) .7px,transparent 1.05px),radial-gradient(circle at 34% 28%,#ffffff 0 24%,#f7f5ec 58%,#e8e5d6 100%);background-size:4px 4px,100% 100%;border-color:#1E5631;box-shadow:0 1px 2px rgba(0,0,0,.16);}.ladder .ladder-steps .lstep.is-done .lstep-dot{background:#fff;background-image:radial-gradient(circle,rgba(0,0,0,.17) .7px,transparent 1.05px),radial-gradient(circle at 34% 28%,#ffffff 0 24%,#f7f5ec 58%,#e8e5d6 100%);background-size:4px 4px,100% 100%;border-color:#3E8E4E;box-shadow:0 1px 2px rgba(0,0,0,.16);}.ladder .lstep-mark{position:relative;}.ladder .lstep-mark .lstep-ball{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:3;}

/* ---- from assets/ffm-locker-fix.css ---- */
/* 17 — the through-line runs through the BALLS, not the titles (desktop) */
.ladder-line { top: 78px !important; }
.ladder-steps--nine { margin-top: 26px !important; }

@media (max-width: 1024px) {
  .ladder-track { overflow-x: visible !important; }
  .ladder-steps--nine {
    grid-template-columns: repeat(3, 1fr) !important;
    row-gap: 40px !important; margin-top: 30px !important;
  }
  .ladder-line { display: none !important; }
  .lstep-mark::before {
    content: ""; position: absolute; left: -10px; right: -10px; top: 50%;
    height: 6px; background: #3E9350; border-radius: 3px;
    transform: translateY(-50%); z-index: 0;
  }
  .lstep.t1 .lstep-mark::before, .lstep.t4 .lstep-mark::before,
  .lstep.t7 .lstep-mark::before { left: 8px; }
  .lstep.t3 .lstep-mark::before, .lstep.t6 .lstep-mark::before,
  .lstep.t9 .lstep-mark::before { right: 8px; }
  .ffa-bucket-wrap.L { grid-column: 1 / -1 !important; margin-top: 10px; }

}

/* 18 — tier group titles say Member */
.lstep.t1::before { content: 'JUNIOR MEMBER' !important; }
.lstep.t4::before { content: 'ELITE MEMBER' !important; }
.lstep.t7::before { content: 'LEGEND MEMBER' !important; }
/* HER ORDER 2026-08-24 — THE LINE RIDES BEHIND THE BALLS.
   Cause: .lstep-dot is position:static, so the absolutely-positioned line
   pseudo-element painted ON TOP of it. Lifting the ball into its own layer
   puts the line behind, where a ladder rail belongs. */
.lstep-dot { position: relative; z-index: 2; }
.ladder .lstep-mark .lstep-ball { z-index: 3; }
@media (max-width: 1024px) { .lstep-mark::before { z-index: 0; } }
/* 2026-09-04: she reported the through-line covering the ball markers again.
   It did NOT reproduce - checked in real WebKit on /locker at 393, 852, 768,
   1024 and 1180px: the dot carries z-index 2 and nothing covered it at any of
   them. The 2026-08-24 rule above was already doing its job. This line makes
   the rail's place explicit rather than relying on the dot out-ranking a
   z-index:auto sibling, so the invariant cannot drift back. No visual change. */
.ladder .ladder-line { z-index: 0; }

/* her order: thinner green band, slightly bigger ball */
.lstep-dot {
  width: 22px !important; height: 22px !important;
  border-width: 1.5px !important;
}

/* ---- from locker.html, the hye <style> ---- */
html body .ladder .ladder-h{margin-bottom:12px;}  /* her order ~14:15: flattened */

/* ===== HER ITEM 10, 2026-09-06: the band gradient stays but MORE PRONOUNCED, the three
   band labels CENTERED over their category and with MORE CONTRAST so they can be read.
   Measured before: tints .05/.07/.11 alpha, label #b3ab97 left-aligned on the first rung
   of each band (left:2px). Three rung columns + two 3px gaps = calc(300% + 6px). ===== */
.lstep.t1,.lstep.t2,.lstep.t3{background:rgba(47,122,60,.11);}
.lstep.t4,.lstep.t5,.lstep.t6{background:rgba(201,162,39,.16);}
.lstep.t7,.lstep.t8,.lstep.t9{background:rgba(168,132,42,.22);}
.lstep.t1::before,.lstep.t4::before,.lstep.t7::before{
  left:0;width:calc(300% + 6px);text-align:center;color:#5d5849;font-size:10.5px;letter-spacing:.2em;}
.lstep.band-now.t1::before,.lstep.band-now.t4::before,.lstep.band-now.t7::before{color:var(--green-dark);font-size:11.5px;}
@media (max-width:1024px){
  .lstep.t1::before,.lstep.t4::before,.lstep.t7::before{width:calc(300% + 6px);}
}

/* ===== HER ITEM 12, 2026-09-06: the crests become MINI crests in one row directly under the
   rung tiles, same grid as the rungs. Click one to pop it up big, and download from the
   pop-up. The old crest under "Open a locker" and the separate "Your crests" card are gone. */
/* HER ORDER 2026-09-06 ~12:55: "Put the emblem inside this space here in each of the tiles, and
   make the patch as large as you can so it can be seen clearly." The crest lives INSIDE its rung,
   under the pill, at the full inner width of the tile - the widest the tile allows, since the tile
   is 92px wide and 206px tall at 1440 and the crest is 4:3. Earned ones are full colour; the rest
   sit faint so the child can see what is coming. (The second row of tiles built a few minutes
   earlier is gone: "That looks terrible.") */
.lstep .lcrest{display:block;margin:10px 3px 6px;cursor:pointer;}
/* HER ORDER 2026-09-06 ~15:45: "Take away the square behind the emblem with rounded corners, but you can do
   some shadowing on the emblem." The square WAS this box-shadow on a square, transparent image. A drop-shadow
   follows the picture's own alpha, so it hugs the circle and nothing else. */
/* HER ORDER 2026-09-06 ~15:50: "Make all the emblems the size of the caddy emblem." MEASURED before: width:100%
   made each emblem follow its tile, and tiles with long names are wider - New Member 91px, Caddie 78, Club
   Champion 99, Board Member 94, the rest 78. Now every emblem is the Caddie size, 78px, centred in its tile. */
html body .ladder .lstep .lcrest img{width:78px;max-width:100%;height:auto;display:block;margin:0 auto;box-shadow:none;border-radius:0;background:none;filter:drop-shadow(0 2px 5px rgba(0,0,0,.22));}  /* her order ~15:45: no square, ever - whatever an older rule says */
/* her order 2026-09-06 ~16:55: 'Uncover the greyed-out emblems and make them all live' - no fade, no grey, pointer on all nine */
.lstep .lcrest.locked img{opacity:1;filter:drop-shadow(0 2px 5px rgba(0,0,0,.22));}
.lstep .lcrest.locked{cursor:pointer;}  /* her order ~14:00: grey patches do not pop */
.lstep .lcrest:focus-visible{outline:3px solid var(--green-dark);outline-offset:2px;}
@media (max-width:1024px){.lstep .lcrest{margin:12px 10px 8px;}.lstep .lcrest img{width:112px;}}  /* three wide columns: still one size for all */
/* HER ORDER 2026-09-06 ~12:55: "I don't want the whole screen to go gray. I want a pop-up. It
   pops." So: no backdrop at all. The card is placed by script right beside the crest that was
   clicked - above it when there is room, below it when there is not - with a little caret pointing
   at the tile. It closes on the x, on Escape, or on a click anywhere else. The name is NOT repeated
   under the picture: "Junior - Level 1" is already inside the patch. Just Download. */
#ffaCrestPop{position:absolute;z-index:99997;width:min(340px,92vw);}
#ffaCrestPop[hidden]{display:none;}
#ffaCrestPop .cp-card{position:relative;background:#fffdf6;border:2px solid #d9d0b8;border-radius:16px;padding:14px 14px 12px;text-align:center;box-shadow:0 14px 40px rgba(30,40,26,.28);animation:cpPop .16s ease-out;}
@keyframes cpPop{from{transform:scale(.92);opacity:0}to{transform:none;opacity:1}}
#ffaCrestPop .cp-card::after{content:"";position:absolute;left:50%;width:16px;height:16px;background:#fffdf6;border:2px solid #d9d0b8;transform:translateX(-50%) rotate(45deg);}
#ffaCrestPop.above .cp-card::after{bottom:-10px;border-top:0;border-left:0;}
#ffaCrestPop.below .cp-card::after{top:-10px;border-bottom:0;border-right:0;}
#ffaCrestPop .cp-card img{width:100%;height:auto;display:block;filter:drop-shadow(0 8px 16px rgba(0,0,0,.24));}  /* her order ~15:45: shadow on the emblem, no square */
#ffaCrestPop .cp-name{display:none;}
#ffaCrestPop .cp-dl{display:inline-block;margin-top:10px;font:700 13px var(--ui);color:#2f7a3c;text-decoration:none;border:2px solid #2f7a3c;border-radius:999px;padding:8px 18px;background:#fff;}
#ffaCrestPop .cp-x{position:absolute;top:4px;right:10px;background:none;border:none;font-size:24px;line-height:1;color:#9d968a;cursor:pointer;z-index:1;}

/* HER ORDER 2026-09-06 ~14:15: "the little green thing that goes from the ball almost to the basket
   should be gone." MEASURED at 1440 before this rule: the rail ended 53px past the Hall of Fame ball's
   centre (right was 5.5% of a 960px track). It now ends AT that centre - 11.02% of the track, measured -
   and the ball sits on top of it, so no tail shows. The homepage ladder has no basket column, so its
   rail ends at its own last ball too. */
html body .ladder .ladder-line{right:5.3%;}  /* re-measured 2026-09-06 16:05 with nine columns: 5.3% ends at the Hall of Fame ball */

/* HER ORDER 2026-09-06 ~16:05: "Make the golf ball marker, wherever it is on the ladder, pulse like a little
   heart." Two beats then a rest, like a heartbeat; only the marker on the rung they stand on. */
/* MEASURED 2026-09-06 16:15 (her screenshot): animating transform threw away the ball's own transform that
   centres it on the rail, so the marker dropped below the line. The beat now uses the separate scale
   property, which composes with transform instead of replacing it. */
@keyframes ffaHeart{0%,100%{scale:1;}12%{scale:1.16;}24%{scale:1;}36%{scale:1.12;}56%{scale:1;}}
.ladder .lstep.is-now .lstep-ball{animation:ffaHeart 1.5s ease-in-out infinite;transform-origin:50% 50%;}
@media (prefers-reduced-motion:reduce){.ladder .lstep.is-now .lstep-ball{animation:none;}}
