/* site.css -- OUR additions on top of the 2014 theme.
 *
 * Loaded last, after dota2_2014.css and fonts.css. Nothing here overrides the original
 * layout; it styles the parts of the site that did not exist in 2014 (the ladder, the
 * hero pages, the GET DOTA funnel, the editor) plus a few small fixes where the original
 * markup assumed something we don't ship.
 *
 * Palette taken from the theme so additions don't look bolted on:
 *   page/panel bg   #1b1d1d   panel border   #272a2a
 *   body text       #969aa1   bright text    #cfcfcf   dim text  #4b4949
 *   link hover      #ffffff   rule           #2b2e2e
 *   strength #c0453d   agility #6bad4b   intelligence #4aa5c9
 */

/* --- fixes to the vendored theme --- */

/* The original showed the nav only inside the Dota client and relied on inline JS to
 * reveal it. We always want it, so undo the hidden default. */
#navBarBGRepeat { display: block !important; }

/* The theme's sub-menus and language list start hidden and were opened by jQuery. We use
 * CSS hover instead (see site.js for the keyboard path), so declare the closed state here
 * rather than inline. */
.menuSubItemList,
#languageList { display: none; }
.navItem:hover .menuSubItemList,
.navItem.open .menuSubItemList,
#languageSelector:hover #languageList,
#languageSelector.open #languageList { display: block; }
.navItem { position: relative; }
.menuSubItemList { top: 100%; left: 0; }
#languageSelector { position: relative; }
#languageList {
    position: absolute; right: 0; top: 100%; min-width: 130px;
    padding: 3px 2px; border: solid #555 1px; background-color: #111;
    text-align: left; z-index: 999999;
}
#languageList a.languageItem {
    display: block; padding: 6px 8px; color: #aaa;
    font: small Arial, Helvetica, sans-serif; text-decoration: none;
}
#languageList a.languageItem:hover { color: #fff; background-color: #555; }

/* The active nav item, which the original marked with a separate image per page. */
#navBar a.navBarItem.navBarItemOn { color: #fff; }

/* --- account controls in the nav --- */

#navAccount {
    float: right; clear: right; padding-top: 4px;
    font: 11px Arial, Helvetica, sans-serif; text-align: right;
}
#navAccount a { color: #908d8b; text-decoration: none; margin-left: 10px; }
#navAccount a:hover { color: #fff; }
.navAvatar { vertical-align: middle; margin-right: 5px; border-radius: 2px; }

/* --- shared bits --- */

