/* ============================================================================
   Hero
   ========================================================================= */

/* A blurred mesh of cool blue-greys: near-white down the left, one broad soft
   mass centre-right, smaller ones at the top-left and bottom-right corners.

   Built from radials rather than shipped as the supplied bitmap. The artwork
   is entirely soft gradient, which is what gradients are for — so this costs
   no request, cannot become the LCP element, and stays sharp at any viewport
   instead of resampling a fixed-width image. Swap `background-image` for a
   `url()` if the exact file is ever needed.

   No yellow. The previous wash carried a brand-yellow radial in the top-left;
   the supplied artwork is blue-grey throughout, and the hero's yellow now
   comes from the CTA alone. */
.hero {
  position: relative;
  padding-top: clamp(7rem, 5rem + 6vw, 9.5rem);
  overflow: clip;
  isolation: isolate;
  background-color: var(--mesh-base);
  background-image:
    radial-gradient(38% 48% at 57% 54%, rgba(var(--mesh-deep), .58) 0%, rgba(var(--mesh-deep), 0) 72%),
    radial-gradient(32% 44% at 90% 92%, rgba(var(--mesh-deep), .50) 0%, rgba(var(--mesh-deep), 0) 70%),
    radial-gradient(30% 40% at 82% 4%, rgba(var(--mesh-soft), .44) 0%, rgba(var(--mesh-soft), 0) 74%),
    radial-gradient(24% 34% at 6% 8%, rgba(var(--mesh-soft), .40) 0%, rgba(var(--mesh-soft), 0) 72%),
    radial-gradient(44% 56% at 16% 66%, rgba(255, 255, 255, .70) 0%, rgba(255, 255, 255, 0) 70%);
}

/* Film grain over the mesh — the texture that keeps a large soft gradient from
   banding on 8-bit displays, and the one detail that makes it read as artwork
   rather than as a CSS gradient.

   Tiled fractal noise, desaturated, laid at low opacity with NORMAL blending.
   A blend mode would be the obvious way to do grain and is the wrong tool
   here: this element sits inside `isolation: isolate` alongside a hero that
   animates opacity and transform on entry, and both of those silently break
   blending mid-animation. Plain alpha has no such failure mode.

   `stitchTiles='stitch'` is what makes the 200px tile seamless; without it
   every tile edge shows as a faint grid. */
.hero__field {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  opacity: 0.2;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='200' height='200'%3E%3Cfilter id='g'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='200' height='200' filter='url(%23g)'/%3E%3C/svg%3E");
  background-repeat: repeat;
  background-size: 200px 200px;
}

.hero__inner {
  display: grid;
  gap: clamp(1.5rem, 0.75rem + 2.5vw, 2.5rem);
  align-items: center;
  padding-bottom: clamp(2.5rem, 1.75rem + 3vw, 4rem);
}

.hero__head { grid-column: 1 / -1; }

/* --- Copy ----------------------------------------------------------------- */

.hero__copy { max-width: 34rem; }

.hero__badge { display: inline-flex; margin-bottom: 1.5rem; }


/* Held at its own weight: `.twotone` moved to 700 site-wide, and this banner
   heading was already approved as it is. */
.hero__title.twotone { font-weight: 600; }

.hero__title {

  /* One step below display-1, because the two authored lines are held on a
     single row each and so cannot reflow out of trouble — see the token. */
  font-size: var(--fs-display-hero);
}

/* The second line carries the emphasis, in one typeface rather than two: the
   banner is set entirely in Bricolage Grotesque, and the accent is weight plus
   the brand blue.

   It used to be a Playfair Display italic. That device is still right for
   section headings, where an italic phrase inside a 2rem line reads as a
   considered aside; at banner size, against a soft photographic composition, a
   second typeface was the loudest thing on the screen. Blue at 700 says the
   same thing without introducing a face the rest of the banner never uses.

   --blue-600, not the brand --blue-500: 7.5:1 on the pale left of the mesh and
   still 4.4:1 where the mesh is at its deepest, so the line holds wherever the
   gradient puts it. */
