/* ==========================================================================
   3CIS Football Pool — "Chalk & Slate"
   --------------------------------------------------------------------------
   A design layer over Bootstrap 3.1 and the legacy admin theme. Loaded LAST
   so it wins without the theme files having to be deleted.

   The page is a box score. The typographic tradition for dense standings
   grids is agate -- the tiny condensed type sports pages have set box scores
   in for a century -- so the matrix is set in a narrow grotesque with tabular
   figures, on a white sheet, under a deep slate header band.

   Deliberately team-neutral: a player's own allegiance shows in their row
   watermark, so the furniture stays out of it.

   The one signature: pick cells carry a tally rule underneath. Solid slate =
   hit, red dash = miss, nothing = not played yet. A row reads as a row of
   pencil ticks on a pool sheet, which is what it is.
   ========================================================================== */

:root {
  /* Color ---------------------------------------------------------------- */
  --band-deep: #1C2530;   /* header band, your own row */
  --band-mid:  #2F4256;   /* hits, active states */
  --chalk:     #EEF0F2;   /* page ground: newsprint grey, not cream */
  --sheet:     #FFFFFF;   /* the scorecard itself */
  --ink:       #10141A;
  --rule:      #D6D9DE;
  --accent:    #C25B2A;   /* burnt orange: tie breakers, attention */
  --accent-up: #F0A86B;   /* the same orange, lifted to carry on --band-deep:
                             the base accent only clears 3.6:1 there, which is
                             a large-text ratio and this is used at 10px */
  --hit:       #4E7BA6;   /* correct pick: steel blue, reads on chip and sheet */
  --shut:      #7A4A05;   /* amber: this game is closed, you cannot pick it */
  --miss:      #A8352A;

  /* Derived --------------------------------------------------------------- */
  --ink-soft:  #5C6570;
  --ink-faint: #8A9099;
  --band-line: rgba(255, 255, 255, 0.14);

  /* Matrix column widths --------------------------------------------------
     The colgroup and the frozen columns' sticky offsets both read these, so
     the offsets stay exact at any window size. Narrowed on phones in §10. */
  --w-weekly: 52px;
  --w-total:  56px;
  --w-name:   170px;
  --w-game:   74px;
  --w-tb:     78px;

  /* Type ----------------------------------------------------------------- */
  --font-display: 'Anton', 'Archivo Narrow', Impact, sans-serif;
  --font-ui: 'Archivo', 'Helvetica Neue', Arial, sans-serif;
  --font-agate: 'Archivo Narrow', 'Archivo', 'Helvetica Neue', Arial, sans-serif;
}

/* ==========================================================================
   1. Ground
   ========================================================================== */

body {
  background: var(--chalk) !important;
  color: var(--ink);
  font-family: var(--font-ui);
  font-size: 14px;
  line-height: 1.45;
  /* No -webkit-font-smoothing: antialiased. On a Mac it renders every stem a
     fraction thinner, which is a fair trade for large dark-on-light type and
     a bad one for small light-on-dark type: the white chips sampled around
     #8C8E94 rather than white, because no pixel in an 11px condensed stem was
     ever fully covered. Subpixel rendering is the browser default and lays
     down heavier strokes. */
}

#container,
#content {
  background: transparent !important;
}

#content {
  /* The band is 56px plus its 3px rule; this clears it and no more. It was
     84px, which left a slab of empty grey above the first card. */
  padding-top: 68px !important;
  padding-bottom: 48px;
}

#sidebar { display: none !important; }

/* Numbers in this app are all meant to be compared down a column. */
table, .summary h3, .score-value, .agate-num {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

a { color: var(--band-mid); }
a:hover, a:focus { color: var(--band-deep); }

/* Keyboard focus stays visible everywhere. */
a:focus-visible,
button:focus-visible,
input:focus-visible,
.team:focus-visible,
.team-option:focus-visible {
  outline: 2px solid var(--accent) !important;
  outline-offset: 2px !important;
}

/* ==========================================================================
   2. The slate band (fixed header)
   ========================================================================== */

.header.navbar,
header.header {
  background: var(--band-deep) !important;
  background-image: none !important;
  border: 0 !important;
  border-bottom: 3px solid var(--accent) !important;
  box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
  min-height: 56px;
  filter: none !important;
}

.header.navbar .navbar-brand,
.header .navbar-brand {
  font-family: var(--font-display);
  font-size: 21px;
  letter-spacing: 0.055em;
  text-transform: uppercase;
  color: #fff !important;
  padding: 17px 18px 14px 0;
  height: auto;
  line-height: 1;
  text-shadow: none;
}

.header .navbar-brand strong {
  font-weight: normal;   /* Anton has one weight; strong would fake-bold it */
  color: var(--accent);
}

/* Nav items on the band */
.header.navbar .nav > li > a,
.header .nav > li > a {
  font-family: var(--font-agate);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.09em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.82) !important;
  background: transparent !important;
  border: 0 !important;
  border-left: 1px solid var(--band-line) !important;
  padding: 20px 16px 18px !important;
  text-shadow: none !important;
  transition: color 120ms ease, background-color 120ms ease;
}

.header.navbar .nav > li > a:hover,
.header.navbar .nav > li > a:focus,
.header.navbar .nav > li.open > a,
.header .nav > li.open > a {
  color: #fff !important;
  background: rgba(255, 255, 255, 0.08) !important;
}

.header.navbar .nav.navbar-right > li:last-child > a {
  border-right: 1px solid var(--band-line) !important;
}

.header .nav > li > a .username {
  font-family: var(--font-agate);
  letter-spacing: 0.06em;
}

/* Dropdowns: a plain white sheet, hairline ruled */
.header .dropdown-menu,
.dropdown-menu {
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-top: 3px solid var(--accent);
  border-radius: 0;
  box-shadow: 0 8px 24px rgba(28, 37, 48, 0.16);
  padding: 4px 0;
  min-width: 190px;
}

.dropdown-menu > li > a {
  font-family: var(--font-agate);
  font-size: 13px;
  letter-spacing: 0.03em;
  color: var(--ink) !important;
  padding: 7px 16px;
}

.dropdown-menu > li > a:hover,
.dropdown-menu > li > a:focus {
  background: var(--chalk) !important;
  color: var(--band-deep) !important;
}

/* The week list is 19 items; let it breathe in two columns on wide screens. */
@media (min-width: 992px) {
  .header .nav > li.dropdown > .dropdown-menu.week-menu {
    column-count: 2;
    column-gap: 0;
    min-width: 320px;
  }
}

/* ==========================================================================
   3. Page header — "your line"
   ==========================================================================
   The old theme put a bare name here. It now states the one thing a player
   opens the page to learn: where they stand this week.
   ========================================================================== */

/* The theme's wrapper adds 52px above the content on top of the padding that
   already clears the fixed band, which left a slab of empty grey between the
   two. The band is 61px; #content's 68px is the whole clearance needed. */
.fixed-header { margin-top: 0 !important; }

.page-header {
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-left: 4px solid var(--band-deep);
  border-radius: 0;
  margin: 0 0 18px;
  padding: 16px 20px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  /* flex-start, not space-between. Whitespace between the children resolves
     to zero-width anonymous flex items, so space-between was dividing the row
     into four slots and the week heading floated 215px in from the card edge
     instead of sitting against it. The stats are pushed right explicitly. */
  justify-content: flex-start;
  gap: 16px;
}

.page-header .page-stats { margin-left: auto; }

/* text-align: left because the theme's responsive sheet centres this block
   below its breakpoint, which left the name and season floating mid-card
   while the week heading and the status chips either side of them sat hard
   against the edge. */
.page-header .page-title { margin: 0; padding: 0; float: none; text-align: left; }

.page-header .page-title h3 {
  font-family: var(--font-display);
  font-size: 26px;
  line-height: 1.05;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
}

/* Whose sheet this is. It was 11px faint agate -- a caption under the week,
   when it is the other half of what the header says. Real UI type, full ink,
   with the season kept quiet behind it. */
.page-header .page-standing {
  font-family: var(--font-ui);
  font-size: 17px;
  font-weight: 700;
  letter-spacing: 0;
  text-transform: none;
  color: var(--ink);
  margin: 2px 0 0;
}

.page-header .page-standing .season-note {
  font-family: var(--font-agate);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-left: 6px;
}


/* Stat cluster: agate label above a display figure. */
.page-header .page-stats {
  float: none;
  display: flex;
  align-items: stretch;
  gap: 0;
  margin: 0;
  padding: 0;
  list-style: none;
}

.page-header .page-stats > li {
  padding: 2px 22px;
  border-left: 1px solid var(--rule);
  display: flex;
  /* Top, not centre. The winner's name wraps to two lines and the season
     total carries a standing beside it, so centring floated the shorter
     figures down against the tallest block and the labels stopped lining up
     across the row. */
  align-items: flex-start;
  gap: 14px;
  min-width: 0;
}

