/* ============================================================================
   2026 FBS SEASON CALENDAR

   Stadium at night. Near-black field with a green cast, chalk type, one amber
   accent for anything live or active, and a cool cyan reserved strictly for
   interactive affordances so the two never compete.

   One web font, served from this origin and nothing else. Linking a font from
   a third party would put every visitor's address in front of somebody they
   did not choose on every page load, which the privacy notice is specific
   about — so the file is ours, the policy allows font-src 'self', and no
   external host is involved.
   ========================================================================= */
/*
 * The display face, shipped rather than hoped for.
 *
 * The stack asked for Oswald and the site never carried it, so every visitor
 * without Oswald installed — which is almost everyone, including the machine
 * this was built on — saw Arial Narrow or Impact instead. The masthead was not
 * the typeface it had been designed in.
 *
 * A variable font, so 400, 600 and 700 come from one request instead of three.
 * `swap` because the words matter more than the lettering: they render at once
 * in the fallback and change over when the font arrives.
 *
 * No unicode-range: there is a single file, so narrowing it would save no
 * download, and anything it cannot draw falls back per character anyway.
 */
@font-face {
  font-family: "Oswald";
  src: url("/web/assets/fonts/oswald-latin.woff2") format("woff2");
  font-weight: 200 700;
  font-style: normal;
  font-display: swap;
}

:root{
  /* field — five steps, so elevation is a real scale rather than guesswork */
  --f0:#040705;      /* page floor, behind everything */
  --f1:#070c09;      /* page */
  --f2:#0c1310;      /* raised: cards, bars */
  --f3:#121b16;      /* raised further: hover, saturday cells */
  --f4:#18241d;      /* highest: active chips, pressed states */

  --line:#1b2a22;    /* structural */
  --line-2:#132019;  /* hairline */
  --line-3:#24382d;  /* emphasised */

  --chalk:#f2f6f0;
  --chalk-2:#c3d0c6;
  --muted:#8ea299;
  --muted-2:#5f7369;

  --amber:#ffc247;       /* live, active, today */
  --amber-2:#8a6a1d;
  --amber-ghost:rgba(255,194,71,.09);
  --ice:#79d2e8;         /* interactive affordance only */
  --flag:#ff6055;

  --r-sm:3px;
  --r-md:6px;
  --r-lg:10px;
  --r-pill:100px;
  /* The shell width every band shares. Named so the five cannot drift. */
  --shell:1760px;

  --barh:0px;
  --monthbarh:0px;
  --theadh:0px;
  --receipth:0px;

  --num:ui-monospace,"SF Mono",SFMono-Regular,Menlo,Consolas,"Liberation Mono",monospace;
  --sans:ui-sans-serif,-apple-system,"Segoe UI",Roboto,Helvetica,sans-serif;
  --display:"Oswald","Barlow Condensed","Archivo Narrow","Arial Narrow",Impact,var(--sans);

  --shadow-1:0 1px 2px rgba(0,0,0,.5);
  --shadow-2:0 6px 18px -8px rgba(0,0,0,.75);
  --shadow-3:0 24px 60px -20px rgba(0,0,0,.85);

  --grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
}

*{box-sizing:border-box}

/* Any `display` rule silently beats the hidden attribute's default, which is
   how the filter drawer and the empty count pip both rendered while marked
   hidden. Settle it once for everything. */
