/* HERO LAYOUT MODULE — the reusable CSS page-hero system. This is the
   top-of-page hero shown on the design-templates cards. Every hero arranges the
   SAME items a different way and is a named .he-* class on the hero (.he-hero).
   The items are always:

     .he-eyebrow   the vendor category
     .he-name      the business name (big heading)
     .he-pills     meta chips (.he-pill: service area, reply time)
     .he-bio       the short bio / tagline
     .he-contact   the Call / Text / Email row (.he-cbtn)
     .he-quote     the Request-a-Quote CTA

   Only the .he-* class on .he-hero changes between looks, so a page hero swaps
   its whole arrangement by class alone — same discipline as footer_layouts.css.

   All color comes from the --he-* role variables (set on a wrapping canvas),
   via color-mix, so a hero recolors automatically when the palette swaps:

     --he-bg / --he-ink / --he-ink-rgb   page background + text
     --he-primary / --he-on-primary      brand color + text on it
     --he-accent / --he-on-accent        secondary color + text on it
     --he-support                        tertiary / supporting color
     --he-hf / --he-bf / --he-tw         heading font / body font / heading weight
     --he-radius                         button corner radius (from the template)

   The background PATTERN (.hep-*) and the GLOW (.glow-on) live on the canvas
   (.he-canvas), independent of the item layout — a scoped subset of the
   header-backgrounds set, so any layout composes with any backdrop.

   --he-boost scales every pattern alpha per scheme: 1 on dark palettes, ~1.8 on
   light ones. Set alongside the palette variables so it swaps with the scheme.

   The lab page chrome lives in hero_sections.css; this module is meant to be
   reused on the live vendor page later (same split as footer_layouts.css).

   TYPE: Zulli Typography Kit v1.0, section 06 level 1 (the page stack). The
   hero carries the one display-level heading on the page, so it is the only
   block allowed above --type-display-m:
     eyebrow  --section-eyebrow  mono 500, +0.14em, muted (was bold sans, brand)
     name     --type-display-l   30-40px, was 30-46px; the deliberately loud
                                 layouts step up to --type-display-xl (56)
     pills    --type-label       mono 12
     bio      --type-body        15px
     contact  --btn-sm/--btn-md  500, not 600
     quote    --btn-lg           15.5/600
   Every step below the name is fixed px; only display-level type scales. */

/* ---- canvas (holds palette vars, background pattern + glow) ---- */
.he-canvas {
  --he-pad-y: clamp(26px, 6cqi, 46px);
  --he-pad-x: clamp(22px, 6cqi, 44px);
  position: relative;
  background-color: var(--he-bg);
  background-image: var(--he-pattern, none);
  background-size: var(--he-pattern-size, auto);
  color: var(--he-ink);
  font-family: var(--he-bf);
  padding: var(--he-pad-y) var(--he-pad-x);
  min-height: 360px;
  display: flex;
  align-items: stretch;
}

.he-canvas.glow-on {
  background-image:
    radial-gradient(120% 80% at 12% -8%, color-mix(in srgb, var(--he-primary) 22%, transparent) 0%, transparent 52%),
    radial-gradient(120% 85% at 108% 112%, color-mix(in srgb, var(--he-accent) 16%, transparent) 0%, transparent 50%),
    var(--he-pattern, none);
  background-size: cover, cover, var(--he-pattern-size, auto);
}

