/* ===========================================================
   Astamangala Enterprises — global styles
   Tokens, reset, and cross-section primitives (buttons, .a-wrap, .eyebrow,
   the knot mark) shared by more than one section. Section-specific rules
   live in css/sections/*.css — see index.html for load order.
   =========================================================== */

:root {
  /* Palette B — docs/palette.md, hex pinned from the real logo file (assets/logo/astamangala-logo.svg) */
  --ink: #1B1B1B;
  --bg: #FAF7F2;
  --ink-deep: #141414;
  --terracotta: #A14139;
  --terracotta-hover: #86362f;
  /* Darkened from the original #8A8175 (2026-08-03 audit) - the original sat at
     ~3.6:1 against --bg, failing WCAG AA 4.5:1 for non-large text despite being used
     for form notes/hints/captions sitewide. This value hits ~4.5:1 in the same warm-
     grey hue (same R:G:B ratio), so it reads as the same color, just legible. */
  --muted: #797166;

  /* Type — docs/type-system.md. Display swapped Cabinet Grotesk -> Geist per client
     direction (2026-07-30); body stays General Sans. See docs/type-system.md decision log. */
  --font-display: 'Geist', 'General Sans', system-ui, sans-serif;
  --font-body: 'General Sans', system-ui, sans-serif;

  --h1: clamp(2.75rem, 2.1rem + 2.8vw, 4.75rem);
  --h2: clamp(2rem, 1.65rem + 1.6vw, 3.25rem);
  --h3: clamp(1.375rem, 1.2rem + 0.8vw, 1.75rem);
  /* Flat 1rem (= 16px at the root size set on `html` below), not a clamp.
     This used to be clamp(1rem, 0.95rem + 0.2vw, 1.125rem), i.e. 16px on a
     phone growing to 18px on a wide desktop. Pinned to 16px per client
     direction (2026-09-17). Kept as the token rather than hard-coding 1rem on
     `body` alone, because everything that sets `font-size: var(--body)`
     explicitly — modal copy, form inputs, the contact drawer's values —
     would otherwise still ride the old 18px ceiling and out-size the body
     text they sit next to. */
  --body: 1rem;
  --small: clamp(0.8125rem, 0.8rem + 0.05vw, 0.875rem);
  --eyebrow: clamp(0.75rem, 0.73rem + 0.05vw, 0.8125rem);
  --btn-size: clamp(0.9375rem, 0.92rem + 0.05vw, 1rem);

  /* Shape system — soft geometry for buttons and panels */
  --radius: 0.25rem;
  --radius-pill: 1rem;
  /* Card-level radius - tokenizes the rounded treatment Why Us already established
     (14px cards / 12px icon boxes), so Services and Commitment's cards can match it
     instead of the sharper --radius used for buttons/inputs/modals. */
  --radius-card: 0.875rem;
  --radius-card-icon: 0.75rem;

  --wrap: 100rem;
  --gap: 1.5rem;

  /* Section rhythm — shared by every content section (About, Services,
     Industries, Why Us, Commitment, the footer's CTA band and info grid) so
     top/bottom whitespace and the gap under a section's title read the same
     everywhere on the page, instead of each section inventing its own clamp(). */
  --section-pad-block: clamp(3rem, 6vw, 5rem);
  --section-header-gap: clamp(2.5rem, 5vw, 3.75rem);
}

/* ---------- Reset ---------- */
*, *::before, *::after { box-sizing: border-box; }
/* 100%, not a hard `16px`: it resolves to exactly 16px in every browser's
   default, which is what makes `1rem` mean 16px throughout — but it still
   scales with a reader who has raised their browser's default font size,
   which a pixel value would silently override. Swap it for `16px` only if
   that override is actually wanted. */
html { scroll-behavior: smooth; font-size: 100%; }
/* `html` prefix (not just `body`/`h1`/`p`) is load-bearing, not decoration: the
   block editor iframe injects its own default-typography stylesheet (bare
   body/p/h1-h6 selectors, same (0,0,1) specificity as ours, loaded after ours)
   for themes with no theme.json. Tied specificity means the later rule wins,
   so without this prefix the editor canvas silently falls back to WP's system
   font stack instead of ours. `html body`/`html h1` etc. are (0,0,2), which
   wins regardless of load order — and is a no-op on the frontend, which has
   the same `<html>` ancestor. */
html body {
  margin: 0;
  background: var(--bg);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: var(--body);
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  /* min-height + flex column so a page shorter than the viewport (e.g.
     /order-history/, a card and a table with no full-bleed hero above it)
     doesn't leave the footer floating mid-page. #main soaking up the extra
     space is what pins the footer to the bottom; a no-op on every taller
     section-stacked page like the homepage. */
  min-height: 100vh;
  display: flex;
  flex-direction: column;
}
#main { flex: 1 0 auto; }
img { max-width: 100%; display: block; }
/* Guards the native `hidden` attribute against later `display:` rules on the same
   element (e.g. `.about-grid{display:grid}`) — needed by the variant-swap pattern used
   for About/Services, where inactive variants are `hidden` rather than deleted. */
