/* public/style.css — MyTX15, mobile-first
   Palette matched to the Bobby Pulido for Congress brand sheet so this page
   reads as a native subpage of the official site rather than a separate
   branded app: navy #00205B, crimson #AD0B32 (used sparingly, as an accent
   only — never as a full-card background), light gray #E9E9E9.

   TYPEFACE. Museo Slab 500 is the brand sheet's heading face and is now
   actually served, self-hosted from public/assets/fonts (25 KB woff2, 29 KB
   woff fallback). It was declared in --font-heading for months but never
   loaded, so every heading silently rendered in Georgia. font-display:swap
   paints text immediately in the fallback and reflows once, rather than
   holding a headline blank on a slow connection.

   2026-08 redesign: hybrid type system. Headings keep the brand serif
   (Museo Slab/Georgia); ALL other UI text — body, labels, buttons, inputs —
   uses the platform system sans (SF on iOS, Segoe on Windows, Roboto on
   Android) for legibility and a cleaner, more premium feel on phones. */
@font-face{
  font-family:"Museo Slab";
  src:url("assets/fonts/MuseoSlab-500.woff2") format("woff2"),
      url("assets/fonts/MuseoSlab-500.woff") format("woff");
  font-weight:400 700;
  font-style:normal;
  font-display:swap;
}

:root{
  /* The three brand-sheet colors, exact. Everything else on this page is a
     tint or a semantic state color derived from them. */
  --ink:#00205B; --ink-soft:#3B4A73; --muted:#5E6785;
  --page:#E9E9E9; --surface:#FFFFFF;
  --blue:#00205B; --blue-dark:#001640;
  --red:#AD0B32; --red-soft:#F7E6EA; --green:#1E9E6B; --green-soft:#E8F8F1;
  --amber-soft:#FEF6E6; --blue-soft:#EDEFF5;
  --line:rgba(0,32,91,.12);
  --campaign-red:#AD0B32; --campaign-red-soft:#F7E6EA;

  /* Map palette. District blue is kept (the one color the client asked to
     preserve); counties moved from orange to a violet analogous to it, the
     precinct highlight from green to teal on its other side. Keep in sync
     with scripts/build-static-map.js COLORS. */
  --map-district:#086CFF;
  --map-county:#6E56CF;
  --map-county-label:#4A4370;
  --map-precinct:#0E8E8E;

  /* Pill palette. Each pill type gets its own hue so a card reads as several
     distinct facts rather than one grey wash — every one is a soft tint at
     roughly the same weight, so none of them shouts. */
  --pill-election:#8A6100; --pill-election-soft:#FDF3E0;
  --pill-count:#5B4BC4;   --pill-count-soft:#EEEBFA;

  --radius-lg:18px; --radius-md:14px; --radius-sm:10px;
  --shadow-sm:0 1px 2px rgba(0,32,91,.05), 0 1px 1px rgba(0,32,91,.04);
  --shadow-md:0 2px 12px rgba(0,32,91,.06), 0 1px 3px rgba(0,32,91,.05);
  --shadow-lg:0 12px 32px rgba(0,32,91,.12), 0 4px 10px rgba(0,32,91,.05);
  --font-heading: "Museo Slab", "Georgia", "Times New Roman", serif;
  --font-ui: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  /* Legacy alias — a few older rules still reference --font. */
  --font: var(--font-heading);
}
*{box-sizing:border-box}
html{scroll-behavior:smooth}
/* The hidden attribute must always win: display:flex/grid on a class (e.g.
   .ios-row on the collapsible ZIP row) otherwise out-specifies the UA's
   [hidden]{display:none} and the "hidden" element renders anyway. */
[hidden]{display:none!important}
body{
  margin:0;background:var(--page);color:var(--ink);font-family:var(--font-ui);
  -webkit-font-smoothing:antialiased;line-height:1.5;font-size:16px;
}
h1,h2,h3{font-family:var(--font-heading)}
img{max-width:100%;display:block}
button,input,textarea{font-family:inherit}
:focus-visible{outline:3px solid rgba(8,108,255,.55);outline-offset:2px;border-radius:4px}
.skip-link{position:fixed;left:12px;top:-80px;z-index:9999;background:#fff;padding:12px 16px;border-radius:8px;box-shadow:var(--shadow-md)}
.skip-link:focus{top:12px}

/* ---------- Header ---------- */
/* Deliberately minimal: no site nav — this page is meant to sit inline on the
   official site's own page shell, so this just needs the brand mark, the
   2026-cycle note, and the language toggle. */
.topbar{
  display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap;
  padding:14px 4px;border-bottom:0;position:relative;
}
/* A single hairline. The three-band flag stripe sat directly under the logo
   and competed with it, and hard color bands under a header read as dated
   political-website chrome. With Museo Slab now actually loading, the wordmark
   and the type carry the identity; this rule only terminates the header. */
.topbar::after{
  content:"";position:absolute;left:0;right:0;bottom:0;height:1px;
  background:var(--line);
}
.cycle-badge-wrap{display:flex;align-items:center;gap:10px;min-width:0}
.brand-logo{height:30px;width:auto;display:block}
.brand-logo-link,.footer-logo-link{display:block;text-decoration:none;border-radius:6px}
.brand-logo-link:active,.footer-logo-link:active{opacity:.8}
@media(max-width:400px){.brand-logo{height:26px}}
.language-toggle{display:flex;padding:3px;background:var(--blue-soft);border-radius:10px}
.language-toggle button{border:0;background:transparent;min-height:38px;padding:7px 13px;border-radius:8px;font-weight:600;font-size:13px;color:var(--muted);cursor:pointer;transition:background .2s,color .2s;white-space:nowrap}
.language-toggle button.is-active{background:#fff;color:var(--ink);box-shadow:var(--shadow-sm)}

/* ---------- Layout ---------- */
/* 16px, not 40px: the footer supplies its own margin and padding, so the
   extra 40 here just opened a gap under whatever each screen ends with. */
main{max-width:640px;margin:0 auto;padding:0 16px 16px}
.view{display:none;animation:view-in .35s cubic-bezier(.22,.9,.28,1)}
.view.is-active{display:block}
@keyframes view-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}
@media(prefers-reduced-motion: reduce){.view{animation:none}}

/* ---------- Hero ---------- */
.hero-copy{padding:30px 0 4px;text-align:center}
.hero-copy .eyebrow{font-size:12px;font-weight:700;letter-spacing:.08em;text-transform:uppercase;color:var(--red);margin:0 0 10px}
.hero-copy h1{font-size:clamp(28px,7vw,40px);font-weight:600;letter-spacing:-.01em;line-height:1.12;margin:0 0 14px;color:var(--ink)}
.hero-subtitle{font-size:16px;color:var(--ink-soft);margin:0 auto 18px;max-width:46ch}

.new-for-2026-card{
  padding:16px 18px;border-radius:var(--radius-md);
  background:var(--surface);
  border:1px solid var(--line);border-left:3px solid var(--campaign-red);
  margin-bottom:8px;text-align:left;
}
.new-for-2026-card .tag{
  display:inline-block;font-size:10px;font-weight:700;letter-spacing:.07em;
  color:#fff;background:var(--ink);
  padding:4px 9px;border-radius:5px;margin-bottom:9px;
}
.new-for-2026-card p{margin:0;font-size:14.5px;color:var(--ink-soft);line-height:1.55}

/* ---------- How it works (page 1 explainer) ---------- */
.how-steps{display:grid;grid-template-columns:1fr;gap:10px;margin-top:16px;text-align:left}
.how-step{display:flex;align-items:flex-start;gap:12px;padding:14px 16px;background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-md)}
.how-step-number{
  flex:none;width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:var(--blue-soft);color:var(--ink);font-weight:700;font-size:14px;
}
.how-step strong{display:block;font-size:15px;font-weight:600;color:var(--ink)}
.how-step span{display:block;font-size:13.5px;color:var(--muted);margin-top:1px;line-height:1.45}
@media(min-width:760px){.how-steps{grid-template-columns:1fr 1fr 1fr}}

