/* ===========================================================================
   COUNTERPIVOT HUB, DESIGN SYSTEM
   (brand name lives only in config.js + logo.svg)

   DIRECTION: "THE MIDNIGHT DOCKET"
   This market runs on coded instruments: a solicitation is a title, an
   identifier, a NAICS code and a closing clock. The whole site now works the
   way that market is actually watched: after hours, on a dark desk, on a live
   board. One continuous midnight ground runs under every page; sections are
   not stacked rectangles of different colours but pools of light on the same
   material. Panels are glass lifted off the ground; every coded value is set
   in the data face and the data itself is what glows.

   THREE TYPEFACES, THREE JOBS (unchanged)
     --f-display  Archivo, widened (wdth 112..120) and heavy. Monumental,
                  signage-derived. Headlines and figures only.
     --f-body     Public Sans. The U.S. Web Design System's own face, the
                  typeface of the government this curriculum is about.
     --f-mono     IBM Plex Mono. Every coded value: tier codes, counts, prices,
                  deadlines, opportunity numbers. Never used decoratively.

   COLOUR
     CounterPivot's navy / green / grey, redistributed again. Navy is now the
     room itself. Green is the live signal: grants, active state, progress,
     the light the board runs on. A steel blue within the navy family marks
     the contract half of the market. Gold stays reserved for the certificate
     register, and nothing else. Paper survives only where a thing IS a
     document: the certificate cards, lit like paper on the dark desk.

   CONTRAST RULES (re-derived for the dark ground, still enforced)
     · green-500 and gold-500 remain FILLS AND ICON SHAPES on light surfaces
     · on the dark ground, measured on the glass panel (#192739 effective):
         on-navy 11.5:1 · on-navy-soft 8.1:1 · on-navy-mute 6.2:1
         green-400 8.5:1 · gold-500 7.0:1 · steel 7.1:1 · danger-300 6.8:1
     · button ink #08172A on green-500 7.5:1, on gold-500 8.4:1
     · every text/background pair is >= 4.5:1, every meaningful icon >= 3:1

   DEPTH
     No surface is a flat fill. The ground carries two fixed off-axis glows
     and a grain plate; heroes and deep sections add a ruled plotting grid;
     every raised panel is a translucent glass step with a lit top edge and a
     doubled shadow. Light arrives from the content, not from a lamp.
   =========================================================================== */

:root{
  color-scheme:dark;

  /* ------------------------------------------------ navy: the room itself */
  --abyss:#050C17;      /* the floor beneath everything                       */
  --navy-950:#08172A;
  --navy-900:#0E2038;   /* opaque panels: modals, menus, form controls        */
  --navy-800:#132B48;
  --navy-700:#1B3A5C;
  --navy-600:#27527E;   /* the blue glow partner, never text                  */
  --navy-100:#DDE5F1;
  --navy-050:#EAEFF7;
  --navy-line:#C2CFE0;

  /* --------------------------------------- steel: the contract half, blue */
  /* The navy family, promoted to a signal. Text-safe on every dark surface:
     8.5:1 on navy-950, 7.1:1 on the glass panel. */
  --steel-400:#A9CBEF;  /* contract figures, the brighter step                */
  --steel-500:#8FB6E0;  /* contract accent: dots, spines, chips               */

  /* ------------------------------------------------------- brand green */
  --green-500:#79B928;  /* THE brand green: fills, progress, logo emblem      */
  --green-400:#94D53C;  /* green as text on dark, 8.5:1 on the glass panel    */
  --green-700:#456E15;  /* green as text on the light document cards          */
  --green-800:#3E6612;
  --green-050:#EFF7E2;
  --green-line:#CCE2A8;

  /* --------------------------- gold: the certificate register, and nothing else */
  --gold-500:#E8A33D;   /* seals, ratings, badges; text-safe on dark, 7.0:1   */
  --gold-300:#F2C784;   /* gold prose on dark gold-tinted panels, 7.7:1       */
  --gold-600:#B8801F;
  --gold-700:#9A6A15;
  --gold-800:#8A5D10;   /* the only gold usable as text on the gold tint      */
  --gold-050:#FCF3E5;
  --gold-line:#EBD2A0;

  /* ------------------------------------------------------------ surfaces */
  /* The glass steps. Two translucent lifts over the ground, plus one opaque
     panel for the things that must not let the page bleed through: modals,
     dropdown menus, form controls. */
  --panel:linear-gradient(168deg, rgba(255,255,255,.075), rgba(255,255,255,.035));
  --panel-2:linear-gradient(168deg, rgba(255,255,255,.11), rgba(255,255,255,.05));
  --panel-solid:#0E2038;
  --panel-line:rgba(255,255,255,.13);       /* the standing hairline on glass */
  --panel-line-strong:rgba(255,255,255,.22);
  --hairline:rgba(255,255,255,.10);         /* section separations            */

  /* Paper survives as the material of DOCUMENTS: certificate cards only. */
  --paper:#E7EBF1;
  --paper-2:#DDE3EC;
  --white:#FFFFFF;
  --page:var(--paper);
  --cream:var(--paper-2);

  /* ---------------------------------------------------------------- text */
  --ink-900:#0C1A2B;    /* body text on the paper documents                   */
  --ink-700:#33465B;
  --ink-500:#556577;
  --line:#CBD3DF;       /* hairline on the paper documents                    */
  --neutral-050:#E4E8EF;
  --danger:#B3261E;     /* danger on light (document) surfaces                */
  --danger-300:#F2948C; /* danger as text on dark, 6.8:1 on the glass panel   */

  --on-navy:#D6E2F0;    /* body text on the ground, 13.7:1                    */
  --on-navy-soft:#AEC0D6;/* secondary, 9.7:1                                  */
  --on-navy-mute:#93A8C2;/* tertiary and coded labels, 7.4:1                  */

  /* -------------------------------------------------------- atmosphere */
  /* One grain plate, held once and reused. feTurbulence rather than an image
     so nothing is fetched and it costs no request from file://.             */
  --grain:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='160' height='160' filter='url(%23n)'/%3E%3C/svg%3E");
  /* The ruled plotting field behind heroes and deep pools: a form grid, not
     decoration. */
  --rule-dark:rgba(255,255,255,.05);
  --rule-light:rgba(12,26,43,.045);

  /* --------------------------------------------------------- elevation */
  /* Two shadows per step: a tight contact shadow and a wide ambient one.
     Deeper than the light build; shadow has to work harder on a dark ground. */
  --shadow-xs:0 1px 1px rgba(0,0,0,.25);
  --shadow-sm:0 1px 2px rgba(0,0,0,.3), 0 3px 9px -1px rgba(0,0,0,.28);
  --shadow-md:0 1px 2px rgba(0,0,0,.32), 0 12px 28px -8px rgba(0,0,0,.5);
  --shadow-lg:0 2px 6px rgba(0,0,0,.36), 0 30px 64px -16px rgba(0,0,0,.62);
  --shadow-glow:0 0 0 1px rgba(121,185,40,.32), 0 10px 36px -8px rgba(121,185,40,.3);
  --shadow-glow-steel:0 0 0 1px rgba(143,182,224,.3), 0 10px 36px -8px rgba(143,182,224,.22);
  --edge:inset 0 1px 0 rgba(255,255,255,.85);   /* lit top edge of paper      */
  --edge-dark:inset 0 1px 0 rgba(255,255,255,.09); /* lit top edge of glass   */
  --ring:0 0 0 3px rgba(121,185,40,.30);

  /* Modest radii with lit edges. Zero-radius reads as a broadsheet template;
     a big pill reads as decoration. This is precision, not either of those. */
  --r:10px;
  --r-sm:7px;
  --r-lg:16px;
  --r-btn:6px;

  --ease:cubic-bezier(.22,.68,.24,1);
  --ease-out:cubic-bezier(.16,1,.3,1);

  /* --------------------------------------------------------- typography */
  --f-display:'Archivo','Archivo Expanded','Helvetica Neue',Arial,sans-serif;
  --f-body:'Public Sans','Libre Franklin','Helvetica Neue',Arial,sans-serif;
  --f-mono:'IBM Plex Mono','SF Mono',ui-monospace,Menlo,Consolas,monospace;

  /* One scale, stated once. Every heading on the site is drawn from it. */
  --t-hero:clamp(37px,5.5vw,74px);
  --t-h1:clamp(31px,4.8vw,60px);
  --t-h2:clamp(25px,3.5vw,44px);
  --t-h3:clamp(17px,1.5vw,20px);
  --t-lede:clamp(16.5px,1.75vw,21px);
  --t-code:11.5px;

  --wrap:1220px;
  --gut:clamp(18px,3.6vw,40px);
  --nav-h:70px;
}

