/**
 * Itqan+ — the Ausbildung dossier service.
 *
 * Built on the site's own tokens, not a second design system. Earlier passes
 * gave this page an ivory-and-gold identity of its own; it looked expensive
 * and it read as a different company, which is the opposite of what a
 * Moroccan student needs to feel before paying 299 درهم. So: the Itqan
 * palette, the Itqan radius, the Itqan header and footer, and one page short
 * enough to read standing up.
 *
 * The page has one job — say what the thing is, show the bridge, price it —
 * and one visual idea: Morocco on one side, Germany on the other, Itqan+ in
 * the middle. Everything here serves that or is not here.
 */

/* Baloo for headlines only. It is a rounded, warm Arabic face and it is the
   difference between "institution" and "somebody who will help you" — but a
   whole page set in it is exhausting, so body copy stays Cairo. */
.ipx {
  --happy: "Baloo Bhaijaan 2", var(--font-ar);

  /* A page in one accent is a calm page, and calm is not what this one is
     for. Three warm-to-cool accents, drawn from tokens the site already
     owns, cycled across the numbered and ticked things so the eye reads
     variety rather than a single institutional blue.

     --sun is the only new colour on the page, and it is a fill: text on it
     uses --sun-ink, which is the site's own --warn and passes on cream. */
  --sun:     #F0A93B;
  --sun-ink: var(--warn);
  --sun-bg:  var(--warn-bg);
  --joy:     var(--ok);
  --joy-bg:  var(--ok-bg);
  --sky:     var(--signal-deep);
  --sky-bg:  var(--signal-wash);
}
html[data-theme="dark"] .ipx { --sun-ink: #E8C98A; --sky: var(--signal); }

/* Every section headline gets a short coloured rule over it, three colours
   cycling down the page. Small and cheap, and it is most of what stops a long
   cream page reading as a document. */
/* 72px of padding above and below every section — 144px of nothing between
   them — is the site's rhythm for pages of text. This page is a sequence of
   objects that each make one point, and the gaps were reading as the page
   having ended. */
.ipx section.block { padding-block: clamp(30px, 5vw, 46px); }
.ipx .ipx-hero { padding-top: 18px; }
.ipx-h2 { position: relative; padding-top: 14px; }
.ipx-h2::before {
  content: ''; position: absolute; top: 0; inset-inline-start: 0;
  width: 42px; height: 4px; border-radius: 4px; background: var(--sky);
}
.block:nth-of-type(2n) .ipx-h2::before { background: var(--sun); }
.block:nth-of-type(3n) .ipx-h2::before { background: var(--joy); }

.ipx-h1, .ipx-h2, .ipx-price b, .ipx-card h3 { font-family: var(--happy); font-weight: 700; }

/* ── hero ──────────────────────────────────────────────────────────────── */

/* A warm wash behind the headline. It is the only decoration on the page
   that is purely mood, and it earns its place: the first impression should be
   "this is going to be fine", which an unrelieved cream field does not say. */
.ipx-hero { text-align: center; padding: 26px 0 8px; position: relative; }
.ipx-hero::before {
  /* inset-inline 0, not a negative bleed. -20% put 260px of glow outside the
     viewport on a 1280px screen and gave the whole page a horizontal
     scrollbar — a decoration that moves the page sideways is not a
     decoration. The radial falloff does the softening instead. */
  content: ''; position: absolute; inset: -40px 0 auto; height: 340px;
  z-index: -1; pointer-events: none;
  /* Two lights, not one: a warm one low on the right and a cool one high on
     the left. A single centred wash reads as a gradient; two read as morning. */
  background:
    radial-gradient(46% 62% at 78% 30%,
      color-mix(in srgb, var(--sun-bg) 92%, transparent) 0%, transparent 72%),
    radial-gradient(56% 70% at 32% 10%,
      color-mix(in srgb, var(--sky-bg) 88%, transparent) 0%, transparent 74%);
}
.ipx-badge {
  position: relative; overflow: hidden;
  display: inline-flex; align-items: center; gap: 8px;
  padding: 8px 18px; border-radius: 999px;
  background: var(--signal-wash); color: var(--accent-ink);
  font-weight: 700; font-size: .88rem;
  box-shadow: 0 1px 0 color-mix(in srgb, var(--signal) 30%, transparent) inset;
}
.ipx-badge::before {
  content: ''; width: 7px; height: 7px; border-radius: 50%;
  background: var(--signal-deep); flex: none;
}
/* A light crosses it, once every few seconds. The badge is the first thing on
   the page and it was completely still; a slow sweep catches the eye without
   asking to be read twice. ::after is the light, and it is inert to pointers
   so it can never sit between a finger and the badge. */
.ipx-badge::after {
  content: ''; position: absolute; inset: 0; pointer-events: none;
  background: linear-gradient(105deg, transparent 38%,
    color-mix(in srgb, #fff 62%, transparent) 50%, transparent 62%);
  transform: translateX(-130%);
}
@media (prefers-reduced-motion: no-preference) {
  .ipx-badge { animation: ipx-badge-in .5s var(--ease) both, ipx-badge-float 4.5s 1s ease-in-out infinite; }
  .ipx-badge::before { animation: ipx-badge-dot 2.4s ease-in-out infinite; }
  .ipx-badge::after { animation: ipx-badge-sheen 4.5s 1.6s var(--ease) infinite; }
}
@keyframes ipx-badge-in { from { opacity: 0; transform: translateY(-8px) scale(.94); } }
@keyframes ipx-badge-float { 0%, 100% { transform: none; } 50% { transform: translateY(-3px); } }
@keyframes ipx-badge-dot {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--signal-deep) 55%, transparent); }
  55% { box-shadow: 0 0 0 6px color-mix(in srgb, var(--signal-deep) 0%, transparent); }
}
@keyframes ipx-badge-sheen {
  0% { transform: translateX(-130%); } 26%, 100% { transform: translateX(130%); }
}
.ipx-h1 {
  margin: 16px 0 12px;
  font-size: clamp(1.8rem, 4.6vw, 2.9rem); line-height: 1.3;
  letter-spacing: -.01em;
}
/* The highlighter draws itself in, once, like somebody underlining the
   important bit for you. background-size, so it sweeps rather than fades. */
.ipx-h1 mark {
  background-image: linear-gradient(transparent 58%, var(--signal-wash) 58%);
  background-repeat: no-repeat; background-position: right center;
  background-size: 100% 100%;
  background-color: transparent; color: inherit; padding-inline: 2px;
}
@media (prefers-reduced-motion: no-preference) {
  .ipx-h1 mark { animation: ipx-mark .85s .35s var(--ease) both; }
}
@keyframes ipx-mark { from { background-size: 0 100%; } to { background-size: 100% 100%; } }
.ipx-lede {
  margin: 0 auto; max-width: 46ch;
  font-size: clamp(.94rem, 1.25vw, 1.02rem); line-height: 1.75; color: var(--ink-2);
  text-wrap: pretty;
}

/* ── the journey ───────────────────────────────────────────────────────── */

/* Three cells in a row was a diagram, and a diagram says "here are three
   things". The point of this object is that they are one trip — so there is a
   route, and something travels it. The plane is the only animation on the
   page that loops, because it is the only one making an argument. */
/* Bigger than it was. The plane is the page's one looping animation and the
   whole idea in one object, and at 880px wide with a 62px route it was a
   detail rather than a journey — the traveller crossed too little ground to
   be seen doing it. */
.ipx-journey {
  position: relative;
  margin: 34px auto 0; max-width: 1000px;
  padding: 44px 16px 34px;
  border: 1px solid var(--line); border-radius: var(--radius-lg);
  background:
    radial-gradient(120% 140% at 50% 0%, var(--signal-wash) 0%, transparent 62%),
    var(--surface);
  overflow: hidden;
}

