/* ==========================================================================
   32963 Social Club — one stylesheet, no build step.
   Palette brief: Cherry Red, Turquoise, Ivory, Gold, Sage Green.
   Discipline: ivory is the canvas, cherry is the single call-to-action
   color, turquoise carries interaction (links, the map), gold is hairlines
   and ornament only (it never carries text — too low contrast), sage is the
   calm alternate band.
   ========================================================================== */

/* ------------------------------------------------- the ampersand fix -- */
/*
 * Fraunces draws a completely different ampersand in italic -- a looping
 * swash -- so "5 FT & Under Club" (roman) and "Find your people & say
 * Hello." (italic) showed two unrelated marks for the same character. The
 * club's name contains an ampersand, so it has to be one mark everywhere.
 *
 * This is a family carrying ONE glyph, restricted to U+0026 and listed FIRST
 * in --display. Every other character falls through to real Fraunces
 * untouched.
 *
 * The glyph is no longer Fraunces. It is the ampersand from the club's own
 * crest, traced from the logo artwork, so the name on the page matches the
 * name on the badge. Its metrics were copied from the Fraunces subset it
 * replaced (2000 upem, cap 1400, yMin -50, yMax 1573) so the swap could not
 * shift the surrounding type.
 *
 * FOUR faces, carrying TWO drawings:
 *
 *   weight 100-500  the ampersand from logo-800.png       (advance 1637)
 *   weight 600-900  the ampersand from logo-800-bold.png  (advance 1635)
 *
 * declared for both normal and italic. The club has two logo files, a regular
 * and a bold, and each contains its own ampersand -- so the bold weight is her
 * artwork too, not a thickened copy of the light one. Both were traced to the
 * same height and baseline, so changing weight cannot change the line's size.
 *
 * The weight split matters: headings run at 700 and the light drawing looked
 * starved beside them. The split is by RANGE, not a single value, so any
 * weight the site ever uses lands on a real face.
 *
 * Italic is declared explicitly rather than left to synthesis. With only a
 * normal face the browser would slant the roman drawing and invent an oblique
 * that is not hers.
 *
 * Inlined as a data: URI rather than a file because the editor's WYSIWYG
 * preview runs in an opaque-origin srcdoc iframe where a relative font URL
 * cannot resolve -- and because a <span style="font-style:normal"> around
 * the character would be destroyed the moment the client edits that region
 * (the bridge writes el.textContent, which drops child elements).
 *
 * DO NOT regenerate this by subsetting Fraunces — that would silently undo
 * the crest match. It is built from img/amp.svg (itself traced from the logo
 * with potrace) using fontTools: parse the path, apply potrace's transform,
 * scale to the metrics above, convert cubics to quadratics, and emit a
 * single-glyph woff2 mapped at U+0026.
 *
 * The Fraunces ampersand this replaced is kept, base64 and all, outside the
 * shared folder, so the swap can be undone byte-for-byte.
 */
