/* ==========================================================================
   ZerofyAI landing, desktop

   Palette, type and geometry taken from
   "ZerofyAI, Brand Identity Guidelines v1.1", pages 12, 13, 16 and 21.
   No gradients anywhere. Flat fields only.

   THE SKELETON
   Every section is a .row: full bleed, one hairline along its bottom edge,
   so horizontal rules run the whole width of the window. Inside each row sits
   a .rail: a centred column, capped at --frame, carrying a hairline on each
   side. Because the rows stack with no gap, those side hairlines line up into
   two continuous vertical lines down the entire page. That is the frame, and
   nothing is allowed outside it except the ground and the horizontal rules.

   A panel that should touch both vertical lines uses .rail--flush, which drops
   the inner padding but keeps the borders. The hero photograph, the statement
   band, the closing field and the footer all use it.

   Stacking order
     0  panel photographs
     1  content inside a panel
     3  sticky nav
   ========================================================================== */

:root{
  /* The four */
  --cream:#EFE6DE;
  --ink:#151515;
  --garnet:#5A2132;
  --deep:#300A14;

  /* Mixtures of the four, and nothing else */
  --cream-2:#E8DCD5;   /* second light field, garnet at 5%   */
  --ink-2:#6D5055;     /* secondary type on cream, deep 70%  */
  --on-ink:#9C9792;    /* secondary type on ink, cream 64%   */
  --rule:#D0C3BE;      /* hairlines and dividers, deep 16%   */

  /* Garnet to cream ladder, one step per product, brand page 21.
     Five products, five steps, in the manual's own order. */
  --ladder-1:#5A2132;  /* Unicorn */
  --ladder-2:#7A4551;  /* Capital */
  --ladder-3:#9A6971;  /* Astral  */
  --ladder-4:#BA8D92;  /* Streak+ */
  --ladder-5:#D9B1B2;  /* Lore    */

  /* The frame */
  --frame:1280px;
  --gutter:48px;
  --nav-h:66px;   /* the glass bar, filling the rail edge to edge */
  --hair:1px;

  --r-8:8px;
  --r-12:12px;
  --r-20:20px;

  /* Type, brand page 13 */
  --fs-display:clamp(46px,3.9vw,60px);
  --fs-h2:clamp(30px,2.5vw,40px);
  --fs-h3:28px;
  --fs-body:16px;
  --fs-caption:12px;

  /* Rhythm, matching the reference's 100px section padding */
  --sec:100px;
  --sec-tight:76px;

  /* Motion */
  --ease:cubic-bezier(.16,1,.3,1);
  --t-fast:140ms;
  --t-mid:560ms;

  /* The display face, for the Arabic type that sits on the photographs.
     Supplied by the owner. Arabic only, by instruction: the Latin headings
     stay on IBM Plex Sans. Falls back to the Arabic body face, never to a
     Latin serif, because the only thing it ever sets is Arabic. */
  --font-display:"Milan Display","IBM Plex Sans Arabic","IBM Plex Sans",sans-serif;
  --font-latin:"IBM Plex Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-arabic:"IBM Plex Sans Arabic","IBM Plex Sans",system-ui,sans-serif;
  --font-mono:"JetBrains Mono",ui-monospace,SFMono-Regular,Menlo,monospace;
}

*,*::before,*::after{box-sizing:border-box}

html{-webkit-text-size-adjust:100%;scroll-behavior:smooth;scrollbar-gutter:stable}

body{
  margin:0;
  background:var(--cream);
  color:var(--ink);
  font-family:var(--font-latin);
  font-size:var(--fs-body);
  line-height:1.5;
  letter-spacing:-.005em;
  -webkit-font-smoothing:antialiased;
  text-rendering:optimizeLegibility;
}

html[dir="rtl"] body{font-family:var(--font-arabic)}

img{display:block;max-width:100%;height:auto}
ul,ol{margin:0;padding:0;list-style:none}
h1,h2,h3,h4{margin:0;font-weight:600}
p{margin:0}
a{color:inherit;text-decoration:none}

/* Browser surfaces belong to the palette too. */
::selection{background:var(--garnet);color:var(--cream)}
:focus-visible{
  outline:2px solid var(--garnet);
  outline-offset:3px;
}
html{scrollbar-color:var(--rule) var(--cream)}

/* --------------------------------------------------------------------------
   The frame
   -------------------------------------------------------------------------- */

.row{
  position:relative;
  border-block-end:var(--hair) solid var(--rule);
}

.rail{
  max-width:var(--frame);
  margin-inline:auto;
  padding-inline:var(--gutter);
  border-inline:var(--hair) solid var(--rule);
}

/* Panels that must touch both vertical lines. */
.rail--flush{padding-inline:0}

/* Block padding always belongs to the rail. Put it on the row and the rail
   stops short of the row's edges, which punches a gap in both vertical
   lines at every section boundary. */
.section{padding-block:var(--sec)}
.section--tight{padding-block:var(--sec-tight)}

.caption{
  font-size:var(--fs-caption);
  font-weight:500;
  letter-spacing:.01em;
  color:var(--ink-2);
}

/* Screen-reader-only, for text that exists but is not drawn. */
.sr{
  position:absolute;
  width:1px;
  height:1px;
  margin:-1px;
  padding:0;
  overflow:hidden;
  clip-path:inset(50%);
  white-space:nowrap;
  border:0;
}

/* --------------------------------------------------------------------------
   Hero kicker. One word of the line changes on a timer.

   The swap is a blur dissolve rather than a slide: the outgoing word loses
   focus and lifts a few pixels as it goes, the incoming one arrives out of
   focus from just below. Nothing travels far enough to read as movement,
   which is what keeps a permanent loop from becoming the loudest thing on
   the page.

   The transition is switched off for one frame between the two states, so the
   element snaps to the incoming start rather than animating from the outgoing
   end. Without that the word would visibly slide from above to below while
   invisible, and arrive late.
   -------------------------------------------------------------------------- */

/* Set at the size of the lede below it rather than as a tracked-caps label.
   At 18px the uppercase treatment stopped being a kicker and started being a
   second headline, which is the thing the manual warns about. */
.eyebrow.kicker{
  font-size:18px;
  font-weight:400;
  letter-spacing:-.005em;
  text-transform:none;
}
html[dir="rtl"] .eyebrow.kicker{font-size:18px;letter-spacing:0}

.kicker__w{
  display:inline-block;
  color:var(--garnet);
  /* The rule is part of the word, not a box under it, so it re-measures
     itself on every swap and blurs away with the letters it belongs to. */
  text-decoration:underline;
  text-decoration-thickness:1.5px;
  text-underline-offset:5px;
  transition:opacity 260ms var(--ease),
             filter 260ms var(--ease),
             transform 260ms var(--ease);
}
.kicker__w.is-out{opacity:0;filter:blur(5px);transform:translateY(-4px)}
.kicker__w.is-in{opacity:0;filter:blur(5px);transform:translateY(4px)}

.eyebrow{
  font-size:var(--fs-caption);
  font-weight:500;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--ink-2);
}
html[dir="rtl"] .eyebrow{letter-spacing:0;text-transform:none;font-size:13px}

.h2{
  font-size:var(--fs-h2);
  text-wrap:balance;
  letter-spacing:-.018em;
  line-height:1.14;
}
html[dir="rtl"] .h2{letter-spacing:0;line-height:1.34}

.skip{
  position:fixed;
  inset-block-start:-100px;
  inset-inline-start:16px;
  z-index:60;
  background:var(--ink);
  color:var(--cream);
  padding:10px 16px;
  border-radius:var(--r-8);
  font-size:14px;
  transition:inset-block-start var(--t-fast) var(--ease);
}
.skip:focus{inset-block-start:16px}

/* --------------------------------------------------------------------------
   Entrance. One authored moment on load: the photograph wipes down behind
   copy that settles up into it. The frame itself never animates; it is the
   ruling of the page and reads as something that was always there.
   -------------------------------------------------------------------------- */

.reveal{opacity:0;transform:translateY(14px)}
body.is-ready .reveal{
  animation:reveal var(--t-mid) var(--ease) forwards;
  animation-delay:var(--d,0ms);
}
@keyframes reveal{to{opacity:1;transform:none}}

.hero__photo{clip-path:inset(0 0 100% 0)}
body.is-ready .hero__photo{
  animation:wipe 900ms var(--ease) 80ms forwards;
}
@keyframes wipe{to{clip-path:inset(0 0 0 0)}}

/* Once the entrance has played, drop the animations so nothing stays
   promoted to its own compositing layer for the life of the page. */
body.is-done .reveal{animation:none;opacity:1;transform:none}
body.is-done .hero__photo{animation:none;clip-path:none}

/* --------------------------------------------------------------------------
   Nav. Sits on the paper, inside the frame, above everything.
   -------------------------------------------------------------------------- */