/* the route */
.ipx-path { position: absolute; inset-inline: 15%; top: 82px; height: 2px; }
.ipx-dash {
  position: absolute; inset: 0;
  background-image: linear-gradient(90deg, var(--signal) 50%, transparent 50%);
  background-size: 12px 2px; background-repeat: repeat-x;
  opacity: .55;
}
/* Physical left/right and an animated `left`, not logical properties or a
   sign flipped through a variable. The route always runs from Morocco on the
   right to Germany on the left because the page is always RTL, so the
   geometry says right-to-left and means it — and a reader can tell from the
   keyframe alone which way the plane goes. */
.ipx-plane {
  position: absolute; top: 50%; left: 0;
  color: var(--signal-deep);
  transform: translate(-50%, -50%);
  filter: drop-shadow(0 2px 3px rgba(20, 38, 58, .18));
}
/* The size has to be here. PLANE_SVG carries a viewBox and no width/height so
   each of the three planes can be sized for its own context — and this was the
   one that had its dimensions inline before the glyph was shared, so it was
   left with none at all and rendered at the SVG default, far outside a 2px
   rail. The other two were already sized in CSS; now all three are. */
.ipx-plane svg { display: block; width: 30px; height: 30px; transform: rotate(-90deg); }
html[data-theme="dark"] .ipx-plane { color: var(--signal); }

/* the stops */
.ipx-stops {
  position: relative; list-style: none; margin: 0; padding: 0;
  display: grid; grid-template-columns: repeat(3, 1fr);
}
.ipx-stop {
  display: flex; flex-direction: column; align-items: center; gap: 7px;
  text-align: center; padding: 0 10px;
}
/* The label and its caption live in one wrapper so they stack as a unit.
   Without it they are two flex items, and the phone layout — which turns the
   stop into a row — laid the caption out beside the name instead of under
   it. */
.ipx-stop-t { display: block; }
.ipx-stop-t b { display: block; font-size: 1.06rem; }
.ipx-stop-t > span { display: block; font-size: .85rem; color: var(--ink-3);
  line-height: 1.5; margin-top: 2px; }

/* The two flags, drawn rather than typed. An emoji flag renders differently
   on every platform and is missing outright on some Androids — and this is
   the one image on the page that has to be unmistakable. */
.ipx-flag { width: 46px; height: 31px; border-radius: 5px; overflow: hidden;
  display: grid; box-shadow: 0 1px 2px rgba(20, 38, 58, .25); }
