/* ==========================================================================
   Feder · page-level additions
   tokens.css, motion.css and motion.js come untouched from the feder-ui skill
   (default register: minimal monochrome card, no colour accent anywhere).
   This file only holds what the skill's one-field waitlist doesn't ship:
   the extra fields (prénom / nom), the consent line, and the plain text
   pages (mentions légales, confidentialité, 404).
   It only reuses skill tokens — no new colours, radii or fonts.
   ========================================================================== */

/* ---------- brand mark: the client's own logo (white PNG on transparent) ----------
   Replaces the skill's placeholder eye. It is wider than the placeholder (about 3.7:1), so it
   gets a wider box, and it is dimmed to the muted-ink level the skill uses for .brand-mark. */
img.brand-mark{width:150px;height:auto;opacity:.78;user-select:none;-webkit-user-drag:none}

/* ---------- date (top) and venue (bottom): thin type framing the card ----------
   Inter 300 in the skill's full ink colour: thin, but still clearly readable. Wide tracking keeps thin
   strokes legible; a soft black halo (no visible shadow) holds the contrast when a bright reflection of the
   background video passes behind the text. The card is a flex column: the first item pushes the content
   down and the last one pushes it up, so the centre block stays centred between them. */
.card{padding:calc(30px + env(safe-area-inset-top,0px)) 24px calc(26px + env(safe-area-inset-bottom,0px))}
.edge{font-family:var(--font-ui);font-weight:300;color:var(--ink);text-align:center;
  text-shadow:0 0 14px rgba(0,0,0,.7),0 1px 2px rgba(0,0,0,.45)}
.edge-top{margin:0 0 auto;padding-bottom:28px;font-size:16px;letter-spacing:.3em;font-variant-numeric:tabular-nums}
/* the date is set in Orbitron (Google Fonts, loaded in index.html). 400 is Orbitron's lightest weight. */
.orbitron,.edge-top time{font-family:"Orbitron",var(--font-ui);font-optical-sizing:auto;font-weight:400;font-style:normal}
.edge-top{font-size:15px;letter-spacing:.2em}
.edge-top time{margin-right:-.2em}     /* cancels the trailing letter-space so the text is optically centred */
.edge-bottom{display:flex;flex-direction:column;align-items:center;margin-top:auto;padding-top:28px}
.venue{font-size:14px;letter-spacing:.2em;text-decoration:underline;text-decoration-thickness:1px;
  text-underline-offset:6px;text-decoration-color:rgba(237,237,234,.35);transition:text-decoration-color .2s ease}
@media (hover:hover){.venue:hover{text-decoration-color:var(--ink)}}
.edge-bottom .legal-links{margin-top:14px}

/* ---------- perks ticker: what signing up unlocks ----------
   A full-bleed tape between the wordmark and the form (it replaces the small hairline). Thin Inter in the
   theme's ink, the logo's four-point spark as the separator, a very slow drift, and the ends fade out.
   Under .js the group is cloned by main.js as often as the screen width needs, and the track slides by
   exactly one group (--gw) in a loop, at a constant speed (--dur).
   With prefers-reduced-motion it stops and shows a single static, centred group. */
