/* OldGold, public pages. A sound system rig in textured black: rendered horn-loaded cabinet faces (see
   tools/render_rig.py), flared horn frames around the content, a flight case for booking. /links is the rack.
   Gold is for the one thing to press (Play) and the cabinets' nameplates. */

/* Archivo (SIL Open Font License), self-hosted: the Latin subset of the variable font, width 62 to 125%, weight 100 to 900 */
@font-face{font-family:'Archivo'; font-style:normal; font-weight:100 900; font-stretch:62% 125%; font-display:swap;
  src:url(/assets/archivo-latin.woff2) format('woff2')}

:root{
  --floor:#070707;
  --bone:#ECEAE4; --dim:#A9A69E; --faint:#8C8981; --gold:#C9A43E; --gold-hi:#E2BE55;
  --face:'Archivo','Arial Narrow',Arial,sans-serif;
  --gap:4px; --beat:.4286s; --bar:calc(var(--beat) * 4);
  color-scheme:dark; accent-color:var(--gold); caret-color:var(--gold);
}
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0; min-height:100svh; color:var(--bone); font:16px/1.5 var(--face); -webkit-font-smoothing:antialiased;
  background:
    radial-gradient(70% 45% at 18% -4%, rgba(236,234,228,.06), transparent 70%) no-repeat,
    radial-gradient(110% 60% at 50% -8%, #1b1914 0%, #0c0c0a 42%, var(--floor) 72%) no-repeat, var(--floor)}
::selection{background:rgba(201,164,62,.3); color:#FFF6E4}
:focus-visible{outline:2px solid var(--bone); outline-offset:3px; border-radius:4px}
a{color:inherit}
img{display:block; max-width:100%; height:auto}
h1,h2,p{margin:0}
[hidden]{display:none !important}
.sr{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap}
button{font:inherit; color:inherit; cursor:pointer}

/* ---------------------------------------------------------------- the room behind the rig */
/* Haze with two stage lights sweeping slowly through it and dust drifting in the light (public.js draws the dust).
   At rest it is barely there; while the set plays the lights warm to gold and pulse with the bar, and the dust
   jumps on the kick. It sits under everything and never takes a click. */
.room{position:fixed; inset:0; z-index:-1; overflow:hidden; pointer-events:none}
.dust{position:absolute; inset:0; width:100%; height:100%}
.beam{position:absolute; top:-12vh; width:min(64vmax,900px); height:140vh; transform-origin:50% 0; will-change:transform;
  clip-path:polygon(47% 0, 53% 0, 100% 100%, 0 100%);
  background:linear-gradient(180deg, rgba(236,234,228,.075), rgba(236,234,228,.025) 38%, transparent 72%)}
.beam::after{content:''; position:absolute; inset:0; opacity:0; transition:opacity 1.2s;
  background:linear-gradient(180deg, rgba(226,190,85,.16), rgba(201,164,62,.05) 40%, transparent 74%)}
.b1{left:calc(50% - min(64vmax,900px) * .5 - 34vw); animation:sweep 23s ease-in-out infinite alternate}
.b2{left:calc(50% - min(64vmax,900px) * .5 + 34vw); animation:sweep 29s ease-in-out -11s infinite alternate-reverse}
@keyframes sweep{from{transform:rotate(-13deg)} to{transform:rotate(9deg)}}
.live .beam::after{opacity:1; animation:flare var(--bar) cubic-bezier(.2,.8,.3,1) infinite}
@keyframes flare{0%{opacity:1} 30%{opacity:.45} 50%{opacity:.8} 70%,100%{opacity:.5}}

/* ---------------------------------------------------------------- the rig */
.rig{width:min(100% - 24px, 720px); margin:0 auto; padding:clamp(12px,3vh,28px) 0 0; display:grid; gap:var(--gap);
  grid-template-areas:"top" "sub" "next" "photo" "tunes" "list" "case" "floor"}
.rig > .top{grid-area:top} .rig > .sub{grid-area:sub} .rig > #shows{grid-area:next} .rig > .photo{grid-area:photo}
.rig > .tunes{grid-area:tunes} .rig > .list{grid-area:list} .rig > .case{grid-area:case} .rig > .floor{grid-area:floor}
@media (min-width:700px){
  .rig{grid-template-columns:minmax(0,1.1fr) minmax(0,1fr); grid-template-areas:"top top" "sub sub" "next photo" "tunes tunes" "list list" "case case" "floor floor"}
}
/* wide: a wall. The sub dominates the left; the mids stack beside it; the flight case sits on the floor.
   It starts where the dates fit one to a row beside the mark (see .dates below). */
@media (min-width:1240px){
  .rig{width:min(100% - 64px, 1240px); grid-template-columns:minmax(0,1.45fr) minmax(0,1fr);
    grid-template-areas:"top next" "sub photo" "sub tunes" "list list" "case case" "floor floor"}
  .rig > .top{align-content:center}
}

/* a cabinet: square, textured black coating, steel corner protectors laid over its corners, and its name printed
   across the top edge, the heading for what the box holds */
/* each cabinet's standby light, in the top edge past the corner steel: they switch on top to bottom as the page
   loads, breathe while the rig idles, and flash on the beat while the set plays */
.rig > .cab::before{content:''; position:absolute; z-index:2; top:calc(clamp(8px,1.6vw,12px) / 2 - 3px); left:40px;
  width:6px; height:6px; border-radius:50%; background:#4a3c18; box-shadow:0 0 0 2px #0c0b09;
  animation:standby 4.8s ease-in-out infinite, power .7s cubic-bezier(.16,1,.3,1) backwards;
  animation-delay:calc(var(--i,0) * -.6s), calc(var(--i,0) * 110ms + 250ms)}
.rig > .top{--i:0} .rig > .sub{--i:1} .rig > #shows{--i:2} .rig > .photo{--i:3} .rig > .tunes{--i:4}
@keyframes standby{0%,100%{background:#3e3216} 50%{background:#8a6c26; box-shadow:0 0 0 2px #0c0b09, 0 0 7px rgba(201,164,62,.3)}}
@keyframes power{0%{opacity:0} 35%{opacity:1; background:var(--gold-hi); box-shadow:0 0 0 2px #0c0b09, 0 0 12px rgba(226,190,85,.9)} 100%{opacity:1}}
.live .rig > .cab::before{animation:blink var(--beat) steps(1) infinite}
@keyframes blink{0%{background:var(--gold-hi); box-shadow:0 0 0 2px #0c0b09, 0 0 10px rgba(226,190,85,.85)} 35%{background:#6a5420; box-shadow:0 0 0 2px #0c0b09}}
.cab{position:relative; display:grid; align-content:start; padding:clamp(8px,1.6vw,12px);
  background:url(coat.jpg) 0 0 / 160px 160px, #141414;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.06), inset 0 0 0 1px rgba(0,0,0,.7), 0 26px 40px -26px #000}
.cab::after{content:''; position:absolute; inset:0; pointer-events:none;
  background:url(corner-tl.png) left top / 32px 32px no-repeat, url(corner-tr.png) right top / 32px 32px no-repeat,
    url(corner-bl.png) left bottom / 32px 32px no-repeat, url(corner-br.png) right bottom / 32px 32px no-repeat}
.badge{justify-self:center; margin:1px 0 clamp(8px,1.4vw,11px); padding-left:.26em; color:var(--gold); font-size:11px;
  line-height:1.4; font-weight:800; letter-spacing:.26em; text-transform:uppercase; white-space:nowrap}
/* the top box's way into the bio: a small plate under the mark, a control rather than a name. The hit area is 44px. */
.more{position:relative; justify-self:center; display:inline-flex; align-items:center; gap:.6em; min-height:36px;
  margin-top:clamp(8px,1.4vw,11px); padding:0 14px 0 calc(14px + .24em); border:1px solid rgba(236,234,228,.26);
  border-radius:2px; background:rgba(0,0,0,.3); color:var(--bone); text-decoration:none; font-size:11px; font-weight:800;
  letter-spacing:.24em; text-transform:uppercase; transition:color .2s, border-color .2s}
.more::before{content:''; position:absolute; inset:-5px -8px}
.more .chev{width:.62em; height:.78em; background:currentColor; clip-path:polygon(0 0, 45% 0, 100% 50%, 45% 100%, 0 100%, 55% 50%)}
.more:hover,.more:focus-visible{color:var(--gold-hi); border-color:rgba(226,190,85,.55)}

/* a rendered cabinet face, with whatever sits in its throat laid over it */
.face{position:relative; container-type:inline-size; overflow:hidden}
.face-img{width:100%}

/* top: his mark on the flat panel inside a shallow horn */
.top .panel{position:absolute; left:16%; right:16%; top:19%; bottom:19%; display:grid; place-content:center; justify-items:center;
  gap:clamp(4px,1.3cqi,12px); text-align:center}
.mark img{width:min(46cqi,420px); margin-inline:auto}
.tag{font-size:clamp(11px,1.8cqi,13px); font-weight:700; letter-spacing:.22em; text-transform:uppercase; color:var(--dim)}
@container (max-width:480px){.tag{letter-spacing:.08em}}
@container (max-width:300px){.tag{letter-spacing:.03em; font-size:10px}}

/* sub: the Play badge sits on the driver at the back of the throat; the wavefronts leave through the mouth */
.fx{position:absolute; inset:0; width:100%; height:100%}
.glow{opacity:0; transition:opacity .5s}
.wave{fill:none; stroke:var(--gold); stroke-width:2; vector-effect:non-scaling-stroke; opacity:0; transform-box:fill-box; transform-origin:center}
.sub.on .glow{animation:beat var(--beat) cubic-bezier(.2,.8,.3,1) infinite}
.sub.on .wave{animation:front calc(var(--beat) * 3) linear infinite}
.sub.on .wave:nth-of-type(3){animation-delay:calc(var(--beat) * -1)}
.sub.on .wave:nth-of-type(4){animation-delay:calc(var(--beat) * -2)}
@keyframes beat{from{opacity:.95} to{opacity:.22}}
@keyframes front{from{transform:scale(.191,.243); opacity:.85} to{transform:scale(1,1); opacity:0}}

.play{position:absolute; left:50%; top:53%; translate:-50% -50%; width:clamp(52px,15cqi,116px); aspect-ratio:1;
  display:grid; place-items:center; align-content:center; gap:6px; border-radius:50%; border:2px solid var(--gold); color:var(--gold);
  background:radial-gradient(circle at 50% 36%, #231e11, #090807 72%); outline:1px solid rgba(201,164,62,.3); outline-offset:5px;
  box-shadow:0 10px 26px rgba(0,0,0,.75); transition:color .3s, border-color .3s, outline-color .3s, outline-offset .3s}
.play:hover{color:var(--gold-hi); border-color:var(--gold-hi); outline-color:rgba(226,190,85,.6)}
.play:focus-visible{outline:2px solid var(--bone); outline-offset:5px}
.play-glyph{width:28%; aspect-ratio:1; background:currentColor; clip-path:polygon(22% 6%, 94% 50%, 22% 94%)}
.sub.on .play-glyph{clip-path:none; background:linear-gradient(90deg, currentColor 0 34%, transparent 34% 66%, currentColor 66%)}
.play-label{font-size:11px; font-weight:800; letter-spacing:.22em; text-transform:uppercase; padding-left:.22em}
@container (max-width:460px){.play-label{position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap} .play-glyph{width:36%}}
.play.loading{animation:wait 1.1s ease-in-out infinite}
@keyframes wait{50%{outline-offset:11px; outline-color:rgba(201,164,62,.6)}}
/* the cones: a disc of the rendered driver laid over itself, so the real cone moves. While the set plays the sub
   pushes on the kick and wobbles between (half-time 140), and the ring, which is printed on the cone, and the Play
   badge, which sits on its dust cap, move with it. The cannon's driver hits on the snare. */
.cone{position:absolute; inset:0; pointer-events:none; background-size:100% 100%;
  clip-path:circle(var(--cr) at var(--cx) var(--cy)); transform-origin:var(--cx) var(--cy)}
.sub .cone{--cx:50%; --cy:53%; --cr:19cqi; background-image:url(sub-face-700.jpg);
  background-image:image-set(url(sub-face-700.jpg) 1x, url(sub-face-1400.jpg) 2x)}
.cannon .cone{--cx:50%; --cy:50%; --cr:5.6cqi; background-image:url(cannon-face-640.jpg);
  background-image:image-set(url(cannon-face-640.jpg) 1x, url(cannon-face-1280.jpg) 2x)}
.sub.on .cone,.sub.on .play{animation:kick var(--bar) cubic-bezier(.2,.8,.3,1) infinite}
.sub.on .ring{transform-box:view-box; transform-origin:700px 638px; animation:kick var(--bar) cubic-bezier(.2,.8,.3,1) infinite}
.live .cannon .cone,.live .cannon .driver{animation:snare var(--bar) cubic-bezier(.2,.8,.3,1) infinite}
@keyframes kick{
  0%{scale:1; filter:brightness(1)} 4%{scale:1.05; filter:brightness(1.18)} 16%{scale:.99; filter:brightness(.96)}
  26%{scale:1.008} 36%{scale:1; filter:brightness(1)}
  56%{scale:1.014} 62%{scale:.998} 68%{scale:1.012} 74%{scale:.998} 80%{scale:1.012} 86%{scale:.998} 92%,100%{scale:1}}
@keyframes snare{0%,48%{scale:1; filter:brightness(1)} 51%{scale:1.1; filter:brightness(1.25)} 60%{scale:.985} 70%,100%{scale:1; filter:brightness(1)}}
/* the other boxes answer too: the mids' throats catch light on the snare, the top horn on every beat */
.mid .throat::after,.top .face::after{content:''; position:absolute; inset:0; pointer-events:none; opacity:0}
.mid .throat::after{background:radial-gradient(90% 60% at 50% 100%, rgba(201,164,62,.16), transparent 70%)}
.top .face::after{background:radial-gradient(40% 55% at 50% 50%, rgba(201,164,62,.12), transparent 75%)}
.live .mid .throat::after{animation:catch var(--bar) cubic-bezier(.2,.8,.3,1) infinite}
.live .top .face::after{animation:tick var(--beat) cubic-bezier(.2,.8,.3,1) infinite}
@keyframes catch{0%,48%{opacity:0} 51%{opacity:1} 80%,100%{opacity:0}}
@keyframes tick{0%{opacity:.9} 60%,100%{opacity:0}}

/* the ring: a bar for each slice of the set, clockwise from twelve; they light gold as the set plays */
.ring line{stroke:var(--bone); stroke-width:2; stroke-linecap:butt; opacity:.3; vector-effect:non-scaling-stroke;
  transition:stroke .3s, opacity .3s}
.ring line.major{stroke-width:3; opacity:.5}
.ring .rim{fill:none; stroke:var(--bone); stroke-width:1; opacity:.18; vector-effect:non-scaling-stroke}
.ring line.lit{stroke:var(--gold-hi); opacity:.95}
@container (max-width:460px){ .ring line{stroke-width:1.2} .ring line.major{stroke-width:2} }
/* the readout: what is loaded and how far in, like the display on a player */
.readout{display:flex; align-items:center; justify-content:space-between; gap:14px; width:min(100%, 560px); margin:10px auto 0;
  padding:9px 14px; border-radius:2px; background:#040404; box-shadow:inset 0 1px 8px rgba(0,0,0,.95), 0 1px 0 rgba(255,255,255,.05);
  font-size:11.5px; font-weight:700; letter-spacing:.14em; line-height:1.3; text-transform:uppercase; color:var(--dim)}
.readout .now{min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.clock{flex:none; font-variant-numeric:tabular-nums; letter-spacing:.08em; color:var(--faint); transition:color .3s}
.sub.on .clock{color:var(--gold-hi)}
.player{margin-top:10px}
.player iframe{display:block; width:100%; height:20px; border:0}
.player.full iframe{height:166px}
.hint{margin:10px auto 0; max-width:560px; font-size:13.5px; line-height:1.45; color:var(--bone); text-align:center}
.hint:empty{margin:0}

/* mids: content in the throat of a flared horn (a rendered frame, stretched along its walls) */
.horn{display:grid; border-style:solid; border-width:var(--ft,22px) var(--fs,30px) var(--fb,26px);
  border-image-source:url(horn-frame.png); border-image-slice:72 96 84; border-image-repeat:stretch}
.throat{position:relative; background:#060606; padding:clamp(16px,3.4vw,26px);
  box-shadow:inset 0 18px 26px -18px #000, inset 0 0 0 1px #000}
.cab.mid{align-content:stretch; grid-template-rows:auto 1fr}
.mid .horn{height:100%}
/* the list sets the columns and every date shares them (subgrid), so the date column is as wide as the longest date
   ("Oct 15–19") and the events line up; the fixed widths are for browsers without subgrid */
.dates{list-style:none; margin:0; padding:0; display:grid; grid-template-columns:max-content minmax(0,1fr); column-gap:14px}
.dates li{grid-column:1 / -1; display:grid; grid-template-columns:6.6em minmax(0,1fr); grid-template-columns:subgrid; row-gap:2px;
  padding:14px 0; border-top:1px solid rgba(236,234,228,.09)}
.dates li:first-child{border-top:0; padding-top:4px}
.dates time{grid-row:1 / span 3; display:grid; align-content:start; justify-items:start; padding-top:2px; white-space:nowrap; line-height:1}
.dates .mo{font-size:11px; font-weight:800; letter-spacing:.3em; text-transform:uppercase; color:var(--gold); padding-left:.12em}
.dates .dd{margin-top:3px; font-stretch:72%; font-weight:800; font-size:clamp(2rem,5.6vw,2.7rem); letter-spacing:-.02em}
.ev{font-stretch:78%; font-weight:780; font-size:clamp(1.12rem,2.6vw,1.3rem); line-height:1.08; letter-spacing:.02em; text-transform:uppercase}
.at{margin-top:3px; font-size:11px; font-weight:700; letter-spacing:.14em; text-transform:uppercase; color:var(--dim); line-height:1.5}
.tix{justify-self:start; display:inline-flex; align-items:center; gap:.7em; min-height:44px; margin-top:8px; padding:0 14px 0 calc(14px + .2em);
  border-radius:2px; border:1px solid rgba(236,234,228,.28); color:var(--bone); font-size:11px; font-weight:800; letter-spacing:.2em;
  text-transform:uppercase; text-decoration:none; transition:border-color .2s, background-color .2s}
.tix::after{content:''; width:.6em; height:.8em; background:currentColor; transition:translate .25s cubic-bezier(.16,1,.3,1);
  clip-path:polygon(0 0, 45% 0, 100% 50%, 45% 100%, 0 100%, 55% 50%)}
.tix:hover{border-color:rgba(236,234,228,.6); background:rgba(236,234,228,.06)}
.tix:hover::after{translate:3px 0}
/* where the throat is wide enough a date is one row, so on the wall the top row stays level with the mark */
#shows .throat{container-type:inline-size}
/* very narrow throats (a 320 phone): the date sits over the event instead of beside it */
@container (max-width:200px){ .dates{grid-template-columns:minmax(0,1fr)} .dates li{grid-template-columns:1fr; grid-template-columns:subgrid}
  .dates time{grid-row:auto; margin-bottom:4px} }
@container (min-width:330px){
  .dates{grid-template-columns:max-content minmax(0,1fr) auto}
  .dates li{grid-template-columns:6.6em minmax(0,1fr) auto; grid-template-columns:subgrid; align-items:center; padding:11px 0}
  .dates time{grid-row:1 / span 2; align-content:center; padding-top:0}
  .dates .tix{grid-column:3; grid-row:1 / span 2; margin-top:0}
}
#shows .dates li:nth-child(n+4){display:none}
.all-dates{display:inline-flex; align-items:center; min-height:44px; margin-top:4px; color:var(--dim); font-size:11px; font-weight:800;
  letter-spacing:.2em; text-transform:uppercase; text-decoration:underline; text-decoration-color:rgba(236,234,228,.25); text-underline-offset:5px}
.all-dates:hover{color:var(--bone); text-decoration-color:var(--bone)}
.photo .throat{padding:0; min-height:280px; overflow:hidden}
.photo .throat img{position:absolute; inset:0; width:100%; height:100%; object-fit:cover; object-position:92% 60%}  /* he stands right of centre */

/* tunes: a cannon mid horn whose driver is the button; Spotify's player replaces it on request */
/* the button sits on the rendered driver: a play mark and a faint ring at rest (touch has no hover), brighter on hover and focus */
.cannon .driver{position:absolute; left:50%; top:50%; translate:-50% -50%; width:clamp(48px,11.5cqi,96px); aspect-ratio:1;
  display:grid; place-items:center; border-radius:50%; border:2px solid rgba(236,234,228,.32); background:transparent; transition:border-color .3s}
.cannon .driver:hover{border-color:rgba(236,234,228,.8)}
.cannon .driver:focus-visible{border-color:rgba(236,234,228,.8); outline-offset:5px}
.driver-glyph{width:30%; aspect-ratio:1; margin-left:7%; background:var(--bone); opacity:.85; clip-path:polygon(22% 6%, 94% 50%, 22% 94%); transition:opacity .3s}
.cannon .driver:hover .driver-glyph,.cannon .driver:focus-visible .driver-glyph{opacity:1}
.embed-horn{--ft:16px; --fs:22px; --fb:20px}
.embed-horn .throat{padding:0}
.embed{display:block; width:100%; height:352px; border:0; border-radius:12px}
.outs{display:flex; flex-wrap:wrap; justify-content:center; gap:0 20px; margin-top:2px}
.outs a{display:inline-flex; align-items:center; min-height:44px; color:var(--dim); font-size:.92rem; font-weight:600;
  text-decoration:underline; text-decoration-color:rgba(236,234,228,.25); text-underline-offset:4px}
.outs a:hover{color:var(--bone); text-decoration-color:var(--bone)}

/* the case: booking, in a flight case with aluminium trim and steel ball corners (a rendered frame) */
.case{position:relative; display:grid; align-content:center; gap:6px; margin-top:10px; padding:clamp(14px,2.6vw,22px) clamp(16px,3vw,26px);
  border-style:solid; border-width:22px; border-image:url(case-frame.png) 64 / 22px stretch;
  background:url(coat.jpg) 0 0 / 160px 160px, #141413; filter:drop-shadow(0 18px 24px rgba(0,0,0,.7))}
.mail{display:flex; flex-wrap:wrap; align-items:center; gap:10px 16px}
.mail a{font-stretch:78%; font-weight:760; font-size:clamp(1.45rem,5.2vw,2.3rem); line-height:1.1; letter-spacing:-.005em;
  text-decoration:none; overflow-wrap:anywhere}
.mail a:hover{color:var(--gold-hi)}
.mail a{display:inline-flex; align-items:center; min-height:44px}
.copy{min-height:44px; padding:0 16px; border-radius:2px; border:1px solid rgba(236,234,228,.22); background:rgba(0,0,0,.35);
  font-size:.88rem; font-weight:700; color:var(--dim)}
.copy:hover{border-color:rgba(236,234,228,.6); color:var(--bone)}
.who{font-size:.95rem; color:var(--dim)}


/* the floor */
.floor{padding:18px 0 44px}
.floor nav{display:flex; flex-wrap:wrap; justify-content:center; gap:4px 22px}
.floor a{display:inline-flex; align-items:center; min-height:44px; color:var(--faint); font-size:.9rem; font-weight:600; text-decoration:none}
.floor a:hover{color:var(--bone)}

/* ---------------------------------------------------------------- /links: the rack */
.rack{width:min(100% - 24px, 520px); margin:0 auto; padding:clamp(12px,3vh,24px) 0 0; display:grid; gap:18px}
.rack > section{display:grid; gap:6px}
.links-top{padding:10px 10px 16px}
.links-top .horn{--ft:14px; --fs:20px; --fb:18px}
.links-top .throat{padding:0; overflow:hidden}
.links-top .shot{width:100%; aspect-ratio:16/9; object-fit:cover; object-position:50% 38%}
.links-top .mark{margin-top:14px}
.links-top .mark img{width:min(58%,280px)}
.links-top .mark a{display:block; width:fit-content; margin-inline:auto}
.links-top .mark a img{width:min(280px, 58vw)}
/* the photographer's credit, printed small in the photo's corner */
.credit{position:absolute; right:0; bottom:0; padding:22px 10px 8px 34px; font-size:11px; font-weight:700; letter-spacing:.14em;
  line-height:1.3; text-transform:uppercase; color:rgba(236,234,228,.82); pointer-events:none;
  background:radial-gradient(farthest-side at 100% 100%, rgba(0,0,0,.6), transparent)}
/* a group's name on the rail above its units, in line with the LEDs */
.badge.rail{justify-self:start; margin:0 0 0 36px; padding-left:0}
.rack,.rig{
  --plate:
    url(rack-ear.png) left center / 24px 58px no-repeat,
    url(rack-ear-r.png) right center / 24px 58px no-repeat,
    linear-gradient(90deg, #121211 0 24px, #040404 24px 25px, transparent 25px calc(100% - 25px), #040404 calc(100% - 25px) calc(100% - 24px), #121211 calc(100% - 24px)),
    url(rack-plate.jpg) center / 256px 64px, #161615;
  --plate-2u:
    url(rack-ear.png) left top / 24px 58px no-repeat round,
    url(rack-ear-r.png) right top / 24px 58px no-repeat round,
    linear-gradient(90deg, #121211 0 24px, #040404 24px 25px, transparent 25px calc(100% - 25px), #040404 calc(100% - 25px) calc(100% - 24px), #121211 calc(100% - 24px)),
    url(rack-plate.jpg) center / 256px 64px, #161615;
  --plate-shadow:inset 0 1px 0 rgba(255,255,255,.06), inset 0 -1px 0 rgba(0,0,0,.6), 0 8px 14px -10px rgba(0,0,0,.9)}
.unit{position:relative; display:grid; grid-template-columns:20px minmax(0,1fr) auto; align-items:center; column-gap:12px;
  min-height:58px; padding:9px 36px 9px 36px; border-radius:3px; color:var(--bone); text-decoration:none;
  background:var(--plate); box-shadow:var(--plate-shadow)}
.led{grid-row:1 / span 2; justify-self:center; width:7px; height:7px; border-radius:50%; background:#5a4a1e; box-shadow:0 0 0 2px #0c0b09; transition:background .2s, box-shadow .2s}
.unit:hover .led,.unit:focus-visible .led,.unit:active .led{background:var(--gold-hi); box-shadow:0 0 0 2px #0c0b09, 0 0 12px rgba(201,164,62,.9)}
.u-main{font-weight:700; font-size:1rem; line-height:1.25}
.u-sub{grid-column:2; font-size:11.5px; font-weight:600; letter-spacing:.08em; text-transform:uppercase; color:var(--dim); line-height:1.4}
/* a service's mark sits where the LED would, and lights the same way */
.ico{grid-row:1 / span 2; width:20px; height:20px; color:var(--dim); transition:color .2s}
.unit:hover .ico,.unit:focus-visible .ico,.unit:active .ico{color:var(--gold-hi)}
/* the chevron: this goes somewhere */
.go{grid-column:3; grid-row:1 / span 2; width:7px; height:11px; background:var(--faint); transition:background .2s;
  clip-path:polygon(0 0, 40% 0, 100% 50%, 40% 100%, 0 100%, 60% 50%)}
.unit:hover .go,.unit:focus-visible .go{background:var(--bone)}
.units-1,.units-2{display:grid; gap:6px}
/* Spotify, the one to follow: a wider unit with a bigger mark */
.unit.big{grid-template-columns:26px minmax(0,1fr) auto; min-height:66px}
.unit.big .ico{width:26px; height:26px}
.unit.big .u-main{font-size:1.12rem}
/* pads: two to a row, the mark over the name */
.pads{display:grid; grid-template-columns:repeat(2,minmax(0,1fr)); gap:6px}
.unit.pad{grid-template-columns:minmax(0,1fr); justify-items:center; row-gap:7px; min-height:84px; padding:13px 28px 11px; text-align:center}
.unit.pad .ico{grid-row:auto; width:24px; height:24px}
.unit.pad .go{display:none}

/* the rack powers on: each unit's light flashes in turn from the top as the page loads (public.js numbers them),
   and the mailing list's light breathes while it waits, the rack's one press */
.rack .led,.rack .ico{animation:rack-on .8s cubic-bezier(.16,1,.3,1); animation-delay:calc(var(--n,0) * 60ms + 200ms)}
@keyframes rack-on{0%{background:#5a4a1e} 25%{background:var(--gold-hi); color:var(--gold-hi); box-shadow:0 0 0 2px #0c0b09, 0 0 12px rgba(226,190,85,.9)} 100%{}}
.rack .signup:not(.done) .led{animation:rack-on .8s cubic-bezier(.16,1,.3,1) calc(var(--n,0) * 60ms + 200ms), standby 4.8s ease-in-out 1.4s infinite}

/* shows on the rack: the date, the event, where, and a Tickets tag. The next one is the lead: a 2U plate with a big
   date, how soon it is, and a Tickets plate across it. The whole unit is the link. */
.shows{display:grid; gap:6px}
.unit.show{grid-template-columns:20px minmax(0,1fr) auto; grid-template-areas:"led date cta" "led main cta" "led sub cta";
  row-gap:1px; padding-block:10px}
.show .led{grid-area:led}
.s-date{grid-area:date; font-size:11.5px; font-weight:800; letter-spacing:.14em; text-transform:uppercase; line-height:1.4; white-space:nowrap}
.s-date .mo{color:var(--gold); margin-right:.2em}
.show .u-main{grid-area:main; font-stretch:78%; font-weight:780; font-size:1.08rem; letter-spacing:.02em; text-transform:uppercase; line-height:1.15}
.show .u-sub{grid-area:sub}
.s-soon{display:none}
.s-cta{grid-area:cta; display:inline-flex; align-items:center; justify-content:center; gap:.6em; min-height:34px; padding:0 10px 0 calc(10px + .2em);
  border-radius:2px; border:1px solid rgba(236,234,228,.28); font-size:10.5px; font-weight:800; letter-spacing:.2em; text-transform:uppercase;
  white-space:nowrap; transition:border-color .2s, background .2s}
.s-cta::after{content:''; width:.55em; height:.75em; background:currentColor; transition:translate .25s cubic-bezier(.16,1,.3,1);
  clip-path:polygon(0 0, 45% 0, 100% 50%, 45% 100%, 0 100%, 55% 50%)}
.show:hover .s-cta::after,.show:focus-visible .s-cta::after{translate:3px 0}
.show:hover .s-cta,.show:focus-visible .s-cta{border-color:rgba(236,234,228,.65); background:rgba(236,234,228,.06)}
.unit.show.lead{grid-template-areas:"led date soon" ". main main" ". sub sub" ". cta cta"; row-gap:2px; padding:16px 36px 18px;
  background:var(--plate-2u)}
.show.lead .led{align-self:center}
.show.lead .s-date{display:grid; justify-items:start; line-height:1}
.show.lead .s-date .mo{margin:0; font-size:11px; letter-spacing:.3em; padding-left:.12em}
.show.lead .s-date .dd{margin-top:3px; font-stretch:72%; font-weight:800; font-size:clamp(2.2rem,10vw,2.9rem); letter-spacing:-.02em; text-transform:none}
.show.lead .u-main{margin-top:10px; font-size:1.4rem}
.show.lead .s-soon{grid-area:soon; display:block; justify-self:end; font-size:11px; font-weight:800; letter-spacing:.16em;
  text-transform:uppercase; color:var(--bone)}
.show.lead .s-soon:empty{display:none}
.show.lead .s-cta{min-height:50px; margin-top:14px; border-color:var(--bone); background:var(--bone); color:#0e0d0b; font-size:12px; letter-spacing:.24em}
.show.lead:hover .s-cta,.show.lead:focus-visible .s-cta{border-color:#fff; background:#fff}

/* booking: the address is the plate (the whole unit opens mail) and Copy sits on it for phones with no mail app */
.unit.book a.u-main{color:var(--bone); text-decoration:none; overflow-wrap:anywhere}
.unit.book a.u-main::before{content:''; position:absolute; inset:0; border-radius:3px}
.unit.book .copy{grid-column:3; grid-row:1 / span 2; position:relative; z-index:1}
.unit.book:hover a.u-main{color:var(--gold-hi)}
/* the narrowest phones: Copy moves under the address so the address keeps its width */
@media (max-width:360px){
  .unit.book .copy{grid-column:2; grid-row:3; justify-self:start; margin-top:8px}
  .unit.book a.u-main{overflow-wrap:normal}
}

/* the mailing list: a rack panel with a slot for an address (/, /links/, /bio/) */
.signup{position:relative; display:grid; grid-template-columns:20px minmax(0,1fr); align-items:center; gap:10px 12px; margin:0;
  padding:12px 36px 12px 36px; border-radius:3px; background:var(--plate-2u); box-shadow:var(--plate-shadow)}
.signup > p{margin:0}
.signup .led{grid-row:1}
.s-head{display:grid}
.s-head .u-sub{grid-column:auto}
.s-row{grid-column:1 / -1; display:flex; gap:8px}
.s-row input{flex:1 1 auto; min-width:0; min-height:44px; padding:0 12px; border:1px solid rgba(236,234,228,.16); border-radius:2px;
  background:#050505; color:var(--bone); font:inherit; font-size:16px; box-shadow:inset 0 2px 8px rgba(0,0,0,.9)}
.s-row input::placeholder{color:var(--faint)}
.s-row input:focus-visible{outline:2px solid var(--bone); outline-offset:2px}
.s-row button{flex:none; min-height:44px; padding:0 18px; border:1px solid rgba(236,234,228,.3); border-radius:2px;
  background:rgba(0,0,0,.35); font-size:.9rem; font-weight:700}
.s-row button:hover{border-color:rgba(236,234,228,.65)}
.s-row button:disabled{opacity:.55; cursor:default}
.rack .s-row button{border-color:var(--gold); background:var(--gold); color:#100e08; font-weight:800}
.rack .s-row button:hover{border-color:var(--gold-hi); background:var(--gold-hi)}
.s-note{grid-column:1 / -1; font-size:13px; color:var(--dim)}
.s-note:empty{position:absolute}
.signup.done .led{background:var(--gold-hi); box-shadow:0 0 0 2px #0c0b09, 0 0 12px rgba(201,164,62,.9)}
.signup.done .s-row{display:none}
.signup.done .s-note{color:var(--bone)}
.hp{position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden}
/* on the main page it runs the full width of the rig, name on the left and the slot on the right */
@media (min-width:700px){
  .rig .signup{grid-template-columns:20px auto minmax(0,1fr); padding-block:14px}
  .rig .s-row{grid-column:auto; width:min(100%, 520px); justify-self:end}
  .rig .s-note{grid-column:2 / -1}
  .rig .signup.done .s-note{grid-column:3; justify-self:end}
}

/* /bio/: a taller photo, and the words in a horn */
.links-top .shot.tall{aspect-ratio:4/5; object-position:50% 40%}
.words .throat p{margin:0 0 12px; color:#DAD7CF; line-height:1.62}
.words .throat p:last-child{margin:0}
.units-2{grid-template-columns:repeat(auto-fit,minmax(210px,1fr))}

/* ---------------------------------------------------------------- motion and print */
@media (prefers-reduced-motion:reduce){
  .rack .led,.rack .ico,.rack .signup .led{animation:none}
  .sub.on .glow{animation:none; opacity:.6}
  .sub.on .wave,.play.loading{animation:none}
  .beam,.sub.on .cone,.sub.on .play,.sub.on .ring,.live .cannon .cone,.live .cannon .driver,
  .live .mid .throat::after,.live .top .face::after,.live .beam::after{animation:none}
  .rig > .cab::before{animation:none; background:#6a5420}
  .live .rig > .cab::before{animation:none; background:var(--gold-hi)}
  .live .beam::after{opacity:.6}
  *{transition:none !important}
}
@media print{
  body{background:#fff; color:#111}
  .face,.player,.tunes,.links-top .shot,.room{display:none}
}
