:root{
  --peat:#120E1F; --heather:#B47BD8; --whin:#F5C542; --bracken:#E8556B;
  --bone:#F0EBE1; --dim:rgba(240,235,225,.55); --faint:rgba(240,235,225,.16);
  --hair:rgba(240,235,225,.08); --card:rgba(23,22,43,.55);
  --display:'Anton','Haettenschweiler','Impact',sans-serif;
  --body:'IBM Plex Sans','Segoe UI',system-ui,-apple-system,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,Menlo,monospace;
}
*{box-sizing:border-box;-webkit-tap-highlight-color:transparent}
html,body{margin:0;padding:0;overflow-x:hidden}
body{
  font-family:var(--body);color:var(--bone);background:var(--peat);
  background-image:linear-gradient(178deg,#3D1F5C 0%,#2A1745 28%,#1A1030 58%,#120E1F 100%);
  background-attachment:fixed;min-height:100vh;font-size:15px;line-height:1.45;
  padding-bottom:calc(48px + env(safe-area-inset-bottom));
}
/* manipulation kills the 300ms tap delay and double-tap zoom; the hover rule is gated
   so it never sticks on a touchscreen, where :hover latches until you tap elsewhere */
button{font-family:inherit;color:inherit;touch-action:manipulation}
button:active,a:active{opacity:.85}
@media (hover:hover){button:hover{filter:brightness(1.08)}}
input{font-family:inherit}

/* This is a phone app. On anything wider, hold it to a phone's width and centre it
   rather than letting the tile grid and day buttons stretch across a monitor. */
.mast,.switch,main,.foot{max-width:600px;margin-left:auto;margin-right:auto}

/* ---------- masthead ---------- */
/* env(safe-area-inset-top) keeps the kicker clear of a notch or Dynamic Island —
   viewport-fit=cover (index.html) lets content draw right under them otherwise.
   This is the reason the "Unofficial" tag lives in the kicker rather than its own
   bar above the header: a bar spanning the very top edge sits exactly where a
   notch clips it, where the padded header does not. */
.mast{padding:calc(20px + env(safe-area-inset-top)) 18px 14px;
  border-bottom:1px solid var(--faint);position:relative}

/* the logo sits to the left of the day heading, sized to match its two-line height —
   the mark's own height clamp mirrors the h1 font-size clamp times line-height times
   two lines, so top and bottom line up with "WEDNESDAY" and the date beneath it
   without the two elements needing to measure each other */
.headrow{display:flex;align-items:flex-start;gap:12px;margin-top:8px}
.brand{display:block;flex:none;border:0;background:none;padding:0;cursor:pointer;line-height:0}
.brand:focus-visible{outline:2px solid var(--heather);outline-offset:3px;border-radius:18%}
.brandmark{width:clamp(48px,14.35vw,74px);height:clamp(48px,14.35vw,74px);
  border-radius:18%;display:block}

/* home-screen shortcut, top-right of the day heading — a labelled pill rather than
   an icon on its own, because a bare "+" doesn't say what it does. Hidden by JS
   the moment the page is already running from that shortcut, so it only ever
   offers something useful to tap. */
.a2hs{flex:none;margin-left:auto;align-self:flex-start;display:inline-flex;align-items:center;
  gap:5px;padding:7px 11px;border-radius:99px;border:1px solid var(--faint);
  background:transparent;color:var(--dim);font-family:inherit;font-size:10.5px;
  font-weight:600;letter-spacing:.04em;text-transform:uppercase;line-height:1.1;cursor:pointer}
.a2hsicon{font-size:13px;line-height:1}
.a2hs:hover,.a2hs:focus-visible{color:var(--heather);border-color:var(--heather)}
.a2hs:focus-visible{outline:2px solid var(--heather);outline-offset:2px}
/* an author display: rule always beats the browser's [hidden]{display:none} default,
   whichever came first — so hiding this via JS needs its own rule, same as .scrim does */
.a2hs[hidden]{display:none}

/* the stats line is short and the right of that row is dead space, so the report
   and support buttons sit there — above the back half of the day switch, where a
   thumb already is. Report comes first: fixing something wrong outranks a tip. */
.statrow{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;
  gap:8px 12px;margin-top:12px}
.statrow .statline{margin-top:0;min-width:0}
.statbtns{display:flex;align-items:center;gap:8px;flex:none}
.statbtns .kofi{margin:0}

.kofi{display:inline-flex;align-items:center;gap:7px;margin:6px 0 2px;
  padding:8px 12px;border-radius:99px;text-decoration:none;font-size:11px;font-weight:600;
  letter-spacing:.05em;color:var(--whin);border:1px solid rgba(245,197,66,.42);
  background:rgba(245,197,66,.1);line-height:1.1;transition:background .15s,border-color .15s}
.kofi:hover,.kofi:focus-visible{background:rgba(245,197,66,.2);border-color:rgba(245,197,66,.75)}
.kofi:focus-visible{outline:2px solid var(--whin);outline-offset:2px}
/* a pint glass rather than a coffee cup: straight sides, and a line for the head */
.cup{width:9px;height:12px;flex:none;border:1.5px solid var(--whin);border-top:0;
  border-radius:1px 1px 3px 3px;position:relative}
.cup:after{content:"";position:absolute;left:0;right:0;top:2.5px;height:1.5px;
  background:var(--whin)}
@media (max-width:360px){.kofi .cup{display:none}.kofi{font-size:10px;padding:7px 10px}}

/* A link, deliberately not a Spotify embed. An embed loads third-party script and
   cookies, which breaks "nothing sent anywhere", and it is a dead grey box with no
   signal — which is most of a weekend in a field. This costs nothing until tapped. */
.plink{display:inline-flex;align-items:center;gap:8px;margin:6px 0 2px;
  padding:8px 12px;border-radius:99px;text-decoration:none;font-size:11px;font-weight:600;
  letter-spacing:.05em;color:var(--heather);border:1px solid rgba(180,123,216,.42);
  background:rgba(180,123,216,.1);line-height:1.1;transition:background .15s,border-color .15s}
.plink:hover,.plink:focus-visible{background:rgba(180,123,216,.2);border-color:rgba(180,123,216,.75)}
.plink:focus-visible{outline:2px solid var(--heather);outline-offset:2px}
.ptri{width:0;height:0;flex:none;border-left:8px solid var(--heather);
  border-top:5px solid transparent;border-bottom:5px solid transparent}

.kicker{font-size:10px;letter-spacing:.26em;text-transform:uppercase;color:var(--heather);font-weight:600}
.lastnight{color:var(--whin);letter-spacing:.26em}

/* a second, plainer affiliation line, with the ask built in rather than a bare
   statement — this is also why there's a report route right in the header, not
   just the footer or a set's own sheet */
.notrun{margin:10px 0 0;font-size:11px;font-style:italic;color:var(--dim)}

/* a quieter outline next to the filled-in Support pill, so the pair still reads
   report-first, tip-second rather than as two equal calls to action */
.reporterr{flex:none;display:inline-flex;align-items:center;font-family:inherit;
  font-size:10.5px;letter-spacing:.04em;font-weight:600;color:var(--dim);
  background:transparent;border:1px solid var(--faint);border-radius:99px;
  padding:7px 11px;line-height:1.1;text-decoration:none;cursor:pointer;
  transition:color .15s,border-color .15s}
.reporterr:hover,.reporterr:focus-visible{color:var(--heather);border-color:var(--heather)}
.reporterr:focus-visible{outline:2px solid var(--heather);outline-offset:2px}
.mast h1{font-family:var(--display);font-weight:400;font-size:clamp(26px,7.8vw,40px);
  line-height:.92;margin:0;letter-spacing:.01em;flex:1;min-width:0}
.mast h1 em{font-style:normal;color:var(--whin)}
.mast h1 sup{font-size:.44em;letter-spacing:0;position:relative;top:-.35em}
.statline{font-family:var(--mono);font-size:12px;color:var(--dim);margin-top:12px;font-variant-numeric:tabular-nums}
.statline b{color:var(--bone);font-weight:500}

.dayswitch{display:flex;gap:5px;margin-top:14px}
.daybtn{flex:1;position:relative;padding:9px 2px 8px;font-size:11px;font-weight:600;letter-spacing:.07em;
  text-transform:uppercase;border-radius:3px;cursor:pointer;color:var(--dim);display:flex;
  flex-direction:column;align-items:center;gap:2px;
  background:transparent;border:1px solid var(--faint);transition:color .15s,background .15s,border-color .15s}
.dayno{font-family:var(--mono);font-size:13px;letter-spacing:0;font-weight:500;line-height:1}
.daybtn[aria-pressed="true"]{color:var(--peat);background:var(--bone);border-color:var(--bone)}
.daybtn:focus-visible{outline:2px solid var(--whin);outline-offset:2px}
.daydot{position:absolute;top:-6px;right:-4px;min-width:16px;height:16px;border-radius:99px;
  font-family:var(--mono);font-size:9.5px;line-height:16px;letter-spacing:0;
  background:var(--bracken);color:#fff;display:none}
.daydot[data-on="true"]{display:block}

/* ---------- tabs ---------- */
.switch{display:flex;gap:5px;padding:11px 14px;position:sticky;top:0;z-index:40;
  background:linear-gradient(#241D3B,rgba(36,29,59,.95));backdrop-filter:blur(8px);
  border-bottom:1px solid var(--faint)}
.switch button{flex:1;font-size:11px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;
  padding:11px 2px;color:var(--dim);background:transparent;border:1px solid var(--faint);
  border-radius:3px;cursor:pointer;transition:color .15s,background .15s,border-color .15s}
.switch button[aria-selected="true"]{color:var(--peat);background:var(--whin);border-color:var(--whin)}
.switch button:focus-visible{outline:2px solid var(--heather);outline-offset:2px}
.switch .badge{margin-left:3px;font-family:var(--mono);font-size:10px;opacity:.85}

.panel{padding:18px}
.panel[hidden]{display:none}

.label{font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--heather);
  font-weight:600;margin:0 0 10px;display:flex;align-items:center;gap:10px}
.label:after{content:"";flex:1;height:1px;background:var(--faint)}
.label.spaced{margin-top:28px}
.hint{font-size:11.5px;color:var(--dim);margin:0 0 14px}
.hint.mt{margin:14px 0 0}

.fx{position:fixed;inset:0;z-index:55;pointer-events:none;opacity:0;transition:opacity .5s}
.fx.on{opacity:1}

/* ---------- countdown ---------- */
.countdown{display:flex;align-items:center;gap:14px;border:1px solid var(--faint);border-radius:3px;
  padding:14px 16px;margin-bottom:16px;background:linear-gradient(120deg,rgba(180,123,216,.16),rgba(180,123,216,.04))}
.cdn{font-family:var(--display);font-size:44px;line-height:.85;color:var(--whin)}
.cdl{font-size:12.5px;color:var(--dim);line-height:1.45}
.cdl b{color:var(--bone);font-weight:600}

/* ---------- alert ---------- */
.alert{display:flex;align-items:flex-start;gap:10px;padding:12px 12px 12px 13px;margin-bottom:14px;
  border:1px solid rgba(245,197,66,.45);background:rgba(245,197,66,.1);border-radius:3px;font-size:13.5px}
.alerticon{flex:none;width:18px;height:18px;border-radius:50%;background:var(--whin);color:var(--peat);
  font-weight:700;font-size:12px;text-align:center;line-height:18px}
.alerttext{flex:1;min-width:0}
.alertx{flex:none;border:0;background:none;color:var(--dim);font-size:20px;line-height:1;cursor:pointer;padding:0 2px}
.alertx:focus-visible{outline:2px solid var(--whin);outline-offset:2px}
/* offline is information, not a warning — heather rather than the amber of an alert */
.alert.offline{border-color:rgba(180,123,216,.45);background:rgba(180,123,216,.1)}
.alert.offline .alerticon{background:var(--heather);color:#fff;font-size:9px}

/* ---------- weather ---------- */
.wx{border:1px solid var(--faint);border-radius:3px;padding:14px 14px 12px;margin-bottom:16px;
  background:linear-gradient(150deg,rgba(240,235,225,.05),rgba(240,235,225,.01))}
.wx.wet{background:linear-gradient(150deg,rgba(111,160,168,.2),rgba(111,160,168,.05));
  border-color:rgba(111,160,168,.4)}
.wxtop{display:flex;justify-content:space-between;align-items:flex-start;gap:12px}
.wxtemp{font-family:var(--display);font-weight:400;font-size:34px;line-height:.9;letter-spacing:.01em}
.wxdesc{display:block;font-size:12.5px;color:var(--bone);margin-top:4px}
.wxsub{font-family:var(--mono);font-size:10.5px;color:var(--dim);text-align:right;line-height:1.5;flex:none}
.wxverdict{font-size:13px;color:var(--bone);margin-top:10px;padding-top:10px;border-top:1px solid var(--hair)}
.wxhours,.wxdays{display:flex;gap:4px;margin-top:12px}
.wxh{flex:1;display:flex;flex-direction:column;align-items:center;gap:3px;min-width:0}
.wxhp{font-family:var(--mono);font-size:9px;color:var(--dim);font-variant-numeric:tabular-nums}
.wxbar{width:100%;height:30px;background:rgba(240,235,225,.08);border-radius:2px;
  display:flex;align-items:flex-end;overflow:hidden}
.wxbar i{width:100%;background:#6FA0A8;border-radius:2px;min-height:2px}
.wxht{font-family:var(--mono);font-size:10px;color:var(--bone);font-variant-numeric:tabular-nums}
.wxhh{font-family:var(--mono);font-size:9px;color:var(--dim);font-variant-numeric:tabular-nums}
.wxd{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:3px;padding:8px 2px;
  border:1px solid var(--faint);border-radius:3px;background:transparent;cursor:pointer}
.wxd[data-on="true"]{border-color:var(--whin);background:rgba(245,197,66,.12)}
/* days past the model's horizon show dashes — fade them so they read as absent, not cold */
.wxd[data-known="false"]{opacity:.5}
.wxd:focus-visible{outline:2px solid var(--whin);outline-offset:2px}
.wxdl{font-size:9.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--dim);font-weight:600}
.wxdt{font-family:var(--mono);font-size:14px;color:var(--bone)}
.wxdp{font-family:var(--mono);font-size:9.5px;color:#6FA0A8}
/* same low/moderate/high bands as uvBand() in app.js, so colour and the "Pack
   sunscreen" verdict text always agree with each other */
.wxdu{font-family:var(--mono);font-size:9px;color:var(--dim)}
.wxdu[data-band="moderate"]{color:var(--whin)}
.wxdu[data-band="high"],.wxdu[data-band="very high"]{color:var(--bracken)}
.wxcredit{font-size:9.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--dim);margin-top:11px}

/* ---------- hero ---------- */
.hero{border:1px solid rgba(245,197,66,.4);border-radius:3px;padding:16px;
  background:linear-gradient(140deg,rgba(245,197,66,.16),rgba(245,197,66,.03));
  box-shadow:0 4px 20px rgba(0,0,0,.18)}
.hero .stage{font-size:10px;letter-spacing:.2em;text-transform:uppercase;color:var(--whin);font-weight:600}
.hero .act{font-family:var(--display);font-weight:400;font-size:clamp(26px,7.5vw,38px);line-height:.98;margin:6px 0 8px}
.hero .when{font-family:var(--mono);font-size:12.5px;color:var(--dim);font-variant-numeric:tabular-nums}
.bar{height:3px;background:var(--faint);margin-top:12px;border-radius:2px;overflow:hidden}
.bar i{display:block;height:100%;background:var(--whin);border-radius:2px;transition:width .4s}
.hero.ending{border-color:rgba(232,85,107,.55);
  background:linear-gradient(140deg,rgba(232,85,107,.14),rgba(232,85,107,.02))}
.hero.ending .bar i{background:var(--bracken)}

/* ---------- day at a glance ---------- */
.glances{display:grid;gap:8px}
.glance{display:block;width:100%;text-align:left;border:1px solid var(--faint);border-left:3px solid var(--c);
  border-radius:3px;background:var(--card);padding:11px 13px;cursor:pointer}
.glance:focus-visible{outline:2px solid var(--heather);outline-offset:2px}
.gs{display:block;font-size:9.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--c);font-weight:600}
.ga{display:block;font-size:16px;font-weight:600;line-height:1.2;margin-top:3px}
.gt{display:block;font-family:var(--mono);font-size:11px;color:var(--dim);margin-top:3px}

/* ---------- generic rows ---------- */
.list{display:grid;gap:1px;background:var(--faint);border:1px solid var(--faint);border-radius:3px;overflow:hidden}
.rowitem{display:flex;align-items:stretch;background:var(--card)}
.rowmain{flex:1;display:grid;grid-template-columns:62px 1fr;gap:12px;align-items:center;
  text-align:left;border:0;background:none;padding:11px 0 11px 13px;cursor:pointer;min-width:0}
.rowmain:focus-visible{outline:2px solid var(--heather);outline-offset:-2px}
.rowtext{display:block;min-width:0}
.rowitem .t{font-family:var(--mono);font-size:12px;color:var(--whin);font-variant-numeric:tabular-nums}
.rowitem .n{display:block;font-weight:500;font-size:14.5px;line-height:1.25}
.rowitem .s{display:block;font-size:10.5px;letter-spacing:.11em;text-transform:uppercase;color:var(--dim);margin-top:2px}
.rowitem[data-starred="true"] .heart{color:var(--bracken)}
.fav{border:0;background:none;cursor:pointer;padding:0 14px;display:flex;align-items:center;font:inherit;flex:none}
.fav:focus-visible{outline:2px solid var(--bracken);outline-offset:-2px}
.heart{font-size:17px;color:var(--faint);line-height:1;transition:color .15s,transform .15s}
[data-starred="true"] .heart{color:var(--bracken);transform:scale(1.1)}
.infodot{color:var(--heather);font-size:11px;margin-left:5px;opacity:.8}

.empty{border:1px dashed var(--faint);border-radius:3px;padding:22px 16px;color:var(--dim);font-size:14px}
.empty b{display:block;color:var(--bone);font-weight:600;margin-bottom:4px}

.note{border-left:3px solid var(--bracken);background:rgba(232,85,107,.12);padding:11px 13px;
  border-radius:0 3px 3px 0;margin-bottom:8px;font-size:13.5px}
.note b{color:var(--bracken)}
.note .fix{display:block;margin-top:5px;color:var(--dim);font-size:12.5px}
.note.gap{border-left-color:var(--heather);background:rgba(180,123,216,.12)}
.note.gap b{color:var(--heather)}

/* ---------- segmented control ---------- */
.seg{display:flex;gap:5px;margin-bottom:14px}
.seg button{flex:1;padding:10px 4px;font-size:11.5px;font-weight:600;letter-spacing:.05em;
  text-transform:uppercase;border-radius:3px;cursor:pointer;color:var(--dim);
  background:transparent;border:1px solid var(--faint)}
.seg button[aria-pressed="true"]{color:var(--peat);background:var(--bone);border-color:var(--bone)}
.seg button:focus-visible{outline:2px solid var(--whin);outline-offset:2px}

/* ---------- departure board ---------- */
/* Modelled on a station departure board: a time spine down the left, everything
   grouped under the minute it starts. The day runs downwards and you scroll it,
   which is what lets the slider go — and with it, the last sideways scroll. */
.bhead{display:flex;align-items:baseline;justify-content:space-between;gap:10px;
  margin:20px 0 0;padding:0 1px 6px;border-bottom:1px solid var(--faint)}
.bhead:first-child{margin-top:0}
.bhl{font-family:var(--mono);font-size:12.5px;font-weight:500;color:var(--whin);
  letter-spacing:.08em;font-variant-numeric:tabular-nums}
.bhr{font-size:10px;color:var(--dim);flex:none}
.brows{display:grid;gap:1px;background:var(--faint);border:1px solid var(--faint);
  border-top:0;border-radius:0 0 3px 3px;overflow:hidden}
.brow{display:flex;align-items:stretch;background:var(--card);border-left:3px solid var(--c)}
.bmain{flex:1;min-width:0;display:flex;gap:11px;border:0;background:none;cursor:pointer;
  text-align:left;padding:10px 2px 10px 11px}
.bmain:focus-visible{outline:2px solid var(--heather);outline-offset:-2px}
.bt{flex:none;font-family:var(--mono);font-size:13px;color:var(--bone);line-height:1.35;
  font-variant-numeric:tabular-nums}
.brow.later .bt{color:var(--dim)}
.btext{flex:1;min-width:0}
.bs{display:block;font-size:9px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--c);font-weight:600;line-height:1.3}
.bn{display:block;font-size:14px;font-weight:500;line-height:1.25;margin-top:2px;overflow-wrap:anywhere}
.bl{display:block;font-family:var(--mono);font-size:10.5px;color:var(--dim);margin-top:3px;
  font-variant-numeric:tabular-nums}
.brow .fav{padding:0 9px}
.bgo{flex:none;border:0;background:none;color:var(--dim);font-size:20px;line-height:1;
  padding:0 12px;cursor:pointer}
.bgo:focus-visible{outline:2px solid var(--heather);outline-offset:-2px}

/* ---------- stage list ---------- */
/* stretch, not fixed heights, so the ALL chip always matches whatever height
   the input actually renders at, font rendering differences and all */
.searchwrap{display:flex;gap:8px;align-items:stretch;margin-bottom:14px}
.searchwrap input{flex:1;min-width:0;padding:12px 13px;font-size:15px;color:var(--bone);
  background:rgba(240,235,225,.06);border:1px solid var(--faint);border-radius:3px}

/* a single filter chip rather than a second row of buttons — press it to widen
   the Acts search from this day to the whole festival */
.bandall{flex:none;padding:0 14px;border-radius:3px;border:1px solid var(--faint);
  background:transparent;color:var(--dim);font-family:inherit;font-size:12px;font-weight:600;
  letter-spacing:.06em;cursor:pointer}
.bandall[aria-pressed="true"]{color:var(--peat);background:var(--bone);border-color:var(--bone)}
.bandall:focus-visible{outline:2px solid var(--whin);outline-offset:2px}
.searchwrap input::placeholder{color:var(--dim)}
.searchwrap input:focus{outline:2px solid var(--whin);outline-offset:-1px}
.grouphead{font-size:10px;letter-spacing:.22em;text-transform:uppercase;color:var(--dim);
  font-weight:600;margin:22px 0 8px}
.grouphead:first-child{margin-top:0}
.stlist{display:grid;gap:1px;background:var(--faint);border:1px solid var(--faint);border-radius:3px;overflow:hidden}
.strow{display:block;width:100%;text-align:left;border:0;border-left:3px solid var(--c);
  background:var(--card);padding:11px 13px;cursor:pointer}
.strow:focus-visible{outline:2px solid var(--heather);outline-offset:-2px}
.stname{display:flex;align-items:center;gap:8px;font-size:15px;font-weight:600;line-height:1.25}
.stsaved{font-family:var(--mono);font-size:10.5px;color:var(--bracken);font-weight:400}
.stmeta{display:block;font-family:var(--mono);font-size:11px;color:var(--dim);margin-top:3px;
  font-variant-numeric:tabular-nums}
.ston{display:block;font-size:11.5px;color:var(--c);margin-top:4px}

/* A sub-screen needs an obvious way out. Full-width, sticky under the tabs, and a
   real 44px target — the old bare text link was too small to find on a phone. */
.backbar{position:sticky;top:var(--tabh,44px);z-index:30;margin:-18px -18px 16px;
  padding:9px 18px;background:#241D3B;border-bottom:1px solid var(--faint)}
.back{display:flex;align-items:center;gap:9px;width:100%;min-height:44px;
  padding:0 13px;border:1px solid var(--faint);border-radius:3px;background:var(--card);
  color:var(--bone);font-size:13px;font-weight:600;cursor:pointer;letter-spacing:.02em}
.backchev{font-size:21px;line-height:1;color:var(--heather);flex:none;margin-top:-2px}
.backwhere{margin-left:auto;font-size:10px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--dim);font-weight:600;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.back:focus-visible{outline:2px solid var(--heather);outline-offset:2px}
.stagehead{border-left:3px solid var(--c);padding-left:11px;margin-bottom:16px}
.stagehead h3{font-family:var(--display);font-weight:400;font-size:clamp(22px,6.4vw,30px);
  margin:0;line-height:1;letter-spacing:.01em}
.stagehead .meta{font-family:var(--mono);font-size:11.5px;color:var(--dim);margin-top:6px;
  font-variant-numeric:tabular-nums}

/* ---------- timeline ---------- */
/* Blocks stack rather than being pinned to an absolute clock, so the empty hours a
   stage is dark cost nothing. Each block is still sized by its own length. */
.tl{margin:0 0 8px;display:flex;flex-direction:column;gap:2px}
.tlblk{border-radius:0 3px 3px 0;display:flex;
  align-items:stretch;overflow:hidden;transition:box-shadow .3s}

.tlgap{display:flex;align-items:center;gap:9px;padding:3px 0 3px 12px;
  font-family:var(--mono);font-size:10px;color:var(--dim);font-variant-numeric:tabular-nums}
.tlgap:before,.tlgap:after{content:"";height:1px;background:var(--hair)}
.tlgap:before{width:14px;flex:none}
.tlgap:after{flex:1}

.tlearlier{display:flex;align-items:center;gap:9px;width:100%;min-height:42px;padding:0 13px;
  margin-bottom:2px;border:1px dashed var(--faint);border-radius:3px;background:none;
  color:var(--dim);font-size:12px;font-weight:600;cursor:pointer;letter-spacing:.02em}
.tlearlier .tlchev{font-size:9px;transition:transform .2s}
.tlearlier.open .tlchev{transform:rotate(180deg)}
.tlearlier:focus-visible{outline:2px solid var(--heather);outline-offset:2px}
.tlpast{display:flex;flex-direction:column;gap:2px;margin-bottom:2px}
.tlpast[hidden]{display:none}
.tlmain{flex:1;text-align:left;border:0;background:none;padding:6px 4px 6px 9px;cursor:pointer;min-width:0}
.tlmain:focus-visible{outline:2px solid var(--bone);outline-offset:-2px}
.tlt{display:block;font-family:var(--mono);font-size:10px;color:var(--dim);font-variant-numeric:tabular-nums}
.tln{display:block;font-size:13.5px;font-weight:500;line-height:1.2;margin-top:1px;overflow-wrap:anywhere}
.tlblk .fav{padding:0 10px}
.tlblk.past{opacity:.42}
.tlblk.live{box-shadow:inset 0 0 0 1px var(--whin)}
.tlblk.approx .tlt{font-style:italic}
.tlblk.flash{box-shadow:0 0 0 2px var(--whin)}

/* ---------- A–Z ---------- */
.azlist{display:grid;gap:1px;background:var(--faint);border:1px solid var(--faint);border-radius:3px;overflow:hidden}
.azhead{background:#1B1430;font-family:var(--mono);font-size:11px;color:var(--whin);padding:6px 13px;
  letter-spacing:.1em;position:sticky;top:var(--tabh,58px);z-index:5}
.azrow{display:flex;align-items:stretch;background:var(--card)}
.azmain{flex:1;text-align:left;border:0;background:none;padding:10px 0 10px 13px;cursor:pointer;min-width:0}
.azmain:focus-visible{outline:2px solid var(--heather);outline-offset:-2px}
.azn{display:block;font-size:14.5px;font-weight:500;line-height:1.25;overflow-wrap:anywhere}
.azmeta{display:block;font-family:var(--mono);font-size:11px;color:var(--dim);margin-top:2px;
  font-variant-numeric:tabular-nums}
.azrow[data-past="true"]{opacity:.45}
.azday{color:var(--whin)!important}
.azgo{flex:none;display:flex;align-items:center;padding:0 16px;color:var(--dim);font-size:18px}

/* ---------- actions ---------- */
.actions{display:grid;gap:8px;margin-top:18px}
.action{padding:13px;font-size:13px;font-weight:600;letter-spacing:.05em;text-transform:uppercase;
  border-radius:3px;cursor:pointer;color:var(--peat);background:var(--whin);border:1px solid var(--whin)}
.action.ghost{color:var(--dim);background:transparent;border-color:var(--faint)}
.action:focus-visible{outline:2px solid var(--heather);outline-offset:2px}

/* ---------- sheet ---------- */
.scrim{position:fixed;inset:0;z-index:60;background:rgba(9,7,16,.72);display:flex;align-items:flex-end}
.scrim[hidden]{display:none}
.sheet{width:100%;max-height:88vh;overflow-y:auto;background:#1B1430;border-top:2px solid var(--whin);
  border-radius:12px 12px 0 0;padding:22px 18px calc(22px + env(safe-area-inset-bottom))}
.sstage{font-size:10px;letter-spacing:.2em;text-transform:uppercase;font-weight:600}
.sheet h3{font-family:var(--display);font-weight:400;font-size:clamp(24px,7vw,34px);line-height:1.02;
  margin:7px 0 8px;letter-spacing:.01em}
.swhen{font-family:var(--mono);font-size:12px;color:var(--dim);font-variant-numeric:tabular-nums}
.sclash{margin-top:10px;font-size:12.5px;color:var(--bracken);border-left:3px solid var(--bracken);
  padding-left:10px}
.sbody{margin:16px 0 20px;font-size:14.5px;line-height:1.55}
.sbody.none{color:var(--dim);font-size:13.5px}
.sheetacts{display:grid;gap:8px}
.primary,.spot,.ghostbtn{padding:13px;font-size:13px;font-weight:600;letter-spacing:.05em;
  text-transform:uppercase;border-radius:3px;cursor:pointer;text-align:center;text-decoration:none}
.primary{color:var(--peat);background:var(--whin);border:1px solid var(--whin)}
.primary[data-starred="true"]{background:var(--bracken);border-color:var(--bracken);color:#fff}
.spot{color:#1DB954;background:rgba(29,185,84,.12);border:1px solid rgba(29,185,84,.45)}
.ghostbtn{color:var(--dim);background:transparent;border:1px solid var(--faint)}
.sclose{width:100%;margin-top:16px;padding:11px;font-size:12px;letter-spacing:.1em;text-transform:uppercase;
  color:var(--dim);background:none;border:0;cursor:pointer}
.primary:focus-visible,.spot:focus-visible,.ghostbtn:focus-visible,.sclose:focus-visible{
  outline:2px solid var(--heather);outline-offset:2px}

/* a quiet way to flag a wrong time or venue right from the listing that's wrong,
   rather than making someone hunt for a contact address in the footer */
.reportlink{display:block;width:100%;margin-top:12px;padding:0;font:inherit;font-size:11px;
  color:var(--dim);background:none;border:0;cursor:pointer;
  text-align:center;text-decoration:underline;text-decoration-color:var(--faint)}
.reportlink:hover,.reportlink:focus-visible{color:var(--heather);text-decoration-color:var(--heather)}

/* the report form's own field — same visual language as the Acts search box */
.reporttext{width:100%;margin:2px 0 16px;padding:12px 13px;font-family:inherit;font-size:15px;
  color:var(--bone);background:rgba(240,235,225,.06);border:1px solid var(--faint);
  border-radius:3px;resize:vertical}
.reporttext::placeholder{color:var(--dim)}
.reporttext:focus{outline:2px solid var(--whin);outline-offset:-1px}

/* two platforms stacked rather than side by side — nothing here scrolls sideways,
   and stacking is one less thing that can go wrong on a narrow phone */
.a2hsteps{margin-top:16px;display:grid;gap:18px}
.a2hsplat h4{font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--heather);
  font-weight:600;margin:0 0 8px}
.a2hsplat ol{margin:0;padding-left:18px;font-size:13.5px;line-height:1.6;color:var(--bone)}
.a2hsplat li{margin-bottom:4px}
.a2hsplat li:last-child{margin-bottom:0}

/* ---------- footer ---------- */
.foot{padding:26px 18px 40px;border-top:1px solid var(--faint);margin-top:22px;
  font-size:11.5px;color:var(--dim);line-height:1.6}
.foot p{margin:0 0 7px}
.foot a{color:var(--heather);text-decoration:underline;text-decoration-color:rgba(180,123,216,.4)}
.foot a:hover,.foot a:focus-visible{text-decoration-color:var(--heather)}
#offline{color:var(--heather)}
.foot .sig{margin-top:14px;font-size:10px;letter-spacing:.18em;text-transform:uppercase;color:var(--heather)}

@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important;scroll-behavior:auto!important}}
