/* ═══════════════════════════════════════════════════════════════
   SAHAYATA CARE — Swiss grid, elder-legible scale.
   Everything you are likely to change lives in two places:
     · the :root token block below
     · the CONFIG object at the top of the script
   ═══════════════════════════════════════════════════════════════ */

:root{
  /* Committed to one visual world: the paper the brand is printed on.
     No dark theme — the logo's deep teal wordmark is unreadable on a dark
     ground, and a care brand should look the same on every device it
     reaches. Everything below is painted explicitly for that reason. */
  color-scheme:light;
  /* ── TYPE, DECLARED ONCE ──────────────────────────────────────────────
     RAJ: "change the font to poppins universal... I want a central css that
     guides all the pages. no hard coded css within the frontend layer."

     The family name was written out SEVENTEEN times in this file. Changing
     the typeface meant editing every one of them, and missing a single line
     left one element in the old face -- the kind of near-invisible
     inconsistency that makes a site feel unfinished without anybody being
     able to say why. Now it is three values.

     --font      Questrial, for running text -- the body face from Raj's
                 Structura reference. ONE WEIGHT ONLY (400), which is why
                 --font-head exists rather than bolding this one: asking a
                 browser to embolden Questrial gets a synthesised smear, not
                 a bold. Anything that needs weight uses Nunito.
     --font-head Nunito, for headings, navigation, buttons, labels and
                 figures. Carries 400-900, so the hierarchy is real weight.
                 Neither face has Telugu glyphs, so the Telugu stack falls
                 through per character.
     --font-te   NTR for the Telugu itself, ahead of Noto Sans Telugu -- Raj
                 chose it and the order in this list is what decides, not the
                 presence of a name. Noto stays behind it as the fallback for
                 a machine where NTR fails to load, and Nirmala UI / Gautami
                 behind that for Windows offline. NTR ships ONE weight, so
                 Telugu hierarchy is built from size, never from bold:
                 font-synthesis-weight:none below stops the browser
                 manufacturing a bold that would render the vowel signs as
                 mush.
     --font-te  Telugu. On Windows and some Android builds the default face
                has no Telugu, and what it substitutes renders vowel signs
                detached from their consonant -- gibberish to a Telugu
                reader, not merely an ugly font.
     --font-num Numerals and labels: rupee figures, counts, eyebrows.

     RAJ, TWICE: "make it universal in css". It was IBM Plex Mono, and that
     was the answer both times he asked -- sixteen rules used it, so the
     eyebrows, the facts numbers, every price and every tag rendered in a
     monospace face while the rest of the page was Poppins. It is now Poppins
     too, and the site has ONE family.

     The token stays rather than being deleted into --font, because those
     sixteen places are a real role -- figures and tracked-out labels -- and
     pointing the role at a different face later should stay a one-line
     change. What is gone is the second typeface, not the distinction.

     WHAT WAS GIVEN UP, MEASURED RATHER THAN GUESSED. Mono gave every digit
     the same width, so a column of figures lined up. Poppins ships no
     tabular figures and its digits are properly proportional: at the 54px
     price size a "1" is 20.3px against a "4" at 36.6px -- an 80% spread.
     ₹4,500 and ₹7,500 are 7.7px apart in overall width. The
     `font-variant-numeric: tabular-nums` on body is now a no-op; it is left
     in place because it costs nothing and starts working again the day a
     face that supports it is chosen.

     WHY IT DOES NOT BITE HERE. Nothing on this site stacks numbers in a
     column. The three prices sit in three side-by-side cards, each
     left-aligned inside its own card, so their differing widths never meet.
     The facts strip has the same arrangement, with min-width:3.2ch holding
     the text after each number in line.

     SO: the day somebody builds a table of figures -- an invoice, a usage
     summary, a rate card with a right-aligned amount column -- it will look
     crooked, and this line is why. Give that table its own mono token
     rather than reaching for one globally. */
  --font:"Questrial","Helvetica Neue",Helvetica,Arial,sans-serif;
  --font-head:"Nunito","Helvetica Neue",Helvetica,Arial,sans-serif;
  --font-te:"Nunito","NTR","Noto Sans Telugu","Nirmala UI",Gautami,sans-serif;
  --font-num:var(--font-head);

  /* ground + ink — neutrals biased a few degrees toward the brand teal
     so the paper belongs to the mark rather than sitting under it */
  --paper:#FFFFFF;
  --panel:#FFFFFF;
  --band:#0A3335;
  --band-ink:#EDF3F2;
  --ink:#272727;
  --ink-2:#4C4C4C;
  --rule:#E6E6E6;
  --rule-soft:#F0F0F0;
  /* the accent, straight off the logo.
     --teal      #178687  the mark's deep teal — fills, rules, large type
     --teal-ink  #0B5C5C  7.1:1 on paper — anything small enough to read
     --sage      #77B3AC  the mark's light hand — decoration, never text */
/* ── WHERE THE TEAL IS ALLOWED ────────────────────────────────────────────
   RAJ: "keep the tarquish green but use it to minimal."

   The reference page is white and its accent appears roughly twice on a
   screenful. Teal was doing far more work than that here -- every section
   number, every pictogram, every big figure in the facts strip -- and a
   colour used everywhere stops being an accent and becomes the background.

   IT NOW APPEARS IN SIX PLACES AND NOWHERE ELSE:
     · the second half of the hero sentence ("Not in an old age home")
     · the underline under the current nav item
     · the small square markers in the plan lists and the dropdown
     · the rule under the phone number on the contact page
     · the WhatsApp button, which is a brand cue rather than decoration
     · focus rings, which are not decoration at all

   Everything else that was teal is now ink or grey: the numbers, the
   pictograms, the eyebrows, the group counts. If the page ever feels too
   plain, this list is the place to add one back -- deliberately, one at a
   time. */
  --teal:#178687;
  --teal-ink:#0B5C5C;
  --teal-wash:#F2F7F6;
  --sage:#77B3AC;
  /* metrics */
  --pad:clamp(20px,5vw,64px);
  --maxw:1170px;
  --band-soft:#FAFAFA;   /* the only tone on the page besides white */
  --t-hero:clamp(2.1rem,4.2vw,3.25rem);
  --t-h2:clamp(1.6rem,2.6vw,2rem);
  --t-h3:clamp(1.15rem,1.5vw,1.375rem);
  --t-lead:clamp(1.05rem,1.3vw,1.1875rem);
  --t-body:clamp(1.0625rem,1.15vw,1.1875rem);
  --t-label:0.78rem;
  --ease:cubic-bezier(.2,.7,.3,1);
}

*,*::before,*::after{box-sizing:border-box}

/* THE hidden ATTRIBUTE HAS TO WIN. Its default is display:none, which any
   display: rule outranks -- so `.btn{display:inline-flex}` quietly made
   hidden="" do nothing, and the slider showed both of its calls to action at
   once. Every element on this page that sets display is a candidate for the
   same bug; one rule ends it. */
[hidden]{display:none !important}
html{-webkit-text-size-adjust:100%}
/* ── ONE FAMILY, ON EVERYTHING, WITH NO EXCEPTIONS ───────────────────────
   RAJ, THREE TIMES: "poppins ... universal ... no matter what."

   It was set on `body` alone, which leaves two gaps, and an audit of all
   nine pages in both languages found both of them:

   1. FORM CONTROLS DO NOT INHERIT. A browser gives input, select, textarea
      and button their own font from the operating system, so they ignore
      whatever body says. Four radio inputs on the contact form and two
      hidden fields were rendering in Arial. Individual rules had set
      `font:inherit` on the visible text fields one at a time -- which is
      how the ones nobody looks at got missed.

   2. <html> ITSELF was on the browser default. Nothing renders there today,
      but anything ever placed outside <body>, and any element that resolves
      its font before body applies, gets Times New Roman.

   Set on the root, inherited by everything, and force-inherited by the
   controls that refuse to. Adding a rule per element type is what produced
   the gaps; this is the rule that cannot have a gap. */
html{font-family:var(--font)}

/* NAMED, NOT INHERITED. `font-family:inherit` only promises a control will
   match its PARENT -- so the day any wrapper sets a different family, every
   field inside it quietly follows. Naming the token means a form control
   cannot deviate from the site face whatever it is sitting in. Same reason
   the placeholder and the dropdown's own options are listed: the placeholder
   is a pseudo-element and does not inherit from the input, and `option` is
   drawn from its own box.

   `select` is the honest exception: on Windows the OPEN dropdown list is
   painted by the operating system, outside the page, and no stylesheet
   reaches it. The closed control obeys this rule. */
button,input,optgroup,select,textarea,option,
::placeholder,::file-selector-button{font-family:var(--font)}

/* THE CLASS, AS WELL. Every field in the markup carries class="input" and
   this names the family on it directly. The element selectors above are the
   safety net for a control somebody adds later and forgets to class; this is
   the thing you can see in the HTML and check by eye. Two ways of saying the
   same thing on purpose -- a form field is where a stray system font is most
   likely to appear and least likely to be noticed. */
.input,.input::placeholder{font-family:var(--font)}
html[lang="te"] .input,html[lang="te"] .input::placeholder{font-family:var(--font-te)}
html[lang="te"] button,html[lang="te"] input,html[lang="te"] optgroup,
html[lang="te"] select,html[lang="te"] textarea,html[lang="te"] option,
html[lang="te"] ::placeholder,html[lang="te"] ::file-selector-button{font-family:var(--font-te)}

body{
  margin:0; background:var(--paper); color:var(--ink);
  font-family:var(--font);
  font-size:var(--t-body); line-height:1.75;
  font-variant-numeric:tabular-nums;
}
/* Telugu resolves the same way, from the root down. Poppins stays FIRST in
   the stack: it has no Telugu letters, so the Telugu falls through to a face
   that does, while the Latin inside a Telugu sentence -- a number, a rupee
   figure, "WhatsApp" -- is still drawn in Poppins. That per-character
   fallback is the browser's, not a setting, and no amount of CSS makes
   Poppins draw a letter it does not contain. */
/* SWITCH THE TOKENS, NOT THE ELEMENTS. Setting font-family on <html> alone
   was not enough and the bug was invisible: every heading, the navigation,
   the buttons and the labels name --font-head directly, so they kept the
   Latin stack in Telugu and NTR never got near them. Redefining the two
   tokens here fixes every rule that uses them at once, and a rule added
   later is covered without anyone remembering this. */
html[lang="te"]{
  font-synthesis-weight:none;
  --font:var(--font-te);
  --font-head:var(--font-te);
  font-family:var(--font-te);
}
html[lang="te"] body{
  font-family:var(--font-te);
  line-height:1.9; font-size:calc(var(--t-body) * 1.06);
}
h1,h2,h3,h4{margin:0; font-family:var(--font-head); text-wrap:balance; font-weight:800; line-height:1.2; letter-spacing:-.01em}
html[lang="te"] h1,html[lang="te"] h2,html[lang="te"] h3{
  line-height:1.34; letter-spacing:0; font-weight:400; font-synthesis-weight:none;
}
html[lang="te"] .plan .tagline,html[lang="te"] .facts b,html[lang="te"] b{font-weight:400}
p{margin:0}
a{color:inherit}
img,svg{max-width:100%}

/* Paper. Generated, not licensed — a tiling turbulence grain plus one soft
   wash of the logo's light hand, so the white has a temperature without
   costing a file, a download or a licence to keep track of. */
/* THE TEXTURE IS GONE. It was two teal washes and a noise tile over the
   whole page -- warmth, and the opposite of what Raj's reference does. That
   page is white, and every bit of its calm comes from white space and
   hairlines rather than from a tinted ground. Kept in the file, commented,
   because it is three lines to put back if the site ever feels too clinical.

body::before{ ... two radial teal washes plus a turbulence tile ... }  */

.wrap{max-width:var(--maxw); margin-inline:auto; padding-inline:var(--pad)}

/* ── the eyebrow: mono, tracked, always paired with a rule ── */
.eyebrow{
  font-family:var(--font-num);
  font-size:var(--t-label); font-weight:500;
  letter-spacing:.16em; text-transform:uppercase; color:var(--ink-2);
}
html[lang="te"] .eyebrow{font-family:var(--font-te); letter-spacing:.06em; font-weight:700}
.num{
  font-family:var(--font-num);
  font-size:var(--t-label); font-weight:600; color:var(--ink-2);
  letter-spacing:.1em;
}