/* The bar is one sheet of glass filling the rail from one vertical hairline
   to the other, so the header reads as a band of the frame rather than an
   object floating on top of it. The row keeps its own hairline along the
   bottom edge, and that is the point: the rule runs the full width of the
   window while the rail's two verticals run from the very top of the page
   down through the bar. All three cross, and every line carries on past the
   crossing. Those crossings are what tie the header into the skeleton.

   The header element itself stays transparent. The glass needs the page
   visible behind it for the backdrop filter to have anything to work with.

   Every highlight here is cream at a high alpha rather than white. The glass
   is a departure from the manual's flat-field rule, taken deliberately at the
   owner's instruction; keeping it inside the four hues is what stops it
   becoming a second palette. */
.nav{
  position:sticky;
  inset-block-start:0;
  z-index:3;
  background:transparent;
}
/* The rail keeps its verticals but hands its gutter to the glass, so the
   sheet touches both lines while the content inside it still sits on the same
   48px margin as every other section. */
.nav__inner{padding-inline:0}

.navglass{
  display:grid;
  grid-template-columns:1fr auto 1fr;
  align-items:center;
  height:var(--nav-h);
  padding-inline:var(--gutter);
  background:linear-gradient(180deg,rgba(239,230,222,.82),rgba(239,230,222,.62));
  -webkit-backdrop-filter:blur(22px) saturate(180%);
          backdrop-filter:blur(22px) saturate(180%);
  /* No outline ring. The rail hairlines already sit on both edges and the
     row's rule sits on the bottom one; a fourth line would double them. */
  box-shadow:inset 0 1px 0 rgba(239,230,222,.9);
}

/* --------------------------------------------------------------------------
   Lockup. The supplied artwork, cropped to its own bounds and tinted once at
   build time into the two grounds it has to sit on: ink for the header, cream
   for the footer. It arrived as white on transparency, which is invisible on
   paper, and a PNG cannot take currentColor the way the drawn version could.
   Tinting two files beats a CSS filter, which would have to invert a
   photograph of type and would land somewhere near the colour rather than on
   it.
   -------------------------------------------------------------------------- */

.lockup{display:inline-flex;align-items:center;color:var(--ink)}
.lockup__art{height:26px;width:auto;display:block}

.nav__links{
  display:flex;
  gap:34px;
  font-size:15px;
  font-weight:500;
  color:var(--ink-2);
}
.nav__links a{transition:color var(--t-fast) var(--ease)}
.nav__links a:hover{color:var(--ink)}

.nav__actions{
  justify-self:end;
  display:flex;
  align-items:center;
  gap:12px;
}

/* --------------------------------------------------------------------------
   Nav menus. Three of them, and none of their items is an anchor on this
   page: they lead to the docs, to the five live app sites, or to the
   waitlist. A nav item that scrolls you down the page you are already on is
   not navigation.

   The popover is the header's own glass, one step smaller and one step more
   opaque, so it reads as the bar folding down rather than a card appearing
   over it. It opens on hover with a short intent delay and on focus, which is
   what makes it usable from the keyboard as well as the mouse.
   -------------------------------------------------------------------------- */

.menu{position:relative}

.menu__btn{
  display:flex;
  align-items:center;
  gap:7px;
  padding:8px 0;
  font:inherit;
  font-size:15px;
  font-weight:500;
  letter-spacing:-.01em;
  color:var(--ink-2);
  background:none;
  border:0;
  cursor:pointer;
  transition:color var(--t-fast) var(--ease);
}
.menu__btn:hover,
.menu.is-open .menu__btn{color:var(--ink)}
html[dir="rtl"] .menu__btn{letter-spacing:0}

.menu__chev{
  width:14px;
  height:14px;
  fill:none;
  stroke:currentColor;
  stroke-width:1.8;
  stroke-linecap:round;
  stroke-linejoin:round;
  opacity:.7;
  transition:transform 200ms var(--ease);
}
.menu.is-open .menu__chev{transform:rotate(180deg)}

.menu__pop{
  position:absolute;
  inset-block-start:calc(100% + 14px);
  inset-inline-start:-18px;
  z-index:5;
  width:320px;
  padding:8px;
  border-radius:var(--r-20);
  background:linear-gradient(180deg,rgba(239,230,222,.94),rgba(239,230,222,.88));
  -webkit-backdrop-filter:blur(22px) saturate(180%);
          backdrop-filter:blur(22px) saturate(180%);
  box-shadow:
    inset 0 1px 0 rgba(239,230,222,.9),
    inset 0 0 0 1px rgba(208,195,190,.6),
    0 18px 40px rgba(48,10,20,.16);
  opacity:0;
  visibility:hidden;
  transform:translateY(-6px);
  transition:opacity 200ms var(--ease),
             transform 200ms var(--ease),
             visibility 200ms;
}
.menu.is-open .menu__pop{
  opacity:1;
  visibility:visible;
  transform:none;
}

/* The gap between the button and the panel would drop the hover halfway
   across. This bridges it without moving anything. */
.menu__pop::before{
  content:"";
  position:absolute;
  inset-block-start:-14px;
  inset-inline:0;
  height:14px;
}

.menu__item{
  display:flex;
  flex-direction:column;
  gap:3px;
  padding:11px 14px;
  border-radius:var(--r-12);
  transition:background var(--t-fast) var(--ease);
}
.menu__item:hover,
.menu__item:focus-visible{background:var(--cream-2)}
.menu__t{font-size:15px;font-weight:600;letter-spacing:-.01em;color:var(--ink)}
.menu__d{font-size:13px;color:var(--ink-2);line-height:1.45}
html[dir="rtl"] .menu__t,
html[dir="rtl"] .menu__d{letter-spacing:0}

/* The apps menu carries each product's mark and its ladder step. */
.menu__pop--apps{width:340px}
.menu__app{
  display:grid;
  grid-template-columns:auto 1fr;
  align-items:center;
  gap:14px;
  padding:10px 14px;
  border-radius:var(--r-12);
  transition:background var(--t-fast) var(--ease);
}
.menu__app:hover,
.menu__app:focus-visible{background:var(--cream-2)}
.menu__app img{height:26px;width:auto;opacity:.85}
.menu__app:hover img{opacity:1}
.menu__n{
  font-size:15px;
  font-weight:600;
  letter-spacing:-.01em;
  color:var(--ink);
}
html[dir="rtl"] .menu__n{font-family:var(--font-latin);direction:ltr;unicode-bidi:isolate}
.menu__c{font-size:13px;color:var(--ink-2)}
html[dir="rtl"] .menu__c{letter-spacing:0}

/* docs.html has no menus, only two plain links. */
.nav__plain{
  font-size:15px;
  font-weight:500;
  color:var(--ink-2);
  transition:color var(--t-fast) var(--ease);
}
.nav__plain:hover{color:var(--ink)}

/* --------------------------------------------------------------------------
   Docs page
   -------------------------------------------------------------------------- */

.doc__title{margin-block-start:18px}
.doc__title-lede{max-width:62ch}

.doc{
  display:grid;
  grid-template-columns:240px 1fr;
  gap:72px;
  padding-block:var(--sec-tight);
  align-items:start;
}

.doc__index{position:sticky;inset-block-start:calc(var(--nav-h) + 40px)}
.doc__index-h{
  font-size:var(--fs-caption);
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ink-2);
  margin-block-end:16px;
}
.doc__index-list{display:flex;flex-direction:column}
.doc__index-list a{
  padding-block:8px;
  font-size:14px;
  color:var(--ink-2);
  border-inline-start:2px solid var(--rule);
  padding-inline-start:16px;
  transition:color var(--t-fast) var(--ease),border-color var(--t-fast) var(--ease);
}
.doc__index-list a:hover{color:var(--ink);border-inline-start-color:var(--garnet)}

.doc__sec{scroll-margin-block-start:calc(var(--nav-h) + 32px)}
.doc__sec + .doc__sec{margin-block-start:64px}
.doc__h{
  font-size:var(--fs-h3);
  font-weight:600;
  letter-spacing:-.018em;
}
.doc__lede{
  margin-block-start:12px;
  font-size:18px;
  color:var(--ink-2);
  max-width:60ch;
}
.doc__list{
  margin:26px 0 0;
  border-block-start:var(--hair) solid var(--rule);
}
.doc__row{
  margin:0;
  display:grid;
  grid-template-columns:1fr 1.6fr;
  gap:40px;
  padding-block:20px;
  border-block-end:var(--hair) solid var(--rule);
}
.doc__t{font-size:16px;font-weight:600;letter-spacing:-.01em}
.doc__d{margin:0;font-size:15px;color:var(--ink-2)}

.lang{
  font:inherit;
  font-size:12px;
  font-weight:500;
  color:var(--ink-2);
  background:none;
  border:0;
  padding:6px 10px;
  cursor:pointer;
  border-radius:var(--r-8);
  transition:color var(--t-fast) var(--ease),background var(--t-fast) var(--ease);
}
.lang:hover{color:var(--ink);background:var(--cream-2)}

/* --------------------------------------------------------------------------
   Liquid Carve button. The one button on this page. It began as the header
   call to action and is now the whole button system, by instruction: every
   call to action, on paper, on a photograph and on the dark console, is this
   shape at one of three sizes. One authored specular pass on hover, 620ms,
   ease-out, no loop.

   The sweep is a negative-z pseudo-element inside an isolated stacking
   context, so it lands above the field and below the label without the label
   needing a wrapper. That matters: the language switch rewrites the button's
   textContent, and any wrapper would be thrown away with it.
   -------------------------------------------------------------------------- */

