/* Mystic Model Yacht Club. Design system, Direction A "Burgee".
   Hand written CSS, no framework, no runtime CDN. Fonts are vendored in assets/fonts.
   One theme: dark everywhere, with a white header band.

   Contrast notes, checked against WCAG AA (4.5:1 body text, 3:1 large text and UI edges):
   the bright signal red (#e8332a) only reaches 4.25:1 on white, so it is kept for large
   display type and decorative bars, and a slightly deeper red carries anything that is small
   text or a filled button. Both reds read as the same signal red on screen. */

@import url("./fonts/fonts.css");

/* ---------- tokens ----------
   The site is dark, always. Brandon settled that on 2026-09-22 along with a white header
   band, which is the one light surface on the page and exists so the burgee reads properly
   instead of sitting on navy. There is no light theme and no toggle any more, so these
   tokens are the only set. Header colours are separate tokens below for that reason. */
:root{
  --navy:#0b3a6e;
  --navy-deep:#072a51;
  --bg:#06162b;
  --ink:#eef3f9;
  --muted:#9db0c8;         /* 6.4:1 on --bg */
  --card:#0b2444;
  --line:#1c3a62;

  --red-bright:#e8332a;    /* display type and decorative bars only */
  --red:#cf2e24;           /* filled buttons, 5.2:1 against white text */
  --on-red:#ffffff;
  --red-text:#ff8078;      /* 6.3:1 on --card, the deep red is too dark on a navy field */

  --on-navy:#ffffff;
  --on-navy-soft:#d6e2f2;  /* 8.9:1 on --navy-deep */
  --focus:#ff8078;

  /* the white header band */
  --head-bg:#ffffff;
  --head-ink:#0f1c2e;      /* 16.6:1 on white */
  --head-muted:#41506480;
  --head-link:#21344c;     /* 11.4:1 on white */

  --radius:6px;
  --display:"Archivo Narrow",Archivo,"Arial Narrow",system-ui,sans-serif;
  --sans:Archivo,system-ui,-apple-system,"Segoe UI",sans-serif;
}

/* ---------- base ---------- */
*{box-sizing:border-box;margin:0}
html{scroll-behavior:smooth}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto} *{animation:none !important;transition:none !important}}
body{
  font-family:var(--sans);
  background:var(--bg);
  color:var(--ink);
  line-height:1.5;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
/* Any rule that sets a display beats the hidden attribute's own display:none, which is how
   the signup form's guardian block (display:grid) stayed on screen for everyone. Nothing in
   this stylesheet should ever outrank hidden. */
[hidden]{display:none !important}
a{color:inherit}
:focus-visible{outline:3px solid var(--focus);outline-offset:2px;border-radius:3px}
.skip{position:absolute;left:-9999px;top:0;background:var(--card);color:var(--ink);padding:12px 18px;z-index:60;border-radius:0 0 6px 0}
.skip:focus{left:0}
.wrap{max-width:1120px;margin:0 auto;padding:0 20px}
.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}

/* ---------- display type ---------- */
h1,h2,h3,.facts b,.when{font-family:var(--display);text-transform:uppercase}
h1{font-weight:700;font-size:clamp(40px,9vw,112px);line-height:.92;letter-spacing:-.01em;max-width:14ch}
h1 span{color:var(--red-bright)}
h2{font-weight:700;font-size:clamp(30px,5vw,56px);line-height:.95;margin-bottom:8px}
h3{font-family:var(--sans);text-transform:none;font-weight:700;font-size:20px;line-height:1.25}
.sub{color:var(--muted);margin-bottom:28px;max-width:62ch}
.lede{color:var(--muted);font-size:18px;margin-top:18px;max-width:56ch}
.kicker{display:inline-flex;align-items:center;gap:10px;font-size:12px;font-weight:700;letter-spacing:.18em;text-transform:uppercase;margin-bottom:18px}
.kicker:before{content:"";width:28px;height:3px;background:var(--red-bright);flex:none}

