@charset "utf-8";
/* ==========================================================================
   लोकसंकल्प Site stylesheet
   Single stylesheet, no build step. Mobile-first. Devanagari-first typography.
   Sections: 1 reset · 2 base · 3 layout · 4 header/nav · 5 hero · 6 components
             · 7 sections · 8 forms · 9 footer · 10 utilities · 11 motion/print
   ========================================================================== */

/* ---------- 1. Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
[hidden] { display: none !important; }   /* class selectors otherwise beat it */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
img, svg, video { display: block; max-width: 100%; height: auto; }
button, input, select, textarea { font: inherit; color: inherit; }
ul[class], ol[class] { list-style: none; padding: 0; }
.site-nav ul, .site-footer ul, .crumbs ol, .hero__chips { list-style: none; padding: 0; }

/* ---------- 2. Base ---------- */
body {
  background: var(--ls-bg);
  color: var(--ls-ink);
  font-family: var(--ls-font-body);
  font-size: var(--ls-fs-body);
  line-height: var(--ls-lh-body);
  font-synthesis-weight: none;
  text-rendering: optimizeLegibility;
  overflow-x: hidden;
  overflow-wrap: break-word;
}

.wrap, .site-header__bar { max-width: 100%; }
h1, h2, h3, h4 {
  font-family: var(--ls-font-head);
  line-height: 1.35;
  color: var(--ls-blue-dark);
  font-weight: 700;
  text-wrap: balance;
}
h1 { font-size: var(--ls-fs-hero); }
h2 { font-size: var(--ls-fs-h2); }
h3 { font-size: clamp(1.2rem, 2.2vw, 1.5rem); }
p  { text-wrap: pretty; max-width: 68ch; }
a  { color: var(--ls-blue); text-underline-offset: .22em; text-decoration-thickness: .08em; }
a:hover { color: var(--ls-saffron-dk); }
strong { font-weight: 700; color: var(--ls-blue-dark); }

:focus-visible {
  outline: 3px solid var(--ls-saffron);
  outline-offset: 3px;
  border-radius: 6px;
}

.skip-link {
  position: absolute; left: 12px; top: -100px; z-index: 200;
  background: var(--ls-blue-dark); color: #fff;
  padding: .8rem 1.4rem; border-radius: 0 0 10px 10px; font-weight: 700;
  transition: top .18s ease;
}
.skip-link:focus { top: 0; color: #fff; }

/* ---------- 3. Layout ---------- */
.wrap { width: min(100% - 2.2rem, var(--ls-maxw)); margin-inline: auto; }
.section { padding-block: clamp(3rem, 7vw, 5.5rem); }
.section--tint { background: var(--ls-surface-alt); }
.section--ink  { background: var(--ls-blue-dark); color: #eef1fb; }
.section--ink h2, .section--ink h3 { color: #fff; }
.section--ink p { color: #d6ddf4; }

.section-head { text-align: center; margin-bottom: clamp(2rem, 4vw, 3rem); }
.section-head p { margin-inline: auto; color: var(--ls-ink-soft); }
.eyebrow {
  /* No uppercase or wide tracking here: both are Latin conventions that pull
     Devanagari conjuncts and matras apart and make the label hard to read.
     Weight, size and colour carry the emphasis instead. */
  display: inline-block; margin-bottom: .55rem;
  font-size: .9rem; font-weight: 700; letter-spacing: .01em;
  color: var(--ls-saffron-dk);
}
.eyebrow:lang(en) { text-transform: uppercase; letter-spacing: .12em; font-size: .84rem; }
.section--ink .eyebrow { color: var(--ls-gold); }

.grid { display: grid; gap: clamp(1rem, 2.4vw, 1.6rem); }
.grid--2 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 20rem), 1fr)); }
.grid--3 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 16.5rem), 1fr)); }
.grid--4 { grid-template-columns: repeat(auto-fit, minmax(min(100%, 13rem), 1fr)); }

/* ---------- 4. Header & navigation ---------- */
.site-header {
  position: sticky; top: 0; z-index: 100;
  background: rgba(255, 253, 248, .98);
  border-bottom: 1px solid var(--ls-border);
  /* NO backdrop-filter here. It makes the header a containing block for
     position:fixed descendants, which traps the open mobile menu inside the
     header box instead of the viewport, so the menu renders a couple of
     items tall with the page showing through. It is re-applied at desktop
     widths, where the nav is static and nothing is trapped. */
}
.site-header__bar {
  display: flex; align-items: center; gap: 1rem;
  min-height: 72px; padding-block: .5rem;
}
.brand { display: flex; align-items: center; gap: .7rem; text-decoration: none; flex: 0 1 auto; min-width: 0; }
.brand > span { min-width: 0; }
.brand img { width: 54px; height: 54px; flex: 0 0 54px; }
.brand__name {
  font-family: var(--ls-font-head); font-size: 1.5rem; font-weight: 700;
  color: var(--ls-blue-dark); line-height: 1.1;
}
.brand__name em { font-style: normal; color: var(--ls-green); }
.brand__tag { display: block; font-size: .72rem; color: var(--ls-ink-soft); font-family: var(--ls-font-body); line-height: 1.3; max-width: 26ch; }

