/* ============================================================================
   ComicsPRO — COMPONENTS
   ----------------------------------------------------------------------------
   Hand-written CSS equivalents of the design system's React components, with
   matching variant names so the design system's documentation stays accurate
   against this stylesheet. Values reference tokens throughout, with one
   documented exception: the .on-ink shadow overrides need literal offsets
   because no token exists for a light-on-dark hard shadow. Fold them back into
   the design system as --shadow-pop-on-ink if they prove durable.

   Design system → class map
     Button        → .cp-btn      (base = primary; --secondary --dark --ghost --accent --block | --sm --lg)
     Card          → .cp-card     (--panel --cyan --tint --ink --paper --flat | .is-interactive)
     Tag           → .cp-tag
     Alert         → .cp-alert    (--info --success --warning --danger)
     SectionHeading→ .cp-heading
     BenefitCard   → .cp-benefit
     StatCard      → .cp-stat
     MemberCard    → .cp-member
     Starburst     → .cp-burst    (--cyan --red --pow)
     Input/Select/Checkbox → .cp-field / .cp-input / .cp-select / .cp-check

   Added by this build (not in the design system yet)
     .cp-card--featured   the one live tier among several
     .cp-heading--spark   SectionHeading with the starburst accent
     .cp-member__photo--initials   headshot fallback
     .cp-hero--condensed  alias of .cp-phead, per spec §6.3
     .cp-benefits--four / --six    non-uniform benefit grids
     .cp-split--top       card pairs that must align at the top
     .cp-sectionbar       heading block + trailing action
     .cp-price            tier price figure
     .cp-h-sm / .cp-caption / .cp-note   the three repeating type steps
     .cp-soon             status pill. Deliberately FLAT — no offset shadow,
                          no hover — because in this world depth means
                          interactive, so a non-interactive label must have none
     .cp-members-only     gated-post indicator. Cyan FILL so it reads as a
                          property of the post, not as another filter control
     .cp-faq              native <details>/<summary> disclosure list, no JS
     .cp-stream-empty     empty state for a filter that matches nothing
     .cp-linkish          a real <button> styled as a link, for mid-sentence
                          controls that must stay keyboard-operable
     .cp-pillars          five-item benefit grid (3 across, then 2 wider)

   Direction-specific (THE MEMBERSHIP SUMMARY — see the contract in index.html)
     .cp-mcard   the membership summary panel. NOTE: this renders LIKE a card
                 because the form carries price, tier and eligibility in one
                 glance — but ComicsPRO issues no physical membership card and
                 no copy may imply one. See plan 2026-08-05, Task 1.
     .cp-badge   the Annual Conference lanyard badge
     .cp-frame   outlined, rotated photo panel
     .cp-pull    pull-box divider item (news)
   ============================================================================ */


/* ==== Button ============================================================== */

.cp-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: 16px;
  line-height: 1;
  letter-spacing: 0.01em;
  padding: 13px 26px;
  color: var(--cp-ink);
  background: var(--cp-cyan);
  border: var(--stroke) solid var(--border-ink);
  border-radius: var(--radius-pill);
  box-shadow: var(--shadow-pop);
  cursor: pointer;
  text-decoration: none;
  -webkit-tap-highlight-color: transparent;
  transition: transform var(--dur-fast) var(--ease-pop),
              box-shadow var(--dur-fast) var(--ease-pop),
              background var(--dur) ease;
}
.cp-btn:hover {
  color: var(--cp-ink);
  transform: translate(-1px, -1px);
  box-shadow: var(--shadow-pop-lg);
}
.cp-btn:active {
  transform: translate(2px, 2px);
  box-shadow: 0 0 0 var(--cp-ink-surface);
}

.cp-btn--secondary { background: var(--cp-white); }
.cp-btn--dark      { background: var(--cp-ink); color: var(--cp-white); }
.cp-btn--dark:hover{ color: var(--cp-white); }
.cp-btn--ghost     { background: transparent; }
.cp-btn--accent    { background: var(--cp-red); color: var(--cp-white); }
.cp-btn--accent:hover { color: var(--cp-white); }

.cp-btn--sm { padding: 8px 16px; font-size: 14px; box-shadow: var(--shadow-pop-sm); }
.cp-btn--sm:hover { box-shadow: var(--shadow-pop); }
.cp-btn--lg { padding: 18px 38px; font-size: 19px; }

.cp-btn--block { display: flex; width: 100%; }

