﻿/* @import rules must be first in a stylesheet (only @charset can precede
   them) - see tokens-v26.css's own comment for why this exists: a genuine
   single source for tokens this file used to duplicate with baseV26.css. */
@import url("/resources/StyleSheets/tokens-v26.css");

.font15 {
    font-size: 1.5em !important;
}

.font22 {
    font-size: 2.2em !important;
}

.displayOn {
    display: block;
}

.displayOff {
    display: none !important;
}

.displayShow {
    visibility: visible;
}

.displayHidden {
    visibility: hidden;
}

th, td {
    word-break: keep-all;
}

ul > li > a:hover, ul > li > a:visited,
ul > li > a:active, ul > li > a:link  {
    text-decoration: none;
}

.scroll1::-webkit-scrollbar {
  width: 3px;
}
 
.scroll1::-webkit-scrollbar-track {
  background: #ddd;
}
 
.scroll1::-webkit-scrollbar-thumb {
  background: #666; 
}

/* ==========================================================================
    MAIN CONTETN
   ========================================================================== */

.leftPane, .rightPane
{ 
    float: left;
    top: 82px;
    left: 0;
    right: 0;
    bottom: 0;
    position: fixed;
}
.leftPane{
    width: 220px;
    background: #2166ac;
    min-height: 500px;
    color: #fff;
    text-align: left;
    transition: all .2s ease-in-out;
}
.rightPane{ 
    width: 100%;
    background: #fff;
    overflow-y: auto;
}
.rightPane-inner{ 
    margin-left: 220px;
    word-break: break-all;
    padding: 0px 0px 20px 0px;
    transition: all .2s ease-in-out;
}

.contentBlock {
    text-align: center; 
    border: 1px solid #808080; 
    border-radius: 5px;
    display: inline-block; 
    width: 99%; 
    margin: auto; 
    margin-top: 10px; 
    padding-top: 10px; 
    padding-bottom: 10px;
}

#toFromBox {
    display: inline-flex; 
}

/* in left pane*/

#tabNav ul {
    list-style-type: none;
}

#tabs li {
    display: block;
    width: 50px;
    height: 50px;
    background-color: #01467D;
    opacity: .6;
    border-radius: 0 7px 7px 0;
    margin-top: 15px;
    -webkit-transition: width 1s ease;
	-moz-transition: width 1s ease;
	-o-transition: width 2s ease;
	-ms-transition: width 1s ease;
	transition: width 1s ease;
}

#tabs li:first-child {
    margin-top: 60px;
}

#tabs li:hover {
    box-shadow: 3px 4px 4px rgba(34, 25, 25, 0.3);
}

#tabs li > a > i {
    font-size: 2em;
    margin-top: 8px;
    margin-left: 8px;
    color: #fff;
}

#tabs li:nth-child(2) > a > i {
    margin-left: 10px;
}
/*#tabs li:nth-child(4) > a > i {
    margin-left: 15px;
}*/
#tabs li:nth-child(4) > a > i {
    margin-left: 11px;
}

#tabs li > a > i:hover {
    color: #68D2F9;
}

#tabs li#tab2 {
    display: none;
}

#btnCollapse > i {
    transition: transform 600ms ease-in-out;
    margin-left: 11px !important;
}
#btnCollapse.shrink > i {
    -moz-transform: rotate(180deg);
    -ms-transform: rotate(180deg);
    -webkit-transform: rotate(180deg);
    transform: rotate(180deg);
}

#tabContent {
    top: 82px;
    bottom: 0;
    position: fixed;
    overflow-y: auto;
    width: 220px;
}

#tabContent > .tab-pane {
    display: none;
    visibility: hidden;
    overflow-x: hidden;
}

#tabContent > .active {
    display: block;
    visibility: visible;
}

#tabPane-1 {
    margin: 16px;
}

.filter-cell {
    margin-bottom: 8px;
}

.filter-caption {
    font-size: 0.9em;
    font-weight: bold;
    color: #FFF;
    margin-bottom: 5px;
    margin-top: 15px;
}

.filter-caption > i {
    color: rgba(0, 164, 83, 0.6);
    margin-left: 15px;
    border-radius: 50%;
}

#tabContent ul li a {
    font-size: 1.05em;
    font-weight: 600;
    padding-top: 2px;
    transition: font-size 0.2s ease;
    color: #DDD;
    margin-bottom: 8px;
    white-space: nowrap;
    overflow: hidden;
    line-height: 36px;
}

#tabContent ul li a:hover {
    color: #FFF;
}

.player-filter {
    display: none;
}

.site0-menu-item, .player-menu-item {
    display: none;
}

/* Hidden until renderSiteView() knows there's at least one site — same
   flash-avoidance reasoning as .page-explainer just above it. */
.no-site-hide {
    display: none;
}

/* start of right-pane content */
#ribbon {
    height: 42px;
    min-height: 40px;
    padding: 0 13px;
    position: relative;
    text-align: left;
}

.ribbon-button-alignment {
    padding-top: 10px;
    display: inline-block;
    font-weight: bold;
}

.dbTable {
    text-align: left;
}

.tablesorter-header {
    white-space: nowrap !important;
}

/* No tablesorter theme is loaded, so sortable columns otherwise look
   identical to non-sortable ones — this adds a visible sort-arrow cue and
   pointer cursor, using the plugin's own (currently unstyled) elements. */
/* !important + explicit width:auto — inline-flex should already shrink to
   content by default, but the glyph was empirically ending up at the far
   right edge of the (wide) column instead of hugging the text, meaning
   something is stretching this div to the full column width. Forcing
   both here guarantees it can't win regardless of what that turns out to be. */
.tablesorter-header-inner {
    display: inline-flex !important;
    width: auto !important;
    max-width: fit-content !important;
    align-items: center;
    gap: 6px;
}

.tablesorter-header:not(.sorter-false) {
    cursor: pointer;
}

/* A tablesorter *theme* stylesheet turns out to be loaded after all
   (contrary to what I'd assumed) — it sets a background-image sort arrow
   positioned via background-position:center right directly on the <th>
   itself, which is what was actually rendering at the far right of wide
   columns, entirely independent of the ::after arrow above. Confirmed via
   DevTools (disabling this exact rule removed the far-right glyph). */
.tablesorter-default .header,
.tablesorter-default .tablesorter-header {
    background-image: none !important;
}

/* Same theme stylesheet also adds a border/underline to mark the actively-
   sorted column — covering both this fork's class names and the older
   headerSortUp/Down names defensively, since which one actually applies
   isn't confirmed. */
.tablesorter-default .tablesorter-headerAsc,
.tablesorter-default .tablesorter-headerDesc,
.tablesorter-default .headerSortUp,
.tablesorter-default .headerSortDown {
    border-bottom: none !important;
    text-decoration: none !important;
}

/* This tablesorter build doesn't actually render a .tablesorter-icon element
   (confirmed via live DOM inspection), so the arrow is generated content
   attached directly to .tablesorter-header-inner — guaranteed to sit right
   next to the header text since it's part of that same element. */
.tablesorter-header-inner::after {
    font-family: FontAwesome;
    content: "\f0dc";
    margin-left: 6px;
    font-size: 11px;
    color: var(--muted2);
    opacity: .5;
}

.tablesorter-headerAsc .tablesorter-header-inner::after {
    content: "\f0de";
    opacity: 1;
    color: var(--accent);
}

.tablesorter-headerDesc .tablesorter-header-inner::after {
    content: "\f0dd";
    opacity: 1;
    color: var(--accent);
}

.tablesorter-header.sorter-false .tablesorter-header-inner::after {
    content: none;
}

/* Once a column is actually sorted, this build adds its own default active-
   sort affordances (a second icon element trailing the column, and an
   underline on the header text) — since our ::after arrow above already
   covers the asc/desc/unsorted states, suppress the plugin's own extras. */
.tablesorter-header,
.tablesorter-header:focus,
.tablesorter-header-inner,
.tablesorter-headerAsc,
.tablesorter-headerDesc {
    text-decoration: none !important;
}

.tablesorter-icon {
    display: none !important;
}

.tablesorter thead tr {
    line-height: 40px;
    font-size: .9em;
    color: #444;
}
.tablesorter>tbody>tr:nth-child(even) {
    background-color: #F8F8F8;
}

.tablesorter tbody td {
    padding: 5px;
    line-height: 20px;
    font-size: 1.1em;
    color: #555;
}

.tablesorter tbody td label {
    margin-left: 10px; 
}

.tablesorter .btn-screen {
    font-weight: 600;
}

/* Was a 32x32 background-image icon (blurry at this size, dated look) —
   replaced with a plain CSS dot. Same class names, so no JS/markup changes
   needed anywhere these are used. */
span.power-on,
span.power-off {
    width: 11px;
    height: 11px;
    border-radius: 50%;
    display: inline-block;
    background-image: none;
}

span.power-on {
    background: #22c55e;
    box-shadow: 0 0 0 3px rgba(34,197,94,.15);
}

span.power-off {
    background: #cbd5e1;
    box-shadow: 0 0 0 3px rgba(100,116,139,.10);
}

/* Same red already used for offline in the zone/site summary's own Online/
   Offline stat (previously scoped to just .site-stats .site-stat), now
   general-purpose so an individual player row's own offline dot can match
   it — box-shadow left at .power-off's own muted tint rather than a red
   one, since that's a subtle background glow, not the dot's main color. */
span.power-off-red {
    background: #ef292a;
}

/* Centers the online/offline dot within its column in every player table
   (the full tbPlayer views and the compact player-nested-table alike) —
   selecting by content via :has() rather than column position, so it
   applies uniformly regardless of how many columns precede it in a given
   table. Scoped to .tbPlayer specifically so it doesn't touch
   .site-stats's own power-on/power-off usage (already laid out/aligned on
   its own terms). */
.tbPlayer td:has(> .power-on),
.tbPlayer td:has(> .power-off) {
    text-align: center;
}

/* span.brand-icon-*, its size overrides, and .chip-brand's own icon-
   sizing override all moved to ddnv26/css/brand-icons.css - section-
   specific CSS now lives in that section's own folder rather than this
   shared one, by request - loaded only by ddnv26/default.aspx (the only
   page that actually uses these classes). Scoped out of this shared base
   file since they were DDN-specific (not truly shared) and this file's
   own copy pointed at the now-retired legacy ddn/ app's image folder,
   which no longer needs consideration at all. */

/* ~75% of the original 32px badges — same specificity as the 13 rules
   above (class + type), so this wins purely by being later in the file,
   without needing to touch each background-image declaration. */
span[class^="brand-icon-"] {
    width: 24px;
    height: 24px;
}

.tablesorter {
    font-size: 14px !important;
    border-collapse: collapse;
}

.tablesorter tbody td > span:not(.site-stats) {
    font-size: 1.1em;
    font-weight: 600;
}

/* Zone table (5 cols: Zone, Language, Brands, Screens, Actions) — last
   column holds up to 3-4 action icons. Player table (unchanged, 7/9 cols)
   keeps its own separate Online/Content-Up-to-date columns per screen. */
#ndTable .tablesorter tbody td:last-child {
    width: 140px;
    white-space: nowrap;
}
#pdTable .tablesorter tbody td:nth-child(8) {
    white-space: nowrap;
}
#pdTable .tablesorter tbody td:last-child {
    width: 110px;
    white-space: nowrap;
}

