/* .rl__lockmsg, .rl__grid2 and .rl__ts WERE DELETED 27 August 2026 with the candidate
   layout they dressed: a blurred name form behind a lock message, and a tinted steps pane.
   Nicole replaced that shape with the same two panels the business tab renders.
   REMOVED RATHER THAN LEFT DORMANT. A rule for a deleted shape is how the shape returns,
   because the next person to write className 'rl__lockmsg' gets a styled box and no error. */
/* ============================================================================
   SIGNED-OUT PORTAL PREVIEW - REPLICA OF THE REAL PARTNER PAGES
   ----------------------------------------------------------------------------
   Added 12 Aug 2026.

   Styles the six page replicas that src/signed-out-sidebar.jsx renders behind
   the lock card on the signed-out portal rail: Home, Opportunities, My
   Projects, Referrals, Earnings, Profile.

   These are traced from the real partner portal, aonslow/gogorilla-platform,
   which serves /partners as a rewrite of /account. Copy, tab labels, fixture
   data and the type scale are taken from that source so the preview reads as
   the actual product rather than a wireframe of it. Nothing here fetches or
   renders real user data: every figure is the portal's own fixture or its
   documented zero state.

   Tokens lifted from the platform, keep them in step if it changes:
     page             #efede7 warm paper
     glass pane       rgba(255,255,255,0.55), radius 18px, no border
     brand blue       #002abf   (eyebrows use --color-brand #06079c)
     primary gradient linear-gradient(109deg,#2e5dff,#002abf 60%,#001b82)
     orange gradient  linear-gradient(109deg,#ff962e,#bf6000 60%,#824100)
     success green    #0f8847
     h1               1.875rem/700   eyebrow .6875rem/700 uppercase .1em
     body             .8125rem        fine print .6875rem

   WHY REAL TEXT
   An earlier revision drew grey bars. Blurred, bars read as a loading state,
   because that is what they are. Real strings at real sizes give the ragged
   line lengths and the type rhythm of a populated page, which is what makes
   6px of blur read as a real screen behind glass. The text is not meant to be
   legible through the blur, it is meant to be shaped like text.

   ACCESSIBILITY
   The JSX wraps all of this in aria-hidden, so none of this copy reaches a
   screen reader. The glimpse itself is the labelled dialog.
   ========================================================================= */

.gg-scope .sp-root{ display: contents; }

/* The rail's own tab strip is hidden for these pages; each replica draws its
   own, because the real tab labels and the neumorphic pill treatment are part
   of what makes the page recognisable, and Home has no tab strip at all. */
.gg-scope .gg-sos__blur:has(.sp) .gg-sos__sk-tabs{ display: none; }

.gg-scope .gg-sos__blur:has(.sp){
  display: block;
  padding: 72px 3vw 3vw;
  overflow: hidden;
}

/* ── Shell ───────────────────────────────────────────────────────────────── */
.gg-scope .sp{
  width: 100%;
  max-width: 1280px;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 1rem;
  text-align: left;
  font-family: var(--gg-font, Inter, system-ui, -apple-system, "Segoe UI", sans-serif);
  color: #0f172a;
  --sp-slate7: #334155;
  --sp-slate6: #475569;
  --sp-slate5: #64748b;
  --sp-slate4: #94a3b8;
  --sp-edge: rgba(15, 28, 53, 0.09);
  --sp-brand: #06079c;
  --sp-blue: #002abf;
}
.gg-scope .sp *{ box-sizing: border-box; }

/* Glass pane. The real one carries a nine-slice bevel on ::before; behind 6px
   of blur that detail is invisible, so a plain edge and the same shadow stack
   is indistinguishable and far cheaper. */
.gg-scope .sp__pane{
  display: flex;
  flex-direction: column;
  gap: 0.7rem;
  padding: 1.15rem 1.25rem;
  border-radius: 18px;
  background: rgba(255,255,255,0.55);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.9),
              0 1px 2px rgba(15,23,42,0.05),
              0 18px 36px -18px rgba(44,51,102,0.2);
}
/* Nested pane: solid rather than translucent, as in the real cards. */
.gg-scope .sp__pane--in{
  background: rgba(255,255,255,0.82);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.9), 0 1px 2px rgba(15,23,42,0.05);
}