.page-header .page-stats > li:first-child { border-left: 0; }

.page-stats .summary span {
  display: block;
  font-family: var(--font-agate);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-faint);
  margin-bottom: 1px;
}

.page-stats .summary h3 {
  font-family: var(--font-display);
  font-size: 30px;
  line-height: 1;
  color: var(--band-deep);
  margin: 0;
}

/* Your standing, riding alongside the season total it ranks. Agate so it
   reads as an annotation on the figure rather than a second figure. */
.page-stats .summary h3 .standing {
  display: inline-block;
  white-space: nowrap;   /* "5th of 39" is one phrase, not three words */
  margin-left: 7px;
  font-family: var(--font-agate);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-faint);
  vertical-align: 0.28em;
}

/* Winner is a name, not a figure: set it in UI type, flagged gold. */
.page-stats .summary h3.winner-name {
  font-family: var(--font-ui);
  font-size: 15px;
  font-weight: 700;
  line-height: 1.2;
  color: var(--ink);
  border-left: 3px solid var(--accent);
  padding-left: 8px;
}

.page-stats .summary h3.winner-name.is-tbd {
  color: var(--ink-faint);
  border-left-color: var(--rule);
  font-weight: 600;
}

/* ==========================================================================
   4. Sheets (the theme's "widget box")
   ========================================================================== */

.widget,
.widget.box {
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-radius: 0;
  box-shadow: none;
  margin-bottom: 18px;
}

.widget-header,
.widget.box > .widget-header {
  background: var(--sheet) !important;
  background-image: none !important;
  border: 0 !important;
  border-bottom: 1px solid var(--rule) !important;
  border-radius: 0 !important;
  height: auto;
  min-height: 0;
  padding: 14px 18px 12px;
  filter: none !important;
}

.widget-header h4 {
  font-family: var(--font-display);
  font-size: 19px;
  letter-spacing: 0.035em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0;
  padding: 0;
  line-height: 1.15;
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 10px;
}

.widget-header h4 > i { display: none; }   /* the reorder icon says nothing */

.widget-header .text-muted,
.widget-header p.text-muted {
  font-family: var(--font-agate);
  font-size: 12px;
  letter-spacing: 0.04em;
  color: var(--ink-soft) !important;
  margin: 8px 0 0;
}

.widget-content { padding: 16px 18px; }

/* Filter row: which slice of the pool the sheet is showing. */
.sheet-filter {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 0;
  margin: 10px 0 0 !important;
  font-family: var(--font-agate);
  font-size: 12px;
}

.sheet-filter a {
  font-weight: 600;
  letter-spacing: 0.05em;
  color: var(--ink-soft);
  padding: 3px 11px;
  border-left: 1px solid var(--rule);
  transition: color 120ms ease;
}

.sheet-filter a:first-child { border-left: 0; padding-left: 0; }
.sheet-filter a:hover { color: var(--band-deep); }

.sheet-filter a.is-active {
  color: var(--ink);
  font-weight: 700;
  box-shadow: inset 0 -2px 0 var(--accent);
}

.sheet-filter a.is-quiet { color: var(--ink-faint); font-weight: 400; }

.sheet-filter .filter-count {
  margin-left: auto;
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

.enroll-note {
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--ink);
  background: #FBF2F1;
  border-left: 3px solid var(--miss);
  padding: 9px 12px;
  margin: 10px 0 0 !important;
}

/* Small state chips used in headers (archive, not-enrolled) */
.label,
.widget-header .label {
  font-family: var(--font-agate);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  border-radius: 0;
  padding: 4px 8px;
  white-space: normal;
  text-shadow: none;
}