.cp-btn[aria-disabled="true"],
.cp-btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
  pointer-events: none;
}

/* On the ink ground a soft-black offset renders at ≈1.68:1 and disappears.
   The PRIMARY must keep the heaviest object weight, so it takes the visible
   shadow and the ghost drops to none — the reverse of what shipped first. */
.on-ink .cp-btn { box-shadow: 5px 5px 0 var(--cp-white); }
.on-ink .cp-btn:hover { box-shadow: 8px 8px 0 var(--cp-white); }
.on-ink .cp-btn:active { box-shadow: 0 0 0 var(--cp-white); }
.on-ink .cp-btn--lg { box-shadow: 6px 6px 0 var(--cp-white); }
.on-ink .cp-btn--lg:hover { box-shadow: 9px 9px 0 var(--cp-white); }

.on-ink .cp-btn--ghost { box-shadow: none; color: var(--cp-white); border-color: var(--cp-white); }
.on-ink .cp-btn--ghost:hover { box-shadow: none; color: var(--cp-ink); background: var(--cp-white); transform: translate(-1px,-1px); }
.on-ink .cp-btn--dark { box-shadow: 5px 5px 0 var(--cp-cyan); }
.on-ink .cp-btn--dark:hover { box-shadow: 8px 8px 0 var(--cp-cyan); }


/* --focus-ring resolves to the fill-only brand blue (~2.19:1 on white), under
   the 3:1 SC 1.4.11 needs. Deep blue on light grounds, bright blue on ink. */
:focus-visible { outline-color: var(--cp-cyan-deep); }
.on-ink :focus-visible, .cp-footer :focus-visible, .cp-utility :focus-visible { outline-color: var(--cp-cyan); }
/* Deep blue on the brand blue is 2.65:1 — under 3:1. Ink carries it there. */
.cp-card--cyan :focus-visible, .cp-meetfeature :focus-visible, .cp-section--cyan :focus-visible { outline-color: var(--cp-ink); }
/* A component that paints its own LIGHT background inside .on-ink must also
   own its focus ring — cyan on white is 2.19:1, under the 3:1 SC 1.4.11 bar.
   Mirrors the light-component text rule documented below. */
.on-ink .cp-card:not(.cp-card--cyan) :focus-visible,
.on-ink .cp-alert :focus-visible,
.on-ink .cp-mcard:not(.cp-mcard--cyan) :focus-visible,
.on-ink .cp-step :focus-visible,
.on-ink .cp-frame :focus-visible { outline-color: var(--cp-cyan-deep); }


/* ==== Light components on a dark ground =================================== *
 * A component that paints its own light background must own its own text
 * colour, or it inherits .on-ink's white and renders invisible. Listed here
 * are the light components that CARRY TEXT. .cp-frame, .cp-tag and .cp-burst
 * are also light-surfaced but each sets its own colour or holds no text; add
 * any new text-bearing light component to this list.                        */
.on-ink .cp-card,
.on-ink .cp-alert,
.on-ink .cp-mcard,
.on-ink .cp-badge,
.on-ink .cp-benefit,
.on-ink .cp-member,
.on-ink .cp-pull,
.on-ink .cp-step,
.on-ink .cp-agenda,
.on-ink .cp-reserved {
  --text-body: var(--cp-ink-soft);
  --text-heading: var(--cp-ink);
  --text-muted: var(--cp-ink-50);
  --text-link: var(--cp-blue);
  --text-link-hover: var(--cp-blue-deep);
  color: var(--text-body);
}
/* …except the ones that are deliberately dark. */
.on-ink .cp-card--ink,
.cp-card--ink {
  --text-body: var(--cp-white);
  --text-heading: var(--cp-white);
  --text-muted: var(--cp-gray-light);
  --text-link: var(--cp-cyan);
  color: var(--text-body);
}
/* A white offset shadow vanishes on a white card. */
.on-ink .cp-card .cp-btn { box-shadow: var(--shadow-pop); }
.on-ink .cp-card .cp-btn:hover { box-shadow: var(--shadow-pop-lg); }
.on-ink .cp-card .cp-btn:active { box-shadow: 0 0 0 var(--cp-ink-surface); }


/* ==== Card ================================================================ */