@font-face {
  font-family: "Fraunces Ampersand";
  font-style: normal;
  font-weight: 100 500;
  font-display: swap;
  src: url("data:font/woff2;base64,d09GMgABAAAAAANUAAoAAAAABYwAAAMIAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAANAqDZIM8ATYCJAMGCwYABCAFgzMHJhuoBEAehXGzU0QojkrjLfp2ZP38e/rnNmk7ABmsDGDXZTIeweD5c++PJrDd76qFFlocJGHAtsj5n3Ppvtg0Wicy5CqgBF9b2nRvKH2RqEV0oHDmLifxoiXM8aGWh28ELCk0DQNOxAj4IVA2ZTq3/eOBHKF/AD7/AQBhngcAA6ACgzIXRwDAAfmmVb7y/6UAADwMAAdVgB0A3oJRgAPYVdNtu8sxNvtp2ntXzQ1L0l1hGIcHL++XHrtoxaWuXbOodob2Xp5Haw4+vIuDjMtt5q6Vn8a6RzR5Yht8FhqXZLP/X8K4MKkXt3vvo2kplk25cGaHyvypW7eMj9Gs6wmW1TvCckEHOY7z8kphOU68h3W/RSct0/Rm1YWzDzmrpxzq2VC8uCg1esqcpmmGYaTHOLOdd8/uRT1HLA+wLGtDlV1owXLtYtRxkRVVHhbjne8tDDZIc9POs6hv2m1ImobFLGL4+gOdi8I6TekNO4WJSoJPIgX8/xlt2UB5LfsQocuZwcrlg0nGUL1kCbvShM5o//BbJxOic/xyLRpaFMQ5L65r/xT5NBr4lcHBiJREBR+MOvvv4p3G15USxZIdlaSrG8mSqIPo1rQPjU6LyvTtrcZz+KXul2rnDbDSOMnZ9JgGlZQ0QTSKswolD60GOd/93xBgMns+w6sLx9fOhrtlThuuVZgLaqgn43VDJF1dzV6u8vFLvm/8ejynbSYBAAACgMBCe8GOXHnvrxIhfAQAVje++96K+dVJe34JMTyeco5eIdjgzzkdABET6UxIQgSAZwe0AR4fSenkg6PSoxAljhSPUDDFh4m8LqApBgZ1SQAoUOQoxNhdikfOe4pP4O+EgGNgARXVVK01aNVf95rFmXEhyCTC1LqV3v8s8fehVbJW1FAppuqIov4dFjrZ2mv14NrgSQhQoRqlVh2RSgUI9X2eiBgFCr0qFZpSMQrBReSSkhBMrWSeZY3fRQhSrkE+glgtSp16tki1RBpUEqPUIfY1E2AWzXplOZFaTmzZM7tinw1G8Ig0w5IEAAAA") format("woff2");
  unicode-range: U+0026;
}
@font-face {
  font-family: "Fraunces Ampersand";
  font-style: normal;
  font-weight: 600 900;
  font-display: swap;
  src: url("data:font/woff2;base64,d09GMgABAAAAAANMAAoAAAAABYAAAAMDAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAANAqDaIM6ATYCJAMGCwYABCAFgyEHJhuUBICeB7atYr0IGhhGXOqAA4mMpwme+rW93f37D2ma8URiukkKlHzQInM1YBJ1KtfcIC7Bg7jlgNaDmGpkhs+jor8DYXMLoiAYSrKU89CLtf0/dC7d2UQjyYacgVGgkZY43D4N37+BnrTA+dXpbNF8hTxuhuijUET8RSxDpBG4gGwBhhBod8E1SleoBKKLp/0BqAOAAgMVjKSYTOoAAUjQvRlsbuNCIKALGYATcAzwoP2KVM4ERRHKdwQ6i+Po5q1QK8GUeFvbjMaMcusKVDS9zVE9KTS5Oi3Zc/KgMkEYXhEbG31jDGwPH3FHrNdH05yd7duzfKHjGkVJdsxw1hRaHOI4Sfr5oZuXp6cGq9Xr6/A1SUJF1IjkCkW5B45cCpsvV6cTp9Jn+I93Hl5OJBdWhiP7lzmqb1UfcVy3jyAI44mbmx2oaJlE5klSIy1i3583CNfhOeDpRj65Wzp9sneCwwb57PltlEKQZN04Df/nWSI8103DGXbJ5uHINh7GzbfqKo34uNfrP6nebNWDNmweKpBuC8h+fnGVUVbNetX5Yv4B/3XnWJNsa5JrqcPvI2YLj3z8wQdbfFopNuvm6ZeodwzoiTSC4OJ40bDp+MLdN3dfuVRUn8XuT09Ew6LeNwTopoSYzkWUiqtj7gzeg4s3MW9ub7PbcXH2eNKI0/34xM6h2QEWFvN9kE0dZ2Psfwt7T21/QRMaasrCwoh1vOLjkCiFzwAACBBs+nb9C6/Fn81YHwG4D3z7v8/aXHxU9IqIjbr4e8glrgqzOQKEqigQ4IGpDNiCYlKQuqM+MCZEiR6hghnhzOp8VOOOkQQ7gDVsIUTbGaFyXoSL3ieinv+2cYlhyZ2glvqo97rNiqGcEyoHd7bcuz8t5NehKadkLC0+BLaclfvGMdZHdAR51bTiTmArTqIwyVJg4oWSkzrDMCHCQHiQIC6zkcLIMQTTCUoOrNFc3BkUybQXK03wsyGShUmRCuEkGSZNvBDMyV31vXYSxAqlD6HjmIKtFRswIKdreQ==") format("woff2");
  unicode-range: U+0026;
}
@font-face {
  font-family: "Fraunces Ampersand";
  font-style: italic;
  font-weight: 100 500;
  font-display: swap;
  src: url("data:font/woff2;base64,d09GMgABAAAAAANUAAoAAAAABYwAAAMIAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAANAqDZIM8ATYCJAMGCwYABCAFgzMHJhuoBEAehXGzU0QojkrjLfp2ZP38e/rnNmk7ABmsDGDXZTIeweD5c++PJrDd76qFFlocJGHAtsj5n3Ppvtg0Wicy5CqgBF9b2nRvKH2RqEV0oHDmLifxoiXM8aGWh28ELCk0DQNOxAj4IVA2ZTq3/eOBHKF/AD7/AQBhngcAA6ACgzIXRwDAAfmmVb7y/6UAADwMAAdVgB0A3oJRgAPYVdNtu8sxNvtp2ntXzQ1L0l1hGIcHL++XHrtoxaWuXbOodob2Xp5Haw4+vIuDjMtt5q6Vn8a6RzR5Yht8FhqXZLP/X8K4MKkXt3vvo2kplk25cGaHyvypW7eMj9Gs6wmW1TvCckEHOY7z8kphOU68h3W/RSct0/Rm1YWzDzmrpxzq2VC8uCg1esqcpmmGYaTHOLOdd8/uRT1HLA+wLGtDlV1owXLtYtRxkRVVHhbjne8tDDZIc9POs6hv2m1ImobFLGL4+gOdi8I6TekNO4WJSoJPIgX8/xlt2UB5LfsQocuZwcrlg0nGUL1kCbvShM5o//BbJxOic/xyLRpaFMQ5L65r/xT5NBr4lcHBiJREBR+MOvvv4p3G15USxZIdlaSrG8mSqIPo1rQPjU6LyvTtrcZz+KXul2rnDbDSOMnZ9JgGlZQ0QTSKswolD60GOd/93xBgMns+w6sLx9fOhrtlThuuVZgLaqgn43VDJF1dzV6u8vFLvm/8ejynbSYBAAACgMBCe8GOXHnvrxIhfAQAVje++96K+dVJe34JMTyeco5eIdjgzzkdABET6UxIQgSAZwe0AR4fSenkg6PSoxAljhSPUDDFh4m8LqApBgZ1SQAoUOQoxNhdikfOe4pP4O+EgGNgARXVVK01aNVf95rFmXEhyCTC1LqV3v8s8fehVbJW1FAppuqIov4dFjrZ2mv14NrgSQhQoRqlVh2RSgUI9X2eiBgFCr0qFZpSMQrBReSSkhBMrWSeZY3fRQhSrkE+glgtSp16tki1RBpUEqPUIfY1E2AWzXplOZFaTmzZM7tinw1G8Ig0w5IEAAAA") format("woff2");
  unicode-range: U+0026;
}
@font-face {
  font-family: "Fraunces Ampersand";
  font-style: italic;
  font-weight: 600 900;
  font-display: swap;
  src: url("data:font/woff2;base64,d09GMgABAAAAAANMAAoAAAAABYAAAAMDAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAABmAANAqDaIM6ATYCJAMGCwYABCAFgyEHJhuUBICeB7atYr0IGhhGXOqAA4mMpwme+rW93f37D2ma8URiukkKlHzQInM1YBJ1KtfcIC7Bg7jlgNaDmGpkhs+jor8DYXMLoiAYSrKU89CLtf0/dC7d2UQjyYacgVGgkZY43D4N37+BnrTA+dXpbNF8hTxuhuijUET8RSxDpBG4gGwBhhBod8E1SleoBKKLp/0BqAOAAgMVjKSYTOoAAUjQvRlsbuNCIKALGYATcAzwoP2KVM4ERRHKdwQ6i+Po5q1QK8GUeFvbjMaMcusKVDS9zVE9KTS5Oi3Zc/KgMkEYXhEbG31jDGwPH3FHrNdH05yd7duzfKHjGkVJdsxw1hRaHOI4Sfr5oZuXp6cGq9Xr6/A1SUJF1IjkCkW5B45cCpsvV6cTp9Jn+I93Hl5OJBdWhiP7lzmqb1UfcVy3jyAI44mbmx2oaJlE5klSIy1i3583CNfhOeDpRj65Wzp9sneCwwb57PltlEKQZN04Df/nWSI8103DGXbJ5uHINh7GzbfqKo34uNfrP6nebNWDNmweKpBuC8h+fnGVUVbNetX5Yv4B/3XnWJNsa5JrqcPvI2YLj3z8wQdbfFopNuvm6ZeodwzoiTSC4OJ40bDp+MLdN3dfuVRUn8XuT09Ew6LeNwTopoSYzkWUiqtj7gzeg4s3MW9ub7PbcXH2eNKI0/34xM6h2QEWFvN9kE0dZ2Psfwt7T21/QRMaasrCwoh1vOLjkCiFzwAACBBs+nb9C6/Fn81YHwG4D3z7v8/aXHxU9IqIjbr4e8glrgqzOQKEqigQ4IGpDNiCYlKQuqM+MCZEiR6hghnhzOp8VOOOkQQ7gDVsIUTbGaFyXoSL3ieinv+2cYlhyZ2glvqo97rNiqGcEyoHd7bcuz8t5NehKadkLC0+BLaclfvGMdZHdAR51bTiTmArTqIwyVJg4oWSkzrDMCHCQHiQIC6zkcLIMQTTCUoOrNFc3BkUybQXK03wsyGShUmRCuEkGSZNvBDMyV31vXYSxAqlD6HjmIKtFRswIKdreQ==") format("woff2");
  unicode-range: U+0026;
}

:root {
  /* surfaces */
  --ivory:        #FCF8F1;
  --ivory-deep:   #F4EDE0;
  --paper:        #FFFFFF;

  /* ink */
  --ink:          #241F1C;
  --ink-soft:     #5A514B;   /* 7.2:1 on ivory */
  --ink-faint:    #8A7F77;

  /* accents */
  --cherry:       #C8102E;   /* 5.5:1 on ivory */
  --cherry-deep:  #97091F;
  --cherry-tint:  #FBE9EC;
  --turq-ink:     #0E7373;   /* 5.3:1 on ivory — the link color */
  --turq:         #128C8C;
  --turq-bright:  #1FB3B3;
  --turq-tint:    #E4F5F4;
  --gold:         #C9A227;
  --gold-soft:    #E7D49B;
  --gold-ink:     #8A6F14;   /* 4.6:1 on ivory — the ONE gold that may carry
                                text, added for the Founding 100 badge. Plain
                                --gold stays ornament-only, per the note above;
                                it is used for that badge's text on the dark
                                map tooltip only, where it measures 6.7:1. */
  --sage:         #8FA37E;
  --sage-deep:    #5F7350;
  --sage-tint:    #EDF1E8;

  /* type */
  --display: "Fraunces Ampersand", "Fraunces", "Iowan Old Style", Georgia, serif;
  --body: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;

  /* rhythm */
  --measure: 68ch;
  --shell: 1180px;
  --gutter: clamp(1.25rem, 5vw, 3rem);
  --band: clamp(4rem, 9vw, 7.5rem);
  --radius: 14px;
  --radius-lg: 26px;

  --shadow-sm: 0 1px 2px rgba(36, 31, 28, .06), 0 4px 14px rgba(36, 31, 28, .05);
  --shadow-md: 0 2px 6px rgba(36, 31, 28, .07), 0 18px 44px rgba(36, 31, 28, .09);
  --ring: 0 0 0 3px rgba(18, 140, 140, .35);
}

/* --------------------------------------------------------------- reset -- */

*, *::before, *::after { box-sizing: border-box; }

