/**
NOTE: Removed all overflow: scroll settings as in April 2023 it started
messing up the layout with white borders and scoll bars
**/

/** Clean-up with Cursor on June 17, 2026 **/

/* Core brand palette - the colors repeated 3+ times across the file.
   Introduced during a CSS audit pass; deliberately doesn't try to
   name every one-off gray/black/shadow value, just the recurring
   site-identity blues (+ one pink accent) that were previously
   hand-typed the same way in many places. */
:root {
  /* Breathing room above a card set review's details block. Shared so
     the live site and the CMS preview can't drift apart on it. */
  --set-details-top-pad: 24px;
  --color-link: #3FA7D6;
  --color-text-dark: rgb(11, 62, 100);
  --color-heading-outline: rgb(2, 70, 153);
  --color-masthead-bg: rgb(44, 82, 137);
  --color-image-border: rgb(22, 86, 138);
  --color-input-border: rgb(85, 174, 233);
  --color-accent-hover: #e551f5;
  --color-page-bg: rgb(229, 239, 245);
  /* Buttons - see the shared "Buttons" block near the checklist modal */
  --btn-radius: 10px;
  --btn-secondary-border: #d6d6d6;
  --btn-secondary-hover: #f2f2f2;
}

/* Set up the flex container */
.flex-container {
    display: flex;
    justify-content: center;
    
  }
  
  .flex-container div {
    width: 1000px;
    padding: 15px;  
   /** overflow: scroll; **/
    margin: 5px; 
  }

  a:link, a:visited {
    color: var(--color-link);
}

h1 {
  font-size: 2.5rem;
  line-height: 1.1;
}

/********************** Autobus SMS Styles *************************/

/* ============================
   BASE SHARED STYLES
   ============================ */

.autobus-results-table,
.autobus-textarea,
.autobus-send-btn {
    font-family: "Work Sans", sans-serif;
}

.autobus-sent-message-title {
    font-family: "Work Sans", sans-serif;
    display: block;
    background: none;
    padding: 0;
    margin: 0 0 6px 0;
    font-size: 15px;
    font-weight: 600;
    color: #000;
}

/* Had no rule at all previously, so it fell back to the browser's
   default serif font instead of matching the rest of the page */
.autobus-sent-message {
    font-family: "Work Sans", sans-serif;
    display: block;
    font-size: 16px;
    color: #000;
}

/* Shared table layout width */
.autobus-form,
.autobus-results {
    width: 100%;
    box-sizing: border-box;
    max-width: 700px;
    margin-left: 20px;
    padding-left: 0; /* override the generic `form { padding-left: 1.5% }`
      rule below, which was pushing .autobus-form past its container */
}

/* ============================
   RESULTS TABLE
   ============================ */

.autobus-results-table {
    margin-left: 0;   /* ensures perfect alignment with form */
    width: 100%;
    border-collapse: collapse;
    background: #ffffff;
    border: 1px solid #ddd;
    font-size: 16px;
    margin-top: 20px;
}

.autobus-results-table thead th {
    background: #f4f4f4;
    padding: 10px;
    border-bottom: 2px solid #ccc;
    text-align: left;
    font-weight: 700;
}

.autobus-results-table tbody td {
    padding: 8px 10px;
    border-bottom: 1px solid #eee;
}

.autobus-results-table tbody tr:nth-child(even) {
    background: #fafafa;
}

.autobus-summary-row {
    background: #f0f8ff;
    font-weight: bold;
    text-align: center;
    border-top: 2px solid #ccc;
}

/* ============================
   FORM (LEFT ALIGNED)
   ============================ */

.autobus-form {
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.autobus-textarea {
    width: 100%;
    box-sizing: border-box;
    padding: 14px;
    font-size: 16px;
    border: 1px solid #ccc;
    border-radius: 6px;
    resize: vertical;
}

/* ============================
   SEND BUTTON
   ============================ */

.autobus-send-btn {
    display: block;
    margin: 20px auto 0 auto;
    background-color: #256386;
    color: #fff;
}

.autobus-send-btn:active {
    transform: scale(0.97);
}

/* ============================
   RESULTS SECTION ALIGNMENT
   ============================ */

.autobus-results {
    margin-top: 30px;
}

/* ============================
   TWO COLUMN LAYOUT SECTION 
   ============================ */
.autobus-two-col {
    display: flex;
    gap: 40px;
    align-items: flex-start;
    margin-top: 20px;
}

.autobus-left {
    flex: 1;
    padding-top: 35px;
}

.autobus-right {
    flex: 1;
}

.autobus-results-label {
    font-family: "Work Sans", sans-serif;
    display: block;
    /* font-weight: 600; */
    margin-bottom: 6px;
    color: #000;
}

/* Standardize on the textarea's 16px (autobus-left label was inheriting
   20px from the generic `form { font-size: 20px }` rule) */
.autobus-left label,
.autobus-results-label {
    margin-top: 0;
    font-size: 16px;
}

/* Progress Spinner */
#autobus-spinner-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.75);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 9999;
}

.autobus-spinner {
    width: 60px;
    height: 60px;
    border: 6px solid #ccc;
    border-top-color: #333;
    border-radius: 50%;
    animation: autobus-spin 0.8s linear infinite;
}

@keyframes autobus-spin {
    to { transform: rotate(360deg); }
}

/* Progress Spinner - Player Search - same look/pattern as the Autobus
   spinner above (including reusing its autobus-spin keyframe, which
   has nothing Autobus-specific in it - just a rotation), just under
   playerSearch-specific names since this page has nothing to do with
   the Autobus SMS tool. */
#player-search-spinner-overlay {
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.75);
    display: none;
    align-items: center;
    justify-content: center;
    z-index: 9999;
}

.player-search-spinner {
    width: 60px;
    height: 60px;
    border: 6px solid #ccc;
    border-top-color: #333;
    border-radius: 50%;
    animation: autobus-spin 0.8s linear infinite;
}

/* --- Overlay --- */
.bulk-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* --- Modal container --- */
.bulk-modal {
  background: #fff;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 32px 36px;
  width: 480px;
  max-width: 92vw;
  box-shadow: 0 8px 32px rgba(0,0,0,0.18);
  font-family: 'Source Sans 3', sans-serif;
}

.bulk-modal-title {
  font-family: 'Work Sans', sans-serif;
  font-weight: 700;
  font-size: 1.2rem;
  margin: 0 0 12px 0;
  color: #222;
}

.bulk-modal-instructions {
  font-size: 0.9rem;
  color: #555;
  margin: 0 0 20px 0;
  line-height: 1.5;
}

.bulk-modal-instructions code {
  background: #f4f4f4;
  padding: 1px 5px;
  border-radius: 3px;
  font-size: 0.85rem;
}

/* --- Drop zone --- */
.bulk-drop-zone {
  border: 2px dashed #aaa;
  border-radius: 4px;
  padding: 28px 20px;
  text-align: center;
  font-size: 0.9rem;
  color: #666;
  cursor: pointer;
  transition: border-color 0.2s, background 0.2s;
}

.bulk-drop-zone.drag-over {
  border-color: #555;
  background: #f9f9f9;
}

.bulk-file-label {
  color: #333;
  text-decoration: underline;
  cursor: pointer;
  font-weight: 600;
}

.bulk-file-name {
  margin: 8px 0 0 0;
  font-size: 0.85rem;
  color: #333;
  font-weight: 600;
}

/* --- Feedback --- */
.bulk-feedback {
  margin-top: 16px;
  padding: 10px 14px;
  border-radius: 4px;
  font-size: 0.9rem;
  line-height: 1.5;
}

.bulk-feedback.success {
  background: #edfaed;
  border: 1px solid #7cc47c;
  color: #2a6b2a;
}

.bulk-feedback.error {
  background: #fdecea;
  border: 1px solid #e08080;
  color: #8b1a1a;
}

/* --- Buttons --- */
.bulk-modal-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 24px;
}

.bulk-btn {
  font-family: 'Work Sans', sans-serif;
}

.bulk-btn-upload {
  background: #256386;
  color: #fff;
}

/* User Guide Modal */
/* --- Help modal container --- */
.help-modal {
  background: #fff;
  border: 1px solid #ccc;
  border-radius: 4px;
  padding: 32px 36px;
  width: 620px;
  max-width: 92vw;
  max-height: 85vh;
  overflow-y: auto;
  box-shadow: 0 8px 32px rgba(0,0,0,0.18);
  font-family: 'Source Sans 3', sans-serif;
}

/* --- Help content --- */
.help-content {
  font-size: 0.9rem;
  color: #444;
  line-height: 1.6;
}

.help-section-title {
  font-family: 'Work Sans', sans-serif;
  font-weight: 700;
  font-size: 0.95rem;
  color: #222;
  margin: 20px 0 6px 0;
  padding-bottom: 4px;
  border-bottom: 1px solid #eee;
}

.help-content p {
  margin: 0 0 10px 0;
}

.help-content ul {
  margin: 0 0 10px 0;
  padding-left: 20px;
}

.help-content ul li {
  margin-bottom: 4px;
}

.help-modal-actions {
  display: flex;
  justify-content: flex-end;
  margin-top: 24px;
}



  .blog-img {
    border: 3px solid rgb(5, 60, 82);
    border-radius: 4px;
    padding: 3px;
    max-width: 100%;
    height: auto;
    display: block;
    margin-left: auto;
    margin-right: auto;
    width: 50%;
  }

/** Navigation link formatting **/
.nav-td {
  font-family: 'Nunito', sans-serif;
  font-size: 22px;
  margin: 15px;
  padding: 20px;
}


.top-nav {
  font-family: 'Nunito';
  font-size: 36px;
  font-weight: bold;
  color:var(--color-text-dark);
}

#global-nav-placeholder {
  height: 70px; /* Helps CLS - sets aside height for global nav */
  position: relative;
}

/* Float the open mobile menu above page content instead of letting it
   overflow the 70px CLS placeholder and get painted over by <main> */
#global-nav-placeholder .nav-links.open {
  position: absolute;
  top: 100%;
  left: 0;
  width: fit-content;
  z-index: 1000;
}

.cms-nav-td {
  display: block;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 24px;
  color:var(--color-text-dark);
  margin: 0;
  padding: 12px 16px;
}

/* Shared by wlcms.html and smsAdmin.html - flex-wrap so a row of nav
   links wraps instead of overflowing, on both desktop and mobile */
.cms-top-nav {
  display: block;
  width: 100%;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 36px;
  color:var(--color-text-dark);
  margin: 15px 0;
  padding: 20px 0;
}

.cms-top-nav tr {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 12px;
  width: 100%;
}

/* wlcms.html's dropdown/flyout main nav - Cards / Blogs / Admin parents
   each reveal a flyout of links; "Exit" has no flyout. Opens via click
   (a small inline script in wlcms.html toggles an "open" class - this
   is what drives it on mobile/touch, where hover isn't meaningful) OR
   via CSS :hover on real pointer devices (below) - the two mechanisms
   are independent and don't conflict, since either one alone is enough
   to satisfy the "show the dropdown" selectors. A separate component
   from the plain .cms-top-nav breadcrumb table used by every other
   cms/*.html page. */
.cms-dropdown-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: flex-start;
  gap: 12px;
  list-style: none;
  width: 100%;
  margin: 0;
  padding: 8px 0;
  font-family: 'Source Sans 3', sans-serif;
}

.cms-nav-item {
  position: relative;
  margin: 0;
}

.cms-nav-parent,
.cms-nav-item-plain > a {
  display: block;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 24px;
  color: var(--color-link);
  background: none;
  border: none;
  margin: 0;
  padding: 12px 16px;
  cursor: pointer;
}

.cms-nav-parent::after {
  content: "\25BE";
  font-size: 0.6em;
  margin-left: 8px;
  display: inline-block;
}

.cms-nav-item.open > .cms-nav-parent::after {
  content: "\25B4";
}

