/* =========================================================
   Spellbinding Media — Site Shell Stylesheet
   Style direction: Apple TV-inspired — full-bleed hero art,
   dark chrome, poster grid below.
   ========================================================= */

:root{
  /* Brand palette — Option A: Oxblood & Brass (confirmed 2026-07-03) */
  --color-oxblood: #5C1A28;
  --color-navy: #1B1F2E;
  --color-brass: #C9A468;
  --color-parchment: #F0E6D8;

  --bg: var(--color-navy);
  --bg-elevated: #252a40; /* lighter navy tint, for cards/surfaces */
  --text: var(--color-parchment);
  --text-dim: rgba(240, 230, 216, .62);
  --accent: var(--color-brass);
  --accent-deep: var(--color-oxblood);

  --nav-height: 64px;
  --radius: 12px;
}

*{
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body{
  background: var(--bg);
  color: var(--text);
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  overflow-x: hidden;
}

a{
  color: inherit;
  text-decoration: none;
}

/* =========================================================
   Logo — sits over the hero art, top-right.
   ========================================================= */
.site-logo{
  /* Absolute (not fixed) so it scrolls away with the hero on this page,
     rather than sticking to the viewport for the whole scroll. */
  position: absolute;
  top: 1.75rem;
  right: 2rem;
  z-index: 500;
}
.site-logo img{
  display: block;
  width: 160px;
  height: auto;
  filter: drop-shadow(0 2px 14px rgba(0,0,0,.55));
}

@media (max-width: 640px){
  .site-logo{
    top: 1.25rem;
    right: 1.25rem;
  }
  .site-logo img{
    width: 110px;
  }
}

/* =========================================================
   Icon menu — top-left, opposite the logo. Public/open-page
   variant: toggle + 2 items (language, sign in). A longer,
   different menu replaces this once a visitor is signed in.
   Fixed to the viewport (deliberately unlike the logo) since
   this is the one persistent way to reach those two controls.
   Same ring size/color as the hero's Series Details/Episode
   List icons (.btn-icon) — kept as separate rules here rather
   than sharing that class, since .btn-icon's hover transform
   would fight with this component's open/closed transforms.
   ========================================================= */
.icon-menu{
  position: fixed;
  top: 1.75rem;
  left: 2rem;
  width: 45px;
  height: 45px;
  z-index: 700; /* above hero content (logo is 500) */
}
.menu-toggle,
.icon-menu .menu-item{
  position: absolute;
  left: 0;
  top: 0;
  width: 45px;
  height: 45px;
  display: block;
  border-radius: 50%;
  /* Semi-transparent navy backing plate — the brass-ring icons have a
     transparent center, so over a busy hero image or body text they were
     hard to read. This fills the circle behind each icon so it stays
     legible regardless of what's behind it, without hiding the ring
     artwork itself (drawn on top via the <img>). */
  background-color: rgba(27, 31, 46, .5); /* var(--color-navy) at 50% */
  filter: drop-shadow(0 4px 14px rgba(0,0,0,.45));
}
.menu-toggle img,
.icon-menu .menu-item img{
  display: block;
  width: 100%;
  height: 100%;
}
.menu-toggle{
  z-index: 2;
  border: 0;
  padding: 0;
  cursor: pointer;
  transition: transform .25s ease;
}
.icon-menu .menu-item{
  opacity: 0;
  pointer-events: none;
  transform: translateY(0) scale(.7);
  transition: transform .25s ease, opacity .2s ease;
}
.icon-menu .menu-item:hover{
  transform: translateY(calc(var(--i) * 58px)) scale(1.08);
}
.icon-menu.open .menu-toggle{
  transform: rotate(45deg); /* turns the + into an X, no separate asset needed */
}
.icon-menu.open .menu-item{
  opacity: 1;
  pointer-events: auto;
  transform: translateY(calc(var(--i) * 58px)) scale(1);
}

@media (max-width: 640px){
  .icon-menu{
    top: 1.25rem;
    left: 1.25rem;
    width: 43px;
    height: 43px;
  }
  .menu-toggle,
  .icon-menu .menu-item{
    width: 43px;
    height: 43px;
  }
  .icon-menu .menu-item:hover{
    transform: translateY(calc(var(--i) * 58px)) scale(1.08);
  }
  .icon-menu.open .menu-item{
    transform: translateY(calc(var(--i) * 58px)) scale(1);
  }
}

/* =========================================================
   Hero
   ========================================================= */
.hero{
  position: relative;
  min-height: 86vh;
  overflow: hidden;
}
/* Hero slider (2026-07-08): each .hero-slide is one featured series,
   stacked via position:absolute/inset:0 and crossfaded by toggling
   .is-active (opacity/visibility) — s/main.js drives the toggling plus
   lazy video loading. .hero itself no longer carries the flex/padding
   that positions .hero-content — that moved onto .hero-slide so every
   slide gets the same alignment .hero used to apply directly. */
.hero-slides{
  position: absolute;
  inset: 0;
}
.hero-slide{
  position: absolute;
  inset: 0;
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  padding: 0 2rem 5rem;
  opacity: 0;
  visibility: hidden;
  transition: opacity .7s ease;
  pointer-events: none;
}
.hero-slide.is-active{
  opacity: 1;
  visibility: visible;
  pointer-events: auto;
  z-index: 1;
}
.hero-bg{
  /* Real <video> (not a CSS background) so autoplay/loop/poster all work
     natively and the poster frame still gives crawlers/no-JS visitors a
     still image. Alt-text equivalent now lives on the .hero section's
     aria-label since <video> has no alt attribute. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  /* Anchor to the top so subjects near the top of the art are never
     cropped — any cover-scaling overflow is trimmed from the bottom
     instead, where the scrim already fades to the page background. */
  object-position: center top;
}
/* Two hero videos stacked in the same box (both position: absolute/inset:
   0 via .hero-bg above); only one is display: block at a time. Default
   (desktop/landscape) shows the horizontal cut; narrow/portrait screens
   swap to the vertical cut — same breakpoint the old <picture> used. */
.hero-bg--vertical{
  display: none;
}
@media (max-width: 1024px) and (orientation: portrait){
  .hero-bg--horizontal{
    display: none;
  }
  .hero-bg--vertical{
    display: block;
  }
}
.hero-scrim{
  position: absolute;
  inset: 0;
  /* Left side stays clear so the artwork reads on its own; right side
     (where the text sits) darkens toward the page background for
     legibility. Layered with the existing bottom fade. */
  background:
    linear-gradient(to right, rgba(27,31,46,0) 38%, var(--bg) 92%),
    linear-gradient(to top, var(--bg) 5%, rgba(27,31,46,0) 55%);
}
.hero-content{
  position: relative;
  max-width: 640px;
  /* Default (wider/"horizontal" screens): the whole block still sits on
     the right side of the hero (via .hero's justify-content: flex-end
     below), but within that column the logo/buttons are centered and
     the synopsis reads left-justified rather than everything being
     right-aligned. Mobile keeps the original all-right-aligned layout —
     see the max-width: 640px override further down. */
  text-align: center;
}
.hero-content h1{
  margin: 0;
  display: block;
  /* The <h1> is just a semantic wrapper around the title-treatment
     logo image; it carries no visual styling of its own. */
}
.hero-title{
  font-size: clamp(2.5rem, 6vw, 4.5rem);
  font-weight: 700;
  line-height: 1.05;
  margin-bottom: 1rem;
  text-shadow: 0 4px 24px rgba(0,0,0,.5);
}
.hero-logo{
  display: inline-block;
  width: min(420px, 70vw);
  height: auto;
  margin-bottom: 1.25rem;
  filter: drop-shadow(0 4px 24px rgba(0,0,0,.5));
}
.hero-tagline{
  font-size: 1.15rem;
  color: var(--text-dim);
  margin-bottom: 1.75rem;
  max-width: 46ch;
  /* Left-justified synopsis, flush to the left edge of .hero-content's
     column (not centered along with the logo/buttons, not right-aligned
     like the old layout). See mobile override below for the original
     right-aligned behavior. */
  margin-left: 0;
  margin-right: auto;
  text-align: left;
}
/* 2026-07-11: genre/rating tags moved onto their own row above
   .hero-actions (previously inline with the CTA buttons, centered).
   Shares .hero-tagline's "shrink to content, then margin-right: auto"
   trick so it lines up flush with the left edge of the synopsis above
   it rather than centering with the logo/buttons — width: fit-content
   is what makes the auto margin actually do something here (a plain
   block/flex box without it would already fill the available width).
   Wherever .hero-tagline's margins are overridden per breakpoint below,
   .hero-tags is added to the same rule so the two stay aligned with
   each other at every screen size. */
.hero-tags{
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: .5rem;
  width: fit-content;
  margin-left: 0;
  margin-right: auto;
  margin-bottom: 1.25rem;
}
/* .hero--detail (2026-07-11) — the series-detail-style hero used by
   s/render_series.php and s/render_episodes.php has no .hero-tagline
   above .hero-tags (see those files' headers: the short synopsis is
   intentionally omitted there), so the tags row's flush-left alignment
   above has nothing to line up with and reads as off-balance under the
   centered hero logo. Centered instead, scoped to this modifier so the
   homepage's carousel hero (which still has its tagline to align with)
   is unaffected. */
.hero--detail .hero-tags{
  width: auto;
  margin-left: auto;
  margin-right: auto;
  justify-content: center;
}
.hero-actions{
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 1rem;
}
.btn{
  display: inline-block;
  padding: .6rem 20px;
  border-radius: var(--radius);
  border: none;
  font-size: .95rem;
  font-weight: 600;
  cursor: pointer;
  transition: transform .15s ease;
}
.btn:hover{
  transform: scale(1.05);
}
.btn-primary{
  background: var(--color-brass);
  color: var(--color-navy);
}
/* Icon-only hero CTAs — play / series details / episode list — so the hero
   carries no copy that needs translating per language. Each icon's
   accessible name lives on its parent <a>'s aria-label. */
.btn-play,
.btn-icon{
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 45px;
  height: 45px;
  flex-shrink: 0;
  filter: drop-shadow(0 4px 14px rgba(0,0,0,.45));
  transition: transform .15s ease;
}
.btn-play:hover,
.btn-icon:hover{
  transform: scale(1.07);
}
.btn-play-icon,
.btn-icon-img{
  display: block;
  width: 100%;
  height: 100%;
}
.rating-badge{
  font-size: .75rem;
  padding: .3rem .6rem;
  border: 1px solid rgba(240,230,216,.25);
  border-radius: 6px;
  color: var(--text-dim);
  letter-spacing: .04em;
}
.rating-badge.small{
  font-size: .7rem;
  padding: .15rem .4rem;
}
/* Hero rating badge sized to 60% of the base .rating-badge (scoped here so
   the poster-grid tile's .small variant is unaffected). Scoped to
   .hero-tags (2026-07-11) now that the tags row lives above .hero-actions
   rather than inline with it. */
.hero-tags .rating-badge{
  font-size: .45rem;
  padding: .18rem .36rem;
  border-radius: 4px;
  letter-spacing: .024em;
}

/* Genre tags (e.g. "BL", "Romance", "Drama") — added 2026-07-11 alongside
   series.genre_tags (see migrate-add-series-genre.sql), one badge per
   genre rather than a single "BL · Drama" string. 2026-07-11 (later same
   day): restyled to match .rating-badge exactly (same border/color/
   weight) per Rolando — a genre badge should read as the same kind of
   tag as the rating badge ("Mature"), not a visually distinct brass
   accent. Kept as its own class (rather than reusing .rating-badge
   directly in markup) so genre and rating stay independently targetable
   if they ever need to diverge again. */
.genre-tag{
  font-size: .75rem;
  padding: .3rem .6rem;
  border: 1px solid rgba(240,230,216,.25);
  border-radius: 6px;
  color: var(--text-dim);
  letter-spacing: .04em;
}
.genre-tag.small{
  font-size: .7rem;
  padding: .15rem .4rem;
}
/* Scoped to .hero-tags (2026-07-11) now that the tags row lives above
   .hero-actions rather than inline with it. */
.hero-tags .genre-tag{
  font-size: .45rem;
  padding: .18rem .36rem;
  border-radius: 4px;
  letter-spacing: .024em;
}

/* Hero slider controls (2026-07-08) — only rendered by
   s/render_home.php when there's more than one featured series.
   Sit above every .hero-slide (z-index 1 when active) but below the
   fixed icon-menu (700); same semi-transparent navy backing plate
   treatment as .icon-menu so they stay legible over any slide's art. */
.hero-arrow{
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 550;
  width: 45px;
  height: 45px;
  border: 0;
  border-radius: 50%;
  background-color: rgba(27, 31, 46, .5);
  color: var(--text);
  font-size: 1.5rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  filter: drop-shadow(0 4px 14px rgba(0,0,0,.45));
  transition: transform .15s ease, background-color .15s ease;
}
.hero-arrow:hover{
  background-color: rgba(27, 31, 46, .75);
  transform: translateY(-50%) scale(1.08);
}
.hero-arrow--prev{
  left: 1.25rem;
}
.hero-arrow--next{
  right: 1.25rem;
}
.hero-dots{
  position: absolute;
  left: 50%;
  bottom: 1.25rem;
  transform: translateX(-50%);
  z-index: 550;
  display: flex;
  gap: .55rem;
}
.hero-dot{
  width: 9px;
  height: 9px;
  padding: 0;
  border: 1px solid rgba(240,230,216,.55);
  border-radius: 50%;
  background: rgba(240,230,216,.15);
  cursor: pointer;
  transition: background-color .2s ease, transform .2s ease;
}
.hero-dot:hover{
  transform: scale(1.15);
}
.hero-dot.is-active{
  background: var(--color-brass);
  border-color: var(--color-brass);
}

/* =========================================================
   Series grid
   ========================================================= */
.series-section{
  max-width: 1400px;
  margin: 0 auto;
  padding: 3rem 2rem 6rem;
}
.section-title{
  font-size: 1.4rem;
  font-weight: 600;
  margin-bottom: 1.5rem;
}
.series-grid{
  display: flex;
  gap: 1rem;
  overflow-x: auto;
  scroll-snap-type: x proximity;
  -webkit-overflow-scrolling: touch;
  padding-bottom: .5rem;
}
.series-card{
  display: block;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-elevated);
  transition: transform .2s ease, box-shadow .2s ease;
  flex: 0 0 calc((100% - 2rem) / 2.5);
  scroll-snap-align: start;
}
.series-card:hover{
  transform: translateY(-4px) scale(1.015);
  box-shadow: 0 12px 32px rgba(0,0,0,.45);
}
.series-poster{
  width: 100%;
  aspect-ratio: 3 / 4;
  display: block;
}
.series-poster-wrap{
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
}
.series-poster-wrap img{
  /* Real <img> elements (not CSS backgrounds) — indexable by image search
     and readable via alt text. The placeholder tile below stays a plain
     div since it has no image to show. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center top;
}
.series-poster--placeholder{
  display: flex;
  align-items: center;
  justify-content: center;
  background: linear-gradient(165deg, #2a3049, var(--bg));
  color: var(--text-dim);
  font-size: .85rem;
  text-align: center;
  padding: 1rem;
}
.series-info{
  padding: .9rem 1rem 1.1rem;
}
.series-info h3{
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: .3rem;
}
.series-meta{
  font-size: .8rem;
  color: var(--text-dim);
  display: flex;
  align-items: center;
  flex-wrap: nowrap;
  gap: .3rem;
  /* Safety net (2026-07-11), not the primary fix: at very narrow card
     widths (e.g. a ~1024px-wide browser window, where the grid is
     already down to 5.5 cards per row) 4 badges can be wider than even
     the shrunk badges below. Rather than let flex's default shrink
     behavior squash/clip the badges, the row scrolls horizontally
     within itself (scrollbar hidden) instead of wrapping to a second
     line or breaking the card. At normal desktop widths this never
     engages — everything fits and nothing scrolls. */
  overflow-x: auto;
  scrollbar-width: none;
}
.series-meta::-webkit-scrollbar{
  display: none;
}
/* 2026-07-11: genre now renders as one badge per tag (BL / Romance /
   Drama) instead of one combined "BL · Drama" badge, so a card's meta
   row can carry 4 badges (3 genre + 1 rating) instead of 2. Sized down
   from the shared .small variant (added for the hero/other contexts)
   so all of them fit on one row without wrapping at normal desktop
   widths; flex-shrink: 0 keeps each badge at its natural size so the
   overflow-x fallback above scrolls cleanly instead of squashing them. */
