@font-face { font-family: "Bricolage"; src: url(/home/assets/fonts/bricolage-latin-1.woff2?v=a79fdb52d4) format("woff2"); font-weight: 200 800; font-display: swap; }
@font-face { font-family: "Plexar"; src: url(/home/assets/fonts/plexar-latin-400.woff2?v=9ed8dcb02e) format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Plexar"; src: url(/home/assets/fonts/plexar-latin-600.woff2?v=63f4757271) format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Cairo"; src: url(/home/assets/fonts/cairo-arabic-400.woff2?v=1b36945f5f) format("woff2"); font-weight: 400; font-display: swap; }
@font-face { font-family: "Cairo"; src: url(/home/assets/fonts/cairo-arabic-600.woff2?v=621909d2e4) format("woff2"); font-weight: 600; font-display: swap; }
@font-face { font-family: "Cairo"; src: url(/home/assets/fonts/cairo-arabic-700.woff2?v=673212b490) format("woff2"); font-weight: 700; font-display: swap; }

:root {
  --sc-canvas: #0E0A12; --sc-surface: #16101C;
  --sc-ink: #F5EFEA;    --sc-ink-soft: #B9ADB4;
  --sc-accent: #E8927C; --sc-accent-ink: #0E0A12;
  --sc-font-display: "Bricolage", "Cairo", system-ui, sans-serif;
  --sc-font-text: "Plexar", "Cairo", system-ui, sans-serif;
  --plum: #3A2A4D; --maroon: #8A1538;
}
[lang="ar"] { font-family: "Cairo", system-ui, sans-serif; }

/* Playback Task 4: the floor this page took from scrollcraft.css, which it
   no longer loads (the scroll engine left the page): the reset, the body,
   the browser surfaces. No scroll-behavior: every scripted move says its own
   (page.js), and an in-page link without JavaScript jumps. */
:root { --sc-ease-out: cubic-bezier(0.23, 1, 0.32, 1); }
*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
  margin: 0; background: var(--sc-canvas); color: var(--sc-ink);
  font-family: var(--sc-font-text); font-size: clamp(1rem, 0.96rem + 0.22vw, 1.125rem); line-height: 1.62; letter-spacing: -0.005em;
  -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; font-synthesis-weight: none; overflow-x: clip;
}
img, video, canvas, svg { display: block; max-width: 100%; }
button, input, select, textarea { font: inherit; color: inherit; }
::selection { background: var(--sc-accent); color: var(--sc-accent-ink); }
:root { caret-color: var(--sc-accent); accent-color: var(--sc-accent); }
:focus-visible { outline: 2px solid var(--sc-accent); outline-offset: 3px; border-radius: 6px; }
:where(a) { color: inherit; text-decoration-thickness: 1px; text-underline-offset: 0.22em; }
@supports (scrollbar-color: auto) {
  html { scrollbar-color: color-mix(in oklab, var(--sc-ink) 26%, transparent) transparent; scrollbar-width: thin; }
}

/* ---------------------------------------- Playback Task 4: the scene track --
   Ten sections ([data-scene]), one viewport each, in .film over a fixed
   .stage. html.snap (page.js: while a scene before the arrival is on
   screen) turns on mandatory snapping, and every section stops a scroll
   (snap-stop: always), so a swipe moves one scene; from the arrival's rest
   on it is off, and the tail scrolls freely. The stage is what the player
   shows (js/stage.js lays its clips and rest pictures into .stage__film);
   the opening's layered hero sits beside them in .stage__hero and comes
   over them while the page rests on scene 0 ([data-hero-on], page.js). No
   backdrop-filter anywhere on the stage. */
.stage { position: fixed; inset: 0; z-index: 0; overflow: hidden; background: var(--sc-canvas); }
.stage__hero, .stage__film { position: absolute; inset: 0; }
.stage__film { z-index: 1; isolation: isolate; }
.film { position: relative; z-index: 1; }
.scene-s { position: relative; }
html.js.snap { scroll-snap-type: y mandatory; }
/* An open dialog freezes the page behind it: no scroll and no snap. On an
   iPhone the keyboard nudged the page to make room, the snap pulled it back,
   and the caret of the focused field in the demo dialog was drawn where the
   page had been (owner's phone, 2026-10-01). page.js wireDialogs sets it. */
html.js.dialog-open, html.js.snap.dialog-open { overflow: hidden; scroll-snap-type: none; }
html.js .scene-s { height: 100vh; height: 100svh; scroll-snap-align: start; scroll-snap-stop: always; }
/* Playback Task 6: a scene's words are in flow now, and a phone's arrival
   (100vw - 32px wide) carries its scrim 20px past each side (.scene::before),
   4px beyond the screen: that widened the phone's layout viewport (the page
   zoomed out a little at the arrival, innerHeight grew). The old engine's
   world clipped it; the sections clip it sideways now, never vertically (the
   scrim runs off the top of the screen on purpose). */
html.js .scene-s { overflow-x: clip; }
/* the tail is a snap area too, taller than the screen, so anything that lands
   in it while the snap is still on (a focused control scrolled into view, a
   link to #book) stays there instead of being snapped back to a scene */
html.js .tail { scroll-snap-align: start; }
/* the hero over the film at scene 0, cross-fading (350ms, the stage's own
   fade) both ways; it drops behind the film only once it has faded out */
html.js .stage__hero { z-index: 0; opacity: 0; transition: opacity 350ms linear, z-index 0s linear 350ms; }
html.js .stage[data-hero-on] .stage__hero { z-index: 2; opacity: 1; transition: opacity 350ms linear; }

/* fixed, not absolute: an absolute link sits at the document's top, so
   focusing it from anywhere down the flight scrolled the reader back to 0 */
.skip { position: fixed; inset-inline-start: -999px; top: 1rem; }
.skip:focus { inset-inline-start: 1rem; top: 1rem; z-index: 999; background: var(--sc-ink); color: var(--sc-canvas); padding: .5rem 1rem; }

/* No JS: nothing snaps and nothing plays; the scenes are stacked in
   document flow over the stage's still poster. Task 21: each scene is a full screen of its own leg's held frame
   (rN, the clip's last frame), the words at the top as in the film, and its
   pins placed statically over it: every dot on its object through the same
   cover crop (pure CSS: the frame is max(100%, 177.78vh) of the pins
   group's own width, which is the scene's; 100vw would count a classic
   scrollbar the scene does not have. Margins take their percentages from
   that width in both axes), the cards in a column at the screen's
   foot, each dot and its card numbered alike (a counter per scene). On a
   portrait screen, where most objects fall outside the crop, the cards show
   without their dots or numbers. The phone chapter bar's "now" line is
   page.js's; without it there is no current chapter to name. */
html:not(.js) [data-sc-copy] { position: relative !important; inset: auto !important; translate: none !important; }
html:not(.js) .dark-beat { display: none; }
html:not(.js) .blk--hero { left: auto; top: auto; margin: 0 auto; padding: 24vh 0 8vh; }
/* Task 22: the example messages are pinned to the city by JavaScript; without it they are not shown */
html:not(.js) .msgs { display: none; }
html:not(.js) .blk--hero { margin-bottom: 34vh; }
/* Playback Task 4: the scene's section carries its rest picture (rN, the
   clip's last frame; the -p crop on a portrait screen), the words and the
   pins lie over it; scene 0 is the stage's poster, behind */