.ipx-flag-de { grid-template-rows: repeat(3, 1fr); }
.ipx-flag-de i { display: block; }
.ipx-flag-de i:nth-child(1) { background: #000; }
.ipx-flag-de i:nth-child(2) { background: #DD0000; }
.ipx-flag-de i:nth-child(3) { background: #FFCE00; }
/* The pentagram is drawn, not typed: a ★ character is a text node, and green
   on red is the flag's own 1.1:1 — authentic, and indistinguishable from
   unreadable copy to an auditor. A shape is what it always was. */
.ipx-flag-ma { background: #C1272D; place-items: center; }
.ipx-flag-ma::after {
  content: ''; width: 15px; height: 15px; background: #006233;
  clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%,
                     50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
}

/* A pin, not a card: the route passes through it, so it has to be a point. */
.ipx-pin {
  width: 74px; height: 74px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--surface); border: 2px solid var(--line);
  box-shadow: var(--shadow-sm);
  transition: transform .3s var(--ease), border-color .3s var(--ease),
              box-shadow .3s var(--ease);
}
.ipx-stop:hover .ipx-pin { transform: translateY(-4px) scale(1.05);
  border-color: var(--signal); box-shadow: var(--shadow); }

/* Germany is the end of the journey, so its pin carries a warm halo — the
   one place the cool palette gives way, because arriving is the warm part. */
.ipx-stop:last-child .ipx-pin {
  border-color: color-mix(in srgb, var(--sun) 55%, var(--line));
  box-shadow: 0 0 0 5px color-mix(in srgb, var(--sun) 16%, transparent),
              var(--shadow-sm);
}

.ipx-pin-core {
  background: var(--signal-deep); border-color: var(--signal-deep);
  position: relative;
}
html[data-theme="dark"] .ipx-pin-core { background: var(--signal); border-color: var(--signal); }
.ipx-pin-mark { color: #fff; font-family: var(--happy); font-weight: 800;
  font-size: 2.3rem; line-height: 1; margin-top: -2px; }
html[data-theme="dark"] .ipx-pin-mark { color: var(--signal-ink); }
/* One soft ring, expanding and fading. It marks the middle stop as the thing
   that is switched on without adding a second colour. */
.ipx-pin-core::after {
  content: ''; position: absolute; inset: -6px; border-radius: 50%;
  border: 2px solid var(--signal-deep); opacity: 0;
}
html[data-theme="dark"] .ipx-pin-core::after { border-color: var(--signal); }
.ipx-stop.is-core b { color: var(--accent-ink); }
html[data-theme="dark"] .ipx-stop.is-core b { color: var(--signal); }

@media (prefers-reduced-motion: no-preference) {
  .ipx-plane { animation: ipx-fly 8.5s var(--ease) infinite; }
  .ipx-pin-core::after { animation: ipx-ring 2.8s ease-out infinite; }
  .ipx-stop .ipx-pin { animation: ipx-bob 4.5s ease-in-out infinite; }
  .ipx-stop:nth-child(2) .ipx-pin { animation-delay: .5s; }
  .ipx-stop:nth-child(3) .ipx-pin { animation-delay: 1s; }
}

/* It takes off from you and lands on Germany, waits a beat, and goes again. */
@keyframes ipx-fly {
  0%        { left: 100%; opacity: 0; }
  10%       { opacity: 1; }
  80%       { opacity: 1; }
  90%, 100% { left: 0%; opacity: 0; }
}
@keyframes ipx-ring {
  0%   { transform: scale(.9); opacity: .7; }
  70%  { transform: scale(1.35); opacity: 0; }
  100% { transform: scale(1.35); opacity: 0; }
}
@keyframes ipx-bob {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -5px; }
}

/* ── the offer table ───────────────────────────────────────────────────── */

.ipx-card {
  max-width: 620px; margin: 34px auto 0;
  transition: transform .3s var(--ease), box-shadow .3s var(--ease);
  border: 2px solid var(--signal-deep); border-radius: var(--radius-lg);
  background: var(--surface); overflow: hidden;
  box-shadow: var(--shadow);
}
/* The offer, rebuilt to be decided on rather than read.
   The order a buyer needs is: what it is, what it costs, what that saves, and
   one button — so the ribbon dates the price, the number carries the weight,
   and the saving is stated in درهم rather than left as arithmetic. */
.ipx-off {
  display: inline-block; margin-bottom: 10px;
  padding: 5px 14px; border-radius: 999px;
  /* --surface as the ink, not white: --joy is dark green in light mode and
     light mint in dark, where a fixed white sat at 1.74:1. */
  background: var(--joy); color: var(--surface);
  font-size: .74rem; font-weight: 800; letter-spacing: .02em;
}
.ipx-card-top { padding: 24px 26px 22px; text-align: center;
  background: linear-gradient(160deg,
    var(--sky-bg) 0%, color-mix(in srgb, var(--sun-bg) 80%, var(--sky-bg)) 100%);
  border-bottom: 1px solid var(--line-soft); }
/* The head reads down one axis: what the offer is, what it is called, what it
   costs. The name was drifting left on wide cards because [lang="de"] sets
   text-align:start and an h3 is a block — centred explicitly now, so the three
   lines share a centre line instead of each finding their own. */
.ipx-card h3 { margin: 8px 0 2px; font-size: 1.55rem; text-align: center; }
.ipx-card-top p { margin: 0; color: var(--ink-2); font-size: .92rem; }

.ipx-price {
  position: relative; display: inline-flex; align-items: baseline;
  justify-content: center; gap: 10px; margin: 16px 0 6px; padding-inline: 8px;
}
.ipx-price b { font-size: 3.9rem; line-height: 1.04; color: var(--signal-deep);
  letter-spacing: -.02em; }
html[data-theme="dark"] .ipx-price b { color: var(--signal); }
.ipx-cur { font-size: 1.1rem; font-weight: 700; color: var(--ink-2); }
.ipx-price b, .ipx-cur { position: relative; z-index: 1; }

/* The highlight, as its own box.
   It was a gradient painted on the number's own background, cut at 62% of the
   line box — but the happy face has tall metrics and generous side bearings,
   so the cut landed below the digits entirely and the band ran well past them
   on one side. That is what made this corner look unfinished. An element sits
   where it is told, spans the whole price, and can be drawn in. */
.ipx-price-ink {
  position: absolute; inset-inline: 0; bottom: 7px; height: 13px; z-index: 0;
  border-radius: 999px;
  background: color-mix(in srgb, var(--sun) 52%, transparent);
  transform-origin: right center;
}

@media (prefers-reduced-motion: no-preference) {
  /* One line after another, in the order they are meant to be read, then the
     highlighter goes under the price. The ribbon keeps a slow beat afterwards
     because "limited" is a claim that should not look static. */
  .ipx-js .ipx-card.is-in .ipx-off {
    animation: ipx-off-in .45s .08s var(--ease) both,
               ipx-off-beat 3.2s 1.3s ease-in-out infinite;
  }
  .ipx-js .ipx-card.is-in .ipx-card-top h3 { animation: ipx-rise .5s .22s var(--ease) both; }
  .ipx-js .ipx-card.is-in .ipx-price b { animation: ipx-pop .55s .34s var(--ease) both; }
  .ipx-js .ipx-card.is-in .ipx-cur { animation: ipx-rise .45s .48s var(--ease) both; }
  .ipx-js .ipx-card.is-in .ipx-price-ink { animation: ipx-ink .5s .58s var(--ease) both; }
}
@keyframes ipx-pop { from { opacity: 0; transform: scale(.82); } }
@keyframes ipx-rise { from { opacity: 0; transform: translateY(9px); } }
@keyframes ipx-ink { from { transform: scaleX(0); } to { transform: scaleX(1); } }
@keyframes ipx-off-in { from { opacity: 0; transform: scale(.7) rotate(-8deg); } }
@keyframes ipx-off-beat { 0%, 100% { transform: none; } 50% { transform: scale(1.06); } }

/* Four groups that open, not eleven lines that don't.

   The flat list was accurate and unreadable — a reader's eye hit the third
   tick and left. Grouped, the whole offer is four rows and a count, and the
   detail is one tap away for the people who want it. Native <details>, so it
   opens with a keyboard and works with no JavaScript at all. */
.ipx-groups { padding: 6px 0; }
.ipx-g + .ipx-g { border-top: 1px solid var(--line-soft); }
.ipx-g summary {
  display: flex; align-items: center; gap: 13px; cursor: pointer;
  padding: 15px 26px; list-style: none;
  transition: background .18s var(--ease);
}
.ipx-g summary::-webkit-details-marker { display: none; }
.ipx-g summary:hover { background: var(--paper-2); }
/* Same set as the gains, same reason: four emoji from four different
   illustrators sat on one card. Ink as well as ground, per tile. */
.ipx-g-i { flex: none; width: 40px; height: 40px; border-radius: 13px;
  display: grid; place-items: center;
  background: var(--sky-bg); color: var(--sky); }
.ipx-g-i svg { width: 20px; height: 20px; display: block; }
.ipx-g:nth-child(2) .ipx-g-i { background: var(--joy-bg); color: var(--joy); }
.ipx-g:nth-child(3) .ipx-g-i { background: var(--sun-bg); color: var(--gold-ink, #8a5a06); }
html[data-theme="dark"] .ipx-g:nth-child(3) .ipx-g-i { color: var(--sun); }
.ipx-g:nth-child(4) .ipx-g-i { background: var(--signal-wash); color: var(--accent-ink); }
html[data-theme="dark"] .ipx-g:nth-child(4) .ipx-g-i { color: var(--signal); }
.ipx-g-t { flex: 1; min-width: 0; }
.ipx-g-t b { display: block; font-size: 1.02rem; line-height: 1.35; }
.ipx-g-t em { display: block; font-style: normal; font-family: var(--font-de);
  font-size: .76rem; letter-spacing: .04em; color: var(--ink-3); margin-top: 1px; }
/* The count is the answer to "how much is in this one", so it stops being a
   small grey pill and becomes the second-loudest thing in the row. It also
   says what it counts — a bare number beside a heading reads as a step
   index, which is the opposite of the intended meaning. Each group's count
   wears its own group's colour, so the badge and the icon opposite it are
   visibly the same row. */
.ipx-g-n { flex: none; display: grid; place-items: center;
  width: 38px; height: 38px; border-radius: 12px;
  background: var(--sky-bg); color: var(--accent-ink);
  font-family: var(--happy); font-weight: 800; font-size: 1.22rem; line-height: 1; }
html[data-theme="dark"] .ipx-g-n { color: var(--signal); }
.ipx-g:nth-child(2) .ipx-g-n { background: var(--joy-bg); color: var(--joy); }
.ipx-g:nth-child(3) .ipx-g-n { background: var(--sun-bg); color: var(--sun-ink); }
.ipx-g:nth-child(4) .ipx-g-n { background: var(--paper-2); color: var(--ink-2); }
/* A chevron drawn from two borders — no glyph a font might not carry. */
.ipx-g-c { flex: none; width: 9px; height: 9px; margin-inline-start: 2px;
  border-inline-end: 2px solid var(--ink-3); border-bottom: 2px solid var(--ink-3);
  transform: rotate(45deg) translate(-2px, -2px);
  transition: transform .25s var(--ease); }
.ipx-g[open] .ipx-g-c { transform: rotate(-135deg) translate(-3px, -3px); }


.ipx-g ul { list-style: none; margin: 0; padding: 0 26px 16px calc(26px + 53px); }
.ipx-g li { display: flex; gap: 10px; align-items: baseline; padding: 6px 0;
  font-size: .94rem; color: var(--ink-2); line-height: 1.55; }
.ipx-g li::before { content: '✓'; flex: none; color: var(--joy); font-size: .74rem;
  font-weight: 700; }
@media (prefers-reduced-motion: no-preference) {
  .ipx-g[open] ul { animation: ipx-open .32s var(--ease) both; }
}
@keyframes ipx-open { from { opacity: 0; transform: translateY(-6px); } }

.ipx-buy { display: flex; align-items: center; justify-content: center; gap: 10px;
  margin: 14px 26px 10px; padding-block: 15px; font-size: 1.12rem; font-weight: 800;
  box-shadow: 0 6px 18px color-mix(in srgb, var(--signal) 35%, transparent);
  transition: transform .2s var(--ease), box-shadow .2s var(--ease); }
.ipx-buy::after { content: '←'; transition: transform .25s var(--ease); }
.ipx-card:hover { transform: translateY(-3px); box-shadow: var(--shadow-lift); }
.ipx-buy:hover { transform: scale(1.02); }
.ipx-buy:hover::after { transform: translateX(-5px); }
.ipx-note { text-align: center; margin: 14px auto 0; max-width: 46ch;
  font-size: .86rem; color: var(--ink-3); }

/* ── the switch: what you pay vs what you get back ─────────────────────── */

/* Two faces of the same 299 درهم. A price is a cost read one way and a
   purchase read the other, and letting somebody flip between the two is the
   honest way to make the second reading land — no claim is added, the same
   service is simply described from the far end. */
/* Hidden until the script is running. Without JavaScript both panels are
   simply listed one after the other, and a switch that cannot switch is worse
   than no switch — it is a control that ignores you. */
.ipx-switch { display: none; }
.ipx-js .ipx-switch { display: grid; }
.ipx-switch {
  position: relative; grid-template-columns: 1fr 1fr;
  margin: 18px 26px 4px; padding: 4px;
  background: var(--paper-2); border-radius: 999px;
}
.ipx-sw {
  position: relative; z-index: 1; appearance: none; border: 0; cursor: pointer;
  padding: 11px 8px; border-radius: 999px; background: transparent;
  font-family: var(--font-ar); font-weight: 700; font-size: .94rem;
  color: var(--ink-2); transition: color .25s var(--ease);
}
.ipx-sw[aria-selected="true"] { color: var(--accent-ink); }
html[data-theme="dark"] .ipx-sw[aria-selected="true"] { color: var(--signal-ink); }
/* One travelling pill instead of two background swaps — the movement is what
   tells you the two panels are the same thing seen differently. */
.ipx-sw-ink {
  position: absolute; z-index: 0; top: 4px; bottom: 4px;
  inset-inline-start: 4px; width: calc(50% - 4px);
  border-radius: 999px; background: var(--surface);
  box-shadow: var(--shadow-sm);
  transition: transform .32s var(--ease);
}
html[data-theme="dark"] .ipx-sw-ink { background: var(--signal); }
.ipx-switch[data-on="1"] .ipx-sw-ink { transform: translateX(calc(-100% + 0px)); }
.ipx-js .ipx-pane[hidden] { display: none; }

.ipx-gain { list-style: none; margin: 0; padding: 6px 0; }
.ipx-gain li { display: flex; gap: 14px; align-items: flex-start;
  padding: 14px 26px; }
.ipx-gain li + li { border-top: 1px solid var(--line-soft); }
/* Each tile carries its own ink as well as its own ground, so the icon is a
   deliberate colour rather than whatever the emoji font shipped. */
.ipx-gain-i { flex: none; width: 42px; height: 42px; border-radius: 13px;
  display: grid; place-items: center;
  background: var(--sky-bg); color: var(--sky); }
.ipx-gain-i svg { width: 21px; height: 21px; display: block; }
.ipx-gain li:nth-child(2) .ipx-gain-i { background: var(--joy-bg); color: var(--joy); }
.ipx-gain li:nth-child(3) .ipx-gain-i { background: var(--sun-bg); color: var(--gold-ink, #8a5a06); }
html[data-theme="dark"] .ipx-gain li:nth-child(3) .ipx-gain-i { color: var(--sun); }
.ipx-gain li:nth-child(4) .ipx-gain-i { background: var(--signal-wash); color: var(--accent-ink); }
html[data-theme="dark"] .ipx-gain li:nth-child(4) .ipx-gain-i { color: var(--signal); }

/* The four of them, arriving.
   The pane is toggled with [hidden], so display goes none → block and these
   animations restart every time the tab is opened: the rows come up in order,
   each tile settles, and the icon draws itself along its own stroke. The dash
   pattern only exists inside the motion query, so with reduced motion the
   icons are simply there, whole, from the first frame. */
@media (prefers-reduced-motion: no-preference) {
  .ipx-pane:not([hidden]) .ipx-gain li {
    animation: ipx-gain-row .5s var(--ease) both;
    animation-delay: calc(var(--i) * .09s);
  }
  .ipx-pane:not([hidden]) .ipx-gain-i {
    animation: ipx-gain-tile .55s var(--ease) both,
               ipx-gain-float 5.5s ease-in-out infinite;
    animation-delay: calc(var(--i) * .09s), calc(1.3s + var(--i) * .22s);
  }
  /* The dash lives only in the keyframes, never in the base style. Declared
     here, a stroke-dashoffset of 1 hides the icon until something animates it
     away — and anything that does not run the animation (a throttled tab, a
     print, an engine that skips it) would render four empty tiles. With the
     dash inside the keyframes the resting state is simply a drawn icon, and
     the animation is the enhancement it was meant to be. */
  .ipx-pane:not([hidden]) .ipx-gain-i svg * {
    animation: ipx-draw .8s var(--ease) both;
    animation-delay: calc(var(--i) * .09s + .16s);
  }
}
@keyframes ipx-gain-row { from { opacity: 0; transform: translateY(10px); } }
@keyframes ipx-gain-tile { from { opacity: 0; transform: scale(.7); } }
@keyframes ipx-draw {
  from { stroke-dasharray: 1; stroke-dashoffset: 1; }
  to   { stroke-dasharray: 1; stroke-dashoffset: 0; }
}
@keyframes ipx-gain-float {
  0%, 100% { transform: translateY(0); }
  50% { transform: translateY(-3px); }
}
.ipx-gain b { display: block; font-size: 1rem; }
/* Scoped to the description, not to every span in the list.
   As `.ipx-gain span` this rule (0-1-1) outranked `.ipx-gain-i` (0-1-0) — and
   the icon tile is a span. It was being forced to display:block, which killed
   the grid centring and left every icon sitting in the top half of its tile,
   and it overrode the first tile's ink to --ink-2 while the other three kept
   their own colour through a heavier nth-child selector. One selector, both
   symptoms. */
.ipx-gain div span { display: block; margin-top: 2px; color: var(--ink-2);
  font-size: .91rem; line-height: 1.6; }
.ipx-gain-note { margin: 4px 26px 0; padding: 12px 16px; border-radius: var(--radius-sm);
  background: var(--ok-bg); color: var(--ok); font-size: .9rem; font-weight: 600;
  text-align: center; }


/* ── the untangling ────────────────────────────────────────────────────── */

.ipx-sub { margin: -4px 0 18px; color: var(--ink-2); font-size: 1rem; }

/* ── the questions, and where they land ────────────────────────────────── */

/* Not a squiggle against a line. On the left are the six questions people
   actually arrive with, drifting and never settling; on the right the same
   work, landed in order with a tick each. It runs continuously on purpose —
   the contrast IS the message, and a contrast you have to scroll past to
   notice is one most readers miss. */
.ipx-chaos {
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: stretch;
  gap: clamp(10px, 2vw, 24px); margin-bottom: 20px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); overflow: hidden;
}
.ipx-ch-side { padding: 20px clamp(14px, 2.4vw, 24px); }
.ipx-ch-side.is-sorted { background: var(--sky-bg); }
.ipx-ch-k { display: block; margin-bottom: 14px; font-size: .84rem; font-weight: 700;
  color: var(--ink-2); }
.ipx-ch-side.is-sorted .ipx-ch-k { color: var(--accent-ink); }
html[data-theme="dark"] .ipx-ch-side.is-sorted .ipx-ch-k { color: var(--signal); }

/* The cloud. Each question sits where it fell, at its own angle, and keeps
   shifting — six chips in a tidy grid would be a list, which is the exact
   thing the left-hand side is not. */
/* Ten questions, overlapping, at four sizes and all leaning different ways.
   Six tidy chips read as a list of topics; this has to read as too much at
   once, which is the actual feeling being described and the reason somebody
   is on this page. They are allowed to cover each other — that is the point,
   not a bug to be spaced out. */
.ipx-ch-cloud { position: relative; height: 178px; }
.ipx-ch-q {
  position: absolute; padding: 6px 12px; border-radius: 999px;
  background: var(--paper-2); border: 1px dashed var(--line);
  color: var(--ink-2); font-size: .8rem; white-space: nowrap;
  transform: rotate(var(--r)) scale(var(--s, 1));
}
.ipx-ch-q:nth-child(1)  { top:  2%; inset-inline-end:  1%; --r: -7deg; --s: 1.05; }
.ipx-ch-q:nth-child(2)  { top: 26%; inset-inline-end: 18%; --r:  5deg; --s: .92; }
.ipx-ch-q:nth-child(3)  { top: 50%; inset-inline-end:  0%; --r: -3deg; --s: 1; }
.ipx-ch-q:nth-child(4)  { top: 12%; inset-inline-end: 40%; --r:  8deg; --s: .88; }
.ipx-ch-q:nth-child(5)  { top: 72%; inset-inline-end: 20%; --r: -6deg; --s: .96; }
.ipx-ch-q:nth-child(6)  { top: 42%; inset-inline-end: 46%; --r:  4deg; --s: .9; }
.ipx-ch-q:nth-child(7)  { top: 64%; inset-inline-end: 52%; --r: -9deg; --s: .86; }
.ipx-ch-q:nth-child(8)  { top: 33%; inset-inline-end:  4%; --r:  7deg; --s: .84; opacity: .8; }
.ipx-ch-q:nth-child(9)  { top: 86%; inset-inline-end:  2%; --r: -4deg; --s: .9; opacity: .72; }
.ipx-ch-q:nth-child(10) { top:  0%; inset-inline-end: 28%; --r: 10deg; --s: .82; opacity: .66; }

.ipx-ch-list { list-style: none; margin: 0; padding: 0; }
.ipx-ch-list li { display: flex; align-items: center; gap: 10px; padding: 9px 0;
  font-size: .88rem; color: var(--ink); }
.ipx-ch-list li + li { border-top: 1px solid color-mix(in srgb, var(--ink) 8%, transparent); }
/* --joy is a DARK green on cream and a LIGHT mint in dark, so a hard-coded
   white tick measured 7.5:1 in one theme and 1.74:1 in the other. The ground
   flips, so the ink has to flip with it. */
.ipx-ch-list span { display: grid; place-items: center; width: 22px; height: 22px;
  flex: none; border-radius: 50%; background: var(--joy); color: var(--surface);
  font-size: .7rem; font-weight: 700; }
html[data-theme="dark"] .ipx-ch-list span { color: var(--canvas); }

/* A plain hairline now, not a plane. Three planes on one page meant the one
   that carries the idea — the journey at the top — stopped being special,
   and this one was decorating a divider rather than saying anything. */
.ipx-ch-go { align-self: stretch; width: 1px; background: var(--line); }

@media (prefers-reduced-motion: no-preference) {
  /* Never still, never far: 7px of drift on a 9s cycle, each chip offset so
     the cloud never pulses in unison. */
  .ipx-ch-q { animation: ipx-drift 6.5s ease-in-out infinite;
    animation-delay: calc(var(--i) * -.9s); }
  .ipx-ch-list li { animation: ipx-land 6s var(--ease) infinite;
    animation-delay: calc(var(--i) * .35s); }
}
/* Bigger throws on a shorter cycle. At 7px over 9s the cloud looked
   becalmed, which is the opposite of overwhelmed. */
@keyframes ipx-drift {
  0%, 100% { transform: rotate(var(--r)) scale(var(--s, 1)) translate(0, 0); }
  25%      { transform: rotate(calc(var(--r) + 4deg)) scale(var(--s, 1)) translate(9px, -10px); }
  55%      { transform: rotate(calc(var(--r) - 5deg)) scale(var(--s, 1)) translate(-11px, 7px); }
  80%      { transform: rotate(calc(var(--r) + 2deg)) scale(var(--s, 1)) translate(6px, 5px); }
}
@keyframes ipx-land {
  0%, 12%   { opacity: .35; transform: translateX(10px); }
  22%, 88%  { opacity: 1; transform: none; }
  100%      { opacity: .35; transform: translateX(10px); }
}

/* ── two lanes, same destination ───────────────────────────────────────── */

/* The comparison, run rather than tabulated. One lane stalls at every
   obstacle and starts over; the other flies it once. The table underneath is
   the detail — this is the argument. */
.ipx-race { padding: 18px clamp(14px, 3vw, 26px) 20px; margin-bottom: 16px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); }
.ipx-race-ends { display: flex; align-items: center; gap: 12px; margin-bottom: 14px; }
.ipx-race-mid { flex: 1; text-align: center; font-size: .78rem; letter-spacing: .04em;
  color: var(--ink-3); }
.ipx-race .ipx-flag { width: 30px; height: 21px; }

.ipx-lane { display: grid; grid-template-columns: 7rem 1fr auto;
  align-items: center; gap: 12px; padding: 12px 10px; border-radius: var(--radius-sm); }
.ipx-lane + .ipx-lane { margin-top: 6px; }
.ipx-lane-k { display: flex; align-items: center; gap: 8px;
  font-size: .88rem; font-weight: 700; color: var(--ink-2); }

/* The Itqan+ lane is the one being sold, so it is the one that looks like
   something: its own ground, its own border, and the mark from the journey's
   middle pin repeated here. The two objects on this page that stand for
   Itqan+ should be recognisably the same thing. */
.ipx-lane.is-with {
  background: var(--sky-bg); border: 1px solid var(--signal); padding-inline: 12px;
}
.ipx-lane.is-with .ipx-lane-k { color: var(--accent-ink); }
html[data-theme="dark"] .ipx-lane.is-with .ipx-lane-k { color: var(--signal); }
.ipx-lane-mark {
  flex: none; width: 24px; height: 24px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--signal-deep); color: #fff;
  font-family: var(--happy); font-weight: 800; font-size: 1rem; line-height: 1;
}
html[data-theme="dark"] .ipx-lane-mark { background: var(--signal); color: var(--signal-ink); }
.ipx-lane.is-with .ipx-track { background: color-mix(in srgb, var(--signal) 22%, transparent); }
.ipx-lane-t { font-size: .78rem; color: var(--ink-3); white-space: nowrap; }
.ipx-lane.is-with .ipx-lane-t { color: var(--joy); font-weight: 700; }

.ipx-track { position: relative; height: 26px; border-radius: 999px;
  background: var(--paper-2); }
/* The obstacles the solo lane keeps hitting. */
/* Walls, not tick-marks. Two thin lines read as scale markings; a solid
   barrier the full height of the lane reads as something you cannot get
   past, which is what these are. */
.ipx-stops-x i { position: absolute; top: 4px; bottom: 4px; inset-inline-end: var(--x);
  width: 4px; border-radius: 2px;
  background: color-mix(in srgb, var(--bad) 70%, transparent); }
/* Physical `right`, animated — not translateX with a percentage.
   A percentage in translateX is a share of the ELEMENT, so translateX(-22%)
   moved the 12px walker by 2.6px instead of a quarter of the lane. Animating
   `right` is a share of the track, which is what both runners are actually
   crossing. The page is always RTL, so the start is the right edge. */
.ipx-walker { position: absolute; top: 50%; right: 6px;
  width: 13px; height: 13px; margin-top: -6.5px; border-radius: 50%;
  background: var(--bad); }
.ipx-trail { position: absolute; top: 50%; right: 8px; height: 2px;
  width: 0; margin-top: -1px; border-radius: 2px;
  background: linear-gradient(to left, var(--sky), transparent); }
.ipx-flyer { position: absolute; top: 50%; right: 6px;
  margin-top: -10px; color: var(--sky); }
.ipx-flyer svg { width: 20px; height: 20px; transform: rotate(-90deg); }

@media (prefers-reduced-motion: no-preference) {
  /* Stutter, stall, give up, start again — four stops in nine seconds and it
     never reaches the end, which is the honest shape of doing this alone. */
  .ipx-walker { animation: ipx-stutter 9s var(--ease) infinite; }
  .ipx-flyer  { animation: ipx-cross 9s var(--ease) infinite; }
  .ipx-trail  { animation: ipx-trail 9s var(--ease) infinite; }
}
/* Three stalls and a reset, and it never reaches the far end — which is the
   honest shape of doing this alone, not a slight against anybody. */
/* Hit a wall, wait, LOSE GROUND, try again — and end up back at the start
   having never crossed. The old version stalled and then carried on forward,
   which reads as slow progress. Going backwards at each wall is what
   actually happens when a Bewerbung comes back incomplete or an employer
   never answers, and it is the difference between "this takes a while" and
   "this is hard". */
@keyframes ipx-stutter {
  0%        { right: 6px; }
  10%, 20%  { right: 23%; }
  25%       { right: 14%; }
  34%, 44%  { right: 45%; }
  49%       { right: 31%; }
  58%, 70%  { right: 67%; }
  76%       { right: 40%; }
  86%, 100% { right: 6px; }
}
@keyframes ipx-cross {
  0%, 6%    { right: 6px; opacity: 0; }
  12%       { opacity: 1; }
  70%, 78%  { right: calc(100% - 26px); opacity: 1; }
  90%, 100% { right: calc(100% - 26px); opacity: 0; }
}
@keyframes ipx-trail {
  0%, 8%    { width: 0; opacity: 0; }
  14%       { opacity: 1; }
  70%, 78%  { width: calc(100% - 34px); opacity: 1; }
  90%, 100% { width: calc(100% - 34px); opacity: 0; }
}

/* ── how it works ──────────────────────────────────────────────────────── */

/* The path walks itself.

   Three cards that simply sit there are three facts. A rail that fills as the
   steps light up is a route being travelled — which is the feeling the
   section is for: this is short, it moves, and most of it is not your work.
   It advances on its own while you are looking at it, and stops the moment
   you touch it, because an autoplay that fights the reader is worse than no
   autoplay. */
.ipx-walk { margin-top: 22px; }
.ipx-rail { position: relative; height: 3px; border-radius: 3px;
  background: var(--paper-2); overflow: hidden; margin-bottom: 16px; }
.ipx-rail-fill { position: absolute; inset-block: 0; inset-inline-start: 0;
  width: 33.33%; border-radius: 3px;
  background: linear-gradient(to left, var(--signal-deep), var(--signal));
  transition: width .55s var(--ease); }
html[data-theme="dark"] .ipx-rail-fill {
  background: linear-gradient(to left, var(--signal), var(--signal-deep)); }

.ipx-steps { display: grid; gap: 14px;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); }
/* A button, not an article: it is pressable, so it has to be pressable by a
   keyboard too. aria-pressed carries the state, and text-align resets what
   the UA button style would otherwise do to Arabic. */
.ipx-step { display: block; width: 100%; text-align: start; font: inherit;
  color: inherit; cursor: pointer;
  padding: 22px; border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--surface); opacity: .72;
  transition: transform .25s var(--ease), border-color .25s var(--ease),
              box-shadow .25s var(--ease), opacity .25s var(--ease); }
.ipx-step:hover { transform: translateY(-3px); border-color: var(--signal);
  box-shadow: var(--shadow); opacity: 1; }
.ipx-step[aria-pressed="true"] { opacity: 1; border-color: var(--signal);
  box-shadow: var(--shadow); }
/* Without the script nothing sets aria-pressed beyond the first card, so the
   dimming has to be off entirely — three greyed cards and no way to light
   them is worse than three plain ones. */
.ipx-walk:not(.is-live) .ipx-step { opacity: 1; }
.ipx-walk:not(.is-live) .ipx-rail { display: none; }

/* The arrival. The route has an end, and saying so is the difference between
   a process diagram and a promise you can picture. */
.ipx-arrive { display: flex; align-items: center; justify-content: center;
  gap: 10px; flex-wrap: wrap; margin: 18px 0 0; padding: 14px 20px;
  border-radius: var(--radius); color: var(--joy);
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--sun-bg) 70%, transparent), var(--joy-bg));
  font-size: 1rem; text-align: center; }
