@import url('https://fonts.googleapis.com/css2?family=Bebas+Neue&family=DM+Mono:wght@400;500&display=swap');

/* ================================================================
   THEME VARIABLES — edit here to restyle the whole site
   ================================================================ */
:root {
  /* -- colors -- */
  --bg: #000000;
  --bg-alt: #1a1a1a;
  --black: #000000;
  --white: #ffffff;
  --orange: #ff8800;

  /* -- shared decorations -- */
  --border: 4px solid var(--orange);
  --shadow: 3px 3px 0px var(--orange);

  /* -- fonts -- */
  --font-display: 'Bebas Neue', sans-serif;
  --font-mono: 'DM Mono', monospace;

  /* -- background pattern (reused by body + page-content) -- */
  --bg-pattern:
    radial-gradient(circle at 20% 20%, rgba(45, 107, 255, 0.12) 0%, transparent 50%),
    radial-gradient(circle at 80% 80%, rgba(255, 45, 107, 0.1) 0%, transparent 50%),
    radial-gradient(circle at 60% 30%, rgba(0, 229, 204, 0.08) 0%, transparent 40%);

  /* ---- Embed dimensions ----
     Applies to every YouTube/Spotify iframe on the page, wherever it appears
     (music grid or inside an xp window) — matched by src, not by location.
     These feed into the window heights below, so changing an embed's height
     grows/shrinks the window that contains it automatically. */
  --youtube-embed-height: 400px;
  --spotify-embed-height: 200px; /* Spotify's standard "compact" embed — much shorter than a video */
  --spotify-embed-width: 150%;
  --bandcamp-embed-height: 120px; /* Bandcamp's compact "artwork + player, no tracklist" embed */

  /* ---- XP window module ----
     Window HEIGHT is derived, not hardcoded: each window's total height =
     its embed's height + the fixed "chrome" around it (titlebar, menu, info
     rows, status bar). That dependency is what keeps the border wrapping the
     content — resize an embed above and its window resizes to match, instead
     of content spilling past a fixed-height box and hiding the border. */
  --xp-win-width: 880px;

  --xp-titlebar-h: 28px;
  --xp-menu-h: 20px;
  --xp-info-h: 30px;
  --xp-sub-h: 50px;
  --xp-stat-h: 50px;
  --xp-winbody-padding: 8px; /* top+bottom padding around the spotify iframe's wrapper */

  /* video windows (Sewer Simon / Pink Tax / Dramatic):
     titlebar + menu + video + info row + subtitle + status bar */
  --xp-chrome-height: calc(var(--xp-titlebar-h) + var(--xp-menu-h) + var(--xp-info-h) + var(--xp-sub-h) + var(--xp-stat-h));
  --xp-win-height: calc(var(--youtube-embed-height) + var(--xp-chrome-height));

  /* spotify window is structurally simpler (titlebar + padded body + status
     bar only) so it needs its own width + a separately-derived height rather
     than sharing --xp-win-height with the video windows */
  --xp-spotify-win-width: 300px;
  --xp-spotify-chrome-height: calc(var(--xp-titlebar-h) + (var(--xp-winbody-padding) * 2) + var(--xp-stat-h));
  --xp-spotify-win-height: calc(var(--spotify-embed-height) + var(--xp-spotify-chrome-height));

  /* bandcamp window shares the spotify window's structure (titlebar +
     padded body + status bar), just with its own embed height */
  --xp-bandcamp-win-width: 300px;
  --xp-bandcamp-chrome-height: calc(var(--xp-titlebar-h) + (var(--xp-winbody-padding) * 2) + var(--xp-stat-h));
  --xp-bandcamp-win-height: calc(var(--bandcamp-embed-height) + var(--xp-bandcamp-chrome-height));

  --xp-font-family: 'Tahoma', 'DM Mono', sans-serif;
  --xp-font-size-sm: 16px;   /* menus, titlebar text */
  --xp-font-size-md: 27px;   /* body copy, status bar, subtitle */
  --xp-font-size-lg: 18px;   /* "NEW" badge */
  --xp-font-size-song: 20px; /* now-playing song title */

  --xp-titlebar-icon-size: 18px;
  --xp-winbtn-width: 17px;
  --xp-winbtn-height: 13px;

  --xp-photo-height: 280px;
}

/* ── RESET & BASE ── */
*, *::before, *::after {
  box-sizing: border-box;
  margin: 0;
  padding: 0;
}

body {
  background-color: var(--bg);
  background-image: var(--bg-pattern);
  color: var(--black);
  font-family: var(--font-mono);
  font-size: 0.9rem;
  min-height: 100vh;
}

/* ── TICKER ── */
.ticker-wrap {
  position: relative;
  z-index: 3;
  overflow: hidden;
  border-bottom: var(--border);
  background: var(--black);
  padding: 0.9rem 0;
  white-space: nowrap;
}