.cms-nav-dropdown {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 240px;
  list-style: none;
  margin: 0;
  padding: 8px 0;
  background-color: var(--color-page-bg);
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
  z-index: 1000;
}

.cms-nav-item.open > .cms-nav-dropdown {
  display: block;
}

.cms-nav-dropdown li {
  margin: 0;
}

.cms-nav-dropdown a {
  display: block;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 20px;
  color: var(--color-text-dark);
  padding: 10px 16px;
  white-space: nowrap;
}

.cms-nav-dropdown a:hover {
  background-color: #fff;
}

/* Hover-to-open, desktop/trackpad only - excluded on touch so a tap
   doesn't leave a dropdown stuck open via a "phantom" hover state with
   no mouseleave to clear it. Mobile keeps the click-toggle above. */
@media (hover: hover) and (pointer: fine) {
  .cms-nav-item:hover > .cms-nav-dropdown {
    display: block;
  }

  .cms-nav-item:hover > .cms-nav-parent::after {
    content: "\25B4";
  }
}

.cms-form-table {
  font-family: 'Source Sans 3', sans-serif;
  font-size: 18px;
  width: 50%;
  margin: 20px 0;
  border-collapse: separate;
  border-spacing: 0 8px;
  text-align: left;
}

.cms-form-table td {
  /* padding: 10px 12px; */
  padding: 8px 10px;
  vertical-align: top;
  white-space: normal;
}

/* Plain divs (not a <table>), so flex-wrap/justify-content behave
   predictably everywhere - wraps onto as many lines as the current total
   needs, at any viewport width, with no JS split to maintain as ranges
   grow year over year.
   Scoped under #set-picker (id specificity) because .flex-container div
   (a bare descendant selector, see top of file) would otherwise match
   every nested div here too and force each one to width: 1000px. */
/* Owns the gap below the year picker. Replaced a <br><br> that sat after
   this block on all three picker pages - ID specificity beats
   .flex-container div's margin:5px. Tune the spacing here, not in HTML. */
#set-picker {
  margin-bottom: 12px;
}

#set-picker .card-set-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 8px;
  width: 100%;
  margin: 0;
  padding: 0;
  font-family: 'Spicy Rice';
  font-size: 23px;
  color:var(--color-text-dark);
  height: auto;
}


/********************************** Set-O-Matic styling **************************************/
#set-picker .junk-set-nav-td {
  display: block;
  width: auto;
  max-width: none;
  margin: 0;
  padding: 4px 10px;
  text-align: center;
  box-sizing: border-box;
}

#set-picker .junk-set-nav-td a {
  display: block;
  padding: 0;
}

.set-o-matic-picker {
  font-family: 'Spicy Rice';
  font-size: 32px;
  text-align: center;
  height: 42px;
}

/* Tighter than the shared .flex-container div's 15px padding, which
   stacked with the browser's default <h2> top margin to leave more
   empty space between the nav and this intro heading than needed. */
#card-intro {
  padding-top: 8px;
}

#card-intro h2 {
  margin-top: 0;
}
/********************************** MAIN Styling Rules **************************************/
body {
    height:100%;
    /* background-color: rgb(160, 188, 240); */
    background-color: var(--color-page-bg);

    /* Set a default font size for the page, then use em to set relative sizes to this */
    font-size: 18px;
}

hr {
  height:2px;
  width: 75%;
  border-width:0;
  color:gray;
  background-color:rgb(14, 74, 114)
}

a {
  text-decoration: none;
  /* color: rgb(12, 101, 136); */
  color: var(--color-heading-outline)
}

.header-link {
  text-decoration: none;
  color: var(--color-link);
}

table {
  border-collapse: collapse;
 }

form {
  font-family: 'Work Sans', sans-serif;
  font-size: 20px;
  padding-left: 1.5%;
 }

 /************************************** CMS TEXTBOX FORM Styling ********************************/
 input[type=text] { 
  font-size: 16px;
  width: 450px; /* Hard code text box width */
  padding: 6px 10px;
  margin: 8px 0;
  display: inline-block;
  border: 1px solid var(--color-input-border);
  border-radius: 2px;
  box-sizing: border-box;
}

select {
  font-size: 16px;
  width: 100px;
  padding: 6px 10px;
  margin: 8px 0;
  display: inline-block;
  border: 1px solid var(--color-input-border);
  border-radius: 2px;
}

/* Star Rating widget - createCardSet.html/setEdit.html (initStarRatingWidget()/
   paintStarRating() in cmsCardSet.js). The real value lives in a hidden
   #stars input right after this; these spans are purely visual. Uses the
   same glowing-star emoji as the public "Hella Rating" display (wax.js)
   for the selected state - emoji ignore CSS `color`, so "empty" is the
   same glyph desaturated/dimmed via `filter` rather than a second icon. */
.star-rating-widget {
  display: inline-flex;
  gap: 6px;
  margin-top: 6px;
  font-size: 28px;
  line-height: 1;
  cursor: pointer;
  user-select: none;
}

.star-rating-icon {
  filter: grayscale(1) opacity(0.35);
  transition: filter 0.1s;
}

.star-rating-icon.selected {
  filter: none;
}

textarea {
  font-size: 24px;
  font-family: 'Consolas', Courier, monospace;
  width: 80%;
  height: 150px;
  box-sizing: border-box;
  border: 1px solid var(--color-input-border);
  border-radius: 2px;
  resize: none;
  overflow: scroll;
} 

.input-button {
  font-family: 'Source Sans 3', sans-serif;
  background-color: #256386;
  color: white;
  text-decoration: none;
  margin: 4px 2px;
}

/* Modifier for destructive actions - e.g. the Delete Post button on blogEdit.html */
.delete-btn {
  background-color: #a83232;
}

/* Required-field marker, e.g. <label>Set Name <sup>*</sup></label> across the CMS forms */
label sup {
  color: #a83232;
  font-weight: bold;
}

.input-text-disabled {
  background-color: #c5cdd3;
}

 .mast-table {
  border-collapse: collapse;
  width: 100%;
  background-color: var(--color-masthead-bg);
}

.autobus-mast-table {
  border-collapse: collapse;
  width: 100%;
  background-color: rgb(0, 0, 0);
}

.mast-table td {
  vertical-align: top;
  padding: 0;
  margin: 0;
}

.mast-table tr {
  height: 7vw; /* matches masthead font size */
}

.mast-table img {
  display: block;
  height: 100%;
  width: auto;
  margin: 0;
  padding: 0;
}


.masthead {
  font-family: 'Spicy Rice';
  font-size: 7vw;
  color: var(--color-link);
  background-color: var(--color-masthead-bg);
  padding: 1px 10px 0 10px;
}

.autobus-masthead {
  font-family: 'Arial';
  font-size: 7vw;
  color: #000000;
  background-color: rgb(0, 0, 0);
  padding: 1px 10px 0 10px;
}

.cms-logo {
  font-family: 'Source Sans 3', sans-serif;
  font-size: 40px;
  text-align: left; 
  font-weight: 500;         
  color: var(--color-link);
  background-color: var(--color-masthead-bg);
  padding: 4px 16px 4px 10px; /* add more right padding */
  line-height: 1.2;
  display: block;             /* ensures alignment behaves predictably */
}

.autobus-cms-logo {
  font-family: 'Source Sans 3', sans-serif;
  font-size: 40px;
  text-align: left; 
  font-weight: 500;         
  color: #f574e0;
  background-color: rgb(0, 0, 0);
  padding: 4px 16px 4px 10px; /* add more right padding */
  line-height: 1.2;
  display: block;             /* ensures alignment behaves predictably */
}


.wax-reviews-mast-table {
  width: 100%;
  height: 150px;
  position: relative;
  /* Lifted above the NHL ticker below it (waxReviews.html), which would
     otherwise paint over this drop shadow. */
  z-index: 1;
  box-shadow: 0 4px 10px rgba(0, 0, 0, 0.35);
  overflow: hidden;
  /* Defaults match the original hella_habs_masthead.webp (Canadiens
     red/navy) - applyRandomMastheadTeam() (helper.js) overrides these
     on load to a random NHL team's colors; without JS, or before it
     runs, this renders identically to the old fixed image. */
  --team-primary: #A6192E;
  --team-tertiary: #001E62;
  /* Reproduces the original image's 5-band stripe exactly (measured by
     sampling its pixels): band proportions 0-33/33-38/38-62/62-67/67-100. */
  background-image: linear-gradient(to bottom,
    var(--team-primary) 0%, var(--team-primary) 33%,
    #ffffff 33%, #ffffff 38%,
    var(--team-tertiary) 38%, var(--team-tertiary) 62%,
    #ffffff 62%, #ffffff 67%,
    var(--team-primary) 67%, var(--team-primary) 100%);
  background-size: cover;
  background-repeat: no-repeat;
  background-position: center;
  color: white;
  font-family: sans-serif;
}

/* Genuinely two-color (+white) teams (Detroit, Tampa Bay, Toronto -
   applyRandomMastheadTeam() in helper.js toggles this class on when
   --team-primary === --team-tertiary) get a simpler design than the
   5-band stripe above: a solid background in that one color with a
   single white stripe centered at 30% of the total width, vertical
   rather than the horizontal bands used elsewhere. */
.wax-reviews-mast-table.masthead-two-color {
  background-image: linear-gradient(to bottom,
    var(--team-primary) 0%, var(--team-primary) 35%,
    #ffffff 35%, #ffffff 65%,
    var(--team-primary) 65%, var(--team-primary) 100%);
}

.wax-reviews-mast-table::before { /* Blurred noise overlay for a vintage vibe */
  content: "";
  position: absolute;
  inset: 0;
  background-image:
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='noise'><feTurbulence type='fractalNoise' baseFrequency='0.8' numOctaves='3'/></filter><rect width='100%' height='100%' filter='url(%23noise)' opacity='0.08'/></svg>");
  background-size: cover;
  background-position: center;
  filter: blur(7px);
  transform: scale(1.05);
  z-index: 0;
  pointer-events: none;
}

/* City-only label (applyRandomMastheadTeam(), helper.js) so the random
   team pick can be visually verified at a glance. White-on-dark-shadow
   rather than the masthead text's fixed blue outline, since that outline
   is tuned for the large Bebas Neue title, not legible at this size. */
.masthead-team-label {
  position: absolute;
  right: 8px;
  bottom: 4px;
  z-index: 1;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 24px;
  color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 1px 2px rgba(0, 0, 0, 0.6);
  pointer-events: none;
}

/* "Loud" pop-in effect (renderLoudText(), helper.js): each character of
   the cheer label is its own span, staggered via animation-delay set in
   JS, so the text appears to pop in letter by letter on load. */
.masthead-team-label .loud-char {
  display: inline-block;
  opacity: 0;
  transform: scale(0.4) rotate(-8deg);
  animation: loudPopIn 0.5s cubic-bezier(0.34, 1.56, 0.64, 1) forwards;
}

@keyframes loudPopIn {
  0% {
    opacity: 0;
    transform: scale(0.4) rotate(-8deg);
  }
  60% {
    opacity: 1;
    transform: scale(1.25) rotate(4deg);
  }
  100% {
    opacity: 1;
    transform: scale(1) rotate(0deg);
  }
}

@media (prefers-reduced-motion: reduce) {
  .masthead-team-label .loud-char {
    animation: none;
    opacity: 1;
    transform: none;
  }
}


.wax-reviews-masthead a {
  font-family: Bebas Neue;
  font-weight: 500;
  font-size: 128px;
  position: relative;
  z-index: 1; /* keeps text above the blur */
  text-transform: uppercase;
  text-decoration: none;
  color: rgb(252, 252, 245);
  display: flex;
  align-items: center;
  padding-left: 20px;
  height: 150px;
  text-shadow:
    -2px -2px 0 var(--color-heading-outline),
     2px -2px 0 var(--color-heading-outline),
    -2px  2px 0 var(--color-heading-outline),
     2px  2px 0 var(--color-heading-outline);
}