/* ---- background patterns (scoped subset of the header-backgrounds set) ---- */
.hep-plain { --he-pattern: none; --he-pattern-size: auto; }
.hep-dots {
  --he-pattern: radial-gradient(color-mix(in srgb, var(--he-primary) calc(12% * var(--he-boost, 1)), transparent) 1.5px, transparent 1.6px);
  --he-pattern-size: 18px 18px;
}
.hep-grid {
  --he-pattern:
    linear-gradient(color-mix(in srgb, var(--he-ink) calc(6% * var(--he-boost, 1)), transparent) 1px, transparent 1px),
    linear-gradient(90deg, color-mix(in srgb, var(--he-ink) calc(6% * var(--he-boost, 1)), transparent) 1px, transparent 1px);
  --he-pattern-size: 22px 22px, 22px 22px;
}
.hep-diagonal {
  --he-pattern: repeating-linear-gradient(45deg,
    color-mix(in srgb, var(--he-primary) calc(9% * var(--he-boost, 1)), transparent) 0 1px, transparent 1px 13px);
  --he-pattern-size: auto;
}
.hep-rings {
  --he-pattern: repeating-radial-gradient(circle at 50% -30%,
    color-mix(in srgb, var(--he-primary) calc(10% * var(--he-boost, 1)), transparent) 0 1px, transparent 1px 46px);
  --he-pattern-size: auto;
}
.hep-mesh {
  --he-pattern:
    radial-gradient(90% 70% at 8% -5%, color-mix(in srgb, var(--he-primary) calc(16% * var(--he-boost, 1)), transparent) 0%, transparent 55%),
    radial-gradient(85% 75% at 105% 20%, color-mix(in srgb, var(--he-accent) calc(12% * var(--he-boost, 1)), transparent) 0%, transparent 55%),
    radial-gradient(100% 80% at 50% 115%, color-mix(in srgb, var(--he-support) calc(10% * var(--he-boost, 1)), transparent) 0%, transparent 60%);
  --he-pattern-size: cover, cover, cover;
}
.hep-spotlight {
  --he-pattern: radial-gradient(130% 90% at 50% -12%,
    color-mix(in srgb, var(--he-primary) calc(18% * var(--he-boost, 1)), transparent) 0%, transparent 55%);
  --he-pattern-size: cover;
}

/* ---- base hero + items ---- */
.he-hero {
  width: 100%;
  display: flex; flex-direction: column; justify-content: center;
  font-family: var(--he-bf);
  text-align: left;
}

/* --section-eyebrow, muted per the kit's eyebrow rule — matches the section
   heads below it (section_title_layouts.css). */
.he-eyebrow {
  font-family: var(--he-mf, ui-monospace, monospace);
  font-size: clamp(10.5px, 2.6cqi, 12px); line-height: 1.2; font-weight: 500; text-transform: uppercase;
  letter-spacing: var(--track-eyebrow, 0.14em); margin: 0 0 var(--stack-eb-gap, clamp(8px, 1vw, 12px));
  color: var(--he-muted, color-mix(in srgb, var(--he-ink) 58%, transparent));
}
/* --type-display-l. 46px was between the kit's 40 and 56 steps. Chose the
   smaller one: it keeps a clean 40/32 step down to the section heads, and the
   brief here was that the page reads too large. The loud layouts below
   (editorial, magazine) take --type-display-xl
   instead — swap this to clamp(30px, 7.6cqi, 56px) if the default hero should
   be louder too. */
.he-name {
  font-family: var(--he-hf); font-weight: var(--he-tw);
  font-size: clamp(30px, 6cqi, 40px); line-height: 1.12; letter-spacing: var(--track-display-l, -0.02em);
  margin: 0 0 var(--stack-sh-gap, clamp(7px, .9vw, 10px)); color: var(--he-ink); word-break: break-word;
}
.he-pills { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 18px; }
.he-pill {
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 11px 5px 9px;
  border-radius: 999px; font-family: var(--he-mf, ui-monospace, monospace);
  font-size: 12px; line-height: 1.2; font-weight: 500; letter-spacing: var(--track-label, .08em);
  text-transform: uppercase; white-space: nowrap;
  background: color-mix(in srgb, var(--he-ink) 7%, transparent); color: var(--he-ink);
}
.he-pill svg { width: var(--icon-inline, 1.15em); height: var(--icon-inline, 1.15em); flex-shrink: 0; color: var(--he-primary-text, var(--he-primary)); }
/* --type-body */
.he-bio {
  font-size: 15px; line-height: 1.6; margin: 0 0 var(--space-md, clamp(16px, 2vw, 24px));
  /* --he-muted like the other secondary text in this file, not a fixed fade:
     72% put 16 of the 72 palettes under AA (worst 2.90:1) on the page's most
     prominent body copy. */
  color: var(--he-muted, color-mix(in srgb, var(--he-ink) 72%, transparent)); max-width: 48ch;
  /* no one-word last lines ("...take home that / night.") — older browsers
     ignore this and keep greedy wrapping */
  text-wrap: pretty;
}

