/* ============================================================================
   HeartFelt Kids Studio - main stylesheet
   Base, layout, header, footer. Plain CSS, no framework, no build step.
   Every value comes from tokens.css.

   Ported from the approved design mockups in design/assets/mockup.css. Rules
   were extracted by selector in their ORIGINAL DOCUMENT ORDER, not by hand
   picking line ranges. That ordering matters: the mockup stylesheet appends
   later refinements after the breakpoints they refine, and reordering them
   silently reinstates desktop layout on phones. It has caused that exact bug
   twice. Add new rules at the end of the relevant section, never by shuffling
   what is already here.

   Only header, footer and the shared base live here so far. Page and component
   styles land as their templates are built.
   ============================================================================ */
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0;
  font-family: var(--font-body);
  font-size: var(--t-body);
  line-height: var(--lh-body);
  color: var(--ink);
  background: var(--surface);
}
h1,h2,h3,h4 { font-family: var(--font-display); line-height: var(--lh-tight); margin: 0 0 var(--s-4); font-weight: 700; letter-spacing: -0.015em; }
h1 { font-size: var(--t-h1); }
h2 { font-size: var(--t-h2); }
h3 { font-size: var(--t-h3); }
h4 { font-size: var(--t-h4); line-height: var(--lh-snug); }
p { margin: 0 0 var(--s-4); }
a { color: var(--blue); }
img { max-width: 100%; display: block; }
ul,ol { margin: 0 0 var(--s-4); padding-left: 1.25em; }
li { margin-bottom: var(--s-2); }
:focus-visible { outline: 3px solid var(--focus); outline-offset: 2px; border-radius: 4px; }
.wrap { width: 100%; max-width: var(--wrap); margin-inline: auto; padding-inline: var(--s-5); }
.wrap-wide { max-width: var(--wrap-wide); }
.section { padding-block: var(--s-9); }
.section-tight { padding-block: var(--s-7); }
.section-alt { background: var(--surface-2); }
.center { text-align: center; }
.measure { max-width: var(--wrap-text); }
.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; }
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--s-2);
  font-family: var(--font-display); font-weight: 600; font-size: var(--t-small);
  line-height: 1; text-decoration: none; cursor: pointer;
  padding: .85rem 1.35rem; border-radius: var(--r-pill);
  border: 2px solid transparent; transition: background-color .15s, color .15s;
  min-height: 44px;
}
.btn-primary { background: var(--orange-btn); color: var(--white); }
.btn-primary:hover { background: var(--orange-btn-hi); }
.btn-blue { background: var(--blue); color: var(--white); }
.btn-teal { background: var(--teal-text); color: var(--white); }
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--line-strong); }
.btn-ghost-light { background: transparent; color: var(--white); border-color: rgba(255,255,255,.55); }
.btn-solid-light { background: var(--white); color: var(--ink); }
.btn-lg { font-size: var(--t-body); padding: 1rem 1.6rem; }
.btn-sm { font-size: var(--t-micro); padding: .55rem 1rem; min-height: 36px; }
.btn svg { width: 1.1em; height: 1.1em; flex: none; }
.site-header {
  position: sticky; top: 0; z-index: 50;
  background: var(--white); border-bottom: 1px solid var(--line);
}
.header-inner { display: flex; align-items: center; gap: var(--s-5); padding-block: var(--s-3); }
.brand { display: flex; align-items: center; gap: var(--s-3); text-decoration: none; flex: none; }
.brand-mark { width: 42px; height: 42px; flex: none; }
.brand-text { font-family: var(--font-display); line-height: 1.05; }
.brand-text b { display: block; font-size: 1.25rem; font-weight: 700; color: var(--ink); letter-spacing: -.02em; }
.brand-text span { display: block; font-size: .8125rem; font-weight: 600; color: var(--blue); }
.nav { margin-left: auto; }
.nav ul { display: flex; gap: var(--s-5); list-style: none; margin: 0; padding: 0; }
.nav li { margin: 0; }
.nav a {
  font-family: var(--font-display); font-size: var(--t-small); font-weight: 500;
  color: var(--ink); text-decoration: none; padding-block: var(--s-2);
  border-bottom: 2px solid transparent; display: block;
}
.nav a:hover, .nav a[aria-current="page"] { color: var(--blue); border-bottom-color: var(--blue); }
.header-cta { flex: none; }
.nav-toggle { display: none; }
@media (max-width: 1023px) {
  .nav {display: none;}
  .nav-toggle {display: inline-flex; align-items: center; gap: var(--s-2); margin-left: auto;
    background: none; border: 1px solid var(--line-strong); border-radius: var(--r-sm);
    padding: .55rem .8rem; font-family: var(--font-display); font-weight: 600;
    font-size: var(--t-small); color: var(--ink); min-height: 44px;}
  .header-cta .btn {padding: .7rem 1rem; font-size: var(--t-micro);}
}
@media (max-width: 560px) {
  .brand-text b {font-size: 1.05rem;}
  .brand-text span {font-size: .75rem;}
  .header-inner {flex-wrap: wrap; gap: var(--s-3);}
  .header-cta {flex: 1 0 100%;}
  .header-cta .btn {width: 100%; font-size: var(--t-small); padding: .8rem 1rem;}
}
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); margin-bottom: var(--s-6); flex-wrap: wrap; }
.section-head h2 { margin: 0; }
.stack-btns { display: grid; gap: var(--s-3); }
.site-footer { background: var(--hero-bg); color: var(--hero-dim); padding-block: var(--s-8) var(--s-5); }
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1.2fr 1.2fr; gap: var(--s-6); }
.site-footer h4 { color: var(--white); font-size: var(--t-small); text-transform: uppercase; letter-spacing: .08em; margin-bottom: var(--s-4); }
.site-footer ul { list-style: none; padding: 0; margin: 0; }
.site-footer li { margin-bottom: var(--s-2); font-size: var(--t-small); }
.site-footer a { color: var(--hero-dim); text-decoration: none; }
.site-footer a:hover { color: var(--white); text-decoration: underline; }
.footer-brand .brand-text b { color: var(--white); }
.footer-brand .brand-text span { color: var(--blue-light); }
.footer-blurb { font-size: var(--t-small); margin-top: var(--s-4); }
.footer-credit { color: var(--white); font-weight: 600; margin-top: var(--s-3); font-size: var(--t-small); }
.footer-tagline { color: var(--yellow); font-family: var(--font-display); font-weight: 600; margin-top: var(--s-2); font-size: var(--t-small); }
.social { display: flex; gap: var(--s-3); margin-top: var(--s-4); list-style: none; padding: 0; }
.social li { margin: 0; }
.social a { width: 40px; height: 40px; border-radius: var(--r-sm); background: rgba(255,255,255,.12); display: grid; place-items: center; color: var(--white); }
.social svg { width: 20px; height: 20px; }
.footer-contact li { display: flex; gap: var(--s-3); align-items: flex-start; }
.footer-contact svg { width: 17px; height: 17px; flex: none; margin-top: 4px; color: var(--blue-light); }
.footer-bottom {
  border-top: 1px solid rgba(255,255,255,.15); margin-top: var(--s-7); padding-top: var(--s-5);
  display: flex; flex-wrap: wrap; gap: var(--s-4); justify-content: space-between; font-size: var(--t-micro);
}
.footer-bottom ul { display: flex; gap: var(--s-5); }
@media (max-width: 1000px) {
  .footer-grid {grid-template-columns: repeat(2, 1fr);}
}
@media (max-width: 560px) {
  .footer-grid {grid-template-columns: 1fr;}
}
@media print {
  .site-header {position: static;}
}
.section-head {
  border-bottom: 1px solid var(--line);
  padding-bottom: var(--s-4);
  align-items: center;
}
.section h2.center { margin-bottom: var(--s-7); }
.btn { box-shadow: 0 1px 2px rgba(16,35,58,.08); }
.btn:hover { box-shadow: var(--shadow-1); }
.btn-ghost:hover { border-color: var(--ink); background: var(--surface-2); }
.btn-ghost-light:hover { border-color: var(--white); background: rgba(255,255,255,.1); }
.btn-blue:hover { background: #094E90; }
.btn-teal:hover { background: #0A5A53; }
.btn-solid-light:hover { background: #F1F5F9; }
.site-footer { padding-top: var(--s-9); }
.footer-bottom p { max-width: 78ch; margin: 0; }
@media (prefers-reduced-motion: reduce) {
  * {transition: none !important; animation: none !important;}
}
.btn-primary {
  box-shadow: 0 1px 2px rgba(184,69,12,.24), 0 4px 12px rgba(184,69,12,.20);
}
.btn-primary:hover { box-shadow: 0 2px 4px rgba(184,69,12,.28), 0 8px 20px rgba(184,69,12,.26); }
.btn-blue { box-shadow: 0 1px 2px rgba(11,95,174,.22), 0 4px 12px rgba(11,95,174,.18); }
.footer-grid { gap: var(--s-7) var(--s-6); }
.site-footer h4 { opacity: .85; }
.social a { transition: background-color .15s ease, transform .15s ease; }
.social a:hover { background: rgba(255,255,255,.22); transform: translateY(-2px); }
.sheet {
  background: var(--white);
  display: flex; flex-direction: column;
  box-shadow: 0 0 60px rgba(7,18,30,.4);
}
.sheet-head {
  display: flex; align-items: center; gap: var(--s-4);
  padding: var(--s-4) var(--s-5); border-bottom: 1px solid var(--line);
}
.sheet-nav { list-style: none; margin: 0; padding: var(--s-3) 0; flex: 1; overflow-y: auto; }
.sheet-nav li { margin: 0; }
.sheet-nav a {
  display: flex; align-items: center; justify-content: space-between;
  padding: var(--s-4) var(--s-5); text-decoration: none; color: var(--ink);
  font-family: var(--font-display); font-weight: 600; font-size: 1.0625rem;
  border-bottom: 1px solid var(--line);
}
.sheet-nav a:hover { background: var(--surface-2); color: var(--blue); }
.sheet-nav a[aria-current="page"] { color: var(--blue); }
.sheet-nav svg { width: 17px; height: 17px; color: var(--line-strong); }
.sheet-foot { padding: var(--s-5); border-top: 1px solid var(--line); display: grid; gap: var(--s-3); }
.section-eyebrow {
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--orange-text);
  margin: 0 0 var(--s-3);
}
.center .section-eyebrow, .section-eyebrow.center { text-align: center; }
h1 { letter-spacing: -.025em; }
h2 { letter-spacing: -.02em; }
h3 { letter-spacing: -.015em; }
.section > .wrap > p.lead,
.page-head p { max-width: 62ch; }
p.lead { font-size: 1.0625rem; color: var(--ink-muted); margin-bottom: var(--s-6); }
.header-inner { min-height: 76px; }
.nav ul { gap: var(--s-6); }
.nav a { font-weight: 500; }
.section + .section { padding-top: var(--s-8); }
.section-head + * { margin-top: 0; }
.site-footer li { margin-bottom: var(--s-3); }
.site-footer a:hover { color: var(--white); text-decoration: none; }
.footer-bottom { font-size: var(--t-micro); line-height: 1.7; }
:focus-visible { outline-offset: 3px; }
.section { padding-block: var(--s-10); }
.section + .section { padding-top: var(--s-10); }
.section-tight { padding-block: var(--s-9); }
.section-head { border-bottom: 0; border-top: 1px solid var(--ink); padding-top: var(--s-4); padding-bottom: 0; margin-bottom: var(--s-7); }
.section-head h2 { font-weight: 700; }
.section-eyebrow { color: var(--ink-muted); }
.site-footer { padding-block: var(--s-10) var(--s-6); }
@media (max-width: 700px) {
  .section, .section + .section {padding-block: var(--s-9);}
}
.nav-toggle svg { width: 20px; height: 20px; flex: none; }
@media (max-width: 700px) {
  .btn-sm {min-height: 44px; padding: .75rem 1.15rem; font-size: var(--t-small);}
  .site-footer li {margin-bottom: 0;}
  .site-footer li a {display: block; padding-block: 12px;}
  .footer-contact li {padding-block: 8px;}
  .social a {width: 44px; height: 44px;}
}


/* ---------------------------------------------------------------------------
   Homepage
   Ported from the approved mockups, selector by selector, in original
   document order. See the note at the top of this file about ordering.
   --------------------------------------------------------------------------- */

.ph-media {
  position: relative;
  display: grid;
  place-items: center;
  text-align: center;
  border: 1px solid var(--line);
  border-radius: var(--r-md);
  font-weight: 600;
  text-transform: uppercase;
  padding: var(--s-4);
  overflow: hidden;
}
.ph-media > span { position: relative; }
.play-badge { position: absolute; inset: 0; display: grid; place-items: center; pointer-events: none; }
.play-badge i {
  display: grid; place-items: center; border-radius: 50%;
  box-shadow: var(--shadow-2); color: var(--ink);
}

.hero {
  background-color: var(--hero-bg);
  background-image: linear-gradient(115deg, var(--hero-bg) 0%, var(--hero-bg) 45%, var(--hero-bg-2) 100%);
  color: var(--white);
  padding-block: var(--s-9) var(--s-8);
}
.hero-grid { display: grid; grid-template-columns: minmax(0,1.08fr) minmax(0,1fr); gap: var(--s-6) var(--s-8); align-items: center; }
.hero-grid > .trust-row { grid-column: 1 / -1; padding-top: var(--s-5); border-top: 1px solid rgba(255,255,255,.14); }
.eyebrow {
  display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center;
  font-family: var(--font-display); font-size: var(--t-micro); font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase; color: var(--yellow);
  margin: 0 0 var(--s-4); padding: 0; list-style: none;
}
.eyebrow li { margin: 0; display: flex; align-items: center; gap: var(--s-3); }
.eyebrow li::before { content: "\2022"; opacity: .55; }
.eyebrow li:first-child::before { content: none; }
.hero h1 { font-size: var(--t-hero); margin-bottom: var(--s-5); }
.hero h1 .accent { color: var(--yellow); display: block; }
.hero p { color: var(--hero-dim); font-size: 1.0625rem; max-width: 46ch; }
.hero-actions { display: flex; flex-wrap: wrap; gap: var(--s-3); margin-block: var(--s-6); }
.trust-row { display: flex; flex-wrap: wrap; gap: var(--s-4) var(--s-6); list-style: none; padding: 0; margin: 0; }
.trust-row li { display: flex; align-items: center; gap: var(--s-2); font-size: var(--t-small); color: var(--hero-dim); margin: 0; }
.trust-row svg { width: 18px; height: 18px; flex: none; color: var(--teal); }
.hero-media { display: grid; gap: var(--s-4); }
.hero-thumbs { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s-3); }
@media (max-width: 900px) {
  .hero-grid {grid-template-columns: 1fr;}
  .hero-thumbs {grid-template-columns: repeat(2, 1fr);}
}
.cat-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--s-4); }
.cat-card {
  border-radius: var(--r-lg); padding: var(--s-5); position: relative; overflow: hidden;
  display: flex; flex-direction: column; min-height: 260px; box-shadow: var(--shadow-1);
}
.cat-card h3 { margin-bottom: var(--s-3); max-width: 12ch; }
.cat-card p { font-size: var(--t-small); color: var(--ink); max-width: 27ch; }
.cat-card .btn { margin-top: auto; align-self: flex-start; }
.cat-peach { background: var(--tint-peach); }
.cat-peach h3 { color: var(--orange-text); }
.cat-teal { background: var(--tint-teal); }
.cat-teal h3 { color: var(--teal-text); }
.cat-yellow { background: var(--tint-yellow); }
.cat-yellow h3 { color: var(--yellow-text); }
.cat-blue { background: var(--tint-blue); }
.cat-blue h3 { color: var(--blue); }
@media (max-width: 1000px) {
  .cat-grid {grid-template-columns: repeat(2, 1fr);}
}
@media (max-width: 560px) {
  .cat-grid {grid-template-columns: 1fr;}
}
.feature-band {
  display: grid; grid-template-columns: 340px minmax(0,1fr); gap: var(--s-6);
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--r-lg); overflow: hidden; align-items: center;
}
.feature-band > .ph-media { border: 0; border-radius: 0; aspect-ratio: auto; align-self: stretch; height: 100%; min-height: 280px; }
.feature-body { padding: var(--s-6) var(--s-6) var(--s-6) 0; }
.feature-body h2 { color: var(--blue); margin-bottom: var(--s-2); }
.feature-body .lede { font-weight: 600; margin-bottom: var(--s-3); }
.cue-types { display: flex; flex-wrap: wrap; gap: var(--s-5); list-style: none; padding: 0; margin: var(--s-5) 0; }
.cue-types li { display: grid; justify-items: center; gap: var(--s-2); width: 92px; text-align: center; font-size: var(--t-micro); font-weight: 600; color: var(--ink-muted); margin: 0; }
.cue-types svg { width: 26px; height: 26px; color: var(--blue-light); }
@media (max-width: 860px) {
  .feature-band {grid-template-columns: 1fr;}
  .feature-body {padding: var(--s-5);}
}
.why-grid { display: grid; grid-template-columns: repeat(6, 1fr); }
.why-item { text-align: center; padding: var(--s-5) var(--s-4); border-right: 1px solid var(--line); }
.why-item:last-child { border-right: 0; }
.why-item h4 { margin-bottom: var(--s-2); }
.why-item p { font-size: var(--t-small); color: var(--ink-muted); margin: 0; }
.why-icon { width: 62px; height: 62px; border-radius: 50%; display: grid; place-items: center; margin: 0 auto var(--s-4); }
.why-icon svg { width: 28px; height: 28px; color: var(--white); }
.bg-orange { background: var(--orange); }
.bg-teal { background: var(--teal); }
.bg-blue { background: var(--blue-light); }
.bg-yellow { background: var(--yellow); }
.bg-yellow svg { color: var(--ink); }
.bg-red { background: #E4573D; }
.bg-green { background: #2FA36B; }
@media (max-width: 1000px) {
  .why-grid {grid-template-columns: repeat(3, 1fr);}
  .why-item {border-bottom: 1px solid var(--line);}
  .why-item:nth-child(3n) {border-right: 0;}
  .why-item:nth-last-child(-n+3) {border-bottom: 0;}
}
@media (max-width: 620px) {
  .why-grid {grid-template-columns: repeat(2, 1fr);}
  .why-item:nth-child(3n) {border-right: 1px solid var(--line);}
  .why-item:nth-child(2n) {border-right: 0;}
  .why-item:nth-last-child(-n+2) {border-bottom: 0;}
}
.section-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--s-4); margin-bottom: var(--s-6); flex-wrap: wrap; }
.section-head h2 { margin: 0; }
.link-more { font-family: var(--font-display); font-weight: 600; font-size: var(--t-small); color: var(--blue); text-decoration: none; }
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: var(--s-5); }
.content-card {
  background: var(--white); border: 1px solid var(--line); border-radius: var(--r-md);
  overflow: hidden; display: flex; flex-direction: column; box-shadow: var(--shadow-1);
}
.content-card .thumb { position: relative; }
.content-card .thumb .ph-media { border: 0; border-radius: 0; }
.card-body { padding: var(--s-4); display: flex; flex-direction: column; gap: var(--s-2); flex: 1; }
.card-body h4 { margin: 0; }
.card-type { font-size: var(--t-micro); font-weight: 600; color: var(--ink-muted); text-transform: uppercase; letter-spacing: .06em; }
.card-meta { display: flex; flex-wrap: wrap; gap: var(--s-2); font-size: var(--t-micro); color: var(--ink-muted); }
.card-actions { margin-top: auto; padding-top: var(--s-3); display: flex; gap: var(--s-2); flex-wrap: wrap; }
.rail-wrap { position: relative; }
.rail { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(212px, 1fr); gap: var(--s-4); overflow-x: auto; padding-bottom: var(--s-3); scroll-snap-type: x mandatory; }
.rail > * { scroll-snap-align: start; }
.rail-btn {
  position: absolute; top: 34%; width: 42px; height: 42px; border-radius: 50%;
  background: var(--white); border: 1px solid var(--line-strong); box-shadow: var(--shadow-2);
  display: grid; place-items: center; cursor: pointer; color: var(--ink);
}
.rail-btn svg { width: 18px; height: 18px; }
.rail-prev { left: -21px; }
.rail-next { right: -21px; }
@media (max-width: 1200px) {
  .rail-prev, .rail-next {display: none;}
}
.cta-band {
  background-color: #12626B;
  background-image: linear-gradient(90deg, #C9490F 0%, #9E571B 38%, #1C7F86 72%, #0B5FAE 100%);
  color: var(--white);
}
.cta-inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--s-5); padding-block: var(--s-7); }
.cta-inner h2 { margin-bottom: var(--s-2); }
.cta-inner p { margin: 0; max-width: 54ch; }
.cta-actions { display: flex; gap: var(--s-3); flex-wrap: wrap; }
.hero-actions { gap: var(--s-3); }
.hero-actions .btn-lg { padding: 1rem 1.2rem; }
@media (max-width: 560px) {
  .eyebrow {gap: var(--s-2) var(--s-5);}
  .eyebrow li::before {content: none;}
}
.content-card, .cat-card, .panel, .side-card {
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.content-card:hover, .panel:hover {
  transform: translateY(-2px);
  box-shadow: var(--shadow-2);
  border-color: var(--line-strong);
}
.cat-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); }
.content-card .thumb { display: block; overflow: hidden; }
.content-card .thumb .ph-media { transition: transform .3s ease; }
.content-card:hover .thumb .ph-media { transform: scale(1.02); }
.card-body h4 a, .content-card h3 a { color: inherit; text-decoration: none; }
.card-body h4 a:hover, .content-card h3 a:hover { color: var(--blue); }
.section-head {
  border-bottom: 1px solid var(--line);
  padding-bottom: var(--s-4);
  align-items: center;
}
.link-more { display: inline-flex; align-items: center; gap: var(--s-2); }
.link-more svg { width: 15px; height: 15px; transition: transform .18s ease; }
.link-more:hover svg { transform: translateX(3px); }
@media (prefers-reduced-motion: reduce) {
  .content-card:hover, .cat-card:hover, .panel:hover {transform: none;}
}
@media (min-width: 1100px) {
  .rail {grid-auto-flow: row;
    grid-template-columns: repeat(3, minmax(0,1fr));
    grid-auto-columns: auto;
    overflow-x: visible;
    gap: var(--s-5);}
  .rail-prev, .rail-next {display: none;}
}
.hero { position: relative; overflow: hidden; }
.hero-media > .ph-media { box-shadow: 0 18px 46px rgba(0,0,0,.38); }
.eyebrow li {
  background: rgba(255,198,41,.13);
  border: 1px solid rgba(255,198,41,.30);
  border-radius: var(--r-pill);
  padding: .4em .8em;
}
.eyebrow li::before { content: none; }
.cat-icon {
  width: 46px; height: 46px; border-radius: 14px; display: grid; place-items: center;
  margin-bottom: var(--s-4); color: var(--white);
}
.cat-icon svg { width: 23px; height: 23px; }
.why-grid { gap: var(--s-4); }
.why-item {
  border: 1px solid var(--line); border-radius: var(--r-lg); background: var(--white);
  padding: var(--s-6) var(--s-4);
  transition: transform .18s ease, box-shadow .18s ease;
}
.why-item, .why-item:last-child, .why-item:nth-child(3n), .why-item:nth-child(2n) { border-right: 1px solid var(--line); border-bottom: 1px solid var(--line); }
.why-item:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); }
.why-icon { box-shadow: 0 6px 16px rgba(16,35,58,.16); }
.content-card, .track-row, .prefill, .captcha-slot { border-radius: var(--r-lg); }
@media (max-width: 1250px) and (min-width: 1001px) {
  .why-grid {grid-template-columns: repeat(3, 1fr);}
}
.section-eyebrow {
  font-family: var(--font-display);
  font-size: var(--t-micro);
  font-weight: 700;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--orange-text);
  margin: 0 0 var(--s-3);
}
.center .section-eyebrow, .section-eyebrow.center { text-align: center; }
.hero h1 { letter-spacing: -.03em; }
.content-card, .panel, .side-card, .filters, .why-item { box-shadow: none; }
.content-card:hover, .panel:hover, .why-item:hover { box-shadow: var(--shadow-2); }
.content-card, .panel, .side-card, .filters, .why-item, .track-row { border-color: var(--line); }
.cat-card { padding: var(--s-6) var(--s-5) var(--s-5); min-height: 272px; }
.cat-card h3 { max-width: 14ch; margin-bottom: var(--s-3); }
.cat-card p { max-width: 30ch; margin-bottom: var(--s-5); }
.cat-icon { margin-bottom: var(--s-5); }
.why-item { display: flex; flex-direction: column; align-items: center; }
.why-item h4 { margin-bottom: var(--s-3); }
.why-item p { max-width: 24ch; }
.why-icon { width: 56px; height: 56px; box-shadow: none; }
.why-icon svg { width: 26px; height: 26px; }
.feature-band { grid-template-columns: 380px minmax(0,1fr); }
.feature-body { padding: var(--s-7) var(--s-7) var(--s-7) 0; }
.feature-body h2 { margin-bottom: var(--s-3); }
.cue-types { gap: var(--s-5) var(--s-6); }
.section-head + * { margin-top: 0; }
.card-meta { align-items: center; gap: var(--s-2) var(--s-3); }
@media (max-width: 860px) {
  .feature-band {grid-template-columns: 1fr;}
  .feature-body {padding: var(--s-5);}
}
.hero { padding-block: var(--s-10) var(--s-9); }
.hero-grid { gap: var(--s-7) var(--s-9); align-items: center; }
.hero h1 { margin-bottom: var(--s-5); font-weight: 700; }
.hero p { font-size: 1.125rem; line-height: 1.6; max-width: 44ch; }
.hero-actions { margin-block: var(--s-7); }
.reel { position: relative; }
.reel .ph-media { border-radius: var(--r-lg); }
.reel-duration {
  position: absolute; right: var(--s-4); bottom: var(--s-4);
  background: rgba(7,18,30,.72);
  border: 1px solid rgba(255,255,255,.22);
  color: #fff; font-family: var(--font-display); font-weight: 600;
  font-size: var(--t-micro); font-variant-numeric: tabular-nums;
  padding: .35em .7em; border-radius: var(--r-sm);
  display: flex; align-items: center; gap: var(--s-2);
}
.reel-duration .ph { background: rgba(255,198,41,.22); color: #FFDE8A; box-shadow: none; }
.trust-row { gap: var(--s-4) var(--s-8); padding-top: var(--s-6); }
.trust-row li { font-size: var(--t-small); letter-spacing: .01em; }
.content-card .thumb { position: relative; overflow: hidden; }
.content-card:hover .thumb .ph-media { transform: scale(1.045); }
.content-card .thumb .ph-media { transition: transform .4s cubic-bezier(.2,.7,.3,1); }
.content-card:hover { transform: none; border-color: var(--ink); }
.content-card { transition: border-color .2s ease, box-shadow .2s ease; }
.card-type {
  /* Tracked out like a credit line, but held at the 12px floor. */
  letter-spacing: .13em; font-size: 12px; color: var(--ink-muted);
}
.card-meta, .spec-list dd, .player-time, .reel-duration { font-variant-numeric: tabular-nums; }
.section-head { border-bottom: 0; border-top: 1px solid var(--ink); padding-top: var(--s-4); padding-bottom: 0; margin-bottom: var(--s-7); }
.section-head h2 { font-weight: 700; }
.section-eyebrow { color: var(--ink-muted); }
.cat-card { min-height: 300px; padding: var(--s-6) var(--s-6) var(--s-6); border-radius: var(--r-xl); }
.cat-card h3 { font-size: clamp(1.25rem, 1.1rem + .5vw, 1.55rem); }
.cat-card p { color: var(--ink-muted); }
.cat-icon { width: 50px; height: 50px; border-radius: 15px; }
.feature-band { border-radius: var(--r-xl); }
.feature-body { padding-block: var(--s-8); }
.feature-body .lede { font-size: 1.0625rem; color: var(--ink); }
.why-item { border-radius: var(--r-xl); padding: var(--s-7) var(--s-4); }
.cta-inner { padding-block: var(--s-9); }
.cta-inner h2 { font-size: clamp(1.6rem, 1.2rem + 1.6vw, 2.4rem); }
@media (max-width: 700px) {
  .hero {padding-block: var(--s-8) var(--s-7);}
}
.hero-grid { grid-template-columns: minmax(0,1.25fr) minmax(0,1fr); }
@media (max-width: 900px) {
  .hero-grid {grid-template-columns: 1fr;}
}
.hero-thumbs .ph-media, .content-card .thumb .ph-media { padding: var(--s-2); }
.reel-duration svg { width: 13px; height: 13px; flex: none; }
.link-more svg, .breadcrumb svg { flex: none; }
@media (max-width: 700px) {
  .cat-card .btn {width: 100%;}
  .link-more {padding-block: 10px;}
  .card-body h4 a,
  .track-row h4 a {display: inline-block; padding-block: 11px;}
  .card-type {font-size: 12px; letter-spacing: .1em;}
}


/* Later refinements, kept after the rules above exactly as they sit in the
   mockup stylesheet. Flat fill, no gradient: a gradient in an empty box is the
   box drawing attention to its own emptiness. */
.ph-media {
  background: #EDF1F6;
  color: #7C8CA0;
  font-size: 12px;
  letter-spacing: .1em;
  box-shadow: inset 0 0 0 1px rgba(16,35,58,.06);
}
.ph-media.on-dark {
  background: #15304A;
  color: #7E97B0;
  border-color: rgba(255,255,255,.14);
  box-shadow: inset 0 0 0 1px rgba(255,255,255,.08);
}
.play-badge i { width: 74px; height: 74px; background: rgba(255,255,255,.95); }
.play-badge.sm i { width: 40px; height: 40px; background: rgba(255,255,255,.94); }
@media (max-width: 700px) {
  .play-badge i { width: 58px; height: 58px; }
}

/* --- Placeholder ratios and blocks -------------------------------------------
   Ported from the mockups. Rick's direction: any temporary artwork or sample
   content must be clearly identified as a placeholder and replaced before
   launch. These are deliberately loud rather than subtle, so nothing
   unfinished can be mistaken for finished. --------------------------------- */
.ph-block {
  background: var(--ph-bg);
  border: 1px solid var(--ph-line);
  border-radius: var(--r-lg);
  color: var(--ph-ink);
  padding: var(--s-5);
  font-size: var(--t-small);
}
.ph-block p:last-child { margin-bottom: 0; }
.ratio-16-9 { aspect-ratio: 16/9; }
.ratio-4-3 { aspect-ratio: 4/3; }
.ratio-1-1 { aspect-ratio: 1/1; }
.ratio-3-2 { aspect-ratio: 3/2; }


/* --- Token overrides from the mockups ----------------------------------------
   These sit late in the mockup stylesheet on purpose: they are the pass that
   opened the design up from brochure scale to studio scale. Ported here in
   the same order. Missing them rendered .section padding at 80px instead of
   104px and h2 at 35.2px instead of 41.6px, which is why the built page came
   out visibly tighter than the approved artwork.
   ------------------------------------------------------------------------ */

:root {
  --shadow-1: 0 1px 2px rgba(16,35,58,.05);
  --shadow-2: 0 1px 2px rgba(16,35,58,.06), 0 6px 16px rgba(16,35,58,.08);
}
:root {
  /* Display sizes step up. A studio front page carries its headline; the
     previous scale was sized for a brochure. */
  --t-hero: clamp(2.4rem, 1.2rem + 4.2vw, 4.25rem);
  --t-h2:   clamp(1.7rem, 1.25rem + 1.9vw, 2.6rem);

  /* Whitespace opens up. Cramped vertical rhythm is the single biggest tell
     between a template and a designed site. */
  --s-9:  5rem;
  --s-10: 6.5rem;
  --s-11: 8rem;
}
@media (max-width: 700px) {
  :root {--s-9: 3.5rem; --s-10: 4rem;}
}
:root { --t-hero: clamp(2.4rem, 1.2rem + 3.4vw, 3.6rem); }

/* ============================================================================
   Theme additions
   Rules that the mockups did not need, appended here rather than merged into
   the ported blocks above so the port stays a faithful copy and a future
   re-export can be diffed against it.
   ============================================================================ */

/* The sheet close button had no rule at all in the mockups, where it was drawn
   as a static board. Measured 29px live, under the 44px a thumb needs. */
.sheet-close {
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  margin-inline-start: auto;
  padding: 0;
  border: 0;
  border-radius: var(--r-sm);
  background: transparent;
  color: var(--ink);
  cursor: pointer;
}
.sheet-close:hover { background: var(--surface-2); }

/* The brand lockup measured 42px, set by the 42px mark inside it. Two pixels
   under the minimum, and it is the largest tap target on a phone header. */
@media (max-width: 700px) {
  .brand { min-height: 44px; }
}

/* The sheet is a live element here, not a flattened board. It needs to sit
   above the sticky header and fill the screen. */
.sheet {
  position: fixed;
  inset: 0;
  z-index: 100;
  max-width: none;
}
.sheet[hidden] { display: none; }

/* Skip link: visually hidden until focused, then it has to be visible and
   clickable, otherwise it is a checkbox exercise rather than a real feature. */
.skip-link:focus {
  position: fixed;
  top: var(--s-3);
  left: var(--s-3);
  z-index: 200;
  width: auto;
  height: auto;
  margin: 0;
  padding: var(--s-3) var(--s-4);
  clip: auto;
  clip-path: none;
  background: var(--white);
  color: var(--ink);
  border-radius: var(--r-sm);
  box-shadow: var(--shadow-2);
  white-space: nowrap;
}

/* Homepage states the mockups did not have to handle -------------------------
   The mockups always drew a reel and a feature image because they were static
   boards. Live, both are content Rick has not supplied. Rather than ship an
   empty player or a grey box to a producer, the section collapses to one
   column and the grid stops reserving space for something that is not there. */
/* The hero and feature band always render their media slot now, as a labelled
   placeholder when there is no real asset. That keeps the built page matching
   the approved design instead of collapsing to a different layout, and the
   placeholder is unmistakable rather than an empty grey box. */

/* oEmbed returns its own iframe; make it fill the reel slot at 16:9. */
.reel iframe,
.reel embed,
.reel object,
.reel video { display: block; width: 100%; aspect-ratio: 16 / 9; height: auto; border: 0; border-radius: var(--r-md); }

/* Featured cards use real featured images once content exists. */
.content-card .thumb img { width: 100%; height: auto; aspect-ratio: 16 / 9; object-fit: cover; }
.feature-band > img { width: 100%; height: 100%; object-fit: cover; }

/* A note only signed-in editors ever see. Rick's rule is that nothing
   unfinished may look finished: a visitor gets no section at all, and the
   person who can fix it gets told what is missing. Loud on purpose. */
.editor-note {
  margin: var(--s-5) 0 0;
  padding: var(--s-4) var(--s-5);
  border-radius: var(--r-sm);
  background: var(--ph-bg);
  color: var(--ph-ink);
  font-size: var(--t-small);
  line-height: var(--lh-body);
  box-shadow: inset 0 -2px 0 rgba(201,174,88,.55);
}
.editor-note b { color: var(--ink); }
.hero .editor-note { background: rgba(247,197,66,.16); color: #F0D48A; box-shadow: none; }
.hero .editor-note b { color: var(--white); }

/* --- Mobile header ordering --------------------------------------------------
   The markup runs brand, nav, request button, Menu. Once .header-inner wraps
   and the button takes a full width row, the Menu button is pushed onto a
   third row on its own, which is what the phone header was doing: three stacked
   rows and a very heavy orange bar in the middle of them.

   Ordering puts Menu back beside the brand and leaves the button its own row
   underneath, which keeps the prominence Rick asked for without the header
   eating a third of the screen. Order, not markup changes, because the DOM
   order is the correct reading order for a screen reader as it stands. */
@media (max-width: 560px) {
  .brand       { order: 1; }
  .nav-toggle  { order: 2; }
  .header-cta  { order: 3; }

  /* The row is brand + Menu, so the toggle no longer needs to be pushed by an
     auto margin against a wrapped line. */
  .nav-toggle { margin-left: auto; }

  /* Slightly less tall than a hero button. It is navigation chrome, not the
     page's main call to action. */
  .header-cta .btn { padding: .7rem 1rem; min-height: 46px; font-size: var(--t-small); }

  .header-inner { row-gap: var(--s-3); column-gap: var(--s-3); }
}

/* --- Where the desktop navigation collapses ----------------------------------
   The eight links need 1232px of content beside the brand and the request
   button: 145 brand + 24 gap + 761 links + 24 gap + 278 button. The wrap adds
   24px of padding each side, and a desktop scrollbar eats another 15, so the
   full row needs a 1295px viewport. Below that the header ran past the edge and
   the whole page scrolled sideways: 68px of overflow at 1024 with the old two
   word button label, 166px with the new one. Renaming the button widened an
   existing fault rather than creating it.

   Collapsing to the Menu button below 1300 is the honest fix. Squeezing the
   link gaps buys about 110px, which is not enough at 1024 and leaves the
   navigation cramped everywhere it does fit. */
@media (max-width: 1299px) {
  .nav { display: none; }
  .nav-toggle {
    display: inline-flex; align-items: center; gap: var(--s-2); margin-left: auto;
    background: none; border: 1px solid var(--line-strong); border-radius: var(--r-sm);
    padding: .55rem .8rem; font-family: var(--font-display); font-weight: 600;
    font-size: var(--t-small); color: var(--ink); min-height: 44px;
  }
  .header-cta .btn { padding: .7rem 1rem; font-size: var(--t-micro); }
}

/* The label is three words now. Never let it break across lines: a wrapped
   button in a sticky header pushes every section on the page down. */
.header-cta .btn { white-space: nowrap; }
.nav a { white-space: nowrap; }


/* --- Inner page components ---------------------------------------------------
   Second pass of the port from design/assets/mockup.css, for the About and
   Series pages. Same rule as the first pass: rules are copied by selector IN
   MOCKUP DOCUMENT ORDER, so a later refinement still lands after the rule it
   refines. Appending the whole ordered run, including selectors the first pass
   already carried, is deliberate. It means the final cascade for these
   selectors is identical to the mockup's rather than a merge of two partial
   copies, which is where the ordering bug bit twice during the design phase. */
.tag {
  display: inline-block; font-size: var(--t-micro); font-weight: 600; line-height: 1;
  padding: .4em .7em; border-radius: var(--r-pill); background: var(--surface-2);
  color: var(--ink-muted); border: 1px solid var(--line);
}
.tag-blue  { background: var(--tint-blue);  color: var(--blue);        border-color: #C6DEF6; }
.tag-teal  { background: var(--tint-teal);  color: var(--teal-text);   border-color: #BFE6E1; }
.tag-peach { background: var(--tint-peach); color: var(--orange-text); border-color: #F7D6C6; }
.tag-yellow{ background: var(--tint-yellow);color: var(--yellow-text); border-color: #EDDCA8; }
.result-bar { display: flex; flex-wrap: wrap; gap: var(--s-3); align-items: center; justify-content: space-between; margin-bottom: var(--s-5); font-size: var(--t-small); color: var(--ink-muted); }
.result-bar .sort { display: flex; align-items: center; gap: var(--s-3); }
.result-bar select { width: auto; }
.notice {
  display: grid; grid-template-columns: 44px minmax(0,1fr); gap: var(--s-4);
  background: var(--tint-blue); border: 1px solid #CFE2F7;
  border-radius: var(--r-lg); padding: var(--s-5);
  font-size: var(--t-small); margin-bottom: var(--s-6);
}
.notice p { margin-bottom: var(--s-2); }
.notice p:last-child { margin-bottom: 0; }
.notice strong {
  display: block; margin-bottom: var(--s-2); font-family: var(--font-display);
  font-size: var(--t-h4); color: var(--blue); letter-spacing: -.01em;
}
.notice-icon {
  width: 44px; height: 44px; border-radius: 13px; display: grid; place-items: center;
  background: rgba(11,95,174,.11); color: var(--blue);
}
.notice-icon svg { width: 21px; height: 21px; }
.notice-warn { background: var(--tint-peach); border-color: #F6D3C1; }
.notice-warn strong { color: var(--orange-text); }
.notice-warn .notice-icon { background: rgba(184,69,12,.12); color: var(--orange-text); }
.page-head { background: var(--surface-2); border-bottom: 1px solid var(--line); padding-block: var(--s-8); }
.page-head h1 { margin-bottom: var(--s-3); }
.page-head p { color: var(--ink-muted); max-width: 64ch; margin: 0; }
.page-head-dark { background: var(--hero-bg); border-bottom: 0; color: var(--white); }
.page-head-dark p { color: var(--hero-dim); }
.steps { list-style: none; padding: 0; display: grid; gap: var(--s-4); }
.steps li { display: grid; grid-template-columns: 44px minmax(0,1fr); gap: var(--s-4); align-items: start; margin: 0; }
.steps b { display: block; font-family: var(--font-display); }
.steps span { font-size: var(--t-small); color: var(--ink-muted); }
.cols-2 { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: var(--s-7); }
.cols-3 { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); gap: var(--s-6); }
@media (max-width: 860px) {
  .cols-2, .cols-3 { grid-template-columns: 1fr; }
}
.panel { background: var(--white); border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--s-5); }
.panel h3 { font-size: var(--t-h4); }
.panel p:last-child, .panel ul:last-child { margin-bottom: 0; }
.tick-list { list-style: none; padding: 0; }
.tick-list li { display: grid; grid-template-columns: 22px minmax(0,1fr); gap: var(--s-3); font-size: var(--t-small); }
.tick-list svg { width: 20px; height: 20px; color: var(--teal-text); margin-top: 2px; }
.page-head h1 { max-width: 20ch; }
.page-head p { font-size: 1.0625rem; line-height: 1.6; }
.tag { font-size: var(--t-micro); padding: .35em .65em; font-weight: 600; }
.section > .wrap > p.lead,
.page-head p { max-width: 62ch; }
.tag { line-height: 1.35; }
.page-head { padding-block: var(--s-9); }
.page-head h1 { font-size: clamp(2rem, 1.4rem + 2.4vw, 3.1rem); }
@media (max-width: 700px) {
  .tag { font-size: 12px; }
  .result-bar { gap: var(--s-4); }
  .result-bar .sort { width: 100%; }
  .result-bar select { width: 100%; }
}

/* --- About introduction video -------------------------------------------------
   Rick asked on 3 September for his own video to lead the About page, playable
   with sound, and to look right on desktop and phone. One 16:9 box that scales
   with the column covers both: aspect-ratio holds the shape so the player never
   letterboxes and never pushes the page sideways on a narrow screen.

   The width is capped rather than full bleed. A talking head stretched across a
   1440px monitor is uncomfortable to watch, and the cap keeps the line length
   of the heading above it readable. */
.about-intro { max-width: 900px; }
.about-intro h2 { margin-bottom: var(--s-5); }
.video-embed {
  position: relative; aspect-ratio: 16 / 9; overflow: hidden;
  border-radius: var(--r-lg); background: #000; box-shadow: var(--shadow-2);
}
/* oEmbed returns an iframe carrying its own width and height attributes, so the
   box has to override them rather than trust the provider's numbers. */
.video-embed iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; display: block; }
/* The self hosted player is NOT locked to 16:9. Rick's introduction video is
   848x1072, taller than it is wide, and forcing a landscape box would put him
   in the middle of a wide black frame on a desktop monitor.

   Letting width and height stay auto means the video uses its own dimensions
   and the two maximums shrink it proportionally, so one rule handles a portrait
   clip and a landscape one with no branching. A portrait video lands about
   570px wide on a desktop and fills the column on a phone; a 16:9 one fills the
   column on both. The min-height is only there because the intrinsic size is
   unknown until metadata arrives, and without it the box starts at the 300x150
   default and visibly jumps. */
.video-player {
  display: block; margin-inline: auto;
  width: auto; height: auto;
  max-width: 100%; max-height: min(72vh, 700px); min-height: 240px;
  border-radius: var(--r-lg); background: #000; box-shadow: var(--shadow-2);
}

/* A placeholder card has nothing to link to, so its thumb is a span rather than
   an anchor. The ported rules key off .thumb and cover both, except for the
   display mode a span does not have by default. */
.content-card span.thumb { display: block; }


/* --- Single catalog item ------------------------------------------------------
   Third pass of the port from design/assets/mockup.css, for a song, video,
   series or cue page. Same rule as the first two passes: copied by selector in
   MOCKUP DOCUMENT ORDER so later refinements still land after what they
   refine. */
.ph-block {
  background: var(--ph-bg);
  border: 1px solid var(--ph-line);
  border-radius: var(--r-lg);
  color: var(--ph-ink);
  padding: var(--s-5);
  font-size: var(--t-small);
}
.ph-block p:last-child { margin-bottom: 0; }
.card-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(232px, 1fr)); gap: var(--s-5); }
.player-note { font-size: var(--t-micro); color: var(--ink-muted); margin-top: var(--s-3); display: flex; align-items: flex-start; gap: var(--s-2); }
.player-note svg { width: 15px; height: 15px; color: var(--teal-text); flex: none; margin-top: 2px; }
.single-grid { display: grid; grid-template-columns: minmax(0,1fr) 320px; gap: var(--s-8); align-items: start; }
.side-card { border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--s-5); background: var(--white); box-shadow: var(--shadow-1); }
.side-card + .side-card { margin-top: var(--s-5); }
.side-card h3 { font-size: var(--t-h4); }
.spec-list { display: grid; grid-template-columns: max-content minmax(0,1fr); gap: var(--s-3) var(--s-4); margin: 0; font-size: var(--t-small); }
.spec-list dt { color: var(--ink-muted); }
.spec-list dd { margin: 0; font-weight: 600; }
.stack-btns { display: grid; gap: var(--s-3); }
.breadcrumb { font-size: var(--t-micro); color: var(--ink-muted); margin-bottom: var(--s-4); }
.breadcrumb a { color: var(--ink-muted); }
.share-url {
  display: flex; gap: var(--s-2); align-items: center; font-size: var(--t-micro);
  background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--r-sm);
  padding: var(--s-2) var(--s-3); overflow-wrap: anywhere; color: var(--ink-muted);
}
@media (max-width: 900px) {
  /* minmax(0,1fr), not 1fr: a bare 1fr track refuses to shrink below its
     content's min-content width, and the waveform is 56 bars wide. That pushed
     every item page 16px past the viewport on a phone. */
  .single-grid { grid-template-columns: minmax(0,1fr); }
}
.spec-list dt, .spec-list dd { padding-bottom: var(--s-3); border-bottom: 1px solid var(--line); }
.spec-list dt:last-of-type, .spec-list dd:last-of-type { border-bottom: 0; padding-bottom: 0; }
@media (min-width: 901px) {
  .single-grid > aside { position: sticky; top: 92px; }
}
.breadcrumb { display: flex; flex-wrap: wrap; gap: var(--s-2); align-items: center; letter-spacing: .01em; }
.breadcrumb a { text-decoration: none; }
.breadcrumb a:hover { color: var(--blue); text-decoration: underline; }
.card-meta, .spec-list dd, .player-time, .reel-duration { font-variant-numeric: tabular-nums; }
.spec-list dt {
  font-size: var(--t-micro); text-transform: uppercase; letter-spacing: .09em;
}
.spec-list dt, .spec-list dd { padding-block: var(--s-3); }
.share-url svg { width: 15px; height: 15px; flex: none; }
.link-more svg, .breadcrumb svg { flex: none; }
@media (max-width: 700px) {
  .breadcrumb a { display: inline-block; padding-block: 8px; }
  .breadcrumb { font-size: var(--t-small); }
}


