/* ═══════════════════════════════════════════════════════════════════════
   Vedic Horā वैदिक होरा — the twenty AI guides (/astrologers).

   Optical-glass material and the existing tokens from public/styles.css only.
   No new colour system, no new type scale, no external font, no image file:
   the identity mark on every card is inline SVG generated from the persona id,
   because the policy is script-src 'self' + nonce with no external origins.

   Three rules this sheet is written to keep:
     • Polarity is colour + SHAPE + label, never colour alone. The measured
       deutan ΔE between --good and --bad is 0.8, so the disc / slashed ring /
       hollow ring glyph and the word beside it carry the meaning on their own.
     • Every interactive target is at least 44×44 CSS px, including the filter
       chips, which are the smallest things on the page.
     • Wide content scrolls inside its own box. The PAGE never scrolls sideways
       at 390 px — the engine list is a definition list rather than a table for
       exactly that reason.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── The AI disclosure ─────────────────────────────────────────────────
   Not a footnote. It is the first block under the hero on the listing and it
   sits inside the header of every profile, because a persona that does not
   say what it is would break the one claim this product sells. */
.ast-disclose { padding: 26px 28px 24px; margin-bottom: 0; }
.ast-disclose-h {
  margin: 0 0 14px; font-size: 1.02rem; font-weight: 600; color: var(--ink);
}
.ast-disclose p.ast-d {
  margin: 0 0 13px; color: var(--ink-soft); font-size: .92rem; line-height: 1.72;
}
.ast-disclose p.ast-d:last-of-type { margin-bottom: 0; }
.ast-fine {
  margin: 16px 0 0; padding-top: 14px; font-size: .8rem; line-height: 1.62;
  color: var(--ink-soft); border-top: 1px solid rgba(120,150,200,.2);
}

/* ── The AI badge ──────────────────────────────────────────────────────
   On every card and at the top of every profile. Shape (the bracketed pill)
   plus the word; it never relies on colour to be understood. */
.ast-badge {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 11px; border-radius: 999px;
  font-size: .68rem; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  color: var(--ink-soft); white-space: nowrap;
  border: 1px solid rgba(120,150,200,.42);
  background: rgba(255,255,255,.46);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9);
}
.ast-badge::before {
  content: ""; width: 8px; height: 8px; flex: none; border-radius: 2px;
  border: 1.6px solid currentColor;
}
.ast-badge-line {
  margin: 12px 0 0; color: var(--ink-soft); font-size: .84rem; line-height: 1.6;
}

/* ── Filters ───────────────────────────────────────────────────────────
   Plain links, resolved on the server. The page therefore works with no
   JavaScript at all and every filtered view is a real, linkable URL. */
.ast-filters { margin: 0 0 30px; }
.ast-frow {
  display: flex; flex-wrap: wrap; align-items: center; gap: 9px; margin-bottom: 12px;
}
.ast-flabel {
  flex: none; min-width: 96px;
  font-size: .72rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-soft);
}
.ast-chip {
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 10px 18px; border-radius: 999px;
  font-size: .88rem; font-weight: 600; text-decoration: none; color: var(--ink-soft);
  border: 1px solid rgba(255,255,255,.6);
  background: rgba(255,255,255,.34);
  box-shadow: inset 0 1px 0 rgba(255,255,255,.9);
  transition: background .2s ease, color .2s ease, border-color .2s ease;
}
.ast-chip:hover { color: var(--ink); background: rgba(255,255,255,.55); }
.ast-chip.current {
  color: var(--ink); background: rgba(255,255,255,.68);
  border-color: rgba(255,255,255,.98);
  box-shadow: inset 0 1px 0 rgba(255,255,255,1), 0 1px 8px rgba(40,60,95,.10);
}
.ast-chip .ast-n {
  font-size: .74rem; font-weight: 650; color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.ast-chip.current .ast-n { color: var(--ink-soft); }
.ast-chip[aria-disabled="true"] { opacity: .45; pointer-events: none; }
.ast-count {
  margin: 4px 0 0; color: var(--ink-soft); font-size: .82rem;
  font-variant-numeric: tabular-nums;
}
.ast-filter-note {
  margin: 10px 0 0; color: var(--ink-soft); font-size: .8rem; line-height: 1.62;
  max-width: 74ch;
}

/* ── The roster grid ───────────────────────────────────────────────────*/
.ast-grid {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(288px, 1fr)); gap: 20px;
}
/* The card is an <article>, not a link. Only its heading is a link, and the
   stretched-link rule below puts that link's hit area over the whole card — so
   the affordance is identical while the accessible name stays short and the
   roster keeps a real heading outline. */
