/* ═══════════════════════════════════════════════════════════════
   NASBOARD — shared stylesheet

   Lives in one file because three pages now use it: index.html,
   privacy.html and ar/index.html. It was inline until the Arabic
   version arrived; keeping three copies in sync by hand was the
   bug waiting to happen.

   Direction-specific rules live in rtl.css, loaded only by the
   Arabic page. Nothing in here should assume left-to-right.
   ═══════════════════════════════════════════════════════════════ */
/* ═══════════════════════════════════════════════════════════════
   NASBOARD

   The page is set like a document, not an app. Ink on paper,
   hairline rules, a visible 12 column grid taken from the logo
   geometry. One full bleed navy passage at the end, on purpose,
   so the page has an arc instead of a uniform surface.

   Francy carries display type. It ships as a single weight, and
   at 60px and up that reads as considered rather than thin, so
   the constraint is doing real work here. Outfit carries anything
   that needs a weight range.
   ═══════════════════════════════════════════════════════════════ */

@font-face {
  font-family: 'Francy';
  /* Relative to THIS file, not to the HTML. These paths were written when
     the CSS was inline in index.html, where assets/ resolved from the site
     root. Moving the stylesheet to assets/css/ silently repointed them at
     assets/css/assets/fonts/ — a 404 — and every headline quietly fell back
     to Outfit, which is close enough to Francy that nothing looked broken. */
  src: url('../fonts/Francy.woff2') format('woff2'),
       url('../fonts/Francy.woff') format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

:root {
  /* ── paper ── */
  --paper:      #FCFCFD;
  --paper-2:    #F2F5F8;
  --ink:        #031A33;
  --ink-2:      #4A5C70;
  --ink-3:      #59697B;
  --rule:       rgba(3, 26, 51, .14);
  --rule-firm:  rgba(3, 26, 51, .28);
  --rule-soft:  rgba(3, 26, 51, .08);
  --rule-faint: rgba(3, 26, 51, .05);

  /* ── accent. Teal fills carry navy text: white on teal is 2.9:1 ── */
  --accent:     #00A8B1;
  --accent-ink: #006E75;
  --on-accent:  #031A33;
  --accent-wash:#E6F8F8;

  /* ── the dark passage ── */
  --band:       #031A33;
  --band-rgb:   3, 26, 51;
  --band-ink:   #F2F7FA;
  --band-ink-2: #9FB3C8;
  --band-rule:  rgba(255, 255, 255, .14);

  --danger:     #B3261E;
  --danger-wash:#FDECEA;

  /* ── motion. The browser defaults are too weak to read as intentional ── */
  --ease-out:    cubic-bezier(.23, 1, .32, 1);
  --ease-in-out: cubic-bezier(.77, 0, .175, 1);

  --nav-h: 66px;
  --gutter: clamp(20px, 4vw, 56px);

  color-scheme: light;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --logo-accent: #35CFD6;
    --logo-mark-paint: #EEF4F8;
    --paper:      #04182C;
    --paper-2:    #071F37;
    --ink:        #EEF4F8;
    --ink-2:      #9BB0C4;
    --ink-3:      #8399AE;
    --rule:       rgba(255, 255, 255, .13);
    --rule-firm:  rgba(255, 255, 255, .26);
    --rule-soft:  rgba(255, 255, 255, .075);
    --rule-faint: rgba(255, 255, 255, .045);
    --accent-ink: #35CFD6;
    --accent-wash:#062B36;
    /* The contrast passage goes deep teal in dark mode. Navy on navy
       would collapse the composition. */
    --band:       #00363C;
    --band-rgb:   0, 54, 60;
    --band-ink:   #F1FBFB;
    --band-ink-2: #9FD4D7;
    --danger:     #FF9A8F;
    --danger-wash:#3A1512;
    color-scheme: dark;
  }
}
:root[data-theme='dark'] {
  --logo-accent: #35CFD6;
  --logo-mark-paint: #EEF4F8;
  --paper:      #04182C;
  --paper-2:    #071F37;
  --ink:        #EEF4F8;
  --ink-2:      #9BB0C4;
  --ink-3:      #8399AE;
  --rule:       rgba(255, 255, 255, .13);
  --rule-firm:  rgba(255, 255, 255, .26);
  --rule-soft:  rgba(255, 255, 255, .075);
  --rule-faint: rgba(255, 255, 255, .045);
  --accent-ink: #35CFD6;
  --accent-wash:#062B36;
  --band:       #00363C;
  --band-rgb:   0, 54, 60;
  --band-ink:   #F1FBFB;
  --band-ink-2: #9FD4D7;
  --danger:     #FF9A8F;
  --danger-wash:#3A1512;
  color-scheme: dark;
}

/* ── base ─────────────────────────────────────────────────── */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: 'Outfit', ui-sans-serif, system-ui, sans-serif;
  font-size: 16px;
  line-height: 1.62;
  -webkit-font-smoothing: antialiased;
  overflow-x: hidden;
}

h1, h2, h3 { margin: 0; font-weight: 500; letter-spacing: -.02em; line-height: 1.1; }
p { margin: 0; }
a { color: inherit; }
ul { margin: 0; padding: 0; list-style: none; }
img, svg { display: block; max-width: 100%; }

.wrap {
  width: 100%;
  max-width: 1320px;
  margin-inline: auto;
  padding-inline: var(--gutter);
}

:where(a, button, input, select, summary, [tabindex]):focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 3px;
  border-radius: 2px;
}

.display {
  font-family: 'Francy', 'Outfit', sans-serif;
  font-weight: 400;
  /* Francy's own sidebearings are already tight, so the -.025em this
     started at collided the letters at hero sizes — "Hire and pay in"
     read as one word. Positive tracking here, not zero: the headline
     needs to look deliberately open rather than merely un-tightened.
     rtl.css overrides this to 0, since Arabic joins and any tracking
     at all breaks the joins. */
  letter-spacing: .012em;
  line-height: 1.02;
}

.meta {
  font-size: .6875rem;
  font-weight: 500;
  letter-spacing: .13em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* ── the grid. Fixed layer, so the rules run the full page and the
      content sits on them rather than next to them. ────────────── */

.grid-layer {
  position: fixed;
  inset: 0;
  z-index: 0;
  pointer-events: none;
}
.grid-layer .wrap { height: 100%; }
.grid-cols {
  height: 100%;
  display: grid;
  grid-template-columns: repeat(12, 1fr);
}
.grid-cols i { border-left: 1px solid var(--rule-faint); }
.grid-cols i:first-child { border-left: 0; }
@media (max-width: 1023px) { .grid-layer { display: none; } }

.page { position: relative; z-index: 1; }

/* ── buttons ──────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 9px;
  white-space: nowrap;
  font: inherit;
  font-weight: 500;
  font-size: .9375rem;
  padding: 13px 24px;
  border: 1px solid transparent;
  border-radius: 2px;            /* Sharp. The logo has no soft corners. */
  cursor: pointer;
  text-decoration: none;
  transition: transform 160ms var(--ease-out),
              background-color 160ms ease,
              border-color 160ms ease,
              color 160ms ease;
}
.btn:active { transform: scale(.97); }
.btn i { font-size: 1.1em; }

.btn-solid { background: var(--accent); color: var(--on-accent); }
.btn-outline { background: transparent; color: var(--ink); border-color: var(--rule); }
.btn-lg { padding: 16px 30px; font-size: 1rem; }