html:not(.js) .scene-s { min-height: 100vh; }
/* the opening is as tall as its words and their 34vh gap to the first scene (flow-root: the gap stays inside it) */
html:not(.js) .scene-s[data-scene="0"] { min-height: 0; display: flow-root; }
html:not(.js) .scene-s:not([data-scene="0"]) {
  background: linear-gradient(rgb(14 10 18 / .8), rgb(14 10 18 / .15) 42%, rgb(14 10 18 / .15) 70%, rgb(14 10 18 / .6)), var(--scene) center / cover no-repeat;
}
html:not(.js) .scene {
  left: auto; top: auto; width: auto; max-width: none; min-height: 100vh; box-sizing: border-box; padding: 16vh 5vw 10vh;
}
html:not(.js) .scene::before { display: none; }
html:not(.js) [data-scene="1"] { --scene: url(/home/assets/r2.webp?v=ae024950c6); }
html:not(.js) [data-scene="2"] { --scene: url(/home/assets/r3.webp?v=99e9a46bf9); }
html:not(.js) [data-scene="3"] { --scene: url(/home/assets/r4.webp?v=496ae3710e); }
html:not(.js) [data-scene="4"] { --scene: url(/home/assets/r5.webp?v=88a23e9211); }
html:not(.js) [data-scene="5"] { --scene: url(/home/assets/r6.webp?v=71bdbbae09); }
html:not(.js) [data-scene="6"] { --scene: url(/home/assets/r7.webp?v=7415fa785b); }
html:not(.js) [data-scene="7"] { --scene: url(/home/assets/r8.webp?v=1f7c143404); }
html:not(.js) [data-scene="8"] { --scene: url(/home/assets/r9.webp?v=816d133b4c); }
html:not(.js) [data-scene="9"] { --scene: url(/home/assets/r10.webp?v=108526cd08); }
@media (max-aspect-ratio: 3/4) {
  html:not(.js) [data-scene="1"] { --scene: url(/home/assets/r2-p.webp?v=6df4094f25); }
  html:not(.js) [data-scene="2"] { --scene: url(/home/assets/r3-p.webp?v=af727cbe6a); }
  html:not(.js) [data-scene="3"] { --scene: url(/home/assets/r4-p.webp?v=bedbf54c0e); }
  html:not(.js) [data-scene="4"] { --scene: url(/home/assets/r5-p.webp?v=1fca495fec); }
  html:not(.js) [data-scene="5"] { --scene: url(/home/assets/r6-p.webp?v=812c64b5ba); }
  html:not(.js) [data-scene="6"] { --scene: url(/home/assets/r7-p.webp?v=e3f17acf77); }
  html:not(.js) [data-scene="7"] { --scene: url(/home/assets/r8-p.webp?v=cdf6010ac6); }
  html:not(.js) [data-scene="8"] { --scene: url(/home/assets/r9-p.webp?v=62b67b02a0); }
  html:not(.js) [data-scene="9"] { --scene: url(/home/assets/r10-p.webp?v=268c03c9b1); }
}
html:not(.js) .pins {
  position: relative; opacity: 1; visibility: visible; height: 100vh; margin-top: -100vh; overflow: hidden;
  display: flex; flex-direction: column; justify-content: flex-end; align-items: center; gap: 8px; padding: 0 16px calc(var(--chap-h) + 1rem); box-sizing: border-box;
  counter-reset: pin;
}
html:not(.js) .pin { position: static; inset: auto; counter-increment: pin; }
html:not(.js) .pin__card { position: relative; left: auto; top: auto; }
html:not(.js) .pin__lead { display: none; }
html:not(.js) .pin__dot {
  position: absolute; width: 18px; height: 18px; left: 50%; top: 50%;
  margin-left: calc((var(--x) - 50) * max(1%, 1.7778vh));
  margin-top: calc((var(--y) - 50) * max(.5625%, 1vh));
}
html:not(.js) .pin__dot::after,
html:not(.js) .pin__card::before {
  content: counter(pin) / ""; display: grid; place-items: center; width: 18px; height: 18px; border-radius: 50%;
  font: 700 11px/1 var(--sc-font-text); color: var(--sc-canvas); background: var(--sc-accent);
}
html:not(.js) .pin__card::before { position: absolute; inset-inline-start: -9px; top: -9px; }
html:not(.js) .pins__note { position: static; }
html:not(.js) .chapters__now { display: none; }
@media (max-aspect-ratio: 3/4) { html:not(.js) .pin__dot { display: none; } html:not(.js) .pin__card::before { content: none; } }
html:not(.js) .bar { background: rgb(14 10 18 / .9); }
html:not(.js) .tail { background: linear-gradient(rgb(14 10 18 / .86), rgb(14 10 18 / .86)), url(/home/assets/r10.webp?v=108526cd08) center / cover no-repeat fixed; }
html:not(.js) .blk--arrival { max-height: none; overflow: visible; }
html:not(.js) .arrival__body { overflow: visible; }

/* Task 10: a faded copy block (page.js, off the engine's own on/off state)
   is not a scroll box, so it is never a Tab stop of its own. */
.blk[data-copy-off], .blk[data-copy-off] .arrival__body { overflow: hidden; }

/* Task 9: the peak's dark beat. Playback Task 4: a fixed layer of its own
   right after the stage, so it paints over the stage and under the film
   (every scene's words); page.js sets its opacity. */