/* --- Catalog listing pages ------------------------------------------------
   Songs and Music Videos share this shell. Ported from the mockup, but with
   its own later refinements folded into each rule rather than appended after
   it: the earlier passes moved these blocks out of mockup order, so a verbatim
   copy of the base rules here would land after the overrides already in this
   file and quietly undo them. Values below are the design's final values. */

.catalog-layout { display: grid; grid-template-columns: 268px minmax(0,1fr); gap: var(--s-7); align-items: start; }
/* No filter panel means no left column. Without this the results sit in the
   narrow filter track and the wide one stays empty. */
.catalog-layout.no-filters { grid-template-columns: minmax(0,1fr); }
.filters {
  border: 1px solid var(--line); border-radius: var(--r-xl); padding: var(--s-5);
  background: var(--white); position: sticky; top: 92px;
}
.filters h3 { font-size: var(--t-h4); margin-bottom: var(--s-4); }
.filter-group { border-top: 1px solid var(--line); padding-block: var(--s-4); }
.filter-group:first-of-type { border-top: 0; padding-top: 0; }
.filter-group > b { display: block; font-family: var(--font-display); font-size: var(--t-small); margin-bottom: var(--s-3); }
.chk {
  display: flex; align-items: center; gap: var(--s-3); font-size: var(--t-small);
  margin-bottom: var(--s-2); color: var(--ink-muted); font-weight: 400;
  font-family: var(--font-body); padding: var(--s-1) var(--s-2);
  margin-left: calc(var(--s-2) * -1); border-radius: var(--r-sm); cursor: pointer;
}
.chk:hover { background: var(--surface-2); color: var(--ink); }
.chk input { width: 18px; height: 18px; accent-color: var(--blue); flex: none; min-height: 0; }
.search-row { display: flex; gap: var(--s-3); margin-bottom: var(--s-5); }
.search-row input[type="search"] { flex: 1; }

