/* ============================================================
   gf.css - THE GrantField design system: B1 "Glasshouse" PLAIN (locked 2026-07-03
   from the founder's pinned b1-home + hybrid-account screenshots). No grain, no marbling: plain frosted glass only.

   This is the single source of truth for tokens and shared components.
   Load ORDER matters: fonts.css, then THIS, then the page's own stylesheet
   (page CSS holds layout specific to that page and must not restate tokens
   or re-style shared components).

   Vocabulary:
   - Ground: a soft green aurora haze over near-white. No grid, no grain,
     no texture overlays (all texture rounds were explicitly rejected).
   - Glass: plain frosted panels (translucent white + blur) with 1px light
     borders. No specular edges, no sheen, no gloss.
   - The big white pieces (data cards, browser frames) are plain white.
   - Saturation is spent ONLY in small accents: buttons, verdict dots, the
     fit bar. Never page-wide, never as dark slabs.
   ============================================================ */

:root {
  /* Ink scale */
  --gf-ink: #0A2A21;
  --gf-ink-2: #3E564D;
  --gf-ink-3: #718880;
  /* Greens */
  --gf-deep: #0A5C42;
  --gf-accent: #10A374;
  --gf-bright: #34C393;
  /* Semantic (separate from accent) */
  --gf-warn: #A34F38;
  --gf-warn-bg-1: #FBEFEA;
  --gf-warn-bg-2: #F3E1D8;
  /* Surfaces */
  --gf-white: #FDFDFB;
  --gf-hair: #ECF2EE;
  --gf-hair-2: #E9F0EC;
  --gf-glass-hi: rgba(255, 255, 255, 0.92);
  /* Type */
  --gf-sans: "Geist", ui-sans-serif, system-ui, sans-serif;
  --gf-mono: "Geist Mono", ui-monospace, monospace;
  /* Prime scale (2026-07-04 handoff): hero display + standalone stat numerals */
  --gf-h1: clamp(56px, 7vw, 88px);
  --gf-stat-num: 40px;
  /* Radii */
  --gf-r-mast: 17px;
  --gf-r-card: 17px;
  --gf-r-btn: 13px;
  --gf-r-slab: 26px;
  --gf-r-frame: 14px;
  --gf-r-tile: 20px;
  /* Shadow recipes */
  --gf-sh-glass: inset 0 1.5px 1px var(--gf-glass-hi), inset 0 -6px 16px rgba(10, 92, 66, 0.10), 0 12px 38px rgba(10, 92, 66, 0.15);
  --gf-sh-card: inset 0 1px 0 #fff, 0 1px 0 rgba(10, 92, 66, 0.08), 0 14px 36px rgba(10, 42, 33, 0.08);
  --gf-sh-tile: inset 0 1.5px 1px var(--gf-glass-hi), inset 0 -14px 30px rgba(10, 92, 66, 0.13), 0 22px 55px rgba(10, 92, 66, 0.15);
}

/* ---- Grounds ------------------------------------------------------------ */

/* Overscroll canvas: the aurora ground lives on <body>, but the rubber-band
   area revealed by pulling past the top or bottom is painted from the ROOT
   element. A flat fill there makes the design stop at a hard line. So the ROOT
   carries the actual aurora, fixed to the viewport (background-attachment:
   fixed), which means the bounce reveals the SAME soft aurora continuing up or
   down instead of a seam. The body grounds layer their page-specific ground on
   top in the content area; the overscroll always shows this shared aurora. */
/* Flat only - NOT the aurora. Painting a second fixed-attachment aurora on the
   root double-composited with the body's on every load and contributed to the
   header-strip color flash. The flat near-white green keeps the overscroll
   bounce area seamless; the body owns the one real aurora. */
/* scrollbar-gutter:stable reserves the vertical scrollbar's space on EVERY page,
   so the centered masthead (and page) never re-centers by ~7px when navigating
   between a short page (no scrollbar) and a tall one (scrollbar) on systems with
   classic non-overlay scrollbars. No effect under overlay scrollbars. */
