/*
 * elfrique.components.layout.css — Layout primitives
 * Mandate: M02 · C2 Component Kit · Phase 1
 *
 * Scope: PageHeader, StatStrip, Hero, Media, ContentCard, Rail.
 * Siblings: elfrique.components.sidebar.css · elfrique.components.data.css
 *           elfrique.components.overlay.css
 *
 * All styles in this file MUST consume tokens from elfrique.css via var(--token).
 * No raw hex. No raw ms. No Bootstrap class names.
 *
 * Caps: ≤ 1,000 lines hard / ≤ 800 lines soft. Aggregate (3 files) ≤ 3,000.
 * Populated by: Phase 1 (Hero, PageHeader, StatStrip); Phase 5 additions
 * (Media, ContentCard, Rail) land here as well.
 */


/* ==========================================================================
   PAGE HEADER
   Breadcrumb + H1 + subtext + action slot.
   Source: Views/Shared/Kit/_PageHeader.cshtml · Model: PageHeaderModel.
   ========================================================================== */

.page-header {
  display:         flex;
  flex-direction:  column;
  gap:             var(--sp-3);
  padding:         var(--sp-5) 0 var(--sp-4);
  border-bottom:   1px solid var(--n-200);
  font-family:     var(--font-sans);
  color:           var(--brand-ink);
}

.page-header__crumbs {
  font-size: var(--fs-1);
  color:     var(--n-500);
}

.page-header__crumb-list {
  display:          flex;
  flex-wrap:        wrap;
  align-items:      center;
  gap:              var(--sp-1);
  margin:           0;
  padding:          0;
  list-style:       none;
  font-family:      var(--font-mono);
  text-transform:   uppercase;
  letter-spacing:   0.04em;
}

.page-header__crumb {
  display:     inline-flex;
  align-items: center;
  gap:         var(--sp-1);
}

.page-header__crumb-link {
  color:            var(--n-600);
  text-decoration:  none;
  padding:          var(--sp-1) 0;
  min-height:       44px;
  display:          inline-flex;
  align-items:      center;
  transition:       color var(--d-1) var(--ease-out-swift);
}

.page-header__crumb-link:hover {
  color:            var(--brand-ink);
  text-decoration:  underline;
  text-underline-offset: 3px;
}

.page-header__crumb-link:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
  border-radius:  var(--r-1);
}

.page-header__crumb--current {
  color:        var(--brand-ink);
  font-weight:  600;
}

.page-header__crumb-sep {
  color: var(--n-300);
}

.page-header__bar {
  display:         flex;
  flex-wrap:       wrap;
  align-items:     flex-start;
  justify-content: space-between;
  gap:             var(--sp-4);
}

.page-header__titleblock {
  flex:        1 1 24rem;
  min-width:   0;
  display:     flex;
  flex-direction: column;
  gap:         var(--sp-2);
}

.page-header__title {
  margin:       0;
  font-family:  var(--font-serif);
  font-size:    var(--fs-6);
  font-weight:  600;
  line-height:  1.15;
  color:        var(--brand-ink);
  letter-spacing: -0.01em;
}

.page-header__subtext {
  margin:     0;
  font-size:  var(--fs-3);
  line-height: 1.55;
  color:      var(--n-600);
  max-width:  48rem;
}

.page-header__actions {
  display:      inline-flex;
  flex-wrap:    wrap;
  align-items:  center;
  gap:          var(--sp-2);
  flex:         0 0 auto;
}

@media (max-width: 640px) {
  .page-header__bar {
    flex-direction: column;
    align-items:    stretch;
  }

  .page-header__actions {
    justify-content: flex-start;
  }
}

@media (prefers-reduced-motion: reduce) {
  .page-header__crumb-link {
    transition: none;
  }
}


/* ==========================================================================
   STAT STRIP
   Horizontal strip of 3–5 metric cells with optional delta chip.
   Source: Views/Shared/Kit/_StatStrip.cshtml · Model: StatStripModel.
   ========================================================================== */

.stat-strip {
  font-family: var(--font-sans);
  color:       var(--brand-ink);
}

.stat-strip__list {
  display:              grid;
  grid-template-columns: repeat(auto-fit, minmax(12rem, 1fr));
  gap:                  var(--sp-4);
  margin:               0;
  padding:              0;
  list-style:           none;
}

.stat-cell {
  display:          flex;
  flex-direction:   column;
  gap:              var(--sp-2);
  padding:          var(--sp-4);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  box-shadow:       var(--shadow-1);
  transition:       box-shadow var(--d-2) var(--ease-out-swift),
                    border-color var(--d-2) var(--ease-out-swift);
}

.stat-cell:hover {
  box-shadow:    var(--shadow-2);
  border-color:  var(--n-300);
}

.stat-cell__label {
  margin:         0;
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color:          var(--n-500);
  font-weight:    500;
}

.stat-cell__body {
  margin:      0;
  display:     flex;
  flex-wrap:   wrap;
  align-items: baseline;
  gap:         var(--sp-2);
}

.stat-cell__value {
  font-family:    var(--font-serif);
  font-size:      var(--fs-5);
  font-weight:    600;
  line-height:    1.1;
  color:          var(--brand-ink);
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
}

.stat-cell__delta {
  display:         inline-flex;
  align-items:     center;
  gap:             var(--sp-1);
  padding:         var(--sp-1) var(--sp-2);
  border-radius:   var(--r-5);
  font-family:     var(--font-mono);
  font-size:       var(--fs-1);
  font-weight:     500;
  line-height:     1;
  letter-spacing:  0.02em;
  white-space:     nowrap;
}

.stat-cell__delta--up {
  color:            var(--state-success);
  background-color: color-mix(in srgb, var(--state-success) 12%, transparent);
}

.stat-cell__delta--down {
  color:            var(--state-danger);
  background-color: color-mix(in srgb, var(--state-danger) 12%, transparent);
}

.stat-cell__delta--flat {
  color:            var(--n-600);
  background-color: var(--n-100);
}

.stat-cell__delta-arrow {
  font-size:   var(--fs-2);
  line-height: 1;
}

@media (prefers-reduced-motion: reduce) {
  .stat-cell {
    transition: none;
  }
}


/* ==========================================================================
   HERO
   Editorial 12-col: eyebrow, serif headline w/ italic accent, subcopy,
   search slot, trust row, full-bleed image. --sm is the default (detail
   pages); --xl escalates to full-bleed (Home only).
   Source: Views/Shared/Kit/_Hero.cshtml · Model: HeroModel.
   ========================================================================== */

/* Base ships with --sm defaults. --xl overrides where it diverges. */
.hero {
  position:         relative;
  width:            100%;
  font-family:      var(--font-sans);
  color:            var(--n-0);
  /* M28 Phase 3 — A+H3 cascade: deeper canvas + white text. Replaces M23 Phase 4 soft-ink surface. */
  background-color: var(--hero-canvas);
  overflow:         hidden;
}

/* M32 Phase 7 fix-cycle 1 D5 — relax the hero clip when the hero contains a
   search slot. Search popovers / autocomplete dropdowns positioned outside the
   hero box need overflow: visible on the section to render past the hero
   bottom edge. Scoped via the .hero--has-search modifier (emitted by
   _Hero.cshtml when SearchSlot is present), so heroes without search keep the
   default clip. .hero__media retains its own overflow: hidden, so image
   clipping is preserved regardless. */
.hero--has-search { overflow: visible; }

.hero__grid {
  display:               grid;
  grid-template-columns: repeat(12, 1fr);
  gap:                   var(--sp-4);
  width:                 100%;
  max-width:             1280px;
  margin:                0 auto;
  padding:               var(--sp-5);
  align-items:           center;
}

.hero__content {
  grid-column:    1 / -1;
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-4);
  min-width:      0;
}

.hero__eyebrow {
  margin:         0;
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color:          var(--n-0);
  font-weight:    500;
}

.hero__headline {
  margin:         0;
  font-family:    var(--font-serif);
  font-size:      var(--fs-5);
  font-weight:    600;
  line-height:    1.08;
  letter-spacing: -0.02em;
  color:          var(--n-0);
  text-wrap:      balance;
}

.hero__headline-accent {
  font-style:  italic;
  font-weight: 500;
  color:       var(--brand-spark);
}

.hero__subcopy {
  margin:      0;
  font-size:   var(--fs-4);
  line-height: 1.55;
  color:       color-mix(in srgb, var(--n-0) 92%, transparent);
  max-width:   40rem;
}

.hero__search {
  /* M32 Phase 6 (N9) — anchor for the AJAX dropdown panel. The kit's
     [data-search-results] panel uses `position: absolute; top: 100%`
     and otherwise resolves against the nearest positioned ancestor;
     `.hero` itself sets `overflow: hidden` (line 265-273), so without
     a closer positioned anchor the panel was rendering INSIDE the
     hero clipping rect and being visually hidden. All three consumers
     (Home / EventsBrowse / VotingContestsBrowse) share this class. */
  position:  relative;
  display:   block;
  width:     100%;
  max-width: 36rem;
}

/* M23 Phase 5 C5 — BelowContentSlot: Voting detail consolidates countdown +
   share block into the hero composition via Model.BelowContentSlot.
   Centered stack matches the .hero--centered layout default. */
.hero__below-content {
  margin-block-start: var(--sp-4);
  display:            flex;
  flex-direction:     column;
  gap:                var(--sp-3);
  align-items:        center;
}

.hero__trust {
  display:     flex;
  flex-wrap:   wrap;
  align-items: center;
  gap:         var(--sp-4);
  margin:      0;
  padding:     var(--sp-3) 0 0;
  list-style:  none;
  border-top:  1px solid color-mix(in srgb, var(--n-0) 18%, transparent);
}

.hero__trust-item {
  display:        inline-flex;
  align-items:    center;
  gap:            var(--sp-2);
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color:          color-mix(in srgb, var(--n-0) 88%, transparent);
}

.hero__trust-icon {
  display: inline-flex;
  width:   1rem;
  height:  1rem;
  color:   var(--n-0);
}

/* Stacked trust list — items render in a vertical stack with icons
   left-aligned at the same x-position, so all metrics are symmetrically
   aligned. Used by Public/ContestantDetail.cshtml so the votes / share /
   rank metrics each sit on their own row instead of running together
   on a single line. The icon column is fixed at 1rem (matches
   .hero__trust-icon width above), and the .hero__trust-item already
   declares display:inline-flex + gap:var(--sp-2), so the fixed icon
   size + uniform gap delivers the vertical symmetry — no additional
   declarations needed on the inner items. */
.hero__trust--stacked {
  flex-direction: column;
  align-items:    flex-start;
  gap:            var(--sp-2);
}

.hero__media {
  grid-column:      1 / -1;
  position:         relative;
  overflow:         hidden;
  border-radius:    var(--r-4);
  aspect-ratio:     21 / 9;
  background-color: var(--n-100);
}

/* M23 Phase 5 C4 — Voting detail hero image 50% height reduction.
   Doubles aspect-ratio width vs. base 21/9 (from .hero__media above) since
   no --hero-image-h-* token exists for max-height-based override. Page-level
   wrapper applied via <div class="contest-hero-cover"> around the _Hero
   invocation in VotingContest.cshtml; aspect-ratio is not covered by HR2/HR3
   per the existing 21/9 precedent in the base rule. */
.contest-hero-cover .hero__media {
  aspect-ratio: 42 / 9;
}

/* M31 Phase 2a F-2a-1 — Voting hero cover image: anchor portrait subjects.
   The doubled 42/9 aspect-ratio above creates an extreme letterbox window;
   the browser default object-position (50% 50%) crops faces at top/bottom of
   typical cover photos. Bias toward the upper third (50% 30%) so subjects'
   faces sit within frame. Scoped to .contest-hero-cover; card surfaces use
   .media--portrait (4/5 aspect) and are handled separately in Phase 2b. */
.contest-hero-cover .hero__image {
  object-position: 50% 30%;
}

/* M30 Phase 4 F-4-1 — Voting hero: left-align BelowContentSlot content
   (countdown + share + meta bar). The base .hero__below-content uses
   align-items: center (centered layout default). Scoped to .contest-hero-cover
   so no other BelowContentSlot consumers are affected. */
.contest-hero-cover .hero__below-content {
  align-items: flex-start;
}

/* M30 Phase 4 F-4-1 — Trust items (Candidates + price-per-vote) rendered inline:
   icon + value + label all on one row. The base .hero__trust-pair stacks value
   above label (column flex). Override to row within the voting contest hero only. */
.contest-hero-cover .hero__trust-pair {
  flex-direction: row;
  align-items:    center;
  gap:            var(--sp-1);
}

/* M32 Phase 7 fix-cycle 1 D2 — optical alignment of mixed-font-size trust text
   with the icon. Tighten value/label line-boxes to font height so the geometric
   centre of "Candidates" / "12,345" / "per vote" / "Total Votes" lands on the
   icon's vertical centre. None of the labels in this set have descenders, so
   line-height: 1 is safe. Scoped to .contest-hero-cover to avoid disturbing
   other hero consumers (Home, Events) where trust-pair stacks vertically. */
.contest-hero-cover .hero__trust-value,
.contest-hero-cover .hero__trust-label { line-height: 1; }

/* M32 Phase 7 fix-cycle 1 D3 — composition row separators inside the voting
   contest hero. The BelowContentSlot stacks countdown, share, and meta-strip
   rows; without separators the rows visually merge against the dark hero canvas.
   color-mix on --n-0 with 12% alpha yields a subtle hairline that reads on the
   dark green canvas (var(--hero-canvas)). Scoped to .contest-hero-cover so
   no other BelowContentSlot consumers are affected. */
.contest-hero-cover .hero__below-content { gap: var(--sp-4); }
.contest-hero-cover .hero__below-content > * + * {
  padding-top: var(--sp-4);
  border-top: 1px solid color-mix(in oklab, var(--n-0) 12%, transparent);
}

/* M30 Phase 4 F-4-2 — Reset .contest-meta-strip container styling when it renders
   inside .hero__below-content (via _VotingHeroBelowSlot.cshtml). The standalone
   .contest-meta-strip section had its own background + padding for use outside the
   hero; inside the hero the BelowContentSlot already provides spacing and the hero
   canvas supplies the dark background.
   Padding-top intentionally NOT reset: the .contest-hero-cover .hero__below-content
   > * + * rhythm rule above sets padding-top: --sp-4 to provide breathing room
   between the hairline divider and the LIVE / Verified / Category pill row.
   A blanket `padding: 0` reset here would override that (specificity tie, later
   source order wins) and collapse the pills against the divider. */
.hero__below-content .contest-meta-strip {
  background: none;
  padding-bottom: 0;
  padding-inline: 0;
  color:      inherit;
}

/* M30 Phase 4 F-4-2 — Remove the container max-width wrapper added by the inner
   .container div within the merged meta-strip, so the content flows naturally
   inside the hero's own grid padding. */
.hero__below-content .contest-meta-strip .container {
  max-width: none;
  padding:   0;
}

/* ==========================================================================
   M31 Phase 3 — Cluster V (voting surfaces polish)
   ==========================================================================
   Rules below were promoted out of the inline <style asp-add-nonce> block in
   VotingContest.cshtml (formerly at L18-42, L595-596, L857-878 pre-promotion)
   and updated per F-3-3 (row spacing token), F-3-7 (countdown contrast),
   F-3-8 (meta-strip row consolidation), F-3-1 (share icons → ghost), F-3-2
   (QR passive). New rules for F-3-4 awards-category section treatment also
   land here (zero pre-existing CSS for those selectors). HR1 binding (no
   green); HR2 (token-only); HR3 (motion tokens only).
   ========================================================================== */

/* F-3-3 / F-3-8 — meta-strip layout. Promoted from VotingContest.cshtml inline
   <style>. Raw `gap: 16px` replaced with --sp-4 token (HR2). __badges row gains
   align-items: center (was already set; reaffirmed for icon alignment). */
.contest-meta-strip {
  padding: var(--sp-5) 0;
  background: var(--n-900);
  color: var(--n-0);
}
.contest-meta-strip .container {
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.contest-meta-strip__row {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.contest-meta-strip__stat {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-1);
}
.contest-meta-strip__stat strong {
  color: var(--n-0);
  font-weight: 700;
}
.hero__below-content .contest-meta-strip__stat strong {
  color: var(--brand-ink);
}
.contest-meta-strip__badges {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.contest-meta-strip__stats {
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  flex-wrap: wrap;
  font-size: var(--fs-1);
}
.contest-meta-strip__stats strong {
  color: var(--n-0);
  font-weight: 700;
}
.contest-meta-strip__stats .stat-dot {
  width: 4px;
  height: 4px;
  border-radius: 50%;
  background: var(--n-500);
}
.contest-meta-strip__countdown {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.contest-meta-strip__cta {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  /* M32 Phase 7 N8b — widen pills→CTA visual gap. Parent .contest-meta-strip
     .container is flex-column so margin-top does not collapse. --sp-6 chosen
     over --sp-8 for closer rhythm fidelity to surrounding rows. */
  margin-top: var(--sp-6);
}
/* F-3-7 / F-11-1 — countdown contrast. The hero canvas resolves to
   var(--hero-canvas) = #2A6047 (dark green) under .contest-hero-cover .hero
   composition, so the countdown digits/labels must use light tokens to read
   against the dark backdrop. Earlier promotion (M31 Phase 3) mistakenly
   tokenised onto --brand-ink for an assumed light below-content background;
   re-audit (Phase 11 F-11-0) confirmed the below-content is dark. Reverting
   to --n-0 family per the original .contest-meta-strip dark-bg treatment.
   HR2 binding (token-only, color-mix on --n-0 for the secondary tier).
   The standalone .contest-meta-strip block (which renders dark-on-dark
   in older surfaces) was always correct and remains untouched. */
.hero__below-content .countdown-label {
  color: var(--n-0);
}
.hero__below-content .countdown-box .cd-num {
  color: var(--n-0);
}
.hero__below-content .countdown-box .cd-label {
  color: color-mix(in oklab, var(--n-0) 80%, var(--n-900));
}
.hero__below-content .countdown-sep {
  color: color-mix(in oklab, var(--n-0) 80%, var(--n-900));
}

/* F-3-1 — share block + share icons (ghost / icon-only). Per-network background
   colors removed; buttons now share a token-aligned ghost treatment (transparent
   bg, --n-0 outlined ring, --n-0 icon color when on dark hero, --brand-ink on
   light backgrounds via the .hero__below-content cascade). HR1 binding — no
   green; --state-success was teal-coded so the prior wa rule was already HR1
   compliant; full removal is a stricter resolution still. Promoted from inline
   <style>. */
.share-block { /* outer composition holding heading + buttons + shortlink + qr */
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: var(--sp-2);
}
/* F-11-1 — share-block left-align modifier. Used by _VotingHeroBelowSlot.cshtml
   so the share composition follows the hero's left-aligned headline rhythm
   (set via .contest-hero-cover .hero__below-content { align-items: flex-start }
   at line 408). Prior version kept text-align:center which contradicted the
   container alignment — rule was effectively a no-op. */
.share-block.share-left {
  align-items: flex-start;
  text-align: left;
}
.share-block.share-left .share-buttons,
.share-block.share-left .share-composition {
  justify-content: flex-start;
}
.share-block h3 {
  font-size: var(--fs-2);
  font-weight: 700;
  color: var(--n-0);
  margin: 0;
  letter-spacing: 0.3px;
}
.share-block .share-subtext {
  font-size: var(--fs-0);
  color: color-mix(in oklab, var(--n-0) 75%, transparent);
  margin: 0;
}
.share-buttons {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  justify-content: center;
}
.share-btn {
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: transparent;
  border: 1px solid color-mix(in oklab, var(--n-0) 35%, transparent);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-2);
  color: var(--n-0);
  cursor: pointer;
  transition: border-color var(--d-1) var(--ease-out-swift),
              color var(--d-1) var(--ease-out-swift),
              background var(--d-1) var(--ease-out-swift),
              transform var(--d-1) var(--ease-out-swift);
}
.share-btn:hover,
.share-btn:focus-visible {
  border-color: var(--n-0);
  background: color-mix(in oklab, var(--n-0) 10%, transparent);
  transform: translateY(-1px);
}
.share-btn:focus-visible {
  outline: 2px solid var(--n-0);
  outline-offset: 2px;
}

/* M32 Phase 7 N6 — share-block on .hero__below-content renders against the
   dark hero canvas (--hero-canvas = #2A6047). Earlier --brand-ink tokenisation
   assumed a light below-content background and produced dark-on-dark; mirrors
   the M31 P11 CF-P11-3 countdown fix at lines 538–549. Swap to --n-0 family
   with color-mix on --n-0 for the secondary tier. HR1 / HR2 token-only. */
.hero__below-content .share-block h3 {
  color: var(--n-0);
}
.hero__below-content .share-block .share-subtext {
  color: color-mix(in oklab, var(--n-0) 80%, var(--n-900));
}
.hero__below-content .share-btn {
  border-color: color-mix(in oklab, var(--n-0) 40%, transparent);
  color: var(--n-0);
}
.hero__below-content .share-btn:hover,
.hero__below-content .share-btn:focus-visible {
  border-color: var(--n-0);
  background: color-mix(in oklab, var(--n-0) 10%, transparent);
}
.hero__below-content .share-btn:focus-visible {
  outline-color: var(--n-0);
}

/* F-3-2 — QR rendered passively beside the share icons. The toggle button +
   the qr-collapse hidden default were removed in this phase. The new
   composition is a flex row holding share-buttons + qr-passive + shortlink,
   centered V+H. QR image keeps token-aligned border-radius via class (HR4
   refactor — was inline style on the <img> at _VotingHeroBelowSlot.cshtml:83). */
.share-composition {
  display: flex;
  flex-direction: row-reverse;
  align-items: center;
  justify-content: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
}
.share-qr {
  display: block;
}
/* F-11-1 — QR sized to share-button height (44px) so the share-composition
   row reads as a single horizontal cluster: 5 share buttons + QR all at the
   same vertical extent. Prior 96px QR dwarfed the buttons and broke the
   side-by-side rhythm flagged in N29. The HTML still emits width/height=96
   attributes (width="96" height="96") as an intrinsic-size hint for layout
   stability before CSS lands; CSS dimensions win at paint time. QR remains
   scannable at 44px on hi-DPI displays since the underlying SVG/PNG is
   higher-resolution; if scan reliability becomes an issue we'll
   reintroduce a hover-zoom or tap-to-expand affordance. */
.share-qr__image {
  display: block;
  border-radius: var(--r-2);
  width: 100px;
  height: 100px;
}

/* F-3-4 — awards-category section treatment. CSS for these selectors did
   not exist anywhere in the kit until M31; ghost (b)+(c) hybrid per user
   pick: outer ghost block + serif section heading with brand-spark accent
   rule. HR1 binding (no green). */
.nominee-category-section {
  background: var(--n-50);
  border: none;
  border-radius: var(--r-3);
  padding: var(--sp-5);
  margin-bottom: var(--sp-6);
}
.nominee-category-section:last-child {
  margin-bottom: 0;
}
.nominee-category-heading {
  font-family: var(--font-serif);
  font-size: var(--fs-4);
  font-weight: 700;
  color: var(--brand-ink);
  border-bottom: 2px solid var(--brand-spark);
  padding-bottom: var(--sp-2);
  margin: 0 0 var(--sp-4);
}

.hero__image {
  display:    block;
  width:      100%;
  height:     100%;
  object-fit: cover;
}


/* --------------------------------------------------------------------------
   Hero · --xl (Home only)
   Full editorial: 7/5 content/media split at ≥1024px; min-height for
   above-the-fold presence. Stacked under 1024px (base grid does the work).
-------------------------------------------------------------------------- */

.hero--xl .hero__grid {
  padding:    var(--sp-8) var(--sp-5);
  gap:        var(--sp-6);
  /* M30 Phase 6 (F-6-1): tier-A hero height — 64vh / 34rem. Reduced from
     80vh / 40rem so above-the-fold content can include the start of the
     Trending Now rail without scrolling on common laptop viewports. */
  min-height: min(64vh, 34rem);
}

.hero--xl .hero__headline {
  font-size: var(--fs-6);
}

.hero--xl.hero--text-only .hero__content {
  grid-column: 2 / span 10;
  align-items: flex-start;
}

@media (min-width: 1024px) {
  .hero--xl.hero--with-image .hero__content {
    grid-column: 1 / span 7;
  }

  .hero--xl.hero--with-image .hero__media {
    grid-column:  8 / span 5;
    aspect-ratio: 4 / 5;
  }
}


/* --------------------------------------------------------------------------
   Hero · mobile tuning (<768px) — M10 Phase 2 W6.3
   Tighter padding, 48px search input, 2×2 trust grid, no horizontal overflow.
   Display type continues to scale via the clamp()-based --fs-* tokens; no
   hardcoded font-size values are introduced (CLAUDE.md hard rule typography).
-------------------------------------------------------------------------- */

@media (max-width: 767.98px) {
  .hero__grid {
    padding: var(--sp-5) var(--sp-4);
    gap:     var(--sp-4);
  }

  .hero--xl .hero__grid {
    padding:    var(--sp-6) var(--sp-4);
    min-height: auto;
  }

  /* Search slot: cap inner control to 48px so the hero search field scales
     down from the 60px desktop spec. The control itself is owned by the
     consumer; we constrain via a max-height on the hero__search inputs. */
  .hero__search {
    max-width: 100%;
  }

  .hero__search > input,
  .hero__search input[type="search"],
  .hero__search input[type="text"] {
    height:    48px;
    min-height: 48px;
  }

  /* Trust row: collapse from inline-flex (1×4) to a 2×2 grid at <768px so
     four chips fit in two tidy rows on a 375px viewport without overflow. */
  .hero__trust {
    display:               grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap:                   var(--sp-3);
  }

  .hero__trust-item {
    min-width: 0;
    overflow:  hidden;
  }

  .hero__trust-pair,
  .hero__trust-label,
  .hero__trust-value {
    min-width:     0;
    overflow:      hidden;
    text-overflow: ellipsis;
  }

  /* Hero__media keeps aspect-ratio but is constrained to viewport width to
     prevent horizontal overflow on full-bleed configs at 375px. */
  .hero__media {
    max-width: 100%;
  }
}

/* --------------------------------------------------------------------------
   Hero · reduced-motion fallback
   Phase 1 has no hero entry animation (Reveal wires that in Phase 6). This
   block future-proofs any transform the image later picks up.
-------------------------------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  .hero__image {
    transform: none;
  }
}


/* --------------------------------------------------------------------------
   Hero · trust-row dual typography (W4.v2.1 closes Phase-1 W-1)
   When HeroTrustItem.Value is set, the item renders Value/Label as a stacked
   pair — serif numeric on top, mono uppercase descriptor below — restoring
   the legacy `.hero-trust` dual-typography hierarchy without forking the kit.
   When Value is null, the item collapses to the original single-line Label
   (Phase-1 back-compat).
-------------------------------------------------------------------------- */

.hero__trust-pair {
  display:        inline-flex;
  flex-direction: column;
  gap:            var(--sp-1);
  align-items:    flex-start;
}

.hero__trust-value {
  font-family:    var(--font-serif);
  font-size:      var(--fs-3);
  font-weight:    600;
  line-height:    1.05;
  letter-spacing: -0.01em;
  color:          var(--n-0);
  text-transform: none;
}


/* --------------------------------------------------------------------------
   Hero · Layout · --centered  (default; preserves Phase 1 markup behaviour)
-------------------------------------------------------------------------- */

.hero--centered .hero__grid {
  /* Default grid; size modifiers (--sm / --xl) carry their own column tweaks. */
}


/* --------------------------------------------------------------------------
   Hero · Layout · --split  (60/40 content/media at desktop)
   Solves the F-2-2 detail-page above-the-fold problem: keeps the brand image
   beside the content rather than stacked below. Mobile collapses to stacked.
-------------------------------------------------------------------------- */

@media (min-width: 1024px) {
  .hero--split.hero--with-image .hero__content {
    grid-column: 1 / span 7;
  }

  .hero--split.hero--with-image .hero__media {
    grid-column:  8 / span 5;
    aspect-ratio: 4 / 5;
  }

  /* --xl Hero on Home gets a slightly taller media pane so the rail below
     it does not lift the image into a portrait crop unnecessarily. */
  .hero--xl.hero--split.hero--with-image .hero__media {
    aspect-ratio: 5 / 6;
  }
}


/* --------------------------------------------------------------------------
   Hero · Layout · --full-bleed  (image is canvas; content overlays at desktop)
   Mobile (<1024px) keeps the standard stacked grid but layers the image as
   a soft canvas backdrop tinted toward brand-ink so type stays legible.
-------------------------------------------------------------------------- */

.hero--full-bleed.hero--with-image {
  position: relative;
}

.hero--full-bleed.hero--with-image .hero__media {
  position:      absolute;
  inset:         0;
  margin:        0;
  border-radius: 0;
  aspect-ratio:  auto;
  z-index:       0;
}

.hero--full-bleed.hero--with-image .hero__image {
  width:      100%;
  height:     100%;
  object-fit: cover;
}

.hero--full-bleed.hero--with-image .hero__grid {
  position: relative;
  z-index:  1;
}

.hero--full-bleed.hero--with-image .hero__grid::before {
  content:        "";
  position:       absolute;
  inset:          0;
  background:     linear-gradient(
                    180deg,
                    color-mix(in srgb, var(--brand-ink) 72%, transparent) 0%,
                    color-mix(in srgb, var(--brand-ink) 40%, transparent) 70%,
                    color-mix(in srgb, var(--brand-ink) 76%, transparent) 100%);
  pointer-events: none;
  z-index:        -1;
}

.hero--full-bleed.hero--with-image .hero__content {
  color: var(--n-0);
}

.hero--full-bleed.hero--with-image .hero__headline {
  color: var(--n-0);
}

.hero--full-bleed.hero--with-image .hero__headline-accent {
  color: var(--brand-spark);
}

.hero--full-bleed.hero--with-image .hero__eyebrow {
  color: var(--brand-spark);
}

.hero--full-bleed.hero--with-image .hero__subcopy,
.hero--full-bleed.hero--with-image .hero__trust-item,
.hero--full-bleed.hero--with-image .hero__trust-label,
.hero--full-bleed.hero--with-image .hero__trust-value {
  color: color-mix(in srgb, var(--n-0) 88%, transparent);
}

.hero--full-bleed.hero--with-image .hero__trust {
  border-top: 1px solid color-mix(in srgb, var(--n-0) 24%, transparent);
}

@media (min-width: 1024px) {
  .hero--full-bleed.hero--with-image .hero__content {
    grid-column: 2 / span 7;
  }

  .hero--full-bleed.hero--with-image .hero__media {
    /* canvas — already absolute-inset above */
  }

  /* Reset the 7/5 split that --xl base imposes; full-bleed owns the canvas. */
  .hero--xl.hero--full-bleed.hero--with-image .hero__media {
    grid-column: 1 / -1;
  }
}

/* When full-bleed has no image (degenerate fallback), behave as centered. */
.hero--full-bleed.hero--text-only .hero__content {
  /* inherits centered defaults */
}

/* ==========================================================================
   EMPTY STATE  (M17 · C17 Phase 1 · W17.2) — typographic empty-state primitive.
   Source: Views/Shared/Kit/_EmptyState.cshtml · Model: EmptyStateViewModel.
   Hard rules: #2 (tokens only, no raw hex); #3 (motion tokens only, no raw ms);
   #5 (no <style> block in partial); #8 (CTA touch target ≥ 44×44 inherited
   from .btn--md / .btn--sm in elfrique.css); #10 (no motion shipped — N/A).
   ========================================================================== */

.c-empty {
  display:          flex;
  align-items:      center;
  justify-content:  center;
  width:            100%;
  padding:          var(--sp-7) var(--sp-5);
  font-family:      var(--font-sans);
  color:            var(--brand-ink);
  background-color: var(--n-0);
  border:           1px dashed var(--n-200);
  border-radius:    var(--r-3);
  box-sizing:       border-box;
}

.c-empty__inner {
  display:        flex;
  flex-direction: column;
  align-items:    flex-start;
  gap:            var(--sp-4);
  width:          100%;
  max-width:      40rem;
  text-align:     start;
}

.c-empty__headline {
  margin:         0;
  font-family:    var(--font-serif);
  font-size:      var(--fs-5);
  font-weight:    600;
  line-height:    1.12;
  letter-spacing: -0.015em;
  color:          var(--brand-ink);
  text-wrap:      balance;
}

.c-empty__headline em,
.c-empty__headline i {
  font-style:  italic;
  font-weight: 500;
  color:       var(--brand-spark);
}

.c-empty__subtext {
  margin:      0;
  font-size:   var(--fs-3);
  line-height: 1.5;
  color:       var(--n-700);
  max-width:   36rem;
}

.c-empty__actions {
  display:     inline-flex;
  flex-wrap:   wrap;
  align-items: center;
  gap:         var(--sp-3);
  margin:      0;
  padding:     var(--sp-2) 0 0;
}

/* Compact variant — inside a card / drawer / sidebar slot.
   Reduces vertical pad, drops border, scales the headline down to body-display
   while keeping subtext at body. CTA is consumed at .btn--sm (44px min-height
   already enforced by elfrique.css base). */
.c-empty--compact {
  padding:       var(--sp-5) var(--sp-4);
  border:        0;
  border-radius: 0;
}

.c-empty--compact .c-empty__inner {
  gap:       var(--sp-3);
  max-width: 28rem;
}

.c-empty--compact .c-empty__headline {
  font-size:   var(--fs-4);
  line-height: 1.18;
}

/* F-1-2 (Phase 2c): compact-variant subtext baseline locked at --fs-2. Sits one
   step below the full variant's --fs-3 body baseline because compact only renders
   inside cards/drawers/sidebars where the surrounding container handles the
   surface-level body text. Decision recorded in docs/kit/empty-state.md addendum. */
.c-empty--compact .c-empty__subtext {
  font-size: var(--fs-2);
}


/* ==========================================================================
   MEDIA  (Phase 5 · W2.14) — fixed-aspect frame + shimmer + broken fallback.
   Source: Views/Shared/Kit/_Media.cshtml · Model: MediaModel.
   Script: wwwroot/js/kit/media.js (solhigson.kit.media).
   Hard rules: #3 (motion tokens); #10 (reduced-motion disables shimmer).
   ========================================================================== */

.media {
  position:         relative;
  display:          block;
  margin:           0;
  overflow:         hidden;
  border-radius:    var(--r-3);
  background-color: var(--n-100);
  color:            var(--brand-ink);
}

/* Aspect-ratio variants — mapped 1:1 to MediaAspectRatio enum. */
.media--square    { aspect-ratio:  1 / 1; }
.media--portrait  { aspect-ratio:  4 / 5; }
.media--video     { aspect-ratio: 16 / 9; }
.media--cinematic { aspect-ratio: 21 / 9; }

.media__image {
  display:    block;
  width:      100%;
  height:     100%;
  object-fit: cover;
  transition: opacity var(--d-2) var(--ease-out-swift);
}

/* Loading state — shimmer painted under the image until it finishes
   decoding. Uses ::before so no extra DOM node is needed. */
.media__image[data-media-loading="true"] {
  opacity: 0;
}

.media::before {
  content:          "";
  position:         absolute;
  inset:            0;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--n-100) 70%, transparent) 0%,
    color-mix(in srgb, var(--n-200) 85%, transparent) 50%,
    color-mix(in srgb, var(--n-100) 70%, transparent) 100%);
  background-size:  200% 100%;
  animation:        media-shimmer var(--d-5) var(--ease-in-out-subtle) infinite;
  opacity:          0;
  pointer-events:   none;
  transition:       opacity var(--d-1) var(--ease-out-swift);
}

.media:has(.media__image[data-media-loading="true"])::before {
  opacity: 1;
}

@keyframes media-shimmer {
  0%   { background-position: 200% 0; }
  100% { background-position: -200% 0; }
}

/* Failed state — image broken or blocked. 2026-05-08 mandate Phase 4:
   replaces the grey "Image unavailable" pictogram with the brand-ink/spark
   no-image gradient from --gradient-no-image. Same visual treatment as the
   .media__gradient-fallback (Path B null/empty Src) so failed-load and
   no-Src cases converge on a single placeholder language. */
.media[data-media-state="failed"] {
  background: var(--gradient-no-image);
}

.media[data-media-state="failed"] .media__image {
  opacity: 0;
}

/* Gradient fallback — emitted by _Media.cshtml Path B when Model.Src is
   null or whitespace-only. Fills the figure frame at the same aspect ratio
   the image would have occupied (the parent .media establishes the box via
   its --square / --portrait / --video / --cinematic modifier on aspect-ratio).
   Pointer-transparent so any sibling overlay (.media__overlay) keeps its
   own click semantics. */
.media__gradient-fallback {
  position:       absolute;
  inset:          0;
  background:     var(--gradient-no-image);
  pointer-events: none;
}

/* Overlay layer — badges, gradients, play glyphs. Wrapper is pointer-
   transparent so the underlying link remains clickable; the badge
   itself can re-enable pointer events. */
.media__overlay {
  position:       absolute;
  inset:          0;
  display:        flex;
  flex-direction: column;
  justify-content: space-between;
  padding:        var(--sp-3);
  pointer-events: none;
}

@media (prefers-reduced-motion: reduce) {
  .media::before {
    animation: none;
  }
  .media__image {
    transition: none;
  }
}


/* ==========================================================================
   CONTENT CARD  (Phase 5 · W2.11) — Media + title + meta + CTA + favorite.
   Source: Views/Shared/Kit/_ContentCard.cshtml · Model: ContentCardModel.
   Hard rules: #1 (Tour accent uses --state-success, teal); #8 (favorite
   ≥ 44×44); #10 (reduced-motion disables hover lift).
   ========================================================================== */

.content-card {
  position:          relative;
  display:           flex;
  flex-direction:    column;
  height:            100%;
  gap:               var(--sp-3);
  padding:           var(--sp-3);
  background-color:  var(--n-0);
  border:            1px solid var(--n-200);
  border-radius:     var(--r-4);
  box-shadow:        var(--shadow-1);
  font-family:       var(--font-sans);
  color:             var(--brand-ink);
  transition:        transform   var(--d-2) var(--ease-out-swift),
                     box-shadow  var(--d-2) var(--ease-out-swift),
                     border-color var(--d-2) var(--ease-out-swift);
}

.content-card:hover {
  transform:      translateY(-2px);
  box-shadow:     var(--shadow-2);
  border-color:   var(--n-300);
}

.content-card:focus-within {
  box-shadow:     var(--shadow-2);
  border-color:   var(--brand-ink);
}

/* Stretched-link pattern — the title <a> grows to cover the whole card
   via ::before. Favorite toggle sits above this via z-index. */
.content-card__link::before {
  content:  "";
  position: absolute;
  inset:    0;
  z-index:  1;
  border-radius: inherit;
}

.content-card__link {
  color:            inherit;
  text-decoration:  none;
}

.content-card__link:focus-visible {
  /* Inherit the global :focus-visible ring (--brand-spark, 2px / 2px offset) from
     elfrique.css. The :has() parent rule below adds a card-wide --state-info ring
     so the entire card surface signals keyboard focus, not just the inline link.
     Both rings are intentional and stack: link-level (brand-spark) + card-level
     (state-info). M11 P1 (W8.1). */
}

.content-card:has(.content-card__link:focus-visible) {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

.content-card__media {
  position:      relative;
  border-radius: var(--r-3);
  overflow:      hidden;
}

.content-card__media .media {
  border-radius: var(--r-3);
}

.content-card__favorite {
  position:         absolute;
  top:              var(--sp-2);
  right:            var(--sp-2);
  z-index:          2;
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  min-width:        44px;
  min-height:       44px;
  padding:          0;
  border:           1px solid color-mix(in srgb, var(--n-900) 10%, transparent);
  border-radius:    50%;
  background-color: color-mix(in srgb, var(--n-0) 88%, transparent);
  color:            var(--brand-ink);
  font-size:        var(--fs-4);
  line-height:      1;
  cursor:           pointer;
  transition:       transform        var(--d-1) var(--ease-out-swift),
                    background-color var(--d-1) var(--ease-out-swift),
                    color            var(--d-1) var(--ease-out-swift);
}

.content-card__favorite:hover {
  background-color: var(--n-0);
  transform:        scale(1.06);
}

.content-card__favorite:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

.content-card__favorite[aria-pressed="true"] {
  color: var(--state-danger);
}

/* M30 Phase 5 (F-5-1/F-5-2) — MediaBadge slot.
   Top-left of the media region so it never collides with the favorite
   toggle (top-right). Consumers pre-render their pill HTML; the slot is
   a passive flex container that lets multiple pills stack horizontally
   when needed (e.g. category + Live for voting cards).

   Hard rule audit:
     #1  Live pill colors are consumer-controlled — consumer MUST use
         --state-success / --brand-spark, NEVER green (audited at consumer).
     #4  No inline style= — slot is class-only.
     #8  N/A — badge is passive label, not interactive.

   The .content-card__media-pill helper class below supplies a default
   pill skin so consumers don't have to recreate it. Custom pill styling
   can override per consumer (consumer wraps their own class on the
   element they pre-render into the slot). */
.content-card__media-badge {
  position:      absolute;
  top:           var(--sp-2);
  left:          var(--sp-2);
  z-index:       2;
  display:       inline-flex;
  flex-wrap:     wrap;
  align-items:   center;
  gap:           var(--sp-1);
  pointer-events: none; /* badge is decorative; doesn't intercept stretched-link clicks */
}

.content-card__media-pill {
  display:         inline-flex;
  align-items:     center;
  gap:             var(--sp-1);
  padding:         calc(var(--sp-1) / 2) var(--sp-2);
  border-radius:   var(--r-pill);
  background-color: color-mix(in srgb, var(--n-0) 92%, transparent);
  color:           var(--brand-ink);
  font-family:     var(--font-mono);
  font-size:       var(--fs-1);
  font-weight:     500;
  letter-spacing:  0.04em;
  white-space:     nowrap;
  line-height:     1.2;
}

/* Live pill — teal --state-success per HR1 (success is teal, never green). */
.content-card__media-pill--live {
  background-color: var(--state-success);
  color:            var(--n-0);
}

.content-card__media-pill--live::before {
  content:          "";
  display:          inline-block;
  width:            6px;
  height:           6px;
  border-radius:    50%;
  background-color: currentColor;
}

/* M49 Phase 9 (D-9-12) — tiered status pills extend the existing --live
   precedent. Three additive modifiers; mutually exclusive emission is
   enforced by the consumer (EventsBrowse.cshtml) per AC#11 precedence
   Sold-out > Live > Selling-fast > Featured. Token-only colours; no new
   tokens introduced. The kit demo at /design/kit shows all four side-by-
   side — see Views/Kit/Index.cshtml. */
.content-card__media-pill--soldout {
  background-color: var(--n-700);
  color:            var(--n-0);
}

.content-card__media-pill--selling-fast {
  background-color: var(--state-warn);
  color:            var(--n-0);
}

.content-card__media-pill--featured {
  background-color: var(--brand-spark);
  color:            var(--brand-ink);
}

.content-card__body {
  display:        flex;
  flex-direction: column;
  flex:           1;
  gap:            var(--sp-2);
  padding:        0 var(--sp-1) var(--sp-1);
}

.content-card__title {
  margin:         0;
  font-family:    var(--font-serif);
  font-size:      var(--fs-4);
  font-weight:    600;
  line-height:    1.22;
  letter-spacing: -0.005em;
  color:          var(--brand-ink);
  text-wrap:      balance;
  display:            -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow:           hidden;
  text-overflow:      ellipsis;
}

.content-card__subtitle {
  margin:      0;
  font-family: var(--font-sans);
  font-size:   var(--fs-2);
  line-height: 1.4;
  color:       var(--n-600);
}

.content-card__meta {
  margin:         0;
  padding:        0;
  list-style:     none;
  display:        flex;
  flex-wrap:      wrap;
  /* M31 Phase 4 (F-4-4) — row gap (--sp-1) stacks icon+text rows vertically when
     they wrap; column gap (--sp-3) spaces siblings on the same row. */
  gap:            var(--sp-1) var(--sp-3);
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  letter-spacing: 0.04em;
  color:          var(--n-600);
}

.content-card__meta-item {
  display:     inline-flex;
  align-items: center;
  /* M31 Phase 4 (F-4-4) — gap separates icon glyph from text label. */
  gap:         var(--sp-2);
  line-height: 1.3;
}

/* M31 Phase 4 (F-4-4 / N7) — meta-item icon glyph. The <i> is a generic icon
   sigil rendered by an MDI class on the consumer side. Sized at --fs-2 so the
   glyph reads slightly larger than the mono text label, neutral-700 for
   subdued affordance against the meta-row's --n-600 text color. flex-shrink: 0
   prevents the glyph from compressing when the text wraps. */
.content-card__meta-item > i {
  font-size:   var(--fs-2);
  color:       var(--n-700);
  flex-shrink: 0;
}

.content-card__footer {
  display:         flex;
  flex-wrap:       wrap;
  align-items:     center;
  justify-content: space-between;
  gap:             var(--sp-2);
  margin-top:      auto;
  padding-top:     var(--sp-2);
  border-top:      1px dashed var(--n-200);
}

/* M20 F3d — Surface CTA pill on home rails. Visual-only span (not <a>);
   the card already carries a stretched link via Href. pointer-events: none
   ensures the pill never intercepts the underlying link. */
.content-card__cta-pill {
  display:         inline-flex;
  align-items:     center;
  padding:         var(--sp-2) var(--sp-3);
  border-radius:   var(--r-pill);
  background:      var(--brand-ink);
  color:           var(--n-0);
  font-family:     var(--font-mono);
  font-size:       var(--fs-1);
  font-weight:     500;
  letter-spacing:  0.04em;
  text-transform:  uppercase;
  white-space:     nowrap;
  pointer-events:  none;
}

.content-card__price {
  font-family:          var(--font-serif);
  font-size:            var(--fs-4);
  font-weight:          600;
  letter-spacing:       -0.01em;
  color:                var(--brand-ink);
  font-variant-numeric: tabular-nums;
}

.content-card__cta {
  display:     inline-flex;
  align-items: center;
  gap:         var(--sp-2);
}

/* Variant accents — modifier classes apply a left border accent and
   shift the meta / price emphasis. All accents via tokens. */
.content-card--event   { border-top: 3px solid var(--brand-ink); }
.content-card--vendor  { border-top: 3px solid var(--brand-spark); }
.content-card--contest { border-top: 3px solid var(--state-info); }
.content-card--tour    { border-top: 3px solid var(--state-success); }

.content-card--vendor .content-card__meta-item:first-child,
.content-card--contest .content-card__meta-item:first-child,
.content-card--tour .content-card__price {
  color: var(--brand-ink);
  font-weight: 600;
}

/* M20 F6 — Blurred background media variant (Phase 4 voting use case primitive) */
.content-card--media-blurred-bg .content-card__media {
  position:       relative;
  overflow:       hidden;
}

/* M30 Phase 5 (F-5-3 root-cause fix) — the blur filter must NOT cascade to the
   sharp foreground <img.content-card__media-foreground> sibling. The :not()
   excludes it at selection time. Defensive `filter: none` reset on the
   foreground rule below provides double-defense. */
.content-card--media-blurred-bg .content-card__media img:not(.content-card__media-foreground),
.content-card--media-blurred-bg .content-card__media picture {
  position:        absolute;
  inset:           0;
  width:           100%;
  height:          100%;
  object-fit:      cover;
  filter:          blur(20px) saturate(1.1);
  transform:       scale(1.15); /* hide blur edge */
}

.content-card--media-blurred-bg .content-card__media::after {
  content:         "";
  position:        absolute;
  inset:           0;
  background:      linear-gradient(180deg, color-mix(in oklab, var(--brand-ink) 0%, transparent) 0%, color-mix(in oklab, var(--brand-ink) 35%, transparent) 100%);
  pointer-events:  none;
}

/* M23 Phase 5 C6 — Sharp foreground image overlays the blurred background.
   The blurred fill is rendered by the inner _Media <img>/<picture> (filtered
   via the rule above). The foreground image is a sibling <img> emitted by
   _ContentCard when BlurredBg=true, sized to fit the frame without crop
   (object-fit: contain) so the source composition reads as intended.
   M30 Phase 5 (F-5-3) — `filter: none` and `transform: none` reset
   defensively in case the broad img blur rule is re-broadened later
   (the :not() above is the primary guard). */
.content-card--media-blurred-bg .content-card__media-foreground {
  position:   absolute;
  inset:      0;
  width:      100%;
  height:     100%;
  object-fit: contain;
  filter:     none;
  transform:  none;
  z-index:    1;
}

@media (prefers-reduced-motion: reduce) {
  .content-card--media-blurred-bg .content-card__media img:not(.content-card__media-foreground),
  .content-card--media-blurred-bg .content-card__media picture {
    transform: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .content-card,
  .content-card__favorite {
    transition: none;
  }
  .content-card:hover {
    transform: none;
  }
  .content-card__favorite:hover {
    transform: none;
  }
}


/* ==========================================================================
   RAIL  (Phase 5 · W2.10) — scroll-snap horizontal rail + affordances.
   Source: Views/Shared/Kit/_Rail.cshtml · Model: RailModel.
   Script: wwwroot/js/kit/rail.js (solhigson.kit.rail) maintains
   data-rail-at-start / data-rail-at-end on the rail root.
   Hard rules: #3 (motion tokens); #8 (see-all + affordances ≥ 44×44);
   #10 (reduced-motion flips scroll-behavior to auto).
   ========================================================================== */

.rail {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-4);
  padding-inline: var(--sp-5);
  font-family:    var(--font-sans);
  color:          var(--brand-ink);
}

.rail__heading-strip {
  display:         flex;
  flex-wrap:       wrap;
  align-items:     flex-end;
  justify-content: space-between;
  gap:             var(--sp-3);
}

.rail__heading-text {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-1);
  min-width:      0;
  flex:           1 1 20rem;
}

.rail__eyebrow {
  margin:         0;
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.12em;
  color:          var(--brand-spark);
  font-weight:    500;
}

.rail__heading {
  margin:         0;
  font-family:    var(--font-serif);
  font-size:      var(--fs-5);
  font-weight:    600;
  line-height:    1.15;
  letter-spacing: -0.01em;
  color:          var(--brand-ink);
}

.rail__description {
  margin:      0;
  font-family: var(--font-sans);
  font-size:   var(--fs-2);
  line-height: 1.5;
  color:       var(--n-600);
  max-width:   40rem;
}

.rail__see-all {
  display:          inline-flex;
  align-items:      center;
  gap:              var(--sp-2);
  min-height:       44px;
  padding:          var(--sp-2) var(--sp-3);
  font-family:      var(--font-mono);
  font-size:        var(--fs-1);
  font-weight:      500;
  text-transform:   uppercase;
  letter-spacing:   0.08em;
  color:            var(--brand-ink);
  text-decoration:  none;
  border-radius:    var(--r-2);
  transition:       background-color var(--d-1) var(--ease-out-swift),
                    color            var(--d-1) var(--ease-out-swift);
}

.rail__see-all:hover {
  background-color: var(--n-100);
  color:            var(--brand-ink);
}

.rail__see-all:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

.rail__see-all-glyph {
  font-size:   var(--fs-3);
  line-height: 1;
}

.rail__viewport {
  position: relative;
  display:  block;
}

.rail__track {
  display:              grid;
  grid-auto-flow:       column;
  grid-auto-columns:    minmax(15rem, 18rem);
  align-items:          stretch;
  gap:                  var(--sp-4);
  margin:               0;
  padding:              var(--sp-2) var(--sp-5);
  list-style:           none;
  overflow-x:           auto;
  overflow-y:           hidden;
  scroll-snap-type:     x mandatory;
  scroll-padding-inline: var(--sp-5);
  scroll-behavior:      smooth;
  scrollbar-width:      thin;
  scrollbar-color:      var(--n-300) transparent;
}

.rail__track::-webkit-scrollbar {
  height: 6px;
}

.rail__track::-webkit-scrollbar-thumb {
  background-color: var(--n-300);
  border-radius:    var(--r-1);
}

.rail__track:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: -2px;
  border-radius:  var(--r-2);
}

.rail__item {
  scroll-snap-align: start;
  min-width:         0;
}

.rail__empty {
  grid-column:      1 / -1;
  padding:          var(--sp-6);
  text-align:       center;
  color:            var(--n-500);
  font-family:      var(--font-mono);
  font-size:        var(--fs-1);
  text-transform:   uppercase;
  letter-spacing:   0.08em;
}

.rail__empty-headline {
  margin: 0;
}

.rail__affordance {
  position:         absolute;
  top:              50%;
  transform:        translateY(-50%);
  z-index:          2;
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  min-width:        44px;
  min-height:       44px;
  padding:          0;
  border:           1px solid var(--n-200);
  border-radius:    50%;
  background-color: var(--n-0);
  color:            var(--brand-ink);
  font-size:        var(--fs-5);
  line-height:      1;
  cursor:           pointer;
  box-shadow:       var(--shadow-2);
  transition:       opacity          var(--d-2) var(--ease-out-swift),
                    transform        var(--d-1) var(--ease-out-swift),
                    background-color var(--d-1) var(--ease-out-swift);
}

.rail__affordance--prev { left:  var(--sp-1); }
.rail__affordance--next { right: var(--sp-1); }

.rail__affordance:hover {
  background-color: var(--n-50);
  transform:        translateY(-50%) scale(1.04);
}

.rail__affordance:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

/* Hide the affordance when the track is already at that edge. JS
   toggles the data attributes on the rail root. */
.rail[data-rail-at-start="true"] .rail__affordance--prev,
.rail[data-rail-at-end="true"]   .rail__affordance--next {
  opacity:        0;
  pointer-events: none;
}

/* Edge gradients — fade the viewport edges so items scrolling out of
   view dissolve rather than hard-clipping against the affordance. */
.rail__viewport::before,
.rail__viewport::after {
  content:        "";
  position:       absolute;
  top:            0;
  bottom:         0;
  width:          var(--sp-6);
  pointer-events: none;
  z-index:        1;
  transition:     opacity var(--d-2) var(--ease-out-swift);
}

.rail__viewport::before {
  left:       0;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--n-0) 96%, transparent) 0%,
    color-mix(in srgb, var(--n-0) 0%,  transparent) 100%);
}

.rail__viewport::after {
  right:      0;
  background: linear-gradient(270deg,
    color-mix(in srgb, var(--n-0) 96%, transparent) 0%,
    color-mix(in srgb, var(--n-0) 0%,  transparent) 100%);
}

.rail[data-rail-at-start="true"] .rail__viewport::before,
.rail[data-rail-at-end="true"]   .rail__viewport::after {
  opacity: 0;
}

@media (max-width: 640px) {
  .rail__track {
    grid-auto-columns: minmax(78%, 82%);
    padding:           var(--sp-2) var(--sp-4);
    scroll-padding-inline: var(--sp-4);
  }
  .rail__affordance {
    display: none;
  }
}

@media (prefers-reduced-motion: reduce) {
  .rail__track {
    scroll-behavior: auto;
  }
  .rail__see-all,
  .rail__affordance {
    transition: none;
  }
  .rail__affordance:hover {
    transform: translateY(-50%);
  }
}


/* ==========================================================================
   HOME · Hero search row + chip bar (M07 W4.1 / W4.3)
   The Hero kit owns the headline / eyebrow / trust-row chrome; this block
   styles the Home-specific search slot (input + submit + chip bar) that
   composes inside the Hero `__search` slot.

   Token discipline: every value below resolves to a token from
   elfrique.css (or a multiple of one). Hard rule #2 (no raw hex), #3
   (no raw ms), #8 (touch targets ≥ 44×44).
   ========================================================================== */

.home-search {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-3);
  width:          100%;
}

.home-search__row {
  display:          flex;
  align-items:      center;
  gap:              var(--sp-2);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-5);
  padding:          var(--sp-2) var(--sp-2) var(--sp-2) var(--sp-4);
  box-shadow:       var(--shadow-3);
}

.home-search__row:focus-within {
  border-color: var(--brand-ink);
  outline:      2px solid var(--brand-ink);
  outline-offset: 2px;
}

.home-search__icon {
  font-size:   var(--fs-3);
  color:       var(--n-400);
  flex-shrink: 0;
}

.home-search__input {
  flex:        1;
  border:      none;
  background:  transparent;
  /* Parent .home-search__row:focus-within provides the brand-ink ring; suppress native to avoid dual outline. */
  outline:     none;
  font-family: var(--font-sans);
  font-size:   var(--fs-3);
  color:       var(--n-800);
  min-width:   0;
  min-height:  44px;
}

.home-search__input::placeholder {
  color: var(--n-400);
}

.home-search__submit {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  min-height:       44px;
  min-width:        44px;
  padding:          0 var(--sp-5);
  border:           none;
  border-radius:    var(--r-5);
  background-color: var(--brand-ink);
  color:            var(--n-0);
  font-family:      var(--font-sans);
  font-size:        var(--fs-2);
  font-weight:      600;
  cursor:           pointer;
  transition:       background-color var(--d-1) var(--ease-out-swift);
  flex-shrink:      0;
}

.home-search__submit:hover,
.home-search__submit:focus-visible {
  background-color: var(--brand-spark);
  color:            var(--brand-on-spark);
}

.home-search__submit:focus-visible {
  outline:        2px solid var(--brand-ink);
  outline-offset: 2px;
}

.home-search__dropdown {
  position:       relative;
}

.home-search__dropdown:empty {
  display: none;
}

.home-search__chips {
  display:    flex;
  flex-wrap:  wrap;
  gap:        var(--sp-2);
  margin:     0;
  padding:    0;
  list-style: none;
}

.home-search__chip-item {
  margin: 0;
}

.home-search__chip {
  display:          inline-flex;
  align-items:      center;
  min-height:       44px;
  padding:          var(--sp-2) var(--sp-4);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-5);
  background-color: var(--n-0);
  font-family:      var(--font-sans);
  font-size:        var(--fs-1);
  font-weight:      500;
  color:            var(--n-700);
  cursor:           pointer;
  transition:       background-color var(--d-1) var(--ease-out-swift),
                    border-color var(--d-1) var(--ease-out-swift),
                    color var(--d-1) var(--ease-out-swift);
}

.home-search__chip:hover {
  border-color: var(--brand-ink);
  color:        var(--brand-ink);
}

.home-search__chip:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
  border-color:   var(--brand-ink);
  color:          var(--brand-ink);
}

@media (prefers-reduced-motion: reduce) {
  .home-search__submit,
  .home-search__chip {
    transition: none;
  }
}


/* ==========================================================================
   NEWSLETTER (M07 W4.1)
   Migrated from the inline <style> block on Home.cshtml. Token-driven —
   no raw hex, no raw ms.
   ========================================================================== */

.newsletter {
  /* M30 Phase 6 (F-6-4): bottom padding dropped to 0 so the newsletter band
     sits flush against the footer's existing top margin — eliminates the
     compounded subscribe→footer gap (sp-8 + sp-7 ≈ 120px). Single-source
     spacing: .footer-public margin-top owns the gap below. */
  padding:    var(--sp-8) 0 0;
  /* M30 Phase 6 (F-6-3): gradient removed per L4 default — solid brand-ink
     surface for visual continuity with the footer below. The previous
     linear-gradient(brand-spark → n-100) is gone; descendants that
     explicitly declare color stay readable on the dark surface. */
  background: var(--brand-ink);
  /* On a brand-ink surface, body text (cascade-fed) reads in n-0/light. */
  color:      var(--n-0);
}

.newsletter-inner {
  text-align: center;
  max-width:  600px;
  margin:     0 auto;
  padding:    0 var(--sp-5);
}

.newsletter-inner h2 {
  font-family: var(--font-serif);
  font-size:   var(--fs-5);
  font-weight: 600;
  margin:      0 0 var(--sp-3);
  /* M30 Phase 6 (F-6-3): newsletter surface flipped from gradient to solid
     brand-ink. Heading reads in n-0 on the dark surface (full contrast,
     no mid-stop bronze fallback needed). */
  color:       var(--n-0);
}

.newsletter-inner p {
  font-size:   var(--fs-3);
  margin:      0 0 var(--sp-6);
  /* M30 Phase 6 (F-6-3): supporting copy on the dark surface — neutral
     light tint so it sits below the heading hierarchy without dropping
     out of contrast. */
  color:       var(--n-100);
}

.newsletter-form {
  display:         flex;
  gap:             var(--sp-3);
  justify-content: center;
  align-items:     center;
}

.newsletter-form input {
  flex:             1;
  max-width:        24rem;
  min-height:       44px;
  padding:          0 var(--sp-5);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-5);
  background-color: var(--n-0);
  font-family:      var(--font-sans);
  font-size:        var(--fs-2);
  color:            var(--n-800);
  transition:       border-color var(--d-1) var(--ease-out-swift);
}

.newsletter-form input:focus-visible {
  border-color:   var(--brand-ink);
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.newsletter-form button {
  min-height:       44px;
  padding:          0 var(--sp-6);
  border:           none;
  border-radius:    var(--r-5);
  background-color: var(--brand-ink);
  color:            var(--n-0);
  font-family:      var(--font-sans);
  font-size:        var(--fs-2);
  font-weight:      600;
  cursor:           pointer;
  transition:       background-color var(--d-1) var(--ease-out-swift);
}

.newsletter-form button:hover,
.newsletter-form button:focus-visible {
  background-color: var(--brand-spark);
  color:            var(--brand-on-spark);
}

.newsletter-form button:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

@media (max-width: 768px) {
  .newsletter-form {
    flex-direction: column;
    align-items:    stretch;
  }

  .newsletter-form input,
  .newsletter-form button {
    max-width: 100%;
    width:     100%;
  }
}

@media (prefers-reduced-motion: reduce) {
  .newsletter-form input,
  .newsletter-form button {
    transition: none;
  }
}


/* ==========================================================================
   EVENT DETAIL (M07 W4.4)
   Composition layer over the Hero kit for /events/{slug}.
   Two-column main+sidebar layout; primary CTA stays above the fold at
   1366×768 because Hero --sm tops out near 340px and the sidebar starts
   immediately to the right.
   Token discipline: every value resolves to a token from elfrique.css.
   ========================================================================== */

.event-detail {
  background-color: var(--n-50);
  padding:          var(--sp-7) 0 var(--sp-8);
}

.event-detail__container {
  width:     100%;
  max-width: 1280px;
  margin:    0 auto;
  padding:   0 var(--sp-5);
}

.event-detail__layout {
  display:               grid;
  grid-template-columns: 1fr 380px;
  gap:                   var(--sp-7);
  align-items:           start;
}

@media (max-width: 991px) {
  .event-detail__layout {
    grid-template-columns: 1fr;
  }
}

.event-detail__main {
  min-width: 0;
}

.event-detail__section {
  margin-bottom: var(--sp-7);
}

.event-detail__section-title {
  font-family:   var(--font-serif);
  font-size:     var(--fs-5);
  font-weight:   600;
  color:         var(--n-900);
  margin:        0 0 var(--sp-4);
  letter-spacing: -0.01em;
}

.event-detail__prose {
  color:       var(--n-700);
  font-size:   var(--fs-3);
  line-height: 1.7;
}

/* M49 Phase 7 · F1 — sanitized RTE description rhythm.
   Block-level rules cover the seven sanitizer-allowed BLOCK tags
   (p / ol / ul / li / h2 / h3 / blockquote) plus the inline `a`
   anchor. Allowlist source: HtmlSanitizationService.cs:44-57.
   Tokens only (HR2 / HR3); no animations introduced (HR10 N/A). */
.event-detail__prose p {
  margin: 0 0 var(--sp-4);
}

.event-detail__prose h2 {
  font-family:    var(--font-serif);
  font-size:      var(--fs-4);
  font-weight:    600;
  color:          var(--n-900);
  letter-spacing: -0.01em;
  margin:         var(--sp-6) 0 var(--sp-3);
}

.event-detail__prose h3 {
  font-family:    var(--font-serif);
  font-size:      var(--fs-3);
  font-weight:    600;
  color:          var(--n-900);
  letter-spacing: -0.01em;
  margin:         var(--sp-5) 0 var(--sp-3);
}

.event-detail__prose ol,
.event-detail__prose ul {
  margin:        0 0 var(--sp-4);
  padding-left:  var(--sp-5);
}

.event-detail__prose li {
  margin: 0 0 var(--sp-2);
}

.event-detail__prose li:last-child {
  margin-bottom: 0;
}

.event-detail__prose blockquote {
  margin:           var(--sp-4) 0;
  padding:          var(--sp-3) var(--sp-4);
  border-left:      3px solid var(--n-200);
  background-color: var(--n-50);
  color:            var(--n-800);
  font-style:       italic;
}

.event-detail__prose blockquote > p:last-child {
  margin-bottom: 0;
}

.event-detail__prose a {
  color:           var(--brand-ink);
  text-decoration: underline;
  text-underline-offset: 2px;
}

.event-detail__prose a:hover,
.event-detail__prose a:focus-visible {
  color: var(--brand-spark);
}

.event-detail__muted {
  color:     var(--n-500);
  font-size: var(--fs-2);
  margin:    0 0 var(--sp-4);
}

/* Highlights ----------------------------------------------------------------- */

.event-detail__highlights {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap:        var(--sp-4);
}

.event-detail__highlight {
  display:          flex;
  align-items:      center;
  gap:              var(--sp-3);
  padding:          var(--sp-4);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
}

.event-detail__highlight-icon {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  width:            44px;
  height:           44px;
  border-radius:    var(--r-2);
  background-color: var(--n-50);
  color:            var(--brand-ink);
  font-size:        var(--fs-3);
  flex-shrink:      0;
}

.event-detail__highlight-text {
  color:     var(--n-800);
  font-size: var(--fs-2);
}

/* Performers ----------------------------------------------------------------- */

.event-detail__performers {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    grid;
  grid-template-columns: repeat(auto-fill, minmax(160px, 1fr));
  gap:        var(--sp-4);
}

.event-detail__performer {
  display:          flex;
  flex-direction:   column;
  align-items:      center;
  gap:              var(--sp-2);
  padding:          var(--sp-4);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  text-align:       center;
}

.event-detail__performer-avatar {
  width:           72px;
  height:          72px;
  border-radius:   50%;
  object-fit:      cover;
  background-color: var(--n-100);
  color:           var(--n-700);
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  font-family:     var(--font-mono);
  font-size:       var(--fs-3);
  font-weight:     600;
}

.event-detail__performer-avatar--initials {
  background-color: var(--brand-ink);
  color:            var(--n-0);
}

.event-detail__performer-name {
  font-size:   var(--fs-2);
  font-weight: 600;
  color:       var(--n-900);
}

.event-detail__performer-tag {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  color:       var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

/* Location -------------------------------------------------------------------- */

.event-detail__location-card {
  display:          flex;
  align-items:      center;
  justify-content:  space-between;
  gap:              var(--sp-4);
  padding:          var(--sp-4) var(--sp-5);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  flex-wrap:        wrap;
}

.event-detail__location-text {
  display:     flex;
  align-items: center;
  gap:         var(--sp-3);
  color:       var(--n-800);
  font-size:   var(--fs-2);
}

.event-detail__location-action {
  min-height:       44px;
  display:          inline-flex;
  align-items:      center;
  padding:          0 var(--sp-5);
  border:           1px solid var(--n-300);
  border-radius:    var(--r-5);
  background-color: var(--n-0);
  color:            var(--brand-ink);
  font-family:      var(--font-sans);
  font-size:        var(--fs-2);
  font-weight:      600;
  text-decoration:  none;
  transition:       background-color var(--d-1) var(--ease-out-swift),
                    color var(--d-1) var(--ease-out-swift);
}

.event-detail__location-action:hover,
.event-detail__location-action:focus-visible {
  background-color: var(--brand-ink);
  color:            var(--n-0);
}

.event-detail__location-action:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

/* Reviews --------------------------------------------------------------------- */

.event-detail__reviews-summary {
  display:          grid;
  grid-template-columns: 200px 1fr;
  gap:              var(--sp-6);
  padding:          var(--sp-5);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  margin-bottom:    var(--sp-5);
}

@media (max-width: 768px) {
  .event-detail__reviews-summary {
    grid-template-columns: 1fr;
  }
}

.event-detail__reviews-rating {
  text-align: center;
}

.event-detail__reviews-number {
  font-family: var(--font-serif);
  font-size:   var(--fs-6);
  font-weight: 600;
  color:       var(--n-900);
  line-height: 1;
}

.event-detail__reviews-stars {
  color:     var(--brand-spark);
  font-size: var(--fs-3);
  margin:    var(--sp-2) 0;
}

.event-detail__reviews-count {
  color:     var(--n-500);
  font-size: var(--fs-1);
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.event-detail__reviews-bars {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    flex;
  flex-direction: column;
  gap:        var(--sp-2);
}

.event-detail__reviews-bar-row {
  display:     grid;
  grid-template-columns: 24px 1fr 36px;
  align-items: center;
  gap:         var(--sp-3);
  font-size:   var(--fs-1);
  color:       var(--n-700);
}

.event-detail__reviews-bar-track {
  display:          block;
  height:           8px;
  background-color: var(--n-100);
  border-radius:    var(--r-1);
  overflow:         hidden;
}

.event-detail__reviews-bar-fill {
  display:          block;
  height:           100%;
  background-color: var(--brand-ink);
  border-radius:    var(--r-1);
  transition:       width var(--d-3) var(--ease-out-swift);
}

.event-detail__reviews-list {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    flex;
  flex-direction: column;
  gap:        var(--sp-4);
}

.event-detail__review {
  padding:          var(--sp-5);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
}

.event-detail__review-header {
  display:        grid;
  grid-template-columns: auto 1fr auto;
  align-items:    center;
  gap:            var(--sp-3);
  margin-bottom:  var(--sp-3);
}

.event-detail__review-avatar {
  width:            44px;
  height:           44px;
  border-radius:    50%;
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  color:            var(--n-0);
  font-family:      var(--font-mono);
  font-weight:      700;
  font-size:        var(--fs-2);
  flex-shrink:      0;
}

.review-avatar--g1 { background-color: var(--brand-ink); }
.review-avatar--g2 { background-color: var(--state-success); }
.review-avatar--g3 { background-color: var(--brand-spark); color: var(--brand-on-spark); }
.review-avatar--g4 { background-color: var(--state-info); }
.review-avatar--g5 { background-color: var(--n-800); }

.event-detail__review-name {
  font-size:   var(--fs-2);
  font-weight: 600;
  color:       var(--n-900);
}

.event-detail__review-date {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  color:       var(--n-500);
}

.event-detail__review-stars {
  color:     var(--brand-spark);
  font-size: var(--fs-2);
}

.event-detail__review-text {
  color:       var(--n-700);
  font-size:   var(--fs-2);
  line-height: 1.6;
  margin:      0;
}

/* Sidebar --------------------------------------------------------------------- */

.event-detail__sidebar {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-5);
  position:       sticky;
  top:            var(--sp-6);
}

@media (max-width: 991px) {
  .event-detail__sidebar {
    position: static;
  }
}

.event-detail__panel {
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  padding:          var(--sp-5);
  box-shadow:       var(--shadow-1);
}

.event-detail__panel--tickets {
  border-top: 4px solid var(--brand-ink);
}

.event-detail__panel-title {
  font-family:   var(--font-serif);
  font-size:     var(--fs-4);
  font-weight:   600;
  color:         var(--n-900);
  margin:        0 0 var(--sp-4);
}

.event-detail__panel-title--spaced {
  margin-top: var(--sp-5);
}

/* 2026-06-02-event-detail-ticket-price-display — informational "from price"
   / range label above the Get-tickets CTA. Mono face for the numeric/data
   read per the project typography scale; recessive weight so it supports the
   CTA rather than competing with it. */
.event-detail__from-price {
  margin:      0 0 var(--sp-3);
  font-family: var(--font-mono);
  font-size:   var(--fs-3);
  font-weight: 600;
  color:       var(--n-900);
  text-align:  center;
}

.event-detail__buy-btn {
  width:            100%;
  min-height:       48px;
  padding:          var(--sp-3) var(--sp-5);
  border:           none;
  border-radius:    var(--r-5);
  background-color: var(--brand-ink);
  color:            var(--n-0);
  font-family:      var(--font-sans);
  font-size:        var(--fs-3);
  font-weight:      600;
  cursor:           pointer;
  transition:       background-color var(--d-1) var(--ease-out-swift),
                    transform var(--d-1) var(--ease-out-swift);
}

.event-detail__buy-btn:hover:not(:disabled),
.event-detail__buy-btn:focus-visible:not(:disabled) {
  background-color: var(--brand-spark);
  /* F-4b-1: routed through --brand-on-spark; default tier resolves to
     --brand-ink (6.87:1), HC tier flips to --n-0 on darkened spark
     #8B4500 (7.12:1 PASS AAA) so the warm CTA stays legible. */
  color:            var(--brand-on-spark);
}

.event-detail__buy-btn:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.event-detail__buy-btn:disabled {
  background-color: var(--n-300);
  color:            var(--n-500);
  cursor:           not-allowed;
}

.event-detail__panel-note {
  margin:    var(--sp-3) 0 0;
  font-size: var(--fs-1);
  color:     var(--n-500);
  text-align: center;
}

.event-detail__organizer {
  display:        grid;
  grid-template-columns: auto 1fr;
  align-items:    center;
  gap:            var(--sp-3);
  margin-bottom:  var(--sp-3);
}

.event-detail__organizer-avatar {
  width:            48px;
  height:           48px;
  border-radius:    50%;
  background-color: var(--brand-ink);
  color:            var(--n-0);
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  font-family:      var(--font-mono);
  font-weight:      700;
  font-size:        var(--fs-2);
}

.event-detail__organizer-name {
  font-size:   var(--fs-2);
  font-weight: 600;
  color:       var(--n-900);
  display:     flex;
  align-items: center;
  gap:         var(--sp-1);
}

.event-detail__organizer-label {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  color:       var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.event-detail__organizer-bio {
  font-size:   var(--fs-2);
  color:       var(--n-700);
  line-height: 1.6;
  margin:      var(--sp-3) 0;
}

.event-detail__verified-icon {
  color:     var(--state-success);
  font-size: var(--fs-3);
  display:   inline-flex;
  align-items: center;
}

.event-detail__whatsapp-btn {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  gap:              var(--sp-2);
  width:            100%;
  min-height:       44px;
  padding:          0 var(--sp-4);
  margin-top:       var(--sp-3);
  border:           1px solid var(--state-success);
  border-radius:    var(--r-5);
  background-color: var(--n-0);
  color:            var(--state-success);
  font-family:      var(--font-sans);
  font-size:        var(--fs-2);
  font-weight:      600;
  text-decoration:  none;
  transition:       background-color var(--d-1) var(--ease-out-swift),
                    color var(--d-1) var(--ease-out-swift);
}

.event-detail__whatsapp-btn:hover,
.event-detail__whatsapp-btn:focus-visible {
  background-color: var(--state-success);
  color:            var(--n-0);
}

.event-detail__info-list {
  margin-top: var(--sp-4);
}

.event-detail__info-row {
  display:         flex;
  justify-content: space-between;
  align-items:     center;
  padding:         var(--sp-3) 0;
  border-bottom:   1px solid var(--n-100);
}

.event-detail__info-row:last-child {
  border-bottom: none;
}

.event-detail__info-label {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  color:       var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0;
}

.event-detail__info-value {
  font-size:   var(--fs-2);
  color:       var(--n-900);
  font-weight: 500;
  margin: 0;
}

.event-detail__share-buttons {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    flex;
  flex-wrap:  wrap;
  gap:        var(--sp-2);
}

.event-detail__share-btn {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  width:            44px;
  height:           44px;
  border:           1px solid var(--n-200);
  border-radius:    50%;
  background-color: var(--n-0);
  color:            var(--n-700);
  cursor:           pointer;
  transition:       background-color var(--d-1) var(--ease-out-swift),
                    color var(--d-1) var(--ease-out-swift),
                    border-color var(--d-1) var(--ease-out-swift);
}

.event-detail__share-btn:hover,
.event-detail__share-btn:focus-visible {
  border-color: var(--brand-ink);
  color:        var(--brand-ink);
}

.event-detail__share-btn:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.event-detail__short-link {
  margin:    var(--sp-3) 0 0;
  font-size: var(--fs-1);
  color:     var(--n-500);
}

.event-detail__short-link a {
  color:           var(--brand-ink);
  text-decoration: underline;
}

/* Phase 9 (M52) — `.event-detail__copy-toast` + `--visible` rules deleted (F-2-03).
   The site-wide [data-action="copy-link"] handler in wwwroot/js/public.js
   flashes aria-label on the copy button itself; no separate toast element exists
   in the DOM. `.event-detail__copy-fallback` is retained below as it provides a
   hidden positioning class still usable by future copy fallbacks if needed —
   but is currently orphaned and may be removed in a future cleanup. */

.event-detail__copy-fallback {
  position: fixed;
  left:     -9999px;
  top:      0;
  opacity:  0;
}

@media (prefers-reduced-motion: reduce) {
  .event-detail__buy-btn,
  .event-detail__share-btn,
  .event-detail__location-action,
  .event-detail__whatsapp-btn,
  .event-detail__reviews-bar-fill {
    transition: none;
  }
}


/* ==========================================================================
   VENDOR MARKETPLACE (M07 W4.5)
   Public list page: Hero --sm + FilterBar + ContentCard grid.
   Token-driven; no raw hex; no raw ms.
   ========================================================================== */

.vendor-marketplace {
  background-color: var(--n-50);
  padding:          var(--sp-7) 0 var(--sp-8);
}

.vendor-marketplace__container {
  width:     100%;
  max-width: 1280px;
  margin:    0 auto;
  padding:   0 var(--sp-5);
}

.vendor-marketplace__filters {
  margin-bottom: var(--sp-5);
}

.vendor-marketplace__grid {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap:        var(--sp-5);
}

.vendor-marketplace__grid-item {
  margin: 0;
}

.vendor-marketplace__empty {
  padding:          var(--sp-7) var(--sp-5);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  text-align:       center;
}

.vendor-marketplace__empty-headline {
  font-family: var(--font-serif);
  font-size:   var(--fs-4);
  color:       var(--n-900);
  margin:      0 0 var(--sp-2);
}

.vendor-marketplace__empty-hint {
  font-size: var(--fs-2);
  color:     var(--n-500);
  margin:    0;
}

.vendor-marketplace__pagination {
  display:        flex;
  justify-content: center;
  margin-top:     var(--sp-7);
}

.vendor-marketplace__load-more {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  min-height:       44px;
  padding:          0 var(--sp-7);
  border:           1px solid var(--brand-ink);
  border-radius:    var(--r-5);
  background-color: var(--n-0);
  color:            var(--brand-ink);
  font-family:      var(--font-sans);
  font-size:        var(--fs-2);
  font-weight:      600;
  text-decoration:  none;
  transition:       background-color var(--d-1) var(--ease-out-swift),
                    color var(--d-1) var(--ease-out-swift);
}

.vendor-marketplace__load-more:hover,
.vendor-marketplace__load-more:focus-visible {
  background-color: var(--brand-ink);
  color:            var(--n-0);
}

.vendor-marketplace__load-more:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .vendor-marketplace__load-more {
    transition: none;
  }
}


/* ==========================================================================
   VENDOR CONSULTING (M50 Phase 15)
   Public /vendor-consulting page (Views/Public/VendorConsulting.cshtml) plus
   the CTA block injected at the bottom of /vendors
   (Views/Public/VendorMarketplace.cshtml). All tokens — no raw hex / ms.
   ========================================================================== */

.vendor-consulting {
  background-color: var(--n-50);
  padding:          var(--sp-7) 0 var(--sp-8);
}

.vendor-consulting__bullets {
  list-style: none;
  margin:     var(--sp-5) 0 0 0;
  padding:    0;
  display:    grid;
  gap:        var(--sp-3);
}

.vendor-consulting__bullets li {
  display:     flex;
  align-items: flex-start;
  gap:         var(--sp-3);
  font-family: var(--font-sans);
  font-size:   var(--fs-2);
  color:       var(--n-700);
  line-height: 1.6;
}

.vendor-consulting__bullets li i {
  flex-shrink: 0;
  font-size:   var(--fs-3);
  color:       var(--state-success);
  margin-top:  2px;
}

.vendor-consulting__status {
  margin-top:    var(--sp-4);
  padding:       var(--sp-3) var(--sp-4);
  border-radius: var(--r-3);
  font-family:   var(--font-sans);
  font-size:     var(--fs-2);
  line-height:   1.5;
}

.vendor-consulting__status[data-status="success"] {
  background-color: color-mix(in srgb, var(--state-success) 12%, transparent);
  color:            var(--state-success);
}

.vendor-consulting__status[data-status="error"] {
  background-color: color-mix(in srgb, var(--state-danger) 12%, transparent);
  color:            var(--state-danger);
}

.vendor-consulting-cta {
  display:          flex;
  flex-direction:   column;
  gap:              var(--sp-5);
  margin-top:       var(--sp-7);
  padding:          var(--sp-7);
  border-radius:    var(--r-5);
  background-color: var(--brand-ink);
  color:            var(--n-0);
}

.vendor-consulting-cta__eyebrow {
  margin:        0 0 var(--sp-2) 0;
  font-family:   var(--font-mono);
  font-size:     var(--fs-1);
  font-weight:   600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color:         var(--brand-spark);
}

.vendor-consulting-cta__headline {
  margin:      0 0 var(--sp-3) 0;
  font-family: var(--font-serif);
  font-size:   var(--fs-4);
  font-weight: 700;
  line-height: 1.25;
  color:       var(--n-0);
}

.vendor-consulting-cta__subcopy {
  margin:      0;
  font-family: var(--font-sans);
  font-size:   var(--fs-2);
  line-height: 1.6;
  color:       var(--n-200);
  max-width:   60ch;
}

.vendor-consulting-cta__action {
  display: flex;
}

.vendor-consulting-cta__action .btn--primary {
  min-height:       44px;
  padding:          0 var(--sp-6);
  background-color: var(--brand-spark);
  color:            var(--brand-ink);
  border:           none;
  border-radius:    var(--r-4);
  font-family:      var(--font-sans);
  font-size:        var(--fs-2);
  font-weight:      600;
  text-decoration:  none;
  transition:       background-color var(--d-1) var(--ease-out-swift);
}

.vendor-consulting-cta__action .btn--primary:hover,
.vendor-consulting-cta__action .btn--primary:focus-visible {
  background-color: color-mix(in srgb, var(--brand-spark) 85%, white);
}

.vendor-consulting-cta__action .btn--primary:focus-visible {
  outline:        2px solid var(--n-0);
  outline-offset: 2px;
}

@media (min-width: 768px) {
  .vendor-consulting-cta {
    flex-direction: row;
    align-items:    center;
    justify-content: space-between;
  }

  .vendor-consulting-cta__body {
    flex: 1 1 auto;
  }

  .vendor-consulting-cta__action {
    flex-shrink: 0;
  }
}

@media (prefers-reduced-motion: reduce) {
  .vendor-consulting-cta__action .btn--primary {
    transition: none;
  }
}


/* ==========================================================================
   TOUR DETAIL (M07 W4.7)
   Composition layer over the Hero kit for /tours/{slug}.
   Two-column main+sidebar layout. Map container preserved per Phase 2
   anti-instruction; Phase 5 expands it.
   ========================================================================== */

.tour-detail {
  background-color: var(--n-50);
  padding:          var(--sp-7) 0 var(--sp-8);
}

.tour-detail__container {
  width:     100%;
  max-width: 1280px;
  margin:    0 auto;
  padding:   0 var(--sp-5);
}

.tour-detail__layout {
  display:               grid;
  grid-template-columns: 1fr 380px;
  gap:                   var(--sp-7);
  align-items:           start;
}

@media (max-width: 991px) {
  .tour-detail__layout {
    grid-template-columns: 1fr;
  }
}

.tour-detail__main {
  min-width: 0;
}

.tour-detail__section {
  margin-bottom: var(--sp-7);
}

.tour-detail__section-title {
  font-family:    var(--font-serif);
  font-size:      var(--fs-5);
  font-weight:    600;
  color:          var(--n-900);
  margin:         0 0 var(--sp-4);
  letter-spacing: -0.01em;
}

.tour-detail__prose {
  color:       var(--n-700);
  font-size:   var(--fs-3);
  line-height: 1.7;
}

.tour-detail__prose p {
  margin: 0 0 var(--sp-4);
}

.tour-detail__policy-text {
  white-space: pre-line;
  color:       var(--n-700);
  font-size:   var(--fs-3);
  line-height: 1.7;
}

/* Read More/Less disclosure for the long policy text. Native <details>/<summary>;
   no JS. Mirrors the .tour-detail__itinerary-summary disclosure (mono/uppercase
   brand-ink label + --brand-spark focus ring), adding a 44x44 touch target, a
   tokenised marker (default browser triangle suppressed), a CSS-only collapsed/
   expanded label swap, and a reduced-motion fallback. */
.tour-detail__policy-summary {
  display:        inline-flex;
  align-items:    center;
  gap:            var(--sp-2);
  min-height:     44px;
  min-width:      44px;
  padding:        var(--sp-2) 0;
  cursor:         pointer;
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  font-weight:    600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color:          var(--brand-ink);
  list-style:     none;
}

/* Suppress the default disclosure triangle (untokenised) in WebKit/Blink and
   the standards-track marker pseudo-element. */
.tour-detail__policy-summary::-webkit-details-marker {
  display: none;
}

.tour-detail__policy-summary::marker {
  content: "";
}

/* Tokenised marker + label, swapped by [open] state with no JS. */
.tour-detail__policy-summary-label {
  display:     inline-flex;
  align-items: center;
  gap:         var(--sp-2);
}

.tour-detail__policy-summary-label::before {
  content:        "\F0140"; /* mdi chevron-down */
  font-family:    "Material Design Icons";
  font-weight:    400;
  font-size:      var(--fs-3);
  line-height:    1;
  color:          var(--brand-spark);
  transition:     transform var(--d-1) var(--ease-out-swift);
}

.tour-detail__policy-details[open] .tour-detail__policy-summary-label::before {
  transform: rotate(180deg);
}

/* Real-text-node labels swapped by [open] state with no JS. The collapsed state
   shows "Read more"; the expanded state shows "Read less". The visible text IS
   the accessible name (no aria-label), so it updates with state per WCAG 2.5.3. */
.tour-detail__policy-summary-more,
.tour-detail__policy-summary-less {
  display:     inline-flex;
  align-items: center;
}

.tour-detail__policy-summary-less {
  display: none;
}

.tour-detail__policy-details[open] .tour-detail__policy-summary-more {
  display: none;
}

.tour-detail__policy-details[open] .tour-detail__policy-summary-less {
  display: inline-flex;
}

.tour-detail__policy-summary:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.tour-detail__policy-details[open] .tour-detail__policy-text {
  margin-top: var(--sp-3);
}

@media (prefers-reduced-motion: reduce) {
  .tour-detail__policy-summary-label::before {
    transition: none;
  }
}

/* Highlights ----------------------------------------------------------------- */

.tour-detail__highlights {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap:        var(--sp-4);
}

.tour-detail__highlight {
  display:          flex;
  align-items:      flex-start;
  gap:              var(--sp-3);
  padding:          var(--sp-4);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
}

.tour-detail__highlight-icon {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  width:            44px;
  height:           44px;
  border-radius:    var(--r-2);
  background-color: var(--n-50);
  color:            var(--state-success);
  font-size:        var(--fs-3);
  flex-shrink:      0;
}

.tour-detail__highlight-title {
  font-family: var(--font-sans);
  font-size:   var(--fs-2);
  font-weight: 600;
  color:       var(--n-900);
  margin:      0 0 var(--sp-1);
}

.tour-detail__highlight-desc {
  font-size: var(--fs-1);
  color:     var(--n-600);
  margin:    0;
  line-height: 1.5;
}

/* Itinerary ------------------------------------------------------------------ */

.tour-detail__itinerary {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    flex;
  flex-direction: column;
  gap:        var(--sp-4);
}

.tour-detail__itinerary-day {
  display:          grid;
  grid-template-columns: auto 1fr;
  gap:              var(--sp-4);
  padding:          var(--sp-5);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
}

.tour-detail__itinerary-marker {
  width:            48px;
  height:           48px;
  border-radius:    50%;
  background-color: var(--brand-ink);
  color:            var(--n-0);
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  font-family:      var(--font-mono);
  font-weight:      700;
  font-size:        var(--fs-2);
  flex-shrink:      0;
}

.tour-detail__itinerary-body {
  min-width: 0;
}

.tour-detail__itinerary-title {
  font-family: var(--font-serif);
  font-size:   var(--fs-3);
  font-weight: 600;
  color:       var(--n-900);
  margin:      0 0 var(--sp-2);
}

.tour-detail__itinerary-desc {
  font-size:   var(--fs-2);
  color:       var(--n-700);
  line-height: 1.6;
  margin:      0;
}

/* Kit/_Prose plain-text branch wraps the description in <div class="...-desc"><p>…</p></div>,
   so zero the inner <p> margin (browser default is 1em 0) to match the bare-<p> spacing this
   class had before, mirroring the .tour-detail__prose p precedent above. */
.tour-detail__itinerary-desc p {
  margin: 0;
}

.tour-detail__itinerary-details {
  margin-top: var(--sp-3);
}

.tour-detail__itinerary-summary {
  cursor:      pointer;
  font-size:   var(--fs-1);
  font-weight: 600;
  color:       var(--brand-ink);
  font-family: var(--font-mono);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tour-detail__itinerary-summary:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.tour-detail__itinerary-extra {
  font-size:   var(--fs-2);
  color:       var(--n-600);
  line-height: 1.6;
  margin:      var(--sp-3) 0 0;
}

/* Inclusions / Exclusions ---------------------------------------------------- */

.tour-detail__inclusions {
  display:               grid;
  grid-template-columns: 1fr 1fr;
  gap:                   var(--sp-4);
}

@media (max-width: 768px) {
  .tour-detail__inclusions {
    grid-template-columns: 1fr;
  }
}

.tour-detail__inclusions-col {
  padding:          var(--sp-4);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
}

.tour-detail__inclusions-col--included {
  border-left: 4px solid var(--state-success);
}

.tour-detail__inclusions-col--excluded {
  border-left: 4px solid var(--state-danger);
}

.tour-detail__inclusions-title {
  display:     flex;
  align-items: center;
  gap:         var(--sp-2);
  font-family: var(--font-sans);
  font-size:   var(--fs-3);
  font-weight: 600;
  margin:      0 0 var(--sp-3);
  color:       var(--n-900);
}

.tour-detail__inclusions-col--included .tour-detail__inclusions-title i {
  color: var(--state-success);
}

.tour-detail__inclusions-col--excluded .tour-detail__inclusions-title i {
  color: var(--state-danger);
}

.tour-detail__inclusions-list {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    flex;
  flex-direction: column;
  gap:        var(--sp-2);
  font-size:  var(--fs-2);
  color:      var(--n-700);
}

/* Map container -------------------------------------------------------------- */

.tour-detail__map {
  display:          flex;
  align-items:      center;
  justify-content:  center;
  min-height:       240px;
  background-color: var(--n-100);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  /* M11 P1 W8.2: lift n-500 -> n-600 on n-100 background (4.39 -> 6.87 AA). */
  color:            var(--n-600);
}

.tour-detail__map-fallback {
  display:     flex;
  align-items: center;
  gap:         var(--sp-3);
  font-size:   var(--fs-3);
  font-family: var(--font-mono);
  margin:      0;
}

/* Reviews -------------------------------------------------------------------- */

.tour-detail__reviews-summary {
  display:          flex;
  align-items:      center;
  gap:              var(--sp-5);
  padding:          var(--sp-5);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  margin-bottom:    var(--sp-5);
}

.tour-detail__reviews-number {
  font-family: var(--font-serif);
  font-size:   var(--fs-6);
  font-weight: 600;
  color:       var(--n-900);
  line-height: 1;
}

.tour-detail__reviews-stars {
  color:     var(--brand-spark);
  font-size: var(--fs-3);
}

.tour-detail__reviews-count {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  color:       var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tour-detail__reviews-list {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    flex;
  flex-direction: column;
  gap:        var(--sp-4);
}

.tour-detail__review {
  padding:          var(--sp-5);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
}

.tour-detail__review-header {
  display:        grid;
  grid-template-columns: auto 1fr auto;
  align-items:    center;
  gap:            var(--sp-3);
  margin-bottom:  var(--sp-3);
}

.tour-detail__review-avatar {
  width:            44px;
  height:           44px;
  border-radius:    50%;
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  background-color: var(--state-success);
  color:            var(--n-0);
  font-family:      var(--font-mono);
  font-weight:      700;
  font-size:        var(--fs-2);
}

.tour-detail__review-name {
  font-size:   var(--fs-2);
  font-weight: 600;
  color:       var(--n-900);
}

.tour-detail__review-date {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  color:       var(--n-500);
}

.tour-detail__review-stars {
  color:     var(--brand-spark);
  font-size: var(--fs-2);
}

.tour-detail__review-text {
  color:       var(--n-700);
  font-size:   var(--fs-2);
  line-height: 1.6;
  margin:      0;
}

/* Sidebar -------------------------------------------------------------------- */

.tour-detail__sidebar {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-5);
  position:       sticky;
  top:            var(--sp-6);
}

@media (max-width: 991px) {
  .tour-detail__sidebar {
    position: static;
  }
}

.tour-detail__panel {
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  padding:          var(--sp-5);
  box-shadow:       var(--shadow-1);
}

.tour-detail__panel--pricing {
  border-top: 4px solid var(--state-success);
}

.tour-detail__panel--favorite {
  padding: var(--sp-4);
}

.tour-detail__panel-header {
  margin-bottom: var(--sp-4);
}

.tour-detail__panel-title {
  font-family:   var(--font-serif);
  font-size:     var(--fs-4);
  font-weight:   600;
  color:         var(--n-900);
  margin:        0 0 var(--sp-1);
}

.tour-detail__panel-subtitle {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  color:       var(--n-500);
  margin:      0;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tour-detail__pricing-tiers {
  list-style: none;
  margin:     0 0 var(--sp-4);
  padding:    0;
  display:    flex;
  flex-direction: column;
  gap:        var(--sp-2);
}

.tour-detail__pricing-tier {
  position:         relative;
  display:          flex;
  flex-direction:   column;
  gap:              var(--sp-1);
  width:            100%;
  min-height:       44px;
  padding:          var(--sp-3) var(--sp-4);
  border:           2px solid var(--n-200);
  border-radius:    var(--r-3);
  background-color: var(--n-0);
  text-align:       left;
  cursor:           pointer;
  transition:       border-color var(--d-1) var(--ease-out-swift),
                    background-color var(--d-1) var(--ease-out-swift);
}

.tour-detail__pricing-tier:hover,
.tour-detail__pricing-tier:focus-visible {
  border-color: var(--brand-ink);
}

.tour-detail__pricing-tier:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.tour-detail__pricing-tier--selected {
  border-color:     var(--state-success);
  background-color: var(--n-50);
}

.tour-detail__pricing-tier-badge {
  position:         absolute;
  top:              calc(var(--sp-2) * -1);
  right:            var(--sp-3);
  padding:          var(--sp-1) var(--sp-3);
  border-radius:    var(--r-5);
  background-color: var(--brand-spark);
  /* F-4b-1: brand-on-spark indirection — flips to --n-0 in HC mode so the
     badge legend stays legible on the darkened bronze fill. */
  color:            var(--brand-on-spark);
  font-family:      var(--font-mono);
  font-size:        var(--fs-1);
  font-weight:      700;
  text-transform:   uppercase;
  letter-spacing:   0.04em;
}

.tour-detail__pricing-tier-name {
  font-size:   var(--fs-3);
  font-weight: 600;
  color:       var(--n-900);
}

.tour-detail__pricing-tier-desc {
  font-size: var(--fs-1);
  color:     var(--n-600);
}

.tour-detail__pricing-tier-price {
  font-family: var(--font-serif);
  font-size:   var(--fs-4);
  color:       var(--state-success);
  font-weight: 600;
}

.tour-detail__pricing-tier-unit {
  font-family: var(--font-sans);
  font-size:   var(--fs-1);
  color:       var(--n-500);
  font-weight: 400;
}

.tour-detail__field {
  margin-bottom: var(--sp-4);
}

.tour-detail__field-label {
  display:     flex;
  align-items: center;
  gap:         var(--sp-2);
  font-family: var(--font-sans);
  font-size:   var(--fs-1);
  font-weight: 600;
  color:       var(--n-700);
  margin-bottom: var(--sp-2);
}

.tour-detail__field-select {
  width:            100%;
  min-height:       44px;
  padding:          0 var(--sp-3);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-2);
  background-color: var(--n-0);
  font-family:      var(--font-sans);
  font-size:        var(--fs-2);
  color:            var(--n-800);
}

.tour-detail__field-select:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.tour-detail__people-counter {
  display:     flex;
  align-items: center;
  gap:         var(--sp-3);
}

.tour-detail__qty-btn {
  width:            44px;
  height:           44px;
  border-radius:    50%;
  border:           1px solid var(--n-300);
  background-color: var(--n-0);
  font-size:        var(--fs-3);
  cursor:           pointer;
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  transition:       background-color var(--d-1) var(--ease-out-swift);
}

.tour-detail__qty-btn:hover,
.tour-detail__qty-btn:focus-visible {
  background-color: var(--n-100);
}

.tour-detail__qty-btn:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.tour-detail__people-count {
  font-size:   var(--fs-3);
  font-weight: 700;
  min-width:   28px;
  text-align:  center;
}

.tour-detail__book-btn {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  gap:              var(--sp-2);
  width:            100%;
  min-height:       48px;
  padding:          0 var(--sp-5);
  border:           none;
  border-radius:    var(--r-5);
  background-color: var(--state-success);
  color:            var(--n-0);
  font-family:      var(--font-sans);
  font-size:        var(--fs-3);
  font-weight:      600;
  cursor:           pointer;
  text-decoration:  none;
  margin-top:       var(--sp-3);
  transition:       background-color var(--d-1) var(--ease-out-swift),
                    color var(--d-1) var(--ease-out-swift);
}

.tour-detail__book-btn:hover,
.tour-detail__book-btn:focus-visible {
  background-color: var(--brand-ink);
  color:            var(--n-0);
}

.tour-detail__book-btn:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.tour-detail__book-btn--quote {
  background-color: var(--brand-ink);
}

.tour-detail__book-note {
  margin:     var(--sp-3) 0 0;
  font-size:  var(--fs-1);
  color:      var(--n-500);
  text-align: center;
}

/* Booking review recap (2026-06-02-tour-prepay-summary-page) -----------------
   Display-only review panel revealed inside the booking drawer between the
   buyer fields and the two-state submit button. Recessed --n-50 fill so it
   reads as a summary surface distinct from the white form fields above; the
   advisory total uses the same serif/--state-success treatment as
   .tour-detail__pricing-tier-price for visual continuity. Tokens only. */
.tour-detail__booking-recap {
  margin-top:       var(--sp-4);
  padding:          var(--sp-4);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  background-color: var(--n-50);
  /* Subtle reveal; disabled under prefers-reduced-motion below. */
  animation: tour-detail-recap-in var(--d-2) var(--ease-out-swift);
}

@keyframes tour-detail-recap-in {
  from { opacity: 0; transform: translateY(var(--sp-2)); }
  to   { opacity: 1; transform: translateY(0); }
}

.tour-detail__booking-recap-title {
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  font-weight:    700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color:          var(--n-500);
  margin:         0 0 var(--sp-3);
}

.tour-detail__booking-recap-list {
  margin:  0 0 var(--sp-3);
  padding: 0;
}

.tour-detail__booking-recap-row {
  display:         flex;
  align-items:     baseline;
  justify-content: space-between;
  gap:             var(--sp-4);
  padding:         var(--sp-2) 0;
  border-bottom:   1px solid var(--n-200);
}

.tour-detail__booking-recap-list .tour-detail__booking-recap-row:last-child {
  border-bottom: none;
}

.tour-detail__booking-recap-label {
  flex:        0 0 auto;
  font-family: var(--font-sans);
  font-size:   var(--fs-1);
  font-weight: 600;
  color:       var(--n-600);
  margin:      0;
}

.tour-detail__booking-recap-value {
  flex:        1 1 auto;
  text-align:  right;
  font-size:   var(--fs-2);
  color:       var(--n-900);
  margin:      0;
  overflow-wrap: anywhere;
}

.tour-detail__booking-recap-breakdown {
  margin-top: var(--sp-3);
}

.tour-detail__booking-recap-row--breakdown {
  border-bottom: none;
  font-size:     var(--fs-2);
  color:         var(--n-700);
}

.tour-detail__booking-recap-tier {
  font-weight: 600;
  color:       var(--n-800);
}

.tour-detail__booking-recap-line {
  font-family: var(--font-mono);
  color:       var(--n-600);
}

.tour-detail__booking-recap-row--total {
  border-top:    1px solid var(--n-300);
  border-bottom: none;
  padding-top:   var(--sp-3);
  margin-top:    var(--sp-2);
}

.tour-detail__booking-recap-total-label {
  font-family: var(--font-sans);
  font-size:   var(--fs-2);
  font-weight: 600;
  color:       var(--n-700);
}

.tour-detail__booking-recap-total {
  font-family: var(--font-serif);
  font-size:   var(--fs-4);
  font-weight: 600;
  color:       var(--state-success);
}

.tour-detail__booking-recap-note {
  display:     flex;
  align-items: center;
  gap:         var(--sp-2);
  margin:      var(--sp-3) 0 0;
  font-size:   var(--fs-1);
  color:       var(--n-500);
}

@media (prefers-reduced-motion: reduce) {
  .tour-detail__booking-recap {
    animation: none;
  }
}

.tour-detail__tier-details {
  margin-bottom: var(--sp-3);
  font-size:     var(--fs-1);
  color:         var(--n-600);
}

/* Operator card -------------------------------------------------------------- */

.tour-detail__operator {
  display:        grid;
  grid-template-columns: auto 1fr;
  align-items:    center;
  gap:            var(--sp-3);
}

.tour-detail__operator-avatar {
  width:            48px;
  height:           48px;
  border-radius:    50%;
  background-color: var(--brand-ink);
  color:            var(--n-0);
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  font-family:      var(--font-mono);
  font-weight:      700;
  font-size:        var(--fs-2);
}

.tour-detail__operator-name {
  font-size:   var(--fs-2);
  font-weight: 600;
  color:       var(--n-900);
  display:     flex;
  align-items: center;
  gap:         var(--sp-1);
}

.tour-detail__operator-label {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  color:       var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.tour-detail__operator-desc {
  font-size:   var(--fs-2);
  color:       var(--n-700);
  line-height: 1.6;
  margin:      var(--sp-3) 0 0;
}

.tour-detail__verified-icon {
  color:       var(--state-success);
  font-size:   var(--fs-3);
  display:     inline-flex;
  align-items: center;
}

.tour-detail__info-list {
  margin: 0;
}

.tour-detail__info-row {
  display:         flex;
  justify-content: space-between;
  align-items:     center;
  padding:         var(--sp-3) 0;
  border-bottom:   1px solid var(--n-100);
}

.tour-detail__info-row:last-child {
  border-bottom: none;
}

.tour-detail__info-label {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  color:       var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0;
}

.tour-detail__info-value {
  font-size:   var(--fs-2);
  color:       var(--n-900);
  font-weight: 500;
  margin: 0;
}

/* Quick info strip — banner-adjacent relocation
   (2026-06-02-tour-detail-quickinfo-banner-restructure).
   Renders the booking-critical facts as a tight, scannable horizontal block
   directly under the hero instead of a vertical sidebar panel. The strip is a
   full-width band on the page's --n-50 ground; the inner aligns to the same
   1280px / --sp-5 gutter as .tour-detail__container so it lines up with the
   two-column layout below it. */
.tour-detail__quickbar {
  background-color: var(--n-50);
  padding:          var(--sp-5) 0 0;
}

.tour-detail__quickbar-inner {
  width:            100%;
  max-width:        1280px;
  margin:           0 auto;
  padding:          var(--sp-5);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  box-shadow:       var(--shadow-1);
}

/* Horizontal scannable grid: auto-fit columns wrap from a 6-up strip down to
   fewer columns as width shrinks, each cell stacking label-over-value. This
   overrides the sidebar list's vertical space-between rows. */
.tour-detail__quickbar .tour-detail__info-list {
  display:               grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap:                   var(--sp-4) var(--sp-6);
  align-items:           start;
}

.tour-detail__quickbar .tour-detail__info-row {
  display:        flex;
  flex-direction: column;
  align-items:    flex-start;
  gap:            var(--sp-1);
  padding:        0;
  border-bottom:  none;
}

.tour-detail__quickbar .tour-detail__info-value {
  font-size: var(--fs-3);
}

@media (max-width: 575px) {
  .tour-detail__quickbar .tour-detail__info-list {
    grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
    gap:                   var(--sp-4);
  }
}

@media (prefers-reduced-motion: reduce) {
  .tour-detail__pricing-tier,
  .tour-detail__qty-btn,
  .tour-detail__book-btn {
    transition: none;
  }
}


/* ==========================================================================
   CONTESTANT DETAIL (M07 W4.7)
   Composition layer over the Hero kit for /voting/{slug}/contestants/{slug}.
   Two-column layout (bio + vote) with sidebar for vote CTA + share.
   ========================================================================== */

.contestant-detail {
  background-color: var(--n-50);
  padding:          var(--sp-7) 0 var(--sp-8);
}

.contestant-detail__container {
  width:     100%;
  max-width: 1280px;
  margin:    0 auto;
  padding:   0 var(--sp-5);
}

.contestant-detail__back {
  margin: 0 0 var(--sp-5);
}

.contestant-detail__back-link {
  display:         inline-flex;
  align-items:     center;
  gap:             var(--sp-2);
  font-size:       var(--fs-2);
  color:           var(--n-600);
  text-decoration: none;
  transition:      color var(--d-1) var(--ease-out-swift);
}

.contestant-detail__back-link:hover,
.contestant-detail__back-link:focus-visible {
  color: var(--brand-ink);
}

.contestant-detail__back-link:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.contestant-detail__layout {
  display:               grid;
  grid-template-columns: 1fr 360px;
  gap:                   var(--sp-7);
  align-items:           start;
}

@media (max-width: 991px) {
  .contestant-detail__layout {
    grid-template-columns: 1fr;
  }
}

.contestant-detail__main {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-5);
  min-width:      0;
}

.contestant-detail__panel {
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  padding:          var(--sp-5);
  box-shadow:       var(--shadow-1);
}

.contestant-detail__panel-title {
  display:     flex;
  align-items: center;
  gap:         var(--sp-2);
  font-family: var(--font-serif);
  font-size:   var(--fs-4);
  font-weight: 600;
  color:       var(--n-900);
  margin:      0 0 var(--sp-3);
}

.contestant-detail__bio {
  font-size:   var(--fs-2);
  color:       var(--n-700);
  line-height: 1.7;
  margin:      0;
}

.contestant-detail__bio--empty {
  color:      var(--n-400);
  font-style: italic;
}

.contestant-detail__vote-count {
  font-family: var(--font-serif);
  font-size:   var(--fs-6);
  font-weight: 700;
  color:       var(--state-success);
  line-height: 1;
}

.contestant-detail__vote-label {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  color:       var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin:      var(--sp-1) 0 var(--sp-4);
}

.contestant-detail__vote-progress {
  margin-top: var(--sp-4);
}

.contestant-detail__vote-progress-row {
  display:         flex;
  justify-content: space-between;
  font-size:       var(--fs-1);
  color:           var(--n-600);
  margin-bottom:   var(--sp-2);
}

.contestant-detail__vote-progress-track {
  display:          block;
  height:           10px;
  background-color: var(--n-100);
  border-radius:    var(--r-1);
  overflow:         hidden;
}

.contestant-detail__vote-progress-fill {
  display:          block;
  height:           100%;
  background-color: var(--state-success);
  border-radius:    var(--r-1);
  transition:       width var(--d-3) var(--ease-out-swift);
}

.contestant-detail__vote-ends {
  font-size: var(--fs-1);
  color:     var(--n-500);
  margin:    var(--sp-3) 0 0;
}

.contestant-detail__sidebar {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-5);
  position:       sticky;
  top:            var(--sp-6);
}

@media (max-width: 991px) {
  .contestant-detail__sidebar {
    position: static;
  }
}

.contestant-detail__vote-cta {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  gap:              var(--sp-2);
  width:            100%;
  min-height:       56px;
  padding:          0 var(--sp-5);
  border:           none;
  border-radius:    var(--r-5);
  background-color: var(--state-success);
  color:            var(--n-0);
  font-family:      var(--font-sans);
  font-size:        var(--fs-3);
  font-weight:      600;
  cursor:           pointer;
  transition:       background-color var(--d-1) var(--ease-out-swift);
}

.contestant-detail__vote-cta:hover,
.contestant-detail__vote-cta:focus-visible {
  background-color: var(--brand-ink);
}

.contestant-detail__vote-cta:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.contestant-detail__qr {
  display:        flex;
  flex-direction: column;
  align-items:    center;
  gap:            var(--sp-3);
  margin-bottom:  var(--sp-4);
}

.contestant-detail__qr-frame {
  width:            120px;
  height:           120px;
  border:           1px solid var(--n-200);
  border-radius:    var(--r-2);
  background-color: var(--n-50);
  display:          flex;
  align-items:      center;
  justify-content:  center;
  overflow:         hidden;
}

.contestant-detail__qr-frame img {
  width:      100%;
  height:     100%;
  object-fit: contain;
}

.contestant-detail__qr-placeholder {
  font-size: var(--fs-6);
  color:     var(--n-400);
}

.contestant-detail__qr-label {
  width:      100%;
  text-align: center;
}

.contestant-detail__qr-eyebrow {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  color:       var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin:      0 0 var(--sp-1);
}

.contestant-detail__share-row {
  list-style: none;
  margin:     var(--sp-3) 0 0;
  padding:    0;
  display:    flex;
  flex-wrap:  wrap;
  gap:        var(--sp-2);
}

/* M31 Phase 11 F-11-2 — N24 icon-only mode. Visible <span> labels were
   stripped from the markup; min-width:44px keeps the touch target at
   spec (HR8) since icon-only content would otherwise collapse the link
   width below 44px. justify-content:center keeps the glyph centered
   inside the now-square-ish hit area. */
.contestant-detail__share-link {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  gap:              var(--sp-2);
  min-height:       44px;
  min-width:        44px;
  padding:          0 var(--sp-4);
  border-radius:    var(--r-5);
  font-family:      var(--font-sans);
  font-size:        var(--fs-1);
  font-weight:      600;
  text-decoration:  none;
  transition:       opacity var(--d-1) var(--ease-out-swift);
}

.contestant-detail__share-link:hover,
.contestant-detail__share-link:focus-visible {
  opacity: 0.9;
}

.contestant-detail__share-link:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.contestant-detail__share-link--wa {
  background-color: var(--state-success);
  color:            var(--n-0);
}

.contestant-detail__share-link--x {
  background-color: var(--n-900);
  color:            var(--n-0);
}

.contestant-detail__share-link--fb {
  background-color: var(--state-info);
  color:            var(--n-0);
}

@media (prefers-reduced-motion: reduce) {
  .contestant-detail__back-link,
  .contestant-detail__vote-cta,
  .contestant-detail__share-link,
  .contestant-detail__vote-progress-fill {
    transition: none;
  }
}


/* ==========================================================================
   M07 PHASE 2.5 — PUBLIC SURFACE INLINE-STYLE SWEEP
   --------------------------------------------------------------------------
   Migrated from <style asp-add-nonce> blocks across 22 Views/Public/*.cshtml
   files (sweep authorised by user 2026-04-25 in response to F-0-2). Token
   translation per docs/work/2026-04-18-mandate-07-c4-public-surface/
   sweep-log.md. Green hex (#1B5E20/#2E7D32/#4CAF50) collapsed to --brand-ink
   per CLAUDE.md hard rule 1.
   ========================================================================== */

/* --- Privacy.cshtml + Terms.cshtml — shared .legal-* layout ---------------- */

.legal-hero {
  background:    var(--brand-ink);
  color:         var(--n-0);
  padding:       var(--sp-8) 0;
  text-align:    center;
}
.legal-hero h1 { font-size: var(--fs-6); font-weight: 800; margin-bottom: var(--sp-3); }
.legal-hero p  { font-size: var(--fs-3); opacity: 0.85; }

.legal-body {
  max-width:   800px;
  margin:      var(--sp-7) auto;
  padding:     0 var(--sp-5);
  color:       var(--n-800);
  line-height: 1.8;
}
.legal-body h2 {
  font-size:     var(--fs-4);
  font-weight:   700;
  margin-top:    var(--sp-7);
  margin-bottom: var(--sp-3);
  color:         var(--n-900);
}
.legal-body p           { margin-bottom: var(--sp-4); }
.legal-body ul          { margin: 0 0 var(--sp-4) var(--sp-5); }
.legal-body ul li       { margin-bottom: 6px; }
.legal-meta             { font-size: var(--fs-1); color: var(--n-500); margin-bottom: var(--sp-6); }

/* --- About.cshtml ---------------------------------------------------------- */

.about-hero {
  background:  var(--brand-ink);
  color:       var(--n-0);
  padding:     80px 0;
  text-align:  center;
}
.about-hero h1 { font-size: var(--fs-6); font-weight: 800; margin-bottom: var(--sp-4); }
.about-hero p  { font-size: var(--fs-4); opacity: 0.9; max-width: 600px; margin: 0 auto; }

.stats-bar {
  background:            var(--n-0);
  padding:               0;
  margin-top:            -40px;
  position:              relative;
  z-index:               1;
  border-radius:         var(--r-4);
  box-shadow:            var(--shadow-3);
  display:               grid;
  grid-template-columns: repeat(5, 1fr);
}
.stat-item {
  padding:      var(--sp-6) var(--sp-4);
  text-align:   center;
  border-right: 1px solid var(--n-200);
}
.stat-item:last-child { border: none; }
.stat-number { font-size: var(--fs-6); font-weight: 800; color: var(--brand-ink); }
.stat-label  { font-size: var(--fs-1); color: var(--n-600); margin-top: 4px; }

.story-section { padding: 80px 0; }
.story-grid    { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-8); align-items: center; }
.story-text h2 { font-size: var(--fs-6); font-weight: 800; margin-bottom: var(--sp-5); }
.story-text p  { font-size: var(--fs-3); color: var(--n-600); line-height: 1.8; margin-bottom: var(--sp-4); }
.story-image {
  height:          360px;
  border-radius:   var(--r-4);
  background:      var(--n-100);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       64px;
}

.mission-vision { display: grid; grid-template-columns: 1fr 1fr; gap: var(--sp-6); margin-top: var(--sp-7); }
.mv-card        { padding: var(--sp-6); border-radius: var(--r-4); }
.mv-card.mission { background: var(--n-100); border-left: 4px solid var(--brand-ink); }
.mv-card.vision  { background: var(--n-50);  border-left: 4px solid var(--brand-spark); }
.mv-card h3      { font-size: var(--fs-4); font-weight: 700; margin-bottom: var(--sp-3); }
.mv-card p       { font-size: var(--fs-3); color: var(--n-600); line-height: 1.7; }

.services-section { padding: 80px 0; background: var(--n-50); }
.services-grid    { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-5); }
.about-service-card {
  background:    var(--n-0);
  padding:       28px 20px;
  border-radius: var(--r-3);
  text-align:    center;
  transition:    transform var(--d-2) var(--ease-out-swift),
                 box-shadow var(--d-2) var(--ease-out-swift);
  box-shadow:    var(--shadow-1);
}
.about-service-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-2); }
.about-service-card .icon { font-size: var(--fs-6); margin-bottom: var(--sp-3); }
.about-service-card h4    { font-size: var(--fs-2); font-weight: 700; margin-bottom: 6px; }
.about-service-card p     { font-size: var(--fs-1); color: var(--n-600); }

.values-section { padding: 80px 0; }
.values-grid    { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-6); }
.value-card     { text-align: center; }
.value-icon {
  width:           64px;
  height:          64px;
  border-radius:   50%;
  background:      var(--n-100);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       28px;
  margin:          0 auto var(--sp-4);
}
.value-card h4  { font-size: var(--fs-3); font-weight: 700; margin-bottom: var(--sp-2); }
.value-card p   { font-size: var(--fs-2); color: var(--n-600); }

.team-section { padding: 80px 0; background: var(--n-50); }
.team-grid    { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--sp-5); }
.team-card {
  background:    var(--n-0);
  border-radius: var(--r-4);
  overflow:      hidden;
  box-shadow:    var(--shadow-1);
  transition:    transform var(--d-2) var(--ease-out-swift);
}
.team-card:hover { transform: translateY(-4px); }
.team-photo {
  height:          200px;
  background:      var(--brand-ink);
  display:         flex;
  align-items:     center;
  justify-content: center;
  color:           var(--n-0);
  font-size:       48px;
  font-weight:     800;
}
.team-info        { padding: 20px; text-align: center; }
.team-info h4     { font-size: var(--fs-3); font-weight: 700; }
.team-info .role  { font-size: var(--fs-1); color: var(--brand-spark); font-weight: 600; margin-top: 4px; }
.team-info p      { font-size: var(--fs-1); color: var(--n-600); margin-top: var(--sp-2); }

.partners-section { padding: var(--sp-8) 0; text-align: center; }
.partners-grid    { display: flex; flex-wrap: wrap; justify-content: center; gap: var(--sp-6); margin-top: var(--sp-6); }
.partner-badge {
  padding:       var(--sp-4) var(--sp-6);
  background:    var(--n-50);
  border-radius: var(--r-3);
  font-weight:   700;
  font-size:     var(--fs-2);
  color:         var(--n-600);
}

.cta-section {
  background:  var(--brand-ink);
  color:       var(--n-0);
  padding:     var(--sp-8) 0;
  text-align:  center;
}
.cta-section h2 { font-size: var(--fs-6); font-weight: 800; margin-bottom: var(--sp-4); }
.cta-section p  { font-size: var(--fs-4); opacity: 0.9; margin-bottom: var(--sp-6); }

@media (max-width: 768px) {
  .about-hero h1                 { font-size: var(--fs-5); }
  .stats-bar                     { grid-template-columns: repeat(2, 1fr); margin-top: -24px; }
  .stat-item:nth-child(2)        { border-right: none; }
  .stat-item:nth-child(4)        { border-right: none; }
  .story-grid                    { grid-template-columns: 1fr; gap: var(--sp-6); }
  .story-image                   { height: 200px; }
  .mission-vision                { grid-template-columns: 1fr; }
  .services-grid                 { grid-template-columns: repeat(2, 1fr); }
  .values-grid                   { grid-template-columns: 1fr 1fr; }
  .team-grid                     { grid-template-columns: 1fr 1fr; }
}

/* --- Contact.cshtml -------------------------------------------------------- */

.contact-hero {
  background:  var(--brand-ink);
  color:       var(--n-0);
  padding:     var(--sp-8) 0;
  text-align:  center;
}
.contact-hero h1 { font-size: var(--fs-6); font-weight: 800; margin-bottom: var(--sp-3); }
.contact-hero p  { font-size: var(--fs-4); opacity: 0.9; max-width: 540px; margin: 0 auto; }

.contact-cards {
  display:                grid;
  grid-template-columns:  repeat(3, 1fr);
  gap:                    var(--sp-5);
  margin-top:             -40px;
  position:               relative;
  z-index:                1;
  margin-bottom:          var(--sp-8);
}
.contact-card {
  background:    var(--n-0);
  border-radius: var(--r-3);
  padding:       var(--sp-6) var(--sp-5);
  text-align:    center;
  box-shadow:    var(--shadow-2);
  transition:    transform var(--d-2) var(--ease-out-swift),
                 box-shadow var(--d-2) var(--ease-out-swift);
}
.contact-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-3); }
.contact-card-icon {
  width:           56px;
  height:          56px;
  border-radius:   50%;
  background:      var(--n-100);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       var(--fs-5);
  margin:          0 auto var(--sp-4);
}
.contact-card h3 { font-size: var(--fs-3); font-weight: 700; margin-bottom: var(--sp-2); }
.contact-card p  { font-size: var(--fs-2); color: var(--n-500); }
.contact-card a  { color: var(--brand-ink); font-weight: 600; }

.contact-main {
  display:                grid;
  grid-template-columns:  1fr;
  gap:                    var(--sp-7);
  padding:                var(--sp-8) 0;
  max-width:              640px;
  margin:                 0 auto;
}
.contact-info-side h2 { font-size: var(--fs-5); font-weight: 800; margin-bottom: var(--sp-5); }

.address-card {
  width:          100%;
  background:     var(--n-50);
  border:         1px solid var(--n-200);
  border-radius:  var(--r-2);
  padding:        var(--sp-5);
  margin-bottom:  var(--sp-5);
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-3);
  font-style:     normal;
}
.address-card-icon-row { display: flex; align-items: flex-start; gap: var(--sp-3); }
.address-card-icon {
  width:           40px;
  height:          40px;
  border-radius:   50%;
  background:      var(--n-100);
  flex-shrink:     0;
  display:         flex;
  align-items:     center;
  justify-content: center;
  color:           var(--brand-ink);
  font-size:       var(--fs-4);
}
.address-card-text          { font-size: var(--fs-2); color: var(--n-700); line-height: 1.6; }
.address-card-text strong   { font-size: var(--fs-3); font-weight: 700; color: var(--n-900); display: block; margin-bottom: 2px; }
.address-card-map-link      { font-size: var(--fs-1); font-weight: 600; color: var(--brand-ink); text-decoration: none; }
.address-card-map-link:hover { text-decoration: underline; }

.office-hours {
  background:    var(--n-50);
  border-radius: var(--r-2);
  padding:       var(--sp-5);
  margin-bottom: var(--sp-5);
}
.office-hours h4 { font-size: var(--fs-3); font-weight: 700; margin-bottom: var(--sp-3); }
.office-hours p  { font-size: var(--fs-2); color: var(--n-500); margin-bottom: 4px; }

.contact-info-side .follow-us-heading { font-size: var(--fs-3); margin-bottom: var(--sp-3); }

.social-links { display: flex; gap: var(--sp-3); margin-top: var(--sp-5); }
.social-link {
  width:           44px;
  height:          44px;
  border-radius:   50%;
  background:      var(--n-100);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       var(--fs-4);
  transition:      background-color var(--d-1) var(--ease-out-swift),
                   color var(--d-1) var(--ease-out-swift),
                   transform var(--d-1) var(--ease-out-swift);
  text-decoration: none;
  color:           inherit;
}
.social-link:hover { background: var(--brand-ink); color: var(--n-0); transform: translateY(-2px); }

.faq-section { padding: var(--sp-8) 0; background: var(--n-50); }
.contact-faq-narrow { max-width: 720px; margin: 0 auto; }
.faq-item {
  background:    var(--n-0);
  border-radius: var(--r-2);
  margin-bottom: var(--sp-3);
  overflow:      hidden;
  box-shadow:    var(--shadow-1);
}
.faq-question {
  padding:        18px var(--sp-5);
  font-weight:    600;
  font-size:      var(--fs-3);
  cursor:         pointer;
  display:        flex;
  justify-content: space-between;
  align-items:    center;
  min-height:     44px;
}
.faq-question:hover { color: var(--brand-ink); }
.faq-answer {
  padding:    0 var(--sp-5) 18px;
  font-size:  var(--fs-2);
  color:      var(--n-500);
  line-height: 1.7;
  display:    none;
}
.faq-item.active .faq-answer            { display: block; }
.faq-item.active .faq-question .arrow   { transform: rotate(180deg); }
.arrow                                   { transition: transform var(--d-2) var(--ease-out-swift); }

@media (max-width: 768px) {
  .contact-hero h1 { font-size: var(--fs-5); }
  .contact-cards   { grid-template-columns: 1fr; margin-top: -24px; }
  .contact-main    { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .about-service-card,
  .team-card,
  .contact-card,
  .social-link,
  .arrow {
    transition: none;
  }
}

/* --- Pricing.cshtml -------------------------------------------------------- */

.pricing-hero {
  background:  var(--brand-ink);
  color:       var(--n-0);
  padding:     72px 0;
  text-align:  center;
}
.pricing-hero h1 { font-size: var(--fs-6); font-weight: 800; margin-bottom: var(--sp-3); }
.pricing-hero p  { font-size: var(--fs-4); opacity: 0.9; max-width: 500px; margin: 0 auto 28px; }

.billing-toggle {
  display:        inline-flex;
  background:     rgba(255,255,255,0.15);
  border-radius:  9999px;
  padding:        4px;
}
.billing-toggle button {
  padding:        10px var(--sp-5);
  border-radius:  9999px;
  font-size:      var(--fs-2);
  font-weight:    600;
  color:          rgba(255,255,255,0.7);
  background:     transparent;
  border:         none;
  cursor:         pointer;
  transition:     background-color var(--d-2) var(--ease-out-swift),
                  color var(--d-2) var(--ease-out-swift);
  min-height:     44px;
}
.billing-toggle button.active { background: var(--n-0); color: var(--brand-ink); }

.pricing-section { padding: 72px 0; }
.pricing-section:nth-child(even) { background: var(--n-50); }
.pricing-section h2 { font-size: var(--fs-6); font-weight: 800; text-align: center; margin-bottom: var(--sp-2); }
.pricing-section > .container > p { text-align: center; color: var(--n-500); margin-bottom: 40px; }

.plans-grid       { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-5); }
.plans-grid-4     { grid-template-columns: repeat(4, 1fr); }

.plan-card {
  background:    var(--n-0);
  border:        2px solid var(--n-200);
  border-radius: var(--r-3);
  padding:       var(--sp-6) var(--sp-5);
  text-align:    center;
  position:      relative;
  transition:    transform var(--d-2) var(--ease-out-swift),
                 box-shadow var(--d-2) var(--ease-out-swift);
}
.plan-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-3); }
.plan-card.featured { border-color: var(--brand-spark); box-shadow: var(--shadow-2); }
.plan-card.featured::before {
  content:        'Most Popular';
  position:       absolute;
  top:            -12px;
  left:           50%;
  transform:      translateX(-50%);
  background:     var(--brand-spark);
  color:          var(--n-0);
  padding:        4px var(--sp-4);
  border-radius:  9999px;
  font-size:      var(--fs-1);
  font-weight:    700;
}
.plan-name           { font-size: var(--fs-4); font-weight: 700; margin-bottom: var(--sp-2); }
.plan-price          { font-size: var(--fs-6); font-weight: 800; color: var(--brand-ink); margin-bottom: 4px; }
.plan-price span     { font-size: var(--fs-2); font-weight: 500; color: var(--n-500); }
.plan-annual         { font-size: var(--fs-1); color: var(--brand-spark); font-weight: 600; margin-bottom: 20px; display: none; }
.plan-annual--visible { display: block; }

.plan-features                { text-align: left; margin: 20px 0 var(--sp-5); list-style: none; padding: 0; }
.plan-features li             { padding: var(--sp-2) 0; font-size: var(--fs-2); color: var(--n-700); border-bottom: 1px solid var(--n-100); display: flex; align-items: center; gap: var(--sp-2); }
.plan-features li::before     { content: '\2713'; color: var(--brand-ink); font-weight: 700; font-size: var(--fs-2); }
.plan-features li.disabled    { color: var(--n-400); }
.plan-features li.disabled::before { content: '\2014'; color: var(--n-400); }

.plan-cta-full         { width: 100%; }
.price-hidden          { display: none; }
.plan-detail-on        { color: var(--brand-ink); }

.commission-table {
  width:           100%;
  border-collapse: collapse;
  background:      var(--n-0);
  border-radius:   var(--r-2);
  overflow:        hidden;
  box-shadow:      var(--shadow-1);
}
.commission-table th { background: var(--brand-ink); color: var(--n-0); padding: 14px 20px; text-align: left; font-size: var(--fs-2); }
.commission-table td { padding: 14px 20px; border-bottom: 1px solid var(--n-100); font-size: var(--fs-2); }
.commission-table tr:hover { background: var(--n-50); }
.pricing-narrow      { max-width: 720px; margin: 0 auto; }
.pricing-narrow-spaced { max-width: 720px; margin: var(--sp-5) auto 0; }

.ad-cards { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-5); }
.ad-card  {
  background:    var(--n-0);
  border-radius: var(--r-3);
  padding:       28px;
  text-align:    center;
  box-shadow:    var(--shadow-1);
}
.ad-card-preview {
  height:          80px;
  background:      var(--n-100);
  border-radius:   6px;
  margin-bottom:   var(--sp-4);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       var(--fs-1);
  /* M11 P1 W8.2: lift n-400 -> n-700 on n-100 (2.31 -> 9.37 AA). */
  color:           var(--n-700);
}
.ad-card h4         { font-size: var(--fs-3); font-weight: 700; margin-bottom: 4px; }
.ad-card .ad-price  { font-size: var(--fs-5); font-weight: 800; color: var(--brand-spark); margin: var(--sp-2) 0; }
.ad-card .ad-price-unit { font-size: var(--fs-2); color: var(--n-500); }
.ad-card p          { font-size: var(--fs-1); color: var(--n-500); }

.faq-section .faq-item {
  background:    var(--n-0);
  border:        1px solid var(--n-200);
  border-radius: var(--r-2);
  margin-bottom: var(--sp-3);
  overflow:      hidden;
}
.faq-q { padding: 18px var(--sp-5); font-weight: 600; font-size: var(--fs-3); cursor: pointer; display: flex; justify-content: space-between; align-items: center; min-height: 44px; }
.faq-q:hover { color: var(--brand-ink); }
.faq-a { padding: 0 var(--sp-5) 18px; font-size: var(--fs-2); color: var(--n-500); line-height: 1.7; display: none; }
.faq-section .faq-item.open .faq-a { display: block; }
.faq-section .faq-item.open .arr   { transform: rotate(180deg); }
.arr { transition: transform var(--d-2) var(--ease-out-swift); }

.plan-expand-btn {
  display:     block;
  width:       100%;
  padding:     10px;
  margin-top:  var(--sp-3);
  font-size:   var(--fs-1);
  font-weight: 700;
  color:       var(--brand-ink);
  background:  transparent;
  border:      none;
  cursor:      pointer;
  transition:  color var(--d-1) var(--ease-out-swift);
  text-align:  center;
  min-height:  44px;
}
.plan-expand-btn:hover    { color: var(--brand-spark); }
.plan-expand-btn.expanded { color: var(--brand-spark); }

.plan-details              { max-height: 0; overflow: hidden; transition: max-height var(--d-3) var(--ease-out-swift); }
.plan-details.open         { max-height: 600px; }
.plan-details-inner        { padding: var(--sp-4) 0 0; border-top: 1px solid var(--n-200); margin-top: var(--sp-3); text-align: left; }
.plan-details-inner h4     { font-size: var(--fs-1); font-weight: 800; color: var(--n-900); text-transform: uppercase; letter-spacing: 0.5px; margin-bottom: 10px; }
.plan-details-inner h4.spaced { margin-top: var(--sp-4); }
.plan-detail-row           { display: flex; justify-content: space-between; align-items: center; padding: 6px 0; font-size: var(--fs-1); border-bottom: 1px solid var(--n-100); }
.plan-detail-row span      { color: var(--n-500); }
.plan-detail-row strong    { font-weight: 700; }
.plan-detail-desc          { font-size: var(--fs-1); color: var(--n-500); line-height: 1.6; margin: 0; }

.pricing-cta {
  background:  var(--brand-ink);
  color:       var(--n-0);
  padding:     var(--sp-8) 0;
  text-align:  center;
}
.pricing-cta h2          { font-size: var(--fs-6); font-weight: 800; margin-bottom: var(--sp-4); }
.pricing-cta p           { font-size: var(--fs-3); opacity: 0.9; margin-bottom: 28px; }
.pricing-cta .btn-group  { display: flex; gap: var(--sp-3); justify-content: center; }
.pricing-cta .btn-secondary { border-color: var(--n-0); color: var(--n-0); }

@media (max-width: 1024px) {
  .plans-grid-4 { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
  .pricing-hero h1                       { font-size: var(--fs-5); }
  .plans-grid, .plans-grid-4             { grid-template-columns: 1fr; max-width: 400px; margin: 0 auto; }
  .ad-cards                              { grid-template-columns: 1fr; }
  .commission-table                      { font-size: var(--fs-1); }
  .commission-table th,
  .commission-table td                   { padding: 10px 12px; }
}

@media (prefers-reduced-motion: reduce) {
  .billing-toggle button,
  .plan-card,
  .plan-expand-btn,
  .plan-details,
  .arr {
    transition: none;
  }
}

/* --- Forms.cshtml + FormsBrowse.cshtml + FormDetail.cshtml shared ---------- */

.forms-hero {
  position:    relative;
  min-height:  340px;
  display:     flex;
  align-items: center;
  background:  var(--brand-ink);
  overflow:    hidden;
  padding:     60px 0 var(--sp-7);
}
.forms-hero::after {
  content:    '';
  position:   absolute;
  bottom:     0;
  left:       0;
  right:      0;
  height:     120px;
  background: linear-gradient(to top, rgba(0,0,0,0.3), transparent);
  pointer-events: none;
}
.forms-hero .container { position: relative; z-index: 2; text-align: center; }
.forms-hero h1 {
  font-size:      var(--fs-6);
  font-weight:    800;
  color:          var(--n-0);
  line-height:    1.15;
  margin-bottom:  var(--sp-3);
  letter-spacing: -1px;
}
.forms-hero p {
  font-size:      var(--fs-4);
  color:          rgba(255,255,255,0.7);
  margin-bottom:  28px;
  max-width:      560px;
  margin-left:    auto;
  margin-right:   auto;
}

.hero-search { max-width: 560px; margin: 0 auto var(--sp-5); position: relative; }
.hero-search input {
  width:         100%;
  height:        52px;
  padding:       0 52px 0 20px;
  border:        2px solid rgba(255,255,255,0.2);
  border-radius: 9999px;
  font-size:     var(--fs-2);
  background:    rgba(255,255,255,0.1);
  color:         var(--n-0);
  transition:    border-color var(--d-2) var(--ease-out-swift);
}
.hero-search input::placeholder { color: rgba(255,255,255,0.5); }
.hero-search input:focus-visible {
  border-color: var(--brand-spark);
  background:   rgba(255,255,255,0.15);
}
.hero-search-btn {
  position:        absolute;
  right:           6px;
  top:             50%;
  transform:       translateY(-50%);
  width:           44px;
  height:          44px;
  border-radius:   50%;
  border:          none;
  background:      var(--brand-spark);
  color:           var(--n-0);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       var(--fs-4);
  cursor:          pointer;
  transition:      background-color var(--d-2) var(--ease-out-swift);
}
.hero-search-btn:hover { background: color-mix(in srgb, var(--brand-spark) 85%, var(--n-900)); }

.filter-chips { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap; }
.filter-chip {
  padding:        var(--sp-2) 20px;
  border-radius:  9999px;
  font-size:      var(--fs-2);
  font-weight:    600;
  cursor:         pointer;
  background:     rgba(255,255,255,0.1);
  color:          rgba(255,255,255,0.8);
  border:         1px solid rgba(255,255,255,0.15);
  transition:     background-color var(--d-2) var(--ease-out-swift),
                  color var(--d-2) var(--ease-out-swift),
                  border-color var(--d-2) var(--ease-out-swift);
  min-height:     36px;
}
.filter-chip:hover { background: rgba(255,255,255,0.2); color: var(--n-0); }
.filter-chip.active {
  background:    var(--brand-spark);
  color:         var(--n-0);
  border-color:  var(--brand-spark);
}

/* M10 Phase 3 W6.6: hit area floored at 44×44 per CLAUDE.md hard rule #8.
   Filter chips inside Hero — interactive buttons; must satisfy touch-target. */
.filter-chip { min-height: 44px; }

.forms-section { padding: 56px 0 var(--sp-8); background: var(--n-50); }
.forms-section .section-title { margin-bottom: var(--sp-2); }
.forms-grid {
  display:               grid;
  grid-template-columns: repeat(3, 1fr);
  gap:                   var(--sp-5);
  margin-top:            40px;
}
.form-card {
  background:    var(--n-0);
  border-radius: var(--r-3);
  box-shadow:    var(--shadow-1);
  overflow:      hidden;
  transition:    transform var(--d-3) var(--ease-out-swift),
                 box-shadow var(--d-3) var(--ease-out-swift);
  position:      relative;
  cursor:        pointer;
  text-decoration: none;
  color:         inherit;
  display:       block;
}
.form-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-3); }
.form-card.is-hidden { display: none; }
.form-card-stripe { height: 5px; width: 100%; }

/* Stripe variants — use design-system tokens; legacy green replaced with brand-ink. */
.stripe-conference  { background: var(--brand-ink); }
.stripe-rsvp        { background: var(--brand-spark); }
.stripe-workshop    { background: var(--state-info); }
.stripe-competition { background: color-mix(in srgb, var(--brand-ink) 60%, var(--brand-spark)); }
.stripe-webinar     { background: var(--state-success); }

.form-card-body { padding: 20px var(--sp-5) var(--sp-5); }
.form-card-top  { display: flex; align-items: flex-start; justify-content: space-between; margin-bottom: var(--sp-3); }
.form-type-badge {
  display:        inline-flex;
  align-items:    center;
  gap:            4px;
  padding:        4px 10px;
  border-radius:  9999px;
  font-size:      var(--fs-1);
  font-weight:    700;
  text-transform: uppercase;
  letter-spacing: 0.5px;
}
.badge-conference  { background: var(--n-100); color: var(--brand-ink); }
.badge-rsvp        { background: var(--n-50);  color: var(--brand-spark); }
.badge-workshop    { background: var(--n-50);  color: var(--state-info); }
.badge-competition { background: var(--n-100); color: var(--n-700); }
.badge-webinar     { background: var(--n-50);  color: var(--state-success); }
.badge-closing {
  display:         inline-flex;
  align-items:     center;
  gap:             4px;
  padding:         4px 10px;
  border-radius:   9999px;
  font-size:       var(--fs-1);
  font-weight:     700;
  text-transform:  uppercase;
  background:      color-mix(in srgb, var(--state-danger) 15%, var(--n-0));
  color:           var(--state-danger);
  animation:       pulse-badge 2s infinite;
}

.form-card-title {
  font-size:     var(--fs-4);
  font-weight:   700;
  color:         var(--n-900);
  margin-bottom: var(--sp-2);
  line-height:   1.3;
}
.form-card-organizer {
  display:       flex;
  align-items:   center;
  gap:           var(--sp-2);
  font-size:     var(--fs-2);
  color:         var(--n-600);
  margin-bottom: 14px;
}
.org-avatar {
  width:         28px;
  height:        28px;
  border-radius: 50%;
  display:       flex;
  align-items:   center;
  justify-content: center;
  font-size:     var(--fs-1);
  font-weight:   700;
  color:         var(--n-0);
  flex-shrink:   0;
  background:    var(--brand-ink);
}
.org-verified-sm {
  display:        inline-flex;
  align-items:    center;
  gap:            3px;
  padding:        2px 7px;
  border-radius:  10px;
  background:     var(--n-100);
  color:          var(--brand-ink);
  font-size:      var(--fs-1);
  font-weight:    700;
  white-space:    nowrap;
}
.form-card-meta {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-2);
  padding-top:    14px;
  border-top:     1px solid var(--n-100);
  margin-bottom:  var(--sp-4);
}
.form-meta-row {
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  font-size:       var(--fs-1);
  color:           var(--n-600);
}
.form-meta-row span { display: inline-flex; align-items: center; gap: 5px; }
.form-price        { font-size: var(--fs-4); font-weight: 800; color: var(--brand-ink); }
.form-price.free   { color: var(--state-success); }
.form-registered   { font-size: var(--fs-1); color: var(--n-400); }
.form-card-btn {
  width:           100%;
  padding:         12px;
  border-radius:   6px;
  background:      var(--brand-ink);
  color:           var(--n-0);
  font-size:       var(--fs-2);
  font-weight:     700;
  transition:      background-color var(--d-2) var(--ease-out-swift),
                   box-shadow var(--d-2) var(--ease-out-swift);
  display:         block;
  text-align:      center;
  text-decoration: none;
  border:          none;
  cursor:          pointer;
  min-height:      44px;
}
.form-card-btn:hover {
  background: color-mix(in srgb, var(--brand-ink) 85%, var(--n-0));
  box-shadow: var(--shadow-2);
  color:      var(--n-0);
}

.cta-banner {
  padding:    var(--sp-8) 0;
  background: var(--brand-ink);
  position:   relative;
  overflow:   hidden;
}
.cta-inner {
  position:   relative;
  z-index:    2;
  text-align: center;
  max-width:  640px;
  margin:     0 auto;
}
.cta-inner h2 { font-size: var(--fs-6); font-weight: 800; color: var(--n-0); margin-bottom: var(--sp-3); }
.cta-inner p  { font-size: var(--fs-4); color: rgba(255,255,255,0.7); margin-bottom: 28px; line-height: 1.6; }

.cta-features {
  display:         flex;
  align-items:     center;
  justify-content: center;
  gap:             var(--sp-5);
  margin-bottom:   var(--sp-6);
  flex-wrap:       wrap;
}
.cta-feat {
  display:     flex;
  align-items: center;
  gap:         var(--sp-2);
  font-size:   var(--fs-2);
  font-weight: 600;
  color:       rgba(255,255,255,0.85);
}
.cta-feat-icon {
  width:           32px;
  height:          32px;
  border-radius:   50%;
  background:      rgba(255,255,255,0.15);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       var(--fs-2);
}
.cta-btn {
  display:        inline-flex;
  align-items:    center;
  gap:            var(--sp-2);
  padding:        var(--sp-4) 36px;
  border-radius:  6px;
  background:     var(--brand-spark);
  color:          var(--n-0);
  font-size:      var(--fs-4);
  font-weight:    700;
  transition:     background-color var(--d-2) var(--ease-out-swift),
                  box-shadow var(--d-2) var(--ease-out-swift),
                  transform var(--d-2) var(--ease-out-swift);
  text-decoration: none;
  min-height:     44px;
}
.cta-btn:hover {
  background:  color-mix(in srgb, var(--brand-spark) 85%, var(--n-900));
  box-shadow:  var(--shadow-3);
  transform:   translateY(-2px);
  color:       var(--n-0);
}

.ad-banner-hero { padding: var(--sp-3) 0; background: var(--n-0); }
.ad-placeholder.ad-hero {
  width:           100%;
  max-width:       1280px;
  height:          90px;
  margin:          0 auto;
  background:      var(--n-100);
  border:          2px dashed var(--n-300);
  border-radius:   var(--r-2);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       var(--fs-1);
  /* M11 P1 W8.2: lift n-400 -> n-700 on n-100 (2.31 -> 9.37 AA). */
  color:           var(--n-700);
  font-weight:     600;
}

@keyframes pulse-badge {
  0%, 100% { opacity: 1; }
  50%      { opacity: 0.7; }
}

@media (max-width: 1024px) { .forms-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 768px) {
  .forms-hero            { min-height: auto; padding: 40px 0 var(--sp-6); }
  .forms-hero h1         { font-size: var(--fs-5); }
  .forms-hero p          { font-size: var(--fs-2); margin-bottom: 20px; }
  .filter-chip           { padding: 6px 14px; font-size: var(--fs-1); }
  .cta-banner            { padding: var(--sp-7) 0; }
  .cta-inner h2          { font-size: var(--fs-5); }
  .cta-inner p           { font-size: var(--fs-2); }
  .cta-features          { gap: var(--sp-4); }
}
@media (max-width: 640px) { .forms-grid { grid-template-columns: 1fr; } }

@media (prefers-reduced-motion: reduce) {
  .form-card,
  .form-card-btn,
  .filter-chip,
  .hero-search input,
  .hero-search-btn,
  .cta-btn,
  .badge-closing {
    transition: none;
    animation:  none;
  }
}

/* --- Blog.cshtml ----------------------------------------------------------- */

.blog-hero {
  background: var(--brand-ink);
  color:      var(--n-0);
  padding:    var(--sp-8) 0 var(--sp-7);
  text-align: center;
}
.blog-hero h1 { font-size: var(--fs-6); font-weight: 800; margin-bottom: var(--sp-3); letter-spacing: -1px; }
.blog-hero p  { font-size: var(--fs-4); opacity: 0.85; margin-bottom: 28px; max-width: 520px; margin-left: auto; margin-right: auto; }

.blog-search { max-width: 520px; margin: 0 auto var(--sp-6); position: relative; }
.blog-search input {
  width:         100%;
  height:        52px;
  padding:       0 52px 0 20px;
  border:        none;
  border-radius: 9999px;
  font-size:     var(--fs-2);
  box-shadow:    var(--shadow-3);
}
.blog-search input::placeholder { color: var(--n-400); }
.blog-search-btn {
  position:        absolute;
  right:           6px;
  top:             50%;
  transform:       translateY(-50%);
  width:           44px;
  height:          44px;
  border-radius:   50%;
  background:      var(--brand-ink);
  color:           var(--n-0);
  display:         flex;
  align-items:     center;
  justify-content: center;
  border:          none;
  cursor:          pointer;
  transition:      background-color var(--d-1) var(--ease-out-swift);
}
.blog-search-btn:hover { background: color-mix(in srgb, var(--brand-ink) 85%, var(--n-0)); }
.blog-search-btn .mdi  { font-size: var(--fs-4); }

.category-tabs { display: flex; justify-content: center; gap: var(--sp-2); flex-wrap: wrap; }
.cat-tab {
  padding:        var(--sp-2) var(--sp-5);
  border-radius:  9999px;
  font-size:      var(--fs-2);
  font-weight:    600;
  background:     rgba(255,255,255,0.15);
  color:          rgba(255,255,255,0.9);
  border:         1px solid rgba(255,255,255,0.2);
  transition:     background-color var(--d-2) var(--ease-out-swift),
                  color var(--d-2) var(--ease-out-swift),
                  border-color var(--d-2) var(--ease-out-swift);
  cursor:         pointer;
  min-height:     36px;
}
.cat-tab:hover, .cat-tab.active {
  background:    var(--n-0);
  color:         var(--brand-ink);
  border-color:  var(--n-0);
}

/* M10 Phase 3 W6.6: hit area floored at 44×44 per CLAUDE.md hard rule #8.
   Category tabs are interactive nav-equivalent buttons — must satisfy the
   touch-target rule. The visual size stays the same on desktop where the
   tab text dictates height; min-height enforces the floor at 44px. */
.cat-tab { min-height: 44px; }

.featured-section { padding: var(--sp-7) 0; }
.featured-card {
  display:               grid;
  grid-template-columns: 1.2fr 1fr;
  gap:                   0;
  border-radius:         var(--r-4);
  overflow:              hidden;
  box-shadow:            var(--shadow-3);
  background:            var(--n-0);
  transition:            transform var(--d-3) var(--ease-out-swift),
                         box-shadow var(--d-3) var(--ease-out-swift);
  cursor:                pointer;
}
.featured-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-4); }
.featured-image {
  background:      var(--brand-ink);
  min-height:      340px;
  display:         flex;
  align-items:     center;
  justify-content: center;
  color:           var(--n-0);
  font-size:       72px;
  position:        relative;
}
.featured-image::after {
  content:    '';
  position:   absolute;
  inset:      0;
  background: linear-gradient(135deg, rgba(15,32,24,0.2), rgba(232,145,45,0.2));
}
.featured-image .img-icon { position: relative; z-index: 1; }
.featured-body { padding: 40px 36px; display: flex; flex-direction: column; justify-content: center; }
.featured-meta { display: flex; align-items: center; gap: var(--sp-3); margin-bottom: var(--sp-4); flex-wrap: wrap; }

.cat-badge {
  display:        inline-flex;
  align-items:    center;
  gap:            4px;
  padding:        4px 12px;
  border-radius:  9999px;
  font-size:      var(--fs-1);
  font-weight:    700;
  text-transform: uppercase;
  letter-spacing: 0.3px;
}
.cat-badge.travel     { background: var(--n-100); color: var(--state-info); }
.cat-badge.events     { background: var(--n-100); color: var(--brand-spark); }
.cat-badge.vendors    { background: var(--n-100); color: var(--brand-ink); }
.cat-badge.voting     { background: var(--n-100); color: var(--n-700); }
.cat-badge.tips       { background: var(--n-100); color: var(--state-warn); }
.cat-badge.industry   { background: var(--n-100); color: var(--n-700); }
.cat-badge--mb-3      { margin-bottom: var(--sp-3); display: inline-flex; }

.meta-text { font-size: var(--fs-1); color: var(--n-600); }
.meta-dot  { width: 4px; height: 4px; border-radius: 50%; background: var(--n-400); }

.featured-body h2          { font-size: var(--fs-5); font-weight: 800; line-height: 1.25; margin-bottom: 14px; color: var(--n-900); }
.featured-body .excerpt    { font-size: var(--fs-3); color: var(--n-600); line-height: 1.7; margin-bottom: var(--sp-5); }
.read-btn {
  display:        inline-flex;
  align-items:    center;
  gap:            var(--sp-2);
  padding:        var(--sp-3) 28px;
  background:     var(--brand-ink);
  color:          var(--n-0);
  border-radius:  var(--r-1);
  font-size:      var(--fs-2);
  font-weight:    600;
  transition:     background-color var(--d-2) var(--ease-out-swift),
                  transform var(--d-2) var(--ease-out-swift),
                  box-shadow var(--d-2) var(--ease-out-swift);
  align-self:     flex-start;
  border:         none;
  cursor:         pointer;
  min-height:     44px;
}
.read-btn:hover { background: color-mix(in srgb, var(--brand-ink) 85%, var(--n-0)); transform: translateY(-1px); box-shadow: var(--shadow-2); }

.blog-content-section         { padding: 0 0 var(--sp-8); }
.blog-content-section--top    { padding-top: var(--sp-6); }
.blog-layout                  { display: grid; grid-template-columns: 1fr 340px; gap: 40px; align-items: start; }

.posts-grid-title { font-size: var(--fs-5); font-weight: 800; margin-bottom: var(--sp-5); color: var(--n-900); }
.posts-grid       { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--sp-5); margin-bottom: 40px; }

.post-card {
  background:    var(--n-0);
  border-radius: var(--r-3);
  box-shadow:    var(--shadow-1);
  overflow:      hidden;
  transition:    transform var(--d-3) var(--ease-out-swift),
                 box-shadow var(--d-3) var(--ease-out-swift);
  cursor:        pointer;
}
.post-card:hover { transform: translateY(-4px); box-shadow: var(--shadow-3); }
.post-card.is-hidden { display: none; }
.post-thumb {
  height:          180px;
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       40px;
  color:           var(--n-0);
  position:        relative;
  background:      var(--brand-ink);
}
.post-thumb .cat-badge { position: absolute; top: 12px; left: 12px; }

/* Per-thumb category accents (replace inline gradient style=). */
.post-thumb--events    { background: var(--brand-spark); }
.post-thumb--travel    { background: var(--state-info); }
.post-thumb--vendors   { background: var(--brand-ink); }
.post-thumb--voting    { background: var(--n-700); }
.post-thumb--tips      { background: var(--state-warn); }
.post-thumb--industry  { background: var(--n-800); }

.post-card-body                       { padding: 20px; }
.post-card-body h3                    { font-size: var(--fs-3); font-weight: 700; line-height: 1.35; margin-bottom: var(--sp-2); color: var(--n-900); }
.post-card-body .card-excerpt         { font-size: var(--fs-1); color: var(--n-600); line-height: 1.6; margin-bottom: 14px; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.post-card-footer                     { display: flex; align-items: center; justify-content: space-between; font-size: var(--fs-1); color: var(--n-400); padding-top: var(--sp-3); border-top: 1px solid var(--n-100); }
.post-card-footer .author             { font-weight: 600; color: var(--n-600); }

.featured-section.is-hidden { display: none; }

.blog-pagination { display: flex; align-items: center; justify-content: center; gap: 6px; margin-bottom: var(--sp-7); }
.page-btn {
  width:         44px;
  height:        44px;
  border-radius: var(--r-1);
  display:       flex;
  align-items:   center;
  justify-content: center;
  font-size:     var(--fs-2);
  font-weight:   600;
  color:         var(--n-600);
  background:    var(--n-0);
  border:        1px solid var(--n-200);
  transition:    border-color var(--d-1) var(--ease-out-swift),
                 color var(--d-1) var(--ease-out-swift),
                 background-color var(--d-1) var(--ease-out-swift);
  cursor:        pointer;
}
.page-btn:hover  { border-color: var(--brand-ink); color: var(--brand-ink); }
.page-btn.active { background: var(--brand-ink); color: var(--n-0); border-color: var(--brand-ink); }
.page-next {
  padding:       0 var(--sp-4);
  height:        44px;
  border-radius: var(--r-1);
  display:       flex;
  align-items:   center;
  gap:           6px;
  font-size:     var(--fs-2);
  font-weight:   600;
  color:         var(--brand-ink);
  background:    var(--n-0);
  border:        1px solid var(--n-200);
  transition:    background-color var(--d-1) var(--ease-out-swift),
                 color var(--d-1) var(--ease-out-swift),
                 border-color var(--d-1) var(--ease-out-swift);
  cursor:        pointer;
}
.page-next:hover { background: var(--brand-ink); color: var(--n-0); border-color: var(--brand-ink); }

.blog-sidebar           { position: sticky; top: 120px; }
.blog-sidebar-card,
.sidebar-card           { background: var(--n-0); border-radius: var(--r-3); box-shadow: var(--shadow-1); padding: var(--sp-5); margin-bottom: var(--sp-5); }
.sidebar-card h3        { font-size: var(--fs-3); font-weight: 700; margin-bottom: var(--sp-4); padding-bottom: var(--sp-3); border-bottom: 2px solid var(--n-100); color: var(--n-900); }

.newsletter-icon              { font-size: var(--fs-6); margin-bottom: var(--sp-2); }
.sidebar-card .nl-desc        { font-size: var(--fs-1); color: var(--n-600); margin-bottom: 14px; line-height: 1.6; }
.nl-form                      { display: flex; flex-direction: column; gap: 10px; }
.nl-form input                { width: 100%; padding: 10px 14px; border: 2px solid var(--n-200); border-radius: var(--r-1); font-size: var(--fs-2); transition: border-color var(--d-2) var(--ease-out-swift); }
.nl-form input:focus-visible  { border-color: var(--brand-spark); }
.nl-form .btn                 { width: 100%; justify-content: center; }

.popular-post {
  display:    flex;
  gap:        var(--sp-3);
  padding:    10px 0;
  border-bottom: 1px solid var(--n-100);
  cursor:     pointer;
  transition: background-color var(--d-1) var(--ease-out-swift);
}
.popular-post:last-child  { border: none; }
.popular-post:hover       { background: var(--n-50); margin: 0 -8px; padding-left: var(--sp-2); padding-right: var(--sp-2); border-radius: var(--r-1); }
.pp-num {
  width:           28px;
  height:          28px;
  border-radius:   50%;
  background:      var(--n-100);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       var(--fs-1);
  font-weight:     800;
  color:           var(--brand-ink);
  flex-shrink:     0;
  margin-top:      2px;
}
.pp-info h4 { font-size: var(--fs-1); font-weight: 600; line-height: 1.4; color: var(--n-900); }
.pp-info p  { font-size: var(--fs-1); color: var(--n-400); margin-top: 3px; }

.cat-list-item {
  display:        flex;
  align-items:    center;
  justify-content: space-between;
  padding:        10px 0;
  border-bottom:  1px solid var(--n-100);
  font-size:      var(--fs-2);
  color:          var(--n-700);
  transition:     color var(--d-1) var(--ease-out-swift);
  cursor:         pointer;
}
.cat-list-item:last-child { border: none; }
.cat-list-item:hover      { color: var(--brand-ink); }
.cat-count {
  background:    var(--n-100);
  padding:       2px 10px;
  border-radius: 9999px;
  font-size:     var(--fs-1);
  font-weight:   600;
  color:         var(--n-600);
}

.social-follow-grid { display: grid; grid-template-columns: repeat(2, 1fr); gap: var(--sp-2); }
/* M10 Phase 3 W6.6: hit area floored at 44×44 per CLAUDE.md hard rule #8.
   Social follow links in widget grid (Facebook / Twitter / Instagram / YouTube). */
.social-follow-btn {
  display:         flex;
  align-items:     center;
  justify-content: center;
  gap:             6px;
  padding:         10px;
  border-radius:   var(--r-1);
  font-size:       var(--fs-1);
  font-weight:     600;
  color:           var(--n-0);
  transition:      opacity var(--d-1) var(--ease-out-swift);
  text-decoration: none;
  min-height:      44px;
}
.social-follow-btn:hover { opacity: 0.9; color: var(--n-0); }
/* Per-network accents — design-system token approximations (raw network hex banned per CLAUDE.md hard rule 2). */
.social-follow-btn.fb    { background: var(--state-info); }
.social-follow-btn.tw    { background: color-mix(in srgb, var(--state-info) 80%, var(--n-0)); }
.social-follow-btn.ig    { background: var(--brand-spark); }
.social-follow-btn.yt    { background: var(--state-danger); }

.sidebar-ad-slot { margin-top: var(--sp-5); }
.sidebar-ad-placeholder {
  width:           100%;
  height:          600px;
  background:      var(--n-100);
  border:          2px dashed var(--n-300);
  border-radius:   var(--r-2);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       var(--fs-1);
  /* M11 P1 W8.2: lift n-400 -> n-700 on n-100 (2.31 -> 9.37 AA). */
  color:           var(--n-700);
  font-weight:     600;
}

.blog-detail            { display: none; }
.blog-detail.active     { display: block; }
.blog-index.hidden      { display: none; }

.breadcrumb              { display: flex; align-items: center; gap: var(--sp-2); font-size: var(--fs-1); color: var(--n-400); margin-bottom: var(--sp-5); flex-wrap: wrap; }
.breadcrumb a            { color: var(--n-600); transition: color var(--d-1) var(--ease-out-swift); }
.breadcrumb a:hover      { color: var(--brand-ink); }
.breadcrumb .sep         { color: var(--n-300); }

.back-to-blog {
  display:        inline-flex;
  align-items:    center;
  gap:            6px;
  font-size:      var(--fs-2);
  font-weight:    600;
  color:          var(--brand-ink);
  margin-bottom:  20px;
  cursor:         pointer;
  transition:     gap var(--d-1) var(--ease-out-swift);
}
.back-to-blog:hover { gap: 10px; }

.article-header { margin-bottom: var(--sp-6); }
.article-header h1 { font-size: var(--fs-6); font-weight: 800; line-height: 1.2; margin-bottom: 20px; color: var(--n-900); letter-spacing: -0.5px; }
.article-author-row { display: flex; align-items: center; gap: var(--sp-4); flex-wrap: wrap; }
.author-avatar {
  width:           48px;
  height:          48px;
  border-radius:   50%;
  background:      var(--brand-ink);
  display:         flex;
  align-items:     center;
  justify-content: center;
  color:           var(--n-0);
  font-weight:     800;
  font-size:       var(--fs-4);
}
.author-info .author-name  { font-size: var(--fs-2); font-weight: 700; color: var(--n-900); }
.author-info .author-date  { font-size: var(--fs-1); color: var(--n-400); }
.share-row                 { display: flex; align-items: center; gap: var(--sp-2); margin-left: auto; }
.share-btn-sm {
  width:           44px;
  height:          44px;
  border-radius:   50%;
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       var(--fs-2);
  background:      var(--n-100);
  color:           var(--n-600);
  transition:      background-color var(--d-1) var(--ease-out-swift),
                   color var(--d-1) var(--ease-out-swift);
  border:          none;
  cursor:          pointer;
}
.share-btn-sm:hover         { background: var(--brand-ink); color: var(--n-0); }
.share-btn-sm.copy-link     { border-radius: 9999px; width: auto; padding: 0 14px; font-size: var(--fs-1); font-weight: 600; gap: 4px; min-height: 44px; }

.article-hero-img {
  width:           100%;
  height:          400px;
  border-radius:   var(--r-4);
  background:      var(--brand-ink);
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       80px;
  color:           var(--n-0);
  margin-bottom:   var(--sp-6);
}

.article-body                  { max-width: 100%; }
.article-body p                { font-size: var(--fs-3); line-height: 1.8; color: var(--n-700); margin-bottom: 20px; }
.article-body h2               { font-size: var(--fs-5); font-weight: 800; color: var(--n-900); margin: 36px 0 var(--sp-4); padding-top: var(--sp-2); }
.article-body h3               { font-size: var(--fs-4); font-weight: 700; color: var(--n-900); margin: 28px 0 var(--sp-3); }
.article-body ul,
.article-body ol               { margin-bottom: 20px; padding-left: var(--sp-5); }
.article-body li               { font-size: var(--fs-3); line-height: 1.8; color: var(--n-700); margin-bottom: var(--sp-2); list-style: disc; }
.article-body blockquote       { border-left: 4px solid var(--brand-ink); padding: var(--sp-4) var(--sp-5); background: var(--n-50); border-radius: 0 var(--r-1) var(--r-1) 0; margin: var(--sp-5) 0; font-style: italic; color: var(--n-600); }

.inline-cta {
  background:      var(--brand-ink);
  color:           var(--n-0);
  padding:         var(--sp-6);
  border-radius:   var(--r-4);
  margin:          36px 0;
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  gap:             20px;
  flex-wrap:       wrap;
}
.inline-cta-text h3 { font-size: var(--fs-4); font-weight: 800; margin-bottom: 6px; }
.inline-cta-text p  { font-size: var(--fs-2); opacity: 0.85; }
.inline-cta .btn {
  background:    var(--brand-spark);
  color:         var(--n-0);
  padding:       var(--sp-3) 28px;
  font-size:     var(--fs-2);
  font-weight:   700;
  border-radius: var(--r-1);
  white-space:   nowrap;
  transition:    background-color var(--d-2) var(--ease-out-swift),
                 transform var(--d-2) var(--ease-out-swift);
}
.inline-cta .btn:hover { background: color-mix(in srgb, var(--brand-spark) 85%, var(--n-900)); transform: translateY(-1px); }

.dest-card {
  display:               grid;
  grid-template-columns: 200px 1fr;
  gap:                   20px;
  background:            var(--n-50);
  border-radius:         var(--r-3);
  padding:               20px;
  margin-bottom:         20px;
  border:                1px solid var(--n-200);
}
.dest-card-img {
  border-radius:   var(--r-1);
  height:          140px;
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       36px;
  color:           var(--n-0);
  background:      var(--brand-ink);
}
.dest-card-img--info  { background: var(--state-info); }
.dest-card-img--warn  { background: var(--state-warn); }
.dest-card-img--succ  { background: var(--state-success); }

.dest-card-info h4              { font-size: var(--fs-4); font-weight: 700; margin-bottom: 6px; }
.dest-card-info p               { font-size: var(--fs-2); color: var(--n-600); line-height: 1.6; }
.dest-card-info .dest-highlights { display: flex; gap: var(--sp-2); margin-top: var(--sp-2); flex-wrap: wrap; }
.dest-highlight {
  padding:       3px 10px;
  background:    var(--n-0);
  border:        1px solid var(--n-200);
  border-radius: 9999px;
  font-size:     var(--fs-1);
  font-weight:   600;
  color:         var(--n-600);
}

.article-tags {
  display:        flex;
  align-items:    center;
  gap:            var(--sp-2);
  flex-wrap:      wrap;
  margin:         var(--sp-6) 0;
  padding:        20px 0;
  border-top:     1px solid var(--n-200);
  border-bottom:  1px solid var(--n-200);
}
.article-tags span { font-size: var(--fs-2); font-weight: 700; color: var(--n-900); }
.tag {
  padding:       4px 14px;
  border-radius: 9999px;
  background:    var(--n-100);
  font-size:     var(--fs-1);
  font-weight:   500;
  color:         var(--n-600);
  transition:    background-color var(--d-1) var(--ease-out-swift),
                 color var(--d-1) var(--ease-out-swift);
}
.tag:hover { background: var(--brand-ink); color: var(--n-0); }

.author-bio-card {
  display:       flex;
  gap:           20px;
  padding:       var(--sp-5);
  background:    var(--n-50);
  border-radius: var(--r-4);
  margin:        var(--sp-6) 0;
  border:        1px solid var(--n-200);
}
.author-bio-avatar {
  width:           72px;
  height:          72px;
  border-radius:   50%;
  background:      var(--brand-ink);
  display:         flex;
  align-items:     center;
  justify-content: center;
  color:           var(--n-0);
  font-weight:     800;
  font-size:       var(--fs-5);
  flex-shrink:     0;
}
.author-bio-info h4         { font-size: var(--fs-4); font-weight: 700; color: var(--n-900); }
.author-bio-info .bio-role  { font-size: var(--fs-1); color: var(--brand-spark); font-weight: 600; margin-top: 2px; }
.author-bio-info p          { font-size: var(--fs-2); color: var(--n-600); line-height: 1.6; margin-top: var(--sp-2); }

.related-section            { margin-top: var(--sp-7); }
.related-section h2         { font-size: var(--fs-5); font-weight: 800; margin-bottom: var(--sp-5); }
.related-grid               { display: grid; grid-template-columns: repeat(3, 1fr); gap: 20px; }
.related-card {
  background:    var(--n-0);
  border-radius: var(--r-3);
  overflow:      hidden;
  box-shadow:    var(--shadow-1);
  transition:    transform var(--d-2) var(--ease-out-swift),
                 box-shadow var(--d-2) var(--ease-out-swift);
  cursor:        pointer;
}
.related-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-2); }
.related-thumb {
  height:          140px;
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       32px;
  color:           var(--n-0);
  background:      var(--brand-ink);
}
.related-thumb--travel    { background: var(--state-info); }
.related-thumb--tips      { background: var(--state-warn); }
.related-thumb--industry  { background: var(--n-700); }

.related-body                  { padding: var(--sp-4); }
.related-body .cat-badge       { margin-bottom: var(--sp-2); }
.related-body h4               { font-size: var(--fs-2); font-weight: 700; line-height: 1.4; margin-bottom: 6px; }
.related-body p                { font-size: var(--fs-1); color: var(--n-400); }

.toast {
  position:        fixed;
  bottom:          100px;
  left:            50%;
  transform:       translateX(-50%) translateY(80px);
  background:      var(--n-900);
  color:           var(--n-0);
  padding:         var(--sp-3) var(--sp-5);
  border-radius:   9999px;
  font-size:       var(--fs-2);
  font-weight:     600;
  z-index:         var(--z-toast);
  opacity:         0;
  transition:      opacity var(--d-4) var(--ease-out-swift),
                   transform var(--d-4) var(--ease-out-swift);
  pointer-events:  none;
}
.toast.show { opacity: 1; transform: translateX(-50%) translateY(0); }

@media (max-width: 1024px) {
  .blog-layout    { grid-template-columns: 1fr; }
  .posts-grid     { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
  .blog-hero          { padding: 40px 0 var(--sp-6); }
  .blog-hero h1       { font-size: var(--fs-5); }
  .blog-hero p        { font-size: var(--fs-2); }
  .cat-tab            { padding: 6px 14px; font-size: var(--fs-1); }
  .featured-card      { grid-template-columns: 1fr; }
  .featured-image     { min-height: 200px; font-size: 48px; }
  .featured-body      { padding: var(--sp-5) 20px; }
  .featured-body h2   { font-size: var(--fs-4); }
  .posts-grid         { grid-template-columns: 1fr; }
  .dest-card          { grid-template-columns: 1fr; }
  .dest-card-img      { height: 120px; }
  .article-header h1  { font-size: var(--fs-5); }
  .article-hero-img   { height: 220px; font-size: 48px; }
  .inline-cta         { flex-direction: column; text-align: center; }
  .share-row          { margin-left: 0; margin-top: var(--sp-3); }
  .author-bio-card    { flex-direction: column; align-items: center; text-align: center; }
  .related-grid       { grid-template-columns: 1fr; }
}

@media (prefers-reduced-motion: reduce) {
  .featured-card,
  .post-card,
  .related-card,
  .read-btn,
  .blog-search-btn,
  .cat-tab,
  .page-btn,
  .page-next,
  .nl-form input,
  .popular-post,
  .cat-list-item,
  .social-follow-btn,
  .breadcrumb a,
  .back-to-blog,
  .share-btn-sm,
  .inline-cta .btn,
  .tag,
  .toast {
    transition: none;
  }
}


/* ==========================================================================
   PUBLIC LIST PAGES — EventsBrowse / VotingContestsBrowse / TourMarketplace
   (M07 Phase 3 · W4.8)
   Composition layer over Hero --sm + FilterBar + ContentCard grid. Mirrors
   the vendor-marketplace family from Phase 2 (W4.5) so all four public list
   surfaces share the same shell and only differ in selector prefix +
   ContentCard subvariant. Token-driven; no raw hex; no raw ms.
   ========================================================================== */

.events-browse,
.voting-browse,
.tour-marketplace {
  background-color: var(--n-50);
  padding:          var(--sp-7) 0 var(--sp-8);
}

.events-browse__container,
.voting-browse__container,
.tour-marketplace__container {
  width:     100%;
  max-width: 1280px;
  margin:    0 auto;
  padding:   0 var(--sp-5);
}

/* M23 Phase 3 (C2): Home rails adopt the same gutter rhythm as the
   events / voting / tours marketplaces. Mirrors the rule above exactly so
   horizontal padding matches across public pages. Wraps the rails switch
   in Views/Public/Home.cshtml; the kit _Hero stays full-bleed and is
   intentionally outside this container. */
.home-rails__container {
  width:     100%;
  max-width: 1280px;
  margin:    0 auto;
  padding:   0 var(--sp-5);
}

/* ==========================================================================
   HOME · TRENDING NOW (M30 Phase 6 · F-6-6)
   Single rail consolidating events / vendors / voting cards behind a
   filter pill row (kit _SegmentedControl). At ≥1024px the rail track is
   re-shaped from the kit default scroll-grid into a 3-up symmetric grid
   so the consolidated rail reads as a curated "set of three" rather than
   a horizontally scrolling strip. Below 1024px the kit rail's native
   scroll-snap behaviour stays — vertical real estate is the constraint.
   Hard rules: #2 tokens only · #3 motion tokens only · #5 zero <style>
   blocks introduced · #10 reduced-motion handled by the kit Rail.
   ========================================================================== */
.home-trending {
  margin-block: var(--sp-7) 0;
}

.home-trending__filter-bar {
  display:         flex;
  justify-content: center;
  margin-bottom:   var(--sp-5);
}

/* The filter-bar inner SegmentedControl has its own 44×44 touch targets
   (HR8) defined in elfrique.components.data.css. No override required;
   the wrapper is centring-only. */

/* The category-tagged wrapper around each card. block-level so the kit
   .rail__item host owns layout; nothing here breaks the grid contract.
   The "is-hidden" toggle is applied to the .rail__item ancestor by JS
   so the grid collapses around filtered-out cards (no empty columns). */
.home-trending__item {
  display: block;
  height: 100%;
}

.home-trending .rail__item.is-hidden {
  display: none;
}

@media (min-width: 1024px) {
  /* M31 Phase 12 (Cluster J · N33 column-count parity + N25 vertical-height).
     Home Trending Now rails render as a wrapping grid that mirrors the
     events / contests / tours browse marketplaces (`.events-browse__grid`
     et al. at line ~5533 below) — `repeat(auto-fill, minmax(280px, 1fr))`.
     Intrinsic sizing yields ~4 cols at the 1280px home-rails container
     width, degrading naturally as viewport narrows. Replaces the prior
     fixed 3-up grid (M30 Phase 6) so home rails reach column-count parity
     with the marketplaces.

     N25 (vertical-height parity) is resolved by the .home-trending .rail__track
     rule below — grid-auto-rows: 1fr forces equal row heights across the rail.
     `.rail__track` already declares `align-items: stretch` (line ~1634), and
     `.content-card` declares `height: 100%` (line ~1176). With auto-flow:row +
     a wrapping grid + grid-auto-rows: 1fr, every row in the grid takes the same
     track height and shorter siblings stretch to match — same behaviour as the
     browse marketplaces.

     The override is scoped to `.home-trending` so the kit rail default
     (horizontal-scroll ribbon) remains intact for every other consumer
     of `Kit/_Rail.cshtml` — TourDetail, Category, RecommendationRail,
     and the Kit demo all continue to render as scroll ribbons. */
  .home-trending .rail__track {
    grid-auto-flow:        row;
    grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
    grid-auto-rows:        1fr;
    grid-auto-columns:     unset;
    overflow-x:            visible;
    scroll-snap-type:      none;
    padding-inline:        0;
  }

  .home-trending .rail__item {
    scroll-snap-align: none;
  }

  .home-trending .rail__affordance,
  .home-trending .rail__viewport::before,
  .home-trending .rail__viewport::after {
    display: none;
  }
}

.events-browse__filters,
.voting-browse__filters,
.tour-marketplace__filters {
  margin-bottom: var(--sp-5);
}

.events-browse__grid,
.voting-browse__grid,
.tour-marketplace__grid {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap:        var(--sp-5);
}

.events-browse__grid-item,
.voting-browse__grid-item,
.tour-marketplace__grid-item {
  margin: 0;
}

.events-browse__empty,
.voting-browse__empty,
.tour-marketplace__empty {
  padding:          var(--sp-7) var(--sp-5);
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  text-align:       center;
}

.events-browse__empty-headline,
.voting-browse__empty-headline,
.tour-marketplace__empty-headline {
  font-family: var(--font-serif);
  font-size:   var(--fs-4);
  color:       var(--n-900);
  margin:      0 0 var(--sp-2);
}

.events-browse__empty-hint,
.voting-browse__empty-hint,
.tour-marketplace__empty-hint {
  font-size: var(--fs-2);
  color:     var(--n-500);
  margin:    0 0 var(--sp-4);
}

.events-browse__empty-cta,
.voting-browse__empty-cta,
.tour-marketplace__empty-cta {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  min-height:       44px;
  min-width:        44px;
  padding:          0 var(--sp-6);
  border:           1px solid var(--brand-ink);
  border-radius:    var(--r-5);
  background-color: var(--n-0);
  color:            var(--brand-ink);
  font-family:      var(--font-sans);
  font-size:        var(--fs-2);
  font-weight:      600;
  text-decoration:  none;
  transition:       background-color var(--d-1) var(--ease-out-swift),
                    color var(--d-1) var(--ease-out-swift);
}

.events-browse__empty-cta:hover,
.events-browse__empty-cta:focus-visible,
.voting-browse__empty-cta:hover,
.voting-browse__empty-cta:focus-visible,
.tour-marketplace__empty-cta:hover,
.tour-marketplace__empty-cta:focus-visible {
  background-color: var(--brand-ink);
  color:            var(--n-0);
}

.events-browse__empty-cta:focus-visible,
.voting-browse__empty-cta:focus-visible,
.tour-marketplace__empty-cta:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.events-browse__pagination,
.voting-browse__pagination,
.tour-marketplace__pagination {
  display:         flex;
  justify-content: center;
  margin-top:      var(--sp-7);
}

.events-browse__load-more,
.voting-browse__load-more,
.tour-marketplace__load-more {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  min-height:       44px;
  padding:          0 var(--sp-7);
  border:           1px solid var(--brand-ink);
  border-radius:    var(--r-5);
  background-color: var(--n-0);
  color:            var(--brand-ink);
  font-family:      var(--font-sans);
  font-size:        var(--fs-2);
  font-weight:      600;
  text-decoration:  none;
  transition:       background-color var(--d-1) var(--ease-out-swift),
                    color var(--d-1) var(--ease-out-swift);
}

.events-browse__load-more:hover,
.events-browse__load-more:focus-visible,
.voting-browse__load-more:hover,
.voting-browse__load-more:focus-visible,
.tour-marketplace__load-more:hover,
.tour-marketplace__load-more:focus-visible {
  background-color: var(--brand-ink);
  color:            var(--n-0);
}

.events-browse__load-more:focus-visible,
.voting-browse__load-more:focus-visible,
.tour-marketplace__load-more:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

/* ContentCard CTA pills — rendered into Cta slot via HtmlString from each
   list view. Token-driven; teal-success for active CTAs, neutral surface for
   sold-out / disabled treatments. */
.events-browse__cta,
.voting-browse__cta,
.tour-marketplace__cta {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  min-height:       44px;
  min-width:        44px;
  padding:          0 var(--sp-5);
  border-radius:    var(--r-3);
  background-color: var(--brand-ink);
  color:            var(--n-0);
  font-family:      var(--font-sans);
  font-size:        var(--fs-1);
  font-weight:      700;
  letter-spacing:   0.02em;
  text-decoration:  none;
}

.events-browse__cta--soldout {
  background-color: var(--n-200);
  color:            var(--n-600);
}

@media (prefers-reduced-motion: reduce) {
  .events-browse__empty-cta,
  .events-browse__load-more,
  .voting-browse__empty-cta,
  .voting-browse__load-more,
  .tour-marketplace__empty-cta,
  .tour-marketplace__load-more {
    transition: none;
  }
}

/* ==========================================================================
   Category landing — M07 Phase 5 (W4.v2.4)
   Slug-driven editorial landing at /category/{slug}.
   Composition: Hero --sm + featured ContentCard + up to three rails.
   The rails reuse the kit Rail family; only the featured wrapper is
   bespoke here. Token-driven; no raw hex, no raw ms.
   ========================================================================== */

.category-landing__featured {
  padding:    var(--sp-7) var(--sp-5);
  max-width:  1200px;
  margin:     0 auto;
}

.category-landing__featured-header {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-2);
  margin-bottom:  var(--sp-5);
}

.category-landing__featured-eyebrow {
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color:          var(--n-600);
  margin:         0;
}

.category-landing__featured-heading {
  font-family:    var(--font-serif);
  font-size:      var(--fs-5);
  font-weight:    700;
  color:          var(--n-900);
  margin:         0;
}

.category-landing__featured-card {
  /* Single-card row — the kit ContentCard already has its own
     styling; this wrapper just provides a max-width to keep the
     featured piece editorially centred on wide viewports. */
  max-width: 720px;
}

@media (min-width: 768px) {
  .category-landing__featured {
    padding: var(--sp-8) var(--sp-6);
  }
}


/* ==========================================================================
   PUBLIC NAVBAR (.nav-public)
   Mandate: M08 · C5 Navigation IA · Phase 1 (W5.1, W5.2, W5.3)
   Source: Views/Shared/_PublicNavBar.cshtml
   Height: --nav-h (4rem / 64px) at viewport >= 1024px.
   Class prefix isolates the refreshed primitive from legacy .nav-bar in
   wwwroot/custom/custom.css (purged at C10 / Mandate 18).
   ========================================================================== */

.nav-public {
  display:           none; /* desktop-only; mobile nav is owned by Mandate 10 */
  background-color:  var(--n-0);
  border-bottom:     1px solid var(--n-200);
  font-family:       var(--font-sans);
  color:             var(--brand-ink);
  position:          relative;
  z-index:           var(--z-sticky);
}

@media (min-width: 768px) {
  .nav-public {
    display: block;
  }
}

.nav-public__inner {
  display:          flex;
  align-items:      stretch;
  gap:              var(--sp-2);
  height:           var(--nav-h);
  max-width:        1280px;
  margin:           0 auto;
  padding:          0 var(--sp-5);
}

.nav-public__list {
  display:        flex;
  align-items:    stretch;
  gap:            var(--sp-1);
  margin:         0;
  /* M30 Phase 2 (F-2-1 / L6) — main-menu text-start alignment with content
     grid. .nav-public__inner contributes 24px (--sp-5) of left padding,
     matching .container / .home-rails__container / .hero__grid. The first
     .nav-public__link contributes another 12px (--sp-3) of left padding,
     pushing the visible "Home" text 12px past the content grid's left edge.
     Negative inline-start margin on the list pulls the entire row back by
     exactly the link's left padding so the first item's text aligns with
     content (hero headline, rail headers) at the 24px-from-1280px-frame
     position. Inter-link padding + gap are preserved untouched. */
  margin-inline-start: calc(var(--sp-3) * -1);
  padding:        0;
  list-style:     none;
}

.nav-public__item {
  position: relative;
  display:  flex;
  align-items: stretch;
}

.nav-public__link {
  display:           inline-flex;
  align-items:       center;
  gap:               var(--sp-2);
  min-height:        44px; /* hard rule #8 */
  padding:           0 var(--sp-3);
  font-size:         var(--fs-3);
  font-weight:       500;
  color:             var(--brand-ink);
  text-decoration:   none;
  border-bottom:     2px solid transparent;
  transition:        color        var(--d-1) var(--ease-out-swift),
                     border-color var(--d-1) var(--ease-out-swift),
                     background-color var(--d-1) var(--ease-out-swift);
  cursor:            pointer;
}

.nav-public__link:hover,
.nav-public__link:focus-visible {
  color:        var(--brand-ink);
  background-color: color-mix(in srgb, var(--brand-ink) 4%, transparent);
}

.nav-public__link:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: -3px;
}

.nav-public__link.is-active,
.nav-public__link[aria-current="page"] {
  border-bottom-color: var(--brand-spark);
  font-weight:         600;
}

.nav-public__caret {
  font-size: var(--fs-2);
  line-height: 1;
}

/* Single-level dropdown panel — replaces the legacy .mega-menu structure for
   Events (W5.2) and the Travel & Tours top-level grouping. No nested columns,
   no horizontal panel — a vertical link list. */
.nav-public__dropdown {
  position:         absolute;
  top:              100%;
  left:             0;
  min-width:        240px;
  margin:           0;
  padding:          var(--sp-2) 0;
  list-style:       none;
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-2);
  box-shadow:       var(--shadow-3);
  opacity:          0;
  visibility:       hidden;
  transform:        translateY(var(--sp-1));
  transition:       opacity   var(--d-2) var(--ease-out-swift),
                    transform var(--d-2) var(--ease-out-swift),
                    visibility var(--d-2) var(--ease-out-swift);
  z-index:          var(--z-dropdown);
}

.nav-public__item:hover .nav-public__dropdown,
.nav-public__item:focus-within .nav-public__dropdown,
.nav-public__link[aria-expanded="true"] + .nav-public__dropdown {
  opacity:    1;
  visibility: visible;
  transform:  translateY(0);
}

.nav-public__dropdown-link {
  display:         block;
  min-height:      44px; /* hard rule #8 */
  padding:         var(--sp-2) var(--sp-4);
  font-size:       var(--fs-2);
  color:           var(--brand-ink);
  text-decoration: none;
  line-height:     1.4;
  transition:      background-color var(--d-1) var(--ease-out-swift);
}

.nav-public__dropdown-link:hover,
.nav-public__dropdown-link:focus-visible {
  background-color: var(--n-50);
}

.nav-public__dropdown-link:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: -3px;
}


/* ==========================================================================
   USER MENU (.user-menu)
   Mandate: M08 · C5 Navigation IA · Phase 1 (W5.4)
   Source: Views/Shared/_UserMenu.cshtml — single shared partial used by both
   _LayoutPublic.cshtml (via _PublicHeader.cshtml call-site) and _Layout.cshtml
   (admin chrome). Branches server-side on IsCurrentUserSystemUser() +
   IsPermissionAllowedAsync(...) — never on a controller-passed prop.
   ========================================================================== */

.user-menu {
  position:         absolute;
  top:              calc(100% + var(--sp-1));
  right:            0;
  min-width:        260px;
  margin:           0;
  padding:          var(--sp-2) 0;
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  box-shadow:       var(--shadow-3);
  list-style:       none;
  font-family:      var(--font-sans);
  color:            var(--brand-ink);
  opacity:          0;
  visibility:       hidden;
  transform:        translateY(var(--sp-1));
  transition:       opacity   var(--d-2) var(--ease-out-swift),
                    transform var(--d-2) var(--ease-out-swift),
                    visibility var(--d-2) var(--ease-out-swift);
  z-index:          var(--z-dropdown);
}

.user-menu.is-open,
.user-menu[data-open="true"] {
  opacity:    1;
  visibility: visible;
  transform:  translateY(0);
}

.user-menu__header {
  padding:       var(--sp-3) var(--sp-4) var(--sp-2);
  border-bottom: 1px solid var(--n-100);
  margin-bottom: var(--sp-1);
}

.user-menu__name {
  display:     block;
  font-size:   var(--fs-3);
  font-weight: 600;
  color:       var(--brand-ink);
  line-height: 1.3;
  word-break:  break-word;
}

.user-menu__email {
  display:    block;
  font-size:  var(--fs-1);
  color:      var(--n-500);
  line-height: 1.3;
  word-break:  break-word;
}

.user-menu__group {
  padding: 0;
  margin:  0;
}

.user-menu__divider {
  height:        1px;
  margin:        var(--sp-2) 0;
  background:    var(--n-100);
  border:        none;
}

.user-menu__item {
  display:         flex;
  align-items:     center;
  gap:             var(--sp-3);
  min-height:      44px; /* hard rule #8 */
  padding:         var(--sp-2) var(--sp-4);
  font-size:       var(--fs-2);
  color:           var(--brand-ink);
  text-decoration: none;
  background:      transparent;
  border:          none;
  width:           100%;
  text-align:      left;
  cursor:          pointer;
  transition:      background-color var(--d-1) var(--ease-out-swift),
                   color            var(--d-1) var(--ease-out-swift);
}

.user-menu__item:hover,
.user-menu__item:focus-visible {
  background-color: var(--n-50);
}

.user-menu__item:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: -3px;
}

.user-menu__item--danger {
  color: var(--state-danger);
}

.user-menu__item--danger:hover,
.user-menu__item--danger:focus-visible {
  background-color: color-mix(in srgb, var(--state-danger) 8%, transparent);
}

.user-menu__icon {
  font-size: var(--fs-3);
  line-height: 1;
  flex-shrink: 0;
}


/* ==========================================================================
   PUBLIC FOOTER (.footer-public)
   Mandate: M08 · C5 Navigation IA · Phase 1 (W5.5)
   Source: Views/Shared/_PublicFooter.cshtml
   Layout: brand strip on top, then exactly 4 link columns
   (Product · Creators · Company · Legal). Class prefix isolates the
   refreshed primitive from legacy .footer in wwwroot/custom/custom.css.
   ========================================================================== */

.footer-public {
  background-color: var(--brand-ink);
  color:            var(--n-100);
  font-family:      var(--font-sans);
  padding:          var(--sp-7) 0 var(--sp-5);
  margin-top:       var(--sp-7);
}

.footer-public__inner {
  max-width: 1280px;
  margin:    0 auto;
  padding:   0 var(--sp-5);
}

.footer-public__brand {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-3);
  padding-bottom: var(--sp-6);
  margin-bottom:  var(--sp-6);
  border-bottom:  1px solid color-mix(in srgb, var(--n-0) 12%, transparent);
}

.footer-public__brand-logo {
  height:    auto;
  max-width: 140px;
}

/* Logo invert filter — replaces the inline style="filter:..." that lived on
   _PublicFooter.cshtml line 19 (F-0-10). The brand logo asset is dark-on-light
   by default; the footer surface is dark, so we invert. */
.footer-public__brand-logo--invert {
  filter: brightness(0) invert(1);
}

.footer-public__tagline {
  font-size:  var(--fs-2);
  line-height: 1.55;
  color:      color-mix(in srgb, var(--n-0) 75%, var(--brand-ink));
  max-width:  56ch;
  margin:     0;
}

/* M31 Phase 7 · F-7-5 / N27: .footer-public__socials and .footer-public__social
   selectors deleted alongside the social icons block in _PublicFooter.cshtml.
   The reduced-motion rule lower in this file also drops .footer-public__social. */

.footer-public__grid {
  display:               grid;
  grid-template-columns: 1fr;
  gap:                   var(--sp-6);
}

@media (min-width: 768px) {
  .footer-public__grid {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (min-width: 1024px) {
  .footer-public__grid {
    grid-template-columns: repeat(3, 1fr); /* 3 columns post-cleanup — Product · Company · Legal */
  }
}

.footer-public__col {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-2);
}

.footer-public__col-heading {
  font-family:     var(--font-mono);
  font-size:       var(--fs-1);
  font-weight:     600;
  text-transform:  uppercase;
  letter-spacing:  0.08em;
  color:           color-mix(in srgb, var(--n-0) 60%, var(--brand-ink));
  margin:          0 0 var(--sp-2) 0;
}

.footer-public__link {
  display:         inline-flex;
  align-items:     center;
  gap:             var(--sp-2);
  min-height:      44px; /* hard rule #8 — anchor hit area */
  padding:         var(--sp-1) 0;
  font-size:       var(--fs-2);
  color:           var(--n-100);
  text-decoration: none;
  line-height:     1.4;
  transition:      color var(--d-1) var(--ease-out-swift);
}

.footer-public__link:hover,
.footer-public__link:focus-visible {
  color: var(--brand-spark);
}

.footer-public__link:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
  border-radius:  var(--r-1);
}

.footer-public__icon {
  font-size: var(--fs-3);
  line-height: 1;
  flex-shrink: 0;
}

.footer-public__contact-line {
  display:    inline-flex;
  flex-wrap:  wrap;
  align-items: center;
  gap:        var(--sp-1);
  font-size:  var(--fs-2);
  color:      var(--n-100);
}

.footer-public__bottom {
  display:        flex;
  flex-wrap:      wrap;
  align-items:    center;
  justify-content: space-between;
  gap:            var(--sp-3);
  margin-top:     var(--sp-6);
  padding-top:    var(--sp-4);
  border-top:     1px solid color-mix(in srgb, var(--n-0) 12%, transparent);
  font-size:      var(--fs-1);
  color:          color-mix(in srgb, var(--n-0) 70%, var(--brand-ink));
}

.footer-public__bottom-links {
  display: inline-flex;
  flex-wrap: wrap;
  gap:     var(--sp-4);
}

.footer-public__bottom-link {
  color:           color-mix(in srgb, var(--n-0) 70%, var(--brand-ink));
  text-decoration: none;
  min-height:      44px;
  display:         inline-flex;
  align-items:     center;
  transition:      color var(--d-1) var(--ease-out-swift);
}

.footer-public__bottom-link:hover,
.footer-public__bottom-link:focus-visible {
  color: var(--brand-spark);
}

.footer-public__bottom-link:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
  border-radius:  var(--r-1);
}


/* ==========================================================================
   ADMIN HEADER HEIGHT ALIGNMENT
   Mandate: M08 · C5 Navigation IA · Phase 1 (W5.3)
   The admin chrome's <header class="admin-header"> in _Layout.cshtml gets
   pinned to --nav-h so public + admin share the same 64px chrome height.
   The .admin-header rule itself lives in custom.css (legacy); this override
   uses the same selector with the new token-derived height. Specificity is
   identical (single-class), so source order at load time wins. The
   elfrique.* sheets are loaded AFTER custom.css per HeadMeta.cshtml.
   ========================================================================== */

.admin-header {
  min-height: var(--nav-h);
}


/* ==========================================================================
   USER MENU — DATA PANELS (.user-menu__panel*)
   Mandate: M08 · C5 Navigation IA · Phase 2a · W5.v2.2.
   Source: Views/Shared/_UserMenu.cshtml (rendered when partial Model = true)
           wwwroot/js/pages/user-menu-panel.js (hydrator)
   Behavior: server renders an inert shell with .user-menu__panel-state--loading;
             user-menu-panel.js fetches /api/user-menu/{recent-orders|saved-events|drafts}
             on first menu open and swaps the body to a list / empty-state / error-state.
   Panels widen the parent .user-menu container slightly to accommodate
   two-line list rows (title + meta) without wrapping the title.
   ========================================================================== */

.user-menu[data-panel-mode="true"] {
  min-width: 320px;
}

.user-menu__panel {
  padding: var(--sp-2) 0;
}

.user-menu__panel + .user-menu__panel {
  border-top: 1px solid var(--n-100);
}

.user-menu__panel-header {
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  gap:             var(--sp-2);
  padding:         var(--sp-1) var(--sp-4);
}

.user-menu__panel-title {
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  font-weight:    600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color:          var(--n-500);
}

.user-menu__panel-view-all {
  display:         inline-flex;
  align-items:     center;
  min-height:      44px; /* hard rule #8 — keep affordance reachable on touch */
  padding:         0 var(--sp-2);
  font-size:       var(--fs-1);
  font-weight:     600;
  color:           var(--brand-ink);
  text-decoration: none;
  border-radius:   var(--r-1);
  transition:      color var(--d-1) var(--ease-out-swift);
}

.user-menu__panel-view-all:hover,
.user-menu__panel-view-all:focus-visible {
  color: var(--brand-spark);
}

.user-menu__panel-view-all:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

.user-menu__panel-body {
  padding: 0;
}

.user-menu__panel-list {
  list-style: none;
  margin:     0;
  padding:    0;
}

.user-menu__panel-item {
  margin: 0;
}

.user-menu__panel-link {
  display:         flex;
  flex-direction:  column;
  gap:             2px;
  min-height:      44px; /* hard rule #8 */
  padding:         var(--sp-2) var(--sp-4);
  text-decoration: none;
  background:      transparent;
  border:          none;
  width:           100%;
  text-align:      left;
  color:           var(--brand-ink);
  transition:      background-color var(--d-1) var(--ease-out-swift);
}

.user-menu__panel-link:hover,
.user-menu__panel-link:focus-visible {
  background-color: var(--n-50);
}

.user-menu__panel-link:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: -3px;
}

.user-menu__panel-link-title {
  display:       block;
  font-size:     var(--fs-2);
  font-weight:   500;
  line-height:   1.3;
  white-space:   nowrap;
  overflow:      hidden;
  text-overflow: ellipsis;
}

.user-menu__panel-link-meta {
  display:     block;
  font-size:   var(--fs-1);
  color:       var(--n-500);
  line-height: 1.3;
}

.user-menu__panel-state {
  margin:      0;
  padding:     var(--sp-2) var(--sp-4);
  font-size:   var(--fs-1);
  color:       var(--n-500);
  line-height: 1.4;
}

.user-menu__panel-state--empty {
  font-style: italic;
}

.user-menu__panel-state--error {
  color: var(--state-danger);
}

.user-menu__panel-state--loading {
  /* Subtle pulse to signal in-flight fetch; collapsed by reduced-motion below. */
  animation: user-menu-panel-pulse var(--d-5) var(--ease-out-swift) infinite alternate;
}

@keyframes user-menu-panel-pulse {
  from { opacity: 0.55; }
  to   { opacity: 1.00; }
}


/* ==========================================================================
   CONTEXTUAL SIDEBAR (Kit · _ContextualSidebar.cshtml)
   M08 · C5 Navigation IA · Phase 2b · W5.v2.1.

   Sibling-navigation surface rendered alongside detail-page content
   (EventDetail, VendorProfile). One markup tree; CSS media query flips
   between vertical column at >=768px and horizontal scroll-snap rail at
   <768px without forking the partial.

   Hard rules engaged:
     #2  no raw hex (token-only — verified via grep at review)
     #3  no raw ms (motion tokens only)
     #8  ≥44×44 touch target on every link (min-height: 44px below)
     #10 prefers-reduced-motion fallback in the block at the file tail
   ========================================================================== */

.contextual-sidebar {
  display:        block;
  margin:         var(--sp-5) 0 0 0;
  padding:        var(--sp-4);
  background:     var(--n-0);
  border:         1px solid var(--n-100);
  border-radius:  var(--r-3);
  box-shadow:     var(--shadow-1);
}

.contextual-sidebar__header {
  display:        flex;
  align-items:    baseline;
  justify-content: space-between;
  gap:            var(--sp-3);
  margin-bottom:  var(--sp-3);
}

.contextual-sidebar__eyebrow {
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color:          var(--n-600);
  margin:         0 0 var(--sp-1) 0;
}

.contextual-sidebar__heading {
  font-family:    var(--font-serif);
  font-size:      var(--fs-3);
  font-weight:    600;
  color:          var(--brand-ink);
  margin:         0;
  line-height:    1.2;
}

.contextual-sidebar__see-all {
  display:        inline-flex;
  align-items:    center;
  gap:            var(--sp-1);
  flex-shrink:    0;
  min-height:     44px;
  padding:        var(--sp-1) var(--sp-2);
  font-family:    var(--font-sans);
  font-size:      var(--fs-1);
  font-weight:    500;
  color:          var(--brand-ink);
  text-decoration: none;
  border-radius:  var(--r-2);
  transition:     background var(--d-1) var(--ease-out-swift),
                  color var(--d-1) var(--ease-out-swift);
}

.contextual-sidebar__see-all:hover,
.contextual-sidebar__see-all:focus-visible {
  background:     var(--n-50);
  color:          var(--brand-spark);
}

.contextual-sidebar__see-all:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.contextual-sidebar__see-all-glyph {
  font-size:      var(--fs-2);
  line-height:    1;
}

.contextual-sidebar__list {
  list-style:     none;
  margin:         0;
  padding:        0;
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-1);
}

.contextual-sidebar__item {
  margin:         0;
  padding:        0;
}

.contextual-sidebar__link {
  display:        flex;
  align-items:    center;
  gap:            var(--sp-3);
  min-height:     44px;
  padding:        var(--sp-2);
  border-radius:  var(--r-2);
  text-decoration: none;
  color:          inherit;
  background:     transparent;
  transition:     background var(--d-1) var(--ease-out-swift),
                  transform var(--d-1) var(--ease-out-swift);
}

.contextual-sidebar__link:hover,
.contextual-sidebar__link:focus-visible {
  background:     var(--n-50);
}

.contextual-sidebar__link:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.contextual-sidebar__avatar {
  flex-shrink:    0;
  width:          48px;
  height:         48px;
  border-radius:  var(--r-2);
  overflow:       hidden;
  display:        inline-flex;
  align-items:    center;
  justify-content: center;
  background:     var(--n-100);
  color:          var(--brand-ink);
}

.contextual-sidebar__avatar-img {
  width:          100%;
  height:         100%;
  object-fit:     cover;
  display:        block;
}

.contextual-sidebar__avatar-initials {
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  font-weight:    700;
  letter-spacing: 0.04em;
}

.contextual-sidebar__body {
  display:        flex;
  flex-direction: column;
  gap:            calc(var(--sp-1) / 2);
  min-width:      0;
  flex:           1 1 auto;
}

.contextual-sidebar__title {
  font-family:    var(--font-sans);
  font-size:      var(--fs-2);
  font-weight:    600;
  color:          var(--brand-ink);
  line-height:    1.3;
  /* Truncate runaway titles in the narrow vertical sidebar without
     hard-clipping the visual rhythm. */
  overflow:       hidden;
  text-overflow:  ellipsis;
  display:        -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  word-break:     break-word;
}

.contextual-sidebar__meta {
  font-family:    var(--font-sans);
  font-size:      var(--fs-1);
  color:          var(--n-600);
  line-height:    1.3;
  overflow:       hidden;
  text-overflow:  ellipsis;
  white-space:    nowrap;
}

/* --------------------------------------------------------------------------
   Empty-state CTA (F-2b-07, M08 Phase 2c).
   Renders when ContextualSidebarViewModel.Items is empty and SeeAllUrl is
   set. Replaces the Phase 2b early-return; surface stays present in DOM so
   the page rhythm doesn't shift, and the user gets a recovery path
   (no "coming soon" placeholder — public-pages rule).
   -------------------------------------------------------------------------- */

.contextual-sidebar__empty {
  font-family:    var(--font-sans);
  font-size:      var(--fs-1);
  color:          var(--n-600);
  margin:         var(--sp-2) 0 var(--sp-3) 0;
}

.contextual-sidebar__empty-cta {
  /* Hard rule #8 — 44×44 touch target. */
  display:        inline-flex;
  align-items:    center;
  gap:            var(--sp-1);
  min-height:     44px;
  padding:        var(--sp-2) var(--sp-3);
  font-family:    var(--font-sans);
  font-size:      var(--fs-1);
  font-weight:    600;
  color:          var(--brand-ink);
  text-decoration: none;
  background:     var(--n-50);
  border:         1px solid var(--n-100);
  border-radius:  var(--r-2);
  transition:     background var(--d-1) var(--ease-out-swift),
                  color var(--d-1) var(--ease-out-swift),
                  border-color var(--d-1) var(--ease-out-swift);
}

.contextual-sidebar__empty-cta:hover,
.contextual-sidebar__empty-cta:focus-visible {
  background:     var(--n-0);
  color:          var(--brand-spark);
  border-color:   var(--brand-spark);
}

.contextual-sidebar__empty-cta:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.contextual-sidebar__empty-cta-glyph {
  font-size:      var(--fs-2);
  line-height:    1;
}

/* --------------------------------------------------------------------------
   Mobile (< 768px) — horizontal scroll-snap rail.
   Verification test case TC-NAV-014 (Phase 0): list flips from vertical
   column to horizontal overflow-x: auto with scroll-snap-type: x mandatory.
   -------------------------------------------------------------------------- */

@media (max-width: 767.98px) {
  .contextual-sidebar {
    /* Let the rail bleed to the container edges so the first/last item
       hint at scrollable content beyond the viewport. */
    padding-inline: var(--sp-3);
  }

  .contextual-sidebar__list {
    flex-direction: row;
    gap:            var(--sp-3);
    overflow-x:     auto;
    overflow-y:     hidden;
    scroll-snap-type: x mandatory;
    /* Inner padding so focus rings on the first/last item aren't clipped. */
    padding:        var(--sp-1) var(--sp-1) var(--sp-2) var(--sp-1);
    -webkit-overflow-scrolling: touch;
  }

  .contextual-sidebar__item {
    scroll-snap-align: start;
    flex:           0 0 auto;
    /* Card-shaped horizontal rows that fit ~2 per viewport at 375px. */
    width:          15rem;
    max-width:      80vw;
  }

  .contextual-sidebar__link {
    /* Stack avatar above body in the horizontal rail to give the title
       room to breathe at narrow widths. */
    flex-direction: column;
    align-items:    flex-start;
    gap:            var(--sp-2);
    height:         100%;
    background:     var(--n-50);
  }

  .contextual-sidebar__title {
    -webkit-line-clamp: 3;
  }
}


/* ==========================================================================
   BREADCRUMB PEER-REVEAL  (Public · _Breadcrumbs.cshtml)
   M08 · C5 Navigation IA · Phase 2c · W5.v2.3.

   Per-crumb sibling/peer panel revealed on hover OR keyboard focus. The
   trigger is a <button> sibling of the crumb label inside the same <li>;
   the panel is an absolutely-positioned <div role="menu"> that becomes
   visible when the host <li> is hovered, focus-within, or the trigger has
   aria-expanded="true". The CSS-only :hover / :focus-within reveal is the
   primary path; the JS at wwwroot/js/pages/breadcrumb-peer-reveal.js keeps
   aria-expanded mirrored (assistive-tech parity) and adds Escape / Tab /
   click-outside semantics.

   Hard rules engaged:
     #2  no raw hex (token-only — verified at review)
     #3  no raw ms (motion tokens only — --d-1, --ease-out-swift)
     #8  trigger ≥ 44×44px effective hit area
     #10 prefers-reduced-motion fallback in the block at file tail
   ========================================================================== */

.breadcrumb-item {
  position:      relative;
  display:       inline-flex;
  align-items:   center;
  gap:           var(--sp-1);
}

.breadcrumb-item__label {
  display:       inline-flex;
  align-items:   center;
}

.breadcrumb-item__link,
.breadcrumb-item__text {
  font-family:   var(--font-sans);
  font-size:     var(--fs-1);
  color:         inherit;
  text-decoration: none;
}

.breadcrumb-item__link {
  color:         var(--brand-ink);
  transition:    color var(--d-1) var(--ease-out-swift);
}

.breadcrumb-item__link:hover,
.breadcrumb-item__link:focus-visible {
  color:         var(--brand-spark);
  text-decoration: underline;
}

.breadcrumb-peer-trigger {
  /* Hard rule #8 — 44×44 effective hit. The visible glyph stays compact;
     the padding expands the click/tap surface. */
  display:        inline-flex;
  align-items:    center;
  justify-content: center;
  min-width:      44px;
  min-height:     44px;
  padding:        0 var(--sp-2);
  background:     transparent;
  border:         0;
  border-radius:  var(--r-2);
  color:          var(--n-600);
  cursor:         pointer;
  font:           inherit;
  line-height:    1;
  transition:     background var(--d-1) var(--ease-out-swift),
                  color var(--d-1) var(--ease-out-swift);
}

.breadcrumb-peer-trigger:hover,
.breadcrumb-peer-trigger:focus-visible {
  background:     var(--n-50);
  color:          var(--brand-ink);
}

.breadcrumb-peer-trigger:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

.breadcrumb-peer-trigger__glyph {
  display:        inline-block;
  font-size:      var(--fs-1);
  transition:     transform var(--d-1) var(--ease-out-swift);
}

/* Rotate the chevron when the panel is open — visible affordance that
   complements the aria-expanded state. */
.breadcrumb-peer-trigger[aria-expanded="true"] .breadcrumb-peer-trigger__glyph {
  transform: rotate(180deg);
}

.breadcrumb-peer-panel {
  /* The host <li> has position: relative; this absolute layer sits flush
     under the crumb. Width is intrinsic up to a sane cap so a long peer
     label doesn't blow the panel across the viewport. */
  position:       absolute;
  top:            calc(100% + var(--sp-1));
  left:           0;
  z-index:        20;
  min-width:      14rem;
  max-width:      22rem;
  padding:        var(--sp-1);
  background:     var(--n-0);
  border:         1px solid var(--n-100);
  border-radius:  var(--r-3);
  box-shadow:     var(--shadow-2, var(--shadow-1));
  /* Reveal animation — fades + slides 4px down to surface. The transition
     duration is via motion tokens; the prefers-reduced-motion block at the
     file tail zeroes it out. The [hidden] attribute is the canonical
     visibility gate; opacity/transform are layered on top so the reveal
     animates rather than snaps when motion IS allowed. */
  opacity:        1;
  transform:      translateY(0);
  transition:     opacity var(--d-1) var(--ease-out-swift),
                  transform var(--d-1) var(--ease-out-swift);
}

.breadcrumb-peer-panel[hidden] {
  /* The hidden attribute is overridden so we can animate; the panel is
     instead made visually inert via opacity 0 + pointer-events: none. */
  display:        block;
  opacity:        0;
  transform:      translateY(-4px);
  pointer-events: none;
}

.breadcrumb-peer-panel__list {
  list-style:     none;
  margin:         0;
  padding:        0;
  display:        flex;
  flex-direction: column;
}

.breadcrumb-peer-panel__item {
  margin:         0;
  padding:        0;
}

.breadcrumb-peer-panel__link {
  /* Hard rule #8 — every menuitem is itself a 44×44 touch target. */
  display:        block;
  min-height:     44px;
  padding:        var(--sp-2) var(--sp-3);
  font-family:    var(--font-sans);
  font-size:      var(--fs-1);
  color:          var(--brand-ink);
  text-decoration: none;
  border-radius:  var(--r-2);
  line-height:    1.4;
  transition:     background var(--d-1) var(--ease-out-swift),
                  color var(--d-1) var(--ease-out-swift);
}

.breadcrumb-peer-panel__link:hover,
.breadcrumb-peer-panel__link:focus-visible {
  background:     var(--n-50);
  color:          var(--brand-spark);
}

.breadcrumb-peer-panel__link:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: -2px;
}

.breadcrumb-peer-panel__link--current {
  font-weight:    600;
  color:          var(--n-600);
  cursor:         default;
}

/* ==========================================================================
   PREFERS-REDUCED-MOTION FALLBACK
   Hard rule #10. The base elfrique.css already wires a global reduce
   media query that collapses all animation/transition durations to a
   near-instant value via the universal selector; this block adds explicit
   overrides for the navbar/userMenu/footer interactive transitions so
   reviewers can verify the fallback is acknowledged at the component level.
   Phase 2a (W5.v2.2): user-menu panel hover/focus + loading-pulse covered.
   Phase 2b (W5.v2.1): contextual-sidebar link/see-all transitions covered.
   Phase 2c (W5.v2.3): breadcrumb peer-reveal trigger / glyph / panel /
                       link transitions covered.
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  .nav-public__link,
  .nav-public__dropdown,
  .nav-public__dropdown-link,
  .user-menu,
  .user-menu__item,
  .user-menu__panel-view-all,
  .user-menu__panel-link,
  .footer-public__link,
  .footer-public__bottom-link,
  .contextual-sidebar__link,
  .contextual-sidebar__see-all,
  .contextual-sidebar__empty-cta,
  .breadcrumb-item__link,
  .breadcrumb-peer-trigger,
  .breadcrumb-peer-trigger__glyph,
  .breadcrumb-peer-panel,
  .breadcrumb-peer-panel__link {
    transition: none;
  }

  .breadcrumb-peer-trigger[aria-expanded="true"] .breadcrumb-peer-trigger__glyph {
    /* Skip the rotation animation; chevron snaps to flipped state instead. */
    transition: none;
  }

  .user-menu__panel-state--loading {
    animation: none;
    opacity:   1;
  }
}

/* ============================================================
   M09 Phase 1 — Checkout-as-pages
   Layout primitives for /checkout/review, /checkout/pay, /checkout/confirm/{orderId}.
   AND migrated `oc-*` / `order-card` block from site.css (legacy OrderConfirmation.cshtml).
   Token translation applied per docs/work/2026-04-18-mandate-07-c4-public-surface/sweep-log.md.
   No raw hex. No raw ms. Reduced-motion handled via @media (prefers-reduced-motion: reduce) below.
   ============================================================ */

.checkout-shell {
  max-width: 56rem;
  margin: 0 auto;
  padding: 2rem 1rem 4rem;
}

.checkout-shell__header {
  text-align: center;
  margin-bottom: 1.5rem;
}

.checkout-shell__eyebrow {
  font-family: var(--font-mono);
  font-size: var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--n-500);
  margin: 0 0 0.5rem;
}

.checkout-shell__title {
  font-family: var(--font-serif);
  font-size: var(--fs-5);
  color: var(--n-900);
  margin: 0 0 0.5rem;
}

.checkout-shell__subcopy {
  font-size: var(--fs-3);
  color: var(--n-700);
  margin: 0;
}

.checkout-card {
  background: var(--n-0);
  border: 1px solid var(--n-200);
  border-radius: var(--r-3);
  box-shadow: var(--shadow-1);
  overflow: hidden;
  margin-bottom: 1.5rem;
}

.checkout-card__head {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 1rem;
  padding: 1rem 1.5rem;
  background: var(--n-50);
  border-bottom: 1px solid var(--n-200);
}

.checkout-card__label {
  font-family: var(--font-mono);
  font-size: var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--n-500);
  margin: 0 0 0.25rem;
}

.checkout-card__title {
  font-family: var(--font-serif);
  font-size: var(--fs-4);
  color: var(--n-900);
  margin: 0;
}

.checkout-card__meta {
  font-size: var(--fs-2);
  color: var(--n-600);
  margin: 0.25rem 0 0;
}

.checkout-card__type {
  font-family: var(--font-mono);
  font-size: var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--brand-ink);
  background: var(--n-100);
  padding: 0.375rem 0.75rem;
  border-radius: var(--r-1);
}

/* Status badge variants on /checkout/confirm */
.checkout-card__status {
  display: inline-flex;
  align-items: center;
  gap: 0.5rem;
  font-family: var(--font-mono);
  font-size: var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  padding: 0.375rem 0.75rem;
  border-radius: var(--r-1);
}

.checkout-card__status--paid {
  background: color-mix(in srgb, var(--state-success) 12%, transparent);
  color: var(--state-success);
}

.checkout-card__status--pending {
  background: color-mix(in srgb, var(--state-warn) 12%, transparent);
  color: var(--state-warn);
}

.checkout-card__body {
  padding: 1.5rem;
}

.checkout-meta {
  display: grid;
  grid-template-columns: 1fr;
  gap: 0.5rem;
  margin: 0 0 1.25rem;
  padding: 0;
}

@media (min-width: 600px) {
  .checkout-meta {
    grid-template-columns: repeat(3, 1fr);
    gap: 1rem;
  }
}

.checkout-meta__row {
  margin: 0;
}

.checkout-meta__label {
  font-family: var(--font-mono);
  font-size: var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--n-500);
  margin: 0 0 0.25rem;
}

.checkout-meta__value {
  font-size: var(--fs-2);
  color: var(--n-800);
  margin: 0;
}

.checkout-lines {
  border-top: 1px solid var(--n-200);
  padding-top: 0.75rem;
  margin-top: 0.5rem;
}

.checkout-lines__head {
  display: grid;
  grid-template-columns: 1fr 4rem 6rem 6rem;
  gap: 0.75rem;
  padding: 0.5rem 0;
  border-bottom: 1px solid var(--n-200);
  font-family: var(--font-mono);
  font-size: var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--n-500);
}

.checkout-lines__row {
  display: grid;
  grid-template-columns: 1fr 4rem 6rem 6rem;
  gap: 0.75rem;
  padding: 0.75rem 0;
  border-bottom: 1px solid var(--n-100);
  font-size: var(--fs-2);
  color: var(--n-800);
}

.checkout-lines__row:last-child {
  border-bottom: none;
}

.checkout-lines__col--qty {
  text-align: center;
}

.checkout-lines__col--unit,
.checkout-lines__col--total {
  text-align: right;
}

.checkout-lines__col--total {
  font-weight: 600;
}

.checkout-lines__title {
  display: block;
  color: var(--n-900);
  font-weight: 500;
}

.checkout-lines__desc {
  display: block;
  font-size: var(--fs-1);
  color: var(--n-500);
  margin-top: 0.25rem;
}

.checkout-totals {
  margin: 1.25rem 0 0;
  padding-top: 1rem;
  border-top: 1px solid var(--n-200);
}

.checkout-totals__row {
  display: flex;
  justify-content: space-between;
  align-items: center;
  font-size: var(--fs-2);
  color: var(--n-700);
  padding: 0.25rem 0;
}

.checkout-totals__row--discount {
  color: var(--state-success);
}

.checkout-totals__row--grand {
  font-size: var(--fs-4);
  font-weight: 700;
  color: var(--n-900);
  margin-top: 0.5rem;
  padding-top: 0.75rem;
  border-top: 2px solid var(--n-200);
}

.checkout-actions {
  display: flex;
  gap: 0.75rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 1.5rem;
}

.checkout-actions .btn {
  min-height: 2.75rem; /* 44px touch target — CLAUDE.md hard rule 8 */
  padding: 0.625rem 1.75rem;
  font-weight: 600;
}

.checkout-actions__back {
  order: 1;
}

.checkout-actions__forward {
  order: 2;
}

/* /checkout/pay — provider chooser */
.checkout-pay-form {
  background: var(--n-0);
  border: 1px solid var(--n-200);
  border-radius: var(--r-3);
  box-shadow: var(--shadow-1);
  padding: 1.5rem;
}

.checkout-providers {
  border: 0;
  padding: 0;
  margin: 0 0 1.25rem;
}

.checkout-providers__legend {
  font-family: var(--font-mono);
  font-size: var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--n-500);
  margin-bottom: 0.75rem;
  padding: 0;
}

.checkout-providers__empty {
  font-size: var(--fs-2);
  color: var(--state-warn);
  margin: 0;
}

.checkout-provider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  padding: 0.875rem 1rem;
  border: 1px solid var(--n-200);
  border-radius: var(--r-2);
  margin-bottom: 0.5rem;
  cursor: pointer;
  min-height: 2.75rem; /* 44px touch target */
  transition: border-color var(--d-2) var(--ease-out-swift),
              background-color var(--d-2) var(--ease-out-swift);
}

.checkout-provider:hover,
.checkout-provider:focus-within {
  border-color: var(--brand-ink);
  background: var(--n-50);
}

.checkout-provider__input {
  width: 1.125rem;
  height: 1.125rem;
  margin: 0;
  accent-color: var(--brand-ink);
}

.checkout-provider__visual {
  width: 2.5rem;
  height: 2.5rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--r-1);
  background: var(--n-100);
  color: var(--brand-ink);
  font-size: var(--fs-4);
}

.checkout-provider__body {
  flex: 1 1 auto;
  display: flex;
  flex-direction: column;
}

.checkout-provider__name {
  font-size: var(--fs-3);
  font-weight: 600;
  color: var(--n-900);
}

.checkout-provider__desc {
  font-size: var(--fs-1);
  color: var(--n-500);
}

/* /checkout/confirm header (success summary) */
.checkout-confirm__header {
  text-align: center;
  margin-bottom: 1.5rem;
}

.checkout-confirm__icon {
  width: 4.5rem;
  height: 4.5rem;
  background: color-mix(in srgb, var(--state-success) 12%, transparent);
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1rem;
  color: var(--state-success);
  font-size: var(--fs-5);
}

.checkout-confirm__title {
  font-family: var(--font-serif);
  font-size: var(--fs-5);
  color: var(--n-900);
  margin: 0 0 0.5rem;
}

.checkout-confirm__subtitle {
  font-size: var(--fs-3);
  color: var(--n-700);
  margin: 0 0 0.5rem;
}

.checkout-confirm__reference {
  font-size: var(--fs-2);
  color: var(--n-500);
  margin: 0 0 0.25rem;
}

.checkout-confirm__reference strong {
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
  color: var(--brand-ink);
}

.checkout-confirm__email {
  font-size: var(--fs-2);
  color: var(--n-500);
  margin: 0;
}

/* ============================================================
   Legacy oc-* / order-card block migrated from site.css
   Used by /checkout/confirmation/{orderReference} (OrderConfirmation.cshtml).
   Tokens applied per M07 sweep-log; green-family hex BANNED (CLAUDE.md hard rule 1) — replaced with brand-ink.
   ============================================================ */

.success-header {
  text-align: center;
  margin-bottom: 2rem;
}

.success-icon {
  width: 5rem;
  height: 5rem;
  background: var(--n-100);
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 1.25rem;
}

.success-icon i {
  font-size: var(--fs-6);
  color: var(--state-success);
}

.success-title {
  font-size: var(--fs-5);
  font-weight: 700;
  color: var(--n-900);
  margin-bottom: 0.5rem;
}

.success-subtitle {
  color: var(--n-700);
  font-size: var(--fs-3);
  font-weight: 500;
  margin-bottom: 0.25rem;
}

.success-reference {
  color: var(--n-500);
  font-size: var(--fs-2);
  margin-bottom: 0.25rem;
}

.success-reference strong {
  color: var(--state-success);
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
}

.success-email {
  color: var(--n-500);
  font-size: var(--fs-2);
  margin-bottom: 0;
}

.order-card {
  border: 1px solid var(--n-200);
  border-radius: var(--r-3);
  box-shadow: var(--shadow-1);
  overflow: hidden;
}

.order-card-header {
  background: var(--brand-ink);
  padding: 1rem 1.5rem;
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.order-card-header-label {
  color: color-mix(in srgb, var(--n-0) 75%, transparent);
  font-size: var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.08em;
}

.order-card-header-ref {
  color: var(--n-0);
  font-size: var(--fs-2);
  font-weight: 600;
}

.order-card-status {
  background: color-mix(in srgb, var(--n-0) 20%, transparent);
  color: var(--n-0);
  font-size: var(--fs-1);
  padding: 0.375rem 0.875rem;
}

.order-card-body {
  padding: 1.5rem;
}

.order-meta-label {
  font-weight: 600;
  color: var(--n-700);
  margin-bottom: 0.25rem;
}

.order-meta-value {
  font-size: var(--fs-2);
  color: var(--n-500);
}

.order-divider {
  border-color: var(--n-200);
  margin: 1rem 0;
}

.order-divider--compact {
  margin-bottom: 0.75rem;
}

.order-items-table {
  margin-bottom: 0;
}

.order-items-table thead tr {
  font-size: var(--fs-1);
  font-weight: 600;
  color: var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 2px solid var(--n-200);
}

.order-items-table thead th {
  padding: 0.5rem 0;
}

.order-items-table thead th.text-center {
  text-align: center;
}

.order-items-table thead th.text-end {
  text-align: right;
}

.order-items-table tbody tr {
  font-size: var(--fs-3);
  border-bottom: 1px solid var(--n-100);
}

.order-items-table tbody td {
  padding: 0.75rem 0;
}

.item-title {
  font-weight: 600;
  color: var(--n-700);
}

.item-desc {
  font-size: var(--fs-1);
  color: var(--n-400);
}

.item-qty {
  text-align: center;
  color: var(--n-500);
}

.item-unit-price {
  text-align: right;
  color: var(--n-500);
}

.item-total {
  text-align: right;
  font-weight: 600;
  color: var(--n-700);
}

.order-totals {
  max-width: 18rem;
  margin-left: auto;
}

.totals-row {
  display: flex;
  justify-content: space-between;
  font-size: var(--fs-2);
  color: var(--n-500);
  margin-bottom: 0.375rem;
}

.totals-row.discount {
  color: var(--state-success);
}

.totals-row.grand-total {
  font-size: var(--fs-4);
  font-weight: 700;
  color: var(--n-900);
  padding-top: 0.5rem;
  border-top: 2px solid var(--n-200);
  margin-bottom: 0;
}

.order-actions {
  display: flex;
  gap: 0.75rem;
  justify-content: center;
  flex-wrap: wrap;
  margin-top: 1.5rem;
}

.order-actions .btn {
  min-height: 2.75rem; /* 44px touch target — CLAUDE.md hard rule 8 */
  padding: 0.625rem 1.75rem;
  font-weight: 600;
}

@media print {
  nav, .navbar, .top-bar, .breadcrumb, .elfrique-breadcrumb,
  footer, .footer, .bottom-tab-bar, .loader, .alert-container {
    display: none !important;
  }

  .order-actions,
  .checkout-actions {
    display: none !important;
  }

  .success-header .success-icon,
  .checkout-confirm__icon {
    display: none !important;
  }

  body {
    background: var(--n-0) !important;
  }

  .order-card,
  .checkout-card {
    box-shadow: none !important;
    border: 1px solid var(--n-200) !important;
  }
}

@media (prefers-reduced-motion: reduce) {
  .checkout-provider {
    transition: none;
  }
}


/* ==========================================================================
   M09 PHASE 2 — Vendor Profile (W7.4) + Creator Event Form (W7.3)
   Component classes added when migrating Profile.cshtml from inline styles
   to token-only CSS, plus the section-nav rail + drafts banner for the
   creator event-form sectioned-nav + autosave flow.
   Hard rules: #1 no green, #2 no raw hex, #3 no raw ms, #10 motion-fallback.
   ========================================================================== */

/* ── Vendor Profile · cards & headers ────────────────────────────────── */
.vendor-profile-card {
  margin-bottom: var(--sp-4);
}
.vendor-profile-card__body {
  display:        flex;
  align-items:    center;
  gap:            var(--sp-4);
  padding:        var(--sp-5);
}
.vendor-profile-section-title {
  font-weight:    700;
  margin-bottom:  var(--sp-3);
}
.vendor-profile-section-title--inline {
  margin: 0;
}
.vendor-profile-section-head {
  display:         flex;
  justify-content: space-between;
  align-items:     center;
  margin-bottom:   var(--sp-3);
}

/* ── Vendor Profile · header avatar + meta ───────────────────────────── */
.vendor-profile-header {
  /* nothing extra — inherits from .vendor-profile-card__body */
}
.vendor-profile-header__avatar,
.vendor-profile-header__avatar-fallback {
  width:        80px;
  height:       80px;
  border-radius: 50%;
  flex-shrink:   0;
  object-fit:    cover;
}
.vendor-profile-header__avatar-fallback {
  display:         flex;
  align-items:     center;
  justify-content: center;
  background:      var(--brand-ink);
  color:           var(--n-0);
  font-size:       var(--fs-4);
  font-weight:     700;
}
.vendor-profile-header__body {
  flex: 1;
}
.vendor-profile-header__name-row {
  display:        flex;
  align-items:    center;
  gap:            var(--sp-2);
  flex-wrap:      wrap;
  margin-bottom:  var(--sp-1);
}
.vendor-profile-header__name {
  font-weight:    700;
  margin:         0;
  color:          var(--brand-ink);
}
.vendor-profile-header__meta {
  font-size:      var(--fs-1);
  color:          var(--n-500);
  margin-bottom:  var(--sp-1);
}
.vendor-profile-header__location {
  margin-left:    var(--sp-2);
}
.vendor-profile-header__since {
  font-size:      var(--fs-1);
  color:          var(--n-400);
}
.vendor-profile-badge {
  display:         inline-flex;
  align-items:     center;
  gap:             var(--sp-1);
  padding:         var(--sp-1) var(--sp-2);
  border-radius:   var(--r-2);
  font-size:       var(--fs-0);
  font-weight:     500;
  background:      var(--n-100);
  color:           var(--n-700);
}
.vendor-profile-badge--verified {
  background:      var(--n-100);
  color:           var(--brand-ink);
}
.vendor-profile-badge--category {
  background:      var(--n-100);
  color:           var(--n-700);
  font-weight:     500;
}

/* ── Vendor Profile · details grid ───────────────────────────────────── */
.vendor-profile-details {
  font-size:      var(--fs-1);
}
.vendor-profile-details__cell {
  margin-bottom:  var(--sp-3);
}
.vendor-profile-details__label {
  color:          var(--n-500);
  font-size:      var(--fs-0);
  margin-bottom:  var(--sp-0);
}
.vendor-profile-details__value {
  color:          var(--n-700);
}
.vendor-profile-details__value--strong {
  font-weight:    600;
}

/* ── Vendor Profile · empty + portfolio cards ────────────────────────── */
.vendor-profile-empty-cell {
  text-align:     center;
  color:          var(--n-400);
}
.vendor-profile-portfolio-empty {
  text-align:     center;
  padding:        var(--sp-5) var(--sp-3);
  color:          var(--n-400);
}
.vendor-profile-portfolio-empty__icon {
  font-size:      var(--fs-5);
  display:        block;
  margin-bottom:  var(--sp-3);
}
.vendor-profile-portfolio-empty__copy {
  font-size:      var(--fs-2);
  margin:         0;
}
.vendor-profile-portfolio-card {
  border:         1px solid var(--n-200);
  border-radius:  var(--r-3);
  overflow:       hidden;
}
.vendor-profile-portfolio-card__image {
  width:          100%;
  height:         180px;
  object-fit:     cover;
  display:        block;
}
.vendor-profile-portfolio-card__footer {
  padding:        var(--sp-3);
  display:        flex;
  align-items:    center;
  justify-content: space-between;
  gap:            var(--sp-2);
}
.vendor-profile-portfolio-card__caption {
  font-size:      var(--fs-1);
  color:          var(--n-700);
  overflow:       hidden;
  text-overflow:  ellipsis;
  white-space:    nowrap;
  flex:           1;
}
.vendor-profile-portfolio-card__actions {
  display:        flex;
  gap:            var(--sp-1);
  flex-shrink:    0;
}
.vendor-profile-inline-form {
  display:        inline;
}

/* ──────────────────────────────────────────────────────────────────────
   M49 Phase 10 — vendor profile publish affordance + RTE bio rhythm
   ────────────────────────────────────────────────────────────────────── */

/* Header action button group — sits next to Edit Profile, Publish/Unpublish
   stacked horizontally with consistent gap. */
.vendor-profile-header__actions {
  display:        flex;
  gap:            var(--sp-2);
  align-items:    center;
  flex-shrink:    0;
}

/* Status badge — three modifiers (draft / published / unpublished). Colour
   discipline: published rides --state-success (teal); draft rides neutral
   tone; unpublished rides --state-warn. NO raw hex; no green. */
.vendor-profile-status-badge {
  display:         inline-flex;
  align-items:     center;
  gap:             var(--sp-1);
  padding:         var(--sp-1) var(--sp-2);
  border-radius:   var(--r-2);
  font-size:       var(--fs-0);
  font-weight:     600;
  letter-spacing:  0.02em;
  text-transform:  uppercase;
  background:      var(--n-100);
  color:           var(--n-700);
  border:          1px solid var(--n-200);
}
.vendor-profile-status-badge--draft {
  background:      var(--n-100);
  color:           var(--n-700);
  border-color:    var(--n-200);
}
.vendor-profile-status-badge--published {
  background:      color-mix(in srgb, var(--state-success) 12%, var(--n-0));
  color:           var(--state-success);
  border-color:    color-mix(in srgb, var(--state-success) 30%, transparent);
}
.vendor-profile-status-badge--unpublished {
  background:      color-mix(in srgb, var(--state-warn) 12%, var(--n-0));
  color:           var(--state-warn);
  border-color:    color-mix(in srgb, var(--state-warn) 30%, transparent);
}

/* Draft-state info banner — surfaced above the manage page header when the
   profile is in Draft AND the publish gate has missing items. Lists the
   missing requirements as a bullet list inside an info-tinted card. */
.vendor-profile-publish-banner {
  display:        flex;
  align-items:    flex-start;
  gap:            var(--sp-3);
  padding:        var(--sp-3) var(--sp-4);
  margin-bottom:  var(--sp-4);
  background:     color-mix(in srgb, var(--state-info) 8%, var(--n-0));
  border:         1px solid color-mix(in srgb, var(--state-info) 30%, transparent);
  border-radius:  var(--r-3);
  color:          var(--n-700);
}
.vendor-profile-publish-banner__icon {
  font-size:      var(--fs-3);
  color:          var(--state-info);
  flex-shrink:    0;
  line-height:    1;
}
.vendor-profile-publish-banner__body {
  flex:           1;
}
.vendor-profile-publish-banner__title {
  font-weight:    600;
  margin:         0 0 var(--sp-1) 0;
  color:          var(--brand-ink);
}
.vendor-profile-publish-banner__copy {
  margin:         0 0 var(--sp-2) 0;
  font-size:      var(--fs-1);
}
.vendor-profile-publish-banner__list {
  margin:         0;
  padding-left:   var(--sp-4);
  font-size:      var(--fs-1);
}
.vendor-profile-publish-banner__list li {
  margin-bottom:  var(--sp-1);
}

/* 2026-05-26-publish-approval-and-leaderboard Phase 5 — admin-rejection
   banner surfaced on the creator/vendor manage page when a previously
   PendingApproval listing was rejected back to Draft. Reuses the
   .vendor-profile-publish-banner family (flex chrome + bullet styling)
   and overrides only the tint + icon color to signal danger instead of
   info. Mounted as <div class="vendor-profile-publish-banner publish-rejection-banner">
   so the icon-color override cascades. */
.publish-rejection-banner {
  background:     color-mix(in srgb, var(--state-danger) 8%, var(--n-0));
  border-color:   color-mix(in srgb, var(--state-danger) 30%, transparent);
}
.publish-rejection-banner .vendor-profile-publish-banner__icon {
  color:          var(--state-danger);
}

/* Bio-text rhythm — applied to BOTH the admin manage-page Description sink
   AND the public profile About section. Mirrors the Phase 6c
   .manage-event-description-copy rule (paragraph spacing for RTE-authored
   HTML). Headings + lists inherit kit defaults. */
.vendor-profile__bio-text p + p {
  margin-top:     var(--sp-3);
}
.vendor-profile__bio-text ul,
.vendor-profile__bio-text ol {
  margin:         var(--sp-2) 0 var(--sp-2) var(--sp-4);
}

/* Owner-preview banner on the public profile (visible only to the owner
   when the profile is not Published — facade returns 404 to anyone else). */
.vendor-profile__preview-banner {
  display:        flex;
  align-items:    flex-start;
  gap:            var(--sp-3);
  padding:        var(--sp-3) var(--sp-4);
  margin-bottom:  var(--sp-4);
  background:     color-mix(in srgb, var(--state-warn) 10%, var(--n-0));
  border:         1px solid color-mix(in srgb, var(--state-warn) 30%, transparent);
  border-radius:  var(--r-3);
  color:          var(--n-700);
}
.vendor-profile__preview-banner-icon {
  font-size:      var(--fs-3);
  color:          var(--state-warn);
  flex-shrink:    0;
  line-height:    1;
}
.vendor-profile__preview-banner-body {
  flex:           1;
}
.vendor-profile__preview-banner-title {
  font-weight:    600;
  margin:         0 0 var(--sp-1) 0;
  color:          var(--brand-ink);
}
.vendor-profile__preview-banner-copy {
  margin:         0;
  font-size:      var(--fs-1);
}
.vendor-profile__preview-banner-copy a {
  color:          var(--state-info);
  text-decoration: underline;
}

/* ── Vendor Profile · drawer body forms ──────────────────────────────── */
.vendor-profile-drawer-form {
  display:         flex;
  flex-direction:  column;
  gap:             var(--sp-3);
}
.vendor-profile-drawer-form__row--split {
  display:         grid;
  grid-template-columns: 1fr 1fr;
  gap:             var(--sp-3);
}
.vendor-profile-drawer-form__actions {
  display:         flex;
  justify-content: flex-end;
  gap:             var(--sp-2);
  margin-top:      var(--sp-3);
}

/* ==========================================================================
   M09 Phase 2 W7.3 — Creator Event Form: section-nav rail + sections
   ========================================================================== */

.creator-event-form-shell {
  display:        grid;
  grid-template-columns: 220px 1fr;
  gap:            var(--sp-5);
}

@media (max-width: 768px) {
  .creator-event-form-shell {
    grid-template-columns: 1fr;
  }
}

.creator-event-section-nav {
  position:       sticky;
  top:            var(--sp-4);
  align-self:     start;
}

.creator-event-section-nav__list {
  list-style:     none;
  padding:        0;
  margin:         0;
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-1);
}

.creator-event-section-nav__item {
  margin: 0;
}

.creator-event-section-nav__link {
  display:        flex;
  align-items:    center;
  gap:            var(--sp-2);
  padding:        var(--sp-3);
  border-radius:  var(--r-2);
  text-decoration: none;
  color:          var(--n-700);
  font-size:      var(--fs-1);
  /* Hard rule #8 — touch target ≥44×44; padding above clears the threshold. */
  min-height:     44px;
  transition:     background-color var(--d-2) var(--ease-out-swift);
}

.creator-event-section-nav__link:hover {
  background:     var(--n-100);
}

.creator-event-section-nav__link:focus-visible {
  outline:        2px solid var(--brand-ink);
  outline-offset: 2px;
}

.creator-event-section-nav__link--active,
.creator-event-section-nav__link[aria-current="true"] {
  background:     var(--brand-ink);
  color:          var(--n-0);
}

.creator-event-section-nav__index {
  width:          24px;
  height:         24px;
  border-radius:  50%;
  background:     var(--n-100);
  color:          var(--n-700);
  display:        flex;
  align-items:    center;
  justify-content: center;
  font-size:      var(--fs-0);
  font-weight:    600;
  flex-shrink:    0;
}

.creator-event-section-nav__link--active .creator-event-section-nav__index,
.creator-event-section-nav__link[aria-current="true"] .creator-event-section-nav__index {
  background:     var(--n-0);
  color:          var(--brand-ink);
}

.creator-event-section-nav__label {
  font-weight:    500;
}

@media (prefers-reduced-motion: reduce) {
  .creator-event-section-nav__link {
    transition: none;
  }
}

.creator-event-form-section {
  padding:        var(--sp-4) 0;
  border-bottom:  1px solid var(--n-200);
}
.creator-event-form-section:first-of-type {
  padding-top:    0;
}
.creator-event-form-section:last-of-type {
  border-bottom:  none;
}
.creator-event-form-section__heading {
  font-size:      var(--fs-3);
  font-weight:    700;
  color:          var(--brand-ink);
  margin-bottom:  var(--sp-1);
}
.creator-event-form-section__copy {
  color:          var(--n-500);
  font-size:      var(--fs-1);
  margin-bottom:  var(--sp-3);
}
.creator-event-form-section:focus-visible {
  outline:        2px solid var(--brand-ink);
  outline-offset: 4px;
  border-radius:  var(--r-2);
}

/* ── M50 Phase 16 — CustomCategoryText disclosure ─────────────────────── */
.creator-event-form-custom-category {
  overflow:       hidden;
  max-height:     400px;
  opacity:        1;
  transition:     max-height var(--d-3) var(--ease-out-swift),
                  opacity   var(--d-2) var(--ease-out-swift);
}
.creator-event-form-custom-category--hidden {
  max-height:     0;
  opacity:        0;
  padding:        0;
  margin:         0;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .creator-event-form-custom-category {
    transition:   none;
  }
}

/* ── M50 Phase 17 — form row gap re-tokenised to var(--sp-5) ─────────────
   Mirrors Bootstrap's .row gutter contract — the project class only
   overrides --bs-gutter-x / --bs-gutter-y so col-* responsive math behaves
   exactly as before. Pairs with `<div class="row creator-event-form-row">`
   in Views/CreatorEvent/_EventForm.cshtml. Anti-scope: do not generalise
   to a global .row tweak; this class is scoped to the creator-event form
   sections by name.
 */
.creator-event-form-row {
  --bs-gutter-x:  var(--sp-5);
  --bs-gutter-y:  var(--sp-5);
}

/* ── M50 Phase 17 — IsFree → ticket-pricing-note disclosure ──────────────
   Parallel to the CustomCategoryText pattern above. Class toggle is driven
   by event-form.js handleIsFreeChange — when IsFree is checked the note
   collapses (free events skip paid pricing); when unchecked the note
   surfaces. Motion-token transitions only; prefers-reduced-motion: reduce
   nukes the transition so reduced-motion users get instant snap (HR10).
 */
.creator-event-form-ticket-pricing-note {
  overflow:       hidden;
  max-height:     400px;
  opacity:        1;
  transition:     max-height var(--d-3) var(--ease-out-swift),
                  opacity   var(--d-2) var(--ease-out-swift);
}
.creator-event-form-ticket-pricing-note--hidden {
  max-height:     0;
  opacity:        0;
  padding:        0;
  margin:         0;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .creator-event-form-ticket-pricing-note {
    transition:   none;
  }
}

.creator-form-header {
  display:        flex;
  align-items:    center;
  gap:            var(--sp-3);
}
.creator-form-header__status {
  margin-left:    auto;
  font-size:      var(--fs-1);
  color:          var(--n-500);
  min-height:     1.5em;
}

/* ── Creator Event · drafts banner (resume) ──────────────────────────── */
.creator-event-drafts-banner {
  background:     var(--n-50);
  border:         1px solid var(--n-200);
  border-radius:  var(--r-3);
  padding:        var(--sp-3) var(--sp-4);
  margin-bottom:  var(--sp-4);
}
.creator-event-drafts-banner__head {
  display:        flex;
  align-items:    center;
  gap:            var(--sp-2);
  margin-bottom:  var(--sp-2);
}
.creator-event-drafts-banner__icon {
  color:          var(--brand-ink);
  font-size:      var(--fs-3);
}
.creator-event-drafts-banner__title {
  font-weight:    600;
  color:          var(--brand-ink);
}
.creator-event-drafts-banner__list {
  list-style:     none;
  padding:        0;
  margin:         0;
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-2);
}
.creator-event-drafts-banner__row {
  display:        flex;
  align-items:    center;
  gap:            var(--sp-3);
  padding:        var(--sp-2) 0;
  flex-wrap:      wrap;
}
.creator-event-drafts-banner__draft-title {
  font-weight:    600;
  color:          var(--n-700);
}
.creator-event-drafts-banner__draft-meta {
  color:          var(--n-500);
  font-size:      var(--fs-0);
  flex:           1;
}

/* M09 Phase 5 / W7.v2.3 — Pager controls. Visible only when > 5 drafts. */
.creator-event-drafts-banner__pager {
  display:        flex;
  align-items:    center;
  justify-content:flex-end;
  gap:            var(--sp-3);
  margin-top:     var(--sp-3);
  padding-top:    var(--sp-2);
  border-top:     1px solid var(--n-200);
}
.creator-event-drafts-banner__pager[hidden] {
  display:        none;
}
.creator-event-drafts-banner__pager-label {
  font-family:    var(--font-sans);
  font-size:      var(--fs-1);
  color:          var(--n-600);
}

/* ==========================================================================
   AUTH SHELL  (M09 Phase 3a — re-rolled in place)
   Hosts Login, BeginResetPassword, ResetPassword, SignUp behind _LayoutAuth.
   Token-only — replaces the legacy `wwwroot/custom/auth-pages.css` file plus
   the inline <style> block previously embedded in _LayoutAuth.cshtml.

   Brand language: private-bank welcome. Brand-ink chrome, generous whitespace,
   serif headlines, sans body. Green-as-brand from the legacy auth shell is
   gone — accent is --brand-ink (near-black-green) per CLAUDE.md hard rule #1.
   ========================================================================== */

.auth-page {
  background-color: var(--n-50);
  min-height:       100vh;
  display:          flex;
  flex-direction:   column;
  font-family:      var(--font-sans);
  color:            var(--n-800);
}

.auth-page__header {
  background:    var(--n-0);
  border-bottom: 1px solid var(--n-200);
  padding:       var(--sp-3) 0;
}

.auth-page__header-inner {
  display:         flex;
  align-items:     center;
  justify-content: space-between;
  gap:             var(--sp-4);
}

.auth-page__brand {
  display:         inline-flex;
  align-items:     center;
  text-decoration: none;
  color:           var(--brand-ink);
  min-height:      44px;
  padding:         var(--sp-1) 0;
}

.auth-page__brand-logo {
  height:    32px;
  width:     auto;
  display:   block;
}

.auth-page__back-link {
  display:         inline-flex;
  align-items:     center;
  gap:             var(--sp-2);
  font-size:       var(--fs-2);
  font-family:     var(--font-sans);
  color:           var(--n-600);
  text-decoration: none;
  min-height:      44px;
  padding:         var(--sp-1) var(--sp-2);
  border-radius:   var(--r-2);
  transition:      color var(--d-1) var(--ease-out-swift),
                   background-color var(--d-1) var(--ease-out-swift);
}

.auth-page__back-link:hover {
  color:      var(--brand-ink);
  background: var(--n-100);
}

.auth-page__back-link:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

.auth-page__main {
  flex:            1;
  display:         flex;
  align-items:     flex-start;
  justify-content: center;
  padding:         var(--sp-6) var(--sp-4);
}

.auth-page__footer {
  background:    var(--n-0);
  border-top:    1px solid var(--n-200);
  padding:       var(--sp-4) 0;
  text-align:    center;
  font-size:     var(--fs-1);
  color:         var(--n-500);
}

.auth-page__footer a {
  color:           var(--brand-ink);
  text-decoration: none;
  padding:         var(--sp-1) var(--sp-2);
  border-radius:   var(--r-1);
  display:         inline-block;
  min-height:      44px;
  line-height:     calc(44px - var(--sp-2));
}

.auth-page__footer a:hover {
  text-decoration: underline;
}

.auth-page__footer a:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

.auth-page__noscript {
  background:  var(--n-100);
  border-bottom: 1px solid var(--state-warn);
  color:       var(--n-800);
  text-align:  center;
  padding:     var(--sp-3) var(--sp-4);
  font-size:   var(--fs-2);
}

@media (prefers-reduced-motion: reduce) {
  .auth-page__back-link {
    transition: none;
  }
}

/* ──────────────────────────────────────────────────────────────────────────
   AUTH CARD (single-pane centered card — Login, BeginResetPassword,
   ResetPassword consume this; SignUp uses the wider .signup-form-card below)
   ────────────────────────────────────────────────────────────────────────── */

.auth-section {
  width:           100%;
  display:         flex;
  align-items:     flex-start;
  justify-content: center;
  padding:         var(--sp-5) var(--sp-4);
}

.auth-card-wrapper {
  width:     100%;
  max-width: 28rem;
}

.auth-card {
  background:    var(--n-0);
  border:        1px solid var(--n-200);
  border-radius: var(--r-3);
  box-shadow:    var(--shadow-2);
  overflow:      hidden;
}

.auth-card .card-body {
  padding: var(--sp-6);
}

.auth-heading {
  text-align:    center;
  margin-bottom: var(--sp-5);
}

.auth-heading h1 {
  font-family:    var(--font-serif);
  font-size:      var(--fs-5);
  font-weight:    600;
  color:          var(--brand-ink);
  letter-spacing: -0.01em;
  margin:         0 0 var(--sp-2) 0;
  line-height:    1.2;
}

.auth-heading p {
  font-family: var(--font-sans);
  font-size:   var(--fs-2);
  line-height: 1.55;
  color:       var(--n-600);
  margin:      var(--sp-2) 0 0 0;
}

.auth-heading .auth-icon,
.auth-icon {
  width:           56px;
  height:          56px;
  border-radius:   50%;
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  font-size:       var(--fs-5);
  margin-bottom:   var(--sp-4);
}

.auth-icon-green {
  background: var(--n-100);
  color:      var(--brand-ink);
}

.auth-link {
  color:           var(--brand-ink);
  font-weight:     600;
  text-decoration: none;
}

.auth-link:hover {
  text-decoration: underline;
}

.auth-forgot {
  font-size:       var(--fs-1);
  color:           var(--brand-ink);
  text-decoration: none;
  white-space:     nowrap;
  display:         inline-flex;
  align-items:     center;
  min-height:      44px;
  padding:         var(--sp-1) var(--sp-2);
  border-radius:   var(--r-1);
}

.auth-forgot:hover {
  text-decoration: underline;
}

.auth-forgot:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

.auth-footer-link {
  text-align:    center;
  margin-top:    var(--sp-5);
  font-size:     var(--fs-2);
  color:         var(--n-600);
}

.auth-footer-link a {
  color:           var(--brand-ink);
  font-weight:     600;
  text-decoration: none;
  display:         inline-flex;
  align-items:     center;
  gap:             var(--sp-1);
  min-height:      44px;
  padding:         var(--sp-1) var(--sp-2);
  border-radius:   var(--r-1);
}

.auth-footer-link a:hover {
  text-decoration: underline;
}

.auth-footer-link a:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

.auth-version {
  text-align: center;
  margin-top: var(--sp-4);
  font-size:  var(--fs-1);
  color:      var(--n-400);
  font-family: var(--font-mono);
  letter-spacing: 0.04em;
}

/* ── Auth alert (replaces inline-style isCheckoutRedirect block) ────────── */

.auth-alert {
  display:       flex;
  align-items:   flex-start;
  gap:           var(--sp-3);
  padding:       var(--sp-3) var(--sp-4);
  margin-bottom: var(--sp-5);
  border-radius: var(--r-2);
  border:        1px solid var(--n-200);
  background:    var(--n-50);
  color:         var(--n-800);
  font-size:     var(--fs-2);
  line-height:   1.45;
}

.auth-alert__icon {
  font-size:   var(--fs-4);
  color:       var(--state-warn);
  flex-shrink: 0;
  margin-top:  2px;
}

.auth-alert__title {
  font-weight:   600;
  color:         var(--brand-ink);
  margin-bottom: var(--sp-1);
}

.auth-alert__copy {
  color:     var(--n-700);
}

.auth-alert__copy a {
  color:           var(--brand-ink);
  font-weight:     600;
  text-decoration: underline;
}

.auth-alert__copy a:hover {
  text-decoration: none;
}

.auth-alert__copy a:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

.auth-alert--checkout {
  border-color: var(--state-warn);
  background:   var(--n-50);
}

/* ──────────────────────────────────────────────────────────────────────────
   SIGNUP — wider two-column layout (form + plan-summary sidebar)
   Consumed by Views/Public/SignUp.cshtml.
   ────────────────────────────────────────────────────────────────────────── */

.signup-main {
  padding: var(--sp-6) 0 var(--sp-8);
}

.signup-grid {
  display:               grid;
  grid-template-columns: 1fr 380px;
  gap:                   var(--sp-6);
  align-items:           start;
  max-width:             1100px;
  margin:                0 auto;
  padding:               0 var(--sp-4);
}

.signup-grid.no-sidebar {
  grid-template-columns: 1fr;
  max-width:             560px;
}

.signup-form-card {
  background:    var(--n-0);
  border:        1px solid var(--n-200);
  border-radius: var(--r-3);
  padding:       var(--sp-6);
  box-shadow:    var(--shadow-1);
}

.signup-form-card h2 {
  font-family:    var(--font-serif);
  font-size:      var(--fs-5);
  font-weight:    600;
  color:          var(--brand-ink);
  letter-spacing: -0.01em;
  margin:         0 0 var(--sp-1) 0;
  text-align:     center;
}

.signup-form-card .subtitle {
  font-family:   var(--font-sans);
  font-size:     var(--fs-2);
  line-height:   1.55;
  color:         var(--n-600);
  margin:        0 0 var(--sp-5) 0;
  text-align:    center;
}

.signup-form-row {
  display:               grid;
  grid-template-columns: 1fr 1fr;
  gap:                   var(--sp-4);
}

.divider-line {
  display:      flex;
  align-items:  center;
  gap:          var(--sp-4);
  margin:       var(--sp-5) 0;
  font-size:    var(--fs-1);
  color:        var(--n-400);
}

.divider-line::before,
.divider-line::after {
  content: '';
  flex:    1;
  height:  1px;
  background: var(--n-200);
}

.social-signup {
  display:       flex;
  gap:           var(--sp-3);
  margin-bottom: var(--sp-5);
}

.social-btn {
  flex:            1;
  display:         flex;
  align-items:     center;
  justify-content: center;
  gap:             var(--sp-2);
  padding:         var(--sp-3);
  min-height:      44px;
  border:          1px solid var(--n-200);
  border-radius:   var(--r-2);
  font-size:       var(--fs-2);
  font-weight:     600;
  color:           var(--n-700);
  background:      var(--n-0);
  cursor:          pointer;
  transition:      background-color var(--d-1) var(--ease-out-swift),
                   border-color     var(--d-1) var(--ease-out-swift);
}

.social-btn:hover {
  background:   var(--n-100);
  border-color: var(--n-300);
}

.social-btn:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

.btn-signup {
  display:       block;
  width:         100%;
  padding:       var(--sp-3) var(--sp-5);
  min-height:    48px;
  font-size:     var(--fs-3);
  font-weight:   600;
  font-family:   var(--font-sans);
  color:         var(--n-0);
  background:    var(--brand-ink);
  border:        2px solid var(--brand-ink);
  border-radius: var(--r-2);
  cursor:        pointer;
  transition:    background-color var(--d-1) var(--ease-out-swift),
                 box-shadow       var(--d-1) var(--ease-out-swift);
}

.btn-signup:hover {
  background: var(--n-900);
  box-shadow: var(--shadow-2);
}

.btn-signup:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

.login-link {
  text-align:  center;
  margin-top:  var(--sp-5);
  font-size:   var(--fs-2);
  color:       var(--n-600);
}

.login-link a {
  color:           var(--brand-ink);
  font-weight:     600;
  text-decoration: none;
  display:         inline-flex;
  align-items:     center;
  min-height:      44px;
  padding:         var(--sp-1) var(--sp-2);
  border-radius:   var(--r-1);
}

.login-link a:hover {
  text-decoration: underline;
}

.login-link a:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
}

/* ── Plan summary sidebar (signup only) ─────────────────────────────────── */

.plan-summary {
  background:    var(--n-0);
  border:        1px solid var(--n-200);
  border-radius: var(--r-3);
  overflow:      hidden;
  box-shadow:    var(--shadow-1);
  position:      sticky;
  top:           calc(var(--nav-h) + var(--sp-3));
}

.plan-summary-header {
  background:  var(--brand-ink);
  color:       var(--n-0);
  padding:     var(--sp-5);
  text-align:  center;
}

.plan-summary-header h3 {
  font-family:     var(--font-mono);
  font-size:       var(--fs-1);
  font-weight:     600;
  text-transform:  uppercase;
  letter-spacing:  0.08em;
  margin:          0 0 var(--sp-2) 0;
  color:           var(--n-0);
  opacity:         0.85;
}

.plan-summary-header .plan-title {
  font-family: var(--font-serif);
  font-size:   var(--fs-5);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.plan-summary-header .plan-price-display {
  font-family: var(--font-serif);
  font-size:   var(--fs-6);
  font-weight: 600;
  margin-top:  var(--sp-2);
}

.plan-summary-header .plan-price-display span {
  font-family: var(--font-sans);
  font-size:   var(--fs-3);
  font-weight: 500;
  opacity:     0.8;
}

.plan-summary-body {
  padding: var(--sp-5);
}

.plan-summary-body h4 {
  font-family:    var(--font-mono);
  font-size:      var(--fs-1);
  font-weight:    600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color:          var(--brand-ink);
  margin:         0 0 var(--sp-3) 0;
}

.plan-feature-row {
  display:     flex;
  align-items: center;
  gap:         var(--sp-3);
  padding:     var(--sp-2) 0;
  font-size:   var(--fs-2);
  color:       var(--n-700);
  border-bottom: 1px solid var(--n-100);
}

.plan-feature-row:last-child {
  border-bottom: none;
}

.plan-feature-row .check {
  color:       var(--state-success);
  font-weight: 700;
  font-size:   var(--fs-3);
  flex-shrink: 0;
}

.plan-feature-row .x-mark {
  color:       var(--n-300);
  font-weight: 700;
  font-size:   var(--fs-3);
  flex-shrink: 0;
}

.plan-summary-footer {
  padding:     var(--sp-3) var(--sp-5);
  background:  var(--n-50);
  border-top:  1px solid var(--n-200);
  text-align:  center;
}

.plan-summary-footer a {
  font-size:       var(--fs-2);
  color:           var(--brand-ink);
  font-weight:     600;
  text-decoration: none;
  display:         inline-flex;
  align-items:     center;
  gap:             var(--sp-1);
  min-height:      44px;
  padding:         var(--sp-1) var(--sp-2);
  border-radius:   var(--r-1);
}

.plan-summary-footer a:hover {
  text-decoration: underline;
}

.plan-badge {
  display:        inline-block;
  background:     var(--brand-spark);
  /* F-4b-1: --brand-on-spark indirection — HC mode flips to --n-0 on the
     darkened spark fill (7.12:1 AAA). */
  color:          var(--brand-on-spark);
  padding:        var(--sp-1) var(--sp-3);
  border-radius:  999px;
  font-size:      var(--fs-1);
  font-weight:    700;
  margin-top:     var(--sp-2);
  font-family:    var(--font-mono);
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

/* ── Account-type tabs ───────────────────────────────────────────────────── */

.account-type-tabs {
  display:        flex;
  gap:            0;
  margin-bottom:  var(--sp-5);
  border:         1px solid var(--n-200);
  border-radius:  var(--r-2);
  overflow:       hidden;
}

.account-type-tab {
  flex:           1;
  padding:        var(--sp-3);
  min-height:     44px;
  text-align:     center;
  font-size:      var(--fs-2);
  font-weight:    600;
  color:          var(--n-600);
  background:     var(--n-0);
  border:         none;
  cursor:         pointer;
  transition:     background-color var(--d-1) var(--ease-out-swift),
                  color            var(--d-1) var(--ease-out-swift);
  font-family:    var(--font-sans);
}

.account-type-tab + .account-type-tab {
  border-left: 1px solid var(--n-200);
}

.account-type-tab:hover {
  background: var(--n-100);
}

.account-type-tab:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: -3px;
}

.account-type-tab.active {
  background: var(--brand-ink);
  color:      var(--n-0);
}

@media (prefers-reduced-motion: reduce) {
  .social-btn,
  .btn-signup,
  .account-type-tab,
  .signup-wizard__stage,
  .role-card {
    transition: none;
  }
}

@media (max-width: 768px) {
  .signup-grid {
    grid-template-columns: 1fr;
  }
  .plan-summary {
    position: static;
    order:    -1;
  }
  .signup-form-row {
    grid-template-columns: 1fr;
  }
  .social-signup {
    flex-direction: column;
  }
}

/* ── Role cards (signup wizard) ────────────────────────────────────────────
   M49 Phase 1 · D7. Stage 1 role-picker primitive for the two-stage signup
   wizard. Tokens-only: no raw hex (HR2), no raw ms (HR3). Touch target
   floor: min-height 88px (HR8 ≥44, doubled for card affordance).
   prefers-reduced-motion fallback shares the block above (.role-card +
   .signup-wizard__stage selectors added inline).
*/

.signup-wizard {
  display:        block;
}

.signup-wizard__stage {
  display:        block;
  /* Stage transitions are handled via the [hidden] attribute toggle in JS;
     no opacity/transform animation today (instant swap). The transition
     property is declared so prefers-reduced-motion's `transition: none`
     fallback above has a target to override should we add a fade later. */
  transition:     opacity var(--d-2) var(--ease-out-swift);
}

.signup-wizard__banner {
  display:        flex;
  align-items:    center;
  gap:            var(--sp-3);
  padding:        var(--sp-3) var(--sp-4);
  margin-bottom:  var(--sp-5);
  background:     var(--n-50);
  border:         1px solid var(--n-200);
  border-radius:  var(--r-2);
}

.signup-wizard__banner > i {
  font-size:      var(--fs-4);
  color:          var(--brand-ink);
  flex-shrink:    0;
}

.signup-wizard__banner > div {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-1);
  min-width:      0;
}

.signup-wizard__banner strong {
  font-size:      var(--fs-3);
  font-weight:    600;
  color:          var(--brand-ink);
}

.signup-wizard__banner span {
  font-size:      var(--fs-2);
  color:          var(--n-700);
}

.signup-wizard__back {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  width:           44px;
  height:          44px;
  padding:         0;
  margin-right:    var(--sp-1);
  background:      transparent;
  border:          1px solid var(--n-200);
  border-radius:   var(--r-1);
  color:           var(--brand-ink);
  cursor:          pointer;
  flex-shrink:     0;
  transition:      background-color var(--d-1) var(--ease-out-swift),
                   border-color     var(--d-1) var(--ease-out-swift);
}

.signup-wizard__back:hover {
  background:      var(--n-100);
  border-color:    var(--n-300);
}

.signup-wizard__back:focus-visible {
  outline:         3px solid var(--state-info);
  outline-offset:  2px;
}

.signup-wizard__back i {
  font-size:       var(--fs-3);
}

.role-card-grid {
  display:                grid;
  grid-template-columns:  repeat(auto-fit, minmax(260px, 1fr));
  gap:                    var(--sp-3);
  margin-bottom:          var(--sp-5);
}

/* D4 — single-card centering: when only one role is feature-flag-enabled,
   the grid collapses to a single column with a max-width cap so the lone
   card doesn't stretch full-width. Auto-reshapes when flags flip. */
.role-card-grid--single {
  max-width:      360px;
  margin-inline:  auto;
}

.role-card {
  display:         flex;
  flex-direction:  column;
  align-items:     flex-start;
  gap:             var(--sp-2);
  padding:         var(--sp-4);
  min-height:      88px;
  background:      var(--n-0);
  border:          1px solid var(--n-200);
  border-radius:   var(--r-3);
  color:           var(--n-900);
  font-family:     var(--font-sans);
  text-align:      left;
  cursor:          pointer;
  transition:      background-color var(--d-2) var(--ease-out-swift),
                   border-color     var(--d-2) var(--ease-out-swift),
                   box-shadow       var(--d-2) var(--ease-out-swift),
                   transform        var(--d-2) var(--ease-out-swift);
}

.role-card > i {
  font-size:       var(--fs-5);
  color:           var(--brand-ink);
}

.role-card__title {
  font-size:       var(--fs-2);
  font-weight:     600;
  color:           var(--brand-ink);
}

.role-card__subtitle {
  font-size:       var(--fs-1);
  color:           var(--n-700);
  line-height:     1.4;
}

.role-card:hover {
  background:      var(--n-50);
  border-color:    var(--n-300);
  box-shadow:      var(--shadow-1);
  transform:       translateY(-1px);
}

.role-card:focus-visible {
  outline:         3px solid var(--brand-spark);
  outline-offset:  2px;
}

.role-card[aria-pressed="true"],
.role-card--active {
  background:      var(--n-50);
  border-color:    var(--brand-ink);
  border-width:    2px;
  /* Compensate for the +1px border so cards in a grid don't shift */
  padding:         calc(var(--sp-4) - 1px);
}

/* ==========================================================================
   M09 PHASE 3b — Manage-Event / Manage-Tour / Payout / Reviews drawer
   migrations + Vendor Profile Create/Edit page-title sweep + Alert primitive.
   Token-only replacements for inline <style> blocks and inline style="..."
   on the modal-to-drawer migration surfaces. Hard rules 1-10 in force.
   ========================================================================== */

/* ── Vendor Profile · page title (deleted Phase 9 / M52 — F-8-01) ─────── */
/*
   `.vendor-profile-page-title` rule deleted after Phase 8 of M52
   (2026-05-17-service-surface-parity) migrated both Create.cshtml and
   Edit.cshtml to Kit/_PageHeader. Zero remaining consumers confirmed via
   grep in cumulative-context.md Phase 8 close-out. The `vendor-profile-page-title`
   string still appears in Create.cshtml + Edit.cshtml header comments as
   historical documentation of the inline-style migration; the comment refs
   are documentary and do not bind any element.
*/

/* ── Manage Event · sections (F-3b-03 sweep on _ManageEvent.cshtml) ──── */
/*
   Replaces the entire <style asp-add-nonce> block previously embedded at
   the top of _ManageEvent.cshtml (lines 12-110) plus the inline style=""
   attributes scattered through the view (Description label/copy, review
   meta, review reply, review-stars colour, commission card, etc).
*/
.manage-header {
  display:        flex;
  align-items:    flex-start;
  justify-content: space-between;
  margin-bottom:  var(--sp-5);
  flex-wrap:      wrap;
  gap:            var(--sp-3);
}
.manage-header h1 {
  font-family:   var(--font-serif);
  font-size:     var(--fs-4);
  font-weight:   600;
  color:         var(--brand-ink);
  margin:        0;
  letter-spacing: -0.01em;
}
.manage-actions {
  display:       flex;
  gap:           var(--sp-2);
  flex-wrap:     wrap;
}
.manage-back-link {
  display:        flex;
  align-items:    center;
  margin-bottom:  var(--sp-3);
}
.manage-back-link__caption {
  color:         var(--n-500);
  font-size:     var(--fs-1);
}
.manage-detail-grid {
  display:       grid;
  grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
  gap:           var(--sp-4);
}
.manage-detail-item label {
  font-size:     var(--fs-0);
  font-weight:   600;
  color:         var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  margin-bottom: var(--sp-1);
  display:       block;
}
.manage-detail-item span {
  font-size:     var(--fs-1);
  color:         var(--n-700);
}
.manage-section-title {
  font-family:   var(--font-serif);
  font-size:     var(--fs-3);
  font-weight:   600;
  color:         var(--brand-ink);
  margin-bottom: var(--sp-3);
  padding-bottom: var(--sp-2);
  border-bottom: 2px solid var(--n-200);
}
.manage-section-title--no-rule {
  border-bottom: none;
  padding-bottom: 0;
  margin-bottom: 0;
}
.manage-section-header {
  display:       flex;
  align-items:   center;
  justify-content: space-between;
  margin-bottom: var(--sp-3);
  padding-bottom: var(--sp-2);
  border-bottom: 2px solid var(--n-200);
}
.manage-section-header h2 {
  font-family:   var(--font-serif);
  font-size:     var(--fs-3);
  font-weight:   600;
  color:         var(--brand-ink);
  margin:        0;
}
.manage-event-details-head {
  display:       flex;
  align-items:   center;
  justify-content: space-between;
  margin-bottom: var(--sp-3);
  padding-bottom: var(--sp-2);
  border-bottom: 2px solid var(--n-200);
}
.manage-event-details-actions {
  display:       flex;
  gap:           var(--sp-2);
}
.manage-event-description-label {
  font-size:     var(--fs-0);
  font-weight:   600;
  color:         var(--n-500);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}
.manage-event-description-copy {
  margin-top:    var(--sp-1);
  font-size:     var(--fs-1);
  color:         var(--n-700);
  line-height:   1.6;
}
/* Phase 6c — paragraph spacing for sanitized RTE HTML inside the description block. */
.manage-event-description-copy p + p {
  margin-top:    var(--sp-3);
}
.manage-child-empty {
  text-align:    center;
  padding:       var(--sp-4);
  color:         var(--n-400);
  font-size:     var(--fs-1);
}
.manage-child-empty__icon {
  display:       block;
  margin-bottom: var(--sp-2);
  font-size:     var(--fs-4);
}
.manage-child-table {
  width:         100%;
}
.manage-child-table th {
  font-size:     var(--fs-0);
  font-weight:   600;
  color:         var(--n-500);
  text-transform: uppercase;
  padding:       var(--sp-2) var(--sp-3);
  border-bottom: 2px solid var(--n-200);
  text-align:    left;
  background-color: var(--n-50);
}
.manage-child-table td {
  padding:       var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--n-100);
  font-size:     var(--fs-1);
  color:         var(--n-700);
}
.manage-child-table th--actions,
.manage-child-table td--actions {
  width:         100px;
}
.manage-btn-action {
  padding:       var(--sp-1) var(--sp-2);
  font-size:     var(--fs-0);
  border:        none;
  background:    none;
  cursor:        pointer;
  border-radius: var(--r-1);
  min-height:    44px;
  min-width:     44px;
  display:       inline-flex;
  align-items:   center;
  justify-content: center;
}
.manage-btn-action:hover {
  background-color: var(--n-100);
}
.manage-btn-action--edit { color: var(--state-info); }
.manage-btn-action--delete { color: var(--state-danger); }

/* ── Manage Event · commission card ─────────────────────────────────── */
.manage-commission-card {
  border-left:   3px solid var(--state-info);
}
.manage-commission-input-cell {
  min-width:     150px;
  width:         150px;
}
.manage-commission-save-btn {
  height:        44px;
  white-space:   nowrap;
}

/* ── Manage · per-channel commission editor (Mandate 2026-05-19 Phase 6) ─ */
.manage-commission-channel-grid {
  display:        none;
  margin-top:     var(--sp-3);
  padding:        var(--sp-3);
  border:         1px solid var(--n-100);
  border-radius:  var(--radius-sm, 6px);
  background:     var(--n-50);
}
.manage-commission-channel-grid.is-open {
  display:        block;
}
.manage-commission-channel-section-label {
  display:        block;
  margin-bottom:  var(--sp-2);
  font-size:      var(--fs-0);
  font-weight:    600;
  color:          var(--n-500);
}

/* ── Form-level per-channel commission editor (Shared/_CommissionOverride) ── */
.commission-override-section-label {
  display:        block;
  margin-bottom:  var(--sp-2);
  font-size:      var(--fs-0);
  font-weight:    600;
  color:          var(--n-500);
}
.commission-override-toggle-label {
  font-size:      var(--fs-0);
}
.commission-override-grid {
  margin-top:     var(--sp-2);
}
.commission-override-grid.is-hidden {
  display:        none;
}
.commission-override-hint {
  margin-bottom:  var(--sp-2);
  font-size:      var(--fs-0);
  color:          var(--n-500);
}

/* ── Manage Event · reviews ─────────────────────────────────────────── */
.manage-review-card {
  padding-bottom: var(--sp-3);
  margin-bottom:  var(--sp-3);
  border-bottom:  1px solid var(--n-100);
}
.manage-review-stars {
  display:        inline-flex;
  align-items:    center;
  gap:            var(--sp-1);
  color:          var(--state-warn);
  font-size:      var(--fs-2);
}
.manage-review-date {
  color:          var(--n-500);
  font-size:      var(--fs-0);
}
.manage-review-pending {
  font-size:      var(--fs-0);
}
.manage-review-text {
  margin:         var(--sp-1) 0;
  font-size:      var(--fs-1);
  color:          var(--n-700);
}
.manage-review-reply {
  margin-left:    var(--sp-4);
  margin-top:     var(--sp-2);
  padding:        var(--sp-2);
  background:     var(--n-50);
  border-radius:  var(--r-2);
  border-left:    3px solid var(--brand-ink);
}
.manage-review-reply__copy {
  margin-bottom:  0;
  font-size:      var(--fs-1);
  color:          var(--n-700);
}

/* ── Drawer body · creator/vendor write forms (shared layout) ────────── */
/*
   Form row utilities for the new _*DrawerBody.cshtml partials introduced
   by Phase 3b. Mirrors the vendor-profile-drawer-form__row pattern from
   Phase 2 W7.4 but lives under a generic name so creator + vendor + payout
   drawer bodies can all share it.
*/
.creator-drawer-form {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-3);
}
.creator-drawer-form__row {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-1);
}
.creator-drawer-form__row--split {
  display:        grid;
  grid-template-columns: 1fr 1fr;
  gap:            var(--sp-3);
}
.creator-drawer-form__actions {
  display:        flex;
  justify-content: flex-end;
  gap:            var(--sp-2);
  margin-top:     var(--sp-3);
}

/* ── Alert / Confirm primitive (F-3b-01 CODE RED) ─────────────────────── */
/*
   Replaces the banned greens (#2e7d32) on Views/Shared/Alert.cshtml's
   #cs_confirmModal header + icon + the inline-style declarations on the
   header / body / footer / OK / Cancel buttons. Token-only.
*/
.alert-modal-message {
  text-align:    center;
}
.alert-modal-close {
  width:         100%;
}
.confirm-modal-header {
  font-weight:   600;
  border-bottom: 2px solid var(--brand-ink);
}
.confirm-modal-icon {
  color:         var(--brand-ink);
}
.confirm-modal-btn {
  min-width:     100px;
  min-height:    44px;
}


/* ==========================================================================
   M10 PHASE 1 (W6.1) — Bottom Tabs (mobile-only public nav)
   --------------------------------------------------------------------------
   Five-slot fixed bottom nav: Home · Search · Voting · Tickets · Me.
   Visible only at <768px; hidden at >=768px via CSS media query — no JS
   branch (mandate-wide anti-instruction).

   Search-overlay primitive (.mobile-search-overlay) styles immediately
   below this section; element IDs are bound by `wwwroot/js/public.js`
   and are preserved in `_PublicMobileSearchOverlay.cshtml`.

   Hard rules: #1 (no green), #2 (no raw hex), #3 (no raw ms), #4 (no inline
   style on Kit partials — N/A here, CSS file), #5 (no <style> in views —
   honored: this file, not a view), #8 (>=44x44 hit area), #10 (reduced-motion
   fallback present at section foot).
   ========================================================================== */

/* Default: hidden at desktop. The block flips to flex at <768px. */
.bottom-tabs {
  display: none;
}

/* Search overlay: hidden by default; activated by `.is-active` (mobile-only). */
.mobile-search-overlay {
  display: none;
}

@media (max-width: 767.98px) {
  /* ── Bottom tab strip ───────────────────────────────────────────────── */
  .bottom-tabs {
    display:           flex;
    position:          fixed;
    bottom:            0;
    left:              0;
    right:             0;
    z-index:           1000;
    align-items:       stretch;
    justify-content:   space-around;
    background:        var(--n-0);
    border-top:        1px solid var(--n-200);
    padding-bottom:    env(safe-area-inset-bottom, 0px);
    box-shadow:        0 -1px 0 color-mix(in srgb, var(--brand-ink) 6%, transparent);
  }

  .bottom-tabs__item {
    /* position:relative — establishes the positioning context for the
       .is-active::after underline indicator (F-1-5 cleanup, M10 Phase 2). */
    position:          relative;
    flex:              1 1 0;
    display:           inline-flex;
    flex-direction:    column;
    align-items:       center;
    justify-content:   center;
    gap:               2px;
    min-width:         44px;
    min-height:        56px;          /* nav bar visible content; total >=44 hit */
    padding:           6px 4px;
    background:        transparent;
    border:            0;
    color:             var(--n-500);
    font-family:       var(--font-sans);
    font-size:         var(--fs-1);
    font-weight:       600;
    text-decoration:   none;
    cursor:            pointer;
    transition:
      color            var(--d-1) var(--ease-out-swift),
      background-color var(--d-1) var(--ease-out-swift);
    -webkit-tap-highlight-color: transparent;
  }

  .bottom-tabs__item:hover,
  .bottom-tabs__item:focus-visible {
    color:             var(--brand-ink);
  }

  .bottom-tabs__item:focus-visible {
    outline:           2px solid var(--brand-ink);
    outline-offset:    -2px;
  }

  .bottom-tabs__item.is-active,
  .bottom-tabs__item[aria-current="page"] {
    color:             var(--brand-ink);
  }

  .bottom-tabs__item.is-active::after,
  .bottom-tabs__item[aria-current="page"]::after {
    content:           "";
    position:          absolute;
    bottom:            0;
    height:            2px;
    width:             24px;
    background:        var(--brand-ink);
    border-radius:     1px;
  }

  .bottom-tabs__icon {
    font-size:         22px;          /* mdi glyph size; the wrapper is 44+ */
    line-height:       1;
  }

  .bottom-tabs__label {
    font-size:         var(--fs-1);
    line-height:       1.1;
    white-space:       nowrap;
  }

  /* Body padding to keep page content above the bar. */
  body.has-bottom-tabs {
    padding-bottom:    calc(56px + env(safe-area-inset-bottom, 0px));
  }

  /* ── Header hamburger override (Phase 1 success criterion) ─────────────
     The legacy `_PublicMobileNav.cshtml` offcanvas is deleted in this
     phase. Any surviving `.hamburger` element from `_PublicHeader.cshtml`
     stays hidden at <768px (the bottom tabs replace it). Legacy
     `custom.css` flips it to flex at <768px; this rule wins by being
     loaded after `custom.css` in `HeadMeta.cshtml`. */
  .hamburger {
    display:           none !important;
  }

  /* ── Mobile search overlay (extracted to _PublicMobileSearchOverlay.cshtml) ── */
  .mobile-search-overlay {
    display:           flex;
    position:          fixed;
    inset:             0;
    z-index:           1100;          /* above bottom-tabs */
    flex-direction:    column;
    background:        var(--n-0);
    transform:         translateY(100%);
    transition:        transform var(--d-2) var(--ease-out-swift);
    padding-top:       env(safe-area-inset-top, 0px);
    padding-bottom:    env(safe-area-inset-bottom, 0px);
  }

  .mobile-search-overlay.active {
    transform:         translateY(0);
  }

  .mobile-search-header {
    display:           flex;
    align-items:       center;
    gap:               8px;
    padding:           12px 16px;
    border-bottom:     1px solid var(--n-200);
  }

  .mobile-search-header input {
    flex:              1;
    min-height:        44px;
    padding:           10px 14px;
    border:            1px solid var(--n-200);
    border-radius:     8px;
    background:        var(--n-50);
    font-family:       var(--font-sans);
    font-size:         var(--fs-3);
    color:             var(--n-900);
    transition:        border-color var(--d-1) var(--ease-out-swift),
                       background   var(--d-1) var(--ease-out-swift);
  }

  .mobile-search-header input:focus-visible {
    border-color:      var(--brand-ink);
    background:        var(--n-0);
  }

  .mobile-search-close {
    width:             44px;
    height:            44px;
    display:           inline-flex;
    align-items:       center;
    justify-content:   center;
    background:        transparent;
    border:            0;
    border-radius:     8px;
    color:             var(--n-700);
    cursor:            pointer;
    transition:        background var(--d-1) var(--ease-out-swift);
  }

  .mobile-search-close:hover,
  .mobile-search-close:focus-visible {
    background:        var(--n-100);
  }

  .mobile-search-close:focus-visible {
    outline:           2px solid var(--brand-ink);
    outline-offset:    -2px;
  }

  .mobile-search-close .mdi {
    font-size:         22px;
    line-height:       1;
  }

  .mobile-search-results {
    flex:              1;
    overflow-y:        auto;
    padding:           8px 0;
  }
}

/* Reduced-motion fallback (CLAUDE.md hard rule #10) — disable the slide-in
   transform animation on the search overlay. The overlay still functions;
   only the motion is removed. */
@media (prefers-reduced-motion: reduce) {
  .mobile-search-overlay {
    transition:        none;
  }
  .bottom-tabs__item {
    transition:        none;
  }
}

/* ── Tap-feedback compression (M10 Phase 4 · W6.v2.1) ────────────────────────
   Opt-in: any element bearing `data-tap-feedback` springs 2px down on
   pointerdown via a JS-applied `is-pressing` class. The transition itself
   uses --d-2 + --ease-spring tokens (Phase 4 success criterion #3).

   Driver: wwwroot/js/kit/tap-feedback.js (solhigson.kit.tapFeedback). The
   delegator listener is global; opt-in is per element via the data attribute.
   Hard rule #3 — no raw ms. Hard rule #10 — reduced-motion suppresses the
   transform; the delegator still fires for state-tracking but the visual is
   `transform: none`. */
[data-tap-feedback] {
  transition:        transform var(--d-2) var(--ease-spring);
  /* Hint to the GPU compositor that transform is the animated property. */
  will-change:       transform;
}

[data-tap-feedback].is-pressing {
  transform:         translateY(2px);
}

/* ── Bottom-tab underline-slide indicator (M10 Phase 4 · W6.v2.1) ────────────
   The Razor partial renders the active state via server-side path match and
   exposes a `::after` pseudo-element on the active tab as the no-JS fallback.
   When wwwroot/js/kit/tap-feedback.js initialises, it appends a single
   `<span class="bottom-tabs__indicator">` to the nav and adds the
   `has-indicator-overlay` class — the pseudo is then suppressed and the
   overlay element animates between active-tab geometries via FLIP-equivalent
   (the JS writes new `transform: translate3d` + `width`; CSS interpolates).

   M10 F-4-3 / M11 P2 — the indicator bar width is now a CSS custom property
   (--bottom-tab-indicator-width) so tap-feedback.js reads it via
   getComputedStyle rather than duplicating the value in JS. Single source of
   truth: change the value here, JS adapts automatically.

   Hard rule #3 — motion via --d-2 + --ease-spring. Hard rule #10 — reduced-
   motion users see an instant snap (transition: none) via the no-motion
   modifier set by JS at init. */
@media (max-width: 767.98px) {
  /* Indicator width custom property — readable by JS via getComputedStyle. */
  [data-kit-component="bottom-tabs"] {
    --bottom-tab-indicator-width: 24px;
  }

  .bottom-tabs.has-indicator-overlay .bottom-tabs__item.is-active::after,
  .bottom-tabs.has-indicator-overlay .bottom-tabs__item[aria-current="page"]::after {
    /* JS overlay supersedes the server-rendered pseudo. */
    display:           none;
  }

  /* W14.7 audit (M13 Phase 3, 2026-04-28): bottom-tabs FLIP indicator
     reviewed against W14.7 acceptance criteria — PASS.
       - Motion tokens cited (no raw ms): --d-2 + --ease-spring on transform
         and width; --d-1 + --ease-out-swift on opacity. Pairing matches
         M13 Phase 1 motion-spec guidance for tactile micro-interactions.
       - FLIP via transform: translate3d(...) — non-layout-affecting; JS
         driver writes geometry once per active-state change inside rAF
         (see wwwroot/js/kit/tap-feedback.js positionIndicator + setupIndicator).
       - Reduced-motion bypass: bottom-tabs__indicator--no-motion (set by JS
         when matchMedia matches) sets transition: none below; the @media
         (prefers-reduced-motion: reduce) block is defence-in-depth.
     Catalog entry: docs/motion.md → bottom-tabs-indicator-flip. */
  .bottom-tabs__indicator {
    position:          absolute;
    bottom:            env(safe-area-inset-bottom, 0px);
    left:              0;
    height:            2px;
    width:             24px;
    background:        var(--brand-ink);
    border-radius:     1px;
    pointer-events:    none;
    opacity:           0;
    transform:         translate3d(0, 0, 0);
    transition:
      transform        var(--d-2) var(--ease-spring),
      width            var(--d-2) var(--ease-spring),
      opacity          var(--d-1) var(--ease-out-swift);
  }

  /* No-motion modifier set by JS when prefers-reduced-motion: reduce.
     Snap instantly to the new position; no spring interpolation. */
  .bottom-tabs__indicator.bottom-tabs__indicator--no-motion {
    transition:        none;
  }
}

@media (prefers-reduced-motion: reduce) {
  /* Tap-compression collapses to no transform under reduced-motion. The
     `is-pressing` class still toggles for consumers that hook into it; only
     the visual translateY is suppressed. */
  [data-tap-feedback],
  [data-tap-feedback].is-pressing {
    transform:         none;
    transition:        none;
  }

  /* Indicator overlay snap (covers cases where JS didn't apply the
     no-motion modifier — e.g. preference toggled mid-session). */
  .bottom-tabs__indicator {
    transition:        none;
  }
}

/* ── Pull-to-refresh (M10 Phase 5 · W6.v2.3) ────────────────────────────────
   Driver: wwwroot/js/kit/pull-to-refresh.js (solhigson.kit.pullToRefresh).
   Opt-in via [data-pull-to-refresh][data-refresh-url] on the host container.

   Architecture:
     The host container is the visible page region. The JS appends one CSS
     variable on the container during drag — `--ptr-pull` (px offset) and
     `--ptr-progress` (0..1). CSS owns all visuals: a wordmark indicator
     fixed-positioned above the container's top edge, fill driven by
     clip-path inset() keyed on `--ptr-progress`.

   F-0-6 (P0 design review carry-forward): overscroll-behavior-y: contain
     prevents browser pull-to-refresh chrome from chaining through.

   Hard rules:
     #2  No raw hex — colours via tokens (--brand-ink, --brand-spark, --n-*).
     #3  No raw ms — transitions via --d-2/--d-3 + --ease-spring/--ease-in-out-subtle.
     #8  Visible Refresh button is rendered in the host page (not here);
         this section sizes only the indicator overlay.
    #10  prefers-reduced-motion: reduce — shimmer becomes a static linear
         progress bar; spring-back collapses to instant snap.
   ─────────────────────────────────────────────────────────────────────────── */

[data-pull-to-refresh] {
  /* Block native browser pull-to-refresh + scroll-chaining (F-0-6). */
  overscroll-behavior-y: contain;
  /* Platform owns horizontal/diagonal axis; we only see vertical drag. */
  touch-action:          pan-y;
  /* The indicator anchors above the container's top edge — establish a
     positioning context so the absolutely-positioned indicator does not
     escape into a far ancestor. */
  position:              relative;
}

/* Indicator overlay — rendered as a top-anchored bar that grows with
   `--ptr-pull`. The wordmark fill is a clip-path inset that retreats as
   `--ptr-progress` approaches 1 (0 → 100% fill). */
[data-pull-to-refresh]::before {
  content:           "";
  position:          absolute;
  top:               0;
  left:              50%;
  transform:         translate(-50%, calc(-100% + var(--ptr-pull, 0px)));
  width:             clamp(120px, 40vw, 180px);
  height:            32px;
  pointer-events:    none;
  background-color:  color-mix(in srgb, var(--brand-ink) 4%, transparent);
  border:            1px solid color-mix(in srgb, var(--brand-ink) 8%, transparent);
  border-radius:     999px;
  /* Fill the indicator from left → right with --brand-spark at progress 1.
     We use a linear-gradient hard-stop driven by --ptr-progress and let
     CSS interpolate the percentage. The leading bar stays --brand-ink
     compatible by tinting through brand-spark at low opacity. */
  background-image:  linear-gradient(
                       90deg,
                       var(--brand-spark) 0%,
                       var(--brand-spark) calc(var(--ptr-progress, 0) * 100%),
                       transparent calc(var(--ptr-progress, 0) * 100%),
                       transparent 100%
                     );
  background-size:   100% 100%;
  background-repeat: no-repeat;
  opacity:           clamp(0, var(--ptr-progress, 0), 1);
  transition:        opacity var(--d-2) var(--ease-out-swift);
  /* `Elfrique` wordmark glyph rendered via mask-image so it composites with
     the gradient fill. Falls back to the bare gradient when mask-image is
     unsupported — still legible. */
  display:           flex;
  align-items:       center;
  justify-content:   center;
  font-family:       var(--font-serif);
  font-size:         var(--fs-2);
  font-weight:       600;
  color:             var(--brand-ink);
  z-index:           5;
  will-change:       transform;
}

/* Indicator label — placed via ::after sibling so it sits over the gradient
   without inheriting its background-clip behavior. The label fades in at
   --ptr-progress > 0.1 and shows "Pull to refresh" at <1, "Release to
   refresh" at >=1 (CSS content via attr-driven class). */
[data-pull-to-refresh]::after {
  content:           "Pull to refresh";
  position:          absolute;
  top:               0;
  left:              50%;
  transform:         translate(-50%, calc(-100% + var(--ptr-pull, 0px) + 8px));
  pointer-events:    none;
  font-family:       var(--font-mono);
  font-size:         var(--fs-1);
  font-weight:       500;
  color:             var(--brand-ink);
  letter-spacing:    0.04em;
  text-transform:    uppercase;
  opacity:           clamp(0, calc(var(--ptr-progress, 0) * 2 - 0.3), 1);
  transition:        opacity var(--d-2) var(--ease-out-swift);
  z-index:           6;
  white-space:       nowrap;
}

[data-pull-to-refresh].is-pull-armed::after {
  content:           "Release to refresh";
  color:             var(--brand-spark);
}

/* During an active drag — suppress transitions so the visual follows the
   finger 1:1 inside requestAnimationFrame. */
[data-pull-to-refresh].is-pulling::before,
[data-pull-to-refresh].is-pulling::after {
  transition:        none;
}

/* Spring-back (sub-threshold release) — re-enable the transition with the
   spring curve so --ptr-pull animates back to 0. Both pseudo-elements
   smoothly retract. */
[data-pull-to-refresh].is-springing-back::before,
[data-pull-to-refresh].is-springing-back::after {
  transition:        transform var(--d-2) var(--ease-spring),
                     opacity   var(--d-2) var(--ease-out-swift);
}

/* Refreshing state — the indicator stays armed and a shimmer plays across
   the gradient fill. Implemented as a background-position oscillation on a
   secondary linear-gradient. The indicator itself is still pinned at
   --ptr-pull = THRESHOLD; the shimmer is purely decorative. */
@keyframes ptr-shimmer {
  0%   { background-position: -100% 0; }
  100% { background-position:  200% 0; }
}

[data-pull-to-refresh].is-refreshing::before {
  /* Layered gradients: base fill (full --brand-spark) + a wide shimmer band
     that sweeps across. */
  background-image:  linear-gradient(
                       90deg,
                       transparent 0%,
                       color-mix(in srgb, var(--n-0) 60%, transparent) 50%,
                       transparent 100%
                     ),
                     linear-gradient(
                       90deg,
                       var(--brand-spark) 0%,
                       var(--brand-spark) 100%
                     );
  background-size:   50% 100%, 100% 100%;
  background-repeat: no-repeat, no-repeat;
  background-position: -100% 0, 0 0;
  animation:         ptr-shimmer var(--d-3) var(--ease-in-out-subtle) infinite;
}

[data-pull-to-refresh].is-refreshing::after {
  content:           "Refreshing…";
  color:             var(--brand-ink);
}

/* Success / error fade — both fade the indicator out via opacity to 0 over
   --d-2. The state classes are removed from JS after the fade duration. */
[data-pull-to-refresh].is-refresh-success::before,
[data-pull-to-refresh].is-refresh-success::after,
[data-pull-to-refresh].is-refresh-error::before,
[data-pull-to-refresh].is-refresh-error::after {
  opacity:           0;
  transition:        opacity var(--d-2) var(--ease-out-swift);
  animation:         none;
}

/* ── Sticky public navbar safe-area (W6.v2.4) ──────────────────────────────
   The legacy `.main-header { position: sticky; top: 0; }` lives in
   wwwroot/custom/custom.css. With `viewport-fit=cover` the notch can occlude
   the top edge of the sticky header on iOS. Adding `padding-top:
   env(safe-area-inset-top)` keeps the header content below the notch.
   Loaded after custom.css per HeadMeta.cshtml include order — wins by
   specificity + cascade. */
.main-header {
  padding-top:       env(safe-area-inset-top, 0px);
  /* M20 F13: lift above .nav-public (z=20 via --z-sticky) so the .user-menu
     dropdown nested under .header-avatar-wrap stacks correctly. */
  position:          relative;
  z-index:           25;
}

/* ── Pull-to-refresh · prefers-reduced-motion ──
   Hard rule #10. The shimmer keyframe halts; the indicator becomes a static
   linear progress bar (the same gradient, but pinned at progress=1 with no
   sweep). Spring-back collapses to an instant snap. */
@media (prefers-reduced-motion: reduce) {
  [data-pull-to-refresh].is-refreshing::before {
    animation:       none;
    /* Static linear progress: full --brand-spark fill, no sweep band. */
    background-image: linear-gradient(
                        90deg,
                        var(--brand-spark) 0%,
                        var(--brand-spark) 100%
                      );
    background-size:   100% 100%;
    background-position: 0 0;
  }

  [data-pull-to-refresh].is-springing-back::before,
  [data-pull-to-refresh].is-springing-back::after {
    transition:      none;
  }

  [data-pull-to-refresh]::before,
  [data-pull-to-refresh]::after {
    /* Drag-following transform is direct manipulation, but the opacity
       transition collapses to instant under reduced-motion. */
    transition:      none;
  }
}

/* ==========================================================================
   MEDIA — <picture> manifest path (M14 Phase 3 · W16.4)
   Extends the Media block (Phase 5 · W2.14) at the MEDIA section above.
   Source: Views/Shared/Kit/_Media.cshtml · Model: MediaModel (ImageId path).
   Script: wwwroot/js/kit/media-lqip.js (LQIP blur-up companion).

   Hard rules engaged:
     #2  No raw hex — tokens only (--n-*, --brand-ink, etc.).
     #3  No raw ms — motion tokens only.
     #4  No inline style= on kit partials — LQIP applied via media-lqip.js JS companion.
    #10  prefers-reduced-motion: reduce — shimmer/transition collapses to instant
         (handled in the Phase 5 Media block above; no additional rules needed here).

   D7 (F-3-02 fix): stale bottom-tabs doc-comment line number reference updated
   in this same commit (removed "L8511-8526" stale reference; replaced with
   semantic description of the @media block).
   ========================================================================== */

/* The <figure> root is already styled by .media in the Phase 5 block above.
   The <picture> child needs display:contents (or block) so it doesn't
   create a layout boundary that breaks the aspect-ratio frame. */
.media picture {
  display:           contents;
}

/* The <img> inside <picture> inherits the .media__image treatment from the
   Phase 5 block. No additional rules needed — .media__image already provides:
     display: block; width: 100%; height: 100%; object-fit: cover;
     transition: opacity; data-media-loading opacity: 0 shimmer behaviour. */

/* LQIP host: when media-lqip.js sets backgroundImage on the <img>,
   background-size/position are also set by the script. This rule acts as
   a CSS-level default so the LQIP is never visible after the real image loads
   (the real image on top renders the LQIP invisible once opacity: 1). */
.media__image[data-lqip] {
  /* background-image, background-size, background-position set by media-lqip.js. */
  background-repeat: no-repeat;
}

/* Broken-placeholder state for missing manifest entries (dev-only path).
   Signals authoring gap. Production: ImageryManifestService throws before this renders. */
.media--manifest-missing {
  border:            2px dashed var(--state-danger);
  background-color:  color-mix(in srgb, var(--state-danger) 8%, var(--n-0));
}

.media--manifest-missing::after {
  content:          "Missing manifest entry";
  position:         absolute;
  inset:            0;
  display:          flex;
  align-items:      center;
  justify-content:  center;
  padding:          var(--sp-3);
  font-family:      var(--font-mono);
  font-size:        var(--fs-1);
  letter-spacing:   0.06em;
  text-transform:   uppercase;
  color:            var(--state-danger);
  text-align:       center;
}


/* ==========================================================================
   LAYOUT ROW
   Mobile-first responsive grid wrapper for stacking 2, 3, or 4 fields/cells
   side-by-side at >=768px (3/4-col steps up to 4 only at >=1024px) and
   stacking on mobile. Replaces Materialize `row + col s12 m6 l6` patterns.
   --4col extension authored in M18 Phase 1b-2 per D-1b1-FC1-R-Confirm-1
   established-pattern decision (4-col filter rows for ledger / log views
   with 4 sibling form fields including the FromToDate helper which emits
   2 children).
   ========================================================================== */
.l-row {
  display:               grid;
  grid-template-columns: 1fr;
  gap:                   var(--sp-4);
}
@media (min-width: 768px) {
  .l-row--2col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .l-row--3col { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .l-row--4col { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (min-width: 1024px) {
  .l-row--4col { grid-template-columns: repeat(4, minmax(0, 1fr)); }
}

/* ==========================================================================
   M19 PHASE 2 — CUSTOM.CSS RULE MIGRATIONS (layout target)
   Source: wwwroot/custom/custom.css (deleted at Phase 2 close)
   All legacy token refs replaced with canonical equivalents per M19 mapping.
   No new tokens introduced. Token map:
     --primary-color → --brand-ink
     --white         → --n-0
     --neutral-*     → --n-*
     --radius-sm     → --r-2  (6px → 8px; accepted visual delta)
     --radius-md     → --r-3  (12px)
     --radius-lg     → --r-4  (16px)
     --radius-full   → 9999px literal
     #e5e5e5 / #e9ecef → --n-200 (close match)
     #111827         → --n-900
   HC-mode note: --brand-ink is not in the state palette; no HC override.
   ========================================================================== */

/* ── .login-bg (M19 P2 migration)
   Live consumers: _LayoutNoMenu.cshtml:12, _LayoutPrint.cshtml:20.
   Classification (III) — no canonical equivalent.
   --primary-color (#2E7D32) → --brand-ink (#0F2018): accepted visual delta
   (login background was prototype green; canonical is brand near-black-green).
   ──────────────────────────────────────────────────────────────────────── */
.login-bg {
  background-repeat: no-repeat;
  background-size: cover;
  background-color: var(--brand-ink) !important;
}

/* ── .elfrique-breadcrumb block (M19 P2 migration)
   Live consumers: Views/Shared/_Breadcrumbs.cshtml, Views/Kit/Index.cshtml.
   Classification (III) — no standalone canonical equivalent
   (elfrique.components.layout.css has only a print-hide reference).
   Raw hex values mapped to canonical neutrals.
   Note: .elfrique-breadcrumb .breadcrumb-item a uses --primary-color for
   link color → --brand-ink. Fallback values removed as canonical resolves.
   ──────────────────────────────────────────────────────────────────────── */
.elfrique-breadcrumb {
  background-color: var(--n-50);
  padding: 12px 0;
  border-bottom: 1px solid var(--n-200);
}

.elfrique-breadcrumb .breadcrumb {
  margin-bottom: 0;
  font-size: 0.875rem;
}

.elfrique-breadcrumb .breadcrumb-item a {
  color: var(--brand-ink);
  text-decoration: none;
}

.elfrique-breadcrumb .breadcrumb-item a:hover {
  color: color-mix(in srgb, var(--brand-ink) 70%, var(--n-0));
  text-decoration: underline;
}

.elfrique-breadcrumb .breadcrumb-item.active {
  color: var(--n-600);
  font-weight: 500;
}

/* ==========================================================================
   M19 PHASE 2 — PUBLIC PAGE CSS MIGRATION (layout target, continued)
   Source: wwwroot/custom/custom.css (lines 822–1562 public-page block).
   Classification: (III) — all rules have live consumers; none have canonical
   equivalents in any elfrique sheet. Migrated to elfrique.components.layout.css
   per orphan-rule policy (public layout primitives).

   Token map (in addition to the map above):
     --secondary-color (#4CAF50 green focus/hover) →
         color-mix(in srgb, var(--brand-ink) 85%, var(--n-0))
         Accepted visual delta: green focus rings → brand-ink-tinted focus rings.
         This is consistent with the compat.css btn-primary:hover pattern.
     --color-three → --brand-spark (#E8912D identical value)
     --color-four  → no canonical token; var(--color-four, #e9ecef) fallback
                     value used where sole consumer (.loader) was found dead;
                     live occurrences use inline rgba() already (bottom-tab-create).
     --error / var(--color-error) → --state-danger
     Raw hex #E8F5E9 (green tint) → color-mix(in srgb, var(--brand-ink) 8%, var(--n-0))
                     (accepted visual delta: light teal-tinted bg)
     Raw hex #065f46, #991b1b, #1e40af, #92400e (badge text) → mapped to canonical
                     state/brand tokens in M19 fix-cycle 1.1 (F-P2-1). Mapping:
                     verified/free→--state-success, live→--state-danger,
                     elfrique→--brand-ink, partner→--state-info, paid→--state-warn.
                     Light fills via color-mix 12% over transparent.
     Raw px font-size/padding values in admin-layout rules: retained (scope-widening
     to extract these to fs-* tokens is out of M19 scope per anti-instruction §286).
   ========================================================================== */

/* ── Reset & Base (scoped to public pages via .has-bottom-tabs layout) ── */
.has-bottom-tabs a { text-decoration: none; /*color: inherit;*/ transition: color var(--d-1); }
.has-bottom-tabs ul { list-style: none; }
.has-bottom-tabs img { max-width: 100%; display: block; }
.has-bottom-tabs button { font-family: var(--font-sans); cursor: pointer; border: none; }
.has-bottom-tabs input, .has-bottom-tabs select, .has-bottom-tabs textarea { font-family: var(--font-sans); }

.container { max-width: 1280px; margin: 0 auto; padding: 0 24px; }
@media (max-width: 768px) { .container { padding: 0 16px; } }

.sr-only {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); border: 0;
}

/* ── Public Buttons ── */
.btn {
  display: inline-flex; align-items: center; justify-content: center;
  gap: 8px; font-weight: 600; border-radius: var(--r-2);
  transition: all var(--d-2) var(--ease-out-swift); white-space: nowrap;
}
.btn:hover { transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
/* M19 fix-cycle 1.4 (F-P2-4): scoped to .has-bottom-tabs to disambiguate from
   the canonical .btn-primary shim in elfrique.compat.css. Public-page tweaks
   add padding + font-size; compat.css owns the global brand-ink fill. */
.has-bottom-tabs .btn-primary { background: var(--brand-ink); color: var(--n-0); padding: 12px 24px; font-size: 14px; }
.has-bottom-tabs .btn-primary:hover { background: color-mix(in srgb, var(--brand-ink) 85%, var(--n-0)); box-shadow: var(--shadow-2); }
.btn-accent { background: var(--brand-spark); color: var(--n-0); padding: 12px 24px; font-size: 14px; }
.btn-accent:hover { background: color-mix(in srgb, var(--brand-spark) 85%, var(--n-900)); box-shadow: var(--shadow-2); }
.btn-secondary { background: var(--n-0); color: var(--brand-ink); border: 1.5px solid var(--brand-ink); padding: 12px 24px; font-size: 14px; }
.btn-secondary:hover { background: var(--brand-ink); color: var(--n-0); }
.btn-ghost { background: transparent; color: var(--brand-ink); padding: 10px 20px; font-size: 14px; }
.btn-ghost:hover { background: var(--n-100); }
.btn-sm { padding: 8px 16px; font-size: 13px; }
.btn-lg { padding: 16px 32px; font-size: 16px; }

@media (prefers-reduced-motion: reduce) {
  .btn { transition: none; }
  .btn:hover { transform: none; }
  .btn:active { transform: none; }
}

/* ── Public Badges ── */
.badge {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px; border-radius: 9999px;
  font-size: 11px; font-weight: 600;
}
/* badge-* mapped to canonical state/brand tokens (M19 fix-cycle 1.1, F-P2-1).
   Light-fill pattern: 12% state token over transparent for background, full state
   token for text. Semantic mapping: verified/free=success, live=danger,
   elfrique=brand-ink, partner=info, paid=warn. */
.badge-verified { background: color-mix(in srgb, var(--state-success) 12%, transparent); color: var(--state-success); }
.badge-live { background: color-mix(in srgb, var(--state-danger) 12%, transparent); color: var(--state-danger); animation: pulse-badge var(--d-5) infinite; }
.badge-elfrique { background: color-mix(in srgb, var(--brand-ink) 12%, transparent); color: var(--brand-ink); }
.badge-partner { background: color-mix(in srgb, var(--state-info) 12%, transparent); color: var(--state-info); }
.badge-free { background: color-mix(in srgb, var(--state-success) 12%, transparent); color: var(--state-success); }
.badge-paid { background: color-mix(in srgb, var(--state-warn) 12%, transparent); color: var(--state-warn); }
@keyframes pulse-badge { 0%, 100% { opacity: 1; } 50% { opacity: 0.7; } }

@media (prefers-reduced-motion: reduce) {
  .badge-live { animation: none; }
}

/* ── Section title / subtitle ── */
.section-title { font-size: 30px; font-weight: 700; color: var(--n-900); text-align: center; margin-bottom: 12px; }
.section-subtitle { font-size: 17px; color: var(--n-600); text-align: center; margin-bottom: 40px; max-width: 600px; margin-left: auto; margin-right: auto; line-height: 1.7; }
@media (max-width: 768px) {
  .section-title { font-size: 24px; }
  .section-subtitle { font-size: 15px; margin-bottom: 32px; }
}

/* ── Public Forms ── */
.form-group { margin-bottom: 20px; }
.form-group label { display: block; font-size: 14px; font-weight: 600; color: var(--n-700); margin-bottom: 6px; }
.form-group input, .form-group select, .form-group textarea {
  width: 100%; padding: 12px 14px; border: 1.5px solid var(--n-200);
  border-radius: var(--r-2); font-size: 15px; outline: none;
  transition: border-color var(--d-2); background: var(--n-0);
}
.form-group input:focus, .form-group select:focus, .form-group textarea:focus {
  border-color: color-mix(in srgb, var(--brand-ink) 85%, var(--n-0));
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--brand-ink) 10%, transparent);
}
.form-group textarea { resize: vertical; min-height: 100px; }
.form-row { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
@media (max-width: 768px) { .form-row { grid-template-columns: 1fr; } }

/* ── Top Bar ── */
.top-bar { background: var(--brand-ink); color: rgba(255,255,255,0.75); font-size: 13px; padding: 6px 0; }
.top-bar .container { display: flex; align-items: center; justify-content: space-between; }
.top-bar-left { display: flex; align-items: center; gap: 16px; }
.top-bar-right { display: flex; align-items: center; gap: 16px; }
.top-bar a { color: rgba(255,255,255,0.85); transition: color var(--d-1); }
.top-bar a:hover { color: var(--n-0); }
.currency-auto {
  display: flex; align-items: center; gap: 6px;
  font-size: 12px; color: rgba(255,255,255,0.8);
}
@media (max-width: 768px) { .top-bar { display: none; } }

/* ── Main Header ── */
.header-main { display: flex; align-items: center; justify-content: space-between; height: 68px; gap: 24px; }
.logo { flex-shrink: 0; display: inline-flex; align-items: center; }
.logo img { height: 36px; width: auto; }
.header-search { flex: 1; max-width: 520px; position: relative; }
.header-search input {
  width: 100%; height: 44px; padding: 0 44px 0 16px;
  border: 1.5px solid var(--n-200); border-radius: 9999px;
  font-size: 14px; outline: none; transition: border-color var(--d-2);
}
.header-search input:focus { border-color: color-mix(in srgb, var(--brand-ink) 85%, var(--n-0)); }
.header-search input::placeholder { color: var(--n-400); }
.header-search-btn {
  position: absolute; right: 4px; top: 50%; transform: translateY(-50%);
  width: 36px; height: 36px; border-radius: 50%;
  background: var(--brand-ink); color: var(--n-0);
  display: flex; align-items: center; justify-content: center;
}
.header-search-btn:hover { background: color-mix(in srgb, var(--brand-ink) 85%, var(--n-0)); }

/* ── Search Dropdown ── */
.search-dropdown {
  position: absolute; top: 100%; left: 0; right: 0; margin-top: 4px;
  background: var(--n-0); border: 1px solid var(--n-200); border-radius: 12px;
  box-shadow: 0 8px 24px rgba(0,0,0,0.12); z-index: 1060;
  max-height: 420px; overflow-y: auto;
}
.search-dropdown-group { padding: 8px 16px 4px; }
.search-dropdown-group-label {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px;
  color: var(--n-400); margin-bottom: 4px;
}
.search-dropdown-item {
  display: flex; align-items: center; gap: 12px; padding: 10px 16px;
  text-decoration: none; color: var(--n-900); border-radius: 8px;
  transition: background var(--d-1);
}
.search-dropdown-item:hover { background: var(--n-50); }
.search-dropdown-item img {
  width: 40px; height: 40px; border-radius: 8px; object-fit: cover; flex-shrink: 0;
  background: var(--n-100);
}
.search-dropdown-item-text { min-width: 0; }
.search-dropdown-item-name {
  font-size: 14px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.search-dropdown-item-subtitle {
  font-size: 12px; color: var(--n-400); white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.search-dropdown-empty {
  padding: 24px 16px; text-align: center; color: var(--n-400); font-size: 14px;
}
.search-dropdown-loading {
  padding: 24px 16px; text-align: center; color: var(--n-400); font-size: 13px;
}

/* ── Mobile Search Overlay ── */
.mobile-search-overlay {
  position: fixed; inset: 0; background: var(--n-0); z-index: 1070;
  display: none; flex-direction: column;
}
.mobile-search-overlay.active { display: flex; }
.mobile-search-header {
  display: flex; align-items: center; gap: 8px; padding: 12px 16px;
  border-bottom: 1px solid var(--n-100);
}
.mobile-search-header input {
  flex: 1; height: 44px; padding: 0 16px; border: 1.5px solid var(--n-200);
  border-radius: 9999px; font-size: 15px; outline: none;
}
.mobile-search-header input:focus { border-color: color-mix(in srgb, var(--brand-ink) 85%, var(--n-0)); }
.mobile-search-close {
  width: 40px; height: 40px; border-radius: 50%; display: flex;
  align-items: center; justify-content: center; background: none; color: var(--n-600);
}
.mobile-search-close:hover { background: var(--n-100); }
.mobile-search-results { flex: 1; overflow-y: auto; padding: 8px 0; }

/* ── Header Right / Notif ── */
.header-right { display: flex; align-items: center; gap: 8px; flex-shrink: 0; }
.header-notif {
  position: relative; width: 40px; height: 40px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  background: var(--n-50); transition: background var(--d-1);
}
.header-notif:hover { background: var(--n-200); }
.header-notif .notif-dot {
  position: absolute; top: 6px; right: 6px; width: 10px; height: 10px;
  border-radius: 50%; background: var(--state-danger); border: 2px solid var(--n-0);
}
.header-notif-wrap { position: relative; }

/* ── Notification Dropdown ── */
.notif-dropdown {
  display: none;
  position: absolute; top: calc(100% + 8px); right: 0; width: 360px;
  background: var(--n-0); border: 1px solid var(--n-200);
  border-radius: 12px; box-shadow: 0 8px 24px rgba(0,0,0,0.12);
  z-index: 1100; overflow: hidden;
}
.notif-dropdown-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 14px 16px; border-bottom: 1px solid var(--n-100);
}
.notif-dropdown-title { font-size: 15px; font-weight: 700; color: var(--n-900); }
.notif-mark-all-read { font-size: 13px; color: var(--brand-ink); font-weight: 600; }
.notif-mark-all-read:hover { text-decoration: underline; }
.notif-list { max-height: 400px; overflow-y: auto; }
.notif-item {
  display: flex; gap: 12px; padding: 12px 16px;
  cursor: pointer; transition: background var(--d-1); border-left: 3px solid transparent;
}
.notif-item:hover { background: var(--n-50); }
.notif-item.notif-unread { background: var(--n-0); border-left-color: var(--brand-ink); }
.notif-item.notif-read { background: var(--n-50); }
.notif-item-icon {
  width: 36px; height: 36px; border-radius: 50%; flex-shrink: 0;
  display: flex; align-items: center; justify-content: center;
  background: var(--n-100); color: var(--n-600); font-size: 16px;
}
.notif-item.notif-unread .notif-item-icon {
  background: color-mix(in srgb, var(--brand-ink) 8%, var(--n-0));
  color: var(--brand-ink);
}
.notif-item-body { flex: 1; min-width: 0; }
.notif-item-title {
  font-size: 13px; font-weight: 600; color: var(--n-900);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.notif-item-message {
  font-size: 12px; color: var(--n-600); line-height: 1.4; margin-top: 2px;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.notif-item-time { font-size: 11px; color: var(--n-400); margin-top: 4px; }
.notif-empty {
  padding: 40px 16px; text-align: center; color: var(--n-400);
}
.notif-empty i { font-size: 36px; display: block; margin-bottom: 8px; }
.notif-empty p { font-size: 13px; margin: 0; }
.notif-dropdown-footer {
  padding: 10px 16px; text-align: center; border-top: 1px solid var(--n-100);
}
.notif-dropdown-footer a {
  font-size: 13px; font-weight: 600; color: var(--brand-ink);
}
.notif-dropdown-footer a:hover { text-decoration: underline; }

/* ── Header auth / hamburger / responsive ── */
.header-auth { display: flex; align-items: center; gap: 8px; }
.hamburger { display: none; flex-direction: column; gap: 5px; background: none; padding: 8px; }
.hamburger span { display: block; width: 22px; height: 2px; background: var(--n-900); border-radius: 2px; transition: all var(--d-2); }
@media (max-width: 768px) {
  .header-search { display: none; }
  .hamburger { display: flex; }
  .header-right .btn { display: none; }
  .header-notif-wrap { display: none; }
}
@media (min-width: 769px) and (max-width: 992px) {
  .notif-dropdown { width: 320px; }
}

/* ── Navigation / mega-menu ── */
.nav-link {
  display: flex; align-items: center; gap: 4px; padding: 12px 24px;
  font-size: 13px; font-weight: 600; color: var(--n-700);
  white-space: nowrap; border-bottom: 2px solid transparent; transition: all var(--d-1);
}
.nav-link:hover, .nav-link.active { color: var(--brand-ink); border-bottom-color: var(--brand-ink); }
.nav-link svg { width: 16px; height: 16px; }
.nav-item { position: relative; }
.mega-menu {
  display: none; position: absolute; top: 100%; left: 0;
  min-width: 560px; background: var(--n-0);
  border-radius: 0 0 var(--r-4) var(--r-4);
  box-shadow: var(--shadow-3); padding: 20px;
  z-index: 1001; border-top: 2px solid var(--brand-ink);
}
.nav-item:hover .mega-menu { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.mega-menu-item { display: flex; align-items: flex-start; gap: 12px; padding: 12px; border-radius: var(--r-3); transition: background var(--d-1); }
.mega-menu-item:hover { background: var(--n-50); }
.mega-menu-icon { width: 40px; height: 40px; border-radius: var(--r-2); background: var(--n-100); display: flex; align-items: center; justify-content: center; font-size: 18px; flex-shrink: 0; }
.mega-menu-text h4 { font-size: 14px; font-weight: 600; color: var(--n-900); }
.mega-menu-text p { font-size: 12px; color: var(--n-600); margin-top: 2px; }

/* ── Mobile Nav ── */
.mobile-nav-overlay { display: none; position: fixed; inset: 0; z-index: 2000; background: rgba(0,0,0,0.5); }
.mobile-nav-overlay.active { display: block; }
.mobile-nav {
  position: fixed; top: 0; left: -300px; width: 300px; height: 100%;
  background: var(--n-0); z-index: 2001; transition: left var(--d-3) var(--ease-out-swift);
  overflow-y: auto; padding-bottom: 60px;
}
.mobile-nav.active { left: 0; }
.mobile-nav-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: 16px 20px; border-bottom: 1px solid var(--n-200);
}
.mobile-nav-close { background: none; font-size: 24px; color: var(--n-600); }
.mobile-nav-items { padding: 16px 0; }
.mobile-nav-item {
  display: block; padding: 14px 20px; font-size: 15px; font-weight: 600;
  color: var(--n-700); border-bottom: 1px solid var(--n-100);
}
.mobile-nav-item:hover { background: var(--n-50); color: var(--brand-ink); }
.mobile-nav-sub { padding-left: 20px; display: none; }
.mobile-nav-sub a { display: block; padding: 10px 20px; font-size: 14px; color: var(--n-600); font-weight: 500; }
.mobile-nav-sub a:hover { color: var(--brand-ink); }
.mobile-nav-auth {
  padding: 20px; display: flex; flex-direction: column; gap: 10px;
  border-top: 1px solid var(--n-200); margin-top: 16px;
}
.mobile-nav-auth .btn { width: 100%; justify-content: center; }

@media (prefers-reduced-motion: reduce) {
  .mobile-nav { transition: none; }
}

/* ── Bottom Tab Bar ── */
.bottom-tab-bar {
  display: none; position: fixed; bottom: 0; left: 0; right: 0;
  background: var(--n-0); border-top: 1px solid var(--n-200);
  z-index: 1000; padding-bottom: env(safe-area-inset-bottom);
}
.bottom-tabs { display: flex; justify-content: space-around; align-items: center; height: 60px; }
.bottom-tab {
  display: flex; flex-direction: column; align-items: center; gap: 3px;
  font-size: 10px; font-weight: 600; color: var(--n-400); background: none;
  transition: color var(--d-1); padding: 4px 12px;
}
.bottom-tab.active { color: var(--brand-ink); }
.bottom-tab svg { width: 22px; height: 22px; }
.bottom-tab-create {
  width: 48px; height: 48px; border-radius: 50%;
  background: var(--brand-spark); color: var(--n-0);
  display: flex; align-items: center; justify-content: center;
  box-shadow: 0 4px 12px rgba(232,145,45,0.4); margin-top: -20px;
}
.bottom-tab-create svg { width: 24px; height: 24px; }
@media (max-width: 768px) { .bottom-tab-bar { display: block; } body.has-bottom-tabs { padding-bottom: 70px; } }

/* ── Public Footer (legacy .footer class — distinct from .footer-public BEM variant) ── */
.footer { background: var(--n-900); color: rgba(255,255,255,0.7); padding: 80px 0 0; }
.footer-grid { display: grid; grid-template-columns: 1.5fr 1fr 1fr 1fr; gap: 56px; }
.footer-brand p { font-size: 14px; margin: 16px 0 24px; line-height: 1.7; }
.footer-socials { display: flex; gap: 12px; }
.footer-social-link {
  width: 40px; height: 40px; border-radius: 50%; background: rgba(255,255,255,0.1);
  display: flex; align-items: center; justify-content: center;
  transition: all var(--d-1); font-size: 16px;
}
.footer-social-link:hover { background: var(--brand-spark); color: var(--n-0); transform: translateY(-2px); }
.footer-col h4 {
  font-size: 15px; font-weight: 600; color: var(--n-0);
  margin-bottom: 20px; text-transform: uppercase; letter-spacing: 0.5px;
}
.footer-col a { display: block; font-size: 14px; padding: 5px 0; color: rgba(255,255,255,0.6); transition: color var(--d-1); }
.footer-col a:hover { color: var(--brand-spark); }
.footer-col .footer-contact-line { display: block; font-size: 14px; padding: 5px 0; color: rgba(255,255,255,0.6); }
.footer-col .footer-contact-line a { display: inline; padding: 0; }
.footer-bottom {
  margin-top: 48px; padding: 20px 0;
  border-top: 1px solid rgba(255,255,255,0.1);
  display: flex; justify-content: space-between; align-items: center; font-size: 13px;
}
@media (max-width: 768px) {
  .footer { padding: 48px 0 0; }
  .footer-grid { grid-template-columns: 1fr 1fr; gap: 32px; }
  .footer-brand { grid-column: 1 / -1; }
  .footer-bottom { flex-direction: column; gap: 8px; text-align: center; }
}

/* ── Live Chat Button ── */
.live-chat-btn {
  position: fixed; bottom: 24px; right: 24px; width: 52px; height: 52px;
  border-radius: 50%; background: var(--brand-ink); color: var(--n-0);
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; box-shadow: var(--shadow-2); z-index: 999; transition: all var(--d-2);
}
.live-chat-btn:hover { background: color-mix(in srgb, var(--brand-ink) 85%, var(--n-0)); transform: scale(1.1); }
@media (max-width: 768px) { .live-chat-btn { bottom: 80px; width: 48px; height: 48px; font-size: 18px; } }

/* ── Scroll Animations ── */
.fade-in-up { opacity: 0; transform: translateY(30px); transition: opacity var(--d-5) var(--ease-out-swift), transform var(--d-5) var(--ease-out-swift); }
.fade-in-up.visible { opacity: 1; transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .fade-in-up { opacity: 1; transform: none; transition: none; }
}

/* ── Header avatar wrap (M20: positioning context for _UserMenu .user-menu dropdown) ── */
.header-avatar-wrap { position: relative; }

/* ── Browse Filter Sidebar + Drawer ── */
.browse-results-layout {
  display: grid; grid-template-columns: 280px 1fr; gap: 32px; align-items: start;
}
.filter-sidebar {
  position: sticky; top: 80px; background: var(--n-0);
  border: 1px solid var(--n-200); border-radius: var(--r-4);
  padding: 24px; box-shadow: var(--shadow-1);
}
.filter-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
.filter-header h3 { font-size: 16px; font-weight: 700; color: var(--n-900); margin: 0; }
.filter-clear {
  font-size: 13px; font-weight: 600; color: var(--brand-ink);
  cursor: pointer; background: none; border: none;
}
.filter-clear:hover { color: color-mix(in srgb, var(--brand-ink) 80%, var(--n-900)); }
.filter-group { margin-bottom: 24px; padding-bottom: 24px; border-bottom: 1px solid var(--n-100); }
.filter-group:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }
.filter-group-title { font-size: 14px; font-weight: 700; color: var(--n-900); margin-bottom: 12px; }
.filter-group select {
  width: 100%; padding: 10px 12px; border: 1.5px solid var(--n-200);
  border-radius: var(--r-2); font-size: 14px; color: var(--n-700);
  outline: none; background: var(--n-0); cursor: pointer; transition: border-color var(--d-2);
}
.filter-group select:focus { border-color: color-mix(in srgb, var(--brand-ink) 85%, var(--n-0)); }
.filter-checkbox {
  display: flex; align-items: center; gap: 10px; padding: 6px 0;
  cursor: pointer; font-size: 14px; color: var(--n-700); transition: color var(--d-1);
}
.filter-checkbox:hover { color: var(--n-900); }
.filter-checkbox input[type="checkbox"],
.filter-checkbox input[type="radio"] {
  width: 18px; height: 18px; accent-color: var(--brand-ink);
  cursor: pointer; flex-shrink: 0;
}
.filter-checkbox .count { margin-left: auto; font-size: 12px; color: var(--n-400); font-weight: 500; }
.filter-date-row { display: flex; gap: 8px; }
.filter-date-input {
  width: 100%; padding: 10px 12px; border: 1.5px solid var(--n-200);
  border-radius: var(--r-2); font-size: 14px; color: var(--n-700);
  outline: none; transition: border-color var(--d-2);
}
.filter-date-input:focus { border-color: color-mix(in srgb, var(--brand-ink) 85%, var(--n-0)); }
.mobile-filter-btn {
  display: none; align-items: center; gap: 6px; padding: 10px 20px;
  border-radius: 9999px; border: 1.5px solid var(--n-200);
  background: var(--n-0); font-size: 14px; font-weight: 600; cursor: pointer;
}
.filter-drawer-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 1200; display: none; }
.filter-drawer-overlay.open { display: block; }
.filter-drawer {
  position: fixed; top: 0; left: -340px; width: 320px; height: 100vh;
  background: var(--n-0); z-index: 1201; overflow-y: auto;
  transition: left var(--d-3) var(--ease-out-swift); padding: 24px;
}
.filter-drawer.open { left: 0; }
.filter-drawer-header {
  display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px;
}
.filter-drawer-close { background: none; border: none; font-size: 24px; cursor: pointer; color: var(--n-600); }
@media (max-width: 900px) {
  .browse-results-layout { grid-template-columns: 1fr; }
  .filter-sidebar { display: none; }
  .mobile-filter-btn { display: inline-flex; }
}
@media (prefers-reduced-motion: reduce) {
  .filter-drawer { transition: none; }
}

/* ── Card hover states ── */
.service-card:hover, .earning-card:hover, .qr-card:hover,
.vendor-slide-card:hover, .campaign-card:hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-2);
}
@media (prefers-reduced-motion: reduce) {
  .service-card:hover, .earning-card:hover, .qr-card:hover,
  .vendor-slide-card:hover, .campaign-card:hover {
    transform: none;
  }
}

/* ── Ad Placeholder ── */
.ad-placeholder { display: none !important; }

/* ==========================================================================
   Currency toggle — header chip group (multi-currency mandate, ported on
   merge of origin/main into design-refresh)
   --------------------------------------------------------------------------
   Origin: src/Elfrique.Web.Ui/wwwroot/css/elfrique.components.css (deleted
   on M19). Token-rewrites applied on port:
     --neutral-100 → --n-100, --neutral-200 → --n-200, --neutral-700 → --n-700,
     --neutral-900 → --n-900, --white → --n-0, --primary-color → --brand-ink,
     --radius-full → 9999px (M19 convention), raw 150-millisecond → --d-1 +
     --ease-out-swift, raw outline (banned green hex) → --state-info per HR1.
   Touch target ≥44×44 preserved. prefers-reduced-motion fallback retained.
   ========================================================================== */

.currency-toggle {
    display: inline-flex;
    align-items: center;
    gap: 4px;
    padding: 4px;
    background: var(--n-100);
    border: 1px solid var(--n-200);
    border-radius: 9999px;
    margin-right: 8px;
}

.currency-toggle__option {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-width: 44px;
    min-height: 44px;
    padding: 0 12px;
    border: none;
    background: transparent;
    color: var(--n-700);
    border-radius: 9999px;
    font-size: 13px;
    font-weight: 600;
    line-height: 1;
    cursor: pointer;
    transition: background-color var(--d-1) var(--ease-out-swift),
                color            var(--d-1) var(--ease-out-swift);
}

.currency-toggle__option:hover {
    background: var(--n-200);
    color: var(--n-900);
}

.currency-toggle__option:focus-visible {
    outline: 2px solid var(--state-info);
    outline-offset: 2px;
}

.currency-toggle__option.is-active {
    background: var(--n-0);
    color: var(--n-900);
    box-shadow: var(--shadow-1);
}

.currency-toggle__option.is-active:hover {
    background: var(--n-0);
    color: var(--n-900);
}

.currency-toggle__symbol {
    font-size: 14px;
    line-height: 1;
}

.currency-toggle__iso {
    font-size: 12px;
    letter-spacing: 0.04em;
}

@media (prefers-reduced-motion: reduce) {
    .currency-toggle__option {
        transition: none;
    }
}

@media (max-width: 480px) {
    .currency-toggle__iso {
        display: none;
    }
}

/* Read-only chip — surfaced when AppSettings.AllowCurrencySelection=false.
   Same pill geometry as the interactive chip but no hover state, no
   pointer cursor, no focus ring (it is not a button). */
.currency-toggle__option--readonly {
    cursor: default;
    background: var(--n-0);
    color: var(--n-900);
    box-shadow: var(--shadow-1);
}

.currency-toggle__option--readonly:hover {
    background: var(--n-0);
    color: var(--n-900);
}

/* "Use my location" link — surfaced when AllowCurrencySelection=true AND
   the buyer has a session override active. Clears the override and reloads
   so the formatter re-renders in the geo-resolved currency. */
.currency-toggle__use-location {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
    padding: 0 12px;
    margin-left: 4px;
    border: none;
    background: transparent;
    color: var(--n-700);
    font-size: 12px;
    font-weight: 500;
    line-height: 1;
    text-decoration: underline;
    cursor: pointer;
    border-radius: 9999px;
    transition: color var(--d-1) var(--ease-out-swift);
}

.currency-toggle__use-location:hover {
    color: var(--n-900);
}

.currency-toggle__use-location:focus-visible {
    outline: 2px solid var(--state-info);
    outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
    .currency-toggle__use-location {
        transition: none;
    }
}

@media (max-width: 480px) {
    .currency-toggle__use-location {
        font-size: 11px;
        padding: 0 8px;
    }
}

/* ==========================================================================
   FX snapshot — buyer receipt FX-rate breakdown (multi-currency mandate)
   --------------------------------------------------------------------------
   Rendered on Views/Checkout/OrderConfirmation.cshtml when
   FxSettings.ShowFxBlockOnBuyerSurfaces == true AND the three-way coincidence
   rule does not hold. Tokens only — no raw hex / ms.
   Token-rewrites: --neutral-* → --n-*.
   ========================================================================== */

.fx-snapshot {
    margin-top: 16px;
    padding: 16px 20px;
    background: var(--n-100);
    border: 1px solid var(--n-200);
    border-radius: var(--r-4);
}

.fx-snapshot__heading {
    font-size: 13px;
    font-weight: 700;
    color: var(--n-700);
    text-transform: uppercase;
    letter-spacing: 0.05em;
    margin-bottom: 10px;
}

.fx-snapshot__row {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    padding: 4px 0;
    font-size: 14px;
    color: var(--n-800);
}

.fx-snapshot__row-label {
    color: var(--n-700);
}

.fx-snapshot__row-value {
    font-weight: 600;
    color: var(--n-900);
}

.fx-snapshot__rate {
    margin-top: 8px;
    padding-top: 10px;
    border-top: 1px solid var(--n-200);
}

.fx-snapshot__disclosure {
    margin-top: 12px;
    padding-top: 10px;
    border-top: 1px solid var(--n-200);
    font-size: 12px;
    color: var(--n-600);
    line-height: 1.5;
}


/* ==========================================================================
   PAYMENT VERIFY (M23 Phase 2 · B4 — M31 Phase 10 N23 reposition)
   Public anonymous payment-verification page (/payment/verify). The form
   now lives in its own .payment-verify-section directly below the kit
   Hero (M31 Phase 10 N23a — was previously embedded in HeroModel.SearchSlot
   which left empty whitespace under the hero on initial GET). The result
   card below the form uses --state-success (Hard rule #1: --state-success
   is teal, not green) and --state-warn (amber) tokens — never raw hex.
   Source view: Views/PaymentVerification/Verify.cshtml.
   ========================================================================== */

/* Section wrapper that hosts the verify form below the hero. Centers a
   readable column width and provides vertical rhythm matching the hero
   subcopy/eyebrow spacing token scale. */
.payment-verify-section {
  width:          100%;
  max-width:      48rem;
  margin:         var(--sp-6) auto;
  padding:        0 var(--sp-5);
}

.payment-verify-form {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-3);
  width:          100%;
  /* M30 Phase 2 (F-2-3 / L7) — verify-payment text box hero alignment.
     Prior `margin: 0 auto` centered the form within the .hero__search slot
     (max 36rem), which left the input row indented from the hero headline /
     subcopy left edge. Drop the auto-centering so the form aligns with the
     hero content's left gutter, matching the home-search precedent at
     elfrique.components.layout.css:1413-1418 (.home-search has no
     auto-margin). max-width matches .hero__search (36rem) so the input row
     fills the same width as Home's search slot. */
  max-width:      36rem;
}

.payment-verify-form__row {
  display:        flex;
  flex-wrap:      wrap;
  gap:            var(--sp-3);
  align-items:    stretch;
}

.payment-verify-form__input {
  flex:           1 1 18rem;
  min-height:     48px; /* HR8 — 44x44 minimum touch target. */
  padding:        var(--sp-3) var(--sp-4);
  font-family:    var(--font-mono);
  font-size:      var(--fs-3);
  color:          var(--brand-ink);
  background:     var(--n-0);
  border:         2px solid var(--n-200);
  border-radius:  var(--r-2);
  transition:     border-color var(--d-1) var(--ease-out-swift),
                  box-shadow   var(--d-1) var(--ease-out-swift);
}

.payment-verify-form__input::placeholder {
  color:          var(--n-500);
}

.payment-verify-form__input:focus-visible {
  outline:        3px solid var(--state-info);
  outline-offset: 2px;
  border-color:   var(--brand-ink);
}

.payment-verify-form__input[aria-invalid="true"] {
  border-color:   var(--state-warn);
}

.payment-verify-form__submit {
  /* Reuses .btn .btn--primary .btn--lg from elfrique.css (48px height,
     >= 44x44 touch target — HR8). This selector exists only to stretch
     the button across the row at narrow widths so it doesn't dangle. */
  flex:           0 0 auto;
}

.payment-verify-form__help,
.payment-verify-form__error {
  margin:         0;
  font-family:    var(--font-sans);
  font-size:      var(--fs-2);
  line-height:    1.5;
}

.payment-verify-form__help {
  color:          var(--n-600);
}

.payment-verify-form__error {
  color:          var(--state-warn);
  font-weight:    500;
}

@media (prefers-reduced-motion: reduce) {
  .payment-verify-form__input {
    transition:   none;
  }
}

/* --- Result card below the hero -------------------------------------- */

.payment-verify-result {
  width:          100%;
  max-width:      48rem;
  margin:         var(--sp-6) auto;
  padding:        0 var(--sp-5);
}

.payment-verify-result__inner {
  display:        flex;
  flex-direction: column;
  align-items:    center;
  gap:            var(--sp-3);
  padding:        var(--sp-6) var(--sp-5);
  text-align:     center;
  background:     var(--n-0);
  border:         2px solid var(--n-200);
  border-radius:  var(--r-3);
  box-shadow:     var(--shadow-1);
}

.payment-verify-result__icon {
  font-size:      var(--fs-6);
  line-height:    1;
}

.payment-verify-result__headline {
  margin:         0;
  font-family:    var(--font-serif);
  font-size:      var(--fs-5);
  font-weight:    600;
  color:          var(--brand-ink);
  line-height:    1.2;
}

.payment-verify-result__body {
  margin:         0;
  font-family:    var(--font-sans);
  font-size:      var(--fs-3);
  color:          var(--n-700);
  line-height:    1.5;
}

/* Success — uses --state-success (TEAL per HR1, never green). */
.payment-verify-result--success .payment-verify-result__inner {
  border-color:   var(--state-success);
  background:     color-mix(in srgb, var(--state-success) 6%, var(--n-0));
}

.payment-verify-result--success .payment-verify-result__icon {
  color:          var(--state-success);
}

/* Warn — used for the NotSuccessful branch. Amber, not danger-red:
   "not successful" is informational, not a hard error from the user's
   perspective (they may simply need to wait for gateway settlement). */
.payment-verify-result--warn .payment-verify-result__inner {
  border-color:   var(--state-warn);
  background:     color-mix(in srgb, var(--state-warn) 6%, var(--n-0));
}

.payment-verify-result--warn .payment-verify-result__icon {
  color:          var(--state-warn);
}

/* ====================================================================
   PAYMENT-VERIFY DETAIL — M50 2026-05-16 transaction-visibility Phase 4
   ====================================================================
   Transactional card replaces the binary success message. M23 PII
   redaction reopened (event/item title + quantity + amount + timestamp
   + statuses surfaced); name / email / phone / IP still PII-banned.

   The card splits into:
     - header  (headline + reference)
     - grid    (definition-list of transactional fields)
     - fulfillment panel (locked-copy + status pill — the user-trust hinge)

   Tokens only (HR2). No inline style= or <style> blocks. Tokens used:
   --sp-*, --n-*, --r-*, --shadow-*, --state-success, --font-sans,
   --font-serif, --font-mono, --fs-*. No raw hex; no raw ms.
   ==================================================================== */

.payment-verify-detail {
  width:          100%;
  max-width:      48rem;
  margin:         var(--sp-6) auto;
  padding:        0 var(--sp-5);
}

.payment-verify-detail__inner {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-5);
  padding:        var(--sp-6) var(--sp-5);
  background:     var(--n-0);
  border:         2px solid var(--state-success);
  border-radius:  var(--r-3);
  box-shadow:     var(--shadow-1);
}

.payment-verify-detail__header {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-2);
  text-align:     center;
}

.payment-verify-detail__headline {
  margin:         0;
  font-family:    var(--font-serif);
  font-size:      var(--fs-5);
  font-weight:    600;
  color:          var(--brand-ink);
  line-height:    1.2;
}

.payment-verify-detail__reference {
  margin:         0;
  display:        inline-flex;
  flex-wrap:      wrap;
  justify-content: center;
  align-items:    center;
  gap:            var(--sp-2);
  font-size:      var(--fs-2);
  color:          var(--n-700);
}

.payment-verify-detail__reference-label {
  font-family:    var(--font-sans);
  font-weight:    500;
  color:          var(--n-600);
}

.payment-verify-detail__reference-value {
  font-family:    var(--font-mono);
  font-weight:    600;
  color:          var(--brand-ink);
  letter-spacing: 0.02em;
}

.payment-verify-detail__grid {
  margin:         0;
  display:        grid;
  grid-template-columns: 1fr;
  gap:            var(--sp-3);
  padding:        var(--sp-4) 0;
  border-top:     1px solid var(--n-200);
  border-bottom:  1px solid var(--n-200);
}

.payment-verify-detail__row {
  display:        flex;
  flex-wrap:      wrap;
  align-items:    center;
  justify-content: space-between;
  gap:            var(--sp-3);
}

.payment-verify-detail__label {
  margin:         0;
  font-family:    var(--font-sans);
  font-size:      var(--fs-2);
  font-weight:    500;
  color:          var(--n-600);
}

.payment-verify-detail__value {
  margin:         0;
  font-family:    var(--font-sans);
  font-size:      var(--fs-3);
  font-weight:    500;
  color:          var(--brand-ink);
  text-align:     right;
}

.payment-verify-detail__fulfillment {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-3);
}

.payment-verify-detail__fulfillment-row {
  display:        flex;
  flex-wrap:      wrap;
  align-items:    center;
  justify-content: space-between;
  gap:            var(--sp-3);
}

.payment-verify-detail__fulfillment-headline {
  margin:         0;
  font-family:    var(--font-sans);
  font-size:      var(--fs-3);
  font-weight:    600;
  color:          var(--brand-ink);
}

.payment-verify-detail__fulfillment-copy {
  margin:         0;
  font-family:    var(--font-sans);
  font-size:      var(--fs-3);
  color:          var(--n-800);
  line-height:    1.5;
}

/* ============================================================================
   VENDOR PROFILE — Phase 6 (mandate 2026-05-07-admin-fix-batch)
   ============================================================================
   Promoted from the deleted inline <style> block at Views/Public/VendorProfile.cshtml.
   All raw hex / ms / inline-style violations removed. The block is fully
   token-driven (numeric / percentage / aspect-ratio literals retained per
   plan-review amendment 6). Hard rules engaged:
     #2 token-only colors (incl. KoraPay color-mix per VotingContest precedent)
     #3 motion tokens (--d-1..--d-5) only — no raw ms
     #8 ≥44×44 touch target on share-btns / booking-submit / copy-link
     #10 prefers-reduced-motion: reduce fallback for .vendor-profile__animate
   Amendment 1: social share btns reuse `social-follow-btn.fb/.tw/.wa` palette
     — `var(--state-info)` / color-mix(state-info,80%,n-0) / `var(--state-success)`.
   Amendment 4: 13 distinct gradient slots derived from brand + state tokens
     via color-mix expressions — no token-surface expansion.
   ============================================================================ */

/* Hero wrap — overrides the kit hero's surface to the brand-ink editorial tone.
   The kit Hero partial owns layout; this rule paints the section background and
   forces the BelowContentSlot card on top. */
.vendor-profile__hero-wrap {
  background:    linear-gradient(135deg,
                  color-mix(in oklab, var(--brand-ink) 90%, var(--n-900)) 0%,
                  var(--brand-ink) 40%,
                  color-mix(in oklab, var(--brand-ink) 70%, var(--state-success)) 70%,
                  var(--brand-ink) 100%);
  color:         var(--n-0);
  padding:       80px 0 60px;
  position:      relative;
  overflow:      hidden;
}
.vendor-profile__hero-wrap .hero,
.vendor-profile__hero-wrap .hero__headline,
.vendor-profile__hero-wrap .hero__eyebrow,
.vendor-profile__hero-wrap .hero__subcopy {
  color:         var(--n-0);
}
.vendor-profile__hero-wrap .hero__headline-pre {
  color:         var(--n-0);
}

/* BelowContentSlot — avatar disc + badges + rating + meta. */
.vendor-profile__hero-below {
  display:        flex;
  flex-direction: column;
  align-items:    center;
  gap:            12px;
}
.vendor-profile__avatar {
  width:           120px;
  height:          120px;
  border-radius:   50%;
  background:      linear-gradient(135deg,
                    var(--brand-spark),
                    color-mix(in oklab, var(--brand-spark) 70%, var(--brand-ink)));
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       42px;
  font-weight:     800;
  color:           var(--n-0);
  border:          4px solid color-mix(in srgb, var(--n-0) 30%, transparent);
  box-shadow:      0 8px 32px color-mix(in srgb, var(--n-900) 30%, transparent);
  letter-spacing:  1px;
}
.vendor-profile__badges {
  display:        flex;
  align-items:    center;
  gap:            10px;
  flex-wrap:      wrap;
  justify-content: center;
}
.vendor-profile__badge {
  display:        inline-flex;
  align-items:    center;
  gap:            5px;
  padding:        5px 14px;
  border-radius:  9999px;
  font-size:      13px;
  font-weight:    600;
}
.vendor-profile__badge-icon {
  font-size:      14px;
}
.vendor-profile__badge--certified {
  background:     color-mix(in srgb, var(--brand-spark) 20%, transparent);
  color:          color-mix(in srgb, var(--brand-spark) 70%, var(--n-0));
  border:         1px solid color-mix(in srgb, var(--brand-spark) 35%, transparent);
}
.vendor-profile__badge--top {
  background:     color-mix(in srgb, var(--n-0) 15%, transparent);
  color:          var(--n-0);
  border:         1px solid color-mix(in srgb, var(--n-0) 25%, transparent);
}
.vendor-profile__badge--korapay {
  background:     color-mix(in oklab, var(--state-success) 20%, transparent);
  color:          color-mix(in oklab, var(--state-success) 50%, var(--n-0));
  border:         1px solid color-mix(in oklab, var(--state-success) 40%, transparent);
}
.vendor-profile__rating {
  display:        flex;
  align-items:    center;
  gap:            8px;
  font-size:      16px;
}
.vendor-profile__rating-stars {
  color:          var(--brand-spark);
  font-size:      18px;
  letter-spacing: 2px;
}
.vendor-profile__rating-score {
  font-weight:    700;
  font-size:      20px;
}
.vendor-profile__rating-count {
  opacity:        0.8;
  font-size:      14px;
}
.vendor-profile__meta {
  display:        flex;
  align-items:    center;
  gap:            20px;
  font-size:      14px;
  opacity:        0.85;
  flex-wrap:      wrap;
  justify-content: center;
}
.vendor-profile__meta-item {
  display:        inline-flex;
  align-items:    center;
  gap:            6px;
}
.vendor-profile__meta-item i {
  font-size:      16px;
  opacity:        0.7;
}

/* Hero CTA row — sits below kit hero, before the StatStrip. */
.vendor-profile__hero-actions {
  display:        flex;
  gap:            12px;
  margin-top:     20px;
  justify-content: center;
  flex-wrap:      wrap;
}
.vendor-profile__cta-primary,
.vendor-profile__cta-secondary {
  min-height:     44px;
  display:        inline-flex;
  align-items:    center;
  gap:            6px;
  padding:        12px 28px;
  font-size:      15px;
  border-radius:  6px;
  cursor:         pointer;
  transition:     background var(--d-1) var(--ease-out-swift),
                  transform var(--d-1) var(--ease-out-swift);
}
.vendor-profile__cta-secondary {
  background:     color-mix(in srgb, var(--n-0) 12%, transparent);
  color:          var(--n-0);
  border:         2px solid color-mix(in srgb, var(--n-0) 40%, transparent);
}
.vendor-profile__cta-secondary:hover {
  background:     color-mix(in srgb, var(--n-0) 25%, transparent);
  color:          var(--n-0);
}
.vendor-profile__cta-icon {
  font-size:      16px;
}

/* StatStrip overrides — match the dark hero surround. */
.vendor-profile__statstrip {
  margin-top:     24px;
}
.vendor-profile__statstrip .stat-strip {
  background:     color-mix(in srgb, var(--n-0) 10%, transparent);
  border:         1px solid color-mix(in srgb, var(--n-0) 15%, transparent);
  border-radius:  12px;
  padding:        16px 24px;
}
.vendor-profile__statstrip .stat-cell__label,
.vendor-profile__statstrip .stat-cell__value {
  color:          var(--n-0);
}
.vendor-profile__statstrip .stat-cell__label {
  opacity:        0.75;
}
/* Cell surface override — base .stat-cell uses var(--n-0) background + var(--n-200)
   border, which renders white-on-white against the dark hero. Lift to a token-driven
   transparent surface with a thin light border so cell text is legible. */
.vendor-profile__statstrip .stat-cell {
  background-color: transparent;
  border-color:     color-mix(in srgb, var(--n-0) 15%, transparent);
}

/* Two-column layout. */
.vendor-profile__layout {
  display:               grid;
  grid-template-columns: 1fr 380px;
  gap:                   32px;
  padding:               40px 0 80px;
  align-items:           start;
}
.vendor-profile__main { min-width: 0; }

/* Section blocks — token-driven surface. */
.vendor-profile__section {
  background:    var(--n-0);
  border:        1px solid var(--n-200);
  border-radius: 12px;
  padding:       32px;
  margin-bottom: 24px;
}
.vendor-profile__section-title {
  font-size:    22px;
  font-weight:  700;
  margin-bottom: 16px;
  color:        var(--n-900);
  display:      flex;
  align-items:  center;
  gap:          10px;
}
.vendor-profile__section-title i {
  font-size:    22px;
  color:        var(--brand-ink);
}

/* About text. */
.vendor-profile__about-text {
  font-size:    15px;
  line-height:  1.8;
  color:        var(--n-600);
}
.vendor-profile__about-text p + p {
  margin-top:   12px;
}

/* Services grid — service cell is plain (no kit ContentCard adoption since
   the existing surface is icon-glyph + 3-line copy + price; the ContentCard
   shape would force a media frame). The cell is composed from the same
   tokens used by other vendor surfaces. */
.vendor-profile__services-grid {
  display:               grid;
  grid-template-columns: repeat(2, 1fr);
  gap:                   16px;
}
.vendor-profile__service-cell {
  border:        1px solid var(--n-200);
  border-radius: 8px;
  padding:       24px;
  display:       flex;
  flex-direction: column;
  gap:           12px;
  transition:    border-color var(--d-2) var(--ease-out-swift),
                 transform var(--d-2) var(--ease-out-swift),
                 box-shadow var(--d-2) var(--ease-out-swift);
  position:      relative;
  overflow:      hidden;
}
.vendor-profile__service-cell::before {
  content:    '';
  position:   absolute;
  top:        0;
  left:       0;
  width:      4px;
  height:     100%;
  background: var(--brand-ink);
  transform:  scaleY(0);
  transition: transform var(--d-2) var(--ease-out-swift);
}
.vendor-profile__service-cell:hover {
  border-color: var(--brand-spark);
  box-shadow:   0 4px 12px color-mix(in srgb, var(--n-900) 8%, transparent);
  transform:    translateY(-2px);
}
.vendor-profile__service-cell:hover::before {
  transform:    scaleY(1);
}
.vendor-profile__service-icon {
  font-size: 28px;
  color:     var(--brand-ink);
}
.vendor-profile__service-icon i {
  font-size: 28px;
}
.vendor-profile__service-name {
  font-size: 16px;
  font-weight: 700;
  color:     var(--n-900);
  margin:    0;
}
.vendor-profile__service-desc {
  font-size:   13px;
  color:       var(--n-600);
  line-height: 1.5;
  margin:      0;
}
.vendor-profile__service-price {
  font-size:   15px;
  font-weight: 700;
  color:       var(--brand-ink);
}

/* Portfolio grid — 8 token-derived gradient slots (amendment 4). */
.vendor-profile__portfolio-grid {
  display:               grid;
  grid-template-columns: repeat(4, 1fr);
  gap:                   12px;
}
.vendor-profile__portfolio-item {
  aspect-ratio:  1;
  border-radius: 8px;
  overflow:      hidden;
  position:      relative;
  cursor:        pointer;
  border:        none;
  padding:       0;
  display:       block;
  min-height:    44px;
  min-width:     44px;
}
.vendor-profile__portfolio-placeholder {
  width:           100%;
  height:          100%;
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       28px;
  color:           color-mix(in srgb, var(--n-0) 70%, transparent);
  transition:      transform var(--d-4) var(--ease-out-swift),
                   filter var(--d-2) var(--ease-out-swift);
}
.vendor-profile__portfolio-item--g1 .vendor-profile__portfolio-placeholder {
  background: linear-gradient(135deg, var(--brand-ink),
              color-mix(in oklab, var(--state-success) 60%, var(--brand-ink)));
}
.vendor-profile__portfolio-item--g2 .vendor-profile__portfolio-placeholder {
  background: linear-gradient(135deg, var(--brand-spark),
              color-mix(in srgb, var(--brand-spark) 60%, var(--n-0)));
}
.vendor-profile__portfolio-item--g3 .vendor-profile__portfolio-placeholder {
  background: linear-gradient(135deg, var(--state-info),
              color-mix(in srgb, var(--state-info) 60%, var(--n-0)));
}
.vendor-profile__portfolio-item--g4 .vendor-profile__portfolio-placeholder {
  background: linear-gradient(135deg,
              color-mix(in oklab, var(--state-info) 60%, var(--state-danger)),
              color-mix(in srgb, var(--state-info) 40%, var(--n-0)));
}
.vendor-profile__portfolio-item--g5 .vendor-profile__portfolio-placeholder {
  background: linear-gradient(135deg, var(--state-danger),
              color-mix(in srgb, var(--state-danger) 60%, var(--n-0)));
}
.vendor-profile__portfolio-item--g6 .vendor-profile__portfolio-placeholder {
  background: linear-gradient(135deg, var(--state-success),
              color-mix(in srgb, var(--state-success) 60%, var(--n-0)));
}
.vendor-profile__portfolio-item--g7 .vendor-profile__portfolio-placeholder {
  background: linear-gradient(135deg,
              color-mix(in oklab, var(--brand-spark) 70%, var(--state-danger)),
              color-mix(in srgb, var(--brand-spark) 50%, var(--n-0)));
}
.vendor-profile__portfolio-item--g8 .vendor-profile__portfolio-placeholder {
  background: linear-gradient(135deg,
              color-mix(in oklab, var(--state-info) 70%, var(--brand-ink)),
              color-mix(in srgb, var(--state-info) 50%, var(--n-0)));
}
.vendor-profile__portfolio-overlay {
  position:        absolute;
  inset:           0;
  background:      color-mix(in srgb, var(--n-900) 40%, transparent);
  display:         flex;
  align-items:     center;
  justify-content: center;
  opacity:         0;
  transition:      opacity var(--d-2) var(--ease-out-swift);
}
.vendor-profile__portfolio-overlay i {
  font-size: 32px;
  color:     var(--n-0);
}
.vendor-profile__portfolio-item:hover .vendor-profile__portfolio-overlay,
.vendor-profile__portfolio-item:focus-visible .vendor-profile__portfolio-overlay {
  opacity: 1;
}
/* Hover scale promoted from JS (amendment 2 — pure CSS, no JS needed). */
.vendor-profile__portfolio-item:hover .vendor-profile__portfolio-placeholder,
.vendor-profile__portfolio-item:focus-visible .vendor-profile__portfolio-placeholder {
  transform: scale(1.08);
}

/* Reviews — rating distribution + individual reviews. */
.vendor-profile__rating-dist {
  margin-bottom: 28px;
}
.vendor-profile__rating-dist-row {
  display:      flex;
  align-items:  center;
  gap:          10px;
  margin-bottom: 8px;
  font-size:    14px;
}
.vendor-profile__rating-dist-label {
  width:       50px;
  font-weight: 600;
  color:       var(--n-700);
  text-align:  right;
}
.vendor-profile__rating-dist-bar {
  flex:           1;
  height:         10px;
  background:     var(--n-100);
  border-radius:  9999px;
  overflow:       hidden;
}
.vendor-profile__rating-dist-fill {
  height:        100%;
  width:         0%;
  border-radius: 9999px;
  background:    var(--brand-ink);
  transition:    width var(--d-5) var(--ease-out-swift);
}
.vendor-profile__rating-dist-count {
  width:     30px;
  font-size: 13px;
  color:     var(--n-400);
}

.vendor-profile__review {
  padding:       20px 0;
  border-bottom: 1px solid var(--n-100);
}
.vendor-profile__review:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.vendor-profile__review-header {
  display:      flex;
  align-items:  center;
  gap:          12px;
  margin-bottom: 10px;
}
.vendor-profile__review-avatar {
  width:           42px;
  height:          42px;
  border-radius:   50%;
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       16px;
  font-weight:     700;
  color:           var(--n-0);
  flex-shrink:     0;
}
/* 5 review-avatar slots (amendment 4) — token-derived, distinct from portfolio. */
.vendor-profile__review-avatar--g1 {
  background: linear-gradient(135deg, var(--brand-ink),
              color-mix(in oklab, var(--state-success) 60%, var(--brand-ink)));
}
.vendor-profile__review-avatar--g2 {
  background: linear-gradient(135deg, var(--brand-spark),
              color-mix(in srgb, var(--brand-spark) 60%, var(--n-0)));
}
.vendor-profile__review-avatar--g3 {
  background: linear-gradient(135deg, var(--state-info),
              color-mix(in srgb, var(--state-info) 60%, var(--n-0)));
}
.vendor-profile__review-avatar--g4 {
  background: linear-gradient(135deg,
              color-mix(in oklab, var(--state-info) 60%, var(--state-danger)),
              color-mix(in srgb, var(--state-info) 40%, var(--n-0)));
}
.vendor-profile__review-avatar--g5 {
  background: linear-gradient(135deg,
              color-mix(in oklab, var(--state-danger) 60%, var(--brand-spark)),
              color-mix(in srgb, var(--state-danger) 40%, var(--n-0)));
}
.vendor-profile__review-info { flex: 1; }
.vendor-profile__review-name {
  font-weight: 600;
  font-size:   15px;
  color:       var(--n-900);
}
.vendor-profile__review-date {
  font-size: 13px;
  color:     var(--n-400);
}
.vendor-profile__review-stars {
  color:          var(--brand-spark);
  font-size:      14px;
  letter-spacing: 1px;
}
.vendor-profile__review-stars-empty {
  color:          var(--n-300);
}
.vendor-profile__review-text {
  font-size:   14px;
  line-height: 1.7;
  color:       var(--n-600);
  margin-top:  4px;
}

/* Right sidebar — sticky on desktop. */
.vendor-profile__sidebar {
  position: sticky;
  top:      24px;
}

/* Booking card. */
.vendor-profile__booking-card {
  background:    var(--n-0);
  border:        1px solid var(--n-200);
  border-radius: 12px;
  padding:       28px;
  margin-bottom: 20px;
  box-shadow:    0 4px 12px color-mix(in srgb, var(--n-900) 8%, transparent);
  transition:    box-shadow var(--d-2) var(--ease-out-swift);
}
.vendor-profile__booking-card--highlighted {
  box-shadow:    0 0 0 3px color-mix(in srgb, var(--brand-spark) 40%, transparent),
                 0 8px 24px color-mix(in srgb, var(--n-900) 12%, transparent);
}
.vendor-profile__booking-title {
  font-size:    18px;
  font-weight:  700;
  color:        var(--n-900);
  margin-bottom: 20px;
  display:      flex;
  align-items:  center;
  gap:          8px;
}
.vendor-profile__booking-title i {
  font-size: 20px;
  color:     var(--brand-ink);
}
.vendor-profile__booking-card .form-field {
  margin-bottom: 16px;
}
.vendor-profile__booking-submit {
  width:         100%;
  min-height:    44px;
  padding:       14px;
  background:    var(--brand-spark);
  color:         var(--n-0);
  font-size:     16px;
  font-weight:   700;
  border:        none;
  border-radius: 6px;
  cursor:        pointer;
  transition:    background var(--d-1) var(--ease-out-swift),
                 transform var(--d-1) var(--ease-out-swift),
                 box-shadow var(--d-1) var(--ease-out-swift),
                 opacity var(--d-1) var(--ease-out-swift);
}
.vendor-profile__booking-submit:hover {
  background: color-mix(in srgb, var(--brand-spark) 85%, var(--n-900));
  box-shadow: 0 4px 12px color-mix(in srgb, var(--n-900) 8%, transparent);
  transform:  translateY(-1px);
}
.vendor-profile__booking-submit--submitting {
  opacity: 0.7;
  cursor:  not-allowed;
}
.vendor-profile__booking-submit--success {
  background: var(--state-success);
}
.vendor-profile__booking-note {
  text-align: center;
  font-size:  12px;
  color:      var(--n-400);
  margin-top: 12px;
}

/* Quick info card. */
.vendor-profile__quickinfo {
  background:    var(--n-0);
  border:        1px solid var(--n-200);
  border-radius: 12px;
  padding:       24px;
  margin-bottom: 20px;
}
.vendor-profile__quickinfo-title {
  font-size:     16px;
  font-weight:   700;
  margin-bottom: 16px;
  color:         var(--n-900);
}
.vendor-profile__quickinfo-row {
  display:         flex;
  justify-content: space-between;
  align-items:     flex-start;
  padding:         10px 0;
  border-bottom:   1px solid var(--n-100);
  font-size:       14px;
  gap:             12px;
}
.vendor-profile__quickinfo-row:last-child {
  border-bottom: none;
  padding-bottom: 0;
}
.vendor-profile__quickinfo-label {
  color:       var(--n-400);
  font-weight: 500;
  flex-shrink: 0;
}
.vendor-profile__quickinfo-value {
  color:       var(--n-900);
  font-weight: 600;
  text-align:  right;
}

/* KoraPay sidebar badge — color-mix on --state-success per VotingContest precedent. */
.vendor-profile__korapay-badge {
  display:        flex;
  align-items:    flex-start;
  gap:            12px;
  padding:        14px 16px;
  background:     color-mix(in oklab, var(--state-success) 8%, var(--n-0));
  border:         1px solid color-mix(in oklab, var(--state-success) 30%, transparent);
  border-radius:  8px;
  margin-bottom:  16px;
}
.vendor-profile__korapay-badge-icon {
  width:           36px;
  height:          36px;
  border-radius:   50%;
  background:      var(--state-success);
  display:         flex;
  align-items:     center;
  justify-content: center;
  color:           var(--n-0);
  font-size:       16px;
  font-weight:     800;
  flex-shrink:     0;
}
.vendor-profile__korapay-badge-content { flex: 1; }
.vendor-profile__korapay-badge-title {
  font-size:    13px;
  font-weight:  700;
  color:        color-mix(in oklab, var(--state-success) 60%, var(--n-900));
  margin-bottom: 6px;
  display:      flex;
  align-items:  center;
  gap:          6px;
}
.vendor-profile__korapay-verified-icon {
  color: color-mix(in oklab, var(--state-success) 70%, var(--n-0));
}
.vendor-profile__korapay-verified-items {
  display:   flex;
  flex-wrap: wrap;
  gap:       10px;
}
.vendor-profile__korapay-item {
  display:     inline-flex;
  align-items: center;
  gap:         4px;
  font-size:   12px;
  color:       color-mix(in oklab, var(--state-success) 60%, var(--n-900));
  font-weight: 500;
}
.vendor-profile__korapay-check {
  color:       color-mix(in oklab, var(--state-success) 70%, var(--n-0));
  font-weight: 700;
  font-size:   13px;
}

/* Share card — per-network btns reuse social-follow-btn precedent (amendment 1). */
.vendor-profile__share {
  background:    var(--n-0);
  border:        1px solid var(--n-200);
  border-radius: 12px;
  padding:       24px;
  margin-bottom: 20px;
}
.vendor-profile__share-title {
  font-size:    16px;
  font-weight:  700;
  margin-bottom: 16px;
  color:        var(--n-900);
}
.vendor-profile__share-btns {
  display: flex;
  gap:     10px;
  margin-bottom: 16px;
}
.vendor-profile__share-btn {
  flex:            1;
  min-height:      44px;
  min-width:       44px;
  height:          44px;
  border-radius:   6px;
  display:         flex;
  align-items:     center;
  justify-content: center;
  font-size:       14px;
  font-weight:     600;
  color:           var(--n-0);
  cursor:          pointer;
  border:          none;
  transition:      opacity var(--d-1) var(--ease-out-swift),
                   transform var(--d-1) var(--ease-out-swift);
}
.vendor-profile__share-btn:hover {
  opacity:   0.85;
  transform: translateY(-1px);
}
/* Per-network accents — amendment 1 — reuses .social-follow-btn palette
   so no new tokens enter elfrique.css. Network-brand hex banned per HR2. */
.vendor-profile__share-btn--fb   { background: var(--state-info); }
.vendor-profile__share-btn--tw   { background: color-mix(in srgb, var(--state-info) 80%, var(--n-0)); }
.vendor-profile__share-btn--wa   { background: var(--state-success); }
.vendor-profile__share-btn--link { background: var(--n-700); }

.vendor-profile__qr-placeholder {
  width:           100%;
  height:          120px;
  background:      var(--n-50);
  border:          2px dashed var(--n-200);
  border-radius:   8px;
  display:         flex;
  align-items:     center;
  justify-content: center;
  flex-direction:  column;
  gap:             6px;
  margin-bottom:   12px;
}
.vendor-profile__qr-placeholder i {
  font-size: 36px;
  color:     var(--n-300);
}
.vendor-profile__qr-placeholder span {
  font-size: 12px;
  color:     var(--n-400);
}
.vendor-profile__share-link {
  background:    var(--n-50);
  border:        1px solid var(--n-200);
  border-radius: 6px;
  padding:       10px 14px;
  font-size:     13px;
  color:         var(--brand-ink);
  font-weight:   600;
  text-align:    center;
  display:       block;
  word-break:    break-all;
}

/* Scroll animations — token motion + reduced-motion fallback (HR10). */
.vendor-profile__animate {
  opacity:    0;
  transform:  translateY(24px);
  transition: opacity var(--d-5) var(--ease-out-swift),
              transform var(--d-5) var(--ease-out-swift);
}
.vendor-profile__animate--visible {
  opacity:   1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .vendor-profile__animate {
    opacity:    1;
    transform:  none;
    transition: none;
  }
  .vendor-profile__rating-dist-fill,
  .vendor-profile__service-cell,
  .vendor-profile__service-cell::before,
  .vendor-profile__portfolio-placeholder,
  .vendor-profile__booking-card,
  .vendor-profile__booking-submit,
  .vendor-profile__share-btn,
  .vendor-profile__cta-primary,
  .vendor-profile__cta-secondary {
    transition: none;
  }
  .vendor-profile__portfolio-item:hover .vendor-profile__portfolio-placeholder,
  .vendor-profile__portfolio-item:focus-visible .vendor-profile__portfolio-placeholder {
    transform: none;
  }
}

/* Responsive. */
@media (max-width: 1024px) {
  .vendor-profile__layout {
    grid-template-columns: 1fr;
  }
  .vendor-profile__sidebar {
    position:              static;
    display:               grid;
    grid-template-columns: repeat(2, 1fr);
    gap:                   16px;
  }
  .vendor-profile__booking-card {
    grid-column: 1 / -1;
  }
}
@media (max-width: 768px) {
  .vendor-profile__hero-wrap {
    padding: 64px 0 40px;
  }
  .vendor-profile__avatar {
    width:     90px;
    height:    90px;
    font-size: 32px;
  }
  .vendor-profile__hero-actions {
    flex-direction: column;
    width:          100%;
    max-width:      300px;
    margin-left:    auto;
    margin-right:   auto;
  }
  .vendor-profile__hero-actions .vendor-profile__cta-primary,
  .vendor-profile__hero-actions .vendor-profile__cta-secondary,
  .vendor-profile__hero-actions .vendor-profile__hero-share {
    width:           100%;
    justify-content: center;
  }
  .vendor-profile__services-grid {
    grid-template-columns: 1fr;
  }
  .vendor-profile__portfolio-grid {
    grid-template-columns: repeat(2, 1fr);
  }
  .vendor-profile__section {
    padding: 24px 20px;
  }
  .vendor-profile__sidebar {
    display: block;
  }
}
@media (max-width: 480px) {
  .vendor-profile__portfolio-grid {
    grid-template-columns: repeat(2, 1fr);
    gap:                   8px;
  }
  .vendor-profile__share-btns {
    flex-wrap: wrap;
  }
  .vendor-profile__share-btn {
    flex: 1 1 40%;
  }
  .vendor-profile__meta {
    flex-direction: column;
    gap:            6px;
  }
}


/* ==========================================================================
   VOTING CONTEST — page-local layout/component primitives.
   Mandate 2026-05-08-creator-vendor-fix-batch · Phase 4 · CF-M23-3 closure.
   Extracted verbatim from the `<style asp-add-nonce>` block in
   Views/Public/VotingContest.cshtml (L12-L986) per hard rule #5 (no <style>
   in views). Razor `@@media` / `@@keyframes` escapes are unescaped to single
   `@` in this CSS file.
   Sections (preserved order from the original block):
     - Contest meta strip (korapay, badges, countdown, hero CTAs)
     - Contestants section (filter search, candidates header, counter)
     - Award nominee category tabs
     - Contestant card layout (no-image fallback, photo, info, results, vote btn)
     - Pagination controls
     - Contest description block
     - Top-3 performers strip (podium tints, avatar, hero shortlink)
     - Hero __below countdown chrome
     - Leaderboard section (podium gradients, table cells, mobile cards)
     - Results display toggle (bar chart, percentage, numerical)
     - Mobile sticky vote bar
     - Contestant detail modal
     - Footer active-link override (WK-142)
     - Contestant profile link (.contestant-profile-link)
     - Reduced-motion overrides (live-results)
   ========================================================================== */

/* M20 Phase 4 / slice 4 — restore styling for .korapay-badge-inline
   (M20 finding: class was consumed at the meta-strip render path with no
   matching rule, leaving the KoraPay verification chip visually unstyled).
   Mirrors the .badge-verified-lg surface treatment — same teal/white wash
   on the dark meta-strip — and emits a flex row for the icon+text+items
   sub-spans (.kp-icon, .kp-text, .kp-items, .kp-check). Token-only.

   M49 Phase 9 (D-9-14) — generalised the selector family with the
   .event-detail co-selector so the same chip renders in EventDetail's
   organiser column. Lower blast radius than removing the
   .contest-meta-strip ancestor entirely (other consumers may inherit
   the meta-strip class accidentally; co-selecting keeps the rule
   scoped to known consumers). */
.contest-meta-strip .korapay-badge-inline,
.event-detail .korapay-badge-inline,
.form-detail .korapay-badge-inline {
  display: inline-flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap;
  padding: 6px 14px; border-radius: 9999px;
  background: color-mix(in oklab, var(--state-success) 18%, transparent);
  border: 1px solid color-mix(in oklab, var(--state-success) 40%, transparent);
  color: color-mix(in oklab, var(--state-success) 50%, var(--n-0));
  font-size: 13px; font-weight: 600; min-height: 44px;
}
.contest-meta-strip .korapay-badge-inline .kp-icon,
.event-detail .korapay-badge-inline .kp-icon,
.form-detail .korapay-badge-inline .kp-icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%;
  background: color-mix(in oklab, var(--state-success) 50%, var(--n-0));
  color: var(--n-0); font-size: 12px; font-weight: 700;
}
.contest-meta-strip .korapay-badge-inline .kp-text,
.event-detail .korapay-badge-inline .kp-text,
.form-detail .korapay-badge-inline .kp-text { font-weight: 700; }
.contest-meta-strip .korapay-badge-inline .kp-items,
.event-detail .korapay-badge-inline .kp-items,
.form-detail .korapay-badge-inline .kp-items {
  display: inline-flex; align-items: center; gap: 10px; flex-wrap: wrap;
  font-size: 12px; opacity: 0.92;
}
.contest-meta-strip .korapay-badge-inline .kp-items > span,
.event-detail .korapay-badge-inline .kp-items > span,
.form-detail .korapay-badge-inline .kp-items > span {
  display: inline-flex; align-items: center; gap: 4px;
}
.contest-meta-strip .korapay-badge-inline .kp-check,
.event-detail .korapay-badge-inline .kp-check,
.form-detail .korapay-badge-inline .kp-check {
  color: color-mix(in oklab, var(--state-success) 60%, var(--n-0));
  font-weight: 700;
}
/* Meta-strip chrome rules — relocated from the deleted .contest-hero block
   in slice 3a. Slice 4 tokenised every raw-hex literal (red, green, amber)
   into --state-* / --brand-* color-mix expressions; touch-target min-height
   and prefers-reduced-motion fallbacks remain additive per CLAUDE.md hard
   rules #8 and #10.

   M49 Phase 9 (D-9-13) — generalised the .badge-live-lg + .pulse-dot family
   with the .event-detail co-selector so the EventDetail hero LIVE pill
   reuses the existing keyframe + reduced-motion fallback. No new keyframe,
   no new raw-ms duration introduced (Hard Rule #3 preserved). */
.contest-meta-strip .badge-live-lg,
.event-detail .badge-live-lg {
  display: inline-flex; align-items: center; gap: 6px;
  background: color-mix(in oklab, var(--state-danger) 15%, transparent);
  border: 1px solid color-mix(in oklab, var(--state-danger) 40%, transparent);
  color: color-mix(in oklab, var(--state-danger) 60%, var(--n-0));
  padding: 6px 14px; border-radius: 9999px;
  font-size: 13px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.5px;
  min-height: 44px;
}
.contest-meta-strip .pulse-dot,
.event-detail .pulse-dot {
  width: 8px; height: 8px; border-radius: 50%; background: var(--state-danger);
  animation: pulse-dot 1.5s ease-in-out infinite;
}
@keyframes pulse-dot {
  0%, 100% { opacity: 1; box-shadow: 0 0 0 0 color-mix(in oklab, var(--state-danger) 60%, transparent); }
  50% { opacity: 0.8; box-shadow: 0 0 0 6px color-mix(in oklab, var(--state-danger) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
  .contest-meta-strip .pulse-dot,
  .event-detail .pulse-dot { animation: none; }
}

/* M49 Phase 9 (D-9-13) — countdown-strip family. Reusable hero countdown
   block consumed by EventDetail hero (event start/end live window) and the
   contest hero (voting end window — replaces the static stub). The
   [data-countdown-unit] children are 2-digit numeric spans wired by
   wwwroot/js/kit/countdown-strip.js at ~1Hz. font-variant-numeric: tabular-
   nums prevents reflow on tick. The block degrades to its server-rendered
   initial frame under prefers-reduced-motion (JS short-circuits the rAF
   loop; CSS does not need motion overrides because the block has no entry
   animation of its own). */
.countdown-strip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
}
.countdown-strip__label {
  font-family: var(--font-mono);
  font-size: var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.05em;
  color: color-mix(in oklab, var(--brand-ink) 70%, var(--n-0));
}
.countdown-strip__boxes {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
}
.countdown-strip__box {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  min-width: 44px;
  min-height: 44px;
  padding: var(--sp-1) var(--sp-2);
  border-radius: var(--r-2);
  background: color-mix(in oklab, var(--brand-ink) 6%, var(--n-0));
  border: 1px solid color-mix(in oklab, var(--brand-ink) 12%, transparent);
}
.countdown-strip__num {
  font-family: var(--font-mono);
  font-size: var(--fs-3);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  line-height: 1.1;
  color: var(--brand-ink);
}
.countdown-strip__unit {
  font-family: var(--font-mono);
  font-size: var(--fs-1);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: color-mix(in oklab, var(--brand-ink) 65%, var(--n-0));
}
.countdown-strip__sep {
  font-family: var(--font-mono);
  font-size: var(--fs-3);
  font-weight: 700;
  color: color-mix(in oklab, var(--brand-ink) 40%, var(--n-0));
}

.contest-meta-strip .badge-verified-lg {
  display: inline-flex; align-items: center; gap: 5px;
  background: color-mix(in oklab, var(--state-success) 20%, transparent);
  border: 1px solid color-mix(in oklab, var(--state-success) 40%, transparent);
  color: color-mix(in oklab, var(--state-success) 50%, var(--n-0));
  padding: 6px 14px; border-radius: 9999px;
  font-size: 13px; font-weight: 600;
  min-height: 44px;
}
.contest-meta-strip .badge-category {
  display: inline-flex; align-items: center; gap: 5px;
  background: color-mix(in oklab, var(--brand-spark) 15%, transparent);
  border: 1px solid color-mix(in oklab, var(--brand-spark) 30%, transparent);
  color: var(--brand-spark);
  padding: 6px 14px; border-radius: 9999px;
  font-size: 13px; font-weight: 600;
  min-height: 44px;
}
.countdown-label {
  font-size: 14px; color: color-mix(in oklab, var(--n-0) 80%, transparent);
  font-weight: 600; letter-spacing: 0.5px;
}
.countdown-boxes { display: flex; gap: 8px; }
.countdown-box {
  display: flex; flex-direction: column; align-items: center;
  background: color-mix(in oklab, var(--n-0) 10%, transparent);
  border: 1px solid color-mix(in oklab, var(--n-0) 15%, transparent);
  border-radius: var(--r-2); padding: 10px 14px; min-width: 64px;
  backdrop-filter: blur(8px);
}
.countdown-box .cd-num {
  font-size: 28px; font-weight: 800; color: var(--n-0);
  line-height: 1; font-variant-numeric: tabular-nums;
}
.countdown-box .cd-label {
  font-size: 10px; color: color-mix(in oklab, var(--n-0) 75%, transparent);
  text-transform: uppercase;
  letter-spacing: 1px; margin-top: 4px;
}
.countdown-sep {
  font-size: 24px; font-weight: 700;
  color: color-mix(in oklab, var(--n-0) 75%, transparent);
  align-self: flex-start; margin-top: 10px;
}
.contest-meta-strip .hero-cta-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 12px 28px; border-radius: var(--r-2);
  background: var(--brand-spark); color: var(--n-0) !important;
  font-size: 15px; font-weight: 700; transition: all 150ms;
  text-decoration: none; min-height: 44px;
}
.contest-meta-strip .hero-cta-btn:hover { background: color-mix(in srgb, var(--brand-spark) 85%, var(--n-900)); transform: translateY(-2px); box-shadow: var(--shadow-2); color: var(--n-0); text-decoration: none; }
/* AC-1: Leaderboard navigation link */
.contest-meta-strip .hero-leaderboard-btn {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 12px 24px; border-radius: var(--r-2);
  background: color-mix(in oklab, var(--n-0) 12%, transparent);
  border: 1px solid color-mix(in oklab, var(--n-0) 50%, transparent);
  color: var(--n-0) !important; font-size: 14px; font-weight: 600;
  transition: all 150ms; min-height: 44px;
}
.contest-meta-strip .hero-leaderboard-btn:hover {
  background: color-mix(in oklab, var(--n-0) 20%, transparent);
  color: var(--n-0); text-decoration: none;
}
@media (prefers-reduced-motion: reduce) {
  .contest-meta-strip .hero-cta-btn,
  .contest-meta-strip .hero-leaderboard-btn { transition: none; }
  .contest-meta-strip .hero-cta-btn:hover { transform: none; }
}
@media (max-width: 768px) {
  .countdown-box { padding: 8px 10px; min-width: 52px; }
  .countdown-box .cd-num { font-size: 22px; }
}

/* M20 Phase 4 / slice 3b — WK-134 photo-placeholder gradient-contrast
   rules removed alongside the .contestant-photo[style*="gradient"]
   pattern they shimmed. The no-image fallback now uses a neutral
   .photo-placeholder treatment defined in the .contestant-photo
   block below. */

/* ============================================
   CONTESTANTS SECTION
   ============================================ */
.candidates-section { padding: 64px 0; background: var(--n-50); }
.candidates-header {
  display: flex; flex-direction: column; align-items: center;
  text-align: center; margin-bottom: 32px; gap: 16px;
}
.candidates-header h2 { font-size: 28px; font-weight: 800; color: var(--n-900); }
.candidates-filters {
  display: flex; justify-content: center; width: 100%;
}
.shortlink-display { display: flex; align-items: center; gap: 8px; background: var(--n-50); border-radius: var(--r-2); padding: 10px 14px; }
.shortlink-url { flex: 1; font-size: 14px; font-weight: 600; color: var(--brand-spark); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.shortlink-url--empty { color: var(--n-500); font-weight: 400; }
/* M31 Phase 11 F-11-3 — `.shortlink-copy` rule + hover promoted to
   elfrique.components.data.css so the candidate detail page (which
   also composes _ShortLinkDisplay.cshtml) inherits the styling. */
.filter-search {
  position: relative; width: 100%; max-width: 400px;
}
/* Design token: search pill pattern (shared with hero search bar) */
.filter-search-wrapper {
  display: flex; align-items: center;
  background: var(--n-0); border-radius: var(--pill-radius, 60px);
  box-shadow: var(--pill-shadow, 0 4px 24px rgba(0,0,0,0.10));
  padding: 6px 16px 6px 20px;
  height: 52px;
  transition: box-shadow 200ms;
}
.filter-search-wrapper:focus-within {
  box-shadow: var(--pill-shadow-focus, 0 4px 24px rgba(0,0,0,0.18));
}
.filter-search .search-icon {
  font-size: 18px; color: var(--n-500); margin-right: 12px; flex-shrink: 0;
}
.filter-search input {
  flex: 1; border: none; outline: none; background: transparent;
  font-size: 15px; color: var(--n-800); min-width: 0;
}
.filter-search input::placeholder { color: var(--n-500); }
.filter-search .search-clear {
  display: none; background: none; border: none; cursor: pointer;
  font-size: 18px; color: var(--n-500); padding: 4px 0 4px 8px;
  flex-shrink: 0; line-height: 1;
}
.filter-search .search-clear:hover { color: var(--n-600); }
.no-results-message {
  text-align: center; padding: 48px 24px; color: var(--neutral-500);
  font-size: 16px;
}
/* AC-3: Sort label */
.sort-label {
  font-size: 13px; font-weight: 600; color: var(--neutral-500);
  display: inline-flex; align-items: center; gap: 5px;
}
.sort-label i { font-size: 14px; }
/* AC-4: Pagination counter */
.candidates-counter {
  font-size: 13px; color: var(--neutral-500); text-align: center; margin-bottom: 16px;
}
/* ============================================
   G7: AWARD NOMINEE CATEGORY TABS
   ============================================ */
.nominee-category-tabs {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
  justify-content: center;
  margin-bottom: 32px;
}
.nominee-category-tab {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 24px;
  border-radius: 9999px;
  font-size: 15px;
  font-weight: 700;
  color: var(--n-700);
  background: var(--n-50);
  border: 2px solid var(--n-200);
  cursor: pointer;
  transition: all 200ms;
  white-space: nowrap;
  font-family: inherit;
}
.nominee-category-tab:hover {
  border-color: var(--brand-spark);
  color: var(--brand-ink);
  /* M20 Phase 4 / slice 4 — was a near-mint raw-hex wash.
     Tokenised: a low-opacity brand-spark wash on white. */
  background: color-mix(in oklab, var(--brand-spark) 8%, var(--n-0));
}
.nominee-category-tab.active,
.nominee-category-tab[aria-selected="true"] {
  background: var(--brand-ink);
  color: var(--n-0);
  border-color: var(--brand-ink);
}
.nominee-category-tab .tab-count {
  font-size: 12px;
  font-weight: 700;
  padding: 2px 8px;
  border-radius: 9999px;
  background: var(--n-200);
  color: var(--n-600);
}
.nominee-category-tab.active .tab-count,
.nominee-category-tab[aria-selected="true"] .tab-count {
  background: rgba(255,255,255,0.3);
  color: var(--n-0);
}
.nominee-category-tab:focus-visible {
  outline: 3px solid var(--brand-ink);
  outline-offset: 2px;
}
.nominee-category-empty {
  text-align: center;
  padding: 32px 24px;
  color: var(--n-500);
  font-size: 15px;
  background: var(--n-0);
  border-radius: var(--r-4);
  border: 1px dashed var(--n-200);
}
@media (max-width: 768px) {
  .nominee-category-tabs {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding: 0 4px 4px;
    gap: 8px;
  }
  .nominee-category-tabs::-webkit-scrollbar { display: none; }
  .nominee-category-tab {
    padding: 10px 18px;
    font-size: 14px;
  }
}
.candidates-grid {
  display: grid; grid-template-columns: repeat(4, 1fr); gap: 24px;
}
/* M20 Phase 4 / slice 3b — _ContestantCard now composes Kit/_ContentCard
   (BlurredBg=true) which provides the card chrome (background, border,
   border-radius, shadow, hover-lift). The outer .contestant-card is a
   thin position-relative wrapper used to layer the rank badge, results
   row, progress bar, and View Profile affordance over the kit card.

   Background / border-radius / overflow / shadow / hover-lift were
   removed here to avoid double-card visual nesting with the inner
   .content-card. The kit owns those tokens. */
.contestant-card {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
}
/* No-image fallback — the .contestant-photo + .contestant-info block
   is rendered by _ContestantCard.cshtml only when ImageUrl is empty.
   It re-introduces card chrome locally (since the kit isn't used on
   this branch) so the no-image card visually matches the with-image
   card silhouette. */
.contestant-card:has(.contestant-photo) {
  background: var(--n-0);
  border-radius: var(--r-4);
  overflow: hidden;
  box-shadow: var(--shadow-1);
  transition: transform var(--d-2) var(--ease-out-swift),
              box-shadow var(--d-2) var(--ease-out-swift);
}
.contestant-card:has(.contestant-photo):hover {
  transform: translateY(-4px);
  box-shadow: var(--shadow-3);
}
/* padding-top shifts the absolute .photo-img down via padding-box inset */
.contestant-photo {
  height: 240px; position: relative; display: flex;
  align-items: flex-end; justify-content: center; overflow: hidden;
  padding: 16px 0 0;
  background: var(--n-100);
}
.contestant-photo .photo-placeholder {
  position: absolute; inset: 0; display: flex; align-items: center;
  justify-content: center; font-size: 64px; font-weight: 700;
  color: var(--n-500);
}
.contestant-number {
  position: absolute; bottom: 12px; left: 12px;
  background: rgba(0,0,0,0.65); color: var(--n-0);
  padding: 3px 8px; border-radius: var(--r-2);
  font-size: 11px; font-weight: 600; backdrop-filter: blur(4px);
  letter-spacing: 0.5px;
}
.contestant-rank {
  position: absolute; top: 12px; right: 12px;
  padding: 4px 10px; border-radius: 9999px;
  font-size: 11px; font-weight: 800; color: var(--n-0);
  backdrop-filter: blur(4px);
  /* Layer above the kit ContentCard's media + body so the rank stays
     visible on with-image cards. M20 Phase 4 / slice 3b. */
  z-index: 2;
}
/* M20 Phase 4 / slice 4 — gold/bronze tinted via color-mix on brand/state
   tokens. Matches the leaderboard podium-tint pattern used at L583-591. */
.rank-gold   { background: color-mix(in oklab, var(--brand-spark) 80%, var(--n-900)); }
.rank-silver { background: var(--n-600); }
.rank-bronze { background: color-mix(in oklab, var(--state-warn) 70%, var(--n-900)); }
.rank-default { background: var(--n-200); color: var(--n-900) !important; }
.contestant-info { padding: 16px; }
.contestant-name { font-size: 16px; font-weight: 700; color: var(--n-900); margin-bottom: 2px; }
.contestant-state { font-size: 13px; color: var(--n-500); margin-bottom: 10px; }
/* M20 Phase 4 / slice 3b — new BEM aliases for the contestant-card
   outer-wrapper overlays. Legacy class names (.contestant-votes,
   .contestant-pct, .vote-progress, .vote-progress-fill) are retained
   in the markup as JS-binding hooks alongside the BEM names. */
.contestant-card__results {
  display: flex; align-items: center; justify-content: space-between;
  gap: var(--sp-2);
  padding: 0 var(--sp-3);
}
.contestant-votes,
.contestant-card__votes { font-size: 15px; font-weight: 800; color: var(--brand-ink); }
.contestant-pct,
.contestant-card__pct { font-size: 12px; font-weight: 600; color: var(--n-500); }
.vote-progress,
.contestant-card__progress {
  height: 6px; background: var(--n-100); border-radius: 9999px;
  overflow: hidden;
  margin: 0 var(--sp-3);
}
.vote-progress-fill,
.contestant-card__progress-fill {
  height: 100%; border-radius: 9999px;
  background: linear-gradient(90deg, var(--brand-ink), var(--brand-spark));
  transition: width var(--d-4) var(--ease-out-swift);
}
/* No-image fallback path keeps the prior margin-below behavior so
   the legacy .contestant-info block visually closes off the card. */
.contestant-card:has(.contestant-photo) .vote-progress {
  margin-bottom: var(--sp-3);
}
.vote-now-btn {
  width: 100%; padding: 10px; border-radius: var(--r-2);
  background: var(--brand-spark); color: var(--n-0); font-size: 14px;
  font-weight: 700; display: flex; align-items: center; justify-content: center;
  gap: 6px; transition: all var(--d-2) var(--ease-out-swift);
  min-height: 44px;
}
.vote-now-btn:hover { background: color-mix(in srgb, var(--brand-spark) 85%, var(--n-900)); transform: translateY(-1px); box-shadow: var(--shadow-2); }
@media (max-width: 1024px) {
  .candidates-grid { grid-template-columns: repeat(3, 1fr); }
}
@media (max-width: 768px) {
  .candidates-section { padding: 40px 0; }
  .candidates-grid { grid-template-columns: repeat(2, 1fr); gap: 14px; }
  .contestant-photo { height: 180px; }
  .filter-search { max-width: 100%; }
  .candidates-filters { width: 100%; }
}
@media (max-width: 420px) {
  .candidates-grid { gap: 10px; }
  .contestant-info { padding: 12px; }
  .contestant-name { font-size: 14px; }
}

/* AC-4: Pagination controls */
.pagination-wrap {
  display: flex; flex-direction: column; align-items: center; gap: 14px;
  margin-top: 32px;
}
.pagination-controls {
  display: flex; align-items: center; gap: 6px; flex-wrap: wrap; justify-content: center;
}
.pg-btn {
  min-width: 38px; height: 38px; padding: 0 10px; border-radius: var(--r-2);
  border: 1.5px solid var(--n-200); background: var(--n-0);
  font-size: 14px; font-weight: 600; color: var(--n-600);
  cursor: pointer; transition: all 150ms; display: inline-flex;
  align-items: center; justify-content: center;
}
.pg-btn:hover:not(:disabled) { border-color: var(--brand-ink); color: var(--brand-ink); }
.pg-btn.active { background: var(--brand-ink); border-color: var(--brand-ink); color: var(--n-0); }
.pg-btn:disabled { opacity: 0.4; cursor: default; }
.pg-ellipsis { font-size: 14px; color: var(--n-500); padding: 0 4px; }
@media (max-width: 420px) {
  .pg-btn { min-width: 32px; height: 32px; font-size: 13px; }
}

/* Contest description block */
.contest-description {
  background: linear-gradient(135deg, var(--brand-ink) 0%, var(--n-900) 100%);
  padding: 24px 0;
  text-align: center;
}
.contest-description p {
  max-width: 800px; margin: 0 auto;
  font-size: 15px; line-height: 1.6;
  color: color-mix(in oklab, var(--n-0) 85%, transparent);
  padding: 0 16px;
}

/* AC-2: Top 3 performers strip */
.top3-strip {
  background: linear-gradient(135deg, var(--brand-ink) 0%, color-mix(in oklab, var(--brand-ink) 80%, var(--n-900)) 60%, var(--n-900) 100%);
  padding: 28px 0;
}
.top3-strip .container { display: flex; flex-direction: row; align-items: center; justify-content: center; gap: 40px; flex-wrap: wrap; }
.top3-block {
  flex: 0 1 auto; min-width: 340px;
  background: color-mix(in oklab, var(--n-0) 10%, transparent);
  border: 1px solid color-mix(in oklab, var(--n-0) 15%, transparent);
  border-radius: var(--r-4); padding: 24px;
}
.top3-cards { display: flex; gap: 16px; justify-content: flex-start; flex-wrap: nowrap; }
/* M31 Phase 3 F-3-1/F-3-2 — legacy .share-block + .share-block @media rules
   (formerly the share-card sizing for .top3-strip pre-M23 consolidation)
   are deleted. The current .share-block lives at _VotingHeroBelowSlot.cshtml
   inside .hero__below-content; styling moved to elfrique.components.layout.css
   §M31 Phase 3 (flex-column composition + ghost share buttons + passive QR).
   The .top3-strip wrapper still exists for the Top Performers section but no
   longer composes a share-block sibling. */
@media (max-width: 900px) {
  .top3-strip .container { gap: 24px; }
  .top3-block { min-width: 280px; }
  .top3-cards { flex-wrap: wrap; }
}
@media (max-width: 700px) {
  .top3-block { flex: 1 1 100%; }
  .top3-cards { justify-content: center; flex-wrap: wrap; }
}
.top3-strip-heading {
  font-size: 14px; font-weight: 700; text-transform: uppercase;
  letter-spacing: 1px; color: color-mix(in oklab, var(--n-0) 80%, transparent);
  text-align: center; display: block; margin-bottom: 16px;
}
.top3-card {
  display: flex; flex-direction: column; align-items: center; gap: 6px;
  background: color-mix(in oklab, var(--n-0) 8%, transparent);
  border: 1px solid color-mix(in oklab, var(--n-0) 15%, transparent);
  border-radius: var(--r-4); padding: 20px 28px; min-width: 140px;
  transition: background 150ms;
}
.top3-card:hover { background: color-mix(in oklab, var(--n-0) 13%, transparent); }
.top3-rank-badge {
  width: 28px; height: 28px; border-radius: 50%; display: flex;
  align-items: center; justify-content: center; font-size: 12px;
  font-weight: 800; color: var(--n-0);
}
/* Token-driven podium tints — match the leaderboard podium-tint scheme
   (L583-591) so gold/silver/bronze read across views without raw hex. */
.top3-rank-badge.gold { background: linear-gradient(135deg, var(--brand-spark), color-mix(in oklab, var(--brand-spark) 70%, var(--n-900))); }
.top3-rank-badge.silver { background: linear-gradient(135deg, var(--n-300), var(--n-500)); }
.top3-rank-badge.bronze { background: linear-gradient(135deg, var(--state-warn), color-mix(in oklab, var(--state-warn) 70%, var(--n-900))); }
.top3-avatar {
  width: 56px; height: 56px; border-radius: 50%; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  font-size: 22px; font-weight: 700; color: var(--n-0);
  border: 2px solid color-mix(in oklab, var(--n-0) 25%, transparent);
}
.top3-avatar img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Token-only initials fallback used when the avatar img errors. Default
   display:none; the inline onerror flips it to flex. Replaces the prior
   raw-hex inline style= block to satisfy hard rule #2. */
.top3-avatar__initials-fallback {
  display: none; width: 100%; height: 100%;
  align-items: center; justify-content: center;
  font-size: 22px; font-weight: 700; color: var(--n-0);
}
.top3-name { font-size: 14px; font-weight: 700; color: var(--n-0); text-align: center; max-width: 120px; }
.top3-votes { font-size: 13px; font-weight: 800; color: color-mix(in oklab, var(--n-0) 80%, transparent); }
/* Dark-context overrides for shortlink display */
.top3-strip .shortlink-display { background: color-mix(in oklab, var(--n-0) 8%, transparent); border: 1px solid color-mix(in oklab, var(--n-0) 15%, transparent); margin-top: 12px; }
.top3-strip .shortlink-url { color: var(--n-0); }
.top3-strip .shortlink-url--empty { color: color-mix(in oklab, var(--n-0) 75%, transparent); }
.top3-strip .shortlink-copy { background: color-mix(in oklab, var(--n-0) 20%, transparent); color: var(--n-0); }
.top3-strip .shortlink-copy:hover { background: color-mix(in oklab, var(--n-0) 30%, transparent); }
/* M31 Phase 3 F-3-2 — .qr-toggle-btn rules deleted (toggle button itself
   removed from the markup; QR renders passively). The dark-bg .share-left
   h3 / .share-subtext color rules are also relocated to the kit CSS file's
   M31 Phase 3 §share-block section (covered there for both standalone
   dark .contest-meta-strip and .hero__below-content cascade). */
/* M23 Phase 5 FixCycle-2 (countdown-chip in-hero remap) + qr-collapse
   toggle rules PROMOTED to elfrique.components.layout.css §M31 Phase 3
   (F-3-7 contrast fix uses 90%/80% mix for AA contrast vs. the prior
   75% mix; F-3-2 deletes the toggle entirely so .qr-collapse open/hide
   state is no longer needed). The .hero__below-content .countdown-box
   background/border-color ramp below stays here since it covers the
   remaining countdown chrome (chip surface) untouched by F-3-7. */
.hero__below-content .countdown-box {
  background: color-mix(in oklab, var(--brand-ink) 8%, transparent);
  border-color: color-mix(in oklab, var(--brand-ink) 15%, transparent);
}
@media (max-width: 600px) {
  .top3-cards { gap: 10px; }
  .top3-card { padding: 14px 16px; min-width: 100px; }
}

/* ============================================
   LEADERBOARD SECTION
   ============================================ */
.leaderboard-section { padding: 64px 0; background: var(--n-0); }
.leaderboard-header {
  text-align: center; margin-bottom: 40px;
}
.leaderboard-header h2 { font-size: 28px; font-weight: 800; color: var(--n-900); margin-bottom: 6px; }
.leaderboard-header p { font-size: 14px; color: var(--n-500); }
.leaderboard-header p span {
  display: inline-block; width: 8px; height: 8px; border-radius: 50%;
  /* M20 Phase 4 / slice 4 — pulse-dot was a green raw hex. Green is banned
     per CLAUDE.md hard rule #1; --state-success is teal and signals "live". */
  background: var(--state-success); margin-right: 6px; animation: pulse-dot 1.5s ease-in-out infinite;
}
/* Podium */
.podium { display: flex; align-items: flex-end; justify-content: center; gap: 16px; margin-bottom: 48px; }
.podium-item {
  display: flex; flex-direction: column; align-items: center;
  border-radius: var(--r-4) var(--r-4) 0 0;
  padding: 24px 20px; position: relative; min-width: 180px;
}
/* Podium block tints — gradients tokenised against the same brand-spark /
   n-300 / state-warn palette used for the rank badges above. The 18%/30%
   mixes keep the surface light enough that the dark .podium-name + .podium-votes
   text retain WCAG AA contrast. */
.podium-1 { background: linear-gradient(180deg, color-mix(in oklab, var(--brand-spark) 18%, var(--n-0)), color-mix(in oklab, var(--brand-spark) 35%, var(--n-0))); min-height: 240px; order: 2; }
.podium-2 { background: linear-gradient(180deg, var(--n-100), var(--n-300)); min-height: 200px; order: 1; }
.podium-3 { background: linear-gradient(180deg, color-mix(in oklab, var(--state-warn) 12%, var(--n-0)), color-mix(in oklab, var(--state-warn) 30%, var(--n-0))); min-height: 170px; order: 3; }
.podium-avatar {
  width: 72px; height: 72px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 32px; margin-bottom: 10px; border: 3px solid var(--n-0);
  box-shadow: var(--shadow-2);
}
.podium-1 .podium-avatar { width: 84px; height: 84px; font-size: 36px; }
.podium-crown {
  position: absolute; top: -10px; font-size: 28px;
}
.podium-name { font-size: 15px; font-weight: 700; color: var(--n-900); margin-bottom: 2px; text-align: center; }
.podium-state-label { font-size: 12px; color: var(--n-600); margin-bottom: 8px; }
.podium-votes { font-size: 18px; font-weight: 800; color: var(--brand-ink); }
.podium-rank-label {
  width: 28px; height: 28px; border-radius: 50%; display: flex;
  align-items: center; justify-content: center; font-size: 13px;
  font-weight: 800; color: var(--n-0); margin-bottom: 8px;
}
/* Same gold/silver/bronze tokenisation as .top3-rank-badge above. */
.podium-1 .podium-rank-label { background: linear-gradient(135deg, var(--brand-spark), color-mix(in oklab, var(--brand-spark) 70%, var(--n-900))); }
.podium-2 .podium-rank-label { background: linear-gradient(135deg, var(--n-300), var(--n-500)); }
.podium-3 .podium-rank-label { background: linear-gradient(135deg, var(--state-warn), color-mix(in oklab, var(--state-warn) 70%, var(--n-900))); }
@media (max-width: 768px) {
  .podium { gap: 8px; }
  .podium-item { min-width: 100px; padding: 16px 12px; }
  .podium-avatar { width: 56px; height: 56px; font-size: 24px; }
  .podium-1 .podium-avatar { width: 64px; height: 64px; font-size: 28px; }
  .podium-name { font-size: 13px; }
  .podium-votes { font-size: 15px; }
  .podium-crown { font-size: 22px; top: -6px; }
}
/* Leaderboard table — M20 Phase 4 slice 3c.
   Two leaderboard sub-views (default `viewGraph` and `viewNumerical`) render via
   _DataTable. Cell-content classes (.lb-rank/.lb-votes/.lb-pct/.lb-name/.lb-state)
   remain so the live-results polling JS at ~L2330 keeps its selectors. The
   _DataTable partial owns its own border / hover / responsive cards-mode CSS, so
   the legacy .lb-table* table-styling rules are no longer needed and have been
   deleted. .lb-table-wrap is retained as the desktop/mobile breakpoint shell that
   hides the table at <769px and shows .lb-mobile-cards instead. */
.lb-table-wrap { overflow-x: auto; }

/* Podium tints (top-3 rows). Per-row class is unsupported by _DataTable, so
   :nth-child(1/2/3) targets the rendered rows. The leaderboard is server-sorted
   by VoteCount desc, so positional selectors are stable. Tints use color-mix on
   brand/state/neutral tokens to keep the gold/silver/bronze read without raw hex.
   Scoped under .lb-podium-tint so only the leaderboard tables receive it. */
.lb-podium-tint .data-table__tbody .data-table__row:nth-child(1) {
  background: color-mix(in oklab, var(--brand-spark) 12%, var(--n-0));
}
.lb-podium-tint .data-table__tbody .data-table__row:nth-child(2) {
  background: color-mix(in oklab, var(--n-300) 30%, var(--n-0));
}
.lb-podium-tint .data-table__tbody .data-table__row:nth-child(3) {
  background: color-mix(in oklab, var(--state-warn) 12%, var(--n-0));
}

/* Candidate cell — avatar + name composed inside one DataTable cell. Token-driven
   initials avatar mirrors .entity-cell__avatar--initials (shared pattern). When a
   contestant has ImageUrl, an <img> is rendered inside the same shell. */
.lb-cand {
  display: inline-flex; align-items: center; gap: 12px;
}
.lb-cand__avatar {
  display: inline-flex; align-items: center; justify-content: center;
  width: 36px; height: 36px; border-radius: 50%;
  overflow: hidden; flex: 0 0 auto;
  background-color: var(--n-100);
  border: 1px solid var(--n-200);
}
.lb-cand__avatar--initials { color: var(--brand-ink); }
.lb-cand__avatar-img {
  display: block; width: 100%; height: 100%; object-fit: cover;
}
.lb-cand__initials {
  font-family: var(--font-mono);
  font-size: 13px; font-weight: 600;
  letter-spacing: 0.04em; line-height: 1; text-transform: uppercase;
  color: var(--brand-ink);
}
.lb-cand__name { font-weight: 700; color: var(--n-900); }

.lb-rank { font-weight: 800; color: var(--n-900); }
.lb-name { font-weight: 700; color: var(--n-900); }
.lb-state { font-size: 12px; color: var(--n-500); }
.lb-votes { font-weight: 800; color: var(--brand-ink); }
.lb-votes--lg { font-size: 18px; }
.lb-pct { color: var(--n-600); }
.lb-trend-same { color: var(--n-500); }
.lb-diff { color: var(--n-700); }
.lb-diff--down { color: var(--state-danger); }
.lb-empty { text-align: center; color: var(--n-500); padding: 32px 0; }

@media (max-width: 768px) {
  .lb-table-wrap { display: none; }
  .lb-mobile-cards { display: block !important; }
}
.lb-mobile-cards { display: none; }
.lb-mobile-card {
  display: flex; align-items: center; gap: 12px; padding: 14px 16px;
  border-bottom: 1px solid var(--n-100);
}
/* Mobile podium tints — replace inline `style="background:#…"` raw-hex literals
   with token-mixed surfaces matching the desktop :nth-child rules above. */
.lb-mobile-card--gold {
  background: color-mix(in oklab, var(--brand-spark) 12%, var(--n-0));
}
.lb-mobile-card--silver {
  background: color-mix(in oklab, var(--n-300) 30%, var(--n-0));
}
.lb-mobile-card--bronze {
  background: color-mix(in oklab, var(--state-warn) 12%, var(--n-0));
}
.lb-mobile-rank {
  width: 32px; height: 32px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 13px; font-weight: 800; flex-shrink: 0;
  color: var(--n-0);
}
.lb-mobile-info { flex: 1; }
.lb-mobile-info .lb-name { font-size: 14px; }
.lb-mobile-info .lb-state { font-size: 12px; }
.lb-mobile-right { text-align: right; }
.lb-mobile-right .lb-votes { font-size: 14px; display: block; }
.lb-mobile-right .lb-pct { font-size: 12px; }

/* ============================================
   RESULTS DISPLAY TOGGLE
   ============================================ */
.results-toggle-row {
  display: flex; align-items: center; justify-content: center;
  flex-wrap: wrap; gap: 12px; margin-bottom: 24px;
}
.results-toggle-group {
  display: flex; align-items: center; gap: 8px;
}
.results-toggle-label {
  font-size: 13px; font-weight: 600; color: var(--n-600);
}
.results-toggle-btns {
  display: flex; gap: 4px; background: var(--n-100);
  border-radius: var(--r-2); padding: 4px;
}
.results-toggle-btn {
  padding: 8px 16px; border-radius: var(--radius-xs, 4px);
  font-size: 13px; font-weight: 700; color: var(--n-600);
  cursor: pointer; transition: all 150ms; white-space: nowrap;
}
.results-toggle-btn:hover { color: var(--n-900); }
.results-toggle-btn.active {
  background: var(--n-0); color: var(--brand-ink);
  box-shadow: 0 1px 3px rgba(0,0,0,0.1);
}
.results-organiser-note {
  font-size: 12px; color: var(--n-500); font-style: italic;
}
.results-view { display: none; }
.results-view.active { display: block; }
/* Bar chart view */
.results-bar-chart { display: none; }
.results-bar-chart.active { display: block; }
.bar-chart-item {
  display: flex; align-items: center; gap: 12px; margin-bottom: 12px;
}
.bar-chart-rank {
  width: 28px; font-size: 14px; font-weight: 800; color: var(--n-900);
  text-align: center; flex-shrink: 0;
}
.bar-chart-avatar {
  width: 36px; height: 36px; border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  font-size: 16px; flex-shrink: 0;
}
.bar-chart-info { flex: 1; min-width: 0; }
.bar-chart-name { font-size: 14px; font-weight: 700; color: var(--n-900); }
.bar-chart-bar-wrap {
  height: 24px; background: var(--n-100); border-radius: 12px;
  overflow: hidden; margin-top: 4px;
}
.bar-chart-bar {
  height: 100%; border-radius: 12px;
  /* M20 Phase 4 / slice 4 — gradient tokenised; previously fell through to
     a green raw hex (banned by hard rule #1). Now uses brand-spark as the
     warm-end stop, matching the .vote-progress-fill rule above. */
  background: linear-gradient(90deg, var(--brand-ink), var(--brand-spark));
  display: flex; align-items: center; justify-content: flex-end;
  padding-right: 8px; min-width: 40px; transition: width 600ms ease;
}
.bar-chart-bar span {
  font-size: 11px; font-weight: 800; color: var(--n-0);
}
.bar-chart-votes {
  width: 80px; text-align: right; font-size: 13px; font-weight: 700;
  color: var(--n-600); flex-shrink: 0;
}
/* Percentage view */
.results-percentage { display: none; }
.results-percentage.active { display: block; }
.pct-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 16px;
}
.pct-card {
  background: var(--n-50); border-radius: var(--r-2);
  padding: 20px; text-align: center; border: 1px solid var(--n-200);
}
.pct-avatar-sm {
  width: 48px; height: 48px; border-radius: 50%; margin: 0 auto 8px;
  display: flex; align-items: center; justify-content: center; font-size: 22px;
}
.pct-name { font-size: 14px; font-weight: 700; color: var(--n-900); margin-bottom: 4px; }
.pct-value {
  font-size: 28px; font-weight: 800; color: var(--brand-ink); margin-bottom: 2px;
}
.pct-votes { font-size: 12px; color: var(--n-500); }
/* Numerical view */
.results-numerical { display: none; }
.results-numerical.active { display: block; }
@media (max-width: 768px) {
  .results-toggle-row { flex-direction: column; align-items: flex-start; }
  .results-toggle-btns { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  .pct-grid { grid-template-columns: repeat(2, 1fr); }
}


/* M31 Phase 3 — SHARE & QR rules PROMOTED to
   elfrique.components.layout.css §M31 Phase 3:
     F-3-1 share-block / share-buttons / share-btn now ghost
             (per-network bg removed; ring-outline + cursor + hover
             reside in the kit CSS file).
     F-3-2 .qr-placeholder removed (passive QR uses .share-qr +
             .share-qr__image classes; no more dashed placeholder).
   The .share-section .shortlink-display margin rule is also relocated
   (no longer needed after F-3-2 since the QR + shortlink share a
   parent flex container with its own gap). */


/* ============================================
   MOBILE STICKY VOTE BAR
   ============================================ */
.mobile-vote-bar {
  display: none; position: fixed; bottom: 60px; left: 0; right: 0;
  background: var(--n-0); border-top: 1px solid var(--n-200);
  padding: 10px 16px; z-index: 1500; box-shadow: 0 -2px 12px rgba(0,0,0,0.08);
}
.mobile-vote-bar-inner {
  display: flex; align-items: center; justify-content: space-between; gap: 12px;
}
.mobile-vote-bar .mvb-info { font-size: 13px; color: var(--n-600); }
.mobile-vote-bar .mvb-info strong { color: var(--n-900); }
.mobile-vote-bar .mvb-btn {
  padding: 10px 28px; border-radius: var(--r-2); background: var(--brand-spark);
  color: var(--n-0); font-weight: 700; font-size: 14px; cursor: pointer;
  white-space: nowrap;
}
@media (max-width: 768px) {
  .mobile-vote-bar { display: block; }
  body { padding-bottom: 130px; }
}

/* ============================================
   CONTESTANT DETAIL MODAL
   ============================================ */
.contestant-modal-overlay {
  position: fixed; top: 0; left: 0; width: 100%; height: 100%;
  background: rgba(0,0,0,0.6); z-index: 2000; display: flex;
  align-items: center; justify-content: center;
  opacity: 0; visibility: hidden; transition: opacity 300ms, visibility 300ms;
  padding: 24px;
}
.contestant-modal-overlay.active { opacity: 1; visibility: visible; }
.contestant-modal {
  background: var(--n-0); border-radius: var(--r-4);
  max-width: 480px; width: 100%; max-height: calc(100vh - 48px);
  display: flex; flex-direction: column; overflow: hidden;
  box-shadow: var(--shadow-3); position: relative;
}
/* F3: hero takes remaining vertical space; image scales to fit — no inner scroll */
.contestant-modal-hero {
  flex: 1 1 0;
  min-height: 0;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--n-50);
  border-top-left-radius: var(--r-4); border-top-right-radius: var(--r-4);
}
.contestant-modal-hero:empty { display: none; }
.contestant-modal-hero img {
  width: 100%;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}
.contestant-modal-body {
  overflow: hidden;
  flex: 0 0 auto;
  padding: 20px 24px;
}
.contestant-modal-header {
  flex: 0 0 auto;
  display: flex; align-items: center; gap: 16px; padding: 24px 24px 16px;
  border-bottom: 1px solid var(--n-100);
}
.contestant-modal-avatar {
  width: 64px; height: 64px; border-radius: 50%; object-fit: cover;
  flex-shrink: 0;
}
.contestant-modal-avatar-placeholder {
  width: 64px; height: 64px; border-radius: 50%; display: flex;
  align-items: center; justify-content: center; font-size: 22px;
  font-weight: 700; color: var(--n-0); flex-shrink: 0;
}
.contestant-modal-info h3 { font-size: 20px; font-weight: 700; color: var(--n-900); margin: 0; }
.contestant-modal-info .modal-subtitle { font-size: 14px; color: var(--neutral-500); margin-top: 2px; }
.contestant-modal-info .modal-rank { font-size: 13px; font-weight: 600; color: var(--brand-spark); margin-top: 4px; }
.contestant-modal-close {
  position: absolute; top: 16px; right: 16px; background: none; border: none;
  font-size: 24px; color: var(--n-500); cursor: pointer; line-height: 1;
  padding: 4px;
}
.contestant-modal-close:hover { color: var(--n-700); }
.contestant-modal-bio { font-size: 14px; color: var(--n-700); line-height: 1.6; margin-bottom: 20px; }
.contestant-modal-bio:empty { display: none; }
.contestant-modal-stats {
  display: flex; gap: 24px; margin-bottom: 20px; padding: 16px;
  background: var(--n-50); border-radius: var(--r-3);
}
.contestant-modal-stat { text-align: center; flex: 1; }
.contestant-modal-stat .stat-value { font-size: 20px; font-weight: 700; color: var(--n-900); }
.contestant-modal-stat .stat-label { font-size: 12px; color: var(--neutral-500); text-transform: uppercase; letter-spacing: 0.3px; }
.contestant-modal-share { margin-top: 4px; }
.contestant-modal-share h4 { font-size: 14px; font-weight: 600; color: var(--n-900); margin-bottom: 12px; }
.contestant-modal-qr { text-align: center; margin-bottom: 16px; }
.contestant-modal-qr img { width: 120px; height: 120px; border-radius: var(--r-2); display: block; margin: 0 auto; }
.contestant-modal-qr .qr-placeholder {
  width: 120px; height: 120px; display: inline-flex; align-items: center;
  justify-content: center; background: var(--n-100); border-radius: var(--r-2);
  color: var(--n-500); font-size: 13px;
}
.contestant-modal-footer {
  flex: 0 0 auto;
  padding: 16px 24px; border-top: 1px solid var(--n-100);
  text-align: center;
}
.contestant-modal-footer a {
  font-size: 14px; font-weight: 600; color: var(--brand-spark);
  text-decoration: none;
}
.contestant-modal-footer a:hover { text-decoration: underline; }
@media (max-width: 768px) {
  .contestant-modal { max-width: 100%; margin: 0; }
  .contestant-modal-stats { flex-direction: column; gap: 12px; }
}

/* M20 Phase 4 / slice 4 — the AUTH MODALS block (.modal-overlay, .modal,
   .modal-header, .modal-close, .modal-body, .social-auth*, .divider,
   .modal-switch, .terms-check, .ad-banner-hero) was deleted. None of those
   classes were rendered by this view at any point in slices 3a-3c; the
   block was carried over from a pre-refresh login-prompt design that never
   shipped on the voting contest page. The Razor markup below uses the
   contestant detail modal (.contestant-modal* — different prefix, distinct
   rule set above) and the kit Drawer for the vote flow, neither of which
   touches these selectors. */

/* WK-142: override any stale active-link styling in footer/nav that bleeds onto voting page */
footer a.active, .site-footer a.active,
.public-footer a.active, .footer-links a.active {
  color: inherit !important;
  font-weight: inherit !important;
  border-bottom: none !important;
}

.contestant-profile-link {
    display: block; text-align: center; margin-top: 10px; padding: 8px 16px;
    font-size: 13px; font-weight: 600; color: var(--brand-spark);
    border: 1.5px solid var(--brand-spark); border-radius: var(--r-2);
    text-decoration: none; transition: all 200ms;
}
.contestant-profile-link:hover {
    background: var(--brand-spark); color: var(--n-0);
}

/* Reduced-motion users: strip width-transition animation on the live-results
   bar chart + progress fill so the 5s poll does not drive visible motion. */
@media (prefers-reduced-motion: reduce) {
    .bar-chart-bar,
    .vote-progress-fill {
        transition: none;
    }
}

/* ── SSO button row (M49 Phase 2b · D-2b-09) ───────────────────────────────
   Signup + Login "Continue with Google" / "Continue with Facebook" pair.
   Tokens-only: no raw hex (HR2 — the trademark colors live in elfrique.css
   under the --logo-* carve-out), no raw ms (HR3), no inline style (HR4).
   Touch target floor: min-height 44px via .btn--md (HR8).
   Demo row on /design/kit (HR9); prefers-reduced-motion fallback below.
*/

.sso-button-row {
  display:         flex;
  flex-direction:  column;
  gap:             var(--sp-2);
  margin-bottom:   var(--sp-3);
}

.sso-form {
  display:         block;
  margin:          0;
}

.btn--sso {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  gap:             var(--sp-2);
  width:           100%;
  min-height:      44px;
  padding:         var(--sp-2) var(--sp-3);
  background:      var(--n-0);
  border:          1px solid var(--n-300);
  border-radius:   var(--r-2);
  color:           var(--n-900);
  font-family:     var(--font-sans);
  font-size:       var(--fs-2);
  font-weight:     600;
  cursor:          pointer;
  transition:      background-color var(--d-1) var(--ease-out-swift),
                   border-color     var(--d-1) var(--ease-out-swift),
                   box-shadow       var(--d-1) var(--ease-out-swift);
}

.btn--sso:hover {
  background:      var(--n-50);
  border-color:    var(--n-400);
  box-shadow:      var(--shadow-1);
}

.btn--sso:focus-visible {
  outline:         3px solid var(--state-info);
  outline-offset:  2px;
}

.btn--sso__logo {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  flex-shrink:     0;
  width:           20px;
  height:          20px;
}

.btn--sso__label {
  display:         inline-block;
  line-height:     1.2;
}

/* Per-provider logo color via the --logo-* namespace (D-2b-09 carve-out).
   The inline SVG uses fill="currentColor", and `color` flows through to
   the logo glyph only (the label inherits .btn--sso's --n-900 text). */
.btn--sso-google .btn--sso__logo {
  color:           var(--logo-google-red);
}

.btn--sso-facebook .btn--sso__logo {
  color:           var(--logo-facebook-blue);
}

.sso-divider {
  display:         flex;
  align-items:     center;
  gap:             var(--sp-2);
  margin:          var(--sp-3) 0;
  font-size:       var(--fs-1);
  color:           var(--n-600);
  text-align:      center;
}

.sso-divider::before,
.sso-divider::after {
  content:         "";
  flex:            1;
  height:          1px;
  background:      var(--n-200);
}

.sso-divider > span {
  flex-shrink:     0;
  padding:         0 var(--sp-1);
}

@media (prefers-reduced-motion: reduce) {
  .btn--sso {
    transition: none;
  }
}

/* ==========================================================================
   FORM DETAIL — Public form registration page (M50 Phase 4a)
   Consumed by: Views/Public/FormDetail.cshtml + drawer body partial
                Views/Shared/_FormRegistrationDrawerBody.cshtml.
   Modelled on the .event-detail__* / .tour-detail__* BEM precedent;
   all colors / spacing / motion via tokens (no raw hex / ms).
   ========================================================================== */

.form-detail {
  background-color: var(--n-50);
  padding:          var(--sp-5) 0 var(--sp-7);
}

.form-detail__container {
  width:        100%;
  max-width:    var(--container-max, 1280px);
  margin:       0 auto;
  padding:      0 var(--sp-4);
}

.form-detail__strip {
  margin-bottom: var(--sp-5);
}

/* Primary CTA block — opens the registration drawer */
.form-detail__cta-wrap {
  display:        flex;
  flex-direction: column;
  align-items:    flex-start;
  gap:            var(--sp-2);
  margin-bottom:  var(--sp-6);
}

.form-detail__cta {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  gap:              var(--sp-2);
  min-height:       48px;
  min-width:        220px;
  padding:          var(--sp-3) var(--sp-5);
  background-color: var(--brand-spark);
  color:            var(--n-0);
  border:           none;
  border-radius:    var(--r-2);
  font-family:      var(--font-sans);
  font-size:        var(--fs-3);
  font-weight:      700;
  cursor:           pointer;
  transition:       background-color var(--d-2) var(--ease-out-swift),
                    box-shadow      var(--d-2) var(--ease-out-swift),
                    transform       var(--d-2) var(--ease-out-swift);
}

.form-detail__cta:hover,
.form-detail__cta:focus-visible {
  background-color: color-mix(in oklab, var(--brand-spark) 88%, var(--n-900));
  box-shadow:       var(--shadow-2);
  transform:        translateY(-1px);
}

.form-detail__cta:focus-visible {
  outline:        2px solid var(--brand-ink);
  outline-offset: 2px;
}

.form-detail__cta-note {
  display:      inline-flex;
  align-items:  center;
  gap:          var(--sp-1);
  margin:       0;
  font-size:    var(--fs-1);
  color:        var(--n-600);
}

/* 2-column body layout — matches .event-detail__layout precedent */
.form-detail__layout {
  display:               grid;
  grid-template-columns: 1fr 360px;
  gap:                   var(--sp-7);
  align-items:           start;
}

@media (max-width: 991px) {
  .form-detail__layout {
    grid-template-columns: 1fr;
  }
}

.form-detail__main {
  min-width: 0;
}

.form-detail__section {
  margin-bottom: var(--sp-7);
}

.form-detail__section-title {
  font-family:    var(--font-serif);
  font-size:      var(--fs-5);
  font-weight:    600;
  color:          var(--n-900);
  margin:         0 0 var(--sp-4);
  letter-spacing: -0.01em;
}

.form-detail__prose p {
  margin:      0 0 var(--sp-3);
  font-size:   var(--fs-2);
  line-height: 1.7;
  color:       var(--n-700);
}

/* Agenda list */
.form-detail__agenda {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    flex;
  flex-direction: column;
  gap:        var(--sp-3);
}

.form-detail__agenda-item {
  display:          flex;
  align-items:      flex-start;
  gap:              var(--sp-4);
  padding:          var(--sp-4);
  background-color: var(--n-0);
  border-radius:    var(--r-3);
  border-left:      4px solid var(--brand-ink);
  box-shadow:       var(--shadow-1);
  transition:       box-shadow var(--d-2) var(--ease-out-swift),
                    transform  var(--d-2) var(--ease-out-swift);
}

.form-detail__agenda-item:hover {
  box-shadow: var(--shadow-2);
  transform:  translateX(4px);
}

.form-detail__agenda-time {
  font-family: var(--font-mono);
  font-size:   var(--fs-1);
  font-weight: 700;
  color:       var(--brand-ink);
  white-space: nowrap;
  min-width:   80px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

.form-detail__agenda-title {
  margin:     0 0 var(--sp-1);
  font-size:  var(--fs-2);
  font-weight: 600;
  color:      var(--n-900);
}

.form-detail__agenda-desc {
  margin:     0;
  font-size:  var(--fs-1);
  color:      var(--n-600);
  line-height: 1.5;
}

/* Speakers grid */
.form-detail__speakers {
  list-style: none;
  margin:     0;
  padding:    0;
  display:    grid;
  grid-template-columns: repeat(4, 1fr);
  gap:        var(--sp-3);
}

@media (max-width: 991px) {
  .form-detail__speakers {
    grid-template-columns: repeat(2, 1fr);
  }
}

@media (max-width: 480px) {
  .form-detail__speakers {
    grid-template-columns: 1fr;
  }
}

.form-detail__speaker {
  display:          flex;
  flex-direction:   column;
  align-items:      center;
  text-align:       center;
  padding:          var(--sp-5) var(--sp-3);
  background-color: var(--n-0);
  border-radius:    var(--r-3);
  box-shadow:       var(--shadow-1);
  transition:       box-shadow var(--d-2) var(--ease-out-swift),
                    transform  var(--d-2) var(--ease-out-swift);
}

.form-detail__speaker:hover {
  box-shadow: var(--shadow-2);
  transform:  translateY(-3px);
}

.form-detail__speaker-avatar {
  display:          flex;
  align-items:      center;
  justify-content:  center;
  width:            64px;
  height:           64px;
  border-radius:    50%;
  background-color: var(--brand-ink);
  color:            var(--n-0);
  font-size:        var(--fs-3);
  font-weight:      700;
  margin-bottom:    var(--sp-3);
}

.form-detail__speaker-name {
  margin:    0 0 var(--sp-1);
  font-size: var(--fs-2);
  font-weight: 700;
  color:     var(--n-900);
}

.form-detail__speaker-title {
  margin:    0;
  font-size: var(--fs-1);
  color:     var(--n-600);
}

/* Sidebar panel */
.form-detail__sidebar {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-4);
  position:       sticky;
  top:            var(--sp-6);
}

@media (max-width: 991px) {
  .form-detail__sidebar {
    position: static;
  }
}

.form-detail__panel {
  background-color: var(--n-0);
  border:           1px solid var(--n-200);
  border-radius:    var(--r-3);
  padding:          var(--sp-5);
  box-shadow:       var(--shadow-1);
}

.form-detail__panel-title {
  margin:        0 0 var(--sp-4);
  font-family:   var(--font-serif);
  font-size:     var(--fs-3);
  font-weight:   600;
  color:         var(--n-900);
}

/* Phase 9 (M52) — F-3-06: Register CTA full-width polish.
   `.btn--primary` is `inline-flex` by default which left the Register CTA
   content-width inside the sidebar panel, off-balance against the
   EventDetail full-width precedent. Scoping to `.form-detail__panel`
   keeps the rule isolated (kit primary buttons elsewhere remain
   inline-flex). The selector targets the kit class directly so the
   button keeps its `.btn .btn--primary .btn--lg` modifier chain. */
.form-detail__panel .btn--primary {
  width:          100%;
  justify-content: center;
}

.form-detail__organiser {
  display:       flex;
  align-items:   center;
  gap:           var(--sp-3);
  margin-bottom: var(--sp-3);
}

.form-detail__organiser-avatar {
  display:          flex;
  align-items:      center;
  justify-content:  center;
  width:            48px;
  height:           48px;
  border-radius:    50%;
  background-color: var(--brand-ink);
  color:            var(--n-0);
  font-size:        var(--fs-2);
  font-weight:      700;
  flex-shrink:      0;
}

.form-detail__organiser-info {
  flex:      1;
  min-width: 0;
}

.form-detail__organiser-name {
  display:     flex;
  align-items: center;
  gap:         var(--sp-1);
  font-size:   var(--fs-2);
  font-weight: 700;
  color:       var(--n-900);
}

.form-detail__verified-icon {
  display:     inline-flex;
  align-items: center;
  color:       var(--state-success);
}

.form-detail__organiser-label {
  font-size: var(--fs-1);
  color:     var(--n-500);
}

.form-detail__organiser-bio {
  margin:      var(--sp-2) 0 var(--sp-3);
  font-size:   var(--fs-1);
  color:       var(--n-600);
  line-height: 1.5;
}

.form-detail__contact-btn {
  display:          inline-flex;
  align-items:      center;
  justify-content:  center;
  gap:              var(--sp-1);
  width:            100%;
  min-height:       44px;
  margin-top:       var(--sp-3);
  padding:          var(--sp-2) var(--sp-4);
  background-color: var(--brand-ink);
  color:            var(--n-0);
  border:           none;
  border-radius:    var(--r-2);
  font-size:        var(--fs-2);
  font-weight:      600;
  cursor:           pointer;
  transition:       background-color var(--d-2) var(--ease-out-swift);
}

.form-detail__contact-btn:hover,
.form-detail__contact-btn:focus-visible {
  background-color: color-mix(in oklab, var(--brand-ink) 85%, var(--n-0));
}

.form-detail__contact-btn:focus-visible {
  outline:        2px solid var(--brand-spark);
  outline-offset: 2px;
}

/* Back link */
.form-detail__back {
  margin-top: var(--sp-5);
}

.form-detail__back-link {
  display:         inline-flex;
  align-items:     center;
  gap:             var(--sp-1);
  min-height:      44px;
  padding:         var(--sp-2) 0;
  color:           var(--brand-ink);
  font-size:       var(--fs-2);
  font-weight:     600;
  text-decoration: none;
  transition:      gap var(--d-1) var(--ease-out-swift);
}

.form-detail__back-link:hover,
.form-detail__back-link:focus-visible {
  gap: var(--sp-2);
}

/* ── Drawer body: registration form ────────────────────────────────── */

.form-detail__reg-form {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-4);
}

.form-detail__reg-section {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-3);
}

.form-detail__reg-section-title {
  margin:      0 0 var(--sp-2);
  font-family: var(--font-serif);
  font-size:   var(--fs-3);
  font-weight: 600;
  color:       var(--n-900);
}

.form-detail__reg-payment {
  padding-top:  var(--sp-3);
  border-top:   1px solid var(--n-200);
}

.form-detail__field {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-1);
}

.form-detail__field-row {
  display:               grid;
  grid-template-columns: 1fr 1fr;
  gap:                   var(--sp-3);
}

@media (max-width: 480px) {
  .form-detail__field-row {
    grid-template-columns: 1fr;
  }
}

.form-detail__field-label {
  font-size:   var(--fs-1);
  font-weight: 600;
  color:       var(--n-700);
}

.form-detail__field-required {
  color:       var(--state-danger);
  margin-left: var(--sp-1);
}

.form-detail__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;
}

.form-detail__field-input,
.form-detail__field-textarea,
.form-detail__field-select {
  width:            100%;
  min-height:       44px;
  padding:          var(--sp-2) var(--sp-3);
  background-color: var(--n-0);
  border:           1px solid var(--n-300);
  border-radius:    var(--r-2);
  font-family:      var(--font-sans);
  font-size:        var(--fs-2);
  color:            var(--n-900);
  transition:       border-color var(--d-2) var(--ease-out-swift),
                    box-shadow   var(--d-2) var(--ease-out-swift);
}

.form-detail__field-input::placeholder,
.form-detail__field-textarea::placeholder {
  color: var(--n-400);
}

.form-detail__field-input:focus,
.form-detail__field-textarea:focus,
.form-detail__field-select:focus {
  outline:      none;
  border-color: var(--brand-ink);
  box-shadow:   0 0 0 3px color-mix(in oklab, var(--brand-ink) 18%, transparent);
}

.form-detail__field-textarea {
  resize:      vertical;
  min-height:  88px;
  line-height: 1.5;
}

.form-detail__field-select-wrap {
  position: relative;
}

.form-detail__field-select {
  appearance:        none;
  -webkit-appearance: none;
  padding-right:     var(--sp-6);
  cursor:            pointer;
}

.form-detail__field-select-glyph {
  position:        absolute;
  top:             50%;
  right:           var(--sp-3);
  transform:       translateY(-50%);
  color:           var(--n-500);
  pointer-events:  none;
  font-size:       var(--fs-2);
}

.form-detail__checkbox-group {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-1);
}

.form-detail__checkbox-item {
  display:     inline-flex;
  align-items: center;
  gap:         var(--sp-2);
  min-height:  44px;
  padding:     0 var(--sp-1);
  font-size:   var(--fs-2);
  color:       var(--n-800);
  cursor:      pointer;
}

.form-detail__checkbox-input {
  width:        18px;
  height:       18px;
  accent-color: var(--brand-ink);
  cursor:       pointer;
}

.form-detail__checkbox-label {
  font-size: var(--fs-2);
  color:     var(--n-800);
}

.form-detail__reg-summary {
  display:          flex;
  align-items:      center;
  justify-content:  space-between;
  padding:          var(--sp-3) 0;
  border-top:       1px solid var(--n-200);
  border-bottom:    1px solid var(--n-200);
  font-size:        var(--fs-2);
}

.form-detail__reg-summary-label {
  color:       var(--n-600);
  font-weight: 500;
}

.form-detail__reg-summary-value {
  font-family: var(--font-serif);
  font-size:   var(--fs-4);
  font-weight: 700;
  color:       var(--brand-ink);
}

.form-detail__reg-security {
  display:     inline-flex;
  align-items: center;
  gap:         var(--sp-1);
  margin:      0;
  font-size:   var(--fs-1);
  color:       var(--n-500);
  text-align:  center;
  justify-content: center;
}

/* ── 2026-05-20 Phase 2: two-screen state machine ─────────────────────
   Drawer screen 1 (form) and screen 2 (summary) live inside one form;
   form-registration-drawer.js toggles visibility via the [hidden] attribute
   on the [data-form-registration-state="form|summary"] containers. Mirrors
   the .buy-tickets-form__state shape in elfrique.components.overlay.css
   §1335 so the two registration drawers share a single mental model.
   HR6 single-overlay invariant: same drawer instance, two screens. */
.form-detail__reg-state[hidden] {
  display: none;
}

.form-detail__reg-state--form,
.form-detail__reg-state--summary {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-4);
}

.form-detail__reg-summary-title {
  margin:      0;
  font-family: var(--font-serif);
  font-size:   var(--fs-3);
  font-weight: 600;
  color:       var(--n-900);
}

.form-detail__reg-summary-title:focus-visible {
  outline:        2px solid var(--brand-ink);
  outline-offset: 2px;
}

.form-detail__reg-summary-list {
  margin:         0;
  padding:        var(--sp-3) 0;
  border-top:     1px solid var(--n-200);
  border-bottom:  1px solid var(--n-200);
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-2);
}

.form-detail__reg-summary-row {
  display:         flex;
  align-items:     baseline;
  justify-content: space-between;
  gap:             var(--sp-3);
}

.form-detail__reg-summary-row--total {
  padding-top: var(--sp-2);
  border-top:  1px solid var(--n-200);
}

.form-detail__reg-summary-key {
  margin:      0;
  color:       var(--n-600);
  font-size:   var(--fs-1);
  font-weight: 500;
}

.form-detail__reg-summary-val {
  margin:      0;
  color:       var(--n-900);
  font-size:   var(--fs-2);
  font-weight: 600;
  text-align:  right;
}

.form-detail__reg-summary-row--total .form-detail__reg-summary-val {
  font-family: var(--font-serif);
  font-size:   var(--fs-3);
  color:       var(--brand-ink);
}

.form-detail__reg-error {
  margin:      0;
  padding:     var(--sp-2) var(--sp-3);
  background:  color-mix(in oklab, var(--state-danger) 8%, var(--n-0));
  border:      1px solid color-mix(in oklab, var(--state-danger) 35%, transparent);
  border-radius: var(--r-2);
  color:       var(--state-danger);
  font-size:   var(--fs-1);
}

.form-detail__reg-actions {
  display:         flex;
  align-items:     center;
  justify-content: flex-end;
  gap:             var(--sp-2);
  flex-wrap:       wrap;
}

/* Reduced-motion fallback — kill the agenda/speaker hover transforms +
   CTA transforms when the user has prefers-reduced-motion: reduce. */
@media (prefers-reduced-motion: reduce) {
  .form-detail__cta,
  .form-detail__contact-btn,
  .form-detail__back-link,
  .form-detail__agenda-item,
  .form-detail__speaker {
    transition: none;
  }
  .form-detail__cta:hover,
  .form-detail__agenda-item:hover,
  .form-detail__speaker:hover {
    transform: none;
  }
}

/* ── M50 Phase 8 — admin BidPost reference-photo gallery ───────────────────
   Used by Views/AdminBidPost/Detail.cshtml. Token-driven thumbnail tiles
   that link out to the raw photo URL in a new tab — admin browse surface
   only, no lightbox / no inline preview swap (kept minimal — Phase 8 is a
   read-only inspection surface, not an editing surface).
   Hard rules: #2 (tokens only), #8 (touch ≥44px), #10 (reduced-motion). */
.bidpost-gallery {
  display:               grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap:                   var(--sp-3);
}
.bidpost-gallery__item {
  display:       block;
  aspect-ratio:  1;
  border-radius: var(--r-2);
  overflow:      hidden;
  border:        1px solid var(--n-200);
  background:    var(--n-100);
  min-height:    44px;
  min-width:     44px;
  transition:    transform var(--d-2) var(--ease-out-swift),
                 box-shadow var(--d-2) var(--ease-out-swift);
}
.bidpost-gallery__item:hover {
  transform:  translateY(-1px);
  box-shadow: 0 4px 12px color-mix(in srgb, var(--brand-ink) 12%, transparent);
}
.bidpost-gallery__img {
  width:      100%;
  height:     100%;
  object-fit: cover;
  display:    block;
}
@media (prefers-reduced-motion: reduce) {
  .bidpost-gallery__item {
    transition: none;
  }
  .bidpost-gallery__item:hover {
    transform: none;
  }
}

/* ── 2026-05-20-uat-round-2-fixes Phase 2 fold-in (F-2-01) — Preview banner
   Source: Views/Shared/_PreviewBanner.cshtml · Model: PreviewBannerViewModel.
   Rendered above the hero when a non-Live listing is shown to its owner in
   preview mode (PublicController.EventDetail/FormDetail/TourDetail; plus
   pre-existing VotingContest/ContestantDetail consumers). Warm warning
   palette via --state-warn token + color-mix for soft fill; matches the
   visual intent of the prior inline <style> block (extracted per Hard
   Rule #5; raw hex purged per Hard Rule #2).
   ────────────────────────────────────────────────────────────────────── */
.preview-banner {
  display:         flex;
  align-items:     center;
  justify-content: center;
  gap:             var(--sp-2);
  background:      color-mix(in srgb, var(--state-warn) 8%, var(--n-0));
  border-bottom:   2px solid color-mix(in srgb, var(--state-warn) 60%, var(--n-0));
  color:           var(--state-warn);
  font-family:     var(--font-sans);
  font-size:       var(--fs-2);
  font-weight:     600;
  padding:         var(--sp-3) var(--sp-4);
  text-align:      center;
  position:        relative;
  z-index:         10;
}

.preview-banner-icon {
  font-size:   var(--fs-3);
  color:       var(--state-warn);
  flex-shrink: 0;
}

.preview-banner-text {
  line-height: 1.4;
}

/* ==========================================================================
   FreeOrPaidChooser primitive (2026-05-20-uat-round-2-fixes Phase 3)
   Source: Views/Shared/Kit/_FreeOrPaidChooser.cshtml · Model: FreeOrPaidChooserModel.
   Pre-step routing primitive: two card-buttons that redirect to the entity's
   existing Create{Entity}?paid=false|true. Brand-ink + state-success palette
   via tokens; no raw hex; touch targets exceed 44x44 via padding scale.
   ────────────────────────────────────────────────────────────────────── */
.free-paid-chooser {
  display:        flex;
  flex-direction: column;
  gap:            var(--sp-6);
  max-width:      48rem;
  margin:         0 auto;
  padding:        var(--sp-6) var(--sp-4);
}

.free-paid-chooser__header {
  display:        flex;
  flex-direction: column;
  align-items:    center;
  gap:            var(--sp-2);
  text-align:     center;
}

.free-paid-chooser__title {
  font-family: var(--font-serif);
  font-size:   var(--fs-5);
  font-weight: 600;
  color:       var(--brand-ink);
  margin:      0;
}

.free-paid-chooser__description {
  font-family: var(--font-sans);
  font-size:   var(--fs-2);
  color:       var(--n-700);
  margin:      0;
  max-width:   36rem;
}

.free-paid-chooser__grid {
  display:               grid;
  grid-template-columns: 1fr;
  gap:                   var(--sp-4);
}

@media (min-width: 640px) {
  .free-paid-chooser__grid {
    grid-template-columns: 1fr 1fr;
  }
}

.free-paid-chooser__card {
  display:         flex;
  flex-direction:  column;
  align-items:     center;
  justify-content: center;
  gap:             var(--sp-3);
  min-height:      11rem;
  padding:         var(--sp-5) var(--sp-4);
  border-radius:   var(--r-3);
  border:          2px solid var(--n-200);
  background:      var(--n-0);
  color:           var(--brand-ink);
  text-align:      center;
  text-decoration: none;
  transition:      border-color var(--d-2) var(--ease-out-swift),
                   box-shadow var(--d-2) var(--ease-out-swift),
                   transform var(--d-2) var(--ease-out-swift);
}

.free-paid-chooser__card:hover,
.free-paid-chooser__card:focus-visible {
  border-color: var(--brand-ink);
  box-shadow:   0 4px 16px color-mix(in srgb, var(--brand-ink) 12%, transparent);
  transform:    translateY(-2px);
  outline:      none;
}

.free-paid-chooser__card:focus-visible {
  outline:        3px solid color-mix(in srgb, var(--brand-spark) 60%, transparent);
  outline-offset: 2px;
}

.free-paid-chooser__card--free {
  border-color: color-mix(in srgb, var(--state-success) 30%, var(--n-200));
}

.free-paid-chooser__card--free:hover,
.free-paid-chooser__card--free:focus-visible {
  border-color: var(--state-success);
  box-shadow:   0 4px 16px color-mix(in srgb, var(--state-success) 18%, transparent);
}

.free-paid-chooser__card--paid {
  border-color: color-mix(in srgb, var(--brand-spark) 30%, var(--n-200));
}

.free-paid-chooser__card--paid:hover,
.free-paid-chooser__card--paid:focus-visible {
  border-color: var(--brand-spark);
  box-shadow:   0 4px 16px color-mix(in srgb, var(--brand-spark) 18%, transparent);
}

.free-paid-chooser__card-icon {
  display:         inline-flex;
  align-items:     center;
  justify-content: center;
  width:           3rem;
  height:          3rem;
  border-radius:   50%;
  background:      color-mix(in srgb, var(--brand-ink) 6%, var(--n-0));
  font-size:       var(--fs-4);
}

.free-paid-chooser__card--free .free-paid-chooser__card-icon {
  background: color-mix(in srgb, var(--state-success) 14%, var(--n-0));
  color:      var(--state-success);
}

.free-paid-chooser__card--paid .free-paid-chooser__card-icon {
  background: color-mix(in srgb, var(--brand-spark) 14%, var(--n-0));
  color:      var(--brand-spark);
}

.free-paid-chooser__card-label {
  font-family: var(--font-sans);
  font-size:   var(--fs-3);
  font-weight: 700;
}

.free-paid-chooser__card-detail {
  font-family: var(--font-sans);
  font-size:   var(--fs-1);
  color:       var(--n-700);
  line-height: 1.4;
  max-width:   16rem;
}

@media (prefers-reduced-motion: reduce) {
  .free-paid-chooser__card {
    transition: none;
  }
  .free-paid-chooser__card:hover,
  .free-paid-chooser__card:focus-visible {
    transform: none;
  }
}