.ast-card {
  position: relative;
  display: flex; flex-direction: column; gap: 0;
  padding: 24px 24px 20px; margin-bottom: 0;
  color: inherit;
  transition: transform .32s cubic-bezier(.22,1,.36,1);
}
.ast-card:hover { transform: translateY(-3px); }
.ast-card-top { display: flex; align-items: flex-start; gap: 15px; margin-bottom: 15px; }
.ast-mark-sm { width: 62px; height: 62px; flex: none; }
.ast-card-id { min-width: 0; }
.ast-name {
  display: block; margin: 0;
  font-size: 1.06rem; font-weight: 600; color: var(--ink); line-height: 1.28;
}
.ast-card-link { color: inherit; text-decoration: none; }
/* The overlay's containing block must be the CARD, so every wrapper between
   the link and the card has to be unpositioned. styles.css:221 positions all
   of them — `.glass > * { position: relative; z-index: 1 }` — and that rule
   exists only to lift content above the `.glass::before` specular sheen, which
   is positioned with z-index auto. Dropping the sheen behind the content
   instead (the way `.glass::after`, the bevel, already sits at z-index -1)
   achieves the same thing and leaves the children static. Same look, and the
   sheen keeps `pointer-events: none` either way.

   `z-index: auto` matters as much as `position: static` here: .ast-card is a
   flex container, and per the Flexbox spec z-index applies to a flex ITEM even
   when it is statically positioned. Leaving z-index:1 on the three rows put
   them in the same paint layer as the overlay and later in DOM order, so the
   card's middle stayed unclickable while its corners worked. */
.ast-card::before { z-index: -1; }
.ast-card > * { position: static; z-index: auto; }
/* Now the hit area is the whole card, not the six words of a name —
   comfortably past 44px in both axes at every breakpoint. */
.ast-card-link::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.ast-card:has(.ast-card-link:focus-visible) {
  outline: 2px solid var(--accent); outline-offset: 3px;
}
/* Fallback for engines without :has() — the ring lands on the name instead of
   the card, which is still a visible, correctly-placed focus indicator. */
.ast-card-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }
/* Visually hidden, still announced. Carries the guide's subject into the link
   name so "Ācārya Bāla" is not the whole of what a screen reader hears. */
.ast-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}
.ast-name-dev { display: block; font-size: .86rem; font-weight: 500; color: var(--ink-soft); margin-top: 3px; }
.ast-spec {
  display: block; margin-top: 9px;
  font-size: .72rem; font-weight: 650; letter-spacing: .06em; text-transform: uppercase;
  color: var(--ink-soft);
}
.ast-label { margin: 15px 0 9px; font-size: .95rem; font-weight: 600; color: var(--ink); line-height: 1.5; }
.ast-blurb { margin: 0 0 15px; color: var(--ink-soft); font-size: .875rem; line-height: 1.68; }
.ast-card-foot { margin-top: auto; padding-top: 14px; border-top: 1px solid rgba(120,150,200,.18); }
.ast-leans { margin: 0 0 12px; font-size: .76rem; line-height: 1.62; color: var(--ink-soft); }
.ast-leans b { color: var(--ink-soft); font-weight: 650; }
/* Each title now carries its Devanāgarī, like the profile — which roughly
   doubles the length of this line. It must therefore wrap freely: a
   `white-space: nowrap` here would put a ~50-character title inside a 240px
   card body and push the whole page sideways at 390px. */