/* .masthead-two-color's centered white stripe sits directly under part
   of the title - the near-white fill (rgb(252,252,245)) all but
   vanishes against it, leaving only the thin 2px blue outline above to
   define the letterforms, which isn't enough on its own. Add a larger,
   darker outline layer behind the existing blue one (painted first,
   per text-shadow's back-to-front list order) so the title stays
   legible over white without changing the stripe's centered position. */
.wax-reviews-mast-table.masthead-two-color .wax-reviews-masthead a {
  text-shadow:
    -2px -2px 0 var(--color-heading-outline),
     2px -2px 0 var(--color-heading-outline),
    -2px  2px 0 var(--color-heading-outline),
     2px  2px 0 var(--color-heading-outline),
    -3px -3px 0 #000000,
     3px -3px 0 #000000,
    -3px  3px 0 #000000,
     3px  3px 0 #000000;
}

/* NHL scores ticker (initNhlTicker(), wax.js) - dark strip under the
   masthead. The scroller holds two identical tracks and slides -50%,
   so the loop is seamless; duration is set in JS from the track width. */
.nhl-ticker {
  display: flex;
  align-items: center;
  height: 40px;
  margin-top: 6px;
  overflow: hidden;
  background-color: #1b1b1b;
  color: #f2f2f2;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 15px;
  font-variant-numeric: tabular-nums;
}

/* display: flex above would otherwise override the hidden attribute. */
.nhl-ticker[hidden] {
  display: none;
}

.nhl-ticker:focus-visible {
  outline: 2px solid var(--color-link);
  outline-offset: -2px;
}

.nhl-ticker-scroller {
  display: flex;
  width: max-content;
  animation: nhlTickerScroll 60s linear infinite;
}

/* Pause on hover/keyboard focus so a score can actually be read. */
.nhl-ticker:hover .nhl-ticker-scroller,
.nhl-ticker:focus-within .nhl-ticker-scroller {
  animation-play-state: paused;
}

@keyframes nhlTickerScroll {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

.nhl-ticker-track {
  display: flex;
  align-items: center;
}

/* One block per league (buildTickerLeagueSection(), wax.js): the league's
   logo, then its games. Logo sizes match the width/height set in JS. */
.ticker-league {
  display: flex;
  align-items: center;
  height: 100%;
}

.ticker-league-logo {
  flex: none;
  margin: 0 6px 0 16px;
}

.ticker-league[data-league="nhl"] .ticker-league-logo {
  width: 48px;
  height: 32px;
  /* The NHL SVG has ~9px of transparent padding around the shield; a
     negative margin evens the visible gap with the PWHL wordmark's. */
  margin-right: -3px;
}

.ticker-league[data-league="pwhl"] .ticker-league-logo {
  width: 85px;
  height: 18px;
  /* The wordmark has no built-in padding (the NHL logo has ~10px), so
     it needs more lead-in for both league breaks to look the same. */
  margin-left: 26px;
}

/* A one-colour logo repainted in its league's logoColor (wax.js): the
   colour fills the box, and the logo image is the mask that shapes it. */
.ticker-league-logo-masked {
  display: inline-block;
  -webkit-mask-repeat: no-repeat;
  mask-repeat: no-repeat;
  -webkit-mask-position: center;
  mask-position: center;
  -webkit-mask-size: contain;
  mask-size: contain;
}

/* A league with no games yesterday or today shows its next date
   instead ("Season starts" / "Next game"), styled like game status. */
.ticker-league-note {
  padding: 0 16px 0 10px;
  border-right: 1px solid rgba(255, 255, 255, 0.15);
  color: #b5b5b5;
  font-size: 13px;
  text-transform: uppercase;
  white-space: nowrap;
}

/* Dividers separate games within a league; the logo already separates
   leagues, so the last item in each section (game or note) has none. */
.ticker-league > :last-child {
  border-right: 0;
}

/* PWHL team logos are square PNGs, not the NHL's 3:2 SVGs - and with
   no built-in padding, so they need a margin to sit as far from the
   abbreviation as the NHL's do (12px visible gap on desktop). */
.ticker-league[data-league="pwhl"] .nhl-team img {
  width: 28px;
  height: 28px;
  margin-right: 8px;
}

/* A section added while on-screen (no hidden moment available - see
   applyTickerSectionSwap(), wax.js) fades in rather than popping. */
.ticker-league-entering {
  animation: tickerLeagueFadeIn 0.4s ease-out;
}

@keyframes tickerLeagueFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

/* Date / "Today" labels get the same divider as the games and the PWHL
   notice, so each label is set off from the games that follow it. */
.nhl-ticker-label {
  padding: 0 14px;
  border-right: 1px solid rgba(255, 255, 255, 0.15);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--color-link);
  white-space: nowrap;
}

/* Chips are <button>s (they open the game modal) - reset the browser's
   button look so they read as plain ticker text. */
.nhl-chip {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  height: 100%;
  padding: 0 16px;
  border: 0;
  border-right: 1px solid rgba(255, 255, 255, 0.15);
  background: none;
  color: inherit;
  font: inherit;
  white-space: nowrap;
  cursor: pointer;
}

.nhl-chip:hover:not(:disabled) {
  background-color: rgba(255, 255, 255, 0.08);
}

.nhl-chip:focus-visible {
  outline: 2px solid var(--color-link);
  outline-offset: -2px;
}

/* Upcoming games: nothing to show in the modal yet. */
.nhl-chip:disabled {
  cursor: default;
}

.nhl-team {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}

/* NHL logos are 3:2 SVGs (960x640) with built-in padding - a square
   box would shrink them to fit the width, so match their shape. */
.nhl-team img {
  width: 42px;
  height: 28px;
}

/* Regular weight by default so a final's winner (.nhl-team-winner,
   set in fillNhlGameChip(), wax.js) can stand out in bold white. */
.nhl-team {
  color: #cfcfcf;
}

.nhl-abbrev {
  margin-right: 5px;
}

.nhl-team-winner {
  color: #ffffff;
  font-weight: 700;
}

.nhl-status {
  font-size: 13px;
  color: #b5b5b5;
  text-transform: uppercase;
}

/* Same red as .delete-btn / rookie cards, lightened to read on dark. */
.nhl-chip-live .nhl-status {
  color: #ff7a7a;
  font-weight: 700;
}

/* NHL game modal (openNhlGameModal(), wax.js) - reuses the checklist
   modal's overlay/content/close classes; .nhl-game-modal narrows it. */
/* Same type as the blog/review pages: Source Sans 3 body text in the
   site's body colour, Work Sans for headings (like blog post titles). */
.checklist-modal-content.nhl-game-modal {
  max-width: 900px;
  color: rgb(34, 38, 41);
  font-family: 'Source Sans 3', sans-serif;
  font-variant-numeric: tabular-nums;
}

.nhl-game-abbrev,
.nhl-game-section h3,
.nhl-recap h3 {
  font-family: 'Work Sans', sans-serif;
}

.nhl-game-scoreline {
  display: grid;
  grid-template-columns: 1fr auto minmax(90px, auto) auto 1fr;
  align-items: center;
  gap: 20px;
}

.nhl-game-side-away {
  justify-self: end;
}

.nhl-game-side-home {
  justify-self: start;
}

.nhl-game-team {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* Home team reads logo-last, mirroring the away side. */
.nhl-game-side-home .nhl-game-team {
  flex-direction: row-reverse;
}

.nhl-game-team-text {
  display: flex;
  flex-direction: column;
  line-height: 1.1;
}

.nhl-game-side-home .nhl-game-team-text {
  align-items: flex-end;
}

.nhl-game-abbrev {
  font-size: 28px;
  font-weight: 700;
}

.nhl-game-record {
  font-size: 14px;
  color: #666;
}

.nhl-game-score {
  font-size: 56px;
  font-weight: 700;
  line-height: 1;
}

.nhl-game-score-loser {
  font-weight: 400;
  color: #8a8a8a;
}

.nhl-game-status {
  font-size: 16px;
  font-weight: 700;
  text-align: center;
  color: #444;
}

.nhl-game-meta {
  margin: 10px 0 0;
  text-align: center;
  font-size: 14px;
  color: #666;
}

.nhl-game-tabs {
  display: flex;
  margin: 20px 0 16px;
  border-bottom: 1px solid #d6d6d6;
}

.nhl-game-tabs [role="tab"] {
  flex: 1;
  padding: 10px 8px;
  border: 0;
  border-bottom: 3px solid transparent;
  background: none;
  color: #444;
  font: inherit;
  /* After the font shorthand, which would otherwise reset it. */
  font-family: 'Work Sans', sans-serif;
  font-size: 16px;
  font-weight: 600;
  cursor: pointer;
}

.nhl-game-tabs [role="tab"][aria-selected="true"] {
  border-bottom-color: #256386;
  color: #256386;
}

.nhl-game-tabs [role="tab"]:focus-visible {
  outline: 2px solid #256386;
  outline-offset: -2px;
}

.nhl-game-section h3 {
  margin: 18px 0 6px;
  padding-bottom: 6px;
  border-bottom: 1px solid #d6d6d6;
  font-size: 18px;
}

.nhl-game-empty {
  margin: 10px 0;
  color: #555;
}

.nhl-game-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 0;
}

.nhl-game-row-main {
  flex: 1;
  min-width: 0;
}

.nhl-game-row-note {
  color: #555;
  font-size: 14px;
  white-space: nowrap;
}

.nhl-goal-time {
  width: 44px;
  font-weight: 600;
}

.nhl-goal-scorer {
  font-weight: 700;
}

.nhl-goal-assists {
  font-size: 14px;
  color: #555;
}

.nhl-goal-badge {
  margin-left: 4px;
  padding: 1px 6px;
  border-radius: 4px;
  background-color: #256386;
  color: #fff;
  font-size: 11px;
  font-weight: 700;
}

.nhl-shootout-goal {
  color: #1d7a3a;
  font-weight: 700;
}

.nhl-shootout-miss {
  color: #8a8a8a;
}

.nhl-star {
  width: 44px;
  color: #c9a227;
  letter-spacing: -2px;
}

.nhl-linescore-box {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 32px;
  padding: 16px;
  border: 1px solid #d6d6d6;
  border-radius: var(--btn-radius);
}

/* A many-overtime playoff line score scrolls inside its own box rather
   than pushing the page sideways. */
.nhl-linescore-wrap {
  flex: 1 1 320px;
  overflow-x: auto;
}

.nhl-linescore,
.nhl-team-stats {
  width: 100%;
  border-collapse: collapse;
}

.nhl-linescore th,
.nhl-linescore td {
  padding: 8px 10px;
  border-bottom: 1px solid #d6d6d6;
  text-align: center;
}

.nhl-linescore thead th {
  color: #555;
  font-weight: 600;
}

.nhl-linescore thead th:first-child,
.nhl-linescore tbody th {
  text-align: left;
  white-space: nowrap;
}

.nhl-linescore tbody th img {
  vertical-align: middle;
}

.nhl-linescore tbody tr:last-child th,
.nhl-linescore tbody tr:last-child td {
  border-bottom: 0;
}

.nhl-linescore-total {
  font-weight: 700;
}

.nhl-game-decisions p {
  margin: 4px 0;
}

.nhl-team-stats {
  margin-top: 20px;
}

.nhl-team-stats th,
.nhl-team-stats td {
  padding: 7px 10px;
  border-bottom: 1px solid #ececec;
  text-align: center;
}

.nhl-team-stats thead th {
  font-weight: 700;
}

.nhl-team-stats tbody th {
  font-weight: 400;
  color: #555;
}

.nhl-video-poster {
  position: relative;
  display: block;
  width: 100%;
  font: inherit;
  aspect-ratio: 16 / 9;
  padding: 0;
  border: 0;
  border-radius: var(--btn-radius);
  overflow: hidden;
  background-color: #1b1b1b;
  cursor: pointer;
}

