/* PROF public landing page (PRF-1184).
   All rules scoped under .prof-landing so nothing leaks to other pages:
   same discipline as prof-login.css / prof-legal.css.

   ==========================================================================
   HOW THIS FILE RELATES TO THE FIGMA DESIGN
   https://www.figma.com/design/vH5jodziAcRtBUG4VIJvHE/PROF-10-Platforme

   The design is a fixed 1728px-wide composition, and every number in this
   file is read out of it. But a Figma coordinate is NOT automatically a CSS
   coordinate: each measurement is classified before it is written down.

     FIXED          Border widths, border radii minimums, icon aspect ratios,
                    the logo's proportions. Written as plain px or ratios.

     CONTENT-DRIVEN Button widths, nav item widths, every text box's height,
                    card heights. Written as padding + line-height so the box
                    grows with its content. NEVER as width/height. This is
                    what keeps French from clipping.

     RESPONSIVE     Container width, section padding, type size, grid tracks,
                    the hero composition. Written as clamp()/%/fr so the
                    layout is the design's proportions at 1728px and reflows
                    below it.

   The design's 1528px content measure inside a 1728px canvas is reproduced
   by --pl-content + --pl-gutter: at a 1728px viewport .prof-landing__shell
   is exactly 1728 wide with exactly 1528 of content, and below that it is
   fluid at the same proportions. The page itself is never 1728px wide.

   Type sizes are clamp(floor, Xvw, FIGMA) where X = FIGMA / 1728 * 100, so
   every heading and label hits its exact Figma pixel size at 1728px and
   scales down to a readable floor instead of to nothing. Line heights are
   unitless ratios (Figma leading / Figma size) so they follow.

   var(--u) survives in a few places as "one design pixel at this section's
   width". It is used ONLY for decorative artwork geometry: the hero's curve
   mask, the features band's gradient matrix, two drop shadows. All cases
   where the number is part of a vector construction rather than of layout.
   No text, box or spacing value uses it.

   BREAKPOINTS (the ones already in use elsewhere in this project)
     1200px  small desktop, composition still side-by-side
      900px  tablet       , hero, cards and intro go single column,
                              nav links drop to their own centred row
      600px  phone        , feature grid halves, footer left-aligns

   Palette: this page uses its own navy (#004B99) rather than
   prof-theme.css's --prof-primary (#003DA5): the landing design is a
   distinct brand surface.
   ========================================================================== */

/* This page is standalone (it does not extend store-base.html), so it never
   picks up a CSS reset. Without this the browser's default body margin leaves
   an 8px white gutter down both sides of every full-bleed band. Scoped to the
   landing page's own body class so it cannot affect any other page. */
body.prof-landing-body {
  margin: 0;
  padding: 0;
}

.prof-landing {
  --pl-navy: #004B99;          /* headings, nav, footer, icon line art  */
  --pl-navy-deep: #003C7A;     /* button hover                          */
  --pl-slate: #2E5781;         /* body copy (Figma 275:1061)            */
  --pl-cyan: #00B3E4;          /* accent: arrows, Log In pill           */
  --pl-cyan-hover: #009BC7;
  --pl-pale: #E9FAFF;          /* pale card + badge fill                */
  --pl-pale-tint: #F5FBFF;     /* open FAQ row                          */
  /* Hero band: a 3-stop linear gradient down the frame.

     These are the RENDERED colours, sampled straight off frame 275:1061 at
     design y=0 / 413 / 1117, not the stop colours Figma's inspector reports.
     Do not "restore" the inspector values here. That layer is white ->
     #7CD8F1 -> #00B3E4 at 18% opacity, but it composites over a pale cyan
     base (~#E8FAFF), not over white. Reading the 18% as an alpha over white
     is the obvious mistake and it washes the whole band out to near-white;
     it has been tried twice. */
  --pl-hero-top: #EDFBFF;
  --pl-hero-mid: #D3F3FC;
  --pl-hero-end: #B8EBF9;
  /* Figma "Rectangle 5": the water band is the same navy as the headings. */
  --pl-water: #004B99;
  --pl-border: #CFE6F5;
  /* The frame carries no opaque fill of its own; its 18% gradient composites
     over the document's own #E9FAFF page rect. */
  --pl-page: #E9FAFF;

  /* ------------------------------------------------------------- layout */
  /* Measured off the design: every left-aligned element starts at x=100 and
     the Log In button ends at x=1628, so the content measure is 1528 inside
     a 1728 canvas. The gutter reaches exactly 100px at a 1728px viewport and
     shrinks with the window below that, so the whole composition stays on
     the design's proportions without the page ever being a fixed width. */
  --pl-content: 1528px;   /* the design's content measure, for reference */
  --pl-gutter: max(1.25rem, 5.787vw);

  /* ------------------------------------------------------ type scale
     clamp(floor, FIGMA/1728*100 vw, FIGMA). Exact at 1728px, readable at
     375px. Line heights live on the elements as unitless Figma ratios. */
  --pl-fs-61: max(2rem, 3.5301vw);       /* hero + intro H1  */
  --pl-fs-49: max(1.625rem, 2.8356vw);   /* section headings */
  --pl-fs-39: max(1.5rem, 2.2569vw);     /* card titles      */
  --pl-fs-34: max(1.25rem, 1.9676vw);     /* hero tagline     */
  --pl-fs-31: max(1.25rem, 1.794vw);     /* intro copy       */
  --pl-fs-25: max(1.0625rem, 1.4468vw);  /* hero copy, FAQ q */
  --pl-fs-24: max(1.0625rem, 1.3889vw);     /* card copy        */
  --pl-fs-20: max(0.9375rem, 1.1574vw);    /* buttons, nav      */
  --pl-fs-17: max(0.9375rem, 0.9838vw);  /* FAQ answers      */
  --pl-fs-13: max(0.75rem, 0.7523vw);    /* player timecode  */

  /* The ® is drawn by Museo Sans Rounded small and raised to cap height;
     Nunito draws it full size on the baseline. These two ratios (measured off
     frame 275:1135: 25.155/39 and 13/25.155) put it back. em-based, so they
     follow the type scale instead of needing a value per size. */
  --pl-reg-size: 0.645em;
  --pl-reg-rise: 0.517em;

  font-family: 'Karla', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
  color: var(--pl-slate);
  line-height: 1.6;
  /* Not white: the sticky bar below 1200px is translucent, and at scroll 0 it
     composites against this. Matching --pl-hero-top is what keeps the bar and
     the hero band seamless. Every section paints its own background over this,
     so it is only ever visible behind the bar. */
  background-color: var(--pl-hero-top);
  /* Long unbroken strings (URLs, compound French words) break rather than
     push a section wider than the viewport. This is a content guard, not an
     overflow band-aid; there is deliberately no overflow-x: hidden here. */
  overflow-wrap: break-word;
}

.prof-landing *,
.prof-landing *::before,
.prof-landing *::after {
  box-sizing: border-box;
}

/* The one container every section aligns to. Full-bleed backgrounds stay on
   the section; this only constrains content. */
/* The one container every section aligns to. Full-bleed backgrounds stay on
   the section; this only constrains content.

   There is deliberately NO max-width. The design's relationship is a 1528px
   content measure inside a 1728px canvas (a 100px gutter, or 5.787% either
   side), and that RATIO is what the container reproduces, at every width.
   Capping it at 1728 was tried and rejected: on a 3042px screen it left the
   whole composition as a narrow island with ~750px of dead space either side
   while the wave and background still ran full-bleed, which reads nothing
   like the design. Above 1728 the type scale, spacing and hero artwork all
   keep scaling on the same ratio (see --u and the type scale), so a large
   screen shows the Figma composition enlarged rather than stranded. */
.prof-landing__shell {
  width: 100%;
  margin-inline: auto;
  padding-inline: var(--pl-gutter);
}

/* ---------------------------------------------------------------- buttons */

/* Figma's pills are 175 / 162 / 94 x 54 around a 20/24 Semibold label. Those
   widths were measured around the English strings, so they are expressed as
   the padding that produces them (20px either side of a ~135px label) rather
   than as a width. The pill then grows with its own text and "Se connecter"
   fits where a 94px box clipped it. 15px of vertical padding either side of a
   24px line box is the design's 54px height, content-driven. */
.prof-landing__btn,
.prof-hero-fig__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: max(0.5rem, 0.868vw) max(0.875rem, 1.1574vw);
  border-radius: max(6px, 0.5787vw);
  font-family: 'Source Sans 3', sans-serif;
  font-weight: 600;
  font-size: var(--pl-fs-20);
  /* Without this the page's 1.6 body leading makes the pill 64px tall. */
  line-height: 1.2;
  text-align: center;
  text-decoration: none;
  /* No border: 15 + 24 + 15 is the design's 54px pill, and a 1px transparent
     border under border-box made every pill on the page 56. */
  border: 0;
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}

.prof-landing__btn:hover,
.prof-landing__btn:focus,
.prof-hero-fig__btn:hover,
.prof-hero-fig__btn:focus {
  text-decoration: none;
}

.prof-landing__btn--navy {
  background-color: var(--pl-navy);
  color: #ffffff;
}

.prof-landing__btn--navy:hover,
.prof-landing__btn--navy:focus {
  background-color: var(--pl-navy-deep);
  color: #ffffff;
}

.prof-landing__btn--white {
  background-color: #ffffff;
  color: var(--pl-navy);
}

.prof-landing__btn--white:hover,
.prof-landing__btn--white:focus {
  background-color: var(--pl-pale);
  color: var(--pl-navy);
}

/* --------------------------------------------- shared: registered mark */

/* Page-wide fallback for the ® outside the Figma-measured frames. */
.prof-landing__reg {
  font-size: 0.6em;
  vertical-align: 0.5em;
  line-height: 0;
}

/* Inside the measured frames the mark uses the design's own ratio. The
   line-height: 0 is load-bearing rather than cosmetic: a smaller inline box
   sharing the line's leading gets positive half-leading, which grows the line
   box and drags the whole card taller. Zeroing it lets the main run set the
   line on its own. */
