@import url("/assets/fa/fontawesome.min.css");
@import url("/assets/fa/solid.min.css");

/* Size calculator.
   Reuses the site tokens from site.css: --blue (navy), --snow (page), --ink,
   --muted, --line, --sans. No new fonts or libraries beyond the Font Awesome
   solid set the landing page already self-hosts.

   Asset measurements this file depends on, taken from the artwork itself:
     background   948x992   peaks across the full width, snow is the bottom ~15%
     skier       1024x1536  opaque content x 6.9%-77.4%, y 2.1%-98.7%
   Neither image is ever given both a width and a height, so neither distorts. */

/* The scene is absolutely positioned, so it needs a positioned ancestor of its
   own; without this it would anchor to the initial containing block and sit at
   the top of the document rather than behind this section. */
.sz-shell{
  position: relative;

  /* Moves the WHOLE illustration right: skier, skis, both dotted rules and
     every label. Those four are positioned with `right` as a percentage of the
     scene, and all four subtract this one number, so the group slides together
     and not a single internal gap changes. It lives HERE, not on .sz-scene,
     because the recommendation column's width calc reads it too and that column
     is a sibling of the scene, not a child. Raise it to push the illustration
     further right; the limit is the ski-length labels, which have about 50px of
     room left at 1280px wide. */
  --sz-shift: 0.06;
  /* How much narrower the gap between the character and the equipment is than
     the artwork's own spacing. One rendered adult ski is 5% of the scene's
     width (33.7px in a 1500px window, measured on the adult male pair), so this
     closes the gap by exactly one ski width. Half comes off each side: the character moves right, the
     equipment moves left, so the composition's centre does not move and the
     orange button stays centred under it. Percentages of the scene, not pixels,
     so the same visual intent holds at every window width. One dial, applied to
     all six combinations; set it to 0 to restore the original spacing. */
  --sz-gap-close: 5%;

  /* Where the scene box starts, measured from the top of this shell. .sz-page's
     own padding-top is 26px, so this is also the distance to the "YOUR
     RECOMMENDATION" eyebrow: 11px puts the top of the mountain 15px above it and
     leaves clean white between the header and the picture. Everything in the
     composition -- skier, skis, both dotted rules, every label -- is positioned
     against the scene box, so this one number moves the whole group and changes
     nothing inside it. */
  --sz-scene-top: 11px;

  /* The call to action, which belongs to the illustration rather than the prose.
     --sz-cta-centre is its centre as a fraction of the scene width measured from
     the scene's right edge: the midpoint between the skier's left edge and the
     ski pair's right edge works out at 42.9%-44.2% across desktop widths, so one
     constant centres it on the group everywhere. --sz-cta-drop is the clearance
     below the boot/tail ground line. */
  --sz-cta-centre: 0.435;
  --sz-cta-drop: 44px;
}/* The comp's page is solid white, not the site's off-white paper. Scoped to this
   page through the layout's bodyClass hook so no other page is affected. */