.lcb{
  position:relative;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  height:40px;
  padding-inline:22px;
  border-radius:999px;
  font-family:inherit;
  font-size:14px;
  font-weight:600;
  letter-spacing:-.005em;
  white-space:nowrap;
  color:var(--cream);
  border:0;
  cursor:pointer;
  overflow:hidden;
  isolation:isolate;
  background:
    linear-gradient(180deg,rgba(239,230,222,.24),rgba(239,230,222,0) 48%),
    rgba(90,33,50,.86);
  -webkit-backdrop-filter:blur(14px) saturate(170%);
          backdrop-filter:blur(14px) saturate(170%);
  box-shadow:
    inset 0 1px 0 rgba(239,230,222,.55),
    inset 0 -1px 0 rgba(48,10,20,.6),
    inset 0 0 0 1px rgba(239,230,222,.16),
    0 6px 18px rgba(48,10,20,.24);
  transition:box-shadow 280ms var(--ease),transform 280ms var(--ease);
}
html[dir="rtl"] .lcb{letter-spacing:0}

.lcb::after{
  content:"";
  position:absolute;
  z-index:-1;
  inset-block:0;
  inset-inline-start:-70%;
  width:55%;
  background:linear-gradient(100deg,transparent,rgba(239,230,222,.45),transparent);
  transition:transform 620ms var(--ease);
  pointer-events:none;
}
.lcb:hover{
  transform:translateY(-1px);
  box-shadow:
    inset 0 1px 0 rgba(239,230,222,.62),
    inset 0 -1px 0 rgba(48,10,20,.6),
    inset 0 0 0 1px rgba(239,230,222,.2),
    0 10px 24px rgba(48,10,20,.3);
}
.lcb:hover::after{transform:translateX(330%)}
html[dir="rtl"] .lcb:hover::after{transform:translateX(-330%)}
.lcb:active{transform:translateY(0)}

/* Three sizes, one shape. Large carries a section on its own, small sits
   inside the console mock, and the unmarked default belongs to the header. */
.lcb--lg{height:48px;padding-inline:28px;font-size:16px}
.lcb--sm{height:36px;padding-inline:18px;font-size:13px}

/* The same glass cut from cream instead of garnet, for a second action on a
   dark ground where a garnet field would read as the only thing in view. */
.lcb--quiet{
  color:var(--cream);
  background:
    linear-gradient(180deg,rgba(239,230,222,.18),rgba(239,230,222,0) 48%),
    rgba(239,230,222,.06);
  box-shadow:
    inset 0 1px 0 rgba(239,230,222,.26),
    inset 0 -1px 0 rgba(48,10,20,.5),
    inset 0 0 0 1px rgba(239,230,222,.18),
    0 6px 18px rgba(48,10,20,.3);
}
.lcb--quiet:hover{
  box-shadow:
    inset 0 1px 0 rgba(239,230,222,.34),
    inset 0 -1px 0 rgba(48,10,20,.5),
    inset 0 0 0 1px rgba(239,230,222,.26),
    0 10px 24px rgba(48,10,20,.34);
}

/* --------------------------------------------------------------------------
   Hero. The photograph is a panel that fills the frame exactly and stops at
   the two vertical lines. It runs at its own aspect ratio, so nothing is
   cropped and nothing escapes the skeleton. The copy sits over the sky, which
   is within a shade of the brand cream, so ink type needs no scrim and the
   no-gradient rule survives intact.
   -------------------------------------------------------------------------- */

.hero__panel{
  position:relative;
  overflow:hidden;
  background:var(--cream-2);
}
.hero__photo{
  width:100%;
  height:auto;
  display:block;
}

/* Both photographs are composed with their empty sky on the reading-start
   side and their subject on the far side. Mirror them in RTL so the copy
   keeps landing on open sky instead of on the tower. */
html[dir="rtl"] .hero__photo,
html[dir="rtl"] .band__photo{transform:scaleX(-1)}
.hero__copy{
  position:absolute;
  inset-block-start:0;
  inset-inline-start:0;
  z-index:1;
  padding:clamp(40px,4.6vw,64px);
  /* Sized to hold the tagline that replaced "From zero to limitless.".
     The old value left this block 20 to 30px short of its second line,
     which broke the headline into three. */
  max-width:min(64%,790px);
  text-align:start;
}

/* The three panels that sit on a photograph carry the display face in Arabic
   and IBM Plex Sans in English, by instruction. Milan is a high-contrast
   Black, so where it does appear it takes the 900 and drops the negative
   tracking the sans headings use; Arabic never wanted that tracking anyway. */
html[dir="rtl"] .display,
html[dir="rtl"] .band__quote,
html[dir="rtl"] .close__h{
  font-family:var(--font-display);
  font-weight:900;
  letter-spacing:0;
}

.display{
  margin-block:20px 0;
  font-size:var(--fs-display);
  text-wrap:balance;
  letter-spacing:-.02em;
  line-height:1.04;
}
html[dir="rtl"] .display{line-height:1.28}

.lede{
  margin-block-start:20px;
  max-width:44ch;
  font-size:18px;
  color:var(--ink-2);
}
html[dir="rtl"] .lede{letter-spacing:0}

.hero__actions{margin-block-start:30px;display:flex;gap:12px}

/* --------------------------------------------------------------------------
   Sections
   -------------------------------------------------------------------------- */

.section__head{
  display:grid;
  grid-template-columns:1fr 1fr;
  column-gap:64px;
  align-items:end;
  margin-block-end:56px;
}
.section__head > .h2{grid-area:1/1}
.section__lede{
  grid-area:1/2;
  font-size:18px;
  line-height:1.55;
  color:var(--ink-2);
  max-width:46ch;
}

/* A job moving through ZerofyAI. Each step of the garnet to cream ladder
   becomes a solid plate carrying its numeral, and the four plates step down
   in width so the sequence reads before the copy does.

   The plate carries the colour and the numeral rides on it, so the numerals
   are the only type ever set on a ladder ground. Cream sits on steps 1 and 2,
   ink on 3, 4 and 5; every pairing clears the large-text threshold and the two
   dark ones clear AA outright. Everything anyone reads as prose stays on cream
   at full contrast. */

.pla{border-block-start:var(--hair) solid var(--rule)}

.pla__row{
  display:grid;
  grid-template-columns:220px 1fr;
  align-items:stretch;
  column-gap:48px;
  border-block-end:var(--hair) solid var(--rule);
}

/* The plate is narrower than its track, and the row runs it out to the full
   track on hover. That is the only motion the section has. */
.pla__n{
  display:flex;
  align-items:center;
  justify-content:center;
  inline-size:calc(84px + var(--plate) * 26px);
  background:var(--step);
  color:var(--on);
  font-family:var(--font-mono);
  font-size:44px;
  font-weight:500;
  line-height:1;
  letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;
  direction:ltr;
  transition:inline-size var(--t-mid) var(--ease);
}
.pla__row:hover .pla__n{inline-size:220px}

@media (prefers-reduced-motion: reduce){
  .pla__n{transition:none}
}

.pla__txt{
  display:flex;
  flex-direction:column;
  gap:10px;
  justify-content:center;
  padding-block:30px;
  max-inline-size:66ch;
}
.pla__t{
  font-size:21px;
  font-weight:600;
  letter-spacing:-.012em;
  line-height:1.3;
}
.pla__b{
  color:var(--ink-2);
  font-size:16px;
  line-height:1.5;
  letter-spacing:-.005em;
}
html[dir="rtl"] .pla__t,
html[dir="rtl"] .pla__b{letter-spacing:0}

/* --------------------------------------------------------------------------
   Founder loop.

   The five product jobs form one continuous route instead of five more app
   cards. The detailed suite below owns names, marks and product descriptions;
   this section owns the relationship between them. The complete path and all
   five stages are visible without script. Script only draws the route once.
   -------------------------------------------------------------------------- */

.founder-loop{
  background:transparent;
  color:var(--ink);
  overflow:hidden;
}
.founder-loop__head{
  display:grid;
  grid-template-columns:minmax(0,1fr) minmax(320px,.72fr);
  align-items:end;
  gap:64px;
  padding:64px clamp(40px,4.6vw,64px) 44px;
  border-block-end:var(--hair) solid var(--rule);
}
.founder-loop__h{
  max-inline-size:18ch;
  font-size:var(--fs-h2);
  line-height:1.14;
  letter-spacing:-.018em;
  text-wrap:balance;
}
.founder-loop__lede{
  max-inline-size:44ch;
  color:var(--ink-2);
  font-size:18px;
  line-height:1.55;
}
html[dir="rtl"] .founder-loop__h,
html[dir="rtl"] .founder-loop__lede{letter-spacing:0}