span.span-yes,
span.span-no {
    font-weight: 600;
}
span.span-yes {
    color: #16a34a;
}
span.span-no {
    color: #ef292a;
}
span.span-yes::before,
span.span-no::before {
    font-family: FontAwesome;
    margin-right: 4px;
    font-weight: normal;
}
span.span-yes::before {
    content: "\f00c";
}
span.span-no::before {
    content: "\f00d";
}

span.span-num {
    /*color: #0078D7;*/
}

.btn-modal {
    background-color: transparent;
    border-color: transparent;
    color: #666;
    font-size: 1.05em;
    font-weight: 500;
    width: 130px;
}
.btn-modal:hover, .btn-modal:active, .btn-modal:focus {
  color: #fff !important;
  background-color: #01A453 !important;
  border-color: #fff !important;
}

label > i:hover {
    color: #01467D;
}

/* modal body */
/* Sized to its widest row's actual content (fit-content) rather than a
   fixed 96% of the modal, then centered as one unit via margin:auto —
   every row inside stays plain left-aligned (default), so they all share
   the same left edge instead of each one separately centering within a
   wider box and drifting out of alignment with the others. */
.edit-block {
    display: block;
    margin: 0px auto !important;
    text-align: Left;
    width: fit-content;
    max-width: 96%;
    /*border: solid 1px #b3b3b3;
    border-radius: 2%;*/
}

.modal-row {
    margin: 0px 12px;
}

.modal-row-2 {
    margin: 8px 12px;
}

/* Groups related fields under a small labeled box — e.g. content.aspx's
   "Play Schedule" (days + start/end time together), rather than those
   rows just sitting anonymously among all the other unrelated fields. */
.form-section {
    margin: 8px 12px;
    padding: 12px 12px 4px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--panel2);
}

.form-section-title {
    font-size: 11px;
    font-weight: 800;
    text-transform: uppercase;
    letter-spacing: .04em;
    color: var(--muted);
    margin-bottom: 8px;
}

/* .modal-row-2's own left/right margin would otherwise double up with
   .form-section's own padding here. */
.form-section > .modal-row-2 {
    margin-left: 0;
    margin-right: 0;
}

.cb-box {
    margin-right: 20px;
    display: inline-flex;
}

.cb-box label {
    font-weight: 600;
    color: #655;
}

.cb-label {
    display: inline-flex;
    margin-right: 20px;
    font-weight: 700;
}

.cb-cell > i {
    font-size: 1.5em;
    position: relative;
    top: 2px;
    left: -5px;
    cursor: pointer;
}
/* Scoped to .actions-cell specifically (not just any td i) — action icons
   are nested one level deeper now, inside a fixed-width .action-slot
   wrapper (see .action-slot), and a broader "any icon in any td"
   descendant selector would also catch the zone name cell's own
   .zone-toggle-icon (chevron) and override its 12px font-size. */
.tbNetwork td.actions-cell i:hover,
.tbPlayer td.actions-cell i:hover {
    color: #01467D;
}

.setting-switch {
    display: inline-flex;
    width: 33%;
}

.setting-switch > span {
    line-height: 34px;
    font-size: 18px;
    font-weight: 600;
    margin-right: 20px;
    color: #444;
}

/* line-height:1 stops the icon's own font falling back to "normal" line
   spacing, which needs more vertical room than the cell's 20px and was
   forcing the whole row taller than the header row above it (42px vs
   36px); vertical-align:middle centers it against that shorter line box
   in place of the old fixed top:5px offset, which was hand-tuned for the
   previous (taller, inconsistent) row heights. */
.tbNetwork td.actions-cell i {
    color: var(--accent);
    font-size: 1.5em;
    line-height: 1;
    vertical-align: middle;
    cursor: pointer;
}

.tbPlayer td.actions-cell i {
    color: var(--accent);
    line-height: 1;
    vertical-align: middle;
}

/* No-sites empty state (.noSiteBoard) is fully styled further down,
   alongside the other dashboard-panel rules — see "No-subscriber board". */

/* =================================
   Customize 3rd plugin CSS
   ================================= */

/* replace css of bootstrap */
button:active, .button:active, button:focus, .button:focus, button:hover, .button:hover{
  outline: 0 !important;
  outline-offset: 0  !important;
  background-image: none  !important;
  -webkit-box-shadow: none !important;
  box-shadow: none  !important;
}

.fa-lg {
    vertical-align: 0;
}

.btn {
    border-radius: 2px;
}

.btn-success {
    background-color: #73D118;
}

/* replace css of multi-select */
.ms-drop {
    text-align: left;
}

.ms-drop input[type="checkbox"] {
    margin-top: -3px;
}

.ms-drop input[type="radio"] {
    display: none;
}

.ms-drop label {
    font-size: 0.9em;
    margin: 3px 5px 3px 0;
    padding: 0 5px;
}

.ms-drop ul>li label:hover {
    background-color: var(--accentSoft);
    color: var(--text);
}

.ms-drop ul {
    padding: 5px 0px 5px 5px;
}

.ms-choice > span {
    font-size: 0.9em;
}

.ms-choice > div {
    top: 5px;
}

.ms-parent > button {
    height: 34px;
    line-height: 32px;
}

/* ========================================
    Special Effects

   ======================================== */

/* bootstrap customer bar */
#custom-search-input {
    margin:0;
    margin-top: 10px;
    padding: 0;
    display: none;
}

#custom-search-input #siteSearchTerm {
    width: 186px;
    font-weight: 600;
    color: #555;
}
 
#custom-search-input .search-query {
    padding-right: 30px;
    padding-left: 8px;
    /* IE7-8 doesn't have border-radius, so don't indent the padding */
 
    margin-bottom: 0;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    border-radius: 3px;
}
 
#custom-search-input button {
    border: 0;
    background: none;
    /** belows styles are working good */
    padding: 2px 5px;
    margin-top: 2px;
    position: relative;
    left: -32px;
    /* IE7-8 doesn't have border-radius, so don't indent the padding */
    margin-bottom: 0;
    -webkit-border-radius: 3px;
    -moz-border-radius: 3px;
    border-radius: 3px;
    color: #D9230F;
}
 
.search-query + span > button {
    z-index: 3 !important;   
}
/* End of bootstrap customer bar */

/* bootstrap arrow button */
.btn-arrow-right,
.btn-arrow-left {
    position: relative;
    padding-left: 12px;
    padding-right: 12px;
}
.btn-arrow-right {
    padding-left: 12px;
}
.btn-arrow-left {
    padding-right: 12px;
}
.btn-arrow-right:before,
.btn-arrow-right:after,
.btn-arrow-left:before
/*.btn-arrow-left:after*/ { /* make two squares (before and after), looking similar to the button */
    content:"";
    position: absolute;
    top: 4px; /* move it down because of rounded corners */
    width: 22px; /* same as height */
    height: 22px; /* button_outer_height / sqrt(2) */
    background: inherit; /* use parent background */
    border: inherit; /* use parent border */
    border-left-color: transparent; /* hide left border */
    border-bottom-color: transparent; /* hide bottom border */
    border-radius: 0px 4px 0px 0px; /* round arrow corner, the shorthand property doesn't accept "inherit" so it is set to 4px */
    -webkit-border-radius: 0px 4px 0px 0px;
    -moz-border-radius: 0px 4px 0px 0px;
}
.btn-arrow-right:before,
.btn-arrow-right:after {
    transform: rotate(45deg); /* rotate right arrow squares 45 deg to point right */
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
    -o-transform: rotate(45deg);
    -ms-transform: rotate(45deg);
}
.btn-arrow-left:before,
.btn-arrow-left:after {
    transform: rotate(225deg); /* rotate left arrow squares 225 deg to point left */
    -webkit-transform: rotate(225deg);
    -moz-transform: rotate(225deg);
    -o-transform: rotate(225deg);
    -ms-transform: rotate(225deg);
}
.btn-arrow-right:before,
.btn-arrow-left:before { /* align the "before" square to the left */
    left: -12px;
}
.btn-arrow-right:after,
.btn-arrow-left:after { /* align the "after" square to the right */
    right: -12px;
}
.btn-arrow-right:after,
.btn-arrow-left:before { /* bring arrow pointers to front */
    z-index: 1;
}
.btn-arrow-right:before,
.btn-arrow-left:after { /* hide arrow tails background */
    background-color: white;
}
/* End of bootstrap arrow button */   

/* Pure CSS Custom Checkboxes */
.styled-checkbox {
  position: absolute;
  opacity: 0;
}
.styled-checkbox + label {
  position: relative;
  cursor: pointer;
  padding: 0;
}
.styled-checkbox + label:before {
  content: '';
  margin-right: 5px;
  display: inline-block;
  vertical-align: text-bottom;
  width: 20px;
  height: 20px;
  background: #f0f0f0;
  border: 1px solid #bbb
}
.styled-checkbox:hover + label:before {
  background: #73D118;
}
.styled-checkbox:focus + label:before {
  box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.12);
}
.styled-checkbox:checked + label:before {
  background: #73D118;
}
.styled-checkbox:disabled + label {
  color: #b8b8b8;
  cursor: auto;
}
.styled-checkbox:disabled + label:before {
  box-shadow: none;
  background: #ddd;
}
.styled-checkbox:checked + label:after {
  content: '';
  position: absolute;
  left: 5px;
  top: 9px;
  background: #fff;
  width: 3px;
  height: 3px;
  box-shadow: 2px 0 0 white, 4px 0 0 white, 4px -2px 0 white, 4px -4px 0 white, 4px -6px 0 white, 4px -8px 0 white;
  -webkit-transform: rotate(45deg);
          transform: rotate(45deg);
}
/* End of Pure CSS Custom Checkboxes */

/* Accordion css */
.accordion {
  position: relative;
  margin-bottom: 1px;
  width: 100%;
  color: #fff;
  overflow: hidden;
}
.accordion > input {
  position: absolute;
  opacity: 0;
  z-index: -1;
}
.accordion > label {
  position: relative;
  display: inline-flex;
  align-items: center;
  padding: 0 0 0 1em;
  color: #5397f0;
  font-weight: bold;
  line-height: 3;
  cursor: pointer;
  width: 99%;
  margin-left: 5px;
  border-bottom: 2px solid;
}
.accordion > label > span {
    cursor: default;
}

.accordion > label > i {
    font-size: 28px;
    cursor: pointer;
}
.accordion > label > i:first-child {
    margin-left: 30px;
}
.accordion > label > i#iconVOD {
    background-color: #5397f0;
    color: #fff;
    border-radius: 50%;
    width: 28px;
    height: 28px;
    line-height: 30px;
    font-size: 22px;
    font-weight: 600;
    margin-left: 5px;
    font-family: inherit;
}
.accordion > label > i#iconVOD:hover {
    background-color: #2166ac;
}


.acc-content {
  height: 0;
  overflow: hidden;
  -webkit-transition: height .35s;
  -o-transition: height .35s;
  transition: height .35s;
  width: 100%;
}
.acc-content p, #pdTable p {
  margin: .5em;
  color: #888;
  margin-left: 60px;
  font-weight: 600;
}

.accordion > hr {
    position: relative;
    border-top: 2px solid #5397f0;
    width: 99%;
    margin: 0 0 5px 5px;
    display: none;
}

/* :checked */
.accordion > input:checked ~ .acc-content {
  height: auto;
}
.accordion > input:checked ~ label {
  border-bottom: 1px solid #ccc;
}
.accordion > input:checked ~ hr {
    display: block;
}