.dark-beat { position: fixed; inset: 0; z-index: 0; background: #07050A; pointer-events: none; opacity: 0; }

h2 { font: 650 clamp(1.9rem, 3.6vw, 3.2rem)/1.02 var(--sc-font-display); letter-spacing: -0.02em; text-wrap: balance; margin: 0 0 .9rem; }
p { line-height: 1.62; text-wrap: pretty; max-width: 62ch; }
.lede { font-size: 1.15rem; color: var(--sc-ink); }
.fine { font-size: .88rem; color: var(--sc-ink-soft); }
.label { font: 600 .78rem/1 var(--sc-font-text); letter-spacing: .08em; text-transform: uppercase; color: var(--sc-ink-soft); margin-top: 1.25rem; }
.vh { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }

.bar { position: fixed; inset: 0 0 auto 0; z-index: 300; display: flex; align-items: center; gap: 1.25rem; padding: 1rem 5vw; }
/* The official wordmark, painted as a CSS mask (matches the live site's
   Nav.tsx): the asset is an alpha mask of the letterforms only, so the
   colour on screen is background-color, here the page ink token. The base
   rule below is the fallback for a browser that cannot paint a mask -- the
   text wordmark exactly as it shipped before -- kept behind an @supports
   test (both spellings, since Safari shipped -webkit-mask-image first) so
   the branch is resolved before first paint. The "GOAI" text node stays in
   the DOM (text-transparent, not hidden) so it is still selectable and so
   copy extraction is unchanged; aria-label carries the accessible name
   either way. */
.bar__mark { font: 800 1.05rem/1 var(--sc-font-display); letter-spacing: .14em; color: var(--sc-ink); text-decoration: none; margin-inline-end: auto; display: inline-flex; align-items: center; }
@supports ((mask-image: url(/home/assets/brand/goai-wordmark.png?v=46d3d32848)) or (-webkit-mask-image: url(/home/assets/brand/goai-wordmark.png?v=46d3d32848))) {
  .bar__mark {
    width: 55px; height: 15px;
    background-color: var(--sc-ink);
    color: transparent;
    -webkit-mask: url(/home/assets/brand/goai-wordmark.png?v=46d3d32848) center / contain no-repeat;
    mask: url(/home/assets/brand/goai-wordmark.png?v=46d3d32848) center / contain no-repeat;
  }
}
/* final review: the bar's Questions is a link to #questions (it works with
   no JavaScript; page.js upgrades it to open the drawer), laid out as the
   44px box it had as a <button> (phones still hide it, below) */
.bar__link { background: none; border: 0; color: var(--sc-ink); font: inherit; cursor: pointer; min-height: 44px; display: inline-flex; align-items: center; text-decoration: none; }
.btn { font: 600 1rem/1 var(--sc-font-text); border-radius: 4px; padding: .85rem 1.3rem; min-height: 44px; cursor: pointer; border: 1px solid transparent; }
.btn--primary { background: var(--sc-accent); color: var(--sc-accent-ink); }
.drawer { margin: 0; margin-inline-start: auto; height: 100dvh; max-height: none; width: min(34rem, 100vw); background: var(--sc-surface); color: var(--sc-ink); border: 0; padding: 2rem; overflow: auto; }
.drawer::backdrop, .sheet::backdrop { background: rgb(14 10 18 / .6); }
.drawer details { border-bottom: 1px solid rgb(245 239 234 / .12); padding: .9rem 0; }
.drawer summary { cursor: pointer; font-weight: 600; min-height: 44px; display: flex; align-items: center; }
.drawer__close { display: flex; justify-content: flex-end; margin: 0 0 1rem; }
.drawer__close button { min-height: 44px; min-width: 44px; padding: .6rem 1.1rem; background: rgb(245 239 234 / .08); color: var(--sc-ink); border: 1px solid rgb(245 239 234 / .28); border-radius: 4px; font: 600 .85rem/1 var(--sc-font-text); cursor: pointer; }
.drawer__close button:hover, .drawer__close button:focus-visible { background: rgb(245 239 234 / .18); outline: none; }
@media (max-width: 760px) {
  /* Task 18: phones keep Pricing and Book a demo; Questions is in the tail */
  .bar__link:not(.bar__link--pricing, .bar__lang) { display: none; }
}

.sheet { width: min(36rem, 100vw); max-height: 92dvh; background: var(--sc-surface); color: var(--sc-ink); border: 0; border-radius: 18px; padding: 2rem; }
.demo { display: grid; grid-template-columns: minmax(0, 1fr); gap: .9rem; }
.demo label { display: grid; grid-template-columns: minmax(0, 1fr); gap: .35rem; font-weight: 600; }
.demo label[hidden] { display: none; }
.demo input, .demo select, .demo textarea { width: 100%; min-width: 0; font: inherit; padding: .75rem .9rem; border-radius: 10px; border: 1px solid rgb(245 239 234 / .25); background: var(--sc-canvas); color: var(--sc-ink); min-height: 44px; }
.demo [aria-invalid="true"] { border-color: var(--sc-accent); }
.help { display: block; font-weight: 400; font-size: .85rem; color: var(--sc-ink-soft); }
.hp { position: absolute; inset-inline-start: -9999px; }

/* ====================== Task 21 (spec Revision 5): the layout inside the film ==
   The owner's approved mock (lab/film-mock.html, public/lab/film/scenes/):
   rechitta.com's approach. Every scene is one centred idea over the calm part
   of its frame, with a soft radial scrim (no boxes, no columns): a small rose
   eyebrow, one headline, at most one line under it. Details are glass cards
   joined by a thin leader to a glowing dot on an object in the held last
   frame (js/pins.js). A chapter bar along the bottom replaces the rail. */
:root {
  --ink-2: #DCD3D7;                          /* secondary text: 4.5:1 over the scrims, unlike ink-soft */
  --hair: rgb(245 239 234 / .2);
  --chap-h: 3.25rem;                         /* the chapter bar's height, from the screen's foot */
}
/* the eyebrow is small rose text: it carries its own feathered ground (no edge) */
.eyebrow { display: inline-block; padding: 7px 22px; background: radial-gradient(closest-side, rgb(14 10 18 / .85), rgb(14 10 18 / .6) 60%, rgb(14 10 18 / 0)); }
.eyebrow { font: 600 12px/1.2 var(--sc-font-text); letter-spacing: .22em; text-transform: uppercase; color: var(--sc-accent); margin: 0 0 11px; max-width: none; text-shadow: 0 0 2px rgb(14 10 18), 0 0 4px rgb(14 10 18), 0 0 8px rgb(14 10 18 / .95), 0 0 16px rgb(14 10 18 / .85); }
.scene {
  /* never under the bar: its height plus the engine's largest upward drift (2vh) */
  position: absolute; left: 50%; top: max(var(--top, 10%), calc(5.25rem + 2vh)); translate: -50% 0;
  width: min(1100px, 90vw); max-width: none; text-align: center; isolation: isolate; padding: 0;
}
/* the scrim: a soft radial darkening under the words only, never a box */
.scene::before, .blk--hero::before {
  content: ""; position: absolute; z-index: -1; inset: -90px -140px -80px; pointer-events: none;
  background: radial-gradient(closest-side, rgb(14 10 18 / .8), rgb(14 10 18 / .7) 45%, rgb(14 10 18 / .32) 75%, rgb(14 10 18 / .1) 90%, rgb(14 10 18 / 0));
}
.scene h2 {
  font: 500 min(clamp(34px, 4.4vw, 64px), 9vh)/1.04 var(--sc-font-display); letter-spacing: -0.02em;
  text-wrap: balance; margin: 0 auto; max-width: none; text-shadow: 0 2px 30px rgb(14 10 18 / .6);
}
.scene .line {
  max-width: 600px; margin: 18px auto 0; font-size: clamp(15px, 1.25vw, 18px); line-height: 1.5;
  color: var(--sc-ink); text-wrap: balance; text-shadow: 0 0 2px rgb(14 10 18), 0 0 5px rgb(14 10 18 / .95), 0 1px 16px rgb(14 10 18 / .9);
}
/* each scene over the calm part of its own frame (the mock's placements) */
#bay { --top: 8%; }
#channels { --top: 9%; }
#language { --top: 14%; }
#memory { --top: 12%; }
#rules { --top: 5%; }
#handoff { --top: 12%; }
#answer { --top: 7%; }
#morning { --top: 6%; }
#arrival { --top: 12%; }
@media (max-width: 760px) {
  .scene { width: calc(100vw - 40px); }
  /* phones: the width is the screen's, so the scrim is a band across it,
     running off the top of the screen and feathered below the words */
  .scene::before { inset: -160px -20px -80px; filter: none;
    background: linear-gradient(rgb(14 10 18 / .88), rgb(14 10 18 / .84) 66%, rgb(14 10 18 / .45) 86%, rgb(14 10 18 / 0)); }
  .blk--hero::before { inset: -40px -20px; }
  .scene h2 { font-size: min(34px, 8.5vw); max-width: none; }
  .scene .line { font-size: 15px; margin-top: 12px; }
  .eyebrow { font-size: 11px; margin-bottom: 12px; }
  #bay, #channels, #memory, #handoff, #arrival { --top: 11%; }
  #language { --top: 12%; }
  #rules, #morning { --top: 9%; }
  #answer { --top: 10%; }
}
/* short screens: one tighter step */
@media (max-height: 700px) {
  .scene { --top: 0px !important; }
  .scene h2 { font-size: min(clamp(30px, 4vw, 52px), 8.5vh); }
  .scene .line { margin-top: 10px; font-size: 15px; }
  .eyebrow { margin-bottom: 10px; }
}

/* short phones (360x640 and the like): one compact step, so the pins fit under the copy */
@media (max-width: 760px) and (max-height: 700px) {
  .scene h2 { font-size: 28px; }
  .scene .line { font-size: 14px; margin-top: 8px; line-height: 1.45; }
  .pin__card { font-size: 12px !important; padding: 7px 11px; }
  .pin__card p[lang="ar"] { font-size: 16px !important; line-height: 1.4; }
  .pin__gloss { font-size: 11.5px; }
}

/* ---- the pins: each dot rides its object while the clip moves, its card
   with it (js/pins.js writes the opacities and moves every dot, leader and
   card by transform, off data/tracks.json and the frame on screen) */
.pins { position: absolute; inset: 0; pointer-events: none; opacity: 0; visibility: hidden; }
/* Playback Task 6: a group lies over the stage, fixed to the screen like it
   (its scene's section scrolls away while the next clip plays), and is up
   while the stage shows its leg (js/pins.js data-up): it fades out as the
   next leg's clip starts, and in on a rest picture */
html.js .pins { position: fixed; transition: opacity .3s linear, visibility 0s linear .3s; }
html.js .pins[data-up] { opacity: 1; visibility: visible; transition: opacity .3s linear; }
.pin { position: absolute; inset: 0; }
.pin__dot {
  position: absolute; left: -99px; top: -99px; width: 10px; height: 10px; border-radius: 50%;
  background: var(--sc-accent); translate: -50% -50%;
  box-shadow: 0 0 0 5px rgb(232 146 124 / .25), 0 0 18px var(--sc-accent);
}
.pin__lead { position: absolute; left: 0; top: 0; width: 100%; height: 100%; overflow: visible; }
.pin__lead line { stroke: rgb(245 239 234 / .6); stroke-width: 1; }
.pin[data-docked] .pin__dot, .pin[data-docked] .pin__lead { display: none; }
.pin__card {
  position: absolute; left: 0; top: 0; margin: 0; box-sizing: border-box;
  width: max-content; max-width: min(24rem, calc(100vw - 32px));
  padding: 10px 14px; border-radius: 8px; border: 1px solid rgb(245 239 234 / .22);
  background: rgb(14 10 18 / .84);
  font-size: 13px; line-height: 1.4; color: var(--sc-ink); text-align: start;
}
.pin__card small { display: block; font: 600 10.5px/1.3 var(--sc-font-text); letter-spacing: .14em; text-transform: uppercase; color: var(--sc-accent); margin: 0 0 2px; }
.pin__card p { margin: 0; max-width: none; line-height: 1.4; }
.pin--wide .pin__card { width: min(340px, calc(100vw - 32px)); }
.pin__card p[lang="ar"] { font: 400 18px/1.5 "Cairo", "Plexar", system-ui, sans-serif; margin: .15rem 0 0; }
.pin__gloss { color: var(--ink-2); font-size: 12.5px; margin: 4px 0 0 !important; }
.pins__note { position: absolute; left: 0; right: 0; bottom: calc(var(--chap-h) + 1.4rem); margin: 0; max-width: none; text-align: center; font-size: 13px; color: var(--ink-2); text-shadow: 0 0 3px rgb(14 10 18), 0 0 10px rgb(14 10 18 / .95); }
/* Task 24: the note now sits over the moving film (the souq's lit ground and
   the fibre ring pass under it), so it gets a quiet glass pill of its own */
html.js .pins__note { left: 50%; right: auto; translate: -50% 0; width: max-content; max-width: calc(100vw - 32px); padding: 3px 12px; border-radius: 999px; background: rgb(14 10 18 / .72); }
/* the peak's card carries the page's one maroon light (leg 8, the answer) */
.pin--answer .pin__card { border-color: rgb(232 146 124 / .42); box-shadow: 0 0 0 1px rgb(138 21 56 / .5), 0 0 60px 6px rgb(138 21 56 / .45); }
@media (max-width: 760px) {
  /* Task 24 note (superseded by playback task 7): cards were glass here to
     avoid a backdrop-filter re-sampling the moving video every frame; cards
     are solid everywhere now, so no phone-specific background is needed. */
  .pin__card { font-size: 12.5px; white-space: normal; max-width: calc(100vw - 32px); }
  .pin__card p[lang="ar"] { font-size: 17px; }
}

/* ---- the chapter bar: 01 Doha to 09 Pricing along the foot of the screen */
.chapters { position: fixed; left: 40px; right: 40px; bottom: 0; z-index: 250; padding: 0 0 max(16px, env(safe-area-inset-bottom)); }
.chapters::before { content: ""; position: absolute; z-index: -1; inset: -2.5rem -40px 0; pointer-events: none; background: linear-gradient(rgb(14 10 18 / 0), rgb(14 10 18 / .78)); }
.chapters ol { list-style: none; margin: 0; padding: 8px 0 0; display: flex; justify-content: space-between; border-top: 1px solid rgb(245 239 234 / .22); }
.chapters a {
  position: relative; display: inline-flex; align-items: center; gap: .5em; min-height: 28px;
  font: 600 11px/1 var(--sc-font-text); letter-spacing: .14em; text-transform: uppercase;
  color: rgb(245 239 234 / .72); text-decoration: none; white-space: nowrap;
}
.chapters a[data-done] { color: rgb(245 239 234 / .86); }
.chapters a[aria-current="step"] { color: var(--sc-ink); }
.chapters a[aria-current="step"]::before { content: ""; position: absolute; top: -12px; inset-inline-start: 0; width: 7px; height: 7px; border-radius: 50%; background: var(--sc-accent); box-shadow: 0 0 12px var(--sc-accent); }
.chapters a:focus-visible { outline: 2px solid var(--sc-ink); outline-offset: 3px; }
.chapters__now { display: none; }
/* load-wait (js/page.js, owner 2026-10-11): while the next clip is still
   downloading, a line fills along the bar's top edge (--nf-wait, 0 to 1,
   from the reading side), and the picture breathes (.stage, inline) */
.chapters::after {
  content: ""; position: absolute; top: -1px; inset-inline-start: 0; height: 2px; pointer-events: none;
  width: calc(var(--nf-wait, 0) * 100%); background: var(--sc-accent); box-shadow: 0 0 10px var(--sc-accent);
  opacity: 0; transition: opacity 300ms linear;
}
html[data-nf-wait] .chapters::after { opacity: 1; }
@media (max-width: 1100px) and (min-width: 761px) { .chapters a { letter-spacing: .08em; font-size: 10px; } .chapters { left: 24px; right: 24px; } }
/* phones: the current chapter's number and name, and nine ticks */
@media (max-width: 760px) {
  .chapters { left: 20px; right: 20px; display: flex; align-items: center; justify-content: space-between; gap: .75rem; border-top: 1px solid rgb(245 239 234 / .22); padding-top: 4px; }
  .chapters::before { inset: -2rem -20px 0; }
  .chapters__now { display: block; margin: 0; font: 600 10px/1 var(--sc-font-text); letter-spacing: .1em; text-transform: uppercase; color: var(--sc-ink); white-space: nowrap; max-width: none; }
  .chapters ol { border-top: 0; padding: 0; gap: 0; justify-content: flex-end; }
  .chapters a { font-size: 0; letter-spacing: 0; min-width: 24px; min-height: 28px; justify-content: center; }
  .chapters a::after { content: ""; width: 16px; height: 2px; background: rgb(245 239 234 / .3); }
  .chapters a[data-done]::after { background: rgb(245 239 234 / .62); }
  .chapters a[aria-current="step"]::after { background: var(--sc-accent); box-shadow: 0 0 8px var(--sc-accent); }
  .chapters a[aria-current="step"]::before { display: none; }
}

/* ---- the arrival: Pricing, the two plans as glass cards, centred */
.blk--arrival { width: min(760px, 90vw); display: flex; flex-direction: column; align-items: center; max-height: calc(100% - max(var(--top), calc(5.25rem + 2vh)) - var(--chap-h) - 1rem); }
.arrival__body { display: flex; flex-direction: column; align-items: center; min-height: 0; width: 100%; }
.arrival__body[data-scrolls] { scrollbar-width: thin; scrollbar-color: rgb(245 239 234 / .55) transparent; }
.arrival__body[data-scrolls]:not([data-at-end]) {
  -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 3rem), rgb(0 0 0 / .12));
  mask-image: linear-gradient(to bottom, #000 calc(100% - 3rem), rgb(0 0 0 / .12));
}
.arrival__body > * { margin: 0; }
.blk--arrival h2.close-h { margin: 0 auto; padding: 10px 48px; background: radial-gradient(closest-side, rgb(14 10 18 / .8), rgb(14 10 18 / .6) 55%, rgb(14 10 18 / 0)); }
.plans { display: flex; gap: 16px; justify-content: center; margin: 30px 0 0 !important; text-align: start; }
.plan {
  width: 260px; padding: 18px 22px; border-radius: 10px; border: 1px solid rgb(245 239 234 / .22);
  background: rgb(14 10 18 / .84);
}
.plan--featured { border-color: var(--sc-accent); }
.plan h3 { font: 500 18px/1.2 var(--sc-font-display); margin: 0; color: var(--sc-ink); }
.price { margin: 4px 0 8px; font-size: 13px; color: var(--ink-2); max-width: none; }
.price b { font: 500 30px/1.1 var(--sc-font-display); color: var(--sc-ink); margin-inline-end: .2em; }
.plan ul { list-style: none; padding: 0; margin: 0; }
.plan li { padding: .25rem 0; font-size: 13px; line-height: 1.4; color: var(--ink-2); }
.blk--arrival .fine { margin-top: 14px !important; font-size: 12.5px; line-height: 1.5; color: var(--ink-2); max-width: 46ch; text-shadow: 0 0 3px rgb(14 10 18), 0 1px 12px rgb(14 10 18 / .9); }
.blk--arrival .fine b { color: var(--sc-ink); }
.blk--arrival .ctas { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: .6rem 1.6rem; margin: 22px 0 0; max-width: none; }
.blk--arrival .ctas .btn::after { content: "→" / ""; margin-inline-start: .6rem; }
a.btn { display: inline-flex; align-items: center; text-decoration: none; }
.blk--arrival .ctas a:not(.btn) { color: var(--sc-ink); font-weight: 600; font-size: 14px; text-decoration: underline; text-decoration-color: var(--sc-accent); text-decoration-thickness: 2px; text-underline-offset: .45em; min-height: 44px; display: inline-flex; align-items: center; text-shadow: 0 0 3px rgb(14 10 18), 0 1px 12px rgb(14 10 18 / .9); column-gap: .3em; }
/* inline-flex drops the space between "Rather write?" and an isolated <bdi> address (the Arabic page: the words and the address are two flex items), so the gap is set here; a one-run English link is one item and is unchanged */
.clients { display: flex; align-items: center; justify-content: center; gap: .6rem 1.4rem; flex-wrap: wrap; margin: 18px 0 0; }
.blk--arrival .clients .label { margin: 0; font: 600 11px/1 var(--sc-font-text); letter-spacing: .18em; text-transform: uppercase; color: var(--sc-ink); padding: 6px 14px; background: radial-gradient(closest-side, rgb(14 10 18 / .85), rgb(14 10 18 / .55) 60%, rgb(14 10 18 / 0)); text-shadow: 0 0 2px rgb(14 10 18), 0 0 6px rgb(14 10 18 / .95); }
.clients img { height: 28px; width: auto; filter: grayscale(1) brightness(1.6) drop-shadow(0 0 6px rgb(14 10 18 / .9)); opacity: .82; }
.quote { flex: 1 0 100%; margin: .3rem 0 0; text-align: start; }
.quote blockquote { margin: 0; padding-inline-start: 1rem; border-inline-start: 2px solid var(--sc-accent); }
.quote p { margin: 0; font-size: 16px; line-height: 1.5; color: var(--sc-ink); max-width: 52ch; }
.quote figcaption { margin: .45rem 0 0; padding-inline-start: 1rem; font-size: 14px; line-height: 1.4; color: var(--ink-2); }
/* Task 25 (spec Revision 5b): the dawn behind the prices ("Nobody waits
   until morning" read over a night sky). Desktop: a lighter scrim under the
   headline, and a text-shadow to keep it legible; the arrival's own scrim
   lighter. Phones: the shading over the sky fades out by 55%, the plan
   cards are firmer glass instead, and leg 10 pans toward the sunrise (the
   right side of the wide dawn frame) as its film plays, 50% to 68% of it
   (Playback Task 6: the playing clip's film, --pan; 0 at the 9 to 10 seam,
   so the seam is the same frame as before); reduced motion shows r10 at the
   final pan. The mock: /lab/film/dawn/. */