/* Any author rule that sets `display` outranks the browser's [hidden]
   default, which silently reveals every panel this site hides. Say it once,
   loudly, so `hidden` keeps meaning hidden. */
[hidden] { display: none !important; }

html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after {
    animation-duration: .01ms !important; animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
}

body {
  margin: 0;
  background: var(--ivory);
  color: var(--ink);
  font: 400 clamp(1rem, .96rem + .2vw, 1.075rem)/1.65 var(--body);
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

/* A warm, barely-there wash so the ivory does not read as flat gray-white. */
body::before {
  content: "";
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: -1;
  background:
    radial-gradient(60rem 40rem at 12% -8%, rgba(31, 179, 179, .10), transparent 62%),
    radial-gradient(52rem 38rem at 92% 4%, rgba(200, 16, 46, .07), transparent 60%),
    radial-gradient(46rem 34rem at 50% 108%, rgba(201, 162, 39, .09), transparent 64%);
}

img, svg { max-width: 100%; }
img { height: auto; display: block; }

h1, h2, h3, h4 {
  font-family: var(--display);
  font-weight: 600;
  line-height: 1.1;
  letter-spacing: -.015em;
  margin: 0 0 .5em;
  /* NO font-variation-settings, deliberately.
   *
   * There used to be `"SOFT" 20, "WONK" 0` here. Both were dead: the site
   * asks Google Fonts for Fraunces with the ital, opsz and wght axes only,
   * so SOFT and WONK are not in the file the browser downloads and setting
   * them did nothing. Removing the line was verified to change not one pixel
   * across twelve headings.
   *
   * It is called out because it cost real time. The club asked to soften the
   * swash-tailed J and hooked f, this line looked like the switch that would
   * do it, and it is not -- those shapes are simply how Fraunces is drawn.
   * The club has since chosen to keep them. If anyone ever does want to try
   * those axes, they have to be added to the font URL first. */
}
h1 { font-size: clamp(2.35rem, 1.5rem + 4.2vw, 4.35rem); font-weight: 700; }
h2 { font-size: clamp(1.85rem, 1.3rem + 2.4vw, 2.85rem); }
h3 { font-size: clamp(1.2rem, 1.05rem + .6vw, 1.5rem); }
p  { margin: 0 0 1.15em; max-width: var(--measure); }
ul, ol { max-width: var(--measure); }

a { color: var(--turq-ink); text-decoration-thickness: 1px; text-underline-offset: .18em; }
a:hover { color: var(--cherry); }

:focus-visible {
  outline: 2px solid var(--turq-ink);
  outline-offset: 3px;
  border-radius: 4px;
}

.skip-link {
  position: absolute; left: 50%; top: 0; transform: translate(-50%, -120%);
  background: var(--ink); color: var(--ivory); padding: .7rem 1.2rem;
  border-radius: 0 0 10px 10px; z-index: 200; font-weight: 600;
}
.skip-link:focus { transform: translate(-50%, 0); color: var(--ivory); }

.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
}

/* -------------------------------------------------------------- layout -- */

.shell { width: min(100% - (var(--gutter) * 2), var(--shell)); margin-inline: auto; }
.shell--narrow { width: min(100% - (var(--gutter) * 2), 780px); }
.band { padding-block: var(--band); }
.band--tint  { background: var(--ivory-deep); }
.band--sage  { background: var(--sage-tint); }
.band--turq  { background: var(--turq-tint); }

.eyebrow {
  font: 600 .78rem/1 var(--body);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--turq-ink);
  display: flex; align-items: center; gap: .7rem;
  margin: 0 0 1.1rem;
  /* Most eyebrows are two or three words. Privacy's and Terms' are whole
     sentences, and left to itself the line broke one word onto row two
     ("...EVERYTHING ELSE / IS NOT"), which reads like a mistake next to the
     gold rule. Balancing splits the rows evenly instead. line-height comes
     up from 1 because two rows of uppercase at .18em tracking collide. */
  text-wrap: balance;
  line-height: 1.35;
}
.eyebrow::before {
  content: ""; width: 2.2rem; height: 2px; flex: none;
  background: linear-gradient(90deg, var(--gold), var(--gold-soft));
}
/* The eyebrow is a <p>, so it inherits max-width:68ch. Centering the text
   inside that box is not enough — the box itself must span the container,
   or on a wide screen it sits left of center with its contents neatly
   centered inside it. */
.eyebrow--center { justify-content: center; max-width: none; margin-inline: auto; }
.eyebrow--center::after {
  content: ""; width: 2.2rem; height: 2px; flex: none;
  background: linear-gradient(270deg, var(--gold), var(--gold-soft));
}

.lede { font-size: clamp(1.1rem, 1rem + .5vw, 1.35rem); color: var(--ink-soft); line-height: 1.6; }
.center { text-align: center; }
/* h1 is in this list because a centered section can now carry the page's
   h1 (About Us & Mission opens with the mission). It was omitted only
   because no centered section had one. Headings carry no max-width today,
   so this changes nothing yet -- it is here so that adding one later does
   not silently left-align the page's biggest heading. */
.center p, .center h1, .center h2, .center .lede { margin-inline: auto; }

/* ------------------------------------------------------------- buttons -- */

.btn {
  --btn-bg: var(--cherry);
  --btn-fg: #fff;
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  /* justify-content centers the label as a BOX. It says nothing about the
     lines inside that box, so the moment a label wrapped -- "My Profile"
     breaking after "My" in the nav -- both lines went hard left and the
     button looked broken. text-align governs the lines; nowrap stops a short
     button label from wrapping at all, which is what it should never do. */
  text-align: center;
  white-space: nowrap;
  padding: .95rem 1.7rem;
  border: 1.5px solid transparent;
  border-radius: 999px;
  background: var(--btn-bg);
  color: var(--btn-fg);
  font: 600 1rem/1 var(--body);
  letter-spacing: .01em;
  text-decoration: none;
  cursor: pointer;
  transition: transform .18s ease, box-shadow .18s ease, background-color .18s ease;
  box-shadow: 0 1px 2px rgba(151, 9, 31, .18), 0 10px 22px -12px rgba(151, 9, 31, .55);
}
/* Hover recolors through the SAME token the base reads -- a literal
   `color` here outranks every variant's token and turned the ghost
   button white-on-white. */