.ticker {
  display: flex;
  width: max-content;
  white-space: nowrap;
}

.ticker.is-ready {
  animation: ticker-scroll var(--ticker-duration, 20s) linear infinite;
}

.ticker-track {
  display: inline-flex;
  gap: 2rem;
  flex-shrink: 0;
  padding-right: 2rem;
  white-space: nowrap;
}

.ticker span {
  font-size: 1.425rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--white);
}

.ticker-dot { color: var(--orange) !important; }

@media (prefers-reduced-motion: reduce) {
  .ticker.is-ready { animation: none; }
}

@keyframes ticker-scroll {
  0%   { transform: translateX(0); }
  100% { transform: translateX(-50%); }
}

/* ── HERO ── */
.hero {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100vh;
  z-index: 0;
}

.hero-image {
  position: absolute;
  inset: 0;
}

.hero-image img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center center;
  display: block;
}

.hero-image::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  right: 0;
  height: 45%;
  background: linear-gradient(to bottom, transparent, var(--bg));
  pointer-events: none;
}

.hero-overlay {
  position: absolute;
  inset: 0;
  z-index: 2;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 2rem 2.5rem;
}

.hero-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
}

.hero-brand {
  display: inline-block;
  font-family: var(--font-display);
  font-size: clamp(3.5rem, 7vw, 7rem);
  line-height: 1;
  color: var(--black);
  text-decoration: none;
  letter-spacing: 0.04em;
  text-shadow: 3px 3px 0px rgba(255,136,0,0.3);
  margin-top: 1.5rem;
}

.hero-brand:hover { color: var(--orange); }

.hero-nav {
  display: flex;
  gap: 1.5rem;
  padding-top: 0.6rem;
}

/* icon-tile nav links, matching the desktop-icon look used on the
   34 Convictions page (.conv-icon-face / .conv-icon-img /
   .conv-icon-label) — image + label, no button chrome. Icon images
   are placeholders (txt_file_icon_orange.png) until real per-section
   icons are supplied. */
.hero-nav-icon {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.3rem;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.18s ease;
}

.hero-nav-icon img {
  width: 40px;
  height: 40px;
  object-fit: contain;
}

.hero-nav-icon span {
  font-family: var(--xp-font-family);
  font-size: 0.7rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--black);
  text-align: center;
}

.hero-nav-icon:hover {
  transform: scale(1.1);
}

.hero-nav-icon:hover span {
  color: var(--orange);
}

.hero-bottom {
  display: flex;
  justify-content: flex-end;
  padding-bottom: 3rem;
}

.hero-meta {
  font-size: 0.7rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--black);
  opacity: 0.6;
  text-align: right;
  line-height: 1.6;
}

/* ── PAGE CONTENT WRAPPER ──
   Sits below the fixed 100vh hero and scrolls over it. Anything meant to
   appear above the hero must live inside this wrapper (or get its own
   z-index >= 1) — elements added as siblings of it, in the layout template,
   will render underneath the hero regardless of their own color. */
.page-content {
  position: relative;
  z-index: 1;
  margin-top: 100vh;
  background: rgba(0, 0, 0, 0.35);
  backdrop-filter: blur(2px);
  -webkit-backdrop-filter: blur(2px);
  background-image: none;
}

/* ── SECTION SHELL ── */

section {
  border-bottom: var(--border);
}

.section-inner {
  max-width: 1100px;
  margin: 0 auto;
  padding: 4rem 2.5rem;
}

.section-header {
  display: flex;
  align-items: baseline;
  gap: 1.5rem;
  margin-bottom: 3rem;
  padding-bottom: 1rem;
  border-bottom: var(--border);
}

.section-header h2 {
  font-family: var(--font-display);
  font-size: 3rem;
  font-weight: 400;
  letter-spacing: 0.06em;
}

.section-number {
  font-size: 0.68rem;
  letter-spacing: 0.2em;
  color: var(--orange);
  text-transform: lowercase;
  background: var(--bg-alt);
  border: var(--border);
  padding: 0.2rem 0.5rem;
  box-shadow: var(--shadow);
}

#manifesto .section-header h2,
#shows .section-header h2,
#contact .section-header h2 {
  color: var(--orange);
}

#shows .show-name {
  color: var(--orange);
}

/* music section: no padding, no border, no header gap */
#music {
  border-bottom: none;
}

#music .section-inner {
  padding: 2rem 0 0 0;
  max-width: 100%;
}

/* ── MUSIC ── */
.embed-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
}

.embed-block {
  padding: 2rem;
  border-right: var(--border);
  border-bottom: var(--border);
  background: var(--white);
  transition: background 0.15s;
}

.embed-block:hover { background: var(--bg-alt); }
.embed-block:nth-child(even) { border-right: none; }
.embed-block:nth-last-child(-n+2) { border-bottom: none; }