@media (hover: hover) and (pointer: fine) {
  .btn-solid:hover { background: #12BAC3; }
  .btn-outline:hover { border-color: var(--accent); color: var(--accent-ink); }
}
.btn:disabled { opacity: .5; cursor: not-allowed; transform: none; }

/* The language switch is a .btn so its box model is the CTA's box model.
   The first attempt styled it independently and it never matched height;
   sharing the base rule makes a mismatch impossible. Quieter than an
   outline button, but the same size and on the same baseline. */
.btn-lang {
  background: transparent;
  color: var(--ink-2);
  border-color: transparent;
  padding-inline: 14px;
}
.btn-lang i { color: var(--accent); font-size: 1.15em; }
@media (hover: hover) and (pointer: fine) {
  .btn-lang:hover { color: var(--ink); border-color: var(--rule); }
}
@media (max-width: 420px) { .btn-lang .lbl { display: none; } }

/* ── header ───────────────────────────────────────────────── */

.masthead {
  position: sticky;
  top: 0;
  z-index: 40;
  height: var(--nav-h);
  display: flex;
  align-items: center;
  background: color-mix(in srgb, var(--paper) 86%, transparent);
  backdrop-filter: blur(12px) saturate(180%);
  -webkit-backdrop-filter: blur(12px) saturate(180%);
  border-bottom: 1px solid transparent;
  transition: border-color 200ms ease;
}
.masthead.stuck { border-bottom-color: var(--rule); }
.masthead .wrap { display: flex; align-items: center; justify-content: space-between; gap: 16px; }

/* ── brand lockup ──────────────────────────────────────────────────
   The real logo, inlined as a <symbol>. Its wordmark is outlined from
   Francy rather than set as live text, so the lockup does not depend on a
   webfont having loaded and cannot fall back to a system font. The same
   outlines are also written out as standalone files in assets/logo/
   (nasboard-horizontal-outlined*.svg) for use outside this site.

   Fills are CSS variables so one asset serves light, dark and the navy
   footer. Aspect ratio is fixed by the viewBox: set the height and the
   width follows. */
:root {
  --logo-ink:    var(--ink);
  --logo-accent: #00A8B1;
  /* The whole paint, not two stops: a gradient referenced by url() is
     resolved once against the sprite, so per-surface theming has to swap
     the reference rather than the stops inside it. */
  --logo-mark-paint: url(#logo-grad);
  --logo-mark-a: #00A8B1;
  --logo-mark-b: #041A33;
}
.brand { display: inline-flex; align-items: center; text-decoration: none; }
.logo {
  /* Pinned LTR. The wordmark is outlined now, so paths carry no text
     direction and this is no longer load-bearing — but it was: while the
     wordmark was live <text>, dir="rtl" reinterpreted its explicitly
     positioned tspans and the letters scattered. Kept as a guard, because
     a logo is never reordered or mirrored whatever it is made of. */
  direction: ltr;
  height: 27px;
  width: auto;
  aspect-ratio: 1028.72 / 217.82;
  display: block;
  flex: none;
}

.masthead nav { display: flex; align-items: center; gap: 4px; }

.icon-btn {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border: 1px solid transparent;
  border-radius: 2px;
  background: transparent;
  color: var(--ink-2);
  cursor: pointer;
  font-size: 17px;
  transition: color 160ms ease, border-color 160ms ease, transform 160ms var(--ease-out);
}
.icon-btn:active { transform: scale(.94); }
@media (hover: hover) and (pointer: fine) {
  .icon-btn:hover { color: var(--ink); border-color: var(--rule); }
}
.icon-btn .ph-moon { display: none; }
:root[data-theme='dark'] .icon-btn .ph-moon { display: block; }
:root[data-theme='dark'] .icon-btn .ph-sun { display: none; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .icon-btn .ph-moon { display: block; }
  :root:not([data-theme='light']) .icon-btn .ph-sun { display: none; }
}
/* The nav CTA goes away on small screens because the hero has its own and
   two of them crowd the header. The language switch must NOT go with it:
   it is the only way to change language, and it has no duplicate further
   down the page. Below 420px it drops its label and stays as the icon. */
@media (max-width: 600px) {
  .masthead .btn { display: none; }
  .masthead .btn-lang { display: inline-flex; padding-inline: 10px; }
}

/* ═══ HERO ════════════════════════════════════════════════════ */

/* clip is a safety net: decorative blobs and floating cards must never
   create a horizontal scroll, whatever the viewport */
.hero { border-bottom: 1px solid var(--rule); overflow-x: clip; }
/* alternating tint gives the page a rhythm; previously only .how was tinted */
.tint { background: var(--paper-2); border-block: 1px solid var(--rule); }
/* .hero-grid owns the hero columns. The old `.hero .wrap` rule that lived
   here out-specified it (0,2,0 beats 0,1,0), so the new proportions and gap
   were never applied and its 980px breakpoint fought the new 1000px one. */
.hero-copy { display: flex; flex-direction: column; justify-content: center; }
@media (max-width: 980px) {
  .hero-copy { border-right: 0; border-bottom: 1px solid var(--rule); padding-inline: 0; }
}

.status {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 30px;
}
.status .sq { width: 8px; height: 8px; background: var(--accent); flex: none; }
/* A real status indicator, so a perpetual loop is doing actual work here.
   This is the only infinite animation on the page. */
@media (prefers-reduced-motion: no-preference) {
  .status .sq { animation: beat 2.6s ease-in-out infinite; }
}
@keyframes beat {
  0%, 100% { opacity: 1; transform: scale(1); }
  50%      { opacity: .4; transform: scale(.78); }
}

.hero h1 {
  /* Capped so the longest line ("Hire in Egypt") fits the 6-col column.
     The previous 5.5rem cap overflowed it and was only hidden by clip. */
  font-size: clamp(1.9rem, 0.5rem + 5vw, 4.5rem);
  margin-bottom: 26px;
}
/* Each line rises out of its own clipping box. The padding/margin pair
   buys room for the descenders in "Egypt" so the mask does not shear
   the g, y and p. */
.ln {
  display: block;
  overflow: hidden;
  padding-bottom: .14em;
  margin-bottom: -.14em;
}
/* A solid teal square as the full stop. The logo is squares; the
   headline should end in one. */
.stop {
  display: inline-block;
  width: .13em; height: .13em;
  background: var(--accent);
  vertical-align: baseline;
  margin-left: .04em;
}
/* The reveal state for this lives in the .js block near the end of the
   stylesheet, so it lands after the line has finished climbing. */

.deck {
  font-size: clamp(1.0625rem, 1rem + .35vw, 1.3125rem);
  line-height: 1.5;
  color: var(--ink-2);
  max-width: 34ch;
}
.deck b { color: var(--ink); font-weight: 500; }
.hero-cta { margin-top: clamp(28px, 3.5vh, 40px); }

/* ── the form, set into the page rather than floating on it ── */

.signup {
  padding: clamp(36px, 5vh, 60px) 0 clamp(36px, 5vh, 56px) clamp(32px, 4vw, 68px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}
@media (max-width: 980px) { .signup { padding-left: 0; } }

.signup-head { margin-bottom: 28px; }
.signup-head h2 { font-size: 1.1875rem; margin-bottom: 7px; }
.signup-head p { font-size: .875rem; color: var(--ink-2); line-height: 1.55; max-width: 40ch; }

/* blur bridges the two states so the swap reads as one object
   changing rather than two objects trading places */
.signup-body {
  transition: opacity 200ms ease, filter 200ms ease;
}
.signup-body.swapping { opacity: .35; filter: blur(3px); }

/* ── form rhythm ───────────────────────────────────────────────────
   Every interval in this form used to be 20px, so six controls read as
   one undifferentiated stack with nothing to scan. Three intervals now
   do three different jobs, and the contrast between them is what makes
   the grouping legible — proximity, not dividers or boxes.

     --f-label   a label and its input: one unit
     --f-field   controls inside the same group
     --f-group   between groups, the largest gap in the form

   The groups answer three questions in order: who you are, how we
   reach you, what you need. */
.signup-body {
  --f-label: 7px;
  --f-field: 18px;
  --f-group: 32px;
}
.fgroup { display: grid; gap: var(--f-field); }
.fgroup + .fgroup { margin-top: var(--f-group); }

.row2 { display: grid; grid-template-columns: 1fr 1fr; gap: var(--f-field) 22px; }
@media (max-width: 480px) { .row2 { grid-template-columns: 1fr; } }

/* No bottom margin: the group's gap owns vertical rhythm. A margin here
   would stack on top of the gap and bring the flat 20px cadence back. */
.field { display: flex; flex-direction: column; gap: var(--f-label); }
.field > label { font-size: .75rem; font-weight: 500; color: var(--ink-2); letter-spacing: .01em; }

/* Underline inputs. A boxed input would make this look like every
   other signup form; a ruled line looks like a document you fill in. */
.input {
  font: inherit;
  font-size: 1rem;
  width: 100%;
  padding: 7px 0;
  color: var(--ink);
  background: transparent;
  border: 0;
  border-bottom: 1px solid var(--rule);
  border-radius: 0;
  transition: border-color 180ms ease, box-shadow 180ms ease;
}
.input::placeholder { color: var(--ink-3); opacity: .72; }
.input:focus {
  outline: none;
  border-bottom-color: var(--accent);
  box-shadow: 0 1px 0 0 var(--accent);
}
@media (hover: hover) and (pointer: fine) {
  .input:hover:not(:focus) { border-bottom-color: var(--ink-3); }
}
select.input {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
                    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 9px) calc(50% + 1px), calc(100% - 5px) calc(50% + 1px);
  background-size: 4px 4px, 4px 4px;
  background-repeat: no-repeat;
  padding-right: 22px;
  cursor: pointer;
}
/* Sized for a country name plus its code. The native select truncates
   with an ellipsis when the name is long, and because the code is at the
   end of the label the dropdown stays alphabetically scannable. */
.tel { display: grid; grid-template-columns: clamp(104px, 30%, 132px) minmax(0, 1fr); gap: 12px; }

.note { font-size: .75rem; color: var(--ink-3); line-height: 1.5; margin-top: 6px; }

.error {
  display: none;
  align-items: center;
  gap: 5px;
  font-size: .75rem;
  color: var(--danger);
  margin-top: 6px;
  opacity: 0;
  transform: translateY(-3px);
  transition: opacity 160ms var(--ease-out), transform 160ms var(--ease-out);
}
.field.invalid .error { display: flex; opacity: 1; transform: none; }
.field.invalid .input { border-bottom-color: var(--danger); box-shadow: 0 1px 0 0 var(--danger); }

.submit { margin-top: var(--f-group); }
.submit .btn { width: 100%; }
/* Off-screen rather than display:none. Some bots skip hidden inputs but
   fill anything laid out, so this stays in the layout and out of view. */
.trap {
  position: absolute;
  left: -9999px;
  width: 1px; height: 1px;
  overflow: hidden;
}
.consent {
  margin: 16px 0 0;
  font-size: .8125rem;
  line-height: 1.55;
  color: var(--ink-3);
}
.consent a { color: var(--accent-ink); text-decoration: underline; text-underline-offset: 2px; }
.form-error {
  margin: 0 0 16px;
  padding: 11px 13px;
  background: var(--danger-wash);
  border: 1px solid var(--danger);
  color: var(--danger);
  font-size: .875rem;
}
.btn .busy { display: none; }
.btn[data-busy] .idle { display: none; }
.btn[data-busy] .busy { display: inline; }

.switcher {
  margin-top: 18px;
  font-size: .8125rem;
  color: var(--ink-3);
  text-align: center;
}
.switcher button {
  font: inherit;
  font-size: inherit;
  background: none;
  border: 0;
  padding: 0;
  color: var(--accent-ink);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  text-decoration-thickness: 1px;
  transition: opacity 160ms ease;
}
@media (hover: hover) and (pointer: fine) { .switcher button:hover { opacity: .7; } }

/* success */
.done { display: none; }
.signup.finished .signup-body,
.signup.finished .signup-head,
.signup.finished .switcher { display: none; }
.signup.finished .done { display: block; }
.done .tick {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 22px;
  margin-bottom: 22px;
}
.done h2 { font-size: 1.375rem; margin-bottom: 10px; }
.done > p { color: var(--ink-2); margin-bottom: 26px; max-width: 36ch; }
.done ol { display: grid; gap: 0; border-top: 1px solid var(--rule); }
.done li {
  display: grid;
  grid-template-columns: 26px 1fr;
  gap: 12px;
  padding: 14px 0;
  border-bottom: 1px solid var(--rule);
  font-size: .875rem;
  color: var(--ink-2);
}
.done li span { color: var(--accent-ink); font-variant-numeric: tabular-nums; }

/* ═══ MARKETS ═════════════════════════════════════════════════ */

.markets {
  border-bottom: 1px solid var(--rule);
  padding: clamp(64px, 8vw, 116px) 0;
}
.markets .sec-title { margin-bottom: clamp(28px, 3vw, 44px); }
.markets-cols { display: grid; grid-template-columns: 6fr 6fr; }
@media (max-width: 820px) { .markets-cols { grid-template-columns: 1fr; } }

/* Night shots on a light page went muddy under a fade, so the panel becomes a
   navy card instead: the photo keeps a strip of its own at close to its real
   aspect, and the copy sits below it on flat --band where nothing competes. */
.market {
  display: flex;
  flex-direction: column;
  background: var(--band);
  color: var(--band-ink);
}
.market + .market { border-left: 1px solid var(--band-rule); }
@media (max-width: 820px) {
  .market + .market { border-left: 0; border-top: 1px solid var(--band-rule); }
}
.market p { color: var(--band-ink-2); max-width: 42ch; }

.market-shot { position: relative; aspect-ratio: 16 / 9; overflow: hidden; }
.market-bg {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* both landmarks sit right of centre in a 2.24:1 frame, so each panel names
     its own focal point rather than sharing one */
  object-position: var(--focus, 50% 50%);
}
/* dissolves the strip's lower edge into the body so it reads as one card
   rather than a photo stuck above a block */
.market-shot::after {
  content: '';
  position: absolute;
  inset: auto 0 -1px 0;
  height: 46%;
  background: linear-gradient(to bottom,
    rgba(var(--band-rgb), 0)   0%,
    rgba(var(--band-rgb), .45) 46%,
    rgba(var(--band-rgb), .88) 80%,
    rgba(var(--band-rgb), 1)   100%);
  pointer-events: none;
}

.market-body { padding: clamp(24px, 2.6vw, 36px) clamp(26px, 3vw, 40px) clamp(30px, 3.4vw, 44px); }

.market-name { display: flex; align-items: baseline; gap: 13px; margin-bottom: 14px; }
.market-name h3 {
  color: #FFFFFF;
  font-family: 'Francy', 'Outfit', sans-serif;
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.5rem);
  letter-spacing: -.02em;
  line-height: 1;
}
.market-name .ar {
  font-family: 'IBM Plex Sans Arabic', 'Outfit', sans-serif;
  font-size: clamp(1rem, .9rem + .5vw, 1.375rem);
  color: var(--band-ink-2);
  direction: rtl;
  line-height: 1;
}

.facts { margin-top: 22px; border-top: 1px solid var(--band-rule); }
.facts li {
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 10px 0;
  border-bottom: 1px solid var(--band-rule);
  font-size: .875rem;
  color: var(--band-ink-2);
}
.facts i { color: var(--accent); font-size: 1.125rem; flex: none; }

/* ═══ SECTION HEADINGS ═══ */
.section { padding-block: clamp(64px, 8vw, 116px); }
.sec-title { margin-bottom: clamp(32px, 4vw, 52px); }
.sec-title h2 {
  font-size: clamp(1.75rem, 1.2rem + 2vw, 2.75rem);
  max-width: 20ch;
  margin-bottom: 14px;
}
.sec-title p { color: var(--ink-2); max-width: 52ch; font-size: 1.0625rem; }

/* One inline ask, placed where the reader has just finished reading how the
   thing works. Sits on the section rule so it reads as the section signing
   off rather than a banner dropped in. */
.mid-cta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px 28px;
  margin-top: clamp(40px, 5vw, 68px);
  padding-top: clamp(26px, 3vw, 38px);
  border-top: 1px solid var(--rule);
}
.mid-cta p { max-width: 46ch; color: var(--ink-2); }
.mid-cta p b { color: var(--ink); font-weight: 500; }
@media (max-width: 620px) { .mid-cta .btn { width: 100%; justify-content: center; } }