.ipx-arrive span { display: grid; place-items: center; width: 24px; height: 24px;
  border-radius: 50%; background: var(--ok); color: var(--ok-bg);
  font-size: .74rem; font-weight: 700; flex: none; }
.ipx-arrive b { color: var(--ok); }
.ipx-step-n { display: inline-grid; place-items: center; width: 38px; height: 38px;
  border-radius: 50%; background: var(--sky-bg); color: var(--accent-ink);
  font-family: var(--happy); font-weight: 700; font-size: 1.05rem; margin-bottom: 12px; }
.ipx-step:nth-child(2) .ipx-step-n { background: var(--joy-bg); color: var(--joy); }
.ipx-step:nth-child(3) .ipx-step-n { background: var(--sun-bg); color: var(--sun-ink); }
.ipx-step b { display: block; margin-bottom: 6px; font-size: 1.04rem; }
.ipx-step p { margin: 0; color: var(--ink-2); font-size: .93rem; line-height: 1.65; }
.ipx-step-f { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin-top: 14px; }
.ipx-step-who { display: inline-block; padding: 3px 10px;
  border-radius: 999px; font-size: .74rem; font-weight: 700;
  background: var(--paper-2); color: var(--ink-2); }
.ipx-step-who.is-us { background: var(--ok-bg); color: var(--ok); }
.ipx-step-cost { font-size: .8rem; color: var(--ink-3); }
/* Step two is the one being bought, so it is the one that looks different. */
.ipx-step.is-core { border-color: var(--signal); background:
  linear-gradient(var(--surface), var(--surface)) padding-box,
  var(--surface); box-shadow: var(--shadow-sm); }