.embed-block .platform-label {
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--orange);
  margin-bottom: 0.75rem;
}

.embed-block .track-title {
  font-family: var(--font-display);
  font-size: 1.6rem;
  letter-spacing: 0.06em;
  margin-bottom: 1rem;
  color: var(--black);
}

.embed-block iframe {
  width: 100%;
  display: block;
  border: none;
}

/* YouTube/Spotify sizing — matched by src so it applies everywhere
   (music grid embeds AND the xp-desktop windows) from one place */
iframe[src*="youtube.com"],
iframe[src*="youtu.be"] {
  height: var(--youtube-embed-height);
}

iframe[src*="spotify.com"] {
  width: var(--spotify-embed-width);
  height: var(--spotify-embed-height);
}

iframe[src*="bandcamp.com"] {
  height: var(--bandcamp-embed-height);
}

/* ── SHOWS ── */
.show-entry {
  display: grid;
  grid-template-columns: 8rem 1fr auto;
  align-items: baseline;
  gap: 2rem;
  padding: 1.5rem 0;
  border-bottom: 1px solid rgba(26,10,46,0.15);
}

.show-entry:last-child { border-bottom: none; }

.show-entry .date {
  font-size: 0.7rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--orange);
}

.show-entry .show-name {
  font-family: var(--font-display);
  font-size: 1.4rem;
  letter-spacing: 0.06em;
  color: var(--orange);
}

.show-entry .venue {
  font-size: 0.75rem;
  color: var(--orange);
  margin-top: 0.2rem;
}

.show-entry a.ticket-link {
  font-size: 0.65rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--black);
  text-decoration: none;
  border: var(--border);
  padding: 0.4rem 0.8rem;
  background: var(--bg-alt);
  box-shadow: var(--shadow);
  transition: background 0.15s, color 0.15s;
  white-space: nowrap;
}

.show-entry a.ticket-link:hover {
  background: var(--black);
  color: var(--white);
}

.no-shows {
  color: var(--orange);
  font-size: 0.78rem;
  letter-spacing: 0.08em;
}

/* ── CONTACT ── */
.contact-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  border: var(--border);
  box-shadow: var(--shadow);
  background: var(--white);
}

.contact-col {
  padding: 2.5rem;
  border-right: var(--border);
}

.contact-col:last-child { border-right: none; }

.contact-col h3 {
  font-size: 0.62rem;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--orange);
  margin-bottom: 1.5rem;
}

.social-links {
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
}

/* social links + email share the same display-font link style;
   only size differs, so that's the one thing declared per-selector */
.social-links a,
.contact-email a {
  font-family: var(--font-display);
  letter-spacing: 0.06em;
  color: var(--black);
  text-decoration: none;
  transition: color 0.15s;
}

.social-links a { font-size: 1.5rem; }
.contact-email a { font-size: 1.3rem; letter-spacing: 0.04em; }

.social-links a:hover,
.contact-email a:hover { color: var(--orange); }

/* ── CONTACT FORM ── */
.contact-form {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.form-field {
  display: flex;
  flex-direction: column;
  gap: 0.4rem;
}

.form-field label {
  font-size: 0.62rem;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--orange);
}

.form-field input,
.form-field textarea {
  background: var(--bg);
  border: none;
  border-bottom: var(--border);
  padding: 0.6rem 0;
  font-family: var(--font-mono);
  font-size: 0.85rem;
  color: var(--black);
  outline: none;
  width: 100%;
  resize: none;
  transition: border-color 0.15s;
}

.form-field input::placeholder,
.form-field textarea::placeholder {
  color: var(--orange);
  opacity: 0.6;
}

.form-field input:focus,
.form-field textarea:focus {
  border-bottom: 2px solid var(--orange);
}

.contact-form button {
  align-self: flex-start;
  background: var(--black);
  color: var(--white);
  border: var(--border);
  padding: 0.75rem 1.75rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  cursor: pointer;
  box-shadow: var(--shadow);
  transition: background 0.15s, box-shadow 0.1s, transform 0.1s;
}

.contact-form button:hover {
  background: var(--orange);
  box-shadow: none;
  transform: translate(3px, 3px);
}

/* ── FOOTER ── */
footer {
  position: relative;
  z-index: 1;
  background: var(--bg);
  padding: 1.5rem 2.5rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: 0.65rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--orange);
  border-top: var(--border);
}

/* ── IMPRESSUM POPUP ── */
.xp-overlay {
  position: fixed;
  inset: 0;
  background: rgba(26,10,46,0.6);
  z-index: 1000;
  display: flex;
  align-items: center;
  justify-content: center;
}

.xp-window {
  width: min(480px, 92vw);
  border: 2px solid var(--orange);
  box-shadow: 4px 4px 0 rgba(255,136,0,0.45);
  background: var(--black);
  font-family: var(--font-mono);
}