.nhl-video-poster img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.nhl-video-play {
  position: absolute;
  top: 50%;
  left: 50%;
  width: 72px;
  height: 72px;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background-color: #256386;
  color: #fff;
  font-size: 30px;
  line-height: 72px;
  text-indent: 6px;
}

.nhl-video-poster:hover .nhl-video-play,
.nhl-video-poster:focus-visible .nhl-video-play {
  filter: brightness(1.15);
}

.nhl-video-caption {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 10px 14px;
  background: linear-gradient(transparent, rgba(0, 0, 0, 0.75));
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  text-align: left;
}

.nhl-video-frame {
  display: block;
  width: 100%;
  aspect-ratio: 16 / 9;
  border: 0;
  border-radius: var(--btn-radius);
}

.nhl-recap h3 {
  margin: 18px 0 8px;
  font-size: 20px;
}

.nhl-recap p {
  margin: 0 0 12px;
  line-height: 1.5;
}

.nhl-recap a {
  color: #256386;
  font-weight: 600;
}

.nhl-recap-image {
  width: 100%;
  border-radius: var(--btn-radius);
}

/* No marquee: a plain row the visitor can swipe/scroll instead. */
@media (prefers-reduced-motion: reduce) {
  .nhl-ticker {
    overflow-x: auto;
  }
  .nhl-ticker-scroller {
    animation: none;
  }
  .nhl-ticker-track-copy {
    display: none;
  }
  .ticker-league-entering {
    animation: none;
  }
}


.blog-type-divider {
  margin-top: 24px;
  margin-bottom: 8px;
  font-family: 'Work Sans', sans-serif;
  font-size: 1.3rem;
  font-weight: bold;
  font-style: italic;
  color: var(--color-link);
  border-bottom: 2px solid #0564a3;
  padding-bottom: 4px;
  width: 325px; /* Makes the dividing line fixed length */
  
}

.header-style h1{
    font-family: 'Work Sans', sans-serif;
    font-size: 28px;
    margin: 5px;
    position: relative;
    top: 1px;
}

/* waxReviews.html only (see the .wax-set-name-header class on its
   .header-style div) - hides the set name shown right under the
   hamburger menu, on every breakpoint, since the set-details section
   further down the page repeats the same name as its own heading.
   lockout.html shares #pageHeader's id but not this class, so its own
   (non-redundant) title is unaffected. */
.wax-set-name-header {
  display: none;
}

.intro {
  font-family: 'Work Sans', sans-serif;
  font-size: 18px;
  margin: 5px auto;
  width: 950px;
}

/* Same .flex-container div padding + default heading/paragraph margin
   stacking as #card-intro/#player-search-intro below - #blog-intro
   (index.html/tech.html, shared) and #junkwax-intro
   (theJunkWaxYears.html) left more empty space above their text than
   intended for the same reason. */
#blog-intro {
  padding-top: 8px;
}

#blog-intro h1 {
  margin-top: 0;
}

#junkwax-intro {
  padding-top: 8px;
}

#junkwax-intro p:first-child {
  margin-top: 0;
}

.blog-entry { /* USED BY ALL REVIEW PAGES */ 
    font-family: 'Source Sans 3';
    background: rgb(212, 233, 241);
    border-radius: 3px;
    color:rgb(34, 38, 41);
    font-size: 18px;
    font-weight: 400; /* Light */
    text-align: left;
    padding: 10px; /* changing to 10px */
} 

.blog-title {
  font-family: 'Work Sans', sans-serif;
  font-size: 22px;
  color:rgb(11, 109, 167);
}

.blurb p {
  font-family: 'Source Sans 3', sans-serif;
  color:rgb(34, 38, 41);
  font-size: 16px;
  text-align: left;
}

  #weather {
    display: flex;
    justify-content: left;
    min-height: 50px;
  }

.caption {
  font-family: "Special Elite";
  font-size: 16px;
}
    

/* Table Stuff */
.table-style {
  margin-left: auto;
  margin-right: auto;
  font-family: 'Nunito';
  font-size: 16px;
  text-align: left;
}

.set-details-table-style {
  width: 100%;
  table-layout: fixed;
  font-size: 18px;
  line-height: 1.4;
  font-family: 'Source Sans 3', sans-serif;
}

/* Previously had no base/desktop rule at all - only the mobile override
   existed, so desktop relied purely on inherited styling. Matches the
   mobile values intentionally now instead of by inheritance accident. */
.set-details-author {
  font-family: 'Source Sans 3', sans-serif;
  font-size: 18px;
  /* Missing these let the review body (postBody, TinyMCE-authored HTML
     of widely varying quality/vintage) push this table wider than its
     container on at least one set - width:auto tables aren't reliably
     bounded by their container, unlike .set-details-table-style right
     above it (the image/details box), which already sets both and
     renders correctly contained. */
  width: 100%;
  table-layout: fixed;
}

#cardSetDiv {
  min-height: 750px;   /* small amount of pre-setting for set review height - soften the impact for CLS */
}

#blogsDiv {
  min-height: 750px;   /* small amount of pre-setting for set review height - soften the impact for CLS */
}

/* Used to style the first table displaying the main set details */

.set-details-table-style td {
  display: table-cell;
  table-layout: fixed;
  margin-left: 5px;
  margin-right: 5px;
  font-family: 'Special Elite', sans-serif; 
  font-size: 18px;
  text-align: left;
  padding: 2px 4px;
  width: auto;
}

/* Move the set image closer to the card set details */
.set-details-table-style td:first-child {
  max-width: 60%;
}

.card-table-style td{
  margin-left: 5px;
  margin-right: 5px;
  font-family: 'Special Elite';
  font-style: italic;
  font-size: 16px;
  text-align: left;
  padding: 6px;
}

.cms-set-picker {
  width: 800px;
  margin-left: 200px;
}

/* Unlike set-details-table-style / set-details-author, this table never
   had an explicit width - it shrink-wrapped to its image content and sat
   left-aligned instead of letting the image's margin:auto center it */
.set-footer-table-style {
  width: 100%;
}

/* .set-footer-table-style is now plain <div>s (see wax.js) - .flex-container
   div (a bare descendant selector, top of file) matches every div nested
   inside #cardSetDiv too, forcing width:1000px/padding:15px/margin:5px
   onto this and the .caption div inside it. Override with #cardSetDiv's
   higher specificity, same fix as the #set-picker one above. */
#cardSetDiv .set-footer-table-style,
#cardSetDiv .set-footer-table-style > div {
  width: 100%;
  max-width: none;
  padding: 0;
  margin: 0;
}

/* Breathing room between the end of the review text and the caption */
#cardSetDiv .set-footer-table-style {
  margin-top: 16px;
}

/* ...and between the caption and the image below it */
#cardSetDiv .set-footer-table-style .caption {
  margin-bottom: 20px;
}

/* Trim the trailing margin left by the last paragraph of the review body,
   so it doesn't read as a gap before the footer table */
.set-details-author td > *:last-child {
  margin-bottom: 0;
}

/* Replaces the old rowspan'd <table class="set-details-table-style">
   for the set-details box - CSS Grid instead of a table, so the mobile
   override below can reorder name -> image -> list without fighting a
   rowspan (see FRONTEND.md's "Mobile / responsive design" section for
   why that doesn't work reliably). Shared by the live site and the CMS
   preview modal, which render identical markup - see
   buildCardSetMarkup() in helper.js. */
.set-details-grid {
  display: grid;
  grid-template-columns: 25% 75%;
  grid-template-areas:
    "name image"
    "list image";
  font-family: 'Source Sans 3', sans-serif;
  padding: var(--set-details-top-pad) 0 0 0;
  /* Explicit, not auto: the percentage column tracks shrink-wrap to
     content when the parent's width is indefinite, which is the case
     in the CMS preview modal (but not under #cardSetDiv, where
     .flex-container div forces a fixed width). */
  width: 100%;
}

.set-details-name {
  grid-area: name;
  font-family: 'Special Elite', sans-serif;
  font-size: 20px;
  padding: 2px 4px;
}

.set-details-image {
  grid-area: image;
  display: flex;
  align-items: center;
  justify-content: center;
  /* min-height, not height: this cell spans both grid rows, so letting
     it stretch keeps the image centred against the whole left column
     even when a Checklist row makes that column taller than 285px. */
  min-height: 285px;
}

/* The base rule's 8px top margin would push the image below true
   centre here; the grid cell handles its spacing instead. */
.set-details-image .table-header-img {
  margin-top: 0;
}

.set-details-list {
  grid-area: list;
  /* Flex column so .set-detail-row-checklist's order below can move
     the Checklist row after Hella Rating without changing the DOM
     order displayCardSet() (wax.js) builds - applies on both desktop
     and mobile, same reorder either way. */
  display: flex;
  flex-direction: column;
}

.set-detail-row {
  /* Body font (matches .set-details-author's postBody text) for the
     actual values - Special Elite below is only for the bolded field
     names (e.g. "Set Size:"), matching this site's older convention
     (still visible in the #previewContainer .set-details-author td
     strong/i rule) of field names in Special Elite, values in the
     regular body font, not the whole row in one font. */
  font-family: 'Source Sans 3', sans-serif;
  font-size: 18px;
  padding: 2px 4px;
}

.set-detail-row strong {
  font-family: 'Special Elite', sans-serif;
}

/* order:0 (the default) for every other row keeps them in their
   existing DOM order; giving just this one a higher order value moves
   it after all of them, i.e. after Hella Rating - on both desktop and
   mobile. */
.set-detail-row-checklist {
  order: 1;
}

/* #cardSetDiv sits inside .flex-container, whose bare descendant
   selector (.flex-container div, top of file - and its mobile
   redefinition) matches every div nested inside it at any depth,
   including all of the above - forcing width:1000px/padding:15px
   (desktop) or width:100%/padding:10px (mobile) onto each one
   regardless of the grid-area layout. Same recurring bug, same fix
   pattern as #cardSetDiv .set-footer-table-style above: ID specificity
   beats the shared rule's class+type specificity, on both breakpoints
   at once since this isn't itself inside a media query. */
#cardSetDiv .set-details-grid {
  width: auto;
  max-width: none;
  margin: 0;
  /* Restated (not inherited) because this rule has to beat
     .flex-container div's padding:15px - see the comment above. */
  padding: var(--set-details-top-pad) 0 0 0;
}
#cardSetDiv .set-details-name,
#cardSetDiv .set-detail-row {
  width: auto;
  max-width: none;
  margin: 0;
  padding: 2px 4px;
}
#cardSetDiv .set-details-image,
#cardSetDiv .set-details-list {
  width: auto;
  max-width: none;
  margin: 0;
  padding: 0;
}

/*************************************** Image Styles ****************************************/

.table-header-img {
  max-width: 620px; /* or whatever size feels right */
  width: 100%;
  height: auto;
  display: block;
  margin: 8px auto 0 auto; /* top margin + horizontal centering */
  border: 1px solid;
  border-color: var(--color-image-border);
  border-radius: 2px;
  box-shadow: 5px 10px 18px #888888;
}

.card-middle-img {
  /* First four values center the image, no table needed */
  width: 75%;
  display: block;
  margin-left: auto;
  margin-right: auto;
  border: 2px solid;
  border-color: var(--color-image-border);
  border-radius: 2px;
  box-shadow: 5px 10px 18px #888888;
}

.mache-sync-img {
  /* First four values center the image, no table needed */
  width: 50%;
  height: 50%;
  display: block;
  margin-left: auto;
  margin-right: auto;
  border: 2px solid;
  border-color: var(--color-image-border);
  border-radius: 2px;
  box-shadow: 5px 10px 18px #888888;
}

.img-wrap-left {
  float: left;
  margin: 0 15px 15px 0;
}

.img-wrap-right {
  float: right;
  margin: 0 0 15px 15px;
}

/* These are small accent/logo images - cap their size regardless of
   whatever inline width/height got hand-set in the stored post content */
.img-wrap-left,
.img-wrap-right {
  max-width: 50px !important;
  height: auto !important;
}