@media (max-width: 900px) {
  .catalog-layout { grid-template-columns: 1fr; }
  .filters { position: static; }
}

/* --- Preview playback -----------------------------------------------------
   The dark player on an item page, and the compact row used in listings. The
   waveform bars are the mockup's, drawn to a fixed pattern. They are not a
   reading of the recording; which bars are lit is what tracks playback. */

.player {
  display: flex; align-items: center; gap: var(--s-4);
  background: var(--hero-bg); color: var(--white);
  border-radius: var(--r-lg); padding: var(--s-5) var(--s-6);
}
.player-play {
  width: 56px; height: 56px; flex: none; border-radius: 50%; border: 0; cursor: pointer;
  background: var(--orange-btn); color: var(--white); display: grid; place-items: center;
  padding: 0; min-height: 0; transition: transform .15s ease, background-color .15s ease;
}
.player-play:hover { background: var(--orange-btn-hi); transform: scale(1.06); }
.player-play .play-tri { margin-left: 2px; }
/* An author display value beats the browser's own [hidden] rule, so the button
   would sit there looking live for anyone whose script did not run. */
.player-play[hidden] { display: none; }
/* One button, two icons. Swapping the shown one avoids rebuilding the SVG in
   script and keeps the markup identical whether it is playing or not. */