.ast-leans { overflow-wrap: anywhere; }
.ast-leans-t .dev { font-weight: 500; opacity: .82; }
.ast-go {
  display: inline-flex; align-items: center; gap: 8px; min-height: 24px;
  font-size: .84rem; font-weight: 650;
  /* --accent alone measures 4.15:1 on the darkest part of the chamber
     gradient. Pulled 16% toward --ink it reaches 5.0:1 and still reads as
     the same blue. */
  color: color-mix(in srgb, var(--accent) 84%, var(--ink));
}
.ast-arrow { transition: transform .28s cubic-bezier(.22,1,.36,1); }
.ast-card:hover .ast-arrow { transform: translateX(4px); }

/* ── Empty state ───────────────────────────────────────────────────────*/
.ast-empty { padding: 32px 30px; text-align: center; margin-bottom: 0; }
.ast-empty h2 { margin: 0 0 10px; font-size: 1.1rem; color: var(--ink); }
.ast-empty p { margin: 0 auto 20px; max-width: 56ch; color: var(--ink-soft); font-size: .9rem; line-height: 1.68; }

/* ── The identity mark ─────────────────────────────────────────────────
   Abstract geometry drawn from the persona id: rings, a petal band, a polygon
   and a bindu. There is no face here and there is no photograph anywhere on
   these pages — that is a product constraint, not a stylistic one. */
.yantra { display: block; width: 100%; height: 100%; overflow: visible; }
.yantra .y-ring { fill: none; stroke: var(--ink-faint); stroke-width: 1; opacity: .5; }
.yantra .y-ring-2 { stroke-width: .65; opacity: .3; }
.yantra .y-petal {
  fill: rgba(61,108,200,.075); stroke: var(--accent); stroke-width: .9; opacity: .52;
  stroke-linejoin: round;
}
.yantra .y-dot { fill: var(--ink-faint); opacity: .5; }
.yantra .y-poly {
  fill: none; stroke: var(--ink-soft); stroke-width: 1.05; opacity: .58;
  stroke-linejoin: round;
}
.yantra .y-poly-2 { opacity: .34; }
.yantra .y-bindu { fill: var(--gold); opacity: .85; }

/* ── Profile ───────────────────────────────────────────────────────────*/
.ast-head { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 28px; margin: 6px 0 40px; }
.ast-mark-lg { width: 132px; height: 132px; flex: none; }
.ast-head-text { flex: 1 1 340px; min-width: 0; }
.ast-head h1 { font-size: clamp(1.75rem, 4vw, 2.5rem); margin: 0 0 6px; line-height: 1.15; }
.ast-head h1 .dev { display: block; font-size: .62em; font-weight: 500; color: var(--ink-soft); margin-top: 6px; }
.ast-head-meta { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 16px 0 0; }
.ast-head-label { margin: 16px 0 0; font-size: 1.02rem; color: var(--ink); line-height: 1.6; max-width: 64ch; }

.ast-sec { margin-bottom: 58px; }
.ast-sec h2 { font-size: clamp(1.25rem, 2.6vw, 1.6rem); margin: 0 0 14px; line-height: 1.24; }
.ast-sec > p { color: var(--ink-soft); max-width: 74ch; line-height: 1.72; margin: 0 0 22px; }
.ast-sec > p:last-child { margin-bottom: 0; }

/* Quoted opening line. A fixed greeting, so it is set as a quotation and
   labelled as one — it must never read as a reading of anybody's chart. */
.ast-quote { padding: 24px 26px; margin-bottom: 0; }
.ast-quote blockquote {
  margin: 0; font-size: 1.02rem; line-height: 1.74; color: var(--ink);
  border-left: 2px solid rgba(120,150,200,.4); padding-left: 18px;
}
.ast-quote figcaption { margin: 14px 0 0; font-size: .78rem; color: var(--ink-soft); line-height: 1.6; }