/* ═══ HEADER ═══ */
.top{
  position:sticky; top:0; z-index:60;
  background:var(--paper); border-bottom:1px solid var(--rule);
}
.top-in{
  max-width:var(--maxw); margin-inline:auto; padding:14px var(--pad);
  display:flex; align-items:center; gap:24px; flex-wrap:wrap;
}
.mark{display:flex; align-items:center; margin-right:auto; text-decoration:none}
.mark img{display:block; height:clamp(38px,5vw,54px); width:auto}
.mark:focus-visible{outline:3px solid var(--teal); outline-offset:4px}
.mark-foot{margin:0 0 16px; display:inline-flex}
.mark-foot img{height:52px}
.nav{display:flex; gap:4px; flex-wrap:wrap; align-items:center}
.nav a{
  font-family:var(--font-head);
  text-decoration:none; padding:10px 14px; border-radius:2px;
  font-weight:600; font-size:1rem; color:var(--ink-2);
  border-bottom:3px solid transparent;
}
.nav a:hover{color:var(--ink); background:var(--rule-soft)}
.nav a[aria-current="page"]{color:var(--ink); border-bottom-color:var(--teal)}

/* language toggle — a two-state switch, not a dropdown */
/* ── THE LANGUAGE PICKER ──────────────────────────────────────────────────
   RAJ: "change the languages into dropdown."

   It is a real <select> now, wearing the same drawn control the contact form
   uses -- so there is ONE dropdown on this site rather than a form one and a
   header one that drift apart. Two languages today; adding a third is a
   single <option>, where the old two-button switch would have needed a new
   layout.

   COMPACT, because it sits in a header next to the text-size control and the
   navigation: 44px rather than the form's 56px, and the type a step down. The
   list it opens is the same list, at the same 60px rows, because that is
   where the tapping happens. */
.lang{display:flex}
.lang .dd{min-width:9.5rem}

/* ═══ SHARED SECTION FURNITURE ═══ */
section{border-top:1px solid var(--rule)}
section:first-of-type{border-top:0}
.sec{padding-block:clamp(52px,7vw,104px)}
.sec-head{
  display:grid; grid-template-columns:minmax(0,1fr); gap:14px;
  padding-bottom:clamp(28px,4vw,52px);
}
@media(min-width:820px){
  .sec-head{grid-template-columns:180px minmax(0,1fr); gap:0 48px; align-items:start}
}
.sec-head h2{font-size:var(--t-h2)}
.sec-head .lead{margin-top:16px; font-size:var(--t-lead); color:var(--ink-2); max-width:62ch}

/* ═══ HERO ═══ */
.hero{padding-block:clamp(44px,7vw,92px)}
.hero .rule-top{display:flex; align-items:center; gap:16px; padding-bottom:clamp(24px,4vw,40px)}
.hero .rule-top hr{flex:1; border:0; border-top:1px solid var(--rule); margin:0}
.hero h1{
  font-size:var(--t-hero); max-width:17ch;
}
.hero h1 em{font-style:normal; color:var(--teal); display:block; margin-top:.12em}
.hero .sub{
  margin-top:clamp(22px,3vw,32px); font-size:var(--t-lead);
  color:var(--ink-2); max-width:56ch;
}
.hero-grid{display:grid; gap:clamp(28px,4vw,56px)}
@media(min-width:960px){.hero-grid{grid-template-columns:minmax(0,1.25fr) minmax(0,1fr); align-items:start}}

/* the facts strip runs the full width beneath the hero, four across */
.facts{
  display:grid; gap:0; border-top:1px solid var(--rule);
  margin-top:clamp(36px,5vw,64px);
}
@media(min-width:820px){.facts{grid-template-columns:repeat(4,1fr)}}
.facts div{
  display:grid; grid-template-columns:auto 1fr; gap:14px; align-items:baseline;
  padding:18px 24px 18px 0; border-bottom:1px solid var(--rule);
}
@media(min-width:820px){
  /* THE DIVIDER NEEDS AIR ON BOTH SIDES. Each cell only had padding on its
     right, so the "80" and the "1" sat hard against the rule of the cell
     before them -- fine for the first column, which has the section margin,
     and cramped for the other three. Padding on the left of every cell, then
     taken back off the first so the strip still lines up with the headline
     above it. */
  .facts div{border-bottom:0; border-right:1px solid var(--rule); align-content:start;
    padding-left:28px}
  .facts div:first-child{padding-left:0}
  .facts div:last-child{border-right:0; padding-right:0}
  .facts div:last-child{border-right:0}
}
.facts b{
  font-family:var(--font-num); font-size:1.6rem;
  font-weight:600; color:var(--ink); min-width:3.2ch;
}
.facts span{color:var(--ink-2); font-size:max(12px,.99rem); line-height:1.45}

/* ═══ IMAGE SLOTS ═══
   Every photograph on this page is a .shot. Drop a real file in and the
   placeholder disappears on its own — the <img> covers the frame when it
   loads and stays hidden (alt text suppressed) when there is no src yet. */
.shot{
  position:relative; margin:0; overflow:hidden; background:var(--teal-wash);
  border:1px solid var(--rule); min-height:280px;
}
.shot-hero{aspect-ratio:4/5}
.shot img{
  position:absolute; inset:0; width:100%; height:100%;
  object-fit:cover; display:block;
}
.shot img:not([src]),.shot img[src=""]{display:none}
.shot-art{position:absolute; inset:0; width:100%; height:100%; display:block}
.shot:has(img[src]) .shot-art,.shot:has(img[src]) .shot-mark{display:none}
.shot-mark{
  position:absolute; inset:0; display:flex; flex-direction:column;
  justify-content:flex-end; gap:6px; padding:22px;
  font-family:var(--font-num); font-size:max(12px,.74rem);
  letter-spacing:.1em; text-transform:uppercase; color:var(--ink-2);
}
.shot-mark b{font-size:max(12px,.95rem); letter-spacing:.04em; color:var(--ink)}
.shot-mark::before,.shot-mark::after{
  content:""; position:absolute; width:34px; height:34px;
  border:1px solid var(--rule); pointer-events:none;
}
.shot-mark::before{top:16px; left:16px; border-right:0; border-bottom:0}
.shot-mark::after{bottom:16px; right:16px; border-left:0; border-top:0}

/* ═══ GROUP PICTOGRAMS ═══ */
.gicon{width:44px; height:44px; color:var(--ink); flex:none}
.gicon svg{display:block; width:100%; height:100%}

/* ═══ BUTTONS — 56px min, the elder floor ═══ */
.actions{display:flex; flex-wrap:wrap; gap:12px; margin-top:clamp(28px,4vw,40px)}
.btn{
  /* POSITION:RELATIVE IS LOAD-BEARING, and its absence was a real bug. The
     two flip faces are position:absolute; inset:0, so they size themselves
     against the nearest POSITIONED ancestor. Without this line a button that
     happened to sit inside a positioned parent looked right, and one that did
     not had its faces resolve against the viewport -- a white panel 1400px
     wide and the full height of the screen, painted over the whole page. It
     looked like the page had failed to render. */
  position:relative;
  display:inline-flex; align-items:center; justify-content:center; gap:10px;
  min-height:60px; padding:0 26px; border:1px solid var(--ink); border-radius:2px;
  font:inherit; font-family:var(--font-head); font-weight:700; font-size:1.08rem; text-decoration:none;
  background:var(--ink); color:#fff; cursor:pointer;
  transition:transform .16s var(--ease), background .16s var(--ease), color .16s var(--ease);
}
/* ═══ BUTTON MOTION ═══════════════════════════════════════════════════════
   RAJ's reference: paul-themes.com/html/supershot — "the first time when it
   comes on to the screen they dangle, and after that, when user hovers mouse
   pointer, it rotates vertically." Buttons only; nothing else on the page
   moves.

   Both effects are rebuilt here in this site's own colours and sizes. The
   TECHNIQUE is what was taken, and it is worth writing down because neither
   is obvious:

   THE FLIP is two stacked faces, not one element turning over. The button
   keeps a hidden copy of its own content to hold the box open at the right
   size, and two absolutely-positioned faces sit on top of it. At rest the
   front is at rotateX(0) and the back is folded away at rotateX(90deg); on
   hover the front folds to -90 and the back unfolds to 0. They cross at the
   horizontal, so it reads as one panel turning on a rod through its middle.

   NO `perspective`, deliberately, and the reference does not use one either.
   With perspective the face nearer the eye grows as it turns, which at this
   size looks like a wobble rather than a turn. Without it the rotation is a
   clean vertical shutter.

   THE FACES CARRY THE COLOUR. The button element itself goes transparent
   once enhanced, so the front face holds what .btn/.btn-primary/.btn-accent
   used to paint and the back face holds what their :hover used to. The
   colour logic is unchanged -- it is delivered by a fold instead of a fade.

   THE DANGLE is a damped pendulum, transform-origin at top centre, fired
   once when the button first scrolls into view. The swing angles are the
   reference's own (15, -10, 5, -5) and live in --btn-swing: one number, one
   place, if it wants calming down. It is a lot of movement for a page read
   by people in their seventies, which is why reduce-motion switches both
   effects off completely rather than shortening them. */

.btn:hover{transform:translateY(-2px)}

/* Once the faces are built, the element is only a box: the look moved. */
/* The element gives up its own border as well as its background: with
   box-sizing:border-box the faces sit at inset:0 on the padding box, so a
   border left on the button would show as a hairline ring a pixel outside
   every face. The faces carry the border now. */
.btn[data-flip]{background:transparent; border-width:0; transition:none}
.btn[data-flip]:hover{transform:none}

/* Holds the button open at exactly the size it was before -- AND is the only
   copy a screen reader can see. The two faces are aria-hidden, so if this one
   were visibility:hidden (which also removes an element from the
   accessibility tree) the button would have no accessible name at all: a
   "Call us" link announced as an unlabelled link. opacity:0 keeps it in the
   tree while taking it off the screen. The reference template has exactly
   this bug; it is not worth inheriting. */
.btn .btn-size{opacity:0; display:inline-flex; align-items:center; gap:10px}

.btn-face{
  font-family:var(--font-head); font-weight:700;
  position:absolute; inset:0; display:flex; align-items:center; justify-content:center;
  gap:10px; padding:0 26px; border:1px solid transparent; border-radius:2px;
  transition:transform .3s var(--ease);
  /* THE LABEL MUST WRAP THE SAME WAY IN BOTH COPIES, which is a different
     requirement from never wrapping. It was nowrap, and that made every
     button unshrinkable: "Save the contact card" wanted 230px, the column it
     sat in was 157px, and the button simply hung out over the form beside it.

     flex:none on the children is what actually fixes the original bug -- a
     label inside a face is a flex item and would otherwise shrink below its
     natural width and break onto a second line while the hidden sizing copy
     did not. With that in place both copies wrap at exactly the same point,
     so a button in a narrow column grows taller instead of wider, and the
     fold line follows it because --btn-half is re-measured on resize. */
}
.btn-face > *{flex:none}
/* THE FOLD LINE IS AT THE BOTTOM EDGE, NOT THE MIDDLE -- and translateZ is
   what puts it there. It looks pointless without a perspective, and I first
   left it out for that reason. It is not pointless: rotateX turns the Z axis
   into the Y axis, so a face rotated 90 degrees with translateZ(half the
   button height) collapses to a line half a button BELOW its own centre --
   which is the bottom edge. Drop the translateZ and both faces collapse at
   the middle, which is the difference Raj spotted.

   --btn-half is set per button by site.js and kept current by a
   ResizeObserver, because the button grows with the text-size control and a
   hardcoded 30px would fold in the wrong place at the largest step. */
.btn-face-front{transform:rotateX(0deg) translateZ(var(--btn-half,30px))}
.btn-face-back{transform:rotateX(90deg) translateZ(var(--btn-half,30px))}
.btn[data-flip]:hover .btn-face-front,
.btn[data-flip]:focus-visible .btn-face-front{transform:rotateX(-90deg) translateZ(var(--btn-half,30px))}
.btn[data-flip]:hover .btn-face-back,
.btn[data-flip]:focus-visible .btn-face-back{transform:rotateX(0deg) translateZ(var(--btn-half,30px))}