[hidden] { display: none !important; }
ul { list-style: none; margin: 0; padding: 0; }
a { color: inherit; text-decoration: none; }
html h1, html h2, html h3 { font-family: var(--font-display); font-weight: 600; margin: 0 0 0.5em; color: inherit; }
html p { margin: 0 0 1em; max-width: 68ch; }
button { font-family: inherit; cursor: pointer; }

/* Shared eyebrow utility — rationed per docs/section-layouts.md (max ~1 per 3 sections). */
.eyebrow {
  font-size: var(--eyebrow);
  font-weight: 600;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 0.75em;
}

/* Named `.a-wrap`, not `.wrap` — WordPress admin's own common.css defines a
   `.wrap` class for its page-wrapper convention, and that stylesheet loads
   inside the block-editor iframe. A bare `.wrap` here would collide with it
   (same specificity, admin's rule wins ties), silently distorting section
   width/padding and even h1 font-weight in the canvas — this happened, see
   git history. */
.a-wrap {
  max-width: var(--wrap);
  margin-inline: auto;
  padding-inline: clamp(0.75rem, 2vw, 1.5rem);
}

/* ---------- Prose page shell (.asta-prose) ----------
   For a page built out of CORE blocks — paragraphs, headings, lists — on the
   "Astamangala Landing" template: Terms, Privacy, and any other page that is
   continuous copy rather than designed sections.

   page-astamangala.php puts the_content() straight inside <main> with no
   wrapper, deliberately, because every other page is built from full-bleed
   section blocks that carry their own .a-wrap. Core blocks carry nothing, so
   without this they run edge-to-edge and start underneath the fixed header.

   It also has to undo three resets above that are right for designed sections
   and wrong for body copy: `ul {list-style:none}` (no bullets), `a
   {color:inherit;text-decoration:none}` (links indistinguishable from the
   text around them), and the fact that h1-h3 are given a family and weight
   but no size, so on a page with no section CSS they fall back to the
   browser's defaults instead of the --h1/--h2/--h3 scale. */
.asta-prose {
  /* 70ch, NOT var(--wrap): that is 100rem, right for the navbar and the order
     table, unreadable for continuous prose. This sits just above the 68ch
     that `html p` already caps paragraphs at, so headings, lists and
     paragraphs all share one measure instead of paragraphs ending short. */
  max-width: 70ch;
  margin-inline: auto;
  padding-inline: clamp(1rem, 4vw, 1.5rem);
  /* Same clearance .order-history-page uses, for the same reason: no
     full-bleed hero above to push content clear of the fixed .site-header. */
  padding-top: clamp(7rem, 14vw, 9rem);
  padding-bottom: clamp(3rem, 6vw, 5rem);
}
.asta-prose h1 { font-size: var(--h2); margin-bottom: 0.75em; }
/* Generous margin-top, small margin-bottom: a heading belongs to the text
   below it, and the numbered clauses here are long enough that the gap is the
   main cue for where one ends and the next begins. */
.asta-prose h2 { font-size: var(--h3); margin-top: 2.25em; margin-bottom: 0.6em; }
.asta-prose h3 { font-size: 1.05rem; margin-top: 1.75em; margin-bottom: 0.5em; }
.asta-prose > :first-child { margin-top: 0; }
.asta-prose p { max-width: none; }
.asta-prose ul { list-style: disc; }
.asta-prose ol { list-style: decimal; }
.asta-prose ul,
.asta-prose ol {
  margin: 0 0 1.25em;
  padding-left: 1.5em;
}
.asta-prose li { margin-bottom: 0.5em; }
.asta-prose li::marker { color: var(--muted); }
.asta-prose a {
  color: var(--terracotta);
  text-decoration: underline;
  text-underline-offset: 0.15em;
}
.asta-prose a:hover { color: var(--terracotta-hover); }
.asta-prose strong { font-weight: 600; }
/* Sets the date/version line apart from the clause text without a heading. */
.asta-prose .prose-meta {
  font-size: var(--small);
  color: var(--muted);
  margin-bottom: 2.5em;
}