.player-play .pause-bars { display: none; }
.player-play.is-playing .play-tri { display: none; }
.player-play.is-playing .pause-bars { display: block; }
.player-main { flex: 1; min-width: 0; }

/* The waveform is the scrubber. Padding gives it a comfortable hit area on a
   phone without making the drawn bars any taller. */
.player-scrub {
  position: relative; cursor: pointer; padding-block: var(--s-2);
  touch-action: none; border-radius: var(--r-sm);
}
.player-scrub:focus-visible { outline: 2px solid var(--teal); outline-offset: 3px; }
.player-head {
  position: absolute; top: var(--s-2); bottom: var(--s-2); left: 0;
  width: 2px; margin-left: -1px; background: var(--white); border-radius: 1px;
  box-shadow: 0 0 0 1px rgba(0,0,0,.25); pointer-events: none;
}
.player-scrub:hover .waveform i { background: rgba(255,255,255,.36); }
.player-scrub:hover .waveform i.on { background: var(--teal); }

.player-side { display: flex; align-items: center; gap: var(--s-4); flex: none; }

.player-volume { display: flex; align-items: center; gap: var(--s-2); }
.vol-btn {
  width: 36px; height: 36px; min-height: 0; flex: none; padding: 0; border: 0;
  border-radius: 50%; background: rgba(255,255,255,.12); color: var(--white);
  display: grid; place-items: center; cursor: pointer;
  transition: background-color .15s ease;
}
.vol-btn:hover { background: rgba(255,255,255,.22); }
.vol-btn svg { width: 18px; height: 18px; }
.vol-btn .ic-off { display: none; }
.vol-btn.is-muted .ic-on { display: none; }
.vol-btn.is-muted .ic-off { display: block; }