.series-meta .genre-tag,
.series-meta .rating-badge{
  font-size: .58rem;
  padding: .12rem .32rem;
  white-space: nowrap;
  flex-shrink: 0;
}
.series-card--placeholder{
  cursor: default;
  opacity: .6;
  flex: 0 0 calc((100% - 2rem) / 2.5);
  scroll-snap-align: start;
}

/* =========================================================
   Episode ribbon + dimmed thumbnail (2026-07-11)
   Shared by s/render_series.php's season strip AND the standalone
   Episode List page (s/render_episodes.php) — an "upcoming" episode
   (is_announced=1, live_date_time still in the future) gets the
   identical treatment in both places: a saturated-down/darkened
   thumbnail plus a release-date ribbon pinned to the bottom edge, no
   lock badge — upcoming isn't a permission gate, see
   spm_episode_card_status() in s/access_control.php.
   ========================================================= */
.series-poster.is-dim,
.episode-thumb-img.is-dim{
  filter: saturate(.35) brightness(.72);
}
.episode-ribbon{
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(27,31,46,.82);
  color: var(--color-parchment);
  font-size: .68rem;
  font-weight: 700;
  letter-spacing: .03em;
  text-align: center;
  padding: .4rem .3rem;
}
.series-card--upcoming,
.episode-card--upcoming{
  cursor: default;
}
.series-card--upcoming:hover{
  transform: none;
  box-shadow: none;
}

