/* =====================================================================
   Million Beers Club v3 release 2: invite codes and the QR card, share
   pictures, browser help. Jules, 2026-10-29. Plain CSS, no build step.
   Load after v3.css and v3-bob.css, before the event files:
     styles.css > v3.css > v3-bob.css > r2.css > events.css > event-<name>.css

   Same vocabulary as v1 to v3: stout outlines, cream labels with a dashed
   inner line, green buttons with a stout rim, stout sheets, Ultra for
   anything that should feel like a pub sign, Figtree for everything small.

   Event safe: every colour is a token from styles.css or v3.css, or an
   event slot (--ev-*) with today's value as its fallback, so Halloween and
   later events dress every part here. ONE deliberate exception: the QR code
   itself (--qr-ink on --qr-paper) stays dark on light in every event, so it
   always scans. The ticket around it takes the event colours.
   Nothing here needs an inline style or script (the page's security policy).
   Every block names its README section.
   ===================================================================== */

:root {
  /* the QR code: dark modules on a white square (README 1.4). --stout is a deep ink in every event
     (the event kit requires it for plain text), so the code follows the event's ink and still scans. */
  --qr-ink: var(--stout);
  --qr-paper: #FFFFFF;
}

/* ---------- Inline keys: the button to tap, drawn inside a step (README 3.1) ---------- */
.key {
  display: inline-grid; place-items: center; vertical-align: -6px;
  min-width: 28px; height: 24px; padding: 0 5px; margin: 0 1px; border-radius: 7px;
  background: var(--cream-12, rgba(255, 244, 223, .14)); color: currentColor;
}
.key svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.key svg .dot { fill: currentColor; stroke: none; }
.key b { font: 800 12.5px/1 var(--font-body); letter-spacing: .02em; }

/* =====================================================================
   1. INVITE (README section 1)
   ===================================================================== */

/* 1.1 One club: "Invite to [club]" under the club's row, inside the clubs card. Outlined, so the +1
   cap stays the one green thing on the screen. Wraps to two lines for long club names. */
.crow-invite {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  width: calc(100% - 16px); min-height: 46px; margin: 0 8px 8px; padding: 6px 18px 6px 14px;
  border: 2.5px solid var(--stout); border-radius: 999px; background: transparent; color: var(--stout);
  font: 400 16px/1.15 var(--font-display); letter-spacing: .01em; text-align: center; overflow-wrap: anywhere;
  transition: background-color .15s, transform .15s var(--ease-out);
}
.crow-invite:active { background: var(--ink-10); transform: scale(.98); }
.crow-invite svg { flex: none; width: 22px; height: 22px; fill: none; stroke: var(--tap); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }

/* 1.2 Two or more clubs: a round invite button on each row, under the club's count. The row button
   reserves the right-hand column on its second and third lines; the invite button sits there (a sibling
   of the row button, never inside it). */
.clubs--inv .clubs__list li { position: relative; }
.clubs--inv .crow {
  grid-template-columns: auto minmax(0, 1fr) minmax(46px, auto);
  grid-template-areas: "cap name count" "cap next ." "cap meter .";
  align-content: start;          /* the count stays on the first line; the room under it is the button's */
  min-height: 80px; padding-bottom: 12px;
}
.crow-inv {
  position: absolute; right: 9px; bottom: 8px; z-index: 1;
  display: grid; place-items: center; width: 36px; height: 36px; border-radius: 50%;
  border: 2.5px solid var(--stout); background: var(--cream); color: var(--tap);
  box-shadow: 0 3px 0 var(--ink-22);
  transition: transform .15s var(--ease-out), background-color .15s;
}
.crow-inv::before { content: ""; position: absolute; inset: -5px; border-radius: 50%; }   /* a 46px target */
.crow-inv:active { transform: scale(.92); background: var(--ink-10); }
.crow-inv svg { width: 21px; height: 21px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }

/* 1.3 The club page: "Invite to [club]" leads, on its own line. Share a picture, Edit and Starter tools
   sit under it. */
.cp__invite { height: auto; min-height: 56px; margin-top: 16px; padding: 9px 22px; font-size: 17px; line-height: 1.15; overflow-wrap: anywhere; }
.cp__invite svg, .crow-invite svg { overflow: visible; }
/* a label longer than 28 characters ("Invite to" and a long club name): one step smaller, so it stays on two lines */
.cp__invite--long, .crow-invite--long { font-size: 15px; }
.cp__actions--r2 { margin-top: 12px; }

