/* Batch 33 (2026-10-03): site-wide motion and button system. Enqueued on every public route after batch 28.
   Groups:
   C1a reveal system (data-reveal and data-reveal-child)   C1b button states for the whole button family
   C7  footer address is a map link
   Motion rules: opacity, translate, filter, transform and box-shadow only. Reduced motion and ?static=1 show everything, nothing moves.
   The Shopping Guide keeps its own batch 31 reveal (data-gd31); no element carries both hooks. */

:root{--rv33-ease:cubic-bezier(.2,.7,.2,1)}

/* ---------- C1a. Reveal: opacity 0 to 1, 24px rise, 6px blur clear, 650ms, one time, 80ms stagger by CSS index ---------- */
/* Hidden start state exists only when the head guard added html.rv33-js (not for reduced motion, not for ?static=1, not without IntersectionObserver).
   data-reveal animates its own element. data-reveal="group" animates only its data-reveal-child descendants, which rise with the stagger once the group is visible.
   The individual translate property is used, never transform, so tilts and hover transforms on the same element stay intact. */
html.rv33-js [data-reveal]:not([data-reveal="group"]):not(.is-in),
html.rv33-js [data-reveal-child]{opacity:0;translate:0 24px;filter:blur(6px)}
/* The older site reveal (site-family.js, data-site-reveal on every .journey-section, .om-site-community>section and the like) must not stack on top of this one.
   Any element that carries a batch 33 hook, and any section that contains one, is released from the older reveal so each region animates once. */
html.rv33 body.om-mvp :is([data-reveal],section:has([data-reveal],[data-reveal-child]))[data-site-reveal]{opacity:1;transform:none;transition:none}
/* The visible state carries the transition list. Hover transitions are repeated so a revealed card keeps its own lift and ring easing. */
html.rv33-js body.om-mvp [data-reveal].is-in:not([data-reveal="group"]),
html.rv33-js body.om-mvp [data-reveal].is-in [data-reveal-child]{
  transition:opacity 650ms var(--rv33-ease) var(--rv33-d,0ms),translate 650ms var(--rv33-ease) var(--rv33-d,0ms),filter 650ms var(--rv33-ease) var(--rv33-d,0ms),
    transform 160ms ease,box-shadow 160ms ease,background-color 160ms ease,border-color 160ms ease;
}
html.rv33-js body.om-mvp [data-reveal].is-in [data-reveal-child]{opacity:1;translate:0 0;filter:none}
/* Stagger: 80ms per step by a CSS index variable. Only the children of a [data-reveal-stagger] container get an index, so a lone section never waits.
   The index is reset on every hooked element because custom properties inherit. */
[data-reveal],[data-reveal-child]{--rv33-i:0;--rv33-d:calc(var(--rv33-i) * 80ms)}
[data-reveal-stagger]>:nth-child(2){--rv33-i:1}
[data-reveal-stagger]>:nth-child(3){--rv33-i:2}
[data-reveal-stagger]>:nth-child(4){--rv33-i:3}
[data-reveal-stagger]>:nth-child(5){--rv33-i:4}
[data-reveal-stagger]>:nth-child(6){--rv33-i:5}
/* The About page already uses its own data-reveal and .is-in for masked word reveals (batch 23). The guard below is not output on that route, so every rule
   in this group stays inert there. */
/* Failsafe: if the script never runs, the guarded start state clears itself after 3 seconds. */
html.rv33-js:not(.rv33-ready) :is([data-reveal]:not([data-reveal="group"]),[data-reveal-child]){animation:rv33-failsafe 1ms linear 3s forwards}
@keyframes rv33-failsafe{to{opacity:1;translate:0 0;filter:none}}
/* ---------- C1b. Buttons: the whole button family gets the same 160ms states ----------
   Family = .om-btn--primary and --secondary (also spelled -primary and -secondary), .journey-button, the batch 17 S2 siblings
   (.ticket-action .hm12-btn .album-gift-browse .om-site-call-button .om17-btn .om17-btn-secondary .editorial-actions links) and the ticket card links.
   Header Get Tickets (.om-site-ticket) is not in the family and is unchanged. Rounded rectangles stay 10px (rules from batch 17 are not touched). */