.skip-link {
  position: absolute;
  left: -999px;
  top: 0;
  background: var(--ink);
  color: var(--bg);
  padding: 0.75em 1.25em;
  z-index: 200;
}
.skip-link:focus { left: 1rem; top: 1rem; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  border: 1px solid transparent;
  border-radius: var(--radius);
  padding: 0.85em 1.6em;
  font-size: var(--btn-size);
  font-family: var(--font-body);
  font-weight: 500;
  line-height: 1;
  letter-spacing: 0.01em;
  white-space: nowrap;
  transition: transform 0.15s ease, background 0.2s ease, border-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
}
.btn:active { transform: scale(0.98); }
.btn-primary {
  background: var(--terracotta);
  color: #fff;
  border-color: transparent;
  border-radius: var(--radius);
}
.btn-primary:hover {
  background: var(--terracotta-hover);
  color: #fff;
  border-color: transparent;
}
.btn-ghost { background: transparent; color: var(--ink); border-color: var(--ink); }
.btn-ghost:hover { background: var(--ink); color: var(--bg); }
.btn-ghost--on-dark { color: #fff; border-color: rgba(255,255,255,0.65); }
.btn-ghost--on-dark:hover { background: #fff; color: var(--ink); }
.btn-outline { background: transparent; color: var(--terracotta); border-color: var(--terracotta); }
.btn-outline:hover { background: var(--terracotta); color: #fff; }
/* Secondary: filled dark button (image 2) */
.btn-secondary {
  background: rgba(20,20,20,0.85);
  color: #fff;
  border: 1px solid transparent;
  border-radius: var(--radius);
}
.btn-secondary:hover { background: rgba(20,20,20,0.95); }
/* Link-style button: text-only with hover arrow (image 3) */
.btn-link {
  background: transparent;
  color: var(--ink);
  border: none;
  padding: 0;
  gap: 0.5rem;
}
.btn-link:hover { color: var(--terracotta); }
/* On-dark variant - the base .btn-link assumes ink text on a light ground; this one
   is for link-style buttons sitting on the footer showcase's dark scrim/photo. */
.btn-link--on-dark { color: rgba(255, 255, 255, 0.85); text-decoration: underline; text-underline-offset: 0.25em; }
.btn-link--on-dark:hover { color: #fff; }
.btn-block { width: 100%; }

/* Loading state — toggled from JS while a button's own fetch is in flight
   (currently the auth-modal's login/register/forgot submits, chrome.js).
   The spinner is a ::before pseudo-element, so it drops into the existing
   flex layout as an extra item ahead of the button's text with no markup
   change; `currentColor` picks up whatever text color the button variant
   already uses. */
.btn.is-loading {
  opacity: 0.75;
  cursor: default;
}
.btn.is-loading::before {
  content: "";
  width: 1em;
  height: 1em;
  flex-shrink: 0;
  border: 2px solid currentColor;
  border-right-color: transparent;
  border-radius: 50%;
  animation: asta-btn-spin 0.6s linear infinite;
}
@keyframes asta-btn-spin {
  to { transform: rotate(360deg); }
}

/* Phosphor arrow icon riding inside a .btn — rendered inline (not a hover-only
   pseudo-element) so the flex `gap` never reserves invisible space when there's
   no arrow markup in a given button. */
.btn-arrow {
  display: inline-flex;
  font-size: 0.95em;
  transition: transform 0.18s ease;
}
.btn:hover .btn-arrow { transform: translateX(0.2em); }

/* ---------- Shared dark-section "commitment" pattern ---------- */
/* Used by both About's split variant and the Commitment section — same
   centered-quote-on-dark composition, kept here (not in either section's own
   CSS file) so it isn't silently missing when one of the two files isn't loaded. */
.commitment-inner {
  display: grid;
  gap: clamp(1.5rem, 3vw, 2.5rem);
  max-width: 90rem; /* 1440px */
  margin-inline: auto;
}
.commitment-center {
  display: grid;
  justify-items: center;
  gap: 1.5rem;
  padding: 1.5rem 0 0;
}
.commitment-quote {
  font-family: var(--font-display);
  font-size: clamp(1.35rem, 1.9vw, 2.1rem);
  line-height: 1.25;
  max-width: 51ch;
  margin: 0;
  color: var(--bg);
}
.commitment-text {
  margin: 0 auto;
  max-width: 72ch;
  color: color-mix(in srgb, var(--bg) 80%, transparent);
  line-height: 1.75;
}
@media (max-width: 720px) {
  .commitment-quote { font-size: clamp(1.5rem, 2.8vw, 2rem); }
}

/* ---------- Knot mark ---------- */
/* Inline SVG of just the knot mark's own paths (not a cropped <img> of the full
   logo file), so the highlight sub-paths can be recolored per section — see
   .knot-highlight below. Shared by About and Commitment (both var(--ink-deep) grounds). */
.knot-crop {
  display: block;
  width: 53px;
  height: 64px;
  margin-inline: auto;
}
.knot-crop svg { width: 100%; height: 100%; }
/* The original logo file uses white/near-white fills for the knot's internal
   negative-space highlights, tuned to sit on a white ground. On these dark
   sections that showed up as a stray light patch — recolor to match the
   section's own background instead, the same way it "disappears" on white. */
.knot-highlight { fill: var(--ink-deep); }

/* The scroll-reveal JS bails out entirely under reduced motion (see
   initScrollReveal in chrome.js), so nothing here needs to undo it. What this
   block covers is the transitions CSS applies unconditionally: buttons, the
   drawers, and the hover/zoom effects on the two photo grids. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .btn, .mobile-nav, .modal, .modal-scrim { transition: none; }
  .btn.is-loading::before { animation: none; }
  /* Was .service-row-hover/.service-row-media/.service-row-marker until the
     Services redesign removed the hover rows; these are the elements that
     actually animate now. */
  .service-card, .service-group-media img { transition: none; }
  .industry-card, .industry-card img { transition: none; }
  .why-card, .commitment-box { transition: none; }
}