.btn:hover { --btn-bg: var(--cherry-deep); --btn-fg: #fff; transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn .icon { width: 1.15em; height: 1.15em; }

.btn--ghost {
  --btn-bg: transparent; --btn-fg: var(--ink);
  border-color: rgba(36, 31, 28, .22);
  box-shadow: none;
}
.btn--ghost:hover { --btn-bg: var(--paper); --btn-fg: var(--ink); border-color: var(--gold); }

.btn--teal { --btn-bg: var(--turq-ink); box-shadow: 0 1px 2px rgba(14,115,115,.18), 0 10px 22px -12px rgba(14,115,115,.6); }
.btn--teal:hover { --btn-bg: #0a5c5c; }

.btn--lg { padding: 1.1rem 2.1rem; font-size: 1.06rem; }
.btn--block { width: 100%; }
.btn[disabled], .btn[aria-disabled="true"] { opacity: .5; cursor: not-allowed; transform: none; }

/* An icon inside a button pushes the LABEL off center.
 *
 * justify-content centers the whole [label + gap + icon] group, so on "Join
 * Here →" the words sit ~14px left of the middle and on "⬤ Facebook Group"
 * they sit ~14px right of it -- measured, and visible once you look for it.
 * Padding on the opposite side is widened by exactly the icon's own width
 * plus the gap, which puts the label back in the middle of the button and
 * leaves the icon in the space beside it.
 *
 * Done with padding rather than by taking the icon out of the flow: an
 * absolutely positioned icon centers the label just as well right up until a
 * long label runs underneath it.
 *
 * Which side the icon sits on cannot be read from CSS alone. A button whose
 * only element child is the icon matches :first-child AND :last-child at the
 * same time -- and every icon button here is exactly that, because the label
 * beside it is a bare text node. So the two buttons that lead with an icon
 * carry .btn--icon-start in the markup, and everything else is taken to
 * trail, which is the pattern the rest of the site follows. */
.btn:has(> .icon) { padding-left: calc(1.7rem + 1em + .55rem); padding-right: 1.7rem; }
.btn--lg:has(> .icon) { padding-left: calc(2.1rem + 1em + .55rem); padding-right: 2.1rem; }
.btn--icon-start:has(> .icon) { padding-left: 1.7rem; padding-right: calc(1.7rem + 1em + .55rem); }
.btn--lg.btn--icon-start:has(> .icon) { padding-left: 2.1rem; padding-right: calc(2.1rem + 1em + .55rem); }

.btn-row { display: flex; flex-wrap: wrap; gap: .85rem; }
.btn-row--center { justify-content: center; }

.icon { width: 1em; height: 1em; fill: currentColor; flex: none; }

/* The main call to action and its quieter twin, stacked. Whichever of the two
   suits the visitor is the button and the other is the text link -- script.js
   decides, from whether anyone has ever signed in on this browser. */
.nav-cta { display: inline-flex; flex-direction: column; align-items: center; gap: .3rem; }
.nav-cta__alt {
  font-size: .85rem; font-weight: 600; color: var(--ink-soft);
  text-decoration: none; padding: .1rem .3rem; border-radius: 6px;
}
.nav-cta__alt:hover { color: var(--cherry); text-decoration: underline; }

/* ---------------------------------------------------------------- nav --- */

.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(252, 248, 241, .88);
  backdrop-filter: saturate(1.4) blur(12px);
  border-bottom: 1px solid rgba(201, 162, 39, .3);
}
.site-header__inner {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; padding-block: .85rem;
}

.brand { display: inline-flex; align-items: center; gap: .7rem; text-decoration: none; color: var(--ink); }
.brand__mark { width: 32px; height: 38px; flex: none; }
.brand__logo {
  width: 46px; height: 46px; flex: none;
  /* Transparent PNG: the artwork supplies its own circular edge, and the
     branch's leaves extend past the circle at the lower left -- no CSS
     crop, ring, or shadow on top of it. */
}

/* In the HEADER the badge is a crest: far larger than the bar, hanging out
   of it over the page. The header is sticky, so script.js collapses it to
   an inline mark after the first bit of scrolling -- a quarter-page badge
   floating over every screen would wear out its welcome fast. The footer
   keeps the small inline version above.

   Note for anyone tempted to tighten the interior pages further: the crest
   starts at .shell's left edge (1180px) and interior copy sits in
   .shell--narrow (780px). Both are centered, so their left edges are always
   exactly (1180 - 780) / 2 = 200px apart. Only a crest of 200px or less
   can miss the text column entirely; at this size it cannot, so interior
   pages must clear it vertically. That trade was measured and the large
   crest was chosen deliberately. */
:root { --crest: clamp(172px, 21vw, 345px); }
.site-header .brand {
  position: relative;
  padding-left: calc(var(--crest) + 18px);
  min-height: 50px;
  display: inline-flex; align-items: center;
}
.site-header .brand__logo {
  position: absolute; left: 0; top: -4px;
  width: var(--crest); height: var(--crest);
  transition: width .28s ease, height .28s ease;
}
.site-header.is-scrolled .brand { padding-left: 64px; transition: padding-left .28s ease; }
.site-header.is-scrolled .brand__logo { width: 64px; height: 64px; }
.site-header .brand { transition: padding-left .28s ease; }
@media (max-width: 700px) {
  :root { --crest: 128px; }
}
/* Interior pages open on the SAME rhythm as the home hero.

   The old rule cleared the crest's full overhang, then the first
   <section class="band"> added its own var(--band) on top -- two independent
   clearances stacked, ~263px of dead space at 1500px wide against the home
   page's 88px. index.html never cleared the crest at all: its hero starts
   158px INSIDE the crest's vertical span and simply passes to the right of
   it, because the badge is a left-hand letterhead and hero content is
   centered. Interior pages do the same thing now.

   Both numbers are sweep results, not taste. Ten interior pages were tested
   at 390/700/820/1000/1200/1500/1800 against offsets from 60 to 180, using
   PER-LINE rects (range.getClientRects(), not the union bounding box -- the
   union overstates a centered two-line h1, and re-running with per-line
   rects returned identical verdicts, so the limit is real geometry):

     - 60px   clean at every width
     - 80px   breaks at 390; privacy also at 820
     - 100px  clean at 1200 and above, breaks below
     - 120px  about + members break at EVERY width, 390 through 1800

   Hence 100 above 1200px and 60 below. The binding pages are about and
   members: their headlines are long, wrap to two lines, and the wider line
   reaches left under the badge.

   This is the floor while --crest is 21vw. It does NOT reach the home
   page's 88px and cannot: the crest starts at .shell's left edge and the
   copy sits in .shell--narrow, whose left edge is a constant 200px to its
   right, so only a crest of 200px or less could miss the column entirely.
   index.html escapes only because its headline is short and centered.
   Re-run the sweep before changing either number. */
body.interior main { padding-top: calc(var(--crest) - 60px); }
body.interior main > .band:first-child { padding-top: 0; }

/* Every interior page opens with .shell--narrow, whose column begins a
   constant 200px right of .shell's left edge — clear of the crest. That is
   what the tuning above depends on, and About Us & Mission briefly broke it by
   opening with a full-width section: the eyebrow landed directly under the
   logo. The fix was to center that section like every other page's opener, not
   to pad around it. If a page ever does need to open full-width, this is the
   comment that explains why it looks wrong. */
@media (min-width: 1200px) {
  body.interior main { padding-top: calc(var(--crest) - 100px); }
}
.brand__text { display: flex; flex-direction: column; line-height: 1; }
.brand__num {
  /* "5 FT & Under" runs longer than "32963" did; a notch smaller keeps
     the lockup from crowding the nav. */
  font: 700 1.18rem/1 var(--display);
  letter-spacing: .01em;
  /* NO font-variation-settings, deliberately.
   *
   * There used to be `"SOFT" 20, "WONK" 0` here. Both were dead: the site
   * asks Google Fonts for Fraunces with the ital, opsz and wght axes only,
   * so SOFT and WONK are not in the file the browser downloads and setting
   * them did nothing. Removing the line was verified to change not one pixel
   * across twelve headings.
   *
   * It is called out because it cost real time. The club asked to soften the
   * swash-tailed J and hooked f, this line looked like the switch that would
   * do it, and it is not -- those shapes are simply how Fraunces is drawn.
   * The club has since chosen to keep them. If anyone ever does want to try
   * those axes, they have to be added to the font URL first. */
}
.brand__sub {
  font: 600 .58rem/1 var(--body);
  letter-spacing: .26em; text-transform: uppercase; color: var(--ink-faint); margin-top: .3rem;
}

.nav { display: flex; align-items: center; gap: .15rem; margin-left: auto; }
/* A menu label is a name, so it never breaks across lines: "About Us &
   Mission" wrapping after the ampersand read as two menu items rather than
   one. The room for that comes out of the padding.

   The header is capped at the 1180px shell, the crest takes 363px of it, and
   these seven labels want 824px -- which overflowed the remainder by SEVEN
   pixels and wrapped the whole row. Tighter spacing buys back far more than
   that, and the breakpoint below hands over to the menu button well before
   it gets tight again. */
.nav a {
  padding: .55rem .55rem; border-radius: 999px; text-decoration: none;
  color: var(--ink-soft); font-weight: 500; font-size: .95rem;
  white-space: nowrap;
}
.nav a:hover { background: rgba(201, 162, 39, .16); color: var(--ink); }
/* The current-page pill must not repaint the Join button's cherry fill. */
.nav a[aria-current="page"]:not(.btn) { color: var(--ink); font-weight: 600; background: rgba(201, 162, 39, .2); }
/* `.nav a` is more specific than `.btn`, so the pill needs its color said
   out loud or it inherits the muted link ink and vanishes on cherry. */
.nav a.btn { margin-left: .5rem; padding: .65rem 1.25rem; font-size: .95rem; color: #fff; }
.nav a.btn:hover { background: var(--cherry-deep); color: #fff; }

.nav-toggle {
  display: none; align-items: center; justify-content: center;
  width: 44px; height: 44px; border: 1.5px solid rgba(36,31,28,.2);
  border-radius: 12px; background: transparent; cursor: pointer; color: var(--ink);
}
.nav-toggle__bars, .nav-toggle__bars::before, .nav-toggle__bars::after {
  content: ""; display: block; width: 19px; height: 2px; background: currentColor; border-radius: 2px;
  transition: transform .2s ease, opacity .2s ease;
}
.nav-toggle__bars::before { transform: translateY(-6px); }
.nav-toggle__bars::after  { transform: translateY(4px); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars { background: transparent; }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::before { transform: rotate(45deg); }
.nav-toggle[aria-expanded="true"] .nav-toggle__bars::after  { transform: translateY(-2px) rotate(-45deg); }

/* THE MENU BUTTON TAKES OVER AT 1280px.
 *
 * Measured, not guessed. The header holds the crest, seven links and the call
 * to action. The crest is 21vw (up to 345px), the links need 627px and the
 * button 133px, while the shell they sit in is only the viewport minus its
 * gutters -- so the row stops fitting at about 1175px and the call to action
 * starts sliding off the right-hand edge. At 1090px it hung 60px past the
 * edge of the page.
 *
 * 1280 rather than 1180 on purpose: at 1180 there were eleven pixels to
 * spare, which one more menu item or one different font would swallow. The
 * hamburger appearing a little early costs nothing; a header that overflows
 * costs the page.
 *
 * script.js does NOT repeat this number -- it asks whether the hamburger is
 * showing. Changing it here is enough. */
@media (max-width: 1280px) {
  .nav-toggle { display: inline-flex; }
  .nav {
    position: absolute; inset: 100% 0 auto; flex-direction: column; align-items: stretch;
    gap: .15rem; padding: .8rem var(--gutter) 1.4rem;
    background: var(--ivory); border-bottom: 1px solid rgba(201,162,39,.35);
    box-shadow: var(--shadow-md);
  }
  .nav[hidden] { display: none; }
  .nav a { padding: .8rem 1rem; font-size: 1.05rem; }

  /* The call to action comes OUT of the collapsed menu and sits in the header
     bar, to the left of the menu button.

     Inside the menu it was invisible until you opened the menu -- so on a
     phone the site's single most important button was two taps away and the
     club could not see it at all. Out here it is the first thing in the top
     right on every screen, which is where it was before the menu ever
     collapsed. The quiet second link stays in the menu: it is the
     alternative, and two buttons side by side in a narrow bar is one too
     many. */
  /* The call to action stays in the header bar, left of the menu button,
     rather than collapsing into the menu with the links.

     Inside the menu it was invisible until you opened it -- so on a phone the
     site's single most important button was two taps away, and the club could
     not see it at all. Out here it is the first thing in the top right on
     every screen, which is where it sat before the menu ever collapsed. */
  .nav-cta { order: 2; flex-direction: row; align-items: center; gap: .5rem; }
  .nav-toggle { order: 3; }
  .nav-cta .btn { padding: .6rem 1.1rem; font-size: .95rem; }
  .nav-cta__alt { font-size: .8rem; }
}

/* ---------------------------------------------------------------- hero -- */

.hero { padding-block: clamp(3rem, 6vw, 5.5rem) clamp(2rem, 4vw, 3rem); text-align: center; }
.hero__mark { width: 62px; height: 74px; margin: 0 auto 1.4rem; display: block; }
/* The trademark mark. Sized in em so it tracks whatever it follows -- the
   hero headline is fluid type and the footer wordmark is small, and one rule
   has to look right on both. Raised rather than superscripted: `vertical-align:
   super` also shrinks the glyph in some browsers, which on top of the .42em
   here left it too small to read at all. */
/* The hero headline's trademark, and only that one. The ™ character already
   draws itself small and raised, but at ~70px "small" is still bigger than the
   mark should ever be, so here it is scaled down and re-aligned by hand. The
   footer marks are plain characters and want none of this -- see the note
   below this rule. */
.tm {
  /* In em, so it tracks the headline's fluid size (37.6px to 69.6px) instead
     of being right at one width and wrong at the rest. */
  font-size: .34em;
  /* `vertical-align: super` shrinks the glyph a second time on top of the
     size above, which left it illegible; raising it explicitly does not.
   *
   * The raise aligns the TOP of the mark with the top of the letters it
   * follows. Measured from the fonts' real ink extents rather than nudged by
   * eye, using:
   *
   *     bottom = Abase / r - Amark          (in the mark's own em)
   *
   * where Abase is how far the neighboring letter's ink rises above the
   * baseline, Amark the same for the mark, and r is the mark's font-size
   * divided by its neighbor's. All em, so it holds at every viewport width --
   * the headline is fluid type from 37.6px to 69.6px and r stays 0.34 across
   * the whole range, so the alignment does too.
   *
   * Here: Fraunces "b" ascender 0.749em, mark 0.710em, r 0.34, giving
   * 0.749/0.34 - 0.710 = 1.49.
   *
   * The formula is kept here because it is the only honest way to place this
   * glyph: it is not a superscript the font positions for you, and eyeballing
   * it at one screen width guarantees it is wrong at another. */
  vertical-align: baseline;
  position: relative;
  bottom: 1.49em;
  margin-left: .1em;
  /* The headline carries its own tracking, which does not belong on a single
     raised glyph sitting tight against the word before it. */
  letter-spacing: 0;
  font-weight: 700;
  /* Reads as part of the name, so it must not stretch the line box. */
  line-height: 0;
}

/* The two footer marks deliberately use NO class at all -- they are a plain
 * &trade; character in the markup.
 *
 * The ™ glyph is already drawn small and raised inside its own em box; that
 * is what the character is. Shrinking it again only helps where the
 * surrounding type is big enough to make even that small glyph loud, which is
 * true of the ~70px headline and of nothing else on this site. Applied to the
 * footer wordmark (9.28px) and the copyright line (13.6px) it produced a 7px
 * smudge -- the browser's own minimum font size, and below what anyone can
 * read. At their natural size those two need no help and no rule. */

.hero h1 { margin-bottom: .35em; }
.hero h1 .line { display: block; }
.hero h1 .accent { color: var(--cherry); font-style: italic; }
.hero__sub { font-size: clamp(1.08rem, 1rem + .55vw, 1.32rem); color: var(--ink-soft); margin-inline: auto; max-width: 58ch; }
.hero .btn-row { margin-top: 2rem; }

.hero__rule {
  width: min(100%, 460px); height: 1px; margin: 2.6rem auto 0;
  background: linear-gradient(90deg, transparent, var(--gold-soft) 15%, var(--gold) 50%, var(--gold-soft) 85%, transparent);
}

.principle {
  font-family: var(--display);
  font-size: clamp(1.15rem, 1rem + .7vw, 1.55rem);
  font-style: italic;
  color: var(--ink);
  line-height: 1.45;
  max-width: 24ch;
  margin: 1.6rem auto 0;
}
.principle .split { display: block; color: var(--cherry); }

/* ----------------------------------------------------------------- map -- */

.map-section { padding-block: clamp(1rem, 3vw, 2rem) var(--band); }

.map-card {
  background: var(--paper);
  border: 1px solid rgba(201, 162, 39, .45);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-md);
  overflow: hidden;
}
.map-card__head {
  display: flex; flex-wrap: wrap; align-items: flex-end; justify-content: space-between;
  gap: 1rem 1.5rem; padding: 1.4rem clamp(1.1rem, 3vw, 2rem) 1.1rem;
  border-bottom: 1px solid var(--ivory-deep);
}
.map-card__head h2 { margin: 0; font-size: clamp(1.4rem, 1.15rem + 1vw, 1.9rem); }
.map-card__head p { margin: .35rem 0 0; color: var(--ink-soft); font-size: .95rem; max-width: 46ch; }

.tally { display: flex; gap: clamp(1rem, 3vw, 2.2rem); }
.tally div { text-align: right; }
.tally dt, .tally .tally__label {
  font: 600 .68rem/1 var(--body); letter-spacing: .16em; text-transform: uppercase;
  color: var(--ink-faint); margin: 0 0 .3rem;
}
.tally dd, .tally .tally__value {
  margin: 0; font: 700 clamp(1.6rem, 1.3rem + 1.2vw, 2.3rem)/1 var(--display);
  color: var(--cherry); font-variant-numeric: tabular-nums;
}
.tally div:nth-child(2) .tally__value { color: var(--turq-ink); }

.map-stage {
  position: relative;
  background:
    linear-gradient(180deg, var(--turq-tint), #F2FAF9 65%, var(--ivory));
  /* WHO OWNS ONE FINGER DEPENDS ON WHETHER THE MAP CAN MOVE.
     At the default zoom the pan is clamped to nothing, so a finger given to
     the map would do nothing AND stop the page scrolling -- the page would
     simply be stuck. So at rest the page keeps one finger and the map takes
     two (map.js grabs the second, see touchGuard).
     Once zoomed there IS somewhere to pan, so the map takes one finger and
     behaves the way a map should: one to move, two to zoom. `is-zoomed` is
     set by map.js whenever the zoom leaves 1, and Reset hands the finger
     back to the page. */
  touch-action: pan-y;
  cursor: grab;
  overflow: hidden;
  /* A drag across the map is a pan, never a text selection. Without this the
     browser selects the SVG as you drag and the selection fights the gesture. */
  user-select: none;
  -webkit-user-select: none;
}
.map-stage.is-gesture,
.map-stage.is-zoomed { touch-action: none; }
.map-stage.is-panning { cursor: grabbing; }
.map-stage__svg { display: block; width: 100%; height: auto; }

.us-state {
  fill: #FFFDF7;
  stroke: var(--sage);
  stroke-width: .6;
  stroke-linejoin: round;
  vector-effect: non-scaling-stroke;
  transition: fill .18s ease;
}
.us-state.has-members { fill: #FBF3E4; }
.us-state.is-hot { fill: var(--gold-soft); }

/* One pin style for every member — the club's logo mark at map scale:
   cherry teardrop, gold ring, ivory heart. */
.pin { cursor: pointer; }
.pin__body  { fill: var(--cherry); stroke: #fff; stroke-width: .9; }
.pin__ring  { fill: none; stroke: var(--gold); stroke-width: 1.1; }
.pin__heart { fill: var(--ivory); }

/* The number on a marker shared by several members. Sized and centered to sit
   inside the pin's ring, where the heart would otherwise be. Tabular figures
   so 11 and 14 are the same width, and non-selectable so a drag across the map
   does not highlight it. */
.pin__count {
  fill: var(--paper);
  font: 700 11px/1 var(--body);
  font-variant-numeric: tabular-nums;
  text-anchor: middle;
  dominant-baseline: central;
  paint-order: stroke;
  user-select: none;
  pointer-events: none;
}
.pin:hover .pin__body, .pin.is-active .pin__body { fill: var(--cherry-deep); }
.pin__halo  { fill: var(--cherry); opacity: 0; transition: opacity .18s ease; }
.pin:hover .pin__halo, .pin.is-active .pin__halo { opacity: .18; }

/* The founder's gold pin was here. It came out when markers became one-per-
   town: the gold spread to every member sharing the founder's town. Founding
   100 recognition is now the gold NAME in the card (.map-tip__handle
   .is-founding) and the star in the member directory. */

.map-controls {
  position: absolute; right: .85rem; top: .85rem;
  display: flex; flex-direction: column; gap: .4rem;
}
.map-controls button {
  width: 40px; height: 40px; display: grid; place-items: center;
  border: 1px solid rgba(36,31,28,.14); border-radius: 11px;
  background: rgba(255,255,255,.94); color: var(--ink); cursor: pointer;
  box-shadow: var(--shadow-sm);
}
.map-controls button:hover { background: #fff; border-color: var(--gold); color: var(--cherry); }
.map-controls .icon { width: 18px; height: 18px; }


.map-hint {
  position: absolute; inset: 0; display: grid; place-items: center;
  background: rgba(36, 31, 28, .55); color: #fff; font-weight: 600;
  opacity: 0; pointer-events: none; transition: opacity .2s ease; padding: 1rem; text-align: center;
}
.map-hint.is-visible { opacity: 1; }

/* The card is placed by map.js (see placeTip), not by a CSS transform, so it
   can be kept inside the stage -- which clips its overflow, and used to slice
   the member's handle in half whenever her pin sat near an edge. left/top are
   the final position; nothing here may re-offset them. min-width yields on a
   narrow phone, where insisting on 168px is what pushed the card out of the
   stage in the first place. */
.map-tip {
  position: absolute; z-index: 5; top: 0; left: 0;
  /* NO min-width. The card is now only as wide as the handle and the town
     need, because on a phone it has to sit beside a pin without burying its
     neighbor -- and members in neighboring towns are exactly the ones
     somebody wants to tap between. It used to be forced to 168px and allowed
     to reach 240px, which on a 360px screen is two thirds of the map.
     max-width still caps a very long handle, and the text wraps. */
  max-width: min(190px, calc(100% - 16px));
  width: max-content;
  background: var(--ink); color: var(--ivory);
  border-radius: 12px; padding: .5rem .65rem;
  box-shadow: var(--shadow-md); pointer-events: none;
  opacity: 0; transition: opacity .14s ease;
  font-size: .78rem; line-height: 1.35;
}
.map-tip.is-visible { opacity: 1; }
/* Laid out for measurement, invisible and unclickable until placed. */
.map-tip.is-measuring { opacity: 0; }
.map-tip::after {
  content: ""; position: absolute; left: var(--tip-arrow, 50%); bottom: -6px;
  width: 12px; height: 12px;
  background: var(--ink); transform: translateX(-50%) rotate(45deg); border-radius: 2px;
}
/* Flipped under its pin when there was no room above. */
.map-tip--below::after { bottom: auto; top: -6px; }
.map-tip__handle {
  display: block; font: 700 .92rem/1.25 var(--display); margin-bottom: .1rem;
  /* A handle is free text she typed. A long one with no spaces would
     otherwise widen the card until it left the map. */
  overflow-wrap: anywhere;
}
/* Town names run long -- "Altamonte Springs, FL" -- so the line wraps rather
   than widening the card past the cap above. */
.map-tip__meta { color: #C8BFB7; display: block; overflow-wrap: anywhere; }

/* A Founding 100 Member's name, in the same gold as the directory star.
   ~7:1 against the card's dark ground, so it stays legible rather than
   decorative. The distinction sits on the NAME because a marker now stands for
   a whole town -- coloring the marker would decorate everyone in it. */
.map-tip__handle .is-founding { color: var(--gold); }

/* The Founding 100 badge that used to sit inside the map card is gone: it was
   the widest line in a card that has to stay narrow enough to tap around on a
   phone. The honor still appears in the member directory (.dir-founding),
   where there is room for it. */

/* Founding 100 invitation. Deliberately quiet — gold hairline on ivory, not a
   banner — because it sits under a lede that is already doing the selling. */
.founding-call {
  display: flex; align-items: flex-start; gap: .55rem; text-align: left;
  max-width: 48ch; margin: 1.5rem auto 0; padding: .8rem 1rem;
  background: var(--ivory); border: 1px solid var(--gold-soft);
  border-radius: var(--radius); font-size: .9rem; line-height: 1.55;
  color: var(--ink-soft);
}
/* The screen that replaces the join form once an application is in. It has to
   read as a different page, not a note appended to the one she just filled
   in -- the old version left the greyed-out form in place and on a phone the
   confirmation sat below the fold entirely. */
.join-done { padding-block: clamp(2rem, 5vw, 3.5rem); }
.join-done__tick {
  width: 74px; height: 74px; color: var(--turq-ink); margin: 0 auto 1.2rem; display: block;
}
.join-done h2 { margin-bottom: .4rem; }
.join-done h2:focus-visible { outline: none; }
.join-done__steps {
  list-style: none; counter-reset: step; margin: 2rem auto 0; padding: 0;
  max-width: 46ch; text-align: left; display: grid; gap: .9rem;
}
.join-done__steps li {
  counter-increment: step; position: relative; padding-left: 2.6rem;
  color: var(--ink-soft); line-height: 1.55;
}
.join-done__steps li::before {
  content: counter(step); position: absolute; left: 0; top: -.1rem;
  width: 1.8rem; height: 1.8rem; border-radius: 999px;
  background: var(--gold-soft); color: var(--gold-ink);
  font: 700 .9rem/1.8rem var(--body); text-align: center;
}

.founding-call[hidden] { display: none; }
.founding-call .icon { width: 18px; height: 18px; fill: var(--gold); flex: none; margin-top: .15rem; }
.founding-call strong { color: var(--gold-ink); }
.founding-call--closed strong { color: var(--ink); }

.map-card__foot {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 1rem; padding: 1.1rem clamp(1.1rem, 3vw, 2rem);
  border-top: 1px solid var(--ivory-deep); background: var(--ivory);
}


.map-note { font-size: .8rem; color: var(--ink-faint); margin: 0; }

/* roster — the text twin of the map: real content for people who do not
   want (or cannot use) the interactive version, and for search engines. */
.roster { margin-top: 2.5rem; }
.roster summary {
  cursor: pointer; font: 600 1rem/1 var(--body); color: var(--turq-ink);
  padding: .9rem 1.1rem; background: var(--paper);
  border: 1px solid rgba(201,162,39,.4); border-radius: var(--radius);
  list-style: none; display: flex; align-items: center; gap: .55rem;
}
.roster summary::-webkit-details-marker { display: none; }
.roster summary::before { content: "▸"; transition: transform .2s ease; display: inline-block; }
.roster[open] summary::before { transform: rotate(90deg); }
.roster ul {
  list-style: none; margin: 1rem 0 0; padding: 0; max-width: none;
  /* The column gap is load-bearing, not decoration. Every row right-aligns its
     count, so with only a hairline between columns that number lands flush
     against the NEXT state's name and reads as belonging to it — "1 Nevada".
     The row gap stays tight so the rows still read as one list. */
  display: grid; gap: .1rem 2.75rem;
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 320px), 1fr));
}
.roster li {
  display: grid; grid-template-columns: 1fr auto; align-items: baseline;
  gap: 0 .6rem; padding: .6rem .2rem; border-bottom: 1px solid rgba(201,162,39,.25);
}
.roster-count { color: var(--cherry); font-weight: 700; font-variant-numeric: tabular-nums; }
.roster-cities { grid-column: 1 / -1; font-size: .82rem; color: var(--ink-faint); }

/* -------------------------------------------------------------- pieces -- */

.grid { display: grid; gap: clamp(1.1rem, 2.5vw, 1.8rem); }
/* 300px is chosen so at most three columns fit the shell — six cards land as
   3 + 3 rather than a lopsided 4 + 2. */
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 300px), 1fr)); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 320px), 1fr)); }