/* A plain range input, restyled. Rebuilding one by hand would mean rebuilding
   the keyboard behaviour it already has. */
.vol-range {
  -webkit-appearance: none; appearance: none; width: 84px; height: 4px;
  min-height: 0; padding: 0; border: 0; border-radius: 2px;
  background: rgba(255,255,255,.28); cursor: pointer;
}
.vol-range:focus-visible { outline: 2px solid var(--teal); outline-offset: 4px; }
.vol-range::-webkit-slider-thumb {
  -webkit-appearance: none; appearance: none; width: 14px; height: 14px;
  border-radius: 50%; background: var(--white); border: 0; cursor: pointer;
}
.vol-range::-moz-range-thumb {
  width: 14px; height: 14px; border-radius: 50%; background: var(--white);
  border: 0; cursor: pointer;
}
.player-title { font-family: var(--font-display); font-weight: 600; font-size: var(--t-small); margin-bottom: var(--s-2); }
/* The bars are decorative and fixed; which ones are lit follows real playback. */
.waveform { display: flex; align-items: flex-end; gap: 2px; height: 46px; }
.waveform i { flex: 1; background: rgba(255,255,255,.28); border-radius: 1px; }
.waveform i.on { background: var(--teal); }
.player-time { font-variant-numeric: tabular-nums; font-size: var(--t-micro); color: var(--hero-dim); flex: none; }