/* Texts and engines: definition lists, so they reflow at 390 px instead of
   forcing the page sideways the way a table would. */
.ast-list { list-style: none; margin: 0; padding: 0; display: grid; gap: 14px; }
.ast-item { padding: 18px 22px; margin-bottom: 0; }
.ast-item-h { margin: 0 0 6px; font-size: .97rem; font-weight: 600; color: var(--ink); line-height: 1.44; }
.ast-item-h .dev { color: var(--ink-soft); font-weight: 500; font-size: .92em; }
.ast-item-b { margin: 0; color: var(--ink-soft); font-size: .875rem; line-height: 1.7; }
.ast-item-top { display: flex; flex-wrap: wrap; align-items: baseline; gap: 10px; margin-bottom: 7px; }
.ast-tool-name {
  font-family: ui-monospace, "Cascadia Mono", "Segoe UI Mono", Consolas, monospace;
  font-size: .8rem; color: var(--ink); font-weight: 600;
  padding: 3px 8px; border-radius: 7px;
  background: rgba(255,255,255,.5); border: 1px solid rgba(120,150,200,.26);
  overflow-wrap: anywhere;
}
.ast-tool-arg { font-size: .78rem; color: var(--ink-soft); }

/* Where a refusal is actually enforced. The meaning is carried entirely by the
   words — the left rule is decoration, and a reader who sees no colour at all
   loses nothing, which is the same rule the polarity marks below follow. */
.ast-enforce {
  margin: 12px 0 0; padding: 8px 0 0 12px;
  border-left: 3px solid rgba(120,150,200,.4);
  font-size: .78rem; line-height: 1.62; color: var(--ink-soft);
}
.ast-enforce b { color: var(--ink); font-weight: 650; }
.ast-enforce-gate, .ast-enforce-verifier { border-left-color: color-mix(in srgb, var(--accent) 62%, transparent); }
.ast-enforce-guide, .ast-enforce-mixed { border-left-style: dashed; }

/* ── Polarity marks: colour + SHAPE + label ────────────────────────────*/
.ast-mark {
  display: inline-flex; align-items: center; gap: 7px; flex: none;
  font-size: .7rem; font-weight: 700; letter-spacing: .07em; text-transform: uppercase;
  white-space: nowrap;
}
.ast-mark::before { content: ""; width: 10px; height: 10px; border-radius: 50%; flex: none; }
/* filled disc — the guide reads this */
.ast-mark.yes { color: color-mix(in srgb, var(--good) 74%, var(--ink)); }
.ast-mark.yes::before { background: currentColor; }
/* slashed ring — withheld, refused */
.ast-mark.no { color: color-mix(in srgb, var(--bad) 78%, var(--ink)); }
.ast-mark.no::before {
  border: 1.6px solid currentColor;
  background: linear-gradient(135deg, transparent 43%, currentColor 43% 57%, transparent 57%);
}
/* hollow ring — neutral: real, but not built yet */
.ast-mark.wait { color: var(--ink-soft); }
.ast-mark.wait::before { border: 1.6px solid currentColor; background: none; }

.ast-sub { margin: 36px 0 14px; font-size: 1rem; font-weight: 600; color: var(--ink); }

/* ── Refusals ──────────────────────────────────────────────────────────*/
.ast-refusal { padding: 18px 22px; margin-bottom: 0; }
.ast-refusal .ast-item-top { margin-bottom: 8px; }
.ast-refusal .ast-item-h { margin: 0; }

/* ── The consultation entry point, disabled ────────────────────────────
   A button that looked live but did nothing would be its own small lie, so
   the disabled state is loud and the sentence beside it is plain. */