/* =========================================================
   Episode access badge — "Concept B", confirmed with Rolando
   2026-07-11 (see episode-lock-overlay-concept.html). A badge appears
   only when tapping the card won't get the visitor in: members-tier
   while logged out, or paid-tier not yet unlocked. Free episodes, and
   members/paid episodes the visitor already has access to, show no
   badge at all — same "nested in the icon-menu's circular navy plate"
   treatment as the mockup, sized as a pill rather than a circle since
   the paid badge carries a ticket count alongside its icons.
   ========================================================= */
.episode-badge{
  position: absolute;
  bottom: .6rem;
  right: .6rem;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: .22rem;
  height: 28px;
  padding: 0 .5rem 0 .4rem;
  background: rgba(27,31,46,.72);
  border-radius: 999px;
  filter: drop-shadow(0 3px 8px rgba(0,0,0,.45));
}
.episode-badge .badge-icon{
  display: block;
  flex-shrink: 0;
}
.episode-badge .badge-ticket-count{
  font-size: .7rem;
  font-weight: 700;
  color: var(--color-parchment);
  line-height: 1;
}

/* =========================================================
   Episode List page (2026-07-11) — see s/render_episodes.php.
   Full responsive grid, replacing the series-detail page's
   horizontal-scroll strip: every announced episode of a season, each
   card a two-cell tile (thumbnail | synopsis).

   BREAKPOINT: matches the device groups Rolando specified — vertical
   phone / horizontal phone / vertical tablet collapse into one
   "compact" tier (2 cards per row, thumbnail stacked above synopsis
   within each card), while horizontal tablet / desktop get a second
   tier (3 cards per row, thumbnail beside synopsis). Uses a plain
   width breakpoint (1024px — the common landscape-tablet threshold)
   rather than @media (orientation:) queries, since orientation alone
   can't tell a landscape phone from a landscape tablet apart, and the
   two need different card counts here.
   ========================================================= */
