/* ============================================================================
   Ganit — the shared chrome: header, navigation, footer, and the marketing
   components the front page is built from.

   Every page already defines the same token block in its own <style>, so this
   file inherits --s0/--tp/--ac and the fonts without redeclaring them. It is
   linked LAST in each head, after that inline block, so where a page has an
   old bare `header {}` or `footer {}` rule these win the tie.

   Why a shared file at all, in a project that deliberately had none: fifteen
   pages each carrying their own copy of the shell is fifteen places to change
   a nav item, which is why there was no nav item. One file is the reason the
   site can have a menu.

   The locked brand rules still hold here. Vermilion is a dot, not a wash —
   it marks the active page, the one primary action, and nothing else.
   Computed values stay mono and tabular. Data surfaces keep square corners.
   ========================================================================== */

/* Every var() below carries its own fallback. Four pages never defined --on,
   --s2 or --tint, and the printable calendar defines almost no tokens at all,
   so a bare var(--on) with no fallback fell through to inherit and rendered the Sign-in label
   grey on near-black. A shared stylesheet cannot assume the page it lands on
   declared everything it needs. */
/* ---------------------------------------------------------------- fallbacks
   A CSS fallback is a literal, so a hard-coded #565C64 stays mid-grey even in
   dark mode — which on a page that never declared --ts put mid-grey nav links
   on a near-black bar at 2.8:1. Routing every fallback through a second
   variable makes it flip with the theme, so the four pages missing tokens and
   the printable calendar get a correct dark mode for free. */
:root{
  --gfb-s0:#FBFBFA;
  --gfb-s1:#FFFFFF;
  --gfb-s2:#F2F2F0;
  --gfb-bd:#E3E3E0;
  --gfb-bds:#C6C6C2;
  --gfb-tp:#15181C;
  --gfb-ts:#565C64;
  --gfb-tt:#7C838B;
  --gfb-ac:#B3372A;
  --gfb-tint:#FAEDEB;
}
/* A page can opt the shell out of dark mode. The printable calendar does:
   its own stylesheet says "No dark mode. It would misrepresent what comes out
   of the tray", and it keeps --ac at the light vermilion to match the ink. A
   dark bar above a light sheet put that accent at 3.15:1 and looked like a
   different site. Opting out respects the page's decision rather than
   overriding it. */
body[data-chrome~="light"]{
  --gfb-s0:#FBFBFA;
  --gfb-s1:#FFFFFF;
  --gfb-s2:#F2F2F0;
  --gfb-bd:#E3E3E0;
  --gfb-bds:#C6C6C2;
  --gfb-tp:#15181C;
  --gfb-ts:#565C64;
  --gfb-tt:#7C838B;
  --gfb-ac:#B3372A;
  --gfb-tint:#FAEDEB;
}

@media (prefers-color-scheme:dark){
  :root{
    --gfb-s0:#0F1114;
    --gfb-s1:#15181C;
    --gfb-s2:#1C2026;
    --gfb-bd:#252A31;
    --gfb-bds:#39404A;
    --gfb-tp:#F2F3F4;
    --gfb-ts:#A8AFB8;
    --gfb-tt:#868D96;
    --gfb-ac:#F2705E;
    --gfb-tint:#2A1D1B;
  }
}

/* ------------------------------------------------------------------ header */
.gnav{position:sticky;top:0;z-index:60;background:var(--s0,var(--gfb-s0));
  border-bottom:1px solid var(--bd,var(--gfb-bd))}
.gnav .in{max-width:1080px;margin:0 auto;padding:0 20px;
  display:flex;align-items:center;gap:18px;min-height:60px}
.gnav .brand{display:flex;align-items:center;gap:9px;color:var(--tp,var(--gfb-tp));
  text-decoration:none;flex:0 0 auto}