#arrival.scene::before { background: radial-gradient(closest-side, rgb(14 10 18 / .45), rgb(14 10 18 / .39) 45%, rgb(14 10 18 / .18) 75%, rgb(14 10 18 / 0)); }
.blk--arrival h2.close-h {
  background: radial-gradient(closest-side, rgb(14 10 18 / .38), rgb(14 10 18 / .28) 55%, rgb(14 10 18 / 0));
  text-shadow: 0 0 3px rgb(14 10 18 / .85), 0 2px 16px rgb(14 10 18 / .8), 0 2px 34px rgb(14 10 18 / .6);
}
/* with the arrival's scrim lighter, its small words carry their own soft
   local shading (no boxes): the eyebrow's pill firmer, and a feathered
   patch under the fine print and under "Rather write?" */
#arrival .eyebrow { background: radial-gradient(closest-side, rgb(14 10 18 / .95), rgb(14 10 18 / .9) 72%, rgb(14 10 18 / 0)); }
.blk--arrival .fine, .blk--arrival .ctas a:not(.btn) { position: relative; isolation: isolate; }
.blk--arrival .fine::before, .blk--arrival .ctas a:not(.btn)::before {
  content: ""; position: absolute; z-index: -1; inset: -10px -28px; pointer-events: none;
  background: radial-gradient(closest-side, rgb(14 10 18 / .82), rgb(14 10 18 / .62) 60%, rgb(14 10 18 / 0));
}
@media (max-width: 760px) {
  #arrival.scene::before { background: linear-gradient(rgb(14 10 18 / .5), rgb(14 10 18 / 0) 55%); }
  .plan { background: rgb(14 10 18 / .72); }
  /* Task 26: the phone's dawn is the sharp 1080p crop now, whose lit shore
     under the fine print is brighter than the old 540p blur was (4.19:1 at
     360x640): the fine print's own patch is a little firmer, the sky is not */
  .blk--arrival .fine::before { background: radial-gradient(closest-side, rgb(14 10 18 / .9), rgb(14 10 18 / .74) 60%, rgb(14 10 18 / 0)); }
}
/* Task 26: a portrait screen's leg 10 media (clip leg10-m, posters p10-p and
   r10-p) are a crop of the dawn frame, x 656 to 1502 of 1920 at full height
   (tools/encode-playback.sh, js/pins.js CROPS), which holds the whole pan at
   every portrait aspect. The pan is re-mapped into the crop so the screen
   shows what the 16:9 frame showed: the frame's left edge on screen stays
   (1920 - V) * p, p = 50% + 18% of the film, V the frame width the screen
   shows. The box is as tall as a 9:16 crop drawn with object-fit: cover
   would be (--h, container units of the leg), so up to 9:16 it is the 16:9
   frame's own scale, and on wider portrait screens it is the scale of legs 3
   to 9's 608x1080 crops, whose view it meets at the 9 to 10 seam (film 0,
   the crop's left 608 columns: the centre 9:16 of the frame). The offset is
   p x (box - image) + (656 - 1074 p) x --h / 1080, 1074 = 1920 - 846. */