/* 1.4 The invite sheet: a ticket. QR on top, the readable code below the tear, then the link actions.
   The head: a small "Invite to" kicker over the club's name, so a 30 letter name still fits in two lines. */
.sheet__kicker { margin-bottom: 6px; font: 800 11.5px/1.2 var(--font-body); letter-spacing: .15em; text-transform: uppercase; color: var(--gold); }
.invite .sheet__body { padding-top: 2px; }
.ticket {
  position: relative; margin: 4px 4px 0; padding: 14px 16px 16px;
  background: var(--cream); color: var(--stout);
  border: 3px solid var(--stout); border-radius: 22px;
  box-shadow: 0 6px 0 rgba(0, 0, 0, .28);
  text-align: center;
}
.ticket::before {
  content: ""; position: absolute; inset: 5px; border-radius: 16px;
  border: 1.5px dashed var(--ink-22); pointer-events: none;
}
.ticket__kicker {
  display: flex; align-items: center; justify-content: center; gap: 8px;
  font: 800 11.5px/1.2 var(--font-body); letter-spacing: .15em; text-transform: uppercase; color: var(--tap);
}
.ticket__kicker svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
/* the code itself: a white square that already holds the full quiet zone (4 modules) inside its
   viewBox. Nothing is drawn over it, nothing overlaps it, no rounded corners cut into it. */
.qr {
  position: relative; display: block; width: min(272px, 100%, 40vh); aspect-ratio: 1;
  margin: 10px auto 0; background: var(--qr-paper);
  box-shadow: 0 0 0 2.5px var(--stout);
}
.qr__svg { display: block; width: 100%; height: 100%; }
.qr__paper { fill: var(--qr-paper); }
.qr__ink { fill: var(--qr-ink); }
/* the tear: a dashed line with a notch bitten out of each side */
.ticket__tear { position: relative; height: 26px; margin: 4px -16px 0; }
.ticket__tear::before {
  content: ""; position: absolute; left: 22px; right: 22px; top: 50%;
  border-top: 2px dashed var(--ink-22);
}
.ticket__tear::after {
  content: ""; position: absolute; left: -15px; right: -15px; top: 50%; height: 26px; margin-top: -13px;
  background:
    radial-gradient(circle at 0 50%, var(--stout) 0 12px, transparent 12.5px),
    radial-gradient(circle at 100% 50%, var(--stout) 0 12px, transparent 12.5px);
}
/* the readable code: two groups of four, on a stout plate. Tap to copy. */
.code {
  display: inline-flex; align-items: center; gap: 12px; margin-top: 9px; padding: 9px 12px 9px 18px;
  border-radius: 14px; background: var(--stout); color: var(--cream);
  box-shadow: 0 4px 0 var(--ink-22);
  font: 800 30px/1 var(--font-body); letter-spacing: .13em; font-variant-numeric: tabular-nums;
  transition: transform .15s var(--ease-out);
}
.code:active { transform: scale(.97); }
.code__g + .code__g { margin-left: .3em; }
.code__copy { flex: none; width: 34px; height: 34px; border-radius: 10px; display: grid; place-items: center; background: var(--cream-12, rgba(255, 244, 223, .12)); }
.code__copy svg { width: 19px; height: 19px; fill: none; stroke: var(--gold); stroke-width: 2.3; stroke-linecap: round; stroke-linejoin: round; }
/* the link actions: always in reach at the bottom of the sheet, whatever the phone's height */
.invite__actions {
  position: sticky; bottom: calc(-1 * (var(--safe-bottom) + 22px)); z-index: 2;
  display: flex; flex-direction: column; gap: 10px; margin: 16px -12px 0;
  padding: 18px 16px calc(var(--safe-bottom) + 16px);
  background: linear-gradient(180deg, transparent, var(--stout) 22%);
}
.invite__actions .btn { height: auto; min-height: 54px; padding: 8px 20px; line-height: 1.15; }
.invite__note { margin: 4px 14px 0; font: 600 13px/1.45 var(--font-body); color: var(--cream-68, rgba(255, 244, 223, .68)); text-align: center; }