.gnav .brand svg{display:block;flex:0 0 auto}
.gnav .brand b{font-size:17px;font-weight:700;letter-spacing:-.025em;line-height:1}
.gnav .brand i{font-family:var(--deva,'Tiro Devanagari Hindi','Noto Serif Devanagari',serif);font-style:normal;font-size:15px;
  color:var(--ac,var(--gfb-ac));line-height:1}

.gnav .links{display:flex;align-items:center;gap:2px;margin-left:auto}
.gnav .links a{font-size:13.5px;font-weight:500;color:var(--ts,var(--gfb-ts));
  text-decoration:none;padding:8px 11px;white-space:nowrap;border-radius:2px}
.gnav .links a:hover{color:var(--tp,var(--gfb-tp));background:var(--s2,var(--gfb-s2))}
/* The active page is the one place a nav item earns the accent. */
.gnav .links a[aria-current="page"]{color:var(--ac,var(--gfb-ac));font-weight:600}
.gnav .sep{width:1px;height:20px;background:var(--bd,var(--gfb-bd));margin:0 8px;flex:0 0 auto}
/* a.cta, not .cta: the button lives INSIDE .links, so `.gnav .links a` at
   (0,2,1) was beating a bare `.gnav .cta` at (0,2,0) and painting the label
   --ts on near-black — 2.64:1. Caught by measuring, not by looking; at a
   glance it reads as a deliberately quiet button. */
/* --s0, not --on, for the label on a --tp button. --on is white on every page
   that declares it and #FFF as a fallback on the four that do not, but --tp
   INVERTS in dark mode — so white-on---tp became white on near-white, 1.15:1.
   --s0 is the page ground: near-white in light, near-black in dark, which is
   exactly the contrast a --tp fill needs in both. */
.gnav .links a.cta{font-size:13.5px;font-weight:600;color:var(--s0,var(--gfb-s0));
  background:var(--tp,var(--gfb-tp));border:1px solid var(--tp,var(--gfb-tp));padding:9px 15px;
  text-decoration:none;white-space:nowrap;border-radius:0}
.gnav .links a.cta:hover{background:var(--ac,var(--gfb-ac));border-color:var(--ac,var(--gfb-ac));
  color:#FFF}

/* ------------------------------------------------------- language control
   A two-state segmented control rather than a dropdown: there are exactly two
   languages, and a <select> for two options costs a tap to discover what the
   other one is. Each label is written in its own script, which is the whole
   affordance -- a reader who cannot read the English word "Hindi" can read
   the Devanagari. The current language is the disabled half, so the control
   reads as a state rather than as two buttons that both do something. */
.gnav .glang{display:flex;align-items:center;border:1px solid var(--bd,var(--gfb-bd));
  flex:0 0 auto;margin-right:8px}
.gnav .glang button{font:600 11.5px/1 var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);
  letter-spacing:.06em;color:var(--tt,var(--gfb-tt));background:none;border:none;
  padding:7px 9px;cursor:pointer;min-width:34px;white-space:nowrap}
.gnav .glang button:hover:not([disabled]){color:var(--tp,var(--gfb-tp));
  background:var(--s2,var(--gfb-s2))}
/* The Devanagari half needs a face that has the glyphs, and a hair more size:
   at 11.5px the matras on हिं close up against the cap line. */
.gnav .glang button[data-lang="hi"]{font-family:var(--deva,'Tiro Devanagari Hindi',
  'Noto Sans Devanagari','Nirmala UI','Kohinoor Devanagari',serif);font-size:13px;
  letter-spacing:0}
.gnav .glang button[aria-current="true"]{color:var(--s0,var(--gfb-s0));
  background:var(--tp,var(--gfb-tp));cursor:default;opacity:1}

.gnav .burger{display:none;margin-left:auto;width:44px;height:44px;padding:0;
  align-items:center;justify-content:center;background:none;border:1px solid var(--bd,var(--gfb-bd));
  cursor:pointer;color:var(--tp,var(--gfb-tp))}