.marquee{width:100vw;max-width:none;align-self:center;margin:26px 0 28px;overflow:hidden;
  border-top:var(--bw) solid var(--line);border-bottom:var(--bw) solid var(--line);
  -webkit-mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent);
          mask-image:linear-gradient(90deg,transparent,#000 12%,#000 88%,transparent)}
.marquee-track{display:flex;width:max-content;margin:0 auto}
.marquee-group{display:flex;align-items:center;flex:none;list-style:none;padding:0;margin:0}
.marquee-group li{flex:none;padding:13px 20px;font-family:var(--font-ui);font-weight:300;font-size:12px;line-height:1;
  letter-spacing:.32em;text-transform:uppercase;color:var(--ink);white-space:nowrap;
  text-shadow:0 0 12px rgba(0,0,0,.7),0 1px 2px rgba(0,0,0,.45)}
.marquee-group li.sep{padding:13px 0;display:flex;align-items:center}
.spark-sep{width:11px;height:11px;color:var(--ink-muted)}
@keyframes marquee-slide{to{transform:translateX(calc(var(--gw,0px) * -1))}}
.js .marquee-track{margin:0;animation:marquee-slide var(--dur,34s) linear infinite}
@media (hover:hover){.marquee:hover .marquee-track{animation-play-state:paused}}
@media (prefers-reduced-motion:reduce){
  .js .marquee-track{animation:none;margin:0 auto}
  .marquee-group[aria-hidden="true"]{display:none}
  .marquee{-webkit-mask-image:none;mask-image:none}
  .marquee-group{flex-wrap:wrap;justify-content:center}
}

/* ---------- confirmation: the perks, once the person is in ---------- */
.done-lead{max-width:24ch;font-size:13px;line-height:1.5;color:var(--ink-muted)}
.perks{list-style:none;margin:2px 0 6px;padding:0;display:grid;gap:2px}
.perks li{font-family:var(--font-ui);font-weight:700;font-size:18px;line-height:1.55;color:var(--ink);
  opacity:0;transform:translateY(6px);transition:opacity .5s ease calc(.35s + var(--i) * .11s),transform .5s ease calc(.35s + var(--i) * .11s)}
.form-done.is-in .perks li{opacity:1;transform:none}

/* ---------- background video: fixed, full-bleed, behind everything ----------
   The clip is monochrome (liquid metal), so it stays inside the "no colour" rule.
   .bg-scrim keeps small text legible over the bright highlights; the skill's own
   .vignette (z-index 0) and .card (z-index 1) sit on top. */
.bg-video{position:fixed;inset:0;z-index:-2;width:100%;height:100%;object-fit:cover;pointer-events:none;background:var(--bg)}
.bg-video.is-top{z-index:-1}   /* la copie qui apparaît en fondu passe au-dessus (voir background.js) */
.bg-scrim{position:fixed;inset:0;z-index:0;pointer-events:none;background:rgba(13,13,13,.5)}

/* ---------- waitlist: prénom + nom on one row, email below ---------- */
.f-row{display:grid;grid-template-columns:1fr 1fr;gap:12px}
.f-group + .f-group,.f-row + .f-group{margin-top:16px}
/* ---------- rounded shapes: fields and button are full pills ----------
   Client request. Uses the skill's own --r-pill token (999px) instead of the default 6px radius;
   text is inset a little more so it clears the curve, and the small labels follow. */
.waitlist input:not([type="checkbox"]),.waitlist-submit{border-radius:var(--r-pill)}
.waitlist input:not([type="checkbox"]){padding-left:22px;padding-right:22px}
.waitlist .f-row input{padding-left:20px;padding-right:20px}
.waitlist .f-label{padding-left:18px}

/* ---------- outline width shared by the fields and the button ----------
   Client request: half of the skill's 1px. On a phone (2-3 device pixels per CSS pixel) this is a true
   hairline; a 1x desktop screen cannot draw less than one device pixel, so it rounds back up to 1px there. */
:root{--bw:.5px}

/* ---------- fields: full pill outline ----------
   The outline is drawn on the wrapper (.field::after) rather than on the input, so the shake animation (which
   moves the wrapper) carries it along. It is complete all the way round — the interrupted version from the
   client reference image was dropped on request (it is in the git history, commit "Champs à contour interrompu").
   Placeholder and typed text are centred. */
.field{position:relative}
.field::after{content:"";position:absolute;inset:0;border-radius:var(--r-pill);border:var(--bw) solid var(--line-strong);pointer-events:none}
.waitlist .field input{border-color:transparent;text-align:center}
/* no fill: the field is frosted glass. Only a blur of whatever is behind it (the video), plus the outline.
   backdrop-filter needs the -webkit- form for older Safari. */
.waitlist .field input{background:transparent;-webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}
/* browsers paint their own opaque fill on autofilled fields, which would break the glass look:
   hold that fill off for a very long time and keep the text in the theme's ink colour */
.waitlist .field input:-webkit-autofill{-webkit-text-fill-color:var(--ink);caret-color:var(--ink);
  transition:background-color 99999s ease-in-out 0s}
.waitlist .field input::placeholder{color:var(--ink-muted)}
/* the shake moves the whole wrapper, so the outline follows the field */
.waitlist .field input.is-invalid{animation:none}
.field:has(input.is-invalid){animation:field-shake .45s ease}

/* ---------- submit button: frosted glass too ----------
   No fill any more — a blur of what is behind it, a full outline of the same width as the fields, and the
   label in the theme's light ink (dark text on glass would be unreadable). The skill's inset highlights were
   made for a filled button, so they are switched off; press feedback becomes a faint light wash. */
.waitlist-submit{background:transparent;color:var(--ink);border:var(--bw) solid var(--line-strong);box-shadow:none;
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px);
  transition:transform .28s cubic-bezier(.3,1.5,.5,1),background-color .2s ease,border-color .3s ease}
.waitlist-submit:active{box-shadow:none;background:rgba(255,255,255,.1)}
@media (hover:hover){.waitlist-submit:hover{filter:none;background:rgba(255,255,255,.06)}}
/* while it dissolves, the outline and the blur leave with the label */
.waitlist-submit.is-dissolving{border-color:transparent;-webkit-backdrop-filter:none;backdrop-filter:none}

/* consent: a small round check, same crisp border as the inputs, monochrome */
.waitlist .consent{display:flex;align-items:flex-start;gap:10px;margin-top:16px;
  font-size:12px;line-height:1.45;color:var(--ink-muted);cursor:pointer}
.waitlist .consent input{flex:none;width:16px;height:16px;padding:0;margin:1px 0 0;
  appearance:none;-webkit-appearance:none;border-radius:50%;cursor:pointer;
  background:var(--bg) center/11px no-repeat;transition:background-color .15s ease}