/* ═══ SEQUENCE (how it works) ═════════════════════════════════ */

.how { background: var(--paper-2); border-block: 1px solid var(--rule); }

/* The rule draws left to right, so the three steps read as a sequence
   rather than three parallel facts. That is the whole reason it moves. */
.seq { position: relative; }
/* runs through the icon row rather than sitting above it: three tiles on a
   line read as a sequence, three tiles under a line read as three columns */
.seq-rule {
  position: absolute;
  top: 25px; left: 0; right: 0;
  height: 1px;
  background: var(--rule-firm);
}
.steps { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; }
@media (max-width: 820px) { .steps { grid-template-columns: 1fr; } }

.step { padding: 0 clamp(24px, 3vw, 48px) 0 0; position: relative; }
@media (max-width: 820px) {
  .seq-rule { display: none; }
  .step { padding: 26px 0; border-top: 1px solid var(--rule); }
  .step:first-child { padding-top: 0; border-top: 0; }
}
.step-top { display: flex; align-items: center; gap: 14px; margin-bottom: 22px; }
.step-icon {
  width: 50px; height: 50px;
  display: grid; place-items: center;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 23px;
  flex: none;
  position: relative;
  z-index: 1;                       /* covers the rule passing behind it */
  box-shadow: 0 0 0 8px var(--paper-2);
}
.step-n {
  font-family: 'Francy', 'Outfit', sans-serif;
  font-size: 1.125rem;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  position: relative; z-index: 1;
  background: var(--paper-2);
  padding-right: 10px;
}
.step h3 { font-size: 1.1875rem; margin-bottom: 11px; }
.step p { color: var(--ink-2); font-size: .9375rem; }

/* ═══ SCHEDULE (what we cover) ════════════════════════════════ */

.schedule { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0 clamp(24px, 3vw, 52px); }
@media (max-width: 820px) { .schedule { grid-template-columns: 1fr; gap: 0; } }
.sched-col { border-top: 1px solid var(--ink); padding-top: 18px; }
@media (max-width: 820px) { .sched-col + .sched-col { margin-top: 34px; } }
.sched-col h3 {
  font-size: .8125rem; font-weight: 600; letter-spacing: .02em; margin-bottom: 6px;
  display: flex; align-items: center; gap: 9px;
}
.sched-col h3 i { color: var(--accent-ink); font-size: 1.125rem; }
.sched-col li {
  padding: 11px 0;
  border-bottom: 1px solid var(--rule-soft);
  font-size: .9375rem;
  color: var(--ink-2);
  display: flex;
  gap: 10px;
  align-items: baseline;
}
.sched-col li::before {
  content: '';
  width: 5px; height: 5px;
  background: var(--accent);
  flex: none;
  transform: translateY(-2px);
}