.ipx-step.is-core .ipx-step-n { background: var(--signal-deep); color: #fff; }
html[data-theme="dark"] .ipx-step.is-core .ipx-step-n { background: var(--signal);
  color: var(--signal-ink); }

/* ── what we commit to ─────────────────────────────────────────────────── */

/* Trust asserted is just a word. Every line in here is something a reader can
   check on this page in the next ten seconds, which is the only kind of trust
   claim worth printing. */
.ipx-trust { display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); margin-top: 20px; }
.ipx-tr { display: flex; gap: 13px; align-items: flex-start;
  padding: 18px 20px; border-radius: var(--radius);
  background: var(--surface); border: 1px solid var(--line);
  transition: border-color .22s var(--ease), transform .22s var(--ease); }
.ipx-tr:hover { border-color: var(--signal); transform: translateY(-2px); }
/* Four cards that answer a fear each.

   The previous version was four identical green ticks and a promise — which
   is what every page claiming to be trustworthy looks like. These name the
   thing somebody is actually worried about (will they take my money and
   vanish; is the price real; do I own what I paid for; do they know this
   process at all) and answer it with something checkable on this page. The
   last line is the verdict, so a reader who only scans the bold gets it. */
.ipx-tr-i { flex: none; width: 46px; height: 46px; border-radius: 14px;
  display: grid; place-items: center; font-size: 1.3rem;
  background: var(--sky-bg); }