/* Images inserted into the review body via the WYSIWYG editor carry
   whatever inline width/height the editor set (or none at all) - scale
   them to their container instead of rendering at raw/mismatched size */
.set-details-author img {
  max-width: 100% !important;
  height: auto !important;
}

/* Opt-in per-image mobile scaling for hand-inserted wrap images (small
   logos/accent images with a hardcoded desktop width/height, e.g. the
   All-Star Game logo on McDonald's sets). Add one of these classes
   alongside .img-wrap-left/.img-wrap-right - no per-image sizing
   needed to type:
     <img class="img-wrap-left img-wrap-sm" style="width: 214px; height: 117px;" ...>
   .img-wrap-sm -> half size on mobile; .img-wrap-md -> 65% size on
   mobile, for images where half is too aggressive a shrink.
   applyImgWrapSmSizing() (helper.js, called from wax.js once each
   set's postBody renders) reads the image's own width/height attribute
   and sets --wrap-w/--wrap-h custom properties from it. The mobile
   rules below (main mobile media query, GLOBAL / SITE-WIDE section)
   then resize the actual box off those - a real layout resize, not
   just a visual transform, so wrapped text reflows in tight to the
   now-smaller image instead of leaving a blank gap. Also scoped under
   .set-details-author to out-specificity the rule just
   above (0,2,1 vs 0,1,1), same class of clobbering that made the old
   .img-wrap-left/.img-wrap-right max-width:50px cap below never
   actually apply here. */

.table-footer-img {
  width: 90%;
  display: inline-block;
  vertical-align: top;
  margin: 0;
  border: 1px solid;
  border-color: var(--color-image-border);
  border-radius: 2px;
  box-shadow: 5px 10px 18px #888888;
}

.page-footer {
    font-size: 10px;
    font-family: 'Work Sans', sans-serif;
    padding: 20px;
    display: inline;
}

.password-style {
	font-family: "Special Elite";
	font-size: 16px;
}

.error-msg {
  font-family: 'Fira Code';
  font-size: 18px;
  color:rgb(7, 62, 126);
  width:400px;
}

/* Checklist upload/review (cms/uploadChecklist.html) */
.checklist-trigger-row {
  padding-left: 8px;
}

#checklistImportLink,
#checklistDeleteLink {
  color: white;
  padding: 6px 14px;
  font-size: 14px;
}

#checklistDeleteLink {
  margin-left: 8px;
}

.checklist-button-row {
  display: flex;
  align-items: center;
  gap: 12px;
  margin-top: 20px;
}

.checklist-add-row-btn {
  background-color: var(--color-link);
}

/* Delete Checklist modal on cms/uploadChecklist.html (.bulk-* chrome) - one
   row per stored group (main set + each insert set), built by
   buildChecklistGroupRow() in checklistUpload.js. */
/* ID-scoped so it beats the global input[type=text] rule (0,1,1), which
   otherwise wins over a bare class and forces width:450px/margin:8px 0.
   display:block + margin:0 keep the type-ahead dropdown flush below. */
#checklistDeleteOverlay .checklist-delete-input {
  display: block;
  width: 100%;
  max-width: none;
  margin: 0;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 16px;
  padding: 6px 8px;
  border: 1px solid var(--color-input-border);
  border-radius: 3px;
  box-sizing: border-box;
}

/* Anchors the dropdown's top:100% to the input. The bottom margin sits here
   rather than on the input so it can't push the dropdown off. */
.checklist-typeahead-wrap {
  position: relative;
  width: 100%;
  margin-bottom: 10px;
}

.checklist-typeahead-suggestions {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 100;
  margin: 2px 0 0 0;
  padding: 4px 0;
  list-style: none;
  background-color: #fff;
  border: 1px solid var(--color-input-border);
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  max-height: 260px;
  overflow-y: auto;
}

.checklist-typeahead-suggestion {
  padding: 8px 12px;
  cursor: pointer;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 16px;
}

.checklist-typeahead-suggestion:hover,
.checklist-typeahead-suggestion.active {
  background-color: var(--color-page-bg);
}

/* Real sets run to 8-12 groups: scroll the list, not the modal, so the
   Close/Load row never leaves the screen. The type-ahead dropdown is a
   sibling of this list, so the scroll container can't clip it. */
#checklistDeleteList {
  max-height: 280px;
  overflow-y: auto;
}

.checklist-delete-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--color-input-border);
  font-family: 'Source Sans 3', sans-serif;
  font-size: 16px;
}

.checklist-page-content {
  font-family: 'Source Sans 3', sans-serif;
  max-width: 700px;
  padding-left: 8px;
}

.checklist-status-msg {
  font-family: 'Source Sans 3', sans-serif;
  font-size: 16px;
  max-width: 900px;
  margin-top: 28px;
  color: rgb(7, 62, 126);
}

.checklist-review-table {
  font-family: 'Source Sans 3', sans-serif;
  font-size: 15px;
  width: 100%;
  border-collapse: collapse;
  margin: 20px 0;
}

.checklist-review-table th {
  text-align: left;
  padding: 6px 8px;
  border-bottom: 2px solid var(--color-input-border);
  color: var(--color-text-dark);
}

.checklist-review-table td {
  padding: 4px 6px;
  border-bottom: 1px solid rgba(85, 174, 233, 0.3);
}

.checklist-review-table input[type="text"] {
  width: 100%;
  box-sizing: border-box;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 15px;
  padding: 4px 6px;
  border: 1px solid var(--color-input-border);
  border-radius: 3px;
}

.checklist-review-table td.checklist-num-col input {
  width: 5em;
}

.checklist-row-delete-btn {
  background: none;
  border: none;
  color: rgb(180, 40, 40);
  font-size: 18px;
  cursor: pointer;
  padding: 0 6px;
}

/* cmsAlert() modal (scripts/cmsAlert.js) - a styled replacement for the
   native alert() used throughout the CMS. Visually mirrors the public
   checklist modal below (masthead-blue header, white box, box-shadow
   overlay) so both sides of the site share one modal look, but this is
   a separate, much smaller component - just a message + OK button, no
   print/close-button chrome or card layout to reuse. */
.cms-alert-overlay {
  display: none;
  position: fixed;
  z-index: 10000;
  inset: 0;
  background-color: rgba(0, 0, 0, 0.6);
  overflow-y: auto;
  align-items: flex-start;
  justify-content: center;
  /* ~25% down the viewport rather than dead-center - center felt too
     low/disconnected from whatever the CMS action just happened near
     the top of the page. */
  padding-top: 25vh;
}

.cms-alert-content {
  background-color: #fff;
  border-radius: 8px;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
  width: 90%;
  max-width: 420px;
  overflow: hidden;
  font-family: 'Source Sans 3', sans-serif;
}

.cms-alert-header {
  background-color: var(--color-masthead-bg);
  color: rgb(252, 252, 245);
  font-family: 'Work Sans', sans-serif;
  font-weight: 700;
  font-size: 15px;
  padding: 12px 20px;
}

.cms-alert-message {
  margin: 0;
  padding: 20px;
  font-size: 16px;
  line-height: 1.4;
  color: var(--color-text-dark);
  white-space: pre-wrap;
}

.cms-alert-ok-btn {
  display: block;
  margin: 0 20px 20px auto;
  background-color: #256386;
  color: #fff;
  font-family: 'Work Sans', sans-serif;
}

/* cmsConfirm() (scripts/helper.js) - reuses .cms-alert-overlay/-content
   above for the overlay/box itself; only the header color and the
   button row differ from cmsAlert(), to flag these as the more
   serious/destructive action. Red matches the site's one established
   red (.delete-btn, label sup, rookie-card styling). */
.cms-confirm-header {
  background-color: #a83232;
  color: rgb(252, 252, 245);
  font-family: 'Work Sans', sans-serif;
  font-weight: 700;
  font-size: 15px;
  padding: 12px 20px;
}

.cms-confirm-btn-row {
  display: flex;
  justify-content: flex-end;
  gap: 12px;
  margin: 0 20px 20px 20px;
}

.cms-confirm-cancel-btn {
  font-family: 'Work Sans', sans-serif;
}

.cms-confirm-confirm-btn {
  background-color: #a83232;
  color: #fff;
  font-family: 'Work Sans', sans-serif;
}

/* Checklist display (waxReviews.html) - the public-facing "Checklist"
   link + modal, distinct from the CMS upload/review styles above */
.checklist-view-link {
  color: var(--color-link);
  font-family: 'Special Elite', sans-serif;
  font-weight: 700;
  text-decoration: underline;
  cursor: pointer;
}

.checklist-view-link:hover {
  color: var(--color-accent-hover);
}

.checklist-modal-overlay {
  display: none;
  position: fixed;
  z-index: 9999;
  inset: 0;
  background-color: rgba(0, 0, 0, 0.6);
  overflow-y: auto;
  padding: 40px 0;
}

.checklist-modal-content {
  background-color: #fff;
  margin: 0 auto 40px auto;
  padding: 24px 32px;
  border-radius: 8px;
  width: 75%;
  max-width: 1400px;
  /* Without this, width + padding stack additively (content-box is the
     default) - at the mobile breakpoint's width:92%/padding:16px 18px
     that rendered wider than the viewport itself, bleeding a few px
     off the right edge of the screen on real phones (e.g. iPhone 14). */
  box-sizing: border-box;
  box-shadow: 0 0 20px rgba(0, 0, 0, 0.3);
  font-family: 'Source Sans 3', sans-serif;
}

.checklist-modal-controls {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 16px;
  margin-bottom: 16px;
}

/* Same row as the set-name title, right-justified - see
   .checklist-modal-title below, which no longer carries its own
   bottom margin now that this row owns that spacing. */
.checklist-modal-title-row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  margin: 0 0 16px 0;
}

.checklist-modal-rc-filter {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
  font-family: 'Source Sans 3', sans-serif;
  font-weight: 700;
  font-size: 17px;
  color: #fff;
  background-color: #256386;
  border-radius: 20px;
  padding: 8px 16px;
  cursor: pointer;
}

.checklist-modal-rc-filter input[type="checkbox"] {
  width: 18px;
  height: 18px;
  accent-color: #2e8b57;
  cursor: pointer;
}

.checklist-modal-print-btn {
  font-family: 'Work Sans', sans-serif;
  background-color: #256386;
  color: white;
}

.checklist-modal-pdf-btn {
  font-family: 'Work Sans', sans-serif;
  background-color: #256386;
  color: white;
}

/* Buttons - one shared shape for every site/CMS button, placed after
   each button's own rule so it wins at equal specificity. Primary =
   filled + thin same-colour ring; secondary = white + grey border. */
.input-button,
.bulk-btn,
.cms-alert-ok-btn,
.cms-confirm-cancel-btn,
.cms-confirm-confirm-btn,
.checklist-modal-print-btn,
.checklist-modal-pdf-btn,
.autobus-send-btn {
  --btn-ring: #256386;
  border: 1px solid transparent;
  border-radius: var(--btn-radius);
  padding: 10px 20px;
  font-size: 15px;
  font-weight: 600;
  line-height: 1.2;
  cursor: pointer;
  box-shadow: 0 0 0 1px #fff, 0 0 0 2px var(--btn-ring);
  transition: filter 0.15s ease, background-color 0.15s ease;
}

.delete-btn,
.cms-confirm-confirm-btn {
  --btn-ring: #a83232;
}

.input-button:hover:not(:disabled),
.bulk-btn:hover:not(:disabled),
.cms-alert-ok-btn:hover,
.cms-confirm-confirm-btn:hover,
.checklist-modal-print-btn:hover,
.checklist-modal-pdf-btn:hover,
.autobus-send-btn:hover:not(:disabled) {
  filter: brightness(0.92);
}

