/* ============================================================================
   GEPA — "LIVE ENERGY GRID" homepage. Scoped under .grid-home.
   The page is one electrical circuit: cursor-reactive particle lattice (canvas),
   a gold current line (svg) that charges down the page, sections energize as the
   current reaches them, over film-graded real photography. Dependency-free.

   It is a landing page, not a reading page. Below the hero every section is a
   single horizontal rail on a phone and at most three tiles on a desk, each
   ending in the index it summarises. At 375px wide the whole page, footer
   included, is budgeted at 6,000px — about seven screens. That is worked out
   from the sizes below, not measured, so check it on a phone after any
   change that adds height.
   ========================================================================== */

.grid-home {
    --forest: #042420;
    --forest-2: #06342d;
    --forest-3: #0a463c;
    --teal: #0c5c52;
    --teal-lit: #12897a;
    --gold: #f4c24c;
    --gold-hi: #ffdd86;
    --gold-press: #d9a531;
    --ivory: #f6f2e9;
    --ivory-dim: rgba(246, 242, 233, .66);
    --line-cold: rgba(244, 194, 76, .14);
    --shadow-lg: 0 40px 80px -32px rgba(4, 36, 32, .5);
    --shadow-card: 0 24px 46px -28px rgba(4, 36, 32, .42);
    --serif: var(--font-display);
    --ease: cubic-bezier(.16, 1, .3, 1);
    --ease-io: cubic-bezier(.65, 0, .35, 1);
    --ease-hover: cubic-bezier(.22, 1, .36, 1);
    /* one gutter, read by the inner column and by the rails that bleed past it */
    --gx-gutter: clamp(1.25rem, 4vw, 3rem);

    position: relative;
    isolation: isolate; /* keep the ambient layers' blend modes inside the grid */
    background: var(--forest);
    color: var(--ivory);
    font-family: var(--font-ui);
    -webkit-font-smoothing: antialiased;
}

.grid-home ::selection { background: var(--gold); color: var(--forest); }

/* ---- the footer ----------------------------------------------------------
   The footer sits outside .grid-home, and .grid-home is a positioned stacking
   context, so every fixed layer inside it — vignette, grain, lattice — painted
   over the static footer and dimmed it to near-invisible on a phone. Lifting
   the footer above the whole grid puts it back on top of anything this page
   draws. This stylesheet only loads on the homepage, so no other page is
   touched. */
footer.site-footer {
    position: relative;
    z-index: 20;
}

/* ---- fixed ambient layers -------------------------------------------------
   Every decorative layer sits UNDER the content. Sections are z-index 10; the
   lattice, grain, vignette and the current line all stack below that, so the
   line reads through the gaps and transparent bands between cards and never
   cuts through a word. Opaque cards may hide it — a current behind a panel is
   still a current.

   The two full-bleed photographs, the hero's and the story's, are ground
   rather than content, so those sections stack differently: see
   "photographs are ground" below. */
.gx-canvas {
    position: fixed;
    inset: 0;
    width: 100%;
    height: 100%;
    z-index: 0;
    pointer-events: none;
}

.gx-grain {
    position: fixed;
    inset: 0;
    z-index: 2;
    pointer-events: none;
    opacity: .05;
    mix-blend-mode: overlay;
    background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
}

.gx-vignette {
    position: fixed;
    inset: 0;
    z-index: 3;
    pointer-events: none;
    background: radial-gradient(ellipse at center, transparent 52%, rgba(4, 36, 32, .62) 100%);
}

/* the master current-line svg — spans the whole document, under the sections */
.gx-current {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 5;
    pointer-events: none;
    overflow: visible;
}

/* GRID LOAD meter — instrument HUD, desk only (hidden below 1025px and on
   touch screens, further down) */
.gx-meter {
    position: fixed;
    right: 22px;
    bottom: 22px;
    z-index: 45;
    pointer-events: none;
    display: flex;
    align-items: center;
    gap: .6rem;
    padding: .55rem .8rem;
    border: 1px solid rgba(244, 194, 76, .22);
    border-radius: 999px;
    background: rgba(4, 36, 32, .62);
    backdrop-filter: blur(10px);
    color: var(--ivory-dim);
    font-size: .64rem;
    font-weight: 700;
    letter-spacing: .16em;
    text-transform: uppercase;
    opacity: 0;
    transform: translateY(10px);
    transition: opacity .6s var(--ease), transform .6s var(--ease);
}

