/* ================================================================
   FPFX — signed-out pages (login, register, reset, 2FA)

   A SPLIT SCREEN, AND THE HALVES ARE THE OTHER WAY ROUND.
   ----------------------------------------------------------------
   The inherited layout was illustration-LEFT, form-RIGHT, with an
   orbiting cartoon character in the illustration half. This is form
   LEFT, panel RIGHT, and the ordering is not a preference:

     · the tab pill (Sign in / Create account) is the first control on
       the page and has to precede the decorative column in reading
       and tab order, not follow a screenful of scenery;
     · with the form first in the DOM the mobile stack falls out with
       no `order:` property anywhere, so what a screen reader reads and
       what the eye sees can never disagree;
     · and it is the mirror of the inherited composition, which is the
       point — a recolour of that layout would still BE that layout.

   The right half carries the approved brand render
   (assets/images/bull-candlestick.webp) with pointer parallax applied
   TO the render, and five programme-fact cards read from
   challenge_phases crossfading over it. mix-blend-mode:screen is
   MANDATORY on that image: it is a render on a solid black ground and
   without it the panel gets a black rectangle with visible edges.

   Below 1080px the panel demotes rather than stacking: the render
   leaves the flow entirely and becomes a fixed ground layer at
   z-index 0 (zero layout height), and the fact cards collapse to one
   horizontally-scrollable snap strip. Auto-rotation is desktop-only;
   below 1080px the strip is swiped instead. Below 430px the strip
   goes too — a phone keyboard covers it the moment a field is
   focused, so it is height spent on nothing.

   Kept from what this file already shipped: the live market field
   behind everything, the payout proof ticker at the foot, and the
   whole `.fa-*` form vocabulary. What LEFT is `.fa-rail`, the
   hand-rolled status banner — replaced by the shared public header in
   its `auth` variant, whose second tier carries the same status line.
   ================================================================ */