.xp-titlebar {
  background: var(--black);
  color: var(--orange);
  border-bottom: 1px solid var(--orange);
  padding: 0.35rem 0.6rem;
  font-size: 0.72rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
  letter-spacing: 0.02em;
}

.xp-close {
  background: var(--black);
  color: var(--orange);
  border: 1px solid var(--orange);
  padding: 0 0.4rem;
  font-size: 0.7rem;
  cursor: pointer;
  line-height: 1.4;
}

.xp-close:hover {
  background: var(--orange);
  color: var(--black);
}

.xp-body {
  padding: 1.5rem;
  color: var(--orange);
  font-size: 0.78rem;
}

.xp-intro {
  font-style: italic;
  opacity: 0.6;
  margin-bottom: 1.25rem;
  font-size: 0.72rem;
  color: var(--orange);
}

.impressum-data {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: 0.5rem 1.5rem;
  margin-bottom: 1.5rem;
}

.impressum-data dt {
  font-size: 0.62rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  opacity: 0.75;
  padding-top: 0.1rem;
  color: var(--orange);
}

.impressum-data dd { margin: 0; }
.impressum-data dd a { color: var(--orange); }

.xp-ok {
  display: block;
  margin: 0 auto;
  background: var(--black);
  border: 2px solid var(--orange);
  padding: 0.3rem 2.5rem;
  font-family: var(--font-mono);
  font-size: 0.75rem;
  cursor: pointer;
  letter-spacing: 0.08em;
  color: var(--orange);
}

.xp-ok:hover {
  background: var(--orange);
  color: var(--black);
}

.impressum-trigger {
  background: none;
  border: none;
  font-family: var(--font-mono);
  font-size: 0.65rem;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--orange);
  cursor: pointer;
  padding: 0;
  transition: color 0.15s;
}

.impressum-trigger:hover { color: var(--orange); }

/* ── XP DESKTOP ──
   All faux-window sizing/typography comes from the --xp-* variables
   defined at the top of the file — resize/restyle every window there. */
.xp-desktop-area {
  position: relative;
  width: 100%;
  height: 100vh;
  overflow: visible;
}

/* window frame */
.xp-win {
  position: absolute;
  width: var(--xp-win-width);
  height: var(--xp-win-height);
  background: var(--black);
  border: 2px solid var(--orange);
  box-shadow: 3px 3px 0 rgba(255,136,0,0.45);
  cursor: default;
  z-index: 1;
}

/* Spotify window is smaller/shorter than the video windows —
   sized from its own dedicated variables instead of --xp-win-width/height */
#win-spotify {
  width: var(--xp-spotify-win-width);
  height: var(--xp-spotify-win-height);
}

/* Bandcamp window follows the same "smaller than video windows" logic */
#win-bandcamp {
  width: var(--xp-bandcamp-win-width);
  height: var(--xp-bandcamp-win-height);
}

/* titlebar + minimize/maximize/close buttons */
.xp-wintitle {
  background: var(--black);
  padding: 3px 4px;
  display: flex;
  align-items: center;
  gap: 4px;
  cursor: move;
  user-select: none;
  font-family: var(--xp-font-family);
  font-size: var(--xp-font-size-sm);
  font-weight: bold;
  color: var(--orange);
  text-shadow: none;
  white-space: nowrap;
  overflow: hidden;
}

.xp-wintitle-ico { font-size: var(--xp-titlebar-icon-size); flex-shrink: 0; }

.xp-wintitle > span:nth-child(2) {
  flex: 1;
  overflow: hidden;
  text-overflow: ellipsis;
}

.xp-winbtns {
  display: flex;
  gap: 2px;
  flex-shrink: 0;
  margin-left: auto;
}

.xp-winbtns span {
  width: var(--xp-winbtn-width);
  height: var(--xp-winbtn-height);
  border: 1px solid var(--orange);
  font-size: 9px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--black);
  color: var(--orange);
  cursor: pointer;
  font-family: var(--xp-font-family);
  line-height: 1;
}

/* hide minimise and maximise buttons in popup windows — show only the close (X) */
.xp-winbtns span:nth-child(1),
.xp-winbtns span:nth-child(2) {
  display: none;
}

/* .xp-winclose is itself a .xp-winbtns span, so it already inherits the
   base button look above — only the hover state needs its own rule */
.xp-winclose:hover {
  filter: brightness(1.2);
  background: var(--orange) !important;
  color: var(--black) !important;
}

/* File/View/Play menu bar + its dropdown */
.xp-winmenu {
  background: var(--black);
  border-bottom: 1px solid var(--orange);
  padding: 1px 4px;
  display: flex;
  font-family: var(--xp-font-family);
  font-size: var(--xp-font-size-sm);
  position: relative;
  z-index: 50;
}

.xp-menuitem {
  padding: 2px 8px;
  cursor: pointer;
  color: var(--orange);
  user-select: none;
  position: relative;
}