.gx-meter.on { opacity: 1; transform: none; }
.gx-meter .gx-meter-label { white-space: nowrap; }
.gx-meter .gx-meter-bar { display: flex; gap: 2px; }
.gx-meter .gx-tick { width: 3px; height: 12px; border-radius: 2px; background: rgba(246, 242, 233, .18); transition: background .18s, box-shadow .18s; }
.gx-meter .gx-tick.lit { background: var(--gold); box-shadow: 0 0 6px rgba(244, 194, 76, .8); }
.gx-meter .gx-meter-state { color: var(--gold); min-width: 2.4em; }

/* ---- layout scaffold ----------------------------------------------------- */
/* Each section holds at most one rail, so the rail's scroll timeline is
   scoped here and the swipe bar beside it can read it. */
.gx-sec { position: relative; z-index: 10; padding-block: clamp(2.75rem, 7vw, 7rem); timeline-scope: --gx-strip; }
.gx-inner { max-width: 1360px; margin: 0 auto; padding-inline: var(--gx-gutter); }

/* Photographs are ground. A section at z-index 10 is its own stacking
   context, so everything in it — its photograph too — painted over the
   current: the line vanished across the whole first screen and the whole
   story band, and the vignette and grain no longer graded the hero. These
   two sections give that context up. Their photograph (z 1) then sits over
   the lattice but under the grain, the vignette and the current, exactly as
   the hero was designed; their words (z 10) stay above every one of them. */
.gx-hero,
.gx-story { z-index: auto; }

.gx-eyebrow {
    display: inline-flex;
    align-items: center;
    gap: .7rem;
    margin: 0;
    color: #3dc0a7;
    font-size: .72rem;
    font-weight: 700;
    letter-spacing: .2em;
    text-transform: uppercase;
}
.gx-eyebrow::before { content: ""; flex: none; width: 30px; height: 1.5px; background: var(--gold); display: inline-block; }

.gx-h {
    font-family: var(--serif);
    font-weight: 400;
    line-height: 1.03;
    letter-spacing: -.02em;
    margin: 1rem 0 0;
    text-wrap: balance;
}
.gx-h.xl { font-size: clamp(2.6rem, 6.2vw, 5.7rem); }
.gx-h.lg { font-size: clamp(1.9rem, 4vw, 3.5rem); }
.gx-h.md { font-size: clamp(1.5rem, 2.4vw, 2.15rem); }
.gx-h em { font-style: italic; color: var(--gold); }

/* Section head. On a phone the "see all" link shares the eyebrow's row so it
   costs no height; from 901px it stands beside the title as a pill. */
.gx-sec-head {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    grid-template-areas: "eyebrow link" "title title" "rule rule";
    align-items: center;
    column-gap: 1rem;
    margin-bottom: 1.25rem;
}
.gx-sec-head > .gx-eyebrow { grid-area: eyebrow; }
.gx-sec-head > .gx-h { grid-area: title; margin-top: .55rem; }
.gx-sec-head > .gx-rule { grid-area: rule; width: 120px; margin-top: .9rem; }

.gx-sec-link {
    grid-area: link;
    justify-self: end;
    display: inline-flex;
    align-items: center;
    gap: .45rem;
    min-height: 44px;
    color: var(--gold);
    font-size: .92rem;
    font-weight: 700;
    text-decoration: none;
    white-space: nowrap;
    transition: border-color .22s, background .22s, transform .22s var(--ease-hover);
}
.gx-sec-link .a { transition: transform .22s var(--ease-hover); }
.gx-sec-link:hover .a { transform: translateX(4px); }

/* ---- reveal system -------------------------------------------------------
   Content is never gated on the animation. Hidden states are gated on .gx-js,
   which the inline script removes again if the engine has not booted within
   900ms, so with JS off — or broken — everything is simply there.

   On a desk the reveal is a short entry animation, driven by the element's
   own view timeline where that exists so the delays do not all burn while
   the reader is still on the hero. On a phone it is switched off below: a
   section that fades in as you reach it reads as an empty screen while you
   are scrolling through it. */
.gx-js .gx-sec [data-reveal] {
    animation: gx-rise .55s cubic-bezier(.22, 1, .36, 1) both;
    animation-delay: calc(var(--i, 0) * 45ms);
}
@keyframes gx-rise {
    from { opacity: 0; transform: translateY(18px); }
    to   { opacity: 1; transform: none; }
}
@supports (animation-timeline: view()) {
    .gx-js .gx-sec [data-reveal] {
        animation-timeline: view();
        animation-range: entry 0% entry 40%;
        animation-delay: 0s;
    }
}
@media (prefers-reduced-motion: reduce) {
    .gx-js .gx-sec [data-reveal] { animation: none; }
}

.gx-rule { height: 2px; background: linear-gradient(90deg, var(--gold), transparent); transform-origin: left; }
.gx-js .gx-rule { transform: scaleX(0); transition: transform .8s var(--ease) .1s; }
.gx-js .gx-sec.is-live .gx-rule { transform: scaleX(1); }