.prof-intro-fig .prof-landing__reg,
.prof-disc-fig__title .prof-landing__reg {
  font-size: var(--pl-reg-size);
  vertical-align: var(--pl-reg-rise);
  line-height: 0;
}

/* ------------------------------------------------------ language switcher */

/* Posts to Django's built-in set_language view, which sets the cookie and
   redirects back to `next`, so this needs no JavaScript, which matters
   because these pages deliberately ship none. */
.prof-landing__lang {
  display: flex;
  align-items: center;
  gap: 0.5rem;
  margin: 0;
}

/* The bordered box is the IMG, not the button.

   The button used to be the painted box: 1px border, radius 3, padding 0, so
   its hit area was exactly the flag, 22x12 on a phone. That is far under the
   24x24 minimum (WCAG 2.2 SC 2.5.8) and the two sat 8px apart, which makes
   mis-taps likely on the one control that changes the whole site's language.

   So the border and radius move to the image, which paints the identical box
   (content-box below keeps the 20px flag + 2px border at the same 22px), and
   the hit area is grown by the ::after below rather than by padding here.
   Padding would have to be paid back out of the 8px gap to keep the flags
   where they are; an absolutely positioned pseudo-element is out of flow, so
   it cannot move anything by construction and needs no compensation.
   line-height: 0 still keeps the button from inheriting a text line box.

   Verified: with these rules against the originals re-injected at runtime, the
   switcher region is pixel-identical at 2x DPR at 390/768/1440/1728, and the
   form's width and x-position are unchanged to 2dp. */
.prof-landing__lang-btn {
  position: relative;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
  line-height: 0;
  /* Inactive flags are muted so the current language reads at a glance. */
  opacity: 0.45;
  filter: saturate(0.6);
  transition: opacity 0.15s ease, filter 0.15s ease, border-color 0.15s ease;
}

/* The tap target, centred on the flag and never smaller than 24x24 (WCAG 2.2
   SC 2.5.8). max() so it only ever grows the area: once the flag itself passes
   24px on a large screen the target simply follows it. Out of flow, so the
   painted box, the 8px gap and the bar's height are all untouched; the two
   targets grow 1px either side into that gap and still stop 6px apart. */
.prof-landing__lang-btn::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: max(100%, 24px);
  height: max(100%, 24px);
}

.prof-landing__lang-btn:hover,
.prof-landing__lang-btn:focus {
  opacity: 0.85;
  filter: none;
}

.prof-landing__lang-btn.is-active {
  opacity: 1;
  filter: none;
}

/* Aspect-locked rather than sized twice, so the flag can never be squashed.
   Carries the border the button used to draw.

   content-box against the page's global border-box: the 20px was the flag's
   own measure while the button drew the border around it, so the painted box
   has always been 22px. Leaving this on border-box would fold the border into
   the 20 and quietly shrink the flag by 2px, which is exactly the kind of
   drift this move is supposed to avoid. */
.prof-landing__lang-btn img {
  display: block;
  box-sizing: content-box;
  width: max(20px, 1.5046vw);
  height: auto;
  border: 1px solid rgba(0, 75, 153, 0.25);
  border-radius: 3px;
  transition: border-color 0.15s ease;
}

.prof-landing__lang-btn.is-active img {
  border-color: var(--pl-navy);
}

/* ==========================================================================
   HERO: Figma frame 275:1061 "HERO SECTION" (1728x1117)

   Was one absolutely-positioned 1728x1117 canvas. Now flow blocks on the
   shared container, with only the wave left as decorative artwork. The nav
   bar is no longer part of this section (it is a page-level sibling, so it
   can be sticky), which is why the section measures 977 rather than 1117.

   The design's vertical rhythm is reproduced as flow spacing and it adds
   back up. Reading down from the top of the page:

     nav      61 padding + 78.894 logo            = 139.894
     main     123.65 padding, then the card row     263.544  (card's own y)
     copy     +12.96 on top of that                 276.5    (headline y)
     row      572.8 tall (the card sets it)         836.344
     water    pulled up 351.3, 475 of clear water
              above the tagline, 116 below it       1117

   So nav + hero is the frame's 1117 exactly, and the hero on its own is
   1117 - 139.894 = 977.
   ========================================================================== */

.prof-hero-fig {
  container-type: inline-size;
  position: relative;
  /* Figma: the frame has no opaque fill, only an 18% gradient over the
     document's #E9FAFF page rect. Stop positions are the frame's own
     (923.5/1117 span, middle stop at 344.5/1117). All three stops carry the
     same alpha, so these rgba() values are exact rather than approximate.
     Held as percentages so the ramp follows the section however tall the
     content makes it. */
  background-color: var(--pl-page);
  background-image: linear-gradient(180deg,
      rgba(255, 255, 255, 0.18) 0%,
      rgba(124, 216, 241, 0.18) 30.843%,
      rgba(0, 179, 228, 0.18) 82.677%);
  /* Clips the wave, exactly as the Figma frame clips it. This is intentional
     artwork clipping on one section, not a page-level overflow band-aid. */
  overflow: hidden;
}

/* One design pixel at this section's width. Decorative geometry only, and
   deliberately uncapped: the whole composition scales past 1728 on the
   design's own ratio, so the wave and the tagline's well have to scale with
   it or the hero comes apart on a large screen. */
.prof-hero-fig__water,
.prof-hero-fig__card {
  --u: calc(100cqw / 1728);
}

/* ------------------------------------------------------------------- nav */

/* Figma "NAV" (275:1077): 100px/61px padding, logo left, menu right.

   A page-level bar, not part of the hero. Its background is the colour the
   hero's gradient composites to at 0%, so the two meet with no seam, and it
   is what makes the bar opaque once it is sticky. z-index keeps it over every
   later section (the features and trusted bands are positioned). */
.prof-hero-fig__nav {
  position: relative;
  z-index: 40;
  background-color: var(--pl-hero-top);
  padding-top: max(1.25rem, 3.5301vw);
  padding-bottom: 0;
}

/* Figma puts a drop shadow on the NAV frame, which has no fill, so what it
   actually shadows is the logo/label/pill silhouettes rather than a band.
   The filter therefore belongs on this transparent inner wrapper, NOT on the
   bar: the bar now carries a background, and a drop-shadow on that silhouettes
   the whole rectangle and draws a seam across the page under it.
   In vw rather than --u, which only resolves inside the hero's container. */
.prof-hero-fig__nav-inner {
  filter: drop-shadow(0 1.2153vw 1.088vw rgba(0, 0, 0, 0.08));
}

/* Figma "Menu droite" gap is 37px. flex-wrap is what makes this survive a
   long translation: items drop to the next row rather than overlapping. */
.prof-hero-fig__nav-inner {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: max(0.75rem, 2.1412vw);
}

/* margin-right: auto reproduces the design's space-between without pinning
   anything to a coordinate: logo left, everything else grouped on the right
   at the design's 37px gap. */
.prof-hero-fig__logo-link {
  flex: none;
  margin-right: auto;
  display: block;
  line-height: 0;
}

/* Figma "Layer_1" (275:1078): 240 x 78.894. Height is auto so the logo can
   never be distorted; the SVG carries the ratio. */
.prof-hero-fig__logo {
  display: block;
  width: max(120px, 13.889vw);
  height: auto;
}

/* ---------------------------------------------- nav: one markup, two modes */

/* Not in the Figma frame, but it is the only control for a feature this page
   ships (the copy is translated), so it is kept. It sits between the FAQ link
   and the Log In pill, on the row's own 37px gap. No auto margin here: the
   logo's margin-right: auto already takes all the free space, so the links,
   the flags and the pill stay grouped hard against the right edge and the
   pill still closes on the design's x=1628. */
.prof-hero-fig__lang {
  flex: none;
  gap: max(4px, 0.463vw);
}

/* Figma 275:1118 is ONE text node reading
   "Discover the Platform     ·     Features     ·     FAQ", five spaces
   either side of each separator, which measure ~25px at 20px. Reproduced as
   a real gap on a real flex row rather than as literal spaces under
   white-space: pre, so the links can wrap when there is no room for them. */
.prof-hero-fig__links {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: max(0.4rem, 1.4468vw);
  font-family: 'Source Sans 3', sans-serif;
  font-weight: 600;
  font-size: var(--pl-fs-20);
  line-height: 1.2;
  color: var(--pl-navy);
}

.prof-hero-fig__links a {
  color: inherit;
  text-decoration: none;
}

.prof-hero-fig__links a:hover,
.prof-hero-fig__links a:focus {
  color: var(--pl-cyan);
  text-decoration: none;
}

.prof-hero-fig__sep {
  opacity: 0.85;
}

/* Figma 275:1119: fill Bleu Ciel. No width, see the button block above. */
.prof-hero-fig__btn--login {
  flex: none;
  background-color: var(--pl-cyan);
  color: #ffffff;
}

.prof-hero-fig__btn--login:hover,
.prof-hero-fig__btn--login:focus {
  background-color: var(--pl-cyan-hover);
  color: #ffffff;
}

/* --------------------------------------------------------- hero content */

/* Figma's "Textes intro" box runs y=118..835 and centres its 400px of content
   in it, which puts the headline at y=276.5, NOT at the 158.5 the frame
   reports, which is the offset INSIDE that box. The card box starts at
   263.54, so the row's own top is the card's and the copy is nudged the
   remaining 12.96 down. The logo ends at 139.894, so 123.65 of flow spacing
   opens the row exactly where the design does.

   The two tracks are the design's own measures: the copy runs x=100..854 and
   the card box x=854..1614.76 inside the 1528 content. Declaring them as fr
   keeps that ratio at every width instead of freezing the split at 1728. */
.prof-hero-fig__main {
  position: relative;
  z-index: 1;
  padding-top: max(1.5rem, 7.1557vw);
  display: grid;
  grid-template-columns: minmax(0, 754.19fr) minmax(0, 773.81fr);
  align-items: start;
}

/* Figma "Textes intro" (275:1069): auto-layout column, 40px gap. */
.prof-hero-fig__copy {
  padding-top: max(0rem, 0.75vw);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: max(1rem, 2.3148vw);
}