.card {
  background: var(--paper);
  border: 1px solid rgba(201, 162, 39, .38);
  border-radius: var(--radius);
  padding: clamp(1.3rem, 3vw, 1.9rem);
  box-shadow: var(--shadow-sm);
}
.card h3 { margin-bottom: .45em; }
.card p:last-child { margin-bottom: 0; }
.card__num {
  display: grid; place-items: center; width: 2.6rem; height: 2.6rem; margin-bottom: 1rem;
  border-radius: 999px; background: var(--cherry-tint); color: var(--cherry);
  font: 700 1.15rem/1 var(--display);
}
.card__icon {
  display: grid; place-items: center; width: 2.9rem; height: 2.9rem; margin-bottom: 1.05rem;
  border-radius: 999px; background: var(--turq-tint);
}
.card__icon .icon { width: 1.5rem; height: 1.5rem; fill: var(--turq-ink); }

.pull {
  border-left: 3px solid var(--gold);
  padding: .3rem 0 .3rem 1.5rem;
  font-family: var(--display);
  font-size: clamp(1.2rem, 1.05rem + .8vw, 1.7rem);
  font-style: italic;
  line-height: 1.4;
  color: var(--ink);
  margin: 2rem 0;
  max-width: 34ch;
}

/* A pull-quote under centered copy. The left bar is a margin note; centered,
   it hangs off one side of a symmetrical block and reads as a stray rule. A
   short gold rule above keeps the gold without the asymmetry. */