.cp-card {
  background: var(--surface-card);
  border: var(--stroke) solid var(--border-ink);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop);
  padding: var(--space-5);
}
.cp-card--panel { background: var(--surface-panel); }
.cp-card--cyan  { background: var(--cp-cyan); }
.cp-card--tint  { background: var(--cp-cyan-tint); }
.cp-card--ink   { background: var(--cp-ink); color: var(--cp-white); }
.cp-card--ink h1, .cp-card--ink h2, .cp-card--ink h3, .cp-card--ink h4 { color: var(--cp-white); }
.cp-card--paper { background: var(--cp-paper); }
.cp-card--flat  { box-shadow: none; }
/* The one live tier among three. Was an inline border-width. */
.cp-card--featured { border-width: 5px; }

.cp-card.is-interactive {
  display: block;
  text-decoration: none;
  color: inherit;
  transition: transform var(--dur) var(--ease-pop), box-shadow var(--dur) var(--ease-pop);
}
.cp-card.is-interactive:hover {
  transform: var(--lift);
  box-shadow: var(--shadow-pop-lg);
  color: inherit;
}


/* ==== Tag ================================================================= */

.cp-tag {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: var(--fs-caption);
  letter-spacing: 0.04em;
  text-transform: uppercase;
  padding: 5px 14px;
  background: var(--cp-white);
  color: var(--cp-ink);
  border: var(--stroke-hair) solid var(--border-ink);
  border-radius: var(--radius-pill);
  text-decoration: none;
  white-space: nowrap;
}
.cp-tag--cyan   { background: var(--cp-cyan); }
.cp-tag--tint   { background: var(--cp-cyan-tint); }
.cp-tag--yellow { background: var(--cp-yellow); }
.cp-tag--ink    { background: var(--cp-ink); color: var(--cp-white); border-color: var(--cp-white); }

a.cp-tag { transition: transform var(--dur-fast) var(--ease-pop), background var(--dur) ease; }
a.cp-tag:hover { transform: translate(-1px, -1px); background: var(--cp-cyan); color: var(--cp-ink); }

/* Filters must not look like the static category chips beside them. */
.cp-filters .cp-tag {
  background: var(--cp-cyan-tint);
  box-shadow: var(--shadow-pop-sm);   /* the real affordance — tint alone is 1.16:1 vs white */
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-pop), background var(--dur) ease, box-shadow var(--dur-fast) var(--ease-pop);
}
.cp-filters .cp-tag:hover { transform: translate(-1px, -1px); background: var(--cp-cyan); box-shadow: var(--shadow-pop); }
/* Hovering the selected filter must not repaint it as deselected. */
.cp-filters .cp-tag[aria-pressed="true"]:hover { background: var(--cp-ink); color: var(--cp-white); }

/* Filter row uses aria-pressed as the state carrier. */
.cp-tag[aria-pressed="true"] {
  background: var(--cp-ink);
  color: var(--cp-white);
  border-color: var(--cp-ink);
}


/* ==== Status pill ========================================================= *
 * "Coming Soon" and similar. Deliberately NOT a .cp-tag and NOT a button:
 * flat grey, no offset shadow, no hover. In this world depth means
 * interactive, so a status pill must have none.                              */
.cp-soon {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: var(--fs-caption);
  font-style: normal;          /* it is applied to an <em> in the footer */
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cp-ink);
  background: var(--cp-gray-light);
  border: var(--stroke-hair) solid var(--cp-ink-50);
  border-radius: var(--radius-pill);
  padding: 4px 13px;
  box-shadow: none;
  cursor: default;
  white-space: nowrap;
}
/* On the ink footer the light-gray fill needs no change — it is 15.9:1 on
   black and the ink text sits at 15.3:1 on the fill. */


/* ==== FAQ ================================================================= *
 * Native <details>/<summary>. No JS — the disclosure is the platform's.      */
.cp-faq { border: var(--stroke) solid var(--border-ink); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-pop); }
.cp-faq details { border-bottom: var(--stroke-hair) solid var(--border-ink); background: var(--cp-white); }
.cp-faq details:last-child { border-bottom: 0; }
.cp-faq summary {
  cursor: pointer; padding: var(--space-4) var(--space-5);
  font-family: var(--font-body); font-weight: var(--fw-bold); font-size: var(--fs-body);
  color: var(--text-heading); list-style: none; display: flex; justify-content: space-between; gap: var(--space-4);
}
.cp-faq summary::-webkit-details-marker { display: none; }
.cp-faq summary::after { content: "+"; font-family: var(--font-display); font-size: var(--fs-h4); line-height: 1; }
.cp-faq details[open] summary::after { content: "–"; }
.cp-faq details[open] summary { background: var(--cp-cyan-tint); }
.cp-faq__body { padding: 0 var(--space-5) var(--space-5); font-size: var(--fs-body-sm); }
.cp-faq__body p:last-child, .cp-faq__body ul:last-child { margin-bottom: 0; }