.hero__title-accent {
  font-weight: 600;
  color: var(--blue-600);
}

/* The headline used to span the full container with each written line held on
   one row. That left the intro text in the row below, centred against the
   tall visual beside it, with a large empty band under the headline. The
   headline now sits in the left column directly above the intro (see the
   900px block at the foot of this file), so its lines are free to wrap:
   three lines at desktop sizes, by the owner's call. */
.hero__title .tr-line, .hero__title .tr-line-static { text-wrap: balance; }

.hero__lead { color: var(--text); font-weight: 400; max-width: 33rem; }
.hero__sub {
  margin-top: 0.9rem;
  font-size: var(--fs-body);
  line-height: 1.6;
  color: var(--text-muted);
  max-width: 32rem;
}

.hero__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 2rem; }

/* --- Proof strip -----------------------------------------------------------
   A tinted plate spanning the container, holding three claims in a row.

   `auto-fit` rather than space-between: with three items and flex-wrap, the
   moment one wraps the remaining two are pushed to opposite ends of the row
   and the strip looks broken. Equal tracks collapse 3 → 2 → 1 as the viewport
   narrows and every arrangement stays a grid. */
.hero__proofs {
  grid-column: 1 / -1;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(15rem, 1fr));
  align-items: start;
  gap: 0.9rem clamp(1rem, 2.5vw, 2rem);
  margin-top: clamp(1.5rem, 1rem + 1.5vw, 2.5rem);
  padding: clamp(0.9rem, 0.75rem + 0.5vw, 1.15rem) clamp(1.1rem, 0.8rem + 1.4vw, 1.9rem);
  border-radius: var(--r-lg);
  /* Reads as a plate on the hero's own wash: the gradient runs from almost
     white on the left to the chip tint on the right, in the same direction as
     the loop gradient everywhere else on the page. */
  background: linear-gradient(100deg, var(--tint-2) 0%, var(--blue-200) 100%);
  box-shadow: inset 0 0 0 1px rgba(35, 105, 210, .10);
}
.hero__proofs li {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  font-size: var(--fs-sm);
  line-height: 1.45;
  color: var(--text);
}
/* The heavy phrase. 650 rather than 700 — Poppins jumps hard into bold, and at
   15px against 400 the step is already unmistakable. */
.hero__proof-text strong { font-weight: 650; }

/* Aligned to the first line rather than centred: on a phone the third proof
   wraps, and a centred dot floats against the second line. */
.hero__proof-dot {
  width: 19px; height: 19px;
  flex: none;
  margin-top: 0.1em;
  color: var(--blue-500);
  display: grid;
  place-items: center;
}

/* --- Loop composition ------------------------------------------------------ */

.hero__visual {
  position: relative;
  aspect-ratio: 1 / 0.64;
  min-height: 17rem;
  display: grid;
  place-items: center;
}

.hero__loop-wrap {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
}
/* In flow, centred by the wrapper's own `place-items`, and NOT absolutely
   positioned with a translate. That matters: Framer animates this element's
   scale on entry and writes `transform` to do it, which would blow away a
   transform-based centring and throw the mark off-frame halfway through the
   animation. Letting grid do the centring leaves the transform free.

   Enough shadow to lift the ribbon off the pale mesh, not enough to make it
   look like a sticker. */
.hero__loop {
  width: 100%;
  max-width: none;
  height: auto;
  filter: drop-shadow(0 20px 34px rgba(35, 105, 210, .14));
}

/* --- The subject in the middle -------------------------------------------
   Held between the two rings, overlapping both. Sizing is in percentages of
   the frame so the whole composition scales as one object; `object-fit: cover`
   means the supplied file can be any portrait crop and still fill the plate. */
.hero__portrait {
  position: absolute;
  left: 18%;
  top: 10%;
  width: 453px;
  border-radius: var(--r-lg);
  overflow: hidden;
  z-index: 1;
  box-shadow:inherit;
}
.hero__portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Two floating cards, one off each ring. Percentages rather than fixed offsets
   so they hold their relationship as the composition scales. */