/* buttons */
.gx-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: .55rem;
    min-height: 48px;
    padding: .9rem 1.6rem;
    border-radius: 999px;
    border: 2px solid transparent;
    font-weight: 700;
    font-size: .98rem;
    line-height: 1.2;
    text-decoration: none;
    transition: transform .22s var(--ease-hover), box-shadow .22s var(--ease-hover), background .22s, border-color .22s;
}
.gx-btn .a { transition: transform .22s var(--ease-hover); }
.gx-btn:hover .a { transform: translateX(4px); }
.gx-btn.solid { background: linear-gradient(180deg, var(--gold-hi), var(--gold)); color: #3a2a00; box-shadow: 0 14px 34px -14px rgba(244, 194, 76, .75); }
.gx-btn.solid:hover { transform: translateY(-2px); box-shadow: 0 20px 44px -14px rgba(244, 194, 76, .9); }
/* The outlined button used to read as a link: no fill, a faint 1.5px edge and
   the browser's underline. It is a button, so it has a button's edge. */
.gx-btn.ghost {
    border-color: rgba(246, 242, 233, .72);
    background: rgba(4, 36, 32, .45);
    color: var(--ivory);
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
}
.gx-btn.ghost:hover { border-color: var(--gold); background: rgba(244, 194, 76, .1); transform: translateY(-2px); }

/* a quiet gold text link with a 44px target */
.gx-textlink {
    display: inline-flex;
    align-items: center;
    gap: .5rem;
    min-height: 44px;
    color: var(--gold);
    font-weight: 700;
    text-decoration: none;
}
.gx-textlink .a { transition: transform .22s var(--ease-hover); }
.gx-textlink:hover .a { transform: translateX(4px); }

/* ---- cinematic photo treatment ------------------------------------------ */
.gx-photo { position: relative; overflow: hidden; background: var(--forest-2); }
.gx-photo img {
    width: 100%; height: 100%; object-fit: cover; display: block;
    filter: saturate(.5) contrast(1.06) brightness(.58);
    transform: scale(1.05);
    transition: filter 1.1s var(--ease), transform 1.3s var(--ease);
}
.gx-photo::before {
    content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
    background: linear-gradient(150deg, rgba(4, 36, 32, .5), rgba(18, 137, 122, .12) 45%, rgba(244, 194, 76, .16));
    mix-blend-mode: soft-light;
}
.gx-photo::after {
    content: ""; position: absolute; inset: 0; z-index: 1; pointer-events: none;
    background: linear-gradient(0deg, rgba(4, 36, 32, .92), rgba(4, 36, 32, .1) 55%, transparent);
}
.gx-sec.is-live .gx-photo img { filter: saturate(.94) contrast(1.06) brightness(.84); transform: scale(1); }

/* ============================ HERO ======================================== */
.gx-hero { min-height: 100svh; display: flex; align-items: center; padding-block: 7rem 6.5rem; overflow: hidden; }
.gx-hero-photo {
    position: absolute; inset: 0; z-index: 1; pointer-events: none;
    -webkit-mask-image: radial-gradient(120% 100% at 60% 40%, #000 45%, transparent 92%);
    mask-image: radial-gradient(120% 100% at 60% 40%, #000 45%, transparent 92%);
}
.gx-hero-photo img {
    width: 100%; height: 116%; object-fit: cover;
    filter: saturate(.9) contrast(1.08) brightness(.72);
    animation: gx-ken 18s ease-out forwards;
    opacity: .82;
    transition: opacity 1.6s var(--ease), filter 1.6s var(--ease);
}
.gx-js .gx-hero-photo img { opacity: 0; filter: saturate(.62) contrast(1.08) brightness(.5); }
.gx-hero.ready .gx-hero-photo img { opacity: .96; filter: saturate(1) contrast(1.08) brightness(.92); }
/* The copy carries its own scrim (below), so this overlay only grades the
   photograph and settles it into the band beneath. */
.gx-hero-photo::after { content: ""; position: absolute; inset: 0; background: linear-gradient(90deg, rgba(4, 36, 32, .6) 0%, rgba(4, 36, 32, .3) 42%, rgba(4, 36, 32, .1) 100%), linear-gradient(0deg, rgba(4, 36, 32, .6), transparent 40%); }
@keyframes gx-ken { from { transform: scale(1.08) translateY(-1%); } to { transform: scale(1) translateY(0); } }

.gx-hero-inner { position: relative; z-index: 10; max-width: 1360px; margin: 0 auto; padding-inline: var(--gx-gutter); width: 100%; }
.gx-hero-copy { position: relative; max-width: 62ch; }

/* The scrim. A bright cloud in the photograph used to wash the eyebrow out.
   This band is forest at .7 behind every line of the copy — enough that
   ivory, the .92 lead and the gold-lit eyebrow all clear AA even over a
   pure-white pixel of the photo (worst case 5.3:1, for the eyebrow) — and it
   feathers out 120px above and below and 220px to the right, so the rest of
   the photograph keeps its light. */
.gx-hero-copy::before {
    content: "";
    position: absolute;
    z-index: -1;
    top: -120px;
    bottom: -120px;
    left: -100vw;
    right: -220px;
    pointer-events: none;
    background: linear-gradient(270deg, transparent 0, rgba(4, 36, 32, .7) 220px);
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 120px, #000 calc(100% - 120px), transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0, #000 120px, #000 calc(100% - 120px), transparent 100%);
}

.gx-hero-eyebrow { color: var(--gold-hi); font-weight: 800; line-height: 1.5; }
.gx-hero h1 { font-size: clamp(2.7rem, 8vw, 6.6rem); }
.gx-hero .gx-lead { color: rgba(246, 242, 233, .92); font-size: clamp(1.05rem, 1.5vw, 1.28rem); line-height: 1.6; margin: 1.3rem 0 0; max-width: 34rem; }
.gx-hero-actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 2.1rem; }

/* The promise plate: the three things GEPA stands on, on their own dark,
   blurred backing so they read over any part of the photograph. */
.gx-promise {
    list-style: none;
    margin: 2.2rem 0 0;
    padding: 0;
    max-width: 880px;
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    background: rgba(2, 21, 18, .8);
    -webkit-backdrop-filter: blur(12px);
    backdrop-filter: blur(12px);
    border: 1px solid rgba(244, 194, 76, .32);
    border-radius: 16px;
    overflow: hidden;
    box-shadow: 0 24px 50px -30px rgba(0, 0, 0, .8);
}
.gx-promise li {
    display: flex;
    align-items: center;
    gap: .8rem;
    padding: .65rem 1rem;
    color: var(--ivory);
    font: 700 15px/1.3 var(--font-ui);
}
.gx-promise li + li { border-top: 1px solid rgba(244, 194, 76, .16); }
.gx-promise-ic {
    flex: none;
    display: grid;
    place-items: center;
    width: 34px;
    height: 34px;
    border-radius: 999px;
    background: rgba(244, 194, 76, .12);
    border: 1px solid rgba(244, 194, 76, .45);
    color: var(--gold);
}
.gx-promise-ic .icon { width: 18px; height: 18px; }
@media (min-width: 640px) {
    .gx-promise { grid-template-columns: repeat(3, minmax(0, 1fr)); }
    .gx-promise li { padding: .9rem 1.1rem; }
    .gx-promise li + li { border-top: 0; border-left: 1px solid rgba(244, 194, 76, .16); }
}

/* hero line-by-line reveal */
.gx-hero h1 .ln { display: block; overflow: hidden; }
.gx-hero h1 .ln > span { display: block; }
.gx-js .gx-hero h1 .ln > span { transform: translateY(110%); transition: transform .8s var(--ease); }
.gx-js .gx-hero.ready h1 .ln > span { transform: none; }
.gx-hero h1 .ln:nth-child(2) > span { transition-delay: .09s; }
.gx-hero h1 .ln:nth-child(3) > span { transition-delay: .18s; }
.gx-js .gx-hero .gx-fade { opacity: 0; transform: translateY(16px); transition: opacity .8s var(--ease), transform .8s var(--ease); }
.gx-js .gx-hero.ready .gx-fade { opacity: 1; transform: none; }
.gx-hero.ready .gx-lead { transition-delay: .28s; }
.gx-hero.ready .gx-hero-actions { transition-delay: .38s; }
.gx-hero.ready .gx-promise { transition-delay: .48s; }

/* Near-full ivory: this sits on the photograph with only the bottom grade
   (about .7 forest) under it, where the .66 dim ivory would miss AA. */
.gx-scrollcue { position: absolute; left: 50%; bottom: 26px; z-index: 10; transform: translateX(-50%); display: flex; flex-direction: column; align-items: center; gap: .5rem; color: rgba(246, 242, 233, .9); font-size: .62rem; letter-spacing: .22em; text-transform: uppercase; }
.gx-scrollcue .tube { width: 1px; height: 42px; background: rgba(244, 194, 76, .25); position: relative; overflow: hidden; }
.gx-scrollcue .tube::after { content: ""; position: absolute; left: -1.5px; width: 4px; height: 10px; border-radius: 4px; background: var(--gold); box-shadow: 0 0 10px var(--gold); animation: gx-drop 2s var(--ease) infinite; }
@keyframes gx-drop { 0% { top: -12px; opacity: 0; } 30% { opacity: 1; } 100% { top: 44px; opacity: 0; } }

/* ============================ STATS ======================================= */
/* Translucent, not opaque, so the current is still seen crossing the band. */
.gx-stats { background: rgba(6, 52, 45, .62); padding-block: clamp(2.25rem, 5vw, 4.5rem); }
/* The tile count comes from the view, because auto-fit leaves collapsed 0px
   tracks and this grid draws its dividers with gap over a background —
   so each empty track would show as a stray hairline. */
.gx-stats-grid { display: grid; grid-template-columns: repeat(var(--stat-count, 4), minmax(0, 1fr)); gap: 1px; background: rgba(244, 194, 76, .12); border: 1px solid rgba(244, 194, 76, .12); border-radius: 20px; overflow: hidden; }
.gx-stat { padding: 2.2rem 1.8rem; background: var(--forest); position: relative; }
.gx-stat .n { font-family: var(--serif); font-size: clamp(2.3rem, 4vw, 3.4rem); font-weight: 500; color: var(--gold); line-height: 1; font-variant-numeric: tabular-nums; }
.gx-stat .l { color: var(--ivory-dim); font-size: .8rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; margin-top: .7rem; }

/* ============================ RAILS ======================================= */
/* Mobile first: one row that scrolls sideways, each card ~78vw so the next
   one peeks in, snapping card by card. It bleeds to the screen edge past the
   gutter so a card scrolls off the glass rather than off a margin. No script
   is involved — tabindex="0" in the markup makes it keyboard-scrollable, and
   the arrow keys move it once it has focus. */
.gx-strip {
    list-style: none;
    margin: 0 calc(var(--gx-gutter) * -1);
    padding: 8px var(--gx-gutter) 14px; /* room for the hover lift and the focus ring */
    display: flex;
    gap: 12px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x mandatory;
    scroll-padding-inline: var(--gx-gutter);
    scrollbar-width: thin;
    scrollbar-color: rgba(244, 194, 76, .5) transparent;
    scroll-timeline: --gx-strip x;
}
.gx-strip:focus-visible { outline-offset: -3px; }
/* min-width: 0 on the item and its card. A flex item keeps min-width:auto,
   so a cover whose intrinsic width is larger than the basis (a library photo
   is cut at 1600px) stretched its card to 763px on a 390px phone and ran the
   title off the screen. The basis is the width; content may not argue. */
.gx-strip > li { flex: 0 0 min(78vw, 340px); min-width: 0; display: flex; scroll-snap-align: start; }
.gx-strip > li > * { min-width: 0; width: 100%; }
.gx-strip > .gx-strip-end { flex-basis: min(46vw, 220px); }

.gx-strip-hint {
    display: flex;
    align-items: center;
    gap: .75rem;
    margin: .2rem 0 0;
    color: var(--ivory-dim);
    font: 500 12px/1.4 var(--font-data);
    letter-spacing: .08em;
    text-transform: uppercase;
}
.gx-strip-bar { position: relative; flex: 0 0 56px; height: 2px; border-radius: 2px; background: rgba(246, 242, 233, .18); overflow: hidden; }
.gx-strip-bar i { position: absolute; inset: 0; background: var(--gold); transform-origin: left; transform: scaleX(.3); }
@supports (animation-timeline: scroll()) {
    .gx-strip-bar i { animation: gx-strip-fill auto linear both; animation-timeline: --gx-strip; }
}
@keyframes gx-strip-fill { from { transform: scaleX(.18); } to { transform: scaleX(1); } }
.gx-strip-arrow { display: inline-block; color: var(--gold); animation: gx-nudge 1.8s var(--ease) infinite; }
@keyframes gx-nudge { 0%, 100% { transform: none; } 50% { transform: translateX(4px); } }

/* the card a rail ends on — a gold terminal node and the way to the index */
.gx-seeall {
    display: flex;
    flex-direction: column;
    justify-content: flex-end;
    gap: .8rem;
    width: 100%;
    padding: 1.25rem;
    border-radius: 18px;
    border: 1px dashed rgba(244, 194, 76, .5);
    background: radial-gradient(120% 80% at 100% 0%, rgba(244, 194, 76, .14), transparent 60%), var(--forest-2);
    color: var(--ivory);
    text-decoration: none;
}
.gx-seeall-node {
    display: grid;
    place-items: center;
    width: 52px;
    height: 52px;
    border-radius: 999px;
    background: var(--gold);
    color: #3a2a00;
    font-size: 1.3rem;
    font-weight: 700;
    box-shadow: 0 0 0 6px rgba(244, 194, 76, .14), 0 0 28px rgba(244, 194, 76, .45);
    transition: transform .22s var(--ease-hover);
}
.gx-seeall:hover .gx-seeall-node { transform: translateX(4px); }
.gx-seeall-label { font: 500 1.3rem/1.2 var(--font-display); }
.gx-seeall-meta { color: var(--ivory-dim); font: 500 12px/1.4 var(--font-data); letter-spacing: .08em; text-transform: uppercase; }

/* ============================ CARDS ======================================= */
/* One card for tracks, courses and posts: a still, a title, one line. The
   title (or "Read more") is the link and its overlay covers the tile. */
.gx-card {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    background: var(--forest-2);
    border: 1px solid rgba(244, 194, 76, .14);
    border-radius: 18px;
    overflow: hidden;
    transition: transform .3s var(--ease-hover), border-color .3s;
}
.gx-card:hover { transform: translateY(-6px); border-color: rgba(244, 194, 76, .5); }
/* The tile's link sits inside it, so the ring goes on the tile. A click
   focuses the link too, and only a keyboard should draw the ring; where
   :has() is not supported the ring simply shows on click as well. */
.gx-card:focus-within,
.gx-person:focus-within { outline: 3px solid var(--focus); outline-offset: 2px; }
.gx-card:has(:focus:not(:focus-visible)),
.gx-person:has(:focus:not(:focus-visible)) { outline: none; }
.gx-card-media { aspect-ratio: 16 / 10; }
.gx-card:hover .gx-card-media img { transform: scale(1.05); filter: saturate(1) contrast(1.06) brightness(.92); }
.gx-card-num { position: absolute; z-index: 2; left: .9rem; bottom: .75rem; color: var(--gold); font: 500 12px/1 var(--font-data); letter-spacing: .14em; }
.gx-card-tags { position: absolute; z-index: 2; left: .8rem; bottom: .8rem; display: flex; gap: .4rem; }
.gx-card-tags .t { padding: .28rem .6rem; border-radius: 999px; font-size: .68rem; font-weight: 800; letter-spacing: .04em; text-transform: uppercase; background: rgba(246, 242, 233, .94); color: var(--forest); }
.gx-card-tags .t.gold { background: var(--gold); color: #3a2a00; }

.gx-card-body { display: flex; flex-direction: column; gap: .45rem; flex: 1; padding: 1rem 1.15rem 1.05rem; }
.gx-card-kicker { margin: 0; color: #3dc0a7; font: 500 12px/1.4 var(--font-data); letter-spacing: .1em; text-transform: uppercase; }
.gx-card-title { margin: 0; color: var(--ivory); font: 500 1.24rem/1.2 var(--font-display); letter-spacing: -.01em; text-wrap: balance; }
.gx-card-title a { color: inherit; text-decoration: none; }
.gx-card-title a::after,
.gx-card-go::after { content: ""; position: absolute; inset: 0; z-index: 3; }
.gx-card-title a:focus-visible,
.gx-card-go:focus-visible { outline: none; }
/* Title and one line: the line is clipped to the card's width here, and cut
   at a word in the partial so a screen reader is not read the paragraph. */
.gx-card-line {
    margin: 0;
    color: var(--ivory-dim);
    font-size: .92rem;
    line-height: 1.5;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.gx-card-meta { margin: 0; color: #3dc0a7; font: 500 12.5px/1.45 var(--font-data); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.gx-card-foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    margin: auto 0 0;
    padding-top: .75rem;
    border-top: 1px solid rgba(244, 194, 76, .12);
    color: var(--ivory);
    font-size: .88rem;
    font-weight: 700;
}
.gx-card-arrow { color: var(--gold); transition: transform .22s var(--ease-hover); }
.gx-card:hover .gx-card-arrow { transform: translateX(4px); }
.gx-card-go {
    display: inline-flex;
    align-items: center;
    gap: .4rem;
    min-height: 44px;
    margin-top: auto;
    color: var(--gold);
    font-size: .92rem;
    font-weight: 700;
    text-decoration: none;
}

/* ============================ FACULTY ===================================== */
.gx-faculty { background: rgba(6, 52, 45, .55); }
.gx-person {
    position: relative;
    display: flex;
    flex-direction: column;
    width: 100%;
    background: var(--forest);
    border: 1px solid rgba(246, 242, 233, .12);
    border-radius: 18px;
    overflow: hidden;
    transition: transform .3s var(--ease-hover), border-color .3s;
}
.gx-person:hover { transform: translateY(-6px); border-color: rgba(244, 194, 76, .55); }
.gx-person-media { aspect-ratio: 4 / 3; overflow: hidden; background: var(--forest-2); }
.gx-person-media img { width: 100%; height: 100%; object-fit: cover; object-position: 50% 22%; }

/* The monogram tile — deliberately not a photograph. Initials in the display
   face over a gold node, with the rings of current spreading out from it. */
.gx-person-mono {
    display: grid;
    place-items: center;
    height: 100%;
    background:
        radial-gradient(circle at 80% 84%, var(--gold) 0 4px, rgba(244, 194, 76, .35) 5px, transparent 14px),
        repeating-radial-gradient(circle at 80% 84%, transparent 0 44px, rgba(244, 194, 76, .16) 44px 45px),
        linear-gradient(150deg, var(--forest-3), var(--forest-2) 55%, var(--forest));
    border-bottom: 1px solid var(--gilt);
    color: var(--gold);
    font: 400 clamp(2.8rem, 12vw, 3.8rem)/1 var(--font-display);
    letter-spacing: .04em;
}

.gx-person-body { display: flex; flex-direction: column; gap: .3rem; flex: 1; padding: 1rem 1.15rem 1.15rem; }
.gx-person-count { margin: 0; color: var(--gold); font: 500 12px/1.4 var(--font-data); letter-spacing: .1em; text-transform: uppercase; }
.gx-person-name { margin: 0; color: var(--ivory); font: 500 1.25rem/1.2 var(--font-display); letter-spacing: -.01em; }
.gx-person-name a { color: inherit; text-decoration: none; }
.gx-person-name a::after { content: ""; position: absolute; inset: 0; z-index: 3; }
.gx-person-name a:focus-visible { outline: none; }
.gx-person-line {
    margin: 0;
    color: var(--ivory-dim);
    font-size: .9rem;
    line-height: 1.45;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* ============================ STORY ======================================= */
/* One line and a link where a statement and four pillars used to be. */
.gx-story { overflow: hidden; }
.gx-story-photo { position: absolute; inset: 0; z-index: 1; }
/* Fixed, not energised: the copy's contrast is worked out against this grade.
   Matches .gx-sec.is-live .gx-photo img in weight so it wins either way. */
.gx-sec.gx-story .gx-story-photo img { filter: saturate(.95) contrast(1.08) brightness(.62); transform: none; }
.gx-story-photo::after { background: linear-gradient(180deg, rgba(4, 36, 32, .86), rgba(4, 36, 32, .66) 45%, rgba(4, 36, 32, .9)); }
.gx-story .gx-inner { position: relative; z-index: 10; display: grid; gap: 1rem; }
.gx-story .gx-h { max-width: 18ch; }
.gx-story-line { color: rgba(246, 242, 233, .9); max-width: 44ch; }
.gx-story-close { display: grid; justify-items: start; gap: .35rem; }

/* ============================ BLOG ======================================== */
.gx-blog-cta { margin-top: 1.1rem; }

/* ============================ CLOSE ======================================= */
/* Two compact tiles: one sentence and one action each. Opaque, so nothing
   decorative shows through behind the words. The icon stands beside the
   heading rather than on a row of its own — two tiles stacked on a phone
   are a screen's worth, and that row was the part saying least. */
.gx-close-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 12px; }
.gx-tile {
    position: relative;
    display: grid;
    grid-template-columns: auto minmax(0, 1fr);
    align-items: center;
    justify-items: start;
    gap: .65rem .85rem;
    padding: 1.35rem;
    border: 1px solid rgba(244, 194, 76, .2);
    border-radius: 20px;
    overflow: hidden;
}
.gx-tile > * { position: relative; z-index: 1; }
.gx-tile > .gx-tile-p,
.gx-tile > .gx-btn { grid-column: 1 / -1; }
.gx-tile .gx-tile-photo { position: absolute; inset: 0; z-index: 0; opacity: .2; }
.gx-tile--verify { background: linear-gradient(150deg, rgba(18, 137, 122, .3), rgba(4, 36, 32, .6)), var(--forest-2); }
.gx-tile--corp { background: linear-gradient(150deg, rgba(244, 194, 76, .16), rgba(4, 36, 32, .6)), var(--forest-2); }
.gx-tile-ic {
    display: grid;
    place-items: center;
    width: 40px;
    height: 40px;
    border-radius: 999px;
    background: rgba(244, 194, 76, .12);
    border: 1px solid rgba(244, 194, 76, .45);
    color: var(--gold);
}
.gx-tile-p { margin: 0 0 .35rem; color: rgba(246, 242, 233, .86); line-height: 1.55; max-width: 42ch; }
.gx-corp-btn.solid { animation: gx-shimmer 3.5s ease-in-out infinite; }
@keyframes gx-shimmer { 0%, 100% { box-shadow: 0 14px 34px -14px rgba(244, 194, 76, .55); } 50% { box-shadow: 0 14px 44px -10px rgba(244, 194, 76, .9); } }

/* ============================ GROUND ====================================== */
/* The end of the circuit. It stays inside the grid, clear of the footer. */
.gx-ground { position: relative; z-index: 10; padding-block: 1.5rem 3rem; text-align: center; }
.gx-ground .sym { font-size: 1.4rem; color: var(--gold); }
.gx-ground p { color: var(--ivory-dim); font-size: .85rem; margin: .5rem 0 0; }

/* ============================ RESPONSIVE ================================== */
@media (min-width: 720px) {
    .gx-close-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.3rem; }
    .gx-tile { padding: clamp(1.6rem, 3vw, 2.4rem); }
}

/* From 901px a rail is a grid of at most three; the "see all" card and the
   swipe hint give way to the pill in the section head. */
@media (min-width: 901px) {
    .gx-sec-head { grid-template-areas: "eyebrow link" "title link" "rule link"; align-items: end; margin-bottom: 2.4rem; }
    .gx-sec-link {
        align-self: end;
        padding: .8rem 1.5rem;
        border: 2px solid rgba(246, 242, 233, .6);
        border-radius: 999px;
        color: var(--ivory);
        font-size: .96rem;
    }
    .gx-sec-link:hover { border-color: var(--gold); background: rgba(244, 194, 76, .08); transform: translateY(-2px); }

    .gx-strip {
        display: grid;
        grid-template-columns: repeat(3, minmax(0, 1fr));
        gap: 1.3rem;
        margin: 0;
        padding: 0;
        overflow: visible;
        scroll-snap-type: none;
    }
    .gx-strip > li:nth-child(n + 4),
    .gx-strip > .gx-strip-end,
    .gx-strip-hint { display: none; }

    .gx-story .gx-inner { grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr); align-items: end; column-gap: 4rem; }
}

@media (max-width: 768px) {
    /* The hero fills the screen under the sticky header, not behind it. */
    .gx-hero { min-height: calc(100svh - 72px); padding-block: 2.5rem 2.75rem; }
    /* the copy's scrim covers the text; here the photo only settles into the band below */
    .gx-hero-photo::after { background: linear-gradient(0deg, rgba(4, 36, 32, .7), transparent 32%); }
    .gx-hero-actions { flex-direction: column; align-items: stretch; }
    .gx-hero-actions .gx-btn { width: 100%; }

    /* Everyone knows to scroll a phone. */
    .gx-scrollcue { display: none; }

    /* Short reveals on a phone: nothing waits more than a fifth of a second. */
    .gx-js .gx-hero .gx-fade { transition-duration: .45s, .45s; }
    .gx-hero.ready .gx-lead { transition-delay: .06s; }
    .gx-hero.ready .gx-hero-actions { transition-delay: .12s; }
    .gx-hero.ready .gx-promise { transition-delay: .18s; }
    .gx-js .gx-sec [data-reveal] { animation: none; }
    .gx-js .gx-rule { transform: none; transition: none; }
    .gx-sec:not(.gx-hero):not(.gx-story) .gx-photo img { filter: saturate(.94) contrast(1.06) brightness(.84); transform: none; }
}

/* The HUD is a desk instrument: it reads the pointer, and on anything
   narrower than a laptop its corner is content — an iPad at 820px has cards
   under it. A touch screen has no pointer to read, so it goes there too. */
@media (max-width: 1024px), (pointer: coarse) {
    .gx-meter { display: none; }
}

@media (max-width: 720px) {
    .gx-stats-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
    /* An odd tile out would leave the gap-drawn grid showing an empty gold
       cell beside it; the last odd tile takes the whole row instead. Works
       for any count from one to four. */
    .gx-stat:last-child:nth-child(odd) { grid-column: 1 / -1; }
    .gx-stat { padding: 1.3rem 1.15rem; }
}

/* ============================ REDUCED MOTION ============================= */
@media (prefers-reduced-motion: reduce) {
    .grid-home * { animation: none !important; }
    .gx-sec [data-reveal], .gx-hero .gx-fade, .gx-hero h1 .ln > span { opacity: 1 !important; transform: none !important; transition: none !important; }
    .gx-rule { transform: scaleX(1) !important; }
    .gx-hero-photo img { opacity: .82 !important; }
    .gx-photo img { filter: saturate(.9) contrast(1.06) brightness(.8) !important; transform: none !important; }
}

/* The current-line glow is a layered stroke, not a filter: a Gaussian blur over
   a path thousands of pixels tall re-rasterises on every gradient tick. */
.grid-home .gx-halo { will-change: stroke-dashoffset; }
.grid-home .gx-live { will-change: stroke-dashoffset; }
.grid-home.gx-static .gx-halo,
.grid-home.gx-static .gx-live { will-change: auto; }