.founder-loop__field{
  position:relative;
  isolation:isolate;
  min-block-size:clamp(400px,36vw,470px);
  overflow:hidden;
}
.founder-loop__field::before,
.founder-loop__field::after{
  content:"";
  position:absolute;
  z-index:0;
  inset-inline:0;
  block-size:var(--hair);
  background:rgba(48,10,20,.08);
}
.founder-loop__field::before{inset-block-start:25%}
.founder-loop__field::after{inset-block-end:25%}
.founder-loop__route{
  position:absolute;
  z-index:1;
  inset:5% 2%;
  inline-size:96%;
  block-size:90%;
  overflow:visible;
}
.founder-loop__route--narrow{display:none}
.founder-loop__route-base,
.founder-loop__route-draw{
  fill:none;
  vector-effect:non-scaling-stroke;
}
.founder-loop__route-base{
  stroke:rgba(48,10,20,.1);
  stroke-width:1;
}
.founder-loop__route-draw{
  stroke:var(--garnet);
  stroke-width:1.6;
  stroke-linecap:round;
  stroke-linejoin:round;
}
.founder-loop.has-motion .founder-loop__route-draw{
  transition:stroke-dashoffset 820ms cubic-bezier(.16,1,.3,1);
  stroke-dasharray:var(--loop-length);
  stroke-dashoffset:var(--loop-length);
}
.founder-loop.is-inview .founder-loop__route-draw{stroke-dashoffset:0}
.founder-loop__stages{position:absolute;z-index:2;inset:0}
.founder-loop__stage{
  position:absolute;
  left:var(--x);
  inset-block-start:var(--y);
  display:grid;
  grid-template-columns:auto auto;
  align-items:center;
  gap:10px;
  padding:9px 12px 9px 10px;
  color:var(--ink);
  background:var(--cream);
  transform:translate(-50%,-50%);
  white-space:nowrap;
}
.founder-loop__stage::before{
  content:"";
  position:absolute;
  inset-block-start:0;
  inset-inline-start:10px;
  inline-size:28px;
  block-size:3px;
  background:var(--stage);
}
.founder-loop__number{
  min-inline-size:2.2em;
  font-family:var(--font-mono);
  font-size:12px;
  font-weight:500;
  line-height:1;
  letter-spacing:.01em;
  direction:ltr;
  font-variant-numeric:tabular-nums;
  color:var(--ink-2);
}
.founder-loop__verb{
  padding-inline-start:10px;
  border-inline-start:var(--hair) solid var(--rule);
  font-size:18px;
  font-weight:500;
  line-height:1.2;
  letter-spacing:-.012em;
}
html[dir="rtl"] .founder-loop__verb{letter-spacing:0}
.founder-loop.has-motion:not(.is-inview) .founder-loop__stage{
  opacity:0;
  transform:translate(-50%,calc(-50% + 8px));
}
.founder-loop.has-motion .founder-loop__stage{
  transition:opacity 360ms ease-out,transform 500ms cubic-bezier(.16,1,.3,1);
}
.founder-loop.has-motion .founder-loop__stage:nth-child(1){transition-delay:240ms}
.founder-loop.has-motion .founder-loop__stage:nth-child(2){transition-delay:300ms}
.founder-loop.has-motion .founder-loop__stage:nth-child(3){transition-delay:360ms}
.founder-loop.has-motion .founder-loop__stage:nth-child(4){transition-delay:420ms}
.founder-loop.has-motion .founder-loop__stage:nth-child(5){transition-delay:480ms}
html[dir="rtl"] .founder-loop__stage:nth-child(1){--x:87% !important}
html[dir="rtl"] .founder-loop__stage:nth-child(2){--x:71% !important}
html[dir="rtl"] .founder-loop__stage:nth-child(4){--x:29% !important}
html[dir="rtl"] .founder-loop__stage:nth-child(5){--x:13% !important}
/* --------------------------------------------------------------------------
   Statement band. Same containment rule as the hero.
   -------------------------------------------------------------------------- */

.band__panel{
  position:relative;
  overflow:hidden;
  background:var(--cream-2);
}
.band__photo{width:100%;height:auto;display:block}
.band__copy{
  position:absolute;
  inset-block-start:0;
  inset-inline-start:0;
  z-index:1;
  padding:clamp(40px,4.6vw,64px);
  max-width:min(70%,800px);
  text-align:start;
}
.band__quote{
  text-wrap:balance;
  font-size:var(--fs-h2);
  font-weight:600;
  letter-spacing:-.018em;
  line-height:1.18;
}
html[dir="rtl"] .band__quote{line-height:1.4}

/* --------------------------------------------------------------------------
   Suite. Five products, five ladder steps, brand page 21.

   The row is a register, not a set of cards: five cells divided by the same
   hairline as the frame, each carrying its own step of the garnet to cream
   ladder as a tick along the top edge. The tick runs the width of the cell on
   hover, which is the only motion the row has.

   Nothing unfolds here. Asking for an app opens the dialog below, over the
   page rather than inside it, because the detail is a place you go and come
   back from rather than a longer version of the row.
   -------------------------------------------------------------------------- */

.suite__row{
  display:grid;
  grid-template-columns:repeat(5,1fr);
  border-block-start:var(--hair) solid var(--rule);
}
.suite__cell{border-inline-end:var(--hair) solid var(--rule)}
.suite__cell:last-child{border-inline-end:0}

.suite__btn{
  position:relative;
  width:100%;
  height:100%;
  display:flex;
  flex-direction:column;
  align-items:flex-start;
  padding:36px 24px 30px;
  font:inherit;
  color:inherit;
  text-align:start;
  background:none;
  border:0;
  cursor:pointer;
  transition:background var(--t-fast) var(--ease);
}
.suite__btn::before{
  content:"";
  position:absolute;
  inset-block-start:-1px;
  inset-inline-start:0;
  width:48px;
  height:3px;
  background:var(--step);
  transition:width var(--t-mid) var(--ease);
}
.suite__btn:hover,
.suite__btn:focus-visible{background:var(--cream-2)}
.suite__btn:hover::before,
.suite__btn:focus-visible::before{width:100%}
.suite__btn:focus-visible{outline:2px solid var(--garnet);outline-offset:-3px}
.suite__btn.is-active{background:var(--cream-2)}
.suite__btn.is-active::before{width:100%}

.suite__icon{
  height:42px;
  width:auto;
  opacity:.92;
  transition:transform var(--t-mid) var(--ease);
}
.suite__btn:hover .suite__icon{transform:translateY(-3px)}

.suite__name{
  margin-block-start:24px;
  font-size:21px;
  font-weight:600;
  letter-spacing:-.02em;
}
html[dir="rtl"] .suite__name{font-family:var(--font-latin);direction:ltr;unicode-bidi:isolate}

.suite__cat{
  margin-block-start:8px;
  font-size:var(--fs-caption);
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ink-2);
}
html[dir="rtl"] .suite__cat{letter-spacing:0;text-transform:none;font-size:13px}

.suite__more{
  margin-block-start:auto;
  padding-block-start:30px;
  display:inline-flex;
  align-items:center;
  gap:8px;
  font-size:13px;
  font-weight:600;
  color:var(--garnet);
}
.suite__more svg{
  width:15px;
  height:15px;
  fill:none;
  stroke:currentColor;
  stroke-width:1.6;
  stroke-linecap:round;
  stroke-linejoin:round;
  transition:transform var(--t-fast) var(--ease);
}
html[dir="rtl"] .suite__more svg{transform:scaleX(-1)}
.suite__btn:hover .suite__more svg{transform:translateX(3px)}
html[dir="rtl"] .suite__btn:hover .suite__more svg{transform:scaleX(-1) translateX(3px)}

/* --------------------------------------------------------------------------
   App dialog. The detail for one product, over the page.

   Hidden from the accessibility tree entirely between openings, so the five
   copies of this content never sit in the document as five silent regions.
   Opening writes the card from the same APPS table that writes the row, then
   moves focus into it; closing puts focus back on the cell that asked. The
   scrim and the card carry separate transitions so the card arrives a beat
   after the ground darkens, and leaves before it lifts.
   -------------------------------------------------------------------------- */

.modal{
  position:fixed;
  inset:0;
  z-index:40;
  display:grid;
  place-items:center;
  padding:40px;
}
.modal[hidden]{display:none}
/* While it is leaving, the overlay is still in the layout for the length of
   the card's transition. Without this it would swallow the first click a
   visitor makes after closing it. */
.modal:not(.is-open){pointer-events:none}

.modal__scrim{
  position:absolute;
  inset:0;
  background:rgba(48,10,20,.44);
  -webkit-backdrop-filter:blur(7px) saturate(120%);
          backdrop-filter:blur(7px) saturate(120%);
  opacity:0;
  transition:opacity 300ms var(--ease);
}
.modal.is-open .modal__scrim{opacity:1}

.modal__card{
  position:relative;
  width:min(620px,100%);
  max-height:calc(100vh - 80px);
  overflow:auto;
  background:var(--cream);
  border-radius:var(--r-20);
  box-shadow:0 40px 90px rgba(48,10,20,.3);
  opacity:0;
  transform:translateY(18px) scale(.972);
  transition:opacity 220ms var(--ease),transform 220ms var(--ease);
}
.modal.is-open .modal__card{
  opacity:1;
  transform:none;
  transition-duration:440ms;
  transition-delay:50ms;
}

/* The product's own step of the ladder, along the top edge of the card. */
.modal__bar{
  position:sticky;
  inset-block-start:0;
  height:4px;
  background:var(--step);
}