.ipx-tr:nth-child(2) .ipx-tr-i { background: var(--joy-bg); }
.ipx-tr:nth-child(3) .ipx-tr-i { background: var(--sun-bg); }
.ipx-tr:nth-child(4) .ipx-tr-i { background: var(--paper-2); }
/* These were lost when this block was rewritten: the markup moved to
   .ipx-tr-b b and nothing styled it, so every headline fell back to a plain
   bold at body size — which is most of why the section read as flat. The
   headline is what a scanner reads, so it is larger, tighter and inked
   rather than muted: four answers you can take in without reading a single
   supporting line. */
.ipx-tr-b b { display: block; font-family: var(--happy); font-weight: 700;
  font-size: 1.16rem; line-height: 1.35; letter-spacing: -.01em; color: var(--ink); }
.ipx-tr-b > span { display: block; margin-top: 6px; color: var(--ink-2);
  font-size: .9rem; line-height: 1.65; }
.ipx-tr-b em { display: inline-block; margin-top: 10px; padding: 4px 11px;
  border-radius: 999px; font-style: normal; font-size: .76rem; font-weight: 700;
  background: var(--joy-bg); color: var(--joy); }
.ipx-tr:nth-child(2) .ipx-tr-b em { background: var(--sky-bg); color: var(--accent-ink); }
.ipx-tr:nth-child(3) .ipx-tr-b em { background: var(--sun-bg); color: var(--sun-ink); }
.ipx-tr:nth-child(4) .ipx-tr-b em { background: var(--paper-2); color: var(--ink-2); }
html[data-theme="dark"] .ipx-tr:nth-child(2) .ipx-tr-b em { color: var(--signal); }
/* They arrive one after another, as a row of four facts being laid down. */
@media (prefers-reduced-motion: no-preference) {
  .ipx-js .ipx-trust.is-in .ipx-tr {
    animation: ipx-card .5s var(--ease) both; animation-delay: calc(var(--i) * 110ms);
  }
}
@keyframes ipx-card { from { opacity: 0; transform: translateY(14px); } }

