/* =====================================================================
   Volant Equinox Campout
   Mobile first. Most traffic arrives from the Instagram bio link.

   THE DEVICE: the page is one ticket, torn into stubs. Every section is
   a stub on its own paper stock, joined to the next by a punched
   perforation, and side printed with a rotated caps label the way a real
   ticket is. The stocks run the poster's own sequence, warm first: night
   gate, full sun, cream paper, rust, olive, forest, pool, night again.
   Each stock carries a quiet authored pattern (rays, dots, star field,
   lattice, hatch, pool tile) over a slice of the poster's own paint, so
   no section is a flat digital gradient.
   ===================================================================== */

:root{
  --ground:   #0d0904;   /* the dark table the ticket lies on */
  --ink:      #1b1206;
  --cream:    #f2e7cd;

  --bronze:   #b5772d;
  --amber:    #e8a33a;
  --gold:     #d9b43a;
  --gold-lt:  #f0d99a;
  --rust:     #8f2409;
  --rust-dk:  #5d1505;
  --olive:    #5a6401;
  --olive-dk: #3d4601;
  --forest:   #13481b;
  --forest-dk:#0b2a11;
  --teal:     #0c9c89;
  --teal-dp:  #03464e;
  --night:    #071a24;

  /* per stock, redefined by each .zone-* */
  --paper:    var(--ground);
  --stock-ink:var(--cream);
  --ink-mute: rgba(242,231,205,.78);
  --edge:     rgba(242,231,205,.26);
  --accent:   var(--gold);
  --panel:    rgba(0,0,0,.22);
  --shadow:   rgba(0,0,0,.45);
  --stamp:    rgba(242,231,205,.42);
  --keyline:  rgba(0,0,0,.6);
  --chip:     var(--ink);
  --chip-ink: #ffdf9f;
  --btn-face: var(--gold);
  --btn-ink:  var(--ink);
  --btn-edge: rgba(0,0,0,.6);

  --display: "Arial Black","Helvetica Neue",Helvetica,Arial,sans-serif;
  --body: system-ui,-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --side: 34px;
}

*,*::before,*::after{ box-sizing:border-box; }

html{ scroll-behavior:smooth; scroll-padding-top:66px; }
@media (prefers-reduced-motion:reduce){ html{ scroll-behavior:auto; } }