.xp-menuitem:hover {
  background: rgba(255,136,0,0.15);
  color: var(--black);
}

.xp-dropdown {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  background: var(--black);
  border: 1px solid var(--orange);
  border-top: none;
  box-shadow: 2px 2px 4px rgba(0,0,0,0.4);
  padding: 8px 10px;
  font-family: var(--xp-font-family);
  font-size: var(--xp-font-size-sm);
  color: var(--orange);
  z-index: 200;
  width: 280px;
  line-height: 1.6;
  white-space: normal;
}

/* fallback "photo" view toggled in by the View menu (see toggleView() in main.js) */
.xp-viewpanel { width: 100%; }

.xp-photo-placeholder {
  width: 100%;
  height: var(--xp-photo-height);
  background: var(--black);
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: var(--xp-font-family);
  font-size: var(--xp-font-size-md);
  color: var(--orange);
  border-bottom: 1px solid var(--orange);
}

/* embed wrapper (video/spotify iframe) */
.xp-winbody { padding: 0; background: var(--black); }

.xp-winbody iframe,
.xp-win iframe {
  width: 100%;
  display: block;
  border: none;
}

/* now-playing info row, subtitle + status bar, "NEW" badge */
.xp-wininfo {
  padding: 5px 8px 2px;
  display: flex;
  align-items: center;
  gap: 6px;
  font-family: var(--xp-font-family);
  color: var(--orange);
}

@keyframes xp-blink {
  0%, 100% { opacity: 1; }
  50% { opacity: 0; }
}

.xp-winsong {
  font-size: var(--xp-font-size-song);
  font-weight: bold;
  color: var(--orange);
}

.xp-winsub {
  padding: 0 8px 8px;
  font-size: var(--xp-font-size-md);
  color: var(--orange);
  font-family: var(--xp-font-family);
}

.xp-winstat {
  border-top: 1px solid rgba(255,136,0,0.3);
  padding: 4px 8px;
  font-size: var(--xp-font-size-md);
  color: var(--orange);
  background: var(--black);
  display: flex;
  justify-content: space-between;
  font-family: var(--xp-font-family);
}

.xp-new {
  background: var(--orange);
  color: var(--black);
  font-size: var(--xp-font-size-lg);
  font-weight: bold;
  padding: 2px 7px;
  font-family: 'Tahoma', sans-serif;
  animation: xp-blink 0.8s step-end infinite;
}

.xp-playstate { transition: color 0.3s; }

/* ================================================================
   34 CONVICTIONS PROMO PAGE
   ================================================================ */
body.convictions-page {
  min-height: 100vh;
}

.conv-topbar {
  position: relative;
  z-index: 3;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 1.25rem 2.5rem;
  border-bottom: var(--border);
  background: var(--black);
}

.conv-brand {
  font-family: var(--font-display);
  font-size: clamp(1.6rem, 3vw, 2.4rem);
  letter-spacing: 0.04em;
  color: var(--white);
  text-decoration: none;
}

.conv-brand:hover { color: var(--orange); }

.conv-stage {
  position: relative;
  z-index: 1;
  min-height: calc(100vh - 6.5rem);
  padding: 3rem 2.5rem;
}

/* Base/default layout: everything stacks in normal document flow,
   static-positioned, so nothing can ever overlap anything else.
   This is the layout for any viewport that isn't reliably wide
   enough to fit the video (fixed 880px) plus two note windows
   beside it without them colliding — see the min-width:1500px
   override below for the floating "desktop" version. */
.conv-desktop-area {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 1.5rem;
}

.conv-main-win {
  position: static;
  width: 100%;
  max-width: 1560px; /* 1500px TV + 30px flashing text border on each side */
  height: auto;
  z-index: 5;
  cursor: default;
  margin: 0 auto;
}

/* the video "plays inside" tvscreen.png — the image supplies the CRT
   bezel, and .conv-tv-screen is an absolutely-positioned black cutout
   matched to the screen area baked into that image, with the iframe
   filling it edge-to-edge (inset:0) so the embed fills the visible
   screen with no gaps.
   .conv-tv-outer reserves 30px of padding on every side for the 4
   .conv-tv-border strips (absolutely positioned over that padding),
   which keeps .conv-tv's own box undisturbed so the screen cutout's
   percentages stay aligned with the image regardless of border
   thickness. */
.conv-tv-outer {
  position: relative;
  padding: 30px;
}

/* the border strips: a shared flashing red/orange/white/blue
   background (kept in lockstep across all 4 since they share one
   animation), each filled with repeated marquee text. The text is
   plain white with mix-blend-mode:difference, isolated to just this
   strip's own backdrop — that makes it render as the mathematical
   negative of whatever the strip's current background colour is,
   automatically, with no need to hand-sync a second colour animation. */