/* ---------- header ----------
   A white band. The burgee is a navy and red mark on white, so this is the surface it was
   drawn for, and it stops the club's own logo having to wear a keyline to survive. */
header.site{background:var(--head-bg);color:var(--head-ink);border-bottom:3px solid var(--red)}
header.site nav{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:76px;flex-wrap:wrap}
header.site .brand{display:flex;align-items:center;gap:14px;font-weight:900;letter-spacing:.02em;text-transform:uppercase;font-size:15px;text-decoration:none;color:var(--head-ink)}
header.site .brand img{height:42px;width:auto}
/* order so the row reads brand, then nav links, then the Join button on the right */
header.site ul{display:flex;gap:28px;list-style:none;font-size:14px;font-weight:600;margin:0;padding:0;align-items:center;order:1;margin-left:auto}
header.site ul a{text-decoration:none;color:var(--head-link)}
header.site ul a:hover{color:var(--head-ink);text-decoration:underline}
header.site ul a[aria-current="page"]{color:var(--head-ink);border-bottom:3px solid var(--red);padding-bottom:3px}
header.site .join{background:var(--red);color:var(--on-red);padding:10px 18px;border-radius:4px;font-weight:700;text-decoration:none;font-size:14px}
header.site .join:hover{filter:brightness(1.1)}
.navtools{display:flex;align-items:center;gap:10px;order:2;margin-left:28px}
.menubtn{display:none;background:transparent;border:1px solid #c3cedd;color:var(--head-link);border-radius:4px;padding:9px 13px;font:inherit;font-size:13px;font-weight:700;cursor:pointer}
.menubtn:hover{border-color:var(--head-ink);color:var(--head-ink)}
header.site .brand .short{display:none}
/* The horizontal nav only appears where it actually FITS. Re-measured 2026-09-23 with the
   eight items now in build.mjs (Start here, News, Boats, Gallery, Donate, Shop, Contact,
   Members) at 14px/600 Archivo. The live nine item list measured 643; dropping the duplicate
   Join (label 28 + one 28 gap) leaves 587, which agrees with the font metrics (labels 376
   from the hmtx table plus 196 of gaps, the browser's faux bold adding a few px). So the row
   is brand 319 + two nav gaps 32 + links 587 + tools margin 28 + tools 65 = 1031px of
   content, plus the 40px of .wrap side padding = 1071. The old 1060 breakpoint sat below
   that, so a 1080 to 1280 desktop still wrapped onto two rows. 1140 gives 40px of slack
   past 1071 even after a 15px scrollbar comes out of the viewport, and above 1120 the .wrap
   caps at 1080 of content, which is 49px more than the row needs. Below this it is the Menu
   button, which is one row at any width. If you add a nav item, re-measure and move this
   number. */
@media(max-width:1140px){
  header.site nav{padding:12px 0;min-height:0}
  .menubtn{display:block}
  header.site .brand img{height:36px}
  header.site .brand{font-size:13px}
  header.site ul{display:none;order:3;width:100%;flex-direction:column;align-items:flex-start;gap:0;padding-bottom:8px;margin-left:0}
  .navtools{margin-left:auto}
  header.site ul.open{display:flex}
  header.site ul li{width:100%;border-top:1px solid #e1e7ef}
  header.site ul a{display:block;padding:13px 0;font-size:16px}
  header.site ul a[aria-current="page"]{border-bottom:0;text-decoration:underline;text-decoration-color:var(--red);text-decoration-thickness:3px;text-underline-offset:4px}
}
/* Below this the full club name plus Menu plus Join wrapped onto two rows, so the brand
   switches to the short name. It sits after the 860px block deliberately: both match on a
   phone at equal specificity, so source order is what decides. */
@media(max-width:620px){
  header.site .brand .full{display:none}
  header.site .brand .short{display:inline}
  header.site .brand{font-size:12.5px;gap:10px}
  header.site .brand img{height:30px}
  /* Measured at 375px: brand 186 + gap 16 + a 12px left margin + tools 123 came to 337 in a
     335 row, so it wrapped by two pixels. The gap comes down and the fixed margin goes; auto
     takes up the slack without adding width of its own. */
  header.site nav{gap:10px}
  .navtools{gap:8px;margin-left:auto}
  .menubtn{padding:8px 11px}
  header.site .join{padding:9px 14px}
}

/* ---------- hero ---------- */
.hero{position:relative;background:var(--navy-deep);color:var(--on-navy);overflow:hidden;min-height:82vh;display:grid;align-items:end}
/* The photo is shown in full colour. Direction A originally called for a navy duotone, which
   was the right call for generic stock: it forced every photo into the same world. It is the
   wrong call for the club's own photograph of its boats at Mystic Seaport in October, where
   the autumn colour and the coloured sails ARE the picture. Legibility is handled instead by
   a gradient scrim that is nearly transparent at the top and solid navy where the type sits,
   so the white headline still clears AA against what is behind it. */
.hero img.photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:50% 56%;filter:saturate(1.02) contrast(1.02)}
.hero:after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,
  rgba(7,42,81,.10) 0%,
  rgba(7,42,81,.26) 38%,
  rgba(7,42,81,.60) 66%,
  rgba(7,42,81,.86) 86%,
  #072a51 100%)}
/* A soft shadow under the hero type. With the duotone gone, the kicker in particular can land
   on a sunlit boathouse, and this keeps it readable without darkening the whole photograph. */
.hero .wrap{position:relative;z-index:1;padding-top:96px;padding-bottom:60px;text-shadow:0 1px 16px rgba(4,20,40,.6)}
.hero p{max-width:52ch;font-size:18px;margin-top:20px;color:var(--on-navy-soft)}
.hero.short{min-height:0}
.hero.short .wrap{padding-top:64px;padding-bottom:48px}
.hero.short h1{font-size:clamp(34px,6.5vw,72px)}
@media(max-width:760px){
  /* Tall enough to let the portrait crop breathe, so the fleet and the sheds sit high and the
     copy lands on open water rather than across the buildings. */
  .hero{min-height:78vh}
  .hero.short{min-height:0}
  /* The portrait source is relatively wider than a phone hero box, so cover trims the sides
     and keeps the full height: leaves at the top, water at the bottom. Centre it. */
  .hero img.photo{object-position:50% 50%}
  .hero .wrap{padding-top:56px;padding-bottom:44px}
}
/* On a phone the kicker is long enough to wrap, and as an inline-flex row with a dash in
   front it wrapped badly: the dash held the first line, the second line started under the
   text, and the whole thing read as mis-centred. So on narrow screens it moves below the
   headline and the paragraph, sits on the water rather than across the trees, and the dash
   becomes a rule above it instead of an item beside it. */
@media(max-width:620px){
  .hero .wrap{display:flex;flex-direction:column;align-items:flex-start}
  .hero h1{order:1}
  /* :not(.kicker) matters. Without it the kicker is also a direct p child, matches at the
     same specificity, and stays put in source order, which is the bug this rule fixes. */
  .hero .wrap>p:not(.kicker){order:2}
  /* Tightened so the whole line fits on a 375px screen. It was wrapping to "FORMING / NOW",
     which with a dash on the first line read as badly centred rather than as a wrap. */
  .hero .wrap>p.kicker{order:3;display:block;margin:24px 0 0;font-size:11px;letter-spacing:.1em;white-space:nowrap}
  .hero .wrap>p.kicker:before{display:block;margin-bottom:10px}
  .hero .cta{order:4}
}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:14px 22px;border-radius:4px;font-family:var(--sans);font-weight:700;text-decoration:none;font-size:15px;line-height:1;border:2px solid transparent;cursor:pointer;background:var(--navy);color:var(--on-navy)}
.btn:hover{filter:brightness(1.12)}
.btn.red{background:var(--red);color:var(--on-red)}
.btn.ghost{background:transparent;border-color:rgba(255,255,255,.6);color:#fff}
.btn.ghost:hover{border-color:#fff;filter:none}
.btn.line{background:transparent;border-color:var(--line);color:var(--ink)}
.btn.line:hover{border-color:var(--ink);filter:none}
.btn[disabled],.btn[aria-disabled="true"]{opacity:.55;cursor:not-allowed;filter:none}
.cta,.btnrow{display:flex;gap:12px;flex-wrap:wrap;margin-top:30px}
/* A card already carries 28px of its own padding, so 30px on top of that floats the buttons
   away from what they belong to. Match .sub-gap instead. */
.card + .btnrow,.boats + .btnrow,.partner + .btnrow{margin-top:22px}

/* ---------- red ticker strip ---------- */
.strip{background:var(--red);color:var(--on-red);font-weight:700;font-size:13px;letter-spacing:.08em;text-transform:uppercase}
.strip .wrap{display:flex;gap:40px;padding:12px 20px;overflow-x:auto;white-space:nowrap}
.strip a{color:var(--on-red)}
/* On a phone the single scrolling line just sliced the second fact in half at the screen
   edge with no scrollbar or arrow to say there was more, so it read as broken rather than
   scrollable. Below this it wraps onto as many lines as it needs instead. */
@media(max-width:700px){
  .strip .wrap{flex-wrap:wrap;white-space:normal;overflow-x:visible;gap:4px 20px;
    font-size:11.5px;letter-spacing:.06em;padding:11px 20px;line-height:1.6}
}

/* ---------- facts band ---------- */
.facts{display:grid;grid-template-columns:repeat(3,1fr);gap:2px;background:var(--line);margin:64px 0}
.facts>div{background:var(--card);padding:32px 28px}
.facts b{display:block;font-size:clamp(28px,3.4vw,40px);line-height:1;color:#fff;font-weight:700}
.facts small{display:block;margin-top:10px;color:var(--muted);font-size:14px;line-height:1.45}
@media(max-width:760px){.facts{grid-template-columns:1fr;margin:44px 0}}

/* ---------- news cards ----------
   Every card the same size, whatever the post is. An Instagram feed mixes a wide graphic with
   a tall photograph with a one word caption, and left to itself that produces cards of wildly
   different heights with pools of empty navy under the short ones. So: one image ratio, a
   headline clamped to two lines, a caption clamped to three, and the link pinned to the
   bottom of the card rather than floating under whatever text happened to arrive. */
.news{display:grid;grid-template-columns:repeat(auto-fill,minmax(272px,1fr));gap:20px;align-items:stretch}
.news.featured{grid-template-columns:repeat(3,1fr)}
@media(max-width:940px){.news,.news.featured{grid-template-columns:repeat(2,1fr)}}
@media(max-width:620px){.news,.news.featured{grid-template-columns:1fr}}
.post{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);overflow:hidden;display:flex;flex-direction:column}
.post>img,.post .thumb{width:100%;aspect-ratio:4/3;object-fit:cover;background:var(--line)}
.post .body{padding:18px 20px 20px}
.post time{font-size:12px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--red-text)}
.post h3{margin:8px 0 0;font-size:18px;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}
.post p{color:var(--muted);font-size:14.5px;margin-top:8px;
  display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
.post .fb{margin-top:auto;padding:14px 20px;border-top:1px solid var(--line);font-size:13px;font-weight:700;text-decoration:none;display:flex;justify-content:space-between;gap:10px;color:var(--ink)}
.post .fb:hover{background:var(--bg)}

/* ---------- source of truth callout ---------- */
.truth{margin:64px 0;padding:22px 26px;border-left:6px solid var(--red);background:var(--card);border-radius:0 var(--radius) var(--radius) 0;font-size:15px;color:var(--ink)}
.truth b{text-transform:uppercase;letter-spacing:.08em;font-size:12px;display:block;margin-bottom:4px;color:var(--red-text)}
.truth a{color:var(--ink);font-weight:700}

/* ---------- events ---------- */
.events{list-style:none;padding:0;margin:28px 0 0}
.events li{display:grid;grid-template-columns:130px 1fr;gap:24px;padding:22px 0;border-bottom:1px solid var(--line);align-items:start}
.events .when{font-weight:700;color:var(--red-text);font-size:22px;line-height:1.05}
.events .when small{display:block;color:var(--muted);font-family:var(--sans);text-transform:uppercase;font-size:12px;font-weight:500;letter-spacing:.1em;margin-top:6px}
.events p{color:var(--muted);font-size:15px;margin-top:4px}
@media(max-width:620px){.events li{grid-template-columns:1fr;gap:6px}}
/* compact version used in the home page sidebar */
.events.compact li{grid-template-columns:86px 1fr;gap:16px;padding:14px 0}
.events.compact .when{font-size:17px}
.events.compact h3{font-size:16px}

/* ---------- gallery ---------- */
.grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:18px;margin-top:28px}
.grid figure{margin:0}
.grid img{width:100%;aspect-ratio:4/3;object-fit:cover;border-radius:var(--radius);background:var(--line)}
.grid figcaption{font-size:13px;color:var(--muted);margin-top:8px}

/* ---------- cards and boats ---------- */
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:28px}
@media(max-width:620px){.card{padding:22px 18px}}
.boats{display:grid;grid-template-columns:repeat(auto-fit,minmax(290px,1fr));gap:20px;margin-top:28px}
.boats .card h3{font-family:var(--display);text-transform:uppercase;font-size:26px;line-height:1}
.boats .card>p{color:var(--muted);margin-top:10px;font-size:15px}
.boats dl{margin-top:16px;font-size:14px}
.boats dt{color:var(--muted);font-size:11px;letter-spacing:.12em;text-transform:uppercase;margin-top:14px;font-weight:700}
.boats dd{margin:2px 0 0}