/* ═══ FAQ ═════════════════════════════════════════════════════ */

.faq-list { border-top: 1px solid var(--ink); }
.qa { border-bottom: 1px solid var(--rule); }
.qa summary {
  display: grid;
  grid-template-columns: 1fr 24px;
  gap: 20px;
  align-items: center;
  padding: 21px 0;
  cursor: pointer;
  list-style: none;
  font-size: clamp(1rem, .96rem + .25vw, 1.125rem);
  font-weight: 500;
  transition: color 160ms ease;
}
.qa summary::-webkit-details-marker { display: none; }
@media (hover: hover) and (pointer: fine) { .qa summary:hover { color: var(--accent-ink); } }
.qa summary i {
  color: var(--accent-ink);
  font-size: 1.125rem;
  justify-self: end;
  transition: transform 240ms var(--ease-out);
}
.qa[open] summary i { transform: rotate(45deg); }

/* 0fr to 1fr is the one height animation worth having: it is
   interruptible and needs no measured pixel value */
.qa-body { display: grid; grid-template-rows: 0fr; transition: grid-template-rows 260ms var(--ease-out); }
.qa[open] .qa-body { grid-template-rows: 1fr; }
.qa-body > div { overflow: hidden; }
.qa-body p { color: var(--ink-2); max-width: 68ch; padding-bottom: 24px; }

/* ═══ CLOSE (the dark passage) ════════════════════════════════ */