@media (max-width: 560px) {
  .player { flex-wrap: wrap; }
  .player-main { flex-basis: 100%; order: 3; }
  /* The volume slider is the first thing to go on a phone: there are hardware
     buttons for it, and the space is better spent on the waveform. That leaves
     mute as the only volume control, so it gets a full size tap target. */
  .vol-range { display: none; }
  .vol-btn { width: 44px; height: 44px; }
  .player-side { gap: var(--s-3); margin-left: auto; }
}

.track-row {
  display: grid; grid-template-columns: 44px minmax(0,1fr) auto; gap: var(--s-4);
  align-items: center; padding: var(--s-4) var(--s-5); border: 1px solid var(--line);
  border-radius: var(--r-lg); background: var(--white); margin-bottom: var(--s-3);
  transition: border-color .18s ease, box-shadow .18s ease;
}
.track-row:hover { border-color: var(--line-strong); box-shadow: var(--shadow-1); }
.track-row .player-play { width: 44px; height: 44px; }
.track-row h4 { margin: 0 0 var(--s-1); }
.track-row .card-meta { margin: 0; }
.track-row .row-actions { display: flex; gap: var(--s-2); flex-wrap: wrap; justify-content: flex-end; }

@media (max-width: 700px) {
  .track-row { grid-template-columns: 44px minmax(0,1fr); gap: var(--s-3); padding: var(--s-4); }
  .track-row .row-actions { grid-column: 1 / -1; justify-content: flex-start; gap: var(--s-3); }
  .track-row .row-actions .btn { flex: 1; }
  .filters { padding: var(--s-4); }
}
.pager { display: flex; gap: var(--s-2); justify-content: center; margin-top: var(--s-7); }
.pager a, .pager span {
  min-width: 44px; min-height: 44px; display: grid; place-items: center; padding-inline: var(--s-3);
  border: 1px solid var(--line-strong); border-radius: var(--r-sm); text-decoration: none;
  color: var(--ink); font-size: var(--t-small); font-weight: 600;
}
.pager [aria-current="page"] { background: var(--blue); color: var(--white); border-color: var(--blue); }