/* Icon */
.accordion > label::after {
  position: absolute;
  right: 0;
  top: 0;
  font-size: 1.5em;
  display: block;
  width: 2em;
  height: 2em;
  line-height: 2;
  text-align: center;
  -webkit-transition: all .35s;
  -o-transition: all .35s;
  transition: all .35s;
}
.accordion > input[type=checkbox] + label::after {
  content: "\f078";
}
input[type=radio] + label::after {
  content: "\25BC";
}
.accordion > input[type=checkbox]:checked + label::after {
  transform: rotate(315deg);
}
.accordion > input[type=radio]:checked + label::after {
  transform: rotateX(180deg);
}

/* The table itself is what's indented (not just its content) — width is
   reduced by the same amount as the margin so the right edge stays
   exactly where it was (avoiding the earlier "header doesn't reach the
   end of the row" issue), while the left edge, and any border the table
   itself carries, genuinely shifts right under the site row above it. */
/* border-collapse:collapse (set on .tablesorter, added by the plugin)
   would otherwise prevent border-radius from rendering on a table in
   most browsers — separate + zero spacing gives the same flush-edge
   look without that limitation. */
/* No border-radius/overflow:hidden of its own anymore — this table's own
   height is no longer fixed once a zone's players can expand inside it, and
   a second clip+radius layer nested inside .accordion's own (which already
   rounds/clips the true bottom of whatever total content height results)
   fought with it once that height became dynamic, producing a stray
   rounded box artifact when the last zone's players were shown. Relying on
   .accordion's own outer clip alone is sufficient and stays correct at any
   height. */
.acc-content > table {
    width: calc(100% - 24px);
    margin: 0 0 0 24px;
    border-collapse: separate;
    border-spacing: 0;
}

/* Zone -> player nesting: same pure-CSS checkbox+label expand pattern as
   the site -> zone accordion above, except the toggle lives inside a <td>
   rather than wrapping the whole row, so :has() is used to reach from the
   zone <tr> down to its checkbox and control the following sibling
   detail <tr> (a plain adjacent-sibling selector can't reach out of the
   <td> the checkbox lives in). */
.zone-toggle-input {
    position: absolute;
    opacity: 0;
    z-index: -1;
}

.zone-name-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    cursor: pointer;
    color: inherit;
    max-width: 100%;
    /* Lets .zone-name-text actually shrink/ellipsis below its content size —
       flex items default to a min-width equal to their content, which would
       otherwise stop the text from ever truncating. */
    min-width: 0;
}

/* The truncating part of the zone name cell — separate from the toggle
   icon so long names ellipsis on their own without squeezing the icon. */
.zone-name-text {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    min-width: 0;
}

.zone-toggle-icon {
    font-size: 12px;
    color: var(--accent);
    flex-shrink: 0;
    transition: transform .25s, color .12s ease;
}

.zone-name-toggle:hover .zone-toggle-icon {
    color: #01467D;
}

.zone-toggle-input:checked + .zone-name-toggle .zone-toggle-icon {
    transform: rotate(180deg);
}

.player-detail-row {
    display: none;
}

tr:has(> td > .zone-toggle-input:checked) + tr.player-detail-row {
    display: table-row;
}

/* border-bottom intentionally left at its base (.tablesorter tbody td)
   value — it's what separates the expanded player list from whatever zone
   row comes next. */
.player-detail-row > td {
    padding: 0 !important;
}

.player-detail-inner {
    padding: 0;
    background: var(--panel);
}

/* Indented the same way .acc-content > table is indented under the site
   row above it — width reduced by the same amount as the margin so the
   right edge lines up with the zone table's own right edge. */
.player-nested-table {
    width: calc(100% - 24px);
    margin: 0 0 0 24px;
    border-left: 2px solid var(--border);
    border-collapse: separate;
    border-spacing: 0;
    overflow: hidden;
}

/* Zone/player name columns fixed to a specific width so the Language
   column lines up between the two tables. table-layout:fixed is what
   makes that width actually stick (in the default auto layout, a column
   can still grow past its declared width to fit long content — which
   would defeat the alignment and stop ellipsis from ever kicking in). The
   player table sits 24px further right than the zone table (its own
   extra indent under a zone row), so its name column is 24px narrower —
   250px vs 226px — to land the Language column at the same page
   position in both. */
.tbNetwork,
.player-nested-table {
    table-layout: fixed;
}

.tbNetwork thead th:first-child,
.tbNetwork tbody td:first-child {
    width: 250px;
}

.player-nested-table thead th:first-child,
.player-nested-table tbody td:first-child {
    width: 226px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Lang column capped the same in both tables — since the name column
   above already absorbed the 24px indent offset between the two tables,
   giving this (and every column after it) an equal width in both keeps
   Brands, and everything past it, aligned too. */
.tbNetwork thead th:nth-child(2),
.tbNetwork tbody td:nth-child(2),
.player-nested-table thead th:nth-child(2),
.player-nested-table tbody td:nth-child(2) {
    width: 75px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}

/* Brands column — same alignment logic as Lang above, just wider since
   a row can carry a lot of brand icons. */
.tbNetwork thead th:nth-child(3),
.tbNetwork tbody td:nth-child(3),
.player-nested-table thead th:nth-child(3),
.player-nested-table tbody td:nth-child(3) {
    width: 400px;
}

/* tbNetwork's Screens column — the only explicit-width column left
   unmatched by player-nested-table now that the latter has its own
   Last Check-in/Online/Content-status columns (below) instead of a blank
   spacer. Each table still needs EVERY column but its last (Actions) to
   have an explicit width — that's what keeps table-layout:fixed from
   proportionally re-stretching Name/Lang/Brands above; it no longer
   requires the two tables' non-Name/Lang/Brands columns to match in either
   count or width. */
.tbNetwork thead th:nth-child(4),
.tbNetwork tbody td:nth-child(4) {
    width: 350px;
}

/* Screens header now spells out what the 3 numbers mean ("Screens (Total,
   Online, Up-to-Date)") — nowrap so that longer label doesn't wrap and
   blow out the unified row height. */
.tbNetwork thead th:nth-child(4) {
    white-space: nowrap;
}

/* Player-nested-table's own status columns: Last Check-in, Online,
   Content-up-to-date — replacing the blank 4th-column spacer this table
   used to carry. Actions (5th column in tbNetwork, 7th here) stays the one
   column with no explicit width in both tables, so it's still the sole
   flexible column absorbing leftover space. */
.player-nested-table thead th:nth-child(4),
.player-nested-table tbody td:nth-child(4) {
    width: 140px;
}

.player-nested-table thead th:nth-child(5),
.player-nested-table tbody td:nth-child(5) {
    width: 60px;
}

.player-nested-table thead th:nth-child(6),
.player-nested-table tbody td:nth-child(6) {
    width: 70px;
}

/* The indent border used to live on the table itself, but a border on the
   <table> box spans its full height regardless of row content — once the
   player-detail-row made one row much taller, that same border just kept
   going down alongside it. Moving it to each row's own first cell keeps
   the indent guide next to actual zone rows (and the thead row above
   them) only; .player-detail-row isn't class="rowAll" so it's naturally
   skipped, leaving no border next to the nested player table's own
   indent gutter. */
/* Direct-child combinator on thead — a plain descendant selector here would
   also reach the nested player table's own thead (it's still a descendant
   of .acc-content > table, just one level further in), doubling up with
   .player-nested-table's own border-left on that inner header cell. */
.acc-content > table > thead > tr > th:first-child,
.acc-content > table tr.rowAll > td:first-child {
    border-left: 2px solid var(--border);
}

/* Closing bottom edge of the zone list — given to the last zone row's own
   cells (not the table itself, which would span its full width including
   the empty indent gutter reserved for a nested player table and show as
   a stray line there). When that last zone's players are expanded, the
   true final row is the nested player table instead, so it gets its own
   matching bottom border — scoped to the nested table's own (already
   indented) width, not the outer row's, so it doesn't cross that gutter
   either. */
.acc-content > table tr.rowAll:not(:has(~ tr.rowAll)) > td {
    border-bottom: 2px solid var(--border);
}

.acc-content > table tr.rowAll:not(:has(~ tr.rowAll)) + tr.player-detail-row .player-nested-table {
    border-bottom: 2px solid var(--border);
}

.accordion > label > span.badge {
    position: absolute;
    right: 5em;
    top: 1.25em;
    background-color: #5397f0;
}

/* End of Accordion CSS*/

/* =============================
    Material Input
   ============================= */
/* form starting stylings ------------------------------- */
/* Bordered/rounded box matching the rest of the page's inputs (e.g.
   .search-query) instead of the old underline-only Material style — still
   keeps the floating-label behavior (label shrinks and rises on focus/
   valid content), just against a proper box instead of a bare line. */
.inputGroup {
  position:relative;
  float: left;
  margin: 20px 20px 10px 20px;
}
.inputGroup input {
  font-size: 14px;
  padding: 10px 12px;
  display:block;
  width:300px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel);
  color: var(--text);
  transition: border-color .12s ease, box-shadow .12s ease;
}
.inputGroup input:focus {
  outline:none;
  border-color: var(--accent);
  box-shadow: 0 0 0 3px var(--accentSoft);
}

/* LABEL ======================================= */
/* Sits inside the box at rest; on focus/valid it rises to straddle the
   border (top:-9px), with a background matching the input so it "notches"
   into the border line instead of overlapping it illegibly. */
.inputGroup > label {
  color: var(--muted);
  font-size: 14px;
  font-weight: 600;
  position:absolute;
  pointer-events:none;
  left: 12px;
  top: 12px;
  background: var(--panel);
  padding: 0 4px;
  transition:0.15s ease all;
  -moz-transition:0.15s ease all;
  -webkit-transition:0.15s ease all;
}

/* Adjustment of <= IE9 */
.inputLabelOfIe9 {
    top: -20px !important;
    font-size: 14px !important;
    color: var(--accent) !important;
}

/* active state */
.inputGroup input:focus ~ label, .inputGroup input:valid ~ label 		{
  top: -9px;
  left: 8px;
  font-size:12px;
  color: var(--accent);
}

/* .bar/.highlight were the old underline's animated accents — no longer
   used now that the input has its own full border + focus ring, but kept
   in the DOM (per the existing markup in default.aspx) rather than
   removing markup across every modal, so just hidden here. */
.bar,
.highlight {
  display: none;
}