/* ---------- prose ---------- */
.prose p{margin-top:16px;max-width:68ch;color:var(--ink)}
/* padding-left rather than margin-left, so the browser's own 40px list indent is replaced
   instead of added to. On a phone the two together pushed list text most of the way across
   the card and made it read as centred. */
.prose ul,.prose ol{margin:16px 0 0;padding-left:24px;max-width:68ch}
.prose li{margin-top:10px}
.prose h2{margin-top:48px}
.prose h3{margin-top:28px}
.section{padding:64px 0}
.section.tight{padding:44px 0}
/* Two tight sections in a row would otherwise put 88px between them, more air than sits
   between a heading and its own card. Halve the second one's top padding so the rhythm
   reads as one page rather than a stack of separate panels. */
.section.tight + .section.tight{padding-top:22px}

/* ---------- subscribe panel ---------- */
/* auto-fit so the panel is one wide column when only one block is shipped, two when the
   WhatsApp block is switched on in club.json */
.subscribe{background:var(--navy);color:var(--on-navy);border-radius:8px;padding:48px 40px;display:grid;grid-template-columns:repeat(auto-fit,minmax(300px,1fr));gap:40px;margin:64px 0}
.subscribe .btnrow{margin-top:20px}
.subscribe .fineprint{font-size:13px;color:#a9c0dc;margin-top:12px}
.subscribe h2{color:#fff}
.subscribe h2.small{font-size:28px}
.subscribe p{color:var(--on-navy-soft);margin-top:10px;font-size:15px}
.subscribe .qr{width:120px;height:120px;background:#fff;border-radius:6px;padding:8px;flex:none}
.subscribe .qr img{width:100%;height:100%;object-fit:contain}
.subscribe .row{display:flex;gap:20px;align-items:center;margin-top:18px;flex-wrap:wrap}
@media(max-width:760px){.subscribe{grid-template-columns:1fr;padding:32px 24px;margin:44px 0}}

/* ---------- forms ----------
   Only the membership signup and the members sign in use these. Fields sit on the card colour
   so they read as part of the page rather than as a browser default dropped onto it. */
form.stack{display:grid;gap:18px;margin-top:8px;max-width:640px}
label{font-size:14px;font-weight:700;display:block;margin-bottom:6px}
label .hint{display:block;font-weight:400;color:var(--muted);font-size:13px;margin-top:4px;line-height:1.45}
p.hint{color:var(--muted);font-size:13.5px;line-height:1.5;margin-top:8px;max-width:62ch}
/* Fields sit on --bg, which is DARKER than the --card they sit inside. They used to share the
   card colour, so a text box read as a thin outline and not as somewhere to type. A field
   should look like a well cut into the card. */
input[type=text],input[type=email],input[type=tel],input[type=number],textarea,select{
  width:100%;padding:12px 14px;border-radius:4px;border:1px solid var(--line);
  font:inherit;line-height:1.4;background:var(--bg);color:var(--ink);
  transition:border-color .12s ease,box-shadow .12s ease}
input[type=text]:hover,input[type=email]:hover,textarea:hover,select:hover{border-color:#2b5187}
input:focus-visible,textarea:focus-visible,select:focus-visible{border-color:var(--focus)}
textarea{min-height:96px;resize:vertical;line-height:1.55}
input::placeholder,textarea::placeholder{color:var(--muted);opacity:1}
/* The native select control renders as a light Windows widget on a dark page, which is the
   one field that never matched the rest. Drawn here instead, caret and all. */
select{appearance:none;-webkit-appearance:none;padding-right:42px;cursor:pointer;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 8'%3E%3Cpath fill='%239db0c8' d='M1.4 0 6 4.6 10.6 0 12 1.4 6 7.4 0 1.4z'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 15px center;background-size:11px 7px}
select option{background:var(--bg);color:var(--ink)}
button{font:inherit;cursor:pointer}
.narrow{max-width:300px}

.signup .fieldset{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);
  padding:26px 24px;display:grid;gap:18px}
/* Form section headings are labels for a group of fields, not page headlines, so they sit a
   step below the display scale and carry a hairline instead of shouting. */
.signup .fieldset h2{font-size:clamp(19px,2.2vw,23px);margin:0;padding-bottom:14px;
  border-bottom:1px solid var(--line)}
fieldset.choices{border:0;padding:0;margin:0;display:grid;gap:11px}
fieldset.choices legend{font-size:14px;font-weight:700;padding:0;margin-bottom:11px}
.choice{display:flex;align-items:flex-start;gap:11px;font-weight:400;font-size:15px;margin:0;cursor:pointer;line-height:1.45}
.choice input{width:17px;height:17px;margin-top:2px;flex:none;accent-color:var(--red);cursor:pointer}
/* The two blocks that appear only when the age answer calls for them. */
.youth,.guardian,.adult{display:grid;gap:16px;border-left:3px solid var(--red);padding-left:18px}
.youth,.adult{gap:0}
/* The running total and the button belong together, so they are one band rather than two
   stacked blocks with a gap between them. */
.submitrow{background:var(--navy);border-radius:var(--radius);padding:18px 20px;
  display:flex;align-items:center;justify-content:space-between;gap:18px;flex-wrap:wrap}
.owed{color:#fff;font-size:17px;margin:0}
.owed .hint{color:var(--on-navy-soft);display:block;margin-top:4px;font-size:13px;max-width:none}
.submitrow .btn{flex:none}
@media(max-width:520px){.submitrow{align-items:stretch}.submitrow .btn{width:100%;text-align:center}}
/* The honeypot. Off screen rather than display:none, because some bots skip hidden inputs. */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
@media(max-width:620px){.signup .fieldset{padding:20px 18px}}

/* ---------- empty states ---------- */
.empty{border:1px dashed var(--line);border-radius:var(--radius);padding:28px;color:var(--muted);text-align:center;grid-column:1 / -1}
.empty a{color:var(--red-text);font-weight:700}

/* ---------- footer ----------
   Three columns: who and where, the site's own pages, everywhere else the club exists.
   Then one fine-print row. The club's one standing message, that Facebook is where the talking
   happens, is said once on the home page and once here, and nowhere else. */
/* White, to bookend the white header. It also lets the burgee be the plain navy-on-white mark
   at a proper size, instead of the outlined version wearing a pale halo on a navy field. */
footer.site{background:var(--head-bg);color:var(--head-ink);border-top:3px solid var(--red);
  padding:56px 0 28px;font-size:14px;margin-top:80px}
footer.site a{color:var(--head-link);text-decoration:none;border-bottom:1px solid rgba(15,28,46,.28)}
footer.site a:hover{color:var(--head-ink);border-bottom-color:var(--head-ink)}
footer.site .cols{display:grid;grid-template-columns:2fr 1fr 1fr;gap:40px}
footer.site .who img{margin-bottom:18px;height:72px;width:auto}
footer.site .who p{margin-top:3px;color:#54637a}          /* 5.9:1 on white */
footer.site .who .nm{font-family:var(--display);text-transform:uppercase;font-weight:700;font-size:21px;color:var(--head-ink);letter-spacing:.01em;margin-bottom:8px}
footer.site .hd{font-size:11px;letter-spacing:.16em;text-transform:uppercase;font-weight:700;color:#54637a;margin-bottom:14px}
footer.site ul{list-style:none;margin:0;padding:0}
footer.site li{margin-bottom:9px}
footer.site .fine{display:flex;justify-content:space-between;gap:24px;flex-wrap:wrap;
  margin-top:44px;padding-top:20px;border-top:1px solid rgba(15,28,46,.14);
  font-size:13px;color:#54637a}
footer.site .fine span{max-width:58ch}
@media(max-width:760px){
  footer.site{padding:40px 0 24px;margin-top:56px}
  footer.site .cols{grid-template-columns:1fr;gap:32px}
  footer.site .who img{height:64px}
  footer.site .fine{margin-top:32px;gap:12px}
}

/* ---------- partner block, the MudRatz introduction ---------- */
.partner{display:grid;grid-template-columns:200px 1fr;gap:36px;align-items:start;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:32px}
.partner img{width:100%;height:auto}
.partner p{color:var(--muted);margin-top:14px;max-width:68ch}
.partner h2{margin-bottom:0}
@media(max-width:720px){
  .partner{grid-template-columns:1fr;gap:22px;padding:24px 20px}
  .partner img{width:150px}
}
.badge-row{margin-top:26px}
.badge-row img{width:280px;height:auto}
.fineprint{color:var(--muted);font-size:13.5px;max-width:68ch}

/* ---------- members table ---------- */
.tablewrap{overflow-x:auto;border:1px solid var(--line);border-radius:var(--radius);background:var(--card);margin-top:22px}
table.members{width:100%;border-collapse:collapse;font-size:15px}
table.members th{text-align:left;font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted);
  font-weight:700;padding:14px 20px;border-bottom:1px solid var(--line);white-space:nowrap}
table.members td{padding:14px 20px;border-bottom:1px solid var(--line)}
table.members tr:last-child td{border-bottom:0}
table.members td:first-child{font-weight:700}
table.members td:nth-child(2),table.members td:last-child{color:var(--muted)}
.pill{display:inline-block;padding:3px 10px;border-radius:999px;font-size:11.5px;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;white-space:nowrap}
.pill.on{background:rgba(46,160,79,.18);color:#7fe0a0;border:1px solid rgba(127,224,160,.35)}
.pill.off{background:rgba(207,46,36,.16);color:var(--red-text);border:1px solid rgba(255,128,120,.3)}

/* ---------- map ----------
   A Google embed, which is the one third party thing on the site. It is here because a pin is
   genuinely more useful than a paragraph for finding a spot on the Seaport grounds. It is lazy
   loaded, so it costs nothing until someone scrolls to it. */
.mapwrap{position:relative;margin-top:28px;border-radius:var(--radius);overflow:hidden;
  border:1px solid var(--line);background:var(--card);aspect-ratio:16/9}
.mapwrap iframe{position:absolute;inset:0;width:100%;height:100%;border:0;display:block}
@media(max-width:620px){.mapwrap{aspect-ratio:4/3}}

/* QA round 1: replaced inline styles so the CSP stays strict */
.card-sub{color:var(--muted);margin-top:10px;font-size:15px}
.sub-gap{margin-top:22px}

/* ---------- the officers' desk ----------
   Signed in, officer flagged, noindex, and linked from nowhere but the members page. The
   styling is deliberately plain: this is a work surface, not a page anyone is being sold. */
.card.desk{margin-bottom:18px}
.card.desk dl{display:grid;grid-template-columns:auto 1fr;gap:6px 18px;margin-top:14px;font-size:15px}
.card.desk dt{color:var(--muted);font-weight:400}
.card.desk dd{margin:0}
.deskrow{display:flex;gap:10px;flex-wrap:wrap;margin-top:16px}
.deskrow .btn{margin:0}
.btn.small{padding:7px 12px;font-size:13px}
table.members .deskrow{margin:0}
@media(max-width:520px){.card.desk dl{grid-template-columns:1fr;gap:2px}.card.desk dt{margin-top:8px}}

/* The members directory carries contact details now, so it is a wider table than it was.
   .tablewrap already scrolls sideways on a phone, which is the right answer for a table of
   real data: shrinking the type to fit would make it unreadable for exactly the people most
   likely to need a phone number. */
table.members .contact{font-size:14px;line-height:1.5;white-space:nowrap}
table.members .contact a{color:var(--red-text);text-decoration:none}
table.members .contact a:hover{text-decoration:underline}
table.members .muted{color:var(--muted)}
table.members .renews{display:block;color:var(--muted);font-size:13px;margin-top:5px;white-space:nowrap}
.emailrow{margin-top:8px}
.emailrow input{width:auto;min-width:200px;padding:7px 10px;font-size:13px}

/* ---------- the shop ----------
   Preorder cards. The Founding Member Sponsor bundle is marked featured in club.json and
   gets a wider card, image beside copy instead of above it, so it reads as the one to look
   at first without shouting over the others. */
/* Column minimum is 300, not 240. In a 1080 wrap, 240 plus 20 gaps let four columns fit, and
   with three regular cards under the full width featured one that left an empty fourth
   column. 300 caps it at three (4 x 300 + 3 x 20 = 1260 > 1080; 3 x 300 + 40 = 940 fits),
   and min(100%, 300px) keeps it one column on a 335 wide phone instead of overflowing. */
.shop{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,300px),1fr));gap:20px;margin-top:28px}
.shopitem{display:flex;flex-direction:column}
/* height:auto matters. The cards ship with width="522" height="522" on the img so the page
   does not jump while it loads, but with width forced to 100% and no height rule the 522
   attribute won, and the Hat, Sticker and Burgee rendered as 198 x 522 strips. */
.shopitem img{width:100%;height:auto;aspect-ratio:1/1;object-fit:cover;border-radius:var(--radius);background:var(--line)}
.shopitem-body{margin-top:18px;display:flex;flex-direction:column;flex:1}
.shopitem .price{color:var(--red-text);font-weight:700;font-size:19px;margin-top:6px}
.shopitem>.shopitem-body>p:not(.price):not(.kicker):not(.hint){color:var(--muted);margin-top:8px;font-size:15px}
.shopitem .qty{display:flex;align-items:center;gap:12px;margin-top:auto;padding-top:18px}
.shopitem .qty label{margin:0;font-size:13px;color:var(--muted);font-weight:400}
.shopitem .qty select{width:auto;min-width:70px}
.shopitem.featured{grid-column:1 / -1;flex-direction:row;gap:28px;align-items:flex-start}
.shopitem.featured img{width:220px;height:220px;flex:none}
.shopitem.featured .shopitem-body{margin-top:0}
@media(max-width:620px){
  .shopitem.featured{flex-direction:column}
  .shopitem.featured img{width:100%;height:auto}
}
.success{margin-top:22px}