.conv-tv-border {
  position: absolute;
  overflow: hidden;
  isolation: isolate;
  display: flex;
  align-items: center;
  animation: conv-tv-border-flash 4s linear infinite;
}

.conv-tv-border-top,
.conv-tv-border-bottom {
  left: 0;
  right: 0;
  height: 30px;
}

.conv-tv-border-top { top: 0; }
.conv-tv-border-bottom { bottom: 0; }

.conv-tv-border-left,
.conv-tv-border-right {
  top: 30px;
  bottom: 30px;
  width: 30px;
  writing-mode: vertical-rl;
}

.conv-tv-border-left { left: 0; }
.conv-tv-border-right { right: 0; }

.conv-tv-border-text {
  color: #fff;
  mix-blend-mode: difference;
  white-space: nowrap;
  font-family: var(--xp-font-family);
  font-size: 0.8rem;
  font-weight: bold;
  letter-spacing: 0.05em;
}

@keyframes conv-tv-border-flash {
  0%, 24%   { background: #ff2d2d; }
  25%, 49%  { background: #ff8800; }
  50%, 74%  { background: #ffffff; }
  75%, 99%  { background: #2d6bff; }
  100%      { background: #ff2d2d; }
}

.conv-tv {
  position: relative;
  width: 100%;
  aspect-ratio: 1015 / 729;
}

.conv-tv-frame {
  display: block;
  width: 100%;
  height: 100%;
}

.conv-tv-screen {
  position: absolute;
  left: 15%;
  top: 11%;
  width: 69%;
  height: 72%;
  overflow: hidden;
}

.conv-tv-screen iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: none;
  display: block;
}

/* physical-looking play/pause button on the TV's bottom-left bezel —
   toggles the embed via the YouTube iframe postMessage API (see
   convToggleMainPlay() in 34convictions.njk). Sized/positioned as a %
   of .conv-tv so it stays in the bezel margin (which starts around
   84-85% across/down) at any TV size. */
.conv-tv-playbtn {
  position: absolute;
  left: 3%;
  bottom: 3%;
  width: 9%;
  aspect-ratio: 269 / 189;
  padding: 0;
  border: 3px solid #000;
  /* buttons default to box-sizing:border-box, which would shrink the
     content box the border wraps by 3px on every side — negligible for
     this near-square button, but for .conv-tv-livebtn's much flatter
     310x94 bar that 3px comes out of a much smaller height than width,
     visibly skewing its aspect ratio and pillarboxing the image inside
     it (object-fit:contain letterboxing to match). content-box keeps
     width/aspect-ratio describing the image area itself, with the
     border drawn outside it instead of eating into it. */
  box-sizing: content-box;
  background: transparent;
  cursor: pointer;
  z-index: 6;
}

.conv-tv-playbtn img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}

/* mirrors .conv-tv-playbtn to the opposite (bottom-right) corner of the
   bezel — LiveButton1.jpg is a wide bar (310x94) rather than the play
   button's near-square icon, so it gets its own width/aspect-ratio
   instead of sharing .conv-tv-playbtn's */
.conv-tv-livebtn {
  left: auto;
  right: 3.6%;
  width: 12.8%;
  aspect-ratio: 310 / 94;
}

/* red tint while the video is playing — sepia+saturate+hue-rotate
   pushes the button's natural greys toward red without flattening
   out its shading/detail the way brightness(0) would */
.conv-tv-playbtn.is-playing img {
  filter: sepia(1) saturate(8) hue-rotate(-20deg) brightness(0.85) contrast(1.1);
}

/* text windows — draggable on wide desktops via convStartDrag()/
   convCloseWin() in 34convictions.njk, static/stacked otherwise.
   Each one starts as a small icon (.is-icon) and unfurls into the
   full window on click — see .conv-note-win.is-icon below. Width
   and max-height are both explicit lengths (never `auto`/`none`) so
   the icon⇄window transition can animate smoothly.
   Selector is .xp-win.conv-note-win (not just .conv-note-win) so it
   unambiguously outranks .xp-win's own fixed height/width — those are
   sized for the homepage's video windows and would otherwise leave a
   tall dead-space gap here (most visible on win-bandcamp-embed, which
   has a footer row that exposes exactly how much space was left over). */
.xp-win.conv-note-win {
  position: static;
  width: 100%;
  max-width: 880px;
  max-height: 1200px;
  height: auto;
  z-index: 10;
  margin: 0 auto;
  overflow: hidden;
  transition: width 0.32s ease, max-height 0.32s ease, opacity 0.2s ease, transform 0.18s ease;
}

/* lyrics.txt holds a full song, so it gets 50% more width than the
   other note windows — here for the stacked layout, and again in the
   wide-desktop floating layout below */
#win-lyrics {
  max-width: 1320px;
}

/* the Bandcamp embed (unlike the text windows) has a fixed intrinsic
   size, so it gets a fixed width instead of reflowing — this one rule
   covers it in both the stacked layout and the wide-desktop floating
   layout below, since an ID beats the .conv-note-win width rules in
   either context. 450px (450 = homepage's 300px + 50%) and the iframe
   height below are deliberately scoped to #win-bandcamp-embed — this
   page uses its own id specifically so it can't collide with the
   homepage's #win-bandcamp rules (which have their own fixed size and
   a mobile !important override that would otherwise win here too). */
#win-bandcamp-embed:not(.is-icon) {
  width: 450px;
}

#win-bandcamp-embed iframe[src*="bandcamp.com"] {
  height: 180px; /* homepage's 120px + 50% */
}