.episode-list-section{
  max-width: 1400px;
  margin: 0 auto;
  padding: 2rem 2rem 4rem;
}
.episode-list-grid{
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 1.25rem;
}
.episode-card{
  display: flex;
  flex-direction: column;
  border-radius: var(--radius);
  overflow: hidden;
  background: var(--bg-elevated);
  transition: transform .2s ease, box-shadow .2s ease;
}
a.episode-card:hover{
  transform: translateY(-4px) scale(1.015);
  box-shadow: 0 12px 32px rgba(0,0,0,.45);
}
.episode-card-thumb{
  position: relative;
  width: 100%;
  aspect-ratio: 3 / 4;
  flex-shrink: 0;
}
.episode-thumb-img{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  object-fit: cover;
  object-position: center top;
}
/* Parchment scrim at the bottom of every EPISODE thumbnail (2026-07-11) —
   shared by the Episode List page's cards (.episode-card-thumb) and the
   series-detail page's season-strip cards (.series-poster-wrap--episode).
   Purely decorative now that the episode title lives in the synopsis
   cell instead of overlaid here (see .episode-eyebrow/.episode-title
   below) — it exists so the lock/ticket badge and the "coming soon"
   ribbon, both of which sit in this same bottom region, have a
   consistent warm backdrop instead of landing straight on raw art.
   ::after rather than a markup element: zero extra DOM per thumbnail,
   and pointer-events: none keeps it from ever intercepting the card's
   own click target. NOT applied to plain .series-poster-wrap (the
   homepage's "All Series" grid) — real series posters never carry a
   lock/ticket overlay, so they don't need a backdrop for one. */