/* ---------- Static district map (page 1) ---------- */
.home-map-panel{position:relative;margin-top:20px;padding:0}
.map-caption{padding:16px 18px 10px}
.map-caption strong{display:block;font-size:16px;font-weight:600;color:var(--ink);font-family:var(--font-heading)}
.map-caption span{display:block;font-size:13px;color:var(--muted);margin-top:2px}
.static-map{padding:6px 18px 4px;display:flex;justify-content:center;background:#FFFFFF}
/* Bounded by HEIGHT, not width. The district is a genuinely long, narrow
   shape (Gonzales down to Hidalgo) and the artwork is 760x1517 — a 1:2 ratio.
   Sizing it to width:100% made it ~800px tall on a 375px phone, taller than
   the viewport, so the map alone pushed the form two screens down. */
.static-map img{max-width:100%;max-height:52vh;width:auto;height:auto}
@media(min-width:760px){.static-map img{max-height:520px}}

/* ---------- Home v2: merged landing + intake (2026-08-12) ---------- */
/* Block 1 reuses .hero-copy above. The trust line closes the hero: the three
   facts (free, bilingual, a minute) a visitor wants before typing anything. */
.trust-line{font-size:13px;font-weight:600;color:var(--muted);text-align:center;margin:0 0 10px}

/* Block 2 — the intake card. Stripe-checkout register: one white card, fields
   with visible borders and a soft focus ring, labels above inputs. Everything
   here uses .field/.pair classes, NOT .ios-row, so the older grouped-row form
   styling (still used by the result screen's help card) is untouched. */
.info-form{margin-top:10px;max-width:560px;margin-left:auto;margin-right:auto}
.intake-card{
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-md);padding:22px 18px 20px;
}
.intake-head{margin-bottom:18px}
.intake-head h2{margin:0;font-size:22px;font-weight:600;color:var(--ink);letter-spacing:-.015em;line-height:1.2}
.intake-head small{display:block;font-size:13.5px;color:var(--muted);margin-top:4px;line-height:1.5}

