@import url('https://fonts.googleapis.com/css2?family=Marcellus&family=Work+Sans:wght@400;500;600;700;800&display=swap');

:root {
  --marble: #f7f1e6;
  --marble-deep: #efe4cf;
  --panel: #fffdf9;
  --ink: #2a1e13;
  --ink-muted: #6b5d4d;
  --kumkum: #b3241d;
  /* Success, and the only place a colour outside the cream-and-gold system is
     allowed to carry meaning: a valid voucher at a festival counter and a
     completed payment both have to be unmistakable at a glance, and gold is
     not that. Named rather than repeated as three loose hexes. */
  --ok: #0c8f4e;
  --ok-soft: #ecfdf5;
  --ok-tint: #f2fdf6;
  --ok-line: #cdeedd;
  --kumkum-dark: #8c1b16;
  --kumkum-light: #d64a3a;
  --gold: #a9781f;
  --gold-soft: #e8d9b5;
  /* --gold on --marble-deep is 3.1:1 - fine for a rule or a large glyph,
     under AA for the 12-15px type the footer sets in it. This one is 5.3:1
     and still reads as gold. Use it wherever gold carries words. */
  --gold-deep: #7d5511;
  --gold-glow: #f0c869;
  --tulsi: #3f6b4f;
  --marigold: #e2932e;
  --radius: 14px;
  --radius-lg: 26px;
  --shadow-warm: 0 18px 44px -18px rgba(140, 60, 20, 0.35);
  --shadow-soft: 0 10px 30px -14px rgba(90, 60, 20, 0.22);
  --ease-spring: cubic-bezier(0.22, 1, 0.36, 1);
  --font-display: "Marcellus", ui-serif, Georgia, serif;
  --font-body: "Work Sans", ui-sans-serif, system-ui, sans-serif;
}

* { box-sizing: border-box; }
html { scroll-behavior: smooth; }
body {
  margin: 0;
  background:
    radial-gradient(1100px 480px at 12% -8%, rgba(226, 147, 46, 0.16), transparent 60%),
    radial-gradient(900px 460px at 92% 8%, rgba(179, 36, 29, 0.10), transparent 55%),
    var(--marble);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
img { max-width: 100%; display: block; }
a { color: inherit; }
h1, h2, h3 { font-family: var(--font-display); font-weight: 600; margin: 0; line-height: 1.1; letter-spacing: -0.01em; }
button, input, select, textarea { font-family: inherit; font-size: 16px; }

/* ---- signature: diya flame glyph ---- */
.diya { width: 28px; height: 28px; display: inline-block; flex-shrink: 0; }
.diya .flame { transform-origin: 50% 70%; animation: flicker 2.4s ease-in-out infinite; }
@keyframes flicker {
  0%, 100% { transform: scaleY(1) scaleX(1); opacity: 1; }
  50% { transform: scaleY(1.08) scaleX(0.95); opacity: 0.92; }
}

.divider { display: flex; align-items: center; justify-content: center; gap: 14px; padding: 34px 0; color: var(--gold); }
.divider .rule { width: 72px; height: 1px; background: linear-gradient(90deg, transparent, var(--gold-soft)); }
.divider .rule.flip { background: linear-gradient(90deg, var(--gold-soft), transparent); }

/* ---- eyebrow / pill labels ---- */
.eyebrow {
  display: inline-flex; align-items: center; gap: 7px; padding: 6px 14px; border-radius: 999px;
  font-size: 11px; font-weight: 700; letter-spacing: 0.14em; text-transform: uppercase;
  background: rgba(255,255,255,0.14); color: #fff; border: 1px solid rgba(255,255,255,0.28);
  backdrop-filter: blur(6px);
}

/* ---- scroll reveal ---- */
/* Reveal-on-scroll, and the one rule that matters about it: **the animation is
   opt-in, visibility is not**.

   These selectors used to start at `opacity: 0` and rely on JavaScript to add
   `.is-visible`. With JavaScript unavailable - blocked, a CDN failure, an old
   Android WebView with no IntersectionObserver - the donation form rendered at
   304x841px and opacity 0. In the DOM, laid out, and invisible. A donor saw an
   empty cream page and no way to give.

   So the hidden state is scoped to `html.js`, which the shell sets in its own
   <head> before the body paints. No JavaScript, no hiding. */
.reveal { opacity: 1; }
.js .reveal {
  opacity: 0;
  transform: translateY(22px);
  filter: blur(6px);
  transition: opacity 800ms var(--ease-spring), transform 800ms var(--ease-spring),
    filter 800ms var(--ease-spring);
}
.js .reveal.is-visible { opacity: 1; transform: translateY(0); filter: blur(0); }
@media (prefers-reduced-motion: reduce) {
  .reveal, .js .reveal { opacity: 1; transform: none; filter: none; transition: none; }
}

/* ---- floating nav ---- */
.site-nav-wrap { position: sticky; top: 0; z-index: 40; display: flex; justify-content: center; padding: 14px 16px 0; }

/*
 * The nav is sticky and 85px tall on a phone, so anything scrolled to - a
 * field the browser jumps to on a validation error, an in-page link, the
 * donate button from the header - landed underneath it. On the donation form
 * that meant the label of the field being corrected was the part covered.
 *
 * scroll-margin rather than padding: it moves the scroll stop, not the layout.
 */
:root { --nav-clearance: 100px; }

.field,
.amount-row,
.give-tabs,
.donate-panel,
[id] { scroll-margin-top: var(--nav-clearance); }
.site-nav {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  width: 100%; max-width: 760px; padding: 10px 10px 10px 20px;
  background: rgba(255, 253, 249, 0.78); backdrop-filter: blur(14px) saturate(1.4);
  border: 1px solid rgba(169, 120, 31, 0.22); border-radius: 999px; box-shadow: var(--shadow-soft);
}
.site-nav .wordmark {
  display: flex; align-items: center; gap: 8px; font-family: var(--font-display); font-size: 16px; font-weight: 600;
  color: var(--kumkum); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0;
}
.site-nav .wordmark .diya { width: 22px; height: 22px; flex-shrink: 0; }
@media (max-width: 560px) { .site-nav .wordmark { font-size: 14px; max-width: 46vw; } }

.btn-pill {
  display: inline-flex; align-items: center; gap: 4px; padding: 6px 6px 6px 18px; border-radius: 999px;
  background: var(--kumkum); color: #fff; font-weight: 600; font-size: 13.5px; text-decoration: none; border: none; cursor: pointer;
  transition: transform 240ms var(--ease-spring), background 200ms ease;
}
.btn-pill:hover { background: var(--kumkum-dark); }
.btn-pill:active { transform: scale(0.97); }
.btn-pill .icon-dot {
  width: 26px; height: 26px; border-radius: 50%; background: rgba(255,255,255,0.2);
  display: flex; align-items: center; justify-content: center; transition: transform 240ms var(--ease-spring);
}
.btn-pill:hover .icon-dot { transform: translate(2px, -1px) scale(1.06); }

/* ---- footer ---- */
/* Columns are proportioned by content, not by count. The failure this replaces
   was a founder photograph tall enough to set the height of the whole row: the
   address and the phone list ended two hundred pixels above the fold of it, so
   two thirds of the footer was empty cream. Every column now lands within about
   sixty pixels of every other, which is what closed the gap - not tighter
   padding. */
.site-footer {
  margin-top: 64px;
  padding: 0 24px;
  /* The top edge as a gradient hairline rather than a flat 1px rule across the
     full width, which reads as a table border. */
  background:
    linear-gradient(90deg, transparent, var(--gold-soft) 16%, var(--gold-soft) 84%, transparent)
      top left / 100% 1px no-repeat,
    var(--marble-deep);
  color: var(--ink-muted);
  font-size: 14px;
}

.footer-main {
  display: grid;
  grid-template-columns: 1.5fr 1.15fr 0.95fr;
  align-items: start;
  gap: 28px 44px;
  max-width: 1180px;
  margin: 0 auto;
  padding: 38px 0 26px;
}

/* The founder column only exists when a photo is configured, so the track count
   has to follow it rather than being fixed in one place. */
.footer-main:has(.footer-founder) { grid-template-columns: 1.05fr 1.1fr 0.8fr 1fr; }

/* A tick of fixed length above each label, not a rule under it. The underline
   this replaces ran the width of its own column, so four columns of four widths
   drew four rules of four lengths - ragged where it was meant to look ruled. */
.footer-col h2 {
  font-family: var(--font-display);
  font-size: 12px;
  font-weight: 400;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--gold-deep);
  margin: 0 0 15px;
  padding-top: 13px;
  background: linear-gradient(90deg, var(--gold) 0 26px, transparent 26px) top left / 100% 2px no-repeat;
}