.pull--center {
  border-left: 0;
  padding: 1.4rem 0 .3rem;
  margin-inline: auto;
  text-align: center;
}
.pull--center::before {
  content: ""; display: block; width: 2.75rem; height: 2px; margin: 0 auto 1.1rem;
  background: linear-gradient(90deg, var(--gold), var(--gold-soft));
}

.checklist { list-style: none; margin: 0; padding: 0; display: grid; gap: .8rem; }
.checklist li { display: grid; grid-template-columns: auto 1fr; gap: .75rem; align-items: start; }
.checklist .icon { width: 1.35rem; height: 1.35rem; fill: var(--sage-deep); margin-top: .16rem; }
.checklist strong { display: block; }
.checklist span { color: var(--ink-soft); font-size: .95rem; }

.badge {
  display: inline-flex; align-items: center; gap: .45rem;
  padding: .38rem .85rem; border-radius: 999px;
  background: var(--gold-soft); color: #6B5410;
  font: 600 .74rem/1 var(--body); letter-spacing: .1em; text-transform: uppercase;
}
.badge--teal { background: var(--turq-tint); color: var(--turq-ink); }
.badge--cherry { background: var(--cherry-tint); color: var(--cherry-deep); }

.portrait {
  border-radius: var(--radius-lg);
  border: 1px solid rgba(201,162,39,.45);
  box-shadow: var(--shadow-md);
  background: var(--ivory-deep);
  width: 100%;
}

