/* The fonts, served from this site (2026-09-29): Google Fonts' stylesheet held up the first paint ~0.9 s on a slow phone
   and needed two more servers. Latin subsets from Google Fonts (SIL Open Font License); Source Sans 3 is one variable
   file for every weight. */
@font-face{font-family:"Source Sans 3";font-style:normal;font-weight:200 900;font-display:swap;src:url(/fonts/source-sans-3.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Source Sans 3";font-style:italic;font-weight:400;font-display:swap;src:url(/fonts/source-sans-3-italic.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:"Young Serif";font-style:normal;font-weight:400;font-display:swap;src:url(/fonts/young-serif.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
/* Dorian Tide — site styles.
   Colours: PROJECTS/DorianTide/brand/README.md (never guessed). The two "deep" navies
   below are Dorian Tide Navy mixed toward black, not new colours. */
:root{
  --navy:#1C445B;
  --navy-deep:color-mix(in oklab,#1C445B 78%,#000);
  --navy-deeper:color-mix(in oklab,#1C445B 58%,#000);
  --navy-raised:color-mix(in oklab,#1C445B 88%,#ABC4D8);
  --cream:#FCE6CC;          /* Gold 1 */
  --gold:#F7D0A1;           /* Gold 2 */
  --gold-deep:#C48E45;      /* Gold 3 */
  --copper:#AB7F42;         /* outlines and shadow only, never text on navy */
  --string:#ABC4D8;         /* Lyre String Blue: secondary text */
  --beam:#FFFFC4;           /* Lighthouse Beam Yellow: the one warm highlight */
  --gold-grad:linear-gradient(180deg,#FCE6CC 0%,#F7D0A1 45%,#C48E45 100%);
  --gold-grad-x:linear-gradient(90deg,#FCE6CC 0%,#F7D0A1 45%,#C48E45 100%);
  --rule:color-mix(in oklab,#ABC4D8 22%,#1C445B);
  /* every filled box is 60% opaque and gold buttons 80%, so the album art shows through (Mason, 2026-09-18) */
  --fill:60%;
  --box:color-mix(in oklab,var(--navy-raised) var(--fill),transparent);
  --box-deep:color-mix(in oklab,var(--navy-deeper) var(--fill),transparent);
  --gold-grad-fill:linear-gradient(180deg,rgb(252 230 204 / .8) 0%,rgb(247 208 161 / .8) 45%,rgb(196 142 69 / .8) 100%);   /* gold buttons: 80% */

  --serif:"Young Serif",Georgia,"Times New Roman",serif;
  --sans:"Source Sans 3",-apple-system,"Segoe UI",Roboto,sans-serif;

  --wrap:1120px;
  --gutter:clamp(16px,4vw,32px);
  --radius:10px;
  --ease:cubic-bezier(.2,.7,.2,1);
  --ease-soft:cubic-bezier(.33,1,.68,1);   /* ease-out-cubic: no lurch at the start */
  --bar:136px;--head:calc(var(--bar) + 22px);   /* the header: the bar the logo drifts in, plus the wave strip (twice as tall, Mason 2026-09-29) */
  color-scheme:dark;
}

*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth}
body{margin:0;background:var(--navy-deep);color:var(--cream);font:400 18px/1.6 var(--sans);
  text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;min-height:100svh;display:flex;flex-direction:column}
main{flex:1}
img{max-width:100%;height:auto;display:block}
a{color:var(--gold);text-decoration-thickness:1px;text-underline-offset:3px}
a:hover{color:var(--cream)}
:focus-visible{outline:2px solid var(--gold);outline-offset:3px;border-radius:4px}
::selection{background:var(--gold);color:var(--navy)}
h1,h2,h3{font-family:var(--serif);font-weight:400;line-height:1.12;margin:0;text-wrap:balance;color:var(--cream)}
h1{font-size:clamp(38px,6.4vw,72px)}
h2{font-size:clamp(30px,4vw,44px)}
h3{font-size:clamp(21px,2.4vw,25px)}
p{margin:0 0 1em}
.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--gutter)}
.skip{position:absolute;left:-999px;top:8px;background:var(--gold);color:var(--navy);padding:8px 14px;border-radius:6px;z-index:100}
.skip:focus{left:8px}
.muted{color:var(--string)}
.eyebrow{font:700 17px/1.3 var(--sans);letter-spacing:.16em;text-transform:uppercase;color:var(--gold-deep)}   /* was 13px (Mason, 2026-09-29: larger); 1.3 so the long Wildcat label wraps cleanly on phones */
.lede{font-size:clamp(19px,2vw,22px);color:var(--string);max-width:60ch}

/* ---------- header ---------- */
.site-header{position:sticky;top:0;z-index:50;background:var(--navy-deeper);   /* solid: at 97% the home buttons showed through once scrolled under it (Mason, 2026-09-19) */
  view-transition-name:site-header}
.site-header .bar{display:flex;align-items:center;justify-content:space-between;gap:20px;height:var(--bar);max-width:none}   /* full width: the menu sits at the right edge */
.nav,.menu-btn{position:relative;z-index:1}   /* above the drifting logo (which bounces off a box round them, site.js) */
.brand{display:flex;align-items:center;gap:12px;text-decoration:none;flex-shrink:0}
.brand-in{display:flex;align-items:center;gap:12px}
/* the DVD-screensaver drift: site.js moves the lyre and the wordmark as two bouncing bodies (DT_FLAGS.logoBounce) */
.brand .lyre{display:block;width:40px;height:41px;background:url(/img/lyre-112.webp) center/contain no-repeat}
/* a background, not an <img>: Safari (iPhone and Mac) left a frozen copy of a moving <img> behind (2026-09-18, 2026-09-29) */
.bounce .brand-in .lyre,.bounce .brand-in .wordmark{display:block}
/* the drifting logo is drawn on a canvas over the bar (site.js); the real lyre and wordmark move with it, invisible,
   so the logo is still a link wherever it is */
.site-header .bar{position:relative}
.logo-fx{position:absolute;left:0;top:0;pointer-events:none}
.logo-canvas .brand-in .lyre,.logo-canvas .brand-in .wordmark{opacity:0}
.wordmark{display:block;width:150px;aspect-ratio:790/134;background:var(--gold-grad);
  -webkit-mask:url(../img/wordmark.svg) center/contain no-repeat;mask:url(../img/wordmark.svg) center/contain no-repeat}
.nav{display:flex;gap:4px;align-items:center}
.nav a{position:relative;color:var(--cream);text-decoration:none;font-weight:600;font-size:16px;padding:8px 11px;border-radius:6px;white-space:nowrap}
.nav a::after{content:"";position:absolute;left:11px;right:11px;bottom:3px;height:2px;border-radius:2px;background:var(--gold-grad-x);
  transform:scaleX(0);transform-origin:left;transition:transform .35s var(--ease)}
.nav a:hover::after,.nav a[aria-current="page"]::after{transform:scaleX(1)}
.nav a[aria-current="page"]{color:var(--gold)}
.nav a.nav-book{margin-left:8px;padding:8px 16px;border-radius:999px;color:var(--cream);
  background:var(--box-deep);--ring:1.5px;padding:9.5px 17.5px;transition:color .2s}
.nav a.nav-book::after{display:none}
.nav a.nav-book:hover,.nav a.nav-book[aria-current="page"]{color:var(--gold)}
.menu-btn{display:none;background:none;border:1.5px solid var(--copper);color:var(--cream);border-radius:8px;
  font:600 15px var(--sans);padding:8px 12px;cursor:pointer}

/* the running-wave strip: the Vitruvian scroll from the logo ring (_build/waves.py draws it), drifting like a slow tide */
.waves{height:22px;overflow:hidden;position:relative;background:var(--navy-deeper)}
/* one tile = one wave, 33 x 22 px. The wave's own width : height is 1.5103 (33.23 px); the tile is drawn a whole
   33 px wide because Safari rounds repeating background tiles to whole px, and the dots (placed every
   js/wave-dots.js `tile` px) then slipped off the waves a little more with every wave (found 2026-09-18). The
   strip drifts four tiles (132 px) per loop and joins seamlessly */
.waves .tide{position:absolute;inset:0 auto 0 0;width:calc(100% + 132px);
  background:url(/img/wave.svg) 0 0/33px 22px repeat-x;
  animation:tide 14s linear infinite;animation-play-state:var(--play,running);will-change:transform}
/* the dots: each colour on its own layer INSIDE the drifting .tide, so they ride the waves' own movement (one
   animation for waves and dots alike, so they can never fall out of step in any browser). js/site.js turns each
   layer's still dots (the fallback) into dots that travel through every wave along its own curve: up the back,
   over the crest and round the curl, shrinking to nothing as it tightens, then again; navy through the gold
   waves, gold through the navy ones, half-turn twins. Transform and opacity only. */
.waves .dots{position:absolute;inset:0;background:0 0/33px 22px repeat-x}
.waves .dots.gold{background-image:url(/img/wave-dots-gold.svg)}
.waves .dots.navy{background-image:url(/img/wave-dots-navy.svg)}
.waves .dots.live{background:none}
.waves .fx{position:absolute;left:0;top:0;height:22px}   /* js/site.js draws the dots and eyes here, one tile repeated */
@keyframes tide{from{transform:translateX(-132px)}to{transform:none}}

/* everything above the waves, larger (Mason, 2026-09-29: the lyre was hard to make out; wordmark and menu bigger too) */
.brand .lyre{width:80px;height:82px;background-image:url(/img/lyre-320.webp)}
.site-header .wordmark{width:300px}
.brand-in{gap:16px}
.nav{gap:6px}
.nav a{font-size:20px;padding:10px 14px}
.nav a::after{left:14px;right:14px}
.nav a.nav-book{margin-left:10px;padding:11.5px 21.5px}
.menu-btn{font-size:18px;padding:10px 16px}

/* folding-phone cover screens (~280px): the full-size wordmark pushed the menu button off the screen */
@media (max-width:319px){.wordmark{width:112px}.site-header .bar{gap:10px}}

@media (max-width:1100px){
  .menu-btn{display:block}
  .nav{position:absolute;top:100%;left:0;right:0;flex-direction:column;align-items:stretch;gap:0;
    background:var(--navy-deeper);padding:8px var(--gutter) 18px;border-bottom:1px solid var(--rule);
    clip-path:inset(0 0 100% 0);visibility:hidden;transition:clip-path .35s var(--ease),visibility 0s .35s}
  .nav a{padding:13px 4px;font-size:18px;border-bottom:1px solid var(--rule)}
  .nav a::after{left:4px;right:auto;width:40px;bottom:8px}
  .nav a.nav-book{margin:14px 0 0;text-align:center;padding:14.5px 17.5px}
  .site-header.open .nav{clip-path:inset(0 0 0 0);visibility:visible;transition:clip-path .35s var(--ease)}
}

/* ---------- buttons ---------- */
.ring{position:relative}
.ring::before,.btn-line::before,.nav a.nav-book::before,.panel.gold-edge::before{content:"";position:absolute;inset:0;border-radius:inherit;
  padding:var(--ring,2px);background:var(--gold-grad);pointer-events:none;
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude}
.btn{position:relative;display:inline-flex;align-items:center;justify-content:center;gap:8px;overflow:hidden;
  font:700 16px/1 var(--sans);letter-spacing:.02em;padding:15px 26px;border-radius:999px;text-decoration:none;cursor:pointer;
  border:0;transition:transform .25s var(--ease),box-shadow .25s var(--ease)}
.btn-gold{background:var(--gold-grad-fill);color:var(--navy);box-shadow:0 6px 22px -10px var(--gold-deep)}
.btn-gold:hover{color:var(--navy);transform:translateY(-2px);box-shadow:0 12px 28px -12px var(--gold-deep)}
/* a single sheen crosses the gold on hover, like light on brass */
.btn-gold::after{content:"";position:absolute;inset:0;background:linear-gradient(105deg,transparent 35%,rgba(255,255,236,.75) 50%,transparent 65%);
  transform:translateX(-120%);pointer-events:none}
.btn-gold:hover::after{transform:translateX(120%);transition:transform .8s var(--ease)}
.btn-line{color:var(--cream);background:color-mix(in oklab,var(--navy-deep) var(--fill),transparent);padding:17px 28px}
.btn-line.btn-sm{padding:12px 20px}
.btn-line:hover{color:var(--gold);transform:translateY(-2px)}
.btn-sm{padding:10px 18px;font-size:15px}
.btn-row{display:flex;flex-wrap:wrap;gap:12px;align-items:center}
/* the band's profiles beside the buttons: round, in the Book button's navy and copper, the logos in cream */
.socials{display:flex;gap:10px;flex-wrap:wrap}
.soc{display:grid;place-items:center;width:48px;height:48px;border-radius:50%;background:var(--box-deep);border:1.5px solid var(--copper);
  color:var(--cream);transition:color .2s,border-color .2s,transform .2s}
.soc svg{width:22px;height:22px;fill:currentColor}
.soc:hover,.soc:focus-visible{color:var(--gold);border-color:var(--gold);transform:translateY(-2px)}

/* ---------- sections ---------- */
.section{padding:clamp(64px,9vw,112px) 0}
/* no colour bands between sections (Mason + Tim, 2026-09-19): the page runs continuously over the art */
.section-head{display:grid;gap:12px;margin-bottom:clamp(28px,4vw,44px);max-width:720px}
.section-head h2{position:relative;padding-bottom:16px}
.section-head h2::after{content:"";position:absolute;left:0;bottom:0;width:64px;height:3px;border-radius:2px;background:var(--gold-grad-x);
  transform-origin:left}
.section-head.center{margin-inline:auto;text-align:center;justify-items:center}
.section-head.center h2::after{left:50%;margin-left:-32px;transform-origin:center}
.two-col{display:grid;grid-template-columns:1.1fr .9fr;gap:clamp(32px,6vw,80px);align-items:center}
@media (max-width:820px){.two-col{grid-template-columns:minmax(0,1fr)}}
.prose{max-width:64ch}
.prose p:last-child{margin-bottom:0}

/* ---------- page hero (inner pages) ---------- */
.page-hero{position:relative;padding:clamp(72px,11vw,128px) 0 clamp(48px,7vw,80px);overflow:hidden;isolation:isolate}
.page-hero .glow{position:absolute;z-index:-1;right:-6%;top:-30%;width:min(60vw,640px);aspect-ratio:1;border-radius:50%;
  background:radial-gradient(closest-side,color-mix(in oklab,var(--beam) 16%,transparent),transparent);
  animation:breathe 9s ease-in-out infinite alternate}
@keyframes breathe{from{opacity:.55;transform:scale(.94)}to{opacity:1;transform:scale(1.04)}}
.page-hero h1{margin:14px 0 18px}
/* slim header: just the small gold page title (and an optional paragraph), then straight into the page */
.page-hero.slim{padding:clamp(40px,6vw,64px) 0 0;background:none}
.page-hero.slim h1{margin:0}
.page-hero.slim .lede{margin:16px 0 0}
.page-hero.slim+.section{padding-top:clamp(24px,3.5vw,36px)}

/* ---------- home hero ---------- */
.hero{position:relative;display:grid;align-items:center}
/* The album art is pinned behind the whole home page: the page scrolls over it, and after the first few
   pixels it eases to 60% (site.js sets .scrolled). It sits below the sticky header (--head (wave strip included), and uses
   the large viewport height so a phone's collapsing toolbar never resizes it mid-scroll. */
.hero-art{position:fixed;left:0;top:var(--head);width:100%;height:calc(100lvh - var(--head));z-index:-2;background-size:cover;background-position:center;
  overflow:hidden;transition:opacity .8s var(--ease)}
.settle .hero-art{animation:settle 2.6s var(--ease) backwards}   /* first visit of the session only */
.scrolled .hero-art,.has-art:not(.page-home) .hero-art{opacity:.6}   /* inner pages: dimmed from the start */
.nodim.scrolled .page-home .hero-art{opacity:1}   /* phones, DT_FLAGS.phoneNoDim: no dimming on scroll */
/* phone zoom-out (DT_FLAGS.phoneArtFill): the art sits at the bottom; above it, the sky's own colour until the
   clouds layer continues it */
.hero-art.zoomed{background:linear-gradient(#070d18,#0d1d2f) !important}
/* the animated art fades in over the still once its first frame is drawn (html.sky-ready, clouds.js); that frame
   matches the still, and the motion eases in after it, so the only visible change is a phone's added sky arriving */
.clouds-gl{opacity:0;transition:opacity .6s var(--ease)}
.sky-ready .clouds-gl{opacity:1}
.hero-art img{width:100%;height:100%;object-fit:cover;object-position:0 50%}   /* screens narrower than the art trim only its right edge (clouds and stars): the nebula, lighthouse and beach on the left always show (Mason, 2026-09-19) */
/* The lighthouse beacon: the Tide visualizer's slow turning beam, ported to two composited layers.
   site.js sets --lx/--ly (the lantern, in px) and --bw/--bh (the beam's size) from the image's crop. */
.beacon{position:absolute;left:var(--lx,0);top:var(--ly,0);width:0;height:0;display:none;mix-blend-mode:screen}
.beacon.on{display:block}
.beacon .beam{position:absolute;left:0;top:calc(var(--bh,0px) / -2);width:var(--bw,0px);height:var(--bh,0px);
  transform-origin:0 50%;will-change:transform,opacity}
.beacon .lamp{position:absolute;left:calc(var(--lamp,40px) / -2);top:calc(var(--lamp,40px) / -2);width:var(--lamp,40px);height:var(--lamp,40px);
  border-radius:50%;will-change:transform,opacity;
  background:radial-gradient(closest-side,rgba(238,244,255,.95) 0%,rgba(238,244,255,.5) 18%,rgba(238,244,255,.14) 45%,transparent 100%)}
/* the flash as the beam faces you: a bloom far wider than the lantern, with a glare streak across and a
   fainter one up and down (site.js animates it with the turn) */
.beacon .flash{position:absolute;left:calc(var(--flash,120px) / -2);top:calc(var(--flash,120px) / -2);width:var(--flash,120px);
  height:var(--flash,120px);opacity:0;will-change:transform,opacity;border-radius:50%;
  background:radial-gradient(closest-side,#fff 0%,rgba(242,247,255,.9) 5%,rgba(232,241,255,.5) 13%,rgba(215,230,255,.2) 32%,rgba(200,220,255,.07) 60%,transparent 100%)}
.beacon .flash::before,.beacon .flash::after{content:"";position:absolute;left:50%;top:50%}
.beacon .flash::before{width:140%;height:2px;margin:-1px 0 0 -70%;
  background:linear-gradient(90deg,transparent,rgba(225,236,255,.22) 28%,rgba(255,255,255,.8) 50%,rgba(225,236,255,.22) 72%,transparent)}
.beacon .flash::after{width:1.5px;height:60%;margin:-30% 0 0 -.75px;
  background:linear-gradient(transparent,rgba(225,236,255,.15) 30%,rgba(255,255,255,.5) 50%,rgba(225,236,255,.15) 70%,transparent)}
@keyframes settle{from{transform:scale(1.07);opacity:.2}to{transform:scale(1);opacity:1}}
.hero>.wrap{width:100%}
.hero{align-items:start}
/* the buttons sit just under the waves, and Next Shows follows close behind, all in the first view */
.hero-copy{padding:clamp(20px,3vw,32px) 0 0;display:grid;gap:18px;max-width:560px;margin-left:auto}
.page-home .hero+.section{padding-top:clamp(28px,4vw,44px);background:none}
/* every screen: the first view is the art and the buttons only, and once they scroll away the whole art shows
   with nothing over it; Next Shows starts below that (Mason: phones 2026-09-18, tablets and desktop 2026-09-19,
   past the buttons 2026-09-19). A full screen below the buttons: the tallest screen (toolbars hidden) under
   the header (--head), plus a margin */
.page-home .hero{padding-bottom:calc(100lvh - var(--head) + 28px)}
/* phones held sideways (Tim, 2026-09-19): the art hangs from the top of its layer, so the buttons sit over the
   starry sky at its top and the moon, lighthouse and beach all fall below them */
@media (orientation:landscape) and (max-height:500px){html .hero-art img{object-position:0 0}}   /* html: outranks the max-width:820px rule below */
.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}
.hero-copy h1{text-shadow:0 2px 30px rgba(0,0,0,.45);font-size:clamp(38px,5.4vw,64px)}
.hero-copy p{font-size:clamp(19px,2vw,22px);color:var(--cream);max-width:34ch;margin:0 0 8px;text-shadow:0 1px 18px rgba(0,0,0,.55)}
@media (max-width:820px){
  .hero-copy{margin-left:0}
}
.hero .wordmark{width:clamp(220px,34vw,360px)}
/* with no colour bands behind the sections (2026-09-19), a soft dark halo keeps words readable where they
   cross the bright clouds; buttons keep their own clean text. The blur is kept small
   because every line of text carries it */
.has-art main{text-shadow:0 1px 2px rgba(0,0,0,.7),0 0 6px rgba(4,10,20,.65)}
.has-art main .btn,.has-art main .soc{text-shadow:none}

/* ---------- shows ---------- */
.show-list{list-style:none;margin:0;padding:0;display:grid;gap:14px}
.show{display:grid;grid-template-columns:84px 1fr auto;gap:22px;align-items:center;padding:18px 22px;border-radius:var(--radius);
  background:var(--box);border:1px solid var(--rule);transition:transform .3s var(--ease),border-color .3s}
.show:hover{transform:translateX(4px);border-color:var(--copper)}
.show-date{display:grid;justify-items:center;line-height:1;padding:10px 0;border-radius:8px;background:var(--box-deep)}
.show-date .m{font:700 13px var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold-deep)}
.show-date .d{font:400 34px var(--serif);color:var(--cream);margin-top:6px}
.show-date .w{font:600 12px var(--sans);color:var(--string);margin-top:6px;text-transform:uppercase;letter-spacing:.1em}
.show h3{font-size:22px}
.show .where{color:var(--string);margin:4px 0 0;font-size:16px}
.show .tag{font:700 12px var(--sans);letter-spacing:.12em;text-transform:uppercase;color:var(--gold);border:1px solid var(--copper);padding:6px 10px;border-radius:999px;white-space:nowrap}
.shows-empty{display:none;padding:28px;border:1px dashed var(--copper);border-radius:var(--radius);max-width:60ch}
.shows-empty.show-me{display:block}
@media (max-width:560px){.show{grid-template-columns:68px 1fr;gap:16px;padding:14px}.show .tag{grid-column:2;justify-self:start}}

/* ---------- media facades: nothing third-party loads until asked ---------- */
.facade{position:relative;display:block;width:100%;max-width:900px;aspect-ratio:16/9;border:0;padding:0;border-radius:var(--radius);overflow:hidden;cursor:pointer;
  background:var(--navy-deeper);color:var(--cream);box-shadow:0 30px 60px -30px rgba(0,0,0,.6)}
.facade img{width:100%;height:100%;object-fit:cover;transition:transform .8s var(--ease),filter .4s}
.facade:hover img{transform:scale(1.03);filter:brightness(1.08)}
.facade .play{position:absolute;inset:0;margin:auto;width:78px;height:78px;border-radius:50%;background:var(--gold-grad-fill);
  display:grid;place-items:center;box-shadow:0 10px 30px -8px rgba(0,0,0,.6);transition:transform .3s var(--ease)}
.facade .play::before{content:"";margin-left:6px;border-left:22px solid var(--navy);border-top:14px solid transparent;border-bottom:14px solid transparent}
.facade:hover .play{transform:scale(1.08)}
.facade .caption{position:absolute;left:0;right:0;bottom:0;padding:40px 20px 16px;text-align:left;font:600 16px var(--sans);
  background:linear-gradient(transparent,rgba(8,20,28,.85))}
.facade iframe{position:absolute;inset:0;width:100%;height:100%;border:0}
.video-pair{margin-top:22px;max-width:900px}
.video-pair .facade .play{width:62px;height:62px}
.spotify-slot{border-radius:12px;overflow:hidden;min-height:152px}
.spotify-slot iframe{display:block;width:100%;height:352px;border:0}

/* ---------- cards / merch ---------- */
.grid-2{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));gap:22px}
.grid-3{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,260px),1fr));gap:22px}
.card{display:grid;grid-template-rows:auto 1fr;background:var(--box);border:1px solid var(--rule);border-radius:14px;overflow:hidden;
  transition:transform .35s var(--ease),border-color .35s,box-shadow .35s}
.card:hover{transform:translateY(-4px);border-color:var(--copper);box-shadow:0 24px 50px -30px rgba(0,0,0,.7)}
.card-art{aspect-ratio:1;display:grid;place-items:center;background:var(--navy);padding:9%;overflow:hidden}
.card-art.light{background:radial-gradient(circle at 50% 45%,#FCE6CC 0%,#F7D0A1 70%,#C48E45 130%)}
.card-art img{width:100%;height:100%;object-fit:contain;transition:transform .6s var(--ease)}
.card:hover .card-art img{transform:scale(1.04) rotate(-1deg)}
.card-body{padding:20px 22px 24px;display:grid;gap:8px;align-content:start}
.card-body .price{font:400 22px var(--serif);color:var(--gold)}
.card-body .meta{font-size:15px;color:var(--string);margin:0}
.card-body .btn{justify-self:start;margin-top:8px}
.sold-out .card-art img{filter:saturate(.6) brightness(.8)}
.ribbon{position:absolute;top:14px;left:14px;z-index:1;padding:6px 12px;border-radius:999px;background:var(--navy-deeper);color:var(--gold);font:700 12px var(--sans);letter-spacing:.12em;text-transform:uppercase}
.card-art{position:relative}

/* ---------- lists, FAQ ---------- */
.ticks{list-style:none;margin:0;padding:0;display:grid;gap:14px}
.ticks li{position:relative;padding-left:34px}
.ticks li::before{content:"";position:absolute;left:0;top:.35em;width:18px;height:18px;border-radius:50%;background:var(--gold-grad);
  -webkit-mask:radial-gradient(circle,#000 38%,transparent 40%,transparent 58%,#000 60%);mask:radial-gradient(circle,#000 38%,transparent 40%,transparent 58%,#000 60%)}
.ticks b{color:var(--gold);font-weight:700}
.faq{display:grid;gap:10px}
.faq details{background:var(--box);border:1px solid var(--rule);border-radius:var(--radius);interpolate-size:allow-keywords}
.faq summary{list-style:none;cursor:pointer;padding:18px 54px 18px 20px;font-weight:700;position:relative}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"";position:absolute;right:22px;top:50%;width:10px;height:10px;margin-top:-7px;border-right:2px solid var(--gold);border-bottom:2px solid var(--gold);
  transform:rotate(45deg);transition:transform .3s var(--ease)}
.faq details[open] summary::after{transform:rotate(225deg);margin-top:-2px}
.faq details::details-content{block-size:0;overflow:clip;transition:block-size .35s var(--ease),content-visibility .35s allow-discrete}
.faq details[open]::details-content{block-size:auto}
.faq details p{padding:0 20px 18px;margin:0;color:var(--string)}

/* ---------- forms ---------- */
.form{display:grid;grid-template-columns:1fr 1fr;gap:18px 20px;background:var(--box);border:1px solid var(--rule);border-radius:16px;padding:clamp(20px,4vw,36px)}
.form .full{grid-column:1/-1}
@media (max-width:640px){.form{grid-template-columns:1fr}}
.field{display:grid;gap:7px}
.field label{font-weight:700;font-size:15px}
.field label .opt{font-weight:400;color:var(--string)}
.field input,.field select,.field textarea{width:100%;font:400 17px var(--sans);color:var(--cream);background:var(--box-deep);
  border:1.5px solid var(--rule);border-radius:8px;padding:12px 14px;transition:border-color .2s,box-shadow .2s}
.field textarea{min-height:130px;resize:vertical}
.field input::placeholder,.field textarea::placeholder{color:color-mix(in oklab,var(--string) 70%,transparent)}
.field input:focus,.field select:focus,.field textarea:focus{outline:none;border-color:var(--gold);box-shadow:0 0 0 3px color-mix(in oklab,var(--gold) 25%,transparent)}
.form-foot{grid-column:1/-1;display:flex;flex-wrap:wrap;align-items:center;gap:16px 24px}
.form-foot p{margin:0;color:var(--string);font-size:16px}
.form-status{grid-column:1/-1;margin:0;color:var(--gold);min-height:1.4em}
.inline-form{display:flex;gap:10px;flex-wrap:wrap;max-width:520px}
.inline-form input{flex:1 1 220px;font:400 17px var(--sans);color:var(--cream);background:var(--box-deep);border:1.5px solid var(--rule);border-radius:999px;padding:13px 20px}
.inline-form input:focus{outline:none;border-color:var(--gold)}

/* ---------- panels ---------- */
.panel{background:var(--box);position:relative;border:1px solid var(--rule);border-radius:16px;padding:clamp(24px,4vw,40px)}
.panel.gold-edge{border:0;--ring:1.5px}
.stat-row{display:flex;flex-wrap:wrap;gap:28px 48px;margin-top:8px}
.stat .n{font:400 clamp(34px,4vw,46px)/1 var(--serif);background:var(--gold-grad);-webkit-background-clip:text;background-clip:text;color:transparent}
.stat .l{font-size:15px;color:var(--string);margin-top:6px}
.cover{border-radius:12px;box-shadow:0 40px 80px -40px rgba(0,0,0,.8)}
.float{animation:float 7s ease-in-out infinite alternate}
@keyframes float{from{transform:translateY(-6px)}to{transform:translateY(6px)}}

/* ---------- about: the two bios ---------- */
.bios .wrap{display:grid;gap:clamp(56px,8vw,96px)}
.bio{display:grid;grid-template-columns:minmax(0,340px) minmax(0,1fr);gap:clamp(28px,5vw,64px);align-items:start}
.bio:nth-child(even){grid-template-columns:minmax(0,1fr) minmax(0,340px)}
.bio:nth-child(even) .bio-photo{order:2}
.bio-photo{margin:0;position:sticky;top:120px}
.bio-photo img{width:100%;aspect-ratio:1;object-fit:cover;border-radius:14px;box-shadow:0 30px 60px -30px rgba(0,0,0,.7)}
.bio-photo figcaption{margin-top:10px;font-size:14px;color:var(--string)}
.bio-text h2{margin-bottom:6px}
.bio-role{font:700 13px/1.4 var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold-deep);margin-bottom:22px}
.bio-text p:not(.bio-role){max-width:66ch}
@media (max-width:820px){
  .bio,.bio:nth-child(even){grid-template-columns:1fr}
  .bio:nth-child(even) .bio-photo{order:0}
  .bio-photo{position:static;max-width:360px}
}

/* placeholders for things that come across from Bandzoogle before launch */
.todo{border:1.5px dashed var(--copper);border-radius:var(--radius);padding:14px 18px;color:var(--string);font-size:15px}
.todo b{color:var(--gold-deep)}

/* ---------- footer ---------- */

/* ---------- living clouds (prototype) ---------- */
.clouds-gl{position:absolute;inset:0;width:100%;height:100%;display:block}
/* shooting stars (js/site.js): one thin streak at a time, bright at its head, over the clouds and under the beam */
.meteors{position:absolute;inset:0;overflow:hidden;pointer-events:none}
/* the comet (every tenth, js/site.js): its head at the container's origin, the tails reaching back behind it */
.comet{position:absolute;left:0;top:0;width:0;height:0;opacity:0;mix-blend-mode:screen;will-change:transform,opacity}
.comet i{position:absolute;display:block}
/* a real comet's head (Mason: the old one looked like a light bulb): a tiny sharp nucleus in a hazy coma with the
   faint green-cyan of real comae, brightest at the nucleus, fading fast ahead of it, swept back into a teardrop
   that runs into the tail */
.comet .head{left:-1.5px;top:-1.5px;width:3px;height:3px;border-radius:50%;
  background:radial-gradient(closest-side,#fff 0,rgba(235,252,255,.9) 45%,transparent)}
.comet .coma{left:-62px;top:-16px;width:84px;height:32px;
  background:radial-gradient(ellipse 62px 16px at 62px 50%,rgba(215,250,240,.5) 0,rgba(170,235,220,.24) 20%,rgba(140,215,210,.09) 48%,transparent);
  -webkit-mask:linear-gradient(to right,#000 62%,transparent 92%);mask:linear-gradient(to right,#000 62%,transparent 92%)}
.comet .halo{left:-9px;top:-9px;width:18px;height:18px;border-radius:50%;
  background:radial-gradient(closest-side,rgba(225,250,245,.35),rgba(180,235,225,.1) 55%,transparent)}
.comet .tail{right:calc(var(--th) * -.22);top:calc(var(--th) / -2);width:calc(var(--tl) + var(--th) * .22);height:var(--th);
  border-radius:0 50% 50% 0 / 0 50% 50% 0;border-top-right-radius:calc(var(--th) * .5) 50%;border-bottom-right-radius:calc(var(--th) * .5) 50%;
  background:radial-gradient(ellipse var(--tl) calc(var(--th) / 2) at calc(100% - var(--th) * .22) 50%,
    rgba(228,242,255,.72) 0,rgba(190,228,255,.32) 20%,rgba(150,220,245,.12) 48%,transparent);
  -webkit-mask:linear-gradient(to left,transparent 0,#000 calc(var(--th) * .3));mask:linear-gradient(to left,transparent 0,#000 calc(var(--th) * .3))}
.spark{position:absolute;left:0;top:0;width:1px;height:1px;opacity:0;mix-blend-mode:screen;will-change:transform,opacity;
  background:#c6fbff}                       /* one pixel each (Mason): a solid colour, since a gradient that small washes out */
.spark.deep{background:#8ff5e6}
.comet .ion{right:0;top:-.5px;width:calc(var(--tl) * 1.25);height:1px;transform-origin:100% 50%;transform:rotate(-2.5deg);
  background:linear-gradient(to left,rgba(170,205,255,.55),rgba(150,190,255,.15) 45%,transparent)}
.meteor{position:absolute;left:0;top:0;height:2px;margin-top:-1px;border-radius:1px;transform-origin:0 50%;opacity:0;
  background:linear-gradient(90deg,rgba(210,228,255,0),rgba(210,228,255,.35) 55%,#fff);mix-blend-mode:screen;will-change:transform,opacity}
.page-lab .hero-art.hero-art.hero-art{opacity:1}
.page-lab main{min-height:100vh}
.page-lab main+.waves{display:none}
.lab{position:fixed;right:16px;bottom:16px;z-index:60;width:300px;max-height:calc(100vh - 120px);overflow:auto;
  background:rgb(10 24 32 / .88);border:1px solid var(--copper);border-radius:14px;padding:14px 16px;font-size:14px;color:var(--cream)}
.lab-head{display:flex;justify-content:space-between;align-items:center;margin-bottom:4px}
.lab button{font:600 13px var(--sans);color:var(--gold);background:none;border:1px solid var(--copper);border-radius:999px;padding:5px 12px;cursor:pointer}
.lab-group{margin:12px 0 4px;font:700 11px var(--sans);letter-spacing:.14em;text-transform:uppercase;color:var(--gold-deep)}
.lab label{display:grid;grid-template-columns:1fr 44px;align-items:center;gap:2px 8px;margin:6px 0}
.lab input{grid-column:1/-1;grid-row:2;width:100%;accent-color:var(--gold)}
.lab output{text-align:right;color:var(--string);font-variant-numeric:tabular-nums}
.lab-row{display:flex;gap:8px;margin-top:12px}
.lab-stats{margin:10px 0 0;color:var(--string);font-size:12px}
.lab-min > :not(.lab-head){display:none}

/* ---------- screensaver (Home only) ---------- */
/* After 10 s with no mouse or keys (site.js adds .idle), everything below the header fades away completely
   and the album art comes up to full, so the art and the turning beam take over. The header, gold waves
   included, stays bright. It fades out slowly and comes back at once. */
/* one layer each for Safari: otherwise it draws some cards on layers of their own and leaves them on screen */
.page-home main{transition:opacity .25s ease,visibility 0s;will-change:opacity}
/* Safari leaves some layers drawn when only the parent's opacity drops, so the content is also hidden
   (visibility) once the fade has run: that removes every piece in every browser. */
.idle .page-home main{opacity:0;visibility:hidden;transition:opacity 1.6s ease,visibility 0s 1.6s}
html.idle .hero-art.hero-art.hero-art{opacity:1}

/* ---------- motion ---------- */
/* reveal-on-scroll: only when JS is running, so nothing is ever hidden without it */
/* smoothed (Mason, 2026-09-18: "kinda jerky"): starts just before the block scrolls in, a softer ease-out over
   ~1 s, a shorter rise, and the layer is ready before it moves (site.js drops will-change once it has landed) */
.js [data-reveal]{opacity:0;transform:translate3d(0,14px,0);will-change:opacity,transform;
  transition:opacity .9s var(--ease-soft),transform 1.1s var(--ease-soft);transition-delay:calc(var(--i,0) * 70ms)}
.js [data-reveal].in{opacity:1;transform:none}
.js [data-reveal].landed{transition-delay:0s}
.js .show[data-reveal].landed{transition:transform .3s var(--ease),border-color .3s}   /* hover snaps as before */
.js .section-head[data-reveal] h2::after{transform:scaleX(0);transition:transform .9s var(--ease) .25s}
.js .section-head[data-reveal].in h2::after{transform:scaleX(1)}
.js [data-reveal].now,.js [data-reveal].now h2::after{transition:none!important}   /* on screen at load: no fade (the inline script in build.py FOOT) */
/* entrances only on the first visit of a session (.settle): on later page changes the page is simply there */
.settle .hero-copy>*{animation:rise .9s var(--ease) both}
.settle .hero-copy>*:nth-child(2){animation-delay:.15s}.settle .hero-copy>*:nth-child(3){animation-delay:.3s}.settle .hero-copy>*:nth-child(4){animation-delay:.45s}
@keyframes rise{from{opacity:0;transform:translateY(16px)}}
.settle .page-hero .wrap>*{animation:rise .8s var(--ease) both}
.settle .page-hero .wrap>*:nth-child(2){animation-delay:.1s}.settle .page-hero .wrap>*:nth-child(3){animation-delay:.2s}

/* page-to-page: the header stays put, the page underneath crossfades */
@view-transition{navigation:auto}
/* the old page stays solid underneath while the new one fades in over it, so nothing ever dips to half opacity
   (Mason, 2026-09-29: pages sat at ~50% for a second; a separate art layer held over the content and an
   out-fade faster than the in-fade both dimmed everything). The art is part of the page again, so it can't cover it. */
::view-transition-old(root){animation:none;mix-blend-mode:normal}
::view-transition-new(root){animation:.3s var(--ease) both vt-in;mix-blend-mode:normal}
@keyframes vt-in{from{opacity:0}}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important;scroll-behavior:auto!important}
  .js [data-reveal]{opacity:1;transform:none}
  @view-transition{navigation:none}
}


/* the larger header on smaller screens: lyre + wordmark + Menu must still fit on one line */
@media (max-width:1100px){.brand .lyre{width:60px;height:62px}.site-header .wordmark{width:210px}}
@media (max-width:400px){.brand .lyre{width:50px;height:51px}.brand-in{gap:12px}.site-header .wordmark{width:170px}.menu-btn{font-size:16px;padding:8px 12px}}
@media (max-width:360px){.brand .lyre{width:44px;height:45px}.brand-in{gap:10px}.site-header .wordmark{width:140px}}
@media (max-width:319px){.brand .lyre{width:40px;height:41px}.site-header .wordmark{width:112px}}

/* Home: Listen, Book the band and the social buttons centred at the top of the page (Mason, 2026-09-29; briefly at the
   right edge, like the menu) */
.page-home .hero>.wrap{max-width:none}
.page-home .hero-copy,html .page-home .hero-copy{margin-left:auto;margin-right:auto}
.page-home .hero .btn-row,.page-home .hero .socials{justify-content:center}
/* Listen, Book the band and the three profile icons on one row (Mason, 2026-09-29), sized down to fit narrow phones */
.page-home .hero .btn-row{flex-wrap:nowrap}
.page-home .hero .btn,.page-home .hero .soc{flex-shrink:0;white-space:nowrap}
@media (max-width:480px){.page-home .hero .btn-row,.page-home .hero .socials{gap:8px}.page-home .hero .btn{padding:13px 16px;font-size:15px}
  .page-home .hero .soc{width:42px;height:42px}.page-home .hero .soc svg{width:19px;height:19px}}
@media (max-width:420px){.page-home .hero .btn-row,.page-home .hero .socials{gap:7px}.page-home .hero .btn{padding:12px 13px;font-size:14px}
  .page-home .hero .soc{width:40px;height:40px}.page-home .hero .soc svg{width:18px;height:18px}}
@media (max-width:370px){.page-home .hero .btn-row,.page-home .hero .socials{gap:5px}.page-home .hero .btn{padding:11px 10px;font-size:13px;letter-spacing:0}
  .page-home .hero .soc{width:33px;height:33px}.page-home .hero .soc svg{width:15px;height:15px}}
@media (max-width:310px){.page-home .hero .btn-row,.page-home .hero .socials{gap:4px}.page-home .hero .btn{padding:10px 8px;font-size:12px}
  .page-home .hero .soc{width:30px;height:30px}.page-home .hero .soc svg{width:14px;height:14px}}