/* A grid item's automatic minimum size is its longest unbreakable run, so
   without this the address pushed past the track and out of the footer - which
   `overflow: hidden` on the art host then quietly cut off at the screen edge
   instead of wrapping. */
.footer-col { min-width: 0; }
.footer-col p, .footer-col address { margin: 0 0 10px; font-style: normal; line-height: 1.6; overflow-wrap: break-word; }
.footer-col > :last-child { margin-bottom: 0; }
.footer-col address { white-space: pre-line; max-width: 26ch; }
.footer-col a {
  color: inherit; text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: color 180ms ease, border-color 180ms ease;
}
.footer-col a:hover { color: var(--kumkum); border-bottom-color: currentColor; }
.footer-col a:focus-visible { outline: 2px solid var(--gold-deep); outline-offset: 3px; border-radius: 2px; }
.footer-col .footer-email a { word-break: break-word; }

/* Aligned to the tick above the other columns' labels rather than to the top of
   the box, so the four columns start on one line. */
/* Starts level with the labels beside it, not with the ticks above them:
   the mark is the column's first line of content, so it lines up with the
   other columns' first line of content. */
.footer-about { padding-top: 11px; }
.footer-about .footer-mark { width: 162px; height: auto; margin: 0 0 14px; }
.footer-about .mantra {
  font-family: var(--font-display);
  font-size: 14.5px;
  line-height: 1.62;
  color: var(--gold-deep);
  margin-bottom: 20px;
}

.contact-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 12px; }
.contact-list .purpose {
  display: block; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase;
  color: var(--ink-muted); opacity: 0.85; margin-bottom: 1px;
}
.contact-list a { font-variant-numeric: tabular-nums; white-space: nowrap; }

.footer-founder img {
  width: 108px; height: auto; border-radius: 10px;
  border: 1px solid var(--gold-soft); box-shadow: var(--shadow-soft);
  margin-bottom: 11px;
}
.footer-founder .founder-name {
  font-family: var(--font-display); color: var(--ink);
  font-size: 14.5px; line-height: 1.4; margin: 0;
}

/* Monochrome by default, the platform's own colour on hover: the standard
   treatment, and the one that keeps five saturated circles from being the
   loudest thing on a page of cream and gold. Colour never carries the meaning -
   each link has an aria-label and a distinct glyph. 44px meets the AAA target
   size without needing a separate rule for touch. */