/* ANIMATIONS ================ */
@-webkit-keyframes inputHighlighter {
	from { background:#5264AE; }
  to 	{ width:0; background:transparent; }
}
@-moz-keyframes inputHighlighter {
	from { background:#5264AE; }
  to 	{ width:0; background:transparent; }
}
@keyframes inputHighlighter {
	from { background:#5264AE; }
  to 	{ width:0; background:transparent; }
}

/*=== End Material Input ===*/

/* =============================
    Switch CSS
   =============================*/
.switch {
  position: relative;
  display: inline-block;
  width: 60px;
  height: 34px;
}

.switch input {display:none;}

.switch > .slider {
  position: absolute;
  cursor: pointer;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: #ccc;
  -webkit-transition: .4s;
  transition: .4s;
  margin-bottom: 0px;
}

.switch > .slider:before {
  position: absolute;
  content: "";
  height: 26px;
  width: 26px;
  left: 4px;
  bottom: 4px;
  background-color: white;
  -webkit-transition: .4s;
  transition: .4s;
}

.switch > input:checked + .slider {
  background-color: #73D118; /*rgb(0, 173, 239);*/ 
}

.switch > input:focus + .slider {
  box-shadow: 0 0 1px #01A453;
}

.switch > input:checked + .slider:before {
  -webkit-transform: translateX(26px);
  -ms-transform: translateX(26px);
  transform: translateX(26px);
}

/* Rounded sliders */
.slider.round {
  border-radius: 34px;
}

.slider.round:before {
  border-radius: 50%;
}

/* Compact variant — same look/colors as the full-size switch above, scaled
   down for inline use next to a label (From Zone / VOD / 4K) instead of its
   own full-width row. */
.switch-sm {
  width: 32px;
  height: 18px;
}

.switch-sm > .slider:before {
  height: 14px;
  width: 14px;
  left: 2px;
  bottom: 2px;
}

.switch-sm > input:checked + .slider:before {
  -webkit-transform: translateX(14px);
  -ms-transform: translateX(14px);
  transform: translateX(14px);
}
/*=== End Switch ===*/

.form-switch-inline {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
}
    
/* ==========================================================================
.___  ___.  _______  _______   __       ___           ______      __    __   _______ .______       __   _______     _______.
|   \/   | |   ____||       \ |  |     /   \         /  __  \    |  |  |  | |   ____||   _  \     |  | |   ____|   /       |
|  \  /  | |  |__   |  .--.  ||  |    /  ^  \       |  |  |  |   |  |  |  | |  |__   |  |_)  |    |  | |  |__     |   (----`
|  |\/|  | |   __|  |  |  |  ||  |   /  /_\  \      |  |  |  |   |  |  |  | |   __|  |      /     |  | |   __|     \   \    
|  |  |  | |  |____ |  '--'  ||  |  /  _____  \     |  `--'  '--.|  `--'  | |  |____ |  |\  \----.|  | |  |____.----)   |   
|__|  |__| |_______||_______/ |__| /__/     \__\     \_____\_____\\______/  |_______|| _| `._____||__| |_______|_______/     

   ========================================================================== */
@media (max-width: 1600px) {
	#dvMenu .tbl-center {
	  float: right;
	  margin-right: 100px !important;
	}

    #left-panel {
        position: fixed;
    }
}

@media (max-width: 1312px) and (min-width: 1030px) {
	#dd-logo {
		display: none;
	}
	
	#dvMenu .tbl-center {
	  float: none;
	  margin-right: 100px !important;
	}
	
    #dvMenu .tbl-center > #head-banner{
        text-align: right;
        margin: 2px 30px 0px 20px;
    }

	#dvMenu {
	  height: 60px !important;
	  min-height: 60px !important;
	}

    #left-panel {
        position: absolute;
    }
}

@media (max-width: 1029px) and (min-width: 769px) {
  #left-panel {
    left: -190px;
  }

  #main {
    margin-left: 0;
  }
  
  #dd-logo, #head-banner { display: none }
  
  #dvMenu .tbl-center {
	  float: none  !important;
	  margin: 0 0 0 0 !important;
	  width: 100%;
	}
  
    #dvMenu {
		height: 50px !important;
		min-height: 50px !important;
	}
	
	/*Make dropdown links appear inline*/
	#dvMenu ul {
		position: static;
		display: none;
		width: 100%;
	}
	/*Create vertical spacing*/
	#dvMenu li {
		margin-bottom: 0px;
	}
	/* menu item bottom border */
	#menu > li {
		border-bottom: solid 1px #E6E6E6;
	}
	/* menu item content's backgroup color */
	#menu > li > a {
		background: #f2f2f2 !important;
	}
	/* selected or hover menu item */
	#menu > li:hover > a {
	    background: #083890 !important;
	}
	/* selected or hover submenu item in dropdown menu */
	.to-hide > li > a:hover {
		background: #3868B0 !important;
	}
	/*Make all menu links full width*/
	#dvMenu ul li, #dvMenu li a {
		width: 100% !important;
	}
	/*Display 'show menu' link*/
	.show-menu {
		display: block !important;
	}
	/*Style for dropdown links*/
	#dvMenu li:hover ul a {
		text-align: center !important;
	}
  
}

@media (max-width: 768px) { 
  #main {
    margin-left: 0;
  }

  #left-panel {
    left: -190px;
  }
  
  #dd-logo, #head-banner { display: none }
  
  #dvMenu .tbl-center {
	  float: none;
	  margin: 0 0 0 0 !important;
  }
  
  #dvMenu {
	height: 50px;
	min-height: 50px;
  }
}

@media (max-width: 550px) {
  #content {
    padding: 0;
  }

  #content > .row {
    display: none;
  }

  #main {
    margin-left: 0;
  }

  #left-panel {
    left: -190px;
  }
  
  #dd-logo, #head-banner { display: none }

  #dvMenu {
	height: 50px;
	min-height: 50px;
  }
}

@media print {
    a:link:after,
    a:visited:after {
        content: "" !important;
    }

    html, body {
      font-size: 12px;
      background: #fff;
    }
}

@media all {
    @-ms-viewport{
        width: device-width;
    }
    @viewport{
        width: device-width;
    }
}

/* ==========================================================================
    REPORTS PORTAL-STYLE RESKIN
    Visual tokens borrowed from /reports/Reports.master + /reports/default.aspx.
    Layout/structure/JS hooks untouched — styling only.
   ========================================================================== */

/* Defined on :root (not #masterContainer) because the modal markup on this
   page sits outside #masterContainer in the DOM and still needs these. */
:root {
    --bg: #ffffff;
    --text: #0f172a;
    --muted: #475569;
    --muted2: #64748b;
    --border: #e2e8f0;
    --panel: #ffffff;
    --panel2: #f8fafc;
    --shadow: 0 14px 28px rgba(15,23,42,.08);
    --accent: #2166ac;
    --accentSoft: rgba(33,102,172,.10);
    --accentBorder: rgba(33,102,172,.35);
    --radius: 8px;
    --radius-sm: 12px;
    /* --radius-btn moved to tokens-v26.css (@import'd at the top of this
       file) - genuinely single-sourced now instead of duplicated here and
       in baseV26.css. */
    /* Matches BlueBarMenu.master's/WhiteBarMenu.master's own --font (self-
       hosted Roboto, same files /default.aspx uses) - by request. This
       file loads AFTER those masters' own inline styles on every page
       that uses both (a page's own HeadContent, where this link tag
       lives, renders after the master's head content), so a page loading
       this file would otherwise silently override the masters' own
       --font back to the system stack for the whole page, menu included -
       custom properties resolve off the last :root declaration in the
       cascade, not off whichever file happens to use var(--font). */
    --font: 'Roboto', Arial, sans-serif;
}

body,
.modal-content {
    font-family: var(--font);
}

/* Ribbon header — was a bright, unrelated blue (.bgcolor-2: #5397f0) sitting
   directly under the new dark navy header; recolored to a plain page-title
   bar so it reads as part of the white content instead of a 3rd shade of blue. */
/* No longer needs position:sticky — .rightPane-inner is now a flex column
   with the ribbon as a fixed-height row above .rightPane-scroll, so the
   ribbon naturally never scrolls and the scrollbar only appears next to
   the content below it. */
#ribbon.bgcolor-2 {
    background: var(--panel) !important;
    border-bottom: 1px solid var(--border);
    height: auto;
    flex: 0 0 auto;
    padding: 10px 24px;
    display: flex;
}

/* Title + action buttons share this row — with filters moved out to their
   own panel below, space-between just works with no wrap-priority tricks
   needed (only 2 items, so there's nothing to fight over). */
.ribbon-row-top {
    width: 100%;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 14px;
    flex-wrap: wrap;
    min-height: 34px;
}

.ribbon-button-alignment {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    padding-top: 0;
    /* Same lighter accent blue as /user/changews.aspx's own sub-heading,
       rather than the page's usual dark text color. */
    color: var(--accent);
    font-size: 1.2em;
    font-weight: 800;
    letter-spacing: .01em;
    white-space: nowrap;
    flex-shrink: 0;
}

/* .ribbon-title-text is the part JS swaps via .text() when switching
   views (site dashboard / player dashboard / enterprise) — kept as its
   own inner span specifically so those updates never wipe out the logo
   sitting next to it (.text() replaces all child content, image included,
   if applied to the outer element instead). */
.ribbon-logo {
    height: 28px;
    width: auto;
}

/* Filters/search panel — its own labeled, rounded frame below the ribbon,
   hidden entirely (see updateFiltersPanelVisibility in dashboard.js) unless
   there are more than 3 dealers to filter/search across. */
.filters-panel {
    display: none;
    align-self: center;
    width: fit-content;
    max-width: calc(100% - 48px);
    /* Bottom margin is 0 on purpose — .dbTable below already carries its
       own 18px top margin, so this alone matches the 18px above (there's
       nothing below the ribbon adding extra space the way .dbTable does). */
    margin: 18px auto 0 auto;
    padding: 10px 16px;
    background: var(--panel2);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    flex-wrap: wrap;
    align-items: center;
    justify-content: center;
    gap: 12px;
}

.filters-panel-label {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
    text-transform: uppercase;
    letter-spacing: .04em;
    white-space: nowrap;
}

.ribbon-center {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    justify-content: flex-start;
    gap: 8px;
}

/* Action buttons + utility links, at the end of the top row. */
#ribbon-actions {
    flex-shrink: 0;
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 10px;
}

#ribbon-actions > ul {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 6px;
    list-style: none;
    margin: 0;
    padding: 0 !important;
}

/* Same blue family as the main nav (--navBg), lighter than a solid navy
   fill but solid enough (not a faint transparent wash) to read clearly as
   an active, colored button rather than a disabled one. */
#ribbon-actions ul li a {
    display: inline-flex;
    align-items: center;
    /* Was var(--radius-sm) (12px) - on this button's own shorter height,
       12px rounded almost the whole box into a pill. var(--radius-btn)
       (see :root) is the shared "slight rounding" value now. */
    border-radius: var(--radius-btn);
    color: var(--accent);
    font-size: 13px;
    font-weight: 700;
    line-height: 1.2;
    padding: 8px 10px;
    white-space: nowrap;
    background: #dce8f4;
    border: 1px solid var(--accent);
    transition: background .12s ease, color .12s ease, border-color .12s ease;
}

#ribbon-actions ul li a:hover {
    background: #c7dcef;
    color: var(--accent);
    border-color: var(--accent);
}

#ribbon-actions > ul:last-child li a {
    padding: 6px 8px;
    font-weight: 600;
    color: var(--muted2);
    background: transparent;
    border-color: transparent;
}

/* Explainer strip — sits between the ribbon and the filter bar/content
   below it, briefly saying what the page is for plus a legend for any
   per-item icons the page uses (edit/delete/etc.). Shared across the DDN
   pages (and reused as-is on /user/changews.aspx, which also loads this
   stylesheet) rather than a bespoke block per page. */
/* Left accent border + info icon (same callout treatment as
   /user/changews.aspx's .cw-info) instead of a fully-bordered box on all
   four sides — reads as a page-level note, not a separate boxed-off panel. */
