  /* ---------- typefaces ---------- */
  /* Self-hosted from public/fonts. See scripts/patch-card-fonts.mjs. */
  @font-face{font-family:'Saira Condensed Text';font-style:normal;font-weight:400;font-display:swap;
             src:url(/fonts/saira-condensed-latin-400-normal.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
  @font-face{font-family:'Saira Condensed Text';font-style:normal;font-weight:400;font-display:swap;
             src:url(/fonts/saira-condensed-latin-ext-400-normal.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
  @font-face{font-family:'Saira Condensed Text';font-style:normal;font-weight:500;font-display:swap;
             src:url(/fonts/saira-condensed-latin-500-normal.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
  @font-face{font-family:'Saira Condensed Text';font-style:normal;font-weight:500;font-display:swap;
             src:url(/fonts/saira-condensed-latin-ext-500-normal.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
  @font-face{font-family:'Saira Condensed Text';font-style:normal;font-weight:600;font-display:swap;
             src:url(/fonts/saira-condensed-latin-600-normal.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
  @font-face{font-family:'Saira Condensed Text';font-style:normal;font-weight:600;font-display:swap;
             src:url(/fonts/saira-condensed-latin-ext-600-normal.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
  @font-face{font-family:'Saira Condensed';font-style:normal;font-weight:600;font-display:swap;
             src:url(/fonts/saira-condensed-latin-600-normal.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
  @font-face{font-family:'Saira Condensed';font-style:normal;font-weight:600;font-display:swap;
             src:url(/fonts/saira-condensed-latin-ext-600-normal.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}
  @font-face{font-family:'Saira Condensed';font-style:normal;font-weight:700;font-display:swap;
             src:url(/fonts/saira-condensed-latin-700-normal.woff2) format('woff2');unicode-range:U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD}
  @font-face{font-family:'Saira Condensed';font-style:normal;font-weight:700;font-display:swap;
             src:url(/fonts/saira-condensed-latin-ext-700-normal.woff2) format('woff2');unicode-range:U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF}

  /* One typeface for the whole page: Saira Condensed. It came for the
     headings first (William, 8 October 2026: in Barlow Condensed, which it
     replaced, an M and an H looked too much alike; HDSC and MDSC differ by
     that one letter), then for everything: "I want to start using the new
     font on the website every where, including in tables, charts, cards".
     Until then text was Barlow.

     Two family names over the same files, on purpose. Text asks for "bold" in
     a hundred places (a <b>, a <th>, font-weight 650 or 700), and Barlow's
     heaviest file here was the 600, so all of those drew semibold. Given one
     family with a 700 in it, every one of them would turn a weight heavier.
     So text has its own name with Barlow's three weights (400, 500, 600), and
     the display name keeps its two (600, 700). A file both names is fetched
     once.

     Its own line is tall: 1.574 of its size, where Barlow's was 1.2. So
     anything set in it states its line-height. The page's text inherits one;
     a button or a field does not (a browser gives it the font's own line),
     which is why the rule for those, below, says 1.2: the line they had.

     It has no tabular figures: a 1 is narrower than an 8 whatever is asked,
     so the numbers of a column no longer stand digit under digit, as they
     did in Barlow. font-variant-numeric is left where it was written; it
     does nothing in this face. */
  :root{
    --font-display:'Saira Condensed','Arial Narrow',sans-serif;
    --font-body:'Saira Condensed Text','Arial Narrow',sans-serif;
  }
  /* One palette. The page is dark and only dark: a card exported today looks
     like a card exported tomorrow, which is the whole point of a format you
     post under your own name. Everything below paints from these.

     The page ground is #202124 — a neutral grey, no blue in it — and the rest
     of the neutrals are stepped off that: surfaces lift away from the page so
     a card reads as a card, the identity band drops below it so it still
     anchors the top of a card. The one colour that marks things is the
     brand orange below; the blue accent that did it before went with
     redesign step 17, when the card's last uses of it turned orange. */
  :root{
    --ink:#e8eaed; --ink2:#c8ccd0; --muted:#a8aeb4; --faint:#8f959b;
    --line:#3c3f43; --bg:#202124;
    --surface:#2a2b2e;      /* cards, rail, panels */
    --surface2:#303134;     /* stat strips, tinted rows */
    --surface3:#2d2e31;     /* comp tiles, notes */
    --hover:#35363a; --sel:#33393f; --sel2:#2f3236;
    --track:#3a3b3f; --thead:#2a2b2e; --thead-on:#343a41; --tabbg:#2a2b2e;
    --avatar:#3c3f43; --nobox:#303134;
    --band:#17181a; --onband:#ffffff; --onband-dim:rgba(255,255,255,.68);
    --good:#5fbd88;
    /* The brand orange (redesign, 5 October 2026). --brand is for fills: the
       strip, the page you are on in the menu, the one main button. Text and
       icons on it are --on-brand, never white, which is too faint on orange.
       --brand-text is the brighter orange for orange TEXT on the grays:
       --brand itself is 4.3:1 on a panel, under the 4.5:1 a reader needs.
       Never on a percentile bar, whose 25th percentile is a dull orange. */
    --brand:#F26B21; --brand-text:#FF8A3D; --on-brand:#1c1305;
    /* The glow round a control that has the keyboard (styles/21-controls.css). */
    --brand-ring:rgba(255,138,61,.3);
    /* The card's own outline, separate from --line: it has to read against
       the page in an exported PNG, where --line is nearly invisible. */
    --cardline:rgba(255,255,255,.62);
    /* Every container's edge. --line stays the quiet hairline that separates
       rows and sections INSIDE a box; this one is what makes the box read as
       a box against the page. */
    --box:rgba(255,255,255,.40);
    --warn-bg:#2e2513; --warn-line:#4d3f1f; --warn-ink:#e2bd78;
    color-scheme: dark;
  }
  *{box-sizing:border-box}
  /* .wrap sets display:flex, which outranks the browser's own [hidden] rule —
     without this the hidden tab renders anyway. */
  [hidden]{display:none!important}
  /* Stops iOS inflating text in the tall, narrow columns it thinks it is
     helping with. */
  html{-webkit-text-size-adjust:100%}
  body{margin:0;background:var(--bg);color:var(--ink);
       font:400 14px/1.45 var(--font-body)}
  button,input,select,textarea,optgroup,option{font-family:inherit;line-height:1.2}
  /* Headings, stat tiles, big numbers and table headers. 700 where it
     carries a name or a figure, 600 where it is a small label. */
  h1,h2,h3,
  .line .n,.c-line .n,
  .lbtable thead th,.ctscroll thead th{font-family:var(--font-display);letter-spacing:-0.01em}
  h1,.line .n,.c-line .n{font-weight:700}
  h2,h3,.lbtable thead th,.ctscroll thead th{font-weight:600;letter-spacing:.07em}
  /* Figures line up in every column of them, so a table does not shuffle
     sideways as its numbers change. */
  .lbtable,.ctscroll,.line,.c-line,.m,.c-m,.card,.ccard,.pbox,.sctip{font-variant-numeric:tabular-nums}

  .wrap{display:flex;gap:22px;padding:20px;align-items:flex-start;max-width:1340px;margin:0 auto}
  /* The card tab holds a card AND two charts, so it is allowed to be wider
     than the rest. */
  #mode-card{max-width:1560px}
  @media(max-width:860px){.wrap{flex-direction:column;padding:12px}}

  /* The rail's own header, which is a button only on a phone. */
  .railtop{display:none}

  /* ---------- left rail ---------- */
  /* 400 rather than 290: it was first sized for a row of three buttons at
     the foot, one of them the bar-colour switch that has since gone
     (patch-card-bars-red-green.mjs). The width stays -- the tab row is lined
     up with it and the controls above use the room. All rails share one
     width so the tabs don't shift sideways as you move between them. */
  .rail{width:400px;flex:0 0 400px;background:var(--surface);border:1px solid var(--box);
        border-radius:10px;padding:16px;position:sticky;top:20px}
  /* In a squeezed window the card needs the room more than the buttons need
     to share a line, so the rail gives it back and they wrap. */
  @media(max-width:1180px){
    .rail{width:320px;flex:0 0 320px}
    .acts{width:320px;flex:0 0 320px}
  }

  /* The foot of the settings box: what this tab can do with what you have
     picked above it. A sibling of .railbody rather than a child, so that on a
     phone \u2014 where the body folds away behind a tap \u2014 the actions stay out
     where you can reach them. */
  .railacts{display:flex;flex-wrap:wrap;gap:7px;margin-top:16px;padding-top:14px;
            border-top:1px solid var(--line)}
  .railacts button{flex:0 0 auto}
  #globalActs{display:contents}

  /* Icon, hairline, word \u2014 so the three export buttons read as one family
     and the word is the only part that changes between them. */
  .ico{width:13px;height:13px;flex:0 0 13px;fill:none;stroke:currentColor;
       stroke-width:1.6;stroke-linecap:round;stroke-linejoin:round}
  .sep{width:1px;height:13px;background:currentColor;opacity:.32;flex:0 0 1px}
  button .lbl{white-space:nowrap}
  @media(max-width:860px){.rail{width:100%;flex:1 1 auto;position:static}}
  /* Every heading after the first opens a new group, whatever precedes it —
     a select, a button, a row of chips. */
  .rail h2{margin:20px 0 10px;font-size:12px;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
  .rail h2:first-child{margin-top:0}
  /* A heading straight over a Regular Season / Playoffs switch: the switch's
     own pull-up is for when it opens the rail, not when it follows a title. */
  .rail h2 + .modeseg{margin-top:0}
  /* The scatter's and the radar's controls each open with a heading that is
     the first child of its box, which cost it the gap above; it follows the
     Scatter / Radar switch, so it needs it like any other. */
  #scatterOnly > h2:first-child, #radarOnly > h2:first-child{margin-top:20px}
  #scScale{margin-bottom:10px}
  .rail select,.rail input[type=text]{width:100%;padding:8px 10px;border:1px solid var(--box);
          border-radius:7px;font-size:14px;background:var(--surface);color:var(--ink);
          margin-bottom:12px;outline:none}
  .rail .row{display:flex;gap:7px;margin-bottom:12px}
  .rail .row input[type=text]{margin-bottom:0}
  .rail .row button{flex:0 0 auto}
  .rail button.wide{width:100%;margin-top:2px;margin-bottom:4px}
  .dim{opacity:.45}

  /* ---------- card ---------- */
  .stage{flex:1;min-width:0}

  /* Where an export is laid out: an iframe of its own, off to one side of the
     page. Not display:none and not visibility:hidden — both of those make an
     element unmeasurable, and the whole point is to measure it. */
  .exportstage{position:fixed;top:0;left:0;border:0;z-index:-1;opacity:0;
               pointer-events:none}

  /* ---------- the card and its two charts ----------
     One box, not three: the header runs the whole width of it and everything
     under the header splits into the card's own content on the left and the
     charts down the right. The wrapper stays because it is what the export
     points at. */
  .cardrow{display:block}
  /* Everything below the header. Stretch, so the rule between the two columns
     runs the full height of the card rather than stopping under the charts. */
  .cbody{display:flex;align-items:stretch}
  .cmain{flex:1 1 auto;min-width:0}
  .cside{flex:0 0 320px;min-width:0;padding:13px 15px 12px;
         border-left:1px solid var(--cardline);display:flex}
  /* Centred in the space the column has, however tall the bars beside it make
     that column: the leftover is split between the top and the bottom rather
     than all falling underneath. */
  .ccol{display:flex;flex-direction:column;justify-content:center;
        flex:1 1 auto;min-width:0}
  /* The two plots: stacked down the column beside the card, side by side once
     that column goes full width underneath it. */
  .ccplots{display:flex;flex-direction:column;gap:12px}
  .ccplots > .ccplot + .ccplot{border-top:1px solid var(--line);padding-top:12px}
  .ccplot{position:relative;min-width:0;flex:1 1 0}
  .ccplot canvas{width:100%;display:block}
  /* Centred under the trajectory it belongs to, not flush with the box. */
  .cclegend{display:flex;flex-wrap:wrap;justify-content:center;gap:3px 10px;
            margin-top:9px;font-size:11.5px;color:var(--muted)}
  .cclegend .who{display:flex;align-items:center;gap:6px;flex:0 0 auto;white-space:nowrap}
  .cclegend .dot{width:9px;height:9px;border-radius:50%;flex:0 0 9px}

  /* Under 1500px the card needs the whole width, so the charts go
     beneath it — side by side while there is room for two, stacked when
     there isn't. Nothing is hidden at any width. 1500, not 1200: between the
     two the card kept as little as ~480px beside the charts, its percentile
     bars vanished and the fourth comparable lay over the charts
     (scripts/patch-card-mid-width.mjs has the arithmetic). */
  @media(max-width:1500px){
    /* Not enough width for a column beside the card, so it becomes a band
       across the bottom of the same box — still inside the card, still in
       the exported image. Nothing to centre vertically once it is a band. */
    .cbody{flex-direction:column}
    .cside{flex:1 1 auto;width:100%;border-left:0;border-top:1px solid var(--cardline)}
    .ccol{justify-content:flex-start}
    .ccplots{flex-direction:row;gap:18px}
    .ccplots > .ccplot + .ccplot{border-top:0;padding-top:0;
                                 border-left:1px solid var(--line);padding-left:18px}
  }
  @media(max-width:760px){
    .ccplots{flex-direction:column;gap:13px}
    .ccplots > .ccplot + .ccplot{border-left:0;padding-left:0;
                                 border-top:1px solid var(--line);padding-top:13px}
  }
  .bar{display:flex;gap:8px;margin-bottom:12px;align-items:center;flex-wrap:wrap}
  button{padding:8px 15px;border:1px solid var(--box);background:var(--surface);border-radius:7px;
         cursor:pointer;font-size:13px;color:var(--ink)}
  button:hover{border-color:var(--faint);color:#fff}
  button:disabled{opacity:.45;cursor:default}

  .card{background:var(--surface);border:1px solid var(--cardline);border-radius:12px;overflow:hidden}
  .hdr{background:var(--band);color:var(--onband);padding:13px 20px;display:flex;gap:14px;align-items:center}
  .shot{width:62px;height:62px;border-radius:8px;object-fit:cover;background:#fff;flex:0 0 62px}
  .who{flex:1;min-width:0}
  .who h1{margin:0;font-size:21px;line-height:1.15;font-weight:650}
  .who .sub{margin-top:3px;font-size:12px;color:var(--onband-dim)}
  .tag{display:inline-block;margin-left:7px;padding:1px 7px;border-radius:20px;
       background:var(--brand);color:var(--on-brand);font-size:10px;letter-spacing:.05em;vertical-align:1px}
  .crest{width:62px;height:62px;flex:0 0 62px;border-radius:8px;background:#fff;
         padding:6px;object-fit:contain}

  .line{display:flex;border-bottom:1px solid var(--line);background:var(--surface2);flex-wrap:wrap}
  .line > div{flex:1;padding:9px 8px;text-align:center;border-right:1px solid var(--line);min-width:70px}
  .line > div:last-child{border-right:0}
  .line .n{font-size:22px;font-weight:650;line-height:1.15}
  .line .k{font-size:11px;color:var(--muted);letter-spacing:.07em;text-transform:uppercase;margin-top:3px;line-height:1.2}

  .body{padding:13px 20px 15px}
  .bio{display:flex;flex-wrap:wrap;gap:0 22px;font-size:13.5px;color:var(--muted);
       padding-bottom:9px;border-bottom:1px solid var(--line);margin-bottom:11px}
  .bio b{color:var(--ink);font-weight:600}
  /* The season a player is actually draft-eligible is the one worth spotting
     from across the page, so that value alone gets the site's orange (it
     was blue until redesign step 17). */
  .bio b.dy{color:var(--brand-text)}

  .comps{margin:0 0 12px}
  .comps-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:7px}
  .comps h3{margin:0;font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
  /* minmax(0,1fr), not 1fr: a plain 1fr never shrinks below its content, so
     a tight row pushed the last tile out of the card's column. */
  .compgrid{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}
  @media(max-width:560px){.compgrid{grid-template-columns:repeat(2,minmax(0,1fr))}}
  .comp{border:1px solid var(--box);border-radius:7px;padding:6px 9px;background:var(--surface3);
        display:flex;align-items:center;gap:8px;cursor:pointer}
  /* Each tile is a link to that season's card. The hover state changes border,
     background and name colour only — no transform — because html2canvas
     renders whatever is on screen, and a tile that lifted under the cursor
     would lift in the exported PNG too. */
  .comp:hover{border-color:var(--brand-text);background:var(--sel2)}
  .comp:hover .nm{color:var(--brand-text)}
  .comp:focus{outline:none;border-color:var(--brand-text);box-shadow:0 0 0 2px var(--brand-ring)}
  /* 34px fits inside the tile's existing two-line height, so the photos cost
     no extra card height. */
  .comp .av,.comp .ini{width:38px;height:38px;border-radius:50%;flex:0 0 38px;
        object-fit:cover;background:var(--avatar);display:block}
  .comp .ini{display:flex;align-items:center;justify-content:center;
        font-size:12.5px;font-weight:650;color:var(--faint)}
  .comp .who2{min-width:0;flex:1}
  .comp .nm{font-size:13px;font-weight:600;line-height:1.2;color:var(--ink);overflow-wrap:anywhere}
  .comp .sn{font-size:12px;color:var(--muted);margin-top:1px}
  .comp .sim{font-size:12.5px;font-weight:650;color:var(--good);white-space:nowrap;flex:0 0 auto}
  /* Says why the section is empty, instead of leaving you to guess. */
  .comps-head .csit{font-weight:400;color:var(--muted);text-transform:none;letter-spacing:0}
  .compnote{border:1px dashed var(--box);border-radius:7px;padding:9px 12px;
            background:var(--surface3);font-size:13.5px;color:var(--muted)}

  /* Two balanced columns; a section never splits across the gap. */
  .metrics{column-count:2;column-gap:30px}
  @media(max-width:700px){.metrics{column-count:1}}
  /* In a DOWNLOADED card, three (6 October 2026): the card had grown a third
     taller since September as stats were added, and its picture read as
     narrow. Only the copy that is photographed carries data-export (see
     exportStage_ in scripts/05-export.js); the page's card keeps two. The
     copy is laid out EXPORT_EL.card wide, which is what gives a third column
     room for its bars. */
  [data-export="cardRow"] .metrics{column-count:3}
  .sec{margin:0 0 11px;break-inside:avoid;-webkit-column-break-inside:avoid;page-break-inside:avoid}
  .sec h3{margin:0 0 6px;font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
  .m{display:grid;grid-template-columns:150px 64px 1fr 34px;gap:8px;align-items:center;padding:3px 0}
  @media(max-width:520px){.m{grid-template-columns:118px 56px 1fr 30px;gap:6px}}
  .m .lab{color:var(--ink2);font-size:14px}
  .m .val{text-align:right;font-weight:600;font-size:14px;font-variant-numeric:tabular-nums}
  .track{height:10px;background:var(--track);border-radius:5px;overflow:hidden}
  .fill{height:100%;border-radius:5px}
  .pn{text-align:right;font-size:11px;color:var(--muted);font-variant-numeric:tabular-nums}
  /* A card's ranks a size up with its rows (15 October 2026); Compare's keep 11px. */
  .m .pn{font-size:12.5px}

  /* Full width, under both columns, with the card's own side padding rather
     than the body's — it is a footer for the card, not a last line of the
     left-hand column. */
  .note{font-size:12.5px;color:var(--muted);border-top:1px solid var(--cardline);
        padding:9px 20px 13px}
  /* Not a warning box: it is a fact about the card, not a fault with it. */
  .plfnote{font-size:13px;color:var(--muted);margin:-4px 0 11px;
           padding-bottom:9px;border-bottom:1px solid var(--line)}
  .plfnote b{color:var(--ink2);font-weight:600}
  .warn{background:var(--warn-bg);border:1px solid var(--warn-line);color:var(--warn-ink);padding:8px 11px;
        border-radius:7px;font-size:13.5px;margin-bottom:11px}


  .empty{padding:50px 22px;text-align:center;color:var(--muted)}

  /* Every dead end in the app \u2014 broken, empty, or not built yet \u2014 is this
     one block, so a visitor learns to read it once. A heading that says which
     of the three it is, a sentence they can act on, and a button only when
     there is genuinely something to press. */
  .dead{padding:44px 22px;text-align:center;max-width:46ch;margin:0 auto}
  .dead h4{margin:0 0 7px;font-size:14px;font-weight:650;color:var(--ink2);
           letter-spacing:.01em}
  .dead p{margin:0;font-size:13px;line-height:1.55;color:var(--muted)}
  .dead .act{margin-top:15px;display:flex;gap:8px;justify-content:center;flex-wrap:wrap}
  .dead details{margin-top:16px;text-align:left}
  .dead summary{font-size:11px;color:var(--faint);cursor:pointer}
  .dead pre{margin:7px 0 0;padding:9px 11px;background:var(--surface2);
            border:1px solid var(--line);border-radius:6px;font-size:11px;
            color:var(--ink2);white-space:pre-wrap;word-break:break-word}
  /* Inline versions, for the one-line meta slots that have no room for a block. */
  .deadline{color:var(--muted)}
  .deadline b{color:var(--ink2);font-weight:600}

  /* ---------- action rows ----------
     This file was "header row": the row of tab buttons across the top of the
     page. The site header replaced that row on 5 October 2026 and its styles
     are in 14-site-header.css. What stays here is what was beside it. */
  .hbtns{flex:0 0 auto;align-self:flex-end;display:flex;gap:8px}
  @media(max-width:860px){
    .hbtns{align-self:flex-start}
  }
  /* Bounded on all four sides: they sit above the card rather than against
     it, so an open bottom edge would just look unfinished. */
  .railacts button,.lbacts button{display:inline-flex;align-items:center;gap:8px}
  .lbacts{display:flex;gap:7px;align-items:flex-end}

  .sr{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}

  /* A league heading in the season picker. Browsers default to italic grey;
     this is the same quiet capital the rest of the rail uses. */
  #season optgroup{font-style:normal;font-weight:700;color:var(--faint);
                   font-size:11px;letter-spacing:.06em;text-transform:uppercase}
  #season option{font-style:normal;font-weight:400;color:var(--ink);
                 font-size:13px;letter-spacing:0;text-transform:none}
  /* ---------- leaderboard ---------- */
  .lb-wrap .stage{width:100%}
  .lbbar{display:flex;gap:10px;flex-wrap:wrap;align-items:flex-end;background:var(--surface);
         border:1px solid var(--box);border-radius:10px;padding:12px 14px;margin-bottom:10px}
  .lbbar label{display:flex;flex-direction:column;gap:5px;font-size:11px;
               letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
  .lbbar label.grow{flex:1;min-width:170px}
  .lbbar select,.lbbar input{padding:7px 9px;border:1px solid var(--box);border-radius:7px;
        font-size:13.5px;background:var(--surface);color:var(--ink);text-transform:none;letter-spacing:0}
  .lbbar button{margin-left:auto;align-self:flex-end}
  .lbmeta{font-size:11.5px;color:var(--muted);margin-bottom:8px}
  .lbtable td.num.ctr{text-align:center}
  /* Sits over the plot rather than under it, so an empty grid is never left
     on screen looking like a chart with no players in the league. */
  .scplot{position:relative}
  .scdead{position:absolute;inset:0;display:flex;align-items:center;
          justify-content:center;background:var(--surface);border-radius:8px}

  .lbscroll{overflow:auto;max-height:70vh;border:1px solid var(--box);
            border-radius:10px;background:var(--surface)}
  .lbtable{border-collapse:separate;border-spacing:0;font-size:12px;width:max-content;min-width:100%}
  .lbtable th,.lbtable td{padding:0;white-space:nowrap}

  /* Sticky in both directions: the stat names stay put while you scroll down,
     and the player stays put while you scroll 19 metrics to the right. */
  .lbtable thead th{position:sticky;top:0;z-index:3;background:var(--thead);
        border-bottom:1px solid var(--line);color:var(--muted);
        font-size:10px;letter-spacing:.06em;text-transform:uppercase;font-weight:600;
        padding:7px 8px;cursor:pointer;user-select:none}
  /* A stat's code is shown as written: "xG/GP", not "XG/GP". Every other code
     is capitals already, so only the xG columns look any different. */
  thead th.mcode{text-transform:none}
  .lbtable thead th .ar{font-size:8px;margin-left:3px}
  .lbtable td{border-bottom:1px solid var(--line);padding:5px 8px;color:var(--ink)}
  .lbtable tbody tr:hover td{background:var(--hover)}

  .lbtable .stick{position:sticky;left:0;z-index:2;background:var(--surface)}
  .lbtable thead .stick{z-index:4;background:var(--thead)}
  .lbtable tbody tr:hover .stick{background:var(--hover)}
  .lbtable .stick2{position:sticky;left:44px;z-index:2;background:var(--surface);
        box-shadow:1px 0 0 var(--line)}
  .lbtable thead .stick2{z-index:4;background:var(--thead)}
  .lbtable tbody tr:hover .stick2{background:var(--hover)}

  .lbtable .rk{text-align:right;color:var(--muted);font-variant-numeric:tabular-nums;width:44px}
  .lbtable .nm{font-weight:600;min-width:150px}
  /* The name is a link to his page; it looks as the cell always did. */
  .lbtable .nm a{color:inherit;text-decoration:inherit;cursor:pointer}
  .lbtable .num{text-align:right;font-variant-numeric:tabular-nums}

  /* One box per metric: percentile large, the rate it came from underneath. */
  /* The text colour is set per box, from the fill underneath it: both
     percentile ramps run dark to light, so one fixed colour would be
     unreadable at one end of whichever ramp is showing. */
  .pbox{display:flex;flex-direction:column;align-items:center;justify-content:center;
        min-width:46px;border-radius:5px;padding:3px 5px;line-height:1.15;color:#fff}
  .pbox b{font-size:12px;font-weight:650;font-variant-numeric:tabular-nums}
  .pbox span{font-size:9px;font-variant-numeric:tabular-nums}
  .pbox.none{background:var(--nobox);color:var(--muted)}
  .lbmore{text-align:center;padding:12px 0}
  .rowspick{display:flex;flex-direction:column;gap:5px;flex:0 0 auto;font-size:11px;
            letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
  .rowspick select{padding:7px 9px;min-width:74px;border:1px solid var(--box);border-radius:7px;
                   font-size:13.5px;font-weight:650;background:var(--surface);color:var(--ink);cursor:pointer}
  /* Previous · Page [n] of N · Next, under the table. */
  .pager{display:flex;align-items:center;justify-content:center;gap:16px;padding:16px 0 6px}
  .pager button{min-width:128px;font-weight:650}
  .pgmid{display:flex;align-items:center;gap:9px;font-size:13.5px;color:var(--ink)}
  .pgmid input{width:52px;padding:7px 6px;text-align:center;border:1px solid var(--box);border-radius:7px;
               font-size:13.5px;font-weight:650;background:var(--surface);color:var(--ink)}
  @media (max-width:600px){
    .pager{gap:10px}
    .pager button{min-width:0;padding:8px 12px}
  }

  /* ---------- the two tables under the card ---------- */
  /* Outside #cardRow, which is what the export photographs — so nothing
     here can reach the picture however tall it grows. */
  /* On a phone the wrap stacks with its items at flex-start, which makes the
     stage shrink to fit its widest child — and these tables are wider than a
     phone. Full width, so they scroll inside their own box instead of
     widening the page. (flex:1 sets flex-basis to 0, so this changes nothing
     on a desktop.) */
  #mode-card .stage{width:100%}
  #belowCard{margin-top:18px;display:flex;flex-direction:column;gap:16px}
  .ctable{background:var(--surface);border:1px solid var(--box);border-radius:10px;padding:14px 16px}
  .ctable h3{margin:0 0 10px;font-size:12px;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
  /* The log's own season. Since redesign step 17 it sits at the right of
     the box's heading (styles/22-profile-page.css); the year in each option
     is caption enough on its own. */
  #logSeason{display:block;margin:0 0 10px;min-width:190px;padding:6px 9px;
             border:1px solid var(--box);border-radius:7px;font-size:13px;
             background:var(--surface);color:var(--ink);outline:none}
  .ctscroll{overflow:auto;max-height:52vh;border:1px solid var(--line);border-radius:8px}
  .ctscroll table{border-collapse:separate;border-spacing:0;font-size:12px;width:max-content;min-width:100%}
  .ctscroll th,.ctscroll td{padding:5px 9px;white-space:nowrap;border-bottom:1px solid var(--line)}
  .ctscroll thead th{position:sticky;top:0;z-index:2;background:var(--thead);color:var(--muted);
        font-size:10px;letter-spacing:.06em;text-transform:uppercase;font-weight:600;text-align:left}
  .ctscroll tbody tr:hover td{background:var(--hover)}
  .ctscroll .num{text-align:right;font-variant-numeric:tabular-nums}
  .ctscroll thead .num{text-align:right}
  .ctscroll tbody tr:last-child td{border-bottom:0}
  /* The season the card is showing, so the eye finds it without reading. */
  .ctscroll tr.on td{background:var(--sel2)}
  .ctscroll tr.tot td{border-top:1px solid var(--box);font-weight:650;color:var(--ink)}
  .ctempty{padding:18px 10px;text-align:center;color:var(--muted);font-size:14px}
  /* The shot map (patch-card-shot-map.mjs): the rink, then the selectors one
     above another, then the table by danger over what the selection adds up
     to, then the radar of his scoring-chance percentiles; the key runs along
     the bottom of the box. Four columns on a wide screen, wrapping as the
     box narrows, one under the other on a phone. */
  .ctable h3 .smsub{color:var(--faint);letter-spacing:.04em;text-transform:none;font-weight:500}
  .smhead{display:flex;align-items:center;justify-content:space-between;gap:12px;margin:0 0 10px}
  .smhead h3{margin:0}
  /* The splits box (patch-card-splits.mjs): four tables, one above the
     other (William: "list them all on top of one another and add more stats
     with the gained width"), so each has the whole width for the whole
     line. Each scrolls sideways by itself where the screen is narrower. */
  #splitWrap{display:flex;flex-direction:column;gap:14px}
  .spl{min-width:0}
  /* One grid for all four: a fixed first column, and every stat the same
     width, so a stat sits in the same place in each table and the eye runs
     straight down. Left to itself each table sized its columns by its own
     numbers, and no two lined up ("spacing looks a bit funky"). spLoad sets
     the least width from the number of columns. */
  .spl .ctscroll table{table-layout:fixed;width:100%}
  /* The first column's width is the table's own <col> (scripts/15-splits.js,
     SP_FIRST): under a row of group names the first cell of a row is no
     longer the first column's. */
  .ctscroll td.nil{color:var(--faint)}
  .spl h4{margin:0 0 7px;font-size:12.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--faint);font-weight:600}
  .spl .ctscroll{max-height:none}
  .spl .ctscroll td.stick{color:var(--ink);font-weight:600}
  #smPng{display:inline-flex;align-items:center;gap:7px;padding:6px 11px;font-size:13px}
  /* In the picture the heading says whose map it is and what was chosen:
     the selectors are controls and are not photographed. */
  /* And over it, the card's own header (scripts/16-shot-map.js,
     smCardHeader_): in the picture only, this class is on nothing in the
     page. It runs to the box's edges (the box's padding, undone) and ends
     in a rule; the bio is its last row, so that row's own rule and gap go. */
  .smxcard{margin:-14px -16px 16px;border:0;border-bottom:1px solid var(--cardline);border-radius:0}
  .smxcard .body{padding-bottom:0}
  .smxcard .bio{border-bottom:0;margin-bottom:0;padding-bottom:13px}
  .smxwho{display:flex;flex-direction:column;gap:3px;min-width:0}
  .smxwho b{font-family:var(--font-display);font-size:21px;font-weight:650;color:var(--ink);letter-spacing:.01em}
  .smxwho span{font-size:14px;color:var(--muted)}
  .smxwho .smxsel{color:var(--ink2)}
  /* The rink is the tallest thing in the box; the columns beside it sit at
     its middle rather than hanging from the top (William, 5 October 2026). */
  .shotmap{display:flex;gap:30px;align-items:center;flex-wrap:wrap}
  .shotmap .smrinkcol{flex:0 0 auto;width:380px;max-width:100%}
  .shotmap .smrink svg{width:100%;height:auto;display:block}
  /* Dots or zones (scripts/16-shot-map.js, smViewSeg): over the rink, as wide
     as two buttons need, on every map of the site. */
  .seg.smview{display:inline-flex;margin:0 0 10px}
  .seg.smview button{flex:0 0 auto;padding:6px 16px;font-size:14px}
  .smrink circle[data-i]{cursor:pointer}
  .smrink circle[data-i]:hover,.smrink circle.on{stroke:#ffffff;stroke-opacity:1;stroke-width:.55}
  .smside{flex:0 1 250px;min-width:210px;font-size:14px;color:var(--ink2)}
  .smthird{flex:1 1 320px;max-width:480px;min-width:0;font-size:14px;color:var(--ink2)}
  .smradar{flex:1 1 300px;max-width:480px;min-width:0;font-size:14px;color:var(--ink2)}
  .smradar .smh span{text-transform:none;letter-spacing:.02em;font-weight:500;color:var(--faint)}
  .smrdplot{position:relative}
  .smrdplot canvas{display:block}
  .smfs{display:flex;flex-direction:column;gap:11px;margin:0 0 6px}
  .smf{display:flex;flex-direction:column;gap:4px;min-width:0}
  .smf span,.smh{font-size:11.5px;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);font-weight:600}
  .smf select{width:100%;padding:6px 8px;border:1px solid var(--box);border-radius:7px;font-size:14px;
              background:var(--surface);color:var(--ink);outline:none;min-width:0}
  .smreset{margin:4px 0 0;padding:0;border:0;background:none;font:inherit;font-size:13.5px;cursor:pointer}
  .smreset[disabled]{color:var(--faint);cursor:default}
  .smsum{display:grid;grid-template-columns:1fr auto;gap:8px 18px;margin:0;font-variant-numeric:tabular-nums;
         border-top:1px solid var(--line);padding-top:12px}
  .smsum dt{color:var(--muted)} .smsum dd{margin:0;text-align:right;color:var(--ink);font-weight:600}
  .smh{margin:0 0 8px}
  .smbands{width:100%;border-collapse:collapse;margin:0 0 16px;font-variant-numeric:tabular-nums}
  .smbands th{font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);font-weight:600;
              text-align:right;padding:0 0 6px 10px}
  .smbands th:first-child,.smbands td:first-child{text-align:left;padding-left:8px}
  .smbands td{padding:6px 0 6px 10px;text-align:right;border-top:1px solid var(--line);color:var(--ink)}
  .smbands td:first-child{color:var(--ink2)}
  .smbands tr.on td{background:var(--sel2)}
  /* The table by zone (scripts/16-shot-map.js, smZoneTable): under the box's row, its whole width; sideways on a phone. */
  .smzt{margin-top:18px}
  .smztwrap{overflow-x:auto}
  .smztable{margin:0;min-width:560px}
  .smztable tr.tot td{font-weight:600;color:var(--ink);border-top:1px solid var(--box)}
  .smztable th:first-child,.smztable td:first-child{position:sticky;left:0;z-index:1;background:var(--surface)}
  .smfoot{margin-top:16px;padding-top:12px;border-top:1px solid var(--line);font-size:14px;
          display:flex;flex-wrap:wrap;gap:10px 40px;align-items:flex-start}
  .smkey{display:flex;flex-wrap:wrap;gap:6px 26px;margin:0;color:var(--muted)}
  .smkey span{display:flex;align-items:center;gap:8px}
  .smkey svg{width:38px;height:18px;flex:0 0 auto}
  .smnote{flex:1 1 420px;color:var(--faint);font-size:13px;line-height:1.5}
  .smnote p{display:inline;margin:0}
  .smnote p + p:before{content:' '}
  @media (max-width:640px){ .smside{flex:1 1 100%} }
  @media(max-width:860px){ .ctscroll{max-height:46vh} }

  /* ---------- the radar ---------- */

  /* Two buttons behaving as one control. The chart type is a choice between
     two views, not a filter you add to, so it isn't a dropdown. */
  /* On the card the switch sits directly under the season dropdown — the two
     together name the set of numbers being read — so it pulls up against it
     rather than carrying a heading of its own. */
  .modeseg{margin:-4px 0 14px}
  .seg{display:flex;border:1px solid var(--box);border-radius:8px;overflow:hidden;
       margin-bottom:2px}
  .seg button{flex:1;padding:8px 10px;border:0;background:var(--surface2);
              color:var(--muted);font:inherit;font-size:13px;cursor:pointer}
  .seg button + button{border-left:1px solid var(--box)}
  .seg button[aria-pressed="true"]{background:var(--sel);color:var(--ink);font-weight:600}
  .seg button:focus{outline:none}

  /* A player slot wears its own colour, so the rail and the chart agree
     without anybody having to match names to shapes. */
  .pslot{display:flex;align-items:center;gap:8px;margin-bottom:7px}
  .pslot .pdot{width:9px;height:9px;border-radius:50%;flex:0 0 9px;background:var(--track)}
  .pslot input{margin:0;min-width:0;flex:1}
  .pslot input.filled{color:var(--ink)}
  .pslot .rdx{flex:0 0 auto;padding:6px 9px;font-size:13px;line-height:1}

  /* One results panel for whichever search is being typed in — three separate
     dropdowns would stack three lists on top of each other. */
  .rdhits{max-height:210px;overflow-y:auto;border:1px solid var(--box);
          border-radius:8px;background:var(--surface2);margin:2px 0 9px}
  .rdhits .hit{padding:7px 10px;cursor:pointer;font-size:12.5px;
               border-bottom:1px solid var(--line);display:flex;
               justify-content:space-between;gap:8px;align-items:baseline}
  .rdhits .hit:last-child{border-bottom:0}
  .rdhits .hit:hover{background:var(--hover)}
  .rdhits .hit b{color:var(--ink);font-weight:600}
  .rdhits .hit span{color:var(--muted);font-size:11px;white-space:nowrap}
  .rdhits .none{padding:9px 10px;font-size:12px;color:var(--muted)}

  .slot{display:flex;align-items:center;gap:8px;margin-bottom:7px}
  .slot .n{font-family:var(--font-body);font-variant-numeric:tabular-nums;font-size:10.5px;
           color:var(--faint);width:13px;flex:0 0 13px;text-align:right}
  .slot select{margin:0;min-width:0;flex:1}

  /* The names ride above the plot rather than inside a corner of it: three of
     them with a club and a season each is more than a corner can hold. */
  .rdlegend{display:flex;flex-wrap:wrap;justify-content:center;gap:6px 20px;
            padding:4px 2px 10px;font-size:12.5px;min-height:20px}
  /* Pinned to their content: the panel is wide, and a legend whose entries
     stretch to fill it reads as two unrelated captions rather than one key. */
  .rdlegend .who{display:flex;align-items:center;gap:7px;min-width:0;flex:0 0 auto}
  .rdlegend .dot{width:9px;height:9px;border-radius:50%;flex:0 0 9px}
  .rdlegend b{color:var(--ink);font-weight:600}
  .rdlegend span{color:var(--muted)}
  @media(max-width:520px){.rdlegend{font-size:11.5px;gap:4px 14px}}

  /* ---------- chart ---------- */
  /* One chip per committed highlight, so several players can be picked out at
     once without the search box having to parse a list. */
  .chips{display:flex;flex-wrap:wrap;gap:6px;margin:0 0 10px}
  .chip{display:inline-flex;align-items:center;gap:6px;padding:4px 8px 4px 10px;
        border:1px solid var(--cardline);border-radius:20px;background:var(--surface);
        font-size:12px;color:var(--ink)}
  .chip i{width:9px;height:9px;border-radius:50%;flex:0 0 9px;font-style:normal}
  .chip button{padding:0;border:0;background:none;color:var(--muted);font-size:14px;
               line-height:1;cursor:pointer}

  .scpanel{padding:14px 16px 12px;max-width:1000px}

  /* ---------- lines ---------- */
  .lnpanel{padding:14px 16px 12px;max-width:1000px}
  .lnday{display:flex;align-items:center;gap:8px;margin-bottom:8px}
  .lnday button{flex:0 0 auto;padding:8px 12px}
  .lnday span{flex:1;text-align:center;font-weight:600}
  .lnhow{font-size:12px;color:var(--muted);line-height:1.45;margin:14px 0 0}
  /* The list: a section per league, QMJHL, OHL, WHL. */
  .lnsec + .lnsec{margin-top:18px}
  /* The league's name at 17px, its count at 14px (William, 14 Oct 2026: both were 12px, too small). */
  .lnsec h3{display:flex;align-items:baseline;gap:12px;margin:0;padding:0 2px 8px;
            border-bottom:1px solid var(--line);font-size:17px;letter-spacing:.08em;text-transform:uppercase}
  .lnsec h3 span{font-size:14px;font-weight:400;letter-spacing:0;text-transform:none;color:var(--muted)}
  .lnrow{display:grid;grid-template-columns:104px minmax(0,1fr) auto;gap:6px 14px;align-items:center;
         padding:11px 2px;border-top:1px solid var(--line)}
  .lnsec h3 + .lnrow{border-top:0}
  /* The picker, in the settings box: the games with lines, by league. */
  .lnpick{border:1px solid var(--box);border-radius:8px;padding:6px 10px 8px;max-height:340px;overflow:auto}
  .lnpick .none{font-size:12px;color:var(--muted);padding:4px 0}
  .lnpg + .lnpg{margin-top:6px;padding-top:6px;border-top:1px solid var(--line)}
  .lnpgh{display:flex;justify-content:space-between;align-items:center;font-size:11px;font-weight:600;
         letter-spacing:.08em;color:var(--muted);padding:3px 0}
  .lnpick label{display:flex;align-items:center;gap:8px;padding:4px 0;font-size:13px;cursor:pointer}
  .lnpick label span{margin-left:auto;font-size:11.5px;color:var(--muted);font-variant-numeric:tabular-nums;white-space:nowrap}
  .lnpick input[type=checkbox]{width:16px;height:16px;margin:0;flex:0 0 16px;cursor:pointer}
  .lnlinks{display:flex;gap:14px;margin:6px 0 2px;font-size:12px}
  .lnlinks button, .lnpgh button{padding:0;border:0;background:none;font-size:inherit;
         font-weight:inherit;letter-spacing:inherit;cursor:pointer}
  .lntime{font-variant-numeric:tabular-nums;color:var(--ink2);font-size:14.5px}
  .lnteams{font-size:16px;line-height:1.35}
  .lnteams b{font-weight:600}
  .lnteams i{font-style:normal;color:var(--muted);padding:0 5px}
  .lnstate{font-size:13px;color:var(--muted);margin-top:2px}
  .lnstate.ok{color:var(--good)}
  .lnstate.half{color:var(--warn-ink)}
  .lnacts{display:flex;gap:8px;align-items:center;justify-content:flex-end;flex-wrap:wrap}
  /* The rest of the box a size up too (William, 14 Oct 2026, after the league names):
     its title, date and count, the row's buttons and the note under it. Scoped to
     the Lines box, as .sctitle and .scfoot are the Charts tab's too. */
  .lnpanel .sctitle b{font-size:18px}
  .lnpanel .sctitle span, .lnpanel #lnMeta{font-size:13px}
  .lnpanel .scfoot{font-size:12.5px}
  .ctl .lnpanel a.btnlink, .ctl .lnpanel .lnopen{height:38px;font-size:14.5px}
  .lnsrc{font-size:13.5px;color:var(--muted)}
  /* A download is a link, dressed as the buttons beside it. */
  a.btnlink{display:inline-flex;align-items:center;gap:6px;padding:8px 15px;border:1px solid var(--box);
            background:var(--surface);border-radius:7px;font-size:13px;color:var(--ink);text-decoration:none}
  /* A game opened in place: both clubs' lines (scripts/patch-card-lines-view.mjs). */
  .lnrow.can .lnteams{cursor:pointer}
  .lnopen{display:inline-flex;align-items:center;gap:6px;padding:8px 13px;border:1px solid var(--box);
          background:var(--surface);border-radius:7px;font-size:13px;color:var(--ink);cursor:pointer}
  .lnopen .car{font-size:10px;transition:transform .15s}
  .lnopen[aria-expanded=true] .car{transform:rotate(180deg)}
  .lnview{padding:2px 2px 16px}
  .lnview .none{font-size:13px;color:var(--muted);padding:10px 0}
  .lnview .none button{padding:0;border:0;background:none;font-size:inherit;cursor:pointer}
  /* Each club in its own colours, as on the social images (lib/lines/social.tsx):
     a bar in its colour over it, its crest, its city over its nickname, and
     its colour on the numbers, the section marks and START. --club and --band
     come from wa_linesgame, read off the crest; gray if they don't. */
  .lvteam{border-top:4px solid var(--band,var(--muted));padding-top:10px;margin-top:6px}
  .lvteam + .lvteam{margin-top:16px}
  .lvhead{display:flex;align-items:center;gap:12px;margin-bottom:2px}
  .lvcrest{flex:0 0 52px;width:52px;height:52px;object-fit:contain}
  /* A .jpg-only club's crest comes with a white square round it: a tile, meant. */
  .lvcrest.tile{display:flex;align-items:center;justify-content:center;background:#fff;border-radius:8px}
  .lvcrest.tile img{width:44px;height:44px;object-fit:contain}
  .lvname{display:flex;flex-direction:column;flex:1;min-width:0}
  .lvcity{font-size:12.5px;line-height:1.15;color:var(--muted)}
  .lvnick{font-family:var(--font-display);font-weight:600;font-size:28px;line-height:1;letter-spacing:.01em;
          text-transform:uppercase;color:var(--ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .lvside{align-self:flex-start;font-size:10.5px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--muted)}
  /* Slim section heads, each with the club's mark; the rows' own labels (L1, D1) carry the rest. */
  .lvsec{font-size:10.5px;font-weight:600;letter-spacing:.09em;color:var(--muted);margin:8px 0 4px}
  .lvsec span{display:inline-flex;align-items:center;gap:7px}
  .lvsec span::before{content:'';width:4px;height:11px;border-radius:2px;background:var(--band,var(--muted))}
  .lvrow{display:grid;grid-template-columns:26px repeat(3,minmax(0,1fr));gap:6px 8px}
  .lvrow.two{grid-template-columns:26px repeat(2,minmax(0,1fr))}
  .lvrow + .lvrow{margin-top:6px}
  .lvlab{display:flex;align-items:center;justify-content:center;font-family:var(--font-display);
         font-weight:600;font-size:14px;color:var(--faint)}
  /* The goalies sit in the third column beside the defence pairs, which only
     use two: a row and a heading saved. Their head shares the defence's line.
     On a phone they get their own section again (below). */
  /* Every section head sits on the rows' grid, so FORWARDS and DEFENCE start where
     the first cell does and GOALIES where the third does (William's ask). */
  .lvsec{display:grid;grid-template-columns:26px repeat(3,minmax(0,1fr));gap:8px}
  .lvsec span:first-child{grid-column:2}
  .lvsec span + span{grid-column:4}
  .lvgkown{display:none}
  .lvgkcell{display:flex;min-width:0}
  .lvgkcell > .lvc{flex:1}
  .lvc{display:flex;flex-direction:column;min-width:0;background:var(--surface);border:1px solid var(--box);
       border-radius:10px;overflow:hidden}
  /* No one in a slot: nothing drawn, but the slot is kept so each man stays in his
     position's column (William: never leave empty cells). A phone drops it. */
  .lvgap{min-width:0}
  .lvtop{position:relative;display:flex;align-items:center;gap:10px;flex:1;padding:5px 10px 4px}
  .lvnum{flex:0 0 36px;text-align:right;font-family:var(--font-display);font-weight:600;font-size:30px;
         line-height:1;color:var(--club,var(--muted))}
  .lvwho{flex:1;min-width:0}
  .lvfirst{display:block;font-size:12px;line-height:1.15;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .lvlast{display:block;font-family:var(--font-display);font-weight:600;font-size:19px;line-height:1.05;
          text-transform:uppercase;color:var(--ink);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .lvdet{margin-top:1px;font-size:11.5px;line-height:1.3;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .lvdet i{font-style:normal;color:var(--line);padding:0 4px}
  /* A draft-year player's DY: the green chip the social images use. */
  .lvdet .dy{display:inline-block;padding:0 5px;border-radius:4px;background:var(--good);color:#0f1a14;
             font-size:10.5px;font-weight:600;line-height:14px}
  .lvtag{position:absolute;top:5px;right:9px;font-size:10px;font-weight:600;letter-spacing:.1em;color:var(--club,var(--muted))}
  .lvstats{display:flex;border-top:1px solid var(--line);background:var(--bg)}
  .lvstats span{flex:1;display:flex;justify-content:center;align-items:baseline;gap:5px;padding:2px 0;
                font-size:12.5px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}
  .lvstats span + span{border-left:1px solid var(--line)}
  .lvstats i{font-style:normal;font-size:10px;font-weight:600;letter-spacing:.06em;color:var(--faint)}
  /* (patch-card-lines-phone-grid.mjs) A phone shows the PC grid, each club
     drawn 720px wide and zoomed to fit (--lvz, set by lvFit()); the phone's
     pinch zoom reads it. It replaced one cell a row. */
  @media(max-width:700px){
    .lnview .lvteam{width:720px;zoom:var(--lvz,.5)}
    /* The tighter cells a 1920 screen gets, so each details line fits whole at 720px. */
    .lvrow, .lvsec{grid-template-columns:20px repeat(3,minmax(0,1fr));gap:6px}
    .lvrow.two{grid-template-columns:20px repeat(2,minmax(0,1fr))}
    .lvtop{gap:8px;padding:5px 8px 4px}
    .lvnum{flex-basis:30px;font-size:26px}
    .lvlast{font-size:17px}
    .lvdet{font-size:10.5px}
    .lvdet i{padding:0 3px}
    .lvstats span{font-size:12px}
  }
  /* Wide screens: the Lines tab takes more of the width, and an open game
     puts its two clubs side by side once it has room for them. */
  #mode-lines{max-width:2080px}
  #mode-lines .lnpanel{max-width:none}
  .lnview{container:lnview / inline-size}
  /* (patch-card-lines-compact.mjs) Side by side from 1150px, not 1360. */
  @container lnview (min-width:1150px){
    .lvteams{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:24px;align-items:start}
    .lvteam + .lvteam{margin-top:6px}   /* the same as the first, so both colour bars line up */
  }
  @container lnview (min-width:1360px) and (max-width:1559px){
    .lvrow, .lvsec{grid-template-columns:20px repeat(3,minmax(0,1fr));gap:6px}
    .lvrow.two{grid-template-columns:20px repeat(2,minmax(0,1fr))}
    .lvtop{gap:8px;padding:5px 8px 4px}
    .lvnum{flex-basis:30px;font-size:26px}
    .lvlast{font-size:17px}
    .lvdet{font-size:10.5px}
    .lvdet i{padding:0 3px}
    .lvstats span{font-size:12px}
  }
  /* (patch-card-mid-width-tabs.mjs) Too narrow for time, teams and buttons
     on one line, the buttons go on their own line under the teams. */
  #lnList{container:lnlist / inline-size}
  @container lnlist (max-width:720px){
    .lnrow{grid-template-columns:104px minmax(0,1fr)}
    .lnacts{grid-column:2;justify-content:flex-start}
  }
  @media(max-width:700px){
    .lnrow{grid-template-columns:minmax(0,1fr);gap:4px}
    .lnacts{grid-column:auto}   /* a phone's one column: the rule above must not open a second */
    .lnacts{justify-content:flex-start}
  }
  .sctitle{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;margin-bottom:10px}
  .sctitle .grow{flex:1}
  #scMeta{font-size:11.5px;color:var(--muted);white-space:nowrap}
  .sctitle b{font-size:15px;font-weight:650}
  .sctitle span{font-size:11.5px;color:var(--muted)}
  /* The canvas sits in a grid cell with the axis captions around it, so the
     plot keeps its own coordinate space and the labels never overlap it. */
  /* The captions are painted into the bitmap, so the plot is one element and
     the margins below reserve the room they need. */
  .scplot{position:relative}
  #scCanvas{width:100%;display:block;cursor:crosshair;touch-action:none}
  /* Only on screen while the plot is zoomed, and never in the PNG. */
  /* Sits in the title line beside the count, outside the plot: in the plot's
     corner it covered the very crests a zoom into the top range is for. */
  .sczoom{display:flex;gap:6px;align-items:center;align-self:center;flex:0 0 auto;
          border:1px solid var(--cardline);border-radius:7px;
          padding:3px 5px 3px 9px;font-size:11px;color:var(--muted);
          font-variant-numeric:tabular-nums}
  .sctitle .sczoom span{font-size:11px}
  .sczoom button{font:inherit;color:var(--ink);background:none;border:1px solid var(--cardline);
                 border-radius:5px;padding:2px 7px;cursor:pointer}
  .sczoom button:hover{border-color:var(--muted)}
  #trCanvas{width:100%;display:block;cursor:crosshair}
  /* The second legend row: the lines, under the man they belong to. */
  .rdlegend + .rdlegend{margin-top:-4px;font-size:11.5px}
  .scfoot{display:flex;justify-content:space-between;align-items:flex-end;gap:14px;
          margin-top:9px;padding-top:8px;border-top:1px solid var(--line);
          font-size:11px;color:var(--muted)}

  /* Follows the cursor, so it must never sit under it and eat the next move. */
  .sctip{position:fixed;z-index:50;pointer-events:none;background:var(--surface);
         border:1px solid var(--cardline);border-radius:8px;padding:8px 11px;
         font-size:12px;color:var(--ink);box-shadow:0 6px 22px rgba(0,0,0,.22);
         max-width:250px}
  .sctip b{display:block;font-size:13px;font-weight:650;margin-bottom:1px}
  .sctip .who{font-size:11px;color:var(--muted);margin-bottom:6px}
  .sctip table{border-collapse:collapse;width:100%}
  .sctip td{padding:1px 0;font-size:11.5px}
  .sctip td.v{text-align:right;font-weight:600;font-variant-numeric:tabular-nums;padding-left:10px}
  .sctip td.p{text-align:right;font-variant-numeric:tabular-nums;color:var(--muted);padding-left:8px}

  /* ---------- compare ---------- */
  .rail .sQ{font-size:13.5px}

  /* Three columns sharing one grid: every row of content is one grid row, so
     the two sides stay aligned line-for-line no matter what is in them — which
     is what lets the middle column carry a per-metric gap at all. */
  #compare{max-width:1120px}
  .cmp{display:grid;grid-template-columns:minmax(0,1fr) 66px minmax(0,1fr);
       align-items:stretch;background:transparent}
  /* Card chrome is painted on each cell rather than on one element spanning
     the whole column. A spanning element has to be explicitly placed, and an
     explicitly placed item makes every other cell auto-place around it — which
     is exactly what knocked the gutter out of line with its rows. */
  .cell{background:var(--surface);min-width:0;
        border-left:1px solid var(--cardline);border-right:1px solid var(--cardline)}
  .cell.top{border-top:1px solid var(--cardline);border-radius:12px 12px 0 0;overflow:hidden}
  .cell.bot{border-bottom:1px solid var(--cardline);border-radius:0 0 12px 12px;min-height:11px}

  .c-hdr{background:var(--band);color:var(--onband);padding:11px 14px;display:flex;gap:11px;align-items:center}
  .c-hdr .shot{width:52px;height:52px;flex:0 0 52px}
  .c-hdr .crest{width:52px;height:52px;flex:0 0 52px;padding:5px}
  .c-hdr h1{margin:0;font-size:17px;line-height:1.15;font-weight:650}
  .c-hdr .sub{margin-top:2px;font-size:11px;color:var(--onband-dim)}

  .c-line{display:flex;background:var(--surface2);border-bottom:1px solid var(--line);flex-wrap:wrap}
  .c-line > div{flex:1;padding:7px 4px;text-align:center;border-right:1px solid var(--line);min-width:52px}
  .c-line > div:last-child{border-right:0}
  .c-line .n{font-size:15px;font-weight:650;line-height:1.15}
  .c-line .k{font-size:9px;color:var(--muted);letter-spacing:.06em;text-transform:uppercase;margin-top:2px}

  .c-bio{display:flex;flex-wrap:wrap;gap:0 15px;font-size:11.5px;color:var(--muted);
         padding:9px 14px;border-bottom:1px solid var(--line)}
  .c-bio b{color:var(--ink);font-weight:600}
  .c-bio b.dy{color:var(--brand-text)}

  .c-sec{padding:9px 14px 2px;font-size:10px;letter-spacing:.1em;
         text-transform:uppercase;color:var(--muted);font-weight:600}
  /* Single column, the original vertical layout — with two cards side by side
     there is no reason to fold the metrics into two columns. */
  .c-m{display:grid;grid-template-columns:118px 52px 1fr 26px;gap:7px;
       align-items:center;padding:2.5px 14px;font-size:12px}
  .c-m .lab{color:var(--ink2)}
  .c-m .val{text-align:right;font-weight:600;font-variant-numeric:tabular-nums}
  .c-m .pn{text-align:right;font-size:10.5px;color:var(--muted);font-variant-numeric:tabular-nums}
  .c-m .track{height:8px;background:var(--track);border-radius:5px;overflow:hidden}
  /* display:block matters — .track isn't a flex or grid container, so an
     inline .fill would ignore both its width and its height. */
  .c-m .fill{display:block;height:100%;border-radius:5px}

  /* The gutter. Empty on every row that isn't a metric, so the gap numbers sit
     exactly on the lines they describe. */
  /* Swapping sides is a thing you do TO the pair, so it sits between them
     rather than in a menu beside them. .noexport keeps it out of the PNG. */
  .swapbtn{width:30px;height:30px;padding:0;display:flex;align-items:center;
           justify-content:center;font-size:14px;line-height:1;border-radius:8px}
  .swapbtn:disabled{opacity:.4}

  .gap{display:flex;align-items:center;justify-content:center;font-size:11px;
       font-variant-numeric:tabular-nums;color:var(--muted);gap:3px}
  .gap b{color:var(--ink);font-weight:650}
  .gap .car{color:var(--brand-text);font-size:9px}
  .gap.sec{font-size:9px}

  .c-foot{grid-column:1/-1;display:flex;justify-content:space-between;align-items:flex-end;
          gap:16px;padding:11px 2px 0;font-size:11px;color:var(--muted)}
  /* The words run the footer's whole width (7 October 2026: "Expand footer
     legend all the way across on website"). They were held to 78 characters
     to leave room for the league and handle at the right, which are gone. */
  .c-foot p{margin:0}
  .cmp-note{background:var(--warn-bg);border:1px solid var(--warn-line);color:var(--warn-ink);padding:10px 13px;
            border-radius:7px;font-size:12.5px;grid-column:1/-1;margin-top:10px}

  /* =================================================================
     NARROW SCREENS
     -----------------------------------------------------------------
     Last in the file on purpose. Every rule here overrides one above
     it at the same weight, so its position in the file is what makes
     it win.
     ================================================================= */

  @media(max-width:860px){
    .railtop{display:flex;align-items:center;justify-content:space-between;gap:10px;
             width:100%;min-height:40px;padding:11px 13px;font-size:13.5px;font-weight:600;
             background:var(--surface);color:var(--ink);
             border:1px solid var(--box);border-radius:10px;cursor:pointer}
    .railtop .car{color:var(--muted);font-size:11px;transition:transform .15s}
    .rail.open .railtop .car{transform:rotate(180deg)}
    .rail{padding:0;border:0;background:none;border-radius:0}
    /* .railacts is the exception: folding the settings away must not fold
       away the export button with them. */
    .rail > *:not(.railtop):not(.railacts){display:none}
    .railacts{margin-top:9px;padding-top:0;border-top:0}
    .rail.open .railacts{margin-top:10px}
    .rail.open{padding:0}
    .rail.open > *{display:block}
    .rail.open .railtop{display:flex;border-radius:10px 10px 0 0;border-bottom:0}
    /* The body of an open rail keeps the box the header started. */
    .rail.open .railbody{display:block;border:1px solid var(--box);border-top:0;
             border-radius:0 0 10px 10px;background:var(--surface);padding:14px}
    .rail .railbody{display:none}
    /* 16px or iOS zooms the whole page the moment a field takes focus. */
    .rail select,.rail input[type=text]{font-size:16px;padding:10px 11px}
    button{padding:10px 15px}
  }

  @media(max-width:700px){
    /* Two cards will not fit side by side, but the comparison is the point,
       so the pair stays on one line per metric and the label moves above it:
       A's number runs out from the middle to the left, B's to the right, and
       the gap in percentile sits between them exactly as it does on a
       desktop. */
    /* With the labels shared, the pair reads as one card rather than two, so
       the outline moves to the whole grid and the cells lose their own. */
    .cmp{grid-template-columns:minmax(0,1fr) 40px minmax(0,1fr);
         border:1px solid var(--cardline);border-radius:12px;overflow:hidden}
    .cell{border-left:0;border-right:0}
    .cell.top{border-top:0;border-radius:0}
    .cell.bot{border-bottom:0;border-radius:0;min-height:6px}
    /* Each side is a card in its own right: its own section headings, its own
       stat names, both set against its own outer edge so the two mirror
       across the gutter rather than both reading left to right. */
    .c-sec{padding:10px 12px 2px;border-top:1px solid var(--line);margin-top:5px}
    .cell.l .c-sec{text-align:left}
    .cell.r .c-sec{text-align:right}

    /* Two lines per stat: the name, then the value, the percentile and the
       bar. The two numbers sit against the gutter and the bar runs away
       from it, so each side is read outward from the middle.

       The percentile used to be dropped here for room. It is the fallback
       for anyone who can't read the bar's colour, so it stays and the bar
       gives up the width instead. */
    .c-m{grid-template-columns:42px 19px 1fr;gap:2px 6px;padding:3px 10px 8px;font-size:12px}
    .c-m .lab{display:block;grid-column:1/-1;font-size:11px;
              color:var(--ink2);font-weight:600;text-align:right}
    .c-m .pn{display:block;font-size:10px;text-align:center;color:var(--faint)}
    .cell.r .c-m .val{order:1}
    .cell.r .c-m .pn{order:2}
    .cell.r .c-m .track{order:3}
    .cell.l .c-m{grid-template-columns:1fr 19px 42px}
    .cell.l .c-m .lab{text-align:left;order:0}
    .cell.l .c-m .track{order:1}
    .cell.l .c-m .pn{order:2}
    .cell.l .c-m .val{order:3;text-align:right}
    .cell.l .c-m .fill{float:right}

    .c-hdr{padding:9px 10px;gap:8px}
    .c-hdr .shot,.c-hdr .crest{width:38px;height:38px;flex:0 0 38px}
    .c-hdr h1{font-size:13.5px;line-height:1.2}
    .c-hdr .sub{font-size:9.5px;margin-top:1px}
    .c-line > div{min-width:0;padding:6px 2px}
    .c-line .n{font-size:13px}
    .c-line .k{font-size:8px}
    .c-bio{padding:7px 10px;gap:0 9px;font-size:10.5px}
    .c-sec{padding:8px 12px 1px}
    /* The gap belongs to the bars, not the names above them, so it sits on
       the last line of the block rather than in the middle of it. */
    .gap{font-size:10px;align-items:flex-end;padding-bottom:9px}
    .gap.sec{padding-bottom:0}
    .c-foot{font-size:10px;flex-direction:column;align-items:flex-end;gap:7px;
            padding:10px 13px 11px}
  }

  @media(max-width:700px){
    .scpanel{padding:11px 11px 9px}
    .sctitle b{font-size:13.5px}
    .sctitle span{font-size:10.5px}
    #scMeta{width:100%;white-space:normal}
    .sctip{max-width:78vw;font-size:11.5px}
  }

  /* (patch-card-lines-actions.mjs) Lines' PDF button, inside its box on a phone. */
  @media(max-width:860px){
    #lnActs{margin-top:14px;padding-top:12px;border-top:1px solid var(--line)}
  }
  /* (patch-card-bio.mjs) The card's header and bio, after NHL.com's. */
  .hdr{padding:16px 22px;gap:16px}
  /* --hsz: the name block's height, set by the observer below; --himg holds
     it between a floor and a ceiling, because the images take width from
     the text, and on a very narrow screen taller text would ask for wider
     images, which squeeze the text taller still. */
  .hdr{--himg:clamp(56px, var(--hsz,100px), 116px)}
  .hdr .shot, .hdr .crest{width:var(--himg);height:var(--himg);flex:0 0 var(--himg)}
  .hdr .crest{padding:calc(var(--himg) * .1)}
  .hdr .who .fn{font-size:17px;font-weight:500;line-height:1.1;color:var(--onband-dim)}
  /* Saira Condensed stands .052 of its size higher on its line than Barlow
     Condensed did (01-type-and-palette.css). At this size that is 2px nearer
     the first name and 2px further from the facts, on the page and in every
     downloaded card, so the name is set back down by it. */
  .hdr .who h1{position:relative;top:.052em;font-family:var(--font-display);font-weight:700;font-size:40px;line-height:1;letter-spacing:.005em}
  .hdr .who .tag{vertical-align:8px;font-family:var(--font-body);font-weight:600;font-size:11px}
  .hdr .who .facts{margin-top:6px;font-size:15px;font-weight:600;line-height:1.25}
  /* A narrow screen may break the line after a bullet (it is glued to the
     fact before it, so no line starts with one), never inside a fact
     ("201 lb" stays whole). */
  .hdr .who .facts i{font-style:normal;margin:0 3px;opacity:.45}
  .hdr .who .facts span{white-space:nowrap}
  .hdr .who .facts .dy{color:var(--brand-text)}
  .hdr .who .sub{margin-top:4px;font-size:13.5px}
  .bio{gap:9px 30px;padding-bottom:11px}
  .bio > div{display:flex;flex-direction:column;gap:2px;min-width:0}
  .bio .k{font-size:11px;letter-spacing:.07em;text-transform:uppercase;color:var(--muted);line-height:1.2}
  .bio b{font-size:14.5px;line-height:1.25}
  /* A phone has no room for two images the height of the name block: they
     would squeeze the text taller than themselves. The photo still matches
     it; the crest becomes a small badge in the band's top corner (the band
     keeps the crest's colour). */
  @media(max-width:560px){
    .hdr{position:relative;padding:13px 14px;gap:12px;--himg:clamp(56px, var(--hsz,96px), 116px)}
    .hdr .crest{position:absolute;top:12px;right:12px;width:40px;height:40px;flex:none;padding:4px;border-radius:7px}
    .hdr .who{padding-right:44px}
    .hdr .who .fn{font-size:14px}
    .hdr .who h1{font-size:30px}
    .hdr .who .facts{font-size:13px}
    .hdr .who .facts i{margin:0 2px}
    .bio{gap:8px 20px}
  }
  /* (patch-card-nhl-logos.mjs) The NHL club holding a player's rights, in
     the cell's top-right corner (with a goalie's START tag after it). The
     names make room; the details line runs the cell's full width under it.
     As big as the cell allows, by the cell's own width (a container query:
     the same screen can hold cells of different widths, and a phone draws
     them 720px wide and zooms). The logos are cropped to what is drawn
     (scripts/fetch-nhl-logos.mjs), so the box is the logo. Measured, 26
     September 2026: under 210px (1100px screens) the names had 28px to
     spare; at 216-236px (1920, 1280) about 60; at 343px (1600) the details
     line had 120, room for a logo the height of all three lines. */
  .lvc{container:lvcell / inline-size}
  .lvtop.hasnhl .lvwho{position:relative}
  .lvcorner{position:absolute;top:0;right:0;display:flex;align-items:center}
  /* A very narrow cell (a tablet upright: about 150px): the logo on the
     first-name line only, where names are short, so the surname keeps the
     whole width ("BRYZGALOV" was cut to "BRYZ..." beside a two-line logo). */
  .lvnhl{display:block;width:21px;height:12px;object-fit:contain;object-position:right center}
  .lvtop.hasnhl .lvfirst{margin-right:24px}
  @container lvcell (min-width:180px){
    .lvtop.hasnhl:not(.hastag) .lvnhl{width:34px;height:26px}
    .lvtop.hasnhl:not(.hastag) .lvfirst, .lvtop.hasnhl:not(.hastag) .lvlast{margin-right:38px}
  }
  @container lvcell (min-width:210px){
    .lvtop.hasnhl:not(.hastag) .lvnhl{width:44px;height:31px}
    .lvtop.hasnhl:not(.hastag) .lvfirst, .lvtop.hasnhl:not(.hastag) .lvlast{margin-right:48px}
  }
  @container lvcell (min-width:230px){
    .lvtop.hasnhl:not(.hastag) .lvnhl{width:52px;height:33px}
    .lvtop.hasnhl:not(.hastag) .lvfirst, .lvtop.hasnhl:not(.hastag) .lvlast{margin-right:56px}
  }
  /* A wide cell: the logo the height of all three lines, centred down the
     name block, and the details line makes room too. */
  @container lvcell (min-width:300px){
    .lvtop.hasnhl:not(.hastag) .lvcorner{top:50%;transform:translateY(-50%)}
    .lvtop.hasnhl:not(.hastag) .lvnhl{width:72px;height:46px}
    .lvtop.hasnhl:not(.hastag) .lvfirst, .lvtop.hasnhl:not(.hastag) .lvlast,
    .lvtop.hasnhl:not(.hastag) .lvdet{margin-right:78px}
  }
  /* A starting goalie: his START tag keeps the cell's corner on the first-name
     line, as it always has; the logo sits under it, beside the surname, so
     only the surname makes room -- and a long one (Ivan Tkach-Tkachenko)
     is not cut for the tag and the logo both. */
  /* In a very narrow cell (a tablet upright) the surname can't spare even
     that: the logo goes left of the tag on the first-name line, and a long
     first name is the one shortened (Brady Knowling's surname stays whole). */
  .lvtop.hasnhl.hastag .lvcorner{top:0;right:40px}
  .lvtop.hasnhl.hastag .lvnhl{width:19px;height:12px}
  .lvtop.hasnhl.hastag .lvfirst{margin-right:63px}
  .lvtop.hasnhl.hastag .lvlast{margin-right:0}
  @container lvcell (min-width:180px){
    .lvtop.hasnhl.hastag .lvcorner{top:14px;right:0}
    .lvtop.hasnhl.hastag .lvnhl{width:28px;height:18px}
    .lvtop.hasnhl.hastag .lvfirst{margin-right:0}
    .lvtop.hasnhl.hastag .lvlast{margin-right:31px}
  }
  /* (patch-card-nhl-crest.mjs) The NHL box beside the crest: its twin on a PC;
     on a phone the two corner badges side by side, NHL outermost. */
  @media(max-width:560px){
    .hdr.hasnhl .crest{right:58px}
    .hdr.hasnhl .crest.nhlcrest{right:12px}
    /* The badges sit beside the first name and surname only; the facts and
       the club line run below them, so they keep the full width (a whole
       block kept clear wrapped the facts onto three lines). The same for a
       card with the crest alone. */
    .hdr .who{padding-right:0}
    .hdr .who .fn, .hdr .who h1{margin-right:44px}
    .hdr.hasnhl .who .fn, .hdr.hasnhl .who h1{margin-right:94px}
  }
  /* (patch-card-lines-top-bar.mjs) The Lines tab's settings bar. */
  .lnbar{position:relative;align-items:flex-end;gap:14px 22px}
  .lnf{display:flex;flex-direction:column;gap:5px}
  .lnfl{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
  .lnbar .seg{margin:0}
  .lnbar .seg button{padding:7px 16px}
  .lnbar .lnday{margin:0;gap:8px}
  .lnbar .lnday span{flex:0 0 auto;min-width:92px}
  .lnbar .lnday button{padding:7px 12px}
  .lnbar button{margin-left:0}
  .lndl{position:relative}
  #lnDlBtn{display:inline-flex;align-items:center;gap:10px;padding:7px 12px}
  #lnDlBtn .car{font-size:10px;color:var(--muted);transition:transform .15s}
  .lndl.open #lnDlBtn .car{transform:rotate(180deg)}
  .lndlpanel{position:absolute;top:calc(100% + 6px);left:0;z-index:40;width:300px;padding:10px;
             background:var(--surface);border:1px solid var(--box);border-radius:10px;box-shadow:0 12px 30px rgba(0,0,0,.45)}
  .lndlpanel .lnpick{max-height:min(420px, 60vh)}
  /* The picker's rows are labels, which the bar styles as small uppercase
     columns (.lbbar label): put them back as the picker drew them. */
  .lnbar .lnpick label{flex-direction:row;align-items:center;gap:8px;font-size:13px;letter-spacing:0;
                       text-transform:none;color:var(--ink)}
  .lnacts2{margin-left:auto}
  .lnacts2 button{margin-left:0}
  #mode-lines .lnhow{margin:-2px 2px 12px}
  /* A phone: the bar's groups one under another, the picker as wide as the bar. */
  /* Download and the PDF button share a row; the note stays off a phone, as
     it was when it sat inside the rail's closed box. */
  @media(max-width:700px){
    .lnbar{gap:12px}
    .lnf:not(.lndl){width:100%}
    .lnbar .seg{display:flex}
    .lnbar .seg button{flex:1;padding:8px 6px}
    .lnbar .lnday span{flex:1}
    .lndl{position:static;flex:1}
    #lnDlBtn{width:100%;justify-content:space-between}
    .lndlpanel{left:14px;right:14px;width:auto}
    .lnacts2{margin-left:0}
    #mode-lines .lnhow{display:none}
  }
  /* (patch-card-lines-compact.mjs) Side by side below 1360px: smaller cells,
     so each details line still fits whole in a column a third of half the
     list. */
  @container lnview (min-width:1150px) and (max-width:1359px){
    .lvteams{gap:18px}
    .lvrow, .lvsec{grid-template-columns:18px repeat(3,minmax(0,1fr));gap:5px}
    .lvrow.two{grid-template-columns:18px repeat(2,minmax(0,1fr))}
    .lvrow + .lvrow{margin-top:5px}
    .lvlab{font-size:12px}
    .lvtop{gap:6px;padding:4px 6px 3px}
    .lvnum{flex-basis:25px;font-size:23px}
    .lvfirst{font-size:11px}
    .lvlast{font-size:15px}
    .lvdet{font-size:9.6px}
    .lvdet i{padding:0 2px}
    .lvdet .dy{padding:0 4px;font-size:9.5px;line-height:13px}
    .lvstats span{font-size:11px;gap:4px}
    .lvstats i{font-size:9px}
  }
  /* (patch-card-top-bars.mjs) On a phone the rail reads as before: each
     heading is now the first thing in its group, which the rail's own rule
     (h2:first-child) left with no gap above it; every one but the rail's
     first gets it back. */
  @media(max-width:860px){
    .rail .tbf + .tbf > h2, .rail .tbf + div > .tbf:first-child > h2,
    #radarOnly > .tbf:first-child > h2, #scatterOnly > .tbf:first-child > h2{margin-top:20px}
  }
  /* (patch-card-top-bars.mjs) Every tab but the card (#mode-card, 1560) may
     run to 2080px, as Lines does. */
  .wrap.tb{max-width:2080px}
  /* Season Stats and Percentiles take the window's whole width (William, 8
     October 2026: "yes, use the full width"). They stopped at 2080px too,
     which on a 2,560px screen left 240px of nothing either side of a table
     that was scrolling sideways. With the letters grown that day (styles/
     21-controls.css) Season Stats' widest table is 2,445px: it fits such a
     screen whole now, and did not at 2080. */
  /* And Team Stats, its team twin (staging, 17 October 2026: "any way we can make team stats table wider like
     player stats table?"). */
  #mode-stats, #mode-leaderboard, #mode-teamstats{max-width:none}
  /* (patch-card-top-bars.mjs) Every tab's settings across the top on a PC. */
  @media(min-width:861px){
    .wrap.tb{flex-direction:column;align-items:stretch;gap:12px}
    /* The groups and the export row flow as one line of items, wrapping, so
       the buttons take the end of the last line rather than a column. */
    .wrap.tb > .rail{width:auto;flex:none;position:relative;top:auto;display:flex;flex-wrap:wrap;
                     align-items:flex-end;gap:12px 22px;padding:12px 14px}
    .wrap.tb .railbody{display:contents}
    .wrap.tb .railacts{flex:0 0 auto;margin:0 0 0 auto;padding:0;border:0;align-self:flex-end}
    .wrap.tb #scScale{margin-bottom:0}
    .tbf{display:flex;flex-direction:column;gap:6px;min-width:0;position:relative}
    .wrap.tb .rail .tbf > h2{margin:0;font-size:11px}
    .tbc{display:flex;flex-wrap:wrap;align-items:center;gap:8px}
    .wrap.tb .rail .tbc select, .wrap.tb .rail .tbc input[type=text]{width:auto;min-width:130px;margin:0}
    .wrap.tb .rail .tbc .seg{margin:0}
    .wrap.tb .rail .tbc .seg button{padding:7px 14px;white-space:nowrap}
    .wrap.tb .rail button.wide{width:auto;margin:0}
    .wrap.tb .rail .row{margin:0}
    .tbc .chips{flex-basis:100%;margin:0}
    .wrap.tb .pslot{margin:0}
    .wrap.tb .pslot input{min-width:210px}
    .wrap.tb .slot{margin:0}
    .tbc #trSlots, .tbc #rdSlots{display:flex;flex-wrap:wrap;gap:8px}
    #radarOnly:not([hidden]), #scatterOnly:not([hidden]){display:contents}
    #scatterOnly > h2:first-child, #radarOnly > h2:first-child{margin-top:0}
    /* Search results open over the page, under their box. */
    .wrap.tb .rdhits{position:absolute;top:calc(100% + 4px);left:0;z-index:40;width:340px;
             max-height:min(420px, 55vh);margin:0;background:var(--surface);border:1px solid var(--box);
             border-radius:8px;box-shadow:0 12px 30px rgba(0,0,0,.45)}
    /* The charts were capped at 1000px to sit beside the rail; the width the
       rail gave back is theirs now. */
    .wrap.tb .scpanel{max-width:none}
    /* An empty trajectory (no player yet) is a bare canvas, whose default
       2:1 shape grew with the width into a screen-tall blank; a drawn one is
       420px high (trPlot sets it inline, which wins), so the empty one is too. */
    .wrap.tb #trCanvas{height:420px}
    /* Compare was capped at 1120px to sit beside the rail; its two cards share
       the whole width now, and their bars grow with it. */
    .wrap.tb #compare{max-width:none}
  }
  /* (patch-card-scatter-square.mjs) The square scatter, centred in its panel. */
  #scCanvas{margin:0 auto}
  /* (patch-card-chart-bars.mjs) The X and Y labels are for the bar only. */
  .axl{display:none}
  /* (patch-card-chart-bars.mjs) The Charts bar in three rows on a PC: the
     row both charts share, what's plotted, who's shown. */
  @media(min-width:861px){
    #mode-chart.tb > .rail{row-gap:8px}
    #mode-chart.tb > .rail::before, #mode-chart.tb > .rail::after{content:"";flex:0 0 100%;height:0;
             border-top:1px solid var(--line)}
    #mode-chart.tb > .rail::before{order:6}
    #mode-chart.tb > .rail::after{order:9}
    /* Row 1, the same on both charts. */
    #mode-chart .tbf:has(#scView){order:1}
    #mode-chart .tbf:has(.lgPick){order:2}
    #mode-chart .tbf:has(.modeseg){order:3}
    #mode-chart .tbf:has(#scGroup), #mode-chart .tbf:has(#rdGroup){order:4}
    #mode-chart .tbf.sitf{order:5}
    #mode-chart .railacts{order:5}
    /* Row 2, what's plotted. */
    #mode-chart .scscale, #mode-chart .scaxes, #mode-chart .rdplayers{order:7}
    /* Row 3, who's shown. */
    #mode-chart .tbf:has(#scSeason), #mode-chart .tbf:has(#scQ), #mode-chart .scclr,
    #mode-chart .rdstats{order:10}
    /* The empty group the top-bars patch left between the two boxes. */
    #mode-chart #radarOnly + .tbf{display:none}
    #mode-chart .scclr{margin-left:auto}
    #mode-chart .axl{display:inline;font-size:11px;letter-spacing:.08em;color:var(--muted)}
    #mode-chart .scaxes .axl + select{margin-left:-2px}
    #mode-chart .swl{display:none}
    #mode-chart #scSwap{padding:7px 11px}
    /* The radar's players share the row; its stats are a 4 x 2 grid. */
    #mode-chart .rdplayers, #mode-chart .rdstats{flex:1 1 100%}
    #mode-chart .rdplayers .tbc{flex-wrap:nowrap}
    #mode-chart .rdplayers .pslot{flex:1 1 0;min-width:0}
    #mode-chart .rdplayers .pslot input{min-width:0}
    #mode-chart #rdClear{flex:none}
    #mode-chart .tbc #rdSlots{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px 12px;flex:1 1 100%}
    #mode-chart #rdSlots select{min-width:0}
  }
  /* (patch-card-trajectory-bar.mjs) The Trajectory bar in two rows on a PC:
     who and what, then the stats. */
  @media(min-width:861px){
    #mode-trajectory.tb > .rail{row-gap:8px}
    #mode-trajectory.tb > .rail::after{content:"";flex:0 0 100%;height:0;order:6;
             border-top:1px solid var(--line)}
    #mode-trajectory .tbf:has(.lgPick){order:1}
    #mode-trajectory .tbf:has(.modeseg){order:2}
    #mode-trajectory .tbf.sitf{order:2}
    #mode-trajectory .tbf:has(#trQ){order:3;flex:1 1 240px;max-width:420px}
    #mode-trajectory .tbf:has(#trClass){order:4}
    #mode-trajectory .railacts{order:5}
    #mode-trajectory .trstats{order:7;flex:1 1 100%}
    #mode-trajectory .tbf:has(#trQ) .pslot{flex:1 1 auto;min-width:0}
    #mode-trajectory .tbf:has(#trQ) .pslot input{min-width:0}
    #mode-trajectory .trstats .tbc{flex-wrap:nowrap}
    #mode-trajectory .tbc #trSlots{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px 12px;flex:1 1 auto}
    #mode-trajectory #trSlots select{min-width:0}
    #mode-trajectory #trClear{flex:none}
  }
  /* (patch-card-compare-bar.mjs) The Compare bar in two rows on a PC: the
     season type, then each side over its own card. */
  @media(min-width:861px){
    #mode-compare.tb > .rail{row-gap:8px}
    #mode-compare.tb > .rail::after{content:"";flex:0 0 100%;height:0;order:3;
             border-top:1px solid var(--line)}
    #mode-compare .cmpmode{order:1}
    #mode-compare .sitf{order:1}
    #mode-compare .railacts{order:2}
    /* The two sides share the row; B starts where its card does, past the
       cards' 66px middle column, with a rule down the middle of it. */
    #mode-compare .cmpside{order:4;flex:1 1 0;min-width:0}
    #mode-compare .cmpside + .cmpside{margin-left:22px;padding-left:22px;border-left:1px solid var(--line)}
    #mode-compare .cmpside .tbc{display:grid;gap:8px;
             grid-template-columns:minmax(0,.8fr) minmax(0,.9fr) minmax(0,1.3fr) minmax(0,1fr)}
    #mode-compare .cmpside .tbc select, #mode-compare .cmpside .tbc input{min-width:0;width:100%}
    #mode-compare .cmpside .sQ{grid-row:2;grid-column:1 / 3}
    #mode-compare .cmpside .sPlayer{grid-row:2;grid-column:3 / 5}
  }
  @media(min-width:861px){
    /* (patch-card-profile-bar.mjs) Every tab's bar: menus as tall as the
       boxes and buttons beside them (they were 37px against 35). */
    .wrap.tb .rail .tbc select{height:35px}
  }
  /* (patch-card-scatter-side.mjs) The scatter's side column. */
  #scPanel .scplot.withside{display:flex;justify-content:center;align-items:flex-start;gap:28px}
  #scPanel .scplot.withside #scCanvas{margin:0;flex:none}
  .scside{flex:0 0 320px;width:320px;font-size:12px;color:var(--muted)}
  .scside.below{width:auto;max-width:560px;margin:16px auto 0}
  .scside .sshead{font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--ink);font-weight:600;margin:0 0 2px}
  .scside .ssnote{font-size:11px;margin:0 0 8px}
  /* Beside the square the column is a fixed height (set in scPaintSide), the
     list at its top and By quarter pushed to its bottom. */
  #scPanel .scplot.withside .scside{display:flex;flex-direction:column;overflow:hidden}
  .scside .ssqwrap{margin-top:auto;padding-top:16px}
  .sstop{width:100%;border-collapse:collapse;table-layout:fixed}
  .sstop th{font-size:10px;font-weight:600;text-align:right;padding:0 0 4px;color:var(--muted);font-family:var(--font-body)}
  .sstop th:nth-child(2){text-align:left}
  .sstop td{padding:4px 0;border-top:1px solid var(--line);vertical-align:middle}
  .sstop tr[data-name]{cursor:pointer}
  .sstop tr[data-name]:hover td{background:rgba(255,255,255,.04)}
  .sstop tr.on b{color:var(--ink)}
  .sstop .ssn{width:20px;font-variant-numeric:tabular-nums}
  .sstop th:first-child{width:20px}
  .sstop th:nth-child(3), .sstop th:nth-child(4){width:48px}
  /* One line a player, so twenty fit: the name, then team and position in
     grey; a name too long for the column ends in an ellipsis. */
  .sstop .ssp{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .sstop .ssp b{font-weight:600;color:var(--ink);font-size:12.5px}
  .sstop .ssp span{font-size:10.5px;margin-left:3px}
  .sstop .ssv{text-align:right;font-variant-numeric:tabular-nums;color:var(--ink);padding-left:8px}
  .sstop .ssnone{padding:10px 0}
  .ssdot{display:inline-block;width:8px;height:8px;border-radius:50%;margin-right:5px;vertical-align:1px}
  .ssquad{display:grid;grid-template-columns:18px 1fr 1fr;grid-template-rows:auto auto auto;gap:4px}
  .ssquad .ssy{grid-row:1 / 3;grid-column:1;writing-mode:vertical-rl;transform:rotate(180deg);text-align:center;font-size:10px}
  .ssquad .ssx{grid-column:2 / 4;text-align:center;font-size:10px}
  .ssq{border:1px solid var(--line);border-radius:6px;padding:7px 8px;display:flex;flex-direction:column;gap:1px}
  .ssq b{font-size:16px;color:var(--ink);font-variant-numeric:tabular-nums}
  .ssq span{font-size:10.5px}
  .ssq.tr{border-color:var(--box)}
  /* ---------- the site header (redesign step 5) ----------
     A strip of the brand orange, then a header on the panel gray, all on one
     level: the name, search, the menu, and the X account at the far right.
     The page you are on is filled orange with dark text on it (white on
     this orange is too faint to read).

     The header is the full width of the window on every tab. The row of
     tabs it replaced widened and narrowed with the tab's own content; a
     header that did that would move the logo every time you changed page. */
  .hdstrip{height:4px;background:var(--brand)}
  .sitehead{background:var(--surface);border-bottom:1px solid var(--line)}
  .sitehead .head{position:relative;display:flex;align-items:center;gap:8px 20px;min-height:64px;padding:8px 20px}

  .hdlogo{flex:0 0 auto;display:flex;align-items:center;gap:9px;min-height:44px;color:#fff;text-decoration:none;border-radius:8px}
  /* The mark before the name (8 October 2026): 1.35 times as tall as the
     name's capitals and centred on them, in the orange for something filled.
     Its width is its height times 46.3 / 53.96, the drawing's own shape. */
  .hdmark{flex:none;width:22.3px;height:26px;fill:var(--brand)}
  .hdlogo span{font-family:var(--font-display);font-weight:700;font-size:28px;line-height:1;letter-spacing:.03em;text-transform:uppercase;white-space:nowrap}
  .hdlogo:focus{outline:none}
  .hdlogo:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}

  /* It gives way first when the row is tight: 300px down to 200. */
  .hdsearch{position:relative;flex:0 1 300px;min-width:200px}
  .hdfield{display:flex;align-items:center;gap:10px;height:40px;padding:0 14px;background:var(--bg);
           border:1px solid var(--line);border-radius:20px;color:var(--muted);cursor:text}
  .hdfield svg{flex:none;width:16px;height:16px}
  .hdfield input{flex:1;min-width:0;padding:0;border:0;outline:0;background:transparent;color:var(--ink);
                 font:inherit;font-size:14px;-webkit-appearance:none;appearance:none}
  .hdfield input::-webkit-search-cancel-button{display:none}
  .hdfield:focus-within{border-color:var(--brand-text);box-shadow:0 0 0 2px rgba(255,138,61,.3)}
  /* What the search found: a list under the box, over the page, and wider
     than the box when the box is narrow. */
  .hdhits{position:absolute;left:0;top:100%;margin-top:6px;z-index:80;width:max(100%,340px);max-width:calc(100vw - 24px);
          max-height:min(70vh,520px);overflow-y:auto;background:var(--surface);border:1px solid var(--box);border-radius:10px;
          box-shadow:0 12px 30px rgba(0,0,0,.5)}
  .hdhit{display:flex;align-items:baseline;justify-content:space-between;gap:12px;width:100%;padding:10px 14px;border:0;
         border-radius:0;background:transparent;font:inherit;font-size:14px;color:var(--ink);text-align:left;cursor:pointer}
  .hdhit + .hdhit{border-top:1px solid var(--line)}
  .hdhit:hover,.hdhit.on{background:var(--surface2)}
  .hdhit:focus{outline:none}
  .hdhit b{font-weight:600;color:#fff}
  .hdhit span{flex:none;color:var(--muted);font-size:12.5px;white-space:nowrap}
  /* A club in the search: its crest before its name (17 October 2026). */
  .hdclub b{display:flex;align-items:center;gap:8px}
  .hdclub .tcrest{flex:none;width:20px;height:20px;object-fit:contain}
  .hdclub{align-items:center}
  .hdnote{padding:10px 14px;color:var(--muted);font-size:12.5px}
  .hdhits .hdnote + .hdhit,.hdhits .hdhit + .hdnote{border-top:1px solid var(--line)}

  /* The menu. Still the tabs, restyled: capitals in the display face, each
     as wide as its name, taking whatever of the row is left. */
  /* It never shrinks: squeezed, its last item ran under what follows it. The
     search is what gives way. */
  .sitehead .tabs{flex:1 0 auto;display:flex;flex-wrap:nowrap;gap:2px}
  .sitehead .tab{flex:0 0 auto;display:flex;align-items:center;min-height:40px;padding:0 12px;border:0;border-radius:8px;
                 background:transparent;font-family:var(--font-display);font-size:16px;line-height:1.2;font-weight:600;letter-spacing:.06em;
                 text-transform:uppercase;color:var(--ink2);white-space:nowrap;cursor:pointer}
  .sitehead .tab:hover{background:var(--surface2);color:#fff}
  .sitehead .tab.on{background:var(--brand);color:var(--on-brand);font-weight:700}
  .sitehead .tab:focus{outline:none}
  .sitehead .tab:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}
  .sitehead .tab.on:focus-visible{box-shadow:0 0 0 2px var(--surface),0 0 0 4px var(--brand-text)}

  /* An item that is a list (the first was Leaderboards, 7 October 2026;
     since 19 October 2026 the menu is four of them: Games, Players, Teams,
     Charts): one item of the menu that opens its pages under it. It looks like a
     tab, with a small arrow, and is lit when the page in use is one of
     its pages: the stylesheet sees that for itself (:has), so it is right
     from the first moment, before any code has run. The list is over the
     page, like the search's. */
  .sitehead .tabgrp{position:relative;flex:0 0 auto;display:flex}
  .sitehead .tabgrpbtn{display:flex;align-items:center;gap:7px;min-height:40px;padding:0 11px 0 12px;border:0;border-radius:8px;
                 background:transparent;font-family:var(--font-display);font-size:16px;line-height:1.2;font-weight:600;letter-spacing:.06em;
                 text-transform:uppercase;color:var(--ink2);white-space:nowrap;cursor:pointer}
  .sitehead .tabgrpbtn svg{flex:none;width:10px;height:10px}
  .sitehead .tabgrp.open .tabgrpbtn svg{transform:rotate(180deg)}
  .sitehead .tabgrpbtn:hover,.sitehead .tabgrp.open .tabgrpbtn{background:var(--surface2);color:#fff}
  .sitehead .tabgrp:has(.tab.on) .tabgrpbtn{background:var(--brand);color:var(--on-brand);font-weight:700}
  .sitehead .tabgrpbtn:focus{outline:none}
  .sitehead .tabgrpbtn:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}
  .sitehead .tabgrp:has(.tab.on) .tabgrpbtn:focus-visible{box-shadow:0 0 0 2px var(--surface),0 0 0 4px var(--brand-text)}
  .sitehead .tabdrop{display:none;position:absolute;left:0;top:100%;z-index:85;min-width:100%;margin-top:6px;padding:6px;flex-direction:column;gap:2px;
                 background:var(--surface);border:1px solid var(--box);border-radius:10px;box-shadow:0 12px 30px rgba(0,0,0,.5)}
  .sitehead .tabgrp.open .tabdrop{display:flex}
  .sitehead .tabdrop .tab{width:100%;justify-content:flex-start}

  /* The X mark, at the far right whatever the menu leaves. */
  .hdx{flex:0 0 auto;margin-left:auto;display:flex;align-items:center;justify-content:center;width:40px;height:40px;border-radius:8px;color:var(--ink2)}
  .hdx svg{width:18px;height:18px}
  /* The second account's mark stands close against the first: the two read
     as a pair, and only the first is pushed to the row's far right. The
     row's own gap between two things is 20px; all but 4 are taken back. */
  .hdx + .hdx{margin-left:-16px}
  .hdig svg{width:19px;height:19px}
  .hdx:hover{background:var(--surface2);color:#fff}
  .hdx:focus{outline:none}
  .hdx:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}

  /* The menu button is a phone's. */
  .tabmenu{display:none}
  /* Every tool starts as far under the header as every other: the wrapper's
     own padding (.wrap, styles/01-type-and-palette.css), 20px, and 12 on a
     narrow screen. The profile had a rule of its own here, 14px, left from
     the old row of tabs; William saw the difference between pages (7
     October 2026: "make it the same across all pages"), and it went. */

  /* Narrower than the row needs with the search at its smallest: the name,
     search and the two marks stay on the first line and the menu takes a
     second one to itself. It was 1079px with one mark; the second mark is
     44px more of row (itself and the 4px before it), and measured at
     1100px the row then ran 7px past its right edge.
     The logo's mark (8 October 2026) is 31px more again, and the width
     stayed: the site's face had become a narrower one the same day, and
     measured at 1130px the row fits with the search still 245px wide.
     Four items since 19 October 2026 (Games, Players, Teams, Charts: 362px
     of menu, where the six were some 600): the row needs 891px with the
     search at its smallest, so one row from 920px of window, a scrollbar
     included. */
  @media(max-width:919px){
    .sitehead .head{flex-wrap:wrap}
    .hdsearch{flex:1 1 240px;max-width:520px}
    .sitehead .tabs{order:9;flex:1 0 100%;flex-wrap:wrap}
  }

  /* A phone: the name, X and the menu button, then the search. The menu
     drops from under the first row, over the page. */
  @media(max-width:700px){
    .sitehead .head{display:grid;grid-template-columns:minmax(0,1fr) auto auto auto;
                    grid-template-areas:"logo x ig menu" "search search search search";gap:8px;min-height:0;padding:8px 12px 10px}
    /* The logo is its mark and its name here too, a size smaller than on a
       wide screen so that the row keeps room for the page's name: the name
       22px, the mark 21 tall (18 wide), 6 between them: 114 in all. */
    .hdlogo{grid-area:logo;gap:6px}
    .hdlogo span{font-size:22px}
    .hdmark{width:18px;height:21px}
    /* Two marks now, each a column of its own, 40 wide and pulled together
       so the pair costs the row 76px: the logo keeps its width, and the
       menu button its name. */
    .hdx{grid-area:x;margin-left:0;width:40px;height:44px}
    .hdx.hdig{grid-area:ig;margin-left:-4px}
    .hdsearch{grid-area:search;min-width:0;max-width:none}
    .hdfield{height:44px;border-radius:22px}
    /* 16px or iOS zooms the whole page the moment a field takes focus. */
    .hdfield input{font-size:16px}
    .hdhits{width:auto;right:0}
    /* The button names the page it is on, in the menu's own letters, then the
       three bars (the label is shown by tabTo(); until then, and on the
       not-found page, the button is the bars alone, 44px square). A long
       name gives way before the logo does. */
    .sitehead .tabmenu{grid-area:menu;display:flex;align-items:center;justify-content:center;gap:9px;min-width:44px;height:44px;padding:0 12px;
                       background:transparent;color:var(--ink);border:1px solid var(--line);border-radius:8px;cursor:pointer}
    .sitehead .tabmenu svg{flex:none;width:18px;height:18px}
    /* The name may be as wide as leaves the logo its mark and words: the
       screen, less the row's padding (24) and gaps (20), the two accounts'
       marks (80), the logo (114) and what the button is besides its name
       (53). The longest name, PERCENTILES, is 79 wide. */
    .sitehead .tabmenu .lbl:not(.sr){max-width:calc(100vw - 291px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
                       font-family:var(--font-display);font-weight:600;font-size:15px;letter-spacing:.06em;text-transform:uppercase;color:#fff}
    .sitehead .head.menu-open .tabmenu{border-color:var(--brand-text);color:var(--brand-text)}
    /* A narrow phone: each account's mark gives 4px and the logo is a size
       smaller (the name 20px, its mark 19 tall: 104 in all), which is what
       PERCENTILES needs at 360px. A very narrow one (320px, the narrowest
       there is): the logo smaller again (18px and 17 tall, 4 between: 92),
       and the longest names end in "…". */
    @media(max-width:380px){
      .hdx{width:36px}
      .hdlogo span{font-size:20px}
      .hdmark{width:16.3px;height:19px}
      .sitehead .tabmenu .lbl:not(.sr){max-width:calc(100vw - 273px)}
    }
    @media(max-width:340px){
      .hdlogo{gap:4px}
      .hdlogo span{font-size:18px}
      .hdmark{width:14.6px;height:17px}
      .sitehead .tabmenu .lbl:not(.sr){max-width:calc(100vw - 261px)}
    }
    .sitehead .tabs{display:none}
    .sitehead .head.menu-open .tabs{display:flex;flex-direction:column;flex-wrap:nowrap;gap:0;position:absolute;left:12px;right:12px;
                                    top:58px;z-index:90;padding:0;overflow:hidden auto;max-height:calc(100vh - 70px);background:var(--surface);border:1px solid var(--box);
                                    border-radius:10px;box-shadow:0 12px 30px rgba(0,0,0,.5)}
    .sitehead .head.menu-open .tab{width:100%;min-height:48px;padding:0 16px;border-radius:0;font-size:17px}
    .sitehead .head.menu-open .tab + .tab,.sitehead .head.menu-open .tabgrp + .tab,.sitehead .head.menu-open .tabgrp + .tabgrp{border-top:1px solid var(--line)}
    /* An item that is a list, in a menu that is a list already: a heading
       over its pages, which are in the list like every other page. Not
       something to press here. */
    .sitehead .head.menu-open .tabgrp{display:block}
    .sitehead .head.menu-open .tabgrpbtn,.sitehead .head.menu-open .tabgrp:has(.tab.on) .tabgrpbtn{width:100%;min-height:0;padding:12px 16px 6px;border-radius:0;
                       background:transparent;font-size:12px;font-weight:600;letter-spacing:.1em;color:var(--muted);pointer-events:none}
    .sitehead .head.menu-open .tabgrpbtn svg{display:none}
    .sitehead .head.menu-open .tabdrop{display:flex;position:static;min-width:0;margin:0;padding:0;gap:0;border:0;border-radius:0;background:transparent;box-shadow:none}
    .sitehead .head.menu-open .tab.on{background:var(--brand);color:var(--on-brand)}
  }
  /* ---------- the site footer (redesign step 6) ----------
     A band on the panel gray across the whole window, as the header is: the
     two frame the page. Column headings in the orange for text; links plain
     until pointed at. Outside every tab and every card, so the PNG export
     never sees it. */
  .sitefoot{margin-top:36px;background:var(--surface);border-top:1px solid var(--line);font-size:14px;line-height:1.45;color:var(--ink2)}
  .ftin{display:flex;flex-direction:column;gap:22px;padding:30px 20px 26px}
  .ftcols{display:grid;grid-template-columns:minmax(220px,1.7fr) repeat(6,minmax(120px,1fr));gap:24px 32px}

  .ftbrand{display:flex;flex-direction:column;align-items:flex-start;gap:8px}
  .ftname{display:flex;align-items:center;gap:8px;font-family:var(--font-display);font-weight:700;font-size:24px;line-height:1;letter-spacing:.03em;text-transform:uppercase;
          color:#fff;text-decoration:none;border-radius:6px}
  /* The mark before the name, as in the header: 1.35 times as tall as the
     capitals, in the orange for something filled. */
  .ftmark{flex:none;width:19px;height:22px;fill:var(--brand)}
  .ftbrand p{margin:0;max-width:300px;color:var(--muted);font-size:13px}

  .ftcol{display:flex;flex-direction:column;align-items:flex-start}
  .ftcol h2{margin:0 0 6px;font-size:11px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--brand-text)}
  .ftcol a{display:flex;align-items:center;min-height:32px;color:var(--ink2);text-decoration:none;border-radius:6px}
  .ftcol a:hover{color:#fff;text-decoration:underline}
  .ftname:focus,.ftcol a:focus{outline:none}
  .ftname:focus-visible,.ftcol a:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}

  .ftnote{margin:0;padding-top:16px;border-top:1px solid var(--line);color:var(--muted);font-size:12.5px;line-height:1.6}
  .ftnote b{color:var(--ink2);font-weight:600}

  /* Narrower: the name on a line of its own, the columns two abreast. Six
     columns of 120px and the name's 220 need about 1,170px of window
     (19 October 2026; with five it was about 1,000, and the page scrolled
     sideways from 900 to there). */
  @media(max-width:1180px){
    .ftcols{grid-template-columns:repeat(2,minmax(0,1fr))}
    .ftbrand{grid-column:1 / -1}
  }
  /* A phone: the page's own margins, and links tall enough for a thumb. */
  @media(max-width:700px){
    .sitefoot{margin-top:28px}
    .ftin{padding:24px 12px 28px}
    .ftcol a{min-height:40px}
  }
  /* ---------- the front page ----------
     A grid of panels, one a feature of the site (body/00b-home.html): two
     abreast on a wide screen, one under another on a narrow one. Each
     panel is its name, a line on what it does, a preview, and its buttons
     at the foot, so the buttons of two panels side by side stand level.

     While it is the page on screen the body is a column as tall as the
     window, so the footer sits at the bottom of the window on a screen
     taller than the page.

     <html data-page="home"> is how a plain page is on screen
     (styles/17-site-pages.css). */
  html[data-page="home"] body{display:flex;flex-direction:column;min-height:100vh}
  html[data-page="home"] #mode-home{display:block!important;flex:1 0 auto}
  html[data-page="home"] .sitefoot{margin-top:0}

  .hmgrid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:20px;max-width:2080px;margin:0 auto;padding:24px 20px 44px}
  @media(max-width:1000px){ .hmgrid{grid-template-columns:minmax(0,1fr);gap:16px;padding:16px 12px 32px} }

  .hmp{display:flex;flex-direction:column;min-width:0;padding:18px 20px 16px;border:1px solid var(--box);border-radius:12px;background:var(--surface)}
  .hmhd{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}
  .hmhd h2{margin:0;font-family:var(--font-display);font-weight:700;font-size:26px;line-height:1.2;letter-spacing:.02em;text-transform:uppercase;color:#fff}
  .hmdesc{margin:6px 0 14px;font-size:15px;line-height:1.45;color:var(--muted);max-width:640px}
  .hmbody{flex:1 0 auto;min-height:120px}
  .hmft{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin-top:16px;padding-top:14px;border-top:1px solid var(--line)}

  /* The buttons: the tools' own look. One filled orange a panel, its way in. */
  .hmbtn{display:inline-flex;align-items:center;height:38px;padding:0 16px;border:1px solid var(--box);border-radius:8px;
         font-size:15px;font-weight:600;color:var(--ink);text-decoration:none;white-space:nowrap}
  .hmbtn > span{margin-left:.35em}             /* the "›": a flex box drops the space before it */
  .hmbtn:hover{border-color:var(--ink2);color:#fff}
  .hmbtn.primary{border-color:var(--brand);background:var(--brand);color:var(--on-brand)}
  .hmbtn.primary:hover{border-color:var(--brand-text);background:var(--brand-text);color:var(--on-brand)}
  .hmbtn:focus{outline:none}
  .hmbtn:focus-visible{box-shadow:0 0 0 2px var(--surface),0 0 0 4px var(--brand-text)}
  .hmhint{font-size:14px;color:var(--muted)}

  /* The Season Stats panel's league switch: the tools' switch, small. */
  .hmlgs{display:inline-flex;padding:3px;gap:2px;border-radius:9px;background:var(--bg);border:1px solid var(--line)}
  .hmlgs button{height:30px;padding:0 12px;border:0;border-radius:6px;background:none;font:inherit;font-size:13.5px;font-weight:600;
                letter-spacing:.03em;color:var(--muted);cursor:pointer}
  .hmlgs button:hover{color:#fff}
  .hmlgs button.on{background:var(--hover);color:#fff;box-shadow:inset 0 -2px 0 var(--brand)}
  .hmlgs button:focus{outline:none}
  .hmlgs button:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}

  /* What a preview is of, over it. */
  .hmcap{margin:0 0 8px;font-size:13px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--brand-text)}
  .hmnote{margin:8px 0;font-size:15px;line-height:1.5;color:var(--muted)}
  .hmnote a,.hmmore a{color:var(--brand-text)}
  .hmmore{margin:8px 0 0;font-size:13.5px;color:var(--faint)}

  /* A small table: the rank, the player with his club under his name, numbers. */
  .hmtbl{width:100%;border-collapse:collapse;font-size:15px}
  .hmtbl th{padding:0 8px 6px;font-family:var(--font-display);font-size:12.5px;font-weight:600;letter-spacing:.06em;text-align:left;
            color:var(--muted);border-bottom:2px solid var(--brand)}
  .hmtbl td{padding:6px 8px;border-bottom:1px solid var(--line);vertical-align:middle}
  .hmtbl tr:last-child td{border-bottom:0}
  .hmtbl tbody tr:hover td{background:var(--hover)}
  .hmtbl .r{width:28px;text-align:right;color:var(--faint)}
  .hmtbl .n{width:58px;text-align:right;white-space:nowrap;color:var(--ink2)}
  .hmtbl th.on{color:#fff}
  .hmtbl td.on{color:#fff;font-weight:700}
  .hmname{color:var(--brand-text);font-weight:600;text-decoration:none}
  .hmname:hover{color:#fff;text-decoration:underline;text-underline-offset:2px}
  .hmsub{display:block;margin-top:1px;font-size:12.5px;color:var(--faint)}
  .hmlg{display:inline-block;margin-right:6px;padding:0 5px;border:1px solid var(--line);border-radius:4px;font-size:11px;font-weight:600;
        letter-spacing:.04em;line-height:16px;color:var(--muted)}
  .hmpct{display:inline-block;min-width:34px;padding:2px 6px;border-radius:5px;font-weight:700;text-align:center}

  /* The leader's card, as a profile draws it: laid out 1,100px wide
     (HM_CARD_W in scripts/06i-home.js) and scaled to the panel by --hmz. A
     phone's is laid out as a phone's profile is, at its own width. */
  .hmfit{zoom:var(--hmz,1)}
  .hmfit .hmcard{width:1100px}
  @media(max-width:700px){ .hmfit .hmcard{width:auto} }

  /* Today's games: the time, the league, the two clubs, where the lines stand. */
  .hmgames{list-style:none;margin:0;padding:0}
  .hmgames li{border-bottom:1px solid var(--line)}
  .hmgames li:last-child{border-bottom:0}
  .hmgames a{display:grid;grid-template-columns:70px 64px minmax(0,1fr) auto;align-items:center;gap:8px;padding:8px 6px;
             color:var(--ink2);text-decoration:none;border-radius:6px}
  .hmgames a:hover{background:var(--hover);color:#fff}
  .hmgames .hmlg{justify-self:start;margin:0}
  .hmtime{font-variant-numeric:tabular-nums;color:var(--muted)}
  .hmmatch{font-family:var(--font-display);font-size:17px;font-weight:600;letter-spacing:.03em;color:#fff}
  .hmmatch i{font-style:normal;font-family:var(--font-body);font-size:13px;font-weight:400;color:var(--faint);margin:0 3px}
  .hmstate{font-size:13px;color:var(--faint);white-space:nowrap}
  .hmstate.ok{color:var(--good)}
  .hmstate.half{color:var(--warn-ink)}
  /* The last night's results (box scores): the winner's side in orange; More tools under all of them, across. */
  .hmscores .hmtime{font-family:var(--font-display);font-weight:600;font-size:13px;letter-spacing:.05em;text-transform:uppercase}
  .hmscores .hmwon{color:var(--brand-text)}
  .hmp-tools{grid-column:1 / -1}

  /* More tools: three tiles, each a drawing of what the tool shows. */
  .hmtools{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px;margin-top:14px;flex:1 0 auto}
  .hmtool{display:flex;flex-direction:column;justify-content:center;gap:6px;padding:14px;border:1px solid var(--line);border-radius:10px;background:var(--bg);
          text-decoration:none;color:var(--muted);font-size:14px;line-height:1.4}
  .hmtool:hover{border-color:var(--brand);color:var(--ink2)}
  .hmtool:focus{outline:none}
  .hmtool:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}
  .hmtool b{font-family:var(--font-display);font-size:19px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:#fff}
  .hmtool svg{width:100%;max-width:210px;height:auto;margin-bottom:8px}
  .hmsvg-a rect{fill:var(--brand)}
  .hmsvg-b rect{fill:var(--ink2)}
  .hmsvg-grid{fill:none;stroke:var(--line);stroke-width:1.5}
  .hmsvg-mid{fill:none;stroke:var(--faint);stroke-width:2;stroke-dasharray:4 4}
  .hmsvg-line{fill:none;stroke:var(--brand);stroke-width:3;stroke-linejoin:round;stroke-linecap:round}
  .hmsvg-dots circle{fill:var(--brand)}
  .hmsvg-faint circle{fill:var(--ink2);opacity:.7}
  .hmsvg-hot{fill:var(--brand)}
  .hmsvg-web{fill:none;stroke:var(--line);stroke-width:1.5}
  .hmsvg-shape{fill:rgba(242,107,33,.35);stroke:var(--brand);stroke-width:2;stroke-linejoin:round}
  @media(max-width:700px){
    .hmtools{grid-template-columns:minmax(0,1fr)}
    .hmtool{display:grid;grid-template-columns:96px minmax(0,1fr);grid-template-rows:auto auto;column-gap:14px;row-gap:2px;align-items:start}
    .hmtool svg{grid-row:1 / span 2;margin:0}
    .hmp{padding:16px 14px 14px}
    .hmhd h2{font-size:23px}
    .hmtbl{font-size:14.5px}
    .hmtbl .n{width:44px}
    .hmgames a{grid-template-columns:62px 56px minmax(0,1fr);row-gap:2px}
    .hmgames .hmstate{grid-column:3}
  }
  /* ---------- the plain pages (redesign step 11) ----------
     Pages that are something to read, not a tool: About, the front page,
     the glossary and privacy. Each is a <main class="sitepage">.

     Which one is on screen is said on <html data-page="about">: by the
     server in the document it sends (lib/serve-page.ts), so the page is
     there before any code has run and for a reader with none, then by
     tabTo(). The !important rules are for that first moment, when the
     markup still has a tool's tab open and the page itself still hidden. */
  html[data-page] .wrap{display:none!important}
  html[data-page="about"] #mode-about{display:block!important}
  html[data-page="privacy"] #mode-privacy{display:block!important}
  /* A player's own page (redesign step 20) is marked the same way, "card":
     the profile is a tool's tab, but on his address it holds what the server
     wrote of him, which has to be on screen before any code has run, and for
     a reader with none. tabTo() takes the mark off as it does for any tool. */
  html[data-page="card"] #mode-card{display:flex!important}
  /* And every tool's own page (redesign step 22). The markup opens on
     Percentiles, whatever the address, and the page's code turned to the
     right tab only once it had run and had its first answer: for a second
     or more /lines showed Percentiles' empty bar, then jumped. The server
     now marks the document for every tab, and it is on the right one before
     any code runs. */
  html[data-page="stats"] #mode-stats,html[data-page="leaderboard"] #mode-leaderboard,html[data-page="compare"] #mode-compare,
  html[data-page="trajectory"] #mode-trajectory,html[data-page="chart"] #mode-chart,html[data-page="lines"] #mode-lines,html[data-page="streaks"] #mode-streaks{display:flex!important}
  html[data-page="teams"] #mode-teams{display:flex!important}
  html[data-page="teamstats"] #mode-teamstats{display:flex!important}
  html[data-page="games"] #mode-games{display:flex!important}
  html[data-page="rankings"] #mode-rankings{display:flex!important}

  /* Text to read: one column, the page's left edge, a line a reader can
     follow (about 70 characters). Headings of a section in the orange for
     text, as the footer's are. */
  .prose{padding:30px 20px 8px}
  .prose > *{max-width:700px}
  .prose h1{margin:0 0 8px;font-family:var(--font-display);font-weight:700;font-size:42px;line-height:1.02;letter-spacing:.02em;
            text-transform:uppercase;color:#fff;text-wrap:balance}
  .prose .lede{margin:0 0 4px;font-size:18px;line-height:1.5;color:var(--ink)}
  .prose h2{margin:34px 0 10px;padding-top:18px;border-top:1px solid var(--line);font-size:12px;font-weight:600;letter-spacing:.1em;
            text-transform:uppercase;color:var(--brand-text)}
  .prose p,.prose li{font-size:16px;line-height:1.6;color:var(--ink2)}
  .prose p{margin:0 0 12px}
  .prose ul{margin:0 0 12px;padding-left:20px}
  .prose li{margin-bottom:6px}
  .prose strong{color:#fff;font-weight:600}
  .prose a{color:var(--brand-text);text-underline-offset:2px;border-radius:4px}
  .prose a:hover{color:#fff}
  .prose a:focus{outline:none}
  .prose a:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}

  /* What each league has, side by side. All three leagues stay in view on
     a phone: a table that scrolled sideways there hid the WHL's column, the
     one the paragraph under it is about. A season never breaks in two; the
     row's own label and "Not recorded" may. */
  .prose .cover{max-width:700px;margin:4px 0 14px;overflow-x:auto;border:1px solid var(--line);border-radius:8px;background:var(--surface)}
  .prose .cover table{width:100%;border-collapse:collapse;font-size:14.5px;line-height:1.35}
  .prose .cover td{white-space:nowrap}
  .prose .cover th,.prose .cover td{padding:9px 12px;text-align:left;border-bottom:1px solid var(--line);color:var(--ink2);font-variant-numeric:tabular-nums}
  .prose .cover tr:last-child th,.prose .cover tr:last-child td{border-bottom:0}
  .prose .cover thead th{font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
  .prose .cover tbody th{font-weight:500;color:var(--ink)}
  .prose .cover .no{color:var(--muted);white-space:normal}

  @media(max-width:700px){
    .prose{padding:22px 12px 4px}
    .prose h1{font-size:34px}
    .prose .lede{font-size:17px}
    .prose .cover table{font-size:13.5px}
    .prose .cover th,.prose .cover td{padding:8px 8px}
  }
  /* ---------- the glossary (redesign step 12) ----------
     A reference sheet: the sections listed down the left, staying in view
     while the entries scroll; each entry its code and name beside what it
     means. A plain page (17-site-pages.css says how one is put on screen).

     Class names start with g: an entry's code and name would otherwise meet
     rules written for the tools (.code, .name, .empty). */
  html[data-page="glossary"] #mode-glossary{display:block!important}

  .gloss{padding:30px 20px 8px}
  .gloss h1{margin:0 0 8px;font-family:var(--font-display);font-weight:700;font-size:42px;line-height:1.02;letter-spacing:.02em;
            text-transform:uppercase;color:#fff;text-wrap:balance}
  .gloss .lede{margin:0;max-width:700px;font-size:18px;line-height:1.5;color:var(--ink)}

  .gsearch{display:flex;flex-wrap:wrap;align-items:center;gap:8px 12px;margin-top:18px}
  .gsearch input{width:min(420px,100%);height:40px;padding:0 14px;font:inherit;font-size:15px;color:var(--ink);
                 background:var(--surface);border:1px solid var(--box);border-radius:8px}
  .gsearch input::placeholder{color:var(--muted)}
  .gsearch input:focus{outline:none;border-color:var(--brand-text)}
  .gcount{color:var(--muted);font-size:14px;font-variant-numeric:tabular-nums}

  .gbody{display:grid;grid-template-columns:190px minmax(0,1fr);gap:44px;max-width:1120px;margin-top:26px}
  .gindex{position:sticky;top:14px;align-self:start}
  .gindex ol{display:grid;gap:2px;margin:0;padding:0;list-style:none}
  .gindex a{display:block;padding:6px 10px;border-radius:6px;color:var(--ink2);font-size:15px;font-weight:500;text-decoration:none}
  .gindex a:hover{background:var(--surface);color:#fff}
  .gindex a:focus{outline:none}
  .gindex a:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}

  .gmain{display:grid;gap:42px;min-width:0}
  .gmain section,.gterm{scroll-margin-top:14px}
  .gmain h2{margin:0 0 8px;font-size:12px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--brand-text)}
  .gintro{margin:0 0 14px;max-width:700px;font-size:16px;line-height:1.55;color:var(--ink2)}
  .gmain dl{margin:0;border-top:1px solid var(--line)}

  /* An entry: what you see in a table on the left, what it means on the right. */
  .gterm{display:grid;grid-template-columns:160px minmax(0,1fr);gap:4px 22px;padding:15px 0;border-bottom:1px solid var(--line)}
  .gterm dt{display:flex;flex-direction:column;align-items:flex-start;gap:6px}
  .gcode{padding:3px 8px;border-radius:5px;background:var(--surface);border:1px solid var(--line);color:#fff;
         font-family:var(--font-display);font-weight:700;font-size:19px;line-height:1.15;letter-spacing:.02em;font-variant-numeric:tabular-nums}
  .gname{color:var(--muted);font-size:14px;line-height:1.3}
  .gterm dd{margin:0;max-width:700px}
  .gterm dd p{margin:0 0 7px;font-size:16px;line-height:1.55;color:var(--ink2)}
  .gterm dd p:last-child{margin-bottom:0}
  .gterm dd p.gcalc{font-size:15px}
  .gterm dd b{font-weight:600;color:var(--ink)}
  .gterm dd p.gwhere{font-size:13px;color:var(--muted)}
  .gwhere span + span::before{content:" · "}

  /* What each league has, and since when. Its cells wrap instead of the
     table scrolling sideways, so no league's column is ever out of view. */
  .gtable{max-width:860px;border:1px solid var(--line);border-radius:8px;background:var(--surface)}
  .gtable table{width:100%;border-collapse:collapse;font-size:14.5px;line-height:1.35;font-variant-numeric:tabular-nums}
  .gtable th,.gtable td{padding:9px 12px;text-align:left;vertical-align:top;border-bottom:1px solid var(--line);color:var(--ink2)}
  .gtable thead th{font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
  .gtable td:first-child{color:var(--ink);font-weight:500}
  .gtable tr:last-child td{border-bottom:0}

  .gnone{margin:0;padding:8px 0 20px;color:var(--muted);font-size:16px}

  /* Narrower: the sections become a row of chips over the entries, and an
     entry's code sits on the line above what it means. */
  @media(max-width:900px){
    .gbody{grid-template-columns:minmax(0,1fr);gap:22px}
    .gindex{position:static}
    .gindex ol{display:flex;flex-wrap:wrap;gap:6px}
    .gindex a{padding:6px 11px;border:1px solid var(--line);background:var(--surface);font-size:14px}
    .gterm{grid-template-columns:minmax(0,1fr)}
    .gterm dt{flex-direction:row;flex-wrap:wrap;align-items:baseline;gap:8px 10px}
  }
  @media(max-width:700px){
    .gloss{padding:22px 12px 4px}
    .gloss h1{font-size:34px}
    .gloss .lede{font-size:17px}
    .gindex a{min-height:36px;display:flex;align-items:center}
    .gtable table{font-size:13px}
    .gtable th,.gtable td{padding:8px 8px}
  }
  /* ---------- one set of controls (redesign step 15) ----------
     Menus, text boxes, buttons, switches and tables that look and behave the
     same on every tab, as the style guide drew them (5 October 2026).

     Every rule here starts with .ctl, the class on a tool's wrapper. The
     tabs took it one at a time (four slices, each looked at before the
     next); all seven have it now. It stays: it is what says "inside a tool",
     as against the header, the footer and the pages to read, and taking it
     off would lower the weight of every rule here against the layout rules
     that are still in each tab's own stylesheet.

     Those older stylesheets keep what places things (a bar's rows, a
     group's width, a phone's stacking). What they said about colour and
     edge for a control, this file says, and the clean-up took out of them.

     The rules of it:
     - A control is a well in the panel: the page's own gray, a quiet edge.
     - Orange means "this one": the control that has the keyboard (edge and
       glow), and a filter set to something other than its default (edge
       only, class "set": scripts/06e-controls.js), so what is filtered
       shows at a glance.
     - A page's main action is a filled orange button; every other button
       is an outline. On a tool that is its picture download. The profile
       has two, the card's and the shot map's (William, 6 October 2026:
       "make download shot map button the same as download cards"). Never blue: the old accent is gone from a tab that has
       the class.
     - Red and green are the percentiles'. No control uses them. */

  /* --- between a table's filters and the table: what the table is showing ---
     This line used to stand at the right of the page's name, in large
     letters ("SEASON STATS"). The names went on 7 October 2026 (William:
     "remove the page titles (we already see the page's names in the
     header)"); each tool still has its name as an <h1 class="sr">, for a
     screen reader and a search engine. The line then went under the
     filters, the same day ("move stat legend between setting box and
     table"), and reads from the left.
     Its margins make the same gap over it as under it: the filters' box
     ends 14px above (.ctl .lbbar), so 4 of that are taken back. */
  .pghead{margin:-4px 0 10px}
  .pghead .lbmeta{margin:0;font-size:12.5px;line-height:1.4;color:var(--muted);text-align:left}

  /* --- which stats a table shows (scripts/06g-column-picker.js) ---
     The button is in the table's bar; it has the orange edge while the
     table is not showing everything in its own order, as a filter that is
     set does. The box opens under the bar, the bar's own kind of box: a
     line of words and four buttons, then the groups side by side, as many
     as fit, each a list of tick boxes under the group's own. */
  .ctl .lbbar button.colbtn.set{border-color:var(--brand-text);color:#fff}
  .ctl .lbbar button.colbtn[aria-expanded="true"]{border-color:var(--brand-text);box-shadow:0 0 0 2px var(--brand-ring)}
  .ctl .colpick{margin:-4px 0 14px;padding:14px 16px 16px;border:1px solid var(--box);border-radius:10px;background:var(--surface)}
  .ctl .cphead{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:10px 18px;margin-bottom:14px}
  .ctl .cpsay{flex:1 1 320px;font-size:12.5px;line-height:1.4;color:var(--muted)}
  .ctl .cpsay strong{margin-right:6px;font-family:var(--font-display);font-size:16px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:#fff}
  .ctl .cpacts{display:flex;flex-wrap:wrap;gap:8px}
  .ctl .cpacts button{height:36px;padding:0 13px;border:1px solid var(--line);border-radius:7px;background:transparent;color:var(--ink2);font-size:13px;font-weight:600;cursor:pointer}
  .ctl .cpacts button:hover{border-color:var(--faint);color:#fff}
  .ctl .cpacts button:disabled{border-color:transparent;background:var(--surface2);color:var(--faint);cursor:default}
  /* "Done" shuts the box. Not filled: a page has one filled button, its main action (Copy link here). */
  .ctl .cpacts button.cpdone{border-color:var(--faint);color:#fff}
  .ctl .cpacts button:focus-visible,.ctl .cpmv button:focus-visible{outline:none;border-color:var(--brand-text);box-shadow:0 0 0 2px var(--brand-ring)}
  .ctl .cpgroups{display:grid;grid-template-columns:repeat(auto-fill,minmax(170px,1fr));gap:16px 18px;align-items:start}
  .ctl .cpg{min-width:0;margin:0;padding:0;border:0}
  .ctl .cpg legend{display:flex;align-items:center;justify-content:space-between;gap:8px;width:100%;margin:0 0 4px;padding:0 0 5px;border-bottom:1px solid var(--line)}
  .ctl .cpg legend label{font-family:var(--font-display);font-size:13px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:#fff}
  .ctl .cpg label{display:flex;align-items:center;gap:9px;min-height:30px;font-size:13.5px;font-weight:500;letter-spacing:0;text-transform:none;color:var(--ink);cursor:pointer}
  .ctl .cpg label:hover span{color:#fff}
  .ctl .cpg input[type=checkbox]{flex:none;width:16px;height:16px;margin:0;accent-color:var(--brand);cursor:pointer}
  .ctl .cpmv{display:flex;gap:4px}
  .ctl .cpmv button{width:28px;height:26px;padding:0;border:1px solid var(--line);border-radius:6px;background:transparent;color:var(--ink2);font-size:10px;line-height:1;cursor:pointer}
  .ctl .cpmv button:hover{border-color:var(--faint);color:#fff}
  .ctl .cpmv button:disabled{border-color:transparent;color:var(--faint);cursor:default}
  @media(max-width:700px){
    /* Two groups abreast on a phone, and rows a thumb can hit. */
    .ctl .colpick{padding:12px 12px 14px}
    .ctl .cpgroups{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px 14px}
    .ctl .cpg label{min-height:36px}
    .ctl .cpacts button{height:40px}
    .ctl .cpmv button{width:34px;height:32px}
  }

  /* --- menus and text boxes --- */
  .ctl .lbbar{gap:12px;padding:14px 16px;margin-bottom:14px}
  .ctl .lbbar label,.ctl .rowspick{font-weight:600}
  .ctl select,.ctl input[type=text]{height:40px;padding:0 10px;border:1px solid var(--line);border-radius:7px;background:var(--bg);
       color:var(--ink);font-size:14px;font-weight:500;letter-spacing:0;text-transform:none}
  .ctl select{cursor:pointer}
  .ctl input[type=text]::placeholder{color:var(--faint)}
  .ctl select:hover,.ctl input[type=text]:hover{border-color:var(--faint)}
  .ctl select:focus,.ctl input[type=text]:focus{outline:none;border-color:var(--brand-text);box-shadow:0 0 0 2px var(--brand-ring)}
  .ctl select.set,.ctl input[type=text].set{border-color:var(--brand-text)}

  /* --- buttons: an outline, and one filled main action a page --- */
  /* Named by where they sit (a table's bar, its page picker, a tool's row
     of actions, a box's heading, a group of a tool's bar), not "every
     button": a switch, a chip and a link in a sentence are buttons
     underneath, and each has its own look. */
  .ctl :where(.lbbar,.pager,.railacts,.smhead) button,.ctl .tbc > button,.ctl .tbc > .row > button{height:40px;padding:0 14px;border:1px solid var(--line);border-radius:7px;background:transparent;color:var(--ink2);
       font-size:14px;font-weight:500;white-space:nowrap;cursor:pointer}
  .ctl :where(.lbbar,.pager,.railacts,.smhead) button:hover,.ctl .tbc > button:hover,.ctl .tbc > .row > button:hover{border-color:var(--faint);color:#fff}
  .ctl :where(.lbbar,.pager,.railacts,.smhead) button:focus,.ctl .tbc > button:focus,.ctl .tbc > .row > button:focus{outline:none}
  .ctl :where(.lbbar,.pager,.railacts,.smhead) button:focus-visible,.ctl .tbc > button:focus-visible,.ctl .tbc > .row > button:focus-visible{border-color:var(--brand-text);box-shadow:0 0 0 2px var(--brand-ring)}
  /* The main action. On the two tables that is "Copy link": the table is
     what you came to share. */
  .ctl button.primary,.ctl .lbacts .copy{padding:0 18px;border-color:var(--brand);background:var(--brand);color:var(--on-brand);font-weight:600}
  .ctl button.primary:hover,.ctl .lbacts .copy:hover{border-color:var(--brand-text);background:var(--brand-text);color:var(--on-brand)}
  .ctl button.primary:focus-visible,.ctl .lbacts .copy:focus-visible{box-shadow:0 0 0 2px var(--surface),0 0 0 4px var(--brand-text)}
  /* Not available: flat and gray, the main action too. */
  .ctl :where(.lbbar,.pager,.railacts,.smhead) button:disabled,.ctl .tbc > button:disabled,.ctl .tbc > .row > button:disabled,.ctl :where(.lbbar,.pager,.railacts,.smhead) button:disabled:hover,.ctl .tbc > button:disabled:hover,.ctl button.primary:disabled,.ctl button.primary:disabled:hover{border-color:transparent;background:var(--surface2);color:var(--faint);opacity:1;cursor:default}
  .ctl .lbbar button{margin-left:0}
  .ctl .lbbar #stClear,.ctl .lbbar #lbClear{margin-left:auto}

  /* --- minimums (scripts/06h-minimums.js; William, 9 October 2026) ---
     A group of the bar like its labelled menus: the word over a menu of the
     table's stats, a box for the number and "Add". What is set stands
     beside it as chips, each with the orange edge a set filter has and a
     cross that takes it off. The chip's cross is a button inside a bar, so
     the bar's plain-button look reaches it; it is named and put back. */
  .ctl .lbbar .minf{display:flex;flex-direction:column;gap:5px}
  .ctl .lbbar .minlab{font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
  .ctl .lbbar .minrow{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
  .ctl .lbbar .minrow select{max-width:132px}
  .ctl .lbbar .minrow input[type=text]{width:96px}
  .ctl .lbbar .minrow input[type=text].bad{border-color:var(--warn-ink)}
  .ctl .lbbar .minchips{display:flex;flex-wrap:wrap;gap:6px;align-items:center;align-self:flex-end;min-height:40px}
  .ctl .lbbar .minchips[hidden]{display:none}
  .ctl .lbbar .minchips .chip{height:32px;gap:7px;padding:0 5px 0 12px;border-color:var(--brand-text);font-size:14px;white-space:nowrap}
  .ctl .lbbar .minchips .chip b{font-weight:700;color:#fff}
  .ctl .lbbar .minchips .chip button{height:22px;width:22px;padding:0;margin:0;border:0;border-radius:50%;background:none;color:var(--ink2);font-size:19px;line-height:1;cursor:pointer}
  .ctl .lbbar .minchips .chip button:hover{color:#fff;background:var(--surface2)}
  .ctl .lbbar .minchips .chip button:focus-visible{box-shadow:0 0 0 2px var(--brand-ring);color:#fff}

  /* --- a date range (scripts/10-season-stats.js; William, 10 October 2026: "add date range to stat table") ---
     A group of the bar like the Minimum one: the word over two boxes for a day, the first of the games wanted
     and the last. Each is the browser's own date field, dressed as the bar's wells are; one that holds a day has
     the orange edge a set filter has. An empty one writes its pattern (yyyy-mm-dd) faintly, as a text box writes
     its placeholder. */
  .ctl .lbbar .datef{display:flex;flex-direction:column;gap:5px}
  .ctl .lbbar .daterow{display:flex;gap:6px;align-items:center}
  .ctl .lbbar .datesep{font-size:13px;color:var(--muted)}
  .ctl input[type=date]{height:40px;padding:0 8px;border:1px solid var(--line);border-radius:7px;background:var(--bg);
       color:var(--ink);font-size:14px;font-weight:500;letter-spacing:0;text-transform:none}
  .ctl input[type=date]:hover{border-color:var(--faint)}
  .ctl input[type=date]:focus{outline:none;border-color:var(--brand-text);box-shadow:0 0 0 2px var(--brand-ring)}
  .ctl input[type=date].set{border-color:var(--brand-text)}
  .ctl input[type=date]:not(.set)::-webkit-datetime-edit{color:var(--faint)}
  .ctl input[type=date]::-webkit-calendar-picker-indicator{cursor:pointer;opacity:.7}
  .ctl input[type=date]::-webkit-calendar-picker-indicator:hover{opacity:1}

  /* --- the page picker under a table --- */
  .ctl .pager{gap:14px;padding:18px 0 6px}
  /* The line under a table (William, 6 October 2026: "Move rows picker to
     bottom of table with page"). One group in the middle: the page
     switcher, then the Rows menu a wider gap after it, so the two read as
     two controls side by side. At the table's far right the menu would be
     a thousand pixels from the switcher on a wide screen. With one page the
     switcher is hidden and the menu stands alone in the middle. On a phone
     the menu wraps under the switcher. No table on screen (still loading,
     nothing matching, a failure): no line. */
  .ctl .tblfoot{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:12px 28px;padding:18px 0 6px}
  .ctl .tblfoot .pager{padding:0}
  .ctl .tblfoot .rowspick{flex-direction:row;align-items:center;gap:8px}
  .ctl .lbscroll[hidden] + .tblfoot{display:none}
  .ctl .pager button{min-width:120px;font-weight:500}
  .ctl .pgmid{font-size:14px;color:var(--ink2)}
  .ctl .pgmid input{width:54px;padding:0 6px;font-weight:600}
  .ctl .rowspick select{min-width:72px;font-weight:600}

  /* --- tables --- */
  /* An orange line under the headings; the sorted column in white, its
     heading too; a player's name in the orange for text, since it is the
     way in to his card; a row under the pointer raised a shade; a stat with
     nothing to say faint. The headings keep the narrow face: a table of
     thirty-five columns has no room for the guide's wider one. */
  .ctl .lbscroll{border-radius:10px}
  .ctl .lbtable thead th{padding:10px 8px 9px;border-bottom:2px solid var(--brand);font-size:var(--tblh);color:var(--muted)}
  .ctl .lbtable thead th:hover{color:#fff}
  .ctl .lbtable thead th.on{color:#fff;background:var(--thead)}
  .ctl .lbtable td{padding:7px 8px}
  .ctl .lbtable td.on{color:#fff;font-weight:600}
  .ctl .lbtable td.nil{color:var(--faint)}
  .ctl .lbtable tbody tr:hover td,.ctl .lbtable tbody tr:hover .stick,.ctl .lbtable tbody tr:hover .stick2{background:var(--surface2)}
  .ctl .lbtable .nm{color:var(--brand-text)}
  .ctl .lbtable .nm:hover{color:#fff;text-decoration:underline;text-underline-offset:2px}
  /* (step 22) Where the keyboard is, in a table: a heading that sorts, a
     name, the table's own box (which Tab reaches so that the arrow keys can
     scroll it), a row of the scatter's side list. An orange line just inside
     the edge, since a glow would be cut off by the box. */
  .ctl .lbtable thead th:focus,.ctl .lbtable .nm a:focus,.ctl .lbscroll:focus,.ctl .ctscroll:focus,.ctl .sstop tr:focus{outline:none}
  .ctl .lbtable thead th:focus-visible,.ctl .lbtable .nm a:focus-visible,.ctl .sstop tr:focus-visible{outline:2px solid var(--brand-text);outline-offset:-2px}
  .ctl .lbscroll:focus-visible,.ctl .ctscroll:focus-visible{outline:2px solid var(--brand-text);outline-offset:-2px}
  .ctl .lbtable tbody tr:last-child td{border-bottom:0}

  /* --- grouped headings, and a table's spacing (step 16) ---
     A row of group names over the column headings
     (scripts/06f-table-groups.js), and a thin line down the table where
     each group starts, with more room either side of it than between two
     columns of one group.
     - Both heading rows stay put while the table scrolls: the group names
       at the top, the column headings right under them. The one height
       --grph says where "right under" is; the two rules that use it must
       agree, or rows show through a gap between the two.
     - The names are centred over their groups, in white (William, 6
       October 2026: "Make titles centred and make them brighter"). They
       were to the left, in a gray a shade under the table's text. Since
       all are white now, the group that holds the sorted column ("cur")
       is marked by an orange line under its name instead.
     - "Name" (th.gn) is one cell over the two pinned columns, and carries
       the line that ends the pinned block, as the Player heading does.
     - A heading lines up with what is under it: words to the left, numbers
       to the right, a percentile's box in the middle. Until this step every
       heading but a number's was centred over a column that was not. */
  /* The names' letters were 10px, smaller than the headings under them
     (William, 7 October 2026, with a picture of the row: "make the font of
     titles in stats tabs bigger"). 13px now, the row 4px taller to hold
     them, and a little less air between the letters so that a long name
     over two narrow columns ("Short-handed") widens them no more than it
     did. One size for the big tables and a profile's, as one height. */
  /* Every size of letters in a stat table, in one place (William, 8 October
     2026, with a picture of Season Stats on a wide screen: "make the size of
     fonts in tables bigger. It is too small as is without zooming in").
       --tblf  a cell's text            14px, where it was 12
       --tblh  a column's heading       12px, where it was 10.5
       --grpf  a group's name           15px, where it was 13
       --grph  the row of group names   32px tall, where it was 28
     The three leaderboards and the tables under a card read these four and
     say no size of their own; what goes with a size (the rank's column, a
     percentile's box, the Splits box's grid) is in em or follows below.
     A phone sets them back to what they were (styles/24-phone.css): there a
     table has 390px to show a name and a number in. */
  .ctl .lbtable,.ctl .ctscroll table{--grph:32px;--grpf:15px;--tblf:14px;--tblh:12px}
  .ctl .lbtable,.ctl .ctscroll table{font-size:var(--tblf)}
  /* The rank's column holds four digits (1,737 player-seasons on a CHL
     table) at that size, and the name is pinned where it ends. */
  .ctl .lbtable .rk{width:50px}
  .ctl .lbtable .stick2{left:50px}
  /* (faces) A player's headshot before his name, and his club's crest before
     its code (scripts/06j-table-faces.js): in em, so a phone's smaller table
     has smaller ones, and a row is the height it was (35px). The initials are drawn under the picture and are what
     is left when the league has none; they are not text of the cell. */
  .ctl .lbtable .nm a{display:inline-flex;align-items:center;gap:.5em;vertical-align:top}
  .ctl .tface{position:relative;flex:none;width:1.5em;height:1.5em;border-radius:50%;overflow:hidden;
        background:var(--surface2);box-shadow:inset 0 0 0 1px var(--line)}
  .ctl .tface::before{content:attr(data-ini);position:absolute;inset:0;display:grid;place-items:center;
        font-size:.6em;font-weight:600;letter-spacing:.02em;color:var(--muted)}
  .ctl .tface img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
  .ctl .tcrest{width:1.2857em;height:1.2857em;object-fit:contain;vertical-align:top;margin:0 .4286em 0 0}
  /* A club's cell is a link to its page, in the orange for text like a player's name, and like his white and
     underlined under the pointer (William, 18 October 2026: "make team names (SNB, NB, etc) in orange like players names"). */
  .ctl .lbtable a.tclub{color:var(--brand-text);text-decoration:none;white-space:nowrap}
  .ctl .lbtable a.tclub:hover{color:#fff;text-decoration:underline;text-underline-offset:2px}
  .ctl .lbtable a.tclub:focus{outline:none}
  .ctl .lbtable a.tclub:focus-visible{outline:2px solid var(--brand-text);outline-offset:1px}
  .ctl .lbtable thead th .ar{font-size:.76em}
  /* A percentile's box, by the table's own size: the percentile as large as
     a cell's text, the value under it three quarters of that. */
  .ctl .lbtable .pbox{min-width:3.8333em}
  .ctl .lbtable .pbox b{font-size:1em}
  .ctl .lbtable .pbox span{font-size:.75em}
  .ctl .lbtable thead th{text-align:left}
  .ctl .lbtable thead th.num,.ctl .lbtable thead th.rk{text-align:right}
  .ctl .lbtable thead th.ctr{text-align:center}
  .ctl .lbtable thead tr.grp th{top:0;box-sizing:border-box;height:var(--grph);padding:0 8px;border-bottom:1px solid var(--line);
       font-size:var(--grpf);letter-spacing:.07em;color:#fff;text-align:center;cursor:default}
  .ctl .lbtable thead tr.grp th.gn{box-shadow:1px 0 0 var(--line)}
  .ctl .lbtable thead tr.grp th.cur{box-shadow:inset 0 -2px 0 var(--brand)}
  .ctl .lbtable thead tr.grp + tr th{top:var(--grph)}
  .ctl .lbtable .gs,.ctl .lbtable thead tr.grp th.gs{border-left:1px solid var(--line)}
  .ctl .lbtable .gs{padding-left:12px}
  .ctl .lbtable .ge{padding-right:12px}

  /* --- a profile's tables, drawn like the two above (William, 7 October
     2026: "make stat tables on player profiles look like main stat table") ---
     Season by season, the four of the Splits box, the game log
     (scripts/14-below-card.js, cbTable). The same row of group names, the
     same lines between groups, the same room in a cell.
     - One column is pinned at the left (th.stick, td.stick), and it ends
       with the line that ends a pinned block. Its heading is one tall cell
       over both heading rows: it is in the row of names, so the rules for
       that row are undone on it, one by one.
     - --grph is the big tables' own height, and here too the two rules
       that use it must agree. */
  .ctl .ctscroll thead th{padding:10px 8px 9px}
  .ctl .ctscroll td{padding:7px 8px}
  /* A stat's heading keeps its own letters (xG, GF% Rel), as on Season Stats.
     Said here and not left to the big tables' rule (styles/05-tables.css),
     which this table's own "headings in capitals" comes after and outranks. */
  .ctl .ctscroll thead th.mcode{text-transform:none}
  .ctl .ctscroll .stick{position:sticky;left:0;z-index:1;background:var(--surface);box-shadow:1px 0 0 var(--line);text-align:left}
  .ctl .ctscroll thead .stick{z-index:3;background:var(--thead)}
  .ctl .ctscroll tbody tr:hover .stick{background:var(--surface2)}
  /* The card's season keeps its orange mark at the left and the line at the
     right. "tbody" is there for weight: the rule that draws the mark alone
     (tr.on td:first-child, further down) weighs the same without it, comes
     later, and won. */
  .ctl .ctscroll tr.on .stick{background:var(--sel2)}
  .ctl .ctscroll tbody tr.on td.stick{box-shadow:inset 3px 0 0 var(--brand),1px 0 0 var(--line)}
  .ctl .ctscroll thead tr.grp th{top:0;box-sizing:border-box;height:var(--grph);padding:0 8px;border-bottom:1px solid var(--line);
       font-size:var(--grpf);letter-spacing:.07em;color:#fff;text-align:center}
  .ctl .ctscroll thead tr.grp th.stick{height:auto;padding:10px 8px 9px;border-bottom:2px solid var(--brand);vertical-align:bottom;
       font-size:var(--tblh);letter-spacing:.07em;color:var(--muted);text-align:left}
  .ctl .ctscroll thead tr.grp + tr th{top:var(--grph)}
  .ctl .ctscroll .gs,.ctl .ctscroll thead tr.grp th.gs{border-left:1px solid var(--line)}
  .ctl .ctscroll .gs{padding-left:12px}
  .ctl .ctscroll .ge{padding-right:12px}

  @media(max-width:600px){
    .ctl .pager{gap:8px}
    .ctl .pager button{min-width:0;padding:0 12px}
  }

  /* --- a tool's settings bar: headed groups in a box across the top (.rail) --- */
  .ctl.tb > .rail{padding:14px 16px}
  .ctl .rail h2{font-size:11px;font-weight:600;letter-spacing:.08em}
  .ctl.tb .rail .tbc select{height:40px}
  /* On a phone the bar's menus keep their size: 16px, so the phone does not
     zoom in on one, and tall enough for a thumb. */
  @media(max-width:860px){
    .ctl .rail select,.ctl .rail input[type=text]{height:44px;font-size:16px}
    /* Where the settings fold behind one button (styles/12-narrow-screens.css),
       the bar is no box: that button and the row of buttons under it are.
       The padding above is the box's, and here it only pushed both 16px in
       from the page's edges, so the settings were narrower than the card
       or chart under them and the buttons did not start where it does
       (William, 7 October 2026, on his phone: "Extend settings box to match
       the width of tables/cards + line up buttons ... to the left"). The
       narrow-screen rule that says so weighs less than the one above. */
    .ctl.tb > .rail{padding:0}
    /* And a tool's own box is the page's width, whatever is in it. Stacked,
       the wrapper lets each child be as narrow as its content: Trajectory
       with nobody picked was as wide as its message ("Trajectory box
       doesn't match the width of others"), and Compare's the same on a
       wider phone. The profile has had this since its tables went in. */
    .ctl.tb > .stage{width:100%;min-width:0}
  }

  /* --- a switch between two or three: the one in use raised, the rest flat --- */
  .ctl .seg{padding:3px;border:1px solid var(--line);border-radius:8px;background:var(--bg);overflow:visible}
  .ctl .seg button{height:32px;padding:0 12px;border:0;border-radius:6px;background:transparent;color:var(--ink2);font-size:13px;font-weight:500;
       white-space:nowrap;cursor:pointer}
  .ctl.tb .rail .tbc .seg button{padding:0 12px}
  .ctl .seg button + button{border-left:0}
  .ctl .seg button:hover{color:#fff}
  .ctl .seg button[aria-pressed="true"]{background:var(--track);color:#fff;font-weight:600}
  .ctl .seg button:focus-visible{outline:none;box-shadow:0 0 0 2px var(--brand-ring),inset 0 0 0 1px var(--brand-text)}

  /* --- the small buttons of a tool's bar --- */
  /* The cross that takes a player out of his box, and the one on a
     highlight's chip: quiet until pointed at, then white. Never the old
     blue. "Reset", beside a zoomed plot's range, is a small outline. */
  .ctl .pslot .rdx{height:40px;padding:0 11px;border:1px solid var(--line);border-radius:7px;background:transparent;color:var(--muted);font-size:15px;cursor:pointer}
  .ctl .pslot .rdx:hover{border-color:var(--faint);color:#fff}
  .ctl .chip{border-color:var(--line);background:var(--bg)}
  .ctl .chip button:hover{color:#fff}
  .ctl .sczoom button{height:28px;padding:0 10px;border:1px solid var(--line);border-radius:6px;background:transparent;color:var(--ink2);font-size:12px;cursor:pointer}
  .ctl .sczoom button:hover{border-color:var(--faint);color:#fff}
  /* A list of matches under a search box: the row under the pointer raised a shade, as in a table. */
  .ctl .rdhits .hit:hover{background:var(--surface2)}

  /* --- Lines: its bar, the games picker, and a game's row --- */
  /* The bar is the tables' bar with groups headed by a word, not labels. */
  .ctl .lnbar{gap:14px 22px}
  .ctl .lnfl{font-weight:600}
  .ctl .lnbar .lnday button{padding:0 13px}
  .ctl .lnday span{color:var(--ink)}
  .ctl #lnDlBtn{padding:0 13px}
  .ctl .lndl.open #lnDlBtn{border-color:var(--brand-text);color:#fff}
  /* In the picker, "Select all", "Clear" and "All QMJHL" are words to
     click, not boxes: buttons underneath, links to look at. */
  .ctl .lnlinks button,.ctl .lnpgh button,.ctl .lnview .none button{height:auto;padding:0;border:0;border-radius:3px;background:none;
       color:var(--brand-text);font-size:inherit;font-weight:inherit;letter-spacing:inherit}
  .ctl .lnlinks button:hover,.ctl .lnpgh button:hover,.ctl .lnview .none button:hover{color:#fff;text-decoration:underline}
  .ctl .lnlinks button:focus-visible,.ctl .lnpgh button:focus-visible{box-shadow:0 0 0 2px var(--brand-ring)}
  .ctl .lnpick{border-color:var(--line);background:var(--bg)}
  .ctl .lnpick input[type=checkbox]{accent-color:var(--brand)}
  /* A game's row: what it offers is a row of small outlines, the download
     a link dressed as one of them; the lesser links are words. */
  .ctl a.btnlink,.ctl .lnopen{height:36px;padding:0 13px;border:1px solid var(--line);border-radius:7px;background:transparent;color:var(--ink2);
       font-size:13px;font-weight:500}
  .ctl a.btnlink:hover,.ctl .lnopen:hover{border-color:var(--faint);color:#fff}
  .ctl .lnopen[aria-expanded=true]{border-color:var(--brand-text);color:#fff}
  .ctl a.btnlink:focus-visible,.ctl .lnopen:focus-visible{outline:none;border-color:var(--brand-text);box-shadow:0 0 0 2px var(--brand-ring)}
  .ctl .lnsrc:hover{color:#fff}
  .ctl .lnrow.can .lnteams:hover b{color:var(--brand-text)}
  .ctl a.lvlast:hover{color:var(--brand-text)}

  /* --- the tables in a box under a card (season by season, splits, game log) --- */
  /* The same table as the leaderboards', smaller: the orange line under the
     headings, a row under the pointer raised a shade, and the row the card
     is showing marked in orange where it was blue. */
  .ctl .ctscroll thead th{border-bottom:2px solid var(--brand);font-size:var(--tblh)}
  .ctl .ctscroll tbody tr:hover td{background:var(--surface2)}
  .ctl .ctscroll tr.on td:first-child,.ctl .smbands tr.on td:first-child{box-shadow:inset 3px 0 0 var(--brand)}
  .ctl .ctscroll td.nil{color:var(--faint)}
  .ctl #logSeason{height:40px;padding:0 10px;border-color:var(--line);background:var(--bg);font-size:14px}
  .ctl #logSeason:focus{border-color:var(--brand-text)}

  /* --- the shot map's own menus and buttons: the control set, a size down, in a narrow column --- */
  .ctl .smf select{height:36px;padding:0 9px;font-size:13px}
  .ctl .smf.on select{border-color:var(--brand-text)}
  .ctl .smreset{color:var(--brand-text)}
  .ctl .smreset:hover{color:#fff}
  .ctl .smreset[disabled],.ctl .smreset[disabled]:hover{color:var(--faint)}
  /* The shot map's picture button is the card's twin: the same size, and
     filled (class "primary"), by William's word. Its own older rule made it
     small. */
  .ctl #smPng{padding:0 18px;font-size:14px}
  /* ---------- the profile as a page (redesign step 17) ----------
     The card, then four boxes under it. This part is what makes them read
     as one page: a strip that names the sections and jumps to each
     (scripts/14b-profile-nav.js), and a heading on every box in the site's
     display face, with what the box can do (a picture, a season to pick)
     at the right of its heading.

     Nothing here is on the card: the strip and the boxes sit outside
     #cardRow, which is all the picture export photographs. */

  /* The strip. It sticks to the top of the window; while it is there it
     covers the page with the page's own gray and says whose profile this
     is, at the right, since the card's header has scrolled away. */
  .pfnav{position:sticky;top:0;z-index:20;display:flex;align-items:stretch;gap:16px;height:44px;margin:0 0 12px;
         background:var(--bg);box-shadow:inset 0 -1px 0 var(--line)}
  .pflinks{display:flex;gap:2px;min-width:0;overflow-x:auto;scrollbar-width:none}
  .pflinks::-webkit-scrollbar{display:none}
  .pfnav button{flex:0 0 auto;padding:0 13px;border:0;border-bottom:2px solid transparent;border-radius:0;background:none;
         font-family:var(--font-display);font-size:16px;line-height:1.2;font-weight:600;letter-spacing:.07em;text-transform:uppercase;
         white-space:nowrap;color:var(--muted);cursor:pointer}
  .pfnav button:first-child{padding-left:2px}
  .pfnav button:hover{color:#fff}
  .pfnav button.on{color:#fff;border-bottom-color:var(--brand)}
  .pfnav button:focus{outline:none}
  .pfnav button:focus-visible{color:#fff;box-shadow:inset 0 0 0 2px var(--brand-ring)}
  .pfwho{flex:0 1 auto;margin-left:auto;align-self:center;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
         font-family:var(--font-display);font-size:17.5px;font-weight:600;letter-spacing:.03em;color:var(--ink2);
         opacity:0;transition:opacity .15s}
  .pfnav.stuck .pfwho{opacity:1}
  /* A jump lands a box under the strip, not behind it. */
  #belowCard > section{scroll-margin-top:58px}

  /* A box's heading: the section's name, what it is of beside it, and the
     box's own control at the right. */
  .ctl .ctable{padding:16px 18px 18px}
  .ctl .ctable h3{margin:0 0 12px;font-family:var(--font-display);font-size:23px;line-height:1.1;font-weight:600;
         letter-spacing:.05em;color:var(--ink)}
  .ctl .ctable h3 .smsub{margin-left:2px;font-family:var(--font-body);font-size:14.5px;letter-spacing:0;color:var(--muted)}
  .ctl .smhead{min-height:40px;margin:0 0 12px}
  .ctl .smhead h3{margin:0}
  .ctl .smhead #logSeason{margin:0}
  /* Streaks, over the game log (scripts/14-below-card.js cbStreaks): a well a
     streak, side by side and sharing the width; one under another where
     there is not room for two. A number in the display face, the words
     around it small. */
  .ctl .stks{display:flex;flex-wrap:wrap;gap:8px;margin:0 0 12px}
  .ctl .stks[hidden]{display:none}
  .ctl .stk{flex:1 1 230px;min-width:0;padding:9px 12px 8px;border:1px solid var(--line);border-radius:8px;background:var(--bg)}
  .ctl .stkl{font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
  .ctl .stkv{display:flex;flex-wrap:wrap;align-items:baseline;gap:0 20px;margin-top:2px}
  /* Each number is a button that shows its games in the log (cbMarkStreak):
     no box of its own, the number turning orange under the pointer and
     while its games are shown. One with no games to show is plain text. */
  .ctl .stks button.stkn{padding:0;border:0;border-radius:4px;background:none;font:inherit;font-size:14px;color:var(--ink2);
         white-space:nowrap;text-align:left;cursor:pointer}
  .ctl .stks button.stkn:disabled{opacity:1;cursor:default}
  .ctl .stks button.stkn:hover:not(:disabled) b,.ctl .stks button.stkn[aria-pressed="true"] b{color:var(--brand-text)}
  .ctl .stks button.stkn[aria-pressed="true"]{color:#fff}
  .ctl .stks button.stkn:focus{outline:none}
  .ctl .stks button.stkn:focus-visible{box-shadow:0 0 0 2px var(--brand-ring)}
  .ctl .stkn b{margin-left:6px;font-family:var(--font-display);font-size:27px;line-height:1.2;font-weight:600;color:#fff;font-variant-numeric:tabular-nums}
  .ctl .stkn i{margin-left:8px;font-style:normal;font-size:13.5px;color:var(--muted);font-variant-numeric:tabular-nums}
  /* A goalie's best and worst night (data-hl="night:…"): where and what it
     was is a longer line than a streak's dates, so it goes under the number,
     whole, where four cells abreast leave it no room, and breaks there only
     if it must. The gap is the number's, so a line that went under starts
     at the cell's edge. */
  .ctl .stks button.stkn[data-hl^="night:"]{white-space:normal}
  .ctl .stks button.stkn[data-hl^="night:"] b{margin-right:8px;white-space:nowrap}
  .ctl .stks button.stkn[data-hl^="night:"] i{display:inline-block;margin-left:0}
  /* Four cells (a goalie's two streaks and two nights): where four abreast
     do not fit, two and two, never three and the worst night alone under
     them; one a row where two do not fit. The widths are the cells' own
     230px and the 8px between them: four need 944px, two 468px. A cell's
     width jumps from one to the next as the strip passes each. */
  .ctl .stks:has(> .stk:nth-child(4)) > .stk{
    flex-basis:clamp(230px, calc((944px - 100%) * 999), clamp(calc(50% - 4px), calc((468px - 100%) * 999), 100%))}
  /* Under the cells, the way to the board of every player's streaks. */
  .ctl .stkall{flex:1 0 100%;font-size:14px;color:var(--brand-text);text-decoration:none}
  .ctl .stkall:hover{color:#fff;text-decoration:underline;text-underline-offset:2px}
  /* The Streaks board's table. It is narrower than its box, so the spare
     width is shared among its columns; with words set to the left of a
     column and numbers to the right, that put a number far from the column
     before it and against the one after (William: "so much space between
     the POS and the STREAK and almost no spaces between STREAK and FROM").
     So every column after the name is set in its middle, heading and cells
     alike: whatever width a column is given, half is on each side, and the
     gaps between columns come out even at any width. The first try gave
     all the spare width to the name; the pinned name cell then painted
     over the column beside it, and 480px of nothing stood after a name. */
  .ctl #hotTable th:not(.stick):not(.stick2),.ctl #hotTable td:not(.stick):not(.stick2){text-align:center}
  .ctl #hotTable thead tr:not(.grp) th.gs,.ctl #hotTable td.gs{padding-left:8px}
  .ctl #hotTable thead tr:not(.grp) th.ge,.ctl #hotTable td.ge{padding-right:8px}
  /* In em, so they follow the table's size of letters (styles/21-controls.css):
     at a phone's 12px these are the 44, 84 and 56px, and the 14px streak,
     they were written as. */
  .ctl #hotTable .hotc{min-width:3.6667em}
  .ctl #hotTable .hotd{min-width:7em}
  .ctl #hotTable td.ctr{min-width:4em;font-size:1.1667em}
  /* On the Streaks board, in a season's list: a streak that is still running. */
  .ctl .hoton{margin-left:6px;padding:1px 6px;border:1px solid var(--brand);border-radius:9px;font-size:10px;font-weight:600;
         letter-spacing:.06em;text-transform:uppercase;color:var(--brand-text)}
  .ctl #belowCard{margin-top:16px;gap:16px}

  /* What the server wrote of the player in the address (redesign step 20,
     lib/player-summary.mjs): a plain panel where the card will be. While it
     stands the card's own row is off screen, so a visitor never sees it
     beside the gray bars of a card being built, or beside the card. The
     page's code removes it when the card is up; "keep" is for a card that
     could not be built, where the summary stays above the message. */
  .pfsum{margin:0 0 14px;padding:20px 22px 18px;border:1px solid var(--cardline);border-radius:12px;background:var(--surface)}
  .pfsum h1{margin:0;font-family:var(--font-display);font-size:34px;line-height:1.05;font-weight:700;letter-spacing:.01em;color:#fff}
  .pfsum p{margin:6px 0 0;font-size:14px;line-height:1.5;color:var(--ink2)}
  .pfsum .pfsum-where{margin-top:4px;color:var(--muted)}
  .pfsum .pfsum-line b{margin-right:8px;font-weight:600;color:var(--ink)}
  .pfsum .pfsum-bio,.pfsum .pfsum-note{font-size:13px;color:var(--muted)}
  .pfsum .pfsum-note{margin-top:14px}
  .pfsum-tab{margin:16px 0 0;border-collapse:collapse;font-size:13px;font-variant-numeric:tabular-nums}
  .pfsum-tab caption{padding:0 0 6px;text-align:left;font-size:11px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--muted)}
  .pfsum-tab th,.pfsum-tab td{padding:5px 18px 5px 0;border-bottom:1px solid var(--line);text-align:left;font-weight:500;color:var(--ink2);white-space:nowrap}
  .pfsum-tab thead th{font-size:10.5px;font-weight:600;letter-spacing:.07em;text-transform:uppercase;color:var(--muted)}
  .pfsum-tab .num{text-align:right}
  .pfsum-tab tr.on th,.pfsum-tab tr.on td{color:#fff;font-weight:600}
  .pfsum-tab a{color:var(--brand-text);text-decoration:none}
  .pfsum-tab a:hover{text-decoration:underline}
  #pfSummary:not(.keep) + #cardRow{display:none}

  /* On a phone the strip is the links alone, scrolling sideways if the five
     do not fit; the name would leave them no room. */
  @media(max-width:700px){
    .pfnav{height:42px;gap:0}
    .pfwho{display:none}
    .pfnav button{padding:0 10px;font-size:15px}
    .ctl .ctable{padding:14px 12px 14px}
    /* Nothing to tap under 36px tall (the phone pass). */
    .ctl .stks button.stkn{min-height:36px}
    .ctl .stkall{padding:8px 0}
    .ctl .ctable h3{font-size:20px}
    .pfsum{padding:16px 14px 14px}
    .pfsum h1{font-size:28px}
    .pfsum-tab{display:block;overflow-x:auto}
  }
  /* ---------- waiting, and nothing to show (redesign step 18) ----------
     scripts/04b-states.js builds what is styled here. */

  /* Read by a screen reader, not drawn. */
  .vh{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}

  /* A placeholder bar: where a word or a number will be. */
  .sk{display:block;flex:0 0 auto;height:10px;border-radius:5px;background:var(--track);animation:skpulse 1.5s ease-in-out infinite}
  @keyframes skpulse{0%,100%{opacity:1}50%{opacity:.45}}
  @media (prefers-reduced-motion:reduce){ .sk{animation:none} }

  /* Rows of a stat table: the table's own box, heading strip and row height,
     so the page is the same height when the rows land. No taller than the
     table's box may be. */
  .skbox{max-height:70vh;overflow:hidden;border:1px solid var(--box);border-radius:10px;background:var(--surface)}
  .skrow{display:flex;align-items:center;gap:24px;height:35px;padding:0 14px;border-bottom:1px solid var(--line);overflow:hidden}
  .skrow:last-child{border-bottom:0}
  .skrow.skhead{height:67px;align-items:flex-end;padding-bottom:13px;background:var(--thead);border-bottom:2px solid var(--brand)}
  .skrow.skhead .sk{height:8px;opacity:.7}
  .sk.skn{width:30px}

  /* A card being built. */
  .skcard{min-height:560px}
  .skhdr{display:flex;align-items:center;gap:16px;padding:16px 22px;background:var(--band)}
  .skhdr .sk{background:rgba(255,255,255,.14)}
  .skphoto{width:96px;height:96px;border-radius:8px}
  .skwho{flex:1;display:flex;flex-direction:column;gap:12px;min-width:0}
  .sk.skbig{height:24px}
  .skline{display:flex;background:var(--surface2);border-bottom:1px solid var(--line)}
  .skline span{flex:1;display:flex;justify-content:center;padding:21px 0;border-right:1px solid var(--line)}
  .skline span:last-child{border-right:0}
  .skcols{display:flex;gap:28px;padding:26px 22px}
  .skcols > div{flex:1;display:flex;flex-direction:column;gap:17px;min-width:0}
  .skbar{display:flex;align-items:center;gap:16px}
  .skbar .sk{max-width:45%}
  .skbar .skfill{flex:1 1 auto;max-width:none;height:9px}
  /* Two of them, for Compare. */
  .skpair{display:grid;grid-template-columns:1fr 1fr;gap:66px}
  .skpair .skcard{border:1px solid var(--cardline);border-radius:12px;overflow:hidden;background:var(--surface)}

  /* Lines of a box under the card; taller, a day's games. */
  .sklines{display:flex;flex-direction:column;gap:16px;padding:10px 2px 6px}
  .sklines.tall{gap:0;padding:0}
  .sklines.tall .sk{height:14px;margin:26px 0}

  /* A table whose next answer is on the way keeps its rows, dimmed. */
  .lbscroll.busy tbody{opacity:.42;transition:opacity .12s}
  .lbscroll.busy{cursor:progress}

  /* Every dead end and every prompt: a heading in the display face, a
     sentence, a button when there is one. (The block itself is older:
     03-card.css. This is its look since step 18.) */
  .dead{padding:54px 22px}
  .dead h4{margin:0 0 9px;font-family:var(--font-display);font-size:20px;line-height:1.1;font-weight:600;
           letter-spacing:.05em;text-transform:uppercase;color:var(--ink)}
  .dead p{font-size:14px}
  .dead .act{margin-top:18px}
  .ctl .dead .act button{height:40px;padding:0 16px;border:1px solid var(--line);border-radius:7px;background:transparent;
           color:var(--ink);font-size:14px;font-weight:500;cursor:pointer}
  .ctl .dead .act button:hover{border-color:var(--faint);color:#fff}
  .ctl .dead .act button:focus-visible{outline:none;border-color:var(--brand-text);box-shadow:0 0 0 2px var(--brand-ring)}
  /* Standing in for a table, it is the table's box. */
  #stDead > .dead,#lbDead > .dead{max-width:none;padding:72px 22px;border:1px solid var(--box);border-radius:10px;background:var(--surface)}
  #stDead > .dead p,#lbDead > .dead p{max-width:52ch;margin:0 auto}

  @media(max-width:700px){
    .skcols{flex-direction:column;gap:17px;padding:18px 14px}
    .skhdr{padding:14px}
    .skphoto{width:64px;height:64px}
    .skhdr .skphoto:last-child{display:none}
    .skwho .sk{max-width:100%}
    .skpair{grid-template-columns:1fr;gap:14px}
    .dead{padding:40px 16px}
  }
  /* ---------- Teams (team profiles, phase 1: 16 October 2026) ----------
     body/04c-teams.html, scripts/11d-teams.js. The standings are the tools'
     own tables, a block a division. A club's page: a band in the club's
     colour (--tm, set off its crest; the page's band until it is read), its
     sub-tabs underlined in a lighter shade of it (--tma), and panels of
     numbers in the front page's look. The numbers stay orange (his word). */

  /* A crest that opens its club's page (scripts/11d-teams.js clubAttrs): the card's, Compare's, the Lines tab's. */
  [data-club]{cursor:pointer}
  [data-club]:focus{outline:none}
  [data-club]:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}

  /* The standings. */
  .tmlg{margin:22px 0 4px;font-family:var(--font-display);font-weight:700;font-size:24px;letter-spacing:.03em;color:#fff}
  .tmblock{margin:0 0 22px}
  .tmgh{margin:10px 0 8px;font-family:var(--font-display);font-weight:600;font-size:15px;letter-spacing:.06em;text-transform:uppercase;color:var(--brand-text)}
  /* The crest and the name side by side; a long name wraps beside its crest rather than running into GP when the
     pinned column is narrow (a phone's 124px, 24-phone.css). William, 17 October 2026: "depending on the width, looks
     like the UI breaks". */
  .tmtable td.tmcl a{display:flex;align-items:center;gap:8px;min-width:0;white-space:normal;overflow-wrap:anywhere;line-height:1.2}
  .tmtable td.tmcl{min-width:190px}
  .tmtable td.tmcl img{width:22px;height:22px;object-fit:contain;flex:none}
  .tmtable .tmrecc{white-space:nowrap;color:var(--ink2)}
  /* Team Stats (scripts/11f-team-stats.js): the club's crest beside its name, as in the standings. */
  .tstable td.tmcl a{display:flex;align-items:center;gap:8px;min-width:0;white-space:normal;overflow-wrap:anywhere;line-height:1.2}
  .tstable td.tmcl{min-width:200px}
  .tstable td.tmcl img{width:22px;height:22px;object-fit:contain;flex:none}
  @media(max-width:700px){.tstable td.tmcl{min-width:0}}
  .tstable td.tslead{white-space:nowrap}
  .tstable td.tslead a{color:var(--brand-text);text-decoration:none}
  .tstable td.tslead a:hover{color:#fff;text-decoration:underline;text-underline-offset:2px}

  /* The standings, staging (17 October 2026): the three leagues side by side, a column each, a club a
     row with its place, its record and its goal differential (scripts/11d-teams.js, tmMini). One
     column under another where three would squeeze the names. */
  .tmcols{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:18px 26px;align-items:start}
  .tmcol{min-width:0}
  /* Each league is a panel, the site's box (.tmbox, as a club page's and a box score's), its rule in orange. */
  #tmBoard{--tma:var(--brand)}
  .tmcol h3{display:flex;align-items:baseline;gap:10px}
  .tmcnote{font-family:var(--font-body);font-size:12px;font-weight:500;letter-spacing:0;color:var(--muted)}
  .tmcol .tmblock{margin:0 0 14px}
  .tmcol .tmblock:last-child{margin-bottom:0}
  .tmcol .tmgh{margin:12px 0 6px}
  .tmcol .tmblock:first-of-type .tmgh{margin-top:4px}
  .ctl .tmmini{width:100%;min-width:0;table-layout:fixed}
  .ctl .tmmini thead th{position:static;border-bottom-width:1px}
  .ctl .tmmini .rk{width:34px}
  .ctl .tmmini th:nth-child(3){width:23%}
  .ctl .tmmini th:nth-child(4){width:10%}
  .ctl .tmmini th:nth-child(5){width:11%}
  .ctl .tmmini td.tmcl a{display:flex;align-items:center;gap:8px;min-width:0}
  /* A long name takes a second line rather than being cut (since the points column, 17 October 2026). */
  .ctl .tmmini td.tmcl span{white-space:normal;overflow-wrap:anywhere;line-height:1.2}
  .ctl .tmmini td.tmcl img{width:22px;height:22px;object-fit:contain;flex:none}
  .ctl .tmmini .tmsrec,.ctl .tmmini .tmsgd{color:var(--ink)}
  .ctl .tmmini .tmspts{color:#fff;font-weight:600}
  @media(max-width:1100px){.tmcols{grid-template-columns:minmax(0,1fr)}}
  /* A phone: a long name takes a second line rather than being cut. */
  @media(max-width:700px){.ctl .tmmini td.tmcl span{white-space:normal;overflow-wrap:anywhere;line-height:1.2}}

  /* A club. */
  .tmclub{--tm:var(--band);--tma:var(--brand-text)}
  .tmclub.busy .tmhead,.tmclub.busy .tmpart{opacity:.55;transition:opacity .15s}
  .tmback{display:inline-block;margin:4px 0 10px;font-size:14px;font-weight:600;color:var(--muted);text-decoration:none}
  .tmback:hover{color:#fff}
  .tmhead{border:1px solid var(--box);border-radius:12px;overflow:hidden;background:var(--surface)}
  .tmband{display:flex;align-items:center;gap:18px;padding:18px 22px;background:var(--tm);color:var(--onband);transition:background .3s}
  .tmcrest{flex:none;display:grid;place-items:center;width:84px;height:84px;border-radius:50%;background:rgba(255,255,255,.94)}
  .tmcrest img{width:68px;height:68px;object-fit:contain}
  .tmname{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}
  .tmcity{font-family:var(--font-display);font-weight:600;font-size:17px;letter-spacing:.08em;text-transform:uppercase;color:var(--onband-dim);line-height:1.2}
  .tmnick{margin:0;font-family:var(--font-display);font-weight:700;font-size:44px;line-height:1.05;letter-spacing:.02em;text-transform:uppercase;color:#fff}
  .tmgrp{margin-top:4px;font-size:14px;color:var(--onband-dim)}
  .tmrec{display:flex;flex-direction:column;align-items:flex-end;text-align:right;flex:none}
  .tmrecn{font-family:var(--font-display);font-weight:700;font-size:38px;line-height:1.05;color:#fff}
  .tmrecl{font-size:14px;color:var(--onband-dim)}
  .tmplace{margin-top:4px;font-size:15px;font-weight:600;color:#fff}
  .tmctl{display:flex;align-items:center;gap:16px;flex-wrap:wrap;padding:10px 22px;border-top:1px solid var(--line)}
  .tmctl label{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--muted)}
  .tmctl .modeseg{margin:0}

  .tmtabs{display:flex;gap:4px;margin:14px 0 16px;border-bottom:1px solid var(--line);overflow-x:auto}
  .tmtabs button{padding:10px 16px;border:0;background:none;font:inherit;font-family:var(--font-display);font-weight:600;font-size:17px;
                 letter-spacing:.04em;text-transform:uppercase;color:var(--muted);cursor:pointer;border-bottom:3px solid transparent;white-space:nowrap}
  .tmtabs button:hover{color:#fff}
  .tmtabs button[aria-selected="true"]{color:#fff;border-bottom-color:var(--tma)}
  .tmtabs button:focus{outline:none}
  .tmtabs button:focus-visible{box-shadow:inset 0 0 0 2px var(--brand-text)}

  /* Overview: the numbers by group, and the games beside them. */
  .tmpart#tmOverview{display:grid;grid-template-columns:minmax(0,1fr) 320px;gap:18px;align-items:start}
  .tmpart#tmOverview[hidden]{display:none}
  .tmgrid{display:grid;grid-template-columns:minmax(0,1fr);gap:16px}
  .tmside{display:flex;flex-direction:column;gap:16px}
  .tmbox{padding:14px 16px;border:1px solid var(--box);border-radius:12px;background:var(--surface)}
  .tmbox h3{margin:0 0 10px;font-family:var(--font-display);font-weight:700;font-size:18px;letter-spacing:.04em;text-transform:uppercase;color:#fff;
            padding-bottom:8px;border-bottom:2px solid var(--tma)}
  .tmtiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(104px,1fr));gap:10px}
  .tmtile{display:flex;flex-direction:column;padding:8px 10px;border-radius:8px;background:var(--surface2)}
  .tml{font-family:var(--font-display);font-size:13px;font-weight:600;letter-spacing:.06em;color:var(--muted)}
  .tmv{font-family:var(--font-display);font-weight:700;font-size:26px;line-height:1.15;color:var(--brand-text)}
  .tmr{font-size:12.5px;color:var(--faint);white-space:nowrap}
  .tmr.top{color:var(--ink)}
  .tmnote{grid-column:1 / -1;margin:4px 0 0;font-size:13.5px;line-height:1.5;color:var(--faint)}

  .tmgames{list-style:none;margin:0;padding:0}
  .tmgames li{display:flex;align-items:center;gap:8px;padding:7px 0;border-bottom:1px solid var(--line);font-size:15px}
  .tmgames li:last-child{border-bottom:0}
  .tmd{width:78px;flex:none;color:var(--muted);font-size:14px}
  .tmwhere{width:20px;flex:none;color:var(--faint);font-size:13px}
  .tmopp{display:inline-flex;align-items:center;gap:6px;color:var(--ink);text-decoration:none;font-weight:600}
  a.tmopp:hover span{text-decoration:underline}
  .tmopp img{width:20px;height:20px;object-fit:contain}
  .tmout{margin-left:auto;white-space:nowrap}
  .tmres{display:inline-block;min-width:34px;font-weight:700}
  .tmres.rW{color:var(--good)}
  .tmres.rL{color:var(--muted)}
  .tmres.rOTL,.tmres.rSOL{color:var(--ink2)}
  .tmot{font-size:12.5px;color:var(--faint)}
  .tmtime{color:var(--ink2)}

  /* Roster and schedule: the tools' tables. */
  .tmrbar{display:flex;align-items:center;gap:14px;flex-wrap:wrap;margin:0 0 10px}
  .tmrbar .lbmeta{margin:0}
  .tmstable td{white-space:nowrap}
  .tmstable .tmdc{color:var(--ink2)}
  .tmstable .tmven{color:var(--muted)}
  .tmstable tr.tmfut td{color:var(--muted)}
  .tmptable td{white-space:nowrap}
  .tmnhl{display:flex;align-items:center;gap:6px}
  .tmnhl img{width:22px;height:22px;object-fit:contain}
  .tmmoved{font-size:12px;color:var(--faint);border:1px solid var(--line);border-radius:4px;padding:0 4px}

  /* Charts. The club in its accent, the rest in greys; text in the page's inks. */
  #tmchBody{display:flex;flex-direction:column;gap:16px}
  .tmchh{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin-bottom:10px;padding-bottom:8px;border-bottom:2px solid var(--tma)}
  .tmchh h3{margin:0;padding:0;border:0}
  .tmchctl{display:flex;flex-wrap:wrap;gap:8px 12px;align-items:center}
  .tmchctl .seg.smview{margin:0}
  .tmmaps{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}
  .tmmap{margin:0}
  .tmmap figcaption{font-family:var(--font-display);font-weight:600;font-size:15px;letter-spacing:.06em;text-transform:uppercase;color:var(--ink);margin-bottom:6px}
  .tmmap svg{width:100%;height:auto;display:block;background:var(--surface2);border-radius:10px}
  .tmsum{margin:6px 0 0;font-size:14px;color:var(--ink2)}
  .tmleg{display:flex;gap:14px;flex-wrap:wrap;font-size:13.5px;color:var(--ink2)}
  .tmleg span{display:inline-flex;align-items:center;gap:6px}
  .tmleg i{display:inline-block;width:16px;height:3px;border-radius:2px}
  .tmleg-me i{background:var(--tma)}
  .tmleg-other i{background:var(--muted)}
  .tmchart{position:relative}
  .tmsvg{width:100%;height:auto;display:block;touch-action:pan-y}
  .tmgrid{stroke:var(--line);stroke-width:1}
  .tmmid{stroke:var(--ink2);stroke-opacity:.45;stroke-width:1}
  .tmax{fill:var(--muted);font-size:11px;font-family:var(--font-body)}
  .tmend{fill:var(--ink2);font-size:11px;font-family:var(--font-body)}
  .tmend.me{fill:#fff;font-weight:600}
  .tmline{fill:none;stroke-width:2;stroke-linejoin:round;stroke-linecap:round}
  .tmline-me{stroke:var(--tma);stroke-width:2.5}
  .tmline-other{stroke:var(--muted);stroke-dasharray:5 4}
  .tmline-rest{stroke:var(--faint);stroke-opacity:.7;stroke-width:1.5}
  .tmcross{stroke:var(--ink2);stroke-width:1;stroke-opacity:.5}
  .tmtip{position:absolute;z-index:3;display:flex;flex-direction:column;gap:2px;padding:8px 10px;border:1px solid var(--box);border-radius:8px;
         background:var(--surface);font-size:13px;color:var(--ink2);pointer-events:none;white-space:nowrap;box-shadow:0 4px 16px rgba(0,0,0,.35)}
  .tmtip b{color:#fff;font-weight:600}
  .tmtip .me{color:#fff;font-weight:600}
  .tmbars2{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:22px}
  .tmbh{margin:0 0 8px;font-size:13px;font-weight:600;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
  .tmbr{display:grid;grid-template-columns:96px minmax(0,1fr);gap:2px 10px;margin-bottom:10px}
  .tmbl{grid-row:span 2;align-self:center;font-size:14px;color:var(--ink2)}
  .tmbt{display:flex;align-items:center;gap:6px;height:12px}
  .tmb{display:block;height:10px;min-width:2px;border-radius:0 4px 4px 0}
  .tmb-me{background:var(--tma)}
  .tmb-other{background:var(--muted)}
  .tmbn{font-size:12.5px;color:var(--ink2)}

  /* Lines. A man a column, his number in a slot of its own, so the names start level down a table (William, 16
     October 2026: "make all the names line up"). The latest sheet is the Lines page's own drawing (.lv*, 09-lines.css). */
  #tmlnBody{display:flex;flex-direction:column;gap:16px}
  #tmlnBody .tmrbar{margin:0}
  .tmlntable{width:100%}
  .tmlntable td{white-space:nowrap}
  .tmF .tmpos{width:21%}
  .tmD .tmpos{width:27%}
  .tmG .tmpos{width:34%}
  .tmG .tmfill{width:auto}
  /* The heading over the names, not over the numbers: the number slot (24px) and its gap (8px) in from the cell's own padding. */
  .ctl .tmlntable th.tmpos{padding-left:40px}
  .tmman{display:inline-grid;grid-template-columns:24px auto;column-gap:8px;align-items:baseline}
  .tmman a{color:var(--ink);text-decoration:none;font-weight:600}
  .tmman a:hover{text-decoration:underline}
  .tmman.none{display:inline;color:var(--faint)}
  .tmnum{font-size:12.5px;color:var(--muted);text-align:right}
  .tmsheet{display:flex;flex-direction:column;gap:6px}
  .tmsr{display:grid;grid-template-columns:32px repeat(3,minmax(0,1fr));gap:8px;align-items:center;padding:6px 8px;border-radius:8px;background:var(--surface2);font-size:14.5px}
  .tmsr.two{grid-template-columns:32px repeat(2,minmax(0,1fr)) minmax(0,1fr)}
  .tmsl{font-family:var(--font-display);font-weight:600;color:var(--tma)}
  .tmlv .lvteam{margin-top:0;border-top:0;padding-top:0}     /* the box heading's rule is the band already */

  /* History. */
  #tmhiBody{display:flex;flex-direction:column;gap:16px}
  .tmhtiles{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
  .tmhtiles .tmr{white-space:normal}            /* a club's titles are a list of years: it wraps */
  .tmhtiles .tmv{white-space:nowrap}
  .tmhtable td{white-space:nowrap;vertical-align:top}
  .tmhtable .tmseas{font-weight:600;text-align:left}
  .tmas{display:block;font-size:12px;font-weight:400;color:var(--muted)}
  .tmnow{font-size:11.5px;font-weight:600;color:var(--tma)}
  .tmwl{font-size:12.5px;color:var(--muted)}
  .tmtitle{font-weight:700;color:var(--tma)}
  .tmhtable tr.tmchamp td{background:color-mix(in srgb,var(--tma) 9%,transparent)}
  .tmlead span{display:block;line-height:1.35}
  .tmlead a{color:var(--ink);text-decoration:none}
  .tmlead a:hover{text-decoration:underline}
  .tmlead b{font-weight:600;color:var(--brand-text)}

  /* The Card button, at the end of the club's controls. */
  .tmpng{margin-left:auto;display:inline-flex;align-items:center;gap:8px}
  /* The team card, as it is photographed (1,500 wide; never on screen): the band, the numbers, the chart. */
  .tmcard{--tm:var(--band);--tma:var(--brand-text);background:var(--surface);border:1px solid var(--cardline);border-radius:14px;overflow:hidden;color:var(--ink)}
  .tmcard .tmcband{padding:26px 32px;gap:24px}
  .tmcard .tmcrest{width:132px;height:132px}
  .tmcard .tmcrest img{width:108px;height:108px}
  .tmcard .tmcity{font-size:24px}
  .tmcard .tmnick{font-size:68px}
  .tmcard .tmgrp{font-size:19px}
  .tmcard .tmrecn{font-size:60px}
  .tmcard .tmrecl{font-size:19px}
  .tmcard .tmplace{font-size:21px}
  .tmcbody{display:grid;grid-template-columns:minmax(0,1.15fr) minmax(0,1fr);gap:28px;padding:26px 32px 22px}
  /* A group a row, five slots a row (Shots has five), so every tile is the same width and they line up down the card. */
  .tmcstats{display:grid;grid-template-columns:minmax(0,1fr);gap:16px;align-content:start}
  .tmcgh{margin:0 0 10px;padding-bottom:8px;border-bottom:2px solid var(--tma);font-family:var(--font-display);font-weight:700;font-size:21px;
         letter-spacing:.05em;text-transform:uppercase;color:#fff}
  .tmctiles{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:10px}
  .tmct{display:flex;flex-direction:column;padding:10px 12px;border-radius:9px;background:var(--surface2)}
  .tmct .tml{font-size:15px}
  .tmct .tmv{font-size:34px}
  .tmct .tmr{font-size:14px;color:var(--ink2)}
  .tmcch{display:flex;align-items:flex-end;justify-content:space-between;gap:12px;flex-wrap:wrap}
  .tmcch .tmcgh{flex:1 1 auto}
  .tmcch .tmleg{margin-bottom:12px;font-size:15px}
  .tmccv{display:block;width:100%;margin-top:6px}
  .tmcsub{margin:8px 0 0;font-size:15px;line-height:1.4;color:var(--muted)}
  .tmcard .tmcfoot{margin:0 32px;padding:12px 0 16px;font-size:15px}

  /* Splits. */
  #tmspBody,#tmpnBody,#tmcmBody{display:flex;flex-direction:column;gap:16px}
  .tmsplit td{white-space:nowrap}
  /* Short tables: shown whole, not in the tools' scrolling box (a league has under 25 clubs, a season 12 months). */
  #tmspBody .lbscroll,#tmpnBody .lbscroll,#tmcmBody .lbscroll,#tmlnBody .lbscroll,#tmhiBody .lbscroll{max-height:none}
  .tmsplit .tmsl1{min-width:150px}
  .ctl .tmsplit th.tmsl1{text-align:left}
  .tmvsr{cursor:pointer}
  .tmvsr:hover td{background:var(--hover)}
  .tmvsr:focus{outline:none}
  .tmvsr:focus-visible td{box-shadow:inset 0 0 0 1px var(--brand-text)}
  .tmcaret{display:inline-block;width:14px;color:var(--faint);transition:transform .15s}
  .tmvsr.open .tmcaret{transform:rotate(90deg)}
  .tmvsr .tmopp{margin-right:8px}
  .tmnext{margin-left:4px}
  .tmvsd td{background:var(--surface2);white-space:normal}
  .tmvsg{display:inline-block;margin:2px 18px 2px 0;font-size:14px}
  /* The Roster's makeup. */
  #tmMakeup{margin-bottom:16px}
  .tmmkrow{display:grid;grid-template-columns:minmax(0,1.1fr) minmax(0,1fr) minmax(0,1fr);gap:22px;align-items:start}
  .tmmktiles{grid-template-columns:repeat(2,minmax(0,1fr))}
  .tmmktiles .tmr{white-space:normal}           /* "20 in the season's first year" wraps on a phone, not out of its tile */
  .tmdyr{display:grid;grid-template-columns:52px minmax(0,1fr);gap:10px;align-items:center;margin-bottom:6px}
  .tmnat{display:flex;flex-wrap:wrap;gap:6px;align-content:flex-start}
  .tmnat .tmbh{flex-basis:100%}
  .tmnatc{padding:4px 9px;border-radius:7px;background:var(--surface2);font-size:14px;color:var(--ink2)}
  .tmnatc b{color:#fff;font-weight:600}
  /* Penalties. Two columns read down, as a grid: CSS columns with unbreakable rows put the last one in a third
     column off the page's right edge at 1,920px (the width check of 17 October 2026). --pnrows is set by the script. */
  .tmpnbars{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:repeat(var(--pnrows,8),auto);grid-auto-flow:column;column-gap:28px}
  /* Its tiles say more under each number than the Overview's ("penalties that put it short-handed"): wider, and they wrap. */
  .tmpntiles{grid-template-columns:repeat(auto-fill,minmax(150px,1fr))}
  .tmpntiles .tmr{white-space:normal}
  /* Compare. */
  .tmcmpick{display:flex;align-items:center;gap:8px;font-size:14px;color:var(--muted)}
  .tmcmtable{width:100%}
  .tmcmtable th.tmcmc{text-align:left;vertical-align:bottom}
  .tmcmc img{display:block;width:28px;height:28px;object-fit:contain;margin-bottom:4px}
  .tmcmc span{display:block}
  .tmcmv{width:40%}
  .tmcmv b{font-weight:600;color:var(--ink)}
  .tmcmv.on b{color:var(--brand-text)}
  /* Crowds on the Overview. */
  .tmcrowd{display:flex;flex-direction:column}
  .tmcrowd .tmv{font-family:var(--font-display);font-weight:700;font-size:30px;color:var(--brand-text)}

  @media(max-width:1000px){
    .tmmkrow{grid-template-columns:minmax(0,1fr)}
    .tmpart#tmOverview{grid-template-columns:minmax(0,1fr)}
  }
  @media(max-width:700px){
    .tmpnbars{grid-template-columns:minmax(0,1fr);grid-template-rows:none;grid-auto-flow:row}
    .tmpntiles{grid-template-columns:repeat(2,minmax(0,1fr))}
    /* A chart is drawn at 640 wide and shrunk to the screen: its words are drawn larger to stay readable. */
    .tmax,.tmend{font-size:19px}
    .tmhtiles{grid-template-columns:repeat(2,minmax(0,1fr))}
    .tmhtiles .tmv{font-size:22px}
    .tmsr,.tmsr.two{grid-template-columns:28px minmax(0,1fr)}
    .tmsr .tmman{grid-column:2}
    .tmmaps,.tmbars2{grid-template-columns:minmax(0,1fr)}
    .tmtiles{grid-template-columns:repeat(auto-fill,minmax(92px,1fr))}
    .tmband{flex-wrap:wrap;gap:12px;padding:14px 16px}
    .tmcrest{width:64px;height:64px}
    .tmcrest img{width:52px;height:52px}
    .tmnick{font-size:32px}
    .tmrec{flex-basis:100%;align-items:flex-start;text-align:left}
    .tmrecn{font-size:28px}
    .tmctl{padding:10px 16px}
  }
  /* ---------- Scores and box scores (box scores, step 1: 16 October 2026) ----------
     body/04d-games.html, scripts/11e-games.js. The day's games are cards in a
     grid, a league a block; a game's page borrows the club page's panels
     (.tmbox) and tables (.lbtable), with a band split in the two clubs'
     colours (--gma, --gmh, set off their crests; the page's band until read).
     The numbers stay orange, as on a club's page. */

  /* The day: arrows either side of a calendar, and Today. */
  .gmday{display:flex;align-items:center;gap:6px}
  .gmstep,.gmtoday{height:34px;min-width:34px;padding:0 10px;border:1px solid var(--line);border-radius:8px;background:var(--surface);
                   color:var(--ink);font:inherit;font-size:16px;cursor:pointer}
  .gmtoday{font-size:14px;font-weight:600}
  .gmstep:hover:not(:disabled),.gmtoday:hover:not(:disabled){background:var(--hover)}
  .gmstep:disabled,.gmtoday:disabled{opacity:.4;cursor:default}
  .gmdate input{height:34px;padding:0 8px;border:1px solid var(--line);border-radius:8px;background:var(--surface);color:var(--ink);font:inherit;
                color-scheme:dark}

  /* A game on the day's list. */
  .gmcards{display:grid;grid-template-columns:repeat(auto-fill,minmax(270px,1fr));gap:12px;margin:0 0 18px}
  .gmcard{display:flex;flex-direction:column;gap:6px;padding:12px 14px;border:1px solid var(--box);border-radius:12px;background:var(--surface);
          color:var(--ink);text-decoration:none;transition:background .12s,border-color .12s}
  .gmcard:hover{background:var(--hover);border-color:var(--brand-text)}
  .gmcard:focus{outline:none}
  .gmcard:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}
  .gmct{display:flex;align-items:center;gap:8px;font-size:13px;color:var(--muted)}
  .gmst{font-family:var(--font-display);font-weight:600;letter-spacing:.06em;text-transform:uppercase}
  .gmst.fin{color:var(--ink)}
  .gmpo{margin-left:auto;font-size:12px;border:1px solid var(--line);border-radius:4px;padding:0 5px}
  .gmcr{display:flex;align-items:center;gap:10px;min-width:0}
  .gmcr img,.gmnocrest{width:28px;height:28px;object-fit:contain;flex:none}
  .gmcn{display:flex;flex-direction:column;min-width:0;flex:1 1 auto;line-height:1.15}
  .gmcn b{font-family:var(--font-display);font-weight:700;font-size:19px;letter-spacing:.02em;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .gmcn small{font-size:12.5px;color:var(--muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .gmcs{font-family:var(--font-display);font-weight:700;font-size:26px;line-height:1;color:var(--ink2);min-width:22px;text-align:right}
  .gmcr.won .gmcs{color:var(--brand-text)}
  .gmcr.lost .gmcn b{color:var(--ink2)}
  .gmcf{margin-top:2px;padding-top:6px;border-top:1px solid var(--line);font-size:12.5px;color:var(--faint);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .gmcard.fut .gmcs{display:none}

  /* A game's page. */
  .gmgame{--tma:var(--brand-text)}
  .gmgame.busy .gmhead,.gmgame.busy #gmBody{opacity:.55;transition:opacity .15s}
  .gmhead{--gma:var(--band);--gmh:var(--band);border:1px solid var(--box);border-radius:12px;overflow:hidden;background:var(--surface);margin-bottom:16px}
  .gmband{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:14px;padding:18px 22px;
          background:linear-gradient(90deg,var(--gma) 0%,var(--gma) 38%,var(--band) 50%,var(--gmh) 62%,var(--gmh) 100%);color:var(--onband)}
  .gmclub.home{justify-self:end;text-align:right}
  .gmclubl{display:flex;align-items:center;gap:14px;color:#fff;text-decoration:none;min-width:0}
  a.gmclubl:hover .gmnick{text-decoration:underline}
  .gmcrest{width:72px;height:72px}
  .gmcrest img{width:58px;height:58px}
  .gmcname{display:flex;flex-direction:column;min-width:0}
  .gmnick{font-family:var(--font-display);font-weight:700;font-size:34px;line-height:1.05;letter-spacing:.02em;text-transform:uppercase;color:#fff}
  .gmrec{font-size:14px;color:var(--onband-dim)}
  .gmmid{display:flex;flex-direction:column;align-items:center;gap:4px;padding:0 6px}
  .gmscore{font-family:var(--font-display);font-weight:700;font-size:52px;line-height:1;color:#fff;white-space:nowrap}
  .gmstatus{font-family:var(--font-display);font-weight:600;font-size:15px;letter-spacing:.08em;text-transform:uppercase;color:var(--onband-dim);white-space:nowrap}
  .gmwhen{margin:0;padding:10px 22px;border-top:1px solid var(--line);font-size:14px;color:var(--muted);text-align:center}

  #gmBody{display:flex;flex-direction:column;gap:16px}
  /* The score by period as wide as its table; the xG chart beside it, in the rest and as tall as it (gmFlowDraw). */
  .gmrow{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:16px;align-items:stretch}
  .gmsmall{margin:8px 0 0;font-size:13px;color:var(--faint)}
  .gmnote{margin:0}
  .gmnone{margin:4px 0 8px;color:var(--muted);font-size:14px}

  /* By period: as wide as its numbers, not the box (William, 16 October 2026: "way too much space. Can we make it
     tighter?"). No frame of its own inside the panel's, short rows, each number column the width of "0.00". */
  .gmper .lbscroll{border:0;border-radius:0;max-height:none}
  .gmptable{width:auto}
  .ctl .gmptable td,.ctl .gmptable th{white-space:nowrap;padding:4px 6px}
  .ctl .gmptable thead th{padding:2px 6px 6px}
  .ctl .gmptable td.num,.ctl .gmptable th.num{min-width:38px;text-align:center}
  .ctl .gmptable td.gmtot,.ctl .gmptable thead th:last-child{padding-left:14px}
  .ctl .gmptable .gmph th{padding:10px 0 2px;text-align:left;font-family:var(--font-display);font-weight:600;font-size:12px;letter-spacing:.06em;text-transform:uppercase;color:var(--muted);background:none;border:0}
  .gmpc{display:flex;align-items:center;gap:6px;font-weight:600;padding-right:10px}
  .gmpc img{width:18px;height:18px;object-fit:contain}
  .gmtot{font-weight:700;color:var(--brand-text)}
  /* The shootout's line wraps to the table's width rather than setting the box's. */
  .gmper .gmsmall{width:0;min-width:100%}

  /* Best of the night: a strip across, a tile a man (under the players' tables since William's word). */
  .gmstarl{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px}
  .gmstarl li{display:flex;align-items:center;gap:12px;padding:10px 14px;border-radius:10px;background:var(--surface2)}
  .gmsn{width:18px;flex:none;font-family:var(--font-display);font-weight:700;font-size:22px;color:var(--muted)}
  .gmci{width:22px;height:22px;object-fit:contain;flex:none}
  .gmsw{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}
  .gmsw small{display:flex;align-items:center;gap:5px;font-size:13px;color:var(--muted)}
  .gmsw small .gmci{width:16px;height:16px}

  /* A face in a ring of its club's colour (--fa, --fh: the chart's), its initials under the picture. */
  .gmgame{--fa:var(--brand-text);--fh:var(--ink2)}
  .gmface{position:relative;flex:none;display:inline-grid;place-items:center;border-radius:50%;overflow:hidden;background:var(--surface3);
          box-shadow:0 0 0 2px var(--fa);font-family:var(--font-display);font-weight:700;font-size:12px;color:var(--ink2)}
  .gmface.home{box-shadow:0 0 0 2px var(--fh)}
  .gmface img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
  /* No man to show (a bench penalty, a feed event naming nobody): the room kept, so the names stay in one column. */
  .gmface.gmfnone{background:none;box-shadow:none}

  /* The expected goals as the game went. */
  .gmftop{display:flex;align-items:center;justify-content:center;gap:12px;margin:-2px 0 4px}
  .gmft{display:inline-flex;align-items:center;gap:8px}
  .gmft b{font-family:var(--font-display);font-weight:700;font-size:26px}
  .gmft.a b{color:var(--fa)}
  .gmft.h b{color:var(--fh)}
  .gmfdash{color:var(--faint);font-size:20px}
  /* The chart takes what the section has left once By period sets the row's height; drawn at that size (gmFlowDraw), its
     drawing never sets a size of its own. */
  .gmfbox{position:relative;flex:1 1 0;min-height:220px}
  .gmfbox svg{position:absolute;inset:0;display:block}
  .gmfg{stroke:var(--line);stroke-width:1;stroke-dasharray:3 4}
  .gmfp{stroke:var(--ink2);stroke-opacity:.4;stroke-width:1;stroke-dasharray:4 4}
  .gmfax{fill:var(--muted);font-size:10.5px;font-family:var(--font-body)}
  .gmfpl{fill:var(--ink2);font-size:11px;font-family:var(--font-display);font-weight:600;letter-spacing:.06em;text-transform:uppercase}
  .gmfl{fill:none;stroke-width:2.2;stroke-linejoin:round}
  .gmfl.a,.gmfd.a{stroke:var(--fa)}
  .gmfl.h,.gmfd.h{stroke:var(--fh)}
  .gmfd.a{fill:var(--fa)}
  .gmfd.h{fill:var(--fh)}
  .gmfgoal{position:absolute;transform:translate(-50%,-50%);line-height:0}
  .gmflow{min-width:0;display:flex;flex-direction:column}
  .gmsv{font-family:var(--font-display);font-weight:700;font-size:24px;color:var(--brand-text)}
  .gmnm{color:var(--ink);font-weight:600;text-decoration:none}
  a.gmnm:hover{text-decoration:underline}

  /* Team stats: the two numbers either side, the shares as one bar. */
  .gmtrh{display:flex;justify-content:space-between;margin:-2px 0 6px;font-family:var(--font-display);font-weight:700;font-size:16px;letter-spacing:.04em}
  .gmtrh span{display:inline-flex;align-items:center;gap:6px}
  .gmtr{display:grid;grid-template-columns:70px minmax(0,1fr) 70px;align-items:center;gap:10px;padding:6px 0;border-bottom:1px solid var(--line)}
  .gmtr:last-child{border-bottom:0}
  /* The numbers white, each club's code and share of the bar in its colour (--fa, --fh, read off the crests; orange and
     grey until read). William, 16 October 2026: "use team colours for bars and numbers", then "change numbers to
     white, keep bars team colours". */
  .gmtv{font-family:var(--font-display);font-weight:700;font-size:20px;color:#fff}
  .gmtrh .a{color:var(--fa)}
  .gmtrh .h{color:var(--fh)}
  .gmtv:last-child{text-align:right}
  .gmtl{display:flex;flex-direction:column;align-items:center;gap:5px;font-size:13.5px;color:var(--ink2)}
  .gmtb{display:flex;width:100%;height:6px;border-radius:3px;overflow:hidden;background:var(--track)}
  .gmtb i{display:block;height:100%}
  .gmtb i.a{background:var(--fa)}
  .gmtb i.h{background:var(--fh);box-shadow:inset 2px 0 0 var(--surface)}

  /* Goals and penalties: a line an event. */
  .gmpl{display:flex;align-items:center;gap:8px;margin:12px 0 4px;font-family:var(--font-display);font-weight:600;font-size:15px;letter-spacing:.06em;text-transform:uppercase;color:var(--brand-text)}
  .gmpl:first-of-type{margin-top:2px}
  .gmev{list-style:none;margin:0;padding:0}
  .gmev li{display:flex;align-items:center;gap:10px;padding:7px 0;border-bottom:1px solid var(--line)}
  .gmev li:last-child{border-bottom:0}
  .gmt{width:44px;flex:none;color:var(--muted);font-variant-numeric:tabular-nums}
  .gmwho{display:flex;flex-direction:column;min-width:0;flex:1 1 auto}
  .gmwho small{font-size:13px;color:var(--muted)}
  .gmln{display:block}
  .gmwho small .gmnm{color:var(--ink2);font-weight:400}
  .gmcount{color:var(--faint);font-weight:400}
  .gmtag{display:inline-block;margin-left:6px;padding:0 5px;border:1px solid var(--line);border-radius:4px;font-size:11.5px;font-weight:600;color:var(--ink2);vertical-align:1px}
  .gmxg{flex:none;font-size:13px;color:var(--faint)}
  .gmsc{flex:none;width:44px;text-align:right;font-family:var(--font-display);font-weight:700;font-size:18px;color:var(--ink)}

  /* Shot maps. */
  /* The legend under the maps (his word), and the empty nets left out beside it. */
  .gmleg{display:flex;flex-wrap:wrap;gap:6px 16px;margin:12px 0 0;font-size:13.5px;color:var(--ink2)}
  .gmleg .gmlegn{color:var(--faint)}
  .gmmapsh{display:flex;align-items:center;justify-content:space-between;gap:8px 12px;flex-wrap:wrap;margin:0 0 10px}
  .gmmapsh h3{margin:0}
  .gmmapsh .seg.smview{margin:0}
  .gmleg svg.gmzkey{width:34px;height:16px;flex:0 0 auto}
  /* A club's crest by its name over its map; the rink as wide as its column, every dot a pointer. */
  .gmmap figcaption{display:flex;align-items:center;gap:8px}
  /* Its two menus, between the name and the rink (his word), side by side, sharing the width. */
  .gmmf{display:flex;gap:8px;margin:0 0 8px}
  .gmmf label{flex:1 1 0;min-width:0}
  .ctl .gmmf select{width:100%;height:34px;font-size:14px}
  .gmrink svg{width:100%;height:auto;display:block;background:var(--surface2);border-radius:10px}
  .gmleg span{display:inline-flex;align-items:center;gap:6px}
  .gmleg i{display:inline-block;width:11px;height:11px;border-radius:50%}
  .gmleg i.g{background:#5fbd88;border:1px solid #fff}
  .gmleg i.s{border:1px solid #c8ccd0}

  /* The players: one box, a club at a time, picked at its top (his word); the heading's line under both. */
  .gmplh{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;margin:0 0 12px;padding-bottom:8px;border-bottom:2px solid var(--tma)}
  .gmplh h3{margin:0;padding:0;border:0}
  .gmpick{flex:none}
  .gmpick button{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
  .gmpick button .gmci{width:18px;height:18px}
  /* The goals' and penalties' box: how many of each on its switch. */
  .gmevn{color:var(--faint);font-weight:400}
  /* Every man of the night in sight: no scrolling within the table, as the site's long tables have. */
  .gmplayers .lbscroll{max-height:none}
  /* Every column centred, words and numbers alike (William, 16 October 2026: "why are FO lined to the left and FO% lined
     to the right? can't we make all the text in tables centred?"); the names alone stay left, a list to read down. */
  .ctl .gmplayers .lbtable thead th,.ctl .gmplayers .lbtable td{text-align:center}
  .ctl .gmplayers .lbtable thead th.stick,.ctl .gmplayers .lbtable td.stick{text-align:left}
  .gmsk,.gmgk{margin-bottom:10px}
  .gmsk td,.gmgk td{white-space:nowrap}
  .gmsk th.gmsort{cursor:pointer;user-select:none}
  .gmsk th.gmsort:hover{color:#fff}
  .gmsk th.gmsort.on{color:var(--brand-text)}
  .gmsk tr.gmdline td{border-top:2px solid var(--line)}
  .gmgs{color:var(--brand-text);font-weight:700}
  .gmsk .nil,.gmgk .nil{color:var(--faint)}

  /* The lines dressed: the two sheets side by side. */
  .gmsheets{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:18px}
  .gmsheet .gmpl{color:var(--ink)}

  /* A game's result in a table, as a link to its box score (a game log, a club's schedule). */
  a.gmlink{color:inherit;text-decoration:none;border-bottom:1px dotted var(--faint)}
  a.gmlink:hover{color:#fff;border-bottom-color:#fff}

  /* A league with no priced shots (the WHL): the score by period alone, as wide as its table. */
  .gmrow.one{grid-template-columns:max-content}
  @media (max-width:900px){
    .gmrow,.gmrow.one{grid-template-columns:minmax(0,1fr)}
    .gmstarl{grid-template-columns:minmax(0,1fr)}
    /* Stacked, nothing beside the chart sets its height: it grows with the width (William, of a stacked one, after its
       footnote went: "it should help gain some height"). */
    .gmfbox{min-height:clamp(240px,38vw,340px)}
  }
  @media (max-width:760px){
    .gmband{grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:8px;padding:14px 12px}
    .gmclubl{flex-direction:column;gap:6px;text-align:center}
    .gmclub.home .gmclubl{flex-direction:column-reverse}
    .gmclub.home{text-align:center}
    .gmcname{align-items:center}
    .gmcrest{width:52px;height:52px}
    .gmcrest img{width:42px;height:42px}
    .gmnick{font-size:20px;overflow-wrap:anywhere}
    .gmband .tmcity{font-size:12px}
    .gmscore{font-size:36px}
    .gmstatus{font-size:12.5px}
    .gmsheets{grid-template-columns:minmax(0,1fr)}
    .gmtr{grid-template-columns:52px minmax(0,1fr) 52px}
    .gmxg{display:none}
  }

  /* A man's night in a box of its own (gmPopOpen; William, 16 October 2026: "when you click on a players name in a
     box score, make it open a pop up window with all his stats and his shot map/save map for goalies"). Over the
     whole page, header included; the page under it does not scroll; a shot's box over it. */
  .gmpop{position:fixed;inset:0;z-index:100;display:grid;place-items:center;padding:12px}
  .gmpop[hidden]{display:none}
  .gmpopbg{position:absolute;inset:0;background:rgba(0,0,0,.62)}
  .gmpopc{position:relative;width:min(460px,100%);max-height:calc(100vh - 24px);overflow:auto;padding:18px 18px 16px;
          border:1px solid var(--box);border-radius:14px;background:var(--surface);box-shadow:0 18px 50px rgba(0,0,0,.5)}
  body.gmpopping{overflow:hidden}
  body.gmpopping .sctip{z-index:120}
  .gmpopx{position:absolute;top:8px;right:10px;width:34px;height:34px;border:0;border-radius:8px;background:none;color:var(--muted);font-size:24px;line-height:1;cursor:pointer}
  .gmpopx:hover{background:var(--hover);color:#fff}
  /* Not the control set's boxed button: a plain × with a ring for the keyboard alone. */
  .ctl .gmpopx{height:34px;padding:0;border:0;box-shadow:none}
  .ctl .gmpopx:focus{outline:none}
  .ctl .gmpopx:focus-visible{box-shadow:0 0 0 2px var(--brand-text)}
  .gmpoph{display:flex;align-items:center;gap:14px;padding:0 34px 14px 0;margin-bottom:12px;border-bottom:1px solid var(--line)}
  .gmpoph .gmface{font-size:20px}
  .gmpopn{display:flex;flex-direction:column;gap:3px;min-width:0}
  .gmpopn .gmpopname{font-family:var(--font-display);font-weight:700;font-size:24px;line-height:1.1;color:#fff;text-decoration:none}
  .gmpopn .gmpopname:hover{color:var(--brand-text);text-decoration:underline;text-underline-offset:3px}
  .gmpopn span{display:flex;align-items:center;gap:5px;font-size:14px;color:var(--muted)}
  .gmpopn .gmci{width:18px;height:18px}
  .gmpops{display:grid;grid-template-columns:repeat(auto-fill,minmax(62px,1fr));gap:10px 6px;margin:0 0 14px}
  .gmpopt{display:flex;flex-direction:column;align-items:center}
  .gmpopt b{font-family:var(--font-display);font-weight:700;font-size:21px;line-height:1.1;color:#fff}
  .gmpopt span{font-size:12px;letter-spacing:.04em;color:var(--muted)}
  .gmpopper{margin:0 0 10px}
  .gmpopper button{padding:6px 8px}
  /* The rink no wider than 360px, so his whole box fits a laptop's window without scrolling. */
  .gmpoprink{max-width:360px;margin:0 auto}
  .gmpoprink svg{width:100%;height:auto;display:block;background:var(--surface2);border-radius:10px}
  .gmleg i.ga{background:#e0625a;border:1px solid #fff}

  /* A game to come: its pregame (gmPre). The line over it, the lines or that they are not set, the two clubs' seasons,
     their players. */
  .gmprelines{margin-bottom:16px}
  .gmnolines{padding:6px 0}
  .gmpreteams{margin-bottom:16px}
  /* A row a club, as the players' table (his word: "move the team stats into a horizontal row like we do players"):
     the groups over their columns, a line where each starts, each number with its place under it. */
  .gmprec{display:flex;align-items:center;gap:10px;min-width:0}
  .gmprec .gmci{width:28px;height:28px}
  .gmprec > span{display:flex;flex-direction:column;min-width:0}
  .gmprec b{font-family:var(--font-display);font-weight:700;font-size:18px;line-height:1.1;color:#fff;text-transform:uppercase;letter-spacing:.02em}
  .gmprec small{font-size:12px;color:var(--muted);white-space:nowrap}
  .gmprevs{font-family:var(--font-display);font-weight:700;font-size:15px;letter-spacing:.08em;text-transform:uppercase;color:var(--faint)}
  .gmpretable td,.gmpretable th{white-space:nowrap}
  .gmpretable td b{display:block;font-family:var(--font-display);font-weight:500;font-size:17px;line-height:1.15;color:var(--ink2)}
  .gmpretable td small{display:block;font-size:10.5px;color:var(--faint)}
  /* The leader in a stat: bold and white (his word: "bold stat for the team leading in that category"). */
  .gmpretable td.lead b{font-weight:700;color:#fff}
  .gmpretable .gs{border-left:1px solid var(--line)}
  .ctl .gmpretable tr.gmpregrp th{font-family:var(--font-display);font-weight:600;font-size:13px;letter-spacing:.06em;text-transform:uppercase;color:var(--brand-text)}
  .gmpreplayers th.gmpresort{cursor:pointer;user-select:none}
  .gmpreplayers th.gmpresort:hover{color:#fff}
  .gmpreplayers th.gmpresort.on{color:var(--brand-text)}
  .gmpreplayers td .gmci{width:18px;height:18px;vertical-align:middle;margin-right:5px}

  /* ---- the pregame's form and head-to-head, goalie matchup and players to watch (17 October 2026) ---- */
  .gmpreform,.gmpregk,.gmprewatch{margin-bottom:16px}
  .gmfrow{display:grid;grid-template-columns:minmax(0,1fr) minmax(220px,300px) minmax(0,1fr);gap:16px;align-items:start}
  .gmfcol,.gmwcol{min-width:0;padding:10px 14px 12px;border:1px solid var(--line);border-radius:10px;background:var(--surface2)}
  .gmfhd{display:flex;align-items:center;gap:10px;margin:0 0 10px}
  .gmfhd b{font-family:var(--font-display);font-weight:700;font-size:20px;line-height:1.1;color:#fff;text-transform:uppercase;letter-spacing:.02em}
  .gmfstat{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px;margin:0 0 10px}
  .gmfstat span{display:flex;flex-direction:column;min-width:0}
  .gmfstat small{font-size:11.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--faint)}
  .gmfstat b{font-family:var(--font-display);font-weight:600;font-size:17px;color:var(--ink2);line-height:1.2}
  .gmfgames{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:6px}
  .gmfg{display:flex;flex-direction:column;align-items:center;padding:6px 2px;border:1px solid var(--line);border-radius:8px;background:var(--surface);text-decoration:none;color:var(--ink2);min-width:0}
  .gmfg:hover{border-color:var(--box)}
  .gmfg b{font-family:var(--font-display);font-weight:700;font-size:16px;color:var(--faint)}
  .gmfg.rW b{color:var(--brand-text)}
  .gmfg span{font-size:13px;white-space:nowrap}
  .gmfg small{font-size:11.5px;color:var(--faint);white-space:nowrap}
  .gmh2h{display:flex;flex-direction:column;align-items:center;padding:10px 12px;border:1px solid var(--line);border-radius:10px;background:var(--surface2);min-width:0}
  .gmh2h .gmpl{margin:0 0 4px}
  .gmh2hn{display:flex;align-items:center;gap:10px;font-family:var(--font-display);font-weight:700;font-size:34px;line-height:1.1;color:#fff}
  .gmh2hn i{font-style:normal;color:var(--faint);font-weight:500}
  .gmh2hl{display:flex;flex-direction:column;gap:4px;width:100%;margin-top:8px}
  .gmh2hl a{display:flex;justify-content:space-between;gap:8px;padding:4px 8px;border-radius:6px;background:var(--surface);text-decoration:none;color:var(--ink2);font-size:13.5px}
  .gmh2hl a:hover{background:var(--surface3)}
  .gmh2hl small{color:var(--faint);white-space:nowrap}
  .gmh2hl em{font-style:normal}
  .gmh2hl em.w{color:#fff;font-weight:700}
  .gmgrow{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:16px;align-items:center}
  .gmgcard{min-width:0;padding:12px 14px;border:1px solid var(--line);border-radius:10px;background:var(--surface2)}
  .gmghd{display:flex;align-items:center;gap:8px;margin:0 0 10px;font-family:var(--font-display);font-weight:600;font-size:15px;letter-spacing:.04em;text-transform:uppercase;color:var(--ink2)}
  .gmghd em{margin-left:auto;font-style:normal;font-size:12px;letter-spacing:.06em;color:var(--faint)}
  .gmghd em.sheet{color:var(--brand-text)}
  .gmgwho{display:flex;align-items:center;gap:14px;margin:0 0 10px}
  .gmgwho .gmface{font-size:20px}
  .gmgwho > div{display:flex;flex-direction:column;min-width:0}
  .gmgnm{font-family:var(--font-display);font-weight:700;font-size:21px;line-height:1.15}
  .gmgnm a{color:#fff;text-decoration:none}
  .gmgnm a:hover{color:var(--brand-text)}
  .gmgwho small{font-size:13px;color:var(--muted)}
  .gmgtiles{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:8px}
  .gmgtiles span{display:flex;flex-direction:column;align-items:center;padding:6px 4px;border-radius:8px;background:var(--surface)}
  .gmgtiles b{font-family:var(--font-display);font-weight:700;font-size:20px;color:var(--brand-text);line-height:1.1}
  .gmgtiles small{font-size:11.5px;letter-spacing:.06em;color:var(--faint)}
  .gmglast{margin:10px 0 0;font-size:13px;color:var(--muted)}
  .gmglast a{color:var(--ink2)}
  .gmwrow{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:16px}
  .gmwp{display:flex;align-items:center;gap:12px;padding:8px 0;border-top:1px solid var(--line)}
  .gmwp:first-of-type{border-top:0}
  .gmwp .gmface{font-size:16px}
  .gmwtx{display:flex;flex-direction:column;gap:2px;min-width:0}
  .gmwnm{display:flex;align-items:center;flex-wrap:wrap;gap:6px}
  .gmwnm .gmnm{font-family:var(--font-display);font-weight:700;font-size:18px;color:#fff;text-decoration:none}
  .gmwnm a.gmnm:hover{color:var(--brand-text)}
  .gmwnm small{font-size:12px;color:var(--faint)}
  .gmwnm .dy{padding:0 5px;border-radius:4px;font-size:11.5px;line-height:16px;background:var(--surface3);color:var(--ink2)}
  .gmwnm .dy.on{background:var(--good);color:#0f1a14}
  .gmwnhl{height:20px;width:auto;max-width:34px}
  .gmwwhy{font-size:14px;color:var(--brand-text)}
  .gmwln{font-size:13px;color:var(--muted)}
  /* The NHL prospects: a row a man, the logo of the club holding his rights at its right. */
  .gmpros .gmwtx{flex:1 1 auto}
  .gmpronhl{flex:0 0 auto;height:30px;width:auto;max-width:46px;margin-left:auto}
  .gmpron{margin-left:auto;font-size:12.5px;color:var(--faint)}
  .gmprotag{font-size:12px;color:var(--faint);border:1px solid var(--line);border-radius:4px;padding:0 4px}
  @media (max-width:1000px){
    .gmfrow{grid-template-columns:minmax(0,1fr)}
    .gmgrow{grid-template-columns:minmax(0,1fr)}
    .gmgrow .gmprevs{display:none}
    .gmwrow{grid-template-columns:minmax(0,1fr)}
  }
  @media (max-width:760px){
    .gmfstat{grid-template-columns:repeat(2,minmax(0,1fr))}
    .gmfg span{font-size:12px}
    .gmgtiles b{font-size:17px}
  }
  @media (max-width:760px){
    .gmprec b{font-size:15px}
  }
  /* The goalies' table apart from the skaters' (his word: "leave a gap between skaters and goalies boxes"), in both
     Players boxes. */
  .gmplayers .lbscroll + .lbscroll{margin-top:16px}

  /* ---- a game under way (box scores, step 2) ---- */
  /* LIVE, a power play, an empty net: under the score in the band. */
  .gmlivetag{display:flex;flex-wrap:wrap;justify-content:center;gap:4px 8px;font-family:var(--font-display);font-weight:600;font-size:13px;letter-spacing:.06em;text-transform:uppercase;color:#fff}
  .gmlivetag[hidden]{display:none}
  .gmlivedot{display:inline-flex;align-items:center;gap:5px;color:var(--brand-text);font-weight:700}
  .gmlivedot::before{content:"";width:8px;height:8px;border-radius:50%;background:var(--brand);animation:gmpulse 1.6s ease-in-out infinite}
  .gmpp,.gmen{padding:1px 7px;border-radius:4px;background:rgba(0,0,0,.35)}
  @keyframes gmpulse{0%,100%{opacity:1}50%{opacity:.25}}
  /* The goal alert (his word): the score flashes, the goals just in are lit a few seconds. */
  .gmscore.gmflash{animation:gmflash 1s ease-in-out 4}
  @keyframes gmflash{0%,100%{color:#fff;text-shadow:none}50%{color:var(--brand-text);text-shadow:0 0 18px var(--brand)}}
  .gmev li.gmnew{background:rgba(242,107,33,.16);transition:background 1s}
  @media (prefers-reduced-motion:reduce){ .gmlivedot::before,.gmscore.gmflash{animation:none} .gmscore.gmflash{color:var(--brand-text)} }
  /* The play-by-play: newest first, in its own scrolling list. */
  .gmpbp{margin-bottom:16px}
  .gmpbpl{list-style:none;margin:0;padding:0;max-height:420px;overflow:auto}
  .gmpbpl li{display:flex;align-items:center;gap:10px;padding:6px 2px;border-bottom:1px solid var(--line);font-size:14px;color:var(--ink2)}
  .gmpbpl li .gmt{flex:0 0 78px;font-family:var(--font-display);font-weight:600;letter-spacing:.04em;color:var(--muted);white-space:nowrap}
  .gmpbpl .gmpbt{flex:1 1 auto;min-width:0}
  .gmpbpl li.k-goal{color:#fff;font-weight:600}
  .gmpbpl li.k-goal .gmt{color:var(--brand-text)}
  .gmpbpl li.k-penalty .gmpbt{color:var(--muted)}
  /* The Scores tab's cards and the front page: a game under way. */
  .gmst.live,.hmscores .hmtime.live{color:var(--brand-text)}
  /* ---------- The games bar (16 October 2026) ----------
     body/00a-scorebar.html, scripts/06j-scorebar.js. Under the header on every
     page, floating in a box of its own (his picture): the day at its left, then
     each league's games behind a line and the league's name, sideways. */
  /* As wide as the window allows and no wider than its games: the front page's body is a flex column, where a box with no
     width of its own takes its content's (all the day's games side by side: the page was 2,080px wide at 1,280). */
  .sbwrap{box-sizing:border-box;width:100%;min-width:0;max-width:2080px;margin:12px auto 0;padding:0 20px}
  .sbar{position:relative;display:flex;align-items:stretch;min-height:96px;border:1px solid var(--box);border-radius:12px;background:var(--surface);overflow:hidden}

  /* The day: the month small over the date, a press opens a calendar. */
  .sbdate{position:relative;flex:none;display:flex;flex-direction:column;align-items:center;justify-content:center;width:76px;
          border-right:1px solid var(--line);cursor:pointer;font-family:var(--font-display);line-height:1.05}
  .sbdate:hover{background:var(--hover)}
  .sbm{font-weight:600;font-size:15px;letter-spacing:.08em;color:var(--brand-text)}
  .sbd{font-weight:700;font-size:30px;color:#fff}
  .sbdate input{position:absolute;inset:auto 0 0 0;width:100%;height:1px;opacity:0;pointer-events:none;border:0;padding:0}

  /* No scrollbar across the games' last row: the arrows at its ends, a swipe or a trackpad move it. */
  .sbtrack{flex:1 1 auto;min-width:0;display:flex;align-items:stretch;overflow-x:auto;scrollbar-width:none;scroll-behavior:smooth}
  .sbtrack::-webkit-scrollbar{display:none}
  .sbgrp{flex:none;display:flex;align-items:stretch}
  /* Between leagues: a line, and the league's name standing up beside its games. */
  .sbgrp + .sbgrp{border-left:1px solid var(--box)}
  .sblg{flex:none;display:flex;align-items:center;justify-content:center;width:30px;writing-mode:vertical-rl;transform:rotate(180deg);
        font-family:var(--font-display);font-weight:600;font-size:13px;letter-spacing:.12em;color:var(--muted);background:var(--surface2)}
  .sbg{flex:none;display:flex;flex-direction:column;justify-content:center;gap:4px;min-width:140px;padding:8px 14px;color:var(--ink);text-decoration:none;
       border-right:1px solid var(--line)}
  .sbgrp .sbg:last-child{border-right:0}
  .sbg:hover{background:var(--hover)}
  .sbg:focus{outline:none}
  .sbg:focus-visible{box-shadow:inset 0 0 0 2px var(--brand-text)}
  .sbst{font-family:var(--font-display);font-weight:600;font-size:13px;letter-spacing:.06em;color:var(--muted);white-space:nowrap}
  .sbst.fin{color:var(--ink2)}
  .sbst.on{color:var(--good)}
  /* A game under way (box scores, step 2): its period and clock in orange. */
  .sbst.live{color:var(--brand-text)}
  .sbr{display:flex;align-items:center;gap:8px;font-family:var(--font-display)}
  .sbr img,.sbnc{width:24px;height:24px;object-fit:contain;flex:none}
  .sbr b{font-weight:700;font-size:18px;letter-spacing:.03em;min-width:40px}
  .sbs{margin-left:auto;font-weight:700;font-size:20px;min-width:14px;text-align:right}
  .sbr.lost{color:var(--faint)}
  .sbr.won{color:#fff}
  .sbnone{display:flex;align-items:center;padding:0 16px;font-size:15px;color:var(--muted)}

  /* The arrows at its ends, over the games, where there is more to see. */
  .sbstep{position:absolute;top:0;bottom:0;z-index:2;width:32px;border:0;padding:0;background:linear-gradient(90deg,var(--surface) 55%,transparent);
          color:var(--ink);font-size:26px;cursor:pointer}
  #sbL{left:76px}
  #sbR{right:0;background:linear-gradient(270deg,var(--surface) 55%,transparent)}
  .sbstep:hover{color:var(--brand-text)}
  .sbstep[hidden]{display:none}

  @media (max-width:760px){
    .sbwrap{padding:0 12px;margin-top:10px}
    .sbar{min-height:84px}
    .sbdate{width:60px}
    .sbd{font-size:25px}
    #sbL{left:60px}
    .sbg{min-width:120px;padding:7px 11px}
    .sbr b{font-size:16px;min-width:36px}
    .sbs{font-size:18px}
    .sbr img,.sbnc{width:22px;height:22px}
  }
  /* ===================== POWER RANKINGS =====================
     One Monday's list (scripts/11g-rankings.js). The table is the boards' own
     (.lbtable); a club's cell is the standings' (crest and name), and the
     moves are the arrows of the lists the leagues post: up in green, down in
     red, as on the OHL's own graphic William sent (19 October 2026). */
  .ctl .prtable td.tmcl a{display:flex;align-items:center;gap:8px;min-width:0;color:var(--brand-text);text-decoration:none}
  .ctl .prtable td.tmcl a:hover{color:#fff;text-decoration:underline;text-underline-offset:2px}
  .ctl .prtable td.tmcl img{width:22px;height:22px;object-fit:contain;flex:none}
  .ctl .prtable .prmv{width:64px;text-align:center;white-space:nowrap}
  .prup{color:#3ec27a;font-weight:600}
  .prdown{color:#e5534b;font-weight:600}
  .prsame,.prnew{color:var(--muted)}
  .ctl .prtable .prelo{color:#fff;font-weight:600}
  .ctl .prtable td.prwk{white-space:normal;min-width:220px}
  .prg{display:inline-block;margin:2px 6px 2px 0;padding:1px 7px;border-radius:999px;border:1px solid var(--box);font-size:.92em;white-space:nowrap}
  .prg.w{border-color:rgba(62,194,122,.55)}
  .prg.l{border-color:rgba(229,83,75,.5)}
  .prhow{margin:14px 2px 0;max-width:900px;color:var(--muted);font-size:13px;line-height:1.5}
  /* ---------- the phone pass (redesign step 19) ----------
     Last of the stylesheet's parts, so that what it says for a phone wins.

     1. THE TWO TABLES' FILTERS FOLD AWAY. Season Stats and Percentiles
        opened on a phone with a dozen menus one under another: the whole
        first screen, and most of the second, before a single row. Their
        bar (.lbbar.folds) now opens shut: one button that says which
        table this is (league, position, season) and how many filters are
        set, with Copy link beside it; a tap opens the menus under it.
        The other tools have always folded theirs (.rail, the button
        .railtop). scripts/06e-controls.js writes the button's words.
     2. THE TABLE'S PINNED COLUMNS ARE NARROWER, so numbers show beside the
        names: on a 390px screen # and Player took 194px of it.

     The button is not there at all on a wider screen. */
  .lbtop{display:none}

  @media(max-width:700px){
    .ctl .lbbar.folds .lbtop{display:flex;align-items:center;gap:9px;flex:1 1 auto;min-width:0;height:46px;padding:0 13px;
           border:1px solid var(--box);border-radius:10px;background:var(--surface);
           font-size:14.5px;font-weight:600;color:var(--ink);text-align:left;white-space:nowrap}
    .lbtop .lbts{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;font-weight:500;color:var(--muted)}
    /* How many filters are set: the brand's orange, as a set filter's edge is. */
    .lbtop .lbtn{flex:0 0 auto;min-width:20px;padding:1px 6px;border-radius:20px;background:var(--brand);color:var(--on-brand);
           font-size:12px;font-weight:700;text-align:center}
    .lbtop .car{flex:0 0 auto;color:var(--muted);font-size:11px;transition:transform .15s}

    /* Shut: the button and Copy link on one line, and nothing else. */
    .ctl .lbbar.folds:not(.open){flex-wrap:nowrap;align-items:center;gap:8px;padding:0;border:0;background:none}
    .ctl .lbbar.folds:not(.open) > *:not(.lbtop):not(.lbacts){display:none}
    .ctl .lbbar.folds:not(.open) .lbacts{flex:0 0 auto;margin:0}
    .ctl .lbbar.folds:not(.open) .lbacts .copy{height:46px}

    /* Open: the bar is its box again, the button its first line. */
    .ctl .lbbar.folds.open .lbtop{flex:1 1 100%;height:44px;padding:0 0 8px;border:0;border-bottom:1px solid var(--line);
           border-radius:0;background:none}
    .ctl .lbbar.folds.open .lbtop .car{transform:rotate(180deg)}

    /* A table's letters stay the size they were on a phone (William's ask of
       8 October 2026 was of a wide screen): the four sizes of
       styles/21-controls.css, set back, and the loading rows with them. */
    .ctl .lbtable,.ctl .ctscroll table{--grph:28px;--grpf:13px;--tblf:12px;--tblh:10.5px}
    .skrow{height:32px}
    .skrow.skhead{height:61px}

    /* The pinned columns. 36px holds a rank of four digits; the name's left
       edge is that same 36px, or the two overlap when the table is scrolled
       sideways. A long name takes a second line, not a wider column.
       124px since the names have a headshot before them (17 October 2026;
       it was 112): at 112 seven of a page's 25 names took two lines, at 124
       two do, where one did with no headshot. */
    .ctl .lbtable .rk{width:36px;padding-left:4px;padding-right:4px}
    .ctl .lbtable .stick2{left:36px}
    .ctl .lbtable .nm{min-width:0;width:124px;max-width:124px;white-space:normal;overflow-wrap:anywhere;line-height:1.2}
    .ctl .lbtable thead th.stick2{width:124px}

    /* 3. NO FIELD UNDER 16px. An iPhone zooms the whole page the moment a
       field smaller than that takes the keyboard or opens its list, and
       does not zoom back. The tools' own bars were 16px already; these
       were the ones left: the rows menu and page box of a table, its
       filters, the shot map's menus, the game log's season. */
    .ctl .rowspick select,.ctl .pgmid input,.ctl .lbbar select,.ctl .lbbar input[type=text],.ctl .lbbar input[type=date],
    .ctl .smf select,.ctl #logSeason{font-size:16px}

    /* 4. NOTHING TO TAP UNDER 36px TALL: the shot map's "Clear filters",
       the button between Compare's two cards, and every switch (Regular
       Season / Playoffs, the leagues on Lines, Scatter / Radar...). */
    .ctl .smreset{min-height:36px;margin-top:0;font-size:13.5px}
    .ctl #cswap{min-height:36px}
    .ctl .seg button{min-height:36px}
    /* And the cross of a minimum's chip (scripts/06h-minimums.js). */
    .ctl .lbbar .minchips .chip{height:40px}
    .ctl .lbbar .minchips .chip button{height:36px;width:36px}

    /* 5. THE LINE UNDER A TABLE'S NAME IS TWO LINES AT MOST. It says how
       many rows, how sorted and how ranked; on a phone Percentiles' ran to
       four lines above the table. The rest is on a wider screen and in the
       glossary. */
    .pghead .lbmeta{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden}
  }