/* Figma 275:1070: 61px over 73px leading. No width and no height, the
   headline wraps to whatever the column gives it and the box follows. */
.prof-hero-fig__title {
  margin: 0;
  font-family: 'Nunito', sans-serif;
  font-weight: 900;
  font-size: var(--pl-fs-61);
  line-height: 1.19672;
  color: var(--pl-navy);
}

/* Figma 275:1071: 25/30, set on a 680 measure inside the 754 column. Kept as
   a proportion of the column so the design's four-line wrap survives at
   desktop while the paragraph is free to run longer in French. */
.prof-hero-fig__text {
  margin: 0;
  max-width: 90.16%;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: var(--pl-fs-25);
  line-height: 1.2;
  color: var(--pl-slate);
}

/* Figma "Boutons Hero" (275:1072): 20px gap. Wraps so two long French labels
   cannot push the row past the column. */
.prof-hero-fig__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  gap: max(0.625rem, 1.1574vw);
}

/* Figma 275:1073: fill Bleu. */
.prof-hero-fig__btn--primary {
  background-color: var(--pl-navy);
  color: #ffffff;
}

.prof-hero-fig__btn--primary:hover,
.prof-hero-fig__btn--primary:focus {
  background-color: var(--pl-navy-deep);
  color: #ffffff;
}

/* Figma 275:1075: no fill, dotted underline, Paragraphe. Keeps the same
   vertical padding as the filled pill so both sit on one 54px baseline. */
.prof-hero-fig__btn--text {
  color: var(--pl-slate);
  text-decoration: underline;
  text-decoration-style: dotted;
  text-decoration-thickness: from-font;
}

.prof-hero-fig__btn--text:hover,
.prof-hero-fig__btn--text:focus {
  color: var(--pl-navy);
  text-decoration: underline;
  text-decoration-style: dotted;
}

/* Figma "Image - Rapport Eau" (275:1558): 760.569x572.802 at x=854.19,
   y=263.54. Width is a proportion of its own track; the height now follows
   the card's own content, which is built to the same 1.3277 ratio, so it
   still cannot be stretched. The drop-shadow filter follows the rendered
   shape, so it picks up the border-radius rather than drawing square corners
   the way a box-shadow would.

   It is a query container so the card's interior can be sized in cqw and
   scale as one piece with its column, exactly as the flattened image did. */
.prof-hero-fig__card {
  width: 98.29%;
  container-type: inline-size;
  filter: drop-shadow(0 0 calc(53.018 * var(--u)) rgba(0, 0, 0, 0.05));
}

/* ------------------------------------------ water analysis card interior */

/* The design ships this card as ONE flattened PNG with no sub-layers, so its
   nine strings ("pH", "Free chlorine", "In range", ...) sat outside gettext
   and the card could not be translated at all. It is rebuilt here as markup.

   Every number below is a design pixel on the 760.569-wide card. They were
   measured off a 4x export of the node ("Image - Rapport Eau", 3467x2716 with
   the drop shadow, card plate 3042.09x2290.83 => 760.523 x 572.706 design),
   cross-checked against the lossless PNG embedded in the HERO SECTION SVG.
   The two sources agree everywhere to within 0.76 design px.

   Type is Inter with TABULAR figures. That is not a guess: the export's "1"
   carries a foot serif, which is exactly what Inter's tnum "1" has and its
   proportional "1" does not. Hence font-feature-settings below; drop it and
   every number in the card changes shape and width.

   The export is hand-composed, not laid out on a grid: its rows are
   100.66 / 89.74 / 98.40 tall, its pills sit 4.76 / 8.51 / 0 back from the
   content edge, and its value-to-pill gaps are 23.4 / 22.5 / 14.9. All of
   that is reproduced per row rather than averaged, which is what holds the
   rebuild to a mean 0.50 design px against the export.

   None of it is absolute positioning: pills are pinned to the right edge and
   grow leftward on their own padding, so a longer translated word still
   fits. Verified in EN and FR down to 375px. */

.prof-wa {
  /* 1 unit == 1 design px on the 760.569 card. Declared on the descendant:
     cqw resolves against the nearest ANCESTOR container. */
  --c: calc(100cqw / 760.569);

  --wa-ink: #00071b;          /* values, units, action text */
  --wa-muted: #566784;        /* labels, both section headings */
  --wa-rule: #e4e8ee;
  --wa-panel: #f3f5f7;
  --wa-badge: #1f3e84;
  --wa-warn-bg: #f0e6db;
  --wa-warn-ink: #8f642b;
  --wa-ok-bg: #dbefe5;
  --wa-ok-ink: #007f4a;

  box-sizing: border-box;
  background: #fff;
  border-radius: calc(29.5 * var(--c));   /* four corner fits: 30.8 30.3 28.8 28.2 */
  /* Top padding is set from the title's INK, not its line box: the cap top
     sits 44.81 from the card top and Inter puts 5.94 of line box above the
     cap at this size. Bottom padding is the design's own 41.73. */
  padding: calc(39.51 * var(--c)) calc(41.78 * var(--c)) calc(42.58 * var(--c)) calc(42.99 * var(--c));
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  font-feature-settings: 'tnum' 1;   /* the export's figures are tabular */
}

.prof-wa__title {
  margin: 0;
  padding-left: calc(0.95 * var(--c));
  font-size: max(11px, calc(25.1 * var(--c)));
  font-weight: 500;
  line-height: 1.2;
  letter-spacing: calc(0.24 * var(--c));
  text-transform: uppercase;
  color: var(--wa-muted);
}

/* The rule is each row's own top border, so they land at 98.50 / 199.16 /
   288.89 and the panel opens at 387.29, all as measured. */
.prof-wa__row {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  border-top: 1px solid var(--wa-rule);
}

/* Each row carries its own three measurements from the export, because the
   export is hand-placed and they genuinely differ per row:
     --pill-inset  pill right edge, back from the 719.32 content edge
     --pill-gap    unit/value ink to pill box
     --unit-gap    value ink to unit ink                                     */
.prof-wa__row:nth-of-type(1) {
  height: calc(100.66 * var(--c));
  padding-top: calc(9.3 * var(--c));
  --pill-inset: 4.76;
  --pill-gap: 23.4;
  --unit-gap: 15.5;
  --pill-pad: 19.3;
  --readout-shift: 2.84;
  --pill-shift: 1.04;
}
.prof-wa__row:nth-of-type(2) {
  height: calc(89.74 * var(--c));
  padding-top: calc(3 * var(--c));
  --pill-inset: 8.51;
  --pill-gap: 22.5;
  --unit-gap: 16.4;
  --pill-pad: 18.5;
}
.prof-wa__row:nth-of-type(3) {
  height: calc(98.40 * var(--c));
  padding-bottom: calc(6 * var(--c));
  --pill-inset: 0;
  --pill-gap: 14.9;
  --unit-gap: 14.9;
  --pill-pad: 15.45;
  --lbl-track: 0.319;
  --pill-shift: 1.5;
}

.prof-wa__row:first-of-type {
  margin-top: calc(28.29 * var(--c));
}

.prof-wa__label {
  flex: 1 1 auto;
  padding-left: calc(1.05 * var(--c));
  font-size: max(11px, calc(25.5 * var(--c)));
  font-weight: 500;
  line-height: 1.25;
  letter-spacing: calc(var(--lbl-track, 0.15) * var(--c));
  color: var(--wa-muted);
}

.prof-wa__readout {
  position: relative;
  top: calc(var(--readout-shift, 0) * var(--c));
  display: flex;
  align-items: baseline;
  gap: calc(var(--unit-gap) * var(--c));
  flex-shrink: 0;
}

.prof-wa__value {
  font-size: max(13px, calc(31.62 * var(--c)));
  font-weight: 700;
  line-height: 1.2;
  color: var(--wa-ink);
}

.prof-wa__unit {
  font-size: max(12px, calc(27.5 * var(--c)));
  font-weight: 700;
  line-height: 1.2;
  color: var(--wa-ink);
}

/* Stadium pills, padding-driven so a translated word grows the pill rather
   than overflowing it. --pill-inset pins the right edge, so growth is
   leftward and the pill never crosses the card's content edge. */
.prof-wa__pill {
  position: relative;
  top: calc(var(--pill-shift, 0.6) * var(--c));
  display: inline-flex;
  align-items: center;
  justify-content: center;
  align-self: center;
  min-height: calc(39.4 * var(--c));
  padding: 0 calc(var(--pill-pad) * var(--c));
  margin-left: calc(var(--pill-gap) * var(--c));
  margin-right: calc(var(--pill-inset) * var(--c));
  border-radius: 999px;
  font-size: max(10px, calc(19.9 * var(--c)));
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
}

.prof-wa__pill--warn { background: var(--wa-warn-bg); color: var(--wa-warn-ink); }
.prof-wa__pill--ok   { background: var(--wa-ok-bg);   color: var(--wa-ok-ink); }

/* Recommended-action panel: 676.57 x 144.26 at y 387.29, on the same content
   edge as the rules. */
.prof-wa__action {
  box-sizing: border-box;
  height: calc(144.12 * var(--c));
  padding: calc(26.2 * var(--c)) calc(25 * var(--c));
  border-radius: calc(28 * var(--c));
  background: var(--wa-panel);
  display: flex;
  flex-direction: column;
}

.prof-wa__action-label {
  margin: 0;
  font-size: max(10px, calc(18.65 * var(--c)));
  font-weight: 600;
  line-height: 1.2;
  letter-spacing: calc(1.93 * var(--c));
  padding-left: calc(2.28 * var(--c));   /* the export insets this label 2.28 past the badge */
  text-transform: uppercase;
  color: var(--wa-muted);
}

.prof-wa__action-body {
  display: flex;
  align-items: center;
  gap: calc(24.3 * var(--c));
  margin-top: calc(17.9 * var(--c));
}