/* Pure positioning frame — width/max-width/margin here define where the
   box's top-right corner sits, and (unlike the previous version of this
   fix) this NEVER changes between expanded/collapsed, in either state.
   All the actual visible chrome (background, border, padding, flex layout)
   lives on .page-explainer-inner instead, which is what actually resizes.
   Reason: this box is centered (see the width/max-width comment below),
   not flush against its parent's edge — so on wide screens there's a real
   gap on each side, and its right edge sits at a viewport-dependent
   position, not a fixed offset. Shrinking THIS element directly (an
   earlier version of this fix did) recentered/right-anchored it against
   the wrong reference point and moved that corner. Keeping this frame's
   own box permanently fixed at the expanded footprint, and only
   right-aligning+shrinking the inner pill within it, means the inner
   pill's right edge is mathematically guaranteed to land exactly on the
   frame's — i.e. the expanded box's — own right edge, in both states. */
.page-explainer {
    /* NOT display:none here — this class is shared by every page's info
       panel (content.aspx, cmsVOD.aspx, changews.aspx, concierge.aspx...),
       and only default.aspx's dashboard.js ever calls .show() on it. A
       default-hidden rule here previously left every OTHER page's panel
       permanently hidden with nothing to un-hide it. default.aspx hides its
       own instance inline instead (style="display:none" in the markup) —
       see the comment there for why (flash-before-hide on the no-sites
       screen). */
    /* Roughly 75% of the viewport (capped so it doesn't get absurdly wide
       on very large monitors), centered — same idea as /user/changews.aspx's
       .cw-info — rather than stretching edge-to-edge with the content below. */
    max-width: min(75vw, 1400px);
    width: 100%;
    /* #ribbon's own bottom padding (10px, not margin) doesn't collapse with
       anything, so it adds on top of this top margin for the real gap
       above; below, this margin collapses with the next element's own 18px
       top margin (.filters-panel / .cms-filter-bar) taking whichever is
       larger — 20px here intentionally makes the gap above the panel wider
       than the ~18px below it. */
    margin: 20px auto 0;
    position: relative;
}

.page-explainer-inner {
    display: flex;
    align-items: flex-start;
    flex-wrap: wrap;
    /* Column-gap kept small — it's also the icon-to-text spacing, and .cw-info
       handles its own text-to-legend separation via the legend's own
       border-left + padding-left, not this. */
    gap: 8px 12px;
    /* Fills the frame above exactly when expanded; the collapsed-state rule
       further down overrides this to fit-content instead. */
    width: 100%;
    padding: 12px 16px;
    background: var(--panel2);
    border-left: 4px solid var(--accent);
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    font-size: 13px;
    color: var(--muted);
    /* .rightPane-inner sets word-break:break-all (needed elsewhere for long
       unbroken strings like hardware IDs) — that made ordinary sentences
       here break mid-word instead of at word boundaries. */
    word-break: normal;
    overflow-wrap: break-word;
    /* Left-align explicitly — some ancestor on this page centers text by
       default, which this block shouldn't inherit. */
    text-align: left;
}

/* Collapse toggle — a pure-CSS checkbox hack (no JS) so it works
   identically on content.aspx and default.aspx without depending on
   dashboard.js, which content.aspx doesn't load. The checkbox itself is
   visually hidden; its :checked state (toggled by clicking the label)
   drives everything via the general sibling combinator. */
.page-explainer-toggle-input {
    position: absolute;
    width: 1px;
    height: 1px;
    opacity: 0;
    pointer-events: none;
}

.page-explainer-toggle {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
    margin-left: auto;
    padding: 2px 4px;
    cursor: pointer;
    color: var(--muted2);
    font-size: 13px;
}

/* Collapsed state: the only other visible child is .page-explainer-icon
   (text/legend are display:none — see above), and that icon has no
   left-margin pulling it rightward on its own, so it would otherwise sit
   pinned to the inner box's left edge while just the toggle (via its own
   margin-left:auto) sits at the right — two islands with a big gap between
   rather than one grouped unit. Grouping them at the right edge instead —
   "where the box ends when expanded" — needs the toggle's own auto margin
   turned off (it would otherwise still eat all the leftover space itself)
   so justify-content:flex-end can pack both together instead.

   width/margin here shrink .page-explainer-inner to fit that grouped
   content and right-align it — but .page-explainer (the outer frame) is
   untouched by this selector, so its box (and therefore the true position
   of its right edge — the actual anchor point) never moves. Shrinking the
   inner element within that fixed frame, rather than the frame itself,
   means the inner pill's right edge always lands exactly on the frame's —
   i.e. the always-expanded-sized — right edge, in both states. */
.page-explainer:has(.page-explainer-toggle-input:checked) .page-explainer-inner {
    justify-content: flex-end;
    width: fit-content;
    margin-left: auto;
    margin-right: 0;
}

.page-explainer:has(.page-explainer-toggle-input:checked) .page-explainer-toggle {
    margin-left: 0;
}

.page-explainer-toggle:hover {
    color: var(--accent);
}

.page-explainer-toggle-input:checked ~ .page-explainer-text,
.page-explainer-toggle-input:checked ~ .page-explainer-legend {
    display: none;
}

/* Hidden while expanded — the panel's own content already says what this
   is; only shown once collapsed, so there's still something explaining
   what the now-mostly-empty bar is/does. */
.page-explainer-toggle-label {
    display: none;
    font-weight: 700;
}

.page-explainer-toggle-input:checked ~ .page-explainer-toggle .page-explainer-toggle-label {
    display: inline;
}

/* fa-chevron-down (\f078) once collapsed, in place of the default
   fa-chevron-up — points the direction the panel will move on the next
   click either way. */
.page-explainer-toggle-input:checked ~ .page-explainer-toggle i:before {
    content: "\f078";
}

.page-explainer-icon {
    flex: 0 0 auto;
    margin-top: 1px;
    font-size: 20px;
    color: var(--accent);
}

.page-explainer-text {
    flex: 1 1 380px;
    text-align: left;
}

.page-explainer-text p {
    margin: 0 0 6px;
    text-align: left;
}

.page-explainer-text p:last-child {
    margin-bottom: 0;
}

.page-explainer-legend {
    flex: 0 1 220px;
    padding-left: 20px;
    border-left: 1px solid var(--border);
}

.page-explainer-legend-title {
    margin: 0 0 8px;
    font-size: 11px;
    font-weight: 800;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--muted2);
}

.page-explainer-legend-grid {
    display: grid;
    grid-template-columns: repeat(2, auto);
    gap: 8px 18px;
}

/* Grid, not flex — the icons here are genuinely different native sizes
   (11px dots, 16px FontAwesome glyphs, 14px zone-grid icon), so packing
   them into a flex row left them left-aligned at different widths, with
   each icon's own center landing at a different X position (the narrower
   11px dot's center sits well left of a 16px icon's center). A fixed
   16px first column, with justify-self:center set on each icon
   individually (NOT justify-items on the container — the label text is a
   bare text node, not a wrapped element, so it can't be targeted by a
   selector to opt back out of centering; leaving the container's own
   alignment alone keeps it left-aligned automatically). */
.page-explainer-legend-item {
    display: inline-grid;
    grid-template-columns: 16px auto;
    align-items: center;
    gap: 6px;
    white-space: nowrap;
}

/* Centers the glyph (rendered via ::before) within the icon's own box —
   different FontAwesome 4.7 glyphs (e.g. solid "circle" icons vs. thinner
   edit/trash outlines) aren't positioned identically within their own font
   metrics, so this centers the box itself rather than relying on that. */
.page-explainer-legend-item i {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    justify-self: center;
    width: 16px;
    height: 16px;
    color: var(--accent);
}

.page-explainer-legend-item i.on-color {
    color: #F44336;
}

.page-explainer-legend-item .power-on,
.page-explainer-legend-item .power-off {
    display: inline-block;
    justify-self: center;
}

/* Shrunk to match the ~16px column every other legend icon sits in — at
   its normal 21px (see .zone-grid-icon), "Add zone" stood out as visibly
   larger than everything around it. */
.page-explainer-legend-item .zone-grid-icon {
    width: 14px;
    height: 14px;
    gap: 2px;
    justify-self: center;
}

.ribbon-center .site0-menu-item {
    margin-bottom: 0 !important;
}

.ribbon-center .ms-parent {
    width: 150px !important;
}

#custom-search-input {
    margin: 0 !important;
}

#custom-search-input .input-group {
    display: inline-flex !important;
    width: auto !important;
    float: none !important;
    position: relative;
}

#custom-search-input #btnClearSearch {
    position: absolute;
    right: 10px;
    top: 50%;
    transform: translateY(-50%);
    color: var(--muted);
    font-size: 14px;
    cursor: pointer;
    z-index: 2;
}

#custom-search-input #btnClearSearch:hover {
    color: var(--text);
}

#custom-search-input .input-group-btn {
    display: inline-flex !important;
    width: auto !important;
}

#custom-search-input #siteSearchTerm {
    width: 280px;
}

#custom-search-input .search-query {
    border-radius: var(--radius-sm);
    border: 1px solid var(--border);
    background: #fff;
    color: var(--text);
    height: 34px;
    transition: border-color .12s ease, box-shadow .12s ease;
}

#custom-search-input .search-query:hover {
    border-color: var(--accentBorder);
}

#custom-search-input .search-query:focus {
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accentSoft);
    outline: none;
}

.ms-parent > .ms-choice {
    border-radius: var(--radius-sm) !important;
    border-color: var(--border) !important;
    background: #fff;
    transition: border-color .12s ease, box-shadow .12s ease;
}

.ms-parent > .ms-choice:hover {
    border-color: var(--accentBorder) !important;
}

.ms-parent:focus-within > .ms-choice {
    border-color: var(--accent) !important;
    box-shadow: 0 0 0 3px var(--accentSoft);
}

/* Dealer picker in the site modal: kept narrow when closed (freeing up
   room on the row for Site Name + Language), but the open list itself is
   wider than that closed box so the dealer names underneath aren't
   cramped — .ms-drop is the plugin's own absolutely-positioned dropdown,
   scoped here via the adjacent-sibling selector to the original (now
   hidden) #sel-dealers <select> so only this one dropdown is affected. */
#sel-dealers + .ms-parent .ms-drop {
    width: 420px !important;
}

/* Stops the open list well short of the modal's own bottom edge instead
   of running (or nearly running) all the way down to it — the option
   list itself scrolls once it hits this height rather than the dropdown
   just growing to fit however many dealers there are. */
#sel-dealers + .ms-parent .ms-drop ul {
    max-height: 240px;
    overflow-y: auto;
}

#sel-region-filter,
#sel-dma-filter,
#sel-lang-filter {
    border-radius: var(--radius-sm) !important;
}

/* The old vertical sidebar (.leftPane / #tabNav / #tabContent / #tabPane-1)
   is now empty — its contents moved into #ribbon-actions and .ribbon-center —
   so it's hidden outright instead of reserving layout space for it. */
.leftPane {
    display: none;
}

/* Scrollbar now lives on .rightPane-scroll (just the site-list area)
   instead of spanning the ribbon too, so .rightPane itself no longer
   scrolls — it's just a fixed-size flex column: ribbon row (auto height)
   + scrollable content row (fills the rest). */
.rightPane {
    top: var(--headerH);
    overflow-y: hidden;
}

.rightPane-inner {
    margin-left: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
}

.rightPane-scroll {
    flex: 1 1 auto;
    overflow-y: auto;
}

/* Data tables presented as cards */
/* No card-level border at all — every side (top/bottom/right) comes from
   each .accordion row instead, so nothing here would double up with it. */
/* TEMP width test — fixes just the list (not the ribbon/header above it,
   which stays full-width) to 1350px, centered, regardless of the actual
   browser width. Remove width/max-width (back to 100%) once done
   checking. */