.waitlist .consent input:checked{background-color:var(--ink);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%230d0d0d' stroke-width='3.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 13l4 4L19 7'/%3E%3C/svg%3E")}
.waitlist .consent a{color:var(--ink);text-decoration:underline;text-underline-offset:2px}

/* ---------- the whole form disperses like smoke on a valid submit (see form-dissolve.js) ----------
   The button uses the skill's own dissolve; the fields, labels and consent line fade + blur out in a
   wave (--sd = per-block delay) while a canvas draws the same grey dust the skill uses. Monochrome. */
.card{overflow-x:clip}   /* the smoke canvas is wider than the form: never let it create a sideways scroll on a phone */
.form-stage{position:relative}
.form-body [data-smoke]{transition:opacity .6s ease var(--sd,0ms),filter .6s ease var(--sd,0ms),transform .8s ease var(--sd,0ms)}
.form-body.is-smoking{pointer-events:none}
.form-body.is-smoking [data-smoke]{opacity:0;filter:blur(7px);transform:translateY(-10px)}
.form-body.is-gone{visibility:hidden}
.form-dust{position:absolute;z-index:2;pointer-events:none;opacity:0}

/* confirmation that takes the form's place */
.form-done{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:14px;
  text-align:center;opacity:0;transition:opacity .6s ease}
.form-done.is-in{opacity:1}
/* an author `display:flex` beats the browser's own [hidden] rule, which left this invisible panel
   sitting on top of the form and swallowing every click — so [hidden] must win explicitly */
[hidden]{display:none!important}
.done-msg{font-size:15px;font-weight:600;color:var(--ink)}
.again{padding:6px 4px;font-size:12px;color:var(--ink-muted);text-decoration:underline;text-underline-offset:3px}
@media (hover:hover){.again:hover{color:var(--ink)}}

/* honeypot: real people never see or tab into it */
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}

/* errors stay colourless: same line, full ink instead of dim */
.waitlist-status.is-error{color:var(--ink)}

@media (max-width:360px){
  .f-row{grid-template-columns:1fr}
}

/* ---------- legal links under the card ---------- */
.legal-links{margin-top:22px;display:flex;flex-wrap:wrap;gap:4px 16px;justify-content:center;font-size:12px;color:var(--ink-dim)}
@media (hover:hover){.legal-links a:hover{color:var(--ink)}}

/* ---------- text pages (legal, 404) ---------- */
.doc{position:relative;z-index:1;min-height:100svh;display:flex;flex-direction:column;align-items:center;padding:48px 24px 40px}
.doc .brand-mark{margin-bottom:26px}
.doc-body{width:100%;max-width:640px}
.doc h1{font-family:var(--font-display);font-size:clamp(28px,6vw,44px);line-height:.98;text-transform:uppercase;text-align:center;margin-bottom:8px}
.doc h2{font-family:var(--font-ui);font-size:11px;font-weight:700;letter-spacing:.12em;text-transform:uppercase;color:var(--ink-muted);margin:32px 0 9px}
.doc p,.doc li{font-size:15px;line-height:1.6}
.doc p+p{margin-top:12px}
.doc a{text-decoration:underline;text-underline-offset:2px}
.doc .todo{color:var(--ink-muted);border-bottom:1px dashed var(--ink-dim)}
.doc .back{margin-top:44px;text-align:center;font-size:12px;color:var(--ink-dim)}
.doc .back a{color:var(--ink-muted)}

.notfound{position:relative;z-index:1;min-height:100svh;display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:64px 24px}
.notfound .brand-mark{margin-bottom:22px}
.notfound h1{font-family:var(--font-display);text-transform:uppercase;line-height:.92;font-size:clamp(46px,13vw,92px)}
.notfound .waitlist-submit{display:inline-flex;align-items:center;justify-content:center;width:auto;padding:0 28px;margin-top:0}
.notfound .hairline{margin:26px auto 28px}

/* ---------- entrée de page (intro.js) ----------
   Avant .intro-go : tout est masqué. Le wordmark est révélé par le canvas de fumée puis en fondu ;
   les autres blocs entrent ensuite l'un après l'autre. Filet de sécurité : si intro.js ne tourne pas,
   tout devient visible après 4 s. Avec « moins d'animations » : visible tout de suite. */
.js .card > *{opacity:0;filter:blur(6px);animation:intro-failsafe .01s 4s forwards}
.js .card > .brand-stack{filter:blur(10px)}
.js.intro-go .card > *{opacity:1;filter:none;animation:none;
  transition:opacity 1s ease var(--rd,0ms),filter 1.1s ease var(--rd,0ms)}
.js.intro-go .card > .brand-stack{--rd:0ms;transition-duration:1.2s,1.4s}
.js.intro-go .card > .brand-mark{--rd:150ms}
.js.intro-go .card > .edge-top{--rd:650ms}
.js.intro-go .card > .marquee{--rd:1000ms}
.js.intro-go .card > .waitlist{--rd:1350ms}
.js.intro-go .card > .edge-bottom{--rd:1700ms}
@keyframes intro-failsafe{to{opacity:1;filter:none}}
@media (prefers-reduced-motion:reduce){
  .js .card > *{opacity:1;filter:none;animation:none}
}