.prof-wa__badge {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: calc(67.75 * var(--c));
  height: calc(64.5 * var(--c));
  border-radius: calc(15 * var(--c));
  background: var(--wa-badge);
  color: #fff;
  font-size: max(11px, calc(26 * var(--c)));
  font-weight: 700;
  line-height: 1;
}

.prof-wa__action-text {
  margin: 0;
  font-size: max(12px, calc(26.8 * var(--c)));
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: calc(-0.352 * var(--c));
  color: var(--wa-ink);
}

/* ------------------------------------------------- water band + tagline */

/* Figma "Mask group" (275:1063): a navy rect with the water photo multiplied
   over it, clipped by the frame's own "Courbe bleue" vector.

   The design draws that as a fixed 1742x632 rect inside a 2941x1444 mask
   box. Here the band is a flow element that grows with its content and the
   crest has been re-cut (hero-curve-crest.svg) to span exactly the frame's
   width, so the same curve reads correctly whatever height the band ends up.
   Two mask layers: the crest at the top, and a solid layer covering
   everything below it. Their union is the band.

   The negative margin is the design's own overlap, it is what lifts the
   crest behind the analysis card, expressed in design pixels so it stays
   proportional instead of drifting as the window widens. */
.prof-hero-fig__water {
  position: relative;
  z-index: 0;
  margin-top: calc(-351.3 * var(--u));
  /* 960 - 485: clear water between the crest box and the tagline. */
  padding-top: calc(475 * var(--u));
  /* 1117 - 1001: the frame's own bottom margin, so the section needs none. */
  padding-bottom: calc(116 * var(--u));
  background-color: var(--pl-water);
  -webkit-mask-image: url("../img/prof/landing/hero-curve-crest.svg"), linear-gradient(#000, #000);
          mask-image: url("../img/prof/landing/hero-curve-crest.svg"), linear-gradient(#000, #000);
  /* The crest spans the band's full width but its DEPTH is a design pixel
     value, so past 1728 the wave flattens and widens instead of growing
     taller than the tagline's well beneath it. (The SVG carries
     preserveAspectRatio="none" for exactly this.) At or below 1728,
     400 * var(--u) is 23.15% of the width, identical to `auto`.

     The +2px on the lower layer is load-bearing, not slop. The two layers used
     to ABUT exactly at 400 * var(--u), and 400 * var(--u) is almost never a
     whole device pixel: wherever it landed on a fraction, neither layer fully
     covered that row and the hero gradient showed through the navy as a
     bright hairline across the whole band. It reproduced at 1200/1280/1600/
     1920 with a row delta of up to 158/255, and looked clean at 1366/1440/
     1728, which is exactly the "only sometimes" signature. Overlapping the
     layers removes the boundary; mask layers composite with `add`, so the
     overlap is invisible. */
  -webkit-mask-size: 100% calc(400 * var(--u)), 100% calc(100% - 400 * var(--u) + 2px);
          mask-size: 100% calc(400 * var(--u)), 100% calc(100% - 400 * var(--u) + 2px);
  -webkit-mask-position: top left, bottom left;
          mask-position: top left, bottom left;
  -webkit-mask-repeat: no-repeat, no-repeat;
          mask-repeat: no-repeat, no-repeat;
}

/* The photo multiplies over the navy fill, both inside the mask, same
   stacking as Figma. cover can never leave a gap at any band height, and the
   22.5% vertical position is the design's own crop: it puts the photo's top
   127 design pixels above the band, which is what lands the waterline. */
.prof-hero-fig__water::before {
  content: "";
  position: absolute;
  inset: 0;
  background-image: url("../img/prof/landing/hero-water-photo.webp");
  background-size: cover;
  background-position: center 22.5%;
  background-repeat: no-repeat;
  mix-blend-mode: multiply;
}

/* Figma 275:1067: 34/41, at the same x=100 grid line as the logo, headline,
   paragraph and buttons. The design's node is a nowrap 618px box; here it
   wraps, because a French tagline that cannot wrap is a horizontal scrollbar. */
.prof-hero-fig__slogan {
  /* The photo layer above is an absolutely positioned ::before, so the
     tagline needs to be positioned too or it paints underneath it. */
  position: relative;
  z-index: 1;
  margin: 0;
  color: #ffffff;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: var(--pl-fs-34);
  line-height: 1.20588;
}

/* Figma runs "safe" and "beautiful" at weight 900 against the 700 around them. */
.prof-hero-fig__slogan strong {
  font-weight: 900;
}

/* Figma sets the space before the mark at 31px against the line's 34. */
.prof-hero-fig__slogan-gap {
  font-size: 0.912em;
}

/* Figma sets the mark at 19.995 with its baseline 11px above the line's.
   Both as em of their own run, so they follow the fluid type. */
.prof-hero-fig__slogan sup {
  font-size: 0.588em;
  line-height: 0;
  vertical-align: 0.55em;
}

/* The ® is a plain glyph inside the hero's own runs in Figma, the face draws
   it small and raised on its own, so the page-wide shrink is neutralised
   here. The span stays because it is part of the translated msgid. */
.prof-hero-fig .prof-landing__reg {
  font-size: inherit;
  vertical-align: baseline;
  line-height: inherit;
}

/* ==========================================================================
   INTRO: Figma frame 275:1121 "More Than Water Testing" (1728x436)

   Was a 436px-tall canvas with both children placed absolutely. Now a
   two-column grid on the shared container. The tracks are the frame's own
   measures (839 copy + 123 gap + 566 points = 1528) and the 42.5px offset
   Figma gives the bullet column is exactly what centring the shorter column
   against the taller one produces, so align-items does it for free.
   ========================================================================== */

.prof-intro-fig {
  background-color: #ffffff;
  padding-block: max(2.5rem, 5.787vw);
}

.prof-intro-fig__inner {
  display: grid;
  grid-template-columns: minmax(0, 839fr) minmax(0, 566fr);
  column-gap: max(1.5rem, 7.1181vw);
  align-items: center;
}

/* Heading 73 tall, paragraph starts at y=88, a 15px column gap. */
.prof-intro-fig__copy {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: max(0.4rem, 0.868vw);
}

/* Figma 275:1123: Museo Sans Rounded 900 at 61/73, the same H1 style as the
   hero headline. Fill is Bleu. */
.prof-intro-fig__title {
  margin: 0;
  font-family: 'Nunito', sans-serif;
  font-weight: 900;
  font-size: var(--pl-fs-61);
  line-height: 1.19672;
  color: var(--pl-navy);
}

/* Figma 275:1124: the H4 style, 31/37, fill Paragraphe. */
.prof-intro-fig__text {
  margin: 0;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: var(--pl-fs-31);
  line-height: 1.19355;
  color: var(--pl-slate);
}

/* Figma "3 points" (275:1125): three 37px rows, 20px apart. */
.prof-intro-fig__points {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: max(0.6rem, 1.1574vw);
}

/* The design's rows are one line each and the old build forced that with
   white-space: nowrap, which is why a longer French label ran into the row
   below it. A flex row with a real gap lets the label wrap under itself
   instead, and the row grows. */
.prof-intro-fig__points li {
  display: flex;
  align-items: flex-start;
  gap: max(0.4rem, 0.5885vw);
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: var(--pl-fs-31);
  line-height: 1.19355;
  color: var(--pl-cyan);
}

/* The frame's own "Vector 9", not a glyph or a border. Figma reports the
   node as 32 x 21.333, but the exported path carries a 4px stroke, so its
   visual box is 36.83 x 24.162, which is the SVG's viewBox. Height is auto
   so the arrow keeps that ratio; the top margin centres it on the first line
   of the label rather than on the whole wrapped block. */
.prof-intro-fig__points img {
  flex: none;
  display: block;
  width: max(22px, 2.1314vw);
  height: auto;
  margin-top: 0.21em;
}

/* ==========================================================================
   DISCOVER CARDS: Figma frame 275:1135 (1728x2058)

   Already a flow column; what was static was every dimension inside it. The
   cards now take their height from their copy (which is what makes them safe
   for French), the circle is a percentage of the card and each icon a
   percentage of the circle, and below 900px the row becomes a column.
   ========================================================================== */

.prof-disc-fig {
  background-color: #ffffff;
  /* The frame's own bottom padding is the gap to the next band. */
  padding-bottom: max(2.5rem, 5.787vw);
}

/* Figma "Frame 15" (275:1136): column, 30px gap. */
.prof-disc-fig__list {
  display: flex;
  flex-direction: column;
  gap: max(1rem, 1.7361vw);
}

/* Every card: radius 40, row, 50px gap, centred, padding 70/90/70/60. The
   asymmetric horizontal padding is the design's and is what makes the text
   column measure 1022 (1528 - 60 - 306 - 50 - 90). */
.prof-disc-fig__card {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: max(1.25rem, 2.8935vw);
  border-radius: max(18px, 2.3148vw);
  padding: max(1.5rem, 4.0509vw) max(1.25rem, 5.2083vw)
           max(1.5rem, 4.0509vw) max(1.25rem, 3.4722vw);
}

/* Figma 275:2065. The angle, both stop colours and both stop positions are
   the frame's own, note the second stop sits at 150.39%, past the box, so
   the visible range is only the first two thirds of the ramp. */
.prof-disc-fig__card--gradient {
  background-image: linear-gradient(109.8640045102175deg,
      var(--pl-navy) 0.33153%,
      var(--pl-cyan) 150.39%);
}

.prof-disc-fig__card--pale {
  background-color: var(--pl-pale);
}

/* Figma "Frame 18": a 306px circle carrying no fill of its own, the card
   colour shows through. Sized against the viewport so it tracks the card's
   own padding, and aspect-locked so it is always round. */
.prof-disc-fig__icon {
  flex: none;
  width: max(96px, 17.7083vw);
  aspect-ratio: 1;
  border-radius: 50%;
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
}

/* Each artwork has its own proportions and Figma centres each on the circle
   at its own size, so these are per-icon percentages of the 306 circle. The
   height follows each SVG's viewBox, so none of them can be distorted. */
.prof-disc-fig__icon img {
  display: block;
  height: auto;
}

.prof-disc-fig__icon--what img    { width: 61.76%; }  /* 189/306 */
.prof-disc-fig__icon--how img     { width: 62.09%; }  /* 190/306 */
.prof-disc-fig__icon--matters img { width: 67.32%; }  /* 206/306 */
.prof-disc-fig__icon--choose img  { width: 70.26%; }  /* 215/306 */

/* Figma "Frame 14"/"Frame 17": fills the remaining measure, column, 25px gap.
   min-width: 0 is what lets a flex child actually shrink to it. */
.prof-disc-fig__body {
  flex: 1 1 0;
  min-width: 0;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: max(0.75rem, 1.4468vw);
}

/* Figma H3: Museo Sans Rounded 900 at 39/46. */
.prof-disc-fig__title {
  width: 100%;
  margin: 0;
  font-family: 'Nunito', sans-serif;
  font-weight: 900;
  font-size: var(--pl-fs-39);
  line-height: 1.17949;
}

/* Figma's text column holds exactly two children, the heading and ONE text
   node carrying every paragraph, so the column's 25px gap falls once, below
   the heading. Without this wrapper each <p> becomes a flex child and the gap
   repeats between them. */
.prof-disc-fig__copy {
  width: 100%;
}

/* Figma "Accroche": Myriad Pro Regular at 24/29. Figma separates paragraphs
   with a real blank line, a zero-width-space paragraph, not a margin. One
   blank line is exactly one line box, so the margin is 1 line height: as an
   em it stays one line at every type size. */
.prof-disc-fig__body p {
  margin: 0 0 1.20833em 0;
  font-family: 'Source Sans 3', sans-serif;
  font-weight: 400;
  font-size: var(--pl-fs-24);
  line-height: 1.20833;
}

.prof-disc-fig__body p:last-child {
  margin-bottom: 0;
}

/* Figma has no blank line between these two in "How PROF® Works", they run
   straight on. Every other pair in the section is separated. */
.prof-disc-fig__body p.is-tight {
  margin-bottom: 0;
}

.prof-disc-fig__card--gradient .prof-disc-fig__title  { color: #ffffff; }
.prof-disc-fig__card--gradient .prof-disc-fig__body p { color: var(--pl-pale); }
.prof-disc-fig__card--pale .prof-disc-fig__title      { color: var(--pl-navy); }
.prof-disc-fig__card--pale .prof-disc-fig__body p     { color: var(--pl-slate); }

/* ==========================================================================
   FEATURES: Figma frame 275:1236
   "Everything You Need in One Platform" (1728x1237)

   Was nine absolutely-placed items on a fixed-height canvas. The design
   staggers the middle row, x=214/614/1314 against 364/764/1164 above and
   below it, but that ±150px offset was dropped by request: all nine items
   sit on one regular three-column grid, so every circle lines up with the
   ones above and below it at any width.
   ========================================================================== */

.prof-feat-fig {
  container-type: inline-size;
}

.prof-feat-fig__canvas {
  --u: calc(100cqw / 1728);

  position: relative;
  /* The transformed gradient below is centred on the band and much larger
     than it, so this only backstops the corners while it paints. */
  background-color: #004B99;
  /* The frame's own padding is asymmetric: 100 above the heading, 76 below
     the last row of circles (1237 - 864 - 297). */
  padding-top: max(2.5rem, 5.787vw);
  padding-bottom: max(2rem, 4.3981vw);
  overflow: hidden;
}

/* The band is a Figma ANGULAR (conic) fill, not the linear one it reads as:
   #004B99 -> #00B3E4 across a single 360deg turn, which is what puts the hard
   seam across the lower left. Its matrix is reproduced rather than baked into
   an image, so the band stays vector at any size.

   The export wraps the gradient in a 1833.58px square centred on the frame
   and maps it with matrix(-0.9465 0.672262 -0.939101 -1.24066 864 618.052).
   864/618 is the frame's own centre, so anchoring at 50%/50% reproduces the
   translate without depending on the band still being 1237 tall. After the
   matrix the parallelogram measures ~2129 x 2853 design px about that centre,
   which covers the band with room to spare at any desktop height. */
.prof-feat-fig__canvas::before {
  content: "";
  position: absolute;
  z-index: 0;
  left: 50%;
  top: 50%;
  width: calc(1833.58 * var(--u));
  height: calc(1833.58 * var(--u));
  background: conic-gradient(from 90deg, #004B99 0deg, #00B3E4 360deg);
  transform-origin: 0 0;
  transform: matrix(-0.9465, 0.672262, -0.939101, -1.24066, 0, 0)
             translate(calc(-916.792 * var(--u)), calc(-916.792 * var(--u)));
}

/* Figma's four white swooshes at 7%, the frame clips them, which is why the
   asset carries the full 1728x1237 box rather than a tight one. cover instead
   of 100% 100% so they are never stretched when the band grows; at the band's
   own proportions that is the design's framing exactly. */
.prof-feat-fig__canvas::after {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  background-image: url("../img/prof/landing/features-swooshes.svg");
  background-size: cover;
  background-position: center;
  background-repeat: no-repeat;
}

/* Figma: 49/58.408 white, centred, text box at y=100 with the first row of
   circles at y=218. The 2px top margin is a font-substitution correction, not
   a design value: Nunito's ascent runs taller than Museo Sans Rounded's, so
   at y=100 the glyphs land 2px high of the export. The same +2 is applied to
   the trusted and FAQ headings. */
.prof-feat-fig__title {
  position: relative;
  z-index: 1;
  margin: max(0px, 0.1157vw) 0 max(1.75rem, 3.3329vw) 0;
  padding-inline: var(--pl-gutter);
  text-align: center;
  font-family: 'Nunito', sans-serif;
  font-weight: 900;
  font-size: var(--pl-fs-49);
  line-height: 1.192;
  color: #ffffff;
}

/* Figma: three 200px columns spanning x=364..1364, a 1000px measure with
   200px gutters, centred. A percentage column gap holds that 200:200 ratio
   at every width, so the grid is the design's proportions rather than its
   coordinates. */
.prof-feat-fig__grid {
  position: relative;
  z-index: 1;
  /* 1000 of 1728 is 57.87%. max() holds the design's 1000px measure up to the
     design width and then lets it grow with the page, so the circles keep
     their share of a larger screen instead of freezing; min() hands the
     gutter back on anything narrower than the measure. */
  width: min(calc(100% - 2 * var(--pl-gutter)), max(1000px, 57.87vw));
  margin-inline: auto;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  column-gap: 20%;
  /* Figma stacks the rows on a fixed 323px pitch. A row here is 273 tall
     (200 circle + 25 + a two-line label), so 50 of gap reproduces that pitch
     exactly, and a row whose label runs to three lines in French simply
     grows instead of colliding with the one below it. */
  row-gap: max(1.5rem, 2.8935vw);
  align-items: start;
}

.prof-feat-fig__item {
  text-align: center;
}

/* Figma: 200x200 circle, Bleu Très Claire. Each icon SVG carries a viewBox
   re-origined onto its own circle, so filling the badge places the artwork
   exactly where Figma drew it, no centring or per-icon sizing involved. */
.prof-feat-fig__badge {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  border-radius: 50%;
  background-color: var(--pl-pale);
  overflow: hidden;
}

.prof-feat-fig__badge img {
  display: block;
  width: 100%;
  height: 100%;
}

/* Figma: Myriad Pro Semibold 20/24 in Bleu Très Claire, NOT white, the same
   pale as the circles, starting 25px under a 200px circle, i.e. 12.5% of it. */
.prof-feat-fig__label {
  margin: 12.5% 0 0 0;
  font-family: 'Source Sans 3', sans-serif;
  font-weight: 600;
  font-size: var(--pl-fs-20);
  line-height: 1.2;
  color: var(--pl-pale);
}

/* ==========================================================================
   TRUSTED: Figma frame 275:1474 (1728x1200)

   The poster is full-bleed and aspect-locked. Figma draws a 1528x116 player
   bar over its lower edge; that chrome was removed by request, so the section
   is the heading over a clean image. The box stays position: relative for
   whatever real player replaces the poster (PRF-1184).
   ========================================================================== */

.prof-trust-fig {
  background-color: #ffffff;
  padding-top: max(2.5rem, 5.787vw);
}

/* Figma: 49/58.408 in Bleu, centred, text box at y=100 with the poster at
   y=228. Same +2 Nunito correction as the features heading. */
.prof-trust-fig__title {
  margin: max(0px, 0.1157vw) 0 max(1.75rem, 3.9120vw) 0;
  padding-inline: var(--pl-gutter);
  text-align: center;
  font-family: 'Nunito', sans-serif;
  font-weight: 900;
  font-size: var(--pl-fs-49);
  line-height: 1.192;
  color: var(--pl-navy);
}

/* Figma 275:1475: 1728x972, a 16:9 box, full-bleed. The photo is 3:2 and
   Figma's image matrix centres the overflow, which is exactly what cover
   does, so no object-position is needed to land the design's crop. */
/* Full-bleed, but the height stops at the design's 972: letting a 16:9 box
   follow a 2560px viewport would make the poster 1440px tall and swallow the
   screen. Past 1728 it holds 972 and the photo crops wider instead. */
.prof-trust-fig__video {
  position: relative;
  width: 100%;
  aspect-ratio: 1728 / 972;
  overflow: hidden;
}

.prof-trust-fig__video img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* ==========================================================================
   FAQ: Figma frame "Frequently Asked Questions" (1728x1648)

   Thirteen 1240x80 rows at x=244 on a 95px pitch, radius 20, 1px #98C1ED,
   the first one open over #EFFCFF at 46%.

   The rows were already a flow column so the accordion works; what was
   static was the row height. An 80px row is what the design's one-line
   English questions produce, so it is written as a min-height around real
   padding, a two-line French question grows the row instead of spilling
   out of it.
   ========================================================================== */

.prof-faq-fig {
  background-color: #ffffff;
  padding-block: max(2.5rem, 5.787vw);
}

/* Figma: 49/58.408 in Bleu, centred, text box at y=100 with the first row at
   y=218. Same +2 Nunito correction as the features heading. */
.prof-faq-fig__title {
  margin: max(0px, 0.1157vw) 0 max(1.75rem, 3.3333vw) 0;
  text-align: center;
  font-family: 'Nunito', sans-serif;
  font-weight: 900;
  font-size: var(--pl-fs-49);
  line-height: 1.192;
  color: var(--pl-navy);
}

/* 1240 centred on the 1528 content measure puts the column on the frame's
   x=244, and it goes fluid as soon as the window is narrower than that. */
.prof-faq-fig__list {
  width: min(100%, max(1240px, 71.7593vw));
  margin-inline: auto;
  display: flex;
  flex-direction: column;
  gap: max(8px, 0.868vw);
}

/* The stroke is centred on Figma's 1239x79 rect, so the row reads 1240x80
   with the line inside it, which is what border-box gives for a 1px border.
   1px is a genuinely fixed design property and is not scaled. */
.prof-faq-fig__item {
  border: 1px solid #98C1ED;
  border-radius: max(12px, 1.1574vw);
  background-color: #ffffff;
}

.prof-faq-fig__item[open] {
  background-color: rgba(239, 252, 255, 0.46);
}

/* Figma insets the contents 35 from the frame edge; 34 of padding plus the
   border lands on that. */
.prof-faq-fig__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: max(0.75rem, 1.1574vw);
  min-height: max(46px, 4.5139vw);
  padding: max(0.625rem, 1.1574vw) max(0.875rem, 1.9676vw);
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: var(--pl-fs-25);
  line-height: 1.192;
  color: var(--pl-slate);
  cursor: pointer;
  list-style: none;
}

/* Hide the native disclosure triangle in both engines. */
.prof-faq-fig__q::-webkit-details-marker {
  display: none;
}

.prof-faq-fig__q::marker {
  content: "";
}

/* Its own element so the summary always has exactly two flex items: any
   inline markup in the question (the ® span) would otherwise become a third
   and space-between would scatter the words across the row. */
.prof-faq-fig__text {
  min-width: 0;
  /* Nunito centres slightly higher in the row than Museo Sans Rounded does.
     Nudging the text rather than the row keeps the icon on the design's
     centre line; as an em it holds at every type size. */
  position: relative;
  top: 0.08em;
}

/* Figma draws the mark at the size and rise below rather than as a true
   superscript; both are measured off the export's glyph box. */
.prof-faq-fig__text .prof-landing__reg {
  font-size: 0.6em;
  vertical-align: 0.533em;
  line-height: 0;
}

/* Figma: a 20x20 plus in Paragraphe, 4 wide with round caps, its path box
   right-aligned on the 35px inset, so the caps overhang it by 2, which is
   why the SVG is allowed to overflow. */
.prof-faq-fig__sign {
  flex: 0 0 auto;
  display: block;
  width: max(14px, 1.1574vw);
  height: max(14px, 1.1574vw);
  color: var(--pl-slate);
}

.prof-faq-fig__sign svg {
  display: block;
  width: 100%;
  height: 100%;
  overflow: visible;
  transition: transform 0.15s ease;
}

/* The design's close mark is this same plus turned 45deg: its arms are the
   same 20 long and its ends land on the export's ±7.071 diagonal. */
.prof-faq-fig__item[open] .prof-faq-fig__sign svg {
  transform: rotate(45deg);
}

/* Figma: Myriad Pro 17/20 in Paragraphe, 20 between paragraphs, on the same
   35px inset as the question. */
.prof-faq-fig__a {
  padding: max(0.25rem, 0.3472vw) max(0.875rem, 1.9676vw)
           max(0.875rem, 1.3889vw);
  font-family: 'Source Sans 3', sans-serif;
  font-weight: 400;
  font-size: var(--pl-fs-17);
  line-height: 1.17647;
  color: var(--pl-slate);
}

.prof-faq-fig__a p {
  margin: 0 0 max(0.625rem, 1.1574vw) 0;
}

.prof-faq-fig__a p:last-child {
  margin-bottom: 0;
}

/* Only the left inset is set so the markers sit inside the answer's own
   padding rather than hanging into the row's edge. */
.prof-faq-fig__a ol {
  margin: 0;
  padding-left: max(1rem, 1.3889vw);
}

.prof-faq-fig__a li {
  margin-bottom: max(0.625rem, 1.1574vw);
}

.prof-faq-fig__a li:last-child {
  margin-bottom: 0;
}

/* ==========================================================================
   FOOTER: Figma frame (1728x573)

   The one section that was never built from the design; it was approximated
   until the export arrived. Every number below is the frame's own.

   Reading down the 1728 canvas:

     padding      130 top and bottom (logo top y=130, buttons bottom y=443)
     LEFT col     x=100, 530 wide
       heading    25/29.8 white, cap top y=136.25
       Log In     94x54 at (100,175), radius 10, white on Bleu
       heading    25/29.8 white, cap top y=295.25
       paragraph  17/20 in Bleu Tres Claire, two lines on the 530 measure
       Request..  182x54 at (100,389), radius 10
     RIGHT col    right edge x=1628, 390 wide
       logo       220 x 72.3193 at (1408,130)
       note       17/20, right-aligned, two lines
       legal      17px with a DOTTED underline (the export draws it as a run
                  of 0.85px dots on a 1.7px pitch), baseline y=437, pushed to
                  the bottom of the column so it lands level with the last
                  button

   Both pill widths (94 and 182) are the design's measured English widths and
   are NOT set here: the padding that produces them is, so French grows the
   pill instead of clipping it.
   ========================================================================== */

.prof-landing__footer {
  background-color: var(--pl-navy);
  color: #ffffff;
  /* Frame padding 130. */
  padding-block: max(2.5rem, 7.5231vw);
}

.prof-landing__footer-grid {
  display: flex;
  justify-content: space-between;
  gap: max(2rem, 3.7037vw);
  flex-wrap: wrap;
}

/* A flex column rather than a block: it makes the two pills block-level, so
   they size to their own content and cannot pick up the stray descender space
   an inline-flex button gets from the surrounding 1.6 line-height. */
.prof-landing__footer-left {
  flex: 1 1 max(440px, 25.463vw);
  /* The design's column is 530, which holds "Ready to Simplify Professional
     Water Analysis?" on one line in Museo Sans Rounded (527.2). Nunito sets
     the same string at 551.4, so a 530 column wraps it and the whole footer
     grows a line. The column is widened to 560 to keep the design's single
     line; the paragraph keeps its own 530 measure below, so its two-line wrap
     is unaffected. There is 578px of clear space to the right column, so this
     costs nothing. */
  max-width: max(560px, 32.4074vw);
  min-width: min(100%, 260px);
  display: flex;
  flex-direction: column;
  align-items: flex-start;
}

/* Right-aligned in the design: logo, the Sani Marc note, then the legal
   links. It left-aligns once it stacks, see the breakpoints block.

   flex-basis is deliberately `auto`, NOT the design's 390. 390 is the measure
   of the Sani Marc NOTE, and pinning the whole column to it also pinned the
   legal link row, which is a different kind of content: in English
   "Terms of Use" + "Privacy Policy" fit in 390, but in French
   "Conditions d'utilisation" + "Politique de confidentialité" need ~458 and
   the row broke onto two lines.

   The general rule this is an instance of: a measure taken from prose belongs
   on the prose, never on a container that also holds a row of short labels.
   Sizing the column to its widest child lets the link row stay on one line in
   any language, while the note keeps its own max-width below and the column
   still shrinks (flex-shrink stays 1) when the viewport demands it. */
.prof-landing__footer-right {
  flex: 0 1 auto;
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  text-align: right;
}

/* Museo Sans Rounded, so Nunito here, as everywhere else on this page. */
.prof-landing__footer-already,
.prof-landing__footer-cta-title {
  margin: 0;
  font-family: 'Nunito', sans-serif;
  font-weight: 700;
  font-size: var(--pl-fs-25);
  line-height: 1.192;
  color: #ffffff;
}

/* Heading box bottom 159.8 to the pill's y=175. */
.prof-landing__footer-already {
  margin-bottom: max(0.5rem, 0.8796vw);
}

/* Pill bottom 229 to the second heading's box top. */
.prof-landing__footer-cta-title {
  margin-top: max(1.5rem, 3.5012vw);
  margin-bottom: max(0.4rem, 0.735vw);
}

/* Myriad Pro, so Source Sans 3. 17/20 in Bleu Tres Claire. */
.prof-landing__footer-cta-text,
.prof-landing__footer-note,
.prof-landing__footer-legal a {
  font-family: 'Source Sans 3', sans-serif;
  font-weight: 400;
  font-size: var(--pl-fs-17);
  line-height: 1.17647;
  color: var(--pl-pale);
}

.prof-landing__footer-cta-text {
  margin: 0 0 max(0.75rem, 0.9838vw) 0;
  max-width: max(530px, 30.6713vw);
}

/* Figma 220 x 72.3193. height:auto so the lockup can never be distorted. */
.prof-landing__footer-logo {
  width: max(150px, 12.7315vw);
  height: auto;
  display: block;
}

/* Logo bottom 202.32 to the note's box top. */
.prof-landing__footer-note {
  margin: max(0.75rem, 1.7361vw) 0 0 0;
  max-width: max(390px, 22.5694vw);
}

/* margin-top:auto drops the row to the foot of the column, which is what puts
   it level with the Request a Demo pill as the design has it.

   The padding is the row's MINIMUM separation from the note above it, and it
   is padding rather than margin precisely so it does not fight that auto
   margin: where the column has slack the auto margin simply absorbs it, the
   box grows by the padding and its top edge rises by the same amount, so the
   links do not move and the design's alignment with the pill is unchanged.
   Where the column has no slack (the request-demo footer, whose left column
   is only a heading and a pill, so the right column sets the height) the auto
   margin resolves to 0 and this is the only thing keeping the links off the
   note. It matches the logo-to-note gap above, so the column keeps one
   rhythm. */
.prof-landing__footer-legal {
  display: flex;
  flex-wrap: wrap;
  gap: max(1rem, 2.7662vw);
  margin-top: auto;
  padding-top: max(0.75rem, 1.7361vw);
}

/* The export draws the underline as a run of dots, not a rule. */
/* Each link stays whole: if the row ever does have to wrap on a narrow screen
   it breaks between the links, never inside "Conditions d'utilisation". */
.prof-landing__footer-legal a {
  white-space: nowrap;
  text-decoration: underline;
  text-decoration-style: dotted;
  text-underline-offset: 3px;
}

.prof-landing__footer-legal a:hover,
.prof-landing__footer-legal a:focus {
  color: #ffffff;
}

/* ==========================================================================
   BREAKPOINTS

   Everything above is the fluid desktop composition. These three rules are
   the points where reflowing beats scaling: side-by-side stops fitting, the
   nav runs out of room, and a three-up grid stops being legible.
   ========================================================================== */

/* --------------------------------------------- tablet: 900px - 1199px */

/* Above this the page is the Figma composition, sized fluidly. Below 1200 it
   stops being one: the design's vertical rhythm is a fraction of a 1728px
   canvas, and carried down proportionally it leaves a tablet hero that is the
   right shape but mostly empty, the same 0.646 height-to-width ratio as
   desktop, which is the signature of a shrunk layout rather than a laid-out
   one. So the hero's lead-in and the tagline's well are compacted to what the
   content needs, and the copy takes a little width back off the card. */
@media (max-width: 1199px) {
  /* Sticky from tablet down. The bar is a direct child of .prof-landing, so
     it stays pinned for the whole page rather than unpinning at the end of
     the hero, and its opaque --pl-hero-top background is what lets content
     scroll under it. The Figma drop-shadow is dropped here: it silhouettes
     the logo and pill, which reads as grime once the bar has a real
     background, so the bar takes an edge shadow of its own instead. */
  .prof-hero-fig__nav {
    position: sticky;
    top: 0;
    padding-top: max(0.45rem, 1.3vw);
    padding-bottom: max(0.45rem, 1.3vw);
    /* Frosted rather than flat: content reads through the bar as it scrolls
       under, which is what stops a pinned bar feeling like a lid. The alpha is
       high enough that navy-on-pale stays legible over the dark water band. */
    background-color: rgba(237, 251, 255, 0.88);
    backdrop-filter: blur(14px) saturate(1.4);
    -webkit-backdrop-filter: blur(14px) saturate(1.4);
    /* A hairline to sit the bar on, plus a soft lift that only shows once
       something is behind it. */
    box-shadow: 0 1px 0 rgba(0, 75, 153, 0.08),
                0 10px 30px -18px rgba(0, 60, 120, 0.45);
  }

  /* One shadow is enough once the bar has an edge shadow of its own. */
  .prof-hero-fig__nav-inner {
    filter: none;
  }

  .prof-hero-fig__main {
    /* Content-driven, instead of the design's 123.65 scaled down. */
    padding-top: clamp(1.25rem, 3.5vw, 3rem);
    grid-template-columns: minmax(0, 1fr) minmax(0, 0.9fr);
    column-gap: clamp(1rem, 2.5vw, 2rem);
  }

  /* The well only has to clear the crest (whose deepest point is 344.7 design
     px) and give the tagline air, not reproduce the design's 475. */
  .prof-hero-fig__water {
    margin-top: calc(-300 * var(--u));
    padding-top: max(calc(390 * var(--u)), 5rem);
    padding-bottom: max(calc(116 * var(--u)), 2.25rem);
  }

  /* Cards: the design's 60/90 side padding is generous for a tablet measure
     and eats the text column. */
  .prof-disc-fig__card {
    padding: clamp(1.5rem, 3.25vw, 2.75rem);
    gap: clamp(1.25rem, 2.5vw, 2.25rem);
  }
}

/* ------------------------------------------------------- tablet: < 900px */
@media (max-width: 899px) {
  /* Hero: the copy/card split stops working once the card is under ~350px,
     so they stack. The card centres and takes a readable maximum rather than
     stretching across a tablet. */
  .prof-hero-fig__main {
    grid-template-columns: minmax(0, 1fr);
    row-gap: clamp(1.75rem, 5vw, 3rem);
    padding-top: clamp(1.5rem, 4vw, 2.5rem);
  }

  .prof-hero-fig__card {
    width: 100%;
    max-width: 560px;
    margin: 0 auto;
  }

  .prof-hero-fig__text {
    max-width: 42rem;
  }

  /* Intro: bullets move under the copy. */
  .prof-intro-fig__inner {
    grid-template-columns: minmax(0, 1fr);
    row-gap: clamp(1.5rem, 4vw, 2.5rem);
  }

  /* Cards: icon over copy. The circle keeps its own scale rather than
     stretching to the card width. */
  .prof-disc-fig__card {
    flex-direction: column;
    align-items: flex-start;
    gap: clamp(1rem, 3vw, 1.75rem);
  }

  .prof-disc-fig__icon {
    align-self: center;
    width: clamp(120px, 30vw, 240px);
  }

  /* Features: the design's 200:200 column-to-gutter ratio leaves the circles
     too small to read once the grid is this narrow, so the gutter gives way
     to the columns rather than the other way round. */
  .prof-feat-fig__grid {
    column-gap: 12%;
  }

  /* The band's artwork is built around the frame's 1728x1237 proportions, and
     once it stacks into a tall column neither layer reaches its corners: the
     gradient's transformed square is sized off the band's WIDTH, and the
     swooshes zoom to a fragment under cover. So below this width the gradient
     is drawn as a plain angular fill of the whole band, same two colours,
     same seam pointing down-left, just without the matrix that assumed a
     landscape frame, and the swooshes render at their own proportions across
     the width instead of being blown up. */
  .prof-feat-fig__canvas::before {
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;
    transform: none;
    background: conic-gradient(from 234.6deg at 50% 50%, #004B99 0deg, #00B3E4 360deg);
  }

  .prof-feat-fig__canvas::after {
    background-size: 100% auto;
    background-position: center;
  }
}

/* The section's one remaining desktop-only rule. Declared as a min-width rule
   so the overhang is never applied and then undone. */
@media (min-width: 900px) {
  /* The one label the design does not run inside the 200px circle measure:
     its longest line is ~356px, so Figma widens the box to 380 on a 200px
     column, a 90px overhang either side, into the grid's own 200px gutter,
     so it cannot reach a neighbour.

     The overhang is capped at the page gutter rather than written as a flat
     190%/-45%: from 1728px up the grid is centred with plenty of band either
     side, but at ~1024 the grid fills the viewport and a proportional
     overhang runs off the edge, where the band's overflow: hidden clips it. */
  .prof-feat-fig__item--push .prof-feat-fig__label {
    --pl-over: 5.2083vw;
    width: calc(100% + 2 * var(--pl-over));
    margin-left: calc(-1 * var(--pl-over));
  }
}

/* ------------------------------------------- nav: two tiers below 768px

   Measured rather than guessed: the bar's own content (logo + links + flags +
   pill + gaps) needs ~525px in English and ~575px in French, so a single row
   is still comfortable at 768 (690px of container, ~100px of slack for a
   longer translation) and only runs out below ~660. Above this breakpoint the
   bar therefore stays one row, which is what a tablet should get; below it,
   the links take a tier of their own.

   The second tier is a deliberate structure, not a wrap: a hairline rule
   separates it, and space-between lands the first link on the same left edge
   as the logo and the last on the same right edge as the pill, so the two
   tiers read as one grid instead of as an accident.
   ========================================================================== */
@media (max-width: 767px) {
  /* Bounded at both ends: a bare vw here sized the logo at 199px on a 767px
     window and 90px on a 375px one. */
  .prof-hero-fig__logo {
    width: clamp(104px, 15vw, 132px);
  }

  .prof-hero-fig__nav-inner {
    row-gap: 0;
  }

  /* Tier 1 keeps the logo, flags and pill. The flags get their own breathing
     room from the pill rather than sharing the row's tighter gap. */
  .prof-hero-fig__lang {
    margin-right: 0.6rem;
  }

  /* space-between fills the row on a phone, where the links all but span it.
     The max-width stops them scattering across a 700px tablet, where the run
     is only ~230px wide: the rule above still spans the full container, so a
     centred row under it reads as structure rather than as leftovers. */
  .prof-hero-fig__links {
    order: 1;
    width: 100%;
    max-width: 30rem;
    margin-top: 0.45rem;
    margin-inline: auto;
    justify-content: space-between;
    gap: 0.35rem 0.75rem;
    padding-top: 0.45rem;
    border-top: 1px solid rgba(0, 75, 153, 0.12);
  }

  /* The design's middot separators only read on one line. */
  .prof-hero-fig__sep {
    display: none;
  }

  /* Comfortable tap targets: the padding takes each link to ~40px of hit area
     without changing the type. */
  .prof-hero-fig__links a {
    padding: 0.3rem 0;
  }

  .prof-hero-fig__btn--login {
    min-height: 40px;
  }
}

/* ------------------------------------------- footer: 600px - 1199px

   The footer's two columns fit side by side down to 1024. They used to stack
   below 900, but stacking is the worse layout here rather than a narrower one:
   both columns go full width and left-align, and the right column is short (a
   logo, a two-line note, two links), so it leaves most of a full-width band
   empty down its right side. The stack point is therefore pushed down to 600
   and this range keeps the two columns by compressing them instead.

   Two sub-ranges, because a different thing limits each end:

   900-1199: flex-wrap alone dropped the right column onto its own line, where
   it sized to its content (~390) and sat at the LEFT of that line while still
   right-aligning its own text, leaving 406-458px of dead space. nowrap keeps
   them side by side; the right column holds its content width, the left takes
   what is left, a 373/390 split at 900.

   600-899: the right column can no longer have its content width. ~390 of the
   531px container at 600 would leave the left one ~108px, so both columns take
   a stated share instead. The legal row was what set that 390 floor and it
   turns out not to need one: it is already flex-wrap: wrap over nowrap links,
   so in French it breaks between "Conditions d'utilisation" and "Politique de
   confidentialite" instead of forcing the column wider.
   ========================================================================== */
@media (min-width: 900px) and (max-width: 1199px) {
  .prof-landing__footer-grid {
    flex-wrap: nowrap;
  }

  .prof-landing__footer-left {
    flex: 1 1 0;
    min-width: 0;
    max-width: none;
  }

  .prof-landing__footer-right {
    flex: 0 0 auto;
    min-width: 0;
  }
}

@media (min-width: 600px) and (max-width: 899px) {
  .prof-landing__footer-grid {
    flex-wrap: nowrap;
    /* The design's 3.7% gutter is worth more as column width down here. */
    gap: max(1.5rem, 3.7037vw);
  }

  /* A stated share rather than the content-driven split above: the left
     column carries the prose, so it keeps the larger half. */
  .prof-landing__footer-left {
    flex: 1 1 55%;
    min-width: 0;
    max-width: none;
  }

  .prof-landing__footer-right {
    flex: 1 1 45%;
    min-width: 0;
  }
}

/* ------------------------------------------------ short viewports: <= 430px

   The bar is sticky from 1199px down, and below 767 it is two tiers tall. On a
   phone held sideways that combination is measured at 98px of a 320px
   viewport, ~31%, and it never goes away: a third of the screen is permanently
   header. The same thing happens to a desktop user at 250-300% browser zoom,
   where the CSS viewport is only 300-360px tall.

   Height is the honest thing to test here, not width, so the bar simply stops
   being sticky once there is not enough height to spare and scrolls away like
   any other content. Nothing about how it looks changes; only whether it
   stays pinned. Above this height the sticky behaviour is untouched. */
@media (max-height: 430px) {
  .prof-hero-fig__nav {
    position: static;
  }
}

/* -------------------------------------------------------- phone: < 600px */
@media (max-width: 599px) {
  /* Three 100px circles are too small to read; two is the honest layout. */
  .prof-feat-fig__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    column-gap: 12%;
    row-gap: clamp(1.25rem, 5vw, 2rem);
  }

  /* Footer: only here does the band genuinely run out of room for two columns
     (they would be ~230px each side of the gap), so this is where it stacks.
     Right-aligned text on a full-width column reads as a mistake, so the right
     column left-aligns with the left one and the legal row stops being pushed
     to the foot of its column. */
  .prof-landing__footer-grid {
    flex-direction: column;
    gap: clamp(2rem, 6vw, 3rem);
  }

  .prof-landing__footer-left,
  .prof-landing__footer-right {
    flex: 1 1 auto;
    width: 100%;
    max-width: none;
  }

  .prof-landing__footer-right {
    align-items: flex-start;
    text-align: left;
  }

  .prof-landing__footer-legal {
    margin-top: 0;
    padding-top: clamp(1rem, 5vw, 2rem);
  }
}

/* ==========================================================================
   REQUEST A DEMO (PRF-1184)

   A separate page (request_demo.html) that reuses this file's tokens so the
   form reads as the same brand surface. The .prof-landing__hero / __header /
   __nav rules below are that page's chrome, the landing page's own hero no
   longer uses them.

   This block was originally written in a different idiom from the rest of the
   file, clamp(rem, vw, rem) with px caps against the max(rem, vw) tokens used
   everywhere else, and that produced a bug rather than just an inconsistency:
   .prof-demo__wrap carried BOTH .prof-landing__shell's vw-based
   padding-inline AND max-width: 900px, and under the page's
   box-sizing: border-box the cap applies to the border box. So the growing
   gutter was subtracted from a frozen outer width and the form got NARROWER
   as the window got WIDER (900 - 2 x gutter: 752px at 1280, 560px at 2940),
   eventually squeezing the two-column field grid into one column.

   So the measure is now a ratio like every other container here, and the type
   and spacing use the shared tokens, which is what keeps the form growing
   with the nav and footer above the design width instead of freezing.
   ========================================================================== */

.prof-landing__hero {
  position: relative;
  background-color: var(--pl-hero-end);
  background-image: linear-gradient(180deg, var(--pl-hero-top) 0%, var(--pl-hero-mid) 37%, var(--pl-hero-end) 100%);
  background-size: 100% 64.64vw;
  background-repeat: no-repeat;
  display: flex;
  flex-direction: column;
}

.prof-demo__hero {
  padding-bottom: max(3rem, 5.0926vw);
}

/* The form's own measure, and deliberately NOT .prof-landing__shell's: the
   page's other sections align to the 1528px content measure, a form does not.
   900 of the design's 1728 canvas is 52.083%, and this is the same min/max
   pattern .prof-feat-fig__grid uses. max() holds the design's 900px measure
   up to the design width and then lets it grow on the canvas ratio, so the
   form tracks the nav and footer above 1728 instead of stranding itself;
   min() hands the gutter back on anything narrower than the measure.

   Written as width rather than max-width so the gutter is subtracted by the
   min() branch instead of by padding inside a frozen cap. That is what makes
   this monotonic: the form never shrinks as the window grows. */
.prof-demo__wrap {
  width: min(calc(100% - 2 * var(--pl-gutter)), max(900px, 52.083vw));
  margin-inline: auto;
  padding-top: max(2.5rem, 4.1667vw);
}

.prof-demo__title {
  color: var(--pl-navy);
  font-weight: 700;
  font-size: var(--pl-fs-49);
  line-height: 1.15;
  margin: 0 0 max(1rem, 0.9259vw) 0;
}

.prof-demo__lead {
  color: var(--pl-slate);
  font-size: var(--pl-fs-17);
  margin: 0 0 max(1.75rem, 2.3148vw) 0;
  /* A reading measure, so it scales on the same ratio rather than holding
     40rem while the type around it grows. */
  max-width: max(40rem, 37.037vw);
}

.prof-demo__card {
  background-color: #ffffff;
  border-radius: max(12px, 1.2731vw);
  box-shadow: 0 20px 50px rgba(0, 60, 120, 0.14);
  padding: max(1.5rem, 2.5463vw);
}

.prof-demo__card--done {
  text-align: center;
}

.prof-demo__card--done .prof-demo__lead {
  margin-left: auto;
  margin-right: auto;
}

/* Two columns, the design's pairing: first/last, email/phone, name/location.

   This was auto-fit over minmax(240px, 1fr), which collapsed on its own but
   only held at two columns because the card was capped at 900px. Now that the
   card grows with the canvas that same rule would keep ADDING columns, five
   of them at 2940px, and break the pairing. So the column count is stated and
   the collapse to one column is a breakpoint (see the phone block), which is
   where the old rule folded anyway: it ran out of room at ~620px. */
.prof-demo__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: max(1rem, 1.3889vw);
}

.prof-demo__field--full {
  grid-column: 1 / -1;
}

.prof-demo__field label {
  display: block;
  color: var(--pl-navy);
  font-size: var(--pl-fs-13);
  font-weight: 700;
  margin-bottom: max(0.4rem, 0.3704vw);
}

.prof-demo__req {
  color: #c0392b;
}

.prof-demo__input {
  width: 100%;
  border: 1px solid var(--pl-border);
  border-radius: max(6px, 0.463vw);
  padding: max(0.6rem, 0.6481vw) max(0.75rem, 0.8333vw);
  font-family: inherit;
  font-size: var(--pl-fs-17);
  color: #12223A;
  background-color: #ffffff;
  box-sizing: border-box;
}

.prof-demo__input:focus {
  outline: none;
  border-color: var(--pl-navy);
  box-shadow: 0 0 0 3px rgba(0, 75, 153, 0.12);
}

.prof-demo__input::placeholder {
  color: #9bacbd;
}

textarea.prof-demo__input {
  resize: vertical;
  min-height: max(7rem, 6.4815vw);
}

.prof-demo__hint {
  color: #7d8fa0;
  font-size: var(--pl-fs-13);
  margin: max(0.35rem, 0.3241vw) 0 0 0;
}

.prof-demo__error {
  color: #c0392b;
  font-size: var(--pl-fs-13);
  margin: max(0.35rem, 0.3241vw) 0 0 0;
}

.prof-demo__alert {
  background-color: #fdecec;
  color: #c0392b;
  border-radius: max(6px, 0.463vw);
  padding: max(0.75rem, 0.6944vw) max(1rem, 0.9259vw);
  font-size: var(--pl-fs-13);
  margin: 0 0 max(1.25rem, 1.1574vw) 0;
}

.prof-demo__consent {
  display: flex;
  align-items: flex-start;
  gap: max(0.6rem, 0.5556vw);
  margin-top: max(1.25rem, 1.6204vw);
  color: var(--pl-slate);
  font-size: var(--pl-fs-17);
  cursor: pointer;
}

/* The box tracks the label it sits next to, so the two stay proportional
   instead of the tick shrinking against the text on a large screen.

   The floor is the design's own 17px, NOT a smaller number: 0.9838vw only
   overtakes it above ~1730px, so a lower floor would shrink the box on every
   phone and tablet rather than leaving the design untouched and growing it on
   a large screen, which is the whole point of the pair. */
.prof-demo__consent input {
  margin: 0.2rem 0 0 0;
  width: max(17px, 0.9838vw);
  height: max(17px, 0.9838vw);
  accent-color: var(--pl-navy);
  flex: 0 0 auto;
}

/* Honeypot: off-screen rather than display:none, since some bots skip fields
   that are explicitly hidden. */
.prof-demo__hp {
  position: absolute;
  left: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

.prof-demo__submit {
  margin-top: max(1.5rem, 1.8519vw);
  border: none;
  font-family: inherit;
}

/* ------------------------------------------------------- demo: < 600px

   This page's breakpoint has to live at the end of its own block rather than
   with the other phone rules further up: this whole section is appended after
   every media query in the file, so an override placed up there loses to the
   base rules below it on source order at equal specificity. */
@media (max-width: 599px) {
  /* Paired fields need ~240px a column; below this the card cannot give them
     that, which is where the old auto-fit rule folded on its own. */
  .prof-demo__grid {
    grid-template-columns: minmax(0, 1fr);
  }
}