/* The numbers strip, which renders only when there are real numbers. */
.ipx-stats { display: grid; gap: 12px;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); margin: 18px 0; }
.ipx-stats div { padding: 18px; text-align: center; border-radius: var(--radius);
  background: var(--signal-wash); }
.ipx-stats b { display: block; font-family: var(--happy); font-size: 2rem;
  line-height: 1; color: var(--accent-ink); }
html[data-theme="dark"] .ipx-stats b { color: var(--signal); }
.ipx-stats span { display: block; margin-top: 6px; font-size: .88rem; color: var(--ink-2); }

/* ── the future ────────────────────────────────────────────────────────── */

/* The page used to end on the disclaimer, which is a true sentence and a
   miserable last impression. The honest note still comes, but after this. */
.ipx-future {
  position: relative; overflow: hidden;
  margin-top: 30px; padding: clamp(34px, 5vw, 56px) 26px; text-align: center;
  border-radius: var(--radius-lg);
  /* The last thing before the small print, and the warmest: sun low, sky
     high. Everything above has been explaining; this one is only meant to
     feel like arriving. */
  background:
    radial-gradient(70% 90% at 78% 100%,
      color-mix(in srgb, var(--sun-bg) 90%, transparent) 0%, transparent 70%),
    radial-gradient(80% 110% at 28% 0%, var(--sky-bg) 0%, transparent 72%),
    var(--surface);
  border: 1px solid var(--line);
}
/* The dossier, finished and stamped.
   Everything above is about getting somewhere; this is about the thing being
   done. The stamp falls, presses, and settles — a shallow press, because a
   heavy one reads as a novelty rather than as a conclusion. */
.ipx-seal { position: relative; width: 150px; height: 118px; margin: 0 auto 20px; }
.ipx-seal-doc {
  position: absolute; inset-inline-start: 18px; top: 6px;
  width: 92px; height: 106px; padding: 14px 12px 0;
  display: flex; flex-direction: column; gap: 9px;
  border-radius: 8px; background: var(--surface);
  border: 1px solid var(--line);
  box-shadow: 0 6px 18px rgba(0, 0, 0, .10);
  transform: rotate(-4deg);
}
/* Two sheets behind it, so it reads as a file and not a single page. */
.ipx-seal-doc::before, .ipx-seal-doc::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  border-radius: 8px; background: var(--surface); border: 1px solid var(--line);
}
.ipx-seal-doc::before { transform: rotate(5deg) translate(4px, 2px); }
.ipx-seal-doc::after { transform: rotate(10deg) translate(8px, 4px); opacity: .6; }
.ipx-seal-doc i {
  display: block; height: 5px; border-radius: 3px;
  background: color-mix(in srgb, var(--ink) 13%, transparent);
}
.ipx-seal-doc i:nth-child(1) { width: 62%; }
.ipx-seal-doc i:nth-child(2) { width: 100%; }
.ipx-seal-doc i:nth-child(3) { width: 84%; }
.ipx-seal-doc i:nth-child(4) { width: 44%; }
.ipx-seal-mark {
  position: absolute; inset-inline-end: 10px; bottom: 4px;
  width: 58px; height: 58px; border-radius: 50%;
  display: grid; place-items: center;
  color: var(--joy);
  background: color-mix(in srgb, var(--joy) 14%, var(--surface));
  border: 2.5px dashed color-mix(in srgb, var(--joy) 65%, transparent);
  transform: rotate(-12deg);
}
.ipx-seal-mark svg { width: 26px; height: 26px; }
@media (prefers-reduced-motion: no-preference) {
  .ipx-seal-mark { animation: ipx-stamp 5s 1.1s var(--ease) infinite; }
  .ipx-buy-2 { animation: ipx-buy-pulse 3.2s 1.2s ease-in-out infinite; }
}
/* Down, press, settle — then hold, so it is a punctuation mark and not a
   flicker in the corner of the eye for the rest of the visit. */
@keyframes ipx-stamp {
  0%      { transform: rotate(-12deg) translate(6px, -22px) scale(1.3); opacity: 0; }
  10%     { opacity: 1; }
  16%     { transform: rotate(-12deg) translate(0, 0) scale(.94); opacity: 1; }
  22%     { transform: rotate(-12deg) translate(0, 0) scale(1.04); }
  28%, 92% { transform: rotate(-12deg) translate(0, 0) scale(1); opacity: 1; }
  100%    { transform: rotate(-12deg) translate(0, 0) scale(1); opacity: 1; }
}
@keyframes ipx-buy-pulse {
  0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--signal) 40%, transparent); }
  55% { box-shadow: 0 0 0 12px color-mix(in srgb, var(--signal) 0%, transparent); }
}
.ipx-future-note {
  margin-top: 14px !important; font-size: .84rem; color: var(--ink-3);
}
.ipx-future .ipx-h2 { padding-top: 0; }
.ipx-future .ipx-h2::before { display: none; }
.ipx-future p { margin: 8px auto 0; max-width: 46ch; color: var(--ink-2); }
.ipx-buy-2 { display: inline-flex; margin: 22px auto 0; padding-inline: 34px; }

/* The market line, which renders only when there is a real range to compare
   against. Two figures side by side and no adjective — the gap is the
   argument, and a swipe at rivals is the easiest thing for them to answer. */
.ipx-market { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px;
  margin: 0 0 16px; padding: 16px 20px; border-radius: var(--radius);
  background: var(--paper-2); font-size: .96rem; color: var(--ink-2); }
.ipx-market b { color: var(--ink); }
.ipx-market-us { margin-inline-start: auto; padding: 7px 16px; border-radius: 999px;
  background: var(--joy-bg); color: var(--joy); font-weight: 700; }
.ipx-market-us b { color: var(--joy); font-size: 1.08rem; }

/* The same sentence the amber panel used to carry, in the place it belongs:
   under the last button, sized like small print because that is what it is.
   A service that never says what it does not do is a service arguing with a
   customer later. */
