/* ──────────────────────────────────────────────────────────────
   Vidi Web — premium dark experiences-marketplace system
   Warm near-black canvas · off-white text · Vidi orange accent
   CHANEY Extended (home-hero tagline only) · Alexandria (everything else).
   Token names preserved across the app; --serif still aliases the display face.
   ────────────────────────────────────────────────────────────── */
/* Typography, 2026-08-05: Chaney is now scoped to the home-hero tagline
   ("See more. Know better.", .display-tagline) at the team's request; every
   other title — .display page H1s and .form-card h1 — is Alexandria. This
   narrows the 2026-07-31 revert, which had put ALL page titles on Chaney.
   --title keeps the Chaney stack for the tagline; --display stays Alexandria.
   Two standing constraints on the Chaney face:
   - The woff2 is weight 400 ONLY. Never request a heavier weight from --title
     or the browser synthesizes a fake bold.
   - It draws capitals for lowercase input; all titles keep an explicit
     text-transform:uppercase (the tagline inherits it from .display) so the
     Alexandria fallback renders the same silhouette if the woff2 fails, and
     because templates pass mixed case ("Events", a user's display name).
   Still open: the Atipo webfont licence question, and the ask for the exact
   Chaney cut the mobile app ships. When that cut arrives, drop it in as
   ../fonts/chaney.woff2 — the family name and every consumer stay unchanged. */