.gnav .burger span{display:block;width:17px;height:1.5px;background:currentColor;
  position:relative}
.gnav .burger span::before,.gnav .burger span::after{content:"";position:absolute;
  left:0;width:17px;height:1.5px;background:currentColor;transition:.16s ease}
.gnav .burger span::before{top:-5.5px}
.gnav .burger span::after{top:5.5px}
.gnav .burger[aria-expanded="true"] span{background:transparent}
.gnav .burger[aria-expanded="true"] span::before{top:0;transform:rotate(45deg)}
.gnav .burger[aria-expanded="true"] span::after{top:0;transform:rotate(-45deg)}

/* 1100, not 1040, and not 900. Measured each time an item was added, never
   guessed. With nine items the English bar needed 1025px and the Hindi bar
   913px, so the burger came in at 1040. /ank is the tenth item and the
   English bar now needs 1081px, measured in Chromium against the real
   header — so the burger comes in at 1100 and both languages clear it with
   room. Below the old number every screen in the band scrolled the whole
   page sideways, in English, long before the Hindi work went in.
   tools/test_ank_page.js re-measures this and fails the build if an item is
   ever added without moving it. */
@media (max-width:1100px){
  .gnav .burger{display:flex}
  .gnav .links{position:fixed;inset:60px 0 auto 0;margin:0;display:none;
    flex-direction:column;align-items:stretch;gap:0;background:var(--s0,var(--gfb-s0));
    border-bottom:1px solid var(--bd,var(--gfb-bd));padding:6px 12px 14px;
    max-height:calc(100vh - 60px);overflow:auto}
  .gnav .links.open{display:flex}
  .gnav .links a{padding:13px 10px;font-size:15px;border-radius:0}
  .gnav .sep{width:auto;height:1px;margin:6px 10px}
  .gnav .links a.cta{margin:8px 10px 0;text-align:center;padding:13px 15px}
  /* In the drawer everything else is a full-width row; the language control
     is the one thing that should not stretch, so it is left-aligned at its
     natural width with the same 10px gutter as the links above it. */
  .gnav .glang{align-self:flex-start;margin:6px 10px 0}
  /* 44px, measured: the drawer is a touch surface and this control was 39px
     tall before it was checked against a ruler rather than against a
     screenshot. min-height + flex centring rather than more padding, so the
     two halves stay the same height when only one of them is Devanagari --
     हिं is taller than EN and would otherwise set the row height on its own. */
  .gnav .glang button{display:flex;align-items:center;justify-content:center;
    min-height:44px;padding:0 16px;font-size:13px}
  .gnav .glang button[data-lang="hi"]{font-size:15px}
}

/* ------------------------------------------------------------------ footer */
.gfoot{border-top:1px solid var(--bd,var(--gfb-bd));background:var(--s1,var(--gfb-s1));margin-top:56px}
.gfoot .in{max-width:1080px;margin:0 auto;padding:38px 20px 30px}
.gfoot .cols{display:grid;grid-template-columns:1.5fr 1fr 1fr 1fr;gap:30px}
@media (max-width:860px){.gfoot .cols{grid-template-columns:1fr 1fr;gap:26px}}
@media (max-width:480px){.gfoot .cols{grid-template-columns:1fr}}
.gfoot h4{font:600 9.5px/1.3 var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);letter-spacing:.12em;text-transform:uppercase;
  color:var(--tt,var(--gfb-tt));margin:0 0 12px}
.gfoot ul{list-style:none;margin:0;padding:0}
.gfoot li{margin:0 0 8px}
.gfoot a{font-size:13.5px;color:var(--ts,var(--gfb-ts));text-decoration:none}
.gfoot a:hover{color:var(--ac,var(--gfb-ac))}
.gfoot .mark{display:flex;align-items:center;gap:9px;color:var(--tp,var(--gfb-tp));
  text-decoration:none;margin-bottom:11px}