.ast-consult { padding: 28px 30px; margin-bottom: 0; }
.ast-consult-row { display: flex; flex-wrap: wrap; align-items: center; gap: 14px; }
.ast-btn-off {
  display: inline-flex; align-items: center; gap: 10px;
  min-height: 48px; padding: 14px 26px; border-radius: 17px;
  font-size: .96rem; font-weight: 600; font-family: inherit;
  color: var(--ink-soft);
  border: 1px dashed rgba(120,150,200,.55);
  background: rgba(255,255,255,.22);
  cursor: not-allowed;
}
.ast-consult-note { margin: 18px 0 0; color: var(--ink-soft); font-size: .89rem; line-height: 1.72; max-width: 72ch; }
.ast-consult-then { margin: 22px 0 0; padding-top: 20px; border-top: 1px solid rgba(120,150,200,.2); }
.ast-consult-then h3 { margin: 0 0 8px; font-size: .98rem; color: var(--ink); }
.ast-consult-then p { margin: 0 0 20px; color: var(--ink-soft); font-size: .89rem; line-height: 1.72; max-width: 72ch; }
.ast-actions { display: flex; flex-wrap: wrap; gap: 12px; }
.ast-actions.centred { justify-content: center; }
.ast-flow-lede { margin-bottom: 22px; }

/* ── "One engine, twenty voices" ───────────────────────────────────────*/
.ast-flow { list-style: none; counter-reset: astflow; margin: 0; padding: 0; display: grid; gap: 14px; }
.ast-flow li {
  counter-increment: astflow;
  display: flex; align-items: flex-start; gap: 15px;
  padding: 18px 22px; margin-bottom: 0;
  color: var(--ink-soft); font-size: .89rem; line-height: 1.72;
}
.ast-flow li::before {
  content: counter(astflow);
  flex: none; width: 26px; height: 26px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-size: .76rem; font-weight: 700; color: var(--ink-soft);
  border: 1px solid rgba(120,150,200,.42); background: rgba(255,255,255,.5);
  font-variant-numeric: tabular-nums;
}

/* ── Breadcrumb hit area ───────────────────────────────────────────────
   The shared .crumbs pattern renders a 17 px-tall link, which is below the
   44 px touch minimum. This sheet only loads on these two pages, so the fix is
   scoped here rather than pushed into the shared sheet: an invisible expanded
   hit area, so the target reaches 44 px without changing the line's look or
   moving anything below it. */
.page .crumbs a { position: relative; display: inline-block; }
.page .crumbs a::after {
  content: ""; position: absolute; left: -8px; right: -8px;
  top: 50%; height: 44px; transform: translateY(-50%);
}

/* ── Back link ─────────────────────────────────────────────────────────*/
.ast-back {
  display: inline-flex; align-items: center; gap: 9px; min-height: 44px;
  font-size: .88rem; font-weight: 600; color: var(--ink-soft); text-decoration: none;
}
.ast-back:hover { color: var(--ink); text-decoration: underline; }

/* ── Narrow ────────────────────────────────────────────────────────────*/
@media (max-width: 720px) {
  .ast-grid { grid-template-columns: 1fr; }
  .ast-disclose { padding: 22px 20px 20px; }
  .ast-card { padding: 20px 20px 18px; }
  .ast-head { gap: 20px; margin-bottom: 32px; }
  .ast-mark-lg { width: 96px; height: 96px; }
  .ast-flabel { min-width: 100%; margin-bottom: -2px; }
  .ast-item, .ast-refusal, .ast-flow li { padding: 16px 18px; }
  .ast-consult { padding: 22px 20px; }
  .ast-quote { padding: 20px 18px; }
  .ast-quote blockquote { padding-left: 14px; font-size: .97rem; }
  .ast-sec { margin-bottom: 46px; }
  .ast-btn-off { width: 100%; justify-content: center; }
  .ast-actions .glass-btn { width: 100%; justify-content: center; text-align: center; }
}

@media (prefers-reduced-motion: reduce) {
  .ast-card, .ast-arrow { transition: none; }
  .ast-card:hover { transform: none; }
  .ast-card:hover .ast-arrow { transform: none; }
}