/* ── Type ────────────────────────────────────────────────────────────────── */
.gg-scope .sp__h1{ font-size: 1.875rem; font-weight: 700; line-height: 1.15; letter-spacing: -0.01em; white-space: nowrap; }
.gg-scope .sp__h1--hero{ font-size: 1.6rem; white-space: normal; }
.gg-scope .sp__h2{ font-size: 0.8125rem; font-weight: 700; }
.gg-scope .sp__eyebrow{ font-size: 0.6875rem; font-weight: 700; text-transform: uppercase; letter-spacing: 0.1em; color: var(--sp-brand); }
.gg-scope .sp__eyebrow--am{ color: #92400e; }
.gg-scope .sp__eyebrow--b{ color: var(--sp-blue); letter-spacing: 0.06em; }
/* The muted EXAMPLE tag on the profile-strength card, mirroring the portal's own. */
.gg-scope .sp__eyebrow--r{ color: #94a3b8; margin-left: auto; }
.gg-scope .sp__tt{ font-size: 0.8125rem; font-weight: 600; }
.gg-scope .sp__tt--lg{ font-size: 0.9rem; font-weight: 700; }
.gg-scope .sp__tt2{ font-size: 0.8125rem; font-weight: 600; white-space: nowrap; }
.gg-scope .sp__cardt{ font-size: 0.8125rem; font-weight: 500; color: var(--sp-slate5); }
.gg-scope .sp__ts{ font-size: 0.75rem; line-height: 1.45; color: var(--sp-slate6); }
.gg-scope .sp__ts--mut{ color: var(--sp-slate5); }
.gg-scope .sp__ts--r{ text-align: right; white-space: nowrap; }
.gg-scope .sp__meta{ font-size: 0.6875rem; font-weight: 600; color: var(--sp-slate5); white-space: nowrap; }
.gg-scope .sp__cap{ font-size: 0.75rem; line-height: 1.35; color: var(--sp-slate6); }
.gg-scope .sp__fine{ font-size: 0.6875rem; line-height: 1.4; color: var(--sp-slate4); }
.gg-scope .sp__link{ font-size: 0.75rem; font-weight: 500; color: #1d4ed8; white-space: nowrap; }
.gg-scope .sp__fig{ font-size: 1.75rem; font-weight: 700; line-height: 1; letter-spacing: -0.02em; }
.gg-scope .sp__fig--rail{ font-size: 2rem; }
.gg-scope .sp__fig--ok{ color: #0f8847; }
.gg-scope .sp__figsuf{ font-size: 0.8125rem; font-weight: 600; color: var(--sp-slate6); }
.gg-scope .sp__figrow{ display: flex; align-items: baseline; gap: 0.4rem; }

/* ── Controls ───────────────────────────────────────────────────────────── */
.gg-scope .sp__btn{
  display: inline-flex; align-items: center; justify-content: center;
  flex: none; align-self: flex-start;
  padding: 0.5rem 0.95rem; border-radius: 10px;
  font-size: 0.75rem; font-weight: 600; white-space: nowrap;
  background: linear-gradient(109deg, #e6e6e6 13%, #e6e6e6 100%);
  color: #111; border: 1px solid rgba(120,130,160,0.28);
}
.gg-scope .sp__btn--primary{
  background: linear-gradient(109deg, #2e5dff 0%, #002abf 60%, #001b82 100%);
  color: #fff; border-color: transparent;
}
.gg-scope .sp__btn--orange{
  background: linear-gradient(109deg, #ff962e 0%, #bf6000 60%, #824100 100%);
  color: #fff; border-color: transparent;
}
.gg-scope .sp__btn--sm{ padding: 0.4rem 0.75rem; font-size: 0.7rem; }
.gg-scope .sp__btn--ghost{ color: #334155; }

/* Neumorphic tab track, as in components/tabs/tabs.css */
.gg-scope .sp__tabs{
  display: inline-flex; align-self: flex-start; gap: 6px; padding: 5px;
  border-radius: 15px; border: 1px solid rgba(120,130,160,0.3);
  background: linear-gradient(180deg, #ececee 0%, #e2e3e8 100%);
  box-shadow: inset 0 1px 2px rgba(20,28,60,0.1), 0 1px 0 rgba(255,255,255,0.9);
  max-width: 100%; flex-wrap: nowrap; overflow: hidden;
}
.gg-scope .sp__tab{
  padding: 0.5rem 0.85rem; border-radius: 11px;
  font-size: 0.75rem; font-weight: 600; line-height: 1; white-space: nowrap;
  background: linear-gradient(109deg, #e6e6e6 13%, #e6e6e6 100%); color: #111;
}
.gg-scope .sp__tab--on{
  background: linear-gradient(109deg, #2e5dff 0%, #002abf 60%, #001b82 100%);
  color: #fff;
}
.gg-scope .sp__search,
.gg-scope .sp__urlbox,
.gg-scope .sp__select{
  border-radius: 10px; border: 1px solid rgba(120,130,160,0.3);
  background: linear-gradient(180deg, #f7f7f9, #eeeff3);
  box-shadow: inset 0 1px 2px rgba(20,28,60,0.1);
  font-size: 0.75rem; color: var(--sp-slate4);
  padding: 0.55rem 0.75rem;
}
.gg-scope .sp__search{ flex: 1 1 auto; min-width: 0; }
.gg-scope .sp__urlbox{ flex: 1 1 auto; min-width: 0; color: var(--sp-slate7); overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.gg-scope .sp__select{ align-self: flex-start; color: var(--sp-slate6); }
.gg-scope .sp__ctl{ display: flex; align-items: center; gap: 0.6rem; width: 100%; }
.gg-scope .sp__inputrow{ display: flex; align-items: center; gap: 0.5rem; width: 100%; }
.gg-scope .sp__rule{ height: 1px; width: 100%; background: var(--sp-edge); }

/* ── Rows and layout ─────────────────────────────────────────────────────── */
.gg-scope .sp__hrow{ display: flex; align-items: center; justify-content: space-between; gap: 1rem; width: 100%; }
.gg-scope .sp__srow{ display: flex; align-items: center; justify-content: space-between; gap: 0.85rem; width: 100%; }
.gg-scope .sp__srow--top{ padding-top: 0.6rem; border-top: 1px solid var(--sp-edge); }
.gg-scope .sp__tl{ display: flex; flex-direction: column; gap: 0.2rem; flex: 1 1 auto; min-width: 0; }
.gg-scope .sp__amt{ display: flex; align-items: center; gap: 0.6rem; flex: none; }
.gg-scope .sp__badge{ font-size: 0.6875rem; font-weight: 600; color: #15803d; background: #f0fdf4; border-radius: 99px; padding: 0.1rem 0.45rem; }
.gg-scope .sp__cols{ display: flex; flex-wrap: wrap; gap: 1rem; align-items: flex-start; width: 100%; }
.gg-scope .sp__main{ flex: 2.1 1 460px; display: flex; flex-direction: column; gap: 0.85rem; min-width: 0; }
.gg-scope .sp__side{ flex: 1 1 250px; display: flex; flex-direction: column; gap: 0.85rem; min-width: 0; }
.gg-scope .sp__cols2{ display: flex; flex-wrap: wrap; gap: 0.85rem; align-items: stretch; width: 100%; }
/* min-width:0 is load-bearing. The referral URL is one unbreakable token, so
   without it that card's min-content width wins over its flex share and the
   card overflows across its neighbour. */
.gg-scope .sp__cols2 > *{ flex: 1 1 280px; min-width: 0; }
.gg-scope .sp__grow2{ flex: 2 1 380px; min-width: 0; }
/* align-items must stay flex-start. With stretch, equalising row heights across
   a 12-card wrap sent the offline renderer into a layout blow-up (sub-second to
   over three minutes for this one page) and it left a tall dead band under the
   Profile field grid. Cards get an even look from min-height instead. */
.gg-scope .sp__wrap{ display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.75rem; width: 100%; }
.gg-scope .sp__wrap > *{ flex: 1 1 235px; min-width: 0; }
.gg-scope .sp__wrap--4 > *{ flex: 1 1 190px; }
.gg-scope .sp__wrap--2{ gap: 0.9rem 2.5rem; }
.gg-scope .sp__wrap--2 > *{ flex: 1 1 420px; }
.gg-scope .sp__rowc{ flex-direction: row; align-items: center; gap: 1rem; }

/* ── Home ──────────────────────────────────────────────────────────────── */
.gg-scope .sp__stepper{ flex-direction: row; align-items: center; gap: 0.85rem; padding: 0.85rem 1rem; }
.gg-scope .sp__step{ display: flex; align-items: center; gap: 0.55rem; flex: none; }
.gg-scope .sp__stepico{ height: 30px; width: 30px; flex: none; border-radius: 8px; background: #dbe2f2; }
.gg-scope .sp__steptxt{ display: flex; flex-direction: column; gap: 0.1rem; }
.gg-scope .sp__steplbl{ font-size: 0.8125rem; font-weight: 700; white-space: nowrap; }
.gg-scope .sp__steprail{ height: 3px; flex: 1 1 auto; border-radius: 2px; background: #dfe3ec; }
.gg-scope .sp__steprail--on{ background: var(--sp-blue); }
.gg-scope .sp__task{ display: flex; align-items: flex-start; gap: 0.7rem; width: 100%; }
.gg-scope .sp__node{ height: 12px; width: 12px; flex: none; border-radius: 50%; margin-top: 3px; background: #fff; border: 2px solid #cbd5e1; }
.gg-scope .sp__task--opt,
.gg-scope .sp__task--call{ padding: 0.8rem; border-radius: 12px; align-items: center; }
.gg-scope .sp__task--opt{ background: #fdf7ec; border: 1px solid #ecdcc0; }
.gg-scope .sp__task--call{ background: #faf7f3; border: 1px solid #c9a882; }
.gg-scope .sp__segs{ display: flex; gap: 4px; width: 100%; }
.gg-scope .sp__seg{ height: 5px; flex: 1 1 0; border-radius: 3px; background: #e6eaf2; }
/* 2026-08-19: the filled segment, so the 80% figure beside it is actually represented.
   Added because the class was going to ship with NO RULE AT ALL otherwise, which is the
   qualifier-q__textfield trap in this repo's own trap list: a class present on the element,
   absent from every stylesheet, and therefore invisible. Checked before pushing, not after. */
.gg-scope .sp__seg--on{ background: var(--sp-blue, #002ABF); }

/* ── Opportunities ───────────────────────────────────────────────────────── */
.gg-scope .sp__role{ gap: 0.3rem; padding: 0.8rem 0.85rem; min-height: 138px; }
.gg-scope .sp__rt{ font-size: 0.8125rem; font-weight: 600; line-height: 1.3; }
.gg-scope .sp__role .sp__rt{ min-height: 2.1em; }
.gg-scope .sp__rpay{ font-size: 0.75rem; font-weight: 500; color: var(--sp-slate7); }
.gg-scope .sp__rshape{ font-size: 0.6875rem; font-weight: 500; color: var(--sp-brand); line-height: 1.35; }
.gg-scope .sp__rmeta{ font-size: 0.6875rem; color: var(--sp-slate5); }
.gg-scope .sp__cfoot{ display: flex; align-items: center; justify-content: space-between; gap: 0.5rem; width: 100%; margin-top: auto; padding-top: 0.45rem; border-top: 1px solid var(--sp-edge); }
.gg-scope .sp__cfoot .sp__rmeta{ font-size: 0.625rem; white-space: nowrap; overflow: hidden; }
.gg-scope .sp__cfoot .sp__link{ flex: none; font-size: 0.6875rem; }
.gg-scope .sp__favs{ display: flex; align-items: center; gap: 0.35rem; min-width: 0; overflow: hidden; }
.gg-scope .sp__avs{ display: flex; flex: none; }
.gg-scope .sp__av{
  height: 17px; width: 17px; flex: none; border-radius: 50%; margin-left: -5px;
  background: var(--sp-blue); color: #fff; border: 1.5px solid #fff;
  font-size: 0.5rem; font-weight: 600;
  display: flex; align-items: center; justify-content: center;
}
.gg-scope .sp__av:first-child{ margin-left: 0; }
.gg-scope .sp__av:nth-child(3){ background: #d97706; }

/* ── My Projects ─────────────────────────────────────────────────────────── */
.gg-scope .sp__board{ display: flex; flex-wrap: wrap; align-items: flex-start; gap: 0.7rem; width: 100%; }
.gg-scope .sp__kcol{
  flex: 1 1 195px; display: flex; flex-direction: column; gap: 0.5rem;
  padding: 0.65rem; min-height: 220px; border-radius: 14px;
  background: rgba(255,255,255,0.55);
  box-shadow: inset 0 1px 0 rgba(255,255,255,0.9), 0 1px 2px rgba(15,23,42,0.05);
}
.gg-scope .sp__khead{ display: flex; align-items: center; gap: 0.4rem; }
.gg-scope .sp__kdot{ height: 7px; width: 7px; border-radius: 50%; flex: none; }
.gg-scope .sp__kdot--b{ background: #2563eb; } .gg-scope .sp__kdot--a{ background: #f59e0b; }
.gg-scope .sp__kdot--v{ background: #7c3aed; } .gg-scope .sp__kdot--g{ background: #16a34a; }
.gg-scope .sp__kname{ font-size: 0.75rem; font-weight: 600; color: var(--sp-slate7); }
.gg-scope .sp__kcount{ font-size: 0.6875rem; font-weight: 600; color: var(--sp-slate4); }
.gg-scope .sp__kdate{ font-size: 0.625rem; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--sp-slate4); padding-top: 0.15rem; border-top: 1px solid var(--sp-edge); }
.gg-scope .sp__kcard{
  display: flex; flex-direction: column; gap: 0.35rem; align-items: flex-start;
  padding: 0.6rem; background: #fff; border: 1px solid #cbd5e1; border-radius: 9px;
}
.gg-scope .sp__kt{ font-size: 0.75rem; font-weight: 500; color: #1e293b; line-height: 1.3; }
.gg-scope .sp__ktag{ font-size: 0.625rem; font-weight: 500; border-radius: 5px; padding: 0.1rem 0.35rem; }
.gg-scope .sp__ktag--pink{ background: #fce7f3; color: #9d174d; }
.gg-scope .sp__ktag--blue{ background: #dbeafe; color: #1e40af; }
.gg-scope .sp__ktag--green{ background: #dcfce7; color: #166534; }
.gg-scope .sp__kfoot{ display: flex; align-items: center; gap: 0.5rem; flex-wrap: nowrap; }
.gg-scope .sp__kdue,
.gg-scope .sp__kchk{ font-size: 0.625rem; color: var(--sp-slate5); white-space: nowrap; }

/* ── Referrals and Profile ───────────────────────────────────────────────── */
.gg-scope .sp__stat{ gap: 0.45rem; padding: 0.85rem 0.9rem; min-height: 120px; }
.gg-scope .sp__chips{ display: flex; flex-wrap: wrap; gap: 0.45rem; width: 100%; }
.gg-scope .sp__chip{
  font-size: 0.75rem; font-weight: 500; color: var(--sp-slate7);
  background: #f8fafc; border: 1px solid #e2e8f0; border-radius: 99px; padding: 0.2rem 0.65rem;
}
.gg-scope .sp__field{ display: flex; flex-direction: column; gap: 0.15rem; }
.gg-scope .sp__flabel{ font-size: 0.625rem; font-weight: 500; text-transform: uppercase; letter-spacing: 0.05em; color: var(--sp-slate4); }
.gg-scope .sp__fval{ font-size: 0.8125rem; color: #0f172a; }

/* Small viewports. The rail hides the glimpse entirely below its own
   breakpoint, so this only has to cover tablet widths. */
@media (max-width: 820px){
  .gg-scope .gg-sos__blur:has(.sp){ padding: 60px 4vw 4vw; }
  .gg-scope .sp__wrap > *{ flex: 1 1 45%; }
  .gg-scope .sp__h1{ font-size: 1.4rem; }
}

/* ══ THE LIVE REFERRALS SURFACE ═══════════════════════════════════════════════
   19 Aug 2026. FREELANCER 18 at 1:47 and 2:31. Referrals is the one rail surface
   that renders for real: unblurred, scrollable and interactive. It draws NO
   .gg-sos__blur, so the blur rule in app.v2.css simply never applies here and
   nothing has to be un-set. The glimpse box itself does need overriding, because
   it centres a small card and this is a full page.

   THE DOUBLE CLASS IS DELIBERATE. .gg-sos__glimpse--live alone ties with
   app.v2.css on specificity and would depend on stylesheet order; chaining it to
   .gg-sos__glimpse wins outright, so this holds whichever file loads last.
   ─────────────────────────────────────────────────────────────────────────── */
.gg-scope .gg-sos__glimpse.gg-sos__glimpse--live{
  display: block; align-items: stretch; justify-content: flex-start;
  overflow-y: auto; overflow-x: hidden; -webkit-overflow-scrolling: touch;
}
.gg-scope .gg-sos__glimpse--live::before{ backdrop-filter: none; }

/* ───────────────────────────────────────────────────────────────────────────
   2026-08-19 (Nicole). THREE COMPLAINTS, ONE CAUSE, AND THE CAUSE IS NOT SPACING.

   Reported as "it opens with a lot of space above that you have to scroll past",
   "flat panels instead of the glass layered ones", and "not sitting on the right
   textured background".

   THE FIRST TWO ARE THE SAME BUG. .gg-sos__glimpse::before in app.v2.css is an
   OPAQUE #f2efe9 wash across the whole glimpse, added 7 Aug on purpose so a
   padlocked glimpse hides the calculator behind it. .gg-sos__live never set a
   position or a z-index, so its children paint in the same layer as that wash and
   LOSE, because the pseudo-element comes later in paint order. The header, the
   tabs, the hero and the sub-line were all rendered, visible, opacity 1, dark
   text, sitting at y=96 to y=290 - and invisible. Measured, not guessed.

   THE TELL THAT EXPLAINS EVERYTHING: the only children that DID show are
   .rl__pane and .rl__cell, and they show because backdrop-filter gives them their
   own stacking context. Nothing else on the surface has one. So "empty space at
   the top" was never spacing, and adding a negative margin - the obvious fix -
   would have moved invisible elements around and shipped the bug.

   DO NOT FIX THIS BY LOWERING THE WASH. The comment on it in app.v2.css is
   explicit that showing the calculator through it is the bug, not a feature. We
   keep it opaque and lift our own content over it instead.
   ─────────────────────────────────────────────────────────────────────────── */
.gg-scope .gg-sos__live{ position: relative; z-index: 1; }

/* The wash stays opaque, but it was a FLAT fill whilst every other surface sits on
   the concrete texture, which was the third complaint.

   AND IT MOVES OFF THE ::before ONTO THE ELEMENT, WHICH IS THE FIX FOR A SECOND
   DEFECT NICOLE FOUND BY SCROLLING. 2026-08-19, same evening.

   .gg-sos__glimpse--live is position: fixed with overflow-y: auto, and this surface
   is TALLER than the viewport - measured 1634px of content against 861px of box. The
   wash was on an `position: absolute; inset: 0` pseudo-element, which sizes to the
   scroll ORIGIN rather than to the visible box, so scrolling down slid the wash up
   and out and the pricing calculator underneath became visible through the gap.

   AN ELEMENT BACKGROUND DOES NOT SCROLL WITH OVERFLOW CONTENT. It paints over the
   padding box at every scroll position, which is exactly the behaviour wanted, and it
   needs no extra element. So the background moves here and the pseudo-element is
   switched off for this variant only - the padlocked glimpse still uses its ::before,
   because that variant centres a small card and never scrolls.

   WHY THE BUG WAS INVISIBLE UNTIL TODAY: before the stacking fix above, everything in
   .gg-sos__live painted UNDER the wash, so there was nothing worth scrolling to. The
   moment the content came out from underneath, the wash's own defect became reachable.
   One fix exposing the next is not a regression, but it does mean the surface needed
   looking at a second time rather than once. */
/* 2026-08-25 (Alexander, Loom 20 at 09:31, reported through Nicole as "it isnt
   layered"). THE PANES WERE NEVER THE PROBLEM. .gg-pane-1 is
   rgba(255,255,255,.55) over backdrop-filter: blur(6px), and a blur over a FLAT
   fill has nothing to refract, so every pane paints as a plain white card. The
   panes here measure identically to the portals own and still read wrong,
   because what differs is the GROUND.

   THIS IS THE SAME FIX AS e1a16e4 ON 24 AUG, WHICH MISSED THIS ONE SURFACE.
   That commit put the three portal backdrop layers behind their glass, but
   scoped them :has(.gg-portal-preview). The referrals surface is OUR render and
   never emits that class, so the selector could not reach it. Extending the
   scope would have been the smaller diff and is WRONG here, for the reason in
   the next paragraph.

   IT GOES ON THE ELEMENT, NOT ON ::before, AND THAT IS NOT A STYLE PREFERENCE.
   The block above records why: this variant is position: fixed with overflow-y:
   auto and its content is taller than the box, and an inset:0 pseudo-element
   sizes to the scroll ORIGIN, so it slides up and out on scroll and exposes the
   calculator underneath. Nicole found that by scrolling on 19 Aug. The 24 Aug
   comment on the :has() rule says the same thing from the other side, that the
   pseudo-element is safe THERE only because .gg-sos__blur is overflow: hidden
   and does not scroll. An element background paints over the padding box at
   every scroll position, so the layers arrive and the scroll defect does not.

   OPACITY IS PRESERVED, which is the one property the 7 Aug note in app.v2.css
   says must not be given up. The bottom layer is an opaque #efede7 and
   bg-page.webp is cover over it, so the calculator behind stays hidden.

   #efede7 RATHER THAN #f2efe9, deliberately. #efede7 is what the portals
   page-backdrop.css uses and what e1a16e4 shipped for the preview surfaces, so
   the two grounds now match instead of sitting two hex values apart.
   Layer stack and blend modes are byte-identical to the :has() rule below. */
.gg-scope .gg-sos__glimpse.gg-sos__glimpse--live{
  background:
    linear-gradient(to top, #ffffff 0%, rgba(255,255,255,0.85) 25%, rgba(255,255,255,0) 100%)
      left bottom / 100% 75vh no-repeat,
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.15  0 0 0 0 0.12  0 0 0 0 0.1  0 0 0 0.00875 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>")
      left top / 200px 200px repeat,
    url('bg-page.webp') center center / cover no-repeat,
    #efede7;
  background-blend-mode: normal, multiply, normal, normal;
}
.gg-scope .gg-sos__glimpse.gg-sos__glimpse--live::before{ content: none; }

/* The layered glass frame, traced from .thin-glass-frame in app.v2.css rather than
   invented, so the panels match every other inline panel in the calculator. It is
   copied rather than reused by class because these elements are built in
   signed-out-sidebar.jsx through React.createElement string classNames, and a CSS
   rule here keeps the two files from drifting apart at seven call sites.
   The relative URLs resolve against THIS stylesheet, which sits in assets/ beside
   app.v2.css, so the paths are the same ones that file uses. */
.gg-scope .rl__pane, .gg-scope .rl__cell{ position: relative; }
.gg-scope .rl__pane::before, .gg-scope .rl__cell::before{
  content: ''; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background:
    url('glass-frame/top-left.webp')     top left     / 14px 14px no-repeat,
    url('glass-frame/top-right.webp')    top right    / 14px 14px no-repeat,
    url('glass-frame/bottom-left.webp')  bottom left  / 14px 14px no-repeat,
    url('glass-frame/bottom-right.webp') bottom right / 14px 14px no-repeat,
    url('glass-frame/top.webp')    14px top    / calc(100% - 28px) 14px repeat-x,
    url('glass-frame/bottom.webp') 14px bottom / calc(100% - 28px) 14px repeat-x,
    url('glass-frame/left.webp')   left 14px   / 14px calc(100% - 28px) repeat-y,
    url('glass-frame/right.webp')  right 14px  / 14px calc(100% - 28px) repeat-y;
  mix-blend-mode: multiply; z-index: 1;
}
.gg-scope .rl__pane > *, .gg-scope .rl__cell > *{ position: relative; z-index: 2; }

/* ── PORTAL-SERVED PREVIEW CONTAINER, behind ?preview=live. 20 Aug 2026 ─────────
   Their markup arrives with its own stylesheet, which is scoped to .gg-preview, so it
   cannot reach our page. This rule is the reverse guard: it stops THEIR block from
   overflowing the glimpse, because their layout assumes a full portal viewport and ours
   is a fixed panel beside the rail. Nothing here restyles their components. */
.gg-scope .gg-portal-preview{
  width: 100%; max-width: 100%; overflow-x: hidden; contain: layout paint;
}
/* ══ THE PAGE SHELL PADDING, READ FROM THE PORTAL ═══════════════════════════════
   Nicole, 26 August 2026: "please can you check the margin at the top of the referrals
   view? The margin should match the portal, and I don't think it's that big." She was
   right. It was 96px against the portal's 48px, exactly double, and nothing in this file
   explained where 96 came from. The horizontal was wrong too and nobody had noticed:
   3vw is 43px at a 1440 viewport where the portal uses 104px.

   THE SOURCE IS app/account/_components/CustomerShell.tsx, whose <main> carries
   `px-4 pt-10 pb-28 sm:px-6 lg:px-12 lg:pt-12 lg:pb-8 xl:px-[104px]`. Resolved:

     base          16px sides, 40px top, 112px bottom
     >= 640px      24px sides
     >= 1024px     48px sides, 48px top, 32px bottom
     >= 1280px     104px sides

   TRACED RATHER THAN IMPORTED, and that is the reuse law's first exception stated out
   loud: their shell is Tailwind utility classes on a server component, and this is a
   plain stylesheet in an app with no build step, so there is no class or component to
   reach for. The breakpoints are Tailwind's own so the two step at the same widths.

   max-width: 1600px IS UNCHANGED and was already right. It matches SectionShellView's
   `mx-auto w-full max-w-[1600px]`. */
.gg-scope .gg-sos__live{ padding: 40px 16px 112px; max-width: 1600px; margin: 0 auto; }
@media (min-width: 640px){ .gg-scope .gg-sos__live{ padding-left: 24px; padding-right: 24px; } }
@media (min-width: 1024px){
  .gg-scope .gg-sos__live{ padding: 48px 48px 32px; }
}
@media (min-width: 1280px){ .gg-scope .gg-sos__live{ padding-left: 104px; padding-right: 104px; } }

.gg-scope .rl{ font-size: 15px; color: #0f172a; }
.gg-scope .rl__hrow{ margin-bottom: 1rem; }
.gg-scope .rl__h1{ font-size: 1.875rem; font-weight: 700; color: #0f172a; margin: 0; }
.gg-scope .rl__tabs{ display: flex; gap: .5rem; margin-bottom: 1.5rem; flex-wrap: wrap; }
.gg-scope .rl__tab{
  appearance: none; border: 1px solid #cbd5e1; background: rgba(255,255,255,.6);
  border-radius: 999px; padding: .4rem 1rem; font-size: .875rem; font-weight: 600;
  color: #475569; cursor: pointer;
}
.gg-scope .rl__tab--on{ background: #06079c; border-color: #06079c; color: #fff; }
.gg-scope .rl__hero{ font-size: 1.875rem; font-weight: 700; margin: 0 0 .25rem; color: #0f172a; }
.gg-scope .rl__sub{ font-size: .875rem; color: #64748b; margin: 0 0 2rem; max-width: 62ch; }

.gg-scope .rl__row{ display: grid; gap: 1.5rem; margin-bottom: 1.5rem; }
@media (min-width: 1024px){
  .gg-scope .rl__row--3{ grid-template-columns: 2fr 1fr; align-items: stretch; }
  .gg-scope .rl__row--2{ grid-template-columns: 1fr 1fr; align-items: stretch; }
}
.gg-scope .rl__rail{ display: grid; gap: 1rem; grid-template-columns: 1fr; }
@media (min-width: 640px){ .gg-scope .rl__rail{ grid-template-columns: 1fr 1fr; } }

.gg-scope .rl__pane,
.gg-scope .rl__cell{
  background: rgba(255,255,255,.55); backdrop-filter: blur(6px);
  border-radius: 18px; padding: 1.5rem; border: 0;
  box-shadow: 0 1px 2px rgba(15,23,42,.06), 0 8px 24px rgba(15,23,42,.06);
  display: flex; flex-direction: column;
}
.gg-scope .rl__cell{ padding: 1.25rem; }
.gg-scope .rl__cell--btn{ appearance: none; cursor: pointer; text-align: left; font: inherit; }
.gg-scope .rl__cell--on{ outline: 2px solid #06079c; outline-offset: 2px; }
.gg-scope .rl__eyebrow{
  font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em;
  color: #06079c; margin: 0 0 .75rem;
}
.gg-scope .rl__fig{ font-size: 2.25rem; font-weight: 700; font-variant-numeric: tabular-nums; margin: 0; color: #0f172a; line-height: 1.1; }
.gg-scope .rl__fig--big{ font-size: 2.25rem; }
.gg-scope .rl__fig--ok{ color: #0f8847; }
.gg-scope .rl__cap{ margin: auto 0 0; padding-top: .5rem; font-size: .875rem; line-height: 1.35; color: #475569; }
.gg-scope .rl__note{ font-size: .875rem; color: #64748b; margin: 0 0 .5rem; }
.gg-scope .rl__fine{ font-size: .75rem; color: #94a3b8; margin: .5rem 0 0; }
.gg-scope .rl__rule{ height: 1px; background: #e2e8f0; margin: .875rem 0; }
.gg-scope .rl__filterline{ font-size: .875rem; color: #475569; margin: -.5rem 0 1.5rem; }
.gg-scope .rl__linkbtn{ appearance: none; background: none; border: 0; padding: 0; font: inherit; font-weight: 600; text-decoration: underline; color: #06079c; cursor: pointer; }
.gg-scope .rl__srow{ display: flex; align-items: flex-start; justify-content: space-between; gap: 1rem; flex-wrap: wrap; }
.gg-scope .rl__h2{ font-size: 1.125rem; font-weight: 700; margin: 0 0 1rem; color: #0f172a; }

.gg-scope .rl__btn{
  appearance: none; border-radius: 10px; border: 1px solid transparent; cursor: pointer;
  font-weight: 600; font-size: .875rem; padding: .5rem 1rem; white-space: nowrap;
}
.gg-scope .rl__btn--primary{ background: linear-gradient(109deg,#2e5dff,#002abf); color: #fff; }
.gg-scope .rl__btn--sec{ background: #fff; border-color: #cbd5e1; color: #334155; }
.gg-scope .rl__btn--ghost{ background: transparent; border-color: #cbd5e1; color: #334155; }
.gg-scope .rl__btn[disabled]{ opacity: .45; cursor: not-allowed; }

.gg-scope .rl__form{ margin-top: 1rem; }
@media (min-width: 640px){ .gg-scope .rl__grid2{ grid-template-columns: 1fr 1fr; } }
.gg-scope .rl__field{ display: block; margin-bottom: 1rem; }
.gg-scope .rl__flabel{ display: block; font-size: .8125rem; font-weight: 600; color: #334155; margin-bottom: .35rem; }
.gg-scope .rl__input{
  width: 100%; border: 1px solid #cbd5e1; border-radius: 10px; padding: .55rem .75rem;
  font-size: .9375rem; color: #0f172a;
  /* the same derived concave white as the checkout fields, vv943 */
  background: linear-gradient(180deg,#FFFFFF 0%,#EDEEF2 100%);
}
/* 27 Aug 2026 (Nicole): "the text is a lighter grey". There was NO ::placeholder rule
   here at all, so these fields fell back to the browser default, which is darker than
   every other input in the product. #b8c0cc is the checkout form's own value, read from
   app.v2.css:6875 rather than sampled from a screenshot. */
.gg-scope .rl__input::placeholder{ color: #b8c0cc; }
.gg-scope .rl__input:focus{ outline: 2px solid #06079c; outline-offset: 1px; }
.gg-scope .rl__err{ color: #b91c1c; font-size: .8125rem; font-weight: 600; margin: 0 0 .5rem; }
.gg-scope .rl__done{ font-size: .875rem; color: #0f8847; font-weight: 600; margin: .75rem 0 0; }
.gg-scope .rl__frow{ display: flex; gap: .625rem; margin-top: .5rem; }

.gg-scope .rl__controls{ display: flex; flex-wrap: wrap; align-items: flex-end; gap: .75rem 1rem; margin-bottom: 1.25rem; }
.gg-scope .rl__search{ flex: 1 1 220px; min-width: 220px; }
.gg-scope .rl__ctl{ display: block; }
.gg-scope .rl__clabel{ display: block; font-size: .75rem; font-weight: 500; color: #475569; margin-bottom: .25rem; }
.gg-scope .rl__select{
  border: 1px solid #cbd5e1; border-radius: 10px; padding: .5rem .625rem;
  font-size: .875rem; background: #fff; color: #0f172a;
}
.gg-scope .rl__sr{ position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

.gg-scope .rl__tablewrap{ overflow-x: auto; border-radius: 14px; border: 1px solid #e2e8f0; }
.gg-scope .rl__table{ width: 100%; min-width: 560px; border-collapse: collapse; font-size: .875rem; background: rgba(255,255,255,.5); }
.gg-scope .rl__table th{
  text-align: left; padding: .75rem 1rem; font-size: .75rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; color: #64748b;
  background: rgba(248,250,252,.6); border-bottom: 1px solid #cbd5e1;
}
.gg-scope .rl__table td{ padding: .75rem 1rem; border-bottom: 1px solid #e2e8f0; }
.gg-scope .rl__mono{ font-family: ui-monospace,SFMono-Regular,Menlo,monospace; color: #334155; }
.gg-scope .rl__dim{ color: #94a3b8; }
.gg-scope .rl__badge{ display: inline-block; padding: .125rem .5rem; border-radius: 6px; font-size: 11px; font-weight: 700; background: #fef3c7; color: #92400e; }
.gg-scope .rl__emptycell{ padding: 3rem 1rem !important; text-align: center; }
.gg-scope .rl__emptyh{ font-weight: 600; color: #334155; margin: 0; }
.gg-scope .rl__emptys{ font-size: .875rem; color: #64748b; margin: .25rem 0 0; }
.gg-scope .rl__empty2{ text-align: center; padding: 3rem 1.5rem; }

/* The 900px override was removed on 26 August with the 96px it was correcting. It read
   `padding: 84px 5vw 5vw`, which was a second invented scale fighting the first, and it
   sat BELOW the new min-width rules so it would have overridden them at 640 to 900. The
   portal's own base and sm steps cover this range. .rl__live keeps its own rule below. */
@media (max-width: 900px){ .gg-scope .rl__live{ padding: 84px 5vw 5vw; } }

/* ── Portal preview: mirror the portal's OWN page padding, exactly ───────────
   Nicole, 20 Aug: "I want the panel sizes to be exactly the same as what we have
   on the portal, spacing, margins, and stuff like that. Don't guess."

   So this is not a guess. It is read off the portal's own <main> element:
     px-4 pt-10 pb-28 sm:px-6 lg:px-12 lg:pt-12 lg:pb-8 xl:px-[104px]
   which is 16 / 24 / 48 / 104px horizontal across their four breakpoints, and a
   bottom of 112px collapsing to 32px at lg. Measured at 1440: their main is
   1329px wide with 104px sides, giving a 1121px content box. Ours was 4vw
   (57.6px), giving 1214px - 93px too wide, with the content sitting closer to
   the edges. These rules land us on 1121px exactly.

   SCOPED TO :has(.gg-portal-preview) ON PURPOSE. The traced surfaces keep their
   own padding, so the default path that every visitor sees is untouched by this.

   TOP STAYS OURS at 104px, and that is deliberate rather than an oversight: we
   render a tab strip above the panel that the portal Home does not have, so
   their pt-12 is not a like-for-like number to copy. */
.gg-scope .gg-sos__blur:has(.gg-portal-preview){
  padding-left: 16px; padding-right: 16px; padding-bottom: 112px;
}
@media (min-width: 640px){
  .gg-scope .gg-sos__blur:has(.gg-portal-preview){ padding-left: 24px; padding-right: 24px; }
}
@media (min-width: 1024px){
  .gg-scope .gg-sos__blur:has(.gg-portal-preview){
    padding-left: 48px; padding-right: 48px; padding-bottom: 32px;
  }
}
@media (min-width: 1280px){
  .gg-scope .gg-sos__blur:has(.gg-portal-preview){ padding-left: 104px; padding-right: 104px; }
}

/* ══ THE GROUND UNDER THEIR PANEL. 24 Aug 2026, Nicole's third fault ═════════
   Reported as "you do not have the correct color of the base layered glass panel".

   IT IS NOT THE PANEL. Measured on both pages the same afternoon, their
   /partners and our rail agree exactly: background rgba(255,255,255,0.2),
   backdrop-filter blur(6px). .gg-section-base has NO colour of its own -- it is
   a fifth of white over whatever is behind it -- so a panel that matches
   declaration for declaration still reads wrong when the ground does not.

   WHAT IS BEHIND IT ON THEIR PAGE is three fixed layers from
   components/frames/page-backdrop.css: the bg-page photo on #efede7, a paper
   grain multiplied at 25%, and a white gradient rising over the lower 75vh.
   Count of those in their payload: ZERO. They live in the app shell, not in the
   surface, so the preview endpoint can never carry them.

   AND WE DO NOT NEED IT TO, because they are ours. That file's own header says
   the fade is "verbatim from gogorilla-pricing-calculator assets/app.css:37-46.
   The pricing calculator is the design source of truth for every component."
   The photo and the grain are body and body::before in the same file. This is
   the glass-and-buttons ruling again: what came from us we render from our own
   copy rather than ask them to publish back.

   WHY IT IS ON ::before AND NOT ON TWO NEW ELEMENTS. The wash is already here,
   already inset:0, already the thing painting under .gg-sos__blur. The blurred
   glimpse does not scroll -- .gg-sos__blur is overflow:hidden -- so the
   scroll-origin defect that drove the live referrals wash onto its element in
   August cannot apply. Three background layers replace one flat fill and no
   markup changes.

   THE GRAIN ALPHA IS SCALED, NOT APPROXIMATED, and this is the one line worth
   checking. Their grain is a separate element at opacity .25 with
   mix-blend-mode:multiply; ours is a background layer, and a layer carries no
   opacity of its own. For a multiply source of colour Cs and alpha As over an
   opaque backdrop Cb, element opacity O gives
       Cb*(1 - O*As*(1 - Cs))
   and a layer whose own alpha is O*As gives the identical expression. So
   0.035 * 0.25 = 0.00875 in the feColorMatrix alpha row is an EQUIVALENCE and
   not a taste judgement. Every other character of the data-URI is byte-identical
   to app.css:29, including the %23n, which breaks as a literal #.

   THE FADE IS KEPT AT 75vh EVEN THOUGH IT MAY WASH THE GLASS OUT. That argument
   has already been had on their side -- shortened to 32vh on 6 Aug for exactly
   this reason, restored on the 11th -- and the ruling recorded there is that
   parity with the calculator wins and the panes get tuned instead. These panes
   ARE theirs, so re-litigating it here would put the two pages back out of step.

   SCOPED TO :has(.gg-portal-preview) like the padding above it: the traced
   surfaces keep the flat concrete wash, so the default path every visitor sees
   is untouched. The wash also stays fully opaque, which is the one property the
   7 Aug comment in app.v2.css says must not be given up -- the calculator behind
   must not show through. bg-page.webp is cover over an opaque #efede7. */
.gg-scope .gg-sos__glimpse:has(.gg-portal-preview)::before{
  background:
    linear-gradient(to top, #ffffff 0%, rgba(255,255,255,0.85) 25%, rgba(255,255,255,0) 100%)
      left bottom / 100% 75vh no-repeat,
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='200' height='200'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/><feColorMatrix values='0 0 0 0 0.15  0 0 0 0 0.12  0 0 0 0 0.1  0 0 0 0.00875 0'/></filter><rect width='100%' height='100%' filter='url(%23n)'/></svg>")
      left top / 200px 200px repeat,
    url('bg-page.webp') center center / cover no-repeat,
    #efede7;
  background-blend-mode: normal, multiply, normal, normal;
}

/* THE TOP PADDING WAS 104px TO CLEAR A TAB STRIP THAT NO LONGER RENDERS.
   The note on the padding block above says so in as many words: "TOP STAYS OURS
   at 104px ... we render a tab strip above the panel that the portal Home does
   not have". v54 stopped drawing that strip over their composition, so the
   reason went with it and the number was left behind. Theirs is pt-10 rising to
   lg:pt-12 -- 40px, then 48px from 1024 -- and there is nothing else in the
   glimpse to clear: no close control, no header, the lock card is centred.
   Checked before changing rather than assumed. */
.gg-scope .gg-sos__blur:has(.gg-portal-preview){ padding-top: 40px; }
@media (min-width: 1024px){
  .gg-scope .gg-sos__blur:has(.gg-portal-preview){ padding-top: 48px; }
}

/* ═══════════════════════════════════════════════════════════════════════════
   THE REFERRALS SURFACE, MATCHED TO THE PORTAL. 24 Aug 2026.

   Alexander: "it has to look identical to the portal." Everything below this
   line replaces the hand-drawn .rl__* skin above it and the JS-injected
   .gg-refskin block that used to live in signed-out-sidebar.jsx. That block
   is deleted, not disabled — its `display:contents` + `order:` rules existed
   to re-sort a DOM shaped for a different layout, and the DOM is shaped like
   the portal's now.

   APPENDED RATHER THAN INTERLEAVED, DELIBERATELY. The older .rl__* rules stay
   where they are so the surrounding surfaces (.sp-*, the glimpse chrome) are
   untouched; these rules come later in the file and win on source order at
   equal specificity. The one case that matters is ::before — a cell carries
   BOTH .rl__cell and .gg-pane-1, and only one ::before can exist, so
   .gg-pane-1::before must come after .rl__cell::before. It does. Do not move
   this block above the one at the top of the file.

   PORTED FROM SOURCE, NOT MEASURED OFF A SCREENSHOT:
     components/tabs/tabs.css     → .gg-tabs / .gg-tab
     components/glass/glass.css   → .gg-section-base, .gg-pane-1, .gg-pane-2
   The asset URLs are the only edit: theirs are absolute /assets/..., and a
   relative URL in THIS file already resolves against assets/, so the prefix
   comes off. Everything else, shadow order included, is verbatim.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── The tab strip. components/tabs/tabs.css ─────────────────────────────── */
.gg-scope .gg-tabs{
  display: flex; flex-wrap: wrap; gap: 8px; align-items: stretch;
  width: fit-content; max-width: 100%; padding: 6px; border-radius: 16px;
  border: 1px solid rgba(120, 130, 160, 0.3);
  background: linear-gradient(180deg, #ececee 0%, #e2e3e8 100%);
  box-shadow: inset 0 1px 2px rgba(20, 28, 60, 0.1), 0 1px 0 rgba(255, 255, 255, 0.9);
  margin: 0 0 24px;
}
.gg-scope .gg-tab{
  position: relative; display: inline-flex; align-items: center; gap: 8px;
  padding: 14px 19px; border: 1px solid transparent; border-radius: 12px;
  font-family: inherit; font-size: 14.4px; font-weight: 600; line-height: 1;
  letter-spacing: 0.005em; white-space: nowrap; cursor: pointer;
  -webkit-appearance: none; appearance: none;
  transition: background 150ms ease, box-shadow 150ms ease, color 150ms ease, transform 150ms ease;
}
.gg-scope .gg-tab:focus-visible{ outline: 2px solid var(--gg-blue, #002abf); outline-offset: 2px; }
.gg-scope .gg-tab--ghost{
  background: linear-gradient(109deg, #e6e6e6 13%, #e6e6e6 100%); color: #111111;
  box-shadow:
    -2px -2px 2px -1px rgba(255, 255, 255, 0.36),
    inset 1px 1.5px 2px rgba(255, 255, 255, 0.6),
    inset -2px -2px 2px rgba(140, 139, 137, 0.29),
    -2px -2px 8px rgba(224, 223, 222, 0.5),
    2px 2px 8px rgba(84, 84, 84, 0.14),
    inset -1px -4px 20px rgba(179, 179, 179, 0.36);
}
.gg-scope .gg-tab--ghost:hover{ background: linear-gradient(109deg, #eeeeee 13%, #eaeaea 100%); transform: translateY(-1px); }
.gg-scope .gg-tab--ghost:active{ transform: translateY(0); }
.gg-scope .gg-tab--selected{
  background: linear-gradient(109deg, #2e5dff 0%, #002abf 60%, #001b82 100%); color: #ffffff;
  box-shadow:
    -2px -2px 2px -1px rgba(255, 255, 255, 0.5),
    inset 1px 1.5px 2px rgba(219, 227, 255, 0.69),
    inset -2.5px -2px 2px rgba(123, 145, 227, 0.63),
    2px 2px 8px rgba(84, 84, 84, 0.35),
    inset -1px -4px 20px rgba(0, 31, 145, 0.8);
}

/* ── The section base: ONE pane holding the whole surface. glass.css:547 ─── */
.gg-scope .gg-section-base{
  position: relative; isolation: isolate; padding: 24px;
  background: rgba(255, 255, 255, 0.2);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 0; border-radius: 18px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 1px 2px rgba(15, 23, 42, 0.05),
    0 18px 36px -18px rgba(44, 51, 102, 0.2);
}
.gg-scope .gg-section-base::before{
  content: ''; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background:
    url('glass-frame/top-left.webp')     top left     / 22px 22px no-repeat,
    url('glass-frame/top-right.webp')    top right    / 22px 22px no-repeat,
    url('glass-frame/bottom-left.webp')  bottom left  / 22px 22px no-repeat,
    url('glass-frame/bottom-right.webp') bottom right / 22px 22px no-repeat,
    url('glass-frame/top.webp')    22px top    / calc(100% - 44px) 22px repeat-x,
    url('glass-frame/bottom.webp') 22px bottom / calc(100% - 44px) 22px repeat-x,
    url('glass-frame/left.webp')   left 22px   / 22px calc(100% - 44px) repeat-y,
    url('glass-frame/right.webp')  right 22px  / 22px calc(100% - 44px) repeat-y;
  mix-blend-mode: multiply; z-index: 1; image-rendering: pixelated;
}
.gg-scope .gg-section-base > *{ position: relative; z-index: 2; }

/* ── Level 1 pane. glass.css:41 ──────────────────────────────────────────── */
.gg-scope .gg-pane-1{
  position: relative; isolation: isolate;
  background: rgba(255, 255, 255, 0.55);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  border: 0; border-radius: 18px;
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 1px 2px rgba(15, 23, 42, 0.05),
    0 18px 36px -18px rgba(44, 51, 102, 0.2);
  transition: box-shadow 0.2s, transform 0.2s;
}
.gg-scope .gg-pane-1::before{
  content: ''; position: absolute; inset: 0; pointer-events: none; border-radius: inherit;
  background:
    url('glass-frame/top-left.webp')     top left     / 22px 22px no-repeat,
    url('glass-frame/top-right.webp')    top right    / 22px 22px no-repeat,
    url('glass-frame/bottom-left.webp')  bottom left  / 22px 22px no-repeat,
    url('glass-frame/bottom-right.webp') bottom right / 22px 22px no-repeat,
    url('glass-frame/top.webp')    22px top    / calc(100% - 44px) 22px repeat-x,
    url('glass-frame/bottom.webp') 22px bottom / calc(100% - 44px) 22px repeat-x,
    url('glass-frame/left.webp')   left 22px   / 22px calc(100% - 44px) repeat-y,
    url('glass-frame/right.webp')  right 22px  / 22px calc(100% - 44px) repeat-y;
  mix-blend-mode: multiply; z-index: 1; image-rendering: pixelated;
}
.gg-scope .gg-pane-1::after{
  content: ''; position: absolute; inset: 1px; border-radius: inherit; pointer-events: none;
  background: radial-gradient(130% 90% at 50% -15%, rgba(255, 255, 255, 0.5), transparent 55%);
  z-index: 0;
}
.gg-scope .gg-pane-1 > *{ position: relative; z-index: 2; }
.gg-scope .gg-pane-1--tinted{ background: linear-gradient(90deg, #ffffff 0%, #e8edff 100%); }
.gg-scope .gg-pane--selectable{ cursor: pointer; }
.gg-scope .gg-pane--selectable:not(.gg-pane--selected):hover{
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 1px 2px rgba(15, 23, 42, 0.05),
    0 20px 40px -18px rgba(44, 51, 102, 0.26);
  transform: translateY(-1px);
}
.gg-scope .gg-pane-1.gg-pane--selected{
  background: linear-gradient(180deg, rgba(255, 255, 255, 0.92) 0%, rgba(232, 238, 255, 0.85) 100%);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, 0.9),
    0 1px 2px rgba(15, 23, 42, 0.05),
    0 0 0 2px rgba(0, 42, 191, 0.45),
    0 18px 36px -18px rgba(0, 42, 191, 0.3);
}

/* ── Level 2 pane: the metal-framed money cell. One per screen, never nested. */
.gg-scope .gg-pane-2{
  --gg-pane-2-slice: 18px;
  position: relative; isolation: isolate;
  background:
    linear-gradient(rgba(255, 251, 244, 0.5), rgba(255, 251, 244, 0.5)),
    url('UI_Card_Concrete_02_Seamless.webp') 0 0 / 480px 480px repeat;
  -webkit-backdrop-filter: none; backdrop-filter: none;
  border: 0;
  border-radius: calc(var(--gg-pane-2-slice) * 0.86);
  box-shadow: 0 1px 2px rgba(15, 23, 42, 0.08), 0 12px 32px rgba(15, 23, 42, 0.1);
}
.gg-scope .gg-pane-2::before{ content: none; }
.gg-scope .gg-pane-2::after{
  content: ''; position: absolute; inset: 0; border-radius: inherit; pointer-events: none;
  image-rendering: pixelated; background-repeat: no-repeat;
  background-image:
    url('metal-frame/Metal%20frame-top%20left.webp'),
    url('metal-frame/Metal%20frame-top%20center.webp'),
    url('metal-frame/Metal%20frame-top%20right.webp'),
    url('metal-frame/Metal%20frame-left.webp'),
    url('metal-frame/Metal%20frame-right.webp'),
    url('metal-frame/Metal%20frame-bottom%20left.webp'),
    url('metal-frame/Metal%20frame-bottom%20center.webp'),
    url('metal-frame/Metal%20frame-bottom%20right.webp');
  background-size:
    var(--gg-pane-2-slice) var(--gg-pane-2-slice),
    calc(100% - (2 * var(--gg-pane-2-slice))) var(--gg-pane-2-slice),
    var(--gg-pane-2-slice) var(--gg-pane-2-slice),
    var(--gg-pane-2-slice) calc(100% - (2 * var(--gg-pane-2-slice))),
    var(--gg-pane-2-slice) calc(100% - (2 * var(--gg-pane-2-slice))),
    var(--gg-pane-2-slice) var(--gg-pane-2-slice),
    calc(100% - (2 * var(--gg-pane-2-slice))) var(--gg-pane-2-slice),
    var(--gg-pane-2-slice) var(--gg-pane-2-slice);
  background-position: left top, center top, right top, left center, right center, left bottom, center bottom, right bottom;
  opacity: 0.85; z-index: 0;
}
.gg-scope .gg-pane-2 > *{ position: relative; z-index: 1; }

/* ── The page's own rhythm. ─────────────────────────────────────────────── */
.gg-scope .rl__hrow{ margin: 0 0 16px; }
.gg-scope .rl__h1{ font-size: 1.875rem; font-weight: 700; color: #0f172a; margin: 0; }
.gg-scope .rl__hero{ font-size: 1.875rem; font-weight: 700; margin: 0 0 4px; color: #0f172a; }
/* ⚠️ max-width IS RESET HERE ON PURPOSE, 26 August 2026. The rule further up this file
   caps .rl__sub at 62ch, which measured 548px inside a 1229px panel, so the lede sat in
   the first column whilst the heading above it ran the full width. Nicole spotted the
   mismatch. 62ch is a sensible measure for a paragraph in a narrow column and wrong for
   a lede under a full-width heading, so this overrides rather than edits the earlier
   rule, which other surfaces still use. */
.gg-scope .rl__sub{ font-size: .875rem; line-height: 1.5; color: #64748b; margin: 0 0 32px; max-width: none; }

/* THE EYEBROW IS THE ONE TYPE STYLE THAT REPEATS EVERYWHERE ON THIS SURFACE.
   text-xs font-bold uppercase tracking-widest text-brand, on every card title,
   every rail label and the FAQ heading. --gg-blue is the calculator's own token
   and is the same #002ABF the portal's --brand resolves to. */
.gg-scope .rl__eyebrow{
  font-size: .75rem; font-weight: 700; text-transform: uppercase;
  letter-spacing: .1em; color: var(--gg-blue, #002abf); margin: 0;
}

/* ── ROW ONE: link, submit, earnings. Equal thirds, shared height. ──────── */
/* TWO PANES, NOT THREE. The Earnings pane was removed on 25 August, so the class is
   renamed with it: a name that is only true in one branch is the same rot as a comment
   that is only true in one branch, which is this file's own rule.
   THE ACTION PANE IS THE WIDER OF THE TWO because it holds the picker, the field and
   the button, whilst the link pane holds a line of text until a link exists. Equal
   thirds were what made the link pane read as mostly empty. */
/* ⚠️ stretch AGAIN, AND THE ROUTE HERE MATTERS MORE THAN THE VALUE.
   It was stretch, then start this morning, and stretch again this afternoon. That is not
   indecision, it is the same rule applied to two different panels.
   THE RULE: a stretched pair is as tall as its taller half, so it is only safe when the two
   halves are close. It was not safe this morning: panel 01 held four short lines beside a
   panel 02 carrying a form skeleton and a cover, and the left panel filled with air. 371px,
   then 95px, then 171px across three attempted fixes. start removed it by letting each panel
   size itself.
   WHAT CHANGED SINCE: the registration form moved into an overlay, so panel 01 is a prompt
   and a button, and panel 02 lost the mode pills to its header row and two thirds of its
   skeleton. The two are now within a few dozen pixels of each other, so stretch costs almost
   nothing and gives Nicole the matched pair she asked for.
   ⚠️ IF PANEL 02 EVER GROWS AGAIN, THIS GOES BACK TO start. The air is a symptom of the gap
   between the two, not of this property, and the measurement is the thing to check rather
   than the value. */
.gg-scope .rl__panes{
  display: grid; grid-template-columns: minmax(0, 0.85fr) minmax(0, 1.15fr);
  gap: 24px; align-items: stretch; margin: 0 0 24px;
}
.gg-scope .rl__p6{ padding: 24px; }
.gg-scope .rl__col{ display: flex; flex-direction: column; }
/* mt-auto on their side: the button and the "N active referrals" line are
   pushed to the foot of the card so all three panes agree at the baseline. */
.gg-scope .rl__push{ margin-top: auto; padding-top: 20px; }
.gg-scope .rl__shead{ display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; margin-bottom: 12px; }
.gg-scope .rl__sharebtn{
  display: inline-flex; align-items: center; gap: 6px; flex-shrink: 0;
  border: 1px solid #cbd5e1; border-radius: 8px; padding: 4px 10px;
  font-size: .75rem; font-weight: 500; color: #334155; background: transparent;
}
.gg-scope .rl__sharechev{ width: 14px; height: 14px; }
.gg-scope .rl__note{ font-size: .875rem; line-height: 1.5; color: #64748b; margin: 4px 0 0; }
.gg-scope .rl__fine{ font-size: .75rem; line-height: 1.5; color: #94a3b8; margin: 8px 0 0; }
.gg-scope .rl__fig{ font-size: 2.25rem; font-weight: 700; font-variant-numeric: tabular-nums; margin: 8px 0 0; color: #0f172a; line-height: 1.1; }
.gg-scope .rl__fig--big{ margin: 12px 0 4px; }
.gg-scope .rl__fig--ok{ color: var(--gg-success, #0f8847); }
.gg-scope .rl__cap0{ font-size: .875rem; color: #64748b; margin: 0; }
.gg-scope .rl__strong{ font-weight: 600; color: #0f172a; }

/* ── THE PANEL: heading, rail, filters, table, count. ───────────────────── */
.gg-scope .rl__panel{ padding: 24px; display: flex; flex-direction: column; }
.gg-scope .rl__phead{ display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 4px 16px; margin-bottom: 16px; }
.gg-scope .rl__h2{ font-size: 1.125rem; font-weight: 700; margin: 0; color: #0f172a; }
.gg-scope .rl__filterline{ font-size: .875rem; color: #475569; margin: 0; }
.gg-scope .rl__linkbtn{ appearance: none; background: none; border: 0; padding: 0; font: inherit; font-weight: 600; text-decoration: underline; color: inherit; cursor: pointer; }

/* The pipeline, four across, INSIDE the panel. Their 19 Aug arrangement: the
   rail is the table's stage filter, so it belongs in the box with the table. */
.gg-scope .rl__rail{ display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; margin-bottom: 20px; }
.gg-scope .rl__cellbtn{
  appearance: none; background: none; border: 0; padding: 0; margin: 0; font: inherit;
  text-align: left; cursor: pointer; display: block; height: 100%;
}
.gg-scope .rl__cellbtn:focus-visible{ outline: 2px solid var(--gg-blue, #002abf); outline-offset: 2px; border-radius: 18px; }
/* Overrides the older .rl__cell box above; the pane classes own the surface now.
   DO NOT ADD `background` OR `border` HERE. Both are set by .gg-pane-1 and
   .gg-pane-2, which sit at the same specificity — a declaration in this rule
   wins on source order and would strip the fill off all four cells. Layout
   only, and the older .rl__cell rule further up is already outranked by the
   pane classes for everything else. */
.gg-scope .rl__cell{
  display: flex; flex-direction: column; height: 100%; padding: 20px;
}
.gg-scope .rl__cell .rl__fig{ margin-top: 8px; }
.gg-scope .rl__cap{ margin: auto 0 0; padding-top: 8px; font-size: .875rem; line-height: 1.35; color: #475569; }

/* The filter row, all on one baseline: the search box has no visible label and
   the four selects do, so without items:end the box floats above them. */
.gg-scope .rl__controls{ display: flex; flex-wrap: wrap; align-items: flex-end; gap: 16px 12px; margin-bottom: 20px; }
.gg-scope .rl__search{ flex: 1 1 220px; min-width: 220px; }
.gg-scope .rl__searchbox{ position: relative; }
.gg-scope .rl__searchicon{ position: absolute; left: 12px; top: 50%; transform: translateY(-50%); width: 16px; height: 16px; color: #94a3b8; pointer-events: none; }
.gg-scope .rl__input--search{ padding-left: 36px; }
.gg-scope .rl__ctl{ display: block; }
.gg-scope .rl__clabel{ display: block; font-size: .75rem; font-weight: 500; color: #475569; margin-bottom: 4px; }
.gg-scope .rl__select{
  appearance: none; border: 1px solid #cbd5e1; border-radius: 8px;
  background: rgba(255,255,255,.7) url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2364748b' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 8px center / 14px 14px;
  padding: 8px 30px 8px 10px; font: inherit; font-size: .875rem; color: #0f172a; cursor: pointer;
}
.gg-scope .rl__export{ margin-left: auto; }
.gg-scope .rl__sr{ position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

/* The table sits in its own level-1 pane inside the panel, overflow hidden so
   the rows clip to the pane radius. */
.gg-scope .rl__tablepane{ overflow: hidden; }
.gg-scope .rl__tablewrap{ overflow-x: auto; border: 0; border-radius: 0; }
.gg-scope .rl__table{ width: 100%; min-width: 560px; border-collapse: collapse; font-size: .875rem; background: transparent; }
.gg-scope .rl__table thead{ background: rgba(248, 250, 252, .6); }
.gg-scope .rl__table th{
  text-align: left; padding: 12px 16px; font-size: .75rem; font-weight: 700;
  text-transform: uppercase; letter-spacing: .05em; color: #64748b;
  border-bottom: 1px solid rgba(15, 23, 42, .08);
}
.gg-scope .rl__table td{ padding: 12px 16px; border-bottom: 1px solid rgba(15, 23, 42, .08); }
.gg-scope .rl__table tbody tr:last-child td{ border-bottom: 0; }
.gg-scope .rl__table tbody tr{ transition: background-color .15s; }
.gg-scope .rl__table tbody tr:hover{ background: rgba(15, 23, 42, .05); }
.gg-scope .rl__empty{ display: flex; flex-direction: column; align-items: center; justify-content: center; padding: 48px 16px; text-align: center; }
.gg-scope .rl__foot{ display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; margin-top: 20px; }
.gg-scope .rl__count{ font-size: .875rem; color: #475569; margin: 0; }

/* Status pills, StatusBadge variant="referral". */
.gg-scope .rl__badge{ display: inline-block; padding: 2px 8px; border-radius: 6px; font-size: 11px; font-weight: 700; background: #fef3c7; color: #92400e; }

/* ── THE FAQ, full width under the panel. ───────────────────────────────── */
.gg-scope .rl__faq{ padding: 24px; margin-top: 32px; }
/* THE SIX .rl__faq ROW RULES WERE DELETED HERE, 26 August 2026, NOT LEFT DORMANT.
   They dressed a hand-rolled accordion on this surface that turned out to duplicate
   GMFaq, the house component this repo has carried all along and which the portal's
   own GGAccordion is a verbatim port of. The FAQ now renders GMFaq and inherits
   .gm-ov__faq* from app.v2.css, so these had no emitter left.
   Deleted rather than kept, on the ggFillBlanks rule of 25 August: a rule kept just in
   case is a second representation of one design waiting for somebody to reach for it.
   .rl__faq and .rl__faqt survive, because the CARD and its eyebrow heading are still
   ours; only the rows moved. */
.gg-scope .rl__faqt{
  font-size: .75rem; font-weight: 700; text-transform: uppercase; letter-spacing: .1em;
  color: var(--gg-blue, #002abf); margin: 0 0 16px;
}

/* ── The candidates tab. Their 3fr/2fr grid, ported off .gg-refskin. ────── */
.gg-scope .rl__cand{ display: grid; grid-template-columns: 3fr 2fr; gap: 16px; align-items: start; }
.gg-scope .rl__candl{ display: flex; flex-direction: column; gap: 16px; }
.gg-scope .rl__step{ display: flex; gap: 12px; margin-top: 18px; }
.gg-scope .rl__stepn{ flex: 0 0 auto; width: 28px; height: 28px; border-radius: 8px; background: #eef2ff; color: var(--gg-blue, #002abf); font-weight: 700; font-size: 12px; display: flex; align-items: center; justify-content: center; }
.gg-scope .rl__lockwrap{ position: relative; }
.gg-scope .rl__lockwrap > .rl__locked{ filter: blur(5px); pointer-events: none; user-select: none; }

/* ── Narrow. 1024 is the breakpoint the portal's own lg: prefix uses, so the
   two stack at the same width rather than at two widths a hair apart. ───── */
@media (max-width: 1023px){
  .gg-scope .rl__panes{ grid-template-columns: 1fr; }
  .gg-scope .rl__rail{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .gg-scope .rl__cand{ grid-template-columns: 1fr; }
}
@media (max-width: 639px){
  .gg-scope .rl__rail{ grid-template-columns: 1fr; }
  .gg-scope .rl__export{ margin-left: 0; }
}

/* The "(optional)" span inside .rl__flabel. The field() factory in
   signed-out-sidebar.jsx emits this class and SubmitReferralForm.tsx carries the
   word as a lighter run inside the label rather than as separate text beside it,
   but no rule was ever written for it, so it inherited the label's 600 weight and
   read as part of the field name. Weight and colour only; the span is inline. */
.gg-scope .rl__fopt{ font-weight: 400; color: #94a3b8; }

/* ══ REFERRALS PANE DEPTH — REVERTED 25 AUGUST 2026 ══════════════════════════
   Nicole's ruling, after comparing this surface with the portal's own referrals page.

   WHAT WAS HERE. Two levels of pane, scoped to .rl: level 1 tinted to a warm neutral
   at .86 falling to .74, level 2 cells raised to near white. It was built to answer
   Alexander's "it isnt layered" and it did make a hierarchy.

   WHY IT WENT. It made us DIVERGE FROM THE PORTAL, which is the one thing this
   surface is not allowed to do. Checked against their repo rather than assumed:
   components/glass/glass.css line 41 still defines .gg-pane-1 as
   rgba(255, 255, 255, 0.55) with the same blur and the same shadow, unchanged. They
   never moved. Our port was already correct and the tint was a local deviation from
   it dressed up as a fix.

   WHAT THE REAL DIFFERENCE WAS, and it is worth being precise because the tint was
   aimed at the wrong thing. The panes were always identical to theirs. The GROUND
   behind them differed, which is what c71125ed fixed and that fix STAYS: four
   backdrop layers on the element rather than one flat wash. A pane with nothing to
   refract reads flat however you colour it.

   SO THE PANES ARE THE SHARED .gg-pane-1 PORT AGAIN, with no local override, and any
   future change to their depth belongs in the portal's component so both surfaces
   move together. */

/* ══ RAIL TOOLTIPS ════════════════════════════════════════════════════════════
   2026-08-25. Loom 20 at 09:16: "there should be side tooltips, maybe with a
   pointy arrow, so you go on this, tooltip, tooltip, tooltip." Nicole scoped it to
   the rail items on the left.

   IN THIS FILE RATHER THAN app.v2.css, DELIBERATELY. The rail itself is styled in
   app.v2.css because it mirrors FreelancerRail.tsx and re-syncs against it. These
   tips are ours and exist only on the signed-out surface, so they live beside the
   other .gg-sos overrides where a future rail re-sync will not have to step around
   them. app.v2.css is also the shared production stylesheet at vv952 and this
   change has no business widening its blast radius.

   NO CLIPPING TO FIGHT, CHECKED BEFORE BUILDING. .gg-sos__rail is
   position: fixed, width 96px, z-index 40, and sets NO overflow, so an absolutely
   positioned child paints outside the rail box. It sits above the glimpse, which
   is z-index 39. The one thing the item was missing is position: relative, which
   it never needed until now.

   CSS ONLY, NO STATE. The tip is a child of the button, so :hover and
   :focus-visible on the button drive it with no listener, no portal and no React
   state to get out of step with the pointer. focus-visible is not decoration here,
   it is the only way a keyboard reaches these at all.

   POINTER IS A ROTATED SQUARE, not a border triangle, because the tip has a
   1px border and a shadow and a border triangle cannot carry either. */
.gg-scope .gg-sos__item{ position: relative; }

/* ⚠️ RESTYLED 25 AUG, SAME DAY, AND THE FIRST VERSION WAS OFF BRAND.
   I shipped these as a navy card with a rotated-square pointer. Nicole challenged
   the colour and she was right. Every tooltip in this product is a WHITE card:
   .dis-tip, .info-tip-portal, .step-lock-tip, .wl-tip, .summary__total-tip,
   .addon__capacity-tip and the step-indicator tips are all #ffffff on #4b5563 or
   #374151, and there is not one dark tooltip anywhere in app.v2.css. Mine was the
   only one in the codebase, which is the definition of off brand.

   AND ALEXANDER SAID SO IN THE ASK. Loom 20 at 09:16 is "a bit like we've got
   tooltips HERE" - a pointer at the existing component, not a request for a new
   one. I read it as a request for tooltips and invented a style. Reuse, not
   reinvention, and this file already had the answer.

   EVERY VALUE BELOW IS .dis-tip's, at app.v2.css:2494, not chosen here. If that
   component is restyled, this should be restyled with it rather than drifting.

   THE CARET IS THE CANONICAL TWO-PIECE BORDER TRIANGLE, not my rotated square.
   My commit message claimed a border triangle cannot carry a 1px border, which is
   why I reached for a square. That is wrong, and the house solved it long ago:
   ::before draws a 7px triangle in the border colour, ::after draws a 6px white
   one over it offset by 1px, and the sliver that shows through IS the hairline.
   This is the --right variant that did not exist, built from the --above and
   --below pair rather than freehand.

   Z-INDEX STAYS SMALL ON PURPOSE. .dis-tip uses 2147483647 because it is portalled
   to the document root and has to beat everything. This one is a child of the rail,
   which is its own stacking context via backdrop-filter, so the tip only ever
   competes with its six sibling items and a large value would be cargo cult. */
.gg-scope .gg-sos__tip{
  position: absolute; left: calc(100% - 2px); top: 50%;
  transform: translate(-4px, -50%);
  z-index: 3;
  width: 220px;
  padding: 0.65rem 0.8rem;
  background: #ffffff;
  border: 1px solid rgba(0, 0, 0, 0.09);
  border-radius: 10px;
  box-shadow: 0 4px 18px rgba(0, 0, 0, 0.13);
  font-size: 0.73rem; line-height: 1.45; font-weight: 400;
  color: #4b5563;
  text-align: left; white-space: normal; letter-spacing: 0; text-transform: none;
  opacity: 0; visibility: hidden; pointer-events: none;
  transition: opacity .16s ease, transform .16s ease, visibility 0s linear .16s;
}
/* The hairline half of the caret. */
.gg-scope .gg-sos__tip::before{
  content: ''; position: absolute;
  right: 100%; top: 50%; transform: translateY(-50%);
  border: 7px solid transparent;
  border-right-color: rgba(0, 0, 0, 0.09);
  border-left-width: 0;
}
/* The white fill, one pixel over it, leaving the hairline showing as an edge. */
.gg-scope .gg-sos__tip::after{
  content: ''; position: absolute;
  right: calc(100% - 1px); top: 50%; transform: translateY(-50%);
  border: 6px solid transparent;
  border-right-color: #ffffff;
  border-left-width: 0;
}
.gg-scope .gg-sos__item:hover > .gg-sos__tip,
.gg-scope .gg-sos__item:focus-visible > .gg-sos__tip{
  opacity: 1; visibility: visible;
  transform: translate(6px, -50%);
  transition: opacity .16s ease, transform .16s ease, visibility 0s;
}

/* NO PHONE RULE IS NEEDED HERE, AND I WROTE ONE BEFORE CHECKING. Recorded because
   the wrong version was plausible. I added a max-width: 900px rule to hide the tip,
   on the assumption that the rail becomes a bottom bar at that width and a
   right-anchored tip would land off screen. Both halves were wrong. The breakpoint
   is 820px, and at 820px the rail is not a bottom bar, it is display: none
   outright, on Nicole's 10 August ruling that phones do not get the preview rail at
   all because .mobile-bar covers it at z-index 60 and made all seven items
   unhittable. A child of a display: none ancestor is already gone, so the rule
   guarded a state that cannot occur. The bottom-bar rules above that block in
   app.v2.css are deliberately kept dead code, which is what made the wrong
   assumption so easy to reach by skimming. */

/* Reduced motion keeps the tooltip, drops the travel. It is an affordance, not an
   animation, so removing it entirely would remove the information. */
@media (prefers-reduced-motion: reduce){
  .gg-scope .gg-sos__tip{ transition: opacity .01s linear, visibility 0s linear .01s; transform: translate(6px, -50%); }
  .gg-scope .gg-sos__item:hover > .gg-sos__tip,
  .gg-scope .gg-sos__item:focus-visible > .gg-sos__tip{ transform: translate(6px, -50%); }
}

/* ══ THE COARSE SERVICE PICKER ════════════════════════════════════════════════
   2026-08-25. FREELANCER 20 at 21:47 asked for the services at a coarse grain,
   shown back as tags. It shipped as nine chips in a grid and Nicole changed it to a
   dropdown the same day, with Vercel's Environments picker as the reference: nine
   chips made the middle pane far taller than the two beside it, and the trio is
   stretched to a shared height, so the whole row grew to fit one panel.

   THE PANEL IS TRACED FROM .bd-commit-menu IN app.v2.css, our own dropdown, so this
   is not a fifth panel style in the product. Same white, same 10px radius, same
   shadow, same blue at 0.07 for hover and 0.10 for selected. Traced rather than
   reused by class because that component lives in the shared production stylesheet
   and this surface should not start depending on the commitment picker.

   THE PORTAL'S OWN PICKER COULD NOT BE REUSED. QuickLinksPicker.tsx is a Radix
   Popover, and this repo loads React and Babel from a CDN with no build step, so
   Radix is not available. Its own doc block records that it is a Popover only
   because drag-to-reorder was asked for, and that it began as a dropdown menu with
   checkbox items. We need no reordering, so the earlier shape is the right one. */

/* The trigger. Sized and coloured as the white checkout field, which is the input
   treatment Nicole ruled for every typing field on 14 August, so a control that sits
   directly above a real input does not read as a different species. */
/* ⚠️ THE MENU PAINTED BEHIND THE FORM AND EVERY DOM CHECK PASSED. Fixed 25 Aug 2026.
   The panel is z-index 30 and the fields behind it are 2, so on paper it wins. It did
   not, and the cause is one line in app.v2.css that has nothing to do with this
   component: `.gg-pane-1 > *` sets `position: relative; z-index: 2` on every direct
   child of a pane. .rl__dd is a direct child, so it inherits a NON-AUTO z-index whilst
   positioned, which makes it A STACKING CONTEXT. The menu's 30 is then scoped inside
   .rl__dd and competes with nothing, whilst the form, a later sibling at the same
   z-index 2, paints over it.
   PROVED, NOT REASONED: elementFromPoint at the centre of the open menu returned
   .rl__fine, the fine print behind it.
   THE FIX IS TO RAISE .rl__dd ITSELF, because a stacking context can only be escaped by
   its parent. Scoped `.rl__p6 > .rl__dd` at (0,3,0) so it beats `.gg-pane-1 > *` at
   (0,2,0) outright rather than depending on which stylesheet loads last.
   SAME FAMILY AS THE 19 AUGUST BUG ON THIS SURFACE, where .gg-sos__live had no position
   and its children lost to a pseudo-element that came later in paint order. A z-index
   is a claim about a stacking context, and the context is usually somewhere else. */
.gg-scope .rl__dd{ position: relative; margin: 0.75rem 0 0; }
/* ⚠️ THIS FIX WAS SCOPED TO A PARENT AND THE PARENT CHANGED. Rewritten 25 Aug.
   The first version was `.rl__p6 > .rl__dd`, which worked until the picker moved into
   .rl__pickpanel for the two-column layout. The selector then matched nothing, the
   dropdown fell back to the z-index 2 it inherits, and the menu painted UNDER its own
   later siblings again: measured, elementFromPoint returned rl__tags, rl__flabel and
   rl__tiers through the open menu.
   SO IT NO LONGER NAMES AN ANCESTOR. The doubled class is the smallest way to beat the
   (0,2,0) rule that sets z-index 2 on pane children without tying this to whichever
   container the picker happens to live in next. A stacking fix that depends on the
   parent's class is a fix with an expiry date. */
.gg-scope .rl__dd.rl__dd{ z-index: 5; }

/* AND THE SAME BUG ONE LEVEL UP, WHICH THE FIRST FIX DID NOT REACH. I raised .rl__dd,
   confirmed the top of the menu was now on top, and the BOTTOM of it was still covered
   by the Your referrals panel below. .rl__panes is itself a direct child of
   .gg-section-base, so it takes position relative with z-index 2 from that pane rule
   too, and is therefore ITS OWN stacking context. Everything I did inside it was
   invisible to the comparison that actually mattered, which is .rl__panes against
   .rl__panel, two siblings at the same z-index where the later one in the DOM wins.

   THE RULE, AND IT IS THE REUSABLE PART: fix stacking at the level where the two
   elements you are comparing are SIBLINGS. I stopped at the first stacking context I
   found rather than walking up to the common ancestor, so I fixed a real problem that
   was not the whole problem and reported it as done. Walk the chain to the common
   ancestor and print it, exactly as the 19 August note on this surface says for
   filter, opacity and pointer-events. */
.gg-scope .gg-section-base > .rl__panes{ z-index: 6; }
/* THE ADD-ONS BAR SHAPE, per Nicole 25 Aug. Traced from the collapsed add-ons row on
   the calculator: plus square, bold count, blue chip, chevron at the far right, on a
   taller white bar with a soft ring rather than a plain 1px input border. Same visual
   sentence as the control it sits beneath, which is the point of tracing rather than
   inventing a second row idiom for the same job. */
.gg-scope .rl__ddbtn{
  width: 100%; display: flex; align-items: center; gap: 0.6rem;
  appearance: none; cursor: pointer; text-align: left;
  background: #ffffff;
  border: 1px solid rgba(15,23,42,0.10);
  border-radius: 12px;
  padding: 0.72rem 0.85rem;
  font-size: 0.85rem; font-weight: 700; line-height: 1.3; color: #0f172a;
  box-shadow: 0 1px 2px rgba(15,23,42,0.05), 0 4px 12px rgba(15,23,42,0.045);
  transition: border-color .14s ease, box-shadow .14s ease;
}
.gg-scope .rl__ddplus{
  flex: 0 0 auto; width: 22px; height: 22px; border-radius: 7px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(0,42,191,0.07); border: 1px solid rgba(0,42,191,0.16);
  color: var(--gg-blue, #002abf); font-size: 0.95rem; font-weight: 700; line-height: 1;
}
.gg-scope .rl__ddlbl{ flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* The chip is the add-ons bar's "4 available without a plan" in the same blue tint. */
.gg-scope .rl__ddchip{
  flex: 0 0 auto; display: inline-flex; align-items: center;
  background: rgba(0,42,191,0.08); color: var(--gg-blue, #002abf);
  font-size: 0.72rem; font-weight: 600; border-radius: 5px; padding: 2px 7px;
}
.gg-scope .rl__ddbtn:hover{ border-color: rgba(0,42,191,0.35); }
.gg-scope .rl__ddbtn.is-open,
.gg-scope .rl__ddbtn:focus-visible{
  border-color: rgba(0,42,191,0.55);
  box-shadow: 0 0 0 3px rgba(0,42,191,0.12);
  outline: none;
}
/* The placeholder is lighter than a chosen value, which is the only thing telling a
   reader at a glance whether they have answered this yet. */
.gg-scope .rl__ddbtn.is-open{ box-shadow: 0 0 0 3px rgba(0,42,191,0.12); }
.gg-scope .rl__ddchev{ flex: 0 0 auto; width: 14px; height: 14px; color: #64748b; transition: transform .16s ease; }
.gg-scope .rl__ddbtn.is-open .rl__ddchev{ transform: rotate(180deg); }

/* The panel, from .bd-commit-menu. z-index 30 is its value too, and it sits inside
   .gg-sos__live which is z-index 1, so it clears the panes without touching the rail. */


/* The read-back. A dropdown hides the answer the moment it closes, so these are what
   keeps it visible, which is the "shows here as tags" half of the ask. Not
   interactive: the dropdown is the one place the selection changes. */
/* .rl__tags / .rl__tag / .rl__tag--more WERE DELETED 26 AUGUST 2026. The chosen
   services stopped being a read-back and became the switcher, so they are now
   .qual-pill inside a .qualifier-q__opts--pills row, which is the component Nicole
   named and which app.v2.css:11771 already defines. The rules are removed rather than
   left dormant, because a dormant rule for a replaced shape is how the replaced shape
   returns: the next person to write className 'rl__tag' gets a styled chip and no
   error, and this surface quietly has two pill designs again.
   ONLY THE MARGIN IS OURS. Everything else about these pills, the fill, the border, the
   radius, the selected inversion, comes from app.v2.css and must keep coming from
   there. */
.gg-scope .rl__svcpills{ margin: 0.6rem 0 0; }

/* ── THE DEDICATED RESOURCES PANEL ────────────────────────────────────────────
   26 Aug 2026, THIRD version. Layout ONLY. The dropdown is .rl__dd*, the checkbox is
   .rl__ddbox (traced from the portal's options popover in August) and the small
   control on the header row is .bd-commit-pill. NOTHING HERE RESTATES A BORDER, A
   RADIUS OR A COLOUR ON ANY OF THEM.

   WHAT THE TWO EARLIER VERSIONS GOT WRONG, kept short because both are gone: a
   native <select>, then image flags fetched for a checkbox-sized slot. The flags are
   now the emoji FT_LOCATIONS has carried since June.

   ONE ROW PER ROLE, ONE CHECKBOX PER OFFICE. A role wanted in two offices is two
   people, which is the case neither earlier version could express. */
/* TWO FIELDS ON ONE ROW, 26 Aug 2026. The registration form gained four fields and
   Nicole's standing complaint about this pane is vertical space, so first and last name
   share a line. Layout only, and the fields keep .rl__field and .rl__input untouched.
   Collapses to one column on a narrow pane rather than squeezing two inputs nobody can
   type into. */
.gg-scope .rl__fpair{ display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 560px){ .gg-scope .rl__fpair{ grid-template-columns: 1fr; } }

.gg-scope .rl__ded{ display: flex; flex-direction: column; gap: 10px; margin-top: 0.6rem; }
.gg-scope .rl__dednote{ margin: 2px 0 0; }

/* ── THE COMMITMENT MENU MUST PAINT OVER THE TIER CARDS ───────────────────────
   26 Aug 2026, reported by Nicole and then MEASURED rather than guessed at:
     .svc__tier-label-row   position: relative; z-index: 2
     .tiers                 position: relative; z-index: 2
   They are SIBLINGS inside .refer-who-select and .tiers comes later in the DOM. At
   equal z-index the later sibling wins, so the tier grid painted over the label row
   and everything inside it. The menu's own z-index of 30 could never help: it only
   orders the menu WITHIN the label row's stacking context, and it was that whole
   context losing.
   THE FIX IS ONE NUMBER ON THE ROW, not on the menu. Raising the menu again would
   have looked like a fix and changed nothing, which is how a z-index gets bumped
   four times and still loses. */
.gg-scope .svc__tier-label-row.rl__tierrow{ position: relative; z-index: 4; }

/* The grid: role name takes the space left over, then one fixed cell per office. The
   cells are a fixed width so every row's checkboxes line up under their heading, which
   is the whole reason the heading can be words and the cells can be flags. */
.gg-scope .rl__ddroles{ display: flex; flex-direction: column; gap: 2px; max-height: 320px; overflow-y: auto; }
.gg-scope .rl__ddrolehead,
.gg-scope .rl__ddrolerow{
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 10px;
}
/* Sticky so the office headings stay visible whilst a long role list scrolls. The
   backdrop is `inherit`, NOT a repeated #ffffff: the menu already sets its own and
   restating it here would be a second place to change if it ever moves. */
.gg-scope .rl__ddrolehead{ position: sticky; top: 0; background: inherit; z-index: 1; }
/* The eyebrows in this header lose the rule the service picker's carry: there it
   separates groups within one list, here it would draw a line across the top of the
   menu for no reason. */
.gg-scope .rl__ddrolehead .rl__ddeyebrow{ border-top: 0; padding-top: 0; }
/* 76px, NOT 56px. Measured on the live page 26 Aug 2026: at 56px "PHILIPPINES" and
   "SOUTH AFRICA" collided into "PHILIPPINESSOUTH AFRICA" because the heading could not
   break inside a word. The cell now fits the longest single word and the two-word names
   wrap cleanly onto two lines. */
.gg-scope .rl__ddflaghead{
  width: 80px; text-align: center; padding-left: 2px; padding-right: 2px;
  line-height: 1.25;
  /* 10px and NO letter-spacing, measured rather than chosen. At 11px with the eyebrow's
     0.025em tracking, "PHILIPPINES" needs ~79px and broke mid-word as "PHILIPPINE / S",
     one orphaned letter. Dropping the tracking and a point of size fits the longest
     single word on one line, so only the two-word names wrap, and they wrap at the space.
     overflow-wrap is deliberately NOT set: with the word fitting, allowing mid-word breaks
     only reintroduces the orphan the first time a name grows. */
  font-size: 10px; letter-spacing: 0;
}
.gg-scope .rl__ddflags{ display: flex; gap: 0; }
.gg-scope .rl__ddflagcell{
  width: 80px; display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 0; background: none; padding: 5px 0; cursor: pointer;
}
/* NO HOVER RESTYLE OF .rl__ddbox HERE. A first draft set its border-color on hover and
   the suite caught it: that is the house checkbox, traced from the portal, and painting
   it locally forks the component in place. Its own states are its own business. */
/* The emoji, sized as Nicole asked: "really small flags, kind of like emojis". It IS
   an emoji, so this only sets the size and stops it being selectable text. */
/* The flag is a 16x11 image, because a flag EMOJI does not render on Windows: it is a
   regional indicator pair and Chrome falls back to drawing the two letters, which is what
   Nicole saw. .rl__ddflag remains for the emoji fallback path only. */
.gg-scope .rl__ddflagimg{ flex: 0 0 auto; display: block; border-radius: 1px; }
.gg-scope .rl__ddflag{ font-size: 13px; line-height: 1; user-select: none; }
.gg-scope .rl__ddrolename{
  font-size: 14px; line-height: 20px; color: #334155;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* A role not offered from an office renders an empty cell of the same width, so the
   columns stay aligned without a disabled control inviting a click that cannot work. */
.gg-scope .rl__ddflagcell:empty{ cursor: default; }

/* ══ THE REFERRAL LINK EMPTY STATE ════════════════════════════════════════════
   2026-08-25. Nicole: once the row went to two panes this one was mostly dead
   space, so it gets a graphic with the grey line beneath it.

   THE GLYPH IS THE RAIL'S OWN Referrals ICON, enlarged and quietened, rather than
   a new illustration. The tab beside this panel already draws that share-node
   graph, so the empty state speaks the language the surface already speaks. An
   empty state is the wrong place to introduce a drawing style used nowhere else,
   which is what the reference sketch would have done.

   RESTRAINT IS THE WHOLE BRIEF. No gradient, no drop shadow, no colour beyond the
   brand blue at low alpha. It has to read as part of an enterprise surface at a
   glance and then get out of the way, because it is standing in for information
   the reader does not have yet rather than presenting any. */
.gg-scope .rl__empty{
  flex: 1 1 auto;
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  text-align: center; gap: 0.15rem; padding: 0.5rem 0 0.25rem;
}
.gg-scope .rl__emptyart{ width: 96px; height: 96px; color: rgba(0,42,191,0.42); margin-bottom: 0.5rem; }
/* The ground is a flat tint rather than a ring, so the glyph sits ON something
   without a second outline competing with its own strokes. */
.gg-scope .rl__emptyart-ground{ fill: rgba(0,42,191,0.055); }
.gg-scope .rl__emptyart-glyph circle{ fill: #ffffff; }
/* THE READER IS THE FILLED NODE and the two they have not referred yet are the
   outlined ones. It is the only meaning the picture carries. */
.gg-scope .rl__emptyart-me{ fill: rgba(0,42,191,0.42) !important; }
.gg-scope .rl__empty .rl__note{ margin: 0; }
.gg-scope .rl__empty .rl__fine{ margin: 0.25rem 0 0; max-width: 30ch; }

/* Two columns above 1023px, one below, so the sentence names the direction that is
   actually true at the width it is being read at. Both are in the markup and the
   cascade picks.
   AND display:none IS THE RIGHT TOOL HERE, which I described backwards in the first
   version of this comment. It removes the unused variant from the accessibility tree
   as well as from the page, so a screen reader reads exactly the one sentence that is
   true at that width. visibility:hidden or an off-screen clip would leave both in the
   tree and read the direction twice. */
.gg-scope .rl__dir--under{ display: none; }
@media (max-width: 1023px){
  .gg-scope .rl__dir--side{ display: none; }
  .gg-scope .rl__dir--under{ display: inline; }
}

/* ══ THE LOCKED SUBMIT PANEL ══════════════════════════════════════════════════
   2026-08-25. The two panels are a sequence: registration on the left, referring
   on the right, and the right is inert until a link exists.

   SAME TREATMENT AS THE FREE PROPOSALS CARD, which became the house pattern this
   morning: padlock, greyed copy, and controls that are genuinely absent rather
   than merely dim. It is honest here in a way it is not everywhere, because the
   wall is REAL — you cannot tie a referral to a link that does not exist — rather
   than commercial. Nothing about this lock implies a price.

   THE PANE ITSELF DOES NOT DIM. Only the copy does. Fading the whole pane would
   push it behind the ground and read as broken rather than as waiting, and the two
   panes have to stay a matched pair for the row to look deliberate. */
.gg-scope .rl__locked-pane .rl__note,
.gg-scope .rl__locked-pane .rl__fine{ color: #9aa3b2; }
.gg-scope .rl__locked-pane .rl__eyebrow{ color: #8b95a7; }
.gg-scope .rl__lockbadge{ display: inline-flex; align-items: center; color: #9aa3b2; }

/* The sign-in control is the calculator's own primary button, so it carries no
   underline. Stated because the version this replaced was an underlined anchor and
   the underline is the thing Nicole asked to lose. */
.gg-scope .rl__signin{ text-decoration: none; align-self: flex-start; }

/* ══ WHO ARE YOU REFERRING, on the Referrals view ═════════════════════════════
   2026-08-25. Relocated from the Grow step, where the original render stays as the
   fallback for the cases the rail does not cover.

   STACKED, NOT THREE ACROSS. On the Grow step these are a wide row. Here they sit
   in one half of a two-pane row, so three columns would give each about 100px and
   the descriptions carry real numbers that must stay readable. Vertical also puts
   them in the order they are chosen rather than compared.

   THE SELECTED STATE IS THE HOUSE BLUE, not the amber the Grow-step version gives
   its Most common card. That amber exists to mark a recommendation among three
   equals on a page selling a plan. Here the reader is stating a fact about who they
   know, so there is nothing to recommend and a highlight would be a nudge without a
   reason behind it. */
.gg-scope .rl__who{ display: flex; flex-direction: column; gap: 8px; margin: 0.75rem 0 0.25rem; }
.gg-scope .rl__whocard{
  appearance: none; cursor: pointer; text-align: left;
  display: grid; grid-template-columns: 1fr auto; gap: 2px 10px;
  background: rgba(255,255,255,0.62);
  border: 1px solid rgba(15,23,42,0.1);
  border-radius: 12px; padding: 0.6rem 0.75rem;
  transition: background-color .14s ease, border-color .14s ease;
}
.gg-scope .rl__whocard:hover{ border-color: rgba(0,42,191,0.32); }
.gg-scope .rl__whocard.is-on{ background: rgba(0,42,191,0.07); border-color: rgba(0,42,191,0.48); }
.gg-scope .rl__whocard:focus-visible{ outline: 2px solid rgba(0,42,191,0.55); outline-offset: 2px; }
.gg-scope .rl__wholabel{ font-size: 0.82rem; font-weight: 700; color: #0f172a; }
.gg-scope .rl__whonum{ display: inline-flex; align-items: baseline; gap: 5px; justify-self: end; }
.gg-scope .rl__whobig{ font-size: 0.95rem; font-weight: 800; color: #0f8847; }
.gg-scope .rl__whounit{ font-size: 0.7rem; font-weight: 600; color: #64748b; }
/* The description carries the bonus, so it is the one line here that must not be
   treated as fine print however long it runs. */
.gg-scope .rl__whodesc{ grid-column: 1 / -1; font-size: 0.72rem; line-height: 1.45; color: #64748b; }

/* The graphic moved to the locked panel on 25 August, so it is drawn in the locked
   greys there rather than the brand blue. A blue illustration above a padlock reads
   as an invitation, which is the opposite of what the panel is saying. */
.gg-scope .rl__emptyart--locked{ color: rgba(100,116,139,0.45); }
.gg-scope .rl__emptyart--locked .rl__emptyart-ground{ fill: rgba(100,116,139,0.07); }
.gg-scope .rl__emptyart--locked .rl__emptyart-me{ fill: rgba(100,116,139,0.45) !important; }

/* Step one is not an empty state, so its heading block just sits above the form
   rather than centring itself in space it does not have. */
.gg-scope .rl__intro{ margin: 0.35rem 0 0.9rem; }
.gg-scope .rl__intro .rl__note{ margin: 0; }
.gg-scope .rl__intro .rl__fine{ margin: 0.25rem 0 0; }

/* ══ THE LOCKED SUBMIT PANEL, REBUILT TO NICOLE'S MOCKUP 1e ═══════════════════
   2026-08-25. A centred icon said "empty". A skeleton of the real form under a
   cover says "this exists and is not yours yet", which is the pattern the whole
   signed-out surface already uses on every other locked tab.

   NOTHING IS BLURRED, deliberately, and her mockup is right about it. Blur is for a
   rendered surface with real content behind it. There is no content here yet, so
   blurring flat grey blocks would be theatre rather than information.

   THE COVER IS THE CONCRETE CARD THE RAIL ALREADY USES, PROMPT_CARD_STYLE, not the
   dark panel in the sketch. The sketch was dark because it is a sketch. Using our
   own locked-surface treatment means this reads as the same product rather than as
   a new visual language introduced on one panel. */
.gg-scope .rl__lockwrap2{ position: relative; flex: 1 1 auto; display: flex; align-items: center; padding: 0.5rem 0; }

/* The skeleton is the shape of the form that appears once the link exists: two short
   labels, two fields side by side, a label, a wide field, a button. It is not a
   guess at some generic form, it is that form with the text taken out. */
.gg-scope .rl__skel{ width: 100%; display: flex; flex-direction: column; gap: 10px; }
.gg-scope .rl__skelrow{ display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
.gg-scope .rl__skelbar{ height: 9px; border-radius: 5px; background: rgba(15,23,42,0.07); display: block; }
.gg-scope .rl__skelbar--sm{ width: 42%; }
.gg-scope .rl__skelfield{ height: 34px; border-radius: 9px; background: rgba(15,23,42,0.045); display: block; }
.gg-scope .rl__skelfield--wide{ width: 100%; }
.gg-scope .rl__skelbtn{ height: 32px; width: 132px; border-radius: 9px; background: rgba(15,23,42,0.07); display: block; margin-top: 2px; }

/* The cover sits across the middle rather than centred in the pane, so the skeleton
   reads above and below it and the panel still looks like a form with something in
   front of it rather than a card on a grey field. */
.gg-scope .rl__cover{
  position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.8rem 0.95rem;
  box-shadow: 0 1px 2px rgba(15,23,42,0.08), 0 14px 34px -14px rgba(15,23,42,0.3);
}
.gg-scope .rl__coverlock{
  flex: 0 0 auto; width: 30px; height: 30px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(15,23,42,0.06); color: #5f6673;
}
.gg-scope .rl__covertitle{ margin: 0; font-size: 0.84rem; font-weight: 700; color: #1a2233; }
.gg-scope .rl__covertext{ margin: 0.1rem 0 0; font-size: 0.75rem; line-height: 1.4; color: #6b7280; }

/* Step one lost its heading, so its one remaining sentence leads the panel. */
.gg-scope .rl__lead{ margin: 0.35rem 0 0.9rem; }

/* ══ THE PANELS ARE NUMBERED ══════════════════════════════════════════════════
   2026-08-25, Nicole. The two panels are a sequence and the lock alone could not
   say so: a padlock states that you cannot, a number states what to do first.
   rl__stepn is the chip the "What happens on the call" list already uses, reused
   rather than redrawn, at a smaller size because it sits inline in an eyebrow
   rather than leading a paragraph. */
.gg-scope .rl__eyebrow--step{ display: flex; align-items: center; gap: 8px; }
.gg-scope .rl__stepn--sm{ width: 22px; height: 22px; border-radius: 6px; font-size: 10.5px; }
/* On the locked panel the chip follows the copy into the muted greys, so the pair
   reads as one waiting state rather than a live number over a dead panel. */
.gg-scope .rl__locked-pane .rl__stepn--sm{ background: rgba(100,116,139,0.1); color: #6b7280; }

/* THE GAP UNDER THE EYEBROW WAS DOUBLED AND NEITHER HALF WAS OBVIOUS ALONE.
   rl__shead carries margin-bottom 12px and rl__lead added another 0.35rem on top,
   so the sentence sat about 18px below a label it belongs to. The lead now closes
   up against it and keeps its space underneath, where the form starts. */
.gg-scope .rl__lead{ margin: 0 0 0.9rem; }

/* The cover is a gg-pane-2 now, so it brings its own concrete and its own metal
   frame. These are only the things that pane does not know: how to sit across the
   panel, and how to lay a lock beside two lines of copy. */
.gg-scope .rl__cover{
  position: absolute; left: 0; right: 0; top: 50%; transform: translateY(-50%);
  display: flex; align-items: center; gap: 0.7rem;
  padding: 0.85rem 1rem;
}

/* ══ THE FORECAST PANEL ═══════════════════════════════════════════════════════
   2026-08-25. What is left of the old Your referrals panel once the table, the
   filter row, the count and the three zero pipeline cells were removed: the
   commission cell, which is the one cell there that was never a count of rows we
   do not have.

   IT IS NOT FULL WIDTH. The cell reads as a figure rather than as a banner, and a
   single money card stretched across the panel would look like a summary of data
   that is not there, which is the impression the removal exists to end. */
.gg-scope .rl__panel--forecast{ padding: 20px 24px 24px; }
.gg-scope .rl__forecastnote{ margin: 0 0 14px; }
.gg-scope .rl__forecastrow{ display: grid; grid-template-columns: minmax(0, 320px); }
@media (max-width: 1023px){
  .gg-scope .rl__forecastrow{ grid-template-columns: 1fr; }
}

/* ══ THE FORECAST ═════════════════════════════════════════════════════════════
   2026-08-25. Input on the left, figure on the right, and the bonus named beside
   the figure rather than summed into it.

   THE BONUS IS DELIBERATELY QUIET AND DELIBERATELY PRESENT. The £50 on sign-up
   and the investor £100 have no payout mechanism, portal gaps 2 and 1, open since
   22 July. Nicole's standing rule is that the calculator states the commercial
   intent and the portal builds to it, and the record says do not quietly remove
   them again. So they are neither hidden nor promoted: named, in the smaller type,
   outside the headline a reader would treat as their balance. */
.gg-scope .rl__fcgrid{
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 320px);
  gap: 24px; align-items: start;
}
@media (max-width: 1023px){ .gg-scope .rl__fcgrid{ grid-template-columns: 1fr; } }
.gg-scope .rl__fcinput{ display: flex; flex-direction: column; gap: 0.4rem; }

/* THE PICKER COLUMN. Who, then what, then which plan, in the order the money
   depends on them: who decides the bonus, what and which tier decide the monthly
   total the 10% runs on. */
.gg-scope .rl__flabel--sp{ margin-top: 1rem; }
.gg-scope .rl__fcinput .rl__who{ margin: 0.45rem 0 0; }
/* The cards lose their description here. On the Grow step they are the whole
   explanation; in a forecast column the description is three lines of prose between
   a reader and the next control, and the same words are already on the Plus, on top
   line beside the figure. */
.gg-scope .rl__fcinput .rl__whocard{ grid-template-columns: 1fr auto; }

/* THE TIER PANELS ARE THE CALCULATOR'S OWN .tiers / .tier NOW, so the local card
   styles that used to live here are gone rather than left dormant. Dead rules for a
   shape that was replaced are how the replaced shape comes back. Only the grid
   override below is ours, because this column is narrower than the calculator's. */


/* ── THE FAMILY STEP BAR ─────────────────────────────────────────────────────
   Real .sdg-stepper markup, so it inherits the calculator's stepper look. Two
   local corrections only:
   ONE, the steps are buttons here rather than divs, because these are a choice
   rather than a readout, so the button reset has to be undone.
   TWO, .sdg-stepper__num is never rendered, so the step needs its own left
   padding where the circle used to sit. */
.gg-scope .rl__fams{ margin: 0 0 12px; }
.gg-scope .rl__fam{
  appearance: none; background: none; border: 0; cursor: pointer; font: inherit;
  padding: 4px 2px; color: #64748b;
}
.gg-scope .rl__fam .sdg-stepper__lbl{ font-weight: 700; }
.gg-scope .rl__fam:hover{ color: #0f172a; }
.gg-scope .rl__fam.is-current{ color: var(--gg-blue, #002abf); }
.gg-scope .rl__fam:focus-visible{ outline: 2px solid rgba(0,42,191,0.55); outline-offset: 2px; border-radius: 6px; }

/* The commitment bar sits in a narrower column than the calculator's, so it wraps
   rather than overflowing. Everything else is the ported look. */

/* A GREYED OPTION IS STILL SELECTABLE, and that is deliberate. Nicole's call was to
   show waitlisted and per-person services rather than hide them, so a referrer who
   knows the business wants 3D animation sees it and learns why it does not price,
   instead of wondering whether we do it at all. The selection is a real signal about
   the referral even when it cannot carry a number. */
.gg-scope .rl__ddopt.is-muted{ color: #94a3b8; }
.gg-scope .rl__ddwhy{
  margin-left: auto; padding-left: 10px; flex: 0 0 auto;
  font-size: 0.68rem; font-weight: 600; color: #a3aab8; text-transform: lowercase;
}

/* The readout: the money cell, then the lines that explain it. */
.gg-scope .rl__fclines{ margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.gg-scope .rl__fcline{ display: flex; justify-content: space-between; gap: 12px; font-size: 0.78rem; color: #64748b; }
.gg-scope .rl__fclineval{ font-weight: 700; color: #0f172a; text-align: right; }
.gg-scope .rl__fcline--bonus .rl__fclineval{ font-weight: 500; color: #64748b; font-size: 0.72rem; max-width: 30ch; }
/* THE FLOOR LINE ONLY APPEARS WHEN IT IS TRUE. A permanent caveat is wallpaper; one
   that arrives the moment a reader picks a service that cannot price is information. */
.gg-scope .rl__fcfloor{ margin: 4px 0 0; font-size: 0.72rem; line-height: 1.45; color: #8b95a7; }

.gg-scope .rl__fcbonus{ margin: 0.65rem 0 0; display: flex; flex-direction: column; gap: 2px; }
.gg-scope .rl__fcbonuslbl{ font-size: 0.68rem; font-weight: 800; letter-spacing: 0.07em; text-transform: uppercase; color: #8b95a7; }
.gg-scope .rl__fcbonustxt{ font-size: 0.75rem; line-height: 1.45; color: #64748b; max-width: 46ch; }
/* Tabular figures so a counting number does not jitter its own width. */
.gg-scope .rl__fccell .rl__fig{ font-variant-numeric: tabular-nums; }

/* ══ THE TWO-COLUMN FORECAST ══════════════════════════════════════════════════
   2026-08-25, Nicole's layout A. Controls on the left, readout on the right,
   which is the only arrangement in which "still like the sidebar calculator" is
   true: a sidebar is a summary, not an input.

   THE WHO PANEL IS THE REAL COMPONENT. window.GGReferWhoCards is
   ClientTypeSection's own block, extracted today and published, so it arrives with
   refer-who-select and refer-who-card already styled by app.v2.css. Nothing here
   restyles it; these rules only place it. */
.gg-scope .rl__fcgrid{
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 340px);
  gap: 24px; align-items: start;
}
@media (max-width: 1023px){ .gg-scope .rl__fcgrid{ grid-template-columns: 1fr; } }
.gg-scope .rl__fccol{ display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.gg-scope .rl__pickpanel{ padding: 18px 20px 20px; }

/* The sidebar column: the referral card above the forecast card, as in the
   calculator's own summary rail. */
.gg-scope .rl__side{ display: flex; flex-direction: column; gap: 14px; }

/* 26 Aug 2026: .rl__side is rendered with .summary-wrap alongside it, so the
   sticky behaviour, the max-height and the internal scrolling all come from
   app.v2.css and are not restated here. Two rules in that inheritance have to
   be undone, both of them hides:

     app.css:2127        @media (max-width: 880px) .summary-wrap{ display: none }
     app.v2.css:14758    @media (max-width: 720px) .summary-wrap{ display: none !important }

   The calculator hides its sidebar on phones because the totals are repeated in
   a mobile bar underneath. The referrals view has no mobile bar, so hiding the
   forecast there would lose it entirely. Specificity 0,3,0 beats the 0,2,0 of
   both rules, so this wins whatever order the files load in. */
@media (max-width: 880px){
  .gg-scope .rl__side.summary-wrap{ display: flex !important; }
}


.gg-scope .rl__sidebig{ display: flex; flex-direction: column; gap: 2px; margin: 10px 0 12px; }
.gg-scope .rl__sidebiglbl{ font-size: 0.78rem; font-weight: 700; color: #0E8A50; }
/* Tabular figures so the counting number does not jitter its own width. */
.gg-scope .rl__sidebigval{ font-size: 30px; font-weight: 800; color: #0E8A50; line-height: 1.05; font-variant-numeric: tabular-nums; }
.gg-scope .rl__sidebigunit{ font-size: 0.62rem; font-weight: 800; letter-spacing: 0.08em; text-transform: uppercase; color: #9A968F; }
.gg-scope .rl__sideline{
  display: flex; justify-content: space-between; gap: 12px; align-items: baseline;
  padding: 7px 0; border-top: 1px solid rgba(15,23,42,0.07);
  font-size: 0.78rem; color: #64748b;
}
.gg-scope .rl__sidelineval{ font-weight: 700; color: #0f172a; text-align: right; }
.gg-scope .rl__sideline--bonus .rl__sidelineval{ font-weight: 500; color: #64748b; font-size: 0.72rem; max-width: 22ch; }


/* ── (OPTIONAL), AND THE HOUSE TOOLTIP ──────────────────────────────────────
   The local .rl__tip bubble is GONE. It had to solve placement, stacking and
   hit-testing for itself and got all three wrong in turn. window.HoverPortalTip
   portals to z-index 2147483647 outside every stacking context, so none of the
   three can recur, and .dis-tip is the one tooltip style this product has.
   Only the grey marker and the icon's alignment are ours. */
.gg-scope .rl__opt{ margin-left: 6px; font-size: 0.76rem; font-weight: 500; color: #94a3b8; }
.gg-scope .rl__tipwrap{ display: inline-flex; align-items: center; margin-left: 5px; vertical-align: middle; }

/* ── THE TIER LABEL ROW AND THE COMMITMENT DROPDOWN ──────────────────────────
   svc__tier-label-row already lays out space-between, so the label sits left and
   the commitment sits right, which is the slot the calculator gives the
   pay-upfront toggle. */
.gg-scope .rl__tierrow{ margin-top: 1.1rem; }
.gg-scope .rl__commitslot{ display: inline-flex; align-items: center; gap: 2px; margin-left: auto; }
.gg-scope .rl__commitlbl{
  font-size: 0.68rem; font-weight: 800; letter-spacing: 0.1em;
  text-transform: uppercase; color: var(--gg-muted, #6B6B6B);
}

/* ── THE TIER GRID FILLS THE COLUMN ──────────────────────────────────────────
   Nicole: extend the tier panels so there is no dead space on the right. The
   calculator sets gridTemplateColumns inline as repeat(N, 1fr), which fills its
   own container; ours was inheriting a narrower box. width:100% with the grid
   declared here rather than inline keeps all three cards equal and edge to edge. */
/* THREE ATTEMPTS AT THIS ONE LINE, AND THE FIRST TWO WERE THE WRONG DIAGNOSIS.
   app.v2.css declares .gg-scope .tiers{ grid-template-columns: repeat(4, minmax(0,1fr))
   } with !important. Attempt one wrote .gg-scope .rl__tiers2 and lost. Attempt two read
   that as a specificity tie and raised it to .gg-scope .tiers.rl__tiers2, three classes,
   which also lost — because SPECIFICITY NEVER BEATS !important, at any weight. Both
   times the grid computed four 174px tracks for three cards and left exactly the dead
   space the rule existed to remove, and both times the suite passed.
   The calculator never hits the !important because it sets the columns INLINE, and an
   inline declaration does outrank it. We cannot: our count is fixed, not per service.
   So this matches !important with !important, which is the only thing that answers it. */
.gg-scope .tiers.rl__tiers2{
  display: grid; width: 100%;
  grid-template-columns: repeat(3, minmax(0, 1fr)) !important;
  gap: 10px; margin-top: 0.6rem;
}
/* ONE RULE PER TIER COUNT, 26 Aug 2026. The list is window.tiersFor(service) now, so it
   is no longer always three: white label sells Reseller Fulfilment, Fulfilment + Client
   Management and Enterprise, and a service with no override falls through to the global
   four. The calculator sets this inline (sections.v2.jsx:5936) and we cannot, because
   app.v2.css declares .gg-scope .tiers repeat(4) !important and a plain inline
   declaration loses to a stylesheet !important. Each of these is 0,3,0 against that
   rule's 0,2,0, so each wins on specificity with !important on both sides. */
.gg-scope .tiers.rl__tiers2.rl__tiers2--n2{ grid-template-columns: repeat(2, minmax(0, 1fr)) !important; }
.gg-scope .tiers.rl__tiers2.rl__tiers2--n4{ grid-template-columns: repeat(4, minmax(0, 1fr)) !important; }
@media (max-width: 560px){ .gg-scope .tiers.rl__tiers2{ grid-template-columns: 1fr !important; } }

/* ── THE PICKER MENU, TRACED FROM THE PORTAL'S HOME OPTIONS POPOVER ──────────
   app/account/_components/home/QuickLinksPicker.tsx, with the checkbox recipe
   from the portal's own globals.css .gg-check. Their stack is Radix plus
   Tailwind v4 and ours is neither, so the utilities are resolved to the values
   they compile to rather than approximated by eye. Radix contributes no CSS
   here at all, only the data-state attribute, which we set ourselves. */
.gg-scope .rl__ddmenu{
  background: #ffffff; color: #09090b;
  border: 1px solid #ebebee; border-radius: 6px;
  box-shadow: 0 4px 6px -1px rgba(0,0,0,.1), 0 2px 4px -2px rgba(0,0,0,.1);
  padding: 12px;
}
.gg-scope .rl__ddeyebrow{
  margin: 0; border-top: 1px solid #e2e8f0; padding: 8px 4px 4px;
  font-size: 11px; font-weight: 700; letter-spacing: .025em;
  text-transform: uppercase; color: #94a3b8;
}
.gg-scope .rl__ddeyebrow:first-child{ border-top: 0; padding-top: 0; }
.gg-scope .rl__ddopt{
  display: flex; align-items: center; gap: 8px;
  width: 100%; padding: 4px 0; border: 0; background: none;
  font-size: 14px; line-height: 20px; color: #334155; text-align: left; cursor: pointer;
}
.gg-scope .rl__ddopt.is-muted{ color: #94a3b8; }
.gg-scope .rl__ddwhy{ margin-left: auto; font-size: 12px; color: #94a3b8; }
/* .gg-check, value for value from the portal's globals.css 856 to 909. */
.gg-scope .rl__ddbox{
  width: 18px; height: 18px; box-sizing: border-box;
  border: 2px solid #e2e2e2; border-radius: 5px;
  background: #fff; color: #fff;
  display: grid; place-items: center; flex-shrink: 0;
  box-shadow: inset 1px 1px 3px rgba(0,0,0,.06),
              1px 1px 3px rgba(0,0,0,.06),
              -1px -1px 2px rgba(255,255,255,.7);
  transition: background .15s, border-color .15s, box-shadow .15s, transform .15s;
}
.gg-scope .rl__ddopt:hover .rl__ddbox{
  border-color: #6b82d6;
  box-shadow: inset 1px 1px 3px rgba(0,0,0,.06),
              2px 2px 6px rgba(0,0,0,.08),
              -1px -1px 3px rgba(255,255,255,.8);
}
.gg-scope .rl__ddbox.is-on{
  background: #002abf; border-color: transparent; transform: scale(1.05);
  box-shadow: rgba(255,255,255,.5) -2px -2px 2px -1px,
              rgba(219,227,255,.69) 1px 1.5px 2px 0 inset,
              rgba(123,145,227,.63) -2.5px -2px 2px 0 inset,
              rgba(84,84,84,.35) 2px 2px 8px 0,
              rgba(0,31,145,.8) -1px -4px 20px 0 inset;
}
.gg-scope .rl__ddbox svg{ width: 9px; height: 9px; stroke-width: 3; display: block; }
.gg-scope .rl__ddopt:focus-visible .rl__ddbox{ outline: 2px solid #002abf; outline-offset: 2px; }

/* ── THE SIDEBAR IS .summary NOW, so almost nothing here is ours ─────────────
   The metal frame, the concrete ground and the inner glass bevels all arrive
   with the classes. Only the width, the sticky behaviour and the forecast
   figure's own type are local. */
.gg-scope .rl__side1{ padding: 18px; }
/* The eyebrow row above the refer-mode totals, traced to the calculator's own inline
   values at its call site: 0.72rem, 800, 0.06em tracking, uppercase, brand blue. Those
   are inline styles there rather than a class, so there was no class to reuse. */
.gg-scope .rl__forecasthead{ display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 0 0 6px; order: -2; }
.gg-scope .rl__forecasteyebrow{ font-size: 0.72rem; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: #002ABF; }
.gg-scope .rl__sidetotal{ margin-top: 12px; }


/* ── THE STACKING LIFT IS GONE BECAUSE THE PROBLEM IS GONE ───────────────────
   There used to be a rule here raising the glass-frame child that contained the
   local tooltip, because app.v2.css makes every glass-frame child a stacking
   context at z-index 2 and a bubble at 6 was sealed inside it.
   window.HoverPortalTip portals its bubble to window.ggPortalHost(), outside every
   stacking context on the page, so there is nothing left to lift. The rule is
   deleted rather than left dormant: a selector that matches nothing is indis-
   tinguishable from one that has quietly stopped matching, which is the exact
   failure it was written to fix. The lesson it recorded is kept in the handover.
   PORTALLING BEATS OUT-STACKING. Four separate z-index fixes on this surface in
   one day were all attempts to win a contest the element was never entered in. */

/* ── BACK TO GROW ────────────────────────────────────────────────────────────
   Nicole, 25 August 2026: blue and bold, so it reads as the way back to the
   pricing calculator rather than as chrome. It is the only exit from refer mode
   now that the switch-back toggles are retired, which is why it is a real button
   with a hit area rather than a text link. */
/* ══ THE CRUMB TRAIL ═══════════════════════════════════════════════════════════
   Values read from the portal's components/nav/CrumbBar.tsx on 26 August 2026, which
   its own header calls "ONE crumb trail for the whole estate", rather than chosen here.
   Its Tailwind classes resolve to: the row is text-sm at gap-1.5 in slate-500; links get
   hover:text-slate-900 and NO underline in any state; the separator is a lucide
   ChevronRight at size-4 in slate-400; the last crumb is font-semibold in the brand
   colour and is not a link.
   THE OLD RULE UNDERLINED ON HOVER and Nicole rejected it, because text-decoration
   inherits to inline children so the chevron underlined with the label. */
.gg-scope .rl__crumbs{
  display: flex; align-items: center; gap: 6px;
  font-size: 0.875rem; color: #64748b; margin: 0 0 6px;
}
.gg-scope .rl__crumblink{
  background: none; border: 0; padding: 0; font: inherit; color: #64748b;
  cursor: pointer; text-decoration: none; transition: color .15s ease;
}
.gg-scope .rl__crumblink:hover{ color: #0f172a; text-decoration: none; }
.gg-scope .rl__crumblink:focus-visible{
  outline: 2px solid rgba(0,42,191,0.55); outline-offset: 2px; border-radius: 6px;
}
.gg-scope .rl__crumbsep{ display: inline-flex; align-items: center; color: #94a3b8; flex: 0 0 auto; }
.gg-scope .rl__crumbnow{ font-weight: 600; color: #002ABF; }
.gg-scope .rl__backchev{ font-size: 1.05rem; line-height: 1; font-weight: 700; }

/* ══ THE COVER CARRIES THE WAY THROUGH THE WALL ═══════════════════════════════
   2026-08-27, Nicole: panel 02 never unlocks pre-login, so the sign-in control moved
   out of panel 01 and onto the cover. The cover is a flex ROW, lock beside copy, and
   the control lives in the copy block under two lines, so it needs a top margin
   rather than rl__push's margin-top:auto, which resolves to zero outside a column. */
/* The control sits at the END of the cover row rather than under the copy, so it costs
   no vertical space at all: the cover is as tall as the copy, which was always the
   tallest thing in it. The copy takes the slack and the control keeps its own width.
   min-width:0 on the copy is what lets the copy wrap instead of shoving the button out. */
/* ⚠️ THE COPY HAS A FLOOR AND THE ROW WRAPS, rather than the copy shrinking to nothing.
   Measured 27 Aug 2026 at a real 390px viewport: the cover is 232px wide there and the
   control is 194px, so a copy that may shrink to zero WILL, because flexbox shrinks before
   it wraps. The reader would get one character per line beside a full-width button.
   A FLOOR PLUS flex-wrap IS WHY THERE IS NO BREAKPOINT HERE. The row stays on one line
   wherever 150px of copy and the control both fit, and drops the control underneath where
   they do not, at whatever width that happens to be. A media query would put a number in
   the stylesheet that has to be kept in step with a button width defined in another file. */
.gg-scope .rl__cover{ flex-wrap: wrap; }
/* ⚠️ THE BASIS IS 150px AND `auto` WAS THE DEFECT. Measured at four real viewports on
   27 Aug 2026: 390 wrapped correctly, 1440 stayed inline, and 768 AND 1920 BOTH WRAPPED
   with hundreds of pixels to spare, which made no sense until the order of operations did.
   A WRAPPING FLEX CONTAINER BREAKS LINES ON HYPOTHETICAL MAIN SIZES, THEN SHRINKS WITHIN
   EACH LINE. It does not shrink first and wrap only if that fails. With `flex-basis: auto`
   the copy's hypothetical size is its max-content, about 638px for the business sentence,
   so the line broke whenever the cover was narrower than that sentence PLUS the control,
   and whether that happened had nothing to do with whether the two would have fitted after
   shrinking. 1440 escaped by luck of where that sentence wrapped.
   A 150px BASIS MAKES THE LINE-BREAK TEST THE ONE WE MEANT: 150 for the copy plus 193 for
   the control plus the lock and the gaps, against the width actually available. It grows
   back to fill whatever is left, so nothing is lost at the wide end. */
.gg-scope .rl__covercopy{ flex: 1 1 150px; min-width: 150px; }
.gg-scope .rl__coverbtn{ flex: 0 0 auto; margin-top: 0; max-width: 210px; }
/* Once it has wrapped it is alone on its line, so it lines up under the copy rather than
   under the lock, which is the column the eye is already reading down. */
.gg-scope .rl__cover > .rl__coverbtn{ margin-left: auto; }
.gg-scope .rl__cover > .rl__covercopy ~ .rl__coverbtn{ margin-left: auto; }
.gg-scope .rl__coverbtn .rl__fine{ margin: 0; }

/* The cover with a control in it is a two-line copy block plus a button, so centring the
   lock against the whole block drops it beside the button instead of beside the title it
   labels. Top-aligned, with a nudge so the lock's centre meets the title's centre. */
.gg-scope .rl__push:empty{ padding-top: 0; }

/* ══ THE MODE SWITCH, AND THE FORECAST'S SCOPE CHIP ═══════════════════════════
   2026-08-28. The two referrals tabs became a mode on panel 02, so the choice sits
   beside the action it describes rather than at the top of the page. The pills are the
   segmented shape the tab strip used, at panel scale rather than page scale, so the
   control reads as a description of the next step rather than as navigation. */
/* ⚠️ align-self IS WHAT STOPS IT SPANNING THE PANEL, not inline-flex. The panel is a
   flex COLUMN, and a flex column stretches its children across the cross axis by default,
   so display:inline-flex was overruled and the pill group ran to the far right with two
   pills floating at the left of it. Nicole spotted it within a minute of it going live. */
.gg-scope .rl__modes{ display: inline-flex; align-self: flex-start; gap: 4px; padding: 3px;
  margin: 0 0 0.9rem; border-radius: 10px; background: rgba(15,23,42,0.05); }
.gg-scope .rl__mode{ appearance: none; border: 0; cursor: pointer; font: inherit;
  font-size: 0.78rem; font-weight: 600; letter-spacing: 0.01em;
  padding: 5px 12px; border-radius: 8px; color: #5b6577; background: transparent;
  transition: background 140ms ease-out, color 140ms ease-out, box-shadow 140ms ease-out; }
.gg-scope .rl__mode:hover{ color: #1a2233; }
.gg-scope .rl__mode--on{ background: #fff; color: #0f172a;
  box-shadow: 0 1px 2px rgba(15,23,42,0.10), 0 0 0 1px rgba(15,23,42,0.05); }
.gg-scope .rl__mode:focus-visible{ outline: none; box-shadow: 0 0 0 3px rgba(0,42,191,0.28); }

/* The chip states what the figures below it cover. It sits on the heading row rather
   than in the copy so it reads as a label on the panel rather than as a caveat. */
.gg-scope .rl__phead{ display: flex; align-items: center; justify-content: space-between; gap: 0.75rem; }
/* ⚠️ BLUE, NOT AMBER. Nicole, 28 Aug. Amber on this surface means an offer or a warning:
   the POPULAR badge, the waitlist pill, the accountability discount. This chip states the
   SCOPE of the figures beside it, which is neither, and in amber it read as a promotion.
   #002ABF is the house blue this file already uses for rl__forecasteyebrow, one line of
   which sits directly above this chip in the same panel. */
.gg-scope .rl__scope{ flex: 0 0 auto; font-size: 0.66rem; font-weight: 700; letter-spacing: 0.07em;
  text-transform: uppercase; color: #002ABF; background: rgba(0,42,191,0.08);
  border: 1px solid rgba(0,42,191,0.22); border-radius: 999px; padding: 4px 10px; }

/* ⚠️ THE PANEL HEADER WRAPS ON A NARROW SCREEN, and it did not before because nothing
   sat beside the eyebrow. Measured at a real 390px viewport, 28 Aug: "01 YOUR REFERRAL
   LINK" ran to FOUR lines in 114px whilst the Share control held 106px of a 232px row,
   because rl__shead is a nowrap flex row with space-between and the eyebrow was the only
   thing able to shrink.
   IT IS A WRAP RATHER THAN A BREAKPOINT. The row stays on one line wherever both fit and
   drops the control underneath where they do not, at whatever width that turns out to be,
   which is the same reasoning as the cover control and for the same reason: a number in
   here would have to be kept in step with a control width defined elsewhere. */
.gg-scope .rl__shead{ flex-wrap: wrap; row-gap: 8px; }
.gg-scope .rl__shead > .rl__eyebrow--step{ flex: 1 1 auto; min-width: 140px; }

/* The code, stated under the shared share block in the registration overlay. It is the one
   thing on that panel somebody reads aloud, so it gets the body colour rather than the muted
   grey rl__fine normally carries. */
.gg-scope .rl__ovcode{ margin: 0.7rem 0 0; color: #475A86; }
.gg-scope .rl__ovcode strong{ color: #0F1C35; font-weight: 700; letter-spacing: 0.01em; }

/* ══ THE EMPTY HALF OF PANEL 01 ═══════════════════════════════════════════════
   2026-08-28. The pair is stretched, so both panels are as tall as panel 02, and before a
   link exists panel 01 is a sentence and a button with 118px of nothing under it. This
   centres the call to action in whatever room is left rather than letting it sit at the top
   of a half-empty panel. flex: 1 1 auto is what makes it take the slack; the panel is
   already a flex column (rl__col). */
/* ⚠️ THE GAP DOES THE WORK, NOT A HEIGHT. Nicole, 28 August: "move it up a little bit so
   it's not too close to the CTA button, and maybe the button could also be moved a little bit
   downward. But don't make the panel longer."
   The block is centred in whatever slack the panel has, so widening the gap pushes the glyph
   up and the button down by the same amount and the group stays centred. The PANEL does not
   grow, because its height comes from panel 02 through the stretched pair, and this content
   still fits inside that with room to spare. Measured after: 268px and 268px, unchanged. */
.gg-scope .rl__cta{
  flex: 1 1 auto; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: 1.75rem; padding: 0.5rem 0 0.25rem;
}
/* ⚠️ THE CIRCLE IS rl__coverlock's TREATMENT, NOT A NEW ONE. It sits on the same surface,
   forty lines up, holding the padlock on the cover: a round well in rgba(15,23,42,0.06) with
   a muted glyph on it. Nicole asked for the circle back and this is the one this file already
   uses, at a larger size because it is carrying a 34px mark rather than a 15px one.
   IT IS NOT THE BLACKLIST'S "ICON IN A COLOURED CIRCLE". That entry is about decoration in
   brand colours. This is a grey well marking an empty state, the same as the padlock beside
   it, and both are states rather than ornament. */
.gg-scope .rl__ctaicon{
  display: inline-flex; align-items: center; justify-content: center;
  width: 62px; height: 62px; border-radius: 50%;
  background: rgba(15,23,42,0.06); color: #98a4b6;
}
.gg-scope .rl__ctaicon svg{ width: 30px; height: 30px; }