.hcard {
  position: absolute;
  width: min(14.5rem, 48%);
  padding: 0.95rem 1.05rem 1.05rem;
  border-radius: var(--r-lg);
  background: rgba(255, 255, 255, .94);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: var(--e-3);
  z-index: 2;
}
/* Pushed to opposite outer corners, so the rings and the subject between them
   stay readable in the diagonal the cards leave open. */
.hcard--resident { left: -4%; top: -8%; }
.hcard--staff { right: -4%; bottom: -8%; }

/* The card's own headline, in the display face — this is what turned the cards
   from two labelled fragments into two named things. It replaced a small
   uppercase RESIDENT / STAFF tag, which named the audience rather than the
   thing on the card and left the card itself unheaded. */
.hcard__title {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 24, 'wdth' 100;
  font-size: 0.9375rem;
  font-weight: 700;
  line-height: 1.25;
  letter-spacing: -0.012em;
  color: var(--text);
  margin-bottom: 0.7rem;
  /* Two lines, and the third is cut rather than allowed to grow the card —
     these are absolutely positioned over the rings, so height is composition,
     not content. */
  display: -webkit-box;
  -webkit-line-clamp: 2;
  line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* The blue disc riding the card's bottom-right corner, half outside it. The
   same rounded-square-on-blue idiom as the mega-menu's icon tiles, so the
   banner's smallest brand object is one the rest of the site already uses. */
.hcard__badge {
  position: absolute;
  right: -0.6rem;
  bottom: -0.6rem;
  width: 2.15rem;
  height: 2.15rem;
  display: grid;
  place-items: center;
  border-radius: var(--r-sm);
  background: var(--blue-500);
  color: #fff;
  box-shadow: var(--e-brand);
}

/* Category pills under the staff card's track — the four things a request can
   be about. Authored, like everything else in these cards. */
.hcard__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 0.3rem;
  margin-top: 0.7rem;
}
.hcard__chips span {
  padding: 0.2rem 0.5rem;
  border-radius: var(--r-pill);
  background: var(--blue-100);
  color: var(--blue-800);
  font-size: 0.625rem;
  font-weight: 600;
  line-height: 1.4;
}

.hcard__search {
  display: flex;
  align-items: center;
  gap: 0.45rem;
  padding: 0.45rem 0.6rem;
  border-radius: var(--r-pill);
  background: var(--sunken);
  border: 1px solid var(--border);
  font-size: 0.75rem;
  color: var(--text-secondary);
  margin-bottom: 0.55rem;
}
.hcard__search svg { color: var(--text-muted); flex: none; }

.hcard__result { display: flex; gap: 0.55rem; align-items: flex-start; }
.hcard__result-icon { color: var(--blue-500); flex: none; margin-top: 0.1rem; }
.hcard__result-title { font-size: 0.8125rem; font-weight: 680; color: var(--text); line-height: 1.35; }
.hcard__result-meta { font-size: 0.6875rem; color: var(--text-muted); line-height: 1.4; }

.hcard__req-title { font-size: 0.8125rem; font-weight: 680; color: var(--text); line-height: 1.35; }
.hcard__req-meta { font-size: 0.6875rem; color: var(--text-muted); line-height: 1.4; margin-top: 0.1rem; }

.hcard__track { display: flex; gap: 4px; margin-top: 0.7rem; }
.hcard__track span {
  flex: 1; height: 4px; border-radius: 2px;
  background: var(--ink-100);
}
.hcard__track .is-done { background: var(--blue-500); }
.hcard__track .is-live { background: var(--yellow-300); }

/* --- Trust bar ------------------------------------------------------------ */

.hero__trust {
  border-top: 1px solid var(--border);
  background: rgba(255, 255, 255, .55);
}
.hero__trust-inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 1rem clamp(1.25rem, 3vw, 3rem);
  padding-block: 1.35rem;
}
.hero__trust-label { color: var(--text-muted); flex: none; }