/* ==== Empty state ======================================================== *
 * Shown when a news filter matches nothing. The reset-to-everything control
 * is a real <button> for keyboard and screen-reader users, styled as a link
 * because it reads mid-sentence.                                            */
.cp-stream-empty { text-align: center; padding: var(--space-8) 0; }
.cp-linkish {
  font: inherit; color: var(--text-link); background: none; border: 0;
  padding: 0; text-decoration: underline; cursor: pointer;
}
.cp-linkish:hover { color: var(--cp-ink); }


/* ==== Members-only indicator ============================================= *
 * Marks a gated post in an otherwise public feed. Cyan fill + ink text, so
 * it reads as a property of the post, not as another filter control.        */
.cp-members-only {
  display: inline-flex; align-items: center; gap: 5px;
  font-family: var(--font-body); font-weight: var(--fw-bold);
  font-size: var(--fs-caption); letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--cp-ink); background: var(--cp-cyan);
  border: var(--stroke-hair) solid var(--border-ink);
  border-radius: var(--radius-pill); padding: 2px 9px; white-space: nowrap;
}
/* flex: none — the badge is inline-flex and the glyph is a flex item, so
   without this it shrinks to width 0 and the lock silently disappears. */
.cp-members-only svg { width: 12px; height: 12px; flex: none; }


/* ==== Starburst =========================================================== */

.cp-burst {
  display: inline-block;
  width: 64px;
  aspect-ratio: 1;
  background: var(--cp-yellow);
  clip-path: polygon(50% 0%, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0% 50%, 40% 40%);
  filter:
    drop-shadow( 1.5px 0 0 var(--cp-ink-surface))
    drop-shadow(-1.5px 0 0 var(--cp-ink-surface))
    drop-shadow(0  1.5px 0 var(--cp-ink-surface))
    drop-shadow(0 -1.5px 0 var(--cp-ink-surface));
  flex: none;
}
.cp-burst--cyan { background: var(--cp-cyan); }
.cp-burst--red  { background: var(--cp-red); }

/* "Pow" burst — a spiky 16-point badge that takes a label. */
.cp-burst--pow {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  clip-path: polygon(
    50% 0%, 57.3% 11.4%, 63.9% 4.1%, 68.6% 16.6%, 77.4% 11.4%, 78.9% 24.7%,
    89.1% 22.6%, 86.6% 35.8%, 97.1% 38.2%, 90.4% 49.2%, 100% 50%, 90.4% 60.8%,
    97.1% 61.8%, 86.6% 74.2%, 89.1% 77.4%, 78.9% 75.3%, 77.4% 88.6%, 68.6% 83.4%,
    63.9% 95.9%, 57.3% 88.6%, 50% 100%, 42.7% 88.6%, 36.1% 95.9%, 31.4% 83.4%,
    22.6% 88.6%, 21.1% 75.3%, 10.9% 77.4%, 13.4% 74.2%, 2.9% 61.8%, 9.6% 60.8%,
    0% 50%, 9.6% 49.2%, 2.9% 38.2%, 13.4% 35.8%, 10.9% 22.6%, 21.1% 24.7%,
    22.6% 11.4%, 31.4% 16.6%, 36.1% 4.1%, 42.7% 11.4%
  );
  font-family: var(--font-pop);
  font-weight: 600;
  text-transform: uppercase;
  color: var(--cp-ink);
  line-height: 1.05;
  text-align: center;
  transform: rotate(-8deg);
  filter:
    drop-shadow( 2px 0 0 var(--cp-ink-surface))
    drop-shadow(-2px 0 0 var(--cp-ink-surface))
    drop-shadow(0  2px 0 var(--cp-ink-surface))
    drop-shadow(0 -2px 0 var(--cp-ink-surface));
}


/* ==== Section heading ===================================================== */

