/* NOCT stylesheet. Split out of index.html so UI work and app logic stop colliding in one file. */
:root{--ink:#0B0B0B;--chalk:#FFFFFF;--d1:rgba(255,255,255,.66);--d2:rgba(255,255,255,.40);
--hair:rgba(255,255,255,.22);--f:'Google Sans','Helvetica Neue',Helvetica,Arial,sans-serif;--pad:20px;
--rule:rgba(255,255,255,.13);--topH:150px}
*{box-sizing:border-box;margin:0;padding:0}
html,body{background:var(--ink);height:100%;min-height:100dvh}
body{font-family:var(--f);color:var(--chalk);-webkit-font-smoothing:antialiased;display:flex;justify-content:center;
 overscroll-behavior:none}
button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;text-align:left}
a{color:inherit}
:focus-visible{outline:1px solid var(--chalk);outline-offset:3px}
.app{position:relative;width:100%;max-width:440px;height:100vh;height:100dvh;min-height:100svh;overflow:hidden;background:var(--ink)}
@media (min-width:520px){.app{border-left:.7px solid rgba(255,255,255,.12);border-right:.7px solid rgba(255,255,255,.12)}}
.sm{font-size:14px;line-height:1.55}
.lnk{font-size:14px;text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:.7px}
.lnk:hover{opacity:.62}