.dbTable {
    width: 1350px;
    max-width: calc(100% - 48px);
    margin: 18px auto;
    background: var(--panel);
    border-radius: 0;
    overflow: hidden;
}

.tablesorter thead tr {
    background: linear-gradient(180deg, #fff, #f2f4f6);
    color: var(--muted);
    font-weight: 700;
    letter-spacing: .02em;
    border-bottom: 1px solid var(--border);
}

/* Padding + line-height matched to .tablesorter tbody td below, and both
   matched to .accordion > label's own 36px min-height, so site, zone, and
   player rows — header or data — all come out the same height. */
.tablesorter thead th {
    padding: 8px 16px !important;
    line-height: 20px;
    text-align: left;
}

.tablesorter tbody td {
    border-bottom: 1px solid var(--border);
    padding: 8px 16px;
    line-height: 20px;
    font-size: 1em;
    vertical-align: middle;
}

.tablesorter tbody tr:last-child td {
    border-bottom: none;
}

.tablesorter tbody tr:hover {
    background-color: var(--accentSoft) !important;
}

/* No alternating-row shading on zone detail rows specifically (the
   header keeps its own shading above) — the base rule above still
   applies to the player table. !important since the base rule's exact
   specificity/structural assumptions may not be matching as expected. */
.tbNetwork tbody tr:nth-child(even) {
    background-color: transparent !important;
}

/* Buttons */
.btn {
    border-radius: var(--radius-sm);
    font-weight: 700;
    transition: transform .12s ease, box-shadow .12s ease;
}

.btn-modal {
    border-radius: var(--radius-sm);
    width: auto;
    padding: 6px 16px;
    font-size: 14px;
    font-weight: 600;
    line-height: 1.4;
}

.btn-success {
    border-radius: var(--radius-sm);
}

/* Save (the primary action, no data-dismiss) — solid page-accent blue
   instead of Bootstrap's default green .btn-primary, which didn't match
   anything else on the page. */
.modal-footer .btn-primary.btn-modal {
    background: var(--accent);
    border-color: var(--accent);
    color: #fff;
}

.modal-footer .btn-primary.btn-modal:hover {
    background: #1a5490;
    border-color: #1a5490;
    color: #fff;
}

/* Cancel — every modal's dismiss button carries data-dismiss="modal", so
   this reaches it without needing to touch each modal's own markup/class
   list. Comes after the rule above so it wins the tie for buttons that
   (like these) match both selectors. */
.modal-footer .btn-modal[data-dismiss="modal"] {
    background: var(--panel);
    border-color: var(--border);
    color: var(--muted);
}

.modal-footer .btn-modal[data-dismiss="modal"]:hover {
    background: var(--panel2);
    border-color: var(--muted);
    color: var(--text);
    box-shadow: none;
}

/* Destructive-action button (confirm modal's Delete) — solid red instead
   of the page's blue accent, so a destructive confirm doesn't look like
   just another "Save" button. */
.modal-footer .btn-danger.btn-modal {
    background: #dc2626;
    border-color: #dc2626;
    color: #fff;
}

.modal-footer .btn-danger.btn-modal:hover {
    background: #b91c1c;
    border-color: #b91c1c;
    color: #fff;
}

/* Confirm modal is just a short message + 2 buttons — doesn't need the
   wider form-modal widths. */
.confirm-modal-dialog {
    width: 420px;
}

.confirm-modal-message {
    font-size: 14px;
    color: var(--text);
    margin: 4px 0;
}

/* Adopt Players popup — wide enough for its 4-column table, with its own
   scroll region so a long unadopted-players list doesn't stretch the modal
   off-screen. */
.adopt-players-dialog {
    width: 700px;
}

.adopt-players-body {
    max-height: 60vh;
    overflow-y: auto;
}

.adopt-players-search {
    margin: 0 0 10px 0;
}

.adopt-players-search .form-input {
    width: 100%;
}

/* Modals */
/* The top nav (.dd-header, in BlueBarMenu.master) sits at z-index:9999 —
   above Bootstrap 3's default .modal (1050) / .modal-backdrop (1040) — so
   the header was rendering on top of the modal and covering its own
   header/title. Its mega-dropdown panel goes up to 10050, so these clear
   both. */
.modal-backdrop {
    z-index: 10060;
}

.modal {
    z-index: 10070;
}

/* Bootstrap 3 has no built-in vertical centering (.modal-dialog just gets
   margin:30px auto, i.e. anchored near the top) — this is the standard
   BS3 vertical-center technique: a full-height inline-block spacer
   (:before) that vertical-align:middle lines up against, with the dialog
   itself set to do the same, rather than fighting the JS-toggled
   display:block with a forced flex layout. */
.modal {
    text-align: center;
}

.modal::before {
    content: '';
    display: inline-block;
    height: 100%;
    vertical-align: middle;
    margin-right: -4px;
}

.modal-dialog {
    display: inline-block;
    text-align: left;
    vertical-align: middle;
}

.modal-content {
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: 0 22px 50px rgba(15,23,42,.18);
    /* No longer overflow:hidden — that clipped any open dropdown (Site,
       Zone, Brand's multipleSelect panel, etc.) that needed to extend past
       the modal's own box, which happened easily on a short form (e.g. an
       unadopted player, before Brand/Language even render — see
       .unadopted-items). The header/footer's own rounded corners below
       (previously relying on this clipping the parent's square corners)
       now carry their own matching border-radius instead. */
    color: var(--text);
}

.modal-header {
    border-radius: var(--radius) var(--radius) 0 0;
}

/* Flat var(--accent) instead of the old gradient down to a separate dark
   navy (#123a63) — same blue used for buttons/focus rings/accents
   elsewhere on the page, so it reads as "this page's blue" rather than a
   custom one-off; padding trimmed down from the original 50px-tall header. */
.modal-header.mam-header {
    background: var(--accent);
    border-bottom: 0;
    color: #fff;
    padding: 8px 16px;
    height: auto;
}

.modal-title-text {
    float: left;
    font-size: 1.05em;
    font-weight: 700;
    color: #fff;
    line-height: 1.6;
}

.modal-header.mam-header .close {
    color: #fff;
    opacity: .85;
    text-shadow: none;
}

.modal-header.mam-header .close:hover {
    color: #fff;
    opacity: 1;
}

/* Shared field wrapper for every prompt in a modal form (text input,
   plain/multipleSelect dropdown, or chip picker) — a single "label above,
   field below" pattern so every field reads the same way, instead of some
   labels floating inside the field's own border and others sitting as
   plain text above it. */
.form-field {
    display: inline-block;
    vertical-align: top;
    margin: 0 14px 10px 0;
    text-align: left;
}

.form-label {
    display: block;
    color: var(--muted);
    font-size: 12px;
    font-weight: 700;
    text-transform: uppercase;
    letter-spacing: .03em;
    margin-bottom: 4px;
}

.form-input {
    display: block;
    width: 260px;
    padding: 8px 12px;
    font-size: 14px;
    border: 1px solid var(--border);
    border-radius: var(--radius-sm);
    background: var(--panel);
    color: var(--text);
    transition: border-color .12s ease, box-shadow .12s ease;
}

.form-input:focus {
    outline: none;
    border-color: var(--accent);
    box-shadow: 0 0 0 3px var(--accentSoft);
}

.form-input:disabled {
    background: var(--panel2);
    color: var(--muted);
    cursor: not-allowed;
}

/* Explains the brand picker's muted-vs-full-color contrast now that
   there's no ring/badge also marking a selected brand. */
/* Sits inline next to its .form-label now (in a .form-label-row), not
   below the picker it describes. */
.form-label-row {
    display: flex;
    align-items: baseline;
    gap: 8px;
    margin-bottom: 6px;
}

.form-label-row .form-label {
    margin-bottom: 0;
}

.form-hint {
    font-size: 12px;
    font-style: italic;
    color: var(--muted);
}

.form-input-sm {
    width: 130px;
}

/* For a .form-input sitting alone in a .form-field-full row — content.aspx's
   content modal uses this for Display Name/Add URL, which read oddly at
   the default fixed 260px once the rest of that modal switched to this
   same form-field/form-label system (they'd previously used a completely
   different floating-label .inputGroup pattern instead, which read as
   inconsistent with everything else once just those two fields kept it). */
.form-input-full {
    width: 100%;
}

/* Hardware ID — never more than 16 chars, so it doesn't need anywhere
   near as much room as a name/description field. */
.form-input-xs {
    width: 110px;
}

.form-field-full {
    display: block;
    margin-right: 0;
}

/* Chip pickers — brands (icon-based) and language (text-pill based) both
   use the same underlying pattern: muted/unselected by default, full
   color once picked, instead of a <select multiple> dropdown that hides
   everything behind a click. */
.chip-picker {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px;
    max-width: 460px;
}

/* Language specifically — only 2 chips, they should never stack even if
   the field ends up squeezed for space on a crowded row. */
#langPicker1 {
    flex-wrap: nowrap;
}

/* Brands specifically stay on one line — up to 12 icons, wrapping them
   would defeat the point of a compact, at-a-glance picker. */
.chip-picker-nowrap {
    flex-wrap: nowrap;
    max-width: none;
    overflow-x: auto;
}

.chip {
    position: relative;
    cursor: pointer;
    transition: filter .15s ease, opacity .15s ease, border-color .15s ease,
        background .15s ease, color .15s ease, box-shadow .15s ease;
}

/* display:inline-flex centers the nested 24px .brand-icon-* span inside
   this 32px box — those spans are float:left/margin:0 3px by default (for
   flowing several in a row elsewhere on the page), which would otherwise
   leave it offset rather than centered in an isolated single-icon chip. */
.chip-brand {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 32px;
    height: 32px;
    flex-shrink: 0;
    filter: grayscale(1);
    opacity: .35;
    border-radius: 6px;
}

/* Moved to ddnv26/css/brand-icons.css alongside the rest of the
   brand-icon-* rules it depends on (that version also sets a 28px
   size + 108% background-size this file's copy never had - reconciled
   there rather than carrying two different versions forward). */

.chip-brand:hover {
    opacity: .7;
}

.chip-brand.selected {
    filter: none;
    opacity: 1;
}

/* Tiny top-left badge — small enough to not fight the brand's own logo,
   just a quiet secondary confirmation alongside the muted/full-color
   contrast (see .form-hint) rather than a prominent indicator on its own. */
.chip-check {
    display: none;
    position: absolute;
    top: -5px;
    left: -5px;
    font-size: 14px;
    color: #16a34a;
    text-shadow: 0 0 2px var(--panel), 0 0 2px var(--panel);
}

.chip.selected .chip-check {
    display: block;
}

/* Pill-style chip — used for language, where there's no icon to mute/
   desaturate, so the muted/selected states are conveyed through the
   pill's own border/background/text color instead. */
.chip-lang {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 7px 14px;
    border: 1px solid var(--border);
    border-radius: 999px;
    background: var(--panel2);
    color: var(--muted);
    font-weight: 600;
    font-size: 13px;
}

.chip-lang:hover {
    border-color: var(--accentBorder);
}

.chip-lang.selected {
    border-color: var(--accent);
    background: var(--accentSoft);
    color: var(--accent);
}

.chip-lang .chip-check-inline {
    display: none;
    font-size: 12px;
}

.chip-lang.selected .chip-check-inline {
    display: inline;
}

