/* ======================================================
   /tv — "Andrew Live" landing page

   Built on the site's existing design system — no invented values:
   - colors via tokens: var(--brand-teal-hex) #009296, rgb(var(--heading-color)) #003b3c
   - cream #F6F2EC + divider #D9E2E2 (site-wide constants), muted #406c6d
   - spacing via var(--gutter-*) / var(--grid-column-gap)
   - canonical breakpoints: 600 / 768 / 960 / 1280 / 1600
   - hero band + container widths mirror the legal / FAQ / contact pages
   - primary buttons reuse the global .btn-brand class (applied in the markup)
   Headings inherit STIX Two Text + heading color globally; we only set sizes.
   ====================================================== */

/* ---------- container: ONE content band used by every section so edges line up
   (site content band ~1140; Story/Quality shell is 1440 w/ generous gutters) ---------- */
.tv-wrap { max-width: 1140px; margin: 0 auto; padding: 0 20px; }
@media (min-width: 600px) { .tv-wrap { padding: 0 32px; } }
@media (min-width: 960px) { .tv-wrap { padding: 0 48px; } }
/* widen the band on large monitors so content isn't marooned in the middle at 1440/1920 */
@media (min-width: 1440px) { .tv-wrap { max-width: 1140px; padding: 0 40px; } }
@media (min-width: 1728px) { .tv-wrap { max-width: 1140px; padding: 0 40px; } }

.tv-eyebrow {
    font-family: Inter, sans-serif; font-size: 12px; font-weight: 600;
    letter-spacing: .16em; text-transform: uppercase;
    color: var(--brand-teal-hex); margin: 0 0 14px;
}