.topscrim{position:absolute;top:0;left:0;right:0;height:calc(var(--topH) + 30px);z-index:21;pointer-events:none;opacity:0;transition:opacity .28s ease;
 backdrop-filter:blur(18px) saturate(.85);-webkit-backdrop-filter:blur(18px) saturate(.85);
 background:linear-gradient(180deg,rgba(11,11,11,.86) 0%,rgba(11,11,11,.7) 56%,rgba(11,11,11,0) 100%);
 -webkit-mask-image:linear-gradient(180deg,#000 0%,#000 60%,transparent 100%);mask-image:linear-gradient(180deg,#000 0%,#000 60%,transparent 100%)}
.topscrim.on{opacity:1}
.botscrim{position:absolute;bottom:0;left:0;right:0;height:calc(156px + env(safe-area-inset-bottom));z-index:19;pointer-events:none;opacity:0;transition:opacity .28s ease;
 backdrop-filter:blur(18px) saturate(.85);-webkit-backdrop-filter:blur(18px) saturate(.85);
 background:linear-gradient(0deg,rgba(11,11,11,.88) 0%,rgba(11,11,11,.72) 54%,rgba(11,11,11,0) 100%);
 -webkit-mask-image:linear-gradient(0deg,#000 0%,#000 58%,transparent 100%);mask-image:linear-gradient(0deg,#000 0%,#000 58%,transparent 100%)}
.botscrim.on{opacity:1}
.top{position:absolute;top:0;left:0;right:0;z-index:22;padding:calc(16px + env(safe-area-inset-top)) var(--pad) 0;pointer-events:none}
.brand{display:flex;justify-content:space-between;width:100%;pointer-events:none}
.bm{font-size:46px;font-weight:700;letter-spacing:-.022em;line-height:.86;pointer-events:auto;cursor:pointer;transition:opacity .16s;padding:0}
.bm:hover{opacity:.62}
.bm:active{opacity:.4}
.ctrl{display:flex;align-items:center;gap:14px;margin-top:16px;pointer-events:auto}
.ctrl button{font-size:16px;display:flex;align-items:center;gap:7px;white-space:nowrap;min-width:0}
.ctrl button i{font-style:normal;font-size:10px;opacity:.55;transform:translateY(1px)}
.ctrl .sep{width:.7px;height:15px;background:var(--hair);flex:none}
.ctrl b{font-weight:400;overflow:hidden;text-overflow:ellipsis}
.ctrl[hidden]{display:none}
/* A single label could not say whether it was the state or the action ("All" — am I seeing all, or will
   tapping give me all?). Both options are shown, and the live one is marked the way every other choice in
   the app is marked: chalk and underlined. */
.seg{display:flex;align-items:center;gap:14px;margin-top:11px;pointer-events:auto}
.seg[hidden]{display:none}
.seg button{font-size:16px;color:var(--d2);white-space:nowrap}
.seg button[aria-pressed="true"]{color:var(--chalk);text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:.7px}
#backRow button{gap:11px}
.vtitle{font-size:29px;font-weight:700;letter-spacing:-.03em;padding:0 var(--pad);margin-bottom:26px}
.view{position:absolute;inset:0}
.view[hidden]{display:none}

#imageView{overflow:hidden;touch-action:pan-y}
.slide{position:absolute;inset:0;opacity:0;transform:scale(1.045);filter:blur(8px) brightness(.5) contrast(1.1);
 transition:opacity .52s cubic-bezier(.4,0,.2,1),transform 1.1s cubic-bezier(.16,.84,.24,1),filter .52s cubic-bezier(.4,0,.2,1)}
.slide.on{opacity:1;transform:scale(1);filter:blur(0) brightness(1) contrast(1)}
.gate{position:absolute;inset:0;z-index:14;pointer-events:none;background:#000;opacity:0}
.gate.flick{animation:flick .36s ease-out}
@keyframes flick{0%{opacity:0}16%{opacity:.62}38%{opacity:.1}56%{opacity:.4}78%{opacity:.06}100%{opacity:0}}
.grain{position:absolute;inset:0;z-index:13;pointer-events:none;opacity:.17;mix-blend-mode:overlay;
 background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='240' height='240'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='240' height='240' filter='url(%23n)'/%3E%3C/svg%3E")}
.tex{position:absolute;inset:0}
.tex::after{content:'';position:absolute;inset:0;background:
 linear-gradient(180deg,rgba(8,8,8,.92) 0%,rgba(8,8,8,.42) 26%,rgba(8,8,8,.5) 48%,rgba(8,8,8,.97) 100%),
 linear-gradient(0deg,rgba(8,8,8,.42),rgba(8,8,8,.42))}
.x1{background:repeating-linear-gradient(90deg,#070707 0 5px,#242424 5px 9px,#949494 9px 10px,#3B3B3B 10px 14px),linear-gradient(180deg,#000,#141414)}
.x2{background-image:radial-gradient(circle,#7E7E7E 1px,transparent 1.3px);background-size:9px 9px;background-color:#0E0E0E}
.x3{background:radial-gradient(115% 62% at 75% 17%,rgba(255,255,255,.36) 0%,rgba(255,255,255,0) 58%),repeating-linear-gradient(0deg,rgba(255,255,255,.06) 0 1px,transparent 1px 6px),#0C0C0C}
.x4{background:repeating-linear-gradient(72deg,#0A0A0A 0 11px,#1F1F1F 11px 22px),repeating-linear-gradient(108deg,rgba(255,255,255,.075) 0 11px,transparent 11px 22px),#0B0B0B}
.x5{background:radial-gradient(60% 40% at 31% 61%,rgba(255,255,255,.44) 0%,rgba(255,255,255,.07) 42%,rgba(255,255,255,0) 71%),linear-gradient(200deg,#1A1A1A,#050505)}
.x6{background:repeating-linear-gradient(90deg,transparent 0 2px,rgba(255,255,255,.17) 2px 3px,transparent 3px 16px),linear-gradient(160deg,#1D1D1D,#060606)}

.caption{position:absolute;left:var(--pad);right:var(--pad);bottom:calc(136px + env(safe-area-inset-bottom));z-index:15}
.caption .idx{color:var(--d1);margin-bottom:12px}
.caption .name{font-size:29px;font-weight:500;letter-spacing:-.032em;line-height:1.08;margin-bottom:11px;
 display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.caption .gen{font-size:15px;margin-bottom:9px}
.caption .meta{color:var(--d1);margin-bottom:18px}
.caption .go{color:var(--chalk);margin-bottom:16px}
.swipe{position:absolute;left:50%;transform:translateX(-50%);bottom:calc(84px + env(safe-area-inset-bottom));z-index:15;display:flex;align-items:center;gap:18px;border:.7px solid var(--hair);padding:9px 18px;color:var(--d1);max-width:calc(100% - var(--pad)*2)}
.swipe span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.swipe button{flex:none}
.swipe button{color:var(--chalk);font-size:14px;line-height:1}
.zone{position:absolute;top:120px;bottom:200px;width:34%;z-index:12}
.zone.l{left:0}.zone.r{right:0}

#listView{overflow-y:auto;padding:calc(var(--topH) + 18px) 0 calc(138px + env(safe-area-inset-bottom));-webkit-overflow-scrolling:touch}
.srcline{padding:0 var(--pad) 20px;font-size:13px;color:var(--d2);line-height:1.5}
.fbar{display:flex;gap:6px;overflow-x:auto;margin-top:13px;pointer-events:auto;scrollbar-width:none;padding-bottom:2px}
.fbar[hidden]{display:none}
.fbar::-webkit-scrollbar{display:none}
.fb{flex:none;font-size:12px;line-height:1;border:.7px solid var(--hair);padding:6px 10px;color:var(--d1);white-space:nowrap;transition:.15s}
.fb:hover{border-color:rgba(255,255,255,.5)}
.fb.on{background:var(--chalk);color:var(--ink);border-color:var(--chalk)}
.fb.plain{border-color:transparent;color:var(--d2);text-decoration:underline;text-underline-offset:3px;padding-left:2px;padding-right:4px}
.dayhead{padding:22px var(--pad) 6px;font-size:13px;color:var(--d2)}
.row{display:grid;grid-template-columns:minmax(0,1fr) 104px;gap:3px 14px;width:100%;padding:14px var(--pad)}
.row:active{background:#141414}
.rt{font-size:13.5px;color:var(--d2);grid-column:1;grid-row:1}
.rn{font-size:19px;font-weight:500;letter-spacing:-.026em;line-height:1.18;grid-column:1;grid-row:2;margin:3px 0 4px;
 display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.rg{font-size:13.5px;grid-column:1;grid-row:3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.rv{font-size:13.5px;color:var(--d1);grid-column:1;grid-row:4;margin-top:1px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* price sits on the name's line so it reads as belonging to the event, not the time */
.rp{font-size:15px;text-align:right;white-space:nowrap;grid-column:2;grid-row:2;align-self:baseline}
.rp.gone{color:var(--d2);font-size:13.5px}
.rs{font-size:12px;color:var(--d2);text-align:right;grid-column:2;grid-row:3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.rgo{font-size:12px;color:var(--d1);text-align:right;white-space:nowrap;grid-column:2;grid-row:4;margin-top:1px}

#savedView,#venuesView,#profileView{overflow-y:auto;padding:calc(var(--topH) + 18px) 0 calc(138px + env(safe-area-inset-bottom))}
.slab{font-size:13px;color:var(--d2);padding:0 var(--pad);margin-bottom:14px}
.blk{margin-bottom:44px}
.frow{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:18px;align-items:baseline;width:100%;padding:14px var(--pad)}
.frow:active{background:#141414}
.fn{font-size:19px;font-weight:500;letter-spacing:-.026em;line-height:1.2}
.fm{font-size:13.5px;color:var(--d1);margin-top:5px}
.tg{font-size:14px;color:var(--d2);white-space:nowrap}
.tg[aria-pressed="true"]{color:var(--chalk)}

.bottom{position:absolute;left:0;right:0;bottom:0;display:flex;justify-content:space-between;align-items:flex-end;padding:0 var(--pad) calc(28px + env(safe-area-inset-bottom));z-index:20;pointer-events:none}
#openMenu{padding:13px 18px 13px 0;margin:0 0 -5px -2px}
.bottom>*{pointer-events:auto}
.cr{display:flex;flex-direction:row;align-items:stretch;border:.7px solid var(--hair)}
/* padding gives the tap target, the negative margin keeps the original 24px pitch */
.cr button{font-size:12.5px;line-height:1;color:var(--d2);text-align:center;padding:9px 14px;transition:.15s}
.cr button+button{border-left:.7px solid var(--hair)}
.cr button:hover{color:var(--chalk)}
.cr button[aria-pressed="true"]{background:var(--chalk);color:var(--ink)}

.sheet{position:absolute;inset:0;background:var(--ink);z-index:50;transform:translateY(101%);transition:transform .4s cubic-bezier(.5,0,.15,1);overflow-y:auto;padding:0 var(--pad) 40px}
.sheet.open{transform:translateY(0)}
.sheet.down{transform:translateY(-101%)}
.sheet.down.open{transform:translateY(0)}
/* Sheets that can be opened while a page (#det 54, #ven 56) is up have to clear it, or they open behind it
   and the tap reads as "nothing happened" — which is exactly what tapping a line-up name did. */
#onb{z-index:60;padding-bottom:0}   /* its footer is sticky; the sheet's own bottom padding would hold it 40px short of the edge */
#srch{z-index:60}
#artist{z-index:62}
#signSheet{z-index:64}
.sx{margin:calc(22px + env(safe-area-inset-top)) 0 24px;font-size:22px;line-height:1;width:28px}
.sh2{font-size:29px;font-weight:700;letter-spacing:-.03em;margin-bottom:14px}
.lede{font-size:15.5px;line-height:1.6;color:var(--d1);margin-bottom:24px}
.grp{margin-top:30px}
.dbody .grp{margin-top:26px;padding-top:26px;border-top:.7px solid var(--rule)}
.grp h3{font-size:13px;color:var(--d2);font-weight:400;margin-bottom:13px}
.opts{display:flex;flex-wrap:wrap;gap:11px 22px}
.opts button{font-size:16px;color:var(--d2)}
.opts button[aria-pressed="true"]{color:var(--chalk);text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:.7px}
.opts button[disabled]{color:rgba(255,255,255,.18);cursor:default;text-decoration:none}
.stack button{display:flex;justify-content:space-between;align-items:baseline;width:100%;font-size:18px;padding:14px 0;border-bottom:.7px solid var(--hair)}
.stack button span{font-size:13.5px;color:var(--d2)}
.pick{width:100%;padding:16px 0;border-bottom:.7px solid var(--hair);display:block}
.pick .t{font-size:19px}
.pick .d{font-size:13.5px;color:var(--d2);margin-top:6px;line-height:1.5}
.pick[aria-pressed="true"] .t{text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:.7px}
.pick[aria-pressed="true"] .d{color:var(--d1)}
.foot{display:flex;gap:26px;margin-top:34px}
.cal{margin-top:30px}
.calhd{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px}
.calhd .m{font-size:16px}
.calhd button{font-size:17px;color:var(--d2);padding:4px 12px;line-height:1}
.calhd button:hover{color:var(--chalk)}
.calhd button[disabled]{color:rgba(255,255,255,.18);cursor:default}
.calg{display:grid;grid-template-columns:repeat(7,1fr)}
.calg .wd{font-size:11px;color:var(--d2);text-align:center;padding-bottom:10px}
.calg button{height:48px;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;font-size:15px;color:var(--d1);text-align:center}
.calg button .n{font-size:10.5px;color:var(--d2);line-height:1}
.calg button[disabled]{color:rgba(255,255,255,.18);cursor:default}
.calg button[aria-current="date"]{color:var(--chalk)}
.calg button[aria-pressed="true"]{color:var(--chalk);text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:.7px}
.calg .pad{height:48px}
.why{font-size:12.5px;color:var(--d2);line-height:1.5;margin-top:4px}
.rec{align-items:center}
.rec .recmain{width:100%;min-width:0}
.recend{display:flex;align-items:center;gap:12px}
.recx{color:var(--d2);font-size:13px;line-height:1;padding:11px 9px;margin:-11px -7px -11px 0;border-radius:999px}
.recx:active{background:#141414;color:var(--t)}
.recgone{color:var(--d2);font-size:13.5px}
/* "For you", said in place rather than as a card floating over the artwork */
.fortag{font-size:12.5px;color:var(--chalk);margin:0 0 12px;display:flex;align-items:flex-start;gap:8px;line-height:1.4}
.fydot{width:5px;height:5px;border-radius:50%;background:var(--chalk);flex:0 0 auto;margin-top:6px}
/* Rows 1-4 of .row are spoken for, so the list marker rides the time line instead of claiming a new row.
   The rail directly above already carries the reason; here it only has to explain why this row is first. */
.rfor{color:var(--chalk)}
.rfor::before{content:'';display:inline-block;width:4px;height:4px;border-radius:50%;
  background:var(--chalk);vertical-align:middle;margin:-1px 6px 0 0}
/* a pick's one-line justification ("You saw Four Tet", "On sale · 1,118 interested", "Outside your genres"):
   a fifth row under the venue in the list, a line under the venue in the caption */
.row .why{grid-column:1;grid-row:5;margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.caption .meta.haswhy{margin-bottom:4px}
.caption .why{margin:0 0 18px;color:var(--d1)}
/* Onboarding. Two skippable questions using the chips and sheet the app already has, so it reads as the same
   product rather than a form bolted to the front of it. */
.onbsub{font-size:15px;color:var(--d1);line-height:1.55;margin:-4px 0 26px}
.pk{display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-top:8px}
.pkc{position:relative;aspect-ratio:1/1;border:.7px solid var(--hair);border-radius:3px;overflow:hidden;
  background:#141414;padding:0;display:block}
.pkc img{width:100%;height:100%;object-fit:cover;opacity:.66;transition:opacity .18s ease}
.pkc[aria-pressed="true"]{border-color:var(--chalk)}
.pkc[aria-pressed="true"] img{opacity:1}
.pkl{position:absolute;left:0;right:0;bottom:0;padding:30px 11px 10px;font-size:12.5px;line-height:1.32;
  background:linear-gradient(180deg,rgba(11,11,11,0),rgba(11,11,11,.92) 62%)}
.pkl b{font-weight:600;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pkl span{color:var(--d1)}
.pkt{position:absolute;top:9px;right:9px;width:23px;height:23px;border-radius:50%;
  border:.7px solid rgba(255,255,255,.55);display:flex;align-items:center;justify-content:center;
  font-size:12px;line-height:1;background:rgba(11,11,11,.45);color:transparent}
.pkc[aria-pressed="true"] .pkt{background:var(--chalk);color:var(--ink);border-color:var(--chalk)}
/* the footer stays in view while the flyers scroll: Done is never somewhere below sixteen cards */
.onbfoot{display:flex;align-items:center;justify-content:space-between;gap:20px;margin-top:14px;
  position:sticky;bottom:0;padding:26px 0 calc(14px + env(safe-area-inset-bottom));
  background:linear-gradient(180deg,rgba(11,11,11,0),var(--ink) 34%)}
/* Search */
.sinput{width:100%;background:none;border:0;border-bottom:.7px solid var(--hair);color:var(--chalk);
  font:inherit;font-size:19px;padding:10px 0 12px;margin-bottom:8px;outline:none}
.sinput::placeholder{color:var(--d2)}
.sinput:focus{border-bottom-color:var(--chalk)}
.sgrp{margin-top:26px}
.sgrp h3{font-size:13px;color:var(--d2);font-weight:400;margin-bottom:10px}
.shit{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:14px;align-items:baseline;
  width:100%;padding:11px 0;border-bottom:.7px solid var(--hair);text-align:left}
.shit b{font-size:17px;font-weight:500;letter-spacing:-.02em;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.shit span{font-size:13px;color:var(--d2);white-space:nowrap}
.shit .ssub{display:block;font-size:13px;color:var(--d1);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* Artist sheet: where to go and listen */
.alisten{display:flex;flex-wrap:wrap;gap:10px;margin:4px 0 30px}
.alisten a{border:.7px solid var(--hair);border-radius:999px;padding:9px 16px;font-size:14px;
  color:var(--d1);text-decoration:none;white-space:nowrap}
.alisten a:active{background:var(--chalk);color:var(--ink);border-color:var(--chalk)}
/* a bare name with an arrow reads like the venue link above it, so the heading says what the tap does */
.hint{color:var(--d2);font-weight:400}
/* the night's cards inside the When sheet: the sheet already pads the sides, so the rows only need a rule */
#calList .row{padding-left:0;padding-right:0;border-top:.7px solid var(--hair)}
.field{display:flex;align-items:baseline;gap:8px;border-bottom:.7px solid var(--hair);padding:12px 0}
.field b{font-weight:400;font-size:20px;color:var(--d2)}
.field input{flex:1;min-width:0;background:none;border:0;color:#fff;font:inherit;font-size:20px;outline:none;padding:0}
.field input::placeholder{color:rgba(255,255,255,.24)}
.note{font-size:13px;color:var(--d2);line-height:1.55;margin-top:12px}

.page{position:absolute;inset:0;background:var(--ink);transform:translateY(101%);transition:transform .4s cubic-bezier(.5,0,.15,1);overflow-y:auto}
.page.open{transform:translateY(0)}
#det{z-index:54}
#ven{z-index:56}
#det.over{z-index:58}   /* an event opened from the venue list sits over it */
.dhero{position:relative;height:34%;min-height:220px}
.dx{position:absolute;top:calc(20px + env(safe-area-inset-top));right:var(--pad);z-index:5;font-size:22px;line-height:1}
.dbody{padding:26px var(--pad) 50px}
.dname{font-size:27px;font-weight:500;letter-spacing:-.032em;line-height:1.1}
/* when the title IS the act, the title is the way to their sets */
.dsup{font-size:15px;color:var(--d1);margin-top:10px;line-height:1.5}
.specs{display:grid;grid-template-columns:104px minmax(0,1fr);gap:9px 18px;margin-top:24px;padding-top:24px;
 border-top:.7px solid var(--rule);font-size:15px;line-height:1.5}
.specs .k{color:var(--d2)}
.specs .go{text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:.7px}
.tk{display:grid;grid-template-columns:minmax(0,1fr) auto auto;gap:16px;align-items:baseline;padding:12px 0}
.tk .src{font-size:17px}
.tk .st{font-size:13px;color:var(--d2);margin-top:4px;line-height:1.45}
.tk .amt{font-size:16px;text-align:right}
.tk.dead{color:var(--d2)}
.gapnote{font-size:14px;color:var(--d1);margin-top:12px;line-height:1.55}
.ro{display:grid;grid-template-columns:88px minmax(0,1fr);gap:12px 16px;padding:6px 0;align-items:baseline}
.ro .t{font-size:13.5px;color:var(--d2)}
.ro .who{font-size:16px;line-height:1.35}
.prose{font-size:15.5px;line-height:1.6;color:var(--d1)}
.dacts{display:flex;justify-content:space-between;gap:12px 18px;margin-top:34px;flex-wrap:wrap}   /* four actions, one line */
.dacts button[aria-pressed="true"]{color:#fff}
.empty{padding:40px var(--pad);font-size:15.5px;color:var(--d1);line-height:1.6}
.crowd{display:flex;flex-wrap:wrap;gap:9px 15px;font-size:15px;color:var(--d1)}
.crowd .me{color:var(--chalk);text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:.7px}
.crowd .more{color:var(--d2)}
.goline{font-size:14px;color:var(--d1);margin-top:14px;line-height:1.55}
.links a,.links button{display:flex;justify-content:space-between;align-items:baseline;padding:14px 0;border-bottom:.7px solid var(--hair);font-size:17px;text-decoration:none;width:100%}
.links a span,.links button span{font-size:13.5px;color:var(--d2);text-align:right;padding-left:14px}
.strip{display:flex;gap:3px;overflow-x:auto;margin:0 calc(-1 * var(--pad));padding:0 var(--pad);scrollbar-width:none}
.strip::-webkit-scrollbar{display:none}
.ph{flex:none;width:158px;aspect-ratio:3/4;position:relative;overflow:hidden}
.ph .cp{position:absolute;left:10px;right:10px;bottom:9px;font-size:11.5px;color:rgba(255,255,255,.9);z-index:3;line-height:1.35}
.shade{position:absolute;inset:0;background:linear-gradient(180deg,rgba(11,11,11,0) 45%,rgba(11,11,11,.85) 100%)}
.iggrid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:3px}
.igt{position:relative;aspect-ratio:1;overflow:hidden;display:block;width:100%}
.igt .kind{position:absolute;top:7px;right:8px;font-size:11px;z-index:3;color:#fff}
.igt .cp{position:absolute;left:8px;right:8px;bottom:7px;font-size:11px;color:rgba(255,255,255,.88);z-index:3;line-height:1.3}
.mini{font-size:13px;color:var(--d2);margin-top:12px;line-height:1.5}
.flag{font-size:12.5px;color:var(--d2);line-height:1.5;padding:0 var(--pad);margin-top:-6px;margin-bottom:18px}
@media (prefers-reduced-motion:reduce){*{transition-duration:.01ms!important}}

/* ---------- Map view ----------
   CARTO's dark basemap is the one map that already looks like this app: near-black ground, hairline roads,
   no colour. Venues are dots sized by how many nights they hold in the loaded range; tapping one opens the
   venue sheet, which already lists them. */
#map{position:absolute;inset:0;background:var(--ink);z-index:1}
#map .leaflet-tile-pane{filter:invert(1) hue-rotate(180deg) saturate(0) brightness(.78) contrast(1.15)}
#map .leaflet-control-attribution{background:rgba(11,11,11,.7);color:var(--d2);font:inherit;font-size:10px;padding:2px 6px}
#map .leaflet-control-attribution a{color:var(--d1)}
#map .leaflet-control-zoom{border:0;box-shadow:none;margin:0 var(--pad) calc(170px + env(safe-area-inset-bottom)) 0}
#map .leaflet-bottom.leaflet-left .leaflet-control-attribution{margin-bottom:calc(150px + env(safe-area-inset-bottom))}
#map .leaflet-control-zoom a{background:rgba(11,11,11,.78);color:var(--chalk);border:.7px solid var(--hair);width:34px;height:34px;line-height:32px;font-weight:400}
#map .leaflet-control-zoom a:first-child{border-radius:3px 3px 0 0}
#map .leaflet-control-zoom a:last-child{border-radius:0 0 3px 3px;border-top:0}
.vdot{display:flex;align-items:center;justify-content:center;border-radius:50%;
  background:var(--chalk);color:var(--ink);font-size:12px;font-weight:600;letter-spacing:-.02em;
  border:2px solid var(--ink);box-shadow:0 0 0 1px rgba(255,255,255,.35)}
.vdot.you{background:var(--ink);color:var(--chalk);border-color:var(--chalk)}   /* a For-you night lives here */
.vdot.dim{opacity:.55}
/* the pick's name beside its dot ("Best match", "Wildcard"): Leaflet's tooltip, restyled to the palette, no arrow */
#map .leaflet-tooltip.vlbl{background:var(--ink);color:var(--chalk);border:.7px solid var(--hair);border-radius:2px;
  padding:3px 7px;font:inherit;font-size:12px;line-height:1.3;box-shadow:none;white-space:nowrap;opacity:1}
#map .leaflet-tooltip.vlbl::before{display:none}
.mapnote{position:absolute;left:var(--pad);right:var(--pad);bottom:calc(150px + env(safe-area-inset-bottom));
  z-index:16;font-size:12.5px;color:var(--d2);pointer-events:none}
.mapnote[hidden]{display:none}
/* The promoter's track: a text control, the title, the platform it plays from. No meter and no progress bar --
   either would imply a chosen segment, and the clip is the platform's, not ours. */
/* Line-up section: one row per name, the whole row is the tap; the night's track hangs under its artist */
.lu{display:flex;justify-content:space-between;align-items:baseline;gap:16px;width:100%;padding:12px 0;border-bottom:.7px solid var(--hair)}
.lu.has{border-bottom:0;padding-bottom:4px}
.lu:last-child{border-bottom:0}
.lun{font-size:17px;min-width:0}
.luh{font-size:12px;color:var(--d2);margin-left:10px;white-space:nowrap}
.luset{font-size:13.5px;color:var(--d1);white-space:nowrap;text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:.7px}
.lu:active .luset{color:var(--chalk)}
.tkr{padding:0 0 12px;border-bottom:.7px solid var(--hair);font-size:13.5px}
.tkr:last-child{border-bottom:0}
/* the song on one line (truncated before it wraps), its two controls together on the next */
.tkt{color:var(--d1);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.tkc{display:flex;align-items:baseline;gap:8px;margin-top:3px;color:var(--d2)}
.tkc .sep{color:var(--d2)}
.tkp{color:var(--d1);white-space:nowrap;text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:.7px}
.tkp[aria-pressed="true"]{color:var(--chalk)}
.tkp[disabled]{color:var(--d2);text-decoration:none;cursor:default}
.tkc a{color:var(--d1);white-space:nowrap;text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:.7px}   /* the same weight as Play 30 s: two equal ways to hear it */
.nw{white-space:nowrap}
/* After this, nearby: one room per row, the way to it on the right */
.nx{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:16px;align-items:baseline;padding:12px 0;border-bottom:.7px solid var(--hair)}
.nx:last-child{border-bottom:0}
.nxmain{text-align:left;min-width:0;padding:0;width:100%}
.nxv{font-size:17px}
.nxh{font-size:13.5px;color:var(--d1);margin-top:3px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.nxs{font-size:13px;color:var(--d2);margin-top:3px}
/* Group Mode. The deck is the image view with two words under the card; the plan is a sheet of counts. */
#group{z-index:63}
.gvote{display:flex;gap:34px;margin:2px 0 16px}
.gvote button{font-size:17px;color:var(--d1);text-decoration:underline;text-underline-offset:5px;text-decoration-thickness:.7px}
.gvote button[aria-pressed="true"]{color:var(--chalk)}
.gsub{font-size:14px;color:var(--d2);margin:-4px 0 22px;line-height:1.5}
.gintro{font-size:17px;line-height:1.5;color:var(--d1);margin:6px 0 30px;max-width:30ch}
.gintro em{font-style:normal;color:var(--chalk)}
.gsend{margin:-8px 0 24px}
.gpick{margin:0 0 18px}
.gpick h3{font-size:12px;color:var(--d2);font-weight:400;margin-bottom:9px}
.gpick .opts{gap:9px 18px}
.gnights{flex-wrap:nowrap;overflow-x:auto;scrollbar-width:none}
.gnights::-webkit-scrollbar{display:none}
.gcount{font-size:14px;color:var(--d2);white-space:nowrap}
.gcount.all{color:var(--chalk)}