.gfoot .mark b{font-size:16px;font-weight:700;letter-spacing:-.025em}
.gfoot .mark i{font-family:var(--deva,'Tiro Devanagari Hindi','Noto Serif Devanagari',serif);font-style:normal;color:var(--ac,var(--gfb-ac));font-size:14px}
.gfoot .blurb{font-size:13px;line-height:1.6;color:var(--ts,var(--gfb-ts));margin:0 0 16px;max-width:30em}

/* the home-screen note + notify field, in the wide first column */
/* --tt is 3.83:1 on --s1 and this is prose, not a label. Small text is the
   last place to spend contrast. */
.gfoot .install{font-size:12px;line-height:1.65;color:var(--ts,var(--gfb-ts));margin:0 0 12px}
.gfoot .install b{color:var(--ts,var(--gfb-ts));font-weight:600}
.gfoot form{display:flex;gap:7px;flex-wrap:wrap;margin:0;max-width:26em}
.gfoot input[type=email]{flex:1 1 170px;min-width:0;min-height:44px;padding:0 12px;
  font:400 14px/1 var(--sans,'Archivo','Helvetica Neue',Helvetica,Arial,sans-serif);color:var(--tp,var(--gfb-tp));background:var(--s0,var(--gfb-s0));
  border:1px solid var(--bds,var(--gfb-bds));border-radius:0}
.gfoot input[type=email]:focus{outline:2px solid var(--ac,var(--gfb-ac));outline-offset:-1px;
  border-color:var(--ac,var(--gfb-ac))}
.gfoot button{min-height:44px;padding:0 16px;font:600 13px/1 var(--sans,'Archivo','Helvetica Neue',Helvetica,Arial,sans-serif);cursor:pointer;
  background:var(--tp,var(--gfb-tp));color:var(--s0,var(--gfb-s0));border:1px solid var(--tp,var(--gfb-tp));border-radius:0}
.gfoot button:hover{background:var(--ac,var(--gfb-ac));border-color:var(--ac,var(--gfb-ac));color:#FFF}
.gfoot button[disabled]{opacity:.5;cursor:default}
.gfoot .said{font-size:12px;line-height:1.6;color:var(--ts,var(--gfb-ts));margin:10px 0 0;max-width:30em}
.gfoot .said.bad{color:var(--ac,var(--gfb-ac))}
.gfoot .fine{font-size:11px;line-height:1.6;color:var(--ts,var(--gfb-ts));margin:9px 0 0;max-width:30em}

.gfoot .base{border-top:1px solid var(--bd,var(--gfb-bd));margin-top:30px;padding-top:18px;
  display:flex;flex-wrap:wrap;gap:8px 20px;align-items:baseline}
.gfoot .base p{font-size:12px;color:var(--ts,var(--gfb-ts));margin:0}
.gfoot .base .right{margin-left:auto;display:flex;gap:18px;flex-wrap:wrap}
.gfoot .base a{font-size:12px;color:var(--ts,var(--gfb-ts))}

.gvh{position:absolute;width:1px;height:1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap}

/* ================================================================= marketing
   Used by the front page. Kept here rather than inline so the next page that
   needs a hero or a card grid does not invent a second version of one. */

.gsec{max-width:1080px;margin:0 auto;padding:0 20px}
.gsec + .gsec{margin-top:64px}
@media (max-width:700px){.gsec + .gsec{margin-top:46px}}

.geyebrow{font:600 9.5px/1.3 var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);letter-spacing:.13em;text-transform:uppercase;
  color:var(--tt,var(--gfb-tt));margin:0 0 12px;display:flex;align-items:center;gap:8px}
.geyebrow::before{content:"";width:5px;height:5px;background:var(--ac,var(--gfb-ac));flex:0 0 auto}

/* hero -------------------------------------------------------------------- */
/* padding-top/bottom, not the shorthand: .gsec sets the 20px gutter and a
   `padding:60px 0 18px` here silently zeroed it, putting the headline hard
   against the left edge of every phone. */