.close {
  background: var(--band);
  color: var(--band-ink);
  position: relative;
  overflow: hidden;
  padding-block: clamp(76px, 11vw, 148px);
}
.close-mark {
  position: absolute;
  right: -5vw; bottom: -20%;
  width: min(42vw, 500px);
  fill: #FFFFFF;
  opacity: .03;
  pointer-events: none;
  -webkit-mask-image: linear-gradient(240deg, #000 20%, transparent 92%);
  mask-image: linear-gradient(240deg, #000 20%, transparent 92%);
}
.close .wrap { position: relative; z-index: 1; }
.close-grid { display: grid; grid-template-columns: 1fr; }

.close h2 {
  max-width: 20ch;
  font-family: 'Francy', 'Outfit', sans-serif;
  font-size: clamp(2rem, 1.3rem + 2.6vw, 3.25rem);
  letter-spacing: -.02em;
  line-height: 1.06;
  text-wrap: balance;
}
.close p { color: var(--band-ink-2); font-size: 1.0625rem; max-width: 44ch; margin-top: 20px; }
/* Needs to out-specify `.close p` above, which would otherwise
   flatten this to body size. */
.close p.nas {
  max-width: none;
  font-family: 'IBM Plex Sans Arabic', 'Outfit', sans-serif;
  font-size: clamp(3.2rem, 2.1rem + 4.2vw, 5.5rem);
  line-height: 1.32;
  color: var(--band-ink-2);
  direction: rtl;
  text-align: left;   /* RTL shaping, but hung on the same left edge as the headline */
  margin: 0 0 6px;
  max-width: none;
}
.close .btn-solid { margin-top: 30px; }

/* ═══ FOOTER ══════════════════════════════════════════════════ */

.foot { background: var(--band); color: var(--band-ink); border-top: 1px solid var(--band-rule); padding-block: 52px 34px; }
.foot-grid { display: grid; grid-template-columns: 5fr 3fr 4fr; gap: 0; padding-bottom: 34px; }
.foot-grid > * { padding-right: 32px; }
.foot-grid > *:last-child { padding-right: 0; }
@media (max-width: 780px) {
  .foot-grid { grid-template-columns: 1fr 1fr; gap: 36px; }
  .foot-grid > * { padding-right: 0; }
}
@media (max-width: 520px) { .foot-grid { grid-template-columns: 1fr; gap: 26px; } }
/* The brand's own dark-background variant (nasboard-horizontal-white.svg)
   drops the gradient entirely and goes solid, and at 25px on navy the
   reason is obvious: the mark's strokes are ~2px there, and a gradient
   fading toward a pale stop makes half of it read as missing. Both stops
   are set to the same value here, which is the gradient going solid
   without needing a second asset. "Board" keeps its teal, which is the
   one place this departs from the shipped white variant. */
.foot .brand {
  margin-bottom: 15px;
  --logo-ink:    var(--band-ink);
  --logo-accent: #35CFD6;
  --logo-mark-paint: var(--band-ink);
}
.foot .logo { height: 26px; }
.foot-about { color: var(--band-ink-2); font-size: .9375rem; max-width: 33ch; }
.foot h3 { margin: 0 0 13px; font-size: .75rem; font-weight: 600; letter-spacing: .05em; text-transform: uppercase; color: var(--band-ink-2); }
.foot li { font-size: .875rem; color: var(--band-ink-2); padding-block: 4px; line-height: 1.5; }
.foot li b { display: block; color: var(--band-ink); font-weight: 500; }
.foot a { text-decoration: none; transition: color 160ms ease; }
@media (hover: hover) and (pointer: fine) { .foot a:hover { color: var(--band-ink); } }
.socials { display: flex; gap: 8px; margin-top: 18px; }
.socials a {
  width: 36px; height: 36px;
  display: grid; place-items: center;
  border: 1px solid var(--band-rule);
  font-size: 17px;
  color: var(--band-ink-2);
  transition: border-color 160ms ease, color 160ms ease, transform 160ms var(--ease-out);
}
.socials a:active { transform: scale(.94); }
@media (hover: hover) and (pointer: fine) { .socials a:hover { border-color: var(--band-ink-2); color: var(--band-ink); } }
.foot-base {
  border-top: 1px solid var(--band-rule);
  padding-top: 20px;
  display: flex; justify-content: space-between; flex-wrap: wrap; gap: 12px;
  font-size: .8125rem; color: var(--band-ink-2);
}

/* ═══ ENTRANCE ════════════════════════════════════════════════
   Seen once per visit, so it earns its keep: it establishes reading
   order. Transform and opacity only, both off the main thread.
   ═════════════════════════════════════════════════════════════ */

/* ═══════════════════════════════════════════════════════════════
   TECHWIND-STYLE HERO
   Split copy/media, a colour blob behind the mock, floating metric
   cards breaking its edges, and a swoosh highlight on one word.
   ═══════════════════════════════════════════════════════════════ */

/* Marker highlight under a word. The word keeps the ink colour: at 88px,
   teal text plus a teal bar on two words was far too much accent. */
.swoosh { position: relative; white-space: nowrap; }
.swoosh::after {
  content: '';
  position: absolute;
  /* Anchored from the top as a percentage of the inline box. Anchoring to
     the bottom put the bar under the glyphs, because line-height .98 makes
     the inline box shorter than the em box and the descenders overflow it. */
  left: -.03em; right: -.03em;
  top: 58%; height: 20%;
  background: var(--accent);
  opacity: .28;
  transform: rotate(-1.6deg);
  z-index: -1;
  border-radius: 2px;
}
.js .swoosh::after { transform: rotate(-2.2deg) scaleX(0); transform-origin: left center; transition: transform 700ms var(--ease-out) 700ms; }
.js .lines.shown .swoosh::after { transform: rotate(-2.2deg) scaleX(1); }
@media (prefers-reduced-motion: reduce) {
  .js .swoosh::after { transform: rotate(-2.2deg); transition: none; }
}

/* Colour mass behind the media. Techwind puts a big saturated circle here;
   a rotated square carries the same weight while echoing the logo, which is
   two overlapping squares. Bold on purpose: the old blurred version at 16%
   was invisible and did no compositional work. */
.blob {
  position: absolute;
  z-index: 0;
  transform: rotate(45deg);
  background: linear-gradient(150deg, var(--accent) 0%, rgba(0,168,177,.55) 48%, rgba(0,168,177,.10) 100%);
  opacity: .30;
  pointer-events: none;
}
@media (prefers-color-scheme: dark) { :root:not([data-theme='light']) .blob { opacity: .22; } }
:root[data-theme='dark'] .blob { opacity: .22; }

/* ── composed image group: large plate, colour mass behind, small inset
      overlapping one corner. Techwind's split-media composition in this
      page's square geometry. ── */
.plate-wrap { position: relative; }
.plate-mass {
  position: absolute;
  z-index: 0;
  /* A square on its corner. The rotation is applied after layout, so the
     visual diamond overhangs its own box by 0.207 x width on every side:
     at 46% of a 524px column that is 50px, which is what keeps the top
     corner below the photo's edge and the bottom corner inside the section
     while the right corner still clears the frame. */
  width: 46%;
  aspect-ratio: 1;
  right: -2%; top: 15%;
  transform: rotate(45deg);
  background: linear-gradient(150deg, var(--accent) 0%, rgba(0,168,177,.5) 50%, rgba(0,168,177,.08) 100%);
  opacity: .17;
  pointer-events: none;
}
@media (prefers-color-scheme: dark) { :root:not([data-theme='light']) .plate-mass { opacity: .20; } }
:root[data-theme='dark'] .plate-mass { opacity: .20; }

/* Inset from the left so the floating column has somewhere to hang off. The
   86% keeps the logo on the wall clear of the tag card: a 5:4 crop of this
   shot puts the wordmark between 25% and 75% of the frame, and the tag stops
   at 23%. */
.plate {
  position: relative;
  z-index: 1;
  margin: 0 0 0 14%;       /* figure carries a UA margin-inline: 40px */
  width: 86%;
  /* leaves the left 14% and the bottom for the floating column */
  overflow: hidden;
  background: var(--band);
}
.plate img { width: 100%; height: auto; aspect-ratio: 5 / 4; object-fit: cover; object-position: 50% 50%; display: block; }

/* dot field, top left, the one piece of pure decoration in the group */
.plate-dots {
  position: absolute;
  z-index: 0;
  left: 0; top: -38px;
  width: 91px; height: 65px;
  background-image: radial-gradient(var(--accent) 1.6px, transparent 1.6px);
  background-size: 13px 13px;
  opacity: .40;
  pointer-events: none;
}

/* the floating column: a label card, a photo and a caption, all hanging off
   the plate's left and bottom edges. Same card vocabulary as the hero. */
.plate-tag,
.plate-note {
  position: absolute;
  z-index: 3;
  background: var(--paper);
  border: 1px solid var(--rule);
  border-radius: 2px;
  box-shadow: 0 2px 4px rgba(3,26,51,.05), 0 18px 40px -18px rgba(3,26,51,.30);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .plate-tag,
  :root:not([data-theme='light']) .plate-note { box-shadow: 0 18px 40px -18px rgba(0,0,0,.75); }
}
:root[data-theme='dark'] .plate-tag,
:root[data-theme='dark'] .plate-note { box-shadow: 0 18px 40px -18px rgba(0,0,0,.75); }

.plate-tag { left: 0; top: 13%; width: 31%; padding: 15px; }
.plate-tag .ico {
  width: 40px; height: 40px;
  display: grid; place-items: center;
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-size: 20px;
  margin-bottom: 14px;
}
.plate-tag .val {
  display: block;
  font-family: 'Francy', 'Outfit', sans-serif;
  font-size: 1.25rem;
  line-height: 1.1;
}
.plate-tag .lbl { display: block; font-size: .75rem; color: var(--ink-3); margin-top: 6px; }

/* solid teal square straddling the plate's top edge, the logo's own geometry */
.plate-badge {
  position: absolute;
  z-index: 3;
  right: 7%; top: -26px;
  width: 60px; height: 60px;
  display: grid; place-items: center;
  background: var(--accent);
  color: var(--on-accent);
  font-size: 27px;
}

.plate-inset {
  position: absolute;
  z-index: 2;
  margin: 0;
  left: 0; bottom: -30px;
  width: 31%;
  overflow: hidden;
  border: 6px solid var(--paper);
  background: var(--band);
}
.plate-inset img { width: 100%; height: auto; aspect-ratio: 1; object-fit: cover; display: block; }

.plate-note {
  right: 0; bottom: -34px;
  width: 46%;
  display: flex; align-items: center; gap: 12px;
  padding: 14px 16px;
}
.plate-note i { color: var(--accent-ink); font-size: 22px; flex: none; }
.plate-note .val { display: block; font-size: .9375rem; font-weight: 500; line-height: 1.2; }
.plate-note .lbl { display: block; font-size: .75rem; color: var(--ink-3); margin-top: 3px; }

@media (max-width: 940px) {
  .plate { width: 82%; margin-left: 18%; }
  .plate-tag { width: 38%; padding: 14px; }
  .plate-badge { width: 52px; height: 52px; font-size: 23px; top: -20px; }
  .plate-note { width: 54%; bottom: -28px; }
  .plate-inset { width: 34%; bottom: -26px; }
}
/* Below this the cards would cover more of the photo than they reveal, so
   the group falls back to plate + one inset and the facts live in the list
   beside it, which says the same thing in words. */
@media (max-width: 620px) {
  .plate { width: 100%; margin-left: 0; }
  /* the diamond's corner would be cut flat by the viewport edge here, which
     looks worse than not having it */
  .plate-tag, .plate-note, .plate-dots, .plate-mass { display: none; }
  .plate-badge { right: 6%; top: -18px; width: 48px; height: 48px; font-size: 21px; }
  .plate-inset { left: auto; right: 0; bottom: -20px; width: 40%; border-width: 5px; }
}

/* ── app frame ── */
.frame {
  position: relative;
  z-index: 2;
  background: var(--paper);
  border: 1px solid var(--rule);
  box-shadow: 0 2px 4px rgba(3,26,51,.04), 0 34px 80px -34px rgba(3,26,51,.34);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .frame { box-shadow: 0 34px 80px -34px rgba(0,0,0,.8); }
}
:root[data-theme='dark'] .frame { box-shadow: 0 34px 80px -34px rgba(0,0,0,.8); }

.frame-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 10px 14px;
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
}
.frame-bar .dots { display: flex; gap: 5px; }
.frame-bar .dots i { width: 8px; height: 8px; border-radius: 50%; background: var(--rule); display: block; }
.frame-bar .addr {
  flex: 1; text-align: center;
  font-size: .6875rem; color: var(--ink-3);
  letter-spacing: .02em;
}

.frame .panel-bar { padding: 13px 14px; }
.frame .panel-bar h3 { font-size: .875rem; }
.frame .panel-foot { padding: 12px 14px; font-size: .75rem; }
.frame .panel-foot b { font-size: .9375rem; }
.frame .panel { border: 0; box-shadow: none; background: transparent; }

/* ── floating metric cards ── */
.fcard {
  position: absolute;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 11px;
  padding: 13px 15px;
  background: var(--paper);
  border: 1px solid var(--rule);
  box-shadow: 0 2px 4px rgba(3,26,51,.05), 0 18px 40px -18px rgba(3,26,51,.30);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .fcard { box-shadow: 0 18px 40px -18px rgba(0,0,0,.75); }
}
:root[data-theme='dark'] .fcard { box-shadow: 0 18px 40px -18px rgba(0,0,0,.75); }

.fcard .ico {
  width: 38px; height: 38px;
  display: grid; place-items: center;
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-size: 19px;
  flex: none;
}
.fcard .lbl { font-size: .6875rem; color: var(--ink-3); display: block; margin-bottom: 1px; }
.fcard .val {
  font-family: 'Francy', 'Outfit', sans-serif;
  font-size: 1.125rem; line-height: 1.1;
  font-variant-numeric: tabular-nums;
  display: block;
}
.fcard .delta { font-size: .6875rem; color: var(--accent-ink); font-weight: 500; white-space: nowrap; }

/* Both sit over table rows, never over the panel's own title. */
.fc-pay  { left: -34px;  top: 40%; }
/* top-right, over the empty half of the frame bar, so it covers no data */
.fc-comp { right: -24px; top: -24px; min-width: 186px; flex-direction: column; align-items: stretch; gap: 8px; }
.fc-comp .bar { height: 4px; background: var(--rule); overflow: hidden; }
/* scaleX, not width: animating width relayouts the card on every frame */
.fc-comp .bar span {
  display: block; height: 100%; width: 100%;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 1100ms var(--ease-out) 900ms;
}
.js .hero-media.shown .fc-comp .bar span { transform: scaleX(1); }
@media (prefers-reduced-motion: reduce) { .fc-comp .bar span { transform: none; transition: none; } }

@media (max-width: 1100px) { .fc-pay { left: -14px; } .fc-comp { right: -12px; } }
/* On a narrow mock two overlapping cards just bury the rows they are meant
   to dress up, so the panel stands alone on phones. */
@media (max-width: 620px) {
  .fcard { display: none; }
}


/* ── hero split ── */
.hero-grid {
  display: grid;
  grid-template-columns: 6fr 6fr;      /* right column starts on a grid line */
  gap: 0;
  align-items: center;
  padding-block: clamp(48px, 7vh, 96px);
}
.hero-grid > .hero-copy { padding-right: clamp(28px, 4.5vw, 72px); }
@media (max-width: 1000px) {
  .hero-grid { grid-template-columns: 1fr; gap: 64px; padding-block: 44px 60px; }
  .hero-grid > .hero-copy { padding-right: 0; }   /* column padding must not survive the stack */
}
.hero-media { position: relative; }
/* One shoulder, not four points. Bottom-right is the only frame corner
   without a floating card on it. */
.hero-media .blob { width: 60%; aspect-ratio: 1; height: auto; right: -7%; bottom: -11%; left: auto; top: auto; }

@media (max-width: 620px) {
  .hero-media .blob { width: 58%; right: -6%; bottom: -8%; left: auto; top: auto; }
  /* base rule anchors this card from the top; the mobile rule anchors it
     from the bottom, so the top value has to be released explicitly */
  .fc-comp { top: auto; }
}

/* ═══════════════════════════════════════════════════════════════
   SERVICES
   Six engagement models. One card inverts to solid accent, the
   Techwind device, marking the flagship rather than decorating.
   ═══════════════════════════════════════════════════════════════ */

.svcs { display: grid; grid-template-columns: repeat(3, 1fr); gap: clamp(14px, 1.6vw, 20px); }
@media (max-width: 900px) { .svcs { grid-template-columns: 1fr 1fr; } }
@media (max-width: 560px) { .svcs { grid-template-columns: 1fr; } }

.svc {
  position: relative;
  padding: clamp(22px, 2.4vw, 30px);
  border: 1px solid var(--rule);
  background: var(--paper);
  transition: border-color 240ms var(--ease-out), box-shadow 240ms var(--ease-out);
}
.svc .ico2 {
  width: 42px; height: 42px;
  display: grid; place-items: center;
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-size: 21px;
  margin-bottom: 18px;
}
.svc h3 { font-size: 1.0625rem; margin-bottom: 9px; }
.svc p { color: var(--ink-2); font-size: .875rem; }
@media (hover: hover) and (pointer: fine) {
  .svc:hover { border-color: var(--rule-firm); box-shadow: 0 16px 40px -20px rgba(3,26,51,.24); }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .svc:hover { box-shadow: 0 16px 40px -20px rgba(0,0,0,.7); }
}
:root[data-theme='dark'] .svc:hover { box-shadow: 0 16px 40px -20px rgba(0,0,0,.7); }

/* the flagship */
.svc-on { background: var(--accent); border-color: var(--accent); }
.svc-on .ico2 { background: rgba(3,26,51,.14); color: var(--on-accent); }
.svc-on h3 { color: var(--on-accent); }
.svc-on p { color: rgba(3,26,51,.9); }        /* .78 composited to 4.25:1 on teal */
.svc-on .flag {
  position: absolute; top: 14px; right: 14px;
  font-size: .625rem; font-weight: 600; letter-spacing: .1em;
  text-transform: uppercase;
  color: rgba(3,26,51,.88);   /* .62 composited to 3.1:1 */
}

/* ═══════════════════════════════════════════════════════════════
   PROBLEM CARDS
   2x2 with the right column dropped, so the eye zigzags instead of
   scanning four identical rows. Numeral is the watermark here; the
   answer section uses an icon watermark, so the two do not twin.
   ═══════════════════════════════════════════════════════════════ */

.probs {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(16px, 1.8vw, 24px);
  /* without this the row stretches to the offset card's outer height and
     the shorter card gains a block of dead space */
  align-items: start;
}
/* margin, not transform: .rise.shown resets transform and would cancel it */
.probs > *:nth-child(2n) { margin-top: clamp(24px, 4vw, 56px); }
@media (max-width: 820px) {
  .probs { grid-template-columns: 1fr; }
  .probs > *:nth-child(2n) { margin-top: 0; }
}

.prob {
  position: relative;
  overflow: hidden;
  padding: clamp(24px, 2.6vw, 32px);
  border: 1px solid var(--rule);
  background: var(--paper);
  transition: border-color 260ms var(--ease-out), box-shadow 260ms var(--ease-out);
}
.prob::before {
  content: '';
  position: absolute;
  left: 0; top: 0;
  width: 3px; height: 100%;
  background: var(--accent);
  transform: scaleY(0);
  transform-origin: top center;
  transition: transform 340ms var(--ease-out);
}
@media (hover: hover) and (pointer: fine) {
  .prob:hover { border-color: var(--rule-firm); box-shadow: 0 18px 44px -22px rgba(3,26,51,.28); }
  .prob:hover::before { transform: scaleY(1); }
  .prob:hover .prob-n { opacity: .13; }
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .prob:hover { box-shadow: 0 18px 44px -22px rgba(0,0,0,.7); }
}
:root[data-theme='dark'] .prob:hover { box-shadow: 0 18px 44px -22px rgba(0,0,0,.7); }

.prob-n {
  position: absolute;
  right: 14px; top: -2px;
  font-family: 'Francy', 'Outfit', sans-serif;
  font-size: clamp(4rem, 3rem + 3vw, 6rem);
  line-height: 1;
  color: var(--ink);
  opacity: .055;
  font-variant-numeric: tabular-nums;
  pointer-events: none;
  transition: opacity 300ms var(--ease-out);
}
.prob .chip { margin-bottom: 18px; }
.prob h3 { font-size: clamp(1.0625rem, 1rem + .35vw, 1.25rem); margin-bottom: 10px; max-width: 24ch; position: relative; }
.prob p { color: var(--ink-2); font-size: .9375rem; max-width: 46ch; position: relative; }

/* ═══════════════════════════════════════════════════════════════
   REQUEST CARD
   Navy panel carrying the offer, form on paper beside it. Inputs get a
   leading icon, the one Techwind form device worth borrowing.
   ═══════════════════════════════════════════════════════════════ */

.cta-card {
  display: grid;
  grid-template-columns: 5fr 7fr;      /* seam lands on a grid line */
  border: 1px solid var(--rule);
  background: var(--paper);
  box-shadow: 0 2px 4px rgba(3,26,51,.04), 0 34px 80px -36px rgba(3,26,51,.30);
  overflow: hidden;
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .cta-card { box-shadow: 0 34px 80px -36px rgba(0,0,0,.75); }
}
:root[data-theme='dark'] .cta-card { box-shadow: 0 34px 80px -36px rgba(0,0,0,.75); }
@media (max-width: 880px) { .cta-card { grid-template-columns: 1fr; } }

.cta-side {
  position: relative;
  overflow: hidden;
  background: var(--band);
  color: var(--band-ink);
  padding: clamp(28px, 3.4vw, 42px);
  display: flex;
  flex-direction: column;
}
.cta-side .wm {
  position: absolute;
  right: -24%; bottom: -22%;
  width: 66%;
  fill: #FFFFFF;
  opacity: .035;
  pointer-events: none;
}
.cta-side > * { position: relative; z-index: 1; }
.cta-kicker {
  display: block;
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 14px;
}
.cta-side h2 {
  font-family: 'Francy', 'Outfit', sans-serif;
  font-size: clamp(1.375rem, 1.1rem + 1vw, 1.75rem);
  line-height: 1.18;
  letter-spacing: -.02em;
  margin-bottom: 12px;
}
.cta-side > p { color: var(--band-ink-2); font-size: .9375rem; margin-bottom: 26px; }

.cta-side .ticks { margin: 0; gap: 14px; }
.cta-side .ticks li { color: var(--band-ink-2); font-size: .875rem; }
.cta-side .ticks i { color: var(--accent); }

.cta-foot {
  margin-top: auto;
  padding-top: 26px;
  border-top: 1px solid var(--band-rule);
  font-size: .8125rem;
  color: var(--band-ink-2);
}
.cta-foot a { color: var(--band-ink); text-decoration: none; }
@media (hover: hover) and (pointer: fine) { .cta-foot a:hover { color: var(--accent); } }
@media (max-width: 880px) { .cta-foot { margin-top: 26px; } }

.cta-body { padding: clamp(28px, 3.4vw, 42px); }

/* boxed, icon-led inputs, scoped to this card so the document-style
   underline fields elsewhere are untouched */
.ifield { position: relative; }
.ifield > i {
  position: absolute;
  left: 13px; top: 50%;
  transform: translateY(-50%);
  color: var(--ink-3);
  font-size: 1.0625rem;
  pointer-events: none;
  transition: color 180ms var(--ease-out);
}
.cta-body .input {
  border: 1px solid var(--rule);
  padding: 12px 13px 12px 40px;
  /* background-color, not the `background` shorthand: the shorthand resets
     background-image and background-position, which silently deleted the
     custom arrow that select.input draws. */
  background-color: var(--paper);
}
/* room for the arrow on top of the room for the leading icon */
.cta-body select.input { padding-right: 30px; }
.cta-body .input:focus {
  border-color: var(--accent);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 20%, transparent);
}
.ifield:focus-within > i { color: var(--accent-ink); }
.cta-body .field.invalid .input { border-color: var(--danger); box-shadow: none; }
/* 92px was sized for a bare "+20". The select now carries a country name
   after the code, so the column grows with the form and the label survives
   instead of being clipped at the second character. */
