/* ============================================================
   Shapes Infinity — "2050" design system (all hub pages)
   Same layout skeleton as the playground system; the skin is
   deep-space glass: void ground with gradient mesh, luminous
   panels, hue glows, glossy pills. Every page loads this file;
   page-specific layout goes in a small per-page stylesheet.
   ============================================================ */

:root {
  /* semantic trio (inverted from the light skin — page css keys off these) */
  --cream: #07070d;                    /* page ground: the void */
  --ink: #f2f0fa;                      /* "ink" is light now */
  --paper: #14131f;                    /* panel base */

  --muted: #a9a4b8;
  --ink-dim: var(--muted);             /* alias — secondary text on feature pages */
  --line: rgba(242, 240, 250, 0.14);   /* soft hairlines instead of hard borders */
  --glass: rgba(255, 255, 255, 0.045);

  /* luminous hues */
  --orange: #ff6b00;                   /* brand lead */
  --purple: #a866ff;
  --purple-deep: #241a38;
  --red: #ff5544;
  --blue: #3d8bff;
  --amber: #ffb21e;
  --green: #2ad17e;
  --cyan: #00c8ff;
  --holo: linear-gradient(135deg, #a866ff, #00c8ff);
  --ember: linear-gradient(135deg, #ff6b00, #ffb21e);

  --font-display: "General Sans", "Space Grotesk", "Segoe UI", sans-serif;
  --font-body: "Inter", "Segoe UI", system-ui, sans-serif;
  --font-ar: "Noto Kufi Arabic", "Segoe UI", sans-serif;

  --radius: 26px;
  --radius-sm: 16px;
  --pill: 999px;
  --rail-w: 128px;
  --gap: 20px;
  --pad: clamp(18px, 2.4vw, 34px);
  --section-gap: clamp(56px, 8vw, 110px);

  /* motion tokens — one rhythm for the whole site */
  --ease-fluid: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-exit: cubic-bezier(0.55, 0, 0.55, 0.2);
  --dur-tap: 160ms;
  --dur-ui: 300ms;
  --dur-scene: 560ms;
}
/* cross-page transitions where the browser supports them */
@view-transition { navigation: auto; }
::view-transition-old(root) { animation-duration: 200ms; }
::view-transition-new(root) { animation-duration: 320ms; }
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
html { scroll-behavior: smooth; scroll-padding-top: 90px; }
body {
  background-color: var(--cream);
  background-image:
    radial-gradient(900px 600px at 85% -5%, rgba(168, 102, 255, 0.14), transparent 60%),
    radial-gradient(800px 600px at -10% 20%, rgba(255, 107, 0, 0.10), transparent 55%),
    radial-gradient(700px 500px at 60% 110%, rgba(0, 200, 255, 0.08), transparent 60%);
  background-attachment: fixed;
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 1rem;
  line-height: 1.55;
  -webkit-font-smoothing: antialiased;
  overflow-x: clip;
}
img { display: block; max-width: 100%; height: auto; }
a { color: inherit; }
ul[role="list"] { list-style: none; }
::selection { background: var(--orange); color: #07070d; }
:focus-visible { outline: 2px solid var(--cyan); outline-offset: 3px; border-radius: 8px; box-shadow: 0 0 12px rgba(0, 200, 255, 0.5); }
h1, h2, h3, .display {
  font-family: var(--font-display);
  font-weight: 700;
  line-height: 1.04;
  letter-spacing: -0.02em;
  text-wrap: balance;
}
html[lang="ar"] h1, html[lang="ar"] h2, html[lang="ar"] h3 {
  font-family: var(--font-ar); font-weight: 700; line-height: 1.25; letter-spacing: 0;
}
.skip-link {
  position: absolute; inset-inline-start: 16px; top: -100px; z-index: 200;
  background: var(--ink); color: var(--cream);
  padding: 10px 18px; border-radius: var(--pill);
  font-weight: 700; font-size: 0.875rem; text-decoration: none;
}
.skip-link:focus { top: 14px; }
/* shared glass recipe */
.chip, .lang-switch, .block-card, .hero-copy-card, .banner,
.contact-value, .faq details, .pill, .hero-pill, .gallery-pill,
.marquee, .footer-pills a {
  background:
    linear-gradient(var(--glass), var(--glass)) padding-box,
    linear-gradient(160deg, rgba(242, 240, 250, 0.28), rgba(242, 240, 250, 0.06) 45%, rgba(242, 240, 250, 0.16)) border-box;
  border: 1px solid transparent;
}
/* ============================================================
   chip rail — glass chips with hue glow (top bar on small screens)
   ============================================================ */
.brand-mark {
  position: fixed; top: 12px; inset-inline-start: 12px; z-index: 90;
  display: flex; align-items: center;
  text-decoration: none; line-height: 0;
  /* glass scrim: keeps the white lockup legible over the light content canvas */
  background: rgba(7, 7, 13, 0.72);
  padding: 10px 16px; border-radius: var(--pill);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  transition: box-shadow var(--dur-ui) var(--ease-fluid);
}
/* height drives the lockup; width follows the 2.848:1 artwork ratio.
   The nav uses logo-nav.webp — the same lockup with the "we are in present"
   tagline lifted. At this size that line renders about five pixels tall and
   turns to grey mush; the full lockup is kept for the loader, the footer
   wordmark and the console gate, where it is large enough to read. */
.brand-mark img { display: block; height: 34px; width: auto; }
.brand-mark:hover { box-shadow: 0 0 26px rgba(255, 107, 0, 0.35); }
.brand-mark:focus-visible { outline: 2px solid var(--orange); outline-offset: 3px; }
@media (max-width: 599px) {
  /* 26px lockup + 10px block padding = a 46px touch target, measured */
  .brand-mark { padding: 10px 12px; }
  .brand-mark img { height: 26px; }
}
.chip-rail {
  position: fixed; top: 88px; inset-inline-start: 18px; bottom: 18px; z-index: 90;
  width: calc(var(--rail-w) - 34px); /* rail ends 16px before the page content */
  display: flex; flex-direction: column; gap: 10px;
  overflow-y: auto; scrollbar-width: none;
}
.chip-rail::-webkit-scrollbar { display: none; }
.chip {
  display: flex; flex-direction: column; align-items: flex-start; gap: 6px;
  padding: 12px 14px;
  border-radius: var(--radius-sm);
  text-decoration: none; color: var(--ink);
  font-size: 0.72rem; font-weight: 700; line-height: 1.15;
  flex: 0 1 auto;
  transition: transform 140ms ease, box-shadow 140ms ease;
}
.chip:hover { transform: translateX(4px); }
/* the rail scrolls horizontally on phones, where each chip measured 32px —
   too small to hit reliably while the rail is moving under the thumb */
@media (pointer: coarse) { .chip { min-height: 44px; justify-content: center; } }
html[dir="rtl"] .chip:hover { transform: translateX(-4px); }
.chip .chip-num { font-family: var(--font-display); font-weight: 700; font-size: 0.8rem; opacity: 0.75; }
.chip--orange { box-shadow: inset 3px 0 0 var(--orange), 0 0 18px rgba(255, 107, 0, 0.2); }
.chip--blue   { box-shadow: inset 3px 0 0 var(--blue),   0 0 18px rgba(61, 139, 255, 0.18); }
.chip--red    { box-shadow: inset 3px 0 0 var(--red),    0 0 18px rgba(255, 85, 68, 0.18); }
.chip--amber  { box-shadow: inset 3px 0 0 var(--amber),  0 0 18px rgba(255, 178, 30, 0.16); }
.chip--cream  { box-shadow: inset 3px 0 0 var(--cyan),   0 0 18px rgba(0, 200, 255, 0.16); }
.chip--green  { box-shadow: inset 3px 0 0 var(--green),  0 0 18px rgba(42, 209, 126, 0.16); }
.chip--purple { box-shadow: inset 3px 0 0 var(--purple), 0 0 18px rgba(168, 102, 255, 0.2); }
.chip--black  { box-shadow: inset 3px 0 0 var(--muted); }
html[dir="rtl"] .chip--orange { box-shadow: inset -3px 0 0 var(--orange), 0 0 18px rgba(255, 107, 0, 0.2); }
html[dir="rtl"] .chip--blue   { box-shadow: inset -3px 0 0 var(--blue),   0 0 18px rgba(61, 139, 255, 0.18); }
html[dir="rtl"] .chip--red    { box-shadow: inset -3px 0 0 var(--red),    0 0 18px rgba(255, 85, 68, 0.18); }
html[dir="rtl"] .chip--amber  { box-shadow: inset -3px 0 0 var(--amber),  0 0 18px rgba(255, 178, 30, 0.16); }
html[dir="rtl"] .chip--cream  { box-shadow: inset -3px 0 0 var(--cyan),   0 0 18px rgba(0, 200, 255, 0.16); }
html[dir="rtl"] .chip--green  { box-shadow: inset -3px 0 0 var(--green),  0 0 18px rgba(42, 209, 126, 0.16); }
html[dir="rtl"] .chip--purple { box-shadow: inset -3px 0 0 var(--purple), 0 0 18px rgba(168, 102, 255, 0.2); }
.chip[aria-current="page"] {
  background: linear-gradient(150deg, rgba(255, 107, 0, 0.22), rgba(255, 178, 30, 0.08)) padding-box,
              var(--ember) border-box;
  border: 1px solid transparent;
  box-shadow: 0 0 22px rgba(255, 107, 0, 0.35);
}
.chip--cta {
  margin-top: auto; gap: 6px;
  background: var(--ember);
  color: #07070d; border: 0;
  box-shadow: 0 0 26px rgba(255, 107, 0, 0.4);
}
.chip--cta:hover { box-shadow: 0 0 36px rgba(255, 107, 0, 0.6); }
.lang-switch {
  border-radius: var(--radius-sm);
  color: var(--ink);
  font-family: var(--font-body); font-weight: 700; font-size: 0.78rem;
  padding: 10px; cursor: pointer; text-align: start;
}
.lang-switch:hover { box-shadow: 0 0 18px rgba(0, 200, 255, 0.25); }
.lang-switch .ar-label { font-family: var(--font-ar); }
.chip-socials { flex-direction: column; align-items: center; gap: 12px; padding: 14px 10px; }
.chip-socials a, .chip-socials .social-soon { display: inline-flex; color: var(--muted); }
.chip-socials a:hover { color: var(--orange); filter: drop-shadow(0 0 6px rgba(255, 107, 0, 0.6)); }
.chip-socials .social-soon { opacity: 0.4; }
.chip-socials svg { width: 16px; height: 16px; fill: currentColor; }
.page { margin-inline-start: var(--rail-w); padding: 60px 16px 0 0; } /* clears the fixed brand mark */
html[dir="rtl"] .page { padding: 60px 0 0 16px; }
@media (max-width: 1099px) {
  .brand-mark { position: static; display: inline-block; margin: 16px 0 0; margin-inline-start: 16px; }
  .chip-rail {
    position: sticky; top: 0; inset-inline: 0; bottom: auto; width: auto;
    flex-direction: row; align-items: stretch;
    padding: 10px 16px; margin-top: 8px;
    background: rgba(7, 7, 13, 0.85);
    backdrop-filter: blur(14px);
    -webkit-backdrop-filter: blur(14px);
    overflow-x: auto; overflow-y: hidden;
    /* fade hint: more chips wait past the edge */
    mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent);
    -webkit-mask-image: linear-gradient(to right, #000 calc(100% - 32px), transparent);
  }
  html[dir="rtl"] .chip-rail {
    mask-image: linear-gradient(to left, #000 calc(100% - 32px), transparent);
    -webkit-mask-image: linear-gradient(to left, #000 calc(100% - 32px), transparent);
  }
  .chip { flex: 0 0 auto; flex-direction: row; align-items: center; gap: 8px; padding: 12px 14px; min-height: 44px; }
  .lang-switch { min-height: 44px; padding: 10px 14px; }
  .chip--cta { margin-top: 0; margin-inline-start: auto; }
  .chip-socials { flex-direction: row; }
  .chip-socials a, .chip-socials .social-soon { padding: 8px; }
  .page { margin-inline-start: 0; padding: 12px 16px 0; }
  /* fixed backgrounds repaint on scroll on mobile GPUs — let it scroll */
  body { background-attachment: scroll; }
}
/* ============================================================
   hero — luminous art panel + tinted glass statement card
   ============================================================ */
.v2-hero {
  display: grid; grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  gap: var(--gap);
  min-height: min(820px, calc(100svh - 90px));
}
.hero-card { border-radius: var(--radius); overflow: hidden; position: relative; }
.hero-art-card {
  background: #ffffff;
  box-shadow: 0 0 0 1px var(--line), 0 20px 70px rgba(0, 0, 0, 0.55), 0 0 60px rgba(168, 102, 255, 0.12);
}
.hero-art-card img { width: 100%; height: 100%; object-fit: cover; }
.hero-copy-card {
  padding: var(--pad);
  display: flex; flex-direction: column; align-items: flex-start;
  background:
    linear-gradient(150deg, rgba(255, 107, 0, 0.2), rgba(255, 107, 0, 0.05) 55%, rgba(255, 178, 30, 0.08)) padding-box,
    linear-gradient(160deg, rgba(255, 107, 0, 0.6), rgba(242, 240, 250, 0.08) 50%, rgba(255, 178, 30, 0.35)) border-box;
  border: 1px solid transparent;
  box-shadow: 0 0 60px rgba(255, 107, 0, 0.14);
}
.hero-pill {
  align-self: flex-end;
  border-radius: var(--pill);
  padding: 12px 20px; color: var(--ink);
  font-weight: 700; font-size: 0.82rem; text-decoration: none;
  transition: box-shadow 140ms ease;
}
.hero-pill:hover { box-shadow: 0 0 20px rgba(0, 200, 255, 0.35); }
.hero-copy-card h1 {
  margin-top: auto;
  font-size: clamp(2.1rem, 4.4vw, 4rem);
  max-width: 14ch;
  text-shadow: 0 0 40px rgba(242, 240, 250, 0.25);
}
.hero-copy-card .hero-body {
  margin-top: 20px;
  font-size: 0.98rem; font-weight: 450; line-height: 1.65;
  color: var(--muted);
  max-width: 52ch;
}
.hero-copy-card .hero-body strong { color: var(--ink); }
/* per-page hero tints (same class names as the light skin) */
.hero-copy-card--red {
  background:
    linear-gradient(150deg, rgba(255, 85, 68, 0.2), rgba(255, 85, 68, 0.05) 55%, rgba(255, 107, 0, 0.08)) padding-box,
    linear-gradient(160deg, rgba(255, 85, 68, 0.6), rgba(242, 240, 250, 0.08) 50%, rgba(255, 107, 0, 0.35)) border-box;
  box-shadow: 0 0 60px rgba(255, 85, 68, 0.14);
}
.hero-copy-card--amber {
  background:
    linear-gradient(150deg, rgba(255, 178, 30, 0.18), rgba(255, 178, 30, 0.04) 55%, rgba(255, 107, 0, 0.08)) padding-box,
    linear-gradient(160deg, rgba(255, 178, 30, 0.55), rgba(242, 240, 250, 0.08) 50%, rgba(255, 107, 0, 0.3)) border-box;
  box-shadow: 0 0 60px rgba(255, 178, 30, 0.12);
}
.hero-copy-card--blue {
  background:
    linear-gradient(150deg, rgba(61, 139, 255, 0.2), rgba(61, 139, 255, 0.05) 55%, rgba(0, 200, 255, 0.08)) padding-box,
    linear-gradient(160deg, rgba(61, 139, 255, 0.6), rgba(242, 240, 250, 0.08) 50%, rgba(0, 200, 255, 0.35)) border-box;
  box-shadow: 0 0 60px rgba(61, 139, 255, 0.14);
}
.hero-copy-card--green {
  background:
    linear-gradient(150deg, rgba(42, 209, 126, 0.18), rgba(42, 209, 126, 0.04) 55%, rgba(0, 200, 255, 0.06)) padding-box,
    linear-gradient(160deg, rgba(42, 209, 126, 0.55), rgba(242, 240, 250, 0.08) 50%, rgba(0, 200, 255, 0.3)) border-box;
  box-shadow: 0 0 60px rgba(42, 209, 126, 0.12);
}
.hero-copy-card--purple {
  background:
    linear-gradient(150deg, rgba(168, 102, 255, 0.2), rgba(168, 102, 255, 0.05) 55%, rgba(0, 200, 255, 0.08)) padding-box,
    linear-gradient(160deg, rgba(168, 102, 255, 0.6), rgba(242, 240, 250, 0.08) 50%, rgba(0, 200, 255, 0.35)) border-box;
  box-shadow: 0 0 60px rgba(168, 102, 255, 0.16);
}
@media (max-width: 899px) {
  .v2-hero { grid-template-columns: 1fr; min-height: 0; }
  .hero-art-card { aspect-ratio: 4 / 3; order: 2; }
}
/* generic pill */
.pill {
  display: inline-block;
  border-radius: var(--pill); color: var(--ink);
  padding: 12px 20px;
  font-weight: 700; font-size: 0.82rem; text-decoration: none;
  transition: box-shadow 140ms ease;
}
.pill:hover { box-shadow: 0 0 20px rgba(0, 200, 255, 0.3); }
/* ============================================================
   marquee — glass strip with glowing separators
   ============================================================ */
.marquee {
  position: relative;
  margin-top: var(--gap);
  color: var(--ink);
  border-radius: var(--pill);
  overflow: hidden;
  padding: 11px 0;
  direction: ltr;
}
.marquee-track { display: flex; width: max-content; animation: marquee-scroll 38s linear infinite; }
.marquee:hover .marquee-track,
.marquee:focus-within .marquee-track,
.marquee.is-paused .marquee-track { animation-play-state: paused; }
.marquee-seq { display: flex; align-items: center; flex-shrink: 0; direction: ltr; }
.marquee-seq > span { white-space: nowrap; font-weight: 700; font-size: 0.85rem; }
.marquee .cat { color: var(--amber); }
.marquee .sep {
  width: 8px; height: 8px; border-radius: 2px;
  background: var(--orange);
  box-shadow: 0 0 10px rgba(255, 107, 0, 0.8);
  margin: 0 22px; flex-shrink: 0;
  transform: rotate(45deg);
}
@keyframes marquee-scroll { from { transform: translateX(0); } to { transform: translateX(-50%); } }
/* edge scrims: the track fades out instead of guillotining letters at the pill ends */
.marquee::before, .marquee::after {
  content: ""; position: absolute; top: 0; bottom: 0;
  pointer-events: none; z-index: 1;
}
.marquee::before { left: 0; width: 52px; background: linear-gradient(to right, rgba(7, 7, 13, 0.95), transparent); }
.marquee::after { right: 0; width: 110px; background: linear-gradient(to left, rgba(7, 7, 13, 0.95), transparent); }
.marquee-toggle {
  position: absolute; inset-inline-end: 8px; top: 50%; transform: translateY(-50%);
  z-index: 2;
  background: var(--cream); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--pill);
  font-weight: 700; font-size: 0.7rem;
  padding: 10px 14px; cursor: pointer;
}
.marquee-toggle:hover { border-color: var(--cyan); }
/* ============================================================
   entries head + color-tinted glass masonry
   ============================================================ */
.entries-head { padding: var(--section-gap) 6px 30px; }
.entries-head h2 { font-size: clamp(1.9rem, 3.6vw, 3rem); max-width: 18ch; }
/* the section lead was the same size as the card body copy under it, with a
   longer measure and tighter leading — no tier at all. Matched to the hero's
   own lead: 1.04rem/58ch lands pixel-identical to .mega-sub, and the 1.7
   leading is what actually reads as a step. */
.entries-head .lead {
  margin-top: 14px; max-width: 58ch;
  font-size: 1.04rem; line-height: 1.7;
  font-weight: 450; color: var(--muted);
}
.masonry { display: grid; grid-template-columns: repeat(3, 1fr); gap: var(--gap); align-items: start; }
.masonry-col { display: grid; gap: var(--gap); }
.block-card {
  border-radius: var(--radius); padding: var(--pad);
  transition: transform 160ms ease, box-shadow 160ms ease;
}
.block-card:hover { transform: translateY(-4px); }
.block-card h3 { font-size: clamp(1.3rem, 1.9vw, 1.7rem); margin-bottom: 12px; }
.block-card p { font-weight: 450; font-size: 0.95rem; max-width: 46ch; color: var(--muted); }
.block-card .card-tag {
  display: inline-block; margin-bottom: 26px;
  border: 1px solid var(--line); border-radius: var(--pill);
  padding: 5px 14px; font-weight: 700; font-size: 0.72rem;
  color: var(--ink);
}
.card--purple { box-shadow: inset 0 1px 0 rgba(168,102,255,0.5), 0 0 40px rgba(168,102,255,0.12); }
.card--purple .card-tag { color: var(--purple); border-color: rgba(168,102,255,0.5); }
.card--green { box-shadow: inset 0 1px 0 rgba(42,209,126,0.5), 0 0 40px rgba(42,209,126,0.1); }
.card--green .card-tag { color: var(--green); border-color: rgba(42,209,126,0.5); }
.card--amber { box-shadow: inset 0 1px 0 rgba(255,178,30,0.5), 0 0 40px rgba(255,178,30,0.1); }
.card--amber .card-tag { color: var(--amber); border-color: rgba(255,178,30,0.5); }
.card--blue { box-shadow: inset 0 1px 0 rgba(61,139,255,0.5), 0 0 40px rgba(61,139,255,0.12); }
.card--blue .card-tag { color: var(--blue); border-color: rgba(61,139,255,0.5); }
.card--white { box-shadow: inset 0 1px 0 rgba(242,240,250,0.35); }
.card--orange, .block-card.card--orange { box-shadow: inset 0 1px 0 rgba(255,107,0,0.55), 0 0 40px rgba(255,107,0,0.12); }
.card--orange .card-tag { color: var(--orange); border-color: rgba(255,107,0,0.55); }
.card--blue, .card--purple, .card--green, .card--amber, .card--white, .card--orange { color: var(--ink); }
.card--blue p, .card--purple p, .card--green p, .card--amber p, .card--white p, .card--orange p { color: var(--muted); }
.card--purple img { margin: 8px 0 26px; width: min(100%, 340px); filter: drop-shadow(0 0 18px rgba(168,102,255,0.4)); }
.card--tall { min-height: 520px; display: flex; flex-direction: column; }
.card--tall h3 { margin-top: auto; }
.art-card {
  border-radius: var(--radius); overflow: hidden;
  box-shadow: 0 0 0 1px var(--line), 0 16px 50px rgba(0, 0, 0, 0.5);
}
.art-card img { width: 100%; height: auto; }
/* tablet keeps two columns — one wide column wastes the width */
@media (max-width: 899px) {
  .masonry { grid-template-columns: repeat(2, 1fr); }
  .card--tall { min-height: 0; }
}
@media (max-width: 599px) {
  .masonry { grid-template-columns: 1fr; }
}
/* ============================================================
   gallery — tinted panel + holo tile strip + lightbox
   ============================================================ */
.gallery-panel {
  margin-top: var(--section-gap);
  border-radius: var(--radius);
  padding: var(--pad);
  display: grid; grid-template-columns: minmax(0, 4fr) minmax(0, 8fr);
  gap: var(--gap);
  background:
    linear-gradient(150deg, rgba(255, 107, 0, 0.16), rgba(255, 107, 0, 0.04) 55%, rgba(168, 102, 255, 0.08)) padding-box,
    linear-gradient(160deg, rgba(255, 107, 0, 0.55), rgba(242, 240, 250, 0.08) 50%, rgba(168, 102, 255, 0.35)) border-box;
  border: 1px solid transparent;
  box-shadow: 0 0 60px rgba(255, 107, 0, 0.1);
}
.gallery-intro { display: flex; flex-direction: column; align-items: flex-start; }
.gallery-intro h2 { font-size: clamp(1.8rem, 3vw, 2.6rem); max-width: 12ch; }
.gallery-intro p { margin-top: 14px; font-weight: 450; font-size: 0.95rem; max-width: 40ch; color: var(--muted); }
.gallery-pill {
  margin-top: auto; padding: 9px 18px;
  border-radius: var(--pill);
  font-weight: 700; font-size: 0.82rem; color: var(--ink);
}
.tile-strip {
  display: flex; gap: var(--gap);
  overflow-x: auto; scroll-snap-type: x mandatory; scroll-padding-inline: 4px;
  padding-bottom: 6px;
}
.tile {
  flex: 0 0 clamp(220px, 24vw, 320px);
  scroll-snap-align: start;
  position: relative; overflow: hidden;
  border: 0; border-radius: var(--radius-sm);
  padding: 0; cursor: zoom-in; background: none;
  box-shadow: 0 0 0 1px var(--line);
  transition: box-shadow 160ms ease, transform 160ms ease;
}
.tile:hover { transform: translateY(-3px); box-shadow: 0 0 0 1px rgba(0, 200, 255, 0.5), 0 0 30px rgba(0, 200, 255, 0.25); }
.tile img { width: 100%; height: 100%; object-fit: cover; aspect-ratio: 3 / 4; }
.tile .tile-cap {
  position: absolute; inset-inline-start: 12px; bottom: 12px;
  background: rgba(7, 7, 13, 0.85); color: var(--ink);
  border: 1px solid var(--line);
  border-radius: var(--pill); padding: 5px 13px;
  font-weight: 700; font-size: 0.72rem;
  opacity: 0; transform: translateY(6px);
  transition: opacity 140ms ease, transform 140ms ease;
  pointer-events: none;
}
.tile:hover .tile-cap, .tile:focus-visible .tile-cap { opacity: 1; transform: none; }
@media (hover: none) { .tile .tile-cap { opacity: 1; transform: none; } }
@media (max-width: 899px) {
  .gallery-panel { grid-template-columns: 1fr; }
  .gallery-pill { margin-top: 18px; }
}
.lightbox { border: 0; padding: 0; background: transparent; max-width: min(92vw, 1100px); width: 100%; }
.lightbox::backdrop { background: rgba(4, 4, 8, 0.92); }
.lightbox img { width: 100%; max-height: 82vh; object-fit: contain; border-radius: var(--radius-sm); }
.lightbox-bar {
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  padding-top: 14px; color: var(--ink); font-weight: 600; font-size: 0.85rem;
}
.lightbox-controls { display: flex; gap: 8px; }
.lightbox-close, .lightbox-nav {
  background: rgba(7, 7, 13, 0.85); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--pill);
  font-weight: 700; font-size: 0.78rem;
  padding: 11px 16px; cursor: pointer;
}
.lightbox-close:hover, .lightbox-nav:hover { border-color: var(--cyan); box-shadow: 0 0 14px rgba(0, 200, 255, 0.35); }
html:has(#lightbox[open]) { overflow: hidden; }
/* ============================================================
   banner + contact row
   ============================================================ */
.banner {
  margin-top: var(--section-gap);
  color: var(--ink);
  border-radius: var(--pill);
  padding: 18px 28px;
  display: flex; align-items: center; justify-content: center; gap: 10px;
  text-align: center; flex-wrap: wrap;
  font-weight: 600; font-size: 0.95rem;
}
.banner a {
  color: var(--amber); font-weight: 700; text-underline-offset: 4px;
  display: inline-block; padding: 10px 8px; margin: -10px -8px; /* invisible tap-area extension */
}
.banner a:hover { color: var(--orange); text-shadow: 0 0 14px rgba(255, 107, 0, 0.6); }
.contact-row { display: flex; gap: var(--gap); margin-top: var(--gap); align-items: stretch; }
.contact-label {
  background: var(--ember); color: #07070d;
  border-radius: var(--pill); padding: 20px 34px;
  font-family: var(--font-display); font-weight: 700; font-size: clamp(1.1rem, 2vw, 1.6rem);
  display: flex; align-items: center;
  box-shadow: 0 0 34px rgba(255, 107, 0, 0.35);
}
.contact-value {
  flex: 1;
  color: var(--ink);
  border-radius: var(--pill); padding: 20px 34px;
  display: flex; align-items: center;
  font-weight: 700; font-size: clamp(1rem, 1.6vw, 1.3rem);
  text-decoration: none;
  transition: box-shadow 140ms ease;
}
.contact-value:hover { box-shadow: 0 0 26px rgba(0, 200, 255, 0.3); }
.contact-arrow {
  background: var(--ember); color: #07070d;
  border-radius: var(--pill);
  width: 76px; display: flex; align-items: center; justify-content: center;
  font-size: 1.5rem; text-decoration: none;
  box-shadow: 0 0 26px rgba(255, 107, 0, 0.35);
}
.contact-arrow:hover { box-shadow: 0 0 40px rgba(255, 107, 0, 0.6); }
/* mirror only the glyph — flipping the whole link would mirror the email
   address itself under Arabic */
html[dir="rtl"] .contact-arrow-mark { display: inline-block; transform: scaleX(-1); }
.contact-arrow-text { display: none; }
@media (max-width: 767px) {
  .contact-row { flex-direction: column; }
  /* stacked, this was a third full-width ember slab whose entire visible
     content was one arrow — the email address existed only in aria-label.
     On a phone it now reads as a real contact route in glass, so the brand
     gradient fires once (the label) instead of twice 65px apart. */
  .contact-arrow {
    width: auto; padding: 20px 24px; gap: 10px;
    font-size: 1rem; color: var(--ink);
    background:
      linear-gradient(var(--glass), var(--glass)) padding-box,
      linear-gradient(160deg, rgba(242, 240, 250, 0.28), rgba(242, 240, 250, 0.06) 45%, rgba(242, 240, 250, 0.16)) border-box;
    border: 1px solid transparent;
    box-shadow: none;
  }
  .contact-arrow-text { display: inline; }
}
/* ============================================================
   footer — luminous grid horizon with glowing orbs
   ============================================================ */
.v2-footer {
  position: relative;
  margin-top: var(--section-gap);
  padding: 48px 16px 24px;
  background-image:
    linear-gradient(to right, rgba(242, 240, 250, 0.07) 1px, transparent 1px),
    linear-gradient(to bottom, rgba(242, 240, 250, 0.07) 1px, transparent 1px);
  background-size: 56px 56px;
  border-top: 1px solid var(--line);
  border-radius: var(--radius) var(--radius) 0 0;
  overflow: hidden;
}
.v2-footer::before {
  content: ""; position: absolute; inset: 0;
  background: radial-gradient(600px 300px at 50% 100%, rgba(255, 107, 0, 0.12), transparent 70%);
  pointer-events: none;
}
.confetti { position: absolute; width: 16px; height: 16px; border-radius: 50%; }
.confetti--1 { background: var(--orange); box-shadow: 0 0 18px 4px rgba(255, 107, 0, 0.55); top: 14%; inset-inline-start: 12%; }
.confetti--2 { background: var(--purple); box-shadow: 0 0 18px 4px rgba(168, 102, 255, 0.5); top: 8%; inset-inline-end: 28%; }
.confetti--3 { background: var(--green); box-shadow: 0 0 18px 4px rgba(42, 209, 126, 0.5); bottom: 30%; inset-inline-end: 10%; }
.confetti--4 { background: var(--blue); box-shadow: 0 0 18px 4px rgba(61, 139, 255, 0.5); top: 42%; inset-inline-start: 30%; }
.confetti--5 { background: var(--red); box-shadow: 0 0 18px 4px rgba(255, 85, 68, 0.5); bottom: 18%; inset-inline-start: 48%; }
@media (max-width: 767px) {
  /* desktop-tuned offsets land on text in the short mobile footer */
  .confetti--4, .confetti--5 { display: none; }
}
.wordmark {
  position: relative;
  display: flex; justify-content: center;
  padding-inline: 4%;
}
.wordmark img {
  display: block; width: 100%; max-width: 760px; height: auto;
  opacity: 0.92;
}
.footer-links {
  position: relative;
  display: flex; flex-wrap: wrap; gap: 4px 18px; justify-content: center;
  margin-top: 28px;
}
.footer-links a {
  color: var(--muted); font-size: 0.8rem; font-weight: 600;
  text-decoration: none; padding: 10px 6px;
}
.footer-links a:hover { color: var(--orange); }
.footer-row {
  position: relative;
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center; justify-content: space-between;
  margin-top: 18px;
  font-size: 0.8rem; font-weight: 500; color: var(--muted);
}
.footer-pills { display: flex; flex-wrap: wrap; gap: 8px; }
.footer-pills a {
  border-radius: var(--pill); color: var(--ink);
  padding: 12px 18px; font-weight: 700; font-size: 0.75rem; text-decoration: none;
}
.footer-pills a:hover { box-shadow: 0 0 16px rgba(0, 200, 255, 0.3); }
/* ---- footer 3.0: statement CTA + link columns above the wordmark ---- */
.footer-hail {
  position: relative; text-align: center;
  max-width: 880px; margin-inline: auto;
  padding: clamp(30px, 6vw, 60px) 16px clamp(10px, 2vw, 20px);
}
.footer-hail-kicker {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--orange);
}
/* now a real <h2> so the footer emits a heading; letter-spacing is pinned so
   the global heading rule's -0.02em cannot change the render */
.footer-hail-title {
  font-family: var(--font-display); font-weight: 700; color: var(--ink);
  font-size: clamp(2.1rem, 5.5vw, 3.6rem); line-height: 1.06; margin-top: 10px;
  letter-spacing: normal;
}
.footer-hail-accent {
  background: var(--ember);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.footer-hail-sub { color: var(--muted); font-size: 1rem; margin-top: 14px; }
.footer-hail-actions { display: flex; flex-wrap: wrap; justify-content: center; gap: 12px; margin-top: 28px; }
.footer-cta-main {
  border-radius: var(--pill); padding: 14px 22px;
  background: var(--ember); color: #140a02;
  font-weight: 700; font-size: 0.85rem; text-decoration: none;
  transition: transform var(--dur-tap) var(--ease-fluid), box-shadow var(--dur-ui) var(--ease-fluid);
}
.footer-cta-main:hover { transform: translateY(-1px); box-shadow: 0 6px 22px rgba(255, 107, 0, 0.4); }
.footer-cta-ghost {
  border-radius: var(--pill); padding: 14px 22px;
  border: 1px solid var(--line); color: var(--ink);
  font-weight: 700; font-size: 0.85rem; text-decoration: none;
  transition: border-color var(--dur-ui) var(--ease-fluid), box-shadow var(--dur-ui) var(--ease-fluid);
}
.footer-cta-ghost:hover { border-color: var(--orange); box-shadow: 0 0 16px rgba(255, 107, 0, 0.25); }
.footer-grid {
  position: relative;
  display: grid; grid-template-columns: minmax(260px, 1.4fr) 1fr 1fr;
  gap: 32px clamp(24px, 5vw, 64px);
  max-width: 1080px; margin: 34px auto 0;
  padding-block: 36px 34px;
  border-block: 1px solid var(--line);
}
.footer-brand-line { color: var(--muted); font-size: 0.88rem; line-height: 1.65; }
/* labelled rows: the contact block reads as a company record */
.footer-contact { display: grid; gap: 14px; margin-top: 20px; }
.footer-contact a, .footer-contact > span {
  display: grid; gap: 3px;
  color: var(--ink); font-size: 0.88rem; font-weight: 600;
  text-decoration: none; width: fit-content;
  direction: ltr; unicode-bidi: isolate;
}
.fc-label {
  font-size: 0.64rem; font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted);
}
.footer-contact a:hover { color: var(--orange); }
.footer-contact a:hover .fc-label { color: var(--muted); }
.footer-col { display: grid; gap: 9px; align-content: start; }
.footer-col-title {
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.18em;
  text-transform: uppercase; color: var(--orange); margin-bottom: 4px;
}
.footer-col a { color: var(--muted); font-size: 0.85rem; font-weight: 600; text-decoration: none; width: fit-content; }
.footer-col a:hover { color: var(--orange); }
/* Touch: the footer nav links measured 21px tall — half a thumb. On coarse
   pointers each becomes a full 44px target. Desktop density is untouched. */
@media (pointer: coarse) {
  .footer-col { gap: 2px; }
  .footer-col a { min-height: 44px; display: flex; align-items: center; }
  .footer-contact a, .footer-contact > span { min-height: 44px; justify-content: center; }
  .footer-pills a { min-height: 44px; display: inline-flex; align-items: center; }
}
@media (max-width: 860px) {
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .footer-brand { grid-column: 1 / -1; }
}
@media (max-width: 480px) { .footer-grid { grid-template-columns: 1fr; } }
.v2-footer .wordmark { margin-top: 40px; }
.v2-footer .footer-row { max-width: 1080px; margin: 18px auto 0; }
/* ============================================================
   faq accordion — glass details
   ============================================================ */
.faq { display: grid; gap: 12px; }
.faq details { border-radius: var(--radius-sm); overflow: hidden; }
.faq summary {
  cursor: pointer; list-style: none;
  padding: 16px 22px;
  font-family: var(--font-display); font-weight: 700; font-size: 1.02rem;
  display: flex; justify-content: space-between; align-items: center; gap: 12px;
  color: var(--ink);
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after { content: "+"; font-size: 1.35rem; flex-shrink: 0; color: var(--orange); }
.faq details[open] summary::after { content: "–"; }
.faq details[open] { box-shadow: inset 0 1px 0 rgba(255, 178, 30, 0.5), 0 0 30px rgba(255, 178, 30, 0.12); }
.faq .faq-body { padding: 0 22px 18px; font-weight: 450; font-size: 0.95rem; max-width: 72ch; color: var(--muted); }
html[lang="ar"] .faq summary { font-family: var(--font-ar); }
/* ============================================================
   motion layer — reveals, tilt, hero entrance (effects.js drives)
   ============================================================ */
/* one-shot entrance animation — never fights the interactive transitions */
@keyframes reveal-in {
  from { opacity: 0; transform: perspective(760px) translateY(38px) rotateX(9deg) scale(0.965); filter: blur(7px); }
  to { filter: blur(0); }
}
html.motion-on .reveal { opacity: 0; }
html.motion-on .reveal.in-view {
  opacity: 1;
  animation: reveal-in var(--dur-scene) var(--ease-fluid) var(--reveal-delay, 0ms) backwards;
}
/* 3D presence: cards tilt toward the pointer */
html.motion-on .block-card,
html.motion-on .art-card,
html.motion-on .hero-card,
html.motion-on .tile {
  transform: perspective(900px) rotateX(var(--tilt-x, 0deg)) rotateY(var(--tilt-y, 0deg)) translateY(var(--lift, 0px));
  transition: transform var(--dur-ui) var(--ease-fluid), box-shadow var(--dur-ui) var(--ease-fluid);
}
html.motion-on .block-card:hover, html.motion-on .tile:hover { --lift: -6px; }
/* hero entrance: art and statement glide in on load */
html.motion-on .v2-hero .hero-card { animation: reveal-in var(--dur-scene) var(--ease-fluid) both; }
html.motion-on .v2-hero .hero-card:nth-child(2) { animation-delay: 90ms; }
html.motion-on .hero-art-card img { transition: transform 200ms linear; }
/* press feedback — every interactive element answers the tap */
.chip:active, .pill:active, .hero-pill:active, .gallery-pill:active,
.btn-cta:active, .lang-switch:active, .marquee-toggle:active,
.lightbox-close:active, .lightbox-nav:active,
.contact-label:active, .contact-value:active, .contact-arrow:active,
.footer-pills a:active { transform: scale(0.97); }
.chip, .pill, .hero-pill, .gallery-pill, .lang-switch,
.contact-value, .contact-arrow, .footer-pills a, .faq summary {
  transition: transform var(--dur-tap) var(--ease-fluid), box-shadow var(--dur-ui) var(--ease-fluid), color var(--dur-tap) ease;
  cursor: pointer;
}
/* card hover: no sheen overlay — cards answer hover with their own
   border/translate styles only (white shade removed at user request) */
.block-card, .hero-copy-card, .gallery-panel { position: relative; }
/* ============================================================
   site AI assistant widget
   ============================================================ */
.agent-root { position: fixed; inset-inline-end: 18px; bottom: 18px; z-index: 95; }
/* the dragon crest IS the launcher — no pill, no label */
.agent-launcher {
  display: grid; place-items: center;
  background: none; border: 0; padding: 0; cursor: pointer;
  filter: drop-shadow(0 5px 14px rgba(0, 0, 0, 0.55));
  transition: transform var(--dur-tap) var(--ease-fluid);
}
.agent-launcher:active { transform: scale(0.97); }
.agent-panel {
  /* viewport-anchored: agent.js lifts this out of .agent-root, whose
     `perspective` used to make it the containing block. 36/102 reproduce
     where the panel sat when it was nested (root's own 18/84 plus its
     offset), so nothing moves on screen. */
  position: fixed; inset-inline-end: 36px; bottom: 102px;
  /* The panel used to sit inside .agent-root and borrow its z-index. Lifting
     it out to <body> (so the keyboard maths works) dropped it to auto, and
     the hero headline and the chip rail painted straight through it. 96 puts
     it one above .agent-root's 95, and clear of the rail and brand mark at 90. */
  z-index: 96;
  width: min(380px, calc(100vw - 36px));
  height: min(560px, calc(100dvh - 120px));
  display: flex; flex-direction: column;
  border-radius: var(--radius);
  /* fully opaque: at 0.96 the hero headline ghosted through the conversation,
     which on a phone (where the panel is nearly full-screen) made the chat
     look broken. The gradient border still carries the brand edge. */
  background:
    linear-gradient(#0c0b14, #0c0b14) padding-box,
    linear-gradient(160deg, rgba(255, 107, 0, 0.55), rgba(242, 240, 250, 0.1) 50%, rgba(168, 102, 255, 0.35)) border-box;
  border: 1px solid transparent;
  box-shadow: 0 24px 80px rgba(0, 0, 0, 0.6), 0 0 60px rgba(255, 107, 0, 0.12);
}
.agent-panel[hidden] { display: none; }
/* the header and the composer are the two things that must never be squeezed
   out of the sheet — the close button lives in one, the input in the other */
.agent-head {
  display: flex; align-items: center; gap: 10px;
  padding: 16px 18px; border-bottom: 1px solid var(--line);
  flex-shrink: 0;
}
.agent-head > div { flex: 1; min-width: 0; }
.agent-title { display: block; font-family: var(--font-display); font-weight: 700; font-size: 1rem; color: var(--ink); }
.agent-subtitle { display: block; font-size: 0.72rem; font-weight: 600; color: var(--muted); margin-top: 2px; }
.agent-close {
  background: none; border: 1px solid var(--line); border-radius: var(--pill);
  color: var(--ink); font-size: 1rem; line-height: 1;
  width: 34px; height: 34px; cursor: pointer; flex-shrink: 0;
}
.agent-close:hover { border-color: var(--cyan); }
/* on touch the close button is the escape hatch — give it a real target */
@media (hover: none) {
  .agent-close { width: 44px; height: 44px; font-size: 1.25rem; }
}
/* the page must not scroll behind the open sheet, or closing the keyboard
   leaves people somewhere they never navigated to */
@media (max-width: 1099px) {
  html.agent-open, html.agent-open body { overflow: hidden; touch-action: none; }
}
.agent-msgs { flex: 1; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 10px; }
.agent-bubble {
  max-width: 85%; padding: 10px 14px;
  border-radius: 16px;
  font-size: 0.9rem; line-height: 1.55;
  white-space: pre-wrap; overflow-wrap: break-word;
}
.agent-bubble--assistant {
  align-self: flex-start;
  background: rgba(255, 255, 255, 0.06);
  border: 1px solid var(--line);
  color: var(--ink);
  border-start-start-radius: 4px;
}
.agent-bubble--user {
  align-self: flex-end;
  background: linear-gradient(150deg, rgba(255, 107, 0, 0.3), rgba(255, 178, 30, 0.16));
  border: 1px solid rgba(255, 107, 0, 0.4);
  color: var(--ink);
  border-start-end-radius: 4px;
}
.agent-bubble--thinking { color: var(--muted); letter-spacing: 3px; }
.agent-wa { align-self: flex-start; font-size: 0.78rem; }
.agent-form {
  display: flex; gap: 8px; padding: 12px; border-top: 1px solid var(--line);
  flex-shrink: 0;
}
.agent-input {
  flex: 1; min-width: 0;
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--line); border-radius: var(--pill);
  color: var(--ink); font-family: var(--font-body); font-size: 0.9rem;
  padding: 11px 16px;
}
.agent-input:focus-visible { outline: 2px solid var(--cyan); outline-offset: 1px; }
.agent-send {
  background: var(--ember); color: #07070d;
  border: 0; border-radius: var(--pill);
  font-weight: 700; font-size: 0.82rem;
  padding: 11px 18px; cursor: pointer;
}
.agent-send:disabled { opacity: 0.55; cursor: wait; }
/* ============================================================
   bidi + motion discipline
   ============================================================ */
html[dir="rtl"] [lang="en"] { direction: ltr; unicode-bidi: isolate; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .marquee-track { animation: none; }
  ::view-transition-old(root), ::view-transition-new(root) { animation: none; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}
/* ============================================================
   service hub cards — clickable block-cards linking to the
   service detail pages (used on services.html + hub pages)
   ============================================================ */
.hub-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: var(--gap);
  align-items: stretch;
}
.hub-card { text-decoration: none; display: flex; flex-direction: column; align-items: flex-start; }
.hub-card:hover h3 { color: var(--orange); transition: color var(--dur-tap) ease; }
html[dir="rtl"] .hub-card { direction: ltr; }
.hub-card .pill { margin-top: auto; }
.hub-card p { margin-bottom: 16px; }
@media (max-width: 1099px) { .hub-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 767px) { .hub-grid { grid-template-columns: 1fr; } }
/* ============================================================
   dark content canvas — the whole site sits on the deep-space
   skin (:root palette). The content column keeps its layout
   frame; every glass/card/marquee recipe uses the base dark
   styles defined above. Scoped so the admin console is untouched.
   ============================================================ */
.page:not(.admin-page) {
  background: var(--cream);
  color: var(--ink);
  min-height: 100vh;
  padding: 60px var(--pad) 0;
  border-start-start-radius: var(--radius);
}
@media (max-width: 1099px) {
  .page:not(.admin-page) { padding: 12px 16px 0; border-radius: var(--radius) var(--radius) 0 0; }
}
/* ============================================================
   cinema layer — typographic mega-heroes, floating shape field,
   3D reveals, glare tilt, magnetic CTAs (content-first redesign)
   ============================================================ */

/* ---- mega hero: giant staggered type, content follows immediately ---- */
.mega-hero { position: relative; padding: clamp(44px, 8vh, 96px) 0 clamp(26px, 4vh, 54px); }
.kicker {
  display: inline-flex; align-items: center; gap: 10px;
  border-radius: var(--pill); padding: 10px 18px;
  font-weight: 700; font-size: 0.78rem; color: var(--ink);
  background: var(--glass); border: 1px solid var(--line);
}
.kicker::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--orange); box-shadow: 0 0 12px rgba(255, 107, 0, 0.8);
}
/* the pulse was ungated and infinite, so it ran for visitors who had
   explicitly asked for no motion — effects.js owns the motion-on class */
html.motion-on .kicker::before { animation: kicker-pulse 2.4s ease-in-out infinite; }
@keyframes kicker-pulse { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.35); opacity: 0.6; } }
/* The hero headline runs General Sans (display token). It previously ran Bricolage Grotesque, variable 600-800. Space
   Grotesk is the fallback rather than a system face, so the pre-swap frame
   is already the brand's own grotesk at the same optical weight — the swap
   reads as the type gaining weight, never as a typeface change.
   Tracking is tighter than the old face carried because Bricolage sets
   wider by default at display sizes. */