.input-button:focus-visible,
.bulk-btn:focus-visible,
.cms-alert-ok-btn:focus-visible,
.cms-confirm-cancel-btn:focus-visible,
.cms-confirm-confirm-btn:focus-visible,
.checklist-modal-print-btn:focus-visible,
.checklist-modal-pdf-btn:focus-visible,
.autobus-send-btn:focus-visible {
  outline: 2px solid var(--btn-ring);
  outline-offset: 3px;
}

.input-button:disabled,
.bulk-btn:disabled,
.autobus-send-btn:disabled {
  opacity: 0.45;
  cursor: not-allowed;
}

/* Secondary - Cancel/Close (dismiss) actions */
.bulk-btn-cancel,
.cms-confirm-cancel-btn,
.btn-secondary {
  --btn-ring: var(--btn-secondary-border);
  background-color: #fff;
  color: var(--color-text-dark);
  border-color: var(--btn-secondary-border);
  box-shadow: none;
}

.bulk-btn-cancel:hover:not(:disabled),
.cms-confirm-cancel-btn:hover,
.btn-secondary:hover:not(:disabled) {
  background-color: var(--btn-secondary-hover);
  filter: none;
}

/* Compact - small toolbar buttons (the triggers on uploadChecklist.html
   keep their own ID-scoped padding) */
.checklist-modal-print-btn,
.checklist-modal-pdf-btn {
  padding: 6px 14px;
  font-size: 14px;
}

.checklist-modal-close {
  font-size: 32px;
  font-weight: bold;
  color: #444;
  cursor: pointer;
  line-height: 1;
}

.checklist-modal-close:hover {
  color: var(--color-accent-hover);
}

/* Scaled-down version of .wax-reviews-masthead's Bebas Neue treatment
   (same font/outline-text-shadow look) - a flat background color
   instead of that masthead's photographic one, both because a modal
   header has nowhere near that much room and because background
   images are unreliable in print output (suppressed by default in
   most browsers) and this masthead exists here specifically so a
   printed checklist keeps its branding. */
.checklist-modal-masthead {
  background-color: var(--color-masthead-bg);
  margin: 0 -32px 16px -32px;
  padding: 14px 32px;
}

.checklist-modal-masthead a {
  font-family: 'Bebas Neue';
  font-weight: 500;
  font-size: 40px;
  text-transform: uppercase;
  text-decoration: none;
  color: rgb(252, 252, 245);
  text-shadow:
    -1px -1px 0 var(--color-heading-outline),
     1px -1px 0 var(--color-heading-outline),
    -1px  1px 0 var(--color-heading-outline),
     1px  1px 0 var(--color-heading-outline);
}

.checklist-modal-title {
  font-family: 'Work Sans', sans-serif;
  font-weight: 700;
  font-size: 1.4rem;
  color: var(--color-text-dark);
  margin: 0;
}

.checklist-modal-cards {
  columns: 3;
  column-gap: 32px;
}

.checklist-modal-group-title {
  column-span: all;
  font-family: 'Work Sans', sans-serif;
  font-weight: 700;
  font-size: 1.1rem;
  color: var(--color-text-dark);
  border-bottom: 2px solid var(--color-input-border);
  margin: 20px 0 8px 0;
  padding-bottom: 4px;
}

.checklist-modal-cards .checklist-modal-group-title:first-child {
  margin-top: 0;
}

.checklist-modal-card {
  break-inside: avoid;
  padding: 3px 0;
  font-size: 15px;
  line-height: 1.4;
}

/* Print-only - see @media print below for the visible version */
.checklist-modal-card-checkbox {
  display: none;
}

.checklist-modal-print-footer {
  display: none;
}

.checklist-modal-card-num {
  color: var(--color-text-dark);
  font-weight: 700;
}

.checklist-modal-card-notes {
  color: #777;
  font-size: 0.85em;
}

@media (max-width: 600px) {
  .checklist-modal-content {
    width: 92%;
    padding: 16px 18px;
  }

  .checklist-modal-cards {
    columns: 1;
  }

  /* .checklist-modal-masthead's base rule cancels the desktop content
     box's 32px padding with a matching -32px negative margin so the
     masthead bar bleeds edge-to-edge. At this breakpoint the content
     box's own padding shrinks to 18px (above), so that same -32px
     overshoots by 14px a side, bleeding the masthead past the modal's
     (and on a narrow phone, the viewport's) edge - match it here. */
  .checklist-modal-masthead {
    margin: 0 -18px 16px -18px;
    padding: 14px 18px;
  }

  /* Not enough width for the title and the badge-style filter to sit
     side by side - stack them instead. */
  .checklist-modal-title-row {
    flex-direction: column;
    align-items: flex-start;
    gap: 10px;
  }

  .checklist-modal-rc-filter {
    align-self: flex-end;
  }
}

/* Scoped to body.checklist-modal-open (toggled in openChecklistModal()/
   closeChecklistModal(), scripts/wax.js) so printing the page normally
   - modal never opened - is completely unaffected. Without that scope,
   these rules would hide the whole page any time it's printed, modal
   open or not, since #checklistModalOverlay would still be empty. */
@media print {
  body.checklist-modal-open > *:not(#checklistModalOverlay) {
    display: none !important;
  }

  body.checklist-modal-open .checklist-modal-overlay {
    position: static;
    background: none;
    padding: 0;
    overflow: visible;
  }

  body.checklist-modal-open .checklist-modal-content {
    box-shadow: none;
    border-radius: 0;
    width: 100%;
    max-width: none;
    margin: 0;
    padding: 0;
  }

  body.checklist-modal-open .checklist-modal-masthead {
    margin: 0 0 16px 0;
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  body.checklist-modal-open .checklist-modal-cards {
    columns: 2;
  }

  .checklist-modal-controls,
  .checklist-modal-rc-filter {
    display: none !important;
  }

  .checklist-modal-card-checkbox {
    display: inline-block;
    width: 10px;
    height: 10px;
    border: 1px solid #000;
    margin-right: 6px;
    vertical-align: middle;
  }

  .checklist-modal-print-footer {
    display: block;
    margin-top: 24px;
    padding-top: 8px;
    border-top: 1px solid #ccc;
    font-family: 'Source Sans 3', sans-serif;
    font-size: 12px;
    color: #666;
    text-align: center;
  }
}

/**********************************************************
*********************** S3 BUCKET MODAL *******************
***********************************************************/

/* The Modal (background) */
.modal {
  display: none; /* Hidden by default */
  position: fixed; /* Stay in place */
  z-index: 1000; 
  left: 0;
  top: 0;
  width: 100%; /* Full width */
  height: 100%; /* Full height */
  overflow: auto; /* Enable scroll if needed */
  background-color: rgb(0,0,0); /* Fallback color */
  background-color: rgba(0,0,0,0.4); /* Black w/ opacity */
}

/* Modal Content/Box */
.modal-content {
  background-color: #fefefe;
  margin: 5% auto;
  padding: 20px 30px;
  border: 1px solid #888;
  width: 900px;
  max-width: 90%;
  border-radius: 8px;
  box-shadow: 0 0 20px rgba(0,0,0,0.3);
  font-family: 'Source Sans 3', sans-serif;
}

/* Image list grid */
#imageList {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
  margin-top: 20px;
}

/* The Close Button */
.close {
  color: #aaa;
  float: right;
  font-size: 28px;
  font-weight: bold;
}

.close:hover,
.close:focus {
  color: var(--color-accent-hover);
  text-decoration: none;
  cursor: pointer;
}

/*************************************** Pagination Styles... ********************************/
.pagination-link {
  font-family: 'Work Sans', sans-serif;
  font-size: 1.4rem;
  color: var(--color-link);
  text-decoration: none;
  margin: 0 15px;
  cursor: pointer;
  font-weight: bold;
}

.pagination-link:hover {
  text-decoration: underline;
}

.pagination-link.disabled {
  color: #999;
  pointer-events: none;
  text-decoration: none;
  cursor: default;
}

.pagination-page {
  font-family: 'Work Sans', sans-serif;
  font-size: 1.2rem;
  margin: 0 10px;
  color: #444;
}

.pagination-setname-short {
  display: none;
}

/*************************************** Vote Widget Styles... ********************************/
.vote-widget {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 20px;
  margin: 10px 0;
}

.vote-btn {
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 16px;
  background-color: #fff;
  border: 1px solid var(--color-text-dark);
  border-radius: 20px;
  padding: 8px 16px;
  cursor: pointer;
  color: var(--color-text-dark);
  transition: background-color 0.15s ease, transform 0.1s ease;
}

.vote-btn:hover:not(:disabled) {
  background-color: var(--color-page-bg);
}

.vote-btn:active:not(:disabled) {
  transform: scale(0.96);
}

.vote-btn.voted {
  background-color: var(--color-text-dark);
  color: #fff;
}

.vote-btn:disabled {
  cursor: default;
  opacity: 0.7;
}

.vote-count {
  font-weight: bold;
}

/*************************************** Player Search Styles... ********************************/
/* The global `form { padding-left: 1.5%; }` rule (written for the CMS
   forms) also applies here - override it so the label/input line up
   with the plain text above/below rather than sitting indented past
   it. Scoped under #player-search-form rather than editing the shared
   rule, same pattern as other .flex-container-related fixes - see
   FRONTEND.md's Mobile / responsive design gotchas. */
/* Tighter than the shared .flex-container div's 15px/5px padding+margin
   and the browser's default <p> margins - this page's intro is a short
   two-line blurb, not a big content block, so the generic spacing left
   too much air above/below it. */
#player-search-intro {
  padding-top: 8px;
  padding-bottom: 8px;
}

#player-search-intro p {
  margin-top: 0;
  margin-bottom: 0;
}

#player-search-form {
  padding-top: 8px;
}

#player-search-form form {
  padding-left: 0;
}

#player-search-form input[type="text"] {
  width: 100%;
  max-width: 450px;
}

/* #player-search-form prefix (id specificity) beats the shared
   .flex-container div descendant selector, which otherwise also
   matches this nested div and pushes the actual input box 20px right
   of the label/button/intro text with its 15px padding + 5px margin -
   same recurring gotcha as #playerSearchResults .player-search-group
   above. */
#player-search-form .player-search-input-wrap {
  position: relative;
  width: 100%;
  max-width: 450px;
  padding: 0;
  margin: 0;
}

.player-search-suggestions {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 100;
  margin: 2px 0 0 0;
  padding: 4px 0;
  list-style: none;
  background-color: #fff;
  border: 1px solid var(--color-input-border);
  border-radius: 4px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  max-height: 260px;
  overflow-y: auto;
}

.player-search-suggestion {
  padding: 8px 12px;
  cursor: pointer;
  font-family: 'Source Sans 3', sans-serif;
}

.player-search-suggestion:hover,
.player-search-suggestion.active {
  background-color: var(--color-page-bg);
}

.player-search-message,
.player-search-summary {
  font-family: 'Work Sans', sans-serif;
}

/* #playerSearchResults prefix (id specificity) beats the bare
   .flex-container div descendant selector, which otherwise also
   matches this nested div and forces width:1000px/padding:15px/
   margin:5px onto it - same recurring gotcha documented in
   FRONTEND.md (the set-o-matic picker, the footer caption). Without
   this, every result group also overflows its container to the left,
   since forcing children to width:1000px each defeats the outer
   #playerSearchResults div's own flex-shrink. */
#playerSearchResults .player-search-group {
  width: auto;
  padding: 0 0 16px 0;
  margin: 24px 0;
  border-bottom: 1px solid var(--color-input-border);
}

.player-search-set-name {
  font-family: 'Work Sans', sans-serif;
  margin-bottom: 8px;
}

.player-search-set-name a {
  color: var(--color-link);
  text-decoration: underline;
}

.player-search-no-review {
  font-size: 0.85em;
  font-weight: normal;
  color: var(--color-text-dark);
  opacity: 0.7;
}

.player-search-card-list {
  list-style: none;
  padding-left: 0;
  margin: 0;
}

.player-search-card-list li {
  font-family: 'Source Sans 3', sans-serif;
  padding: 4px 0;
}

.player-search-card-notes {
  font-size: 0.85em;
  opacity: 0.75;
}

