:root{
  --ink:#12161c;          /* page */
  --slate:#1a2029;        /* panes */
  --slate-2:#222a35;      /* rows */
  --line:#2f3946;
  --teal:#2bb3be;         /* the sheet's header teal */
  --orange:#ee7326;       /* the sheet's pick-number orange */
  --gold:#f2b01e;         /* fantasy points */
  --money:#7ce0a6;        /* every dollar value */
  --green:#3fbf7f;
  --pos-wr:#2bb3be;       /* unchanged, the sheet's teal */
  --pos-rb:#3fbf7f;
  --pos-qb:#f06fa8;
  --pos-te:#a78bfa;
  --pos-ink:#10161d;      /* text inside a filled position badge */
  --red:#e2574c;
  --pink:#e8577a;         /* relinquish */
  --blue:#4a9be8;         /* match */
  --text:#e8edf3;
  --muted:#8d9aab;
  --display:'Bitter',Georgia,serif;
  --ui:'Barlow',system-ui,-apple-system,sans-serif;
  --cond:'Barlow Condensed','Barlow',sans-serif;
  --r:10px;
}
*{box-sizing:border-box}
/* class selectors outrank the UA [hidden] rule, so pin it down globally */
[hidden]{display:none!important}
html,body{height:100%}
/* Chromium's font boosting reads this off the root element. */
html{-webkit-text-size-adjust:100%;text-size-adjust:100%}
:root{--sat:env(safe-area-inset-top);--sab:env(safe-area-inset-bottom)}
body{
  margin:0;background:var(--ink);color:var(--text);
  font-family:var(--ui);font-size:15px;line-height:1.45;
  -webkit-font-smoothing:antialiased;
  /* Kills the double-tap-to-zoom delay, and stops iOS inflating type when the
     phone is rotated. Pinch is handled in app.js. */
  touch-action:manipulation;
  -webkit-text-size-adjust:100%;
}
button,input,select{font-family:inherit;font-size:inherit;color:inherit}
/* Desktop browsers put spinner arrows on number inputs and let the mouse
   wheel change the value — an easy way to alter a bid by accident. */
input[type=number]{-moz-appearance:textfield;appearance:textfield}
input[type=number]::-webkit-outer-spin-button,
input[type=number]::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}
:focus-visible{outline:2px solid var(--teal);outline-offset:2px}