.episode-card-thumb::after,
.series-poster-wrap--episode::after{
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 20%;
  background: linear-gradient(to top, rgba(240,230,216,.55), rgba(240,230,216,0));
  pointer-events: none;
}
.episode-card-synopsis{
  padding: 1rem 1.1rem 1.2rem;
  /* Faint brass wash (2026-07-11) so the synopsis cell reads as part of
     the same warm, brand-colored tile as the thumbnail rather than a
     plain gray panel — kept subtle enough not to fight the body text. */
  background: linear-gradient(160deg, rgba(201,164,104,.10), transparent 65%);
}
/* Small brass "kicker" (2026-07-11) — about 60% the size of the title
   below it, on purpose: it's a label, not a heading, so the actual
   episode title reads as the prominent element in this cell. */
.episode-eyebrow{
  font-size: .43rem;
  font-weight: 700;
  color: var(--color-brass);
  text-transform: uppercase;
  letter-spacing: .07em;
  margin-bottom: .3rem;
}
/* The episode title, moved here from the thumbnail overlay (2026-07-11)
   — sits directly under .episode-eyebrow so the two read as one heading
   block. The brass divider that used to sit under the eyebrow moved down
   to here instead, so it now separates the whole number+title block from
   the synopsis paragraph below it (the "line break" Rolando asked for),
   rather than splitting the number from its own title. */
.episode-title{
  font-size: 1.05rem;
  font-weight: 700;
  color: var(--text);
  line-height: 1.3;
  padding-bottom: .55rem;
  margin-bottom: .6rem;
  border-bottom: 1px solid rgba(201,164,104,.35);
}
.episode-synopsis-text{
  font-size: .88rem;
  line-height: 1.55;
  color: var(--text);
}
.episode-list-empty{
  color: var(--text-dim);
  font-size: .95rem;
}

@media (min-width: 1025px){
  .episode-list-grid{
    grid-template-columns: repeat(3, 1fr);
  }
  .episode-card{
    flex-direction: row;
  }
  .episode-card-thumb{
    width: 42%;
    aspect-ratio: auto;
    min-height: 220px;
  }
  .episode-card-synopsis{
    flex: 1;
    display: flex;
    flex-direction: column;
    justify-content: center;
  }
}

/* =========================================================
   Series info page — long-form synopsis (2026-07-11)
   SEO/GEO prose block under the per-season episode lists (see
   s/render_series.php). Same left-aligned readable-article measure as
   .about-section rather than centered like .series-section above it,
   since this is body copy meant to be read, not a browsable shelf.
   ========================================================= */
.series-synopsis-section{
  max-width: 900px;
  margin: 0 auto;
  padding: 0 2rem 6rem;
}
.series-synopsis-section h2{
  font-size: 1.4rem;
  font-weight: 600;
  margin-bottom: 1.25rem;
}
.series-synopsis-section p{
  color: var(--text-dim);
  line-height: 1.7;
  margin-bottom: 1rem;
  max-width: 68ch;
}
.series-synopsis-section p:last-child{
  margin-bottom: 0;
}

/* =========================================================
   Footer
   ========================================================= */
