/* ==========================================================================
   Jareed landing page
   --------------------------------------------------------------------------
   Fourth page in the duroob house style, after PropIntel, e-tender and Hatif,
   built the same way: duroob tokens, then duroob components, then this file
   for what is specific to the page.

   COLOUR IS THE HOUSE'S. The indigo ramp, the ground semantics, the accent
   mapping light and dark and the drenched recipe are byte for byte the ones
   in css/hatif.css, css/propintel.css and css/etender.css. Only the product
   prefix differs: --jr-accent.

   What this page has that its sisters do not is PICTURES. Jareed sells
   rendered, unbuilt buildings, so the one place the page spends its boldness
   is the photograph. Everything around it is held quiet: Geist, hairlines,
   indigo, and the picture framed in the same window chrome the sisters put
   their terminals in. The studio's previous site set Cormorant Garamond on a
   warm cream with all-caps labels; none of that survives, and the renders do
   the persuading.
   ========================================================================== */

.page {
  /* ---------- The accent: indigo, PropIntel's ----------
     Sampled out of the fluted-glass texture, whose signature tone is #1D1E30,
     and drifted toward duroob purple, so the dark end IS the glass and the
     light end reads as family with purple. Hue 248 to 262. Twelve steps,
     byte for byte the ones in css/propintel.css. */
  --indigo-50:   #F7F4FA;
  --indigo-100:  #EBE5F5;
  --indigo-200:  #D2C6EB;
  --indigo-300:  #B29EE0;
  --indigo-400:  #8D70D7;
  --indigo-500:  #6642CD;
  --indigo-600:  #4D2EAD;
  --indigo-700:  #3B2687;
  --indigo-800:  #2D2065;
  --indigo-900:  #201943;
  --indigo-950:  #18132F;
  --indigo-1000: #0D0B19;
  /* The house re-cut: indigo's values under purple's names, nothing downstream
     renamed. All three pages carry it, so the viewport chrome and the inverted
     rows are the same hue everywhere instead of e-tender alone being indigo.
     --purple-600 is deliberately NOT aliased: --accent-primary reads it, and
     that button is still duroob purple: semantic/accent primary in Figma. */
  --purple-200:  var(--indigo-200);
  --purple-300:  var(--indigo-300);
  --purple-700:  var(--indigo-700);
  --purple-800:  var(--indigo-800);
  --purple-950:  var(--indigo-950);
  --purple-1000: var(--indigo-1000);

  /* Cool neutral ground. A near-white with the faintest lavender cast, so
     indigo is the only chroma in the frame and the page blends with the dark
     bands. */
  --bg:             #F4F4F7;
  --surface:        color-mix(in srgb, var(--periwinkle-100) 30%, #E9E9EE);
  --border:         color-mix(in srgb, var(--neutral-200) 62%, #E9E9EE);
  --border-control: color-mix(in srgb, var(--neutral-500) 88%, #E9E9EE);
  /* A hairline has to be visible to be a divider. This was neutral-100
     at 55 percent over the page, which landed on #EDEDEF against a
     #F4F4F7 ground: seven levels, invisible at arm's length, so two
     light sections running back to back read as one. Ten percent of the
     ground colour gives #DEDEE3 and carries the family tint. */
  --divider:        color-mix(in srgb, var(--indigo-950) 10%, #F4F4F7);

  /* Semantic, light ground. Same mapping as --pi-accent and friends. */
  --jr-accent:      var(--indigo-600);   /* 8.1:1 on the ground */
  --jr-accent-deep: var(--indigo-800);
  --jr-line:        var(--indigo-600);

  /* The dark band base under the photographic bands: indigo-950, which is the
     step PropIntel's --pi-ground points at. The ramp's dark end was sampled
     from this photograph, so tinting the photograph with it cannot fight it. */
  --jr-ground:      var(--indigo-950);

  /* Softened panel corner: enough curve to stop reading as a wireframe, short
     of a rounded UI. Controls take it too, so nothing on the page is a pill. */
  --jr-cut: 8px;

  /* A flat scrim laid over the finished glass band, the way an overlay sits
     over a modal. The texture and its gradient are untouched underneath; this
     one value is the whole dial. 0.40 is the sisters' setting and it is this
     page's too. Lower it for more glass, raise it for more contrast. */
  --glass-modal:    0.18;

  /* One rhythm for the gap between a section heading and the block it
     introduces, and one optical nudge for a standfirst set beside a title. */
  --jr-head-gap: var(--space-8);
  --jr-optical: .35rem;

  /* Grain over the wash. The same plate the drenched bands use, so the whole
     page is one material rather than two: photographic where it is dark,
     the same tooth where it is light. It sits in the background layer rather
     than as a fixed overlay, so any section with its own ground paints over
     it and the dark bands are not grained twice. soft-light keeps it as
     texture; multiply would dirty the wash. */
  background-color: var(--bg);
  background-image: url("../assets/duroob-texture-grain.jpg");
  background-size: 620px auto;
  background-blend-mode: soft-light;
  color: var(--ink);
  font: var(--text-body);
}

/* Semantic, the Drenched bands. The same two steps up PropIntel takes. */
[data-theme="dark"] {
  --bg: var(--indigo-950);
  --jr-accent:      var(--indigo-300);   /* 7.6:1 on the band */
  --jr-accent-deep: var(--indigo-200);
  --jr-line:        var(--indigo-300);
  /* One dark value set, shared by every dark surface on all three pages and by
     the Drenched mode of duroob/color in Figma. The shared file's dark theme
     puts neutral greys here; on this ground a grey hairline reads as dirt, and
     having the photographic band, the flat ink band and the terminal each
     carry their own value is what let the three pages drift apart. */
  --ink-secondary: var(--indigo-50);
  --border:  color-mix(in srgb, var(--indigo-300) 20%, transparent);
  --divider: color-mix(in srgb, var(--indigo-300) 14%, transparent);
}

*, *::before, *::after { box-sizing: border-box; }
html { scroll-behavior: smooth; }
/* Jumped-to sections start clear of the top edge instead of flush against it. */
#build, #devices, #personal, #insight, #about, #contact { scroll-margin-top: var(--space-8); }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }
body { margin: 0; -webkit-font-smoothing: antialiased; text-rendering: optimizeLegibility; }
a { color: inherit; text-decoration: none; }
::selection { background: color-mix(in srgb, var(--jr-accent) 24%, transparent); }
/* duroob.css rings the controls it owns; plain links are left with the browser
   default, which belongs to no design system. */
a:focus-visible { outline: 2px solid var(--focus-ring); outline-offset: 3px;
  border-radius: 2px; }
img, svg { max-width: 100%; }

/* Arabic takes the Arabic face, everywhere, automatically. The token set has
   carried Alexandria and a full --text-*-ar scale all along and nothing was
   reaching for it, so Arabic set on this page fell through Geist to whatever
   the system had. A page that claims to speak Arabic naturally cannot render
   Arabic in a fallback: it is the first thing a native reader sees.

   Scoped under .page for specificity, not for reach: every component here sets
   its type with the `font:` SHORTHAND, which carries a family, so a bare
   :lang(ar) ties on specificity and loses to whichever component rule happens
   to come later in the file. .page buys one class and settles it for good. */
.page :lang(ar) { font-family: var(--font-arabic); }

/* ---------- Measure ----------
   .shell owns the page gutter so a background can run edge to edge while its
   content stays on the measure. */
.shell { max-width: 1200px; margin: 0 auto; padding-inline: var(--space-6); }
@media (min-width: 900px) { .shell { padding-inline: var(--space-8); } }

/* Sections do not all weigh the same, so they do not all get the same
   interval. Every non hero section ran padding-block 64px and every head ran
   margin-bottom 32px: six bands of identical height and one repeated gap, which
   is what made the page read flat however the contents were arranged. Three
   weights now, and more space above a heading than below it, so a section
   opens rather than simply starting. */
section { --band: var(--space-8); padding-block: var(--band); }
@media (min-width: 900px) {
  section { --band: var(--space-16); padding-block: calc(var(--band) * 1.35) var(--band); }
  /* The two that carry the product get air. The supporting runs stay tighter,
     which is what makes the air read as a choice. */
  .personal { --band: calc(var(--space-16) * 1.4); }
  .devices { --band: var(--space-16); }
}

/* Sections divide on a full-bleed hairline, so the break reads across the whole
   page. The drenched bands carry their own edge and are left out. */
main > section:not(.drenched) + section:not(.drenched) { border-top: 1px solid var(--divider); }

/* ---------- Section heads ---------- */
.sechead { margin: 0 0 var(--jr-head-gap); }
.sechead .sec { margin: 0 0 var(--space-4); }
.sechead .lede { margin: 0; color: var(--ink-secondary); font: var(--text-body-large); }
/* Title above, standfirst below, always. The two-column head (title left,
   standfirst right on one line) is retired on this page. */
.sechead__in { display: block; }
.sechead .sec { margin: 0 0 var(--space-4); max-width: 20ch; }
.sechead .lede { max-width: 60ch; padding-top: 0; }

h2.sec { font: var(--text-h1); letter-spacing: -0.025em; margin: 0 0 var(--space-6);
  max-width: 22ch; text-wrap: balance; }
@media (max-width: 700px) { h2.sec { font: var(--text-h2); letter-spacing: -0.015em; } }
p.lede { font: var(--text-body-large); color: var(--ink-secondary); margin: 0; max-width: 68ch; }

/* ---------- The ground, shared by the hero and the close ----------
   Three layers, bottom up: the fluted glass photograph on the element itself, a
   grain plate over it in overlay, then one dim so type sits clear of both. The
   texture is duroob's own: the file the brand book names for dark hero
   surfaces, and the same one both sister pages use. */
.drenched { position: relative; isolation: isolate; overflow: hidden;
  color: var(--ink);
  background-image: url("../assets/duroob-texture-fluted-glass.jpg");
  background-size: cover; background-position: center; }

.drenched::before { content: ""; position: absolute; inset: 0; z-index: -2;
  background-image: url("../assets/duroob-texture-grain.jpg");
  background-size: cover; background-position: center;
  mix-blend-mode: overlay; opacity: .62; pointer-events: none; }

.drenched::after { content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(0deg,
      color-mix(in srgb, var(--indigo-1000) calc(var(--glass-modal) * 100%), transparent),
      color-mix(in srgb, var(--indigo-1000) calc(var(--glass-modal) * 100%), transparent)),
    /* A tint over the photograph, not a drench. This ran 44/60/72 percent of
       the ground under a scrim at the full 40 percent, and between them they
       buried the picture: the band read as flat indigo and the fluting never
       showed.

       Two things buy the light back. The texture ships mirrored, so the
       photograph's navy half falls under the copy column and its silver half
       under the call card, which wants a bright ground anyway; unmirrored, the
       hero lede sat on the brightest ribs in the frame at 3.3:1. And the dim
       now runs densest at the top, where the nav sits on thin air, instead of
       densest at the bottom.

       Measured on the rendered band: nav and lede in indigo-50 at 4.9:1 and
       16:1, the h1 at 7.9:1. The nav is what binds: thin the 50 percent top
       stop and it goes under the 4.5:1 AA floor first. All three pages run
       the same setting. */
    linear-gradient(175deg,
      color-mix(in srgb, var(--jr-ground) 50%, transparent) 0%,
      color-mix(in srgb, var(--jr-ground) 30%, transparent) 55%,
      color-mix(in srgb, var(--jr-ground) 20%, transparent) 100%); }

/* A flat dark band. The page already spends the fluted glass photograph on the
   hero and the close, and a third use would make it wallpaper rather than an
   event. This is the plain version: the same ground colour, no texture, so the
   run of sections alternates light and dark without the band competing with
   the two that are meant to. */
.band--ink { background: var(--indigo-1000); color: var(--ink); }
main > section.band--ink + section, main > section.band--ink { border-top: 0; }

/* ---------- Navigation, inside the hero band ----------
   It lies over the hero rather than on it: no fill of its own, no shadow, and
   it does not stick on scroll. */
.nav { padding-block: var(--space-4); border-bottom: 1px solid color-mix(in srgb, var(--neutral-50) 14%, transparent); }
.nav__in { display: flex; align-items: center; gap: var(--space-8); }
.brand { display: flex; align-items: baseline; gap: var(--space-1); }
.brand__name { font: var(--text-h3); letter-spacing: -0.02em; color: var(--ink); }
.nav__links { display: none; gap: var(--space-6); margin-inline-start: auto; }
.nav__links a { font: var(--text-body); color: var(--ink-secondary); }
.nav__links a:hover { color: var(--ink); }
@media (min-width: 900px) { .nav__links { display: flex; } }
.nav__cta { display: none; margin-inline-start: auto; }
@media (min-width: 620px) { .nav__cta { display: inline-flex; } }
@media (min-width: 900px) { .nav__cta { margin-inline-start: 0; } }

/* ---------- The window chrome ----------
   The frame the walkthrough port sits in, and the same frame PropIntel puts
   its terminal in: a dark application window, light content inside it. */
.viewport { position: relative; border-radius: var(--jr-cut); overflow: hidden;
  background: var(--indigo-950);
  border: 1px solid color-mix(in srgb, var(--indigo-300) 22%, transparent);
  box-shadow: 0 22px 52px rgba(13, 11, 25, 0.38);
  padding: var(--space-2); padding-top: 0; }
.viewport__bar { display: flex; align-items: center; gap: var(--space-3);
  height: 30px; padding: 0 var(--space-2); }
.viewport__dots { display: flex; gap: var(--space-1); }
.viewport__dots i { width: 6px; height: 6px; border-radius: 1px;
  background: color-mix(in srgb, var(--indigo-300) 46%, transparent); }

/* ---------- Hero ----------
   Hatif's hero, unchanged: copy leads, the window stands beside it, on the
   same fluted glass band all three sisters open on. The window carries the
   studio's own reel instead of a product panel. */
.hero { padding-block: 0 var(--space-16); }
.hero__in { display: grid; gap: var(--space-16); padding-top: var(--space-16); }
@media (min-width: 1000px) {
  /* 424 + 32 + 680 = 1136, the same measure the nav spans. The window takes
     the larger share: it carries the product here, so it is sized like a
     desktop screen rather than a side panel. */
  .hero__in { grid-template-columns: minmax(0, 424fr) minmax(0, 680fr);
    gap: var(--space-16) var(--space-8); align-items: center; }
}
.hero h1 { font: var(--text-display); letter-spacing: -0.03em; margin: 0 0 var(--space-6);
  max-width: 18ch; text-wrap: balance; }
@media (max-width: 900px) { .hero h1 { font: var(--text-h1); letter-spacing: -0.025em; } }
.hero__lede { font: var(--text-body-large); color: var(--ink-secondary);
  margin: 0 0 var(--space-8); max-width: 470px; }
.hero__actions { display: flex; flex-wrap: wrap; gap: var(--space-3); }

/* ---------- The window chrome ----------
   The frame every sister puts its product in. Here it frames renders. */
.viewport { position: relative; border-radius: var(--jr-cut); overflow: hidden;
  background: var(--indigo-950);
  border: 1px solid color-mix(in srgb, var(--indigo-300) 22%, transparent);
  box-shadow: 0 22px 52px rgba(13, 11, 25, 0.38);
  padding: var(--space-2); padding-top: 0; }
.viewport__bar { display: flex; align-items: center; gap: var(--space-3);
  height: 30px; padding: 0 var(--space-2); }
.viewport__dots { display: flex; gap: var(--space-1); }
.viewport__dots i { width: 6px; height: 6px; border-radius: 1px;
  background: color-mix(in srgb, var(--indigo-300) 46%, transparent); }
/* The stage inside the window: a render or a film, cropped to the frame. */
.shot { position: relative; overflow: hidden; aspect-ratio: 16 / 10;
  border-radius: calc(var(--jr-cut) - 1px); background: var(--indigo-1000); }
.shot img, .shot video { position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; display: block; }
.hero .shot { aspect-ratio: 16 / 10; }

/* ---------- Labels ----------
   The small capitals the sisters use for a structural label (e-tender's card
   labels, the footer's "Powered by"). One step, one weight, one tracking. */
.label { font: var(--text-caption); font-weight: 600; text-transform: uppercase;
  letter-spacing: 0.14em; color: var(--ink-secondary); margin: 0 0 var(--space-4); }

/* ---------- Commercial Solutions: a light head, then four scenes ----------
   The head sits on the page ground like every other section's. Under it the
   original page's set piece: a stage four windows tall that sticks for the
   length of itself, each solution taking the whole screen in turn. Scroll
   position only decides WHICH scene is up (js/scenes.js, an
   IntersectionObserver, no scroll listener); the change is a timed CSS
   transition, as on the sisters.

   Without the script nothing pins: the four scenes stack as full-width frames,
   each carrying its own caption. The resting state is the finished state. */
.build { padding-bottom: 0; }
.build__stage { --scenes: 4; position: relative; background: var(--indigo-1000); color: var(--ink); }
html[data-scenes="on"] .build__stage { height: calc(var(--scenes) * 100svh); }
.build__pin { position: relative; }
html[data-scenes="on"] .build__pin { position: sticky; top: 0; height: 100svh; overflow: hidden; }

/* The steps the observer watches. They span the pinned run only, measured at
   the middle of the window (half a window in from each end), so each scene
   gets an equal share of the time the stage is held. */
.build__steps { display: none; }
html[data-scenes="on"] .build__steps { display: grid; position: absolute; inset: 50svh 0;
  grid-template-rows: repeat(var(--scenes), minmax(0, 1fr)); pointer-events: none; }

/* A scene: the render, indigo scrims where type and the rail sit, the
   caption bottom left. */
.scene { position: relative; isolation: isolate; overflow: hidden; min-height: 86svh;
  display: flex; align-items: flex-end; }
.scene__img { position: absolute; inset: 0; z-index: -2; }
.scene__img img { display: block; width: 100%; height: 100%; object-fit: cover; }
.scene::after { content: ""; position: absolute; inset: 0; z-index: -1;
  background:
    linear-gradient(0deg, color-mix(in srgb, var(--indigo-1000) 86%, transparent) 0%,
      color-mix(in srgb, var(--indigo-1000) 26%, transparent) 40%, transparent 62%),
    linear-gradient(90deg, color-mix(in srgb, var(--indigo-1000) 40%, transparent) 0%, transparent 50%),
    /* The rail is a hairline on the right edge, and renders are brightest
       there as often as not: a white wall swallowed it. */
    linear-gradient(270deg, color-mix(in srgb, var(--indigo-1000) 55%, transparent) 0%, transparent 22%); }
.scene__cap { width: 100%; padding-bottom: var(--space-16); }
.scene__n { font: var(--text-caption); font-family: var(--font-mono); letter-spacing: 0;
  color: var(--ink-secondary); margin: 0 0 var(--space-3); }
/* The h2 step: the section title above the stage is the h1 step, so the scene
   names read as the items under it rather than competing with it. */
.scene__t { font: var(--text-h2); letter-spacing: -0.015em; margin: 0 0 var(--space-2); }
.scene__d { font: var(--text-body-large); color: var(--ink-secondary); margin: 0; max-width: 38ch; }

/* Pinned: the scenes stack in one frame and only the current one shows. */
html[data-scenes="on"] .build__scenes { position: absolute; inset: 0; }
html[data-scenes="on"] .scene { position: absolute; inset: 0; min-height: 0;
  opacity: 0; pointer-events: none; }
html[data-scenes="on"] .scene.is-on { opacity: 1; }

/* The rail: a hairline that fills a quarter per scene, and a dot per scene in
   the window chrome's square. */
.build__rail { display: none; }
html[data-scenes="on"] .build__rail { position: absolute; z-index: 2; top: 50%; translate: 0 -50%;
  right: max(var(--space-6), calc((100vw - 1200px) / 2 + var(--space-8)));
  display: grid; justify-items: center; gap: var(--space-6); }
.build__line { position: relative; width: 1px; height: 128px; overflow: hidden;
  background: color-mix(in srgb, var(--ink) 14%, transparent); }
.build__line::after { content: ""; position: absolute; inset: 0; background: var(--jr-accent);
  transform-origin: top; transform: scaleY(calc((var(--at, 0) + 1) / var(--scenes))); }
.build__dots { display: grid; gap: var(--space-4); }
.build__dots i { display: block; width: 6px; height: 6px; border-radius: 1px;
  background: color-mix(in srgb, var(--ink) 25%, transparent); }
.build__dots i.is-on { background: var(--jr-accent); transform: scale(1.35); }

@media (prefers-reduced-motion: no-preference) {
  html[data-scenes="on"] .scene { transition: opacity 900ms cubic-bezier(0.4, 0, 0.2, 1); }
  html[data-scenes="on"] .scene__img img { scale: 1.08;
    transition: scale 1800ms cubic-bezier(0.16, 1, 0.3, 1); }
  html[data-scenes="on"] .scene.is-on .scene__img img { scale: 1; }
  html[data-scenes="on"] .scene__cap > * { opacity: 0; translate: 0 12px;
    transition: opacity 300ms ease, translate 300ms ease; }
  html[data-scenes="on"] .scene.is-on .scene__cap > * { opacity: 1; translate: 0 0;
    transition: opacity 700ms cubic-bezier(0.16, 1, 0.3, 1), translate 700ms cubic-bezier(0.16, 1, 0.3, 1); }
  html[data-scenes="on"] .scene.is-on .scene__n { transition-delay: 250ms; }
  html[data-scenes="on"] .scene.is-on .scene__t { transition-delay: 330ms; }
  html[data-scenes="on"] .scene.is-on .scene__d { transition-delay: 410ms; }
  .build__line::after { transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1); }
  .build__dots i { transition: background-color 400ms ease, transform 400ms ease; }
}

/* ---------- One Experience. Any Device. ----------
   PropIntel's assurance row: not cards, columns told apart by a hairline, the
   mark leading each one at 96px and the name under it. Five across at full
   width, which is the only count that closes the row. */
.plats { list-style: none; margin: 0; padding: 0; display: grid; gap: 0; }
.pl { display: grid; justify-items: center; text-align: center; align-content: start;
  padding: var(--space-8) var(--space-6); }
.pl + .pl { border-top: 1px solid var(--divider); }
.pl__m { display: block; width: 96px; height: 96px; color: var(--jr-accent);
  margin: 0 0 var(--space-6); }
.pl__m svg { display: block; width: 100%; height: 100%; }
.pl__t { font: var(--text-h3); margin: 0; text-wrap: balance; }
@media (min-width: 720px) {
  .plats { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pl + .pl { border-top: 0; }
  .pl:nth-child(even) { border-left: 1px solid var(--divider); }
  .pl:nth-child(n+3) { border-top: 1px solid var(--divider); }
}
@media (min-width: 1100px) {
  .plats { grid-template-columns: repeat(5, minmax(0, 1fr)); }
  .pl:nth-child(n+3) { border-top: 0; }
  .pl:nth-child(even) { border-left: 0; }
  .pl + .pl { border-left: 1px solid var(--divider); }
}
.devices__note { font: var(--text-body-large); color: var(--ink-secondary);
  margin: var(--space-8) 0 0; }

/* ---------- Copy beside a window ----------
   Hatif's walkthrough grid: one third copy, two thirds window, the title on
   the window's top line and the standfirst dropped to the foot of the column.
   --flip puts the window first, so two in a row do not stack identically. */
.watch__grid { display: grid; gap: var(--space-8); }
.watch__copy .sec { max-width: 18ch; }
.watch__copy p.lede { margin: 0; max-width: 46ch; }
/* The copy is one block: label, title, standfirst, in that order and close
   together, centred against the window. Pushed apart to span the window's
   height (Hatif's walkthrough, where the copy is one line) it left a hole
   under every title, three sections running. */
.watch__copy { display: grid; gap: var(--space-6); align-content: start; }
.watch__copy .sec { margin: 0; }
@media (min-width: 960px) {
  .watch__grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
    gap: var(--space-16); align-items: center; }
  .watch__grid--flip { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .watch__grid--flip .watch__copy { order: 2; }
  .watch__copy p.lede { max-width: 40ch; }
}
.reads { list-style: none; margin: var(--space-4) 0 0; padding: 0;
  display: flex; flex-wrap: wrap; gap: var(--space-2); }

/* ---------- Who We Are: the render as the band ----------
   No window and no scrim: the facade render runs edge to edge behind the
   section and the copy is set light, straight on the picture. The section is
   data-theme="dark", so the copy takes the dark scope's inks. Decorative, so
   the image carries no alt: the copy says what the section is. */
.about { position: relative; isolation: isolate; overflow: hidden;
  min-height: min(82svh, 760px); display: flex; align-items: center;
  background: var(--indigo-1000); color: var(--ink); }
.about > .shell { width: 100%; }
.about__bg { position: absolute; inset: 0; z-index: -1; }
.about__bg img { display: block; width: 100%; height: 100%; object-fit: cover; object-position: 60% center; }
.about__copy { max-width: 520px; }
.about__copy .sec { margin: 0 0 var(--space-6); max-width: 14ch; }
.about__copy .lede { max-width: 44ch; }
@media (max-width: 899px) {
  .about { align-items: flex-start; min-height: 0; padding-bottom: 62vw; }
}

/* ---------- Close ---------- */
.close { text-align: center; }
.close h2 { font: var(--text-h1); letter-spacing: -0.025em; margin: 0 0 var(--space-8);
  text-wrap: balance; }
@media (max-width: 900px) { .close h2 { font: var(--text-h2); letter-spacing: -0.015em; } }

/* ---------- Footer ----------
   Hatif's and PropIntel's, unchanged. */
.foot { padding-block: var(--space-8); border-top: 1px solid var(--divider); }
.foot__in { display: flex; flex-wrap: wrap; gap: var(--space-4) var(--space-8);
  align-items: center; justify-content: space-between; }
.foot__mark { display: flex; flex-direction: column; gap: var(--space-1); }
.foot__lockup { height: 26px; width: auto; }
.foot__label { font: var(--text-caption); color: var(--ink-secondary); margin: 0;
  text-transform: uppercase; letter-spacing: 0.14em; }
.foot p.foot__note { font: var(--text-caption); color: var(--ink-secondary);
  margin: 0; text-align: end; }
.foot__copy { font: var(--text-caption); font-family: var(--font-mono); letter-spacing: 0;
  color: var(--ink-secondary); text-align: center;
  margin: var(--space-6) 0 0; padding-top: var(--space-6);
  border-top: 1px solid var(--divider); }

/* ---------- Motion ----------
   The resting state is the finished one. The hero plays on load; every other
   sequence plays once when its section arrives, keyed off is-in from
   js/reveal.js, the driver all three sisters share byte for byte. */
.page .dr-btn { transition: transform 160ms cubic-bezier(0.23, 1, 0.32, 1); }
.page .dr-btn:active { transform: translateY(1px); }

@keyframes jr-rise { from { opacity: 0; translate: 0 16px; } to { opacity: 1; translate: 0 0; } }
@keyframes jr-rise-m { from { opacity: 0; translate: 0 10px; } to { opacity: 1; translate: 0 0; } }
@keyframes jr-mark-rise { from { opacity: 0; translate: 0 28px; } to { opacity: 1; translate: 0 0; } }
@keyframes jr-wipe { from { clip-path: inset(0 0 100% 0); } to { clip-path: inset(0 0 0 0); } }

@media (prefers-reduced-motion: no-preference) {
  .hero__copy > *, .hero .viewport {
    animation: jr-rise 620ms cubic-bezier(0.16, 1, 0.3, 1) both; }
  .hero__copy > :nth-child(1) { animation-delay: 60ms; }
  .hero__copy > :nth-child(2) { animation-delay: 140ms; }
  .hero__copy > :nth-child(3) { animation-delay: 220ms; }
  .hero .viewport { animation-delay: 300ms; }

  /* Applied paused, started by is-in; with no driver, not applied at all. */
  html[data-reveal="on"] [data-reveal] :where(.pl__m, .pl__t, .watch .viewport, .about__bg img) {
    animation-play-state: paused; }
  html:not([data-reveal="on"]) [data-reveal] :where(.pl__m, .pl__t, .watch .viewport, .about__bg img) {
    animation-name: none; }
  html[data-reveal="on"] [data-reveal].is-in :where(.pl__m, .pl__t, .watch .viewport, .about__bg img) {
    animation-play-state: running; }

  /* --t is one percent of the section's sequence, as on the sisters. */
  .devices { --t: 24ms; }
  .pl:nth-child(1) { --i: 0; }
  .pl:nth-child(2) { --i: 1; }
  .pl:nth-child(3) { --i: 2; }
  .pl:nth-child(4) { --i: 3; }
  .pl:nth-child(5) { --i: 4; }

  .pl__m, .pl__t { animation-timing-function: cubic-bezier(0.16, 1, 0.3, 1);
    animation-fill-mode: both; }
  .pl__m { animation-name: jr-mark-rise;
    animation-delay: calc((8 + var(--i) * 8) * var(--t));
    animation-duration: calc(30 * var(--t)); }
  .pl__t { animation-name: jr-rise-m;
    animation-delay: calc((14 + var(--i) * 8) * var(--t));
    animation-duration: calc(28 * var(--t)); }

  /* A window wipes down its own height, because it is a screen. */
  .watch .viewport { animation: jr-wipe 700ms cubic-bezier(0.22, 1, 0.36, 1) both; }
  /* The band's render settles into place, the move the solution scenes make. */
  @keyframes jr-settle { from { scale: 1.06; } to { scale: 1; } }
  .about__bg img { animation: jr-settle 1800ms cubic-bezier(0.16, 1, 0.3, 1) both; }
}