[hidden]{display:none !important}
html,body{margin:0;padding:0}
html{scroll-behavior:smooth}
body{
  min-height:100vh;color:var(--chalk);
  font-family:var(--sans);font-size:13.5px;line-height:1.55;
  -webkit-font-smoothing:antialiased;
  background:
    radial-gradient(120% 80% at 50% -10%, #10201a 0%, transparent 55%),
    var(--f1);
}
body::after{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:999;
  background-image:var(--grain);opacity:.03;mix-blend-mode:overlay;
}
button,input,select{font:inherit;color:inherit}
:focus-visible{outline:2px solid var(--ice);outline-offset:2px;border-radius:var(--r-sm)}
::selection{background:var(--amber);color:#150f02}
.mono,.num{font-family:var(--num);font-variant-numeric:tabular-nums}
.vh{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
/* `scrollbar-width: thin` alone leaves Chrome painting a pale default thumb,
   which read as a bright bar under the week rail. Set the colours explicitly. */
*{scrollbar-color:var(--line-3) transparent}
::-webkit-scrollbar{width:10px;height:10px}
::-webkit-scrollbar-track{background:transparent}
::-webkit-scrollbar-thumb{
  background:var(--line-3);border-radius:var(--r-pill);
  border:3px solid transparent;background-clip:content-box;
}
::-webkit-scrollbar-thumb:hover{background:var(--muted-2);background-clip:content-box}

@media (prefers-reduced-motion:reduce){
  *{transition:none!important;animation:none!important}
  html{scroll-behavior:auto}
}

/* ============================================================ masthead */
.mast{
  position:relative;overflow:hidden;border-bottom:1px solid var(--line);
  background:
    radial-gradient(90% 160% at 8% -60%, rgba(66,120,96,.30) 0%, transparent 62%),
    repeating-linear-gradient(90deg, transparent 0 92px, rgba(242,246,240,.028) 92px 93px),
    linear-gradient(180deg,#0f1a15 0%, var(--f0) 100%);
}
.mast::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:linear-gradient(90deg,transparent, rgba(255,194,71,.55) 22%, transparent 60%);
}
.mast-in{
  position:relative;display:flex;align-items:flex-end;gap:28px;flex-wrap:wrap;
  padding:22px 24px 18px;max-width:var(--shell);margin-inline:auto;
}
.brand{display:flex;align-items:baseline;gap:12px;line-height:.85}
.brand .yr{
  font-family:var(--display);font-weight:700;font-size:clamp(38px,6.2vw,60px);
  letter-spacing:-1px;color:var(--amber);
  text-shadow:0 0 40px rgba(255,194,71,.28);
}
.brand .ttl{
  font-family:var(--display);font-weight:600;font-size:clamp(15px,2.2vw,21px);
  letter-spacing:3px;text-transform:uppercase;color:var(--chalk);
}
.brand .ttl small{
  display:block;font-size:9.5px;letter-spacing:3.6px;color:var(--muted-2);
  font-weight:400;margin-top:5px;
}

.tally{
  margin-left:auto;display:flex;gap:1px;background:var(--line-2);
  border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;
}
.tally div{background:rgba(4,7,5,.7);padding:9px 18px;min-width:92px}
.tally b{
  display:block;font-family:var(--num);font-size:23px;font-weight:600;
  color:var(--amber);letter-spacing:-.6px;line-height:1.05;font-variant-numeric:tabular-nums;
}
.tally i{
  display:block;font-style:normal;font-size:9px;letter-spacing:1.7px;
  text-transform:uppercase;color:var(--muted-2);margin-top:4px;
}
.tally div.rng b{font-size:14px;padding-top:7px}

/* ============================================== command bar + filters */
.controls{
  position:sticky;top:0;z-index:30;border-bottom:1px solid var(--line);
  background:rgba(7,12,9,.88);backdrop-filter:blur(14px) saturate(1.3);
}
.bar{
  display:flex;gap:8px;align-items:center;flex-wrap:wrap;
  padding:10px 24px;max-width:var(--shell);margin-inline:auto;
}
.bar-gap{flex:1 1 auto}

.seg{
  display:flex;border:1px solid var(--line);border-radius:var(--r-md);
  overflow:hidden;flex:none;background:var(--f2);
}
.seg button{
  background:transparent;border:0;padding:8px 16px;cursor:pointer;color:var(--muted);
  font-family:var(--display);font-size:13px;letter-spacing:1.4px;text-transform:uppercase;
  position:relative;transition:color .16s,background .16s;
}
.seg button + button{border-left:1px solid var(--line-2)}
.seg button:hover{color:var(--chalk);background:var(--f3)}
.seg button[aria-pressed=true]{color:#150f02;background:var(--amber)}

.search-wrap{position:relative;flex:1 1 210px;max-width:300px;display:flex;align-items:center}
.search-icon{
  position:absolute;left:11px;font-family:var(--num);font-size:11px;color:var(--muted-2);
  pointer-events:none;border:1px solid var(--line-3);border-radius:3px;
  padding:0 4px;line-height:1.35;
}
.search-wrap input{
  width:100%;background:var(--f2);border:1px solid var(--line);
  padding:8px 12px 8px 34px;border-radius:var(--r-md);
  font-size:13px;transition:border-color .16s,background .16s;
}
.search-wrap input:hover{border-color:var(--line-3)}
.search-wrap input:focus{border-color:var(--ice);background:var(--f1);outline:none}
.search-wrap input::placeholder{color:var(--muted-2)}
.search-wrap input::-webkit-search-cancel-button{filter:invert(.6)}

.btn{
  background:var(--f2);border:1px solid var(--line);color:var(--chalk-2);
  padding:8px 14px;border-radius:var(--r-md);cursor:pointer;white-space:nowrap;
  transition:background .16s,border-color .16s,color .16s,transform .08s;
}
.btn:hover{background:var(--f3);border-color:var(--line-3);color:var(--chalk)}
.btn:active{transform:translateY(1px)}
.btn.go{
  background:var(--amber);color:#150f02;border-color:var(--amber);font-weight:600;
  box-shadow:0 2px 10px -4px rgba(255,194,71,.7);
}
.btn.go:hover{background:#ffd06b;border-color:#ffd06b;color:#150f02}
.btn.sm{padding:6px 11px;font-size:12.5px}
.btn.ghost{background:transparent}
.btn.icon{width:30px;padding:6px 0;text-align:center}
.btn[disabled]{opacity:.4;cursor:not-allowed}
.btn.toggle[aria-expanded=true]{background:var(--f4);border-color:var(--amber-2);color:var(--chalk)}
.pip{
  display:inline-block;margin-left:7px;min-width:17px;padding:0 5px;
  background:var(--amber);color:#150f02;border-radius:var(--r-pill);
  font-family:var(--num);font-size:10.5px;font-weight:600;line-height:16px;text-align:center;
}
.follow-cta{letter-spacing:.2px}

.filters{
  border-top:1px solid var(--line-2);background:var(--f0);
  padding:14px 24px 16px;max-width:var(--shell);margin-inline:auto;
  display:grid;gap:12px;
  animation:drop .18s ease-out;
}
@keyframes drop{from{opacity:0;transform:translateY(-6px)}to{opacity:1;transform:none}}
.filter-group{display:flex;gap:10px;align-items:center;flex-wrap:wrap}
.filter-group.wrapping{align-items:flex-start}
.ctl-lbl{
  font-family:var(--display);font-size:10px;letter-spacing:2px;text-transform:uppercase;
  color:var(--muted-2);flex:none;min-width:78px;padding-top:5px;
}
label.chk{
  display:flex;gap:7px;align-items:center;color:var(--muted);font-size:12.5px;
  cursor:pointer;user-select:none;white-space:nowrap;padding:4px 0;
}
label.chk:hover{color:var(--chalk)}
label.chk input{accent-color:var(--amber);margin:0;width:15px;height:15px}
select.tz{
  background:var(--f2);border:1px solid var(--line);padding:7px 11px;
  border-radius:var(--r-md);font-size:12.5px;cursor:pointer;min-width:170px;
}
select.tz:hover{border-color:var(--line-3)}
select.tz:focus{border-color:var(--ice);outline:none}

.chips{display:flex;gap:5px;flex-wrap:wrap;align-items:center}
.chip{
  display:inline-flex;align-items:center;gap:7px;border:1px solid var(--line);
  background:var(--f2);padding:4px 11px 4px 8px;border-radius:var(--r-pill);
  cursor:pointer;font-size:12px;white-space:nowrap;
  transition:opacity .16s,border-color .16s,background .16s,color .16s;
}
.chip:hover{border-color:var(--line-3);background:var(--f3)}
.chip .dot{width:8px;height:8px;border-radius:50%;flex:none;box-shadow:0 0 8px -1px currentColor}
.chip .n{font-family:var(--num);color:var(--muted-2);font-size:10.5px}
.chip[data-on=false]{opacity:.32}
.chip[data-on=false] .dot{box-shadow:none}
.chip.win[data-on=true]{border-color:var(--amber-2);background:var(--amber-ghost)}
.chip-group{display:inline-flex;align-items:center;gap:1px}
.chip-group .chip{border-top-right-radius:0;border-bottom-right-radius:0}

.receipt{
  display:none;align-items:center;gap:10px;flex-wrap:wrap;
  padding:8px 24px;background:linear-gradient(90deg, rgba(255,194,71,.16), rgba(255,194,71,.05));
  border-bottom:1px solid var(--amber-2);
  font-size:12px;color:#ffe6b3;position:sticky;top:var(--barh);z-index:29;
}
.receipt.on{display:flex}
.receipt .tag{
  border:1px solid rgba(255,194,71,.35);padding:2px 9px;border-radius:var(--r-pill);
  background:rgba(255,194,71,.1);
}
.receipt .btn{background:transparent;border-color:rgba(255,194,71,.4);color:#ffe6b3}
.receipt .btn:hover{background:rgba(255,194,71,.16);color:#fff}

/*
 * Every band of the page — masthead, toolbar, filters, board, colophon — is
 * capped at the same width and centred on it. The cap was always there; the
 * centring was not, so on any display wider than the cap the whole page hugged
 * the left edge and left a stripe of empty floor down the right. It looked
 * fine on a laptop and wrong on a desktop, which is why it survived this long.
 */

/* ================================================================ views */
.wrap{padding:24px 24px 100px;max-width:var(--shell);margin-inline:auto}

/* Credit where the schedule comes from, and a note on the club marks.
   Attribution is not required by the data licence — it is recommended, costs a
   line, and is the difference between using somebody's work and helping
   yourself to it. Deliberately the quietest type on the page: it should be
   findable, never competing with a kickoff time. */
.colophon{border-top:1px solid var(--line-2);margin-top:8px}
.colophon-in{
  display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;
  padding:20px 24px 36px;max-width:var(--shell);margin-inline:auto;
}
.colophon-label{
  font-family:var(--display);font-size:10px;letter-spacing:2px;text-transform:uppercase;
  color:var(--muted-2);flex:0 0 auto;
}
.colophon p{margin:0;font-size:12px;line-height:1.6;color:var(--muted-2);max-width:74ch}
.colophon a,.colophon .linklike{
  color:var(--chalk-2);text-decoration:underline;text-underline-offset:3px;font-size:inherit;
}
.colophon a:hover,.colophon .linklike:hover{color:var(--amber)}

/* A ledger rather than paragraphs: the question is "what rows exist about me",
   and a list of labelled rows answers it at a glance where prose would not. */
.privacy .ledger{list-style:none;margin:0;padding:0;display:grid;gap:10px}
.privacy .ledger li{
  display:grid;grid-template-columns:minmax(140px,200px) 1fr;gap:6px 18px;
  padding:10px 0;border-top:1px solid var(--line-2);
}
.privacy .ledger li:first-child{border-top:0}
.privacy .ledger b{
  font-family:var(--display);font-size:11px;letter-spacing:1.4px;text-transform:uppercase;
  color:var(--chalk-2);
}
.privacy .ledger span{font-size:12.5px;line-height:1.6;color:var(--muted)}
@media (max-width:560px){
  .privacy .ledger li{grid-template-columns:1fr;gap:3px}
}

.weeks{
  display:flex;gap:6px;overflow-x:auto;margin-bottom:24px;
  border-bottom:1px solid var(--line);scrollbar-width:thin;scroll-snap-type:x proximity;
  scrollbar-color:var(--line-3) transparent;
  /* Top room for the NOW badge and the active tab's glow. `overflow-x: auto`
     makes the vertical axis clip too, so anything drawn above a tab is cut in
     half without it. */
  padding:12px 0 14px;
}
.weeks button{
  background:var(--f2);border:1px solid var(--line);color:var(--muted);
  padding:9px 15px;cursor:pointer;white-space:nowrap;border-radius:var(--r-md);
  font-family:var(--display);letter-spacing:1.5px;font-size:13.5px;text-transform:uppercase;
  transition:color .16s,border-color .16s,background .16s;flex:none;position:relative;
  scroll-snap-align:start;
}
.weeks button:hover{color:var(--chalk);border-color:var(--line-3);background:var(--f3)}
.weeks button[aria-pressed=true]{
  border-color:var(--amber);color:var(--amber);background:var(--amber-ghost);
  box-shadow:0 0 0 1px var(--amber), 0 4px 16px -8px rgba(255,194,71,.8);
}
.weeks button .c{font-family:var(--num);font-size:10px;color:var(--muted-2);margin-left:7px}
.weeks button[aria-pressed=true] .c{color:var(--amber);opacity:.8}
.weeks button.isnow::after{
  content:"NOW";position:absolute;top:-8px;right:-4px;
  background:var(--amber);color:#150f02;font-family:var(--display);font-size:8px;
  letter-spacing:1.2px;padding:1px 5px;border-radius:var(--r-pill);
}

.dayblock{
  margin-bottom:34px;
  animation:rise .4s cubic-bezier(.2,.7,.3,1) both;
  animation-delay:calc(var(--i,0) * 55ms);
}
@keyframes rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}

.dayhead{
  display:flex;align-items:center;gap:14px;position:relative;
  padding-bottom:10px;margin-bottom:14px;border-bottom:1px solid var(--line);
}
.dayhead h3{
  font-family:var(--display);font-size:23px;margin:0;letter-spacing:2px;
  font-weight:600;text-transform:uppercase;color:var(--chalk);
}
.dayhead .c{
  font-family:var(--num);font-size:11px;color:var(--muted-2);
  border:1px solid var(--line);border-radius:var(--r-pill);padding:2px 9px;
}
.dayhead.today h3{color:var(--amber)}
.dayhead.today::after{
  content:"";position:absolute;left:0;bottom:-1px;width:88px;height:2px;
  background:var(--amber);box-shadow:0 0 12px rgba(255,194,71,.7);
}
.nowchip{
  font-family:var(--display);font-size:9.5px;letter-spacing:2px;text-transform:uppercase;
  background:var(--amber);color:#150f02;padding:3px 9px;border-radius:var(--r-pill);
}

/* ------------------------------------------------------------ game card */
.games{display:grid;grid-template-columns:repeat(auto-fill,minmax(310px,1fr));gap:10px}
.game{
  position:relative;overflow:hidden;
  border:1px solid var(--line-2);border-left:3px solid var(--gc,#888);
  background:var(--f2);padding:12px 14px;border-radius:var(--r-md);
  box-shadow:var(--shadow-1);
  transition:background .16s,border-color .16s,transform .16s,box-shadow .16s;
}
.game::before{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(100deg, color-mix(in srgb, var(--gc,#888) 7%, transparent), transparent 55%);
}
.game:hover{
  background:var(--f3);border-color:var(--line-3);
  transform:translateY(-2px);box-shadow:var(--shadow-2);
}
.game.followed{border-color:var(--amber-2)}
.game > *{position:relative}

.game .mu{display:flex;justify-content:space-between;gap:14px;align-items:flex-start}
.game .teams{display:grid;gap:3px;font-size:14.5px;font-weight:500;letter-spacing:.15px}
.game .side{display:flex;align-items:center;gap:5px;white-space:nowrap}
.game .at{
  font-family:var(--display);color:var(--muted-2);font-weight:400;font-size:9.5px;
  letter-spacing:1.6px;text-transform:uppercase;padding-left:2px;
}
.game .rk{
  font-family:var(--num);font-size:10px;color:var(--amber);
  border:1px solid var(--amber-2);border-radius:3px;padding:0 3px;line-height:1.4;
}
.game .kick{
  font-family:var(--num);font-size:12.5px;color:var(--chalk-2);white-space:nowrap;
  font-variant-numeric:tabular-nums;
}
.game .kick.tba{color:var(--muted-2);font-style:italic}
.game .score{font-family:var(--num);color:var(--muted);font-weight:600;font-size:14px}
.game .score .w{color:var(--amber)}
.game .meta{
  margin-top:9px;padding-top:9px;border-top:1px solid var(--line-2);
  font-size:11.5px;color:var(--muted-2);
  display:flex;gap:8px;flex-wrap:wrap;align-items:center;
}
.game .tag{
  border:1px solid var(--gc,#888);color:var(--gc,#888);border-radius:var(--r-pill);
  padding:1px 8px;font-size:10.5px;letter-spacing:.3px;
}
.game .flagbit{
  font-family:var(--display);font-size:9px;letter-spacing:1.5px;text-transform:uppercase;
  color:var(--muted-2);border-left:1px solid var(--line);padding-left:8px;
}

/* follow star */
.team-star,.chip-star{display:none}
body[data-signed-in="true"] .team-star,
body[data-signed-in="true"] .chip-star{
  display:inline-flex;align-items:center;justify-content:center;
  background:transparent;border:0;padding:0;cursor:pointer;line-height:1;
  color:var(--muted-2);transition:color .14s,opacity .14s,transform .14s;
}
body[data-signed-in="true"] .team-star{width:14px;font-size:12px;opacity:0}
.game:hover .team-star,.game .team-star:focus-visible{opacity:.75}
body[data-signed-in="true"] .team-star.on{opacity:1;color:var(--amber)}
.team-star:hover{color:var(--amber);transform:scale(1.2)}
@media (hover: none){ body[data-signed-in="true"] .team-star{opacity:.5} }

body[data-signed-in="true"] .chip-star{
  font-size:12px;padding:4px 7px;border:1px solid var(--line);border-left:0;
  background:var(--f2);border-radius:0 var(--r-pill) var(--r-pill) 0;
}
body[data-signed-in="true"] .chip-star.on{color:var(--amber);background:var(--amber-ghost)}
.chip-star:hover{color:var(--amber);background:var(--f3)}

/* -------------------------------------------------------- month grid */
.month + .month{margin-top:44px}
.month h3{
  font-family:var(--display);font-size:25px;margin:0 0 14px;letter-spacing:2.4px;
  font-weight:600;text-transform:uppercase;display:flex;align-items:baseline;gap:14px;
}
.month h3 .c{
  font-family:var(--num);font-size:11px;color:var(--muted-2);letter-spacing:0;
  border:1px solid var(--line);border-radius:var(--r-pill);padding:2px 9px;
}
.cal{
  display:grid;grid-template-columns:repeat(7,minmax(0,1fr));gap:1px;
  background:var(--line-2);border:1px solid var(--line);border-radius:var(--r-md);
  overflow:hidden;
}
.cal .dow{
  background:var(--f0);color:var(--muted-2);padding:7px;text-align:center;
  font-family:var(--display);font-size:10px;letter-spacing:2px;text-transform:uppercase;
}
.cal .cell{background:var(--f2);min-height:112px;padding:8px;position:relative;transition:background .16s}
.cal .cell.sat{
  background:
    repeating-linear-gradient(135deg, rgba(255,194,71,.03) 0 7px, transparent 7px 14px),
    var(--f3);
}
.cal .cell.blank{background:var(--f0)}
.cal .cell.has{cursor:pointer}
.cal .cell.has:hover{background:var(--f4)}
.cal .cell.now{box-shadow:inset 0 0 0 2px var(--amber)}
.cal .cell.now .d b{color:var(--amber)}
.cal .cell .d{font-family:var(--num);font-size:11px;color:var(--muted-2);display:flex;gap:6px;align-items:baseline}
.cal .cell .d b{color:var(--chalk);font-weight:600;font-size:14px}
.cal .dots{display:flex;flex-wrap:wrap;gap:3px;margin-top:8px;padding-right:24px}
.cal .dots i{width:7px;height:7px;border-radius:50%;display:block;box-shadow:0 0 5px -1px currentColor}
.cal .dots .plus{font-family:var(--num);font-size:9px;color:var(--muted-2);line-height:7px}
.cal .cell .top{margin-top:8px;font-size:10.5px;color:var(--muted);line-height:1.4;display:none}
.cal .cell .top .more-n{color:var(--muted-2)}
@media (min-width:1180px){ .cal .cell .top{display:block} .cal .cell{min-height:126px} }
.cal .cell button.more{position:absolute;inset:0;background:transparent;border:0;cursor:pointer;width:100%}
.cal .cell .n{
  font-family:var(--num);font-size:11px;color:var(--amber);position:absolute;right:8px;top:8px;
}
.hintline{font-size:12px;color:var(--muted-2);margin:0 0 18px;max-width:92ch}

/* -------------------------------------------------------------- table */
/* The table scrolls itself, in both directions.
   `overflow-x:auto` alone already made this a scroll container on both axes —
   CSS gives you no way to scroll one axis and let the other overflow visibly —
   which is what broke the sticky header: `th` was offsetting itself by the
   toolbar height *inside this box* rather than parking under the toolbar, so an
   empty band appeared above the header and the first row showed through it.
   Bounding the height makes that stickiness mean something instead: the header
   pins to the top of the table while 888 rows move under it. */
.tscroll{
  overflow:auto;border:1px solid var(--line);border-radius:var(--r-md);
  /* Both bars, not just the toolbar. Leaving the month bar out of this is what
     pushed the box past the bottom of the window and made the table refuse to
     scroll cleanly to its top. */
  max-height:calc(100vh - var(--barh) - var(--receipth) - var(--monthbarh) - 56px);min-height:320px;
  /* Scroll chaining is deliberately left on. `overscroll-behavior: contain`
     was stopping it, so once this box reached its own top the wheel did
     nothing at all — the page stayed where it was and the table appeared
     unable to scroll back to the top. Chaining hands the scroll up to the page
     instead, which is what anybody expects from a table on a page. */
}
table{width:100%;border-collapse:collapse;font-size:12.5px;min-width:900px}
th{
  text-align:left;font-weight:600;color:var(--muted);
  border-bottom:1px solid var(--line);padding:10px 12px;
  /* Zero, because the scroll container is .tscroll and not the page. Any other
     value pushes the header down inside the table and leaves a gap above it. */
  position:sticky;top:0;background:var(--f0);z-index:5;
  font-family:var(--display);font-size:10.5px;letter-spacing:1.8px;text-transform:uppercase;
  white-space:nowrap;
}
th.sortable{cursor:pointer;user-select:none;transition:color .16s}
th.sortable:hover{color:var(--chalk)}
th .arrow{color:var(--amber);font-size:9px;margin-left:5px}
td{padding:8px 12px;border-bottom:1px solid var(--line-2)}
tbody tr{transition:background .12s}
tbody tr:hover td{background:var(--f3)}

/*
 * The current month, boxed, so the table says where you are without a header.
 *
 * Drawn as a border on the cells rather than on the row or a tbody: in a
 * collapsed table a border set on tr is unreliable across browsers, while cell
 * edges are exactly where the line belongs. The run's first and last rows are
 * marked by the renderer, because CSS cannot see where a run of equal values
 * starts and stops.
 *
 * Sits under the hover tint deliberately — hovering a row should still read as
 * hovering, inside the band or out of it.
 */
tbody tr.thismonth td{background:var(--amber-ghost)}
tbody tr.thismonth:hover td{background:var(--f3)}
tbody tr.thismonth td:first-child{border-left:2px solid var(--amber)}
tbody tr.thismonth td:last-child{border-right:2px solid var(--amber)}
tbody tr.thismonth-first td{border-top:2px solid var(--amber)}
tbody tr.thismonth-last td{border-bottom:2px solid var(--amber)}
td.cf{border-left:3px solid var(--gc,#888);font-weight:500}

td.going{white-space:nowrap;text-align:right;width:1%}
td.mono{font-family:var(--num);font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums}
td .rk{font-family:var(--num);font-size:10px;color:var(--amber);margin-right:4px}

/* ------------------------------------------------------------ dialogs */
/* Dialog widths.
   The dialog is the measure — panels always fill it, and never carry a
   max-width of their own. Getting that backwards is what made three of these
   look off-centre: a 600px panel sat against the left edge of an 820px window
   with 179px of dead space beside it, and in the Feeds dialog one section was
   600px while the section under it was 778px, so their right edges disagreed.

   Three steps, named for what the surface does:
     card   one decision, a few short fields          (signing in)
     sheet  a form or a settings surface              (profile, privacy, help)
     board  a list, a grid, something to scan         (teams, feeds, friends) */
:root{
  --dlg-card:440px;
  --dlg-sheet:620px;
  --dlg-board:820px;
}

dialog{
  background:var(--f2);color:var(--chalk);border:1px solid var(--line-3);
  border-radius:var(--r-lg);max-width:var(--dlg-board);width:92%;padding:0;
  box-shadow:var(--shadow-3);
  /* Never a scroll container itself. A browser's default is overflow:auto,
     which made every dialog scrollable in its own right: the header could be
     driven off the top, taking the Close button with it, and there was empty
     space below the body to scroll through. The body is the only thing that
     scrolls. */
  overflow:hidden;
  max-height:calc(100dvh - 40px);
}

/* Only when open, or this beats the browser rule that keeps a closed dialog
   hidden and every panel in the document renders at once. */
dialog[open]{display:flex;flex-direction:column}
dialog::backdrop{background:rgba(2,5,3,.8);backdrop-filter:blur(4px)}

/* Narrow on purpose. At 820px the sign-in form sat in the left two thirds with
   179px of dead space beside it, which is what made it read as off-centre. A
   short column also stops an email field being six inches wide. */
#authDialog,#profileDialog{max-width:var(--dlg-card)}
#accountDialog,#privacyDialog,#helpDialog{max-width:var(--dlg-sheet)}
/* A short card can afford more of the viewport than a data panel needs. At 70vh
   the sign-up form scrolled and put the Discord route below the fold, which
   hides the alternative from anyone who does not think to scroll. */
.dlg-head{
  display:flex;justify-content:space-between;align-items:center;gap:16px;
  padding:16px 20px;border-bottom:1px solid var(--line);
  background:linear-gradient(180deg,var(--f3),transparent);
  /* Fixed height, always on screen: it holds the way out. */
  flex:0 0 auto;
}
.dlg-head h3{
  font-family:var(--display);font-size:20px;margin:0;letter-spacing:2px;text-transform:uppercase;
}
.dlg-body{
  padding:20px;overflow:auto;
  /* Takes what is left after the header rather than a share of the viewport.
     70vh was a guess that did not account for the header, so head plus body
     could exceed the dialog and hand the overflow to the dialog itself.
     min-height:0 is what lets a flex child actually shrink and scroll. */
  flex:1 1 auto;min-height:0;
  /* Positioned so the visually-hidden labels inside are contained here and
     clipped by this overflow. Absolute positioning looks for the nearest
     positioned ancestor, and while this was static it found the dialog — so
     one-pixel screen-reader spans sat at their static offsets deep in the
     scrolled content and stretched the dialog's scroll height by 357px.
     That was the blank space. */
  position:relative;
}
.dlg-body h4{
  font-family:var(--display);font-size:11.5px;letter-spacing:2.2px;text-transform:uppercase;
  color:var(--amber);margin:0 0 10px;
}
.dlg-body section + section{margin-top:26px;padding-top:22px;border-top:1px solid var(--line-2)}
/* A panel that opens with a sentence needs air under it. `section + section`
   spaces the sections from each other but says nothing about the preamble
   above the first one, so the intro collided with the first heading in three
   panels at once. */
.dlg-body > * > .prose:first-child{margin-bottom:22px}
.dlg-body .prose{color:var(--muted);font-size:12.5px;margin:0;max-width:74ch;line-height:1.6}
.keys{display:grid;grid-template-columns:auto 1fr;gap:9px 16px;font-size:12.5px;align-items:baseline}
.keys kbd{
  font-family:var(--num);font-size:11px;background:var(--f0);border:1px solid var(--line-3);
  border-bottom-width:2px;padding:3px 8px;border-radius:var(--r-sm);color:var(--chalk);white-space:nowrap;
}

/* -------------------------------------------------------------- forms */
/* Deliberately no max-width on any panel: see the dialog widths above. */
.field{display:block;margin-bottom:14px}
.field > span{
  display:block;font-family:var(--display);font-size:10px;letter-spacing:2px;
  text-transform:uppercase;color:var(--muted-2);margin-bottom:6px;
}
.field input{
  width:100%;background:var(--f0);border:1px solid var(--line);padding:10px 12px;
  border-radius:var(--r-md);font-size:13.5px;transition:border-color .16s;
}
.field input:hover{border-color:var(--line-3)}
.field input:focus{border-color:var(--ice);outline:none}
.field input::placeholder{color:var(--muted-2)}
.fieldnote{font-size:11.5px;color:var(--muted-2);margin:0 0 14px;max-width:64ch;line-height:1.6}
.chk.remember{margin-bottom:16px}
.availability{display:block;margin-top:6px;font-size:11.5px;color:var(--muted-2);min-height:1.2em}
.availability[data-state=good]{color:#7fdca0}
.availability[data-state=bad]{color:#ffaea6}

/* Full width, because it is the one thing this card exists for. Previously a
   75px button sat beside a 600px Discord button, which inverted the hierarchy:
   the alternative looked like the action. */
.btn.wide{width:100%;justify-content:center;padding-top:11px;padding-bottom:11px}
.btn.go.wide{font-size:14px;letter-spacing:1.6px}

/* Neither an action nor a field label: a way out, parked at the edge. */
.fieldaside{display:flex;justify-content:flex-end;margin:-6px 0 14px;font-size:12px}

/* Where a challenge renders. Collapses entirely when none is configured, so
   the layout is the same whether or not one is switched on. */
.gate{display:flex;justify-content:center;margin:0}
.gate:not(:empty){margin:4px 0 16px}

.fieldnote.tight{margin:8px 0 0;font-size:11px}
.authswitch{font-size:12.5px;color:var(--muted-2);margin:20px 0 0}

/* A rule with the word sitting in it, rather than a bare line that reads as a
   section break between two unrelated things. */
/* The reminder schedule: a label and its time, aligned so the four times read
   as a column rather than four sentences. */
.tiers{list-style:none;margin:10px 0 12px;padding:0;display:grid;gap:7px}
.tiers li{
  display:flex;align-items:baseline;gap:12px;
  padding:8px 11px;border:1px solid var(--line);border-radius:var(--r-sm);
  background:rgba(255,255,255,.02);font-size:12.5px;
}
.tiers li b{color:var(--chalk);min-width:132px}
.tiers li span{color:var(--muted-2)}

.authsep{
  display:flex;align-items:center;gap:12px;
  margin:18px 0 12px;font-family:var(--display);
  font-size:10px;letter-spacing:2px;text-transform:uppercase;color:var(--muted-2);
}
.authsep::before,.authsep::after{content:"";flex:1;height:1px;background:var(--line)}

/* Discord's blurple, outlined rather than filled.
   Filled, at full width, it drowned the amber primary beside it — the loudest
   thing on the card was the alternative route. Outlined keeps the colour
   recognisable, which is what stops a sign-in button reading as a decoy, while
   leaving amber as the only saturated surface on the page. */
.btn.discord{
  background:transparent;border-color:#4d59d6;color:#aab2ff;font-weight:600;
}
.btn.discord:hover{background:rgba(88,101,242,.14);border-color:#5865f2;color:#c8cdff}
.btn.discord:focus-visible{outline:2px solid #8b95f5;outline-offset:2px}
.linklike{
  background:none;border:0;padding:0;color:var(--ice);cursor:pointer;
  font:inherit;text-decoration:underline;text-underline-offset:3px;
}
.linklike:hover{color:var(--chalk)}

.authfault{
  border-left:3px solid var(--flag);background:linear-gradient(90deg,rgba(255,96,85,.14),transparent);
  padding:11px 14px;margin:0 0 16px;font-size:12.5px;color:#ffd9d4;border-radius:0 var(--r-sm) var(--r-sm) 0;
}
.authnotice{
  border-left:3px solid var(--amber);background:linear-gradient(90deg,var(--amber-ghost),transparent);
  padding:11px 14px;margin:0 0 16px;font-size:12.5px;color:#ffe6b3;border-radius:0 var(--r-sm) var(--r-sm) 0;
}

/* ------------------------------------------------------------ account */
.identity{display:flex;align-items:center;gap:9px}
.identity .who{
  font-size:12.5px;color:var(--chalk-2);max-width:150px;overflow:hidden;
  text-overflow:ellipsis;white-space:nowrap;
}
.identity img{display:block;border-radius:50%;object-fit:cover;aspect-ratio:1}
.avatar-button{
  background:transparent;border:1px solid var(--line-3);border-radius:50%;padding:1px;
  cursor:pointer;line-height:0;transition:border-color .16s,transform .16s;
}
.avatar-button:hover{border-color:var(--amber);transform:scale(1.06)}
.identity-note{
  font-family:var(--display);font-size:10.5px;letter-spacing:1.8px;text-transform:uppercase;
  color:var(--amber);border:1px solid var(--amber-2);background:var(--amber-ghost);
  padding:4px 10px;border-radius:var(--r-pill);
}

.avatar-preview{display:flex;align-items:center;gap:16px;margin-bottom:16px}
.avatar-preview img{
  border-radius:50%;border:2px solid var(--line-3);display:block;
  object-fit:cover;aspect-ratio:1;background:var(--f3);
}
.avatar-name{
  font-family:var(--display);font-size:13px;letter-spacing:2.2px;text-transform:uppercase;
  color:var(--chalk);
}
.avatar-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(66px,1fr));gap:9px;
  max-height:330px;overflow-y:auto;padding:12px;border:1px solid var(--line-2);
  background:var(--f0);border-radius:var(--r-md);
}
.avatar-option{
  background:transparent;border:2px solid transparent;border-radius:50%;padding:0;
  cursor:pointer;line-height:0;transition:border-color .14s,transform .14s;
}
.avatar-option:hover{transform:scale(1.08)}
.avatar-option[aria-checked=true]{border-color:var(--amber);box-shadow:0 0 14px -4px var(--amber)}
.avatar-option img{
  display:block;border-radius:50%;width:100%;height:auto;
  object-fit:cover;aspect-ratio:1;background:var(--f3);
}

.account section.danger{border-top-color:#4d211c}
.account section.danger h4{color:var(--flag)}
.btn.danger{background:transparent;border-color:#5e2a24;color:#ffb0a8}
.btn.danger:hover:not([disabled]){background:#2a1310;border-color:var(--flag);color:#fff}

/* ------------------------------------------------------------ follows */
.follow-grid{
  display:grid;grid-template-columns:repeat(auto-fill,minmax(186px,1fr));gap:4px;
  max-height:320px;overflow-y:auto;padding:4px;border:1px solid var(--line-2);
  border-radius:var(--r-md);background:var(--f0);
}
.follow-row{
  display:flex;align-items:center;gap:9px;text-align:left;
  background:transparent;border:1px solid transparent;border-radius:var(--r-sm);
  padding:7px 10px;cursor:pointer;font-size:12.5px;color:var(--muted);
  transition:background .14s,color .14s,border-color .14s;
}
.follow-row:hover{background:var(--f3);color:var(--chalk);border-color:var(--line)}
.follow-row[aria-checked=true]{color:var(--chalk);background:var(--amber-ghost);border-color:var(--amber-2)}
.follow-row .star{color:var(--muted-2);font-size:13px;flex:none;width:13px}
.follow-row[aria-checked=true] .star{color:var(--amber)}
.follow-row .swatch{width:8px;height:8px;border-radius:50%;flex:none}
.follow-row .follow-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* -------------------------------------------------------------- feeds */
.calendars .created{
  border-left:3px solid var(--amber);padding:2px 0 2px 16px;
  background:linear-gradient(90deg,var(--amber-ghost),transparent);
}
.feed-url{display:flex;gap:9px;margin-bottom:12px}
.feed-url input{
  flex:1;background:var(--f0);border:1px solid var(--line);padding:10px 12px;
  border-radius:var(--r-md);font-family:var(--num);font-size:12px;
}
.feeds{list-style:none;margin:0;padding:0;display:grid;gap:7px}
.feed{
  display:flex;align-items:center;gap:14px;justify-content:space-between;
  border:1px solid var(--line-2);background:var(--f0);padding:11px 14px;
  border-radius:var(--r-md);
}
.feed b{font-size:13.5px;display:block;color:var(--chalk)}
.feed-note{display:block;font-size:11.5px;color:var(--muted-2);margin-top:2px}

/* ------------------------------------------------------------- states */
.empty{
  color:var(--muted);padding:70px 24px;text-align:center;
  border:1px dashed var(--line-3);border-radius:var(--r-lg);background:var(--f2);
}
.empty b{
  display:block;font-family:var(--display);font-size:19px;letter-spacing:2px;
  text-transform:uppercase;color:var(--chalk);margin-bottom:10px;
}
.empty .btn{margin-top:18px}

.loading{padding:90px 24px;text-align:center;color:var(--muted-2)}
.loading .bar{
  width:210px;height:2px;background:var(--line);margin:0 auto 20px;
  overflow:hidden;position:relative;border-radius:var(--r-pill);
}
.loading .bar::after{
  content:"";position:absolute;inset:0;width:40%;background:var(--amber);
  border-radius:var(--r-pill);animation:sweep 1.1s ease-in-out infinite;
}
@keyframes sweep{0%{transform:translateX(-110%)}100%{transform:translateX(260%)}}
.loading p{
  font-family:var(--display);letter-spacing:2.6px;text-transform:uppercase;
  font-size:12px;margin:0;
}

.fault{
  border-left:3px solid var(--flag);background:linear-gradient(90deg,rgba(255,96,85,.12),transparent);
  padding:20px 22px;margin:24px 0;border-radius:0 var(--r-md) var(--r-md) 0;
}
.fault h3{
  font-family:var(--display);font-size:16px;letter-spacing:2px;text-transform:uppercase;
  margin:0 0 8px;color:var(--flag);
}
.fault p{margin:0 0 12px;color:var(--muted);max-width:72ch}
.fault code{
  font-family:var(--num);font-size:11.5px;background:var(--f0);padding:2px 7px;
  border:1px solid var(--line-2);border-radius:var(--r-sm);
}

@media (max-width:720px){
  .mast-in{padding:16px 14px 14px;gap:16px}
  .tally{margin-left:0;width:100%}
  .tally div{flex:1;min-width:0;padding:8px 10px}
  .bar,.filters,.receipt{padding-left:14px;padding-right:14px}
  .wrap{padding:16px 14px 80px}
  .colophon-in{padding:16px 14px 28px;gap:8px}
  .ctl-lbl{min-width:100%}
  .cal .cell{min-height:78px;padding:5px}
  .cal .dots{padding-right:18px}
  .games{grid-template-columns:1fr}
}

/* ------------------------------------------------------------- interest */
.game .right{display:flex;flex-direction:column;align-items:flex-end;gap:7px}
.in-btn{display:none}
body[data-signed-in="true"] .in-btn{
  display:inline-flex;align-items:center;
  background:transparent;border:1px solid var(--line);color:var(--muted-2);
  font-family:var(--display);font-size:9.5px;letter-spacing:1.4px;text-transform:uppercase;
  padding:3px 8px;border-radius:var(--r-pill);cursor:pointer;
  transition:color .14s,border-color .14s,background .14s,opacity .14s;
  opacity:0;
}
.game:hover .in-btn,.game .in-btn:focus-visible{opacity:1}
body[data-signed-in="true"] .in-btn.on{
  opacity:1;color:var(--amber);border-color:var(--amber-2);background:var(--amber-ghost);
}
.in-btn:hover{color:var(--chalk);border-color:var(--line-3);background:var(--f4)}
body[data-signed-in="true"] .in-btn.on:hover{color:#150f02;background:var(--amber);border-color:var(--amber)}
@media (hover: none){ body[data-signed-in="true"] .in-btn{opacity:.75} }

/* The going cell in the table.
   A card reveals its button on hover, which suits a surface you point at. A
   table is scanned top to bottom, and a control that only exists while the
   cursor is over its row is a control nobody finds — so here it is always
   visible.

   This has to sit after the rules above and carry the same [data-signed-in]
   prefix. Written as `td.going .in-btn` it tied on specificity with
   `body[data-signed-in="true"] .in-btn{opacity:0}` and lost on source order,
   which left 888 buttons in the DOM and none of them on screen. */
body[data-signed-in="true"] td.going .in-btn{opacity:1}
td.going .friends-in{margin:4px 0 0;justify-content:flex-end;font-size:10.5px}
td.going .friends-in span:last-child{max-width:14ch}

.game.marked{box-shadow:var(--shadow-1), inset 3px 0 0 -1px var(--amber)}

/* ------------------------------------------------------------- friends */
.friends-in{
  display:flex;align-items:center;gap:6px;margin-top:8px;
  font-size:11px;color:var(--ice);
}
.friends-in-icon{font-size:9px;opacity:.8}
.friends-in span:last-child{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

.add-friend{display:flex;gap:9px;align-items:flex-start}
.add-friend .field{flex:1;margin-bottom:0}
.friends{list-style:none;margin:0;padding:0;display:grid;gap:7px}
.friend{
  display:flex;align-items:center;gap:12px;
  border:1px solid var(--line-2);background:var(--f0);padding:9px 12px;
  border-radius:var(--r-md);
}
.friend img{border-radius:50%;flex:none;object-fit:cover;aspect-ratio:1;background:var(--f3)}
.friend-who{flex:1;min-width:0}
.friend-who b{display:block;font-size:13.5px;color:var(--chalk)}
.friend-note{display:block;font-size:11.5px;color:var(--muted-2);margin-top:1px}
.friend-actions{display:flex;gap:6px;flex-wrap:wrap;flex:none}

/* ------------------------------------------------------------- discord */
.dlg-rule{border:0;border-top:1px solid var(--line);margin:26px 0}
.discord section + section{margin-top:24px;padding-top:20px;border-top:1px solid var(--line-2)}
.discord h4{
  font-family:var(--display);font-size:12px;letter-spacing:2px;text-transform:uppercase;
  color:var(--amber);margin:0 0 10px;
}
.discord .prose{color:var(--muted);font-size:12.5px;margin:0 0 12px;max-width:66ch}
.hook-ok{display:block;font-size:11.5px;color:#7fdca0;margin-top:2px}
.hook-bad{display:block;font-size:11.5px;color:#ffaea6;margin-top:2px}

.follow-label{display:flex;flex-direction:column;gap:1px;min-width:0}
.follow-friends{
  font-size:10.5px;color:var(--ice);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
}

/* ---------------------------------------------------------------- logos
   No chip behind them. The provider's dark-background variant already keeps
   team colour where it reads and lightens only the marks that would vanish,
   so a chip would be a light disc under a logo already designed for this
   background. */
.logo{
  width:20px;height:20px;flex:none;object-fit:contain;
  display:inline-block;vertical-align:-4px;
}
.logo-sm{width:18px;height:18px;vertical-align:-4px}
/* Initials keep the row height identical when a team has no logo. */
.logo-none{
  display:inline-flex;align-items:center;justify-content:center;
  background:var(--f4);color:var(--muted);border-radius:50%;
  font-family:var(--display);font-size:8.5px;letter-spacing:.5px;
}
.game .side{gap:6px}
td.cf .logo{margin-right:6px}
.follow-row .logo{margin-right:2px}
.identity .fav-team{margin-left:-2px}

.favorite-now{display:flex;align-items:center;gap:10px;margin-bottom:12px}
.favorite-now span{
  font-family:var(--display);font-size:13px;letter-spacing:1.6px;text-transform:uppercase;
  color:var(--chalk);
}
#favoriteTeam{
  width:100%;background:var(--f0);border:1px solid var(--line);padding:10px 12px;
  border-radius:var(--r-md);font-size:13.5px;cursor:pointer;
}
#favoriteTeam:hover{border-color:var(--line-3)}
#favoriteTeam:focus{border-color:var(--ice);outline:none}

/* -------------------------------------------------- a friend at a glance */
/*
 * A card, not a page. Fixed at the narrow dialog width so the two sections
 * sit one under the other in a single readable column — a profile that needs
 * scrolling has stopped being a glance.
 */
.pcard{display:grid;gap:20px}

.pc-head{display:flex;align-items:center;gap:14px}
.pc-head img{border-radius:var(--r-md);background:var(--f3);flex:none}
.pc-head h4{
  font-family:var(--display);font-weight:600;font-size:20px;letter-spacing:.2px;
  margin:0;color:var(--chalk);line-height:1.15;
}
/* The one reserved character, worn rather than announced. */
.pc-owner{color:var(--amber);font-size:14px;vertical-align:2px}

.pc-fav{
  display:flex;align-items:center;gap:7px;margin:5px 0 0;
  font-size:12.5px;color:var(--chalk-2);
}
.pc-fav .logo{flex:none}
.pc-fav.dim{color:var(--muted-2)}
.pcard .dim{color:var(--muted-2)}

/*
 * Sheets in this app space their sections generously — `.dlg-body section +
 * section` adds 26px, another 22px of padding and its own rule. A card is not
 * a sheet: at this width that rhythm opens a hole between two short sections,
 * so the card sets its own and lets the grid gap do the separating.
 */
.pcard .pc-sect{margin-top:0;padding-top:14px;border-top:1px solid var(--line-2)}
.pc-sect h5{
  font-family:var(--display);font-size:11px;font-weight:600;
  letter-spacing:1.6px;text-transform:uppercase;color:var(--muted-2);
  margin:0 0 10px;
}

/* Chips wrap rather than scroll: somebody following twenty teams gets a taller
   card, which is honest, instead of a hidden overflow. */
.pc-teams{list-style:none;margin:0;padding:0;display:flex;flex-wrap:wrap;gap:6px}
.pc-teams li{
  background:var(--f3);border:1px solid var(--line);border-radius:var(--r-pill);
  padding:3px 10px;font-size:11.5px;color:var(--chalk-2);
}

.pc-games{list-style:none;margin:0;padding:0;display:grid;gap:2px}
.pc-games li{
  display:flex;align-items:baseline;gap:10px;padding:6px 8px;
  border-radius:var(--r-sm);
}
.pc-games li:nth-child(odd){background:var(--f2)}
.pc-when{
  font-family:var(--num);font-size:11px;color:var(--muted-2);
  flex:none;min-width:11ch;
}
.pc-when b{color:var(--amber);font-weight:600;margin-left:4px}
.pc-match{font-size:12.5px;color:var(--chalk-2);min-width:0}
.pc-match i{color:var(--muted-2);font-style:normal;font-size:11px;margin:0 2px}
.pc-games + .prose{margin-top:9px}

/*
 * A name you can open.
 *
 * Styled as text rather than a button so a card stays a card, but it is a real
 * <button>: hover does not exist on a phone, and focus has to land somewhere
 * for anybody using a keyboard.
 */
.pc-link{
  background:none;border:0;padding:0;font:inherit;color:inherit;
  cursor:pointer;border-bottom:1px dotted var(--muted-2);
}
.pc-link:hover{color:var(--amber);border-bottom-color:var(--amber-2)}
.friend-name{
  display:block;font-family:var(--sans);font-size:13.5px;
  color:var(--chalk);border-bottom-color:transparent;text-align:left;
}
.friend-name:hover{border-bottom-color:var(--amber-2)}

.pc-avatar{
  background:none;border:0;padding:0;cursor:pointer;flex:none;
  border-radius:var(--r-md);line-height:0;
}
.pc-avatar:hover img{outline:1px solid var(--amber-2);outline-offset:1px}

/* ------------------------------------------------------ friend activity */
/*
 * A column of short lines, each one a person and a doing. Read top to bottom
 * and mostly skimmed, so the eye needs one strong column for the names and a
 * quiet one for the times — not a table.
 */
#activityDialog{max-width:var(--dlg-sheet)}

.af-list{list-style:none;margin:0;padding:0;display:grid;gap:1px}
.af-item{
  display:grid;grid-template-columns:30px 1fr auto auto;
  align-items:center;gap:11px;
  padding:9px 10px;border-radius:var(--r-sm);
}
.af-item:nth-child(odd){background:var(--f2)}

.af-said{min-width:0}
.af-said p{margin:0;font-size:13px;color:var(--chalk-2);line-height:1.45}
.af-said p span{color:var(--muted)}
.af-said .pc-link{color:var(--chalk);border-bottom-color:transparent}
.af-said .pc-link:hover{color:var(--amber);border-bottom-color:var(--amber-2)}

/* The kickoff of a game somebody is going to — the one detail worth a second line. */
.af-kick{
  display:block;margin-top:2px;
  font-family:var(--num);font-size:10.5px;color:var(--muted-2);
}

.af-mark{color:var(--amber-2);font-size:11px;flex:none}
.af-when{
  font-family:var(--num);font-size:10.5px;color:var(--muted-2);
  flex:none;text-align:right;min-width:6ch;
}

.af-note{margin-top:16px;padding-top:13px;border-top:1px solid var(--line-2)}
.dlg-body .prose.dim{color:var(--muted-2)}

@media (max-width:520px){
  /* The mark is decoration; the time is not. */
  .af-item{grid-template-columns:30px 1fr auto;gap:9px}
  .af-mark{display:none}
}

/* Two explanations in a row need air between them, or they read as one
   paragraph that changed its mind. */
.dlg-body .prose + .prose{margin-top:9px}

/*
 * Managed mode verifies silently for almost everybody, and Turnstile leaves an
 * empty 72px box behind when it does — a hole between the password hint and the
 * submit button. Collapse the slot unless there is an actual challenge in it.
 *
 * Keyed on the iframe rather than on a class we set, because Cloudflare decides
 * whether to show a challenge and does not tell us.
 */
.gate:not(:has(iframe)) {
  height: 0;
  margin: 0;
  overflow: hidden;
}

/* ------------------------------------------------------- jumping to a month */
/*
 * The month grid and the table are one long scroll each, so both carry the
 * same tab row the week view already has — it wears the .weeks styling rather
 * than a second set of rules, because it is the same control doing the same
 * job and it should not look like a different one.
 *
 * scroll-margin-top is what keeps a jump from landing underneath something
 * sticky: the toolbar over the month sections, the table head over a row. Done
 * here rather than by arithmetic in the scrolling code, which would have to
 * measure both.
 */
/*
 * The month bar follows the reader.
 *
 * Sticky under the toolbar rather than at the top of the window, because the
 * toolbar is itself sticky and grows when the filters panel opens — `top` reads
 * the measured height so the two never overlap at any width.
 *
 * It needs its own ground: a transparent sticky bar shows the cards sliding
 * underneath it. Sits below the receipt's layer and above the board.
 */
.monthbar{
  position:sticky;top:calc(var(--barh) + var(--receipth));z-index:28;
  margin-bottom:18px;background:var(--f0);
  border-bottom:1px solid var(--line);
  /* .weeks pads 12px above for the NOW badge; sticky needs the same ground to
     extend to the toolbar's edge so nothing shows through the gap. */
  padding-top:10px;
}

/* Under both bars, so a jumped-to row is not hidden by the toolbar above it. */
.month[data-month]{
  scroll-margin-top:calc(var(--barh) + var(--receipth) + var(--monthbarh) + 18px);
}
/* Inside the table's own scrollport the toolbar is irrelevant; what covers a
   row there is the sticky table head. */
.tscroll tbody tr[data-month]{scroll-margin-top:var(--theadh)}

/*
 * One scroller, wherever the table fits.
 *
 * The table used to scroll inside its own box while the page scrolled the
 * masthead — two nested vertical scrollers. Chrome latches a wheel gesture to
 * whichever one it started on, so scrolling up inside the table reached the
 * table's top and then stopped dead: the page's remaining scroll was not handed
 * over until the gesture ended and a new one began. That is the scrolling that
 * got stuck and then corrected itself.
 *
 * The box only ever existed to pan a table too wide for the window, and at
 * these widths it is not: the table needs 900px and there is more than that
 * going spare. So above this width it stops being a scroll container, the page
 * becomes the only one, and the header sticks to the window under both bars
 * instead of to a box that no longer scrolls.
 *
 * Below it, the box comes back — a narrow screen genuinely needs to pan
 * sideways, and that is worth a latch nobody meets while panning.
 */
@media (min-width: 1000px) {
  .tscroll{overflow:visible;max-height:none}
  .tscroll th{top:calc(var(--barh) + var(--receipth) + var(--monthbarh))}
  .tscroll tbody tr[data-month]{
    scroll-margin-top:calc(var(--barh) + var(--receipth) + var(--monthbarh) + var(--theadh));
  }
}
/* The week board lands on a day rather than a month, and has only the toolbar
   over it. */
.dayblock{scroll-margin-top:calc(var(--barh) + var(--receipth) + 18px)}