.mega-title {
  margin-top: 28px;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(2.6rem, 6.8vw, 5.9rem);
  line-height: 0.98; letter-spacing: -0.045em;
  max-width: 21ch;
  /* opsz is not in this subset's axes; the optical correction is the
     tracking above. font-synthesis off so no faux-bold on the fallback. */
  font-synthesis-weight: none;
}
.mega-title .line { display: block; overflow: hidden; padding-block: 0.06em; }
.mega-title .line > span { display: inline-block; will-change: transform, filter; }
/* The entrance: each line is masked by its own overflow box, rises from
   below, and resolves out of a short defocus. Transform + opacity + filter
   only — the type never reflows, so the largest text on the page cannot
   contribute layout shift while it animates.
   The easing is a long expo tail: the line covers most of its travel early
   and settles slowly, which is what reads as "smooth" rather than "slid". */
html.motion-on .mega-title .line > span {
  transform: translateY(118%);
  animation: line-rise 1.05s cubic-bezier(0.16, 1, 0.3, 1) forwards;
}
html.motion-on .mega-title .line:nth-child(1) > span { animation-delay: 60ms; }
html.motion-on .mega-title .line:nth-child(2) > span { animation-delay: 175ms; }
html.motion-on .mega-title .line:nth-child(3) > span { animation-delay: 290ms; }
@keyframes line-rise {
  from { transform: translateY(118%) skewY(3.2deg); filter: blur(9px); opacity: 0; }
  55%  { filter: blur(0); opacity: 1; }
  to   { transform: translateY(0) skewY(0deg); filter: blur(0); opacity: 1; }
}
/* the weight morph runs on the whole heading, once, after the lines land:
   600 -> 800 over one beat. Kept off the per-line boxes so it resolves as a
   single gesture instead of three. */