/* Playback Task 6: the pan follows the playing film. The stage's leg 10
   layers (its clips leg10-m and leg10-m-r, and the rest picture r10-p;
   js/stage.js lays them in .stage__film with inline inset/size, hence the
   !important) read --pan, leg 10's forward-normalised film, which page.js
   writes on every frame leg 10 presents, either way, and sets to 1 at rest
   on the arrival (the final pan; reduced motion only ever rests there). */
@media (max-aspect-ratio: 3/4) {
  html.js .stage__film { container-type: size; }
  .stage__film > :is(video[data-clip*="/leg10-m"], img[src*="/r10-p.webp"]) {
    --p: calc(.5 + .18 * var(--pan, 1));
    --h: max(100cqh, 100cqw * 1080 / 608);
    inset: auto 0 !important; top: calc(50cqh - var(--h) / 2) !important; height: var(--h) !important;
    object-position: calc(var(--p) * 100% + (656 - 1074 * var(--p)) * var(--h) / 1080) 50%;
  }
}
@media (max-aspect-ratio: 3/4) and (prefers-reduced-motion: reduce) {
  .stage__film > :is(video[data-clip*="/leg10-m"], img[src*="/r10-p.webp"]) { --p: .68; }
}
@media (max-width: 760px) {
  .blk--arrival { width: calc(100vw - 32px); }
  .arrival__body { overflow-y: auto; overscroll-behavior: contain; flex: 0 1 auto; }
  .plans { flex-direction: column; align-items: stretch; gap: 12px; margin-top: 20px !important; width: 100%; }
  .plan { width: auto; padding: 14px 18px; }
  .price b { font-size: 26px; }
  .blk--arrival .ctas { gap: .2rem 1.2rem; margin-top: 14px; }
  .clients { margin-top: 10px; }
  .clients img { height: 24px; }
}
/* short screens (landscape phones, short laptops): the arrival's body scrolls
   inside itself between the headline's top and Book a demo, and shows it */
@media (max-height: 500px) {
  .arrival__body { overflow-y: auto; overscroll-behavior: contain; flex: 0 1 auto; }
  .plans { flex-direction: row; }
}
@media (max-height: 800px) {
  .plans { margin-top: 16px !important; }
  .plan { padding: 12px 16px; }
  .plan li { padding: .12rem 0; font-size: 12.5px; }
  .price b { font-size: 24px; }
  .blk--arrival .ctas { margin-top: 12px; }
  .clients { margin-top: 8px; }
}

/* ---- the error summary in the demo form */
.err-summary { border-inline-start: 3px solid var(--sc-accent); background: rgb(232 146 124 / .1); padding: .8rem 1rem; border-start-start-radius: 0; border-end-start-radius: 0; border-start-end-radius: 6px; border-end-end-radius: 6px; }
.err-summary p { margin: 0 0 .4rem; font-weight: 600; }
.err-summary ul { margin: 0; padding-inline-start: 1.1rem; }
.err-summary li { line-height: 1.45; }
.err-summary:focus-visible { outline: 2px solid var(--sc-ink); outline-offset: 2px; }

/* ------------------------------------------------ leg 1: the layered hero --
   Task 13: Doha at night. Three planes derived from the approved photo: the
   sky and horizon haze (far), the bay and the sea (water) and the lit city
   (city). Each plane is the image's own box under object-fit: cover (sized
   with container units). The sky scales about the glide's focus of expansion
   (--ox/--oy, a percent of the image box); the two ground planes carry one
   projective transform written in their own px (hero.js), so their origin is
   0 0. The box is scaled 1.03 to match the engine's resting poster push. */