/* Rookie cards (RC in the notes column) are the most sought-after -
   call them out instead of blending in with every other marker. Same
   red as .delete-btn/label sup elsewhere on the site. */
.player-search-card-notes-rc {
  font-weight: bold;
  color: #a83232;
  opacity: 1;
}

/*************************************** Admin Tools Styles... ********************************/
.admin-tool-card {
  max-width: 900px;
  margin: 0 0 32px 0;
  padding-bottom: 24px;
  border-bottom: 1px solid var(--color-input-border);
  font-family: 'Work Sans', sans-serif;
}

.admin-tool-card h2 {
  font-family: 'Source Sans 3', sans-serif;
}

.admin-status-msg {
  font-weight: bold;
  margin: 8px 0;
}

.admin-results-table {
  width: 100%;
  border-collapse: collapse;
  font-family: 'Source Sans 3', sans-serif;
  font-size: 15px;
}

.admin-results-table th,
.admin-results-table td {
  text-align: left;
  padding: 6px 10px;
  border-bottom: 1px solid var(--color-input-border);
  vertical-align: top;
}

.admin-results-url {
  word-break: break-all;
}

.admin-results-list {
  font-family: 'Source Sans 3', sans-serif;
  font-size: 15px;
}


.masthead-container {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  padding: 15px 20px;
  background-color: var(--color-masthead-bg);
  flex-wrap: nowrap;
}

.weather-box {
  font-size: 1rem;
  color: rgb(169, 220, 243);
  text-align: left;
  max-width: 500px;
  word-break: break-word;
  overflow-wrap: anywhere;
  margin-left: auto;
}

/* Let's make sure the fonts are always applied */
.weather-box,
.weather-full,
.weather-condensed {
  font-family: 'Work Sans', sans-serif;
}

/* ============================================
   PREVIEW MODAL — OVERLAY + CONTENT BOX
   Completely isolated from the CMS image-picker modal
   ============================================ */

/* Modal overlay */
.preview-modal {
  display: none;               /* Hidden by default */
  position: fixed;
  z-index: 9999;
  inset: 0;                    /* shorthand for top/left/right/bottom: 0 */
  background-color: rgba(0,0,0,0.6);
  overflow-y: auto;
  padding-top: 40px;
}

/* Modal content box */
.preview-modal-content {
  background-color: #dbeff8;
  margin: 40px auto;
  padding: 20px 30px;
  border-radius: 8px;
  width: 1000px; /* Match the width of the live site's flex container */
  box-shadow: 0 0 20px rgba(0,0,0,0.3);
  font-family: 'Source Sans 3', sans-serif;
  font-size: 18px;
  font-weight: 400; /* Light */
}

/* Base typography for the modal. Deliberately NOT a `.preview-modal *`
   blanket reset: that killed the real .set-details-* styling inside
   #previewContainer, which then had to be re-added by hand for every
   markup change - the mechanism behind preview/production drift. */
.preview-modal {
  font-family: 'Source Sans 3', sans-serif;
  font-size: 18px;
  font-weight: 400; /* Light */
  text-align: left;
}

/* Close button */
.preview-modal .close {
  float: right;
  font-size: 32px;
  font-weight: bold;
  color: #444;
  cursor: pointer;
}
.preview-modal .close:hover {
  color: var(--color-accent-hover);
}

/*  Add Subscriber Modal */
.add-subscriber-form {
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-bottom: 4px;
}

.add-subscriber-label {
  font-family: 'Work Sans', sans-serif;
  font-weight: 700;
  font-size: 0.88rem;
  color: #333;
  margin-top: 10px;
}

.add-subscriber-input {
  font-family: 'Source Sans 3', sans-serif;
  font-size: 0.95rem;
  padding: 8px 10px;
  border: 1px solid #ccc;
  border-radius: 3px;
  color: #222;
  width: 100%;
  box-sizing: border-box;
  transition: border-color 0.15s;
}

.add-subscriber-input:focus {
  outline: none;
  border-color: #555;
}


/* ****************************************************************************************************
   ********************************     PREVIEW CONTENT — CARD-SET STYLING ****************************
                                  Matches the live site, scoped only to preview
   ****************************************************************************************************/

/* #previewContainer renders the same markup as the live site (see
   buildCardSetMarkup() in helper.js), so it inherits the real
   .set-details-* / .table-header-img rules. Only the author table
   needs anything here - it isn't inside .flex-container, so the
   #cardSetDiv-scoped width resets don't reach it. */
#previewContainer table.set-details-author {
  width: 100%;
  border-collapse: collapse;
  font-size: 18px;
  line-height: 1.4;
  font-family: 'Source Sans 3', sans-serif;
  font-weight: 400; /* Light */
}

/* General table cell styling */
#previewContainer td {
  padding: 2px 4px;
  font-size: 18px;
  text-align: left;
}

/* Caption styling */
.preview-modal #previewContainer p.caption {
  font-family: "Special Elite" !important;
  font-size: 16px !important;
  font-weight: bold !important;
  text-align: left !important;
  margin: 0 !important;
  padding: 0 !important;
}








/* ========================================================================================================================
///////////////// MOBILE RESPONSIVE STYLES ////////////////////////////////////////////////////////////////////////
======================================================================================================================== */
@media (max-width: 600px) {

/* ============================
   GLOBAL / SITE-WIDE
   ============================ */

  body {
    font-size: 16px;
  }

  /* Wrap images opted into .img-wrap-sm/.img-wrap-md render at half or
     65% of their desktop size on mobile - see the base rule
     near .img-wrap-left. --wrap-w/--wrap-h are set by
     applyImgWrapSmSizing() (helper.js) from each image's own
     width/height attribute, so this is a real box resize (text
     reflows in tight) rather than a visual-only transform: scale(),
     which left the original full-size box reserved and an
     unacceptable gap next to the shrunk image. */
  .set-details-author img.img-wrap-sm {
    width: calc(var(--wrap-w) / 2) !important;
    height: calc(var(--wrap-h) / 2) !important;
  }

  .set-details-author img.img-wrap-md {
    width: calc(var(--wrap-w) * 0.65) !important;
    height: calc(var(--wrap-h) * 0.65) !important;
  }

  /* Flex container should not force 1000px width */
  .flex-container div {
    width: 100%;
    padding: 10px;
    margin: 0;
    box-sizing: border-box;
  }

  /* Tables should scroll instead of overflow */
  table {
    width: 100%;
    display: block;
    overflow-x: auto;
  }

  /* Simple "Home / Back to CMS" nav table used on several pages
     (createBlogPost.html, createCardSet.html, etc.) */
  .top-nav {
    font-size: 24px;
  }

/* ============================
   HOME PAGE & BLOG STREAM (index.html, tech.html)
   ============================ */

  /* Blog intro */
  .intro {
    width: 100%;
    font-size: 18px;
    padding: 0 10px;
    box-sizing: border-box;
  }

  /* Blog images */
  .blog-img {
    width: 100%;
    max-width: 100%;
    padding: 0;
  }

  /* Blog entry container */
  .blog-entry {
    font-size: 18px;
    padding: 10px;
  }

  /* Pagination */
  .pagination-link {
    font-size: 1rem;
    margin: 0 8px;
  }

  .pagination-page {
    font-size: 0.9rem;
  }

  .pagination-setname-full {
    display: none;
  }

  .pagination-setname-short {
    display: inline;
  }

  /* Masthead & Weather Mobile Styles (index.html only - .masthead-container
     is unique to that page). Scoped to .masthead-container .masthead
     specifically - a bare .masthead rule here would collide with the
     CMS/tech.html masthead rule below (same specificity, so whichever
     came later in the file would silently win for shared properties
     like font-size on every page, not just this one). */
  .masthead-container {
    flex-direction: row;         /* keep horizontal layout */
    justify-content: space-between;
    align-items: flex-start;
    flex-wrap: nowrap;
  }

  .masthead-container .masthead {
    padding-left: 2px;
    font-size: 10vw;
    white-space: nowrap;
  }

  /* flex:1 so this actually claims the leftover row width as real box
     width, instead of margin-left:auto pushing it right while the box
     itself stays shrink-wrapped to its content (the previous approach
     turned unused space into invisible margin instead of usable room) */
  .weather-box {
    font-size: 0.75rem;
    flex: 1;
    max-width: 70%;
    text-align: center;
    padding-left: 10px;
    box-sizing: border-box;
  }

  /* #weather is display:flex (base rule, justify-content:left) since
     the element carries both id="weather" and class="weather-box" - the
     text-align:center above does nothing because its children are flex
     items, not inline text. Override the actual alignment mechanism. */
  #weather {
    justify-content: center;
  }

  .weather-full { display: none; }
  .weather-condensed { display: block; }

/* ============================
   cardStack CMS SHARED CHROME (wlcms.html, createBlogPost.html,
   createCardSet.html, blogEdit.html, setEdit.html, pickBlog.html,
   pickCardSet.html) - also tech.html for the masthead/mast-table rules,
   since it reuses the same masthead markup
   ============================ */

  /* Set picker */
  .cms-set-picker {
    width: 100%;
    margin-left: 0;
  }

  /* cardStack/Autobus CMS top nav (wlcms.html, smsAdmin.html) */
  .cms-top-nav {
    font-size: 20px;
    margin: 10px 0;
    padding: 10px 0;
  }

  .cms-top-nav tr {
    gap: 8px;
  }

  .cms-nav-td {
    font-size: 16px;
    padding: 10px 14px;
  }

  /* wlcms.html dropdown/flyout nav - stack the parents full-width and
     turn each flyout into an inline accordion instead of an absolutely
     positioned overlay, which doesn't have room to sit next to its
     parent at mobile widths */
  .cms-dropdown-nav {
    flex-direction: column;
    gap: 0;
    margin: 10px 0;
    padding: 10px 0;
  }

  .cms-nav-item {
    width: 100%;
  }

  .cms-nav-parent,
  .cms-nav-item-plain > a {
    font-size: 18px;
    padding: 10px 14px;
  }

  .cms-nav-dropdown {
    position: static;
    width: auto;
    min-width: 0;
    margin-left: 14px;
    border-left: 3px solid var(--color-input-border);
    border-radius: 0;
    box-shadow: none;
  }

  .cms-nav-dropdown a {
    font-size: 18px;
    padding: 8px 14px;
  }

  /* cardStack CMS masthead (shared across every cms/*.html page) - a
     real height (not auto) so height:100% on any img inside the row has
     something to compute against; auto height makes percentage-height
     children fall back to their native size instead. Scaled to roughly
     match the 14vw masthead font. */
  .mast-table tr {
    height: 16vw;
  }

  .masthead {
    font-size: 14vw;
    text-align: center;
    padding: 8px 10px 4px 10px;
  }

  /* Hide the "Content Management System" subtitle on mobile rather than
     squeezing a fixed 40px font into a 20%-width table column */
  .cms-logo {
    display: none;
  }

/* ============================
   AUTOBUS MESSAGING PLATFORM (smsAdmin.html)
   ============================ */

  /* Autobus Messaging Platform masthead - same treatment as the
     cardStack masthead above */
  .autobus-mast-table tr {
    height: auto;
  }

  .autobus-masthead img {
    max-width: 100%;
    height: auto;
  }

  .autobus-cms-logo {
    display: none;
  }

  /* Autobus form/results two-column layout - stack on mobile instead of
     squeezing both columns to roughly half the screen width.
     align-items:flex-start (desktop, base rule) controls vertical
     alignment in row direction, but becomes horizontal sizing once
     flex-direction is column - override to stretch so the stacked
     columns fill the full width instead of shrinking to content */
  .autobus-two-col {
    flex-direction: column;
    align-items: stretch;
    gap: 20px;
  }

  .autobus-form,
  .autobus-results {
    max-width: 100%;
    margin-left: 0;
  }

  .autobus-left {
    padding-top: 0;
  }