.cp-heading { margin-bottom: var(--space-7); max-width: 46ch; }
.cp-heading > h2, .cp-heading > h3 { margin-bottom: var(--space-4); }
.cp-heading p {
  font-size: var(--fs-body-lg);
  color: var(--text-muted);
  margin: 0;
  max-width: 60ch;
}
.cp-heading--spark > h2, .cp-heading--spark > h3 { display: flex; align-items: center; gap: var(--space-4); }
.cp-heading--spark > h2::after, .cp-heading--spark > h3::after {
  content: "";
  width: 30px; height: 30px; flex: none;
  background: var(--cp-yellow);
  clip-path: polygon(50% 0%, 60% 40%, 100% 50%, 60% 60%, 50% 100%, 40% 60%, 0% 50%, 40% 40%);
  filter: drop-shadow(1.5px 0 0 var(--cp-ink-surface)) drop-shadow(-1.5px 0 0 var(--cp-ink-surface))
          drop-shadow(0 1.5px 0 var(--cp-ink-surface)) drop-shadow(0 -1.5px 0 var(--cp-ink-surface));
}
.cp-heading--center { margin-left: auto; margin-right: auto; text-align: center; }
.cp-heading--center p { margin-left: auto; margin-right: auto; }
.on-ink .cp-heading p { color: var(--cp-cyan-tint); }


/* ==== Benefit ============================================================= */

.cp-benefit {
  background: var(--surface-card);
  border: var(--stroke) solid var(--border-ink);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop);
  padding: var(--space-6) var(--space-5) var(--space-5);
}
.cp-benefit h3 {
  font-size: var(--fs-h4);
  font-family: var(--font-display);
  font-weight: 600;
  margin-bottom: var(--space-3);
}
.cp-benefit p { margin: 0; color: var(--text-body); font-size: var(--fs-body-sm); }
.cp-benefit__icon {
  width: 54px; height: 54px;
  display: grid;
  place-items: center;
  background: var(--cp-cyan);
  border: var(--stroke-hair) solid var(--border-ink);
  border-radius: var(--radius-md);
  margin-bottom: var(--space-4);
}
.cp-benefit__icon svg { width: 27px; height: 27px; }
.cp-benefit--tint  .cp-benefit__icon { background: var(--cp-cyan-tint); }
.cp-benefit--yellow .cp-benefit__icon { background: var(--cp-yellow); }


/* ==== Stat ================================================================ */

.cp-stat { display: block; }
.cp-stat__num {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: clamp(2.75rem, 6vw, var(--fs-h1));
  line-height: 1;
  letter-spacing: var(--ls-display);
  color: var(--cp-cyan);
  display: block;
}
.cp-stat__label {
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: var(--fs-caption);
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cp-white);
  margin-top: var(--space-2);
  display: block;
}


/* ==== Member card (person) ================================================ */

.cp-member {
  background: var(--surface-card);
  border: var(--stroke) solid var(--border-ink);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop);
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.cp-member__photo {
  aspect-ratio: 4 / 5;
  background: var(--cp-cyan-tint);
  border-bottom: var(--stroke) solid var(--border-ink);
  overflow: hidden;
}
.cp-member__photo img {
  width: 100%; height: 100%;
  object-fit: cover;
  object-position: center 22%;
}
/* Documented fallback for a missing headshot. */
.cp-member__photo--initials {
  display: grid; place-items: center;
  font-family: var(--font-display); font-weight: 600;
  font-size: var(--fs-h1); color: var(--cp-cyan-deep);
  letter-spacing: 0.04em;
}
.cp-member__body { padding: var(--space-4) var(--space-5) var(--space-5); }
.cp-member__name {
  font-family: var(--font-display);
  font-weight: 600;
  text-transform: uppercase;
  font-size: var(--fs-h4);
  line-height: var(--lh-snug);
  color: var(--text-heading);
  margin: 0 0 var(--space-1);
}
.cp-member__role {
  font-weight: var(--fw-bold);
  font-size: var(--fs-body-sm);
  color: var(--cp-cyan-deep);
  margin: 0 0 var(--space-2);
}
.cp-member__shop {
  font-size: var(--fs-body-sm);
  color: var(--text-muted);
  margin: 0;
}


/* ==== Alert =============================================================== */

.cp-alert {
  color: var(--text-body);
  display: flex;
  gap: var(--space-4);
  align-items: flex-start;
  background: var(--cp-cyan-tint);
  border: var(--stroke-hair) solid var(--border-ink);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  font-size: var(--fs-body-sm);
}
.cp-alert__mark { flex: none; width: 22px; height: 22px; margin-top: 1px; }
.cp-alert p:last-child { margin-bottom: 0; }
.cp-alert p { max-width: 68ch; }
.cp-alert--info    { background: var(--cp-cyan-tint); }   /* = the base style; declared so the variant map is true */
.cp-alert--success { background: var(--cp-cyan-tint); }
.cp-alert--warning { background: var(--cp-yellow); }
.cp-alert--danger  { background: var(--cp-white); border-color: var(--cp-red); }


