/* ============================================================================
   OS.TV — CANONICAL CARD SYSTEM (the ONE card system for every module).
   Three variants over one base: content · channel · network (+ poster modifier).
   Anatomy: .os-card > .os-card__media > (.os-card__image, .os-card__badge*) + .os-card__body > (.os-card__title, .os-card__meta, .os-card__source).
   ⛔ No module may define its own card width, thumbnail ratio, or badge slots. Module CSS may only add decorations.
   ============================================================================ */
:root {
  --os-card-width: 224px;
  --os-card-radius: 12px;
  --os-card-gap: 14px;
  --os-thumb-ratio-content: 16 / 9;
  --os-thumb-ratio-channel: 16 / 9;
  --os-thumb-ratio-poster: 2 / 3;
  --os-card-bg: #0f1d31;
  --os-card-bd: #23405f;
  --os-accent: #12d39a;
}

/* ── Canonical grid — SAME column width on every equivalent surface (Home rails, IPTV, OTA, WWBN videos/channels, SearchTube).
   min(width,100%) guarantees a track never exceeds its container, so grids always reflow (never overflow/clip) at any width. */
.os-grid, .iptv-grid, .ostv-grid, .ostv-chan-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(min(var(--os-card-width), 100%), 1fr)); gap: var(--os-card-gap); min-width: 0;
}
.os-grid--poster, .ent-grid { display: grid; gap: var(--os-card-gap); grid-template-columns: repeat(auto-fill, minmax(min(150px, 100%), 1fr)); min-width: 0; }   /* Movies & Shows posters (2:3) */

/* Responsive density — cards shrink as the viewport narrows so every surface keeps a sensible column count (never 1 huge card / never clipped). */
@media (max-width: 1360px) { :root { --os-card-width: 200px; } }
@media (max-width: 1024px) { :root { --os-card-width: 184px; } }
@media (max-width: 640px)  { :root { --os-card-width: 158px; --os-card-gap: 11px; } }
@media (max-width: 380px)  { :root { --os-card-width: 140px; } }

/* Phones: ONE full-width card per row for the wide channel/video/content grids — a clipped partial 2nd card is
   worse than one clean card (standard mobile pattern). MUST live here in cards.css (loaded after ostv.css) so it
   overrides the base .os-grid auto-fill rule above. Posters (.ent-grid/.os-grid--poster) stay multi-up — they're narrow. */
@media (max-width: 480px) {
  .os-grid, .iptv-grid, .ostv-grid, .ostv-chan-grid, .chan-grid, .soc-grid, .soc-connect, .apps-grid, .ostv-stats {
    grid-template-columns: 1fr;
  }
}
.rail-row { display: flex; gap: var(--os-card-gap); overflow-x: auto; padding:10px;}
.rail-row > .os-card { flex: 0 0 var(--os-card-width); }

/* ── Card shell ─────────────────────────────────────────────────────────── */
.os-card {
  background: var(--os-card-bg); border: 1px solid var(--os-card-bd); border-radius: var(--os-card-radius);
  overflow: hidden; cursor: pointer; outline: none; display: flex; flex-direction: column; text-decoration: none;
  color: inherit; transition: border-color .12s, transform .12s;
}
.os-card:hover { border-color: var(--os-accent); transform: translateY(-2px); }
.os-card:focus, .os-card:focus-visible, [data-content-id]:focus-visible { border-color: var(--os-accent); box-shadow: 0 0 0 2px var(--os-accent); }
.os-card[aria-selected="true"] { border-color: var(--os-accent); box-shadow: 0 0 0 2px var(--os-accent); }