body.om-mvp :is(.om-btn--primary,.om-btn--secondary,.om-btn-primary,.om-btn-secondary,.journey-button,.ticket-action,.hm12-btn,.album-gift-browse,.om-site-call-button,.om17-btn,.om17-btn-secondary,.editorial-actions a){transition:transform 160ms ease,box-shadow 160ms ease!important}
body.om-mvp :is(.om-btn--primary,.om-btn--secondary,.om-btn-primary,.om-btn-secondary,.journey-button,.ticket-action,.hm12-btn,.album-gift-browse,.om-site-call-button,.om17-btn,.om17-btn-secondary,.editorial-actions a):hover{transform:translateY(-1px)!important;box-shadow:0 0 0 3px rgba(239,36,53,.28)!important}
body.om-mvp :is(.om-btn--primary,.om-btn--secondary,.om-btn-primary,.om-btn-secondary,.journey-button,.ticket-action,.hm12-btn,.album-gift-browse,.om-site-call-button,.om17-btn,.om17-btn-secondary,.editorial-actions a):active{transform:scale(.98)!important}
body.om-mvp :is(.om-btn--primary,.om-btn--secondary,.om-btn-primary,.om-btn-secondary,.journey-button,.ticket-action,.hm12-btn,.album-gift-browse,.om-site-call-button,.om17-btn,.om17-btn-secondary,.editorial-actions a):focus-visible{outline:3px solid #68f8b3!important;outline-offset:2px!important}
/* Ticket card links ("See full ticket details"). The Home chooser sets its own transition at specificity 0,4,1, so the selector is repeated to outrank it without !important. */
body.om-mvp .ticket-comparison-choice.ticket-comparison-choice.ticket-comparison-choice.ticket-comparison-choice{transition:transform 160ms ease,box-shadow 160ms ease,background-color 160ms ease,border-color 160ms ease;border-radius:10px}
body.om-mvp .ticket-comparison-choice:hover{transform:translateY(-1px)!important;box-shadow:0 0 0 3px rgba(239,36,53,.28)!important}
body.om-mvp .ticket-comparison-choice:active{transform:scale(.98)!important}
body.om-mvp .ticket-comparison-choice:focus-visible{outline:3px solid #68f8b3!important;outline-offset:2px!important}
@media(prefers-reduced-motion:reduce){
  body.om-mvp :is(.om-btn--primary,.om-btn--secondary,.om-btn-primary,.om-btn-secondary,.journey-button,.ticket-action,.hm12-btn,.album-gift-browse,.om-site-call-button,.om17-btn,.om17-btn-secondary,.editorial-actions a),
  body.om-mvp .ticket-comparison-choice.ticket-comparison-choice.ticket-comparison-choice.ticket-comparison-choice{transition:none!important}
}

/* ---------- C7. Footer address is the same map link as the Guide: Apple Maps, mint, Open in Maps label ---------- */
body.om-mvp footer.om-site-footer .om-site-maps{display:inline-flex;flex-wrap:wrap;align-items:baseline;align-content:center;column-gap:14px;min-height:44px;color:#68f8b3;text-decoration:none;font-weight:700}
body.om-mvp footer.om-site-footer .om-site-maps>span:first-child{text-decoration:underline;text-underline-offset:4px;text-decoration-thickness:2px}
body.om-mvp footer.om-site-footer .om-site-maps-label{font:700 12px/1.4 "OMHM Tomorrow",sans-serif;letter-spacing:.1em;text-transform:uppercase;color:#68f8b3}
body.om-mvp footer.om-site-footer .om-site-maps:hover>span:first-child{color:#fff}
body.om-mvp footer.om-site-footer .om-site-maps:focus-visible{outline:3px solid #68f8b3;outline-offset:2px;border-radius:4px}

/* ======================================================================================================================
   Batch 39 (2026-10-04): shared header and footer (templates/site-shell.php). Loaded on every public route after batch 28.
   H1 Get Tickets glyphs   H2 logo slot geometry   H3 header sizes   H4 anchor offsets from the measured header   H5 mobile drawer
   F1 footer brand column and columns
   The mark is a swappable slot: site-shell.php emits the artwork box as --om-logo-* variables on the header and the footer, and
   every size below is the VISIBLE artwork width (--om-brand-w), not the file box. Rounded rectangles only, no motion added.
   ====================================================================================================================== */

/* ---------- H1. Get Tickets: the Backline face has one weight (400). The shorthand asked for 700, so the browser faux-bolded it,
   a blurred black shadow sat in the eye of every "e", and macOS stem darkening fattened the strokes again. At 29px the eye of
   the Backline "e" is under one pixel wide even in the clean face, so it also needs the grayscale smoothing and a little size. ---------- */
body.om-mvp header.om-site-header .om-site-ticket{font-weight:400!important;font-synthesis:none;font-size:31px!important;padding-block:9px;letter-spacing:0;text-shadow:none!important;-webkit-text-stroke:0;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:geometricPrecision}

/* ---------- H2. Logo slot geometry. The anchor is exactly the opaque artwork box; the transparent padding of the file hangs outside it
   (pointer-events off on the image, so the padding never steals a click). ---------- */
:root{--om-header-h:130px}
body.om-mvp :is(header.om-site-header,footer.om-site-footer){--om-brand-w:270px;--om-brand-h:calc(var(--om-brand-w) * var(--om-logo-vy) / var(--om-logo-vx) / var(--om-logo-ar))}
body.om-mvp :is(header.om-site-header,footer.om-site-footer) .om-site-brand{display:flex;align-items:center;flex:none;box-sizing:border-box;width:var(--om-brand-w);max-width:100%;height:max(44px,var(--om-brand-h));margin:0;position:relative}
body.om-mvp :is(header.om-site-header,footer.om-site-footer) .om-site-brand img.om-site-logo{--om-logo-box-w:calc(var(--om-brand-w) / var(--om-logo-vx));display:block;flex:none;box-sizing:border-box;width:var(--om-logo-box-w)!important;max-width:none!important;height:auto!important;aspect-ratio:var(--om-logo-ar);object-fit:fill;margin:0 0 0 calc(var(--om-logo-box-w) * var(--om-logo-ox) * -1)!important;position:relative;top:calc(var(--om-logo-box-w) / var(--om-logo-ar) * (.5 - var(--om-logo-oy) - var(--om-logo-vy) / 2));pointer-events:none}
body.om-mvp :is(header.om-site-header,footer.om-site-footer) .om-site-brand:focus-visible{outline:3px solid #68f8b3;outline-offset:3px;border-radius:6px}

/* ---------- H3. Header sizes. Ruling 2026-10-04 (gate): the bigger patch. The mark (the plaid patch) leads the header, left aligned, with the links and
   Get Tickets centered on it. --om-brand-max-h is the patch's VISIBLE height (118px desktop, 96px phones), so the bar is 4px padding + patch + 4px padding
   + the 4px red border = 130px (108px on phones, 12.8 percent of an 844px screen). --om-brand-want is only a width ceiling for wide marks. To change the
   size, change --om-brand-max-h and the bar follows (header height = max-h + 12px). ---------- */
body.om-mvp header.om-site-header{padding-block:4px;align-items:center;--om-brand-max-h:118px;--om-brand-want:clamp(160px,calc(100vw - 975px),270px);--om-brand-w:min(var(--om-brand-want),calc(var(--om-brand-max-h) * var(--om-logo-vx) * var(--om-logo-ar) / var(--om-logo-vy)))}
@media(min-width:1101px) and (max-width:1229px){
  body.om-mvp header.om-site-header{--om-brand-want:clamp(160px,calc(100vw - 900px),270px)}
  body.om-mvp header.om-site-header .om-site-desktop a{min-width:0!important}
}
@media(min-width:761px) and (max-width:1100px){body.om-mvp header.om-site-header{--om-brand-want:clamp(176px,23vw,240px)}}
@media(max-width:760px){
  :root{--om-header-h:108px}
  /* The bigger bar costs 28px of the first screen on a phone. Taking 18px back from the gap under it keeps the Home actions (See tickets, Plan your visit) inside an 844px first screen. */
  body.om-mvp header.om-site-header{--om-brand-max-h:96px;--om-brand-want:clamp(112px,39vw,190px);margin-bottom:6px}
}
@media(max-width:600px){
  body.om-mvp header.om-site-header .om-site-menu{width:64px}
  body.om-mvp header.om-site-header .om-site-ticket{font-size:clamp(16px,5.4vw,20.8px)!important;padding:6px clamp(6px,2.4vw,10px)}
}
@media(max-width:360px){body.om-mvp header.om-site-header{--om-brand-want:clamp(112px,37vw,190px);padding-inline:10px;gap:4px}body.om-mvp header.om-site-header .om-site-menu{width:56px}}

/* ---------- H4. Anchor offsets. The header is sticky, so every hash target, skip-link target and focused control keeps clear of it.
   --om-header-h is written by site-family.js from the real header box (ResizeObserver); the value above is only the first-paint fallback.
   Older per-section scroll-margin values and the Holiday html scroll-padding are replaced, not added to. ---------- */
html:root{scroll-padding-top:0!important}
html body.om-mvp [id]{scroll-margin-top:calc(var(--om-header-h) + 16px)!important}
html body.om-mvp :is(a[href],button,input,select,textarea,summary,[tabindex]):not(header.om-site-header *){scroll-margin-top:calc(var(--om-header-h) + 12px)!important}

/* ---------- H5. Menu drawer (phones and the 761 to 1100 menu range): it overlays the page (nothing is pushed), clears the header border,
   is never taller than the space under the header, and scrolls inside itself if it must. ---------- */
@media(max-width:1100px){
  body.om-mvp header.om-site-header .om-site-menu nav{top:calc(100% + 8px);max-height:calc(100dvh - var(--om-header-h) - 24px);overflow-y:auto;overscroll-behavior:contain;box-shadow:0 18px 40px #000c}
}

/* ---------- F1. Footer: a stronger brand column (large mark, date, venue, map, email) beside two aligned link columns, tighter spacing.
   Mobile order is brand and contact, then navigation, then help and legal, then the closing line. ---------- */
body.om-mvp footer.om-site-footer{--om-brand-w:clamp(180px,46vw,240px);grid-template-columns:minmax(0,1.45fr) minmax(0,1fr) minmax(0,1fr);column-gap:clamp(28px,4vw,64px);row-gap:16px;align-items:start;padding:30px clamp(20px,4vw,56px) 22px}
body.om-mvp footer.om-site-footer .om-site-footer-brand{display:flex;flex-direction:column;align-items:flex-start;gap:0;padding-right:clamp(0px,3vw,40px);border-right:1px solid #ef243559}
body.om-mvp footer.om-site-footer .om-site-footer-brand p{margin:10px 0 2px;font-size:15px;line-height:1.6}
body.om-mvp footer.om-site-footer :is(.om-site-footer-explore,.om-site-footer-legal){gap:0;margin-top:0}
body.om-mvp footer.om-site-footer :is(.om-site-footer-explore,.om-site-footer-legal) a{min-height:44px;line-height:1.3}
body.om-mvp footer.om-site-footer .om-site-footer-note{margin:2px 0 0;padding-top:14px;line-height:1.6}
@media(max-width:1000px){
  body.om-mvp footer.om-site-footer{grid-template-columns:1fr 1fr;column-gap:24px}
  body.om-mvp footer.om-site-footer .om-site-footer-brand{grid-column:1/-1;padding-right:0;padding-bottom:14px;border-right:0;border-bottom:1px solid #ef243559}
  body.om-mvp footer.om-site-footer :is(.om-site-footer-explore,.om-site-footer-legal){margin-top:0}
}
@media(max-width:760px){
  body.om-mvp footer.om-site-footer{grid-template-columns:1fr 1fr;column-gap:16px;row-gap:6px;padding:26px 20px 20px;margin-top:28px}
  body.om-mvp footer.om-site-footer .om-site-footer-brand{grid-column:1/-1;padding-right:0;padding-bottom:14px;border-right:0;border-bottom:1px solid #ef243559}
  body.om-mvp footer.om-site-footer :is(.om-site-footer-explore,.om-site-footer-legal){grid-column:1/-1;display:grid;grid-template-columns:1fr 1fr;column-gap:16px;margin-top:0}
  body.om-mvp footer.om-site-footer .om-site-footer-explore a:nth-last-child(2){grid-column:1/-1}
  body.om-mvp footer.om-site-footer .om-site-footer-legal{border-top:1px solid #ffffff22;margin-top:6px;padding-top:6px}
}

/* ---------- Wave E (2026-10-07, Justin's walkthrough H1): the header carries the wide OHIO [state] MADE lockup again (the tall badge moved to the footer and the Home hero).
   Same rule as H3: --om-brand-max-h is the lockup's VISIBLE height, the bar is that plus 12px (the 80px minimum height below still holds), --om-brand-want is the width ceiling. ---------- */
body.om-mvp header.om-site-header.om-site-header--wide{--om-brand-max-h:66px;--om-brand-want:clamp(240px,calc(100vw - 950px),350px)}
@media(min-width:1101px) and (max-width:1229px){body.om-mvp header.om-site-header.om-site-header--wide{--om-brand-want:clamp(240px,calc(100vw - 880px),350px)}}
@media(min-width:761px) and (max-width:1100px){body.om-mvp header.om-site-header.om-site-header--wide{--om-brand-want:clamp(200px,28vw,280px)}}
@media(max-width:760px){body.om-mvp header.om-site-header.om-site-header--wide{--om-brand-max-h:44px;--om-brand-want:clamp(104px,calc(78vw - 140px),230px);margin-bottom:6px}}