/* ── TWO FILLS AND ONE HOVER ──────────────────────────────────────────────
   RAJ: "one color for primary and one color for secondary buttons ... on
   hover, give the border and change the background to white with black text."

   It used to be four fills shading dark-to-light, which is why the hover read
   as a dimming rather than a change. Now there are exactly two resting
   colours and a single hover, the same for every button on the site:

     PRIMARY    teal    -- every call to action, including WhatsApp
     SECONDARY  ink     -- everything else
     HOVER      white ground, black text, black border -- all of them

   Teal on the primaries is the one deliberate exception to keeping the colour
   minimal: it is not decoration there, it is the mark of "this is the thing
   to press". */
.btn .btn-face-front{background:var(--ink); color:#fff; border-color:var(--ink)}
.btn-primary .btn-face-front,
.btn-accent .btn-face-front{background:var(--teal); color:#fff; border-color:var(--teal)}

/* one hover, every button */
.btn .btn-face-back,
.btn-primary .btn-face-back,
.btn-accent .btn-face-back{background:#FFFFFF; color:var(--ink); border-color:var(--ink)}

@keyframes btn-dangle{
  0%  {transform:rotate(0deg)}
  20% {transform:rotate(var(--btn-swing))}
  40% {transform:rotate(calc(var(--btn-swing) * -0.667))}
  60% {transform:rotate(calc(var(--btn-swing) * 0.333))}
  80% {transform:rotate(calc(var(--btn-swing) * -0.333))}
  100%{transform:rotate(0deg)}
}
.btn[data-enter="1"]{
  /* the fallback only; site.js sets a per-button angle from its width */
  --btn-swing:15deg;
  transform-origin:top center;
  animation:btn-dangle .9s ease both;
  animation-delay:var(--btn-delay,0ms);
}

@media (prefers-reduced-motion:reduce){
  /* The shadow still deepens -- that is information, not decoration. What
     goes is the travel, which is the part that causes trouble. */
  .plan,.sec-cost .plan-strip .pill{transition:box-shadow .2s linear}
  .plan:hover,.plan:focus-within,
  .sec-cost .plan-strip .pill:hover,.sec-cost .plan-strip .pill:focus-within{transform:none}
  .btn-face{transition:none}
  .btn[data-enter="1"]{animation:none}
  .btn[data-flip]:hover .btn-face-front,.btn[data-flip]:focus-visible .btn-face-front{transform:rotateX(0deg)}
  .btn[data-flip]:hover .btn-face-back,.btn[data-flip]:focus-visible .btn-face-back{transform:rotateX(90deg)}
  /* the colour change still has to happen, just without the fold */
  .btn[data-flip]:hover .btn-face-front{background:#FFFFFF; color:var(--ink); border-color:var(--ink)}
}
.btn:focus-visible{outline:3px solid var(--teal); outline-offset:3px}
.btn-primary{background:var(--teal); color:#fff; border-color:var(--teal)}
.btn-primary:hover{background:#FFFFFF; border-color:var(--ink); color:var(--ink)}
.btn-accent{background:var(--teal); border-color:var(--teal); color:#fff}
.btn-accent:hover{background:#FFFFFF; border-color:var(--ink); color:var(--ink)}
.btn svg{width:22px; height:22px; flex:none}

/* ═══ THE SIX GROUPS ═══ */
.groups{display:grid; gap:0; border-top:1px solid var(--rule)}
.group{
  display:grid; gap:6px 32px; padding:clamp(22px,3vw,32px) 0;
  border-bottom:1px solid var(--rule); align-items:start;
}
@media(min-width:820px){
  .group{grid-template-columns:46px 56px minmax(0,1.05fr) minmax(0,1.45fr) auto}
}
@media(max-width:819px){
  .group{grid-template-columns:auto 1fr; align-items:center}
  .group h3{grid-column:2}
  .group p,.group .count{grid-column:1/-1}
}
.group h3{font-size:var(--t-h3)}
.group p{color:var(--ink-2); font-size:1.02rem; line-height:1.5}
.group .count{
  font-family:var(--font-num); font-size:max(12px,.92rem);
  color:var(--ink-2); white-space:nowrap; align-self:center;
}

/* ═══ EMERGENCY BAND — the one inversion on the page ═══ */
.band{background:var(--band); color:var(--band-ink)}
.band .eyebrow{color:#8FBDB8}
.band h2{font-size:var(--t-h2)}
.band .lead{color:#BBD4D1}
.band-list{
  display:grid; gap:0; margin-top:clamp(28px,4vw,40px);
  border-top:1px solid #1E5052;
}
.band-list li{
  list-style:none; padding:15px 0; border-bottom:1px solid #1E5052;
  display:grid; grid-template-columns:auto 1fr; gap:16px; align-items:baseline;
}
.band-list li::before{content:"—"; color:var(--sage); font-weight:700}
.band-note{
  margin-top:28px; padding:20px 24px; border-left:4px solid var(--sage);
  background:#0F4143; color:#D3E4E1; max-width:64ch;
}

/* ═══ PLANS ═══ */
.plans{display:grid; gap:clamp(20px,3vw,28px)}
/* auto-fit, not a fixed two. The page used to know there were two plans; it
   reads them from the database now, so the grid has to take three or four
   without leaving one stranded on a row of its own. */
.plans{grid-template-columns:repeat(auto-fit,minmax(320px,1fr))}
/* ── A CARD COMING FORWARD ────────────────────────────────────────────────
   RAJ: "as if it is moving towards us. increase the shadow depth and give
   that illusion."

   Three things move together, and it only reads as depth because all three
   agree -- any one of them alone reads as a glitch:

     1. THE CARD GROWS, barely. 1.5%. Enough for the eye to register that the
        edges have moved outward; small enough that the text underneath does
        not visibly resample.
     2. THE SHADOW DEEPENS AND SPREADS. A near object casts a larger, softer,
        weaker-edged shadow than a distant one, so the blur roughly triples
        while the opacity only doubles. A shadow that got darker without
        getting softer would read as the card pressing DOWN into the page.
     3. IT RISES A LITTLE. 6px, which is what sells the shadow as a gap
        underneath rather than a dark outline around.

   THE RESTING SHADOW IS NOT ZERO, on purpose: going from no shadow to a deep
   one is a light being switched on, not an object approaching. The card
   starts already a millimetre off the page.

   scale() RATHER THAN A PERSPECTIVE AND translateZ: a real 3D translate on a
   card this wide skews the far edge, which at the top of a price card looks
   like a mistake rather than like depth.

   MODEST ON PURPOSE. This is read by people in their seventies, often with a
   hand that is not steady on a mouse; a card that leaps 20px under the
   cursor is unpleasant to use, and the shadow can carry the impression on
   its own. */
.plan{
  background:var(--panel); border:1px solid var(--rule);
  padding:clamp(28px,3.4vw,40px); display:flex; flex-direction:column; gap:20px;
  box-shadow:0 1px 2px rgba(39,39,39,.04), 0 4px 10px rgba(39,39,39,.03);
  transition:transform .26s var(--ease), box-shadow .26s var(--ease);
  will-change:transform;
}
.plan:hover,.plan:focus-within{
  transform:translateY(-6px) scale(1.015);
  box-shadow:0 2px 6px rgba(39,39,39,.06), 0 18px 40px rgba(39,39,39,.10);
}
.plan-top{display:flex; align-items:baseline; justify-content:space-between; gap:16px; flex-wrap:wrap}
.plan h3{font-size:clamp(1.7rem,2.6vw,2.2rem)}
.plan .tagline{color:var(--teal-ink); font-weight:600; font-size:1.05rem}
.price{display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; border-top:1px solid var(--rule); padding-top:20px}
.price .amt{
  font-family:var(--font-num);
  font-size:clamp(2.4rem,5vw,3.4rem); font-weight:600; letter-spacing:-.03em; line-height:1;
}
.price .per{color:var(--ink-2); font-size:1.02rem}
.price-year{color:var(--ink-2); font-size:1rem; margin-top:-6px}
.price-year b{color:var(--ink); font-weight:600}
.plan ul{margin:0; padding:0; display:grid; gap:0; border-top:1px solid var(--rule)}
.plan li{
  list-style:none; padding:13px 0; border-bottom:1px solid var(--rule-soft);
  display:grid; grid-template-columns:auto 1fr; gap:14px; align-items:baseline;
  font-size:1.02rem; line-height:1.5;
}
.plan li::before{content:""; width:9px; height:9px; background:var(--teal); transform:translateY(-2px)}
.plan .plan-foot{margin-top:auto}
.tax-line{
  margin-top:clamp(24px,3vw,32px); padding:16px 20px;
  background:transparent; border-left:2px solid var(--teal);
  color:var(--ink-2); font-size:1rem; max-width:70ch;
}
.held{
  margin-top:clamp(24px,3vw,32px); border-top:1px solid var(--rule); padding-top:20px;
  color:var(--ink-2); font-size:1rem; max-width:70ch;
}

/* ═══ HOW IT WORKS — a real sequence, so it is numbered ═══ */
.steps{display:grid; gap:0; border-top:1px solid var(--rule); counter-reset:s}
@media(min-width:900px){.steps{grid-template-columns:repeat(4,1fr); border-top:0}}
.step{padding:24px 0; border-bottom:1px solid var(--rule)}
@media(min-width:900px){
  .step{border-top:1px solid var(--rule); border-bottom:0; padding:24px 28px 0 0}
}
.step .n{
  font-family:var(--font-num); font-weight:600;
  color:var(--ink-2); font-size:max(12px,.95rem); letter-spacing:.1em;
}
.step h3{font-size:1.28rem; margin-top:12px}
.step p{margin-top:10px; color:var(--ink-2); font-size:1rem; line-height:1.55}

/* ═══ QR ═══ */
.qr-row{display:grid; gap:clamp(28px,4vw,56px); align-items:center}
@media(min-width:820px){.qr-row{grid-template-columns:auto minmax(0,1fr)}}
.qr-plate{
  background:#fff; padding:20px; border:1px solid var(--rule);
  width:min(280px,72vw); justify-self:start; position:relative;
}
.qr-plate img{display:block; width:100%; height:auto}

/* ═══ CONTACT ═══ */
.contact-grid{display:grid; gap:clamp(32px,4vw,56px)}
@media(min-width:900px){.contact-grid{grid-template-columns:minmax(0,1fr) minmax(0,1fr)}}
.callnum{
  display:inline-block; text-decoration:none;
  font-family:var(--font-num);
  font-size:clamp(1.8rem,4.4vw,2.9rem); font-weight:600; letter-spacing:-.03em;
  border-bottom:4px solid var(--teal); padding-bottom:6px; line-height:1.2;
}
.callnum:hover{color:var(--teal-ink)}
.reach{display:grid; grid-template-columns:auto 1fr; gap:10px 20px; margin:26px 0 0;
  padding-top:20px; border-top:1px solid var(--rule); align-items:baseline}
.reach dt{font-family:var(--font-num); font-size:var(--t-label);
  letter-spacing:.14em; text-transform:uppercase; color:var(--ink-2)}
html[lang="te"] .reach dt{font-family:var(--font-te); letter-spacing:.04em}
.reach dd{margin:0; font-size:1.06rem}
.reach a{color:var(--teal-ink); text-decoration:none; border-bottom:2px solid var(--rule)}
.reach a:hover{border-bottom-color:var(--teal)}
.field{display:grid; gap:8px; margin-bottom:18px}
.field label{font-family:var(--font-head); font-weight:600; font-size:1.02rem}
.field input,.field select,.field textarea{
  font:inherit; font-size:1.05rem; padding:15px 14px; min-height:56px;
  background:var(--panel); color:var(--ink);
  border:2px solid var(--rule); border-radius:2px; width:100%;
}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:0; border-color:var(--ink); box-shadow:0 0 0 3px var(--teal-wash);
}

/* ═══ THE DROPDOWN, DRAWN BY US ═══════════════════════════════════════════
   RAJ: "use a custom style or custom dropdown but I don't want to deviate
   from the design language."

   A native <select> obeys the page when it is closed and the operating
   system when it is OPEN: Windows paints that list of choices outside the
   page entirely, in its own font, its own row height, its own blue
   highlight. No stylesheet reaches it. So the list is rebuilt here.

   THE NATIVE SELECT IS STILL THERE and is still the truth. It is hidden
   from sight and from the tab order, not removed: it keeps the field in the
   form, keeps `name="when"` submitting, and keeps the WhatsApp message and
   the enquiry POST reading `f.when.options[...]` exactly as they did. The
   drawn control is a face on it, not a replacement for it -- so if this
   JavaScript ever fails to run, the field degrades to a working native
   select rather than to nothing.

   ROWS ARE 60px, not the 28px an operating system gives you. Same floor as
   every other tap target on this site, for the same reason. */
.dd{position:relative}

.dd-native{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

.dd-btn{
  font-family:var(--font); font-size:1.05rem; text-align:left;
  padding:15px 14px; min-height:56px; width:100%; cursor:pointer;
  background:var(--panel); color:var(--ink);
  border:2px solid var(--rule); border-radius:2px;
  display:flex; align-items:center; justify-content:space-between; gap:12px;
}
.dd-btn:focus-visible{outline:0; border-color:var(--ink); box-shadow:0 0 0 3px var(--teal-wash)}

/* the header variant: shorter, tighter, same list underneath */
.dd-compact + .dd-btn,.dd .dd-btn.is-compact{min-height:44px}
.dd[data-compact] .dd-btn{
  min-height:44px; padding:8px 12px; font-size:max(12px,.95rem);
  font-family:var(--font-head); font-weight:700; border-color:var(--ink);
}
.dd[data-compact] .dd-chev{width:18px; height:18px}
.dd[data-open="1"] .dd-btn{border-color:var(--ink)}
.dd-chev{width:22px; height:22px; flex:none; color:var(--ink-2); transition:transform .16s var(--ease)}
.dd[data-open="1"] .dd-chev{transform:rotate(180deg)}

.dd-list{
  position:absolute; z-index:80; inset-inline:0; top:calc(100% + 6px);
  margin:0; padding:0; list-style:none; max-height:min(60vh,420px); overflow:auto;
  background:var(--panel); border:2px solid var(--ink); border-radius:2px;
  box-shadow:0 12px 32px rgba(10,51,53,.16);
}
.dd-opt{
  display:grid; grid-template-columns:9px 1fr; gap:14px; align-items:center;
  min-height:60px; padding:12px 16px; cursor:pointer;
  border-bottom:1px solid var(--rule-soft); font-size:1.05rem; line-height:1.4;
}
.dd-opt:last-child{border-bottom:0}
/* The selected row is marked with the same teal square the plan lists use,
   rather than a full-width highlight -- a filled bar reads as "hovered" to
   somebody who has just moved the mouse, and as nothing at all in print. */
.dd-opt::before{content:""; width:9px; height:9px; background:transparent}
.dd-opt[aria-selected="true"]::before{background:var(--teal)}
.dd-opt[aria-selected="true"]{font-weight:600}
.dd-opt:hover,.dd-opt[data-active="1"]{background:var(--teal-wash)}
.dd-opt[data-active="1"]{box-shadow:inset 3px 0 0 var(--teal)}

@media (prefers-reduced-motion:reduce){.dd-chev{transition:none}}
.choice{display:flex; gap:10px; flex-wrap:wrap; margin-bottom:22px}
.choice label{
  flex:1 1 200px; display:flex; gap:12px; align-items:center; cursor:pointer;
  border:2px solid var(--rule); padding:15px 16px; min-height:60px;
  font-weight:600; background:var(--panel);
}
.choice label:has(input:checked){border-color:var(--ink); background:var(--teal-wash)}
.choice label:has(input:focus-visible){outline:3px solid var(--teal); outline-offset:2px}
.choice input{width:22px; height:22px; accent-color:var(--teal); flex:none}
.form-note{color:var(--ink-2); font-size:max(12px,.98rem); margin-top:14px}
/* The honeypot. Off the page rather than display:none, because a bot that
   reads the stylesheet skips a hidden field and fills a visible one. */
.hp{position:absolute; left:-9999px; width:1px; height:1px; overflow:hidden}

/* ═══ SERVICES PAGE ═══ */
.svc-controls{
  display:grid; gap:14px; padding-block:20px;
  border-top:1px solid var(--rule); border-bottom:1px solid var(--rule);
  position:sticky; top:var(--hh,0px); background:var(--paper); z-index:40;
}
.chip-sep{
  align-self:stretch; width:1px; background:var(--rule); margin-inline:6px;
}
@media(max-width:539px){.chip-sep{display:none}}
.svc-search{
  font:inherit; font-size:1.08rem; padding:15px 16px; min-height:58px; width:100%;
  border:2px solid var(--ink); border-radius:2px; background:var(--panel); color:var(--ink);
}
.svc-search:focus{outline:0; box-shadow:0 0 0 3px var(--teal-wash)}
.chips{display:flex; gap:8px; flex-wrap:wrap}
.chip{
  font:inherit; font-weight:600; font-size:max(12px,.98rem); cursor:pointer;
  padding:11px 16px; min-height:48px; border-radius:2px;
  border:2px solid var(--rule); background:var(--panel); color:var(--ink-2);
}
.chip[aria-pressed="true"]{border-color:var(--ink); background:var(--ink); color:var(--paper)}
.chip:focus-visible{outline:3px solid var(--teal); outline-offset:2px}

.svc-group{border-top:1px solid var(--rule); padding-block:clamp(30px,4vw,52px)}
.svc-group:first-child{border-top:0}
.svc-group-head{display:flex; align-items:baseline; gap:16px; flex-wrap:wrap; margin-bottom:24px}
.svc-group-head h2{font-size:clamp(1.5rem,2.6vw,2.1rem)}
.shelf{margin-top:28px}
.shelf > .eyebrow{display:block; padding-bottom:10px; border-bottom:1px solid var(--rule)}
.svc-list{display:grid; gap:0}
.svc{
  display:grid; gap:4px 24px; padding:14px 0; border-bottom:1px solid var(--rule-soft);
  align-items:baseline;
}
@media(min-width:760px){.svc{grid-template-columns:minmax(0,1fr) 260px}}
.svc-name{font-size:1.06rem; font-weight:500; line-height:1.45}
.svc-name small{display:block; color:var(--ink-2); font-weight:400; font-size:max(12px,.94rem); margin-top:3px}
.tag{
  font-family:var(--font-num); font-size:max(12px,.76rem); font-weight:500;
  letter-spacing:.06em; text-transform:uppercase; padding:5px 9px; white-space:nowrap;
  border:1px solid var(--rule); color:var(--ink-2); display:inline-block; line-height:1.3;
}
html[lang="te"] .tag{font-family:var(--font-te); text-transform:none; letter-spacing:0}
.tag.t-both{border-color:var(--ink); color:var(--ink)}
.tag.t-samp{border-color:var(--teal); color:var(--teal-ink)}
.tag.t-every{background:var(--ink); color:var(--paper); border-color:var(--ink)}
.tag.t-arr{border-style:dashed}
.tag.t-soon{background:var(--rule-soft); border-color:var(--rule-soft)}
.svc-empty{padding:48px 0; color:var(--ink-2); font-size:1.1rem}

/* ═══ FOOTER ═══ */
.foot{border-top:1px solid var(--rule); padding-block:clamp(36px,4vw,56px); font-size:1rem}
.foot-grid{display:grid; gap:28px}
@media(min-width:760px){.foot-grid{grid-template-columns:1.5fr 1fr 1fr 1fr}}
.foot a{color:var(--ink-2); text-decoration:none; display:block; padding:7px 0}
.foot a:hover{color:var(--ink); text-decoration:underline}
.foot .fine{color:var(--ink-2); font-size:max(12px,.94rem); line-height:1.6; max-width:46ch}

/* ═══ STICKY MOBILE ACTION BAR ═══ */
.dock{
  position:fixed; left:0; right:0; bottom:0; z-index:70;
  display:grid; grid-template-columns:1fr 1fr; gap:0;
  border-top:1px solid var(--rule); background:var(--paper);
}
.dock a{
  display:flex; align-items:center; justify-content:center; gap:9px;
  min-height:62px; text-decoration:none; font-weight:700; font-size:1.05rem;
}
.dock a:first-child{border-right:1px solid var(--rule)}
.dock a.wa{background:var(--teal-ink); color:#fff}
.dock svg{width:21px; height:21px}
@media(min-width:760px){.dock{display:none}}
@media(max-width:759px){body{padding-bottom:64px}}

/* skip link */
.skip{position:absolute; left:-9999px; top:0; background:var(--ink); color:var(--paper); padding:14px 20px; z-index:100}
.skip:focus{left:0}

.hide{display:none !important}

/* ── MOTION ────────────────────────────────────────────────────
   Deliberately minimal for now: hover feedback, the language
   cross-fade, and nothing that moves on its own. This block is
   the single place to drop in a chosen animation direction.
   ────────────────────────────────────────────────────────────── */
.swap{transition:opacity .18s var(--ease)}
.swapping .swap{opacity:.25}
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{transition-duration:.001ms !important; animation-duration:.001ms !important}
  .btn:hover,.plan:hover{transform:none}
}

/* ═══ PAGE HERO — the shorter opener every page but the home page uses ═══ */
.page-hero{padding-block:clamp(36px,5vw,72px)}
.page-hero h1{font-size:clamp(2.1rem,4.6vw,3.4rem); max-width:20ch}
.page-hero .sub{max-width:60ch}

/* ═══ LEGAL PROSE ═══
   Measure is the whole job here: a policy nobody can read is a policy
   nobody reads. 68 characters, generous leading, real heading hierarchy. */
.prose{max-width:68ch}
.prose h2{
  font-size:clamp(1.15rem,1.9vw,1.4rem); margin:clamp(34px,4vw,46px) 0 12px;
  padding-top:20px; border-top:1px solid var(--rule);
}
.prose h2:first-of-type{margin-top:0}
.prose p{margin:0 0 16px; line-height:1.72}
.prose ul{margin:0 0 18px; padding-left:0; list-style:none; display:grid; gap:12px}
/* Positioned marker, NOT a grid column. These list items contain <b> and
   links, and with `display:grid` every inline child becomes its own grid
   item — which threw the bold lead-in of each item onto a row of its own. */
.prose li{position:relative; padding-left:26px; line-height:1.65}
.prose li::before{
  content:""; position:absolute; left:0; top:.6em;
  width:8px; height:8px; background:var(--teal);
}
.prose a{color:var(--teal-ink); text-decoration:none; border-bottom:2px solid var(--rule)}
.prose a:hover{border-bottom-color:var(--teal)}
.legal-note{
  margin:0 0 clamp(30px,4vw,44px); padding:18px 22px;
  background:var(--teal-wash); border-left:4px solid var(--teal);
  font-size:1rem; line-height:1.6;
}
.reach dd{margin:0}


/* ═══ PRICE STRIP (home page) ═══
   Deliberately NOT the pricing page's card. That one is for deciding between
   plans and carries the whole inclusion list; this one answers "roughly what
   does this cost" in one glance and sends the reader to the real card. Same
   data, less of it. */
.plan-strip{display:grid; gap:0; border-top:1px solid var(--rule); margin-top:clamp(20px,3vw,32px)}
@media(min-width:820px){.plan-strip{grid-template-columns:repeat(auto-fit,minmax(260px,1fr)); border-top:0}}
.plan-strip .pill{padding:22px 0; border-bottom:1px solid var(--rule)}
@media(min-width:820px){
  .plan-strip .pill{border-top:1px solid var(--rule); border-bottom:0; padding:22px 28px 22px 0}
}
.plan-strip .pill-top{display:flex; align-items:baseline; justify-content:space-between; gap:14px; flex-wrap:wrap}
.plan-strip h3{font-size:1.5rem}
.plan-strip .tagline{color:var(--teal-ink); font-weight:600; font-size:1.02rem; margin-top:6px}
.plan-strip .amt{
  font-family:var(--font-num); font-weight:600;
  font-size:clamp(1.9rem,3.4vw,2.5rem); letter-spacing:-.02em; display:block; margin-top:14px;
}
.plan-strip .per{color:var(--ink-2); font-size:1rem}

/* ── THE COST BAND ON THE HOME PAGE ───────────────────────────────────────
   RAJ: "give a grey background and the price tiers in white box. with
   rounded edges."

   The one tinted section on the site. It earns the tint: on a page that is
   otherwise white end to end, a band is how the eye finds the prices without
   a heading having to shout. The boxes then have to be white or they would
   disappear into it -- which is the whole reason this section's cards are
   built the other way round from the pricing page's, where white cards sit
   on white and a hairline does the separating.

   ROUNDED HERE ONLY, and deliberately: everything else on the site is square
   to 2px. If the corners look out of place against the pricing page, the
   answer is to round those too rather than to unround these -- one rule
   either way, not a mixture that looks accidental. */
.sec-cost{background:var(--band-soft)}
.sec-cost .plan-strip{border-top:0; gap:20px; margin-top:clamp(24px,3vw,36px)}
.sec-cost .plan-strip .pill{
  background:var(--panel); border:1px solid var(--rule); border-top:1px solid var(--rule);
  border-radius:12px; padding:26px 28px 30px;
  box-shadow:0 1px 2px rgba(39,39,39,.04), 0 4px 10px rgba(39,39,39,.03);
  transition:transform .26s var(--ease), box-shadow .26s var(--ease);
}
.sec-cost .plan-strip .pill:hover,.sec-cost .plan-strip .pill:focus-within{
  transform:translateY(-6px) scale(1.015);
  box-shadow:0 2px 6px rgba(39,39,39,.07), 0 18px 40px rgba(39,39,39,.12);
}
.sec-cost .tax-line{background:transparent}
@media(min-width:820px){
  .sec-cost .plan-strip .pill{border-top:1px solid var(--rule); padding:26px 28px 30px}
}


/* ═══════════════════════════════════════════════════════════════════════
   NAMED INSTEAD OF INLINE.

   RAJ: "no hard coded css within the frontend layer."

   Seven style="" attributes lived in contact.html and first-step.html and
   three more were injected by site.js at render time. Ten places where a
   colour or a measure could drift from this file without anybody noticing,
   and ten a restyle would silently miss. They are named now: if something
   looks a certain way, the reason is in this file.
   ═══════════════════════════════════════════════════════════════════════ */

.btn-wide{width:100%}
.callnum-wrap{margin-top:16px}
/* THE CONTACT PAGE'S QR ROW STACKS, ALWAYS. Every other qr-row has a full
   page width to divide; this one is already inside half of a two-column
   layout, so splitting it again left the text 157px wide -- one or two words
   a line, and no room at all for the button underneath it. Plate, then the
   words, then the action that belongs to them. */
.qr-row-spaced{margin-top:clamp(36px,5vw,56px)}
@media(min-width:820px){.qr-row-spaced{grid-template-columns:minmax(0,1fr); gap:clamp(20px,3vw,28px)}}
.lead-tight{margin-top:12px; color:var(--ink-2); max-width:44ch}
.note-block{margin-top:28px; color:var(--ink-2); max-width:44ch}
.choice-spaced{margin-top:16px}
.plan-summary{color:var(--ink-2)}
.count-end{margin-left:auto}

/* ═══════════════════════════════════════════════════════════════════════
   THE HEADER — folded in from what was menu.css.

   It shipped as a second stylesheet, which is the patchwork being pointed
   at: two files, two places to look, and a restyle that reaches one and not
   the other. One stylesheet for this site now. These rules are inert until
   the new nav markup goes into the pages; nothing here changes the header
   as it stands today.
   ═══════════════════════════════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════════════════
   NAVIGATION — triggers, mega panels, and a mobile menu that finally exists.

   TWO PROBLEMS, ONE COMPONENT.

   The first is the one Raj asked for: Services and Packages should open,
   not just link. Six service groups and three packages are the whole offer,
   and until now a visitor had to click through to two other pages to learn
   what either word meant.

   WHERE THE BREAKPOINT IS, AND WHY IT IS NOT 900. The drawer first took over
   below 900px, and between 900 and about 1010 the desktop bar was measured at
   800px of content inside 810px of room -- it fitted on paper and wrapped to
   two rows in fact, because --pad grows with the viewport and eats the margin
   the arithmetic assumed. Measured rather than guessed: 1024 is the first
   width where the bar has real room, so that is where it switches.

   The second problem he did not ask for and it is arguably worse. At 390px the old
   nav simply WRAPPED -- "What we do / Services / What it costs" on one row,
   "Talk to us" on the next, the language switch on a third. Three rows of
   header before the headline, on the device most people arrive on. There
   was no mobile menu at all; there was a desktop menu that folded.

   NOTHING HERE IS ROUNDED, AND THAT IS DELIBERATE. The reference Raj liked
   is a shadcn panel -- soft corners, soft shadows. This site is Swiss: 2px
   borders, 2px radius, mono numerals, hard edges. Copying the reference's
   SHAPE would have put a different brand inside the header. What is copied
   is its STRUCTURE -- a multi-column panel where every row is an icon, a
   title and a line that says what it means.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── the bar itself ───────────────────────────────────────────────────── */

/* The trigger has to be a <button>: it opens something rather than going
   somewhere, and a screen reader is entitled to be told which. It is then
   painted to sit level with the real links beside it. */
.nav-trigger{
  font:inherit; font-weight:600; font-size:1rem; cursor:pointer;
  display:inline-flex; align-items:center; gap:7px;
  padding:10px 14px; min-height:44px; border:0; border-bottom:3px solid transparent;
  border-radius:2px; background:transparent; color:var(--ink-2);
}
.nav-trigger:hover{color:var(--ink); background:var(--rule-soft)}
.nav-trigger:focus-visible{outline:3px solid var(--teal); outline-offset:-3px}
.nav-trigger[aria-expanded="true"]{color:var(--ink); border-bottom-color:var(--teal)}
.nav-trigger .chev{
  width:11px; height:11px; flex:none; transition:transform .18s var(--ease);
}
.nav-trigger[aria-expanded="true"] .chev{transform:rotate(180deg)}

/* ── the panel ────────────────────────────────────────────────────────── */

/* FULL BLEED, hung off the sticky header. `.top` is position:sticky, which
   is a positioned element, so it is the containing block for this. */
.navpanel{
  position:absolute; left:0; right:0; top:100%;
  background:var(--panel);
  border-top:1px solid var(--rule);
  border-bottom:2px solid var(--ink);
  box-shadow:0 18px 40px -28px rgba(10,51,53,.55);
  opacity:0; transform:translateY(-6px); pointer-events:none;
  transition:opacity .16s var(--ease), transform .16s var(--ease);
}
.navpanel[data-open="true"]{opacity:1; transform:none; pointer-events:auto}
.navpanel[hidden]{display:none}
.navpanel-in{max-width:var(--maxw); margin-inline:auto; padding:clamp(22px,3vw,34px) var(--pad)}

.navgrid{display:grid; gap:2px 0}
html:not(.nav-compact) .navgrid{grid-template-columns:repeat(3,minmax(0,1fr)); gap:2px 28px}

/* ── one row of the panel ─────────────────────────────────────────────── */
.navcell{
  display:grid; grid-template-columns:auto minmax(0,1fr); gap:4px 16px;
  align-items:start; padding:14px 14px 14px 12px;
  text-decoration:none; color:var(--ink); border-radius:2px;
  border-left:3px solid transparent;
  transition:background .14s var(--ease), border-color .14s var(--ease);
}
.navcell:hover,.navcell:focus-visible{background:var(--teal-wash); border-left-color:var(--teal)}
.navcell:focus-visible{outline:3px solid var(--teal); outline-offset:-3px}
.navcell .gicon{width:30px; height:30px; grid-row:1/3}
.navcell b{font-size:1.04rem; font-weight:700; line-height:1.3}
.navcell span{color:var(--ink-2); font-size:max(12px,.94rem); line-height:1.45}
.navcell .count{
  font-family:var(--font-num); font-size:max(12px,.76rem);
  letter-spacing:.1em; text-transform:uppercase; color:var(--teal-ink);
  margin-top:4px; display:block;
}
html[lang="te"] .navcell .count{font-family:var(--font-te); letter-spacing:.04em; text-transform:none}

/* ── a package row: the price is the thing being read ─────────────────── */
.navcell.plan-cell{grid-template-columns:minmax(0,1fr)}
.navcell.plan-cell .amt{
  font-family:var(--font-num); font-weight:600;
  font-size:1.6rem; letter-spacing:-.02em; color:var(--ink); display:block; margin-top:8px;
}
.navcell.plan-cell .per{color:var(--ink-2); font-size:max(12px,.9rem)}

/* ── the line under the grid ──────────────────────────────────────────── */
.navfoot{
  display:flex; flex-wrap:wrap; gap:10px 22px; align-items:center;
  margin-top:16px; padding-top:16px; border-top:1px solid var(--rule);
}
.navfoot a{
  color:var(--teal-ink); font-weight:700; text-decoration:none;
  border-bottom:2px solid var(--rule); padding:4px 0;
}
.navfoot a:hover{border-bottom-color:var(--teal)}
.navfoot .note{color:var(--ink-2); font-size:max(12px,.94rem); margin-left:auto}

/* ── COMPACT OR NOT IS MEASURED, NOT GUESSED ──────────────────────────────
   These were @media(max-width:1023px). A fixed width is the wrong test: what
   actually matters is whether the bar FITS, and that moves with things a
   media query cannot see. Measured, with the desktop bar forced at every
   width from 1000px up:

       normal text, English    fits from 1030px
       largest text, English   fits from 1100px
       largest text, Telugu    fits from 1150px

   At 1024 with the text turned up the header silently wrapped to two rows --
   160px of header above the headline, on the setting an elder is most likely
   to have chosen. Telugu is worse again, because the words are longer.

   So menu.js measures the real thing on load, on resize, when the text size
   changes and when the language changes, and puts .nav-compact on <html>
   when the bar will not fit on one row. Add a nav item or a longer label and
   it still behaves; nobody has to remember to move a number.
   ────────────────────────────────────────────────────────────────────────── */

/* ═══ COMPACT ═══════════════════════════════════════════════════════════
   The old nav did not collapse, it wrapped. Below 900px the links move
   into a panel behind one button, and the two triggers become accordions
   rather than overlays -- an overlay inside a drawer is a trap on a phone.
   ═══════════════════════════════════════════════════════════════════════ */

.menu-btn{
  display:none; align-items:center; gap:9px;
  font:inherit; font-weight:700; font-size:1rem; cursor:pointer;
  min-height:48px; padding:0 14px; border:2px solid var(--ink); border-radius:2px;
  background:var(--panel); color:var(--ink);
}
.menu-btn:focus-visible{outline:3px solid var(--teal); outline-offset:2px}
.menu-btn .bars{display:block; width:18px; height:2px; background:currentColor; position:relative}
.menu-btn .bars::before,.menu-btn .bars::after{
  content:""; position:absolute; left:0; width:18px; height:2px; background:currentColor;
  transition:transform .18s var(--ease), opacity .18s var(--ease);
}
.menu-btn .bars::before{top:-6px}
.menu-btn .bars::after{top:6px}
.menu-btn[aria-expanded="true"] .bars{background:transparent}
.menu-btn[aria-expanded="true"] .bars::before{transform:translateY(6px) rotate(45deg)}
.menu-btn[aria-expanded="true"] .bars::after{transform:translateY(-6px) rotate(-45deg)}


  html.nav-compact .menu-btn{display:inline-flex}

  /* The header keeps ONE row at every width: mark, menu button, language. */
  html.nav-compact .top-in{gap:12px; flex-wrap:nowrap}
  html.nav-compact .lang .dd-btn{padding:6px 10px; font-size:max(12px,.9rem)}

  html.nav-compact .nav{
    position:absolute; left:0; right:0; top:100%;
    display:block; background:var(--panel);
    border-top:1px solid var(--rule); border-bottom:2px solid var(--ink);
    box-shadow:0 18px 40px -28px rgba(10,51,53,.55);
    max-height:calc(100dvh - 100%); overflow-y:auto;
    padding:8px var(--pad) 20px;
  }
  html.nav-compact .nav[hidden]{display:none}
  html.nav-compact .nav > a, html.nav-compact .nav-trigger{
    display:flex; width:100%; justify-content:space-between; align-items:center;
    min-height:58px; padding:12px 2px; font-size:1.1rem;
    border-bottom:1px solid var(--rule-soft); border-radius:0;
  }
  html.nav-compact .nav > a{border-bottom:1px solid var(--rule-soft)}
  html.nav-compact .nav a[aria-current="page"]{border-bottom-color:var(--teal)}
  html.nav-compact .nav-trigger[aria-expanded="true"]{border-bottom-color:var(--rule-soft)}

  /* In the drawer the panel is an accordion in normal flow, not an overlay. */
  html.nav-compact .navpanel{
    position:static; opacity:1; transform:none; pointer-events:auto;
    border:0; box-shadow:none; background:transparent;
  }
  html.nav-compact .navpanel-in{padding:4px 0 14px}
  html.nav-compact .navcell{padding:12px 10px; background:var(--paper); margin-bottom:2px}
  html.nav-compact .navfoot{margin-top:12px; padding-top:12px}
  html.nav-compact .navfoot .note{margin-left:0; width:100%}


/* The scrim only exists on the desktop overlay, and only to catch a click
   outside. It is never a dark wash: the header stays legible over it. */
.navscrim{
  position:fixed; inset:0; z-index:55; background:transparent; border:0; padding:0;
}
.navscrim[hidden]{display:none}
html.nav-compact .navscrim{background:rgba(10,51,53,.22)}

/* ── the narrow header, measured rather than guessed ───────────────────────
   At 390px the three items came to about 379px inside 326px of usable width
   and the తెలుగు button was cut in half. The word "Menu" is the cheapest
   ~55px to give back: the three bars are universally understood and the
   button keeps its accessible name either way.

   The language switch is NOT what moves into the drawer, though it is the
   obvious candidate. A Telugu reader is precisely the visitor least likely
   to hunt for it, and putting their own language two taps deep in a menu
   labelled in English is the wrong economy. */
@media(max-width:559px){
  .menu-btn{padding:0 12px; gap:0}
  .menu-btn span:not(.bars){
    position:absolute; width:1px; height:1px; overflow:hidden;
    clip-path:inset(50%); white-space:nowrap;
  }
  .mark img{height:34px}
  .lang .dd-btn{padding:6px 9px; font-size:max(12px,.86rem)}
  .lang .dd{min-width:8rem}
}

/* ═══════════════════════════════════════════════════════════════════════
   TEXT SIZE.

   RAJ: "give an option to increase or decrease the font size"

   The single most useful control on a site read by people in their
   seventies, and the one they are least likely to find in their browser's
   own settings. Three steps, not a slider: a slider is a fiddly target for
   an unsteady hand and invites a size nobody designed for.

   HOW IT SCALES, AND WHY IT IS ONE LINE. Every type token in site.css is
   written in rem -- --t-hero, --t-h2, --t-lead, --t-body -- so all of them
   are already multiples of the root font size. Moving that one value moves
   the entire scale and nothing has to be restyled.

   PLUS TWO PIXELS, NOT TIMES 1.125. It was a multiplier; Raj asked for
   "an increment of 2 upto 2 steps" and the addition is the better rule
   anyway. A multiplier grows an 80px headline to 100px for somebody who
   only wanted to read the paragraph -- the layout rearranges itself around
   a request that was about body copy. Adding a fixed 2px moves the reading
   sizes where it matters and barely touches the display sizes, most of
   which are capped by a vw term at these widths. Body copy reads 17px,
   19px, 21px.

   `calc(100% + step)`, NOT `calc(16px + step)`. 100% is whatever the
   person has already set as their browser's default text size, and ours is
   added to it. A fixed 16px base would silently throw away the setting of
   the very person most likely to have changed it.

   AND A FLOOR UNDER ALL OF IT. Raj: "12px as minimum". No text on this
   site renders below 12px at any setting -- every size under 1rem in this
   file is written max(12px, Xrem), so a reader whose browser base is 14px
   still gets 12 where the arithmetic would have given 9.8. That is why
   those declarations look wordier than they need to. Do not tidy them
   back. The floor rises with the steps, because max() is evaluated against
   the grown rem.

   --pad and the grid are in px and vw on purpose and do NOT scale. Text
   grows inside a layout that stays put, which is what keeps the page from
   falling apart at the largest step.
   ═══════════════════════════════════════════════════════════════════════ */

:root{--step:0px}
html{font-size:calc(100% + var(--step))}
html[data-text="1"]{--step:2px}
html[data-text="2"]{--step:4px}

/* Visually hidden, still read aloud. Three A's are a picture of the
   control; a screen reader needs the words. */
.sr{
  position:absolute; width:1px; height:1px; padding:0; margin:-1px;
  overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0;
}

.size{display:flex; border:2px solid var(--ink); border-radius:2px; overflow:hidden; flex:none}
.size button{
  font:inherit; font-family:var(--font); cursor:pointer;
  border:0; background:transparent; color:var(--ink);
  min-height:44px; padding:0 11px; line-height:1; font-weight:700;
  display:flex; align-items:center; justify-content:center;
}
/* Sized in px, not rem — a control that resized itself as you pressed it
   would move under the finger that was pressing it. */
.size button{font-size:20px; min-width:42px; line-height:1}
.size .size-label{
  display:flex; align-items:center; justify-content:center;
  min-width:34px; font-size:16px; font-weight:700; color:var(--ink-2);
  border-left:1px solid var(--rule); border-right:1px solid var(--rule);
}
.size button:disabled{color:var(--rule); cursor:default}
.size button[aria-pressed="true"]{background:var(--ink); color:var(--paper)}
.size button:focus-visible{outline:3px solid var(--teal); outline-offset:-3px}

/* ── in the drawer, where there is room to say what it is ──
   The header at 390px was measured at 308px of content in 350px of space.
   A third control does not fit and nothing worth removing would make it
   fit, so on a phone this sits at the top of the drawer with a label. It
   is the first thing in the menu rather than the last, because the person
   most likely to open the menu looking for it is the person who cannot
   comfortably read the menu. */
.size-row{
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding:14px 2px 16px; border-bottom:2px solid var(--ink);
}
.size-row .lbl{font-weight:700; font-size:1.02rem}
html:not(.nav-compact) .size-row{display:none}
html.nav-compact .top-in > .size{display:none}

/* ═══════════════════════════════════════════════════════════════════════
   LANGUAGE — a picker, not a pair of buttons.

   RAJ sent a reference: a trigger showing the current choice, opening a
   list with a tick against it.

   IT IS ALSO NARROWER, which is not a side benefit. "English | తెలుగు" as
   two live buttons is about 150px of header; a trigger showing only the
   current language is about 105. That is 45px back in the one row that had
   to hold a logo, a menu, a text-size control and this -- and the header
   measurement above says 45px is the difference between fitting and
   wrapping at the largest text size.

   NO FLAGS, and the reference has them. A flag stands for a country and
   these are two languages of the SAME country. There is no flag that means
   Telugu, and using the Indian flag for Telugu while English gets a British
   or American one would say something about who belongs here that we do
   not mean. The language's own name, written in that language, is what
   every reader recognises fastest anyway.

   THE OPTIONS KEEP THE IDS site.js ALREADY LOOKS FOR. applyLang() does an
   unguarded $("#lang-en").setAttribute(...) -- if those two elements ever
   stop existing, switching language throws and takes the rest of the
   function with it. So the two options ARE #lang-en and #lang-te; site.js
   wires their clicks and sets aria-pressed on them exactly as before, and
   aria-pressed is what draws the tick. Nothing in site.js changes.
   ═══════════════════════════════════════════════════════════════════════ */

.langpick{position:relative; flex:none}
.langpick-btn{
  display:inline-flex; align-items:center; gap:9px;
  font:inherit; font-weight:700; font-size:max(12px,.98rem); cursor:pointer;
  min-height:44px; padding:0 13px; border:2px solid var(--ink); border-radius:2px;
  background:var(--panel); color:var(--ink); white-space:nowrap;
}
.langpick-btn:hover{background:var(--rule-soft)}
.langpick-btn:focus-visible{outline:3px solid var(--teal); outline-offset:2px}
.langpick-btn .chev{width:11px; height:11px; flex:none; transition:transform .18s var(--ease)}
.langpick-btn[aria-expanded="true"] .chev{transform:rotate(180deg)}

.langpick-list{
  position:absolute; right:0; top:calc(100% + 6px); z-index:80;
  min-width:200px; padding:6px;
  background:var(--panel); border:2px solid var(--ink); border-radius:2px;
  box-shadow:0 18px 40px -26px rgba(10,51,53,.6);
  opacity:0; transform:translateY(-5px); pointer-events:none;
  transition:opacity .14s var(--ease), transform .14s var(--ease);
}
.langpick-list[data-open="true"]{opacity:1; transform:none; pointer-events:auto}
.langpick-list[hidden]{display:none}
.langpick-list .hdr{
  display:block; padding:8px 10px 6px;
  font-family:var(--font-num); font-size:max(12px,.7rem);
  letter-spacing:.16em; text-transform:uppercase; color:var(--ink-2);
}
.langpick-list button{
  display:flex; width:100%; align-items:center; gap:12px;
  font:inherit; font-weight:600; font-size:1.02rem; text-align:left; cursor:pointer;
  min-height:52px; padding:10px 10px; border:0; border-radius:2px;
  background:transparent; color:var(--ink);
}
.langpick-list button:hover{background:var(--teal-wash)}
.langpick-list button:focus-visible{outline:3px solid var(--teal); outline-offset:-3px}
/* The tick is drawn by aria-pressed, so the accessible state and the visible
   state are the same fact and cannot disagree. */
.langpick-list button .tick{width:18px; height:18px; margin-left:auto; flex:none; opacity:0; color:var(--teal-ink)}
.langpick-list button[aria-pressed="true"]{background:var(--teal-wash)}
.langpick-list button[aria-pressed="true"] .tick{opacity:1}

/* In the drawer it is a row like the text size, not a floating panel. */
html.nav-compact .top-in > .langpick{display:none}
.lang-row{
  display:flex; align-items:center; justify-content:space-between; gap:14px;
  padding:14px 2px; border-bottom:1px solid var(--rule-soft);
}
.lang-row .lbl{font-weight:700; font-size:1.02rem}
html:not(.nav-compact) .lang-row{display:none}
html.nav-compact .lang-row .langpick-list{position:static; opacity:1; transform:none;
  pointer-events:auto; box-shadow:none; border:0; padding:0; min-width:0}

/* ── the measuring state ──────────────────────────────────────────────────
   Held for a single synchronous read in menu.js and removed before the
   browser paints, so it is never seen.

   flex-shrink is why this is needed at all. With only `flex-wrap:nowrap` the
   children obediently squeeze themselves narrower instead of overflowing, so
   scrollWidth always equalled clientWidth and the header cheerfully reported
   that it fitted at every width. Pinned to flex:0 0 auto they keep their
   natural size, overflow for real, and scrollWidth finally means something. */
.top-in.measuring{flex-wrap:nowrap}
.top-in.measuring > *{flex:0 0 auto}
.top-in.measuring .nav{flex-wrap:nowrap}
.top-in.measuring .nav > *{flex:0 0 auto}


/* ═══════════════════════════════════════════════════════════════════════
   THE PRINTED-CODE PAGE — folded in from the <style> block that was inside
   first-step.html.

   It carried its own stylesheet because it deliberately does not load
   site.js or data.js: 72KB of catalogue and search machinery that a person
   standing at a pandal on borrowed wifi has no use for. That reasoning
   holds for the SCRIPT and never held for the CSS -- the page has always
   loaded this file. So the rules live here and the page keeps its light
   payload.
   ═══════════════════════════════════════════════════════════════════════ */

  /* ═══════════════════════════════════════════════════════════════
     FOUR THINGS site.css DOES NOT HAVE, BUILT FROM ITS OWN TOKENS.
     No new colour is invented here. If a value below is not a var(),
     it is a metric, not a paint.
     ═══════════════════════════════════════════════════════════════ */

  /* Telugu, named rather than left to the system face. On Windows and on
     some Android builds the default has no Telugu at all and the fallback
     renders vowel signs detached from their consonant — which a Telugu
     reader sees as gibberish, not as a font they dislike. */
  [lang="te"]{
    font-family:var(--font-te);
    font-synthesis-weight:none;
  }

  /* ── 1. the measure. A poster, not a page: one column, thumb-width. ── */
  .go{max-width:560px; margin-inline:auto; padding-block:clamp(22px,5vw,40px)}
  .go-mark{display:block; text-align:center; margin-bottom:clamp(22px,4vw,32px)}
  .go-mark img{height:clamp(44px,9vw,58px); width:auto; display:inline-block}

  .go h1{
    font-size:clamp(1.65rem,6vw,2.3rem); line-height:1.3;
    text-align:center; letter-spacing:-.008em;
  }
  [lang="te"].go-head{font-weight:400; line-height:1.42}
  .go-en{
    text-align:center; margin-top:10px;
    font-size:var(--t-lead); color:var(--ink-2);
  }
  /* GRID, NOT WRAPPING FLEX. As a flex row the two facts ran together and
     re-broke mid-phrase — "Kukatpally &" on one line and "Nizampet" alone on
     the next. Two rows that each break on their own is the honest layout. */
  .go-meta{
    display:grid; gap:7px; justify-items:center;
    margin-top:20px; padding-top:18px; border-top:1px solid var(--rule);
    text-align:center;
  }
  .go-meta span{font-size:1rem; color:var(--ink-2)}
  .go-meta b{color:var(--teal-ink); font-weight:700}

  /* ── 2. THE NUMBER. Biggest thing on the page, and that is the point.
        A 71-year-old will ring; she will not tap a button labelled Call.
        --teal-ink rather than --teal: 7.1:1 against white, where the
        lighter mark teal is 3.9:1 and this is the one element on the
        site that absolutely must be legible in daylight at a pandal. ── */
  .callplate{
    display:block; margin-top:clamp(24px,4vw,32px); padding:22px 18px;
    background:var(--teal-ink); color:#fff; text-decoration:none;
    border:2px solid var(--teal-ink); border-radius:2px; text-align:center;
    transition:transform .16s var(--ease), background .16s var(--ease);
  }
  .callplate:hover{transform:translateY(-2px); background:var(--teal)}
  .callplate:focus-visible{outline:3px solid var(--ink); outline-offset:3px}
  .callplate .digits{
    display:block;
    font-family:var(--font-num);
    font-size:clamp(1.75rem,7.4vw,2.6rem); font-weight:600;
    letter-spacing:-.02em; line-height:1.1;
  }
  .callplate .lbl{display:block; margin-top:8px; font-size:1.02rem; font-weight:700}
  .callplate .quick{
    display:block; margin-top:10px; padding-top:10px;
    border-top:1px solid rgba(255,255,255,.28);
    font-family:var(--font-num);
    font-size:max(12px,.82rem); letter-spacing:.18em; color:#BBD4D1;
  }

  /* ── 3. the four ways out. The site's .btn, stacked two-up with a
        second line, because a Telugu label and its English gloss will
        not sit on one row on a 320px screen. ── */
  .go-row{display:grid; grid-template-columns:1fr 1fr; gap:10px; margin-top:10px}
  .gobtn{
    display:flex; flex-direction:column; align-items:center; justify-content:center;
    gap:4px; min-height:72px; padding:12px 10px; text-align:center;
    border:2px solid var(--ink); border-radius:2px;
    background:var(--panel); color:var(--ink); text-decoration:none;
    font-weight:700; font-size:1.02rem; line-height:1.3;
    transition:transform .16s var(--ease), background .16s var(--ease);
  }
  .gobtn:hover{transform:translateY(-2px)}
  .gobtn:focus-visible{outline:3px solid var(--teal); outline-offset:3px}
  .gobtn small{font-weight:400; font-size:max(12px,.84rem); color:var(--ink-2)}
  .gobtn.wa{background:var(--teal-ink); border-color:var(--teal-ink); color:#fff}
  .gobtn.wa small{color:#BBD4D1}
  .gobtn.wa:hover{background:var(--teal); border-color:var(--teal)}
  .gobtn.save{background:var(--teal-wash)}

  /* ── 4. who is this for. One question, two taps, no typing. It decides
        who the office rings and at what hour, and it is the only thing
        they genuinely need before dialling. ── */
  .who{margin-top:clamp(32px,5vw,44px); padding-top:clamp(26px,4vw,34px); border-top:2px solid var(--ink)}
  .who h2{font-size:1.35rem; text-align:center}
  .who .why{margin-top:8px; text-align:center; color:var(--ink-2); font-size:1rem}
  .who .choice{margin-top:20px; margin-bottom:0}
  /* THE RADIO STAYS BESIDE THE TEXT, which is the site's own .choice layout.
     A first version stacked it with flex-direction:column and the result was
     a radio floating centred above two lines that then ran into each other —
     `small` is inline, so "For my parents" wrapped up beside the Telugu
     instead of sitting under it. Both faults came from one override. */
  .who .choice label{flex:1 1 160px}
  .who .choice label small{
    display:block; margin-top:3px;
    font-weight:400; font-size:max(12px,.86rem); color:var(--ink-2); line-height:1.35;
  }
  .who form{margin-top:22px}
  .who form[hidden]{display:none}

  .go-foot{
    margin-top:clamp(30px,5vw,40px); padding-top:20px;
    border-top:1px solid var(--rule); text-align:center;
    color:var(--ink-2); font-size:max(12px,.96rem); line-height:1.7;
  }
  .go-foot a{color:var(--teal-ink)}
  .said[hidden]{display:none}

/* ═══ THE PLAN SLIDER ═════════════════════════════════════════════════════
   RAJ, with the Loops pricing slider as the reference: "based on the
   available packages that we are getting from the server, we need to create
   a slider ... if there are 2 packages only, the slider would have 3 stages.
   0, tier 1 and tier 2." And the constraint that matters most: "the list of
   items should not be unaware for the user who is watching."

   SO THE LIST NEVER CHANGES LENGTH. Every service any plan includes is on
   screen at every stage; moving the slider lights more of them up and dims
   the rest. A list that grew and shrank would hide the thing the slider
   exists to show -- you would have to remember what was there a second ago
   to know what you had gained. Here you can see what you are not buying.

   STAGE 0 IS "NO PLAN", not a free tier. It shows nothing lit and the one
   thing that is still true without a plan: the first visit costs nothing.
   It is what makes the first move of the slider mean something.

   SINGLE COLUMN, slider on top, exactly as Raj allowed -- at 1170px a
   three-way split would have put the list in a column too narrow for
   sentences of this length. */
.pslider{
  border:1px solid var(--rule); border-radius:12px; background:var(--panel);
  padding:clamp(24px,3vw,36px); margin-top:clamp(20px,3vw,32px);
}

/* ── the track ── */
.ps-track{padding:8px 0 0}
.ps-range{
  -webkit-appearance:none; appearance:none; width:100%; height:44px;
  background:transparent; cursor:pointer; display:block; margin:0;
}
.ps-range:focus{outline:0}
.ps-range::-webkit-slider-runnable-track{height:6px; border-radius:3px; background:var(--rule)}
.ps-range::-moz-range-track{height:6px; border-radius:3px; background:var(--rule)}
/* the filled part, drawn as a background on the input itself */
.ps-range{background:linear-gradient(var(--teal),var(--teal)) no-repeat;
  background-size:var(--fill,0%) 6px; background-position:0 19px}
.ps-range::-webkit-slider-thumb{
  -webkit-appearance:none; appearance:none;
  width:34px; height:34px; border-radius:50%; margin-top:-14px;
  background:var(--panel); border:3px solid var(--teal);
  box-shadow:0 2px 8px rgba(39,39,39,.18);
}
.ps-range::-moz-range-thumb{
  width:34px; height:34px; border-radius:50%;
  background:var(--panel); border:3px solid var(--teal);
  box-shadow:0 2px 8px rgba(39,39,39,.18);
}
.ps-range:focus-visible::-webkit-slider-thumb{box-shadow:0 0 0 4px var(--teal-wash)}
.ps-range:focus-visible::-moz-range-thumb{box-shadow:0 0 0 4px var(--teal-wash)}

/* ── the stops ──
   Real buttons, not decoration: a 34px thumb is a hard target for an
   unsteady hand, and pressing the name of the plan you want is easier than
   dragging to it. */
.ps-ticks{display:grid; gap:8px; margin-top:2px}
.ps-tick{
  font:inherit; font-family:var(--font-head); font-weight:600;
  font-size:max(12px,.95rem); line-height:1.3; text-align:center;
  background:none; border:0; border-top:2px solid var(--rule);
  padding:12px 4px 0; min-height:44px; color:var(--ink-2); cursor:pointer;
}
.ps-tick[aria-current="true"]{color:var(--ink); border-top-color:var(--teal)}
.ps-tick:focus-visible{outline:3px solid var(--teal); outline-offset:2px}

/* ── name and price ── */
.ps-head{
  display:grid; gap:20px; align-items:start;
  padding:clamp(22px,3vw,32px) 0 0; margin-top:clamp(18px,2.5vw,26px);
  border-top:1px solid var(--rule);
}
@media(min-width:760px){.ps-head{grid-template-columns:minmax(0,1fr) auto; gap:32px}}
.ps-name h3{font-size:clamp(1.5rem,2.4vw,2rem)}
.ps-name .tagline{color:var(--teal-ink); font-weight:600; font-size:1.05rem; margin-top:6px}
.ps-name .ps-sum{color:var(--ink-2); margin-top:12px; max-width:58ch}
.ps-price{
  background:var(--band-soft); border:1px solid var(--rule); border-radius:10px;
  padding:20px 24px; min-width:15rem;
}
.ps-amt{
  font-family:var(--font-num); font-weight:700; letter-spacing:-.02em; line-height:1;
  font-size:clamp(2rem,3.6vw,2.75rem); display:block;
}
.ps-per{color:var(--ink-2); font-size:1rem}
.ps-year{color:var(--ink-2); font-size:.98rem; margin-top:10px}
.ps-year b{color:var(--ink); font-weight:600}

/* ── the list ── */
.ps-count{
  font-family:var(--font-head); font-weight:600; color:var(--ink-2);
  font-size:max(12px,.95rem); margin:clamp(22px,3vw,30px) 0 0;
}
.ps-list{list-style:none; margin:10px 0 0; padding:0; display:grid; border-top:1px solid var(--rule)}
.ps-item{
  display:grid; grid-template-columns:auto 1fr auto; gap:14px; align-items:baseline;
  padding:13px 0; border-bottom:1px solid var(--rule-soft); font-size:1.02rem; line-height:1.5;
  transition:color .2s var(--ease), opacity .2s var(--ease);
}
.ps-item::before{content:""; width:9px; height:9px; transform:translateY(-1px);
  border:1px solid var(--rule); background:transparent}
.ps-item[data-in="1"]::before{background:var(--teal); border-color:var(--teal)}
.ps-item[data-in="0"]{color:var(--ink-2); opacity:.45}
.ps-new{
  font-family:var(--font-head); font-size:max(12px,.78rem); font-weight:700;
  letter-spacing:.08em; text-transform:uppercase; color:var(--teal-ink); white-space:nowrap;
}
@keyframes ps-lit{from{background:var(--teal-wash)} to{background:transparent}}
.ps-item[data-lit="1"]{animation:ps-lit .7s var(--ease)}

.ps-foot{display:flex; flex-wrap:wrap; gap:12px; align-items:center; margin-top:clamp(22px,3vw,30px)}

@media (prefers-reduced-motion:reduce){
  .ps-item{transition:none}
  .ps-item[data-lit="1"]{animation:none}
}

/* ═══════════════════════════════════════════════════════════════════════
   THE FRONT DOOR — join, verify, sign in, reset, get the app
   ═══════════════════════════════════════════════════════════════════════

   RAJ: "no hard coded css within the frontend layer. I want a central css
   that guides all the pages."

   So every piece of these five pages is named here. The pages themselves
   carry class names and nothing else, and `onboard.js` adds and removes
   classes rather than setting styles.

   WHO THESE SCREENS ARE READ BY, which decides most of the numbers below:
   a seventy-something on a phone, in sunlight, possibly without reading
   glasses to hand. Every target is at least 56px, every label is real text
   rather than a placeholder, and nothing is communicated by colour alone.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── one panel at a time ──────────────────────────────────────────────────
   The whole flow is one page with several panels, not several pages. A step
   that reloads the browser is a step where a half-typed form is lost, and a
   person who loses a form twice does not fill it in a third time. */
.panel{display:none}
.panel[data-on="1"]{display:block}

/* ── where they are in the flow ───────────────────────────────────────────
   NUMBERED, NOT A BAR. A progress bar tells somebody they are 40% of the way
   through something of unknown length; "Step 2 of 3" tells them there are
   three and this is the second. The count is also the promise: three steps
   means three, and if the flow grows this line has to change with it. */
.flow{display:flex;align-items:center;gap:10px;margin-bottom:clamp(18px,3vw,28px);
      font-family:var(--font-num);font-size:max(12px,.92rem);letter-spacing:.08em;
      text-transform:uppercase;color:var(--ink-2)}
.flow-dots{display:flex;gap:6px}
.flow-dot{width:9px;height:9px;border-radius:50%;background:var(--rule);flex:none}
.flow-dot[data-on="1"]{background:var(--teal)}
.flow-dot[data-done="1"]{background:var(--ink)}

/* ── the country and the number, on one row ───────────────────────────────
   THE COUNTRY IS A REAL SELECT, not a flag-picker with a search box. It is
   the control every phone already knows how to open, it works with a screen
   reader, and it needs no library. `+91` is preselected and the list is
   short on purpose: the countries Telugu families actually live in, and then
   the rest. A list of 200 is a list nobody scrolls. */
/* STACKED ON A PHONE, SIDE BY SIDE ON A DESKTOP. Sharing a 390px row, the
   country box is about 110px wide and "+91  India" does not fit in it -- the
   control renders looking empty, which is the one thing a select must never
   do. Below 520px the country gets its own full-width row, where the name is
   readable, and it is the only thing on this form that changes shape. */
.tel-row{display:grid;grid-template-columns:minmax(0,1fr);gap:10px}
.tel-row select{min-width:0}
@media (min-width:520px){
  .tel-row{grid-template-columns:minmax(150px,34%) minmax(0,1fr)}
}

/* ── the group of choices ─────────────────────────────────────────────────
   A fieldset arrives with a border and a notched legend, and it is the only
   box on a form whose every other control is a plain rule. Stripped back to
   nothing: the grouping is still there for a screen reader, which is the
   only reason the element is being used. */
.door fieldset{border:0;margin:0;padding:0;min-width:0}
.door legend{padding:0;margin-bottom:10px;display:block;width:100%}

/* ── the six boxes ────────────────────────────────────────────────────────
   ONE INPUT PER DIGIT, because a single box holding six digits gives no
   feedback about how many have been typed, and an OTP is precisely the
   moment somebody is counting. `inputmode="numeric"` brings up the number
   pad; `autocomplete="one-time-code"` lets iOS and Android fill it from the
   message without the person leaving the page, which for this audience is
   the difference between finishing and giving up.

   MONOSPACE, so six digits are six equal columns and a mistyped one is
   visible by its position rather than by reading the whole row. */
.otp{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;max-width:22rem;margin-block:6px 4px}
.otp input{font-family:var(--font-num);font-size:1.5rem;font-weight:600;text-align:center;
           padding:12px 0;min-height:64px;background:var(--panel);color:var(--ink);
           border:2px solid var(--rule);border-radius:0;caret-color:var(--teal)}
.otp input:focus{outline:0;border-color:var(--ink);box-shadow:0 0 0 3px var(--teal-wash)}
.otp input[data-filled="1"]{border-color:var(--ink)}
@media (max-width:400px){
  .otp{gap:6px}
  .otp input{font-size:1.25rem;min-height:56px}
}

/* ── the PIN, and why it is not six more boxes ────────────────────────────
   A PIN IS A SECRET AND AN OTP IS NOT. Six separate boxes showing six
   separate digits is exactly what you do not want somebody typing on a bus.
   So the PIN is one field, masked, with a deliberate "show" control for the
   person who cannot see what they typed -- which is most of this audience,
   and the reason the control is a labelled button rather than an eye icon
   nobody over sixty has been taught to recognise. */
.pin-wrap{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:10px;align-items:start}
.pin-wrap input{font-family:var(--font-num);font-size:1.6rem;letter-spacing:.5em;text-align:center}
.pin-show{min-height:56px;padding:0 16px;background:transparent;color:var(--ink);
          border:2px solid var(--rule);font:inherit;font-weight:600;cursor:pointer;white-space:nowrap}
.pin-show:hover{border-color:var(--ink)}
.pin-show:focus-visible{outline:3px solid var(--teal);outline-offset:2px}

/* Under the PIN box: six dots that fill as they type, so somebody who cannot
   read the masked characters can still see how many have gone in. */
.pin-dots{display:flex;gap:8px;margin-top:10px}
.pin-dot{width:12px;height:12px;border-radius:50%;border:2px solid var(--rule);flex:none}
.pin-dot[data-on="1"]{background:var(--teal);border-color:var(--teal)}

/* ── saying what happened ─────────────────────────────────────────────────
   THREE TONES AND A WORD IN EACH. Never colour alone: a red box and a green
   box are the same box to eight percent of men, and this audience is mostly
   in reading glasses. Each one opens with a word -- Sorry, Done, Please note
   -- so the tone is in the text before it is in the border. */
.msg{margin:18px 0;padding:16px 20px;border-left:4px solid var(--rule);
     background:var(--panel);font-size:1.02rem;line-height:1.6}
.msg strong{display:block;font-family:var(--font-head);font-weight:700;margin-bottom:4px}
.msg[data-tone="bad"]{border-left-color:#B3261E;background:#FDF3F2}
.msg[data-tone="good"]{border-left-color:var(--teal);background:var(--teal-wash)}
.msg[data-tone="wait"]{border-left-color:var(--ink-2)}
.msg a{color:inherit}

/* ── a field that is being checked, or has been refused ───────────────────
   The inline answer under a box, in the two states it can have. Kept off the
   `.msg` block on purpose: a message about ONE field belongs beside that
   field, not in a banner at the top that says a form has errors somewhere. */
.field-note{font-size:max(12px,.96rem);line-height:1.5;color:var(--ink-2);margin-top:-2px}
.field-note[data-tone="bad"]{color:#B3261E;font-weight:600}
.field-note[data-tone="busy"]{color:var(--ink-2);font-style:italic}
.field input[aria-invalid="true"],
.field select[aria-invalid="true"]{border-color:#B3261E}

/* ── the consent, which has to be read rather than scrolled past ──────────
   DPDP wants consent that is free, specific, informed and unambiguous, and
   the thing that makes it unambiguous is a deliberate action on a statement
   the person can actually see. So the box is large, the text is full size
   rather than fine print, and the button underneath says what agreeing does
   instead of saying "Submit". */
.consent{display:flex;gap:14px;align-items:flex-start;padding:18px 20px;
         border:2px solid var(--rule);background:var(--panel);margin-block:20px;cursor:pointer}
.consent:has(input:checked){border-color:var(--teal);background:var(--teal-wash)}
.consent:has(input:focus-visible){outline:3px solid var(--teal);outline-offset:2px}
.consent input{width:24px;height:24px;accent-color:var(--teal);flex:none;margin-top:2px}
.consent span{font-size:1.02rem;line-height:1.55}

/* ── the two store buttons ────────────────────────────────────────────────
   The one for the phone they are holding comes first and is primary; the
   other is still there, because an NRI son reading this on a laptop is
   choosing for somebody else's phone, not his own. */
.stores{display:grid;gap:12px;margin-top:24px}
@media (min-width:520px){
  .stores{grid-template-columns:1fr 1fr}
}

/* ── the narrow column these pages live in ────────────────────────────────
   Narrower than `.wrap`. A form is read down, not across, and a 60ch line of
   labels on a desktop makes somebody's eye travel for no reason. */
.door{max-width:38rem;margin-inline:auto;padding-inline:var(--pad);
      padding-block:clamp(28px,5vw,56px)}
.door h1{font-size:var(--t-h2);line-height:1.15}
.door .lead{margin-top:14px;font-size:var(--t-lead);color:var(--ink-2)}
.door form{margin-top:clamp(22px,4vw,34px)}

/* ── a row of two buttons, back and on ────────────────────────────────────
   Back is never the primary and is never first on a phone: the thumb rests
   at the bottom right and that is where "continue" belongs. */
.door-actions{display:grid;gap:10px;margin-top:26px}
@media (min-width:480px){
  .door-actions{grid-template-columns:auto minmax(0,1fr);align-items:center}
}

/* ── waiting ──────────────────────────────────────────────────────────────
   No spinner. A button that says "Sending…" and is disabled says the same
   thing, in words, without a second moving object on the page. */
.btn[aria-busy="true"]{opacity:.72;pointer-events:none}

@media (prefers-reduced-motion:reduce){
  .flow-dot,.pin-dot{transition:none}
}

/* An empty message box is still a box: padding, a border and a background,
   sitting on the page before anything has gone wrong. The panels each hold
   one of these waiting to be filled, so it has to take no room until it is. */
.msg:empty{display:none}

/* The two cards stack on a phone. `.choice label{flex:1 1 160px}` lets two sit
   side by side once the fieldset border stopped eating the width, and at
   390px that gives "For my parent or relative" three wrapped lines beside a
   two-word neighbour. One per row until there is room for two properly. */
@media (max-width:560px){
  .door .choice label{flex:1 1 100%}
}

/* THE HEADING IS FOCUSED WHEN A PANEL OPENS, so a screen reader announces
   which step this is before it announces the first field. That focus must not
   draw a box: nobody asked for it and it reads as an error state. `:not(
   :focus-visible)` keeps the ring for somebody who actually tabbed to it and
   drops it for the move the script made on their behalf. */
.panel h1[tabindex]:focus:not(:focus-visible),
.panel h2[tabindex]:focus:not(:focus-visible){outline:none}

/* ═══════════════════════════════════════════════════════════════════════
   THE BURGER, AND THE CATEGORY DROPDOWN
   ───────────────────────────────────────────────────────────────────────
   WHY. Measured on a 375x812 phone, the services page spent 265px on the
   header and another 450px on the category chips -- seven rows, because
   "Company, wellbeing and the last chapter" is 335px wide inside a 335px
   column. The first actual service sat at y=1369: nearly two screens of
   chrome before a word of the thing the page is for. Raj's report was
   "all I see is the service categories", and he was right.

   The chips were never misbehaving. They wrap exactly as told. Six long
   category names simply cannot share a row on a phone, and no amount of
   flex-wrap changes that -- so on a phone they stop being chips and become
   the same drawn dropdown the language picker and the contact form already
   use. One control, one idiom, ~60px instead of 450.

   The breakpoint is 760px rather than a round 768 so that a 768px tablet
   in portrait gets the full bar, which it has room for.
   ═══════════════════════════════════════════════════════════════════════ */

.burger{display:none}
.hmenu{display:flex; align-items:center; gap:24px}

@media (max-width:760px){
  .top-in{gap:12px; padding-block:10px}
  .mark img{height:36px}

  .burger{
    display:inline-flex; align-items:center; gap:10px; cursor:pointer;
    font:inherit; font-family:var(--font-head); font-weight:700; font-size:1rem;
    min-height:44px; padding:8px 14px; margin-left:auto;
    background:transparent; color:var(--ink);
    border:1px solid var(--ink); border-radius:2px;
  }
  .burger:focus-visible{outline:3px solid var(--teal); outline-offset:2px}

  /* Three rules drawn from one element, so the close cross is the same
     three lines rotated rather than a second icon that has to be kept in
     step with the first. */
  .burger-bars{
    display:block; position:relative;
    width:20px; height:2px; background:currentColor;
  }
  .burger-bars::before,.burger-bars::after{
    content:""; position:absolute; left:0; width:20px; height:2px;
    background:currentColor;
    transition:transform .18s var(--ease), top .18s var(--ease);
  }
  .burger-bars::before{top:-6px}
  .burger-bars::after{top:6px}
  .burger[aria-expanded="true"] .burger-bars{background:transparent}
  .burger[aria-expanded="true"] .burger-bars::before{top:0; transform:rotate(45deg)}
  .burger[aria-expanded="true"] .burger-bars::after{top:0; transform:rotate(-45deg)}

  /* display:none rather than height:0 -- the panel holds four links, two
     buttons and a dropdown, and a collapsed panel that is still in the tab
     order is a keyboard trap that nobody can see. */
  .hmenu{
    display:none;
    flex-basis:100%; width:100%;
    flex-direction:column; align-items:stretch; gap:14px;
    margin-top:2px; padding-top:14px; border-top:1px solid var(--rule);
  }
  .hmenu[data-open="1"]{display:flex}

  .hmenu .nav{flex-direction:column; align-items:stretch; gap:0}
  .hmenu .nav a{
    display:flex; align-items:center; min-height:52px;
    padding:12px 8px; border-radius:0;
    border-bottom:1px solid var(--rule-soft);
  }
  .hmenu .nav a[aria-current="page"]{border-bottom-color:var(--teal)}
  .hmenu .size{justify-content:flex-start}
  .hmenu .lang,.hmenu .lang .dd{width:100%}
}

@media (prefers-reduced-motion:reduce){
  .burger-bars::before,.burger-bars::after{transition:none}
}

/* ── the category filter: chips on a desk, a dropdown in a hand ───────── */
.chips-wide{display:flex; gap:8px; flex-wrap:wrap}
.chips-narrow{display:none}

@media (max-width:760px){
  .chips-wide{display:none}
  .chips-narrow{display:block; width:100%}
  .chips-narrow .dd{width:100%}
}