.cta-body .tel { grid-template-columns: clamp(106px, 32%, 132px) minmax(0, 1fr); }
/* select only. Resetting this for every .tel input pushed the phone
   placeholder under its own leading icon. */
.cta-body .tel select.input { padding-left: 13px; }
.cta-body .ifield select.input { padding-left: 40px; }

/* ═══════════════════════════════════════════════════════════════
   SPLIT FEATURE SECTION
   Frame left with a rotated square behind it, ghost-icon cards right.
   The square is sharp rather than a blob: the logo is squares, and an
   organic teardrop would fight the rest of the page.
   ═══════════════════════════════════════════════════════════════ */

.split { position: relative; overflow-x: clip; }
.split-grid {
  display: grid;
  grid-template-columns: 6fr 6fr;
  gap: 0;
  align-items: center;
}
.split-grid > .split-media { padding-right: clamp(40px, 6vw, 96px); }
@media (max-width: 940px) {
  .split-grid { grid-template-columns: 1fr; gap: 48px; }
  .split-grid > .split-media { padding-right: 0; }
}

/* Sized to sit behind the frame's top-left shoulder. At 74% the four
   corners poked out evenly and read as four unrelated triangles. */
.diamond {
  position: absolute;
  z-index: 0;
  width: 52%;
  aspect-ratio: 1;
  left: -9%; top: -14%;
  transform: rotate(45deg);
  background: linear-gradient(135deg, rgba(0,168,177,.20), rgba(0,168,177,.04));
  pointer-events: none;
}
@media (max-width: 940px) { .diamond { width: 46%; left: -6%; top: -9%; } }