/* ── Media (thumbnail) — fixed ratio; badges in fixed slots ───────────────── */
.os-card__media {
  position: relative; aspect-ratio: var(--os-thumb-ratio-content); background: #0a1526;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
}
.os-card__image { width: 100%; height: 100%; object-fit: cover; display: block; }
.os-card__media--noimg { color: #3d5674; font-size: 26px; }
/* Channels: logos must FIT inside the box (not crop-fill like a poster) on a neutral panel. */
.os-card--channel .os-card__media { aspect-ratio: var(--os-thumb-ratio-channel); background: #0b1626; }
.os-card--channel .os-card__image { /*object-fit: contain;  padding: 12px; */}
/* Networks: same, slightly more inset. */
.os-card--network .os-card__media { aspect-ratio: 16 / 9; background: #0b1626; }
.os-card--network .os-card__image { object-fit: contain; padding: 16px; }
/* Posters (Movies & Shows): 2:3, cover. */
.os-card--poster .os-card__media { aspect-ratio: var(--os-thumb-ratio-poster); }
.os-card--poster .os-card__image { object-fit: cover; }

.os-card__badge { position: absolute; z-index: 1; font-size: 10px; font-weight: 800; padding: 2px 7px; border-radius: 5px; letter-spacing: .04em; }
.os-card__badge--tl { top: 7px; left: 7px; background: #ff3b47; color: #fff; }                                   /* LIVE */
.os-card__badge--tr { top: 7px; right: 7px; background: rgba(18,211,154,.92); color: #04211a; }                  /* confidence % */
.os-card__badge--bl { bottom: 6px; left: 6px; background: #0e1826cc; color: #9fb4c9; border: 1px solid #2c4260; font-weight: 700; } /* CH # */
.os-card__badge--br { bottom: 6px; right: 6px; background: #000a; color: #e8eef6; font-weight: 700; }            /* duration */
.os-card__health { position: absolute; top: 9px; left: 9px; width: 8px; height: 8px; border-radius: 50%; box-shadow: 0 0 0 2px #0a1526; z-index: 1; }

/* ── Body — consistent metadata hierarchy + min-height so titles align across the grid ───────────────────────── */
.os-card__body { padding: 9px 11px; display: flex; flex-direction: column; gap: 5px; min-height: 66px; }
.os-card__title { font-size: 13px; font-weight: 700; color: #dbe6f2; line-height: 1.25; margin: 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.os-card__meta { font-size: 11.5px; color: #c6d4e2; display: flex; align-items: center; gap: 5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.os-card__source { font-size: 11px; color: #8ea3ba; display: flex; align-items: center; gap: 5px;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.os-card__meta i, .os-card__source i { font-size: 10px; color: var(--os-accent); }
.os-card__price { font-size: 11.5px; color: var(--os-accent); font-weight: 700; }
/* Taxonomy chips — the fourth dimension (WHAT the content is about). Primary = accent-tinted, secondary = muted. */
.os-card__topics { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 5px; }
.os-card__topic { font-size: 9.5px; line-height: 1.5; font-weight: 600; letter-spacing: .02em; padding: 0 7px;
  border-radius: 10px; color: var(--os-accent); background: rgba(18, 211, 154, .1); border: 1px solid rgba(18, 211, 154, .3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.os-card__topic--sec { color: #8ea3ba; background: rgba(255, 255, 255, .05); border-color: #2c4260; }

/* Skeleton / loading card (shared). */
.os-card--skeleton { pointer-events: none; }
.os-card--skeleton .os-card__media { background: linear-gradient(90deg, #0a1526, #12233a, #0a1526); }

/* ── OS.TV Channel Certification badge (shared component: js/certification-badge.js) ──────────────────────────────
   ⛔ The badge is a DOORWAY into the certificate, never a substitute for it. Colour is a hint; the text carries the
   meaning. Sits bottom-right on the card media; CH# keeps bottom-left. */
.os-cert {
  position: absolute; bottom: 6px; right: 6px; z-index: 5;
  display: flex; flex-direction: column; align-items: center; gap: 1px;
  padding: 3px 7px; border: 0; border-radius: 7px; cursor: pointer;
  font: 700 11px/1.1 var(--os-font, system-ui, sans-serif); letter-spacing: .02em;
  background: rgba(4, 18, 27, .92); color: #d8e6f2; box-shadow: 0 2px 6px rgba(0, 0, 0, .45);
}
.os-cert:hover, .os-cert:focus-visible { outline: 2px solid var(--os-accent, #12d39a); outline-offset: 1px; }
.os-cert__face { font-size: 12px; font-weight: 800; }
.os-cert__state { font-size: 8px; font-weight: 700; opacity: .85; letter-spacing: .06em; }
.os-cert--compact { padding: 2px 6px; }
.os-cert.is-certified   { background: rgba(18, 211, 154, .94); color: #04121b; }
.os-cert.is-conditional { background: rgba(255, 157, 60, .94); color: #1c0d00; }
.os-cert.is-failed      { background: rgba(255, 107, 115, .94); color: #23060a; }
/* Unverified is NOT a verdict — it must look neutral, never like a failure. */
.os-cert.is-unverified  { background: rgba(90, 110, 130, .82); color: #dce7f0; }
/* Expired keeps the grade legible but visibly lapsed: the record stands, the claim does not. */
.os-cert.is-expired     { background: rgba(4, 18, 27, .92); color: #9fb3c6; border: 1px dashed rgba(159, 179, 198, .6); }
.os-cert.is-measuring   { background: rgba(4, 18, 27, .92); color: #9fb3c6; }
.os-cert.is-aging       { box-shadow: 0 2px 6px rgba(0, 0, 0, .45), inset 0 0 0 1px rgba(255, 157, 60, .8); }
.os-cert.is-rechecking .os-cert__state { animation: os-cert-pulse 1.4s ease-in-out infinite; }
@keyframes os-cert-pulse { 0%, 100% { opacity: .45; } 50% { opacity: 1; } }

/* ── Certification panel (Layer 3 consumer interpretation) ── */
.os-cert-modal { display: none; }
.os-cert-modal.is-open { display: block; position: fixed; inset: 0; z-index: 9000; }
.os-cert-modal__scrim { position: absolute; inset: 0; background: rgba(2, 8, 14, .72); }
.os-cert-modal__box {
  position: relative; margin: 6vh auto; max-width: 520px; max-height: 84vh; overflow: auto;
  background: var(--os-panel, #0a1526); border: 1px solid rgba(120, 150, 180, .22); border-radius: 14px; padding: 20px 22px;
  box-shadow: 0 18px 50px rgba(0, 0, 0, .6);
}
.os-cert-modal__x { position: absolute; top: 10px; right: 12px; background: none; border: 0; color: #8ba3ba; font-size: 22px; cursor: pointer; }
.os-cert-panel h2 { font-size: 12px; letter-spacing: .1em; text-transform: uppercase; color: #7f97ad; margin: 0 0 4px; }
.os-cert-panel__ch { font-size: 18px; font-weight: 700; color: #e8f1f8; margin-bottom: 12px; }
.os-cert-panel__head { display: flex; align-items: baseline; gap: 10px; padding: 10px 12px; border-radius: 10px; margin-bottom: 12px; }
.os-cert-panel__head.is-certified { background: rgba(18, 211, 154, .14); }
.os-cert-panel__head.is-conditional { background: rgba(255, 157, 60, .14); }
.os-cert-panel__head.is-failed { background: rgba(255, 107, 115, .14); }
.os-cert-panel__head.is-expired, .os-cert-panel__head.is-unverified { background: rgba(120, 150, 180, .12); }
.os-cert-panel__score { font-size: 26px; font-weight: 800; color: #e8f1f8; }
.os-cert-panel__verdict { font-size: 11px; font-weight: 700; letter-spacing: .08em; color: #b9cde0; }
/* ⛔ These stay SEPARATE lines: quality, completeness and freshness answer different questions. */
.os-cert-panel__facts { list-style: none; padding: 0; margin: 0 0 14px; font-size: 12.5px; color: #b9cde0; }
.os-cert-panel__facts li { padding: 2px 0; }
.os-cert-panel__facts b { color: #e8f1f8; }
.os-cert-panel__expired { color: #ff9d3c; }
.os-cert-panel__aging { color: #ffcf7a; }
.os-cert-panel__tbl { width: 100%; border-collapse: collapse; font-size: 12.5px; }
.os-cert-panel__tbl th { text-align: left; vertical-align: top; width: 84px; padding: 7px 0; color: #7f97ad; font-weight: 600; }
.os-cert-panel__tbl td { padding: 7px 0; color: #dce7f0; border-bottom: 1px solid rgba(120, 150, 180, .12); }
.os-cert-panel__caveat { color: #8ba3ba; font-style: italic; font-size: 11.5px; }
.os-cert-panel__none { color: #dce7f0; font-size: 14px; }
.os-cert-panel__note { color: #8ba3ba; font-size: 12px; }
.os-cert-panel__full { margin-top: 14px; }
.os-cert-panel__full summary { cursor: pointer; color: var(--os-accent, #12d39a); font-size: 12.5px; font-weight: 600; }
.os-cert-panel__checks { list-style: none; padding: 0; margin: 10px 0 0; font-size: 12px; }
.os-cert-panel__checks li { display: grid; grid-template-columns: auto 1fr auto; gap: 8px; align-items: center; padding: 5px 0; border-bottom: 1px solid rgba(120, 150, 180, .1); }
.os-cert-chk { font-size: 9.5px; font-weight: 700; padding: 2px 6px; border-radius: 5px; letter-spacing: .04em; white-space: nowrap; }
.os-cert-chk--passed { background: rgba(18, 211, 154, .18); color: #3ee6b4; }
.os-cert-chk--failed { background: rgba(255, 107, 115, .18); color: #ff8b92; }
.os-cert-chk--unmeasured { background: rgba(255, 157, 60, .16); color: #ffb066; }
/* not_applicable must read as neutral — a radio station is not deficient for having no picture. */
.os-cert-chk--not_applicable { background: rgba(120, 150, 180, .16); color: #a8bccf; }
.os-cert-chk__label { color: #dce7f0; }
.os-cert-chk__pts { color: #7f97ad; font-variant-numeric: tabular-nums; }
.os-cert-chk__why { grid-column: 1 / -1; color: #7f97ad; font-size: 11px; }
.os-cert-panel__prov { margin-top: 10px; color: #6b8299; font-size: 10.5px; }

/* Newer-certificate notice — the panel shows the certificate you SELECTED; this says the world moved on. */
.os-cert-panel__newer {
  background: rgba(255, 157, 60, .14); border: 1px solid rgba(255, 157, 60, .35); border-radius: 8px;
  padding: 7px 10px; margin-bottom: 10px; font-size: 12px; color: #ffcf7a;
}
.os-cert-panel__newer button { margin-left: 8px; background: rgba(255, 157, 60, .9); color: #1c0d00; border: 0; border-radius: 6px; padding: 3px 8px; font-weight: 700; font-size: 11px; cursor: pointer; }

/* ── Certification filter bar (shared). ⛔ Filtering is ALWAYS user-selected and always VISIBLE — a user must never
   wonder why channels disappeared, so the active count + a clear-all are permanent fixtures. */
.os-certbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0 0 12px; }
.os-certbar__grp { display: flex; align-items: center; gap: 5px; }
.os-certbar__lbl { font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase; color: #6b8299; margin-right: 2px; }
.os-certbar__chip {
  background: rgba(120, 150, 180, .13); border: 1px solid transparent; color: #b9cde0;
  border-radius: 999px; padding: 4px 10px; font-size: 11.5px; cursor: pointer; white-space: nowrap;
}
.os-certbar__chip:hover { background: rgba(120, 150, 180, .22); }
.os-certbar__chip.is-on { background: rgba(18, 211, 154, .9); color: #04121b; font-weight: 700; }
.os-certbar__chip:focus-visible { outline: 2px solid var(--os-accent, #12d39a); outline-offset: 2px; }
.os-certbar__clear { background: none; border: 0; color: var(--os-accent, #12d39a); font-size: 11.5px; cursor: pointer; text-decoration: underline; }
.os-certbar__state { font-size: 11.5px; color: #7f97ad; }
.os-certbar__sort { background: rgb(1, 19, 37); border: 1px solid rgba(120, 150, 180, .25); color: #dce7f0; border-radius: 7px; padding: 4px 8px; font-size: 11.5px; }
.os-certbar__sort option{ background: rgba(2, 22, 41 ) !important; border: 1px solid rgba(120, 150, 180, .25); color: #dce7f0; border-radius: 7px; padding: 4px 8px; font-size: 11.5px; }