.label-warning { background: var(--accent) !important; color: #FFFFFF !important; }
.label-important,
.label-danger { background: var(--miss) !important; color: #fff !important; }

/* --- Your progress through the week -------------------------------------
   Two jobs, stated where you look first. Each item is a chip so the states
   read apart at a glance rather than as one run of prose. */
.pick-status {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin: 6px 0 0 !important;
  font-family: var(--font-agate);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
}

.pick-status span {
  padding: 2px 7px;
  color: var(--ink-soft);
  background: var(--chalk);
}

.pick-status .is-done   { color: #fff; background: var(--hit); }
.pick-status .is-todo   { color: #fff; background: var(--accent); }
.pick-status .is-missed { color: #fff; background: var(--miss); }

/* --- Week navigation ------------------------------------------------------
   The week is what the page is about, so it is the headline; the player's own
   name drops to the standing line under it. */

.week-nav {
  display: flex;
  align-items: center;
  gap: 6px;
  margin: 0 0 0 -2px;   /* optical: the heading's side bearing, not a gap */
}

.week-heading {
  font-family: var(--font-display);
  font-size: 32px;
  line-height: 1;
  letter-spacing: 0.02em;
  text-transform: uppercase;
  color: var(--ink);
  margin: 0 10px 0 0;
  order: -1;            /* heading first, arrows after: it starts at the card
                           edge in every week, whichever arrows are live */
}

.week-arrow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  font-size: 26px;
  line-height: 1;
  text-decoration: none;
  color: var(--band-mid);
  border: 1px solid var(--rule);
  background: var(--sheet);
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.week-arrow:hover,
.week-arrow:focus {
  background: var(--band-deep);
  border-color: var(--band-deep);
  color: #fff;
  text-decoration: none;
}

/* Either end of the schedule: gone entirely. It used to keep its space so the
   heading would not shift, but the heading leads the row now and anchors
   itself, so an empty slot buys nothing and reads as a dead control. */
.week-arrow.is-disabled { display: none; }

/* --- The sheet's own tools ------------------------------------------------
   Tie breaker and the admin recalculation, in the strip above the matrix
   rather than in the page header. The tie breaker feeds the sheet's last
   column, so it belongs with the sheet. */

.filter-count { display: inline-flex; align-items: center; gap: 10px; }
.filter-count .btn { padding: 4px 10px; font-size: 10px; }

/* ==========================================================================
   4a. The two panes
   ==========================================================================
   Picking and comparing are different jobs, but only on a phone do they need
   separate surfaces. From 1000px the standings is the whole page and you pick
   from the matrix head. Below that the two become tabs: stacked, the
   standings sat under sixteen pick rows and nobody scrolled that far.
   ========================================================================== */

.week-tabs { display: none; }

@media (min-width: 1000px) {
  /* The sheet is the page. Picking happens in the matrix head, where the team
     abbreviations are live, so a second copy of your own games earns nothing
     here -- it only pushed the standings sideways. It stays for phones, where
     a 54px matrix cell behind a sideways scroll is not a tap target. */
  .week-pane-picks { display: none; }
}

@media (max-width: 999px) {
  .week-tabs {
    display: flex;
    gap: 0;
    margin: 0 0 14px;
    border-bottom: 2px solid var(--rule);
  }

  .week-tab {
    flex: 1 1 0;
    min-height: 44px;
    padding: 10px 12px;
    background: transparent;
    border: 0;
    border-bottom: 3px solid transparent;
    margin-bottom: -2px;
    font-family: var(--font-agate);
    font-size: 12px;
    font-weight: 700;
    letter-spacing: 0.12em;
    text-transform: uppercase;
    color: var(--ink-faint);
    cursor: pointer;
    transition: color 120ms ease, border-color 120ms ease;
  }

  .week-tab.is-active {
    color: var(--ink);
    border-bottom-color: var(--accent);
  }

  .week-pane { display: none; }
  .week-split[data-panel="picks"] .week-pane-picks { display: block; }
  .week-split[data-panel="standings"] .week-pane-standings { display: block; }

  /* The tab already says "Your picks"; the panel heading underneath just
     repeated it. The instruction line below it stays. */
  .week-pane-picks .widget-header h4 { display: none; }
  .week-pane-picks .widget-header { padding-bottom: 0; }
}

/* ==========================================================================
   4b. "Your picks" — the picking surface
   ==========================================================================
   The only per-user interactive part of the page. On a phone this is what a
   player actually came for, so it is a plain stacked list with thumb-sized
   targets, not a miniature of the matrix.
   ========================================================================== */

.mypicks { margin-bottom: 18px; }

.mypicks .widget-header .text-muted {
  font-family: var(--font-agate);
  font-size: 12px;
  /* The theme gives this 35px of line-height, sized for a one-line caption
     sitting beside a heading. On one line that only looks tall; the moment it
     wraps -- which it does on any phone -- it opens a 35px chasm between the
     two lines. */
  line-height: 1.4;
  margin: 4px 0 0;
  color: var(--ink-soft);
}

.mypicks-list { padding: 0 !important; }

.mypick {
  display: grid;
  grid-template-columns: 104px minmax(0, 1fr) 128px;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  border-bottom: 1px solid var(--rule);
}

.mypick:last-child { border-bottom: 0; }

.mypick.is-tiebreaker { border-left: 3px solid var(--accent); padding-left: 13px; }

.mypick-when {
  font-family: var(--font-agate);
  font-size: 11px;
  line-height: 1.3;
  color: var(--ink-faint);
  text-transform: uppercase;
  letter-spacing: 0.07em;
}

.mypick-date { display: block; font-weight: 700; color: var(--ink-soft); }
.mypick-time { display: block; }

.mypick-teams {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
}

.mypick-at {
  font-family: var(--font-agate);
  font-size: 11px;
  color: var(--ink-faint);
}

.mypick-nopick {
  font-family: var(--font-agate);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--miss);
}

/* --------------------------------------------------------------------------
   The pick buttons: the logo IS the control.

   The logo fills the chip as a watermark and the abbreviation sits on top of
   it, so the badge is the button's face rather than an icon perched above a
   label. The logo is held well back in opacity -- it is identification, not
   decoration, and the three letters have to stay the most legible thing in
   the chip at arm's length.

   Two states have to be unmistakable at a glance, on a phone, mid-scroll:
   picked and not picked. Colour alone would not carry that, so the picked
   side changes on four axes at once -- dark chip, the watermark coming up to
   full colour, white type, and a tick -- while the unpicked side stays pale
   and desaturated. Whichever one you took should be the only thing your eye
   lands on.
   -------------------------------------------------------------------------- */
.team-option {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 92px;
  min-height: 58px;
  padding: 6px 10px;
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-radius: 0;
  /* No overflow clipping here. The logo does its own clipping in a wrapper,
     which leaves the button free to let the badge straddle its corner. */
  cursor: pointer;
  transition: background-color 120ms ease, border-color 120ms ease, box-shadow 120ms ease;
}

/* The logo IS the chip's background: cover, not contain, so it bleeds to all
   four edges instead of sitting as a letterboxed icon with dead space beside
   it. Cover crops, which is why the chip is kept close to square -- the wider
   the chip, the more of the badge's top and bottom gets cut away. The
   abbreviation rides on top, so identification never depends on the crop. */
/* The clipping layer. It exists so the chip itself does not have to clip,
   which is what lets the picked badge sit centred on the corner rather than
   tucked inside it. */
.team-option-crop {
  position: absolute;
  inset: 0;
  overflow: hidden;
  pointer-events: none;
}

.team-option-logo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
  /* Past the edges on purpose. cover fills the element, but these SVGs carry
     their own margins inside the viewBox, so the artwork still floated with a
     gap around it. Scaling up crops that padding away against the chip's
     overflow, and the badge reads as the surface rather than a picture on it. */
  transform: scale(1.45);
  filter: grayscale(1);
  opacity: 0.32;
  pointer-events: none;
  transition: filter 120ms ease, opacity 120ms ease;
}

.team-option-abbr {
  position: relative;        /* above the watermark */
  z-index: 1;
  font-family: var(--font-agate);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.1em;
  color: var(--ink);
  transition: color 120ms ease;
}

.team-option:hover {
  border-color: var(--ink-faint);
  background: var(--chalk);
}

.team-option:hover .team-option-logo { filter: grayscale(0.4); opacity: 0.5; }

/* --- Picked ------------------------------------------------------------- */

.team-option.is-picked {
  background: var(--band-deep);
  border-color: var(--band-deep);
}

/* Full colour, but still held back far enough that white type stays crisp
   over a busy badge; the shadow does the rest of the separating. */
.team-option.is-picked .team-option-logo { filter: none; opacity: 0.5; }

.team-option.is-picked .team-option-abbr {
  color: #fff;
  text-shadow: 0 1px 3px rgba(0, 0, 0, 0.9), 0 0 8px rgba(0, 0, 0, 0.55);
}

/* The badge reports a RESULT, so it appears only once there is one. It used
   to sit on every picked chip carrying a tick, which on a game that had not
   kicked off yet read as "you got this right" -- and now that a real hit is
   a tick too, the two were a colour apart. Undecided picks say what they are
   through the chip itself: dark ground, white type, full-colour badge
   against the pale grey of the side you did not take.

   Belt and braces with the colour: the glyph survives being viewed in
   sunlight, in greyscale, or by someone colourblind. */
.team-option.is-picked.is-hit::after,
.team-option.is-picked.is-miss::after {
  content: '';
  position: absolute;
  /* Centred on the corner, straddling it. Half in and half out is what makes
     it read at a glance -- it breaks the chip's outline instead of sitting
     politely within it. */
  top: -10px;
  right: -10px;
  width: 21px;
  height: 21px;
  border-radius: 50%;
  z-index: 2;
  background: var(--accent) center / 12px 12px no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1.5 6.4 4.4 9.3 10.5 3' fill='none' stroke='white' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  box-shadow: 0 0 0 2px var(--sheet);
}

/* --- Settled games ------------------------------------------------------- */

/* The badge carries the result on its own: blue tick for a hit, red cross
   for a miss, and the miss greys its logo out as well. The chips used to
   carry a coloured bar underneath too, which said the same thing twice. */
.team-option.is-picked.is-hit::after {
  background: var(--hit) center / 12px 12px no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M1.5 6.4 4.4 9.3 10.5 3' fill='none' stroke='white' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  box-shadow: 0 0 0 2px var(--sheet);
}

.team-option.is-picked.is-miss .team-option-logo { filter: grayscale(1); opacity: 0.3; }
.team-option.is-picked.is-miss::after {
  background: var(--miss) center / 12px 12px no-repeat
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M3 3l6 6M9 3l-6 6' fill='none' stroke='white' stroke-width='2.2' stroke-linecap='round'/%3E%3C/svg%3E");
  box-shadow: 0 0 0 2px var(--sheet);
}

/* Past the cutoff: same face, no affordance. */
.team-option.is-static { cursor: default; }
.team-option.is-static:hover { background: var(--sheet); border-color: var(--rule); }
.team-option.is-static:hover .team-option-logo { filter: grayscale(1); opacity: 0.32; }
.team-option.is-static.is-picked:hover { background: var(--band-deep); border-color: var(--band-deep); }
.team-option.is-static.is-picked:hover .team-option-logo { filter: none; opacity: 0.5; }
.team-option.is-static.is-picked.is-miss:hover .team-option-logo { filter: grayscale(1); opacity: 0.3; }

.mypick-line {
  display: flex;
  align-items: center;
  gap: 10px;
  justify-content: flex-end;
}

.game-spread.is-none { color: var(--ink-faint); font-style: italic; }

/* --- Narrow picking column ------------------------------------------------
   Keyed to the pane's own width, not the viewport's. The same panel is a
   ~380px column beside the matrix on a desktop and a full-width pane on a
   phone, so a media query would get one of the two wrong -- side by side, the
   three-column row has nowhere to put the chips and they stack one per line.
   Under ~520px of pane the row folds: when + line on top, chips across the
   full width beneath. */
.week-pane-picks { container-type: inline-size; container-name: picks; }

@container picks (max-width: 520px) {
  .mypick {
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas:
      "when line"
      "teams teams";
    row-gap: 8px;
    padding: 12px 14px;
    align-items: center;
  }

  .mypick.is-tiebreaker { padding-left: 11px; }

  .mypick-when  { grid-area: when; display: flex; gap: 6px; align-items: baseline; }
  .mypick-line  { grid-area: line; }
  .mypick-teams { grid-area: teams; }

  .mypick-date, .mypick-time { display: inline; }
}

/* ==========================================================================
   5. The matrix
   ========================================================================== */

#picktable_wrapper { border: 0; }

/* --- Scroll container and frozen identity columns ------------------------
   The matrix is wider than any phone and most laptops. It scrolls sideways
   inside this container while the three identity columns stay put, so a row
   never loses its name. The sticky offsets are computed from the same width
   variables the colgroup uses -- change a width in one place only. */

.matrix-scroll {
  overflow-x: auto;
  overflow-y: visible;
  -webkit-overflow-scrolling: touch;
  padding: 0 !important;
}

#picktable.matrix {
  table-layout: fixed;
  /* min-content, not max-content: under fixed layout a max-content table is
     sized by its contents (1310px here) and the surplus over the declared
     column widths (1114px) gets spread across every column -- which inflated
     the name column from 108px to 155px and let the frozen block eat a phone
     viewport. min-content resolves to exactly the declared widths. */
  width: min-content;
  min-width: 100%;
}

.c-weekly { width: var(--w-weekly); }
.c-total  { width: var(--w-total); }
.c-name   { width: var(--w-name); }
.c-game   { width: var(--w-game); }
.c-tb     { width: var(--w-tb); }

/* Sticky cells need their own opaque background or the scrolling columns
   show through them. */
#picktable thead th:nth-child(-n+3),
#picktable .matrix-kickoffs td:first-child,
#picktable tbody td:nth-child(-n+2),
#picktable tbody td.player-td {
  position: sticky;
  background: var(--sheet);
  /* Layering in this table is by COLUMN first, row second. A frozen cell must
     cover every scrolling cell, whoever's row it belongs to:
        7  frozen header cells
        6  frozen cells on your own row
        5  frozen cells on everyone else's
        2  your own scrolling cells (so the shadow box falls on the rows
           either side of it)
        0  everyone else's scrolling cells
     Getting this the other way round sent your picks sliding over the top of
     the name column while everybody else's correctly went under it. */
  z-index: 5;
}

#picktable thead th:nth-child(-n+3),
#picktable .matrix-kickoffs td:first-child { z-index: 7; }

#picktable thead th:nth-child(1),
#picktable tbody td:nth-child(1),
#picktable .matrix-kickoffs td:first-child { left: 0; }

#picktable thead th:nth-child(2),
#picktable tbody td:nth-child(2) { left: var(--w-weekly); }

#picktable thead th:nth-child(3),
#picktable tbody td.player-td { left: calc(var(--w-weekly) + var(--w-total)); }

/* The hairline that separates the frozen block from the scrolling games. */
#picktable thead th:nth-child(3),
#picktable tbody td.player-td { border-right: 1px solid var(--rule); }

#picktable tbody tr.current-user td:nth-child(-n+2),
#picktable tbody tr.current-user td.player-td { background: var(--sheet); }

/* --- Sortable heads ------------------------------------------------------ */

#picktable th.sortable { cursor: pointer; user-select: none; }
#picktable th.sortable:hover { color: var(--band-mid); }

#picktable th.sortable::after {
  content: '';
  display: inline-block;
  margin-left: 5px;
  border: 4px solid transparent;
  vertical-align: middle;
  opacity: 0;
}