.split-2 {
  display: grid; gap: clamp(1.8rem, 5vw, 3.5rem);
  grid-template-columns: minmax(0, 1fr);
  align-items: center;
}
@media (min-width: 900px) {
  .split-2 { grid-template-columns: minmax(0, .85fr) minmax(0, 1.15fr); }
  .split-2--flip { grid-template-columns: minmax(0, 1.15fr) minmax(0, .85fr); }
}

/* --------------------------------------------------------------- forms -- */

.form { display: grid; gap: 1.15rem; }
.field { display: grid; gap: .4rem; }
.field > label, .fieldset__legend {
  font: 600 .87rem/1.3 var(--body); color: var(--ink);
}
.field .hint { font-size: .82rem; color: var(--ink-faint); }
.req { color: var(--cherry); }
.opt { color: var(--ink-faint); font-weight: 400; }

input[type="text"], input[type="email"], input[type="number"], input[type="file"], select, textarea {
  font: 400 1rem/1.4 var(--body);
  color: var(--ink);
  background: var(--paper);
  border: 1.5px solid rgba(36, 31, 28, .18);
  border-radius: 11px;
  padding: .8rem .9rem;
  width: 100%;
}
textarea { min-height: 8.5rem; resize: vertical; }
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: none; border-color: var(--turq-ink); box-shadow: var(--ring);
}
input::placeholder, textarea::placeholder { color: var(--ink-faint); }
input[aria-invalid="true"], select[aria-invalid="true"] { border-color: var(--cherry); }

/* Fields size to their own content. Without this, a tall field (the two-part
   height picker) stretches its neighbors, leaving their labels stranded at
   the top and their controls floating in the middle. */
.field-row {
  display: grid; gap: 1.15rem; align-items: start;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 190px), 1fr));
}
.field { align-content: start; }

/* Feet and inches always sit side by side — they are too narrow to be worth
   wrapping, and wrapping them is what unbalanced the row. */
.field-row--tight {
  gap: .6rem;
  grid-template-columns: repeat(2, minmax(0, 1fr));
}

fieldset { border: 0; margin: 0; padding: 0; }
.fieldset__legend { display: block; margin-bottom: .55rem; }