/* 1.5 Join with a code: the existing "Got an invite or code?" sheet, with a code-shaped field */
.codeform { display: flex; flex-direction: column; gap: 10px; padding: 4px 6px 0; }
.codefield {
  height: 66px; font: 800 27px/1 var(--font-body); letter-spacing: .14em; text-transform: uppercase;
  font-variant-numeric: tabular-nums; text-align: center;
}
.codefield::placeholder { font: 700 18px/1 var(--font-body); letter-spacing: 0; text-transform: none; }
.codefield.is-link { font: 700 16px/1.2 var(--font-body); letter-spacing: 0; text-transform: none; text-align: left; }
.codeform__help { font: 600 13px/1.4 var(--font-body); color: var(--cream-68, rgba(255, 244, 223, .68)); text-align: center; }
.codeform .tag__err { margin-top: 0; text-align: center; color: var(--gold); }
.codeform .btn { margin-top: 4px; }

/* 1.5b The first screen: "Got a code?" in the clubs card's head opens the same code sheet, so joining another
   club is one tap from the main screen (most useful in the home screen app, where links cannot open) */
.clubs__code {
  display: inline-flex; align-items: center; gap: 5px; margin: -12px -6px -12px 0; padding: 12px 6px;
  font: 800 12.5px/1 var(--font-body); color: var(--tap);
  text-decoration: underline; text-decoration-thickness: 1.5px; text-underline-offset: 3px;
}
.clubs__code svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.clubs__code:active { opacity: .7; }

/* 1.6 Your clubs: a row that opens the code sheet (replaces the paste box) */
.rowx__icon {
  flex: none; width: 42px; height: 42px; border-radius: 50%; display: grid; place-items: center;
  background: var(--cream-12, rgba(255, 244, 223, .12)); color: var(--gold);
}
.rowx__icon svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.rowx__chev { flex: none; width: 18px; height: 18px; fill: none; stroke: var(--cream-68, rgba(255, 244, 223, .68)); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; }

/* =====================================================================
   2. SHARE PICTURES: the preview sheet and its doors (README section 2)
   The pictures themselves are drawn by share-pictures.js on a canvas.
   ===================================================================== */
