/* =====================================================================
   GIUSUM website styles.
   Everything is positioned in DESIGN PIXELS (the px of the General Design Editor) multiplied by --u,
   the size of one design pixel on this screen (set by main.js: window width / design width).
   So the page always keeps the exact proportions of the design file.
   ===================================================================== */
@font-face {
  font-family: 'Oswald';
  src: url('/assets/fonts/Oswald-Variable.woff2') format('woff2'), url('/assets/fonts/Oswald-Variable.ttf') format('truetype');   /* (the .ttf: older browsers and the frozen reference page) */
  font-weight: 200 700;
  font-display: swap;
}
:root {
  --u: 1px;                 /* 1 design px, in real px (updated by main.js) */
  --blue: #003DA5;          /* the palette: white #ffffff, light grey #bababa, dark grey #2e2e2e, black #000000, this blue. 3D models keep their own colours. */
  --ease: cubic-bezier(.4, 0, .2, 1);
}
* { box-sizing: border-box; }
/* Only <html> gets the black colour, so the fixed gradient (#bg) can show through <body>. */
html { background: #000; -webkit-text-size-adjust: 100%; }
body { margin: 0; color: #fff; font-family: 'Oswald', 'Arial Narrow', sans-serif; overflow-x: clip;
       -webkit-tap-highlight-color: transparent; }

/* Static background: does not move when scrolling. Dark grey centre, black sides. */
#bg { position: fixed; inset: 0; z-index: -1; pointer-events: none;
      background: radial-gradient(ellipse at center, #2e2e2e 0%, #000 100%); }
/* Invisible ruler: the height of the screen (with the browser bars shown), measured by main.js. */
#svh { position: fixed; top: 0; left: 0; width: 0; height: 100svh; visibility: hidden; pointer-events: none; }

/* The page: as tall as the design's page end. */
#page { position: relative; width: 100%; height: calc(var(--ph) * var(--u)); overflow-x: clip; }
/* Header: fixed band at the top of the screen, in front of everything. */
#hdr { position: fixed; top: 0; left: 0; width: 100%; height: calc(var(--hh) * var(--u)); z-index: 10; }

/* Any element placed with design coordinates: --x --y --w --h (design px). */
.abs { position: absolute;
       left: calc(var(--x) * var(--u)); top: calc(var(--y) * var(--u));
       width: calc(var(--w) * var(--u)); height: calc(var(--h) * var(--u)); }
svg.abs { overflow: visible; pointer-events: none; }

/* ---- "Pinned at the end of a zone" ----
   A track as tall as the group + the pin length. Inside it, the group is "sticky": it scrolls with the page,
   stops when the bottom of the screen reaches the zone line, and moves again when the track ends.
   This is done by the browser itself (no JavaScript while scrolling), so it stays smooth on phones. */
.pin-track { pointer-events: none; }
.pin { position: sticky; height: calc(var(--gh) * var(--u));
       top: min(calc(var(--gy) * var(--u)), calc((var(--gy) - var(--zy)) * var(--u) + 100svh)); }
/* Home menu on the Computer layout: stops as soon as it is centred in the space under the header, if that comes first.
   (The block centred = the group plus its margin down to the zone line, so at the design's proportions nothing changes.)
   Same calculation as menuTop() in main.js. */
.pin.centre { top: min(calc(var(--gy) * var(--u)), calc((var(--gy) - var(--zy)) * var(--u) + 100svh),
                       calc(var(--hh-page) * var(--u) + (100svh - var(--hh-page) * var(--u) - (var(--zy) - var(--gy)) * var(--u)) / 2)); }
.pin a, .pin button { pointer-events: auto; }

/* ---- Text ---- --fs = font size in design px.
   Minimum sizes keep text readable when a layout is shrunk (e.g. Computer layout in an 800 px window):
   the text is scaled with the design, but never below --min (12 px for short texts, 14 px for paragraphs). */
.t { display: flex; align-items: center; justify-content: center; text-align: center;
     font-size: max(calc(var(--fs) * var(--u)), var(--min, 12px)); line-height: 1.25; white-space: pre; color: #fff; }
/* line breaks typed in the design editor are kept (pre / pre-line) */
.t.para { --min: 14px; white-space: pre-line; align-items: flex-start; font-weight: 300; }
.t.left { justify-content: flex-start; text-align: left; }
a.t { text-decoration: none; }
button.t, button.ib { background: none; border: 0; padding: 0; margin: 0; font: inherit; color: inherit; cursor: pointer; }
a:focus-visible, button:focus-visible { outline: 2px solid var(--blue); outline-offset: 2px; border-radius: 2px; }
.blue { color: var(--blue); }

/* ---- Home: hero (logo, 3D probe, description) ---- */
/* Header: the 3 links in one centred row, with half-height separators. Underline: grows from left to right on hover,
   shrinks back the same way. Language button: white square, grows on hover. Hover effects only with a mouse. */
/* The row spans the whole header to stay centred, so only its links catch the mouse: it must not cover the language button. */
.hnav { display: flex; align-items: center; justify-content: center; gap: calc(var(--gap) * var(--u)); pointer-events: none; }
.hnav a { pointer-events: auto; }
.hnav a { position: relative; color: #fff; text-decoration: none; text-transform: uppercase; line-height: 1.25; white-space: nowrap;
          font-size: max(calc(var(--fs) * var(--u)), 12px); }
.hnav a::after { content: ''; position: absolute; left: 0; right: 0; bottom: -.1em; height: 1px; background: #fff;
                 transform: scaleX(0); transform-origin: left; transition: transform .25s var(--ease); }
.hnav-sep { flex: none; width: calc(var(--sep-w) * var(--u)); height: calc(var(--sep-h) * var(--u)); background: #fff; }
a.hlang { border: 1px solid #fff; transition: transform .2s var(--ease); }
@media (hover: hover) {
  .hnav a:hover::after { transform: none; }
  a.hlang:hover { transform: scale(1.12); }
}
.hero-sub { color: #bababa; }
/* Second line of the hero: fades in on the inner element; the outer one keeps the scroll fade (fadeHero in main.js). */
.hero-line2 > div { opacity: 0; transition: opacity var(--fade-ms, .6s) ease; }
.hero-line2.show > div { opacity: 1; }
.logo { margin: 0; }
/* Fade while the menu settles in a narrow window (fadeHero in main.js sets these; not set = fully visible) */
.logo, .probe3d { opacity: var(--fade-logo, 1); }
[data-name="HeroDescriptionSubtitle"] { opacity: var(--fade-sub, 1); }
[data-name="HeroDescriptionSubSubTitle"] { opacity: var(--fade-subsub, 1); }
.logo img, .foot-logo img { display: block; }
/* « Sortant du vide » (docs/animations.md): the element is clipped at an imaginary line and slides out of it.
   Upward version: the line is the box's BOTTOM edge (only what is below it is hidden).
   .down version: the line is the box's TOP edge and the element comes down out of it.
   Only `transform` is animated (smooth on phones). Once finished (.done) the clipping is removed. */
.vide { clip-path: inset(-100vh -100vw 0 -100vw); }
.vide > .vide-in { position: relative; height: 100%; transform: translateY(100%); }
.vide.down { clip-path: inset(0 -100vw -100vh -100vw); }
.vide.down > .vide-in { height: auto; transform: translateY(-130%); }   /* past 100 %: letters reach beyond their own box, and nothing may show before it plays */
.vide.play > .vide-in { animation: sortir-du-vide .75s cubic-bezier(.65, 0, .35, 1) forwards; }
.vide.down.play > .vide-in { animation-name: sortir-du-vide-bas; }
.vide.done { clip-path: none; }
.vide.done > .vide-in { transform: none; animation: none; }
@keyframes sortir-du-vide { from { transform: translateY(100%); } to { transform: none; } }
@keyframes sortir-du-vide-bas { from { transform: translateY(-130%); } to { transform: none; } }
/* "UM" fades in once the probe has landed */
.um { opacity: 0; transition: opacity .5s ease; }
.um.show { opacity: 1; }
.probe3d { pointer-events: none; }
.probe3d canvas { display: block; }

/* Loading screen: the usual background with the animated icon in the centre. Covers everything, header included.
   It is present in the page shells so it shows at once. If the page's script could never run, it removes itself after 10 s. */
#loader { position: fixed; inset: 0; z-index: 100; display: flex; align-items: center; justify-content: center;
          background: radial-gradient(ellipse at center, #2e2e2e 0%, #000 100%);
          transition: opacity .25s ease; animation: loader-giveup 0s 10s forwards; }
#loader.out { opacity: 0; pointer-events: none; }
#loader img { width: min(25vw, 110px); height: auto; }
@keyframes loader-giveup { to { visibility: hidden; } }

/* "In development" placeholder: italic text, centred, with the Icone_Barré icon centred under it */
.t.wip { white-space: normal; }
.copyright { --min: 10px; }
.t.disclaimer { --min: 8px; color: #bababa; opacity: .5; line-height: 1.25; white-space: normal; }

/* ---- Home: ultrasound menu ---- */
.mi { opacity: .7; transform: scale(1); transition: transform .35s var(--ease), opacity .35s var(--ease); }
.mi.on { opacity: 1; transform: scale(1.12); }
/* Menu titles: sized with the window, tilted along the curve (--tilt, set in main.js) */
button.mt { font-size: max(calc(var(--fs) * var(--u)), 16px); transform: rotate(var(--tilt, 0deg)); }
button.mt.on { transform: rotate(var(--tilt, 0deg)) scale(1.12); }
.ib img { width: 100%; height: 100%; object-fit: contain; display: block; }
/* Filled icon over the outline one: the two cross-fade when the section is selected */
.mi img { transition: opacity .35s var(--ease); }
.mi img.mi-full { position: absolute; inset: 0; opacity: 0; }
.mi.on img { opacity: 0; }
.mi.on img.mi-full { opacity: 1; }

/* ---- Home: current activities list (site/js/activities.js) ----
   All lengths are design px × --u. Phone = vertical list (.actl-v), computer = horizontal list (.actl-h).
   --pos = where a box starts along the list, --len = its length along the list, --cross = the zone's other dimension. */
.menu-content { pointer-events: none; }
.actl { position: absolute; inset: 0; display: flex; pointer-events: auto; --f: 1; }
.actl-v { flex-direction: column; }
.actl-track { position: relative; flex: none; margin: calc(var(--gap) * var(--u)); }
/* The invisible lines: a box leaving or entering is cropped at the end of the list. Room is left on the sides for the hover growth. */
.actl-v .actl-track { width: 100%; margin-inline: 0; height: calc(var(--track) * var(--u)); clip-path: inset(-3px -12px -3px -12px); }
.actl-h .actl-track { height: 100%; margin-block: 0; width: calc(var(--track) * var(--u)); clip-path: inset(-12px -3px -12px -3px); }
.ab { position: absolute; left: 0; top: 0; transition: transform .5s var(--ease), width .5s var(--ease), height .5s var(--ease); }
.ab.still, .noanim .ab { transition: none; }
.actl-v .ab { width: 100%; height: calc(var(--len) * var(--u)); transform: translateY(calc(var(--pos) * var(--u))); }
.actl-h .ab { height: 100%; width: calc(var(--len) * var(--u)); transform: translateX(calc(var(--pos) * var(--u))); }
/* The card: white, rounded. Hovering makes all of it slightly bigger, text included. */
.ab-card { position: relative; width: 100%; height: 100%; overflow: hidden; border-radius: calc(14 * var(--u)); clip-path: inset(0 round calc(14 * var(--u))); background: #fff; color: #2e2e2e;
           cursor: pointer; transition: transform .25s var(--ease); line-height: 1.2; }
.ab.on .ab-card { cursor: default; }
@media (hover: hover) { .ab-card:hover { transform: scale(1.03); z-index: 1; } }
.ab:has(.ab-card:hover) { z-index: 1; }
/* The two faces keep their own fixed size and cross-fade: text never re-wraps during the movement */
.ab-face { position: absolute; left: 0; top: 0; transition: opacity .3s var(--ease); }
.actl-v .ab-full { width: 100%; height: calc(var(--A) * var(--u)); }
.actl-h .ab-full { height: 100%; width: calc(var(--A) * var(--u)); }
.actl-v .ab-mini { width: 100%; height: calc(var(--C) * var(--u)); }
.actl-h .ab-mini { height: 100%; width: calc(var(--C) * var(--u)); }
.ab .ab-full { opacity: 0; }
.ab.on .ab-full { opacity: 1; }
.ab.on .ab-mini { opacity: 0; }
.ab-photo { background: #bababa; overflow: hidden; }
.ab-photo img { display: block; width: 100%; height: 100%; object-fit: cover; }
.ab-date { color: var(--blue); font-weight: 700; }
.ab-title { color: #2e2e2e; font-weight: 400; overflow: hidden; overflow-wrap: anywhere; display: -webkit-box; -webkit-box-orient: vertical; }
/* Full face: photo on top, then the body. --pad = padding of the body, in design px (not on the photo).
   Left column: date + times, title right under them, button at the bottom. Right column: the location. */
.ab-full { display: grid; grid-template-rows: 42fr 58fr; }
.ab-full .ab-photo { min-height: 0; }
.actl-v { --pad: 12; } .actl-h { --pad: 20; }
.ab-body { display: grid; grid-template-columns: minmax(0, 1fr) auto; grid-template-rows: auto minmax(0, 1fr) auto; column-gap: calc(var(--pad) * var(--u));
           padding: calc(var(--pad) * .7 * var(--u)) calc(var(--pad) * var(--u)) calc(var(--pad) * var(--u)); min-height: 0; }
.ab-when { grid-column: 1; grid-row: 1; display: flex; align-items: flex-start; gap: calc(var(--pad) * var(--u)); min-width: 0; }
.ab-times, .ab-when .ab-date { white-space: nowrap; }
.ab-times { color: var(--blue); text-align: left; display: flex; flex-direction: column; align-items: flex-start; gap: .15em; }
.ab-times i { display: block; width: 45%; height: 1.5px; background: var(--blue); }
/* The zone stays on the right; its texts are left-aligned in it. The icon is drawn from the file's shape in dark grey (the file is white). */
.ab-place { grid-column: 2; grid-row: 1 / 3; align-self: start; display: grid; grid-template-columns: auto auto; column-gap: .3em; justify-content: start; text-align: left; text-decoration: none; }
a.ab-place:hover .ab-general { text-decoration: underline; }
.ab-pin { width: 1em; height: 1lh; background: #2e2e2e; -webkit-mask: url('/assets/icons/Icone_Location.svg') center / contain no-repeat; mask: url('/assets/icons/Icone_Location.svg') center / contain no-repeat; }
.ab-general { color: #2e2e2e; font-weight: 700; }
.ab-detail { grid-column: 2; color: #bababa; }
.ab-body .ab-title { grid-column: 1; grid-row: 2; margin-top: calc(var(--pad) * .35 * var(--u)); align-self: start; -webkit-line-clamp: 3; }
.ab-signup { grid-column: 1; grid-row: 3; align-self: end; display: flex; align-items: center; justify-content: center; background: var(--blue); color: #fff; text-decoration: none;
             margin-top: calc(var(--pad) * .4 * var(--u)); padding: .45em .3em; border-radius: calc(var(--pad) * .5 * var(--u)); font-weight: 500; }
a.ab-signup { transition: margin .2s var(--ease), filter .2s var(--ease); }
/* Hover: wider on both sides (it stays inside the box's padding), the text keeps its shape */
@media (hover: hover) { a.ab-signup:hover { filter: brightness(1.3); margin-inline: calc(var(--pad) * -.5 * var(--u)); } }
.ab-signup.off { display: none; }
/* Phone: the box is too narrow for the location beside the date and times, so it gets its own line under them
   (a smaller photo makes the room). */
.actl-v .ab-full { grid-template-rows: 30fr 70fr; }
.actl-v .ab-body { grid-template-columns: minmax(0, 1fr); grid-template-rows: auto auto minmax(0, 1fr) auto; }
.actl-v .ab-place { grid-column: 1; grid-row: 2; margin-top: calc(var(--pad) * .35 * var(--u)); }
.actl-v .ab-body .ab-title { grid-row: 3; -webkit-line-clamp: 2; }
.actl-v .ab-signup { grid-row: 4; }
/* Sizes of the texts (never under 12 px, as everywhere on the site) */
.actl-v .ab-full .ab-date { font-size: max(calc(19 * var(--u)), 13px); }
.actl-v .ab-times { font-size: max(calc(12 * var(--u)), 12px); }
.actl-v .ab-general { font-size: max(calc(14 * var(--u)), 12px); }
.actl-v .ab-pin { font-size: max(calc(14 * var(--u)), 12px); }
.actl-v .ab-detail { font-size: max(calc(12 * var(--u)), 12px); }
.actl-v .ab-body .ab-title, .actl-v .ab-signup { font-size: max(calc(12.5 * var(--u)), 12px); }
.actl-h .ab-full .ab-date { font-size: max(calc(36 * var(--u)), 13px); }
.actl-h .ab-times { font-size: max(calc(19 * var(--u)), 12px); }
.actl-h .ab-general { font-size: max(calc(25 * var(--u)), 12px); }
.actl-h .ab-pin { font-size: max(calc(25 * var(--u)), 12px); }
.actl-h .ab-detail { font-size: max(calc(19 * var(--u)), 12px); }
.actl-h .ab-body .ab-title { font-size: max(calc(24 * var(--u)), 12px); }
.actl-h .ab-signup { font-size: max(calc(22 * var(--u)), 12px); }
/* Collapsed, phone: date and title on the left, photo on the right */
.actl-v .ab-mini { display: grid; grid-template-columns: 2fr 1fr; }
.ab-minitext { padding: 0 calc(8 * var(--u)); display: flex; flex-direction: column; justify-content: center; gap: .1em; min-width: 0; }
.actl-v .ab-mini .ab-date { font-size: max(calc(12.5 * var(--u)), 12px); white-space: nowrap; }
.actl-v .ab-mini .ab-title { font-size: 12px; -webkit-line-clamp: 2; }
/* Collapsed, computer: photo, date, then the title turned 90° counter-clockwise */
.actl-h .ab-mini { display: grid; grid-template-rows: 44fr 56fr; }
.actl-h .ab-minitext { justify-content: flex-start; gap: .4em; padding: calc(12 * var(--u)) calc(10 * var(--u)); }
.actl-h .ab-mini .ab-date { font-size: max(calc(19 * var(--u)), 12px); }
.actl-h .ab-mini .ab-title { font-size: max(calc(19 * var(--u)), 12px); -webkit-line-clamp: 3; }
.actl-h .ab-mini .ab-photo { min-height: 0; }
/* Arrows: a simple chevron drawn in CSS (replaceable by an icon from the designers). Their slot stays reserved, so boxes never shift. */
.actl-arrow { flex: none; background: none; border: 0; padding: 0; cursor: pointer; display: flex; align-items: center; justify-content: center; }
.actl-v .actl-arrow { width: 100%; height: calc(var(--arrow) * var(--u)); }
.actl-h .actl-arrow { height: 100%; width: calc(var(--arrow) * var(--u)); }
.actl-arrow[hidden] { display: flex; visibility: hidden; }
.actl-arrow::before { content: ''; width: calc(var(--arrow) * .5 * var(--u)); height: calc(var(--arrow) * .5 * var(--u)); border: solid #fff; border-width: 0 3px 3px 0;
                      opacity: .85; transition: opacity .2s var(--ease), transform .2s var(--ease); }
.actl-h .next::before { transform: rotate(-45deg); } .actl-h .prev::before { transform: rotate(135deg); }
.actl-v .next::before { transform: rotate(45deg); } .actl-v .prev::before { transform: rotate(-135deg); }
.actl-arrow:hover::before { opacity: 1; }
.actl-empty { margin: auto; text-align: center; font-size: max(calc(var(--fs, 18) * var(--u)), 13px); font-style: italic; opacity: .85; }

/* ---- Home: lessons list (site/js/lessons.js) ----
   A centred column; space-evenly makes every space equal: above, between lessons and lines, below. */
.lsl { position: absolute; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: space-evenly; }
/* Phone: the list moves left, and the preview takes the room on its right, up to the edge of the blue shape (design px) */
.lsl.phone { left: calc(-80 * var(--u)); right: calc(80 * var(--u)); }
.lsl.phone .ls-gifzone { right: calc(-125 * var(--u)); }
.ls { position: relative; display: block; background: none; border: 0; padding: 0; color: #fff; font: inherit; text-decoration: none; text-align: center;
      cursor: pointer; pointer-events: auto; transition: transform .25s var(--ease); -webkit-tap-highlight-color: transparent; }
/* Growing: with a mouse on hover; on a touch screen on tap (.tap, set by tapLikeHover in lessons.js), not stuck after it. */
.ls:focus-visible, .ls.soon.tap { transform: scale(1.1); z-index: 2; }
@media (hover: hover) {
  .ls:hover { transform: scale(1.1); z-index: 2; }
  .ls.soon:hover .ls-lock { animation: teeter .6s ease-in-out; }
  .ls.soon:hover .ls-soon { opacity: 1; transform: translate(-50%, 0); }
}
.ls.soon { cursor: default; }
.ls-text { display: block; line-height: 1.25; }
.ls-text b { display: block; font-weight: 700; color: #fff; font-size: max(calc(var(--ls-label) * var(--u)), 13px); }
.ls-name { display: block; font-weight: 400; color: #bababa; font-size: max(calc(var(--ls-name) * var(--u)), 12px); }
.ls-line { display: block; flex: none; height: 1px; background: #fff; width: calc(var(--ls-w) * max(calc(var(--ls-label) * var(--u)), 13px)); }
/* Coming soon: dimmed text, padlock on top at full opacity, small box sliding out under the title */
.ls.soon .ls-text { opacity: .5; }
.ls-lock { position: absolute; left: 50%; top: 50%; width: 2.6em; height: 2.6em; margin: -1.3em 0 0 -1.3em; pointer-events: none;
           font-size: max(calc(var(--ls-label) * var(--u)), 13px); }
.ls.soon:focus-visible .ls-lock, .ls.soon.tap .ls-lock { animation: teeter .6s ease-in-out; }
@keyframes teeter { 0%, 100% { transform: rotate(0); } 25% { transform: rotate(-12deg); } 75% { transform: rotate(12deg); } }
.ls-soon { position: absolute; left: 50%; top: 100%; margin-top: .3em; padding: .15em .55em; white-space: nowrap; border-radius: .4em; background: #2e2e2e; color: #fff; font-style: normal;
           font-size: max(calc(var(--ls-name) * .85 * var(--u)), 12px); opacity: 0; transform: translate(-50%, -.5em); pointer-events: none;
           transition: opacity .25s var(--ease), transform .25s var(--ease); }
.ls.soon:focus-visible .ls-soon, .ls.soon.tap .ls-soon { opacity: 1; transform: translate(-50%, 0); }
/* GIF preview: always in the middle of the region to the right of the list, comes from the left.
   The mask turns it into a circle with a very soft edge, like a cloud. */
.ls-gifzone { position: absolute; top: 0; bottom: 0; right: 0; left: calc(50% + var(--ls-listw) / 2 * var(--u)); pointer-events: none; }
.ls-gif { position: absolute; left: 50%; top: 50%; width: min(calc(300 * var(--u)), 100%); aspect-ratio: 1; pointer-events: none;
          opacity: 0; transform: translate(calc(-50% - 30 * var(--u)), -50%); transition: opacity .3s var(--ease), transform .3s var(--ease);
          /* solid only near the centre, then a long and gradual fade (several steps, so no visible edge remains) */
          --cloud: radial-gradient(closest-side, #000 22%, rgba(0, 0, 0, .8) 40%, rgba(0, 0, 0, .5) 58%, rgba(0, 0, 0, .22) 74%, rgba(0, 0, 0, .06) 88%, transparent 100%);
          -webkit-mask-image: var(--cloud); mask-image: var(--cloud); }
.ls-gif video { display: block; width: 100%; height: 100%; object-fit: cover; }
.ls-gif.on { opacity: 1; transform: translate(-50%, -50%); }

/* ---- Lesson: interactive probe (site/js/probe-lesson.js). Fills the screen under the header, without scrolling. ---- */
body[data-page="lesson"] { overflow: hidden; overscroll-behavior: none; }
.lesson { position: fixed; left: 0; right: 0; bottom: 0; top: calc(var(--hh-page) * var(--u)); display: flex; flex-direction: column; }
.pl-area { flex: 1; min-height: 0; display: flex; justify-content: center; }
.pl-stage { position: relative; height: 100%; }
/* Medical disclaimer: very small, centred at the bottom of the page */
.pl-note { flex: none; margin: 0 auto; padding: 2px 8px calc(3px + env(safe-area-inset-bottom)); max-width: 1000px; text-align: center; font-size: 8px; font-weight: 300; line-height: 1.2; color: #bababa; opacity: .5; }
/* the browser must not use drags for scrolling or zooming, or select anything on a long press */
/* The 2D image's frame: a thin white line (half of this stroke width is covered by the image) and a soft dark shadow, stronger toward the bottom, as on the team photos */
.pl-frame { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; pointer-events: none;
            filter: drop-shadow(0 10px 14px rgba(0, 0, 0, .6)) drop-shadow(0 1px 3px rgba(0, 0, 0, .35)); }
.pl-frame path { fill: #000; stroke: #fff; stroke-width: 2.5px; stroke-linejoin: round; }
.pl-stage canvas { position: relative; display: block; width: 100%; height: 100%; touch-action: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
.pl-error { display: flex; align-items: center; justify-content: center; padding: 1em; text-align: center; }
.pl-marker { position: absolute; width: var(--pl-dot); height: var(--pl-dot); border-radius: 50%; background: var(--blue); pointer-events: none;
             box-shadow: 0 0 calc(var(--pl-dot) * .8) rgba(0, 61, 165, .7); }
/* Compression button: bottom left of the 3D area, on touch screens only. Held down, it compresses. */
.pl-compress { display: none; position: absolute; left: 12px; bottom: calc(12px + env(safe-area-inset-bottom)); padding: .6em 1em; font: inherit; font-size: 15px; color: #fff;
               background: rgba(0, 0, 0, .35); border: 1px solid rgba(255, 255, 255, .7); border-radius: 8px; touch-action: none; -webkit-user-select: none; user-select: none;
               -webkit-touch-callout: none; transition: background .15s var(--ease), color .15s var(--ease); }
.pl-compress.on { background: #fff; color: #2e2e2e; }
@media (any-pointer: coarse) { .pl-compress { display: block; } }

/* ---- Lesson course (site/js/lesson-flow.js): places come from the layout, set by the script in px. --lf-u = 1 design px.
   Only transform and opacity are animated. The zones let touches through to the 3D, except on their texts and buttons. ---- */
.lf { --lf-fast: .25s var(--ease); }
.lf-stage, .lf-side, .lf-press, .lf-bar, .lf-arrow, .lf-title, .lf-glass { position: absolute; }
.lf-stage .pl-stage { position: absolute; inset: 0; width: 100%; height: 100%; }
.lf-stage canvas { position: absolute; inset: 0; }
.lf-side { z-index: 2; pointer-events: none; }
.lf-tasks, .lf-hints { position: relative; display: flex; flex-direction: column; align-items: flex-start; gap: calc(6 * var(--lf-u)); padding: 0 calc(10 * var(--lf-u)); }
/* Thin white line between the tasks and the hints */
.lf-hints:not(:empty) { margin-top: calc(14 * var(--lf-u)); padding-top: calc(14 * var(--lf-u)); border-top: 1px solid #fff; }
.lf-row, .lf-hint { pointer-events: auto; }

/* A task: circle (or movement icon) + text. Now = large; done = smaller and half opaque. */
.lf-row { display: flex; align-items: center; gap: .45em; font-size: max(calc(13 * var(--lf-u)), 13px); line-height: 1.15; transform-origin: left center;
          transition: transform .4s var(--ease), opacity .4s var(--ease); }
.lf-row.done { transform: scale(.82); opacity: .5; }
/* Steps 2 and 3: more room between the movements and the current task */
.lf-row[data-kind="current"] { margin-top: calc(14 * var(--lf-u)); }
.lf-row.new { animation: lf-swipe .5s var(--ease); }
@keyframes lf-swipe { from { transform: translateX(-110%); opacity: 0; } to { transform: none; opacity: 1; } }
.lf-circle { position: relative; flex: none; display: block; width: 1.5em; height: 1.5em; border: 1.5px solid #fff; border-radius: 50%; transition: background .3s var(--ease) .35s; }
.lf-circle.fresh { animation: lf-fade .4s var(--ease); }
.lf-circle svg { display: block; width: 100%; height: 100%; }
.lf-tick { stroke: #fff; stroke-dasharray: 1; stroke-dashoffset: 1; }
.checked > .lf-circle { background: #fff; }
.checked > .lf-circle .lf-tick { stroke: #000; stroke-dashoffset: 0; transition: stroke-dashoffset .35s var(--ease), stroke .3s var(--ease) .35s; }
/* Reminders of steps 2 and 3: the movement's icon instead of the circle. Half opaque, lit while that movement is used. */
.lf-row.reminder > .lf-circle { display: none; }
/* Twice as large; their transparent edges may run under the text */
.lf-icon { flex: none; width: 4em; height: 4em; margin: -1em -.7em; object-fit: contain; pointer-events: none; }
.lf-row.reminder { opacity: .5; transform: scale(.82); }
.lf-row.reminder.lit { opacity: 1; transform: none; }

/* A hint: light grey, italics; fades in and out. */
.lf-hint { display: flex; align-items: flex-start; gap: .45em; color: #bababa; font-size: max(calc(12 * var(--lf-u)), 12px); line-height: 1.2; opacity: .5; animation: lf-hint-in .25s var(--ease); }
.lf-hint.out { opacity: 0; transition: opacity .25s var(--ease); position: absolute; }
.lf-words { margin: 0; font-style: italic; }
.lf-words b { color: #fff; }
/* White circle with a black ! : no taller than the text. Its ring empties when the hint has a limited time. */
/* (.95em of the text = 1.46em of the smaller "!": the circle keeps its size, with more room around the "!") */
.lf-bang { position: relative; flex: none; display: flex; align-items: center; justify-content: center; width: 1.46em; height: 1.46em; margin-top: .18em; border-radius: 50%; background: #fff; color: #000; font-size: .65em; font-style: normal; font-weight: 700; line-height: 1; }
.lf-bang .lf-ring { inset: -.46em; width: calc(100% + .92em); height: calc(100% + .92em); }
.lf-ring { position: absolute; inset: -.3em; width: calc(100% + .6em); height: calc(100% + .6em); transform: rotate(-90deg); stroke-dasharray: 1; animation: lf-ring linear forwards; }
.lf-ring circle { stroke: #fff; }
/* The ring around a task's circle: waits for the first movement, and leaves when the task is done */
.lf-circle svg.lf-ring { position: absolute; left: -.3em; top: -.3em; width: calc(100% + .6em); height: calc(100% + .6em); animation-play-state: paused; }
.lf-circle svg.lf-ring.running { animation-play-state: running; }
.checked > .lf-circle .lf-ring { display: none; }
@keyframes lf-ring { from { stroke-dashoffset: 0; } to { stroke-dashoffset: 1; } }
@keyframes lf-fade { from { opacity: 0; } to { opacity: 1; } }
@keyframes lf-hint-in { from { opacity: 0; } }   /* up to the hint's own opacity */

/* The image's marker blinks during the first hint: larger and lighter, again and again. */
/* Both dots, on the image and on the 3D probe: larger than usual while they blink */
.pl-marker.blink, .pl-probe-dot.on { animation: lf-blink 1.35s ease-in-out infinite; }
@keyframes lf-blink { 0%, 33.3%, 100% { transform: scale(1.5); filter: none; } 16.6% { transform: scale(2.3); filter: brightness(1.5); } }
.pl-probe-dot { display: none; z-index: 1; }
.pl-probe-dot.on { display: block; }
/* The image's dot: its own bright blue, used nowhere else */
.lf .pl-marker { background: #2EAFFF; box-shadow: 0 0 calc(var(--pl-dot) * 1.3) rgba(46, 175, 255, .95); }

/* Compression button: touch only, appears the moment a touch is detected */
.lf-press { display: none; z-index: 3; padding: 0; background: none; border: 0; cursor: pointer; touch-action: none; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; transition: transform .15s var(--ease); }
.lf.touch .lf-press { display: block; }
.lf-press img { display: block; width: 100%; height: 100%; pointer-events: none; }
.lf-press.on { transform: scale(.88); opacity: .75; }

/* Progress bar */
.lf-bar { border: 1.5px solid #fff; border-radius: calc(4 * var(--lf-u)); z-index: 3; }
.lf-fill { position: absolute; inset: 0; background: #fff; border-radius: inherit; transform: scaleX(0); transform-origin: left; transition: transform .55s var(--ease); }
.lf-bar.grow { animation: lf-grow .55s var(--ease); }
@keyframes lf-grow { 50% { transform: scaleY(1.35); } }
.lf-mark { position: absolute; bottom: calc(100% + 3px); width: 1.5px; height: calc(7 * var(--lf-u)); min-height: 5px; margin-left: -.75px; background: #fff; opacity: .5; transition: opacity .4s var(--ease); }
.lf-mark.on { opacity: 1; }
.lf-title { z-index: 3; margin-top: 2px; text-align: center; font-size: max(calc(12 * var(--lf-u)), 12px); line-height: 1.2; white-space: nowrap; pointer-events: none; }
.lf-arrow { z-index: 3; display: flex; align-items: center; justify-content: center; padding: 0; background: none; border: 0; color: #fff; cursor: pointer; transition: transform .2s var(--ease); }
.lf-arrow svg { display: block; width: min(100%, 16px); height: min(100%, 16px); }
.lf-arrow.back svg { transform: scaleX(-1); }
.lf-arrow:active { transform: scale(1.25); }
@media (hover: hover) { .lf-arrow:hover { transform: scale(1.25); } }

/* Bottom of the lessons: only the disclaimer, centred, in very small text. */
.lf-footer { position: absolute; left: 0; right: 0; bottom: 0; display: flex; align-items: center; justify-content: center; padding: 0 8px env(safe-area-inset-bottom); z-index: 6; }
.lf-footer p { margin: 0; max-width: 1000px; text-align: center; font-size: max(calc(7 * var(--lf-u)), 7px); font-weight: 300; line-height: 1.15; color: #bababa; }

/* Frosted glass: a dark veil and one small blurred picture of the lesson. Blurred once: it costs nothing afterwards. */
.lf-glass { z-index: 4; overflow: hidden; background: rgba(20, 20, 20, .72); opacity: 0; pointer-events: none; transition: opacity .9s var(--ease); }
.lf-glass.still { transition: none; }
.lf-glass.on { opacity: 1; pointer-events: auto; }
.lf-glass canvas { position: absolute; filter: blur(10px); opacity: .55; }

/* Title page: text in one half of the screen, the preview in the other */
.lf-intro { position: absolute; inset: 0; z-index: 5; display: none; }
.lf-intro.on { display: flex; flex-direction: column; animation: lf-fade .4s var(--ease); }
@media (min-width: 700px) { .lf-intro.on { flex-direction: row; } }
.lf-intro-text, .lf-gif { flex: 1 1 50%; min-width: 0; min-height: 0; }
.lf-intro-text { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: calc(14 * var(--lf-u)); padding: 12px; text-align: center; }
.lf-number { font-size: max(calc(22 * var(--lf-u)), 18px); font-weight: 700; }
.lf-name { margin: 0; font-size: max(calc(30 * var(--lf-u)), 24px); font-weight: 400; line-height: 1.15; }
.lf-btn { position: relative; display: inline-flex; align-items: center; gap: .4em; padding: .45em 1em; background: transparent; border: 1.5px solid #fff; border-radius: .5em; color: #fff; font: inherit; font-weight: 400;
          font-size: max(calc(18 * var(--lf-u)), 16px); text-decoration: none; cursor: pointer; transition: transform .25s var(--ease), background .25s var(--ease), color .25s var(--ease); }
.lf-btn svg { display: block; width: .7em; height: .7em; }
.lf-btn.home svg { transform: scaleX(-1); }
.lf-btn:not(.soon):focus-visible, .lf-btn:not(.soon):active { background: #fff; color: #000; transform: scale(1.08); }
@media (hover: hover) { .lf-btn:not(.soon):hover { background: #fff; color: #000; transform: scale(1.08); } }
/* The next lesson is not open yet: dimmed button, crossed-out icon on top that teeters */
.lf-btn.soon { cursor: default; border-color: rgba(255, 255, 255, .5); color: rgba(255, 255, 255, .5); }
.lf-lock { position: absolute; left: 50%; top: 50%; width: 2.2em; height: 2.2em; margin: -1.1em 0 0 -1.1em; pointer-events: none; }
.lf-btn.soon.tap .lf-lock { animation: teeter .6s ease-in-out; }
/* same box as in the list of lessons (.ls-soon) */
.lf-soon { position: absolute; left: 50%; top: 100%; margin-top: .3em; padding: .15em .55em; white-space: nowrap; border-radius: .4em; background: #2e2e2e; color: #fff; font-size: .75em; opacity: 0; transform: translate(-50%, -.5em); pointer-events: none; z-index: 2; transition: opacity .25s var(--ease), transform .25s var(--ease); }
.lf-btn.soon.tap .lf-soon { opacity: 1; transform: translate(-50%, 0); }
@media (hover: hover) { .lf-btn.soon:hover .lf-lock { animation: teeter .6s ease-in-out; } .lf-btn.soon:hover .lf-soon { opacity: 1; transform: translate(-50%, 0); } }
/* Preview: same circle with a very soft edge as on the home page (.ls-gif) */
.lf-gif { display: flex; align-items: center; justify-content: center; padding: 8px;
          --cloud: radial-gradient(closest-side, #000 22%, rgba(0, 0, 0, .8) 40%, rgba(0, 0, 0, .5) 58%, rgba(0, 0, 0, .22) 74%, rgba(0, 0, 0, .06) 88%, transparent 100%); }
.lf-gif video { display: block; width: min(100%, 60vh); max-height: 100%; aspect-ratio: 1; object-fit: cover; -webkit-mask-image: var(--cloud); mask-image: var(--cloud); }

/* Computer: the texts are larger, on a screen seen from farther away */
@media (min-width: 700px) {
  .lf-row { font-size: max(calc(24 * var(--lf-u)), 15px); }
  .lf-hint { font-size: max(calc(20 * var(--lf-u)), 14px); }
  .lf-title { font-size: max(calc(17 * var(--lf-u)), 13px); }
  .lf-footer p { font-size: max(calc(10 * var(--lf-u)), 8px); }
  .lf-number { font-size: max(calc(34 * var(--lf-u)), 20px); }
  .lf-name { font-size: max(calc(54 * var(--lf-u)), 28px); }
  .lf-btn { font-size: max(calc(26 * var(--lf-u)), 17px); }
}

/* Loading between two organs */
.lf-loading { position: absolute; inset: 0; z-index: 5; display: none; align-items: center; justify-content: center; background: rgba(0, 0, 0, .6); }
.lf-loading.on { display: flex; }
.lf-loading img { width: 72px; height: 72px; }
/* Placing a reference view (address + ?poses): the numbers of the current pose */
.lf-poses { position: absolute; left: 4px; right: 4px; bottom: 44px; z-index: 9; margin: 0; padding: 2px 4px; background: #000; color: #fff; font: 11px monospace; white-space: pre-wrap; -webkit-user-select: text; user-select: text; }

/* ---- About: "Rencontrez l'équipe" (site/js/team.js). Sizes in design px × --u. ---- */
.tm { height: auto; display: flex; flex-direction: column; gap: calc(var(--tm-gs) * var(--u)); padding-bottom: calc(var(--tm-end) * var(--u)); }
/* A profile (photo + text) grows on hover and shrinks back when the mouse leaves. */
.tm-p { transition: transform .25s var(--ease); }
@media (hover: hover) { .tm-p:hover { transform: scale(1.08); position: relative; z-index: 1; } }
.tm-sep { display: block; flex: none; align-self: center; width: 50%; height: 1px; background: #fff; }
.tm-title { margin: 0 0 calc(var(--tm-gt) * var(--u)); text-align: center; font-weight: 700; line-height: 1.25;
            font-size: max(calc(var(--tm-title) * var(--u)), 13px); }
/* --tm-max: only set for a category of exactly 4 (even lines rather than 3 + 1 on a phone) */
.tm-row { display: flex; flex-wrap: wrap; justify-content: center; align-items: flex-start; margin: 0 auto; max-width: calc(var(--tm-max, 99999) * var(--u));
          gap: calc(var(--tm-gpy) * var(--u)) calc(var(--tm-gpx) * var(--u)); }
.tm-p { margin: 0; flex: none; width: calc(var(--tm-cell) * var(--u)); display: flex; flex-direction: column; align-items: center; text-align: center; }
/* Square photo, cropped to fit. A dark and subtle shadow, stronger toward the bottom. */
.tm-photo { width: calc(var(--tm-photo) * var(--u)); height: calc(var(--tm-photo) * var(--u)); flex: none; background: #2e2e2e; overflow: hidden;
            box-shadow: 0 calc(8 * var(--u)) calc(16 * var(--u)) rgba(0, 0, 0, .6), 0 1px 4px rgba(0, 0, 0, .35); }
.tm-photo img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 50% 15%; }   /* portraits: keeps the top of the head */
.tm-p figcaption { margin-top: calc(var(--tm-gx) * var(--u)); line-height: 1.25; width: 100%; }
.tm-name { display: block; font-weight: 700; opacity: 1; font-size: max(calc(var(--tm-name) * var(--u)), 12px); }
.tm-year { display: block; font-weight: 300; opacity: .7; font-size: max(calc(var(--tm-year) * var(--u)), 12px); }

/* The footer's layer on the About page: follows the team's height (--shift, set by followTeam in main.js). */
.foot-layer { position: absolute; left: 0; top: 0; width: 100%; height: 0; transform: translateY(calc(var(--shift, 0) * var(--u))); }

/* ---- About: mission (3 parts). Only transform and opacity move, so it stays smooth on phones. ---- */
.m-text { color: #bababa; line-height: 1.45; }
.m-sub > .vide-in { display: flex; align-items: center; justify-content: center; width: 100%; }
.m-dot { border-radius: 50%; background: #fff; opacity: .5; transform: scale(.6); transition: opacity .3s var(--ease), transform .3s var(--ease); }
.m-dot.on { opacity: 1; transform: none; }

/* ---- About: activities list (titles + one open description) ---- */
.acts { display: flex; flex-direction: column; }
button.act-t { position: relative; justify-content: flex-start; text-align: left; height: max(calc(var(--th) * var(--u)), 1.1em); flex: none;
               font-size: max(calc(var(--fs) * var(--u)), 13px); padding-left: calc(var(--title-x) * var(--u)); opacity: .7; transition: opacity .25s var(--ease); }
/* Equilateral triangle pointing right, centred in the arrow's box: outline only; when open, filled and pointing down. */
.act-arrow { position: absolute; top: 50%; left: calc((var(--arrow-x) + var(--arrow-w) * .34) * var(--u)); width: calc(var(--arrow-w) * .32 * var(--u)); aspect-ratio: .87;
             transform: translateY(-50%); transition: transform .25s var(--ease); }
.act-arrow svg { display: block; width: 100%; height: 100%; overflow: visible; }
.act-arrow polygon { fill: transparent; stroke: currentColor; stroke-width: 9; stroke-linejoin: round; transition: fill .25s var(--ease); }
.act-t.on .act-arrow { transform: translateY(-50%) rotate(90deg); }
.act-t.on .act-arrow polygon { fill: currentColor; }
/* Small line under the open title: grows from left to right, and shrinks back the same way. */
.act-line { position: absolute; top: 100%; left: calc(var(--line-x) * var(--u)); width: calc(var(--line-w) * var(--u)); height: max(calc(var(--line-h) * var(--u)), 1px);
            background: #fff; transform: scaleX(0); transform-origin: left; transition: transform .3s var(--ease); }
.act-t.on .act-line { transform: none; }
button.act-t + .act-d + .act-t { margin-top: calc(var(--tg) * var(--u)); }
button.act-t:hover { opacity: .9; }
button.act-t.on { opacity: 1; }
/* Collapsing: closing happens at once, opening waits until the closing is done (transition-delay). */
.act-d { display: grid; grid-template-rows: 0fr; transition: grid-template-rows .25s var(--ease); }
.act-d.open { grid-template-rows: 1fr; transition-delay: .25s; }
.act-d > div { overflow: hidden; min-height: 0; }
/* The paragraph takes only the room its text needs: the next title follows it at the same distance as
   between two titles (--tg), at all times (designers' choice 2026-10-29, instead of the design box height). */
.act-d p { margin: 0; padding: calc(var(--dg) * var(--u)) 0 0 calc(var(--desc-x) * var(--u));
           font-size: max(calc(var(--fs) * var(--u)), 13px); font-weight: 300; line-height: 1.35; }
.photos { overflow: hidden; }
.photos img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* new photo "swishes" in from left to right over the old one */
.photos img.in { animation: wipe .6s var(--ease) both; }
@keyframes wipe { from { clip-path: inset(0 100% 0 0); } to { clip-path: inset(0 0 0 0); } }
/* "Nos activités": blue section (height set by placeAbout in main.js). The image takes half of it and fades toward the middle:
   opacity 0 in the middle of the screen, .7 at 75 %, 1 at the edge. The blue stays behind it. */
.acts-sec { --wedge: 70; background: var(--blue); overflow: hidden; }
/* White right-angle triangles along the top and bottom edges, as wide as the page, so the blue's edges look diagonal.
   Top: right angle in the top-left corner. Bottom: right angle in the bottom-right corner. --wedge = height, design px (same value as ACTS_WEDGE in main.js). */
.acts-sec::before, .acts-sec::after { content: ''; position: absolute; left: 0; right: 0; height: calc(var(--wedge) * var(--u)); background: #fff; z-index: 1; pointer-events: none; }
.acts-sec::before { top: 0; clip-path: polygon(0 0, 100% 0, 0 100%); }
.acts-sec::after { bottom: 0; clip-path: polygon(100% 0, 100% 100%, 0 100%); }
@media (max-width: 699.98px) { .acts-sec { --wedge: 36; } }
.acts-sec .photos { -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0, 0, 0, .7) 50%, #000 100%); mask-image: linear-gradient(to right, transparent 0%, rgba(0, 0, 0, .7) 50%, #000 100%);
                    left: 50%; top: 0; width: 50%; height: 100%; }
@media (max-width: 699.98px) {
  .acts-sec .photos { -webkit-mask-image: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, .7) 50%, #000 100%); mask-image: linear-gradient(to bottom, transparent 0%, rgba(0, 0, 0, .7) 50%, #000 100%);
                      left: 0; top: auto; bottom: 0; width: 100%; height: calc(230 * var(--u)); }
}
.graphic { object-fit: contain; }

/* ---- Footer ---- */
.foot-logo img, .social img { width: 100%; height: 100%; object-fit: contain; }
.foot-nav { display: grid; grid-template-columns: 1fr 1fr; align-items: start;
            font-size: max(calc(var(--fs) * var(--u)), 12px); line-height: 1.3; }
.foot-nav div { display: flex; flex-direction: column; align-items: flex-start; }
.foot-nav a { color: #fff; text-decoration: none; white-space: nowrap; }
.fn-title { font-weight: 600; }
.fn-link { opacity: .6; transition: opacity .2s var(--ease); }
.fn-link:hover { opacity: .8; }

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0s !important; transition-delay: 0s !important; animation-duration: 0s !important; }
}