.stage__hero > picture > img.sc-world__poster { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.hero-planes {
  position: absolute; inset: 0; z-index: 1; overflow: hidden;
  container-type: size; scale: 1.03;
  --art: desktop; --W: 2720; --H: 1530; --ox: 61.7647%; --oy: 35.6209%;
  animation: hero-in 420ms ease-out both;
}
.hero-planes [data-plane] {
  position: absolute; left: 50%; top: 50%; display: block;
  width: max(100cqw, 100cqh * var(--W) / var(--H));
  height: max(100cqh, 100cqw * var(--H) / var(--W));
  max-width: none; max-height: none;   /* the engine's media reset caps these at 100% */
  translate: -50% -50%;
  transform-origin: var(--ox) var(--oy);
  will-change: transform;
}
.hero-planes [data-plane="water"], .hero-planes [data-plane="city"] { transform-origin: 0 0; backface-visibility: hidden; }
@media (max-aspect-ratio: 3/4) {
  .hero-planes { --art: phone; --W: 1530; --H: 2720; --ox: 65.3595%; --oy: 27.0221%; }
}
.hero-live > picture > .sc-world__poster { visibility: hidden; }
/* Task 12.2 / 22: the messages' text as energy (js/energy.js). The canvases
   sit in the copy layer right after the message list, so the streaks are
   above every bubble's panel and below every other block's text (the hero
   copy is lifted over them). Only ever created by JS, and never under
   reduced motion. The glow canvas comes first in the DOM, so the core paints
   over it. */
.energy { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.energy--glow { mix-blend-mode: screen; }
.energy[hidden] { display: none; }
.blk--hero { z-index: 1; }
@keyframes hero-in { from { opacity: 0; } to { opacity: 1; } }

/* ------------------------------ the city writes in, live: Revision 5b --
   The pool of example messages (index.html [data-msgs]), each a glass bubble
   over a dot on a lit street, joined by a short upright leader (the approved
   prototype, /lab/film/live/). hero.js pops them up (data-in, data-out),
   places each item's anchor on its dot (translate), sets the bubble's offset
   and scale, its depth (--d, --dn) and fade (--o), and --panel while its text
   erodes into energy. Layout (owner): the channel line (icon, then CHANNEL ·
   LANGUAGE) is always left to right and left-aligned, Arabic included; the
   message follows its own direction (lang, dir), its time after it; the
   small tail corner is on the text's start side. The icons: brand colours by
   default (C2); .msgs--mono makes them all white (C1). */
.msgs { position: absolute; inset: 0; margin: 0; padding: 0; list-style: none; pointer-events: none; }
/* Playback Task 5: the list and its energy canvases live in scene 0's
   section (document order), but they are the city's, not the words': fixed
   to the viewport like the stage's hero, they stay on screen while the page
   moves on to scene 1 and the opening's clock erodes them into energy.
   hero.js hides them once the opening is off screen. */
html.js .msgs, html.js .energy { position: fixed; }
.msg { position: absolute; left: 0; top: 0; width: 0; height: 0; max-width: none; }
/* The fade (hero.js --o) sits on the bubble, the dot and the leader
   themselves: on an ancestor it would make the item a backdrop root, and the
   glass would blur nothing. Depth (hero.js --d, 0.55 far to 1 near, the
   mock's ramp) dims the dot, the leader and the glass's edge fully, and the
   words only down to 0.8 (--t): the mock dimmed whole bubbles, which let the
   bright streets through the glass and put the far ones' words under 3:1. */
.msg__b { opacity: var(--o, 0); --t: calc(.8 + .2 * var(--dn, 1)); }
.msg__dot, .msg__lead { opacity: calc(var(--o, 0) * var(--d, 1)); }
.msg__pop { position: absolute; left: 0; top: 0; opacity: 0; transform-origin: 0 0; }
.msg[data-in] .msg__pop { animation: msg-pop 560ms cubic-bezier(.2, .8, .2, 1) calc(var(--i, 0) * 150ms) both; }
.msg[data-out] .msg__pop { animation: msg-out 450ms ease both; }
@keyframes msg-pop {
  0% { opacity: 0; scale: .86; }
  55% { opacity: 1; scale: 1.035; }
  100% { opacity: 1; scale: 1; }
}
@keyframes msg-out { from { opacity: 1; } to { opacity: 0; translate: 0 -6px; scale: .92; } }
.msg__dot {
  position: absolute; left: 0; top: 0; width: 10px; height: 10px; border-radius: 50%; translate: -50% -50%;
  background: var(--sc-accent); box-shadow: 0 0 0 5px rgb(232 146 124 / .25), 0 0 18px var(--sc-accent);
}
/* the leader: a 1px line from the dot, hero.js sets its length and angle */
.msg__lead { position: absolute; left: 0; top: 0; width: var(--len, 0); height: 1px; margin-top: -.5px; background: rgb(245 239 234 / .6); transform-origin: 0 50%; rotate: var(--ang, 0deg); }
.msg__b {
  position: absolute; left: 0; top: 0; display: block; width: max-content; box-sizing: border-box;
  translate: 0 -100%; transform-origin: 0 100%;
  padding: 7px 10px 6px; border-radius: 14px 14px 14px 4px;
  /* Fix round 1: --panel is not a pop-in value — it stays 1 while the bubble
     shows and ramps 1 to 0 as its glyphs erode into streaks on the way out
     (js/energy.js panelAlpha). A flat background here left a borderless
     opaque box after the border/shadow (still --panel-scaled below) had
     faded away. Solid card, but still one that clears with the bubble. */
  background: rgb(14 10 18 / calc(.84 * var(--panel, 1)));
  border: 1px solid rgb(245 239 234 / calc(.22 * var(--panel, 1) * var(--d, 1)));
  box-shadow: 0 8px 30px rgb(0 0 0 / calc(.35 * var(--panel, 1)));
  color: var(--sc-ink); text-align: start;
}
.msg[dir="rtl"] .msg__b { border-radius: 14px 14px 4px 14px; }
/* the pop's soft glow */
.msg__b::after { content: ""; position: absolute; inset: -1px; border-radius: inherit; pointer-events: none; opacity: 0; box-shadow: 0 0 0 1px rgb(232 146 124 / .55), 0 0 26px 4px rgb(232 146 124 / .45); }
.msg[data-in] .msg__b::after { animation: msg-glow 1100ms ease-out calc(var(--i, 0) * 150ms) both; }
@keyframes msg-glow { 0% { opacity: 0; } 25% { opacity: 1; } 100% { opacity: 0; } }
.msg__who {
  display: flex; align-items: center; justify-content: flex-start; gap: 6px; direction: ltr; text-align: left; margin: 0 0 2px;
  font: 600 9.5px/1.3 var(--sc-font-text); letter-spacing: .14em; text-transform: uppercase; color: rgb(232 146 124 / var(--t));
}
.msg__ic { display: block; flex: none; width: 16px; height: 16px; fill: var(--sc-ink); opacity: calc(var(--panel, 1) * var(--t)); }
.msg__ic--mail, .msg__ic--call { width: 14px; height: 14px; }
.msg__ic--wa { fill: #25D366; }
.msg__ic--ig { fill: url(#ic-ig-grad); }
.msgs--mono .msg__ic { fill: var(--sc-ink); }
/* scene 3's lanes (owner 2026-09-29): the channel as its app icon and name, no "Way in" label; C2 colours as the city messages */
.pin__card--ch { display: flex; align-items: center; gap: 8px; }
.pin__ic { display: block; flex: none; width: 16px; height: 16px; fill: var(--sc-ink); }
.pin__ic--wa { fill: #25D366; }
.pin__ic--ig { fill: url(#ic-ig-grad); }
.pin__ic--call { width: 14px; height: 14px; }
.msg__m { display: flex; align-items: flex-end; gap: 10px; font: 400 14px/1.5 var(--sc-font-text); color: rgb(245 239 234 / var(--t)); white-space: nowrap; }
.msg__m time { font: 400 11px/1 var(--sc-font-text); color: rgb(201 190 196 / var(--t)); padding-bottom: 4px; direction: ltr; }
.msg[lang="ar"] .msg__m { font: 400 14.5px/1.5 "Cairo", "Plexar", system-ui, sans-serif; }
.msg[lang="ar"] .msg__m time { font-family: var(--sc-font-text); }
.msg[lang="ja"] .msg__t { font-family: "Hiragino Sans", "Yu Gothic", "Noto Sans JP", sans-serif; }
.msg__ch, .msg__t, .msg__m time { display: block; }
.sprite { position: absolute; width: 0; height: 0; overflow: hidden; }
/* a fixed set (reduced motion, the tests' stage) shows without the pop */
.msg[data-quiet][data-in] .msg__pop { animation: none; opacity: 1; }
.msg[data-quiet][data-in] .msg__b::after { animation: none; }
@media (prefers-reduced-motion: reduce) {
  .msg[data-in] .msg__pop, .msg[data-out] .msg__pop { animation: none; opacity: 1; }
  .msg[data-out] .msg__pop { opacity: 0; }
  .msg[data-in] .msg__b::after { animation: none; }
}

/* ------------------------------------------ the hero copy: Revision 5 --
   Centred in the sky as in the approved mock: the eyebrow, the two-line
   headline, the lede, Book a demo and See pricing, then the clients row.
   hero.js walks its fit steps until the block clears the bar, the chapter
   bar and the front message(s) resting on the city below (Task 22). */
.blk--hero {
  position: absolute; left: 50%; top: var(--hero-top, 23%); translate: -50% 0; bottom: auto;
  width: min(1100px, 90vw); max-width: none; padding: 0; text-align: center; isolation: isolate; z-index: 1;
}
.hero-h {
  font: 500 min(clamp(44px, 6.2vw, 92px), 10.5vh)/1.02 var(--sc-font-display);
  letter-spacing: -0.02em; margin: 0; text-shadow: 0 2px 30px rgb(14 10 18 / .6);
}
.hero-h span { display: block; }
.blk--hero .lede { max-width: 600px; margin: 18px auto 0; font-size: clamp(15px, 1.25vw, 18px); line-height: 1.5; color: var(--ink-2); text-shadow: 0 0 3px rgb(14 10 18 / .9), 0 1px 16px rgb(14 10 18 / .9); }
.blk--hero .ctas { display: flex; align-items: center; justify-content: center; gap: 1.4rem; margin: 30px auto 0; max-width: none; width: fit-content; }
.blk--hero .ctas .btn { padding-inline: 1.25rem; }
.blk--hero .ctas .btn span { margin-inline-start: .5rem; }
.link {
  color: var(--sc-ink); font-weight: 600; text-decoration: underline; text-decoration-color: var(--sc-accent);
  text-decoration-thickness: 2px; text-underline-offset: .5em; min-height: 44px; display: inline-flex; align-items: center;
  text-shadow: 0 0 3px rgb(14 10 18), 0 1px 12px rgb(14 10 18 / .9);
}
.link:hover { text-decoration-color: var(--sc-ink); }
.proof { display: flex; align-items: center; justify-content: center; gap: .5rem 1.4rem; margin: 30px auto 0; flex-wrap: wrap; width: fit-content; max-width: 100%; }
.proof__label { margin: 0; font: 600 11px/1 var(--sc-font-text); letter-spacing: .18em; text-transform: uppercase; color: var(--sc-ink); text-shadow: 0 0 2px rgb(14 10 18), 0 0 4px rgb(14 10 18), 0 0 10px rgb(14 10 18 / .95), 0 1px 18px rgb(14 10 18 / .9); }
.proof img { height: 30px; width: auto; filter: grayscale(1) brightness(1.6) drop-shadow(0 0 6px rgb(14 10 18 / .9)); opacity: .8; }
.hero-noproof .blk--hero .proof { display: none; }
.hero-lede-off .blk--hero .lede { display: none; }
.hero-nobook .blk--hero .ctas .btn { display: none; }
.hero-noctas .blk--hero .ctas { display: none; }
.hero-dtight .hero-h { font-size: min(clamp(40px, 5vw, 72px), 9vh); }
.hero-dtight .blk--hero .lede { margin-top: 12px; }
.hero-dtight .blk--hero .ctas { margin-top: 18px; }
@media (max-height: 700px) { .blk--hero { --hero-top: 17%; } }
/* Playback Task 5: the scroll engine rested every copy block 2vh below its
   place (none under reduced motion), and the hero's fit and its clearance
   from the bar were approved there; without the engine the rest is kept here */
html.js .blk--hero { translate: -50% 2vh; }
@media (prefers-reduced-motion: reduce) { html.js .blk--hero { translate: -50% 0; } }
/* Phones: the same, stacked (the mock's phone render) */
@media (max-aspect-ratio: 3/4) {
  .blk--hero { --hero-top: 17%; width: calc(100vw - 40px); }
  .hero-h { font-size: min(44px, 11.5vw); text-shadow: 0 2px 24px rgb(14 10 18 / .8); }
  .blk--hero .lede { font-size: 15px; margin-top: 14px; }
  .blk--hero .ctas { flex-direction: column; gap: .3rem; margin-top: 20px; }
  .proof { margin-top: 18px; gap: .4rem 1.1rem; }
  .proof__label { flex: 1 0 100%; }
  .proof img { height: 24px; }
  .hero-tight .hero-h { font-size: min(38px, 10vw); }
  .hero-tight .blk--hero .lede { font-size: 14px; margin-top: 10px; }
  .hero-tight .blk--hero .ctas { margin-top: 12px; }
}
@media (max-aspect-ratio: 3/4) and (max-height: 700px) { .blk--hero { --hero-top: 12%; } }
@media (prefers-reduced-motion: reduce) {
  .hero-planes { scale: 1; animation: none; }
}

/* =================================================== Task 12b: the tail ==
   After the arrival the page is ordinary content over the flight's held last
   frame. page.js writes --tail (0 when the tail's top meets the bottom of the
   screen at the end of the track, 1 a screen later) and html.tail-on past
   0.35. The flight's copy layer (the arrival) and the chapter bar
   fade out under it, the stage dims, and the bar gets a ground to sit on. */
.stage::after {
  content: ""; position: absolute; inset: 0; z-index: 3; pointer-events: none;
  background: var(--sc-canvas); opacity: calc(var(--tail, 0) * .5);
}
html.js .film { opacity: calc(1 - var(--tail, 0) * 2.5); }
.chapters { opacity: calc(1 - var(--tail, 0) * 2.5); }
html.tail-on .chapters { visibility: hidden; }
html.tail-on .film [data-sc-copy] { pointer-events: none !important; }
.bar { background: rgb(14 10 18 / calc(min(var(--tail, 0) * 2.5, 1) * .9)); }
html.tail-on .bar { -webkit-backdrop-filter: blur(10px); backdrop-filter: blur(10px); }

.tail, .foot { position: relative; z-index: 40; }
.tail {
  padding: 34vh 0 0; padding-inline: max(7vw, 2rem) 5vw;
  background: linear-gradient(rgb(14 10 18 / 0), rgb(14 10 18 / .6) 34vh, rgb(14 10 18 / .72) 100vh);
}
.tail__sec { max-width: 64rem; padding: 0 0 18vh; scroll-margin-top: 5.5rem; }
.tail h2 {
  font: 700 min(clamp(38px, 5vw, 64px), 10.5vh)/.95 var(--sc-font-display); letter-spacing: -0.03em;
  text-wrap: balance; margin: 0 0 2rem; max-width: 18ch;
}
.tail p { font-size: 17px; line-height: 1.6; color: var(--sc-ink); max-width: 46ch; margin: 0; }

/* How it works: the five regions, each named like a flight label */
.regions { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(17rem, 1fr)); gap: 2.2rem 3rem; }
.regions li { padding-top: 1rem; border-top: 1px solid var(--hair); }
.regions h3 {
  display: flex; align-items: center; gap: .75rem; margin: 0 0 .7rem;
  font: 600 12px/1.2 var(--sc-font-text); letter-spacing: .16em; text-transform: uppercase; color: var(--sc-accent);
}
.regions h3::after { content: ""; flex: 0 0 2.5rem; height: 1px; background: currentColor; opacity: .6; }
.regions p { font-size: 16px; line-height: 1.55; }

/* Questions: all ten, open in place (the bar's drawer stays too) */
.faq { max-width: 46rem; border-top: 1px solid var(--hair); }
.faq details { border-bottom: 1px solid var(--hair); }
.faq summary {
  cursor: pointer; min-height: 44px; padding: .85rem 0; display: flex; align-items: center; gap: 1rem;
  font: 600 17px/1.4 var(--sc-font-text); color: var(--sc-ink); list-style: none;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+" / ""; margin-inline-start: auto; font: 400 22px/1 var(--sc-font-text); color: var(--sc-accent); flex: none; }
.faq details[open] summary::after { content: "×" / ""; }
.faq summary:focus-visible { outline: 2px solid var(--sc-ink); outline-offset: 2px; }
.faq details p { color: var(--ink-2); font-size: 16px; line-height: 1.6; max-width: 62ch; padding: 0 0 1.1rem; }
.faq details a { color: var(--sc-ink); text-decoration-color: var(--sc-accent); }

/* Book a demo: the lead beside the form (stacked on phones) */
#book { display: grid; grid-template-columns: minmax(0, 22rem) minmax(0, 34rem); gap: 1.5rem clamp(2rem, 5vw, 5rem); align-items: start; }
#book .book__lead p { color: var(--ink-2); }
.book__form .demo label { color: var(--sc-ink); }
.book__form noscript p a { color: var(--sc-ink); }

.foot {
  padding: 2.2rem 0 2.6rem; padding-inline: max(7vw, 2rem) 5vw; border-top: 1px solid var(--hair);
  background: rgb(14 10 18 / .88); display: grid; gap: .6rem;
}
.foot p { margin: 0; max-width: none; }
.foot__brand { font: 700 18px/1.2 var(--sc-font-display); letter-spacing: .02em; color: var(--sc-ink); display: flex; gap: 1.2rem; align-items: baseline; flex-wrap: wrap; }
/* the footer's brand is the same wordmark as the bar's (owner, 2026-09-30) */
.foot__mark { font: 800 1.05rem/1 var(--sc-font-display); letter-spacing: .14em; }
@supports ((mask-image: url(/home/assets/brand/goai-wordmark.png?v=46d3d32848)) or (-webkit-mask-image: url(/home/assets/brand/goai-wordmark.png?v=46d3d32848))) {
  .foot__mark {
    display: inline-block; width: 55px; height: 15px; background-color: var(--sc-ink); color: transparent;
    -webkit-mask: url(/home/assets/brand/goai-wordmark.png?v=46d3d32848) center / contain no-repeat;
    mask: url(/home/assets/brand/goai-wordmark.png?v=46d3d32848) center / contain no-repeat;
  }
}
.foot__brand a { font: 600 14px/1.4 var(--sc-font-text); letter-spacing: 0; color: var(--sc-ink); text-decoration-color: var(--sc-accent); min-height: 24px; }
.foot .legal { font-size: 12px; line-height: 1.6; color: var(--ink-2); }
.foot .legal a { color: inherit; }

@media (max-width: 900px) {
  #book { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 760px) {
  .tail { padding: 30vh 5vw 0; }
  .tail__sec { padding-bottom: 14vh; }
  .tail h2 { font-size: 38px; margin-bottom: 1.4rem; max-width: none; }
  .tail p, .regions p, .faq details p { font-size: 15px; }
  .faq summary { font-size: 16px; }
  .regions { grid-template-columns: minmax(0, 1fr); gap: 1.6rem; }
  .foot { padding: 1.8rem 5vw 2.2rem; }
}

/* Task 21 (spec Revision 5): the long lists moved here from the flight:
   every way in (the channels answering today and the partner platforms
   ready to connect), what stays with your team, the portal screenshots and
   what it takes to start. Copy moved verbatim. */
.tail .label { font: 600 11px/1.2 var(--sc-font-text); letter-spacing: .16em; text-transform: uppercase; color: var(--sc-accent); margin: 1.6rem 0 .7rem; }
.tail .fine { font-size: 15px; color: var(--ink-2); margin-top: 1rem; }
.chans { list-style: none; padding: 0; margin: 0; display: flex; flex-wrap: wrap; font-size: 16px; line-height: 1.4; }
.chans li { color: var(--sc-ink); }
.chans li + li::before { content: "·" / ""; margin-inline: .5rem; color: var(--ink-2); }
.chans--live { gap: .9rem 1.4rem; align-items: center; }
.chans--live li + li::before { content: none; }
.chans__logo { display: block; width: 30px; height: 30px; }
.chans__logo--wa { fill: #25D366; }
.chans__logo--ig { fill: url(#ic-ig-grad); }
.chans__logo--call { fill: var(--sc-ink); width: 26px; height: 26px; }
.chans--icons { align-items: center; gap: .7rem 1.2rem; color: var(--ink-2); }
.chans--icons li { position: relative; display: flex; align-items: center; min-height: 24px; color: var(--ink-2); }
.chans--icons li + li::before { content: none; }
.chans--icons svg { width: 22px; height: 22px; display: block; fill: currentColor; }
.chans__name { font: 600 11px/1.2 var(--sc-font-text); letter-spacing: .14em; text-transform: uppercase; white-space: nowrap; }
.ledger--no { list-style: none; padding: 0; margin: 0; display: grid; grid-template-columns: 1fr 1fr; column-gap: 2rem; max-width: 40rem; }
.ledger--no li { padding: .6rem 0; border-top: 1px solid var(--hair); font-size: 16px; color: var(--sc-ink); }
.ledger--no li:nth-last-child(-n+2) { border-bottom: 1px solid var(--hair); }
.tail .claim { font: 700 clamp(24px, 2.6vw, 34px)/1.15 var(--sc-font-display); letter-spacing: -0.02em; margin-top: 1.4rem; max-width: 22ch; }
.shots { list-style: none; padding: 0; margin: 1.6rem 0 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 1.2rem 1.4rem; max-width: 60rem; }
.shots li { display: grid; gap: .45rem; }
.shots img { width: 100%; height: auto; display: block; border-radius: 6px; box-shadow: 0 0 0 1px var(--hair), 0 18px 40px -20px rgb(0 0 0 / .8); }
.shots span { font-size: 14px; line-height: 1.3; color: var(--ink-2); }
.steps { list-style: none; counter-reset: step; padding: 0; margin: 0; max-width: 46rem; }
.steps li { counter-increment: step; display: grid; grid-template-columns: 2.25rem minmax(0, 1fr); padding: .9rem 0; border-top: 1px solid var(--hair); font-size: 16px; line-height: 1.55; color: var(--ink-2); }
.steps li:last-child { border-bottom: 1px solid var(--hair); }
.steps li::before { content: counter(step); grid-row: span 3; font: 700 20px/1.3 var(--sc-font-display); color: var(--sc-accent); }
.steps b { display: block; color: var(--sc-ink); font-weight: 600; }
@media (max-width: 760px) {
  .ledger--no { grid-template-columns: minmax(0, 1fr); }
  .ledger--no li { font-size: 15px; }
  .ledger--no li:nth-last-child(2) { border-bottom: 0; }
  .shots { grid-template-columns: minmax(0, 1fr); }
  .steps li { font-size: 15px; grid-template-columns: 1.8rem minmax(0, 1fr); }
}

/* Task 21.5: the tail's structure. Each of the lists that left the flight
   reads as a section of two columns on a wide screen, the heading and its
   line on the left, the list itself on the right (How it works keeps its
   grid of regions, Questions and Book a demo their own layouts); one column
   on phones and tablets. */
@media (min-width: 901px) {
  #ways, #keys, #portal, #start {
    display: grid; grid-template-columns: minmax(0, 22rem) minmax(0, 1fr); grid-template-rows: auto 1fr;
    column-gap: clamp(2rem, 5vw, 5rem); align-items: start;
  }
  :is(#ways, #keys, #portal, #start) > h2 { grid-column: 1; grid-row: 1; }
  :is(#ways, #portal) > p { grid-column: 1; grid-row: 2; color: var(--ink-2); }
  :is(#ways, #keys) > .tail__side, #portal > .shots, #start > .steps { grid-column: 2; grid-row: 1 / span 2; margin-top: .4rem; }
  #ways .tail__side > .label:first-child { margin-top: 0; }
  .tail__sec { max-width: 72rem; }
}

/* ======================== the language switch and the Arabic page ==
   The bar's switch to the other page (the live site's nav.otherLang: its
   label always in the language it switches to, with that lang and dir). */
.bar__lang { font-size: 15px; color: var(--ink-2); }
.bar__lang:hover { color: var(--sc-ink); }
@media (max-width: 760px) { .bar { gap: 1rem; } }
@media (max-width: 380px) { .bar { gap: .8rem; } .bar__lang { font-size: 14px; } }

/* The Arabic page (ar/index.html, lang="ar" dir="rtl") shares this sheet.
   Everything above that has a side is written in logical properties, so the
   words, the bar, the chapter bar, the tail and the dialogs mirror; the
   stage, the pins' dots and leaders and the city's messages belong to the
   film, which is not mirrored, so they keep their physical places. What
   Arabic type needs: Cairo (the live site's own, assets/fonts) carries it
   through the font stacks; no letter-spacing on a joined script and no
   capitals; taller lines for its marks; the small labels a step larger. */
html[lang="ar"] :lang(ar) { letter-spacing: 0 !important; }
:is(.hero-h, .scene h2):lang(ar) { font-weight: 600; line-height: 1.3; }
:is(.tail h2, .tail .claim, h2):lang(ar) { line-height: 1.3; }
.eyebrow:lang(ar) { font-size: 14px; }
:is(.proof__label, .blk--arrival .clients .label, .tail .label):lang(ar) { font-size: 13px; }
.regions h3:lang(ar) { font-size: 14px; }
.pin__card:lang(ar) { font-size: 14px; line-height: 1.5; }
.pin__card small:lang(ar) { font-size: 12.5px; }
.pin__gloss:lang(ar) { font-size: 13.5px; }
.plan li:lang(ar), .price:lang(ar) { font-size: 14px; }
/* the language scene's reply on the Arabic page is the English one */
.pin__card p[lang="en"] { font: 400 16px/1.45 var(--sc-font-text); margin: .15rem 0 0; }
@media (min-width: 761px) { .chapters a:lang(ar) { font-size: 13px; } }
@media (max-width: 1100px) and (min-width: 761px) { .chapters a:lang(ar) { font-size: 12px; } }
@media (max-width: 760px) {
  .eyebrow:lang(ar) { font-size: 13px; }
  .chapters__now:lang(ar) { font-size: 12px; }
  .pin__card:lang(ar) { font-size: 13.5px; }
}
@media (max-width: 760px) and (max-height: 700px) {
  .pin__card:lang(ar) { font-size: 12.5px !important; }
}
/* arrows point the way the page reads */
[dir="rtl"] .blk--arrival .ctas .btn::after { content: "←" / ""; }
/* a phone number and an address are typed left to right, on the page's side */
[dir="rtl"] .demo input[dir="ltr"] { text-align: right; }
/* the tail's Arabic headings run longer than the English: a step smaller on a wide screen */
@media (min-width: 761px) { .tail h2:lang(ar) { font-size: min(clamp(34px, 4vw, 52px), 9vh); } }
/* the bar's Book a demo keeps to one line; the Arabic label is the longer */
.bar__cta { white-space: nowrap; flex: none; }
@media (max-width: 760px) { .bar__cta:lang(ar) { padding-inline: .85rem; } }
@media (max-width: 380px) { .bar__cta:lang(ar) { font-size: 14px; padding-inline: .7rem; } }

/* goai.qa (2026-09-30): the storage notice every page of the site shows
   (js/consent.js; components/consent/ConsentNotice.tsx on the Next pages).
   Fixed, so it cannot move anything; at the inline start, above the chapter
   bar and under the top bar; mirrored on the Arabic page by logical insets.
   Absent without JavaScript, which writes nothing to storage. */
.notice {
  position: fixed; z-index: 260; inset-inline-start: 16px; bottom: calc(max(16px, env(safe-area-inset-bottom)) + 52px);
  width: min(26rem, calc(100vw - 32px)); margin: 0; padding: 16px 18px;
  background: var(--sc-surface); color: var(--sc-ink); border: 1px solid rgb(245 239 234 / .16); border-radius: 14px;
  box-shadow: 0 18px 50px rgb(0 0 0 / .45);
}
.notice__live { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.notice__head { margin: 0; font-size: 15px; font-weight: 600; line-height: 1.35; }
.notice__body { margin: .4rem 0 0; font-size: 13px; line-height: 1.55; color: var(--sc-ink-soft); }
.notice__row { display: flex; flex-wrap: wrap; align-items: center; gap: .6rem 1rem; margin-top: .85rem; }
.notice__row a { font-size: 13px; color: var(--sc-ink-soft); text-underline-offset: .3em; min-height: 44px; display: inline-flex; align-items: center; }
.notice__row a:hover { color: var(--sc-ink); }
.notice__close { min-height: 44px; padding: .5rem 1.1rem; border-radius: 999px; border: 1px solid rgb(245 239 234 / .34); background: transparent; color: var(--sc-ink); font-size: 13px; font-weight: 600; cursor: pointer; }
.notice__close:hover { border-color: rgb(245 239 234 / .6); }
@media (min-width: 761px) { .notice { inset-inline-start: 40px; bottom: calc(max(16px, env(safe-area-inset-bottom)) + 60px); } }