.ipx-small { margin: 16px auto 0; max-width: 50ch;
  font-size: .84rem; line-height: 1.7; color: var(--ink-3); }

/* ── reveal ────────────────────────────────────────────────────────────── */

/* Both hiding rules are gated on .ipx-js, a class the SCRIPT adds. No
   JavaScript means nothing is hidden — never a blank page waiting for a
   reveal that is not coming. */
.ipx-js .ipx-rv { opacity: 0; transform: translateY(16px); }
.ipx-js .ipx-rv.is-in { opacity: 1; transform: none;
  transition: opacity .6s var(--ease), transform .6s var(--ease); }

/* The offer builds a line at a time — the one place a stagger earns itself,
   because it makes a reader watch the list instead of skipping it. */
.ipx-js .ipx-card.is-in .ipx-feat li {
  animation: ipx-line .45s var(--ease) both; animation-delay: var(--d, 0ms);
}
@keyframes ipx-line { from { opacity: 0; transform: translateY(8px); } }

@media (prefers-reduced-motion: reduce) {
  .ipx-js .ipx-rv { opacity: 1; transform: none; }
  .ipx-js .ipx-card.is-in .ipx-feat li { animation: none; }
}

/* ── phone ─────────────────────────────────────────────────────────────── */

@media (max-width: 680px) {
  /* The journey turns vertical: the stops stack, the route runs down the
     side of them, and the plane descends it. Keeping the row and shrinking it
     would put three flags and three captions into 340px, which is how a
     journey becomes three stamps in a line.

     Roomier than before, and deliberately: the stops are further apart so the
     plane has ground to cover between them, which is the one thing this
     object exists to show. A cramped route reads as a list with a dot on it. */
  .ipx-journey { padding: 26px 18px 30px; }
  .ipx-stops { grid-template-columns: 1fr; gap: 40px; }
  .ipx-stop { flex-direction: row; text-align: start; gap: 16px;
    align-items: center; padding: 0; }
  .ipx-stop-t { flex: 1; }
  .ipx-stop-t b { font-size: 1.1rem; }
  .ipx-pin { width: 60px; height: 60px; flex: none; }
  .ipx-flag { width: 38px; height: 26px; }
  .ipx-pin-mark { font-size: 1.9rem; }
  .ipx-path { inset-inline: auto; top: 52px; bottom: 52px; height: auto;
    width: 2px; inset-inline-start: 47px; }
  .ipx-plane svg { width: 26px; height: 26px; }
  .ipx-dash { background-image: linear-gradient(180deg, var(--signal) 50%, transparent 50%);
    background-size: 2px 12px; background-repeat: repeat-y; }
  .ipx-plane { left: 50%; top: 0; transform: translate(-50%, -50%); }
  .ipx-plane svg { transform: rotate(180deg); }    /* nose-down */
  @keyframes ipx-fly {
    0%        { top: 0%; opacity: 0; }
    10%       { opacity: 1; }
    80%       { opacity: 1; }
    90%, 100% { top: 100%; opacity: 0; }
  }
  .ipx-card { margin-top: 26px; }
  .ipx-chaos { grid-template-columns: 1fr; }
  .ipx-ch-go { justify-self: center; }
  .ipx-ch-go svg { transform: rotate(0deg); }
  .ipx-ch-cloud { height: 132px; }
  .ipx-ch-q { font-size: .74rem; padding: 5px 10px; }
  /* The race, rebuilt for a phone rather than squeezed onto one.

     Three columns at 390px gave the track about 180px — too little for a
     runner to visibly stall, lose ground and restart, which is the entire
     content of the left-hand lane. So the label sits above its own full-width
     track and the verdict sits under it: each lane becomes a small block that
     reads top to bottom, and the track gets the whole width to tell its
     story in. */
  .ipx-race { padding: 16px 14px 18px; }
  .ipx-race-ends { margin-bottom: 12px; }
  .ipx-race-mid { font-size: .72rem; }
  .ipx-lane { grid-template-columns: 1fr; gap: 6px; padding: 12px 12px 10px; }
  .ipx-lane + .ipx-lane { margin-top: 8px; }
  .ipx-lane-k { font-size: .95rem; }
  .ipx-lane-t { font-size: .78rem; white-space: normal; }
  .ipx-track { height: 30px; }
  .ipx-walker { width: 15px; height: 15px; margin-top: -7.5px; }
  .ipx-flyer svg { width: 22px; height: 22px; }
  /* The solo lane used to be painted --paper-2 — the track's own colour — so
     the rail vanished into it and the three walls stood in empty space, which
     is what made this section look broken on a phone rather than tense. The
     lane takes a faint warning tint, and the rail is drawn explicitly on both
     lanes so it can never be lost against whatever it sits on. */
  .ipx-lane.is-alone { background: color-mix(in srgb, var(--bad) 6%, var(--paper)); }
  .ipx-track { background: var(--paper);
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 14%, transparent); }
  .ipx-lane.is-with .ipx-track {
    background: color-mix(in srgb, var(--signal) 16%, var(--paper));
    box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--signal) 45%, transparent); }
  /* Walls read at a glance on a small rail only if they are solid. */
  .ipx-stops-x i { width: 5px; background: var(--bad); }
  /* The trip label is the section's own caption on a phone; the flags carry
     the ends, so it gets its own line instead of being squeezed between them. */
  .ipx-race-ends { flex-wrap: wrap; row-gap: 6px; }
  .ipx-race .ipx-flag { width: 26px; height: 18px; }
  /* The race ended on a band of dead space taller than the lanes themselves. */
  .ipx-race { margin-bottom: 4px; }
  /* No dimming on a phone. The three steps stack, so all of them are on
     screen together and the walk would be pulling two of them down while you
     are reading them. The rail and the active card's border still say where
     the path has got to. */
  .ipx-walk.is-live .ipx-step { opacity: 1; }
  .ipx-switch { margin-inline: 18px; }
  .ipx-gain li { padding-inline: 18px; }
  .ipx-g summary { padding-inline: 18px; gap: 11px; }
  .ipx-g ul { padding-inline: 18px 18px; padding-inline-start: 18px; }
  .ipx-g-i { width: 36px; height: 36px; border-radius: 11px; }
  .ipx-g-i svg { width: 18px; height: 18px; }
  .ipx-ch-cloud { height: 196px; }
  .ipx-gain-note { margin-inline: 18px; }
  .ipx-price b { font-size: 2.7rem; }
  .ipx-price-ink { height: 10px; bottom: 5px; }
  .ipx-feat li { padding-inline: 18px; }
  /* Both buttons, centred and sized for a thumb.
     The closing CTA centres itself with `margin: 22px auto 0` — and this
     mobile rule, being later in the file, was replacing that `auto` with a
     flat 18px. With the section's own 26px padding the button no longer fit
     the line, so it was laid out at the line start, which in an RTL document
     is the right edge: 18px off centre, every phone.
     Widths are stated rather than left to `auto`, which was resolving to the
     full content box here and then overflowing by its own margins. */
  /* Both CTAs, centred with a real gutter.
     premium.css sets `.btn.accent { width: 100% }` under 560px — 0-2-0, which
     outranks `.ipx-buy` at 0-1-0. So the button took the full content box and
     was then pushed out by its own 18px margins; in an RTL document that
     overflow lands on the left, which is the lean you could see. Matched here
     at 0-3-0 so the width meant for this button wins, with auto gutters doing
     the centring. Applies to the closing CTA too — it carries the same
     classes — and both end up on the same axis as everything above them. */
  .ipx-buy.btn.accent { width: calc(100% - 36px); margin-inline: auto; }
}
