/* A Spell in the Sky — site styles
 * Design: "Mock A2 Hybrid" (design-round2-20260825), approved by Hiro 2026-08-25 — plum/cream/pink
 * washi-paper palette, Ropa Sans display headings, Baloo 2 for the hero's flyer-cut lettering,
 * Open Sans / Hiragino Kaku Gothic ProN body stack (matches the live WordPress site's own stack).
 * No Japanese type anywhere — gated by build/verify_site.js.
 * Ported from outputs/design-round2-20260825/{mock_a2_hybrid,artists_a2,info_a2}.html, whose
 * three inline <style> blocks are merged and deduped here into one shared stylesheet.
 */

@font-face {
  font-family: 'Harlow';
  src: url('/assets/a2/harlow_solid_std_regular-webfont.woff2?v=c49d9616') format('woff2');
  font-display: swap;
}

:root {
  --plum:      #440836;
  --plum-deep: #33062a;
  /* Hiro, 30 Aug: 'add a little more pink to the brown/purple banner'. --plum mixed ~18%
     toward --pink, so the dark bands read as plum rather than brown. Cream stays legible
     on it — measured, not assumed; see the contrast checks in verify_site.js. */
  --plum-pink: #5c1046;
  --pink:      #c62a8c;
  --pink2:     #df3f8a;
  --pink3:     #e25b73;
  --rose:      #9a3253;
  --panel:     #6e2440;
  --cream:     #e9e2d5;
  --cream-2:   #f4efe6;
  --ink:       #2c0f22;
  --maxw:      1080px;
  --radius:    6px;
  --radius-lg: 8px;
  /* default before site.js measures the preview banner (or the --live build, which never
     renders one at all) — see the .nav rule and site.js's banner block. */
  --banner-h:  0px;
  font-size: 16px;
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; scrollbar-color: var(--rose) var(--cream-2); scrollbar-width: thin; }
body {
  margin: 0;
  background: var(--cream-2);
  color: var(--ink);
  font-family: 'Hiragino Kaku Gothic ProN', 'Hiragino Sans', 'Open Sans', sans-serif;
  line-height: 1.5;
  overflow-x: hidden;
}
img { max-width: 100%; display: block; }
h1, h2, h3, p, ul { margin: 0; }
ul { padding: 0; list-style: none; }
a { color: inherit; text-decoration: none; }
::selection { background: var(--pink2); color: #fff; }
a:focus-visible, button:focus-visible, input:focus-visible, textarea:focus-visible {
  outline: 2px solid var(--pink2); outline-offset: 3px; border-radius: 4px;
}
.disp { font-family: 'Baloo 2', sans-serif; font-weight: 800; }

.wrap { max-width: var(--maxw); margin: 0 auto; padding: 0 24px; }

.skip {
  /* Off-canvas VERTICALLY, not horizontally — an offscreen-left skip link (the common pattern)
     reads as a real horizontal-overflow element to any gate that walks the DOM for boxes
     outside the viewport, even though nothing actually scrolls. Top keeps the same "invisible
     until focused" behaviour without that false positive. */
  position: absolute; left: 12px; top: -60px; z-index: 200;
  background: var(--plum-deep); color: #fff; padding: 12px 18px; border-radius: 0 0 var(--radius-lg) var(--radius-lg);
  transition: top .15s ease;
}
.skip:focus { top: 0; }

.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* ---------------------------------------------------------------------------
   Buy buttons — the washi-photo pill, everywhere on the site
--------------------------------------------------------------------------- */
.btn-buy {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  /* a translucent plum scrim under the washi photo — the raw image's pink-to-red ramp measured
     as low as 3.26:1 for the white label in its lightest patches (verify_site.js's button
     legibility gate, run on the rendered page); the scrim keeps the texture visible while
     giving the label enough to work with everywhere on the button, not just its darker end. */
  background-image: linear-gradient(rgba(51,6,42,.4), rgba(51,6,42,.4)), url("/assets/a2/btn_washi_flyer.jpg?v=f324c943");
  background-size: cover; background-position: center;
  color: #fff; font-weight: 800; font-size: 19px; letter-spacing: .03em;
  padding: 11px 22px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,.3);
  white-space: nowrap;
}
.btn-buy:hover { filter: brightness(1.08); }
.btn-buy-sm { padding: 8px 18px; font-size: 15px; }