/* ==== Forms =============================================================== */

.cp-field { display: block; margin-bottom: var(--space-5); }
.cp-field__label {
  display: block;
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: var(--fs-caption);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--text-heading);
  margin-bottom: var(--space-2);
}
.cp-input, .cp-select {
  width: 100%;
  font-family: var(--font-body);
  font-size: var(--fs-body);
  color: var(--text-body);
  background: var(--cp-white);
  border: var(--stroke-hair) solid var(--border-ink);
  border-radius: var(--radius-md);
  padding: 12px 16px;
  box-shadow: var(--shadow-soft-sm);
  transition: border-color var(--dur) ease, box-shadow var(--dur) ease;
}
.cp-input::placeholder { color: var(--text-muted); }
.cp-input:focus-visible, .cp-select:focus-visible {
  /* Split, not shorthand: `outline:` resets outline-color and would defeat
     the .cp-card--cyan override above (deep blue on brand blue is 2.65:1). */
  outline-width: var(--stroke);
  outline-style: solid;
  outline-color: var(--cp-cyan-deep);
  outline-offset: 1px;
  border-color: var(--cp-cyan-deep);
  box-shadow: none;
}
/* Mouse focus keeps the softer treatment. */
.cp-input:focus:not(:focus-visible), .cp-select:focus:not(:focus-visible) {
  outline: none;
  border-color: var(--cp-cyan-deep);
  box-shadow: 0 0 0 3px var(--cp-cyan-tint);
}
.cp-field__hint { display: block; font-size: var(--fs-caption); color: var(--text-muted); margin-top: var(--space-2); }

.cp-check { display: flex; gap: var(--space-3); align-items: flex-start; font-size: var(--fs-body-sm); }
.cp-check input {
  flex: none;
  appearance: none;
  width: 22px; height: 22px;
  margin: 1px 0 0;
  background: var(--cp-white);
  border: var(--stroke-hair) solid var(--border-ink);
  border-radius: var(--radius-sm);
  cursor: pointer;
  display: grid;
  place-content: center;
  transition: background var(--dur-fast) ease;
}
.cp-check input::after {
  content: "";
  width: 11px; height: 6px;
  border-left: 2.5px solid var(--cp-ink);
  border-bottom: 2.5px solid var(--cp-ink);
  transform: rotate(-45deg) translate(1px, -1px) scale(0);
  transition: transform var(--dur-fast) var(--ease-pop);
}
.cp-check input:checked { background: var(--cp-cyan); }
.cp-check input:checked::after { transform: rotate(-45deg) translate(1px, -1px) scale(1); }


/* ==== Repeating type steps ================================================ */
/* Extracted because these three pairs accounted for ~15 inline styles. */
.cp-h-sm   { font-size: var(--fs-h4); }
.cp-caption{ font-size: var(--fs-caption); color: var(--text-muted); }
/* Dark Gray on the brand blue is 2.62:1 — under AA. Ink-70 measures 5.76:1.
   Same remedy as .cp-mcard--cyan below. */
.cp-card--cyan .cp-caption,
.cp-section--cyan .cp-caption,
.cp-meetfeature .cp-caption { color: var(--cp-ink-70); }
.cp-note   { font-size: var(--fs-body-sm); color: var(--text-muted); }
.cp-note--flush, .cp-caption--flush { margin: 0; }


/* ==== Photo frame ========================================================= */
/* Real photography sits in an outlined panel, usually rotated 1–2°. The one
   exception is the auction photo on conference.html, already inside a card —
   framing it would double the outline. */

.cp-frame {
  border: var(--stroke) solid var(--border-ink);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop-lg);
  overflow: hidden;
  background: var(--cp-cyan-tint);
  line-height: 0;
}
.cp-frame img { width: 100%; height: 100%; object-fit: cover; }
.cp-frame--tilt-l { transform: rotate(-1.5deg); }
.cp-frame--tilt-r { transform: rotate(1.5deg); }
.cp-frame--cyan   { box-shadow: 8px 8px 0 var(--cp-cyan); }


/* ============================================================================
   THE MEMBERSHIP SUMMARY PANEL — the direction's signature artifact.
   Renders LIKE a card because the form carries price, tier and eligibility
   in one glance. ComicsPRO issues no physical card and no copy may imply one.
   ============================================================================ */