/* --------------------------------------------------------------- reset */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;background:var(--abyss)}
body{
  margin:0;color:var(--on-navy);
  font-family:var(--f-body);font-size:16px;line-height:1.62;
  -webkit-font-smoothing:antialiased;text-rendering:optimizeLegibility;overflow-x:hidden;
  /* The room: one continuous midnight ground under every page. Two fixed
     off-axis glows (the green working light top right, the blue ambient low
     left) so scrolling moves the content through the light rather than
     sliding a backdrop behind it. */
  background:
    radial-gradient(110% 70% at 86% -4%, rgba(121,185,40,.11), transparent 55%),
    radial-gradient(120% 80% at -6% 104%, rgba(39,82,126,.38), transparent 60%),
    linear-gradient(172deg, var(--navy-950) 0%, var(--abyss) 62%, #030910 100%);
  background-attachment:fixed;
}
/* Grain over the whole room, at the threshold of visibility. It is what stops
   a large dark area from reading as a dead #hex swatch. */
body::before{
  content:"";position:fixed;inset:0;z-index:0;pointer-events:none;
  background-image:var(--grain);background-size:160px 160px;
  opacity:.05;mix-blend-mode:overlay;
}
body>*{position:relative;z-index:1}

img,svg{max-width:100%}
img{height:auto;display:block}
a{color:var(--green-400);text-underline-offset:2px}
a:hover{color:#fff}

h1,h2,h3,h4{
  font-family:var(--f-display);color:#fff;margin:0 0 .45em;
  font-weight:800;font-stretch:114%;line-height:1.06;letter-spacing:-.032em;
  text-wrap:balance;
}
/* PAGE AND SECTION TITLES take the course player's own heading treatment:
   Archivo at its heaviest, uppercase, wide. It is the most distinctive setting
   in the product, so the marketing pages now open the same way a course does.
   Card titles (h3/h4) stay mixed case: at 15-17px, uppercase stops being
   readable and starts being decoration. */
h1,h2,
.hero h1,.detail-hero h1,.sec-head h2,.track-head h2,.tier-head h2{
  font-weight:900;text-transform:uppercase;letter-spacing:-.015em;
}
.hero h1{letter-spacing:-.02em}
h1{font-size:var(--t-h1);margin-bottom:.32em}
h2{font-size:var(--t-h2)}
h3,h4{font-stretch:104%;letter-spacing:-.022em;line-height:1.2}
h3{font-size:var(--t-h3)}
p{margin:0 0 1em;text-wrap:pretty}

/* The standing intro paragraph under a page title. One rule, so a page head
   never has to carry its own inline type. */
.lede{font-size:var(--t-lede);color:var(--on-navy-soft);max-width:62ch;line-height:1.56}
/* A heading that labels a band inside a page rather than opening it. */
.sub-head{margin-bottom:16px}
.sub-head h2,h2.sub-h{font-size:19px;margin:0}
button{font-family:inherit}
b,strong{font-weight:700}
::selection{background:var(--green-500);color:#08172A}
:focus-visible{outline:2.5px solid var(--green-400);outline-offset:2px;border-radius:5px}
/* The paper documents are the one light surface left, so they carry the
   light-safe focus ring. */
.cert :focus-visible,.tier-cert :focus-visible{outline-color:var(--green-700)}
/* anchors land below the sticky nav */
:target{scroll-margin-top:calc(var(--nav-h) + 20px)}

.wrap{max-width:var(--wrap);margin:0 auto;padding:0 var(--gut)}
.narrow{max-width:920px}
.visually-hidden{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.skip{position:absolute;left:-9999px;top:0;z-index:300;background:var(--green-500);color:#08172A;padding:12px 18px;border-radius:0 0 var(--r-sm) 0;font-weight:700;text-decoration:none}
.skip:focus{left:0}
.hr{height:1px;background:var(--hairline);border:0;margin:0}

/* ===========================================================================
   MOTION, the page-load orchestration
   ---------------------------------------------------------------------------
   The load sequence is pure CSS with animation-fill-mode:both, so the initial
   (hidden) state comes from the keyframe itself. Nothing depends on JS: if
   assets/motion.js never arrives, every element still animates in. JS is only
   used for scroll reveals, and there it ADDS the hidden state before observing,
   so a JS failure leaves the page fully visible rather than blank.

   Elements opt in with .rise and order themselves with --d (their beat in the
   sequence). One rhythm, one easing, used everywhere.
   =========================================================================== */
@keyframes rise{
  from{opacity:0;transform:translate3d(0,22px,0);filter:blur(7px)}
  to  {opacity:1;transform:none;filter:blur(0)}
}
@keyframes draw{ from{transform:scaleX(0)} to{transform:scaleX(1)} }
@keyframes bloom{
  from{opacity:0;transform:scale(.82)}
  to  {opacity:1;transform:none}
}
@keyframes gridin{ from{opacity:0} to{opacity:1} }
/* The urgency pulse: a ring of light leaving a critical deadline's dot. Used
   only where the data itself is urgent; a pulse everywhere is a pulse nowhere. */
@keyframes pulse{
  0%{box-shadow:0 0 0 0 rgba(242,148,140,.55)}
  75%{box-shadow:0 0 0 8px rgba(242,148,140,0)}
  100%{box-shadow:0 0 0 0 rgba(242,148,140,0)}
}

.rise{animation:rise .82s var(--ease-out) both;animation-delay:var(--d,0ms)}

/* Scroll reveals. .reveal is inert until motion.js marks the document, so the
   content is visible by default and only becomes animated once JS is running. */
/* The reveal moves elements with `translate`, NOT `transform`. Several of the
   things that reveal also carry a transform of their own (the ladder's --drop
   offset, a card's hover lift) and a `transform:none` on the revealed state
   would silently cancel them. The individual property composes instead. */
[data-motion="on"] .reveal{opacity:0;translate:0 26px;filter:blur(6px)}
[data-motion="on"] .reveal.in{
  opacity:1;translate:none;filter:blur(0);
  transition:opacity .78s var(--ease-out),translate .78s var(--ease-out),filter .78s var(--ease-out);
  transition-delay:calc(var(--i,0) * 70ms);
}

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *,*::before,*::after{
    animation-duration:.001ms!important;animation-delay:0ms!important;
    transition-duration:.001ms!important;transition-delay:0ms!important;
  }
  [data-motion="on"] .reveal{opacity:1;translate:none;filter:none}
}

/* ============================================================== TOP NAV */
/* Dark glass over the room. min-height is reserved so the JS-rendered nav
   cannot shift the page. */
.nav{
  position:sticky;top:0;z-index:100;min-height:var(--nav-h);
  background:rgba(5,12,23,.72);
  -webkit-backdrop-filter:saturate(160%) blur(16px);backdrop-filter:saturate(160%) blur(16px);
  border-bottom:1px solid var(--hairline);
  transition:box-shadow .25s var(--ease),background .25s var(--ease);
  animation:rise .6s var(--ease-out) both;
}
.nav.is-scrolled{box-shadow:0 1px 0 rgba(255,255,255,.06),0 18px 40px -18px rgba(0,0,0,.7);background:rgba(5,12,23,.88)}
.nav-in{display:flex;align-items:center;gap:14px;height:var(--nav-h)}
.logo-link{display:flex;align-items:center;flex:none;text-decoration:none;border-radius:6px}
/* The lockup is real markup, not an image: the emblem inherits colour and the
   wordmark renders in the display face at any size. */
.lockup{display:inline-flex;align-items:center;gap:10px;line-height:1}
.lockup .emblem{width:34px;height:19.8px;flex:none;color:var(--green-500);display:block;
  filter:drop-shadow(0 0 10px rgba(121,185,40,.35))}
.lockup .word{
  font-family:var(--f-display);font-size:19px;font-weight:500;font-stretch:108%;
  letter-spacing:-.03em;color:#fff;white-space:nowrap;
}
.lockup .word b{font-weight:800}
.lockup.on-dark .word{color:#fff}
@media (max-width:400px){ .lockup .word{font-size:17px} .lockup .emblem{width:30px;height:17.5px} }

.explore{
  display:inline-flex;align-items:center;gap:7px;flex:none;
  background:none;border:0;cursor:pointer;padding:9px 12px;border-radius:var(--r-sm);
  font-size:14px;font-weight:600;color:var(--on-navy);
  transition:background .15s var(--ease),color .15s var(--ease);
}
.explore:hover{background:rgba(255,255,255,.08);color:#fff}
.explore svg{transition:transform .2s var(--ease)}
.explore[aria-expanded="true"]{background:rgba(255,255,255,.08);color:#fff}
.explore[aria-expanded="true"] svg{transform:rotate(180deg)}

.search{position:relative;flex:1;max-width:480px;min-width:0}
.search input{
  width:100%;font:inherit;font-size:14px;padding:11px 16px 11px 42px;
  border:1px solid var(--panel-line);border-radius:999px;
  background:rgba(255,255,255,.055);color:#fff;
  transition:border-color .16s var(--ease),box-shadow .16s var(--ease),background .16s var(--ease);
}
.search input::placeholder{color:var(--on-navy-mute)}
.search input:hover{border-color:var(--panel-line-strong);background:rgba(255,255,255,.08)}
.search input:focus{outline:none;border-color:var(--green-500);background:rgba(255,255,255,.08);box-shadow:var(--ring)}
.search .mag{position:absolute;left:15px;top:50%;transform:translateY(-50%);color:var(--on-navy-mute);pointer-events:none}
.search button[type=submit]{position:absolute;left:-9999px}

.nav-right{display:flex;align-items:center;gap:2px;margin-left:auto;flex:none}
.nav-right a,.nav-right button.linky{
  font-size:14px;font-weight:600;color:var(--on-navy);text-decoration:none;
  padding:9px 12px;border-radius:var(--r-sm);background:none;border:0;cursor:pointer;white-space:nowrap;
  transition:background .15s var(--ease),color .15s var(--ease);
}
.nav-right a:hover,.nav-right button.linky:hover{background:rgba(255,255,255,.08);color:#fff}
/* The current page is marked with the accent rule, not a grey pill: the same
   "you are here" device the eyebrow rule uses further down the page. */
.nav-right a[aria-current="page"]{color:#fff;position:relative}
.nav-right a[aria-current="page"]::after{
  content:"";position:absolute;left:12px;right:12px;bottom:2px;height:2px;
  background:var(--green-500);border-radius:2px;
  box-shadow:0 0 8px rgba(121,185,40,.6);
}

.nav-toggle{display:none;margin-left:auto;background:rgba(255,255,255,.06);border:1px solid var(--panel-line);border-radius:var(--r-sm);width:42px;height:38px;cursor:pointer;align-items:center;justify-content:center;color:#fff}

/* Explore dropdown: an opaque plate, so the page cannot bleed through the
   words. */
.explore-menu{
  position:absolute;left:0;right:0;top:var(--nav-h);
  background:rgba(10,25,44,.97);
  -webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px);
  border-bottom:1px solid var(--panel-line);box-shadow:var(--shadow-lg);display:none;z-index:99;
}
.explore-menu.open{display:block;animation:rise .34s var(--ease-out) both}
.explore-menu .grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:8px;padding:22px 0 26px}
.explore-menu a{
  display:block;padding:13px 15px;border-radius:var(--r-sm);text-decoration:none;color:var(--on-navy);
  border:1px solid transparent;transition:background .15s var(--ease),border-color .15s var(--ease);
}
.explore-menu a:hover{background:rgba(255,255,255,.06);border-color:var(--panel-line)}
.explore-menu a b{display:block;font-family:var(--f-display);font-weight:700;font-stretch:106%;font-size:14.5px;letter-spacing:-.02em;margin-bottom:3px;color:#fff}
/* block, so the blurb and the course count sit on their own lines
   instead of running together mid-sentence */
.explore-menu a span{display:block;font-size:13px;color:var(--on-navy-soft);line-height:1.45}
/* The count is a coded value, so it is set in the data face like every other one */
.explore-menu a .note{margin-top:7px;font-family:var(--f-mono);font-size:11px;letter-spacing:.04em}

@media (max-width:1080px){
  .search{max-width:none}
  .nav-right .hide-md{display:none}
}
@media (max-width:880px){
  .nav-in{gap:10px}
  .nav-toggle{display:inline-flex}
  .explore,.search{display:none}
  .nav-right{display:none;position:fixed;left:0;right:0;top:var(--nav-h);flex-direction:column;
    align-items:stretch;gap:0;background:rgba(8,23,42,.98);border-bottom:1px solid var(--panel-line);
    box-shadow:var(--shadow-lg);padding:8px var(--gut) 18px;max-height:calc(100dvh - var(--nav-h));overflow-y:auto}
  .nav-right.open{display:flex}
  .nav-right a,.nav-right button.linky{padding:14px 6px;border-bottom:1px solid var(--hairline);border-radius:0;text-align:left}
  .nav-right a[aria-current="page"]::after{left:0;right:auto;width:18px;bottom:10px}
  .nav-right .btn{margin-top:14px;text-align:center;justify-content:center}
  .nav-right .hide-md{display:block}
  .m-search{display:block!important}
}
.m-search{display:none;padding:10px 0 14px}

/* ============================================================== BUTTONS */
/* On a dark ground the accent itself is the primary fill, everywhere: the
   strongest call any page makes, in the colour that carries live state. */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:9px;
  font-family:var(--f-body);font-weight:700;font-size:14.5px;line-height:1;letter-spacing:-.005em;
  padding:13px 22px;border-radius:var(--r-btn);border:1.5px solid var(--green-500);cursor:pointer;
  text-decoration:none;background:var(--green-500);color:#08172A;position:relative;overflow:hidden;
  box-shadow:0 2px 6px rgba(0,0,0,.4),0 12px 30px -10px rgba(121,185,40,.45);
  transition:background .18s var(--ease),color .18s var(--ease),border-color .18s var(--ease),
             transform .18s var(--ease),box-shadow .22s var(--ease);
}
/* The sweep: a lighter plate crossing the fill on hover, arriving rather than
   just switching on. z-index:-1 inside the button's own stacking context, so
   the sweep paints over the fill but under the label, which is often a bare
   text node and so cannot be lifted with a z-index of its own. */
.btn{isolation:isolate}
.btn::after{
  content:"";position:absolute;inset:0;z-index:-1;background:#fff;
  transform:translate3d(-101%,0,0);transition:transform .38s var(--ease-out);
}
.btn:hover{color:#08172A;transform:translateY(-1px);
  box-shadow:0 2px 6px rgba(0,0,0,.4),0 16px 38px -10px rgba(121,185,40,.6)}
.btn:hover::after{transform:none}
.btn:active{transform:translateY(0)}
.btn.ghost{background:transparent;color:#fff;border-color:rgba(255,255,255,.34);box-shadow:none}
.btn.ghost::after{background:#fff}
.btn.ghost:hover{color:var(--navy-950);border-color:#fff;box-shadow:var(--shadow-sm)}
.btn.dark{background:var(--abyss);border-color:var(--abyss);color:#fff}
.btn.dark::after{background:var(--green-500)}
.btn.dark:hover{color:#08172A}
.btn.sm{padding:9px 15px;font-size:13px}
.btn.lg{padding:17px 32px;font-size:16px}
.btn.block{width:100%}
.btn[disabled],.btn.is-disabled{opacity:.42;cursor:not-allowed;pointer-events:none}
.btn-row{display:flex;flex-wrap:wrap;gap:11px}
.on-dark .btn.ghost,.sec.dark .btn.ghost,.hero .btn.ghost{color:#fff;border-color:rgba(255,255,255,.36)}
.on-dark .btn.ghost::after,.sec.dark .btn.ghost::after,.hero .btn.ghost::after{background:#fff}
.on-dark .btn.ghost:hover,.sec.dark .btn.ghost:hover,.hero .btn.ghost:hover{color:var(--navy-900);border-color:#fff}

/* ================================================================ CHIPS */
/* Every chip is a coded value, so every chip is set in the data face. */
.chip{
  display:inline-flex;align-items:center;gap:6px;font-family:var(--f-mono);
  font-size:11px;font-weight:500;letter-spacing:.04em;
  padding:5px 11px;border-radius:999px;border:1px solid var(--panel-line);
  background:rgba(255,255,255,.055);color:var(--on-navy-soft);white-space:nowrap;
}
.chip.free{background:rgba(121,185,40,.14);border-color:rgba(148,213,60,.38);color:var(--green-400);font-weight:600}
.chip.live{background:rgba(143,182,224,.12);border-color:rgba(143,182,224,.3);color:var(--steel-400)}
.chip.program{background:rgba(255,255,255,.92);border-color:rgba(255,255,255,.92);color:var(--navy-950);font-weight:600}
.chip.soon,.chip.production{background:rgba(255,255,255,.04);border-color:var(--hairline);color:var(--on-navy-mute)}
.chip.gold{background:rgba(232,163,61,.12);border-color:rgba(232,163,61,.36);color:var(--gold-500)}
.chip.dot::before{content:"";width:6px;height:6px;border-radius:50%;background:currentColor;flex:none}
.chip.free.dot::before{background:var(--green-500);box-shadow:0 0 7px rgba(121,185,40,.8)}

/* filter chips */
.filters{display:flex;flex-wrap:wrap;gap:8px}
.fchip{
  font-family:var(--f-mono);font-size:12.5px;font-weight:500;letter-spacing:.01em;
  padding:9px 15px;border-radius:999px;
  border:1px solid var(--panel-line);background:rgba(255,255,255,.045);color:var(--on-navy);cursor:pointer;white-space:nowrap;
  box-shadow:var(--shadow-xs);
  transition:border-color .16s var(--ease),color .16s var(--ease),background .16s var(--ease),
             box-shadow .16s var(--ease),transform .16s var(--ease);
}
.fchip:hover{border-color:var(--panel-line-strong);color:#fff;background:rgba(255,255,255,.09);transform:translateY(-1px)}
.fchip:active{transform:translateY(0) scale(.97)}
.fchip[aria-pressed="true"]{background:var(--green-500);border-color:var(--green-500);color:#08172A;font-weight:600;
  box-shadow:0 0 0 1px rgba(121,185,40,.3),0 6px 18px -6px rgba(121,185,40,.55)}

/* ============================================================ SECTIONS */
/* Sections are pools of light on one continuous ground, separated by
   hairlines rather than by changes of material. */
.sec{padding:clamp(48px,6.4vw,96px) 0;position:relative}
.sec.tight{padding:clamp(30px,4vw,52px) 0}
/* The lifted band: one glass step up from the room, with its own hairlines,
   so it reads as a distinct plate without breaking the material. */
.sec.tint{
  background:linear-gradient(180deg, rgba(255,255,255,.045), rgba(255,255,255,.02));
  border-block:1px solid var(--hairline);
}
.sec.accent{background:rgba(121,185,40,.07);border-block:1px solid rgba(148,213,60,.22)}

/* The deep pool: the room's darkest reach, with its own glow field, the ruled
   plotting grid, and grain. Three layers, none of them a flat fill. */
.sec.dark{
  background:
    radial-gradient(90% 120% at 88% 0%, rgba(121,185,40,.14), transparent 58%),
    radial-gradient(80% 110% at 4% 100%, rgba(39,82,126,.4), transparent 62%),
    linear-gradient(170deg, rgba(0,0,0,.22), rgba(0,0,0,.42));
  color:var(--on-navy);position:relative;overflow:hidden;isolation:isolate;
  border-block:1px solid var(--hairline);
}
.sec.dark::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(var(--rule-dark) 1px,transparent 1px),
    linear-gradient(90deg,var(--rule-dark) 1px,transparent 1px);
  background-size:74px 74px;
  -webkit-mask-image:radial-gradient(120% 90% at 50% 0%,#000 20%,transparent 78%);
  mask-image:radial-gradient(120% 90% at 50% 0%,#000 20%,transparent 78%);
}
.sec.dark::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:var(--grain);background-size:160px 160px;opacity:.05;
}
.sec.dark h1,.sec.dark h2,.sec.dark h3{color:#fff}
.sec.dark a{color:var(--green-400)}
/* A link that is a button keeps the button's ink; without this, the deep
   pool's link colour outranks .btn and paints green text on the green fill. */
.sec.dark a.btn{color:#08172A}

/* -------------------------------------------------- the docket rail */
/* A section that carries a code gets the rail: the eyebrow sits alone in a
   narrow left column and the heading is indented past it. This is the one
   structural device the page repeats, and it only appears where a section is
   actually coded; a head with no eyebrow stays a plain block. */
/* Scoped to a DIRECT eyebrow child on purpose: .head-row keeps its eyebrow one
   level down inside a wrapper, and must stay a flex row with its action button
   pinned to the far end rather than becoming a rail. */
.sec-head{margin-bottom:clamp(24px,3.2vw,44px)}
.sec-head:has(>.eyebrow){
  display:grid;grid-template-columns:minmax(0,180px) minmax(0,1fr);
  gap:4px clamp(20px,3.4vw,56px);align-items:start;
}
.sec-head:has(>.eyebrow)>.eyebrow{grid-column:1;grid-row:1;margin:0;padding-top:.7em}
.sec-head:has(>.eyebrow)>h2{grid-column:2;grid-row:1}
.sec-head:has(>.eyebrow)>p{grid-column:2}
@media (max-width:820px){
  .sec-head:has(>.eyebrow){grid-template-columns:minmax(0,1fr)}
  .sec-head:has(>.eyebrow)>.eyebrow{grid-column:1;grid-row:auto;padding-top:0;margin-bottom:12px}
  .sec-head:has(>.eyebrow)>h2,.sec-head:has(>.eyebrow)>p{grid-column:1;grid-row:auto}
}
.sec-head h2{font-size:var(--t-h2);margin:0 0 12px}
.sec-head p:not(.eyebrow){color:var(--on-navy-soft);margin:0;max-width:64ch;font-size:15.5px;line-height:1.62}
.sec.dark .sec-head p:not(.eyebrow){color:var(--on-navy-soft)}

/* The eyebrow is a docket code: the data face, and a rule that draws itself in
   on load. The rule is the site's smallest recurring gesture. */
.eyebrow{
  display:flex;align-items:center;gap:11px;
  font-family:var(--f-mono);font-size:var(--t-code);font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--green-400);margin:0 0 14px;line-height:1.4;
}
.eyebrow::before{
  content:"";width:26px;height:2px;flex:none;border-radius:2px;background:var(--green-500);
  box-shadow:0 0 8px rgba(121,185,40,.5);
  transform-origin:left center;animation:draw .7s var(--ease-out) both;animation-delay:var(--d,120ms);
}
.sec.dark .eyebrow,.hero .eyebrow,.detail-hero .eyebrow{color:var(--green-400)}
.head-row{display:flex;align-items:flex-end;justify-content:space-between;gap:18px;flex-wrap:wrap}
.head-row>div{min-width:0}

/* =============================================================== CARDS */
.grid{display:grid;gap:20px}
.g-cards{grid-template-columns:repeat(auto-fill,minmax(266px,1fr))}
.g2{grid-template-columns:repeat(auto-fit,minmax(280px,1fr))}
.g3{grid-template-columns:repeat(auto-fit,minmax(250px,1fr))}

/* A card is a pane of glass lifted off the room. No backdrop-filter here on
   purpose: sixty of these scroll on the finder, and a blur per card is the
   difference between sleek and stuttering. */
.card{
  display:flex;flex-direction:column;background:var(--panel);
  border:1px solid var(--panel-line);border-radius:var(--r);overflow:hidden;
  text-decoration:none;color:inherit;position:relative;
  box-shadow:var(--shadow-sm),var(--edge-dark);
  transition:box-shadow .22s var(--ease),transform .22s var(--ease),border-color .22s var(--ease);
}
/* The accent spine: it grows from the top edge on hover, so a hovered card is
   marked with the same green that marks an active anything else. */
.card::before{
  content:"";position:absolute;left:0;top:0;bottom:0;width:3px;z-index:3;
  background:var(--green-500);box-shadow:0 0 12px rgba(121,185,40,.55);
  transform:scaleY(0);transform-origin:top;
  transition:transform .34s var(--ease-out);
}
a.card:hover{box-shadow:var(--shadow-lg),var(--shadow-glow);border-color:rgba(148,213,60,.4);transform:translateY(-4px)}
a.card:hover::before{transform:scaleY(1)}
.card.is-program{border-color:rgba(232,163,61,.4)}
.card.is-program::before{background:var(--gold-500);box-shadow:0 0 12px rgba(232,163,61,.5);transform:scaleY(1);opacity:.9}

.thumb{position:relative;aspect-ratio:16/9;background:var(--navy-800);overflow:hidden;flex:none;contain:paint}
.thumb svg{position:absolute;inset:0;width:100%;height:100%;display:block;
  transition:transform .5s var(--ease-out)}
a.card:hover .thumb svg{transform:scale(1.035)}
.thumb .badge{
  position:absolute;left:12px;top:12px;z-index:2;font-family:var(--f-mono);font-size:10.5px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;padding:5px 9px;border-radius:5px;
  background:rgba(255,255,255,.95);color:var(--navy-900);box-shadow:var(--shadow-sm);
}
.thumb .badge.gold{background:var(--gold-500);color:#08172A}

.card-body{padding:17px 18px 18px;display:flex;flex-direction:column;flex:1}
.provider{display:flex;align-items:center;gap:8px;margin-bottom:10px}
.provider .mini{width:22px;height:22px;border-radius:var(--r-sm);background:rgba(255,255,255,.07);
  border:1px solid var(--panel-line);flex:none;display:flex;align-items:center;justify-content:center}
.provider .mini svg{width:14px;height:auto;display:block;color:var(--green-500)}
.provider span{font-family:var(--f-mono);font-size:10.5px;letter-spacing:.09em;text-transform:uppercase;color:var(--on-navy-mute)}
/* Titles clamp to 2 lines and blurbs to 2, so every card in a row is the same
   shape and the eye can compare them. .meta takes the slack instead. */
.card h3{
  font-size:16.5px;line-height:1.28;margin:0 0 8px;font-weight:700;font-stretch:104%;letter-spacing:-.024em;
  color:#fff;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
  overflow-wrap:break-word;
}
.card .sub{
  font-size:13.5px;color:var(--on-navy-soft);margin:0 0 13px;line-height:1.5;
  display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;
}
.meta{font-family:var(--f-mono);font-size:11px;letter-spacing:.05em;color:var(--on-navy-mute);
  display:flex;flex-wrap:wrap;gap:4px 8px;margin:auto 0 12px;text-transform:uppercase}
.meta .sep{opacity:.45}
.card-foot{display:flex;align-items:center;justify-content:space-between;gap:10px;flex-wrap:wrap;
  margin-top:auto;padding-top:13px;border-top:1px solid var(--panel-line)}
.price{font-family:var(--f-display);font-weight:800;font-stretch:100%;font-size:17px;
  letter-spacing:-.03em;color:#fff;font-variant-numeric:tabular-nums}

/* rating: gold star ICON, figure in white */
.rating{display:inline-flex;align-items:center;gap:5px;font-family:var(--f-mono);font-size:12px;color:#fff;font-weight:600}
.rating svg{color:var(--gold-500);flex:none}
.rating .learners{color:var(--on-navy-mute);font-weight:400}

/* program part checklist */
.parts{list-style:none;margin:0 0 12px;padding:0;display:flex;flex-direction:column;gap:6px}
.parts li{display:flex;align-items:flex-start;gap:8px;font-size:13px;color:var(--on-navy)}
.parts li svg{flex:none;margin-top:2px}
.parts li.done svg{color:var(--green-400)}
.parts li.pending{color:var(--on-navy-mute)}
.parts li.pending svg{color:var(--on-navy-mute);opacity:.6}

/* ====================================================== CATEGORY TILES */
/* 172px keeps all six categories on one row at the 1220px wrap. */
.cats{display:grid;grid-template-columns:repeat(auto-fit,minmax(172px,1fr));gap:14px}
.cat{
  display:flex;flex-direction:column;padding:22px 19px;border-radius:var(--r);text-decoration:none;
  background:var(--panel);border:1px solid var(--panel-line);color:var(--on-navy);position:relative;overflow:hidden;
  box-shadow:var(--shadow-xs),var(--edge-dark);
  transition:background .18s var(--ease),border-color .18s var(--ease),transform .18s var(--ease),box-shadow .18s var(--ease);
}
.cat:hover{border-color:rgba(148,213,60,.38);color:var(--on-navy);transform:translateY(-3px);box-shadow:var(--shadow-md),var(--edge-dark)}
.cat .ic{width:38px;height:38px;border-radius:var(--r-sm);background:rgba(121,185,40,.13);
  border:1px solid rgba(148,213,60,.32);display:flex;align-items:center;justify-content:center;margin-bottom:14px;
  transition:background .18s var(--ease),border-color .18s var(--ease),box-shadow .18s var(--ease)}
.cat .ic svg{color:var(--green-400)}
.cat:hover .ic{background:var(--green-500);border-color:var(--green-500);box-shadow:0 0 16px rgba(121,185,40,.5)}
.cat:hover .ic svg{color:#08172A}
.cat b{display:block;font-family:var(--f-display);font-weight:700;font-stretch:106%;font-size:15.5px;margin-bottom:6px;letter-spacing:-.024em;line-height:1.2;color:#fff}
.cat span{font-size:13px;color:var(--on-navy-soft);line-height:1.45;display:block}
/* margin-top:auto pins the count to the bottom, so a two-line title cannot
   knock one tile out of alignment with the rest of the row */
.cat .n{font-family:var(--f-mono);font-size:11px;letter-spacing:.06em;color:var(--green-400);font-weight:600;margin-top:auto;padding-top:14px;display:block}

/* =============================================================== TIERS */
/* The catalog is a ladder: one .tier section per rung, each with its own card
   grid, its certificate promise, and, for a rung that is announced but not
   built, a dashed panel instead of an empty grid. */
.tiers{display:block}
.tier{margin:0 0 clamp(40px,5.4vw,72px)}
.tier:last-child{margin-bottom:0}

/* The catalog is banded by funding instrument before it is banded by tier.
   The band head opens a ladder rather than sitting on one, so it reads as a
   chapter plate: a drawn rule above, the eyebrow code, and the band title at
   near-page scale over a breathing space. */
.track-head{
  margin:0 0 34px;padding-top:clamp(30px,4vw,52px);position:relative;
}
.track-head::before{
  content:"";position:absolute;left:0;top:0;height:1px;width:100%;
  background:linear-gradient(90deg,rgba(148,213,60,.5),var(--hairline) 32%,var(--hairline));
}
.tiers > .track-head:first-child{padding-top:0}
.tiers > .track-head:first-child::before{display:none}
.track-head h2{font-size:clamp(26px,3.6vw,42px);margin:0 0 10px;letter-spacing:-.036em}
.track-head > p:last-child{color:var(--on-navy-soft);margin:0;max-width:64ch;font-size:14.5px;line-height:1.6}

.tier-head{
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:18px 34px;align-items:start;
  padding-bottom:20px;margin-bottom:26px;border-bottom:2px solid rgba(255,255,255,.82);
}
@media (max-width:860px){.tier-head{grid-template-columns:minmax(0,1fr)}}
.tier-head h2{font-size:clamp(23px,3.1vw,36px);margin:0 0 10px}
.tier-head .blurb{color:var(--on-navy-soft);margin:0;max-width:62ch;font-size:14.5px;line-height:1.6}
.tier-head .tier-n{margin:14px 0 0;font-family:var(--f-mono);font-size:11.5px;letter-spacing:.08em;
  text-transform:uppercase;font-weight:500;color:var(--on-navy-mute);
  display:flex;align-items:center;gap:10px;flex-wrap:wrap}

/* The certificate promise: a piece of paper on the dark desk. It is the gold
   register, and deliberately the one warm, light object in the band. */
.tier-cert{
  display:flex;align-items:center;gap:14px;
  background:linear-gradient(160deg,#FDF7EC,var(--gold-050));
  border:1px solid var(--gold-line);border-radius:var(--r);padding:14px 17px;
  max-width:350px;justify-self:start;box-shadow:var(--shadow-md),var(--edge);
  color:var(--ink-700);
}
.tier-cert .seal{
  width:42px;height:42px;border-radius:50%;background:var(--gold-500);color:#08172A;
  display:flex;align-items:center;justify-content:center;flex:none;
  box-shadow:0 2px 10px -2px rgba(232,163,61,.7);
}
.tier-cert .seal svg{width:23px;height:23px}
.tier-cert b{
  display:block;font-family:var(--f-mono);font-size:11px;font-weight:600;
  letter-spacing:.1em;text-transform:uppercase;color:var(--gold-800);margin-bottom:4px;
}
.tier-cert > span > span{display:block;font-size:12.5px;color:var(--ink-500);line-height:1.45}
/* a tier that awards a credential it has not named yet: promised, not sold,
   so it stays an outline on the desk rather than a document */
.tier-cert.pending{background:transparent;border-style:dashed;border-color:var(--panel-line-strong);box-shadow:none;color:var(--on-navy-soft)}
.tier-cert.pending .seal{background:rgba(255,255,255,.08);color:var(--on-navy-mute);box-shadow:none}
.tier-cert.pending b{color:var(--on-navy-mute)}
.tier-cert.pending > span > span{color:var(--on-navy-mute)}

/* an announced tier with nothing in it yet */
.tier-locked .tier-head{border-bottom-color:var(--hairline);border-bottom-width:1px;padding-bottom:14px;margin-bottom:16px}
.tier-locked .tier-head .blurb{display:none}
.tier-soon{
  border:1.5px dashed var(--panel-line-strong);border-radius:var(--r);background:rgba(255,255,255,.025);
  padding:clamp(22px,3vw,32px);display:grid;grid-template-columns:minmax(0,1fr) auto;
  gap:18px 28px;align-items:center;
}
@media (max-width:720px){.tier-soon{grid-template-columns:minmax(0,1fr)}}
.tier-soon h3{margin:0 0 8px;font-size:17px;display:flex;align-items:center;gap:9px;color:var(--on-navy-soft)}
.tier-soon h3 svg{color:var(--on-navy-mute);flex:none}
.tier-soon p{margin:0;color:var(--on-navy-mute);font-size:14px;max-width:60ch}

/* the tier chip: quiet, because it repeats on every card in a labelled section */
.chip.tierchip{background:rgba(143,182,224,.12);border-color:rgba(143,182,224,.3);color:var(--steel-400);font-weight:600}

/* a package card states its size instead of enumerating its parts; the parts
   are revealed on the package's own page, never beside it in the catalog */
.packline{
  display:flex;align-items:center;gap:9px;margin:0 0 13px;padding:8px 11px;
  border:1px solid rgba(148,213,60,.32);background:rgba(121,185,40,.12);border-radius:var(--r-sm);
  font-family:var(--f-mono);font-size:11px;letter-spacing:.045em;text-transform:uppercase;
  font-weight:500;color:var(--green-400);
}
.packline svg{flex:none;color:var(--green-400)}

/* ---------------------------------------------- the ladder, on the homepage */
/* Five rungs, three tiers plus the two shelves, on one row at the wrap. The
   row literally steps upward, because the thing it is describing is a ladder:
   the offset is the content, not an effect. It is dropped the moment the row
   wraps, where a stagger would read as a misalignment instead. */
.rungs{display:grid;grid-template-columns:repeat(auto-fit,minmax(206px,1fr));gap:16px;align-items:stretch}
.rung{
  display:flex;flex-direction:column;padding:24px 21px;border-radius:var(--r);
  background:var(--panel);border:1px solid var(--panel-line);color:var(--on-navy);text-decoration:none;
  position:relative;box-shadow:var(--shadow-xs),var(--edge-dark);
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease),transform .18s var(--ease);
}
.rung::before{
  content:"";position:absolute;left:0;right:0;top:0;height:3px;border-radius:var(--r) var(--r) 0 0;
  background:var(--green-500);box-shadow:0 0 12px rgba(121,185,40,.5);
  transform:scaleX(0);transform-origin:left;
  transition:transform .34s var(--ease-out);
}
.rung:hover{border-color:rgba(148,213,60,.4);box-shadow:var(--shadow-md),var(--edge-dark);color:var(--on-navy);transform:translateY(-4px)}
.rung:hover::before{transform:scaleX(1)}
.rung.locked{background:rgba(255,255,255,.02);border-style:dashed;border-color:var(--panel-line-strong);box-shadow:none}
.rung.locked::before{background:var(--on-navy-mute);box-shadow:none}
/* The rung's code and its status chip share one row, and "Outside the ladder"
   is long enough to need two lines in a 206px column. Let the chip wrap onto
   its own line rather than squeezing the code into a three-line stack. */
.rung-top{display:flex;align-items:flex-start;justify-content:space-between;gap:6px 10px;margin-bottom:8px;flex-wrap:wrap}
.rung-top .eyebrow{margin:0;flex:1 1 auto;min-width:0;font-size:10px;letter-spacing:.13em}
.rung-top .eyebrow::before{width:16px}
.rung-top .chip{flex:none}
.rung b{display:block;font-family:var(--f-display);font-size:20px;font-weight:800;font-stretch:108%;letter-spacing:-.03em;margin-bottom:9px;line-height:1.14;color:#fff}
.rung .rb{display:block;font-size:13.5px;color:var(--on-navy-soft);line-height:1.52}
.rung-foot{display:block;margin-top:auto;padding-top:18px}
.rung .rc{
  display:flex;align-items:center;gap:9px;font-family:var(--f-mono);font-size:10.5px;font-weight:600;
  letter-spacing:.08em;text-transform:uppercase;color:var(--gold-500);margin-bottom:9px;line-height:1.35;
}
.rung .rc svg{width:19px;height:19px;flex:none;color:var(--gold-500)}
.rung .rc.pending,.rung .rc.pending svg{color:var(--on-navy-mute)}
.rung .n{display:block;font-family:var(--f-mono);font-size:11px;letter-spacing:.05em;font-weight:600;color:var(--green-400)}
.rung.locked .n{color:var(--on-navy-mute)}
/* --drop is written by app.js from the catalog itself: a tier that awards a
   tier-level credential is a rung and steps up in sequence; a shelf that
   awards none sits at ground level beside the ladder. So the row rearranges
   correctly if tiers are added or removed, and nothing here has to know how
   many there are. */
@media (min-width:1060px){
  .rungs>.rung{transform:translateY(calc(var(--drop,0) * 1px))}
  .rungs>.rung:hover{transform:translateY(calc(var(--drop,0) * 1px - 4px))}
  .rungs{margin-bottom:52px}
}

/* =============================================================== HERO */
/* The brightest pool in the room: the working light. The green glow sits
   behind the docket panel on the right, so the accent lights the thing it is
   pointing at. The base stays translucent; the room continues underneath. */
.hero{
  padding:clamp(56px,8vw,116px) 0 clamp(48px,6.4vw,96px);
  position:relative;overflow:hidden;isolation:isolate;color:var(--on-navy);
  border-bottom:1px solid var(--hairline);
  background:
    radial-gradient(78% 92% at 84% 14%, rgba(121,185,40,.2), transparent 58%),
    radial-gradient(86% 100% at 6% 96%, rgba(39,82,126,.45), transparent 64%);
}
.hero::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(var(--rule-dark) 1px,transparent 1px),
    linear-gradient(90deg,var(--rule-dark) 1px,transparent 1px);
  background-size:82px 82px;
  -webkit-mask-image:radial-gradient(115% 88% at 46% 4%,#000 18%,transparent 76%);
  mask-image:radial-gradient(115% 88% at 46% 4%,#000 18%,transparent 76%);
  animation:gridin 1.5s var(--ease-out) both;
}
.hero::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:var(--grain);background-size:160px 160px;opacity:.055;
}
.hero .wrap{position:relative;z-index:1}
.hero h1{
  font-size:var(--t-hero);letter-spacing:-.045em;line-height:.94;margin:0 0 22px;
  max-width:15ch;color:#fff;font-weight:800;font-stretch:118%;text-wrap:balance;
}
/* The accent half of the promise, in the accent colour, carrying its own
   light. It is the only place the display face is set in green, so it lands. */
.hero h1 .t{color:var(--green-400);text-shadow:0 0 34px rgba(121,185,40,.35)}
.hero .lede{font-size:var(--t-lede);color:var(--on-navy-soft);max-width:50ch;margin:0 0 30px;line-height:1.56}

/* Asymmetric by construction: the promise takes the wide column and the docket
   panel the narrow one, and the panel is pushed down so the two columns do not
   start on the same line. */
.hero-grid{
  display:grid;grid-template-columns:minmax(0,1.34fr) minmax(0,.66fr);
  gap:clamp(28px,4.6vw,72px);align-items:start;
}
.hero-copy{padding-top:clamp(0px,1.2vw,18px)}
.hero-feature{justify-self:end;width:100%;max-width:360px;padding-top:clamp(10px,4.6vw,64px)}
.hero-feature-label{
  display:flex;align-items:center;gap:11px;
  font-family:var(--f-mono);font-size:var(--t-code);font-weight:600;letter-spacing:.16em;
  text-transform:uppercase;color:var(--green-400);margin:0 0 14px;
}
.hero-feature-label::before{
  content:"";width:26px;height:2px;flex:none;border-radius:2px;background:var(--green-500);
  box-shadow:0 0 8px rgba(121,185,40,.5);
  transform-origin:left center;animation:draw .7s var(--ease-out) both;animation-delay:620ms;
}
/* The featured card earns the one backdrop blur on the page: a single pane of
   true glass in the hero's own light. */
.hero-feature .card{
  background:linear-gradient(168deg,rgba(255,255,255,.09),rgba(255,255,255,.035));
  border-color:rgba(255,255,255,.16);color:var(--on-navy);
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  box-shadow:var(--shadow-lg),var(--edge-dark);
}
.hero-feature .card::before{background:var(--green-500)}
.hero-feature .card h3{color:#fff}
.hero-feature .card .sub{color:var(--on-navy-soft)}
.hero-feature .card .provider span{color:var(--on-navy-mute)}
.hero-feature .card .provider .mini{background:rgba(255,255,255,.08);border-color:rgba(255,255,255,.18)}
.hero-feature .card .meta{color:var(--on-navy-mute)}
.hero-feature .card .card-foot{border-top-color:rgba(255,255,255,.16)}
.hero-feature .card .price{color:#fff}
.hero-feature .card .packline{background:rgba(121,185,40,.14);border-color:rgba(121,185,40,.34);color:var(--green-400)}
.hero-feature .card .packline svg{color:var(--green-400)}
.hero-feature .card .chip{background:rgba(255,255,255,.09);border-color:rgba(255,255,255,.2);color:var(--on-navy)}
.hero-feature .card .rating{color:#fff}
.hero-feature .card .rating svg{color:var(--gold-500)}
.hero-feature .card .rating .learners{color:var(--on-navy-mute)}
.hero-feature .card .thumb{background:var(--navy-950)}
.hero-feature a.card:hover{border-color:rgba(148,213,60,.5);box-shadow:var(--shadow-lg),var(--shadow-glow)}

/* below the two-column breakpoint the featured card is redundant with the
   "Start here" rail further down the page, so it steps aside */
@media (max-width:940px){
  .hero-grid{grid-template-columns:minmax(0,1fr)}
  .hero-feature{display:none}
  .hero h1{max-width:15ch}
}
.hero-cta{display:flex;align-items:center;gap:14px 26px;flex-wrap:wrap;margin-top:30px}
/* a plain, obvious secondary route; a second button would compete with the first */
.textlink{
  font-weight:700;font-size:15px;color:#fff;text-decoration:none;
  border-bottom:1.5px solid rgba(255,255,255,.3);padding-bottom:2px;
  transition:border-color .18s var(--ease),color .18s var(--ease);
}
.textlink:hover{border-bottom-color:var(--green-400);color:var(--green-400)}
.sec.dark .textlink{color:#fff;border-bottom-color:rgba(255,255,255,.3)}
.sec.dark .textlink:hover{color:var(--green-400);border-bottom-color:var(--green-400)}

/* the hero's primary button is the sitewide primary; nothing to invert now */
.hero .btn.ghost{background:transparent;box-shadow:none}

/* ---------------------------------------- the load sequence, stated in one place */
/* The hero is the site's one orchestrated moment: the ruled field fades up
   under everything, then the promise, the explanation, the call, and last the
   package it is offering. Pure CSS with fill-mode:both; nothing here waits on
   a script, so the sequence survives motion.js failing to load. */
.hero-copy>*{animation:rise .84s var(--ease-out) both}
.hero-copy>h1{animation-delay:110ms}
.hero-copy>.lede{animation-delay:250ms}
.hero-copy>.hero-cta{animation-delay:380ms}
.hero-feature{animation:rise .94s var(--ease-out) both;animation-delay:500ms}

/* social proof */
.proof{display:flex;align-items:center;gap:18px 30px;flex-wrap:wrap;padding:22px 0}
/* Mono, uppercase and widely tracked, this label is far wider than it reads.
   flex:none kept it from wrapping and it was the one thing pushing a 320px
   viewport into horizontal scroll. */
.proof p{margin:0;font-family:var(--f-mono);font-size:11px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--on-navy-mute);flex:1 1 auto;min-width:0;line-height:1.5}
.proof .marks{display:flex;gap:20px;flex-wrap:wrap;align-items:center}
.proof .mark{height:24px;width:80px;border-radius:5px;background:rgba(255,255,255,.06);border:1px solid var(--panel-line)}
.proof .mark:nth-child(2){width:62px}
.proof .mark:nth-child(3){width:94px}
.proof .mark:nth-child(4){width:70px}
.proof .mark:nth-child(5){width:86px}

/* ====================================================== PROGRAM SPOTLIGHT */
.spot{display:grid;grid-template-columns:minmax(0,1.06fr) minmax(0,.94fr);gap:clamp(24px,4vw,60px);align-items:center}
@media (max-width:900px){.spot{grid-template-columns:minmax(0,1fr)}}
.spot>div:first-child h2{font-size:var(--t-h2);margin:0 0 14px}
.spot>div:first-child>p:not(.eyebrow){color:var(--on-navy-soft);font-size:15.5px;max-width:56ch}
.spot-card{background:var(--panel-2);border:1px solid var(--panel-line);border-radius:var(--r-lg);
  padding:8px 24px;box-shadow:var(--shadow-md),var(--edge-dark)}
.spot-parts{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.spot-parts li{display:flex;align-items:center;gap:14px;padding:16px 0;border-bottom:1px solid var(--panel-line)}
.spot-parts li:last-child{border-bottom:0}
.spot-parts .tick{width:28px;height:28px;border-radius:50%;flex:none;display:flex;align-items:center;justify-content:center;
  background:var(--green-500);color:#08172A;box-shadow:0 0 12px rgba(121,185,40,.4)}
.spot-parts li.pending .tick{background:rgba(255,255,255,.08);color:var(--on-navy-mute);box-shadow:none}
.spot-parts .t{min-width:0}
.spot-parts .t b{display:block;font-family:var(--f-display);font-size:15px;font-weight:700;font-stretch:104%;letter-spacing:-.02em;line-height:1.25;margin-bottom:2px;color:#fff}
.spot-parts .t span{font-size:12.5px;color:var(--on-navy-soft);line-height:1.45}
.spot-parts .st{margin-left:auto;flex:none}
/* below ~440px the title, the meta line and the chip fight for one row;
   drop the chip onto its own line, aligned with the text column */
@media (max-width:440px){
  .spot-parts li{flex-wrap:wrap;row-gap:8px}
  .spot-parts .t{flex:1 1 100%}
  .spot-parts .st{margin-left:42px}
}

/* ============================================================= PRICING */
.plans{display:grid;grid-template-columns:repeat(auto-fit,minmax(238px,1fr));gap:18px;align-items:stretch}
.plan{
  display:flex;flex-direction:column;background:var(--panel);border:1px solid var(--panel-line);
  border-radius:var(--r);padding:26px 23px;position:relative;
  box-shadow:var(--shadow-xs),var(--edge-dark);
  transition:box-shadow .2s var(--ease),transform .2s var(--ease),border-color .2s var(--ease);
}
.plan:hover{box-shadow:var(--shadow-md),var(--edge-dark);transform:translateY(-3px);border-color:var(--panel-line-strong)}
/* The recommended plan holds its own light: an opaque deep plate in the green
   working glow. The hierarchy is made of light, not of a 2px border. */
.plan.feat{
  background:
    radial-gradient(90% 70% at 88% 0%, rgba(121,185,40,.2), transparent 62%),
    linear-gradient(168deg, var(--navy-800), var(--navy-950));
  border-color:rgba(148,213,60,.42);color:var(--on-navy);
  box-shadow:var(--shadow-lg),var(--shadow-glow),var(--edge-dark);
}
.plan.feat h3{color:var(--on-navy-mute)}
.plan.feat .amt{color:#fff}
.plan.feat .cad,.plan.feat .blurb{color:var(--on-navy-soft)}
.plan.feat li{color:var(--on-navy)}
.plan.feat li svg{color:var(--green-400)}
.plan .flag{
  position:absolute;top:-11px;left:22px;font-family:var(--f-mono);font-size:10px;font-weight:600;letter-spacing:.12em;
  text-transform:uppercase;background:rgba(255,255,255,.92);color:var(--navy-950);padding:5px 11px;border-radius:999px;
  box-shadow:var(--shadow-sm);
}
.plan.feat .flag{background:var(--green-500);color:#08172A;box-shadow:0 0 14px rgba(121,185,40,.5)}
.plan.start .flag{background:var(--gold-500);color:#08172A}
.plan h3{font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;
  margin:0 0 12px;color:var(--on-navy-mute)}
.plan .amt{font-family:var(--f-display);font-weight:800;font-stretch:104%;font-size:clamp(34px,3.4vw,44px);
  letter-spacing:-.045em;line-height:1;margin-bottom:6px;font-variant-numeric:tabular-nums;overflow-wrap:break-word;color:#fff}
/* "Contact us" is a route, not a figure; set at figure size it wraps to two
   lines and reads as a price with a typo. app.js tags any non-numeric amount. */
.plan .amt.is-words{font-size:clamp(22px,2.1vw,26px);letter-spacing:-.03em;line-height:1.12;padding-top:4px}
.plan .cad{font-family:var(--f-mono);font-size:11px;letter-spacing:.06em;color:var(--on-navy-mute);margin-bottom:16px}
.plan .blurb{font-size:13.5px;color:var(--on-navy-soft);margin:0 0 18px;line-height:1.5}
.plan ul{list-style:none;margin:0 0 22px;padding:0;flex:1;display:flex;flex-direction:column;gap:10px}
.plan li{display:flex;gap:10px;font-size:13.5px;align-items:flex-start;line-height:1.45;color:var(--on-navy)}
.plan li svg{color:var(--green-400);flex:none;margin-top:3px}

/* ======================================================= HOW IT WORKS */
/* Three steps that are a real sequence, so they are numbered. */
.steps{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:18px}
.step{background:var(--panel);border:1px solid var(--panel-line);border-radius:var(--r);padding:22px;
  box-shadow:var(--shadow-xs),var(--edge-dark)}
.sec.dark .step{background:rgba(255,255,255,.055);border-color:rgba(255,255,255,.13);box-shadow:var(--edge-dark)}
.step .n{width:34px;height:34px;border-radius:9px;background:var(--green-500);color:#08172A;
  display:flex;align-items:center;justify-content:center;font-family:var(--f-mono);font-weight:600;font-size:14px;margin-bottom:15px;
  box-shadow:0 0 14px rgba(121,185,40,.35)}
.step h3{font-size:16px;margin:0 0 7px;font-weight:700;color:#fff}
.step p{font-size:13.5px;color:var(--on-navy-soft);margin:0;line-height:1.55}
.step p:last-child{margin:0}
/* These steps are deliberately NOT offset. They are already a numbered
   sequence, and the page only earns one structural device of this kind: the
   tier ladder, where the offset is the subject rather than an effect. */

/* ========================================================= TESTIMONIALS */
.tst{background:var(--panel);border:1px solid var(--panel-line);border-radius:var(--r);padding:24px;
  box-shadow:var(--shadow-xs),var(--edge-dark);position:relative}
.tst .stars{color:var(--gold-500);margin-bottom:14px;display:flex;gap:2px}
.tst p{font-size:15px;margin:0 0 16px;line-height:1.6;color:var(--on-navy)}
.tst .who{font-size:12.5px;color:var(--on-navy-mute)}
.tst .who b{display:block;color:#fff;font-weight:700;font-family:var(--f-display);font-stretch:104%;letter-spacing:-.018em;font-size:14px;margin-bottom:1px}

/* ============================================================== BANNER */
/* The free on-ramp: the one block that sits fully inside the green working
   light, so it reads as an offer rather than as another panel. */
.banner{
  background:
    radial-gradient(85% 130% at 88% -20%, rgba(121,185,40,.24), transparent 60%),
    var(--panel-2);
  border:1px solid rgba(148,213,60,.32);border-radius:var(--r-lg);
  padding:clamp(26px,3.6vw,42px);position:relative;overflow:hidden;
  display:grid;grid-template-columns:minmax(0,1.35fr) minmax(0,.65fr);gap:26px;align-items:center;
  box-shadow:var(--shadow-md),var(--edge-dark);
}
.banner::before{
  content:"";position:absolute;right:-8%;top:-60%;width:56%;aspect-ratio:1;border-radius:50%;
  background:radial-gradient(circle,rgba(121,185,40,.2),transparent 68%);pointer-events:none;
}
.banner>*{position:relative}
@media (max-width:800px){.banner{grid-template-columns:minmax(0,1fr)}}
.banner h2{margin:0 0 10px;font-size:clamp(21px,2.8vw,32px);color:#fff}
.banner p:not(.eyebrow){margin:0;color:var(--on-navy-soft);font-size:14.5px;line-height:1.6;max-width:56ch}
.banner .btn-row{justify-content:flex-start}
@media (min-width:801px){.banner .btn-row{justify-content:flex-end}}

/* ======================================================== COURSE DETAIL */
.detail-hero{
  color:var(--on-navy);padding:clamp(34px,4.8vw,60px) 0;position:relative;overflow:hidden;isolation:isolate;
  border-bottom:1px solid var(--hairline);
  background:
    radial-gradient(70% 100% at 86% 0%, rgba(121,185,40,.16), transparent 60%),
    radial-gradient(80% 110% at 4% 100%, rgba(39,82,126,.42), transparent 64%);
}
.detail-hero::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(var(--rule-dark) 1px,transparent 1px),
    linear-gradient(90deg,var(--rule-dark) 1px,transparent 1px);
  background-size:74px 74px;
  -webkit-mask-image:radial-gradient(110% 92% at 44% 0%,#000 16%,transparent 76%);
  mask-image:radial-gradient(110% 92% at 44% 0%,#000 16%,transparent 76%);
}
.detail-hero::after{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:var(--grain);background-size:160px 160px;opacity:.05;
}
.detail-hero .wrap{position:relative;z-index:1}
.detail-hero .crumb{font-family:var(--f-mono);font-size:11.5px;letter-spacing:.06em;color:var(--on-navy-mute);margin-bottom:18px;line-height:1.7}
.detail-hero .crumb a{color:var(--on-navy);text-decoration:none}
.detail-hero .crumb a:hover{color:var(--green-400);text-decoration:underline}
.detail-hero h1{color:#fff;font-size:var(--t-h1);margin:0 0 14px;max-width:19ch;letter-spacing:-.04em;font-stretch:116%}
.detail-hero .sub{color:var(--on-navy-soft);font-size:var(--t-lede);max-width:58ch;margin:0 0 22px;line-height:1.55}
.detail-hero .facts{display:flex;flex-wrap:wrap;gap:9px 18px;align-items:center;
  font-family:var(--f-mono);font-size:12px;letter-spacing:.05em;color:var(--on-navy)}
.detail-hero .facts>span{display:inline-flex;align-items:center;gap:6px}
.detail-hero .chip{background:rgba(255,255,255,.09);border-color:rgba(255,255,255,.2);color:var(--on-navy)}
.detail-hero .chip.free{background:rgba(121,185,40,.18);border-color:rgba(148,213,60,.45);color:var(--green-400)}
.detail-hero .chip.program{background:var(--green-500);border-color:var(--green-500);color:#08172A}
.detail-hero .rating{color:#fff}
.detail-hero .rating svg{color:var(--gold-500)}
.detail-hero .rating .learners{color:var(--on-navy-mute)}
.detail-grid{display:grid;grid-template-columns:minmax(0,1fr) 356px;gap:clamp(24px,3.6vw,52px);align-items:start;padding:clamp(30px,4vw,52px) 0}
/* Grid items default to min-width:auto, so the scrollable .tabs row inflates
   the 1fr track past the viewport. Pin them to 0 so the track can shrink. */
.detail-grid>*{min-width:0}
@media (max-width:1000px){.detail-grid{grid-template-columns:minmax(0,1fr)}}

/* sticky enrollment card: the one structural pane of glass on this page */
.enroll{
  position:sticky;top:calc(var(--nav-h) + 20px);background:var(--panel-2);
  -webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);
  border:1px solid var(--panel-line-strong);border-radius:var(--r-lg);
  box-shadow:var(--shadow-lg),var(--edge-dark);overflow:hidden;
}
@media (max-width:1000px){.enroll{position:static;margin-bottom:8px}}
.enroll .top{aspect-ratio:16/9;position:relative;background:var(--navy-800)}
.enroll .top svg{position:absolute;inset:0;width:100%;height:100%}
.enroll .in{padding:22px}
.enroll .amt{font-family:var(--f-display);font-weight:800;font-stretch:104%;font-size:34px;letter-spacing:-.045em;line-height:1;margin-bottom:6px;font-variant-numeric:tabular-nums;color:#fff}
.enroll .amt-note{font-family:var(--f-mono);font-size:11px;letter-spacing:.05em;color:var(--on-navy-mute);margin-bottom:18px;line-height:1.5}
.enroll ul{list-style:none;margin:18px 0 0;padding:18px 0 0;border-top:1px solid var(--panel-line);display:flex;flex-direction:column;gap:12px}
.enroll li{display:flex;gap:10px;font-size:13.5px;align-items:flex-start;color:var(--on-navy);line-height:1.45}
.enroll li svg{color:var(--green-400);flex:none;margin-top:3px}
.enroll .fine{font-family:var(--f-mono);font-size:10.5px;letter-spacing:.04em;color:var(--on-navy-mute);margin:16px 0 0;text-align:center;line-height:1.5}

/* tabs */
.tabs{display:flex;gap:2px;border-bottom:1px solid var(--hairline);margin-bottom:28px;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:thin}
.tabs button{
  font-family:var(--f-body);font-size:14px;font-weight:700;color:var(--on-navy-mute);background:none;border:0;
  padding:14px 16px;cursor:pointer;border-bottom:2.5px solid transparent;white-space:nowrap;
  transition:color .16s var(--ease),border-color .16s var(--ease);
}
.tabs button:hover{color:#fff}
.tabs button[aria-selected="true"]{color:#fff;border-bottom-color:var(--green-500)}
.panel[hidden]{display:none}
.panel h2{font-size:clamp(21px,2.4vw,27px);margin:0 0 14px}
.panel h3{font-size:16.5px;margin:26px 0 9px}
.panel>p:not(.eyebrow){color:var(--on-navy-soft);max-width:72ch}

/* learn grid (checkmarks) */
.learn-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(288px,1fr));gap:13px 28px;list-style:none;margin:0;padding:0}
.learn-grid li{display:flex;gap:11px;font-size:14.5px;align-items:flex-start;line-height:1.5;color:var(--on-navy)}
.learn-grid li svg{color:var(--green-400);flex:none;margin-top:4px}

/* syllabus accordion */
.acc{border:1px solid var(--panel-line);border-radius:var(--r);overflow:hidden;box-shadow:var(--shadow-xs),var(--edge-dark);background:var(--panel)}
.acc details{border-bottom:1px solid var(--panel-line)}
.acc details:last-child{border-bottom:0}
.acc summary{
  list-style:none;cursor:pointer;padding:16px 18px;display:flex;align-items:center;gap:13px;
  font-family:var(--f-display);font-weight:700;font-stretch:104%;font-size:15px;letter-spacing:-.02em;color:#fff;
  transition:background .15s var(--ease);
}
.acc summary::-webkit-details-marker{display:none}
.acc summary>span:not(.cnt):not(.tick){min-width:0;overflow-wrap:break-word}
.acc summary:hover{background:rgba(255,255,255,.05)}
.acc details[open] summary{background:rgba(255,255,255,.06);border-left:3px solid var(--green-500);padding-left:15px}
.acc .car{flex:none;color:var(--on-navy-mute);transition:transform .2s var(--ease);margin-left:auto}
.acc details[open] .car{transform:rotate(90deg)}
.acc .cnt{font-family:var(--f-mono);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--on-navy-mute);font-weight:500;flex:none}
.acc .bd{padding:4px 18px 20px}
.acc .bd>p{font-size:13.5px;color:var(--on-navy-soft);margin:0 0 14px;max-width:72ch;line-height:1.6}
.acc ol{list-style:none;margin:0;padding:0}
.acc ol li{display:flex;gap:13px;padding:10px 0;border-top:1px solid var(--hairline);font-size:14px;line-height:1.45;color:var(--on-navy)}
.acc ol li .ln{color:var(--green-400);font-weight:600;font-family:var(--f-mono);font-size:11.5px;min-width:24px;flex:none;padding-top:3px}
.acc ol li .lt{font-weight:600;color:var(--on-navy)}
.acc ol li .ls{color:var(--on-navy-mute)}

/* certificate preview: a document. The one warm, light object in the room,
   lit like paper on the desk. Its text is scoped back to ink on purpose. */
.cert{
  border:1px solid var(--gold-line);
  background:
    radial-gradient(80% 60% at 50% 0%, rgba(232,163,61,.14), transparent 62%),
    linear-gradient(170deg,#FDF8EE,var(--gold-050));
  border-radius:var(--r-lg);padding:clamp(24px,3vw,36px);text-align:center;
  box-shadow:var(--shadow-lg),var(--edge);color:var(--ink-700);
}
.cert .seal{width:58px;height:58px;border-radius:50%;background:var(--gold-500);color:#08172A;
  display:flex;align-items:center;justify-content:center;margin:0 auto 16px;
  box-shadow:0 4px 18px -4px rgba(232,163,61,.8)}
.cert h3{font-size:20px;margin:0 0 8px;color:var(--ink-900)}
.cert .issuer{font-family:var(--f-mono);font-size:10.5px;letter-spacing:.16em;text-transform:uppercase;color:var(--gold-800);font-weight:600;margin-bottom:18px}
.cert ul{list-style:none;margin:0;padding:0;display:inline-flex;flex-direction:column;gap:9px;text-align:left;max-width:100%}
.cert li{display:flex;gap:10px;font-size:13.5px;align-items:flex-start;line-height:1.45;color:var(--ink-900)}
.cert li svg{color:var(--gold-800);flex:none;margin-top:3px}
.cert .fine{font-size:12px;color:var(--ink-500);margin:18px 0 0}

/* Two credentials, side by side: the one this course issues, and the advanced
   one its tier issues when every course in that tier is complete. */
.cert-stack{display:grid;grid-template-columns:repeat(auto-fit,minmax(272px,1fr));gap:16px}
.cert .kicker{
  font-family:var(--f-mono);font-size:10.5px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--ink-500);margin:0 0 8px;
}
.cert.is-tier{
  background:
    radial-gradient(80% 60% at 50% 0%, rgba(232,163,61,.18), transparent 62%),
    linear-gradient(168deg, var(--navy-900), var(--abyss));
  border-color:rgba(232,163,61,.32);color:var(--on-navy);box-shadow:var(--shadow-lg),var(--edge-dark);
}
.cert.is-tier h3{color:#fff}
.cert.is-tier .kicker{color:var(--on-navy-mute)}
.cert.is-tier .issuer{color:var(--gold-500)}
.cert.is-tier li{color:var(--on-navy)}
.cert.is-tier li svg{color:var(--gold-500)}
.cert.is-tier li.pending{color:var(--on-navy-mute)}
.cert.is-tier li.here span{font-weight:700;color:#fff}
.cert.is-tier li em{font-style:normal;color:var(--on-navy-mute);font-weight:400}
.cert.is-tier .fine{color:var(--on-navy-mute)}

/* FAQ */
.faq details{border-bottom:1px solid var(--hairline);padding:2px 0}
.faq summary{cursor:pointer;padding:17px 0;font-weight:700;font-family:var(--f-display);font-stretch:104%;
  letter-spacing:-.02em;font-size:15.5px;list-style:none;display:flex;align-items:flex-start;gap:14px;line-height:1.35;color:#fff}
.faq summary::-webkit-details-marker{display:none}
.faq summary .car{margin-left:auto;color:var(--on-navy-mute);transition:transform .22s var(--ease);flex:none;margin-top:3px}
.faq details[open] summary{color:var(--green-400)}
.faq details[open] summary .car{transform:rotate(45deg);color:var(--green-400)}
.faq .bd{padding:0 0 18px;font-size:14.5px;color:var(--on-navy-soft);max-width:74ch;line-height:1.62}

/* ============================================================ DASHBOARD */
.demo-badge{
  display:flex;align-items:flex-start;gap:13px;
  background:rgba(232,163,61,.09);
  border:1px solid rgba(232,163,61,.32);border-radius:var(--r);padding:15px 18px;margin-bottom:26px;
  box-shadow:var(--shadow-xs),var(--edge-dark);
}
.demo-badge .chip{background:var(--gold-500);border-color:var(--gold-500);color:#08172A;flex:none;font-weight:600}
.demo-badge p{margin:0;font-size:13.5px;color:var(--gold-300);line-height:1.55}
.dash-head{display:flex;align-items:center;gap:18px;flex-wrap:wrap;margin-bottom:30px}
.dash-head .av{width:54px;height:54px;border-radius:14px;color:#fff;flex:none;
  background:linear-gradient(150deg,var(--navy-600),var(--navy-950));
  border:1px solid var(--panel-line);
  display:flex;align-items:center;justify-content:center;font-family:var(--f-display);font-weight:800;font-size:17px;
  box-shadow:var(--shadow-md),var(--edge-dark)}
.dash-head>div{min-width:0}
.dash-head h1{font-size:clamp(23px,3vw,34px);margin:0 0 4px}
.dash-head .sub{font-family:var(--f-mono);font-size:12px;letter-spacing:.05em;color:var(--on-navy-mute)}

.enrolled{display:flex;flex-direction:column;gap:14px}
.erow{
  display:grid;grid-template-columns:180px minmax(0,1fr) auto;gap:22px;align-items:center;
  background:var(--panel);border:1px solid var(--panel-line);border-radius:var(--r);padding:17px;
  box-shadow:var(--shadow-xs),var(--edge-dark);
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease);
}
.erow:hover{border-color:var(--panel-line-strong);box-shadow:var(--shadow-md),var(--edge-dark)}
.erow>*{min-width:0}
@media (max-width:820px){.erow{grid-template-columns:minmax(0,1fr);gap:14px}.erow .ethumb{max-width:240px}}
.ethumb{aspect-ratio:16/9;border-radius:var(--r-sm);overflow:hidden;position:relative;background:var(--navy-800);contain:paint}
.ethumb svg{position:absolute;inset:0;width:100%;height:100%}
.erow h3{font-size:17px;margin:0 0 5px;overflow-wrap:break-word;color:#fff}
.erow .m{font-family:var(--f-mono);font-size:10.5px;letter-spacing:.06em;text-transform:uppercase;color:var(--on-navy-mute);margin-bottom:14px}

/* Progress is light in a channel: the green fill carries its own glow. */
.bar{height:9px;border-radius:99px;background:rgba(255,255,255,.12);overflow:hidden;box-shadow:inset 0 1px 2px rgba(0,0,0,.4)}
.bar i{display:block;height:100%;background:linear-gradient(90deg,var(--green-700),var(--green-400));border-radius:99px;
  box-shadow:0 0 12px rgba(121,185,40,.55);
  transition:width .8s var(--ease-out)}
.bar.navy i{background:linear-gradient(90deg,var(--navy-600),var(--steel-500));box-shadow:0 0 12px rgba(143,182,224,.4)}
.bar.gold i{background:linear-gradient(90deg,var(--gold-700),var(--gold-500));box-shadow:0 0 12px rgba(232,163,61,.5)}
.bar-meta{display:flex;justify-content:space-between;gap:12px;font-family:var(--f-mono);font-size:11px;letter-spacing:.04em;color:var(--on-navy-mute);margin-top:9px;flex-wrap:wrap}

.certcard{
  color:var(--on-navy);border-radius:var(--r-lg);padding:28px;position:relative;overflow:hidden;isolation:isolate;
  border:1px solid rgba(232,163,61,.28);
  background:
    radial-gradient(70% 90% at 88% 0%, rgba(232,163,61,.2), transparent 60%),
    linear-gradient(166deg, var(--navy-900) 0%, var(--navy-950) 58%, var(--abyss) 100%);
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:24px;align-items:center;
  box-shadow:var(--shadow-lg),var(--edge-dark);
}
.certcard::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:var(--grain);background-size:160px 160px;opacity:.05}
@media (max-width:720px){.certcard{grid-template-columns:minmax(0,1fr)}}
.certcard .eyebrow{color:var(--gold-500);margin:0 0 10px}
.certcard .eyebrow::before{background:var(--gold-500);box-shadow:0 0 8px rgba(232,163,61,.5)}
.certcard h3{color:#fff;margin:0 0 8px;font-size:clamp(19px,2.2vw,24px)}
.certcard p:not(.eyebrow){color:var(--on-navy-soft);font-size:13.5px;margin:0 0 16px;line-height:1.55;max-width:60ch}
.certcard .bar{background:rgba(255,255,255,.14);box-shadow:inset 0 1px 2px rgba(0,0,0,.3)}
.certcard .seal{width:68px;height:68px;border-radius:50%;background:var(--gold-500);color:#08172A;
  display:flex;align-items:center;justify-content:center;flex:none;
  box-shadow:0 6px 24px -4px rgba(232,163,61,.65)}

/* rail */
.rail{display:flex;gap:16px;overflow-x:auto;padding:4px 0 10px;-webkit-overflow-scrolling:touch;scroll-snap-type:x mandatory}
.rail>*{flex:0 0 268px;scroll-snap-align:start}

/* =============================================================== MODAL */
.modal{position:fixed;inset:0;z-index:200;display:none;align-items:center;justify-content:center;padding:20px}
.modal.open{display:flex}
.modal-back{position:absolute;inset:0;background:rgba(2,6,12,.72);-webkit-backdrop-filter:blur(5px);backdrop-filter:blur(5px);animation:gridin .3s var(--ease-out) both}
.modal-box{position:relative;background:var(--panel-solid);border:1px solid var(--panel-line-strong);
  border-radius:var(--r-lg);max-width:460px;width:100%;color:var(--on-navy);
  box-shadow:var(--shadow-lg),var(--edge-dark);max-height:92dvh;overflow-y:auto;animation:rise .42s var(--ease-out) both}
.modal-in{padding:30px}
.modal-close{position:absolute;right:12px;top:12px;background:none;border:0;cursor:pointer;color:var(--on-navy-mute);padding:7px;border-radius:8px;line-height:0;z-index:2}
.modal-close:hover{background:rgba(255,255,255,.08);color:#fff}
.modal-box h2{font-size:clamp(20px,2.4vw,24px);margin:0 0 10px;padding-right:28px}
.modal-box p{font-size:14px;color:var(--on-navy-soft);line-height:1.55}
.field{display:block;margin-top:18px}
.field span{font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.09em;text-transform:uppercase;color:var(--on-navy-mute);display:block;margin-bottom:7px}
.field input{width:100%;font:inherit;font-size:15px;padding:13px 14px;border:1px solid var(--panel-line-strong);border-radius:var(--r-sm);
  background:rgba(255,255,255,.055);color:#fff;
  transition:border-color .16s var(--ease),box-shadow .16s var(--ease)}
.field input::placeholder{color:var(--on-navy-mute)}
.field input:focus{outline:none;border-color:var(--green-500);box-shadow:var(--ring)}
.err{color:var(--danger-300);font-size:13px;margin:9px 0 0;display:none}
.err.show{display:block}
.ok-tick{width:56px;height:56px;border-radius:50%;background:var(--green-500);color:#08172A;display:flex;align-items:center;justify-content:center;margin:0 auto 16px;box-shadow:0 4px 18px -4px rgba(121,185,40,.8)}
.srow{display:flex;justify-content:space-between;gap:14px;padding:12px 0;border-bottom:1px solid var(--panel-line);font-size:14px}
.srow:last-of-type{border-bottom:0}
.srow b{font-family:var(--f-mono);font-weight:600;font-variant-numeric:tabular-nums;color:#fff}
.fine{font-size:12px;color:var(--on-navy-mute);text-align:center;margin:14px 0 0}

/* =============================================================== FOOTER */
.foot{
  color:var(--on-navy);padding:clamp(46px,5.4vw,72px) 0 0;margin-top:auto;
  position:relative;overflow:hidden;isolation:isolate;
  border-top:1px solid var(--hairline);
  background:
    radial-gradient(70% 90% at 92% 0%, rgba(121,185,40,.11), transparent 60%),
    radial-gradient(80% 100% at 0% 100%, rgba(39,82,126,.35), transparent 62%),
    linear-gradient(180deg, rgba(0,0,0,.2), rgba(0,0,0,.5));
}
.foot::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(var(--rule-dark) 1px,transparent 1px),
    linear-gradient(90deg,var(--rule-dark) 1px,transparent 1px);
  background-size:74px 74px;
  -webkit-mask-image:radial-gradient(110% 80% at 50% 0%,#000 12%,transparent 72%);
  mask-image:radial-gradient(110% 80% at 50% 0%,#000 12%,transparent 72%);
}
.foot-grid{display:grid;grid-template-columns:1.8fr 1fr 1fr 1fr 1fr;gap:32px;padding-bottom:38px}
@media (max-width:1060px){.foot-grid{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:840px){.foot-grid{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:480px){.foot-grid{grid-template-columns:minmax(0,1fr);gap:26px}}
.foot h4{font-family:var(--f-mono);font-size:10.5px;font-weight:600;letter-spacing:.16em;text-transform:uppercase;color:var(--green-400);margin:0 0 16px}
.foot ul{list-style:none;margin:0;padding:0}
.foot li{margin-bottom:10px}
.foot a{color:var(--on-navy);text-decoration:none;font-size:14px;
  transition:color .15s var(--ease)}
.foot a:hover{color:var(--green-400)}
.foot .blurb{font-size:13.5px;color:var(--on-navy-mute);margin:16px 0 0;max-width:34ch;line-height:1.6}
.foot-bot{border-top:1px solid var(--hairline);padding:20px 0 26px;display:flex;justify-content:space-between;gap:12px;flex-wrap:wrap;
  font-family:var(--f-mono);font-size:11px;letter-spacing:.04em;color:var(--on-navy-mute);line-height:1.6}

/* ================================================================ MISC */
.page{min-height:100dvh;display:flex;flex-direction:column}
.page>main{flex:1}
.count-line{font-family:var(--f-mono);font-size:12.5px;letter-spacing:.03em;color:var(--on-navy-mute);margin:0;line-height:1.7}
.empty{text-align:center;padding:72px 20px;color:var(--on-navy-mute)}
.empty h3{margin-bottom:8px;font-size:20px;color:#fff}
.note{font-family:var(--f-mono);font-size:11px;letter-spacing:.04em;color:var(--on-navy-mute);line-height:1.7}
.tick-list{list-style:none;margin:0;padding:0}
.tick-list li{display:flex;gap:11px;font-size:14.5px;margin-bottom:11px;align-items:flex-start;line-height:1.5;color:var(--on-navy)}
.tick-list li svg{color:var(--green-400);flex:none;margin-top:4px}
.on-dark .tick-list li{color:var(--on-navy)}
.on-dark .tick-list li svg{color:var(--green-400)}

/* A long unbroken token (a course id, a NAICS string, an agency acronym run
   together) must never be the thing that sets a column's minimum width. */
h1,h2,h3,h4,p,li,summary,td,th{overflow-wrap:break-word}


/* ======================================================= FUNDING FINDER */
/* The live board, and the room's showpiece: this is the page the whole
   midnight direction is built around. Everything here is namespaced `gf-` so
   the imported tools cannot collide with the course platform's own
   components, and every colour comes from the palette above.

   ONE COLOUR DECISION RUNS THROUGH THE WHOLE BOARD
     grants (.s-g)     green  : assistance, the money you are awarded
     contracts (.s-c)  steel  : acquisition, the work you are bought for
   It appears on the source tabs, the KPI tiles, the provenance dots, the card
   spine and the card's first chip, so the half of the market a row belongs to
   is legible from any one of them alone and never has to be read. */

.gf-head{display:flex;justify-content:space-between;align-items:flex-end;gap:20px;flex-wrap:wrap}
.gf-head h1{font-size:var(--t-h1);margin:0 0 12px;max-width:22ch}
.gf-head .gf-sub{font-size:14.5px;color:var(--on-navy-soft);margin:0;max-width:74ch;line-height:1.6}
.gf-head .gf-sub b{font-family:var(--f-mono);color:#fff;font-weight:600;font-variant-numeric:tabular-nums}

/* Provenance strip: where the numbers came from and when. */
.gf-source{
  display:flex;flex-wrap:wrap;align-items:center;gap:8px 18px;
  margin:20px 0 0;padding:12px 15px;border:1px solid var(--panel-line);
  border-radius:var(--r);background:var(--panel);box-shadow:var(--shadow-xs),var(--edge-dark);
  font-family:var(--f-mono);font-size:11.5px;letter-spacing:.03em;color:var(--on-navy-mute);
}
/* Each entry is a run of prose with <b> values inside it, so it has to stay a
   TEXT box. As an inline-flex row every text run and every <b> became its own
   flex item, and the line shattered into spaced fragments the moment the strip
   was too narrow to hold an entry whole. The dot is positioned out of flow
   instead of being a flex sibling. */
.gf-source .gf-src{display:block;position:relative;padding-left:15px;min-width:0;max-width:100%}
.gf-source .gf-src b{color:var(--on-navy);font-weight:600;white-space:nowrap}
.gf-source .gf-src::before{
  content:"";position:absolute;left:0;top:.52em;
  width:7px;height:7px;border-radius:50%;background:var(--on-navy-mute);
}
/* Narrow enough that two entries cannot share a line: stack them rather than
   letting one wrap under the other's dot. */
@media (max-width:680px){
  .gf-source{flex-direction:column;align-items:stretch;gap:9px}
}
.gf-source .gf-src.s-g::before{background:var(--green-500);box-shadow:0 0 8px rgba(121,185,40,.6)}
.gf-source .gf-src.s-c::before{background:var(--steel-500);box-shadow:0 0 8px rgba(143,182,224,.5)}

/* Caveats the pull jobs report about themselves. Gold = "read this", not
   "error". Two feeds produce several of these, so they collect into one
   openable panel; stacked banners would push the board off the screen, and
   the summary line still states how many gaps there are while collapsed. */
.gf-notice{
  margin:12px 0 0;padding:12px 16px;
  border:1px solid rgba(232,163,61,.34);background:rgba(232,163,61,.08);
  border-radius:var(--r);box-shadow:var(--shadow-xs),var(--edge-dark);
  font-size:13.5px;color:var(--gold-300);
}
.gf-notice summary{
  display:flex;align-items:center;gap:10px;cursor:pointer;list-style:none;
  font-size:13.5px;color:var(--gold-300);
}
.gf-notice summary::-webkit-details-marker{display:none}
.gf-notice summary b{color:var(--gold-300);font-weight:600}
.gf-notice summary .n{font-family:var(--f-mono);color:var(--gold-500);font-size:11.5px;letter-spacing:.03em}
.gf-notice summary .chev{margin-left:auto;transition:transform .16s var(--ease)}
.gf-notice[open] summary .chev{transform:rotate(180deg)}
.gf-notice summary:focus-visible{outline:2px solid var(--gold-500);outline-offset:3px;border-radius:var(--r-sm)}
.gf-notice ul{margin:11px 0 2px;padding:0 0 0 18px;display:grid;gap:8px}
.gf-notice li{line-height:1.55}
.gf-notice li::marker{color:var(--gold-500)}
.gf-notice b{color:var(--gold-300)}
.gf-notice svg{flex:none;color:var(--gold-500)}

/* ------------------------------------------------------------- KPI row */
/* Five instruments on the desk. The figures are the light source: each
   coloured tile glows in its own signal colour, and the number carries a
   halo of the same light. */
.gf-kpis{display:grid;grid-template-columns:repeat(5,minmax(0,1fr));gap:12px;margin:24px 0 0}
.gf-kpi{background:var(--panel);border:1px solid var(--panel-line);border-radius:var(--r);padding:17px 17px;
  box-shadow:var(--shadow-xs),var(--edge-dark);min-width:0;
  transition:transform .18s var(--ease),box-shadow .18s var(--ease),border-color .18s var(--ease)}
.gf-kpi:hover{transform:translateY(-2px);box-shadow:var(--shadow-md),var(--edge-dark)}
.gf-kpi .v{font-family:var(--f-display);font-size:clamp(24px,2.7vw,34px);font-weight:800;font-stretch:104%;
  letter-spacing:-.042em;color:#fff;font-variant-numeric:tabular-nums;line-height:1.04;overflow-wrap:break-word}
.gf-kpi .l{font-family:var(--f-mono);font-size:10px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;
  color:var(--on-navy-mute);margin-top:7px;line-height:1.4}
.gf-kpi.urgent{background:radial-gradient(120% 130% at 50% -20%, rgba(214,69,58,.16), transparent 70%),var(--panel);
  border-color:rgba(242,148,140,.34)}
.gf-kpi.urgent .v{color:var(--danger-300);text-shadow:0 0 22px rgba(214,69,58,.5)}
/* The two source tiles carry the board's source colours so the split reads
   from the KPI row before anyone reaches the switch below it. */
.gf-kpi.grant{background:radial-gradient(120% 130% at 50% -20%, rgba(121,185,40,.17), transparent 70%),var(--panel);
  border-color:rgba(148,213,60,.34)}
.gf-kpi.grant .v{color:var(--green-400);text-shadow:0 0 22px rgba(121,185,40,.45)}
.gf-kpi.contract{background:radial-gradient(120% 130% at 50% -20%, rgba(143,182,224,.15), transparent 70%),var(--panel);
  border-color:rgba(143,182,224,.32)}
.gf-kpi.contract .v{color:var(--steel-400);text-shadow:0 0 22px rgba(143,182,224,.4)}
@media (max-width:1040px){.gf-kpis{grid-template-columns:repeat(3,minmax(0,1fr))}}
@media (max-width:660px){.gf-kpis{grid-template-columns:repeat(2,minmax(0,1fr))}}
@media (max-width:400px){.gf-kpis{grid-template-columns:minmax(0,1fr)}}

/* --------------------------------------------------- source switch (tabs) */
/* The first decision on the page, and the one that changes what every other
   control means: a full-width band above the layout rather than one more
   select in the filter row. */
.gf-switch{
  display:flex;align-items:center;gap:14px 22px;flex-wrap:wrap;
  margin-top:26px;padding:15px 17px;border:1px solid var(--panel-line);
  border-radius:var(--r-lg);background:var(--panel);box-shadow:var(--shadow-sm),var(--edge-dark);
}
.gf-tabs{display:flex;gap:6px;flex-wrap:wrap;flex:none}
.gf-tab{
  display:inline-flex;align-items:center;gap:9px;font-family:var(--f-mono);font-size:12.5px;font-weight:500;
  letter-spacing:.02em;color:var(--on-navy);background:rgba(255,255,255,.045);border:1px solid var(--panel-line);
  border-radius:999px;padding:9px 15px 9px 14px;cursor:pointer;
  transition:background .14s var(--ease),border-color .14s var(--ease),color .14s var(--ease),
             box-shadow .14s var(--ease),transform .14s var(--ease);
}
.gf-tab:active{transform:scale(.97)}
.gf-tab::before{
  content:"";width:9px;height:9px;border-radius:50%;background:var(--on-navy-mute);
  flex:none;opacity:.5;transition:opacity .12s var(--ease),background .12s var(--ease),box-shadow .12s var(--ease);
}
.gf-tab.s-g::before{background:var(--green-500)}
.gf-tab.s-c::before{background:var(--steel-500)}
.gf-tab .ct{
  font-size:11.5px;font-weight:700;font-variant-numeric:tabular-nums;
  background:rgba(255,255,255,.07);border:1px solid var(--panel-line);border-radius:999px;padding:1px 8px;
}
.gf-tab:hover{border-color:var(--panel-line-strong);color:#fff;background:rgba(255,255,255,.09)}
/* The live tab is the lit tab: an opaque white plate, the brightest object in
   the switch, with the source dot glowing on it. */
.gf-tab[aria-selected="true"]{background:rgba(255,255,255,.93);border-color:rgba(255,255,255,.93);color:var(--navy-950);font-weight:600;box-shadow:var(--shadow-md)}
.gf-tab[aria-selected="true"]::before{opacity:1}
.gf-tab[aria-selected="true"].s-g::before{background:var(--green-500);box-shadow:0 0 7px rgba(121,185,40,.7)}
.gf-tab[aria-selected="true"].s-c::before{background:var(--navy-600);box-shadow:0 0 7px rgba(39,82,126,.6)}
.gf-tab[aria-selected="true"] .ct{background:rgba(8,23,42,.08);border-color:rgba(8,23,42,.18);color:var(--navy-950)}
.gf-switch-note{margin:0;font-size:12.5px;line-height:1.6;color:var(--on-navy-mute);flex:1;min-width:250px}
.gf-switch-note b{color:var(--on-navy);font-weight:600}
@media (max-width:700px){.gf-switch{flex-direction:column;align-items:stretch}}

/* --------------------------------------------------------- page layout */
/* minmax(0,1fr), not 1fr: a bare `1fr` cannot shrink below the results
   column's min-content width, and a long agency name or opportunity number
   was enough to push the whole board past the page gutter. */
.gf-layout{display:grid;grid-template-columns:292px minmax(0,1fr);gap:26px;align-items:start;margin-top:26px}
@media (max-width:1040px){.gf-layout{grid-template-columns:minmax(0,1fr)}}

.gf-panel{background:var(--panel);border:1px solid var(--panel-line);border-radius:var(--r-lg);padding:19px;
  box-shadow:var(--shadow-xs),var(--edge-dark)}
.gf-rail{position:sticky;top:calc(var(--nav-h) + 16px);max-height:calc(100dvh - var(--nav-h) - 32px);overflow-y:auto}
@media (max-width:1040px){.gf-rail{position:static;max-height:none;overflow:visible}}
.gf-rail h2,.gf-filters h2{
  font-family:var(--f-mono);font-size:10.5px;font-weight:600;letter-spacing:.14em;
  text-transform:uppercase;color:var(--on-navy-mute);margin:0 0 14px;
}

/* Archetype rail: the ten funding themes CounterPivot maps clients against.
   Each row's bar is a channel of light, sized to the live count. */
.gf-arow{
  display:grid;grid-template-columns:24px 1fr auto;align-items:center;gap:10px;
  width:100%;text-align:left;padding:8px 9px;border-radius:var(--r-sm);
  border:1px solid transparent;background:transparent;cursor:pointer;font-family:inherit;
  transition:background .12s var(--ease),border-color .12s var(--ease);
}
.gf-arow:hover{background:rgba(255,255,255,.06)}
.gf-arow[aria-pressed="true"]{background:rgba(255,255,255,.09);border-color:var(--panel-line-strong)}
.gf-arow .let{
  font-family:var(--f-mono);font-weight:600;font-size:12.5px;color:var(--steel-400);
  text-align:center;line-height:1;
}
.gf-arow[aria-pressed="true"] .let{color:#fff}
.gf-arow.uni .let{color:var(--green-400)}
.gf-arow .nm{font-size:13px;line-height:1.3;color:var(--on-navy)}
.gf-arow .ct{font-family:var(--f-mono);font-size:11.5px;font-weight:600;color:var(--on-navy-mute);font-variant-numeric:tabular-nums}
.gf-arow .bar{grid-column:2/4;height:4px;border-radius:3px;background:rgba(255,255,255,.09);margin-top:6px;overflow:hidden}
.gf-arow .bar>i{display:block;height:100%;background:var(--green-500);border-radius:3px;box-shadow:0 0 8px rgba(121,185,40,.55)}
.gf-arow[aria-pressed="true"] .bar>i{background:var(--green-400)}
.gf-arow .bar{box-shadow:none}
.gf-clear{
  width:100%;margin-top:10px;padding:9px;border:1px dashed var(--panel-line-strong);background:transparent;
  color:var(--on-navy-mute);border-radius:var(--r-sm);cursor:pointer;font-family:inherit;font-size:12.5px;
}
.gf-clear{font-family:var(--f-mono);letter-spacing:.04em}
.gf-clear:hover:not(:disabled){border-color:rgba(255,255,255,.4);color:#fff;background:rgba(255,255,255,.06)}
.gf-clear:disabled{opacity:.45;cursor:default}

/* ------------------------------------------------------------- filters */
.gf-filters{margin-bottom:16px}
.gf-frow{display:flex;gap:12px;flex-wrap:wrap;align-items:flex-end}
.gf-field{display:flex;flex-direction:column;gap:5px;min-width:0}
.gf-field label{font-family:var(--f-mono);font-size:10px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;color:var(--on-navy-mute)}
/* Opaque controls: the native dropdown inherits the dark scheme, and the page
   must never bleed through a value someone is trying to read. */
.gf-field select,.gf-field input[type=search]{
  font-family:inherit;font-size:13.5px;color:#fff;background:var(--panel-solid);
  border:1px solid rgba(255,255,255,.2);border-radius:var(--r-sm);padding:9px 11px;min-height:40px;max-width:100%;
  transition:border-color .15s var(--ease),box-shadow .15s var(--ease);
}
.gf-field input[type=search]::placeholder{color:var(--on-navy-mute)}
.gf-field select:focus-visible,.gf-field input[type=search]:focus-visible{border-color:var(--green-500);box-shadow:var(--ring);outline:none}
/* On a narrow screen the search field is the only control worth full width;
   a 220px minimum was enough to push the toolbar off a 360px viewport. */
.gf-field input[type=search]{min-width:min(220px,100%)}
@media (max-width:560px){.gf-frow>.gf-field{flex:1 1 100%;min-width:0}.gf-frow>.gf-field select{max-width:none;width:100%}}
/* Agency names run to "National Aeronautics and Space Administration", and an
   auto-sized select takes its width from the longest option, which alone
   pushed the toolbar onto three rows. Capped here, not in the advanced panel,
   where the selects are deliberately full-width. */
.gf-frow>.gf-field select{max-width:230px}
.gf-field select:hover,.gf-field input[type=search]:hover{border-color:rgba(255,255,255,.4)}
.gf-check{
  display:inline-flex;align-items:center;gap:8px;font-size:13px;color:var(--on-navy-soft);
  cursor:pointer;user-select:none;margin-top:12px;
}
.gf-check input{accent-color:var(--green-500);width:15px;height:15px}
.gf-fbottom{display:flex;justify-content:flex-end;margin-top:12px;padding-top:12px;border-top:1px solid var(--panel-line)}
.gf-count{font-family:var(--f-mono);font-size:12.5px;letter-spacing:.03em;color:var(--on-navy-mute);margin:0 0 14px;line-height:1.6}
.gf-count b{color:#fff;font-weight:600;font-variant-numeric:tabular-nums}

/* --------------------------------------------------- opportunity cards */
/* The spine does the work the chip repeats: scanning a mixed list, the eye
   picks up the colour of the left edge long before it reads a label. On the
   dark board the spine is a strip of light with its own halo. */
.gf-card{
  position:relative;overflow:hidden;
  background:var(--panel);border:1px solid var(--panel-line);border-radius:var(--r-lg);
  padding:19px 21px 19px 25px;margin-bottom:12px;box-shadow:var(--shadow-xs),var(--edge-dark);
  transition:border-color .16s var(--ease),box-shadow .16s var(--ease),transform .16s var(--ease);
}
/* The board deals its first hand: the top cards rise in sequence on each
   render. Only the first eight animate; everything deeper arrives instantly,
   so paging in 60 more never replays the whole list. */
#gf-list .gf-card{animation:none}
#gf-list .gf-card:nth-child(-n+8){animation:rise .5s var(--ease-out) both}
#gf-list .gf-card:nth-child(1){animation-delay:0ms}
#gf-list .gf-card:nth-child(2){animation-delay:45ms}
#gf-list .gf-card:nth-child(3){animation-delay:90ms}
#gf-list .gf-card:nth-child(4){animation-delay:135ms}
#gf-list .gf-card:nth-child(5){animation-delay:180ms}
#gf-list .gf-card:nth-child(6){animation-delay:225ms}
#gf-list .gf-card:nth-child(7){animation-delay:270ms}
#gf-list .gf-card:nth-child(8){animation-delay:315ms}
.gf-card::before{content:"";position:absolute;left:0;top:0;bottom:0;width:4px;background:var(--panel-line-strong)}
.gf-card.s-g::before{background:linear-gradient(180deg,var(--green-400),var(--green-700));box-shadow:0 0 14px rgba(121,185,40,.5)}
.gf-card.s-c::before{background:linear-gradient(180deg,var(--steel-400),var(--navy-600));box-shadow:0 0 14px rgba(143,182,224,.4)}
.gf-card:hover{border-color:var(--panel-line-strong);box-shadow:var(--shadow-md),var(--edge-dark);transform:translateY(-2px)}
.gf-card.s-g:hover{border-color:rgba(148,213,60,.36)}
.gf-card.s-c:hover{border-color:rgba(143,182,224,.36)}
.gf-ct{display:flex;justify-content:space-between;gap:10px 16px;align-items:flex-start;flex-wrap:wrap}
/* A basis rather than flex:1: below ~240px of title room the badge, which can
   never wrap, takes its own line instead of crushing the title into a column
   of single letters. */
.gf-cthead{flex:1 1 240px;min-width:0}
.gf-ct>.gf-badge{flex:none;margin-left:auto}
.gf-card h3{font-size:16.5px;line-height:1.28;margin:0 0 6px;overflow-wrap:break-word;letter-spacing:-.024em}
.gf-card h3 a{color:#fff;text-decoration:none;transition:color .14s var(--ease)}
.gf-card h3 a:hover{color:var(--green-400);text-decoration:underline}
.gf-card.s-c h3 a:hover{color:var(--steel-400)}
.gf-agency{font-size:13.5px;color:var(--on-navy-mute);margin:0 0 12px}
.gf-agency .fc{color:var(--on-navy-mute);font-style:italic}

/* Deadline badge. Red at <=30 days, gold at 31 to 60, green further out:
   the same urgency language the certificate/rating chips already use. The
   critical dot pulses; it is the only thing on the board allowed to. */
.gf-badge{
  white-space:nowrap;font-family:var(--f-mono);font-size:11px;font-weight:600;letter-spacing:.04em;
  padding:5px 11px;border-radius:999px;
  display:inline-flex;align-items:center;gap:7px;border:1px solid transparent;
}
.gf-badge .dot{width:7px;height:7px;border-radius:50%;background:currentColor;flex:none}
.gf-b-crit{background:rgba(214,69,58,.14);color:var(--danger-300);border-color:rgba(242,148,140,.38)}
.gf-b-crit .dot{animation:pulse 2.2s var(--ease) infinite}
.gf-b-warn{background:rgba(232,163,61,.12);color:var(--gold-500);border-color:rgba(232,163,61,.38)}
.gf-b-soon{background:rgba(121,185,40,.13);color:var(--green-400);border-color:rgba(148,213,60,.38)}
.gf-b-far,.gf-b-rolling{background:rgba(255,255,255,.05);color:var(--on-navy-mute);border-color:var(--panel-line)}

.gf-meta{display:flex;flex-wrap:wrap;gap:8px 22px;margin:0 0 12px}
.gf-meta>div{min-width:0}
.gf-meta .k{font-family:var(--f-mono);font-size:10px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;color:var(--on-navy-mute)}
.gf-meta .val{font-family:var(--f-mono);font-size:13px;font-weight:600;color:#fff;font-variant-numeric:tabular-nums;overflow-wrap:break-word}
/* NAICS codes and notice types mean nothing to a new entrant on their own, so
   the plain-English gloss travels with the code rather than in a tooltip. */
.gf-meta .val .hint{font-family:var(--f-body);font-weight:400;color:var(--on-navy-mute);font-size:12.5px}

.gf-chips{display:flex;flex-wrap:wrap;gap:6px;margin-top:9px}
.gf-chip{
  font-family:var(--f-mono);font-size:10.5px;letter-spacing:.03em;line-height:1.6;padding:3px 9px;border-radius:var(--r-sm);
  background:rgba(255,255,255,.05);border:1px solid var(--panel-line);color:var(--on-navy-mute);
}
.gf-chip.arch{background:rgba(143,182,224,.12);border-color:rgba(143,182,224,.3);color:var(--steel-400);font-weight:600}
.gf-chip.uni{background:rgba(121,185,40,.12);border-color:rgba(148,213,60,.34);color:var(--green-400);font-weight:600}
/* The source chip is the only solid-filled chip on a card, and it always comes
   first, so "which market is this" is answered before the eye starts reading. */
.gf-chip.src{font-weight:700;letter-spacing:.01em}
.gf-chip.src.s-g{background:var(--green-500);border-color:var(--green-500);color:#08172A}
.gf-chip.src.s-c{background:var(--steel-500);border-color:var(--steel-500);color:#08172A}
.gf-chip.sa{background:rgba(232,163,61,.12);border-color:rgba(232,163,61,.34);color:var(--gold-500);font-weight:600}
.gf-chip.broad{border-style:dashed;background:transparent}
.gf-desc{font-size:13.5px;color:var(--on-navy-soft);line-height:1.6;margin:12px 0 0}
.gf-foot{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-top:14px}
/* Sixty cards must not mean sixty green buttons: on a card, the outbound link
   is a quiet ghost, and the green sweep only arrives on hover. */
.gf-foot .btn{background:transparent;border-color:rgba(255,255,255,.3);color:#fff;box-shadow:none}
.gf-foot .btn::after{background:var(--green-500)}
.gf-foot .btn:hover{color:#08172A;border-color:var(--green-500);box-shadow:var(--shadow-sm)}
/* A SAM.gov "opportunity number" is sometimes a 60-character underscore-joined
   sentence with no break opportunity in it, which on its own set the minimum
   width of the entire results column. It has to be allowed to break. */
.gf-num{font-family:var(--f-mono);font-size:11px;color:var(--on-navy-mute);font-variant-numeric:tabular-nums;
  display:inline-flex;align-items:center;gap:8px;flex-wrap:wrap;min-width:0;
  overflow-wrap:anywhere}
.gf-num a{color:var(--green-400);overflow-wrap:anywhere}
.gf-num .sep{color:var(--panel-line-strong)}

/* The one place a learner crosses from the dashboard back into the courses. */
.gf-bridge{
  display:grid;grid-template-columns:minmax(0,1fr) auto;gap:24px;align-items:center;
  color:var(--on-navy);border-radius:var(--r-lg);padding:30px 32px;margin-top:8px;
  position:relative;overflow:hidden;isolation:isolate;
  border:1px solid var(--panel-line);
  background:
    radial-gradient(70% 100% at 90% 0%, rgba(121,185,40,.18), transparent 60%),
    linear-gradient(166deg, var(--navy-900) 0%, var(--navy-950) 58%, var(--abyss) 100%);
  box-shadow:var(--shadow-lg),var(--edge-dark);
}
.gf-bridge::before{
  content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:
    linear-gradient(var(--rule-dark) 1px,transparent 1px),
    linear-gradient(90deg,var(--rule-dark) 1px,transparent 1px);
  background-size:74px 74px;
  -webkit-mask-image:radial-gradient(120% 100% at 80% 0%,#000 15%,transparent 75%);
  mask-image:radial-gradient(120% 100% at 80% 0%,#000 15%,transparent 75%);
}
.gf-bridge::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;
  background-image:var(--grain);background-size:160px 160px;opacity:.05}
.gf-bridge h2{color:#fff;font-size:clamp(21px,2.5vw,30px);margin:0 0 10px}
.gf-bridge p:not(.eyebrow){color:var(--on-navy-soft);font-size:14.5px;margin:0;max-width:62ch}
@media (max-width:780px){.gf-bridge{grid-template-columns:minmax(0,1fr)}}
.gf-lbl{
  font-family:var(--f-mono);font-size:10px;font-weight:600;letter-spacing:.11em;text-transform:uppercase;
  color:var(--on-navy-mute);align-self:center;margin-right:2px;
}

/* ------------------------------------------- grant finder: advanced filters */
/* Pinned to the right of the filter row so the panel, which hangs off that
   edge, always opens inside the card rather than over the archetype rail. */
.gf-adv-wrap{position:relative;display:flex;align-items:flex-end;margin-left:auto}
.gf-advbtn{
  display:inline-flex;align-items:center;gap:8px;font-family:var(--f-mono);font-size:12.5px;font-weight:600;
  letter-spacing:.02em;color:#fff;background:var(--panel-solid);border:1px solid rgba(255,255,255,.2);
  border-radius:var(--r-sm);padding:9px 13px;min-height:40px;cursor:pointer;white-space:nowrap;
  transition:border-color .15s var(--ease),background .15s var(--ease);
}
.gf-advbtn:hover{background:var(--navy-800);border-color:rgba(255,255,255,.4)}
.gf-advbtn[aria-expanded="true"]{background:var(--navy-800);border-color:rgba(255,255,255,.4)}
.gf-advbtn[aria-expanded="true"] svg{transform:rotate(180deg)}
.gf-advbtn svg{transition:transform .18s var(--ease)}
.gf-advbtn.has-filters{border-color:rgba(148,213,60,.5)}
.gf-advcount{
  display:inline-flex;align-items:center;justify-content:center;min-width:19px;height:19px;padding:0 5px;
  border-radius:999px;background:var(--green-500);color:#08172A;font-size:11px;font-weight:700;
  box-shadow:0 0 10px rgba(121,185,40,.5);
}

/* Anchored to the button and right-aligned so it never runs off the panel.
   Opaque: a filter panel floating over sixty cards cannot be translucent. */
.gf-adv{
  position:absolute;top:calc(100% + 8px);right:0;z-index:60;width:min(520px,calc(100vw - 2 * var(--gut)));
  background:var(--panel-solid);border:1px solid var(--panel-line-strong);border-radius:var(--r-lg);
  box-shadow:var(--shadow-lg),var(--edge-dark);padding:19px;animation:rise .3s var(--ease-out) both;
  /* Two source groups make this panel tall enough to run off a laptop screen. */
  max-height:min(72vh,640px);overflow-y:auto;
}
.gf-adv h3{font-size:14px;margin:0 0 14px;color:#fff}
.gf-advgrid{display:grid;grid-template-columns:1fr 1fr;gap:13px}
.gf-advgrid .gf-field select{width:100%}
@media (max-width:560px){.gf-advgrid{grid-template-columns:1fr}}

/* Half these filters only mean something to one of the two markets. Dimming
   the group that does not apply, rather than hiding it, keeps an active
   filter visible instead of letting it silently empty the board. */
.gf-advgroup{margin-bottom:16px}
.gf-advgh{
  display:flex;align-items:center;gap:8px;margin:0 0 10px;flex-wrap:wrap;
  font-family:var(--f-mono);font-size:10px;font-weight:600;letter-spacing:.12em;text-transform:uppercase;color:var(--on-navy-mute);
}
.gf-advgh .dot{width:8px;height:8px;border-radius:50%;flex:none}
.gf-advgroup[data-for="g"] .gf-advgh .dot{background:var(--green-500);box-shadow:0 0 7px rgba(121,185,40,.6)}
.gf-advgroup[data-for="c"] .gf-advgh .dot{background:var(--steel-500);box-shadow:0 0 7px rgba(143,182,224,.5)}
.gf-advgh .off{display:none;text-transform:none;letter-spacing:0;font-weight:500;color:var(--gold-500)}
.gf-advgroup.is-off{opacity:.5}
.gf-advgroup.is-off .gf-advgh .off{display:inline}
.gf-advgroup.is-off select{cursor:not-allowed}
.gf-advfoot{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-top:16px;
  padding-top:14px;border-top:1px solid var(--panel-line)}
.gf-linkbtn{
  background:none;border:0;padding:0;font-family:var(--f-mono);font-size:12px;font-weight:500;letter-spacing:.02em;
  color:var(--green-400);cursor:pointer;text-decoration:underline;text-underline-offset:3px;
}
.gf-linkbtn:hover{color:#fff}

/* ------------------------------------------------ grant finder: export & picking */
.gf-actions{display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap;margin-bottom:14px}
.gf-actions .gf-count{margin:0}
.gf-actbtns{display:flex;gap:9px;flex-wrap:wrap}
.gf-actbtns .btn{display:inline-flex;align-items:center}

.gf-selbar{
  position:sticky;top:calc(var(--nav-h) + 10px);z-index:50;
  display:flex;justify-content:space-between;align-items:center;gap:14px;flex-wrap:wrap;
  background:linear-gradient(160deg,var(--navy-800),var(--navy-950));color:#fff;
  border:1px solid rgba(148,213,60,.42);
  border-radius:var(--r);padding:13px 17px;margin-bottom:14px;
  box-shadow:var(--shadow-lg),var(--shadow-glow);animation:rise .32s var(--ease-out) both;
}
.gf-selbar b{font-family:var(--f-display);font-weight:800;font-stretch:104%;font-size:16px;letter-spacing:-.03em}
/* A shortlist that spans both markets is the point of the export, so the bar
   says what the mix is before the sheet is opened. */
.gf-selbar .mix{color:var(--on-navy-soft);font-size:13px;margin-left:8px}
.gf-selbar .btn{display:inline-flex;align-items:center}
.gf-selbar .gf-linkbtn{color:var(--on-navy)}
.gf-selbar .gf-linkbtn:hover{color:#fff}

.gf-pick{display:flex;align-items:center;flex:none;padding:2px 4px 0 0;cursor:pointer}
.gf-pick input{width:17px;height:17px;accent-color:var(--green-500);cursor:pointer}
.gf-card.is-picked{border-color:rgba(148,213,60,.55);
  background:linear-gradient(168deg, rgba(121,185,40,.13), rgba(121,185,40,.05));
  box-shadow:var(--shadow-xs),0 0 0 1px rgba(121,185,40,.22),var(--edge-dark)}
.gf-card.is-picked::before{background:var(--green-500);box-shadow:0 0 14px rgba(121,185,40,.6)}
.gf-card.is-picked:hover{border-color:var(--green-400)}

/* A `display` rule outranks the hidden attribute's UA style, so anything the
   Grant Finder toggles with [hidden] has to say so explicitly. */
.gf-advcount[hidden],.gf-selbar[hidden],.gf-adv[hidden]{display:none}


/* ================================================ FINDER: LOCKED TEASER */
/* Non-members see the same board rendered from ten public sample rows,
   blurred, with the unlock panel floating in the green working light. */
.gf-locked #gf-list{filter:blur(9px) saturate(.8);pointer-events:none;user-select:none}
.gf-locked .gf-selbar{display:none}
.gf-lockhost{position:relative}
.gf-unlock{position:absolute;inset:0;z-index:6;display:flex;justify-content:center;
  align-items:flex-start;padding:110px var(--gut) 0;pointer-events:none}
.gf-unlock-card{pointer-events:auto;max-width:440px;text-align:center;padding:30px 28px;
  border-radius:var(--r-lg);
  background:radial-gradient(120% 140% at 50% -20%, rgba(121,185,40,.16), transparent 65%),var(--navy-900);
  border:1px solid rgba(148,213,60,.4);
  box-shadow:var(--shadow-lg),var(--shadow-glow),var(--edge-dark)}
.gf-unlock-card .eyebrow{justify-content:center}
.gf-unlock-card h3{font-size:22px;margin-bottom:10px}
.gf-unlock-card p:not(.eyebrow){color:var(--on-navy-soft);font-size:14px;line-height:1.6}
.gf-unlock-card .btn-row{justify-content:center;margin-top:16px}


/* ============================================= HERO PRICE CARD */
/* The only price list on the homepage: the two ways to buy the ladder, the
   exam, the board, and the free way in. Rows are a two-column grid so the
   figure always sits hard right against its label, whatever the wrap. */
.pricecard{
  background:var(--panel-2);border:1px solid var(--panel-line-strong);
  border-radius:var(--r-lg);padding:22px 22px 18px;
  -webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px);
  box-shadow:var(--shadow-lg),var(--edge-dark);
}
.pricecard .eyebrow{margin-bottom:16px}
.pricelist{list-style:none;margin:0;padding:0}
.pricelist li{
  display:grid;grid-template-columns:1fr auto;gap:0 14px;align-items:baseline;
  padding:12px 0;border-bottom:1px solid var(--panel-line);
  transition:background .16s var(--ease);
}
.pricelist li:last-child{border-bottom:0}
/* The recommended row is lit rather than boxed: same rhythm, more light. */
.pricelist li.is-feat{
  background:linear-gradient(90deg,rgba(121,185,40,.10),transparent 70%);
  border-radius:var(--r-sm);padding-left:12px;padding-right:12px;
  margin:2px -12px;border-bottom-color:transparent;
}
.pl-n{font-size:14.5px;font-weight:600;color:#fff;display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.pl-p{font-family:var(--f-display);font-weight:800;font-size:20px;letter-spacing:-.035em;
  color:#fff;font-variant-numeric:tabular-nums;text-align:right;white-space:nowrap}
.pricelist li.is-feat .pl-p{color:var(--green-400);text-shadow:0 0 20px rgba(121,185,40,.35)}
.pl-s{grid-column:1/-1;font-family:var(--f-mono);font-size:10.5px;letter-spacing:.03em;
  color:var(--on-navy-mute);margin-top:4px;line-height:1.5}
.pl-from{font-family:var(--f-mono);font-size:10px;font-weight:500;letter-spacing:.04em;
  color:var(--on-navy-mute);vertical-align:middle}
.pl-tag{
  font-family:var(--f-mono);font-size:9px;font-weight:600;letter-spacing:.12em;
  padding:3px 7px;border-radius:999px;line-height:1;
  background:rgba(255,255,255,.08);border:1px solid var(--panel-line);color:var(--on-navy-mute);
}
.pl-tag.feat{background:var(--green-500);border-color:var(--green-500);color:#08172A}
.pl-foot{margin-top:18px;padding-top:16px;border-top:1px solid var(--panel-line)}
.pl-foot .btn{margin-bottom:10px}
.pl-fine{margin:0;font-family:var(--f-mono);font-size:10px;letter-spacing:.03em;
  color:var(--on-navy-mute);line-height:1.6;text-align:center}