.social { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; gap: 9px; }
.social a {
  display: grid; place-items: center; width: 44px; height: 44px; border-radius: 50%;
  color: var(--ink); background: var(--panel);
  border: 1px solid var(--gold-soft);
  transition: color 180ms ease, background-color 180ms ease,
              border-color 180ms ease, transform 200ms var(--ease-spring);
}
/* Touch fires :hover on tap, so the lift would stick after a press. */
@media (hover: hover) and (pointer: fine) {
  .social a:hover { color: #fff; border-color: transparent; transform: translateY(-2px); }
}
.social a:active { transform: scale(0.96); }
.social a:focus-visible { outline: 2px solid var(--gold-deep); outline-offset: 3px; }
/* The colour change still lands; only the lift is dropped. */
@media (prefers-reduced-motion: reduce) {
  .social a { transition: color 180ms ease, background-color 180ms ease, border-color 180ms ease; }
  .social a:hover, .social a:active { transform: none; }
}
.social-facebook:hover { background: #1877f2; }
.social-youtube:hover { background: #ff0000; }
.social-whatsapp:hover { background: #128c4a; }
.social-instagram:hover { background: linear-gradient(45deg, #f09433, #dc2743 45%, #bc1888); }
.social-twitter:hover { background: #101418; }

.footer-bar {
  max-width: 1180px;
  margin: 0 auto;
  padding: 15px 0 24px;
  border-top: 1px solid var(--gold-soft);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px 32px;
  font-size: 13px;
}
.footer-bar .copyright { margin: 0; font-size: 12.5px; opacity: 0.85; }
.policy-links { list-style: none; display: flex; flex-wrap: wrap; gap: 4px 20px; padding: 0; margin: 0; }
.policy-links a { color: inherit; text-decoration: none; }
.policy-links a:hover { color: var(--kumkum); text-decoration: underline; }
.policy-links a:focus-visible { outline: 2px solid var(--gold-deep); outline-offset: 3px; border-radius: 2px; }

/* Tablet: four columns will not hold an address, so pair them. The identity
   block keeps the full width - it is the only one whose content is a mark. */
@media (max-width: 900px) {
  .footer-main,
  .footer-main:has(.footer-founder) { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 28px 40px; }
  .footer-about { grid-column: 1 / -1; padding-top: 0; }
  .footer-about .mantra { margin-bottom: 16px; }
  /* Three columns into two tracks leaves the founder alone on a row of its own,
     a tall narrow block beside half a row of nothing. Turned on its side and
     given the full width it is a caption, which is what it reads as. */
  .footer-founder {
    grid-column: 1 / -1;
    display: grid; grid-template-columns: 108px 1fr; gap: 0 18px; align-items: center;
  }
  .footer-founder h2 { grid-column: 1 / -1; }
  .footer-founder img { margin: 0; }
}

@media (max-width: 560px) {
  /* Two tracks wherever two will fit, one where they will not - so a 320px
     phone and a 430px one each get the densest layout their width supports,
     without a hand-picked second breakpoint guessing where that is. The blocks
     that need the whole width say so. */
  .site-footer { margin-top: 44px; padding: 0 20px; }
  .footer-main,
  .footer-main:has(.footer-founder) {
    /* Not two equal halves: the address and the email need the room, the two
       phone numbers do not. Equal tracks broke the email across "@gmail. /
       com" while a third of the column beside it stood empty. */
    grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
    gap: 24px 20px;
    padding: 28px 0 20px;
  }
  .footer-about, .footer-founder { grid-column: 1 / -1; }

  /* The mark and the mantra read as one masthead, rather than as two rows each
     with half a screen of nothing beside it. This is what the four-line mantra
     is for: set in two, it is too wide to sit next to anything. */
  .footer-about {
    display: grid; grid-template-columns: auto 1fr; align-items: center;
    column-gap: 18px; padding-top: 0;
  }
  .footer-about .footer-mark { width: 116px; margin: 0; }
  .footer-about .mantra { font-size: 12.5px; line-height: 1.58; margin: 0; }
  /* A little larger and a little tighter, so five circles read as one rail.
     Spread to both edges they were five separate dots with a thumb-width of
     nothing between them, which is worse than ending short of the margin. */
  .footer-about .social { grid-column: 1 / -1; margin-top: 20px; gap: 13px; }
  .social a { width: 46px; height: 46px; }

  /* The stored line breaks are set for a column three times this wide. Kept,
     each one wraps again and the address arrives ragged. */
  .footer-col address { max-width: none; white-space: normal; }
  .contact-list { gap: 13px; }
  .contact-list a, .footer-col .footer-email a { display: inline-block; padding: 2px 0; }
  /* One point down is the difference between the address column holding the
     whole address and breaking it across "@gmai / l.com". */
  .footer-col .footer-email a { font-size: 13px; }

  .footer-founder { grid-template-columns: 84px 1fr; gap: 0 14px; }
  .footer-founder img { width: 84px; }

  .footer-bar { padding: 14px 0 22px; gap: 9px; }
  .policy-links { gap: 4px 16px; }
  .policy-links a { display: inline-block; padding: 3px 0; }
}
@media (max-width: 379px) {
  .footer-main,
  .footer-main:has(.footer-founder) { grid-template-columns: 1fr; }
  /* Five circles at 46 need 282px and a 320px phone has 280, so the last one
     wrapped onto a line of its own. Back to 44 - still the AAA target size -
     and the rail holds. */
  .social a { width: 44px; height: 44px; }
  .footer-about .social { gap: 9px; }
}



/* ---- hero / carousel ---- */
.hero { position: relative; overflow: hidden; min-height: 58vh; display: flex; align-items: flex-end; margin: 14px 14px 0; border-radius: var(--radius-lg); }
.hero-carousel { position: absolute; inset: 0; }
.hero-carousel .slide {
  position: absolute; inset: 0; opacity: 0; transition: opacity 900ms var(--ease-spring);
}
.hero-carousel .slide.active { opacity: 1; }
.hero-carousel .slide picture { display: block; width: 100%; height: 100%; }
.hero-carousel .slide img { width: 100%; height: 100%; object-fit: cover; }

/* A portrait mobile banner needs a taller hero than a landscape desktop one,
   otherwise the crop throws away most of what makes it portrait. */
@media (max-width: 768px) {
  .hero { min-height: 74vh; }
}
.hero.no-image { display: none; }

/* One carousel per device. Only the matching one is displayed; the other's
   images are lazy and inside a display:none ancestor, so they never load. */
.hero-mobile { display: none; }

@media (max-width: 768px) {
  .hero-stack.has-mobile-alternative .hero-desktop { display: none; }
  .hero-mobile { display: flex; }
}

/* Title sits under the image, not on it: contrast over an admin-uploaded
   photograph is a lottery, and a long title over a busy image is unreadable
   no matter how heavy the scrim. */
.page-title {
  max-width: 800px; margin: 0 auto; padding: 36px 24px 0; text-align: center;
  animation: rise 700ms var(--ease-spring) both;
}
.page-title h1,
.page-title .person-heading { font-size: clamp(30px, 4.4vw, 50px); line-height: 1.12; text-wrap: balance; }
.page-title .person-heading { font-weight: 700; margin: 0; }

/* Present to assistive technology, absent from the layout. Standard clip-rect
   pattern rather than display:none, which would remove it from the accessible
   tree along with the visual one. */
.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0;
  clip-path: inset(50%);
  overflow: hidden;
  white-space: nowrap;
}
.page-title .subtitle {
  margin: 14px auto 0; font-size: 18px; color: var(--ink-muted); max-width: 60ch; text-wrap: pretty;
}

/* Carousel controls.
   These were white at 16-40% opacity, which is invisible on the bright saffron
   banners the temple actually uploads - the carousel worked, nobody could see
   that it was one. They are now dark and opaque, because a control has to
   survive whatever photograph is behind it, and a scrim under the dots gives
   them a guaranteed background regardless of the image.

   No hover dependency: on a phone there is no hover, and controls that only
   appear on hover are controls half the visitors never find. */
.hero-scrim {
  position: absolute; z-index: 1; inset: auto 0 0 0; height: 130px; pointer-events: none;
  background: linear-gradient(to top, rgba(20, 12, 6, 0.55), transparent);
}

.hero-dots {
  position: absolute; z-index: 2; bottom: 18px; left: 50%; transform: translateX(-50%);
  display: flex; gap: 9px; padding: 8px 12px; border-radius: 999px;
  background: rgba(20, 12, 6, 0.45); backdrop-filter: blur(6px);
}
.hero-dots button {
  width: 9px; height: 9px; border-radius: 50%; border: none; background: rgba(255, 255, 255, 0.55); cursor: pointer;
  padding: 0; transition: width 240ms var(--ease-spring), background 240ms var(--ease-spring);
}
.hero-dots button:hover { background: rgba(255, 255, 255, 0.85); }
.hero-dots button.active { background: #fff; width: 26px; border-radius: 999px; }

.hero-arrow {
  position: absolute; z-index: 2; top: 50%; transform: translateY(-50%);
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(20, 12, 6, 0.5); border: 1px solid rgba(255, 255, 255, 0.45); color: #fff; cursor: pointer;
  display: flex; align-items: center; justify-content: center; backdrop-filter: blur(8px);
  box-shadow: 0 4px 14px -4px rgba(0, 0, 0, 0.5);
  transition: background 200ms ease, transform 200ms var(--ease-spring);
}
.hero-arrow:hover { background: rgba(20, 12, 6, 0.72); }
.hero-arrow:active { transform: translateY(-50%) scale(0.94); }
.hero-arrow.prev { left: 18px; } .hero-arrow.next { right: 18px; }

@media (max-width: 640px) {
  /* Thumb-sized and inset from the rounded corners. */
  .hero-arrow { width: 38px; height: 38px; }
  .hero-arrow.prev { left: 10px; } .hero-arrow.next { right: 10px; }
  .hero-dots { bottom: 14px; }
}

@keyframes rise { from { opacity: 0; transform: translateY(18px); } to { opacity: 1; transform: translateY(0); } }
@media (prefers-reduced-motion: reduce) {
  .page-title { animation: none; }
  .diya .flame { animation: none; }
  .hero-carousel .slide { transition: none; }
}

/* ---- layout ---- */
.page-body { max-width: 1100px; margin: 0 auto; padding: 44px 24px 24px; display: grid; grid-template-columns: 1.5fr 1fr; gap: 40px; align-items: start; }
/* The ticker is a child of the page grid rather than of the story, so that one
   source order can serve both layouts: here it is placed back under the sevas
   in the left column, and on a phone it simply falls last. */
.page-body > .story { grid-column: 1; grid-row: 1; }
.page-body > .donate-panel { grid-column: 2; grid-row: 1 / span 2; }
.page-body > .ticker { grid-column: 1; grid-row: 2; }
@media (max-width: 860px) {
  .page-body { grid-template-columns: 1fr; padding: 32px 16px; }
  /* One column, source order: story, form, ticker. */
  .page-body > .story,
  .page-body > .donate-panel,
  .page-body > .ticker { grid-column: 1; grid-row: auto; }
  /* Sticky is for the desktop column, where the form must stay in view beside
     a long story. In one column it pins the whole form to the top and the
     ticker scrolls underneath it - which only became visible once anything
     followed the form at all. */
  /* `.page-body >` rather than `.donate-panel` alone: the sticky rule is
     further down this file, and at equal specificity the later rule wins
     whether or not the earlier one is in a media query. */
  .page-body > .donate-panel { position: static; top: auto; }
  .hero { margin: 10px 10px 0; }
}

.story { min-width: 0; }
.story .body-copy { font-size: 16px; color: var(--ink); }
.story .body-copy p { margin: 0 0 14px; max-width: 66ch; }

/* ---- organizer / preacher card ---- */

/* ---- progress ---- */
.progress-block {
  margin: 8px 0 30px; padding: 22px 24px; background: var(--panel); border: 1px solid var(--gold-soft);
  border-radius: var(--radius); box-shadow: var(--shadow-soft);
}
.progress-stats { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 12px; flex-wrap: wrap; gap: 6px; }
.progress-stats .raised {
  font-family: var(--font-display); font-size: 26px; font-weight: 600; font-variant-numeric: tabular-nums;
  background: linear-gradient(90deg, var(--kumkum), var(--marigold)); -webkit-background-clip: text; background-clip: text; color: transparent;
}
.progress-stats .goal-of { font-size: 13.5px; color: var(--ink-muted); }
.progress-track { height: 14px; border-radius: 999px; background: var(--marble-deep); overflow: hidden; position: relative; }
.progress-fill {
  height: 100%; border-radius: 999px; background: linear-gradient(90deg, var(--marigold), var(--kumkum) 70%, var(--kumkum-dark));
  width: 0; animation: fill-bar 1300ms 200ms var(--ease-spring) forwards; box-shadow: 0 0 14px rgba(226, 147, 46, 0.5);
}
@keyframes fill-bar { to { width: var(--fill-pct); } }
@media (prefers-reduced-motion: reduce) { .progress-fill { animation: none; width: var(--fill-pct); } }

/* ---- seva / plan grid (double-bezel cards) ---- */
.seva-heading { margin: 40px 0 16px; font-size: 21px; }
/* 220px rather than 190: a card now has to hold four amounts when it is
   chosen, and two columns of those on a phone are unreadable. Rows stretch so
   the cards beside an open one keep their height. */
.seva-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 14px; align-items: start; }
.seva-card {
  position: relative; text-align: left; background: var(--gold-soft); border: none; padding: 3px;
  border-radius: calc(var(--radius) + 3px); cursor: pointer; transition: transform 260ms var(--ease-spring), box-shadow 260ms var(--ease-spring);
}
.seva-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-warm); }
.seva-card .inner { background: var(--panel); border-radius: var(--radius); padding: 16px; height: 100%; box-shadow: inset 0 1px 0 rgba(255,255,255,0.6); }
.seva-card.selected { background: linear-gradient(135deg, var(--kumkum), var(--marigold)); }
.seva-card.selected .inner { box-shadow: inset 0 1px 0 rgba(255,255,255,0.6), 0 0 0 1px rgba(255,255,255,0.4); }
.seva-card .name { font-weight: 600; font-size: 15px; }
.seva-card .amount { margin-top: 7px; font-size: 13px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.seva-card .special-tag {
  position: absolute; top: -9px; right: 12px; background: linear-gradient(90deg, var(--gold), var(--marigold)); color: #fff; font-size: 10px;
  padding: 3px 10px; border-radius: 999px; letter-spacing: 0.06em; text-transform: uppercase; box-shadow: 0 4px 10px -3px rgba(169,120,31,0.6);
}

/* The chosen seva's own amounts, under the grid. Marked off by the same gold
   edge the cards use, so it reads as belonging to the card above it rather
   than as a second, unrelated question. */
/* The chosen seva's amounts, inside its own card and separated from the words
   above by a hairline. The card grows; nothing around it moves sideways. */
.seva-ladder { margin-top: 14px; padding-top: 12px; border-top: 1px solid var(--gold-soft); }
.seva-ladder-label { margin: 0 0 10px; font-size: 12.5px; color: var(--ink-muted); }
/* Grid, not flex-wrap: wrapping stretched a lone fourth amount across the
   whole card, which made ₹1,000 look like the recommended one. */
.seva-ladder .amount-row {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(84px, 1fr)); gap: 8px; margin: 0;
}
.seva-ladder .amount-chip { padding: 8px 10px; font-size: 13.5px; }

/* ---- donation ticker ---- */
.ticker { margin-top: 34px; }
.ticker ul { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 8px; }
.ticker li {
  display: flex; align-items: center; gap: 12px; font-size: 13.5px; padding: 10px 14px;
  background: var(--panel); border: 1px solid var(--gold-soft); border-radius: 999px; color: var(--ink-muted);
}
.ticker li .avatar {
  width: 30px; height: 30px; border-radius: 50%; background: linear-gradient(135deg, var(--gold-soft), var(--marigold));
  color: #5a3f10; font-weight: 700; font-size: 12px; display: flex; align-items: center; justify-content: center; flex-shrink: 0;
}
.ticker li .who { flex: 1; color: var(--ink); font-weight: 500; }
.ticker li .amt { font-weight: 700; color: var(--kumkum-dark); font-variant-numeric: tabular-nums; }

.note-block { margin-bottom: 4px; }

/* ---- donate panel ---- */
.donate-panel {
  background: var(--panel); border: 1px solid var(--gold-soft); border-radius: var(--radius-lg); padding: 26px;
  position: sticky; top: 96px; box-shadow: var(--shadow-soft);
}
.donate-panel h2 { font-size: 21px; margin-bottom: 4px; }
.donate-panel .min-note { font-size: 12.5px; color: var(--ink-muted); margin-bottom: 18px; }

/* Four equal columns rather than flex-wrap, so the presets read as one set of
   choices instead of a 3-then-1 orphan. Equal columns also stop the widest
   amount from making its own chip look like the recommended one. */
/* auto-fit rather than a fixed 4, because a campaign may set five quick amounts. */
.amount-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(76px, 1fr)); gap: 8px;
  margin-top: 18px; margin-bottom: 14px; }
.amount-chip {
  border: 1px solid var(--gold-soft); background: var(--marble); border-radius: 999px;
  padding: 9px 4px; text-align: center; font-variant-numeric: tabular-nums;
  font-size: 14px; font-weight: 500; cursor: pointer;
  transition: border-color 200ms var(--ease-spring), transform 200ms var(--ease-spring),
              background 200ms var(--ease-spring), color 200ms var(--ease-spring),
              box-shadow 200ms var(--ease-spring);
}
/* A subscription plan is a commitment, not a number: it states the amount, what
   the seva is, and how long it runs. Three lines need a full-width row and a
   left edge to read down, so these are not pills at all. */
#plan-chips { grid-template-columns: 1fr; gap: 10px; }
.plan-chip {
  border-radius: 12px; padding: 12px 14px; text-align: left;
  display: grid; gap: 2px; line-height: 1.35;
}
.plan-chip-amount { font-size: 16px; font-weight: 600; }
.plan-chip-amount small { font-size: 12.5px; font-weight: 500; opacity: 0.75; }
.plan-chip-name { font-size: 13px; }
.plan-chip-term { font-size: 12px; opacity: 0.7; }

/* What the ₹5 check is, what arrives afterwards, and how to stop. Set quiet
   and below the button: a donor reads these while hesitating, not while
   choosing. */
.give-notes { list-style: none; margin: 14px 0 0; padding: 0; display: grid; gap: 6px; }
.give-notes li { font-size: 12.5px; color: var(--ink-muted); padding-left: 16px; position: relative; }
.give-notes li::before { content: "\2022"; position: absolute; left: 4px; color: var(--gold); }
.amount-chip:hover { border-color: var(--gold); transform: translateY(-1px); }
.amount-chip.selected { background: linear-gradient(90deg, var(--kumkum), var(--kumkum-light)); border-color: var(--kumkum); color: #fff; box-shadow: 0 6px 14px -6px rgba(179,36,29,0.6); }

.field { margin-bottom: 14px; }
.field label { display: block; font-size: 12.5px; color: var(--ink-muted); margin-bottom: 5px; }
.field input, .field textarea, .field select {
  width: 100%; padding: 11px 13px; border: 1px solid var(--gold-soft); border-radius: 10px; background: #fff; color: var(--ink);
  transition: border-color 180ms ease, box-shadow 180ms ease;
}
.field input:focus, .field textarea:focus, .field select:focus { border-color: var(--gold); box-shadow: 0 0 0 3px rgba(169,120,31,0.15); outline: none; }

/* A bare <select> renders in the operating system's own chrome, which on this
   page reads as a form control someone forgot about. Strip the native arrow and
   draw one in the page's own gold, keeping the control the same height as the
   text inputs beside it. color-scheme keeps the dropdown list itself light, so
   a donor with the OS in dark mode does not get white text on white options. */
.field select {
  appearance: none; color-scheme: light; cursor: pointer;
  padding-right: 38px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%23a9781f' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 13px center;
}
.field select:hover { border-color: var(--gold); }
.amount-chip:focus-visible, .seva-card:focus-visible, .btn:focus-visible, .btn-pill:focus-visible {
  outline: 3px solid var(--gold); outline-offset: 2px;
}
.checkbox-field { display: flex; align-items: flex-start; gap: 8px; font-size: 13.5px; margin-bottom: 14px; }
.checkbox-field input { width: auto; margin-top: 3px; }

.btn-donate {
  width: 100%; padding: 15px; background: linear-gradient(90deg, var(--kumkum), var(--kumkum-dark)); color: #fff; border: none; border-radius: 12px;
  font-size: 16px; font-weight: 700; cursor: pointer; transition: transform 220ms var(--ease-spring), box-shadow 220ms var(--ease-spring);
  box-shadow: 0 12px 26px -12px rgba(140,27,22,0.7);
}
.btn-donate:hover { transform: translateY(-1px); box-shadow: 0 16px 32px -12px rgba(140,27,22,0.8); }
.btn-donate:active { transform: scale(0.98); }
.btn-donate:disabled { opacity: 0.6; cursor: not-allowed; transform: none; }

.form-error { color: var(--kumkum-dark); font-size: 13px; margin-top: 10px; min-height: 1em; }


.badge-80g { display: inline-block; margin-top: 8px; font-size: 11.5px; color: var(--tulsi); border: 1px solid var(--tulsi); padding: 2px 8px; border-radius: 999px; }

.not-found { max-width: 480px; margin: 80px auto; text-align: center; padding: 0 24px; }
.not-found .diya { width: 40px; height: 40px; margin: 0 auto 16px; }


/* ---- give tabs ---- */
/* One-time and subscription share one card. Stacking two panels in the sticky
   column made it taller than the viewport and pushed monthly below the fold. */
.give-tabs {
  display: flex; gap: 4px; padding: 4px; margin-bottom: 20px;
  background: var(--paper-sunk, rgba(0, 0, 0, 0.04)); border-radius: 999px;
}
.give-tab {
  flex: 1; padding: 10px 16px; border: none; border-radius: 999px; cursor: pointer;
  background: transparent; color: var(--ink-muted); font: inherit; font-weight: 600; font-size: 14px;
  transition: background 180ms ease, color 180ms ease;
}
.give-tab:hover { color: var(--ink); }
.give-tab.active { background: #fff; color: var(--ink); box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1); }
.give-tab:focus-visible { outline: 2px solid var(--gold, #b8862b); outline-offset: 2px; }

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


/* --- Temple logo in the public header ----------------------------------- */
.site-nav .wordmark img {
  width: 150px;
  height: auto;
  display: block;
}

@media (max-width: 640px) {
  .site-nav .wordmark img { width: 116px; }
}


/* Marks a field the donor can skip, so an optional pick does not read as
   another thing standing between them and giving. */
/* A quiet line under a control: what a minimum is, or what an address is for.
   Muted and small on purpose - it explains, it does not ask. */
.field-note {
  margin: 5px 0 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--ink-muted);
}

#prasadam-row .field-note { margin: 0 0 6px; }

/* Not a .field-note: those explain a rule calmly and stay put. This one
   appears only when a keystroke was refused, so it is the temple's red rather
   than muted grey, and it clears itself. A devotee whose keyboard is set to
   Kannada watches their letters fail to appear; without this line that reads
   as a broken form. */
.script-note {
  margin: 5px 0 0;
  font-size: 12px;
  line-height: 1.45;
  color: var(--kumkum-dark);
}

.field label .optional {
  font-weight: 400;
  font-size: 12px;
  color: var(--ink-muted);
  margin-left: 4px;
}


/* ---- person page lead ---- */
/* A person page is an ask from someone, so their face leads it. Beside the
   story on desktop, above it on mobile - the same call donation-pages made. */
/* Portrait flush to the card edge, copy in the other column. The previous
   version put a 128px circle inside 24px of padding, which left the card mostly
   empty and made the face the smallest thing on it. */
.organizer-lead {
  display: grid;
  grid-template-columns: minmax(160px, 34%) 1fr;
  margin-bottom: 28px;
  background: #fff;
  border: 1px solid var(--gold-soft, rgba(0, 0, 0, 0.08));
  border-radius: var(--radius-lg, 20px);
  overflow: hidden;
  box-shadow: var(--shadow-soft);
}

.organizer-lead .portrait {
  position: relative;
  /* A portrait crop. Fixed ratio rather than a fixed height so the card grows
     with its copy instead of letterboxing the face. */
  aspect-ratio: 4 / 5;
  background: linear-gradient(135deg, #b8862b, #8a5a1c);
}

.organizer-lead .portrait img,
.organizer-lead .organizer-initial {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.organizer-lead .portrait img { object-fit: cover; object-position: center 22%; }

.organizer-lead .organizer-initial {
  display: grid;
  place-items: center;
  font-size: 64px;
  font-weight: 700;
  color: #fff;
}

.organizer-lead .info {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 10px;
  padding: 28px 30px;
  min-width: 0;
}

.organizer-lead .role {
  font-size: 11.5px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--ink-muted);
}

.organizer-lead .name {
  font-size: clamp(22px, 3vw, 30px);
  font-weight: 700;
  line-height: 1.15;
  text-wrap: balance;
}

.organizer-lead .lede {
  margin: 6px 0 0;
  /* The person's own appeal, so it reads as body copy rather than as a caption
     - a shade darker and a size up from the credit note beneath it. */
  font-size: 15.5px;
  line-height: 1.55;
  color: var(--ink, #2a1e13);
  text-wrap: pretty;
}

/* Only the person's own words keep their line breaks - an admin who types two
   paragraphs gets two. The fallback line below is template markup, and its
   source newlines are indentation rather than intent. */
.organizer-lead .bio { white-space: pre-line; }

/* Reassurance, not the appeal: smaller, muted, and separated by a hairline so
   it reads as a footnote to the paragraph above rather than its last sentence. */
.organizer-lead .credit-note {
  margin: 10px 0 0;
  padding-top: 10px;
  border-top: 1px solid var(--gold-soft, rgba(0, 0, 0, 0.08));
  font-size: 13px;
  line-height: 1.45;
  color: var(--ink-muted);
  text-wrap: pretty;
}

@media (max-width: 640px) {
  /* Stacked, on a square crop.
     A 16:10 band across a phone cut the head off a portrait photograph - the
     photos staff upload are portrait, and a landscape crop of a portrait has
     to throw away most of the height. A square keeps the face and still fits
     above the fold, and object-position sits high because a face is in the top
     half of a portrait, never the middle. */
  .organizer-lead { grid-template-columns: 1fr; }
  .organizer-lead .portrait { aspect-ratio: 1 / 1; }
  .organizer-lead .portrait img { object-position: center 18%; }
  .organizer-lead .info { padding: 20px 22px 24px; }
  .organizer-lead .name { font-size: 24px; }
}


/* ---- document pages (certificates, and later the policies) ---- */
.doc-page { max-width: 760px; margin: 0 auto; padding: 8px 24px 56px; }

.doc-facts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 14px 24px;
  margin: 0 0 28px;
  padding: 20px 22px;
  background: var(--panel);
  border: 1px solid var(--gold-soft);
  border-radius: var(--radius);
}
.doc-facts dt { font-size: 11.5px; letter-spacing: 0.08em; text-transform: uppercase; color: var(--ink-muted); }
.doc-facts dd { margin: 3px 0 0; font-weight: 600; word-break: break-word; }

.doc-list { list-style: none; padding: 0; margin: 0; display: grid; gap: 10px; }
.doc-list a {
  display: flex; align-items: center; gap: 14px;
  padding: 16px 18px;
  background: var(--panel);
  border: 1px solid var(--gold-soft);
  border-radius: var(--radius);
  color: inherit; text-decoration: none;
  transition: border-color 180ms ease, transform 180ms var(--ease-spring), box-shadow 180ms ease;
}
.doc-list a:hover { border-color: var(--gold); transform: translateY(-1px); box-shadow: var(--shadow-soft); }
.doc-list a:active { transform: none; }

.doc-icon { flex-shrink: 0; display: grid; place-items: center; width: 42px; height: 42px; border-radius: 50%; background: rgba(169,120,31,0.12); color: var(--gold); }
.doc-text { flex: 1; min-width: 0; }
.doc-name { display: block; font-weight: 600; }
.doc-help { display: block; font-size: 13.5px; color: var(--ink-muted); text-wrap: pretty; }
.doc-action { flex-shrink: 0; font-size: 11.5px; font-weight: 700; letter-spacing: 0.08em; color: var(--kumkum); }
.doc-empty { color: var(--ink-muted); }
.doc-note { margin-top: 26px; font-size: 14px; color: var(--ink-muted); }

@media (max-width: 560px) {
  .doc-page { padding: 4px 18px 44px; }
  .doc-list a { padding: 14px; gap: 12px; }
  .doc-icon { width: 36px; height: 36px; }
}

/* Long-form written pages: policies, and anything else the temple writes.
   Measure capped for reading rather than for the layout - .doc-page is already
   760px, and prose wants the same discipline applied to its own children. */
.prose { font-size: 16.5px; line-height: 1.75; color: var(--ink); }
.prose > * + * { margin-top: 1em; }
.prose h2 { font-family: var(--font-display); font-size: 24px; margin-top: 1.8em; line-height: 1.25; }
.prose h3 { font-size: 19px; font-weight: 700; margin-top: 1.5em; }
.prose p, .prose li { text-wrap: pretty; }
.prose ul, .prose ol { padding-left: 1.35em; }
.prose li + li { margin-top: 0.4em; }
.prose a { color: var(--kumkum); }
.prose blockquote {
  margin-left: 0; padding: 2px 0 2px 18px;
  border-left: 3px solid var(--gold-soft); color: var(--ink-muted);
}
.prose table { width: 100%; border-collapse: collapse; font-size: 15px; }
.prose th, .prose td { padding: 8px 10px; border: 1px solid var(--gold-soft); text-align: left; }
.prose img { border-radius: var(--radius); margin: 1.2em 0; }
.prose hr { border: none; border-top: 1px solid var(--gold-soft); margin: 2em 0; }

.doc-updated { margin-top: 2.5em; font-size: 13.5px; color: var(--ink-muted); }

/* Draft markers on an unpublished policy. Deliberately loud - a passage that
   still needs a decision must be impossible to skim past. */
.prose mark {
  background: var(--gold-glow);
  color: var(--ink);
  padding: 1px 5px;
  border-radius: 4px;
}

/* ---- trust block ---- */
/* Sits under the donate button, where a donor hesitates.
   The first version was cramped: tight padding, a small headline and the
   payment strip shrunk to 22px, so the marks looked squeezed in rather than
   presented. This gives each part room - the reference block reads as calm,
   and calm is the whole point of a reassurance panel. Green rather than the
   page's saffron on purpose: this is not another call to act. */
/* The reassurance block, in the temple's own colours.
 *
 * It was mint green throughout - background, border, headline and sub-line -
 * the only component on the site that ignored the palette,
 * sitting directly under the donate button where the identity matters most.
 * The sub-line measured 3.09:1 on its own background, under the 4.5:1 this
 * page needs at 13.5px: a washed-out green that read as a design choice rather
 * than as a defect, which is the same trap the gold rule above describes.
 *
 * Cream and gold now, and every colour on it clears AA on --panel: ink 16:1,
 * ink-muted 6.3:1, gold-deep 6.5:1. */
.trust-block {
  margin-top: 22px;
  padding: 22px 20px 20px;
  text-align: center;
  background: var(--panel);
  border: 1px solid var(--gold-soft);
  border-radius: 16px;
}
.trust-headline {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  margin: 0;
  font-size: 17px;
  font-weight: 700;
  line-height: 1.35;
  color: var(--ink);
  text-wrap: balance;
}
.trust-headline svg { flex-shrink: 0; color: var(--gold); }
.trust-sub {
  margin: 6px 0 0;
  font-size: 13.5px;
  line-height: 1.55;
  color: var(--ink-muted);
  text-wrap: balance;
}
/* Full width up to its natural size, so the marks sit at a readable scale
   instead of being squeezed to fit a height that was chosen arbitrarily. */
.trust-block img {
  display: block;
  margin: 16px auto 0;
  width: 100%;
  max-width: 290px;
  height: auto;
  opacity: 0.92;
}

@media (max-width: 420px) {
  .trust-block { padding: 18px 14px 16px; }
  .trust-headline { font-size: 15.5px; }
  .trust-block img { max-width: 240px; }
}

/* ---- seva card description ---- */
/* Clamped, not just capped at the model. The 300-character limit stops the
   worst case; three lines keeps every card in a row the same height whatever
   the temple writes. */
.seva-description {
  margin: 8px 0 0;
  font-size: 13.5px;
  line-height: 1.5;
  color: var(--ink-muted);
  text-wrap: pretty;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ---- festival dates ---- */
/* No label, and set apart from the subtitle so it reads as a fact rather than
   as more of the sentence above it. */
/* The festival dates.
   Set large, because for a festival page this is the second thing a donor
   needs after knowing what the page is for - "when is it?" was being answered
   in 17px, smaller than the subtitle above it.

   Flanked by gold rules rather than set in a bordered pill. A pill sits a few
   hundred pixels from the donate button and reads as a second one; rules mark
   the line as a heading instead, which is what it is. It also matches the diya
   divider directly below, so the header closes with a motif the page already
   uses. */
.page-dates {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(12px, 2.4vw, 22px);
  margin: 20px auto 0;
  color: var(--kumkum);
}

.page-dates::before,
.page-dates::after {
  content: "";
  height: 1px;
  /* Bounded so the rules frame the date on a wide screen instead of running
     to the edges, and collapse before they crowd it on a narrow one. */
  width: clamp(0px, 12vw, 92px);
  background: linear-gradient(90deg, transparent, var(--gold-soft));
}

.page-dates::after {
  background: linear-gradient(90deg, var(--gold-soft), transparent);
}

.page-dates .on {
  font-family: var(--font-display);
  /* Sits between the subtitle (18px) and the title (up to 50px): clearly the
     next thing to read, never competing with the name of the campaign. */
  font-size: clamp(24px, 3.6vw, 38px);
  line-height: 1.15;
  letter-spacing: 0.01em;
  white-space: nowrap;
}

/* A long range - "28 December 2026 - 3 January 2027" - is the one case that
   cannot stay on one line on a phone. It wraps rather than overflowing, and
   the rules go, since there is nothing left to flank. */
@media (max-width: 420px) {
  .page-dates .on { white-space: normal; }
  .page-dates::before,
  .page-dates::after { display: none; }
}

/* ---- payment result dialog ---- */
/* The one moment on this page worth marking. Motion is deliberate rather than
   decorative: the ring draws, then the tick, so the eye is led to the mark
   that says "done" instead of being shown a finished icon it has to read. */
.result-modal {
  width: min(440px, calc(100vw - 32px));
  padding: 0;
  border: none;
  border-radius: var(--radius-lg);
  background: transparent;
  overflow: visible;
}
.result-modal::backdrop {
  background: rgba(28, 16, 8, 0.55);
  backdrop-filter: blur(3px);
  /* @starting-style needs an explicit start for the backdrop too, or it snaps
     in while the card animates. */
  animation: result-fade 260ms var(--ease-spring) both;
}

.result-card {
  padding: 34px 28px 26px;
  text-align: center;
  background: var(--panel);
  border: 1px solid var(--gold-soft);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-warm);
  animation: result-rise 340ms var(--ease-spring) both;
}

/* Never from scale(0): nothing in the world appears out of nothing, and a card
   that does reads as a glitch rather than an arrival. */
@keyframes result-rise {
  from { opacity: 0; transform: scale(0.94) translateY(10px); }
  to   { opacity: 1; transform: none; }
}
@keyframes result-fade { from { opacity: 0; } to { opacity: 1; } }

.result-emblem { width: 82px; height: 82px; margin: 0 auto 18px; }
.result-ring { width: 100%; height: 100%; overflow: visible; }
.result-ring .ring,
.result-ring .tick,
.result-ring .cross {
  fill: none;
  stroke-width: 3;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.result-ring .ring { stroke-dasharray: 152; stroke-dashoffset: 152; }
.result-ring .tick { stroke-dasharray: 40; stroke-dashoffset: 40; }
.result-ring .cross { stroke-dasharray: 46; stroke-dashoffset: 46; }

/* Success is the temple's own green; failure is stated plainly rather than
   alarmingly - nothing was charged, and the donor has done nothing wrong. */
[data-state="success"] .ring, [data-state="success"] .tick { stroke: var(--ok); }
[data-state="failure"] .ring, [data-state="failure"] .cross { stroke: var(--kumkum); }
[data-state="success"] .cross, [data-state="failure"] .tick { display: none; }

.result-emblem.is-drawn .ring {
  transition: stroke-dashoffset 520ms var(--ease-spring);
  stroke-dashoffset: 0;
}
.result-emblem.is-drawn .tick,
.result-emblem.is-drawn .cross {
  transition: stroke-dashoffset 300ms var(--ease-spring) 380ms;
  stroke-dashoffset: 0;
}

.result-title { font-family: var(--font-display); font-size: 27px; margin: 0; line-height: 1.2; }
.result-message { margin: 8px 0 0; color: var(--ink-muted); text-wrap: pretty; }

.result-meta {
  display: grid;
  gap: 8px;
  margin: 22px 0 0;
  padding: 16px 18px;
  text-align: left;
  background: var(--marble);
  border-radius: var(--radius);
  font-size: 14px;
}
.result-meta > div { display: flex; justify-content: space-between; gap: 16px; }
.result-meta dt { color: var(--ink-muted); }
.result-meta dd { margin: 0; font-weight: 600; text-align: right; word-break: break-all; }

.result-note { margin: 18px 0 0; font-size: 14px; color: var(--tulsi); }
.result-actions { margin-top: 22px; }

@media (prefers-reduced-motion: reduce) {
  /* The mark still appears - only the drawing of it is dropped. Removing the
     animation must not remove the information. */
  .result-card, .result-modal::backdrop { animation: none; }
  .result-ring .ring, .result-ring .tick, .result-ring .cross { stroke-dashoffset: 0; }
  .result-emblem.is-drawn .ring,
  .result-emblem.is-drawn .tick,
  .result-emblem.is-drawn .cross { transition: none; }
}

/* ---- voucher status ---- */
/* What a patron sees on their own phone. Deliberately plain: the useful
   version of this page is the one held up at a counter in poor light. */
.voucher-page { padding-top: 8px; }
.voucher-card {
  padding: 34px 26px;
  text-align: center;
  border-radius: var(--radius-lg);
  border: 1px solid var(--gold-soft);
  background: var(--panel);
}
.voucher-card h1 { font-size: clamp(24px, 5vw, 34px); margin: 0; line-height: 1.15; text-wrap: balance; }
.voucher-eyebrow {
  margin: 0 0 8px; font-size: 12px; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--ink-muted);
}
.voucher-for { margin: 14px 0 0; font-size: 19px; font-weight: 600; }
.voucher-note { margin: 18px 0 0; color: var(--ink-muted); }
.voucher-card.is-valid { border-color: var(--ok-line); background: linear-gradient(135deg, var(--ok-tint), var(--ok-soft)); }
.voucher-card.is-valid h1 { color: var(--ok); }
.voucher-card.is-used { background: var(--marble-deep); }
.voucher-card.is-invalid { border-color: rgba(179, 36, 29, 0.3); }
.voucher-card.is-invalid h1 { color: var(--kumkum); }

/* --- Standing monthly sevas (/subscription) ---------------------------------
 *
 * One card, three decisions, four fields. Everything optional is inside a
 * <details> so the donor who does not want it never sees it: the evidence on
 * donation forms is that each visible field costs completion, and this page
 * exists to be finished rather than admired.
 */
.subscription-page { padding-bottom: 4rem; }

/* Story left, form right. Same proportions as a campaign page, because the
 * reading is the same shape: a long argument beside a short decision. */
.subscription-body {
  max-width: 1100px;
  margin: 0 auto;
  padding: clamp(2rem, 6vw, 3rem) var(--gutter, 1.25rem) 0;
  display: grid;
  grid-template-columns: 1.5fr 1fr;
  gap: 40px;
  align-items: start;
}

.subscription-story { min-width: 0; }

.subscription-panel {
  min-width: 0;
  position: sticky;
  /* Clear of the fixed header, with a little air. */
  top: 88px;
}

@media (max-width: 860px) {
  .subscription-body {
    grid-template-columns: 1fr;
    gap: 0;
    padding: 2rem var(--gutter, 1rem) 0;
  }
  /* Sticky is for the desktop column, where the form stays in view beside a
   * long story. In one column it pins the form over everything under it. */
  .subscription-body > .subscription-panel { position: static; top: auto; }
}

.subscription-intro h1 {
  font-size: clamp(1.75rem, 4.5vw, 2.6rem);
  line-height: 1.15;
  margin: 0.25rem 0 0.75rem;
  text-wrap: balance;
}

.subscription-intro .lede {
  color: var(--ink-muted);
  max-width: 34rem;
  font-size: 1.05rem;
}

/* The scriptural case, between the lede and the form. Sized as a reading
   column rather than as a panel: this is the only passage on the public site a
   donor is meant to read slowly, and a card around it would make it skimmable
   furniture next to the form. The gold rules do the separating instead. */
.seva-case {
  margin-top: 2rem;
  font-size: 1.02rem;
  line-height: 1.7;
  color: var(--ink);
}

.seva-case h2 {
  font-size: clamp(1.25rem, 3vw, 1.5rem);
  margin-bottom: 0.9rem;
}

.seva-case > p { margin: 0 0 1.25rem; max-width: 38rem; text-wrap: pretty; }

/* The verse itself. The one element here that is a panel, because a quoted
   śloka is not prose and should not scan as a paragraph someone may skip. */
.seva-case .verse {
  margin: 0 0 1.5rem;
  padding: 1.1rem 1.25rem;
  background: var(--marble-deep);
  border: 1px solid var(--gold-soft);
  border-radius: var(--radius);
  text-align: center;
}

.seva-case .verse-line {
  font-family: var(--font-display);
  font-size: clamp(1.05rem, 2.6vw, 1.3rem);
  line-height: 1.4;
  margin: 0 0 0.6rem;
  color: var(--gold-deep);
  text-wrap: balance;
}

.seva-case .verse figcaption {
  font-size: 0.95rem;
  font-style: italic;
  color: var(--ink-muted);
  text-wrap: pretty;
}

.seva-case blockquote {
  margin: 0 0 1.4rem;
  padding: 0.15rem 0 0.15rem 1.1rem;
  border-left: 3px solid var(--gold-soft);
}

.seva-case blockquote p { margin: 0; text-wrap: pretty; }

/* Both the verse's source and the speaker. display: block so the attribution
   takes its own line under a quote of any length, rather than trailing the
   last word of one and sitting alone after another. */
.seva-case cite {
  display: block;
  margin-top: 0.5rem;
  font-style: normal;
  font-size: 0.9rem;
  letter-spacing: 0.02em;
  color: var(--gold-deep);
}

.seva-case .verse cite { margin-top: 0.75rem; }

.subscription-card {
  background: var(--panel);
  border: 1px solid var(--gold-soft);
  border-radius: var(--radius-lg);
  padding: clamp(1.25rem, 4vw, 2rem);
  margin-top: 0;
  box-shadow: var(--shadow-warm);
}

.subscription-empty {
  background: var(--panel);
  border: 1px solid var(--gold-soft);
  border-radius: var(--radius);
  padding: 1.5rem;
  margin-top: 1.5rem;
  color: var(--ink-muted);
}

.subscription-card .field { margin-bottom: 1.1rem; }

.subscription-card label,
.subscription-card #amount-label {
  display: block;
  font-weight: 600;
  margin-bottom: 0.4rem;
  color: var(--ink);
}

.subscription-card .optional { font-weight: 400; color: var(--ink-muted); }

.subscription-card select,
.subscription-card input,
.subscription-card textarea {
  width: 100%;
  padding: 0.7rem 0.85rem;
  border: 1px solid var(--gold-soft);
  border-radius: var(--radius);
  background: #fff;
  color: var(--ink);
  font: inherit;
  /* 16px minimum, or iOS Safari zooms the whole page on focus. */
  font-size: max(1rem, 16px);
}

.subscription-card select:focus-visible,
.subscription-card input:focus-visible,
.subscription-card textarea:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}

.field-row {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0 1rem;
}

@media (max-width: 36rem) {
  .field-row { grid-template-columns: 1fr; }
}

/* The amount is the most important decision on the page, so it is laid out as
 * choices rather than a <select>, which would hide every option but one. */
.amount-choices {
  /* A grid, not wrapping flex. Four amounts under flex:1 1 6rem came out as
   * three across and a stretched orphan on a phone; auto-fit gives two even
   * rows there and one row of four on a laptop. */
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(7rem, 1fr));
  gap: 0.5rem;
}

.amount-choice {
  /* 44px, the smallest comfortable touch target. */
  min-height: 44px;
  padding: 0.6rem 0.9rem;
  border: 1.5px solid var(--gold-soft);
  border-radius: var(--radius);
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-weight: 600;
  font-size: 1.05rem;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}

.amount-choice:hover { border-color: var(--gold); }

.amount-choice[aria-checked="true"] {
  border-color: var(--kumkum);
  background: var(--kumkum);
  color: #fff;
}

/* Twenty-eight days as a grid, not a dropdown. Seven across so the columns
 * read as weeks without claiming to be a calendar - there is no month here,
 * and no year, because the choice is "the 9th of every month". */
.day-field {
  border: 0;
  padding: 0;
  margin: 0 0 1.1rem;
}

.day-field legend {
  padding: 0;
  margin-bottom: 0.45rem;
}

.day-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 0.35rem;
}

.day-grid .day {
  /* Square, and never under the 44px a thumb needs. */
  aspect-ratio: 1;
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1.5px solid var(--gold-soft);
  border-radius: var(--radius);
  background: #fff;
  color: var(--ink);
  font: inherit;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  transition: border-color 120ms ease, background 120ms ease;
}

.day-grid .day:hover { border-color: var(--gold); }

.day-grid .day:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 1px;
}

.day-grid .day.chosen {
  border-color: var(--kumkum);
  background: var(--kumkum);
  color: #fff;
  font-weight: 600;
}

.seva-note,
.field-note {
  margin: 0.4rem 0 0;
  color: var(--ink-muted);
  font-size: 0.92rem;
}

.subscription-card .extras {
  border-top: 1px solid var(--gold-soft);
  padding-top: 0.9rem;
  margin-bottom: 1rem;
}

.subscription-card .extras > summary {
  cursor: pointer;
  font-weight: 600;
  color: var(--gold-deep);
  min-height: 44px;
  display: flex;
  align-items: center;
}

.subscription-card .extras[open] > summary { margin-bottom: 0.75rem; }

.subscription-card .btn-donate { width: 100%; margin-top: 0.5rem; }

.subscription-card .give-notes {
  list-style: none;
  padding: 0;
  margin: 1.1rem 0 0;
  color: var(--ink-muted);
  font-size: 0.92rem;
}

.subscription-card .give-notes li { margin-bottom: 0.35rem; }

.subscription-card .form-error {
  color: var(--kumkum-dark);
  margin: 0.5rem 0 0;
  min-height: 1.2em;
}