/* icon picker */
.picker { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fit, minmax(96px, 1fr)); }
.picker input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.picker label {
  display: grid; place-items: center; gap: .45rem; padding: .85rem .5rem;
  background: var(--paper); border: 1.5px solid rgba(36,31,28,.14);
  border-radius: var(--radius); cursor: pointer; text-align: center;
  font: 500 .78rem/1.2 var(--body); color: var(--ink-soft);
  transition: border-color .16s ease, background-color .16s ease, transform .16s ease;
}
.picker .icon { width: 2rem; height: 2rem; }
.picker label:hover { transform: translateY(-2px); border-color: var(--gold); }
.picker input:focus-visible + label { box-shadow: var(--ring); }
.picker input:checked + label {
  border-color: var(--cherry); background: var(--cherry-tint); color: var(--ink); font-weight: 600;
}

.gate {
  background: var(--paper); border: 1px solid rgba(201,162,39,.45);
  border-radius: var(--radius-lg); padding: clamp(1.4rem, 4vw, 2.4rem);
  box-shadow: var(--shadow-md);
}
.gate__q { font-family: var(--display); font-size: clamp(1.3rem, 1.1rem + 1vw, 1.85rem); margin-bottom: 1.4rem; }
.gate__opts { display: flex; flex-wrap: wrap; gap: .8rem; }

.notice {
  display: grid; grid-template-columns: auto 1fr; gap: .8rem; align-items: start;
  padding: 1rem 1.15rem; border-radius: var(--radius);
  background: var(--turq-tint); border: 1px solid rgba(18,140,140,.28);
  font-size: .9rem; color: #0B5C5C;
}
.notice .icon { width: 1.25rem; height: 1.25rem; fill: currentColor; margin-top: .12rem; }
.notice p { margin: 0; max-width: none; }
.notice strong { display: block; margin-bottom: .15rem; }
.notice--gold { background: #FBF3DE; border-color: rgba(201,162,39,.5); color: #6B5410; }
.notice--cherry { background: var(--cherry-tint); border-color: rgba(200,16,46,.3); color: var(--cherry-deep); }

.error-text { color: var(--cherry); font-size: .82rem; margin: 0; }

/* preview card shown beside the join form */
.preview {
  position: sticky; top: 5.5rem;
  background: var(--paper); border: 1px solid rgba(201,162,39,.45);
  border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-sm);
}
.preview__head { padding: 1rem 1.2rem .8rem; border-bottom: 1px solid var(--ivory-deep); }
.preview__head h3 { margin: 0; font-size: 1.1rem; }
.preview__head p { margin: .2rem 0 0; font-size: .82rem; color: var(--ink-faint); }
.preview__map { background: linear-gradient(180deg, var(--turq-tint), var(--ivory)); }
.preview__map svg { display: block; width: 100%; height: auto; }
.preview__body { padding: 1rem 1.2rem 1.2rem; display: grid; gap: .55rem; }
.preview__row { display: grid; grid-template-columns: auto 1fr; gap: .6rem; align-items: center; font-size: .9rem; }
.preview__row .icon { width: 1.7rem; height: 1.7rem; }
.preview__handle { font: 700 1.05rem/1.2 var(--display); }
.preview__meta { color: var(--ink-soft); font-size: .86rem; }

/* --------------------------------------------------------------- misc --- */

.steps { counter-reset: step; }
.timeline { list-style: none; margin: 0; padding: 0; display: grid; gap: 1.1rem; max-width: none; }
.timeline li {
  display: grid; grid-template-columns: auto 1fr; gap: 1rem; align-items: start;
  padding: 1.1rem 1.2rem; background: var(--paper);
  border: 1px solid rgba(201,162,39,.35); border-radius: var(--radius);
}
.timeline .dot {
  width: .85rem; height: .85rem; border-radius: 999px; margin-top: .42rem;
  background: var(--gold-soft); border: 2px solid var(--gold);
}
.timeline li.is-live .dot { background: var(--turq-bright); border-color: var(--turq-ink); }
.timeline li.is-next .dot { background: var(--cherry); border-color: var(--cherry-deep); }
.timeline strong { display: block; margin-bottom: .15rem; }
.timeline span { color: var(--ink-soft); font-size: .93rem; }

/* ------------------------------------------------------------- merch --- */

.products {
  display: grid; gap: clamp(1.1rem, 2.5vw, 1.8rem); list-style: none; margin: 0; padding: 0;
  max-width: none;
  /* auto-FILL, not auto-fit. auto-fit collapses the empty tracks, so with a
     single product in the store that one card stretched across the entire
     page -- a 600px photo blown up to full width, which is what "why is the
     image so big?" was about. auto-fill keeps the tracks, so one product is
     one card and the row fills in as more are added. */
  grid-template-columns: repeat(auto-fill, minmax(min(100%, 280px), 1fr));
}
.product {
  display: flex; flex-direction: column;
  background: var(--paper);
  border: 1px solid rgba(201, 162, 39, .38);
  border-radius: var(--radius);
  overflow: hidden;
  box-shadow: var(--shadow-sm);
  transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease;
}
.product:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--gold); }
.product__shot { display: block; width: 100%; aspect-ratio: 1; object-fit: cover; background: var(--ivory-deep); }
/* Shown when the club has no products listed -- while a new drop-ship
   partner is being chosen, that is the normal state of this page, not an
   error, so it reads as a note rather than a warning. */
.merch-empty {
  max-width: 46ch; margin: 0 auto; text-align: center;
  color: var(--ink-soft); font-size: 1rem; line-height: 1.6;
}
.product__body { padding: 1.1rem 1.2rem 1.3rem; display: flex; flex-direction: column; gap: .35rem; flex: 1; }
.product h3 { margin: 0; font-size: 1.15rem; }
.product p { margin: 0; font-size: .92rem; color: var(--ink-soft); max-width: none; }
/* The whole card is the link target; the stretched anchor keeps the markup
   flat and the tap area honest on touch. */
.product__link {
  margin-top: auto; padding-top: .8rem;
  display: inline-flex; align-items: center; gap: .4rem;
  font-weight: 600; font-size: .92rem; text-decoration: none; color: var(--turq-ink);
}
.product__link::after { content: ""; position: absolute; inset: 0; }
.product { position: relative; }
.product:hover .product__link { color: var(--cherry); }
.product__link .icon { width: 1em; height: 1em; transition: transform .18s ease; }
.product:hover .product__link .icon { transform: translateX(3px); }


/* -------------------------------------------------------------- footer -- */

.site-footer {
  background: var(--ink); color: #D9D1CA;
  padding-block: clamp(3rem, 6vw, 4.5rem) 2rem;
  margin-top: var(--band);
}
.site-footer a { color: #EFE7DF; text-decoration: none; }
.site-footer a:hover { color: #fff; text-decoration: underline; }
.footer-grid {
  display: grid; gap: 2.2rem;
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
}
.site-footer h2, .site-footer h3 {
  font: 600 .74rem/1 var(--body); letter-spacing: .17em; text-transform: uppercase;
  color: #9C9088; margin: 0 0 1rem;
}
.site-footer ul { list-style: none; margin: 0; padding: 0; display: grid; gap: .6rem; font-size: .95rem; }
.site-footer .brand { color: #F4EDE0; }
/* The footer wears the badge at display size too. */
.site-footer .brand__logo { width: 120px; height: 120px; }
.site-footer .brand { gap: 1.1rem; }
.site-footer .brand__sub { color: #9C9088; }
.site-footer p { font-size: .93rem; color: #B3A9A1; }

.social { display: flex; gap: .6rem; }
.social a {
  display: grid; place-items: center; width: 42px; height: 42px; border-radius: 999px;
  border: 1px solid rgba(255,255,255,.18); color: #EFE7DF;
}
.social a:hover { background: var(--cherry); border-color: var(--cherry); color: #fff; }
.social .icon { width: 1.15rem; height: 1.15rem; }

.footer-bottom {
  margin-top: 2.6rem; padding-top: 1.4rem; border-top: 1px solid rgba(255,255,255,.12);
  display: flex; flex-wrap: wrap; gap: .6rem 1.5rem; justify-content: space-between;
  font-size: .85rem; color: #9C9088;
}
.footer-bottom p { margin: 0; font-size: .85rem; }

/* --------------------------------------------------------------- print -- */
@media print {
  .site-header, .map-controls, .btn-row, .site-footer { display: none; }
  body::before { display: none; }
}