.modal-footer {
    background: var(--panel2);
    border-top: 1px solid var(--border);
    padding: 10px 20px;
    /* Matches .modal-content's own corners now that it no longer clips its
       children via overflow:hidden (see .modal-content's comment) — without
       this, the footer's own square corners would show past the outer
       rounded ones. */
    border-radius: 0 0 var(--radius) var(--radius);
}

/* Site modal's content doesn't need the full modal-lg width (900px) — the
   widest row (Dealer + Site Name + Language) comes in well under that,
   which was leaving a large empty gap on the right. */
#siteModal .modal-dialog {
    width: 850px;
}

#zoneModal .modal-dialog {
    width: 700px;
}

#playerModal .modal-dialog {
    width: 850px;
    transition: width .15s ease;
}

/* Widens the modal to fit the Kiosk side panel instead of the modal
   just getting taller — toggled in JS (updateKioskSettingsVisibility())
   alongside #kioskSettings itself, both driven by Device Type. */
#playerModal.kiosk-open .modal-dialog {
    width: 1180px;
}

.player-modal-columns {
    display: flex;
    align-items: flex-start;
    justify-content: center;
}

/* .edit-block's own margin:auto (its usual self-centering trick when it's
   the only thing in the modal body) fights justify-content here once it's
   a flex item alongside .kiosk-panel — overridden so centering is purely
   the flex container's job (single item when the panel's hidden, two
   items side by side when it's shown). */
.player-modal-columns > .edit-block {
    margin: 0 !important;
}

/* Kiosk Settings pops out as a second column instead of stacking below
   the (already tall) rest of the form. Fixed width rather than flexing —
   this panel's own content (a couple of selects/switches) never needs
   more room than that, so letting it grow would just leave it looking
   sparse against the main column's denser layout. */
.kiosk-panel {
    flex: 0 0 260px;
    margin-left: 24px;
    padding-left: 24px;
    border-left: 1px solid var(--border);
}

/* "From Zone" toggle next to the Brands label — wraps the checkbox
   directly (rather than a for/id-matched separate <label>, which the old
   markup had slightly wrong anyway) so clicking the text also toggles it. */
.form-checkbox-inline {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    margin-left: auto;
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
    cursor: pointer;
}

.form-checkbox-inline input[type="checkbox"] {
    accent-color: var(--accent);
    cursor: pointer;
}

/* Locks (not dims) the brand chip picker while "From Zone" is checked —
   every rendered chip is already selected at that point (player.brands
   was set to exactly the zone's own brand list), so they should read as
   clearly, fully "on" rather than faded/greyed like a typical disabled
   control would. Scoped to .chip specifically (not the whole container)
   so the "From Zone" toggle itself — now rendered as this picker's own
   first item, see renderPlayerBrandPicker() — stays clickable to turn
   locking back off; a container-wide pointer-events:none would trap it
   too. */
.chip-picker-disabled .chip {
    pointer-events: none;
}

/* Selected brands still read as "on" while locked to the zone's own set
   (From Zone enabled), but a notch duller than the normal full-color
   selected look — so it's visually clear these came from the zone, not a
   direct pick, without going all the way back to the unselected/grayscale
   look (.chip-brand's own base opacity: .35 + grayscale(1)). */
.chip-picker-disabled .chip-brand.selected {
    opacity: .7;
    filter: grayscale(.35);
}

/* VOD/4K toggle rows — label + switch side by side within their own
   .form-field, replacing the old ad hoc inline-flex + hardcoded colors. */
.form-switch-row {
    display: flex;
    align-items: center;
    gap: 14px;
}

.form-switch-row .form-label {
    margin-bottom: 0;
}

/* Clockpicker's popover is a Bootstrap .popover (default z-index:1060) —
   well below the modal's own boosted z-index:10070 (see .modal above), so
   it was rendering behind the modal instead of on top of it. */
.clockpicker-popover {
    z-index: 10080 !important;
}

/* Clockpicker's own input-group — border/radius matched to the rest of
   the page's inputs instead of the old hardcoded #CCC border, without
   reusing .form-input directly (its display:block/fixed-width assumptions
   don't fit an input-group-with-addon layout). */
.form-time-input {
    width: 140px;
}

.form-time-input .form-control {
    border: 1px solid var(--border) !important;
    border-radius: var(--radius-sm) 0 0 var(--radius-sm) !important;
    box-shadow: none !important;
}

.form-time-input:focus-within .form-control {
    border-color: var(--accent) !important;
}

.form-time-input .input-group-addon {
    border: 1px solid var(--border);
    border-left: 0;
    border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
    background: var(--panel2);
    color: var(--muted);
}

/* "(24h)" next to Player On/Off Time — the clockpicker widget already
   defaults to 24-hour mode (twelvehour:false), but nothing in the UI
   itself said so, risking "07:00" being misread as either 7am or 7pm. */
.form-label-hint {
    text-transform: none;
    font-weight: 400;
    color: var(--muted);
}


/* No-subscriber board — shown instead of the site list when the dealer has
   no sites set up at all (see renderSiteView() in dashboard.js, which also
   hides .page-explainer in this state — there's nothing to explain yet). */
div.noSiteBoard {
    display: none;
    /* Same "roughly 75% of viewport, capped" sizing as .page-explainer. */
    max-width: min(75vw, 1400px);
    margin: 60px auto;
    padding: 0;
    background: var(--panel);
    border: 1px solid var(--border);
    border-radius: var(--radius);
    box-shadow: var(--shadow);
    /* Clips .noSiteBoard-media's square edge to the card's own rounded
       corner instead of needing its own radius logic. */
    overflow: hidden;
}

/* Image (left) + everything else (right) — a plain two-column split, wraps
   to stacked (image on top) on narrow widths since this card can now get
   quite wide. */
.noSiteBoard-layout {
    display: flex;
    flex-wrap: wrap;
    align-items: stretch;
}

/* No explicit height: an align-items:stretch flex item matches the row's
   tallest sibling (.noSiteBoard-content) automatically, and the <img>'s own
   height:100% + object-fit:cover fills whatever that turns out to be. */
.noSiteBoard-media {
    flex: 1 1 320px;
    max-width: 420px;
}

.noSiteBoard-hero {
    display: block;
    width: 100%;
    height: 100%;
    min-height: 320px;
    object-fit: cover;
}

.noSiteBoard-content {
    flex: 2 1 420px;
    padding: 36px 40px;
    text-align: left;
}

.noSiteBoard-header {
    display: flex;
    align-items: center;
    gap: 12px;
    margin-bottom: 14px;
}

/* Hand-built TV shape (frame + screen + stand) rather than the fa-television
   glyph — a font-icon is one solid color, so there's no way to recolor just
   its screen area red while keeping the frame a different color. Same
   building-block approach as .zone-grid-icon elsewhere on this page. */
.noSiteBoard-icon {
    display: block;
    flex: 0 0 auto;
    width: 34px;
}

.noSiteBoard-icon-frame {
    display: flex;
    align-items: center;
    justify-content: center;
    width: 34px;
    height: 24px;
    background: var(--accent);
    border-radius: 4px;
}

/* The "screen" — solid red with a white ! so it reads as an on-screen
   alert/broadcast graphic rather than a caution sticker on the frame. */
.noSiteBoard-icon-screen {
    box-sizing: border-box;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 26px;
    height: 17px;
    background: #ef292a;
    /* Keeps the red from anti-aliasing directly against the blue frame,
       which read as a purple fringe without it. */
    border: 2px solid #fff;
    border-radius: 3px;
    color: #fff;
    font-weight: 900;
    font-size: 12px;
    line-height: 1;
}

.noSiteBoard-icon-stand {
    display: block;
    width: 12px;
    height: 4px;
    margin: 2px auto 0;
    background: var(--accent);
    border-radius: 0 0 2px 2px;
}

.noSiteBoard-title {
    font-size: 1.3em;
    font-weight: 700;
    color: var(--text);
}

.noSiteBoard-body {
    text-align: left;
    color: var(--muted);
    font-size: 14px;
    line-height: 1.6;
    /* .rightPane-inner sets word-break:break-all (needed elsewhere for long
       unbroken strings) which was cutting ordinary words mid-word here —
       same fix as .page-explainer. */
    word-break: normal;
    overflow-wrap: break-word;
}

.noSiteBoard-body p {
    margin: 0 0 10px;
}

.noSiteBoard-body p:last-child {
    margin-bottom: 0;
}

.noSiteBoard-body ul {
    margin: 0 0 10px;
    padding-left: 20px;
}

.noSiteBoard-body li {
    margin-bottom: 6px;
}

.noSiteBoard-body li:last-child {
    margin-bottom: 0;
}

.noSiteBoard-actions {
    display: flex;
    justify-content: flex-start;
    flex-wrap: wrap;
    gap: 10px;
    margin-top: 24px;
}

/* Same pill look as #ribbon-actions ul li a, for a consistent "action
   button" style across the page. */
.noSiteBoard-btn {
    display: inline-flex;
    align-items: center;
    gap: 8px;
    /* Was var(--radius-sm) - matches #ribbon-actions ul li a's own switch
       to the shared var(--radius-btn) "slight rounding" token. */
    border-radius: var(--radius-btn);
    color: var(--accent);
    font-size: 13px;
    font-weight: 700;
    padding: 10px 16px;
    background: #dce8f4;
    border: 1px solid var(--accent);
    text-decoration: none;
    transition: background .12s ease, color .12s ease;
}

.noSiteBoard-btn:hover {
    background: #c7dcef;
    color: var(--accent);
}

/* Sits below the actions, inside the same content column (was briefly a
   right-hand sidebar next to the pitch — folded back into one column now
   that the image took the other side). */
.noSiteBoard-brands {
    margin-top: 28px;
    padding-top: 22px;
    border-top: 1px solid var(--border);
}

.noSiteBoard-brands-title {
    font-size: 11px;
    font-weight: 700;
    letter-spacing: .04em;
    text-transform: uppercase;
    color: var(--muted2);
    margin-bottom: 14px;
}

.noSiteBoard-brands-grid {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: 10px 18px;
}

.noSiteBoard-brand-item {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    font-size: 12px;
    font-weight: 600;
    color: var(--muted);
}

/* .brand-icon-* are shared with the site-row brand chips (float:left,
   margin:0 3px, sized for that inline-list context) — reset to sit inline
   with this label instead, and shrunk slightly to read as a small badge
   rather than a full brand logo. */
.noSiteBoard-brand-item [class^="brand-icon-"] {
    float: none;
    margin: 0;
    width: 22px;
    height: 22px;
}

/* Site list rows (accordion) */
.accordion {
    border-top: 2px solid var(--border);
    border-right: 2px solid var(--border);
    border-bottom: 2px solid var(--border);
    border-radius: var(--radius);
    margin-bottom: 6px;
    transition: background .12s ease;
}

/* When expanded, the accordion's own border-bottom spans the full width
   including the zone table's left indent gap (which has no border of its
   own there), showing up as an isolated stray segment. The zone table
   gets its own bottom edge instead (below), so this one is suppressed
   only while expanded. */
.accordion:has(> input:checked) {
    border-bottom: none;
}

.accordion:hover {
    background: var(--panel2);
}

/* .accordion:hover's tint applies to the whole accordion box, including
   the zone table's left indent gap — resetting it here whenever the
   mouse is anywhere over the expanded zone content stops that tint from
   showing in the gap, leaving only the zone row's own hover highlight
   (below) visible. */
.accordion:hover .acc-content {
    background: var(--panel);
}

