/* THE CLAN SHEET (social wave, 10 Sep 2026; Surge deck slide 7 — "Gamify
   referrals using clans"). One sheet, three views, on app.js's own .ov shell:
     discover  — no clan yet: start one, or join one from the list
     create    — name, tag, the badge (catalogue or your own PNG)
     clan      — the plate top-left in the profile's grammar, pill tabs to the
                 right: MEMBERS · POKÉDEX · BOARDS · CHAT
   Everything wears the stage sheet's own skin — the sky panel, white tiles
   with the key outline and the hard drop, the pink accent, Barlow Condensed
   italic — and borrows the profile's Pokédex tiles (.pf-mon / .pf-dex /
   .pf-bar, unscoped in profile.css) so the clan Pokédex IS the profile's
   Pokédex with a holder count on each tile. Nothing here is an emoji; the
   picker's emoji are user content and render only inside it and the bubbles. */

.ov--clan .ov__panel{width:min(1040px,100%);max-height:100%}
/* THE SCROLL CONTAINER of the clan sheet is this body (#clBody). On the desktop the
   stage gives every sheet body 64px of top padding and 44px of bottom (stage.css:2512
   and :1742 outrank the line below), which is why the profile's plate opens 64px
   down. Here the 64px (22px on the phone) is a MARGIN on the body's first child
   instead of padding on the body: Chrome measures a sticky offset from the scroll
   container's content box, so a sticky `top` inside a padded body lands padding+top
   (measured 10 Sep: top:0 = the painted spot, top:64px = 64px lower), and the
   phone's tab bar and the plate need `top` to mean what it says in every engine.
   Same geometry as the profile to the pixel (FE-B-NOTES-R2.md §3.5). */
.ov--clan{--cl-top:64px}
.ov--clan .ov__body{padding:0 26px 22px;overflow:auto;position:relative;z-index:1}
.ov--clan .ov__body>:first-child{margin-top:var(--cl-top)}
html[data-layout="stage"] .ov--clan .ov__body{-webkit-mask-image:none;mask-image:none;padding-top:0}

/* EXCEPT ON THE LIST, WHICH FEATHERS (Luke, 11 Sep: "on the clans page, when
   you're not in a clan and you just click clans, when you start scrolling,
   everything cuts under the header, and that cut doesn't look nice. Instead,
   the list of clans should just fade behind the starter clan card and the
   joining one card at the top").
   Measured at 1147x655 before this: the body's mask was `none` outright (the
   rule above), so at scrollTop 220 the two hero cards and every row under them
   were cut dead on the body's top edge at y105 — a hard straight line, which is
   the line he is pointing at. The cards are what sits above the rows, so that
   edge IS "behind the two cards"; they scroll with the list rather than pinning,
   and nothing here pins them, because he asked for the cut to stop looking like
   a cut, not for the top of the page to become furniture.
   SCROLL-LINKED, NOT FIXED — the trap that caught the first version of the clan
   and profile feathers this morning (07:11: "it's faded before I've even
   started scrolling"). This body has padding-top:0, so a static ramp would dim
   the top of the START A CLAN card at rest. --cl-fade is 0 until the list
   moves and reaches 14px by 40px of travel (clan.js setFade). The bottom is the
   34px every sheet wears. */