body{
  margin:0; background:var(--ground); color:var(--cream);
  font-family:var(--body); font-size:16px; line-height:1.56;
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}
/* press grain over everything */
body::after{
  content:""; position:fixed; inset:0; z-index:60;
  pointer-events:none; opacity:.06; mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.8' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}
@media (prefers-reduced-motion:reduce){ body::after{ display:none; } }

h1,h2,h3{ margin:0; line-height:1.02; letter-spacing:-.02em; }
p{ margin:0 0 1rem; }
a{ color:var(--accent); }
a:hover{ color:var(--stock-ink); }
img{ max-width:100%; height:auto; display:block; }
svg{ max-width:100%; display:block; }
ul,dl{ margin:0; padding:0; list-style:none; }
dd{ margin:0; }

.skip{
  position:absolute; left:-9999px; top:0; z-index:200;
  background:var(--gold); color:var(--ink); padding:12px 18px;
  font-weight:800; text-decoration:none;
}
.skip:focus{ left:0; }
:focus-visible{ outline:3px solid var(--gold); outline-offset:3px; }

.visually-hidden{
  position:absolute; width:1px; height:1px; margin:-1px; padding:0;
  overflow:hidden; clip:rect(0 0 0 0); clip-path:inset(50%); white-space:nowrap;
}

.dot{
  display:inline-block; width:4px; height:4px; background:currentColor;
  opacity:.55; margin:0 .7em; vertical-align:middle; transform:rotate(45deg);
}

/* display type: heavy caps with a hard ink keyline, the way the poster
   sets its own. paint-order keeps the stroke behind the fill so the
   letterforms do not thin out. */
.dt{
  font-family:var(--display); text-transform:uppercase; letter-spacing:-.035em;
  -webkit-text-stroke:.05em var(--keyline); paint-order:stroke fill;
}

/* =====================================================================
   NAV
   ===================================================================== */
.nav{
  position:sticky; top:0; z-index:100;
  display:flex; align-items:center; gap:16px; padding:9px 14px;
  background:linear-gradient(180deg,#17110a 0%,#0b0703 100%);
  border-bottom:2px solid var(--gold);
  transition:box-shadow .25s ease;
}
.nav.is-stuck{ box-shadow:0 10px 26px rgba(0,0,0,.6); }
.nav::after{
  content:""; position:absolute; left:0; right:0; top:100%; height:8px;
  pointer-events:none;
  background:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='20' height='8'%3E%3Cpath d='M0 0 L10 8 L20 0 Z' fill='%23d9b43a'/%3E%3C/svg%3E") repeat-x;
  background-size:20px 8px;
}
.nav__brand{ display:flex; margin-right:auto; }
.nav__mark{ width:26px; height:26px; }
.nav__links{ display:none; gap:22px; }
.nav__links a{
  position:relative; text-decoration:none;
  font-size:.68rem; font-weight:900; letter-spacing:.2em; text-transform:uppercase;
  color:rgba(242,231,205,.72); padding-bottom:3px; transition:color .16s ease;
}
.nav__links a::after{
  content:""; position:absolute; left:0; right:0; bottom:0; height:2px;
  background:var(--gold); transform:scaleX(0); transform-origin:left;
  transition:transform .18s ease;
}
.nav__links a:hover{ color:var(--gold); }
.nav__links a:hover::after{ transform:scaleX(1); }
.nav__cta{ display:none; }
@media (min-width:840px){
  .nav{ padding:10px 26px; }
  .nav__links,.nav__cta{ display:flex; }
}
@media (prefers-reduced-motion:reduce){ .nav__links a::after{ transition:none; } }

/* =====================================================================
   THE ROLL AND ITS STUBS
   ===================================================================== */
.roll{ margin:12px 10px 26px; }
@media (min-width:1100px){ .roll{ max-width:1060px; margin:22px auto 40px; } }

.stub{
  position:relative; display:flex; align-items:stretch;
  background-color:var(--paper); color:var(--stock-ink);
}
/* the perforation: a dashed tear with a punch at each edge */
.stub + .stub{ border-top:2px dashed rgba(0,0,0,.35); }
.stub + .stub::before,
.stub + .stub::after{
  content:""; position:absolute; top:-14px; width:26px; height:26px;
  border-radius:50%; background:var(--ground); z-index:3;
}
.stub + .stub::before{ left:-14px; }
.stub + .stub::after{ right:-14px; }
.stub--lightseam + .stub{ border-top-color:rgba(242,231,205,.4); }

.side{
  flex:0 0 var(--side); position:relative; z-index:2;
  display:flex; align-items:center; justify-content:center;
  border-right:2px dotted var(--edge);
}
.side > span{
  writing-mode:vertical-rl; transform:rotate(180deg);
  font-size:.6rem; font-weight:900; letter-spacing:.34em; text-transform:uppercase;
  white-space:nowrap; color:var(--ink-mute);
}
.stub__body{
  flex:1 1 auto; min-width:0; position:relative; z-index:1;
  padding:40px 18px 44px;
}
@media (min-width:840px){
  :root{ --side:46px; }
  .stub__body{ padding:70px 46px 76px; }
}

/* =====================================================================
   PAPER STOCKS
   Each one is an authored pattern over a tint over a type free slice of
   the poster's own paint.
   ===================================================================== */

/* the gate: night, with the sunburst turning behind the emblem */
.zone-gate{
  --paper:#160e06;
  background-image:
    radial-gradient(120% 90% at 50% 0%, rgba(181,119,45,.42) 0%, transparent 62%),
    radial-gradient(90% 70% at 50% 108%, rgba(143,36,9,.5) 0%, transparent 60%);
  --edge:rgba(242,231,205,.24);
  --accent:var(--gold);
  --stamp:rgba(242,231,205,.4);
}

/* full sun */
.zone-sun{
  --paper:var(--amber);
  background-image:
    repeating-linear-gradient(112deg, rgba(255,255,255,.09) 0 2px, transparent 2px 17px),
    linear-gradient(180deg, rgba(240,178,68,.88) 0%, rgba(201,118,31,.92) 100%),
    url("assets/bg-sun.jpg");
  background-size:auto, auto, cover;
  background-position:center, center, center;
  --stock-ink:var(--ink);
  --ink-mute:rgba(27,18,6,.78);
  --edge:rgba(27,18,6,.36);
  --accent:var(--rust-dk);
  --panel:rgba(255,248,232,.5);
  --stamp:rgba(27,18,6,.5);
  --keyline:transparent;
  --chip:var(--ink); --chip-ink:#ffdf9f;
  --btn-face:var(--ink); --btn-ink:#ffe3b6; --btn-edge:var(--rust-dk);
  --shadow:rgba(93,21,5,.4);
}

/* cream paper, where the money would change hands */
.zone-paper{
  --paper:#f2e7cd;
  background-image:
    radial-gradient(rgba(27,18,6,.1) 1px, transparent 1.2px),
    radial-gradient(120% 90% at 50% 0%, rgba(232,163,58,.22) 0%, transparent 60%);
  background-size:15px 15px, auto;
  --stock-ink:var(--ink);
  --ink-mute:rgba(27,18,6,.72);
  --edge:rgba(27,18,6,.32);
  --accent:var(--rust);
  --panel:rgba(255,252,244,.72);
  --stamp:rgba(27,18,6,.45);
  --keyline:transparent;
  --chip:var(--rust); --chip-ink:#ffeeda;
  --btn-face:var(--ink); --btn-ink:#ffe3b6; --btn-edge:var(--rust);
  --shadow:rgba(27,18,6,.32);
}

/* the bill, rust over a star field */
.zone-rust{
  --paper:var(--rust);
  background-image:
    radial-gradient(rgba(255,236,207,.5) .9px, transparent 1px),
    radial-gradient(rgba(255,236,207,.3) .7px, transparent .9px),
    linear-gradient(180deg, rgba(143,36,9,.9) 0%, rgba(93,21,5,.94) 100%),
    url("assets/bg-ember.jpg");
  background-size:46px 46px, 23px 23px, auto, cover;
  background-position:0 0, 11px 9px, center, center;
  --accent:#ffce6a;
  --edge:rgba(242,231,205,.3);
  --stamp:rgba(242,231,205,.46);
}

/* the field, olive under a diamond lattice */
.zone-olive{
  --paper:var(--olive);
  background-image:
    repeating-linear-gradient(45deg, rgba(242,231,205,.07) 0 1px, transparent 1px 26px),
    repeating-linear-gradient(-45deg, rgba(242,231,205,.07) 0 1px, transparent 1px 26px),
    linear-gradient(180deg, rgba(90,100,1,.88) 0%, rgba(61,70,1,.92) 100%),
    url("assets/bg-field.jpg");
  background-size:auto, auto, auto, cover;
  background-position:center, center, center, center top;
  --accent:#ffd882;
  --edge:rgba(242,231,205,.28);
}

/* deeper into the trees */
.zone-forest{
  --paper:var(--forest);
  background-image:
    repeating-linear-gradient(72deg, rgba(242,231,205,.06) 0 1px, transparent 1px 13px),
    linear-gradient(180deg, rgba(19,72,27,.9) 0%, rgba(11,42,17,.94) 100%),
    url("assets/bg-wood.jpg");
  background-size:auto, auto, cover;
  --accent:#66e3b9;
  --edge:rgba(242,231,205,.24);
}

/* the pool, the one cool stock, on tile */
.zone-pool{
  --paper:var(--teal-dp);
  background-image:
    repeating-linear-gradient(0deg, rgba(242,231,205,.09) 0 1px, transparent 1px 30px),
    repeating-linear-gradient(90deg, rgba(242,231,205,.09) 0 1px, transparent 1px 30px),
    linear-gradient(180deg, rgba(12,120,110,.88) 0%, rgba(3,70,78,.94) 100%),
    url("assets/bg-water.jpg");
  background-size:auto, auto, auto, cover;
  --accent:#8ff0e6;
  --edge:rgba(242,231,205,.28);
}

/* night, stage lights on */
.zone-night{
  --paper:var(--night);
  background-image:
    radial-gradient(rgba(242,231,205,.4) .9px, transparent 1px),
    radial-gradient(80% 80% at 50% 100%, rgba(224,122,32,.34) 0%, transparent 62%),
    linear-gradient(180deg, rgba(7,26,36,.9) 0%, rgba(6,16,22,.95) 100%),
    url("assets/bg-stage.jpg");
  background-size:52px 52px, auto, auto, cover;
  background-position:0 0, center, center, center bottom;
  --accent:var(--gold);
  --edge:rgba(242,231,205,.22);
}

/* the keep this half stub */
.zone-ink{
  --paper:#0b0703;
  background-image:repeating-linear-gradient(112deg, rgba(242,231,205,.05) 0 1px, transparent 1px 15px);
  --edge:rgba(242,231,205,.2);
  --ink-mute:rgba(242,231,205,.6);
}

/* =====================================================================
   SHARED PARTS
   ===================================================================== */
.chip{
  display:inline-block; background:var(--chip); color:var(--chip-ink);
  font-size:.6rem; font-weight:900; letter-spacing:.22em; text-transform:uppercase;
  padding:6px 13px; border:2px solid rgba(0,0,0,.35);
  box-shadow:3px 3px 0 var(--shadow);
}

/* the announced soon stamp. Four blocks are honestly incomplete a week
   out (price, address, lineup, vendors) and they all say so the same way. */
.stamp{
  display:inline-flex; align-items:flex-start; gap:.6em; max-width:100%;
  font-size:.64rem; font-weight:900; letter-spacing:.16em; text-transform:uppercase;
  line-height:1.3; color:var(--ink-mute); text-align:left;
  border:2px dashed var(--stamp); padding:7px 12px; overflow-wrap:anywhere;
}
.stamp::before{
  content:""; flex:none; width:7px; height:7px; margin-top:.3em;
  border:2px solid currentColor; transform:rotate(45deg);
}
.stamp--lg{ font-size:.7rem; padding:10px 15px; }

/* screen printed buttons: square, heavy caps, hard offset shadow, and
   the face slides onto its own shadow when pressed. */
.btn{
  position:relative; display:inline-flex; align-items:center; justify-content:center;
  gap:.5em; text-align:center; text-decoration:none; cursor:pointer;
  background:var(--btn-face); color:var(--btn-ink);
  font-weight:900; font-size:.8rem; letter-spacing:.12em; text-transform:uppercase;
  padding:14px 24px; border:2px solid var(--btn-edge);
  box-shadow:4px 4px 0 var(--btn-edge);
  /* A button never leaves its container, however long the label.
     `@volantequinoxcampout` is one 21 character token and with letter
     spacing it once measured 324px inside a 345px phone, so the follow
     button was silently clipped by body overflow-x:hidden while being
     the only action on the page. Fixed generally, not per label. */
  max-width:100%; flex-wrap:wrap; overflow-wrap:anywhere;
  transition:transform .12s ease, box-shadow .12s ease;
}
.btn:hover{ color:var(--btn-ink); transform:translate(2px,2px); box-shadow:2px 2px 0 var(--btn-edge); }
.btn:active{ transform:translate(4px,4px); box-shadow:0 0 0 var(--btn-edge); }
.btn--lg{ padding:17px 28px; font-size:.88rem; min-height:52px; }
@media (max-width:420px){ .btn--lg{ padding:15px 16px; font-size:.76rem; letter-spacing:.06em; } }
.btn--sm{ padding:9px 14px; font-size:.68rem; box-shadow:3px 3px 0 var(--btn-edge); }
.btn--sm:hover{ box-shadow:1px 1px 0 var(--btn-edge); }
.btn--block{ width:100%; }
.btn--ghost{
  background:transparent; color:var(--stock-ink);
  border-color:var(--stock-ink); box-shadow:3px 3px 0 var(--stock-ink);
}
.btn--ghost:hover{ color:var(--stock-ink); box-shadow:1px 1px 0 var(--stock-ink); }
.btn[aria-disabled="true"]{
  background:transparent; color:var(--ink-mute);
  border:2px dashed var(--stamp); box-shadow:none; cursor:not-allowed;
}
.btn[aria-disabled="true"]:hover{ transform:none; box-shadow:none; }
@media (prefers-reduced-motion:reduce){ .btn,.btn:hover,.btn:active{ transition:none; transform:none; } }

.tlink{
  display:inline-flex; align-items:center; gap:.5em; text-decoration:none;
  font-size:.72rem; font-weight:900; letter-spacing:.18em; text-transform:uppercase;
  color:var(--stock-ink); border-bottom:2px solid var(--accent); padding-bottom:3px;
}
.tlink:hover{ color:var(--accent); }

.shead{ text-align:center; margin-bottom:30px; }
.shead--left{ text-align:left; margin-bottom:20px; }
.shead .chip{ margin-bottom:14px; }
.shead__title{ font-size:clamp(2.1rem,9vw,3.6rem); }
.shead__sub{ margin:14px auto 0; max-width:50ch; color:var(--ink-mute); font-size:.92rem; }
.shead--left .shead__sub{ margin-inline:0; }
.lead{ font-size:1rem; color:var(--ink-mute); }

/* =====================================================================
   THE GATE
   ===================================================================== */
.hero{ text-align:center; overflow:hidden; padding-top:30px; }
.hero__sky{ position:absolute; inset:0; overflow:hidden; pointer-events:none; z-index:0; }
/* the poster's hard edged burst, authored as flat triangles rather than
   a gradient. The fan spins about the viewBox centre: the origin below
   is a second copy of that coordinate, so if the burst ever moves, move
   both. */
.sunburst{
  position:absolute; left:50%; top:40%; width:min(190%,1300px); height:auto;
  aspect-ratio:1; transform:translate(-50%,-50%);
}
.sunburst__fan{ transform-origin:500px 500px; animation:turn 280s linear infinite; }
@keyframes turn{ to{ transform:rotate(360deg); } }
@media (prefers-reduced-motion:reduce){ .sunburst__fan{ animation:none; } }
.stars{ position:absolute; inset:0; opacity:.8; }
.stars span{
  position:absolute; width:2px; height:2px; background:var(--cream);
  animation:twinkle 4s ease-in-out infinite;
}
@keyframes twinkle{ 0%,100%{opacity:.15} 50%{opacity:.9} }
@media (prefers-reduced-motion:reduce){ .stars span{ animation:none; opacity:.5; } }

.hero > *:not(.hero__sky){ position:relative; }
.hero__presented{
  font-size:.58rem; font-weight:900; letter-spacing:.2em; text-transform:uppercase;
  color:rgba(240,217,154,.72); line-height:1.7; margin:0 0 16px;
}
.emblem{ width:min(80%,420px); margin:0 auto 14px; }
.emblem img{ width:100%; height:auto; filter:drop-shadow(0 8px 26px rgba(0,0,0,.6)); }
.hero__chapter{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center; margin:0 0 16px;
  font-size:.64rem; font-weight:900; letter-spacing:.26em; text-transform:uppercase;
  color:var(--gold-lt);
}
.hero__chapter b{ color:var(--gold); }

.plate{
  display:inline-block; max-width:100%; margin:0 auto 18px; padding:12px 20px;
  background:var(--rust); color:#fff4e2;
  border:2px solid rgba(0,0,0,.42); box-shadow:6px 6px 0 rgba(0,0,0,.45);
}
.plate__date{ display:block; font-size:clamp(1.05rem,5vw,1.6rem); line-height:1.06; -webkit-text-stroke:0; }
.plate__place{
  display:block; margin-top:5px;
  font-size:.64rem; font-weight:900; letter-spacing:.2em; text-transform:uppercase; color:#ffd9a8;
}
.hero__tagline{
  font-size:clamp(.72rem,2.9vw,.9rem); font-weight:900; letter-spacing:.26em;
  text-transform:uppercase; color:var(--gold-lt); margin:0 0 18px;
}
.hero__actions{ display:flex; flex-direction:column; align-items:center; gap:14px; margin-bottom:18px; }
.hero__actions .btn{ width:100%; max-width:320px; }
@media (min-width:560px){
  .hero__actions{ flex-direction:row; justify-content:center; gap:18px; }
  .hero__actions .btn{ width:auto; }
}
.hero__note{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center; margin:0;
  font-size:.7rem; font-weight:900; letter-spacing:.14em; text-transform:uppercase;
  color:#fff1da;
}

/* =====================================================================
   AT A GLANCE, set as the ticket's fine print grid
   ===================================================================== */
.glance{ display:grid; gap:1px; grid-template-columns:1fr 1fr; background:var(--edge); }
.glance__cell{
  background:var(--paper); padding:14px 14px 16px;
  display:flex; flex-direction:column; gap:4px;
}
.zone-sun .glance__cell{ background:rgba(255,246,226,.22); }
.glance dt{
  font-size:.56rem; font-weight:900; letter-spacing:.22em; text-transform:uppercase;
  color:var(--accent);
}
.glance dd{ font-size:.92rem; font-weight:800; line-height:1.25; }
.glance small{ font-size:.72rem; color:var(--ink-mute); }
.glance .stamp{ margin-top:4px; font-size:.56rem; padding:5px 9px; }
@media (min-width:840px){ .glance{ grid-template-columns:repeat(4,1fr); } }

/* the marquee is the tear strip between the sun and the paper */
.marquee{
  position:relative; overflow:hidden; padding:9px 0;
  background:var(--ink); color:#ffce6a;
  border-top:2px dashed rgba(0,0,0,.5);
}
.marquee::before,.marquee::after{
  content:""; position:absolute; top:-14px; width:26px; height:26px;
  border-radius:50%; background:var(--ground); z-index:3;
}
.marquee::before{ left:-14px; }
.marquee::after{ right:-14px; }
.marquee__track{ display:flex; gap:28px; width:max-content; animation:slide 34s linear infinite; }
@keyframes slide{ to{ transform:translateX(-50%); } }
@media (prefers-reduced-motion:reduce){ .marquee__track{ animation:none; } }
.marquee__item{
  font-size:.72rem; font-weight:900; letter-spacing:.22em; text-transform:uppercase; white-space:nowrap;
}
.marquee__item::after{ content:"\2736"; color:var(--amber); margin-left:28px; }

/* =====================================================================
   TICKETS
   ===================================================================== */
.tiers{ display:grid; gap:14px; }
@media (min-width:900px){ .tiers{ grid-template-columns:repeat(3,1fr); } }
.tier{
  position:relative; background:var(--panel); color:var(--stock-ink);
  border:2px solid var(--edge); padding:24px 20px;
  display:flex; flex-direction:column; gap:12px; box-shadow:6px 6px 0 var(--shadow);
}
.tier--featured{ border-width:3px; border-color:var(--ink); }
.tier__flag{
  position:absolute; top:-13px; left:16px; background:var(--ink); color:#ffce6a;
  font-size:.58rem; font-weight:900; letter-spacing:.16em; text-transform:uppercase;
  padding:5px 12px; white-space:nowrap;
}
.tier__name{ font-size:1.12rem; font-weight:900; }
.tier__price{ display:flex; align-items:baseline; gap:6px; flex-wrap:wrap; }
.tier__amount{ font-family:var(--display); font-size:2.4rem; line-height:1; letter-spacing:-.04em; }
.tier__cur{ font-size:.78rem; font-weight:800; color:var(--ink-mute); }
.tier__blurb{ font-size:.88rem; color:var(--ink-mute); margin:0; }
.tier__includes{ display:flex; flex-direction:column; gap:8px; }
.tier__includes li{ position:relative; padding-left:22px; font-size:.87rem; line-height:1.45; }
.tier__includes li::before{
  content:""; position:absolute; left:0; top:.52em; width:8px; height:8px;
  background:var(--accent); transform:rotate(45deg);
}
.tier .btn{ margin-top:auto; }
.tier--soldout{ opacity:.62; }

.addons{
  margin-top:18px; border:2px solid var(--edge); background:var(--panel);
  padding:18px; box-shadow:6px 6px 0 var(--shadow);
}
.addons__title{
  font-size:.62rem; font-weight:900; letter-spacing:.2em; text-transform:uppercase;
  color:var(--accent); margin-bottom:12px;
}
.addons__list{ display:flex; flex-wrap:wrap; gap:9px; }
.addon{
  display:flex; align-items:center; gap:9px; text-decoration:none; color:var(--stock-ink);
  border:2px solid var(--edge); padding:8px 14px; font-size:.85rem;
}
.addon:hover{ color:var(--stock-ink); border-color:currentColor; }
.addon__price{ font-weight:900; }
.addon[aria-disabled="true"]{ border-style:dashed; opacity:.7; cursor:not-allowed; }

/* the coming-soon panel, which in this mode holds the only action on the
   whole page */
.notice{
  max-width:540px; margin:0 auto; text-align:center;
  background:var(--panel); color:var(--stock-ink);
  border:3px solid var(--edge); padding:28px 20px 30px;
  box-shadow:8px 8px 0 var(--shadow);
}
.notice__icon{ width:36px; margin:0 auto 14px; }
.notice__title{ font-size:clamp(1.55rem,7vw,2.1rem); line-height:1; margin-bottom:14px; }
.notice .stamp{ margin-bottom:16px; }
.notice__body{ color:var(--ink-mute); font-size:.92rem; margin-bottom:20px; }
.notice .btn{ width:100%; }
@media (min-width:560px){ .notice .btn{ width:auto; min-width:280px; } }
.notice__handle{
  margin:14px 0 0; font-size:.72rem; font-weight:800; color:var(--ink-mute); overflow-wrap:anywhere;
}
.eventbrite-embed{ min-height:520px; border:2px solid var(--edge); overflow:hidden; }

/* =====================================================================
   THE BILL
   ===================================================================== */
.bill{ text-align:center; }
.bill__label{
  font-size:.6rem; font-weight:900; letter-spacing:.28em; text-transform:uppercase;
  color:var(--accent); margin-bottom:12px;
}
.bill__head{
  font-size:clamp(1.7rem,9.6vw,5.4rem); line-height:.92; color:#fffaf0;
  overflow-wrap:anywhere; margin-bottom:10px;
}
.bill__support{
  display:flex; flex-wrap:wrap; align-items:center; justify-content:center; gap:.1em .5em;
  font-size:clamp(1.1rem,6vw,2.4rem); line-height:1.05; color:#fff3dd; margin-bottom:16px;
}
.bill__sep{ color:var(--accent); -webkit-text-stroke:0; }
.bill__note{ display:flex; justify-content:center; margin-bottom:4px; }

.poster{ margin:26px auto 0; max-width:420px; }
.poster img{ width:100%; height:auto; border:2px solid rgba(242,231,205,.55); box-shadow:8px 8px 0 rgba(0,0,0,.4); }
.poster figcaption{
  margin-top:10px; text-align:center;
  font-size:.6rem; font-weight:900; letter-spacing:.2em; text-transform:uppercase; color:var(--ink-mute);
}

.genres{
  display:flex; flex-wrap:wrap; gap:.35em .7em; justify-content:center;
  margin-top:26px; padding-top:20px; border-top:2px solid var(--edge);
}
.genre{
  font-size:.72rem; font-weight:900; letter-spacing:.16em; text-transform:uppercase; color:var(--ink-mute);
}
.genre::after{ content:"\2736"; color:var(--accent); margin-left:.7em; }
.genre:last-child::after{ content:none; }

/* =====================================================================
   THE GROUNDS, set as the poster's info block
   ===================================================================== */
.fgrid{ display:grid; gap:24px; }
@media (min-width:760px){ .fgrid{ grid-template-columns:1fr 1fr; gap:32px 40px; } }
@media (min-width:1080px){ .fgrid{ grid-template-columns:repeat(4,1fr); } }
.fgroup{
  display:flex; flex-direction:column; align-items:center; gap:13px;
  text-align:center; padding-top:20px; border-top:2px solid var(--edge);
}
.fgroup__icon{ width:28px; height:28px; color:var(--accent); }
.fgroup__list{ display:flex; flex-direction:column; gap:8px; }
.fgroup__list li{
  font-size:.76rem; font-weight:800; letter-spacing:.1em; text-transform:uppercase; line-height:1.35;
}

/* ---------------- camping ---------------- */
.camping{ display:grid; gap:26px; align-items:center; }
@media (min-width:900px){ .camping{ grid-template-columns:1.05fr .95fr; gap:44px; } }
.camping__art svg{ width:100%; border:2px solid var(--edge); }
.ticks{ display:flex; flex-direction:column; gap:11px; }
.ticks li{ position:relative; padding-left:26px; font-size:.95rem; }
.ticks li::before{
  content:""; position:absolute; left:0; top:.52em; width:9px; height:9px;
  background:var(--accent); transform:rotate(45deg);
}

/* ---------------- faq ---------------- */
.faq{ display:flex; flex-direction:column; gap:8px; }
.faq details{ border:2px solid var(--edge); background:var(--panel); }
.faq summary{
  cursor:pointer; list-style:none; position:relative; min-height:52px;
  padding:15px 46px 15px 16px; font-weight:800; font-size:.95rem;
}
.faq summary::-webkit-details-marker{ display:none; }
.faq summary::after{
  content:""; position:absolute; right:18px; top:50%; width:9px; height:9px; margin-top:-6px;
  border-right:2.4px solid var(--accent); border-bottom:2.4px solid var(--accent);
  transform:rotate(45deg); transition:transform .2s ease;
}
.faq details[open] summary::after{ transform:rotate(-135deg); margin-top:-2px; }
@media (prefers-reduced-motion:reduce){ .faq summary::after{ transition:none; } }
.faq__a{ padding:0 16px 16px; margin:0; font-size:.92rem; color:var(--ink-mute); }

/* ---------------- get involved ---------------- */
.involve{ text-align:center; }
.involve__title{ font-size:clamp(1.6rem,6.6vw,2.8rem); margin-bottom:14px; }
.involve .lead{ margin-bottom:18px; }
.involve__roles{ display:flex; flex-wrap:wrap; gap:8px; justify-content:center; margin-bottom:18px; }
.role{
  border:2px solid var(--edge); padding:7px 15px;
  font-size:.74rem; font-weight:900; letter-spacing:.14em; text-transform:uppercase;
}
.involve .stamp{ margin:0 auto 22px; }
.involve .btn{ width:100%; max-width:400px; }

/* ---------------- keep this half ---------------- */
.foot{ text-align:center; }
.foot__mark{ width:56px; margin:0 auto 12px; opacity:.85; }
.foot__name strong{ display:block; font-size:.95rem; }
.foot__name span{ display:block; font-size:.8rem; color:var(--ink-mute); }
.foot__links{ display:flex; flex-wrap:wrap; justify-content:center; gap:18px; margin:16px 0 14px; }
.foot__links a{
  font-size:.7rem; font-weight:900; letter-spacing:.16em; text-transform:uppercase;
  color:var(--ink-mute); text-decoration:none;
}
.foot__links a:hover{ color:var(--gold); }
.foot__presented{ font-size:.68rem; letter-spacing:.08em; color:rgba(242,231,205,.45); margin:0 auto; max-width:44ch; }

/* =====================================================================
   STICKY PHONE ACTION BAR
   In coming-soon mode the Instagram follow is the only action on the
   page and the page is long, so one bar carries it, phone only, up once
   the gate has scrolled away. Labelled by app.js per ticketing mode.
   ===================================================================== */
.actionbar{
  position:fixed; left:0; right:0; bottom:0; z-index:120;
  display:flex; align-items:center; gap:12px;
  padding:10px 14px calc(10px + env(safe-area-inset-bottom));
  background:linear-gradient(180deg,#17110a 0%,#0b0703 100%);
  border-top:2px solid var(--gold);
  transform:translateY(120%); transition:transform .28s ease;
}
.actionbar.is-up{ transform:translateY(0); }
@media (prefers-reduced-motion:reduce){ .actionbar{ transition:none; } }
.actionbar__label{
  flex:1 1 auto; min-width:0; line-height:1.25;
  font-size:.6rem; font-weight:900; letter-spacing:.14em; text-transform:uppercase; color:var(--gold-lt);
}
.actionbar .btn{ flex:0 1 auto; max-width:62%; --btn-face:var(--gold); --btn-ink:var(--ink); --btn-edge:#000; }
@media (min-width:840px){ .actionbar{ display:none; } }
body.has-actionbar{ padding-bottom:74px; }
@media (min-width:840px){ body.has-actionbar{ padding-bottom:0; } }

/* =====================================================================
   SCROLL LAYER
   Two mechanisms, deliberately separate.

   1. .reveal / .is-in  is driven by IntersectionObserver in app.js.
      Works everywhere, including the older iOS WebViews the Instagram
      in-app browser uses. This carries the entrance motion.

   2. @supports (animation-timeline: view()) adds scrubbed motion with
      no JS at all. Chrome and Chromium Android get it; anything else
      simply never enters the block and keeps the static layout, which
      already looks right. Progressive enhancement, not a fallback.

   Everything here is off under prefers-reduced-motion. No exceptions:
   a scrubbed parallax is exactly the effect that makes motion-sensitive
   people ill, and this page is read on a phone while walking.
   ===================================================================== */

.reveal{
  opacity:0;
  transform:translateY(18px);
  transition:opacity .62s cubic-bezier(.22,.68,.32,1),
             transform .62s cubic-bezier(.22,.68,.32,1);
  /* --i is the stagger index, set per element by app.js */
  transition-delay:calc(var(--i, 0) * 70ms);
  will-change:opacity, transform;
}
.reveal.is-in{ opacity:1; transform:none; will-change:auto; }

/* Section heads arrive from the side, like a stamp being pressed on. */
.reveal--head{ transform:translateY(10px) scale(.985); }

/* Tiers and cards rise further so a row of them reads as a deal. */
.reveal--lift{ transform:translateY(26px); }

@media (prefers-reduced-motion:reduce){
  .reveal, .reveal--head, .reveal--lift{
    opacity:1; transform:none; transition:none; will-change:auto;
  }
}

/* A gold rule under the nav that fills as the page is read. Pure CSS,
   no scroll listener, so it cannot cost a frame. */
.progress{
  position:fixed; left:0; top:0; z-index:60;
  height:3px; width:100%;
  transform-origin:0 50%; transform:scaleX(0);
  background:linear-gradient(90deg, var(--gold, #d9b43a), #ef7622);
  pointer-events:none;
  display:none;
}
@supports (animation-timeline: scroll()){
  @media (prefers-reduced-motion:no-preference){
    .progress{
      display:block;
      animation:progress-grow linear both;
      animation-timeline:scroll(root block);
    }
  }
}
@keyframes progress-grow{ to{ transform:scaleX(1); } }

@supports (animation-timeline: view()){
  @media (prefers-reduced-motion:no-preference){
    /* The emblem drifts and settles as the hero leaves. Small number on
       purpose: the owl is the identity, it should not slide around. */
    .emblem{
      animation:emblem-drift linear both;
      animation-timeline:view(block);
      animation-range:exit 0% exit 90%;
    }
    @keyframes emblem-drift{
      to{ transform:translateY(-26px) scale(.96); opacity:.55; }
    }

    /* Zone art parallax. The background sits on the section, so this
       nudges its position rather than transforming the section itself,
       which would drag the type along with it. */
    .zone-rust, .zone-olive, .zone-forest, .zone-pool{
      animation:zone-pan linear both;
      animation-timeline:view(block);
      animation-range:entry 0% exit 100%;
    }
    @keyframes zone-pan{
      from{ background-position-y:44%; }
      to{ background-position-y:56%; }
    }
  }
}

/* ---------------------------------------------------------------------
   BILL DENSITY
   Set by app.js from the number of support acts, because the roster is
   config data and grew 8x in a single edit. A support row set near the
   headliner's size stops the headliner reading as the headliner.
   --------------------------------------------------------------------- */
.bill--mid   .bill__support{ font-size:clamp(1.15rem, 5.2vw, 1.7rem); line-height:1.22; }
.bill--dense .bill__support{ font-size:clamp(.95rem, 4.2vw, 1.35rem); line-height:1.3; letter-spacing:.02em; }
.bill--dense .bill__sep{ opacity:.55; }

/* Artist links. Underline is drawn rather than text-decoration so it sits
   clear of the descenders in a heavy display face. */
.actlink{
  color:inherit; text-decoration:none;
  background-image:linear-gradient(var(--accent), var(--accent));
  background-size:0% 2px; background-position:0 100%; background-repeat:no-repeat;
  transition:background-size .22s ease;
}
.actlink:hover, .actlink:focus-visible{ background-size:100% 2px; }
@media (prefers-reduced-motion:reduce){ .actlink{ transition:none; } }

/* =====================================================================
   DESKTOP WIDTH
   The page was built phone first, correctly, but the roll was capped at
   1060px, so a 1440 screen showed a narrow column with 190px of dead
   paper each side and the whole thing read as a phone layout centred on
   a desktop.

   Filling the width is not the same as stretching everything. Structure
   fills; PROSE does not, because a 1500px line of body copy is unreadable
   and looks worse than the narrow version. So the roll and the design
   elements grow, and only the running-text blocks keep a measure.
   ===================================================================== */

@media (min-width:1100px){
  .roll{ max-width:min(94vw, 1500px); margin:22px auto 44px; }

  :root{ --side:54px; }
  .stub__body{ padding:78px 64px 84px; }

  /* The emblem is the identity. On a wide screen it was 29% of the
     viewport, which made the hero read as a small picture on a big
     background rather than as a poster. */
  .emblem{ width:min(46%, 560px); }

  /* The one action on the page in coming-soon mode. It was 38% of the
     viewport and looked like a dialog box dropped on the page. */
  .notice{ max-width:760px; padding:40px 44px 44px; }
  .notice__title{ font-size:clamp(2rem, 3.4vw, 2.9rem); }
  .notice__body{ font-size:1rem; max-width:52ch; margin-left:auto; margin-right:auto; }

  .poster{ max-width:560px; }

  /* Prose keeps a measure. These are the only things that do. */
  .shead__sub{ max-width:64ch; font-size:1rem; }
  .lead{ max-width:70ch; margin-left:auto; margin-right:auto; }

  /* Section heads scale with the room they now have. */
  .shead__title{ font-size:clamp(2.6rem, 4.4vw, 4.2rem); }

  /* The bill gets the full roll, so a 24 act roster uses fewer, longer
     lines instead of stacking into a column. */
  .bill--dense .bill__support,
  .bill--mid   .bill__support{ font-size:clamp(1.3rem, 1.9vw, 2.05rem); max-width:none; }
  .bill__head{ font-size:clamp(3.4rem, 6.4vw, 6.4rem); }

  /* Six across for the grounds, which at 1500px is a comfortable card
     rather than four wide ones with air inside them. */
  .fgrid{ grid-template-columns:repeat(3, 1fr); gap:38px 46px; }

  .glance{ grid-template-columns:repeat(4, 1fr); }
  .involve__roles{ gap:14px; }
}

@media (min-width:1400px){
  .fgrid{ grid-template-columns:repeat(4, 1fr); }
  .stub__body{ padding:88px 78px 94px; }
}

/* Venue address under the Where cell, and the tier-name list used by the
   external ticketing mode (names only, never prices). */
.glance__addr{ display:block; margin-top:4px; line-height:1.35; }
.notice__tiers{
  list-style:none; margin:18px 0 0; padding:0;
  display:flex; flex-wrap:wrap; justify-content:center; gap:8px 10px;
}
.notice__tiers li{
  border:2px solid var(--edge); padding:6px 12px;
  font-size:.68rem; font-weight:900; letter-spacing:.1em; text-transform:uppercase;
}

/* ---------------------------------------------------------------------
   PROSE
   Used only by privacy.html. Running text needs a measure; the festival
   page has almost none, which is why this did not exist until now.
   --------------------------------------------------------------------- */
.prose{ max-width:68ch; margin:0 auto; }
.prose h2{
  margin:30px 0 10px; font-family:var(--display);
  font-size:clamp(1.05rem,4vw,1.35rem); line-height:1.15;
  letter-spacing:.01em; text-transform:uppercase; color:var(--ink);
}
.prose h2:first-child{ margin-top:0; }
.prose p{ margin:0 0 14px; color:var(--ink-mute); }
.prose a{ color:var(--ink); text-decoration:underline; text-underline-offset:3px; }
.prose a:hover{ color:var(--accent); }
.prose b{ color:var(--ink); }
.prose__links{ display:flex; flex-wrap:wrap; gap:10px 22px; }
.prose__back{ margin:34px 0 0; text-align:center; }
@media (min-width:1100px){
  .prose{ max-width:72ch; }
  .prose h2{ margin-top:38px; }
}

/* Build credit. Deliberately quieter than .foot__presented above it: that is
   the organizers' credit on their own festival, this is the vendor's. */
.foot__credit{
  margin:14px 0 0;
  font-size:.62rem; letter-spacing:.12em; text-transform:uppercase;
  color:rgba(242,231,205,.32);
}
.foot__credit a{ color:inherit; text-decoration:none; border-bottom:1px solid transparent; }
.foot__credit a:hover, .foot__credit a:focus-visible{ color:var(--gold-lt); border-bottom-color:currentColor; }

/* Lineup disclaimer. Fine print under the bill, not a stamp. */
.bill__fine{
  margin:10px 0 0; text-align:center;
  font-size:.62rem; letter-spacing:.14em; text-transform:uppercase;
  color:var(--ink-mute); opacity:.75;
}