/* --- Item page ------------------------------------------------------------
   The catalog pages were built before there was anything in the catalog. These
   are the adjustments that only became visible once real songs were in. */

/* The summary line under the title carries the whole pitch for the item, so it
   should not be set at the same weight as body copy three sections down. */
.item-lede {
  font-size: 1.0625rem; color: var(--ink-muted); max-width: 62ch;
  margin-bottom: var(--s-5);
}

/* Classification sits with the title, the way it does on a catalog card, so a
   producer arriving from a shared link knows what this is before pressing play. */
.item-tags { margin-bottom: var(--s-5); }

/* The details panel is the part a producer actually reads. Rules between rows
   make a long list scannable, and a value that wraps stays tied to its label. */
.spec-list dt { align-self: start; }
.spec-list dd { align-self: start; }
.spec-list dt:not(:first-of-type),
.spec-list dd:not(:first-of-type) { border-top: 1px solid var(--line); padding-top: var(--s-3); }

@media (max-width: 700px) {
  /* Two narrow columns turn every value into a ragged stack on a phone. */
  .spec-list { grid-template-columns: minmax(0,1fr); gap: var(--s-1); }
  .spec-list dd:not(:first-of-type) { border-top: 0; padding-top: 0; }
  .spec-list dd { margin-bottom: var(--s-3); }
}


/* --- Forms ----------------------------------------------------------------
   Ported from the mockups, which carried a full set of control styles that the
   earlier passes never brought across: the theme was falling back to whatever
   the operating system draws. That is why the search box was a bare rectangle
   and the sort control was a raw OS dropdown.

   Kept in mockup order, with its later refinements folded in, for the same
   reason as the catalog block above. */

input, select, textarea {
  width: 100%; font-family: var(--font-body); font-size: var(--t-small); color: var(--ink);
  background: var(--white); border: 1px solid var(--line-strong); border-radius: var(--r-sm);
  padding: .7rem .85rem; min-height: 44px;
}
textarea { min-height: 120px; resize: vertical; line-height: var(--lh-body); }
label { display: block; font-family: var(--font-display); font-weight: 600; font-size: var(--t-small); margin-bottom: var(--s-2); }
.field { margin-bottom: var(--s-5); }
.field .hint { font-size: var(--t-micro); color: var(--ink-muted); margin: var(--s-2) 0 0; }
.req { color: var(--orange-text); }
.form-grid { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 0 var(--s-5); }
.form-grid .span-2 { grid-column: 1 / -1; }
fieldset { border: 1px solid var(--line); border-radius: var(--r-md); padding: var(--s-5); margin: 0 0 var(--s-6); }
legend { font-family: var(--font-display); font-weight: 700; font-size: var(--t-h4); padding-inline: var(--s-2); }
.consent { display: flex; gap: var(--s-3); align-items: flex-start; margin-bottom: var(--s-4); font-size: var(--t-small); }
.consent input { width: 20px; height: 20px; flex: none; margin-top: 2px; min-height: 0; accent-color: var(--blue); }
.form-actions { display: flex; flex-wrap: wrap; gap: var(--s-4); align-items: center; }