.btn-outline {
  display: inline-flex; align-items: center; justify-content: center;
  border: 1.5px solid var(--rose); color: var(--rose);
  font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase;
  letter-spacing: .06em; font-size: 15px;
  padding: 10px 20px; border-radius: 999px; white-space: nowrap;
}
.btn-outline:hover, .btn-outline:focus { background: var(--rose); color: #fff; }
.btn-outline--light { border-color: rgba(233,226,213,.6); color: var(--cream); }
.btn-outline--light:hover, .btn-outline--light:focus { background: rgba(233,226,213,.16); color: var(--cream); }

/* ---------------------------------------------------------------------------
   Nav — fixed, transparent-to-plum gradient over the hero
--------------------------------------------------------------------------- */
.nav {
  /* --banner-h is set by site.js to the preview banner's real height (0 once dismissed, or on
     the --live build where the banner never renders) so the fixed nav sits BELOW the banner
     instead of fighting it for the same pixels — a real bug the preview mode introduced that
     the approved mock (which never carries a banner) never had to solve. */
  position: fixed; top: var(--banner-h, 0px); left: 0; right: 0; z-index: 50;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 18px;
  padding: 14px 24px;
  background: linear-gradient(rgba(51,6,42,.55), rgba(51,6,42,0));
  transition: background .25s ease, box-shadow .25s ease;
}
/* Past the hero the gradient's transparent tail lets page content bleed through under the
   links (codex review 2026-08-26, BLOCKER 3 — visible in every mid-scroll capture). site.js
   toggles this class past ~60px; with scripting off the gradient stays, which is the same
   state the approved mock always had. */
.nav--scrolled {
  background: rgba(51,6,42,.96);
  box-shadow: 0 1px 8px rgba(0,0,0,.22);
}
.nav__mark { color:#fff; font-family:'Harlow', cursive; font-weight:400; font-size:24px; letter-spacing:.01em; display:inline-flex; align-items:center; gap:10px; white-space:nowrap; }
.nav__logo { height: 30px; width: auto; opacity: .95; }
.nav__links { display: flex; flex-wrap: wrap; gap: 26px; margin-left: auto; }
.nav__links a { color: #fff; font-size: 14px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; opacity: .92; }
.nav__links a:hover, .nav__links a[aria-current="page"] { opacity: 1; text-decoration: underline; text-underline-offset: 4px; }
.nav .btn-buy { padding: 8px 18px; font-size: 16px; }
/* Seven links now that WHO WE ARE (the longest label) joined the strip (Hiro 27 Aug: the page
   was footer-only). Full-size strip needs ~1140px; between 1040 and 1140 the labels tighten
   instead of wrapping the buy pill under the brand (render-measured: compact fits at 1050,
   still wraps at 990), and below 1040 the strip hides. */
@media (max-width: 1140px) {
  .nav__links { gap: 15px; }
  .nav__links a { font-size: 13px; letter-spacing: .05em; }
}
@media (max-width: 1040px) {
  .nav__links { display: none; }
  .nav__mark { font-size:19px; white-space: nowrap; gap: 8px; }
  .nav__logo { height: 24px; }
}

/* A non-hero page needs the same fixed nav to sit over a solid backer instead of the hero image;
   .nav-solid gives every interior-page body the gradient a resting place before .phead starts. */
.nav-solid-spacer { height: 0; }

/* ---------------------------------------------------------------------------
   Who we are — past-event blocks, live-parity (name, date, the live page's own photos)
--------------------------------------------------------------------------- */
.whoev { text-align: center; }
.whoev__name {
  font-family: 'Baloo 2', sans-serif; font-weight: 800;
  font-size: clamp(34px, 5.4vw, 56px); letter-spacing: .02em; color: var(--plum);
  line-height: 1.05;
}
.whoev__date { color: var(--rose); font-weight: 600; font-size: 16px; margin: 6px 0 26px; }
.whoev__grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
  gap: 14px; max-width: 980px; margin: 0 auto;
}
.whoev__tile { margin: 0; }
.whoev__tile img {
  width: 100%; height: 100%; object-fit: cover; aspect-ratio: 4 / 3;
  border-radius: var(--radius); display: block;
}
@media (max-width: 700px) {
  .whoev__grid { grid-template-columns: 1fr 1fr; gap: 10px; }
}

/* ---------------------------------------------------------------------------
   Hero — the flyer as layered paper (home page only)
--------------------------------------------------------------------------- */
.hero {
  position: relative;
  min-height: 100svh;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  padding: 110px 24px 96px;
  /* fallback matches the washi's average tone so white hero text stays readable
     during the seconds before the jpg arrives (slow links showed cream + ghost text) */
  background-color: #bf4d79;
  /* WebP halves the transfer (321 -> 176 KB at 1x, 584 -> 306 KB at 2x) with no visible loss of
     the paper grain, compared at 1:1. The plain url() above image-set() is a REAL fallback: a
     browser without image-set support never parses the second declaration and gets the jpg. */
  background-image: url("/assets/a2/hero_washi_real.jpg?v=9bb06e8f");
  background-image: image-set(url("/assets/a2/hero_washi_real.webp?v=68b81948") type("image/webp"),
                              url("/assets/a2/hero_washi_real.jpg?v=9bb06e8f")  type("image/jpeg"));
  background-size: cover; background-position: center top;
}
.hero__mark {
  position: absolute; left: 50%; top: 44%; transform: translate(-50%, -50%);
  width: min(72vh, 80vw); opacity: .15; pointer-events: none; user-select: none;
}
.hero__inner {
  position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 14px;
  width: 100%; max-width: 760px; text-align: center;
}
.hero::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  box-shadow: inset 0 -120px 140px rgba(44,6,34,.35), inset 0 80px 120px rgba(44,6,34,.18);
}
.hero__presents { color: #fff; font-weight: 700; font-size: 19px; letter-spacing: .14em; text-transform: uppercase; }
.cut { height: auto; filter: drop-shadow(0 10px 22px rgba(44,6,34,.45)); }
.cut--script { width: min(470px, 78vw); transform: rotate(-.5deg); }
.cut--nujabes { width: min(600px, 88vw); margin-top: 2px; filter: drop-shadow(0 16px 30px rgba(44,6,34,.55)); }
.cut--tribute { width: min(330px, 52vw); transform: rotate(.4deg); }
.t-block { display: flex; flex-direction: column; align-items: center; gap: 2px; }
.t-role {
  font-family: 'Baloo 2', sans-serif; font-weight: 600; color: var(--cream);
  text-transform: uppercase; letter-spacing: .22em; font-size: clamp(13px, 2vw, 16px);
  margin-top: 2px; text-shadow: 0 2px 0 rgba(44,6,34,.28);
}
.t-head {
  font-family: 'Baloo 2', sans-serif; font-weight: 800; color: var(--cream);
  text-transform: uppercase; line-height: .96; letter-spacing: .015em;
  text-shadow: 0 3px 0 rgba(44,6,34,.32), 0 -1px 0 rgba(255,255,255,.18), 0 16px 30px rgba(44,6,34,.5);
}
.t-head--sm { font-size: clamp(22px, 3.8vw, 34px); }
.hero__bill { display: flex; flex-direction: column; align-items: center; gap: 16px; margin-top: 8px; }
.hero__bill .cut--jeremy { width: min(430px, 68vw); }
.hero__bill .cut--mndsgn { width: min(235px, 44vw); }
.hero__bill .cut--teebs { width: min(180px, 35vw); }
.hero__bill .cut--graham { width: min(300px, 52vw); }
.hero__bill .cut--tsugu { width: min(205px, 38vw); }
.hero__facts { color: #fff; font-weight: 700; font-size: 19px; line-height: 1.55; margin-top: 14px; text-shadow: 0 1px 10px rgba(44,6,34,.35); }
.hero__cta { margin-top: 12px; display: flex; flex-direction: column; align-items: center; gap: 10px; }
.hero__cta .btn-buy { font-size: 19px; padding: 16px 34px; }
.hero__early { color: #fff; font-weight: 700; font-size: 19px; opacity: .94; }
.hero__spell { margin-top: 26px; color: #fff; font-weight: 600; font-size: 17px; font-style: italic; opacity: .95; max-width: 34ch; line-height: 1.6; }
.hero__tear, .tickets__tear, .practical__tear {
  position: absolute; left: 0; right: 0; bottom: -1px; height: 56px;
  background: url("/assets/a2/torn_cream.png?v=92985aaf") bottom/1600px 90px repeat-x;
  transform: scaleY(-1); pointer-events: none;
}
.practical__tear { background-image: url("/assets/a2/torn_plum.png?v=602bcf57"); }

@media (prefers-reduced-motion: no-preference) {
  .settle { opacity: 0; transform: translateY(18px); animation: settle .7s cubic-bezier(.16,1,.3,1) forwards; }
  .settle:nth-child(2) { animation-delay: .06s } .settle:nth-child(3) { animation-delay: .12s }
  .settle:nth-child(4) { animation-delay: .18s } .settle:nth-child(5) { animation-delay: .24s }
  .settle:nth-child(6) { animation-delay: .30s } .settle:nth-child(7) { animation-delay: .36s }
  .settle:nth-child(8) { animation-delay: .42s } .settle:nth-child(9) { animation-delay: .48s }
  .settle:nth-child(10) { animation-delay: .54s }
  @keyframes settle { to { opacity: 1; transform: none; } }
}

/* ---------------------------------------------------------------------------
   Section shell — generic band used site-wide
--------------------------------------------------------------------------- */
.section { padding: 76px 24px; }
.section__head { max-width: var(--maxw); margin: 0 auto 40px; }
.section__title {
  font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase;
  font-size: clamp(34px, 4.6vw, 52px); line-height: 1.05; color: var(--plum);
  letter-spacing: .01em; text-wrap: balance;
}
.section__sub { margin-top: 10px; font-size: 17px; font-weight: 500; color: var(--rose); }
.kicker {
  font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase;
  letter-spacing: .14em; font-size: 15px; color: var(--rose); margin-bottom: 8px; display: block;
}

/* ---------------------------------------------------------------------------
   Artists grid — home page (live's grid, A2's dress)
--------------------------------------------------------------------------- */
.artists { background: var(--cream-2); }
.artists__grid { max-width: var(--maxw); margin: 0 auto; display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.artist { display: flex; flex-direction: column; gap: 12px; }
.artist__photo { aspect-ratio: 1/1.08; overflow: hidden; border-radius: var(--radius); box-shadow: 0 12px 26px rgba(44,15,34,.22); background: #fff; }
.artist__photo img { width: 100%; height: 100%; object-fit: cover; }
.artist__name { font-weight: 700; font-size: 18px; letter-spacing: .04em; text-transform: uppercase; color: var(--plum); }
/* Hiro 27 Aug: the "presented by" line drops a step so the act name carries the card */
.artist__sub { font-size: 14px; font-weight: 600; letter-spacing: .05em; }
.artist__feat { font-size: 15px; font-weight: 600; color: var(--rose); line-height: 1.5; }
@media (max-width: 760px) { .artists__grid { grid-template-columns: repeat(2, 1fr); gap: 20px; } }

/* ---------------------------------------------------------------------------
   Tickets — live's cards in washi paper
--------------------------------------------------------------------------- */
.tickets { position: relative;
  background: linear-gradient(175deg, rgba(198,42,140,.22), rgba(198,42,140,.05) 52%, rgba(226,91,115,.17)),
              var(--plum-pink) url("/assets/a2/washi-mid.jpg?v=e63989d7");
  background-size: auto, 340px; background-blend-mode: normal, multiply; }
.tickets .section__title { color: var(--cream); }
.tickets .section__sub { color: var(--cream); opacity: .85; }
.tickets__grid { max-width: var(--maxw); margin: 0 auto; display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; align-items: stretch; }
.tier {
  background: linear-gradient(rgba(244,239,230,.9), rgba(244,239,230,.9)), url("/assets/a2/washi.jpg?v=d5181676");
  background-size: auto, 420px;
  border-radius: var(--radius-lg); padding: 26px 24px 24px;
  display: flex; flex-direction: column; gap: 14px;
  box-shadow: 0 18px 36px rgba(20,3,16,.4);
}
.tier__chips { display: flex; flex-wrap: wrap; gap: 6px; }
/* An EMPTY chip row still holds a chip's height wherever the cards sit side by side, so a
   card that has lost its tag keeps its heading and price on the same line as its neighbours.
   GA loses the "Early Bird" tag at the price changeover, and without this its title and $79
   rode 26px higher than VIP's and the table's -- measured, not guessed. Stacked on a phone
   there is nothing to align to, so the reserved space would just be a gap. The invariant is
   asserted by verify_site.js's tier-heading alignment gate; these numbers are only how it is
   currently achieved, and they track the chip metrics in the two rules below. */
@media (min-width: 761px) { .tier__chips { min-height: 26.5px; } }
.chip {
  font-size: 11px; font-weight: 700; letter-spacing: .05em; text-transform: uppercase;
  color: var(--cream); padding: 5px 10px; border-radius: 999px; background: var(--plum-deep);
  white-space: nowrap;
}
.chip--scarce { background: #6d1310; }
/* Tablet width (768px) is the tight case: three cards, two chips on the VIP card — this
   keeps "Best Value" + "Early Bird" on one row instead of wrapping to a second, which is
   what verify_site.js's tier-geometry gate requires. */
@media (min-width: 761px) and (max-width: 900px) {
  .tier { padding: 20px 16px 18px; }
  .chip { font-size: 9.5px; padding: 4px 8px; letter-spacing: .03em; }
  .tier__chips { min-height: 22.3px; }
}
.tier__name { font-weight: 700; font-size: 19px; letter-spacing: .05em; text-transform: uppercase; color: var(--plum); }
.tier__price { font-weight: 800; font-size: 36px; color: var(--rose); font-variant-numeric: tabular-nums; line-height: 1; }
.tier__price small { display: block; margin-top: 7px; font-size: 14px; font-weight: 600; color: var(--rose); letter-spacing: 0; line-height: 1.35; }
.tier__bullets { display: flex; flex-direction: column; gap: 7px; margin-bottom: 14px; }
.tier__bullets li { font-size: 16px; line-height: 1.5; padding-left: 18px; position: relative; }
.tier__bullets li::before {
  content: ""; position: absolute; left: 2px; top: .5em; width: 7px; height: 7px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--pink2), var(--pink));
}
.tier .btn-buy { margin-top: auto; background-image: url("/assets/a2/btn_zone_ga_v5.jpg?v=355e6464"); }
.tier--mid .btn-buy { background-image: url("/assets/a2/btn_zone_vip_v5.jpg?v=891d444b"); }
.tier--table .btn-buy { background-image: url("/assets/a2/btn_zone_table_v5.jpg?v=74b9f6ee"); }
.tickets__know { max-width: var(--maxw); margin: 44px auto 0; color: var(--cream); }
.tickets__know h3 { font-family: 'Ropa Sans', sans-serif; font-weight: 700; font-size: 19px; margin-bottom: 12px; }
.tickets__know li { font-size: 16px; line-height: 1.7; padding-left: 18px; position: relative; }
.tickets__know li::before {
  content: ""; position: absolute; left: 2px; top: .62em; width: 7px; height: 7px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--cream), var(--pink3));
}
.tickets__know a { text-decoration: underline; text-underline-offset: 3px; }
.tickets__checkout { margin-top: 18px; font-size: 15px; color: var(--cream); opacity: .8; max-width: 64ch; }
@media (max-width: 760px) { .tickets__grid { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------------------
   Vendor village — home AND vendors page share this component
--------------------------------------------------------------------------- */
.food { background: var(--cream-2); }
.food__grid { max-width: 1120px; margin: 0 auto; display: flex; flex-wrap: wrap; justify-content: center; gap: 26px 20px; }
/* Hiro, 30 Aug: change the layout of the Food Village tiles. The flat centred row put five
   equal boxes in a 3+2 that left the second row floating. A real grid instead, with the
   first tile — Chef Diego's Estrano, which the section's own line now leads with — taking
   two columns and two rows, so the block reads as one composition and the bottom edge is
   straight. Falls back to a plain two-up on narrow screens. */
.food__grid--feature {
  display: grid; grid-template-columns: repeat(4, 1fr); grid-auto-rows: 200px; align-items: stretch;
}
.food__grid--feature .vcard { width: auto; grid-column: span 1; grid-row: span 1; }
.food__grid--feature .vcard:first-child { grid-column: span 2; grid-row: span 2; }
/* The block is FOUR tiles since 31 Aug — the pending matcha/boba stand turned out to be the
   kakigori stand (Umacha), so two cards became one. Four columns minus the 2x2 feature leaves
   four cells for three tiles, which would hole the corner; the last tile takes two of them.
   Deliberately :last-child and not :nth-child(4) — it holds at the two-column breakpoint too,
   where it becomes a full-width bottom tile. If the vendor count ever returns to five this
   rule comes back out; nothing else in the grid depends on the count. */
.food__grid--feature .vcard:last-child { grid-column: span 2; }
.food__grid--feature .vcard,
.food__grid--feature .vcard__photo,
.food__grid--feature .vcard__photo .vph { height: 100%; width: 100%; object-fit: cover; }
@media (max-width: 900px) {
  .food__grid--feature { grid-template-columns: repeat(2, 1fr); grid-auto-rows: 170px; }
  .food__grid--feature .vcard:first-child { grid-column: span 2; grid-row: span 1; }
}
.vcard { width: 336px; max-width: 100%; }
/* Home-page tiles (Hiro 27 Aug): the picture IS the link into the Food Village page —
   no hover overlay, no captions. The span keeps the __photo block styling. */
.vcard--photolink { display: block; text-decoration: none; }
.vcard--photolink .vcard__photo { display: block; }
.food__more { text-align: center; margin: 30px 0 0; }
.food__more a { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase;
  letter-spacing: .1em; font-size: 15px; color: var(--plum-deep); text-underline-offset: 4px; }
.vcard__photo { position: relative; aspect-ratio: 1/1; overflow: hidden; border-radius: var(--radius); box-shadow: 0 12px 26px rgba(44,15,34,.22); cursor: pointer; }
.vcard__photo > img.vph { width: 100%; height: 100%; object-fit: cover; display: block; transition: transform .5s ease; }
.vcard__photo:hover > img.vph { transform: scale(1.05); }
.vcard__hover {
  position: absolute; inset: 0; opacity: 0; transition: opacity .35s ease;
  background: linear-gradient(rgba(244,239,230,.94), rgba(244,239,230,.94)), url("/assets/a2/washi.jpg?v=d5181676");
  background-size: cover; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; padding: 28px 26px; text-align: center;
}
.vcard__photo:hover .vcard__hover, .vcard__photo:focus-visible .vcard__hover, .vcard__photo.is-open .vcard__hover { opacity: 1; }
.vcard__hover img { max-width: 52%; max-height: 42%; object-fit: contain; }
/* the vendor's logo rides INSIDE the photo (Hiro 2026-08-26), a small paper chip */
.vcard__badge {
  position: absolute; left: 12px; bottom: 12px;
  background: rgba(255,255,255,.94); border-radius: var(--radius-lg);
  padding: 6px 10px; box-shadow: 0 4px 12px rgba(44,15,34,.25);
  display: flex; align-items: center; justify-content: center; pointer-events: none;
}
.vcard__badge img { height: 52px; width: auto; max-width: 170px; object-fit: contain; display: block; }
.vcard__pitch { font-family: 'Hiragino Kaku Gothic ProN', 'Hiragino Sans', 'Open Sans', sans-serif; font-size: 14.5px; line-height: 1.55; color: var(--ink); margin: 0; }
.vcard__name { margin: 14px 0 2px; text-align: center; font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; letter-spacing: .06em; font-size: 18px; color: var(--plum-deep); }
.vcard__kind { margin: 0; text-align: center; font-size: 13.5px; color: var(--rose); font-family: 'Hiragino Kaku Gothic ProN', 'Hiragino Sans', 'Open Sans', sans-serif; }
.vcard__plate {
  position: absolute; inset: 0;
  background: linear-gradient(rgba(244,239,230,.92), rgba(244,239,230,.92)), url("/assets/a2/washi.jpg?v=d5181676");
  background-size: cover; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 14px; padding: 26px;
}
.vcard__plate img { max-width: 62%; max-height: 52%; object-fit: contain; }
.vcard--tbd .vcard__q {
  width: 88px; height: 88px; border-radius: 50%;
  background: radial-gradient(circle at 35% 35%, var(--pink2), var(--pink));
  display: flex; align-items: center; justify-content: center;
  color: #fff; font-family: 'Ropa Sans', sans-serif; font-weight: 600; font-size: 44px;
}
.vcard--tbd .vcard__soon { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; letter-spacing: .14em; font-size: 13px; color: var(--plum-deep); margin: 0; }
@media (max-width: 760px) { .vcard { width: min(336px, 86vw); } }

/* Set times — pre-built for Miwa's running order (26 Aug call, fix #2); renders only
   when SHOW_SET_TIMES is on in the builder. */
.settimes { padding: 70px 24px 60px; max-width: 720px; margin: 0 auto; }
.settimes__title { font-family: 'Ropa Sans', sans-serif; font-weight: 600; color: var(--plum-deep); font-size: clamp(34px, 5vw, 52px); line-height: 1.02; text-align: center; margin: 0 0 28px; }
.settimes__list { list-style: none; margin: 0; padding: 0; }
.settimes__row { display: flex; gap: 18px; align-items: baseline; padding: 13px 6px; border-bottom: 1px solid rgba(51, 6, 42, .18); }
.settimes__time { font-family: 'Ropa Sans', sans-serif; font-weight: 600; min-width: 100px; color: var(--plum-deep); font-size: 18px; }
.settimes__act { font-size: 18px; color: #2a1420; }
.settimes__note { text-align: center; color: #6b4a5e; font-size: 14px; margin-top: 18px; }

/* ---------------------------------------------------------------------------
   Buy band + enquiries + playlist + footer
--------------------------------------------------------------------------- */
.buyband { position: relative;
  background: linear-gradient(175deg, rgba(198,42,140,.26), rgba(198,42,140,.07) 55%, rgba(226,91,115,.20)),
              var(--plum-pink) url("/assets/a2/washi-mid.jpg?v=e63989d7");
  background-size: auto, 340px; background-blend-mode: normal, multiply;
  padding: 80px 24px; text-align: center; }
/* Hiro, 30 Aug: the bottom banner takes the live site's own CTA photograph and its wordmark.
   who/cta_band.jpg is that frame — the magenta-lit DJ set with the line array and the crowd
   in silhouette, already in the mirror from the who-we-are port. The scrim is the same plum
   and pink he asked for on the flat version an hour earlier, so the band still reads as part
   of this palette rather than as a photograph dropped in. Cream is measured against it. */
/* Hiro, 31 Aug: "add a little more pink to make it lighter. add a little washi texture (but
   not as pronounced as the Hero page)". Two separate moves: (1) the scrim itself moves off
   near-black (28,5,22) onto --plum-pink (92,16,70), and the linear-gradient's top stop
   swaps to --pink (198,42,140) — same alpha discipline as before, just a lighter, pinker
   hue doing the darkening instead of near-black. (2) a washi layer sits BETWEEN the scrim
   and the photograph, multiply-blended so it only tints/grains the photo rather than
   replacing it — the hero's washi is the whole background at full strength; this is a
   340px tile at multiply, which is categorically subtler. washi-MID, not plain washi.jpg:
   measured average pixel of washi.jpg is a neutral (128,128,128) grey, and multiplying a
   background by a mid-grey darkens it by half — that 50% darkening is what was reading as
   "brown" on the countdown strip below (band #3) even after that strip's base already
   moved to --plum-pink. washi-mid.jpg averages (220,81,149), almost exactly --pink2
   (223,63,138): multiplying by a channel that light barely darkens the photo (~15%) and
   carries its own pink tint into the grain, which is the "little more pink" and the
   "little washi" in one file. */
.buyband--photo {
  background:
    radial-gradient(ellipse 62% 130% at 50% 42%, rgba(92,16,70,.72), rgba(92,16,70,.22) 72%, rgba(92,16,70,0)),
    linear-gradient(rgba(198,42,140,.22), rgba(92,16,70,.42)),
    url("/assets/a2/washi-mid.jpg?v=e63989d7") center / 340px repeat,
    url("/assets/img/who/cta_band.jpg?v=4dda8598") center 42% / cover no-repeat;
  background-blend-mode: normal, normal, multiply, normal;
}
.buyband__mark {
  font-family: 'Harlow', cursive; font-weight: 400; color: var(--cream);
  font-size: clamp(38px, 6.4vw, 78px); line-height: 1.02; margin-bottom: 6px;
  text-shadow: 0 2px 18px rgba(20,4,16,.55);
}
.buyband--photo .buyband__title { text-shadow: 0 2px 14px rgba(20,4,16,.5); }
@media (max-width: 640px) { .buyband__mark { font-size: clamp(30px, 9vw, 46px); } }
.buyband__title { font-family: 'Ropa Sans', sans-serif; font-weight: 600; color: var(--cream); font-size: clamp(38px, 6vw, 64px); line-height: 1.02; letter-spacing: .01em; text-wrap: balance; }
/* the info page's closing buyband borrows the flyer's script instead (design-round2 info_a2.html) */
.buyband__title--script { font-family: 'Harlow', cursive; font-weight: 400; font-size: clamp(28px, 4vw, 42px); margin-bottom: 4px; }
.buyband .btn-buy { margin-top: 26px; font-size: 19px; padding: 16px 38px; }
.buyband__early { margin-top: 14px; color: var(--cream); font-weight: 700; font-size: 19px; opacity: .92; }
/* A stand-in product photograph says so on the card. Small, bottom-left, out of the way
   of the hover panel — but never absent, because the image otherwise reads as the
   vendor's own food (Hiro, 27 Aug: kakigori + matcha placeholders). */
/* 12.5px, not the 11px this shipped at: it broke the site's own no-text-under-12px floor on
   both surfaces at all three widths, and went unseen because the rendered phase that checks
   the floor had been hanging. This label is the only thing telling a ticket buyer the photo
   is not that vendor's food, so it is the last text on the page that should be squinted at. */
.vcard__stock { position: absolute; left: 10px; bottom: 10px; z-index: 2;
  font-family: 'Ropa Sans', sans-serif; font-size: 12.5px; letter-spacing: .07em;
  text-transform: uppercase; color: var(--cream); background: rgba(44,15,34,.72);
  padding: 4px 9px; border-radius: 3px; pointer-events: none; }

/* ---- Invitation + story sections (restored from the 23 Aug build, 27 Aug) -------------
   The A2 rework dropped every line that explained the festival. These carry it back, in
   the page's existing vocabulary — same kicker/title scale, same reveal, same washi. */
.section__kick { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase;
  font-size: 13px; letter-spacing: .14em; color: var(--rose); margin-bottom: 10px; }
.section__lede { margin-top: 12px; font-size: 17.5px; line-height: 1.7; color: var(--ink);
  opacity: .88; max-width: 46em; }
.tickets .section__lede { color: var(--cream); }

.vision { background: linear-gradient(rgba(244,239,230,.94), rgba(244,239,230,.94)),
  url("/assets/a2/washi.jpg?v=d5181676"); background-size: 420px; }
.vision__grid { max-width: var(--maxw); margin: 0 auto; display: grid;
  grid-template-columns: 1fr 1fr; gap: 46px; align-items: start; }
.vision__pull { margin-top: 16px; font-size: 19px; line-height: 1.65; color: var(--rose);
  font-weight: 600; }
.vision__body p { font-size: 16.5px; line-height: 1.78; color: var(--ink); margin-bottom: 15px;
  max-width: 54ch; }
.vision__cta { margin-bottom: 0; }
.vision__cta a { font-weight: 700; color: var(--pink); text-decoration: underline;
  text-underline-offset: 4px; }

.story__grid { max-width: var(--maxw); margin: 30px auto 0; display: grid;
  grid-template-columns: repeat(3, 1fr); gap: 22px; }
.story__card { display: block; text-decoration: none; }
/* These tiles hold FLYERS now (Hiro, 28 Aug), and a flyer is a designed object with its own
   name, bill and date set right to its edges — so they are matted rather than cropped. A
   cover-crop is what a photograph wants; here it destroys the thing the tile exists to show.
   Measured before choosing: City Pop Night's flyer is square (900x900), Moon in the Sky's is
   900x1129 and ennichi '25's 694x900. Cover-cropping the square one into a portrait tile
   takes 12.5% off each side, which cuts through "CITY" and "NIGHT" in the title.
   5/6 is the ratio that keeps the mat narrow for all three at once: the two portrait flyers
   sit almost edge to edge, and the square one gains a plum band top and bottom that reads as
   matting. The ground is --plum-deep because every one of these posters is dark and saturated;
   on the cream page a light mat would glare around them. */
.story__photo { display: block; overflow: hidden; border-radius: var(--radius-lg);
  aspect-ratio: 5 / 6; background: var(--plum-deep); }
.story__photo img { width: 100%; height: 100%; object-fit: contain; display: block;
  transition: filter .25s ease; }
.story__card:hover .story__photo img { filter: brightness(1.06); }
.story__name { display: block; margin-top: 12px; font-family: 'Ropa Sans', sans-serif;
  font-weight: 600; text-transform: uppercase; letter-spacing: .03em; font-size: 17px;
  color: var(--ink); }
.story__meta { display: block; margin-top: 3px; font-size: 14px; color: var(--rose); }

@media (max-width: 860px) {
  .vision__grid { grid-template-columns: 1fr; gap: 26px; }
  .story__grid { grid-template-columns: 1fr; gap: 26px; }
}

/* the playlist leads the pre-footer — big Spotify mark, like live's (design-round2, 2026-08-26) */
/* Hiro, 27 Aug: "the red is really red. Make this washi texture with the same color
   combination as the flyer." The player is a CROSS-ORIGIN iframe, so its interior cannot be
   restyled from here — that red is Spotify extracting the dominant colour of the playlist
   artwork (measured rgb(159,0,0)). Two things are done instead: the embed src carries
   theme=0, which drops the artwork colour for a neutral ground (measured rgb(31,31,31)),
   and the band + frame below carry the washi and the flyer palette. Repainting the player
   itself in plum needs the PLAYLIST COVER changed on Spotify — that is the only lever that
   moves the colour Spotify extracts. */
/* Hiro, 31 Aug: the playlist sits ON the photograph now, inside .buyband--playlist. First
   pass gave the frame one flat colour instead of the washi; Hiro looked again same day and
   said "lose the frame. Keep the icon one color" — confirmed on a second pass: "yes, lose
   the frame completely", no thin flat-colour edge left as a compromise. So the frame is
   GONE outright: no padding, no border, no box-shadow, no background panel — the player
   sits directly on the photograph behind it. "Keep the icon one color" is a constraint on
   ANY chrome that might reappear here later, not license to bring padding/background back
   as long as it is flat. The icon and the "A Spell in the Sky — the official playlist" line
   beneath stay gone, per the same 31 Aug instruction. */
.buyband--playlist { padding-bottom: 64px; }
.buyband__player { max-width: 860px; margin: 44px auto 0; }
.playlistband__embed { display: block; }
.playlistband__embed iframe { display: block; }
.enquiries__amb { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; font-size: 14px; letter-spacing: .12em; color: var(--rose); margin-bottom: 10px; }
.enquiries__amb span { color: var(--pink2); }
.enquiries { background: var(--cream-2); border-top: 1px solid rgba(154,50,83,.18); text-align: center; padding: 26px 24px 30px; }
.enquiries p { font-size: 15.5px; line-height: 1.6; color: var(--ink); }
.enquiries a { color: var(--pink); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
.enquiries span[aria-hidden] { color: var(--pink2); margin: 0 10px; }

.foot { background: linear-gradient(180deg, #40092f, var(--plum-deep) 42%, #250420);
        color: var(--cream); padding: 56px 0 0; }
.foot-in { display: grid; grid-template-columns: 1.3fr 1fr 1fr; gap: 40px; padding-bottom: 40px; }
.foot-in h4 {
  font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; letter-spacing: .1em;
  font-size: 14px; color: var(--pink3); margin: 0 0 14px;
}
.foot-in .brand {
  font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; letter-spacing: .02em;
  font-size: 22px; color: #fff;
}
.foot-in ul { display: flex; flex-direction: column; gap: 9px; }
.foot-in a { font-size: 15px; opacity: .88; }
.foot-in a:hover { opacity: 1; text-decoration: underline; text-underline-offset: 3px; }
.foot-meta {
  display: flex; flex-wrap: wrap; gap: 8px 22px; justify-content: space-between;
  padding: 20px 0 26px; border-top: 1px solid rgba(233,226,213,.16);
  font-size: 13px; opacity: .7;
}
@media (max-width: 760px) { .foot-in { grid-template-columns: 1fr; gap: 30px; } }

/* ---------------------------------------------------------------------------
   Early-bird countdown strip
--------------------------------------------------------------------------- */
/* Hiro, 31 Aug, first pass: "change the brownish color of the banner up top to match more
   of the purple/magenta color base used elsewhere". The brown was --panel #6e2440
   multiplied with the WARM washi scan; both were the warm half of the palette. --plum-pink
   over washi.jpg was the fix attempted here — same family as the tickets band. He looked
   again and still read it as dark brown: the base colour moved, but washi.jpg itself is a
   neutral (128,128,128) grey scan, and multiplying anything by a mid-grey darkens it by
   half — that 50% darkening is what was still muddying plum-pink toward brown, independent
   of which base colour sat under it. Second pass: "use the same color/texture as #2 (once
   updated)" — #2 (.buyband--photo) landed on --plum-pink over washi-MID (not plain washi),
   because washi-mid.jpg averages (220,81,149), close to --pink2, and only darkens by
   ~15% instead of 50%. Same base colour, same washi file, same 340px tile: no photograph
   to layer it over here, so it is the base plus a matching pink-tinted linear-gradient
   wash (the exact same top/bottom stops #2 uses) rather than #2's radial photo-vignette,
   which has no subject on a flat strip. The --panel token itself is still left alone — it
   has other consumers and repointing it would move all of them. */
.cdstrip {
  background:
    linear-gradient(rgba(198,42,140,.22), rgba(92,16,70,.42)),
    var(--plum-pink) url("/assets/a2/washi-mid.jpg?v=e63989d7");
  background-size: auto, 340px;
  background-blend-mode: normal, multiply;
}
.cdstrip-in {
  max-width: var(--maxw); margin: 0 auto; padding: 22px 24px;
  display: flex; flex-wrap: wrap; gap: 16px 24px; align-items: center; justify-content: center;
}
.strip-note { font-size: 15.5px; font-weight: 700; color: var(--cream); margin: 0; }
.cd { display: flex; gap: 18px; align-items: flex-start; }
.cd-unit { text-align: center; min-width: 44px; }
.cd-n { display: block; font-family: 'Ropa Sans', sans-serif; font-weight: 600; font-size: 26px; color: var(--cream); font-variant-numeric: tabular-nums; }
.cd-l { display: block; font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--cream); opacity: .7; }

/* ---------------------------------------------------------------------------
   Cursor-follow buy circle (desktop, over the buy band)
--------------------------------------------------------------------------- */
.cursor-buy {
  position: fixed; left: 0; top: 0; z-index: 60;
  width: 96px; height: 96px; border-radius: 50%;
  display: none; align-items: center; justify-content: center;
  /* Hiro picked this on 31 Aug from three rendered against the live band. It is a brush-drawn
     ring and nothing else — no fill, no border, no shadow box — so the photograph reads
     straight through it. The rough edge is feTurbulence displacing a plain circle, which is
     why this is an inline SVG rather than a border-radius.
     WHY THE OLD ONE HAD TO GO: it was a disc filled with the washi flyer texture, drawn for a
     near-black band. After the band went pink on his instruction the same disc became a pink
     circle on a pink field — the icon did not change, the ground under it did. */
  border: 0; background: none; box-shadow: none;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 100'><filter id='w'><feTurbulence baseFrequency='0.055' numOctaves='2' seed='3'/><feDisplacementMap in='SourceGraphic' scale='4.5'/></filter><circle cx='50' cy='50' r='43' fill='none' stroke='%23f2ece0' stroke-width='3.2' filter='url(%23w)'/></svg>");
  background-size: contain; background-repeat: no-repeat;
  filter: drop-shadow(0 4px 14px rgba(30,4,24,.55));
  opacity: 0; transition: opacity .18s ease;
  pointer-events: none; will-change: transform;
}
.cursor-buy.is-on { opacity: 1; pointer-events: auto; }
/* outside the buy band the ring rides smaller, an accent rather than a takeover */
.cursor-buy.is-small { width: 68px; height: 68px; }
.cursor-buy.is-small svg { width: 20px; height: 20px; }
@media (hover: hover) and (pointer: fine) {
  .cursor-buy { display: flex; }
  .buyband { cursor: none; }
  .buyband .btn-buy { cursor: pointer; }
}

/* ---------------------------------------------------------------------------
   Sticky mobile buy bar
--------------------------------------------------------------------------- */
.sticky-buy { display: none; }
@media (max-width: 760px) {
  .sticky-buy {
    display: flex; position: fixed; left: 0; right: 0; bottom: 0; z-index: 99;
    padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
    background: rgba(51,6,42,.92);
    backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
    align-items: center; justify-content: center;
  }
  .sticky-buy .btn-buy { width: 100%; padding: 14px 20px; }
  body.has-sticky-buy { padding-bottom: 64px; }
}

/* ---------------------------------------------------------------------------
   Interior page header band — .phead, shared by artists/info/who-we-are/
   vendors/contact (from artists_a2.html / info_a2.html)
--------------------------------------------------------------------------- */
.phead {
  position: relative;
  background-color: #bf4d79; /* same pre-load fallback as .hero */
  background-image: url("/assets/a2/hero_washi_real.jpg?v=9bb06e8f");
  background-image: image-set(url("/assets/a2/hero_washi_real.webp?v=68b81948") type("image/webp"),
                              url("/assets/a2/hero_washi_real.jpg?v=9bb06e8f")  type("image/jpeg"));
  background-size: cover; background-position: center 30%;
  padding: 120px 24px 64px;
  text-align: center;
}
/* sharper washi scan on big screens — hero and .phead both (design-round2-20260825) */
@media (min-width: 1280px) {
  .hero  { background-image: url("/assets/a2/hero_washi_real_2x.jpg?v=b99f4d86"); }
  .phead { background-image: url("/assets/a2/hero_washi_real_2x.jpg?v=b99f4d86"); }
  .hero, .phead {
    background-image: image-set(url("/assets/a2/hero_washi_real_2x.webp?v=1b894712") type("image/webp"),
                                url("/assets/a2/hero_washi_real_2x.jpg?v=b99f4d86")  type("image/jpeg"));
  }
}
.phead__script {
  font-family: 'Harlow', cursive; font-weight: 400; color: var(--cream);
  font-size: clamp(26px, 3.6vw, 38px); line-height: 1.05;
  text-shadow: 0 2px 12px rgba(44,6,34,.4);
}
.phead__title {
  font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase;
  color: #fff; font-size: clamp(44px, 7vw, 76px); line-height: 1;
  letter-spacing: .03em; margin-top: 6px;
  text-shadow: 0 2px 14px rgba(44,6,34,.4);
}
.phead__sub { color: #fff; font-size: 17px; margin-top: 14px; opacity: .94; text-shadow: 0 1px 8px rgba(44,6,34,.5); }
.phead__tear {
  position: absolute; left: 0; right: 0; bottom: -1px; height: 56px;
  background: url("/assets/a2/torn_cream.png?v=92985aaf") bottom/1600px 90px repeat-x;
  transform: scaleY(-1); pointer-events: none;
}

/* ---------------------------------------------------------------------------
   Artists page — card grid + fullscreen bio overlay
--------------------------------------------------------------------------- */
.grid { max-width: var(--maxw); margin: 0 auto; padding: 64px 24px 84px; display: grid; grid-template-columns: repeat(3, 1fr); gap: 28px; }
.card { display: flex; flex-direction: column; gap: 12px; text-align: left; background: none; border: 0; padding: 0; cursor: pointer; font: inherit; color: inherit; }
.card__photo { aspect-ratio: 1/1.08; overflow: hidden; border-radius: var(--radius); box-shadow: 0 12px 26px rgba(44,15,34,.22); background: #fff; position: relative; }
.card__photo img { width: 100%; height: 100%; object-fit: cover; transition: transform .35s ease; }
.card:hover .card__photo img { transform: scale(1.035); }
.card__name { font-weight: 700; font-size: 18px; letter-spacing: .04em; text-transform: uppercase; color: var(--plum); }
.card__role { font-size: 15px; font-weight: 600; color: var(--rose); }
@media (prefers-reduced-motion: reduce) { .card__photo img { transition: none; } .card:hover .card__photo img { transform: none; } }
.also-billed { font-size: 15.5px; color: var(--rose); margin-top: 8px; }

/* fullscreen bio overlay — LIVE PARITY, measured off intheskyproduction.com/artists/ on
   31 Aug at 1440x900 (Hiro: "font style and size, placement (Height should be center and
   not top), background color, Spotify icon style/color, should all mimic the live site's",
   "the full page overlay movement ... should also use the same movement").

   Salient's .nectar_team_member_overlay[data-style=bio-fullscreen-alt], reproduced:
     ground        #f2f2f2, body colour #555
     copy column   padding 8% 60% 4% 10%, margin:auto 0 inside a flex row  <- the vertical
                   CENTRING Hiro asked for; it scrolls when the bio is taller than the pane
     heading       Ropa Sans 600, 34/44, #000, 30px below
     body          14/26, #555, 21px between paragraphs
     picture       position:fixed, right 0, width 50%, full height, background cover
     movement      panel translateX(100%) -> 0 over .8s cubic-bezier(.2,1,.2,1)
                   copy fades up 40px, staggered: h2 .55s, body .7s
                   picture scale(1.11) -> 1 over 15s, with a #f2f2f2 panel wiping
                   left-to-right off it (scaleX(1) -> 0, 1s)
   The washi ground and the plum heading are GONE from this overlay on purpose: the
   background colour was named in the instruction. Everything outside .bio is untouched. */
.bio {
  position: fixed; inset: 0; z-index: 80;
  background: #f2f2f2; color: #555;
  overflow: hidden;
  visibility: hidden; pointer-events: none;
  transform: translateX(100%);
  transition: transform .8s cubic-bezier(.2,1,.2,1), visibility 0s .8s;
}
.bio.is-open { visibility: visible; pointer-events: auto; transform: translateX(0); transition: transform .8s cubic-bezier(.2,1,.2,1); }
.bio__inner { display: flex; width: 100%; height: 100%; }
.bio__copy {
  width: 100%; padding: 8% 60% 4% 10%;
  margin: auto 0; max-height: 100vh; overflow-y: auto;
}
.bio__img { position: fixed; right: 0; top: 0; width: 50%; height: 100%; overflow: hidden; background-color: rgba(0,0,0,.1); pointer-events: none; }
.bio__img img {
  width: 100%; height: 100%; object-fit: cover; object-position: center top;
  opacity: 0; transform: scale(1.11);
  transition: transform 15s cubic-bezier(.15,0,.7,1), opacity .3s;
}
.bio.is-open .bio__img img { opacity: 1; transform: scale(1); }
/* the ground-coloured panel that wipes off the photograph, left to right */
.bio__wipe {
  position: absolute; left: -2px; top: 0; width: 100%; height: 100%; z-index: 2;
  background: #f2f2f2; transform-origin: left; transform: scaleX(1);
  transition: transform 1s cubic-bezier(.25,1,.2,1);
}
.bio.is-open .bio__wipe { transform: scaleX(0); }
/* the copy rises into place after the panel has arrived */
.bio__name, .bio__copy p, .bio__embed, .spot-l, .bio__hint {
  opacity: 0; transform: translateY(40px);
  transition: all 1.1s cubic-bezier(.2,1,.2,1) .4s;
}
.bio__name { transition-delay: .55s; }
.bio__copy p, .bio__embed, .spot-l, .bio__hint { transition-delay: .7s; }
.bio.is-open .bio__name, .bio.is-open .bio__copy p, .bio.is-open .bio__embed,
.bio.is-open .spot-l, .bio.is-open .bio__hint { opacity: 1; transform: translateY(0); }
.bio__name { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; color: #000; font-size: 34px; line-height: 44px; letter-spacing: normal; margin-bottom: 30px; text-wrap: balance; }
.bio__role { font-size: 15.5px; font-weight: 600; color: var(--rose); text-transform: uppercase; letter-spacing: .04em; margin-bottom: 16px; }
.bio__copy p { color: #555; font-size: 14px; line-height: 26px; margin: 0 0 21px; max-width: none; }
.bio__copy em { font-style: italic; }
.bio__copy a { text-decoration: underline; text-underline-offset: 3px; font-weight: 600; color: #000; }
/* a second photograph inside the copy column. Live's own bios put pictures in the text
   flow the same way, so this is within the parity rule rather than a new mechanism. */
.bio__extra { margin: 0 0 21px; }
.bio__extra img { display: block; width: 100%; height: auto; border-radius: 2px; }
.bio__extra figcaption { margin-top: 8px; font-size: 13px; line-height: 20px; color: #555; }
.bio__embed { margin: 0 0 21px; border-radius: 12px; overflow: hidden; }
.bio__embed iframe { display: block; width: 100%; height: 352px; border: 0; border-radius: 12px; }
.spot-l { display: inline-block; margin-top: 0; font-size: 14px; font-weight: 600; color: #000; text-decoration: underline; text-underline-offset: 3px; }
.bio__hint { margin-top: 26px; font-size: 13px; font-weight: 600; letter-spacing: .06em; text-transform: uppercase; color: #555; opacity: .75; }
/* Live drops the picture entirely below 690 and narrows it to 35% between 691 and 999. */
@media (max-width: 999px) { .bio__copy { padding-right: 45%; } .bio__img { width: 35%; } }
@media (max-width: 690px) {
  .bio__copy { padding: 12% 10%; }
  .bio__img { display: none; }
  .bio__name { font-size: 28px; line-height: 36px; }
}
@media (max-width: 860px) {
  .grid { grid-template-columns: repeat(2, 1fr); gap: 20px; padding-top: 48px; }
}
/* Motion is decoration here, never the mechanism: with it suppressed the panel still
   arrives and every element is already in place. */
@media (prefers-reduced-motion: reduce) {
  .bio, .bio__img img, .bio__wipe, .bio__name, .bio__copy p, .bio__embed, .spot-l, .bio__hint {
    transition: none !important;
  }
}

.cursor-x {
  position: fixed; left: 0; top: 0; z-index: 90;
  width: 90px; height: 90px; border-radius: 50%;
  display: none; align-items: center; justify-content: center;
  background: transparent; border: 2px solid #fff;
  mix-blend-mode: difference;
  opacity: 0; transition: opacity .18s ease;
  pointer-events: none; will-change: transform;
}
.cursor-x.is-on { opacity: 1; }
.bio__close {
  position: fixed; top: 18px; right: 18px; z-index: 95;
  width: 48px; height: 48px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: rgba(244,239,230,.6); border: 1.5px solid var(--ink);
  color: var(--ink); cursor: pointer;
}
@media (hover: hover) and (pointer: fine) {
  .bio.is-open ~ .cursor-x { display: flex; }
  .bio.is-open .bio__close { opacity: 0; pointer-events: none; }
}

/* ---------------------------------------------------------------------------
   Info-box / list-card system — info, who-we-are, vendors, contact
--------------------------------------------------------------------------- */
.sect { padding: 56px 0 8px; max-width: 1020px; margin: 0 auto; }
.sect--first { padding-top: 64px; }
.sect__title {
  font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase;
  letter-spacing: .04em; font-size: clamp(26px, 3.4vw, 34px); color: var(--plum-deep);
}
.sect__lede { margin-top: 8px; font-size: 16.5px; color: var(--rose); font-weight: 600; }
.sect__intro { margin-top: 14px; font-size: 16.5px; line-height: 1.7; max-width: 66ch; }
.sect__intro a { color: var(--pink); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
/* Centered sections: the 66ch intro box must center WITH its text, not hug the column's left edge. */
.sect--center { text-align: center; }
.sect--center .sect__intro { margin-inline: auto; }

/* Featured-chef card (vendors page): Chef Diego's own block above the vendor grid —
   placement, not hierarchy; the grid below keeps the same card component. */
.vfeature { display: grid; grid-template-columns: minmax(220px, 300px) 1fr; gap: 30px;
  align-items: center; max-width: 860px; margin: 34px auto 0; padding: 26px; text-align: left;
  background: linear-gradient(rgba(244,239,230,.88), rgba(244,239,230,.88)), url("/assets/a2/washi.jpg?v=d5181676");
  background-size: cover; border-radius: var(--radius-lg); box-shadow: 0 8px 20px rgba(44,15,34,.10); }
.vfeature__photo { width: 100%; aspect-ratio: 4 / 5; object-fit: cover; border-radius: 12px; display: block; }
.vfeature__kick { font-family: 'Ropa Sans', sans-serif; text-transform: uppercase;
  letter-spacing: .08em; font-size: 13px; color: var(--rose); font-weight: 600; }
.vfeature__name { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; font-size: 21px; color: var(--plum); margin: 6px 0 10px; }
.vfeature__body p { font-size: 15.5px; line-height: 1.65; margin: 0 0 12px; }
.vfeature__body p:last-child { margin-bottom: 0; }
.vfeature__body a { color: var(--pink); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
@media (max-width: 820px) {
  .vfeature { grid-template-columns: 1fr; padding: 22px; }
  .vfeature__photo { max-width: 340px; margin-inline: auto; }
}

/* ---- Know-before-you-go washi grounds (Hiro, 26 Aug) ----------------------
   One big crumpled-washi sheet per section instead of a grid of small boxes.
   Textures: scripts/build_washi_sections.py derives eight distinct crops/rotations
   of Miwa's crumpled-sheet photograph, with the cream lightening BAKED INTO the
   file so the torn-edge mask below masks tone and texture together — a CSS
   gradient layer would paint over the tears. Silhouettes: per-section SVG alpha
   masks (preserveAspectRatio none + mask-size 100% 100%), so each sheet's tear
   stretches to its own box. Tear depth is capped at ~3% per edge in the mask;
   the sheet's padding must always exceed the stretched depth — that is why the
   mobile block padding below is larger than the desktop one (a tall stacked
   sheet stretches the top/bottom tears deeper in px).
   The tilt and the bleed live on ::before, not the element: the paper leans and
   spills past the text column while the text itself stays level and inside. */
.wsheet { position: relative; margin: 30px 0 10px; padding: 46px 52px 50px;
  filter: drop-shadow(0 12px 20px rgba(44,15,34,.11)); }
.wsheet > * { position: relative; z-index: 1; }
.wsheet::before {
  content: ""; position: absolute; z-index: 0;
  inset: var(--bt,-14px) var(--br,-28px) var(--bb,-16px) var(--bl,-28px);
  transform: rotate(var(--tilt,0deg));
  background: #efe4da center / cover no-repeat;
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
}
.wsheet--basics        { --bt:-18px; --br:-40px; --bb:-12px; --bl:-20px; --tilt:.4deg; }
.wsheet--getting-there { --bt:-12px; --br:-18px; --bb:-20px; --bl:-42px; --tilt:-.45deg; }
.wsheet--coming-in     { --bt:-20px; --br:-34px; --bb:-14px; --bl:-26px; --tilt:.3deg; }
.wsheet--pack          { --bt:-14px; --br:-24px; --bb:-22px; --bl:-36px; --tilt:-.3deg; }
.wsheet--rules         { --bt:-16px; --br:-44px; --bb:-12px; --bl:-16px; --tilt:.5deg; }
.wsheet--tickets       { --bt:-12px; --br:-20px; --bb:-18px; --bl:-40px; --tilt:-.35deg; }
.wsheet--access        { --bt:-20px; --br:-30px; --bb:-16px; --bl:-28px; --tilt:.35deg; }
.wsheet--contact       { --bt:-10px; --br:-22px; --bb:-12px; --bl:-22px; --tilt:-.4deg; }
.wsheet--basics::before        { background-image: url("/assets/a2/washi-sect-basics.jpg?v=bde9f344");        -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M23 16L121 11L151 16L219 17L361 20L372 19L470 16L489 16L533 20L657 17L660 15L662 16L952 17L980 11L980 30L976 76L971 86L974 116L968 126L972 209L985 439L983 609L978 629L957 628L873 626L849 623L644 628L486 627L461 627L338 626L305 617L293 622L163 628L99 627L39 615L23 625L14 579L26 555L12 540L27 479L28 473L27 374L18 357L33 269L37 214L19 165Z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M23 16L121 11L151 16L219 17L361 20L372 19L470 16L489 16L533 20L657 17L660 15L662 16L952 17L980 11L980 30L976 76L971 86L974 116L968 126L972 209L985 439L983 609L978 629L957 628L873 626L849 623L644 628L486 627L461 627L338 626L305 617L293 622L163 628L99 627L39 615L23 625L14 579L26 555L12 540L27 479L28 473L27 374L18 357L33 269L37 214L19 165Z'/%3E%3C/svg%3E"); }
.wsheet--getting-there::before { background-image: url("/assets/a2/washi-sect-getting-there.jpg?v=7487d221"); -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M33 14L240 16L555 15L589 10L626 17L728 21L784 16L793 10L866 24L950 18L979 17L962 36L972 157L975 197L987 362L982 408L976 555L984 585L968 627L938 622L934 616L891 621L885 629L769 629L458 627L417 618L383 628L46 629L34 624L12 551L21 540L26 510L16 499L36 357L33 212L20 178L24 154Z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M33 14L240 16L555 15L589 10L626 17L728 21L784 16L793 10L866 24L950 18L979 17L962 36L972 157L975 197L987 362L982 408L976 555L984 585L968 627L938 622L934 616L891 621L885 629L769 629L458 627L417 618L383 628L46 629L34 624L12 551L21 540L26 510L16 499L36 357L33 212L20 178L24 154Z'/%3E%3C/svg%3E"); }
.wsheet--coming-in::before     { background-image: url("/assets/a2/washi-sect-coming-in.jpg?v=6fc53752");     -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M25 12L33 11L33 14L191 11L231 15L268 15L422 15L427 11L471 12L490 17L611 22L666 14L792 23L919 10L967 12L977 87L962 126L981 143L975 295L982 332L981 371L975 500L988 541L964 604L979 630L714 625L657 629L638 621L621 624L586 625L366 629L300 625L116 627L97 630L48 617L33 627L26 608L20 481L15 439L28 409L21 310L19 228L13 196L32 142L16 94L32 93Z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M25 12L33 11L33 14L191 11L231 15L268 15L422 15L427 11L471 12L490 17L611 22L666 14L792 23L919 10L967 12L977 87L962 126L981 143L975 295L982 332L981 371L975 500L988 541L964 604L979 630L714 625L657 629L638 621L621 624L586 625L366 629L300 625L116 627L97 630L48 617L33 627L26 608L20 481L15 439L28 409L21 310L19 228L13 196L32 142L16 94L32 93Z'/%3E%3C/svg%3E"); }
.wsheet--pack::before          { background-image: url("/assets/a2/washi-sect-pack.jpg?v=c2d1a91e");          -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M20 16L126 10L197 19L344 14L459 14L507 12L533 22L561 14L582 14L594 10L656 18L672 26L849 15L896 17L982 12L989 49L982 117L987 149L968 193L977 217L983 398L971 525L970 626L863 625L802 626L781 616L511 621L350 629L324 624L293 627L212 620L99 627L19 630L14 508L20 343L27 333L24 264L12 153L34 83L20 81L34 80L17 54Z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M20 16L126 10L197 19L344 14L459 14L507 12L533 22L561 14L582 14L594 10L656 18L672 26L849 15L896 17L982 12L989 49L982 117L987 149L968 193L977 217L983 398L971 525L970 626L863 625L802 626L781 616L511 621L350 629L324 624L293 627L212 620L99 627L19 630L14 508L20 343L27 333L24 264L12 153L34 83L20 81L34 80L17 54Z'/%3E%3C/svg%3E"); }
.wsheet--rules::before         { background-image: url("/assets/a2/washi-sect-rules.jpg?v=beeee400");         -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M24 11L52 15L213 20L215 11L354 21L391 18L591 10L629 11L666 15L761 12L792 15L846 16L894 17L969 17L987 42L982 223L979 321L987 361L964 440L966 477L981 508L978 628L952 618L868 624L565 629L503 623L407 629L373 620L230 625L132 629L123 623L25 624L20 603L21 555L14 548L16 510L17 432L21 359L31 289L18 108L31 90Z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M24 11L52 15L213 20L215 11L354 21L391 18L591 10L629 11L666 15L761 12L792 15L846 16L894 17L969 17L987 42L982 223L979 321L987 361L964 440L966 477L981 508L978 628L952 618L868 624L565 629L503 623L407 629L373 620L230 625L132 629L123 623L25 624L20 603L21 555L14 548L16 510L17 432L21 359L31 289L18 108L31 90Z'/%3E%3C/svg%3E"); }
.wsheet--tickets::before       { background-image: url("/assets/a2/washi-sect-tickets.jpg?v=8ab18769");       -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M18 10L34 17L51 11L75 17L160 12L176 19L266 10L346 25L394 26L411 18L655 17L684 16L771 18L972 13L964 50L968 131L972 187L973 232L975 344L989 362L983 463L986 499L978 626L971 624L932 623L894 622L827 629L804 620L610 628L448 630L339 625L215 626L189 625L93 616L19 626L24 619L34 573L17 523L27 391L14 335L11 287L30 228Z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M18 10L34 17L51 11L75 17L160 12L176 19L266 10L346 25L394 26L411 18L655 17L684 16L771 18L972 13L964 50L968 131L972 187L973 232L975 344L989 362L983 463L986 499L978 626L971 624L932 623L894 622L827 629L804 620L610 628L448 630L339 625L215 626L189 625L93 616L19 626L24 619L34 573L17 523L27 391L14 335L11 287L30 228Z'/%3E%3C/svg%3E"); }
.wsheet--access::before        { background-image: url("/assets/a2/washi-sect-access.jpg?v=56765b9f");        -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M26 15L80 12L166 18L188 13L190 17L305 18L311 16L329 18L340 23L398 24L475 12L967 10L975 78L976 106L980 212L964 222L963 252L980 392L986 537L974 627L898 628L745 622L741 618L695 625L676 628L538 629L223 615L210 630L73 622L53 624L19 625L17 513L24 466L22 460L17 415L37 359L14 356L30 302L14 169L17 153Z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M26 15L80 12L166 18L188 13L190 17L305 18L311 16L329 18L340 23L398 24L475 12L967 10L975 78L976 106L980 212L964 222L963 252L980 392L986 537L974 627L898 628L745 622L741 618L695 625L676 628L538 629L223 615L210 630L73 622L53 624L19 625L17 513L24 466L22 460L17 415L37 359L14 356L30 302L14 169L17 153Z'/%3E%3C/svg%3E"); }
.wsheet--contact::before       { background-image: url("/assets/a2/washi-sect-contact.jpg?v=b282e806");       -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M25 15L42 15L87 15L135 15L197 17L212 10L225 13L274 23L318 15L355 12L479 16L777 22L878 19L896 13L979 15L978 91L974 100L984 192L980 219L985 225L969 405L984 410L973 438L971 562L975 588L977 627L873 627L795 615L729 621L595 623L572 625L547 626L495 627L358 617L126 630L111 623L19 623L21 586L25 563L24 489L34 359L24 247L31 152L24 40Z'/%3E%3C/svg%3E"); mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M25 15L42 15L87 15L135 15L197 17L212 10L225 13L274 23L318 15L355 12L479 16L777 22L878 19L896 13L979 15L978 91L974 100L984 192L980 219L985 225L969 405L984 410L973 438L971 562L975 588L977 627L873 627L795 615L729 621L595 623L572 625L547 626L495 627L358 617L126 630L111 623L19 623L21 586L25 563L24 489L34 359L24 247L31 152L24 40Z'/%3E%3C/svg%3E"); }

.ib-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: 26px 44px; }
.ib h3 { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; font-size: 16.5px; color: var(--plum); margin-bottom: 8px; }
.ib p { font-size: 15.5px; line-height: 1.65; }
.ib a { text-decoration: underline; text-underline-offset: 3px; font-weight: 600; color: var(--pink); }
.ib .mapbox { margin-top: 12px; border-radius: var(--radius); overflow: hidden; }
.ib .mapbox iframe { display: block; width: 100%; height: 200px; border: 0; }

.lists { display: grid; grid-template-columns: 1fr 1fr; gap: 26px; margin-top: 26px; }
/* Inside a washi sheet the bring-list sits straight on the paper; the dark leave-card
   stays a separate scrap laid on top of it, with its own (reused) torn silhouette. */
.wsheet .lists { margin-top: 0; gap: 36px; }
.wsheet .listcard--bring { background: none; box-shadow: none; padding: 0; border-radius: 0; }
.wsheet .listcard--leave {
  box-shadow: none; border-radius: 0; padding: 28px 30px; transform: rotate(-.4deg);
  -webkit-mask-repeat: no-repeat; mask-repeat: no-repeat;
  -webkit-mask-size: 100% 100%; mask-size: 100% 100%;
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M25 15L42 15L87 15L135 15L197 17L212 10L225 13L274 23L318 15L355 12L479 16L777 22L878 19L896 13L979 15L978 91L974 100L984 192L980 219L985 225L969 405L984 410L973 438L971 562L975 588L977 627L873 627L795 615L729 621L595 623L572 625L547 626L495 627L358 617L126 630L111 623L19 623L21 586L25 563L24 489L34 359L24 247L31 152L24 40Z'/%3E%3C/svg%3E");
  mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 1000 640' preserveAspectRatio='none'%3E%3Cfilter id='r' x='-5%25' y='-5%25' width='110%25' height='110%25'%3E%3CfeGaussianBlur stdDeviation='2.2'/%3E%3C/filter%3E%3Cpath filter='url%28%23r%29' fill='%23fff' d='M25 15L42 15L87 15L135 15L197 17L212 10L225 13L274 23L318 15L355 12L479 16L777 22L878 19L896 13L979 15L978 91L974 100L984 192L980 219L985 225L969 405L984 410L973 438L971 562L975 588L977 627L873 627L795 615L729 621L595 623L572 625L547 626L495 627L358 617L126 630L111 623L19 623L21 586L25 563L24 489L34 359L24 247L31 152L24 40Z'/%3E%3C/svg%3E");
}
.listcard { border-radius: var(--radius-lg); padding: 22px 24px; box-shadow: 0 8px 20px rgba(44,15,34,.10); }
.listcard--bring { background: linear-gradient(rgba(244,239,230,.88), rgba(244,239,230,.88)), url("/assets/a2/washi.jpg?v=d5181676"); background-size: cover; }
.listcard--leave { background: var(--panel) url("/assets/a2/washi-mid.jpg?v=e63989d7"); background-size: 340px; background-blend-mode: multiply; color: var(--cream); }
.listcard h3 { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; font-size: 18px; margin-bottom: 12px; }
.listcard--bring h3 { color: var(--plum); }
.listcard li { position: relative; padding-left: 20px; margin-bottom: 9px; font-size: 15.5px; line-height: 1.55; }
.listcard li::before { content: ""; position: absolute; left: 0; top: .52em; width: 7px; height: 7px; border-radius: 50%; }
.listcard--bring li::before { background: radial-gradient(circle at 35% 35%, var(--pink2), var(--pink)); }
.listcard--leave li::before { background: radial-gradient(circle at 35% 35%, var(--cream), var(--pink3)); }

.contactline {
  margin: 40px 0 0; padding: 26px; text-align: center; border-radius: var(--radius-lg);
  background: linear-gradient(rgba(244,239,230,.88), rgba(244,239,230,.88)), url("/assets/a2/washi.jpg?v=d5181676");
  background-size: cover; font-size: 16.5px;
}
.contactline a { color: var(--pink); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }
/* On /info/ the contact line rides its own small torn strip; the strip is the ground. */
.wsheet--contact { max-width: 1020px; margin: 48px auto 0; padding: 30px 44px; }
.wsheet--contact .contactline { margin: 0; padding: 0; background: none; box-shadow: none; border-radius: 0; }

/* ---------------------------------------------------------------------------
   Sponsors page (design-round2-20260825/sponsors_a2.html) + the Vendors page's
   closed-applications card (vendors_a2.html) — both new in commit 02bb8ab, 2026-08-26.
--------------------------------------------------------------------------- */
.sect__kick { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; font-size: 15px; letter-spacing: .14em; color: var(--rose); margin-bottom: 22px; }
.sponsor-card {
  display: inline-block; padding: 52px 72px;
  background: linear-gradient(rgba(255,253,248,.9), rgba(255,253,248,.9)), url("/assets/a2/washi.jpg?v=d5181676");
  background-size: cover;
  border-radius: var(--radius-lg); box-shadow: 0 12px 28px rgba(44,15,34,.14);
}
.sponsor-card__mark { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; font-size: clamp(34px, 5vw, 52px); letter-spacing: .08em; color: var(--plum); line-height: 1; }
.sponsor-card__role { margin-top: 12px; font-size: 14.5px; font-weight: 600; letter-spacing: .1em; text-transform: uppercase; color: var(--rose); }
.amb { margin-top: 44px; }
.amb__names { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; font-size: clamp(20px, 2.6vw, 28px); color: var(--plum); letter-spacing: .06em; }
.amb__names span { color: var(--pink2); }

.become, .closedcard {
  margin: 64px auto 0; padding: 34px 30px; border-radius: var(--radius-lg); text-align: center;
  background: var(--panel) url("/assets/a2/washi-mid.jpg?v=e63989d7");
  background-size: 340px; background-blend-mode: multiply; color: var(--cream);
}
.closedcard { max-width: 760px; padding: 30px 32px; }
.become h2, .closedcard h2 {
  font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase;
  letter-spacing: .05em; font-size: 22px; margin-bottom: 10px;
}
.closedcard h2 { font-size: 20px; }
.become p, .closedcard p { font-size: 16px; line-height: 1.65; max-width: 56ch; margin: 0 auto; }
.closedcard p { font-size: 15.5px; line-height: 1.65; }
.become a, .closedcard a { color: #fff; font-weight: 700; text-decoration: underline; text-underline-offset: 3px; }

/* Below ~1120px the 1020px column is already the viewport: pull the bleed in so the
   torn edges stay visible instead of being cut flat by the body's overflow-x clip. */
@media (max-width: 1120px) {
  .wsheet { --bt:-10px; --br:-6px; --bb:-12px; --bl:-6px; padding: 42px 36px 46px; }
}
@media (max-width: 820px) {
  .ib-grid { grid-template-columns: 1fr; }
  .lists { grid-template-columns: 1fr; }
  .sect { padding-top: 44px; }
  /* Single-column sheets are tall, and the mask stretches its top/bottom tears with the
     box (depth is a % of height) — the block padding grows to keep text clear of them.
     Tilt goes to zero here: on a ~2000px-tall sheet even .4deg swings the corners ~12px
     sideways, past the viewport, where the clip cuts the tear flat. The masks alone
     carry the un-uniform edge on phones. */
  .wsheet { margin-inline: 8px; padding: 60px 24px 64px; --tilt: 0deg; }
  .wsheet .lists { gap: 30px; }
}

/* ---------------------------------------------------------------------------
   Who We Are — narrative + past-events grid
--------------------------------------------------------------------------- */
.narrative { display: grid; grid-template-columns: 1fr 1fr; gap: 48px; align-items: start; margin-top: 8px; }
.narrative .pull { font-size: 19px; font-weight: 600; color: var(--rose); line-height: 1.5; margin-top: 10px; }
.narrative p { font-size: 16px; line-height: 1.75; margin-bottom: 14px; }
@media (max-width: 820px) { .narrative { grid-template-columns: 1fr; gap: 22px; } }

.pastgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; margin-top: 34px; }
.pastcard { display: flex; flex-direction: column; gap: 10px; }
.pastcard__photo { aspect-ratio: 4/5; overflow: hidden; border-radius: var(--radius); box-shadow: 0 12px 26px rgba(44,15,34,.2); }
.pastcard__photo img { width: 100%; height: 100%; object-fit: cover; }
.pastcard__plate {
  aspect-ratio: 4/5; border-radius: var(--radius); box-shadow: 0 12px 26px rgba(44,15,34,.2);
  background: var(--panel) url("/assets/a2/washi-mid.jpg?v=e63989d7"); background-size: 300px; background-blend-mode: multiply;
  display: flex; align-items: center; justify-content: center; padding: 20px; text-align: center;
}
.pastcard__plate span { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; font-size: 20px; color: var(--cream); }
.pastcard__n { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; letter-spacing: .03em; font-size: 16px; color: var(--plum); }
.pastcard__d { display: block; font-size: 13.5px; color: var(--rose); margin-top: 2px; }
@media (max-width: 760px) { .pastgrid { grid-template-columns: 1fr; } }

/* ---------------------------------------------------------------------------
   Contact form
--------------------------------------------------------------------------- */
.form {
  background: linear-gradient(rgba(244,239,230,.88), rgba(244,239,230,.88)), url("/assets/a2/washi.jpg?v=d5181676");
  background-size: cover; border-radius: var(--radius-lg); padding: 28px 26px;
  box-shadow: 0 8px 20px rgba(44,15,34,.10);
  display: flex; flex-direction: column; gap: 16px;
}
.field { display: flex; flex-direction: column; gap: 6px; }
.field label { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; letter-spacing: .05em; font-size: 13.5px; color: var(--plum); }
.field input, .field textarea {
  font: inherit; font-size: 15.5px; padding: 11px 13px; border-radius: var(--radius);
  border: 1px solid rgba(154,50,83,.3); background: #fff; color: var(--ink);
}
.field textarea { min-height: 130px; resize: vertical; }
.form .btn-buy { align-self: flex-start; border: 0; cursor: pointer; }
.form .formnote { font-size: 14px; color: var(--rose); margin: 0; }

/* ---------------------------------------------------------------------------
   Meta / small print
--------------------------------------------------------------------------- */
.callout {
  border-radius: var(--radius-lg); padding: 20px 22px; margin-top: 20px;
  background: linear-gradient(rgba(244,239,230,.88), rgba(244,239,230,.88)), url("/assets/a2/washi.jpg?v=d5181676");
  background-size: cover; box-shadow: 0 8px 20px rgba(44,15,34,.10);
}
.callout h3 { font-family: 'Ropa Sans', sans-serif; font-weight: 600; text-transform: uppercase; letter-spacing: .04em; font-size: 16.5px; color: var(--plum); margin-bottom: 8px; }
.callout p { font-size: 15.5px; line-height: 1.6; }

.vmarks { display: flex; flex-wrap: wrap; gap: 16px; margin-top: 10px; }
.vmarks li { width: 96px; height: 96px; border-radius: var(--radius); background: #fff; box-shadow: 0 6px 16px rgba(44,15,34,.14); display: flex; align-items: center; justify-content: center; padding: 10px; }
.vmarks li img { max-width: 100%; max-height: 100%; object-fit: contain; }

/* ---------------------------------------------------------------------------
   Who We Are — a structural port of the LIVE WordPress page (Hiro, 26 Aug:
   "exact same (including effects, layout, pictures used) as the Live site").
   Every number here was measured off intheskyproduction.com/who-we-are/ with
   Playwright at 1280 and 1600, not eyeballed. Reference geometry at 1280:
   container 1100 (x 90..1190) · H1 Ropa Sans 115.2px/400 · event name 70px/63px
   w700 · poster col 520 · side col 396 starting at 64% · column photo 396x585 ·
   strip cells 352x235 at x 90/464/838 · ground #f8f8f8.
--------------------------------------------------------------------------- */
body:has(.lw) { background: #f8f8f8; }
/* overflow-x:clip (not hidden — no scroll container, so the sticky nav still works)
   contains the reveal's -26px entry offset, which otherwise overflows left on phones. */
.lw { max-width: 1100px; margin: 0 auto; padding: 0 20px; color: #000; overflow-x: clip; }
/* 100px, not 34 — the ported live page had no overlaid nav; ours is fixed and ~70px tall,
   so the crumb needs to start below it or it collides with the brand (seen 27 Aug). */
.lw__crumb { font-size: 13px; color: #8a8a8a; padding-top: 100px; letter-spacing: .01em; }
.lw__crumb a { color: #8a8a8a; text-decoration: none; }
.lw__crumb a:hover { color: #000; }

.lw__head { display: grid; grid-template-columns: 1fr auto; align-items: start;
  gap: 40px; padding: 60px 0 40px; }
.lw__h1 { font-family: 'Ropa Sans', sans-serif; font-weight: 400; color: #000;
  font-size: clamp(52px, 9vw, 115px); line-height: 1.1; letter-spacing: -.005em; margin: 0; }
.lw__jump { display: flex; flex-direction: column; gap: 12px; padding-top: 14px; }
.lw__jump a { font-family: 'Ropa Sans', sans-serif; font-size: 15px; letter-spacing: .02em;
  color: #000; text-decoration: none; border-bottom: 1px solid #000; padding-bottom: 3px;
  align-self: start; transition: opacity .18s ease; }
.lw__jump a:hover { opacity: .55; }

.lw__vision { display: grid; grid-template-columns: 50% 1fr; gap: 44px; align-items: start;
  padding-bottom: 90px; }
/* Two-shot collage since 27 Aug (Miwa cut the guitarist lead, fix #7): the remaining pair
   keeps the live page's staggered overlap, sized up to carry the column alone. */
.lw__cascade { position: relative; min-height: 390px; }
.lw__casc { position: absolute; width: 60%; border-radius: 10px; object-fit: cover;
  box-shadow: 0 18px 40px rgba(0,0,0,.22); }
.lw__casc--b { left: 36%; top: 0; aspect-ratio: 3/2; z-index: 3; }
.lw__casc--c { left: 0;  top: 38%; aspect-ratio: 3/2; z-index: 2; }
.lw__copy p { font-size: 16px; line-height: 1.62; color: #111; margin: 0 0 20px; }
.lw__h2 { font-family: 'Ropa Sans', sans-serif; font-weight: 600; font-size: 29px;
  color: #000; margin: 0 0 22px; }
.lw__ig a { color: #111; text-decoration: none; border-bottom: 1px solid #bbb; font-size: 15px; }
.lw__ig a:hover { border-color: #000; }

.lw__ev { display: grid; grid-template-columns: 50% 1fr; gap: 44px;
  align-items: start; padding-bottom: 96px; }
.lw__ev-poster img, .lw__ev-col img, .lw__cell img { display: block; width: 100%; height: 100%;
  object-fit: cover; border-radius: 10px; }
.lw__ev-poster img { height: auto; }
.lw__ev-name { font-family: 'Hiragino Kaku Gothic ProN', 'Hiragino Sans', 'Open Sans', sans-serif;
  font-weight: 700; font-size: clamp(40px, 5.5vw, 70px); line-height: .92; color: #000;
  margin: 0 0 14px; letter-spacing: -.01em; }
.lw__ev-date { font-family: 'Ropa Sans', sans-serif; font-size: 29px; line-height: 1.15;
  color: #000; margin: 0 0 34px; }
.lw__ev-col { aspect-ratio: 396/585; }
/* The strip spans both columns and keeps the live page's stagger: the first cell
   rides high, the other two drop. */
.lw__strip { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(3, 1fr);
  gap: 22px; margin-top: 34px; }
.lw__cell { aspect-ratio: 3/2; }
.lw__strip { margin-bottom: 90px; }

/* Reveal on scroll, matched to the live page (WP page 111, read 27 Aug 2026).
   Of the twelve images there only THREE animate — each event's lead poster, set to
   "Fade In From Left". Every strip and column photo carries animation="None" and does
   not move at all. The movement that page actually shows is on its TEXT columns: five
   vc_column_inner blocks set to fade-in-from-bottom. This mock had it inverted —
   seventeen photos sliding in from the left past motionless text.
   --sy carries an element's resting offset so a reveal returns to it, not to zero. */
.lw__casc, .lw__ev-poster, .lw__ev-col, .lw__cell, .lw__copy, .lw__ev-side, .reveal { --sy: 0px; }
/* the strip's stagger is LAYOUT, not animation: it holds whether or not the element
   ever animates, so it is set before anything below touches transform. */
.lw__cell:nth-child(2), .lw__cell:nth-child(3) { --sy: 90px; }
.lw__cell { transform: translate(0, var(--sy)); }
/* The hidden starting state may only exist where scripting does: .lw-in is added by
   site.js, so hiding these with script off strands them invisible for ever — which is
   what this page did until 27 Aug. Where the `scripting` feature is unsupported the
   whole block is ignored and the page renders visible and still, which is the safe
   direction to fail in. */
@media (scripting: enabled) {
  /* the three event posters — the only photographs that move, as live */
  .lw__ev-poster {
    --sx: -26px; opacity: 0; transform: translate(var(--sx), var(--sy));
    transition: opacity .7s ease, transform .7s ease; }
  /* the text columns rise into place, as live — and .reveal carries the same movement to
     the home page's restored sections, so the whole site speaks one motion vocabulary */
  .lw__copy, .lw__ev-side, .reveal {
    opacity: 0; transform: translate(0, 30px);
    transition: opacity .7s ease, transform .7s ease; }
  .lw-in { opacity: 1 !important; transform: translate(0, var(--sy)) !important; }
}
.lw__ev-poster:hover img, .lw__cell:hover img, .lw__ev-col:hover img { filter: brightness(1.06); }
.lw__ev-poster img, .lw__cell img, .lw__ev-col img { transition: filter .25s ease; }

.lw__cta { position: relative; margin-top: 20px; padding: 150px 20px; text-align: center;
  background: #0a0a0a url("/assets/img/who/cta_band.jpg?v=4dda8598") center bottom / cover no-repeat;
  color: #fff; }
.lw__cta::after { content: ""; position: absolute; inset: 0; background: rgba(8,6,10,.55); }
.lw__cta-inner { position: relative; z-index: 1; }
.lw__cta-title { font-family: 'Ropa Sans', sans-serif; font-weight: 600;
  font-size: clamp(32px, 5vw, 52px); line-height: 1.05; color: #fff; margin: 0 0 10px; }
.lw__cta-sub { color: rgba(255,255,255,.82); font-size: 16px; margin: 0 0 22px; }

@media (prefers-reduced-motion: reduce) {
  .lw__casc, .lw__ev-poster, .lw__ev-col, .lw__cell, .lw__copy, .lw__ev-side, .reveal {
    opacity: 1; transform: translate(0, var(--sy)); transition: none; }
}
@media (max-width: 900px) {
  /* Below the desktop layout the entry offset would start the poster left of the
     viewport edge, so the reveal fades in place instead of sliding. */
  .lw__ev-poster { --sx: 0px; }
}
@media (max-width: 860px) {
  .lw__head { grid-template-columns: 1fr; gap: 22px; padding: 40px 0 30px; }
  .lw__jump { flex-direction: row; flex-wrap: wrap; gap: 10px 16px; padding-top: 0; }
  .lw__vision, .lw__ev { grid-template-columns: 1fr; gap: 28px; padding-bottom: 60px; }
  .lw__cascade { min-height: 300px; }
  .lw__strip { grid-template-columns: 1fr 1fr; gap: 14px; margin-bottom: 40px; }
  .lw__cell:nth-child(2), .lw__cell:nth-child(3) { --sy: 0px; }
  .lw__cell:nth-child(3) { grid-column: 1 / -1; }
  .lw__ev-date { font-size: 22px; margin-bottom: 22px; }
  .lw__cta { padding: 90px 20px; }
}

/* ---------------------------------------------------------------------------
   Preview banner (unchanged mechanism — see build/build_site.py PREVIEW_BANNER)
--------------------------------------------------------------------------- */
[data-mirror-banner] { position: relative; z-index: 100; }

/* ---------------------------------------------------------------------------
   Responsive — section paddings tighten on phones
--------------------------------------------------------------------------- */
@media (max-width: 760px) {
  .section { padding: 56px 20px; }
  .hero { padding-top: 84px; padding-bottom: 72px; }
  .hero__inner { gap: 10px; }
  .hero__bill { gap: 7px; }
  .hero__facts { font-size: 17px; line-height: 1.45; margin-top: 8px; }
  .cut--nujabes { width: min(600px, 82vw); }
  .hero__spell { font-size: 16px; }
  .phead { padding-top: 96px; }
}
