/* Theme base styles */

/* Tools
Any animations, or functions used throughout the project.
Note: _macros.css needs to be imported into each stylesheet where macros are used and not included here
*/

/* Generic
This is where reset, normalize & box-sizing styles go.
*/

*, *:before, *:after {
  box-sizing: border-box;
}
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */

/* Document
   ========================================================================== */

/**
 * 1. Correct the line height in all browsers.
 * 2. Prevent adjustments of font size after orientation changes in iOS.
 */

html {
  line-height: 1.15; /* 1 */
  -webkit-text-size-adjust: 100%; /* 2 */
}

/* Sections
   ========================================================================== */

/**
 * Remove the margin in all browsers.
 */

body {
  margin: 0;
}

/**
 * Correct the font size and margin on `h1` elements within `section` and
 * `article` contexts in Chrome, Firefox, and Safari.
 */

h1 {
  font-size: 2em;
  margin: 0.67em 0;
}

/* Grouping content
   ========================================================================== */

/**
 * Add the correct box sizing in Firefox.
 */

hr {
  box-sizing: content-box;
  height: 0;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

pre {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/* Text-level semantics
   ========================================================================== */

/**
 * 1. Remove the bottom border in Chrome 57-
 * 2. Add the correct text decoration in Chrome, Edge, Opera, and Safari.
 */

abbr[title] {
  border-bottom: none; /* 1 */
  text-decoration: underline; /* 2 */
  text-decoration: underline dotted; /* 2 */
}

/**
 * Add the correct font weight in Chrome, Edge, and Safari.
 */

b,
strong {
  font-weight: bolder;
}

/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */

code,
kbd,
samp {
  font-family: monospace, monospace; /* 1 */
  font-size: 1em; /* 2 */
}

/**
 * Add the correct font size in all browsers.
 */

small {
  font-size: 80%;
}

/**
 * Prevent `sub` and `sup` elements from affecting the line height in
 * all browsers.
 */

sub,
sup {
  font-size: 75%;
  line-height: 0;
  position: relative;
  vertical-align: baseline;
}

sub {
  bottom: -0.25em;
}

sup {
  top: -0.5em;
}

/* Forms
   ========================================================================== */

/**
 * 1. Change the font styles in all browsers.
 * 2. Remove the margin in Firefox and Safari.
 */

button,
input,
optgroup,
select,
textarea {
  font-family: inherit; /* 1 */
  font-size: 100%; /* 1 */
  line-height: 1.15; /* 1 */
  margin: 0; /* 2 */
}

/**
 * Remove the inheritance of text transform in Edge and Firefox.
 * 1. Remove the inheritance of text transform in Firefox.
 */

button,
select { /* 1 */
  text-transform: none;
}

/**
 * Correct the inability to style clickable types in iOS and Safari.
 */

button,
[type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
}

/**
 * Remove the inner border and padding in Firefox.
 */

button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
  border-style: none;
  padding: 0;
}

/**
 * Restore the focus styles unset by the previous rule.
 */

button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
  outline: 1px dotted ButtonText;
}

/**
 * Correct the padding in Firefox.
 */

fieldset {
  padding: 0.35em 0.75em 0.625em;
}

/**
 * Remove the padding so developers are not caught out when they zero out `fieldset` elements in all browsers.
 */

legend {
  padding: 0;
}

/**
 * Add the correct vertical alignment in Chrome, Firefox, and Opera.
 */

progress {
  vertical-align: baseline;
}

/**
 * Correct the cursor style of increment and decrement buttons in Chrome.
 */

[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
  height: auto;
}

/**
 * 1. Correct the odd appearance in Chrome and Safari.
 * 2. Correct the outline style in Safari.
 */

[type="search"] {
  -webkit-appearance: textfield; /* 1 */
  outline-offset: -2px; /* 2 */
}

/**
 * Remove the inner padding in Chrome and Safari on macOS.
 */

[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none;
}

/**
 * 1. Correct the inability to style clickable types in iOS and Safari.
 * 2. Change font properties to `inherit` in Safari.
 */

::-webkit-file-upload-button {
  -webkit-appearance: button; /* 1 */
  font: inherit; /* 2 */
}

/* Interactive
   ========================================================================== */

/*
 * Add the correct display in Edge and Firefox.
 */

details {
  display: block;
}

/*
 * Add the correct display in all browsers.
 */

summary {
  display: list-item;
}
/* ==========================================================================
   Ripe Global design tokens - Pink Pivot. Source of truth:
   dev-handoff/2026-10-07-pink-pivot-finals-rollout-plan.md section 2.
   Every module and base class references these. No hardcoded hex, spacing,
   or radius anywhere downstream.
   ========================================================================== */

:root {
  /* ------------------------------------------------------------------------
     Base palette - Brand Guidelines v4.1 "Sora & Rose" plus values sampled
     from the approved comps (Home v5, CEO v3). Modules NEVER reference these
     directly. They reference the role and surface tokens further down, so a
     colour decision can change here without a module edit.
     ------------------------------------------------------------------------ */
  --rg-ink:        #0A0B2E;  /* dark ground, text on light and on Rose */
  --rg-ink-raised: #11123B;  /* Ink cards on Ink (stat cells, media thumbs) */
  --rg-ink-deep:   #08091F;  /* stat strip, footer legal strip */
  --rg-paper:      #F8F6F1;  /* shells, footer ground */
  --rg-paper-2:    #EEEAE1;  /* page ground behind Paper cards */
  --rg-white:      #FFFFFF;  /* page ground, card interiors on Paper */
  --rg-rose:       #FF3D7F;  /* signal: CTA fill, accent words, stat glyph */
  --rg-rose-muted: #DC6A91;  /* glows, featured fields */
  --rg-coral-sea:  #134A6E;  /* gradient partner. Never carries text on Ink */
  --rg-whitsunday: #B8F0F2;  /* highlight on Ink / Coral Sea only */
  --rg-black:      #000000;  /* gradient endpoints only */

  /* WCAG pair. Rose Deep is for SMALL text on LIGHT surfaces only (5.11 on
     Paper, 4.60 on Paper-2, 5.6 on white). Never on Ink. Text on Rose is
     always Ink (5.66): nothing downstream can produce white on Rose. */
  --rg-rose-deep:  #D10047;
  --rg-on-rose:    var(--rg-ink);

  /* Page accent. Rose by default. A Page Accent preset or a course wrapper
     overrides the pair (see components/_course-accents.css). Each preset must
     ship an accent AND a deep partner that passes 4.5:1 on light surfaces. */
  --rg-accent:      var(--rg-rose);
  --rg-accent-deep: var(--rg-rose-deep);
  --rg-accent-glow: var(--rg-rose-muted);
  --rg-on-accent:   var(--rg-ink);

  /* Role tokens (plan section 2.2). Defaults build the approved comps. */
  --rg-band-bg:            var(--rg-accent);
  --rg-band-text:          var(--rg-on-accent);
  --rg-feature-card-bg:    var(--rg-accent);
  --rg-feature-card-text:  var(--rg-on-accent);
  --rg-btn-primary-bg:     var(--rg-accent);
  --rg-btn-primary-text:   var(--rg-on-accent);
  --rg-media-bg:           var(--rg-ink-raised);
  --rg-badge-bg:           var(--rg-whitsunday);
  --rg-badge-text:         var(--rg-ink);
  --rg-chip-bg:            var(--rg-paper);
  --rg-chip-text:          var(--rg-accent-deep);
  --rg-chip-mark:          var(--rg-ink);
  --rg-gradient-panel:     linear-gradient(135deg, var(--rg-ink) 35%, var(--rg-coral-sea) 120%);
  /* Coral Sea glow on Ink Raised: the CEO timeline lead card and glow tags. */
  --rg-surface-coral-glow: radial-gradient(70% 90% at 100% 40%, color-mix(in srgb, var(--rg-coral-sea) 70%, transparent) 0%, transparent 70%), var(--rg-ink-raised);
  --rg-glow:               radial-gradient(60% 70% at 0% 0%, var(--rg-accent) 0%, color-mix(in srgb, var(--rg-accent-glow) 45%, transparent) 38%, transparent 72%);

  /* Surface block. Light (white) is the page default. Each .rg-surface--x in
     components/_surfaces.css rewrites this whole block, and text colour always
     derives from it: no module sets its own text colour against a background
     an editor can change. */
  --rg-surface:        var(--rg-white);
  --rg-surface-raised: var(--rg-paper);
  --rg-text:           var(--rg-ink);
  --rg-text-muted:     color-mix(in srgb, var(--rg-ink) 72%, var(--rg-white));
  --rg-line:           color-mix(in srgb, var(--rg-ink) 16%, transparent);
  --rg-border:         1px solid var(--rg-line);
  --rg-border-soft:    1px solid color-mix(in srgb, var(--rg-ink) 9%, transparent);
  --rg-highlight:      var(--rg-text);          /* Whitsunday on Ink only */
  --rg-eyebrow:        var(--rg-accent-deep);   /* W3: small pink text on light */
  --rg-accent-text:    var(--rg-accent-deep);   /* small accent text */
  --rg-accent-large:   var(--rg-accent);        /* large accent words, 3:1 */
  --rg-focus:          var(--rg-ink);
  --rg-dot-inactive:   color-mix(in srgb, var(--rg-ink) 55%, var(--rg-white));
  --rg-btn-secondary-bg:   var(--rg-ink);
  --rg-btn-secondary-text: var(--rg-paper);
  /* The pill on a Rose tab header or band (A2): white with an Ink label,
     19:1. Fixed, not surface-derived: the tab is always Rose. */
  --rg-btn-band-bg:        var(--rg-white);
  --rg-btn-band-text:      var(--rg-ink);

  /* Form / feedback state colors (required marks, invalid borders, messages) */
  --rg-error:         #ef6b51;
  --rg-success:       #3bbf87;
  /* Error TEXT, surface-derived like the block above (components/_surfaces.css
     rewrites it). The raw error colour is 6.3:1 on Ink but 2.9:1 on Paper, so
     light grounds take it mixed toward Ink: 5.5:1 on Paper, 6.0:1 on white. */
  --rg-error-text:    color-mix(in srgb, var(--rg-error) 65%, var(--rg-ink));

  /* Legacy names. Kept as aliases until every module is migrated to the role
     and surface tokens, then deleted. Do not use in new code. */
  --rg-navy:            var(--rg-ink);
  --rg-navy-deep:       var(--rg-ink-deep);
  --rg-teal:            var(--rg-accent);
  --rg-teal-glow:       var(--rg-accent-glow);
  --rg-text-on-light:   var(--rg-ink);
  --rg-accent-on-teal:  var(--rg-on-accent);
  --rg-accent-on-light: var(--rg-accent-deep);
  --rg-surface-light:   var(--rg-white);
  --rg-surface-stat:    color-mix(in srgb, var(--rg-ink) 55%, transparent);
  --rg-surface-panel:   color-mix(in srgb, var(--rg-ink) 51%, transparent);
  --rg-surface-chip:    color-mix(in srgb, var(--rg-ink) 85%, transparent);
  --rg-surface-play:    color-mix(in srgb, var(--rg-accent) 23%, transparent);

  /* Elevation. The navy build used accent glows here. The Pink Pivot comps
     carry no glow shadows, so these are quiet neutral lifts. */
  --rg-glow-sm:  0 2px 8px color-mix(in srgb, var(--rg-ink) 12%, transparent);
  --rg-glow-md:  0 6px 18px color-mix(in srgb, var(--rg-ink) 16%, transparent);
  --rg-glow-lg:  0 14px 40px color-mix(in srgb, var(--rg-ink) 20%, transparent);
  --rg-shadow-card: 0 10px 30px color-mix(in srgb, var(--rg-ink) 14%, transparent);

  /* Typography - Sora for headings, stats, eyebrows, nav and the wordmark.
     Schibsted Grotesk for body, UI, buttons, forms and captions. Both load
     from Google Fonts in templates/layouts/base.html. No third typeface. */
  --rg-font: "Sora", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --rg-body-font: "Schibsted Grotesk", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  --rg-track-head:    -0.035em;  /* v4.1 headline tracking */
  /* Weight for SMALL non-heading text: tags, list items, step copy, stat
     labels (D6). Bold on light grounds; the dark surface block sets it to
     regular, because small bold white text on Ink was hard to read. Headings
     keep their own weight. */
  --rg-small-weight:  700;
  --rg-track-eyebrow: 0.16em;    /* v4.1 eyebrow caps tracking */

  /* Type scale - ONE scale for every module (gallery feedback r1, A1). A module
     heading always takes a step from this list, never a module-local size.
     Fluid between a 390px mobile minimum and a 1920px+ maximum. Values in the
     comments are px at 390 / 1440 / max. Shown in the gallery Primitives. */
  --rg-display-xl: clamp(2.75rem, 6.1vw, 7.75rem);   /* 44 / 88 / 124 - portrait hero */
  --rg-display:    clamp(2.75rem, 5.4vw, 6.25rem);   /* 44 / 78 / 100 - hero, banner display */
  --rg-h1:     clamp(2.25rem, 3.2vw, 3.75rem);       /* 36 / 46 / 60  - banner headlines */
  --rg-h2:     clamp(2rem, 2.6vw, 3rem);             /* 32 / 37 / 48  - section headings, tab headers */
  --rg-h3:     clamp(1.625rem, 2vw, 2.25rem);        /* 26 / 29 / 36  - module headings under a tab, card headings */
  --rg-h4:     clamp(1.375rem, 1.8vw, 1.875rem);     /* 22 / 26 / 30  - card names */
  --rg-h5:     clamp(1.25rem, 1.4vw, 1.5rem);        /* 20 / 20 / 24  - small card titles */
  --rg-h6:     clamp(1.125rem, 1.2vw, 1.25rem);      /* 18 / 18 / 20  - list and tile titles */
  --rg-h2-alt: var(--rg-h2);                         /* legacy alias, do not use in new code */
  --rg-body:   clamp(1rem, 1.15vw, 1.375rem);        /* 16 / 17 / 22  - all body copy */
  --rg-small:  0.9375rem;                           /* 15px - meta lines and captions only */
  --rg-body-lg: clamp(1.125rem, 1.3vw, 1.5rem);     /* 18 / 19 / 24  - a lead or large card body */
  /* Row headings (Home Review 2, G1): the heading on a Rose tab or band, and a
     shell's heading row. One step down the scale from h2, and one weight
     lighter than a headline (Sora 500, loaded in base.html). Every module's
     row heading reads these two, so they move together. */
  --rg-row-heading-size:   var(--rg-h3);
  --rg-row-heading-weight: 500;
  --rg-label:  1.25rem;                              /* 20px - stat labels */
  --rg-btn:    1rem;                                 /* 16px - every CTA, chip, form field */
  --rg-nav:    0.75rem;                              /* 12px - main nav links */

  /* Line heights */
  --rg-lh-tight: 1.05;
  --rg-lh-body:  1.65;

  /* Spacing - imposed 8px scale (the design has no grid; normalization is locked) */
  --rg-space-1:  8px;
  --rg-space-2:  16px;
  --rg-space-3:  24px;
  --rg-space-4:  32px;
  --rg-space-5:  40px;
  --rg-space-6:  48px;
  --rg-space-7:  56px;   /* blog vertical rhythm (hero/section spacing) */
  --rg-space-8:  64px;
  --rg-space-9:  72px;   /* blog vertical rhythm (hero/related spacing) */
  --rg-space-10: 80px;
  --rg-space-12: 96px;
  --rg-space-16: 128px;

  /* Module gap (A3): the ONE vertical gap between adjacent modules on a page,
     and between the halves of a side-by-side section once they stack on
     phones. Applied centrally in components/_rg-base.css, not per module. An
     editor's Space above / below preset still overrides it. */
  --rg-module-gap: var(--rg-space-6);

  /* Radius */
  --rg-radius-lg: 30px;  /* all large cards, panels, image containers. Dominant. */
  --rg-radius-md: 20px;  /* stat cards only */
  --rg-radius-sm: 15px;  /* chips, icon tiles, social tiles */
  --rg-radius-card: var(--rg-radius-lg);  /* shells and cards. By eye from the comps, Figma pending (D5) */
  --rg-radius-pill: 999px;                /* every button and tag */

  /* Circular profile avatar - ONE shared size for every ring headshot
     (educator + graduate grids, community/team cards). Ring outer 210px; the
     image inside lands ~188px after the 8px navy gap + 3px white ring. */
  --rg-avatar: 210px;

  /* Layout */
  --rg-container:  1920px;   /* content width */
  --rg-gutter:     30px;
  /* Outer frame: use as max-width on a wrapper that also has padding-inline of
     --rg-gutter, so the content settles to exactly --rg-container (1920) flush
     on wide screens while keeping a gutter on mobile (30px, narrowing to 15px
     below 768px - see the override at the end of this file). One shared width
     for every content module so their edges align. */
  --rg-container-frame: calc(var(--rg-container) + 2 * var(--rg-gutter));
  /* Blog post widths (Client Round 2): a readable measure for body text and a
     wider track for the header, hero image and media in the body. */
  --rg-post-measure: 46rem;  /* 736px - body text */
  --rg-post-wide:    72rem;  /* 1152px - header, images, video, tables */
  --rg-btn-height: 50px;  /* universal button height */

  /* Page header - one uniform height for every page top (rg-hero + rg-cta-banner
     used as a hero-header), so headers no longer vary page-to-page (S7). */
  --rg-header-min:        825px;
  --rg-header-min-mobile: 480px;

  /* Breakpoints - reference only. CSS custom properties cannot be used inside
     media queries; queries hardcode these px values. Mobile-first.
     sm: 480px | md: 768px | lg: 1024px | xl: 1440px | 2xl: 1920px */
  --bp-sm:  480px;
  --bp-md:  768px;
  --bp-lg:  1024px;
  --bp-xl:  1440px;
  --bp-2xl: 1920px;
}

/* Mobile gutter. --rg-gutter is declared exactly once above and consumed by 37
   files - containers, _rg-base, _stat-bar, _faq, the template stylesheets and
   eleven module stylesheets including header, footer and card-row - so this
   single override narrows the side gutter site-wide below 768px rather than
   touching each consumer. --rg-container-frame is calc()'d from it and follows
   automatically.

   Safe against project notes item 4: no theme field maps to --rg-gutter (it is
   declared in exactly one place in the whole theme), so there is no unresolved
   field able to emit an empty value and stomp the literal. */
@media (max-width: 767.98px) {
  :root {
    --rg-gutter: 15px;
  }
}

/* Objects
Non-cosmetic design patterns including grid and layout classes)
*/



/* CSS variables */

:root {
  --column-gap: 2.13%;
  --column-width-multiplier: 8.333;
}

/* Mobile layout */

.row-fluid {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
}


  .row-fluid .span1,
  .row-fluid .span2,
  .row-fluid .span3,
  .row-fluid .span4,
  .row-fluid .span5,
  .row-fluid .span6,
  .row-fluid .span7,
  .row-fluid .span8,
  .row-fluid .span9,
  .row-fluid .span10,
  .row-fluid .span11,
  .row-fluid .span12{
  min-height: 1px;
  width: 100%;
}

/* Desktop layout */