.field{display:flex;flex-direction:column;gap:6px;margin-bottom:14px;min-width:0}
.field>label,.field>.field-label{font-size:13px;font-weight:600;color:var(--ink)}
.field>label em,.field>.field-label em{font-style:normal;font-weight:500;color:var(--muted)}
.field input{
  width:100%;border:1px solid #D3D8E4;border-radius:10px;padding:11px 13px;
  font-size:16px;color:var(--ink);background:#fff;
  transition:border-color .15s,box-shadow .15s;
}
.field input::placeholder{color:#A3AAC4}
/* The ring replaces the global focus outline on these inputs — border darkens
   to campaign navy and a soft navy halo marks the field, Stripe-style. */
.field input:focus,.field input:focus-visible{outline:none;border-color:var(--ink);box-shadow:0 0 0 4px rgba(0,32,91,.10)}
@media(prefers-reduced-motion: reduce){.field input,.dob-shell{transition:none}}

/* Side-by-side pairs. .pair-always stays two-up even on phones (first/last
   name); plain .pair (phone/email) stacks below 560px. */
.pair{display:grid;grid-template-columns:1fr;gap:0 12px}
.pair-always{grid-template-columns:1fr 1fr}
@media(min-width:560px){.pair{grid-template-columns:1fr 1fr}}

/* DOB as one visual input: the shell carries the border and focus ring, the
   three inner boxes are borderless, the slashes are structural. */
.dob-shell{
  display:flex;align-items:center;gap:2px;border:1px solid #D3D8E4;border-radius:10px;
  background:#fff;padding:0 8px;transition:border-color .15s,box-shadow .15s;
}
.dob-shell:focus-within{border-color:var(--ink);box-shadow:0 0 0 4px rgba(0,32,91,.10)}
.dob-shell input{
  border:0;outline:none;background:transparent;text-align:center;
  font-size:16px;font-weight:600;letter-spacing:.03em;color:var(--ink);
  padding:11px 0;width:44px;flex:none;
}
.dob-shell input:last-of-type{width:64px}
.dob-shell input::placeholder{color:#A3AAC4;font-weight:500}
.dob-shell .dob-sep{color:#C4C9DA;font-weight:600}

/* Suggestions panel under the address field: same normal-flow placement as
   before (never floats over later fields), restyled as a dropdown sheet. */
.field .address-suggestions:not(:empty){border-radius:12px;box-shadow:var(--shadow-lg)}
.field .field-hint{padding:0 2px}

/* Error state matches the focus-ring language, in red: the field the message
   names gets a red border and halo instead of the old inset bar. */
.field.is-invalid input,.field.is-invalid .dob-shell{border-color:var(--red);box-shadow:0 0 0 4px rgba(173,11,50,.08)}
.field.is-invalid .dob-shell input{border:0;box-shadow:none}
.field.is-invalid>label,.field.is-invalid>.field-label{color:var(--red)}
.intake-card .form-error{margin:0 0 12px}
.intake-card .cta-button{margin-top:2px}

/* Block 3 — benefits, the page-1 v6 cards restated. */
.home-benefits{margin-top:30px}
.benefits-lead{font-family:var(--font-heading);font-size:19px;font-weight:600;text-align:center;margin:0 0 14px;color:var(--ink)}
.benefit-grid{display:grid;grid-template-columns:1fr;gap:9px}
@media(min-width:760px){.benefit-grid{grid-template-columns:1fr 1fr}}
.benefit-card{
  display:flex;gap:11px;align-items:flex-start;
  background:var(--surface);border:1px solid var(--line);border-radius:var(--radius-md);
  padding:13px 15px;
}
.benefit-tick{
  flex:none;width:24px;height:24px;border-radius:50%;background:var(--green-soft);color:var(--green);
  text-align:center;line-height:24px;font-size:13px;font-weight:800;
}
.benefit-text{display:block;min-width:0}
.benefit-text b{display:block;font-size:15px;font-weight:700;color:var(--ink)}
.benefit-text>span{display:block;font-size:13.5px;color:var(--muted);line-height:1.5;margin-top:1px}

/* Block 4 — the map card, closing tease above the walk-back CTA. Shares the
   header-bar treatment page 1 used so the page still reads as one set. */
.home-map-card{
  margin:26px auto 0;background:var(--surface);border:1px solid var(--line);
  border-radius:var(--radius-md);overflow:hidden;
}
.home-map-tag{
  font-size:10.5px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;
  color:var(--ink);background:var(--blue-soft);padding:8px 15px;margin:0;text-align:center;
  border-bottom:1px solid var(--line);
}
.home-map-cap{padding:13px 16px 4px;text-align:center;font-size:13px;color:var(--muted);margin:0;line-height:1.55}
.home-map-cta-row{padding:6px 16px 18px}
.home-map-cta-row .cta-button{max-width:420px;margin:0 auto}

/* ---------- Form ---------- */
.form-heading{margin-bottom:12px}
.form-heading h1{margin:0;font-size:26px;font-weight:600;color:var(--ink);letter-spacing:-.015em;line-height:1.15;font-family:var(--font-heading)}
.form-heading small{display:block;font-size:13.5px;color:var(--muted);margin-top:2px}

.ios-card{background:var(--surface);border-radius:var(--radius-md);box-shadow:var(--shadow-md);overflow:hidden;border:1px solid var(--line)}
.field-pair{display:grid;grid-template-columns:1fr 1fr}
.field-pair .ios-row:first-child{border-right:1px solid var(--line)}
.ios-row{display:flex;flex-direction:column;gap:2px;padding:9px 16px;border-bottom:1px solid var(--line);min-height:48px;justify-content:center;position:relative}
.ios-card>.ios-row:last-child,.field-pair{border-bottom:none}
.ios-card>*:last-child{border-bottom:none}
.ios-row span{font-size:12px;color:var(--muted);font-weight:600}
.ios-row span em{font-style:normal;font-weight:600;color:var(--ink);text-decoration:underline;text-decoration-style:dotted;text-decoration-color:rgba(0,32,91,.4);text-underline-offset:2px}
.ios-row input{border:0;outline:0;font-size:16px;padding:2px 0;background:transparent;min-height:24px;color:var(--ink);width:100%}
.ios-row input::placeholder{color:#A3AAC4}
.ios-row:focus-within{background:var(--blue-soft)}

/* Optional fields (Apt/Unit) collapse behind a native <details> so they stay
   out of the way until someone actually needs them — no JS, no ARIA to keep
   in sync, and it re-opens automatically when a value is already present. */
.optional-row{padding-top:0;padding-bottom:0}
.optional-row>summary{
  list-style:none;cursor:pointer;padding:20px 0;
  font-size:12.5px;color:var(--muted);font-weight:600;
  display:flex;align-items:center;gap:6px;
}
.optional-row>summary::-webkit-details-marker{display:none}
.optional-row>summary::after{
  content:"";width:7px;height:7px;margin-left:auto;
  border-right:1.6px solid var(--muted);border-bottom:1.6px solid var(--muted);
  transform:rotate(45deg) translate(-2px,-2px);transition:transform .18s ease;
}
.optional-row[open]>summary::after{transform:rotate(-135deg) translate(-2px,-2px)}
.optional-row>summary em{font-style:normal;font-weight:600;color:var(--ink);text-decoration:underline;text-decoration-style:dotted;text-decoration-color:rgba(0,32,91,.4);text-underline-offset:2px}
.optional-row>input{padding-bottom:14px}
@media(prefers-reduced-motion: reduce){.optional-row>summary::after{transition:none}}

/* Centered as a single MM / DD / YYYY group rather than left-flushed. */
.dob-row{padding-top:6px;padding-bottom:6px}
.dob-row .dob-inputs{display:flex;align-items:center;gap:8px;width:100%}
.dob-inputs input{
  width:46px;flex:none;text-align:center;letter-spacing:.03em;font-weight:600;
  border:1.5px solid var(--line)!important;border-radius:8px;padding:4px 0!important;
  background:#fff;font-size:16px;
}
.dob-inputs input:last-of-type{width:64px}
.dob-inputs input:focus{border-color:var(--ink)!important;background:#fff!important}
.dob-sep{color:#A3AAC4;font-weight:700}

.address-row .address-suggestions{position:relative}
.address-suggestions{margin-top:2px}
/* In normal flow, NOT floating over the fields below it. As an overlay this
   covered the phone and email rows while the visitor typed, which reads as
   those fields having vanished — the opposite of reassuring for someone
   already unsure whether they are filling the form in correctly. Pushing the
   rest of the form down instead keeps everything visible and makes the list
   obviously part of the address field. */
.address-suggestions:not(:empty){
  position:static;margin-top:6px;
  background:#fff;border-radius:var(--radius-sm);box-shadow:var(--shadow-md);
  border:1px solid var(--line);overflow:hidden;max-height:280px;overflow-y:auto;
}
.suggestion-item{display:flex;flex-direction:column;gap:2px;width:100%;min-height:48px;justify-content:center;text-align:left;padding:11px 14px;border:0;border-bottom:1px solid var(--line);background:#fff;cursor:pointer}
.suggestion-item:last-child{border-bottom:none}
.suggestion-item:hover,.suggestion-item:focus{background:var(--blue-soft)}
.suggestion-line1{font-size:15px;font-weight:600;color:var(--ink)}
.suggestion-line2{font-size:13px;color:var(--muted)}
.field-hint{font-size:13px;color:var(--muted);padding:6px 16px 10px}
.field-hint.is-confirmed{color:var(--green);font-weight:700}
/* Flashed on the hint when someone submits without picking a suggestion —
   draws the eye to the one instruction that unblocks them. */
.field-hint.is-nudge{color:var(--red);font-weight:700}

.form-error{color:var(--red);font-size:14px;font-weight:600;min-height:18px;margin:14px 2px 0}

/* Buttons. Primary = solid navy; secondary = quiet outline. 12px radius for
   the softer, more current feel of the 2026-08 redesign (was the campaign
   site's flat 4px). */
.sticky-cta{position:sticky;bottom:0;padding:14px 0 10px;margin-top:6px;background:linear-gradient(to top,var(--page) 55%,transparent)}
.cta-button{
  display:block;width:100%;min-height:52px;border:1.5px solid var(--ink);border-radius:12px;
  background:var(--ink);color:#fff;
  font-weight:600;font-size:16.5px;cursor:pointer;letter-spacing:0;
  transition:opacity .15s,transform .15s;
}
.cta-button:active{opacity:.85;transform:scale(.99)}
.cta-button:disabled{opacity:.5;cursor:default}
.cta-button.link-button{display:flex;align-items:center;justify-content:center;text-decoration:none}
.secondary-button{
  background:#fff;border:1.5px solid var(--line);color:var(--ink);border-radius:12px;
  min-height:48px;font-weight:600;font-size:15px;cursor:pointer;
}
.secondary-button.link-button{display:flex;align-items:center;justify-content:center;text-decoration:none}
.text-button{background:none;border:0;color:var(--ink);font-weight:600;font-size:13.5px;padding:8px 0;cursor:pointer;text-decoration:underline}

/* Required-field marker. Campaign red, the same accent the eyebrow uses, so
   it reads as "attention" rather than as an error that already happened. */
.req{color:var(--campaign-red);font-style:normal;font-weight:700;margin-left:1px}
/* The field a validation message is about. Red rule down the side plus a
   tinted ground, so it is findable when the message is at the bottom of the
   form and the field is halfway up it. */
.ios-row.is-invalid{background:var(--red-soft);box-shadow:inset 3px 0 0 var(--red)}
.ios-row.is-invalid input,.ios-row.is-invalid textarea{background:transparent}
input[aria-invalid="true"],textarea[aria-invalid="true"]{outline:none}
@media(prefers-reduced-motion: reduce){.cta-button{transition:opacity .15s}}

/* ---------- Result: checking state ---------- */
.visually-hidden{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
.checking-panel{padding:120px 0;display:flex;justify-content:center}
.spinner{width:36px;height:36px;border-radius:50%;border:3px solid rgba(0,32,91,.1);border-top-color:var(--ink);animation:spin .9s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
@media(prefers-reduced-motion: reduce){.spinner{animation:none}}

/* ---------- Result body ---------- */
#result-body{padding-top:20px;display:flex;flex-direction:column;gap:18px}
.map-card{padding:0}
.map-card #result-map,.map-panel #map{height:300px;width:100%;background:#eef1fa}

/* Matched address sits at the bottom of the map card, under the legend. */
.map-card .matched-address{padding:12px 16px 14px;border-top:1px solid var(--line)}
.matched-address{display:flex;flex-direction:column;gap:4px}
/* Factual in/out verdict beside the ADDRESS CHECKED label — driven by the
   same point-in-polygon result as the status card, never inferred. */
.tx15-pill{
  display:inline-block;margin-left:8px;padding:2px 9px;border-radius:999px;
  font-size:10.5px;font-weight:800;letter-spacing:.04em;vertical-align:1px;
}
.tx15-pill.inside{background:var(--green-soft);color:var(--green)}
.tx15-pill.outside{background:var(--red-soft);color:var(--red)}
.matched-address span{font-size:11px;font-weight:700;color:var(--muted);text-transform:uppercase;letter-spacing:.05em}
.matched-address strong{font-size:15px;color:var(--ink);font-weight:600;line-height:1.4}
.matched-address .address-warning{font-size:12.5px;font-weight:700;color:#B9770E;text-transform:none;letter-spacing:0}

.status-card{padding:24px 20px 6px;text-align:center}
.status-icon{
  width:52px;height:52px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  font-size:22px;font-weight:700;margin:0 auto 14px;
}
.status-card h2{font-size:21px;font-weight:600;margin:0 0 8px;letter-spacing:-.01em}
.status-card p{font-size:15px;color:var(--ink-soft);margin:0 0 16px;line-height:1.6}
.status-card .cta-button,.status-card .secondary-button{margin-top:4px;margin-bottom:18px}
.status-success .status-icon{background:var(--green-soft);color:var(--green)}
.status-review .status-icon{background:var(--amber-soft);color:#B9770E}
.status-outside .status-icon{background:var(--red-soft);color:var(--red)}
.status-checking .status-icon{background:var(--blue-soft);color:var(--muted)}

.dash-card h4{margin:0 0 4px;padding:16px 18px 6px;font-size:11px;font-weight:700;letter-spacing:.06em;text-transform:uppercase;color:var(--muted)}
.dash-row{display:flex;justify-content:space-between;gap:12px;padding:12px 18px;border-top:1px solid var(--line);font-size:14px}
.dash-row span{color:var(--muted)}
.dash-row b,.dash-row a{color:var(--ink);font-weight:600;text-align:right;text-decoration:none;white-space:nowrap}
.dash-row a{text-decoration:underline}
/* "Previously District NN" note under the district pill — context, not a
   category, so it stays quiet muted text rather than joining the pill
   palette. flex-basis:100% drops it onto its own line in the flex row. */
.dash-row .dash-sub{font-size:11.5px;font-weight:600;color:var(--muted);letter-spacing:.01em}
.dash-row b .dash-sub-stacked{flex-basis:100%;text-align:right}
/* Every value on this card is a PASS 4 pill; rows flex-wrap so a long pill
   drops to its own line instead of shrinking or overflowing. */
.dash-row{align-items:center}
.dash-row b{display:flex;flex-wrap:wrap;justify-content:flex-end;align-items:center;gap:6px;white-space:normal}

/* Page-2 bottom actions: the officials CTA is the prominent next step; the
   "check a different address" restart sits under it as a quiet secondary. */
.result-actions{display:flex;flex-direction:column;gap:10px;padding:2px 0 4px}
.result-actions .secondary-button{align-self:center;min-width:220px;padding-left:20px;padding-right:20px}
/* The restart action as a quiet centered text link, pushed clear of the
   button above it so the two can't be confused or mis-tapped. */
.result-actions .restart-link{align-self:center;margin-top:10px;min-height:44px;color:var(--muted);font-size:13.5px}
/* Page 4's two quiet escape hatches (restart + report an error) share one
   compact section under a single divider. */
/* Both links sit symmetrically between the divider above and the footer
   rule below — same 10px breathing room top and bottom, nothing dead in
   between, and both in the same darker ink-soft so neither looks disabled. */
.officials-bottom-links{
  border-top:1px solid var(--line);
  margin-top:14px;padding:4px 0;display:flex;flex-direction:column;align-items:center;
}
.officials-bottom-links .restart-link,
.officials-bottom-links .officials-feedback-trigger{
  margin:0;min-height:0;padding:10px 6px;color:var(--ink-soft);font-size:13.5px;font-weight:600;
}
.officials-bottom-links .officials-feedback-panel{width:100%}

/* ---------- Officials page (page 3) ---------- */
.officials-page-header{padding:26px 0 14px;text-align:center}
.officials-page-header h2{font-size:clamp(24px,6vw,32px);font-weight:600;margin:0 0 6px;color:var(--ink);letter-spacing:-.01em}
.officials-page-header p{margin:0;font-size:14.5px;color:var(--muted)}
#officials-page-body{display:flex;flex-direction:column;gap:16px}
.tier-card{padding:0;scroll-margin-top:10px}
/* Title and count read as one unit on the left, chevron pinned right.
   space-between used to spread all three children apart, which left the count
   pill floating at a different x on every card (it tracked the title's width)
   and pushed the title itself hard into the card's 14px corner radius. */
.tier-summary{
  list-style:none;cursor:pointer;display:flex;align-items:center;justify-content:flex-start;
  gap:10px;padding:15px 20px;min-height:56px;
}
.tier-summary::-webkit-details-marker{display:none}
.tier-summary h3{margin:0;font-size:19px;font-weight:600;color:var(--ink);letter-spacing:-.01em}
.tier-summary .tier-meta{display:flex;align-items:center;gap:10px}
/* Verified-count chip styling comes from the PASS 4 pill system. */
.tier-summary::after{
  content:"";width:8px;height:8px;flex:none;
  border-right:1.8px solid var(--muted);border-bottom:1.8px solid var(--muted);
  transform:rotate(45deg);transition:transform .18s ease;margin-left:auto;
}
.tier-card[open]>.tier-summary::after{transform:rotate(-135deg)}
@media(prefers-reduced-motion: reduce){.tier-summary::after{transition:none}}
.tier-card .official-list{padding:0 18px 16px;border-top:1px solid var(--line)}
.officials-pending{padding:40px 0;display:flex;justify-content:center}

.official-row{display:flex;flex-direction:column;gap:2px;padding:12px 0;border-bottom:1px solid var(--line)}
.official-row:last-child{border-bottom:none}
.official-row strong{font-size:15.5px;color:var(--ink);font-weight:600}
.official-row strong a{color:inherit;text-decoration:none}
.official-row strong a:hover{text-decoration:underline}
.official-title{font-size:13px;color:var(--muted);font-weight:600}
/* Term line — "In office since 2023 · Next election 2026". Deliberately
   quieter than the title: it is context, not the answer the visitor came for,
   and it is absent on ~59% of entries, so it must not leave an obvious hole
   in the rows that lack it. */
/* Colors/geometry come from the pill system; this positions the chip on
   its own line under the title. align-self stops the row's column-flex
   from stretching any pill to the card's full width. */
.official-term{margin-top:5px}
.official-row .pill{align-self:flex-start}
.official-contact{font-size:13.5px;color:var(--ink-soft)}
.official-contact a{color:inherit;text-decoration:underline}
.official-note{font-size:12px;color:var(--muted);font-style:italic}
.party-badge{display:inline-block;font-size:10px;font-weight:700;padding:1px 5px;border-radius:5px;vertical-align:middle;letter-spacing:.02em}
/* Personalized "Your commissioner" badge: pill system (pill--yours). */
.party-badge.party-d{background:#E5EEFF;color:#1E4FBF}
.party-badge.party-r{background:var(--campaign-red-soft);color:var(--campaign-red)}
.party-badge.party-other{background:var(--line);color:var(--muted)}
.official-row-empty{padding:12px 0}
.official-row-empty .muted-note{color:var(--muted);font-weight:600;font-size:13.5px}

.official-subgroup-label{
  padding:12px 0 2px;margin-top:4px;font-size:11px;font-weight:700;
  letter-spacing:.06em;text-transform:uppercase;color:var(--muted);
}
.official-subgroup-label:first-child{margin-top:0}

/* Population sits centered at the top of each open tier card; its look is
   the PASS 4 population pill — informational, never a solid CTA-blue. */
.population-pill-row{display:flex;justify-content:center;padding:12px 0 4px}

.official-more{border-bottom:1px solid var(--line);padding:6px 0}
.official-more:last-child{border-bottom:none}
.official-more .official-row{border-bottom:none;padding:10px 0 0}
.official-more-toggle{cursor:pointer;font-size:13.5px;font-weight:600;color:var(--campaign-red);list-style:none;padding:10px 0;min-height:44px;display:flex;align-items:center}
.official-more-toggle::-webkit-details-marker{display:none}
.official-more-toggle::before{content:'+ ';font-weight:700;margin-right:2px}
.official-more[open]>.official-more-toggle::before{content:'– '}

/* "About this role" — a quiet per-office disclosure with a 1-2 sentence
   plain-language description of what the office actually does. */
.role-about{margin-top:2px}
.role-about>summary{
  list-style:none;cursor:pointer;display:inline-flex;align-items:center;min-height:32px;
  font-size:12.5px;font-weight:600;color:var(--map-district);
}
.role-about>summary::-webkit-details-marker{display:none}
.role-about>summary::after{content:"▸";margin-left:4px;font-size:10px;transition:transform .15s}
.role-about[open]>summary::after{transform:rotate(90deg)}
.role-about>p{
  margin:6px 0 4px;padding:10px 12px;border-radius:10px;
  background:var(--blue-soft);font-size:13.5px;color:var(--ink-soft);line-height:1.55;
}
@media(prefers-reduced-motion: reduce){.role-about>summary::after{transition:none}}

.officials-feedback{border-top:1px solid var(--line);padding:12px 16px 4px;text-align:center}
.officials-feedback-trigger{background:none;border:none;padding:10px 6px;min-height:44px;font-size:13.5px;font-weight:600;color:var(--muted);text-decoration:underline;cursor:pointer}
.officials-feedback-panel[hidden]{display:none}
.officials-feedback-panel .help-card-inline{margin:0;border-top:none;padding-top:10px}
.officials-feedback-panel .help-card-inline h4{padding:0 0 4px}
.officials-feedback-panel .help-card-inline p{padding:0 0 12px}
.officials-feedback-panel .help-card-inline form{padding:0 0 6px}
.officials-feedback-panel .help-sent-message{padding:0}
.officials-feedback-panel textarea{border:1px solid var(--line);border-radius:8px;margin-bottom:10px;padding:11px 14px;font:inherit;resize:vertical;min-height:64px}
.officials-feedback-cancel{background:none;border:none;padding:10px 0;min-height:44px;font-size:13.5px;font-weight:600;color:var(--muted);text-decoration:underline;cursor:pointer;align-self:flex-start}

.help-card-inline{border-top:1px solid var(--line);margin:0 -20px;padding-top:18px;text-align:left}
.help-card-inline h4{padding:0 20px 4px;margin:0;font-size:16px;font-weight:600;color:var(--ink)}
.help-card-inline p{margin:0;padding:0 20px 12px;font-size:13.5px;color:var(--muted);line-height:1.5}
.help-card-inline form{padding:0 20px 18px;display:flex;flex-direction:column;gap:2px}
.help-card-inline .ios-row{border:1px solid var(--line);border-radius:10px;margin-bottom:10px;padding:11px 14px}
.help-card-done{padding-bottom:18px}
.help-sent-message{margin:0;padding:0 20px;font-size:14px;font-weight:600;color:var(--green)}
.consent-row{display:flex;align-items:flex-start;gap:10px;font-size:13.5px;color:var(--ink-soft);margin:6px 0 14px;line-height:1.4}
.consent-row input{margin-top:3px;width:18px;height:18px}
#help-status{font-size:13.5px;font-weight:600;margin:10px 0 0;min-height:16px}
#help-status.is-success{color:var(--green)}
#help-status.is-error{color:var(--red)}

.actions-row{display:grid;grid-template-columns:1fr;gap:10px;margin-top:4px;padding-bottom:8px;text-align:center}
.actions-row .secondary-button{width:100%;font-size:13.5px;padding-left:8px;padding-right:8px}

.check-another-row{padding:2px 4px 4px;text-align:center}
.check-another-row .secondary-button{display:inline-flex;align-items:center;justify-content:center;min-width:220px;padding-left:20px;padding-right:20px}

.details-officials-row{display:grid;grid-template-columns:1fr;gap:14px;align-items:start}

/* ---------- Map ---------- */
.campaign-pin{width:42px;height:42px;border-radius:50% 50% 50% 8px;transform:rotate(-45deg);background:var(--ink);border:4px solid #fff;box-shadow:0 8px 20px rgba(0,32,91,.35);display:grid;place-items:center}
.campaign-pin span{transform:rotate(45deg);color:#fff;font-weight:700;font-size:13px}
.county-label{width:auto!important;height:auto!important;margin:0!important;overflow:visible!important;background:transparent!important;border:0!important;pointer-events:none!important}
/* font-size deliberately NOT !important: map.js's updateLabelScale() sets the
   real size (10-14px by zoom) as an inline style, which an !important rule
   here silently overrode — that was the "labels stuck tiny" bug. This is only
   the pre-first-zoom fallback. */
.county-label span{
  display:block!important;width:max-content!important;max-width:none!important;padding:0!important;overflow:visible!important;
  white-space:nowrap!important;line-height:1!important;letter-spacing:.02em!important;
  color:var(--map-county-label)!important;font-size:11px;font-weight:600!important;
  font-family:var(--font-ui)!important;
  background:transparent!important;border:0!important;box-shadow:none!important;
  transform:translate(-50%,-50%);
  text-shadow:-1px -1px 0 #fff,1px -1px 0 #fff,-1px 1px 0 #fff,1px 1px 0 #fff!important;
  transition:font-size .15s;
}
.leaflet-container{font-family:inherit}

/* One-finger-drag hint: shown briefly over the map on touch devices when
   someone tries to pan with one finger (drag is two-finger there so the page
   itself stays scrollable). Toggled by map.js. */
.map-touch-hint{
  position:absolute;inset:0;z-index:600;display:flex;align-items:center;justify-content:center;
  background:rgba(0,32,91,.35);opacity:0;pointer-events:none;transition:opacity .25s;
}
.map-touch-hint.is-visible{opacity:1}
.map-touch-hint span{
  background:rgba(255,255,255,.95);color:var(--ink);font-size:14px;font-weight:600;
  padding:10px 16px;border-radius:10px;box-shadow:var(--shadow-md);text-align:center;max-width:80%;
}
@media(prefers-reduced-motion: reduce){.map-touch-hint{transition:none}}

/* ---------- Map legend ---------- */
/* One row at 375px, never wraps: nowrap on the container plus swatches and
   gaps sized so "TX-15 boundary / Counties / Voting District" fits. */
.map-legend{display:flex;flex-wrap:nowrap;justify-content:center;align-items:center;gap:0 10px;padding:6px 8px}
.map-legend-item{display:inline-flex;align-items:center;gap:4px;color:var(--muted);white-space:nowrap;min-width:0}
.map-legend-swatch{width:13px;height:0;flex:none}
.map-legend-swatch.solid{border-top:3px solid var(--map-district)}
.map-legend-swatch.dashed{border-top:2px dashed var(--map-county)}
.map-legend-swatch.precinct{border-top:2px dashed var(--map-precinct)}
.map-legend-item span{font-size:10.5px;color:var(--ink-soft);font-weight:600}
@media(max-width:360px){.map-legend-item span{font-size:9.5px}.map-legend{gap:0 7px}}
.map-status{position:absolute;left:12px;right:12px;bottom:12px;z-index:500;margin:0;padding:10px 12px;border-radius:8px;background:rgba(255,255,255,.94);color:var(--red);font-size:12.5px;line-height:1.4;box-shadow:var(--shadow-md)}
.map-status:empty{display:none}

/* ---------- Desktop ---------- */
@media(min-width:760px){
  main{max-width:900px;padding:0 24px 24px}
  .hero-copy{padding-top:40px}
  #result-body{display:grid;grid-template-columns:1fr 1fr;align-items:start}
  .map-card,.status-card,#registration-help-card,.details-officials-row,.result-actions,.check-another-row{grid-column:1/-1}
  .map-card #result-map{height:360px}
  .status-card{padding:28px 32px 6px}
  .help-card-inline{margin:0 -32px}
  .help-card-inline h4{padding:0 32px 4px}
  .help-card-inline p{padding:0 32px 12px}
  .help-card-inline form{padding:0 32px 18px}
  .help-sent-message{padding:0 32px}
  #officials-page-body{display:grid;grid-template-columns:1fr 1fr;gap:16px;align-items:start}
  .officials-page-actions{grid-column:1/-1}
}
/* ---------- Footer ---------- */
.site-footer{
  /* 14px, not 36px: the page's last section already ends on its own rule,
     so a large margin here read as dead space under "Report an error". */
  max-width:560px;margin:14px auto 0;padding:24px 20px 32px;
  border-top:1px solid var(--line);
  text-align:center;
}
.footer-brand-row{margin-bottom:14px}
/* Campaign logo and MyTX15 wordmark as one side-by-side lockup. */
.footer-brand-lockup{display:flex;align-items:center;justify-content:center;gap:10px}
.footer-logo{height:34px;width:auto;display:block;margin:0}
.footer-brand-name{font-size:17px;font-weight:800;letter-spacing:-.01em;color:var(--ink);font-family:var(--font-heading);text-decoration:none}
.footer-brand-name:active{opacity:.8}
.footer-brand-name span{color:var(--blue)}
.footer-tagline{margin:3px 0 0;font-size:12.5px;color:var(--muted)}
.paid-for-box{
  display:block;margin:12px auto 0;padding:9px 16px;max-width:420px;
  border:2px solid var(--ink);border-radius:8px;
  background:transparent;color:var(--ink);
  font-size:12px;font-weight:800;letter-spacing:.03em;text-transform:uppercase;
}

/* No separators between the legal links, tighter rows. */
.footer-nav{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:0 6px;margin-bottom:14px}
.footer-nav button{
  background:none;border:0;padding:4px 10px;min-height:40px;font-size:13px;font-weight:600;
  color:var(--ink-soft);cursor:pointer;text-decoration:none;line-height:1.4;
}
.footer-nav button:hover,.footer-nav button:focus-visible{color:var(--blue)}

.footer-note{margin:0 auto;max-width:440px;padding-top:16px;border-top:1px solid var(--line);font-size:12px;color:var(--muted);line-height:1.6}

.legal-dialog{
  border:0;border-radius:var(--radius-lg);padding:0;max-width:520px;width:92vw;max-height:82vh;
  box-shadow:var(--shadow-lg);
}
.legal-dialog::backdrop{background:rgba(11,18,48,.5);backdrop-filter:blur(2px)}
.legal-dialog>div{padding:26px 22px 30px;overflow-y:auto;max-height:82vh}
.legal-dialog h2{font-size:19px;font-weight:800;margin:0 0 14px;color:var(--ink)}
.legal-dialog h4{font-size:14.5px;font-weight:800;margin:18px 0 6px;color:var(--ink)}
.legal-dialog p{font-size:13.5px;color:var(--ink-soft);line-height:1.65;margin:0 0 12px}
.legal-dialog a{color:var(--blue)}
.dialog-close{
  position:sticky;float:right;top:14px;right:14px;margin:14px 14px 0 0;
  width:36px;height:36px;border-radius:50%;border:0;background:#EEF1F7;color:var(--ink-soft);
  font-size:18px;cursor:pointer;display:flex;align-items:center;justify-content:center;
}

@media(min-width:1000px){
  .site-footer,main{max-width:960px}
}

/* =====================================================================
   2026-08 CONTINUOUS-SITE RESTYLE (Marco's direction, reaffirmed)
   Pages 1-4 read as one website: page 1 on pulidoevents.com is a
   look-alike of this app's form, so this block makes the app match that
   design language exactly — white page, Lora serif display (700 roman +
   700 italic, self-hosted; Google Fonts is blocked by our CSP), 2px navy
   cards on 10px radii, quiet #D0D5E0 input borders with a soft navy focus
   ring, solid navy CTA set in the display face. Appended last so it wins
   the cascade over the token system above without rewriting it.
   ===================================================================== */
@font-face{font-family:"Lora";src:url("assets/fonts/Lora-700.woff2") format("woff2");
  font-weight:700;font-style:normal;font-display:swap}
@font-face{font-family:"Lora";src:url("assets/fonts/Lora-700-Italic.woff2") format("woff2");
  font-weight:700;font-style:italic;font-display:swap}

body{background:#FFFFFF}
:root{--page:#FFFFFF;--line:#EDEFF5;--radius-md:10px}
h1,h2,h3,.form-heading h1,.map-caption strong,.tier-summary h3{
  font-family:"Lora",Georgia,"Times New Roman",serif;font-weight:700}
.hero-copy h1{font-style:italic;letter-spacing:-.8px}

.ios-card,.intake-card,.dash-card,.tier-card,.status-card,.address-card,.map-card,
.officials-feedback-card,.help-card-inline{
  border:2px solid var(--ink);border-radius:10px;
  box-shadow:0 2px 8px rgba(0,32,91,.06)}

input,textarea,select{border-color:#D0D5E0}
input:focus,textarea:focus{
  outline:none;border-color:var(--ink);box-shadow:0 0 0 4px rgba(0,32,91,.06)}

.cta-button{
  font-family:"Lora",Georgia,serif;font-weight:700;letter-spacing:.3px;
  border:2px solid var(--ink);border-radius:6px;background:var(--ink)}
.cta-button:active{opacity:.92;transform:translateY(1px)}
.secondary-button{border-radius:6px}

.topbar::after{background:#EDEFF5}

/* --- Continuous-site restyle, pass 2: the chrome. Pass 1 above carried the
   tokens (white page, Lora, navy cards); Marco's review said the app still
   read as the old design, and he is right - the header pills, the blue-tint
   chips on the result and officials screens, and the footer were untouched.
   This finishes the job: every piece of shared chrome now matches page 1's
   language exactly - hairline dividers, bordered white chips instead of
   tinted fills, square EN/ES buttons, the bordered uppercase paid-for box. */

/* Header: logo left, square language chips right, hairline below. */
.topbar{border-bottom:1px solid #EDEFF5;padding:18px 16px}
.topbar::after{display:none}
.cycle-badge{display:none!important}
.language-toggle{background:transparent;padding:0;gap:6px}
.language-toggle button{
  border:1.5px solid #D0D5E0;background:#fff;border-radius:5px;
  min-height:34px;padding:6px 11px;font-size:11px;letter-spacing:.5px;color:#777}
.language-toggle button.is-active{
  background:var(--ink);color:#fff;border-color:var(--ink);box-shadow:none}

/* Hero text matches the draft's rhythm. */
.hero-copy h1{letter-spacing:-.8px}
.hero-subtitle,.hero-copy p{color:#555}

/* Chips now come from the PASS 4 pill system at the end of this file —
   one geometry, per-category tints. (A previous pass flattened every chip
   to bordered white, which made district, election, and verified-count
   information all read as the same thing.) */
.party-badge{background:#fff;border:1px solid #D0D5E0}

/* Quiet buttons: white with navy border, matching the CTA family. */
.secondary-button{
  background:#fff;border:1.5px solid var(--ink);color:var(--ink);
  border-radius:6px;font-weight:600}

/* Footer: hairline top, Lora lockup, bordered uppercase paid-for box,
   tiny gray legal row - the draft's footer, verbatim. */
.site-footer{border-top:1px solid #EDEFF5;background:#fff;margin-top:40px;
  padding:40px 20px 20px;text-align:center}
.footer-brand-name{font-family:"Lora",Georgia,serif;font-weight:800;
  font-size:20px;color:var(--ink);letter-spacing:-.3px}
.paid-for-box{
  margin:16px auto 0;padding:12px 20px;max-width:420px;
  border:2px solid var(--ink);border-radius:6px;background:transparent;
  color:var(--ink);font-size:11px;font-weight:800;letter-spacing:.8px;
  text-transform:uppercase;font-family:"Lora",Georgia,serif}
.footer-nav{gap:4px 8px;font-size:10px}
.footer-nav button{color:#777;font-weight:500;font-size:10px;background:none;border:0}
.footer-nav button:hover{color:var(--ink)}
.footer-note{max-width:480px;margin:12px auto 0;padding-top:20px;
  border-top:1px solid #EDEFF5;font-size:12px;color:#777;line-height:1.8}

/* Home map card, matched to the comp: bordered navy card, Lora tag, gray
   caption, the live OSM embed filling the card's width. */
.home-map-card{background:#fff;border:2px solid var(--ink);border-radius:10px;
  box-shadow:0 2px 8px rgba(0,32,91,.06);overflow:hidden;margin:0 auto 64px;padding:0}
.home-map-tag{font-family:"Lora",Georgia,serif;font-size:clamp(22px,3vw,28px);
  font-weight:700;color:var(--ink);letter-spacing:-.3px;padding:24px 28px 0;margin:0;text-align:left}
.home-map-cap{padding:12px 28px 20px;font-size:14px;color:#666;margin:0;line-height:1.6;text-align:left}
.home-map-frame{width:100%;height:500px;border:0;display:block;background:#F7F8F9}
.home-map-cta-row{display:none}
@media(max-width:560px){.home-map-card{margin:0 0 48px;border-radius:8px}
  .home-map-tag{font-size:20px;padding:18px 18px 0}.home-map-cap{padding:10px 18px 16px}}
/* The comp's tag is sentence-case Lora on white; an earlier rule was
   uppercasing it onto a tinted band. */
.home-map-tag{text-transform:none;background:transparent;letter-spacing:-.3px}
.home-map-cap{background:transparent}

/* =====================================================================
   PASS 3 — pages 1 and 2 matched to Marco's mockup (2026-08-14)
   Three things change from pass 2: card headings become large left-aligned
   Lora rather than small centred labels, the benefits block becomes ONE
   card of numbered rows instead of four tiles with green ticks, and the
   district map is a real Leaflet canvas instead of an iframe.
   ===================================================================== */

/* --- Intake card ------------------------------------------------------
   The comp leads each card with a large left-aligned Lora line. The old
   intake-head centred a small heading over a subtitle, which read as a
   form label rather than a section opening. */
.intake-card{padding:28px;border-radius:12px}
.intake-head{margin:0 0 22px;text-align:left}
.intake-head h2{
  font-family:"Lora",Georgia,serif;font-weight:700;
  font-size:clamp(26px,5.2vw,34px);line-height:1.15;letter-spacing:-.5px;
  color:var(--ink);margin:0;text-align:left}
.intake-head small{
  display:block;margin-top:8px;font-size:15px;color:#666;line-height:1.55}

.intake-card .field{margin-bottom:18px}
.intake-card label,.intake-card .field-label{
  display:block;margin-bottom:7px;
  font-size:15px;font-weight:700;color:var(--ink)}
.intake-card label em,.intake-card .field-label em{
  font-style:normal;font-weight:500;color:#666}
.req{color:#AD0B32;font-style:normal;font-weight:700}

.intake-card input{
  width:100%;padding:14px 16px;font-size:16px;
  border:1.5px solid #D0D5E0;border-radius:8px;background:#fff;color:var(--ink)}
.intake-card input::placeholder{color:#9AA3B5}
.dob-shell{border:1.5px solid #D0D5E0;border-radius:8px;padding:0 10px}
/* Two classes deep on purpose: `.intake-card input` above sets width:100%,
   which the three DOB boxes must NOT inherit — they are flex children of a
   shared shell, and at 100% each they push the slashes off the card edge. */
.intake-card .dob-shell input{
  width:44px;flex:none;border:0;padding:14px 0;text-align:center}
.intake-card .dob-shell input:last-of-type{width:64px}
.dob-sep{color:#C2C9D8}

/* Phone and email each get their own row at every width (Marco, 2026-08-14 —
   he saw the two-column version and chose stacked). */
.pair{display:grid;grid-template-columns:1fr;gap:0}

.intake-card .cta-button{
  width:100%;margin-top:6px;padding:17px 20px;font-size:17px;border-radius:8px}

/* --- Benefits: one card, numbered rows --------------------------------
   Was four bordered tiles each with a green check. The comp is a single
   card whose rows are separated by hairlines and led by an outlined red
   numeral, so the list reads as a sequence rather than four claims. */
.home-benefits{
  background:#fff;border:2px solid var(--ink);border-radius:12px;
  box-shadow:0 2px 8px rgba(0,32,91,.06);
  padding:28px 28px 4px;margin:0 auto 28px}
.benefits-lead{
  font-family:"Lora",Georgia,serif;font-weight:700;
  font-size:clamp(24px,4.6vw,30px);line-height:1.2;letter-spacing:-.4px;
  color:var(--ink);margin:0 0 4px;text-align:left}
.benefit-grid{display:block;margin:0;padding:0;gap:0}
.benefit-card{
  display:flex;align-items:flex-start;gap:18px;
  background:transparent;border:0;border-radius:0;box-shadow:none;
  padding:22px 0;margin:0;border-bottom:1px solid #EDEFF5}
.benefit-card:last-child{border-bottom:0}
.benefit-num{
  flex:none;width:42px;height:42px;border-radius:50%;
  border:2px solid #AD0B32;color:#AD0B32;background:#fff;
  display:flex;align-items:center;justify-content:center;
  font-size:14px;font-weight:800;letter-spacing:.02em}
.benefit-text{display:block}
.benefit-text b{
  display:block;font-size:16px;font-weight:700;color:var(--ink);margin-bottom:5px}
.benefit-text span{display:block;font-size:15px;color:#666;line-height:1.6}

/* --- District map (the GitHub Pages embed, same as page 1) ------------ */
/* An earlier pass gave the tag a bottom rule, which the comp does not have —
   there the heading and its caption read as one block above the map. */
.home-map-tag{border-bottom:0}
.home-map-frame{border-top:1px solid #EDEFF5}

/* --- One width for all three cards ------------------------------------
   Marco's spec: the form, map and benefits cards read as the same component
   at every viewport. 560px cap, centred. Without this the desktop media
   query widens main to 900px and the map/benefits cards grow past the form
   (which .info-form already caps at 560). */
.info-form,.home-map-card,.home-benefits{
  max-width:560px;margin-left:auto;margin-right:auto}
.home-map-card{margin-bottom:28px}

/* Helper line pinned to the top of the address-suggestions dropdown. */
.suggest-helper{
  padding:10px 14px;font-size:12px;color:#666;
  border-bottom:1px solid #EDEFF5;line-height:1.5}

/* --- Condensed legal row, all five, every page ------------------------ */
.footer-nav{
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:2px 6px;font-size:10px}
.footer-nav button{
  padding:4px 2px;font-size:10px;color:#777;font-weight:500;line-height:1.4}
.footer-nav button+button::before{
  content:"·";margin-right:8px;color:#C2C9D8}

@media(max-width:560px){
  .intake-card{padding:20px}
  .home-benefits{padding:20px 20px 2px}
  .benefit-card{gap:14px;padding:18px 0}
  .benefit-num{width:36px;height:36px;font-size:13px}
  .home-map-frame{height:380px}
}

/* ======================================================================
   PASS 4 (Marco, 2026-08-14): one pill system, everywhere.
   ONE base class owns geometry; variants change ONLY color. Importance is
   placement and label, never size: no pill grows taller or louder because
   its text matters more. Gray is reserved for unavailable/pending — the
   Coming Soon pill is the only neutral gray on either page.
   Size classes: --sm gives short numerics (40, 0106, Pct 4) a floor so
   they don't shrivel next to text pills; --md for one-word values; long
   values just grow wider at the same height. --wrap is for the one pill
   holding a sentence (CWPP).
   ====================================================================== */
.pill{
  display:inline-flex;align-items:center;justify-content:center;
  box-sizing:border-box;min-height:28px;padding:4px 12px;border-radius:999px;
  font-size:11.5px;font-weight:700;line-height:1.15;letter-spacing:.01em;
  border:1px solid transparent;white-space:nowrap;vertical-align:middle;
  max-width:100%;
}
.pill--sm{min-width:64px}
.pill--md{min-width:92px}
.pill--wrap{white-space:normal;height:auto;line-height:1.35;text-align:center}

/* Category tints: soft background, dark readable text. One category, one
   color — every Next-election pill matches every other, on every official,
   in both languages. */
/* ================= PILL COLORS — EDIT HERE ==========================
   Marco: change any pill's colors by editing ONLY these variables.
   Each pill has two: *-bg is the fill, *-ink is the text. Nothing else
   in the file needs touching — the rules below just read these.
   Rules of the palette: one category = one color everywhere, in both
   languages; gray belongs to pending/unavailable and nothing else.
   ==================================================================== */
:root{
  --pill-district-bg:#D8E7FF;        --pill-district-ink:#1859A9;
  --pill-representative-bg:#E7DAF8;  --pill-representative-ink:#65429B;
  --pill-county-bg:#CFEEE9;          --pill-county-ink:#127A6E;
  --pill-county-precinct-bg:#FFE3C9; --pill-county-precinct-ink:#A85518;
  --pill-voting-precinct-bg:#F9D7E1; --pill-voting-precinct-ink:#A83D5D;
  --pill-house-bg:#D9DDF6;           --pill-house-ink:#4F56A6;
  --pill-senate-bg:#FFEDB3;          --pill-senate-ink:#8A6500;
  --pill-cwpp-bg:#CFF0DE;            --pill-cwpp-ink:#148257;
  --pill-pending-bg:#EEF0F4;         --pill-pending-ink:#687187;
  --pill-verified-bg:#E0D9F8;        --pill-verified-ink:#5B4BC4;
  --pill-election-bg:#C7E9F6;        --pill-election-ink:#17708F;
  --pill-population-bg:#E9F0CF;      --pill-population-ink:#5F7018;
  --pill-yours-bg:#DCE6F9;           --pill-yours-ink:#00205B;
}
.pill--district{background:var(--pill-district-bg);color:var(--pill-district-ink)}
.pill--representative{background:var(--pill-representative-bg);color:var(--pill-representative-ink)}
.pill--county{background:var(--pill-county-bg);color:var(--pill-county-ink)}
.pill--county-precinct{background:var(--pill-county-precinct-bg);color:var(--pill-county-precinct-ink)}
.pill--voting-precinct{background:var(--pill-voting-precinct-bg);color:var(--pill-voting-precinct-ink)}
.pill--house{background:var(--pill-house-bg);color:var(--pill-house-ink)}
.pill--senate{background:var(--pill-senate-bg);color:var(--pill-senate-ink)}
.pill--cwpp{background:var(--pill-cwpp-bg);color:var(--pill-cwpp-ink)}
/* The ONLY gray pill: information that is pending/unavailable. */
.pill--pending{background:var(--pill-pending-bg);color:var(--pill-pending-ink)}
.pill--verified{background:var(--pill-verified-bg);color:var(--pill-verified-ink)}
.pill--election{background:var(--pill-election-bg);color:var(--pill-election-ink)}
.pill--population{background:var(--pill-population-bg);color:var(--pill-population-ink)}
/* Personalized: this official answers to YOUR address. Filled navy tint
   with a navy border — the white/outline-only version read as an empty
   pill (Marco, 2026-08-14). */
.pill--yours{background:var(--pill-yours-bg);border-color:var(--ink);color:var(--pill-yours-ink)}

/* The verified-count chip must never crush the tier title or chevron:
   title and pill both keep their natural size and the header wraps to a
   second line when the two can't share one; the chevron is pinned to the
   right edge out of the flow so wrapping never displaces it. */
.tier-summary{flex-wrap:wrap;position:relative;padding-right:44px}
.tier-summary .pill,.tier-summary h3{flex:none}
.tier-summary::after{position:absolute;right:22px;top:50%;margin:-6px 0 0}
.tier-card[open]>.tier-summary::after{margin-top:-3px}

/* Tier accent: a small colored dot before the level name — five cards stay
   one component, the dot alone carries the level's identity. */
.tier-dot{width:10px;height:10px;border-radius:50%;flex:none}
.tier-card[data-tier="federal"] .tier-dot{background:#1769AA}
.tier-card[data-tier="state"] .tier-dot{background:#7048A8}
.tier-card[data-tier="county"] .tier-dot{background:#168C8C}
.tier-card[data-tier="city"] .tier-dot{background:#C66A28}
.tier-card[data-tier="school"] .tier-dot{background:#B94A68}

/* Inline pills riding an official's name line sit a notch smaller so the
   name stays the loudest thing in its row. Same geometry family. */
.official-row strong .pill{min-height:24px;padding:2px 9px;font-size:10.5px;margin-left:6px}

/* ---- Page 1/page 2 parity: same gaps, same padding (page 1 uses 26px
   between cards and 26/22 card padding; these bring page 2 to match). ---- */
.info-form{margin-bottom:0}
.home-map-card{margin:26px auto}
.home-benefits{margin:26px auto 0}
.intake-card{padding:26px 22px}
.home-benefits{padding:26px 22px 4px}
.home-map-frame{height:440px}
@media(max-width:560px){
  .intake-card{padding:20px 16px}
  .home-benefits{padding:20px 16px 2px}
  .home-map-frame{height:340px}
}

/* Help card inside the status card: pass 2 gave it a full navy border
   (a nested card) but kept the full-bleed negative margins from when it
   was a borderless section — which parked its border 2px from the parent
   card's, reading as two overlapping cards (Marco's page-3 report,
   2026-08-14). Inset it inside the parent's padding instead. */
.help-card-inline{margin:0 0 14px}

/* Page 4's two escape links, per Marco's sketch (2026-08-14): a rule
   above, the two links, a rule below, minimal padding after. Centered,
   with +10% breathing room over the first cut (padding 6->7, 10->11). */
.officials-bottom-links{
  border-top:1px solid var(--line);border-bottom:1px solid var(--line);
  margin-top:14px;padding:7px 0;align-items:center}
.officials-bottom-links .restart-link,
.officials-bottom-links .officials-feedback-trigger{
  text-decoration:underline;padding:11px 2px;text-align:center}

/* The help form's status line is an empty aria-live slot until something
   is worth saying — while empty it and its margins added ~60px of dead
   space under the Request-help button. */
#help-status:empty{display:none}

/* Footer hugs the page content — the old 40px top margin plus main's own
   16px bottom padding left a dead zone after page 4's bottom links (and
   every other page's last card). The footer's 40px top PADDING stays. */
.site-footer{margin-top:16px}

/* Breathing room between the "Official Texas voter lookup" link and the
   help card that follows it (Marco, 2026-08-14). */
#registration-help-card .help-card-inline{margin-top:28px}