.site-footer{
  padding: 2rem;
  text-align: center;
  color: var(--text-dim);
  font-size: .8rem;
  border-top: 1px solid rgba(240,230,216,.08);
}
.footer-watermark{
  display: block;
  width: 140px;
  height: auto;
  margin: 0 auto .85rem;
}
.footer-nav{
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: .4rem 1.25rem;
  max-width: 640px;
  /* Extra bottom margin here (vs. the watermark's .85rem) is the
     "spacing before the watermark" the nav needs now that it sits above
     the logo instead of below it. */
  margin: 0 auto 1.75rem;
}
.footer-nav a{
  color: var(--text-dim);
  text-decoration: none;
}
.footer-nav a:hover{
  color: var(--accent);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.lang-override{
  margin-top: .6rem;
  font-size: .75rem;
}
.lang-override a{
  text-decoration: underline;
  text-underline-offset: 2px;
  opacity: .8;
}
.lang-override a:hover{
  opacity: 1;
}

/* =========================================================
   Simple utility pages (language picker, sign-in placeholder,
   and similar minimal pages that aren't the main landing page)
   ========================================================= */
.simple-page{
  min-height: 70vh;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 8rem 2rem 4rem;
}
.simple-page-title{
  font-size: clamp(1.5rem, 4vw, 2.25rem);
  font-weight: 600;
  line-height: 1.4;
  margin-bottom: 2rem;
  max-width: 44ch;
}
/* Visually hidden but still readable by screen readers — used for a
   static heading copy when the visible version rotates/animates. */
.sr-only{
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0,0,0,0);
  white-space: nowrap;
  border: 0;
}
.lang-rotator-item{
  display: none;
}
.lang-rotator-item.is-active{
  display: inline-block;
  animation: langRotatorFadeIn .5s ease;
}
@keyframes langRotatorFadeIn{
  from{ opacity: 0; transform: translateY(4px); }
  to{ opacity: 1; transform: translateY(0); }
}
.simple-page-body{
  color: var(--text-dim);
  max-width: 46ch;
  margin-bottom: 2rem;
}
.simple-page-back a{
  font-size: .85rem;
  color: var(--text-dim);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.simple-page-back a:hover{
  color: var(--text);
}

/* =========================================================
   About page — a real article layout (left-aligned, readable
   measure) rather than the centered .simple-page treatment used
   by short utility pages.
   ========================================================= */
.about-page{
  max-width: 720px;
  margin: 0 auto;
  padding: 8rem 2rem 4rem;
}
.about-hero{
  margin-bottom: 2.5rem;
}
.about-hero h1{
  font-size: clamp(2rem, 5vw, 2.75rem);
  font-weight: 600;
  line-height: 1.25;
  margin-bottom: 1rem;
}
.about-lede{
  color: var(--text-dim);
  font-size: 1.1rem;
  max-width: 58ch;
}
.about-section{
  margin-bottom: 2.5rem;
}
.about-section h2{
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--accent);
  margin-bottom: .85rem;
}
.about-section p{
  color: var(--text-dim);
  line-height: 1.7;
  margin-bottom: 1rem;
  max-width: 62ch;
}
.about-section p:last-child{
  margin-bottom: 0;
}
.about-section a{
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.about-section a:hover{
  color: var(--accent);
}
.about-faq-item{
  margin-bottom: 1.5rem;
}
.about-faq-item:last-child{
  margin-bottom: 0;
}
.about-faq-item h3{
  font-size: 1rem;
  font-weight: 600;
  margin-bottom: .4rem;
}
.about-faq-item p{
  color: var(--text-dim);
  line-height: 1.7;
  max-width: 62ch;
}
.about-back{
  text-align: left;
}
@media (max-width: 640px){
  .about-page{
    padding: 7rem 1.25rem 3rem;
  }
}

/* =========================================================
   Legal pages (Terms of Use, and future pages like it — Privacy
   Policy, Cookie Policy) — same left-aligned readable-article
   treatment as .about-page, but for long sectioned legal text
   rendered from a structured content array (see s/render_terms.php)
   rather than hand-written markup: numbered h2/h3 section headings,
   an arbitration/class-action notice callout, and an ALL CAPS style
   for disclaimer/liability paragraphs that must render as-is.
   ========================================================= */
.legal-page{
  max-width: 720px;
  margin: 0 auto;
  padding: 8rem 2rem 4rem;
}
.legal-header{
  margin-bottom: 1.5rem;
}
.legal-header h1{
  font-size: clamp(2rem, 5vw, 2.75rem);
  font-weight: 600;
  line-height: 1.25;
  margin-bottom: .75rem;
}
.legal-meta{
  color: var(--text-dim);
  font-size: .85rem;
  font-style: italic;
}
.legal-notice{
  color: var(--text);
  background: var(--bg-elevated);
  border: 1px solid rgba(201, 164, 104, .35);
  border-radius: var(--radius);
  padding: 1rem 1.25rem;
  font-size: .85rem;
  font-weight: 600;
  line-height: 1.6;
  margin: 1.5rem 0 2.5rem;
  max-width: 62ch;
}
.legal-h1{
  font-size: 1.35rem;
  font-weight: 600;
  color: var(--accent);
  margin: 2.25rem 0 .85rem;
}
.legal-h2{
  font-size: 1rem;
  font-weight: 600;
  margin: 1.5rem 0 .5rem;
}
.legal-page p{
  color: var(--text-dim);
  line-height: 1.7;
  margin-bottom: 1rem;
  max-width: 62ch;
}
.legal-caps{
  font-size: .85rem;
  letter-spacing: .01em;
}
.legal-list{
  color: var(--text-dim);
  line-height: 1.7;
  margin: 0 0 1rem 1.25rem;
  max-width: 62ch;
}
.legal-list li{
  margin-bottom: .4rem;
}
.legal-page a{
  color: var(--text);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.legal-page a:hover{
  color: var(--accent);
}
.legal-back{
  text-align: left;
  margin-top: 2rem;
}
@media (max-width: 640px){
  .legal-page{
    padding: 7rem 1.25rem 3rem;
  }
}

/* Support form styling — matches legal-page layout with form-specific enhancements */
#support-form{
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
  margin-top: 2.5rem;
}

.form-group{
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.form-group label{
  font-size: .95rem;
  font-weight: 600;
  color: var(--text);
}

.form-group input,
.form-group select,
.form-group textarea{
  padding: .75rem 1rem;
  border: 1px solid rgba(201, 164, 104, .35);
  border-radius: var(--radius);
  background: var(--bg-elevated);
  color: var(--text);
  font-size: .95rem;
  font-family: inherit;
  transition: border-color .2s ease, box-shadow .2s ease;
}

.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus{
  outline: none;
  border-color: var(--accent);
  box-shadow: 0 0 0 2px rgba(201, 164, 104, .15);
}

.form-group textarea{
  resize: vertical;
  min-height: 140px;
}

.error-message{
  font-size: .85rem;
  color: #e74c3c;
  display: none;
  margin-top: .25rem;
}

/* Support form submit button */
#support-form .btn-primary{
  align-self: center;
  margin-top: .5rem;
}

/* Thank You page — centered layout */
.thank-you-page{
  text-align: center;
}

.thank-you-page h1{
  font-size: clamp(2rem, 5vw, 2.75rem);
  font-weight: 600;
  line-height: 1.25;
  margin-bottom: 1.5rem;
  color: var(--text);
}

.thank-you-page > p{
  max-width: 640px;
  margin: 0 auto 2.5rem;
  color: var(--text-dim);
  line-height: 1.7;
  font-size: 1rem;
}

.thank-you-page .simple-page-back{
  text-align: center;
}

@media (max-width: 640px){
  #support-form{
    gap: 1.5rem;
  }

  .form-group input,
  .form-group select,
  .form-group textarea{
    font-size: 16px; /* prevents mobile zoom on focus */
  }
}