#picktable th.sortable[aria-sort="ascending"]::after {
  border-bottom-color: var(--band-mid);
  border-top-width: 0;
  opacity: 1;
}

#picktable th.sortable[aria-sort="descending"]::after {
  border-top-color: var(--band-mid);
  border-bottom-width: 0;
  opacity: 1;
}

/* --- Kickoff row and tie-break head -------------------------------------- */

/* Centred like everything else in the column, and dark enough to read: this
   was 3.22:1 on white, under the 4.5 AA floor for text this size. */
#picktable .matrix-kickoffs td { text-align: center; }
.kick-date { display: block; font-weight: 700; }
.kick-time { display: block; color: var(--ink-soft); }

.tb-head { text-align: center; }

/* Saved-tie-breaker flash */
.tb-saved { margin: 10px 0 0; }

#picktable {
  border-collapse: separate;
  border-spacing: 0;
  background: var(--sheet);
  font-family: var(--font-agate);
  font-size: 12px !important;
}

/* --- Agate column heads -------------------------------------------------- */

#picktable thead td,
#picktable thead th {
  background: var(--sheet);
  border: 0;
  border-bottom: 1px solid var(--rule);
  vertical-align: bottom;
  font-weight: 600;
}

/* Kickoff row */
#picktable thead tr:first-child td {
  font-family: var(--font-agate);
  font-size: 10px !important;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  border-bottom: 0;
  padding: 10px 3px 2px !important;
  line-height: 1.25;
}

/* Matchup row */
#picktable thead tr:nth-child(2) th {
  padding: 3px 3px 9px !important;
  font-size: 11px !important;
  color: var(--ink);
  line-height: 1.3;
}

#picktable thead tr:nth-child(2) th > span {
  font-family: var(--font-agate);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* A hairline between game columns. This used to set a colour and a height on
   a pseudo-element it assumed the theme was already drawing -- it was not, so
   `content` was never set and no rule ever appeared. On a phone the columns
   are 54px and a matchup is 48px, which leaves three pixels a side: without a
   rule "NYJ @ TEN" and "ATL @ PIT" simply run together. */
#picktable thead th.game-head,
#picktable thead .matrix-kickoffs td { position: relative; }

#picktable thead th.game-head::after,
#picktable thead .matrix-kickoffs td:not(:first-child)::after {
  content: '';
  position: absolute;
  top: 4px;
  bottom: 4px;
  right: 0;
  width: 1px;
  background: var(--rule);
}

/* Clickable team abbreviations in the head */
#picktable .team {
  display: inline-block;
  padding: 1px 3px;
  border-bottom: 2px solid transparent;
  color: var(--ink);
  font-weight: 700;
  letter-spacing: 0.02em;
  cursor: pointer;
  transition: color 120ms ease, border-color 120ms ease, background-color 120ms ease;
}

#picktable .team:hover {
  color: var(--band-deep);
  border-bottom-color: var(--band-mid);
  background: var(--chalk);
}

/* Game column head: matchup / spread / final, stacked tight */
.game-head {
  padding: 3px 3px 9px !important;
  width: 50px;
  vertical-align: bottom !important;
  text-align: center;
}

.game-matchup {
  white-space: nowrap;
  font-family: var(--font-agate);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0;
}

/* "@" is the sport's own notation for away-at-home; "vs" was wrong here. */
.game-at {
  color: var(--ink-faint);
  font-weight: 400;
  padding: 0 1px;
}

/* Name cell: the watermark sits behind, so this layer needs its own stacking.
   min-width:0 on both the flex line and the name lets a long name ellipsize
   rather than force the cell wider than its column. */
.player-cell {
  position: relative;
  z-index: 1;
  padding: 6px 9px;
  display: flex;
  align-items: baseline;
  gap: 7px;
  min-width: 0;
  max-width: 100%;
}

.player-cell .player-name {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.player-cell .player-rank { flex: 0 0 auto; }

/* Spread and final, set as data not decoration */
.game-spread {
  display: block;
  font-family: var(--font-agate);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.04em;
  color: var(--accent);
  filter: brightness(0.72);   /* gold is for chips; keep type readable */
  margin-top: 2px;
}

/* The final score doubles as the "this game is done" marker. Set as a chip,
   it announces the boundary between the played and the unplayed once per
   column -- sixteen marks rather than one under each of 624 cells, which is
   what the rules under the badges were. It also happens to be the number you
   came to look at. */
/* Shut games. Amber, and deliberately not the burnt orange of --accent: that
   colour already means "this is your pick", and a second meaning on the same
   hue is how a legend starts lying. Live and Locked are both closed; the word
   says which kind of closed. */
.game-state {
  display: inline-block;
  /* Not the condensed face. Agate is right for a column of numbers read down
     the page; it is wrong for four white letters on a dark ground at 11px,
     where its stems are too fine to cover a pixel. */
  font-family: var(--font-ui);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  padding: 2px 7px;
  margin-top: 3px;
  color: #fff;
  background: var(--shut);
}

/* Locked was amber-on-cream, which measured 4.62:1 -- inside AA on paper and
   thin on a phone at this size. Both shut states are the same solid chip now,
   at 7.5:1, and the word is what separates them: the colour says the game is
   closed, "Live" or "Locked" says which kind of closed. */
.game-state.is-locked {
  color: #fff;
  background: var(--shut);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
}

/* The whole column steps back when it is shut, so "can I still pick this"
   is answerable without reading a word. */
#picktable thead th.is-live,
#picktable thead th.is-locked { background: #FDF8EF; }

.game-final {
  display: inline-block;
  font-family: var(--font-ui);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.01em;
  font-variant-numeric: tabular-nums;
  color: #fff;
  background: var(--band-deep);
  padding: 2px 7px;
  margin-top: 3px;
}

/* A score that is not the score yet. Same chip so the column does not jump
   when the game ends, in the amber that means "shut but not settled" rather
   than the near-black that means "this is the result", with a dot in front
   that a final score never has. Amber carries a white 12px bold at 5.0:1.

   The dot does not blink. A blinking element on sixteen columns at once is a
   fairground, and it would still be blinking an hour after the last whistle
   if a final post ever went missing. */
.game-final.is-running {
  background: var(--shut);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
}

.game-final.is-running::before {
  content: '';
  display: inline-block;
  width: 5px;
  height: 5px;
  margin-right: 5px;
  border-radius: 50%;
  background: #FFD9A8;
  vertical-align: 1px;
}

/* With the score carrying the weight, the line it sits under can step back. */
#picktable .game-spread { color: var(--ink-soft); }

/* An undecided pick is held back, so a badge at full strength always means
   you got it right. Grey still means you did not. */
#picktable .pick-img.pending { opacity: 0.5; }

/* Made by your standing rule, not by you. Only ever on your own row -- whether
   someone else's pick came from a rule is not your business, and 38 more marks
   would be noise in a grid that is already dense.

   A corner tick rather than a badge: it has to be findable when you go looking
   and ignorable when you are reading the week. */
#picktable td { position: relative; }

#picktable .pick-img.by-rule::after { content: none; }   /* img has no ::after */

#picktable .pick-img.by-rule {
  /* The mark is painted into the cell corner behind the logo's transparent
     margin, so it costs the badge no room. */
  background-image: linear-gradient(135deg, var(--accent) 0 5px, transparent 5px);
  background-repeat: no-repeat;
  background-position: top right;
}