.hero__trust-list {
  display: flex;
  flex-wrap: wrap;
  gap: 0.75rem clamp(1.25rem, 3.5vw, 3.25rem);
  align-items: baseline;
}
.hero__trust-list li { display: flex; flex-direction: column; gap: 0.1rem; }
.hero__trust-name {
  font-family: var(--font-display);
  font-variation-settings: 'opsz' 96, 'wdth' 100;
  font-size: 1rem;
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--text);
}
.hero__trust-kind { font-size: 0.6875rem; color: var(--text-muted); letter-spacing: 0.01em; }

/* --- Breakpoints ---------------------------------------------------------- */

@media (max-width: 899px) {
  .hero__visual { max-width: 30rem; margin-inline: auto; width: 100%; aspect-ratio: 1 / 0.8; }
  .hcard { width: min(15rem, 58%); }
  .hero__copy { max-width: none; }
}

/* Five names stacked one-per-row ran the trust bar to ~360px on a phone —
   more vertical space than the hero copy above it. Two columns keeps every
   name and its kind, and costs three rows instead of five. */
@media (max-width: 599px) {
  .hero__trust-list {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 0.9rem 1rem;
  }
  .hero__trust-name { font-size: 0.9375rem; }
  .hero__trust-inner { gap: 0.85rem; padding-block: 1.15rem; }
    .hcard__search {
    padding: 0.45rem 10px;
    font-size: 9px;
}
.hcard__result-title {
    font-size: 11px;}
    .hcard--staff {bottom: -41px; right: -2%; }
    .audit__cta a{
        width:100%;
        font-size:12px;
    }
 

}

/* On the narrowest phones the two columns are tight enough that the names
   wrap, and the kind line doubles the height again. The names are
   self-describing — "City of Wauwatosa", "Park District of Oak Park" — so the
   kind drops here and the full label stays in the Results cards. */
@media (max-width: 399px) {
  .hero__trust-kind { display: none; }
  .hero__portrait {
    display:none;
}
.hcard {
        width: 96% !important;
        padding: 0.8rem 0.85rem 0.9rem;
    }
        .hcard--staff {
        bottom: -10px;
        right: -2%;
    }
}

/* On a phone the composition is the tightest thing on the page: two cards at
   two-thirds width plus a portrait between them, inside about 330px. The frame
   goes nearly square to buy vertical room, the cards come in off the corners,
   and the portrait widens — at the desktop 32% it would be a 105px sliver with
   both cards sitting on top of it. */
@media (max-width: 479px) {
  .hero__visual { min-height: 17rem; aspect-ratio: 1 / 0.98; }
  .hcard { width: 64%; padding: 0.8rem 0.85rem 0.9rem; }
  .hcard--resident { top: 0; left: -2%; }
  .hcard--staff {bottom: -41px; right: -2%; }
  .hcard__badge { width: 1.9rem; height: 1.9rem; right: -0.5rem; bottom: -0.5rem; }
  .hero__portrait { left: 9%; top: 31%; width: 81%; }
  .hero__actions .btn { flex: 1 1 100%; }
  .hcard__search {
    padding: 0.45rem 10px;
    font-size: 9px;
}
.hcard__result-title {
    font-size: 11px;}
    .hero__loop-wrap{
    }
        .hcard--staff {
        bottom: 0px;}
}

/* Headline and intro stacked in the left column, the visual to their right
   across both rows. The intro follows the headline at the grid gap instead of
   being centred against the visual, which is what opened the gap between
   them. Anything after these three (the trust strip) still spans both
   columns on the rows below. */
@media (min-width: 900px) {
  .hero__inner {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.02fr);
    align-items: start;
  }
  .hero__head { grid-column: 1; grid-row: 1; align-self: end; }
  .hero__copy { grid-column: 1; grid-row: 2; }
  .hero__visual { grid-column: 2; grid-row: 1 / span 2; align-self: center; }
}

@media (min-width: 1200px) {
  .hero__inner { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); column-gap: 4.5rem; }
}