body.sz-white{ background: #FFFFFF; }/* ---------------------------------------------------------------- the scene */
/* Full-bleed landscape sitting behind the page. It is masked with a single
   radial gradient so its edges dissolve into the page on every side: no
   rectangle, no rounded card, no straight seam. */
.sz-scene{
  position: absolute;
  /* Only as wide as the reveal. When this spanned the full viewport, cover had
     to scale a near-square photo to fill a 1.78-wide box and cropped 46% off
     the top, taking the peaks with it. Half-width leaves the whole image height
     visible at every size. */
  top: var(--sz-scene-top, -24px);
  left: 55%;
  right: 0;
  height: clamp(403.2px, 52.2vw, 648px);
  z-index: 0;
  pointer-events: none;
  overflow: visible;
}.sz-scene__bg{
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;              /* one uniform scale, crops, never distorts */
  object-position: 74% 100%;      /* snow pinned to the floor, under his boots */
  /* With the narrower box there is no vertical overflow left to crop, so the
     peaks and the snow are both in frame; this now only trims ~7% of width. */
  /* A single radial reveal centred on the skier. Sized so the photograph is
     already at zero alpha by ~46% of the viewport, which puts the whole left
     column and the recommendation on clean white with no edge to see. The
     bottom stays near-opaque on purpose: that part of the photo is white snow,
     so it meets the white page invisibly, whereas the dark sky and peaks at the
     top and left are where a hard edge would show, and those fade to nothing.

     The ellipse is taller than wide and sits higher than centre (was 66% 66%).
     Widening it instead would have revealed the photo across the whole left
     flank, including behind the small grey body text; raising and stretching it
     vertically lifts the reveal only where the peaks meet the big number. The
     radii's horizontal term and every colour stop are unchanged, so the left
     edge of the fade and its smoothness are exactly as before. */
  -webkit-mask-image: radial-gradient(64% 70% at 72% 60%,
      #000 0%, #000 30%, rgba(0, 0, 0, 0.95) 48%,
      rgba(0, 0, 0, 0.7) 66%, rgba(0, 0, 0, 0.32) 84%, rgba(0, 0, 0, 0) 100%);
  mask-image: radial-gradient(64% 70% at 72% 60%,
      #000 0%, #000 30%, rgba(0, 0, 0, 0.95) 48%,
      rgba(0, 0, 0, 0.7) 66%, rgba(0, 0, 0, 0.32) 84%, rgba(0, 0, 0, 0) 100%);
}/* ------------------------------------------------- the shared ground anchor */
/* Every character stands on ONE point in the composition. The anchor is a
   property of the scene, not of any character, so switching character cannot
   move it. Values reproduce the male skier's existing boot position exactly, so
   nothing shifted when this system replaced his hard-coded offsets.

   Each character then supplies four numbers, written by the script from the
   measured config in size-calculator.js (search CHARACTERS):
     --ch       content height as a fraction of the image  (strips the padding)
     --stature  how tall this character stands vs an adult (children are 0.76)
     --cx       translateX %, puts the BOOT CENTRE on the anchor
     --foot     translateY %, puts the BOOT SOLE  on the anchor
   The boot centre is measured from the lowest 2.5% of each figure, not from the
   whole silhouette, because outstretched poles and arms skew the overall centre
   by up to 11% of the image width.

   Because the element is sized from its CONTENT height, images with different
   amounts of transparent padding end up the same real size on screen; because
   both offsets are percentages of the element's own box, they rescale with it
   and stay correct at any viewport. */
.sz-scene{
  --anchor-right: 60.4%;    /* boot centre, from the scene's right edge  */
  --anchor-bottom: 9.05%;  /* boot sole,  from the scene's bottom edge  */
  --fig-h: 59.46%;          /* adult CONTENT height, as % of scene height */

}.sz-scene__figure{
  position: absolute;
  right: calc(var(--anchor-right) - var(--sz-shift, 0) * 100% - var(--sz-gap-close, 0%) / 2);
  bottom: var(--anchor-bottom);
  /* Height is derived from the shared content height, so transparent padding
     never changes how big a character looks. */
  height: calc(var(--fig-h) * var(--stature, 1) / var(--ch, 1));
  aspect-ratio: 1024 / 1536;   /* all six share this frame; ratio is preserved */
  transform: translate(var(--cx, 50%), var(--foot, 0%));
}.sz-scene__skier{
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;         /* belt and braces: never distorts */
}/* ------------------------------------------------------- the ski assembly */
/* Two independent skis, side by side, inside one box whose bottom edge sits on
   the same ground anchor as the skier's boots.

   The four PNGs each contain BOTH skis side by side with a gap baked in. Rather
   than stretch that combined image, every section is rendered twice as a CSS
   sprite window: an overflow:hidden box showing one column band of an oversized
   absolutely-positioned <img>. Left and right windows differ only in the img's
   `left`, so the two skis can be placed at any separation without distorting a
   single pixel of source art. Source PNGs are untouched.

   Sizing is expressed entirely in terms of --fig-h, which IS the skier's visible
   height as a share of the scene (the figure element divides out its own
   transparent padding), so one centimetre is the same number of pixels for the
   skier and the skis at every viewport, and the responsive --fig-h overrides
   carry through automatically.

     height = --fig-h x --ski-len-ratio
       where --ski-len-ratio = recommended midpoint cm / the user's SELECTED
       height cm. There is no fixed centimetre reference.
     aspect-ratio = --ski-ar, written by the script as a plain number (calc()
       inside aspect-ratio is not safe in every engine), so the pair's width
       stays put while the height tracks the recommendation.

   Tips and tails are fixed-aspect; only the middle stretches (flex: 1), so the
   total height is exactly what the sizing formula determines and the joins meet
   with no step in width (the art measures 101px at the tips/middle join and
   96px at the middle/tails join in both files). */
.sz-skis{
  position: absolute;
  right: calc(var(--ski-right, 31.5%) - var(--sz-shift, 0) * 100% + var(--sz-gap-close, 0%) / 2);  /* SKI.RIGHT */
  bottom: var(--anchor-bottom);          /* the skier's ground plane */
  transform: translateX(50%);            /* centre the pair on --ski-right */
  height: calc(var(--fig-h) * var(--ski-len-ratio, 1));
  aspect-ratio: var(--ski-ar, 0.16);
  pointer-events: none;
  z-index: 1;
  transition: height .25s ease, aspect-ratio .25s ease;

  /* How far the middle section reaches INTO its neighbours at each join. The
     three sections are separate clipped boxes with fractional heights, so their
     shared edges land mid-device-pixel and each is antialiased independently,
     which let a hairline of background show through at both joins. The source
     art is not the cause: alpha is 255 on both rows at each join and the colours
     match to within one level out of 255. Raise to 2px only if a hairline ever
     reappears. */
  --seam-overlap: 1px;
}.sz-skis[hidden]{ display: none; }/* One ski. Both are centred on the pair's centre and pushed out symmetrically
   by --half-sep-pct, so widening the gap never shifts the pair sideways. */
.sz-ski{
  position: absolute;
  top: 0;
  height: 100%;
  width: var(--ski-w-pct, 46%);
  display: flex;
  flex-direction: column;
  justify-content: flex-end;   /* grow upward from the ground anchor: any
                                  sub-pixel remainder lands at the tips, never
                                  under the tails */
  align-items: center;
  transform: translateX(-50%);
}.sz-ski--l{ left: calc(50% - var(--half-sep-pct, 24%)); }.sz-ski--r{ left: calc(50% + var(--half-sep-pct, 24%)); }/* Each section is a sprite window onto one column band of its PNG.

   These are listed as single classes on purpose. An earlier `.sz-ski > div`
   shorthand carried a type selector, which outranked the single-class rules
   below it and silently forced `flex: none` onto the middle (collapsing it to
   zero, since its img is out of flow) and `position: relative` onto the
   bindings. Keep every rule in this section at single-class specificity. */
.sz-ski__tips,
.sz-ski__middle,
.sz-ski__tails,
.sz-ski__bind{ overflow: hidden; }.sz-ski__tips,
.sz-ski__middle,
.sz-ski__tails{ position: relative; }.sz-ski img{ position: absolute; display: block; max-width: none; }.sz-ski__tips{ width: 100%;    aspect-ratio: 115 / 395; flex: 0 0 auto; }.sz-ski__tails{ width: 96.522%; aspect-ratio: 111 / 483; flex: 0 0 auto; }/* The only section that stretches. Its height is whatever is left once the
   fixed tips and tails are laid out, which is exactly
   total - tips - tails from skiMetrics(). */
.sz-ski__middle{
  width: 87.826%;
  flex: 1 1 auto;
  min-height: 0;
  /* Negative margins, not a taller box: in a flex column a negative margin
     hands that space back as free space, which flex-grow then returns to this
     same item. The middle's border box therefore grows by 2 x --seam-overlap
     while its OUTER size, and so the stack's total height, is unchanged. The
     three sections still sum to exactly the length skiMetrics() asked for, and
     the tips top and tails bottom do not move. Paint order does the rest: the
     middle covers the tips' bottom edge, the tails cover the middle's bottom
     edge, and both covering rows are fully opaque art, so no darker band. */
  margin-top: calc(-1 * var(--seam-overlap, 1px));
  margin-bottom: calc(-1 * var(--seam-overlap, 1px));
}/* Vertical: crop each canvas down to its alpha bounding box.

   The middle is the only section whose crop sits in the INTERIOR of its canvas:
   row 399 above its band and row 704 below it are fully transparent, while the
   tips and tails crops end at their canvas edges, where sampling clamps. Under
   the ~4x upscale a device-pixel-ratio 2 display samples across that boundary
   and mixes those transparent texels into the first rendered row, leaving a
   part-transparent line that the background showed through. That, not a gap and
   not the art, was the hairline at both joins: it is invisible at ratio 1 and
   visible on a retina screen. Fixed by sampling rows 401..702 instead of
   400..703, so the band never touches a transparent neighbour.
     height = 1191 / 302,  top = -401 / 302 */
.sz-ski__tips img{ height: 101.266%; top: -1.266%; }.sz-ski__middle img{ height: 394.371%; top: -132.781%; }.sz-ski__tails img{ height: 100.828%; top: 0; }/* Horizontal: same image, two different bands. */
.sz-ski--l .sz-ski__tips img{ width: 360.000%;  left: -78.261%; }.sz-ski--r .sz-ski__tips img{ width: 360.000%;  left: -182.609%; }.sz-ski--l .sz-ski__middle img{ width: 1306.931%; left: -543.564%; }.sz-ski--r .sz-ski__middle img{ width: 1306.931%; left: -662.376%; }.sz-ski--l .sz-ski__tails img{ width: 400.000%;  left: -93.694%; }.sz-ski--r .sz-ski__tails img{ width: 400.000%;  left: -201.802%; }/* ---- the adult female set -----------------------------------------------
   Her own tips, middle and tails. The binding rules are deliberately NOT
   overridden here: this set uses the male bindings file, so it inherits the
   male band constants from the rules above.

     tips   336x490 : bands x41..159 / x167..285 (119 wide), art rows 3..489
     middle 1321x1191: bands x546..646 / x672..772 (101), art rows 490..619
     tails  316x571 : bands x39..154 / x164..280 (116), art rows 0..567

   Tips end 101px wide and the middle is 101; the middle ends 100px and the
   tails begin 100px, so the sections tile with no step. */
.sz-skis[data-set="female"] .sz-ski__tips{ aspect-ratio: 119 / 487; }.sz-skis[data-set="female"] .sz-ski__middle{ width: 84.874%; }.sz-skis[data-set="female"] .sz-ski__tails{ width: 97.479%; aspect-ratio: 116 / 568; }/* Vertical crops. The middle band is inset by one pixel (rows 491..618 rather
   than 490..619) for the same reason as the other two sets: so the upscale never
   samples the transparent rows either side of it. */
.sz-skis[data-set="female"] .sz-ski__tips img{ height: 100.616%; top: -0.616%; }.sz-skis[data-set="female"] .sz-ski__middle img{ height: 930.469%; top: -383.594%; }.sz-skis[data-set="female"] .sz-ski__tails img{ height: 100.528%; top: 0; }/* Horizontal: one band width for both skis, so they render identically. */
.sz-skis[data-set="female"] .sz-ski__tips img{ width: 282.353%; }.sz-skis[data-set="female"] .sz-ski__middle img{ width: 1307.921%; }.sz-skis[data-set="female"] .sz-ski__tails img{ width: 272.414%; }.sz-skis[data-set="female"] .sz-ski--l .sz-ski__tips img{ left: -34.454%; }.sz-skis[data-set="female"] .sz-ski--r .sz-ski__tips img{ left: -140.336%; }.sz-skis[data-set="female"] .sz-ski--l .sz-ski__middle img{ left: -540.594%; }.sz-skis[data-set="female"] .sz-ski--r .sz-ski__middle img{ left: -665.347%; }.sz-skis[data-set="female"] .sz-ski--l .sz-ski__tails img{ left: -33.621%; }.sz-skis[data-set="female"] .sz-ski--r .sz-ski__tails img{ left: -141.379%; }/* ---- the child set -------------------------------------------------------
   Same assembly, same flex stack, same binding placement, same seam overlap:
   only the sprite constants change, because the child artwork has its own
   canvas sizes and column bands. Measured from the PNGs' alpha channels:

     tips   374x436 : bands x45..172 / x204..331 (128 wide), art rows 18..435
     middle 1254x1254: bands x493..596 / x652..755 (104), art rows 442..623
     tails  394x622 : bands x50..182 / x209..341 (133), art rows 0..610
     binds  1983x793: bands x744..939 / x1043..1238 (196), art rows 15..782

   The sections tile without a step: the tips end 104px wide and the middle is
   104px; the middle ends 101px and the tails begin 102px. */
.sz-skis[data-set="child"] .sz-ski__tips{ aspect-ratio: 128 / 418; }.sz-skis[data-set="child"] .sz-ski__middle{ width: 81.250%; }.sz-skis[data-set="child"] .sz-ski__tails{ width: 103.906%; aspect-ratio: 133 / 611; }/* Vertical crops. As with the adult middle, the band is inset by one pixel
   (rows 443..622 rather than 442..623) so the upscale never samples the
   transparent rows either side of it, which is what produced the hairline. */
.sz-skis[data-set="child"] .sz-ski__tips img{ height: 104.306%; top: -4.306%; }.sz-skis[data-set="child"] .sz-ski__middle img{ height: 696.667%; top: -246.111%; }.sz-skis[data-set="child"] .sz-ski__tails img{ height: 101.800%; top: 0; }.sz-skis[data-set="child"] .sz-ski__bind img{ height: 103.255%; top: -1.953%; }/* Horizontal: same image, two different bands. Both skis use one band width so
   their rendered widths are identical. */
.sz-skis[data-set="child"] .sz-ski__tips img{ width: 292.188%; }.sz-skis[data-set="child"] .sz-ski__middle img{ width: 1205.769%; }.sz-skis[data-set="child"] .sz-ski__tails img{ width: 296.241%; }.sz-skis[data-set="child"] .sz-ski__bind img{ width: 1011.735%; }.sz-skis[data-set="child"] .sz-ski--l .sz-ski__tips img{ left: -35.156%; }.sz-skis[data-set="child"] .sz-ski--r .sz-ski__tips img{ left: -159.375%; }.sz-skis[data-set="child"] .sz-ski--l .sz-ski__middle img{ left: -474.038%; }.sz-skis[data-set="child"] .sz-ski--r .sz-ski__middle img{ left: -626.923%; }.sz-skis[data-set="child"] .sz-ski--l .sz-ski__tails img{ left: -37.594%; }.sz-skis[data-set="child"] .sz-ski--r .sz-ski__tails img{ left: -157.143%; }.sz-skis[data-set="child"] .sz-ski--l .sz-ski__bind img{ left: -379.592%; }.sz-skis[data-set="child"] .sz-ski--r .sz-ski__bind img{ left: -532.143%; }/* Bindings: one per ski, centred over its own shaft, scaled as a share of that
   ski's rendered length (--bind-w-pct is derived from the 28% length target and
   the binding art's own 103:530 aspect ratio, so it never distorts). */
.sz-ski__bind{
  position: absolute;          /* out of the flex flow: it overlays the ski and
                                  never contributes to the section stack */
  left: 50%;
  bottom: var(--binding-bottom, 30%);
  width: var(--bind-w-pct, 105%);
  height: var(--bind-h-pct, 30%);   /* of the ski's rendered length. Width is
                                       set independently so the brakes clear the
                                       ski edges, so there is no aspect-ratio
                                       here; see BINDING_OVERHANG_FRAC. */
  transform: translateX(-50%);
  overflow: hidden;
  transition: bottom .25s ease, width .25s ease, height .25s ease;
}/* Both bands measure 102 x 528 within the 215 x 530 canvas (L cols 0-101,
   R cols 113-214, rows 1-528), so both use the same scale and differ only in
   the left offset. The two bindings are therefore identical in size. */
.sz-ski__bind img{ height: 100.379%; top: -0.189%; width: 210.784%; }.sz-ski--l .sz-ski__bind img{ left: 0; }.sz-ski--r .sz-ski__bind img{ left: -110.784%; }/* ----------------------------------------------------- the snowboard */
/* One board, not a pair, so no left/right bands: each section is a single
   sprite window onto its own PNG. The stack, the bottom anchor and the 1px seam
   overlap are the ski assembly's, unchanged -- only the middle stretches.

   Measured from the PNGs' alpha channels:
     nose   403x606 : cols 55..340 (286 wide), art rows 5..605
     middle 1080x1456: cols 409..655 (247), art rows 606..711
     tail   407x744 : cols 52..344 (293), art rows 0..739
   Sections tile with no step: the nose ends 247px wide and the middle is 247;
   the middle ends 245px and the tail begins 245px. The tail is the widest
   section, so it is the 100% reference for the box. */
.sz-board{
  position: absolute;
  right: calc(var(--board-right, 31.5%) - var(--sz-shift, 0) * 100% + var(--sz-gap-close, 0%) / 2);
  bottom: var(--anchor-bottom);          /* the rider's ground plane */
  transform: translateX(50%);
  height: calc(var(--fig-h) * var(--board-len-ratio, 1));
  aspect-ratio: var(--board-ar, 0.17);
  pointer-events: none;
  z-index: 1;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;             /* grows upward from the tail */
  align-items: center;
  transition: height .25s ease, aspect-ratio .25s ease;
}.sz-board[hidden]{ display: none; }.sz-board__nose, .sz-board__middle, .sz-board__tail{ position: relative; overflow: hidden; }.sz-board img{ position: absolute; display: block; max-width: none; }/* The aspect ratios arrive from the script as plain numbers, because their
   width term carries WIDTH_MULT: the section gets wider, not taller. The
   fallbacks below are the male artwork's own ratios at WIDTH_MULT 1.05. */
.sz-board__nose{ width: 97.611%; aspect-ratio: var(--nose-ar, 0.49967); flex: 0 0 auto; }.sz-board__tail{ width: 100%;    aspect-ratio: var(--tail-ar, 0.41574); flex: 0 0 auto; }/* the only section that stretches; negative margins give the seam overlap back
   as free space, so the three sections still sum to the box height exactly */
.sz-board__middle{
  width: 84.300%;
  flex: 1 1 auto;
  min-height: 0;
  margin-top: calc(-1 * var(--seam-overlap, 1px));
  margin-bottom: calc(-1 * var(--seam-overlap, 1px));
}/* Vertical crops; the middle band is inset one pixel so the upscale never
   samples the transparent rows either side of it. */
.sz-board__nose img{ height: 100.832%; top: -0.832%;   width: 140.909%; left: -19.231%; }.sz-board__middle img{ height: 1400.000%; top: -583.654%; width: 437.247%; left: -165.587%; }.sz-board__tail img{ height: 100.541%; top: 0;          width: 138.908%; left: -17.747%; }/* ---- the bindings -------------------------------------------------------
   Both come from one 1536x1024 PNG, bands x133..729 and x808..1404 (597 wide),
   art rows 21..992. Each is its own clipped window onto that file, so nothing
   is redrawn, recoloured or distorted: the source pixels are shown 1:1 up to a
   uniform scale, and the element simply rotates.

   The element keeps the artwork's own 597:972 portrait aspect; the rotation is
   what lays it ACROSS the board. --bind-rot therefore carries a base turn plus
   the stance angle, and the script writes the finished degrees. */
/* ---- adult female deck ------------------------------------------------
   Identical construction, different artwork. Only the sprite constants are
   overridden; the box, the flex stack, the seam overlap, the bindings and
   every stance value are inherited from the rules above, so the two
   colourways cannot drift apart.

     nose   410x597 : cols 58..345 (288 wide), art rows 2..596 (595 tall)
     middle 1080x1456: cols 407..658 (252), art rows 597..765 (169)
     tail   399x690 : cols 55..349 (295), art rows 0..689 (690)
   Box width is the tail's 295px, so the nose is 288/295 and the middle
   252/295 of it. The middle is inset one row top and bottom (598..764, 167
   rows) for the same reason as the male: so the upscale never samples the
   transparent rows either side of the band. */
.sz-board[data-set="female"] .sz-board__nose{ width: 97.627%; }.sz-board[data-set="female"] .sz-board__middle{ width: 85.424%; }/* the tail is 100% of the box in both sets; both sets' aspect ratios come from
   the script, so only the width percentages differ here */

.sz-board[data-set="female"] .sz-board__nose img{ height: 100.336%; top: -0.336%;   width: 142.361%; left: -20.139%; }.sz-board[data-set="female"] .sz-board__middle img{ height: 871.856%; top: -358.084%; width: 428.571%; left: -161.508%; }.sz-board[data-set="female"] .sz-board__tail img{ height: 100.000%; top: 0;         width: 135.254%; left: -18.644%; }/* ---- child deck ---------------------------------------------------------
   Same construction again; only the sprite constants are new. Aspect ratios
   come from the script (they carry WIDTH_MULT), so only the width
   percentages live here.

     nose   507x627 : cols 91..405 (315 wide), art rows 9..626 (618 tall)
     middle 1024x1536: cols 378..646 (269), art rows 630..770 (141)
     tail   498x765 : cols 83..401 (319), art rows 0..752 (753)
   Box width is the tail's 319px. The middle is inset one row top and bottom
   (631..769, 139 rows) so the upscale never samples the transparent rows
   either side of the band. */
.sz-board[data-set="child"] .sz-board__nose{ width: 98.746%; }.sz-board[data-set="child"] .sz-board__middle{ width: 84.326%; }.sz-board[data-set="child"] .sz-board__nose img{ height: 101.456%; top: -1.456%;   width: 160.952%; left: -28.889%; }.sz-board[data-set="child"] .sz-board__middle img{ height: 1105.036%; top: -453.957%; width: 380.669%; left: -140.520%; }.sz-board[data-set="child"] .sz-board__tail img{ height: 101.594%; top: 0;         width: 156.113%; left: -26.019%; }.sz-board__bind{
  position: absolute;
  left: calc(50% + var(--bind-dx, 0%));
  width: var(--bind-w-pct, 66%);
  aspect-ratio: 597 / 972;
  overflow: hidden;
  transform-origin: 50% 50%;
  transition: bottom .25s ease, width .25s ease;
}.sz-board__bind img{ height: 105.350%; top: -2.160%; width: 257.286%; }/* The file holds a mirrored pair. Band 0 carries its strap ratchets on the
   image's left, band 1 on the right; with the +90 base turn band 0's ratchets
   end up pointing at the nose and band 1's at the tail, which is the outside
   of the left (front) and right (rear) foot respectively. So band 0 is the
   front window and band 1 the rear. No mirroring: chirality comes entirely
   from which band each window shows. */
.sz-board__bind--front img{ left: -22.278%; }/* band 0 - left foot */
.sz-board__bind--rear  img{ left: -135.343%; }/* band 1 - right foot */
.sz-board__bind--front{
  bottom: var(--front-bottom, 65%);
  --bind-dx: var(--front-dx, 0%);
  /* right-most first: scaleX runs in the element's own unrotated frame, which
     is the artwork's 477.6px foot-width axis, and the rotation is applied to the
     already-widened boot. Heel-to-toe (the 777.6px axis) is never scaled. */
  transform: translate(-50%, 50%) rotate(var(--front-rot, 75deg)) scaleX(var(--bind-foot, 1.1));
}.sz-board__bind--rear{
  bottom: var(--rear-bottom, 35%);
  --bind-dx: var(--rear-dx, 0%);
  transform: translate(-50%, 50%) rotate(var(--rear-rot, 96deg)) scaleX(var(--bind-foot, 1.1));
}/* --------------------------------------------- the measurement overlays */
/* Technical annotations, not UI. Two wrappers, each an exact geometric copy of
   what it annotates, so every offset inside is a percentage of that same box:

     .sz-meas--h    copies .sz-scene__figure  -> spans the skier
     .sz-meas--ski  copies .sz-skis           -> spans the illustrated ski

   Nothing here measures anything itself. The height span is driven by --ch and
   --foot, the same two numbers that place the skier, so its ends sit on his
   helmet and boot sole by construction. The ski markers are driven by two
   percentages the script derives from the recommendation already on screen:

     pixelsPerCm        = visibleSkierHeightPx / selectedUserHeightCm
     markerHeightPx     = cm x pixelsPerCm
     box height         = midpointCm x pixelsPerCm
     marker, as % of it = cm / midpointCm            <- --meas-lo-pct / --meas-hi-pct

   so the markers use the identical scale as the skis, and because the midpoint
   lies between lo and hi the minimum always lands below the tips and the maximum
   above them. There is no second sizing algorithm. */
.sz-meas{
  position: absolute;
  pointer-events: none;
  z-index: 2;
  font-family: var(--sans);

  /* ---- every annotation stroke is controlled from here ----
     CSS `dashed` borders give no control over dash length or gap, so the lines
     are drawn as repeating gradients instead. Thickness, dash, gap and colour
     are all variables, and vertical rules, horizontal guides and ticks share
     them, so the whole annotation system moves together. */
  --meas-line: #6E757E;        /* muted slate, darkened for contrast on snow */
  --meas-accent: var(--accent);/* the two ski-length markers only            */
  --meas-w: 2px;               /* stroke width            (was 1px)          */
  --meas-tick-w: 2.4px;          /* tick stroke             (was 1.5px)        */
  --meas-dash-len: 3.6px;      /* dash segment            (was ~2.4px, +50%)   */
  --meas-dash-gap: 3.36px;      /* space between dashes    (was ~2.4px, +40%)   */
  --meas-gap: 16px;            /* clearance from the artwork                 */
  --meas-guide: 25.6px;          /* length of the short horizontal guides      */
  --meas-tick: 8.8px;           /* length of the perpendicular tick marks     */
  --meas-val: 15.2px;            /* ONE size for the height value and both cm
                                  labels, so they read as one system         */
  --meas-label-top: 9%;        /* height label, measured down from the helmet */
  --meas-label-clear: 5.6px;     /* cm labels, offset off their own guide       */

  --meas-stroke-v: repeating-linear-gradient(to bottom,
      var(--meas-line) 0 var(--meas-dash-len),
      transparent var(--meas-dash-len) calc(var(--meas-dash-len) + var(--meas-dash-gap)));
  --meas-stroke-h: repeating-linear-gradient(to right,
      var(--meas-line) 0 var(--meas-dash-len),
      transparent var(--meas-dash-len) calc(var(--meas-dash-len) + var(--meas-dash-gap)));
  --meas-stroke-h-accent: repeating-linear-gradient(to right,
      var(--meas-accent) 0 var(--meas-dash-len),
      transparent var(--meas-dash-len) calc(var(--meas-dash-len) + var(--meas-dash-gap)));
}.sz-meas[hidden]{ display: none; }.sz-meas b, .sz-meas i{ font-style: normal; font-weight: inherit; }/* ---- the skier's height, to the LEFT of the skier ---- */
/* Box identical to .sz-scene__figure; the script writes the same four character
   numbers here, plus --cl, the artwork's left edge as a % of the image width. */
.sz-meas--h{
  right: calc(var(--anchor-right) - var(--sz-shift, 0) * 100% - var(--sz-gap-close, 0%) / 2);
  bottom: var(--anchor-bottom);
  height: calc(var(--fig-h) * var(--stature, 1) / var(--ch, 1));
  aspect-ratio: 1024 / 1536;
  transform: translate(var(--cx, 50%), var(--foot, 0%));
}/* The vertical rule. Bottom and height are the skier's own two numbers, so it
   starts on the boot sole and ends on the top of the helmet. */
.sz-meas__span{
  position: absolute;
  bottom: var(--foot, 0%);
  height: calc(var(--ch, 1) * 100%);
  left: var(--cl, 21%);
  width: var(--meas-w);
  /* centred --meas-gap left of the artwork edge */
  margin-left: calc(-1 * var(--meas-gap) - var(--meas-w) / 2);
  background-image: var(--meas-stroke-v);
}/* Guides and ticks are centred on the end points, so doubling the stroke
   thickens the line without moving what it marks. */
.sz-meas__guide{
  position: absolute;
  left: 0;
  width: var(--meas-guide);
  height: var(--meas-w);
  background-image: var(--meas-stroke-h);
}.sz-meas__guide--top{ top: calc(var(--meas-w) / -2); }.sz-meas__guide--bot{ bottom: calc(var(--meas-w) / -2); }.sz-meas__tick{
  position: absolute;
  left: calc(var(--meas-tick) / -2 + var(--meas-w) / 2);
  width: var(--meas-tick);
  height: var(--meas-tick-w);
  background: var(--meas-line);
}.sz-meas__tick--top{ top: calc(var(--meas-tick-w) / -2); }.sz-meas__tick--bot{ bottom: calc(var(--meas-tick-w) / -2); }.sz-meas__label{
  position: absolute;
  top: var(--meas-label-top);  /* beside the helmet, not the hip */
  right: 9.6px;                 /* left of the rule, clear of the skier */
  transform: translateY(-50%);
  text-align: right;
  white-space: nowrap;
  line-height: 1.25;
}.sz-meas__cap{
  display: block;
  font-size: 8.8px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
}.sz-meas__val{
  display: block;
  font-size: var(--meas-val);
  font-weight: 700;
  letter-spacing: -0.01em;
  color: var(--ink);
}.sz-meas__sub{ display: block; font-size: 9.6px; color: var(--muted); }/* ---- the recommended ski length, to the RIGHT of the skis ---- */
/* Box identical to .sz-skis, so its height IS the illustrated ski length. */
.sz-meas--ski{
  right: calc(var(--ski-right, 31.5%) - var(--sz-shift, 0) * 100% + var(--sz-gap-close, 0%) / 2);
  bottom: var(--anchor-bottom);
  transform: translateX(50%);
  height: calc(var(--fig-h) * var(--ski-len-ratio, 1));
  aspect-ratio: var(--ski-ar, 0.16);
}/* Marks are zero-height boxes AT the exact marker height; the rail is the only
   child with real width. Both are centred on the same vertical axis. */
.sz-meas--ski > *{ position: absolute; left: 100%; }.sz-meas__mark{ width: 0; margin-left: calc(var(--meas-gap) + var(--meas-w) / 2); }/* Runs from the tails up to the maximum marker. */
.sz-meas__rail{
  bottom: 0;
  height: var(--meas-hi-pct, 102%);
  width: var(--meas-w);
  margin-left: var(--meas-gap);
  background-image: var(--meas-stroke-v);
}.sz-meas__mark--hi{ bottom: var(--meas-hi-pct, 102%); }.sz-meas__mark--lo{ bottom: var(--meas-lo-pct, 98%); }.sz-meas__mark--ground{ bottom: 0; }/* The short guide runs LEFT, back toward the skis. */
.sz-meas__mark i{
  position: absolute;
  right: 0;
  top: calc(var(--meas-w) / -2);
  width: var(--meas-guide);
  height: var(--meas-w);
  background-image: var(--meas-stroke-h);
}.sz-meas__mark::before{
  content: "";
  position: absolute;
  left: calc(var(--meas-tick) / -2);
  top: calc(var(--meas-tick-w) / -2);
  width: var(--meas-tick);
  height: var(--meas-tick-w);
  background: var(--meas-line);
}/* the subtle orange accents, kept to the two range markers */
.sz-meas__mark--hi i, .sz-meas__mark--lo i{ background-image: var(--meas-stroke-h-accent); }.sz-meas__mark--hi::before, .sz-meas__mark--lo::before{ background: var(--meas-accent); }/* Labels sit just off their own guide. At a 6cm spread the two markers are only
   about 15px apart on screen, so centring both on their lines would overlap
   them: the maximum reads above its guide, the minimum below its own. */
/* Same family, weight and size as the skier's height value. At a 6cm spread the
   two guides are only ~15px apart, far less than a 19px line box, so the TEXT is
   nudged clear of its own guide while the guide itself stays at the exact
   mathematical height. Only the type moves, never the measurement. */
.sz-meas__mark b{
  position: absolute;
  left: 10.4px;
  font-size: var(--meas-val);
  font-weight: 700;
  letter-spacing: -0.01em;
  line-height: 1.1;
  color: var(--ink);
  white-space: nowrap;
}.sz-meas__mark--hi b{ bottom: var(--meas-label-clear); }.sz-meas__mark--lo b{ top: var(--meas-label-clear); }/* Below 1000px the scene shrinks to roughly half and the page stacks; there is
   no longer room for annotations beside the artwork, so they are dropped rather
   than allowed to collide with the skier or the controls. */
@media (min-width: 641px) and (max-width: 999px){
  .sz-meas { display: none; }
}/* Below 641px the scene is a full-width band of its own (see the phone block
   at the end of this file), so there IS room beside the artwork again and the
   annotations come back, retuned for the smaller scale. */

/* --------------------------------------------------------------- the layout */
.sz-page{
  position: relative;
  z-index: 1;
  display: grid;
  gap: 32px;
  padding: 20.8px 0 57.6px;
}@media (min-width: 1000px){.sz-page{
    grid-template-columns: minmax(0, 0.92fr) minmax(0, 1.08fr);
    column-gap: 44.8px;
    align-items: start;
  }/* The divider in the comp: one hairline between the two columns. */
  .sz-rec{
    border-left: 1px solid var(--line);
    padding-left: 44.8px;
    /* Tall enough to contain the absolutely placed button, so it can never
       spill past .sz-page into the Quick Tips band below. */
    min-height: calc(var(--sz-scene-top) + 0.9095 * clamp(403.2px, 52.2vw, 648px)
      + var(--sz-cta-drop) + 46.4px + 12.8px - 20.8px);
  }

}/* ------------------------------------------------------------ left: heading */
.sz-eyebrow{
  margin: 0 0 11.2px;
  font-size: 9.6px;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--muted);
}.sz-h1{
  margin: 0 0 14.4px;
  font-family: var(--sans);
  font-size: clamp(27.2px, 3.5vw, 40px);
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.025em;
  color: var(--ink);
}.sz-lede{
  margin: 0 0 24px;
  max-width: 34em;
  font-size: clamp(12px, 1.15vw, 13.6px);
  line-height: 1.55;
  color: var(--muted);
}.sz-vh{
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
}/* --------------------------------------------------- segmented ski / board */
.sz-seg{
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 0;
  margin: 0 0 24px;
  padding: 3.2px;
  border: 0;
  border-radius: 11.2px;
  background: var(--line-2);
}.sz-seg input{
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}.sz-seg label{
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 6.4px 8px;
  border-radius: 8px;
  font-size: 12.8px;
  font-weight: 600;
  color: var(--ink);
  cursor: pointer;
  transition: background .15s, color .15s;
}.sz-seg label i{ font-size: 14.4px; line-height: 1; }/* Second segmented control (Adults / Kids): same shape and states as the first,
   a little more compact and text only, so it reads as secondary to it. */