.ghero{padding-top:60px;padding-bottom:18px}
@media (max-width:700px){.ghero{padding-top:38px;padding-bottom:12px}}
.ghero h2{font-size:clamp(31px,5.4vw,52px);line-height:1.06;letter-spacing:-.032em;
  font-weight:700;color:var(--tp,var(--gfb-tp));margin:0 0 20px;max-width:16em}
.ghero .lede{font-size:clamp(15px,2vw,18px);line-height:1.6;color:var(--ts,var(--gfb-ts));
  margin:0 0 26px;max-width:34em}
.ghero .lede b{color:var(--tp,var(--gfb-tp));font-weight:600}
.ghero .acts{display:flex;gap:11px;flex-wrap:wrap;align-items:center}
.gbtn{display:inline-flex;align-items:center;justify-content:center;min-height:46px;
  padding:0 20px;font:600 14.5px/1 var(--sans,'Archivo','Helvetica Neue',Helvetica,Arial,sans-serif);text-decoration:none;border-radius:0;
  border:1px solid var(--tp,var(--gfb-tp));background:var(--tp,var(--gfb-tp));color:var(--s0,var(--gfb-s0));cursor:pointer}
.gbtn:hover{background:var(--ac,var(--gfb-ac));border-color:var(--ac,var(--gfb-ac));color:#FFF}
.gbtn.ghost{background:none;color:var(--tp,var(--gfb-tp))}
.gbtn.ghost:hover{background:var(--s2,var(--gfb-s2));color:var(--tp,var(--gfb-tp));border-color:var(--tp,var(--gfb-tp))}

/* store badges ------------------------------------------------------------ */
/* Apple's and Google's artwork, unaltered. The two files are drawn to
   different conventions: Apple's SVG is the button and nothing else, Google's
   PNG wraps the button in 41px of transparent clear space on all four sides
   (646x250 around a 564x168 button). Rendered at their natural proportions
   that puts the Play button 33% shorter and floating away from the Apple one,
   so the Play image is rendered taller and the clear space is pulled back out
   with a negative margin: 66 x 0.672 = 44.4px of visible button against
   Apple's 44, and the two left edges line up. */
.gstores{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.gstore{display:inline-flex;text-decoration:none;border:0}
.gstore img{display:block;height:44px;width:auto}
.gstore:hover img{opacity:.82}
.gstore.play img{height:66px;margin:-11px -10.8px}
.ghero .gnow{font:600 9.5px/1.3 var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);
  letter-spacing:.11em;text-transform:uppercase;color:var(--ac,var(--gfb-ac));margin:28px 0 12px}
.gfoot .gstores{margin:0 0 16px}

/* the proof strip under the hero */
.gproof{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--bd,var(--gfb-bd));
  border:1px solid var(--bd,var(--gfb-bd));margin-top:34px}
@media (max-width:640px){.gproof{grid-template-columns:1fr}}
.gproof div{background:var(--s1,var(--gfb-s1));padding:16px 18px}
.gproof .k{font:600 9.5px/1.3 var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);letter-spacing:.11em;text-transform:uppercase;
  color:var(--tt,var(--gfb-tt));margin:0 0 6px}
.gproof .v{font-size:14px;line-height:1.5;color:var(--tp,var(--gfb-tp));margin:0;font-weight:500}
.gproof .v span{color:var(--ts,var(--gfb-ts));font-weight:400}

/* section heading --------------------------------------------------------- */
.ghd{font-size:clamp(22px,3.2vw,30px);line-height:1.15;letter-spacing:-.024em;
  font-weight:700;color:var(--tp,var(--gfb-tp));margin:0 0 12px;max-width:20em}
.gsub{font-size:15px;line-height:1.65;color:var(--ts,var(--gfb-ts));margin:0 0 26px;max-width:40em}