.modal__close{
  position:absolute;
  inset-block-start:22px;
  inset-inline-end:22px;
  z-index:2;
  width:34px;
  height:34px;
  display:grid;
  place-items:center;
  border-radius:999px;
  background:rgba(239,230,222,.72);
  border:var(--hair) solid var(--rule);
  color:var(--ink-2);
  cursor:pointer;
  -webkit-backdrop-filter:blur(10px);
          backdrop-filter:blur(10px);
  transition:color var(--t-fast) var(--ease),
             background var(--t-fast) var(--ease),
             border-color var(--t-fast) var(--ease);
}
.modal__close:hover{color:var(--ink);background:var(--cream-2);border-color:var(--ink)}
.modal__close svg{
  width:15px;
  height:15px;
  fill:none;
  stroke:currentColor;
  stroke-width:1.7;
  stroke-linecap:round;
}

.modal__head{
  display:flex;
  align-items:center;
  gap:20px;
  padding:34px 40px 30px;
  background:var(--cream-2);
  border-block-end:var(--hair) solid var(--rule);
}
.modal__icon{height:52px;width:auto}
.modal__cat{
  font-size:var(--fs-caption);
  font-weight:500;
  letter-spacing:.14em;
  text-transform:uppercase;
  color:var(--ink-2);
}
html[dir="rtl"] .modal__cat{letter-spacing:0;text-transform:none;font-size:13px}
.modal__name{
  margin-block-start:6px;
  font-size:var(--fs-h3);
  font-weight:600;
  letter-spacing:-.02em;
}
html[dir="rtl"] .modal__name{letter-spacing:0;font-family:var(--font-latin);direction:ltr;unicode-bidi:isolate}

.modal__body{padding:32px 40px 36px}
.modal__lede{
  font-size:17px;
  line-height:1.55;
  color:var(--ink-2);
}
html[dir="rtl"] .modal__lede{letter-spacing:0}

/* The four steps the app takes you through, stacked rather than in columns:
   the card is 620px wide and four columns at that width is four words each. */
.msteps{
  margin-block-start:26px;
  border-block-start:var(--hair) solid var(--rule);
}
.mstep{
  display:grid;
  grid-template-columns:auto 1fr;
  gap:18px;
  padding-block:15px;
  border-block-end:var(--hair) solid var(--rule);
}
.mstep__n{
  font-family:var(--font-mono);
  font-size:13px;
  line-height:1.5;
  direction:ltr;
  color:var(--ink-2);
  opacity:.55;
}
.mstep__t{
  font-size:15px;
  font-weight:600;
  letter-spacing:-.01em;
}
.mstep__b{
  margin-block-start:4px;
  font-size:14px;
  color:var(--ink-2);
}
html[dir="rtl"] .mstep__t,
html[dir="rtl"] .mstep__b{letter-spacing:0}

.modal__foot{margin-block-start:30px}

/* Laptop screens have enough width for the full card but less vertical room.
   Tighten the same structure instead of making one app scroll while its
   neighbours fit. Phone sheets keep their roomier touch spacing below. */
@media (min-width:761px) and (max-height:820px){
  .modal{padding:24px}
  .modal__card{max-height:calc(100vh - 48px)}
  .modal__head{padding:24px 32px 22px}
  .modal__body{padding:24px 32px 28px}
  .msteps{margin-block-start:18px}
  .mstep{padding-block:11px}
  .modal__foot{margin-block-start:22px}
}

/* Each row of the card settles in behind the card itself, top to bottom, so
   the dialog assembles rather than appearing whole. */
.modal__card .rise{
  opacity:0;
  transform:translateY(8px);
  transition:opacity 320ms var(--ease),transform 320ms var(--ease);
}
.modal.is-open .modal__card .rise{
  opacity:1;
  transform:none;
  transition-delay:var(--rd,0ms);
}

body.is-locked{overflow:hidden}
/* --------------------------------------------------------------------------
   Figures
   -------------------------------------------------------------------------- */

.figures{
  display:grid;
  grid-template-columns:repeat(4,1fr);
}
.figure{
  padding:46px 22px 50px;
  border-inline-end:var(--hair) solid var(--rule);
  text-align:start;
}
.figure:last-child{border-inline-end:0}
.figure__n{
  font-family:var(--font-mono);
  font-size:46px;
  font-weight:500;
  line-height:1;
  letter-spacing:-.03em;
  font-variant-numeric:tabular-nums;
  direction:ltr;
}
.figure__l{margin-block-start:14px;color:var(--ink-2);font-size:14px}
html[dir="rtl"] .figure__l{letter-spacing:0}
html[dir="rtl"] .figure__n{text-align:start}

/* The waitlist block that used to sit here was removed at the owner's
   instruction. The closing panel carries the last call to action now, and
   holds the #waitlist anchor so every button still lands somewhere. */

/* --------------------------------------------------------------------------
   Questions. An accordion, at the owner's instruction, replacing the ruled
   register that was here.

   The behaviour is SmoothUI's basic-accordion (MIT): one panel open at a
   time, a chevron that turns 180 degrees, a height that animates rather than
   snapping, and collapsed panels left mounted but `inert` so the width never
   shifts and nothing hidden keeps a tab stop. Their timings came across as
   they are, 250ms on the height and 200ms on the fade and the chevron. What
   did not come across is the skin: a rounded bordered box on a filled ground
   would be a foreign object here, so the rows are drawn in the page's own
   language, hairline dividers and no ground at all.

   The panel opens on grid-template-rows, which is the one way to animate from
   nothing to auto in CSS without measuring in script. It is also why .acc__clip
   exists: the row is the grid, the clip is the thing that hides the overflow.
   -------------------------------------------------------------------------- */

.qa__h{margin-block-end:48px}

.acc{border-block-start:var(--hair) solid var(--rule)}
.acc__row{border-block-end:var(--hair) solid var(--rule)}

.acc__h{margin:0;font-size:inherit;font-weight:inherit}
.acc__btn{
  width:100%;
  min-height:44px;
  display:flex;
  align-items:center;
  justify-content:space-between;
  gap:32px;
  padding-block:26px;
  font:inherit;
  font-size:18px;
  font-weight:500;
  letter-spacing:-.012em;
  color:inherit;
  text-align:start;
  background:none;
  border:0;
  cursor:pointer;
  transition:color var(--t-fast) var(--ease);
}
.acc__btn:hover{color:var(--garnet)}
.acc__btn:focus-visible{outline:2px solid var(--garnet);outline-offset:-2px}
html[dir="rtl"] .acc__btn{letter-spacing:0}

.acc__chev{
  width:20px;
  height:20px;
  flex:none;
  fill:none;
  stroke:currentColor;
  stroke-width:1.6;         /* icon rule, brand page 14 */
  stroke-linecap:round;
  stroke-linejoin:round;
  color:var(--ink-2);
  transition:transform 200ms var(--ease),color var(--t-fast) var(--ease);
}
.acc__btn:hover .acc__chev{color:var(--garnet)}
.acc__row.is-open .acc__chev{transform:rotate(180deg)}

/* Without script every answer is simply open, which is what the markup says.
   .is-live is added by main.js and is the only thing that collapses them. */
.acc.is-live .acc__panel{
  display:grid;
  grid-template-rows:0fr;
  opacity:0;
  transition:grid-template-rows 250ms var(--ease),opacity 200ms var(--ease);
}
.acc.is-live .acc__row.is-open .acc__panel{
  grid-template-rows:1fr;
  opacity:1;
}
.acc__clip{overflow:hidden}

.acc__a{
  padding-block-end:28px;
  padding-inline-end:52px;   /* clear of the chevron's column */
  color:var(--ink-2);
  max-width:64ch;
}
html[dir="rtl"] .acc__a{letter-spacing:0}

/* --------------------------------------------------------------------------
   Closing. The third photograph, contained by the frame exactly like the
   other two and running at its own aspect ratio. The copy sits on the sky,
   which is within a shade of the paper, so ink type needs no scrim and the
   no-gradient rule holds.
   -------------------------------------------------------------------------- */

.close__panel{
  position:relative;
  overflow:hidden;
  background:var(--cream-2);
}
.close__photo{
  width:100%;
  height:auto;
  display:block;
}
/* Composed with the city on one side and open sky on the other, so it
   mirrors in RTL for the same reason the hero and the band do. */
html[dir="rtl"] .close__photo{transform:scaleX(-1)}

.close__copy{
  position:absolute;
  inset-block-start:0;
  inset-inline-start:0;
  z-index:1;
  padding:clamp(40px,4.6vw,64px);
  max-width:min(56%,640px);
  text-align:start;
}
.close__h{
  font-size:var(--fs-display);
  text-wrap:balance;
  letter-spacing:-.02em;
  line-height:1.04;
}
html[dir="rtl"] .close__h{line-height:1.28}
.close__p{
  margin-block-start:18px;
  font-size:18px;
  color:var(--ink-2);
  max-width:34ch;
}
html[dir="rtl"] .close__p{letter-spacing:0}
.close__actions{margin-block-start:30px;display:flex;gap:12px}