.dim { color: #4b4949; }
.ok { color: #6bad4b; }
.warn { color: #c9a24a; }
.readMore {
    font: bold 11px Arial, Helvetica, sans-serif; letter-spacing: 1px;
    text-transform: uppercase; color: #969aa1; text-decoration: none;
}
.readMore:hover { color: #fff; }

.heroSection {
    margin: 26px 0 10px; padding-bottom: 6px; border-bottom: solid #2b2e2e 1px;
    font: 14px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 3px; text-transform: uppercase; color: #cfcfcf;
}

.notice { margin: 0 0 18px; padding: 12px 14px; border-left: solid 3px #555; background: #161818; }
.notice p { margin: 6px 0 0; }
.noticeBad { border-left-color: #c0453d; }

.bigButton, .steamButton, .dangerButton {
    display: inline-block; padding: 9px 20px; border: solid #3a3f3f 1px;
    background: #23282a; color: #cfcfcf !important;
    font: bold 12px Arial, Helvetica, sans-serif; letter-spacing: 2px;
    text-transform: uppercase; text-decoration: none; cursor: pointer;
}
.bigButton:hover, .steamButton:hover { background: #2f3537; color: #fff !important; }
.steamButton img { vertical-align: middle; margin-right: 8px; }
.dangerButton { border-color: #5a2b28; background: #2a1817; }
.dangerButton:hover { background: #3a1e1c; }

.draftBadge {
    display: inline-block; margin-left: 8px; padding: 1px 6px;
    background: #4b3a12; color: #d8b34a;
    font: bold 10px Arial, sans-serif; letter-spacing: 1px;
}

/* The theme reserved #primary{min-height:1900px} and #mainContent{min-height:1051px} for a
 * right rail stacked with a dozen event banners (TI, Diretide, New Bloom, the comic...).
 * Our rail is four items, so those minimums pad every page with ~1200px of empty frame.
 * Keep enough height that the frame's top and bottom images don't collide on a short page.
 */
#primary { min-height: 0; }
#mainContent { min-height: 560px; }

/* --- the callout band --- */

/* The theme's #calloutHeader is a fixed 384px band that always held event key art. With no
 * art it renders as an enormous black void above every page, so collapse it to a thin
 * gradient seam and only take the full height when a page actually supplies an image. */
#calloutHeader {
    height: 34px;
    background: linear-gradient(#050606, #0b0d0d 60%, #010101);
    border-bottom: solid #1a1d1d 1px;
}
#calloutHeader[style*="background-image"] {
    height: 384px;
    border-bottom: 0;
}

/* --- right rail additions --- */

/* GET DOTA and the player count are drawn in CSS rather than using the theme's images.
 * Both of those images have Valve's own copy baked into the pixels -- "GET DOTA 2 / PLAY
 * FOR FREE ON STEAM(R)" and "UNIQUE PLAYERS IN LAST MONTH" -- which is wrong twice over
 * here: the download is ours and not Steam's, and the number underneath is who is online
 * right now, not a monthly unique count. Text in an image also can't be translated, and
 * this site has a language switcher.
 *
 * The styling deliberately copies the theme's vocabulary (dark inset panel, hairline
 * border, Goudy Trajan caps, wide letter-spacing) so it reads as part of the same design
 * rather than a patch on top of it. */
#rightColGetDotaLink {
    background-image: none;
    box-sizing: border-box;
    padding-top: 17px;
    background: linear-gradient(#3c2320, #251715 55%, #1a1211);
    border: solid #4d2f2a 1px;
    box-shadow: 0 0 6px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .06);
    text-align: center;
    text-decoration: none;
}
#rightColGetDotaLink:hover {
    background: linear-gradient(#4a2b27, #2e1c1a 55%, #201514);
    border-color: #6b423b;
}
/* The theme's markup puts a 264x77 transparent spacer gif inside the link to give it size;
 * we set our own box, so hide the spacer and use ::before/::after for the two text lines. */
#rightColGetDotaLink img { display: none; }
#rightColGetDotaLink::before {
    content: attr(data-title);
    display: block;
    font: 21px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 4px; text-transform: uppercase; color: #e6ddd7;
    text-shadow: 0 1px 2px rgba(0, 0, 0, .8);
}
#rightColGetDotaLink::after { content: none; }
#rightColGetDotaLink { display: flex; align-items: center; justify-content: center; padding-top: 0; }
.railDownloadDiscord { margin: 10px 0 10px 14px; }
.getDownloadActions { display: flex; flex-wrap: wrap; align-items: stretch; gap: 12px; margin: 12px 0; }
.getDownloadActions > .bigButton { display: flex; align-items: center; justify-content: center; }
.getDownloadActions > .railDiscord { width: auto; flex: 1 1 230px; }

/* Server reachable / not. Replaces the theme's big player-count plaque: a live number under
 * the download button would advertise the population's smallest honest figure at exactly the
 * moment someone is deciding whether to commit to a 10 GB download. Reachability is the part
 * that actually helps -- it answers "is it me or is it them". */
#serverState {
    width: 264px; margin: 0 0 10px 14px; padding: 7px 0;
    text-align: center;
    font: 10px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
    border-bottom: solid #1f2222 1px;
}
#serverState .dot {
    display: inline-block; width: 7px; height: 7px; margin-right: 7px;
    border-radius: 50%; vertical-align: baseline;
}
#serverState.up { color: #6f7479; }
#serverState.up .dot { background: #6bad4b; box-shadow: 0 0 5px rgba(107, 173, 75, .8); }
#serverState.down { color: #5c5050; }
#serverState.down .dot { background: #7d3b35; }
/* "N in queue", shown only when N is not zero (see _rail.html for why). Sized like the
   download button's title, because when it appears it is the most persuasive thing on the
   page and should not whisper. */
#railQueue {
    display: block; box-sizing: border-box; width: 264px;
    margin: 0 0 10px 14px; padding: 9px 0 10px;
    background: linear-gradient(#20301f, #182418 55%, #131c13);
    border: solid #2f4a2c 1px;
    text-align: center; text-decoration: none;
}
#railQueue:hover { background: linear-gradient(#284029, #1e2e1e 55%, #172317); border-color: #436b3e; }
#railQueue b {
    display: block;
    font: 19px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 3px; color: #9fd182; font-weight: normal;
}
#railQueue span {
    display: block; margin-top: 3px;
    font: 9px Arial, sans-serif; letter-spacing: 2px; text-transform: uppercase; color: #6f8a63;
}

/* The rail's search box. Two controls on one line at the rail's own width; the theme has no
   form vocabulary at all, so this borrows the panel treatment from everything around it. */
/* The search box, on the search page. It was #railSearch, in the right rail on every page of
   the site; it is the same control, moved to the one page it belongs on. */
.srchForm { display: flex; gap: 8px; max-width: 420px; margin: 0 0 18px; }
.srchForm input {
    flex: 1 1 auto; min-width: 0;
    box-sizing: border-box; padding: 8px 10px;
    background: #101212; border: solid #2b2e2e 1px;
    color: #cfcfcf; font: 13px Arial, Helvetica, sans-serif;
}
.srchForm input:focus { outline: none; border-color: #4a4f52; background: #141717; }
.srchForm input::placeholder { color: #5c6165; }
.srchForm button {
    flex: 0 0 auto; padding: 8px 14px;
    background: linear-gradient(#2a2d2d, #1d1f1f); border: solid #33383a 1px;
    color: #b9bcc2; font: 11px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
    cursor: pointer;
}
.srchForm button:hover { color: #fff; border-color: #4a5153; }

/* The way from the ladder to the players who are not on it. */
.ladderFind { margin: 10px 0 0; font-size: 12px; }
.ladderFind a { color: #8b9dc3; text-decoration: none; }
.ladderFind a:hover { color: #fff; }

/* The results table is the ladder's, minus the win-rate column. An exact hit is called out
   above it rather than redirected to: a redirect would make the back button bounce the
   reader out of their own query. */
.srchExact { margin: 0 0 10px; font-size: 13px; }
.srchExact a { color: #cfcfcf; }
.srchTable { margin-top: 4px; }

.rightLinksTitle {
    padding: 4px 0 8px 14px;
    font: 12px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 3px; text-transform: uppercase; color: #8b8f95 !important;
}

/* The links panel is rebuilt rather than reused. The theme made it a fixed 275x229 box with
 * a background image that has the "DOTA LINKS" heading painted into it, and positioned each
 * link ABSOLUTELY at a per-id top offset -- five hardcoded slots for Valve's five links
 * (PlayDota, Facebook, Twitter, YouTube, Steam). Our list is shorter, so those offsets put
 * the rows on top of each other. Normal flow instead. */
#rightColDotaLinks {
    width: 275px; height: auto;
    margin: 14px 0 0 14px; padding: 0 0 8px;
    background-image: none;
    border-top: solid #262a2a 1px;
}
/* One anchor per row, containing icon + label, so the whole row is the hit target and the
 * inline SVG inherits the link's colour through currentColor. */
#rightColDotaLinks .railLink {
    display: flex; align-items: center; gap: 10px;
    padding: 7px 0;
    color: #969aa1; font: 12px Arial, Helvetica, sans-serif; text-decoration: none;
}
#rightColDotaLinks .railLink:hover { color: #fff; }

/* The Discord panel. Same width and vocabulary as the download button above it -- inset
 * panel, hairline border, a title in caps over a small explanatory line -- but in Discord's
 * blurple, because a service is recognised by its colour and its mark before its label is
 * read. It replaced a 12px text row that was the smallest thing in the rail while being one
 * of the two links that matter. */
.railDiscord {
    display: flex; align-items: center; gap: 12px;
    box-sizing: border-box; width: 264px; padding: 12px 14px;
    background: linear-gradient(#3a3e6e, #2b2e57 55%, #23264a);
    border: solid #4a4f86 1px;
    box-shadow: 0 0 6px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .06);
    color: #dfe1f5; text-decoration: none;
}
.railDiscord:hover {
    background: linear-gradient(#464b85, #343869 55%, #2a2e59);
    border-color: #6a70ad; color: #fff;
}
/* Bigger than the 18px row icons and at full strength: this one is the affordance, not a
 * bullet. */
.railDiscord .icon {
    width: 30px; height: 30px; flex: 0 0 30px; opacity: 1;
}
.railDiscordText { display: flex; flex-direction: column; min-width: 0; }
.railDiscordText b {
    font: 13px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 2px; text-transform: uppercase; font-weight: normal;
}
.railDiscordText i {
    margin-top: 3px;
    font: 10px Arial, sans-serif; font-style: normal; letter-spacing: 1px;
    text-transform: uppercase; color: #a3a7d8;
}
.railDiscord:hover .railDiscordText i { color: #c6c9ee; }

/* --- inline SVG icons --- */

.icon {
    width: 18px; height: 18px;
    flex: 0 0 18px;
    /* The 2014 palette is low-contrast; full-strength logos would shout next to it. Lift to
     * full opacity on hover along with the label. */
    opacity: .72;
    transition: opacity .1s;
}
.railLink:hover .icon, a:hover > .icon { opacity: 1; }

.steamButton .icon { width: 20px; height: 20px; flex: 0 0 20px; opacity: 1; }

/* The nav drop-down. The theme's rules make these plain text links in a dark box; add the
 * icon on the same baseline without changing the box. */
.menuSubItemList a {
    display: flex !important;
    align-items: center;
    gap: 9px;
}
.menuSubItemList .icon { width: 14px; height: 14px; flex: 0 0 14px; }

/* LADDER button, drawn instead of using rcb_leaderboards.png -- that image has the word
 * "Leaderboards" baked into it, which a bilingual site cannot use. Same treatment as GET
 * DOTA: the theme's vocabulary, with text we can translate. */
#lbLink {
    display: flex; align-items: center; justify-content: center; gap: 9px;
    box-sizing: border-box;
    width: 262px; height: 48px;
    margin: 0 0 6px 14px;
    background: linear-gradient(#1c2022, #121516);
    background-image: none;
    border: solid #2b3032 1px;
    color: #b9bdc2;
    font: 13px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 3px; text-transform: uppercase; text-decoration: none;
    box-shadow: 0 0 5px 1px rgba(0, 0, 0, .75);
}
#lbLink:hover {
    background: linear-gradient(#232829, #171b1c);
    border-color: #3a4144; color: #fff;
}
#lbLink .icon { opacity: .8; }
#lbLink:hover .icon { opacity: 1; }

/* --- blog / patch notes --- */

.patchList { list-style: none; margin: 8px 0 0; padding: 0; }
.patchList li {
    padding: 7px 0; border-bottom: solid #232626 1px;
    font: 13px Arial, Helvetica, sans-serif;
}
.patchList a { color: #cfcfcf; text-decoration: none; }
.patchList a:hover { color: #fff; }
.patchDate { display: inline-block; width: 110px; color: #4b4949; font-size: 11px; }

.faq dt { margin-top: 12px; color: #cfcfcf; font-weight: bold; }
.faq dd { margin: 4px 0 0 18px; color: #969aa1; }

/* --- hero grid --- */

.heroFilter { margin: 6px 0 14px; }
#heroSearch {
    width: 240px; padding: 6px 8px; border: solid #2b2e2e 1px;
    background: #101212; color: #cfcfcf; font: 13px Arial, sans-serif;
}
.heroGroupTitle {
    margin: 20px 0 8px; padding-bottom: 5px; border-bottom: solid #2b2e2e 1px;
    font: 13px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 3px; text-transform: uppercase;
}
/* Stands in for the attribute icon. 6.81b keeps those inside the client's Flash .gfx
 * files rather than as loose PNGs, so there is nothing to extract -- a square in the
 * attribute's colour carries the same information. currentColor picks it up from the
 * .attr-* class already on the heading. */
.heroGroupTitle::before {
    content: ""; display: inline-block;
    width: 9px; height: 9px; margin-right: 8px;
    background: currentColor; vertical-align: baseline;
}
.attr-strength { color: #c0453d; }
.attr-agility { color: #6bad4b; }
.attr-intelligence { color: #4aa5c9; }

.heroGrid { display: flex; flex-wrap: wrap; gap: 4px; }
.heroCell {
    position: relative; display: block; width: 90px; height: 50px;
    overflow: hidden; text-decoration: none;
}
.heroCell img { display: block; width: 90px; height: 50px; opacity: .78; transition: opacity .1s; }
.heroCell:hover img { opacity: 1; }
.heroCellName {
    position: absolute; left: 0; right: 0; bottom: 0;
    padding: 1px 3px; background: rgba(0,0,0,.72); color: #cfcfcf;
    font: 9px Arial, sans-serif; letter-spacing: .3px;
    white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.heroCell:hover .heroCellName { color: #fff; }
/* Hidden by the search box in site.js. */
.heroCell.filtered, .heroGroup.filtered { display: none; }

/* --- hero page --- */

.heroHeader { overflow: hidden; margin-bottom: 6px; }
.heroPortraitLarge { float: left; margin: 0 16px 10px 0; border: solid #2b2e2e 1px; }
.heroHype { color: #cfcfcf; font-size: 14px; line-height: 20px; }

.statTable { width: 100%; margin-top: 4px; font: 13px Arial, Helvetica, sans-serif; }
.statTable th, .statTable td { padding: 5px 8px; border-bottom: solid #232626 1px; text-align: left; }
.statTable th { width: 22%; color: #8b8f95; font-weight: normal; }
.statTable td { width: 28%; color: #cfcfcf; }
.statTable .gain { color: #4b4949; }

.ability { overflow: hidden; margin: 14px 0; padding: 12px; background: #161818; border-left: solid 3px #2b2e2e; }
.abilityUlt { border-left-color: #a8863c; }
.abilityIcon { float: left; margin: 0 12px 0 0; border: solid #2b2e2e 1px; }
.abilityBody { margin-left: 80px; }
.abilityName { color: #cfcfcf; font: bold 15px Arial, Helvetica, sans-serif; }
.abilityTag {
    margin-left: 8px; padding: 1px 5px; background: #4b3a12; color: #d8b34a;
    font: bold 9px Arial, sans-serif; letter-spacing: 1px; vertical-align: middle;
}
.abilityBehavior { margin-left: 8px; color: #6f7479; font: normal 11px Arial, sans-serif; }
.abilityDesc { margin-top: 5px; color: #969aa1; font-size: 13px; line-height: 19px; }
.abilityMeta, .abilityValues { margin-top: 7px; font: 11px Arial, sans-serif; color: #6f7479; }
.abilityMeta span, .abilityValue { display: inline-block; margin-right: 14px; }
.abilityMeta b, .abilityValue b { color: #8b8f95; font-weight: normal; }
.abilityValues { padding-top: 6px; border-top: solid #212424 1px; }
.abilityMeta .bkb { color: #c9a24a; }
.abilityNotes { margin: 8px 0 0 18px; color: #7d8288; font-size: 12px; line-height: 18px; }
.abilityLore { margin-top: 8px; color: #4b4949; font-size: 12px; font-style: italic; }

/* --- ladder --- */

.ladderTable { width: 100%; table-layout: fixed; margin-top: 6px; font: 13px Arial, Helvetica, sans-serif; }
.ladderTable th {
    padding: 6px 8px; border-bottom: solid #2b2e2e 1px; text-align: left;
    color: #8b8f95; font: 11px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
}
.ladderTable td { padding: 6px 8px; border-bottom: solid #1f2222 1px; color: #cfcfcf; }
.ladderTable tbody tr:hover td { background: #161818; }
.ladderTable .lRank { width: 46px; color: #6f7479; }
.ladderTable .lMMR { width: 70px; color: #fff; font-weight: bold; }
.ladderTable .lRecord { width: 90px; white-space: nowrap; }
.ladderTable .lPlayer { overflow: hidden; }
.ladderTable .lPlayer a { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Highlight the signed-in visitor's own row -- the first thing anyone looks for. */
.ladderTable tr.meRow td { background: #1d2320; color: #fff; }
.ladderFootnote { margin-top: 12px; font-size: 11px; }
.backToSearch { margin: 0 0 18px; font: 12px Arial, sans-serif; }
.backToSearch a { display: inline-block; padding: 8px 12px; border: 1px solid #3a3f3f; background: #23282a; color: #cfcfcf; text-decoration: none; }
.backToSearch a:hover { background: #2f3537; color: #fff; }
/* The player name is the link to a profile; the whole row is not, because a row is
   also something you want to select and read. */
.ladderTable .lPlayer a { color: #cfcfcf; text-decoration: none; border-bottom: solid #33383a 1px; }
.ladderTable .lPlayer a:hover { color: #fff; border-bottom-color: #6f7479; }

/* --- player profile ---------------------------------------------------------------
   The first page in the hybrid style: the 2014 chrome frames it, the panels inside are
   the CLIENT's own Scaleform art out of static/ui (see tools/gfxpack). */

.pfHeader {
    display: flex; align-items: center; gap: 16px;
    margin: 4px 0 0; padding: 18px;
    /* profile_banner is 1024x512 of purple smoke -- the backdrop behind the client's
       own profile header. Anchored bottom so the lit part sits under the text. */
    background: #0d0e10 url(/static/ui/profile_banner.png) center bottom / cover no-repeat;
    border: solid #2b2e2e 1px;
}
/* The visitor's own profile, marked the way their ladder row is. */
.pfHeader.pfMe { border-color: #3c5a44; }
.pfAvatar {
    flex: 0 0 auto; width: 64px; height: 64px;
    background: url(/static/ui/avatar_frame.png) center / 64px 64px no-repeat;
}
/* Scoped through #mainLoop, or the vendored theme's `#mainLoop img { width:auto; height:auto }`
   wins on specificity and renders Steam's 100x100 avatarmedium at its native size, blowing
   the header apart. Same trap as the item icons. */
#mainLoop .pfAvatarImg { display: block; width: 64px; height: 64px; }

/* The home link where Valve's wordmark used to be. The theme sized that slot with the
   image itself, so the text needs its own width to keep the nav bar's rhythm; the gold is
   the project's own accent, not the 2014 red. */
/* Scoped like navBarItemOn just above, because the theme colours nav links through
   `a.navBarItem:link` -- a pseudo-class the plain `.navBarItem.navHome` cannot outweigh. */
#navBar a.navBarItem.navHome { color: #c8a04a; letter-spacing: 2px; }
#navBar a.navBarItem.navHome:hover { color: #e0bd6a; }
.pfIdent { flex: 1 1 auto; min-width: 0; }
.pfName {
    margin: 0; color: #fff; font: 22px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 2px; text-transform: uppercase;
    /* The banner is busy; the shadow is what keeps a long name readable over it. */
    text-shadow: 0 1px 3px #000;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.pfRank { margin-top: 4px; color: #b9bcc2; font-size: 12px; text-shadow: 0 1px 2px #000; }

/* The three profile tabs. Ordinary links, so the current one has to be marked visually --
   the underline sits on the box's own bottom border and continues the header above it. */
.pfTabs { display: flex; gap: 2px; margin-top: 6px; border-bottom: solid #2b2e2e 1px; }
.pfTab {
    padding: 7px 14px; border: solid transparent 1px; border-bottom: none;
    color: #8b8f95; text-decoration: none;
    font: 11px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
}
.pfTab:hover { color: #fff; background: #191c1c; }
/* -1px pulls the tab over the row's border so the current one reads as open at the bottom. */
.pfTabOn {
    margin-bottom: -1px; padding-bottom: 8px;
    background: #141616; border-color: #2b2e2e; color: #fff;
}

/* "See all" under a truncated block, and the count above a full one. */
.pfMore { margin: 8px 0 0; font-size: 12px; }
.pfCount { margin: 6px 0 0; color: #8b8f95; font-size: 12px; }

/* Newer/older rather than numbered pages: this list is chronological, so the only two
   moves a reader wants are "further back" and "back towards now". A disabled end is shown
   rather than removed, so the pager does not change width at the first and last page. */
.pfPager {
    display: flex; align-items: center; gap: 12px; margin-top: 12px;
    font-size: 12px;
}
.pfPage { color: #cfcfcf; text-decoration: none; }
.pfPage:hover { color: #fff; }
.pfPageOff { color: #4a4f52; }
/* Centred between the two moves rather than pushed to one side, so "older" stays at the
   right edge where the arrow points. */
.pfPageAt { margin: 0 auto; color: #6f7479; font-size: 11px; }

/* The full hero table. Same fixed layout and border-box as the match tables -- see the
   note there: a content-box width plus cell padding is 12px wider than it reads. */
.phTable { width: 100%; table-layout: fixed; margin-top: 6px; font: 13px Arial, Helvetica, sans-serif; }
.phTable th, .phTable td { box-sizing: border-box; }
.phTable th {
    padding: 6px; border-bottom: solid #2b2e2e 1px; text-align: left;
    color: #8b8f95; font: 11px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.phTable td { padding: 5px 6px; border-bottom: solid #1f2222 1px; color: #cfcfcf; line-height: 32px; }
.phTable tbody tr:hover td { background: #161818; }
.phTable .phHero { width: 190px; }
.phTable .phHero .pmLink {
    display: flex; align-items: center; gap: 8px; height: 32px;
    color: inherit; text-decoration: none; line-height: normal;
}
.phTable .phHero span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.phTable tbody tr:hover .phHero .pmLink { color: #fff; }
/* Wide enough for the English header "GAMES", which is what sets this column, not the
   two-digit counts under it. */
.phTable .phGames { width: 56px; text-align: right; }
.phTable .phRec { width: 66px; text-align: right; }
.phTable .phWin { width: 74px; text-align: right; color: #969aa1; }
.phTable .phKDA { width: 62px; text-align: right; }
.phTable .phLH { width: 62px; text-align: right; color: #969aa1; }
.phTable .phGPM { width: 60px; text-align: right; color: #969aa1; }
.pfMMR { flex: 0 0 auto; text-align: right; }
.pfMMRValue { color: #fff; font: bold 26px Arial, Helvetica, sans-serif; text-shadow: 0 1px 3px #000; }
.pfMMRLabel {
    color: #b9bcc2; font: 11px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
}

.pfStats { display: flex; margin: 0 0 4px; border: solid #2b2e2e 1px; border-top: 0; }
.pfStat {
    flex: 1 1 0; padding: 10px 12px; text-align: center;
    background: #101212 url(/static/ui/panel_fill.png) center / cover no-repeat;
    border-left: solid #1f2222 1px;
}
.pfStat:first-child { border-left: 0; }
.pfStatValue { color: #fff; font: bold 15px Arial, Helvetica, sans-serif; }
.pfStatLabel {
    margin-top: 3px; color: #8b8f95;
    font: 11px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
}

/* Recent form: a row of pips, newest first. Small enough to sit under the stat strip
   without competing with it. */
.pfForm { display: flex; align-items: center; gap: 5px; margin: 10px 0 0; }
.pfFormLabel {
    margin-right: 4px; color: #8b8f95;
    font: 11px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
}
.pfPip { display: inline-block; width: 12px; height: 12px; border-radius: 2px; }
.pfPipWon { background: #4f7a3a; }
.pfPipLost { background: #7a3a3a; }
.pfFormRuns { margin-left: auto; color: #6f7479; font-size: 11px; }
.pfStatValue.pfUp { color: #8bc46a; }
.pfStatValue.pfDown { color: #c07575; }
/* A "8 / 3" record is two different quantities sharing one slash, and reading which is which
   depended on knowing the convention. The same green and red the match rows already use. */
.recWin { color: #8bc46a; }
.recLoss { color: #c07575; }

/* Per-game averages: value over label. A GRID, not a flex row -- flex wrapped the seven
   items 6+1 and the orphan read as a bug. Four fixed columns wrap deliberately. */
.pfAvg {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(4, 1fr); gap: 1px;
    background: #232626; border: solid #232626 1px;
}
.pfAvg li { padding: 8px 6px; text-align: center; background: #141616; }
.pfAvg li b { display: block; color: #fff; font: bold 14px Arial, Helvetica, sans-serif; }
.pfAvg li span {
    display: block; margin-top: 3px; color: #8b8f95;
    font: 10px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
}

/* Career bests. Each one links to the game it happened in -- a record with no match behind
   it is just a number someone typed. */
.pfRecords {
    list-style: none; margin: 0; padding: 0;
    display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px;
}
.pfRecords li { background: #141616; border: solid #232626 1px; min-width: 0; }
.pfRecords a {
    display: flex; align-items: center; gap: 8px; padding: 6px 10px 6px 6px;
    color: #cfcfcf; text-decoration: none;
}
.pfRecords a:hover { color: #fff; background: #191c1c; }
/* Three narrow columns, so the label goes UNDER the value rather than beside it. Stacked in
   their own flex column with min-width:0 -- an earlier version used a 100% flex-basis plus a
   left margin, and a margin is NOT part of a basis, so every card overflowed by exactly that
   margin. */
.pfRecText { display: flex; flex-direction: column; min-width: 0; }
.pfRecValue { color: #fff; font: bold 14px Arial, Helvetica, sans-serif; white-space: nowrap; }
/* The label WRAPS rather than clips. It names the quantity the record is in ("Больше всего
   добиваний"), and a label truncated mid-word is worth less than the two lines it costs --
   the grid stretches all three cards to match anyway. */
.pfRecLabel { margin-top: 2px; color: #8b8f95; font: 11px/14px Arial, Helvetica, sans-serif; }

.pfSection {
    margin: 22px 0 6px; padding-bottom: 8px;
    color: #cfcfcf; font: 13px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 3px; text-transform: uppercase;
    /* divider is a 1024x63 rule with a soft highlight -- the client's own section break.
       Only the lit strip is wanted, so it is anchored to the bottom edge. */
    background: url(/static/ui/divider.png) center bottom / 100% 8px no-repeat;
}

.pfHeroes { list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px; }
.pfHero {
    display: flex; align-items: center; gap: 8px;
    padding: 6px 10px 6px 6px; background: #141616; border: solid #232626 1px;
}
.pfHero a { display: flex; align-items: center; gap: 8px; color: #cfcfcf; text-decoration: none; }
.pfHero a:hover { color: #fff; }
/* Scoped like .mtItem above: the theme's `#mainLoop img` would otherwise decide the size. */
#mainLoop .pfHeroIcon { display: block; width: 32px; height: 32px; vertical-align: middle; }
.pfHeroName { font: 13px Arial, Helvetica, sans-serif; }
.pfHeroRec { color: #8b8f95; font: 12px Arial, Helvetica, sans-serif; }

/* table-layout: fixed is a GUARANTEE, not a preference. With auto layout the browser is
   free to widen a table past its container to fit the content, and it did -- 646px inside a
   580px frame, with the date column hanging outside the page's right edge. Fixed layout
   makes the declared widths binding and the flexible column absorb the rest. */
.pfMatches { width: 100%; table-layout: fixed; margin-top: 6px; font: 13px Arial, Helvetica, sans-serif; }
/* The 2014 theme's content column is 580px, which nine columns of match data do not fit
   into. Rather than widen the frame (the whole point of the hybrid style is that the frame
   stays 2014), the table drops to the columns worth scanning and refuses to wrap: a header
   broken across three lines is what "У / С / П" turns into otherwise. */
.pfMatches th, .pfMatches .pmKDA, .pfMatches .pmMode,
.pfMatches .pmNum, .pfMatches .pmWhen { white-space: nowrap; }
.pfMatches th {
    padding: 6px 6px; border-bottom: solid #2b2e2e 1px; text-align: left;
    color: #8b8f95; font: 11px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
}
/* Same 32px line box as the match scoreboard: a two-word hero name ("Faceless Void") wraps
   and makes the row taller, and centred cells then push every number half a line down. */
.pfMatches td {
    padding: 5px 6px; border-bottom: solid #1f2222 1px; color: #cfcfcf;
    vertical-align: top; line-height: 32px;
}
.pfMatches tbody tr:hover td { background: #161818; }
/* The link fills its cell so that the clickable area is the cell a reader aimed at, and
   inherits colour so the win/loss tint below still shows through. */
.pfMatches .pmLink { display: block; height: 32px; color: inherit; text-decoration: none; }
.pfMatches .pmHero .pmLink { display: flex; align-items: center; gap: 8px; line-height: normal; }
.pfMatches .pmHero .pmLink span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pfMatches tbody tr:hover .pmHero .pmLink { color: #fff; }
/* EVERY column is measured, because table-layout: fixed splits whatever is left equally
   between the columns that are not -- which starved the hero column and truncated every
   name to "Pud...".
 *
 * Sized to the WORST case in either language rather than to whatever the first rows happen
 * to hold: "Captains Draft" is the longest mode name and "16 / 14 / 12" the widest KDA, and
 * both were clipped by columns that had only ever been measured against a short sample.
 * Together 574 of the 580 available. */
.pfMatches .pmHero { width: 138px; }
/* border-box, or every one of those widths is quietly 12px wider than it reads: the padding
   below is not part of a content-box width, and seven columns of it pushed the table to 654
   inside the 580px frame -- fixed layout binds the COLUMN width, not the table's. */
.pfMatches th, .pfMatches td, .mtTable th, .mtTable td { box-sizing: border-box; }
.pfMatches .pmResult { width: 78px; font-size: 12px; }
.pfMatches .pmMode { width: 100px; color: #969aa1; font-size: 12px; }
.pfMatches .pmKDA { width: 78px; }
.pfMatches .pmLH { width: 38px; text-align: right; color: #969aa1; }
/* 58, not 52: this column is set by the Russian header "ВРЕМЯ", not by the "40:00" under it. */
.pfMatches .pmDur { width: 58px; text-align: right; color: #969aa1; }
.pfMatches .pmWhen { width: 84px; color: #6f7479; font-size: 11px; }
/* A header that outgrows its column must clip, not spill into the next one. */
.pfMatches th, .mtTable th { overflow: hidden; text-overflow: ellipsis; }
/* Win/loss is carried by a left edge rather than by row colour: a fully tinted row
   fights the hero art, and the word is in the cell anyway for a colour-blind reader. */
.pfMatches tr.pmWon td:first-child { box-shadow: inset 3px 0 0 #6bad4b; }
.pfMatches tr.pmLost td:first-child { box-shadow: inset 3px 0 0 #9c4a4a; }
.pfMatches tr.pmWon .pmResult { color: #8bc46a; }
.pfMatches tr.pmLost .pmResult { color: #c07575; }
.pmAbandon { color: #c9a24a; }

/* Set off from the table rather than tucked under it: this is a way OUT of the page, not the
   last row of the match list, and 18px read as the latter. */
.pfBack { margin-top: 30px; font-size: 12px; }

/* --- match scoreboard -------------------------------------------------------------- */

.mtHeader {
    display: flex; align-items: center; justify-content: space-between; gap: 16px;
    margin: 4px 0 0; padding: 14px 18px;
    background: #0d0e10 url(/static/ui/backdrop.png) center / cover no-repeat;
    border: solid #2b2e2e 1px;
}
.mtTitle {
    margin: 0; color: #fff; font: 18px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 2px; text-transform: uppercase;
}
.mtMeta { margin-top: 4px; color: #8b8f95; font-size: 12px; }
.mtOutcome { text-align: right; }
.mtWinner { color: #fff; font: bold 14px Arial, Helvetica, sans-serif; }
.mtDuration { margin-top: 4px; color: #8b8f95; font-size: 12px; }

.mtSide {
    margin: 20px 0 4px; padding-bottom: 8px;
    color: #cfcfcf; font: 13px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 3px; text-transform: uppercase;
    background: url(/static/ui/divider.png) center bottom / 100% 8px no-repeat;
}
.mtSideResult { margin-left: 8px; font-size: 11px; letter-spacing: 1px; }
.mtSideWon .mtSideResult { color: #8bc46a; }
.mtSideLost .mtSideResult { color: #c07575; }

/* Fixed layout for the same reason as .pfMatches: the declared widths must bind, so a long
   nickname cannot push the table out of the 580px content frame. */
.mtTable { width: 100%; table-layout: fixed; font: 13px Arial, Helvetica, sans-serif; }
.mtTable th, .mtTable .mtNum, .mtTable .mtKDA { white-space: nowrap; }
.mtTable th {
    padding: 6px; border-bottom: solid #2b2e2e 1px; text-align: left;
    color: #8b8f95; font: 11px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
}
/* One row per player, and the row is TOP-aligned: a player cell is two lines tall (name,
   then items) while a number is one, and centring the numbers against the taller cell is
   what made them float halfway between the two lines instead of reading as columns.
 *
 * The 32px line box is the shared baseline. The icon, the name and every number all live in
 * one, so the first visual line of a row is a straight rule across the table -- which is the
 * whole difference between a scoreboard and a list of facts. */
.mtTable td { padding: 5px 6px; color: #cfcfcf; vertical-align: top; line-height: 32px; }
/* Measured for the same reason as .pfMatches: under fixed layout an unmeasured column gets
   an equal share of the leftovers, not the space its content needs. The player column is
   left unmeasured ON PURPOSE -- it is the one that should absorb the remainder, and it needs
   at least 276px for the six-item strip -- six 43px icons plus their gaps. So these five are
   sized to the WIDER of their header and their worst-case value, in the wider of the two
   languages: "LVL" beats "УР", a six-figure net worth beats a five, and "16 / 14 / 12" is a
   good deal wider than the "10 / 2 / 7" a first row happens to show. Together 246 of the 580,
   which leaves the player column 322 of usable width. */
.mtTable .mtLevel { width: 36px; }
.mtTable .mtKDA { width: 78px; color: #fff; }
.mtTable .mtLH { width: 34px; }
.mtTable .mtGPM { width: 42px; }
.mtTable .mtNW { width: 56px; }
.mtTable .mtMMR { width: 70px; text-align: right; white-space: nowrap; }
.mtTable .mtDelta { display: block; font-size: 11px; line-height: 18px; }
.mtTable .mtMMR .recWin { color: #6bad4b; }
.mtTable .mtMMR .recLoss { color: #c0453d; }
.mtTable .mtNum, .mtTable .mtLevel, .mtTable .mtLH, .mtTable .mtGPM, .mtTable .mtNW {
    text-align: right; color: #969aa1;
}
.mtTable tr.mtRow td { border-bottom: solid #1f2222 1px; }
.mtTable tr.mtRow:hover td { background: #161818; }

/* The player cell: icon and name on one line, the build under it. */

.mtLine { display: flex; align-items: center; gap: 8px; height: 32px; }
#mainLoop .mtHeroIcon { display: block; width: 32px; height: 32px; }
.mtHeroLink { display: block; flex: 0 0 auto; line-height: 0; }
.mtName {
    color: #cfcfcf; text-decoration: none; line-height: normal;
    overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
a.mtName:hover { color: #fff; }
/* NOT indented under the nickname, which is what it was at first: a build belongs to the
   player, not to their name, so starting it under the portrait costs nothing and buys back
   40px of the width the six-icon strip needs. */
.mtItems { margin: 2px 0; line-height: 0; }
/* 43x22 keeps the client's 124x64 aspect: an item icon is wide, not square, and squashing
   it to a box is the single most obvious way to look like a fan site.
 *
 * Scoped through #mainLoop ON PURPOSE. The vendored 2014 theme carries
 *
 *     #mainLoop img { height: auto; max-width: 576px; width: auto; }
 *
 * which is an id selector and therefore beats a bare `.mtItem` -- it rendered every item at
 * its native 124x64. The hero icons happen to survive it only because 32x32 art at `auto`
 * IS 32x32, so this trap is invisible until an asset's natural size is not its display
 * size. Anything sized in this file that is an <img> under #mainLoop needs the same scope. */
#mainLoop .mtItem {
    display: inline-block; width: 43px; height: 22px; margin-right: 3px;
    vertical-align: middle;
}
#mainLoop .mtItemEmpty { background: #131515; border: solid #1f2222 1px; box-sizing: border-box; }

/* --- GET DOTA --- */

.getSteps { list-style: none; margin: 8px 0 0; padding: 0; counter-reset: step; }
.getStep {
    margin: 0 0 4px; padding: 16px 18px;
    background: #141616; border-left: solid 3px #232626; opacity: .55;
}
.getStep.active { opacity: 1; border-left-color: #4aa5c9; }
.getStep.done { opacity: 1; border-left-color: #6bad4b; }
.getStep h3 {
    margin: 0 0 8px; color: #cfcfcf;
    font: 13px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 3px; text-transform: uppercase;
}
.getStep p { margin: 6px 0; color: #969aa1; font-size: 13px; line-height: 19px; }
.signedInAs { color: #cfcfcf !important; }
.signedInAs img { vertical-align: middle; }
pre.cfg, code {
    background: #0d0f0f; border: solid #212424 1px; color: #9fb4a8;
    font: 12px/18px Consolas, "Courier New", monospace;
}
pre.cfg { margin: 10px 0; padding: 12px; overflow-x: auto; }
code { padding: 1px 4px; }

/* --- admin --- */

.adminTable { width: 100%; font: 13px Arial, Helvetica, sans-serif; }
.adminTable th { padding: 6px 8px; border-bottom: solid #2b2e2e 1px; text-align: left; color: #8b8f95; }
.adminTable td { padding: 6px 8px; border-bottom: solid #1f2222 1px; color: #cfcfcf; }
.adminTable a { color: #cfcfcf; }

.editForm label { display: block; margin: 12px 0; color: #8b8f95; font: 12px Arial, sans-serif; }
.editForm input[type=text], .editForm textarea, .editForm select,
.editForm input[type=datetime-local] {
    display: block; width: 100%; margin-top: 5px; padding: 7px 8px;
    border: solid #2b2e2e 1px; background: #101212; color: #cfcfcf;
    font: 13px/18px Arial, Helvetica, sans-serif; box-sizing: border-box;
}
.editForm textarea { font-family: Consolas, "Courier New", monospace; resize: vertical; }
/* The editor is the one page that wants more than the theme's 580px column. */
.editCols { display: flex; gap: 16px; }
.editCol { flex: 1 1 0; min-width: 0; }
.editCol h3 { margin: 14px 0 0; color: #cfcfcf; font: bold 13px Arial, sans-serif; }
.editActions { margin-top: 18px; }
.editActions .bigButton { margin-right: 8px; }
.deleteForm { margin-top: 28px; padding-top: 16px; border-top: solid #232626 1px; }
body.adminWide #mainLoop { width: 880px; }

/* Present in the markup, not painted. Used for the blog feed's h1: the 2014 design has
   nowhere to show a page heading -- the band above the content is key art and the site name
   lives inside the nav bar's logo image -- but a page still needs exactly one, for screen
   readers and for the outline a crawler builds. Clipped rather than display:none, which
   would take it out of the accessibility tree as well. */
.srOnly {
    position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0;
    overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
    border: 0;
}

/* --- the /play room ---------------------------------------------------------------- */

/* The way in, above the download button and in the same vocabulary. Green rather than the
   download's red: they are different actions and the eye should not have to read to tell
   them apart. */
#railPlay {
    /* Centred by the box, not by a padding guess. It carried one line of type in a slot the
       theme sized for two, and a top padding chosen by eye left the label sitting on the
       bottom edge -- there was no padding under it to balance against. Flex centres it in
       both axes and keeps doing so if the label ever wraps in another language. */
    display: flex; align-items: center; justify-content: center;
    box-sizing: border-box; width: 264px; height: 60px;
    margin: 0 0 10px 14px;
    background: linear-gradient(#20301f, #182418 55%, #131c13);
    border: solid #3a5c35 1px;
    box-shadow: 0 0 6px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .06);
    text-align: center; text-decoration: none;
}
#railPlay:hover { background: linear-gradient(#284029, #1e2e1e 55%, #172317); border-color: #55834e; }
#railPlay img { display: none; } /* the theme's spacer gif: we set our own box */

/* The same button, as the real queue control on /play. It is a <button> in a <form> rather
   than a link, so it shares the box but not the ::before trick -- the label has to be
   swappable by the script, which means it is element text. */
#railPlayForm { margin: 0 0 10px 14px; width: 264px; }
.railPlayBtn {
    display: block; box-sizing: border-box; width: 100%; height: 60px; padding: 0;
    background: linear-gradient(#20301f, #182418 55%, #131c13);
    border: solid #3a5c35 1px;
    box-shadow: 0 0 6px rgba(0, 0, 0, .6), inset 0 1px 0 rgba(255, 255, 255, .06);
    font: 19px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 4px; text-transform: uppercase; color: #cfe6c2;
    text-shadow: 0 1px 2px rgba(0, 0, 0, .8);
    cursor: pointer;
}
.railPlayBtn:hover { background: linear-gradient(#284029, #1e2e1e 55%, #172317); border-color: #55834e; }
/* Searching: the same box in the leave colour, so "this is armed" is readable without the
   words. Red is the theme's own danger colour, used here for the same reason. */
.railPlayBtn.playLeave {
    background: linear-gradient(#301f1f, #241818 55%, #1c1313);
    border-color: #5c3535; color: #e6c2c2; font-size: 15px; letter-spacing: 3px;
}
.railPlayBtn.playLeave:hover { background: linear-gradient(#402929, #2e1e1e 55%, #231717); border-color: #834e4e; }
#railPlay::before {
    content: attr(data-title);
    display: block;
    font: 19px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 4px; text-transform: uppercase; color: #cfe6c2;
    text-shadow: 0 1px 2px rgba(0, 0, 0, .8);
}

/* playHidden rather than [hidden] or an inline style: the script toggles a class, which
   keeps every "is this visible" decision in one stylesheet instead of scattered in JS. */
.playHidden { display: none !important; }

.playPanel { margin: 0 0 16px; }
.playPanel form { display: inline-block; margin: 0 8px 0 0; }
#playQueueBtn.playLeave { border-color: #5a2b28; background: #2a1817; }
#playQueueBtn.playLeave:hover { background: #3a1e1c; }

/* How long YOU have been searching, directly under the button that stops it. Tabular figures
   so the seconds tick without the text jittering sideways. */
.playSearching {
    padding: 5px 0 0; text-align: center;
    color: #c9a24a; font: 13px Arial, Helvetica, sans-serif; letter-spacing: 2px;
}
.playSearching b { font-variant-numeric: tabular-nums; font-weight: normal; }

/* --- the ready-check --------------------------------------------------------------------
   Centred in the viewport on EVERY page, because a match forms whether or not the reader is
   looking at /play and the accept window is measured in seconds. It is the only thing on this
   site that interrupts, and it is placed where the eye already is rather than along the top
   edge, which is where browsers have taught everyone that cookie banners live. */
.matchCard {
    /* Above EVERYTHING, and the number is not decorative. At 9000 the panel painted over the
       2014 nav (z-index 10001) but the nav still won the hit test, so a click aimed at
       ACCEPT landed on the nav link underneath it and navigated away -- pressing "accept"
       took you to the ladder and lost you the match. The theme's own ceiling is 999999
       (the language menu), so this sits one above it. */
    position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
    z-index: 1000000;
    width: 420px; max-width: calc(100vw - 32px); box-sizing: border-box;
    padding: 20px 22px;
    background: linear-gradient(#1d2a33, #121a1f);
    border: solid #2f4a5a 1px;
    box-shadow: 0 10px 44px rgba(0, 0, 0, .85), inset 0 1px 0 rgba(255, 255, 255, .05);
    animation: matchCardIn .22s ease-out;
}
@keyframes matchCardIn {
    from { opacity: 0; transform: translate(-50%, -50%) scale(.96); }
    to { opacity: 1; transform: translate(-50%, -50%) scale(1); }
}
/* Someone who asked for less motion gets the panel without the pop -- it is an alert, so it
   must still be impossible to miss. */
@media (prefers-reduced-motion: reduce) { .matchCard { animation: none; } }

.matchCardCount { margin: 6px 0 0; color: #b9bcc2; font-size: 13px; }
.matchCardCount b { color: #cfe6c2; font-variant-numeric: tabular-nums; }
/* The accept window, counting down. Tabular figures so the seconds tick without shifting
   the text beside them, and amber because it is the one number here with a deadline. */
.matchCardClock {
    margin-left: 10px; padding: 1px 7px;
    background: #201c12; border: solid #4a3c1c 1px; color: #d8b34a;
    font-variant-numeric: tabular-nums;
}
.matchCardNote { margin: 10px 0 0; color: #9fd182; font-size: 13px; }
.matchCard .playFound { margin: 0; padding-right: 26px; } /* room for the fold button */
.matchCard .playConnect { margin: 10px 0 0; }

/* Collapse. Deliberately small and quiet: it must be findable by someone who wants the page
   back, and must not compete with ACCEPT for a hurried click. */
.matchFold {
    position: absolute; top: 8px; right: 8px;
    width: 24px; height: 24px; padding: 0;
    background: transparent; border: solid transparent 1px; border-radius: 2px;
    color: #6f8794; font: 18px/1 Arial, sans-serif; cursor: pointer;
}
.matchFold:hover { color: #cfe6c2; border-color: #2f4a5a; background: #16222a; }

/* Folded: a corner tab that still says a match is waiting, one click from the buttons. It
   goes to the BOTTOM right -- the top is the nav, and a reader who just moved this out of
   their way should not find it sitting on the next thing they wanted to click. */
.matchCard.matchFolded {
    top: auto; bottom: 16px; left: auto; right: 16px; transform: none;
    width: auto; max-width: none; padding: 0;
    background: none; border: 0; box-shadow: none; animation: none;
}
.matchCard.matchFolded .matchCardBody, .matchCard.matchFolded .matchFold { display: none; }
.matchPeek {
    display: flex; align-items: center; gap: 10px;
    padding: 10px 14px; cursor: pointer;
    background: linear-gradient(#1d2a33, #121a1f);
    border: solid #2f4a5a 1px;
    box-shadow: 0 6px 20px rgba(0, 0, 0, .8);
}
.matchPeek:hover { border-color: #4a7186; }
.matchPeekLabel {
    font: 12px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 2px; text-transform: uppercase; color: #8fc7e6;
}
.matchPeekCount { color: #cfe6c2; font: 12px Arial, sans-serif; font-variant-numeric: tabular-nums; }

.playFound {
    margin: 0 0 6px;
    font: 16px goudy_trajan_boldbold, "times new roman", serif;
    letter-spacing: 3px; text-transform: uppercase; color: #8fc7e6;
}
.playReadyBtns { display: flex; gap: 8px; margin-top: 10px; }
.playReadyBtns form { margin: 0; }
.playConnect { margin: 8px 0 0; font-size: 12px; color: #b9bcc2; }
.playConnect code {
    /* Its own line, sized to its contents. Inline after the sentence, its max-width was
       measured from wherever the sentence happened to end, so on a narrow screen the address
       started near the right edge and ran off it -- and a truncated server address is worth
       exactly nothing, it being the string this whole flow exists to deliver. */
    display: block; width: fit-content; max-width: 100%; word-break: break-all;
    margin-top: 4px; padding: 4px 8px;
    background: #0d1013; border: solid #2b2e2e 1px; color: #cfe6c2;
    font: 12px Consolas, monospace;
    /* Selectable in one gesture: this is meant to be copied into a console. */
    user-select: all;
}

.playChat { list-style: none; margin: 6px 0 0; padding: 0; }

/* The chat IS the page now -- the queue button moved to the rail and the roster is gone -- so
   it takes the height rather than a fixed slice of it.

   Sized against the VIEWPORT, not against its own content: growing with the messages would
   walk the send box down the page every time somebody talks, and that is the one element
   that has to stay where the reader last put their cursor. The floor keeps it usable on a
   short laptop screen; the ceiling stops it running past the rail on a tall monitor and
   leaving the send box below the fold. */
.playChat {
    height: calc(100vh - 300px); min-height: 340px; max-height: 760px;
    overflow-y: auto; overscroll-behavior: contain;
    padding: 6px 10px; background: #141616; border: solid #232626 1px;
    /* A visible scrollbar. The default is invisible against this palette until you are
       already dragging it, which makes a full room look like a truncated one -- there is no
       other cue that there is anything above the first line. */
    scrollbar-width: thin; scrollbar-color: #3d4446 #141616;
}
.playChat::-webkit-scrollbar { width: 10px; }
.playChat::-webkit-scrollbar-track { background: #101212; }
.playChat::-webkit-scrollbar-thumb { background: #3d4446; border: solid #101212 2px; }
.playChat::-webkit-scrollbar-thumb:hover { background: #555f61; }
/* One message: the avatar in its own column, then the name and the time on a line, then the
   text under both. Reading down the left edge gives you who is talking; reading down the
   right edge gives you when -- which is what makes a stack of lines a conversation instead of
   a log file. */
.playChat li {
    display: flex; gap: 9px; align-items: flex-start;
    padding: 5px 0; font: 13px Arial, Helvetica, sans-serif; color: #cfcfcf;
}
.playAvatar {
    flex: 0 0 auto; width: 32px; height: 32px; border-radius: 2px;
    background: #1b1e1e; border: solid #2b2e2e 1px; box-sizing: border-box;
}
/* A player with no Steam avatar still gets the column, so every name starts at the same x.
   A ragged left edge is more distracting than an empty square. */
.playAvatarNone { display: block; }
.playMsg { flex: 1 1 auto; min-width: 0; }
.playMsgHead { display: flex; align-items: baseline; gap: 8px; }
.playAt {
    margin-left: auto; flex: 0 0 auto;
    color: #5f6469; font-size: 11px; font-variant-numeric: tabular-nums;
}
/* The quote above a reply. An indented, dimmer line with an elbow drawn in CSS -- it has to
   read as "this came before" at a glance, without competing with the message under it. */
.playQuote {
    display: flex; align-items: baseline; gap: 6px;
    margin: 0 0 2px 10px; padding-left: 10px;
    border-left: solid #3a4147 2px;
    color: #6f7479; font-size: 12px; text-decoration: none;
    /* One line, whatever was quoted: a quote that wraps is a second message on the screen. */
    white-space: nowrap; overflow: hidden;
}
.playQuote:hover { color: #9aa2a8; border-left-color: #4f5a62; }
.playQuote b { flex: 0 0 auto; color: #7d8ba8; font-weight: bold; }
.playQuote span { overflow: hidden; text-overflow: ellipsis; }

/* Where a quote lands. Bright enough to find in a full box, brief enough not to linger. */
@keyframes playFlash {
    from { background: #2b3a2b; }
    to { background: transparent; }
}
.playFlash { animation: playFlash 1.4s ease-out; }
@media (prefers-reduced-motion: reduce) {
    .playFlash { animation: none; outline: solid #4a7a45 1px; }
}

/* Per-message controls: reply for everyone who can write, mute and delete for admins.
   Hidden until the row is hovered or something in it has focus -- a chat with a row of
   buttons against every line is a toolbar with some text in it. focus-within is what keeps
   them reachable from the keyboard, where there is no hover to have. */
.playActForm { display: inline; margin: 0; }
.playAct {
    display: none; padding: 0 4px; margin: 0;
    background: none; border: 0; color: #5f6469;
    font: 12px Arial, sans-serif; line-height: 1; text-decoration: none; cursor: pointer;
}
.playChat li:hover .playAct, .playChat li:focus-within .playAct { display: inline-block; }
.playAct:hover { color: #cfcfcf; }

.playWho { color: #8b9dc3; text-decoration: none; font-weight: bold; }
.playWho:hover { color: #fff; }
/* An admin's name is coloured, not badged: the only thing being said is "this one can post
   links", and a badge would claim more authority than that. */
.playWhoAdmin { color: #c9a24a; }
.playText { display: block; white-space: pre-wrap; word-break: break-word; }

.playSay { margin-top: 8px; }
.playSayRow { display: flex; gap: 6px; }

/* "Replying to X: ..." above the compose box. It sits attached to the box rather than
   floating near the quoted message, because the question it answers is "what will this
   message I am about to send be attached to". */
.playReplyBar {
    display: flex; align-items: baseline; gap: 8px;
    padding: 5px 9px; margin-bottom: -1px;
    background: #171a1a; border: solid #2b2e2e 1px;
    font-size: 12px; color: #6f7479;
}
.playReplyTo { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.playReplyBar b { color: #7d8ba8; }
.playReplyBar i { font-style: normal; color: #5f6469; }
.playReplyCancel { flex: 0 0 auto; color: #5f6469; text-decoration: none; padding: 0 2px; }
.playReplyCancel:hover { color: #cfcfcf; }

.playSay input[type="text"] {
    flex: 1 1 auto; min-width: 0; box-sizing: border-box; padding: 7px 9px;
    background: #101212; border: solid #2b2e2e 1px; color: #cfcfcf;
    font: 13px Arial, Helvetica, sans-serif;
}
.playSay input:focus { outline: none; border-color: #4a4f52; background: #141717; }
.playSayRow button {
    flex: 0 0 auto; padding: 7px 14px;
    background: linear-gradient(#2a2d2d, #1d1f1f); border: solid #33383a 1px;
    color: #b9bcc2; font: 11px Arial, sans-serif; letter-spacing: 1px;
    text-transform: uppercase; cursor: pointer;
}
.playSayRow button:hover { color: #fff; border-color: #4a5153; }

/* "You are muted." Amber, like the other warnings on this site -- it is a state to know
   about, not an error to fix. */
.playMuted {
    margin: 8px 0 0; padding: 7px 10px;
    background: #201c12; border-left: solid 3px #c9a24a;
    color: #c9a24a; font-size: 12px;
}
/* The mute button, when it is offering to UNmute: lit, so an admin can see at a glance who
   in the room is already silenced. */
.playActOn { color: #c9a24a; }

/* The mute menu: how long, chosen at the moment of muting. A <details>, so it opens and
   closes with no script and no state anywhere. */
.playMuteMenu { display: inline-block; position: relative; }
.playMuteMenu > summary { list-style: none; cursor: pointer; }
.playMuteMenu > summary::-webkit-details-marker { display: none; }
/* The summary IS the icon, so it obeys the same hide-until-hover rule as the other controls
   -- except while the menu is open, or it would vanish from under the reader's cursor. */
.playMuteMenu[open] > summary { display: inline-block; color: #c9a24a; }
.playMuteOpts {
    position: absolute; right: 0; top: 100%; z-index: 50;
    display: flex; align-items: center; gap: 4px; white-space: nowrap;
    padding: 6px 8px; background: #16181a; border: solid #33383a 1px;
    box-shadow: 0 6px 18px rgba(0, 0, 0, .8);
}
.playMuteFor { color: #6f7479; font-size: 11px; margin-right: 2px; }
.playMuteOpts button {
    padding: 3px 7px; cursor: pointer;
    background: #23282a; border: solid #3a3f3f 1px; color: #cfcfcf;
    font: 11px Arial, sans-serif;
}
.playMuteOpts button:hover { background: #2f3537; color: #fff; border-color: #4a5153; }

/* A self-hosted clip in a post body (the @video shortcode). Sized to the content column and
   never wider than it, like every image here. */
.postVideo { margin: 18px 0; }
.postVideo video {
    display: block; width: 100%; max-width: 100%; height: auto;
    background: #000; border: solid #2b2e2e 1px;
}

/* --- /matches: every rated game on the server ------------------------------------------ */

.mlLede { margin: 0 0 14px; font-size: 12px; }

/* The filter. One row, and it wraps rather than overflowing the 580px column. */
.mlFilter {
    display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
    margin: 0 0 14px; padding: 10px 12px;
    background: #161818; border: solid #232626 1px;
}
.mlFilter label { color: #6f7479; font-size: 12px; }
.mlFilter select {
    flex: 0 1 auto; max-width: 220px; padding: 5px 7px;
    background: #101212; border: solid #2b2e2e 1px; color: #cfcfcf;
    font: 12px Arial, Helvetica, sans-serif;
}
.mlFilter select:focus { outline: none; border-color: #4a4f52; }
.mlFilter button {
    padding: 5px 12px; cursor: pointer;
    background: linear-gradient(#2a2d2d, #1d1f1f); border: solid #33383a 1px;
    color: #b9bcc2; font: 11px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
}
.mlFilter button:hover { color: #fff; border-color: #4a5153; }
.mlClear { color: #6f7479; font-size: 12px; text-decoration: none; }
.mlClear:hover { color: #cfcfcf; }

.mlCount { margin: 0 0 6px; font-size: 12px; }

/* table-layout: fixed with box-sizing on the cells, for the reason the profile's table
   needed it -- content-box widths silently add the padding on top and the table ends up
   wider than the 580px column it has to live in. */
.mlTable { width: 100%; table-layout: fixed; border-collapse: collapse; }
.mlTable th, .mlTable td { box-sizing: border-box; padding: 5px 4px; }
.mlTable th {
    border-bottom: solid #2b2e2e 1px;
    color: #6f7479; font: 10px Arial, sans-serif; letter-spacing: 1px; text-transform: uppercase;
    text-align: left;
}
.mlTable td { border-bottom: solid #1f2222 1px; font: 12px Arial, Helvetica, sans-serif; }
.mlTable tr:hover td { background: #191c1c; }
.mlWhen { width: 104px; }
.mlLen  { width: 56px; text-align: right; }
.mlWhen a, .mlLen a { color: #969aa1; text-decoration: none; display: block; }
.mlTable tr:hover .mlWhen a, .mlTable tr:hover .mlLen a { color: #fff; }

/* The winning side. A left rule rather than a background: five hero icons already carry a
   lot of colour, and a green wash behind them turns the row into a swatch. */
.mlSide { border-left: solid transparent 2px; }
.mlWon { border-left-color: #6bad4b; }

.mlPicks { display: flex; flex-wrap: wrap; gap: 2px; }
.mlPick { display: block; line-height: 0; opacity: .85; }
.mlPick:hover { opacity: 1; }
.mlPick img { display: block; border: solid #2b2e2e 1px; }
.mlPick:hover img { border-color: #6f7479; }
/* The hero being filtered on, so a row shows WHY it matched instead of making the reader
   hunt for it among ten portraits. */
.mlPickOn img { border-color: #c9a24a; }
.mlPickNone { display: block; width: 32px; height: 18px; background: #1b1e1e; border: solid #2b2e2e 1px; }