.accordion > label {
    padding: 0 24px 0 12px;
    gap: 4px;
    color: var(--text);
    border-bottom: 0 !important;
    border-left: 2px solid var(--border);
    /* The label has its own border-left with no radius of its own, so its
       corners are hard-square regardless of the parent .accordion's own
       rounding — invisible normally, but obvious once the label gets its
       own background fill (accentSoft, when checked/expanded). Rounding
       only the left corners here, matching the parent, fixes that. */
    border-radius: var(--radius) 0 0 var(--radius);
    line-height: normal;
    /* Was 48px — 16px taller than the 32px brand-icon badges (the tallest
       content), leaving empty space below them (centered via align-items)
       before the next row/zone-table starts, which read as an unwanted
       gap in both the collapsed (next site row) and expanded (zone
       header) cases alike, since it's the same box regardless of what
       follows it. */
    min-height: 36px;
    width: 100%;
    /* Bootstrap's base `label` rule (loaded on this page) sets
       margin-bottom: 5px by default; margin-left:0 alone never
       overrode that, so it was still creating a real 5px gap below
       every site row's label — the actual cause of the "gap" reported,
       not padding/min-height (which affect the box's own height, not
       the margin outside it). */
    margin: 0;
    box-sizing: border-box;
}

.accordion > input:checked ~ label {
    border-bottom: 0 !important;
    background: var(--accentSoft);
}

/* Action icons live inside .row-actions now (moved to the far side of the
   brand-icon badges), not as direct children of <label> — see dashboard.js.
   margin-right clears the absolutely-positioned "+"/expand toggle (right:16px,
   26px wide — reaches 42px from the label's padding edge; the label's own
   24px right padding covers the rest, so 20px more here matches the ~54px
   total clearance used elsewhere for this same toggle). */
/* margin-left:auto now does the right-alignment work itself — it used to
   ride along after .site-stats's own auto-margin, but that element is
   absolutely positioned now (out of flow), so this can no longer piggyback
   on it. */
/* gap dropped — each icon now sits in its own fixed-width .action-slot
   (see below), which is what keeps Content/Edit/Delete lined up with the
   equivalent icons at the zone and player levels; an extra gap on top of
   that would throw the alignment off. */
.accordion > label .row-actions {
    display: inline-flex;
    align-items: center;
    margin-left: auto;
    margin-right: 20px;
    padding-left: 10px;
    border-left: 1px solid var(--border);
}

/* Shared fixed-width slot for every level's action icons (site, zone,
   player) — same slot order everywhere (VOD, Create Zone, Content, Edit,
   Delete), left empty when a level has no equivalent action, so Content
   and Edit (present at all 3 levels) always land at the same slot index
   and therefore the same position, regardless of what's actually filled
   in around them. */
.action-slot {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    flex-shrink: 0;
}

/* The pencil glyph in FontAwesome's fa-edit sits slightly toward the top
   of its own em-box compared to the other action icons (film, trash,
   chevron, etc), so it still reads as "too high" even once the line-box
   itself is centered — nudged down a couple px to visually match. */
.action-slot .fa-edit {
    position: relative;
    top: 2px;
}

/* "Create Zone" — a custom 2x2 grid built from 4 plain cells rather than
   FontAwesome's fa-th-large, with one cell replaced by a hand-drawn plus
   instead of a solid square. A badge overlaid on top of the font glyph
   (tried first) never looked right at any size small enough not to
   swallow the icon — this way the "+" genuinely lives inside one of the
   grid's own 4 windows, sized in real pixels instead of fighting glyph
   metrics at a tiny point size. */
.zone-grid-icon {
    display: inline-grid;
    grid-template-columns: 1fr 1fr;
    grid-template-rows: 1fr 1fr;
    gap: 3px;
    width: 21px;
    height: 21px;
    cursor: pointer;
    vertical-align: middle;
    color: var(--accent);
    transition: color .12s ease;
}

.zone-grid-icon:hover {
    color: #01467D;
}

.zone-grid-cell {
    background: currentColor;
    border-radius: 2px;
}

.zone-grid-cell-plus {
    position: relative;
    background: transparent;
}

.zone-grid-cell-plus::before,
.zone-grid-cell-plus::after {
    content: '';
    position: absolute;
    background: currentColor;
    border-radius: 1px;
}

.zone-grid-cell-plus::before {
    top: 50%;
    left: 0;
    width: 100%;
    height: 2px;
    transform: translateY(-50%);
}

.zone-grid-cell-plus::after {
    left: 50%;
    top: 0;
    height: 100%;
    width: 2px;
    transform: translateX(-50%);
}

/* Zone/player action cells get the same total right-hand clearance as the
   site row's .row-actions (20px margin + 24px label padding = 44px),
   instead of the plain 16px cell padding every other column uses — so the
   right-aligned VOD/Create Zone/Content/Edit slots here land at the exact
   same x-position as the site's own 4 slots. position:relative gives
   .zone-delete-action (below) something to anchor to. */
.tbNetwork td.actions-cell,
.player-nested-table td.actions-cell {
    position: relative;
    text-align: right;
    padding-right: 44px;
}

/* Zone's Delete sits outside the slot flow entirely, pinned at the exact
   same right:16px offset as the site row's own expand/collapse chevron
   (.accordion > label::after) — since .actions-cell is the table's last
   column, its border-box right edge is the same shared right edge the
   chevron measures from (see the .site-stats comment above), so the same
   16px offset lands Delete directly under the chevron instead of needing
   its own reserved slot width. */
.zone-delete-action {
    position: absolute;
    right: 16px;
    top: 50%;
    transform: translateY(-50%);
}

/* Matches the zone row's own action icons (.tbNetwork td > i) — that rule
   uses 1.5em against the table's own explicit 14px base (= 21px), but the
   label's ambient font-size isn't the same 14px, so matching with 1.5em
   here produced visibly different sizes; using the same resolved 21px
   directly avoids depending on the two contexts sharing a base size. */
.accordion > label .row-actions i {
    font-size: 21px;
    margin: 0 !important;
    color: var(--accent);
    cursor: pointer;
    transition: color .12s ease;
}

.accordion > label .row-actions i:hover {
    color: #01467D;
}

/* Permission-gated actions (edit/delete/etc.) are always rendered now
   instead of being omitted — shown greyed-out and inert instead, so the
   option stays visible/discoverable but can't be triggered. !important
   since these icons otherwise pick up various context-specific colors
   (row-actions, .tbNetwork/.tbPlayer td > i, etc.). */
.icon-disabled {
    color: #ccc !important;
    cursor: default !important;
    pointer-events: none;
}

.icon-disabled:hover {
    color: #ccc !important;
}

.accordion > label .row-actions img {
    border-radius: 6px;
    cursor: pointer;
}

.accordion > label > span:not(.badge):not(.row-actions):not(.site-stats) {
    color: var(--accent);
    font-weight: 800;
    font-size: 14px;
}

/* Shared "screens" stat cluster — used both in the site row header (in
   place of the old single-count .badge pill) and in the zone table's
   consolidated Screens column. */
.site-stats {
    display: inline-flex;
    align-items: center;
    gap: 20px;
    font-size: 12px;
    font-weight: 700;
    color: var(--muted);
    white-space: nowrap;
}

/* Fixed widths (rather than shrink-to-content) so each sub-column — Total,
   Online, Up-to-date — starts at the same x-offset regardless of its own
   digit count, and lines up between the site row and the zone table's
   Screens column (both share this same markup/classes). Content still
   left-aligns naturally within its own fixed box. */
.site-stats .site-stat {
    position: relative;
    display: inline-flex;
    align-items: center;
    gap: 6px;
    flex: 0 0 auto;
}

.site-stats .site-stat:nth-child(1) {
    width: 46px;
}

.site-stats .site-stat:nth-child(2) {
    width: 88px;
}

.site-stats .site-stat:nth-child(3) {
    width: 96px;
}

/* Pipe divider between metrics, matching the "Total | Online | Up-to-Date"
   wording now used in the column header — an absolutely-positioned
   pseudo-element sitting in the middle of the preceding 20px gap, rather
   than real content, so it doesn't add to (and throw off) the fixed
   sub-column widths above. */
.site-stats .site-stat:not(:first-child)::before {
    content: '|';
    position: absolute;
    left: -13px;
    color: var(--border);
    font-weight: 400;
}

.site-stats .site-stat i {
    font-size: 13px;
    color: var(--muted2);
}

.site-stats .site-stat .power-on,
.site-stats .site-stat .power-off {
    width: 8px;
    height: 8px;
    box-shadow: none;
}

.site-stats .site-stat .power-off-red {
    background: #ef292a;
}

/* Unscoped (not just .site-stats) — also used for the per-player
   content-up-to-date column and the page-explainer legend, neither of
   which sit inside .site-stats. */
i.stat-good {
    color: #16a34a;
}

i.stat-bad {
    color: #ef292a;
}

/* .site-stats .site-stat i (above) sets a muted gray for icons in that
   specific context and outranks the general rule above on specificity —
   these re-assert red/green there specifically, for the roll-up view's own
   Up-to-date/Not-Updated counts. */
.site-stats .site-stat i.stat-good {
    color: #16a34a;
}

.site-stats .site-stat i.stat-bad {
    color: #ef292a;
}

/* Pinned to the same x-offset as the zone table's Screens column content
   (24px table indent + 250px Name + 75px Lang + 400px Brands + 16px cell
   padding = 765px from the accordion's own edge) so the two align, instead
   of flowing after the (variable-length) site name + brand icons via
   margin-left:auto. Tradeoff: a long site name or a lot of brand icons can
   run underneath/into this, since it's no longer part of the flex flow
   that used to make room for it. The label itself (not .accordion) is the
   nearest positioned ancestor here, and absolute offsets are relative to
   its padding edge, i.e. inside its own 2px border-left — hence 763px, not
   765px, to land at the same true 765px from the accordion's edge. */
.accordion > label .site-stats {
    position: absolute;
    left: 763px;
    top: 50%;
    transform: translateY(-50%);
}

/* Kept absolutely positioned (like the original) rather than a flex
   auto-margin, since .badge only renders for some rows — an auto-margin
   on it would leave the "+" toggle inconsistently placed on the rest. */
.accordion > label > span.badge {
    right: 54px;
    top: 50%;
    transform: translateY(-50%);
    background: var(--accent);
    border-radius: 999px;
    padding: 3px 10px;
    font-weight: 700;
    font-size: 12px;
}

/* FontAwesome chevron instead of a "+" rotated 45° to fake an "×" — flips
   180° on expand (pointing up) rather than swapping glyphs, and drops the
   circular badge/border in favor of the same flat, plain-colored icon
   style used for row-actions (.tbNetwork td > i) elsewhere. */
.accordion > label::after {
    font-family: FontAwesome;
    right: 16px;
    top: 50%;
    transform: translateY(-50%);
    width: 20px;
    height: 20px;
    line-height: 20px;
    font-size: 16px;
    text-align: center;
    color: var(--accent);
}

.accordion > label:hover::after {
    color: #01467D;
}

/* The base rule above centers ::after with translateY(-50%); the checked-
   state rule sets its own transform with higher specificity, which would
   otherwise replace (not add to) that translateY and knock the icon
   off-center when a row is expanded. */
.accordion > input[type=checkbox]:checked + label::after {
    transform: translateY(-50%) rotate(180deg);
}

.accordion > hr {
    display: none !important;
}