.fpfx-auth{
  /* Height of the shared header on this surface: the 66px .fh-in row plus the
     .fa-tier status line beneath it. It is what the sticky panel offsets
     itself by, and it is a variable rather than a literal so the two numbers
     are stated once. MEASURED, not guessed: 66.0 + 33.8 = 99.8 at 1280x900,
     rounded up so the panel never tucks a pixel under the hairline. */
  --fa-hdr:100px;
  margin:0; padding:0; min-height:100vh; overflow-x:hidden;
  display:flex; flex-direction:column;
  color:var(--text,#F8F8F8);
  font-family:var(--au-body,"DM Sans",system-ui,-apple-system,"Segoe UI",sans-serif);
  line-height:1.6; -webkit-font-smoothing:antialiased;
}
/* THE GROUND IS NOT PAINTED HERE ANY MORE.
   This rule carried `background:var(--bg); background-image:none` — the
   second line added to clear the inherited cool radials, which are gone at
   source now. Both are removed rather than kept, because the ground moved to
   one owner: .au-host in fpfx-aurora.css paints the four-stop hue-30 radial
   AND the single-octave dither that is the only thing removing quantisation
   contours from a ramp this shallow. `background:` is a shorthand, so setting
   it here resets background-image to none and takes the dither with it.

   It was surviving only on load order — fpfx-aurora.css is linked five <link>s
   after this file in portal/_auth-shell.php, so .au-host won at equal
   specificity. That is a race this file should not be entered in at all. The
   fallback below cannot enter it: it only matches when .au-host is absent. */
body:not(.au-host).fpfx-auth{background:var(--bg,#0A0806)}
/* Outfit's inline box is ~1.19em, taller than Inter's; line-height:1.1 clipped
   the descender (clientHeight 25 / scrollHeight 27 at 22.72px). 1.22 clears it
   at every weight and size without changing the card's rhythm noticeably. */
.fpfx-auth h1,.fpfx-auth h2,.fpfx-auth h3{margin:0;line-height:1.22;letter-spacing:-.03em;
  font-family:var(--au-disp,"Outfit",system-ui,sans-serif)}

/* ---------- market field ---------- */
.fa-field{position:fixed;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.fa-field svg{width:100%;height:100%;display:block;opacity:.5}
.fa-grid line{stroke:rgba(238,183,98,.05);stroke-width:1}
.fa-wick{stroke:rgba(238,183,98,.3);stroke-width:1}
.fa-body{fill:rgba(238,183,98,.16)}
.fa-body.dn{fill:rgba(138,107,58,.16)}
.fa-trend{fill:none;stroke:url(#faTrend);stroke-width:1.6;stroke-linecap:round;
  stroke-dasharray:2600;stroke-dashoffset:2600;animation:faDraw 3.4s cubic-bezier(.16,1,.3,1) .3s forwards}
@keyframes faDraw{to{stroke-dashoffset:0}}
/* .fa-glow AND ITS TWO ELEMENTS ARE GONE — THEY WERE A SECOND ATMOSPHERE.
   ----------------------------------------------------------------
   Two drifting blurred radial blobs, 760x640 and 700x600, animated on a 13s
   and a 17s alternate loop. Structurally that is the same idea the platform
   just replaced everywhere else: the homepage's .nebula.n1/.n2 and the old
   .au-aurora blobs were drifting radial blobs too, and the whole point of
   Liquidity Strata is that ONE atmosphere runs per surface. These sat at
   z-index auto inside .fa-field (z-index 0), i.e. ON TOP of the strata at -1,
   so the signed-out portal was running both at once.

   It is also a measured contrast failure, not only a composition one. Aurora
   gives the atmosphere a computed ceiling — the brightest ground pixel any
   text token is proven against is #261F12, L=0.01436 — and every value in the
   contrast matrix is derived from it. Rasterised at 1280x900 on
   portal.fpfx.local/login with the blobs composited in:

       brightest ground pixel   rgb(63,50,29)   L=0.03427   = 2.39x the ceiling
       resting panel --surface  #171109         L=0.00624
       -> ground 5.49x BRIGHTER THAN A PANEL

   That is the inversion the whole background pass exists to remove: panels
   read as holes punched in a lit field instead of surfaces lifted off a dark
   one. And on that brightest region both meta tokens drop under the 6.02:1
   floor that Aurora sets for 10-11px type:

       --muted-2  #AEA8A1   6.93:1 on the ceiling  ->  5.29:1 on the blob peak
       --gold-meta #CAA265  6.59:1 on the ceiling  ->  5.26:1 on the blob peak

   Removing them puts the surface back under the ceiling with no token change.
   The market field itself STAYS: a candlestick chart in 1px strokes at .05
   to .3 alpha is a market motif, not an atmosphere, and it is what makes this
   surface look like this product rather than like a login form. What left is
   only the part that was competing with the ground.
   The markup went with it, at portal/_auth-shell.php:118 — an orphaned
   <span> with no rule is still an element in the tree. */

/* ---------- status line, now the header's second tier ----------
   These four rules used to dress `.fa-rail`, a banner this file drew for
   itself. That banner is gone: the shared public header renders here in its
   `auth` variant, and the status line is handed to it as its tier-2 slot —
   the same mechanism legal-layout.php uses for the policy switcher and
   help/_layout.php for the search band. So the line survives verbatim; only
   the box around it changed owner.

   .fa-tier sits INSIDE <header class="fh">, which already paints the blur and
   the sticky background, so this adds a hairline and nothing else. Painting a
   second background here would darken the header's own translucency by
   compositing two panes of glass. */
.fa-tier{border-top:1px solid rgba(238,183,98,.1)}
.fa-tier-in{max-width:1240px;margin:0 auto;padding:8px 26px;display:flex;align-items:center;
  gap:22px;font-family:var(--au-mono,"JetBrains Mono",ui-monospace,Menlo,monospace);font-size:10.5px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted-2,#AEA8A1);
  /* one line, and it scrolls rather than wrapping the header taller */
  overflow-x:auto;scrollbar-width:none}
.fa-tier-in::-webkit-scrollbar{display:none}
.fa-stat{display:flex;align-items:center;gap:7px;white-space:nowrap;flex:none}
@media(max-width:760px){.fa-hide-sm{display:none}}
.fa-dot{width:6px;height:6px;border-radius:50%;background:#22C55E;
  animation:faPing 2s ease-in-out infinite}
@keyframes faPing{0%,100%{opacity:1;box-shadow:0 0 0 0 rgba(34,197,94,.55)}
                  50%{opacity:.55;box-shadow:0 0 0 5px rgba(34,197,94,0)}}

/* ---------- the split ----------
   Single column by default and two columns from 1080px up, so the narrow case
   is the one that needs no override. 1.05fr on the right: the panel is the
   wider half by a hair, which stops the render reading as a swatch beside the
   form and gives the fact cards a line length that does not break mid-figure.
   `align-items:start` matters — without it the panel stretches to the height
   of the tallest form (register: 8 fields, a strength meter and two
   checkboxes) and the render distorts to fill it. */
.fa-main{position:relative;z-index:2;flex:1;display:grid;place-items:center;padding:44px 22px}
.fa-stage{width:100%;max-width:452px}

@media(min-width:1080px){
  /* width:100% is load-bearing and not redundant with max-width. .fpfx-auth is
     a flex column, so .fa-main is a flex ITEM: `margin:0 auto` cancels the
     default cross-axis stretch, and without an explicit width the grid then
     shrink-to-fits its own content. Measured at 1280 before this line: the
     row came out 854.9px wide inside a 1270px viewport, columns 366.7/385.0 —
     the 1240px cap was never being reached and the render sat in a 385px box. */
  .fa-main{width:100%;max-width:1240px;margin:0 auto;
    grid-template-columns:minmax(0,1fr) minmax(0,1.05fr);align-items:start;
    justify-items:center;gap:clamp(28px,4vw,64px);
    padding:clamp(34px,5vh,64px) 26px}
  .fa-stage{justify-self:end}
}

.fa-tabs{display:flex;gap:4px;padding:4px;margin-bottom:18px;border-radius:12px;
  border:1px solid rgba(238,183,98,.15);background:rgba(13,11,8,.8);backdrop-filter:blur(10px)}
.fa-tabs a{flex:1;text-align:center;padding:10px;border-radius:9px;font-size:.88rem;
  font-weight:600;color:var(--muted,#C4BCB1);text-decoration:none;
  transition:color .3s cubic-bezier(.22,.61,.36,1),background .3s cubic-bezier(.22,.61,.36,1)}
.fa-tabs a:hover{color:#F8F8F8}
.fa-tabs a.on{background:linear-gradient(100deg,#EEB762,#F3DBB2);color:#120E06}

.fa-card{border:1px solid rgba(238,183,98,.15);border-radius:18px;padding:30px;position:relative;
  overflow:hidden;background:linear-gradient(168deg,rgba(23,19,13,.94),rgba(13,11,8,.94));
  backdrop-filter:blur(18px);box-shadow:0 40px 90px -50px rgba(0,0,0,.95)}
.fa-card::before{content:"";position:absolute;left:0;right:0;top:0;height:1px;opacity:.6;
  background:linear-gradient(90deg,transparent,#EEB762,transparent)}
.fa-crest{display:grid;place-items:center;margin-bottom:16px}
.fa-card h1{font-size:1.42rem;font-weight:800;text-align:center}
.fa-sub{color:var(--muted,#C4BCB1);font-size:.87rem;text-align:center;margin:8px 0 24px}

.fa-banner{display:flex;gap:10px;align-items:flex-start;padding:12px 14px;border-radius:11px;
  margin-bottom:18px;font-size:.84rem;line-height:1.5}
.fa-banner.e{background:rgba(239,68,68,.1);border:1px solid rgba(239,68,68,.32);color:#ffb4b4}
.fa-banner.s{background:rgba(34,197,94,.09);border:1px solid rgba(34,197,94,.3);color:#9ff0bd}

.fa-foot{text-align:center;margin-top:16px;font-size:.76rem;color:var(--muted-2,#AEA8A1)}
.fa-foot a{color:var(--muted-2,#AEA8A1)}
.fa-foot a:hover{color:#EEB762}

/* ================================================================
   FORM VOCABULARY

   The inherited markup was a flat stack of `.fpfx-field` / `.fpfx-input`
   rows with the layout carried on inline style attributes. This
   replaces it with a vocabulary of its own — `.fa-f` field, `.fa-inp`
   input shell, `.fa-rev` reveal, `.fa-pair` split row, `.fa-row`
   spread row, `.fa-go` action, `.fa-sep` divider, `.fa-codes` OTP
   grid — so nothing about the form is inherited any more and no page
   needs a style attribute to lay itself out.
   ================================================================ */
.fa-f{margin-bottom:14px}
.fa-f > label{display:block;font-family:var(--au-mono,"JetBrains Mono",ui-monospace,Menlo,monospace);
  font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted-2,#AEA8A1);margin-bottom:7px}

/* two fields on one line (first / last name) */
.fa-pair{display:grid;grid-template-columns:1fr 1fr;gap:12px}
@media(max-width:430px){.fa-pair{grid-template-columns:1fr;gap:0}}

/* controls */
.fa-in{width:100%;padding:13px 15px;border-radius:11px;font-size:.92rem;font-family:inherit;
  border:1px solid rgba(238,183,98,.15);background:#0D0B08;color:#F8F8F8;
  transition:border-color .3s ease,background .3s ease}
.fa-in:focus{outline:none;border-color:rgba(238,183,98,.42);background:var(--surface,#171109)}
.fa-in::placeholder{color:#4B473F}
select.fa-in{appearance:none;cursor:pointer;padding-right:38px;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'><path d='M1 1l5 5 5-5' fill='none' stroke='%238E8A82' stroke-width='1.6' stroke-linecap='round'/></svg>");
  background-repeat:no-repeat;background-position:right 14px center}
select.fa-in option{background:#0D0B08;color:#F8F8F8}
select.fa-in optgroup{background:#0D0B08;color:var(--muted,#C4BCB1);font-style:normal}

/* input shell — carries the reveal button beside the control */
.fa-inp{position:relative;display:block}
.fa-inp .fa-in{padding-right:62px}
.fa-rev{position:absolute;right:7px;top:50%;transform:translateY(-50%);
  border:1px solid transparent;background:transparent;cursor:pointer;padding:7px 8px;border-radius:8px;
  font-family:var(--au-mono,"JetBrains Mono",ui-monospace,Menlo,monospace);font-size:9px;letter-spacing:.12em;
  color:var(--muted-2,#AEA8A1);transition:color .25s ease,background .25s ease,border-color .25s ease}
.fa-rev:hover{color:#EEB762;background:rgba(238,183,98,.08);border-color:rgba(238,183,98,.15)}

/* checkboxes */
.fa-chk{display:flex;align-items:flex-start;gap:9px;font-size:.8rem;line-height:1.5;
  color:var(--muted,#C4BCB1);cursor:pointer}
.fa-chk input{position:relative;appearance:none;-webkit-appearance:none;flex:none;
  width:16px;height:16px;margin:2px 0 0;
  display:grid;place-items:center;border-radius:5px;border:1px solid rgba(238,183,98,.3);
  background:#0D0B08;cursor:pointer;transition:background .25s ease,border-color .25s ease}
/* WCAG 2.5.8 (Target Size, Minimum). The box is drawn at 16x16 and its label row
   measures ~19px tall, so both the box and the whole label fell under the 24x24
   pointer-target floor. The box stays 16px — a bigger one dominates the form —
   and a transparent ::before grows the TARGET instead.
   ::after is already spoken for by the tick mark, hence ::before.

   THE INSET IS -6px BECAUSE IT RESOLVES AGAINST THE PADDING BOX, NOT THE BORDER
   BOX. The input is 16px border-box with a 1px border, so an absolutely
   positioned child's containing block is 14px wide: at -4px the target measured
   22px, still short. 14 + 2*6 = 26, which clears 24 with a margin for
   sub-pixel rounding. Measured with elementFromPoint, not by reading the box. */
.fa-chk input::before{content:"";position:absolute;inset:-6px;border-radius:4px}
.fa-chk input:checked{background:linear-gradient(100deg,#EEB762,#F3DBB2);border-color:transparent}
.fa-chk input:checked::after{content:"";width:4px;height:8px;margin-top:-2px;
  border:2px solid #120E06;border-top:0;border-left:0;transform:rotate(42deg)}
.fa-chk input:focus-visible{outline:2px solid #EEB762;outline-offset:2px}
/* a checkbox label is still a direct child label — undo the micro-label styling */
.fa-f > label.fa-chk{display:flex;font-family:inherit;font-size:.8rem;letter-spacing:normal;
  text-transform:none;color:var(--muted,#C4BCB1);margin-bottom:0}

/* "keep me signed in" beside "forgot password" */
.fa-row{display:flex;align-items:center;justify-content:space-between;gap:14px;margin:2px 0 18px}
.fa-row > a{font-size:.8rem;white-space:nowrap}

/* actions */
.fa-go{display:block;width:100%;box-sizing:border-box;cursor:pointer;padding:14px;border-radius:11px;
  border:0;font-size:.95rem;font-weight:700;font-family:inherit;text-align:center;text-decoration:none;
  background:linear-gradient(100deg,#EEB762,#F3DBB2);color:#120E06;
  box-shadow:0 14px 34px -14px rgba(238,183,98,.7);
  transition:transform .24s cubic-bezier(.16,1,.3,1),box-shadow .3s ease}
.fa-go:hover{transform:translateY(-2px);box-shadow:0 22px 46px -16px rgba(238,183,98,.85)}
.fa-go:disabled{opacity:.55;cursor:progress;transform:none;box-shadow:none}
.fa-go.ghost{background:transparent;color:var(--muted,#C4BCB1);border:1px solid rgba(238,183,98,.15);box-shadow:none}
.fa-go.ghost:hover{color:#F8F8F8;border-color:rgba(238,183,98,.42);transform:none;box-shadow:none}
.fa-card a.fa-go{color:#120E06}
.fa-card a.fa-go.ghost{color:var(--muted,#C4BCB1)}
.fa-card a.fa-go.ghost:hover{color:#F8F8F8}

/* OR rule */
.fa-sep{display:flex;align-items:center;gap:12px;margin:18px 0;
  font-family:var(--au-mono,"JetBrains Mono",ui-monospace,Menlo,monospace);font-size:9px;letter-spacing:.16em;
  color:var(--muted-2,#AEA8A1)}
.fa-sep::before,.fa-sep::after{content:"";flex:1;height:1px;background:rgba(238,183,98,.15)}

/* trailing links and hints */
.fa-alt{text-align:center;font-size:.85rem;color:var(--muted,#C4BCB1);margin:16px 0 0}
.fa-alt + .fa-alt{margin-top:7px}
.fa-hint{font-size:.74rem;color:var(--muted-2,#AEA8A1);margin-top:7px;line-height:1.5}
.fa-status{text-align:center;font-size:.78rem;color:var(--muted,#C4BCB1);margin-top:10px}

/* one-time-code boxes */
.fa-codes{display:grid;grid-template-columns:repeat(6,1fr);gap:8px;margin:2px 0 16px}
.fa-codes[hidden]{display:none}
.fa-codes input{width:100%;padding:15px 0;text-align:center;border-radius:11px;
  border:1px solid rgba(238,183,98,.15);background:#0D0B08;color:#F8F8F8;
  font-family:var(--au-mono,"JetBrains Mono",ui-monospace,Menlo,monospace);font-size:1.1rem;font-weight:600;
  transition:border-color .25s ease,background .25s ease,box-shadow .25s ease}
.fa-codes input:focus{outline:none;border-color:rgba(238,183,98,.42);background:var(--surface,#171109);
  box-shadow:0 0 0 3px rgba(238,183,98,.1)}
.fa-codes input.on{border-color:rgba(238,183,98,.42)}
.fa-swap{display:block;width:100%;margin:0 0 18px;padding:0;border:0;background:transparent;cursor:pointer;
  font-family:var(--au-mono,"JetBrains Mono",ui-monospace,Menlo,monospace);font-size:9px;letter-spacing:.12em;
  text-transform:uppercase;color:var(--muted-2,#AEA8A1);transition:color .25s ease}
.fa-swap:hover{color:#EEB762}

/* per-field validation */
.fa-card .fa-f.bad .fa-in,
.fa-card .fa-f.bad .iti input,
.fa-card .fpfx-phone.phone-invalid .fa-in{border-color:#EF4444;background:rgba(239,68,68,.05)}
.fa-err{display:none;align-items:center;gap:6px;margin-top:7px;font-size:.76rem;color:#ff9b9b}
.fa-card .fa-f.bad .fa-err,
.fa-card .fpfx-phone.phone-invalid .fa-err{display:flex;
  animation:faShake .32s cubic-bezier(.22,.61,.36,1)}
@keyframes faShake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}
.fa-err::before{content:"!";flex:none;width:14px;height:14px;border-radius:50%;display:grid;
  place-items:center;background:#DC2626;color:#fff;font-size:9px;font-weight:700}
  /* #DC2626, not --bad #EF4444: white on #EF4444 is 3.76:1 and this glyph is 9px.
     #DC2626 is 4.83:1. --bad keeps #EF4444 for bars and borders carrying no text. */

/* password strength */
.fa-meter{height:3px;border-radius:2px;background:rgba(238,183,98,.12);margin-top:9px;overflow:hidden}
.fa-meter i{display:block;height:100%;width:0;border-radius:2px;background:#EF4444;
  transition:width .4s cubic-bezier(.16,1,.3,1),background .4s ease}
.fa-meter-t{display:block;font-family:var(--au-mono,"JetBrains Mono",ui-monospace,Menlo,monospace);font-size:9px;
  letter-spacing:.1em;text-transform:uppercase;color:var(--muted-2,#AEA8A1);margin-top:6px}

/* phone — the shared intl-tel-input module keys off `.fpfx-phone`, so the
   wrapper keeps that behaviour hook while everything visible is ours */
.fa-card .fpfx-phone .iti{display:block;width:100%}
.fa-card .fpfx-phone .iti input.fa-in{padding-left:122px}
.fa-card .fpfx-phone.phone-invalid > label{color:#ff9b9b}
/* the shared 110px country selector leaves too little room to type on a
   narrow screen; intl-tel-input re-measures and re-pads the input itself */
@media(max-width:430px){
  .fa-card .fpfx-phone .iti__selected-country{min-width:92px;padding:0 8px 0 7px!important}
}

/* the E.164 value that will actually be stored */
.fa-e164{display:flex;align-items:center;gap:7px;margin-top:8px;
  font-family:var(--au-mono,"JetBrains Mono",ui-monospace,monospace);font-size:9.5px;letter-spacing:.08em;
  color:var(--muted-2,#AEA8A1);opacity:0;transition:opacity .3s ease}
.fa-e164.on{opacity:1}
.fa-e164 b{color:#22C55E}

/* ================================================================
   THE RIGHT HALF — the brand render, and what it is standing next to

   Two things live here and they answer two different questions. The
   render answers "whose sign-in page is this"; the fact cards answer
   "what am I signing in to" — five programmes read straight out of
   challenge_phases, so an operator editing a target in Office edits
   this panel too and nobody has to remember to.

   REJECTED for this slot, so they are not re-proposed: a live payout
   feed (`payouts` holds 188 rows of which 4 are paid, $2,471 in
   total, oldest 2025-08-06 — a feed of four is not a feed);
   certificate cards (the 68 legacy artefacts carry no card data);
   the portal.auth.proof rows (already on this page, in .fa-proof);
   and testimonials, which have no table at all.
   ================================================================ */
/* max-width 500, not the track width. The render is square (1254x1254), so the
   panel's height is its width plus the cards: at 560 the column measured 807px
   tall against 800px of viewport below the header, which is a sticky element
   taller than the thing it is stuck to — it scrolls, which is the one thing
   sticky is for avoiding. 500 puts it at 747. */
.fa-panel{position:relative;z-index:2;width:100%;max-width:500px;justify-self:start;
  display:grid;gap:18px;
  /* Fed by fpfx-auth.js on pointermove and by NOTHING else. Declared here so
     the very first paint is a correct frame with no script having run: the
     browser pane this is verified in throttles rAF to zero, and an opening
     state applied by JS would be an opening state that never resolves. */
  --fa-px:0; --fa-py:0}

@media(min-width:1080px){
  /* Sticky, and offset by the header it sits under. The register form is the
     tallest thing on this surface by some way; without this the panel scrolls
     off the top and the visitor spends the second half of the form looking at
     an empty column. align-self:start keeps the sticky box from being
     stretched to the row height, which would defeat it. */
  .fa-panel{position:sticky;top:calc(var(--fa-hdr,98px) + 22px);align-self:start}
}

/* ---------- the render ----------
   mix-blend-mode:screen is NOT decoration. bull-candlestick.webp is a render
   on a SOLID BLACK ground; dropped in without it the panel gets a black
   rectangle with four visible edges sitting on a not-quite-black page. screen
   maps that ground to the backdrop and leaves the lit candles.

   Which also fixes the frame: the border and the radius belong to .fa-art,
   the blend belongs to the <img>, so the glass edge is not blended away. */
.fa-art{position:relative;overflow:hidden;border-radius:20px;aspect-ratio:1/1;
  border:1px solid rgba(238,183,98,.15);
  background:radial-gradient(120% 92% at 50% 8%,#211810 0%,#0B0A08 58%,#0A0806 100%);
  box-shadow:0 40px 90px -50px rgba(0,0,0,.95)}
.fa-art::after{content:"";position:absolute;left:0;right:0;top:0;height:1px;opacity:.6;
  background:linear-gradient(90deg,transparent,#EEB762,transparent)}
/* The motion is applied TO the render — a translate and a hair of scale driven
   by the two custom properties above. scale(1.06) at rest gives the translate
   room to move without exposing a bare corner, so the resting frame is already
   the frame the parallax returns to. */
.fa-art img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;
  
  transform:translate3d(calc(var(--fa-px) * 1px),calc(var(--fa-py) * 1px),0) scale(1.06);
  transition:transform .5s cubic-bezier(.2,.8,.3,1);will-change:transform}

/* ---------- programme fact cards ----------
   Stacked in ONE grid cell rather than absolutely positioned, so the track
   takes the height of the tallest card and nothing reflows as they crossfade.
   visibility carries the a11y state; opacity carries the look. */
.fa-facts{display:grid;position:relative}
.fa-fact{grid-area:1/1;opacity:0;visibility:hidden;
  transition:opacity .6s cubic-bezier(.2,.8,.3,1),visibility 0s linear .6s;
  border:1px solid rgba(238,183,98,.15);border-radius:16px;padding:17px 19px 15px;
  background:linear-gradient(168deg,rgba(23,19,13,.94),rgba(13,11,8,.94));
  backdrop-filter:blur(18px)}
/* Printed by the server on card 1. No JS-applied opening state anywhere: this
   selector alone makes the first frame correct, synchronously. */
.fa-fact.is-on{opacity:1;visibility:visible;transition-delay:0s,0s}
.fa-fact-k{display:block;font-family:var(--au-mono,"JetBrains Mono",ui-monospace,monospace);
  font-size:9px;letter-spacing:.14em;text-transform:uppercase;color:var(--muted-2,#AEA8A1)}
.fa-fact-n{display:block;margin:5px 0 13px;font-size:1.12rem;font-weight:800;letter-spacing:-.03em;
  color:#F8F8F8;font-family:var(--au-disp,"Outfit",system-ui,sans-serif)}
.fa-fact-g{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:12px 14px;margin:0}
.fa-fact-g > div{min-width:0}
.fa-fact-g dt{font-family:var(--au-mono,"JetBrains Mono",ui-monospace,monospace);font-size:8.5px;
  letter-spacing:.12em;text-transform:uppercase;color:var(--muted-2,#AEA8A1);margin:0 0 4px}
.fa-fact-g dd{margin:0;font-family:var(--au-mono,"JetBrains Mono",ui-monospace,monospace);
  font-size:.95rem;font-weight:700;color:#EEB762;letter-spacing:-.01em}

/* ---------- the control, and the reason it exists ----------
   The cards advance on a timer, which is auto-updating content: WCAG 2.2.2
   requires a way to stop it, and hover is not one — it is unreachable by
   keyboard and does not exist on touch. These buttons ARE that mechanism.
   Pressing one selects that card and stops the rotation for good; the panel
   also pauses while anything inside it is hovered or focused.

   Colour is never the only signal: the current dot is TALLER as well as gold,
   and carries aria-current for anything that reads neither. */
/* Visually hidden, still read and still focusable. No `display:none` and no
   `visibility:hidden` - both take the text out of the accessibility tree,
   which is the opposite of what a label inside an icon button is for. There
   was no such utility on this surface; this is it. */
.fa-sr{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip-path:inset(50%);white-space:nowrap;border:0}
.fa-fact-dots{display:flex;gap:8px;justify-content:center;align-items:center}
.fa-fact-dots button{width:26px;height:20px;padding:0;border:0;background:transparent;
  cursor:pointer;display:grid;place-items:center;border-radius:5px}
.fa-fact-dots button::before{content:"";width:100%;height:2px;border-radius:2px;
  background:rgba(238,183,98,.24);
  transition:height .3s cubic-bezier(.2,.8,.3,1),background .3s ease}
.fa-fact-dots button:hover::before{background:rgba(238,183,98,.5)}
.fa-fact-dots button[aria-current="true"]::before{height:4px;
  background:linear-gradient(100deg,#EEB762,#F3DBB2)}
.fa-fact-dots button:focus-visible{outline:2px solid #EEB762;outline-offset:2px}

/* ---------- below 1080px: the panel demotes, it does not stack ----------
   Its own breakpoint on purpose. .fa-tabs already has one at 430px and
   reusing that would tie the shape of this panel to the width at which two
   name fields stop fitting on a line, which is unrelated.

   The render LEAVES THE FLOW: fixed, behind everything, zero layout height.
   Stacked in the flow it would be a screen-tall image between the form and
   the footer that nobody scrolls to. .fa-field is dimmed to match so the two
   full-bleed layers do not compete. */
@media(max-width:1079px){
  .fa-panel{max-width:452px;justify-self:center;gap:12px}
  .fa-art{position:fixed;inset:0;z-index:0;border:0;border-radius:0;aspect-ratio:auto;
    background:none;box-shadow:none;pointer-events:none;opacity:.3}
  .fa-art::after{display:none}
  .fa-art img{object-fit:cover;transform:none;transition:none;will-change:auto}
  .fa-field svg{opacity:.3}
  /* one swipeable strip; rotation is switched off in JS at this width */
  .fa-facts{display:flex;gap:12px;overflow-x:auto;scroll-snap-type:x mandatory;
    -webkit-overflow-scrolling:touch;scrollbar-width:none;padding-bottom:2px}
  .fa-facts::-webkit-scrollbar{display:none}
  .fa-fact{flex:0 0 86%;scroll-snap-align:start;opacity:1;visibility:visible;transition:none}
  .fa-fact-dots{display:none}
}
/* A phone keyboard covers this the instant a field takes focus, so below
   430px it is height spent on something nobody sees. The render stays — it
   costs no height. */
@media(max-width:430px){ .fa-facts{display:none} }

/* ---------- payout proof ticker ---------- */
.fa-proof{position:relative;z-index:3;border-top:1px solid rgba(238,183,98,.15);
  background:rgba(9,8,6,.78);backdrop-filter:blur(14px);overflow:hidden}
.fa-proof::before,.fa-proof::after{content:"";position:absolute;top:0;bottom:0;width:120px;
  z-index:2;pointer-events:none}
.fa-proof::before{left:0;background:linear-gradient(90deg,#100C08,transparent)}
.fa-proof::after{right:0;background:linear-gradient(270deg,#100C08,transparent)}
.fa-track{display:flex;width:max-content;padding:11px 0;animation:faMarq 42s linear infinite}
.fa-proof:hover .fa-track{animation-play-state:paused}
@keyframes faMarq{to{transform:translateX(-50%)}}
.fa-pi{display:flex;align-items:center;gap:9px;padding:0 26px;white-space:nowrap;font-size:.8rem;
  color:var(--muted-2,#AEA8A1);border-right:1px solid rgba(238,183,98,.15)}
.fa-pi b{color:#EEB762;font-family:var(--au-mono,"JetBrains Mono",ui-monospace,monospace);font-size:.82rem}
.fa-pi svg{border-radius:2px}

/* The blanket reduced-motion rule EXEMPTS THE AURORA LAYER.
   `.fpfx-auth *` reaches every descendant of <body>, and .au-aurora is one —
   so this rule was landing animation-duration:.001ms !important and
   animation-iteration-count:1 !important on the five strata bands, inside a
   subtree fpfx-aurora.css owns and has its own reduced-motion block for.

   It was not producing a wrong result. Simulated faithfully by re-emitting all
   13 declarations from every (prefers-reduced-motion:reduce) block on this page
   outside the media query, in source order: every band computed
   animation-name:none and transform:matrix(1,0,0,1,0,0) — the identity, which
   is the exact mid-frame of a keyframe pair symmetric about zero — with the
   per-band opacities 1 / .70 / .55 / .40 / .28 intact and zero au-strata
   animations running. A composed static frame, not a frozen one. The
   !important duration was inert because the name resolved to none.

   It is exempted anyway, because that correctness depended on a rule in
   ANOTHER file winning animation-name at a lower weight than this rule's
   !important longhands. That is a coincidence of authorship, not a contract.
   :where() contributes zero specificity, so this changes which elements match
   and nothing else about the rule's weight. */
@media (prefers-reduced-motion:reduce){
  .fpfx-auth *:not(:where(.au-aurora,.au-aurora *)),
  .fpfx-auth *:not(:where(.au-aurora,.au-aurora *))::before,
  .fpfx-auth *:not(:where(.au-aurora,.au-aurora *))::after{
    animation-duration:.001ms !important; animation-iteration-count:1 !important;
    transition-duration:.001ms !important}
}