.conv-note-body {
  padding: 0.9rem 1rem;
  font-family: var(--xp-font-family);
  font-size: var(--xp-font-size-md);
  color: var(--orange);
  line-height: 1.6;
}

.conv-note-verse p {
  white-space: pre-line;
}

/* the real lyrics are much longer than a short blurb — give the
   window a generous cap and let it scroll for whatever doesn't fit,
   instead of the window growing tall enough to push into (or past)
   neighboring windows */
.conv-note-verse {
  max-height: 70vh;
  overflow-y: auto;
}

/* trumpgif.gif window — an image instead of text/an embed, so it just
   scales to the window's width and keeps its own aspect ratio */
.conv-gif-img {
  width: 100%;
  height: auto;
  display: block;
}

/* unnamed placeholder icon (hamsickle.png) — a plain external link, not
   a window like the others, so it reuses their closed-icon footprint
   (207x243, same as .xp-win.conv-note-win.is-icon) without any of the
   open/close/drag machinery those actually need. */
.conv-link-icon {
  position: static;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 207px;
  max-height: 243px;
  margin: 0 auto;
  padding: 1.125rem;
  text-decoration: none;
  cursor: pointer;
  transition: transform 0.18s ease;
}

.conv-link-icon:hover {
  transform: scale(1.08);
}

/* groups link icons (Instagram, streaming platforms, the hamsickle/
   trump easter eggs) into a single column — plain flow here so they
   just stack in document order at any width below the wide-desktop
   breakpoint, where the media query below turns each stack into an
   absolutely-positioned, vertically-centered column beside the TV. */
.conv-icon-stack {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1.5rem;
}

/* ── ICON STATE ──
   Before it's opened, a text window collapses down to a small
   clickable desktop icon (image + label) using
   assets/images/txt_file_icon_orange.png. Clicking it removes
   .is-icon, which grows the window back to its full size in place —
   see convOpenWin()/convCloseWin() in 34convictions.njk. */
.conv-icon-face {
  display: none;
  width: 100%;
  height: 100%;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.75rem;
  padding: 1.125rem;
}

.conv-icon-img {
  width: 99px;
  height: 99px;
  object-fit: contain;
}

.conv-icon-label {
  font-family: var(--xp-font-family);
  font-size: 1.35rem;
  color: var(--orange);
  text-align: center;
  line-height: 1.2;
}

.xp-win.conv-note-win.is-icon {
  width: 207px;
  max-height: 243px;
  background: transparent;
  border: none;
  box-shadow: none;
  cursor: pointer;
}

.xp-win.conv-note-win.is-icon:hover {
  transform: scale(1.08);
}

.xp-win.conv-note-win.is-icon:hover .conv-icon-label {
  color: var(--white);
}

.is-icon .conv-icon-face { display: flex; }

.is-icon .xp-wintitle,
.is-icon .conv-note-body,
.is-icon .xp-winbody,
.is-icon .xp-winstat {
  display: none;
}

/* trumphead.png — falls slowly through the gap between the TV and the
   left-hand icon column, spinning, looping forever. Only shown in the
   wide-desktop layout below: that gap doesn't exist in the stacked
   layout (TV and icons are both full-width there), so it stays hidden
   until the media query turns it on.
   Both the fall and the spin animate `transform` only (translateY on
   the outer element, rotate on the inner image) rather than `top` —
   `top` is a layout property, so animating it forces the browser to
   re-run layout and paint on every single frame; `transform` can run
   entirely on the compositor (GPU), which is what actually fixes the
   stutter, not just a smaller/cheaper animation. */
.conv-trumphead {
  display: none;
  position: absolute;
  left: 15%;
  top: 0;
  width: 9%;
  max-width: 130px;
  aspect-ratio: 472 / 698;
  z-index: 2;
  pointer-events: none;
  will-change: transform;
}

.conv-trumphead-img {
  width: 100%;
  height: 100%;
  display: block;
  will-change: transform;
}

@keyframes conv-trumphead-fall {
  from { transform: translateY(-250px); }
  to   { transform: translateY(1500px); }
}

@keyframes conv-trumphead-spin {
  from { transform: rotate(0deg); }
  to   { transform: rotate(360deg); }
}