.lang-picker{
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: .75rem;
  width: 100%;
  max-width: 320px;
  margin-bottom: 2.5rem;
}
.lang-picker-item{
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: .5rem;
  padding: .9rem 1.5rem;
  border-radius: var(--radius);
  background: var(--bg-elevated);
  border: 1px solid rgba(240,230,216,.1);
  transition: transform .15s ease, border-color .15s ease;
}
.lang-picker-item:hover{
  transform: translateY(-2px);
  border-color: var(--color-brass);
}
.lang-picker-native{
  font-size: 1.1rem;
  font-weight: 600;
}

@media (max-width: 640px){
  .hero{
    min-height: 70vh;
  }
  .hero-slide{
    /* Container itself is now centered on mobile (2026-07-06), not just
       its inner logo/buttons — a further step past the earlier "box
       stays right, contents center" arrangement that was meant for wide/
       "horizontal" screens. Symmetric 1rem side padding to match
       (previously right-only, back when the box was right-aligned). */
    justify-content: center;
    padding: 0 1rem 3rem;
  }
  .hero-arrow{
    width: 38px;
    height: 38px;
    font-size: 1.25rem;
  }
  .hero-arrow--prev{
    left: .6rem;
  }
  .hero-arrow--next{
    right: .6rem;
  }
  /* Extra dark corner behind the site logo/icon-menu area (2026-07-06):
     the vertical crop's own artwork has a lighter blue-toned wall/window
     patch near its top-right, and the shared .hero-scrim (tuned for the
     wide desktop hero) doesn't fully darken it at mobile widths — this
     radial patch mutes just that corner without changing the rest of
     the framing. The right-side linear darkening gradient (needed on
     desktop, where the text column sits flush against the right edge)
     is dropped here (2026-07-06) — content is centered on mobile now, so
     that band no longer lines up with anything and just reads as a
     stray blue-ish stripe. Bottom fade is kept for legibility. */
  .hero-scrim{
    background:
      radial-gradient(ellipse 220px 200px at 100% 0%, var(--bg) 0%, rgba(27,31,46,0) 70%),
      linear-gradient(to top, var(--bg) 5%, rgba(27,31,46,0) 55%);
  }
  .series-section,
  .episode-list-section{
    padding: 2rem 1.25rem 4rem;
    text-align: left;
  }
  .series-card,
  .series-card--placeholder{
    flex: 0 0 calc((100% - 2rem) / 2.5);
  }
  .btn-play,
  .btn-icon{
    width: 72px;
    height: 72px;
  }
  /* Mobile now matches the horizontal-screen alignment (2026-07-06):
     logo/buttons centered, synopsis left-justified, inherited from the
     base rules above — this block only keeps the mobile-specific width
     and spacing tweaks. */
  .hero-content{
    /* "Show info" column occupies ~80% of the screen width (2026-07-05),
       measured against .hero's now-padding-free box, i.e. 80% of the
       true screen width rather than 80% of an already-inset container. */
    width: 80%;
    max-width: 80%;
  }
  .hero-actions{
    gap: .7rem;
  }


  /* Card info on mobile (2026-07-06): the series title is dropped since
     it's already carried by the poster's own logo overlay, and the
     limited real estate doesn't need it repeated as text underneath.
     Whatever text remains (the genre/rating line) is set 40% smaller. */
  .series-info h3{
    display: none;
  }
  .series-meta{
    font-size: .48rem; /* .8rem base, 40% smaller */
    gap: .18rem;
    overflow-x: auto;
    flex-wrap: nowrap;
    scrollbar-width: none; /* Firefox: hide the scrollbar, keep the scroll */
  }
  .series-meta::-webkit-scrollbar{
    display: none; /* Chrome/Safari: hide the scrollbar, keep the scroll */
  }
  .series-meta .rating-badge.small,
  .series-meta .genre-tag.small{
    font-size: .42rem; /* .7rem base, 40% smaller */
    padding: .1rem .26rem;
  }

  /* Footer watermark/copyright ~40% smaller on mobile (2026-07-06). */
  .footer-watermark{
    width: 84px; /* 140px base, 40% smaller */
  }
  .footer-copyright{
    font-size: .48rem; /* .8rem base (inherited from .site-footer), 40% smaller */
  }
}

/* =========================================================
   Landscape orientation (tablets and landscape phones > 640px) —
   keep hero right-justified like desktop
   ========================================================= */
@media (orientation: landscape) and (min-width: 641px){
  .hero{
    min-height: 70vh;
  }
  .hero-slide{
    /* Keep right-aligned for horizontal tablets — desktop behavior */
    justify-content: flex-end;
    padding: 0 1rem 3rem;
  }
  .hero-scrim{
    background:
      linear-gradient(to top, var(--bg) 5%, rgba(27,31,46,0) 55%);
  }
  .hero-content{
    /* 40% width, positioned so its left edge starts at screen center (50%)
       by adding right margin to pull it back from the right edge */
    width: 40%;
    max-width: 40%;
    margin-right: 10%;
  }
  /* Horizontal screens: 5.5 thumbnails per view, left-justified title */
  .series-section,
  .episode-list-section{
    text-align: left;
  }
  .series-card,
  .series-card--placeholder{
    flex: 0 0 calc((100% - 4.5rem) / 5.5);
  }
}