.sz-seg--sm{ margin-top: -14.4px; padding: 3.2px; border-radius: 9.6px; }.sz-seg--sm label{ padding: 7.2px 8px; border-radius: 7.2px; font-size: 12px; }/* The Character control is removed from the flow for kids, not just blanked:
   .sz-seg sets display:grid, which would otherwise beat the [hidden] default. */
.sz-seg[hidden]{ display: none; }.sz-seg input:checked + label{ background: var(--blue); color: #fff; }.sz-seg input:focus-visible + label{ outline: 2px solid var(--blue); outline-offset: 2px; }/* -------------------------------------------------------------- input rows */
.sz-row{
  display: grid;
  grid-template-columns: 22.4px 105.6px minmax(0, 1fr);
  align-items: center;
  column-gap: 11.2px;
  margin-bottom: 20.8px;
}.sz-row--tight{ align-items: center; margin-bottom: 17.6px; }.sz-ico{
  font-size: 16px;
  color: var(--blue);
  text-align: center;
}.sz-key{ display: grid; gap: 2px; }.sz-k{ font-size: 12px; color: var(--muted); }.sz-v{ font-size: 16.8px; font-weight: 700; color: var(--ink); letter-spacing: -0.01em; }/* ----------------------------------------------------------------- sliders */
.sz-slider{ position: relative; padding-top: 27.2px; }.sz-slider input[type="range"]{
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 16px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}.sz-slider input[type="range"]::-webkit-slider-runnable-track{
  height: 3.2px;
  border-radius: 799.2px;
  background: var(--line);
}.sz-slider input[type="range"]::-moz-range-track{
  height: 3.2px;
  border-radius: 799.2px;
  background: var(--line);
}.sz-slider input[type="range"]::-webkit-slider-thumb{
  -webkit-appearance: none;
  width: 14.4px;
  height: 14.4px;
  margin-top: -5.6px;
  border: 0;
  border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 1px 2.4px rgba(22, 24, 27, .25);
}.sz-slider input[type="range"]::-moz-range-thumb{
  width: 14.4px;
  height: 14.4px;
  border: 0;
  border-radius: 50%;
  background: var(--blue);
  box-shadow: 0 1px 2.4px rgba(22, 24, 27, .25);
}.sz-slider input[type="range"]:focus-visible{ outline: 2px solid var(--blue); outline-offset: 3.2px; }/* Floating value indicator. --pos is written by the script as a percentage and
   the translate keeps it centred on the thumb, including at both extremes,
   where the half-thumb correction stops it overhanging the track. */
.sz-bubble{
  position: absolute;
  top: 0;
  left: var(--pos, 50%);
  transform: translateX(-50%);
  padding: 4px 8px;
  border-radius: 6.4px;
  background: var(--blue);
  color: #fff;
  font-size: 10.4px;
  font-weight: 600;
  line-height: 1.2;
  white-space: nowrap;
  pointer-events: none;
}.sz-bubble::after{
  content: "";
  position: absolute;
  top: 100%;
  left: 50%;
  transform: translateX(-50%);
  border: 4px solid transparent;
  border-top-color: var(--blue);
}.sz-ticks{
  position: relative;
  height: 14.4px;
  margin-top: 2px;
}.sz-ticks span{
  position: absolute;
  top: 0;
  transform: translateX(-50%);
  font-size: 9.6px;
  color: var(--muted);
  white-space: nowrap;
}/* ----------------------------------------------------------- ability pills */
.sz-pills{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }.sz-pills input{
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}.sz-pills label{
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 9.6px 4.8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--paper);
  font-size: 12px;
  color: var(--ink);
  cursor: pointer;
  transition: background .15s, color .15s, border-color .15s;
}.sz-pills input:checked + label{
  background: var(--blue);
  border-color: var(--blue);
  color: #fff;
  font-weight: 600;
}.sz-pills input:focus-visible + label{ outline: 2px solid var(--blue); outline-offset: 2px; }/* ------------------------------------------------------------ terrain cards */
.sz-cards{ display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }.sz-cards input{
  position: absolute;
  opacity: 0;
  width: 1px;
  height: 1px;
}.sz-cards label{
  display: block;
  overflow: hidden;
  border: 1px solid var(--line);
  border-radius: 9.6px;
  background: var(--paper);
  cursor: pointer;
  transition: border-color .15s, background .15s, color .15s;
}.sz-cards label img{
  display: block;
  width: 100%;
  height: 59.2px;
  object-fit: cover;        /* crops to the card, never squashes the photo */
  object-position: center;
}.sz-cards label span{
  display: block;
  padding: 7.2px 6.4px 8px;
  font-size: 10.4px;
  line-height: 1.25;
  text-align: center;
  color: var(--ink);
}.sz-cards input:checked + label{
  border-color: var(--blue);
  background: var(--blue);
}.sz-cards input:checked + label span{ color: #fff; font-weight: 600; }.sz-cards input:focus-visible + label{ outline: 2px solid var(--blue); outline-offset: 2px; }/* ------------------------------------------------- right: the recommendation */
.sz-rec{ position: relative; }/* No panel, no scrim, no card. The recommendation sits directly on the same
   white page as the calculator; the reveal above is masked so the photograph
   never reaches this column in the first place. */

/* Phone-only lead block above the illustration; see the phone media query
   at the end of this file. */
.sz-range--lead, .sz-lead-cap, .sz-lead-sub{ display: none; }.sz-range{
  margin: 0 0 4.8px;
  font-size: clamp(33.6px, 5.2vw, 60.8px);
  font-weight: 700;
  line-height: 1;
  letter-spacing: -0.03em;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}.sz-unit{
  font-size: clamp(17.6px, 2.3vw, 27.2px);
  font-weight: 700;
  letter-spacing: -0.01em;
}.sz-reclab{
  margin: 0;
  font-size: clamp(13.6px, 1.5vw, 17.6px);
  color: var(--ink-2);
}/* --------------------------------- the recommendation detail and the CTA */
/* No panel and no scrim: this sits directly on the page, inside the same right
   column as the big number, and the photograph's radial mask keeps the picture
   out of this column. --sz-detail-max is the one dial for how wide the prose
   runs before it would reach the illustration. */
.sz-rec__detail{
  --sz-detail-max: 368px;   /* never wider than the comp's column           */
  --sz-detail-clear: 36.8px;  /* 20.8px of visible gap, plus a 16px correction:
                               the scene is positioned against the SHELL width
                               while this calc works in vw, which includes the
                               scrollbar. Measured in a browser, not guessed;
                               with this value the gap to the label's left edge
                               is 20.8px at 1280, 1440, 1600, 1761, 1920, 2200. */
  --sz-meas-label-w: 68.8px;  /* the "YOUR HEIGHT / 5'11" / (180 cm)" block is
                               right-aligned to the dotted rule, so it reaches
                               this far LEFT of it. Clearing only the rule is
                               what let the disclaimer run under the label.    */
  --sz-detail-top: 150.4px;   /* shell top -> this block: page padding 26, the
                               eyebrow, the number, its caption, margin-top 24 */
  max-width: var(--sz-detail-max);
  margin-top: 19.2px;

  /* Keeps the prose from ending beside the skier's legs on wide screens, so the
     button below it is always clear of the illustration's ground line. */
  min-height: max(0px, calc(
      0.9095 * clamp(403.2px, 52.2vw, 648px) + var(--sz-scene-top)
      - var(--sz-detail-top)));

  /* The right edge is derived from the illustration's own geometry rather than
     guessed, so it holds at every desktop width instead of one. Reading the
     terms left to right, all in the same units the rest of the sheet uses:

       wrapRight   = 50vw + 0.5 x min(100vw, 992px) - 16px
       skierBodyL  = 72.82vw - 0.120925 x sceneH
                     72.82vw   = 100vw - --anchor-right(60.4%) x sceneW(45vw)
                     0.120925  = (--cx 0.49658 - --cl 0.2109) x figW/sceneH,
                                 where figW/sceneH = (--fig-h / --ch) x 1024/1536
       heightLine  = skierBodyL - --meas-gap(16px)
       margin-right = wrapRight - heightLine + --sz-detail-clear

     The two 16px terms cancel, leaving the expression below. max(0px, ...)
     covers very wide viewports, where the illustration has moved far enough
     right that the column no longer needs pulling in at all. */
  margin-right: max(0px, calc(
      0.5 * min(100vw, 992px)
    - 22.82vw
    + 0.120925 * clamp(403.2px, 52.2vw, 648px)
    - var(--sz-shift, 0) * 45vw           /* the shift: n x the 45vw scene    */
    + var(--sz-detail-clear)
    + var(--sz-meas-label-w)));
}.sz-rec__intro{
  margin: 0 0 9.6px;
  font-size: clamp(12.8px, 1.35vw, 16px);
  font-weight: 500;
  line-height: 1.34;
  letter-spacing: -0.005em;
  color: var(--ink);
}.sz-rec__note{
  margin: 0 0 20.8px;
  font-size: 11.6px;
  line-height: 1.5;
  color: var(--muted);
}/* the three terrain-specific rows */
.sz-notes{ list-style: none; margin: 0; padding: 0; display: grid; gap: 16px; }.sz-note{
  display: grid;
  grid-template-columns: 20.8px minmax(0, 1fr);
  gap: 12.8px;
  align-items: start;
}.sz-note__ico{
  font-size: 16.8px;
  line-height: 1.15;
  text-align: center;
  color: var(--blue);        /* dark navy, as in the comp */
}.sz-note__txt b{
  display: block;
  margin-bottom: 2.4px;
  font-size: 12.4px;
  font-weight: 700;
  color: var(--ink);
}.sz-note__txt span{
  display: block;
  font-size: 11.6px;
  line-height: 1.45;
  color: var(--muted);
}.sz-cta{
  /* sampled from the comp */
  --sz-cta-bg: #E47347;
  --sz-cta-bg-hover: #D1623A;
  /* 274.4px is what "Find rentals near your mountain" needs on one line at 17/700
     plus the 41.6px padding, the 14.4px gap and the 12px arrow; 400 leaves headroom
     for the webfont. The button is a sibling of .sz-rec__detail, so it is not
     held to the prose column's width. */
  --sz-cta-max: 320px;
  max-width: var(--sz-cta-max);
  margin-top: 22.4px;
  /* The label is centred on the BUTTON, not on the space left over beside the
     arrow: the arrow is taken out of the flex flow and pinned to the right edge,
     so the text sits dead centre of the full width. position:relative is the
     fallback containing block for it; at desktop widths the rule below makes
     this absolute, which is also a containing block. */
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  min-height: 46.4px;
  padding: 0 20.8px;
  border-radius: 9.6px;
  background: var(--sz-cta-bg);
  color: #fff;
  font-size: 13.6px;
  font-weight: 700;
  letter-spacing: -0.01em;
  text-decoration: none;
  transition: background .18s ease;
}/* Desktop placement. This MUST come after the base .sz-cta rule above: both
   selectors are a single class, so the later one wins, and when this block
   sat earlier in the file the base rule's `position: relative` overrode the
   `absolute` here while `top` still applied -- as a relative offset, which
   shoved the button ~766px down the page and over the footer. */
@media (min-width: 1000px){
  /* The button sits under the illustration, not under the prose. .sz-rec is the
     containing block, so this is written as an offset from the recommendation
     column's right edge:

       wrapRight   = 50vw + 0.5 x min(100vw, 992px) - 16px
       buttonMid   = 100vw - --sz-cta-centre x sceneW(45vw)
       right       = wrapRight - buttonMid        (+ the same 16px shell-vs-vw
                                                   correction as the prose column)

     translateX(50%) then centres the button on that point, so its width can
     change without moving its centre. Vertically it hangs --sz-cta-drop below
     the ground line the boots and ski tails stand on, which is itself derived
     from --sz-scene-top, so the button follows the composition automatically. */
  .sz-cta {
    position: absolute;
    right: calc(var(--sz-cta-centre) * 45vw - 50vw
      + 0.5 * min(100vw, 992px) - 16px + 16px);
    top: calc(var(--sz-scene-top) + 0.9095 * clamp(403.2px, 52.2vw, 648px)
      + var(--sz-cta-drop) - 20.8px);
    transform: translateX(50%);
    margin-top: 0;
  }
}.sz-cta:hover{ background: var(--sz-cta-bg-hover); }.sz-cta:focus-visible{ outline: 2.4px solid var(--blue); outline-offset: 2.4px; }.sz-cta i{
  position: absolute;
  right: 20.8px;               /* matches the button's own horizontal padding */
  top: 50%;
  transform: translateY(-50%);
  font-size: 12px;
}/* --------------------------------------------------------- the quick tips */
/* Five equal areas on a white band: the heading, then four tips divided by
   hairlines. No cards, no shadows. The band sits after .sz-page in normal flow,
   so it always begins below both the calculator and the illustration. */
.sz-tips{
  position: relative;
  z-index: 1;
  background: var(--paper);
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}.sz-tips__inner{
  display: grid;
  padding-top: 27.2px;
  padding-bottom: 27.2px;
}.sz-tips__h{
  margin: 0;
  /* sized to hold "to keep in mind." on one line in a fifth of the wrap */
  font-size: clamp(17.6px, 2vw, 21.6px);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -0.03em;
  color: var(--ink);
}.sz-tips__list{ list-style: none; margin: 0; padding: 0; display: grid; }.sz-tip{
  display: grid;
  /* narrow icon column and tight gutters: each tip heading has to sit on one
     line inside a fifth of the wrap, or the four body texts stop aligning */
  grid-template-columns: 22.4px minmax(0, 1fr);
  gap: 11.2px;
  align-items: start;
}.sz-tip__ico{ font-size: 20px; line-height: 1.1; text-align: center; color: var(--blue); }/* The icon takes column 1 of the first row; the heading and the body both sit in
   column 2, stacked. Without this the body would wrap into the 32px icon column. */
.sz-tip h3, .sz-tip p{ grid-column: 2; }.sz-tip h3{ margin: 0 0 4px; font-size: 12px; font-weight: 700; color: var(--ink); }.sz-tip p{ margin: 0; font-size: 10.8px; line-height: 1.46; color: var(--muted); }/* Stacked by default, then two up, then the five-across band. The band needs
   more room than the page's own 1000px breakpoint: between 1000 and 1180 a
   fifth of the wrap is too narrow to hold "Personal preference" on one line,
   and once one heading wraps the four body texts stop aligning. */
.sz-tips__head{ margin-bottom: 19.2px; }/* Contextual link out to the gear-type guide. Sits under the section heading so
   it reads as part of the intro rather than as a fifth tip (the four tips below
   are written by the script and would overwrite anything placed inside them). */
.sz-tips__more{
  margin: 11.2px 0 0;
  font-size: 11.6px;
  line-height: 1.5;
  color: var(--muted);
}.sz-tips__more a{ color: var(--blue); font-weight: 600; text-decoration: none; }.sz-tips__more a:hover{ text-decoration: underline; }.sz-tips__list{ grid-template-columns: minmax(0, 1fr); gap: 19.2px 22.4px; }@media (min-width: 640px){.sz-tips__list{ grid-template-columns: repeat(2, minmax(0, 1fr)); }
}@media (min-width: 1180px){/* heading + four tips = five equal columns */
  .sz-tips__inner{ grid-template-columns: minmax(0, 1fr) minmax(0, 4fr); }.sz-tips__list{ grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 0; }.sz-tips__head{ margin-bottom: 0; padding-right: 22.4px; }.sz-tips__list > li{ padding: 0 16px; border-left: 1px solid var(--line); }
}/* Below the page's two-column breakpoint the recommendation is full width. */
/* Between the page's 1000px two-column breakpoint and about 1180px there is not
   enough room to shift the illustration without pushing the ski-length labels
   off the right edge, so the shift is dialled back to keep the page from
   scrolling sideways. The recommendation column is very narrow through this
   band; see the note on .sz-page's breakpoint. */
@media (max-width: 1180px){
  .sz-shell { --sz-shift: 0.01; }
}/* Below the two-column breakpoint the illustration no longer sits beside the
   recommendation, so the column is free again. */
@media (max-width: 999px){
  .sz-shell { --sz-shift: 0; }   /* stacked: the illustration stays put */
  .sz-cta { position: relative; transform: none; margin-top: 22.4px; }
  .sz-rec__detail { max-width: none; margin-right: 0; min-height: 0; }
  .sz-cta { max-width: none; }
}/* ------------------------------------------------------------- small screens */
@media (max-width: 999px){
  /* top only: `inset` here would reset left back to 0, making the scene
     full-width again and cropping the peaks off below 800px. */
  .sz-scene {
    --sz-scene-top: -12.8px;
    left: 51.4%;
    height: clamp(273.6px, 57.6vw, 403.2px);
  }
  .sz-scene__bg {
    object-position: 78% 100%;
    -webkit-mask-image: radial-gradient(72% 72% at 72% 68%,
        #000 0%, #000 32%, rgba(0, 0, 0, 0.9) 52%,
        rgba(0, 0, 0, 0.5) 72%, rgba(0, 0, 0, 0) 100%);
    mask-image: radial-gradient(72% 72% at 72% 68%,
        #000 0%, #000 32%, rgba(0, 0, 0, 0.9) 52%,
        rgba(0, 0, 0, 0.5) 72%, rgba(0, 0, 0, 0) 100%);
  }
  .sz-scene { --anchor-right: 66.7%; --anchor-bottom: 12.88%; --fig-h: 49.87%; }
  .sz-rec { padding-top: 6.4px; }
}@media (max-width: 640px){.sz-row{ grid-template-columns: 19.2px 1fr; row-gap: 8px; }.sz-ctl{ grid-column: 1 / -1; }.sz-key{ grid-column: 2; }.sz-cards label img{ height: 49.6px; }.sz-scene{ --anchor-right: 66.7%; --anchor-bottom: 14.74%; --fig-h: 42.2%; }
}/* ===========================================================================
   Phone layout (<= 640px)

   Above this width the illustration is absolutely positioned beside the
   content column, which is right for a two-column page. On one column it sat
   BEHIND the intro copy and the first two toggle rows (measured at 375px:
   scene x 193-375 / y 52-394, lede y 210-290, toggles from y 316). Below
   640px the scene rejoins the flow as its own full-width band, so nothing
   overlaps and the illustration is still the live calculator output.
   =========================================================================== */
@media (max-width: 640px){
  /* .sz-page carries `padding: 20.8px 0 57.6px`, and that shorthand wipes out the
     left/right gutter it inherits from .wrap. Harmless at desktop widths,
     where the 992px max-width supplies the margin; at phone widths it ran
     the whole calculator edge to edge and clipped the slider end labels. */
  .sz-page {
    padding-left: var(--gutter);
    padding-right: var(--gutter);
  }

  .sz-scene {
    position: relative;
    left: auto;
    right: auto;
    top: auto;
    --sz-scene-top: 0px;
    width: 100%;
    /* Taller than the first pass, to carry the 1.5x artwork plus the ski
       length markers, which rise above the tips. */
    height: clamp(361.6px, 150vw, 448px);
    /* Pulled up behind the recommendation block so the sky above the peaks
       becomes its background. --sz-lead-h is that block's measured height
       (caption + range + instruction); the scene starts right under the
       header and the three lines overlay its top. */
    margin: calc(-1 * var(--sz-lead-h, 83.2px)) 0 0;
  }
  /* And the calculator copy is pulled up INTO the snowy foreground, so the
     snow is the transition into the white section instead of a gap. The
     overlap stops short of the boot line, which sits --sz-boot-clear above
     the scene's bottom edge. */
  .sz-page {
    position: relative;
    z-index: 2;
    margin-top: calc(-1 * var(--sz-snow-overlap, 48px));
  }
  /* The radial mask inherited from the >=512.8px layout faded the image out to
     the LEFT, which read as a white wedge over the mountains and stole the
     width the enlarged artwork needs. On phones the band is full-bleed, so
     the image runs edge to edge and only its lower edge is faded, bottom to
     top, into the white content section below. The stop is kept below the
     boot line so the snow the figure stands on stays solid. */
  .sz-scene__bg {
    object-position: 62% 100%;
    -webkit-mask-image: linear-gradient(to top,
        rgba(0,0,0,0) 0%, rgba(0,0,0,0.20) 3%, rgba(0,0,0,0.55) 6%,
        rgba(0,0,0,0.86) 8.5%, #000 10.5%);
    mask-image: linear-gradient(to top,
        rgba(0,0,0,0) 0%, rgba(0,0,0,0.20) 3%, rgba(0,0,0,0.55) 6%,
        rgba(0,0,0,0.86) 8.5%, #000 10.5%);
  }

  /* ---- 1.5x artwork -------------------------------------------------------
     --fig-h is the shared content height as a percentage of the scene, and
     BOTH the character and the equipment derive from it (.sz-scene__figure
     height, and .sz-meas--ski / the ski and board boxes through
     --ski-len-ratio). Raising this one number scales the whole assembly
     together, so proportions, grounding and the dynamic equipment behaviour
     are untouched. Measured at 300px: the old band rendered a 96px figure
     box; 46% of the new 312px band renders 144px, a factor of 1.50.
     --anchor-right moves left to make room for the taller artwork and for
     the height annotation, which sits to the LEFT of the character. */
  .sz-scene {
    /* 46% of the old 312px band rendered a 144.8px figure. 48.3% of the new
       450.4px band rendered a 225.6px figure. 58% renders 270.4px, a further 1.20x,
       with the equipment following through the same variable so the pair
       keeps its relative scale and its grounding. The background image is
       NOT scaled; only the band it sits in grows, and object-position keeps
       the peaks in frame. --anchor-right moves the cluster right to buy back
       the width the taller artwork needs on the left. */
    --fig-h: 58%;
    /* Measured at 300px after the 1.20x: the skis' box ran 221-274 while the
       character's visible body reached about 269, so the tips sat behind his
       arm. Moving the character left and zeroing the gap-close pulls the two
       apart again without touching either one's size. */
    --anchor-right: 57%;
    /* Plants the pair INSIDE the snow field rather than on the horizon line
       where the distant range meets the foreground. 16% put the boots and the
       ski tails right on that seam; 11.4% drops them ~20.8px at 300px, into
       solid snow, and the dotted guides follow because they share this
       anchor. */
    --anchor-bottom: 11.4%;
  }
  /* The character-to-equipment gap is narrowed by this much at desktop sizes.
     At phone scale the pair is far larger relative to the band, so the same
     percentage closed the gap to nothing. */
  .sz-shell {
    --sz-gap-close: 0%;
    /* Height of the recommendation block (caption + range + instruction),
       used to pull the scene up behind it. */
    --sz-lead-h: 94.4px;
    /* How far the calculator copy reaches up into the snow. Kept well below
       the boot line, which measures ~67.2px above the scene's bottom edge. */
    /* Reduced by the same amount the figure dropped, so the clearance between
       the boots and the calculator heading is unchanged at 20.8px. */
    --sz-snow-overlap: 25.6px;
  }
  .sz-lead-cap { padding-top: 11.2px; }

  /* Localized scrim behind the recommendation only. The caption and the big
     number read fine on pale sky, but the instruction line lands on the ridge
     where the image is busy. A soft white wash across the top of the scene,
     fading out well above the figure, lifts all three without touching the
     rest of the picture. The text sits at z-index 2, above this. */
  .sz-scene::before {
    content: "";
    position: absolute;
    inset: 0 0 auto 0;
    height: calc(var(--sz-lead-h, 94.4px) + 41.6px);
    background: linear-gradient(to bottom,
        rgba(255,255,255,0.86) 0%,
        rgba(255,255,255,0.78) 46%,
        rgba(255,255,255,0.40) 76%,
        rgba(255,255,255,0) 100%);
    z-index: 1;
    pointer-events: none;
  }

  /* ---- annotations, retuned for the small scale ---- */
  /* At 1.5x the artwork plus both annotation columns is wider than the 16px
     text gutter allows. The annotations are an overlay on the illustration,
     not body copy, so they are held to the VIEWPORT edge instead, with the
     gap and type tightened to buy the room. */
  .sz-meas {
    --meas-gap: 7.2px;
    --meas-guide: 14.4px;
    --meas-tick: 6.4px;
    --meas-w: 1.5px;
    --meas-tick-w: 2px;
    --meas-dash-len: 2.72px;
    --meas-dash-gap: 2.56px;
    --meas-val: 11.2px;
    --meas-label-clear: 4px;
  }
  /* Stacked over two lines ("Your" / "height"), which roughly halves the
     width this block steals from the left of the figure. */
  /* Stacked over two lines on phones ("Your" / "height"), which roughly
     halves the width this block steals from the left of the figure. Done by
     letting the caption wrap inside a narrow box rather than with a <br> in
     the markup, so the desktop label stays on one line exactly as before.
     .sz-meas__label already sets text-align: right, so the two lines align
     to the dotted rule. */
  .sz-meas__cap {
    font-size: 8.4px;
    letter-spacing: .07em;
    line-height: 1.15;
    white-space: normal;
    max-width: 4.6em;
    margin-left: auto;
    /* Was --muted, which washed out against the mountains. Matches the
       167 / 173 cm labels on the other side. */
    color: var(--ink);
  }
  /* The height VALUE was rendering at weight 400 while the length labels
     rendered at 700. Cause: `.sz-meas b, .sz-meas i { font-weight: inherit }`
     (specificity 0-1-1) outranks `.sz-meas__val` (0-1-0), whereas
     `.sz-meas__mark b` is also 0-1-1 and sits later in the file, so it won.
     Matching the specificity puts both sides on the same weight. The same
     mismatch exists above 512px; left alone there so desktop is unchanged. */
  .sz-meas .sz-meas__val { font-weight: 700; font-size: var(--meas-val); }
  .sz-meas__sub { color: var(--muted); }
  .sz-meas__sub { font-size: 8px; }
  .sz-meas__mark b { font-size: var(--meas-val); }

  /* ---- the recommended length, above the illustration ---- */
  /* Restrained caption; the number below it stays the loud element. The
     equipment word is the existing [data-kindword] hook, which the script
     already sets to "ski" or "snowboard" on every render, so this follows the
     selection with no new logic. */
  /* The recommendation now sits INSIDE the top of the hero rather than in a
     white band above it: the scene is pulled up behind this block by its own
     height (see .sz-scene margin-top below), so these three lines land on the
     sky above the peaks and the whole thing reads as one composition. */
  .sz-lead-cap,
  .sz-range--lead,
  .sz-lead-sub { position: relative; z-index: 2; }

  .sz-lead-cap {
    display: block;
    margin: 0 var(--gutter);
    font-size: 9.2px;
    font-weight: 600;
    letter-spacing: .13em;
    text-transform: uppercase;
    color: var(--muted);
    text-align: center;
  }
  .sz-range--lead {
    display: block;
    margin: 2px var(--gutter) 0;
    font-size: clamp(32px, 12.4vw, 43.2px);
    line-height: 1.02;
    text-align: center;
  }
  /* Secondary to the number by a wide margin, but still readable on snow. */
  .sz-lead-sub {
    display: block;
    margin: 5.6px var(--gutter) 0;
    font-size: 10.4px;
    line-height: 1.35;
    color: var(--muted);
    text-align: center;
  }
  .sz-range--lead .sz-unit {
    font-size: .38em;
    font-weight: 600;
    letter-spacing: 0;
    color: var(--muted);
  }

  /* Slider end labels are centred on their tick, so the first and last ones
     hang half their width past the track. Anchor them inside instead. */
  .sz-ticks span:first-child { transform: none; }
  .sz-ticks span:last-child  { transform: translateX(-100%); }
}/* Small phones. The annotations hang off both sides of the artwork by
   --meas-gap, so on a 320px screen with the height slider at its maximum the
   "Your height" label reached x = 10 and the cm markers reached x = 296 of
   320. Nothing clipped, but the clearance was thin; tightening the gap and
   the type pulls both back inside comfortable margins. */
@media (max-width: 360px){
  .sz-meas {
    --meas-gap: 6.4px;
    --meas-guide: 11.2px;
    --meas-val: 10.4px;
  }
  .sz-meas__cap { font-size: 8px; }
  .sz-meas__sub { font-size: 7.6px; }
  .sz-range--lead { font-size: clamp(28.8px, 12vw, 35.2px); }
  .sz-lead-sub { font-size: 9.6px; margin-top: 4.8px; }
  /* The band is shorter here (150vw of 320 = 384px) but the figure is not,
     so the two ends of the composition crowd. Pulling the scene up LESS
     pushes the figure down away from the instruction line (measured at 256px
     with the tallest skier: 0px of clearance before), and a smaller snow
     overlap keeps the calculator copy off the boots. */
  .sz-shell {
    --sz-lead-h: 76.8px;
    --sz-snow-overlap: 17.6px;
  }
  .sz-lead-cap { font-size: 8.4px; letter-spacing: .1em; }
}