.shot .sheet__body { flex: 1; min-height: 0; display: flex; flex-direction: column; gap: 12px; padding-top: 2px; }
.shot__size { flex: none; margin: 0 4px; }
/* the picture fits whatever room is left between the size switch and the actions, never under them */
.shot__frame { position: relative; flex: 1; min-height: 160px; margin: 6px 6px; }
.shot__img {
  position: absolute; inset: 0; margin: auto;
  display: block; max-width: 100%; max-height: 100%; width: auto; height: auto;
  border-radius: 12px; box-shadow: 0 0 0 3px var(--cream), 0 0 0 5.5px var(--stout), 0 16px 34px rgba(0, 0, 0, .45);
  -webkit-touch-callout: default;   /* press and hold keeps "Save to Photos" on iPhone */
}
.shot__actions { flex: none; display: flex; flex-direction: column; gap: 10px; }
.shot__actions .btn { height: auto; min-height: 56px; padding: 8px 20px; line-height: 1.15; }
.shot__hold {
  display: flex; align-items: center; justify-content: center; gap: 8px; text-align: center;
  font: 700 14px/1.35 var(--font-body); color: var(--cream);
}
.shot__hold svg { flex: none; width: 20px; height: 20px; fill: none; stroke: var(--gold); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.shot__note { flex: none; text-align: center; font: 600 12.5px/1.4 var(--font-body); color: var(--cream-68, rgba(255, 244, 223, .68)); }
/* the club page's secondary row gains "Share a picture" */
.btn--icon .shareglyph { fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
/* after a milestone: the toast offers Share for a few seconds */
.toast.is-share .toast__timer { display: none; }
.toast.is-share .toast__undo { display: inline-flex; align-items: center; gap: 6px; }
.toast.is-share .toast__undo svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
/* reached milestones on the club page get a small share button */
.tl__top { align-items: center; }
.tl__share { margin-left: auto; min-height: 34px; width: 34px; padding: 0; }
.tl__share svg { width: 16px; height: 16px; }
/* the big wall photo: Share sits beside Cheers, for your own photos */
.viewer__actions .btn--icon { height: 48px; font-size: 16px; padding: 0 18px; }

/* =====================================================================
   3. BROWSER HELP (README section 3)
   ===================================================================== */
/* 3.1 Numbered steps. On a stout card by default; .steps--ink on a cream label. */
.steps { list-style: none; margin: 10px 0 0; padding: 0; display: flex; flex-direction: column; gap: 8px; counter-reset: step; }
.steps li { display: grid; grid-template-columns: 24px minmax(0, 1fr); align-items: start; gap: 9px; font: 600 15px/1.42 var(--font-body); }
.steps li::before {
  counter-increment: step; content: counter(step);
  display: grid; place-items: center; width: 24px; height: 24px; margin-top: 1px; border-radius: 50%;
  background: var(--gold); color: var(--stout); font: 400 13px/1 var(--font-display);
}
.steps b { font-weight: 800; }
.steps--ink li::before { background: var(--stout); color: var(--cream); }
.steps--ink .key { background: var(--ink-10); }

/* 3.2 The install card on the main screen names the browser, then its steps */
.hint__for {
  display: inline-flex; align-items: center; gap: 6px; margin-bottom: 8px; padding: 4px 9px 4px 7px; border-radius: 999px;
  background: var(--cream-12, rgba(255, 244, 223, .12));
  font: 800 11px/1 var(--font-body); letter-spacing: .12em; text-transform: uppercase; color: var(--cream);
}
.hint__for svg { width: 14px; height: 14px; fill: none; stroke: var(--gold); stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.hint--steps { max-height: calc(100% - 18px); overflow-y: auto; overscroll-behavior: contain; }
.hint--steps .steps li { font-size: 14px; }
.hint__lede { margin-top: 6px; font: 600 14.5px/1.42 var(--font-body); }

/* 3.3 Notification help inside the Notifications sheet: the same steps on the stout sheet */
.note .steps { margin-top: 10px; }
.note .steps li { font-size: 14px; }
.note__for { display: block; margin-bottom: 4px; font: 800 11px/1.2 var(--font-body); letter-spacing: .12em; text-transform: uppercase; color: var(--cream-68, rgba(255, 244, 223, .68)); }

/* 3.4 The in-app browser warning: shown on the join and start screens before anything else */
.join--inapp .join__inner { max-width: 360px; }
.join--inapp .ccap--xl { --cs: 96px; }
.join--inapp .join__title { font-size: min(36px, 9.6vw); }
.inapp { width: 100%; margin-top: 18px; text-align: left; }
.inapp .tag__kicker { display: flex; align-items: center; gap: 7px; }
.inapp .tag__kicker svg { width: 16px; height: 16px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.inapp .tag__title { margin-top: 8px; }
.inapp .btn { height: auto; min-height: 52px; margin-top: 14px; padding: 8px 18px; line-height: 1.15; }
.inapp__or { margin-top: 14px; text-align: center; font: 700 13.5px/1.35 var(--font-body); color: var(--ink-78); }
.inapp__code { display: flex; justify-content: center; }
.inapp__code .code { margin-top: 8px; font-size: 26px; }
/* the quiet way past: on its own cream pill (today's .join__small), so it reads on any part of the beer */
.inapp__stay { margin-top: 14px; padding: 9px 14px; border-radius: 12px; background: rgba(255, 244, 223, .8); font-size: 14.5px; }

/* =====================================================================
   4. LINK PREVIEWS, 1200 x 630 (README section 4)
   Flexbox and absolute positions only, so the same layout ports to the
   image function. Extends .ogcard from v3.css.
   ===================================================================== */
/* 4.1 The club invite preview: the club's cap on the left, the invitation on the right */
.ogi__cap { position: absolute; left: 96px; top: 150px; width: 330px; height: 330px; }
.ogi__skirt { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.ogi__skirt path { fill: var(--tap); stroke: var(--stout); stroke-width: 3.2; stroke-linejoin: round; }
.ogi__face {
  position: absolute; inset: 14%; border-radius: 50%; overflow: hidden; display: flex; align-items: center; justify-content: center;
  background: radial-gradient(circle at 34% 28%, rgba(255, 255, 255, .3), rgba(255, 255, 255, 0) 58%), var(--tap);
  box-shadow: inset 0 0 0 8px var(--stout);
}
.ogi__face img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.ogi__face::after { content: ""; position: absolute; inset: 0; border-radius: 50%; box-shadow: inset 0 0 0 8px var(--stout); }
.ogi__ring { position: absolute; inset: 9%; border-radius: 50%; border: 5px dotted rgba(255, 244, 223, .7); }
.ogi__initials {
  position: relative; font: 400 104px/1 var(--font-display); color: var(--cream);
  -webkit-text-stroke: 16px var(--stout); paint-order: stroke fill; padding-top: 6px;
}
.ogi__txt { position: absolute; left: 476px; right: 64px; top: 132px; bottom: 120px; display: flex; flex-direction: column; justify-content: center; }
.ogi__kicker { margin: 0; font: 800 24px/1 var(--font-body); letter-spacing: .16em; text-transform: uppercase; color: var(--stout); }
.ogi__name {
  margin: 14px 0 0; font: 400 72px/1.08 var(--font-display); color: var(--cream);
  -webkit-text-stroke: .1em var(--stout); paint-order: stroke fill; text-shadow: 0 .07em 0 var(--stout);
  overflow-wrap: anywhere;
}
.ogi__meta { margin: 18px 0 0; font: 700 30px/1 var(--font-body); color: var(--stout); }
.ogi__meta b { font-weight: 800; }
.ogcard__cta--plain { padding-left: 28px; }
/* today's mark in the foam, top left (no new logo: Tim, 29 Oct) */
.ogcard__brand .og__icon { border-radius: 22%; box-shadow: 0 0 0 3px var(--stout); }

/* 4.2 The live world count: the stroke-free fallback. If the image function cannot outline text,
   the number sits on a stout plate instead (background, radius and padding only). */
.ogcard__n--plate {
  -webkit-text-stroke: 0; text-shadow: none; color: var(--cream);
  background: var(--stout); border-radius: .14em; padding: .02em .2em .06em;
  box-shadow: 0 .05em 0 rgba(0, 0, 0, .3);
}
.ogi__name--plate {
  -webkit-text-stroke: 0; text-shadow: none; color: var(--stout);
}
/* 4.3 The fixed fallback picture (no number): used if the live picture cannot be made */
.ogcard__line { max-width: 960px; margin: 0; font: 400 74px/1.08 var(--font-display); color: var(--cream); text-align: center; text-wrap: balance; -webkit-text-stroke: .1em var(--stout); paint-order: stroke fill; text-shadow: 0 .07em 0 var(--stout); }
.ogcard__line2 { margin: 18px 0 0; font: 700 34px/1.2 var(--font-body); color: var(--stout); text-align: center; }

/* ---------- Shorter phones ---------- */
@media (max-height: 700px) {
  .crow-invite { min-height: 42px; margin-bottom: 6px; font-size: 15px; }
  .clubs--inv .crow { min-height: 68px; padding-bottom: 9px; }
  .crow-inv { width: 32px; height: 32px; right: 8px; bottom: 6px; }
  .crow-inv::before { inset: -6px; }
  .crow-inv svg { width: 18px; height: 18px; }
  .ticket { padding-top: 10px; }
  .code { font-size: 26px; }
  .inapp .btn { min-height: 48px; }
  /* the install card: tighter, so four short steps fit the middle of an iPhone SE without scrolling */
  .hint--steps { padding: 10px 14px; }
  .hint--steps .hint__for { margin-bottom: 5px; }
  .hint--steps .steps { margin-top: 7px; gap: 4px; }
  .hint--steps .steps li { font-size: 13.5px; line-height: 1.35; }
  .hint--steps .hint__actions { margin-top: 7px; }
}

/* ---------- Reduce motion: nothing new moves ---------- */
@media (prefers-reduced-motion: reduce) {
  .crow-invite, .crow-inv, .code { transition-duration: .01ms !important; }
}

/* ---------- Release 1 touch-up (README 6): on 360 wide phones "The Founders" was cut to "The Founde..."
   in the one-club row. One step smaller keeps a 12 letter name whole. ---------- */
@media (max-width: 374px) {
  .clubs--one .crow__name { font-size: 18px; }
}