@media (max-width: 700px) { .form-grid { grid-template-columns: 1fr; } }

/* One hover and focus language across every control. */
input:hover, select:hover, textarea:hover { border-color: var(--line-strong); }
input:focus, select:focus, textarea:focus {
  outline: none; border-color: var(--blue);
  box-shadow: 0 0 0 3px rgba(11,95,174,.16);
}

/* Selects: the arrow the OS draws cannot be styled, so this is an inline SVG
   background instead. */
select {
  appearance: none; -webkit-appearance: none;
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9' fill='none' stroke='%234A5A6E' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 1l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right var(--s-4) center;
  padding-right: var(--s-8);
  cursor: pointer;
}

/* Checkboxes: accent-color only tints a control the OS still paints. Drawn here
   as a real box with an SVG tick so both states match the design. */
input[type="checkbox"] {
  appearance: none; -webkit-appearance: none;
  width: 20px; height: 20px; min-height: 0; flex: none; padding: 0;
  border: 2px solid var(--line-strong); border-radius: 5px;
  background: var(--white); cursor: pointer;
  transition: background-color .15s ease, border-color .15s ease;
}
input[type="checkbox"]:hover { border-color: var(--blue); }
input[type="checkbox"]:checked {
  background-color: var(--blue); border-color: var(--blue);
  background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='11' viewBox='0 0 14 11' fill='none' stroke='%23fff' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M1 5.5l4 4 8-8'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: center;
}

::placeholder { color: #8494A6; opacity: 1; }

/* The search field is the one control that sits beside a solid button, so it
   carries the same corner radius rather than the tighter field radius. */
.search-row input[type="search"] { border-radius: var(--r-md); }
.search-row .btn { flex: none; }

/* The sort control reads as one unit with its label, not a stray dropdown. */
.result-bar .sort label { margin-bottom: 0; color: var(--ink-muted); font-weight: 600; }
.result-bar select { min-width: 168px; }

/* The range input is not a text field and must not inherit the box. */
.vol-range { border: 0; padding: 0; background: rgba(255,255,255,.28); }

/* --- Cover art on an audio item ------------------------------------------
 *
 * A song or a cue leads with the player, so a featured image has nowhere of
 * its own to go. Sitting it beside the controls means a link shared to a
 * producer arrives with a face. Only drawn when art actually exists, so the
 * songs that have none look exactly as they did.
 *
 * The column collapses before the waveform gets too narrow to scrub. */
.player-with-art { display: grid; grid-template-columns: 200px minmax(0,1fr); gap: var(--s-5); align-items: center; }
.player-art img { display: block; width: 100%; height: auto; border-radius: var(--r-lg); }
@media (max-width: 700px) { .player-with-art { grid-template-columns: minmax(0,1fr); } }

/* --- Licensing and Contact ------------------------------------------------
 *
 * .step-n was the one class the mockups' How it works list needed that never
 * came across with the rest of .steps, so the numbers were rendering as bare
 * text where the design has them in a filled circle.
 *
 * Scoped .steps .step-n, not .step-n on its own. The step number is a <span>
 * inside .steps, so the earlier .steps span rule (one class plus one element)
 * outranks a lone class and was painting the digit muted grey on the blue
 * circle. That is the mockup's own flaw, faithfully reproduced, and it made the
 * numbers effectively invisible. The size override is here for the same
 * reason. */
.steps .step-n {
  width: 44px; height: 44px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--blue);
  color: var(--white); font-family: var(--font-display); font-weight: 700;
  font-size: 1rem;
}

/* The email route is the only working way to make contact until the form
   exists, so it is set larger than body copy rather than buried in a line. */
.contact-email { display: flex; align-items: center; gap: var(--s-3); font-size: 1.0625rem; margin-bottom: var(--s-6); }
.contact-email svg { width: 20px; height: 20px; color: var(--teal-text); flex: none; }

/* Request forms.
   The context block carried in from a content page, so a producer never
   retypes a title they already clicked on. Ported from the approved mockups. */
.prefill {
  background: var(--tint-blue); border: 1px solid #C6DEF6; border-radius: var(--r-md);
  padding: var(--s-4) var(--s-5); margin-bottom: var(--s-6);
}
.prefill h3 { font-size: var(--t-h4); color: var(--blue); margin-bottom: var(--s-3); }
.prefill dl { display: grid; grid-template-columns: max-content minmax(0,1fr); gap: var(--s-2) var(--s-4); margin: 0; font-size: var(--t-small); }
.prefill dt { font-weight: 600; color: var(--blue); }
/* overflow-wrap, because a permalink is one unbroken word and will otherwise
   push the whole block past the edge of a phone screen. */
.prefill dd { margin: 0; overflow-wrap: anywhere; }

@media (max-width: 700px) {
  /* A lone button on a wide row reads as an afterthought on a phone. */
  .form-actions .btn { width: 100%; justify-content: center; }
}

/* A track that is still arriving. The pause icon would be a lie while nothing
   can play yet, so both icons stand down and the ring turns in their place.
   These rules sit after the is-playing pair on purpose: the two selectors carry
   the same weight, so the later one is the one that wins. */
.player-play.is-loading { cursor: progress; }
.player-play.is-loading .play-tri,
.player-play.is-loading .pause-bars { display: none; }
.player-play.is-loading::after {
  content: ""; width: 20px; height: 20px; border-radius: 50%;
  border: 2px solid rgba(255,255,255,.35); border-top-color: var(--white);
  animation: hfks-spin .7s linear infinite;
}
@keyframes hfks-spin { to { transform: rotate(360deg); } }
/* Slowed rather than stopped. It is the only sign that anything is happening,
   and a still ring would put us back to a button that looks broken. */
@media (prefers-reduced-motion: reduce) {
  .player-play.is-loading::after { animation-duration: 2.4s; }
}

/* Rick's homepage artwork, chosen 11 September.
   .has-img reuses the placeholder box so the slot keeps its shape, rounding and
   overflow. object-fit: cover is what stops a picture stretching when its own
   proportions and the slot's disagree; it crops instead, which is the failure
   Rick asked to be watched for. The placeholder's border and padding come off,
   or they would draw a line inside the picture. */
.ph-media.has-img { border: 0; padding: 0; }
.ph-media.has-img > img {
  display: block; width: 100%; height: 100%;
  object-fit: cover; object-position: center 42%;
}
/* The feature band image has no fixed ratio: it stretches to the height of the
   text beside it, so it needs the column's full height to cover. */
.feature-band > .ph-media.has-img > img { min-height: 280px; }

/* Category card artwork, as in the homepage mockup: the picture sits on the
   right of the card, behind the words, and fades into the card's own tint
   rather than ending on a hard edge.
   The text keeps its existing max-width limits, so it stays clear of the
   picture without needing a column. The mask is what does the blending; where
   a browser does not support it the picture simply has a straight edge, which
   still reads correctly. */
.cat-card.has-art { position: relative; overflow: hidden; }
.cat-card.has-art > .cat-art {
  position: absolute; right: 0; top: 0; z-index: 0;
  width: 46%; height: 100%;
  object-fit: cover; object-position: 72% center;
  -webkit-mask-image: linear-gradient(to right, transparent 0, #000 40%);
          mask-image: linear-gradient(to right, transparent 0, #000 40%);
}
/* The heading and paragraph carry ch based limits that do not know the picture
   is there, so on a narrow card the text ran over the artwork. These hold the
   words inside the left half whatever the card width turns out to be. */
.cat-card.has-art > h3 { max-width: 58%; }
.cat-card.has-art > p  { max-width: 56%; }
/* The waveform is line art, not a photograph, so it is centred in its half at
   its own proportions instead of being cropped to fill. */
.cat-card.has-art > .cat-art[src$=".svg"] { object-fit: contain; object-position: center; }
.cat-card.has-art > *:not(.cat-art) { position: relative; z-index: 1; }

@media (max-width: 620px) {
  /* Stacked cards are much wider than tall, so a half width picture would sit
     behind the paragraph. It drops to a narrower strip and fades sooner. */
  .cat-card.has-art > .cat-art { width: 34%; }
  .cat-card.has-art > h3 { max-width: 64%; }
  .cat-card.has-art > p  { max-width: 62%; }
}