.split-media { position: relative; }

/* ── ghost-icon cards ── */
.gcards { display: grid; gap: 14px; }
.gcard {
  position: relative;
  overflow: hidden;
  padding: 28px 32px 28px 96px;
  border: 1px solid var(--rule);
  background: var(--paper);
  transition: border-color 220ms var(--ease-out), transform 220ms var(--ease-out);
}
.gcard .ghost {
  position: absolute;
  left: 6px; top: 50%;
  transform: translateY(-50%);
  font-size: 5.25rem;
  line-height: 1;
  color: var(--accent);
  opacity: .13;
  pointer-events: none;
}
.gcard h3 { font-size: 1.125rem; margin-bottom: 8px; }
.gcard p { color: var(--ink-2); font-size: .9375rem; max-width: 44ch; }
@media (hover: hover) and (pointer: fine) {
  .gcard:hover { border-color: var(--accent); transform: translateX(4px); }
  .gcard:hover .ghost { opacity: .2; }
}
@media (max-width: 520px) {
  .gcard { padding: 20px 20px 20px 76px; }
  .gcard .ghost { font-size: 4rem; left: 2px; }
}

/* ── circled tick list ── */
.ticks { display: grid; gap: 12px; margin-top: 22px; }
.ticks li { display: flex; align-items: flex-start; gap: 11px; font-size: .9375rem; color: var(--ink-2); }
.ticks i {
  color: var(--accent-ink);
  font-size: 1.25rem;
  flex: none;
  margin-top: 1px;
}

/* ═══════════════════════════════════════════════════════════════
   FLANKED FEATURES
   Phone centre, three features either side, icons facing inward.
   ═══════════════════════════════════════════════════════════════ */

.flank {
  display: grid;
  grid-template-columns: minmax(0, 1fr) clamp(360px, 34vw, 470px) minmax(0, 1fr);
  gap: clamp(20px, 2.4vw, 40px);
  align-items: center;
}
@media (max-width: 1000px) {
  .flank { grid-template-columns: 1fr 1fr; gap: 32px; }
  .flank .laptop-col { grid-column: 1 / -1; grid-row: 1; justify-self: center; }
}
@media (max-width: 620px) { .flank { grid-template-columns: 1fr; } }

.fset { display: grid; gap: clamp(28px, 4vw, 52px); }
.fitem { display: grid; grid-template-columns: 1fr 52px; gap: 16px; align-items: start; }
.fset-l .fitem { text-align: right; }
.fset-r .fitem { grid-template-columns: 52px 1fr; text-align: left; }
.fset-r .fitem .ficon { order: -1; }
@media (max-width: 620px) {
  .fset-l .fitem { text-align: left; grid-template-columns: 52px 1fr; }
  .fset-l .fitem .ficon { order: -1; }
}
.ficon {
  width: 52px; height: 52px;
  display: grid; place-items: center;   /* square, like every other icon tile */
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-size: 23px;
  flex: none;
}
.fitem h3 { font-size: 1.0625rem; margin-bottom: 7px; }
.fitem p { color: var(--ink-2); font-size: .875rem; }

/* real product screenshots sit flush inside the frame chrome */
.shot { width: 100%; height: auto; display: block; }

/* ── laptop ── */
.laptop-col { position: relative; }
.laptop-col .blob { width: 74%; aspect-ratio: 1; height: auto; left: 13%; top: 18%; }
.laptop { position: relative; z-index: 2; width: 88%; margin-inline: auto; }
.laptop-screen {
  border: 10px solid var(--ink);
  border-bottom: 0;
  border-radius: 12px 12px 0 0;
  background: var(--paper);
  overflow: hidden;
}
/* The screen is inset so the base's overhang still fits the column. Clipping
   .laptop-col instead (the earlier fix) cut the overhang off and the whole
   thing read as a tablet. */
.flank { overflow-x: clip; }
.laptop-base {
  height: 16px;
  width: 113%;
  margin-left: -6.5%;
  background: var(--ink);
  border-radius: 0 0 13px 13px;
  position: relative;
}
.laptop-base::after {
  content: '';
  position: absolute; left: 50%; top: 0;
  transform: translateX(-50%);
  width: 92px; height: 5px;
  background: rgba(255,255,255,.22);
  border-radius: 0 0 4px 4px;
}
.lt-bar {
  display: flex; align-items: center; gap: 10px;
  padding: 9px 12px;
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
}
.lt-bar .dots { display: flex; gap: 5px; }
.lt-bar .dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--rule); display: block; }
.lt-bar .addr { flex: 1; text-align: center; font-size: .625rem; color: var(--ink-3); }


/* ── FAQ, two columns: heading and contact rail on the left ── */
.faq-grid {
  display: grid;
  grid-template-columns: 4fr 8fr;
  gap: 0;
  align-items: start;
}
.faq-grid > .faq-aside { padding-right: clamp(28px, 4vw, 72px); }
@media (max-width: 900px) {
  .faq-grid { grid-template-columns: 1fr; }
  .faq-grid > .faq-aside { padding-right: 0; margin-bottom: 36px; }
}
.faq-aside { position: sticky; top: calc(var(--nav-h) + 32px); }
@media (max-width: 900px) { .faq-aside { position: static; } }
.faq-help {
  margin-top: 28px;
  padding: 20px;
  border: 1px solid var(--rule);
  background: var(--paper);
}
.faq-help p { font-size: .875rem; color: var(--ink-2); margin-bottom: 12px; }
.faq-help a {
  display: inline-flex; align-items: center; gap: 7px;
  font-size: .875rem; font-weight: 500;
  color: var(--accent-ink); text-decoration: none;
}
@media (hover: hover) and (pointer: fine) { .faq-help a:hover { text-decoration: underline; text-underline-offset: 3px; } }

/* ── phone ── */
.phone-col { position: relative; }
.phone-col .blob { width: 96%; aspect-ratio: 1; height: auto; left: 2%; top: 14%; }
.phone {
  position: relative;
  z-index: 2;
  width: 268px;
  border: 9px solid var(--ink);
  border-radius: 38px;
  background: var(--paper);
  overflow: hidden;
  box-shadow: 0 30px 70px -28px rgba(3,26,51,.42);
}
@media (max-width: 340px) { .phone { width: 240px; } }
.phone-notch {
  height: 24px;
  background: var(--ink);
  display: grid; place-items: center;
}
.phone-notch span { width: 62px; height: 5px; border-radius: 99px; background: rgba(255,255,255,.28); display: block; }

.pscreen { padding: 16px 14px 14px; }
.pbar { display: flex; align-items: center; justify-content: space-between; margin-bottom: 16px; }
.pbar .nm2 { font-size: .75rem; font-weight: 600; }
.pbar .who { width: 26px; height: 26px; font-size: .625rem; }

.payslip { border: 1px solid var(--rule); padding: 14px; margin-bottom: 12px; }
.payslip .lbl2 { font-size: .625rem; color: var(--ink-3); letter-spacing: .06em; text-transform: uppercase; display: block; margin-bottom: 5px; }
.payslip .big {
  font-family: 'Francy', 'Outfit', sans-serif;
  font-size: 1.625rem; line-height: 1;
  font-variant-numeric: tabular-nums;
  display: block; margin-bottom: 12px;
}
.payslip .ln2 { display: flex; justify-content: space-between; font-size: .6875rem; padding: 5px 0; color: var(--ink-2); }
.payslip .ln2 b { color: var(--ink); font-weight: 500; font-variant-numeric: tabular-nums; }
.payslip .ln2.net { border-top: 1px solid var(--rule); margin-top: 5px; padding-top: 8px; }