.cp-mcard {
  --mcard-face: var(--cp-white);
  position: relative;
  background: var(--mcard-face);
  border: var(--stroke) solid var(--border-ink);
  border-radius: var(--radius-xl);
  box-shadow: var(--shadow-pop-lg);
  max-width: 460px;
  container-type: inline-size;
}
/* No overflow:hidden — it clipped the starburst pinned to the corner. The
   strip and foot round themselves instead. */
.cp-mcard__strip { border-radius: calc(var(--radius-xl) - 3px) calc(var(--radius-xl) - 3px) 0 0; }
.cp-mcard__foot  { border-radius: 0 0 calc(var(--radius-xl) - 3px) calc(var(--radius-xl) - 3px); }
/* On the ink ground the soft-black offset vanishes; cyan carries the depth. */
.on-ink .cp-mcard, .on-ink .cp-badge { box-shadow: 8px 8px 0 var(--cp-cyan); }
.cp-mcard--cyan { --mcard-face: var(--cp-cyan); }
/* Dark Gray on the brand blue is 2.62:1. Ink-70 measures 5.76:1. */
.cp-mcard--cyan .cp-mcard__key,
.cp-mcard--cyan .cp-mcard__val--blank { color: var(--cp-ink-70); }
.cp-mcard--cyan .cp-mcard__val { border-bottom-color: var(--cp-ink-70); }
.cp-mcard--tint { --mcard-face: var(--cp-cyan-tint); }

.cp-mcard__strip {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-3) var(--space-8) var(--space-3) var(--space-5);
  background: var(--cp-ink);
  border-bottom: var(--stroke) solid var(--border-ink);
}
.cp-mcard__strip img { height: 30px; width: auto; }
.cp-mcard__org {
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: var(--fs-overline);
  letter-spacing: var(--ls-overline);
  text-transform: uppercase;
  color: var(--cp-cyan);
}

.cp-mcard__body { padding: var(--space-6) var(--space-5) var(--space-5); }

/* The engraved slot lines: a form you complete, not a UI panel. The blank
   first slot is the point — the reader sees where their own shop goes. */
.cp-mcard__slot { margin-bottom: var(--space-5); }
.cp-mcard__key {
  display: block;
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: 10px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--cp-ink-50);
  margin-bottom: 2px;
}
.cp-mcard__val {
  font-family: var(--font-display);
  font-weight: 600;
  text-transform: uppercase;
  font-size: clamp(1.25rem, 5cqi, 1.75rem);
  line-height: 1.1;
  letter-spacing: 0.01em;
  color: var(--cp-ink);
  border-bottom: var(--stroke-hair) dashed var(--cp-ink-50);
  padding-bottom: var(--space-2);
  display: block;
}
.cp-mcard__val--blank { color: var(--cp-ink-50); }

.cp-mcard__foot {
  display: flex;
  align-items: flex-end;
  justify-content: space-between;
  gap: var(--space-4);
  padding: var(--space-4) var(--space-5);
  border-top: var(--stroke) solid var(--border-ink);
  background: var(--cp-gray-light);
}
.cp-mcard--cyan .cp-mcard__foot,
.cp-mcard--tint .cp-mcard__foot { background: var(--cp-white); }
.cp-mcard__dues {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-h3);
  line-height: 1;
  color: var(--cp-ink);
}
.cp-mcard__dues span {
  display: block;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: var(--fs-caption);
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--cp-ink-50);
  margin-top: 2px;
}
.cp-mcard__burst {
  position: absolute;
  top: -22px; right: -20px;
  width: 82px;
  font-size: 15px;
  z-index: 3;
}

/* The reverse face — what membership includes, in the same slot grammar. */
.cp-mcard--back .cp-mcard__body { padding-top: var(--space-5); }
.cp-mcard__list { list-style: none; margin: 0; padding: 0; }
.cp-mcard__list li {
  display: flex;
  gap: var(--space-3);
  align-items: flex-start;
  padding: var(--space-3) 0;
  border-bottom: 1px dashed var(--cp-ink-50);
  font-size: var(--fs-body-sm);
  margin: 0;
}
.cp-mcard__list li:last-child { border-bottom: 0; }
.cp-mcard__list svg { flex: none; width: 18px; height: 18px; margin-top: 3px; }


/* ==== Meeting badge (lanyard) ============================================= */