html.motion-on .mega-title {
  animation: title-weight 900ms cubic-bezier(0.16, 1, 0.3, 1) 380ms both;
}
@keyframes title-weight {
  from { font-variation-settings: "wght" 600; }
  to   { font-variation-settings: "wght" 800; }
}
.mega-title .accent {
  background: var(--ember);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
.mega-title .accent--holo {
  background: var(--holo);
  -webkit-background-clip: text; background-clip: text; color: transparent;
}
/* inline icon chips inside the headline (reference: "human + AI") */
.title-chip {
  display: inline-flex; align-items: center; justify-content: center;
  width: 0.82em; height: 0.82em; vertical-align: -0.08em;
  border-radius: 0.22em; margin-inline: 0.04em;
  animation: chip-float 4.6s ease-in-out infinite;
}
.title-chip svg { width: 62%; height: 62%; fill: #fff; }
.title-chip--orange { background: var(--ember); box-shadow: 0 6px 24px rgba(255, 107, 0, 0.45); }
.title-chip--purple { background: linear-gradient(135deg, #a866ff, #7a3cf0); box-shadow: 0 6px 24px rgba(168, 102, 255, 0.45); animation-delay: 1.1s; }
.title-chip--green { background: linear-gradient(135deg, #2ad17e, #12a45c); box-shadow: 0 6px 24px rgba(42, 209, 126, 0.4); animation-delay: 0.6s; }
@keyframes chip-float { 0%, 100% { transform: translateY(0) rotate(-3deg); } 50% { transform: translateY(-0.09em) rotate(4deg); } }
.mega-sub { margin-top: 22px; max-width: 58ch; color: var(--muted); font-size: 1.04rem; line-height: 1.7; font-weight: 450; }
.mega-ctas { margin-top: 30px; display: flex; flex-wrap: wrap; gap: 12px; }
.btn-hero {
  display: inline-flex; align-items: center; gap: 8px;
  background: var(--ember); color: #1a1005;
  border-radius: var(--pill); padding: 15px 26px;
  font-weight: 700; font-size: 0.92rem; text-decoration: none;
  box-shadow: 0 10px 30px rgba(255, 107, 0, 0.35);
  transition: transform var(--dur-tap) var(--ease-fluid), box-shadow var(--dur-ui) var(--ease-fluid);
}
.btn-hero:hover { box-shadow: 0 14px 44px rgba(255, 107, 0, 0.5); }
.btn-hero:active { transform: scale(0.97); }
.page:not(.admin-page) { position: relative; }
.page:not(.admin-page) > * { position: relative; z-index: 1; }
/* pointer glare removed 2026-07-28 — the white blob read as a smudge over the card */

/* ---- blueprint panels: framed line-art per service, continuous 3D ---- */
.blueprint {
  width: 100%;
  background: #0e0d15;
  border: 1px solid rgba(255, 255, 255, 0.18);
  border-radius: 16px;
  padding: 14px 16px 8px;
  margin-bottom: 20px;
  color: #f4f2fb; /* the line art draws in currentColor */
  position: relative; overflow: hidden;
}
.bp-label {
  display: block;
  font-family: var(--font-display); font-weight: 700;
  text-transform: uppercase; letter-spacing: 0.24em; font-size: 0.66rem;
  opacity: 0.9;
  padding-bottom: 9px; margin-bottom: 4px;
  border-bottom: 1px dashed rgba(255, 255, 255, 0.28);
}
.bp-art { display: block; width: 100%; height: auto; }
/* continuous 3D sway — the whole drawing breathes in perspective */
html.motion-on .bp-art { animation: bp-sway 8s ease-in-out infinite; }
html.motion-on .masonry-col .block-card:nth-child(2) .bp-art { animation-delay: -4s; }
@keyframes bp-sway {
  0%, 100% { transform: perspective(700px) rotateY(-5deg) rotateX(1.6deg); }
  50% { transform: perspective(700px) rotateY(5deg) rotateX(-1.6deg); }
}
/* element choreography inside the drawings */
html.motion-on .bp-spin { animation: bp-rot 10s linear infinite; transform-box: fill-box; transform-origin: center; }
@keyframes bp-rot { to { transform: rotate(360deg); } }
html.motion-on .bp-float { animation: bp-bob 3.8s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
@keyframes bp-bob { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-6px); } }
html.motion-on .bp-pulse { animation: bp-pp 2.6s ease-in-out infinite; transform-box: fill-box; transform-origin: center; }
@keyframes bp-pp { 0%, 100% { opacity: 1; transform: scale(1); } 50% { opacity: 0.45; transform: scale(0.86); } }
html.motion-on .bp-blink { animation: bp-bb 2.2s steps(2, jump-none) infinite; }
@keyframes bp-bb { 50% { opacity: 0.25; } }
html.motion-on .bp-draw { animation: bp-dash 5.5s ease-in-out infinite alternate; }
@keyframes bp-dash { from { stroke-dashoffset: 240; } to { stroke-dashoffset: 0; } }
/* pointer parallax: the layers separate in depth toward the cursor */
.bp-l1, .bp-l2, .bp-l3 { transition: transform 0.3s var(--ease-fluid); }
.bp-l1 { transform: translate(calc(var(--bx, 0) * 4px), calc(var(--by, 0) * 3px)); }
.bp-l2 { transform: translate(calc(var(--bx, 0) * 9px), calc(var(--by, 0) * 6px)); }
.bp-l3 { transform: translate(calc(var(--bx, 0) * 15px), calc(var(--by, 0) * 10px)); }
/* compact variant for the homepage service cards */
.blueprint--sm { padding: 10px 12px 4px; margin-bottom: 16px; }
.blueprint--sm .bp-label { font-size: 0.56rem; letter-spacing: 0.2em; padding-bottom: 6px; }
.blueprint--sm .bp-art { max-width: 250px; margin-inline: auto; }
/* ============================================================
   smart FAQ — searchable, filterable, wired to the AI assistant
   ============================================================ */
/* ============================================================
   smart FAQ — no question list, the visitor just asks (assets/js/faq.js)
   NOTE: no margin-top here. faq.js always injects an .entries-head as the
   first child, whose padding-top IS the section gap; adding a margin here
   double-counted it on every page that loads faq.js.
   The old accordion rules (.sfaq-item/.sfaq-q/.sfaq-cat/.sfaq-list) styled
   markup faq.js no longer emits, while what it DOES emit had no styles.
   ============================================================ */
.sfaq-answers { display: grid; gap: 12px; }
.sfaq-qa {
  display: grid; gap: 8px; padding: 16px 20px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--glass);
}
.sfaq-qa-q {
  font-family: var(--font-display); font-weight: 700;
  font-size: 1rem; color: var(--ink);
}
.sfaq-qa-a {
  font-size: 0.93rem; line-height: 1.65; color: var(--muted); max-width: 74ch;
  /* mirrors .agent-bubble: keeps the AI's line breaks and stops a long URL
     in an answer overflowing the viewport at 320px */
  white-space: pre-wrap; overflow-wrap: break-word;
}
.sfaq-qa-a--thinking { letter-spacing: 3px; color: var(--muted); }
.sfaq-qa-wa { justify-self: start; margin-top: 4px; }
.sfaq-ask { display: flex; gap: 10px; margin-top: 22px; max-width: 560px; }
.sfaq-ask-input {
  flex: 1; min-width: 0;
  border: 1px solid var(--line); border-radius: var(--pill);
  background: var(--glass); color: var(--ink);
  font: inherit; font-size: 0.92rem; padding: 12px 20px;
}
.sfaq-ask-input:focus-visible { outline: 2px solid var(--orange); outline-offset: 2px; }
.sfaq-ask-btn { white-space: nowrap; }
@media (max-width: 599px) { .sfaq-ask { flex-direction: column; } }
/* ============================================================
   Blaze — the fire-dragon crest
   A single self-framed SVG: a dragon head in profile inside the
   hex medallion. Idle: the ember core breathes, the eye glows,
   the hex edge shimmers and the flame breath flickers. Hover:
   the whole crest lifts and flares.
   ============================================================ */
.agent-dragon { display: block; flex-shrink: 0; line-height: 0; }
.agent-dragon .bzx { display: block; width: 100%; height: auto; overflow: visible; }
/* the hex medallion is gone, so the crest is now just the creature — it
   occupies ~77% of the viewBox, hence the larger box for the same optical size */
.agent-dragon--sm { width: 78px; }
.agent-dragon--lg { width: 60px; margin-inline-end: 4px; }
@media (max-width: 479px) { .agent-dragon--sm { width: 66px; } }
.bzx-core, .bzx-eye, .bzx-horn, .bzx-flame { transform-box: fill-box; transform-origin: center; }
.bzx-flame { transform-origin: left center; }
html.motion-on .bzx-core { animation: bzx-breathe 2.6s ease-in-out infinite; }
html.motion-on .bzx-eye  { animation: bzx-breathe 2.6s ease-in-out infinite; }
html.motion-on .bzx-flame { animation: bzx-flick 1.7s ease-in-out infinite; }
/* ---- the crest floats in space, same language as the hero plate ----
   Perspective on the fixed root; the yaw/nod rides `rotate` and `translate`
   so it never collides with the hover `transform` on .bzx. Compositor-only,
   so an always-on animation costs no main-thread time. */
.agent-root { perspective: 700px; perspective-origin: 50% 50%; }
html.motion-on .agent-launcher { animation: bzx-hover 3.1s ease-in-out infinite; }
html.motion-on .agent-launcher .agent-dragon { animation: bzx-soar 4.6s ease-in-out infinite; }
/* the body rises and falls */
@keyframes bzx-hover {
  0%, 100% { translate: 0 0; }
  50%      { translate: 0 -7px; }
}
/* while the creature banks through it — different period, so the two never
   sync into an obvious loop */
@keyframes bzx-soar {
  0%, 100% { rotate: 1 6 0 -13deg; scale: 1; }
  35%      { scale: 1.03; }
  50%      { rotate: 1 6 0 13deg; scale: 1; }
  85%      { scale: 0.985; }
}
/* a plain dark shadow, not an ember halo — enough to separate the creature
   from whatever scrolls underneath, without lighting it up */
.agent-launcher { filter: drop-shadow(0 6px 18px rgba(0, 0, 0, 0.55)); }
.agent-launcher:hover { filter: drop-shadow(0 9px 22px rgba(0, 0, 0, 0.62)); }
/* hover / focus: the whole crest reacts */
.agent-launcher .agent-dragon .bzx { transition: transform var(--dur-ui) var(--ease-fluid), filter var(--dur-ui) var(--ease-fluid); }
.agent-launcher:hover .agent-dragon .bzx,
.agent-launcher:focus-visible .agent-dragon .bzx {
  transform: translateY(-1px) scale(1.08) rotate(-3deg);
}
@keyframes bzx-breathe { 0%, 100% { opacity: 0.72; } 50% { opacity: 1; } }
/* bzx-shimmer removed with the hex medallion it lit */
@keyframes bzx-flick { 0%, 100% { transform: scaleX(0.93); opacity: 0.85; } 50% { transform: scaleX(1.05); opacity: 1; } }
/* visually-hidden label text that screen readers still announce */
.agent-sr {
  position: absolute; width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}
/* ============================================================
   Conversion + polish fixes (audit follow-up)
   ============================================================ */
/* the "Start a project" CTA must never scroll out of the desktop rail —
   pin it (and the socials) to the bottom so it's always one glance away */
@media (min-width: 1100px) {
  .chip--cta {
    position: sticky; bottom: 64px; margin-top: auto; z-index: 2;
    background: var(--ember) padding-box; color: #140a02;
  }
  .chip-socials { position: sticky; bottom: 0; background: rgba(7, 7, 13, 0.9); }
}
/* the numbered prefix should whisper, the destination should speak */
.chip .chip-num { opacity: 0.5; font-size: 0.72rem; }
.chip:hover .chip-num, .chip[aria-current="page"] .chip-num { opacity: 0.9; }
/* ============================================================
   HUD boot sequence (#si-pre) — driven by assets/js/preloader.js
   html.si-intro : full tech boot, first page of a session
   html.si-quick : fast reactor + logo flash on every page after
   Neither class (JS never ran) → the overlay never displays.
   A pure-CSS expiry releases the page even if JS dies mid-boot.
   ============================================================ */
.si-pre {
  position: fixed; inset: 0; z-index: 999;
  display: grid; place-items: center; overflow: hidden;
  background:
    radial-gradient(60% 50% at 50% 38%, rgba(255, 107, 0, 0.09), transparent 70%),
    radial-gradient(42% 36% at 78% 82%, rgba(168, 102, 255, 0.08), transparent 70%),
    var(--cream);
  /* the exit fade is dead time once the moment is over */
  transition: opacity 0.3s var(--ease-exit), visibility 0.3s var(--ease-exit);
}
html:not(.si-intro):not(.si-quick) .si-pre { display: none; }
.si-pre.is-done { opacity: 0; visibility: hidden; pointer-events: none; }
/* even with every timer dead, the overlay lets go on its own */
/* the JS-died safety net. Starts at first paint like everything else, so 5s
   here still lands after the 6000ms JS ceiling in preloader.js. */
html.si-intro .si-pre { animation: si-expire 0.6s ease 5s forwards; }
html.si-quick .si-pre { animation: si-expire 0.4s ease 1.8s forwards; }
@keyframes si-expire { to { opacity: 0; visibility: hidden; pointer-events: none; } }
/* ---- reactor core ---- */
.si-core {
  position: relative; display: grid; justify-items: center;
  gap: clamp(16px, 3.5vh, 28px);
  width: min(92vw, 460px); padding: 24px;
}
html.si-intro .si-core { animation: si-rise 0.35s var(--ease-fluid) both; }
@keyframes si-rise { from { opacity: 0; transform: translateY(14px) scale(0.98); } }
.si-logo {
  position: relative; width: 62%; height: auto;
  filter: drop-shadow(0 0 18px rgba(255, 107, 0, 0.35));
}
/* ---- boot readout ---- */
.si-title {
  font-family: var(--font-display); font-size: clamp(12px, 1.6vw, 14px);
  letter-spacing: 0.14em; color: var(--muted); text-align: center;
}
.si-title b { color: var(--ink); font-weight: 600; }
html.si-quick .si-pre { transition-duration: 0.35s; }
@media (max-width: 480px) {
  .si-rail { font-size: 9.5px; padding-inline: 44px; }
}
@media (prefers-reduced-motion: reduce) {
  .si-pre, .si-pre * { animation-duration: 0.01ms !important; }
}
/* ============================================================
   flat-vector art placements — hero art panels, step + legal icons
   ============================================================ */
.mega-hero--art {
  display: grid; grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: var(--gap); align-items: center;
}
.mega-art {
  border-radius: var(--radius); overflow: hidden; background: #fff;
  box-shadow: 0 0 0 1px var(--line), 0 20px 60px rgba(0, 0, 0, 0.5);
}
.mega-art img { display: block; width: 100%; height: auto; }
@media (max-width: 900px) {
  .mega-hero--art { grid-template-columns: 1fr; }
  .mega-art { max-width: 460px; }
}
.step-art { width: 96px; height: auto; margin-bottom: 12px; color: var(--ink); opacity: 0.9; }
/* ---- how a project runs ----
   Four boxes in a row said "four things"; they never said "in this order".
   The steps now sit on a rail, and the rail FILLS as the section scrolls —
   scroll-driven, so the progress bar is the scroll position rather than a
   timer that runs whether anyone is looking or not.

   Each node lights as the fill reaches it. All four share nearly the same
   view() timeline, so the sequence comes from staggered animation-range
   rather than delays — which means it also runs backwards when you scroll up.

   animation-timeline is compositor-driven and costs no main-thread time.
   Where it is unsupported the rail simply sits filled and the nodes lit, so
   nothing is ever missing — only the motion is. */
.process-row {
  position: relative;
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: var(--gap);
  padding-top: 62px;
}
/* the unlit rail */
.process-row::before,
.process-row::after {
  content: "";
  position: absolute;
  top: 23px;
  inset-inline: 6px;
  height: 2px;
  border-radius: 2px;
}
.process-row::before { background: var(--line); }
/* the fill */
.process-row::after {
  background: linear-gradient(90deg, #ff6b00, #ffb21e);
  transform-origin: left center;
}
html.motion-on .process-row::after {
  transform: scaleX(0);
  animation: rail-fill linear both;
  animation-timeline: view();
  animation-range: entry 15% cover 60%;
}
@keyframes rail-fill { to { transform: scaleX(1); } }
/* --- the cards --- */
.process-row .block-card {
  position: relative;
  display: flex; flex-direction: column; align-items: flex-start;
  background: rgba(255, 255, 255, 0.028);
  border-color: rgba(255, 255, 255, 0.07);
  transition: border-color var(--dur-ui) var(--ease-fluid),
              background var(--dur-ui) var(--ease-fluid);
}
.process-row .block-card:hover {
  border-color: rgba(255, 107, 0, 0.34);
  background: rgba(255, 255, 255, 0.05);
}
/* --- the number, lifted out of the card and onto the rail --- */
.process-row .card-tag {
  position: absolute; top: -62px; inset-inline-start: 0;
  width: 46px; height: 46px; padding: 0;
  display: grid; place-items: center;
  border-radius: 50%;
  border: 2px solid var(--line);
  background: #0b0a12;
  font-family: var(--font-display); font-size: 0.82rem; font-weight: 800;
  letter-spacing: 0; color: var(--muted); text-transform: none;
}
html.motion-on .process-row .card-tag {
  animation: node-lit linear both;
  animation-timeline: view();
}
@keyframes node-lit {
  to {
    border-color: transparent;
    background: linear-gradient(135deg, #ff6b00, #ffb21e);
    color: #1a1005;
    scale: 1.08;
  }
}
/* the stagger is a range offset, not a delay, so scrolling back up unlights
   them in the same order */
html.motion-on .process-row .block-card:nth-child(1) .card-tag { animation-range: entry 20% entry 85%; }
html.motion-on .process-row .block-card:nth-child(2) .card-tag { animation-range: entry 55% cover 12%; }
html.motion-on .process-row .block-card:nth-child(3) .card-tag { animation-range: entry 90% cover 32%; }
html.motion-on .process-row .block-card:nth-child(4) .card-tag { animation-range: cover 10% cover 52%; }
/* --- the icon --- */
.process-row .step-art {
  width: 74px; margin-bottom: 14px;
  color: var(--muted); opacity: 1;
  transition: color var(--dur-ui) var(--ease-fluid);
}
.process-row .block-card:hover .step-art { color: var(--ink); }
.process-row .block-card h3 { font-size: 1.12rem; }
.process-row .block-card p { font-size: 0.9rem; line-height: 1.65; }
@media (max-width: 1099px) {
  .process-row { grid-template-columns: repeat(2, 1fr); row-gap: 74px; }
  /* a rail across two rows would have to jump the gap between them */
  .process-row::before, .process-row::after { display: none; }
  html.motion-on .process-row .card-tag { animation-range: entry 10% entry 55%; }
}
@media (max-width: 767px) {
  .process-row { grid-template-columns: 1fr; }
}
/* Unsupported animation-timeline, or reduced motion: everything is already in
   its finished state, because the un-animated declarations above are the LIT
   ones and only the motion-on rules take them back to the start. */
@media (prefers-reduced-motion: reduce) {
  /* cancelling the animation alone would strand the rail at scaleX(0) and the
     nodes unlit, so the finished state has to be restated here */
  html.motion-on .process-row::after { animation: none; transform: scaleX(1); }
  html.motion-on .process-row .card-tag {
    animation: none;
    border-color: transparent;
    background: linear-gradient(135deg, #ff6b00, #ffb21e);
    color: #1a1005;
  }
}
.legal-icon { width: 92px; height: 92px; margin-bottom: 12px; }
/* ============================================================
   hero choreography — staggered entrance + typed rotator line
   ============================================================ */
/* .mega-title is deliberately NOT in this list. Its lines run their own
   masked rise and the heading itself runs the weight morph; adding hero-rise
   here would win on animation-name and kill the morph, and would also double
   the motion on the one element that already has the most. */
html.motion-on .mega-hero .kicker,
html.motion-on .mega-hero .mega-sub,
html.motion-on .mega-hero .mega-type,
html.motion-on .mega-hero .mega-ctas,
html.motion-on .mega-hero .mega-art,
html.motion-on .mega-hero .hero-work {
  animation: hero-rise 0.7s var(--ease-fluid) both;
}
/* no .mega-title delay here — it would override the weight morph's own 380ms */
html.motion-on .mega-hero .mega-sub   { animation-delay: 0.16s; }
html.motion-on .mega-hero .mega-type  { animation-delay: 0.22s; }
html.motion-on .mega-hero .mega-ctas  { animation-delay: 0.28s; }
html.motion-on .mega-hero .mega-art   { animation-delay: 0.2s; }
html.motion-on .mega-hero .hero-work  { animation-delay: 0.2s; }
@keyframes hero-rise {
  from { opacity: 0; transform: translateY(18px); }
  to   { opacity: 1; transform: none; }
}
/* typed rotator: 'we ship websites|' with a blinking caret */
.mega-type {
  margin-top: 16px;
  font-family: var(--font-display); font-weight: 700;
  font-size: clamp(1.05rem, 2vw, 1.4rem); color: var(--muted);
}
.type-word { color: var(--orange); }
.type-caret {
  display: inline-block; width: 3px; height: 1.05em;
  margin-inline-start: 3px; vertical-align: text-bottom;
  background: var(--orange); border-radius: 2px;
}
html.motion-on .type-caret { animation: caret-blink 1s steps(2, jump-none) infinite; }
@keyframes caret-blink { 50% { opacity: 0; } }
/* THE INSTRUMENT hero system removed — replaced by THE LEDGER (end of file). */

/* ============================================================
   instant-quote band — the closing conversion on every page

   This replaced a three-field enquiry form. The form asked for a name, a
   contact and a description before anything happened; the quote tool asks
   two taps and shows a number, and captures the lead itself either way. One
   of them had to go, and it was not the one that answers the question.
   ============================================================ */
.quote-cta {
  position: relative; overflow: hidden;
  display: flex; flex-wrap: wrap; align-items: center;
  justify-content: space-between; gap: clamp(20px, 3vw, 44px);
  margin: var(--section-gap) 0 0;
  padding: clamp(24px, 3.2vw, 40px) clamp(22px, 3vw, 40px);
  border: 1px solid var(--line); border-radius: var(--radius);
  background: var(--glass);
}
/* one ember wash from the corner the button sits in */
.quote-cta::before {
  content: ""; position: absolute; inset: 0; pointer-events: none;
  background: radial-gradient(58% 120% at 100% 0%, rgba(255, 107, 0, 0.14), transparent 62%);
}
.quote-cta-text { position: relative; max-width: 44ch; }
.quote-cta-kicker {
  display: block; font-size: 0.7rem; font-weight: 700;
  letter-spacing: 0.2em; text-transform: uppercase; color: var(--orange);
}
.quote-cta-title {
  font-family: var(--font-display); font-weight: 700; color: var(--ink);
  font-size: clamp(1.35rem, 2.6vw, 2rem); line-height: 1.16; margin-top: 10px;
}
.quote-cta-sub {
  color: var(--muted); margin-top: 10px;
  font-size: 0.95rem; line-height: 1.65; font-weight: 450;
}
.quote-cta-act {
  position: relative; display: flex; flex-wrap: wrap;
  align-items: center; gap: 12px 18px;
}
.quote-cta-alt {
  font-size: 0.86rem; font-weight: 650; color: var(--muted);
  text-decoration: none; border-bottom: 1px solid transparent;
  min-height: 44px; display: inline-flex; align-items: center;
}
.quote-cta-alt:hover { color: var(--ink); border-bottom-color: var(--orange); }
@media (max-width: 700px) {
  .quote-cta { flex-direction: column; align-items: stretch; }
  .quote-cta-act { width: 100%; }
  .quote-cta-act .btn-hero { flex: 1 1 auto; justify-content: center; text-align: center; }
}
/* ---- commitments bar: the studio's terms, stated before they're asked ---- */
/* one panel divided by hairlines — four separate boxes read as chip soup.
   The 1px grid gap lets the panel background show through as the divider,
   so the rules stay correct however the columns wrap. */
.trust-bar {
  list-style: none;
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: 1px;
  /* full page column, same as the enquiry band it is paired with */
  margin: var(--section-gap) 0 0;
  background: var(--line);
  border: 1px solid var(--line); border-radius: var(--radius);
  overflow: hidden;
}
.trust-bar li {
  display: grid; gap: 5px; align-content: start;
  padding: clamp(20px, 2.4vw, 26px) clamp(18px, 2vw, 26px);
  background: #0b0a12;
}
.trust-bar li::before {
  content: ""; width: 22px; height: 2px; border-radius: 2px;
  background: var(--ember); margin-bottom: 10px;
}
.trust-bar strong {
  font-family: var(--font-display); font-size: 1.02rem;
  letter-spacing: -0.01em; color: var(--ink);
}
.trust-bar span { font-size: 0.82rem; line-height: 1.5; color: var(--muted); }
@media (max-width: 780px) { .trust-bar { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 420px) { .trust-bar { grid-template-columns: 1fr; } }
/* ============================================================
   mobile conversion bar — the only reachable CTA below 1100px
   (the chip rail scrolls horizontally behind a mask fade, so its
   quote/CTA chips are off-screen at every scroll position)
   ============================================================ */
.m-cta { display: none; }
@media (max-width: 1099px) {
  .m-cta {
    display: grid; grid-template-columns: 1.25fr 1fr; gap: 8px;
    /* env() keeps the bar above the iPhone home indicator; it resolves to 0
       everywhere else, so the desktop-class layout is unchanged */
    position: fixed; inset-inline: 12px; bottom: calc(12px + env(safe-area-inset-bottom, 0px)); z-index: 94;
    opacity: 0; transform: translateY(120%); pointer-events: none;
    transition: opacity var(--dur-ui) var(--ease-fluid), transform var(--dur-ui) var(--ease-fluid);
  }
  .m-cta.is-on { opacity: 1; transform: none; pointer-events: auto; }
  .m-cta a {
    display: flex; align-items: center; justify-content: center;
    min-height: 48px; padding: 0 14px; border-radius: var(--pill);
    font-family: var(--font-body); font-weight: 700; font-size: 0.8rem;
    line-height: 1.1; text-align: center; text-decoration: none;
  }
  .m-cta-main { background: var(--ember); color: #07070d; box-shadow: 0 6px 24px rgba(255, 107, 0, 0.4); }
  .m-cta-alt {
    background: rgba(7, 7, 13, 0.82); color: var(--ink); border: 1px solid var(--line);
    backdrop-filter: blur(12px); -webkit-backdrop-filter: blur(12px);
  }
  /* the chat launcher AND its panel must clear the bar — the panel is
     positioned independently, so moving only .agent-root drops the open
     panel onto the launcher */
  .agent-root { bottom: calc(84px + env(safe-area-inset-bottom, 0px)); }
  /* --agent-bottom / --agent-height come from agent.js, measured against
     visualViewport — the only thing that knows how much screen the on-screen
     keyboard has taken. The fallbacks are the keyboard-down resting state. */
  .agent-panel {
    inset-inline: 10px; width: auto;
    bottom: var(--agent-bottom, calc(150px + env(safe-area-inset-bottom, 0px)));
    height: var(--agent-height, min(560px, calc(100dvh - 190px - env(safe-area-inset-bottom, 0px))));
    max-height: none;
  }
  /* keyboard up: the launcher and the sticky CTA bar are behind it anyway,
     so the sheet takes the screen and the header stays in reach */
  .agent-panel.is-typing { inset-inline: 6px; }
  body { padding-bottom: calc(76px + env(safe-area-inset-bottom, 0px)); }
  /* pull the money chips to the front of the scroll rail */
  .chip--cta { order: -1; margin-inline-start: 0; }
  .chip[href$="quote.html"] { order: -1; }
  .chip-rail .chip-num { display: none; }
}
@media (max-width: 1099px) and (prefers-reduced-motion: reduce) {
  .m-cta { transition: none; }
}
/* the headline entrance is motion; with it suppressed the type must simply
   be there, at its resting weight, with nothing half-drawn */
@media (prefers-reduced-motion: reduce) {
  .mega-title,
  .mega-title .line > span { animation: none !important; }
  .mega-title .line > span { transform: none; filter: none; opacity: 1; }
  .mega-title { font-variation-settings: "wght" 800; }
}
html.motion-off .mega-title,
html.motion-off .mega-title .line > span { animation: none !important; }
html.motion-off .mega-title .line > span { transform: none; filter: none; opacity: 1; }
/* ============================================================
   FOOTER, STANDARDISED — the luminous grid horizon, the glowing
   orbs and the confetti are retired; what remains is the footer
   every business site has: a calm CTA row, link columns, a legal
   bar. Same markup on all 26 pages, so this is CSS-only.
   ============================================================ */
.v2-footer {
  background-image: none;
  border-radius: 0;
  padding: 56px 16px 26px;
}
.v2-footer::before { content: none; }
.confetti { display: none; }
.footer-hail { text-align: start; max-width: none; }
.footer-hail-title { font-size: clamp(1.5rem, 2.6vw, 2.1rem); }
.footer-hail-sub { margin-top: 8px; font-size: 0.95rem; }
.footer-hail-actions { justify-content: flex-start; margin-top: 20px; }
.footer-col-title {
  font-size: 0.7rem; font-weight: 700; letter-spacing: 0.16em;
  text-transform: uppercase; color: var(--muted);
}
.footer-col a { font-size: 0.9rem; line-height: 2.1; }
/* the billboard wordmark becomes a signature, not a headline */
.wordmark { padding: 8px 0 0; justify-content: flex-start; }
.wordmark img { max-width: 220px; opacity: 0.9; }
.footer-row {
  border-top: 1px solid var(--line);
  margin-top: 26px; padding-top: 18px;
  font-size: 0.8rem;
}
/* ============================================================
   THE PAPER CANVAS — body.paper flips one page to a warm white
   content canvas while the menu keeps its dark band. Everything
   var-driven flips itself; the rules below catch the hardcoded
   dark surfaces.
   ============================================================ */
body.paper {
  background-color: #f7f5f1;
  background-image:
    radial-gradient(900px 600px at 85% -5%, rgba(168, 102, 255, 0.07), transparent 60%),
    radial-gradient(800px 600px at -10% 20%, rgba(255, 107, 0, 0.05), transparent 55%),
    radial-gradient(700px 500px at 60% 110%, rgba(0, 200, 255, 0.05), transparent 60%);
  --ink: #17120c;
  --muted: #6b6353;
  --line: rgba(23, 18, 12, 0.15);
  --glass: rgba(23, 18, 12, 0.045);
}
/* the menu keeps its dark ground: a fixed band behind rail + brand mark */
@media (min-width: 1100px) {
  body.paper::before {
    content: ""; position: fixed; top: 0; bottom: 0; inset-inline-start: 0;
    width: calc(var(--rail-w) - 12px);
    background: #0b0a12;
    z-index: 5;
  }
}
/* below the rail breakpoint the brand mark sits in the flow — give the logo
   its dark chip back so it stays legible on paper */
@media (max-width: 1099px) {
  body.paper .brand-mark {
    background: #0b0a12; border-radius: 14px; padding: 8px 12px;
  }
}
/* hardcoded dark surfaces, re-grounded for paper */
body.paper .trust-bar li { background: #ffffff; }
/* quote wizard on paper: the two hardcoded dark-world surfaces */
body.paper .q-step { background: rgba(23, 18, 12, 0.14); }   /* was near-white glass — invisible on paper */
body.paper .q-bar  { background: rgba(255, 255, 255, 0.92); } /* mobile sticky bar — only the menu stays dark */
body.paper .block-card,
body.paper .art-card,
body.paper .tile {
  background: #ffffff;
  box-shadow: 0 10px 30px rgba(23, 18, 12, 0.06);
}
body.paper .pill {
  background: #ffffff; color: var(--ink);
  border-color: rgba(23, 18, 12, 0.25);
}
body.paper .kicker { background: #ffffff; }
/* the hero sheet dissolves into the canvas — the PAGE is the sheet now */
body.paper .ph-sheet {
  background: transparent; box-shadow: none;
  border-radius: 0; padding-inline: 0;
}
/* .page carries the dark canvas surface — on paper it must not */
body.paper .page { background: transparent; }
/* THE MENU STAYS DARK: the chips inherit the page tokens, so the paper ink
   turned their labels dark-on-dark. Re-pin the rail to its own dark-world
   palette — it lives on the dark band, not on the paper. */
body.paper .chip-rail .chip,
body.paper .brand-mark, 
body.paper .m-cta a {
  color: #f2f0fa;
}
body.paper .chip-rail .chip small,
body.paper .chip-rail .chip span { color: inherit; }
/* the legal pills were dark glass on dark — on paper they read as chips */
body.paper .footer-pills a {
  background: #ffffff; color: var(--ink);
  border: 1px solid rgba(23, 18, 12, 0.22);
}
/* footer on paper: flat, standard, dark logo variant not available in CSS —
   the light wordmark image would vanish, so the signature hides here */
body.paper .wordmark { display: none; }
body.paper .v2-footer { background: transparent; }
/* ============================================================
   THE LEDGER — inner-page hero. One system, 15 pages.
   Replaces THE INSTRUMENT (6 pages), the --art hero (7 pages)
   and the v2-hero (2 pages). Paper-first, var-driven: every
   token resolves from the canvas vars, so the same markup is
   ink-on-paper under body.paper and light-on-dark anywhere not
   yet flipped, with zero per-canvas rules.
   The section keeps .mega-hero so effects.js's reveal exemption
   ("heroes own their entrance") and the existing .mega-type
   entrance rule (delay .22s, above) keep firing. This block
   deliberately declares NO .mega-type entrance — one rule, one
   channel.
   ============================================================ */
.hero-ledger {
  --lh-ink: var(--ink);
  --lh-muted: var(--muted);
  --lh-line: var(--line);
  --lh-accent: var(--orange);
  display: block;
  position: relative;
  padding-block: clamp(46px, 8vh, 104px) clamp(34px, 5vh, 64px);
}
/* ---------- masthead row: kicker · hairline · jump ---------- */
.lh-mast {
  display: grid; grid-template-columns: auto minmax(16px, 1fr) auto;
  align-items: center; gap: 14px; margin: 0;
}
.lh-kicker {
  display: inline-flex; align-items: center; gap: 10px;
  font-family: var(--font-display);
  font-size: 0.72rem; font-weight: 700; letter-spacing: 0.22em;
  text-transform: uppercase; color: var(--lh-muted);
}
/* .lh-kicker is deliberately NOT .kicker: body.paper .kicker is a
   white chip, and the ledger kicker must stay bare type. */
.lh-kicker::before {
  content: ""; flex: none; width: 8px; height: 8px; border-radius: 50%;
  background: var(--lh-accent);
}
.lh-hair { height: 1px; background: var(--lh-line); }
.lh-jump {
  display: inline-flex; align-items: center; min-height: 44px;
  font-size: 0.74rem; font-weight: 700; letter-spacing: 0.02em;
  color: var(--lh-muted); text-decoration: none; white-space: nowrap;
  transition: color var(--dur-ui) var(--ease-fluid);
}
.lh-jump:hover { color: var(--lh-accent); }
.lh-jump:focus-visible { outline: 2px solid var(--lh-accent); outline-offset: 3px; border-radius: 6px; }
/* ---------- the headline ----------
   13 pages keep .mega-title + .line spans (Bricolage stack, line
   reveal and weight morph at their existing rules fire as-is).
   The two data-en/data-ar pages carry a bare h1 — this selector
   dresses it identically without requiring a class. */
.hero-ledger h1 {
  font-family: var(--font-display);
  font-weight: 800; font-synthesis-weight: none;
  font-size: clamp(2.55rem, 8.2vw, 6.2rem);
  line-height: 0.97; letter-spacing: -0.035em;
  color: var(--lh-ink); max-width: 22ch; text-wrap: balance;
  margin-top: clamp(22px, 4vh, 40px);
}
/* flat ember accent (home's .ph-accent grammar) — must reset the
   gradient-clip that .mega-title .accent applies above */
.hero-ledger h1 .accent {
  background: none; -webkit-background-clip: initial; background-clip: initial;
  color: var(--lh-accent);
}
/* ---------- the ember rule ---------- */
.lh-rule {
  position: relative; height: 2px; max-width: min(560px, 62%);
  margin-top: clamp(18px, 3vh, 30px);
  background: var(--lh-line);
}
.lh-rule::after {
  content: ""; position: absolute; inset: 0;
  background: var(--lh-accent);
  transform: scaleX(1);                /* authored rest = fully drawn */
  transform-origin: 0 50%;
}
html[dir="rtl"] .lh-rule::after { transform-origin: 100% 50%; }
/* ---------- sub + rotator ---------- */
.lh-sub {
  margin-top: clamp(18px, 3vh, 28px); max-width: 58ch;
  color: var(--lh-muted); font-size: 1.05rem; line-height: 1.7; font-weight: 480;
}
.hero-ledger .mega-type {              /* bare label — no chip, no glass */
  display: inline-flex; align-items: center; gap: 7px; margin-top: 16px;
  padding: 0; border: 0; background: none;
  font-family: var(--font-display); font-size: 0.92rem; font-weight: 700;
  letter-spacing: 0.01em; color: var(--lh-ink);
}
.hero-ledger .mega-type .type-word  { color: var(--lh-accent); }
.hero-ledger .mega-type .type-caret { background: var(--lh-accent); }
/* ---------- the shelf: CTAs + hard facts on one hairline ---------- */
.lh-shelf {
  display: flex; flex-wrap: wrap; align-items: center; gap: 16px 28px;
  margin-top: clamp(28px, 4.5vh, 44px);
  padding-block-start: 20px;
  border-block-start: 1px solid var(--lh-line);
}
.lh-ctas { display: flex; flex-wrap: wrap; gap: 12px 14px; }
.lh-ghost {
  display: inline-flex; align-items: center; min-height: 48px; padding: 0 24px;
  border-radius: var(--pill);
  border: 1.5px solid rgba(23, 18, 12, 0.3);
  border-color: color-mix(in srgb, var(--lh-ink) 30%, transparent);
  color: var(--lh-ink); font-weight: 700; font-size: 0.92rem; text-decoration: none;
  transition: border-color var(--dur-ui) var(--ease-fluid), color var(--dur-ui) var(--ease-fluid);
}
.lh-ghost:hover { border-color: var(--lh-accent); color: var(--lh-accent); }
.lh-facts {
  list-style: none; margin: 0; padding: 0; margin-inline-start: auto;
  display: flex; flex-wrap: wrap; gap: 8px 30px;
}
.lh-facts li { font-size: 0.86rem; color: var(--lh-muted); }
.lh-facts b {
  font-family: var(--font-display); font-weight: 800;
  color: var(--lh-ink); margin-inline-end: 6px;
}
/* ---------- entrance: shared system only ----------
   .mega-type is intentionally absent (existing rule, delay .22s).
   .mega-title lines run their own reveal (60/175/290ms). The
   bilingual pages' bare h1 gets a plain rise at the same beat. */
html.motion-on .hero-ledger .lh-mast,
html.motion-on .hero-ledger .lh-sub,
html.motion-on .hero-ledger .lh-shelf { animation: hero-rise 0.7s var(--ease-fluid) both; }
html.motion-on .hero-ledger h1:not(.mega-title) { animation: hero-rise 0.7s var(--ease-fluid) 0.06s both; }
html.motion-on .hero-ledger .lh-sub   { animation-delay: 0.18s; }
html.motion-on .hero-ledger .lh-shelf { animation-delay: 0.30s; }
/* ---------- the one scroll move: the rule draws ----------
   scroll(root), not view(): these heroes sit at document top, so a
   view() timeline is mid-range on load (see the SCROLL EFFECTS
   header above). Progress = scrollY / 42vh — deterministic, starts
   at exactly 0. Gate is html:not(.motion-off) so it works JS-off.
   Engines without scroll timelines never match this block and keep
   the authored scaleX(1) — same from{} exception hi-fill used. */
@supports (animation-timeline: scroll()) {
@media (prefers-reduced-motion: no-preference) {
  html:not(.motion-off) .lh-rule::after {
    animation: lh-draw linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 42vh;
  }
}}
@keyframes lh-draw { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* ---------- kill switches (mirror the instrument's) ---------- */
html.motion-off .hero-ledger *,
html.motion-off .hero-ledger *::before,
html.motion-off .hero-ledger *::after { animation: none !important; }
@media (prefers-reduced-motion: reduce) {
  .hero-ledger *,
  .hero-ledger *::before,
  .hero-ledger *::after { animation: none !important; }
}
/* ---------- color-mix floor ---------- */
@supports not (color: color-mix(in srgb, red, blue)) {
  .lh-ghost { border-color: rgba(23, 18, 12, 0.3); }
}
/* ---------- 640px: mast stacks so nothing truncates ---------- */
@media (max-width: 640px) {
  .lh-mast {
    grid-template-columns: minmax(16px, 1fr) auto;
    grid-template-areas: "kick kick" "hair jump"; row-gap: 10px;
  }
  .lh-kicker { grid-area: kick; }
  .lh-hair   { grid-area: hair; }
  .lh-jump   { grid-area: jump; }
  .lh-rule   { max-width: 72%; }
}
/* ---------- 480px: the shelf stacks, thumb-first ---------- */
@media (max-width: 480px) {
  .lh-kicker { font-size: 0.66rem; letter-spacing: 0.16em; }
  .lh-ctas { width: 100%; }
  .lh-ctas .btn-hero, .lh-ctas .lh-ghost {
    flex: 1 1 auto; justify-content: center; text-align: center;
  }
  .lh-facts { margin-inline-start: 0; gap: 6px 22px; }
}
/* ============================================================
   the 3D hero field — canvas layer built by hero-3d.js.
   The canvas floats OVER the hero (shapes are placed against the
   measured text rects, so they never sit on copy) and bleeds past
   the hero's bottom edge so the field reads as floating on the
   page, not boxed in a section. pointer-events: none keeps every
   CTA under it clickable.
   ============================================================ */
/* The hero must sit above its following sibling or the bleed clips.
   Specificity note: these heroes are direct children of .page, where
   `.page:not(.admin-page) > *` sets z-index: 1 —
   a bare class selector would silently lose to it. */
.page:not(.admin-page) > .paper-hero,
.page:not(.admin-page) > .hero-ledger,
.page:not(.admin-page) > .mega-hero,
.page:not(.admin-page) > .v2-hero { z-index: 2; }
.article-head, .lesson-head { position: relative; z-index: 2; }