/* Same fact in the picks panel, where there is room to say it in words. */
.mypick.is-by-rule .mypick-when::after {
  content: 'AUTO';
  display: block;
  margin-top: 3px;
  font-family: var(--font-agate);
  font-size: 9px;
  font-weight: 700;
  letter-spacing: 0.12em;
  color: var(--accent);
}

/* --- Body rows ----------------------------------------------------------- */

#picktable tbody td {
  border: 0;
  border-bottom: 1px solid var(--rule);
  padding: 5px 3px;
  vertical-align: middle;
  background: var(--sheet);
}

#picktable tbody tr:hover td { background: #F5F7F9; }

/* Rank + score columns */
#picktable tbody td:nth-child(1),
#picktable tbody td:nth-child(2) {
  font-family: var(--font-agate);
  font-size: 15px;
  font-weight: 700;
  text-align: center;
  color: var(--ink);
}

#picktable tbody td:nth-child(2) { color: var(--ink-soft); font-weight: 600; }

/* Name column */
.player-name {
  font-family: var(--font-ui);
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--ink);
}

.player-rank {
  font-family: var(--font-agate);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--ink-faint);
}

/* --- The name column ----------------------------------------------------
   Frozen identity columns were tried and removed: they need pixel offsets that
   match the real column widths, and DataTables recomputes those from available
   space under table-layout:fixed, so the offsets drifted as the window narrowed
   and the frozen cells slid across the game columns.

   overflow:hidden is load-bearing, not cosmetic -- it is what guarantees the
   favourite-team watermark and a long name stay inside this cell instead of
   spilling over the first games.
   ------------------------------------------------------------------------ */

#picktable tbody td.player-td {
  /* No `position: relative` here. This cell is sticky (see §5), and being
     later in the file with equal specificity, a relative would win and drop
     the column out of the frozen block -- the body name column then sat 74px
     right of its own header. Sticky is a positioned element, so it is still a
     containing block for the watermark. */
  overflow: hidden;
  padding: 0;
}

/* The one place colour is let into the sheet, and it is not the designer's:
   it is the 39 allegiances of the people playing. The badge is flood-filled
   across the whole cell and bleeds off the right edge, which gives the column
   a rhythm down the page that no palette could invent.

   The div carried nothing but an opacity before this, so it collapsed to zero
   height and the watermark never rendered at all. */
.user-background-image {
  position: absolute;
  inset: 0;
  z-index: 0;
  background-repeat: no-repeat;
  /* Sized by height, not cover. In a cell four times wider than it is tall,
     cover crops a square badge to a quarter-height band -- a smear of team
     colour that reads as neither a badge nor a wash. Overscaled height keeps
     the mark's shape while still bleeding past the top and bottom edges. */
  background-size: auto 175%;
  background-position: right center;
  opacity: 0.55;
}

/* Names have to stay legible over 39 badges of wildly different value -- the
   Ravens' near-black and the Dolphins' aqua in the same column. Rather than
   fade every badge until none of them read, the scrim is solid where the name
   sits and gone by the right edge: crisp type on the left, full colour on the
   right. */
#picktable tbody td.player-td::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 1;
  pointer-events: none;
  background: linear-gradient(
    90deg,
    var(--sheet) 0%,
    rgba(255, 255, 255, 0.94) 34%,
    rgba(255, 255, 255, 0.62) 66%,
    rgba(255, 255, 255, 0.28) 100%
  );
}

/* Above both layers. */
#picktable tbody td.player-td .player-cell { z-index: 2; }

/* Your own badge carries a shade more. */
#picktable tbody tr.current-user .user-background-image { opacity: 0.62; }

/* A faint ground under the identity block. It separates who from what they
   picked, and it gives the pale badges -- the Saints' white fleur, the Jets'
   white wordmark -- something to sit on; on bare white they disappeared. Your
   own row stays pure white, so the lift reads harder against it. */
#picktable tbody td.player-td { background: #F4F6F8; }

/* Ruled off from the games, so the eye knows where identity ends and picks
   begin -- the job the frozen columns were there to do. */
#picktable thead th:nth-child(3),
#picktable thead td:nth-child(3),
#picktable tbody td.player-td {
  border-right: 2px solid var(--rule);
}

/* The week's winner is styled after your own line, further down -- it has to
   come later in the file to beat it, because the winner can also be you. */

/* --- Your own line ------------------------------------------------------ */

/* Your line is raised, not filled. A 16-column block of near-black fought
   every badge in the row and buried the one line you look at first. It is
   lifted off the sheet instead: ruled top and bottom the way a ledger rules
   its total, sitting on a soft shadow, and carrying a little more height than
   the lines around it. All of it rides the row, so a re-sort still finds you.

   Nothing about the DATA changes on your row -- hits and misses keep the
   colours they have everywhere else, or your own line would be the one row
   you cannot compare against the rest. */
#picktable tbody tr.current-user td {
  background: var(--sheet) !important;
  color: var(--ink) !important;
  border-top: 1px solid rgba(16, 20, 26, 0.22);
  border-bottom: 1px solid rgba(16, 20, 26, 0.22) !important;
  padding-top: 11px;
  padding-bottom: 11px;
  /* Cast above and below. A <tr> cannot carry a shadow, so every cell casts
     its own and they join into one edge across the row. */
  box-shadow:
    0 14px 20px -12px rgba(16, 20, 26, 0.55),
    0 -10px 18px -14px rgba(16, 20, 26, 0.38);
}

/* The shadow has to fall ON the neighbouring rows, so these cells sit above
   them. The frozen cells are already sticky -- which is positioned, so they
   take a z-index directly; the game cells need position for theirs. */
#picktable tbody tr.current-user td:nth-child(-n+3) { z-index: 6; }

#picktable tbody tr.current-user td:nth-child(n+4) {
  position: relative;
  z-index: 2;
}

#picktable tbody tr.current-user:hover td { background: #FBFCFD !important; }

/* The left edge of the box, plus the accent tab. Both live on the frozen
   block, so they stay beside you when the games scroll away to the right. */
#picktable tbody tr.current-user td:nth-child(1) {
  box-shadow:
    inset 4px 0 0 var(--accent),
    -12px 0 18px -14px rgba(16, 20, 26, 0.45),
    0 14px 20px -12px rgba(16, 20, 26, 0.55),
    0 -10px 18px -14px rgba(16, 20, 26, 0.38);
}

/* And the right edge, where the sheet ends. */
#picktable tbody tr.current-user td:last-child {
  box-shadow:
    12px 0 18px -14px rgba(16, 20, 26, 0.45),
    0 14px 20px -12px rgba(16, 20, 26, 0.55),
    0 -10px 18px -14px rgba(16, 20, 26, 0.38);
}

#picktable tbody tr.current-user td:nth-child(1),
#picktable tbody tr.current-user td:nth-child(2) {
  color: var(--ink) !important;
  font-weight: 700;
}

#picktable tbody tr.current-user .player-name { color: var(--ink); font-weight: 700; }
#picktable tbody tr.current-user .player-rank { color: var(--accent); }

/* ==========================================================================
   The week's winner
   ==========================================================================
   Finished weeks only. Your own line is RAISED off the sheet; the winner's is
   INVERTED -- the identity block goes to the dark band, name in white, figure
   in lifted orange, and the week is named underneath in so many words. Two
   different signals, so a row that is both still reads as both: the plate
   sits inside the shadow box.

   Everything is confined to the three frozen columns plus a rule top and
   bottom. The picks themselves stay exactly as they are everywhere else --
   fill the whole row and the winner becomes the one line you cannot compare
   against the rest, which is the opposite of what a scorecard is for.

   This block must stay AFTER "Your own line": both are !important on the same
   properties, so the later one wins, and when the winner is you the plate is
   the one that has to survive.
   ========================================================================== */

#picktable tbody tr.is-winner td {
  border-top: 2px solid var(--accent) !important;
  border-bottom: 2px solid var(--accent) !important;
}

/* The plate. Frozen block only, so it stays beside the winner while the games
   scroll away to the right. */
#picktable tbody tr.is-winner td:nth-child(-n+3),
#picktable tbody tr.is-winner td.player-td,
#picktable tbody tr.is-winner:hover td:nth-child(-n+3),
#picktable tbody tr.is-winner:hover td.player-td {
  background: var(--band-deep) !important;
}

#picktable tbody tr.is-winner td:nth-child(1) {
  color: var(--accent-up) !important;
  font-weight: 700;
}

#picktable tbody tr.is-winner td:nth-child(2) {
  color: rgba(255, 255, 255, 0.78) !important;
}

#picktable tbody tr.is-winner .player-name {
  color: #FFFFFF !important;
  font-weight: 700;
}

#picktable tbody tr.is-winner .player-rank {
  color: rgba(255, 255, 255, 0.5) !important;
}

/* The favourite-team wash is tuned for a white cell, where it reads as a faint
   tint. On the plate it goes the other way and lifts, so it is taken right
   down -- a pale logo at wash strength turned the band to grey and took the
   white name with it. Screen blending was worse again for the same reason. */