.pbtn {
  display: flex; align-items: center; justify-content: center; gap: 6px;
  background: var(--accent); color: var(--on-accent);
  font-size: .6875rem; font-weight: 600;
  padding: 10px; margin-bottom: 12px;
}
.ptabs { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--rule); padding-top: 10px; }
.ptabs i { text-align: center; font-size: 17px; color: var(--ink-3); }
.ptabs i.on { color: var(--accent-ink); }

/* ═══════════════════════════════════════════════════════════════
   ACTIVE LAYER
   Product fragments, sample data and interactive bits. Every number
   in here is placeholder: search PLACEHOLDER to find them all.
   ═══════════════════════════════════════════════════════════════ */

/* ── pill badge above a section heading ── */
.badge {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px 13px 5px 10px;
  border: 1px solid var(--rule);
  border-radius: var(--r-pill, 999px);
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-size: .6875rem;
  font-weight: 600;
  letter-spacing: .1em;
  text-transform: uppercase;
  margin-bottom: 20px;
}
.badge i { font-size: 1rem; }

/* ── two-tone heading: second half drops back ── */
.dim { color: var(--ink-3); }

/* ── teal glow wash ── */
.glow {
  position: absolute;
  pointer-events: none;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(0,168,177,.20) 0%, rgba(0,168,177,0) 70%);
  filter: blur(10px);
}

/* ── country code badge. Text codes, not flags: the Syrian flag changed
      in 2025 and a stale or wrong one is worse than none. ── */
.cc {
  display: inline-grid;
  place-items: center;
  width: 26px; height: 18px;
  border: 1px solid var(--rule);
  font-size: .625rem;
  font-weight: 600;
  letter-spacing: .04em;
  color: var(--ink-2);
  flex: none;
}

/* ── initials tile ── */
.who {
  display: inline-grid;
  place-items: center;
  width: 32px; height: 32px;
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-size: .75rem;
  font-weight: 600;
  flex: none;
}
.who i { font-size: 1.0625rem; }   /* record rows use an icon, not initials */

/* ── status pill ── */
.tag {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 9px;
  font-size: .6875rem;
  font-weight: 500;
  border: 1px solid var(--rule);
  color: var(--ink-3);
  white-space: nowrap;
  transition: background-color 320ms var(--ease-out), color 320ms var(--ease-out),
              border-color 320ms var(--ease-out);
}
.tag i { font-size: .8125rem; }
.tag.done { background: var(--accent); border-color: var(--accent); color: var(--on-accent); }

/* ═══ PAYROLL PANEL ═══════════════════════════════════════════ */

.panel-wrap { position: relative; margin-top: calc(clamp(40px, 5vw, 68px) * -1); }
.panel-wrap .glow { width: 62%; height: 300px; left: 12%; top: -60px; }

.panel {
  position: relative;
  background: var(--paper);
  border: 1px solid var(--rule);
  box-shadow: 0 1px 2px rgba(3,26,51,.04), 0 30px 70px -30px rgba(3,26,51,.28);
}
:root[data-theme='dark'] .panel,
.panel { }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) .panel { box-shadow: 0 30px 70px -30px rgba(0,0,0,.7); }
}
:root[data-theme='dark'] .panel { box-shadow: 0 30px 70px -30px rgba(0,0,0,.7); }

.panel-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 16px 20px;
  border-bottom: 1px solid var(--rule);
  background: var(--paper-2);
}
.panel-bar h3 { font-size: .9375rem; font-weight: 600; }
.panel-bar .when { font-size: .75rem; color: var(--ink-3); }
.panel-act { display: flex; align-items: center; gap: 12px; }


.panel-foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 20px;
  border-top: 1px solid var(--rule);
  background: var(--paper-2);
  font-size: .8125rem;
  color: var(--ink-3);
}
.panel-foot b { color: var(--ink); font-weight: 600; font-variant-numeric: tabular-nums; font-size: 1rem; }

/* rows arrive in sequence, then the run completes */

/* ═══ MINI UI FRAGMENTS ═══════════════════════════════════════ */

.frag { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 22px; }
.mini {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 7px 11px;
  border: 1px solid var(--rule);
  background: var(--paper);
  font-size: .75rem;
  color: var(--ink-2);
  transition: border-color 200ms var(--ease-out), transform 200ms var(--ease-out);
}
.mini i { color: var(--accent-ink); font-size: .9375rem; }
.mini b { color: var(--ink); font-weight: 500; font-variant-numeric: tabular-nums; }
@media (hover: hover) and (pointer: fine) {
  .mini:hover { border-color: var(--accent); transform: translateY(-2px); }
}

/* ── icon chip, used on the problem cards ── */
.chip {
  width: 34px; height: 34px;
  display: grid; place-items: center;
  background: var(--accent-wash);
  color: var(--accent-ink);
  font-size: 17px;
  flex: none;
  margin-top: 4px;
}

/* Every rule in this block is gated on .js. Without the head script the
   page is simply visible, which is the correct failure mode. */

.ln > span { display: block; }

.js .rise {
  opacity: 0;
  transform: translateY(12px);
  transition: opacity 520ms var(--ease-out), transform 520ms var(--ease-out);
  transition-delay: var(--wait, 0ms);
}
.js .rise.shown { opacity: 1; transform: none; }

/* lines: display type climbs out of its own mask */
.js .lines .ln > span {
  transform: translateY(112%);
  transition: transform 880ms var(--ease-out);
  transition-delay: var(--wait, 0ms);
}
.js .lines.shown .ln > span { transform: none; }

.js .lines .stop { transform: scale(0); transition: transform 420ms var(--ease-out) 820ms; }
.js .lines.shown .stop { transform: none; }

/* draw: a rule that extends from its left edge */
.js .draw-in {
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform 900ms var(--ease-out);
  transition-delay: var(--wait, 0ms);
}
.js .draw-in.shown { transform: none; }

/* clip: an image wiped in from the bottom edge. Nothing scales in from
   nothing, and nothing fades in from grey either. */
.js .clip-in {
  clip-path: inset(0 0 100% 0);
  transition: clip-path 1000ms var(--ease-out);
  transition-delay: var(--wait, 0ms);
}
.js .clip-in.shown { clip-path: inset(0 0 0 0); }

.js .plate.clip-in img {
  transform: scale(1.07);
  transition: transform 1500ms var(--ease-out);
}
.js .plate.clip-in.shown img { transform: none; }

@media (prefers-reduced-motion: reduce) {
  .js .rise, .js .draw-in, .js .clip-in {
    opacity: 1; transform: none; clip-path: none; transition: none;
  }
  .js .lines .ln > span,
  .js .lines .stop,
  .js .plate.clip-in img { transform: none; transition: none; }
  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
  }
  .qa-body { transition: none; }
}


/* ═══ TICKER BAR ══════════════════════════════════════════════════
   A slim strip above the masthead. It exists for two reasons: it
   carries the proof points that were competing for room in the hero,
   and it gives the language switch somewhere to live. In the nav the
   switch had to sit beside a 52px tall button and never matched it;
   here it is a link among links and the mismatch disappears.

   The masthead is sticky at top:0, so this scrolls away on its own
   and never fights the nav for the viewport edge.
   ═════════════════════════════════════════════════════════════════ */
.ticker {
  position: relative;
  z-index: 41;
  background: var(--band);
  color: var(--band-ink-2);
  border-bottom: 1px solid var(--band-rule);
  font-size: .8125rem;
  line-height: 1;
  display: flex;
  align-items: stretch;
  overflow: hidden;
}
.ticker-view {
  flex: 1;
  min-width: 0;          /* without this the flex item refuses to shrink
                            and the whole bar overflows the viewport */
  overflow: hidden;
  display: flex;
  align-items: center;
  /* fades the text out at both ends instead of cutting it dead */
  mask-image: linear-gradient(to right, transparent 0, #000 40px,
              #000 calc(100% - 40px), transparent 100%);
}
.ticker-run {
  display: flex;
  flex: none;
  align-items: center;
  padding-block: 10px;
  /* two identical runs sit side by side and the pair slides exactly
     half its own width, so the loop has no seam */
  animation: ticker-slide 46s linear infinite;
}
.ticker-run > span {
  display: flex;
  align-items: center;
  gap: 16px;
  padding-inline: 16px;
  white-space: nowrap;
}
.ticker-run > span::after {
  content: '';
  width: 4px; height: 4px;
  background: var(--accent);
  flex: none;
}
@keyframes ticker-slide {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}
/* the strip is decoration around a fact; nobody should have to wait
   for it, and nobody should be made queasy by it */
@media (prefers-reduced-motion: reduce) {
  .ticker-run { animation: none; }
}
@media (hover: hover) and (pointer: fine) {
  .ticker:hover .ticker-run { animation-play-state: paused; }
}

@media (max-width: 560px) {
  .ticker { font-size: .75rem; }
  .ticker-run > span { padding-inline: 12px; }
}
