    
    :root {
      --d2-radius: 0.875rem;
      --d2-line: #e6e8ec;
      --d2-muted: #6b7280;
      --d2-card: #ffffff;
      --d2-accent: #2563eb;
      --d2-head: #f3f4f6;
    }
    html.dark {
      --d2-line: #2b3648;
      --d2-muted: #94a3b8;
      --d2-card: #1e293b;
      --d2-accent: #60a5fa;
      --d2-head: #0f172a;
    }

    body.d2poll, body.d2poll *, body.d2poll *::before, body.d2poll *::after { box-sizing: border-box; }

    body.d2poll { margin: 0; background: #f5f6f8; height: auto; min-height: 100%; }
    html.dark body.d2poll { background: #030712; }
    body.d2poll > main { flex: 1 1 auto; flex-shrink: 0; padding-top: 4.5rem; padding-bottom: 3rem; }
    @media (min-width: 768px) { body.d2poll > main { padding-top: 6rem; } }

    /* ONE column width for the whole page, and it is the HEADER's: full width
       up to 96rem with 1rem gutters, the same container picks.php and
       /d2-pickem use (`container mx-auto px-4`). It was a 44rem column centred
       under a 1248px header, which is what cut team names off in the builder.
       Everything inside lines up with it; the parts that read badly that wide
       get inner grids instead of a narrower page. */
    .d2-wrap { width: 100%; max-width: 96rem; margin-inline: auto; padding-inline: 1rem; }
    @media (max-width: 300px) { .d2-wrap { padding-inline: 0.5rem; } }
    .d2-wrap > section { margin-bottom: 1.25rem; }
    /* The admin-only cards (ingest warnings, disputed finals) sat flush on the
       tab strip. */
    .d2-wrap > .d2-card { margin-bottom: 0.875rem; }

    /* ---- hero ---------------------------------------------------------- */
    .d2-hero { position: relative; overflow: hidden; border-radius: var(--d2-radius);
               padding: 0.7rem 0.9rem 0.75rem; color: #f8fafc; text-align: center;
               background: linear-gradient(140deg, #0b2f5e 0%, #131c3f 48%, #2f0f52 100%); }
    .d2-hero::after { content: ""; position: absolute; inset: 0; pointer-events: none;
               background: radial-gradient(900px 200px at 50% -40%, rgba(56,189,248,0.30), transparent 62%),
                           radial-gradient(700px 200px at 80% 130%, rgba(217,70,239,0.24), transparent 62%); }
    .d2-hero > * { position: relative; z-index: 1; }
    @media (min-width: 768px) { .d2-hero { padding: 2rem 1.5rem 1.75rem; }
                                .d2-stats { margin-top: 1rem; } }

    .d2-eyebrow { display: inline-block; font-size: 0.68rem; font-weight: 800; letter-spacing: 0.14em;
                  text-transform: uppercase; color: #bae6fd;
                  background: rgba(8,47,73,0.5); border: 1px solid rgba(125,211,252,0.32);
                  padding: 0.25rem 0.55rem; border-radius: 999px; }
    .d2-hero h1 { margin: 0.25rem 0 0; font-weight: 900; letter-spacing: -0.025em; line-height: 1.05;
                  font-size: clamp(1.25rem, 5.6vw, 2.5rem); }
    /* The subtitle is three lines on a phone and the page says the same thing
       in its own first rows. Keep it for desktop and for what search engines
       read; hide it where the room actually costs something. */
    .d2-hero p.sub { margin: 0.3rem auto 0; font-size: 0.85rem; line-height: 1.4; color: #c7d2e5; max-width: 34rem; }
    @media (max-width: 767px) { .d2-hero p.sub { display: none; } }
    .d2-eyebrow { font-size: 0.6rem; padding: 0.15rem 0.45rem; }
    .d2-hero a.thread { color: #7dd3fc; font-weight: 700; text-decoration: underline; }

    .d2-stats { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.5rem;
                margin-top: 0.7rem; text-align: center; grid-auto-rows: 1fr; }
    @media (min-width: 768px) { .d2-stats { grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.75rem; } }
    .d2-stat { display: flex; flex-direction: column; height: 100%;
               background: rgba(2,6,23,0.38); border: 1px solid rgba(148,163,184,0.22);
               border-radius: 0.7rem; padding: 0.55rem 0.65rem; min-width: 0; }
    @media (max-width: 1023px) { .d2-stat.hide-sm-card { display: none; } }
    .d2-stat .k { font-size: 0.62rem; letter-spacing: 0.09em; text-transform: uppercase; color: #94a3b8; font-weight: 800; }
    .d2-stat .v { font-size: 1.1rem; font-weight: 900; line-height: 1.2; margin-top: 0.1rem; overflow-wrap: break-word; }
    .d2-stat .n { font-size: 0.7rem; line-height: 1.35; color: #c7d2e5; margin-top: 0.1rem; }

    /* ---- week dropdowns + segmented tabs ---------------------------------- */
    /* Every week choice on the page (the poll week, a voter's weeks under All
       ballots, a voter's ballot history) is a <select>, like the rest of the
       site: the list grows every week and a row of pills does not. 16px so iOS
       does not zoom on focus. */
    .d2-week-select, .wk-select, .vh-select {
      min-height: 44px; padding: 0 2rem 0 0.8rem; font-size: 16px; font-weight: 700; box-sizing: border-box;
      max-width: 100%; border-radius: 0.6rem; border: 1px solid var(--d2-line); background-color: var(--d2-card);
      color: inherit; }
    .d2-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 0.4rem; }
    .d2-weeks { display: flex; justify-content: center; margin-bottom: 0.875rem; }
    .d2-week-select { min-width: 12rem; }

    .d2-tabs { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0.25rem;
               background: var(--d2-card); border: 1px solid var(--d2-line); border-radius: 0.75rem;
               padding: 0.25rem; margin: 0 0 0.875rem; }
    /* The explainer sits in the tab strip on a wide screen and in the filter
       row on a phone. Both are always in the DOM; exactly one is shown. */
    .rules-slot-wide { display: none; }
    @media (min-width: 768px) {
      .d2-tabs { grid-template-columns: repeat(4, minmax(0, 1fr)) auto; }
      .rules-slot-wide { display: block; }
      .rules-slot-phone { display: none; }
      /* Open, it drops below the strip rather than stretching a tab. */
      .d2-tabs .rules-slot-wide details[open] { grid-column: 1 / -1; }
    }
    .d2-tab { min-height: 44px; padding: 0 0.3rem; border-radius: 0.55rem; border: 0; background: transparent;
              color: inherit; font-weight: 700; font-size: 0.76rem; cursor: pointer; line-height: 1.15; }
    @media (min-width: 640px) { .d2-tab { font-size: 0.85rem; } }
    .d2-tab.is-on { background: var(--d2-accent); color: #fff; }

    /* ---- controls ------------------------------------------------------- */
    .d2-controls { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.4rem;
                   margin-bottom: 0.75rem; align-items: center; }
    .d2-controls input[type="search"] { grid-column: 1 / -1; }
    @media (min-width: 768px) { .d2-controls { grid-template-columns: 2fr 1fr 1fr auto auto; align-items: center; }
                                .d2-controls input, .d2-controls select { font-size: 0.88rem; }
                                .d2-controls input[type="search"] { grid-column: auto; } }
    
    .d2-controls > * { min-width: 0; }
    /* 16px, not 14. Safari on iOS ZOOMS THE PAGE when a focused control has a
       font smaller than 16px, which is what "clicking the search box resizes
       the screen" is - the same thing that made the ballot picker look like it
       was jumping. Nothing here is allowed under 16px on a phone. */
    .d2-controls input, .d2-controls select {
      width: 100%; min-width: 0; min-height: 44px; padding: 0 0.7rem; font-size: 16px; box-sizing: border-box;
      border-radius: 0.6rem; border: 1px solid var(--d2-line); background: var(--d2-card); color: inherit; }
    .d2-check { display: inline-flex; align-items: center; justify-content: center; gap: 0.4rem; min-height: 44px;
                font-size: 0.78rem; font-weight: 700; color: var(--d2-muted);
                border: 1px solid var(--d2-line); border-radius: 0.6rem; padding: 0 0.5rem; }
    @media (min-width: 768px) { .d2-check { grid-column: auto; white-space: nowrap; } }
    .d2-check input { width: 1.05rem; height: 1.05rem; min-height: 0; }

    /* ---- board ---------------------------------------------------------- */
    .d2-card { background: var(--d2-card); border: 1px solid var(--d2-line); border-radius: var(--d2-radius); overflow: hidden; }
    .d2-scroll { overflow-x: visible; -webkit-overflow-scrolling: touch; }
    table.d2-board { width: 100%; border-collapse: collapse; font-size: 0.88rem; }
    /* ------------------------------------------------------------------
       The board is FIVE columns wide - rank, move, team, record, points -
       which is narrow enough to stay a table on a phone. It used to become a
       stack of cards below 1024px with a second line of stats under each
       team, and that second line was the "too much" - a phone showed four
       teams a screen. One table at every width is also the only layout that
       cannot drift between mobile and desktop, because there is only one of
       it. ESPN and the NCAA's AP page both do exactly this.
       ------------------------------------------------------------------ */
    table.d2-board th { text-align: left; font-size: 0.6rem; letter-spacing: 0.07em; text-transform: uppercase;
                        color: var(--d2-muted); font-weight: 800; padding: 0.4rem 0.35rem;
                        border-bottom: 1px solid var(--d2-line); white-space: nowrap;
                        background: var(--d2-head); position: sticky; top: 0; }
    table.d2-board td { padding: 0.34rem 0.35rem; border-bottom: 1px solid var(--d2-line);
                        vertical-align: middle; }
    table.d2-board tr:last-child td { border-bottom: 0; }

    /* table-layout: fixed so the columns below are honoured rather than
       negotiated - the team column is the one that must keep the room, and a
       logo plus a long name plus a conference badge will otherwise wrap and
       take the row from 33px to 61px. */
    table.d2-board { table-layout: fixed; }
    /* Full width now, like the header. What kept a 1440px row from falling
       apart was a 44rem cap; what does it now is the columns below: from
       1024px the board shows Ballots / Best-Worst / Avg / PPV - the numbers
       the phone row leaves to the team dialog - so the room carries data
       instead of white space between a name and its points. */
    /* Column widths sit on BOTH th and td: with table-layout:fixed the browser
       measures the FIRST row, which is the header - widths on the body cells
       alone were ignored and all five columns came out an equal 69px, which is
       what squeezed every team name into an ellipsis on a phone. */
    .c-rank { width: 1.35rem; }
    .c-move { width: 2.6rem; }
    .c-rec  { width: 2.1rem; }
    .c-pts  { width: 2.2rem; }
    @media (min-width: 768px) {
      .c-rank { width: 2.2rem; }
      .c-move { width: 3.2rem; }
      .c-rec  { width: 3.6rem; }
      .c-pts  { width: 3.6rem; }
    }
    /* Desktop-only stat columns. display:none on th AND td, so the fixed
       layout never reserves room for them on a phone. */
    table.d2-board .c-wide { display: none; }
    @media (min-width: 1024px) {
      table.d2-board .c-wide { display: table-cell; }
      .c-bal { width: 5rem; } .c-span { width: 6.5rem; } .c-avg { width: 4.5rem; } .c-ppv { width: 4.5rem; }
      td.c-wide { font-size: 0.8rem; font-weight: 600; color: var(--d2-muted); text-align: right;
                  font-variant-numeric: tabular-nums; white-space: nowrap; }
      th.c-wide { text-align: right; }
    }

    .rank, td.c-rank { font-weight: 900; font-size: 0.8rem; text-align: right;
                       font-variant-numeric: tabular-nums; color: var(--d2-muted); }
    td.c-move { white-space: nowrap; }
    /* A team name is NEVER cut off (owner, 2026-10-14). Desktop has the room
       for one line; on a phone the longest names wrap to a second line rather
       than ending in an ellipsis. */
    td.c-team { white-space: normal; overflow-wrap: anywhere; }
    .team { font-weight: 700; font-size: 0.82rem; }
    /* School marks, hotlinked from ESPN. Eight D2 programs are not in their
       database; those rows simply have no image and the name sits where the
       logo would be, so nothing shifts. */
    /* display:inline-block is load-bearing: the site's base CSS sets
       img { display: block }, which put every mark on its own line above the
       name and took the row to 51px. nowrap cannot fix a block element. */
    .tlogo { display: inline-block; width: 18px; height: 18px; object-fit: contain;
             vertical-align: middle; margin-right: 0.3rem; }
    /* The cell's line-height is pinned so an 18px mark cannot inflate the line
       box: a negative vertical-align pushed the image below the baseline and
       took the row from 33px to 51px, which is the opposite of the point. */
    td.c-team { line-height: 1.1; }
    @media (min-width: 768px) { .tlogo { width: 20px; height: 20px; margin-right: 0.4rem; } }
    .conf { display: inline-block; margin-left: 0.3rem; font-size: 0.56rem; font-weight: 800; letter-spacing: 0.02em;
            padding: 0.05rem 0.26rem; border-radius: 0.25rem; background: #eef2ff; color: #4338ca;
            vertical-align: 0.06rem; }
    html.dark .conf { background: #312e81; color: #c7d2fe; }
    /* First-place votes, the way a poll prints them: a small number beside the
       name. It is the one extra fact these pages all keep on the line. */
    .firsts-dot { margin-left: 0.2rem; font-size: 0.66rem; font-weight: 800; color: var(--d2-accent);
                  font-variant-numeric: tabular-nums; }
    td.c-rec { font-size: 0.72rem; font-weight: 600; color: var(--d2-muted);
               font-variant-numeric: tabular-nums; white-space: nowrap; }
    td.c-pts { text-align: right; font-size: 0.75rem; font-weight: 800;
               font-variant-numeric: tabular-nums; }
    th.c-pts { text-align: right; }
    .mv { font-weight: 800; font-size: 0.68rem; font-variant-numeric: tabular-nums; }
    .mv.up { color: #16a34a; } .mv.down { color: #dc2626; } .mv.flat { color: #9ca3af; }
    .mv.new { color: #d97706; font-size: 0.6rem; letter-spacing: 0.03em; }

    tr.board-row { cursor: pointer; }
    tr.board-row:hover { background: var(--d2-head); }
    tr.board-row:focus-visible { outline: 2px solid var(--d2-accent); outline-offset: -2px; }
    /* Where the points fall off a cliff, draw the cliff. */
    tr[data-tier="1"] td { border-top: 2px solid var(--d2-accent); }

    @media (min-width: 768px) {
      table.d2-board th { font-size: 0.64rem; padding: 0.5rem 0.6rem; }
      table.d2-board td { padding: 0.45rem 0.6rem; }
      .rank, td.c-rank { font-size: 0.9rem; }
      .team { font-size: 0.9rem; }
      td.c-rec { font-size: 0.78rem; }
      td.c-pts { font-size: 0.82rem; }
    }

    .d2-panel { display: none; }
    .d2-panel.is-on { display: block; }
    .d2-note { font-size: 0.78rem; line-height: 1.45; color: var(--d2-muted); margin: 0.6rem auto 0; max-width: 46rem; }
    h2.d2-h { font-size: 1rem; font-weight: 900; margin: 1.25rem 0 0.5rem; text-align: center; }

    /* ---- one ballot at a time (scales to any number of voters) ----------- */
    .ballot-pick { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0.4rem; margin-bottom: 0.75rem; }
    @media (min-width: 768px) { .ballot-pick { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
    .ballot-pick > * { min-width: 0; }
    .ballot-pick select { width: 100%; min-width: 0; box-sizing: border-box; min-height: 44px; padding: 0 0.7rem; font-size: 16px;
                          border-radius: 0.6rem; border: 1px solid var(--d2-line); background: var(--d2-card); color: inherit; }
    .ballot-list { list-style: none; margin: 0; padding: 0; }
    .ballot-list li { display: grid; grid-template-columns: 1.9rem minmax(0, 1fr) auto; gap: 0.5rem;
                      align-items: baseline; padding: 0.45rem 0.7rem; border-bottom: 1px solid var(--d2-line); }
    .ballot-list li:last-child { border-bottom: 0; }
    .ballot-list .n { font-weight: 800; color: var(--d2-muted); font-variant-numeric: tabular-nums; font-size: 0.8rem; }
    .ballot-list .t { font-weight: 700; font-size: 0.88rem; }
    .ballot-list .d { font-size: 0.7rem; font-weight: 800; white-space: nowrap; }
    .ballot-list .d.up { color: #16a34a; } .ballot-list .d.down { color: #dc2626; } .ballot-list .d.same { color: var(--d2-muted); }

    /* ---- voters ---------------------------------------------------------- */
    .d2-voters { display: grid; gap: 0.5rem; }
    @media (min-width: 768px) { .d2-voters { grid-template-columns: repeat(2, minmax(0,1fr)); } }
    /* Voter cards three across once the page is header-wide. The two ballot
       panes on All ballots stay two (they are a side-by-side comparison). */
    @media (min-width: 1280px) { #vt-list { grid-template-columns: repeat(3, minmax(0,1fr)); } }
    /* Loading / could-not-load span the whole row, not one card's column. */
    .vt-loading, .vt-error { grid-column: 1 / -1; text-align: center; }
    .vt-error .btn { margin-top: 0.5rem; min-height: 44px; }
    .voter { border: 1px solid var(--d2-line); border-radius: 0.7rem; padding: 0.7rem 0.8rem; background: var(--d2-card); }

    /* ---- the in-progress teaser (Poll tab) -------------------------------- */
    .teaser { border: 1px solid var(--d2-line); border-top: 3px solid #2563eb; border-radius: 0.7rem;
              background: var(--d2-card); padding: 0.6rem 0.8rem; margin-bottom: 0.7rem; text-align: center; }
    .teaser-head { font-weight: 900; font-size: 0.92rem; margin-bottom: 0.3rem; }
    .teaser-head span { font-weight: 600; font-size: 0.78rem; color: var(--d2-muted); }
    .teaser-row { display: flex; flex-wrap: wrap; justify-content: center; align-items: baseline;
                  gap: 0.2rem 0.8rem; font-size: 0.84rem; margin-top: 0.2rem; }
    .teaser-row b { font-size: 0.72rem; text-transform: uppercase; letter-spacing: 0.04em; }
    .teaser-row i { font-style: normal; font-weight: 800; font-size: 0.76rem; }
    .teaser .up { color: #16a34a; } .teaser .down { color: #dc2626; }
    /* On a phone the third mover in a row wrapped onto a line of its own. Two
       fit on one line at 375px, so a phone shows two and a wider screen three. */
    @media (max-width: 639px) { .teaser-row span:nth-of-type(3) { display: none; } }
    .teaser-link { display: inline-block; margin-top: 0.45rem; font-size: 0.8rem; font-weight: 800; color: #2563eb; text-decoration: none; }

    /* ---- when a ballot came in, and the voter's other weeks (All ballots) -- */
    .ballot-when { margin: 0 0 0.4rem; font-size: 0.8rem; font-weight: 700; color: var(--d2-muted); }
    .ballot-list.has-prior li { grid-template-columns: 1.9rem minmax(0, 1fr) 2.4rem auto; }
    .wk-pick { margin: 0 0 0.875rem; }

    /* ---- every voter, week by week (Voters) ------------------------------- */
    /* Your own ballot, confirmed - the answer to "did it go in?". */
    .my-ballot { border: 1px solid #16a34a; background: rgba(22, 163, 74, 0.08); border-radius: 0.7rem;
                 padding: 0.55rem 0.75rem; margin-bottom: 0.7rem; font-size: 0.84rem; line-height: 1.45; }
    .you-tag { margin-left: 0.3rem; font-size: 0.64rem; font-weight: 800; text-transform: uppercase;
               padding: 0.05rem 0.35rem; border-radius: 0.3rem; background: #16a34a; color: #fff; vertical-align: 1px; }
    /* Your card, right after "See my name on the list": one pulse, then gone.
       The class is removed by the script after 2s. */
    .voter.is-you-flash { outline: 2px solid transparent; outline-offset: 2px; animation: d2-you-flash 2s ease-out; }
    @keyframes d2-you-flash {
      0%, 35% { outline-color: #16a34a; background: rgba(22, 163, 74, 0.16); }
      100%    { outline-color: transparent; background: var(--d2-card); }
    }
    @media (prefers-reduced-motion: reduce) {
      .voter.is-you-flash { animation: none; outline-color: #16a34a; }
    }
    /* One voter's history, inside their card, closed until tapped. */
    .card-hist { margin-top: 0.45rem; border-top: 1px solid var(--d2-line); }
    .card-hist > summary { cursor: pointer; min-height: 44px; display: flex; align-items: center;
                           font-size: 0.8rem; font-weight: 800; color: #2563eb; }
    .card-hist .vh-week { padding-left: 0; padding-right: 0; }
    .vh-voter { border: 1px solid var(--d2-line); border-radius: 0.7rem; background: var(--d2-card); }
    .vh-voter > summary { cursor: pointer; padding: 0.65rem 0.8rem; min-height: 44px; box-sizing: border-box;
                          display: flex; flex-wrap: wrap; align-items: baseline; gap: 0.2rem 0.6rem; }
    .vh-sum { font-size: 0.78rem; color: var(--d2-muted); }
    .vh-pick { padding: 0.5rem 0 0.55rem; }
    .vh-panel { padding: 0.35rem 0 0.6rem; }
    .vh-panel[hidden] { display: none; }
    .vh-week { border-top: 1px solid var(--d2-line); padding: 0.6rem 0.8rem; }
    .vh-head { font-weight: 800; font-size: 0.88rem; margin-bottom: 0.25rem; }
    .vh-sent { font-size: 0.8rem; color: var(--d2-muted); }
    .vh-sent.is-counted { color: inherit; font-weight: 600; }
    .vh-counts, .vh-replaced { margin-left: 0.35rem; font-size: 0.68rem; font-weight: 800; text-transform: uppercase;
                               letter-spacing: 0.03em; padding: 0.05rem 0.35rem; border-radius: 0.3rem; }
    .vh-counts { background: #16a34a; color: #fff; }
    .vh-replaced { border: 1px solid var(--d2-line); }
    /* Their ballot with the movement on the row: the name carries the colour,
       so the eye finds what moved without reading a second list. */
    .vh-ballot { margin-top: 0.4rem; }
    .vh-ballot .t.up { color: #15803d; }
    .vh-ballot .t.down { color: #b91c1c; }
    .voter .name { font-weight: 900; font-size: 0.92rem; }
    .voter .meta { font-size: 0.76rem; line-height: 1.45; color: var(--d2-muted); margin-top: 0.1rem; overflow-wrap: anywhere; }
    .lean { display: inline-block; margin-top: 0.3rem; font-size: 0.68rem; font-weight: 800;
            padding: 0.1rem 0.4rem; border-radius: 0.3rem; background: #ecfdf5; color: #047857; }
    html.dark .lean { background: #064e3b; color: #a7f3d0; }
    .src-tag { display: inline-block; margin-left: 0.3rem; font-size: 0.6rem; font-weight: 800; letter-spacing: 0.04em;
               text-transform: uppercase; padding: 0.08rem 0.3rem; border-radius: 0.25rem;
               background: #fef3c7; color: #92400e; }
    html.dark .src-tag { background: #78350f; color: #fde68a; }

    /* ---- ballot builder --------------------------------------------------- */
    /* The builder and the pool of teams not on the ballot. Side by side from
       1024px (the pool sticks while the ranks scroll); stacked below that,
       ranks first. */
    .bld-layout { display: grid; gap: 0.875rem; align-items: start;
                  grid-template-areas: "ranks" "pool" "actions"; }
    .bld-ranks { grid-area: ranks; } .pool { grid-area: pool; } .bld-actions { grid-area: actions; }
    .bld-layout > * { min-width: 0; }
    @media (min-width: 1024px) { .bld-layout { grid-template-columns: minmax(0, 1fr) 20rem;
                                               grid-template-areas: "ranks pool" "actions pool"; } }
    @media (min-width: 1280px) { .bld-layout { grid-template-columns: minmax(0, 1fr) 22rem; } }
    .bld-card { padding: 0.8rem; }
    @media (max-width: 380px) { .bld-card { padding: 0.5rem; } }

    /* Ranks flow DOWN the columns (1-13 then 14-25), so reading order and
       rank order agree. Columns only when there is room for a whole name. */
    .builder { display: grid; gap: 0.35rem; }
    @media (min-width: 768px) {
      .builder { grid-template-columns: repeat(2, minmax(0,1fr)); grid-template-rows: repeat(13, auto); grid-auto-flow: column; column-gap: 0.75rem; }
    }
    @media (min-width: 1440px) {
      .builder { grid-template-columns: repeat(3, minmax(0,1fr)); grid-template-rows: repeat(9, auto); }
    }
    .slot { position: relative; display: flex; align-items: center; gap: 0.3rem; min-width: 0; border-radius: 0.55rem; }
    .slot > .slot-n { flex: 0 0 1.5rem; text-align: right; font-weight: 800; font-size: 0.78rem;
                      color: var(--d2-muted); font-variant-numeric: tabular-nums; }
    /* A button, not a text box - same on phone and desktop. The team name
       WRAPS: it is never cut off (owner, 2026-10-14). */
    .slot-btn { flex: 1 1 auto; min-width: 0; box-sizing: border-box; min-height: 44px; padding: 0.3rem 0.6rem;
                display: flex; align-items: center;
                font-size: 0.88rem; font-weight: 700; line-height: 1.2; text-align: left; cursor: pointer;
                border-radius: 0.5rem; border: 1px solid var(--d2-line); background: var(--d2-card); color: inherit;
                white-space: normal; overflow-wrap: anywhere; }
    .slot-btn .slot-team { font-weight: 700; color: inherit; }
    .slot-btn .slot-team:empty::after { content: "pick a team"; color: var(--d2-muted); font-weight: 600; }
    .slot-btn.dupe { border-color: #d97706; border-width: 2px; }
    .slot-btn.empty { border-style: dashed; }

    /* ---- drag and drop (public/assets/js/d2-ballot-dnd.js) ---------------- */
    /* The handle: 44px, and the ONLY place touch-action:none lives, so a
       finger anywhere else still scrolls the page. Hidden (but still laid
       out, so rows line up) on an empty rank - there is nothing to drag. */
    .dnd-handle { flex: 0 0 44px; width: 44px; height: 44px; display: inline-flex; align-items: center; justify-content: center;
                  padding: 0; border: 0; border-radius: 0.5rem; background: transparent; color: var(--d2-muted);
                  cursor: grab; touch-action: none; -webkit-user-select: none; user-select: none;
                  -webkit-touch-callout: none; }
    .dnd-handle:hover { background: var(--d2-head); color: inherit; }
    .dnd-handle:focus-visible { outline: 2px solid var(--d2-accent); outline-offset: -2px; }
    .dnd-handle svg { width: 14px; height: 20px; pointer-events: none; }
    .slot.is-empty .dnd-handle { visibility: hidden; }
    html.d2-dragging, html.d2-dragging * { cursor: grabbing !important; -webkit-user-select: none; user-select: none; }

    /* The lifted row: follows the pointer, above everything, never a hit
       target itself (elementFromPoint looks straight through it). */
    .dnd-ghost { position: fixed; left: 0; top: 0; z-index: 100001; pointer-events: none;
                 display: flex; align-items: center; min-height: 44px; padding: 0.3rem 0.7rem;
                 border-radius: 0.55rem; border: 2px solid var(--d2-accent); background: var(--d2-card);
                 color: inherit; font-size: 0.88rem; font-weight: 800; line-height: 1.2; overflow-wrap: anywhere;
                 box-shadow: 0 14px 34px rgba(2, 6, 23, 0.35), 0 2px 6px rgba(2, 6, 23, 0.25); opacity: 0.96; }
    .dnd-ghost > .dnd-lift { display: flex; align-items: center; }
    .dnd-ghost.is-lifting > .dnd-lift { animation: dnd-lift 120ms ease-out both; }
    @keyframes dnd-lift { from { transform: scale(1); } to { transform: scale(1.03); } }

    /* Where it will land: the placeholder (dashed, tinted) with a solid
       insertion bar across its top. Rows the drop would shift get a quiet
       tint so the knock-on is visible before letting go. */
    .slot.is-drop .slot-btn { border: 2px dashed var(--d2-accent); background: rgba(37, 99, 235, 0.10); }
    .slot.is-drop::before { content: ""; position: absolute; left: 0; right: 0; top: -3px; height: 3px;
                            border-radius: 2px; background: var(--d2-accent); }
    .slot.is-shifted .slot-btn { background: rgba(37, 99, 235, 0.05); border-color: rgba(37, 99, 235, 0.45); }
    .slot-btn { transition: background-color 120ms ease, border-color 120ms ease; }
    .dnd-hint { min-height: 1.4rem; margin: 0.5rem 0 0; font-size: 0.82rem; font-weight: 700; color: var(--d2-accent); }
    .dnd-hint.is-warn { color: #b45309; }
    html.dark .dnd-hint.is-warn { color: #fbbf24; }

    /* The pool: every D2 program not on the ballot. A drop target as a whole
       (drop a ranked team here = take it off) and a drag source per team. */
    .pool { padding: 0.75rem; }
    @media (min-width: 1024px) { .pool { position: sticky; top: 5.5rem; } }
    .pool.is-drop { outline: 2px dashed var(--d2-accent); outline-offset: -2px; background: rgba(37, 99, 235, 0.06); }
    .pool-head { display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0.25rem 0.5rem; }
    .pool-head h3 { margin: 0; font-size: 0.95rem; font-weight: 900; }
    .pool-head span { font-size: 0.78rem; font-weight: 700; color: var(--d2-muted); }
    .pool-tip { margin: 0.25rem 0 0.5rem; font-size: 0.78rem; line-height: 1.4; color: var(--d2-muted); }
    .pool-q { width: 100%; min-height: 44px; padding: 0 0.7rem; font-size: 16px; border-radius: 0.6rem;
              border: 1px solid var(--d2-line); background: var(--d2-card); color: inherit; }
    .pool-list { margin-top: 0.5rem; max-height: 22rem; overflow-y: auto; overscroll-behavior: contain;
                 -webkit-overflow-scrolling: touch; border-top: 1px solid var(--d2-line); }
    @media (min-width: 1024px) { .pool-list { max-height: calc(100vh - 16rem); min-height: 12rem; } }
    .pool-group { position: sticky; top: 0; z-index: 1; padding: 0.3rem 0.25rem; font-size: 0.64rem; font-weight: 800;
                  letter-spacing: 0.08em; text-transform: uppercase; color: var(--d2-muted); background: var(--d2-head); }
    .pool-item { display: flex; align-items: center; gap: 0.2rem; border-bottom: 1px solid var(--d2-line); }
    .pool-add { flex: 1 1 auto; min-width: 0; min-height: 44px; padding: 0.3rem 0.4rem; display: flex; align-items: center;
                gap: 0.25rem; border: 0; background: transparent; color: inherit; text-align: left; cursor: pointer;
                font-size: 0.86rem; font-weight: 700; line-height: 1.2; overflow-wrap: anywhere; }
    .pool-add:hover { background: var(--d2-head); }
    .pool-add .tlogo { flex: 0 0 auto; }
    .pool-add .pool-name { min-width: 0; }
    .pool-add .pool-conf { margin-left: auto; padding-left: 0.4rem; flex: 0 0 auto; font-size: 0.66rem; font-weight: 800;
                           color: var(--d2-muted); white-space: nowrap; }
    .pool-empty { padding: 0.75rem 0.25rem; font-size: 0.82rem; color: var(--d2-muted); }
    /* The pool is built once and rows are shown/hidden with the hidden
       attribute; .pool-item's display:flex would otherwise beat the UA rule. */
    .pool-item[hidden], .pool-group[hidden], .pool-empty[hidden] { display: none; }

    /* Screen-reader only (the live region and the handle instructions).
       Explicit, not Tailwind's sr-only, which the purge may drop. */
    .d2-sr { position: absolute !important; width: 1px; height: 1px; padding: 0; margin: -1px;
             overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; }

    @media (prefers-reduced-motion: reduce) {
      .dnd-ghost.is-lifting > .dnd-lift { animation: none; }
      .slot-btn { transition: none; }
    }

    .d2pick[hidden] { display: none; }

    /* The overlay is only the scrim. It does NOT lay the sheet out: the sheet
       places itself, so where it sits can never depend on the height of a box
       the soft keyboard resizes. */
    .d2pick { position: fixed; inset: 0; z-index: 100000; box-sizing: border-box; }
    .d2pick-backdrop { position: absolute; inset: 0; background: rgba(3,7,18,0.6); }

    /* Phone: one fixed spot, high on the screen, and it does not move for any
       reason. `top` is a share of the SMALL viewport height - svh is defined
       against the browser's largest chrome and is not touched by a keyboard -
       and the height is capped at 52svh so the whole sheet still clears the
       keyboard on a short phone. The page is scroll-locked while it is open
       (D2Dialog.lock), which is the other half: an unlocked page lets the
       browser scroll a focused search box into view and drag the sheet down
       with it, which is exactly what "it goes below the keyboard" was. */
    .d2pick-sheet { position: fixed; top: 8svh; left: 50%; transform: translateX(-50%);
                    width: calc(100% - 32px); max-width: 380px;
                    height: 420px;        /* fixed: never resizes while you type */
                    max-height: 52svh;    /* ...except to stay on a short phone */
                    display: flex; flex-direction: column; overflow: hidden;
                    background: var(--d2-card); color: inherit; border-radius: 14px;
                    border: 1px solid var(--d2-line); box-shadow: 0 20px 50px rgba(0,0,0,0.35); }
    @supports not (height: 100svh) {
      .d2pick-sheet { top: 8vh; max-height: 52vh; }
    }
    /* 1024, not 768: this is the same line the BOARD switches on (the card
       layout below runs to 1023), and a 768-wide tablet still has a soft
       keyboard, which is the whole reason the phone rules exist. Splitting the
       two breakpoints left 768-1023 half phone and half desktop. */
    @media (min-width: 1024px) {
      /* A mouse has no keyboard to clear, so it sits in the middle. */
      .d2pick-sheet { top: 50%; transform: translate(-50%, -50%);
                      max-width: 30rem; height: 32rem; max-height: calc(100vh - 3rem); }
    }
    .d2pick-head { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem;
                   padding: 0.6rem 0.9rem; border-bottom: 1px solid var(--d2-line); font-size: 0.95rem; }
    .d2pick-x { min-width: 44px; min-height: 44px; border: 0; background: transparent; color: inherit;
                font-size: 1.4rem; line-height: 1; cursor: pointer; }
    .d2pick-search { margin: 0.6rem 0.9rem; padding: 0 0.7rem; min-height: 44px; font-size: 16px;
                     box-sizing: border-box; width: calc(100% - 1.8rem); border-radius: 0.6rem;
                     border: 1px solid var(--d2-line); background: var(--d2-card); color: inherit; }
    .d2pick-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; padding-bottom: 0.4rem; }
    
    .d2pick [data-role="list-view"] { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
    .d2pick [data-role="list-view"][hidden] { display: none; }
    .d2pick-group { position: sticky; top: 0; padding: 0.3rem 0.9rem; font-size: 0.64rem; font-weight: 800;
                    letter-spacing: 0.08em; text-transform: uppercase; color: var(--d2-muted); background: var(--d2-head); }
    .d2pick-row { display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; width: 100%;
                  min-height: 44px; padding: 0 0.9rem; border: 0; background: transparent; color: inherit;
                  font-size: 0.9rem; text-align: left; cursor: pointer; }
    .d2pick-row:hover { background: var(--d2-head); }
    .d2pick-row.is-current { font-weight: 800; color: var(--d2-accent); }
    /* The row is a flex line with space-between, so the mark needs its own
       sizing or the browser spreads logo, name and "at 7" evenly across the
       row. The name takes the slack instead, and truncates rather than
       shoving "at 7" off the edge on the longest school names. */
    .d2pick-row .tlogo { flex: 0 0 auto; }
    .d2pick-team { flex: 1 1 auto; min-width: 0; overflow: hidden;
                   text-overflow: ellipsis; white-space: nowrap; }
    .d2pick-at { font-size: 0.7rem; font-weight: 800; color: var(--d2-muted); white-space: nowrap; }
    /* Team dialog: a compact stat grid at the top of the sheet. */
    /* One row, all ten stats across, on every width. The sheet is 380px on a
       phone, so the type shrinks to fit rather than the grid wrapping - the
       labels may take two lines, which costs height once instead of stacking
       the whole grid. */
    /* One row, all ten stats across, on every width. FULL BLEED inside the
       sheet: side margins, side borders and the corner radius were eating
       ~24px of a 380px phone, and cell padding another ~32px, which is what
       forced the type down. Reclaim the space first, then the text can stay
       readable. Only the 1px grid lines are kept, because they are what makes
       it read as a table. */
    /* Five across, two rows. FULL BLEED inside the sheet: side margins, side
       borders and the corner radius were eating ~24px of a 380px phone, so the
       space is reclaimed first and the type stays readable rather than being
       shrunk to fit chrome. Only the 1px grid lines are kept, because they are
       what makes it read as a table. */
    /* flex:0 0 auto is load-bearing. The sheet is a fixed-height flex column,
       so a shrinkable grid gives up height to whatever else is added - adding
       the line below squeezed it from 94px to 67px and overflow:hidden ate the
       second row's VALUES while leaving its labels, so the card read
       "CONF BEST WORST AVG PPV" over nothing. Only the ballot list may shrink. */
    .t-stats { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr));
               flex: 0 0 auto;
               gap: 1px; margin: 0.5rem 0 0; background: var(--d2-line);
               border-top: 1px solid var(--d2-line); border-bottom: 1px solid var(--d2-line);
               overflow: hidden; text-align: center; }
    .t-stats div { background: var(--d2-card); padding: 0.3rem 0.2rem; min-width: 0; }
    .t-stats .k { display: block; font-size: 0.56rem; font-weight: 800; letter-spacing: 0.02em;
                  line-height: 1.2; text-transform: uppercase; color: var(--d2-muted); }
    .t-stats .v { display: block; margin-top: 0.08rem; font-size: 0.88rem; font-weight: 800;
                  font-variant-numeric: tabular-nums; white-space: nowrap;
                  overflow: hidden; text-overflow: ellipsis; }
    @media (min-width: 768px) {
      .t-stats div { padding: 0.45rem 0.3rem; }
      .t-stats .k { font-size: 0.6rem; }
      .t-stats .v { font-size: 1rem; }
    }
    .t-stats p { grid-column: 1 / -1; margin: 0; padding: 0.5rem 0.6rem;
                 font-size: 0.82rem; color: var(--d2-muted); background: var(--d2-card); }
    .d2pick-empty { padding: 1rem 0.9rem; font-size: 0.85rem; color: var(--d2-muted); }
    .d2pick-foot { padding: 0.6rem 0.9rem; border-top: 1px solid var(--d2-line); }
    .d2pick [data-role="confirm-view"] { display: flex; flex-direction: column; min-height: 0; overflow-y: auto; }
    .d2pick [data-role="confirm-view"][hidden] { display: none; }
    .d2pick-msg { margin: 0.9rem; font-size: 0.92rem; font-weight: 700; }
    .d2pick-actions { display: flex; flex-wrap: wrap; gap: 0.4rem; padding: 0 0.9rem 0.9rem; }
    .d2pick-action { min-height: 44px; padding: 0 0.9rem; border-radius: 0.6rem; border: 1px solid var(--d2-line);
                     background: transparent; color: inherit; font-weight: 800; font-size: 0.85rem; cursor: pointer; }
    .d2pick-action.is-primary { background: var(--d2-accent); border-color: var(--d2-accent); color: #fff; }
    
    /* ------------------------------------------------------------------
       THE CONTRACT, and it applies to EVERY dialog on this page - the team
       picker, the message box, the team card and the rules. Fixing them one
       at a time is how the message box ended up with a 52svh cap, hidden
       overflow and no scrollable body, so a long message was clipped with
       its buttons off the bottom and no way to reach them.

         1. The sheet is position:fixed and sized in svh, so a soft keyboard
            cannot move or resize it.
         2. The sheet NEVER grows past the viewport.
         3. The sheet never scrolls; its BODY does. Head and actions stay put.
       ------------------------------------------------------------------ */
    .d2pick-sheet.say-sheet,
    .d2pick-sheet.rules-sheet { height: auto; max-height: min(78svh, 34rem); }
    @supports not (height: 100svh) {
      .d2pick-sheet.say-sheet,
      .d2pick-sheet.rules-sheet { max-height: min(78vh, 34rem); }
    }
    /* The body of any dialog: it takes the leftover room and scrolls in it.
       min-height:0 is load-bearing - without it a flex child refuses to
       shrink below its content and the sheet blows past its own max-height. */
    .d2pick-msg, .rules-body, .d2pick-list {
        flex: 1 1 auto; min-height: 0; overflow-y: auto; -webkit-overflow-scrolling: touch; }
    /* ...and the parts that must never scroll away. */
    .d2pick-head, .d2pick-actions, .d2pick-foot { flex: 0 0 auto; }

    .btn { display: inline-flex; align-items: center; justify-content: center; min-height: 44px; padding: 0 1rem;
           border-radius: 0.6rem; font-weight: 800; font-size: 0.86rem; cursor: pointer; border: 0;
           background: var(--d2-accent); color: #fff; text-decoration: none; }
    .btn.ghost { background: transparent; border: 1px solid var(--d2-line); color: inherit; }
    .btn[disabled] { opacity: 0.55; cursor: not-allowed; }
    details.rules summary { min-height: 44px; display: flex; align-items: center; }
    /* The trigger is a control like the ones beside it. */
    .rules-btn { width: 100%; min-height: 44px; padding: 0 0.7rem; border-radius: 0.6rem;
                 border: 1px solid var(--d2-line); background: transparent; color: inherit;
                 font-size: 0.78rem; font-weight: 700; cursor: pointer; white-space: nowrap;
                 overflow: hidden; text-overflow: ellipsis; }
    .d2-tabs .rules-btn { border: 0; color: var(--d2-muted); font-size: 0.85rem; font-weight: 800;
                          border-radius: 0.55rem; }
    .d2-tabs .rules-btn:hover { background: var(--d2-head); color: inherit; }
    /* The sheet is taller than the picker's: this is prose, not a list of
       teams, and it scrolls rather than being cut off. */
    .rules-sheet { height: auto; max-height: min(78svh, 34rem); }
    .rules-body { padding: 0.2rem 0 0.6rem; }
    /* Two columns of label + answer, so the eye lands on the label first and
       the answers stop running together into a blurb. */
    .rules-body dl { margin: 0; display: grid; grid-template-columns: auto 1fr;
                     gap: 0 0.8rem; align-items: baseline; }
    .rules-body dt { font-size: 0.6rem; font-weight: 800; letter-spacing: 0.06em;
                     text-transform: uppercase; color: var(--d2-muted); white-space: nowrap;
                     padding: 0.55rem 0 0.55rem 0.9rem; border-top: 1px solid var(--d2-line); }
    .rules-body dd { margin: 0; font-size: 0.82rem; line-height: 1.45;
                     padding: 0.55rem 0.9rem 0.55rem 0; border-top: 1px solid var(--d2-line); }
    .rules-body dt:first-of-type, .rules-body dt:first-of-type + dd { border-top: 0; }
    @media (min-width: 768px) {
      .rules-body dt { font-size: 0.64rem; }
      .rules-body dd { font-size: 0.88rem; }
    }

    /* Left over from when this was a <details> in the controls row. */
    .d2-controls details.rules { margin: 0; align-self: center; }
    .rules-slot-phone { min-width: 0; }
    /* In the tab strip it reads as one more tab until it is opened. */
    .d2-tabs details.rules { margin: 0; }
    .d2-tabs details.rules > summary { justify-content: center; min-height: 44px; padding: 0 0.7rem;
        border-radius: 0.55rem; font-size: 0.85rem; font-weight: 800; white-space: nowrap;
        color: var(--d2-muted); }
    .d2-tabs details.rules > summary:hover { background: var(--d2-head); color: inherit; }
    .d2-tabs details.rules[open] { background: var(--d2-head); border-radius: 0.55rem; }
    .d2-tabs details.rules[open] dl { padding: 0 0.7rem 0.6rem; text-align: left; }
    .d2-controls details.rules > summary { justify-content: center; min-height: 44px;
        padding: 0 0.7rem; border: 1px solid var(--d2-line); border-radius: 0.6rem;
        font-size: 0.82rem; font-weight: 700; white-space: nowrap; }
    /* Open, it must not be trapped in a grid cell - span the row and lay the
       definitions out underneath. */
    .d2-controls details.rules[open] { grid-column: 1 / -1; }
    .h2h-list { font-size: 0.8rem; line-height: 1.55; color: var(--d2-muted); list-style: none; }
    .h2h-list li { padding: 0.4rem 0; border-top: 1px solid var(--d2-line); }
    .h2h-list li:first-child { border-top: 0; }
    /* The winner is the fact being asserted; it should not be grey. */
    .h2h-list strong { color: var(--d2-ink); font-weight: 800; }
    /* Sits in the same row as the ghost buttons and has to read as one of them. */
    #b-from { min-height: 44px; padding: 0 0.7rem; font-size: 0.86rem; font-weight: 800; box-sizing: border-box;
              border-radius: 0.6rem; border: 1px solid var(--d2-line); background: transparent; color: inherit;
              max-width: 100%; }
    .builder-out { width: 100%; min-height: 7.5rem; margin-top: 0.6rem; padding: 0.55rem;
                   font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: 0.76rem;
                   border-radius: 0.5rem; border: 1px solid var(--d2-line); background: var(--d2-card); color: inherit; }
    .note-input { width: 100%; box-sizing: border-box; min-height: 44px; margin-top: 0.5rem; padding: 0 0.7rem; font-size: 16px;
                  font-size: 0.88rem; border-radius: 0.6rem; border: 1px solid var(--d2-line);
                  background: var(--d2-card); color: inherit; }
    .ballot-why { margin: 0.5rem 0.9rem 0; padding: 0.5rem 0.6rem; border-left: 3px solid var(--d2-accent);
                  background: var(--d2-head); border-radius: 0.3rem; font-size: 0.8rem; line-height: 1.45; }
    .ballot-why b { display: block; font-size: 0.64rem; letter-spacing: 0.08em; text-transform: uppercase;
                    color: var(--d2-muted); margin-bottom: 0.1rem; }
    .ask-row { display: flex; flex-wrap: wrap; align-items: center; gap: 0.5rem; margin-top: 0.6rem;
               padding: 0.6rem 0.7rem; border: 1px solid var(--d2-accent); border-radius: 0.6rem;
               background: var(--d2-head); font-size: 0.82rem; font-weight: 700; }
    .ask-row[hidden] { display: none; }
    .ask-btns { display: flex; gap: 0.4rem; margin-left: auto; }
    .submit-row { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0.4rem; margin-top: 0.6rem; }
    @media (min-width: 640px) { .submit-row { grid-template-columns: minmax(0, 1fr) auto; align-items: center; } }
    .submit-row > * { min-width: 0; }
    /* 16px, NOT 0.88rem. iOS Safari zooms the whole page when a control it is
       focusing has text under 16px, and the page does not zoom back out - which
       is the same fault that made every dialog on this page feel broken. The
       note box above already sets 16px for exactly this reason; this one was
       missed. Do not shrink it to make the row look tighter. */
    .submit-row input { min-height: 44px; box-sizing: border-box; width: 100%; padding: 0 0.7rem; font-size: 16px; border-radius: 0.6rem;
                        border: 1px solid var(--d2-line); background: var(--d2-card); color: inherit; }

    /* ---- the name box suggests forum accounts as you type ---------------- */
    /* Anchored to the field rather than floated over the page: this sits above
       an open keyboard on a phone, and anything position:fixed here would fight
       the visual viewport the same way the old dialog lock did. */
    .name-field { position: relative; }
    .name-sug { list-style: none; margin: 0.3rem 0 0; padding: 0; display: none;
                border: 1px solid var(--d2-line); border-radius: 0.6rem; overflow: hidden;
                background: var(--d2-card); }
    .name-sug.on { display: block; }
    .name-sug li { margin: 0; }
    .name-sug button { display: block; width: 100%; text-align: left; min-height: 44px;
                       padding: 0 0.7rem; font-size: 0.95rem; font-weight: 600; cursor: pointer;
                       background: none; border: 0; border-top: 1px solid var(--d2-line); color: inherit; }
    .name-sug li:first-child button { border-top: 0; }
    .name-sug button:hover, .name-sug button:focus { background: rgba(37, 99, 235, 0.1); }
    .name-known { margin-top: 0.3rem; font-size: 0.78rem; font-weight: 700; color: #15803d; display: none; }
    .name-known.on { display: block; }
    .name-account { margin-top: 0.2rem; font-size: 0.78rem; opacity: 0.8; overflow-wrap: anywhere; }

    .d2-cta { border-radius: var(--d2-radius); padding: 1rem; text-align: center;
              background: linear-gradient(135deg, #1d4ed8, #7c3aed); color: #fff; }
    .d2-cta h3 { margin: 0; font-size: 1rem; font-weight: 900; }
    .d2-cta p { margin: 0.3rem 0 0.7rem; font-size: 0.84rem; color: #e0e7ff; }
    .d2-cta .btn { background: #fff; color: #1d4ed8; }

    /* D2 Pick'em CTA under the hero (d2pe-mvp-008): one full-width link, >= 56px.
       It sat flush on the week pills - margin above, NONE below - so at 1280
       the two read as one block and at 390 the pills crowded up under it. The
       hero's own 1.25rem bottom margin spaces it from above; it carries the
       same 1.25rem below, so it never touches the week selector at any width. */
    a.d2-pe-cta { display: flex; flex-direction: column; justify-content: center; gap: 0.15rem; width: 100%;
                  min-height: 56px; margin: 0 0 1.25rem; padding: 0.7rem 1rem; border-radius: var(--d2-radius);
                  background: #1d4ed8; color: #fff; text-decoration: none; text-align: center; }
    a.d2-pe-cta:focus-visible { outline: 3px solid #f59e0b; outline-offset: 2px; }
    a.d2-pe-cta .t { font-size: 1.05rem; font-weight: 900; }
    a.d2-pe-cta .s { font-size: 0.85rem; color: #e0e7ff; }
    a.d2-pe-cta .chip { font-size: 0.75rem; font-weight: 700; color: #fde68a; }

    /* "Try D2 Pick'em" once a ballot is in (d2-pickem-2026-10-29 item 3): the
       card under the submit row (#b-pickem-cta) and the same block inside the
       submit-result dialog (#say-cta). Explicit CSS, not utilities - the
       Tailwind build is purged. The link is a full-width 44px block on a
       phone, so it can never push the row wider than 375px. */
    .pickem-cta, .say-cta { min-width: 0; border: 1px solid var(--d2-accent); border-radius: 0.7rem;
                            background: var(--d2-head); padding: 0.7rem 0.8rem; overflow-wrap: anywhere; }
    .pickem-cta { margin-top: 0.6rem; }
    .say-cta { flex: 0 0 auto; margin: 0 0.9rem 0.9rem; }
    .pickem-cta[hidden], .say-cta[hidden] { display: none; }
    .pickem-cta p, .say-cta p { margin: 0; }
    .pickem-cta .t, .say-cta .t { font-size: 0.95rem; font-weight: 900; }
    .pickem-cta .b, .say-cta .b { margin-top: 0.2rem; font-size: 0.84rem; line-height: 1.45; }
    .pickem-cta .soon, .say-cta .soon { margin-top: 0.2rem; font-size: 0.8rem; font-weight: 700; color: var(--d2-muted); }
    .pickem-cta a.go, .say-cta a.go { display: flex; align-items: center; justify-content: center; width: 100%;
                                      min-height: 44px; margin-top: 0.55rem; padding: 0 1rem; border-radius: 0.6rem;
                                      background: var(--d2-accent); color: #fff; font-weight: 800; font-size: 0.88rem;
                                      text-decoration: none; text-align: center; }
    .pickem-cta a.go:focus-visible, .say-cta a.go:focus-visible { outline: 3px solid #f59e0b; outline-offset: 2px; }
    html.dark .pickem-cta a.go, html.dark .say-cta a.go { color: #0f172a; }
    @media (min-width: 640px) { .pickem-cta a.go, .say-cta a.go { display: inline-flex; width: auto; } }

    .rules { margin: 0.75rem 0 0; border: 1px solid var(--d2-line);
             border-radius: 0.7rem; background: var(--d2-card); }
    /* The open marker used to be content:" 2" - a minus sign that lost its
       encoding somewhere and rendered as a control character plus a literal 2.
       A rotating chevron cannot be mangled by a character set. */
    .rules > summary { list-style: none; cursor: pointer; padding: 0.6rem 0.9rem; font-size: 0.82rem;
                       font-weight: 800; color: var(--d2-accent);
                       display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; }
    .rules > summary::-webkit-details-marker { display: none; }
    .rules > summary::after { content: ""; flex: 0 0 auto; width: 0.5rem; height: 0.5rem;
                              border-right: 2px solid currentColor; border-bottom: 2px solid currentColor;
                              transform: rotate(45deg); transition: transform 0.15s ease; margin-right: 0.15rem; }
    .rules[open] > summary::after { transform: rotate(-135deg); }
    .rules dl { margin: 0; padding: 0 0.9rem 0.8rem; font-size: 0.78rem; line-height: 1.5; color: var(--d2-muted); }
    .rules dt { font-weight: 800; color: inherit; margin-top: 0.5rem; }
    .rules dd { margin: 0.1rem 0 0; }
    /* Anything that is not the <dl> - a note, a list, a table - still needs the
       gutter the dl was carrying, or it sits flush against the border. */
    .rules > p, .rules > ul { padding-left: 0.9rem; padding-right: 0.9rem; }
    .rules > p { margin: 0 0 0.5rem; }
    .rules > ul { margin: 0 0 0.8rem; }
    .rules > table { border-top: 1px solid var(--d2-line); }
    .rules-lede { font-size: 0.78rem; line-height: 1.5; color: var(--d2-muted); max-width: 46rem; }
    .others-list { display: flex; flex-wrap: wrap; gap: 0.3rem 0.5rem; padding: 0 0.9rem 0.8rem; }
    .other-team { font-size: 0.8rem; font-weight: 700; white-space: nowrap; }

    .d2-credit { text-align: center; font-size: 0.76rem; color: var(--d2-muted); margin-top: 1rem; line-height: 1.5; }
    .d2-credit a { color: var(--d2-accent); font-weight: 700; }