html { background: #F2F8F4; scrollbar-gutter: stable; }

/* ONE ground for every page (marketing AND app): the aurora wash + the faint
   grid, applied uniformly so explore/match/account/admin/browse/signup read the
   same as the home. The grid fades out below the fold; the glass panels sit on
   top of it cleanly. */
.gf-marketing, .gf-app {
  font-family: var(--gf-sans); color: var(--gf-ink); -webkit-font-smoothing: antialiased;
  background:
    radial-gradient(900px 600px at 12% -8%, rgba(52, 195, 147, 0.30), transparent 62%),
    radial-gradient(1100px 700px at 88% 4%, rgba(15, 123, 87, 0.24), transparent 64%),
    radial-gradient(700px 600px at 55% 38%, rgba(167, 225, 196, 0.32), transparent 60%),
    radial-gradient(800px 520px at 18% 92%, rgba(52, 195, 147, 0.14), transparent 60%),
    radial-gradient(900px 560px at 92% 78%, rgba(15, 123, 87, 0.10), transparent 62%),
    linear-gradient(#F4FAF7, #EFF6F2 55%, #F3F8F4);
  overflow-x: hidden; position: relative;
}
.gf-marketing::before, .gf-app::before { /* the faint grid, fading out mid-page */
  content: ""; position: absolute; inset: 0 0 auto 0; height: 820px; pointer-events: none;
  background-image:
    linear-gradient(rgba(10, 92, 66, 0.09) 1px, transparent 1px),
    linear-gradient(90deg, rgba(10, 92, 66, 0.09) 1px, transparent 1px);
  background-size: 30px 30px;
  -webkit-mask-image: radial-gradient(820px 520px at 50% 12%, #000 30%, transparent 78%);
  mask-image: radial-gradient(820px 520px at 50% 12%, #000 30%, transparent 78%);
}

/* B1 plain: no film grain. The classes remain as no-ops so markup that
   carries .gf-grain needs no churn. */


.gf-wrap { max-width: 1120px; margin: 0 auto; padding: 0 28px; position: relative; }
.gf-wrap-wide { max-width: 1240px; margin: 0 auto; padding: 0 24px; position: relative; }
/* Masthead wrapper: static pages (hubs, grant leaves) wrap the masthead in
   this so the bar renders at the SAME width as the React pages' .wrap (whose
   content is wider than 1264 at every real viewport). One masthead width
   site-wide; see .gf-mast-in max-width below. */
.gf-mast-wrap { max-width: 1312px; margin: 0 auto; padding: 0 24px; position: relative; }

/* ---- Masthead ------------------------------------------------------------
   Markup contract (shared by gf-mast.jsx and chrome-static.mjs):
   <header class="gf-mast"><div class="gf-mast-in gf-grain"> brand | nav | right </div></header> */
/* A floating rounded pill with a small top gap, so an overscroll at the top of
   the page just reveals more aurora (never a square edge attached to nothing).
   z-index above page content so its dropdowns are never overlapped by cards
   below; max-width keeps the bar one consistent size on every page. */
.gf-mast { position: sticky; top: 14px; z-index: 100; }
.gf-mast-in {
  display: flex; align-items: center; gap: 24px; height: 56px; padding: 0 10px 0 18px;
  max-width: 1264px; margin-inline: auto;
  border-radius: var(--gf-r-mast);
  /* Frosted glass from the FIRST paint - no class flip, no rAF defer. The old
     2-rAF html.gf-frost flip painted the bar un-frosted (0.82) then popped it to
     0.66+blur a frame later - a visible step on every load, and (while
     cross-document view transitions were enabled) the step the crossfade
     amplified into the "darker green band". One stable frosted recipe from
     frame 0 removes it. Always-on backdrop-filter is paint-safe: no late layer
     promotion, no class flip. */
  background: rgba(255, 255, 255, 0.66);
  backdrop-filter: blur(20px) saturate(1.7); -webkit-backdrop-filter: blur(20px) saturate(1.7);
  border: 1px solid rgba(255, 255, 255, 0.85);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85), 0 12px 40px rgba(10, 92, 66, 0.14);
}
.gf-brand { display: flex; align-items: center; gap: 9px; font-weight: 650; font-size: 15.5px; letter-spacing: -0.01em; color: var(--gf-ink); text-decoration: none; white-space: nowrap; }
/* The brand is one clickable target to home; the wordmark span and the gem
   both route through the anchor (no dead gap between them). */
.gf-brand .w { pointer-events: none; }
.gf-brand .mk { pointer-events: none; }
.gf-brand .mk {
  width: 22px; height: 22px; border-radius: 7px; flex: none;
  background: radial-gradient(120% 130% at 45% -10%, #B9F5D9 0%, #34C393 35%, #0F7B57 70%, #073821 100%);
  box-shadow: inset 0 1.5px 1px rgba(255, 255, 255, 0.85), inset 0 -4px 8px rgba(4, 38, 27, 0.5), 0 4px 12px rgba(15, 123, 87, 0.4);
}

/* The gem, cut sharper (Prime). Shared mark recipes for every size above the
   masthead's 22px (which stays exactly as above). Sizes >= 30px carry the
   specular facet (::after) and a deeper inner shade; .lg is the 52px cut. */
.gf-gem {
  position: relative; flex: none; width: 30px; height: 30px; border-radius: 9px;
  background: radial-gradient(120% 130% at 45% -10%, #B9F5D9 0%, #34C393 35%, #0F7B57 70%, #073821 100%);
  box-shadow: inset 0 1.5px 1px rgba(255, 255, 255, 0.85), inset 0 -5px 10px rgba(4, 38, 27, 0.5), 0 6px 16px rgba(15, 123, 87, 0.4);
}
.gf-gem::after {
  content: ""; position: absolute; left: 18%; top: 12%; width: 34%; height: 22%;
  border-radius: 50%; background: linear-gradient(180deg, rgba(255, 255, 255, 0.95), rgba(255, 255, 255, 0));
  filter: blur(1px);
}
.gf-gem.lg {
  width: 52px; height: 52px; border-radius: 15px;
  box-shadow: inset 0 2px 2px rgba(255, 255, 255, 0.9), inset 0 -9px 16px rgba(4, 38, 27, 0.55), 0 10px 26px rgba(15, 123, 87, 0.45);
}

/* Tile row: the 4-up stat grid that lives INSIDE .gf-slab-sage (Prime's
   glass > white card > data layering). Collapses 2-up then 1-up. */
.gf-tilerow { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; }
.gf-slab-sage .gf-tilerow { margin-top: 20px; }
@media (max-width: 900px) { .gf-tilerow { grid-template-columns: 1fr 1fr; } }
@media (max-width: 520px) { .gf-tilerow { grid-template-columns: 1fr; } }
.gf-nav { display: flex; gap: 4px; font-size: 13.5px; font-weight: 500; color: var(--gf-ink-2); }
.gf-nav > a, .gf-nav > .gf-drop > a { display: inline-block; padding: 7px 11px; border-radius: 10px; color: inherit; text-decoration: none; transition: background .15s; }
/* Hover oval: clearly visible (a soft filled pill), but flat - the SELECTED
   tab keeps its raised inset+drop shadow, so hover never overpowers "on". */
.gf-nav > a:hover, .gf-nav > .gf-drop > a:hover { background: rgba(255, 255, 255, 0.72); color: var(--gf-ink); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.85); }
/* Instant press feedback: nav items and the account pill are full-page links,
   so the .on / signed-in state only lands after navigation. The :active state
   acknowledges the click on the current frame, so a tap never feels dropped. */
.gf-nav > a:active, .gf-nav > .gf-drop > a:active, .gf-pill:active, .gf-search:active {
  background: rgba(255, 255, 255, 0.9); transform: translateY(0.5px); }
/* Active-tab oval: identical thickness/opacity for ALL five tabs, including the
   Browse dropdown trigger (.gf-drop > a), so "Browse" gets the same selected
   pill on hub pages that Explore/Match/Pricing/Docs get on theirs. */
.gf-nav > a.on, .gf-nav > .gf-drop > a.on { background: rgba(255, 255, 255, 0.75); color: var(--gf-deep);
  box-shadow: inset 0 1px 1px #fff, inset 0 -2px 6px rgba(10, 92, 66, 0.10), 0 2px 8px rgba(10, 92, 66, 0.10); }
/* Browse dropdown: CSS-only (hover/focus-within), works on static pages too. */
.gf-drop { position: relative; }
.gf-drop-menu {
  position: absolute; left: 0; top: calc(100% + 6px); min-width: 230px; padding: 7px; z-index: 50;
  border-radius: 14px;
  /* Solid surface (founder's call): a menu is opaque so nothing behind bleeds
     through and the items are always crisp. Translucent frost let the page text
     show through, which fought readability. The system card white + a hairline
     ring + soft shadow lift it off the page. */
  background: #FDFDFB;
  box-shadow: inset 0 1px 0 #fff, 0 0 0 1px rgba(10, 92, 66, 0.08), 0 18px 50px rgba(10, 92, 66, 0.20);
  opacity: 0; visibility: hidden; transform: translateY(-4px); transition: opacity .15s, transform .15s, visibility .15s;
}
/* Invisible bridge across the trigger->menu gap so the hover never drops while
   the pointer travels from the pill to the menu. */
.gf-drop-menu::before { content: ""; position: absolute; top: -8px; left: 0; right: 0; height: 8px; }
.gf-drop:hover .gf-drop-menu, .gf-drop:focus-within .gf-drop-menu { opacity: 1; visibility: visible; transform: none; }
/* Hover-intent (THE site standard for every .gf-drop dropdown): a menu waits
   before it opens, so grazing a trigger while the pointer travels past never
   fires it. This is what makes a big target (the account pill is ~1.7x the area
   of the Browse link and sits at the right edge the cursor sweeps through) feel
   as deliberate as a small one, instead of popping the instant the cursor
   breaks its plane. Open only: the delay is on the hover state, so closing
   stays immediate (base rule, no delay) and keyboard focus opens with no wait. */
.gf-drop:hover .gf-drop-menu { transition-delay: .12s; }
.gf-drop-menu a { display: flex; justify-content: space-between; align-items: baseline; gap: 14px; padding: 8px 12px; border-radius: 9px; font-size: 13.5px; color: var(--gf-ink-2); text-decoration: none; }
.gf-drop-menu a:hover { background: rgba(16, 163, 116, 0.09); color: var(--gf-deep); }
.gf-drop-menu a .k { font-family: var(--gf-mono); font-size: 10.5px; color: var(--gf-ink-3); }
.gf-drop-menu .gf-drop-credits b { color: var(--gf-deep); font-weight: 650; font-variant-numeric: tabular-nums; }
/* Group headers in the account dropdown (Workspace / Account), mirroring the
   account rail's .grp labels so the menu reads as the same grouped structure. */
.gf-drop-menu .gf-drop-grp { display: block; font-size: 10.5px; font-weight: 560; color: var(--gf-ink-3);
  text-transform: uppercase; letter-spacing: 0.07em; padding: 10px 12px 4px; }
.gf-drop-menu .gf-drop-credits + .gf-drop-grp, .gf-drop-menu .gf-drop-grp:first-child { padding-top: 4px; }
/* Uniform item rhythm: the group separators are a hairline with only a hair of
   margin, so items read as one evenly spaced list, not gapped-apart clusters. */
.gf-drop-menu .sep { height: 1px; background: rgba(10, 92, 66, 0.09); margin: 3px 10px; }
.gf-mast-r { margin-left: auto; display: flex; align-items: center; gap: 10px; }
.gf-search {
  display: flex; align-items: center; gap: 8px; min-width: 190px; padding: 7px 12px;
  border-radius: 11px; font-size: 13px; color: var(--gf-ink-3); text-decoration: none;
  background: rgba(255, 255, 255, 0.66);
  box-shadow: inset 0 1px 1px var(--gf-glass-hi), inset 0 -2px 6px rgba(10, 92, 66, 0.08);
}
.gf-kbd { font-family: var(--gf-mono); font-size: 10px; background: #fff; border-radius: 5px; padding: 1px 6px; margin-left: auto; box-shadow: 0 1px 0 rgba(10, 42, 33, 0.14); }
.gf-pill {
  display: flex; align-items: center; gap: 8px; padding: 5px 12px 5px 5px; border-radius: 12px;
  font-size: 13px; font-weight: 500; color: var(--gf-ink); text-decoration: none;
  background: rgba(255, 255, 255, 0.66);
  box-shadow: inset 0 1px 1px var(--gf-glass-hi), inset 0 -2px 6px rgba(10, 92, 66, 0.08);
}
.gf-pill .av {
  width: 26px; height: 26px; border-radius: 8px; color: #fff; display: grid; place-items: center;
  font-size: 10px; font-weight: 650; flex: none;
  background: radial-gradient(120% 130% at 45% -10%, #B9F5D9 0%, #34C393 35%, #0F7B57 70%, #073821 100%);
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.7), inset 0 -3px 6px rgba(4, 38, 27, 0.45);
}
.gf-pill b { font-variant-numeric: tabular-nums; color: var(--gf-deep); font-weight: 600; }
/* Paint-safe signed-in pill. gf-auth-boot.js (sync, in <head>) sets
   html.gf-signedin + --gf-av BEFORE the body parses, so the baked anonymous
   pill's FIRST paint is already the Account pill - no frame can show
   "Sign in" to a signed-in visitor, on any page type. The rules are
   IDEMPOTENT: applied to the React signed-in pill (initials + "Account")
   they render the identical result, so nothing steps when React mounts. */
html.gf-signedin .gf-pill .av { font-size: 0; }
html.gf-signedin .gf-pill .av::after { content: var(--gf-av, "\00B7"); font-size: 10px; font-weight: 650; line-height: 1; }
html.gf-signedin .gf-pill > span:not(.av) { font-size: 0; }
html.gf-signedin .gf-pill > span:not(.av)::after { content: "Account"; font-size: 13px; font-weight: 500; }
/* Account dropdown inside the pill (React pages): same glass menu, right-aligned. */
.gf-pill-wrap { position: relative; }
.gf-pill-wrap .gf-drop-menu { left: auto; right: 0; }

/* ---- Buttons ------------------------------------------------------------- */
.gf-btn {
  display: inline-flex; align-items: center; gap: 8px; border: 0; cursor: pointer;
  border-radius: var(--gf-r-btn); padding: 13px 24px; font-family: inherit;
  font-size: 14.5px; font-weight: 570; text-decoration: none; position: relative;
  transition: background .15s, box-shadow .15s, transform .15s;
}
.gf-btn.sm { padding: 9px 17px; font-size: 13.5px; border-radius: 12px; }
.gf-btn.primary {
  color: #fff;
  background: linear-gradient(180deg, #12916A, #0D6B4D);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.35), 0 10px 26px rgba(13, 107, 77, 0.35);
}
/* Buttons respond on hover: the green brightens and lifts, the glass fills in.
   Both had no hover state before (home hero + sample-report CTA read as dead). */
.gf-btn.primary:hover {
  background: linear-gradient(180deg, #14A078, #0F7A58); transform: translateY(-1px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.42), 0 14px 34px rgba(13, 107, 77, 0.45);
}
.gf-btn.primary:active { transform: translateY(0); }
.gf-btn.glass {
  color: var(--gf-deep); background: rgba(255, 255, 255, 0.52);
  border: 1px solid rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85), 0 6px 18px rgba(10, 92, 66, 0.10);
}
.gf-btn.glass:hover {
  background: rgba(255, 255, 255, 0.88); transform: translateY(-1px);
  box-shadow: inset 0 1px 0 #fff, 0 12px 28px rgba(10, 92, 66, 0.18);
}
.gf-btn.glass:active { transform: translateY(0); }
.gf-btn.quiet {
  color: var(--gf-deep); background: rgba(255, 255, 255, 0.88);
  box-shadow: inset 0 1px 1px #fff, inset 0 -3px 8px rgba(10, 92, 66, 0.12), 0 4px 12px rgba(10, 92, 66, 0.10);
}
.gf-btn:focus-visible, a:focus-visible, button:focus-visible { outline: 2px solid var(--gf-accent); outline-offset: 2px; }

/* ---- Eyebrow badge ------------------------------------------------------- */
.gf-eyebrow {
  display: inline-flex; align-items: center; gap: 8px; padding: 6px 14px; border-radius: 999px;
  font-size: 12.5px; font-weight: 550; color: var(--gf-deep);
  background: rgba(255, 255, 255, 0.55); border: 1px solid rgba(255, 255, 255, 0.85);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85);
}
.gf-eyebrow .dot { width: 7px; height: 7px; border-radius: 50%; background: var(--gf-bright); box-shadow: 0 0 0 3px rgba(52, 195, 147, 0.25); }

/* ---- The big white pieces ------------------------------------------------
   White data cards and browser frames: faint sage sheen + fine grain of
   their own. Children get z-index via .gf-card > * so texture stays under. */
.gf-card {
  position: relative; background: var(--gf-white); border-radius: var(--gf-r-card); overflow: hidden;
  box-shadow: var(--gf-sh-card);
}
.gf-card > * { position: relative; z-index: 1; }
.gf-card-h { display: flex; justify-content: space-between; align-items: center; padding: 13px 18px; font-weight: 620; font-size: 14px; border-bottom: 1px solid var(--gf-hair); }
.gf-card-h .act { font-size: 12.5px; color: var(--gf-accent); font-weight: 560; text-decoration: none; }

/* Browser frame (the product-shot chrome): exactly three traffic lights. */
/* A uniform 1px hairline on all four edges so the TOP edge reads as defined as
   the bottom (which the drop shadow alone was darkening); the frame no longer
   looks fainter at the top than the bottom. */
.gf-frame { position: relative; background: var(--gf-white); border-radius: var(--gf-r-frame); overflow: hidden;
  border: 1px solid rgba(10, 42, 33, 0.09);
  box-shadow: 0 16px 44px rgba(10, 42, 33, 0.16); }
.gf-frame::before { content: ""; position: absolute; inset: 0; pointer-events: none; z-index: 0;
  background: radial-gradient(120% 90% at 88% -10%, rgba(157, 224, 193, 0.16), transparent 58%),
              radial-gradient(90% 70% at 0% 110%, rgba(157, 224, 193, 0.10), transparent 55%); }
.gf-frame > * { position: relative; z-index: 1; }
.gf-frame-bar { display: flex; align-items: center; gap: 7px; padding: 12px 16px; border-bottom: 1px solid var(--gf-hair-2); }
.gf-frame-bar .d { width: 10px; height: 10px; border-radius: 50%; flex: none;
  box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.5), inset 0 -1px 2px rgba(0, 0, 0, 0.15); }
.gf-frame-bar .d.r { background: #FF5F57; }
.gf-frame-bar .d.y { background: #FEBC2E; }
.gf-frame-bar .d.g { background: #28C840; }
.gf-frame-bar .addr { margin-left: auto; font-family: var(--gf-mono); font-size: 11px; color: var(--gf-ink-3); white-space: nowrap; }

/* ---- Feature slab: B1's plain frosted stage. No textures, no marbling. */
.gf-slab-sage { position: relative; border-radius: var(--gf-r-slab); overflow: hidden;
  background: linear-gradient(150deg, rgba(255, 255, 255, 0.6), rgba(255, 255, 255, 0.28));
  border: 1px solid rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(22px) saturate(1.7); -webkit-backdrop-filter: blur(22px) saturate(1.7);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85), inset 0 -30px 60px rgba(255, 255, 255, 0.15), 0 30px 80px rgba(10, 92, 66, 0.20); }

/* ---- Glass stat tiles ----------------------------------------------------- */
.gf-tile { border-radius: var(--gf-r-tile); padding: 18px 20px;
  background: rgba(255, 255, 255, 0.52); border: 1px solid rgba(255, 255, 255, 0.85);
  backdrop-filter: blur(16px) saturate(1.5); -webkit-backdrop-filter: blur(16px) saturate(1.5);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.85), 0 10px 28px rgba(10, 92, 66, 0.10); }
.gf-tile .n { font-size: 27px; font-weight: 650; letter-spacing: -0.02em; font-variant-numeric: tabular-nums; color: var(--gf-deep); }
.gf-tile .l { font-size: 12.5px; color: var(--gf-ink-2); margin-top: 3px; }
/* Account top metric tiles: the SAME solid white card material as the match
   report cards below them (was frosted-translucent, which read as a different
   surface). One white card vocabulary down the whole account column. */
.gf-tile.metric { border-radius: var(--gf-r-card); padding: 16px 18px;
  background: var(--gf-white); border: 0; backdrop-filter: none; -webkit-backdrop-filter: none;
  box-shadow: 0 1px 0 rgba(255, 255, 255, 0.9), 0 14px 36px rgba(10, 42, 33, 0.08); }
.gf-tile.metric .n { font-size: 24px; }
.gf-tile.metric .n small { font-size: 12px; color: var(--gf-ink-3); font-weight: 450; }
.gf-tile.metric .l { font-size: 12px; font-weight: 500; margin-top: 0; }

/* ---- Verdict chips + fit bars --------------------------------------------- */
.gf-verd { display: inline-block; border-radius: 999px; font-size: 11.5px; font-weight: 560; padding: 3px 11px;
  background: linear-gradient(180deg, #E8F7F0, #D5EFE3); color: var(--gf-deep);
  box-shadow: inset 0 1px 0 #fff, inset 0 -1px 2px rgba(10, 92, 66, 0.12); }
.gf-verd.w { background: linear-gradient(180deg, var(--gf-warn-bg-1), var(--gf-warn-bg-2)); color: var(--gf-warn);
  box-shadow: inset 0 1px 0 #fff, inset 0 -1px 2px rgba(163, 79, 56, 0.15); }
.gf-verd.mute { background: #F0F3F1; color: var(--gf-ink-3); box-shadow: none; }
.gf-fitbar { display: inline-block; width: 46px; height: 6px; border-radius: 4px; background: #E4EEE9;
  overflow: hidden; vertical-align: 2px; box-shadow: inset 0 1px 2px rgba(10, 42, 33, 0.12); }
.gf-fitbar i { display: block; height: 100%; border-radius: 4px;
  background: linear-gradient(90deg, #0F7B57, #34C393); box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.5); }
.gf-fitbar.w i { background: linear-gradient(90deg, #C97F5F, #A34F38); }
.gf-fit { font-weight: 650; font-variant-numeric: tabular-nums; color: var(--gf-deep); }
.gf-fit.w { color: var(--gf-warn); }

/* ---- Data tables (inside cards/frames) ------------------------------------ */
.gf-table { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.gf-table th { text-align: left; font-size: 10.5px; text-transform: uppercase; letter-spacing: 0.06em;
  color: var(--gf-ink-3); padding: 11px 16px; border-bottom: 1px solid var(--gf-hair-2); font-weight: 560; }
.gf-table td { padding: 14px 16px; border-bottom: 1px solid #EFF4F1; }
.gf-table tr:last-child td { border-bottom: 0; }

/* Row lists (account cards): grid rows with hover. Pages set columns inline. */
.gf-row { display: grid; gap: 12px; align-items: center; padding: 12px 18px;
  border-bottom: 1px solid #F0F5F2; font-size: 13.5px; }
.gf-row:last-child { border-bottom: 0; }
.gf-row:hover { background: #F8FBF9; }
.gf-row .t { font-weight: 570; }
.gf-row .s { font-size: 12px; color: var(--gf-ink-3); margin-top: 1px; }
.gf-mono { font-family: var(--gf-mono); font-size: 12px; color: var(--gf-ink-2); font-variant-numeric: tabular-nums; }
.gf-chev { color: var(--gf-ink-3); text-align: center; }

/* ---- Account rail ---------------------------------------------------------- */
.gf-rail { padding-top: 6px; }
.gf-rail .grp { font-size: 11px; font-weight: 560; color: var(--gf-ink-3); text-transform: uppercase;
  letter-spacing: 0.06em; padding: 16px 12px 7px; }
.gf-rail .grp:first-child { padding-top: 0; }
.gf-rail a { display: flex; align-items: center; gap: 9px; padding: 8px 12px; border-radius: 11px;
  font-size: 13.5px; font-weight: 500; color: var(--gf-ink-2); margin: 1px 0; text-decoration: none; }
.gf-rail a:hover { background: rgba(255, 255, 255, 0.55); }
.gf-rail a.on { background: rgba(255, 255, 255, 0.85); color: var(--gf-deep); font-weight: 560;
  box-shadow: inset 0 1px 1px #fff, inset 0 -2px 6px rgba(10, 92, 66, 0.08), 0 3px 12px rgba(10, 92, 66, 0.10); }
.gf-rail .dot { width: 6px; height: 6px; border-radius: 50%; background: currentColor; opacity: 0.4; flex: none; }
.gf-rail a.on .dot { background: var(--gf-bright); opacity: 1; box-shadow: 0 0 8px rgba(52, 195, 147, 0.8); }

/* ---- Form controls ---------------------------------------------------------- */
.gf-input, .gf-textarea, .gf-selw select {
  font-family: inherit; font-size: 14px; color: var(--gf-ink); width: 100%;
  background: rgba(255, 255, 255, 0.8); border: 0; border-radius: 11px; padding: 12px 14px; outline: 0;
  box-shadow: inset 0 1px 1px var(--gf-glass-hi), inset 0 -2px 6px rgba(10, 92, 66, 0.08), 0 1px 0 rgba(10, 92, 66, 0.06);
  transition: box-shadow .15s;
}
.gf-input:focus, .gf-textarea:focus, .gf-selw select:focus {
  box-shadow: inset 0 1px 1px var(--gf-glass-hi), inset 0 -2px 6px rgba(10, 92, 66, 0.08), 0 0 0 3px rgba(16, 163, 116, 0.18); }
.gf-textarea { resize: vertical; min-height: 120px; line-height: 1.55; }
.gf-selw { position: relative; }
.gf-selw select { appearance: none; -webkit-appearance: none; cursor: pointer; padding-right: 32px; }
.gf-selw::after { content: ""; position: absolute; right: 14px; top: 50%; width: 7px; height: 7px;
  border-right: 1.5px solid var(--gf-ink-3); border-bottom: 1.5px solid var(--gf-ink-3);
  transform: translateY(-65%) rotate(45deg); pointer-events: none; }
.gf-chip { border: 0; border-radius: 20px; padding: 7px 13px; font-size: 12.5px; font-family: inherit;
  color: var(--gf-ink-2); background: rgba(255, 255, 255, 0.66); cursor: pointer;
  box-shadow: inset 0 1px 1px var(--gf-glass-hi), inset 0 -2px 5px rgba(10, 92, 66, 0.08); transition: all .14s; }
.gf-chip:hover { color: var(--gf-ink); }
.gf-chip.on { background: linear-gradient(180deg, #E8F7F0, #D5EFE3); color: var(--gf-deep); font-weight: 550;
  box-shadow: inset 0 1px 0 #fff, inset 0 -1px 2px rgba(10, 92, 66, 0.15); }

/* ---- Type utilities ------------------------------------------------------------ */
.gf-grad-ink { white-space: nowrap;
  background: linear-gradient(95deg, #0A5C42, #10A374 45%, #4ED9A2 78%);
  -webkit-background-clip: text; background-clip: text; color: transparent; }
.gf-hero { padding: 96px 0 0; }

/* ---- Motion ------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  .gf-drop-menu { transition: none; }
  .gf-nav > a, .gf-chip, .gf-input, .gf-textarea { transition: none; }
}

.gf-grain::after { content: none; }
