/* Nasr Solar, demo skeleton
   Palette derived from CIRCLE-LOGO.png, not from the old site.
   Logo is 66.9% blue / 28.6% gold. The old site's navy (#0F172A = Tailwind slate-900)
   and cream (#FAF5E5) appear nowhere in the mark and are not used here.
   Hero uses the client's own BACKGROUND-IMAGE.png under a blue scrim. Their
   remaining photography is demo-garden snapshots and is not hero material. */

:root {
  /* brand, sampled from the logo */
  --blue-700: #0F5F94;
  --blue-600: #157DBE;   /* gradient start */
  --blue-500: #1A8AC7;   /* PRIMARY, logo dominant */
  --blue-400: #15A4DB;   /* gradient end */
  --blue-100: #DCEEF8;
  --blue-050: #F1F8FC;

  --gold-600: #D29E53;
  --gold-500: #FCBF1E;   /* ACCENT, logo sun */
  --gold-400: #FFC721;
  --gold-100: #FFF2CC;

  /* neutrals derived from the brand hue (201°), not generic grey */
  /* hue 218, matching the hero field. Was #0A2A3D (hue 202) which read teal-green
     where .stats-lift sits ON the navy hero: a hard edge across a 15-degree gap.
     --ink paints 7 surfaces (stats, footer, admin side, chips, wa tip) and colours
     ~10 text rules; at 14% luminance the hue shift is invisible as text and is the
     whole fix as a surface. Same lum/sat as before, hue only. */
  --ink:       #0A1D3D;
  --ink-soft:  #4A6B7C;
  --ink-faint: #7D97A5;
  --line:      #E2EBF0;
  --bg:        #FFFFFF;
  --bg-soft:   #F4F8FA;

  --radius: 10px;
  --radius-lg: 16px;
  --wrap: 1120px;
  --shadow-sm: 0 1px 2px rgba(10,42,61,.06);
  --shadow-md: 0 4px 16px rgba(10,42,61,.08);
}

* { box-sizing: border-box; }

html { -webkit-text-size-adjust: 100%; }

body {
  margin: 0;
  font-family: 'Cairo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  color: var(--ink);
  background: var(--bg);
  line-height: 1.75;
  font-size: 16px;
}
/* TEMPORARY demo A/B: when the toggle sets this class, the whole site renders in
   Alyamama (the client's requested face); default stays Cairo. Remove with the rest
   of the font-A/B affordance once the choice is locked. See views/_font-ab.php. */
body.font-alyamama { font-family: 'Alyamama', 'Cairo', system-ui, -apple-system, 'Segoe UI', sans-serif; }

/* RTL: use logical properties throughout so an /en/ LTR mirror needs no CSS fork */
h1,h2,h3,h4 { line-height: 1.35; margin: 0 0 .5rem; font-weight: 700; }
h1 { font-size: clamp(1.9rem, 4vw, 2.9rem); letter-spacing: -.01em; }
h2 { font-size: clamp(1.4rem, 2.6vw, 2rem); }
h3 { font-size: 1.15rem; }
p  { margin: 0 0 1rem; }
a  { color: var(--blue-600); text-decoration: none; }
a:hover { text-decoration: underline; }
img { max-width: 100%; height: auto; display: block; }

.wrap { max-width: var(--wrap); margin-inline: auto; padding-inline: 1.25rem; }
.muted { color: var(--ink-soft); }
.center { text-align: center; }

/* ---------- header ---------- */

.site-header {
  position: sticky; top: 0; z-index: 50;
  background: rgba(255,255,255,.92);
  backdrop-filter: saturate(1.4) blur(8px);
  border-block-end: 1px solid var(--line);
}
.site-header .wrap { display: flex; align-items: center; gap: 1.5rem; min-height: 72px; flex-wrap: wrap; }
.brand { display: flex; align-items: center; gap: .7rem; flex-shrink: 0; }
.brand img { width: 44px; height: 44px; object-fit: contain; }
.brand span { font-weight: 700; font-size: 1.02rem; color: var(--ink); letter-spacing: -.01em; }

.nav { display: flex; gap: .3rem; margin-inline-start: auto; align-items: center; flex-wrap: wrap; }
.nav a {
  color: var(--ink); padding: .5rem .8rem; border-radius: var(--radius);
  font-size: .95rem; font-weight: 500;
}
.nav a:hover { background: var(--blue-050); text-decoration: none; }
.nav a.is-active { color: var(--blue-600); background: var(--blue-050); }
.nav a.cta {
  background: var(--blue-500); color: #fff;
}
.nav a.cta:hover { background: var(--blue-600); }

/* ---------- hero ----------
   Was: the same hero.jpg + scrim on all NINE pages. That repetition, not the colour,
   was what made the site read as generic. Now every page owns its art via
   /assets/img/hero-<key>.*, and the gradient below is the deliberate fallback until
   that file exists, not a placeholder. */

/* The field COMMITS to dark. The old gradient was a mid-bright cyan: neither light nor
   dark, so a deep-navy hero image sat on top of it like a sticker instead of belonging
   to it. Tested against a light field too (the LuminaRay logic): light makes the image
   pop hardest, but it merges the hero into the white nav and kills the header
   separation. Dark wins: the art's blacks dissolve into the field and the gold junction
   becomes the only light in the frame. */