/* --------------------------------------------------------------------------
   Footer. The one thing on the page allowed outside the frame.

   Everywhere else, nothing may cross the two vertical hairlines. Here the ink
   ground runs the full width of the window on purpose, past where those lines
   stop, because by this point the frame has ended and the footer is what the
   page was standing on all along. The type inside it stays on the frame's
   measure, so the lockup still lines up with every section above it: the
   ground breaks out, the grid does not.
   -------------------------------------------------------------------------- */

.foot{
  background:var(--ink);
  color:var(--cream);
}

.foot__inner{
  max-width:var(--frame);
  margin-inline:auto;
  padding:64px var(--gutter) 48px;
  display:flex;
  align-items:flex-start;
  gap:64px;
}

.foot__brand{display:flex;flex-direction:column;gap:16px}
.foot .lockup{color:var(--cream)}
.foot__apps{
  margin-inline-start:auto;
  display:flex;
  gap:34px;
  font-size:15px;
  font-weight:500;
}
.foot__apps a{
  color:var(--cream);
  opacity:.78;
  transition:opacity var(--t-fast) var(--ease);
}
.foot__apps a:hover{opacity:1}
html[dir="rtl"] .foot__apps a{direction:ltr;unicode-bidi:isolate}

/* The rule stays on the frame's measure even though the ground does not. */
.foot__base{
  max-width:var(--frame);
  margin-inline:auto;
  padding:22px var(--gutter) 30px;
  display:flex;
  justify-content:space-between;
  gap:32px;
  border-block-start:var(--hair) solid rgba(239,230,222,.12);
}
.foot .caption{color:var(--on-ink)}
/* "© 2026 ZerofyAI" is a Latin run led by a neutral, which an Arabic
   paragraph would otherwise send to the far end of the line. */
.foot__base .caption:first-child{direction:ltr;unicode-bidi:isolate}
html[dir="rtl"] .foot__base .caption:first-child{text-align:start}

/* --------------------------------------------------------------------------
   Reduced motion
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .reveal{opacity:1;transform:none}
  body.is-ready .reveal{animation:none}
  .hero__photo{clip-path:none}
  body.is-ready .hero__photo{animation:none}
  .kicker__w{transition:none}
  .menu__pop,
  .menu__chev,
  .acc__panel,
  .acc__chev{transition:none}
  .modal__card,
  .modal__scrim,
  .modal__card .rise{transition:none}
  .modal__card{transform:none}
  .modal__card .rise{opacity:1;transform:none}
  .founder-loop__route-draw,
  .founder-loop__stage{transition:none}
  .founder-loop.has-motion:not(.is-inview) .founder-loop__stage{
    opacity:1;
    transform:translate(-50%,-50%);
  }
  *{transition-duration:1ms !important}
}

/* --------------------------------------------------------------------------
   The two views

   index.html holds the whole site: the landing page and the waitlist, as two
   sibling views the router in main.js swaps between. Neither is a page, so
   neither gets a navigation, and moving between them is animated rather than
   reloaded.

   Nothing here sets `display` on .view. The `hidden` attribute is what takes
   a view out, and the UA sheet already means display:none; setting a display
   here would beat it and both views would show at once.
   -------------------------------------------------------------------------- */

/* --------------------------------------------------------------------------
   Moving between them, first choice: the View Transitions API.

   The browser holds a screenshot of the outgoing view and cross-fades it with
   the incoming one. All this does is replace that cross-fade with something
   directional, so going to the waitlist reads as going forward and coming
   back reads as coming back. --nav on the root says which way we are going;
   main.js sets it immediately before it swaps.

   Distances are small on purpose. This is one screen replacing another, not a
   carousel, and the eye only needs enough motion to know which way it went.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference){
  ::view-transition-old(root){
    animation:vt-recede 220ms var(--ease) both;
  }
  ::view-transition-new(root){
    animation:vt-arrive 420ms var(--ease) both;
  }

  html[data-nav="back"] ::view-transition-old(root){animation-name:vt-recede-back}
  html[data-nav="back"] ::view-transition-new(root){animation-name:vt-arrive-back}
}

@keyframes vt-recede{
  from{opacity:1;transform:translateY(0)}
  to  {opacity:0;transform:translateY(-14px)}
}
@keyframes vt-arrive{
  from{opacity:0;transform:translateY(22px)}
  to  {opacity:1;transform:translateY(0)}
}
@keyframes vt-recede-back{
  from{opacity:1;transform:translateY(0)}
  to  {opacity:0;transform:translateY(14px)}
}
@keyframes vt-arrive-back{
  from{opacity:0;transform:translateY(-22px)}
  to  {opacity:1;transform:translateY(0)}
}

/* --------------------------------------------------------------------------
   Second choice: a browser with no View Transitions.

   There is no screenshot to work with, so the outgoing view cannot be
   animated, only the arriving one. main.js puts .is-entering on it for the
   length of the animation. The timing and the easing are the same as above,
   so the two paths feel like one design rather than two.
   -------------------------------------------------------------------------- */

@media (prefers-reduced-motion: no-preference){
  .view.is-entering{animation:vt-arrive 420ms var(--ease) both}
  html[data-nav="back"] .view.is-entering{animation-name:vt-arrive-back}
}

/* ==========================================================================
   NARROW WINDOWS

   Everything above this line describes the page at full width. This is the
   same page told for a hand, and it is deliberately the last thing in the
   sheet: one block to read when the phone is wrong, rather than a breakpoint
   buried in every rule.

   The skeleton does not change. Rows still rule the full width, rails still
   carry the two verticals, and the frame still runs unbroken from the nav to
   the footer — it only gets narrower, and the things inside it stop being
   side by side. What does change is the nav, which cannot hold three menus
   on a 390px bar, and the three photographs, whose copy cannot sit on top of
   an image 220px tall.

   Three stops:
     1100px  the frame tightens. Nothing moves yet.
      900px  the drawer takes over the nav, and every two-column thing in
             the page becomes one column.
      560px  a phone held upright. Type steps down and the bar sheds its
             call to action, which is in the drawer and in the hero anyway.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1100px. A laptop at half width, or a tablet upright. The gutter and the
   section rhythm come in; the layout is untouched.
   -------------------------------------------------------------------------- */

@media (max-width:1100px){
  :root{
    --gutter:32px;
    --sec:84px;
    --sec-tight:64px;
  }

  .section__head{column-gap:44px}
  .pla__row{grid-template-columns:180px 1fr;column-gap:36px}
  .pla__n{inline-size:calc(70px + var(--plate) * 22px)}
  .pla__row:hover .pla__n{inline-size:180px}
  .founder-loop__head{gap:44px}
  .doc{grid-template-columns:200px 1fr;gap:48px}

  /* Five cells stop being readable somewhere around 180px each. Three, then
     the last two, and the fifth takes the width it is given rather than
     leaving a hairline standing in an empty column. */
  .suite__row{grid-template-columns:repeat(3,1fr)}
  .suite__cell{border-block-end:var(--hair) solid var(--rule)}
  .suite__cell:nth-child(3n){border-inline-end:0}
  .suite__cell:nth-child(n+4){border-block-end:0}
  .suite__cell:last-child{grid-column:2/-1;border-inline-end:0}
  .suite__btn{padding:30px 20px 26px}
}

/* --------------------------------------------------------------------------
   900px. The column count goes to one.

   Every grid in the page was a pair of columns holding a heading against its
   lede, a number against its rule, a term against its definition. At this
   width the second column is narrower than its own measure, so each of them
   stacks — and the hairline that divided them becomes the hairline under
   them, which the register already had.
   -------------------------------------------------------------------------- */