/* ── buttons ─────────────────────────────────────────── */
.btn{
  border:1px solid var(--line);background:var(--slate-2);color:var(--text);
  border-radius:8px;padding:9px 14px;cursor:pointer;font-weight:600;
  transition:background .15s,border-color .15s,transform .08s;
}
.btn:hover{background:#2b3542;border-color:#41506180}
.btn:active:not(:disabled){transform:translateY(2px)}
.btn:disabled{opacity:.4;cursor:not-allowed}
.btn-sm{padding:6px 11px;font-size:13.5px}
.btn-primary{background:var(--orange);border-color:var(--orange);color:#1a1005}
.btn-primary:hover{background:#ff8438;border-color:#ff8438}
.btn-ghost{background:transparent}
#logout{background:transparent;border-color:#5f2723;color:#ff9a92}
#logout:hover{background:var(--red);border-color:var(--red);color:#2a0b08}
.btn-quiet{color:var(--muted)}
.btn-warn{background:var(--gold);border-color:var(--gold);color:#2a1e04}
.btn-warn:hover{background:#ffc03a;border-color:#ffc03a}
.btn-go{background:var(--green);border-color:var(--green);color:#062015}
.btn-go:hover{background:#4fd291;border-color:#4fd291}
.btn-stop{background:var(--red);border-color:var(--red);color:#2a0b08}
.btn-stop:hover{background:#ef6a5f;border-color:#ef6a5f}
.btn-danger{background:transparent;border-color:#7a2c26;color:#ff9a92}
.btn-danger:hover{background:#e2574c1f;border-color:var(--red)}
.btn-match{background:var(--blue);border-color:var(--blue);color:#04131f}
.btn-match:hover{background:#5fabf2;border-color:#5fabf2}
.btn-let{background:var(--pink);border-color:var(--pink);color:#2a0710}
.btn-let:hover{background:#f2688a;border-color:#f2688a}

/* ── sign in ─────────────────────────────────────────── */
.gate{min-height:100dvh;display:grid;place-items:center;padding:24px;
  padding-top:calc(24px + var(--sat,0px));
  padding-bottom:calc(24px + var(--sab,0px));
  background:radial-gradient(1100px 600px at 50% -10%,#1c2836 0%,var(--ink) 62%)}
.gate-card{width:min(360px,100%);background:var(--slate);border:1px solid var(--line);
  border-radius:14px;padding:32px 28px 26px;text-align:center}
.gate-mark{font-size:30px;color:var(--red);line-height:1}
.gate-title{font-family:var(--display);font-weight:800;font-size:31px;margin:8px 0 0;letter-spacing:-.01em}
.gate-sub{margin:2px 0 22px;color:var(--muted);font-family:var(--cond);
  text-transform:uppercase;letter-spacing:.18em;font-size:12px}
.field{display:block;text-align:left;margin-bottom:14px}
/* Direct child only: as a descendant selector this also hit the pick badge,
   the penalty text and the passed note inside .bidin-row, which inherited the
   label's uppercase muted styling and a 5px bottom margin. */
.field > span,.bidin-head{display:block;font-size:11px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted);margin-bottom:5px;font-weight:600}
.field input{width:100%;background:var(--ink);border:1px solid var(--line);
  border-radius:8px;padding:10px 12px;font-size:16px}
.gate-card .btn{width:100%;margin-top:6px}
.gate-error{color:var(--red);font-size:13.5px;min-height:19px;margin:10px 0 0}

/* ── chrome ──────────────────────────────────────────── */
.app{height:100dvh;overflow:hidden;display:flex;flex-direction:column}
.topbar{display:flex;align-items:center;gap:20px;padding:10px 18px;
  background:var(--slate);border-bottom:1px solid var(--red);flex-wrap:wrap;
  position:relative;z-index:90}
.brand{display:flex;align-items:center;gap:9px;font-family:var(--display);
  font-weight:800;font-size:18px}
/* An inline SVG rather than U+2692: the glyph renders differently on every
   platform, and this one also feeds the home screen icon. */
.brand-mark{color:var(--red);display:flex;align-items:center}
.mark-svg{width:1.05em;height:1.05em;display:block}
.gate-mark .mark-svg{width:38px;height:38px;margin:0 auto}
.topbar-right{display:flex;align-items:center;gap:12px;margin-left:auto}
.me-text{line-height:1.15;text-align:right}
.me-text b{display:block;font-size:13.5px;font-weight:600}
.me-text span{font-size:10px;letter-spacing:.13em;text-transform:uppercase;color:var(--muted)}
/* Hidden on desktop; the name and Sign out button cover it there. */
.me-avatar{transition:transform .1s}
.me-avatar:active{transform:translateY(2px)}
.me-avatar{display:block;width:32px;height:32px;padding:0;flex:0 0 auto;
  border:1px solid var(--line);border-radius:50%;background:var(--slate-2);
  overflow:hidden;cursor:pointer;-webkit-tap-highlight-color:transparent}
.me-avatar img{display:block;width:100%;height:100%;object-fit:cover;
  object-position:top center}
.me-initials{display:flex;align-items:center;justify-content:center;
  width:100%;height:100%;font-family:var(--cond);font-weight:700;font-size:13px;
  color:var(--muted)}
.account-row{display:flex;align-items:center;gap:14px}
.account-face{width:56px;height:56px;flex:0 0 auto;border-radius:12px;
  border:1px solid var(--line);background:var(--slate-2);overflow:hidden}
.account-face img{display:block;width:100%;height:100%;object-fit:cover;
  object-position:top center}
.account-face .me-initials{font-size:20px}
.account-row b{display:block;font-family:var(--display);font-size:20px;line-height:1.2}
.account-row span{font-family:var(--cond);font-size:12px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted)}

.adminbar{display:flex;align-items:center;gap:8px;flex-wrap:wrap;
  padding:9px 18px;background:#191f2a;border-bottom:1px solid var(--line)}

/* ── floating actions, bottom right (mobile only) ─────────────────── */
.fabs{display:flex;align-items:center;gap:8px;margin-left:auto;order:1}
.topbar-right .me-avatar{order:2}
.fabs[hidden]{display:none}
.fab{width:32px;height:32px;flex:0 0 auto;padding:0;border-radius:50%;
  border:1px solid #2b3542;background:var(--slate);color:var(--red);
  cursor:pointer;display:flex;align-items:center;justify-content:center;
  -webkit-tap-highlight-color:transparent;transition:transform .12s}
.fab:active{transform:translateY(2px)}
.fab:focus{outline:none}
.fab:focus-visible{outline:2px solid var(--teal);outline-offset:3px}
.fab-svg{width:22px;height:22px;display:block}
/* First in the bar, before the brand. */
.homefab{margin-right:10px;color:var(--muted);text-decoration:none}
.homefab:hover{color:var(--text);border-color:#3a4756}
.homefab .fab-svg{width:18px;height:18px}

/* ── full-screen sheets opened from the floating actions ──────────── */
/* With a sheet up, the page behind holds still — otherwise scrolling drags
   the banners and header out from under the frozen chrome. */
body.sheet-open{overflow:hidden}
.sheet{position:fixed;top:var(--chrome-h,0px);right:0;left:0;
  height:calc(var(--app-h, 100dvh) - var(--chrome-h, 0px));z-index:70;
  padding:8px 0 0;box-sizing:border-box;
  opacity:0;visibility:hidden;
  transition:opacity .24s cubic-bezier(.32,.72,0,1),visibility 0s linear .24s;
  display:flex;align-items:center;justify-content:center;
  padding:12px 12px calc(12px + var(--sab,0px));
  background:#080b0fa6;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
.sheet.open{opacity:1;visibility:visible;
  transition:opacity .24s cubic-bezier(.32,.72,0,1),visibility 0s}
.sheet .sheet-card{transform:translateY(-10px) scale(.985);opacity:0;
  transition:transform .26s cubic-bezier(.32,.72,0,1),opacity .24s ease-out}
.sheet.open .sheet-card{transform:none;opacity:1}
.sheet-card{display:flex;flex-direction:column;width:min(560px,100%);
  max-height:100%;min-height:0;flex:0 1 auto;background:#141a23f2;
  border:1px solid var(--line);border-radius:14px;overflow:hidden;
  box-shadow:0 22px 60px #000000b3}
/* Opens from inside the board sheet, so it has to sit above it — same
   z-index plus later-in-DOM would have put the board on top. */
#playerSheet{z-index:80}
/* Opens from inside the other sheets. The bid overlay (82) sits above it. */
#rosterSheet{z-index:79}
/* Filters change how many rows there are; the card shouldn't resize with
   them. */
#boardSheet .sheet-card{height:100%}
/* Opens from inside the expanded board (70), so it sits above it. */
#filterSheet{z-index:76}
/* The owner and position row, revealed by the Filters button. */
.sheet-subfilter{border-top:1px solid var(--line)}
.sheet-actions .btn.on{border-color:var(--teal);color:var(--teal)}
/* Filled once something is actually filtered, so the state is visible
   without opening the card. */
.sheet-actions .btn.active{background:var(--teal);border-color:var(--teal);
  color:#062026}
#boardClearMarks{background:var(--red);border-color:var(--red);color:#fff}
#boardClearMarks:hover{background:#ef6a60;border-color:#ef6a60}
/* Your own team in an owner picker. */
/* Your own team, in the open owner list. */
option.is-me{color:#fff;font-weight:700}
#filterSheet option.is-me,
#picksSheet option.is-me,
#rosterSheet option.is-me,
#draftSheet option.is-me{color:#fff;font-weight:700}

/* The filter card is content-sized, not full height. */
#filterSheet .sheet-card{height:auto}
#filterSheet .field{display:flex;align-items:center;gap:10px;margin-bottom:10px}
#filterSheet .field > span{flex:0 0 74px;font-family:var(--cond);font-size:11px;
  font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted)}
#filterSheet select{flex:1;min-width:0;background:var(--ink);
  border:1px solid var(--line);border-radius:8px;padding:9px;font-size:16px;
  color:var(--text)}
#picksSheet .sheet-filter{justify-content:flex-start}
#picksSheet .sheet-count{margin-left:0}
#picksSheet .sheet-count b{color:var(--money);font-size:14px}
/* Room to breathe, unlike the narrow rail pane. */
#picksSheetList{gap:7px}
#picksSheetList .pick{grid-template-columns:34px 1fr;gap:10px;padding:9px 11px}
#picksSheetList .pick-no{font-size:14px}
#picksSheetList .pick-val{font-size:18px}
#picksSheetList .pick-val.unl{font-size:13px}
#picksSheetList .pick-cost{font-size:11px}
#picksSheetList .pick-cost b{font-size:14px}
/* A fourth rounder buys nothing, so it reads as a note rather than a figure. */
.pick.nobid{opacity:.72}
.pick-val.nobid{color:var(--muted);font-family:var(--cond);font-size:12px;
  letter-spacing:.08em;text-transform:uppercase}
#picksSheetList .pick-val.nobid{font-size:13px}
.sheet-head{display:flex;align-items:center;justify-content:space-between;gap:12px;
  flex:0 0 auto;padding:12px 16px;background:#1a2029f2;
  border-bottom:1px solid var(--red)}
/* The whole title is the control: a native select sits invisibly over it so
   tapping the name opens the platform picker. */
.sheet-title{position:relative;display:flex;align-items:center;gap:8px;
  min-width:0;cursor:pointer}
.sheet-caret{flex:0 0 auto;font-size:11px;color:var(--muted)}
.sheet-title select{position:absolute;inset:0;width:100%;height:100%;
  opacity:0;cursor:pointer;font-size:16px}
.sheet-title b{text-decoration:none}
.sheet-head b{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-family:var(--cond);font-size:20px;font-weight:700;
  letter-spacing:.13em;text-transform:uppercase;color:var(--text)}
.sheet-x{width:36px;height:36px;flex:0 0 auto;padding:0;border:0;border-radius:50%;
  background:none;color:var(--muted);font-size:30px;line-height:1;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  -webkit-tap-highlight-color:transparent}
.sheet-x:focus{outline:none}
.sheet-x:hover{color:var(--text)}
.sheet-x:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
.sheet-filter{display:flex;align-items:center;gap:9px;flex:0 0 auto;
  flex-wrap:wrap;row-gap:8px;padding:9px 16px;background:#161c25e6;border-bottom:1px solid var(--line)}
.sheet-filter label{font-family:var(--cond);font-size:10.5px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
#boardSheetFilter{flex:1 0 100%;justify-content:space-between}
#boardSheetFilter button{flex:1;white-space:nowrap}
.sheet-filter select{flex:1;min-width:0;background:var(--ink);
  border:1px solid var(--line);border-radius:7px;padding:6px 8px;
  font-size:16px;color:var(--text)}
.sheet-filter select:focus{outline:none;border-color:var(--teal)}
.sheet-count{flex:0 0 auto;font-family:var(--cond);font-size:11px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.sheet-actions{display:flex;gap:8px;flex:0 0 auto;padding:10px 16px;
  background:#161c25e6;
  border-bottom:1px solid var(--line)}
.sheet-actions .btn{flex:1;padding:7px 6px;font-family:var(--cond);
  font-size:10.5px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  white-space:nowrap}
.sheet-body{flex:1;min-height:0;overflow-y:auto;padding:14px 16px 20px}

/* An owner photo that opens their roster: same picture, now tappable. */
.ownerbtn{padding:0;border:0;background:none;cursor:pointer;display:flex;
  align-items:center;justify-content:center;
  -webkit-tap-highlight-color:transparent}
.ownerbtn:focus{outline:none}
.ownerbtn:focus-visible{outline:2px solid var(--teal);outline-offset:2px;
  border-radius:50%}
.ownerbtn{transition:transform .1s}
.ownerbtn:active{transform:scale(.94)}
.nom-rights .ownerbtn img{display:block}

/* One owner's roster */
.roster-cap{margin-left:auto;font-family:var(--cond);font-size:13px;
  letter-spacing:.06em;color:var(--muted);white-space:nowrap}
.roster-cap b{font-size:17px;color:var(--money)}
.rr-group{margin-bottom:16px}
.rr-head{display:flex;align-items:baseline;justify-content:space-between;
  padding:0 2px 6px;border-bottom:1px solid var(--line);margin-bottom:7px}
.rr-head b{font-family:var(--cond);font-size:15px;letter-spacing:.14em}
.rr-head span{font-family:var(--cond);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}
.rr-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;
  gap:5px}
.rr{display:flex;align-items:center;gap:10px;padding:6px 9px;
  background:var(--slate-2);border:1px solid transparent;border-radius:8px}
/* Still in play. */
.rr.state-rfa{border-color:#a06b1c}
/* Settled: won from another owner, or kept by matching. */
.rr.state-acquired,.rr.state-matched,.rr.state-kept{border-color:#2f8f5b}
.rr.state-tagged{border-color:var(--red)}
.rr.tappable{cursor:pointer;transition:transform .1s,background .1s}
.rr-name{display:flex;align-items:center;gap:4px;min-width:0}
.rr-nametext{min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.rr-name .rfa-stat{flex:0 0 auto;color:#4a5666}
.rr.tappable:hover .rfa-stat{color:var(--teal)}
.rr.tappable:active{background:#26303c;transform:scale(.99)}
.rr-face{width:34px;height:34px;flex:0 0 auto;border-radius:7px;overflow:hidden;
  background:#0f141b}
.rr-face img{display:block;width:100%;height:100%;object-fit:cover;
  object-position:top center}
.rr-face.blank{background:#141b24}
/* Team mark on the sub-line. Sized explicitly: .rr-face img would otherwise
   have stretched it across the whole photo. */
.rr-sub{display:inline-flex;align-items:center;gap:4px}
.rr-logo{width:13px;height:13px;flex:0 0 auto;object-fit:contain}
.rr-mid{flex:1;min-width:0;line-height:1.2}
.rr-name{display:block;font-size:14px;font-weight:600;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.rr-sub{font-family:var(--cond);font-size:10.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.rr.state-rfa .rr-sub{color:var(--gold)}
.rr.state-acquired .rr-sub,.rr.state-matched .rr-sub,
.rr.state-kept .rr-sub{color:var(--green)}
.rr.state-tagged .rr-sub{color:var(--red)}
.rr-sal{flex:0 0 auto;font-family:var(--cond);font-size:16px;font-weight:700;
  color:var(--money)}
.rr-rank{flex:0 0 auto;font-family:var(--cond);font-size:14px;font-weight:700;
  letter-spacing:.04em;color:var(--teal)}

/* Roster and picks side by side; the picks column drops below on a phone. */
.rr-split{display:grid;grid-template-columns:minmax(0,1fr) 172px;gap:16px;
  align-items:start}
.rr-main{min-width:0}
.rr-picks{min-width:0}
.rr-picklist{list-style:none;margin:0;padding:0;display:flex;
  flex-direction:column;gap:4px}
.rr-picklist li{display:flex;align-items:center;gap:6px;padding:5px 7px;
  background:var(--slate-2);border-radius:7px}
.rr-picklist .pick-chip{flex:0 0 auto;min-width:38px;padding:2px 6px;
  font-size:11px;line-height:1.35;text-align:center}
.rr-pickval{flex:1;min-width:0;font-family:var(--cond);font-size:13px;
  font-weight:700;color:var(--money);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
.rr-pickcost{flex:0 0 auto;display:inline-flex;align-items:baseline;gap:4px;
  font-family:var(--cond);font-size:9px;letter-spacing:.04em;
  color:var(--muted);white-space:nowrap}
.rr-pickcost b{font-size:12px;font-weight:700;color:var(--money)}
.rr-pickcost i{font-style:normal}
.rr-nopicks{margin:0;font-size:13px;color:#5a687a}
/* Later years: round badge, then who the pick came from. */
.rr-picklist li.future{gap:8px}
.rr-pickfrom{flex:1;min-width:0;font-family:var(--cond);font-size:11.5px;
  letter-spacing:.04em;color:var(--muted);white-space:nowrap;overflow:hidden;
  text-overflow:ellipsis}
/* A pick you started with reads differently from one you traded for. */
.rr-pickfrom.own{color:#5a687a}
.rr-picks .rr-group{margin-bottom:14px}

/* Lineup */
.rr-list.lineup{gap:6px}
.lu{display:flex;align-items:center;gap:9px}
.lu-slot{width:44px;flex:0 0 auto;font-family:var(--cond);font-size:12px;
  font-weight:700;letter-spacing:.1em;text-align:center;color:var(--muted)}
.lu-slot.pos-QB{color:var(--pos-qb)}
.lu-slot.pos-RB{color:var(--pos-rb)}
.lu-slot.pos-WR{color:var(--pos-wr)}
.lu-slot.pos-TE{color:var(--pos-te)}
.lu-slot.pos-FLEX,.lu-slot.pos-OP{color:var(--gold)}
.lu-slot.bn{color:var(--red)}
/* The bench, set apart from the starters above it. */
.rr-list.bench{margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
.lu-player{flex:1;min-width:0}
.lu-empty{flex:1;padding:10px 9px;border:1px dashed var(--line);border-radius:8px;
  font-family:var(--cond);font-size:12px;letter-spacing:.08em;
  text-transform:uppercase;color:#4a5666}

/* League access: who's here, and their sign-in details */
.people{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;
  gap:6px}
.person-pw{display:flex;align-items:center;gap:6px;flex:0 0 auto}
.person-pw-input{width:118px;background:var(--ink);border:1px solid var(--line);
  border-radius:7px;padding:6px 8px;font-family:var(--cond);font-size:13px;
  letter-spacing:.02em;color:var(--text)}
.person-pw-input::placeholder{font-size:10px;letter-spacing:.04em;
  text-transform:uppercase;color:#4a5666}
.person-pw-input:focus{outline:none;border-color:var(--teal)}
.person-pw-save{flex:0 0 auto}
.person{display:flex;align-items:center;gap:11px;padding:8px 10px;
  background:var(--slate-2);border:1px solid transparent;border-radius:9px}
.person.online{border-color:#2f8f5b}
.person-face{position:relative;width:36px;height:36px;flex:0 0 auto;
  border-radius:50%;overflow:visible;background:#0f141b;display:flex;
  align-items:center;justify-content:center;font-family:var(--cond);
  font-size:14px;font-weight:700;color:var(--muted)}
.person-face img{width:100%;height:100%;border-radius:50%;object-fit:cover;
  object-position:top center}
.person-initials{position:absolute;inset:0;display:flex;align-items:center;
  justify-content:center}
/* The presence dot, on the photo rather than beside it. */
.person-dot{position:absolute;right:-1px;bottom:-1px;width:11px;height:11px;
  border-radius:50%;background:#3f4b5c;border:2px solid var(--slate-2)}
.person.online .person-dot{background:var(--green)}
.person-mid{flex:1;min-width:0;line-height:1.25}
.person-name{display:block;font-size:14px;font-weight:600;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.person-sub{font-family:var(--cond);font-size:10.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.person.online .person-sub{color:var(--money)}

/* A settled row is history: no target colouring, nothing live about it. */
.rfa-row.done,.rfa-row.done.mine,.rfa-row.done.targeted,.rfa-row.done.live{
  background:var(--slate-2);border-color:transparent}
.rfa-row.done .rfa-name,.rfa-row.done .rfa-nametext,
.rfa-row.done .rfa-sub,.rfa-row.done .rfa-n{color:var(--muted)}
.rfa-row.done .pos{color:var(--muted)}
.rfa-row.done .rfa-logo{filter:grayscale(1);opacity:.55}
.rfa-row.done .rfa-stat{color:#4a5666}
.rfa-row.done .rfa-amt{color:var(--muted)}
/* Owner, arrow and salaries run past the row on a phone, so the line drifts
   back and forth rather than truncating. */
.rfa-row.done .rfa-sub{overflow:hidden;contain:paint}
.rfa-row.done .rfa-sub > span{display:inline-block;white-space:nowrap}
/* Only the lines that actually overflow drift, by exactly their overflow —
   measured after layout, since CSS can't work it out. */
.rfa-sub > span.drift{animation:sub-drift 9s ease-in-out infinite alternate}
@keyframes sub-drift{
  0%,16%{transform:translateX(0)}
  84%,100%{transform:translateX(var(--sub-shift, 0px))}
}
@media (prefers-reduced-motion:reduce){
  .rfa-sub > span.drift{animation:none}
}
/* One Shining Moment: a star instead of a nomination number, and a rule
   separating the group from the RFA class below. */
.rfa-row .rfa-n.rfa-star,
.rfa-row.done .rfa-n.rfa-star{color:#fff;font-size:13px;line-height:1}
.rfa-row.mine .rfa-n.rfa-star{color:var(--gold);font-size:13px;line-height:1}
/* Your own One Shining Moment player, named as such. */
.tgt-osm{letter-spacing:.02em}
.rfa-row.shining .rfa-name{font-weight:600}
.rfa-row.last-shining{position:relative;margin-bottom:11px}
.rfa-row.last-shining::after{content:"";position:absolute;left:8px;right:8px;
  bottom:-6px;height:1px;background:var(--line)}
.rfa-verdict{font-family:var(--cond);font-size:11px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase}
.rfa-verdict.matched{color:var(--green)}
.rfa-verdict.relinquished{color:var(--orange)}
.rfa-verdict.no_bids{color:#5a687a}
/* Tagged: the hammer's own red, so it reads apart from won or kept. */
.rfa-verdict.tagged{color:var(--red)}
.tgt-tagged{width:22px;flex:0 0 auto;display:flex;align-items:center;
  justify-content:center;color:var(--red)}
.tgt-tagged svg{width:15px;height:15px;display:block}
.rfa-row.done .tgt-tagged{color:var(--red)}
.tag-btn{border-color:var(--red);color:var(--red);background:none;
  font-family:var(--cond);font-size:11px;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase}
.tag-btn:hover{background:#e2574c1f}

/* The transfer, spelled out under the rights line. */
.nom-flow{display:flex;align-items:center;gap:10px;padding:10px 0 2px;
  flex-wrap:wrap}
.flow-owner{display:flex;align-items:center;gap:7px;font-size:13px;
  font-weight:600;min-width:0}
.flow-face{width:26px;height:26px;flex:0 0 auto}
.flow-face img{width:26px;height:26px;border-radius:50%;object-fit:cover;
  object-position:top center;display:block}
.flow-arrow{flex:0 0 auto;font-size:17px;color:var(--muted)}

/* Owner badges: a crown for the champion, a throne for the wooden spoon.
   Tucked into the bottom-right corner of the owner's photo. On the viewer's
   own row it stands in for the star. */
.has-badge{position:relative;overflow:visible}
.obadge{position:absolute;right:-4px;bottom:-4px;z-index:3;width:9px;
  height:9px;font-size:9px;line-height:1;pointer-events:none;
  /* A hairline of the pane colour, so it reads apart from the photo. */
  filter:drop-shadow(.7px 0 0 var(--slate)) drop-shadow(-.7px 0 0 var(--slate))
         drop-shadow(0 .7px 0 var(--slate)) drop-shadow(0 -.7px 0 var(--slate))}
.obadge.tiny{font-size:8px;width:8px;height:8px;right:-3px;bottom:-3px}
.lg-row.mine .lg-face.has-badge::after{display:none}

.obadge-trophy::after{content:"\1F3C6";position:absolute;right:0;bottom:0;
  animation:trophy-shine 9s ease-in-out infinite}
@keyframes trophy-shine{
  0%,86%{transform:none;filter:none}
  91%{transform:scale(1.18) rotate(-6deg);
    filter:drop-shadow(0 0 5px #ffd970) brightness(1.55) saturate(1.2)}
  96%{transform:scale(1.06) rotate(3deg);filter:none}
  100%{transform:none;filter:none}
}

/* A shade warmer than the stock porcelain, so it reads on a dark row. */
.obadge-throne::after{content:"\1F6BD";position:absolute;right:0;bottom:0;
  filter:sepia(.45) saturate(1.3) hue-rotate(-8deg) brightness(1.08)}
/* A squirt that arcs out of the bowl now and then. */
.obadge-throne::before{content:"";position:absolute;right:7px;bottom:3px;
  width:3px;height:3px;border-radius:50%;background:#7a4a1e;opacity:0;
  animation:throne-squirt 11s cubic-bezier(.3,-.4,.7,1.4) infinite}
@keyframes throne-squirt{
  0%,88%{opacity:0;transform:translate(0,0) scale(.5)}
  90%{opacity:1;transform:translate(-2px,-5px) scale(1)}
  94%{opacity:1;transform:translate(-6px,-1px) scale(.8)}
  98%{opacity:0;transform:translate(-9px,5px) scale(.4)}
  100%{opacity:0;transform:translate(0,0) scale(.5)}
}

/* The round photo in the draft summary carries one too. */
.dr-face .obadge{right:-2px;bottom:-2px}

@media (prefers-reduced-motion:reduce){
  .obadge-trophy::after,.obadge-throne::before{animation:none}
  .obadge-throne::before{display:none}
}

/* The FantasyPros mark, sitting in a stat card header. */
.fp-btn{flex:0 0 auto;width:20px;height:20px;padding:0;border:0;background:none;
  cursor:pointer;display:flex;align-items:center;justify-content:center;
  -webkit-tap-highlight-color:transparent}
.fp-btn img{display:block;border-radius:50%}
.fp-btn:active{transform:scale(.92)}
.fp-btn:focus{outline:none}
.fp-btn:focus-visible{outline:2px solid var(--teal);outline-offset:2px;
  border-radius:50%}
/* The collapsible header is itself a button, so the logo sits beside it. */
.stat-head-row{display:flex;align-items:center;gap:8px;padding-left:11px;
  background:#161c25;border-bottom:1px solid var(--line)}
.stat-head-row .stat-head{flex:1;padding-left:0;background:none;border-bottom:0}

/* Bid history: the reveal cards again, centred in the card. */
.bidhist{margin-top:12px}
.bidhist-count{margin-left:auto;font-family:var(--cond);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.bidhist .hist-inner{width:100%}
.bidhist-cards{box-sizing:border-box;width:100%;max-width:520px;margin:0 auto;
  padding:12px}
.bidhist-cards .card{height:46px}
.bidhist-cards .card-face{padding:0 11px;gap:9px}
.bidhist-cards .card-pic{width:26px;height:26px}
.bidhist-none{margin:0;padding:22px 12px;text-align:center;
  font-family:var(--cond);font-size:13px;letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted)}
.bidhist-took{margin:0 12px 12px;text-align:center;font-size:12px;
  color:var(--muted)}
.bidhist-took b{color:var(--text);font-family:var(--cond);font-size:14px}

/* Settled: a plain statement of fact under the header rule. */
.rfa-done-banner{margin:-14px -16px 14px;padding:8px 16px;
  background:#152a20;border-bottom:1px solid #2f8f5b;
  font-family:var(--cond);font-size:11.5px;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--green);text-align:center}
.rfa-done-banner b{color:#fff}
/* A relinquished player left the roster, so the banner carries the same
   orange the board verdict uses. */
.rfa-done-banner.relinquished{background:#2c1c0c;border-bottom-color:#8a5a1c;
  color:var(--orange)}
.rfa-done-banner.no_bids{background:#1a2029;border-bottom-color:#2b3542;
  color:var(--muted)}
.rfa-done-banner.tagged{background:#2a1413;border-bottom-color:#8a3a33;
  color:var(--red)}
.rfa-done-banner.no_bids b{color:var(--text)}

/* Salary that moved: the old figure struck through beside the new one. */
.sal-was{color:var(--muted);text-decoration-color:#5a687a;
  text-decoration-thickness:2px;font-weight:400;margin-right:2px}
.rfa-sal{color:var(--money);font-weight:600}
.rfa-row .rfa-sub .rfa-sal,
.rfa-row.done .rfa-sub .rfa-sal{color:var(--money)}
.rfa-row.done .rfa-sub .sal-was{color:var(--muted);
  text-decoration-color:#5a687a}

/* The winning bid was refused, so it reads as spent rather than won. */
.bidhist-cards.refused .card.top .card-front{background:var(--slate-2)}
.bidhist-cards.refused .card.top .card-front::before{display:none}
.bidhist-cards.refused .card.top .card-front::after{display:none}
.bidhist-cards.refused .card.top{filter:grayscale(1);opacity:.65}

/* Where every team stands. */
#leagueSheet .sheet-card,#rosterSheet .sheet-card,
#draftSheet .sheet-card{height:100%}
#signedSheet .sheet-card{height:100%}
.pane-signed .pane-head{gap:8px}
.pane-signed .signed-totals{margin-left:auto}
.lg-row{display:grid;
  grid-template-columns:minmax(0,1fr) 32px 18px 20px 36px 62px 46px;
  align-items:center;gap:2px;width:100%;padding:8px 3px;margin-bottom:4px;
  background:var(--slate-2);border:1px solid transparent;border-radius:8px;
  color:var(--text);font:inherit;text-align:left;cursor:pointer}
.lg-row{transition:transform .1s}
.lg-row:not(.lg-head):active{transform:scale(.99)}
.lg-row.mine{border-color:var(--gold)}
.lg-row.mine .lg-face::after{content:"\2605";position:absolute;right:-3px;
  bottom:-3px;font-size:10px;line-height:1;color:var(--gold);
  text-shadow:0 0 3px #000,0 0 3px #000}
.lg-row.mine .lg-face{position:relative}
.lg-row.broke{opacity:.55}
.lg-head{background:none;margin-bottom:9px;padding-bottom:6px;
  border-bottom:1px solid var(--line);cursor:default;
  font-family:var(--cond);font-size:10px;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted)}
.lg-team{display:flex;align-items:center;gap:4px;min-width:0}
.lg-face{width:18px;height:18px;flex:0 0 auto}
.lg-face img{width:18px;height:18px;border-radius:50%;object-fit:cover;
  object-position:top center;display:block}
.lg-name{min-width:0;font-size:10px;letter-spacing:-.03em;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.lg-num{font-family:var(--cond);font-size:11.5px;font-weight:700;
  text-align:center;letter-spacing:-.02em}
.lg-head .lg-num,.lg-head .lg-team{border:0;background:none;padding:0;
  font-family:var(--cond);letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted);cursor:pointer}
.lg-head .lg-num{font-size:8px;font-weight:700;line-height:1;text-align:center;
  letter-spacing:0;white-space:nowrap}
.lg-head .sorted{color:var(--teal)}
/* Borders, not characters: identical on every device. */
.lg-head i{display:inline-block;width:0;height:0;margin-left:3px;
  vertical-align:middle;border-left:3px solid transparent;
  border-right:3px solid transparent}
.lg-head i.desc{border-top:4px solid currentColor}
.lg-head i.asc{border-bottom:4px solid currentColor}
.lg-head .lg-team{font-size:9px;font-weight:700}
.lg-power{color:var(--money)}
.lg-none{color:var(--red);font-size:9.5px;letter-spacing:0;line-height:1.1;
  text-transform:uppercase}
.lg-dash{color:#4a5666}
.lg-num i{font-style:normal;font-size:inherit;color:var(--red)}
.lg-match{color:var(--gold)}
.lg-back{flex:0 0 auto;background:var(--red);border-color:var(--red);color:#fff}
.lg-roster{flex:0 0 auto;margin-left:auto;background:var(--green);
  border-color:var(--green);color:#062015}
#leagueSheet .sheet-filter{flex-wrap:nowrap}
/* The buttons live inside the count span, so that's what has to be the row
   — otherwise there's no free space for the margin to push against. */
#leagueSheet .sheet-count{display:flex;flex:1;align-items:center;gap:9px;
  min-width:0}
#leagueSheet .sheet-count .lg-roster{margin-left:auto}
.lg-roster:hover{background:#4fd08f;border-color:#4fd08f}
.lg-stripcount{flex:0 0 auto;white-space:nowrap}
/* The card names the team first, then what the card is. */
.lg-title-sub{color:#fff;font-weight:400}
.lg-sortnote{margin-left:auto;text-align:right;font-family:var(--cond);
  font-size:9px;letter-spacing:.04em;text-transform:uppercase;
  color:var(--teal);white-space:nowrap}
.lg-strip-note{margin-left:auto;font-family:var(--cond);font-size:11px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
#leagueSheet .sheet-filter{gap:10px}
.lg-back:hover{background:#ef6a60;border-color:#ef6a60}
/* The four figures behind a team's position. */
.lg-money{display:grid;gap:1px;background:var(--line)}
.lg-money-2{grid-template-columns:1fr 1fr}
.lg-money-3{grid-template-columns:1fr 1fr 1fr;border-top:1px solid var(--line)}
.lg-money-cell{display:flex;flex-direction:column;align-items:center;
  justify-content:center;gap:3px;padding:11px 6px;background:var(--slate)}
.lg-money-cell b{font-family:var(--cond);font-size:19px;font-weight:700;
  line-height:1.1;text-align:center}
.lg-money-3 .lg-money-cell b{font-size:16px}
.lg-money-cell i{font-style:normal;font-size:11px;color:var(--red)}
.lg-nopicks{font-style:normal;font-family:var(--cond);font-size:8.5px;
  font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--red)}
.lg-money-cell b.money{color:var(--money)}
.lg-money-cell span{font-family:var(--cond);font-size:9px;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--muted);
  text-align:center;line-height:1.2}
.lg-group{margin-bottom:10px}
.lg-group-body{padding:9px}
.lg-player{transition:transform .1s}
.lg-player:active{transform:scale(.99)}
.lg-player{display:flex;align-items:center;gap:8px;width:100%;padding:6px 8px;
  margin-bottom:4px;background:var(--slate-2);border:0;border-radius:7px;
  color:var(--text);font:inherit;text-align:left;line-height:1;cursor:pointer}
.lg-player-name{flex:1;min-width:0;font-size:13px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.lg-player-sal{font-family:var(--cond);font-size:14px;font-weight:700;
  color:var(--money)}

/* The running order: drag to move, or send a player straight up. */
.orderlist{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;
  gap:5px}
.ord{display:flex;align-items:center;gap:10px;padding:7px 9px;line-height:1;
  background:var(--slate-2);border:1px solid transparent;border-radius:8px;
  cursor:grab}
.ord{transition:transform .1s}
.ord:active{transform:scale(.99)}
.ord.dragging{opacity:.45}
.ord.over{border-color:var(--teal)}
.ord-n{width:22px;flex:0 0 auto;font-family:var(--cond);font-size:12px;
  color:var(--muted);text-align:center}
.ord-mid{flex:1;min-width:0}
.ord-name{display:flex;align-items:center;gap:6px;font-size:13.5px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ord-sub{font-family:var(--cond);font-size:10.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.ord-grip{flex:0 0 auto;font-size:16px;color:#4a5666;cursor:grab}
#orderSheet .sheet-card{height:100%}

/* Draft summary rows */
.dr-round{margin-bottom:18px}
.dr-head{display:flex;align-items:baseline;justify-content:space-between;
  padding:0 2px 7px;border-bottom:1px solid var(--line);margin-bottom:8px}
.dr-head b{font-family:var(--display);font-size:17px}
.dr-head span{font-family:var(--cond);font-size:11px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.dr-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px}
.dr-none{padding:10px 0;text-align:center;font-family:var(--cond);font-size:16px;
  color:#3b4756}
.dr-round.empty-round .dr-head{opacity:.55}
.dr-row{display:flex;align-items:center;gap:10px;padding:7px 9px;
  min-height:52px;box-sizing:border-box;
  background:var(--slate-2);border:1px solid transparent;border-radius:8px}
/* Your own picks: a rotating red ring. Rotated with transform rather than by
   animating the gradient's angle — there can be a dozen of these on screen,
   and repainting a conic gradient per row per frame is what makes it chug. */
.dr-row.mine{border-color:transparent;position:relative;overflow:hidden;
  contain:paint}
.dr-row.mine::before{content:"";position:absolute;left:50%;top:50%;
  width:112%;aspect-ratio:1;pointer-events:none;z-index:0;
  background:conic-gradient(#7a2c26,#e2574c,#ff9b2f,#ff5a4d,#c2352b,#e2574c,#7a2c26);
  transform:translate(-50%,-50%) rotate(0deg);
  animation:ring-spin 4.5s linear infinite}
.dr-row.mine::after{content:"";position:absolute;inset:1px;border-radius:7px;
  background:#191519;pointer-events:none;z-index:1}
.dr-row.mine > *{position:relative;z-index:2}
.dr-row.mine .dr-who b{color:var(--gold)}

/* The unlimited picks — the ones with no ceiling — get the full rainbow. */
.dr-row.unl{border-color:transparent;position:relative;overflow:hidden;
  contain:paint}
.dr-row.unl::before{content:"";position:absolute;left:50%;top:50%;
  width:112%;aspect-ratio:1;pointer-events:none;z-index:0;
  background:conic-gradient(#ff5a4d,#ff9b2f,#ffd23f,#3fbf7f,#2bb3be,#5b8cff,
    #a86bff,#ff5a4d);
  transform:translate(-50%,-50%) rotate(0deg);opacity:0;
  animation:ring-spin 5s linear infinite,ring-flash 10s ease-in-out infinite;
  animation-delay:0s,1.7s}
.dr-row.unl::after{content:"";position:absolute;inset:1px;border-radius:7px;
  background:#1a2333;pointer-events:none;z-index:1}
.dr-row.unl > *{position:relative;z-index:2}
/* Both at once: the owner treatment wins the ring and the base colour, and
   the rainbow sweeps across the gold rather than replacing it. */
.dr-row.mine.unl{--unl-base:var(--gold)}
.dr-row.mine.unl::before{
  background:conic-gradient(#7a2c26,#e2574c,#ff9b2f,#ff5a4d,#c2352b,#e2574c,#7a2c26);
  opacity:1;animation:ring-spin 4.5s linear infinite}
.dr-row.mine.unl::after{background:#191519}
.dr-row.unl .dr-bid{
  background:linear-gradient(100deg,
    var(--unl-base,#fff) 0 45%,#ff5a4d 47.5%,#ffd23f 49%,#3fbf7f 50.5%,
    #2bb3be 52%,#5b8cff 53.5%,var(--unl-base,#fff) 56% 100%);
  background-size:700% 100%;background-position:0% 0;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:unl-shine 10s ease-in-out infinite;
  animation-delay:1.7s;font-size:13px;letter-spacing:.02em}

/* Only the viewer's own face keeps its colour. */
.dr-face{position:relative;width:26px;height:26px;flex:0 0 auto;padding:0;
  border:0;background:none}
/* The circle and the greyscale live on the photo, so the badge beside it
   keeps its own shape and colour. */
.dr-face img{display:block;width:100%;height:100%;object-fit:cover;
  object-position:top center;border-radius:50%;background:var(--slate-2);
  filter:grayscale(1);opacity:.62}
.dr-row.mine .dr-face img{filter:none;opacity:1}
.dr-row .pick-chip{flex:0 0 auto;min-width:34px;text-align:center}
.dr-who{flex:1;min-width:0;line-height:1.2}
.dr-who b{display:block;font-size:13.5px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.dr-from{font-family:var(--cond);font-size:10.5px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--gold)}
.dr-vals{flex:0 0 auto;width:92px;text-align:right;line-height:1.15}
.dr-bid{display:block;font-family:var(--cond);font-size:15px;font-weight:700;
  color:var(--money)}
.dr-cost{font-family:var(--cond);font-size:10.5px;letter-spacing:.06em;
  color:var(--muted)}

/* ── the room clock, pinned under the topbar ──────────────────────── */
.roomclock{position:sticky;top:0;z-index:89;display:flex;align-items:center;gap:10px;
  padding:6px 18px;background:#161c25;border-bottom:1px solid var(--line)}
.roomclock-label{align-self:center;line-height:1;
  font-family:var(--cond);font-size:10.5px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.roomclock-label.swap{animation:label-roll .34s cubic-bezier(.22,.8,.3,1)}
@keyframes label-roll{
  from{opacity:0;transform:translateY(6px)}
  to{opacity:1;transform:none}
}
@media (prefers-reduced-motion:reduce){ .roomclock-label.swap{animation:none} }
.roomclock-num{font-family:var(--cond);font-size:20px;font-weight:700;line-height:1;
  color:#fff;font-variant-numeric:tabular-nums}
.roomclock-num.urgent{color:var(--red)}
.roomclock-num.paused{color:var(--muted)}
.roomclock-bar{flex:1;height:4px;border-radius:2px;background:#26303c;overflow:hidden}
.roomclock-bar i{display:block;height:100%;background:#fff;
  transition:width .25s linear}
.roomclock-bar i.urgent{background:var(--red)}
.roomclock-bar i.paused{background:#4a5666}

/* Room settings row, above the action bar. */
.autobar{gap:12px}
.ab-label{font-family:var(--cond);font-size:10.5px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted)}
.ab-field{display:flex;align-items:center;gap:5px;font-family:var(--cond);
  font-size:11px;font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  color:var(--muted)}
.ab-field input{width:52px;background:var(--ink);border:1px solid var(--line);
  border-radius:6px;padding:3px 6px;font-family:var(--cond);font-size:13px;
  font-weight:700;color:var(--text);text-align:center}
.ab-field input:focus{outline:none;border-color:var(--teal)}

/* The decision window echoes the countdown. */
.verdict-clock{display:flex;align-items:center;justify-content:center;gap:10px;
  margin:18px 0 14px;padding:10px 14px;border-radius:10px;
  background:#05070a;border:1px solid #2b3542;
  font-family:var(--cond);font-size:11.5px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:#fff;transition:border-color .2s,color .2s}
.verdict-clock b{font-size:21px;line-height:1;color:#fff;
  font-variant-numeric:tabular-nums}
.verdict-clock.urgent{border-color:var(--red);color:var(--red)}
.verdict-clock.urgent b{color:var(--red)}

/* Always-on scroll indicator: iOS hides native overlay scrollbars, so the
   picks list draws its own. */
.pane-picks{position:relative}
.pane-scroll{position:absolute;right:4px;width:4px;border-radius:2px;
  background:#ffffff0f;pointer-events:none;z-index:6;
  opacity:0;transition:opacity .35s ease .4s}
.pane-scroll.showing{opacity:1;transition:opacity .12s ease}
.pane-scroll::after{content:"";position:absolute;left:0;right:0;
  top:var(--thumb-t,0);height:var(--thumb-h,24px);
  background:var(--red);border-radius:2px}

/* ── the two top banners ──────────────────────────────────────────── */
.alerts{display:flex;flex-direction:column;position:relative;z-index:2}
/* The second ribbon slides up behind the first, so the first has to sit
   above it and the pair has to clip at the top. */
.alerts > .alert:first-child{position:relative;z-index:2}
.alerts > .alert{position:relative;z-index:1}
.alert.ascend{animation:ribbon-up .26s cubic-bezier(.4,0,.9,.4) forwards}
/* A restyle of the same player wipes across rather than switching outright. */
.alert-sweep{position:absolute;inset:0;z-index:2;pointer-events:none;
  opacity:0;
  background:linear-gradient(100deg, transparent 0 38%, #ffffff26 46%,
    #ffffff40 50%, #ffffff26 54%, transparent 62% 100%);
  background-size:260% 100%}
.alert.sweep .alert-sweep{animation:alert-sweep .5s cubic-bezier(.25,.6,.3,1) 1}
@keyframes alert-sweep{
  from{background-position:130% 0;opacity:1}
  to{background-position:-70% 0;opacity:0}
}
@media (prefers-reduced-motion:reduce){
  .alert.sweep .alert-sweep{animation:none;display:none}
}
.alert.descend .alert-body{animation:ribbon-down .3s cubic-bezier(.2,.8,.3,1)}
@keyframes ribbon-up{
  0%{transform:translateY(0);opacity:1}
  100%{transform:translateY(-100%);opacity:0}
}
@keyframes ribbon-down{
  0%{transform:translateY(-100%);opacity:0}
  60%{opacity:1}
  100%{transform:translateY(0);opacity:1}
}
@media (prefers-reduced-motion:reduce){
  .alert.ascend,.alert.descend .alert-body{animation:none}
}
/* Passed: the player is still next, but you've said no. Red wash, a red rule
   beneath, and PASS tiled behind everything at a slightly brighter red. */
.alerts .alert.passed .alert-body{background:#2a1210;
  border-bottom:1px solid var(--red)}
.alert.passed .alert-body::before{content:"";position:absolute;inset:0;
  z-index:0;pointer-events:none;
  background-image:repeating-linear-gradient(-24deg,
    transparent 0 2px, #e2574c26 2px 3px, transparent 3px 26px);
  /* The word itself, repeated across the strip. */
  background-image:url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='52' height='22'>\
<text x='1' y='8' font-family='Barlow Condensed,Arial Narrow,sans-serif'\
 font-size='7' font-weight='700' letter-spacing='1'\
 fill='%23e2574c' fill-opacity='0.07' transform='rotate(-12 1 8)'>PASS</text>\
<text x='27' y='19' font-family='Barlow Condensed,Arial Narrow,sans-serif'\
 font-size='7' font-weight='700' letter-spacing='1'\
 fill='%23e2574c' fill-opacity='0.07' transform='rotate(-12 27 19)'>PASS</text>\
</svg>");
  background-repeat:repeat}
/* Everything else rides above the tiling. */
.alert.passed .alert-face,.alert.passed .alert-pos,.alert.passed .alert-name,
.alert.passed .alert-info,.alert.passed .alert-away,.alert.passed .alert-tag{
  position:relative;z-index:1}
/* The team mark and position lose their colour — this isn't live any more. */
.alert.passed .alert-face img{filter:grayscale(1);opacity:.55}
.alert.passed .alert-pos{color:var(--muted)}
/* The pill matches the rule underneath. */
.alerts .alert.passed .alert-away{color:var(--red);border-color:var(--red)}
.alerts .alert.passed .alert-name{color:#f0928a}
.alerts .alert.passed .alert-body{--shine-tint:transparent}

/* The banner itself is always open; the drawer inside it is what collapses. */
.alert{display:grid;grid-template-rows:1fr}
.alert-clip{overflow:hidden;min-height:0}
.alert-body{position:relative;overflow:hidden;display:flex;align-items:center;
  gap:9px;width:100%;padding:8px 18px;border:0;border-bottom:1px solid transparent;
  background:none;color:inherit;font:inherit;text-align:left;cursor:pointer;
  -webkit-tap-highlight-color:transparent}
.alert-body:focus{outline:none}
.alert-body:focus-visible{outline:2px solid var(--teal);outline-offset:-2px}

/* Up next: the same green as the live board row, with a darker rule beneath.
   A rotating gradient on a 2px strip reads as a flicker, not a sweep. */
.alert.next .alert-body{background:#152a3f;border-bottom-color:#3a6ea8;
  color:var(--text)}
.alert.next .alert-away{color:var(--blue)}
/* Up next and on your board: same green as any other target, still labelled
   UP NEXT. Named with the container so it beats .alert.next above. */
.alerts .alert.next.ontarget .alert-body{background:#14301f;
  border-bottom-color:#2f8f5b;color:var(--money)}
.alerts .alert.next.ontarget .alert-away{color:var(--green);
  border-color:var(--green)}
.alerts .alert.next.ontarget .alert-body{--shine-tint:#3fbf7f2b}
/* The next player you're chasing. */
.alert.hot .alert-body{background:#14301f;border-bottom-color:#2f8f5b;
  color:var(--money)}
/* One of your own RFAs. */
.alert.mine .alert-body{background:#242118;border-bottom-color:#f2b01e4d;
  color:var(--gold)}
.alert.mine .alert-name{color:var(--gold)}


.alert-pos{font-family:var(--cond);font-size:11px;font-weight:700;
  letter-spacing:.08em;color:var(--pos-wr)}
.alert-pos.pos-RB{color:var(--pos-rb)}
.alert-pos.pos-QB{color:var(--pos-qb)}
.alert-pos.pos-TE{color:var(--pos-te)}
.alert-name{flex:0 1 auto;min-width:0;font-weight:700;font-size:13.5px;
  color:var(--text);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.alert-away{flex:0 0 auto;margin-left:auto;font-family:var(--cond);font-size:11px;
  font-weight:700;letter-spacing:.1em;text-transform:uppercase;padding:2px 7px;
  border-radius:5px;border:1px solid currentColor;background:#0000004d}
/* The tag sits with the name, so only the away badge is pushed right. */
.alert-tag{flex:0 0 auto}
.alert-info{margin-left:-3px;margin-right:2px}
.alert-info{width:13px;height:13px;flex:0 0 auto;color:currentColor;opacity:.6}
.alert-body:hover .alert-info{opacity:1}
.alert-tag{flex:0 0 auto;font-family:var(--cond);font-size:10px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--gold);
  border:1px solid #f2b01e66;background:#3d3219;border-radius:5px;padding:2px 7px}
.alert-face{width:26px;height:26px;flex:0 0 auto;border-radius:6px;
  display:flex;align-items:center;justify-content:center}
.alert-face img{display:block;width:100%;height:100%;object-fit:contain}

/* The player summary, folded away until the caret is tapped. */

/* A highlight sweeping across, idle for most of the cycle. */
.alert-body::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(105deg,transparent 26%,
    var(--shine-tint,#ffffff20) 50%,transparent 74%);
  transform:translateX(-140%);
  animation:alert-shine var(--shine-dur,22s) ease-in-out var(--shine-delay,0s) infinite}
.alert.hot .alert-body{--shine-tint:#3fbf7f2b}
.alert.mine .alert-body{--shine-tint:#f2b01e24}
@keyframes alert-shine{
  0%,88%{transform:translateX(-140%)}
  100%{transform:translateX(140%)}
}

/* ── the pinned bar shown once the bidding overlay is closed ──────── */
.bidresume{position:sticky;top:0;z-index:88;display:flex;align-items:center;gap:12px;
  padding:8px 18px;background:#1d2530;border-bottom:1px solid var(--teal)}
.bidresume-chip{display:flex;align-items:center;flex:0 0 auto}
.bidresume-chip .pick-chip{font-size:13px;padding:2px 7px}
.bidresume-txt{flex:1;min-width:0;font-size:13.5px;color:var(--text);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bidresume .btn{flex:0 0 auto}

/* The bidding overlay reuses the splash frame; only the head differs. */
.bidstage .splash-head{flex-direction:column;align-items:stretch;gap:0}
.bidhead-row{display:flex;align-items:center;gap:12px}
.bidstage .splash-head .modal-x{margin-left:0}

/* Third title line: the projected finish, which opens the projection. */
.splash-title .proj-line{display:block;margin-top:4px;font-family:var(--cond);
  font-size:12.5px;font-weight:500;letter-spacing:.1em;text-transform:uppercase;
  color:var(--blue)}
.projdrawer{display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .3s cubic-bezier(.33,0,.15,1)}
.projdrawer.open{grid-template-rows:1fr}
.projdrawer-clip{overflow:hidden;min-height:0;opacity:0;
  transition:opacity .2s ease .04s}
.projdrawer.open .projdrawer-clip{opacity:1}
.projdrawer .stat-grid{margin-top:12px;border:1px solid var(--line);
  border-radius:9px;overflow:hidden;background:var(--slate-2)}
.adminbar-label{font-family:var(--cond);text-transform:uppercase;letter-spacing:.16em;
  font-size:11px;color:var(--teal);font-weight:700;margin-right:4px}
.adminbar-actions{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.adminbar-timer{margin-left:auto;font-size:13px;color:var(--muted);display:flex;
  align-items:center;gap:6px}
.adminbar-timer input{width:62px;background:var(--ink);border:1px solid var(--line);
  border-radius:6px;padding:5px 8px}

.grid{flex:1;min-height:0;display:grid;
  grid-template-columns:372px minmax(0,1fr) 372px;
  /* Spending power sizes to its content; picks takes what's left; the last
     row holds Players Signed under the stage. */
  grid-template-rows:auto minmax(0,1fr) minmax(0,auto);
  gap:14px;padding:14px;align-items:stretch}
/* The commissioner has no team, so no rail — the stage takes the space. */
.grid.no-rail{grid-template-columns:minmax(0,1fr) 372px}
/* The rail dissolves so its panes can be placed individually. */
.rail{display:contents}
/* Explicit placement, desktop only — the phone lays these out with order
   and full-width rows, and would inherit these otherwise. */
@media (min-width:1081px){
  .pane-power{grid-column:1;grid-row:1}
  /* Runs to the bottom of the window. */
  .pane-picks{grid-column:1;grid-row:2/-1;min-height:0;display:flex;
    flex-direction:column;max-height:none}
  .pane-picks .pane-body{min-height:0;overflow-y:auto}
  .pane-stage{grid-column:2;grid-row:1/3}
  .pane-signed{grid-column:2;grid-row:3;max-height:34vh}
  .pane-board{grid-column:3;grid-row:1/-1}
  /* No rail: the stage and the board share two columns. */
  .grid.no-rail .pane-stage{grid-column:1;grid-row:1/3}
  .grid.no-rail .pane-signed{grid-column:1;grid-row:3}
  .grid.no-rail .pane-board{grid-column:2;grid-row:1/-1}
}
.grid > *{min-height:0}
.pane-picks{max-height:calc(52dvh - 130px)}
.pane-signed{min-height:0;display:flex;flex-direction:column}
.pane-signed .pane-body{min-height:0;overflow-y:auto}
.pane-board{min-height:0;display:flex;flex-direction:column}
.pane-board .pane-body{min-height:0;overflow-y:auto}

.pane-power .pane-body{padding:13px 14px 14px;overflow:visible;text-align:center}
.power-label{display:block;font-family:var(--cond);font-size:11px;font-weight:700;
  letter-spacing:.18em;text-transform:uppercase;color:var(--muted)}
.power-amt{display:inline-block;align-self:center;
  font-family:var(--cond);font-size:50px;font-weight:700;
  color:var(--text);line-height:1.02;letter-spacing:-.01em;
  margin:10px 0}
.power-amt.over{color:var(--red)}
/* Well funded: a hot fill. Nearly spent: a cold one. Each carries a small
   mark at the bottom right of the figure. */
.power-amt{position:relative}
.pane-power .pane-body{text-align:center}
.power-amt.rich::after,.power-amt.thin::after{position:absolute;
  left:-3px;top:-1px;font-size:9px;line-height:1;
  /* An outline in the pane's own colour that follows the glyph's silhouette
     rather than boxing it: chained drop-shadows expand the alpha a pixel in
     each direction, which a background disc can't do. */
  filter:drop-shadow(.7px 0 0 var(--slate)) drop-shadow(-.7px 0 0 var(--slate))
         drop-shadow(0 .7px 0 var(--slate)) drop-shadow(0 -.7px 0 var(--slate));
  /* The glyph is its own colour — keep the text gradient off it. */
  -webkit-text-fill-color:initial;color:initial}
.power-amt.rich::after{content:"\1F525"}
.power-amt.thin::after{content:"\2744\FE0F"}
.lg-money-cell b.power-amt{position:relative;display:inline-block;margin:0;
  font-size:19px;line-height:1.1;letter-spacing:-.01em}
.lg-money-cell b.power-amt.rich::after,
.lg-money-cell b.power-amt.thin::after{font-size:7px;left:-5px;top:-2px}
.power-amt.rich{background:linear-gradient(160deg,#ffd23f 0%,#ff9b2f 42%,
    #ff5a4d 78%,#e2574c 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.power-amt.thin{background:linear-gradient(160deg,#d6f2ff 0%,#8fd4f2 30%,
    #56b0e4 62%,#2f7fd0 100%);
  -webkit-background-clip:text;background-clip:text;color:transparent}
.power-amt.over{background:none;color:var(--red)}
.power-sub{display:block;font-family:var(--cond);font-size:15px;font-weight:700;
  letter-spacing:.02em;color:#5f6c7d}
.power-note{display:block;font-size:10px;color:#4e5a68;margin-top:10px}
.power-note b{color:var(--red);font-weight:700;text-decoration:underline}
.pane{background:var(--slate);border:1px solid var(--line);border-radius:var(--r);
  overflow:hidden;display:flex;flex-direction:column;max-height:calc(100dvh - 120px)}
/* Expand control beside the board's filters. Hidden until a phone width. */
.pane-expand{display:none;width:26px;height:26px;flex:0 0 auto;padding:0;border:0;
  border-radius:6px;background:none;color:var(--muted);cursor:pointer;
  align-items:center;justify-content:center;-webkit-tap-highlight-color:transparent}
.pane-expand svg{width:18px;height:18px;display:block}
.pane-expand:focus{outline:none}
.pane-expand:focus-visible{outline:2px solid var(--teal);outline-offset:1px}
.pane-head{background:#161c25;border-bottom:1px solid var(--line);
  padding:0 13px;min-height:39px;display:flex;align-items:center;
  font-family:var(--cond);font-size:12px;font-weight:700;letter-spacing:.16em;
  text-transform:uppercase;color:var(--muted)}
.pane-body{padding:13px;overflow:auto;flex:1;
  scrollbar-width:thin;scrollbar-color:var(--red) var(--slate)}
/* Track disappears into the pane; thumb and arrows pick up the hammer's red. */
.pane-body::-webkit-scrollbar{width:13px}
.pane-body::-webkit-scrollbar-track{background:var(--slate)}
.pane-body::-webkit-scrollbar-thumb{background:var(--red);border-radius:7px;
  border:3px solid var(--slate)}
.pane-body::-webkit-scrollbar-thumb:hover{background:#ef6a5f}
.pane-body::-webkit-scrollbar-corner{background:var(--slate)}
.pane-body::-webkit-scrollbar-button:single-button{background:var(--slate);
  display:block;height:13px;width:13px;background-repeat:no-repeat;background-position:center}
.pane-body::-webkit-scrollbar-button:single-button:vertical:decrement{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 3.6 L10 8.4 L3 8.4 Z' fill='%23e2574c'/></svg>")}
.pane-body::-webkit-scrollbar-button:single-button:vertical:decrement:hover{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 3.6 L10 8.4 L3 8.4 Z' fill='%23ef6a5f'/></svg>")}
.pane-body::-webkit-scrollbar-button:single-button:vertical:increment{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 9.4 L3 4.6 L10 4.6 Z' fill='%23e2574c'/></svg>")}
.pane-body::-webkit-scrollbar-button:single-button:vertical:increment:hover{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 9.4 L3 4.6 L10 4.6 Z' fill='%23ef6a5f'/></svg>")}
.head-count{font-style:normal;font-size:11px;color:var(--text);background:var(--slate-2);
  border-radius:4px;padding:1px 6px;margin-left:7px}
.pane-stage{min-height:460px}
.empty{color:var(--muted);font-size:13.5px;margin:6px 2px}

/* ── picks ───────────────────────────── */
.picks{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:5px}
/* align-items:stretch so the round block runs the full height of the row */
.pick{display:grid;grid-template-columns:44px 1fr auto;align-items:stretch;gap:9px;
  background:var(--slate-2);border:1px solid transparent;border-radius:8px;padding:7px 9px;
  transition:border-color .15s,background .15s}
.pick > *:not(.pick-no){align-self:center}
.pick-no{display:flex;align-items:center;justify-content:center;
  font-family:var(--cond);font-weight:700;font-size:15px;color:var(--pos-ink);
  background:var(--orange);border-radius:5px;text-align:center;padding:2px 0}
.pick-val{font-family:var(--cond);font-size:19px;font-weight:700;color:var(--money)}
.pick-val.unl{
  background:linear-gradient(100deg,
    var(--unl-base,#fff) 0 45%,#ff5a4d 47.5%,#ffd23f 49%,#3fbf7f 50.5%,
    #2bb3be 52%,#5b8cff 53.5%,var(--unl-base,#fff) 56% 100%);
  background-size:700% 100%;background-position:0% 0;
  -webkit-background-clip:text;background-clip:text;color:transparent;
  animation:unl-shine 10s ease-in-out infinite}
.pick-cost{font-size:11px;color:var(--muted)}
/* Unlimited picks: rainbow wordmark and a rotating ring, matching the draft
   summary so the same pick reads the same way in both places. */
.pick.unl{border-color:transparent;position:relative;overflow:hidden;
  contain:paint}
.pick.unl::before{content:"";position:absolute;left:50%;top:50%;
  width:118%;aspect-ratio:1;pointer-events:none;z-index:0;
  background:conic-gradient(#ff5a4d,#ff9b2f,#ffd23f,#3fbf7f,#2bb3be,#5b8cff,
    #a86bff,#ff5a4d);
  transform:translate(-50%,-50%) rotate(0deg);opacity:0;
  animation:ring-spin 5s linear infinite,ring-flash 10s ease-in-out infinite}
.pick.unl::after{content:"";position:absolute;inset:1px;border-radius:6px;
  background:var(--slate-2);pointer-events:none;z-index:1}
.pick.unl > *{position:relative;z-index:2}
.pick.armed{border-color:var(--teal);background:#1e3138;box-shadow:0 0 0 1px var(--teal) inset}
.pick.armed .pick-cost::after{content:' · on offer';color:var(--teal);font-weight:600}

/* ── players signed ──────────────────── */
.signed-totals{margin-left:auto;font-family:var(--cond);font-size:11px;
  letter-spacing:.06em;color:var(--muted)}
.signed-totals b{font-size:inherit;font-weight:700;color:inherit}
.sg-pen{color:var(--red)}

.sg{display:flex;align-items:center;gap:8px;padding:7px 9px;margin-bottom:5px;
  background:var(--slate-2);border-radius:7px;line-height:1}
.sg:last-child{margin-bottom:0}
.sg-logo{width:18px;height:18px;flex:0 0 auto;object-fit:contain;display:block}
.sg-who .pos{line-height:1}
.sg-right{line-height:1}
.sg-who{display:flex;align-items:center;gap:6px;flex:1;min-width:0;
  line-height:1}
.sg-name{min-width:0;font-size:13.5px;font-weight:600;color:var(--text);
  line-height:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.sg-rank{flex:0 0 auto;align-self:center;font-family:var(--cond);font-size:11px;
  line-height:1;letter-spacing:.04em;color:var(--teal)}
.sg-info{flex:0 0 auto;width:18px;height:18px;padding:0;border:0;background:none;
  color:#5a687a;cursor:pointer;display:flex;align-items:center;
  justify-content:center;-webkit-tap-highlight-color:transparent}
.sg-info{transition:transform .1s}
.sg-info:active{transform:scale(.9)}
.sg-info:hover{color:var(--teal)}
.sg-info:focus{outline:none}
.sg-info:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
.sg-right{display:flex;align-items:center;gap:8px;flex:0 0 auto}
.sg-right .pick-chip{font-size:10px;padding:1px 5px}
.sg-sal{font-family:var(--cond);font-size:15px;font-weight:700;line-height:1;
  color:var(--money)}

/* Boot splash. Black, the mark fades up, then the whole pane breaks apart
   and the shards fly, revealing whatever finished loading behind. */
/* No width or height here on purpose. Setting top/bottom AND a height
   over-constrains the box: the height wins, bottom is ignored, and any
   shortfall shows as a strip of page along the bottom edge. Insets alone
   always fill the viewport exactly, whatever the browser chrome is doing. */
.boot{position:fixed;inset:0;
  z-index:200;display:flex;align-items:center;justify-content:center;
  background:#000;overflow:hidden}
.boot[hidden]{display:none}
html.booting,html.booting body{background:#000}
/* Pages that fill themselves from state: keep the shell invisible until the
   first paint, so a card can't appear and then change under you. */
html.booting main,html.booting .topbar{opacity:0}
main,.topbar{opacity:1;transition:opacity .18s ease}

/* The pane itself, in pieces. Together they tile the screen exactly. */
.shard{position:absolute;top:-2px;left:-2px;right:-2px;bottom:-2px;
  background:#000;transform-origin:50% 50%}
.shard:nth-child(1){clip-path:polygon(0 0,52% 0,38% 34%,0 47%)}
.shard:nth-child(2){clip-path:polygon(52% 0,100% 0,100% 28%,38% 34%)}
.shard:nth-child(3){clip-path:polygon(100% 28%,100% 62%,63% 58%,38% 34%)}
.shard:nth-child(4){clip-path:polygon(100% 62%,100% 100%,66% 100%,63% 58%)}
.shard:nth-child(5){clip-path:polygon(66% 100%,30% 100%,41% 66%,63% 58%)}
.shard:nth-child(6){clip-path:polygon(30% 100%,0 100%,0 74%,41% 66%)}
.shard:nth-child(7){clip-path:polygon(0 74%,0 47%,38% 34%,41% 66%)}
.shard:nth-child(8){clip-path:polygon(38% 34%,63% 58%,41% 66%)}

.boot-face{position:relative;z-index:2;display:flex;flex-direction:column;
  align-items:center;gap:14px}
.boot-mark{display:block;color:var(--red);opacity:0;transform:scale(.86);
  animation:boot-in .52s cubic-bezier(.22,.9,.3,1) .06s forwards}
.boot-svg{width:78px;height:78px;display:block}
.boot-name{font-family:var(--display);font-size:20px;letter-spacing:.06em;
  color:var(--text);opacity:0;
  animation:boot-in .52s cubic-bezier(.22,.9,.3,1) .18s forwards}
@keyframes boot-in{to{opacity:1;transform:none}}

/* The break: a hammer-blow jolt, the mark snuffed out, then the shards go. */
.boot.done{background:transparent;pointer-events:none;
  animation:boot-jolt .16s ease-out forwards}
.boot.done .boot-face{animation:boot-snuff .18s ease-in forwards}
.boot.done .shard{animation:shard-fly .62s cubic-bezier(.3,.05,.6,1) .1s forwards}

@keyframes boot-jolt{
  0%{transform:translate(0,0)}
  35%{transform:translate(-3px,2px)}
  70%{transform:translate(2px,-2px)}
  100%{transform:translate(0,0)}
}
@keyframes boot-snuff{to{opacity:0;transform:scale(1.14)}}
@keyframes shard-fly{to{opacity:0}}

/* Each piece leaves in its own direction, so it reads as a break rather than
   a fade. The translate distances are in viewport units to clear any screen. */
.boot.done .shard:nth-child(1){--fx:-42vw;--fy:-38vh;--fr:-16deg}
.boot.done .shard:nth-child(2){--fx:34vw;--fy:-44vh;--fr:13deg}
.boot.done .shard:nth-child(3){--fx:52vw;--fy:-10vh;--fr:9deg}
.boot.done .shard:nth-child(4){--fx:46vw;--fy:36vh;--fr:-11deg}
.boot.done .shard:nth-child(5){--fx:6vw;--fy:52vh;--fr:5deg}
.boot.done .shard:nth-child(6){--fx:-40vw;--fy:40vh;--fr:14deg}
.boot.done .shard:nth-child(7){--fx:-50vw;--fy:6vh;--fr:-8deg}
.boot.done .shard:nth-child(8){--fx:0;--fy:-8vh;--fr:22deg}
.boot.done .shard{animation-name:shard-fly}
@keyframes shard-fly{
  0%{transform:translate(0,0) rotate(0);opacity:1}
  12%{transform:translate(0,0) rotate(0);opacity:1}
  100%{transform:translate(var(--fx,0),var(--fy,0)) rotate(var(--fr,0));
       opacity:0}
}

@media (prefers-reduced-motion:reduce){
  .boot-mark,.boot-name{animation:none;opacity:1;transform:none}
  .boot.done{animation:none;opacity:0;transition:opacity .3s}
  .boot.done .shard,.boot.done .boot-face{animation:none}
}

/* ── stage ───────────────────────────────────────────── */
.nom{display:flex;align-items:flex-start;gap:14px;flex-wrap:wrap}
.nom-art .nom-pos{position:absolute;top:-6px;left:-6px;z-index:2;
  font-family:var(--cond);font-weight:700;font-size:12px;letter-spacing:.1em;
  line-height:1.35;background:var(--pos-wr);color:var(--pos-ink);
  border-radius:6px;padding:2px 8px;box-shadow:0 0 0 2px var(--slate)}
.nom-art .nom-pos.pos-RB{background:var(--pos-rb);color:var(--pos-ink)}
.nom-art .nom-pos.pos-QB{background:var(--pos-qb);color:var(--pos-ink)}
.nom-art .nom-pos.pos-TE{background:var(--pos-te);color:var(--pos-ink)}
.nom-art .nom-pos.pos-WR{background:var(--pos-wr);color:var(--pos-ink)}
.nom-name{font-family:var(--display);font-weight:800;font-size:34px;line-height:1.05;margin:0}
/* The dynasty rank is a rating, not chrome — it gets its own colour. */
.dyn{color:var(--teal);font-weight:600}
.nom-meta{color:var(--muted);font-size:13.5px;margin:3px 0 0;
  font-family:var(--cond);font-size:15px;letter-spacing:.06em;text-transform:uppercase}
.nom-bio{margin:5px 0 1px;font-family:var(--cond);font-size:16px;font-weight:700;
  letter-spacing:.09em;text-transform:uppercase;color:var(--text)}
.nom-rights{display:flex;align-items:center;gap:10px;margin-left:auto;
  align-self:flex-start;margin-top:6px;text-align:right}
.nom-rights img{width:36px;height:36px;border-radius:8px;object-fit:cover;
  border:1px solid var(--line);background:var(--slate-2)}
.nom-rights .lbl{display:block;font-family:var(--cond);font-size:10px;font-weight:700;
  letter-spacing:.15em;text-transform:uppercase;color:var(--muted)}
.nom-rights .who{font-size:15px;font-weight:600;line-height:1.15}
@media (max-width:560px){
  .nom-rights{margin-left:0;margin-top:12px;text-align:left;flex-direction:row-reverse;
    justify-content:flex-end}
}
.nom-sal{font-family:var(--cond);font-weight:700;font-size:24px;color:var(--money);
  letter-spacing:0;white-space:nowrap}
.nom-name .sal-was{font-family:var(--cond);font-size:18px;margin-left:6px;
  margin-right:0}

.clock{display:flex;align-items:center;gap:12px;margin:20px 0}
.clock-num{font-family:var(--cond);font-size:44px;font-weight:700;line-height:1;
  min-width:66px;font-variant-numeric:tabular-nums}
.clock-bar{flex:1;height:7px;background:var(--slate-2);border-radius:99px;overflow:hidden}
.clock-fill{height:100%;background:#fff;border-radius:99px;transition:width .25s linear}
.clock.urgent .clock-num{color:var(--red)}
.clock.urgent .clock-fill{background:var(--red)}
/* Stopped clock: the number holds and the bar goes flat, so it reads as
   deliberately paused rather than broken. */
.clock.paused .clock-num{color:var(--muted)}
.clock.paused .clock-fill{background:var(--muted);transition:none}
.clock.paused .clock-num::after{content:" paused";font-size:14px;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted);vertical-align:middle;margin-left:8px}

/* ── the pick menu inside the bidding overlay ─────────── */
/* Tappable in the bid menu: a pick is a one-tap way to bid its value. */
.pick.pick-tap{cursor:pointer;transition:transform .1s,border-color .1s}
.pick.pick-tap:hover{border-color:var(--teal)}
.pick.pick-tap:active{transform:scale(.99)}
.pick.pick-tap:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
.pickmenu{border:1px solid var(--line);border-radius:9px;background:var(--slate-2);
  overflow:hidden;margin-bottom:14px}
.pickmenu-head{display:flex;align-items:center;gap:10px;width:100%;padding:9px 11px;
  background:none;border:0;color:inherit;font:inherit;cursor:pointer;text-align:left;
  -webkit-tap-highlight-color:transparent}
.pickmenu-head:focus{outline:none}
.pickmenu-head:focus-visible{outline:2px solid var(--teal);outline-offset:-2px}
.pickmenu-title{font-family:var(--cond);font-size:12px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
.pickmenu-max{margin-left:auto;font-size:12px;color:var(--muted)}
/* Matches the label beside it in face and size — only weight and colour
   separate them. */
.pickmenu-max b{font-family:inherit;font-size:inherit;font-weight:700;color:#fff}
/* Neon tubing: stroked outlines lit by stacked drop-shadows, each swaying on
   its own clock so they dance instead of pulsing together. */
.flame{display:inline-flex;align-items:center;gap:5px}
/* Sized in px: the svg inherits the 12px label size, not the 16px of the
   figure beside it, so em came out wrong here. overflow:visible keeps the
   glow from being cropped at the viewBox edge. */
.flame-svg{flex:0 0 auto;width:9px;height:10px;
  pointer-events:none;overflow:visible}
.flame-path{fill:none;stroke-linecap:round;stroke-linejoin:round;
  transform-box:fill-box;transform-origin:50% 100%}
.flame-a{stroke:#ff7a1a;stroke-width:4.4;
  filter:drop-shadow(0 0 2px #ffb066) drop-shadow(0 0 6px #ff7a1a)
         drop-shadow(0 0 13px #ff3d1a);
  animation:flame-sway 1.9s ease-in-out infinite alternate}
.flame-b{stroke:#ffd98a;stroke-width:3.2;
  filter:drop-shadow(0 0 2px #fff0c4) drop-shadow(0 0 6px #ffd23f)
         drop-shadow(0 0 11px #ff9b2f);
  animation:flame-sway-b 1.25s ease-in-out infinite alternate}
@keyframes flame-sway{
  from{transform:rotate(-8deg) scaleY(.93) scaleX(1.04)}
  to{transform:rotate(8deg) scaleY(1.07) scaleX(.96)}
}
@keyframes flame-sway-b{
  from{transform:rotate(11deg) scaleY(1.06) scaleX(.94)}
  to{transform:rotate(-11deg) scaleY(.92) scaleX(1.05)}
}
.pickmenu-caret{color:#5a687a;font-size:7px;transition:transform .2s}
.pickmenu.open .pickmenu-caret{transform:rotate(90deg)}
.pickmenu-more{display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .3s cubic-bezier(.33,0,.15,1)}
.pickmenu.open .pickmenu-more{grid-template-rows:1fr}
.pickmenu-clip{overflow:hidden;min-height:0;opacity:0;transition:opacity .2s ease .04s}
.pickmenu.open .pickmenu-clip{opacity:1}
.pickmenu-clip .picks{padding:0 11px 11px}
.pickmenu-clip .footnote{margin:0 11px 11px}

/* Nothing left to bid with. */
.overcap{display:inline-flex;align-items:center;font-family:var(--cond);font-weight:700;
  font-size:15px;letter-spacing:.14em;text-transform:uppercase;color:var(--red);
  border:1px solid #7a2c26;background:#e2574c14;border-radius:9px;padding:11px 16px}

.bidrow{display:flex;gap:9px;align-items:flex-end;flex-wrap:wrap;margin-top:16px}
.bidbtns{display:flex;gap:9px;align-items:stretch}

/* The standing bid, shown where the entry field was. */
.bidin-row{display:flex;align-items:center;justify-content:center;gap:10px;
  padding:0 12px;background:var(--ink);border:1px solid var(--line);
  border-radius:8px;height:var(--bid-h,46px);box-sizing:border-box}
/* Explicit height on the badge so it matches the figure's cap height rather
   than whatever its own padding and line box happen to add up to. */
.bidin-row .pick-chip{flex:0 0 auto;display:inline-flex;align-items:center;
  height:22px;padding:0 8px;font-size:14px;line-height:1}
.bidin-amt{font-family:var(--cond);font-size:19px;font-weight:700;line-height:1;
  color:var(--money)}
/* Same type as the bid figure, so the two sit on one line without any
   per-element box fiddling. */
.bidin-pen{font-family:var(--cond);font-size:26px;font-weight:700;line-height:1;
  color:#ff4a3d;white-space:nowrap}
.bidin-passed{font-size:15px;color:var(--muted)}
.bidrow .field{margin:0}
/* The field and its stepper share one bordered box. */
.bidfield{position:relative;display:flex;align-items:stretch;width:150px}
.bidfield input[type=number]{flex:1;min-width:0;width:auto}
.bidstep{position:absolute;right:5px;top:5px;bottom:5px;display:flex;
  flex-direction:column;gap:2px}
.bidstep-btn{flex:1;width:26px;padding:0;display:flex;align-items:center;
  justify-content:center;background:var(--slate-2);border:1px solid var(--line);
  border-radius:5px;color:var(--text);font-size:10px;line-height:1;
  cursor:pointer;-webkit-tap-highlight-color:transparent;
  transition:transform .1s,background .1s}
.bidstep-btn:hover{background:#2b3542}
.bidstep-btn:active{transform:scale(.94)}
.bidstep-btn:disabled{opacity:.4;cursor:not-allowed}
.bidrow input[type=number]{width:150px;background:var(--ink);border:1px solid var(--line);
  border-radius:8px;padding:0 34px 0 12px;text-align:center;
  font-family:var(--cond);font-size:22px;font-weight:700}
/* The ceiling lives in the field itself until they type over it. */
.bidrow input[type=number]::placeholder{color:#5a687a;font-size:22px;font-weight:700;
  letter-spacing:.04em;text-align:center}
.bidrow input[type=number]:disabled{opacity:.45;cursor:not-allowed}
/* Same height as Submit and Pass, so the row reads as one control group. */
.bidrow .field input[type=number]{height:var(--bid-h,46px);box-sizing:border-box}
.bidbtns .btn{height:var(--bid-h,46px)}
.offer{margin-top:14px;padding:12px 14px;border-radius:9px;background:var(--slate-2);
  border-left:3px solid var(--teal);font-size:14px}
.offer.penalty{border-left-color:var(--red)}
.offer b{color:var(--money)}
.offer .warn{color:#ff9a92;font-weight:600}
.locked .btn{margin-top:9px}
.unl-pick{margin-top:-4px}
.unl-pick{margin-top:16px}
.unl-pick select{width:100%;background:var(--ink);border:1px solid var(--line);
  border-radius:8px;color:var(--text);font:inherit;font-size:15px;padding:9px 10px}
.unl-pick select:focus{outline:none;border-color:var(--teal)}
.locked{margin-top:14px;padding:12px 14px;border-radius:9px;background:#1e3138;
  border-left:3px solid var(--teal)}

.waiting{color:var(--muted);font-size:13.5px;margin-top:14px}
.waiting b{color:var(--text)}
.waiting-cta{text-align:center}
/* The box hugs the text rather than the container, so it reads as a notice. */
.cta-box{display:inline-block;font-weight:700;color:var(--text);
  border:1px solid var(--red);background:#e2574c14;border-radius:8px;
  padding:8px 15px;line-height:1.35;max-width:100%}
/* Fills the leftover height of the stage so the line sits midway between the
   card above it and the bottom of the pane. */
.pane-stage .pane-body{display:flex;flex-direction:column}
.pane-stage .pane-body > *{flex:0 0 auto}
.waiting-fill{flex:1 1 auto;display:flex;align-items:center;justify-content:center;
  text-align:center;margin-top:14px;min-height:56px}

/* ── the reveal (signature) ──────────────────────────── */
.reveal-head{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:12px}
.reveal-head h3{font-family:var(--display);font-size:19px;margin:0}
.reveal-head span{font-size:12px;color:var(--muted);letter-spacing:.1em;text-transform:uppercase}
.cards{display:flex;flex-direction:column;gap:7px}
.card{position:relative;perspective:900px;height:52px}
.card-inner{position:relative;z-index:1;width:100%;height:100%;transform-style:preserve-3d;
  transition:transform .55s cubic-bezier(.2,.75,.3,1)}
.card.open .card-inner{transform:rotateX(180deg)}
.card-face{position:absolute;inset:0;backface-visibility:hidden;border-radius:9px;
  display:flex;align-items:center;gap:12px;padding:0 14px;border:1px solid var(--line)}
.card-back{background:repeating-linear-gradient(135deg,#232c38 0 9px,#1e2530 9px 18px);
  justify-content:center;color:#3f4b5c;font-size:19px}
.card-front{background:var(--slate-2);transform:rotateX(180deg)}
.card-pic{flex:0 0 auto;width:30px;height:30px;border-radius:6px;
  object-fit:cover;object-position:top center;background:#0f141b}
/* The winning bid carries the same rotating rainbow edge as the row on the
   block in the board — see .rfa-row.live for how the ring is drawn. */
.card.top .card-front{background:#152a20;border-color:transparent;
  overflow:hidden}
.card.top .card-front::before{content:"";position:absolute;left:50%;top:50%;
  width:112%;aspect-ratio:1;pointer-events:none;z-index:0;
  background:conic-gradient(#14301f,#2f8f5b,#3fbf7f,#7ce0a6,#c9f7dd,#7ce0a6,
    #3fbf7f,#2f8f5b,#14301f);
  transform:translate(-50%,-50%) rotate(0deg);
  animation:ring-spin 4.5s linear infinite}
.card.top .card-front::after{content:"";position:absolute;inset:1px;
  border-radius:8px;background:#152a20;pointer-events:none;z-index:1}
.card.top .card-front > *{position:relative;z-index:2}

/* The winner's confetti: fires from the middle of the bar, behind it, up over
   the top edge, then falls past the losing bars and out of the card. Each
   piece gets its own drift, height, spin and delay from inline vars. */
.card-pop{position:absolute;left:50%;bottom:26px;width:0;height:0;
  z-index:0;pointer-events:none}
.card-pop i{position:absolute;left:0;top:0;width:7px;height:11px;margin:-5px -3px;
  opacity:0;animation:confetti 1.7s linear var(--d) both}
/* Easing lives on the keyframes, not the animation — a single curve across the
   whole thing warps the 40% peak well off where it reads. */
@keyframes confetti{
  0%{transform:translate(0,0) rotate(0deg) scale(.35);opacity:0;
     animation-timing-function:cubic-bezier(.12,.72,.35,1)}
  9%{opacity:1;animation-timing-function:cubic-bezier(.12,.72,.35,1)}
  40%{transform:translate(calc(var(--x) * .55), var(--rise))
      rotate(calc(var(--rot) * .45)) scale(1);opacity:1;
      animation-timing-function:cubic-bezier(.5,0,.85,.55)}
  82%{opacity:1;animation-timing-function:cubic-bezier(.5,0,.85,.55)}
  100%{transform:translate(var(--x), var(--fall)) rotate(var(--rot)) scale(1);opacity:0}
}
@media (prefers-reduced-motion:reduce){.card-pop{display:none}}
@media (prefers-reduced-motion:reduce){.card-pop{display:none}}
.card-rank{font-family:var(--cond);font-weight:700;color:var(--muted);width:24px}
.card-owner{font-weight:600;flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.card-amt{font-family:var(--cond);font-size:25px;font-weight:700;color:var(--money)}
.card-pick{font-family:var(--cond);font-weight:700;font-size:13px;background:var(--orange);
  color:#1a1005;border-radius:5px;padding:2px 7px}
.card-pen{font-size:11.5px;color:#ff9a92;font-weight:600}
.card.pass .card-amt{color:var(--muted);font-size:15px;font-family:var(--ui);font-weight:500}
.card.pass .card-front{opacity:.62}
/* Bids that didn't win recede: everything desaturated, the amount dropped to
   the same type as the name beside it. Filters go on the individual pieces
   rather than .card-front — a filter there would flatten the 3D flip. */
.card.lost .card-pic,.card.lost .card-pick,.card.lost .card-pen{filter:grayscale(1)}
.card.lost .card-owner{color:#93a1b2}
.card.lost .card-amt{font-family:var(--ui);font-size:15px;font-weight:600;
  color:#93a1b2}

/* ── stat tables under the player on the block ─── */
.statwrap{display:flex;flex-direction:column;gap:9px;margin-top:16px}
.stat-card{background:var(--slate-2);border:1px solid var(--line);border-radius:9px;
  overflow:hidden}
.stat-head{display:flex;align-items:center;gap:8px;padding:7px 11px;
  background:#161c25;border-bottom:1px solid var(--line)}
.stat-head b{flex:0 0 auto;line-height:1;font-family:var(--cond);font-size:11px;
  font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted)}
.stat-head .finish{margin-left:auto;font-family:var(--cond);font-size:13px;
  font-weight:700;line-height:1;color:var(--teal)}
.stat-card.proj .stat-head{background:#1b2530}
.stat-card.proj .stat-head b{color:var(--text)}
.stat-card.proj .stat-head .finish{color:var(--teal)}
.stat-grid{display:flex;flex-wrap:wrap}
.stat-grid{display:flex}
.stat-cell{flex:1 1 0;min-width:52px;padding:8px 6px;text-align:center;
  border-right:1px solid #2b3542}
/* Six or seven columns can't hold the default width on a narrow card, so
   they get tighter cells rather than wrapping onto a second line. */
.stat-grid.cells-6 .stat-cell{min-width:0;padding:8px 3px}
.stat-grid.cells-7 .stat-cell{min-width:0;padding:8px 2px}
.stat-grid.cells-6 .stat-cell b{font-size:16px}
.stat-grid.cells-7 .stat-cell b{font-size:14px}
.stat-grid.cells-6 .stat-cell span,
.stat-grid.cells-7 .stat-cell span{font-size:8.5px;letter-spacing:.02em}
.stat-cell:last-child{border-right:0}
.stat-cell b{display:block;font-family:var(--cond);font-size:19px;font-weight:700;
  line-height:1.1}
.stat-cell.pts b{color:var(--gold)}
.stat-cell span{font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}

.hist-head{width:100%;background:#161c25;border:0;border-bottom:1px solid var(--line);
  cursor:pointer;text-align:left;font:inherit;-webkit-tap-highlight-color:transparent}
.hist-head:focus{outline:none}
.hist-head:focus-visible{outline:2px solid var(--teal);outline-offset:-2px}
.hist-caret{margin-left:auto;color:#5a687a;font-size:7px;transition:transform .2s}
.hist-card.open .hist-caret{transform:rotate(90deg)}
.hist-more{display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .3s cubic-bezier(.33,0,.15,1)}
.hist-card.open .hist-more{grid-template-rows:1fr}
.hist-clip{overflow:hidden;min-height:0}

/* Separator between the forecast and the record. */
.stat-sep{height:1px;background:var(--line);margin:4px 2px}

/* Historical table: same type, sizes and dividers as the projected grid,
   laid out as rows so the years line up. */
.hist{width:100%;border-collapse:collapse;table-layout:fixed}
.hist th{font-family:var(--cond);font-size:9px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted);text-align:center;padding:7px 3px;
  border-right:1px solid #2b3542;border-bottom:1px solid var(--line);
  hyphens:none;word-break:normal}
.hist td{font-family:var(--cond);font-size:17px;font-weight:500;line-height:1.1;
  text-align:center;padding:9px 3px;white-space:nowrap;border-right:1px solid #2b3542;
  border-bottom:1px solid #2b354280}
.hist th:last-child,.hist td:last-child{border-right:0}
.hist tbody tr:last-child td{border-bottom:0}
.hist .c-year{color:var(--muted)}
.hist .c-fin{color:var(--teal);font-size:16px}
.hist .c-pts{color:var(--gold)}

/* ── pick colours ────────────────────────────────────────
   A pick's round is its rank: gold, silver, bronze, then the plain orange of
   the base badge for round four. One block for every badge that shows a pick
   number, so the three of them can't drift apart. */
.pick-no.r1,.pick-chip.r1{
  background:linear-gradient(155deg,#f8dc86 0%,#e0b44a 45%,#b3831f 100%)}
.pick-no.r2,.pick-chip.r2{
  background:linear-gradient(155deg,#eef3f8 0%,#c3ccd7 45%,#8d99a8 100%)}
.pick-no.r3,.pick-chip.r3{
  background:linear-gradient(155deg,#e8b189 0%,#c9834e 45%,#94582a 100%)}
.pick-chip{display:inline-block;font-family:var(--cond);font-weight:700;font-size:14px;
  line-height:1.35;color:var(--pos-ink);background:var(--orange);
  border-radius:5px;padding:1px 7px;vertical-align:baseline}

/* ── decision ────────────────────────────────────────── */
.verdict{border:1px solid var(--line);border-radius:11px;padding:20px;margin-top:16px;
  background:linear-gradient(180deg,#232c38,var(--slate-2))}
.verdict h3{font-family:var(--display);font-size:21px;margin:0 0 4px;text-align:center}
/* Their own threshold, shown where the decision is made. */
.threshold-banner{margin:-4px 0 14px;padding:9px 12px;border-radius:9px;
  background:#f2b01e1f;border:1px solid #f2b01e5c;text-align:center;
  font-family:var(--cond);font-size:12.5px;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:var(--gold)}
.threshold-banner span{opacity:.6;margin:0 2px}
.threshold-banner b{font-size:17px;color:#ffd36b}
.verdict .nom-meta{text-align:center}
.verdict .nom-meta .pick-chip{vertical-align:-2px;line-height:1;padding:2px 7px;
  margin:0 2px}

/* Two columns, each boxed in its own outcome colour and showing where the cap
   lands if you press that button. */
.verdict-choices{display:flex;flex-wrap:wrap;justify-content:center;align-items:stretch;
  gap:16px 20px;margin-top:20px}
.choice{flex:1 1 250px;max-width:330px;display:flex;flex-direction:column;
  align-items:center;text-align:center;gap:0;
  border:1px solid;border-radius:12px;padding:14px}
.choice.keep{border-color:#4a9be85c;background:#4a9be814}
.choice.let{border-color:#e8577a5c;background:#e8577a14}
.choice-kicker{display:block;width:100%;text-align:center;font-family:var(--cond);
  font-size:10px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;
  color:var(--muted);line-height:1.2;
  padding-bottom:8px;margin-bottom:10px;border-bottom:1px solid var(--line)}
.choice-head{width:100%;display:flex;align-items:center;justify-content:center;
  text-align:center;margin-bottom:18px;padding:9px 12px;
  border:1px solid;border-radius:9px}
.choice-title{font-size:13.5px;font-weight:600;color:var(--text);line-height:1.35;
  min-width:0}
/* The dollar figure sits in the same face and size as the name beside it —
   colour alone marks it out. */
.choice-title b{font-family:inherit;font-size:inherit;font-weight:700;
  color:var(--money);margin-left:5px}
/* line-height:1 keeps the chip inside the text's line box, so the boxed row
   is the same height on both sides. */
.choice-title .pick-chip{vertical-align:-1px;margin-right:1px;
  line-height:1;padding:2px 7px}
.title-pos{font-weight:400;color:var(--muted)}
.title-dot{color:#fff;margin:0 5px}
/* The two verbs carry their buttons' colours into the blurb. */
.verb-keep{color:var(--blue)}
.verb-money{color:var(--money)}
.verb-let{color:var(--pink)}
.choice.keep .choice-kicker{border-bottom-color:#4a9be83d}
.choice.let .choice-kicker{border-bottom-color:#e8577a3d}
.choice.keep .choice-head{border-color:#4a9be852;background:#4a9be81f}
.choice.let .choice-head{border-color:#e8577a52;background:#e8577a1f}

.choice-lines{display:flex;flex-direction:column;gap:3px;margin:auto 0}
.choice-line{font-size:12.5px;color:var(--muted)}
/* Values sit in the same face and size as their labels — only the weight
   and colour separate them. */
.choice-line b{font-family:inherit;font-size:inherit;font-weight:700;color:var(--text)}
.choice-line.power b{color:var(--text)}
.choice-line.power.over b{color:var(--red)}

.choice-rule{width:100%;height:1px;background:var(--line);margin:13px 0 15px}
.choice.keep .choice-rule{background:#4a9be83d}
.choice.let .choice-rule{background:#e8577a3d}
/* Both buttons are one fixed size and centre their contents, so the ring on
   one side can't make it taller than the other. */
.choice .btn{width:100%;height:52px;padding:0 14px;
  display:flex;align-items:center;justify-content:center;gap:8px;
  font-size:15.5px;line-height:1;white-space:nowrap}

.outcome{display:flex;align-items:center;gap:12px;margin-top:16px;padding:16px 18px;
  border-radius:11px;background:var(--slate-2);border-left:4px solid var(--muted)}
.outcome.matched{border-left-color:var(--blue);background:#152a3f}
.outcome.relinquished{border-left-color:var(--red);background:#2a1210}
.outcome-verb{font-family:var(--display);font-size:19px;color:#fff}
.outcome.matched .outcome-verb,
.outcome.relinquished .outcome-verb{color:#fff;font-weight:800}
.outcome.matched span,.outcome.relinquished span{color:var(--text)}

/* ── the board: full RFA class in nomination order ───── */
.pane-head{justify-content:space-between;gap:10px}
.seg{display:flex;gap:2px;background:var(--ink);border:1px solid var(--line);
  border-radius:7px;padding:2px}
.seg button{border:0;background:none;color:var(--muted);cursor:pointer;
  font-family:var(--cond);font-size:11px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;padding:3px 8px;border-radius:5px}
.seg button.on{background:var(--slate-2);color:var(--text)}
.seg button{transition:background .12s,color .12s,transform .08s,box-shadow .08s}
.seg button:active{transform:translateY(2px)}
.boardmore{display:block;width:100%;margin-top:8px;padding:9px 12px;
  background:var(--slate-2);border:1px solid var(--line);border-radius:8px;
  color:var(--muted);cursor:pointer;font-family:var(--cond);font-size:12px;
  font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  -webkit-tap-highlight-color:transparent}
.boardmore:hover{background:#2b3542;color:var(--text)}
.boardmore:focus{outline:none}
.boardmore:focus-visible{outline:2px solid var(--teal);outline-offset:-2px}
.pane-foot{border-top:1px solid var(--line);padding:9px 13px;background:#161c25;
  font-size:12.5px;color:var(--muted)}
.pane-foot b{color:var(--money);font-family:var(--cond);font-size:15px}

.rfa{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:3px;
  counter-reset:rfa}
.rfa-row{border-radius:8px;background:var(--slate-2);
  border:1px solid transparent}
.rfa-line{display:grid;grid-template-columns:22px 34px 27px minmax(0,1fr) auto;
  align-items:center;gap:0;padding:6px 9px}
.rfa-row.pending{background:transparent}
.rfa-row.done{opacity:.72}
/* your own restricted free agents — the ones you have to defend */
.rfa-row.mine{background:var(--slate-2);border-color:transparent}
.rfa-row.mine .rfa-name{color:#ffb765}
.rfa-row.mine .rfa-n{color:#8a6a3a}
/* On the block wins over every other row state. */
/* Composited: the browser can hand this to the GPU rather than repainting a
   conic gradient on every frame. */
@keyframes ring-spin{to{transform:translate(-50%,-50%) rotate(360deg)}}
/* The ring is absent most of the time, easing in and out once a cycle. */
@keyframes ring-flash{
  0%,72%{opacity:0}
  80%,90%{opacity:1}
  100%{opacity:0}
}
/* One pass of the band, then base colour again. Both ends of the sweep show
   only base colour, so the loop restart can't be seen. */
@keyframes unl-shine{
  0%,72%{background-position:0% 0}
  100%{background-position:100% 0}
}
@media (prefers-reduced-motion:reduce){
  .pick.unl::before,.dr-row.unl::before,.dr-row.mine::before,
  .card.top .card-front::before{animation:none}
  .pick-val.unl,.dr-row.unl .dr-bid{animation:none;background:none;color:#fff}
}
.rfa-row.live,.rfa-row.mine.live{background:#152a3f;border-color:#3a6ea8}
/* Up next, but you've passed on him. */
.rfa.capped .rfa-row.live.boardpass,
.rfa .rfa-row.live.boardpass,
.rfa-row.live.boardpass,.rfa-row.mine.live.boardpass{background:#2a1210;
  border-color:var(--red)}
.rfa-row.live.boardpass{position:relative}
.rfa-row.live.boardpass::before{content:"";position:absolute;inset:0;z-index:1;
  pointer-events:none;border-radius:inherit;overflow:hidden;
  background-image:url("data:image/svg+xml;utf8,\
<svg xmlns='http://www.w3.org/2000/svg' width='52' height='22'>\
<text x='1' y='8' font-family='Barlow Condensed,Arial Narrow,sans-serif'\
 font-size='7' font-weight='700' letter-spacing='1'\
 fill='%23e2574c' fill-opacity='0.07' transform='rotate(-12 1 8)'>PASS</text>\
<text x='27' y='19' font-family='Barlow Condensed,Arial Narrow,sans-serif'\
 font-size='7' font-weight='700' letter-spacing='1'\
 fill='%23e2574c' fill-opacity='0.07' transform='rotate(-12 27 19)'>PASS</text>\
</svg>");
  background-repeat:repeat}
.rfa-row.live.boardpass .rfa-nametext{color:#f0928a}
.rfa-row.live > *{position:relative;z-index:2}
.rfa-row.live .rfa-name,.rfa-row.live .rfa-n{color:var(--text)}
.rfa-n{font-family:var(--cond);font-size:12px;color:#5a687a;
  text-align:center;margin:0 9px}
/* Target crosshair at the head of the row */
.tgt-icon{width:22px;height:22px;padding:0;flex:0 0 auto;border:0;border-radius:50%;
  background:none;color:#5f6c7d;cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  transition:background .15s,color .15s;-webkit-tap-highlight-color:transparent}
/* Fills the button: the red rim left over is then the same weight as the
   rings themselves, and zero margin can't drift off the pixel grid. */
.tgt-icon svg{width:22px;height:22px;display:block}
.tgt-icon:focus{outline:none}
.tgt-icon:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
/* Selected: the ring stays put and a blue dot appears inside it. The halo
   ring and dot pulse once every few seconds rather than continuously. */
.tgt-dot,.tgt-halo{transform-box:fill-box;transform-origin:center;opacity:0}
.tgt-icon.on .tgt-dot{opacity:1;animation:tgt-pulse 4.5s ease-in-out infinite}
.tgt-icon.on .tgt-halo{animation:tgt-halo 4.5s ease-in-out infinite}
@keyframes tgt-pulse{
  0%,82%,100%{transform:scale(1)}
  88%{transform:scale(1.28)}
  94%{transform:scale(.94)}
}
@keyframes tgt-halo{
  0%,80%,100%{opacity:0;transform:scale(1)}
  86%{opacity:.55;transform:scale(1.12)}
  100%{opacity:0;transform:scale(1.45)}
}
@media (prefers-reduced-motion:reduce){
  .tgt-icon.on .tgt-dot,.tgt-icon.on .tgt-halo{animation:none}
  .tgt-icon.on .tgt-halo{opacity:0}
}
.tgt-spacer{width:22px}
.tgt-rfa{width:22px;flex:0 0 auto;text-align:center;font-family:var(--cond);
  font-size:9.5px;font-weight:700;letter-spacing:.02em;color:var(--gold)}
.tgt-poo{width:22px;flex:0 0 auto;text-align:center;font-size:13px;line-height:1}
.tgt-done{width:22px;height:22px;flex:0 0 auto;display:flex;align-items:center;
  justify-content:center;color:var(--green)}
.tgt-done svg{width:16px;height:16px;display:block}

/* The right-hand slot on a board row */
.marks{display:flex;align-items:center;gap:5px;flex:0 0 auto}

/* Prebid on a targeted player, threshold on one of your own. */
.notefield{display:flex;align-items:center;gap:4px;flex:0 0 auto}
.notefield-label{font-family:var(--cond);font-size:9.5px;font-weight:700;
  letter-spacing:.02em;text-transform:uppercase;color:var(--muted);
  white-space:nowrap}
/* The box holds the frame; the value and penalty are a centred pair inside
   it, both at the same size. Fixed outer width so rows stay aligned. */
.note-box,.pass-box{flex:0 0 auto;width:72px;min-height:27px;display:flex;
  align-items:center;justify-content:center;gap:4px;
  background:var(--ink);border:1px solid var(--line);border-radius:6px;
  padding:4px 5px}
.note-box:focus-within{border-color:var(--teal)}
/* Same box as the bid field; the word sits where the $ placeholder would. */
.pass-box{cursor:pointer;-webkit-tap-highlight-color:transparent;
  transition:border-color .15s}
.pass-box{transition:transform .1s}
.pass-box:active{transform:translateY(1px) scale(.97)}
.pass-box:focus{outline:none}
.pass-box:focus-visible{border-color:var(--teal)}
.pass-label{font-family:var(--cond);font-size:11.5px;font-weight:500;
  line-height:20px;color:#4a5666}
.pass-box.on{border-color:var(--red);background:var(--red)}
.pass-box.on .pass-label{color:#fff;font-weight:700}
.note-input{min-width:0;height:20px;line-height:20px;background:none;border:0;
  padding:0;font-family:var(--cond);font-size:11.5px;font-weight:700;
  color:var(--money);text-align:center}
.note-input:focus{outline:none}
.note-input::placeholder{color:#4a5666;font-weight:500}
.notefield.threshold .note-input{color:var(--gold)}
.notefield.threshold .note-input::placeholder{color:#7a6320;font-weight:700}
/* min-width keeps #6 and #11 the same size so the badges line up too. */
.note-chip{flex:0 0 auto;display:inline-flex;align-items:center;
  justify-content:center;min-width:28px;height:20px;padding:0 5px;
  font-size:11px;line-height:1}
.note-pen{flex:0 0 auto;display:inline-flex;align-items:center;height:20px;
  pointer-events:none;font-family:var(--cond);font-size:11.5px;font-weight:700;
  color:#ff4a3d;white-space:nowrap}

.rfa-row.targeted{border-color:#2f8f5b;background:#14301f}
.rfa-row.boardpass .rfa-n,
.rfa-row.boardpass .rfa-logo,
.rfa-row.boardpass .rfa-mid,
.rfa-row.boardpass .rfa-more{filter:grayscale(1);opacity:.5}
.seg button.targets.on{color:#ff9a92}
.seg button.mine.on{color:#ffb765}
.rfa-logo{width:20px;height:20px;object-fit:contain;margin-right:7px}
.rfa-mid{min-width:0;background:none;border:0;padding:0;text-align:left;
  color:inherit;font:inherit}
button.rfa-mid{cursor:pointer;-webkit-tap-highlight-color:transparent;
  transition:transform .1s}
button.rfa-mid:active{transform:scale(.985)}
button.rfa-mid:focus{outline:none}
button.rfa-mid:focus-visible{outline:2px solid var(--teal);outline-offset:2px;
  border-radius:4px}
/* Hover tint only where there's a real pointer. On a touch screen :hover
   sticks after a tap, which is the colour change that wouldn't go away. */
@media (hover:hover) and (pointer:fine){
  button.rfa-mid:hover .rfa-name{color:var(--teal)}
}
.rfa-stat{width:12px;height:12px;margin-left:3px;vertical-align:-2px;
  color:#5a687a;flex:0 0 auto}
.rfa-mid:hover .rfa-stat{color:var(--teal)}

/* the expanded per-player summary */
/* Collapsed height animates via grid-template-rows. The clipped element must
   carry no padding of its own — overflow:hidden cuts at the padding box, which
   leaks a strip of content into a closed row. */
.rfa-more{display:grid;grid-template-rows:0fr;
  transition:grid-template-rows .34s cubic-bezier(.33,0,.15,1)}
.rfa-row.open .rfa-more{grid-template-rows:1fr}
.rfa-more-clip{overflow:hidden;min-height:0;opacity:0;
  transition:opacity .22s ease .04s}
.rfa-row.open .rfa-more-clip{opacity:1}
.rfa-more-body{border-top:1px solid var(--line);padding:8px 9px 9px;
  background:#151b24;border-radius:0 0 7px 7px}
.facts-more{width:22px;height:22px;flex:0 0 auto;padding:0;border:0;
  background:none;color:var(--muted);cursor:pointer;
  display:flex;align-items:center;justify-content:center;
  -webkit-tap-highlight-color:transparent}
.facts-more svg{width:15px;height:15px;display:block}
.facts-more:focus{outline:none}
.facts-more:focus-visible{outline:2px solid var(--teal);outline-offset:1px}
.rfa-facts{display:flex;align-items:center;justify-content:space-between;gap:8px;
  font-family:var(--cond);font-size:12.5px;font-weight:700;
  letter-spacing:.08em;text-transform:uppercase;color:var(--text);margin-bottom:7px}
.mini{width:100%;border-collapse:collapse;table-layout:fixed}
.mini td{font-family:var(--cond);font-size:14px;font-weight:500;padding:3px 2px;
  border-bottom:1px solid #2b354266}
.mini tr:last-child td{border-bottom:0}
.mini .m-year{color:var(--muted);width:34%}
.mini .m-fin{color:var(--teal);text-align:center;width:30%}
.mini .m-pts{color:var(--gold);text-align:right}
.mini tr.proj .m-year{color:var(--text)}
.mini tr.proj td{border-bottom:1px solid var(--line);font-weight:700}
.rfa-name{display:flex;align-items:center;gap:4px;min-width:0;
  font-weight:400;font-size:13.5px}
.rfa-nametext{flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.rfa-name .rfa-stat{margin-left:0}
.rfa-row.targeted .rfa-name{font-weight:700}
.pos{color:var(--pos-wr);font-family:var(--cond);font-size:11.5px;
  font-weight:700;letter-spacing:.08em}
.rfa-name .pos{margin-right:5px}
.pos-RB{color:var(--pos-rb)}
.pos-QB{color:var(--pos-qb)}
.pos-TE{color:var(--pos-te)}
.rfa-sub{display:block;color:var(--muted);font-size:11.5px;white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.rfa-right{margin-left:10px;display:flex;align-items:center;gap:6px;justify-self:end;
  justify-content:flex-end}
/* Right column matches the Pass and $ boxes so the three line up. */
.rfa-amt{font-family:var(--cond);font-size:16px;font-weight:700;color:var(--money)}
.rfa-live{width:72px;flex:0 0 auto;text-align:center;font-family:var(--cond);
  font-size:11px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--green)}
.tag{font-size:10px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;
  padding:2px 5px;border-radius:4px;white-space:nowrap}
.tag.matched{background:#12352a;color:#6fe0aa}
.tag.relinquished{background:#3a2a14;color:#ffb765}
.tag.no_bids{background:#252d38;color:var(--muted)}
.footnote{font-size:11.5px;color:#5f6c7d;margin:10px 2px 0;line-height:1.4}

/* ── player art on the stage ─────────────────────────── */
.nom-art{position:relative;width:82px;height:82px;flex:0 0 auto}
.nom-shot{width:82px;height:82px;border-radius:11px;object-fit:cover;object-position:top center;
  background:var(--slate-2);border:1px solid var(--line);display:block}
.nom-mono{width:82px;height:82px;border-radius:11px;background:var(--slate-2);
  border:1px solid var(--line);display:grid;place-items:center;
  font-family:var(--display);font-weight:800;font-size:27px;color:#4d5a6b}
.nom-badge{position:absolute;right:-7px;bottom:-7px;width:34px;height:34px;
  border-radius:9px;background:var(--slate);border:1px solid var(--line);
  padding:3px;object-fit:contain}

/* ── modal / toast ───────────────────────────────────── */
.modal{position:fixed;inset:0;background:#080b0fcc;display:grid;place-items:center;
  padding:20px;z-index:92;animation:card-in .26s ease-out both}
.modal.closing{animation:card-out .24s ease-in both;pointer-events:none}
.modal.closing > .modal-card{animation:card-sink .24s ease-in both}
.modal-card{background:var(--slate);border:1px solid var(--line);border-radius:12px;
  width:min(560px,100%);max-height:82dvh;display:flex;flex-direction:column;
  animation:card-rise .34s cubic-bezier(.22,.7,.3,1) both}
.modal-head{display:flex;align-items:center;min-height:39px;padding:0 8px 0 14px;
  background:#161c25;border-bottom:1px solid var(--line);border-radius:12px 12px 0 0;
  font-family:var(--cond);font-size:12px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--muted);font-weight:700}
.modal-x{margin-left:auto;background:none;border:0;font-size:22px;color:var(--muted);
  cursor:pointer;line-height:1;padding:4px 9px}
.modal-body{padding:16px;overflow:auto}
.modal-note{color:var(--muted);font-size:13.5px;margin:0 0 14px}
#accountModal .modal-foot{justify-content:center}
.modal-foot{display:flex;gap:9px;justify-content:flex-end;flex-wrap:wrap;
  padding:12px 16px;background:#161c25;border-top:1px solid var(--line);
  border-radius:0 0 12px 12px}

/* Bid cap block / overbid confirmation.
   These fire from inside the bidding overlay, which is a .splash at z-index 50,
   so they have to clear it — at the shared .modal z-index of 40 they opened
   behind it and were invisible. */
#bidModal{z-index:84}
.modal-lead{font-size:15px;line-height:1.5;margin:0 0 14px;color:var(--text)}
#bidModalBody .modal-note{margin:14px 0 0}
.capsum{display:flex;flex-direction:column;border:1px solid var(--line);
  border-radius:9px;overflow:hidden}
.capsum-row{display:flex;align-items:baseline;justify-content:space-between;gap:12px;
  padding:8px 12px;font-size:13.5px;color:var(--muted);
  border-bottom:1px solid #2b3542}
.capsum-row:last-child{border-bottom:0}
.capsum-row b{font-family:var(--cond);font-size:18px;font-weight:700;color:var(--text)}
.capsum-row.bad{background:#e2574c14}
.capsum-row.bad b{color:var(--red)}
.reassign-row{display:flex;gap:9px;align-items:center;flex-wrap:wrap;margin-bottom:16px}
.reassign-row select{background:var(--ink);border:1px solid var(--line);border-radius:8px;padding:9px 10px}
.arrow{color:var(--muted)}
.ledger{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:8px}
.ledger-team{background:var(--slate-2);border-radius:8px;padding:9px 10px;font-size:12.5px}
.ledger-team b{display:block;margin-bottom:4px;font-size:13px}
.ledger-team span{color:var(--muted);font-family:var(--cond);font-size:14px;margin-right:6px}

/* ── the reveal splash ──────────────────── */
.splash{position:fixed;inset:0;z-index:82;display:grid;place-items:center;padding:20px;
  background:#080b0fee;backdrop-filter:blur(3px);animation:splash-in .22s ease}
@keyframes splash-in{from{opacity:0}to{opacity:1}}
/* The bidding overlay opens below the frozen chrome and grows downward: with
   the card centred it expanded in both directions, sliding up behind the
   clock as the pick menu opened. Declared after .splash so it actually wins. */
/* Centred in the space under the chrome. The top offset means a growing card
   still can't slide up behind the clock. */
.bidstage{top:var(--chrome-h,0px);align-items:center;padding-top:12px}
.bidstage .splash-card{max-height:calc(100dvh - var(--chrome-h,0px) - 32px)}
.splash-card{width:min(680px,100%);max-height:88dvh;display:flex;flex-direction:column;
  background:var(--slate);border:1px solid var(--line);border-radius:13px;overflow:hidden;
  box-shadow:0 24px 70px #000a}
.splash-head{display:flex;align-items:center;gap:12px;padding:14px 18px;
  background:#161c25;border-bottom:1px solid var(--line)}
/* Square, sized to the two title lines. aspect-ratio can't do this on its own:
   in a flex row the width is resolved before the stretched height is known, so
   the box collapses to its borders. */
.splash-head .face-wrap{position:relative;flex:0 0 auto;width:46px;height:46px;
  border-radius:9px;border:1px solid var(--line);
  background:var(--slate-2);overflow:hidden}
.splash-head img.face{position:absolute;inset:0;display:block;width:100%;height:100%;
  object-fit:cover;object-position:top center}
.splash-title{min-width:0;flex:1}
.splash-title > b{display:block;font-family:var(--display);font-size:21px;line-height:1.15}
.splash-title > span{display:block;font-family:var(--cond);font-size:11.5px;
  letter-spacing:.04em;text-transform:uppercase;color:var(--muted)}
.splash-title .name-money{color:var(--money);font-weight:700;white-space:nowrap}
.splash-step{font-family:var(--cond);font-size:11px;font-weight:700;letter-spacing:.15em;
  text-transform:uppercase;color:var(--teal);white-space:nowrap}
.splash-body{padding:16px 18px;overflow:auto;flex:1}
.splash-foot{display:flex;gap:9px;flex-wrap:wrap;align-items:center;
  padding:12px 18px;background:#161c25;border-top:1px solid var(--line)}
.splash-foot .spacer{flex:1}

/* ── bid breakdown on a settled row ───────── */
.bidlog{width:100%;border-collapse:collapse;margin-top:7px}
.bidlog caption{font-family:var(--cond);font-size:10px;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted);text-align:left;padding-bottom:4px}
.bidlog td{font-size:11.5px;padding:3px 2px;border-bottom:1px solid #2b354266}
.bidlog tr:last-child td{border-bottom:0}
.bidlog .b-who{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.bidlog .b-pick{font-family:var(--cond);font-weight:700;color:var(--orange);
  text-align:center;width:34px}
.bidlog .b-amt{font-family:var(--cond);font-weight:700;font-size:14px;color:var(--money);
  text-align:right;width:42px}
.bidlog tr.won .b-who{color:var(--text);font-weight:600}
.bidlog tr.out{opacity:.55}
.bidlog tr.out .b-amt{color:var(--muted)}
.rfa-export{display:block;width:100%;margin-top:2px;text-align:center}

.toast{position:fixed;left:50%;bottom:24px;transform:translateX(-50%);z-index:86;
  background:var(--slate-2);border:1px solid var(--line);border-left:3px solid var(--red);
  border-radius:9px;padding:11px 16px;font-size:14px;max-width:90vw}

/* ── responsive ──────────────────────────────────────── */
/* Phones and tablets: a coarse pointer catches an iPad in landscape,
   which is wider than any width breakpoint would allow for. */
/* Sheets get the same red scrollbar the panes use, and a deeper backdrop so
   the board behind reads as out of the way. */

.sheet-body::-webkit-scrollbar{width:13px}
.sheet-body::-webkit-scrollbar-track{background:var(--slate)}
.sheet-body::-webkit-scrollbar-thumb{background:var(--red);border-radius:7px;
  border:3px solid var(--slate)}
.sheet-body::-webkit-scrollbar-thumb:hover{background:#ef6a5f}
.sheet-body::-webkit-scrollbar-corner{background:var(--slate)}
.sheet-body::-webkit-scrollbar-button:single-button{background:var(--slate);
  display:block;height:13px;width:13px;background-repeat:no-repeat;background-position:center}
.sheet-body::-webkit-scrollbar-button:single-button:vertical:decrement{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 3.6 L10 8.4 L3 8.4 Z' fill='%23e2574c'/></svg>")}
.sheet-body::-webkit-scrollbar-button:single-button:vertical:decrement:hover{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 3.6 L10 8.4 L3 8.4 Z' fill='%23ef6a5f'/></svg>")}
.sheet-body::-webkit-scrollbar-button:single-button:vertical:increment{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 9.4 L3 4.6 L10 4.6 Z' fill='%23e2574c'/></svg>")}
.sheet-body::-webkit-scrollbar-button:single-button:vertical:increment:hover{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 9.4 L3 4.6 L10 4.6 Z' fill='%23ef6a5f'/></svg>")}
.sheet-body .rfa::-webkit-scrollbar{width:13px}
.sheet-body .rfa::-webkit-scrollbar-track{background:var(--slate)}
.sheet-body .rfa::-webkit-scrollbar-thumb{background:var(--red);border-radius:7px;
  border:3px solid var(--slate)}
.sheet-body .rfa::-webkit-scrollbar-thumb:hover{background:#ef6a5f}
.sheet-body .rfa::-webkit-scrollbar-corner{background:var(--slate)}
.sheet-body .rfa::-webkit-scrollbar-button:single-button{background:var(--slate);
  display:block;height:13px;width:13px;background-repeat:no-repeat;background-position:center}
.sheet-body .rfa::-webkit-scrollbar-button:single-button:vertical:decrement{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 3.6 L10 8.4 L3 8.4 Z' fill='%23e2574c'/></svg>")}
.sheet-body .rfa::-webkit-scrollbar-button:single-button:vertical:decrement:hover{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 3.6 L10 8.4 L3 8.4 Z' fill='%23ef6a5f'/></svg>")}
.sheet-body .rfa::-webkit-scrollbar-button:single-button:vertical:increment{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 9.4 L3 4.6 L10 4.6 Z' fill='%23e2574c'/></svg>")}
.sheet-body .rfa::-webkit-scrollbar-button:single-button:vertical:increment:hover{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 9.4 L3 4.6 L10 4.6 Z' fill='%23ef6a5f'/></svg>")}
#leagueBody::-webkit-scrollbar{width:13px}
#leagueBody::-webkit-scrollbar-track{background:var(--slate)}
#leagueBody::-webkit-scrollbar-thumb{background:var(--red);border-radius:7px;
  border:3px solid var(--slate)}
#leagueBody::-webkit-scrollbar-thumb:hover{background:#ef6a5f}
#leagueBody::-webkit-scrollbar-corner{background:var(--slate)}
#leagueBody::-webkit-scrollbar-button:single-button{background:var(--slate);
  display:block;height:13px;width:13px;background-repeat:no-repeat;background-position:center}
#leagueBody::-webkit-scrollbar-button:single-button:vertical:decrement{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 3.6 L10 8.4 L3 8.4 Z' fill='%23e2574c'/></svg>")}
#leagueBody::-webkit-scrollbar-button:single-button:vertical:decrement:hover{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 3.6 L10 8.4 L3 8.4 Z' fill='%23ef6a5f'/></svg>")}
#leagueBody::-webkit-scrollbar-button:single-button:vertical:increment{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 9.4 L3 4.6 L10 4.6 Z' fill='%23e2574c'/></svg>")}
#leagueBody::-webkit-scrollbar-button:single-button:vertical:increment:hover{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 9.4 L3 4.6 L10 4.6 Z' fill='%23ef6a5f'/></svg>")}
#draftBody::-webkit-scrollbar{width:13px}
#draftBody::-webkit-scrollbar-track{background:var(--slate)}
#draftBody::-webkit-scrollbar-thumb{background:var(--red);border-radius:7px;
  border:3px solid var(--slate)}
#draftBody::-webkit-scrollbar-thumb:hover{background:#ef6a5f}
#draftBody::-webkit-scrollbar-corner{background:var(--slate)}
#draftBody::-webkit-scrollbar-button:single-button{background:var(--slate);
  display:block;height:13px;width:13px;background-repeat:no-repeat;background-position:center}
#draftBody::-webkit-scrollbar-button:single-button:vertical:decrement{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 3.6 L10 8.4 L3 8.4 Z' fill='%23e2574c'/></svg>")}
#draftBody::-webkit-scrollbar-button:single-button:vertical:decrement:hover{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 3.6 L10 8.4 L3 8.4 Z' fill='%23ef6a5f'/></svg>")}
#draftBody::-webkit-scrollbar-button:single-button:vertical:increment{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 9.4 L3 4.6 L10 4.6 Z' fill='%23e2574c'/></svg>")}
#draftBody::-webkit-scrollbar-button:single-button:vertical:increment:hover{
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='13' height='13' viewBox='0 0 13 13'><path d='M6.5 9.4 L3 4.6 L10 4.6 Z' fill='%23ef6a5f'/></svg>")}
@media (min-width:1081px){
  .sheet{background:#04060999;
    backdrop-filter:blur(14px) saturate(.7) brightness(.55);
    -webkit-backdrop-filter:blur(14px) saturate(.7) brightness(.55)}
  /* Native pickers default to a light list; match the app. */
  .sheet select,.sheet option{background:var(--slate);color:var(--text)}
  .sheet select{color-scheme:dark}
}

/* A tablet's status bar overlays the web view even in standalone, and the
   safe-area inset can come back as zero — so guarantee clearance. */
@media (min-width:700px) and (pointer:coarse){
  html.standalone .topbar{padding-top:calc(8px + max(var(--sat,0px),22px))}
}

/* ── wide-screen sheets ───────────────────────────────────────────────
   The draft and the snapshot have far more room on a desktop than a phone,
   so they widen and lay out in columns rather than one long list. */
@media (min-width:1081px){
  #draftSheet .sheet-card{width:min(1500px,96vw);height:100%}
  #draftBody{min-height:0;overflow-y:auto}
  /* Twelve rows plus a heading have to clear the card's height, so the
     rows run tighter here than on a phone. */
  #draftBody .dr-row{min-height:42px;padding:5px 8px;margin-bottom:0}
  #draftBody .dr-list{gap:4px}
  #draftBody .dr-round{margin-bottom:10px}
  #draftBody .dr-head{margin-bottom:6px}
  #draftBody .dr-face{width:22px;height:22px}
  #draftBody .dr-who b{font-size:12.5px}
  #draftBody .dr-from{font-size:9.5px}
  #draftBody .dr-bid{font-size:14px}
  #draftBody .dr-cost{font-size:9.5px}
  #draftBody{column-gap:18px}
  .dr-round{break-inside:avoid;margin-bottom:14px}
  #leagueSheet .sheet-card,
  #rosterSheet .sheet-card{width:min(1180px,94vw)}
  /* Tall enough to be useful, never taller than the window. */
  #leagueSheet .sheet-card,#rosterSheet .sheet-card{height:100%}
  #leagueBody,#rosterBody{min-height:0;overflow-y:auto}
  /* Twelve rows fit in that height, so the list shouldn't need scrolling —
     the rows shrink a little rather than overflowing. */
  #leagueSheet .lg-row{padding:7px 14px;margin-bottom:3px}
  #leagueSheet .lg-face{width:28px;height:28px}
  #leagueSheet .lg-face img{width:28px;height:28px}
  /* Roomier rows, and every figure a size up. */
  #leagueSheet .lg-row{grid-template-columns:minmax(0,1fr) 90px 60px 62px 92px
    120px 104px;gap:8px}
  #leagueSheet .lg-name{font-size:15px;letter-spacing:0}
  #leagueSheet .lg-num{font-size:16px}
  #leagueSheet .lg-head .lg-num{font-size:11px;letter-spacing:.06em}
  #leagueSheet .lg-head .lg-team{font-size:11px}
  #leagueSheet .lg-face{width:32px;height:32px}
  #leagueSheet .lg-face img{width:32px;height:32px}
  #leagueSheet .lg-num i{font-size:12px}
}
/* Four rounds abreast once there's genuinely room. */
@media (min-width:1500px){ #draftBody{columns:4} }
/* Two on a mid-sized window. */
@media (min-width:1081px) and (max-width:1499px){ #draftBody{columns:2} }

/* Between the phone breakpoint and a comfortable desktop there isn't room
   for three columns. Rather than letting the stage wrap under the board,
   hand over to the same pop-out cards the phone uses. */
@media (min-width:1081px) and (max-width:1350px){
  .grid{grid-template-columns:372px minmax(0,1fr)}
  .grid.no-rail{grid-template-columns:minmax(0,1fr)}
  .pane-stage{display:none}
  /* The rail stacks down the left; the board takes the rest. */
  .pane-power{grid-column:1;grid-row:1}
  .pane-picks{grid-column:1;grid-row:2}
  .pane-signed{grid-column:1;grid-row:3;max-height:30vh}
  .pane-board{grid-column:2;grid-row:1/-1}
  .grid.no-rail .pane-board{grid-column:1;grid-row:1/-1}
}

@media (max-width:1080px), (pointer:coarse){
  /* Stacked layout, but spending power and picks ride at the top as a pair.
     display:contents dissolves the rail so its three panes place themselves
     directly on the grid and can be ordered independently — otherwise the
     signed-players pane would be dragged up with them. */
  /* One screenful, no page scroll: the rows are sized so the board takes
     what's left and Players Signed grows with its contents. */
  /* Height measured from visualViewport, not a viewport unit: dvh only
     updates after a scroll, and a fixed inset box sizes to the layout
     viewport, which never grows when the toolbar retracts. No `bottom` here
     — setting top, bottom and height at once over-constrains the box and the
     height silently wins. */
  .app{position:fixed;top:0;left:0;right:0;
    height:var(--app-h, 100dvh);overflow:hidden}
  /* The page behind is the app's own colour, so any strip the app doesn't
     cover is invisible rather than a lighter block. */
  html.standalone,html.standalone body{background:var(--ink)}
  /* The auction is a fixed pane, so the page behind it must not rubber-band.
     Scoped to that page: every other page is an ordinary scrolling document. */
  html:has(.app),html:has(.app) body{height:100%;overflow:hidden;
    overscroll-behavior:none;position:fixed;width:100%}
  /* Anything the measured height can't reach — a home-indicator inset, say —
     shows the app's own colour rather than a grey band. */
  html,body{background:var(--ink)}
  .grid,.grid.no-rail{grid-template-columns:1fr 1fr;
    grid-template-rows:auto minmax(120px,1fr) auto;
    gap:8px;align-items:stretch;align-content:stretch;min-height:0;
    overflow:hidden;
    padding-bottom:max(26px, calc(5px + var(--sat, 0px) / 3))}
  .grid > .pane{min-height:0}
  .pane-board{min-height:0}
  .pane-board .pane-body{min-height:0;overflow:hidden}
  /* Fills the row it's given rather than a fixed number of rows. */
  .rfa.capped{max-height:100%;height:100%;overflow-y:auto;
    overscroll-behavior:none;-webkit-overflow-scrolling:auto}
  /* Native overlay scrollbars already appear only while scrolling and always
     paint above content, so the drawn one isn't needed here. */
  .pane-scroll{display:none}
  .pane-body::-webkit-scrollbar,
  .rfa.capped::-webkit-scrollbar{width:5px}
  .pane-body::-webkit-scrollbar-track,
  .rfa.capped::-webkit-scrollbar-track{background:transparent}
  .pane-body::-webkit-scrollbar-thumb,
  .rfa.capped::-webkit-scrollbar-thumb{background:var(--red);border:0;
    border-radius:3px}
  .pane-body::-webkit-scrollbar-button:single-button{display:none}
  .pane-body,.rfa.capped{scrollbar-width:thin;
    scrollbar-color:var(--red) transparent}
  /* The drifting line on a settled row is transform-animated, so WebKit
     gives it its own layer — and a composited layer can paint over an
     overlay scrollbar. Keep the rows clear of the bar entirely. */
  .rfa.capped{margin-right:-11px;padding-right:11px}
  .pane-signed{max-height:38dvh}
  .pane-signed .pane-body{overflow-y:auto}
  #planFoot{display:none}
  .rail{display:contents}
  .pane{max-height:none}
  .pane-power{order:1;grid-column:1}
  .pane-picks{order:2;grid-column:2;max-height:166px}
  .pane-board{order:3;grid-column:1/-1}
  /* The stage has no room once the rail goes two-up; the player card opens
     as a pop-out instead. */
  /* No stage on a narrow layout — the player card opens as a pop-out. */
  .pane-stage{display:none}
  .pane-stage{order:4;grid-column:1/-1}
  .pane-signed{order:5;grid-column:1/-1}

  /* Half-width now, so the pick rows lose the third column and tighten up. */
  /* Centred, since this pane is stretched to match the taller picks pane. */
  .pane-power .pane-body{padding:10px;display:flex;flex-direction:column;
    justify-content:center}
  .power-amt{font-size:40px;margin:8px 0}
  .power-label{font-size:10px;letter-spacing:.14em}
  .power-sub{font-size:13px}
  .power-note{margin-top:8px}
  .pane-picks .pane-body{padding:9px}
  .picks{gap:4px}
  .pick{grid-template-columns:24px 1fr;gap:6px;padding:4px 6px}
  /* Bid value and contract share a line instead of stacking — halves the row
     height, which is what gets a useful number of picks on screen. nowrap so
     a long pair can never push the row or badge taller. */
  .pick > div{display:flex;align-items:center;gap:5px;flex-wrap:nowrap;min-width:0}
  .pick-val,.pick-cost{white-space:nowrap}
  .pick-cost{overflow:hidden;text-overflow:ellipsis}
  .pick-no{font-size:11.5px;border-radius:4px}
  .pick-val{font-size:14px}
  .pick-val.unl{font-size:9.5px;letter-spacing:0}
  .pick-cost{font-size:8.5px}
  /* The "acquired" tag is the first thing to go at this width. */
  .pick > .pick-cost:last-child{display:none}
  .pick.armed .pick-cost::after{content:' · offer'}
  .footnote{font-size:9.5px}
}
@media (max-width:560px){
  /* Freeze the bar to the top and keep brand, name and Sign out on one line —
     it wrapped to two rows and ate a chunk of a short screen. The horizontal
     padding also clears the notch/rounded corners, since the page is set to
     viewport-fit=cover and those insets are otherwise zero. */
  /* Sits directly under the frozen bar; --topbar-h is measured in app.js
     because the bar's height moves with the type. */
  .roomclock{top:var(--topbar-h,49px)}
  /* Pinned below the resume bar so the next two players stay in view while
     the board scrolls. Sheets sit above them, as before. */
  .alerts{position:sticky;top:var(--chrome-h,49px);z-index:27}
  .bidresume{top:var(--stack-h,49px);padding-left:16px;padding-right:16px;gap:10px}
  .bidresume-chip{display:flex;align-items:center;flex:0 0 auto}
.bidresume-chip .pick-chip{font-size:13px;padding:2px 7px}
.bidresume-txt{font-size:12.5px}
  /* The status bar sits over the web view in standalone mode, so the bar
     pads itself clear of the clock and battery while its background still
     runs to the top edge. */
  .topbar{position:sticky;top:0;z-index:90;gap:10px;flex-wrap:nowrap;
    padding-top:calc(8px + var(--sat,0px));padding-bottom:8px;
    padding-left:calc(16px + env(safe-area-inset-left));
    padding-right:calc(16px + env(safe-area-inset-right))}
  .brand{gap:6px;font-size:16px;min-width:0}
  .brand-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
  /* The name and Sign out button collapse into the avatar, which opens a
     sheet with both. Three items wouldn't fit on one line at this width. */
  .me-text,#logout{display:none}
  .me-avatar{display:block}
  .nom-name{font-size:27px}.clock-num{font-size:36px}

  .pane-expand{display:flex;margin-left:auto}
  /* Half-width pane: the title and the control only fit on one line if the
     title is allowed to shrink. */
  .pane-picks .pane-head{gap:6px;padding-left:10px;padding-right:8px}
  .pane-picks .pane-head > span{min-width:0;white-space:nowrap;
    overflow:hidden;text-overflow:ellipsis;font-size:11px;letter-spacing:.1em}
  .pane-picks .head-count{margin-left:5px}
  /* Four filters plus the control is tight; nowrap or the labels break
     across two lines inside their own pills. */
  .pane-board .seg button{padding:5px 6px;font-size:10px;letter-spacing:.02em;
    white-space:nowrap}
  .pane-board .pane-head{gap:6px}

  /* NEXT UP is folded into the top banner on a phone, so the pane would
     only repeat it. The commissioner keeps it — it carries their controls. */
  /* Two selects plus a count is a lot for one line at this width. */
  #boardSheet .sheet-filter select{flex:1 1 30%}
  /* Still two columns at this width — the player rows shrink to pay for it
     rather than the picks dropping below a long roster. */
  .rr-split{grid-template-columns:minmax(0,1fr) 140px;gap:10px}
  .rr-face{width:28px;height:28px;border-radius:6px}
  .rr-name{font-size:12.5px}
  .rr-sub{font-size:9.5px;letter-spacing:.04em}
  .rr-sal{font-size:14px}
  .rr-rank{font-size:12.5px}
  .rr{gap:7px;padding:5px 7px}
  .rr-head b{font-size:13px}
  .rr-head span{font-size:10px}
  .rr-picks .rr-head{gap:6px}
  .rr-picks .rr-head b,.rr-picks .rr-head span{white-space:nowrap}
  /* One line per pick: the badge and the rookie salary. The bid value is
     dropped here — it never fitted, and it is on the bidding screens. */
  .rr-picklist li{flex-wrap:nowrap;gap:6px;padding:5px 6px}
  .rr-picklist .pick-chip{min-width:34px;font-size:10px}
  .rr-pickval{display:none}
  .rr-pickcost{flex:1 1 auto;font-size:9.5px;overflow:hidden}
  .rr-pickcost b{font-size:12px}
  .rr-pickfrom{font-size:10.5px}
  /* Sit in the topbar beside the avatar rather than floating over the page. */
  .fabs{display:flex;gap:8px;position:static;margin-left:auto}
  .topbar .me{margin-left:8px}

  /* One row, with the filters centred: equal side columns put the middle on
     the container's centre line whatever the title and icon measure. */
  .pane-board .pane-head{display:grid;
    grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);
    min-height:0;padding:7px 9px}
  .pane-board .pane-head > span{justify-self:start}
  .pane-board .seg{justify-self:center}
  .pane-board .pane-expand{justify-self:end;margin-left:0}

  /* Clock pinned to the top of the overlay while the rest scrolls under it.
     The negative margins let it span the body's padding so nothing shows
     through at the edges. */
  .bidstage .splash-body{padding-top:0}
  .bidstage .clock{position:sticky;top:0;z-index:5;margin:0 -18px 18px;
    padding:18px 18px;background:var(--slate);border-bottom:1px solid var(--line)}
  /* Roughly the clock's height, so scroll-into-view lands below it rather
     than tucking the target underneath. */
  .bidstage .splash-body{scroll-padding-top:76px}
  .bidstage .bidrow,.bidstage .pickmenu,.bidstage .statwrap,
  .bidstage .locked,.bidstage .offer{scroll-margin-top:76px}

  /* Bid value in white here — the green reads as "money you have", which is
     not what a pick's bid ceiling is. */
  .pick-val{color:var(--text)}

  /* Field spans the width; the two buttons share the row beneath it. */
  .bidrow{flex-direction:column;align-items:stretch;gap:10px}
  .bidrow .field{width:100%}
  .bidrow input[type=number]{width:100%}
  .bidrow .bidfield{width:100%}
  .bidbtns{justify-content:center}
  /* Explicit flex + height: as plain blocks these were sizing off two line
     boxes and coming out 56px tall. */
  .bidbtns > *{flex:1 1 0;display:flex;align-items:center;justify-content:center;
    height:44px;padding:0 8px;white-space:nowrap;line-height:1}

  /* 16px is the threshold below which iOS zooms in on a focused field. */
  .note-input,.unl-pick select,#timerInput,#reassignPick,#reassignOwner{font-size:16px}
}
@media (prefers-reduced-motion:reduce){
  *{animation:none!important;transition-duration:.01ms!important}
}

/* A tablet's status bar overlays the web view even in standalone, and the
   safe-area inset can come back as zero — so guarantee some clearance for
   the clock and battery. Phones are already handled by --sat. */
@media (min-width:700px) and (pointer:coarse){
  html.standalone .topbar{padding-top:calc(8px + max(var(--sat,0px),22px))}
}

/* ── hub ──────────────────────────────────────────────────────────────
   The landing page: which tool are you here for. */
.hub{max-width:640px;margin:0 auto;padding:26px 16px 40px}
.hub-lead{margin:0 0 16px;font-family:var(--cond);font-size:12px;
  font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted)}
.hub-cards{display:flex;flex-direction:column;gap:12px}
.hub-card{display:flex;align-items:center;gap:14px;padding:16px;
  background:var(--slate);border:1px solid var(--line);border-radius:12px;
  color:var(--text);text-decoration:none;transition:transform .1s,border-color .1s}
.hub-card:hover{border-color:#3a4756}
.hub-card:active{transform:scale(.99)}
.hub-card-mark{flex:0 0 auto;width:44px;height:44px;display:flex;
  align-items:center;justify-content:center;border-radius:10px;
  background:var(--slate-2)}
.hub-card-mark svg{width:26px;height:26px}
.hub-card-mark.rfa{color:var(--red)}
.hub-card-mark.rookie{color:var(--teal)}
.hub-card-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}
.hub-card-text b{font-family:var(--display);font-size:19px}
.hub-card-text span{font-family:var(--cond);font-size:12px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.hub-card-go{flex:0 0 auto;font-size:20px;color:#4a5666}

@media (min-width:1081px){
  .hub{max-width:760px;padding-top:40px}
  .hub-card{padding:20px}
}

/* ── the sandwich menu and its drawer ─────────────────────────────────
   Mobile-first: on a wide screen the pages have room for their own links,
   so the button steps aside. */
.menubtn{display:flex;flex-direction:column;justify-content:center;gap:4px;
  width:34px;height:34px;padding:0 7px;flex:0 0 auto;background:none;border:0;
  cursor:pointer;-webkit-tap-highlight-color:transparent;
  transition:transform .1s}
.menubtn span{display:block;height:2px;border-radius:2px;background:var(--text);
  transition:transform .2s,opacity .2s}
.menubtn:active{transform:translateY(2px)}
.menubtn.on span:nth-child(1){transform:translateY(6px) rotate(45deg)}
.menubtn.on span:nth-child(2){opacity:0}
.menubtn.on span:nth-child(3){transform:translateY(-6px) rotate(-45deg)}

.drawer-wrap{position:fixed;inset:0;z-index:95}
.drawer-veil{position:absolute;inset:0;background:#04060999;opacity:0;
  transition:opacity .24s}
.drawer-wrap.open .drawer-veil{opacity:1}
.drawer{position:absolute;top:0;bottom:0;left:0;width:min(280px,82vw);
  display:flex;flex-direction:column;background:var(--slate);
  border-right:1px solid var(--line);
  padding:calc(14px + var(--sat,0px)) 0 14px;
  transform:translateX(-100%);transition:transform .26s cubic-bezier(.32,.72,0,1)}
.drawer-wrap.open .drawer{transform:none}
.drawer-head{display:flex;align-items:center;justify-content:space-between;
  padding:4px 16px 12px;border-bottom:1px solid var(--line);margin-bottom:8px}
.drawer-head b{font-family:var(--cond);font-size:12px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
.drawer-x{background:none;border:0;color:var(--muted);font-size:24px;
  line-height:1;cursor:pointer;padding:0 4px}
.drawer-x:hover{color:var(--text)}
.drawer-link{display:block;padding:13px 16px;color:var(--text);
  text-decoration:none;font-size:15px;transition:background .1s}
.drawer-link:hover{background:var(--slate-2)}
.drawer-link:active{background:#2b3542}
.drawer-link.soon{display:flex;align-items:baseline;justify-content:space-between;
  gap:10px;color:var(--muted);cursor:default}
.drawer-link.soon:hover{background:none}
.drawer-link.soon em{font-family:var(--cond);font-size:10px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;font-style:normal;
  color:#4a5666;white-space:nowrap}
.drawer-rule{height:1px;background:var(--line);margin:8px 16px}

@media (prefers-reduced-motion:reduce){
  .drawer,.drawer-veil{transition:none}
}

/* Repeated rows are self-contained, so changing one doesn't re-lay-out the
   whole list. Cheap on a long roster or a 48-pick board. */
.rrow,.tb-item,.dpick,.trade,.openrow,.note-row,.teamcard,.filterrow{
  contain:layout style}

/* The shared player card borrows the auction's own header and stat cards. */
.playercard{align-items:center;justify-content:center}
.playercard .modal-card{width:min(560px,94vw);margin:auto}
.playercard .nom{margin-bottom:14px}
.playercard .stat-card{margin-top:10px}

/* Cards arrive rather than appear: the veil fades, the card lifts. */
@keyframes card-in{from{opacity:0}to{opacity:1}}
@keyframes card-rise{
  from{opacity:0;transform:translateY(12px) scale(.98)}
  to{opacity:1;transform:none}}
/* The contents follow the card in rather than landing with it. */
@keyframes card-content{from{opacity:0}to{opacity:1}}
@keyframes card-out{from{opacity:1}to{opacity:0}}
@keyframes card-sink{
  from{opacity:1;transform:none}
  to{opacity:0;transform:translateY(10px) scale(.985)}}
/* Leaving takes as long as arriving, so the two feel like one motion. */
.modal.closing{animation:card-out .24s ease-in both;pointer-events:none}
.modal.closing > .modal-card{animation:card-sink .24s ease-in both}
.modal-card > .modal-body{animation:card-content .3s ease-out .08s both}
.sheet.open .sheet-body{animation:card-content .3s ease-out .06s both}
body:has(.home) .sheet{transition:opacity .24s ease-in,
  visibility 0s linear .24s}
body:has(.home) .sheet.open{transition:opacity .26s ease-out,visibility 0s}
body:has(.home) .sheet .sheet-card{transition:transform .26s
  cubic-bezier(.22,.7,.3,1),opacity .26s ease-out}
body:has(.home) .sheet:not(.open) .sheet-card{transform:translateY(12px)
  scale(.985);opacity:0}
@media (prefers-reduced-motion:reduce){
  .modal,.modal > .modal-card{animation:none}
}

/* The hub's panels: the same sheet the auction uses, with a filter row. */
body:has(.home) #rosterSheet,body:has(.home) #draftSheet,
body:has(.home) #tradesSheet{top:var(--bar-h,53px);
  height:calc(100dvh - var(--bar-h,53px))}
body:has(.home) #rosterSheet .sheet-card,
body:has(.home) #draftSheet .sheet-card{width:min(680px,96vw);height:100%}
/* About half the screen: enough to read, and it scrolls for the rest. */
body:has(.home) #tradesSheet .sheet-card{width:min(680px,96vw);
  height:min(56%,560px)}
body:has(.home) #tradesSheet .sheet-body{position:static;
  display:flex;flex-direction:column;min-height:0}
/* The toggle stays in view; only what's below it scrolls. */
/* The toggle is fixed furniture; only the lists below it scroll. */
body:has(.home) #tradesSheet .segwrap{flex:0 0 auto;margin:0 0 14px;
  padding:2px 0 4px;background:none;border-bottom:0}
body:has(.home) #tradesSheet .tradelist,
body:has(.home) #tradesSheet .blocklist{flex:1;min-height:0;overflow-y:auto;
  margin:0 -16px;padding:0 16px 60px}
body:has(.home) #tradesSheet .histbar{flex:0 0 auto}
/* Anchored to the panel, so it doesn't land in one place and jump to
   another once the sheet has laid out. */
body:has(.home) #tradesSheet .sheet-card{position:relative}
body:has(.home) #tradesSheet .tradepage{display:flex;flex-direction:column;
  min-height:0;flex:1;padding:0}
body:has(.home) #tradesSheet .fab-trade{position:absolute;right:16px;
  bottom:16px;z-index:3}
body:has(.home) #rosterSheet .sheet-filter,
body:has(.home) #draftSheet .sheet-filter{
  display:flex;align-items:center;justify-content:space-between;gap:10px;
  flex-wrap:wrap}
/* The picker keeps its width, so choosing a team can't shift what's beside
   it, and the count sits next to it rather than across the row. */
#draftSheet .teampick{flex:0 0 auto;width:190px}
#draftSheet .teampick .teampick-name{flex:1;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}

/* Players on the left, that team's picks on the right. */
.rostercols{display:flex;flex-direction:column;gap:18px}
.rosterpicks{display:flex;flex-direction:column;gap:7px}
.picklist{display:flex;flex-direction:column;gap:16px}
.pgroup{display:flex;flex-direction:column;gap:5px}
.pgroup .rgroup-head{padding-bottom:5px}
.prow{display:flex;align-items:center;gap:8px;padding:7px 9px;
  background:var(--slate);border:1px solid var(--line);border-radius:9px}
.prow-mid{flex:1;display:flex;flex-direction:column;gap:1px;min-width:0}
.prow-spacer{flex:0 0 auto;width:88px}
.prow-mid b{font-size:12.5px}
.prow-mid span{font-family:var(--cond);font-size:10px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.prow-cost{color:var(--money);font-family:var(--cond);font-size:13px}
.prow-from{font-family:var(--cond);font-size:11px;letter-spacing:.06em;
  text-transform:none;color:var(--muted)}
.rrow.lu{gap:9px}
body:has(.home) #rosterBody .rr-list{margin:0;padding:0;list-style:none}
body:has(.home) #rosterBody .rr-list.bench{margin-top:18px;padding-top:14px;
  border-top:1px solid var(--line)}
body:has(.home) #rosterBody .rr-list.bench > li:first-child{margin-top:0}
body:has(.home) #draftSheet .draftboard{display:flex;flex-direction:column;
  gap:18px}

@media (min-width:1081px){
  body:has(.home) #rosterSheet .sheet-card,
  body:has(.home) #draftSheet .sheet-card{height:88vh}
  body:has(.home) #draftSheet .sheet-card{width:min(1400px,96vw)}
  body:has(.home) #draftSheet .draftboard{display:grid;
    grid-template-columns:repeat(4,minmax(0,1fr));gap:18px;align-items:start}
}

/* A live event breathes: brighter for a moment, every few seconds. The
   colours live in the keyframes, which is why setting them on the rule
   alone did nothing — an animation outranks a plain declaration. */
@keyframes live-glow{
  0%,84%{box-shadow:0 0 0 0 #e2574c00}
  90%{box-shadow:0 0 9px 3px #e2574c66}
  100%{box-shadow:0 0 0 0 #e2574c00}
}
@keyframes live-tag{
  0%,84%{border-color:var(--red);color:var(--red)}
  90%{border-color:#ff8f82;color:#ff8f82;box-shadow:0 0 12px #e2574c59}
  100%{border-color:var(--red);color:var(--red)}
}
.evdot.on{animation:live-glow 5s ease-in-out infinite}
.evtag.live{animation:live-tag 5s ease-in-out infinite}
@media (prefers-reduced-motion:reduce){
  .evdot.on,.evtag.live{animation:none}
}

/* ── the trade block ──────────────────────────────────────────────────
   A toggle on your own roster, and the league-wide list on the trades page. */
.blockbtn{flex:0 0 auto;margin-left:8px;width:88px;height:30px;
  display:inline-flex;align-items:center;justify-content:center;
  text-align:center;padding:0 4px;border-radius:7px;
  background:var(--slate-2);border:1px solid var(--line);color:var(--muted);
  font-family:var(--cond);font-size:10px;font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;cursor:pointer;-webkit-tap-highlight-color:transparent;
  transition:transform .1s,border-color .1s,color .1s}
/* Only on a device that really hovers — a tap otherwise leaves the outline
   behind until you touch something else. */
@media (hover:hover){ .blockbtn:hover{border-color:var(--gold)} }
.blockbtn:focus{outline:none}
.blockbtn:focus-visible{outline:2px solid var(--teal);outline-offset:2px}
.blockbtn:active:not(:disabled){transform:translateY(2px)}
.blockbtn.on{background:#2e2410;border-color:var(--gold);color:var(--gold)}
.blockbtn.trade{color:var(--teal)}
@media (hover:hover){ .blockbtn.trade:hover{border-color:var(--teal)} }
/* Already inside an open offer. */
.blockbtn.pending{background:var(--blue);border-color:var(--blue);color:#fff}
.blockbtn.pending:disabled{opacity:1;cursor:default}
.blockbtn:disabled{opacity:.5}

.blocklist{display:flex;flex-direction:column;gap:5px}
.blocklist .tb-item{background:var(--slate);cursor:pointer}
.blocklist .tb-item:hover{border-color:var(--teal)}

/* ── open offers ──────────────────────────────────────────────────────
   Current offers use the same card as a settled trade, tagged and tappable.
   Anything closed is greyed and sits below. */
.trade.tappable{display:block;width:100%;text-align:left;font:inherit;
  color:inherit;cursor:pointer;transition:transform .1s,border-color .1s}
.trade.tappable:hover{border-color:#3a4756}
.trade.tappable:active{transform:translateY(2px)}
.trade.undone{opacity:.5;filter:grayscale(1)}
.trade-tag{font-family:var(--cond);font-size:11px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase}
.tag-out{color:var(--gold)}
.tag-in{color:var(--green)}
.tag-dead{color:var(--muted)}
/* Why a closed offer went nowhere. */
.closed-why{margin:14px 0 0;padding:11px 12px;background:var(--slate-2);
  border-radius:9px;font-family:var(--cond);font-size:12.5px;
  letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
  text-align:center}

/* The history filter */
.histbar{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.histfilter{display:flex;align-items:center;gap:6px;font-family:var(--cond);
  font-size:12px;letter-spacing:.06em;text-transform:uppercase;
  color:var(--muted)}
.histclear{background:none;border:0;color:var(--red);font-size:16px;
  line-height:1;cursor:pointer;padding:0 2px}
.filtersearch{width:100%;background:var(--ink);border:1px solid var(--line);
  border-radius:8px;padding:10px 12px;font-family:var(--ui);font-size:15px;
  color:var(--text)}
.filtersearch:focus{outline:none;border-color:var(--teal)}
.filterlist{margin-top:12px;max-height:52vh;overflow-y:auto;display:flex;
  flex-direction:column;gap:4px;scrollbar-color:var(--red) transparent}
.filterlist::-webkit-scrollbar{width:8px}
.filterlist::-webkit-scrollbar-track{background:transparent}
.filterlist::-webkit-scrollbar-thumb{background:var(--red);border-radius:6px}
.filterhead{margin:8px 0 2px;font-family:var(--cond);font-size:10px;
  font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted)}
.filterhead:first-child{margin-top:0}
.filterrow{display:flex;width:100%;padding:9px 10px;background:var(--slate-2);
  border:1px solid transparent;border-radius:8px;color:inherit;font:inherit;
  text-align:left;cursor:pointer;transition:border-color .1s}
.filterrow:hover{border-color:var(--teal)}
.filterrow:active{transform:translateY(2px)}
.filterrow-mid{display:flex;flex-direction:column;gap:1px;min-width:0}
.filterrow-mid b{font-size:14px}
.filterrow-mid span{font-family:var(--cond);font-size:10.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}

/* ── notifications ────────────────────────────────────────────────────
   A bell beside the avatar: grey when quiet, red with a count when an offer
   is waiting. */
.bell{position:relative;width:32px;height:32px;flex:0 0 auto;padding:0;
  border-radius:50%;border:1px solid #2b3542;background:var(--slate);
  color:var(--muted);cursor:pointer;display:flex;align-items:center;
  justify-content:center;-webkit-tap-highlight-color:transparent;
  transition:transform .12s,color .15s,border-color .15s}
.bell:focus{outline:none}
.bell:focus-visible{outline:2px solid var(--teal);outline-offset:3px}
.bell svg{width:19px;height:19px;display:block}
.bell:active{transform:translateY(2px)}
.bell.on{color:var(--gold);border-color:var(--gold)}
/* A ring every two seconds, so a waiting offer keeps catching the eye. The
   swing itself is about a third of that; the rest is the bell hanging still. */
.bell.on svg{animation:bell-shake 2s ease-in-out infinite;
  transform-origin:50% 20%}
@keyframes bell-shake{
  0%,72%{transform:rotate(0)}
  76%{transform:rotate(12deg)}
  80%{transform:rotate(-10deg)}
  84%{transform:rotate(8deg)}
  88%{transform:rotate(-5deg)}
  92%{transform:rotate(3deg)}
  96%,100%{transform:rotate(0)}
}
.bell-count{position:absolute;top:-3px;right:-3px;min-width:16px;height:16px;
  padding:0 4px;border-radius:99px;background:var(--red);color:#fff;
  font-family:var(--cond);font-size:10px;font-weight:700;line-height:16px;
  text-align:center;box-sizing:border-box;
  /* The count breathes on its own beat, so the two never quite line up and
     the corner always has something moving in it. */
  animation:bell-count-pulse 1.6s ease-in-out infinite}
@keyframes bell-count-pulse{
  0%,100%{transform:scale(1);box-shadow:0 0 0 0 rgba(226,87,76,.55)}
  45%{transform:scale(1.16);box-shadow:0 0 0 5px rgba(226,87,76,0)}
  70%{transform:scale(1);box-shadow:0 0 0 0 rgba(226,87,76,0)}
}
@media (prefers-reduced-motion:reduce){
  .bell.on svg,.bell-count{animation:none}
}

.note-row{display:flex;flex-direction:column;gap:7px;width:100%;padding:12px;
  margin-bottom:8px;background:var(--slate-2);border:1px solid var(--line);
  border-radius:10px;color:inherit;font:inherit;text-align:left;cursor:pointer;
  transition:transform .1s,border-color .1s}
.note-row:hover{border-color:var(--pink)}
.note-row:active{transform:translateY(2px)}
/* News about an offer of your own, rather than one waiting on an answer:
   marked down the edge so the two kinds don't have to be read to be told
   apart — green for a trade that went through, muted for one that didn't. */
/* What an offer would do to both rosters, inside the accept card. */
.offer-tally{margin-top:12px;padding:11px 12px;background:var(--slate-2);
  border:1px solid var(--line);border-radius:10px}
.tally-head{font-family:var(--cond);font-size:10px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted);
  margin-bottom:8px}
.tally-row{display:flex;align-items:baseline;flex-wrap:wrap;gap:4px 10px;
  padding:5px 0}
.tally-row + .tally-row{border-top:1px solid #2a3441}
.tally-who{flex:1 1 100%;font-size:13px;font-weight:600}
.tally-fig{display:inline-flex;align-items:baseline;gap:4px;
  font-family:var(--cond);font-size:13px;color:var(--muted)}
/* The figure it's leaving behind, struck through and stepped back. */
.tally-fig s{color:#5c6878;text-decoration-thickness:1px}
.tally-fig i{font-style:normal;color:#5c6878}
.tally-fig b{font-size:15px;font-weight:700}
.tally-wait{font-family:var(--cond);font-size:13px;color:#3d4858;
  letter-spacing:.3em}

.note-row.note-out{border-left-width:3px}
.note-row.note-out.done{border-left-color:var(--green)}
.note-row.note-out.no{border-left-color:#4a5666}
.note-row.note-out .note-kind{color:var(--muted)}
.note-row.note-out.done .note-kind{color:var(--green)}
.note-row.note-out:hover{border-color:var(--line)}
.note-row.note-out.done:hover{border-left-color:var(--green)}
.note-kind{font-family:var(--cond);font-size:10.5px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted)}
.note-who{display:flex;align-items:center;gap:9px}
.note-who b{font-size:15px}
.note-face{flex:0 0 auto;width:30px;height:30px;border-radius:50%;
  overflow:hidden;background:var(--slate);display:flex;align-items:center;
  justify-content:center}
.note-face img{width:100%;height:100%;object-fit:cover;object-position:top center}
.note-face .me-initials{font-size:10px}

/* Accept on the left, counter and decline together on the right. */
.foot-offer{justify-content:space-between}
.foot-right{display:flex;gap:9px}

/* ── trades ───────────────────────────────────────────────────────────
   History, and the two-column builder behind it. */
.tradepage{max-width:620px;margin:0 auto;padding:16px 16px 40px}
.tradebar{display:flex;align-items:center;justify-content:space-between;
  gap:12px;margin-bottom:16px}
/* The propose button floats, so it's there whichever view is showing. */
.fab-trade{position:fixed;right:16px;z-index:60;
  bottom:calc(16px + var(--sab,0px));
  width:46px;height:46px;padding:0;border-radius:50%;
  border:1px solid #2b3542;background:var(--slate);
  display:flex;align-items:center;justify-content:center;
  cursor:pointer;box-shadow:0 10px 26px #0009;
  -webkit-tap-highlight-color:transparent;transition:transform .12s}
.fab-trade svg{width:24px;height:24px;display:block}
.fab-trade:hover{border-color:#3a4756}
.fab-trade:active{transform:translateY(2px)}
/* Room to scroll past it. */
.tradepage{padding-bottom:96px}
/* Centred, and only as wide as the three labels need. */
.segwrap{display:flex;flex-direction:column;align-items:center;gap:8px;
  margin:0 0 20px}
.tradeseg{flex:0 0 auto}
/* Clear of the toggle above it. */
.histbar{margin-top:6px}
.tradecount{font-family:var(--cond);font-size:12.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.tradelist{display:flex;flex-direction:column;gap:10px}
/* Offers and Block share a first line, so switching between them doesn't
   move the text around. */
.tradelist > .empty,.blocklist > .empty{margin:0;padding:18px 0 0;
  text-align:center;font-size:14px;line-height:1.4}
/* The block list has a gap above its first child; the offers list doesn't,
   so without this the two sit a line apart. */
.blocklist{gap:5px}
.blocklist > .empty:first-child{padding-top:18px}
.trade{padding:13px;background:var(--slate);border:1px solid var(--line);
  border-radius:11px}
.trade.undone{opacity:.55}
.trade-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:8px;margin-bottom:9px}
.trade-when{font-family:var(--cond);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}
.trade-undone{font-family:var(--cond);font-size:10px;font-weight:700;
  letter-spacing:.1em;text-transform:uppercase;color:var(--red);
  border:1px solid var(--red);border-radius:99px;padding:2px 8px}
.trade-body{display:flex;align-items:flex-start;gap:10px}
/* Each side is headed by the team's photo and name, then what they sent. */
.trade-team{display:flex;align-items:center;gap:7px;padding-bottom:7px;
  margin-bottom:7px;border-bottom:1px solid var(--line)}
.trade-team b{font-size:13.5px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.trade-face{flex:0 0 auto;width:26px;height:26px;border-radius:50%;
  overflow:hidden;background:var(--slate-2);display:flex;align-items:center;
  justify-content:center}
.trade-face img{width:100%;height:100%;object-fit:cover;object-position:top center}
.trade-face .me-initials{font-size:9px}
.trade-asset-mid{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.trade-asset-mid .tb-item-sub{gap:3px;font-size:9px}
.trade-asset-mid .tb-item-sub span{font-size:9px}
.trade-asset-mid .tb-teamlogo{width:12px;height:12px}
.trade-asset-mid b{font-size:12.5px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
/* This year's class, marked simply RFA. */
.tb-rfa{color:var(--gold);font-weight:700}
.tb-item-mid .tb-rfa,.trade-asset-mid .tb-rfa{color:var(--gold)}
.confirm-side{margin-top:12px;padding:11px 12px;background:var(--slate-2);
  border-radius:9px;display:flex;flex-direction:column;gap:6px}
.confirm-side > b{font-family:var(--cond);font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted)}
/* Where that side's roster lands once the trade goes through. */
.confirm-after{display:flex;align-items:baseline;justify-content:space-between;
  gap:8px;margin-top:2px;padding-top:8px;border-top:1px solid var(--line)}
.confirm-after > span:first-child{font-family:var(--cond);font-size:10.5px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.confirm-figs{display:flex;align-items:baseline;gap:4px;
  font-family:var(--cond);font-size:11px;color:var(--muted);white-space:nowrap}
.confirm-figs b{font-size:14px;font-weight:700}
/* The cards sit on the card's own background here. */
.confirm-side .tb-item{background:var(--slate);cursor:default}
.notice-line{margin:0;font-size:13.5px;line-height:1.5}
.notice-line b{color:var(--red)}
.trade-side{flex:1;min-width:0;display:flex;flex-direction:column;gap:5px}
.trade-side > b{font-size:14px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.trade-swap{flex:0 0 auto;align-self:center;color:#4a5666;display:flex}
.trade-swap svg{width:22px;height:22px;display:block}
.trade-asset{display:flex;align-items:center;gap:6px;font-size:12.5px;
  min-width:0}
.trade-asset > span:nth-child(2){overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.trade-none{font-family:var(--cond);font-size:12px;color:var(--muted)}
.trade-sal{flex:0 0 auto;font-family:var(--cond);font-weight:700;
  color:var(--money)}
.trade-kind{flex:0 0 auto;font-family:var(--cond);font-size:9px;font-weight:700;
  letter-spacing:.1em;padding:2px 5px;border-radius:4px;color:#12161c}
.kind-pick{background:var(--gold)}
.kind-rfa{background:var(--blue)}
.kind-player{background:var(--muted)}
/* A player's chip carries the position in that position's own colour. */
.trade-pos{flex:0 0 auto;width:var(--badge-w,30px);height:var(--badge-h,34px);
  display:flex;align-items:center;justify-content:center;
  font-family:var(--cond);font-size:11px;font-weight:700;letter-spacing:.08em;
  padding:0;border-radius:6px;color:#fff;background:var(--muted)}
.trade-pos.pos-QB{background:var(--pos-qb)}
.trade-pos.pos-RB{background:var(--pos-rb)}
.trade-pos.pos-WR{background:var(--pos-wr)}
.trade-pos.pos-TE{background:var(--pos-te)}

/* Picks carry the same numbered badge the draft board uses. */
.trade-pick{flex:0 0 auto;width:var(--badge-w,30px);height:var(--badge-h,34px);
  display:flex;align-items:center;justify-content:center;padding:0;
  border-radius:6px;font-family:var(--cond);font-size:11px;font-weight:700;
  letter-spacing:.04em;color:#12161c;background:var(--muted)}
.trade-pick.r1{background:linear-gradient(160deg,#ffd23f,#e0a020)}
.trade-pick.r2{background:linear-gradient(160deg,#e8edf3,#aab6c4)}
.trade-pick.r3{background:linear-gradient(160deg,#d9a273,#b07b4c)}
.trade-pick.r4{background:var(--orange)}
.trade-pick.future{background:var(--slate-2);color:var(--text);
  border:1px solid var(--line);font-size:10px;letter-spacing:0}
.trade-pick.future.r1{background:var(--slate-2);border-color:#e0a020;
  color:#ffd23f}
.trade-pick.future.r2{background:var(--slate-2);border-color:#aab6c4;
  color:#e8edf3}
.trade-pick.future.r3{background:var(--slate-2);border-color:#b07b4c;
  color:#d9a273}
.trade-pick.future.r4{background:var(--slate-2);border-color:var(--orange);
  color:var(--orange)}

/* An RFA still reads as a player; this says which. */
.trade-note{margin:9px 0 0;font-size:12.5px;color:var(--muted)}
.trade .btn{margin-top:10px}

/* the builder */
/* These pages have no --chrome-h, so pin the sheet below the header
   rather than behind it. */
.tradepage ~ .sheet,
body:has(.tradepage) .sheet{top:var(--bar-h,53px);
  height:calc(100dvh - var(--bar-h,53px))}
body:has(.tradepage) .sheet-card{max-height:100%}
#builder .sheet-card{height:100%}
/* The body is the flexing part; the lists inside it take what's left after
   the note and the summary, so the card itself never scrolls. */
#builder .sheet-body{display:flex;flex-direction:column;min-height:0;
  overflow:hidden}
#builder .tb-note,#builder .tb-summary{flex:0 0 auto}
/* The close control sits in the card's own header, so it can't be covered. */
#builder .sheet-head{position:sticky;top:0;z-index:3;background:var(--slate)}
.tb-team{flex:1;min-width:0}
/* Each side scrolls on its own, so a long roster doesn't drag the other
   column — or the header — along with it. */
.tb-cols{display:grid;grid-template-columns:1fr 1fr;
  grid-template-rows:auto auto minmax(0,1fr);
  column-gap:10px;row-gap:0;flex:1;min-height:0}
/* Each list keeps its own fade, showing there's more below. */
.tb-listwrap{position:relative;min-width:0;min-height:0;display:flex}
.tb-listwrap::after{content:"";position:absolute;left:0;right:8px;bottom:0;
  height:22px;pointer-events:none;opacity:0;transition:opacity .15s;
  background:linear-gradient(180deg,transparent,var(--slate))}
.tb-listwrap.more::after{opacity:1}
.tb-colhead{align-self:stretch;display:grid;
  grid-template-rows:34px 16px 16px;align-content:start;gap:4px;
  min-height:76px;padding:0 0 7px;background:var(--slate);
  border-bottom:1px solid var(--line)}
.tb-colhead > *{min-width:0;align-self:center}
.tb-colhead .tb-cap{justify-content:center}
.tb-colhead > span{text-align:center}
.tb-colhead > span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* The team is chosen on its own column rather than from a row above. */
.tb-pick{width:100%;background:var(--slate-2);border:1px solid var(--line);
  border-radius:7px;padding:6px 7px;font-family:var(--ui);font-size:13px;
  font-weight:600;color:var(--text)}
.tb-pick:focus{outline:none;border-color:var(--teal)}
/* Your own side: shown, but not yours to change. */
/* Your own side: the same control, simply not changeable. The events are
   blocked in script — styling it differently moves it. */
.tb-pick.fixed-side{background:var(--slate);border-color:#2b3542;
  color:var(--text);cursor:default}
.tb-pick{box-sizing:border-box;height:34px;align-self:start;
  line-height:1.1}
.tb-cap{display:flex;align-items:baseline;gap:4px;font-family:var(--cond);
  font-size:11px;letter-spacing:.04em;color:var(--muted);white-space:nowrap;
  overflow:hidden;text-overflow:ellipsis}
.tb-cap b{font-size:13px;font-weight:700}
/* Inside the cap, over it, or past the hard cap. */
.cap-ok{color:var(--money)}
.cap-warn{color:var(--gold)}
.cap-over{color:var(--red)}
.count-over{color:var(--red);font-weight:700}
.tb-colhead > span{font-family:var(--cond);font-size:10.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.tb-list{flex:1;min-height:0;overflow-y:auto;display:flex;
  flex-direction:column;gap:5px;padding-right:6px;
  scrollbar-color:var(--red) transparent}
.tb-list::-webkit-scrollbar{width:8px}
.tb-list::-webkit-scrollbar-track{background:transparent}
.tb-list::-webkit-scrollbar-thumb{background:var(--red);border-radius:6px}
.tb-list::-webkit-scrollbar-thumb:hover{background:#ef6a5f}
/* A rule between sections: players, this year's picks, then each future year. */
.tb-group{margin:9px 0 2px;padding-bottom:4px;border-bottom:1px solid var(--line);
  font-family:var(--cond);font-size:10px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted)}
.tb-group:first-child{margin-top:0}
.tb-item{display:flex;align-items:center;gap:6px;width:100%;padding:7px 6px;
  background:var(--slate-2);border:1px solid transparent;border-radius:8px;
  color:inherit;font:inherit;text-align:left;cursor:pointer;
  -webkit-tap-highlight-color:transparent;transition:transform .1s,border-color .1s}
.tb-item:active{transform:translateY(2px)}
.tb-item.on{border-color:var(--green);background:#14301f}
.tb-item-mid{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px;
  height:34px;justify-content:center}
.tb-item-mid b{font-size:12.5px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.tb-item-mid span{font-family:var(--cond);font-size:9.5px;letter-spacing:.04em;
  text-transform:uppercase;color:var(--muted)}
.tb-item-sub{display:flex;align-items:center;gap:2px;min-width:0;
  overflow:hidden;white-space:nowrap}
/* The headshot stands where the position chip used to. */
.tb-face{flex:0 0 auto;width:var(--badge-w,30px);height:var(--badge-h,34px);
  border-radius:6px;overflow:hidden;background:var(--slate);display:flex;
  align-items:flex-end;justify-content:center}
.tb-face img{width:100%;height:100%;object-fit:cover;object-position:top center}
.tb-face .me-initials{font-size:11px;align-self:center}
.tb-teamlogo{flex:0 0 auto;width:12px;height:12px;object-fit:contain}
/* The position keeps its own colour; everything else on the line is muted. */
.tb-pos.pos-QB{color:var(--pos-qb)}
.tb-pos.pos-RB{color:var(--pos-rb)}
.tb-pos.pos-WR{color:var(--pos-wr)}
.tb-pos.pos-TE{color:var(--pos-te)}
.tb-item-sub > span{flex:0 0 auto}
.tb-item-sub > span:first-child{flex:0 1 auto;min-width:0;overflow:hidden;
  text-overflow:ellipsis}
.tb-item-sal{flex:0 0 auto;height:34px;display:flex;align-items:center;
  font-family:var(--cond);font-size:14px;font-weight:700;color:var(--money)}
.tb-note{margin-top:16px;display:block}
.tb-summary{grid-column:1 / -1;margin:10px 0 12px;padding:9px 12px;
  background:var(--slate-2);border-radius:9px;font-size:13px;
  color:var(--muted)}
.tb-summary p{margin:0 0 3px;font-size:12.5px}
.tb-summary p:last-child{margin-bottom:0}
.sheet-foot{display:flex;align-items:center;
  padding:14px 16px calc(14px + var(--sab,0px));
  border-top:1px solid var(--line)}
.sheet-foot .btn{width:100%}
.sheet-foot .btn:active:not(:disabled){transform:translateY(2px)}
#doTrade{transition:background .12s,box-shadow .09s,transform .09s,filter .12s}
#doTrade{background:var(--red);border-color:var(--red);color:#fff}
#doTrade:disabled{opacity:.45}

@media (min-width:1081px){
  .tradepage{max-width:820px;padding-top:26px}
  #builder .sheet-card{width:min(1000px,94vw)}
}

/* ── rookie draft order ───────────────────────────────────────────────
   Four rounds. One column on a phone, four across on a desktop. */
.draftpage{max-width:620px;margin:0 auto;padding:16px 16px 40px}
.draftbar{display:flex;align-items:center;justify-content:space-between;
  gap:12px;margin-bottom:16px;flex-wrap:wrap}
.draftbar .field{flex:1;min-width:180px}
.draftcount{flex:0 0 auto;min-width:82px;text-align:left;
  font-family:var(--cond);font-size:12.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.draftboard{display:flex;flex-direction:column;gap:18px}
.dround{display:flex;flex-direction:column;gap:6px;break-inside:avoid}
.dround.empty-round .dround-head{opacity:.55}
.dround-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:8px;padding:0 2px 5px;border-bottom:1px solid var(--line)}
.dround-head b{font-family:var(--display);font-size:16px}
/* A team's owed picks, headed by whose they are. */
.dfuture-who{display:flex;align-items:center;gap:8px;min-width:0}
.dfuture-who b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.dround-head span{font-family:var(--cond);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--muted)}
.dround-list{display:flex;flex-direction:column;gap:5px}
.dnone{margin:8px 0;text-align:center;font-family:var(--cond);font-size:15px;
  color:#3b4756}
.dpick{display:flex;align-items:center;gap:10px;padding:7px 10px;
  background:var(--slate);border:1px solid var(--line);border-radius:9px;
  min-height:48px;box-sizing:border-box}
.dpick.mine{border-color:var(--gold)}
.draftboard.one-team .dpick.mine{border-color:var(--line)}
.dpick-no{flex:0 0 auto;min-width:40px;text-align:center;padding:3px 7px;
  border-radius:6px;font-family:var(--cond);font-size:13px;font-weight:700;
  color:#12161c;background:var(--muted)}
.dpick-no.r1{background:linear-gradient(160deg,#ffd23f,#e0a020)}
.dpick-no.r2{background:linear-gradient(160deg,#e8edf3,#aab6c4)}
.dpick-no.r3{background:linear-gradient(160deg,#d9a273,#b07b4c)}
.dpick-no.r4{background:var(--orange)}
.dpick-who{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.dpick-who b{font-size:14px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.dpick-from{font-family:var(--cond);font-size:10px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--gold)}
.dpick-face{flex:0 0 auto;width:28px;height:28px;border-radius:50%;
  overflow:hidden;background:var(--slate-2);display:flex;align-items:center;
  justify-content:center}
.dpick-face img{width:100%;height:100%;object-fit:cover;object-position:top center}
.dpick-face .me-initials{font-size:10px}

@media (min-width:1081px){
  .draftpage{max-width:1400px;padding-top:26px}
  .draftboard{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
    gap:18px;align-items:start}
}
@media (min-width:700px) and (max-width:1080px){
  .draftboard{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));
    gap:18px;align-items:start}
}

/* ── rosters page ─────────────────────────────────────────────────────
   The same data the auction shows, on its own page. */
/* The mark and league name are a link home on every page; the page's own
   name sits beside it rather than replacing it. */
a.brand{text-decoration:none;color:inherit;flex:0 0 auto;
  transition:opacity .1s}
a.brand:hover{opacity:.82}
a.brand:active{opacity:.65}
.rosterpage{max-width:620px;margin:0 auto;padding:16px 16px 40px}
.rosterpick{display:flex;align-items:center;gap:12px;margin-bottom:16px;
  flex-wrap:wrap}
.teampick{display:flex;align-items:center;gap:9px;padding:6px 12px 6px 6px;
  background:var(--slate);border:1px solid var(--line);border-radius:99px;
  color:inherit;font:inherit;cursor:pointer;transition:border-color .1s}
.teampick:hover{border-color:var(--gold)}
.teampick:active{transform:translateY(2px)}
.teampick-face{width:30px;height:30px;border-radius:50%;overflow:hidden;
  background:var(--slate-2);display:flex;align-items:center;
  justify-content:center;flex:0 0 auto}
.teampick-face img{width:100%;height:100%;object-fit:cover;
  object-position:top center}
.teampick-face .me-initials{font-size:10px}
.teampick-name{font-size:15px;font-weight:600}
.teampick-caret{color:var(--muted);font-size:11px}

.pc-top{display:flex;align-items:center;gap:12px;padding-bottom:14px;
  border-bottom:1px solid var(--line)}
.pc-top .rrow-face{width:52px;height:56px;border-radius:9px}
.pc-who{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
.pc-who b{font-family:var(--display);font-size:18px}
.pc-cost{display:flex;flex-direction:column;align-items:flex-end;gap:2px}
.pc-cost b{font-family:var(--cond);font-size:20px;color:var(--money)}
.pc-facts,.pc-stats{display:grid;
  grid-template-columns:repeat(auto-fit,minmax(70px,1fr));gap:8px;
  margin-top:12px}
.pc-fact,.pc-stat{padding:9px 6px;background:var(--slate-2);border-radius:8px;
  text-align:center;display:flex;flex-direction:column;gap:2px}
.pc-fact b,.pc-stat b{font-family:var(--cond);font-size:16px}
.pc-fact span,.pc-stat span{font-family:var(--cond);font-size:9.5px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
.pc-head{margin:16px 0 0;font-family:var(--cond);font-size:10.5px;
  font-weight:700;letter-spacing:.14em;text-transform:uppercase;
  color:var(--muted)}

.rosterpick .field{flex:1;min-width:180px}
.rostercap{font-family:var(--cond);font-size:12.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.rostercap b{color:var(--text)}
.rosterbody{display:flex;flex-direction:column;gap:16px}
.rgroup{display:flex;flex-direction:column;gap:5px}
.rgroup-head{display:flex;align-items:center;gap:8px;padding:0 2px 4px;
  border-bottom:1px solid var(--line)}
.rgroup-head b{font-family:var(--cond);font-size:12px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--teal)}
.rgroup-head span{font-family:var(--cond);font-size:11px;color:var(--muted)}
.rrow{display:flex;align-items:center;gap:10px;padding:8px 10px;
  background:var(--slate);border:1px solid var(--line);border-radius:9px}
.rrow.is-rfa{border-color:var(--gold)}
/* Tagged: kept off the block by the tag, so it reads as its own state. */
.rrow.is-tagged{border-color:var(--red)}
.rrow-tag{display:inline-flex;align-items:center;gap:4px;color:var(--red);
  font-weight:700}
.rrow-tag svg{width:12px;height:12px;flex:0 0 auto}
.rrow-face{flex:0 0 auto;width:34px;height:36px;border-radius:7px;
  overflow:hidden;background:var(--slate-2);display:flex;align-items:flex-end;
  justify-content:center}
.rrow-face img{width:100%;height:100%;object-fit:cover;object-position:top center}
.rrow-face .me-initials{font-size:11px;align-self:center}
.rrow-name{display:flex;align-items:center;gap:6px;min-width:0}
.rrow-name b{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rrow-info{flex:0 0 auto;width:16px;height:16px;border-radius:50%;padding:0;
  background:var(--slate-2);border:1px solid var(--line);color:var(--muted);
  font-family:var(--display);font-size:10px;line-height:1;cursor:pointer;
  transition:color .1s,border-color .1s}
.rrow-info:hover{color:var(--teal);border-color:var(--teal)}
.rrow-info:active{transform:translateY(2px)}
.rrow-info{transition:transform .12s,color .1s,border-color .1s}
.rrow-sub{display:flex;align-items:center;gap:5px;min-width:0;
  font-family:var(--cond);font-size:10.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);white-space:nowrap;
  overflow:hidden}
.rrow-teamlogo{flex:0 0 auto;width:13px;height:13px;object-fit:contain}
.rrow-rfa{color:var(--gold);font-weight:700}
.rrow-right .rrow-rank,.pc-cost .rrow-rank{color:var(--blue);font-weight:700}
.cap-power{color:var(--money)}
.rrow-mid{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.rrow-mid b{font-size:14px;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.rrow-mid > .rrow-sub{font-family:var(--cond);font-size:11px;
  letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.rrow-name{text-transform:none}
.rrow-name b{font-family:var(--ui);font-size:14px;font-weight:700}
.rrow-right{flex:0 0 auto;display:flex;flex-direction:column;align-items:flex-end;
  gap:1px}
.rrow-sal{font-family:var(--cond);font-size:16px;font-weight:700;
  color:var(--money)}
.rrow-right span{font-family:var(--cond);font-size:10.5px;color:var(--muted)}

@media (min-width:1081px){ .rosterpage{max-width:760px;padding-top:26px} }

/* ── league home ──────────────────────────────────────────────────────
   A menu, not a tool: what's running, whose roster, and the draft order. */
.home{max-width:620px;margin:0 auto;padding:16px 16px 20px;
  display:flex;flex-direction:column;gap:18px;
  /* One screen, no scrolling: the team grid takes what's left. */
  height:calc(100dvh - var(--bar-h,53px));box-sizing:border-box}
/* The middle column carries what the phone layout carried: events stacked
   on top of the team grid, both the same width. The rails either side of it
   are desktop-only and don't exist below 1081px. */
.home-mid{display:flex;flex-direction:column;gap:18px;flex:1;min-height:0}
/* Named hubrail, not rail: the auction app already owns .rail for its own
   sidecar, and a bare .rail rule here would reach across and hide it. */
.hubrail{display:none}
.home-block{margin-bottom:0;min-height:0;display:flex;flex-direction:column}
.home-block:last-child{flex:1;min-height:0}
.home-h{margin:0 0 10px;font-family:var(--cond);font-size:11px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}

/* Events */
.evlist{display:flex;flex-direction:column;gap:8px}
.evrow{display:flex;align-items:center;gap:12px;padding:14px;
  background:var(--slate);border:1px solid var(--line);border-radius:11px;
  color:var(--text);text-decoration:none;transition:transform .1s,border-color .1s}
a.evrow:hover{border-color:#3a4756}
a.evrow:active{transform:translateY(2px)}
.evrow.dormant{opacity:.5}
.evdot{flex:0 0 auto;width:9px;height:9px;border-radius:50%;background:#3b4756}
.evdot.on{background:var(--red)}
.evtext{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.evtext b{font-family:var(--display);font-size:17px}
.evtext span{font-family:var(--cond);font-size:11.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.evtag{flex:0 0 auto;font-family:var(--cond);font-size:10px;font-weight:700;
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted);
  border:1px solid var(--line);border-radius:99px;padding:3px 9px}
.evtag.live{color:var(--red);border-color:#8f3a33}

/* Rosters */
/* Every row the same height. align-content:stretch shares out the leftover
   space evenly, but it shares it on top of each row's own content height —
   so a row holding a longer name, or a card with a badge on it, ends up
   taller than the rest. Fixed rows take content out of the question. */
.teamgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));
  grid-auto-rows:minmax(0,1fr);
  gap:8px;flex:1;min-height:0;align-content:stretch}
.teamcard{position:relative;display:flex;flex-direction:column;
  align-items:center;justify-content:center;gap:5px;min-height:0;
  padding:6px 4px;background:var(--slate);border:1px solid var(--line);
  border-radius:11px;color:var(--text);text-decoration:none;
  transition:transform .1s,border-color .1s}
/* The card sits deeper at the bottom than the top. A gradient rather than a
   blur, so it stays inside the card's own corners. */
#teams .teamcard::before{content:"";position:absolute;z-index:0;
  left:0;right:0;bottom:0;height:52%;border-radius:inherit;
  pointer-events:none;
  background:linear-gradient(to top,rgba(6,9,14,.62),rgba(6,9,14,0))}
#teams .teamcard > *{position:relative;z-index:1}
/* The reigning champion's circle is ringed in gold rather than the card. */
.teamcard.champ .teamface{box-shadow:0 0 0 2.5px var(--gold),
  0 0 12px rgba(242,176,30,.45);background:var(--gold)}
/* The white in these circles is baked into the JPEG, so CSS can only put
   gold behind it — which shows on the ring and on the initials, not through
   the photo. To recolour the photo's own white as well, uncomment this: it
   multiplies the picture into the gold, turning white to gold exactly at
   the cost of warming his face along with it.
.teamcard.champ .teamface img{mix-blend-mode:multiply}
*/
.teamcard:hover{border-color:#3a4756}
.teamcard:active{transform:translateY(2px)}
.teamcard.mine{border-color:var(--line)}
.teamface{position:relative;width:clamp(30px,7.2vh,44px);
  height:clamp(30px,7.2vh,44px);border-radius:50%;
  background:var(--slate-2);display:flex;align-items:center;
  justify-content:center;flex:0 0 auto}
.teamface img{width:100%;height:100%;object-fit:cover;object-position:top center;
  border-radius:50%}
/* Sits over the photo's edge, so the circle stays a circle. */
.teamface.has-badge{overflow:visible}
.teambadge{position:absolute;right:-2px;bottom:-2px;line-height:1;
  pointer-events:none}
/* Which one is you: the same live dot the events carry, on its own beat. */
.teambadge.you{width:11px;height:11px;border-radius:50%;
  background:var(--green);border:2px solid var(--slate);box-sizing:border-box;
  animation:you-pulse 1.9s ease-in-out infinite}
@keyframes you-pulse{
  0%,100%{box-shadow:0 0 0 0 rgba(63,191,127,.5)}
  55%{box-shadow:0 0 0 5px rgba(63,191,127,0)}
  80%{box-shadow:0 0 0 0 rgba(63,191,127,0)}
}
.teambadge.cup{font-size:12px;filter:drop-shadow(0 1px 2px #000c)}
/* When one team holds both, the dot steps aside. */
.teambadge.you.shifted{right:auto;left:-2px}

/* ── championships ────────────────────────────────────────────────────
   One star a title, arched over the top of the circle. Each star is a full
   overlay rotated about the face's own centre, so it lands on the circle's
   edge and tilts with it — which is what makes the row read as an arc
   rather than a straight line of stars. The reigning champion's newest one
   is gold. */
.crowns{position:absolute;inset:0;pointer-events:none;
  --step:23deg;--size:8px;--gap:3px}
.crowns i{position:absolute;inset:0;display:flex;justify-content:center;
  align-items:flex-start;transform:rotate(calc(var(--step) * var(--k)));
  color:#fff}
/* Drawn from a path rather than set as the ★ character: a glyph is whatever
   the fallback font decides it is, which is how it came out lopsided at one
   size and not another. This is the same five points at every size.

   Placed by the arc, then turned back upright — the wrapper's rotation puts
   the star on the circle, and the star undoes exactly that rotation about
   its own centre so it still stands straight. The lift is its own height
   plus the gap, so that gap is clear air between it and the rim. */
.crowns i::before{content:"";width:var(--size);height:var(--size);
  background:currentColor;
  transform:translateY(calc(-1 * (var(--size) + var(--gap))))
    rotate(calc(var(--step) * var(--k) * -1));
  -webkit-mask:var(--star) center/contain no-repeat;
  mask:var(--star) center/contain no-repeat}
.crowns i.now{color:var(--gold)}
:root{--star:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12.00 1.00 14.47 8.60 22.46 8.60 16.00 13.30 18.47 20.90 12.00 16.20 5.53 20.90 8.00 13.30 1.54 8.60 9.53 8.60 Z' fill='black'/></svg>")}
@media (prefers-reduced-motion:reduce){ .teambadge.you{animation:none} }
.teamname{font-size:11px;line-height:1.2;text-align:center;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}
/* Filled in for every card, shown only once the desktop layout has room. */
.teammeta{display:none}

/* The one big card */
.home-card{display:flex;align-items:center;gap:13px;padding:15px;
  background:var(--slate);border:1px solid var(--line);border-radius:11px;
  color:var(--text);text-decoration:none;transition:transform .1s,border-color .1s}
.home-card:hover{border-color:#3a4756}
.home-card:active{transform:translateY(2px)}
.home-card-mark{flex:0 0 auto;width:42px;height:42px;display:flex;
  align-items:center;justify-content:center;border-radius:10px;
  background:var(--slate-2);color:var(--teal)}
.home-card-mark svg{width:24px;height:24px}
.home-card-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.home-card-text b{font-family:var(--display);font-size:17px}
.home-card-text span{font-family:var(--cond);font-size:11.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.home-card-go{flex:0 0 auto;font-size:19px;color:#4a5666}


/* ── the news panel ───────────────────────────────────────────────────
   Worn by the rail on a desktop and by the pull-out drawer on a phone, so
   it lives out here rather than inside either layout. */
.hubrail-head{flex:0 0 auto;display:flex;align-items:baseline;
  justify-content:space-between;gap:8px;padding:15px 16px 12px;
  border-bottom:1px solid var(--line)}
.hubrail-head b{font-family:var(--cond);font-size:12px;font-weight:700;
  letter-spacing:.16em;text-transform:uppercase;color:var(--muted)}
.hubrail-more{background:none;border:0;padding:0;cursor:pointer;
  font-family:var(--cond);font-size:11px;letter-spacing:.1em;
  text-transform:uppercase;color:var(--teal);text-decoration:none}
.hubrail-more:hover{color:var(--text)}
.hubrail-body{flex:1;min-height:0;overflow-y:auto;overscroll-behavior:contain;
  padding:10px 12px 16px}
.hubrail-body::-webkit-scrollbar{width:8px}
.hubrail-body::-webkit-scrollbar-thumb{background:#2b3542;border-radius:99px}
.hubrail-empty{margin:14px 4px;font-size:13px;color:var(--muted)}

/* ── the news rail ──────────────────────────────────────────────────
   Someone else's content, so it reads as its own panel: cooler and a
   shade deeper than the league's own slate, with the peacock's six
   colours along the bottom edge and a little of that light rising off
   it. The glow is masked upward and sits under the rows, so it lifts
   the panel without touching the type. */
#newsRail{background:linear-gradient(180deg,#161d2b 0%,#111825 100%)}
#newsRail .hubrail-head{border-bottom-color:#26303f}
#newsRail .hubrail-head,
#newsRail .hubrail-body{position:relative;z-index:1}
#newsRail .newsrow + .newsrow{border-top-color:#212a38}
#newsRail .newsrow:hover{background:#1e2635}
#newsRail .news-face{background:#1e2635}

/* The light coming off it. */
#newsRail::before{content:"";position:absolute;z-index:0;
  left:0;right:0;bottom:0;height:150px;pointer-events:none;
  background:linear-gradient(90deg,#fcb711,#f37021,#cc004c,
    #6460aa,#0089d0,#0db14b);
  filter:blur(26px);opacity:.22;
  -webkit-mask-image:linear-gradient(to top,#000 0%,transparent 100%);
  mask-image:linear-gradient(to top,#000 0%,transparent 100%)}
/* The edge itself. */
#newsRail::after{content:"";position:absolute;z-index:2;
  left:0;right:0;bottom:0;height:3px;pointer-events:none;
  background:linear-gradient(90deg,#fcb711,#f37021,#cc004c,
    #6460aa,#0089d0,#0db14b)}

/* Their mark, at a size that sits on the baseline of the heading. */
.news-logo{display:flex;align-items:center;line-height:0}
.news-logo img{height:17px;width:auto;max-width:120px;opacity:.92}
.news-logo:hover img{opacity:1}

/* The foot of the list: a mark while more is coming, then the way out. */
.news-foot{display:flex;align-items:center;justify-content:center;
  padding:14px 0 6px;min-height:26px}
.news-wait{font-family:var(--cond);font-size:14px;letter-spacing:.3em;
  color:#3d4858}
.news-end{font-family:var(--cond);font-size:11px;font-weight:700;
  letter-spacing:.14em;text-transform:uppercase;color:var(--teal);
  text-decoration:none;padding:6px 10px}
.news-end:hover{color:var(--text)}

/* One note. */
.newsrow{display:flex;gap:10px;padding:10px 8px;border-radius:9px;
  color:var(--text);text-decoration:none}
.newsrow + .newsrow{border-top:1px solid #232c37}
.newsrow:hover{background:var(--slate-2)}
.news-face{flex:0 0 auto;width:34px;height:34px;border-radius:50%;
  background:var(--slate-2);overflow:hidden;display:flex;
  align-items:center;justify-content:center}
.news-face img{width:100%;height:100%;object-fit:cover;
  object-position:top center}
.news-face .me-initials{font-size:11px}
.news-mid{min-width:0;display:flex;flex-direction:column;gap:2px}
.news-top{display:flex;align-items:center;gap:7px;min-width:0}
.news-top b{font-size:13px;font-weight:600;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.news-tag{flex:0 0 auto;font-family:var(--cond);font-size:9.5px;
  font-weight:700;letter-spacing:.1em;text-transform:uppercase;
  padding:1px 6px;border-radius:99px;border:1px solid var(--line);
  color:var(--muted)}
.news-tag.injury{color:var(--red);border-color:#5d3330}
.news-tag.transaction{color:var(--teal);border-color:#26535a}
.news-tag.recap{color:var(--gold);border-color:#5c4a1c}
.news-line{font-family:var(--cond);font-size:10.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted);overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.news-head{font-size:12.5px;line-height:1.35;margin-top:2px}
/* Enough of the note to know whether to open it. */
.news-body{font-size:11.5px;line-height:1.4;color:var(--muted);
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;
  overflow:hidden}

/* ── the home page on a desktop ───────────────────────────────────────
   The phone layout is one column that fills the screen, the team grid
   taking whatever height is left. On a tall monitor that same rule
   stretches two rows of cards to 400px each, which is why they read as
   empty boxes with a face floating in them.

   So the page turns instead. The middle column keeps the phone's order —
   events stacked above the roster cards, matching their width — and the
   space either side becomes two rails: the draft board on the left, player
   news on the right. The news rail comes in first, at 1081px; the draft
   rail waits for 1440px, below which three columns would squeeze the cards.

   Everything is scoped to .home, so the team pickers in the roster and
   draft sheets keep the compact card they already have. */
@media (min-width:1081px){
  .home{max-width:none;padding:0;gap:0;
    height:auto;min-height:calc(100dvh - var(--bar-h,53px));
    display:grid;grid-template-columns:minmax(0,1fr) 360px;
    align-items:start}
  /* The rails take the edges, so the page's own margin lives in here. */
  .home-mid{flex:none;gap:22px;padding:24px 26px 30px;min-width:0}
  /* The heading only says what the rows already say. */
  .home-mid .home-block:first-child .home-h{display:none}
  .home-block:last-child{flex:none}
  .home .teamgrid{flex:none;align-content:start}

  .home .evlist{gap:10px}
  .home .evrow{padding:16px 15px}
  .home .evtext b{font-size:18px}

  .home .teamgrid{grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;
    grid-auto-rows:auto}
  .home .teamcard{justify-content:flex-start;gap:9px;padding:18px 14px 14px}
  .home .teamface{width:64px;height:64px}
  .home .teamface .me-initials{font-size:20px}
  .home .teamname{font-size:14px;font-weight:600}
  .home .teambadge.you{width:13px;height:13px;right:-3px;bottom:-3px}
  .home .teambadge.cup{font-size:16px;right:-3px;bottom:-3px}
  .home .teambadge.you.shifted{left:-3px;right:auto}
  /* A wider circle takes a shallower arc and a little more clearance. */
  .home .crowns{--step:19deg;--size:9px;--gap:4px}

  /* Salary against the cap, and how many picks are still in hand. Pick
     salaries stay out of the money left, as they do everywhere else. */
  .home .teammeta{display:flex;flex-direction:column;gap:6px;
    width:100%;margin-top:3px}
  .teamcap{display:flex;justify-content:space-between;align-items:baseline;
    font-family:var(--cond);font-size:11.5px;letter-spacing:.04em;
    color:var(--muted)}
  .teamcap b{font-weight:700;color:var(--money)}
  .teamcap.tight b{color:var(--red)}
  .teambar{height:4px;border-radius:99px;background:#131820;overflow:hidden}
  .teambar i{display:block;height:100%;border-radius:99px;
    background:var(--money);opacity:.85}
  .teambar.tight i{background:var(--red)}
  .teampicks{font-family:var(--cond);font-size:10.5px;letter-spacing:.12em;
    text-transform:uppercase;color:var(--muted)}

  /* ── the rails ──────────────────────────────────────────────────────
     Each scrolls inside itself and sticks below the header, so reading
     forty picks or thirty notes never moves the page underneath. */
  .home .hubrail{display:flex;flex-direction:column;background:var(--slate);
    isolation:isolate;
    border:0;border-radius:0;
    position:sticky;top:var(--bar-h,53px);
    height:calc(100dvh - var(--bar-h,53px));overflow:hidden}
  /* Only the edge facing the middle is drawn; the outer one is the screen. */
  .home #draftRail{border-right:1px solid var(--line)}
  .home #newsRail{border-left:1px solid var(--line)}

  /* A rail with nothing in it is worse than no rail. */
  .home .hubrail.gone{display:none}
  /* Only two columns at this width — the board waits for the next one. */
  .home #draftRail{display:none}

  /* Left: the board. One line a pick, so all four rounds are reachable. */
  .railround + .railround{margin-top:12px}
  .railround-head{font-family:var(--cond);font-size:10.5px;font-weight:700;
    letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
    padding:0 4px 5px}
  .railpick{display:flex;align-items:center;gap:9px;width:100%;
    padding:5px 6px;background:none;border:0;border-radius:7px;
    color:var(--text);font:inherit;text-align:left;cursor:pointer}
  .railpick:hover{background:var(--slate-2)}
  .railpick.mine{background:#1f2a24}
  .railpick.mine:hover{background:#243026}
  .railpick-no{flex:0 0 auto;width:22px;text-align:center;
    font-family:var(--cond);font-size:11px;font-weight:700;color:var(--muted)}
  /* The medal colours the board already uses for the first three rounds. */
  .railpick-no.r1{color:var(--gold)}
  .railpick-no.r2{color:#c6ced8}
  .railpick-no.r3{color:#c88a52}
  .railpick-who{min-width:0;display:flex;flex-direction:column;line-height:1.25}
  .railpick-who b{font-size:12.5px;font-weight:600;overflow:hidden;
    text-overflow:ellipsis;white-space:nowrap}
  .railpick-who span{font-family:var(--cond);font-size:10.5px;
    letter-spacing:.04em;color:var(--muted)}

}

/* Wide enough for the board as well. */
@media (min-width:1440px){
  /* Matched widths: the two rails frame the middle evenly. */
  .home{grid-template-columns:360px minmax(0,1fr) 360px}
  .home #draftRail{display:flex}
}

/* Wide enough for a fourth card in a row, and a roomier news column. */
@media (min-width:1760px){
  .home{grid-template-columns:400px minmax(0,1fr) 400px}
  .home .teamgrid{grid-template-columns:repeat(4,minmax(0,1fr))}
  .home-mid{padding:26px 34px 34px}
}


/* ── one scrollbar, everywhere ────────────────────────────────────────
   The auction's panes and sheets draw a 13px red bar with arrow buttons at
   each end. On a desktop that reads as chrome rather than as an indicator,
   so every scrolling area gets the plain thumb the draft rail uses instead.

   The names are spelled out rather than left to a wildcard because the
   originals are class- and id-led: a wildcard would lose to them on
   specificity and change nothing. Same selectors, later in the file, so
   these win. Touch devices keep their own overlay bars — this is desktop
   only, and the coarse-pointer rules above still stand where they apply. */
@media (min-width:1081px) and (pointer:fine){
  /* Anything scrollable that was never styled at all. */
  *{scrollbar-width:thin;scrollbar-color:#2b3542 transparent}
  *::-webkit-scrollbar{width:9px;height:9px}
  *::-webkit-scrollbar-track{background:transparent}
  *::-webkit-scrollbar-thumb{background:#2b3542;border:0;border-radius:99px}
  *::-webkit-scrollbar-thumb:hover{background:#3a4756}
  *::-webkit-scrollbar-corner{background:transparent}

  /* And the ones that were. */
  .pane-body,.sheet-body,.sheet-body .rfa,#leagueBody,#draftBody,
  .filterlist,.tb-list,.rfa.capped,.hubrail-body{
    scrollbar-width:thin;scrollbar-color:#2b3542 transparent}
  .pane-body::-webkit-scrollbar,.sheet-body::-webkit-scrollbar,
  .sheet-body .rfa::-webkit-scrollbar,#leagueBody::-webkit-scrollbar,
  #draftBody::-webkit-scrollbar,.filterlist::-webkit-scrollbar,
  .tb-list::-webkit-scrollbar,.rfa.capped::-webkit-scrollbar,
  .hubrail-body::-webkit-scrollbar{width:9px;height:9px}
  .pane-body::-webkit-scrollbar-track,.sheet-body::-webkit-scrollbar-track,
  .sheet-body .rfa::-webkit-scrollbar-track,#leagueBody::-webkit-scrollbar-track,
  #draftBody::-webkit-scrollbar-track,.filterlist::-webkit-scrollbar-track,
  .tb-list::-webkit-scrollbar-track,.rfa.capped::-webkit-scrollbar-track,
  .hubrail-body::-webkit-scrollbar-track{background:transparent}
  .pane-body::-webkit-scrollbar-thumb,.sheet-body::-webkit-scrollbar-thumb,
  .sheet-body .rfa::-webkit-scrollbar-thumb,#leagueBody::-webkit-scrollbar-thumb,
  #draftBody::-webkit-scrollbar-thumb,.filterlist::-webkit-scrollbar-thumb,
  .tb-list::-webkit-scrollbar-thumb,.rfa.capped::-webkit-scrollbar-thumb,
  .hubrail-body::-webkit-scrollbar-thumb{background:#2b3542;border:0;
    border-radius:99px}
  .pane-body::-webkit-scrollbar-thumb:hover,
  .sheet-body::-webkit-scrollbar-thumb:hover,
  .sheet-body .rfa::-webkit-scrollbar-thumb:hover,
  #leagueBody::-webkit-scrollbar-thumb:hover,
  #draftBody::-webkit-scrollbar-thumb:hover,
  .filterlist::-webkit-scrollbar-thumb:hover,
  .tb-list::-webkit-scrollbar-thumb:hover,
  .rfa.capped::-webkit-scrollbar-thumb:hover,
  .hubrail-body::-webkit-scrollbar-thumb:hover{background:#3a4756}
  .pane-body::-webkit-scrollbar-corner,.sheet-body::-webkit-scrollbar-corner,
  .sheet-body .rfa::-webkit-scrollbar-corner,#leagueBody::-webkit-scrollbar-corner,
  #draftBody::-webkit-scrollbar-corner{background:transparent}
  /* The arrows at each end go with them. */
  .pane-body::-webkit-scrollbar-button:single-button,
  .sheet-body::-webkit-scrollbar-button:single-button,
  .sheet-body .rfa::-webkit-scrollbar-button:single-button,
  #leagueBody::-webkit-scrollbar-button:single-button,
  #draftBody::-webkit-scrollbar-button:single-button{
    display:none;width:0;height:0;background:none;background-image:none}
}

/* ── the hub answers the pointer ──────────────────────────────────────
   A live event row and a team card are both buttons; on a desktop they
   should say so before they're clicked. Brighter, and the face grows just
   enough to read as a lift rather than a jump. */
@media (min-width:1081px) and (pointer:fine){
  .home a.evrow{transition:background-color .13s ease,border-color .13s ease,
    transform .1s ease}
  .home a.evrow:hover{background:#212a35;border-color:#46566a}
  .home a.evrow:hover .evtext b{color:#fff}
  .home a.evrow:hover .evdot.on{box-shadow:0 0 0 4px #e2574c2e}

  .home .teamcard{transition:background-color .13s ease,border-color .13s ease,
    transform .1s ease}
  .home .teamcard:hover{background:#212a35;border-color:#46566a}
  .home .teamcard:hover .teamname{color:#fff}
  .home .teamface{transition:transform .16s ease}
  .home .teamcard:hover .teamface{transform:scale(1.09)}

  /* The news rail's rows are links too. */
  .home .newsrow{transition:background-color .13s ease}
  .home .news-face{transition:transform .16s ease}
  .home .newsrow:hover .news-face{transform:scale(1.08)}
}


/* ── the news drawer, on a phone ──────────────────────────────────────
   No room for a rail beside anything, so the same panel lives off the
   right edge behind a tab. Translucent, because it sits over the page
   rather than beside it, and it keeps the mark, the rainbow and the glow
   the desktop rail wears.

   The tab is only worth showing once there's something behind it: JS adds
   .ready when the feed lands, and .gone if it never does. */
@media (max-width:1080px){
  :root{--newsw:min(88vw,400px)}

  /* top is set in px once it's been dragged; the translate keeps that
     figure meaning the tab's middle either way. touch-action:none is what
     lets a drag up the edge move it instead of scrolling the page. */
  /* Parked off the right edge, a fixed element still counts toward the
     page's scrollable area — and overflow-x:hidden doesn't clip fixed
     descendants. So it waits in place and fades, rather than sliding in
     from beyond the screen. */
  .newstab{position:fixed;z-index:70;right:0;top:50%;
    transform:translateY(-50%) translateX(0);
    opacity:0;pointer-events:none;
    touch-action:none;-webkit-user-select:none;user-select:none;
    display:flex;flex-direction:column;align-items:center;gap:7px;
    padding:14px 7px 12px;border:1px solid #2a3546;border-right:0;
    border-radius:11px 0 0 11px;
    background:rgba(20,27,40,.86);-webkit-backdrop-filter:blur(12px);
    backdrop-filter:blur(12px);color:var(--muted);
    box-shadow:-4px 0 18px #0006;
    transition:transform .28s cubic-bezier(.22,.61,.36,1),opacity .2s ease;
    cursor:pointer;overflow:hidden}
  /* Only after the feed answers. */
  .newstab.ready{opacity:1;pointer-events:auto}
  .newstab.gone{display:none}
  /* Follow the finger exactly; the slide-out easing is for the tap. */
  .newstab.dragging{transition:none;cursor:grabbing}
  .newstab-word{writing-mode:vertical-rl;text-orientation:mixed;
    font-family:var(--cond);font-size:11px;font-weight:700;
    letter-spacing:.18em;text-transform:uppercase}
  .newstab-arrow{font-size:15px;line-height:1;transition:transform .28s ease}
  /* The same six colours, down the tab's own edge. */
  .newstab::after{content:"";position:absolute;left:0;bottom:0;width:100%;
    height:3px;background:linear-gradient(90deg,#fcb711,#f37021,#cc004c,
      #6460aa,#0089d0,#0db14b)}

  /* Open: the tab rides out with the panel and turns to point back. */
  body.news-open .newstab{transform:translateY(-50%) translateX(calc(-1 * var(--newsw)))}
  body.news-open .newstab-arrow{transform:rotate(180deg)}

  /* The drawer is positioned against .home and clipped by it, so the closed
     panel can sit off the right edge without giving the page somewhere to
     scroll to. overflow:hidden rather than contain:paint deliberately —
     containment would make .home a stacking context and drop the open
     drawer underneath its own veil. */
  .home{position:relative;overflow:hidden}
  .home #newsRail{display:flex;flex-direction:column;position:absolute;z-index:69;
    top:0;right:0;bottom:0;width:var(--newsw);
    border:0;border-left:1px solid #2a3546;border-radius:0;
    isolation:isolate;overflow:hidden;
    /* Translucent, since the page is right behind it. */
    background:linear-gradient(180deg,rgba(22,29,43,.93) 0%,
      rgba(15,21,33,.96) 100%);
    -webkit-backdrop-filter:blur(16px);backdrop-filter:blur(16px);
    box-shadow:-10px 0 30px #0007;
    transform:translateX(100%);
    transition:transform .3s cubic-bezier(.22,.61,.36,1);
    visibility:hidden}
  body.news-open .home #newsRail{transform:translateX(0);visibility:visible}
  /* Momentum scrolling, and the drawer swallows it rather than the page. */
  .home #newsRail .hubrail-body{-webkit-overflow-scrolling:touch;
    overscroll-behavior:contain}
  /* Room to read on a phone. */
  .home #newsRail .news-body{-webkit-line-clamp:4;font-size:12px}
  .home #newsRail .news-head{font-size:13px}

  .newsveil{position:fixed;inset:0;z-index:68;background:#0009;
    opacity:0;pointer-events:none;transition:opacity .3s ease}
  body.news-open .newsveil{opacity:1;pointer-events:auto}
}

/* The tab belongs to the phone. */
@media (min-width:1081px){
  .newstab,.newsveil{display:none}
}


/* ══ TICKER ═══════════════════════════════════════════════════════════
   The hub's skin: deep navy, square corners, block lettering. Scoped to
   body.dhskin — the auction app shares this stylesheet and is deliberately
   left on the slate palette, so lift these into :root when it's time to
   take the whole thing over.

   The accent is spent on one thing only: what is live, and what is now.
   Gold stays on picks and rings, green on money, cyan on rank. */
body.dhskin{
  --ink:#081120;          /* page */
  --slate:#0f1e35;        /* panes */
  --slate-2:#1b2c48;      /* rows */
  --line:#1d3050;
  --text:#f2f7ff;
  --muted:#7d92ae;
  --red:#e8402f;          /* live, and the rule under the header */
  --money:#5fd39b;
  --teal:#54c7d6;
  --blue:#54c7d6;         /* position rank, now the same cyan */
  --gold:#f2b01e;
  --r:4px;
  /* The block face. Used for names, figures and titles — never for prose. */
  --block:'Archivo Black','Archivo',system-ui,sans-serif;
  /* Not background-attachment:fixed — iOS sizes a fixed background against
     the document rather than the viewport, which is its own kind of trouble
     on a page that can scroll. */
  background-color:#081120;
  background-image:linear-gradient(180deg,#0b1526 0%,#081120 60%);
  background-repeat:no-repeat;
  background-size:100% 100dvh;
}

/* ── nothing wider than the screen ────────────────────────────────────
   The wordmark is a good deal wider set in Archivo Black caps than it was
   in Bitter, and .brand-name had no min-width:0 — so it refused to shrink,
   the header ran past the viewport, and the whole page became pannable
   sideways. That pan is what shifted the bar right and cut it off. */
html:has(body.dhskin),body.dhskin{max-width:100%;overflow-x:hidden}
body.dhskin .topbar{width:100%;max-width:100%;box-sizing:border-box}
body.dhskin .brand{min-width:0;flex:0 1 auto}
body.dhskin .brand-name{min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
body.dhskin .brand-mark{flex:0 0 auto}
body.dhskin .topbar-right{flex:0 0 auto;min-width:0}
body.dhskin .topbar{background:#060d18}

/* Square everything the hub draws. */
body.dhskin .evrow,body.dhskin .teamcard,body.dhskin .rrow,body.dhskin .prow,
body.dhskin .dpick,body.dhskin .trade,body.dhskin .tb-item,body.dhskin .note-row,
body.dhskin .offer-tally,body.dhskin .newsrow,body.dhskin .openrow,
body.dhskin .teamcard,body.dhskin .filterrow{border-radius:4px}
body.dhskin .sheet-card,body.dhskin .modal-card{border-radius:6px}
body.dhskin .trade-pick,body.dhskin .dpick-no{border-radius:2px}

/* On a phone a sheet is the screen, not a card floating on it. The inset
   and the rounded corners were invisible while the header was the same
   near-black as everything behind it; against a red bar they read as the
   banner being shifted down and stopping short of both edges. So the card
   fills the space under the header and the bar runs edge to edge. */
@media (max-width:1080px){
  /* The hub's home page is exactly one screen: the header, then a grid
     sized to whatever is left. Nothing on it scrolls — the drawer and the
     sheets do their own scrolling — so the page itself is pinned. */
  html:has(body.dhskin .home),body.dhskin:has(.home){height:100dvh;overflow:hidden}

  body.dhskin .sheet{padding:0}
  body.dhskin .sheet-card{width:100%;height:100%;max-height:100%;
    border-radius:0;border-left:0;border-right:0;border-top:0;
    padding-bottom:var(--sab,0px)}
}

/* A sheet announces itself with the bar, not with a rule under it. */
body.dhskin .sheet-head{background:var(--red);border-bottom:0}
body.dhskin .sheet-head b{font-family:var(--block);font-weight:400;font-size:16px;
  letter-spacing:.005em;text-transform:uppercase;color:#fff}
body.dhskin .sheet-x,body.dhskin .sheet-caret{color:#ffffffb8}
body.dhskin .modal-head{background:var(--red);border-bottom:0;
  border-radius:6px 6px 0 0;font-family:var(--block);font-weight:400;
  font-size:13px;letter-spacing:.02em;color:#fff}
body.dhskin .modal-x{color:#ffffffb8}

/* ── the block face, where it earns its keep ──────────────────────────
   Names, money and rank are what you scan a card for. Everything else —
   the team, the contract year, the prose — stays in Barlow, or the whole
   card shouts and nothing stands out. */
body.dhskin .rrow-name b,
body.dhskin .tb-item-mid b,
body.dhskin .trade-asset-mid b{font-family:var(--block);font-weight:400;
  text-transform:uppercase;letter-spacing:-.005em}
body.dhskin .rrow-name b{font-size:13px}
body.dhskin .tb-item-mid b,body.dhskin .trade-asset-mid b{font-size:11.5px}
body.dhskin .nom-name{font-family:var(--block);font-weight:400;font-size:29px;
  text-transform:uppercase;letter-spacing:-.02em}

/* Money. */
body.dhskin .rrow-sal,body.dhskin .tb-item-sal,body.dhskin .prow-cost,
body.dhskin .nom-sal,body.dhskin .cap-power,body.dhskin .rostercap b,
body.dhskin .tally-fig b,body.dhskin .teamcap b,body.dhskin .stat-cell b{
  font-family:var(--block);font-weight:400;letter-spacing:-.01em}
body.dhskin .rrow-sal{font-size:14px}
body.dhskin .nom-sal{font-size:21px}
body.dhskin .stat-cell b{font-size:17px}

/* Rank. */
body.dhskin .rrow-right .rrow-rank,body.dhskin .pc-cost .rrow-rank{
  font-family:var(--block);font-weight:400;font-size:11px;
  letter-spacing:.01em;color:var(--blue)}

/* Pick numbers are figures too, and they already carry the medal colours. */
body.dhskin .trade-pick,body.dhskin .dpick-no,body.dhskin .railpick-no{
  font-family:var(--block);font-weight:400;letter-spacing:-.01em}

/* Event titles and the wordmark carry the same voice as a sheet title. */
body.dhskin .evtext b{font-family:var(--block);font-weight:400;
  text-transform:uppercase;letter-spacing:-.01em;font-size:15px}
body.dhskin .brand-name{font-family:var(--block);font-weight:400;
  text-transform:uppercase;letter-spacing:0;font-size:16px}
@media (max-width:1080px){
  /* Four controls and a wordmark on one line. It fits at full width with
     room to spare; min-width:0 above is what lets it ellipsis rather than
     push, if a narrower phone ever needs it to. */
  body.dhskin .brand-name{font-size:15.5px;letter-spacing:-.01em}
  body.dhskin .topbar{gap:9px}
}


/* ── the trades sheet, on the skin ────────────────────────────────────
   The button is positioned against the card's padding box, so the card's
   own padding-bottom doesn't lift it — it needs the safe-area inset on its
   own offset or it sits under the home indicator and reads as cut off. */
body.dhskin #tradesSheet .fab-trade{bottom:calc(16px + var(--sab,0px))}

/* Nothing in a sheet scrolls sideways. A flex child only honours its
   ellipsis if it is allowed to shrink, and several links in this chain
   never had min-width:0 — so a long name pushed the row wider than the
   card instead of truncating, and the card took the panel with it. */
body.dhskin .sheet-body,body.dhskin .tradepage{overflow-x:hidden;min-width:0}
body.dhskin .tradepage{max-width:100%}
body.dhskin .trade,body.dhskin .trade-body,body.dhskin .trade-head,
body.dhskin .trade-team,body.dhskin .trade-side,body.dhskin .trade-asset,
body.dhskin .tb-item,body.dhskin .tb-item-mid,body.dhskin .openrow,
body.dhskin .note-row,body.dhskin .note-who{min-width:0}
body.dhskin .trade-team b,body.dhskin .trade-asset-mid b,
body.dhskin .tb-item-mid b,body.dhskin .note-who b{min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* The sub-line under a name is the other thing that can run long. */
body.dhskin .tb-item-sub,body.dhskin .trade-asset-mid .tb-item-sub{
  min-width:0;overflow:hidden}


/* ── the trade filter card ────────────────────────────────────────────
   The body is a flex child of a card capped at 82dvh. Without flex:1 and
   min-height:0 it refused to shrink, so the list ran past the bottom of
   the card and was clipped rather than scrolled — the scrollbar was on an
   element that never became shorter than its content.

   With the body holding the height, the search is simply the row above the
   scroller: it stays put while the list moves under it, and it doesn't need
   to be sticky to do it. */
.filtercard .modal-body{flex:1;min-height:0;display:flex;flex-direction:column;
  gap:12px;overflow:hidden}
.filtercard .filtersearch{flex:0 0 auto}
.filtercard .filterlist{flex:1;min-height:0;max-height:none;margin-top:0;
  overflow-y:auto;overscroll-behavior:contain;
  /* Room at the foot so the last row clears the card's edge. */
  padding-bottom:4px}
/* A card that has something to scroll should look like it: give it a floor
   to scroll within rather than hugging two rows. */
.filtercard{height:min(82dvh,560px)}

/* ── the block list ───────────────────────────────────────────────────
   A blocked player's card is the compact asset row the builder uses, but
   here it sits beside full trade cards in the other two toggles. Matching
   the trade card's padding lines the two up edge to edge and, more to the
   point, lines their contents up too. */
body.dhskin .blocklist .tb-item{width:100%;padding:11px 13px;gap:9px}
body.dhskin .blocklist .tb-item .tb-face,
body.dhskin .blocklist .tb-item .trade-pick{margin-left:0}


/* ── the draft board, fifteen years of it ─────────────────────────────
   The strip scrolls: fifteen years never fit on a phone, and shrinking
   them until they do would make every year illegible to save one swipe. */
.yearstrip{width:100%;overflow-x:auto;overscroll-behavior-x:contain;
  -webkit-overflow-scrolling:touch;scrollbar-width:none}
.yearstrip::-webkit-scrollbar{display:none}
.yearstrip .seg{width:max-content;margin:0 auto;flex-wrap:nowrap}
.yearstrip .seg button{flex:0 0 auto;white-space:nowrap}
/* Three states: drafts already held, the one being run now, and the years
   still owed. Unselected they're all quiet; the colour arrives on the one
   you pick, so the strip says which kind of year you're looking at. */
.yearstrip .seg button{position:relative}
.yearstrip .seg button.y-past,.yearstrip .seg button.y-next{color:#6f7f95}
.yearstrip .seg button.y-now{color:var(--text)}
.yearstrip .seg button.y-now::after{content:"";position:absolute;left:50%;
  bottom:3px;width:3px;height:3px;margin-left:-1.5px;border-radius:50%;
  background:var(--red)}
/* A draft that has been held, one that hasn't, and the live one. */
.yearstrip .seg button.on.y-past{color:var(--red)}
.yearstrip .seg button.on.y-next{color:var(--green)}
.yearstrip .seg button.on.y-now{color:#fff}

/* The filter and its count share a line, one at each end. */
.draftrow{display:flex;align-items:center;justify-content:space-between;
  gap:10px;width:100%}
.draftrow .teampick{flex:0 1 auto;min-width:0}
.draftrow .draftcount{flex:0 0 auto;text-align:right}
.draftfilter{flex-direction:column;align-items:stretch;gap:10px}

/* ── a pick from a draft already held ─────────────────────────────────
   The player is the headline; the owner who took him is the footnote. */
.dhist{align-items:center}
.dhist .dpick-who{gap:2px}
/* Same size and shape as the owner's photo opposite it, so the two bookend
   the row and the name and its sub-line sit between them. */
.dhist > .dpick-shot{width:28px;height:28px}
.dhist-sub{display:flex;align-items:center;gap:5px;min-width:0;
  font-family:var(--cond);font-size:10.5px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.dpick-shot{flex:0 0 auto;width:28px;height:28px;border-radius:50%;
  overflow:hidden;background:var(--slate-2);display:flex;
  align-items:center;justify-content:center}
.dpick-shot img{width:100%;height:100%;object-fit:cover;
  object-position:top center}
.dpick-shot .me-initials{font-size:10px}
.dhist-logo{flex:0 0 auto;width:14px;height:14px;object-fit:contain}
.dhist-team{flex:0 0 auto}
.dhist-pos{flex:0 0 auto;font-weight:700}
.dhist-dot{flex:0 0 auto;opacity:.6}
.dhist-owner{min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}

/* An owner who has left the league. No photo was ever taken for the app,
   and none is coming — so the slot says so rather than sitting empty. */
.dpick-face.gone,.teamface.gone{display:flex;align-items:center;
  justify-content:center;color:#7d8a9c;background:var(--slate-2)}
.dpick-face.gone svg,.teamface.gone svg{width:66%;height:66%;display:block}
.teamcard.gone .teamname{color:var(--muted)}


/* ── the rookie board ─────────────────────────────────────────────────
   Two halves: the draft order on one side, the class on the other. On a
   phone they stack, board first — you look up whose pick it is far more
   often than you scroll the class. */
/* Four regions, two of them full width: the clock, the commissioner's row,
   then the draft on the left and the class on the right. Same arrangement
   at every size — a phone gets narrower columns, not a different page. */
.rookiepage{display:grid;max-width:1500px;margin:0 auto;
  grid-template-areas:"clock clock" "admin admin" "board car";
  grid-template-rows:auto auto minmax(0,1fr);
  grid-template-columns:minmax(0,0.9fr) minmax(0,1fr);
  gap:8px;padding:8px 8px calc(8px + var(--sab,0px));
  height:calc(100dvh - var(--bar-h,53px))}
.rkclock{grid-area:clock}
.rkadmin{grid-area:admin}
.rkboard{grid-area:board}
.rkcar{grid-area:car}
.rkboard,.rkcar{height:100%;min-height:0}
/* Hidden furniture must not leave its row behind. */
.rkclock[hidden],.rkadmin[hidden]{display:none}

@media (min-width:1081px){
  .rookiepage{grid-template-columns:minmax(0,1fr) 420px;
    gap:14px 20px;padding:20px 22px 26px}
}

/* ── the two columns on a phone ───────────────────────────────────────
   Both are narrow, so everything inside them loses a size and the parts
   that only repeat what's already on screen come out entirely. */
@media (max-width:1080px){
  .rkboard-head{padding:8px 10px}
  .rkboard-head b{font-size:11.5px}
  .rkboard-list{padding:8px 8px 12px}
  .rkround-head{font-size:9.5px;letter-spacing:.1em}
  .rkslot{gap:6px;padding:5px 6px}
  .rkslot-no{min-width:28px;padding:2px 3px;font-size:10px}
  .rkslot-face{width:20px;height:20px}
  .rkslot-face .me-initials{font-size:8px}
  .rkslot-who b{font-size:11px}
  .rkslot-who span{font-size:9px}
  /* The slot already says whose pick it is; the tag would wrap the row. */
  .rkslot-tag{display:none}

  .rkcar-top{padding:8px 7px;gap:6px}
  .rkpos button{font-size:10px;letter-spacing:.04em;padding:5px 8px}
  .rktabs button{font-size:10px;padding:6px 8px}
  .rktabs button[data-count]:not([data-count=""])::after{margin-left:4px;
    padding:0 4px;font-size:9px}
  .rklist{padding:7px 7px 12px;gap:4px}
  .rkrow{gap:6px;padding:6px 7px}
  .rk-target{width:20px;height:20px}
  .rk-target svg{width:16px;height:16px}
  .rk-rank{min-width:24px;font-size:11px}
  .rk-face{width:26px;height:26px}
  .rk-name b{font-size:11.5px}
  .rk-sub{gap:4px;font-size:9px}
  /* Between the college and the pro team, the college is the one that
     tells you something about a rookie. */
  .rk-sub > span:last-child:not(.rk-pos):not(.rk-college){display:none}
  .rk-bust{padding:3px 6px;font-size:9px;letter-spacing:.08em}

  .rkclock{padding:7px 10px;gap:8px}
  .rkclock-face{width:26px;height:26px}
  .rkclock-who b{font-size:12.5px}
  .rkclock-time{font-size:17px}
  .rkadmin{padding:8px 10px;gap:7px}
  .rkadmin input{font-size:12px;padding:4px 6px}
  .rkadmin input[type=number]{width:58px}
  .rkadmin label{font-size:9.5px;letter-spacing:.08em}
}

.rkboard,.rkcar{display:flex;flex-direction:column;min-height:0;
  background:var(--slate);border:1px solid var(--line);border-radius:6px;
  overflow:hidden}
.rkboard-head,.rkcar-top{flex:0 0 auto;padding:11px 13px;
  border-bottom:1px solid var(--line)}
.rkboard-head{display:flex;align-items:baseline;justify-content:space-between;
  gap:10px}
/* One line, whatever the column width — the year plus two words is short
   enough to shrink rather than wrap. */
.rkboard-head b{font-family:var(--block,'Archivo Black',sans-serif);
  font-weight:400;font-size:15px;text-transform:uppercase;letter-spacing:-.01em;
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.rkboard-list{flex:1;min-height:0;overflow-y:auto;padding:10px 12px 14px}

.rkround + .rkround{margin-top:12px}
.rkround-head{display:flex;align-items:baseline;justify-content:space-between;
  padding-bottom:5px;margin-bottom:6px;border-bottom:1px solid var(--line);
  font-family:var(--cond);font-size:11px;font-weight:700;letter-spacing:.14em;
  text-transform:uppercase;color:var(--muted)}
.rkround-list{display:flex;flex-direction:column;gap:5px}
.rkslot{display:flex;align-items:center;gap:9px;padding:6px 9px;
  background:var(--slate-2);border:1px solid transparent;border-radius:4px}
.rkslot.mine{border-color:var(--green);background:#14301f}
.rkslot-no{flex:0 0 auto;min-width:36px;text-align:center;padding:3px 6px;
  border-radius:2px;font-family:var(--block,'Archivo Black',sans-serif);
  font-weight:400;font-size:11px;color:#1a1408;background:var(--gold)}
.rkslot-no.r2{background:#c6ced8}
.rkslot-no.r3{background:#c88a52}
.rkslot-no.r4{background:var(--slate);color:var(--text);
  box-shadow:inset 0 0 0 1px var(--line)}
.rkslot-face{flex:0 0 auto;width:26px;height:26px;border-radius:50%;
  overflow:hidden;background:var(--slate);display:flex;align-items:center;
  justify-content:center}
.rkslot-face img{width:100%;height:100%;object-fit:cover;
  object-position:top center}
.rkslot-face .me-initials{font-size:9px}
.rkslot-who{min-width:0;display:flex;flex-direction:column;line-height:1.25}
.rkslot-who b{font-size:12.5px;font-weight:600;min-width:0;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap}
.rkslot-who span{font-family:var(--cond);font-size:10px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}

/* ── the sidecar ──────────────────────────────────────────────────────
   Two toggles: which list, then which position. The second is subordinate
   to the first, so it sits under it and reads quieter. */
/* Centred, and each strip only as wide as the buttons inside it — a
   full-width segment would stretch five position labels across a column
   they don't need. */
.rkcar-top{display:flex;flex-direction:column;align-items:center;gap:8px}
.rktabs,.rkpos{width:max-content;max-width:100%;margin:0 auto}
.rktabs button,.rkpos button{flex:0 0 auto;padding-left:11px;padding-right:11px}
.rkpos button{font-size:11px;letter-spacing:.1em;padding-left:13px;
  padding-right:13px}
/* A tab carries its own total, so Targets says it has something in it
   without being opened. */
.rktabs button[data-count]:not([data-count=""])::after{
  content:attr(data-count);margin-left:6px;font-size:9.5px;font-weight:700;
  padding:1px 5px;border-radius:99px;background:var(--slate);
  color:var(--muted)}
.rktabs button.on[data-count]:not([data-count=""])::after{
  background:#00000033;color:#fff}
.rkcount{font-family:var(--cond);font-size:10.5px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted)}

.rklist{flex:1;min-height:0;overflow-y:auto;padding:8px 10px 14px;
  display:flex;flex-direction:column;gap:5px}
.rkrow{display:flex;align-items:center;gap:8px;padding:7px 9px;min-width:0;
  background:var(--slate-2);border:1px solid transparent;border-radius:4px}
.rkrow.targeted{border-color:var(--gold);background:#241f10}
.rkrow.busted{opacity:.5}
.rkrow.taken{opacity:.45}

/* The bullseye, on the left, exactly where the auction board puts it. */
.rk-target{flex:0 0 auto;width:24px;height:24px;padding:0;border:0;
  background:none;color:#4a5666;cursor:pointer;display:flex;
  align-items:center;justify-content:center;
  -webkit-tap-highlight-color:transparent;transition:color .12s,transform .1s}
.rk-target svg{width:18px;height:18px;display:block}
.rk-target:hover{color:var(--muted)}
.rk-target.on{color:var(--gold)}
.rk-target:active{transform:scale(.9)}

.rk-rank{flex:0 0 auto;min-width:30px;font-family:var(--block,'Archivo Black',sans-serif);
  font-weight:400;font-size:12px;color:var(--muted)}
.rk-face{flex:0 0 auto;width:30px;height:30px;border-radius:50%;
  overflow:hidden;background:var(--slate);display:flex;align-items:center;
  justify-content:center}
.rk-face img{width:100%;height:100%;object-fit:cover;object-position:top center}
.rk-face .me-initials{font-size:10px}
.rk-mid{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.rk-name{min-width:0;display:flex}
.rk-name b{min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap;font-size:12.5px}
.rk-sub{display:flex;align-items:center;gap:6px;min-width:0;
  font-family:var(--cond);font-size:10px;letter-spacing:.06em;
  text-transform:uppercase;color:var(--muted)}
.rk-pos{flex:0 0 auto;font-weight:700}
.rk-college{min-width:0;overflow:hidden;text-overflow:ellipsis;
  white-space:nowrap}
.rk-taken{flex:0 0 auto;color:var(--red)}

.rk-bust{flex:0 0 auto;padding:4px 9px;border-radius:3px;cursor:pointer;
  background:none;border:1px solid var(--line);color:var(--muted);
  font-family:var(--cond);font-size:10px;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;-webkit-tap-highlight-color:transparent;
  transition:border-color .12s,color .12s,background-color .12s}
.rk-bust:hover{border-color:#4a5666;color:var(--text)}
.rk-bust.on{background:#3a1d1a;border-color:var(--red);color:#ff9c92}

body.dhskin .rk-name b{font-family:var(--block);font-weight:400;
  text-transform:uppercase;letter-spacing:-.005em}


/* ── the draft, live ──────────────────────────────────────────────────
   The clock is the only thing on this page that changes every second, so
   it gets the one bright colour and everything else stays still. */
.rkclock{flex:0 0 auto;display:flex;align-items:center;gap:10px;
  padding:9px 13px;border-bottom:1px solid var(--line);background:#0d1b30}
.rkclock-face{flex:0 0 auto;width:30px;height:30px;border-radius:50%;
  overflow:hidden;background:var(--slate-2);display:flex;align-items:center;
  justify-content:center}
.rkclock-face img{width:100%;height:100%;object-fit:cover;
  object-position:top center}
.rkclock-face .me-initials{font-size:10px}
.rkclock-who{flex:1;min-width:0;display:flex;flex-direction:column;
  line-height:1.2}
.rkclock-who b{font-family:var(--block,'Archivo Black',sans-serif);
  font-weight:400;font-size:14px;text-transform:uppercase;min-width:0;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rkclock-who span{font-family:var(--cond);font-size:10px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted)}
.rkclock-time{flex:0 0 auto;font-family:var(--block,'Archivo Black',sans-serif);
  font-weight:400;font-size:20px;letter-spacing:-.02em;
  font-variant-numeric:tabular-nums;color:var(--text)}
/* Your pick, and a pick that has run over. */
.rkclock.mine{background:#12281c}
.rkclock.mine .rkclock-time{color:var(--green)}
.rkclock.out .rkclock-time{color:var(--red)}

/* The commissioner's row. Two lines: what the draft is set to, and what it
   is doing. Nobody else is sent this markup at all. */
.rkadmin{flex:0 0 auto;display:flex;flex-direction:column;gap:8px;
  padding:10px 13px;border-bottom:1px solid var(--line);background:#0b1526}
.rkadmin-set,.rkadmin-run{display:flex;align-items:center;gap:8px;
  flex-wrap:wrap}
.rkadmin label{display:flex;align-items:center;gap:6px;
  font-family:var(--cond);font-size:10.5px;font-weight:700;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted)}
.rkadmin input{background:var(--ink);border:1px solid var(--line);
  border-radius:3px;padding:5px 7px;color:var(--text);font-family:var(--ui);
  font-size:13px}
.rkadmin input[type=number]{width:70px}
.rkadmin .btn:disabled{opacity:.4;cursor:default}

/* ── the slot on the clock ────────────────────────────────────────────
   The one place on the board that accepts a player. It says so, and it
   says it differently depending on whether you're the one who can. */
.rkslot.onclock{border-color:var(--gold);background:#241f10}
.rkslot.onclock.mine{border-color:var(--green);background:#12281c}
.rkslot.onclock.over{border-style:dashed;border-width:2px;
  background:#16351f}
.rkslot-tag{flex:0 0 auto;font-family:var(--cond);font-size:9.5px;
  font-weight:700;letter-spacing:.12em;text-transform:uppercase;
  color:var(--muted)}
.rkslot.filled .rkslot-player{font-family:var(--block,'Archivo Black',sans-serif);
  font-weight:400;text-transform:uppercase;font-size:12px}
.rkslot.filled{opacity:.92}

/* A row being carried, and the card that follows the finger. */
.rkrow.draggable{cursor:grab;touch-action:none}
.rkrow.lifting{opacity:.35}
body.rk-dragging{cursor:grabbing;-webkit-user-select:none;user-select:none}
.rk-ghost{position:fixed;z-index:120;transform:translate(-50%,-140%);
  pointer-events:none;display:flex;flex-direction:column;gap:1px;
  padding:7px 11px;border-radius:4px;background:var(--slate-2);
  border:1px solid var(--gold);box-shadow:0 12px 28px #000a}
.rk-ghost b{font-family:var(--block,'Archivo Black',sans-serif);
  font-weight:400;font-size:12px;text-transform:uppercase;white-space:nowrap}
.rk-ghost span{font-family:var(--cond);font-size:10px;letter-spacing:.1em;
  color:var(--muted)}

/* The last word before he's yours. */
.rkconfirm-card{width:min(420px,100%)}
.rkconfirm-player{display:flex;align-items:center;gap:11px;padding:11px;
  background:var(--slate-2);border:1px solid var(--line);border-radius:4px;
  margin-bottom:12px}
.rkconfirm-player .rk-face{width:44px;height:44px}
.rkconfirm-mid{min-width:0;display:flex;flex-direction:column;gap:2px}
.rkconfirm-mid b{font-family:var(--block,'Archivo Black',sans-serif);
  font-weight:400;font-size:16px;text-transform:uppercase}
.rkconfirm-sub{display:flex;align-items:center;gap:7px;
  font-family:var(--cond);font-size:10.5px;letter-spacing:.08em;
  text-transform:uppercase;color:var(--muted)}
.rk-err{color:var(--red)}