/* ── WIDE DESKTOP ──
   Float the note windows to the left/right margins beside the TV
   (fixed 1560px including its 30px border) and pin credits to the
   bottom-left. about.txt and lyrics.txt are both wider than credits
   (about is landscape so its one paragraph reads as a few wide lines
   instead of a tall narrow column; lyrics holds a full song), so the
   threshold is set by the wider of the two, about's 450px: at
   2800px, margin-per-side (~(100vw-1640px)/2 = ~580px) comfortably
   exceeds it + offset (~535px) — i.e. neither can reach the TV.
   Below 2800px everything just stacks — see the base rules above. */
@media (min-width: 2800px) {
  .conv-desktop-area {
    display: block;
    /* tall enough that the centered .conv-icon-stack columns (up to 4
       icons on the taller side) clear the top-anchored/bottom-anchored
       windows (about/lyrics at top:8%, credits/bandcamp at bottom:8%)
       with room to spare — the stacks self-center via flexbox, so
       raise this if more icons get added later and it gets tight again. */
    min-height: max(80vh, 1300px);
  }

  .conv-trumphead {
    display: block;
    animation: conv-trumphead-fall 16s linear infinite;
  }

  .conv-trumphead-img {
    animation: conv-trumphead-spin 12s linear infinite;
  }

  .conv-main-win {
    position: absolute;
    left: 50%;
    top: 50%;
    transform: translate(-50%, -50%);
    margin: 0;
  }

  .xp-win.conv-note-win {
    position: absolute;
    width: clamp(200px, 15vw, 260px);
    margin: 0;
  }

  #win-about          { left: 2%;  top: 8%; }
  #win-lyrics         { right: 2%; top: 8%; }
  #win-credits        { left: 2%;  bottom: 8%; }
  #win-bandcamp-embed { right: 2%; bottom: 8%; }

  /* vertically centered clusters of link icons, between about/lyrics
     (top) and credits/bandcamp (bottom) on each side. A flex stack
     (base rule is with .conv-icon-stack in the main stylesheet body)
     instead of hand-placed offsets, so icons can be added or removed
     without re-deriving pixel math for every sibling. */
  .conv-icon-stack {
    position: absolute;
    top: 50%;
    transform: translateY(-50%);
  }

  .conv-icon-stack-left  { left: 2%; }
  .conv-icon-stack-right { right: 2%; }

  /* win-trump is a .xp-win.conv-note-win, which the rule above forces
     position:absolute — undo that so it flows as a normal flex child
     of its stack instead of escaping it */
  .conv-icon-stack > .xp-win.conv-note-win {
    position: static;
    margin: 0;
  }

  /* :not(.is-icon) so these don't fight the small fixed icon size
     (.xp-win.conv-note-win.is-icon) before a window's been opened */
  #win-about:not(.is-icon)  { width: clamp(280px, 20vw, 450px); }
  #win-lyrics:not(.is-icon) { width: clamp(300px, 22.5vw, 390px); }
}

/* ── RESPONSIVE ── */
@media (max-width: 768px) {
  /* xp desktop windows */
  .xp-desktop-area { height: auto; min-height: 900px; overflow: hidden; }
  .xp-win { width: 85vw !important; }
  #win-sewer  { left: 5% !important; top: 10px !important; }
  #win-pinktax { left: 5% !important; top: 330px !important; }
  #win-dramatic { left: 5% !important; top: 650px !important; }
  #win-spotify { left: 5% !important; top: 970px !important; width: 85vw !important; }
  #win-bandcamp { left: 5% !important; top: 1290px !important; width: 85vw !important; }

  .conv-topbar { padding: 1rem 1.25rem; }
  .conv-stage { padding: 2rem 1.25rem; }

  /* everything else */
  .hero-overlay { padding: 1.5rem 1.25rem; }
  .hero-brand { font-size: clamp(2.5rem, 10vw, 4rem); }
  .hero-nav { gap: 0.85rem; }
  .hero-nav-icon img { width: 30px; height: 30px; }
  .hero-nav-icon span { font-size: 0.6rem; }
  .hero-bottom { padding-bottom: 4rem; }
  .section-inner { padding: 3rem 1.25rem; }
  .embed-grid { grid-template-columns: 1fr; }
  .embed-block { border-right: none !important; border-bottom: var(--border) !important; }
  .embed-block:last-child { border-bottom: none !important; }
  .contact-grid { grid-template-columns: 1fr; }
  .contact-col { border-right: none; border-bottom: var(--border); }
  .contact-col:last-child { border-bottom: none; }
  .show-entry { grid-template-columns: 1fr; gap: 0.5rem; }
  footer { flex-direction: column; gap: 0.5rem; text-align: center; }
  .hero {
    position: relative;
  }
  .page-content {
    margin-top: 0;
  }
}