@font-face{
  font-family:"CHANEY Extended";
  src:url("../fonts/chaney.woff2") format("woff2");
  font-weight:400;
  font-style:normal;
  font-display:swap;
}
:root{
  /* surfaces */
  --bone:#0F0D0A; --bone-2:#1A1611; --bone-3:#251F18;
  --raise:#211C15;
  /* text */
  --ink:#F6F1EA; --ink-soft:#BDB4A6; --ink-mute:#948B7E;
  /* accent */
  --red:#E81A0C; --red-deep:#FF5436; --red-tint:rgba(232,26,12,.16); --red-glow:rgba(232,26,12,.22);
  --ok:#6BBF93;
  /* type — CHANEY Extended for the home-hero tagline only (--title),
     Alexandria for titles, body, labels and all --display consumers.
     Alexandria is the fallback in the --title stack, not a serif: if the
     self-hosted woff2 fails, the tagline stays on the brand face rather than
     dropping to Georgia. The token names are kept so every consumer updates
     in one place. */
  --title:"CHANEY Extended","Alexandria","General Sans",system-ui,sans-serif;
  --display:"Alexandria","General Sans","Inter",system-ui,sans-serif;
  --serif:var(--display);
  --sans:"Alexandria","General Sans","Inter",system-ui,sans-serif;
  /* label face — historically JetBrains Mono; now Alexandria for mobile-app
     parity (token name kept so every label rule updates in one place) */
  --mono:"Alexandria","General Sans","Inter",system-ui,sans-serif;
  /* lines / radii / motion */
  --line:rgba(246,241,234,.12);
  --hairline:1px solid var(--line);
  --dashed:1px dashed rgba(246,241,234,.2);
  --radius:14px; --radius-sm:10px; --radius-lg:22px;
  --maxw:1140px;
  --ease:cubic-bezier(.22,.8,.3,1);
  --shadow-card:0 18px 40px -26px rgba(0,0,0,.75);
  --shadow-raise:0 30px 64px -28px rgba(0,0,0,.85);
  --surface-grad:linear-gradient(160deg,rgba(255,255,255,.045),rgba(255,255,255,0) 55%);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
body{
  margin:0;background:var(--bone);color:var(--ink);
  font:400 16px/1.6 var(--sans);
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;
  overflow-x:hidden;
}
/* atmosphere: a single warm glow anchored top-center + the faintest grain */
body::before{
  content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:
    radial-gradient(120% 70% at 50% -10%, var(--red-glow), transparent 60%),
    radial-gradient(80% 50% at 85% 8%, rgba(255,120,40,.06), transparent 55%);
}
body::after{
  content:"";position:fixed;inset:0;pointer-events:none;z-index:9999;opacity:.4;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 .025 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

/* ── type ── */
.mono{font-family:var(--mono);font-weight:500;font-size:.74rem;letter-spacing:.08em;text-transform:uppercase}
/* Page titles ("Events", "Profile", partner/place names): Alexandria at 800.
   Sizing/leading/tracking are the Alexandria numbers — this face is far
   narrower than Chaney and reads smaller at the same px, so it runs slightly
   larger. Uppercase is kept: templates pass mixed case ("Events", a user's
   display name) and the titles must stay capitals. overflow-wrap because long
   unbroken partner and place names overflowed without it. */
.display{
  font-family:var(--display);font-weight:800;text-transform:uppercase;
  font-size:clamp(2.5rem,6.2vw,4.5rem);line-height:1.06;letter-spacing:-.01em;margin:.12em 0;
  overflow-wrap:break-word;
}
.display em{font-style:normal;color:var(--red-deep)}
/* The one Chaney consumer: the home-hero tagline ("See more. Know better.").
   Weight 400 is the woff2's only cut — heavier requests synthesize a fake
   bold. Metrics are the original Chaney values (wider face, so smaller px). */
.display-tagline{
  font-family:var(--title);font-weight:400;
  font-size:clamp(2.4rem,6vw,4.4rem);line-height:1.02;letter-spacing:-.02em;
}
.kicker{color:var(--ink-mute)}
.lede{color:var(--ink-soft);font-size:clamp(1.05rem,1.6vw,1.22rem);line-height:1.55;max-width:42rem}
a{color:inherit}
::selection{background:var(--red);color:#fff}
:focus-visible{outline:2px solid var(--red-deep);outline-offset:3px;border-radius:3px}
.skip-link{position:absolute;left:-9999px;top:0;background:var(--ink);color:var(--bone);padding:.5rem 1rem;z-index:10000}
.skip-link:focus{left:8px;top:8px}
.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}
main{max-width:var(--maxw);margin:0 auto;padding:0 22px 96px;min-height:62vh}

/* "Up" arrow on detail pages. Height reserved so adding it above the
   fetchpriority=high hero does not cause a layout jump (CLS) on load. */
.back-link{
  display:flex;width:max-content;   /* block-level: a center-aligned parent (placelist) can't shift it */
  align-items:center;gap:.4rem;margin:18px 0 6px;
  font-size:.9rem;line-height:1;color:var(--ink-soft);
  text-decoration:none;transition:color .15s var(--ease);
}
.back-link:hover{color:var(--ink)}
.back-link svg{width:18px;height:18px;flex:none}
.back-link span{white-space:nowrap}
/* .placelist-cover overrides the hero's margin-top to 0, so the arrow would sit too
   close to the cover — restore the ~26px gap the event/partner heroes have. */
.placelist-landing .back-link{margin-bottom:26px}
@media (pointer:coarse){ .back-link{min-height:44px} }

/* ── header (scroll-aware, sticky, blur) ── */
.site-header{position:sticky;top:0;z-index:100;padding-top:env(safe-area-inset-top,0px);transition:background .3s var(--ease),border-color .3s var(--ease),backdrop-filter .3s var(--ease);border-bottom:1px solid transparent}
.site-header.scrolled{background:rgba(15,13,10,.72);backdrop-filter:saturate(140%) blur(14px);border-bottom:var(--hairline)}
/* iOS Safari paints page content in a sliver ABOVE the sticky header while the
   URL bar collapses / on overscroll. Shield the area above the header with the
   page background so nothing ever shows on top of it. Invisible elsewhere
   (the shield sits outside the viewport when the header is at its normal spot). */
.site-header::before{content:"";position:absolute;left:0;right:0;bottom:100%;height:100vh;background:var(--bone);pointer-events:none}
.nav-inner{display:flex;align-items:center;justify-content:space-between;max-width:var(--maxw);margin:0 auto;padding:16px 22px}
.wordmark{font-family:var(--display);font-weight:400;font-size:1.4rem;text-decoration:none;display:flex;align-items:center;gap:.5rem;letter-spacing:-.02em}
.dot{width:.5em;height:.5em;border-radius:50%;background:var(--red);box-shadow:0 0 0 0 var(--red-glow);animation:pulse 2.8s var(--ease) infinite}
.logo{height:48px;width:auto;display:block}
@keyframes pulse{0%,100%{box-shadow:0 0 0 0 rgba(232,26,12,.5)}50%{box-shadow:0 0 0 7px rgba(232,26,12,0)}}
.nav-toggle{display:none}
/* drawer-only chrome: hidden by default so neither can leak onto desktop, where the
   640px block below never applies */
.nav-close{display:none}
.nav-scrim{display:none}
/* Explicit icon size: WebKit (iOS) gives an inline <svg> with a viewBox but no
   width/height a 0×0 intrinsic size inside a flex parent, so the button stays
   tappable but the icon is invisible. */
.nav-toggle svg{width:24px;height:24px;flex:none}
.site-nav{display:flex;align-items:center;gap:1.3rem}
.site-nav a{text-decoration:none;font-size:.95rem;transition:color .15s}
.site-nav a:not(.btn){color:var(--ink-soft)}
.site-nav a:not(.btn):hover{color:var(--ink)}
/* active-section highlighter (matches the mobile app's red accent) */
.site-nav a.is-active:not(.btn){color:var(--red);font-weight:600;position:relative}
.site-nav a.is-active:not(.btn)::after{
  content:"";position:absolute;left:0;right:0;bottom:-6px;height:2px;
  border-radius:2px;background:var(--red);
}
.site-nav a.is-active:not(.btn):hover{color:var(--red)}
.nav-user{color:var(--ink-soft);text-decoration:none}
.nav-user:hover{color:var(--ink)}
.inline-form{display:inline}

/* ── buttons ── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5rem;
  padding:.8rem 1.5rem;border-radius:999px;border:1px solid transparent;
  font:600 .94rem var(--sans);letter-spacing:.01em;text-decoration:none;cursor:pointer;white-space:nowrap;
  transition:background .18s var(--ease),border-color .18s var(--ease),transform .15s var(--ease),box-shadow .2s var(--ease),color .18s var(--ease);
}
.btn:active{transform:scale(.97)}
.btn-primary{background:var(--red);color:#fff;box-shadow:0 10px 28px -12px var(--red-glow)}
.btn-primary:hover{background:var(--red-deep);box-shadow:0 14px 34px -10px var(--red-glow)}
.btn-ghost{background:rgba(255,255,255,.04);border:var(--hairline);color:var(--ink)}
.btn-ghost:hover{background:rgba(255,255,255,.09);border-color:rgba(246,241,234,.28)}
.btn-light{background:var(--ink);color:#14110D}
.btn-light:hover{background:#fff}
.btn-sm{padding:.46rem 1rem;font-size:.82rem}
.btn-lg{padding:.95rem 1.9rem;font-size:1rem}
.btn[disabled]{opacity:.55;cursor:wait}

/* ── hero + sections ── */
.hero{padding:84px 0 48px}
.hero-tight{padding:60px 0 16px}
.hero-eyebrow{display:inline-flex;align-items:center;gap:.5rem;padding:.4rem .9rem;border:var(--hairline);border-radius:999px;background:rgba(255,255,255,.03);color:var(--ink-soft);margin-bottom:1.2rem}
.cta-row{display:flex;gap:.8rem;flex-wrap:wrap;margin-top:1.7rem}
.section{margin-top:72px}
.section-head{display:flex;align-items:flex-end;justify-content:space-between;gap:1rem;margin-bottom:6px}
.section-eyebrow{display:block;color:var(--red-deep);margin-bottom:.4rem}
.section-title{font-family:var(--sans);font-weight:600;font-size:clamp(1.5rem,3vw,2rem);letter-spacing:-.01em;margin:0}
.section-more{text-decoration:none;color:var(--ink-mute);white-space:nowrap;transition:color .15s}
.section-more:hover{color:var(--red-deep)}

/* ── category chip row ── */
.chip-row{display:flex;flex-wrap:wrap;gap:.55rem;margin-top:1.8rem}
.chip{display:inline-flex;align-items:center;gap:.4rem;padding:.5rem 1rem;border-radius:999px;border:var(--hairline);background:rgba(255,255,255,.03);color:var(--ink-soft);text-decoration:none;font-size:.88rem;transition:all .16s var(--ease)}
.chip:hover{color:var(--ink);border-color:rgba(246,241,234,.3);transform:translateY(-1px)}
.chip-active{background:var(--red);border-color:var(--red);color:#fff}

/* ── cards / grids ── */
.card-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:24px;margin-top:30px}
.card-wrap{position:relative;display:flex}
.card-wrap>.card{flex:1;width:100%}
.card-share{position:absolute;top:12px;right:12px;z-index:3;display:inline-flex;align-items:center;justify-content:center;width:38px;height:38px;border-radius:10px;border:var(--hairline);background:rgba(15,13,10,.74);backdrop-filter:blur(6px);color:var(--ink);cursor:pointer;transition:color .15s,border-color .15s,transform .15s,background .15s}
.card-share:hover{color:#fff;border-color:rgba(246,241,234,.32);background:rgba(15,13,10,.9);transform:translateY(-1px)}
.card-share:active{transform:scale(.94)}
.card-share.is-copied{color:var(--ok);border-color:var(--ok)}
.card-share svg{width:17px;height:17px;display:block}
.card{
  position:relative;background:var(--bone-2);background-image:var(--surface-grad);
  border:var(--hairline);border-radius:var(--radius);overflow:hidden;
  text-decoration:none;display:flex;flex-direction:column;
  transition:transform .26s var(--ease),box-shadow .26s var(--ease),border-color .26s var(--ease);
}
.card:hover{transform:translateY(-5px);box-shadow:var(--shadow-raise);border-color:rgba(246,241,234,.22)}
.card-media{position:relative;margin:0;aspect-ratio:3/2;background:var(--bone-3);overflow:hidden;display:grid;place-items:center}
.card-media::after{content:"";position:absolute;inset:0;background:linear-gradient(to top,rgba(15,13,10,.55),transparent 45%);opacity:.7;transition:opacity .26s}
.card:hover .card-media::after{opacity:.4}
.card-initial{font-family:var(--display);font-weight:700;font-size:3rem;color:var(--ink-mute);opacity:.35;grid-area:1/1}
.card-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;transition:transform .5s var(--ease)}
.card:hover .card-img{transform:scale(1.06)}
.card-datepill{position:absolute;top:12px;left:12px;z-index:2;background:rgba(15,13,10,.74);backdrop-filter:blur(6px);border:var(--hairline);color:var(--ink);padding:.3rem .6rem;border-radius:8px;font-family:var(--mono);font-weight:500;font-size:.64rem;letter-spacing:.06em}
.card-body{padding:17px 18px 20px;display:flex;flex-direction:column;gap:.4rem;flex:1}
.card-meta{color:var(--ink-mute);font-family:var(--mono);font-weight:500;font-size:.66rem;letter-spacing:.07em}
.card-org{margin-top:auto;padding-top:.3rem}
.card-title{font-family:var(--sans);font-weight:600;font-size:1.18rem;line-height:1.22;margin:0;letter-spacing:-.01em}
.card:hover .card-title{color:#fff}
.card-summary{color:var(--ink-soft);font-size:.92rem;margin:0}
/* event tile, mobile-app parity: POI name → red title → Starts/Ends lines */
.card-org-name{color:var(--ink);font-weight:600;font-size:.98rem}
.card-title-accent{color:var(--red-deep)}
.card:hover .card-title-accent{color:var(--red-deep)} /* beat .card:hover .card-title{#fff} */
.card-when{margin-top:auto;padding-top:.4rem;display:grid;gap:.15rem;color:var(--ink-mute);font-family:var(--mono);font-weight:500;font-size:.68rem;letter-spacing:.05em}
/* partner tile: stretched-link card with in-flow Follow button */
.card-link{color:inherit;text-decoration:none}
.card-link::after{content:"";position:absolute;inset:0;z-index:1}
.card-addr{color:var(--ink-soft);font-size:.88rem}
.card-follow{position:relative;z-index:2;margin-top:auto;align-self:flex-start}

/* ── tags ── */
.tag{display:inline-block;font-family:var(--mono);font-weight:500;font-size:.64rem;letter-spacing:.06em;text-transform:uppercase;padding:.26rem .6rem;border:var(--hairline);border-radius:6px;color:var(--ink-soft);margin:0 .3rem .3rem 0;text-decoration:none;transition:all .15s}
.tag:hover{border-color:var(--red);color:var(--red-deep)}
.tag-active{background:var(--red-tint);border-color:var(--red);color:var(--red-deep)}
/* subcategory overflow: hide extras until "See all"; button stays as "See less" (only when JS can toggle them) */
.js .tag-strip:not(.show-all) .tag-extra{display:none}
.tag-see-all{background:transparent;cursor:pointer;color:var(--ink-mute)}
.tag-see-all:hover{border-color:var(--red);color:var(--red-deep)}

/* ── flash ── */
.flash{max-width:var(--maxw);margin:14px auto 0;padding:.8rem 22px;border-radius:10px;font-size:.92rem}
.flash-ok{background:rgba(107,191,147,.14);color:var(--ok);border:1px solid rgba(107,191,147,.3)}
.flash-error{background:var(--red-tint);color:var(--red-deep);border:1px solid rgba(232,26,12,.3)}

/* ── forms ── */
.form-card{max-width:440px;margin:64px auto;background:var(--bone-2);background-image:var(--surface-grad);border:var(--hairline);border-radius:var(--radius-lg);padding:38px;box-shadow:var(--shadow-card)}
/* login/register headings — unclassed h1s, on the title face like page titles.
   The stakeholder list named the hero, Events, Partners and the profile name;
   these come along so every page title in the app shares one face. Size returns
   to the pre-revert 1.8rem. The 1.5rem the Alexandria era used was an attempt to
   keep "CREATE YOUR ACCOUNT" on one line, and that is simply not reachable with
   this face: CHANEY is an Extended (wide) cut, so the string measures two lines
   at 1.5rem (77px) and two at 1.8rem (92px) in the 440px card. Since the wrap is
   unavoidable either way, take the larger, original size — this is exactly how
   the card looked before 7e5552c. */
.form-card h1{font-family:var(--display);font-weight:800;text-transform:uppercase;margin-top:0;font-size:1.5rem;letter-spacing:-.01em}
.field{margin-bottom:1.1rem}
.field label{display:block;font-family:var(--mono);font-weight:500;font-size:.66rem;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft);margin-bottom:.4rem}
.field input,.field select{width:100%;padding:.78rem .95rem;border:var(--hairline);border-radius:10px;background:rgba(0,0,0,.25);font:400 1rem var(--sans);color:var(--ink);transition:border-color .15s,background .15s}
.field input:focus,.field select:focus{outline:none;border-color:var(--red);background:rgba(0,0,0,.4)}
.field input[type=file]{padding:.6rem .7rem;color:var(--ink-soft);font-size:.9rem}
.field-opt{text-transform:none;letter-spacing:0;color:var(--ink-mute);font-size:.9em}
.field-check label{display:flex;align-items:flex-start;gap:.55rem;font-family:var(--sans);font-size:.92rem;letter-spacing:0;text-transform:none;color:var(--ink-soft)}
.field-check input[type=checkbox]{width:auto;margin-top:.2rem;accent-color:var(--red)}
.field-check a{color:var(--ink)}
input::placeholder{color:var(--ink-mute);opacity:1}
.field-error{color:var(--red-deep);font-size:.83rem;margin:.3rem 0 0}
.form-foot{margin-top:1.3rem;font-size:.9rem;color:var(--ink-soft)}
/* show/hide password toggle */
.pw-wrap{position:relative}
.pw-wrap input{padding-right:2.9rem}
.pw-toggle{position:absolute;right:.55rem;top:50%;transform:translateY(-50%);display:flex;align-items:center;padding:.4rem;background:none;border:0;color:var(--ink-mute);cursor:pointer;transition:color .15s}
.pw-toggle:hover,.pw-toggle:focus-visible{color:var(--ink)}
.pw-toggle svg{display:block}
.pw-toggle .pw-eye-off{display:none}
.pw-toggle.is-showing .pw-eye{display:none}
.pw-toggle.is-showing .pw-eye-off{display:block}
/* Google Sign-In block (login/register) */
.google-signin{margin-top:1.2rem;display:grid;justify-items:center;gap:.9rem}
.google-signin.is-loading{opacity:.6;pointer-events:none}
.field-readonly input{opacity:.7;cursor:not-allowed}
.or-divider{display:flex;align-items:center;gap:.8rem;width:100%;color:var(--ink-mute)}
.or-divider::before,.or-divider::after{content:"";flex:1;border-top:var(--hairline)}

/* ── app-gate / 404 ── */
.app-gate{text-align:center;padding:110px 0}
.app-gate .lede{margin-inline:auto}
.app-gate .cta-row{justify-content:center}

/* ── app-download band ── */
.app-band{position:relative;margin-top:84px;padding:54px 40px;border-radius:var(--radius-lg);overflow:hidden;border:var(--hairline);background:linear-gradient(135deg,#1d1812,#14110D);box-shadow:var(--shadow-card)}
.app-band::before{content:"";position:absolute;inset:0;background:radial-gradient(70% 120% at 100% 0,var(--red-glow),transparent 60%);pointer-events:none}
.app-band-inner{position:relative;display:flex;align-items:center;justify-content:space-between;gap:2rem;flex-wrap:wrap}
.app-band h2{font-family:var(--sans);font-weight:600;font-size:clamp(1.5rem,3vw,2.1rem);margin:0 0 .4rem;letter-spacing:-.01em}
.app-band p{color:var(--ink-soft);margin:0;max-width:30rem}

/* ── footer ── */
.site-footer{border-top:var(--hairline);margin-top:90px;background:rgba(0,0,0,.25)}
.footer-inner{max-width:var(--maxw);margin:0 auto;padding:48px 22px 40px;display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:36px}
.footer-brand .wordmark{font-size:1.5rem}
.footer-brand .logo{height:30px}
.footer-brand p{color:var(--ink-mute);font-size:.9rem;margin:.8rem 0 0;max-width:22rem}
.footer-col .footer-h{font-family:var(--mono);font-weight:500;font-size:.66rem;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-mute);margin:0 0 .9rem}
.footer-col a{display:block;color:var(--ink-soft);text-decoration:none;font-size:.92rem;margin-bottom:.6rem;transition:color .15s}
.footer-col a:hover{color:var(--ink)}
.footer-base{max-width:var(--maxw);margin:0 auto;padding:18px 22px 30px;display:flex;justify-content:space-between;gap:1rem;flex-wrap:wrap;color:var(--ink-mute);font-size:.78rem;border-top:var(--hairline)}

/* ── browse: filters + pagination ── */
.filter-bar{display:flex;gap:.6rem;margin:22px 0 14px}
.filter-bar input[type=search]{flex:1;padding:.78rem 1.1rem;border:var(--hairline);border-radius:999px;background:rgba(0,0,0,.25);font:400 .98rem var(--sans);color:var(--ink)}
.filter-bar input[type=search]:focus{outline:none;border-color:var(--red);background:rgba(0,0,0,.4)}
.search-wrap{position:relative;flex:1;display:flex}
.search-wrap input[type=search]{width:100%;padding-right:2.6rem}
.filter-bar input[type=search]::-webkit-search-cancel-button{display:none}
.filter-clear{position:absolute;right:.55rem;top:50%;transform:translateY(-50%);border:0;background:transparent;color:var(--ink-mute);font:400 1.2rem/1 var(--sans);cursor:pointer;padding:.3rem .45rem}
.filter-clear:hover{color:var(--red-deep)}
.tag-strip{display:flex;flex-wrap:wrap;align-items:center;gap:.5rem;margin-bottom:10px}
.tag-strip-right{margin-left:auto;display:inline-flex;gap:.5rem}
.pagination{display:flex;justify-content:center;align-items:baseline;gap:1.6rem;margin-top:46px;color:var(--ink-mute);font-family:var(--mono);font-weight:500;font-size:.74rem;letter-spacing:.06em}
.pagination a{text-decoration:none;color:var(--ink)}
.pagination a:hover{color:var(--red-deep)}

/* ── event detail ── */
.event-hero-frame{aspect-ratio:16/7;width:100%;margin-top:26px;border-radius:var(--radius-lg);overflow:hidden;background:var(--bone-3);box-shadow:var(--shadow-card)}
.event-hero{width:100%;height:100%;object-fit:cover;display:block}
/* immersive overlaid hero (used when an image exists) */
.event-hero-wrap{position:relative;margin-top:26px;border-radius:var(--radius-lg);overflow:hidden;box-shadow:var(--shadow-card);background:var(--bone-3)}
.event-hero-wrap .event-hero{aspect-ratio:16/8}
.event-hero-scrim{position:absolute;inset:0;background:linear-gradient(to top,rgba(10,8,6,.92),rgba(10,8,6,.25) 55%,transparent)}
.event-hero-cap{position:absolute;left:0;right:0;bottom:0;padding:clamp(20px,4vw,44px);max-width:920px}
.event-hero-cap .kicker{color:var(--ink-soft)}
.event-hero-cap .display{font-size:clamp(2rem,4.8vw,3.6rem);margin:.12em 0 .25em;text-shadow:0 2px 34px rgba(0,0,0,.55)}
.event-hero-cap .event-org{margin:.15rem 0 .2rem}
.event-hero-wrap.no-img{display:none}
.event-head{position:relative;padding-right:54px;margin:28px 0 8px}
.event-share{top:4px;right:0}
.event-org-kicker{margin:0 0 .3rem;color:var(--ink-soft)}
.event-desc{color:var(--ink-soft);font-size:1.02rem;line-height:1.7}
.event-org{margin-top:.3rem}
.event-tags{margin-top:.8rem}
.event-cols{display:grid;grid-template-columns:1fr 340px;gap:48px;margin-top:28px;align-items:start}
.event-main{min-width:0}
.event-side{position:sticky;top:88px}
.event-body{color:var(--ink-soft);font-size:1.02rem;line-height:1.7}
.event-body h2,.event-body h3,.event-body h4{font-family:var(--sans);font-weight:600;color:var(--ink)}
.event-body img{max-width:100%;border-radius:10px}
.event-body a{color:var(--red-deep)}
.info-card{border-top:var(--hairline);padding-top:18px;margin-top:30px}
.info-card p{margin:.4rem 0 0}
/* long unbroken URLs/emails (CONTACT etc.) must wrap, not overflow */
.info-card a,.side-card a,.event-body a{overflow-wrap:anywhere}
/* icon rows on detail pages (map pin / clock, mobile-app parity) */
.info-row{display:flex;gap:14px;align-items:flex-start}
.info-icon{width:20px;height:20px;flex:0 0 auto;color:var(--red);margin-top:3px}
/* share affordance restyled as an inline ghost pill (detail-page CTA rows) */
.card-share-inline{position:static;width:auto;height:auto;padding:.7rem 1.3rem;border-radius:999px;gap:.5rem;font:600 .9rem var(--sans)}
.side-card{background:var(--bone-2);background-image:var(--surface-grad);border:var(--hairline);border-radius:var(--radius);padding:20px 22px;margin-bottom:18px;box-shadow:var(--shadow-card)}
.side-card h2{margin-top:0}
.side-note{font-size:.9rem;color:var(--ink-soft);margin:.5rem 0 .9rem}
.price-list{list-style:none;margin:.5rem 0 0;padding:0}
.price-list li{display:flex;justify-content:space-between;gap:1rem;padding:.55rem 0;border-bottom:var(--dashed)}
.price-list li:last-child{border-bottom:0}
.price{color:var(--red-deep);font-variant-numeric:tabular-nums;font-weight:600}
.qr-mode{font-size:.66rem;letter-spacing:.08em;color:var(--ink-mute);margin:.35rem 0 .85rem}
.qr-mode-reusable{color:var(--ok)}
.qr-slot{text-align:center;padding:.4rem 0}
.qr-slot svg{max-width:240px;width:100%;height:auto;background:#fff;border-radius:10px;padding:10px}
.qr-expiry{color:var(--ink-mute);margin:.6rem 0 0;font-size:.6rem}
@media (max-width:860px){.event-cols{grid-template-columns:1fr;gap:8px}.event-side{position:static}}

/* ── partners ── */
.partner-media .partner-logo{object-fit:contain;padding:16%;background:var(--bone-3)}
.partner-cover{aspect-ratio:21/7;width:100%;border-radius:var(--radius-lg);overflow:hidden;background:var(--bone-3);margin-top:26px;box-shadow:var(--shadow-card)}
.partner-cover img{width:100%;height:100%;object-fit:cover}
.partner-cover-empty{display:grid;place-items:center}
.partner-cover-empty svg{width:56px;height:56px;color:var(--ink-mute);opacity:.5}
.partner-head{display:block;margin:30px 0 8px}
.partner-avatar{position:relative;flex:0 0 104px;width:104px;height:104px;margin:0;border:var(--hairline);border-radius:20px;background:var(--bone-3);overflow:hidden;display:grid;place-items:center;box-shadow:var(--shadow-card)}
.partner-avatar img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.partner-avatar .card-initial{font-size:2.6rem}
.verified-mark{color:var(--ok)}
.partner-category{color:var(--red-deep);margin:.1rem 0 .5rem}
.hours-list{list-style:none;margin:.4rem 0 0;padding:0;max-width:26rem}
.hours-list li{display:flex;justify-content:space-between;gap:1rem;padding:.3rem 0;border-bottom:var(--dashed)}
.hours-list li:last-child{border-bottom:0}
.hours-list li span:first-child{color:var(--ink-mute)}
.org-link{color:inherit;text-decoration-color:var(--red);text-underline-offset:3px}
.org-link:hover{color:var(--red-deep)}
@media (max-width:640px){.partner-head{flex-direction:column;gap:16px}}

/* ── user teaser ── */
.user-teaser{text-align:center;padding:84px 0}
.user-teaser .cta-row{justify-content:center}
.user-avatar{position:relative;width:112px;height:112px;margin:0 auto 1.3rem;border:var(--hairline);border-radius:50%;background:var(--bone-3);overflow:hidden;display:grid;place-items:center;box-shadow:var(--shadow-card)}
.user-avatar img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.user-avatar .card-initial{font-size:2.8rem}

/* ── profile (my library) ── */
.profile-head{display:flex;gap:30px;align-items:center;margin:38px 0 10px}
.avatar-block{display:flex;flex-direction:column;align-items:center;gap:.7rem}
.avatar-label{color:var(--ink-mute);max-width:180px;text-align:center;font-size:.68rem;margin:0}
.profile-stats{margin:.6rem 0 0;color:var(--ink-mute)}
.profile-stats strong{color:var(--ink)}
.profile-note{color:var(--ink-soft);font-size:.92rem;margin:.2rem 0 0}
.profile-cta{display:flex;flex-wrap:wrap;align-items:center;gap:14px 18px;margin:18px 0 6px}
.profile-cta .profile-note{margin:0;max-width:32rem}
/* placelist card — mobile-app parity: 4-tile mosaic, eye/heart stats,
   creator + friends-in-common lines, red See-Placelist CTA, share top-right */
.pl-mosaic{display:grid;grid-template-columns:1fr 1fr;grid-template-rows:1fr 1fr;gap:2px;place-items:stretch}
.pl-tile{position:relative;display:grid;place-items:center;background:var(--bone-3);overflow:hidden}
.pl-tile-ph{width:22px;height:22px;color:var(--ink-mute);opacity:.5}
.pl-tile-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.card-stats{display:flex;align-items:center;gap:1.1rem;color:var(--ink-soft)}
.pl-stat{display:inline-flex;align-items:center;gap:.35rem}
.pl-stat svg{width:15px;height:15px;flex:none}
.pl-creator{color:var(--ink-soft);font-size:.88rem}
.pl-mutuals{color:var(--ink-mute);font-size:.85rem}
/* CTA pins to the card's bottom edge, so it lands at the same height on every
   card in a row no matter how many of the optional lines above it are present
   (.pl-creator / .pl-mutuals / .card-summary are each conditional, and
   .pl-collab can wrap .card-meta to a second line). Same margin-top:auto the
   sibling card CTAs use — see .card-follow and .card-when above. No padding-top:
   this is a .btn, so padding would inflate the pill itself; .card-body's
   gap:.4rem already supplies the minimum separation. */
.placelist-card .pl-view{margin-top:auto;align-self:flex-start}
.pl-vis{font-weight:600}
.pl-public{color:var(--ok)}
.pl-private{color:var(--ink-mute)}
.pl-collab{color:var(--red-deep)}
@media (max-width:640px){.profile-head{flex-direction:column;text-align:center;gap:16px}.profile-head .user-avatar{margin-inline:auto}}

/* ── place-list share landing ── */
.placelist-landing{text-align:center;padding:44px 0 96px;max-width:720px;margin:0 auto}
.placelist-cover{margin:0 auto 30px;max-width:580px}
.placelist-landing .lede{margin-inline:auto}
.placelist-desc{color:var(--ink-soft);font-size:1rem;margin-top:.4rem}
.placelist-landing .cta-row{justify-content:center}
.placelist-stores{margin-top:.4rem}
.placelist-foot{color:var(--ink-mute);margin-top:1.8rem;font-size:.66rem}

/* ── reveal motion (only when JS present) ── */
@media (prefers-reduced-motion:no-preference){
  html.js .reveal{opacity:0;transform:translateY(18px);transition:opacity .7s var(--ease),transform .7s var(--ease)}
  html.js .reveal.in{opacity:1;transform:none}
  html.js .r1{transition-delay:.08s}html.js .r2{transition-delay:.16s}html.js .r3{transition-delay:.24s}
}

/* ── responsive ── */
@media (max-width:760px){
  .footer-inner{grid-template-columns:1fr 1fr;gap:28px}
  .footer-brand{grid-column:1/-1}
  .app-band{padding:40px 26px;margin-top:64px}
}
@media (max-width:640px){
  /* Below 640px the six primary items no longer fit one phone line, so the nav
     collapses behind a hamburger and the links become a full-screen overlay
     panel. Genuine progressive enhancement: BOTH the hamburger and the overlay
     are gated on html.js, because body.nav-open is only ever added by JS. With
     JS off the button would otherwise be a dead control and the links would sit
     permanently visibility:hidden — i.e. no header navigation at all on a phone.
     Un-gated, that was live. Keep the html.js prefixes. */
  .nav-inner{gap:clamp(.3rem,2vw,.6rem);padding:12px clamp(10px,3.5vw,16px)}
  .logo{height:clamp(22px,7.4vw,34px)}
  html.js .nav-toggle{display:inline-flex;align-items:center;justify-content:center;
    width:44px;height:44px;background:none;border:0;color:var(--ink);cursor:pointer}
  .nav-toggle .i-close{display:none}

  /* no-JS phones: links stay in the header line and wrap onto a second row */
  html:not(.js) .site-nav{flex-wrap:wrap;gap:.5rem 1rem;justify-content:flex-end}

  /* ── links leave the header line and become a LEFT DRAWER over a dimmed page ──
     A drawer reads as a physical panel, so it slides on transform with no opacity
     fade. visibility (not opacity) gates focusability AND hides the box-shadow,
     which would otherwise bleed on-screen while closed. */
  html.js .site-nav{
    position:fixed;top:0;bottom:0;left:0;z-index:200;
    width:min(86vw,320px);
    flex-direction:column;align-items:stretch;justify-content:flex-start;
    gap:.15rem;
    padding:calc(env(safe-area-inset-top,0px) + 64px) 14px calc(env(safe-area-inset-bottom,0px) + 18px);
    background:var(--raise);background-image:var(--surface-grad);
    border-right:var(--hairline);box-shadow:var(--shadow-raise);
    overflow-y:auto;-webkit-overflow-scrolling:touch;overscroll-behavior:contain;
    transform:translateX(-100%);visibility:hidden;pointer-events:none;
    transition:transform .28s var(--ease),visibility 0s .28s;
  }
  /* rows, not links: full-width tap targets. Beats the ≤310px squeeze rule below on
     specificity (0,2,2 vs 0,1,1), so the old font-size hack is no longer needed. */
  html.js .site-nav a{
    font-size:1.02rem;padding:.72rem .6rem;border-radius:var(--radius-sm);
    white-space:normal;
  }
  .site-nav a.is-active:not(.btn)::after{display:none}   /* underline is odd at this size */
  /* active row: tinted fill only — no left rule. Any border on a drawer row must go all
     the way round the row, never down one edge. */
  html.js .site-nav a.is-active:not(.btn){
    background:var(--red-tint);color:var(--ink)}
  /* the global :focus-visible rule forces border-radius:3px, which would visibly square
     off a 10px row the moment it takes focus — keep the row's own radius so the ring
     traces the row shape */
  html.js .site-nav a:focus-visible{border-radius:var(--radius-sm)}
  /* account actions (Log in/Sign up, or the logout form) sit at the bottom of the panel */
  html.js .site-nav .nav-login,
  html.js .site-nav .inline-form{margin-top:auto}
  html.js .site-nav .btn{font-size:.98rem;padding:.6rem 1.1rem;align-self:stretch;text-align:center}
  html.js .site-nav .inline-form .btn{width:100%}

  /* close button lives INSIDE the panel. This supersedes Fix 3 (§7): the hamburger no
     longer needs position:fixed, because it stays behind the scrim and dims with the
     page. Explicit svg size for the same WebKit 0×0-intrinsic-size reason as .nav-toggle. */
  html.js .nav-close{
    position:absolute;top:calc(env(safe-area-inset-top,0px) + 12px);right:12px;
    width:40px;height:40px;align-items:center;justify-content:center;
    background:none;border:0;color:var(--ink);cursor:pointer;border-radius:50%;
    display:none;
  }
  html.js body.nav-open .nav-close{display:inline-flex}
  html.js .nav-close svg{width:22px;height:22px;flex:none}

  /* scrim — dims AND blurs the page behind the drawer */
  html.js .nav-scrim{
    display:block;position:fixed;inset:0;z-index:150;
    background:rgba(8,6,4,.52);
    backdrop-filter:blur(12px) saturate(115%);
    -webkit-backdrop-filter:blur(12px) saturate(115%);
    opacity:0;visibility:hidden;pointer-events:none;
    transition:opacity .28s var(--ease),visibility 0s .28s;
  }
  html.js body.nav-open .nav-scrim{opacity:1;visibility:visible;pointer-events:auto;transition-delay:0s}
  /* the film grain (body::after, z-index:9999 at body level) paints ABOVE the header's
     z-index:100 context, so it would sit un-blurred on top of the scrim blur. */
  body.nav-open::after{display:none}

  /* iOS scroll-lock: overflow:hidden on <body> is ignored by Safari, so the page
     rubber-bands behind the fixed overlay (and the sticky header + X ride away).
     position:fixed pins the body; JS parks it at -scrollY and restores on close. */
  body.nav-open{position:fixed;left:0;right:0;width:100%;overflow:hidden}
  /* CRITICAL: .site-header.scrolled sets backdrop-filter, which makes the header a
     containing block for position:fixed descendants — without this the overlay is
     trapped inside the (thin) header box instead of covering the viewport.
     transition:none prevents the header's animated backdrop-filter (.3s) from
     fading out over 0.3s — during that fade it is still a containing block, which
     briefly traps the overlay in the header box (a visible flash) before it snaps full. */
  body.nav-open .site-header{backdrop-filter:none;-webkit-backdrop-filter:none;transition:none}
  /* html.js prefix keeps these unambiguously above the gated base rules rather than
     relying on equal specificity + source order */
  html.js body.nav-open .site-nav{
    transform:none;visibility:visible;pointer-events:auto;transition-delay:0s;
  }
  /* JS focuses the PANEL on open (so no control paints :focus-visible on touch —
     the defect Fix 2 removed from the hamburger). The panel itself must not show a
     ring; real controls inside it keep theirs. */
  html.js .site-nav:focus,html.js .site-nav:focus-visible{outline:none}
  /* The hamburger no longer morphs into an X and no longer needs pinning: the close
     control is .nav-close inside the panel, and the toggle sits behind the scrim.
     (Fix 3's position:fixed rule is deliberately gone — superseded, see §7/§9.) */
  body.nav-open .nav-toggle .i-open{display:inline}
  body.nav-open .nav-toggle .i-close{display:none}
  .hero{padding:54px 0 30px}
  main{padding:0 18px 72px}
  /* the old CHANEY face was ultra-wide and needed a hard cap here; Alexandria is
     much narrower, so phones can carry a considerably larger title. The cap is
     2.5rem to meet the base clamp's floor exactly — otherwise the title visibly
     shrinks as the viewport crosses 640px upward. */
  .display{font-size:clamp(2rem,7.6vw,2.5rem)}
}
/* transition-DELAY has to be zeroed too, not just duration: the closed state carries
   `visibility 0s .28s`, so overriding duration alone leaves a ~280ms window where the
   panel is translated away but still visibility:visible. */
@media (prefers-reduced-motion:reduce){
  .site-nav,.nav-scrim{transition-duration:.001s;transition-delay:0s}
  body.nav-open .site-nav,body.nav-open .nav-scrim{transition-delay:0s}
}

/* ── mobile hardening (gateway traffic is mostly phones) ── */
/* responsive media: never let an image force horizontal scroll */
img,svg,video{max-width:100%}
/* nothing may widen the page past the viewport — keeps the sticky header
   (and its Log in / Sign up) pinned on-screen even if content overflows */
html,body{overflow-x:clip}
@media (max-width:400px){
  .card-grid{grid-template-columns:1fr;gap:18px}
  .cta-row .btn{width:100%}
}
/* Ultra-narrow (Galaxy Fold cover screen ~280px). The fluid floors in the 640px
   block bottom out around 310px and the nav starts to overlap the logo, so
   tighten one more step. Nothing above 310px is affected. */
@media (max-width:310px){
  .nav-inner{padding-inline:8px;gap:.25rem}
  .logo{height:18px}
  .site-nav{column-gap:.34rem}
  .site-nav a{font-size:.72rem}
  .site-nav .btn-sm{padding-inline:.5rem;font-size:.68rem}
}
/* touch ergonomics: comfortable tap targets + no iOS focus-zoom on inputs */
@media (pointer:coarse){
  .btn{min-height:44px}
  .btn-sm{min-height:40px;padding-block:.6rem}
  .site-nav a:not(.btn){padding-block:.35rem}
  .tag,.chip{min-height:34px;display:inline-flex;align-items:center}
  input,select,textarea,.filter-bar input[type=search]{font-size:16px}
}