html[data-layout="stage"] .ov--clan[data-view="discover"] .ov__body{
  -webkit-mask-image:linear-gradient(180deg,transparent 0,rgba(0,0,0,.5) calc(var(--cl-fade,0px) / 2),#000 var(--cl-fade,0px),#000 calc(100% - 34px),transparent 100%);
  mask-image:linear-gradient(180deg,transparent 0,rgba(0,0,0,.5) calc(var(--cl-fade,0px) / 2),#000 var(--cl-fade,0px),#000 calc(100% - 34px),transparent 100%)}
/* BACK top-left, the profile's pf-nav sticker exactly (profile.css). Its 12px is
   FE-A2's published figure (REQUESTS-R2.md §3.17) and is what a SHEET would use;
   on a page, page.css re-pins it into the band under the header. The .ov--clan
   .ov__x rule that used to sit here is gone with the button — a page has no X
   (Luke, 10 Sep). */
.ov--clan .cl-nav{position:absolute;left:22px;top:12px;z-index:3;height:40px;padding:0 14px 0 9px;display:inline-flex;align-items:center;gap:5px;background:#fff;border:2.5px solid var(--key);border-radius:12px;box-shadow:0 3px 0 var(--key);color:var(--key);font:900 15px var(--display);font-style:italic;text-transform:uppercase;letter-spacing:.04em;cursor:pointer;line-height:1}
/* an AUTHOR display beats the UA sheet's [hidden]{display:none}, so BACK has to
   be told to go — clan.js hides it on the views that are the CLANS row's own
   destination (Luke, 10 Sep: no BACK on one of the pages on the left). Same
   trap as .sl-dots[hidden] and .sl-arrow[hidden] in stage.css. */
.ov--clan .cl-nav[hidden]{display:none}
.ov--clan .cl-nav svg{width:20px;height:20px}
.ov--clan .cl-nav:hover{background:var(--yellow,#FDC107)}
.ov--clan .cl-nav:active{transform:translateY(2px);box-shadow:0 1px 0 var(--key)}
/* the first row of every view sits between BACK and the X */
.cl-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:0 60px 0 108px;min-height:40px;margin:0 0 16px}
/* §3.5: the clan view has no title row and paints none — clan.js used to leave an
   empty .cl-head here (40px + 16px), which opened the plate 56px below the profile's */
.cl-head:empty{display:none}
.cl-head h2{margin:0;font:900 30px/1 var(--display);font-style:italic;text-transform:uppercase;color:#fff;-webkit-text-stroke:3px var(--key);paint-order:stroke fill;letter-spacing:.01em}
.cl-head h2 b{font-weight:inherit;color:var(--acc-hi)}
.cl-state{padding:40px 16px;text-align:center;font:800 16px var(--ui);color:var(--key)}

/* ---- shared bits ------------------------------------------------------ */
.cl-btn{display:inline-flex;align-items:center;justify-content:center;gap:6px;padding:10px 14px;border:2px solid var(--key);border-radius:12px;box-shadow:0 3px 0 var(--key);font:900 15px var(--display);font-style:italic;text-transform:uppercase;letter-spacing:.04em;color:#fff;background:linear-gradient(180deg,var(--acc-hi),var(--acc) 48%,var(--acc-lo));cursor:pointer;line-height:1;white-space:nowrap}
.cl-btn svg{width:18px;height:18px;flex:0 0 auto}
.cl-btn:active{transform:translateY(2px);box-shadow:0 1px 0 var(--key)}
.cl-btn--ghost{background:#fff;color:var(--key)}
.cl-btn--ghost:hover{background:var(--yellow,#FDC107)}
.cl-btn--on{background:var(--yellow,#FDC107);color:var(--key)}
.cl-btn--sm{padding:6px 11px;font-size:13px;border-radius:9px}
.cl-btn--wide{width:100%}
.cl-btn[disabled]{opacity:.55;cursor:default;transform:none;box-shadow:0 3px 0 var(--key)}
.cl-btn--quiet{background:#fff;color:#3A4354;border-color:rgba(11,15,24,.35);box-shadow:0 3px 0 rgba(11,15,24,.35)}
.cl-msg{margin:8px 0 0;font:700 13px/1.4 var(--ui);color:var(--key);min-height:1.2em}
.cl-msg--bad{color:#B3122E}
.cl-msg--ok{color:#1E7B3C}
.cl-in{width:100%;padding:10px 12px;border:2px solid var(--key);border-radius:12px;background:#fff;font:700 15px var(--ui);color:var(--key);outline:0;min-width:0}
.cl-in:focus{box-shadow:0 0 0 3px rgba(216,73,141,.35)}
.cl-in::placeholder{color:#7A8395;font-weight:600}
.cl-lbl{display:block;margin:0 0 6px;font:800 11px var(--ui);letter-spacing:.12em;text-transform:uppercase;color:#3A4354}
.cl-row{display:flex;gap:8px;align-items:center}
/* the person: a picture or an initial on a name-hashed colour (leaderboard.js avColour) */
.cl-av{width:36px;height:36px;border-radius:50%;border:2px solid var(--key);display:grid;place-items:center;flex:0 0 auto;overflow:hidden;font:900 15px var(--display);color:#fff;line-height:1;background:#8B3FF0;text-transform:uppercase}
.cl-av img{width:100%;height:100%;object-fit:cover;display:block}
.cl-av--28{width:28px;height:28px;font-size:12px}
.cl-av--44{width:44px;height:44px;font-size:18px}
.cl-who{display:inline-flex;align-items:center;gap:8px;min-width:0;font:800 15px var(--ui);color:var(--key);cursor:pointer;background:none;border:0;padding:0;text-align:left}
.cl-who:hover .cl-who__n{color:var(--acc)}
.cl-who__n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* THE CLAN CHIP — badge + tag, inline anywhere (profile name, boards, bell).
   window.CLAN.badge(clan, size) draws it; a click opens the clan. */
.cl-chip{display:inline-flex;align-items:center;gap:5px;height:var(--cl-h,22px);padding:0 8px 0 3px;border:2px solid var(--key);border-radius:999px;background:#fff;font:900 calc(var(--cl-h,22px) * .58) var(--display);font-style:italic;letter-spacing:.05em;color:var(--key);vertical-align:middle;line-height:1;cursor:pointer;white-space:nowrap;text-transform:uppercase;box-shadow:0 2px 0 var(--key)}
.cl-chip img{width:calc(var(--cl-h,22px) - 6px);height:calc(var(--cl-h,22px) - 6px);object-fit:contain;display:block}
.cl-chip:hover{background:var(--yellow,#FDC107)}
.cl-chip--flat{cursor:default;box-shadow:none}
.cl-chip--flat:hover{background:#fff}
.cl-tag{display:inline-flex;align-items:center;padding:3px 9px;border:2px solid var(--key);border-radius:999px;background:#fff;font:900 12px var(--display);font-style:italic;letter-spacing:.06em;text-transform:uppercase;color:var(--key);line-height:1}
.cl-tag--owner{background:var(--yellow,#FDC107)}
.cl-tag--me{background:var(--acc);color:#fff}
.cl-tag--soft{background:#EEF3FA;border-color:rgba(11,15,24,.35);color:#3A4354}
/* the site's Rip Points mark, the profile's */
.cl-pts{display:inline-flex;align-items:center;gap:5px}
.cl-pts svg{width:16px;height:16px}

/* ---- A. DISCOVER --------------------------------------------------------- */
.cl-hero{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin:0 0 18px}
.cl-hero__c{position:relative;background:#fff;border:3px solid var(--key);border-radius:18px;box-shadow:0 5px 0 var(--key);padding:18px 18px 16px;overflow:hidden;display:flex;flex-direction:column;gap:8px;align-items:flex-start}
.cl-hero__c::before{content:'';position:absolute;inset:0;height:8px;background:linear-gradient(90deg,var(--acc-hi),var(--acc))}
.cl-hero__c--join::before{background:linear-gradient(90deg,#5190F7,#82C0F1)}
.cl-hero__c h3{margin:6px 0 0;font:900 28px/1 var(--display);font-style:italic;text-transform:uppercase;color:var(--key)}
.cl-hero__c p{margin:0;font:600 14px/1.45 var(--ui);color:#3A4354;max-width:36ch}
.cl-hero__c .cl-btn{margin-top:6px}
.cl-hero__c .cl-in{margin-top:6px}

/* YOUR CLAN IN THE "JOIN ONE" SLOT (§1.1f). The card keeps the join card's
   exact shape — heading, line, one control — so the two-column grid does not
   move between a member's view and a stranger's; only the heading changes, and
   it becomes the door into the clan. The badge is capped to the cap height of
   the type beside it so a tall badge cannot grow the card. */
.cl-hero__c--mine::before{background:linear-gradient(90deg,var(--acc-hi),var(--acc))}
.cl-mineb{display:flex;align-items:center;gap:10px;padding:0;border:0;background:none;cursor:pointer;
  font:inherit;color:inherit;text-align:left;max-width:100%}
.cl-mineb__b{width:30px;height:30px;flex:0 0 auto;object-fit:contain;filter:drop-shadow(0 2px 0 rgba(11,15,24,.3))}
.cl-mineb span{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cl-mineb:hover span{text-decoration:underline;text-decoration-thickness:2px;text-underline-offset:3px}

/* THE CONFIRM (§1.1g). Its own layer inside the page rather than a tenant of
   the overlay stack: it has to sit over the clans page only, and it must not
   be something PAGE.open or closeAll can leave behind — setView() drops it.
   NOT .cl-ask — that is the CLIP shelf's delete confirm (record.css:331,
   clips-shelf.js:218; `cl-` there is clip, not clan). record.css loads after
   clan.css, so the first draft of this took its white background and z-index:3
   and painted the whole page white with the dialog floating on it. */
.cl-conf{position:absolute;inset:0;z-index:40;display:grid;place-items:center;padding:20px;
  background:rgba(11,15,24,.52);-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}
.cl-conf__c{width:min(420px,100%);background:#fff;border:3px solid var(--key);border-radius:18px;
  box-shadow:0 6px 0 var(--key);padding:20px 20px 18px}
.cl-conf__c h3{margin:0;font:900 26px/1.05 var(--display);font-style:italic;text-transform:uppercase;color:var(--key)}
.cl-conf__c p{margin:10px 0 0;font:600 14px/1.45 var(--ui);color:#3A4354}
.cl-conf__s{font-size:12.5px!important;color:#5B6474!important}
.cl-conf__row{display:flex;gap:10px;margin:16px 0 0}
.cl-conf__row .cl-btn{flex:1 1 0;justify-content:center}
.cl-list{display:flex;flex-direction:column;gap:8px}
.cl-lrow{display:grid;grid-template-columns:44px minmax(0,1.4fr) repeat(3,minmax(0,1fr)) auto;gap:0 14px;align-items:center;background:rgba(255,255,255,.9);border:2px solid var(--key);border-radius:12px;padding:8px 12px 8px 8px}
.cl-lrow__b{width:44px;height:44px;object-fit:contain;display:block}
.cl-lrow__n{min-width:0;display:flex;flex-direction:column;gap:3px}
.cl-lrow__n button{font:900 19px/1.1 var(--display);color:var(--key);background:none;border:0;padding:0;text-align:left;cursor:pointer;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-transform:uppercase;font-style:italic}
.cl-lrow__n button:hover{color:var(--acc)}
.cl-lrow__n .cl-tag{align-self:flex-start;padding:2px 7px;font-size:11px}
.cl-stat{display:flex;flex-direction:column;min-width:0}
.cl-stat b{font:900 18px/1 var(--display);font-style:italic;color:var(--key);white-space:nowrap}
.cl-stat b small{font:inherit;font-size:.6em;color:#3A4354;font-weight:800}
/* the Rip Points mark inside a list stat (the discover rows rank by week points, REVIEW M4) */
.cl-stat b svg{width:16px;height:16px;vertical-align:-2px;margin-right:4px}
.cl-stat span{margin-top:3px;font:800 10px var(--ui);letter-spacing:.12em;text-transform:uppercase;color:#3A4354;white-space:nowrap}
.cl-lrow--mine{background:var(--yellow,#FDC107)}
.cl-empty{padding:24px 12px;text-align:center;font:700 14px var(--ui);color:#3A4354}

/* ---- B. CREATE --------------------------------------------------------- */
.cl-form{display:grid;grid-template-columns:300px minmax(0,1fr);gap:18px;align-items:start}
.cl-form__l{display:flex;flex-direction:column;gap:12px;background:#fff;border:3px solid var(--key);border-radius:18px;box-shadow:0 5px 0 var(--key);padding:16px}
.cl-form__pv{display:flex;align-items:center;gap:10px;padding:10px 12px;background:rgba(111,181,242,.22);border:2px solid var(--key);border-radius:12px;min-height:56px;font:800 13px var(--ui);color:#3A4354}
.cl-form__pv .cl-chip{margin-left:auto}
.cl-form__r{min-width:0}
.cl-form__r h3{margin:0 0 4px;font:900 24px/1 var(--display);font-style:italic;text-transform:uppercase;color:var(--key)}
.cl-form__r h3 b{color:var(--acc);font-weight:inherit}
.cl-form__r p{margin:0 0 12px;font:600 13px/1.45 var(--ui);color:#3A4354}
.cl-bgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(92px,1fr));gap:10px}
.cl-bd{position:relative;background:rgba(255,255,255,.92);border:2px solid var(--key);border-radius:12px;box-shadow:0 3px 0 var(--key);padding:8px 6px 7px;text-align:center;cursor:pointer;font:inherit;color:inherit;min-width:0}
.cl-bd img{width:100%;aspect-ratio:1;object-fit:contain;display:block}
.cl-bd__n{margin-top:5px;font:800 11px/1.2 var(--ui);color:var(--key);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cl-bd:hover{background:var(--yellow,#FDC107)}
.cl-bd.is-on{border-color:var(--acc);box-shadow:0 0 0 2px #fff,0 3px 0 2px var(--acc);background:#fff}
.cl-bd.is-on::after{content:'';position:absolute;right:6px;top:6px;width:14px;height:14px;border-radius:50%;background:var(--acc);border:2px solid var(--key)}
.cl-bd--taken{cursor:default;pointer-events:none}
.cl-bd--taken img{opacity:.22;filter:grayscale(1)}
.cl-bd--taken:hover{background:rgba(255,255,255,.92)}
.cl-bd__t{position:absolute;left:50%;top:38%;transform:translate(-50%,-50%) rotate(-8deg);padding:3px 7px;background:var(--key);color:#fff;border-radius:6px;font:900 10px var(--display);font-style:italic;letter-spacing:.06em;text-transform:uppercase;white-space:nowrap}
.cl-up{margin:14px 0 0;display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.cl-up__pv{width:56px;height:56px;border:2px solid var(--key);border-radius:12px;background:#fff repeating-conic-gradient(#E6ECF5 0 25%,#fff 0 50%) 0 0/14px 14px;display:grid;place-items:center;overflow:hidden}
.cl-up__pv img{width:100%;height:100%;object-fit:contain}
.cl-up input[type=file]{position:absolute;width:1px;height:1px;opacity:0;pointer-events:none}
.cl-up__note{flex:1 1 200px;font:600 12px/1.4 var(--ui);color:#3A4354}

/* ---- C. THE CLAN PAGE -------------------------------------------------- */
.cl-b{display:grid;grid-template-columns:300px minmax(0,1fr);gap:0 18px;align-items:start}

/* ONLY THE LIST SCROLLS (Luke, 11 Sep: "when I scroll on clans, the clan card
   on the left moves up slightly and goes behind the cut. On this main page
   where it just says Members, the only thing that should scroll is the members,
   and that's it. Nothing else should move at all" ... "the only thing that
   should move during a scroll is the chat").
   The scroller was #clBody — the whole page — so everything travelled and the
   plate only LOOKED still because it was sticky, which is why it drifted at the
   ends of its range and clipped under the body's fade. The scroll moves down to
   the panel: the page body stops scrolling at all, the grid fills the frame's
   height, and .cl-panel is the one box with overflow.
   The plate is then plain static — no sticky, no --cl-stick, nothing to drift —
   so clan.js's fitPlate() has nothing left to correct. It still writes the two
   properties; they are simply unused here, and the phone (below) keeps the old
   single-column scroll, where one column IS the page. */
/* SCOPED TO THE CLAN VIEW (data-view="clan", written by clan.js setView). The
   discover list, the create form and the badge picker are ordinary scrolling
   columns and must keep the page's own scroll — the first version of this
   block was unscoped and gave `height:100%` to discover's <h2>, which pushed
   the whole list off the bottom of the screen. */
@media (min-width:1024px){
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .ov__body{overflow:hidden;min-height:0}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .ov__body>:first-child{height:100%}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-b{height:100%;align-items:stretch;min-height:0}
  /* THE PLATE IS STATIC, AND ON A SHORT WINDOW IT CARRIES ITS OWN SCROLL.
     At 1147x655 the frame is 550px and the plate's own content is taller than
     that, so with the page's scroll gone it would either clip or drag the page
     back into scrolling — measured, the body still moved 45px before this.
     Its own overflow keeps Luke's rule ("nothing else should move at all"): the
     page does not move, and a plate that cannot fit is the only thing that
     scrolls, inside its own box. At 1512x982 it fits and never scrolls. */
  /* RELATIVE, NOT STATIC. .cl-plate::before is the pink band across its top and
     it is position:absolute — with the plate static it resolved against the
     page instead and painted a pink bar the full width of the body, under the
     tab strip. Dropping `sticky` has to keep the element POSITIONED. */
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-plate{
    position:relative;align-self:stretch;min-height:0;overflow-y:auto;
    overscroll-behavior:contain;scrollbar-width:thin;scrollbar-color:var(--acc) transparent}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-side{display:flex;flex-direction:column;min-height:0;height:100%}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-tabs{flex:0 0 auto}
  /* the one scroller. Its own bottom fade, the one every sheet wears (§6.9),
     so a list that runs on dissolves instead of being cut flat. */
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel{
    flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;
    padding-bottom:26px;scrollbar-width:thin;scrollbar-color:var(--acc) transparent;
    -webkit-mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 34px),transparent 100%);
    mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 34px),transparent 100%)}
  /* ONE SCROLLER ON THE CHAT TAB, AND NO FADE (Luke, 11 Sep 01:55: "if you look
     at the chat, it's got two scrollbars. The chat scrolls up and down, but the
     actual chat box scrolls up and down as well. The chat box shouldn't scroll
     up and down at all. At the bottom of the chat box, it's faded into the
     footer. There should be no fade in the footer there.")
     Measured signed in as a member at 1512x982: .cl-chat__l scrolled 2213px,
     which is the one that should, and .cl-panel scrolled 35px as well. The chat
     column sizes itself from the VIEWPORT (.cl-chat, :331 — --cl-view less
     --cl-top less 86) and came out 776px inside a 741px box; at 1147x655 the
     same sum overshot by 15. That formula is a sheet-era leftover: on a page the
     panel is already the right height by flex, so the column only has to fill
     it. The bottom mask is the panel's own and the chat is the one tab that
     must not wear it — a composer is not a list that runs on. */
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel[data-tab="chat"]{
    overflow:hidden;padding-bottom:0;-webkit-mask-image:none;mask-image:none}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel[data-tab="chat"] .cl-chat{
    height:100%;min-height:0}

  /* IT MUST NOT SCROLL SIDEWAYS (Luke, 11 Sep 06:27: "the whole pokédex thing
     scrolls left to right. That's why it's cut off on the left. It shouldn't
     scroll left to right at all").
     overflow-y:auto computes overflow-x:auto — one axis cannot stay visible
     while the other scrolls — so ANY overflow at all becomes a sideways
     scrollbar. Measured on the Pokédex tab: scrollWidth 886 against a client
     881, five pixels, which is the dex grid's eight fractional 101.375px
     columns rounding up. Five pixels is enough to drag the first column under
     the panel's left edge, which is the cut he can see. */
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel{overflow-x:hidden}

  /* FADING IN AND FADING OUT (Luke, 11 Sep 06:26, of the members list: "the
     same effect needs to happen to the members on this clan page, with a slight
     fade at the bottom of this page, so that it looks like the fading in and
     fading out" — and, of the Pokédex, "the fade should happen on Pokédex as
     well"). The panel only had the bottom half of that. The top is the 14px
     feather he picked for the pages on 7 Sep ("option C", page.css:197), so a
     row dissolves under the tab strip instead of cutting against it. The chat
     tab overrides both, above — a composer is not a list that runs on.
     THE TOP RAMP FOLLOWS THE SCROLL AND IS 0 AT REST (Luke, 11 Sep 07:11: "it's
     faded before I've even started scrolling. The fade, I guess, should only
     exist once I start scrolling"). This panel has no top padding, so a fixed
     ramp sat straight on the first row and dimmed it on a page nobody had
     touched — it swallowed the BOARDS picker whole, which is why that row read
     as missing rather than faded. clan.js writes --cl-fade from scrollTop
     clamped to 14, so the feather grows in over the first 14px of travel
     instead of snapping on. At 0 every stop collapses to 0 and the mask is
     opaque from the top edge. */
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel{
    -webkit-mask-image:linear-gradient(180deg,transparent 0,rgba(0,0,0,.5) calc(var(--cl-fade,0px) / 2),#000 var(--cl-fade,0px),#000 calc(100% - 34px),transparent 100%);
    mask-image:linear-gradient(180deg,transparent 0,rgba(0,0,0,.5) calc(var(--cl-fade,0px) / 2),#000 var(--cl-fade,0px),#000 calc(100% - 34px),transparent 100%)}

  /* THE ACTIVE TAB'S WHITE RING IS NOT CUT OFF (Luke, 11 Sep 06:26: "where it
     says 'Members' ... the white box doesn't go right the way around the
     'Members' button. It's because it's all being cut off at the top").
     .cl-tab.is-on carries `box-shadow:0 0 0 2px #fff` (:284) — that ring paints
     2px OUTSIDE the pill's box. Measured: the pill's top and #clBody's own clip
     edge were both y120, so the ring's top two pixels were being clipped away
     while its left had 26px of padding to live in, which is why it looked cut
     on one side only. Three pixels of room, so the plate and the strip move
     down together and stay aligned. */
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .ov__body{padding-top:3px}
  /* BOARDS is a short block, not a list — it should simply fit (Luke: "on the
     leaderboards page where it says Boards, that shouldn't be scrollable at
     all. We should find a way to fit it all in"). It inherits the scroller
     above and only uses it if it genuinely overflows. */
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel .cl-boards{margin-top:0}
}
/* AND IT HAS TO FIT ON THE SHORT WINDOW TOO. At 1512x982 the three boards fit
   with room to spare; at 1147x655 the panel is ~440px and ten rows at 43+6 came
   to 490 plus the heads — 162px over, measured. Rather than drop rows (a board
   that shows eight of its ten is a board that lies about who is on it) the ROW
   tightens: 34px instead of 43, a 26px face instead of 28, 4px between. Ten
   rows, three boards, no scroll. */
/* THE ROW TIGHTENING IS GONE. It only ever existed because three ten-row
   boards had to share the panel's width; one board at a time has the lot, so
   the 30px row, the 24px face and the 9px sub-text — the "small and squashed"
   Luke objected to on 11 Sep 06:28 — are not needed and are not here. What is
   left below is the heading/padding trim, which is about height, not width. */
@media (min-width:1024px) and (max-height:760px){
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel .cl-shelf__h{margin-bottom:6px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel .cl-shelf__h h3{font-size:20px}
  /* the scroller's own bottom breathing room, which BOARDS does not need
     because it is not a list that runs on */
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel{padding-bottom:6px}
}
/* §3.4 THE PLATE STAYS while the tab content scrolls. The scroll container is
   #clBody (.ov--clan .ov__body above, overflow:auto; style.css:655). The plate is
   a grid item of .cl-b (align-items:start), so its sticky range is its own grid
   area — the full height of the side column. --cl-stick is --cl-top (64px, the
   spot the plate opens at) while the plate fits under it, so it never moves;
   clan.js fitPlate() lowers it, below zero if need be, when the plate is taller
   than the scrollport, so the plate rides up until its bottom shows, then stays. */
.cl-plate{position:sticky;top:var(--cl-stick,var(--cl-top,64px));background:#fff;border:3px solid var(--key);border-radius:18px;box-shadow:0 5px 0 var(--key);padding:18px 16px 16px;overflow:hidden}
.cl-plate::before{content:'';position:absolute;inset:0;height:74px;background:linear-gradient(180deg,var(--acc-hi),var(--acc));border-bottom:3px solid var(--key)}
.cl-badge{position:relative;width:120px;height:120px;margin:10px auto 0;display:grid;place-items:center}
.cl-badge img{width:100%;height:100%;object-fit:contain;filter:drop-shadow(0 4px 0 rgba(11,15,24,.35))}
.cl-name{text-align:center;margin:8px 0 0;font:900 32px/1 var(--display);font-style:italic;color:#fff;-webkit-text-stroke:3px var(--key);paint-order:stroke fill;letter-spacing:.01em;overflow-wrap:anywhere;text-transform:uppercase;display:flex;align-items:center;justify-content:center;gap:6px}
/* the verified tick slot: drawn only when clan.verified (the Surge "authorised" tick) */
.cl-ver{width:24px;height:24px;flex:0 0 auto;-webkit-text-stroke:0}
.cl-meta{margin:8px 0 0;display:flex;justify-content:center;align-items:center;gap:8px;flex-wrap:wrap;font:700 13px var(--ui);color:var(--key)}
.cl-owner{margin:10px 0 0;display:flex;align-items:center;justify-content:center;gap:8px;font:700 13px var(--ui);color:#3A4354}
.cl-owner .cl-who{font-size:14px}
.cl-stats{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin:14px 0 0}
.cl-tile{display:flex;flex-direction:column;justify-content:center;background:rgba(255,255,255,.92);border:2px solid var(--key);border-radius:12px;padding:7px 10px;min-width:0}
.cl-tile b{display:flex;align-items:center;gap:5px;font:900 22px/1 var(--display);font-style:italic;color:var(--key);letter-spacing:.01em;white-space:nowrap}
.cl-tile b small{font:inherit;font-size:.55em;color:#3A4354;font-weight:800}
.cl-tile b svg{width:18px;height:18px;flex:0 0 auto}
.cl-tile>span{display:block;margin-top:4px;font:800 11px var(--ui);letter-spacing:.12em;text-transform:uppercase;color:#3A4354;white-space:nowrap}
.cl-acts{margin:14px 0 0;display:flex;flex-direction:column;gap:8px}
.cl-acts .cl-row .cl-btn{flex:1}
.cl-invite{display:flex;gap:6px}
.cl-invite .cl-in{flex:1;padding:8px 10px;font-size:14px}
.cl-pend{margin:12px 0 0;border:2px solid var(--key);border-radius:12px;background:rgba(111,181,242,.22);padding:8px 10px 6px}
.cl-pend__h{display:flex;align-items:center;justify-content:space-between;font:900 13px var(--display);font-style:italic;letter-spacing:.06em;text-transform:uppercase;color:var(--key);margin:0 0 6px}
.cl-pend__h i{font-style:normal;padding:1px 7px;border-radius:999px;background:var(--acc);color:#fff;font-size:12px}
.cl-prow{display:flex;align-items:center;gap:8px;padding:5px 0;border-top:1px solid rgba(11,15,24,.12)}
.cl-prow:first-of-type{border-top:0}
.cl-prow .cl-who{flex:1 1 auto;font-size:13px}
.cl-prow .cl-btn{padding:5px 8px;font-size:12px;border-radius:8px;box-shadow:0 2px 0 var(--key)}
.cl-prow small{font:600 12px var(--ui);color:#3A4354}
.cl-link{margin:12px 0 0}
.cl-link__r{display:flex;align-items:center;gap:6px;border:2px solid var(--key);border-radius:12px;background:#fff;padding:5px 5px 5px 10px}
.cl-link__r code{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font:700 12.5px var(--ui);color:var(--key)}
/* tabs: pill stickers, the site's own (stage.css .otab), scoped here */
.cl-side{min-width:0}
.cl-tabs{margin:0 0 12px}
.cl-tabs__in{display:flex;gap:8px;flex-wrap:wrap}
.cl-tab{flex:0 0 auto;padding:9px 14px;border-radius:12px;font:900 16px var(--display);font-style:italic;letter-spacing:.03em;text-transform:uppercase;color:var(--key);background:rgba(255,255,255,.92);border:2px solid var(--key);box-shadow:0 3px 0 var(--key);transform:var(--slant);cursor:pointer;display:inline-flex;align-items:center;gap:6px;line-height:1}
.cl-tab i{font-style:normal;font:800 11px var(--ui);padding:2px 6px;border-radius:999px;background:#EEF3FA;color:#3A4354;transform:var(--slant)}
.cl-tab__ic{display:none}
.cl-tab:hover{background:var(--yellow,#FDC107)}
.cl-tab.is-on{color:#fff;background:linear-gradient(180deg,var(--acc-hi) 0%,var(--acc) 48%,var(--acc-lo) 100%);box-shadow:0 0 0 2px #fff,0 3px 0 2px var(--key)}
.cl-tab.is-on i{background:rgba(255,255,255,.9);color:var(--key)}
.cl-tab:active{transform:var(--slant) translateY(2px);box-shadow:0 1px 0 var(--key)}
.cl-panel{min-height:200px}
.cl-shelf__h{display:flex;align-items:baseline;justify-content:space-between;gap:12px;margin:0 0 10px}
.cl-shelf__h h3{margin:0;font:900 22px/1 var(--display);font-style:italic;text-transform:uppercase;color:var(--key);letter-spacing:.02em}
.cl-shelf__h h3 b{color:var(--acc);font-weight:inherit}
.cl-shelf__h span{font:800 13px var(--ui);color:#0B0F18}

/* MEMBERS */
.cl-mrow{display:grid;grid-template-columns:36px minmax(0,1fr) auto auto auto;gap:0 12px;align-items:center;background:rgba(255,255,255,.88);border:2px solid var(--key);border-radius:12px;padding:7px 12px 7px 8px;margin:0 0 7px;position:relative;transition:background .12s}
/* §3.3: hovering a row only lights it. The owner's MAKE OWNER / KICK sit in a slot of
   their own RIGHT of the counts, on every row of the owner's list (empty on the
   owner's own row, so the counts line up), and fade in on hover or keyboard focus;
   "31 SPECIES" never moves and never hides. 148px = MAKE OWNER + KICK + the gap. */
.cl-mrow:hover{background:#fff}
.cl-mrow--own{grid-template-columns:36px minmax(0,1fr) auto auto auto minmax(148px,auto)}
.cl-mrow--me,.cl-mrow--me:hover{background:var(--yellow,#FDC107)}
.cl-mrow .cl-who{font:800 17px var(--display);text-transform:none}
.cl-mrow__k{font:900 16px var(--display);font-style:italic;color:var(--acc-lo);white-space:nowrap;display:inline-flex;align-items:center;gap:4px;font-variant-numeric:tabular-nums}
.cl-mrow__k small{font:700 11px var(--ui);color:#3A4354;font-style:normal;letter-spacing:.08em;text-transform:uppercase}
.cl-mrow__kick{display:inline-flex;gap:6px;justify-content:flex-end;opacity:0;transition:opacity .12s}
.cl-mrow:hover .cl-mrow__kick,.cl-mrow:focus-within .cl-mrow__kick{opacity:1}

/* POKÉDEX: the profile's tiles, plus the holder count */
.cl-mon{position:relative}
.cl-mon__n{position:absolute;right:5px;top:5px;min-width:20px;height:20px;padding:0 5px;border-radius:999px;background:var(--acc);color:#fff;border:2px solid var(--key);font:900 11px/16px var(--display);text-align:center}
/* IT WRAPS INSTEAD OF RUNNING OFF (11 Sep). An opacity:0 box is still laid out,
   so a nowrap tip on the last column reached past the panel's right edge and was
   the whole of its 5px scrollWidth overshoot — the sideways scroll Luke could
   feel. Capped to the tile, with box-sizing:border-box — 8px of side padding
   falls OUTSIDE a max-width:100% otherwise, which still put the tip 5px past
   the tile and was exactly the overshoot measured. Now it cannot overflow the
   panel, which also means overflow-x:hidden never clips it. */
.cl-mon[data-tip]::after{content:attr(data-tip);position:absolute;left:50%;bottom:calc(100% + 6px);transform:translateX(-50%);padding:5px 8px;border-radius:8px;background:var(--key);color:#fff;font:700 12px var(--ui);white-space:normal;width:max-content;max-width:100%;box-sizing:border-box;opacity:0;pointer-events:none;transition:opacity .12s;z-index:4}
.cl-mon[data-tip]:hover::after{opacity:1}
.cl-dexbar{margin:0 0 12px}
.cl-dexbar .pf-bar{margin:0 0 6px}
.cl-dexbar p{margin:0;font:600 13px/1.4 var(--ui);color:#3A4354}
.cl-dexbar p b{color:var(--key)}

/* BOARDS: three mini boards side by side */
.cl-boards{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
.cl-board{background:rgba(255,255,255,.55);border:2px solid var(--key);border-radius:14px;padding:10px;min-width:0}
.cl-board h4{margin:0 0 8px;font:900 16px/1 var(--display);font-style:italic;text-transform:uppercase;letter-spacing:.04em;color:var(--key)}
/* §3.18: the BIGGEST PULL rows carry the card's name under the person, so they ran
   43px against the other boards' 40.5px (measured at 1147x655, --sl-s .78). Every
   row is now the taller one; the grid centres each cell and the person's column
   centres its own two lines. */
.cl-brow{display:grid;grid-template-columns:22px 28px minmax(0,1fr) auto;gap:0 7px;align-items:center;background:#fff;border:2px solid var(--key);border-radius:10px;padding:5px 8px 5px 6px;margin:0 0 6px;min-width:0;min-height:43px}
.cl-brow--me{background:var(--yellow,#FDC107)}
.cl-brow__n{font:900 16px var(--display);font-style:italic;color:#5A6478;text-align:center;transform:var(--slant);font-variant-numeric:tabular-nums}
.cl-brow--1 .cl-brow__n{color:#B07D06}.cl-brow--2 .cl-brow__n{color:#6B7280}.cl-brow--3 .cl-brow__n{color:#9C5620}
.cl-brow .cl-who{font:800 14px var(--display);flex-direction:column;align-items:flex-start;justify-content:center;gap:1px;width:100%}
.cl-brow .cl-who__n{max-width:100%}
.cl-brow .cl-brow__c{max-width:100%}
.cl-brow__v{font:900 15px var(--display);font-style:italic;color:var(--acc-lo);white-space:nowrap;font-variant-numeric:tabular-nums}
.cl-brow__c{display:block;font:600 10.5px var(--ui);color:#3A4354;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* CHAT */
/* §3.6: the chat must fill the sheet the way MEMBERS and BOARDS do. `100vh` was the real
   viewport, but the sheet lives inside the stage's ZOOMED panel (zoom .78 at 1147x655), so
   the old calc came out ~370px short and left a band of sky under the composer next to a
   sticky 780px plate. --cl-view is #clBody's own clientHeight, set by clan.js fitPlate();
   150px is the sheet's own furniture above and below the panel — the body's first-child
   top margin (--cl-top), the tab row (46 + its 12 margin) and the body's 22px bottom
   padding, plus a few px of slack so the column never itself makes the sheet scroll.
   IT FOLLOWS --cl-top rather than baking its 64 in: on a page that margin is 0 (the
   frame already holds the content off the header — page.css §2a), and a hardcoded 150
   would leave exactly 64px of sky under the composer, which is the band this rule was
   written to remove in the first place. 0 + 86 on a page, 64 + 86 = 150 in a sheet. */
.cl-chat{display:flex;flex-direction:column;height:max(320px,calc(var(--cl-view,100vh) - var(--cl-top,64px) - 86px));min-height:320px;background:rgba(255,255,255,.55);border:2px solid var(--key);border-radius:14px;overflow:hidden;position:relative}
.cl-chat__l{flex:1 1 auto;min-height:0;overflow-y:auto;padding:12px 12px 8px;display:flex;flex-direction:column;gap:2px;scrollbar-width:thin}
.cl-msgg{display:grid;grid-template-columns:36px minmax(0,1fr);gap:0 10px;margin:10px 0 0;align-items:start}
.cl-msgg:first-child{margin-top:0}
.cl-msgg__h{display:flex;align-items:baseline;gap:8px;margin:0 0 3px;font:800 14px var(--ui);color:var(--key)}
.cl-msgg__h button{font:inherit;color:inherit;background:none;border:0;padding:0;cursor:pointer}
.cl-msgg__h button:hover{color:var(--acc)}
.cl-msgg__h time{font:600 11px var(--ui);color:#5A6478}
.cl-bub{display:block;width:fit-content;max-width:min(100%,520px);margin:0 0 3px;padding:7px 11px;background:#fff;border:2px solid var(--key);border-radius:4px 12px 12px 12px;font:600 14px/1.4 var(--ui);color:var(--key);white-space:pre-wrap;overflow-wrap:anywhere}
.cl-bub+.cl-bub{border-radius:12px}
.cl-msgg--me .cl-bub{background:#FFF4C2}
.cl-bub--pend{opacity:.55}
/* §3.6 A CLIP IN THE CHAT (BRIEF-CONTEXT-R2 §3c): a card under the line — poster,
   title, length — that opens the clip viewer (clips-shelf.js CLIPS.view). A clip the
   reader may not see comes as clip:null + clipHidden:true and paints the grey card. */
.cl-clip{display:grid;grid-template-columns:56px minmax(0,1fr);gap:0 10px;align-items:center;width:min(100%,300px);margin:0 0 3px;padding:6px 10px 6px 6px;background:#fff;border:2px solid var(--key);border-radius:12px;box-shadow:0 3px 0 var(--key);cursor:pointer;text-align:left;font:inherit;color:var(--key)}
.cl-clip:hover{background:var(--yellow,#FDC107)}
.cl-clip:active{transform:translateY(2px);box-shadow:0 1px 0 var(--key)}
.cl-clip__p{position:relative;width:56px;height:74px;border:2px solid var(--key);border-radius:8px;overflow:hidden;background:#0B0F18;display:grid;place-items:center;color:#fff}
.cl-clip__p img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.cl-clip__p svg{position:relative;width:26px;height:26px;filter:drop-shadow(0 1px 0 rgba(11,15,24,.6))}
.cl-clip__b{display:flex;flex-direction:column;gap:3px;min-width:0}
.cl-clip__t{font:800 14px/1.25 var(--ui);color:var(--key);overflow:hidden;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow-wrap:anywhere}
.cl-clip__m{font:800 12px var(--ui);letter-spacing:.08em;text-transform:uppercase;color:#3A4354;white-space:nowrap}
.cl-clip--hid{grid-template-columns:22px minmax(0,1fr);cursor:default;box-shadow:none;background:rgba(255,255,255,.7);color:#3A4354}
.cl-clip--hid:hover{background:rgba(255,255,255,.7)}
.cl-clip--hid svg{width:22px;height:22px}
.cl-clip--hid .cl-clip__t{font-weight:700;color:#3A4354}
.cl-sys{align-self:center;margin:8px 0 0;padding:3px 10px;border-radius:999px;background:rgba(11,15,24,.10);font:700 11.5px var(--ui);color:#3A4354;text-align:center}
.cl-new{position:absolute;left:50%;bottom:64px;transform:translateX(-50%);padding:6px 12px;border:2px solid var(--key);border-radius:999px;background:var(--acc);color:#fff;font:900 12px var(--display);font-style:italic;letter-spacing:.05em;text-transform:uppercase;box-shadow:0 3px 0 var(--key);cursor:pointer;z-index:2}
.cl-new[hidden]{display:none}
.cl-comp{flex:0 0 auto;display:flex;align-items:flex-end;gap:6px;padding:8px;border-top:2px solid var(--key);background:#fff;position:relative}
.cl-comp textarea{flex:1;min-width:0;resize:none;max-height:120px;padding:9px 11px;border:2px solid var(--key);border-radius:12px;font:600 14px/1.35 var(--ui);color:var(--key);outline:0;background:#fff}
.cl-comp textarea:focus{box-shadow:0 0 0 3px rgba(216,73,141,.35)}
.cl-comp__ico{width:40px;height:40px;flex:0 0 auto;display:grid;place-items:center;border:2px solid var(--key);border-radius:12px;background:#fff;color:var(--key);cursor:pointer;box-shadow:0 3px 0 var(--key);padding:0}
.cl-comp__ico svg{width:22px;height:22px}
.cl-comp__ico:hover,.cl-comp__ico.is-on{background:var(--yellow,#FDC107)}
.cl-comp__ico:active{transform:translateY(2px);box-shadow:0 1px 0 var(--key)}
.cl-comp .cl-btn{height:40px;padding:0 14px}
.cl-comp__n{position:absolute;right:12px;top:-20px;font:700 11px var(--ui);color:#5A6478}
/* the emoji picker: user content only — a grid of Unicode emoji inside the
   popover; the button that opens it is an SVG smiley outline */
.cl-emo{position:absolute;left:8px;bottom:calc(100% + 6px);width:296px;max-width:calc(100% - 16px);padding:8px;background:#fff;border:2px solid var(--key);border-radius:14px;box-shadow:0 4px 0 var(--key);display:grid;grid-template-columns:repeat(8,1fr);gap:2px;z-index:5}
.cl-emo[hidden]{display:none}
.cl-emo button{height:32px;border:0;background:none;border-radius:8px;font-size:20px;line-height:1;cursor:pointer;padding:0}
.cl-emo button:hover{background:var(--yellow,#FDC107)}

/* ---- the phone ---------------------------------------------------------- */
@media (max-width:1023px){
  html[data-layout="stage"] .ov--clan .ov__panel{height:100%}
  .ov--clan{--cl-top:22px}
  .ov--clan .ov__body{padding:0 14px 18px}
  .cl-head{padding:0 56px 0 100px;margin-bottom:12px}
  .cl-head h2{font-size:24px}
  .cl-hero{grid-template-columns:1fr;gap:10px}
  .cl-lrow{grid-template-columns:40px minmax(0,1fr) auto;gap:6px 10px;padding:8px 10px 8px 8px}
  .cl-lrow__b{width:40px;height:40px;grid-row:1 / span 2}
  .cl-lrow .cl-stat{display:none}
  .cl-lrow .cl-stat--m{display:flex;grid-column:2;grid-row:2;flex-direction:row;align-items:baseline;gap:10px}
  .cl-stat--m b{font-size:15px}
  .cl-stat--m span{margin:0;font-size:12px}
  .cl-lrow .cl-btn{grid-column:3;grid-row:1 / span 2}
  .cl-form{grid-template-columns:1fr;gap:14px}
  .cl-bgrid{grid-template-columns:repeat(4,1fr)}
  .cl-b{grid-template-columns:1fr;gap:14px 0}
  /* `static` here only ever meant "not sticky" — but it also stopped being the
     containing block for .cl-plate::before, the pink banner, whose `inset:0`
     then resolved against .ov__body and painted a full-width strip across the
     top of the sheet instead of the plate's own header. It looked deliberate
     while the plate sat at the very top of a full-screen sheet with BACK and
     the X on that strip; on a page (site/page.js, 10 Sep) the plate is inset
     and the strip stayed edge-to-edge, sticking out past the plate's keyline
     on both sides. `relative` cancels the sticky just as well and puts the
     banner back inside the plate, clipped by its radius and overflow. */
  .cl-plate{position:relative;top:auto}
  .cl-badge{width:104px;height:104px}
  .cl-tile>span{font-size:12px}
  /* §3.4 on the phone the plate scrolls away and the TAB BAR sticks under BACK / X
     (both at top:12px; BACK is 40px tall, the X 44px, so 56px): clan.js syncBar()
     flags it .is-stuck once it has pinned, and the bar then wears the sheet's own sky
     up to the scrollport's top edge, so the rows pass under BACK / X, not around them.
     The 2px line is there unstuck too (transparent) so nothing jumps when it pins. */
  .cl-tabs{position:sticky;top:60px;z-index:2;margin:0 -14px 10px;padding:0;border-bottom:2px solid transparent}
  .cl-tabs__in{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none;padding:4px 14px 6px;-webkit-overflow-scrolling:touch}
  .cl-tabs__in::-webkit-scrollbar{display:none}
  .cl-tabs.is-stuck,.cl-tabs.is-stuck::before{background:var(--sky-sheet,#6FB5F2) radial-gradient(circle,rgba(255,255,255,.34) 1.2px,transparent 1.5px) 0 0/8px 8px}
  .cl-tabs.is-stuck{border-bottom-color:var(--key)}
  .cl-tabs.is-stuck::before{content:'';position:absolute;left:0;right:0;bottom:100%;height:60px}
  /* 11px sides and a 6px gap, not 14 and 8: with MEMBERS as an icon the four tabs are
     still 24px over a 375pt screen (iPhone SE / 13 mini), which is the width that has to
     fit, not the 390 the fix was measured on first. 4 tabs x 6px = the 24. */
  .cl-tab{font-size:15px;padding:9px 11px}
  .cl-tabs__in{gap:6px}
  /* MEMBERS IS THE ICON AND THE COUNT HERE (Luke, 14 Sep 2026). Four tabs were 420px
     inside a 378px scrollport at 390pt, so CHAT sat 42px off the right edge and the
     strip never scrolled itself to it. The word is clipped rather than removed, so the
     button still reads "Members 15" to a screen reader; an absolutely positioned child
     is out of flex flow, so it costs no width and no gap. .cl-tab carries a transform,
     which makes it the containing block for it. */
  .cl-tab__ic{display:block;width:20px;height:20px;flex:0 0 auto}
  .cl-tab--members .cl-tab__w{position:absolute;width:1px;height:1px;padding:0;margin:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  /* two lines: name + role, then points · species (· the owner's buttons) */
  .cl-mrow{grid-template-columns:36px minmax(0,1fr) auto auto;gap:2px 10px}
  .cl-mrow .cl-av{grid-row:1 / span 2}
  .cl-mrow .cl-who{grid-column:2;grid-row:1}
  .cl-mrow .cl-tag{grid-column:3 / span 2;grid-row:1;justify-self:end}
  .cl-mrow__k{grid-column:2;grid-row:2;font-size:14px}
  .cl-mrow__k small{font-size:12px}
  .cl-mrow__k--last{grid-column:3;grid-row:2;justify-self:end}
  .cl-mrow__kick{opacity:1;grid-column:4;grid-row:2;justify-self:end}
  .cl-clip{width:100%}
  .cl-clip__t{font-size:15px}
  .cl-boards{grid-template-columns:1fr}
  .cl-brow .cl-who{font-size:15px}
  .cl-brow__c{font-size:12px}
  .cl-msgg__h{font-size:15px}
  .cl-msgg__h time{font-size:12px}
  .cl-bub{font-size:15px}
  .cl-sys{font-size:12.5px}
  .cl-chat{height:auto;min-height:0;border:0;background:none;border-radius:0;overflow:visible}
  /* §3.6 on the phone the composer is sticky with an -18px bottom margin, so it rides 18px
     over the list's end; without room here the NEWEST line is clipped by it (measured at
     390x844: the last group's bottom 754 against the composer's top 744.4). 28px clears it. */
  .cl-chat__l{overflow:visible;padding:0 0 28px}
  /* the composer sticks to the sheet's bottom edge, above the safe area */
  .cl-comp{position:sticky;bottom:0;margin:0 -14px -18px;padding:8px 14px calc(8px + env(safe-area-inset-bottom,0px));border:0;border-top:2px solid var(--key);z-index:3}
  .cl-new{position:fixed;bottom:calc(var(--mh-nav,0px) + var(--mh-bot,0px) + 84px)}
  .cl-emo{left:14px}
  .cl-msg{font-size:14px}
  .cl-lbl{font-size:12px}
  .cl-bd__n{font-size:12px}
  .cl-up__note{font-size:13px}
  .cl-link__r code{font-size:13px}
  .cl-prow small{font-size:13px}
  .cl-stat span{font-size:12px}
  .cl-tab i{font-size:12px}
  .cl-form__r p,.cl-hero__c p{font-size:14px}
}

/* the volume period, under the tiles (LEAD-DECISIONS §6: 24H / 7D / 30D / ALL) */
.cl-per{display:flex;gap:4px;margin:8px 0 0}
.cl-per__b{flex:1;padding:4px 0;border:2px solid var(--key);border-radius:8px;background:#fff;font:900 11px var(--display);font-style:italic;letter-spacing:.06em;color:var(--key);cursor:pointer;line-height:1}
.cl-per__b:hover{background:var(--yellow,#FDC107)}
.cl-per__b.is-on{background:var(--acc);color:#fff}
@media (max-width:1023px){.cl-per__b{font-size:12px;padding:6px 0}}

/* ── THE CLAN CARD MUST NOT SCROLL ──────────────────────────────────────
   Luke, 11 Sep 06:26: "look at the clan card that's still scrollable", after
   saying it twice the night before. It was NOT reproducible signed out — a
   non-member sees no INVITE, no LEAVE and no CLAN LINK — which is why an
   earlier pass measured zero overflow and left it.
   Measured as a member: the plate's content is a fixed 589px, and .cl-plate is
   align-self:stretch, so it fits exactly until the window is short enough that
   the stretch falls under 589. That is a viewport height of about 740 — 19px
   over at 1512x740, 89px over at 1147x655. Deleting the plate's overflow is not
   the fix: it would put the whole page back to scrolling, which is what the
   overflow was added to stop. The content has to get smaller instead, and only
   where it has to.
   The badge carries most of it (120px square over a 74px band), so it and the
   margins between every block take the cut. Nothing here fires above 820px,
   where the plate already fits and is untouched. */
@media (min-width:1024px) and (max-height:820px){
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-plate{padding:12px 14px 12px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-plate::before{height:56px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-badge{width:76px;height:76px;margin-top:4px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-name{margin-top:6px;font-size:26px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-meta{margin-top:6px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-owner{margin-top:6px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-stats{margin-top:10px;gap:6px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-tile{padding:5px 10px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-per{margin-top:6px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-acts{margin-top:10px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-link{margin-top:8px}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-link .cl-lbl{margin-bottom:4px}
}

/* ── BOARDS: ONE AT A TIME, WITH A PODIUM ───────────────────────────────
   Luke, 11 Sep 06:28: "it should just be one leaderboard, and you pick at the
   top which one you want to click ... it has the same behaviour as the actual
   leaders page with the podiums."
   The plates are the leaders page's own .lbpod/.lbp, borrowed rather than
   re-drawn — the same move the clan Pokédex makes with .pf-dex. Two things
   have to be undone for a different container: leaderboard.css gives .lbpod
   -14px side margins to bleed past THAT page's padding, and .cl-panel has no
   horizontal padding to bleed into, so they would hang 14px out and be cut by
   the overflow-x:hidden above; and its sticky top is measured from this
   scroller, which is what keeps the podium in place while the rows climb. */
.cl-bpick{display:flex;gap:8px;margin:0 0 12px;flex-wrap:wrap}
.cl-bpick__b{flex:0 0 auto;padding:7px 13px;border:2px solid var(--key);border-radius:10px;
  box-shadow:0 3px 0 var(--key);background:#fff;color:var(--key);cursor:pointer;line-height:1;
  font:900 14px var(--display);font-style:italic;text-transform:uppercase;letter-spacing:.04em}
.cl-bpick__b:hover{background:var(--yellow,#FDC107)}
.cl-bpick__b.is-on{color:#fff;background:linear-gradient(180deg,var(--acc-hi),var(--acc) 48%,var(--acc-lo))}
.cl-bpick__b:active{transform:translateY(2px);box-shadow:0 1px 0 var(--key)}
/* THE BOARDS BEHAVE LIKE THE LEADERS PAGE (§1.1d). Luke, 11 Sep: "when we go
   onto the boards page on a clan and we scroll, the podium should be sticky,
   same as on the normal leaders page, where it says 'RIP points, species,
   biggest pull, etc.' That should all be sticky as well, and the 4, 5, 6, 7, 8,
   etc., should all fade behind the podium. Make sure that we can't see it
   above. When we start scrolling, we shouldn't be able to see everything
   scrolling behind the gaps in between, like the 2-1 podium and the 1-3
   podium."
   Measured before this, at 1147x655 with the panel scrolled 152: .cl-bpick and
   .lbpod.cl-pod were both `position:static` and travelled with the list (the
   picker from y159 to y7, the podium from y206 to y54), and no row carried an
   opacity at all. All four of his points were true.
   TWO STICKY ROWS, NOT ONE. He asks for the picker as well as the podium, which
   is where this differs from the leaders page — there the tab strip scrolls away
   and only the podium pins. The picker takes top:0 and the podium sits under it
   at --cl-pick-h, which clan.js measures because the picker wraps to two lines
   on a narrow panel.
   AND BOTH CARRY THE PAGE'S OWN GROUND, which is his fourth point and the one
   that does not follow from the other three. Three plates in a grid with a 10px
   gutter leave holes, and so do the gaps between the picker's pills; a row
   climbing behind would show through every one of them. Same construction as
   leaderboard.css: the identical plate at the identical `center center/cover`
   with background-attachment:fixed, so it is anchored to the viewport exactly as
   .bg is and the seam is invisible by construction rather than by a tint that
   nearly matches. The side margins are NOT borrowed — .cl-panel has no
   horizontal padding to bleed into and overflow-x:hidden above would cut them —
   so the beds span the panel's own width, which is also the rows' width. */
/* DESKTOP ONLY — .cl-panel is the scroller only at >=1024px (the block at :239).
   On the phone the whole page scrolls and .cl-tabs is already sticky at 60px,
   so a picker pinned to top:0 of a scroller that never scrolls would slide
   under the tab strip. The phone keeps the plain static podium it has today. */
@media (min-width:1024px){
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel[data-tab="boards"] .cl-bpick{
    position:sticky;top:0;z-index:5;margin:0;padding:0 0 12px;
    background:url(../bg-plate.png) center center/cover fixed no-repeat}
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel[data-tab="boards"] .lbpod.cl-pod{
    position:sticky;top:var(--cl-pick-h,44px);z-index:4;
    margin:0 0 12px;padding:0 0 12px;
    background:url(../bg-plate.png) center center/cover fixed no-repeat}
  /* NO TOP FEATHER ON BOARDS. The panel's ramp (--cl-fade) is there for a list
     whose first row crosses the top edge; here the picker is pinned at that edge
     from scrollTop 0 and is opaque, so nothing ever crosses it — and a mask fades
     a sticky cover and a row EQUALLY, so the ramp would sit permanently across the
     picker's own top once scrolled. The 34px bottom stays. (This is the same trap
     in a new place: at 07:11 the fixed 14px ramp took the picker to zero alpha and
     the row read as missing, "which is why the podium looked like it was sitting
     under the tab strip".) */
  html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel[data-tab="boards"]{
    -webkit-mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 34px),transparent 100%);
    mask-image:linear-gradient(180deg,#000 0,#000 calc(100% - 34px),transparent 100%)}
}

/* any other tab keeps the plain borrowed podium */
html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel .lbpod.cl-pod{
  margin:0 0 12px;padding:0 0 12px;background:none;position:static}
html[data-layout="stage"] .pg.ov--clan[data-view="clan"] .cl-panel .cl-blist{min-width:0}