@media (min-width: 768px) {
  .row-fluid {
    flex-wrap: nowrap;
    justify-content: space-between;
  }

  
    .row-fluid .span1 {
      width: calc(var(--column-width-multiplier) * 1% * 1 - var(--column-gap) * (11 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span2 {
      width: calc(var(--column-width-multiplier) * 1% * 2 - var(--column-gap) * (10 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span3 {
      width: calc(var(--column-width-multiplier) * 1% * 3 - var(--column-gap) * (9 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span4 {
      width: calc(var(--column-width-multiplier) * 1% * 4 - var(--column-gap) * (8 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span5 {
      width: calc(var(--column-width-multiplier) * 1% * 5 - var(--column-gap) * (7 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span6 {
      width: calc(var(--column-width-multiplier) * 1% * 6 - var(--column-gap) * (6 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span7 {
      width: calc(var(--column-width-multiplier) * 1% * 7 - var(--column-gap) * (5 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span8 {
      width: calc(var(--column-width-multiplier) * 1% * 8 - var(--column-gap) * (4 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span9 {
      width: calc(var(--column-width-multiplier) * 1% * 9 - var(--column-gap) * (3 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span10 {
      width: calc(var(--column-width-multiplier) * 1% * 10 - var(--column-gap) * (2 * var(--column-width-multiplier) / 100));
    }
  
    .row-fluid .span11 {
      width: calc(var(--column-width-multiplier) * 1% * 11 - var(--column-gap) * (1 * var(--column-width-multiplier) / 100));
    }
  
}
/* HubSpot's own layout stylesheet ships `.container-fluid { padding: 15px }`,
   which wraps EVERY dnd page and inset the whole thing 15px on each side at
   every width. Nothing in this theme wants it: every RG module supplies its own
   gutter, either `width: calc(100% - 2 * var(--rg-gutter))` or
   `max-width: var(--rg-container-frame)` + `padding-inline: var(--rg-gutter)`.
   So the 15px was a second, invisible gutter stacked outside the real one -
   30px inset on mobile where the design calls for 15, 45px on desktop where it
   calls for 30 - and it was also what stopped a full-bleed section from ever
   reaching the viewport edge.

   Inline only: vertical rhythm is not ours to change here.

   `body` prefix is load-bearing. The rule lives in HubSpot's
   bootstrap-grid.min.css as bare `.container-fluid { padding-left/right: 15px }`
   - identical specificity to ours, but their sheet loads AFTER the theme's
   (measured on the portal: ours is stylesheet 4, theirs is 15), so a bare
   selector loses the tie. 0,1,1 beats 0,1,0 whatever the order.

   NOTE this is invisible to `hs cms theme preview` - bootstrap-grid.min.css is
   not served there, so a bare selector computes to 0 locally and 15px in the
   portal. Same class of trap as project notes item 13: portal-verify only. */
body .container-fluid {
  padding-inline: 0;
}

.content-wrapper {
  margin: 0 auto;
  padding: 0 1rem;
}

@media screen and (min-width: 1380px) {
  .content-wrapper {
    padding: 0;
  }
}

.dnd-section > .row-fluid {
  margin: 0 auto;
}

.dnd-section .dnd-column {
  padding: 0 1rem;
}

@media (max-width: 767.98px) {
  .dnd-section .dnd-column {
    padding: 0;
  }
}

/* ==========================================================================
   RG Full Width Card Section (Investors build, 2026-08-13)
   --------------------------------------------------------------------------
   Styles the section template `sections/rg-full-width-card.html`, which appears
   in the page editor's "Add Section" panel as a draggable card container editors
   drop any modules into. HubSpot won't let editors add a CSS class to a section
   and the page editor's dnd_section takes no class param - but a SECTION TEMPLATE
   can carry `class="rg-section-card"` on its dnd_section, which is how this lands.

   The class supplies the default card look: the Pink Pivot section shell
   without a tab - a Paper ground with the card radius and the SAME width cap
   as the page content sections. The matching token block is in
   components/_surfaces.css, so modules dropped inside derive their text colour
   from it. Background, padding and alignment stay editable in the section's
   Style panel and override these defaults. Tokens only; render is
   portal-verify. */
.rg-section-card {
  background-color: var(--rg-surface);
  border-radius: var(--rg-radius-card);
  color: var(--rg-text);
  margin-inline: auto;
  max-width: var(--rg-container);
  /* Gutter on narrow screens so the card never touches the edges - nets to the
     same footprint as the shell (capped at --rg-container, else viewport
     minus a gutter each side). Section is full_width so 100% = the viewport. */
  width: calc(100% - 2 * var(--rg-gutter));
  overflow: hidden;
}
/* Two-column pairing (Review 3, S3) - shared object, loaded globally.

   Any two modules placed side by side in one dnd_section, 6 + 6, behave like
   the homepage two-up panels wherever they are: side by side at 1024px and
   up, with the grid's own column gap (2.13%, 30px at 1440, the same gap the
   two-up panels have); stacked below 1024px, full width, one module gap
   apart; and, where both halves are RG modules, the two panels finish at the
   same height. Matched on structure, never on a module class, so a new
   pairing needs no CSS (repo trap 14: this is not a module.css rule).

   The only way to build it from a page template (traps 1b and 12: no class
   on a page-template dnd_section, and a second module in a section is
   rejected unless both carry width and offset):

     dnd_section full_width=True, padding top/bottom/left/right 0
       dnd_module path="../modules/rg-faq-accordion", width=6, offset=0, ...
       end_dnd_module
       dnd_module path="../modules/rg-cta-banner", width=6, offset=6, ...
       end_dnd_module
     end_dnd_section

   (Written without tag braces on purpose: HubSpot parses HubL inside CSS
   files, comments included, trap 17.)

   Equal height is skipped when one half is a rich text, which has no panel
   to stretch and would only leave the other half tall and empty. It is also
   skipped beside a testimonial carousel, which has its own pairing rules in
   rg-split-feature and rg-testimonial-carousel.

   Specificity is deliberate. In the portal HubSpot's bootstrap grid loads
   AFTER the theme (trap 18) and sets float, width (.row-fluid .span6) and a
   2.13% margin-left on every column but the first; the `body` prefix and the
   doubled .span6.dnd-module keep these rules ahead of it, and ahead of the
   module-gap rules in _rg-base.css and the two-up rule in rg-split-feature.
   That grid file is absent from local preview, so the stacked layout in the
   portal is portal-verify only. */

/* Equal height: the row is flex and already stretches its columns; the
   HubSpot wrapper inside each column is block, so it is stretched too and the
   module root fills it. */
body .row-fluid:has(> .span6.dnd-module + .span6.dnd-module):not(:has(.widget-type-rich_text, .rg-tcarousel)) > .span6.dnd-module {
  display: flex;
  flex-direction: column;
}

body .row-fluid:has(> .span6.dnd-module + .span6.dnd-module):not(:has(.widget-type-rich_text, .rg-tcarousel)) > .span6.dnd-module > .hs_cos_wrapper {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
}

body .row-fluid:has(> .span6.dnd-module + .span6.dnd-module):not(:has(.widget-type-rich_text, .rg-tcarousel)) > .span6.dnd-module > .hs_cos_wrapper > [class*="rg-"] {
  flex: 1 1 auto;
}

/* Stack below the two-up breakpoint. A half-width column is too narrow for
   most panels under 1024px (346px at 768); HubSpot's own grid only stacks
   under 768. The second column carries the module gap, so a rich text half
   gets it too, and the module inside it loses its own top margin so the gap
   is not doubled. */
@media (max-width: 1023.98px) {
  body .row-fluid:has(> .span6.dnd-module + .span6.dnd-module):not(:has(.rg-tcarousel)) {
    flex-wrap: wrap;
  }

  body .row-fluid:has(> .span6.dnd-module + .span6.dnd-module):not(:has(.rg-tcarousel)) > .span6.dnd-module {
    flex: 0 0 100%;
    float: none;
    margin-left: 0;
    max-width: 100%;
    width: 100%;
  }

  body .row-fluid:has(> .span6.dnd-module + .span6.dnd-module):not(:has(.rg-tcarousel)) > .span6.dnd-module + .span6.dnd-module {
    margin-top: var(--rg-module-gap);
  }

  body .row-fluid:has(> .span6.dnd-module + .span6.dnd-module):not(:has(.rg-tcarousel)) > .span6.dnd-module + .span6.dnd-module > .hs_cos_wrapper > [class*="rg-"] {
    margin-top: 0;
  }
}

/* Elements
Base HTML elements are styled in this section (<body>, <h1>, <a>, <p>, <button> etc.)
*/

/* The overflow-wrap is meant to prevent long/large words from breaking the mobile responsiveness of a page (e.g. horizontal scrolling). It is preferred to reduce font sizes on mobile to address this, with this CSS specifically helping with extreme scenarios where a reduction in font size is not possible. */

body {
  line-height: 1.4;
  overflow-wrap: break-word;
}

/* Handles word breaking for a few specific languages which handle breaks in words differently. If your content is not translated into these languages, you can safely remove this.  */

html[lang^="ja"] body,
html[lang^="zh"] body,
html[lang^="ko"] body {
  line-break: strict;
  overflow-wrap: normal;
  word-break: break-all;
}

/* Paragraphs */

p {
  font-size: 1rem;
  margin: 0 0 1.4rem;
}

/* Anchors */

a {
  cursor: pointer;
}

/* Headings */

h1,
h2,
h3,
h4,
h5,
h6 {
  margin: 0 0 1.4rem;
}

/* Lists */

ul,
ol {
  margin: 0 0 1.4rem;
}

ul ul,
ol ul,
ul ol,
ol ol {
  margin: 0;
}

ul.no-list {
  list-style: none;
  margin: 0;
  padding-left: 0;
}

/* Code blocks */

pre {
  overflow: auto;
}

code {
  vertical-align: bottom;
}

/* Blockquotes */

blockquote {
  border-left: 2px solid;
  margin: 0 0 1.4rem;
  padding-left: 0.7rem;
}

/* Horizontal rules */

hr {
  border: none;
  border-bottom: 1px solid #CCC;
}

/* Image alt text */

img {
  font-size: 0.583rem;
  word-break: normal;
}
button,
.button,
.hs-button {
  cursor: pointer;
  display: inline-block;
  text-align: center;
  transition: all 0.15s linear;
  white-space: normal;
}

button:disabled,
.button:disabled,
.hs-button:disabled {
  background-color: #D0D0D0;
  border-color: #D0D0D0;
  color: #E6E6E6;
}

/* No button */

.no-button,
.no-button:hover,
.no-button:focus,
.no-button:active {
  background: none;
  border: none;
  border-radius: 0;
  color: initial;
  font-family: inherit;
  font-size: inherit;
  font-style: inherit;
  font-weight: inherit;
  letter-spacing: inherit;
  line-height: inherit;
  margin-bottom: 0;
  padding: 0;
  text-align: left;
  text-decoration: none;
  transition: none;
}

/* The rule at the top of this file puts `transition: all` on every button,
   which reaches controls that never asked for motion (carousel dots, toggles).
   Readers who ask for reduced motion get none of it. */
@media (prefers-reduced-motion: reduce) {
  button,
  .button,
  .hs-button {
    transition: none;
  }
}
/* Fields */

.hs-form-field {
  margin-bottom: 1.4rem;
}

/* Labels */

form label {
  display: block;
  font-size: 0.875rem;
  margin-bottom: 0.35rem;
}

/* Form Title */
.form-title {
  margin-bottom: 0;
}

/* Transparent form background - every real form in this theme sits on a dark
   section (contact, masterclass register/replay, newsletter) and must let the
   navy/teal read through. `!important` beats the non-important `form` background
   mapped from HubSpot's theme.forms.* defaults in theme-overrides.css. If a
   future light-panel form needs a fill, re-scope it then. */
.form-title,
form {
  background-color: transparent !important;
}

/* Help text */

form legend {
  font-size: 0.875rem;
}

/* Inputs */

form input[type=text],
form input[type=search],
form input[type=email],
form input[type=password],
form input[type=tel],
form input[type=number],
form input[type=file],
form select,
form textarea {
  display: inline-block;
  font-size: 0.875rem;
  padding: 0.7rem;
  width: 100%;
}

form textarea {
  resize: vertical;
}

form fieldset {
  max-width: 100% !important;
}

/* Inputs - checkbox/radio */

form .inputs-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

form .inputs-list > li {
  display: block;
  margin: 0.7rem 0;
}

form .inputs-list input,
form .inputs-list span {
  vertical-align: middle;
}

form input[type=checkbox],
form input[type=radio] {
  cursor: pointer;
  margin-right: 0.35rem;
}

/* Inputs - date picker */

.hs-dateinput {
  position: relative;
}

.hs-dateinput:before {
  content:'\01F4C5';
  position: absolute;
  right: 10%;
  top: 50%;
  transform: translateY(-50%);
}

.fn-date-picker .pika-table thead th {
  color: #FFF;
}

.fn-date-picker td.is-selected .pika-button {
  border-radius: 0;
  box-shadow: none;
}

.fn-date-picker td .pika-button:hover,
.fn-date-picker td .pika-button:focus {
  border-radius: 0 !important;
  color: #FFF;
}

/* Inputs - file picker */

form input[type=file] {
  background-color: transparent;
  border: initial;
  padding: initial;
}

/* Headings and text */

form .hs-richtext,
form .hs-richtext p {
  font-size: 0.875rem;
  margin: 0 0 1.4rem;
}

form .hs-richtext img {
  max-width: 100% !important;
}

/* GDPR */

.legal-consent-container .hs-form-booleancheckbox-display > span,
.legal-consent-container .hs-form-booleancheckbox-display > span p {
  margin-left: 1rem !important;
}

/* Validation */

.hs-form-required {
  color: var(--rg-error);
}

.hs-input.invalid.error {
  border-color: var(--rg-error);
}

.hs-error-msg {
  color: var(--rg-error);
  margin-top: 0.35rem;
}

/* Submit button */

form input[type=submit],
form .hs-button {
  cursor: pointer;
  display: inline-block;
  text-align: center;
  transition: all 0.15s linear;
  white-space: normal;
}

/* Captcha */

.grecaptcha-badge {
  margin: 0 auto;
}


  /* Search button input field and suggestions */
  .body-container-wrapper .hs-search-field__button {
    padding: 15px;
  }

  .body-container-wrapper .hs-search-field__bar--button-inline .hs-search-field__button {
    margin-left: 6px;
    margin-bottom: 0;
  }

  .body-container-wrapper .hs-search-field__button svg {
    height: 15px;
    fill: #fff;
  }

  .body-container-wrapper .hs-search-field__bar > form > .hs-search-field__input {
    padding: 10px;
  }

  .body-container-wrapper .hs-search-field__suggestions li a {
    color: #494A52;
    padding: 0.35rem 0.7rem;
    text-decoration: none;
    transition: background-color 0.3s;
  }


/* ==========================================================================
   Ripe theming for real (classic) HubSpot forms - `.hs-form`
   --------------------------------------------------------------------------
   The generic rules above + theme-overrides.css style bare `form`/`form label`
   from portal `theme.forms.*` fields (HubSpot defaults: dark labels, white
   fields) - illegible on RipE's dark surfaces. These `.hs-form`-scoped rules
   carry a class, so they out-specify theme-overrides' type-only selectors
   (`form label`, `form input`) and win without `!important`, regardless of the
   later source order. They mirror the rg-contact placeholder glass look so a
   selected HubSpot form matches the mockup, and apply to every real classic
   form in the theme (contact, masterclass register/replay, newsletter).
   System-page forms are scoped to .systems-page/.error-page (system.css) and
   are unaffected. Glass fill/border use literal rgba (no token for translucent
   fills) to match the placeholder exactly; everything else is tokens.
   ========================================================================== */

/* Labels + help text - white, legible on dark */
.hs-form label,
.hs-form legend {
  color: var(--rg-text);
}

/* Captcha left-aligned (not centered) within the form. */
.hs-form .hs-recaptcha {
  text-align: left;
}

.hs-form .grecaptcha-badge {
  margin: 0;
}

.hs-form label {
  display: block;
  font-size: 0.95rem;
  font-weight: 600;
  margin-bottom: 0.4rem;
}

/* Text-like fields - dark glass, matching the rg-contact placeholder */
.hs-form input[type=text],
.hs-form input[type=email],
.hs-form input[type=tel],
.hs-form input[type=number],
.hs-form input[type=password],
.hs-form input[type=search],
.hs-form input[type=url],
.hs-form input[type=date],
.hs-form select,
.hs-form textarea {
  -webkit-appearance: none;
  appearance: none;
  /* The fill, edge and text read three variables with the dark glass as the
     fallback, so every existing form is unchanged. The Pink Pivot form skin
     (components/_form-skin.css) sets them from the surface tokens, which is
     how the same layer serves a Paper ground without a second rule set. */
  background-color: var(--rg-field-bg, rgba(1, 12, 37, 0.55));
  border: 1px solid var(--rg-field-line, rgba(120, 190, 214, 0.32));
  border-radius: var(--rg-radius-sm);
  color: var(--rg-field-text, var(--rg-text));
  font-family: inherit;
  font-size: var(--rg-btn);
  padding: var(--rg-space-2) var(--rg-space-3);
  width: 100%;
}

.hs-form textarea {
  min-height: 132px;
  resize: vertical;
}

.hs-form input::placeholder,
.hs-form textarea::placeholder {
  color: var(--rg-field-placeholder, var(--rg-text));
  font-weight: var(--rg-field-placeholder-weight, 600);
  opacity: var(--rg-field-placeholder-opacity, 0.75);
}

.hs-form input:focus,
.hs-form select:focus,
.hs-form textarea:focus,
.hs-form input:focus-visible,
.hs-form select:focus-visible,
.hs-form textarea:focus-visible {
  border-color: var(--rg-accent);
  box-shadow: var(--rg-glow-sm);
  outline: none;
}

/* Native select - hide OS chrome, add the placeholder chevron */
.hs-form select {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='9' viewBox='0 0 14 9' fill='none'%3E%3Cpath d='M1 1l6 6 6-6' stroke='%23ffffff' stroke-opacity='0.7' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-position: right var(--rg-space-3) center;
  background-repeat: no-repeat;
  padding-right: var(--rg-space-6);
}

/* Checkbox / radio - accent-tinted, never stretched to field width */
.hs-form input[type=checkbox],
.hs-form input[type=radio] {
  accent-color: var(--rg-accent);
  width: auto;
}

/* Multi-column form rows (HubSpot form-columns-N): a full-width flex row with
   evenly distributed columns, matching the single-column rows' width. */
.hs-form .form-columns-2,
.hs-form .form-columns-3 {
  display: flex;
  flex-wrap: wrap;
  gap: var(--rg-space-2);
  width: 100%;
}

/* Each field an equal share: a per-count flex-basis that already subtracts the
   gaps, so the columns sum to exactly one full row (no wrap) and stay even until
   the 600px single-column collapse below. */
.hs-form .form-columns-2 > .hs-form-field,
.hs-form .form-columns-3 > .hs-form-field {
  float: none;
  min-width: 0;
  padding: 0;
  width: auto;
}

.hs-form .form-columns-2 > .hs-form-field {
  flex: 1 1 calc((100% - var(--rg-space-2)) / 2);
}

.hs-form .form-columns-3 > .hs-form-field {
  flex: 1 1 calc((100% - 2 * var(--rg-space-2)) / 3);
}

/* HubSpot emits a per-form scoped rule (e.g. `.hs-form-<id> fieldset.form-columns-1
   .hs-input { width: 95% }`) whose specificity beats the generic 100% width, so
   inputs stop 5% short of their field. Force them to fill the field across every
   column count; checkboxes/radios stay their natural size. */
.hs-form [class*="form-columns"] .hs-input {
  width: 100% !important;
}

.hs-form [class*="form-columns"] input[type="checkbox"],
.hs-form [class*="form-columns"] input[type="radio"] {
  width: auto !important;
}

/* Submit - ripe teal gradient, matching the placeholder button */
.hs-form input[type=submit],
.hs-form .hs-button {
  background: linear-gradient(180deg, color-mix(in srgb, var(--rg-accent) 92%, #ffffff) 0%, var(--rg-accent) 55%, color-mix(in srgb, var(--rg-accent) 78%, var(--rg-navy)) 100%);
  border: none;
  border-radius: var(--rg-radius-sm);
  color: var(--rg-text);
  font-family: var(--rg-font);
  font-size: var(--rg-btn);
  font-weight: 700;
  min-height: var(--rg-btn-height);
  padding: 0 var(--rg-space-6);
  text-transform: none;
  transition: filter 0.2s ease;
}

.hs-form input[type=submit]:hover,
.hs-form input[type=submit]:focus-visible,
.hs-form .hs-button:hover,
.hs-form .hs-button:focus-visible {
  filter: brightness(1.08);
  outline: none;
}

/* D1: the theme's form .hs-button:hover / :focus rules set their own radius
   in the portal. Keep the submit's shape in every state. */
.hs-form input[type=submit]:is(:hover, :focus, :active),
.hs-form .hs-button:is(:hover, :focus, :active) {
  border-radius: var(--rg-radius-sm);
}

/* Contact section - full-width submit to match the placeholder layout */
.rg-contact .hs-form input[type=submit],
.rg-contact .hs-form .hs-button {
  margin-top: var(--rg-space-2);
  width: 100%;
}

/* Collapse multi-column rows on narrow screens */
@media (max-width: 600px) {
  .hs-form .form-columns-2 > .hs-form-field,
  .hs-form .form-columns-3 > .hs-form-field {
    flex-basis: 100%;
  }
}

/* ==========================================================================
   Global form-styling standard (S13) - every remaining field type on dark
   --------------------------------------------------------------------------
   Extends the .hs-form layer above so ANY classic HubSpot form (waitlist,
   registration, newsletter) drops into a module dark-themed with zero
   per-form CSS. Tokens throughout; translucent glass fills use the same
   literal rgba as the text fields above so surfaces match exactly.
   NOTE: applies to CLASSIC forms only (.hs-form + legacy markup). A new-style
   / React form has different DOM (no .hs-form) and renders UNSTYLED - clone it
   to a classic form at wire time. See project notes traps.
   ========================================================================== */

/* 1. Checkbox / radio LISTS - dark-surface layout + spacing.
   Option labels sit inline at normal weight (the field label above stays 600). */
.hs-form .inputs-list {
  list-style: none;
  margin: 0;
  padding: 0;
}

.hs-form .inputs-list > li {
  align-items: flex-start;
  display: flex;
  gap: var(--rg-space-2);
  margin: var(--rg-space-2) 0;
}

.hs-form .inputs-list > li:first-child {
  margin-top: 0;
}

.hs-form .inputs-list label,
.hs-form .hs-form-booleancheckbox label {
  font-size: 0.95rem;
  font-weight: 400;
  margin: 0;
}

.hs-form .inputs-list input[type=checkbox],
.hs-form .inputs-list input[type=radio] {
  flex: 0 0 auto;
  margin-top: 0.2rem;   /* align box to the first line of the option label */
}

/* 2. Date picker (pika calendar) on dark - overrides the generic #FFF-on-light
   layer for forms. The picker attaches inside the classic date field wrapper.
   [portal-verify: pika DOM/attachment can't be exercised locally.] */
.hs-form .hs-dateinput {
  position: relative;
}

.hs-form .fn-date-picker .pika-single {
  background-color: var(--rg-navy-deep);
  border: 1px solid rgba(120, 190, 214, 0.32);
  border-radius: var(--rg-radius-sm);
  color: var(--rg-text);
}

.hs-form .fn-date-picker .pika-label {
  background-color: var(--rg-navy-deep);
  color: var(--rg-text);
  font-weight: 600;
}

.hs-form .fn-date-picker .pika-table th,
.hs-form .fn-date-picker .pika-table th abbr {
  color: var(--rg-text);
  text-decoration: none;
}

.hs-form .fn-date-picker .pika-button {
  background-color: rgba(1, 12, 37, 0.55);
  color: var(--rg-text);
}

.hs-form .fn-date-picker td .pika-button:hover,
.hs-form .fn-date-picker td .pika-button:focus {
  background-color: var(--rg-accent) !important;
  color: var(--rg-text-on-light);
}

.hs-form .fn-date-picker td.is-selected .pika-button {
  background-color: var(--rg-accent);
  box-shadow: none;
  color: var(--rg-text-on-light);
}

.hs-form .fn-date-picker td.is-today .pika-button {
  color: var(--rg-accent);
}

/* 3. File input on dark - transparent field, glass "choose file" button */
.hs-form input[type=file] {
  background-color: transparent;
  border: none;
  color: var(--rg-text);
  font-size: 0.95rem;
  padding: 0;
  width: 100%;
}

.hs-form input[type=file]::file-selector-button {
  background-color: var(--rg-field-bg, rgba(1, 12, 37, 0.55));
  border: 1px solid var(--rg-field-line, rgba(120, 190, 214, 0.32));
  border-radius: var(--rg-radius-sm);
  color: var(--rg-field-text, var(--rg-text));
  cursor: pointer;
  font-family: var(--rg-body-font);
  margin-right: var(--rg-space-2);
  padding: var(--rg-space-1) var(--rg-space-3);
  transition: border-color 0.15s ease;
}

.hs-form input[type=file]::file-selector-button:hover {
  border-color: var(--rg-accent);
}

/* 4. Rich text inside a form - legible on dark, accent links */
.hs-form .hs-richtext,
.hs-form .hs-richtext p,
.hs-form .hs-richtext li {
  color: var(--rg-text);
}

.hs-form .hs-richtext a {
  color: var(--rg-accent);
  text-decoration: underline;
}

.hs-form .hs-richtext a:hover,
.hs-form .hs-richtext a:focus-visible {
  color: color-mix(in srgb, var(--rg-accent) 70%, #ffffff);
}

/* 5. GDPR / consent - readable fine print + accent links on dark */
.hs-form .legal-consent-container,
.hs-form .legal-consent-container p,
.hs-form .legal-consent-container .hs-form-booleancheckbox-display > span,
.hs-form .legal-consent-container .hs-form-booleancheckbox-display > span p {
  color: var(--rg-text);
  font-size: 0.85rem;
  line-height: var(--rg-lh-body);
}

.hs-form .legal-consent-container a {
  color: var(--rg-accent);
  text-decoration: underline;
}

.hs-form .legal-consent-container a:hover,
.hs-form .legal-consent-container a:focus-visible {
  color: color-mix(in srgb, var(--rg-accent) 70%, #ffffff);
}

/* 6. Validation on dark - tokenized, scoped, with the required asterisk */
.hs-form .hs-form-required {
  color: var(--rg-error);
  margin-left: 0.15rem;
}

.hs-form .hs-error-msg,
.hs-form .hs-error-msgs label {
  color: var(--rg-error);
  font-size: 0.85rem;
  margin-top: 0.35rem;
}

.hs-form .hs-input.invalid.error,
.hs-form .hs-input.error {
  border-color: var(--rg-error);
}

.hs-form .hs-input.invalid.error:focus,
.hs-form .hs-input.error:focus {
  box-shadow: 0 0 15px color-mix(in srgb, var(--rg-error) 45%, transparent);
}

/* Inline validation success (opt-in; HubSpot adds .valid on some builds) */
.hs-form .hs-input.valid {
  border-color: color-mix(in srgb, var(--rg-success) 60%, transparent);
}
/* Table */

table {
  border-collapse: collapse;
  margin-bottom: 1.4rem;
  overflow-wrap: break-word;
}

/* Table cells */

td,
th {
  vertical-align: top;
}

/* Table header */

thead th {
  vertical-align: bottom;
}

/* Components
Specific pieces of UI that are stylized. Typically used for global partial styling
*/

/* Header DND sections */

.header .dnd-section {
  padding: 0;
}

/* Header container */

.header__container {
  display: flex;
  justify-content: space-between;
}

.header__row-1 {
  padding-top: 1rem;
}

.header__row-1,
.header__row-2 {
  align-items: center;
  display: flex;
  justify-content: flex-end;
  width: 100%;
}

@media (max-width: 1150.98px) and (min-width: 767px) {
  .header__column {
    width: 100%;
  }
}

@media (max-width: 767.98px) {
  .header__container {
    flex-direction: column;
    padding: 1rem 0 0;
  }

  .header__column {
    position: relative;
  }

  .header__row-1 {
    padding-top: 0;
  }

  .header__row-2 {
    justify-content: center;
    padding: 1.05rem;
  }
}

/* Navigation skipper */

.header__skip {
  height: 1px;
  left: -1000px;
  overflow: hidden;
  position: absolute;
  text-align: left;
  top: -1000px;
  width: 1px;
}

.header__skip:hover,
.header__skip:focus,
.header__skip:active {
  height: auto;
  left: 0;
  overflow: visible;
  top: 0;
  width: auto;
}

/* Logo */

.header__logo {
  align-items: center;
  display: flex;
  height: auto;
  margin-right: auto;
  max-width: 200px;
  overflow: hidden;
}

@media (max-width: 767.98px) {
  .header__logo {
    margin: 0 auto;
    width: 100%;
  }
}

.header__logo img {
  max-width: 100%;
}

.header__logo .logo-company-name {
  font-size: 1.167rem;
  margin-top: 0.7rem;
}

.header__logo--main {
  padding-top: 1rem;
}

/* Search bar */

.header__search {
  padding: 0 1rem;
  width: auto;
}



  .hs-search-field__form {
    position: relative;
  }

  .header__search .hs-search-field__label {
    flex-basis: auto;
  }



.header__search .hs-search-field__input {
  
  height: 45px;
  padding: 0 0.7rem;
}



  .header__search .hs-search-field__button {
    padding: 0;
    fill: #000;
    background-color: transparent;
    border: none;
    padding: 10px;
    position: absolute;
    top: 0;
    right: 0;
  }

  .header__search .hs-search-field__button svg {
    height: 25px;
  }


.header__search .hs-search-field--open .hs-search-field__input {
  border-bottom: none;
  border-radius: 6px 6px 0 0;
  max-width: 100%;
}

.header__search .hs-search-field--open .hs-search-field__suggestions {
  background-color: #FFF;
  border: 2px solid #D1D6DC;
  border-radius: 0 0 6px 6px;
  border-top-width: 1px;
  position: absolute;
  width: 100%;
  z-index: 10;
}

.header__search .hs-search-field__suggestions li {
  border-top: 1px solid #D1D6DC;
  font-size: 0.875rem;
}

.header__search .hs-search-field__suggestions li a {
  color: #494A52;
  padding: 0.35rem 0.7rem;
  text-decoration: none;
  transition: background-color 0.3s;
}

.header__search .hs-search-field__suggestions #results-for {
  display: none;
}

@media (min-width: 767px) {
  .header__search form {
    align-items: center;
    display: flex;
    flex-direction: row;
  }

  .header__search label {
    margin: 0 1rem 0 0;
  }

  .header__search .hs-search-field__input {
    width: auto;
  }
}

@media (max-width: 767.98px) {
  .header__search {
    border-top: 2px solid #CED4DB;
    order: 1;
    padding: 1.05rem;
  }
}

/* Language switcher */

.header__language-switcher {
  cursor: pointer;
  padding-right: 1.4rem;
}

.header__language-switcher .lang_switcher_class {
  position: static;
}

.header__language-switcher .lang_list_class {
  border: 2px solid;
  border-radius: 3px;
  box-shadow: 0 2px 9px 0 rgba(0, 0, 0, 0.2);
  display: block;
  left: calc(100% - 24px);
  opacity: 0;
  min-width: 100px;
  padding-top: 0;
  text-align: left;
  top: 100%;
  transition: opacity 0.3s;
  visibility: hidden;
}

.header__language-switcher:hover .lang_list_class,
.header__language-switcher:focus .lang_list_class {
  opacity: 1;
  transition: opacity 0.3s;
  visibility: visible;
}

.header__language-switcher .lang_list_class:before {
  left: 70%;
  top: -25px;
}

.header__language-switcher .lang_list_class:after {
  left: 70%;
  top: -22px;
}

.header__language-switcher .lang_list_class.first-active::after {
  top: -22px;
  transition: 0.3s;
}

.header__language-switcher .lang_list_class li {
  border: none;
  font-size: 18px;
  padding: 0.35rem 0.7rem;
}

.header__language-switcher .lang_list_class li:first-child {
  border-radius: 6px 6px 0 0;
  border-top: none;
}

.header__language-switcher .lang_list_class li:last-child {
  border-bottom: none;
  border-radius: 0 0 6px 6px;
}

.header__language-switcher .lang_list_class li:hover {
  transition: background-color 0.3s;
}

.header__language-switcher--label {
  display: flex;
  position: relative;
}

.header__language-switcher--label-current {
  align-items: center;
  display: flex;
  font-size: 0.75rem;
  margin-bottom: 0.175rem;
  margin-left: 0.7rem;
}

.header__language-switcher--label-current:after {
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  border-top: 6px solid #494A52;
  content: "";
  display: block;
  height: 0px;
  margin-left: 0.7rem;
  margin-top: 0.175rem;
  width: 0px;
}

@media (max-width: 767.98px) {
  .header__language-switcher {
    border-top: 2px solid #CED4DB;
    padding-left: 1.05rem;
    padding-right: 0;
  }

  .header__language-switcher .lang_list_class {
    border: none;
    box-shadow: unset;
    display: block;
    left: 30px;
    opacity: 1;
    padding: 0 1.05rem;
    top: 0;
    visibility: visible;
  }

  .header__language-switcher .lang_list_class li {
    background-color: inherit;
    font-size: 0.917rem;
  }

  .header__language-switcher--label-current {
    display: none;
  }

  .header__language-switcher .globe_class {
    background-image: none;
  }

  .header__language-switcher .lang_list_class li:hover{
    background-color: inherit;
  }

  .header__language-switcher .lang_list_class:before,
  .header__language-switcher .lang_list_class:after {
    content: none;
  }
    /* V1 lang switcher updates to keep "in line" w/ v0 mobile styles */
    .header__language-switcher .hs-language-switcher__menu {
        display: block;
        box-shadow:none!important;
        background: transparent;
    }
    .header__language-switcher .hs-language-switcher__menu a {
        font-size: 20px!important;
    }
    .header__language-switcher .hs-language-switcher__button {
        display: none;
    }
  }

/* Navigation */

#nav-toggle {
  display: none;
}

/* Mobile toggles */

@media (max-width: 767.98px) {
  .header__navigation,
  .header__search,
  .header__language-switcher {
    display: none;
    width: 100%;
  }

  .header__navigation.open,
  .header__search.open,
  .header__language-switcher.open {
    background-color: #F8FAFC;
    display: block;
    left: 0;
    min-height: calc(100vh - 115px);
    position: absolute;
    right: 0;
    top: 75px;
    z-index: 2;
  }

  .header__navigation--toggle,
  .header__search--toggle,
  .header__language-switcher--toggle,
  .header__close--toggle {
    cursor: pointer;
    margin: 0 5vw;
    position: relative;
  }

  .header__navigation--toggle.hide,
  .header__search--toggle.hide,
  .header__language-switcher--toggle.hide {
    display: none;
  }

  .header__navigation--toggle.open,
  .header__search--toggle.open,
  .header__language-switcher--toggle.open {
    display: block;
    margin-left: 0;
    margin-right: auto;
  }

  .header__navigation--toggle:after,
  .header__search--toggle:after,
  .header__language-switcher--toggle:after {
    display: none;
    font-size: 1.083rem;
    font-weight: 600;
    position: absolute;
    left: 40px;
    text-transform: uppercase;
    top: -10px;
  }

  .header__navigation--toggle.open:after,
  .header__search--toggle.open:after,
  .header__language-switcher--toggle.open:after {
    display: block;
    word-break: normal;
  }

  .header__navigation--toggle {
    background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAxOSIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5oYW1idXJnZXI8L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGcgaWQ9ImhhbWJ1cmdlciIgc3Ryb2tlPSJub25lIiBzdHJva2Utd2lkdGg9IjEiIGZpbGw9Im5vbmUiIGZpbGwtcnVsZT0iZXZlbm9kZCI+ICAgICAgICA8ZyBpZD0iR3JvdXAiIHN0cm9rZT0iIzQ5NEE1MiIgc3Ryb2tlLXdpZHRoPSIzIj4gICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlIiB4PSIxLjUiIHk9IjEuNSIgd2lkdGg9IjIxIiBoZWlnaHQ9IjEiIHJ4PSIwLjUiPjwvcmVjdD4gICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLUNvcHktNCIgeD0iMS41IiB5PSI5LjUiIHdpZHRoPSIyMSIgaGVpZ2h0PSIxIiByeD0iMC41Ij48L3JlY3Q+ICAgICAgICAgICAgPHJlY3QgaWQ9IlJlY3RhbmdsZS1Db3B5LTUiIHg9IjEuNSIgeT0iMTcuNSIgd2lkdGg9IjIxIiBoZWlnaHQ9IjEiIHJ4PSIwLjUiPjwvcmVjdD4gICAgICAgIDwvZz4gICAgPC9nPjwvc3ZnPg==);
    background-size: cover;
    height: 25px;
    width: 25px;
  }

  .header__navigation--toggle:after {
    content: "Menu";
  }

  .header__language-switcher--toggle {
    background-image: url(//static.hsappstatic.net/cos-LanguageSwitcher/static-1.1/img/globe.png);
    background-size: cover;
    height: 25px;
    width: 25px;
  }

  .header__language-switcher--toggle:after {
    content: "Language";
  }

  .header__search--toggle {
    background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjI0cHgiIHZpZXdCb3g9IjAgMCAyNCAyNCIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5TZWFyY2g8L3RpdGxlPiAgICA8ZGVzYz5DcmVhdGVkIHdpdGggU2tldGNoLjwvZGVzYz4gICAgPGRlZnM+ICAgICAgICA8cGF0aCBkPSJNOS4xMzg2MTUzNCwxNS44OTI1Njg1IEM1LjQxMzk1NzQyLDE1Ljg5MjU2ODUgMi4zODM4ODUyNywxMi44NjM0NDc1IDIuMzgzODg1MjcsOS4xMzkwMDM3NiBDMi4zODM4ODUyNyw1LjQxNDU2MDA1IDUuNDEzOTU3NDIsMi4zODM4ODUyNyA5LjEzODYxNTM0LDIuMzgzODg1MjcgQzEyLjg2MzI3MzMsMi4zODM4ODUyNyAxNS44OTI1Njg1LDUuNDE0NTYwMDUgMTUuODkyNTY4NSw5LjEzOTAwMzc2IEMxNS44OTI1Njg1LDEyLjg2MzQ0NzUgMTIuODYzMjczMywxNS44OTI1Njg1IDkuMTM4NjE1MzQsMTUuODkyNTY4NSBNOS4xMzg3NTI0NSwyLjQzMzYwODg3ZS0xMyBDMTQuMTc3OTk1NSwyLjQzMzYwODg3ZS0xMyAxOC4yNzY0NTM3LDQuMTAwMzI0NzEgMTguMjc2NDUzNyw5LjEzOTI3Nzk2IEMxOC4yNzY0NTM3LDExLjIyOTgyMTEgMTcuNTcxMDE2OSwxMy4xNTg0NDM0IDE2LjM4NTYzMTMsMTQuNjk5NjY5NiBMMjMuNjUwODg4MSwyMS45NjUyMjY2IEMyNC4xMTYzNzA2LDIyLjQzMDcwOTIgMjQuMTE2MzcwNiwyMy4xODU0MDU1IDIzLjY1MDg4ODEsMjMuNjUwODg4MSBDMjMuMTg1NDA1NSwyNC4xMTYzNzA2IDIyLjQzMDcwOTIsMjQuMTE2MzcwNiAyMS45NjUyMjY2LDIzLjY1MDg4ODEgTDE0LjY5OTgxMzMsMTYuMzg1NDcxMyBDMTMuMTU4NDQwNSwxNy41NzA5NTA5IDExLjIyOTU3MzgsMTguMjc2NDUzNyA5LjEzODc1MjQ1LDE4LjI3NjQ1MzcgQzQuMDk5NTA5MzgsMTguMjc2NDUzNyAtMy43MzAzNDkzNmUtMTQsMTQuMTc4MjMxMiAtMy43MzAzNDkzNmUtMTQsOS4xMzkyNzc5NiBDLTMuNzMwMzQ5MzZlLTE0LDQuMTAwMzI0NzEgNC4wOTk1MDkzOCwyLjQzMzYwODg3ZS0xMyA5LjEzODc1MjQ1LDIuNDMzNjA4ODdlLTEzIFoiIGlkPSJwYXRoLTEiPjwvcGF0aD4gICAgPC9kZWZzPiAgICA8ZyBpZD0iU2VhcmNoIiBzdHJva2U9Im5vbmUiIHN0cm9rZS13aWR0aD0iMSIgZmlsbD0ibm9uZSIgZmlsbC1ydWxlPSJldmVub2RkIj4gICAgICAgIDxtYXNrIGlkPSJtYXNrLTIiIGZpbGw9IndoaXRlIj4gICAgICAgICAgICA8dXNlIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPiAgICAgICAgPC9tYXNrPiAgICAgICAgPHVzZSBpZD0iSWNvbnMvQWN0aW9ucy9TZWFyY2giIGZpbGw9IiM0OTRBNTIiIHhsaW5rOmhyZWY9IiNwYXRoLTEiPjwvdXNlPiAgICA8L2c+PC9zdmc+);
    background-size: cover;
    height: 25px;
    width: 25px;
  }

  .header__search--toggle:after {
    content: "Search";
  }

  .header__close--toggle {
    background-image: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz48c3ZnIHdpZHRoPSIyNHB4IiBoZWlnaHQ9IjE5cHgiIHZpZXdCb3g9IjAgMCAyNCAxOSIgdmVyc2lvbj0iMS4xIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIj4gICAgICAgIDx0aXRsZT5jbG9zZTwvdGl0bGU+ICAgIDxkZXNjPkNyZWF0ZWQgd2l0aCBTa2V0Y2guPC9kZXNjPiAgICA8ZyBpZD0iY2xvc2UiIHN0cm9rZT0ibm9uZSIgc3Ryb2tlLXdpZHRoPSIxIiBmaWxsPSJub25lIiBmaWxsLXJ1bGU9ImV2ZW5vZGQiPiAgICAgICAgPGcgaWQ9Ikdyb3VwIiB0cmFuc2Zvcm09InRyYW5zbGF0ZSgyLjAwMDAwMCwgLTEuMDAwMDAwKSIgc3Ryb2tlPSIjNDk0QTUyIiBzdHJva2Utd2lkdGg9IjMiPiAgICAgICAgICAgIDxyZWN0IGlkPSJSZWN0YW5nbGUiIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEwLjAwMDAwMCwgMTAuNTAwMDAwKSByb3RhdGUoLTQ1LjAwMDAwMCkgdHJhbnNsYXRlKC0xMC4wMDAwMDAsIC0xMC41MDAwMDApICIgeD0iLTAuNSIgeT0iMTAuNSIgd2lkdGg9IjIxIiBoZWlnaHQ9IjEiIHJ4PSIwLjUiPjwvcmVjdD4gICAgICAgICAgICA8cmVjdCBpZD0iUmVjdGFuZ2xlLUNvcHktNSIgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMTAuMDAwMDAwLCAxMC41MDAwMDApIHJvdGF0ZSg0NS4wMDAwMDApIHRyYW5zbGF0ZSgtMTAuMDAwMDAwLCAtMTAuNTAwMDAwKSAiIHg9Ii0wLjUiIHk9IjEwLjUiIHdpZHRoPSIyMSIgaGVpZ2h0PSIxIiByeD0iMC41Ij48L3JlY3Q+ICAgICAgICA8L2c+ICAgIDwvZz48L3N2Zz4=);
    background-repeat: no-repeat;
    background-size: 110%;
    display: none;
    height: 25px;
    margin-right: 0;
    width: 25px;
  }

  .header__close--toggle.show {
    display: block;
  }
}
/* Menu and simple menu */

.hs-menu-wrapper ul {
  display: flex;
  flex-wrap: wrap;
  list-style: none;
  margin: 0;
  padding-left: 0;
}

/* Horizontal menu */

.hs-menu-wrapper.hs-menu-flow-horizontal .hs-menu-children-wrapper {
  flex-direction: column;
}

@media (max-width: 767.98px) {
  .hs-menu-wrapper.hs-menu-flow-horizontal ul {
    flex-direction: column;
  }
}

/* Vertical menu */

.hs-menu-wrapper.hs-menu-flow-vertical ul {
  flex-direction: column;
}

/* Flyouts */

.hs-menu-wrapper.hs-menu-flow-vertical.flyouts ul {
  display: inline-flex;
}

@media (max-width: 767.98px) {
  .hs-menu-wrapper.hs-menu-flow-vertical ul {
    display: flex;
  }
}

.hs-menu-wrapper.flyouts .hs-item-has-children {
  position: relative;
}

.hs-menu-wrapper.flyouts .hs-menu-children-wrapper {
  left: -9999px;
  opacity: 0;
  position: absolute;
}

.hs-menu-wrapper.flyouts .hs-menu-children-wrapper a {
  display: block;
  white-space: nowrap;
}

.hs-menu-wrapper.hs-menu-flow-horizontal.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper {
  left: 0;
  opacity: 1;
  top: 100%;
}

.hs-menu-wrapper.hs-menu-flow-vertical.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper {
  left: 100%;
  opacity: 1;
  top: 0;
}

@media (max-width: 767.98px) {
  .hs-menu-wrapper.flyouts .hs-menu-children-wrapper,
  .hs-menu-wrapper.hs-menu-flow-horizontal.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper,
  .hs-menu-wrapper.hs-menu-flow-vertical.flyouts .hs-item-has-children:hover > .hs-menu-children-wrapper {
    left: 0;
    opacity: 1;
    position: relative;
    top: auto;
  }
}

/* CTA, logo, and rich text images */

.hs_cos_wrapper_type_cta img,
.hs_cos_wrapper_type_logo img,
.hs_cos_wrapper_type_rich_text img {
  height: auto;
  max-width: 100%;
}
/* ==========================================================================
   Ripe Global base classes - source of truth: dev-handoff/2026-07-14-theme-spec.md §4
   Every RG module composes from these. Build once, reuse everywhere.
   Tokens live in generic/_tokens.css.
   ========================================================================== */

/* --------------------------------------------------------------------------
   Anchor scrolling

   Eases the jump when a #fragment link lands on a module's Anchor ID instead
   of snapping instantly.

   `scroll-behavior` is NOT inherited - it applies to whichever element is the
   scroll container - so setting it on `html` affects the document scroller
   only. The carousel tracks keep their own scrolling and snap behaviour
   untouched, which is why this does not need scoping away from them.

   Guarded on prefers-reduced-motion: a long smooth scroll is a common
   vestibular trigger, and the whole point of that setting is to opt out of
   exactly this. Readers who ask for reduced motion get the instant jump back.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference) {
  html {
    scroll-behavior: smooth;
  }
}

/* Belt and braces: something outside this file (a HubSpot or portal sheet)
   can set smooth scrolling on html unguarded, so reduced motion resets it
   explicitly rather than relying on the guard above alone. */
@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto !important;
  }
}

/* --------------------------------------------------------------------------
   Page defaults. The page ground is light (white); the token block that goes
   with it lives in _surfaces.css.
   -------------------------------------------------------------------------- */

.rg-page {
  background-color: var(--rg-surface);
  color: var(--rg-text);
  font-family: var(--rg-body-font);
  font-size: var(--rg-body);
  line-height: var(--rg-lh-body);
  /* One end-of-page gap before the footer on every page (Review 4, S6), so a
     closing card never sits on the footer. */
  padding-bottom: var(--rg-space-8);
}

@media (max-width: 767.98px) {
  .rg-page {
    padding-bottom: var(--rg-space-6);
  }
}

/* A closing form panel gets the same gap below it as above it (the module
   gap), so the panel sits centred between the section above and the footer
   (Client Round 1). Keyed on the last dnd row, as the portal renders it. */
.rg-page:has(.row-fluid-wrapper.row-depth-1:last-child .rg-form) {
  padding-bottom: var(--rg-module-gap);
}

/* A page that is only a hero (Career Pathway book a call): the hero meets the
   footer, no end gap (Round A). */
.rg-page.rg-page--hero-only {
  padding-bottom: 0;
}

.rg-container {
  margin-left: auto;
  margin-right: auto;
  max-width: var(--rg-container-frame);
  padding-left: var(--rg-gutter);
  padding-right: var(--rg-gutter);
}

/* --------------------------------------------------------------------------
   .rg-card - the signature shell
   The 1px teal border + 30px radius sits on essentially every card, panel
   and image container in the design.
   -------------------------------------------------------------------------- */

.rg-card {
  border: var(--rg-border);
  border-radius: var(--rg-radius-lg);
  overflow: hidden;
}

/* Split radii for adjoining panels - modifiers, not new tokens */
.rg-card--split-right {
  border-radius: 0 var(--rg-radius-lg) var(--rg-radius-lg) 0;
}

.rg-card--split-left {
  border-radius: var(--rg-radius-lg) 0 0 var(--rg-radius-lg);
}

.rg-card--split-right-sm {
  border-radius: 0 var(--rg-radius-sm) var(--rg-radius-sm) 0;
}

.rg-card--split-left-sm {
  border-radius: var(--rg-radius-sm) 0 0 var(--rg-radius-sm);
}

/* .rg-btn lives in components/_buttons-rg.css. */

/* --------------------------------------------------------------------------
   Focus ring - one visible indicator for every interactive element, on every
   surface. --rg-focus is set per surface (Ink on light, white on Ink, Ink on
   Rose), so it holds 3:1 or better against whatever it sits on. :where() keeps
   specificity at zero so a component can still tune offset or shape.
   -------------------------------------------------------------------------- */

:where(a, button, input, select, textarea, summary, [tabindex]):focus-visible {
  outline: 3px solid var(--rg-focus);
  outline-offset: 3px;
}

/* --------------------------------------------------------------------------
   .rg-band - full-bleed teal section header. 84px at desktop, heading left,
   optional CTA right. Not container-constrained.
   -------------------------------------------------------------------------- */

/* Header bands (heading + carousel below) take the standard gap above and
   sit flush to their carousel below. The carousel's margin-top is 0 so it
   hugs its header. Full-bleed, so vertical margin only. */
.rg-band {
  /* A band is its own small surface: text on Rose is always Ink (W2). Ground
     and text come from the shared tab tokens in _shell.css. */
  --rg-text: var(--rg-tab-text);
  --rg-focus: var(--rg-tab-text);
  background: var(--rg-tab-bg);
  color: var(--rg-tab-text);
  margin-top: var(--rg-space-6);
  width: 100%;
}

/* Heading-only (centered) bands keep the standard top gap like every other
   band - a mid-page section header (e.g. "Meet Your Educators") must not butt
   flush against the section above it (A-S4.2). Only a band deliberately chained
   under the hero opts into flush via .rg-band--flush-top. */
.rg-band--flush-top {
  margin-top: 0;
}

/* Inline accent for headlines and copy. Small accent text takes
   --rg-accent-text (Rose Deep on light surfaces, W3). Inside a large heading it
   takes --rg-accent-large, which stays brand Rose because large text only needs
   3:1 (W6). Both are surface tokens, so there is no per-module light/dark list
   to keep in step any more. */
.rg-accent {
  color: var(--rg-accent-text);
}

:is(h1, h2, h3, .h1, .h2, .h3) .rg-accent {
  color: var(--rg-accent-large);
}

/* On a Rose band the accent cannot be Rose. It takes the tab text colour. */
.rg-band .rg-accent,
.rg-shell__tab .rg-accent {
  color: var(--rg-tab-text);
}

.rg-band__inner {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--rg-space-2) var(--rg-space-4);
  justify-content: space-between;
  margin-inline: auto;
  max-width: var(--rg-container-frame);
  min-height: 84px;
  padding: var(--rg-space-2) var(--rg-gutter);
}

/* A real heading in Ink, as on the shell tab (W2, A2 option B), at the shared
   row heading size and weight. */
.rg-band__heading {
  color: var(--rg-tab-text);
  font-family: var(--rg-font);
  font-size: var(--rg-row-heading-size);
  font-weight: var(--rg-row-heading-weight);
  letter-spacing: var(--rg-track-head);
  line-height: 1.15;
  margin: 0;
  text-transform: none;
}

.rg-band__text {
  display: flex;
  flex-direction: column;
  gap: var(--rg-space-1);
  min-width: 0;
}

/* Raw rich text: colour and size declared with tokens (repo trap 13). */
.rg-band__body,
.rg-band__body p {
  color: var(--rg-tab-text);
  font-family: var(--rg-body-font);
  font-size: var(--rg-body);
  line-height: 1.5;
  margin: 0;
}

/* Paragraph spacing: a band or card with more than one paragraph spaces them
   (Round B, Group Fast-Track closing card). */
.rg-band__body p + p,
.rg-band__body p + ul,
.rg-band__body ul + p {
  margin-top: var(--rg-space-2);
}

.rg-band__body a {
  color: var(--rg-tab-text);
  text-decoration: underline;
}

/* Optional eyebrow above the heading (Review 4, S7). */
.rg-band__eyebrow {
  color: var(--rg-tab-text);
  font-family: var(--rg-body-font);
  font-size: var(--rg-small);
  font-weight: 600;
  letter-spacing: 0.08em;
  line-height: 1.3;
  margin: 0;
  text-transform: uppercase;
}

/* Offer card (Review 4, S7): the band as a rounded card inside the content
   width, the hero corner glow scaled to a taller panel. Used for dated offers
   (the EOY fellowship offer, the Master Series and Membership offers). */
.rg-band.rg-band--card {
  --rg-tab-bg: radial-gradient(55% 150% at 0% 0%, color-mix(in srgb, var(--rg-accent) 75%, var(--rg-ink)) 0%, color-mix(in srgb, var(--rg-accent-glow) 45%, transparent) 38%, transparent 72%), var(--rg-ink);
  border-radius: var(--rg-radius-card);
  margin: var(--rg-space-6) auto;
  max-width: var(--rg-container);
  overflow: hidden;
  width: calc(100% - (2 * var(--rg-gutter)));
}

.rg-band--card .rg-band__inner {
  gap: var(--rg-space-3) var(--rg-space-5);
  min-height: 0;
  padding: var(--rg-space-6) var(--rg-space-6);
}

.rg-band--card .rg-band__text {
  gap: var(--rg-space-2);
  max-width: 62ch;
}

.rg-band--card .rg-band__heading {
  font-size: var(--rg-h2);
}

/* Background (Client Round 2). Accent: the page or course accent with a deep
   corner shade, text in the accent's own text colour, so an offer stands apart
   from a dark hero or stat strip. Paper: a light card with the accent glow
   in the corner, Ink text and the accent pill. Both only reset the band's
   ground and text tokens, so every band and card rule above still applies. */
.rg-band.rg-band--bg-accent {
  --rg-tab-bg: radial-gradient(60% 160% at 100% 100%, color-mix(in srgb, var(--rg-accent-deep) 70%, transparent) 0%, transparent 70%), var(--rg-accent);
  --rg-tab-text: var(--rg-on-accent);
}

.rg-band.rg-band--bg-paper {
  --rg-tab-bg: radial-gradient(55% 150% at 0% 0%, color-mix(in srgb, var(--rg-accent-glow) 35%, transparent) 0%, transparent 70%), var(--rg-paper);
  --rg-tab-text: var(--rg-ink);
  border: var(--rg-border-soft);
}

.rg-band.rg-band--bg-paper .rg-band__eyebrow {
  color: var(--rg-accent-deep);
}

/* Button position (Review 1 addendum). Desktop only: below 768px every band
   stacks. Left sits the pill a fixed gap after the heading (or the heading and
   copy block), right pushes it to the far edge, below puts it under the
   heading. The default .rg-band__inner rule above is the right-edge layout. */
.rg-band--btn-left .rg-band__inner {
  justify-content: flex-start;
}

.rg-band--btn-below .rg-band__inner {
  align-items: flex-start;
  flex-direction: column;
  padding-block: var(--rg-space-3);
}

/* Centred bands (the FRD strapline band) centre the heading and put any
   button under it, whatever the button position says. */
.rg-band--centered .rg-band__inner {
  flex-direction: column;
  justify-content: center;
  padding-block: var(--rg-space-3);
  text-align: center;
}

/* Below 768px every band stacks: heading on top, button under it, both
   left-aligned, with room inside the band. Centred bands stay centred. */
@media (max-width: 767.98px) {
  .rg-band__inner {
    align-items: flex-start;
    flex-direction: column;
    padding-block: var(--rg-space-3);
    text-align: left;
  }

  .rg-band--centered .rg-band__inner {
    align-items: center;
    text-align: center;
  }

  .rg-band--card .rg-band__inner {
    padding: var(--rg-space-5) var(--rg-space-4);
  }
}

/* --------------------------------------------------------------------------
   Gradient + scrim utilities - the three recurring recipes.
   Define once; never re-author per module.
   -------------------------------------------------------------------------- */

/* Radial image scrim: teal core fading through deep blues to black */
.rg-scrim-radial {
  position: relative;
}

/* Alpha curve tuned against rendered cards: the imagery must stay
   legible with a teal-tinted vignette, not drown in navy. */
.rg-scrim-radial::after {
  background: radial-gradient(
    ellipse at center,
    color-mix(in srgb, var(--rg-accent) 25%, transparent) 0%,
    color-mix(in srgb, var(--rg-accent) 20%, transparent) 30%,
    color-mix(in srgb, var(--rg-coral-sea) 25%, transparent) 55%,
    color-mix(in srgb, var(--rg-ink) 38%, transparent) 78%,
    color-mix(in srgb, var(--rg-ink) 60%, transparent) 100%
  );
  content: "";
  inset: 0;
  pointer-events: none;
  position: absolute;
}

.rg-scrim-radial > * {
  position: relative;
  z-index: 1;
}

/* ...but a scrimmed background photo is a direct child too, and must stay BELOW
   the vignette. The blanket rule above was lifting the image to z-index 1
   alongside the content, so the scrim painted UNDERNEATH its own photo and did
   nothing at all - the class was applied, the gradient was correct, and the
   hero still rendered at full photo strength (the CEO profile read as an
   undimmed stock portrait of someone else).
   Declared after the rule above so it wins the tie.

   The original sweep searched for `__bg` and therefore missed
   .rg-feature-card__image - same element role, different suffix. Every mosaic
   card carrying "Show scrim" has been rendering at full photo strength since
   (verified on the live homepage: __image z-index 1, ::after z-index auto),
   which is why copy over the busier cards read as sitting on an undimmed
   photograph. Match on ROLE, not on the class suffix, if this list ever grows
   again: any element that is a background layer inside a .rg-scrim-radial root
   belongs here. */
.rg-cta-banner__bg,
.rg-social-grid__bg,
.rg-split-feature__bg,
.rg-feature-card__image {
  z-index: 0;
}

/* Linear card gradient: navy to teal. The teal endpoint overshoots past
   the corner (130%) so the visible range stays subtle - full-saturation
   teal by the card edge reads far brighter than the Figma cards. */
.rg-gradient-card {
  background: var(--rg-gradient-panel);
}

/* Deep card gradient: black through navy (29%) to teal */
.rg-gradient-card--deep {
  background: linear-gradient(135deg, var(--rg-ink-deep) 0%, var(--rg-ink) 29%, var(--rg-coral-sea) 130%);
}

/* --------------------------------------------------------------------------
   .rg-arrows - 56x56 carousel prev/next pair, positioned at page edges
   -------------------------------------------------------------------------- */

.rg-arrows {
  display: contents;
}

/* Every card fits: the carousel scripts set [hidden] and both arrows go,
   instead of two disabled grey circles (Visual Review Nov 5). */
.rg-arrows[hidden] {
  display: none;
}

/* White circular arrows that sit OUTSIDE the card track (Figma). The track
   reserves room for them - see each carousel module's track margin. */
.rg-arrows__btn {
  align-items: center;
  background-color: var(--rg-btn-secondary-bg);
  border: 0;
  border-radius: 50%;
  box-sizing: border-box;
  color: var(--rg-btn-secondary-text);
  cursor: pointer;
  display: inline-flex;
  height: 56px;
  justify-content: center;
  padding: 0;
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  transition: box-shadow 0.2s ease;
  width: 56px;
  z-index: 2;
}

.rg-arrows__btn svg {
  display: block;
  height: 22px;
  width: 22px;
}

.rg-arrows__btn:hover,
.rg-arrows__btn:focus-visible {
  box-shadow: var(--rg-glow-sm);
}

.rg-arrows__btn:focus-visible {
  outline: 3px solid var(--rg-focus);
  outline-offset: 3px;
}

/* At either end of the track the carousel script disables that arrow, so the
   row stops at its first and last card instead of bouncing (Client Round 1). */
.rg-arrows__btn:disabled {
  box-shadow: none;
  cursor: default;
  opacity: 0.35;
}

/* 56px circles are sized to sit OUTSIDE the cards on desktop. On mobile every
   carousel track runs edge to edge, so the arrows overlay the card art instead,
   where 56px reads as oversized and covers the subject's face.

   Declared HERE, next to the base rule, not in a module stylesheet: .rg-arrows
   is shared by rg-video-carousel and rg-testimonial-carousel, and a module's
   CSS only loads when that module is on the page (project notes item 14). While
   this override lived in rg-video-carousel/module.css, the text carousel got
   40px arrows on /testimonials only because the video carousel happened to be
   on the same page - and would have kept 56px anywhere it renders alone. */
@media (max-width: 767.98px) {
  .rg-arrows__btn {
    height: 40px;
    width: 40px;
  }

  .rg-arrows__btn svg {
    height: 18px;
    width: 18px;
  }
}

.rg-arrows__btn--prev {
  left: var(--rg-gutter);
}

.rg-arrows__btn--next {
  right: var(--rg-gutter);
}

/* --------------------------------------------------------------------------
   .rg-dots - carousel pagination. Each dot is a real button with a 24px hit
   area (WCAG 2.5.8) around a 12px mark. The active dot is larger as well as
   Rose, so the state never rests on colour alone, and the inactive mark holds
   3:1 against its surface (W5).
   -------------------------------------------------------------------------- */

.rg-dots {
  align-items: center;
  display: flex;
  gap: var(--rg-space-1);
  justify-content: center;
  list-style: none;
  margin: var(--rg-space-3) 0 0;
  padding: 0;
}

/* One page needs no pagination. The script sets hidden; display: flex above
   would otherwise keep the lone dot on screen (Home Walk 1). */
.rg-dots[hidden] {
  display: none;
}

.rg-dots__dot {
  align-items: center;
  background: none;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  display: inline-flex;
  height: 24px;
  justify-content: center;
  padding: 0;
  width: 24px;
}

.rg-dots__dot::before {
  background-color: var(--rg-dot-inactive);
  border-radius: 50%;
  content: "";
  height: 12px;
  transition: transform 0.2s ease, background-color 0.2s ease;
  width: 12px;
}

.rg-dots__dot[aria-current="true"]::before {
  background-color: var(--rg-accent);
  transform: scale(1.35);
}

@media (prefers-reduced-motion: reduce) {
  .rg-dots__dot,
  .rg-dots__dot::before {
    transition: none;
  }
}

/* --------------------------------------------------------------------------
   Flush paired cards - equal height. A card with a --flush modifier fills its
   dnd column; the column (.spanN) already stretches (the row is flex), but the
   HubSpot module wrapper is block, so stretch it and let height:100% resolve.
   -------------------------------------------------------------------------- */
.row-fluid > [class*="span"]:has([class*="--flush"]),
.row-fluid > [class*="span"]:has(.rg-feature-grid--icon-inline),
.row-fluid > [class*="span"]:has(.rg-curriculum--marker-check),
.row-fluid > [class*="span"]:has(.rg-calendly) {
  display: flex;
  flex-direction: column;
}

.row-fluid > [class*="span"]:has([class*="--flush"]) > .hs_cos_wrapper,
.row-fluid > [class*="span"]:has(.rg-feature-grid--icon-inline) > .hs_cos_wrapper,
.row-fluid > [class*="span"]:has(.rg-curriculum--marker-check) > .hs_cos_wrapper,
.row-fluid > [class*="span"]:has(.rg-calendly) > .hs_cos_wrapper {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
}

/* --------------------------------------------------------------------------
   Promo row width. The promo cards are the only content laid out as a native
   dnd 2-column row (two width=6 modules) rather than a single self-capping
   module, so the row ran gutter-to-gutter while every other content module
   caps at --rg-container centered - the edges did not line up above 1920px.
   Cap the promo row to match. Scoped to rows that directly hold promo columns.
   !important is required: HubSpot forces `max-width: none !important` on the
   row of a full_width dnd_section (`.dnd_area-row-N-force-full-width-section
   > .row-fluid`); this selector is more specific (0,3,0 vs 0,2,0) but must also
   be !important to beat theirs. Single-module sections self-cap via the module,
   but a native 2-column row can only be capped here at the row level. Same for
   the flush split-feature two-up (teal + navy panels), another native 2-column
   row that otherwise runs full width past the other modules' edges. */
/* Matched on STRUCTURE, not on which module happens to be inside. The original
   pair of selectors named .rg-promo and .rg-split-feature--flush, so a
   two-column row of any other modules was left uncapped - the feature-grid +
   curriculum-list row on the free student page ran to 30px from the screen
   edges at 2560 while the split feature above it sat at 320. Any native
   multi-column row has the same problem, so key off the column class: span6 /
   span4 / span3 are multi-column, span12 is a single module that self-caps. */
.row-fluid:has(> .dnd-module[class*="span"]:not(.span12)) {
  margin-left: auto !important;
  margin-right: auto !important;
  max-width: var(--rg-container) !important;
}

/* The cap above only sets max-width, so below --rg-container these rows ran flush
   to the screen edges while grid content (educator/feature grids) stayed inset by
   the gutter - the promo card "goes flush on shrink" bug (2026-07-29 walk,
   Graduates closing CTA). Inset the row by the gutter so its edges line up with
   the single-module sections at every breakpoint. Generalised from promo-only
   for the same reason as the cap above. The flush split-feature two-up keeps its
   edge-to-edge treatment. */
.row-fluid:has(> .dnd-module[class*="span"]:not(.span12)):not(:has(> .dnd-module .rg-split-feature--flush)) {
  width: calc(100% - (2 * var(--rg-gutter)));
}

/* One gap between modules (A3). Every module root used to set its own top
   margin, and they drifted: 0 (tag list, stat bar, masterclass grid, before
   and after, card row), 8px, 32px (video carousel) and 48px, with the
   newsletter band adding 48px below as well. In a dnd area the gap is now set
   here, once, from --rg-module-gap. Matched on the module wrapper, so rich
   text modules are left alone. Exceptions: the hero opens a page; the stat
   bar is drawn joined to the hero (the Home v5 strip) or floats up over its
   bottom edge with a negative margin (components/_stat-bar.css), so it keeps
   its own; the anchor and page settings modules render nothing. The Space
   above / below presets (.rg-ls--mt / --mb) are !important and still win.
   Exceptions sit in :where() so the selector stays at 0,3,0: high enough to
   beat a module's own root margin, low enough that the multi-column rules
   below (which zero the margin inside a row) still win. */
.dnd-module > .hs_cos_wrapper_type_module:not(:where(.widget-type-rich_text)) > [class*="rg-"]:not(:where(.rg-hero, .rg-stat-bar, .rg-anchor, .rg-pagesettings-note)) {
  margin-bottom: 0;
  margin-top: var(--rg-module-gap);
}

/* ...and with the ROW now carrying the gutter, the modules inside it must not
   carry it too. Each RG section self-gutters (width: calc(100% - 2*gutter))
   because it is normally placed alone in a full-width section - in a column
   that inset stacks on the row's, putting the feature-grid row 30px further in
   than the split feature above it. Fill the column instead. */
.row-fluid:has(> .dnd-module[class*="span"]:not(.span12)) > .dnd-module > .hs_cos_wrapper > [class*="rg-"] {
  margin-inline: 0;
  margin-top: 0;
  max-width: none;
  width: 100%;
}

/* Side-by-side modules must start level. Each RG section carries its own top
   gap, but whether that margin stays inside its column or collapses out of it
   depends on how the column is laid out (a flex column keeps it, a block column
   may not), and HubSpot's grid CSS is not the same in the portal as in local
   preview. In the portal one half of a pair sat 48px lower than the other.
   So in a multi-column row the gap belongs to the ROW: the modules above lose
   their own top margin and the row carries one, once. A module's Space above
   setting still applies on top of this (it is declared important). */
.row-fluid:has(> .dnd-module[class*="span"]:not(.span12)) {
  margin-top: var(--rg-module-gap);
}

/* Below 768px the columns of a side-by-side row stack, and with the module
   margins zeroed above, the halves touched (the split-feature pair, the FAQ
   and circle CTA in rg-sec-faq-circle). Give every half after the first the
   same module gap. */
@media (max-width: 767.98px) {
  .row-fluid:has(> .dnd-module[class*="span"]:not(.span12)) > .dnd-module + .dnd-module > .hs_cos_wrapper > [class*="rg-"] {
    margin-top: var(--rg-module-gap);
  }
}

/* When an icon-inline feature-grid is paired with a promo hero in a 2-column
   row (Investors Platform section), it should FILL its column, not self-cap to
   the container - otherwise its content insets an extra gutter and the row's
   edges don't line up with the single-module rows above/below it. */
.row-fluid:has(> .dnd-module .rg-promo) .rg-feature-grid--icon-inline {
  margin: var(--rg-space-6) 0 0;
  max-width: none;
  width: 100%;
}

/* --------------------------------------------------------------------------
   Button state radius guard (D1). In the portal the theme's button:hover and
   button:focus rules (0,1,1, theme-overrides.css) give every <button> the
   theme's hover radius, and a rule that only sets its radius in the base state
   loses to them on hover and focus. The round controls pin theirs here (0,2,0)
   in every state. .rg-btn pins its own in _buttons-rg.css; module buttons with
   other shapes pin theirs in their module CSS.
   -------------------------------------------------------------------------- */
.rg-arrows__btn:is(:hover, :focus, :active),
.rg-dots__dot:is(:hover, :focus, :active),
.rg-partner-carousel__pause:is(:hover, :focus, :active),
.rg-lightbox__close:is(:hover, :focus, :active),
.rg-form-modal__close:is(:hover, :focus, :active),
.rg-header__account-trigger:is(:hover, :focus, :active) {
  /* The theme's hover rule also adds a 1px border (Walk 10). */
  border: 0;
  border-radius: 50%;
}
/* Card-row grid primitives - PROMOTED from rg-card-row.module/module.css.

   Why this file exists: a module's CSS only loads when THAT module is on the
   page (project notes item 14), so the grid lived somewhere the ten LMS templates
   could never reach. They render Landify's modules, not ours, and every one of
   them needs a grid. Ten per-page grid implementations is exactly the drift the
   shared layer exists to prevent, so the primitives move here and main.css
   loads them on every page. the review's call, Mike agreed, 21 Aug.

   The custom-property contract is unchanged: --rg-row-cols / --rg-row-rows /
   --rg-row-areas are emitted per instance by rg-card-row's module.html, and
   any other consumer sets them inline or in its own scope. Defaults below mean
   an element with .rg-card-row__grid and no properties set is still a valid
   two-column grid.

   Moved verbatim. Do not "tidy" these rules - rg-card-row on the 44 marketing
   pages depends on them behaving identically. */

/* --------------------------------------------------------------------------
   The grid - the ONE block that consumes the layout custom properties
   -------------------------------------------------------------------------- */
.rg-card-row__grid {
  display: grid;
  grid-template-columns: var(--rg-row-cols, 1fr 1fr);
  grid-template-rows: var(--rg-row-rows, auto);
  grid-template-areas: var(--rg-row-areas, none);
  gap: var(--rg-cr-gap, var(--rg-space-6));
  align-items: stretch;
}

/* Equal-height off: cards take their natural height.

   BOTH declarations are load-bearing. `align-items` only positions an item
   INSIDE its track, and every multi-row layout emits 1fr-based tracks
   (--rg-row-rows, e.g. '1fr 1fr' for 2-3), so the tracks equalised to the
   tallest row whatever align-items said - the toggle was inert by construction.
   Measured on the CEO page before the fix: two 714.398px tracks holding cards
   with 176-213px of content, i.e. ~500px of dead space per card.
   `grid-template-rows: auto` overrides the base rule's
   `var(--rg-row-rows, auto)` on source order (same specificity, declared after)
   so the inline custom property is simply not consumed while the toggle is off.
   No !important needed - do not add one. */
.rg-card-row__grid--auto-height {
  align-items: start;
  grid-template-rows: auto;
}

/* Gap scale */
.rg-card-row--gap-tight   { --rg-cr-gap: var(--rg-space-3); }
.rg-card-row--gap-default { --rg-cr-gap: var(--rg-space-6); }
.rg-card-row--gap-loose   { --rg-cr-gap: var(--rg-space-10); }

.rg-card-row__grid--carousel {
  display: flex;
  grid-template-areas: none;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  -webkit-overflow-scrolling: touch;
  padding-bottom: var(--rg-space-2);
}
.rg-card-row__grid--carousel > * {
  grid-area: auto;
  flex: 0 0 min(360px, 82%);
  scroll-snap-align: start;
}

/* --------------------------------------------------------------------------
   Responsive
   Desktop keeps the exact named-area layout. Tablet reflows to an auto-fit grid
   (never cramped, never overflowing), and phones go single column. Cards render
   in DOM order = reading order, so asymmetric splits stack correctly.
   -------------------------------------------------------------------------- */
@media (max-width: 1024.98px) {
  .rg-card-row__grid:not(.rg-card-row__grid--carousel) {
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr)) !important;
    grid-template-rows: auto !important;
    grid-template-areas: none !important;
  }
  .rg-card-row__grid:not(.rg-card-row__grid--carousel) > * {
    grid-area: auto !important;
  }
}

/* --------------------------------------------------------------------------
   Card height floor (Card minimum height field)
   .rg-promo carries a fixed 610px min-height for the standalone promo shell.
   That is the right default for a hero promo and the wrong one for a six-card
   row, so the row can now set its own floor per instance: --rg-cr-card-min is
   emitted by rg-card-row's module.html ('auto' emits 0). Three classes, so it
   outranks the .rg-promo--has-video / --image-top min-height: 0 reset in
   _promo-card.css regardless of which stylesheet lands first.

   Desktop only. Below 768px a card is always content + padding tall - a fixed
   floor on a single-column phone layout is dead space, never a design.
   -------------------------------------------------------------------------- */
@media (min-width: 768px) {
  .rg-card-row--card-min .rg-card-row__card.rg-promo {
    min-height: var(--rg-cr-card-min, 610px);
  }
}

/* --------------------------------------------------------------------------
   Mobile
   Two behaviours, both scoped to card-row cards so the shared .rg-promo
   vocabulary is unchanged wherever else it renders:

   1. Content-height cards (see above) and everything centred. A phone column
      has no side subject to clear and no second column to align against, so
      left-aligned copy in a full-width card just reads off-centre.
   2. Content-height cards. Everything else about the mobile card - centring on
      both axes, the standardised padding, the navy legibility wash - now lives
      in css/components/_promo-card.css keyed on .rg-promo itself, because the
      standalone rg-promo-card module renders the same vocabulary and was
      missing all of it. Do not re-add per-card-row copies here.
   -------------------------------------------------------------------------- */
@media (max-width: 767.98px) {
  /* Card-row only: the Card minimum height field is a desktop control, so a
     row's cards are always content-height on a phone. .rg-promo's own 420px
     mobile floor is right for a standalone promo and wrong for a stacked row. */
  .rg-card-row__card.rg-promo {
    min-height: 0;
  }

  .rg-card-row__head {
    justify-content: center;
    text-align: center;
  }

  .rg-card-row__card .rg-card-row__badge {
    align-self: center;
  }
}

/* Image fit "Whole image, smaller" (Review 3): icon or line art shows uncropped
   and smaller, centred on the card's gradient, instead of filling the frame.
   The inner margin runs on all four sides, so a wide logo (Restocq on
   Partners) keeps clear space at its ends too (Visual Review Nov 5). Percent
   padding follows the card's width, so the margin scales with the card. */
.rg-card-row--fit-contain .rg-pp-card__media--gradient .rg-pp-card__bg {
  box-sizing: border-box;
  object-fit: contain;
  object-position: center;
  padding: 6% 10%;
}

/* Image background: Paper or White (Client Round 2, Partners). Logos and
   other transparent art sit on a light ground instead of the Ink gradient.
   A hairline under the image keeps the image area distinct from the body. */
.rg-card-row--ground-paper .rg-pp-card__media--gradient {
  background: var(--rg-paper);
  border-bottom: var(--rg-border-soft);
}

.rg-card-row--ground-white .rg-pp-card__media--gradient {
  background: var(--rg-white);
  border-bottom: var(--rg-border-soft);
}

/* Image tone: White (Community icon row). Dark line-icon images turn white on
   the dark media panel. Photos keep Original. */
.rg-card-row--img-white .rg-pp-card__bg {
  filter: brightness(0) invert(1);
}

/* Card content alignment: Centred (blog categories, Round B). */
.rg-card-row--card-center .rg-pp-card {
  text-align: center;
}

.rg-card-row--card-center .rg-pp-card__content {
  align-items: center;
}

.rg-card-row--card-center .rg-pp-card__icon-tile {
  align-self: center;
}
/* RG Stat Bar - shared stat-card component. Global (loaded on every page via
   main.css) because the cards are used by TWO modules: the standalone
   rg-stat-bar module AND the in-hero stat row inside rg-cta-banner. Keeping
   these styles module-scoped broke the Implantology hero - HubSpot only loads a
   module's CSS when that module is on the page, so the embedded stats rendered
   completely unstyled (giant white glyph). Card 441x114, r20, surface-stat
   fill, soft border. Do NOT use --rg-border here: the soft border is
   intentional and unique. */

.rg-stat-bar {
  display: grid;
  gap: var(--rg-space-4);
  /* Frame (1920 + 2x gutter) so content settles to exactly --rg-container
     flush, matching every other content module. Using bare --rg-container
     here with the gutter padding capped content 60px narrow (border-box). */
  max-width: var(--rg-container-frame);
  padding: 0 var(--rg-gutter);
  position: relative;
  z-index: 2;
}

/* Float over the hero's bottom edge, contributing ZERO flow height so the next
   section sits flush. The pull equals the real row-block height so any stat
   count reflows without overlap: --rg-stat-pull is computed per row count in
   rg-stat-bar.module/module.html (146*rows - 12). Single row = 134, two = 280.
   Fallback 134px keeps a legacy instance (no var) at the old one-row pull. */
.rg-stat-bar--float {
  margin: calc(-1 * var(--rg-stat-pull, 134px)) auto 20px;
}

/* Legacy: the module now folds float-tall into --float with the auto pull, so
   this class is no longer emitted; kept as a safe fallback for stale instances. */
.rg-stat-bar--float-tall {
  margin: calc(-1 * var(--rg-stat-pull, 280px)) auto 20px;
}

.rg-stat-bar--cols-2 { grid-template-columns: repeat(2, 1fr); }
.rg-stat-bar--cols-3 { grid-template-columns: repeat(3, 1fr); }
.rg-stat-bar--cols-4 { grid-template-columns: repeat(4, 1fr); }

/* Inline placement (fellowship banners): the row sits below the banner in
   normal flow instead of floating up over the hero's bottom edge. */
.rg-stat-bar--inline {
  margin: var(--rg-space-6) auto 0;
}

/* Pill cards (no number) center the label beside the icon. Title-only cards
   carry just this label, so keep it smaller than the numbered cards' number
   (--rg-h4) - otherwise a title-only stat reads as large as a headline number
   and unbalances the row. */
.rg-stat--pill .rg-stat__label {
  font-size: 1.125rem;
}

.rg-stat {
  -webkit-backdrop-filter: blur(16px);
  align-items: center;
  backdrop-filter: blur(16px);
  background: var(--rg-surface-stat);
  border: var(--rg-border-soft);
  border-radius: var(--rg-radius-md);
  color: var(--rg-text);
  display: flex;
  font-family: var(--rg-font);
  gap: var(--rg-space-2);
  min-height: 114px;
  padding: var(--rg-space-2) var(--rg-space-3);
}

/* dark tile, teal border, teal glyph - per Figma */
.rg-stat__icon {
  align-items: center;
  background: var(--rg-surface-chip);
  border: var(--rg-border);
  border-radius: var(--rg-radius-sm);
  display: inline-flex;
  flex-shrink: 0;
  height: 74px;
  justify-content: center;
  width: 74px;
}

.rg-stat__icon img {
  height: 48px;
  width: auto;
}

/* Neutral on-brand placeholder glyph (icon_fallback = neutral) - teal tooth,
   same glyph the curriculum tiles use, until the real per-stat icons land. */
.rg-stat__glyph {
  color: var(--rg-accent);
  height: 42px;
  width: 42px;
}

.rg-stat__text {
  display: flex;
  flex-direction: column;
}

.rg-stat__number {
  font-size: var(--rg-h4);
  font-weight: 700;
  line-height: var(--rg-lh-tight);
}

.rg-stat__label {
  font-size: 1rem;
  font-weight: 700;
  line-height: 1.2;
}

@media (max-width: 1023.98px) {
  .rg-stat-bar--cols-3,
  .rg-stat-bar--cols-4 {
    grid-template-columns: repeat(2, 1fr);
  }

  /* Columns collapse to 2 here, so a floating row can gain rows - use the
     tablet pull the module computed for that column count. */
  .rg-stat-bar--float {
    margin-top: calc(-1 * var(--rg-stat-pull-t, 134px));
  }
}

@media (max-width: 767.98px) {
  .rg-stat-bar--cols-2,
  .rg-stat-bar--cols-3,
  .rg-stat-bar--cols-4 {
    grid-template-columns: 1fr;
  }

  /* The float pull is a DESKTOP effect: the row rides 64px up over the hero's
     bottom edge, and .rg-hero__content's matching space-8 inset is what keeps
     the headline clear of it. On a phone the hero art is only ~300px tall, so
     the same 64px pull dragged the cards up into the middle of the photo and
     the image read straight through them. Zero overlap here; space-3 keeps the
     row off the hero's bottom edge without reopening the gap the pull closes on
     desktop. Inline stays in normal flow (keeps its space-6 from the base
     rule). */
  .rg-stat-bar--float,
  .rg-stat-bar--float-tall {
    margin: var(--rg-space-3) auto 0;
    padding-bottom: var(--rg-space-2);
  }

  /* Opaque cards. --rg-surface-stat is navy at 55%, which is a deliberate
     desktop effect - the hero photo tinting through a card that floats over it.
     Once the row sits in flow below the hero there is nothing to tint through
     but there is still a photo edge behind the top card, so the alpha only
     costs contrast. Flat navy, and the blur goes with it (nothing left to blur,
     and it is a real compositing cost on a phone).

     Alignment is deliberately NOT touched: the icon-then-text lockup keeps its
     own left rag on mobile (Mike, explicitly - the rest of the page centres,
     these do not). */
  .rg-stat {
    -webkit-backdrop-filter: none;
    backdrop-filter: none;
    background: var(--rg-navy);
  }
}

/* Accent glyph on a stat numeral (the "+" in 250+). Large text, so brand Rose
   holds on every surface (W6). */
.rg-stat__suffix {
  color: var(--rg-accent-large);
}

/* ==========================================================================
   Pink Pivot stats (.rg-ppstats). Shared, because a hero or banner may render
   the same list inside itself. White Sora numeral, one accent glyph, label
   under it. Always on Ink.
   ========================================================================== */

.rg-stat-bar.rg-stat-bar--pp {
  display: block;
  margin: 0;
  max-width: none;
  padding: 0;
}

.rg-ppstats {
  display: grid;
  list-style: none;
  margin: 0;
  padding: 0;
}

.rg-ppstat {
  display: flex;
  flex-direction: column;
  gap: var(--rg-space-2);
  min-width: 0;
}

.rg-ppstat__number {
  color: var(--rg-text);
  font-family: var(--rg-font);
  font-size: clamp(2.5rem, 4.4vw, 5.25rem);
  font-weight: 700;
  letter-spacing: -0.03em;
  line-height: 1;
  /* A figure and its suffix never break across lines ("100,00" / "0+"). */
  white-space: nowrap;
}

.rg-ppstat__label {
  color: var(--rg-text);
  font-family: var(--rg-body-font);
  font-size: clamp(1rem, 1.15vw, 1.375rem);
  line-height: 1.25;
  max-width: 22ch;
}

/* Optional second line under the label (RMS data points). Empty = not rendered. */
.rg-ppstat__detail {
  color: color-mix(in srgb, var(--rg-text) 72%, transparent);
  font-family: var(--rg-body-font);
  font-size: var(--rg-small);
  line-height: 1.35;
  max-width: 28ch;
}

.rg-ppstat__icon {
  display: block;
  height: 44px;
  object-fit: contain;
  object-position: left center;
  width: 44px;
}

/* strip: full-bleed cells, hairline dividers, Ink Deep ground. */
.rg-stat-bar--pp-strip.rg-stat-bar--pp {
  background-color: var(--rg-ink-deep);
}

.rg-ppstats--strip {
  grid-template-columns: repeat(var(--rg-stat-count, 4), minmax(0, 1fr));
}

.rg-ppstats--strip .rg-ppstat {
  border-left: var(--rg-border);
  padding: var(--rg-space-8) var(--rg-space-4) var(--rg-space-8) max(var(--rg-space-4), 4.4vw);
}

.rg-ppstats--strip .rg-ppstat:first-child {
  border-left: 0;
}

/* strip, Compact (the default, Home Review 2): numbers at h1, labels small,
   a tighter cell. Large keeps the display numbers above. */
.rg-ppstats--compact .rg-ppstat__number {
  font-size: var(--rg-h1);
}

.rg-ppstats--compact .rg-ppstat__label {
  font-size: var(--rg-small);
  max-width: 26ch;
}

/* Phones: strip cells are two-up, so long figures (100,000+) scale with the
   viewport to fit their cell rather than overflow it. Cards are one per row
   here, so their figures stay large (Client Round 1: call-out numbers were
   too small on the fellowship pages). */
@media (max-width: 479px) {
  .rg-ppstats--strip .rg-ppstat__number,
  .rg-ppstats--strip.rg-ppstats--compact .rg-ppstat__number {
    font-size: clamp(2rem, 9vw, 2.75rem);
  }

  .rg-ppstats--cards .rg-ppstat__number {
    font-size: clamp(2.75rem, 12vw, 3.5rem);
  }
}

.rg-ppstats--strip.rg-ppstats--compact .rg-ppstat {
  gap: var(--rg-space-1);
  padding-block: var(--rg-space-6);
}

/* cards: raised Ink cards inside the content width. */
.rg-stat-bar--pp-cards.rg-stat-bar--pp {
  padding: var(--rg-space-5) var(--rg-gutter);
}

.rg-ppstats--cards {
  gap: var(--rg-space-4);
  grid-template-columns: repeat(3, minmax(0, 1fr));
  margin-inline: auto;
  max-width: var(--rg-container);
}

.rg-ppstats--cards .rg-ppstat {
  background-color: var(--rg-surface-raised);
  border: var(--rg-border);
  border-radius: var(--rg-radius-card);
  justify-content: center;
  min-height: 150px;
  padding: var(--rg-space-4) var(--rg-space-5);
}

.rg-ppstats--cards .rg-ppstat__label {
  color: var(--rg-text-muted);
  font-family: var(--rg-font);
  font-size: clamp(0.9375rem, 1.1vw, 1.25rem);
  font-weight: var(--rg-small-weight);
  max-width: 26ch;
  /* Shown exactly as typed (decision 3), like the strip's labels. */
  text-transform: none;
}

@media (max-width: 1024.98px) {
  .rg-ppstats--strip,
  .rg-ppstats--cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .rg-ppstats--strip .rg-ppstat,
  .rg-ppstats--strip.rg-ppstats--compact .rg-ppstat {
    border-top: var(--rg-border);
    padding: var(--rg-space-5) var(--rg-space-3);
  }

  .rg-ppstats--strip .rg-ppstat:nth-child(odd) {
    border-left: 0;
  }

  .rg-ppstats--strip .rg-ppstat:nth-child(-n+2) {
    border-top: 0;
  }

  /* An odd last card takes the full row rather than leaving a hole. */
  .rg-ppstats--cards .rg-ppstat:last-child:nth-child(odd) {
    grid-column: 1 / -1;
  }

  /* A strip with an odd number of stats (Investors, Implant Live) stacks one
     per row: two-up left an empty fourth box (Client Round 1). */
  .rg-ppstats--strip:has(> .rg-ppstat:last-child:nth-child(odd)) {
    grid-template-columns: minmax(0, 1fr);
  }

  .rg-ppstats--strip:has(> .rg-ppstat:last-child:nth-child(odd)) > .rg-ppstat {
    border-left: 0;
    border-top: var(--rg-border);
  }

  .rg-ppstats--strip:has(> .rg-ppstat:last-child:nth-child(odd)) > .rg-ppstat:first-child {
    border-top: 0;
  }
}

@media (max-width: 479px) {
  .rg-ppstats--cards {
    grid-template-columns: minmax(0, 1fr);
  }
}
/* Per-course accent themes + the accent palette tokens.

   Pink Pivot: Rose is the default accent (_tokens.css). Teal is the proven
   second preset and ships with a measured deep partner. The aligners and
   implantology deep partners are computed, not measured: confirm their
   contrast with the designer before those presets are offered (plan 3.4).

   Applied as a modifier on the .rg-page wrapper of a fellowship template
   (e.g. <div class="rg-page rg-course--aligners">). Each course overrides
   --rg-accent and its glow; the derived tokens (borders, glows, accent
   surfaces) re-resolve on the .rg-page wrapper in _page-accent.css, so the
   whole page recolours through the token cascade with no per-module edits.

   The accent hexes live here (this file *defines* them, like _tokens.css) and
   are exposed as palette tokens so the Page Accent module (rg-page-settings)
   can reference them by name rather than re-emitting hex from a module. */

:root {
  /* Course accent palette - the single source for these hexes. Referenced by
     the .rg-course--x classes below and by the Page Accent module. */
  --rg-accent-restorative:       #22a6bf;
  --rg-accent-restorative-glow:  #48d3ed;
  --rg-accent-restorative-deep:  #177182;  /* 5.23 on Paper, 4.70 on Paper-2 */
  --rg-accent-aligners:          #64a391;
  --rg-accent-aligners-glow:     #8fc4b4;
  --rg-accent-implantology:      #3262eb;
  --rg-accent-implantology-glow: #6f93f5;
  /* Oral Health Therapy: the live page's purple. It is 1.26 on Ink, so on dark
     surfaces accent words and glows take the lighter tint (6.23 on Ink, 5.84
     on Ink-raised). White text on the purple itself is 15.20. */
  --rg-accent-oht:               #221D57;
  --rg-accent-oht-tint:          #9488E0;
  /* Accent words on Paper: the purple reads as Ink there, so a mid purple
     (6.04 on Paper, 6.52 on white). Buttons on Paper keep the purple. */
  --rg-accent-oht-text:          #5A4BC2;
}

.rg-course--restorative {
  --rg-accent: var(--rg-accent-restorative);
  --rg-accent-glow: var(--rg-accent-restorative-glow);
  --rg-accent-deep: var(--rg-accent-restorative-deep);
  /* Teal is 2.89 on white: large accent words on light take the deep partner. */
  --rg-accent-large-light: var(--rg-accent-restorative-deep);
}

.rg-course--aligners {
  --rg-accent: var(--rg-accent-aligners);
  --rg-accent-glow: var(--rg-accent-aligners-glow);
  --rg-accent-deep: color-mix(in srgb, var(--rg-accent-aligners) 55%, black);
  --rg-accent-large-light: color-mix(in srgb, var(--rg-accent-aligners) 55%, black);
}

.rg-course--implantology {
  --rg-accent: var(--rg-accent-implantology);
  --rg-accent-glow: var(--rg-accent-implantology-glow);
  --rg-accent-deep: color-mix(in srgb, var(--rg-accent-implantology) 80%, black);
}

.rg-course--oht {
  --rg-accent: var(--rg-accent-oht);
  --rg-accent-glow: var(--rg-accent-oht-tint);
  --rg-accent-deep: var(--rg-accent-oht-text);
  /* Read by the Ink surface block (_surfaces.css) and the on-accent token
     (_page-accent.css). Unset on every other course, so they fall back. */
  --rg-accent-ink: var(--rg-accent-oht-tint);
  --rg-course-on-accent: var(--rg-white);
  /* Accent words on Paper, also in a paper card nested in an Ink section. */
  --rg-accent-large-light: var(--rg-accent-oht-text);
}

/* On Ink the purple is 1.26, so fills (buttons, markers, dots, glows) vanish.
   Inside an Ink surface the OHT accent becomes the tint, with Ink text on it
   (6.23). The derived tokens resolve on .rg-page (_page-accent.css), so they
   are re-declared here to pick the tint up (repo trap 21). */
.rg-course--oht :is(.rg-surface--ink, .rg-bg--dark, .rg-bg--gradient, .rg-bg--gradient-deep, .rg-bg--image, .rg-gradient-card, .rg-gradient-card--deep, .rg-scrim-radial) {
  --rg-accent:             var(--rg-accent-oht-tint);
  --rg-on-accent:          var(--rg-ink);
  --rg-band-bg:            var(--rg-accent);
  --rg-band-text:          var(--rg-on-accent);
  --rg-feature-card-bg:    var(--rg-accent);
  --rg-feature-card-text:  var(--rg-on-accent);
  --rg-btn-primary-bg:     var(--rg-accent);
  --rg-btn-primary-text:   var(--rg-on-accent);
  --rg-glow:               radial-gradient(60% 70% at 0% 0%, var(--rg-accent-oht) 0%, color-mix(in srgb, var(--rg-accent-glow) 45%, transparent) 38%, transparent 72%);
  --rg-surface-play:       color-mix(in srgb, var(--rg-accent) 23%, transparent);
  --rg-teal:               var(--rg-accent);
  --rg-accent-on-teal:     var(--rg-on-accent);
}
/* Page accent re-resolution.

   A nested var() in a custom property resolves where the property is DECLARED,
   not where it is used. So a token declared only at :root freezes to the
   default Rose and never tracks a course wrapper or a Page Accent preset set
   on .rg-page. This block re-declares every NON-surface token whose value
   depends on the accent, so they re-resolve on the wrapper.

   The surface-dependent ones (eyebrow, accent text, focus, border and so on)
   are re-declared per surface in _surfaces.css, and .rg-page is named in the
   default block there for the same reason.

   Any future token whose value contains var(--rg-accent), --rg-accent-deep or
   --rg-accent-glow must be added here or to _surfaces.css (repo trap 21). */

.rg-page,
[class*="rg-course--"] {
  --rg-on-accent:          var(--rg-course-on-accent, var(--rg-ink));
  --rg-band-bg:            var(--rg-accent);
  --rg-band-text:          var(--rg-on-accent);
  --rg-feature-card-bg:    var(--rg-accent);
  --rg-feature-card-text:  var(--rg-on-accent);
  --rg-btn-primary-bg:     var(--rg-accent);
  --rg-btn-primary-text:   var(--rg-on-accent);
  --rg-chip-text:          var(--rg-accent-deep);
  --rg-glow:               radial-gradient(60% 70% at 0% 0%, var(--rg-accent) 0%, color-mix(in srgb, var(--rg-accent-glow) 45%, transparent) 38%, transparent 72%);
  --rg-surface-play:       color-mix(in srgb, var(--rg-accent) 23%, transparent);

  /* Legacy aliases, re-resolved for the same reason. */
  --rg-teal:            var(--rg-accent);
  --rg-teal-glow:       var(--rg-accent-glow);
  --rg-accent-on-teal:  var(--rg-on-accent);
  --rg-accent-on-light: var(--rg-accent-deep);
}
/* Surfaces - the one place text colour is decided.

   A surface is a named ground (white, paper, ink). Each one writes the same
   token block, and everything painted on it reads those tokens. No module sets
   its own text colour against a background an editor can change, which is how
   editors get to choose colours without being able to break contrast.

   White is the page default, so .rg-page is named in the white block. That is
   not redundant with :root in _tokens.css: these tokens contain var(--rg-accent)
   and must re-resolve on the wrapper that carries a page accent (trap 21).

   The legacy background presets and gradient / scrim utilities are named in the
   block that matches the ground they paint, so unmigrated modules that use them
   keep legible text now that the page default is light. */

.rg-page,
.rg-surface--white,
.rg-bg--white {
  --rg-surface:        var(--rg-white);
  --rg-surface-raised: var(--rg-paper);
  --rg-text:           var(--rg-ink);
  --rg-text-muted:     color-mix(in srgb, var(--rg-ink) 72%, var(--rg-white));
  --rg-line:           color-mix(in srgb, var(--rg-ink) 16%, transparent);
  --rg-border:         1px solid var(--rg-line);
  --rg-border-soft:    1px solid color-mix(in srgb, var(--rg-ink) 9%, transparent);
  --rg-highlight:      var(--rg-text);
  --rg-eyebrow:        var(--rg-accent-deep);
  --rg-accent-text:    var(--rg-accent-deep);
  --rg-accent-large:   var(--rg-accent-large-light, var(--rg-accent));
  --rg-focus:          var(--rg-ink);
  --rg-dot-inactive:   color-mix(in srgb, var(--rg-ink) 55%, var(--rg-white));
  --rg-btn-secondary-bg:   var(--rg-ink);
  --rg-btn-secondary-text: var(--rg-paper);
  --rg-chip-bg:            var(--rg-paper);
  --rg-small-weight:       700;
  --rg-error-text:         color-mix(in srgb, var(--rg-error) 65%, var(--rg-ink));
}

.rg-surface--paper,
.rg-section-card {
  --rg-surface:        var(--rg-paper);
  --rg-surface-raised: var(--rg-white);
  --rg-text:           var(--rg-ink);
  --rg-text-muted:     color-mix(in srgb, var(--rg-ink) 72%, var(--rg-paper));
  --rg-line:           color-mix(in srgb, var(--rg-ink) 16%, transparent);
  --rg-border:         1px solid var(--rg-line);
  --rg-border-soft:    1px solid color-mix(in srgb, var(--rg-ink) 9%, transparent);
  --rg-highlight:      var(--rg-text);
  --rg-eyebrow:        var(--rg-accent-deep);
  --rg-accent-text:    var(--rg-accent-deep);
  --rg-accent-large:   var(--rg-accent-large-light, var(--rg-accent));
  --rg-focus:          var(--rg-ink);
  --rg-dot-inactive:   color-mix(in srgb, var(--rg-ink) 55%, var(--rg-paper));
  --rg-btn-secondary-bg:   var(--rg-ink);
  --rg-btn-secondary-text: var(--rg-paper);
  --rg-chip-bg:            var(--rg-white);
  --rg-small-weight:       700;
  --rg-error-text:         color-mix(in srgb, var(--rg-error) 65%, var(--rg-ink));
}

.rg-surface--ink,
.rg-bg--dark,
.rg-bg--gradient,
.rg-bg--gradient-deep,
.rg-bg--image,
.rg-gradient-card,
.rg-gradient-card--deep,
.rg-scrim-radial {
  --rg-surface:        var(--rg-ink);
  --rg-surface-raised: var(--rg-ink-raised);
  --rg-text:           var(--rg-white);
  --rg-text-muted:     color-mix(in srgb, var(--rg-white) 78%, var(--rg-ink));
  --rg-line:           color-mix(in srgb, var(--rg-white) 20%, transparent);
  --rg-border:         1px solid var(--rg-line);
  --rg-border-soft:    1px solid color-mix(in srgb, var(--rg-white) 11%, transparent);
  --rg-highlight:      var(--rg-whitsunday);
  --rg-eyebrow:        var(--rg-accent-ink, var(--rg-accent));
  --rg-accent-text:    var(--rg-accent-ink, var(--rg-accent));
  --rg-accent-large:   var(--rg-accent-ink, var(--rg-accent));
  --rg-focus:          var(--rg-white);
  --rg-dot-inactive:   color-mix(in srgb, var(--rg-white) 55%, var(--rg-ink));
  --rg-btn-secondary-bg:   var(--rg-paper);
  --rg-btn-secondary-text: var(--rg-ink);
  --rg-chip-bg:            var(--rg-paper);
  --rg-small-weight:       400;
  --rg-error-text:         var(--rg-error);
}

.rg-surface--white,
.rg-surface--paper,
.rg-surface--ink {
  background-color: var(--rg-surface);
  color: var(--rg-text);
}

/* A photo or gradient ground carries light text even with no surface class. */
.rg-gradient-card,
.rg-gradient-card--deep,
.rg-scrim-radial {
  color: var(--rg-text);
}
/* .rg-btn - the pill button. One shape for every CTA.

   primary    Rose fill, Ink label. W1: the comps show a white label (3.37);
              it is built Ink (5.66) for WCAG AA.
   secondary  Ink pill with a Paper label on light surfaces. On Ink the pair
              flips to Paper with an Ink label, set by the surface tokens.
   white      White with an Ink label and an arrow. The button on a Rose tab
              header or section band (A2, option B), where the surface tokens
              do not apply. Ink on White is 19:1.
   ink        Always Ink with a Paper label. The tab button before A2, kept for
              any legacy use.
   ghost      Text plus arrow, no fill.
   full       Full width (media card). Sentence case like every button.

   --dark, --outline and --fill are the navy-era names, kept as aliases until
   the module field choices are renamed in Phase 2.

   Hover lightens a fill toward white, so label contrast only ever goes up. */

.rg-btn {
  align-items: center;
  background-color: var(--rg-btn-primary-bg);
  border: 2px solid var(--rg-btn-border, transparent);
  /* Through a variable, so a module that joins a pill to a field (the
     newsletter) sets --rg-btn-radius and every state follows. */
  border-radius: var(--rg-btn-radius, var(--rg-radius-pill));
  box-sizing: border-box;
  color: var(--rg-btn-primary-text);
  cursor: pointer;
  display: inline-flex;
  font-family: var(--rg-body-font);
  font-size: var(--rg-btn);
  font-weight: 700;
  gap: var(--rg-space-1);
  justify-content: center;
  line-height: 1.25;
  min-height: var(--rg-btn-height);
  /* Declared, never inherited: theme-overrides.css gives every bare button
     theme-field padding (repo trap 20). */
  padding: 0 var(--rg-space-4);
  text-decoration: none;
  text-transform: none;
  transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease;
  /* A CTA row wraps BETWEEN buttons, never inside one. */
  white-space: nowrap;
}

/* Colour, family, weight and radius are re-asserted on every state: in the
   portal the theme's own a:hover rule would otherwise restyle the label, and
   its button:hover / button:focus rules (0,1,1) set a theme-field radius that
   turned every <button> pill square on hover (D1). */
.rg-btn:hover,
.rg-btn:focus,
.rg-btn:focus-visible,
.rg-btn:active {
  background-color: color-mix(in srgb, var(--rg-btn-primary-bg) 84%, var(--rg-white));
  /* The theme's hover rule also sets a 1px border (Walk 10), which thinned the
     2px edge and nudged the pill a pixel. The edge is pinned too. */
  border: 2px solid var(--rg-btn-border, transparent);
  border-radius: var(--rg-btn-radius, var(--rg-radius-pill));
  color: var(--rg-btn-primary-text);
  font-family: var(--rg-body-font);
  font-weight: 700;
  text-decoration: none;
}

.rg-btn:focus-visible {
  outline: 3px solid var(--rg-focus);
  outline-offset: 3px;
}

.rg-btn--secondary,
.rg-btn--dark {
  background-color: var(--rg-btn-secondary-bg);
  color: var(--rg-btn-secondary-text);
}

.rg-btn--secondary:hover,
.rg-btn--secondary:focus,
.rg-btn--secondary:focus-visible,
.rg-btn--secondary:active,
.rg-btn--dark:hover,
.rg-btn--dark:focus,
.rg-btn--dark:focus-visible,
.rg-btn--dark:active {
  background-color: color-mix(in srgb, var(--rg-btn-secondary-bg) 84%, var(--rg-btn-secondary-text));
  color: var(--rg-btn-secondary-text);
}

.rg-btn--ink {
  background-color: var(--rg-ink);
  color: var(--rg-paper);
}

.rg-btn--ink:hover,
.rg-btn--ink:focus,
.rg-btn--ink:focus-visible,
.rg-btn--ink:active {
  background-color: var(--rg-ink-raised);
  color: var(--rg-paper);
}

.rg-btn--white {
  background-color: var(--rg-btn-band-bg);
  color: var(--rg-btn-band-text);
}

.rg-btn--white::after {
  content: "\2192" / "";
  transition: transform 0.2s ease;
}

.rg-btn--white:hover,
.rg-btn--white:focus,
.rg-btn--white:focus-visible,
.rg-btn--white:active {
  background-color: var(--rg-paper);
  color: var(--rg-btn-band-text);
}

.rg-btn--white:hover::after,
.rg-btn--white:focus-visible::after {
  transform: translateX(4px);
}

.rg-btn--outline {
  --rg-btn-border: currentColor;
  background-color: transparent;
  color: var(--rg-text);
}

.rg-btn--outline:hover,
.rg-btn--outline:focus,
.rg-btn--outline:focus-visible,
.rg-btn--outline:active {
  background-color: color-mix(in srgb, var(--rg-text) 10%, transparent);
  color: var(--rg-text);
}

/* The arrow is absolutely placed in padding reserved for it. Text decoration
   is not propagated to an absolutely positioned descendant, so the hover
   underline sits under the label only and the arrow moves on its own (D2).
   As an in-flow ::after it was underlined too, which read as unfinished. */
.rg-btn--ghost {
  background-color: transparent;
  color: var(--rg-text);
  padding-inline: var(--rg-space-1) calc(var(--rg-space-1) + 1.5em);
  position: relative;
}

.rg-btn--ghost::after {
  content: "\2192" / "";
  position: absolute;
  right: var(--rg-space-1);
  top: 50%;
  transform: translateY(-50%);
  transition: transform 0.2s ease;
}

.rg-btn--ghost:hover,
.rg-btn--ghost:focus,
.rg-btn--ghost:focus-visible,
.rg-btn--ghost:active {
  background-color: transparent;
  color: var(--rg-text);
  text-decoration: underline;
  text-underline-offset: 0.25em;
}

.rg-btn--ghost:hover::after,
.rg-btn--ghost:focus-visible::after {
  transform: translate(4px, -50%);
}

.rg-btn--fill,
.rg-btn--full {
  width: 100%;
}

.rg-btn--sm {
  font-size: 0.875rem;
  min-height: 40px;
  padding-inline: var(--rg-space-3);
}

@media (prefers-reduced-motion: reduce) {
  .rg-btn,
  .rg-btn--ghost::after,
  .rg-btn--white::after {
    transition: none;
  }
}
/* Form skin - the Pink Pivot look for a classic HubSpot form (C1, C2).

   Put .rg-form-skin on the element that wraps the form tag. Everything reads
   the surface tokens, so the same rules serve a Paper and an Ink ground: the
   ground is decided by the surface class on an ancestor, never here.

   Shared vocabulary (repo trap 14). rg-form and rg-brochure both use it, and a
   module's own CSS only loads when that module is on the page, so it lives in
   main.css. Any other form (the contact card, the form modal) can opt in with
   the one class.

   It sits on top of the .hs-form layer in elements/_forms.css and does not
   repeat it. That layer reads its field fill, edge and text from the
   --rg-field-* variables set below, with the dark glass as the fallback for
   forms that do not opt in. What the skin adds:
     - labels, help text and the required marker, sized and coloured outright
       (repo trap 13: the portal's theme rules style bare form text)
     - a visible focus ring
     - errors in the surface's error text colour, 4.5:1 or better on both
     - a token-drawn select chevron that follows the text colour
     - the submit as the Rose pill (.rg-btn primary), pinned in every state
       against the theme's .hs-button hover and focus rules (D1, Walk 10)
     - the inline thank-you message

   Classic forms only (repo trap 11). */

.rg-form-skin {
  --rg-field-bg: var(--rg-surface-raised);
  --rg-field-line: color-mix(in srgb, var(--rg-text) 55%, transparent);
  --rg-field-text: var(--rg-text);
  --rg-field-placeholder: var(--rg-text-muted);
  --rg-field-placeholder-weight: 400;
  --rg-field-placeholder-opacity: 1;
  color: var(--rg-text);
  font-family: var(--rg-body-font);
}

/* The form box. The portal's theme gives bare `form` and the thank-you
   message a border, radius and padding from theme fields. */
.rg-form-skin form,
.rg-form-skin .hs-form {
  border: 0;
  border-radius: 0;
  margin: 0;
  padding: 0;
}

/* The form tag always writes a title heading, empty unless a title is set. In
   the portal it carries theme padding, so an empty one is a gap. */
.rg-form-skin .form-title:empty {
  display: none;
}

.rg-form-skin .hs-form fieldset {
  border: 0;
  margin: 0;
  max-width: none !important;
  min-width: 0;
  padding: 0;
}

.rg-form-skin .hs-form-field {
  margin: 0 0 var(--rg-space-3);
}

/* Field labels. Direct children only, so option and error labels keep their
   own rules below. */
.rg-form-skin .hs-form .hs-form-field > label,
.rg-form-skin .hs-form .hs-form-field > legend:not(.hs-field-desc) {
  color: var(--rg-text);
  display: block;
  font-family: var(--rg-body-font);
  font-size: var(--rg-btn);
  font-weight: 600;
  line-height: 1.4;
  margin: 0 0 var(--rg-space-1);
  text-transform: none;
}

.rg-form-skin .hs-form .hs-form-required {
  color: var(--rg-accent-text);
  margin-left: 0.15em;
}

/* Help text: HubSpot writes it as a legend, hidden by an inline style when
   the field has none. */
.rg-form-skin .hs-form legend.hs-field-desc,
.rg-form-skin .hs-form .hs-field-desc {
  color: var(--rg-text-muted);
  font-family: var(--rg-body-font);
  font-size: var(--rg-small);
  font-weight: 400;
  line-height: 1.45;
  margin: 0 0 var(--rg-space-1);
}

/* Text fields, select and textarea. Fill, edge and text come from the
   variables above through the .hs-form layer. */
.rg-form-skin .hs-form input:not([type=checkbox]):not([type=radio]):not([type=submit]):not([type=file]),
.rg-form-skin .hs-form select,
.rg-form-skin .hs-form textarea {
  box-shadow: none;
  font-family: var(--rg-body-font);
  font-size: var(--rg-btn);
  line-height: 1.4;
  min-height: var(--rg-btn-height);
}

/* Select: a chevron drawn from two gradients in the text colour, so it
   follows the ground (the .hs-form layer's chevron is a white image). */
.rg-form-skin .hs-form select {
  background-image:
    linear-gradient(45deg, transparent 50%, var(--rg-field-text) 50%),
    linear-gradient(135deg, var(--rg-field-text) 50%, transparent 50%);
  background-position:
    calc(100% - var(--rg-space-3) - 6px) 50%,
    calc(100% - var(--rg-space-3)) 50%;
  background-repeat: no-repeat;
  background-size: 6px 6px;
  cursor: pointer;
}

/* The disabled "Please select" option HubSpot puts first. */
.rg-form-skin .hs-form select.is-placeholder {
  color: var(--rg-field-placeholder);
}

.rg-form-skin .hs-form select option {
  background-color: var(--rg-field-bg);
  color: var(--rg-field-text);
}

/* Focus: a ring in the surface's focus colour (Ink on light, white on Ink),
   the same as the buttons. Keyboard and mouse both, as fields are typed in. */
.rg-form-skin .hs-form input:focus,
.rg-form-skin .hs-form select:focus,
.rg-form-skin .hs-form textarea:focus {
  border-color: var(--rg-field-text);
  box-shadow: none;
  outline: 3px solid var(--rg-focus);
  outline-offset: 2px;
}

/* Checkbox and radio lists, and the consent checkbox. */
.rg-form-skin .hs-form .inputs-list:not(.hs-error-msgs) label,
.rg-form-skin .hs-form .hs-form-booleancheckbox label {
  color: var(--rg-text);
  cursor: pointer;
  font-family: var(--rg-body-font);
  font-size: var(--rg-btn);
  font-weight: 400;
  line-height: 1.45;
  margin: 0;
}

.rg-form-skin .hs-form .inputs-list:not(.hs-error-msgs) label {
  align-items: flex-start;
  display: flex;
  gap: var(--rg-space-1);
}

.rg-form-skin .hs-form .inputs-list:not(.hs-error-msgs) > li {
  margin: 0 0 var(--rg-space-1);
}

/* Width is !important because the .hs-form layer sets checkboxes and radios
   in a form-columns fieldset to width: auto !important. */
.rg-form-skin .hs-form input[type=checkbox],
.rg-form-skin .hs-form input[type=radio] {
  accent-color: var(--rg-accent-text);
  flex: 0 0 auto;
  height: 1.125rem;
  margin: 0.15em 0 0;
  width: 1.125rem !important;
}

.rg-form-skin .hs-form input[type=checkbox]:focus-visible,
.rg-form-skin .hs-form input[type=radio]:focus-visible {
  outline: 3px solid var(--rg-focus);
  outline-offset: 2px;
}

/* Errors. HubSpot marks the field .error / .invalid and lists the messages
   under it; the rollup above the submit repeats "complete all required". */
.rg-form-skin .hs-form .hs-input.error,
.rg-form-skin .hs-form .hs-input.invalid {
  border-color: var(--rg-error-text);
  box-shadow: inset 0 0 0 1px var(--rg-error-text);
}

.rg-form-skin .hs-form .hs-error-msgs {
  list-style: none;
  margin: var(--rg-space-1) 0 0;
  padding: 0;
}

.rg-form-skin .hs-form .hs-error-msgs li {
  display: block;
  margin: 0;
}

.rg-form-skin .hs-form .hs-error-msg,
.rg-form-skin .hs-form .hs-error-msgs label {
  color: var(--rg-error-text);
  display: block;
  font-family: var(--rg-body-font);
  font-size: var(--rg-small);
  font-weight: 600;
  line-height: 1.45;
  margin: 0;
}

.rg-form-skin .hs-form .hs_error_rollup {
  margin: 0 0 var(--rg-space-2);
}

/* Rich text and consent blocks inside the form (repo trap 13: the portal
   styles bare p). */
.rg-form-skin .hs-form .hs-richtext,
.rg-form-skin .hs-form .hs-richtext p,
.rg-form-skin .hs-form .hs-richtext li,
.rg-form-skin .hs-form .legal-consent-container,
.rg-form-skin .hs-form .legal-consent-container p,
.rg-form-skin .hs-form .legal-consent-container .hs-form-booleancheckbox-display > span,
.rg-form-skin .hs-form .legal-consent-container .hs-form-booleancheckbox-display > span p {
  color: var(--rg-text-muted);
  font-family: var(--rg-body-font);
  font-size: var(--rg-small);
  line-height: 1.5;
}

.rg-form-skin .hs-form .legal-consent-container .hs-form-booleancheckbox-display > span,
.rg-form-skin .hs-form .legal-consent-container .hs-form-booleancheckbox-display > span p {
  margin-left: 0 !important;
}

.rg-form-skin .hs-form .hs-richtext p {
  margin: 0 0 var(--rg-space-2);
}

.rg-form-skin .hs-form .hs-richtext a,
.rg-form-skin .hs-form .legal-consent-container a {
  color: var(--rg-accent-text);
  text-decoration: underline;
}

.rg-form-skin .hs-form .hs-richtext a:hover,
.rg-form-skin .hs-form .hs-richtext a:focus-visible,
.rg-form-skin .hs-form .legal-consent-container a:hover,
.rg-form-skin .hs-form .legal-consent-container a:focus-visible {
  color: var(--rg-text);
}

/* File input: the choose-file button follows the field fill. */
.rg-form-skin .hs-form input[type=file] {
  color: var(--rg-text);
  font-size: var(--rg-btn);
}

/* Submit: the Rose pill, the same as .rg-btn primary. HubSpot writes an
   <input type=submit class="hs-button">, and the theme's .hs-button and
   button rules give it theme-field padding, radius, border and colours, so
   every one of those is declared here and pinned in every state (repo trap
   20, D1). The .hs-form layer's teal gradient and brightness filter are
   cancelled too. */
.rg-form-skin .hs-form .hs_submit {
  margin-top: var(--rg-space-1);
}

.rg-form-skin .hs-form .hs_submit .actions {
  margin: 0;
  padding: 0;
}

.rg-form-skin .hs-form input[type=submit],
.rg-form-skin .hs-form .hs-button {
  -webkit-appearance: none;
  appearance: none;
  background: var(--rg-btn-primary-bg);
  border: 2px solid transparent;
  border-radius: var(--rg-radius-pill);
  box-shadow: none;
  color: var(--rg-btn-primary-text);
  cursor: pointer;
  filter: none;
  font-family: var(--rg-body-font);
  font-size: var(--rg-btn);
  font-weight: 700;
  line-height: 1.25;
  margin: 0;
  min-height: var(--rg-btn-height);
  padding: 0 var(--rg-space-4);
  text-transform: none;
  transition: background-color 0.2s ease;
  width: auto;
}

.rg-form-skin .hs-form input[type=submit]:is(:hover, :focus, :focus-visible, :active),
.rg-form-skin .hs-form .hs-button:is(:hover, :focus, :focus-visible, :active) {
  background: color-mix(in srgb, var(--rg-btn-primary-bg) 84%, var(--rg-white));
  border: 2px solid transparent;
  border-radius: var(--rg-radius-pill);
  box-shadow: none;
  color: var(--rg-btn-primary-text);
  filter: none;
  outline: none;
}

.rg-form-skin .hs-form input[type=submit]:focus-visible,
.rg-form-skin .hs-form .hs-button:focus-visible {
  outline: 3px solid var(--rg-focus);
  outline-offset: 3px;
}

/* Thank-you message (inline response). HubSpot swaps the form for this div.
   The theme gives it the form's border, padding and background, and styles
   its bare p, so all of it is declared here. */
.rg-form-skin .submitted-message {
  background-color: var(--rg-surface-raised);
  border: var(--rg-border);
  border-radius: var(--rg-radius-sm);
  color: var(--rg-text);
  font-family: var(--rg-body-font);
  font-size: var(--rg-body);
  line-height: 1.5;
  margin: 0;
  /* Room on the left for the tick, which is placed, not in flow, so a message
     of several paragraphs stacks normally. */
  padding: var(--rg-space-3) var(--rg-space-3) var(--rg-space-3) calc(var(--rg-space-3) + 2rem + var(--rg-space-2));
  position: relative;
}

.rg-form-skin .submitted-message::before {
  align-items: center;
  background-color: var(--rg-badge-bg);
  border-radius: 50%;
  color: var(--rg-badge-text);
  content: "\2713" / "";
  display: flex;
  font-size: var(--rg-btn);
  font-weight: 700;
  height: 2rem;
  justify-content: center;
  left: var(--rg-space-3);
  position: absolute;
  top: var(--rg-space-3);
  width: 2rem;
}

.rg-form-skin .submitted-message > :first-child {
  margin-top: 0;
}

.rg-form-skin .submitted-message p {
  color: var(--rg-text);
  font-family: var(--rg-body-font);
  font-size: var(--rg-body);
  line-height: 1.5;
  margin: 0 0 var(--rg-space-1);
}

.rg-form-skin .submitted-message p:last-child {
  margin-bottom: 0;
}

.rg-form-skin .submitted-message a {
  color: var(--rg-accent-text);
  text-decoration: underline;
}

@media (prefers-reduced-motion: reduce) {
  .rg-form-skin .hs-form input[type=submit],
  .rg-form-skin .hs-form .hs-button {
    transition: none;
  }
}
/* Section shell - a rounded container with an optional Rose tab header joined
   to it. The most used composition in the approved comps (six times on Home,
   three on CEO). Markup comes from templates/partials/rg-shell.html.

   The shell body takes a surface class (paper or ink), so everything inside it
   derives its text colour from the shell. The tab is its own small surface:
   Rose with Ink text (W2), and a white pill for the optional CTA.

   Section header option B (gallery feedback r1, A2): the tab text is a real
   heading, not a caps label, at the shared row heading size and weight
   (--rg-row-heading-size / -weight, Home Review 2). Desktop puts the heading and
   button on one line with the button at the end. Below 768px they stack,
   heading on top, both left-aligned. */

/* --------------------------------------------------------------------------
   Section heading tab look - the ONE place it is set (Rollout ruling 4).
   Read by the shell tab below and by the full-bleed .rg-band (_rg-base.css),
   so a change here reaches every heading tab and band on the site, the
   homepage included, with no module or template edit.

   --rg-tab-bg    the tab ground (a colour or a gradient)
   --rg-tab-text  the heading, accent words, band copy and the focus ring
   --rg-tab-tile  the social icon tiles in a tab (Ink by default)

   Declared on the tab element itself, not at :root, so a var(--rg-accent)
   inside a value resolves against the page or course accent the tab sits in
   (repo trap 21 does not apply).

   The look is the corner glow (Review 3 S5, option C, Mike 2026-10-28): the
   hero's glow (--rg-glow: accent from the top-left corner through Muted Rose
   into transparent, over Ink), reshaped for a short, wide bar so it blooms
   from the corner instead of smearing along the top, with white text. The
   corner stop is the accent mixed 75% into Ink so white text holds 4.5:1 or
   better where it overlaps the glow: Rose 5.34, restorative 4.61, aligners
   4.64, implantology 7.37; 19.09 on the Ink field. Ink social tiles would
   vanish into the Ink, so they take a light veil.

   The previous solid tab was --rg-tab-bg: var(--rg-band-bg), --rg-tab-text:
   var(--rg-band-text), --rg-tab-tile: var(--rg-ink). Restore those three
   values to go back to it. The comparison shots of all four options are in
   review/rollout/tab-options/.
   -------------------------------------------------------------------------- */

.rg-shell__tab,
.rg-band {
  --rg-tab-bg:   radial-gradient(38% 260% at 0% 0%, color-mix(in srgb, var(--rg-accent) 75%, var(--rg-ink)) 0%, color-mix(in srgb, var(--rg-accent-glow) 45%, transparent) 38%, transparent 72%), var(--rg-ink);
  --rg-tab-text: var(--rg-white);
  --rg-tab-tile: color-mix(in srgb, var(--rg-white) 16%, transparent);
}

.rg-shell {
  border-radius: var(--rg-radius-card);
  margin-inline: auto;
  max-width: var(--rg-container);
  overflow: hidden;
  width: calc(100% - (2 * var(--rg-gutter)));
}

.rg-shell__tab {
  --rg-text: var(--rg-tab-text);
  --rg-focus: var(--rg-tab-text);
  align-items: center;
  background: var(--rg-tab-bg);
  color: var(--rg-tab-text);
  display: flex;
  flex-wrap: wrap;
  gap: var(--rg-space-2) var(--rg-space-4);
  justify-content: space-between;
  min-height: 84px;
  padding: var(--rg-space-2) var(--rg-space-5);
}

/* Button position (Review 1 addendum). Desktop only: below 768px every tab
   stacks. The base rule is the right-edge layout. */
.rg-shell__tab--btn-left {
  justify-content: flex-start;
}

.rg-shell__tab--btn-below {
  align-items: flex-start;
  flex-direction: column;
  padding-block: var(--rg-space-3);
}

.rg-shell__tab--center {
  flex-direction: column;
  justify-content: center;
  text-align: center;
}

.rg-shell__title {
  color: var(--rg-tab-text);
  font-family: var(--rg-font);
  font-size: var(--rg-row-heading-size);
  font-weight: var(--rg-row-heading-weight);
  letter-spacing: var(--rg-track-head);
  line-height: 1.15;
  margin: 0;
  text-transform: none;
}

.rg-shell__actions {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--rg-space-2);
}

.rg-shell__social {
  display: flex;
  gap: var(--rg-space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}

.rg-shell__social-link {
  align-items: center;
  background-color: var(--rg-tab-tile);
  border-radius: var(--rg-radius-sm);
  color: var(--rg-paper);
  display: inline-flex;
  height: 48px;
  justify-content: center;
  width: 48px;
}

/* The glyph SVGs are drawn on a tile-sized artboard with the mark at about a
   third of it, so the image fills the tile and is scaled up a little. */
.rg-shell__social-link img,
.rg-shell__social-link svg {
  display: block;
  height: 100%;
  transform: scale(1.3);
  width: 100%;
}

.rg-shell__body {
  padding: var(--rg-space-4);
}

.rg-shell__body--flush {
  padding: 0;
}

@media (max-width: 767.98px) {
  .rg-shell__tab {
    align-items: flex-start;
    flex-direction: column;
    min-height: 64px;
    padding: var(--rg-space-3);
    text-align: left;
  }

  .rg-shell__tab--center {
    align-items: center;
    text-align: center;
  }

  .rg-shell__body {
    padding: var(--rg-space-2);
  }
}
/* Ring - the system motif: a circle stroke with a Rose dot riding it. Pure CSS,
   no raster. The stroke takes the surface text colour by default (Paper-white
   on Ink, Ink on light), and is broken by a short gap where the dot sits.

   Sizes: --s (step numerals), --m, --l, --xl (banner and panel graphics).
   Content placed inside the ring is centred, which is how the numbered outcome
   steps and the circle CTA use it. Decorative rings carry aria-hidden. */

.rg-ring {
  --rg-ring-size: 120px;
  --rg-ring-stroke: 6px;
  --rg-ring-color: var(--rg-text);
  align-items: center;
  aspect-ratio: 1;
  display: inline-flex;
  flex: none;
  justify-content: center;
  position: relative;
  width: var(--rg-ring-size);
}

.rg-ring::before {
  border: var(--rg-ring-stroke) solid var(--rg-ring-color);
  border-radius: 50%;
  content: "";
  inset: 0;
  /* The gap: 34 degrees of arc left open around the dot at the 45 degree mark. */
  -webkit-mask: conic-gradient(from 28deg, transparent 0 34deg, black 34deg);
  mask: conic-gradient(from 28deg, transparent 0 34deg, black 34deg);
  position: absolute;
}

.rg-ring::after {
  aspect-ratio: 1;
  background-color: var(--rg-accent);
  border-radius: 50%;
  content: "";
  position: absolute;
  /* Centre of the dot lands on the stroke at 45 degrees: r * (1 - cos 45). */
  right: 14.6%;
  top: 14.6%;
  transform: translate(50%, -50%);
  width: 17%;
}

.rg-ring--s  { --rg-ring-size: 72px;  --rg-ring-stroke: 4px; }
.rg-ring--m  { --rg-ring-size: 120px; --rg-ring-stroke: 6px; }
.rg-ring--l  { --rg-ring-size: clamp(180px, 22vw, 280px); --rg-ring-stroke: 12px; }
.rg-ring--xl { --rg-ring-size: clamp(260px, 38vw, 520px); --rg-ring-stroke: clamp(16px, 2.4vw, 34px); }

.rg-ring--paper { --rg-ring-color: var(--rg-paper); }
.rg-ring--ink   { --rg-ring-color: var(--rg-ink); }

.rg-ring__content {
  color: var(--rg-accent-large);
  font-family: var(--rg-font);
  font-size: calc(var(--rg-ring-size) * 0.36);
  font-weight: 600;
  line-height: 1;
  position: relative;
}
/* Media card - one card shape for masterclass, podcast and video.
   Ink thumbnail, the shared play button (components/_play.css), Whitsunday
   type badge, centred title,
   full-width pill. Shared by rg-masterclass-grid, rg-blog-row and
   rg-video-carousel, so it lives here and not in any one module (trap 14).

   The card body is the raised surface of whatever it sits on: white on a Paper
   shell, raised Ink on an Ink shell. */

.rg-media-card {
  background-color: var(--rg-surface-raised);
  border-radius: var(--rg-radius-card);
  color: var(--rg-text);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.rg-media-card__thumb {
  align-items: center;
  aspect-ratio: 16 / 10;
  background-color: var(--rg-media-bg);
  display: flex;
  justify-content: center;
  overflow: hidden;
  position: relative;
}

.rg-media-card__thumb > img {
  height: 100%;
  inset: 0;
  object-fit: cover;
  position: absolute;
  width: 100%;
}

/* The play button is the shared .rg-play component (components/_play.css).
   This class only places it: centred on the plain Ink placeholder, and in the
   corner over a real thumbnail (below). */

.rg-media-card__badge {
  align-items: center;
  background-color: var(--rg-badge-bg);
  border-radius: 50%;
  color: var(--rg-badge-text);
  display: inline-flex;
  height: 40px;
  justify-content: center;
  position: absolute;
  right: var(--rg-space-2);
  top: var(--rg-space-2);
  width: 40px;
}

.rg-media-card__badge svg,
.rg-media-card__badge img {
  display: block;
  height: 20px;
  width: 20px;
}

.rg-media-card__body {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--rg-space-3);
  padding: var(--rg-space-3);
  text-align: center;
}

.rg-media-card__title {
  color: var(--rg-text);
  font-family: var(--rg-font);
  font-size: var(--rg-h5);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.2;
  margin: 0;
}

.rg-media-card__body .rg-btn {
  margin-top: auto;
}

/* The thumbnail can be the play link itself. */
a.rg-media-card__thumb {
  color: inherit;
  text-decoration: none;
}

a.rg-media-card__thumb:focus-visible {
  outline: 3px solid var(--rg-white);
  outline-offset: -6px;
}

.rg-media-card__thumb iframe {
  border: 0;
  height: 100%;
  inset: 0;
  position: absolute;
  width: 100%;
}

/* A real thumbnail is shown whole and undimmed at its 16:9 source ratio, so
   artwork with text in it is not cropped. The play ring steps down to a small
   mark in the bottom-left corner; the large centred ring is for the plain Ink
   placeholder only. */
.rg-media-card__thumb--photo {
  aspect-ratio: 16 / 9;
}

.rg-media-card__thumb--photo > .rg-media-card__play {
  --rg-play-size: 44px;
  --rg-play-ring: 6px;
  bottom: var(--rg-space-2);
  left: var(--rg-space-3);
  position: absolute;
}

.rg-media-card__thumb > img ~ .rg-media-card__play,
.rg-media-card__thumb > img ~ .rg-media-card__badge {
  z-index: 1;
}

/* Whole-card link. The button is the one link on the card; its ::after is
   stretched over the card, so the thumbnail and title are clickable too while
   there is still a single tab stop with a single name. */
.rg-media-card--link {
  position: relative;
}

.rg-media-card--link .rg-btn::after {
  content: "";
  inset: 0;
  position: absolute;
}

.rg-media-card--link:hover .rg-media-card__title {
  text-decoration: underline;
  text-underline-offset: 4px;
}

.rg-media-card__meta {
  color: var(--rg-text-muted);
  font-family: var(--rg-body-font);
  font-size: 0.875rem;
  line-height: 1.4;
  margin: 0;
}

.rg-media-card__title a {
  color: inherit;
  text-decoration: none;
}

.rg-media-card__title a:hover,
.rg-media-card__title a:focus-visible {
  text-decoration: underline;
  text-underline-offset: 4px;
}

/* Flat: the title, copy and button are direct children (no __body wrapper),
   for modules whose card markup predates the wrapper. */
.rg-media-card--flat {
  gap: var(--rg-space-2);
  padding-bottom: var(--rg-space-3);
  text-align: center;
}

.rg-media-card--flat > :not(.rg-media-card__thumb) {
  margin-inline: var(--rg-space-3);
}

.rg-media-card--flat > .rg-media-card__title {
  margin-top: var(--rg-space-2);
}

/* The full-width pill is stretched by the column, not sized at 100%: with the
   side margins above, 100% overflowed the card. */
.rg-media-card--flat > .rg-btn {
  align-self: stretch;
  margin-top: auto;
  width: auto;
}

/* A grid of media cards, shared by the listing modules. */
.rg-media-grid {
  display: grid;
  gap: var(--rg-space-3);
  grid-template-columns: repeat(3, minmax(0, 1fr));
}

@media (max-width: 1023.98px) {
  .rg-media-grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

@media (max-width: 599.98px) {
  .rg-media-grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* Row: three cards to a view in a scroll-snap track, with dots under it
   (js/rg-track-dots.js). Two to a view on tablets, one and a peek on phones. */
.rg-media-grid--row {
  display: flex;
  overflow-x: auto;
  padding-bottom: var(--rg-space-1);
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.rg-media-grid--row::-webkit-scrollbar {
  display: none;
}

.rg-media-grid--row > * {
  flex: 0 0 calc((100% - (2 * var(--rg-space-3))) / 3);
  scroll-snap-align: start;
}

@media (max-width: 1023.98px) {
  .rg-media-grid--row > * {
    flex-basis: calc((100% - var(--rg-space-3)) / 2);
  }
}

@media (max-width: 599.98px) {
  .rg-media-grid--row > * {
    flex-basis: 86%;
  }
}
/* Play button - ONE component for every video thumbnail (gallery feedback r1,
   A5): the media card (masterclass grid, video carousel, card row), the
   split-feature video split and the testimonial video. Shared, so it lives
   here and not in a module (trap 14).

   Each module adds rg-play plus a style modifier from its "Play button style"
   field. The module's own __play class only places and sizes it, through
   --rg-play-size and --rg-play-ring.

   soft   (default) A see-through Ink disc with one static white ring and a
          white glyph. It reads over light photos, dark photos and the plain
          Ink placeholder, and it leaves Rose to the real buttons, so the play
          button and the "Watch" pill no longer compete.
   pulse  A Rose disc with ONE slow, faint halo. Under prefers-reduced-motion
          it renders as soft.

   The glyph is a graphic, not text: white on the disc passes 1.4.11. */

.rg-play {
  --rg-play-size: clamp(56px, 5vw, 76px);
  --rg-play-ring: 10px;
  align-items: center;
  -webkit-backdrop-filter: blur(6px);
  backdrop-filter: blur(6px);
  background-color: color-mix(in srgb, var(--rg-ink) 60%, transparent);
  border-radius: 50%;
  box-shadow: 0 0 0 2px color-mix(in srgb, var(--rg-white) 55%, transparent);
  color: var(--rg-white);
  display: inline-flex;
  flex: none;
  height: var(--rg-play-size);
  justify-content: center;
  position: relative;
  transition: background-color 0.2s ease;
  width: var(--rg-play-size);
}

.rg-play svg {
  display: block;
  height: 38%;
  margin-left: 6%;
  width: 38%;
}

/* The thumbnail or player around it is the link: darken the disc a step. */
a:hover .rg-play,
a:focus-visible .rg-play,
button:hover .rg-play,
button:focus-visible .rg-play {
  background-color: color-mix(in srgb, var(--rg-ink) 78%, transparent);
}

.rg-play--pulse {
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
  background-color: var(--rg-accent);
  box-shadow: none;
  animation: rg-play-pulse 2.8s ease-out infinite;
}

a:hover .rg-play--pulse,
a:focus-visible .rg-play--pulse,
button:hover .rg-play--pulse,
button:focus-visible .rg-play--pulse {
  background-color: color-mix(in srgb, var(--rg-accent) 84%, var(--rg-white));
}

/* none   (video carousel, testimonial carousel, card row) The module renders
          Soft plus this modifier. It is hidden wherever a thumbnail image
          sits in front of it, an earlier sibling, including one the
          auto-thumbnail inserts after load. A card with no image keeps the
          Soft ring so it still reads as a video. The play button is
          aria-hidden and the link around it stays, so the card's name and
          click target do not change. The masterclass grid drops its play
          button in its own script instead. */
img ~ .rg-play--none {
  display: none;
}

@keyframes rg-play-pulse {
  0% {
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--rg-accent) 35%, transparent);
  }

  100% {
    box-shadow: 0 0 0 var(--rg-play-ring) color-mix(in srgb, var(--rg-accent) 0%, transparent);
  }
}

@media (prefers-reduced-motion: reduce) {
  .rg-play {
    transition: none;
  }

  a:hover .rg-play--pulse,
  a:focus-visible .rg-play--pulse,
  button:hover .rg-play--pulse,
  button:focus-visible .rg-play--pulse {
    background-color: color-mix(in srgb, var(--rg-ink) 78%, transparent);
  }

  .rg-play--pulse {
    animation: none;
    -webkit-backdrop-filter: blur(6px);
    backdrop-filter: blur(6px);
    background-color: color-mix(in srgb, var(--rg-ink) 60%, transparent);
    box-shadow: 0 0 0 2px color-mix(in srgb, var(--rg-white) 55%, transparent);
  }
}
/* Background video (templates/partials/rg-video-bg.html, js/rg-video-bg.js).
   Shared by rg-hero and rg-video-band, so it lives here (trap 14).

   The video fills its positioned parent exactly like the photo under it, and
   stays transparent until it is actually playing, so the photo shows while
   it loads, under reduced motion and if it never plays. The parent's own
   overlay (the hero's ::after gradient) still paints over it.

   The toggle is the shared rg-play disc, set smaller and pinned to the
   bottom-right corner above any overlay. It is a real <button>, so it resets
   what theme-overrides.css gives every button (trap 20 and the portal-only
   button:hover rule at 0,1,1); the doubled class keeps it at 0,2,0. */

.rg-video-bg {
  display: block;
  height: 100%;
  inset: 0;
  object-fit: cover;
  opacity: 0;
  pointer-events: none;
  position: absolute;
  transition: opacity 0.6s ease;
  width: 100%;
}

.rg-video-bg.is-playing {
  opacity: 1;
}

.rg-video-bg__toggle.rg-play {
  --rg-play-size: 44px;
  border: 0;
  border-radius: 50%;
  bottom: var(--rg-space-3);
  cursor: pointer;
  padding: 0;
  position: absolute;
  right: var(--rg-space-3);
  z-index: 3;
}

.rg-video-bg__toggle.rg-play[hidden] {
  display: none;
}

.rg-video-bg__toggle.rg-play:hover,
.rg-video-bg__toggle.rg-play:focus-visible {
  background-color: color-mix(in srgb, var(--rg-ink) 78%, transparent);
  border: 0;
  border-radius: 50%;
  color: var(--rg-white);
}

.rg-video-bg__toggle.rg-play:focus-visible {
  outline: 3px solid var(--rg-white);
  outline-offset: 3px;
}

.rg-video-bg__toggle.rg-play svg {
  margin-left: 0;
}

.rg-video-bg__icon-play,
.rg-video-bg__toggle.is-paused .rg-video-bg__icon-pause {
  display: none;
}

.rg-video-bg__toggle.is-paused .rg-video-bg__icon-play {
  display: inline;
}

@media (prefers-reduced-motion: reduce) {
  .rg-video-bg,
  .rg-video-bg__toggle.rg-play {
    display: none;
  }
}
/* Outline pill tag - an icon plus short text inside a hairline pill. Used on
   event and appearance cards and as the content-card badge. It takes the
   surface text colour, so it is Paper-white on Ink and Ink on light. The
   default marker is a small diamond in the highlight colour. */

.rg-tag {
  align-items: center;
  border: 1.5px solid currentColor;
  border-radius: var(--rg-radius-pill);
  color: var(--rg-text);
  display: inline-flex;
  font-family: var(--rg-body-font);
  font-size: 0.8125rem;
  font-weight: var(--rg-small-weight);
  gap: var(--rg-space-1);
  line-height: 1.2;
  padding: 6px 14px;
}

.rg-tag::before {
  background-color: var(--rg-highlight);
  content: "";
  flex: none;
  height: 8px;
  transform: rotate(45deg);
  width: 8px;
}

.rg-tag--icon::before {
  content: none;
}

.rg-tag__icon {
  color: var(--rg-highlight);
  display: block;
  flex: none;
  height: 14px;
  width: 14px;
}

.rg-tags {
  align-items: flex-start;
  display: flex;
  flex-direction: column;
  gap: var(--rg-space-1);
  list-style: none;
  margin: 0;
  padding: 0;
}

.rg-tags--inline {
  flex-direction: row;
  flex-wrap: wrap;
}

/* --------------------------------------------------------------------------
   Tags that sit ON AN IMAGE (card badges, player tags). The plain outline tag
   takes the surface text colour, which is only safe on a known surface. Over a
   photo the ground is unknown, so these variants carry their own tested pair.
   The editor picks one by name; there is no colour picker.

     dark     Ink fill, white text          19.09:1
     light    Paper fill, Ink text          17.67:1
     pink     Rose fill, INK text            5.66:1  (W1: never white on Rose)
     aqua     Whitsunday fill, Ink text     about 15:1
     outline  transparent, white text and border. ONLY with .rg-tag-fade on the
              image container, which lays an Ink fade behind it.

   Weight follows --rg-small-weight (D6): regular for white text on Ink (dark,
   outline, and the plain tag on an Ink surface), bold for the light fills,
   whose own ground is light.
   -------------------------------------------------------------------------- */

.rg-tag--dark {
  --rg-highlight: var(--rg-whitsunday);
  background-color: var(--rg-ink);
  border-color: var(--rg-ink);
  color: var(--rg-white);
}

.rg-tag--light {
  --rg-small-weight: 700;
  --rg-highlight: var(--rg-rose-deep);
  background-color: var(--rg-paper);
  border-color: var(--rg-paper);
  color: var(--rg-ink);
}

.rg-tag--pink {
  --rg-small-weight: 700;
  --rg-highlight: var(--rg-ink);
  background-color: var(--rg-rose);
  border-color: var(--rg-rose);
  color: var(--rg-ink);
}

.rg-tag--aqua {
  --rg-small-weight: 700;
  --rg-highlight: var(--rg-ink);
  background-color: var(--rg-whitsunday);
  border-color: var(--rg-whitsunday);
  color: var(--rg-ink);
}

.rg-tag--outline {
  --rg-highlight: var(--rg-whitsunday);
  background-color: transparent;
  border-color: var(--rg-white);
  color: var(--rg-white);
}

/* Ink fade across the top of an image container, behind an outline tag. The
   container must be positioned and the tag must sit above z-index 0. At the
   tag's position the fade is at least 80% Ink, so white text passes on a pure
   white photo (about 12:1). */
.rg-tag-fade::after {
  background: linear-gradient(to bottom, color-mix(in srgb, var(--rg-ink) 88%, transparent) 0%, color-mix(in srgb, var(--rg-ink) 80%, transparent) 45%, transparent 100%);
  content: "";
  height: var(--rg-space-16);
  inset: 0 0 auto;
  pointer-events: none;
  position: absolute;
  z-index: 0;
}
/* Check chip - a Paper pill with an Ink check circle and its text as typed. Used by
   rg-tag-list and rg-curriculum-list (the FRD topic chips on Ink).

   The comp sets the text in Rose. On Paper that is 3.2:1, so it is built in
   Rose Deep (W3). The chip is always a light pill, whatever surface it sits
   on: --rg-chip-bg is Paper on white and Ink, white on Paper, set by the
   surface block so the pill never disappears into its ground. */

.rg-chip {
  align-items: center;
  background-color: var(--rg-chip-bg);
  /* Hairline so the pill still reads as a chip on White and Paper, where its
     fill is close to the ground. On Ink the line is all but invisible. */
  border: 1px solid var(--rg-line);
  border-radius: var(--rg-radius-pill);
  color: var(--rg-chip-text);
  display: inline-flex;
  font-family: var(--rg-font);
  /* About 18px text in a 48px pill at 1440, as in the FRD comp. Shown as typed
     (Mike, 2026-10-26). */
  font-size: clamp(0.875rem, 1.25vw, 1.125rem);
  font-weight: 700;
  gap: 12px;
  line-height: 1.2;
  /* Centred text, also when a long label wraps (Client Round 1). */
  justify-content: center;
  min-height: 48px;
  padding: 8px 24px 8px 8px;
  text-align: center;
  text-transform: none;
}

.rg-chip__mark {
  align-items: center;
  background-color: var(--rg-chip-mark);
  border-radius: 50%;
  color: var(--rg-chip-bg);
  display: inline-flex;
  flex: none;
  height: 32px;
  justify-content: center;
  width: 32px;
}

.rg-chip__mark svg {
  display: block;
  height: 15px;
  width: 15px;
}

.rg-chips {
  display: flex;
  flex-wrap: wrap;
  gap: var(--rg-space-2);
  list-style: none;
  margin: 0;
  padding: 0;
}
/* Pink Pivot cards - the canonical card vocabulary (plan section 4, #6).
   Rendered by rg-card-row when a card has a `variant`. It lives here, not in
   that module's CSS, because rg-partner-showcase, rg-educator-grid and the
   retiring grid modules will render the same markup (repo trap 14).

   image-fill  discipline card: heading and pill over a photo (Home v5)
   image-top   photo with an outline badge, then heading, copy and pill on the
               raised surface (Home v5 "Redefining the Future")
   tagged      Ink top with stacked outline tags, title and pill below
               (CEO v3 appearances)
   feature     Rose card with an Ink name and status (CEO v3 DSO partners, W4)

   Each card or card part that paints its own ground carries a surface class
   in the markup, so text colour is always derived, never set here. */

.rg-pp-card {
  border-radius: var(--rg-radius-card);
  display: flex;
  flex-direction: column;
  min-width: 0;
  overflow: hidden;
  position: relative;
}

/* Photo layer, shared by the three image styles. */
.rg-pp-card__bg {
  height: 100%;
  inset: 0;
  object-fit: cover;
  position: absolute;
  width: 100%;
}

.rg-pp-card__content {
  align-items: flex-start;
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  gap: var(--rg-space-3);
  padding: var(--rg-space-5);
  position: relative;
}

/* Display scale: about 28px at 1440 and 22px at 375, as measured from the
   comps. Weight follows the module's Heading style choice (see _heading.css). */
.rg-pp-card__heading {
  overflow-wrap: normal;
  word-break: normal;
  color: var(--rg-text);
  font-family: var(--rg-font);
  /* Floor is 24px: the Rose accent word only passes on Paper as large text. */
  font-size: var(--rg-h3);
  font-weight: var(--rg-heading-weight, 600);
  letter-spacing: var(--rg-track-head);
  line-height: 1.1;
  margin: 0;
}

.rg-pp-card__heading .rg-accent,
.rg-pp-card__heading .rg-highlight {
  font-weight: var(--rg-heading-accent-weight, inherit);
}

.rg-pp-card__eyebrow {
  color: var(--rg-eyebrow);
  font-family: var(--rg-font);
  font-size: 0.8125rem;
  font-weight: 700;
  letter-spacing: var(--rg-track-eyebrow);
  line-height: 1.3;
  margin: 0;
  text-transform: uppercase;
}

/* Raw rich text: colour and size are declared with tokens, never inherited
   (repo trap 13). */
.rg-pp-card__body,
.rg-pp-card__body p,
.rg-pp-card__body li {
  color: var(--rg-text);
  font-family: var(--rg-body-font);
  font-size: var(--rg-body);
  line-height: 1.5;
}

.rg-pp-card__body p {
  margin: 0 0 var(--rg-space-2);
}

.rg-pp-card__body p:last-child {
  margin-bottom: 0;
}

.rg-pp-card__content > .rg-btn {
  margin-top: auto;
}

/* ---- image-fill --------------------------------------------------------- */

.rg-pp-card--image-fill {
  /* Comp cards are about 1.15:1. */
  aspect-ratio: 23 / 20;
  justify-content: flex-end;
}

/* Gradient into Ink behind the copy so the white heading holds its contrast
   whatever the photo is. */
.rg-pp-card--image-fill::after {
  background: linear-gradient(180deg, transparent 30%, color-mix(in srgb, var(--rg-ink) 55%, transparent) 62%, color-mix(in srgb, var(--rg-ink) 88%, transparent) 100%);
  content: "";
  inset: 0;
  pointer-events: none;
  position: absolute;
}

.rg-pp-card--image-fill .rg-pp-card__content {
  flex: 0 0 auto;
  z-index: 1;
}

.rg-pp-card__heading--fill {
  font-size: var(--rg-h2);
  font-weight: 600;
  line-height: 1;
  max-width: 12ch;
}

/* ---- image-top ---------------------------------------------------------- */

.rg-pp-card--image-top {
  background-color: var(--rg-surface-raised);
  color: var(--rg-text);
}

.rg-pp-card__media {
  flex: none;
  overflow: hidden;
  position: relative;
}

.rg-pp-card--image-top .rg-pp-card__media {
  aspect-ratio: 4 / 3;
}

/* Image shape (D10). The card row picks the photo shape for its image-top
   cards; 16:9 is the default so the row fits on one screen (it was 4:3).
   Icon tiles keep their own shape. */
.rg-card-row--shape-landscape .rg-pp-card--image-top:not(.rg-pp-card--icon) .rg-pp-card__media {
  aspect-ratio: 16 / 9;
}

.rg-card-row--shape-classic .rg-pp-card--image-top:not(.rg-pp-card--icon) .rg-pp-card__media {
  aspect-ratio: 4 / 3;
}

.rg-card-row--shape-square .rg-pp-card--image-top:not(.rg-pp-card--icon) .rg-pp-card__media {
  aspect-ratio: 1;
}

/* The comps sit the subject on an Ink ground that fades to Coral Sea. */
.rg-pp-card__media--gradient {
  background: linear-gradient(180deg, var(--rg-ink) 45%, var(--rg-coral-sea) 135%);
}

/* The photo overscans the gradient box by a pixel at the bottom. The box height
   comes from aspect-ratio and can land on a half pixel, which let a hairline
   of the Coral Sea end of the gradient show between the photo and the Paper
   body. The card clips the overscan. */
.rg-pp-card__media--gradient .rg-pp-card__bg {
  height: calc(100% + 1px);
}

.rg-pp-card__badge {
  max-width: calc(100% - (2 * var(--rg-space-2)));
  position: absolute;
  right: var(--rg-space-2);
  top: var(--rg-space-3);
  z-index: 1;
}

/* Optional play control over the photo. The whole photo is the link. */
.rg-pp-card__video {
  align-items: center;
  display: flex;
  inset: 0;
  justify-content: center;
  position: absolute;
}

.rg-pp-card__video .rg-pp-card__bg {
  opacity: 0.8;
}

.rg-pp-card__video:focus-visible {
  outline: 3px solid var(--rg-focus);
  outline-offset: -6px;
}

/* Ring footer: heading inside a ring that the card's bottom-left corner crops,
   copy beside it (FRD "Trusted By Students Globally"). */
.rg-pp-card__ringfoot {
  align-items: center;
  display: grid;
  flex: 1 1 auto;
  gap: var(--rg-space-4);
  grid-template-columns: minmax(0, 0.9fr) minmax(0, 1fr);
  overflow: hidden;
  position: relative;
}

.rg-pp-card__ringfoot-mark {
  align-self: stretch;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-height: clamp(200px, 17vw, 300px);
  padding: var(--rg-space-4) var(--rg-space-3) var(--rg-space-4) var(--rg-space-5);
  position: relative;
}

.rg-pp-card__ring {
  --rg-ring-size: clamp(280px, 26vw, 420px);
  --rg-ring-stroke: clamp(12px, 1.3vw, 22px);
  left: -14%;
  position: absolute;
  top: 8%;
}

.rg-pp-card__ring-heading {
  /* Never break inside a word ("Stude/nts"): the heading sizes to fit. */
  overflow-wrap: normal;
  word-break: normal;
  color: var(--rg-text);
  font-family: var(--rg-font);
  font-size: var(--rg-h2);
  font-weight: 700;
  letter-spacing: var(--rg-track-head);
  line-height: 1;
  margin: 0;
  position: relative;
}

/* The accent word takes its own line, as drawn ("Students" / "Globally"),
   which also keeps the heading narrow enough to sit inside the ring. */
.rg-pp-card__ring-heading .rg-accent {
  display: block;
}

.rg-pp-card__ring-eyebrow {
  /* Inset a little, so the line clears the arc beside it. */
  padding-left: 0.5em;
  display: block;
  font-size: 0.45em;
  letter-spacing: -0.01em;
  margin-bottom: 0.4em;
}

.rg-pp-card__ringfoot-copy {
  align-items: flex-start;
  display: flex;
  flex-direction: column;
  gap: var(--rg-space-3);
  padding: var(--rg-space-4) var(--rg-space-5) var(--rg-space-4) 0;
}

.rg-pp-card__body--lead,
.rg-pp-card__body--lead p {
  font-family: var(--rg-font);
  font-size: var(--rg-body);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.25;
}

/* The side-by-side layout needs about 520px of CARD. Narrower than that -
   a half-width card on a tablet as much as a full-width one on a phone - the
   ring and heading sit on top in a smaller ring, clipped to their own block,
   and the copy takes the full width underneath. The card is the size
   container, so this follows the card, not the viewport. */
.rg-pp-card--ring-footer {
  container-type: inline-size;
}

@container (max-width: 519px) {
  .rg-pp-card__ringfoot {
    gap: 0;
    grid-template-columns: minmax(0, 1fr);
  }

  .rg-pp-card__ringfoot-mark {
    min-height: 0;
    overflow: hidden;
    padding: var(--rg-space-5) var(--rg-space-3) var(--rg-space-4) var(--rg-space-4);
  }

  .rg-pp-card__ring {
    --rg-ring-size: clamp(200px, 74cqw, 300px);
    --rg-ring-stroke: 11px;
    left: -8%;
    top: 4%;
  }

  .rg-pp-card__ring-heading {
    font-size: clamp(var(--rg-h5), 9.5cqw, var(--rg-h2));
  }

  .rg-pp-card__ringfoot-copy {
    padding: var(--rg-space-2) var(--rg-space-3) var(--rg-space-4) var(--rg-space-4);
  }
}

/* ---- tagged ------------------------------------------------------------- */

.rg-pp-card--tagged {
  background-color: var(--rg-surface-raised);
  color: var(--rg-text);
}

.rg-pp-card--tagged .rg-pp-card__media {
  flex: 1 1 auto;
  min-height: clamp(200px, 18vw, 340px);
  padding: var(--rg-space-3);
}

/* Tags sit over an optional photo, so that photo is dimmed toward Ink. */
.rg-pp-card--tagged .rg-pp-card__bg {
  opacity: 0.45;
}

.rg-pp-card__tags {
  position: relative;
}

.rg-pp-card__foot {
  align-items: center;
  display: flex;
  flex-wrap: wrap;
  gap: var(--rg-space-2) var(--rg-space-3);
  justify-content: space-between;
  padding: var(--rg-space-3);
}

.rg-pp-card__title {
  color: var(--rg-text);
  flex: 1 1 12ch;
  font-family: var(--rg-font);
  font-size: var(--rg-h4);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.2;
  margin: 0;
}

/* ---- feature ------------------------------------------------------------ */

.rg-pp-card--feature {
  --rg-text: var(--rg-feature-card-text);
  --rg-focus: var(--rg-feature-card-text);
  background-color: var(--rg-feature-card-bg);
  color: var(--rg-feature-card-text);
  gap: var(--rg-space-1);
  justify-content: center;
  min-height: 150px;
  padding: var(--rg-space-4) var(--rg-space-5);
}

/* About 26px at 1440, as in CEO v3. One size wherever the card is used, and
   it holds whether the name is a heading (card row) or a paragraph (partner
   showcase). */
.rg-pp-card__name {
  color: var(--rg-feature-card-text);
  font-family: var(--rg-font);
  font-size: var(--rg-h4);
  font-weight: 600;
  letter-spacing: -0.02em;
  line-height: 1.15;
  margin: 0;
}

.rg-pp-card__status {
  align-items: center;
  color: var(--rg-feature-card-text);
  display: flex;
  font-family: var(--rg-font);
  font-size: 0.875rem;
  font-weight: 700;
  gap: var(--rg-space-1);
  letter-spacing: 0.04em;
  line-height: 1.2;
  margin: 0;
  text-transform: uppercase;
}

.rg-pp-card__status-dot {
  background-color: var(--rg-whitsunday);
  border-radius: 50%;
  flex: none;
  height: 8px;
  width: 8px;
}

/* ---- in a card row ------------------------------------------------------ */

/* The classic promo card carries a 610px desktop floor. These cards size to
   their content. */
.rg-card-row__card.rg-pp-card {
  min-height: 0;
}

.rg-card-row__card.rg-pp-card--feature {
  min-height: 150px;
}

/* Carousel: three cards to a view on desktop, two on tablets, one and a peek
   on phones. */
.rg-card-row__grid--carousel > .rg-pp-card {
  align-self: stretch;
  /* The card cell carries height: 100%. In a flex row that percentage cannot
     resolve, and a non-auto height switches stretch off, so the cards ended
     at their own content heights. */
  height: auto;
  flex: 0 0 calc((100% - (2 * var(--rg-cr-gap, var(--rg-space-6)))) / 3);
}

@media (max-width: 1024.98px) {
  .rg-card-row__grid--carousel > .rg-pp-card {
    flex-basis: calc((100% - var(--rg-cr-gap, var(--rg-space-6))) / 2);
  }
}

@media (max-width: 767.98px) {
  .rg-card-row__grid--carousel > .rg-pp-card {
    flex-basis: 86%;
  }

  .rg-pp-card__content {
    padding: var(--rg-space-3);
  }


  .rg-pp-card__foot .rg-btn {
    width: 100%;
  }
}

/* Tablet: Pink Pivot card rows go to two columns, and an odd last card takes
   the full row instead of leaving a hole beside it. */
@media (min-width: 600px) and (max-width: 1024.98px) {
  .rg-card-row__grid:not(.rg-card-row__grid--carousel):has(> .rg-pp-card) {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
  }

  /* !important: the tablet reflow in _card-row.css resets every card with
     grid-area: auto !important, which cancelled this span and left the wide
     aspect-ratio below on a one-column card (half height; Home Walk 1). */
  .rg-card-row__grid:not(.rg-card-row__grid--carousel) > .rg-pp-card:last-child:nth-child(odd) {
    grid-column: 1 / -1 !important;
  }

  .rg-card-row__grid:not(.rg-card-row__grid--carousel) > .rg-pp-card--image-fill:last-child:nth-child(odd) {
    aspect-ratio: 23 / 10;
  }
}


/* Tablet landscape (1025-1199): a four- or five-across row goes two across,
   as below 1024, so the cards are not squeezed (Client Round 1, Hands-On
   Master Series courses). Two- and three-across rows keep their columns. */
@media (min-width: 1025px) and (max-width: 1199px) {
  .rg-card-row__grid:is(.rg-card-row__grid--cols-4, .rg-card-row__grid--cols-5):not(.rg-card-row__grid--carousel):has(> .rg-pp-card) {
    grid-template-columns: repeat(2, minmax(0, 1fr)) !important;
    grid-template-rows: auto !important;
    grid-template-areas: none !important;
  }

  .rg-card-row__grid:is(.rg-card-row__grid--cols-4, .rg-card-row__grid--cols-5):not(.rg-card-row__grid--carousel) > .rg-pp-card {
    grid-area: auto !important;
  }

  .rg-card-row__grid:is(.rg-card-row__grid--cols-4, .rg-card-row__grid--cols-5):not(.rg-card-row__grid--carousel) > .rg-pp-card:last-child:nth-child(odd) {
    grid-column: 1 / -1 !important;
  }
}


/* ---- image-top with an icon instead of an image -------------------------
   Feature and benefit lists: an Ink rounded tile with a Whitsunday glyph sits
   where the image would. The tile is Ink on every surface, so the glyph pair
   (Whitsunday on Ink) never changes. */

.rg-pp-card__icon-tile {
  align-items: center;
  background-color: var(--rg-ink);
  border-radius: var(--rg-radius-sm);
  color: var(--rg-whitsunday);
  align-self: flex-start;
  display: inline-flex;
  flex: 0 0 auto;
  height: var(--rg-space-8);
  justify-content: center;
  margin: var(--rg-space-5) var(--rg-space-5) 0;
  width: var(--rg-space-8);
}

.rg-pp-card__icon-tile svg {
  fill: currentColor;
  height: var(--rg-space-4);
  width: var(--rg-space-4);
}

/* Below 768 the card copy is inset --rg-space-3, so the tile is too, at every
   phone and small-tablet width. Declared after the base rule above: the
   earlier copy inside the 767 query lost to it on source order (Visual Review
   Nov 5: 40px tile against 24px copy). */
@media (max-width: 767.98px) {
  .rg-pp-card__icon-tile {
    margin: var(--rg-space-3) var(--rg-space-3) 0;
  }
}
/* Quote card - one shape for testimonials and advisory quotes. Shared by
   rg-testimonial-carousel and rg-partner-showcase (repo trap 14). Always on a
   surface class in the markup (Ink in the comps), so its colours derive:
   Rose title (large text), white quote, Whitsunday meta line on Ink. */

.rg-quote-card {
  border-radius: var(--rg-radius-card);
  display: flex;
  flex-direction: column;
  gap: var(--rg-space-2);
  min-width: 0;
  overflow: hidden;
  padding: var(--rg-space-5);
}

.rg-quote-card__title {
  color: var(--rg-accent-large);
  font-family: var(--rg-font);
  font-size: var(--rg-h3);
  font-weight: 700;
  letter-spacing: var(--rg-track-head);
  line-height: 1.1;
  margin: 0;
  overflow-wrap: normal;
  word-break: normal;
}

.rg-quote-card__title--plain {
  color: var(--rg-text);
}

.rg-quote-card__role {
  color: var(--rg-accent-text);
  font-family: var(--rg-font);
  font-size: var(--rg-body);
  font-weight: 700;
  line-height: 1.25;
  margin: 0;
}

/* Raw rich text: colour and size declared with tokens (repo trap 13). The
   quote is body size and regular weight everywhere (walk 9 ruling, D6): small
   bold white text on Ink was hard to read. The card title stays bold. */
.rg-quote-card__quote,
.rg-quote-card__quote p {
  color: var(--rg-text);
  font-family: var(--rg-body-font);
  font-size: var(--rg-body);
  font-weight: 400;
  line-height: 1.4;
  margin: 0;
}

.rg-quote-card__quote {
  flex: 1 1 auto;
  margin-block: var(--rg-space-1);
}

/* Advisory style: a Rose rule beside the quote. */
.rg-quote-card__quote--rule {
  border-left: 6px solid var(--rg-accent);
  padding-left: var(--rg-space-3);
}

.rg-quote-card__stars {
  color: var(--rg-accent-large);
  font-size: 1.25rem;
  letter-spacing: 0.1em;
  line-height: 1;
  margin: 0;
}

/* Optional photo beside the attribution (D12). A fixed square box, so the
   circle never turns oval (A4). */
.rg-quote-card__by--photo {
  align-items: center;
  column-gap: var(--rg-space-2);
  display: grid;
  grid-template-columns: 56px minmax(0, 1fr);
}

.rg-quote-card__by--photo > * {
  grid-column: 2;
}

.rg-quote-card__by--photo > .rg-quote-card__photo {
  grid-column: 1;
  grid-row: 1 / span 2;
}

.rg-quote-card__photo {
  aspect-ratio: 1;
  border: 2px solid var(--rg-text);
  border-radius: 50%;
  display: block;
  height: auto;
  object-fit: cover;
  width: 56px;
}

.rg-quote-card__name {
  color: var(--rg-text);
  display: block;
  font-family: var(--rg-font);
  font-size: var(--rg-body);
  font-weight: 700;
  line-height: 1.2;
  text-transform: none;
}

.rg-quote-card__name--highlight {
  color: var(--rg-highlight);
  text-transform: none;
}

.rg-quote-card__meta {
  color: var(--rg-highlight);
  display: block;
  font-family: var(--rg-font);
  font-size: var(--rg-small);
  font-weight: 700;
  line-height: 1.3;
  text-transform: uppercase;
}

@media (max-width: 767.98px) {
  .rg-quote-card {
    padding: var(--rg-space-4) var(--rg-space-3);
  }
}
/* Layout & Style shared group (Stage 1)
   One consuming block for the per-instance custom properties emitted by
   partials/rg-layout-style.html. Every selector is a modifier class that only
   appears when its Style-tab control is set, so modules with no override are
   untouched. Adding a control later is an edit here + in the macro, not a
   per-module style rule. */

/* Spacing - per side, so an unset side keeps the module's own value */
.rg-ls--pt { padding-top: var(--rg-ls-pt) !important; }
.rg-ls--pr { padding-right: var(--rg-ls-pr) !important; }
.rg-ls--pb { padding-bottom: var(--rg-ls-pb) !important; }
.rg-ls--pl { padding-left: var(--rg-ls-pl) !important; }
.rg-ls--mt { margin-top: var(--rg-ls-mt) !important; }
.rg-ls--mb { margin-bottom: var(--rg-ls-mb) !important; }

@media (max-width: 767.98px) {
  .rg-ls--pt-m { padding-top: var(--rg-ls-pt-m) !important; }
  .rg-ls--pb-m { padding-bottom: var(--rg-ls-pb-m) !important; }
  /* Mobile margin overrides. The group shipped with mobile PADDING but not
     mobile MARGIN, so a desktop margin choice applied at every width with no
     way to change it on a phone - which is how two stacked promo cards on
     About Us ended up butted edge to edge (margin top set to None for the
     desktop layout) with nothing in the editor able to separate them. */
  .rg-ls--mt-m { margin-top: var(--rg-ls-mt-m) !important; }
  .rg-ls--mb-m { margin-bottom: var(--rg-ls-mb-m) !important; }
}

/* Background presets (white/dark/gradient/gradient-deep/image + overlay) now live
   in css/components/_backgrounds.css, shared with rg-card-row. This group emits
   rg-bg--<preset> classes via the macro; only spacing/alignment/width remain here. */

/* Text alignment */
.rg-ls--ta-left { text-align: left !important; }
.rg-ls--ta-center { text-align: center !important; }
.rg-ls--ta-right { text-align: right !important; }

/* Content alignment (flex/grid wrappers) */
.rg-ls--ca-start { align-items: flex-start !important; }
.rg-ls--ca-center { align-items: center !important; }
.rg-ls--ca-end { align-items: flex-end !important; }

/* Width */
.rg-ls--w-contained {
  max-width: var(--rg-ls-maxw, var(--rg-container, 1920px)) !important;
  margin-inline: auto !important;
}
.rg-ls--w-full { max-width: none !important; width: 100% !important; }
/* RG FAQ - shared component (promoted from rg-faq-accordion.module in Stage 3).
   Consumed by BOTH the standalone rg-faq-accordion module AND rg-card-row's
   per-card FAQ type. Lives here (loaded globally via main.css) rather than in a
   module's css_assets, because HubSpot loads module CSS conditionally - a Card
   Row FAQ card on a page without the standalone module would otherwise render
   unstyled. Tokens only. */

.rg-faq {
  color: var(--rg-text);
  font-family: var(--rg-font);
  margin: var(--rg-space-6) auto 0;
  max-width: var(--rg-container);
  padding: var(--rg-space-8);
  width: calc(100% - (2 * var(--rg-gutter)));
}

.rg-faq--bg-dark {
  background-color: var(--rg-navy);
}

/* Flush: fill the column (no self-inset) and match the paired card's height.
   Keep the standard top gap (only the side/bottom insets are removed) so the
   FAQ+card row doesn't butt flush against the section above it (A-S10.1); the
   paired promo card keeps the same top margin, so equal height is preserved. */
.rg-faq--flush {
  height: 100%;
  margin: var(--rg-space-6) 0 0;
  max-width: none;
  width: 100%;
}

.rg-faq--bg-light {
  background-color: var(--rg-text);
  color: var(--rg-text-on-light);
}

/* Optional side image */
.rg-faq--has-image {
  align-items: stretch;
  display: flex;
  gap: var(--rg-space-6);
}

.rg-faq--has-image .rg-faq__media {
  flex: 1 1 40%;
}

.rg-faq--has-image .rg-faq__body {
  flex: 1 1 60%;
}

.rg-faq__media img {
  border-radius: var(--rg-radius-md);
  height: 100%;
  object-fit: cover;
  width: 100%;
}

/* Head */
.rg-faq__head {
  align-items: center;
  display: flex;
  gap: var(--rg-space-3);
  margin-bottom: var(--rg-space-5);
}

.rg-faq__badge {
  align-items: center;
  border: var(--rg-border);
  border-radius: var(--rg-radius-sm);
  color: var(--rg-accent);
  display: flex;
  flex-shrink: 0;
  font-size: var(--rg-h3);
  font-weight: 700;
  height: 64px;
  justify-content: center;
  width: 64px;
}

.rg-faq__heading {
  font-size: var(--rg-h2-alt);
  font-weight: 700;
  line-height: var(--rg-lh-tight);
  margin: 0;
}

/* List */
.rg-faq__list {
  border-top: var(--rg-border-soft);
}

.rg-faq__item {
  border-bottom: var(--rg-border-soft);
}

.rg-faq__q {
  align-items: center;
  background: none;
  border: 0;
  /* Declared: a bare <button> otherwise takes the theme's button radius. */
  border-radius: 0;
  color: inherit;
  cursor: pointer;
  display: flex;
  font-family: inherit;
  gap: var(--rg-space-3);
  justify-content: space-between;
  padding: var(--rg-space-3) 0;
  text-align: left;
  width: 100%;
}

.rg-faq__q-text {
  font-size: var(--rg-body);
  font-weight: 700;
  line-height: var(--rg-lh-tight);
}

/* Hover/focus recolours the question TEXT only - never a background fill (pin
   background:none so the theme's button:hover can't paint a slab).

   A tap left a box around the question (B4). The theme's button:hover and
   button:focus rules (0,1,1, portal only) give every bare button the theme's
   hover border and radius, and iOS adds its own tap highlight. So every state
   pins no border, radius, shadow or outline, and the tap highlight is off.
   Keyboard users still get the :focus-visible ring below, at 3:1 or better. */
.rg-faq__q {
  -webkit-tap-highlight-color: transparent;
}

.rg-faq__q:hover,
.rg-faq__q:focus,
.rg-faq__q:active,
.rg-faq__q:focus-visible {
  background: none;
  border: 0;
  border-radius: 0;
  box-shadow: none;
}

.rg-faq__q:focus:not(:focus-visible) {
  outline: none;
}

.rg-faq__q:hover .rg-faq__q-text,
.rg-faq__q:focus-visible .rg-faq__q-text {
  color: var(--rg-accent);
}

.rg-faq__q:focus-visible {
  outline: 2px solid var(--rg-accent);
  outline-offset: 2px;
}

.rg-faq__chevron {
  flex-shrink: 0;
  height: 22px;
  transition: transform 0.25s ease;
  width: 22px;
}

.rg-faq__chevron path {
  stroke: currentColor;
}

/* Open state - question goes teal, chevron flips */
.rg-faq__item--open .rg-faq__q-text {
  color: var(--rg-accent);
}

.rg-faq__item--open .rg-faq__chevron {
  color: var(--rg-accent);
  transform: rotate(180deg);
}

/* Answer */
.rg-faq__a-inner {
  font-size: var(--rg-body);
  line-height: var(--rg-lh-body);
  padding: 0 0 var(--rg-space-3);
}

.rg-faq__a-inner p {
  margin: 0;
}

/* Collapse behaviour only once JS is active */
.rg-faq--js .rg-faq__a {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
}

@media (max-width: 767.98px) {
  .rg-faq {
    padding: var(--rg-space-6) var(--rg-space-4);
  }

  .rg-faq--has-image {
    flex-direction: column;
  }
}


/* PINK PIVOT (.rg-faq--pp): Ink panel, ghost question mark, hairline rows.
   Here rather than in the module because the FAQ markup is shared with the
   card-row FAQ card (repo trap 14). */
.rg-faq.rg-faq--pp {
  border: 0;
  border-radius: var(--rg-radius-card);
  overflow: hidden;
  position: relative;
}

/* The small badge becomes the large ghost mark behind the list. */
.rg-faq--pp .rg-faq__badge {
  background: none;
  border: 0;
  box-shadow: none;
  color: color-mix(in srgb, var(--rg-coral-sea) 55%, transparent);
  font-family: var(--rg-font);
  font-size: clamp(16rem, 34vw, 34rem);
  font-weight: 700;
  height: auto;
  line-height: 0.8;
  pointer-events: none;
  position: absolute;
  right: 4%;
  top: 0;
  width: auto;
}

.rg-faq--pp .rg-faq__body {
  position: relative;
}

.rg-faq--pp .rg-faq__heading {
  color: var(--rg-text);
  font-size: var(--rg-h2);
  font-weight: 600;
  letter-spacing: var(--rg-track-head);
  position: relative;
}

.rg-faq--pp .rg-faq__item {
  background: none;
  border: 0;
  border-radius: 0;
  border-top: var(--rg-border);
  box-shadow: none;
  position: relative;
}

.rg-faq--pp .rg-faq__q {
  color: var(--rg-text);
  font-family: var(--rg-font);
  font-weight: 700;
  text-transform: none;
}

.rg-faq--pp .rg-faq__q[aria-expanded="true"] {
  color: var(--rg-accent-text);
}

.rg-faq--pp .rg-faq__chevron {
  stroke: var(--rg-accent);
}

.rg-faq--pp .rg-faq__q:focus-visible {
  outline: 3px solid var(--rg-focus);
  outline-offset: -3px;
}

.rg-faq--pp .rg-faq__a-inner,
.rg-faq--pp .rg-faq__a-inner p {
  color: var(--rg-text);
  font-family: var(--rg-body-font);
}


/* The heading that wraps each question button exists for the outline only.
   It adds no box, size or weight of its own: the button carries the styling. */
.rg-faq__q-heading {
  color: inherit;
  font: inherit;
  letter-spacing: inherit;
  margin: 0;
  text-transform: none;
}
/* RG Promo card - shared card component. Global (loaded on every page via
   main.css) because the .rg-promo markup is used by TWO modules: the standalone
   rg-promo-card AND every standard card inside rg-card-row, which renders
   .rg-promo classes deliberately for pixel parity with the module it replaces.

   Keeping these styles module-scoped broke rg-card-row exactly the way it broke
   the Implantology hero before _stat-bar.css was promoted: HubSpot only loads a
   module's CSS when that module is on the page, and rg-promo-card is deprecated
   and on none of the new templates. So every card-row card rendered with zero
   content padding - eyebrows sat 1px from a 30px-radius overflow:hidden corner
   and lost their first glyph ("EDUCATION" -> "DUCATION"), and buttons hung off
   the bottom-left corner.

   Same promotion pattern as _stat-bar.css, _faq.css and _backgrounds.css.
   Do NOT re-add module-scoped .rg-promo styles - it would double-declare and
   drift from the shared component. */

/* RG Promo Card - ~920-968 x ~610 shell */

.rg-promo {
  color: var(--rg-text);
  display: flex;
  margin-top: var(--rg-space-6);
  flex-direction: column;
  font-family: var(--rg-font);
  justify-content: center;
  min-height: 610px;
  position: relative;
}

.rg-promo__bg {
  height: 100%;
  inset: 0;
  object-fit: cover;
  position: absolute;
  width: 100%;
}

/* Optional logo in the top-right corner (Investors "Ultimate Destination" RG globe). */
.rg-promo__corner-logo {
  height: 88px;
  position: absolute;
  right: var(--rg-space-5);
  top: var(--rg-space-5);
  width: 88px;
  z-index: 2;
}

/* Content pinned to the bottom of the card (image-background hero cards). */
.rg-promo--bottom {
  justify-content: flex-end;
}

/* Flush: fill the column (no self-inset) and match the paired card's height.
   Keep the standard top gap (matches .rg-faq--flush) so the row doesn't butt
   flush against the section above; both columns share the top margin, so equal
   height holds (A-S10.1). */
.rg-promo--flush {
  height: 100%;
  margin: var(--rg-space-6) 0 0;
  max-width: none;
  width: 100%;
}

.rg-promo__content {
  align-items: center;
  display: flex;
  flex-direction: column;
  gap: var(--rg-space-3);
  padding: var(--rg-space-6) var(--rg-space-8);
  position: relative;
  text-align: center;
  z-index: 1;
}

.rg-promo--left .rg-promo__content {
  align-items: flex-start;
  text-align: left;
}

/* Constrain the copy column so text clears a subject in the background
   image (young dentist model sits on the right). */
.rg-promo--copy-half .rg-promo__content {
  max-width: 39rem;
}

.rg-promo--copy-narrow .rg-promo__content {
  max-width: 32rem;
}

.rg-promo--center.rg-promo--copy-half .rg-promo__content,
.rg-promo--center.rg-promo--copy-narrow .rg-promo__content {
  align-self: center;
}

/* Centered promo cards have no side subject to clear (content sits mid-card), so
   the narrow copy caps read "smushed" (walk feedback 2026-07-29). Widen the copy
   panel for the centered variants only; the left-over-image caps above are
   unchanged so text still clears the background model. */
.rg-promo--center.rg-promo--copy-half .rg-promo__content {
  max-width: 46rem;
}

.rg-promo--center.rg-promo--copy-narrow .rg-promo__content {
  max-width: 40rem;
}

/* Spread: content fills the card height and distributes icon / heading /
   button top-to-bottom (the graduates card, 258:10438). */
.rg-promo--spread {
  justify-content: stretch;
}

.rg-promo--spread .rg-promo__content {
  flex: 1;
  justify-content: space-between;
}

/* Promo cards run the gradient vertically - navy at top, teal pooling toward
   the bottom-left (Figma). The shared 135deg diagonal pushed teal into the
   bottom-right corner, which reads wrong on these wide cards. Scoped here so
   the narrower video cards keep their approved diagonal. */
.rg-promo.rg-gradient-card {
  background: linear-gradient(200deg, var(--rg-navy) 35%, var(--rg-accent) 115%);
}

.rg-promo.rg-gradient-card--deep {
  background: linear-gradient(200deg, var(--rg-black) 0%, var(--rg-navy) 32%, var(--rg-accent) 115%);
}

/* White card (closing CTA on the fellowship pages) - navy text, teal accent */
.rg-promo--bg-white {
  background-color: var(--rg-text);
  color: var(--rg-text-on-light);
}

/* Solid navy card - the Restorative video cards (revolutionary teaching /
   trusted globally): grayscale video on top, navy fill below. */
.rg-promo--bg-dark {
  background-color: var(--rg-navy);
}

.rg-promo__figure {
  border-radius: var(--rg-radius-sm);
  max-width: min(488px, 100%);
}

.rg-promo__icon {
  height: 5.6875rem;
  width: auto;
}

.rg-promo__eyebrow {
  font-family: var(--rg-font);
  font-size: var(--rg-body);
  font-weight: 700;
  line-height: var(--rg-lh-tight);
  margin: 0;
  text-transform: uppercase;
}

/* Oversized teal hero number (young dentist "2025", 258:2544 - 128px). Snugs
   up under the eyebrow, overriding the content gap. */
.rg-promo__hero-number {
  color: var(--rg-accent);
  font-size: clamp(3.5rem, 6.5vw, 8rem);
  font-weight: 700;
  line-height: var(--rg-lh-tight);
  margin: calc(var(--rg-space-2) * -1) 0 0;
  text-transform: uppercase;
}

.rg-promo__heading {
  font-weight: 700;
  line-height: var(--rg-lh-tight);
  margin: 0;
  text-transform: none;
}

.rg-promo__heading p {
  font-size: inherit;
  font-weight: inherit;
  line-height: inherit;
  margin: 0;
}

.rg-promo__heading--h1 {
  font-size: var(--rg-h1);
}

.rg-promo__heading--h2 {
  font-size: var(--rg-h2);
}

.rg-promo__heading--h2-alt {
  font-size: var(--rg-h2-alt);
}

.rg-promo__body {
  font-size: var(--rg-body);
  line-height: var(--rg-lh-body);
  max-width: 60ch;
}

.rg-promo__body p {
  margin: 0;
}

/* Video-on-top card (Restorative). The card becomes content-height and
   top-aligned so the landscape video isn't stretched into the 610px shell. */
.rg-promo--has-video,
.rg-promo--image-top {
  justify-content: flex-start;
  min-height: 0;
}

/* Static image flush to the top + sides of the card (Redefining / Simulation
   Kits two-card row). The card wrapper clips the top corners. */
.rg-promo--image-top .rg-promo__media--static {
  position: relative;
  width: 100%;
  z-index: 1;
}

.rg-promo__topimage {
  aspect-ratio: 16 / 11;
  display: block;
  object-fit: cover;
  width: 100%;
}

/* Full-width at the top with NO crop. The 16:11 band exists so a row of cards
   keeps its images the same height and the copy below them starts on a shared
   line - dropping it is a deliberate per-card choice, not a default, because a
   row of mixed-ratio images will not line up. */
.rg-promo--image-top-natural .rg-promo__topimage {
  aspect-ratio: auto;
  height: auto;
  object-fit: fill;
}

.rg-promo__media {
  position: relative;
  width: 100%;
  z-index: 1;
}

/* Landscape thumbnail; navy fill shows through until a real thumbnail lands.
   No radius here - the rg-card wrapper clips the top corners. */
.rg-promo__video {
  aspect-ratio: 16 / 10;
  background-color: var(--rg-navy);
  display: block;
  overflow: hidden;
  position: relative;
  width: 100%;
}

.rg-promo__video img {
  height: 100%;
  left: 0;
  object-fit: cover;
  position: absolute;
  top: 0;
  width: 100%;
}

/* rounded-square play button with a teal glow (shared shape with split-feature) */
.rg-promo__play {
  align-items: center;
  background-color: var(--rg-surface-play);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  border: var(--rg-border);
  border-radius: var(--rg-radius-md);
  box-shadow: var(--rg-glow-sm);
  color: var(--rg-text);
  display: flex;
  height: 88px;
  justify-content: center;
  left: 50%;
  position: absolute;
  top: 50%;
  transform: translate(-50%, -50%);
  transition: box-shadow 0.2s ease;
  width: 88px;
}

.rg-promo__video:hover .rg-promo__play,
.rg-promo__video:focus-visible .rg-promo__play {
  box-shadow: var(--rg-glow-md);
}

.rg-promo__play svg {
  height: 32px;
  margin-left: 4px;
  width: 32px;
}

@media (max-width: 767.98px) {
  .rg-promo {
    min-height: 420px;
  }

  /* --------------------------------------------------------------------
     Mobile treatment for EVERY .rg-promo, standalone or inside a card row.

     This started life scoped to .rg-card-row__card and therefore missed the
     standalone rg-promo-card module entirely - which is still placed directly
     on About Us ("Redefining Dental Learning", "Simulation Kits", the two
     Educators/Graduates cards), so those kept the desktop left rag and had no
     wash at all while the card-row cards next to them were centred. The
     vocabulary is shared, so the rule belongs on the vocabulary.

     Two classes (and declared last in the file) so it beats the --left /
     --spread content modifiers without !important.
     -------------------------------------------------------------------- */
  .rg-promo {
    align-items: center;
    justify-content: center;
  }

  .rg-promo .rg-promo__content {
    align-items: center;
    justify-content: center;
    padding: var(--rg-space-4);
    text-align: center;
  }

  .rg-promo .rg-promo__ctas,
  .rg-promo .rg-card-row__ctas {
    justify-content: center;
  }

  /* Navy wash for legibility once a background condenses into a ~400px column.
     Emitted as a class by BOTH promo-rendering modules (rg-card-row and
     rg-promo-card) for every background except the light panel - dark-on-light
     copy is wrecked by a navy overlay - and except card-row's transparent
     "None", which has no card surface to wash.

     Paints above .rg-promo__bg (earlier in tree order, z-index auto) and below
     .rg-promo__content (z-index 1); radius inherited so it cannot square off
     the card's 30px corners. One knob: --rg-cr-bg-wash. */
  .rg-promo--wash::after {
    background: var(--rg-navy);
    border-radius: inherit;
    content: "";
    inset: 0;
    opacity: var(--rg-cr-bg-wash, 0.6);
    pointer-events: none;
    position: absolute;
  }
}

/* ── Checklist chips ───────────────────────────────────────────────────────
   Ticked pills inside a promo card (the membership "choose one discipline"
   card). Two columns so six items read as a block rather than a long list;
   one column on a phone where two would wrap mid-label. Lives here rather
   than in rg-card-row's module.css because .rg-promo is a shared vocabulary -
   rg-card-row and rg-promo-card both render it. */
.rg-promo__checklist {
  display: grid;
  gap: var(--rg-space-2);
  grid-template-columns: repeat(2, minmax(0, 1fr));
  list-style: none;
  margin: var(--rg-space-3) 0 0;
  padding: 0;
  width: 100%;
}

.rg-promo__check-item {
  align-items: center;
  background-color: var(--rg-surface-chip);
  border: var(--rg-border-soft);
  border-radius: var(--rg-radius-sm);
  display: flex;
  gap: var(--rg-space-2);
  padding: var(--rg-space-2) var(--rg-space-3);
}

.rg-promo__check-mark {
  align-items: center;
  display: inline-flex;
  flex-shrink: 0;
  height: 18px;
  justify-content: center;
  width: 18px;
}

.rg-promo__check-mark svg { height: 18px; width: 18px; }
.rg-promo__check-mark circle { fill: var(--rg-accent); }
.rg-promo__check-mark polyline {
  fill: none;
  stroke: var(--rg-text);
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-width: 3;
}

.rg-promo__check-text {
  color: var(--rg-text);
  font-size: var(--rg-small);
  font-weight: 700;
  line-height: var(--rg-lh-tight);
}

@media (max-width: 767.98px) {
  .rg-promo__checklist { grid-template-columns: 1fr; }
}
/* RG Article Card - shared blog card component. Global (loaded on every page
   via main.css) because the .rg-article-card markup is rendered by TWO things:
   the rg-blog-row module AND the blog listing template (blog-index.html).

   Until now the entire block was duplicated byte-for-byte in
   css/templates/blog.css and modules/rg-blog-row.module/module.css. That kept
   both surfaces rendering, but it meant every change had to be made twice and
   the two copies were one edit away from drifting. Same promotion pattern as
   _stat-bar.css, _faq.css, _backgrounds.css, _promo-card.css and _card-row.css.
   Do NOT re-add module- or template-scoped .rg-article-card styles.

   -------------------------------------------------------------------------
   Type hierarchy (2026-08-21 pass)

   The card's three text elements were sized in the wrong order. Measured on
   /latest-news at 1600px, before:

     category   20px / 700 / uppercase / teal chip   <- loudest
     date       20px / 400                           <- equal to the category
     title      18.4px / 700 / line-height 1.0       <- smallest element

   The headline was the smallest thing on the card, and its line-height came
   from --rg-lh-tight (1.0). Set solid is right for a 55px display headline and
   wrong for an 18px title that wraps to three lines - the descenders of one
   line touched the caps of the next.

   Now, using the scale's own intent: --rg-h4 is documented as "band headings,
   video card titles", --rg-btn as "every CTA, chip, form field (uppercase)",
   --rg-nav as the 12px uppercase label. Title dominates, chip supports, date
   is quiet metadata.
   ------------------------------------------------------------------------- */

.rg-article-card {
  background-color: var(--rg-navy-deep);
  box-shadow: var(--rg-shadow-card);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Explicit properties, not `all` - the card was inheriting a blanket
     transition, which animates layout properties too. */
  transition: border-color 0.25s ease, box-shadow 0.25s ease, transform 0.25s ease;
}

/* Restraint at rest, accent on hover. .rg-card paints a full-strength teal
   hairline on all four sides, so in a three-up row every card asked for
   attention equally and none of them got it. The soft border (accent at 18%)
   holds the card shape; the full accent is what the hovered card earns.
   Two classes so it beats .rg-card whatever order the sheets land in. */
.rg-article-card.rg-card {
  border: var(--rg-border-soft);
}

.rg-article-card.rg-card:hover,
.rg-article-card.rg-card:focus-within {
  border: var(--rg-border);
  box-shadow: var(--rg-shadow-card), var(--rg-glow-sm);
  transform: translateY(-4px);
}

@media (prefers-reduced-motion: reduce) {
  .rg-article-card,
  .rg-article-card__image {
    transition: none;
  }

  .rg-article-card.rg-card:hover,
  .rg-article-card.rg-card:focus-within {
    transform: none;
  }
}

.rg-article-card__media {
  aspect-ratio: 16 / 10;
  display: block;
  overflow: hidden;
}

.rg-article-card__image {
  height: 100%;
  object-fit: cover;
  transition: transform 0.4s ease;
  width: 100%;
}

a.rg-article-card__media:hover .rg-article-card__image,
.rg-article-card:hover .rg-article-card__image {
  transform: scale(1.04);
}

.rg-article-card__body {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: var(--rg-space-2);
  /* space-5 (40px) inside a 481px card left a 401px measure and crowded the
     card's own corner radius. */
  padding: var(--rg-space-4);
}

.rg-article-card__cat {
  align-self: flex-start;
  background: var(--rg-surface-chip);
  border: var(--rg-border);
  border-radius: var(--rg-radius-sm);
  color: var(--rg-accent);
  font-size: var(--rg-btn);
  font-weight: 700;
  letter-spacing: 0.04em;
  line-height: 1.2;
  padding: var(--rg-space-1) var(--rg-space-2);
  text-transform: uppercase;
}

.rg-article-card__title {
  font-size: var(--rg-h4);
  font-weight: 700;
  /* Not --rg-lh-tight. These titles run to three lines at a 400px measure and
     1.0 collides them; 1.15 is the smallest value that clears descenders while
     still reading as a headline rather than body copy. Literal for the same
     reason .rg-community__heading carries 1.1 - it is a per-component optical
     correction, not a scale value. */
  line-height: 1.15;
  margin: 0;
}

.rg-article-card__title a {
  color: var(--rg-text);
  text-decoration: none;
  transition: color 0.2s ease;
}

.rg-article-card__title a:hover,
.rg-article-card__title a:focus-visible {
  color: var(--rg-accent);
}

.rg-article-card__excerpt {
  font-size: var(--rg-body);
  line-height: var(--rg-lh-body);
  margin: 0;
  opacity: 0.75;
}

/* Pinned to the foot of the card by margin-top: auto, so the dates line up
   across a row whatever the title wraps to. Quiet metadata: the smallest label
   in the scale, tracked and uppercase to match the theme's label idiom
   (.rg-footer__column-heading uses the same treatment). */
.rg-article-card__date {
  color: var(--rg-text);
  font-size: var(--rg-nav);
  font-weight: 700;
  letter-spacing: 0.04em;
  margin-top: auto;
  opacity: 0.55;
  padding-top: var(--rg-space-1);
  text-transform: uppercase;
}
/* Lists inside centred rich text - shared component, loaded globally.

   A `ul`/`ol` does not centre the way a paragraph does. The browser default is
   `list-style-position: outside` with ~40px of `padding-left`, so the marker
   hangs OUTSIDE the content box: `text-align: center` centres the text inside
   that box while the bullet stays pinned to the far left, visibly detached.
   Measured on the Live Patient Internship page at 430px - list box at x=40,
   text centred inside a content box starting at x=80, bullet stranded 40px to
   its left.

   The fix is to centre the LIST BOX rather than each line: `width: fit-content`
   shrinks it to its longest item, `margin-inline: auto` centres that box, and
   the items inside go back to `text-align: left`. Result:

     - a single short item reads as centred
     - several items of differing lengths align with EACH OTHER rather than
       stair-stepping, which is what makes a centred list look deliberate
     - the marker keeps its hanging indent, so a bullet that wraps to two lines
       still indents its second line correctly

   The alternative - `list-style-position: inside` - centres every line
   individually and is fine for one-word items, but it drops the hanging indent
   so wrapped text slides under the marker. Not used here; editors write real
   sentences into these fields.

   Scope: only where the theme actually centres. The desktop block covers the
   explicitly-centred module variants; the mobile block covers the rich-text
   wrappers, because below 768px essentially every module centres (see the
   767px blocks across the module stylesheets). Lists in left-aligned copy are
   untouched - `fit-content` + `auto` margins would be a no-op visually, but the
   narrowed box would break long-form legal/blog copy, so it is not applied
   there. */

.rg-split-feature--h-center .rg-split-feature__body :is(ul, ol),
.rg-cta-banner--center .rg-cta-banner__body :is(ul, ol),
.rg-promo--center .rg-promo__body :is(ul, ol),
.rg-outcomes__head--center .rg-outcomes__intro :is(ul, ol),
.rg-community--center .rg-community__body :is(ul, ol) {
  margin-inline: auto;
  /* Marker sits in this padding, inside the fitted box, so the box's optical
     centre includes the bullets rather than hanging them off the left edge. */
  padding-inline: 1.25em 0;
  text-align: left;
  width: fit-content;
}

@media (max-width: 767.98px) {
  .rg-split-feature__body :is(ul, ol),
  .rg-cta-banner__body :is(ul, ol),
  .rg-promo__body :is(ul, ol),
  .rg-feature-card__body :is(ul, ol),
  .rg-community__body :is(ul, ol),
  .rg-outcomes__intro :is(ul, ol),
  .rg-step__copy :is(ul, ol) {
    margin-inline: auto;
    padding-inline: 1.25em 0;
    text-align: left;
    width: fit-content;
  }
}
/* RG brand background presets - shared component (Decision 2, bg-vocab unification).
   The ONE source for the on-brand background vocabulary, consumed by BOTH the
   shared Layout & Style group (via the rg-layout-style macro) and rg-card-row's
   per-card background. Loaded globally via main.css (same promotion pattern as
   _faq.css) so a preset renders regardless of which module emits it.

   Theme spec section 3 (locked): choice fields / brand presets, not free colour
   pickers. The fill recipes are lifted byte-equivalent from the base
   .rg-gradient-card / --deep (_rg-base.css) and the promo white/dark panels
   (rg-promo-card/module.css) so migrated card render is pixel-identical. Those
   originals stay in place for the frozen deprecated modules; these presets carry
   the same values. Tokens only. */

.rg-bg--none          { background: transparent !important; }
/* Text colour for each preset is NOT set here. Every preset is named in the
   matching surface token block in _surfaces.css, so its text, eyebrow, border
   and focus colours derive from the surface it paints. */
.rg-bg--white         { background: var(--rg-surface) !important; color: var(--rg-text) !important; }
.rg-bg--dark          { background: var(--rg-surface) !important; color: var(--rg-text) !important; }
.rg-bg--gradient      { background: var(--rg-gradient-panel) !important; color: var(--rg-text) !important; }
.rg-bg--gradient-deep { background: linear-gradient(135deg, var(--rg-ink-deep) 0%, var(--rg-ink) 29%, var(--rg-coral-sea) 130%) !important; color: var(--rg-text) !important; }

/* Image preset - the image URL stays per-instance (a custom property emitted by
   the macro / card), since it is not a brand preset. Overlay/scrim are legibility
   tools over a photo, also per-instance, kept as pickers. */
.rg-bg--image {
  background-image: var(--rg-ls-bg-image) !important;
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

.rg-bg--overlay { position: relative; }
.rg-bg--overlay::before {
  content: "";
  position: absolute;
  inset: 0;
  background: var(--rg-ls-overlay, var(--rg-ink));
  opacity: var(--rg-ls-overlay-op, 0.4);
  pointer-events: none;
  border-radius: inherit;
}
.rg-bg--overlay > * { position: relative; z-index: 1; }

/* Corner glow - Rose and Muted Rose radial (hero corners, testimonial corners,
   outcome panel). Top-left by default; the modifiers mirror it. The gradient is
   the --rg-glow role token, so conforming to v4.1 "Muted Rose only" later is a
   token edit. */
.rg-glow {
  isolation: isolate;
  position: relative;
}

.rg-glow::before {
  background: var(--rg-glow);
  content: "";
  inset: 0;
  pointer-events: none;
  position: absolute;
  z-index: 0;
}

.rg-glow > * {
  position: relative;
  z-index: 1;
}

.rg-glow--tr::before { transform: scaleX(-1); }
.rg-glow--bl::before { transform: scaleY(-1); }
.rg-glow--br::before { transform: scale(-1, -1); }
/* RG heading colour control (shared). Editors pick a brand token via the
   heading_color field; the module emits it as a modifier class on the heading
   element. !important so an explicit editor choice beats a module's own default
   heading colour (same specificity, independent of stylesheet load order).
   Tokens only. 'default' emits no class and inherits the module's own colour. */
.rg-heading--white { color: var(--rg-white) !important; }
.rg-heading--ink   { color: var(--rg-ink) !important; }
.rg-heading--teal  { color: var(--rg-accent-large) !important; }

/* Inline highlight: <em> in a heading. Whitsunday on Ink. On light surfaces
   --rg-highlight falls back to the text colour, so it can never fail there. */
.rg-highlight {
  color: var(--rg-highlight);
  font-style: normal;
}

/* Root-fix: a promo card on a light panel needs dark (ink) heading text - the
   dark-theme default is white, which rendered invisible on the Sim Kit white
   card. This is the default; heading_color=white can still override per-instance. */
/* Two class names for one surface: rg-promo-card emits .rg-promo--bg-white,
   but rg-card-row emits .rg-bg--white for the same "white card" choice. Only
   the first was named here, so a white card placed through the card row got no
   ink heading - it merely happened to look right, falling through to
   theme-overrides and landing on black rather than the ink token. Name both. */
.rg-promo--bg-white .rg-promo__heading,
.rg-bg--white .rg-promo__heading {
  color: var(--rg-text-on-light);
}

/* Heading style (editor choice): Bold, or Light with bold accent. Bold is the
   default. "Light" is how the comps draw the card rows and statement rows:
   Sora 400 with the accent words in 700. A module puts .rg-heading-style--light
   on its root and its headings read the two properties below. */
.rg-heading-style--light {
  --rg-heading-weight: 400;
  --rg-heading-accent-weight: 700;
}

/* Highlight colour (Home Review 2, G2). The editor's choice for the bold
   accent words in a module's headings, set on the module root by
   hc.rg_hl_class(). Default (Rose) adds no class and keeps the page accent.
   Headings only: accent text in body copy keeps its contrast-safe colour.
   !important so the choice beats a module's own accent colour, the same rule
   as the heading colour control above. Whitsunday and White read on dark
   grounds only, Ink on light only; the field's help text says so. */
.rg-hl--rose       { --rg-hl: var(--rg-accent); }
.rg-hl--rose-muted { --rg-hl: var(--rg-rose-muted); }
.rg-hl--whitsunday { --rg-hl: var(--rg-whitsunday); }
.rg-hl--ink        { --rg-hl: var(--rg-ink); }
.rg-hl--white      { --rg-hl: var(--rg-white); }
.rg-hl--inherit    { --rg-hl: currentColor; }

[class*="rg-hl--"] :is(h1, h2, h3, h4, h5, h6, [class*="__heading"], [class*="__headline"], [class*="__title"]) .rg-accent {
  color: var(--rg-hl) !important;
}

/* Headline style (Home Review 4): Size and Text colour, from the group under
   each headline in the Content tab, set on the headline element by
   hc.rg_hs_head(). Default and Auto add no class. !important for the same
   reason as above: an explicit editor choice beats a module's own size or
   colour rule, whatever its specificity. Text colour sets the words that are
   not bold; the bold words keep the highlight colour. */
.rg-hs-size--display-xl { font-size: var(--rg-display-xl) !important; }
.rg-hs-size--display    { font-size: var(--rg-display) !important; }
.rg-hs-size--h1         { font-size: var(--rg-h1) !important; }
.rg-hs-size--h2         { font-size: var(--rg-h2) !important; }
.rg-hs-size--h3         { font-size: var(--rg-h3) !important; }
.rg-hs-size--h4         { font-size: var(--rg-h4) !important; }

.rg-hs-color--white      { color: var(--rg-white) !important; }
.rg-hs-color--ink        { color: var(--rg-ink) !important; }
.rg-hs-color--paper      { color: var(--rg-paper) !important; }
.rg-hs-color--whitsunday { color: var(--rg-whitsunday) !important; }
/* Small print - shared component (Review 3, S2), loaded globally.

   Footnotes, terms and disclosures at the end of a page: quiet, small, muted
   copy that is still readable on the ground it sits on. Built for a plain
   @hubspot/rich_text, so the editor keeps full control of the words:

     html="<div class='rg-smallprint'><p>* Footnote ...</p><p>** ...</p></div>"

   Put it in its own full-width section with zero section padding; the class
   supplies the page frame (same max width and side gutter as .rg-container),
   the vertical spacing and the reading measure, so every small print block on
   the site lines up the same way.

   Colour and size are declared on the text elements themselves, not just the
   wrapper (repo trap 13): in the portal theme-overrides.css styles bare p and
   a from the theme fields, and a direct element rule beats an inherited one,
   so an undeclared footnote renders at the theme's body size and colour. The
   colours are surface tokens, so the block reads correctly on Paper, white or
   Ink. A <small> inside a paragraph (the way the live footnotes were pasted)
   is reset to the same size rather than shrinking again. */

.rg-smallprint {
  color: var(--rg-text-muted);
  font-family: var(--rg-body-font);
  font-size: var(--rg-small);
  line-height: 1.6;
  margin-inline: auto;
  max-width: var(--rg-container-frame);
  /* Inset like the text inside the cards above (Review 4, S6): the gutter
     plus the card's own padding (48px, 24px below 900px, as the split
     feature), never flush with the card edges. No bottom padding: the page's
     end-of-page gap (.rg-page in _rg-base.css) spaces it from the footer. */
  padding: var(--rg-space-5) calc(var(--rg-gutter) + var(--rg-space-6)) 0;
}

.rg-smallprint :is(p, li, small, span, strong, em, b, i) {
  color: var(--rg-text-muted);
  font-family: var(--rg-body-font);
  font-size: var(--rg-small);
  line-height: 1.6;
}

.rg-smallprint :is(strong, b) {
  color: var(--rg-text);
}

/* A title inside the small print (the terms heading on Membership and the
   Hands-On Master Series) stays quiet: copy colour, a little larger than the
   notes, never the theme's heading size (trap 13 applies to h4 too). */
.rg-smallprint :is(h2, h3, h4, h5, h6) {
  color: var(--rg-text);
  font-family: var(--rg-body-font);
  font-size: var(--rg-body);
  font-weight: 600;
  letter-spacing: normal;
  line-height: 1.4;
  margin: var(--rg-space-3) 0 var(--rg-space-2);
  text-transform: none;
}

.rg-smallprint > :is(h2, h3, h4, h5, h6):first-child {
  margin-top: 0;
}

.rg-smallprint :is(p, ul, ol) {
  margin: 0 0 var(--rg-space-2);
  max-width: 110ch;
}

.rg-smallprint :is(ul, ol) {
  padding-left: var(--rg-space-3);
}

.rg-smallprint li {
  margin-bottom: var(--rg-space-1);
}

.rg-smallprint > :last-child,
.rg-smallprint li:last-child {
  margin-bottom: 0;
}

/* Links read as links without shouting: copy colour, underlined. Hover and
   focus thicken the underline; the theme's own a:hover colour is beaten on
   specificity (0,2,1 over 0,1,1). */
.rg-smallprint a,
.rg-smallprint a:is(:hover, :focus, :active) {
  color: var(--rg-text);
  font-family: var(--rg-body-font);
  font-size: inherit;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 0.18em;
}

.rg-smallprint a:is(:hover, :focus-visible) {
  text-decoration-thickness: 2px;
}

.rg-smallprint a:focus-visible {
  outline: 2px solid var(--rg-focus);
  outline-offset: 2px;
}

@media (max-width: 899.98px) {
  .rg-smallprint {
    padding-inline: calc(var(--rg-gutter) + var(--rg-space-3));
  }
}

@media (max-width: 767.98px) {
  .rg-smallprint {
    padding-top: var(--rg-space-4);
  }
}
/* Calendly widget (shared). The markup comes from
   templates/partials/rg-calendly-embed.html and renders inside rg-calendly and
   inside rg-hero's calendar slot, so its styles cannot live in one module's
   module.css (repo trap 14). Calendly paints its own white calendar in an
   iframe; this file only frames it. Tokens only. */

/* The frame keeps the calendar's corners on the card. */
.rg-calendly__frame {
  border-radius: var(--rg-radius-card);
  overflow: hidden;
}

.rg-calendly__frame .calendly-inline-widget {
  max-height: 700px;
  min-height: 560px;
  min-width: 280px;
  width: 100%;
}

/* The frame's cap and floor (Calendly cap, Mike after comparing with live).
   rg-calendly-fit.js sizes the frame to Calendly's own height inside these
   limits; past the cap Calendly scrolls its content inside the frame, as on
   live. Declared here too so the limits hold before the script runs. */
@media (max-width: 767.98px) {
  .rg-calendly__frame .calendly-inline-widget {
    max-height: 640px;
  }
}

.rg-calendly__form {
  margin-inline: auto;
  max-width: 760px;
}

/* rg-calendly-fit.js sizes the widget to Calendly's own height; the change
   between steps eases instead of jumping. */
.rg-calendly__frame .calendly-inline-widget.is-fitted {
  transition: height 0.2s ease;
}

@media (prefers-reduced-motion: reduce) {
  .rg-calendly__frame .calendly-inline-widget.is-fitted {
    transition: none;
  }
}
/* Content library (Wave 6): the public library page, its resource pages and
   the preview modal. The behaviour is Aidan's (Aidans_Playground/Preview_Library
   scripts, untouched); this file is only the look, in theme tokens.

   Shared here, not in a module (trap 14): the cards are rendered by
   rg-library-row on the server AND by preview-search.js in the browser, with
   the same markup (.resource__item and its children), and the modal is
   appended to the page body.

   His scripts add their own style element at runtime, after this sheet, so a
   rule here only wins on equal specificity if it is MORE specific. Where his
   CSS reads a custom property (the pps, rppm and rpp families) the token goes
   into the property instead. The rpp accent and the rppm close colour are set
   inline on the root element by his init script from RipePreviewConfig.accent
   (the templates pass the theme's primary button colour).

   Note: a CSS comment that names HTML elements in angle brackets, or lists
   custom properties with a trailing wildcard, failed HubSpot's validation
   here, so this comment avoids both. */

/* ---- His CSS variables, as theme tokens ---------------------------------- */

:root {
  /* player CTA overlay (preview-player.js) */
  --rpp-font: var(--rg-body-font);
  --rpp-radius: var(--rg-radius-card);
  --rpp-bg: var(--rg-ink);
  --rpp-overlay-bg: color-mix(in srgb, var(--rg-ink) 92%, transparent);
  --rpp-overlay-color: var(--rg-white);
  --rpp-heading-size: var(--rg-h4);
  --rpp-accent-color: var(--rg-btn-primary-text);
  --rpp-cta-radius: var(--rg-radius-pill);
  --rpp-cta-pad: 0 var(--rg-space-5);
  --rpp-cta-size: var(--rg-btn);

  /* modal (preview-modal.js) */
  --rppm-z: 1000;
  --rppm-backdrop: color-mix(in srgb, var(--rg-ink) 90%, transparent);
  --rppm-radius: var(--rg-radius-card);
  --rppm-shadow: var(--rg-shadow-card);
  --rppm-close-bg: var(--rg-paper);
}

.rg-library {
  /* search (preview-search.js) */
  --pps-bar-max: 720px;
  --pps-card-min: 240px;
  --pps-gap: var(--rg-space-4);
  --pps-input-bg: var(--rg-surface-raised);
  --pps-input-border: var(--rg-line);
  --pps-input-color: var(--rg-text);
  --pps-placeholder-color: var(--rg-text-muted);
  --pps-chip-bg: var(--rg-surface-raised);
  --pps-chip-border: var(--rg-line);
  --pps-chip-color: var(--rg-text);
}

/* ---- Search bar, chips, status, empty state ------------------------------ */

.rg-library .preview-search {
  box-sizing: border-box;
  margin: var(--rg-module-gap) auto 0;
  padding-inline: var(--rg-gutter);
  width: 100%;
}

.rg-library .preview-search__icon {
  display: inline-flex;
  left: var(--rg-space-3);
}

.rg-library .preview-search__icon svg {
  display: block;
  height: 18px;
  width: 18px;
}

.rg-library .preview-search input[type="search"] {
  font-family: var(--rg-body-font);
  font-size: var(--rg-body);
  min-height: var(--rg-btn-height);
  padding: 0 var(--rg-space-3) 0 var(--rg-space-8);
}

.rg-library .preview-search input[type="search"]:focus {
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--rg-accent) 25%, transparent);
}

.rg-library .pps-chips {
  gap: var(--rg-space-1);
  margin-top: var(--rg-space-3);
}

/* Bare <button>s: theme-overrides.css styles every button (trap 20), and its
   hover/focus rules outrank the script's .pps-chip, so the chip pins its own
   padding, radius and border in every state. */
.rg-library .pps-chip,
.rg-library .pps-chip:is(:hover, :focus, :active) {
  border: 1px solid var(--pps-chip-border);
  border-radius: var(--rg-radius-pill);
  font-family: var(--rg-body-font);
  font-size: var(--rg-small);
  font-weight: 700;
  line-height: 1.2;
  padding: var(--rg-space-1) var(--rg-space-2);
}

.rg-library .pps-chip:not([aria-pressed="true"]):is(:hover, :focus-visible) {
  background-color: var(--pps-chip-bg);
  border-color: var(--rg-accent);
  color: var(--pps-chip-color);
}

.rg-library .pps-chip[aria-pressed="true"],
.rg-library .pps-chip[aria-pressed="true"]:is(:hover, :focus, :active) {
  background-color: var(--rg-btn-primary-bg);
  border-color: var(--rg-btn-primary-bg);
  color: var(--rg-btn-primary-text);
}

.rg-library .pps-chip:focus-visible {
  outline: 2px solid var(--rg-focus);
  outline-offset: 2px;
}

.rg-library__results {
  box-sizing: border-box;
  margin: 0 auto;
  max-width: var(--rg-container-frame);
  padding-inline: var(--rg-gutter);
}

.rg-library__results [data-preview-results].is-active {
  margin-top: var(--rg-space-6);
}

.rg-library .pps-status {
  color: var(--rg-text-muted);
  font-size: var(--rg-small);
  margin: 0 0 var(--rg-space-3);
  opacity: 1;
}

.rg-library .pps-empty {
  color: var(--rg-text);
  font-size: var(--rg-body);
  opacity: 1;
  padding: var(--rg-space-6) 0;
  text-align: center;
}

/* ---- Library card (rows and search results share this markup) ------------ */

.rg-library .resource__item {
  background-color: var(--rg-surface-raised);
  border: var(--rg-border);
  border-radius: var(--rg-radius-card);
  color: var(--rg-text);
  cursor: pointer;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  transition: box-shadow 0.2s ease, border-color 0.2s ease;
}

.rg-library .resource__item:hover,
.rg-library .resource__item:focus-within {
  border-color: var(--rg-accent);
  box-shadow: var(--rg-shadow-card);
}

.rg-library .resource__image {
  display: flex;
  flex: 1 1 auto;
  flex-direction: column;
  position: relative;
}

.rg-library .resource__image > a {
  aspect-ratio: 16 / 9;
  background-color: var(--rg-media-bg);
  display: block;
  overflow: hidden;
  position: relative;
  text-decoration: none;
}

.rg-library .resource__image > a > img {
  display: block;
  height: 100%;
  inset: 0;
  object-fit: cover;
  position: absolute;
  transition: transform 0.3s ease;
  width: 100%;
}

.rg-library .resource__item:hover .resource__image > a > img {
  transform: scale(1.03);
}

/* No thumbnail (or one that failed to load): the name on the Ink panel. */
.rg-library .placeholder-image {
  align-items: center;
  box-sizing: border-box;
  color: var(--rg-white);
  display: flex;
  font-family: var(--rg-font);
  font-size: var(--rg-small);
  font-weight: 700;
  height: 100%;
  inset: 0;
  justify-content: center;
  line-height: 1.3;
  padding: var(--rg-space-3);
  position: absolute;
  text-align: center;
  width: 100%;
}

.rg-library .searchable-content p {
  color: var(--rg-text);
  font-family: var(--rg-font);
  font-size: var(--rg-h6);
  font-weight: 600;
  letter-spacing: -0.01em;
  line-height: 1.3;
  margin: 0;
  padding: var(--rg-space-2) var(--rg-space-3) var(--rg-space-3);
}

/* CPD/CE badge. His markup carries a Font Awesome check icon (<i class="fas
   fa-check">); the theme has no Font Awesome, so the tick is drawn here. */
.rg-library .certified-course-check {
  align-items: center;
  background-color: var(--rg-badge-bg);
  border-radius: var(--rg-radius-pill);
  color: var(--rg-badge-text);
  display: inline-flex;
  font-family: var(--rg-font);
  font-size: 0.75rem;
  font-weight: 700;
  gap: 6px;
  left: var(--rg-space-2);
  letter-spacing: 0.02em;
  line-height: 1;
  padding: 6px 10px;
  pointer-events: none;
  position: absolute;
  top: var(--rg-space-2);
}

.rg-library .certified-course-check i {
  border-bottom: 2px solid currentColor;
  border-right: 2px solid currentColor;
  display: inline-block;
  height: 8px;
  margin-top: -3px;
  transform: rotate(45deg);
  width: 4px;
}

/* ---- Resource page ------------------------------------------------------- */

.rg-resource {
  box-sizing: border-box;
  margin: 0 auto;
  max-width: calc(900px + 2 * var(--rg-gutter));
  padding: var(--rg-space-8) var(--rg-gutter) 0;
}

.rg-resource__crumb {
  font-size: var(--rg-small);
  margin: 0 0 var(--rg-space-3);
}

.rg-resource__crumb a {
  color: var(--rg-accent-text);
  font-weight: 700;
  text-decoration: none;
}

.rg-resource__crumb a:hover,
.rg-resource__crumb a:focus-visible {
  text-decoration: underline;
  text-underline-offset: 4px;
}

.rg-resource__title {
  color: var(--rg-text);
  font-family: var(--rg-font);
  font-size: var(--rg-h2);
  font-weight: var(--rg-heading-weight, 600);
  letter-spacing: var(--rg-track-head);
  line-height: 1.1;
  margin: 0 0 var(--rg-space-1);
}

.rg-resource__presenter {
  color: var(--rg-text-muted);
  font-size: var(--rg-body);
  margin: 0 0 var(--rg-space-5);
}

.rg-resource__player {
  aspect-ratio: 16 / 9;
  background-color: var(--rg-ink);
  border-radius: var(--rg-radius-card);
  margin: 0 0 var(--rg-space-5);
  overflow: hidden;
  width: 100%;
}

/* Raw rich text: colour and size declared with tokens (trap 13). */
.rg-resource__desc,
.rg-resource__desc p,
.rg-resource__desc li {
  color: var(--rg-text);
  font-family: var(--rg-body-font);
  font-size: var(--rg-body);
  line-height: var(--rg-lh-body);
}

/* ---- Player overlay and modal close (his scripts) ------------------------- */

/* Overlay copy reads as theme type. */
.rpp__heading,
.rpp__body {
  font-family: var(--rg-font);
}

/* The CTA can be a bare <button> (trap 20) and is styled by his script; pin
   the pill height the theme uses for every button. */
body .rpp__cta,
body .rpp__cta:is(:hover, :focus, :active) {
  align-items: center;
  border: 0;
  border-radius: var(--rpp-cta-radius);
  display: inline-flex;
  min-height: var(--rg-btn-height);
}

/* The close control is a bare <button>: without padding: 0 the theme's button
   padding turns the 40px circle into a pill (trap 20). */
body .rppm__close,
body .rppm__close:is(:hover, :focus, :active) {
  border: 0;
  border-radius: 50%;
  padding: 0;
}

body .rppm__close:focus-visible {
  outline: 2px solid var(--rg-focus);
  outline-offset: 2px;
}
/* --------------------------------------------------------------------------
   .rg-mslider - an image slider (Client Round 2, Split Content Band). One
   image at a time on a native scroll-snap track, so it swipes without a
   script. The arrows (js/rg-media-slider.js) page one image and grey out at
   either end; the dots (js/rg-track-dots.js) show and set the position.
   Nothing moves on its own. The slider is a photo surface: it carries
   rg-surface--ink, so captions and dots read on the image scrim.
   Lives here, not in a module stylesheet, so any module can use it (repo
   trap 14).
   -------------------------------------------------------------------------- */

.rg-mslider {
  overflow: hidden;
  position: relative;
}

.rg-mslider__track {
  display: flex;
  height: 100%;
  list-style: none;
  margin: 0;
  overflow-x: auto;
  overscroll-behavior-x: contain;
  padding: 0;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}

.rg-mslider__track::-webkit-scrollbar {
  display: none;
}

.rg-mslider__track:focus-visible {
  outline: 3px solid var(--rg-focus);
  outline-offset: -3px;
}

.rg-mslider__slide {
  flex: 0 0 100%;
  height: 100%;
  margin: 0;
  scroll-snap-align: start;
}

.rg-mslider__figure {
  height: 100%;
  margin: 0;
  position: relative;
}

.rg-mslider__img {
  display: block;
  height: 100%;
  object-fit: cover;
  width: 100%;
}

/* Caption over the bottom of the image, on a scrim, above the dots. */
.rg-mslider__caption {
  background: linear-gradient(0deg, color-mix(in srgb, var(--rg-ink) 85%, transparent) 0%, transparent 100%);
  bottom: 0;
  color: var(--rg-white);
  font-family: var(--rg-body-font);
  font-size: var(--rg-small);
  font-weight: 600;
  left: 0;
  line-height: 1.4;
  padding: var(--rg-space-6) var(--rg-space-3) var(--rg-space-5);
  position: absolute;
  right: 0;
}

.rg-mslider .rg-arrows__btn--prev {
  left: var(--rg-space-2);
}

.rg-mslider .rg-arrows__btn--next {
  right: var(--rg-space-2);
}

/* Dots sit over the bottom edge of the image. */
.rg-mslider .rg-dots {
  bottom: var(--rg-space-1);
  left: 0;
  margin: 0;
  position: absolute;
  right: 0;
  z-index: 2;
}

@media (prefers-reduced-motion: reduce) {
  .rg-mslider__track {
    scroll-behavior: auto;
  }
}

/* Utilities
Helper classes with ability to override anything that comes before it
*/

/* For content that needs to be visually hidden but stay visible for screenreaders */

.show-for-sr {
  border: 0 !important;
  clip: rect(0, 0, 0, 0) !important;
  height: 1px !important;
  overflow: hidden !important;
  padding: 0 !important;
  position: absolute !important;
  white-space: nowrap !important;
  width: 1px !important;
}

@media (max-width: 767.98px) {
  .show-for-sr--mobile {
    border: 0 !important;
    clip: rect(0, 0, 0, 0) !important;
    height: 1px !important;
    overflow: hidden !important;
    padding: 0 !important;
    position: absolute !important;
    white-space: nowrap !important;
    width: 1px !important;
  }
}