.nav-toggle {
  margin-left: auto; flex: 0 0 auto; display: inline-flex; align-items: center; gap: .5rem;
  min-height: var(--ls-tap); padding: .5rem .9rem;
  background: var(--ls-blue-dark); color: #fff; border: 0;
  border-radius: 10px; font-weight: 700; cursor: pointer;
}
.nav-toggle svg { width: 24px; height: 24px; }
.nav-toggle__close { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__open { display: none; }
.nav-toggle[aria-expanded="true"] .nav-toggle__close { display: block; }

.site-nav { display: block; }
.nav-toggle:not([hidden]) ~ .site-nav { display: none; }
.nav-toggle:not([hidden]) ~ .site-nav[data-open="true"] {
  display: block;
  /* Header height varies with how the brand tagline wraps, so it is measured
     at runtime rather than hardcoded; 72px is only the pre-JS fallback. */
  position: fixed; inset: var(--ls-header-h, 72px) 0 0; z-index: 99;
  background: var(--ls-bg); overflow-y: auto; overscroll-behavior: contain;
  padding: 1rem 1.1rem 5.5rem;
  border-top: 1px solid var(--ls-border);
}
.site-nav ul { display: flex; flex-direction: column; gap: .25rem; }
.site-nav a {
  display: flex; align-items: center; gap: .8rem;
  min-height: var(--ls-tap); padding: .7rem .9rem;
  border-radius: 12px; text-decoration: none; font-weight: 600;
  color: var(--ls-blue-dark); border: 1px solid transparent;
}
.site-nav a svg { width: 24px; height: 24px; flex: 0 0 24px; color: var(--ls-saffron-dk); }
.site-nav a:hover { background: var(--ls-surface-alt); }
.site-nav a[aria-current="page"] {
  background: #eaf0ff; border-color: #c9d6ff; color: var(--ls-blue-dark);
}
.site-nav .nav-login {
  margin-top: .8rem; justify-content: center;
  background: var(--ls-saffron); color: #fff;
}
.site-nav .nav-login svg { color: #fff; }
.site-nav .nav-login:hover { background: var(--ls-saffron-dk); }

@media (min-width: 70rem) {
  .nav-toggle { display: none; }
  /* Desktop: brand + login on the top row, the full menu on its own row below.
     Ten destinations do not fit beside the brand without shrinking them to
     an unreadable size, and this audience needs readable links. */
  .site-header { backdrop-filter: saturate(1.4) blur(8px); }
  .site-header__bar { flex-wrap: wrap; min-height: 0; padding-block: .7rem 0; }
  .site-nav { display: block !important; flex: 1 0 100%; margin: 0; }
  .site-nav[data-open="true"] { position: static; padding: 0; border: 0; background: none; inset: auto; }
  .site-nav ul {
    flex-direction: row; align-items: center; gap: .1rem;
    flex-wrap: wrap; justify-content: center;
    border-top: 1px solid var(--ls-border); margin-top: .6rem; padding-top: .15rem;
  }
  .site-nav a {
    min-height: 46px; padding: .5rem .62rem; font-size: .95rem;
    gap: 0; border-radius: 0; white-space: nowrap;
  }
  .site-nav a svg { display: none; }
  .site-nav a:hover { background: none; color: var(--ls-saffron-dk); }
  .site-nav a[aria-current="page"] {
    background: none; border-color: transparent;
    box-shadow: inset 0 -3px 0 var(--ls-saffron); color: var(--ls-blue-dark);
  }
  .site-nav .nav-login { display: none; }
  .header-login { display: inline-flex !important; }
}
.header-login {
  display: none; margin-left: auto; align-items: center; gap: .45rem;
  min-height: 44px; padding: .5rem 1.15rem;
  background: var(--ls-saffron); color: #fff; border-radius: 11px;
  font-weight: 700; text-decoration: none;
}
.header-login:hover { background: var(--ls-saffron-dk); color: #fff; }
.header-login svg { width: 20px; height: 20px; }

/* Login is hidden until the committee accounts are ready. The markup and
   login.html are left in place, so bringing it back is deleting this block.
   !important is needed because the rule above turns the header button on
   with !important inside a media query. */
.header-login,
.site-nav .nav-login { display: none !important; }

/* Sticky mobile action bar: the three primary journeys */
.action-bar {
  position: fixed; inset: auto 0 0 0; z-index: 98;
  display: grid; grid-template-columns: repeat(3, 1fr);
  background: var(--ls-blue-dark);
  box-shadow: 0 -3px 16px rgba(0, 0, 0, .18);
  padding-bottom: env(safe-area-inset-bottom);
}
.action-bar a {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: .18rem;
  min-height: 62px; padding: .45rem .3rem;
  color: #fff; text-decoration: none; font-size: .82rem; font-weight: 700;
  line-height: 1.25; text-align: center;
  border-right: 1px solid rgba(255, 255, 255, .16);
}
.action-bar a:last-child { border-right: 0; }
.action-bar a:hover, .action-bar a:focus-visible { background: var(--ls-blue); color: #fff; }
.action-bar svg { width: 22px; height: 22px; }
.action-bar--pledge { background: var(--ls-saffron); }
body { padding-bottom: 68px; }
@media (min-width: 70rem) {
  .action-bar { display: none; }
  body { padding-bottom: 0; }
  .site-nav[data-open="true"] { display: block; }
}

/* ---------- 5. Hero ---------- */
.hero {
  position: relative; isolation: isolate;
  min-height: min(82svh, 700px);
  display: grid; place-items: center;
  /* Was 5rem at the top end, which pushed the call to action to y=750 on a
     1440x800 laptop, right at the fold. */
  padding-block: clamp(2rem, 4vw, 2.6rem);
  text-align: center;
  background:
    radial-gradient(120% 90% at 50% 0%, #fff8ec 0%, #fdf6ea 42%, #eef3ff 100%);
  overflow: hidden;
}
.hero__bg {
  position: absolute; inset: 0; z-index: -1;
  width: 100%; height: 100%; object-fit: cover;
  opacity: .5;
}
.hero__inner { position: relative; display: grid; gap: .7rem; justify-items: center; }
/* Campaign umbrella above the mark, running institution below it, both kept
   to one short line on a phone so neither competes with the लोकसंकल्प title. */
.hero__umbrella {
  background: rgba(255, 255, 255, .92);
  border: 1px solid var(--ls-border); border-radius: 999px;
  padding: .32rem 1.05rem; font-size: .9rem; font-weight: 700;
  color: var(--ls-blue-dark); letter-spacing: .01em;
}
.hero__by {
  font-size: .88rem; font-weight: 600; line-height: 1.5;
  color: var(--ls-ink-soft); margin-top: -.2rem;
  /* Balanced so the credit never breaks with "द्वारा संचालित" alone on
     its own line; it fits one line once there is room for it. */
  max-width: 40ch; text-wrap: balance;
}
@media (min-width: 48rem) { .hero__by { max-width: none; } }
.hero__title {
  font-size: clamp(2.4rem, 8vw, 4.6rem);
  letter-spacing: -.01em; line-height: 1.08; margin: 0;
}
.hero__title .b { color: var(--ls-blue-dark); }
.hero__title .g { color: var(--ls-green); }
.hero__sub {
  font-size: clamp(1.05rem, 2.6vw, 1.4rem);
  font-weight: 700; color: var(--ls-blue); max-width: 30ch;
}
.hero__quote {
  font-family: var(--ls-font-head);
  font-size: clamp(1.25rem, 3.6vw, 1.9rem);
  color: var(--ls-saffron-dk); line-height: 1.32;
  max-width: 32ch; margin-block: .15rem;
}
.hero__chips { display: flex; flex-wrap: wrap; gap: .45rem; justify-content: center; }
/* Live figures where the decorative word-chips used to sit. A visitor should
   see the size of the movement before they scroll, not four adjectives. */
.hero__stats {
  display: flex; flex-wrap: wrap; justify-content: center;
  gap: .35rem 1.4rem; margin: 0;
  font-size: .95rem; font-weight: 600; color: var(--ls-ink-soft);
}
.hero__stats b {
  font-family: var(--ls-font-head); font-weight: 700;
  font-size: 1.35rem; color: var(--ls-blue-dark);
  font-variant-numeric: tabular-nums; margin-inline-end: .25rem;
}
/* On a phone the three figures do not fit on one line, and left to itself the
   row breaks 2 + 1, which reads as a mistake. Three even columns instead, the
   number over its label, so the row is balanced at any text size. */
@media (max-width: 47.99rem) {
  .hero__stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: .5rem .4rem; }
  .hero__stats > span { display: grid; justify-items: center; align-content: start; line-height: 1.3; }
  .hero__stats b { margin-inline-end: 0; }
}
/* no scrim under the words any more, so no shadow to lift them off it */
.chip {
  background: #fff; border: 1px solid var(--ls-border);
  border-radius: 999px; padding: .3rem .9rem;
  font-size: .88rem; font-weight: 600; color: var(--ls-ink-soft);
}

/* ---------- 6. Components ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: .55rem;
  min-height: var(--ls-tap); padding: .85rem 1.6rem;
  border: 2px solid transparent; border-radius: var(--ls-radius);
  font-weight: 700; font-size: 1.05rem; text-decoration: none; cursor: pointer;
  transition: transform .12s ease, background-color .16s ease, box-shadow .16s ease;
}
.btn svg { width: 22px; height: 22px; }
.btn:hover { transform: translateY(-2px); }
.btn:active { transform: translateY(0); }
.btn--primary { background: var(--ls-saffron); color: #fff; box-shadow: 0 4px 14px rgba(232,115,12,.3); }
.btn--primary:hover { background: var(--ls-saffron-dk); color: #fff; }
.btn--secondary { background: var(--ls-blue-dark); color: #fff; }
.btn--secondary:hover { background: var(--ls-blue); color: #fff; }
.btn--ghost { background: #fff; color: var(--ls-blue-dark); border-color: var(--ls-blue-dark); }
.btn--ghost:hover { background: var(--ls-blue-dark); color: #fff; }
.btn--help { background: var(--ls-green); color: #fff; }
.btn--help:hover { background: var(--ls-green-dark); color: #fff; }
.btn--lg { font-size: 1.15rem; padding: 1.05rem 1.9rem; }
.btn--block { width: 100%; }

/* The three primary journeys, the spine of the whole site */
.journeys { display: grid; gap: .9rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); }
.journey {
  display: grid; grid-template-columns: auto 1fr; align-items: center; gap: 1rem;
  padding: 1.2rem 1.3rem; border-radius: 18px; text-decoration: none;
  border: 2px solid transparent; color: #fff;
  transition: transform .14s ease, box-shadow .16s ease;
}
.journey:hover { transform: translateY(-3px); box-shadow: 0 10px 26px rgba(23,48,122,.2); color: #fff; }
.journey__ic {
  display: grid; place-items: center;
  width: 54px; height: 54px; border-radius: 14px;
  background: rgba(255, 255, 255, .2);
}
.journey__ic svg { width: 30px; height: 30px; }
.journey b { display: block; font-size: 1.2rem; font-family: var(--ls-font-head); }
.journey span { font-size: .93rem; opacity: .92; line-height: 1.5; }
.journey--pledge { background: var(--ls-saffron); }
.journey--sabha  { background: var(--ls-blue-dark); }
.journey--help   { background: var(--ls-green); }

.card {
  background: var(--ls-surface);
  border: 1px solid var(--ls-border);
  border-radius: var(--ls-radius);
  padding: clamp(1.2rem, 2.4vw, 1.7rem);
  box-shadow: var(--ls-shadow);
  height: 100%;
}
.card h3 { margin-bottom: .5rem; }
.card p { color: var(--ls-ink-soft); font-size: 1rem; }
.card__ic {
  display: grid; place-items: center;
  width: 56px; height: 56px; margin-bottom: .9rem;
  border-radius: 16px; background: #eef2ff; color: var(--ls-blue);
}
.card__ic svg { width: 30px; height: 30px; }
.card--link { text-decoration: none; display: block; transition: transform .14s ease, box-shadow .16s ease, border-color .16s ease; }
.card--link:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgba(23,48,122,.13); border-color: #c9d6ff; }
.card--saffron .card__ic { background: #fff0e0; color: var(--ls-saffron-dk); }
.card--green   .card__ic { background: #e6f5ea; color: var(--ls-green-dark); }
.card--gold    .card__ic { background: #fdf1da; color: #7a4f00; }

/* One line under a group heading saying who the group is for. Sits between
   the heading and the cards, so it must not inherit the section-head
   centring used elsewhere. */
.group-note { color: var(--ls-ink-soft); margin-top: .35rem; margin-bottom: .2rem; }
.card--red     .card__ic { background: #fdeaea; color: var(--ls-red); }

/* A resource card that leads somewhere real. Villagers were reading these as
   plain text, so the actions are spelled out instead of relying on the whole
   card silently being a link. The title still covers the card for a big tap
   target; the buttons sit above it. */
.card--doc { position: relative; display: flex; flex-direction: column; }
.card--doc h3 a, .card--doc h4 a { text-decoration: none; color: inherit; }
.card--doc h3 a::after, .card--doc h4 a::after {
  content: ""; position: absolute; inset: 0; border-radius: var(--ls-radius);
}
.card--doc h3 a:focus-visible::after, .card--doc h4 a:focus-visible::after {
  outline: 3px solid var(--ls-saffron); outline-offset: 3px;
}
.card--doc:hover { transform: translateY(-3px); box-shadow: 0 10px 24px rgba(23,48,122,.13); border-color: #c9d6ff; }
.card--doc { transition: transform .14s ease, box-shadow .16s ease, border-color .16s ease; }
.card__actions {
  display: flex; flex-wrap: wrap; gap: .5rem; margin-top: auto; padding-top: 1rem;
  position: relative; z-index: 1;          /* above the title's cover layer */
}
.card__actions .btn { font-size: .97rem; padding: .58rem 1.05rem; min-height: 44px; }

/* A card carrying both parts of one booklet. Each part keeps its buttons
   directly under its own line, so the default margin-top:auto, which would
   drag both rows to the foot of the card, is dropped here. */
.card--parts .card__actions { margin-top: .45rem; padding-top: 0; }
.card__part { font-size: .95rem; color: var(--ls-ink-soft); margin-top: 1rem; }

/* Pillars */
.pillar { position: relative; text-align: center; }
.pillar .card__ic { margin-inline: auto; width: 72px; height: 72px; }
.pillar .card__ic svg { width: 38px; height: 38px; }
.pillar__n {
  position: absolute; top: .8rem; inset-inline-end: 1rem;
  font-family: var(--ls-font-head); font-size: 2.4rem;
  color: var(--ls-border); line-height: 1;
}

/* Impact counters */
/* Wrapping flex, not grid. The separators are drawn by the 1px gap showing the
   background through, so any cell a grid would leave empty appears as a grey
   block: with eight counters on a six-wide row, two of them. Flex items on the
   last row stretch to fill it instead, so the figures divide the width evenly
   whatever their number and however many fit. */
.counters {
  display: flex; flex-wrap: wrap; gap: 1px; background: var(--ls-border);
  border: 1px solid var(--ls-border); border-radius: var(--ls-radius); overflow: hidden;
}
/* Set by the figures code on a counter whose number is 0 or which the
   deployed script does not send. A class rather than [hidden] so it is
   independent of the date gates, and so the counter can come back by itself. */
.counter--empty { display: none; }
.counter {
  flex: 1 1 min(calc(50% - 1px), 10.5rem); min-width: 0;
  background: var(--ls-surface); padding: 1.4rem .8rem; text-align: center;
}
.counter svg { width: 28px; height: 28px; margin-inline: auto; color: var(--ls-saffron-dk); }
.counter b {
  display: block; font-family: var(--ls-font-head);
  font-size: clamp(1.7rem, 4.4vw, 2.5rem); color: var(--ls-blue-dark);
  line-height: 1.1; margin-top: .35rem; font-variant-numeric: tabular-nums;
}
.counter span { font-size: .95rem; color: var(--ls-ink-soft); font-weight: 600; }

/* Figures come from the Sheet a second or two after the page opens. Until they
   arrive the counter shows a resting bar, never a 0: a zero reads as a fact and
   tells a visitor the campaign has achieved nothing. The text stays in place
   but invisible, so nothing moves when the real number lands. */
[data-stat][data-loading] { color: transparent; position: relative; }
[data-stat][data-loading]::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  transform: translate(-50%, -50%);
  width: 2.4ch; height: .58em; border-radius: 999px;
  background: var(--ls-blue-dark); opacity: .13;
  animation: stat-wait 1.3s ease-in-out infinite;
}
@keyframes stat-wait { 0%, 100% { opacity: .09 } 50% { opacity: .2 } }
@media (prefers-reduced-motion: reduce) {
  [data-stat][data-loading]::after { animation: none; }
}

/* Two-column media block */
.split { display: grid; gap: clamp(1.5rem, 4vw, 3rem); align-items: center; }
@media (min-width: 52rem) { .split { grid-template-columns: 1fr 1fr; } .split--flip > :first-child { order: 2; } }
.split figure { margin: 0; }
.split > figure img, .split > figure > svg, .split > img { border-radius: var(--ls-radius); width: 100%; }

/* Checklists */
.ticks { display: grid; gap: .7rem; }
.ticks li { display: grid; grid-template-columns: auto 1fr; gap: .7rem; align-items: start; }
.ticks svg { width: 24px; height: 24px; margin-top: .28rem; color: var(--ls-green); flex: 0 0 24px; }
.section--ink .ticks svg { color: var(--ls-gold); }

/* Numbered steps */
.steps { counter-reset: s; display: grid; gap: 1rem; }
.steps li {
  counter-increment: s; position: relative;
  padding: 1rem 1.2rem 1rem 3.6rem;
  background: var(--ls-surface); border: 1px solid var(--ls-border);
  border-radius: var(--ls-radius);
}
.steps li::before {
  content: counter(s); position: absolute; inset-inline-start: 1rem; top: 1rem;
  display: grid; place-items: center; width: 2rem; height: 2rem;
  background: var(--ls-blue-dark); color: #fff; border-radius: 50%;
  font-family: var(--ls-font-head); font-size: 1.05rem; line-height: 1;
}

/* Story cards (video rail) */
.rail { display: flex; gap: 1rem; overflow-x: auto; padding-bottom: 1rem; scroll-snap-type: x mandatory; scrollbar-width: thin; }
.rail > * { flex: 0 0 min(84%, 20rem); scroll-snap-align: start; }
.story { background: var(--ls-surface); border: 1px solid var(--ls-border); border-radius: var(--ls-radius); overflow: hidden; text-decoration: none; display: block; height: 100%; }
.story:hover { border-color: #c9d6ff; }
.story__thumb {
  position: relative; aspect-ratio: 16 / 9;
  background: linear-gradient(135deg, var(--ls-blue-dark), var(--ls-green));
  display: grid; place-items: center;
}
.story__thumb svg { width: 54px; height: 54px; color: #fff; opacity: .95; }
.story__body { padding: 1rem 1.1rem 1.2rem; }
.story__body b { display: block; font-family: var(--ls-font-head); font-size: 1.13rem; color: var(--ls-blue-dark); }
.story__body span { font-size: .93rem; color: var(--ls-ink-soft); }
.story__tag {
  display: inline-block; margin-bottom: .5rem; padding: .12rem .6rem;
  background: #fff0e0; color: var(--ls-saffron-dk);
  border-radius: 999px; font-size: .78rem; font-weight: 700;
}

/* Quote / message banner */
.quote-band { text-align: center; }
.quote-band blockquote {
  font-family: var(--ls-font-head);
  font-size: clamp(1.4rem, 4vw, 2.4rem);
  line-height: 1.5; margin: 0 auto; max-width: 24ch;
}
.quote-band cite { display: block; margin-top: 1rem; font-style: normal; font-size: .95rem; opacity: .8; }

/* Callout */
.callout {
  border-inline-start: 5px solid var(--ls-saffron);
  background: #fff8ef; border-radius: 0 var(--ls-radius) var(--ls-radius) 0;
  padding: 1.1rem 1.3rem;
}
.callout--green { border-color: var(--ls-green); background: #f0f8f2; }
.callout--red { border-color: var(--ls-red); background: #fdf1f1; }
.callout p { max-width: none; }

/* Placeholder marker for data the team must supply */
.is-placeholder { border-style: dashed; }
.placeholder-note, .story__body .placeholder-note, .card .placeholder-note {
  display: inline-flex; align-items: center; gap: .4rem;
  font-size: .8rem; font-weight: 700; letter-spacing: .04em;
  color: var(--ls-ink-soft); background: #f1f2f6;
  border-radius: 999px; padding: .15rem .7rem;
}


/* ---------- Photographs ----------
   Campaign photographs of real gatherings. Every one is served in two sizes
   with WebP first, so a phone on 3G never pulls a desktop-weight file.
   Aspect boxes are fixed so nothing shifts while the image loads. */
.photo { margin: 0; position: relative; }
.photo > picture { display: block; }
/* The aspect ratio lives on the image, not the figure. Putting it on the figure
   and stretching the image to height:100% collapses the box whenever the figure
   has no height of its own, which is exactly what happens inside a grid. */
.photo img {
  display: block; width: 100%; height: auto;
  border-radius: var(--ls-radius); background: var(--ls-surface-alt);
}
.photo--wide img   { aspect-ratio: 3 / 2;  object-fit: cover; }
.photo--banner img { aspect-ratio: 16 / 7; object-fit: cover; }
.photo--square img { aspect-ratio: 1 / 1;  object-fit: cover; }
.photo figcaption {
  margin-top: .55rem; font-size: .9rem; color: var(--ls-ink-soft); line-height: 1.6;
}
.section--ink .photo figcaption { color: #c6d1f2; }

/* Photo grid for the gallery */
.photo-grid { display: grid; gap: 1.4rem 1rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 17rem), 1fr)); align-items: start; }
.photo-grid .photo img { aspect-ratio: 3 / 2; object-fit: cover; }

/* One photograph large enough to carry a section on its own. Capped below the
   full wrap width: at 1120px a 3:2 image is 747px tall, which pushes the rest
   of the page off a laptop screen. Full width on a phone, where it is small
   anyway and the detail needs every pixel. */
.photo--feature { max-width: 880px; margin-inline: auto; }
.photo--feature img { aspect-ratio: 3 / 2; object-fit: cover; }
.photo--feature a { display: block; border-radius: var(--ls-radius); }
.photo--feature a:focus-visible { outline: 3px solid var(--ls-saffron); outline-offset: 3px; }

/* Gallery: a caption's second line, and the district filter. The filter is
   hidden in the markup and shown by script, so with no JavaScript every photo
   stays on the page instead of leaving dead buttons behind. */
.photo__meta { display: block; margin-top: .15rem; font-size: .82rem; opacity: .8; }
.photo-grid .photo a { display: block; border-radius: var(--ls-radius); }
.photo-grid .photo a:focus-visible { outline: 3px solid var(--ls-saffron); outline-offset: 3px; }
.filters {
  display: flex; flex-wrap: wrap; gap: .5rem; align-items: center;
  margin-bottom: 1.2rem;
}
.filters__label { font-size: .88rem; font-weight: 700; color: var(--ls-ink-soft); }
.chip--filter {
  cursor: pointer; min-height: 38px; font-family: inherit;
  background: #fff; color: var(--ls-ink-soft);
}
.chip--filter:hover { border-color: var(--ls-saffron); }
.chip--filter.is-on {
  background: var(--ls-blue-dark); border-color: var(--ls-blue-dark); color: #fff;
}

/* The photograph in the hero is a photograph, not a backdrop.
   It used to sit behind the words under a heavy cream scrim, which washed the
   picture out and still left the credit line at 2.9:1. Worse, the shot's
   subject is mid-frame, exactly where centred text lands. Showing it as its
   own figure fixes both: the picture is fully visible and the words sit on
   plain cream, needing no scrim at all. */
.hero--photo {
  background: none;
  /* The figure is a grid row under the text on phones. Without this the
     ghost button's outline sat flush against the top edge of the photo. */
  row-gap: clamp(1.4rem, 5vw, 2rem);
}
.hero--photo .hero__media {
  margin: 0; display: grid; gap: .6rem; justify-items: center;
  /* the figure comes first in the markup so it loads early, but the mark and
     the name should be what a visitor meets first */
  order: 2;
}
.hero--photo .hero__inner { order: 1; }
.hero--photo .hero__bg {
  position: static; inset: auto; z-index: auto; opacity: 1;
  width: 100%; height: auto;
  aspect-ratio: 3 / 2; object-fit: contain; object-position: center;
  border-radius: calc(var(--ls-radius) * 1.15);
  box-shadow: 0 16px 48px rgba(23, 48, 122, .18);
}
.hero--photo .hero__media figcaption {
  font-size: .95rem; line-height: 1.5; color: var(--ls-ink-soft);
  max-width: 44ch; text-align: center; text-wrap: balance;
}
.hero--photo .hero__media figcaption b { color: var(--ls-blue-dark); }

/* Side by side once there is room, stacked before that. */
@media (min-width: 64rem) {
  .hero--photo {
    display: grid; align-items: center; justify-items: stretch;
    /* The photograph is 3:2 and is never cropped, so its height follows its
       width. At this split the picture column lands within ~10px of the text
       column's height, which is what stops the picture floating in a pool of
       cream with the text ending well above it. */
    grid-template-columns: minmax(0, 1fr) minmax(0, 1.45fr);
    gap: clamp(1.75rem, 3vw, 2.75rem);
    width: min(100% - 2.2rem, var(--ls-maxw)); margin-inline: auto;
    min-height: 0; text-align: start;
  }
  .hero--photo .hero__media { order: 2; justify-items: stretch; }
  .hero--photo .hero__media figcaption { text-align: start; max-width: none; }

  .hero--photo .hero__inner {
    order: 1; width: auto; max-width: none; margin-inline: 0;
    justify-items: start; text-align: start;
  }
  .hero--photo .hero__by { max-width: 46ch; }
  .hero--photo .hero__sub,
  .hero--photo .hero__quote { max-width: 30ch; }
  .hero--photo .hero__stats { justify-content: flex-start; }
  .hero--photo .hero__inner .cluster--center { justify-content: flex-start; }
}

/* Story cards carrying a real thumbnail instead of the gradient block */
.story__thumb img { width: 100%; height: 100%; object-fit: cover; border-radius: 0; }
.story__thumb--photo { background: var(--ls-surface-alt); }
/* The thumbnail fills the tile; the play mark stays centred by the grid. */
.story__thumb--photo picture { position: absolute; inset: 0; display: block; }
.story__thumb--photo img { width: 100%; height: 100%; object-fit: cover; }
.story__thumb--photo::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,0) 45%, rgba(0,0,0,.35) 100%);
}
.story__thumb--photo svg { position: relative; z-index: 1; filter: drop-shadow(0 2px 6px rgba(0,0,0,.5)); }

/* Page header carrying a photograph behind the title */
.page-head--photo { position: relative; isolation: isolate; overflow: hidden; }
.page-head--photo img {
  position: absolute; inset: 0; z-index: -2;
  width: 100%; height: 100%; object-fit: cover;
}
.page-head--photo::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(135deg, rgba(15,32,88,.92) 0%, rgba(23,48,122,.86) 55%, rgba(17,86,35,.88) 100%);
}

/* Page: dashboard */

/* ---------- Document reader ----------
   Rendered page images rather than an embedded PDF: Chrome on Android will not
   reliably show a PDF inline, and a PDF.js bundle would cost more than the
   whole site. Images render everywhere, load one page at a time, and keep the
   Devanagari exactly as typeset. */
.doc-toc { display: grid; gap: .15rem; list-style: none; padding: 0; }
.doc-toc a {
  display: grid; grid-template-columns: 1fr auto; gap: .7rem; align-items: baseline;
  padding: .6rem .8rem; border-radius: 10px; text-decoration: none;
  color: var(--ls-blue-dark); min-height: var(--ls-tap);
}
.doc-toc a:hover, .doc-toc a:focus-visible { background: var(--ls-surface-alt); }
.doc-toc a span:last-child { color: var(--ls-ink-soft); font-size: .9rem; white-space: nowrap; }

.doc-pages { display: grid; gap: clamp(1rem, 3vw, 1.8rem); }
.doc-page { scroll-margin-top: 90px; }
.doc-page img {
  display: block; width: 100%; height: auto;
  border: 1px solid var(--ls-border); border-radius: var(--ls-radius);
  box-shadow: var(--ls-shadow); background: #fff;
}
.doc-page figcaption {
  margin-top: .4rem; text-align: center;
  font-size: .85rem; color: var(--ls-ink-soft); font-variant-numeric: tabular-nums;
}
/* Follows the reader down all 14 pages, so it stays on one compact row: two
   stacked full-width buttons would cover the page being read. */
.doc-actions {
  position: sticky; bottom: 78px; z-index: 20;
  display: flex; gap: .45rem; flex-wrap: nowrap; justify-content: center;
  pointer-events: none;
}
.doc-actions .btn {
  pointer-events: auto; box-shadow: 0 6px 20px rgba(23,48,122,.25);
  font-size: .95rem; padding: .55rem .9rem; min-height: 44px; white-space: nowrap;
}
/* It sits over page scans, so the outlined button needs its own ground. */
.doc-actions .btn--ghost { background: var(--ls-surface); }
@media (min-width: 70rem) {
  .doc-actions { bottom: 1.4rem; gap: .6rem; }
  .doc-actions .btn { font-size: 1.02rem; padding: .7rem 1.3rem; }
}

/* Data tables */
.table-scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; border-radius: var(--ls-radius); border: 1px solid var(--ls-border); }
table.data { width: 100%; border-collapse: collapse; background: var(--ls-surface); font-size: .97rem; }
table.data caption { caption-side: top; text-align: start; padding: .9rem 1rem; color: var(--ls-ink-soft); font-size: .92rem; }
table.data th, table.data td { padding: .75rem 1rem; text-align: start; border-bottom: 1px solid var(--ls-border); }
table.data thead th { background: var(--ls-surface-alt); color: var(--ls-blue-dark); font-family: var(--ls-font-head); white-space: nowrap; }
table.data td { font-variant-numeric: tabular-nums; }
table.data tbody tr:last-child td { border-bottom: 0; }
table.data tbody tr:hover { background: #fbfcff; }

/* Page header (inner pages) */
.page-head {
  background: linear-gradient(135deg, var(--ls-blue-dark) 0%, var(--ls-blue) 55%, var(--ls-green-dark) 100%);
  color: #fff; padding-block: clamp(2.6rem, 6vw, 4.2rem);
}
.page-head h1 { color: #fff; font-size: clamp(2rem, 5.5vw, 3.2rem); }
.page-head p { color: #dfe6fb; font-size: 1.1rem; margin-top: .7rem; }
.page-head .eyebrow { color: var(--ls-gold); }
.crumbs { font-size: .9rem; margin-bottom: .9rem; color: #c6d1f2; }
.crumbs a { color: #fff; }
.crumbs ol { list-style: none; padding: 0; display: flex; flex-wrap: wrap; gap: .4rem; }
.crumbs li + li::before { content: "›"; margin-inline-end: .4rem; }

/* Accordion (FAQ / long content) */
details.acc {
  background: var(--ls-surface); border: 1px solid var(--ls-border);
  border-radius: var(--ls-radius); padding: 0 1.2rem; margin-bottom: .8rem;
}
details.acc > summary {
  cursor: pointer; list-style: none; padding: 1.05rem 0;
  font-family: var(--ls-font-head); font-size: 1.12rem; color: var(--ls-blue-dark);
  display: flex; justify-content: space-between; gap: 1rem; align-items: center;
  min-height: var(--ls-tap);
}
details.acc > summary::-webkit-details-marker { display: none; }
details.acc > summary::after { content: "+"; font-size: 1.6rem; color: var(--ls-saffron); line-height: 1; }
details.acc[open] > summary::after { content: "–"; }
details.acc > :not(summary) { padding-bottom: 1.1rem; }

/* ---------- 8. Forms ---------- */
.form { display: grid; gap: 1.15rem; }
.field { display: grid; gap: .4rem; }
.field > label { font-weight: 700; color: var(--ls-blue-dark); }
.field .hint { font-size: .88rem; color: var(--ls-ink-soft); }
input[type="text"], input[type="tel"], input[type="email"], input[type="number"],
input[type="date"], input[type="file"], select, textarea {
  min-height: var(--ls-tap); width: 100%;
  padding: .7rem .9rem;
  background: #fff; border: 2px solid var(--ls-border); border-radius: 12px;
}
textarea { min-height: 7rem; resize: vertical; }
input:focus, select:focus, textarea:focus { border-color: var(--ls-blue); outline: none; box-shadow: 0 0 0 3px #d9e2ff; }
fieldset { border: 0; padding: 0; }
legend { font-weight: 700; color: var(--ls-blue-dark); margin-bottom: .6rem; padding: 0; }

/* Big radio/checkbox tiles: easy to tap, easy to read */
.choices { display: grid; gap: .6rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 9.5rem), 1fr)); }
/* The tracks above are sized for short options (विद्यार्थी, युवा, नागरिक),
   which sit two or three to a row on a phone. A sentence-length option in a
   152px track breaks to one word per line, so blocks that carry sentences ask
   for a single column instead. CSS cannot measure the text, so it is marked
   in the markup. */
.choices--wide { grid-template-columns: 1fr; }
.choice {
  position: relative; display: flex; align-items: center; gap: .65rem;
  min-height: var(--ls-tap); padding: .8rem 1rem;
  background: #fff; border: 2px solid var(--ls-border); border-radius: 12px;
  font-weight: 600; cursor: pointer;
}
.choice input { width: 22px; height: 22px; accent-color: var(--ls-saffron); flex: 0 0 22px; }
.choice:hover { border-color: #c9d6ff; }
.choice:has(input:checked) { border-color: var(--ls-saffron); background: #fff7ef; }
.choice:has(input:focus-visible) { outline: 3px solid var(--ls-saffron); outline-offset: 2px; }

.pledge-list { display: grid; gap: .8rem; }
.pledge-list li {
  display: grid; grid-template-columns: auto 1fr; gap: .8rem; align-items: start;
  background: #fff; border: 1px solid var(--ls-border); border-radius: 12px; padding: .9rem 1rem;
}
.pledge-list svg { width: 24px; height: 24px; color: var(--ls-green); margin-top: .28rem; }

.form-note { font-size: .9rem; color: var(--ls-ink-soft); }

/* Submission feedback. Villagers on a slow link need to see that something is
   happening, and to be told plainly when it did not go through. */
.form-status {
  margin: 0; padding: .8rem 1rem; border-radius: 12px;
  font-weight: 600; border: 1px solid var(--ls-border); background: var(--ls-surface-alt);
}
.form-status[data-kind="busy"]  { border-color: #c9d6ff; background: #eef2ff; color: var(--ls-blue-dark); }
.form-status[data-kind="ok"]    { border-color: #b6e0c2; background: #eaf7ee; color: var(--ls-green-dark); }
.form-status[data-kind="error"] { border-color: #f3c2c2; background: #fdeaea; color: #9c1f1f; }

/* Certificate preview */
.certificate {
  border: 6px double var(--ls-blue-dark); border-radius: 10px;
  background: #fffdf5; padding: clamp(1.4rem, 4vw, 2.6rem); text-align: center;
}
.certificate h3 { font-size: clamp(1.4rem, 4vw, 2rem); }
.certificate .cert-name {
  font-family: var(--ls-font-head); font-size: clamp(1.6rem, 5vw, 2.4rem);
  color: var(--ls-green-dark); border-bottom: 2px dotted var(--ls-border);
  display: inline-block; padding: .3rem 2rem; margin: .8rem 0;
}
.cert__mark { width: 64px; height: 64px; margin: 0 auto .4rem; }
.cert__motto {
  font-family: var(--ls-font-head); color: var(--ls-saffron-dk);
  font-size: clamp(1.02rem, 2.6vw, 1.24rem); margin: 1rem auto .2rem; max-width: 34ch;
}
.cert__by {
  font-size: .84rem; line-height: 1.6; color: var(--ls-ink-soft);
  margin: .9rem auto 0; max-width: 46ch;
  border-top: 1px solid var(--ls-border); padding-top: .8rem;
}
.cert__date { font-size: .84rem; color: var(--ls-ink-soft); margin: .35rem auto 0; }
/* The line that turns a private moment into an invitation. It sits outside
   the certificate frame so it is the reader's own words, not the award's. */
.cert__call {
  font-family: var(--ls-font-head); font-size: clamp(1.15rem, 3.4vw, 1.5rem);
  color: var(--ls-blue-dark); text-align: center; margin: 1.2rem auto .2rem;
}

/* ---------- 9. Footer ---------- */
.site-footer { background: var(--ls-blue-dark); color: #cfd8f2; padding-block: clamp(2.5rem, 5vw, 3.6rem) 1.4rem; }
/* The full emblem carries dark blue type inside it, so on the dark footer it
   needs a light plate to sit on. At this size its tagline ring is actually
   readable, which is the whole reason it lives here and not in the header. */
.brand--seal {
  display: inline-block; background: #fff;
  border-radius: 18px; padding: .7rem; line-height: 0;
  box-shadow: 0 8px 26px rgba(0, 0, 0, .18);
}
.brand--seal img { width: clamp(112px, 24vw, 132px); height: auto; display: block; }
.site-footer h2, .site-footer h3 { color: #fff; font-size: 1.1rem; margin-bottom: .8rem; }
.site-footer a { color: #dfe6fb; text-decoration: none; }
.site-footer a:hover { color: var(--ls-gold); text-decoration: underline; }
.site-footer ul { display: grid; gap: .45rem; }
.footer-grid { display: grid; gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(min(100%, 14rem), 1fr)); }
.footer-contact li { display: grid; grid-template-columns: auto 1fr; gap: .6rem; align-items: start; }
.footer-contact svg { width: 20px; height: 20px; margin-top: .32rem; color: var(--ls-gold); }
/* Needs to outrank `.site-footer ul { display: grid }`, which otherwise
   stacks the icons vertically now that this is a list. */
.site-footer .socials { display: flex; gap: .6rem; margin-top: .9rem; list-style: none; padding: 0; flex-wrap: wrap; }
.socials a {
  display: grid; place-items: center; width: var(--ls-tap); height: var(--ls-tap);
  border: 1px solid rgba(255,255,255,.25); border-radius: 12px;
}
.socials a:hover { background: rgba(255,255,255,.12); }
.socials svg { width: 22px; height: 22px; }
.footer-bottom {
  margin-top: 2.2rem; padding-top: 1.2rem; border-top: 1px solid rgba(255,255,255,.16);
  display: flex; flex-wrap: wrap; gap: .6rem 1.4rem; justify-content: space-between;
  font-size: .9rem;
}
.tricolor-bar { height: 5px; background: linear-gradient(90deg, var(--ls-saffron) 0 33.3%, #fff 33.3% 66.6%, var(--ls-green) 66.6% 100%); }

/* ---------- 10. Utilities ---------- */
.visually-hidden {
  position: absolute !important; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.center { text-align: center; }
.stack   { display: grid; gap: 1rem; }
.stack-2 { display: grid; gap: 1.6rem; }
.cluster { display: flex; flex-wrap: wrap; gap: .8rem; }
.cluster--center { justify-content: center; }
.mt-2 { margin-top: 1.6rem; }
.lead { font-size: clamp(1.1rem, 2.2vw, 1.28rem); color: var(--ls-ink-soft); }
.icon { width: 1.4em; height: 1.4em; }

/* ---------- 11. Motion & print ---------- */
.reveal {
  opacity: 0; transform: translateY(18px);
  transition: opacity .55s ease, transform .55s ease;
  /* Failsafe: on a slow village connection js/site.js may never arrive,
     and without this the revealed blocks stay invisible for good. */
  animation: reveal-failsafe .01s linear 2.5s forwards;
}
.reveal.is-in { opacity: 1; transform: none; }
@keyframes reveal-failsafe { to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { animation-duration: .001ms !important; transition-duration: .001ms !important; }
  .reveal { opacity: 1; transform: none; }
}
@media print {
  .site-header, .action-bar, .site-footer, .hero__bg, .btn { display: none !important; }
  body { padding: 0; background: #fff; }
  a[href^="http"]::after { content: " (" attr(href) ")"; font-size: .8em; }
}
