@import url("/assets/fonts.css");

/* fhg-premium.css — shared visual primitives for every FHG surface.
 *
 * WHY THIS EXISTS. Centering, the gold reveal and the card treatment were being
 * applied page by page, which meant they were applied inconsistently and had to
 * be remembered every time a card was added. The standing rule — titles AND
 * body content centered, no exception for long-form — should be what a card
 * DOES, not an instruction to follow.
 *
 * USAGE. One link, one script, both palettes:
 *   <link rel="stylesheet" href="/assets/fhg-premium.css">
 *   <script src="/assets/fhg-premium.js" defer></script>
 *
 * The script needs no configuration. It finds cards by class and by common
 * legacy names, so existing pages inherit the behavior without markup edits.
 *
 * PALETTE. Variables resolve from the host page. Each has a fallback so this
 * file renders correctly dropped into a page that scopes its own tokens
 * differently — University dark, Compass light, corporate dark.
 */

:root {
  --fhg-ease: cubic-bezier(.22, .61, .36, 1);
  --fhg-reveal-shift: 14px;
  --fhg-reveal-dur: .7s;
  --fhg-stagger: 90ms;
}

/* ─── Centering ────────────────────────────────────────────────────
   Applied to the card classes in use across the three sites. Adding a
   class here is how a new card joins, rather than copying rules. */

.fhg-card, .fhg-card *,
.inst-card, .inst-card *,
.inst-cert-card, .inst-cert-card *,
.seat-card, .seat-card *,
.pay-card, .pay-card *,
.fund-card, .fund-card *,
.card, .card * {
  text-align: center;
}

/* Lists lose bullets and indent, or centered text reads ragged. */
.fhg-card ul, .inst-card ul, .inst-cert-card ul,
.seat-card ul, .pay-card ul, .fund-card ul, .card ul {
  list-style: none;
  padding-left: 0;
  margin-left: auto;
  margin-right: auto;
}
.fhg-card li::before, .inst-card li::before, .seat-card li::before,
.pay-card li::before, .fund-card li::before, .card li::before {
  content: none;
}

/* ─── Price rows ──────────────────────────────────────────────────
   text-align centers INLINE content. A price row is almost always a
   flex container, and flex children are positioned by justify-content,
   which text-align does not touch. This is why centering the card did
   not center the price. */

.seat-price, .price, .price-row, .fhg-price,
.seat-card .seat-price, .seat-card .price,
.card .price {
  display: flex;
  align-items: baseline;
  justify-content: center;
  gap: 8px;
  flex-wrap: wrap;
}

/* Anything that sits on its own line under the price. */
.seat-equiv, .price-note, .fhg-price-note,
.seat-card .seat-equiv, .card .price span {
  display: block;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}

/* A pill centers as a block only once it stops filling the row. */
.seat-save, .save-pill, .fhg-pill, .badge {
  display: block;
  width: fit-content;
  margin-left: auto;
  margin-right: auto;
  text-align: center;
}

/* ─── Reveal on scroll ────────────────────────────────────────────
   Cards start hidden ONLY when the script has confirmed it will run.
   Without .fhg-js on <html>, everything renders visible — a stylesheet
   that hides content while its script fails is a blank page. */

.fhg-js .fhg-reveal {
  opacity: 0;
  transform: translateY(var(--fhg-reveal-shift));
  transition:
    opacity var(--fhg-reveal-dur) var(--fhg-ease),
    transform var(--fhg-reveal-dur) var(--fhg-ease),
    box-shadow .35s ease;
}

.fhg-js .fhg-reveal.fhg-in {
  opacity: 1;
  transform: none;
}

/* ─── Gold outline ────────────────────────────────────────────────
   A masked gradient border that traces in behind the card once it has
   settled. Diagonal, so it reads as light catching an edge rather than
   as a highlighted box. */

.fhg-reveal { position: relative; }

.fhg-reveal::after {
  content: "";
  position: absolute;
  inset: -1px;
  border-radius: inherit;
  padding: 1px;
  background: linear-gradient(
    135deg,
    var(--gold, #c9a86a),
    rgba(201, 168, 106, 0) 42%,
    rgba(201, 168, 106, 0) 58%,
    var(--gold, #c9a86a)
  );
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  opacity: 0;
  transition: opacity 1.1s ease .25s;
  pointer-events: none;
}

.fhg-js .fhg-reveal.fhg-in::after { opacity: .8; }
.fhg-reveal:hover::after { opacity: 1; transition-delay: 0s; }

/* ─── Lift ────────────────────────────────────────────────────────
   Shadow tinted toward the brand rather than neutral gray, so it reads
   as warm on cream and does not muddy on near-black. */

.fhg-reveal.fhg-in:hover {
  transform: translateY(-4px);
  box-shadow: 0 14px 34px -18px rgba(74, 58, 22, .38);
}

/* ─── Equal-height cards ──────────────────────────────────────────
   A CTA at the bottom of one card and mid-way up its neighbor is the
   tell that a grid was never checked at width. */

.fhg-card, .seat-card, .card, .fund-card {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
}
.fhg-card ul, .seat-card ul, .card ul, .fund-card ul { flex: 1 0 auto; }

/* ─── Reduced motion ──────────────────────────────────────────────
   Everything visible, nothing animates. Not a degraded view — the same
   page without the movement. */

@media (prefers-reduced-motion: reduce) {
  .fhg-js .fhg-reveal {
    opacity: 1;
    transform: none;
    transition: none;
  }
  .fhg-js .fhg-reveal::after { opacity: .8; transition: none; }
  .fhg-reveal.fhg-in:hover { transform: none; }
}

/* ─── Centered body copy on public surfaces ────────────────────────
   Added Aug 28, 2026. The standing rule is that titles AND body copy
   center on every public FHG page. It was being applied page by page,
   so it was applied unevenly — this makes it what a public page DOES.

   Scoped to [data-surface="public"] deliberately. Dashboards and member
   surfaces link this same stylesheet and are under separate review, so a
   bare `p { text-align: center }` would reach them too.

   Tables, code and form fields keep their own alignment: centering tabular
   data or a code block makes it harder to read, which is the opposite of
   the point. */

[data-surface="public"] p,
[data-surface="public"] h1,
[data-surface="public"] h2,
[data-surface="public"] h3,
[data-surface="public"] h4,
[data-surface="public"] li,
[data-surface="public"] blockquote,
[data-surface="public"] figcaption,
[data-surface="public"] dd,
[data-surface="public"] dt {
  text-align: center;
}

[data-surface="public"] table,
[data-surface="public"] th,
[data-surface="public"] td,
[data-surface="public"] pre,
[data-surface="public"] code,
[data-surface="public"] label,
[data-surface="public"] input,
[data-surface="public"] textarea,
[data-surface="public"] select {
  text-align: initial;
}

/* Centered text needs a measure, or a wide viewport turns a paragraph into
   a ragged ribbon that is genuinely harder to read than left-aligned. */
[data-surface="public"] p {
  max-width: 68ch;
  margin-left: auto;
  margin-right: auto;
}