.hero {
  position: relative; overflow: hidden; color: #fff;
  /* Deep navy, hue 218. Sampled the logo first: its ENTIRE blue family sits at
     40-46% luminance, hue 203, and the darkest real pixel in it is #137AB9 - which
     is ~#157DBE, the exact cyan this hero was rescued from. So "use their darkest
     blue" was a trap; there is no dark blue in that logo to use.
     218 leaves their hue by 15 degrees, and that is free here: the logo lives in the
     white header and never touches this field, so nothing in the layout ever puts
     203 against 218. Going darker still (N4, ~4-15% lum) collapses toward black and
     the field stops reading as blue at all - the cyan failure mirrored. */
  background:
    radial-gradient(900px 480px at 78% 8%, rgba(252,191,30,.10), transparent 62%),
    linear-gradient(160deg, #060E1B 0%, #091831 46%, #0E2A5B 100%);
}
/* faint engineered grid: gives the flat gradient structure without an image, and
   says "drawing" rather than "wallpaper" */
.hero-fx {
  position: absolute; inset: 0; pointer-events: none; opacity: .35;
  background-image:
    linear-gradient(rgba(255,255,255,.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255,255,255,.05) 1px, transparent 1px);
  background-size: 46px 46px;
  mask-image: radial-gradient(120% 100% at 80% 0%, #000 20%, transparent 75%);
  -webkit-mask-image: radial-gradient(120% 100% at 80% 0%, #000 20%, transparent 75%);
}
.hero .wrap { position: relative; z-index: 2; }
/* 900, not 700. The hero headline was the same weight as every section header, so it
   never got its own moment. Weight is the right lever here, not a second family: the
   Arabic type guides warn specifically against pairing a decorative display face with
   a sans (Amiri, Reem Kufi et al read as two brands colliding). Cairo is the consensus
   corporate face and its variable axis reaches 900 at no byte cost. 1.35 line-height
   is a reading value; at display size it left the three lines drifting apart. */
.hero h1 {
  color: #fff; margin-bottom: 1rem; text-wrap: balance;
  font-weight: 900; line-height: 1.25;
}
.hero p { color: rgba(255,255,255,.9); font-size: 1.08rem; max-width: 52ch; line-height: 1.85; }
.hero .eyebrow {
  display: inline-flex; align-items: center; gap: .5rem;
  background: rgba(252,191,30,.16); border: 1px solid rgba(252,191,30,.42);
  color: var(--gold-400);
  padding: .3rem .8rem; border-radius: 999px;
  font-size: .82rem; font-weight: 600; margin-bottom: 1.1rem;
}
.hero-actions { display: flex; gap: .7rem; flex-wrap: wrap; margin-top: 1.7rem; }

/* compact band: inner pages with no art of their own yet */
.hero-band .wrap { padding-block: clamp(2.2rem, 4vw, 3.2rem); }
.hero-band h1 { font-size: clamp(1.6rem, 3vw, 2.2rem); }
.hero-band .hero-inner { max-width: 640px; }
.hero-band p { margin-bottom: 0; }

/* split: text one side, that page's art the other */
.hero-split .wrap {
  display: grid; grid-template-columns: 1fr 0.82fr; gap: clamp(1.5rem, 4vw, 3.5rem);
  /* stretch, not center: centring left the text card at its content height (461.4px
     measured) inside a 520px row, so it sat 58.6px shorter than the art and the two
     columns read as mismatched. Stretch makes both fill the row; the card then centres
     its own content internally (see .hero-split .hero-inner). */
  align-items: stretch; padding-block: clamp(2.4rem, 5vw, 4rem);
}
.hero-split.hero-big .wrap { min-height: 540px; padding-block: clamp(2.5rem, 5vw, 4.5rem); }
/* line-height must be repeated here, not inherited from `.hero h1`. Both selectors are
   specificity (0,1,1) and this one comes later, so it wins on source order: setting
   1.25 up there had no effect on the home hero at all while this said 1.35. */
.hero-big h1 { font-size: clamp(1.9rem, 3.6vw, 2.9rem); line-height: 1.25; }
.hero-art { margin: 0; position: relative; }
/* align-items: center is load-bearing, not cosmetic. A flex container defaults to
   align-items: stretch, and the img's height is auto -- so once the grid above became
   `stretch`, any row taller than the picture (a longer headline on another page, a
   narrow viewport) would stretch the img vertically and break its aspect ratio.
   Centring pins it to its natural height. */
.hero-art { display: flex; justify-content: center; align-items: center; }
.hero-art img {
  width: 100%; height: auto; max-height: 520px; display: block;
  border-radius: var(--radius-lg);
  box-shadow: 0 30px 80px rgba(0,0,0,.55);
  background: rgba(255,255,255,.04);
}
@media (min-width: 861px) { .hero-art img { width: auto; margin-inline: auto; } }

/* Glass panel behind the headline. On the dark field the words are already legible, so
   this is for weight, not rescue: it pairs the text with the art card so the hero reads
   as two deliberate objects rather than type floating on a gradient. */
.hero-split .hero-inner {
  /* The card now fills the row (align-items: stretch above), so without this its text
     would pin to the top of 520px and float in dead space. Flex column + centred main
     axis keeps the content optically where it was while the panel matches the art. */
  display: flex; flex-direction: column; justify-content: center;
  background: rgba(255,255,255,.055);
  border: 1px solid rgba(255,255,255,.10);
  border-radius: 22px;
  padding: clamp(1.6rem, 2.6vw, 2.4rem);
  backdrop-filter: blur(10px);
  -webkit-backdrop-filter: blur(10px);
  box-shadow: 0 20px 60px rgba(0,0,0,.28);
}
/* Consequence of making .hero-inner a flex column: its children are flex items now, and
   a column container stretches them on the cross (horizontal) axis by default. The NREA
   eyebrow is an inline-flex pill and would stretch into a full-width bar without this.
   `start` rather than `flex-start` is writing-mode aware, so under dir="rtl" it pins to
   the right. h1 / p / .hero-actions are happy stretching -- they want the full width. */
.hero-split .hero-inner > .eyebrow { align-self: start; }

@media (max-width: 860px) {
  .hero-split .hero-inner { padding: 1.3rem; }
}
.hero-art figcaption {
  margin-top: .6rem; font-size: .76rem; color: rgba(255,255,255,.6); text-align: center;
}
@media (max-width: 860px) {
  .hero-split .wrap { grid-template-columns: 1fr; }
  .hero-split.hero-big .wrap { min-height: 0; }
  .hero-art { order: 2; }            /* words first on a phone, picture after */
}

/* a project's own photo may back its hero: it IS that project. Scrim stays. */
.hero-shot .wrap { padding-block: clamp(2.4rem, 5vw, 3.4rem); }
.hero-shot .hero-inner { max-width: 640px; }
.hero-shot h1 { font-size: clamp(1.6rem, 3vw, 2.3rem); }
.hero-img { position: absolute; inset: 0; pointer-events: none; background: no-repeat center / cover; }
.hero-scrim {
  position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(to left, rgba(15,95,148,.94) 0%, rgba(21,125,190,.80) 42%, rgba(10,42,61,.30) 100%);
}

.btn {
  display: inline-block; padding: .7rem 1.4rem; border-radius: var(--radius);
  font-weight: 600; font-size: .96rem; border: 1px solid transparent; cursor: pointer;
  font-family: inherit;
}
.btn:hover { text-decoration: none; }
.btn-gold { background: var(--gold-500); color: #3D2E00; }
.btn-gold:hover { background: var(--gold-400); }
.btn-ghost { background: rgba(255,255,255,.1); color: #fff; border-color: rgba(255,255,255,.35); }
.btn-ghost:hover { background: rgba(255,255,255,.18); }
.btn-blue { background: var(--blue-500); color: #fff; }
.btn-blue:hover { background: var(--blue-600); }
.btn-line { background: #fff; color: var(--ink); border-color: var(--line); }
.btn-line:hover { border-color: var(--blue-400); color: var(--blue-600); }

/* ---------- stats band ---------- */

/* ---- counting stats -------------------------------------------------------------
   A count-up with no JavaScript, keeping this build's zero-JS property intact.
   @property registers --tick-n as a real <integer>, which is the whole trick: only a
   REGISTERED custom property can interpolate. Unregistered ones animate discretely, so
   without this the number would sit at 0 and then snap.

   Failure mode is the design constraint here, not the effect. The true Arabic number
   lives in .tick-fb in the HTML and renders by default; the counter only takes over
   INSIDE the @supports block. So any browser that cannot run this shows the correct
   static ٦٣٠ rather than ٠. Showing "٠ مشروع مُنفّذ" to a client would be far worse
   than showing no animation, so the guard fails toward the truth.
   counter(..., arabic-indic) keeps the digits Arabic-Indic; a plain counter() would
   render 630 in Latin digits and break the page's numerals. */
@property --tick-n {
  syntax: "<integer>";
  initial-value: 0;
  inherits: false;
}

@supports at-rule(@property) {
  .tick { counter-reset: tick-n var(--tick-n); }
  .tick .tick-fb { display: none; }
  .tick::before { content: var(--tick-pre, "") counter(tick-n, arabic-indic); }

  /* Deliberately NOT gated on prefers-reduced-motion, unlike .reveal below.
     That setting exists for vestibular triggers: parallax, zoom, spin, things moving
     across the viewport. These digits change in place -- no translation, no scale, no
     scroll coupling -- which is nearer to text updating than to motion. On Windows the
     flag is also routinely set for performance or by a corporate image rather than as an
     accessibility choice, so gating on it hid the effect from most of the people meant
     to see it (including every machine we tested on) to protect against a risk this
     particular animation does not carry. Runs once, 2.2s, then it is over.
     If a genuinely motion-sensitive complaint ever lands, restore the gate here -- the
     .tick-fb fallback in the markup already renders the correct static number. */
  .tick { animation: tick-up 2.2s cubic-bezier(.16,.84,.32,1) .25s both; }
}

@keyframes tick-up {
  from { --tick-n: 1; }
  to   { --tick-n: var(--tick-to); }
}

.stats { background: var(--ink); color: #fff; }
.stats .wrap { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; padding-block: 2rem; }
.stat { text-align: center; }
.stat b {
  display: block; font-size: clamp(1.5rem, 3vw, 2.1rem); font-weight: 700;
  color: var(--gold-500); line-height: 1.2;
}
.stat span { font-size: .88rem; color: rgba(255,255,255,.72); }

/* ---------- sections ---------- */

.section { padding-block: clamp(2.5rem, 5vw, 4rem); }
.section-soft { background: var(--bg-soft); }
.section-head { margin-bottom: 1.8rem; max-width: 60ch; }
.section-head p { color: var(--ink-soft); margin: 0; }

.grid { display: grid; gap: 1.1rem; }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-2 { grid-template-columns: repeat(2, 1fr); }

/* ---------- filter bar ---------- */

.filterbar {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1rem 1.2rem; box-shadow: var(--shadow-sm);
  display: flex; align-items: center; gap: 1rem; flex-wrap: wrap;
}
.filterbar-label {
  font-size: .8rem; font-weight: 700; color: var(--ink-faint);
  letter-spacing: .02em; white-space: nowrap;
}
.chips { display: flex; gap: .4rem; flex-wrap: wrap; }
.chip {
  display: inline-flex; align-items: center; gap: .4rem;
  padding: .42rem .85rem; border-radius: 999px;
  border: 1px solid var(--line); background: var(--bg-soft);
  color: var(--ink); font-size: .88rem; font-weight: 600; white-space: nowrap;
}
.chip:hover { border-color: var(--blue-400); color: var(--blue-600); text-decoration: none; }
.chip b {
  font-size: .74rem; font-weight: 700; padding: .05rem .38rem; border-radius: 999px;
  background: #fff; border: 1px solid var(--line); color: var(--ink-faint); min-width: 1.2rem; text-align: center;
}
.chip.is-on { background: var(--ink); border-color: var(--ink); color: #fff; }
.chip.is-on b { background: rgba(255,255,255,.16); border-color: transparent; color: var(--gold-500); }

.filterbar-search { display: flex; gap: .5rem; margin-inline-start: auto; flex-wrap: wrap; }
.filterbar-search .input { width: 280px; }
@media (max-width: 900px) {
  .filterbar-search { margin-inline-start: 0; width: 100%; }
  .filterbar-search .input { flex: 1; width: auto; min-width: 0; }
}

/* empty state: a search that finds nothing must still look designed */
.empty {
  text-align: center; padding: 3.5rem 1rem;
  border: 1px dashed var(--line); border-radius: var(--radius-lg); background: var(--bg-soft);
}
.empty-mark { font-size: 2.4rem; color: var(--gold-500); line-height: 1; margin-bottom: .5rem; }
.empty h3 { margin-bottom: .2rem; }

/* ---------- cards ---------- */

.card {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.4rem; box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column;
}
.card h3 { margin-bottom: .35rem; }
.card p { color: var(--ink-soft); font-size: .94rem; margin-bottom: 0; }
a.card:hover { border-color: var(--blue-400); box-shadow: var(--shadow-md); text-decoration: none; }

.card-icon {
  width: 42px; height: 42px; border-radius: 10px; margin-bottom: .9rem;
  background: var(--blue-050); border: 1px solid var(--blue-100);
  display: grid; place-items: center; font-size: 1.2rem; flex-shrink: 0;
}

/* project card: colour-blocked header stands in for a photo */
.pcard { padding: 0; overflow: hidden; }
.pcard-top {
  position: relative; padding: 1.3rem; min-height: 132px;
  background: linear-gradient(135deg, var(--blue-600), var(--blue-400));
  color: #fff; display: flex; flex-direction: column; justify-content: space-between;
  overflow: hidden;
}
.pcard-top.t-off_grid { background: linear-gradient(135deg, #0F5F94, #1A8AC7); }
.pcard-top.t-hybrid   { background: linear-gradient(135deg, #157DBE, #D29E53); }
.pcard-top.t-pump     { background: linear-gradient(135deg, #0F5F94, #15A4DB); }
.pcard-cap { font-size: 1.9rem; font-weight: 700; line-height: 1; position: relative; z-index: 2; }
.pcard-cap small { font-size: .8rem; font-weight: 500; opacity: .8; margin-inline-start: .25rem; }
.pcard-type {
  position: relative; z-index: 2; align-self: flex-start;
  background: rgba(255,255,255,.16); border: 1px solid rgba(255,255,255,.28);
  padding: .2rem .65rem; border-radius: 999px; font-size: .78rem; font-weight: 600;
}
/* photo variant: image sits under a scrim so the capacity stays legible on any shot */
.pcard-top.has-img {
  background-size: cover; background-position: center; min-height: 168px;
}
.pcard-top.has-img::before {
  content: ''; position: absolute; inset: 0;
  background: linear-gradient(to top, rgba(10,42,61,.82) 0%, rgba(10,42,61,.20) 60%, rgba(10,42,61,.35) 100%);
}

.pcard-body { padding: 1.1rem 1.3rem 1.3rem; }
.pcard-meta { display: flex; gap: 1rem; font-size: .85rem; color: var(--ink-soft); flex-wrap: wrap; }
.pcard-meta span { display: inline-flex; align-items: center; gap: .3rem; }

/* calculator: coming-soon tile (NOT built) */
.calc-tile {
  position: relative; overflow: hidden;
  border: 1px dashed var(--blue-400); background: var(--blue-050);
  border-radius: var(--radius-lg); padding: 1.8rem;
  display: flex; align-items: center; gap: 1.5rem; flex-wrap: wrap;
}
.calc-tile .badge {
  background: var(--gold-500); color: #3D2E00; font-weight: 700; font-size: .75rem;
  padding: .25rem .7rem; border-radius: 999px; white-space: nowrap;
}
.calc-tile h3 { margin: 0; }
.calc-tile p { margin: .3rem 0 0; color: var(--ink-soft); font-size: .93rem; }

/* ---------- project gallery ---------- */

.gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: .9rem; }
.gitem { margin: 0; border-radius: 12px; overflow: hidden; border: 1px solid var(--line); background: #fff; }
.gitem img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
.gitem figcaption { padding: .6rem .8rem; font-size: .84rem; color: var(--ink-soft); }
@media (max-width: 900px) { .gallery { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) { .gallery { grid-template-columns: 1fr; } }

/* admin gallery manager */
.gmanage { display: grid; grid-template-columns: repeat(4, 1fr); gap: .7rem; margin-bottom: .8rem; }
.gmanage figure { margin: 0; position: relative; border-radius: 8px; overflow: hidden; border: 1px solid var(--line); }
.gmanage img { width: 100%; aspect-ratio: 4/3; object-fit: cover; display: block; }
.gmanage label {
  position: absolute; inset-block-end: 0; inset-inline: 0; background: rgba(10,42,61,.86);
  color: #fff; font-size: .78rem; padding: .3rem .5rem; display: flex; align-items: center;
  gap: .35rem; cursor: pointer; font-weight: 400;
}
@media (max-width: 700px) { .gmanage { grid-template-columns: repeat(2, 1fr); } }

/* ---------- contact ---------- */
.contact-grid { display: grid; grid-template-columns: 1.6fr 1fr; gap: 1.2rem; align-items: start; }
@media (max-width: 860px) { .contact-grid { grid-template-columns: 1fr; } }

/* ---------- article ---------- */

.article { max-width: 72ch; margin-inline: auto; }
.article-head { border-block-end: 1px solid var(--line); padding-block-end: 1.2rem; margin-block-end: 1.6rem; }
.article-meta { color: var(--ink-faint); font-size: .88rem; }
.article-body { font-size: 1.05rem; }
.article-body h2 { margin-top: 2rem; }
.article-body h3 { margin-top: 1.5rem; }
.article-body ul, .article-body ol { padding-inline-start: 1.4rem; }
.article-body li { margin-bottom: .4rem; }
.article-body blockquote {
  margin: 1.5rem 0; padding: .8rem 1.2rem;
  border-inline-start: 3px solid var(--gold-500); background: var(--gold-100);
  border-radius: 0;
}

/* ---------- footer ---------- */

.site-footer { background: var(--ink); color: rgba(255,255,255,.72); margin-top: 3rem; }
.site-footer .wrap { padding-block: 2.5rem; }
.foot-grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr; gap: 2rem; }
.site-footer h4 { color: #fff; font-size: .95rem; margin-bottom: .7rem; }
.site-footer a { color: rgba(255,255,255,.72); font-size: .92rem; }
.site-footer a:hover { color: var(--gold-500); }
.foot-links { list-style: none; margin: 0; padding: 0; }
.foot-links li { margin-bottom: .35rem; }
.foot-bottom {
  border-block-start: 1px solid rgba(255,255,255,.1); margin-top: 2rem; padding-top: 1.2rem;
  font-size: .84rem; display: flex; justify-content: space-between; gap: 1rem; flex-wrap: wrap;
}

/* ---------- admin ---------- */

/* ---------- admin shell (sidebar) ---------- */

.admin-body { background: var(--bg-soft); }
.admin-shell { display: grid; grid-template-columns: 244px 1fr; min-height: 100vh; }
.admin-main { padding: 2.2rem clamp(1rem, 3vw, 2.4rem); min-width: 0; }

.admin-side {
  background: var(--ink); color: #fff;
  display: flex; flex-direction: column;
  position: sticky; top: 0; height: 100vh; overflow-y: auto;
}
.as-brand {
  display: flex; align-items: center; gap: .6rem;
  padding: 1.1rem 1.1rem; border-bottom: 1px solid rgba(255,255,255,.08);
  color: #fff; text-decoration: none;
}
.as-brand img { width: 32px; height: 32px; object-fit: contain; }
.as-brand span { font-weight: 700; font-size: .95rem; line-height: 1.25; }
.as-brand small { display: block; font-weight: 400; font-size: .72rem; color: rgba(255,255,255,.5); }

.as-nav { padding: .8rem .6rem; flex: 1; }
.as-head {
  font-size: .68rem; font-weight: 700; letter-spacing: .04em;
  color: rgba(255,255,255,.35); margin: 1rem .55rem .35rem; text-transform: uppercase;
}
.as-nav a {
  display: flex; align-items: center; gap: .6rem;
  padding: .55rem .55rem; margin-bottom: .1rem; border-radius: 8px;
  color: rgba(255,255,255,.72); text-decoration: none; font-size: .9rem;
  transition: background .12s, color .12s;
}
.as-nav a:hover { background: rgba(255,255,255,.06); color: #fff; }
.as-nav a.is-active { background: var(--blue-500); color: #fff; font-weight: 600; }
.as-nav .ic { width: 1.1rem; text-align: center; opacity: .8; font-size: .95rem; }
.as-nav .lb { flex: 1; }
.as-nav .ct {
  background: rgba(255,255,255,.12); color: rgba(255,255,255,.75);
  font-size: .72rem; font-weight: 700; padding: .05rem .4rem; border-radius: 999px;
}
.as-nav a.is-active .ct { background: rgba(0,0,0,.2); color: #fff; }

.as-foot { padding: .9rem 1.1rem 1.2rem; border-top: 1px solid rgba(255,255,255,.08); font-size: .84rem; }
.as-foot > a { color: rgba(255,255,255,.6); text-decoration: none; }
.as-foot > a:hover { color: var(--gold-500); }
.as-user {
  display: flex; align-items: center; gap: .5rem; margin-top: .7rem;
  color: rgba(255,255,255,.45); font-size: .8rem;
}
.as-user span { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.as-user a { color: rgba(255,255,255,.6); }
.as-user a:hover { color: var(--gold-500); }

@media (max-width: 860px) {
  /* 1.6rem of panel padding costs 51.2px, ~12% of a 430px screen, on every side of
     every card. Claw back 19.2px of it: the panels here hold tables and forms that are
     already at their minimum width, so the breathing room is worth less than the
     content it squeezes. */
  .panel { padding: 1.1rem; }
  .admin-shell { grid-template-columns: 1fr; }
  .admin-side { position: static; height: auto; }
  .as-nav { display: flex; flex-wrap: wrap; gap: .2rem; padding: .5rem; }
  .as-head { display: none; }
  .as-nav a { margin: 0; }
  .as-foot { display: flex; align-items: center; gap: 1rem; }
  .as-foot .as-user { margin: 0; }
}

/* ---------- admin: KPIs + leads ---------- */

.kpis { display: grid; grid-template-columns: repeat(4, 1fr); gap: .9rem; }
.kpi {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.1rem 1.2rem; text-decoration: none; display: block;
  box-shadow: var(--shadow-sm); transition: border-color .12s, transform .12s;
}
.kpi:hover { border-color: var(--blue-400); transform: translateY(-1px); }
.kpi b { display: block; font-size: 1.7rem; color: var(--blue-700); line-height: 1.1; }
.kpi span { font-size: .82rem; color: var(--ink-soft); }
@media (max-width: 760px) { .kpis { grid-template-columns: repeat(2, 1fr); } }

.lead { margin-bottom: .9rem; padding: 1.2rem 1.3rem; }
.lead-top { display: flex; align-items: flex-start; gap: 1rem; flex-wrap: wrap; }
.lead-calc { margin-top: .9rem; padding-top: .9rem; border-top: 1px solid var(--line); }
.lead-calc summary {
  cursor: pointer; font-size: .88rem; color: var(--ink-soft);
  padding: .5rem .7rem; background: var(--bg-soft); border-radius: 8px;
}
.lead-calc summary:hover { background: var(--blue-050); }
.lead-calc summary strong { color: var(--ink); }
.lead-calc[open] summary { margin-bottom: .2rem; }

.login-wrap { max-width: 380px; margin: 4rem auto; }
/* Honeypot hiding. Emphatically NOT `position:absolute; left:-9999px`, which is what
   all three forms used and which cost this build 9999px of horizontal scroll (measured:
   scrollWidth 11424 vs clientWidth 1425 on the calculator's step 2).
   Why that idiom fails here: browsers do not create scrollbars for overflow BEHIND the
   scroll origin, and in LTR the origin is at the left, so left:-9999px is harmless --
   which is exactly why the snippet is copied everywhere. This document is dir="rtl".
   In RTL the inline forward direction is leftward, so left:-9999px lands INSIDE the
   scrollable overflow region and the page grows a 9999px horizontal scroll.
   So: clip the box, never displace it. It stays 1px at its natural spot and contributes
   no overflow in any writing mode. display:none and visibility:hidden are not options --
   bots skip those, which would defeat the trap. */
.hp {
  position: absolute; width: 1px; height: 1px;
  margin: -1px; padding: 0; border: 0; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

.panel {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.6rem; box-shadow: var(--shadow-sm);
}

.field { margin-bottom: 1rem; }
.field label { display: block; font-size: .88rem; font-weight: 600; margin-bottom: .35rem; }
.input, .select, .textarea {
  width: 100%; padding: .6rem .75rem; border: 1px solid var(--line);
  border-radius: var(--radius); font-family: inherit; font-size: .95rem;
  background: #fff; color: var(--ink);
}
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--blue-400); box-shadow: 0 0 0 3px var(--blue-100);
}
.textarea { min-height: 220px; line-height: 1.7; resize: vertical; }
.row { display: grid; grid-template-columns: 1fr 1fr; gap: 1rem; }

/* These tables have a hard floor. The date column is white-space:nowrap and phone
   numbers are unbreakable strings, so the overview table measures 427.1px min-content:
   it CANNOT be narrower, no matter the container. `width: 100%` does not save you here
   -- a table still overflows when its intrinsic minimum exceeds the box.
   Measured at 430px (iPhone 14 Pro Max): the shell hands .admin-main 430px, its own
   padding takes 32, the .panel's takes 51.2, leaving 346.8. The table overflows that by
   80.3px, and since nothing establishes a scroll container the overflow escalates to
   the PAGE -- so the entire admin scrolled sideways instead of just the table.
   Give the table its own scroll container. Do not try to shrink the table itself: the
   columns are already at their minimum and squeezing further just wraps phone numbers. */
/* ---- post cards with a featured image ------------------------------------------
   No `left`/`right` anywhere: the image is FIRST in source order, and under dir="rtl"
   the inline start is the right edge, so it lands top-right exactly as asked. Hardcoding
   `right` would break the moment an EN version ships (the lang column already exists). */
.card-media {
  display: grid; grid-template-columns: 116px 1fr; gap: 1rem; align-items: start;
}
.card-media .card-thumb {
  width: 116px; height: 116px;      /* 1:1 */
  object-fit: cover;                /* crop, never squash: admin uploads are any ratio */
  border-radius: 10px; display: block;
  background: var(--bg-soft);       /* holds the square while it loads */
}
.card-media .card-text {
  min-width: 0;                       /* without this a long Arabic word blows the column out */
  /* flex column is load-bearing: the date <span> positions itself with margin-top, which
     only worked because .card was a flex container and blockified its children. Dropping
     the span into a plain div makes it inline again, and vertical margins do nothing on
     inline boxes -- the date would quietly lose its gap. */
  display: flex; flex-direction: column;
}
@media (max-width: 520px) {
  .card-media { grid-template-columns: 84px 1fr; gap: .8rem; }
  .card-media .card-thumb { width: 84px; height: 84px; }
}

/* ---- the post's own image + lede band ---- */
/* Text column FIRST, image column second. Under dir="rtl" the first column is the
   right one, so this puts the words right and the photo left. Achieved by column order
   + source order rather than `direction` or `order`, so the DOM reading order still
   matches what you see. */
.article-lede {
  display: grid; grid-template-columns: 1fr minmax(0, 300px);
  gap: clamp(1.2rem, 3vw, 2rem); align-items: center;
  margin: 1.6rem 0 2rem;
}
/* Image with no lede: one column, pushed to the same side the photo sits on above.
   `end` is writing-mode aware -- under rtl it resolves LEFT, so the image does not
   jump sides just because the lede happens to be empty. */
.article-lede.is-imageonly {
  grid-template-columns: minmax(0, 300px);
  justify-content: end;
}
.article-figure { margin: 0; }
.article-figure img {
  width: 100%; aspect-ratio: 1 / 1;   /* the 1:1 the brief asked for */
  object-fit: cover; display: block;
  border-radius: 14px; border: 1px solid var(--line);
  background: var(--bg-soft);
}
.article-lede-text {
  font-size: 1.05rem; line-height: 1.9; color: var(--ink-soft); min-width: 0;
}
.article-lede-solo {   /* lede with no image: just an opening paragraph, not a layout */
  font-size: 1.05rem; line-height: 1.9; color: var(--ink-soft);
  margin: 1.4rem 0 1.8rem;
}
@media (max-width: 700px) {
  /* Stacking beats a 140px-wide square next to a squeezed column of Arabic. */
  .article-lede { grid-template-columns: 1fr; gap: 1rem; }
  .article-figure img { max-width: 260px; }
}

.table-wrap { overflow-x: auto; -webkit-overflow-scrolling: touch; }

.table { width: 100%; border-collapse: collapse; font-size: .93rem; }
.table th, .table td { padding: .7rem .6rem; border-block-end: 1px solid var(--line); text-align: start; }
.table th { font-weight: 600; color: var(--ink-soft); font-size: .84rem; }
.table tr:hover td { background: var(--blue-050); }

.pill { display: inline-block; padding: .15rem .55rem; border-radius: 999px; font-size: .78rem; font-weight: 600; }
.pill-on  { background: #DFF3E4; color: #14562A; }
.pill-off { background: var(--line); color: var(--ink-soft); }

.alert { padding: .7rem 1rem; border-radius: var(--radius); margin-bottom: 1rem; font-size: .92rem; }
.alert-err { background: #FDE8E8; color: #8A1C1C; border: 1px solid #F5C2C2; }
.alert-ok  { background: #DFF3E4; color: #14562A; border: 1px solid #B7E0C4; }

.demo-note {
  background: var(--gold-100); border: 1px solid var(--gold-600); color: #5C4405;
  padding: .55rem 1rem; font-size: .85rem; text-align: center;
}

/* ---------- responsive ---------- */

@media (max-width: 900px) {
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .foot-grid { grid-template-columns: 1fr 1fr; }
  .panel-motif { display: none; }
  .stats .wrap { grid-template-columns: repeat(2, 1fr); gap: 1.5rem; }
}
@media (max-width: 620px) {
  .grid-3, .grid-2, .row, .foot-grid { grid-template-columns: 1fr; }
  .site-header .wrap { flex-wrap: wrap; min-height: 0; padding-block: .7rem; gap: .6rem; }
  .nav { margin-inline-start: 0; width: 100%; }
  .nav a { padding: .4rem .6rem; font-size: .9rem; }
}

/* ---------- calculator ---------- */

.calc-tile.live { border-style: solid; border-color: var(--blue-100); }

.calc-steps {
  list-style: none; display: flex; gap: .5rem; flex-wrap: wrap;
  margin: 0 0 1.6rem; padding: 0;
}
.calc-steps li {
  display: flex; align-items: center; gap: .5rem;
  font-size: .88rem; color: var(--ink-faint);
  padding: .4rem .9rem .4rem .5rem; border-radius: 999px;
  border: 1px solid var(--line); background: #fff;
}
.calc-steps li span {
  width: 1.5rem; height: 1.5rem; border-radius: 50%;
  display: grid; place-items: center; font-size: .78rem; font-weight: 700;
  background: var(--bg-soft); color: var(--ink-faint);
}
.calc-steps li.on { color: var(--ink); border-color: var(--blue-400); font-weight: 600; }
.calc-steps li.on span { background: var(--blue-500); color: #fff; }
.calc-steps li.done { color: var(--ink-soft); border-color: var(--blue-100); }
.calc-steps li.done span { background: var(--gold-500); color: #3D2E00; }

.calc-grid { display: grid; grid-template-columns: 1.35fr 1fr; gap: 1.2rem; align-items: start; }
@media (max-width: 860px) { .calc-grid { grid-template-columns: 1fr; } }
.calc-aside { background: var(--blue-050); border-color: var(--blue-100); }

/* the gate: a shape where the numbers will be, with no numbers in it */
.calc-locked { background: var(--bg-soft); border-style: dashed; border-color: var(--blue-100); }
.calc-locked .lock { font-size: 1.6rem; text-align: center; margin-bottom: 1rem; opacity: .5; }
.calc-locked .lockrow {
  height: 14px; border-radius: 999px; margin-bottom: .7rem;
  background: linear-gradient(90deg, var(--blue-100), var(--line));
}
.calc-locked .lockrow.short { width: 55%; }

.rnums { display: grid; grid-template-columns: repeat(4, 1fr); gap: .9rem; margin-bottom: 1.2rem; }
@media (max-width: 760px) { .rnums { grid-template-columns: repeat(2, 1fr); } }
.rnum {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.2rem .9rem; text-align: center; box-shadow: var(--shadow-sm);
}
.rnum b { display: block; font-size: 1.75rem; color: var(--blue-700); line-height: 1.1; }
.rnum span { font-size: .8rem; color: var(--ink-soft); display: block; margin-top: .3rem; }
.rnum.accent { background: var(--gold-100); border-color: var(--gold-600); }
.rnum.accent b { color: #5C4405; }
.rnum.accent span { color: #7A5C10; }

.calc-result .table td:first-child { color: var(--ink-soft); }


/* ---------- mobile nav (CSS only, no JS anywhere in this build) ----------
   The nav is 7 items plus a CTA. Before this it was flex-wrap:wrap, which on a
   phone stacked into ragged rows under the logo. The checkbox is the toggle; the
   :checked ~ sibling selectors do the rest, which is why the input must sit
   before both the burger and the nav in the markup. */

.nav-toggle { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.nav-burger { display: none; }

@media (max-width: 1040px) {
  .nav-burger {
    display: flex; flex-direction: column; justify-content: center; gap: 5px;
    margin-inline-start: auto; cursor: pointer; padding: .55rem; border-radius: var(--radius);
    -webkit-tap-highlight-color: transparent;
  }
  .nav-burger:hover { background: var(--blue-050); }
  .nav-burger span {
    display: block; width: 22px; height: 2px; background: var(--ink); border-radius: 2px;
    transition: transform .18s ease, opacity .18s ease;
  }
  .nav {
    display: none; flex-basis: 100%; flex-direction: column; align-items: stretch;
    gap: .1rem; padding-bottom: .9rem; margin-inline-start: 0;
  }
  .nav-toggle:checked ~ .nav { display: flex; }
  .nav a { padding: .75rem .8rem; border-radius: var(--radius); }
  .nav a.cta { text-align: center; margin-top: .5rem; }

  /* burger turns into an X, so the control reads as open/close rather than a menu that moved */
  .nav-toggle:checked ~ .nav-burger span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
  .nav-toggle:checked ~ .nav-burger span:nth-child(2) { opacity: 0; }
  .nav-toggle:checked ~ .nav-burger span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }
}
@media (prefers-reduced-motion: reduce) { .nav-burger span { transition: none; } }

/* ---------- floating WhatsApp ----------
   inset-inline-end, NOT left. dir="rtl" resolves that to the bottom-LEFT corner,
   which is the conventional FAB position mirrored for RTL. It also means the button
   moves itself to the right the day an LTR/English build ships, with no CSS change. */

.wa-fab {
  position: fixed; bottom: 20px; inset-inline-end: 20px; z-index: 60;
  width: 56px; height: 56px; border-radius: 50%;
  background: #25D366; display: grid; place-items: center;
  box-shadow: 0 6px 20px rgba(37,211,102,.42), 0 2px 6px rgba(10,42,61,.12);
  transition: transform .15s ease, box-shadow .15s ease;
}
.wa-fab:hover { transform: scale(1.07); box-shadow: 0 10px 28px rgba(37,211,102,.55), 0 3px 8px rgba(10,42,61,.16); }
.wa-fab:focus-visible { outline: 3px solid var(--gold-500); outline-offset: 3px; }
.wa-fab svg { width: 30px; height: 30px; fill: #fff; display: block; }
.wa-fab .wa-tip {
  position: absolute; inset-inline-end: calc(100% + 12px); top: 50%; transform: translateY(-50%);
  background: var(--ink); color: #fff; font-size: .8rem; font-weight: 600;
  padding: .4rem .7rem; border-radius: 8px; white-space: nowrap;
  opacity: 0; pointer-events: none; transition: opacity .15s ease;
  box-shadow: var(--shadow-md);
}
.wa-fab:hover .wa-tip, .wa-fab:focus-visible .wa-tip { opacity: 1; }
@media (max-width: 560px) {
  .wa-fab { width: 52px; height: 52px; bottom: 16px; inset-inline-end: 16px; }
  .wa-fab .wa-tip { display: none; }
}
@media (prefers-reduced-motion: reduce) {
  .wa-fab { transition: none; }
  .wa-fab:hover { transform: none; }
}

/* ---------- TEMPORARY demo font A/B toggle ----------
   Bottom-inline-START, which resolves to bottom-RIGHT under RTL, i.e. the opposite
   corner from the WhatsApp FAB (bottom-left) so the two never collide. The control
   keeps its own Cairo label so it stays legible whichever face is active. Remove
   this block with the rest of the font-A/B affordance. See views/_font-ab.php. */
.font-ab {
  position: fixed; bottom: 20px; inset-inline-start: 20px; z-index: 60;
  display: inline-flex; align-items: center; gap: .5rem;
  font-family: 'Cairo', system-ui, -apple-system, 'Segoe UI', sans-serif;
  font-size: .85rem; font-weight: 600; color: var(--ink);
  background: rgba(255,255,255,.96); border: 1px solid var(--line);
  padding: .5rem .8rem; border-radius: 999px; cursor: pointer;
  box-shadow: var(--shadow-md); backdrop-filter: saturate(1.4) blur(6px);
  transition: border-color .15s ease;
}
.font-ab:hover { border-color: var(--blue-400); }
.font-ab:focus-visible { outline: 3px solid var(--gold-500); outline-offset: 2px; }
.font-ab-dot { width: .6rem; height: .6rem; border-radius: 50%; background: var(--gold-500); flex-shrink: 0; }
@media (max-width: 560px) { .font-ab { bottom: 16px; font-size: .8rem; padding: .45rem .7rem; } }

/* ---------- social icons ---------- */

.socials { display: flex; gap: .5rem; flex-wrap: wrap; align-items: center; }
.soc {
  width: 34px; height: 34px; border-radius: 9px; display: grid; place-items: center;
  background: rgba(255,255,255,.08); transition: background .15s ease, transform .15s ease;
}
.soc svg { width: 17px; height: 17px; fill: currentColor; display: block; }
.soc:hover { transform: translateY(-2px); }
.socials-foot { margin-top: 1.1rem; }
.socials-foot .soc { color: rgba(255,255,255,.72); }
.socials-foot .soc:hover { color: #fff; }
.socials-foot .soc-facebook:hover  { background: #1877F2; }
.socials-foot .soc-youtube:hover   { background: #FF0000; }
.socials-foot .soc-instagram:hover { background: linear-gradient(45deg,#F58529,#DD2A7B,#8134AF); }
.socials-foot .soc-tiktok:hover    { background: #000; }
.socials-foot .soc-whatsapp:hover  { background: #25D366; }

.socials-lg { margin-top: .5rem; justify-content: center; }
.socials-lg .soc { width: 40px; height: 40px; border-radius: 10px; background: var(--bg-soft); color: var(--ink-soft); }
.socials-lg .soc svg { width: 19px; height: 19px; }
.socials-lg .soc-facebook:hover  { background: #1877F2; color: #fff; }
.socials-lg .soc-youtube:hover   { background: #FF0000; color: #fff; }
.socials-lg .soc-instagram:hover { background: linear-gradient(45deg,#F58529,#DD2A7B,#8134AF); color: #fff; }
.socials-lg .soc-tiktok:hover    { background: #000; color: #fff; }

/* ---------- contact page ---------- */

.reach { display: grid; grid-template-columns: repeat(4, 1fr); gap: 1rem; }
@media (max-width: 900px) { .reach { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 520px) { .reach { grid-template-columns: 1fr; } }
.reach-card {
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.4rem 1.1rem; text-align: center; box-shadow: var(--shadow-sm);
  display: flex; flex-direction: column; align-items: center; gap: .25rem;
  transition: border-color .15s ease, transform .15s ease;
}
a.reach-card:hover { border-color: var(--blue-400); transform: translateY(-2px); text-decoration: none; }
.reach-card .reach-ic {
  width: 44px; height: 44px; border-radius: 12px; display: grid; place-items: center;
  background: var(--blue-050); color: var(--blue-600); font-size: 1.1rem; margin-bottom: .5rem;
}
.reach-card .reach-ic svg { width: 21px; height: 21px; fill: currentColor; }
.reach-card b { color: var(--ink); font-size: .98rem; }
.reach-card a, .reach-card > span { color: var(--blue-700); font-size: .92rem; font-weight: 600; }
.reach-card em { color: var(--ink-faint); font-size: .78rem; font-style: normal; margin-top: .3rem; }
.reach-wa .reach-ic { background: #E7F9EF; color: #25D366; }
.reach-wa:hover { border-color: #25D366; }

/* branch switcher: radios + sibling selectors, no JS.
   The hidden panes are display:none, so their lazy iframes are never fetched and
   the page costs exactly one map request, not three. */
.maptabs { position: relative; }
.maptabs .mbi { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
.maptabs .tabs { display: flex; gap: .5rem; flex-wrap: wrap; margin-bottom: 1rem; }
.maptabs .tab {
  padding: .5rem 1rem; border-radius: 999px; border: 1px solid var(--line);
  background: #fff; color: var(--ink-soft); font-size: .9rem; font-weight: 600; cursor: pointer;
  transition: background .15s ease, color .15s ease, border-color .15s ease;
}
.maptabs .tab:hover { border-color: var(--blue-400); color: var(--ink); }
.maptabs .pane { display: none; }
.maptabs .mbi-1:checked ~ .panes .pane-1,
.maptabs .mbi-2:checked ~ .panes .pane-2,
.maptabs .mbi-3:checked ~ .panes .pane-3 { display: block; }
.maptabs .mbi-1:checked ~ .tabs .tab-1,
.maptabs .mbi-2:checked ~ .tabs .tab-2,
.maptabs .mbi-3:checked ~ .tabs .tab-3 {
  background: var(--blue-500); color: #fff; border-color: var(--blue-500);
}
.pane-in {
  display: grid; grid-template-columns: 320px 1fr; gap: 1.2rem; align-items: stretch;
  background: #fff; border: 1px solid var(--line); border-radius: var(--radius-lg);
  padding: 1.2rem; box-shadow: var(--shadow-sm);
}
@media (max-width: 860px) { .pane-in { grid-template-columns: 1fr; } }
.pane-info h3 { margin: 0 0 .4rem; font-size: 1.05rem; }
.pane-info p { font-size: .92rem; line-height: 1.8; margin: 0 0 1rem; }
.pane-map { min-height: 260px; border-radius: 12px; overflow: hidden; border: 1px solid var(--line); background: var(--bg-soft); }
.pane-map iframe { width: 100%; height: 100%; min-height: 260px; border: 0; display: block; }

/* ---------- about ---------- */

.about-grid { display: grid; grid-template-columns: 1fr 320px; gap: 2rem; align-items: start; }
@media (max-width: 900px) { .about-grid { grid-template-columns: 1fr; } }
.about-grid h2 { margin: 2rem 0 .8rem; }
.about-grid p { line-height: 1.9; color: var(--ink-soft); }
.whyus { display: flex; flex-direction: column; gap: 1rem; margin-top: 1rem; }
.why { display: flex; gap: .9rem; align-items: flex-start; }
.why-mark {
  flex-shrink: 0; width: 30px; height: 30px; border-radius: 50%;
  background: var(--gold-500); color: #3D2E00; font-weight: 700; font-size: .85rem;
  display: grid; place-items: center; margin-top: .15rem;
}
.why h3 { margin: 0 0 .25rem; font-size: 1rem; }
.why p { margin: 0; font-size: .92rem; }
.ministat { display: flex; align-items: baseline; gap: .6rem; padding: .5rem 0; border-bottom: 1px solid var(--line); }
.ministat:last-child { border-bottom: 0; }
.ministat b { font-size: 1.35rem; color: var(--blue-700); min-width: 62px; }
.ministat span { font-size: .86rem; color: var(--ink-soft); }


/* ---------- depth, rhythm, motion ----------
   The complaint was that the page reads as flat slabs stacked on each other. The fix
   is not dividers, which would date it: it is overlap, real shadow, and rhythm. */

/* the stats bar climbs onto the hero instead of being one more full-width slab */
/* The navy is meant to reach the stats card's MIDLINE.
   That reduces to one equation: we want heroBottom = cardTop + h/2, and cardTop is
   heroBottom + marginTop, so marginTop = -h/2. Nothing else in the box model affects
   the RATIO. The hero's padding only decides whether the navy grows downward or the
   card climbs upward to meet it, and since the ask was to stretch the navy, .hero-big
   gains the delta as padding so the card itself does not move.
   Measured live at 4 columns: card 119.5px -> half 59.8px -> 3.74rem. */
.stats-lift {
  position: relative; z-index: 3; margin-top: -3.74rem;
  background: transparent; padding-block: 0;
}
/* 18.2px: the difference between the old 41.6px overlap and the 59.8px half. Scoped to
   .hero-big because .stats-lift only ever appears on the home page. */
.hero-big { padding-bottom: 1.14rem; }
.stats-lift .wrap {
  background: var(--ink);
  border-radius: var(--radius-lg);
  box-shadow: 0 20px 50px rgba(4,26,42,.30);
  padding-block: 1.6rem;
}
/* Keyed to 900px, NOT 620px, because 900 is where `.stats .wrap` drops to 2 columns and
   the card nearly doubles: 119.5px -> 211.8px measured, so half is 105.9px not 59.8px.
   The rule this replaces keyed off 620px and so never lined up with the grid change --
   between 620 and 900 the card was 211.8px tall while still overlapping by only the
   desktop 41.6px, under 20% of it. One fixed value cannot serve both column counts. */
@media (max-width: 900px) {
  .stats-lift { margin-top: -6.62rem; }
  .hero-big   { padding-bottom: 4.02rem; }
}

.card { transition: transform .18s ease, box-shadow .18s ease, border-color .18s ease; }
.card:hover { transform: translateY(-3px); box-shadow: var(--shadow-md); border-color: var(--blue-100); }

/* ---------- reveal on scroll ----------
   CSS only, because this build has no JavaScript.

   THE TRAP: animation-timeline is Chrome/Edge and Safari 26+. Written naively, the
   opacity:0 start state applies everywhere while the animation only runs where it is
   supported, so Firefox and older Safari would render a page of INVISIBLE content.
   The @supports gate means the hidden state only ever exists where something can undo
   it. Everywhere else the content is simply visible, which is the correct fallback. */

@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .reveal, .reveal-group > * {
      animation: reveal-in linear both;
      animation-timeline: view();
      animation-range: entry 0% cover 26%;
    }
    /* a slight stagger reads as considered rather than mechanical */
    .reveal-group > *:nth-child(2) { animation-range: entry 0% cover 30%; }
    .reveal-group > *:nth-child(3) { animation-range: entry 0% cover 34%; }
    .reveal-group > *:nth-child(4) { animation-range: entry 0% cover 30%; }
    .reveal-group > *:nth-child(5) { animation-range: entry 0% cover 34%; }
    .reveal-group > *:nth-child(6) { animation-range: entry 0% cover 38%; }
  }
}
@keyframes reveal-in {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