/* module cards ------------------------------------------------------------ */
.gcards{display:grid;grid-template-columns:repeat(2,1fr);gap:1px;background:var(--bd,var(--gfb-bd));
  border:1px solid var(--bd,var(--gfb-bd))}
@media (max-width:760px){.gcards{grid-template-columns:1fr}}
.gcard{background:var(--s1,var(--gfb-s1));padding:24px 22px 22px;display:flex;flex-direction:column;
  text-decoration:none;color:inherit;position:relative;transition:background .14s ease}
.gcard:hover{background:var(--s2,var(--gfb-s2))}
.gcard .dv{font-family:var(--deva,'Tiro Devanagari Hindi','Noto Serif Devanagari',serif);font-size:19px;color:var(--ac,var(--gfb-ac));line-height:1;
  margin-bottom:10px;display:block}
.gcard h3{font-size:18px;font-weight:600;letter-spacing:-.018em;color:var(--tp,var(--gfb-tp));
  margin:0 0 4px}
.gcard .en{font:600 9.5px/1.3 var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);letter-spacing:.11em;text-transform:uppercase;
  color:var(--tt,var(--gfb-tt));margin:0 0 11px}
.gcard p{font-size:13.5px;line-height:1.6;color:var(--ts,var(--gfb-ts));margin:0 0 16px}
.gcard .tag{margin-top:auto;font:600 9.5px/1 var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);letter-spacing:.09em;
  text-transform:uppercase;color:var(--ts,var(--gfb-ts));border:1px solid var(--bds,var(--gfb-bds));
  padding:5px 8px;align-self:flex-start}
.gcard .tag.paid{border-color:var(--ac,var(--gfb-ac));color:var(--ac,var(--gfb-ac))}
.gcard .go{position:absolute;right:20px;top:24px;color:var(--tt,var(--gfb-tt));font-size:15px}
.gcard:hover .go{color:var(--ac,var(--gfb-ac))}

/* pricing ----------------------------------------------------------------- */
.gprice{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--bd,var(--gfb-bd));
  border:1px solid var(--bd,var(--gfb-bd))}
@media (max-width:720px){.gprice{grid-template-columns:1fr}}
.gtier{background:var(--s1,var(--gfb-s1));padding:26px 24px;display:flex;flex-direction:column}
.gtier.on{background:var(--tint,var(--gfb-tint))}
.gtier .nm{font-size:19px;font-weight:700;letter-spacing:-.02em;color:var(--tp,var(--gfb-tp));margin:0}
.gtier .amt{font-family:var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);font-size:30px;font-weight:500;color:var(--tp,var(--gfb-tp));
  letter-spacing:-.02em;margin:12px 0 2px;font-variant-numeric:tabular-nums}
.gtier .amt small{font-size:13px;color:var(--ts,var(--gfb-ts));font-weight:400;letter-spacing:0}
.gtier .alt{font-family:var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);font-size:12px;color:var(--ts,var(--gfb-ts));margin:0 0 18px}
.gtier .note{font-size:13px;line-height:1.6;color:var(--ts,var(--gfb-ts));margin:0 0 18px}
.gtier ul{list-style:none;margin:0 0 20px;padding:0}
.gtier li{font-size:13.5px;line-height:1.55;color:var(--ts,var(--gfb-ts));padding:0 0 0 20px;
  margin:0 0 9px;position:relative}
.gtier li:last-child{margin-bottom:0}
.gtier li::before{content:"";position:absolute;left:0;top:7px;width:8px;height:1.5px;
  background:var(--ac,var(--gfb-ac))}
.gtier .gbtn{width:100%;margin-top:auto}

/* a plain prose block ----------------------------------------------------- */
.gnote{border-left:2px solid var(--bd,var(--gfb-bd));padding:2px 0 2px 16px;margin:22px 0 0;
  font-size:13.5px;line-height:1.65;color:var(--ts,var(--gfb-ts));max-width:44em}