/* Contact row — Call / Text / Email. Coloring follows the design-template
   convention (_contact_vars in style_templates.py), so the live page and the
   design lab render the same button. The treatment is set as .contact-<fill> on
   .page from Agent.contact_fill_class and draws entirely from the palette — the
   heading font has no say, so choosing a palette colors these and choosing a
   font never does. This base is the same 18% tint .contact-tint paints, so a
   blank "Auto" renders identically whether or not the class lands.
   All stay lighter than the .he-quote CTA so it still leads. */
.he-contact { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin: 0 0 12px; }
.he-cbtn {
  display: flex; align-items: center; justify-content: center; gap: 7px;
  /* --btn-md height at --btn-sm's 13px label: three buttons share one row, so
     the label steps down while the target stays full size. 600 -> 500 per the
     kit's "500 is for UI affordances". */
  min-height: var(--btn-h-md, clamp(40px, 4.4vw, 44px));
  padding: 8px var(--btn-px-sm, clamp(10px, 1.2vw, 14px)); font: inherit;
  font-size: 13px; line-height: 1.2; font-weight: 500;
  letter-spacing: 0.01em; text-decoration: none; cursor: default;
  /* Declared but transparent: a filled button carrying a rule in its own hue
     just reads as a muddy edge, so only .contact-outline paints it. Keeping the
     1.5px reserved here means every fill renders at the same height, so
     switching Button fill can't shift the hero's layout. */
  border: 1.5px solid transparent;
  border-radius: var(--he-radius, 12px);
  background: var(--he-tint, color-mix(in srgb, var(--he-primary) 18%, transparent));
  color: var(--he-contact-ink, var(--he-ink));
}
/* Icon tracks the label rather than the brand: on a pale-brand palette a
   primary-colored glyph washes out on its own tint, the same way the label
   would. */
/* Inline beside the Call/Text/Email label — em, per the kit. */
.he-cbtn svg { width: var(--icon-inline, 1.15em); height: var(--icon-inline, 1.15em); flex-shrink: 0; color: currentColor; }
/* Tint — the brand washed over the page at whatever strength that palette needs
   to stay visible (--he-tint, resolved in _contact_tint_fill). Identical to the
   base above, so a blank "Auto" renders the same whether or not the class lands. */
.contact-tint .he-cbtn {
  background: var(--he-tint, color-mix(in srgb, var(--he-primary) 18%, transparent));
  color: var(--he-contact-ink, var(--he-ink));
}
/* Ink — a solid ink block with a paper-colored label. Was the mono-font vibe. */
.contact-ink .he-cbtn {
  background: var(--he-ink); color: var(--he-bg);
}
/* Outline — palette-driven: transparent fill, the brand carries the border/
   label. The only treatment that paints the 1.5px border .he-cbtn reserves. */
.contact-outline .he-cbtn {
  background: transparent; border-color: var(--he-primary);
  color: var(--he-primary-text, var(--he-primary));
}
/* Solid — palette-driven: the brand as a full fill, its on-primary role for
   the label so it stays readable regardless of how dark/light the brand is. */
.contact-solid .he-cbtn {
  background: var(--he-primary-fill, var(--he-primary)); color: var(--he-on-primary);
}
/* Accent — same shape as Solid, using the accent role instead of primary, for
   palettes where the accent reads better on a button than the brand itself. */
.contact-accent .he-cbtn {
  background: var(--he-accent); color: var(--he-on-accent);
}
/* -light/-dark pairs — literal white/near-black, deliberately ignoring the
   palette (see CONTACT_FILL_CHOICES in models.py): for a header background
   photo where the theme's own colors may not read against an arbitrary image. */