#picktable tbody tr.is-winner .user-background-image { opacity: 0.16; }

/* The name cell holds a white scrim so the team wash never fights the name.
   It is the same ramp inverted here -- without this the scrim simply paints
   the plate back to white, which is exactly what it did. */
#picktable tbody tr.is-winner td.player-td::after {
  background: linear-gradient(
    90deg,
    var(--band-deep) 0%,
    rgba(28, 37, 48, 0.94) 34%,
    rgba(28, 37, 48, 0.62) 66%,
    rgba(28, 37, 48, 0.28) 100%
  );
}

/* Named, not just marked. On its own line inside the name cell: the column is
   tight enough that a long name already crowds the rank.

   Only winners wrap. Wrapping every name cell dropped the rank to a second
   line on narrow screens and made all 39 rows taller. */
#picktable tbody tr.is-winner .player-cell { flex-wrap: wrap; }

.winner-banner {
  flex: 0 0 100%;
  margin-top: 3px;
  font-family: var(--font-agate);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: var(--accent-up);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.winner-banner i {
  margin-right: 4px;
  font-size: 11px;
}

/* ==========================================================================
   6. The tally rule — the signature
   ==========================================================================
   Was: correct = full opacity, wrong = the same logo at 0.2 opacity, which
   reads as "still loading" and wrecks the mark. Now each pick carries a rule
   underneath, so a row scans as a line of pencil ticks:
     solid slate = hit
     red dash    = miss
     no rule     = not played yet
   ========================================================================== */

.pick-img {
  width: 42px;
  height: auto;
  display: block;
  margin: 0 auto;
  padding-bottom: 4px;
  border-bottom: 3px solid transparent;
  transition: filter 120ms ease;
}

/* No rule under the badge. Whether a game is settled is already stated at
   the top of its column -- a final score is there or it is not -- so the badge
   only has to answer "did I get it", and full colour against grey says that
   without drawing a line under all 624 of them. */
.pick-img.hit     { border-bottom-color: transparent; }
.pick-img.miss    { border-bottom-color: transparent; filter: grayscale(1); opacity: 0.32; }
/* A missed pick is information -- it needs to be visible on a white row. */
.pick-img.empty   { opacity: 0.4; filter: grayscale(1); border-bottom-color: transparent; }

/* A game not yet played draws no rule at all. It used to carry a dotted one,
   but "not played yet" is the default state of every cell on the page until
   results land -- 640 of 640 in week 1 -- so it marked nothing and read as
   noise. The 3px stays reserved by .pick-img above, so the hit and miss rules
   appear without shifting anything. */
.pick-img.pending { border-bottom-color: transparent; }


/* No pick. The placeholder art is a blank pixel, so the absence is drawn
   rather than pictured -- and it has to be visible, because a missed game is
   how a week gets away from you. */
.no-pick {
  display: block;
  text-align: center;
  font-family: var(--font-agate);
  font-size: 15px;
  line-height: 42px;
  color: var(--ink-faint);
  opacity: 0.6;
}

/* Legacy class kept so an un-migrated cell still reads as a miss. */
.pick-img.incorrect:not(.miss):not(.hit) {
  filter: grayscale(1);
  opacity: 0.5;
  border-bottom-color: transparent;
}

/* ==========================================================================
   7. Tie breaker cell
   ========================================================================== */

.tb-cell { text-align: center; padding: 5px 6px !important; }

.tb-chip {
  display: inline-block;
  min-width: 42px;
  font-family: var(--font-agate);
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.03em;
  padding: 4px 8px;
  border: 1px solid var(--rule);
  border-radius: 0;
  background: var(--sheet);
  color: var(--ink);
}

.tb-chip.is-set    { border-color: var(--band-mid); border-left: 3px solid var(--band-mid); color: var(--band-deep); }
.tb-chip.is-unset  { border-color: var(--miss); border-left: 3px solid var(--miss); color: var(--miss); font-size: 10px; letter-spacing: 0.09em; text-transform: uppercase; }
.tb-chip.is-hidden { border-style: dashed; color: var(--ink-faint); font-size: 10px; letter-spacing: 0.09em; text-transform: uppercase; }

/* Your own chip. This was white on a 10%-white ground, which was legible on
   the dark row it was written for and invisible the moment the row went
   white. */
tr.current-user .tb-chip {
  background: var(--sheet);
  border-color: var(--accent);
  border-left: 3px solid var(--accent);
  color: var(--ink);
}

/* --- Tie breaker ---------------------------------------------------------
   Entered in the cell that already holds it -- the sheet's last column -- and
   in its own game's row in the picks panel. It used to have a strip of its
   own above the sheet, which spent a band of vertical space on one number. */

.tb-entry {
  /* Sized by the cell, never by a fixed width: the tie-break column narrows
     to 62px on a phone, where a 58px field plus the cell's padding overflowed
     it. box-sizing is border-box here, so 100% includes the border. */
  width: 100%;
  max-width: 100%;
  min-width: 0;
  height: 28px;
  padding: 3px 4px;
  text-align: center;
  font-family: var(--font-agate);
  font-size: 13px;
  font-weight: 700;
  color: var(--ink);
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-left: 3px solid var(--accent);
  border-radius: 0;
  transition: border-color 120ms ease, background-color 200ms ease;
}

.tb-entry::placeholder { color: var(--ink-faint); font-weight: 400; }

.tb-entry:focus {
  border-color: var(--band-mid);
  border-left-color: var(--accent);
  outline: none;
  box-shadow: 0 0 0 2px rgba(47, 66, 86, 0.16);
}

/* Saved: the field itself confirms, so nothing is inserted and nothing moves. */
.tb-entry.is-saved {
  border-color: var(--hit);
  border-left-color: var(--hit);
  background: #EFF4F8;
}

/* In the picks panel it sits on its own line under the game it belongs to. */
.mypick-tb {
  grid-column: 1 / -1;
  display: flex;
  align-items: center;
  gap: 9px;
  padding-top: 2px;
}

/* In the panel the field sizes to its content -- three digits -- rather than
   filling the row the way it must inside a table cell. */
.mypick-tb .tb-entry { flex: 0 0 74px; max-width: 74px; height: 34px; font-size: 14px; }

.mypick-tb label {
  margin: 0;
  font-family: var(--font-agate);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.11em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* ==========================================================================
   8. Controls
   ========================================================================== */

.btn {
  font-family: var(--font-agate);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  border-radius: 0;
  border: 1px solid transparent;
  box-shadow: none;
  text-shadow: none;
  background-image: none !important;
  padding: 8px 16px;
  transition: background-color 120ms ease, border-color 120ms ease, color 120ms ease;
}

.btn-primary {
  background: var(--band-deep) !important;
  border-color: var(--band-deep) !important;
  color: #fff !important;
}

.btn-primary:hover, .btn-primary:focus {
  background: var(--band-mid) !important;
  border-color: var(--band-mid) !important;
}

.btn-warning {
  background: var(--accent) !important;
  border-color: var(--accent) !important;
  color: #FFFFFF !important;
}

.btn-warning:hover, .btn-warning:focus { filter: brightness(0.93); }

/* Inline SVG icons sit on the text baseline the way the icon-font glyphs
   beside them do, and take their colour from the text. */
.icon-svg {
  display: inline-block;
  vertical-align: -0.15em;
  width: 1em;
  height: 1em;
}

.widget-header h4 .icon-svg { vertical-align: -0.12em; margin-right: 3px; }

/* Logout is a POST (Django 5 only clears the session in LogoutView.post), so
   it has to be a form. These rules make the submit button sit where the old
   anchor sat -- in the navbar dropdown and inline in the footer. */
.logout-form {
  display: inline;
  margin: 0;
  padding: 0;
}

.dropdown-menu .logout-form { display: block; }

.logout-link {
  background: none;
  border: 0;
  padding: 0;
  font: inherit;
  color: var(--band-mid);
  cursor: pointer;
}

.logout-link:hover, .logout-link:focus { color: var(--band-deep); text-decoration: underline; }

.dropdown-menu .logout-link {
  display: block;
  width: 100%;
  text-align: left;
  padding: 3px 20px;
  color: inherit;
}

.dropdown-menu .logout-link:hover,
.dropdown-menu .logout-link:focus { text-decoration: none; }

.btn-default {
  background: var(--sheet) !important;
  border-color: var(--rule) !important;
  color: var(--ink) !important;
}

.btn-default:hover, .btn-default:focus {
  background: var(--chalk) !important;
  border-color: var(--ink-faint) !important;
}

.btn-danger {
  background: var(--miss) !important;
  border-color: var(--miss) !important;
  color: #fff !important;
}

input[type="text"],
input[type="password"],
input[type="email"],
input[type="number"],
.form-control {
  font-family: var(--font-ui) !important;
  border: 1px solid var(--rule) !important;
  border-radius: 0 !important;
  box-shadow: none !important;
  background: var(--sheet);
  color: var(--ink);
}

input[type="text"]:focus,
input[type="password"]:focus,
input[type="email"]:focus,
.form-control:focus {
  border-color: var(--band-mid) !important;
  box-shadow: 0 0 0 2px rgba(47, 66, 86, 0.16) !important;
}

.control-label,
label.control-label {
  font-family: var(--font-agate);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-soft);
}

.alert {
  border-radius: 0;
  border: 1px solid var(--rule);
  border-left: 4px solid var(--ink-faint);
  background: var(--sheet);
  color: var(--ink);
  font-family: var(--font-ui);
  text-shadow: none;
}

.alert-success { border-left-color: var(--band-mid); background: #F1F4F8; }
.alert-danger, .alert-error { border-left-color: var(--miss); background: #FBF2F1; }
.alert-warning { border-left-color: var(--accent); background: #FBF1EA; }

/* ==========================================================================
   10. Phones
   ==========================================================================
   The page keeps its structure at every width -- "your picks" as a stacked
   list, then the matrix scrolling sideways under frozen identity columns.
   What changes here is density: the picking list drops to two rows per game
   so the buttons stay thumb-sized, and the frozen block narrows so there is
   room left to actually see the games.

   (This section used to style a second, phone-only copy of the whole 39-row
   matrix as cards. That copy is gone -- it was most of the page weight and
   only the viewer's own row was ever interactive in it.)
   ========================================================================== */

@media (max-width: 768px) {
  #content { padding-top: 68px !important; }

  /* The name column here is barely wider than "Week 1 winner" is long, and the
     banner truncated to "WEEK 1 WI...". The week is named on the tab above it
     anyway, so drop the qualifier and keep the word that matters. */
  .winner-banner .wb-scope { display: none; }

  .page-header {
    padding: 14px 16px;
    flex-direction: column;
    align-items: stretch;
    gap: 12px;
  }

  .page-header .page-title h3 { font-size: 22px; }

  .page-header .page-stats {
    width: 100%;
    border-top: 1px solid var(--rule);
    padding-top: 12px;
  }

  .page-header .page-stats > li {
    flex: 1;
    padding: 0 10px;
    justify-content: flex-start;
  }

  .page-stats .summary h3 { font-size: 24px; }

  /* Big targets on a narrow phone, but capped so the pair reads as a centred
     group rather than stretching to the edges on a wide one. */
  .team-option {
    flex: 1 1 0;
    min-width: 0;
    max-width: 132px;
    min-height: 58px;
  }

  /* --- The matrix ---------------------------------------------------------
     Narrower frozen block: names truncate rather than eat the viewport, and
     the sticky offsets follow automatically from these variables. */
  :root {
    --w-weekly: 38px;
    --w-total:  42px;
    --w-name:   108px;
    --w-game:   74px;
    --w-tb:     68px;
  }

  #picktable { font-size: 11px !important; }

  /* The matchup stays on one line. Stacking it fitted the column but broke
     the fixture across two rows, which reads worse than it saves; the column
     gets the width instead, and the hairline between columns does the
     separating that was actually missing. */

  .player-cell .player-name {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    max-width: 100%;
  }

  .pick-img { width: 30px; }

  /* A hint that there is more to the right of the frozen block. */
  #picktable thead th:nth-child(3),
  #picktable tbody td.player-td {
    box-shadow: 3px 0 4px -2px rgba(16, 20, 26, 0.18);
  }

  .tb-cell { padding: 4px 3px !important; }

  .sheet-filter { font-size: 11px; }
  .widget-header h4 { font-size: 15px; }
}

/* ==========================================================================
   10b. Toasts
   ==========================================================================
   What window.alert() was doing: blocking the page, unstyleable, and putting
   a browser dialog in the middle of a sheet that is otherwise entirely our
   own. These sit outside the layout so nothing reflows when one appears, and
   they read like the rest of the furniture -- square, ruled, agate.
   ========================================================================== */

.toast-rail {
  position: fixed;
  z-index: 1080;          /* over the fixed band, which is the tallest thing */
  right: 18px;
  bottom: 18px;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 8px;
  pointer-events: none;   /* the rail never eats clicks; the toasts do */
  max-width: min(380px, calc(100vw - 36px));
}

.toast {
  pointer-events: auto;
  display: flex;
  align-items: flex-start;
  gap: 10px;
  width: 100%;
  padding: 11px 12px 11px 14px;
  background: var(--band-deep);
  border-left: 4px solid var(--ink-faint);
  color: #fff;
  box-shadow: 0 10px 24px -10px rgba(16, 20, 26, 0.75);
  /* Visible by default and animated in, rather than starting invisible and
     waiting for script to reveal it. If the animation is blocked, throttled
     or unsupported the toast is simply there, which is the failure worth
     having. */
  opacity: 1;
  /* No fill-mode. `both` includes a backwards fill, which applies the
     zero-opacity first keyframe whenever the animation has not started --
     the same fail-invisible trap as the rAF version, in CSS clothing. With
     no fill the element simply uses its own opacity: 1 until the animation
     actually runs. */
  animation: toast-in 160ms ease;
}

/* Only the slide is animated. Opacity is never a keyframe: an animation that
   is started but not advancing -- throttled, backgrounded, whatever -- holds
   its first frame, and if that frame said opacity 0 the toast would be
   invisible for its whole life. Stranded on this one, it is merely 8px low. */
@keyframes toast-in {
  from { transform: translateY(8px); }
  to   { transform: none; }
}

.toast.is-going {
  opacity: 0;
  transform: translateY(8px);
  transition: opacity 160ms ease, transform 160ms ease;
}

.toast-text {
  flex: 1 1 auto;
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.4;
}

.toast-close {
  flex: 0 0 auto;
  width: 22px;
  height: 22px;
  margin: -2px -4px 0 0;
  padding: 0;
  background: none;
  border: 0;
  color: rgba(255, 255, 255, 0.6);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
}

.toast-close:hover, .toast-close:focus { color: #fff; }

/* The left rule carries the kind, the way it does on the alerts and the
   picking chips. */
.toast.is-error { border-left-color: var(--miss); }
.toast.is-ok    { border-left-color: var(--hit); }
.toast.is-info  { border-left-color: var(--accent); }

/* On a phone they span the width at the bottom, where a thumb is. */
@media (max-width: 640px) {
  .toast-rail {
    right: 10px;
    left: 10px;
    bottom: 10px;
    max-width: none;
    align-items: stretch;
  }
}

/* ==========================================================================
   11. Auto Picks
   ==========================================================================
   A filler for the games you forgot. The menu sits in the nav beside the
   account menu; the confirmation is its own dialog because choosing between
   "this week" and "the rest of the year" needs the two counts side by side,
   and a browser confirm() cannot show them.
   ========================================================================== */

.navbar-nav .autopick > a > .icon-magic { margin-right: 6px; opacity: 0.75; }

/* A standing rule on the bar. Everything else in this menu happens because you
   clicked it and finishes while you are looking; a rule keeps acting for the
   rest of the season with the menu shut, so the one state worth carrying out
   here is that one.

   Two marks rather than one, because colour alone is not a signal everybody
   receives: the wand takes the accent, and a dot follows the label. Both use
   --accent-up, the orange lifted to survive the slate band -- plain --accent
   goes muddy on it. */
.navbar-nav .autopick .ap-dot { display: none; }

.navbar-nav .autopick.has-rule > a > .icon-magic { opacity: 1; color: var(--accent-up); }

.navbar-nav .autopick.has-rule .ap-dot {
  display: inline-block;
  width: 6px;
  height: 6px;
  /* Equal margins, but the markup keeps a space on the caret side and none on
     the label side -- so the gap it actually leaves is wider towards the
     caret, and the dot reads against the words it is marking. */
  margin: 0 6px;
  vertical-align: 1px;   /* centred on the cap height of the uppercase label */
  background: var(--accent-up);
  border-radius: 50%;
}

/* No pulse, for the same reason the running-score dot does not blink: it is
   reporting a setting, not an event, and it would still be going in March. */

.autopick-menu { min-width: 210px; }

/* The standing rule, at the top of the menu. It is the one thing here that
   keeps acting after you close the menu, so it is stated before the actions
   rather than tucked underneath them. */
.autopick-menu .autopick-standing {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 14px;
  font-family: var(--font-ui);
  font-size: 11px;
  color: var(--ink-soft);
  background: #FFF6F0;
  border-bottom: 1px solid var(--rule);
}

.autopick-menu .autopick-standing .aps-name {
  color: var(--accent);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.autopick-menu .autopick-standing .aps-clear {
  flex: 0 0 auto;
  padding: 0;
  font-size: 11px;
  color: var(--ink-soft);
  text-decoration: underline;
  background: none;
}

.autopick-menu .autopick-standing .aps-clear:hover { color: var(--miss); background: none; }

/* Nothing set: the row stays, greyed, so the feature is discoverable rather
   than only appearing once you have already found it. */
.autopick-menu .autopick-standing.is-off { background: none; }
.autopick-menu .autopick-standing.is-off .aps-name { color: var(--ink-faint); }
.autopick-menu .autopick-standing.is-off .aps-clear { display: none; }

/* Your usual tie breaker, under the rule it belongs to. Unlike the row above
   it does NOT stay when there is no rule: the number is stored on the rule and
   the sweep is what applies it, so with no rule the box would be a setting
   that goes nowhere. */
.autopick-menu .autopick-tb {
  padding: 7px 14px 9px;
  font-family: var(--font-ui);
  font-size: 11px;
  color: var(--ink-soft);
  background: #FFF6F0;
  border-bottom: 1px solid var(--rule);
}

.autopick-menu .autopick-tb.is-off { display: none; }

.autopick-menu .apt-form {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
}

.autopick-menu .apt-label {
  margin: 0;
  font-size: 11px;
  font-weight: normal;
  color: var(--ink-soft);
}

/* Narrow on purpose: three digits is the whole range, and a box sized for
   more invites a sentence. */
.autopick-menu .apt-box {
  width: 56px;
  padding: 2px 6px;
  font-family: var(--font-agate);
  font-size: 13px;
  font-weight: 600;
  color: var(--ink);
  text-align: center;
  background: var(--sheet);
  border: 1px solid var(--rule);
  border-radius: 2px;
}

.autopick-menu .apt-box:focus {
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(194, 91, 42, 0.18);
}

.autopick-menu .apt-note {
  display: block;
  margin-top: 5px;
  font-size: 10px;
  line-height: 1.35;
  color: var(--ink-faint);
}

/* The one item that removes picks instead of making them. */
.autopick-menu .autopick-sep {
  margin-top: 4px;
  padding-top: 4px;
  border-top: 1px solid var(--rule);
}

/* Secondary, not alarming. Clearing only removes what Auto Picks put there,
   only where the game is still open, and only after a confirmation -- the same
   reason the clear dialog is grey rather than replace mode's red.

   !important because the .dropdown-menu > li > a rule above already uses it to
   beat the theme, and specificity alone cannot answer that. */
.autopick-menu .autopick-sep > a { color: var(--ink-soft) !important; }
.autopick-menu .autopick-sep > a:hover { color: var(--miss) !important; }

/* Clearing is a removal, not a rewrite -- it gets its own colour rather than
   borrowing replace mode's red, which means "about to overwrite your work". */
.apc-shade.is-clearing .apc-card { border-top-color: var(--ink-soft); }
.apc-shade.is-clearing .apc-scope:not(:disabled) {
  background: var(--ink-soft);
  border-color: var(--ink-soft);
}
.apc-shade.is-clearing .apc-scope:not(:disabled):hover,
.apc-shade.is-clearing .apc-scope:not(:disabled):focus-visible { background: var(--ink); }
.apc-shade.is-clearing .apc-scope:not(:disabled) .apc-scope-detail { color: #E6E9ED; }

/* Says what every item below it does, once, instead of five items each
   carrying the same qualifier. */
.autopick-menu .autopick-note {
  padding: 7px 14px 8px;
  font-family: var(--font-ui);
  font-size: 11px;
  line-height: 1.35;
  color: var(--ink-faint);
  border-bottom: 1px solid var(--rule);
  margin-bottom: 4px;
}

/* --- The confirmation ---------------------------------------------------- */

.apc-shade {
  position: fixed;
  inset: 0;
  z-index: 2000;          /* over the fixed nav, under nothing */
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
  background: rgba(16, 20, 26, 0.55);
}

.apc-shade[hidden] { display: none; }

.apc-card {
  width: 100%;
  max-width: 420px;
  background: var(--sheet);
  border-top: 3px solid var(--accent);
  box-shadow: 0 24px 60px -18px rgba(16, 20, 26, 0.7);
  padding: 22px 22px 18px;
  outline: none;
}

.apc-title {
  margin: 0 0 8px;
  font-family: var(--font-display);
  font-size: 22px;
  line-height: 1.1;
  letter-spacing: 0.01em;
  text-transform: uppercase;
  color: var(--ink);
}

.apc-lede {
  margin: 0 0 18px;
  font-family: var(--font-ui);
  font-size: 13px;
  line-height: 1.5;
  color: var(--ink-soft);
}

/* The dialog is one shell in two modes, so parts of it are hidden with the
   hidden attribute -- which a bare `display: flex` class silently defeats,
   because the UA's [hidden] rule is weaker than any class. Stated here once
   rather than discovered per element. */
.apc-replace[hidden],
.apc-scope[hidden] { display: none; }

/* The one destructive switch in the dialog. Ruled off above and below so it
   does not read as part of the sentence, and never pre-checked. */
.apc-replace {
  display: flex;
  align-items: center;
  gap: 9px;
  margin: 0 0 16px;
  padding: 10px 12px;
  border: 1px solid var(--rule);
  background: #F7F8FA;
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--ink-soft);
  cursor: pointer;
  user-select: none;
}

.apc-replace-box { margin: 0; flex: 0 0 auto; }

.apc-shade.is-replacing .apc-replace {
  border-color: var(--miss);
  background: #FCF3F2;
  color: var(--miss);
  font-weight: 700;
}

/* In replace mode the scope buttons stop being neutral. The count in each one
   is now a count of picks being thrown away, and it should not look like the
   same button it was a moment ago. */
.apc-shade.is-replacing .apc-scope:not(:disabled) {
  background: var(--miss);
  border-color: var(--miss);
}

.apc-shade.is-replacing .apc-scope:not(:disabled):hover,
.apc-shade.is-replacing .apc-scope:not(:disabled):focus-visible {
  background: #8E2B22;
}

.apc-shade.is-replacing .apc-scope:not(:disabled) .apc-scope-detail { color: #FFD9D4; }

.apc-scopes {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* The scope buttons ARE the confirmation, so they carry the weight -- and each
   states its own count, because that number is the reason to pick one. */
.apc-scope {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  padding: 11px 14px;
  border: 1px solid var(--band-mid);
  background: var(--band-deep);
  color: #fff;
  text-align: left;
  cursor: pointer;
}

.apc-scope:hover:not(:disabled),
.apc-scope:focus-visible:not(:disabled) { background: var(--band-mid); }

.apc-scope-name {
  font-family: var(--font-ui);
  font-size: 14px;
  font-weight: 700;
  letter-spacing: 0.01em;
}

.apc-scope-detail {
  font-family: var(--font-agate);
  font-size: 11px;
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--accent-up);
}

/* Disabled rather than hidden: the two choices must not swap places under the
   cursor between one opening of this dialog and the next. */
.apc-scope:disabled {
  background: #EDEFF2;
  border-color: var(--rule);
  color: var(--ink-faint);
  cursor: default;
}

.apc-scope.is-empty .apc-scope-detail { color: var(--ink-faint); }

/* The standing rule is not a third scope, it is a different kind of act: the
   two above write picks now, this one writes down what to do later. Ruled off
   and lighter so it does not read as "the same thing, but bigger". */
.apc-standing {
  margin-top: 6px;
  padding-top: 14px;
  border: 0;
  border-top: 1px solid var(--rule);
  background: none;
  color: var(--ink);
}

.apc-standing:hover:not(:disabled),
.apc-standing:focus-visible:not(:disabled) { background: #F2F4F7; }

.apc-standing .apc-scope-detail { color: var(--accent); }
.apc-standing:disabled { background: none; color: var(--ink-faint); }

/* Replace mode turns the scope buttons red; the standing rule is unavailable
   there and must not join in. */
.apc-shade.is-replacing .apc-standing,
.apc-shade.is-replacing .apc-standing:not(:disabled) {
  background: none;
  border-color: var(--rule);
  color: var(--ink-faint);
}

.apc-cancel {
  display: block;
  margin: 14px auto 0;
  padding: 6px 12px;
  border: 0;
  background: none;
  font-family: var(--font-ui);
  font-size: 13px;
  color: var(--ink-soft);
  text-decoration: underline;
  cursor: pointer;
}

.apc-cancel:hover { color: var(--ink); }

.apc-shade.is-working .apc-card { opacity: 0.6; pointer-events: none; }

@media (max-width: 768px) {
  /* base.html pins every nav dropdown to left:0 so the theme's menus do not
     fly off-screen. For a menu that hangs off the right-hand end of the bar
     that is the bug rather than the fix -- it pushed this one past the right
     edge. Anchored to its own right instead. */
  .navbar-nav .autopick .dropdown-menu {
    left: auto !important;
    right: 0 !important;
    width: auto !important;
    min-width: 200px;
    max-width: calc(100vw - 16px);
  }

  .autopick-menu .autopick-note { white-space: normal; }
}

/* ==========================================================================
   12. Reduced motion
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  /* No slide, but the toast is opaque by default so it still shows. */
  .toast { animation: none; }

  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
}