@media (max-width:900px){
  :root{
    --gutter:24px;
    --sec:68px;
    --sec-tight:56px;
    --nav-h:60px;

    /* The display sizes were written to fill a 1280px frame. Their floors —
       46px and 30px — are wider than a phone at the word, not the line, so
       the floors come down and the ceilings stay where they are. */
    --fs-display:clamp(34px,7.4vw,52px);
    --fs-h2:clamp(26px,4.6vw,34px);
    --fs-h3:24px;
  }

  /* The bar --------------------------------------------------------------- */

  .lockup__art{height:22px}
  .nav__actions{gap:8px}
  .nav__actions .lcb{height:36px;padding-inline:16px;font-size:13px}

  /* .has-drawer is set by main.js once the drawer is built. Without it the
     three menus are still the only navigation there is, so they stay — laid
     out to wrap rather than to overflow. */
  html.has-drawer .nav__links{display:none}
  html.has-drawer .navglass{grid-template-columns:1fr auto}
  html.has-drawer .burger{display:grid}
  html.has-drawer .drawer{display:block}

  html:not(.has-drawer) .navglass{
    height:auto;
    min-height:var(--nav-h);
    padding-block:10px;
    row-gap:10px;
  }
  html:not(.has-drawer) .nav__links{
    grid-column:1/-1;
    flex-wrap:wrap;
    gap:10px 22px;
  }

  /* The three photographs ------------------------------------------------- */

  /* At this width the panel is about 220px tall at the photograph's own
     aspect ratio, and the copy that used to sit on the sky is taller than
     that on its own. So the copy comes off the image and sits under it: the
     panel is still one object between the two verticals, it is simply read
     top to bottom rather than left to right.

     The photographs keep their own aspect ratio here. A tablet at 800px
     shows one 440px tall, which is a hero; it is only the phone, three
     hundred pixels further down, that needs the crop. */
  .hero__copy,
  .band__copy,
  .close__copy{
    position:static;
    /* Not `none`. The panel is now the full width of the frame, and a
       measure that runs the whole of a 780px tablet is a measure nobody
       finishes a line of. The block still sits on the reading-start edge,
       which is where it sat when it was on the sky. */
    max-width:min(100%,640px);
    padding:28px var(--gutter) 34px;
  }

  .display{margin-block-start:16px}
  .lede{font-size:17px;max-width:52ch}
  .eyebrow.kicker,
  html[dir="rtl"] .eyebrow.kicker{font-size:16px}
  .close__p{font-size:16px;max-width:44ch}
  .hero__actions,
  .close__actions{margin-block-start:24px}

  /* The belt -------------------------------------------------------------- */

  /* The legend was beside the strip with a hairline between them. There is
     no room for a column of it here, so the same hairline goes underneath
     and the strip runs the full width of the rail. */
  /* Section heads --------------------------------------------------------- */

  .section__head{
    grid-template-columns:1fr;
    row-gap:14px;
    margin-block-end:34px;
  }
  .section__head > .h2{grid-area:auto}
  .section__lede{grid-area:auto;font-size:16px;max-width:none}

  /* Working flow ---------------------------------------------------------- */

  /* The track narrows and the plates narrow with it, so the sequence
     survives the breakpoint instead of flattening into equal blocks. */
  .pla__row{grid-template-columns:140px 1fr;column-gap:28px}
  .pla__n{inline-size:calc(56px + var(--plate) * 16px);font-size:30px}
  .pla__row:hover .pla__n{inline-size:140px}
  .pla__txt{padding-block:22px;gap:6px}
  .pla__t{font-size:19px}
  .pla__b{font-size:15px;max-inline-size:none}

  /* Founder loop ---------------------------------------------------------- */

  .founder-loop__head{
    grid-template-columns:1fr;
    gap:18px;
    padding:52px var(--gutter) 40px;
  }
  .founder-loop__h{max-inline-size:16ch}
  .founder-loop__lede{max-inline-size:48ch}
  .founder-loop__field{min-block-size:430px}

  /* Figures --------------------------------------------------------------- */

  .figures{grid-template-columns:repeat(2,1fr)}
  .figure{padding:30px 18px 32px;border-block-end:var(--hair) solid var(--rule)}
  .figure:nth-child(2n){border-inline-end:0}
  .figure:nth-child(n+3){border-block-end:0}
  .figure__n{font-size:36px}
  .figure__l{margin-block-start:10px;font-size:13px}

  /* Questions ------------------------------------------------------------- */

  .qa__h{margin-block-end:28px}
  .acc__btn{gap:18px;padding-block:20px;font-size:16px}
  .acc__chev{width:18px;height:18px}
  .acc__a{padding-block-end:22px;padding-inline-end:0;font-size:15px}

  /* Footer ---------------------------------------------------------------- */

  .foot__inner{
    flex-direction:column;
    gap:26px;
    padding:44px var(--gutter) 32px;
  }
  .foot__apps{
    margin-inline-start:0;
    flex-wrap:wrap;
    gap:12px 24px;
  }
  .foot__base{
    flex-direction:column;
    gap:6px;
    padding:18px var(--gutter) 26px;
  }

  /* Docs ------------------------------------------------------------------ */

  /* The index was a sticky column beside the prose. A sticky column is worth
     nothing at one column wide — it would either eat the top of the screen
     or scroll away — so it becomes a row of chips above the reading, once. */
  .doc{grid-template-columns:1fr;gap:30px}
  .doc__index{position:static}
  .doc__index-h{margin-block-end:12px}
  .doc__index-list{flex-direction:row;flex-wrap:wrap;gap:8px}
  .doc__index-list a{
    border:var(--hair) solid var(--rule);
    border-radius:999px;
    padding:7px 13px;
    font-size:13px;
  }
  .doc__index-list a:hover{border-color:var(--garnet)}
  .doc__sec + .doc__sec{margin-block-start:44px}
  .doc__lede{font-size:16px;max-width:none}
  .doc__row{grid-template-columns:1fr;gap:5px;padding-block:16px}
  .doc__title-lede{max-width:none}
}

/* --------------------------------------------------------------------------
   760px. The suite register becomes a list.

   Five cells side by side was a register. Stacked, a cell that is a column
   of icon, name, category and a link is four lines tall and five of them is
   most of a screen, so each becomes one line: the mark, what it is, and the
   arrow that opens it.
   -------------------------------------------------------------------------- */

@media (max-width:760px){
  /* The wide infinity route becomes a vertical loop composed for a hand. */
  .founder-loop__field{min-block-size:620px}
  .founder-loop__route--wide{display:none}
  .founder-loop__route--narrow{display:block;inset:2% 4%;inline-size:92%;block-size:96%}
  .founder-loop__stage:nth-child(1){--x:50% !important;--y:10% !important}
  .founder-loop__stage:nth-child(2){--x:23% !important;--y:30% !important}
  .founder-loop__stage:nth-child(3){--x:50% !important;--y:56% !important}
  .founder-loop__stage:nth-child(4){--x:77% !important;--y:70% !important}
  .founder-loop__stage:nth-child(5){--x:50% !important;--y:90% !important}
  html[dir="rtl"] .founder-loop__stage:nth-child(2){--x:77% !important}
  html[dir="rtl"] .founder-loop__stage:nth-child(4){--x:23% !important}
  html[dir="rtl"] .founder-loop__stage:nth-child(1),
  html[dir="rtl"] .founder-loop__stage:nth-child(3),
  html[dir="rtl"] .founder-loop__stage:nth-child(5){--x:50% !important}
  .founder-loop__verb{font-size:16px}

  .suite__row{grid-template-columns:1fr}
  .suite__cell{
    border-inline-end:0;
    border-block-end:var(--hair) solid var(--rule);
  }
  .suite__cell:nth-child(n+4){border-block-end:var(--hair) solid var(--rule)}
  .suite__cell:last-child{grid-column:auto;border-block-end:0}

  .suite__btn{
    display:grid;
    grid-template-columns:auto 1fr auto;
    align-items:center;
    gap:0 16px;
    padding:18px 2px;
  }
  .suite__icon{grid-area:1/1/3/2;height:36px}
  .suite__btn:hover .suite__icon{transform:none}
  .suite__name{grid-area:1/2;margin-block-start:0;font-size:18px}
  .suite__cat{grid-area:2/2;margin-block-start:2px}
  .suite__more{
    grid-area:1/3/3/4;
    margin-block-start:0;
    padding-block-start:0;
    justify-self:end;
  }
  /* The arrow is the affordance at this size; the word beside it is the
     third thing on a line that already has two. It stays in the document,
     because the language switch writes to it and a screen reader reads it. */
  .suite__more > span[data-i18n]{
    position:absolute;
    width:1px;
    height:1px;
    overflow:hidden;
    clip-path:inset(50%);
    white-space:nowrap;
  }
  .suite__more svg{width:18px;height:18px}

  /* The app dialog becomes a sheet. A centred card with 40px of scrim on
     every side wastes the only dimension a phone has, and a sheet is the
     shape a phone already uses for exactly this: a place you go and come
     back from, arriving from the edge you would dismiss it towards. */
  .modal{padding:0;place-items:end stretch}
  .modal__card{
    width:100%;
    max-height:92dvh;
    border-radius:var(--r-20) var(--r-20) 0 0;
    transform:translateY(28px);
  }
  .modal__head{gap:14px;padding:26px 22px 22px}
  .modal__icon{height:42px}
  .modal__close{inset-block-start:16px;inset-inline-end:16px}
  .modal__body{padding:24px 22px 32px}
  .modal__lede{font-size:16px}
  .mstep{gap:14px;padding-block:13px}

  /* The one action on the sheet, at the width of the sheet. A 150px pill in
     the corner of a full-bleed panel reads as an afterthought. */
  .modal__foot{margin-block-start:26px}
  .modal__foot .lcb{
    width:100%;
    height:48px;
    font-size:16px;
  }
}

/* --------------------------------------------------------------------------
   560px. A phone held upright.
   -------------------------------------------------------------------------- */