/* =========================================================
   Phone in landscape orientation — short viewport height, but
   often wide enough (>640px logical width) to fall outside the
   portrait-mobile breakpoint above while still far too cramped for
   the desktop-scale hero. Without this, the full desktop-sized site
   logo and hero content overflowed the short hero and visibly
   overlapped each other (2026-07-06 bugfix, caught on Rolando's own
   phone). Targeted with orientation: landscape + a low max-height
   rather than max-width, since width alone can't tell a landscape
   phone apart from a small desktop/tablet window.
   ========================================================= */
@media (orientation: landscape) and (max-height: 500px){
  .hero{
    min-height: 100vh;
  }
  .hero-slide{
    /* Right-aligned here (2026-07-06), matching desktop rather than the
       portrait-mobile centering above — landscape phones are wide
       enough that the desktop-style right-side placement reads fine
       once the content itself is scaled down (below). */
    justify-content: flex-end;
    padding: .5rem 1rem;
  }
  .hero-dots{
    bottom: .5rem;
  }
  /* Same fix as portrait mobile (2026-07-06): the desktop .hero-scrim's
     right-side linear darkening is tuned as a small fraction of a huge
     desktop-width image — on a ~800px-wide landscape phone that same
     percentage-based gradient eats a visually dominant chunk of the
     screen, reading as "the image stops and a solid color fills the
     rest" rather than a subtle legibility aid. Dropped for landscape
     too; bottom fade stays. Desktop itself is untouched. */
  .hero-scrim{
    background: linear-gradient(to top, var(--bg) 5%, rgba(27,31,46,0) 55%);
  }
  /* Landscape phones: 5.5 thumbnails per view, left-justified title */
  .series-section,
  .episode-list-section{
    text-align: left;
  }
  .series-card,
  .series-card--placeholder{
    flex: 0 0 calc((100% - 4.5rem) / 5.5);
  }
  .site-logo{
    top: .6rem;
    right: .75rem;
  }
  .site-logo img{
    width: 90px;
  }
  .icon-menu{
    top: .6rem;
    left: .6rem;
    width: 42px;
    height: 42px;
  }
  .menu-toggle,
  .icon-menu .menu-item{
    width: 42px;
    height: 42px;
  }
  .icon-menu .menu-item:hover,
  .icon-menu.open .menu-item{
    transform: translateY(calc(var(--i) * 48px)) scale(1);
  }
  .hero-content{
    /* About half the width/scale the wider-screen rules would otherwise
       give it here — this is exactly what was overflowing the short
       hero and colliding with the site logo. */
    width: 50%;
    max-width: 50%;
  }
  .hero-logo{
    width: min(160px, 30vw);
    margin-bottom: .4rem;
  }
  .hero-tagline{
    font-size: .65rem;
    margin-bottom: .5rem;
  }
  .hero-tags{
    gap: .3rem;
    margin-bottom: .5rem;
  }
  .hero-actions{
    gap: .4rem;
  }
  .btn-play,
  .btn-icon{
    width: 26px;
    height: 26px;
  }
  .hero-tags .rating-badge,
  .hero-tags .genre-tag{
    font-size: .35rem;
    padding: .12rem .28rem;
  }

  /* Footer watermark/copyright ~40% smaller on mobile (2026-07-06) —
     same treatment as the portrait breakpoint below, repeated here since
     landscape phones don't inherit from that max-width query. */
  .footer-watermark{
    width: 84px; /* 140px base, 40% smaller */
  }
  .footer-copyright{
    font-size: .48rem; /* .8rem base (inherited from .site-footer), 40% smaller */
  }
}

/* =========================================================
   Vertical tablets (portrait orientation, 641px–1024px width)
   Center the hero content and series section
   ========================================================= */
@media (orientation: portrait) and (min-width: 641px) and (max-width: 1024px){
  .hero-slide{
    justify-content: center;
    padding: 0 1rem 3rem;
  }
  .hero-scrim{
    background:
      radial-gradient(ellipse 220px 200px at 100% 0%, var(--bg) 0%, rgba(27,31,46,0) 70%),
      linear-gradient(to top, var(--bg) 5%, rgba(27,31,46,0) 55%);
  }
  .hero-content{
    width: 80%;
    max-width: 80%;
  }
  /* BUGFIX 2026-07-08: .hero-tagline's base rule (margin-left: 0;
     margin-right: auto;) exists to keep the synopsis flush against the
     left edge of .hero-content on wide/"horizontal" screens. On phones
     that's invisible — the tagline's own max-width: 46ch cap is already
     wider than the available column, so it fills the column regardless.
     On a vertical tablet the 80%-wide column is wide enough that 46ch is
     genuinely narrower than it, so margin-right: auto pushed the whole
     paragraph against the left edge while the centered logo/buttons
     stayed in the middle — reading as the entire block sitting off-
     center to the left. Centering the tagline's own box (independent of
     its internal text-align: left) re-aligns it with the rest of the
     centered column, matching the phone-portrait look. .hero-tags
     (2026-07-11) gets the same treatment so the tags row re-centers
     along with the synopsis instead of drifting left on its own. */
  .hero-tagline,
  .hero-tags{
    margin-left: auto;
    margin-right: auto;
  }
  .series-section,
  .episode-list-section{
    margin: 0 auto;
    text-align: left;
  }
  .series-card,
  .series-card--placeholder{
    flex: 0 0 calc((100% - 2rem) / 2.5);
  }
}