.contact-outline-light .he-cbtn { background: transparent; border-color: #fff; color: #fff; }
.contact-outline-dark .he-cbtn { background: transparent; border-color: #111111; color: #111111; }
.contact-solid-light .he-cbtn { background: #fff; color: #111111; }
.contact-solid-dark .he-cbtn { background: #111111; color: #fff; }

/* Request-a-Quote CTA — the primary conversion button. */
.he-quote {
  display: flex; align-items: center; justify-content: center; gap: 9px;
  /* --btn-lg — the one primary CTA on the page. Body face, not the display
     face: the kit keeps display type off buttons. */
  min-height: var(--btn-h-lg, clamp(48px, 5.2vw, 54px));
  padding: 8px var(--btn-px-lg, clamp(20px, 2.6vw, 30px));
  font-family: var(--he-bf); font-size: 15.5px; line-height: 1.2; font-weight: 600;
  text-decoration: none; cursor: default;
  background: var(--he-primary-fill, var(--he-primary)); color: var(--he-on-primary); border-radius: var(--he-radius, 12px);
}
.he-quote svg { width: var(--icon-inline, 1.15em); height: var(--icon-inline, 1.15em); }

/* ============================================================
   LAYOUT TYPES — each arranges the SAME hero items a different way.
   ============================================================ */

/* Centered — every element centered. */
.he-center { text-align: center; align-items: center; }
.he-center .he-pills, .he-center .he-contact { justify-content: center; }
.he-center .he-bio { max-width: 52ch; }
.he-center .he-quote { align-self: center; min-width: 260px; }

/* Editorial — centered, serif-forward: eyebrow with flanking rules, big name,
   no contact grid (the CTA carries it), generous spacing. */
.he-editorial { text-align: center; align-items: center; gap: 2px; }
.he-editorial .he-eyebrow {
  display: flex; align-items: center; gap: 12px; letter-spacing: 0.24em;
}
.he-editorial .he-eyebrow::before, .he-editorial .he-eyebrow::after {
  content: ""; height: 1px; width: clamp(24px, 8cqi, 56px);
  background: color-mix(in srgb, var(--he-primary) 55%, transparent);
}
/* --type-display-xl — the loud layouts. Same step for all five so they read
   as one tier rather than five improvised sizes (was 48/50/52/52/54). */
.he-editorial .he-name { font-size: clamp(34px, 8cqi, 56px); margin-bottom: var(--space-sm, clamp(12px,1.4vw,16px)); }
.he-editorial .he-pills { justify-content: center; }
.he-editorial .he-bio { max-width: 50ch; }
.he-editorial .he-contact { display: none; }
.he-editorial .he-quote { align-self: center; min-width: 240px; }

/* Badge Eyebrow — the eyebrow rendered as a filled pill badge; centered. */
.he-badge-pills { text-align: center; align-items: center; }
.he-badge-pills .he-eyebrow {
  display: inline-block; padding: 5px 14px; border-radius: 999px; margin-bottom: 14px;
  background: color-mix(in srgb, var(--he-primary) 14%, transparent); color: var(--he-primary-text, var(--he-primary));
  letter-spacing: 0.1em;
}
.he-badge-pills .he-pills, .he-badge-pills .he-contact { justify-content: center; }

/* Compact — smaller name, pills inline right of the eyebrow, tight spacing,
   inline contact + CTA row. */
/* Compact steps down to --type-display-m rather than off the scale. */
.he-compact .he-name { font-size: clamp(26px, 4.4cqi, 32px); margin-bottom: 10px; }
.he-compact .he-pills { margin-bottom: 14px; }
.he-compact .he-bio { margin-bottom: 16px; }
.he-compact .he-contact {
  display: flex; flex-wrap: wrap; gap: 8px;
}
.he-compact .he-cbtn { padding: 8px 14px; }
.he-compact .he-quote { align-self: flex-start; padding: 12px 22px; }

/* Action Rail — content left; contact + CTA collected into a right-aligned
   narrow rail. */
.he-left-rail { display: grid; grid-template-columns: 1fr auto; gap: clamp(16px, 5cqi, 32px);
  align-items: center; }
.he-left-rail .he-eyebrow, .he-left-rail .he-name, .he-left-rail .he-pills, .he-left-rail .he-bio {
  grid-column: 1;
}
.he-left-rail .he-bio { margin-bottom: 0; }
.he-left-rail .he-contact {
  grid-column: 2; grid-row: 1 / span 4; grid-template-columns: 1fr;
  align-self: center; margin: 0; min-width: 150px;
}
.he-left-rail .he-quote { grid-column: 2; align-self: center; }
@container (max-width: 380px) {
  .he-left-rail { grid-template-columns: 1fr; }
  .he-left-rail > * { grid-column: 1 !important; grid-row: auto !important; }
  .he-left-rail .he-contact { grid-template-columns: repeat(3, 1fr); }
}

/* Framed Card — the whole hero inside a soft bordered, tinted panel. */
.he-framed {
  border: 1px solid color-mix(in srgb, var(--he-ink) 14%, transparent);
  border-radius: 18px; padding: clamp(20px, 5cqi, 32px);
  background: color-mix(in srgb, var(--he-ink) 3%, transparent);
}

/* Accent Overline — a thick accent rule across the top, then the left stack. */
.he-overline { border-top: 4px solid var(--he-accent); padding-top: 22px; }

/* Masthead — editorial masthead: hairline rules top & bottom around a big
   centered name, pills + bio centered, quote centered, no contact grid. */
.he-magazine {
  text-align: center; align-items: center;
  border-top: 1px solid color-mix(in srgb, var(--he-ink) 20%, transparent);
  border-bottom: 1px solid color-mix(in srgb, var(--he-ink) 20%, transparent);
  padding: clamp(18px, 5cqi, 30px) 0;
}
.he-magazine .he-eyebrow { letter-spacing: 0.28em; }
.he-magazine .he-name { font-size: clamp(34px, 8cqi, 56px); letter-spacing: 0.01em; }
.he-magazine .he-pills { justify-content: center; }
.he-magazine .he-bio { max-width: 50ch; }
.he-magazine .he-contact { display: none; }
.he-magazine .he-quote { align-self: center; min-width: 240px; }

/* Ticket Stub — the hero reads as an event ticket: a dashed perimeter with
   two punched notches at mid-height (a filled circle in the canvas color
   erasing a gap in the dashed line), a monospace "barcode" eyebrow, and a
   dashed tear line under the meta pills separating the ticket header from
   the body/CTA stub. Leans into the event-vendor product. */
.he-ticket { position: relative; border: 2px dashed color-mix(in srgb, var(--he-ink) 26%, transparent);
  border-radius: 16px; padding: clamp(22px, 5cqi, 34px); }
.he-ticket::before, .he-ticket::after {
  content: ""; position: absolute; top: 50%; width: 22px; height: 22px; border-radius: 50%;
  background: var(--he-bg); transform: translateY(-50%); z-index: 1;
}
.he-ticket::before { left: -12px; }
.he-ticket::after { right: -12px; }
/* Already mono by hand; now through the theme var like every other eyebrow. */
.he-ticket .he-eyebrow { font-family: var(--he-mf, ui-monospace, monospace); letter-spacing: 0.2em; }
.he-ticket .he-pills { padding-bottom: 16px; margin-bottom: 20px;
  border-bottom: 1.5px dashed color-mix(in srgb, var(--he-ink) 26%, transparent); }
.he-ticket .he-quote { align-self: flex-start; min-width: 220px; }

/* ============================================================
   ALIGNMENT OVERRIDE — one control (he-align-*) that sets which way the hero
   items sit, across EVERY layout. Placed after all the layout type rules so
   `.he-hero.he-align-*` wins over a layout's own baked-in alignment by source
   order.

   IMPORTANT: alignment only moves TEXT and the auto-width flex rows (pills /
   contacts / availability / socials); it deliberately does NOT set `align-items`
   on the hero, because that would collapse the full-width elements — the
   Request-a-Quote CTA and the Call/Text/Email grid — down to their content
   width, so the CTA's width would change with alignment (and mismatch the
   picker samples, which carry no align class). Keeping the hero's default
   `align-items: stretch` means the CTA and contact row stay full-width in every
   alignment; only their inner label position (via each button's own centered
   flex) is affected. The constrained bio block is re-anchored with margins so a
   centered/right alignment still reads right.
   ============================================================ */
.he-hero.he-align-left   { text-align: left; }
.he-hero.he-align-center { text-align: center; }
.he-hero.he-align-right  { text-align: right; }

.he-align-left .he-pills, .he-align-left .he-socials { justify-content: flex-start; }
.he-align-center .he-pills, .he-align-center .he-socials { justify-content: center; }
.he-align-right .he-pills, .he-align-right .he-socials { justify-content: flex-end; }

/* Re-anchor the width-capped bio so it follows the chosen side instead of
   always hugging the left edge. */
.he-align-center .he-bio { margin-left: auto; margin-right: auto; }
.he-align-right .he-bio { margin-left: auto; margin-right: 0; }

/* Social icons row — reused on the live page under the hero (not part of the
   gallery specimen). Styled here so it recolors with the --he-* palette and
   follows the alignment override above.
   Base state IS .contact-tint's own formula (same --he-tint wash, same
   --he-contact-ink label color the Call/Text/Email row uses for Tint) rather
   than an invented neutral gray — Button fill's Auto/Tint should look like
   the same design decision in both places, not two different "default"
   treatments that happen to share a name. Border is reserved transparent at
   full width, same trick as .he-cbtn below: every fill renders at the same
   size, so switching Button fill can't shift the row's layout. */
.he-socials { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 16px; }
.he-socials .social-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 38px; height: 38px; border-radius: 999px;
  border: 1.5px solid transparent;
  background: var(--he-tint, color-mix(in srgb, var(--he-primary) 18%, transparent));
  color: var(--he-contact-ink, var(--he-ink));
  transition: background .15s ease, border-color .15s ease, color .15s ease, transform .15s ease;
}
/* Lift only — .he-cbtn has no hover treatment at all, and recoloring on
   hover here would fight whichever fill the vendor actually chose (a Solid
   icon flashing back to a translucent wash on hover, say). */
.he-socials .social-icon:hover { transform: translateY(-1px); }
/* Standalone social glyphs — icon scale, not em. */
.he-socials .social-icon svg { width: var(--icon-md, 18px); height: var(--icon-md, 18px); fill: currentColor; }

/* Button fill for social icons — the exact same treatment/values as
   .contact-<fill>/.he-cbtn above (Agent.social_fill, CONTACT_FILL_CHOICES
   reused), applied to .social-icon instead. .social-tint restates the base
   above (so a blank Auto renders identically whether or not the class
   lands, same contract as .contact-tint). Scoped to .he-socials only, not
   the nav overlay's own .vnav-social row: the --he-* vars this reads are
   inlined on .vhero-body (hero_he_style, see header.html), and
   .vnav-overlay is that element's SIBLING, not its descendant, so these
   vars would resolve to undefined there. Matches contact_fill's own real
   scope — the Call/Text/Email row never had a nav-overlay duplicate either. */
.social-tint .he-socials .social-icon {
  background: var(--he-tint, color-mix(in srgb, var(--he-primary) 18%, transparent));
  color: var(--he-contact-ink, var(--he-ink));
}
.social-ink .he-socials .social-icon { background: var(--he-ink); color: var(--he-bg); }
.social-outline .he-socials .social-icon {
  background: transparent; border-color: var(--he-primary); color: var(--he-primary-text, var(--he-primary));
}
.social-solid .he-socials .social-icon { background: var(--he-primary-fill, var(--he-primary)); color: var(--he-on-primary); }
.social-accent .he-socials .social-icon { background: var(--he-accent); color: var(--he-on-accent); }
.social-outline-light .he-socials .social-icon { background: transparent; border-color: #fff; color: #fff; }
.social-outline-dark .he-socials .social-icon { background: transparent; border-color: #111111; color: #111111; }
.social-solid-light .he-socials .social-icon { background: #fff; color: #111111; }
.social-solid-dark .he-socials .social-icon { background: #111111; color: #fff; }