.cp-badge {
  position: relative;
  background: var(--cp-white);
  border: var(--stroke) solid var(--border-ink);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-pop-lg);
  max-width: 380px;
  overflow: hidden;
}
.cp-badge__punch {
  height: 34px;
  border-bottom: var(--stroke) solid var(--border-ink);
  background: var(--cp-cyan);
  display: grid;
  place-items: center;
}
/* the lanyard slot */
.cp-badge__punch::after {
  content: "";
  width: 74px; height: 12px;
  background: var(--cp-white);
  border: var(--stroke-hair) solid var(--border-ink);
  border-radius: var(--radius-pill);
}
.cp-badge__body { padding: var(--space-5); text-align: center; }
.cp-badge__event {
  font-family: var(--font-display);
  font-weight: 600;
  text-transform: uppercase;
  font-size: var(--fs-h3);
  line-height: 1.05;
  color: var(--cp-ink);
  margin: 0 0 var(--space-2);
}
.cp-badge__dates {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--fs-h2);
  line-height: 1;
  color: var(--cp-cyan-deep);
  margin: 0 0 var(--space-2);
}
.cp-badge__where {
  font-weight: var(--fw-bold);
  font-size: var(--fs-body-sm);
  color: var(--text-muted);
  margin: 0;
}
.cp-badge__foot {
  border-top: var(--stroke) solid var(--border-ink);
  background: var(--cp-ink);
  color: var(--cp-white);
  padding: var(--space-3) var(--space-5);
  font-family: var(--font-body);
  font-weight: var(--fw-bold);
  font-size: var(--fs-overline);
  letter-spacing: var(--ls-overline);
  text-transform: uppercase;
  text-align: center;
}


/* ==== Pull-box item (news) ================================================ */

.cp-pull {
  display: block;
  text-decoration: none;
  color: inherit;
  background: var(--cp-white);
  border: var(--stroke) solid var(--border-ink);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-pop-sm);
  padding: var(--space-5);
  border-top-width: 10px;
  transition: transform var(--dur) var(--ease-pop), box-shadow var(--dur) var(--ease-pop);
}
.cp-pull:hover { transform: var(--lift); box-shadow: var(--shadow-pop); color: inherit; }
/* Not wired up in the mockup — say so instead of scrolling to the top. */
.cp-pull.is-inert { cursor: default; }
.cp-pull.is-inert:hover { transform: none; box-shadow: var(--shadow-pop-sm); }
a.is-inert:not(.cp-pull) { cursor: default; text-decoration: underline dotted; text-underline-offset: 3px; }

.cp-pull.is-inert h3::after {
  content: " · not mocked";
  font-family: var(--font-body);
  font-size: 10px;
  font-weight: var(--fw-bold);
  letter-spacing: 0.1em;
  color: var(--cp-ink-50);
  white-space: nowrap;
}
/* flex-wrap is load-bearing: every child here is nowrap, so without it the
   row min-content width propagates into the grid track and overflows. */
.cp-pull__meta {
  flex-wrap: wrap;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  font-size: var(--fs-caption);
  color: var(--text-muted);
  font-weight: var(--fw-bold);
}
.cp-pull h3 {
  font-size: var(--fs-h4);
  font-family: var(--font-display);
  font-weight: 600;
  margin-bottom: var(--space-2);
}
.cp-pull p { margin: 0; font-size: var(--fs-body-sm); color: var(--text-body); }


/* ==== Agenda ============================================================== */

.cp-agenda { border: var(--stroke) solid var(--border-ink); border-radius: var(--radius-lg); overflow: hidden; box-shadow: var(--shadow-pop); }
.cp-agenda__day {
  display: grid;
  grid-template-columns: 168px 1fr;
  gap: var(--space-5);
  padding: var(--space-5);
  border-bottom: var(--stroke-hair) solid var(--border-ink);
  background: var(--cp-white);
}
.cp-agenda__day:last-child { border-bottom: 0; }
.cp-agenda__day:nth-child(even) { background: var(--cp-gray-light); }
.cp-agenda__when {
  font-family: var(--font-display);
  font-weight: 600;
  text-transform: uppercase;
  font-size: var(--fs-h4);
  line-height: 1.1;
  color: var(--cp-cyan-deep);
}
.cp-agenda__when span { display: block; font-family: var(--font-body); font-size: var(--fs-caption); font-weight: 700; color: var(--text-muted); letter-spacing: 0.06em; }
.cp-agenda__what { margin: 0; }
.cp-agenda__what li { font-size: var(--fs-body-sm); }