@media (max-width:560px){
  :root{
    --gutter:18px;
    --sec:56px;
    --sec-tight:46px;
    --nav-h:58px;
    --fs-display:clamp(30px,7.8vw,44px);
  }

  /* The bar keeps the lockup, the language and the way into everything else.
     The call to action comes off it: it is the first thing in the drawer, it
     is the button in the hero one scroll below, and it is the whole of the
     closing panel. A fourth copy of it was costing the bar its lockup. */
  html.has-drawer .nav__actions .lcb{display:none}

  .hero__copy,
  .band__copy,
  .close__copy{padding:24px var(--gutter) 30px}

  /* Whole, a photograph of this shape is a 220px strip at the top of a phone
     — too thin to be the thing the page opens with. Cropped to 3:2 it takes
     8% off each side of a composition that has its sky on one side and its
     subject on the other, and gives back about 70px of height. */
  .hero__photo,
  .band__photo,
  .close__photo{
    aspect-ratio:3/2;
    object-fit:cover;
    object-position:center;
  }

  /* One button, one thumb, the width of the column it sits in. */
  .hero__actions,
  .close__actions{flex-direction:column;align-items:stretch}

  .lede,
  .close__p{font-size:16px}

  .pla__row{grid-template-columns:76px 1fr;column-gap:18px}
  .pla__n{inline-size:calc(40px + var(--plate) * 7px);font-size:20px}
  .pla__row:hover .pla__n{inline-size:76px}
  .pla__t{font-size:18px}

  .founder-loop__head{padding:44px var(--gutter) 34px}
  .founder-loop__h{font-size:var(--fs-h2);line-height:1.14}
  .founder-loop__lede{font-size:16px}
  .founder-loop__field{min-block-size:560px}
  .founder-loop__stage{gap:8px;padding:8px 9px 8px 8px}
  .founder-loop__verb{padding-inline-start:8px;font-size:16px}

  /* At one column the number sits beside its proof instead of above it. */
  .figures{grid-template-columns:1fr}
  .figure{
    display:flex;
    align-items:baseline;
    gap:16px;
    padding:22px 4px;
    border-inline-end:0;
    border-block-end:var(--hair) solid var(--rule);
  }
  .figure:last-child{border-block-end:0}
  /* Four characters, because 2026 is four characters and the register only
     reads as a register if the four labels start on the same line. */
  .figure__n{font-size:30px;min-width:4ch}
  .figure__l{margin-block-start:0;font-size:14px}

  .acc__btn{font-size:15px;gap:14px;padding-block:18px}

  .foot__apps{gap:10px 20px;font-size:14px}
}

/* Very small phones, and any window a 320px device can produce. The lockup
   is the only thing left that can give width back to the bar. */
@media (max-width:380px){
  .lockup__art{height:19px}
  .nav__actions{gap:6px}
}

/* --------------------------------------------------------------------------
   No pointer.

   Every hover in this sheet was written for a mouse that leaves again. A
   finger does not: the browser keeps :hover on the last thing tapped until
   something else is, so a row you touched on the way past stays lit, a
   button stays raised, and the page looks like it is holding a selection it
   is not. None of these states carry information, so on a touch screen they
   simply do not happen. :focus-visible still does all of them, which is what
   a keyboard needs and a finger never triggers.
   -------------------------------------------------------------------------- */

@media (hover:none){
  .rule:hover{background:none}
  .lcb:hover{transform:none}
  .lcb:active{transform:translateY(1px)}
  .acc__btn:hover{color:inherit}
  .acc__btn:hover .acc__chev{color:var(--ink-2)}
  .nav__links a:hover,
  .nav__plain:hover,
  .menu__btn:hover{color:var(--ink-2)}
  .lang:hover{color:var(--ink-2);background:none}
  .foot__apps a:hover{opacity:.78}
  .doc__index-list a:hover{color:var(--ink-2)}

  /* The suite tick and ground are the row's own state, not a pointer's. They
     stay for .is-active, which is the cell whose dialog is open. */
  .suite__btn:hover{background:none}
  .suite__btn:hover::before{width:48px}
  .suite__btn:hover .suite__icon{transform:none}
  .suite__btn:hover .suite__more svg{transform:none}
  .suite__btn.is-active{background:var(--cream-2)}
  .suite__btn.is-active::before{width:100%}
  .menu__item:hover,
  .menu__app:hover{background:none}
  .modal__close:hover{
    color:var(--ink-2);
    background:rgba(239,230,222,.72);
    border-color:var(--rule);
  }
}

/* --------------------------------------------------------------------------
   THE DRAWER

   The narrow-window navigation. Under 900px the three menus have nowhere to
   hang, so the bar keeps the lockup, the language and one button, and hands
   everything else to a panel that comes down out of it.

   Nothing in it is a second copy of the navigation. main.js builds it by
   cloning what is already inside .nav__links, so a menu item is still
   written once — in the markup, or in the APPS table — and the language
   switch finds the clones exactly the way it finds the originals.

   It is the header's own glass, one step more opaque because there is a
   whole page behind it rather than a strip.
   -------------------------------------------------------------------------- */

.burger{
  display:none;          /* .has-drawer turns it on, under 900px only */
  place-items:center;
  width:42px;
  height:42px;
  margin-inline-end:-9px;
  padding:0;
  background:none;
  border:0;
  color:var(--ink-2);
  cursor:pointer;
  transition:color var(--t-fast) var(--ease);
}
.burger.is-open{color:var(--ink)}

/* Two bars that cross, rather than two icons that swap. */
.burger__box{
  position:relative;
  display:block;
  width:19px;
  height:13px;
}
.burger__bar{
  position:absolute;
  inset-inline:0;
  height:1.6px;                      /* the icon rule, brand page 14 */
  border-radius:2px;
  background:currentColor;
  transition:transform 320ms var(--ease);
}
.burger__bar:first-child{inset-block-start:0}
.burger__bar:last-child{inset-block-end:0}
.burger.is-open .burger__bar:first-child{transform:translateY(5.7px) rotate(45deg)}
.burger.is-open .burger__bar:last-child{transform:translateY(-5.7px) rotate(-45deg)}

.drawer{
  position:fixed;
  inset-block-start:var(--nav-h);
  inset-block-end:0;
  inset-inline:0;
  z-index:2;
  display:none;          /* .has-drawer turns it on, under 900px only */
  overflow-y:auto;
  overscroll-behavior:contain;
  -webkit-overflow-scrolling:touch;
  background:linear-gradient(180deg,rgba(239,230,222,.97),rgba(239,230,222,.99));
  -webkit-backdrop-filter:blur(22px) saturate(180%);
          backdrop-filter:blur(22px) saturate(180%);
  /* The row's hairline is already on the bar's bottom edge; this is the one
     the panel needs against the page it is covering. */
  border-block-start:var(--hair) solid var(--rule);
  opacity:0;
  visibility:hidden;
  transform:translateY(-10px);
  transition:opacity 240ms var(--ease),
             transform 320ms var(--ease),
             visibility 320ms;
}
html.has-drawer .drawer.is-open{
  opacity:1;
  visibility:visible;
  transform:none;
}

.drawer__inner{
  max-width:var(--frame);
  margin-inline:auto;
  padding-inline:var(--gutter);
  padding-block-start:6px;
  /* Definite, because .drawer is the scroller and has a definite height. It
     is what lets the foot below sit at the bottom of a short panel instead
     of directly under the last link. */
  min-height:100%;
  display:flex;
  flex-direction:column;
}

.drawer__group{
  padding-block:16px;
  border-block-end:var(--hair) solid var(--rule);
}
/* The foot draws the last rule. */
.drawer__group:last-of-type{border-block-end:0}

.drawer__label{
  margin-block-end:4px;
  font-size:var(--fs-caption);
  font-weight:500;
  letter-spacing:.16em;
  text-transform:uppercase;
  color:var(--ink-2);
}
html[dir="rtl"] .drawer__label{letter-spacing:0;text-transform:none;font-size:13px}

/* The clones keep their own classes, so the popover's type and spacing come
   with them. Only the box changes: full width, and the pressed ground pulled
   out to the gutter so it reads as a row rather than a chip. */
.drawer .menu__item,
.drawer .menu__app{
  padding-block:12px;
  padding-inline:12px;
  margin-inline:-12px;
}
.drawer .menu__t,
.drawer .menu__n{font-size:16px}
.drawer .menu__app img{height:26px}

/* docs.html has two plain links and no menus. */
.drawer .nav__plain{
  display:block;
  padding-block:13px;
  font-size:17px;
  color:var(--ink);
}

/* Thirteen destinations and three headings do not fit on a phone screen, and
   the one thing in here that is not a destination is the only thing anybody
   opened the panel to press. So it stays on the bottom edge while the list
   scrolls under it: `margin-block-start:auto` puts it there when the list is
   short — docs.html has two links — and `position:sticky` keeps it there
   when the list is long. The ground has to be opaque for the second of those
   to be worth anything, and at this end of the panel's gradient flat cream
   is what the glass has already arrived at. */
.drawer__foot{
  position:sticky;
  inset-block-end:0;
  margin-block-start:auto;
  /* Full bleed rather than on the inner's measure. The list passing under it
     has to have nothing to pass through, and a gutter-wide strip of clear
     ground down each side of an opaque bar is exactly that. It reads as the
     panel's own bottom edge, which is what it is; the rules above it belong
     to the list and stay on the list's measure. */
  margin-inline:calc(-1 * var(--gutter));
  padding-inline:var(--gutter);
  padding-block:16px calc(20px + env(safe-area-inset-bottom,0px));
  display:flex;
  flex-direction:column;
  background:var(--cream);
  border-block-start:var(--hair) solid var(--rule);
}
.drawer__cta{width:100%}

@media (prefers-reduced-motion:reduce){
  .drawer,
  .burger__bar{transition:none}
  .drawer{transform:none}
}