/* ============================
   waxReviews.html - CARD INTRO
   ============================ */

  /* renderCardIntro() (wax.js) still runs on load - this just hides the
     result, so no new responsive pattern is needed beyond the site's
     existing single-breakpoint CSS approach. Scoped to the #card-intro
     id (not the shared .intro class) since that class is also used for
     the real blog intro on index.html/tech.html and the "404 - Season
     Not Found" text on lockout.html, neither of which should be hidden. */
  #card-intro {
    display: none;
  }

  /* Set name heading, right under the hamburger menu, sized to match
     .set-details-name's 20px. Only actually visible on lockout.html
     now - waxReviews.html hides this same #pageHeader element on every
     breakpoint via .wax-set-name-header (see the base-CSS rule near
     .header-style h1), since its set-details section repeats the name
     as its own heading. Scoped to the #pageHeader id, not
     .header-style h1 generally - that class/tag pair is shared with
     playerSearch.html, theJunkWaxYears.html, and several CMS pages,
     none of which should be affected by a change meant for the
     set-review pages only. */
  #pageHeader {
    font-size: 20px;
  }

/* ============================
   waxReviews.html - SET-O-MATIC YEAR PICKER
   ============================ */

  .set-o-matic-picker {
    font-size: 20px;
    height: auto;
    padding: 8px 0;
  }

  #set-picker .card-set-nav {
    font-size: 16px;
    gap: 2px;
  }

  /* Fixed basis so every row lines up into the same 3 columns, and the
     active (unlinked) year gets the same box as the linked years */
  #set-picker .junk-set-nav-td {
    flex: 0 0 30%;
    max-width: 30%;
    box-sizing: border-box;
    padding: 2px 10px;
  }

/* ============================
   waxReviews.html - CARD SET REVIEW CONTENT
   ============================ */

  .wax-reviews-masthead a {
    font-size: 56px;          /* Scales down from 128px */
    height: 90px;             /* Matches reduced text size */
    padding-left: 12px;       /* Keeps left alignment tight */
    /* Vertical centering comes from the base rule's align-items:center
       (flexbox) - a manual padding-top here was fighting that and
       visibly skewing it off-center, since mobile's shorter text has
       much more slack in its box than desktop's does */
    /* 62px (tried when bumping this up for stripe contrast) wrapped to
       two lines on a real iPhone 15 - a headless-browser check at the
       same 393px CSS width didn't reproduce it. Likely cause: iOS
       Safari's automatic text-inflation quirk, which specifically
       targets text sized by auto-layout containers like a <table>/<td>
       with no explicit width (exactly this markup) and can render text
       larger than its specified px size - something Chromium doesn't
       replicate, hence the gap between this test and the real device.
       text-size-adjust:100% below disables that inflation so the
       rendered size actually matches what's specified here. Kept
       white-space:nowrap as a second guard regardless. */
    -webkit-text-size-adjust: 100%;
    text-size-adjust: 100%;
    white-space: nowrap;
    text-shadow:
      -1px -1px 0 var(--color-heading-outline),
       1px -1px 0 var(--color-heading-outline),
      -1px  1px 0 var(--color-heading-outline),
       1px  1px 0 var(--color-heading-outline);
  }

  /* The extra dark outline for two-color teams (Detroit/Tampa Bay/
     Toronto - see the base .masthead-two-color rule) exists because the
     centered white stripe there is wide enough to swallow the title's
     near-white fill on desktop. On mobile the title is small enough,
     and the stripe proportionally narrow enough, that the plain
     outline above already reads fine - drop back to it instead of the
     heavier one. */
  .wax-reviews-mast-table.masthead-two-color .wax-reviews-masthead a {
    text-shadow:
      -1px -1px 0 var(--color-heading-outline),
       1px -1px 0 var(--color-heading-outline),
      -1px  1px 0 var(--color-heading-outline),
       1px  1px 0 var(--color-heading-outline);
  }

  .wax-reviews-mast-table {
    height: 90px;             /* Match the reduced masthead height */
  }

  /* City/cheer corner label (applyRandomMastheadTeam(), helper.js) -
     hidden on mobile per the site owner, not just shrunk. */
  .masthead-team-label {
    display: none;
  }

  .nhl-ticker {
    height: 36px;
    font-size: 13px;
  }

  .nhl-chip {
    gap: 8px;
    padding: 0 12px;
  }

  .nhl-team img {
    width: 33px;
    height: 22px;
  }

  .ticker-league-logo {
    margin-left: 12px;
  }

  .ticker-league[data-league="nhl"] .ticker-league-logo {
    width: 39px;
    height: 26px;
  }

  .ticker-league[data-league="pwhl"] .ticker-league-logo {
    width: 66px;
    height: 14px;
    margin-left: 19px;
  }

  .ticker-league[data-league="pwhl"] .nhl-team img {
    width: 22px;
    height: 22px;
    margin-right: 6px;
  }

  .nhl-game-scoreline {
    gap: 8px;
  }

  .nhl-game-team {
    flex-direction: column;
    gap: 2px;
  }

  .nhl-game-side-home .nhl-game-team {
    flex-direction: column;
  }

  .nhl-game-team img {
    width: 54px;
    height: 36px;
  }

  .nhl-game-team-text,
  .nhl-game-side-home .nhl-game-team-text {
    align-items: center;
  }

  .nhl-game-abbrev {
    font-size: 20px;
  }

  .nhl-game-record {
    font-size: 12px;
  }

  .nhl-game-score {
    font-size: 36px;
  }

  .nhl-game-status {
    font-size: 13px;
  }

  .nhl-game-tabs [role="tab"] {
    font-size: 14px;
    padding: 10px 4px;
  }

  .nhl-goal-time {
    width: 38px;
    font-size: 14px;
  }

  .nhl-game-row-note {
    font-size: 12px;
  }

  /* Undo the site-wide mobile "table { display: block }" - as a
     block, rows stop stretching to the full width. The line score
     already scrolls inside .nhl-linescore-wrap. */
  .nhl-linescore,
  .nhl-team-stats {
    display: table;
  }

  .set-details-table-style {
  width: 100%;
  table-layout: auto;
  }

  /**/
  .set-details-table-style tr {
    display: block;
    width: 100%;
  }

  .set-details-table-style td {
  display: table-cell;
  table-layout: fixed;
  margin: 0; /* Remove side margins */
  font-family: 'Source Sans 3', sans-serif;
  font-size: 18px;
  line-height: 1.4;
  text-align: left;
  padding: 2px 4px; /* Reduce vertical and horizontal padding */
  width: auto;
}

  .table-header-img {
  display: block;
  margin: 0 auto;
  max-width: 320px; /* adjust as needed */
  width: 100%;
}

  /* .set-details-grid: reorder to name -> image -> list, one column.
     No table/rowspan involved, so this is a plain grid redefinition -
     see the base rule (near .table-header-img) for why this replaced
     the old table markup. */
  .set-details-grid {
    grid-template-columns: 1fr;
    grid-template-areas:
      "name"
      "image"
      "list";
  }

  /* Cancels the base rule's min-height: stacked here, so there's no
     left-hand column for the image to be centred against. */
  .set-details-image {
    min-height: 0;
  }

  /* Breathing room between the set name and the header image below it -
     only needed here, since on desktop the name sits above the details
     list (in its own column), not directly above the image. Scoped
     under #cardSetDiv for the same reason as .set-details-list below. */
  #cardSetDiv .set-details-name {
    margin-bottom: 10px;
  }

  /* Breathing room between the image and "Set Size" - only needed here,
     since on desktop the list sits beside the image, not below it.
     Scoped under #cardSetDiv to beat that same-named rule's own
     margin:0 reset above (id+class specificity, needed regardless of
     media-query order - see the .flex-container div note nearby).
     The Checklist-after-Hella-Rating reorder (.set-detail-row-checklist)
     is universal now (base rule, applies desktop and mobile alike) -
     see near .set-detail-row. */
  #cardSetDiv .set-details-list {
    margin-top: 12px;
  }


  .set-footer-table-style {
    width: 100%;
  }

  /* Centered via the parent's text-align:center (inline-block respects that
     reliably) rather than width:100%+max-width+margin:auto, since that
     combination wasn't resolving correctly here */
  .table-footer-img {
    display: inline-block;
    vertical-align: top;
    margin: 10px 0 0 0;
    width: 100%;
    max-width: 360px;
    box-sizing: border-box; /* base rule's border:1px was adding 2px on
      top of width:100%, same overflow class of bug as the td padding */
  }

  /* Used inline within some stored review bodies (postBody content) */
  .card-table-style td {
    font-size: 12px;
    padding: 2px 1px;}

  /* Vote widget - the "Love this set!"/"Not a fan..." labels need room
     to breathe on narrow screens */
  .vote-widget {
    gap: 10px;
  }

  .vote-btn {
    font-size: 14px;
    padding: 8px 12px;
  }

} /* END MOBILE RESPONSIVE */


/* Tablet + mobile: keep the nav collapsed into the hamburger menu. The
   full table nav (one <td> per NAV_ITEMS entry) doesn't have room to
   lay out on one line below desktop widths - it shrinks each cell
   until label text wraps mid-word instead of overflowing cleanly, so
   this reuses the same hamburger treatment as phone widths rather than
   building a separate cramped-but-not-wrapped layout just for tablets.
   1400px (not 1024px) because current iPads' landscape CSS viewport
   width ranges from ~1080px (mini) up to 1366px (12.9" Pro) - 1024px
   was the old "classic iPad landscape" assumption and left every
   modern iPad showing the wrapped desktop nav in landscape. */
@media (max-width: 1400px) {
  .nav-links {
    display: none;
    width: fit-content;
    background-color: var(--color-masthead-bg);
  }

  .nav-links.open {
    display: block;
  }

  .hamburger {
    font-size: 32px;
    cursor: pointer;
    padding: 10px;
    color: var(--color-link);
    display: block;
  }

  /* The 70px base value (styles.css, non-mobile-scoped) is sized for
     desktop's full nav table; the hamburger icon only needs ~58px
     (32px font + 10px top/bottom padding), leaving a visible gap
     before the page content below it */
  #global-nav-placeholder {
    height: 58px;
  }

  .nav-table {
    width: 100%;
  }

  .nav-table tr {
    display: flex;
    flex-direction: column;
    width: 100%;
  }

  .nav-td {
    display: block;
    width: 100%;
    padding: 0;
    margin: 0;
    text-align: left;
    font-size: 0.9rem;
    border-bottom: 1px solid rgba(255,255,255,0.2);
  }

  /* Padding moved here (from .nav-td above) so the whole row is
     clickable, not just the text itself */
  .nav-td a {
    display: block;
    width: 100%;
    box-sizing: border-box;
    padding: 12px 16px;
    color: #fff;
  }
}

/* Tablet only: the hamburger icon and menu sizes above were tuned for
   phone widths and look undersized on a much bigger tablet screen -
   scale both up. Phone (<=600px) keeps the smaller sizes from the
   block above. */
@media (min-width: 601px) and (max-width: 1400px) {
  .hamburger {
    font-size: 48px;
    padding: 14px;
  }

  #global-nav-placeholder {
    height: 76px;
  }

  .nav-td {
    font-size: 1.3rem;
  }

  .nav-td a {
    padding: 18px 24px;
  }
}


/* Hide the mobile-condensed weather text above phone width (was
   previously unconditional/unscoped - same specificity as the mobile
   "display: block" rule for .weather-condensed and later in the file,
   so it silently won on mobile too, hiding the weather widget entirely
   there. Same bug shape as the .masthead conflict.) */
@media (min-width: 601px) {
  .weather-condensed {
    display: none;
  }
}

/* Desktop only: hide the hamburger and show the normal table nav.
   Tablets stay on the hamburger nav above (max-width: 1400px) - see
   the comment there for why 1400px rather than the more obvious-looking
   1024px. */
@media (min-width: 1401px) {
  .hamburger {
    display: none;
  }

  .nav-links {
    display: block;
  }
}