.gnote b{color:var(--tp,var(--gfb-tp));font-weight:600}

/* the wall (paywall.js) --------------------------------------------------- */
.gwall{border:1px solid var(--bds,var(--gfb-bds));background:var(--s1,var(--gfb-s1));padding:20px 20px 18px;margin:18px 0}
.gwall-k{font:600 9.5px/1.3 var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);letter-spacing:.11em;text-transform:uppercase;
  color:var(--ac,var(--gfb-ac));margin:0 0 6px}
.gwall-h{font-size:19px;font-weight:700;letter-spacing:-.02em;color:var(--tp,var(--gfb-tp));margin:0 0 6px}
.gwall-p{font-size:14px;line-height:1.6;color:var(--ts,var(--gfb-ts));margin:0 0 14px;max-width:44em}
.gwall-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:1px;background:var(--bd,var(--gfb-bd));
  border:1px solid var(--bd,var(--gfb-bd))}
@media (max-width:720px){.gwall-grid{grid-template-columns:1fr}}
.gwall-pass{background:var(--s1,var(--gfb-s1));padding:16px 16px 14px;display:flex;flex-direction:column;min-width:0}
.gwall-pass.best{background:var(--tint,var(--gfb-tint))}
.gwall-best{font:600 9.5px/1 var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);letter-spacing:.09em;text-transform:uppercase;
  color:var(--ac,var(--gfb-ac));margin:0 0 8px}
.gwall-nm{font-size:15px;font-weight:700;color:var(--tp,var(--gfb-tp));margin:0}
.gwall-amt{font-family:var(--mono,'IBM Plex Mono',ui-monospace,Menlo,monospace);font-size:26px;font-weight:500;
  color:var(--tp,var(--gfb-tp));margin:6px 0 4px;font-variant-numeric:tabular-nums}
.gwall-blurb{font-size:13px;line-height:1.5;color:var(--ts,var(--gfb-ts));margin:0 0 14px}
.gwall-pass .gbtn{margin-top:auto;width:100%;min-height:42px}
.gwall-acts{display:flex;gap:10px;flex-wrap:wrap}
.gwall-fine{font-size:12px;line-height:1.55;color:var(--tt,var(--gfb-tt));margin:12px 0 0;max-width:48em}
.gwall-err{font-size:13px;color:var(--ac,var(--gfb-ac));margin:10px 0 0}
@media print{.gwall{display:none}}

/* dark ------------------------------------------------------------------- */
@media (prefers-color-scheme:dark){
  .gnav{background:var(--s0,var(--gfb-s0))}
  .gfoot{background:var(--s1,var(--gfb-s1))}
}

/* ============================================================ page headers
   Every content page opened with a bare eyebrow and an <h2> inside the old
   .wrap, so only the front page looked designed. This band gives the other
   thirteen the same opening: a rule, the module name, the title, the lede —
   and it sits on --s1 so the page proper starts at a visible edge. */
.ghead{background:var(--s1,var(--gfb-s1));border-bottom:1px solid var(--bd,var(--gfb-bd));
  padding:38px 0 32px;margin-bottom:30px}
@media (max-width:700px){.ghead{padding:26px 0 24px;margin-bottom:22px}}
.ghead .in{max-width:1080px;margin:0 auto;padding:0 20px}
.ghead h2,.ghead .title{font-size:clamp(25px,3.8vw,38px);line-height:1.1;
  letter-spacing:-.028em;font-weight:700;color:var(--tp,var(--gfb-tp));margin:0 0 14px;
  max-width:18em}
.ghead .lede{font-size:clamp(14.5px,1.7vw,16.5px);line-height:1.62;
  color:var(--ts,var(--gfb-ts));margin:0;max-width:42em}
.ghead .lede strong,.ghead .lede b{color:var(--tp,var(--gfb-tp));font-weight:600}