/* ---------- buttons: primary reuses global .btn-brand; ghost mirrors its geometry ---------- */
.tv-btn { display: inline-flex; align-items: center; justify-content: center; gap: 9px; text-decoration: none; cursor: pointer; }
.tv-btn-ghost {
    background: transparent; color: rgb(var(--heading-color));
    border: 1.5px solid rgb(var(--heading-color)); border-radius: 9999px;
    font-family: Inter, sans-serif; font-weight: 500; font-size: 16px; padding: 12px 28px;
    transition: background-color .2s, color .2s;
}
.tv-btn-ghost:hover { background: rgb(var(--heading-color)); color: #fff; }

/* whole page sits on tan; sections are transparent, only panels are white/dark */
.tv-page { background: #F6F2EC; }
/* site sets body{overflow-x:hidden}, which makes body a scroll container and breaks position:sticky.
   'clip' clips horizontal overflow the same way WITHOUT the scroll-container side effect. */
body { overflow-x: clip; }

/* ---------- hero (band + type scale match .legal-hero / .faq-hero) ---------- */
.tv-hero { background: #F6F2EC; overflow: hidden; }
/* (old grid-based .tv-hero-grid removed — the flex version lower in this file is
   the active hero layout, and it must not carry stray padding-block.) */

.tv-live {
    display: inline-flex; align-items: center; gap: 8px;
    font-family: Inter, sans-serif; font-size: 12px; font-weight: 600;
    letter-spacing: .16em; text-transform: uppercase; color: var(--brand-teal-hex); margin: 0 0 18px;
}
.tv-live { transition: color .3s ease; }
.tv-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--brand-teal-hex); position: relative; }
/* live-now state — only red + pulsing while Andrew is actually on air (toggled by tick() in Tv.razor) */
.tv-live.is-live { color: #c0322d; }
.tv-live.is-live .tv-dot { background: #e0322d; }
.tv-live.is-live .tv-dot::after { content: ""; position: absolute; inset: -5px; border-radius: 50%; border: 1px solid #e0322d; opacity: .5; animation: tv-pulse 1.8s ease-out infinite; }
@keyframes tv-pulse { 0% { transform: scale(.6); opacity: .7; } 100% { transform: scale(1.5); opacity: 0; } }
@media (prefers-reduced-motion: reduce) { .tv-live.is-live .tv-dot::after { animation: none; } }

/* hero title — STIX inherited; sizes match the legal/faq hero title scale */
.tv-h1 { font-family: 'STIX Two Text', serif; font-weight: 400; font-size: 40px; line-height: 1.06; letter-spacing: -.02em; margin: 0 0 18px; }
@media (min-width: 768px)  { .tv-h1 { font-size: 50px; } }
@media (min-width: 1024px) { .tv-h1 { font-size: 54px; } }
@media (min-width: 1280px) { .tv-h1 { font-size: 60px; } }
@media (min-width: 1600px) { .tv-h1 { font-size: 64px; } }
.tv-h1 em { font-style: italic; color: var(--brand-teal-hex); }

/* line 1 — "Today's Specials airs on HSN": 20px desktop, scales down on small screens; tight gap to line 2 */
/* body copy matches the homepage banner subtitle (.hero-subtitle): Inter 400,
   fluid 16→20px, 140% line-height — one system across the marketing pages */
.tv-when { font-family: Inter, sans-serif; font-size: clamp(16px, calc(12px + 0.5vw), 20px); font-weight: 400; line-height: 1.4; color: rgb(var(--heading-color)); margin: 0 0 24px; }
.tv-when b { font-weight: 600; }
/* line 2 — "First show 12:00AM EST": 16px desktop, scales down; larger gap before the countdown */
.tv-channel { font-family: Inter, sans-serif; font-size: 14px; font-weight: 400; color: rgb(var(--heading-color)); margin: 0 0 30px; }
@media (min-width: 960px) { .tv-channel { font-size: 16px; } }
.tv-channel b { color: rgb(var(--heading-color)); font-weight: 600; }

.tv-cta { display: flex; flex-wrap: wrap; align-items: center; gap: 18px; }
/* quiet ghost pill — the hero's CTA; anchors down to the specials grid.
   teal outline, fills teal on hover, arrow nudges down (scroll cue) */
.tv-cta-link {
    display: inline-flex; align-items: center; gap: 8px;
    font-family: Inter, sans-serif; font-size: 15px; font-weight: 600;
    color: var(--brand-teal-hex); text-decoration: none;
    border: 1.5px solid var(--brand-teal-hex); border-radius: 9999px;
    padding: 11px 22px;
    transition: background-color .2s ease, color .2s ease;
}
.tv-cta-link span { transition: transform .2s ease; }
.tv-cta-link:hover { background: var(--brand-teal-hex); color: #fff; }
.tv-cta-link:hover span { transform: translateY(2px); }

.tv-portrait {
    position: relative; border-radius: 20px; aspect-ratio: 1304 / 1266; overflow: hidden;
    /* Andrew on-set photo (Brandfolder CDN, auto-webp); position biased up so his
       face stays in frame on the wide 2.4:1 tablet crop. Teal fallback while loading. */
    background: #0b7f83 url('https://cdn.bfldr.com/EE0OVGM5/at/q6fm2pjhvtvwft8h35bwjwfm/AML_TV.jpg?auto=webp&format=jpg') center 28% / cover no-repeat;
    display: flex; align-items: flex-end;
}
@media (max-width: 959px) { .tv-portrait { max-width: 520px; } }
.tv-portrait::after { content: ""; position: absolute; inset: 0; background: linear-gradient(to top, rgba(0,25,26,.55), rgba(0,25,26,0) 42%); pointer-events: none; }
.tv-portrait-cap { position: relative; z-index: 1; padding: 22px 26px; color: #eaf3f2; }
/* height:auto keeps the signature's true 5.65:1 ratio (no squish); width clamps to the card */
/* signature size matched to the About Founder video block (268 desktop / 168 mobile) */
.tv-sig { display: block; width: 268px; height: auto; margin-bottom: 8px; filter: brightness(0) invert(1); }
@media (max-width: 767px) { .tv-sig { width: 168px; } }

/* ---------- section rhythm (mirrors .legal-main / .faq-main) ---------- */
/* section gap = padding-TOP only, so each section-to-section gap is a single
   clean value (no doubling) at homepage scale (48 / 64 / 80px). */
.tv-block { padding: 48px 0 0; }
@media (min-width: 768px) { .tv-block { padding: 64px 0 0; } }
@media (min-width: 960px) { .tv-block { padding: 80px 0 0; } }
.tv-tight { padding-top: 0; }

.tv-sec-head { max-width: none; margin: 0 0 32px; }
.tv-sec-head.tv-center { text-align: center; }
/* own em-based tracking (not the global app.css h2, which only sets -1.2px ≥1024
   and leaves mobile loose) so letter-spacing is consistent at every size */
.tv-h2 { font-family: 'STIX Two Text', serif; font-weight: 400; font-size: 30px; line-height: 1.15; letter-spacing: -.03em; margin: 0; }
@media (min-width: 960px) { .tv-h2 { font-size: 42px; } }
.tv-h2 em { font-style: italic; color: var(--brand-teal-hex); }
.tv-h2-lg { font-size: 30px; }
@media (min-width: 768px)  { .tv-h2-lg { font-size: 38px; } }
@media (min-width: 1280px) { .tv-h2-lg { font-size: 44px; } }
@media (min-width: 1600px) { .tv-h2-lg { font-size: 48px; } }

/* ---------- airtimes ---------- */
.tv-airtimes-panel { background: #fff; border-radius: 20px; padding: 8px 28px 20px; }
@media (min-width: 768px) { .tv-airtimes-panel { padding: 8px 40px 24px; } }
.tv-airtimes-head { display: flex; align-items: center; justify-content: space-between; gap: 12px 16px; flex-wrap: wrap; padding: 22px 0 10px; }
.tv-airtimes-date { font-family: Inter, sans-serif; font-weight: 600; font-size: 14px; letter-spacing: .04em; text-transform: uppercase; color: #406c6d; }

/* timezone toggle — segmented control (Your time / ET) */
.tv-tz-toggle { display: inline-flex; background: #EBF0EF; border-radius: 999px; padding: 3px; gap: 2px; }
.tv-tz-opt { border: none; background: transparent; cursor: pointer; font-family: Inter, sans-serif; font-size: 12px; font-weight: 600; letter-spacing: .02em; color: #406c6d; padding: 6px 14px; border-radius: 999px; transition: background-color .15s ease, color .15s ease; }
.tv-tz-opt.is-active { background: #fff; color: var(--brand-teal-hex); box-shadow: 0 1px 2px rgba(0,41,42,.12); }
.tv-tz-opt:hover:not(.is-active) { color: var(--brand-teal-hex); }

/* time + optional weekday chip (shown only when a slot lands on a different day in the viewer's tz) */
.tv-slot-time { display: inline-flex; align-items: baseline; gap: 8px; }
.tv-slot-day { font-family: Inter, sans-serif; font-size: 11px; font-weight: 600; letter-spacing: .04em; text-transform: uppercase; color: rgba(0, 59, 60, .45); }
.tv-airtimes-note { font-family: Inter, sans-serif; font-size: 14px; line-height: 1.5; color: #406c6d; margin: 0 0 8px; }
/* single chronological column — reads straight top-to-bottom (no more L/R zigzag) */
.tv-slots { border-top: 1px solid #D9E2E2; padding-top: 6px; max-width: 580px; }
.tv-slot { display: flex; align-items: center; justify-content: space-between; gap: 20px; padding: 15px 2px; border-bottom: 1px solid #D9E2E2; }
.tv-slot-t { font-family: Inter, sans-serif; font-weight: 600; font-size: 15px; color: rgb(var(--heading-color)); font-variant-numeric: tabular-nums; }
.tv-tag { font-family: Inter, sans-serif; font-size: 11px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; padding: 4px 10px; border-radius: 999px; }
.tv-tag.tv-on { background: #e4f3ea; color: #1f7a48; }  /* schedule "Live" — renamed off .tv-live to avoid colliding with the hero badge */
.tv-tag.tv-ts { background: #EBF6F4; color: var(--brand-teal-hex); }
.tv-tag.tv-rec { background: #efece6; color: #406c6d; }
.tv-tz { font-family: Inter, sans-serif; font-size: 13px; color: #406c6d; margin: 14px 0 0; }

/* ======================================================
   STICKY STAGE (Figma board 1633:285)
   left column = hero + schedule (scrolls); right = portrait that pins, releases at the grid
   ====================================================== */
/* Mirrors the Our Story Founder 2-col EXACTLY (1140 band filled, copy 520 +
   550 square media + 60 gap), flipped: copy left / image right. The gutter
   lives on the section (not the band) so content fills the full 1140 at 1920,
   matching the About page (the old .tv-wrap padding made it ~70px narrower). */
.tv-stage { padding-inline: 20px; }
@media (min-width: 768px) { .tv-stage { padding-inline: 40px; } }
.tv-stage-grid { display: flex; flex-direction: column; gap: 32px; max-width: 1140px; margin: 0 auto; padding-block: 28px 44px; }
@media (min-width: 1100px) {
    .tv-stage-grid { flex-direction: row; gap: 60px; align-items: start; padding-block: 64px; }
    /* balanced 50/50 with the gap unchanged: (1140 - 60) / 2 = 540 each */
    .tv-stage-main { flex: 1 1 auto; min-width: 0; max-width: 540px; }
    .tv-stage-aside { width: 540px; flex-shrink: 0; position: sticky; top: 120px; }
}
@media (max-width: 1099px) {
    .tv-stage-aside { order: -1; }                                  /* Andrew leads when stacked */
    .tv-stage-aside .tv-portrait { margin: 0 auto; max-width: 520px; }
}
/* square portrait fills its 550 column (like the Our Story video slot) */
.tv-stage .tv-portrait { width: 100%; aspect-ratio: 1 / 1; max-width: none; margin: 0; }

/* ── Stacked (mobile + tablet, ≤1099): copy overlays the image bottom-left (like
   the preview3 banner). The hero copy moves OUT of the left rail and INTO the
   image; signature + await note hide to make room. Mobile keeps the 1:1 square;
   tablet switches to a landscape banner (set below) so it isn't a giant square.
   Desktop (≥1100) keeps the rail-copy + sticky square portrait. */
.tv-portrait-hero { display: none; }
@media (max-width: 1099px) {
    .tv-stage-main .tv-hero-block,
    .tv-stage-main .tv-rule { display: none; }              /* copy moved into the image */
    .tv-stage .tv-portrait .tv-portrait-cap { display: none; } /* hide signature where the copy overlays */
    /* Directional brand-teal scrim anchored to the copy corner (bottom-left),
       fading out toward the top-right so Andrew's face + the bright set stay clean.
       Only ≤1099, where the copy actually overlaps the photo. */
    .tv-stage .tv-portrait::after {
        background: linear-gradient(to top right,
            rgba(0,25,26,.80) 0%, rgba(0,25,26,.42) 34%, rgba(0,25,26,0) 68%);
        z-index: 1;
    }
    .tv-portrait-hero {
        display: flex; flex-direction: column; justify-content: flex-end;
        position: absolute; inset: 0; z-index: 2;
        padding: 0 24px 24px;
    }
    .tv-portrait-hero .tv-live:not(.is-live) { color: #63c4c5; }
    .tv-portrait-hero .tv-live:not(.is-live) .tv-dot { background: #63c4c5; }
    .tv-portrait-hero .tv-h1 { color: #fff; margin: 0 0 12px; }
    .tv-portrait-hero .tv-when { color: rgba(255,255,255,.9); margin: 0; }
    /* Stacked layout (mobile + tablet): the schedule card AND its inner rows span
       the same full grid width as the banner — card, head, rows, note all align.
       (Desktop ≥1100 keeps the narrow 560 panel in the 2-col left rail.) */
    .tv-stage-main .tv-airtimes-block .tv-airtimes-panel { max-width: none; }
    .tv-stage-main .tv-slots { max-width: none; }
    /* hero-block + rule are hidden when stacked, so the airtimes margin-top would
       double up on the grid gap below the image — zero it for one clean gap */
    .tv-stage-main .tv-airtimes-block { margin-top: 0; }
}
/* 600–1099 (tablet / landscape phone): landscape banner hero instead of a square.
   Below 600 the square stays — a 2.4:1 banner there is too short to hold the
   copy; by 600 it's ~250px tall and the copy fits, so a tall square is wasteful. */
@media (min-width: 600px) and (max-width: 1099px) {
    .tv-stage .tv-portrait { aspect-ratio: 2.4 / 1; }
    .tv-portrait-hero { padding: 0 48px 40px; max-width: 620px; }
}

/* divider between the hero CTAs and the "When Andrew's on" schedule (left column);
   width matches the schedule panel below it (max 560, left-aligned) */
.tv-rule { border: 0; height: 1px; background: #D9E2E2; margin: 30px 0 0; max-width: 560px; }
@media (min-width: 960px) { .tv-rule { margin-top: 38px; } }

/* left column: hero, then the schedule box below it */
.tv-airtimes-block { margin-top: 30px; }
@media (min-width: 960px) { .tv-airtimes-block { margin-top: 38px; } }
/* 'When Andrew's on' — a touch smaller than the other lg headings (pairs with the ~560 panel) */
/* short copy ("Live show schedule") fits one line, so it carries a proper heading
   size — 30px mobile matches the "Andrew's video gallery" heading below it */
.tv-airtimes-block > .tv-h2 { margin: 0 0 20px; font-size: 30px; }
@media (min-width: 768px)  { .tv-airtimes-block > .tv-h2 { font-size: 32px; } }
@media (min-width: 1280px) { .tv-airtimes-block > .tv-h2 { font-size: 32px; } }
@media (min-width: 1600px) { .tv-airtimes-block > .tv-h2 { font-size: 32px; } }
.tv-airtimes-block .tv-airtimes-panel { max-width: 560px; }


/* ============================================================
   Revised TV page (Oct 2026): conditional specials CTA + YouTube "coming soon"
   ============================================================ */

/* "View Featured Specials" — only rendered while a special is live (dev toggles).
   Solid teal pill = the primary act-now CTA, sits under the schedule panel. */
.tv-specials-cta {
    display: inline-flex; align-items: center; gap: 8px;
    margin-top: 22px;
    padding: 14px 28px;
    font-family: Inter, sans-serif; font-size: 15px; font-weight: 600;
    color: #fff; text-decoration: none;
    background: var(--brand-teal-hex);
    border-radius: 9999px;
    transition: background-color .2s ease;
}
.tv-specials-cta:hover { background: #007b7e; }
.tv-specials-cta-arrow { transition: transform .2s ease; }
.tv-specials-cta:hover .tv-specials-cta-arrow { transform: translateX(3px); }

/* YouTube gallery — tasteful "coming soon" placeholder (built later).
   Bottom padding closes the page before the CTA band (section uses top-only pad). */
.tv-soon { padding-bottom: 48px; }
@media (min-width: 768px) { .tv-soon { padding-bottom: 64px; } }
@media (min-width: 960px) { .tv-soon { padding-bottom: 80px; } }
.tv-soon-inner { text-align: center; max-width: 760px; margin: 0 auto; }  /* wide enough for the sub on one line */
.tv-soon-kicker {
    display: inline-block;
    font-family: Inter, sans-serif; font-size: 12px; font-weight: 600;
    letter-spacing: .16em; text-transform: uppercase;
    color: var(--brand-teal-hex);
    margin: 0 0 14px;
}
.tv-soon .tv-h2 { margin: 0 0 12px; }
/* match the homepage sub-copy (.hero-subtitle): Inter 18 / 400 / #003B3C / 1.4 */
.tv-soon-sub {
    font-family: Inter, sans-serif; font-size: 18px; font-weight: 400; line-height: 1.4;
    color: #003B3C;
    margin: 0;
}

/* Schedule as its own full-width section — spans the SAME 1140 band as the hero.
   At desktop the 8 slots flow into 2 balanced columns so the width reads full. */
.tv-schedule-inner { max-width: none; margin: 0; }
.tv-schedule-inner > .tv-h2 { margin: 0 0 24px; text-align: center; }
/* full-width panel spanning the 1140 band; single chronological column, each
   slot a full-width row (time left, status right). */
.tv-schedule .tv-airtimes-panel { max-width: 100%; margin: 0; }
.tv-schedule .tv-slots { max-width: none; }
.tv-schedule .tv-specials-cta { display: flex; width: fit-content; margin: 28px auto 0; }

/* ============================================================
   Hero — FULL-WIDTH BANNER (same 1140 band as the schedule). Copy sits
   inside the banner on the left, over the image. Placeholder = teal tile.
   ============================================================ */
/* hero: top padding only (gap from header); the schedule's padding-top gives
   the gap below the banner. */
.tv-hero { padding: 28px 0 0; }
@media (min-width: 768px) { .tv-hero { padding: 40px 0 0; } }
@media (min-width: 960px) { .tv-hero { padding: 48px 0 0; } }

.tv-banner {
    position: relative;
    width: 100%;
    aspect-ratio: 2.4 / 1;
    border-radius: 20px;
    overflow: hidden;
    background: #406c6d;                 /* teal placeholder — awaiting creative */
    display: flex;
    align-items: center;
}
@media (max-width: 767px) {
    .tv-banner { aspect-ratio: 4 / 5; align-items: flex-end; }   /* copy sits bottom-left on mobile */
    .tv-banner-copy { padding-bottom: 28px; }
    .tv-banner-await { display: none; }                          /* hide placeholder note on mobile */
}
/* left-edge scrim so the copy stays legible once a real photo is dropped in */
.tv-banner::before {
    content: ""; position: absolute; inset: 0; z-index: 1;
    background: linear-gradient(90deg, rgba(0, 25, 26, .45) 0%, rgba(0, 25, 26, 0) 62%);
}
.tv-banner-copy {
    position: relative; z-index: 2;
    max-width: 560px;
    padding: 0 clamp(24px, 5%, 56px);
}
/* eyebrow + dot: a light tint of the brand teal so it reads on the dark banner
   (brand #009296 would blend teal-on-teal). Live-red state left intact. */
.tv-banner .tv-live:not(.is-live) { color: #63c4c5; }
.tv-banner .tv-live:not(.is-live) .tv-dot { background: #63c4c5; }
.tv-banner .tv-h1 { color: #fff; }
.tv-banner .tv-when { color: rgba(255, 255, 255, .9); }
.tv-banner .tv-when b { color: #fff; }
/* placeholder note, tucked bottom-right so it doesn't fight the copy */
.tv-banner-await {
    position: absolute; right: 24px; bottom: 18px; z-index: 2;
    font-family: Inter, sans-serif; font-size: 12px; font-weight: 500;
    letter-spacing: .14em; text-transform: uppercase; color: rgba(255, 255, 255, .4);
}

/* divider between the specials CTA and the coming-soon section (band-aligned),
   with balanced space on both sides (overrides the top-only rhythm just here). */
.tv-divider { border: 0; height: 1px; background: #D9E2E2; margin: 0; }
.tv-schedule { padding-bottom: 40px; }
.tv-soon { padding-top: 40px; }
@media (min-width: 768px) { .tv-schedule { padding-bottom: 44px; } .tv-soon { padding-top: 44px; } }
@media (min-width: 960px) { .tv-schedule { padding-bottom: 48px; } .tv-soon { padding-top: 48px; } }

/* mobile: keep each schedule row on ONE line — the long "Previously Recorded"
   tag was squeezing the row (broken time + wrapped pill) at ~390px. Time never
   breaks; a slightly smaller/tighter tag fits to ~360; wraps (not overflows) tinier. */
.tv-slot-t { white-space: nowrap; }
@media (max-width: 600px) {
    .tv-airtimes-panel { padding-left: 18px; padding-right: 18px; }
    .tv-slot { gap: 12px; }
    .tv-tag { font-size: 10px; letter-spacing: .03em; padding: 4px 9px; }
}

/* ---------- loading skeleton (same stage grid; bars stand in for type) ---------- */
.tv-skel-dot { width: 8px; height: 8px; flex-shrink: 0; }
.tv-skel-kicker { width: 132px; height: 12px; }
.tv-skel-h1 { line-height: 1; display: flex; flex-direction: column; gap: 0.12em; }
.tv-skel-h1-line { display: block; height: 1em; width: 3.6em; }
.tv-skel-h1-line--long { width: 6.8em; }
.tv-skel-when { display: flex; flex-direction: column; gap: 0.35em; line-height: 1; }
.tv-skel-when > span { display: block; height: 1.15em; width: 100%; }
.tv-skel-when > .tv-skel-when-short { width: 68%; }
.tv-airtimes-block > .tv-skel-h2 { line-height: 1; }
.tv-skel-h2 > span { display: block; height: 1em; width: 8.4em; }
.tv-skel-date { width: 220px; max-width: 58%; height: 14px; }
.tv-skel-toggle { width: 132px; height: 32px; flex-shrink: 0; }
.tv-skel-time { width: 148px; max-width: 58%; height: 15px; }
.tv-skel-tag { width: 58px; height: 22px; flex-shrink: 0; }
.tv-skel-tag--md { width: 124px; }
.tv-skel-tag--lg { width: 168px; }
@media (max-width: 600px) {
    .tv-skel-tag--lg { width: 132px; }
    .tv-skel-time { width: 112px; }
}
.tv-skel-note { display: inline-block; width: min(100%, 340px); height: 13px; vertical-align: middle; }
/* portrait placeholder — same box as the photo, no image request */
.tv-portrait--skel {
    background: linear-gradient(
        90deg,
        rgba(0, 59, 60, 0.06) 0%,
        rgba(0, 59, 60, 0.12) 50%,
        rgba(0, 59, 60, 0.06) 100%
    );
    background-size: 200% 100%;
    animation: brand-skel-shimmer 1.4s ease-in-out infinite;
}
.tv-portrait--skel::after { content: none; }
@media (prefers-reduced-motion: reduce) {
    .tv-portrait--skel { animation: none; }
}
