  :root{
    --bg:#080a08;
    --bg-2:#0c0f0c;
    --panel:#10140f;
    --panel-2:#141a12;
    --ink:#eaf0e6;
    --muted:#8d978a;
    /* raised from #646e62: at 12px that was a 3.5:1 contrast ratio,
       below the 4.5 WCAG AA needs for normal text. Now 5.2:1. */
    --muted-2:#808a7e;
    --line:rgba(196,240,66,.13);
    --line-soft:rgba(255,255,255,.07);
    --lime:#c4f042;
    --lime-deep:#a6d62a;
    --blue:#5b8cff;
    --blue-dim:rgba(91,140,255,.16);
    --radius:14px;
    --maxw:1180px;
    --mono:"JetBrains Mono",ui-monospace,Menlo,monospace;
    --disp:"Bricolage Grotesque",sans-serif;
    --body:"Hanken Grotesk",system-ui,sans-serif;
      --how-bg:      #10130c;
      --how-surface: #181c10;
      --how-border:  #323a22;
      --how-spine:   #2c3320;
      --how-accent:  #aee63f;
      --how-heading: #f4f6ee;
      --how-body:    #bcc1b0;
  }
  *{box-sizing:border-box}
  html{scroll-behavior:smooth}
  /* the nav is sticky and 66px tall, so an anchor would otherwise land its
     target's heading underneath it. Applied to anything addressable by id
     rather than section by section. */
  :target,[id]{scroll-margin-top:86px}
  body{
    margin:0;background:var(--bg);color:var(--ink);
    font-family:var(--body);font-size:17px;line-height:1.6;
    -webkit-font-smoothing:antialiased;overflow-x:hidden;
  }
  /* layered atmosphere */
  body::before{
    content:"";position:fixed;inset:0;z-index:-3;
    background:
      radial-gradient(900px 600px at 82% -8%, rgba(196,240,66,.10), transparent 60%),
      radial-gradient(700px 500px at 8% 12%, rgba(91,140,255,.07), transparent 60%),
      linear-gradient(180deg,var(--bg),var(--bg-2));
  }
  body::after{
    content:"";position:fixed;inset:0;z-index:-2;pointer-events:none;opacity:.4;
    background-image:linear-gradient(var(--line-soft) 1px,transparent 1px),
      linear-gradient(90deg,var(--line-soft) 1px,transparent 1px);
    background-size:46px 46px;
    -webkit-mask-image:radial-gradient(circle at 50% 30%,#000 0%,transparent 78%);
    mask-image:radial-gradient(circle at 50% 30%,#000 0%,transparent 78%);
  }
  .grain{position:fixed;inset:0;z-index:-1;pointer-events:none;opacity:.045;
    background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");}

  .wrap{max-width:var(--maxw);margin:0 auto;padding:0 26px}
  a{color:inherit;text-decoration:none}
  .mono{font-family:var(--mono);letter-spacing:.02em}
  .eyebrow{font-family:var(--mono);font-size:12.5px;letter-spacing:.12em;text-transform:uppercase;color:var(--lime-deep)}

  /* ---------- nav ---------- */
  nav{position:sticky;top:0;z-index:50;backdrop-filter:blur(11px);
    background:linear-gradient(180deg,rgba(8,10,8,.86),rgba(8,10,8,.55));
    border-bottom:1px solid var(--line-soft)}
  .nav-in{display:flex;align-items:center;justify-content:space-between;height:66px}
  .logo{display:flex;align-items:center;gap:10px;font-family:var(--disp);font-weight:800;font-size:20px;letter-spacing:-.01em}
  .logo .dot{width:11px;height:11px;border-radius:3px;background:var(--lime);box-shadow:0 0 16px var(--lime);transform:rotate(12deg)}
  .nav-links{display:flex;gap:30px;align-items:center}
  .nav-links a{color:var(--muted);font-size:14.5px;transition:color .2s}
  .nav-links a:hover{color:var(--ink)}
  /* buttons in the nav keep their own text color (the rules above are for plain links) */
  .nav-links a.btn-primary{color:#10130a}
  .nav-links a.btn-primary:hover{color:#10130a}
  .nav-links a.btn-ghost,.nav-links a.btn-ghost:hover{color:var(--ink)}
  /* active section link (excludes the FR/EN switch, which has its own active style) */
  .nav-links .nav-right > a.active,.nav-links > a.active{color:var(--lime)}
  /* open-tickets count pill next to "Aide" */
  .nav-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;padding:0 5px;
    margin-left:2px;border-radius:999px;background:var(--lime);color:#10130a;font-family:var(--mono);font-size:11px;font-weight:700;line-height:1}
  .btn{display:inline-flex;align-items:center;gap:8px;font-family:var(--body);font-weight:600;
    font-size:15px;padding:11px 18px;border-radius:10px;cursor:pointer;border:1px solid transparent;transition:.22s;white-space:nowrap}
  .btn-primary{background:var(--lime);color:#10130a;box-shadow:0 0 0 0 rgba(196,240,66,.5)}
  .btn-primary:hover{box-shadow:0 6px 30px rgba(196,240,66,.32);transform:translateY(-1px)}
  .btn-ghost{border-color:var(--line);color:var(--ink);background:rgba(255,255,255,.02)}
  .btn-ghost:hover{border-color:var(--lime);background:rgba(196,240,66,.06)}
  .nav-links .nav-cta{display:none}
  @media(max-width:860px){.nav-links{display:none}.nav-links.nav-cta-only{display:flex}}

  /* ---------- hero ---------- */
  header{padding:78px 0 64px;position:relative}
  .hero{display:grid;grid-template-columns:1.05fr .95fr;gap:54px;align-items:center}
  @media(max-width:940px){.hero{grid-template-columns:1fr;gap:40px}}
  h1{font-family:var(--disp);font-weight:800;font-size:clamp(38px,5.4vw,68px);line-height:.99;letter-spacing:-.025em;margin:18px 0 0}
  h1 .em{color:var(--lime);position:relative;white-space:nowrap}
  .hero p.sub{font-size:19px;color:var(--muted);max-width:33ch;margin:24px 0 30px}
  .hero p.sub b{color:var(--ink);font-weight:600}
  .cta-row{display:flex;gap:14px;flex-wrap:wrap;align-items:center}
  .trust{margin-top:22px;font-size:13.5px;color:var(--muted-2);display:flex;align-items:center;gap:9px}
  .trust .lk{width:7px;height:7px;border-radius:50%;background:var(--lime);box-shadow:0 0 10px var(--lime)}

  /* terminal panel */
  .panel{background:linear-gradient(180deg,var(--panel),#0c0f0b);border:1px solid var(--line);
    border-radius:var(--radius);position:relative;box-shadow:0 30px 80px -30px rgba(0,0,0,.8),inset 0 1px 0 rgba(255,255,255,.04)}
  .panel::before,.panel::after{content:"";position:absolute;width:11px;height:11px;border:1.5px solid var(--lime);opacity:.5}
  .panel::before{top:-1px;left:-1px;border-right:0;border-bottom:0}
  .panel::after{bottom:-1px;right:-1px;border-left:0;border-top:0}
  .example-badge{margin-left:auto;font-family:var(--mono);font-size:10.5px;
    letter-spacing:.1em;text-transform:uppercase;color:var(--lime);background:rgba(196,240,66,.1);
    border:1px solid var(--line);border-radius:6px;padding:3px 9px}
  /* the score panel has no terminal bar to sit in, so the badge is pinned to
     its top-right corner instead */
  .panel-example{position:relative}
  .example-badge-float{position:absolute;top:14px;right:14px;margin-left:0;z-index:1}
  /* mirrors the unsupported-plugin list of the real project sheet */
  .home-plugin-detail{margin-top:18px;padding-top:16px;border-top:1px dashed var(--line)}
  .home-plugin-detail-title{font-family:var(--mono);font-size:12.5px;color:var(--muted)}
  .home-plugin-detail .plugin-detail-list{list-style:none;margin:6px 0 0;padding:0}
  .home-plugin-detail .plugin-detail-list li{padding:10px 0;border-top:1px dashed var(--line)}
  .home-plugin-detail .plugin-detail-list li:first-child{border-top:0}
  .home-plugin-detail .plugin-detail-head{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
  .home-plugin-detail .plugin-detail-name{font-family:var(--mono);font-size:13px;word-break:break-all}
  .home-plugin-detail .plugin-detail-count{font-size:12px}
  .home-plugin-detail .plugin-detail-why{margin:5px 0 0;font-size:12.5px;line-height:1.5}
  .home-plugin-detail .badge-plugin{display:inline-block;font-family:var(--mono);font-size:10px;
    text-transform:uppercase;letter-spacing:.05em;border-radius:5px;padding:1px 6px;border:1px solid currentColor}
  .home-plugin-detail .badge-plugin-unconverted{color:#d98f6e}
  .home-plugin-detail .badge-plugin-partial{color:#e8c07a}
  .term-bar{display:flex;align-items:center;gap:8px;padding:13px 16px;border-bottom:1px solid var(--line-soft)}
  .term-bar i{width:11px;height:11px;border-radius:50%;display:inline-block;background:#2a2f28}
  .term-bar i:nth-child(1){background:#3a4035}
  .term-bar .tt{margin-left:8px;font-family:var(--mono);font-size:12px;color:var(--muted-2)}
  .term-body{padding:20px 20px 22px;font-family:var(--mono);font-size:13.5px;line-height:1.9}
  .term-body .cmd{color:var(--ink)}
  .term-body .cmd .p{color:var(--lime)}
  .term-body .ok{color:var(--muted)}
  .term-body .ok b{color:var(--ink);font-weight:500}
  .scoreline{display:flex;align-items:baseline;justify-content:space-between;margin:14px 0 4px}
  .scoreline .lbl{color:var(--muted)}
  .scoreline .big{font-family:var(--disp);font-weight:800;font-size:34px;color:var(--lime);letter-spacing:-.02em}
  .bars{margin-top:6px}
  .bar{display:grid;grid-template-columns:88px 1fr 42px;align-items:center;gap:12px;margin:9px 0;font-size:12.5px;color:var(--muted)}
  .track{height:8px;border-radius:6px;background:rgba(255,255,255,.05);overflow:hidden;position:relative}
  .fill{height:100%;width:0;border-radius:6px;background:linear-gradient(90deg,var(--lime-deep),var(--lime));transition:width 1.2s cubic-bezier(.2,.8,.2,1)}
  .fill.b{background:linear-gradient(90deg,#2f5cd0,var(--blue))}
  .bar .pct{text-align:right;color:var(--ink);font-weight:500}
  .term-foot{margin-top:16px;padding-top:14px;border-top:1px dashed var(--line);color:var(--muted);font-size:13px}
  .term-foot b{color:var(--lime)}

  /* ---------- strip ---------- */
  .strip{border-top:1px solid var(--line-soft);border-bottom:1px solid var(--line-soft);background:rgba(255,255,255,.012)}
  .strip-in{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--line-soft)}
  .strip-in>div{background:var(--bg);padding:26px 22px}
  .strip-in .n{font-family:var(--disp);font-weight:800;font-size:26px;letter-spacing:-.02em}
  .strip-in .n .u{color:var(--lime)}
  .strip-in .c{color:var(--muted);font-size:13.5px;margin-top:4px}
  @media(max-width:760px){.strip-in{grid-template-columns:repeat(2,1fr)}}

  /* ---------- sections ---------- */
  section{padding:96px 0}
  .sec-head{max-width:640px;margin-bottom:48px}
  .sec-head h2{font-family:var(--disp);font-weight:800;font-size:clamp(28px,3.6vw,44px);line-height:1.05;letter-spacing:-.022em;margin:14px 0 14px}
  .sec-head p{color:var(--muted);font-size:18px;margin:0}

  /* steps */
  /* --- Liste des étapes --- */
  .steps {
      max-width: 680px;
      margin: 0 auto;
      display: flex;
      flex-direction: column;
      gap: 44px;
  }

  .step {
      position: relative;
      display: grid;
      grid-template-columns: 48px 1fr;
      column-gap: 24px;
      align-items: start;
  }

  /* ligne de liaison verticale entre les pastilles */
  .step::before {
      content: "";
      position: absolute;
      left: 23px;          /* (48px - 2px) / 2 */
      top: 48px;
      bottom: -44px;       /* = gap de .steps, pour rejoindre la pastille suivante */
      width: 2px;
      background: var(--how-spine);
  }
  .step:last-child::before { display: none; }

  /* pastille numérotée */
  .num {
      width: 48px;
      height: 48px;
      border-radius: 50%;
      background: var(--how-surface);
      border: 1px solid var(--how-border);
      display: flex;
      align-items: center;
      justify-content: center;
      font-family: "JetBrains Mono", ui-monospace, monospace;
      font-size: 15px;
      color: var(--how-accent);
      position: relative;   /* passe au-dessus de la ligne */
      z-index: 1;
  }

  .step-body { padding-top: 4px; }

  .step h3 {
      font-family: "Source Serif 4", Georgia, serif;
      font-weight: 600;
      font-size: 22px;
      line-height: 1.3;
      color: var(--how-heading);
      margin: 0 0 10px;
  }
  .step p {
      font-size: 16px;
      line-height: 1.6;
      color: var(--how-body);
      margin: 0;
  }

  /* style du <code>.bubble</code> injecté par s1_d|raw */
  .step p code {
      font-family: "JetBrains Mono", ui-monospace, monospace;
      font-size: 14px;
      color: #d6e8a3;
      background: #1b2012;
      padding: 2px 6px;
      border-radius: 5px;
  }

  /* --- Animation .reveal (optionnelle) --- */
  .reveal {
      opacity: 0;
      transform: translateY(12px);
      transition: opacity .5s ease, transform .5s ease;
  }
  .reveal.is-visible { opacity: 1; transform: none; }

  @media (prefers-reduced-motion: reduce) {
      .reveal { opacity: 1; transform: none; transition: none; }
  }

  /* texte mono inline injecté via s1_d|raw, ex: <span class="mono">.bubble</span> */
  .mono {
      font-family: "JetBrains Mono", ui-monospace, monospace;
      font-size: 0.875em;       /* ~14px dans un p à 16px */
      color: #d6e8a3;
      background: #1b2012;
      padding: 2px 6px;
      border-radius: 5px;
      white-space: nowrap;
  }

  /* score feature */
  .feat{display:grid;grid-template-columns:1fr 1fr;gap:54px;align-items:center}
  @media(max-width:900px){.feat{grid-template-columns:1fr;gap:38px}}
  .gauge-wrap{display:flex;gap:28px;align-items:center;flex-wrap:wrap}

  /* the analysis panel's two measures, shared by the home page mock-up and the
     real project sheet so the promise and the delivered screen match */
  .measure-card{margin-top:22px;padding:16px 18px;border:1px solid var(--line);border-radius:10px}
  .measure-title{font-family:var(--mono);color:var(--lime);font-size:12px;text-transform:uppercase;letter-spacing:.08em;margin-bottom:12px}
  .score-cols{display:flex;gap:26px;flex-wrap:wrap}
  /* the two scores sit side by side wherever there is room. In a narrow column
     (the home page's two-column score section) they stack instead of forcing a
     width the container cannot give — each score keeps its ring and its wording
     either way, so the two layouts say the same thing. */
  .score-col{flex:1 1 240px;min-width:0}
  .score-cols .gauge-wrap{gap:20px}
  .fnl-explain{flex:1;min-width:150px;margin:0;font-size:13px;line-height:1.6}
  /* Whether the wording fits beside its ring depends on the CARD's width, not
     the window's: the same markup sits in a full-width project sheet and in the
     home page's narrow two-column panel. A container query asks the real
     question — when the card is tight, the wording goes under its ring so the
     two scores still read side by side instead of stacking. */
  .score-cols{container-type:inline-size}
  @container (max-width:620px){
    /* the wording drops under its ring and the ring shrinks, so the two scores
       still stand side by side: stacking them would read as one score followed
       by another rather than as one pair of measures */
    .score-cols .gauge-wrap{flex-direction:column;align-items:flex-start;gap:14px}
    .score-cols .fnl-explain{min-width:0}
    .score-cols .score-col{flex:1 1 0;min-width:0}
    .score-cols .ring{width:128px;height:128px}
    .score-cols .ring svg{width:128px;height:128px}
    .score-cols .ring .num{font-size:34px}
  }
  .ring{position:relative;width:168px;height:168px;flex:none}
  .ring svg{transform:rotate(-90deg)}
  .ring .val{position:absolute;inset:0;display:flex;flex-direction:column;align-items:center;justify-content:center}
  .ring .val .num{font-family:var(--disp);font-weight:800;font-size:42px;color:var(--lime);letter-spacing:-.03em;line-height:1}
  .ring .val .lab{font-family:var(--mono);font-size:10.5px;color:var(--muted);text-transform:uppercase;letter-spacing:.1em;margin-top:5px}
  .layerlist{flex:1;min-width:220px}
  .layerlist .row{display:grid;grid-template-columns:1fr auto;gap:10px;padding:11px 0;border-bottom:1px solid var(--line-soft);font-size:14.5px}
  .layerlist .row span{color:var(--muted)}
  .layerlist .row b{font-family:var(--mono);font-weight:500}
  .tag-hi{color:var(--lime)}.tag-mid{color:#e8d35a}.tag-lo{color:#e89a5a}
  .regen{margin-top:22px;background:var(--blue-dim);border:1px solid rgba(91,140,255,.3);border-radius:12px;padding:16px 18px;font-size:14px;color:#cdd9ff}
  .regen b{color:#fff}
  ul.checks{list-style:none;padding:0;margin:22px 0 0}
  ul.checks li{padding:9px 0 9px 30px;position:relative;color:var(--muted)}
  ul.checks li b{color:var(--ink);font-weight:600}
  ul.checks li::before{content:"";position:absolute;left:0;top:14px;width:13px;height:13px;border-radius:4px;
    background:var(--lime);box-shadow:0 0 12px rgba(196,240,66,.5)}

  /* stacks */
  .stacks{display:flex;flex-wrap:wrap;gap:12px;margin-top:8px}
  .chip{font-family:var(--mono);font-size:14px;padding:11px 18px;border:1px solid var(--line);border-radius:999px;
    background:rgba(196,240,66,.04);color:var(--ink);transition:.2s}
  .chip:hover{background:rgba(196,240,66,.1);transform:translateY(-2px)}
  .chip.soon{border-style:dashed;color:var(--muted-2);background:transparent}
  .chip .b{color:var(--blue);margin-right:7px}

  /* compare — one client's story: three dead ends, then the Exode timeline */
  .case-intro{font-size:15px;color:var(--muted);margin-bottom:22px}
  /* Each card is a subgrid of the row, so title / steps / total line up across
     the three columns: the totals then share one top edge AND one bottom edge,
     whatever the number of steps above them. The routes exist to be compared —
     ragged totals make that comparison harder to read. */
  .case-cols{display:grid;grid-template-columns:repeat(3,1fr);gap:14px;margin-bottom:14px;
    grid-template-rows:auto 1fr auto}
  .case-card{grid-row:span 3;display:grid;grid-template-rows:subgrid;
    border:1px solid var(--line);border-radius:var(--radius);background:var(--panel);padding:24px 22px}
  @media(max-width:820px){
    .case-cols{grid-template-columns:1fr;grid-template-rows:none}
    .case-card{grid-row:auto;display:flex;flex-direction:column}
  }
  .case-card-title{font-family:var(--mono);color:var(--lime);font-size:12px;text-transform:uppercase;
    letter-spacing:.08em;margin-bottom:14px}
  .case-steps{font-size:14.5px;line-height:1.7;color:var(--muted);margin-bottom:14px}
  .case-steps>div{margin-bottom:4px}
  .case-x{color:#d98f6e;margin-right:4px}
  .case-total{border-top:1px dashed var(--line);padding-top:12px;font-size:14.5px;color:var(--muted)}
  .case-total b{color:var(--ink);font-weight:600}
  /* the winning route: same panel as the others, set apart by a lime tint
     rather than by a different shape */
  .case-exode{background:linear-gradient(180deg,rgba(196,240,66,.06),var(--panel));
    border:1px solid rgba(196,240,66,.35);border-radius:var(--radius);padding:24px 22px}
  .case-exode .case-total{margin-top:16px}
  .case-exode-title{font-family:var(--mono);color:var(--lime);font-size:12px;text-transform:uppercase;
    letter-spacing:.08em;margin-bottom:14px}
  .case-timeline{display:grid;grid-template-columns:auto 1fr;gap:10px 16px;font-size:14.5px;line-height:1.6;color:var(--muted)}
  @media(max-width:620px){.case-timeline{grid-template-columns:1fr;gap:2px 0}
    .case-timeline .case-what{margin-bottom:12px}}
  .case-when{font-family:var(--mono);font-size:13px;font-weight:500;color:var(--lime);white-space:nowrap}
  .case-what{color:var(--ink);opacity:.86}
  .case-total-win{border-top-color:rgba(196,240,66,.22);color:var(--ink);opacity:.92}
  .case-disclaimer{font-family:var(--mono);font-size:11px;letter-spacing:.08em;color:var(--muted-2);margin:18px 0 0}

  /* pricing */
  .price{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;align-items:stretch}
  @media(max-width:900px){.price{grid-template-columns:repeat(2,1fr)}}
  @media(max-width:520px){.price{grid-template-columns:1fr}}
  .pcard{border:1px solid var(--line-soft);border-radius:var(--radius);padding:26px 22px;background:var(--panel);display:flex;flex-direction:column;position:relative;transition:.25s}
  .pcard:hover{transform:translateY(-3px);border-color:var(--line)}
  .pcard.feat-card{border-color:var(--lime);background:linear-gradient(180deg,rgba(196,240,66,.07),var(--panel))}
  .pcard .ribbon{position:absolute;top:-11px;right:18px;background:var(--lime);color:#10130a;font-family:var(--mono);
    font-size:10.5px;font-weight:700;letter-spacing:.06em;padding:4px 10px;border-radius:6px;text-transform:uppercase}
  .pcard .name{font-family:var(--disp);font-weight:700;font-size:18px}
  .pcard .amt{font-family:var(--disp);font-weight:800;font-size:30px;margin:12px 0 2px;letter-spacing:-.02em}
  .pcard .amt small{font-size:14px;color:var(--muted);font-weight:500;font-family:var(--body)}
  .pcard .meta{color:var(--muted);font-size:13.5px;min-height:38px}
  .pcard ul{list-style:none;padding:0;margin:18px 0 22px;flex:1}
  .pcard ul li{font-size:14px;color:var(--muted);padding:6px 0 6px 22px;position:relative}
  .pcard ul li::before{content:"›";position:absolute;left:0;color:var(--lime-deep);font-family:var(--mono)}
  .pcard .btn{justify-content:center;width:100%}
  /* ---------- anonymous feedback poll ---------- */
  .feedback{padding:56px 0 72px}
  .feedback-card{max-width:760px;margin:0 auto;padding:30px 32px;
    border:1px solid var(--line);border-radius:var(--radius);background:var(--panel)}
  .feedback-title{font-family:var(--disp);font-weight:800;font-size:clamp(22px,2.6vw,30px);
    letter-spacing:-.02em;line-height:1.1;margin:12px 0 8px}
  .feedback-sub{color:var(--muted);font-size:15px;margin:0 0 22px}
  .feedback-block{margin-bottom:20px}
  .feedback-q{font-family:var(--mono);font-size:12px;text-transform:uppercase;letter-spacing:.08em;
    color:var(--lime);margin-bottom:10px}
  .feedback-ratings,.feedback-interests{display:flex;flex-wrap:wrap;gap:10px}
  /* the whole pill is the target: a 13px radio is a poor thing to aim at */
  .feedback-pill{display:inline-flex;align-items:center;gap:8px;cursor:pointer;
    padding:9px 15px;border:1px solid var(--line);border-radius:999px;
    font-size:14.5px;color:var(--ink);background:rgba(255,255,255,.02);transition:.18s}
  .feedback-pill:hover{border-color:var(--lime);background:rgba(196,240,66,.06)}
  .feedback-pill input{accent-color:var(--lime);margin:0;cursor:pointer}
  .feedback-pill:has(input:checked){border-color:var(--lime);background:rgba(196,240,66,.12)}
  /* keyboard users must see the focused pill, not just a ring on a hidden dot */
  .feedback-pill:focus-within{outline:2px solid var(--lime);outline-offset:2px}
  /* optional, and placed after the answers so it never reads as a gate */
  .feedback-email input{width:100%;max-width:340px;padding:10px 13px;border-radius:10px;
    border:1px solid var(--line);background:rgba(255,255,255,.02);color:var(--ink);
    font-family:var(--body);font-size:14.5px}
  .feedback-email input:focus{outline:none;border-color:var(--lime)}
  .feedback-email input::placeholder{color:var(--muted-2)}
  .feedback-hint{margin:7px 0 0;color:var(--muted-2);font-size:12.5px;line-height:1.5}
  .feedback-foot{display:flex;align-items:center;gap:16px;flex-wrap:wrap;
    margin-top:24px;padding-top:20px;border-top:1px dashed var(--line)}
  /* the note reads first, the submit button sits at the far right. Only the
     visual order is swapped: the button stays first in the DOM, so it keeps
     its natural place in the tab order. */
  .feedback-foot .btn{order:2;margin-left:auto}
  .feedback-note{order:1;margin:0;color:var(--muted-2);font-size:13px;line-height:1.5}
  .feedback-note .hl{color:var(--lime);text-decoration:underline;text-underline-offset:3px}
  @media(max-width:620px){
    .feedback-card{padding:24px 20px}
    .feedback-foot .btn{width:100%;justify-content:center}
  }

  /* Each pricing card carries its own caveat, dashed off from the features
     above it. It used to sit outside the card, centred, where it read as a
     footnote to the whole section rather than to the offer it qualifies. */
  .card-note{margin-top:16px;padding-top:14px;border-top:1px dashed var(--line);
    font-family:var(--mono);font-size:12.5px;color:var(--muted-2);line-height:1.5}
  .backup-what{color:var(--muted);font-size:14.5px;line-height:1.65;margin:12px 0 0;max-width:80ch}
  /* backup tool: sold alone, not a conversion tier — full-width row under the grid */
  /* the price and its button sit at the top of the card, level with the
     offer's name, instead of floating at the vertical centre */
  .pcard-wide{margin-top:16px;flex-direction:row;align-items:flex-start;gap:32px}
  .pcard-wide .pcard-wide-main{flex:1;min-width:0}
  .pcard-wide .meta{min-height:0;margin-top:4px}
  .pcard-wide ul{margin:14px 0 0;display:flex;flex-wrap:wrap;gap:2px 26px}
  .pcard-wide ul li{padding-top:2px;padding-bottom:2px}
  .pcard-wide .pcard-wide-side{display:flex;flex-direction:column;align-items:stretch;gap:12px;flex:0 0 auto;text-align:center}
  .pcard-wide .amt{margin:0}
  @media(max-width:760px){
    .pcard-wide{flex-direction:column;align-items:stretch;gap:18px}
    .pcard-wide ul{display:block}
    .pcard-wide .pcard-wide-side{text-align:left}
  }

  /* claude band */
  /* same vertical lime wash as the other highlighted panels (.pcard.feat-card,
     .case-exode): the radial glow this used to carry was the only one on the
     page and read as a blurred blob */
  .band{border:1px solid var(--line);border-radius:var(--radius);padding:46px 40px;
    background:linear-gradient(180deg,rgba(196,240,66,.07),var(--panel));position:relative;overflow:hidden}
  .band h2{font-family:var(--disp);font-weight:800;font-size:clamp(26px,3.4vw,40px);letter-spacing:-.02em;
    line-height:1.1;margin:8px 0 14px;max-width:22ch}
  .band p{color:var(--muted);font-size:18px;max-width:52ch;margin:0}
  .band .cta-row{margin-top:26px}
  .band .trust{margin-top:18px}

  /* faq */
  .faq{max-width:820px}
  details{border-bottom:1px solid var(--line-soft);padding:6px 0}
  summary{list-style:none;cursor:pointer;padding:18px 4px;font-family:var(--disp);font-weight:600;font-size:18px;
    display:flex;justify-content:space-between;align-items:center;gap:18px;transition:color .2s}
  summary::-webkit-details-marker{display:none}
  summary:hover{color:var(--lime)}
  summary .mk{font-family:var(--mono);color:var(--lime);transition:transform .25s;flex:none}
  details[open] summary .mk{transform:rotate(45deg)}
  /* FAQ answers come from the database, written in an editor that wraps them
     in its own <div>: the browser then closes the <p> before it, so a
     "details p" selector misses the text entirely. Target the <details>. */
  details p,details .faq-answer,details div{margin:0 4px 20px;color:var(--muted);font-size:15.5px}
  details b,details strong{color:#fff;font-weight:700}

  /* final */

  /* footer */
  footer{border-top:1px solid var(--line-soft);padding:54px 0 40px;background:rgba(0,0,0,.25)}
  .foot-grid{display:grid;grid-template-columns:1.4fr 1fr 1fr 1fr;gap:30px}
  @media(max-width:760px){.foot-grid{grid-template-columns:1fr 1fr}}
  .foot-grid h4{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted-2);margin:0 0 16px}
  .foot-grid a{display:block;color:var(--muted);font-size:14.5px;padding:5px 0;transition:color .2s}
  .foot-grid a:hover{color:var(--lime)}
  .foot-grid p{color:var(--muted);font-size:14px;max-width:34ch}
  .disclaimer{margin-top:38px;padding-top:22px;border-top:1px solid var(--line-soft);color:var(--muted-2);font-size:12.5px;display:flex;justify-content:space-between;gap:20px;flex-wrap:wrap}

  /* reveal */
  .reveal{opacity:0;transform:translateY(22px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.8,.2,1)}
  .reveal.in{opacity:1;transform:none}
  .load{opacity:0;transform:translateY(16px);animation:rise .8s forwards}
  @keyframes rise{to{opacity:1;transform:none}}

  /* ---------- language switcher ---------- */
  .lang{display:flex;gap:1px;font-family:var(--mono);font-size:12px;border:1px solid var(--line-soft);border-radius:8px;overflow:hidden;background:rgba(255,255,255,.02)}
  .lang a{padding:6px 10px;color:var(--muted);transition:.18s}
  .lang a.active{background:var(--lime);color:#10130a}
  .lang a:hover:not(.active){color:var(--ink)}
  .nav-right{display:flex;align-items:center;gap:18px}
  /* signed-in dropdown: one entry in the bar, the links in a floating panel */
  /* (the generic details/summary rules below are for the FAQ accordions: undone here) */
  .nav-menu{position:relative;border:0;padding:0;margin:0}
  .nav-menu summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:7px;padding:0;color:var(--muted);
    font-family:var(--body);font-weight:400;font-size:14.5px;transition:color .2s;user-select:none}
  .nav-menu summary::-webkit-details-marker{display:none}
  .nav-menu summary:hover,.nav-menu[open] summary{color:var(--ink)}
  .nav-menu summary.active{color:var(--lime)}
  .nav-menu-caret{width:6px;height:6px;border-right:1.5px solid currentColor;border-bottom:1.5px solid currentColor;transform:translateY(-2px) rotate(45deg);transition:transform .2s}
  .nav-menu[open] .nav-menu-caret{transform:translateY(1px) rotate(225deg)}
  .nav-menu-list{position:absolute;right:0;top:calc(100% + 14px);min-width:190px;display:flex;flex-direction:column;margin:0;padding:8px;font-size:14.5px;
    background:var(--panel);border:1px solid var(--line-soft);border-radius:12px;box-shadow:0 18px 40px rgba(0,0,0,.45);z-index:60}
  .nav-menu-list a{display:block;padding:9px 12px;border-radius:8px;white-space:nowrap}
  .nav-menu-list a:hover{background:rgba(255,255,255,.04)}
  .nav-menu-list a.active{color:var(--lime)}

  /* ---------- auth (login / register) ---------- */
  .auth{min-height:calc(100vh - 66px);display:flex;align-items:flex-start;justify-content:center;padding:90px 26px 70px;
    background:rgba(4,6,4,.55);cursor:pointer}
  .auth-card{cursor:auto}
  .auth-card{width:100%;max-width:430px;border:1px solid var(--line-soft);border-radius:var(--radius);background:var(--panel);padding:38px 34px}
  .auth-card h1{font-family:var(--disp);font-weight:800;font-size:30px;letter-spacing:-.02em;margin:12px 0 6px}
  .auth-sub{color:var(--muted);font-size:15px;margin:0 0 28px}
  /* second heading inside an auth card: separates two forms on one page */
  .account-section{font-family:var(--disp);font-weight:800;font-size:19px;letter-spacing:-.01em;
    margin:38px 0 6px;padding-top:26px;border-top:1px solid var(--line-soft)}
  .account-section:first-of-type{margin-top:6px;padding-top:0;border-top:0}
  .auth-field{margin-bottom:18px}
  .auth-field label{display:block;font-size:13.5px;color:var(--muted);margin-bottom:7px}
  .auth-field input{width:100%;padding:12px 14px;border-radius:10px;border:1px solid var(--line-soft);
    background:rgba(255,255,255,.03);color:var(--ink);font-family:var(--body);font-size:15px;transition:border-color .2s}
  .auth-field input:focus{outline:none;border-color:var(--lime)}
  .auth-help{display:block;margin-top:6px;font-family:var(--mono);font-size:12px;color:var(--muted-2)}
  /* Show/hide toggle, wrapped around password inputs by JS. The button sits
     inside the field, so it must beat the browser's default button styling
     (grey buttonface background) and stay out of the normal flow — otherwise
     it drops below the input. */
  .auth-field .password-field,
  .password-field{position:relative;display:block}
  .auth-field .password-field input,
  .password-field input{padding-right:46px}
  .auth-field .password-reveal,
  .password-reveal{position:absolute;top:0;right:0;height:100%;width:44px;display:flex;align-items:center;
    justify-content:center;background:transparent;background-image:none;border:0;box-shadow:none;padding:0;
    margin:0;cursor:pointer;font-size:15px;line-height:1;color:var(--muted);opacity:.6;
    transition:opacity .2s;-webkit-appearance:none;appearance:none}
  .auth-field .password-reveal:hover,
  .password-reveal:hover{opacity:1;background:transparent}
  .auth-field .password-reveal:focus-visible,
  .password-reveal:focus-visible{outline:2px solid var(--lime);outline-offset:-3px;border-radius:10px;opacity:1}
  .auth-field .password-reveal[aria-pressed="true"],
  .password-reveal[aria-pressed="true"]{opacity:1;color:var(--lime)}
  /* textarea and radio groups: same treatment as the text inputs above */
  .auth-field textarea{width:100%;padding:12px 14px;border-radius:10px;border:1px solid var(--line-soft);
    background:rgba(255,255,255,.03);color:var(--ink);font:inherit;resize:vertical;min-height:120px}
  .auth-field textarea:focus{outline:none;border-color:var(--lime)}
  .auth-field select{width:100%;padding:12px 14px;border-radius:10px;border:1px solid var(--line-soft);
    background:#0d100c;color:var(--ink);font:inherit}
  /* every other select on the site: left to the browser they render white on a
     dark page. Scoped away from .form-select, which is the back office's own
     Bootstrap styling and must keep it. */
  select:not(.form-select){padding:9px 12px;border-radius:8px;border:1px solid var(--line-soft);
    background:#0d100c;color:var(--ink);font:inherit;font-size:14px}
  select:not(.form-select):focus{outline:none;border-color:var(--lime)}
  select:not(.form-select) option{background:#0d100c;color:var(--ink)}
  /* Symfony wraps expanded choices in an inner div, so target descendants */
  .auth-choices,.auth-choices > div{display:flex;flex-wrap:wrap;gap:8px 22px;align-items:center}
  .auth-choices label{display:inline-flex;align-items:center;gap:7px;margin:0 0 0 6px;cursor:pointer;color:var(--ink);font-size:14px}
  .auth-choices input[type=radio],.auth-choices input[type=checkbox]{width:auto;margin:0;accent-color:var(--lime)}
  /* wider card for the multi-field demo request form */
  /* the decision screen carries plugin cards with usage lists: 620px squeezed
     them into unreadable columns */
  .auth-card-wide{max-width:860px}
  /* freeplay: payment is bypassed, so the mode must be unmistakable */
  .freeplay-badge{margin-left:12px;padding:3px 9px;border-radius:6px;font-size:11px;letter-spacing:.05em;
    text-transform:uppercase;background:rgba(217,143,110,.16);border:1px solid rgba(217,143,110,.45);color:#e0a98d}
  .auth-card form .btn{width:100%;justify-content:center;margin-top:6px}
  .auth-error,.auth-card ul{list-style:none;border:1px solid rgba(217,143,110,.4);background:rgba(217,143,110,.08);
    color:#d98f6e;font-size:14px;padding:11px 14px;border-radius:10px;margin:0 0 18px}
  /* bullet lists inside the legal pages. ".auth-card ul" is styled as an error
     block, so these need their own rule rather than inheriting it. */
  .auth-card ul.legal-list{list-style:disc;margin:8px 0 0;padding-left:20px;border:0;background:none;
    font-family:var(--mono);font-size:12px;color:var(--muted-2);line-height:1.6}
  .auth-card ul.legal-list li{margin-bottom:6px}
  .legal-notice-translation{border-left:2px solid var(--line);padding-left:12px;font-style:italic}
  /* Legal pages are read, not skimmed: their body text drops the 12px mono of
     .auth-help (a form-field hint style) for the reading font at a normal size,
     and uses --muted, which clears WCAG AA on the panel background. */
  .legal-page .auth-help,
  .legal-page .auth-card ul.legal-list{font-family:var(--body);font-size:15px;
    line-height:1.65;color:var(--muted);letter-spacing:0}
  .legal-page .auth-help b,.legal-page .auth-help strong,
  .legal-page .auth-card ul.legal-list b,.legal-page .auth-card ul.legal-list strong{color:var(--ink);font-weight:600}
  .legal-page .auth-help a{color:var(--lime);text-decoration:underline}
  .legal-page h2{color:var(--ink)}
  .legal-page .auth-help+.auth-help{margin-top:12px}
  .auth-field ul{margin-top:8px}
  .auth-field .auth-error{margin:8px 0 0;font-size:13px}
  .auth-alt{margin-top:24px;text-align:center;font-size:14px;color:var(--muted)}
  .auth-alt a{color:var(--lime)}
  .auth-alt a:hover{text-decoration:underline}

  /* dev-only one-click login button */
  .btn-dev{border:1px dashed var(--blue);color:var(--blue);background:var(--blue-dim);font-family:var(--mono);font-size:13px}
  .btn-dev:hover{background:rgba(91,140,255,.28)}
  .auth-card .btn-dev{width:100%;justify-content:center;margin-top:14px}

  /* ---------- client area (project list / detail) ---------- */
  .projects{padding:64px 0 80px;min-height:calc(100vh - 66px)}
  .proj-head{display:flex;align-items:flex-end;justify-content:space-between;gap:20px;flex-wrap:wrap;margin-bottom:34px}
  .proj-head h1{font-family:var(--disp);font-weight:800;font-size:clamp(30px,4vw,44px);letter-spacing:-.022em;margin:10px 0 0}
  .proj-back{display:inline-block;font-size:13px;color:var(--muted);margin-bottom:18px;transition:color .2s}
  .proj-back:hover{color:var(--lime)}
  .proj-empty{border:1px dashed var(--line);border-radius:var(--radius);padding:54px 30px;text-align:center;color:var(--muted)}
  .proj-empty p{margin:0 0 22px;max-width:46ch;margin-left:auto;margin-right:auto}
  .proj-list{display:flex;flex-direction:column;gap:14px}
  /* the actions column is fixed rather than "auto": sized by content, each row
     took the width of its own price, so buttons changed size from row to row */
  .proj-row{display:grid;grid-template-columns:1.4fr auto 1.6fr 216px;gap:18px 26px;align-items:center;
    border:1px solid var(--line-soft);border-radius:var(--radius);background:var(--panel);padding:20px 24px;transition:.25s}
  .proj-row:hover{border-color:var(--line)}
  @media(max-width:900px){.proj-row{grid-template-columns:1fr 1fr}}
  .proj-name{font-family:var(--disp);font-weight:700;font-size:18px;transition:color .2s}
  .proj-name:hover{color:var(--lime)}
  .proj-meta{font-size:12px;color:var(--muted-2);margin-top:4px;white-space:normal;line-height:1.5}
  .proj-score{font-size:22px;font-weight:700;color:var(--lime);text-align:center}
  .proj-dates{font-size:11.5px;color:var(--muted-2);margin-top:6px}
  .proj-dates .hl{color:var(--blue)}
  .proj-actions{display:flex;flex-direction:column;gap:8px;align-items:stretch}
  .proj-actions .btn{justify-content:center;font-size:13.5px;padding:9px 14px}
  /* the pay button sits in a form, which would otherwise not stretch like the
     buttons next to it: the two end up different widths */
  .proj-actions form{display:flex}
  .proj-actions form .btn{width:100%}
  /* reminder under the buttons: a link, not a third button competing with them.
     Its width is capped on the buttons' own, so a longer wording can never
     widen the column and resize them. */
  .proj-backup-hint{display:block;max-width:100%;margin-top:2px;text-align:center;font-size:12px;line-height:1.35;
    color:var(--muted-2);text-decoration:underline;text-underline-offset:3px;transition:color .2s}
  .proj-backup-hint:hover{color:var(--lime)}
  .badge{display:inline-block;font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;
    padding:4px 10px;border-radius:6px;border:1px solid var(--line-soft)}
  .badge-to_convert{color:#e8c07a;border-color:rgba(232,192,122,.35);background:rgba(232,192,122,.08)}
  .badge-converted{color:var(--lime);border-color:var(--line);background:rgba(196,240,66,.07)}
  .badge-update_available{color:var(--blue);border-color:rgba(91,140,255,.4);background:var(--blue-dim)}
  .proj-show{display:grid;grid-template-columns:1fr 1fr;gap:24px;align-items:start;margin-top:18px}
  @media(max-width:940px){.proj-show{grid-template-columns:1fr}}
  /* single-column layout: the panel now carries the two score cards, the
     estimate and the report, so it takes the width of the blocks above it
     instead of the 680px it was capped at when it held a few lines */
  .proj-show-single{grid-template-columns:1fr}
  .auth-field input[type=file]{padding:10px 12px;font-size:13.5px;color:var(--muted)}
  .auth-field input[type=file]::file-selector-button{font-family:var(--body);font-weight:600;font-size:13px;color:var(--ink);
    background:rgba(255,255,255,.05);border:1px solid var(--line-soft);border-radius:8px;padding:7px 12px;margin-right:12px;cursor:pointer}
  .badge-converting{color:var(--blue);border-color:rgba(91,140,255,.4);background:var(--blue-dim)}
  .badge-failed{color:#d98f6e;border-color:rgba(217,143,110,.4);background:rgba(217,143,110,.08)}
  .badge-blocked{color:#e8c07a;border-color:rgba(232,192,122,.35);background:rgba(232,192,122,.08)}
  .proj-wait{color:var(--blue);font-size:13px}

  /* stack radio group on conversion forms.
     markup: <label>Backend</label><div id=...><input radio><label for=...>...</div> */
  .stack-field > label{display:block;font-size:13.5px;color:var(--muted);margin-bottom:8px}
  .stack-field > div{display:flex;gap:10px;flex-wrap:wrap}
  /* hide the native radios WITHOUT taking them out of the flow: a position:absolute
     here would escape the card (no positioned ancestor) and overlap the back link,
     stealing its click. width/height:0 + appearance:none keeps them in place. */
  .stack-field > div input[type=radio]{appearance:none;-webkit-appearance:none;width:0;height:0;margin:0;opacity:0;pointer-events:none}
  .stack-field > div label{display:inline-flex;align-items:center;gap:7px;
    border:1px solid var(--line-soft);border-radius:10px;padding:9px 16px;font-size:14px;cursor:pointer;transition:.18s;margin:0}
  .stack-field > div label:hover{border-color:var(--lime)}
  /* checked pill: the input precedes its label in the DOM */
  .stack-field > div input[type=radio]:checked + label{
    border-color:var(--lime);background:rgba(196,240,66,.1);color:var(--ink)}
  .stack-field > div input[type=radio]:focus-visible + label{outline:2px solid var(--lime);outline-offset:2px}

  /* Plugin mode: two cards, one per choice. The whole card is the label, so
     the click target is the option itself rather than a line of text next to
     a control; the selected one holds the fields it needs, inside its own
     border, which is what tells the client they belong to that choice. */
  .plugin-mode-field{border:0;padding:0;margin:0 0 22px;min-width:0}
  .plugin-mode-field legend{padding:0;font-size:13.5px;color:var(--muted)}
  .plugin-mode-intro{margin:6px 0 12px;font-size:13px;line-height:1.5;color:var(--muted-2)}
  .plugin-mode-options{display:flex;flex-direction:column;gap:10px}
  .plugin-mode-option{border:1px solid var(--line-soft);border-radius:12px;padding:14px 16px;transition:.18s}
  .plugin-mode-option:hover{border-color:var(--line)}
  /* the radio is invisible but focusable: keyboard users still get a ring */
  .plugin-mode-option input[type=radio]{appearance:none;-webkit-appearance:none;width:0;height:0;margin:0;opacity:0;position:absolute;pointer-events:none}
  .plugin-mode-option > label{display:block;margin:0;font-size:15px;font-weight:600;color:var(--ink);cursor:pointer}
  /* a dot in front of the title, filled when the option is the selected one */
  .plugin-mode-option > label::before{content:"";display:inline-block;width:13px;height:13px;margin-right:9px;
    vertical-align:-1px;border:1.5px solid var(--muted);border-radius:50%;transition:.18s}
  .plugin-mode-option:has(input:checked){border-color:var(--lime);background:rgba(196,240,66,.06)}
  .plugin-mode-option:has(input:checked) > label::before{border-color:var(--lime);background:var(--lime);box-shadow:inset 0 0 0 3px var(--panel)}
  .plugin-mode-option:has(input:focus-visible){outline:2px solid var(--lime);outline-offset:2px}
  .plugin-mode-consequence{margin:7px 0 0 22px;font-size:13px;line-height:1.5;color:var(--muted)}
  /* the fields of the selected option, set apart from its description */
  .plugin-mode-url{margin:14px 0 0 22px;padding-top:14px;border-top:1px solid var(--line-soft)}
  .plugin-mode-url > label{display:block;font-size:13.5px;color:var(--muted);margin-bottom:6px}
  .plugin-mode-url input[type=url],.plugin-mode-url input[type=text]{width:100%}
  .plugin-url-fallback{border:0;padding:0;margin-top:12px}
  .plugin-url-fallback summary{font-size:13px;color:var(--muted);padding:0;font-family:var(--body);font-weight:400}
  .plugin-url-fallback summary:hover{color:var(--lime)}
  .plugin-url-fallback > label{display:block;margin:10px 0 6px;font-size:13.5px;color:var(--muted)}
  .report-plugin-mode{margin:0 0 14px;font-size:13px;color:var(--muted)}

  /* conversion-state strips on the project detail */
  .conv-state{margin:18px 0 0;padding:13px 16px;border-radius:10px;font-size:14px;border:1px solid var(--line-soft)}
  .conv-state-running{color:var(--blue);border-color:rgba(91,140,255,.4);background:var(--blue-dim)}
  .conv-state-review{color:#e8c07a;border-color:rgba(232,192,122,.35);background:rgba(232,192,122,.08)}
  .conv-state-failed{color:#d98f6e;border-color:rgba(217,143,110,.4);background:rgba(217,143,110,.08)}

  /* plugin decision screen: one plugin per page. The heading is the plugin the
     client must act on, so it leads; the consequences of skipping it are true
     but secondary, and sit at the bottom in small type. */
  .plugins-section{margin-top:26px}
  .plugins-title{font-size:1.05rem;margin:0 0 6px}
  .plugins-intro{margin:0 0 4px;font-size:13.5px;line-height:1.6}
  .plugin-card{margin-top:18px;padding:18px 20px;border:1px solid var(--line);border-radius:10px}
  .plugin-head{display:flex;align-items:baseline;gap:12px;flex-wrap:wrap;padding-bottom:12px;border-bottom:1px solid var(--line-soft)}
  /* the plugin name is the subject of the card: no .mono background pill, which
     would make a heading read as a form control */
  .plugin-name{margin:0;font-family:var(--disp);font-weight:700;font-size:19px;letter-spacing:-.01em;color:var(--lime);word-break:break-word}
  .plugin-count{margin-left:auto;font-family:var(--mono);font-size:11.5px;color:var(--muted)}
  /* where the plugin is called: the only handle a client has on an unnamed one */
  .plugin-usages{margin-top:14px}
  .plugin-usages-title{font-size:12px;color:var(--muted);margin-bottom:5px}
  .plugin-usage-list{margin:0;padding-left:18px;font-size:13px;line-height:1.7}
  .plugin-usage-list .mono{font-size:12.5px;background:none;padding:0;border-radius:0;color:var(--ink)}
  .plugin-usage-more{margin:4px 0 0;font-size:12px}
  .plugin-idhint{margin:10px 0 0;font-size:12.5px;line-height:1.6}
  /* one action = one field, clearly separated from the next */
  .plugin-action{margin-top:16px;padding-top:14px;border-top:1px solid var(--line)}
  .plugin-action-head{display:flex;gap:10px;align-items:center;flex-wrap:wrap;margin-bottom:8px}
  .plugin-action-head .mono{background:none;padding:0;border-radius:0;font-size:14px;color:var(--ink)}
  .plugin-action-io{margin:0 0 8px;font-family:var(--mono);font-size:12px}
  /* .mono sets white-space:nowrap, which in a textarea means the pasted code
     never wraps and scrolls sideways instead — unreadable for a function body */
  .plugin-code{display:block;width:100%;min-height:130px;background:none;padding:10px 12px;border-radius:8px;
    white-space:pre-wrap;overflow-wrap:break-word;resize:vertical;line-height:1.6}
  .plugin-keys{margin-top:12px}
  .plugin-keys-hint{margin:0 0 6px;font-size:12.5px;line-height:1.6}
  .plugin-key-row{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:6px}
  .plugin-key-row label{background:none;padding:0;border-radius:0;font-size:12.5px;color:var(--muted)}
  /* the input keeps a field's look; only the label sheds the .mono pill */
  .plugin-key-row input{flex:1;min-width:200px;padding:8px 10px;border-radius:8px;font-size:13px}
  .plugin-save{display:flex;gap:.6rem;flex-wrap:wrap;align-items:center;margin-top:10px}
  .plugin-save .muted{font-size:12px}
  /* the "what happens if you skip this" line: last, and quiet */
  .plugin-consequence{margin:14px 0 0;padding-top:12px;border-top:1px solid var(--line-soft);font-size:12.5px;line-height:1.6}
  /* pager */
  .plugin-nav{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-top:14px}
  .plugin-pos{font-family:var(--mono);font-size:12px;color:var(--muted)}
  /* a hidden card must take no room at all: [hidden] alone loses to the card's
     own display, leaving its margin behind as a gap above the visible one */
  .plugin-card[hidden]{display:none}
  .plugin-nav button[disabled]{opacity:.4;cursor:default}
  .plugin-keep{margin-top:18px}
  .plugin-keep label{display:flex;gap:.5rem;align-items:flex-start;font-size:13.5px}
  .plugin-keep .muted{font-size:12.5px}
  /* the plugins that ask nothing: folded away, grouped by what becomes of them */
  .plugin-settled{margin-top:20px}
  .plugin-settled summary{cursor:pointer;color:var(--muted);font-size:13.5px}
  .plugin-settled-group{margin-top:14px;padding-left:12px;border-left:2px solid var(--line)}
  .plugin-settled-head{color:var(--lime);font-size:11.5px;text-transform:uppercase;letter-spacing:.06em}
  .plugin-settled-what{margin:4px 0 0;font-size:12.5px;line-height:1.6}
  .plugin-settled-list{margin:6px 0 0;font-size:13px;color:var(--muted);word-break:break-word}

  /* a newer engine version waiting for this project: informative, never a
     warning — nothing is wrong, something got better */
  .engine-update{border-color:rgba(196,240,66,.35);background:rgba(196,240,66,.05)}
  .engine-update-head{display:flex;align-items:baseline;gap:10px;flex-wrap:wrap;color:var(--lime)}
  .engine-update-version{font-size:12px;color:var(--muted)}
  .engine-update-log{margin:8px 0 12px;font-size:13.5px;line-height:1.6;color:var(--muted)}

  /* the static.js field, kept as a fallback behind the app address: folded away
     so the client is not asked two questions for one answer */
  .plugin-url-fallback{margin-top:12px}
  /* the summary is the only thing that toggles the block: made to look like the
     link it behaves as, and kept narrow so a stray click nearby does not close
     a field the client is in the middle of filling */
  .plugin-url-fallback summary{display:inline-block;cursor:pointer;color:var(--muted);font-size:12.5px;
    text-decoration:underline;text-underline-offset:3px}
  .plugin-url-fallback summary:hover{color:var(--lime)}
  .plugin-url-fallback > label{display:block;margin-top:10px}

  /* shown inside a submit button while an upload is on its way: several
     megabytes plus the analysis take long enough that an unchanged page reads
     as a broken one */
  .btn-spinner{display:inline-block;width:14px;height:14px;margin-right:8px;vertical-align:-2px;
    border:2px solid currentColor;border-right-color:transparent;border-radius:50%;
    animation:btn-spin .7s linear infinite}
  @keyframes btn-spin{to{transform:rotate(360deg)}}
  .btn:disabled{opacity:.75;cursor:progress}
  @media(prefers-reduced-motion:reduce){.btn-spinner{animation-duration:2.4s}}

  /* full-screen curtain drawn over the page while a slow submit is on its way.
     A busy button alone is too discreet: the client keeps scrolling, clicking
     and wondering. Blocking the screen says plainly that the wait is expected. */
  .busy-veil{position:fixed;inset:0;z-index:200;display:flex;align-items:center;justify-content:center;
    padding:24px;background:rgba(8,10,8,.86);backdrop-filter:blur(6px);
    animation:busy-veil-in .18s ease-out both;cursor:progress}
  @keyframes busy-veil-in{from{opacity:0}to{opacity:1}}
  .busy-veil-card{max-width:420px;text-align:center;padding:34px 30px;
    border:1px solid var(--line);border-radius:var(--radius);background:var(--panel)}
  .busy-veil-ring{width:44px;height:44px;margin:0 auto 20px;
    border:3px solid rgba(196,240,66,.18);border-top-color:var(--lime);border-radius:50%;
    animation:btn-spin .8s linear infinite}
  .busy-veil-label{font-family:var(--disp);font-size:19px;line-height:1.35;color:var(--ink)}
  .busy-veil-hint{margin-top:10px;font-size:14px;line-height:1.5;color:var(--muted)}
  @media(prefers-reduced-motion:reduce){
    .busy-veil{animation:none}
    .busy-veil-ring{animation-duration:2.4s}
  }

  /* flash messages */
  .flash{margin:0 0 16px;padding:13px 16px;border-radius:10px;font-size:14px;border:1px solid var(--line-soft)}
  .flash-success{color:var(--lime);border-color:var(--line);background:rgba(196,240,66,.07)}
  .flash-warning{color:#e8c07a;border-color:rgba(232,192,122,.35);background:rgba(232,192,122,.08)}
  .flash-error{color:#d98f6e;border-color:rgba(217,143,110,.4);background:rgba(217,143,110,.08)}