/* ===================================================== states and emptiness
   A bare em dash is not a loading state; it is a page that looks broken for
   as long as the network takes. */
.gskel{display:inline-block;min-width:7em;height:.72em;vertical-align:middle;
  border-radius:1px;background:linear-gradient(90deg,
    var(--s2,var(--gfb-s2)) 25%, var(--bd,var(--gfb-bd)) 37%, var(--s2,var(--gfb-s2)) 63%);
  background-size:400% 100%;animation:gsheen 1.3s ease-in-out infinite}
@keyframes gsheen{0%{background-position:100% 50%}100%{background-position:0 50%}}
@media (prefers-reduced-motion:reduce){.gskel{animation:none}}

.gempty{border:1px dashed var(--bds,var(--gfb-bds));background:var(--s1,var(--gfb-s1));
  padding:26px 22px;text-align:center}
.gempty p{margin:0 0 6px;font-size:14.5px;color:var(--tp,var(--gfb-tp));font-weight:600}
.gempty small{font-size:13px;line-height:1.6;color:var(--ts,var(--gfb-ts));display:block;
  max-width:32em;margin:0 auto}

/* ================================================================ dark mode
   The token block each page carries already flips. What did not flip was
   anything this file hard-codes as a fallback, which is every fallback added
   for the four pages that never declared the tokens. On a page that DOES
   declare them the var() wins and dark works; on one that does not, the
   fallback is a light value. So those four get an explicit dark set. */
@media (prefers-color-scheme:dark){
  /* Panels only. Every colour above already flips through --gfb-*. */
  .gtier.on{background:var(--tint,var(--gfb-tint))}
}


/* ==========================================================================
   Hindi
   --------------------------------------------------------------------------
   Set on <html> by chrome.js before i18n.js has even landed, so the type is
   already right when the first Devanagari appears.

   Two things change and nothing else. First the font stacks: Archivo stays in
   front so Latin -- the brand, the numbers, "Stripe", "JPL" -- renders exactly
   as it does in English, and the Devanagari faces sit behind it to catch the
   glyphs Archivo does not have. Putting a Devanagari face first would work and
   would quietly restyle every digit on the site, which on a page of sunrise
   times is the entire page.

   Second, room. Devanagari hangs a matra above the line and a few conjuncts
   below it, so English line-heights clip. And the mono eyebrows are set in
   uppercase with .12em tracking: uppercase does nothing to Devanagari, while
   tracking pulls conjuncts apart into their component letters, which is the
   difference between a label and a spelling mistake.
   ========================================================================== */
:root[lang="hi"]{
  --sans:'Archivo','Helvetica Neue',Helvetica,Arial,'Noto Sans Devanagari',
    'Nirmala UI','Kohinoor Devanagari','Devanagari Sangam MN',Mangal,sans-serif;
  --mono:'IBM Plex Mono',ui-monospace,Menlo,'Noto Sans Devanagari','Nirmala UI',
    'Kohinoor Devanagari',monospace;
}
:root[lang="hi"] body{line-height:1.68}
:root[lang="hi"] h1,:root[lang="hi"] h2,:root[lang="hi"] h3,:root[lang="hi"] h4{line-height:1.4}
:root[lang="hi"] .geyebrow,:root[lang="hi"] .gfoot h4,:root[lang="hi"] .eyebrow,
:root[lang="hi"] .gproof .k,:root[lang="hi"] .gcard .en,:root[lang="hi"] .gcard .tag,
:root[lang="hi"] .gl-card .lab{letter-spacing:.02em}

/* The inline gloss appositive used to be hidden here: it is generated inside
   gloss.js, and while the definitions were English-only it would have been the
   one English clause in a Hindi sentence. Every term carries Hindi now, and
   gloss.js builds the appositive from the reader's own language, so it stays
   on -- hiding it would remove the first and cheapest explanation a Hindi
   reader gets, which is the whole point of the layer. */
