/* XYROX — xyrox.ai
   World: "the object on the table". The page is a floating card on a warm grey
   ground, not a scrolling document. Ember is the only chromatic decision. */

:root{
  /* Ground + surfaces. The world is dark: one near-black ground, one card
     surface a measured step above it, one raised surface above that. The old
     light values are not deleted, they are re-pointed — every component that
     read them keeps working, and the phone's demo screen re-declares them
     locally so the mock website inside it stays a light website. */
  --grey:#FFFFFF; --grey-deep:#F6F5F2;
  --bone:#FBFAF7; --paper:#FFFFFF; --bone-dim:#F3F1ED;
  /* the spark: XYROX's answer to the reference's blue-olive-gold bar */
  --spark:linear-gradient(90deg,#E2643C 0%,#C8871A 48%,#6E9E93 100%);
  --rule:linear-gradient(90deg,rgba(226,100,60,.55) 0%,rgba(200,135,26,.30) 12%,
          rgba(38,32,26,.16) 30%,rgba(38,32,26,.13) 100%);
  --ink:#14171A; --ink-panel:#1B1E22; --ink-deep:#0C0E10;

  /* accent */
  --ember:#E2643C; --ember-deep:#D6592F; --ember-dim:#A34E2C; --ember-wash:rgba(226,100,60,.09);
  /* Ember as TYPE, not as a fill. #E2643C on white is 3.53:1 and fails; this
     is the tint that carries ember as small type on the light ground. Fills
     keep --ember. */
  --ember-lit:#A34E2C;

  /* warm neutrals, on white: 9.9:1, 5.9:1, 3.6:1 (400 is for hairline marks
     and placeholder text only, never for reading copy) */
  --stone-700:#443F39; --stone-500:#6B635A; --stone-400:#8A8179;
  --stone-200:#DED8CF; --stone-100:#EDE9E3;

  /* the void: pure black is the surface, never a dark grey. Ash and Silver are
     the only two greys allowed to speak on it — measured 7.5:1 and 11.2:1. */
  --void:#000000; --ash:#9A9A9A; --silver:#BDBDBD; --ember-lift:#F08A63;

  --display:'Bricolage Grotesque','Archivo',system-ui,sans-serif;
  --body:'Instrument Sans','Public Sans',system-ui,sans-serif;
  --mono:'JetBrains Mono',ui-monospace,'SF Mono',monospace;

  --r-pill:999px; --r-sm:10px; --r-md:16px; --r-lg:24px; --r-card:38px;
  --ctrl-h:36px;   /* every control in the nav row measures this tall */
  --sh-sm:0 1px 3px rgba(38,32,26,.10);
  --sh-md:0 8px 24px rgba(38,32,26,.10);
  --sh-lg:0 20px 52px rgba(38,32,26,.14);
  --sh-card:0 30px 80px rgba(38,32,26,.16);
  --ease:cubic-bezier(.16,1,.3,1);
  --wrap:1240px;
  /* the ground margin: the fixed nav has to line up with the card, so the
     card's own outer gap has to be a value both of them can read */
  --body-pad:22px;
  /* one number owns the page's vertical rhythm: every block — hero, section,
     footer — clears its dividers by exactly this. Change it here, nowhere else. */
  --sec-y:64px;
  /* and one for the gap between blocks inside a section — the section head to
     its content, a rule to what it divides. Ad-hoc margins here are what make
     one section read tighter than the next even when the padding matches. */
  --blk-y:44px;
  /* one token for the sheet's inset, because the void has to cancel it and put
     it back — two clamps that drift apart would leave the hero off-axis */
  --pad-x:clamp(22px,4vw,62px);
}
*{box-sizing:border-box}
[hidden]{display:none!important}
html{color-scheme:light;background:var(--grey);overflow-x:clip}

/* Pure white, and flat. The blooms that carried the colour on the dark ground
   would tint it, so the colour now lives only where it is doing work: the
   ember rule at the head of every divider, the accents, and the one dark card. */

/* This rule has now been deleted twice by edits that replaced the block above
   it and ran past its end. It sets the page's type; if body copy ever renders
   in Times, this is what went missing. */
body{
  margin:0;padding:0;background:transparent;color:var(--ink);
  font-family:var(--body);font-size:17px;line-height:1.6;letter-spacing:.01em;
  -webkit-font-smoothing:antialiased;
}
@media(max-width:760px){:root{--body-pad:10px}}

/* --- browser surfaces: these ship with defaults that belong to no design system --- */
::selection{background:var(--ember);color:var(--bone)}
::-moz-selection{background:var(--ember);color:var(--bone)}
:root{accent-color:var(--ember);caret-color:var(--ember)}
:focus-visible{outline:2px solid var(--ember);outline-offset:3px;border-radius:4px}
*{scrollbar-width:thin;scrollbar-color:var(--stone-400) transparent}
*::-webkit-scrollbar{width:10px;height:10px}
*::-webkit-scrollbar-thumb{background:var(--stone-400);border-radius:99px;border:3px solid var(--grey)}
*::-webkit-scrollbar-track{background:transparent}
a{color:inherit;text-underline-offset:3px;text-decoration-thickness:1px}
img,svg{display:block;max-width:100%}

/* --- the card --- */
.card-page{
  max-width:var(--wrap);margin:0 auto;background:transparent;
  /* not overflow:hidden — an ancestor that clips is a scroll container, and a
     scroll container that never scrolls kills position:sticky in everything
     below it. The one thing that needed clipping was the constellation, so the
     clip lives on the hero now. */
  border-radius:0;box-shadow:none;overflow:visible;position:relative;
  /* the sheet owns the horizontal inset; every block keeps its own vertical
     padding. Do not add a .pad rule here: as a class it out-specifies the
     bare `section` selector and silently zeroes every section's inset. */
  padding-inline:var(--pad-x);
}

/* --- type --- */
h1,h2,h3{font-family:var(--display);font-weight:700;letter-spacing:-.035em;line-height:1;margin:0;text-wrap:balance}
h1{font-size:clamp(42px,6.4vw,88px);letter-spacing:-.045em;line-height:.96}
h2{font-size:clamp(30px,4vw,54px)}
h3{font-size:21px;letter-spacing:-.02em;line-height:1.22}
p{margin:0 0 18px;max-width:68ch}
/* a block's last child never adds a trailing margin: the container's padding
   is what should show, top and bottom alike */
p:last-child,ul:last-child,ol:last-child,h2:last-child,h3:last-child{margin-bottom:0}
.lede{font-size:clamp(17px,1.5vw,20px);color:var(--stone-500);max-width:46ch}
.num{font-family:var(--mono);font-variant-numeric:tabular-nums;letter-spacing:-.02em}

/* --- controls --- */
.btn{
  display:inline-flex;align-items:center;gap:10px;font-family:var(--body);
  font-size:16px;font-weight:600;text-decoration:none;border:1px solid transparent;
  padding:15px 26px;border-radius:var(--r-pill);cursor:pointer;white-space:nowrap;
  transition:background .18s var(--ease),color .18s var(--ease),border-color .18s var(--ease),box-shadow .18s var(--ease),transform .18s var(--ease);
}
.btn svg{width:15px;height:15px;flex:none;transition:transform .18s var(--ease)}
.btn:hover svg{transform:translateX(3px)}
/* --- glass controls -------------------------------------------------------
   Every control is a lens: a translucent fill over a blurred backdrop, a lit
   top edge, a soft floor beneath. Each one states its opaque value FIRST and
   only thins out inside the @supports test, because a glass button that loses
   its blur must never lose its contrast with it. */
.btn-primary{background:var(--ink);color:var(--bone);box-shadow:var(--sh-sm)}
.btn-primary:hover{background:var(--ink-deep);box-shadow:var(--sh-md);transform:translateY(-1px)}
.btn-ember{background:var(--ember);color:var(--ink)}
.btn-ember:hover{background:var(--ember-deep);box-shadow:var(--sh-md);transform:translateY(-1px)}
.btn-ghost{background:var(--paper);color:var(--ink);border-color:var(--stone-200)}
.btn-ghost:hover{border-color:var(--stone-400);background:var(--paper)}

@supports ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){
  /* The two filled actions keep their colour at full strength and take only
     the glass treatment — lit top edge, soft floor, outer bloom. Thinning an
     accent fill over Bone washes the brand out for no gain: there is nothing
     behind a button worth seeing through. The materials — the bar, the pills,
     the ghost buttons, the plates — carry the real translucency. */
  .btn-ghost{
    -webkit-backdrop-filter:blur(18px) saturate(1.7);
    backdrop-filter:blur(18px) saturate(1.7);
  }
  .btn-primary{
    border-color:rgba(255,255,255,.14);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 10px 26px rgba(38,32,26,.22);
  }
  .btn-primary:hover{background:var(--ink-deep)}
  .btn-ember{
    border-color:rgba(255,255,255,.55);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.62),inset 0 -1px 0 rgba(120,40,20,.20),
               0 10px 26px rgba(226,100,60,.26);
  }
  .btn-ember:hover{background:var(--ember-deep)}
  .btn-ghost{
    background:rgba(255,255,255,.62);border-color:rgba(255,255,255,.78);
    box-shadow:inset 0 1px 0 rgba(255,255,255,.7),0 6px 18px rgba(38,32,26,.10);
  }
  .btn-ghost:hover{background:rgba(255,255,255,.8);border-color:rgba(255,255,255,.95)}
}
.btn-lg{padding:18px 32px;font-size:17px}

/* --- nav --- */
/* The nav leaves the flow so the two states can animate into one another:
   fixed from the first frame, sitting exactly where the card's own inset would
   have put it, and only its skin changes on scroll. .nav-rail keeps its seat
   in the flow. A fixed element is not clipped by the card's overflow, and its
   percentage width resolves against the viewport, so it tracks the card. */
.nav{
  position:fixed;z-index:50;
  top:var(--body-pad);left:0;right:0;margin-inline:auto;
  width:min(calc(100% - var(--body-pad) * 2),var(--wrap));
  display:flex;align-items:center;gap:18px;
  padding:13px var(--pad-x);
  border:1px solid transparent;
  /* at rest the bar carries the card's own top curve, so its corners cannot
     poke out past the sheet's rounded edge */
  border-radius:var(--r-card) var(--r-card) 0 0;
  background:rgba(255,255,255,.72);
  transition:top .55s var(--ease),width .55s var(--ease),padding .55s var(--ease),
             border-radius .55s var(--ease),background-color .4s ease,
             border-color .4s ease,box-shadow .4s ease,backdrop-filter .4s ease;
}
.nav-rail{height:calc(26px + var(--ctrl-h))}

/* scrolled: the bar lifts off the card and becomes a lens */
.nav-float{
  top:calc(var(--body-pad) + 10px);
  width:min(calc(100% - var(--body-pad) * 2 - var(--pad-x) * 2),calc(var(--wrap) - var(--pad-x) * 2));
  padding:7px 8px 7px 20px;
  border-radius:var(--r-pill);
  background:rgba(255,255,255,.9);
  border-color:rgba(38,32,26,.10);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9),0 14px 38px rgba(38,32,26,.14),
             0 2px 8px rgba(38,32,26,.07);
}
@supports ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){
  /* The material is on from the first frame — scrolling only changes the
     bar's shape and lift, not what it is made of. .78, not the .6 that looked
     better over a light section: the bar also passes over the dark report
     block, where .6 put the nav links at 4.07:1. Measured, not eyeballed. */
  .nav{
    -webkit-backdrop-filter:blur(26px) saturate(1.9);
    backdrop-filter:blur(26px) saturate(1.9);
  }
}
.brand{display:flex;align-items:center;gap:10px;text-decoration:none;font-family:var(--display);font-weight:700;font-size:23px;letter-spacing:-.03em}
.brand svg{width:27px;height:27px;color:var(--ink)}
.nav-links{display:flex;gap:6px;margin-left:26px}
.nav-links a{
  font-size:15px;font-weight:500;color:var(--stone-700);text-decoration:none;
  padding:9px 15px;border-radius:var(--r-pill);transition:background .18s var(--ease),color .18s var(--ease);
}
.nav-links a:hover{background:transparent;color:var(--ink)}
.nav-right{display:flex;align-items:center;gap:10px;margin-left:auto}
.nav-tel{
  display:inline-flex;align-items:center;gap:9px;font-family:var(--mono);font-size:14px;font-weight:500;
  text-decoration:none;height:var(--ctrl-h);padding:0 18px;box-sizing:border-box;
  /* no plate, no outline: on a glass bar the controls are type and nothing
     else, and the row is shorter for it */
  position:relative;
  border-radius:var(--r-pill);border:1px solid transparent;
  background:transparent;color:var(--stone-700);padding:0 11px;
  transition:color .18s var(--ease);
}
/* the controls shrank to 36px of type; the thumb still gets its 44 */
.nav-tel::after,.lang summary::after{content:"";position:absolute;inset:-5px -4px}
.nav-tel:hover{color:var(--ink);background:transparent}
.nav .btn{height:var(--ctrl-h);padding:0 12px;font-size:15px}
.nav .btn-primary{background:transparent;color:var(--ink);box-shadow:none;border-color:transparent}
.nav .btn-primary:hover{background:transparent;color:var(--ember-lit);transform:none;box-shadow:none}
.nav-tel svg{width:15px;height:15px;flex:none}
@media(max-width:1080px){.nav-links{display:none}}
/* the nav cannot hold four controls on a phone; the hero's own CTA sits
   directly below, so the nav keeps the two that cannot be reached elsewhere */
@media(max-width:620px){.nav .btn{display:none}}
@media(max-width:430px){.nav-tel span{display:none}.nav-tel{padding:0 13px}}

/* --- hero --- */
.hero{overflow:hidden;display:grid;grid-template-columns:1fr 1.04fr;gap:clamp(20px,3vw,44px);align-items:center;
  position:relative;z-index:1;
  padding-top:26px;padding-bottom:var(--sec-y)}
.hero-copy{position:relative;z-index:3;padding-bottom:8px}

/* weight 400 at display scale: the headline is sculptural, not loud. Bold at
   this size would shout; the negative tracking does the work instead. */
.hero h1{font-weight:400;font-size:clamp(42px,5.9vw,84px);letter-spacing:-.04em;line-height:1.04;
  color:var(--ink);margin-bottom:20px}
.hero-label{font-size:13px;font-weight:600;text-transform:uppercase;letter-spacing:.11em;
  color:var(--ember-lit);margin:0 0 12px;font-family:var(--body)}
/* ultra-light at reading size only works if the colour carries it: on Bone the
   thin strokes need Stone 700, not the 500 the rest of the page uses */
.hero .lede{font-family:var(--display);font-weight:200;font-size:clamp(17.5px,1.5vw,20px);
  line-height:1.5;letter-spacing:0;color:var(--stone-700);max-width:42ch;margin-bottom:24px}

.price-line{display:flex;align-items:baseline;gap:14px;flex-wrap:wrap;margin-bottom:24px}
.price-line .fig{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:clamp(30px,3.2vw,40px);font-weight:400;letter-spacing:-.04em;color:var(--ink)}
.price-line .note{font-size:14.5px;color:var(--stone-500)}
/* one call to action in the hero; the number lives in the nav */
.hero-act{display:flex;gap:16px;flex-wrap:wrap;align-items:center}

/* --- the stage: constellation, then device --- */
.stage{position:relative;--ph-h:clamp(400px,56vh,588px);
  /* just the device plus the slack its 8 degree tilt needs; nothing sits
     under it now, and reserved height that holds nothing reads as dead space */
  min-height:calc(var(--ph-h) + 44px);
  display:flex;align-items:center;justify-content:center}

.constellation{
  /* a canvas is a replaced element: with width:auto it takes its intrinsic
     300x150 and ignores the opposite inset, so the field must be sized
     explicitly rather than by inset alone */
  position:absolute;z-index:0;pointer-events:none;
  top:-11%;left:-15%;width:131%;height:124%;
  /* the field is wider than the stage, so its left edge is faded out: on a
     light ground a stray particle behind the headline is just dirt */
  -webkit-mask-image:linear-gradient(90deg,transparent 0,#000 12%,#000 100%);
  mask-image:linear-gradient(90deg,transparent 0,#000 12%,#000 100%);
}
/* the only gradient on the surface, and it belongs to the visualization */
.stage::before{content:"";position:absolute;z-index:0;left:50%;top:50%;
  width:min(680px,116%);aspect-ratio:1;transform:translate(-50%,-50%);border-radius:50%;
  background:radial-gradient(closest-side,rgba(226,100,60,.10),rgba(226,100,60,0) 70%);
  pointer-events:none}

/* three nested layers, because three transforms have to coexist: the mount
   carries the one-time entrance, the float carries the endless drift, and the
   device itself holds the static 8 degree tilt. Collapse any two and one
   animation silently overwrites the other's transform. */
.phone-mount,.phone-float{
  /* width is derived from height: the screens inside are absolutely positioned,
     so an auto width would collapse to zero in this flex context */
  position:relative;z-index:2;flex:none;
  height:var(--ph-h);width:calc(var(--ph-h) * 41 / 85);
}
.phone{
  position:relative;height:100%;width:100%;
  background:var(--ink-deep);border-radius:44px;padding:9px;
  box-shadow:0 36px 84px rgba(38,32,26,.30),0 0 0 1px rgba(20,23,26,.07);
  transform:rotate(-8deg);
}
/* The demo inside the phone is a client's website, and a client's website is
   light. Re-declaring the tokens here restores the whole light world for that
   subtree only — the components below never learn the page went dark. */
.screen{
  --paper:#FFFFFF; --bone:#FBFAF7; --ink:#14171A;
  --stone-700:#443F39; --stone-500:#6B635A; --stone-400:#8A8179;
  --stone-200:#DED8CF; --stone-100:#EDE9E3;
  /* ember as type belongs to the ground it sits on: the lit tint is for the
     dark page, and inside this light screen it would disappear */
  --ember-dim:#A34E2C; --ember-lit:#A34E2C; --ember-wash:rgba(226,100,60,.10);
  position:relative;width:100%;height:100%;border-radius:36px;overflow:hidden;background:var(--paper)}
.screen-view{position:absolute;inset:0;display:flex;flex-direction:column;
  opacity:0;visibility:hidden;transform:translateY(8px);
  transition:opacity .26s var(--ease),transform .3s var(--ease),visibility 0s linear .26s}
.screen-view[data-active="true"]{opacity:1;visibility:visible;transform:none;
  transition:opacity .26s var(--ease),transform .4s var(--ease)}

/* the demo site living inside the phone */
.sv-top{padding:26px 18px 14px;background:var(--ink);color:var(--bone);flex:none}
.sv-brand{font-family:var(--display);font-weight:700;font-size:15px;letter-spacing:-.02em;display:flex;align-items:center;gap:7px}
.sv-brand i{width:7px;height:7px;border-radius:50%;background:var(--ember);display:block}
.sv-h{font-family:var(--display);font-weight:700;font-size:22px;line-height:1.03;letter-spacing:-.03em;margin:14px 0 8px}
.sv-p{font-size:11.5px;color:rgba(251,250,247,.74);line-height:1.45;margin:0}
.sv-cta{margin-top:14px;background:var(--ember);color:var(--ink);font-weight:700;font-size:12px;
  padding:10px 0;border-radius:var(--r-pill);text-align:center}
.sv-body{padding:14px 18px;display:grid;gap:9px;background:var(--bone);flex:1;align-content:start}
.sv-row{display:flex;align-items:center;gap:9px;background:var(--paper);border:1px solid var(--stone-200);
  border-radius:12px;padding:10px 11px}
.sv-row b{font-size:11.5px;font-weight:600;display:block;line-height:1.2}
.sv-row span{font-size:11px;color:var(--stone-500);display:block}
.sv-ic{width:24px;height:24px;border-radius:8px;background:var(--ember-wash);display:grid;place-items:center;flex:none;color:var(--ember-lit)}
.sv-ic svg{width:12px;height:12px}
.sv-foot{
  /* margin, not margin-top: this is a <p>, and the global bottom margin was
     leaving an 18px white band under the footer inside the screen */
  margin:auto 0 0;padding:11px 18px;background:var(--ink);color:var(--bone);
  font-family:var(--mono);font-size:11px;text-align:center;letter-spacing:.03em}

/* The pinned labels overlap a near-black device, so they carry their own
   ground: a frosted plate. The opaque value is the fallback and is readable on
   its own; only where backdrop-filter exists does it thin out to glass.
   Measured over the darkest thing under them, the ink still clears 9:1. */
.plate{
  background:rgba(255,255,255,.9);
  border:1px solid rgba(255,255,255,.7);
  box-shadow:0 10px 30px rgba(38,32,26,.18),0 1px 2px rgba(38,32,26,.10);
}
@supports ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){
  .plate{
    background:rgba(255,255,255,.76);
    -webkit-backdrop-filter:blur(16px) saturate(1.5);
    backdrop-filter:blur(16px) saturate(1.5);
  }
}

/* the one fact left on the surface, pinned to the device's right. It keeps its
   frosted plate: it overlaps the phone's bezel by design, and the plate is what
   makes it readable there. */
.badge{
  /* pinned to the device, not to the stage: the phone is centred in the
     stage, so its top edge is 50% minus half its height, and the label hangs
     10% of the device down from there. 10px in from the edge, never flush. */
  position:absolute;z-index:3;right:10px;
  top:calc(50% - var(--ph-h) / 2 + var(--ph-h) * .1);
  display:flex;align-items:center;gap:9px;
  padding:11px 15px;border-radius:var(--r-md);white-space:nowrap;
  font-size:14px;font-weight:600;letter-spacing:-.01em;color:var(--ink);
}
.badge .dot{width:7px;height:7px;border-radius:50%;background:var(--ember);flex:none}

@media(max-width:1000px){
  .hero{grid-template-columns:1fr}
  .stage{--ph-h:clamp(360px,52vh,470px);margin-top:18px}
  .constellation{top:-6%;left:-14%;width:128%;height:114%}
}
@media(max-width:560px){
  :root{--sec-y:44px;--blk-y:32px}   /* the same two tokens, scaled for a phone */

  /* set on the stage, not the phone: min-height derives from this var, and
     overriding it on .phone alone left dead space below the device. A 390px
     column also has no room to the right of the device for a label, so on a
     phone the fact sits above it instead of covering the screen. */
  .stage{--ph-h:clamp(300px,40vh,380px);margin-top:6px;
    min-height:calc(var(--ph-h) + 84px);padding-top:40px}
  .badge{top:0;right:0;font-size:13px;padding:9px 12px}

  /* the thesis is the device: compress the copy stack so it breaks the fold */
  .hero{padding-top:12px;padding-bottom:calc(var(--sec-y) * .6)}
  .hero h1{font-size:38px;letter-spacing:-.035em;margin-bottom:14px}
  .hero .lede{font-size:16.5px;line-height:1.45;margin-bottom:20px}
  .price-line{margin-bottom:18px;gap:6px}
  .price-line .fig{font-size:27px}
  .price-line .note{font-size:13px}
  .hero-act .btn-ember{width:100%;justify-content:center;padding:16px 20px;font-size:16px}
  .nav{padding-top:16px}
}

/* --- generic sections --- */
section{position:relative;z-index:1;background:transparent;padding:var(--sec-y) 0;
  /* a 1px gradient instead of a border: the divider is where the colour
     shows, ember at the leading edge and gone by the middle */
  border-top:none;background-image:var(--rule);background-repeat:no-repeat;background-size:100% 1px}
.sec-head{margin-bottom:var(--blk-y)}
.sec-head h2{max-width:17ch}
.sec-head h2{margin-bottom:16px}
.sec-head p{color:var(--stone-500);max-width:48ch;margin:0}

/* premise: asymmetric, not a card grid */
.premise{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,5vw,72px);align-items:start}
@media(max-width:900px){.premise{grid-template-columns:1fr}}
.checks{list-style:none;margin:0;padding:8px 10px;border-radius:var(--r-lg);
  border:1px solid var(--stone-200);background:var(--paper);box-shadow:var(--sh-sm)}
.checks li{display:flex;gap:14px;align-items:flex-start;padding:15px 12px;
  font-size:16px;color:var(--stone-700);line-height:1.45;border-bottom:1px solid var(--stone-100)}
.checks li:last-child{border-bottom:none}
.checks .tick{width:22px;height:22px;flex:none;border-radius:50%;background:rgba(226,100,60,.16);display:grid;place-items:center;color:var(--ember-lit);margin-top:1px}
.checks .tick svg{width:11px;height:11px}

/* offers: one lead + two supports, deliberately not a triptych */
.offers{display:grid;grid-template-columns:1.35fr 1fr;gap:18px}
@media(max-width:900px){.offers{grid-template-columns:1fr}}
.offer{background:var(--paper);border:1px solid var(--stone-200);border-radius:var(--r-lg);padding:clamp(26px,3vw,38px);
  transition:border-color .2s var(--ease),box-shadow .2s var(--ease),transform .2s var(--ease)}
.offer:hover{border-color:var(--stone-400);box-shadow:var(--sh-md);transform:translateY(-2px)}
.offer h3{margin-bottom:10px}
.offer p{font-size:16px;color:var(--stone-500);margin:0;max-width:44ch}
.offer-lead{grid-row:span 2;display:flex;flex-direction:column;justify-content:space-between}
.offer-lead h3{font-size:clamp(24px,2.6vw,32px);letter-spacing:-.03em}
.offer-lead p{color:rgba(251,250,247,.66);max-width:36ch}
.offer-lead:hover{transform:none;box-shadow:none}
.offer-price{margin-top:34px;display:flex;align-items:baseline;gap:12px;flex-wrap:wrap}
.offer-price .fig{font-family:var(--mono);font-variant-numeric:tabular-nums;font-size:29px;font-weight:500;letter-spacing:-.03em}
.offer-price .sub{font-size:13.5px;color:rgba(251,250,247,.72)}

/* steps: a real sequence, so the order is information.

   No rules around them. A band closed by a border at the top and left open at
   the bottom reads as hanging from the line above it however symmetric its
   padding measures — and it measured symmetric twice. Whitespace carries the
   grouping instead, which is also what the dark reference does. */
.steps{display:grid;grid-template-columns:repeat(3,1fr);gap:0;
  margin-top:var(--sec-y);padding:0}
@media(max-width:820px){.steps{grid-template-columns:1fr;gap:34px}}
.step{padding:0 26px;border:none}
.step:first-child{padding-left:0}
.step:last-child{padding-right:0}
@media(max-width:820px){.step{padding-left:0;padding-right:0}}
.step .n{font-family:var(--mono);font-size:12px;color:var(--ember-lit);letter-spacing:.1em;display:block;margin-bottom:14px}
.step h3{margin-bottom:8px}
.step p{font-size:15.5px;color:var(--stone-500);margin:0;max-width:34ch}

/* report: the one dark moment */
/* --- the dark card -------------------------------------------------------
   One material, used wherever the page goes dark: Ink, no border, no shadow,
   the same radius, and the same ember bloom off its top-right corner. The
   report card is the prototype; the offer lead is the same card at a smaller
   size, so the bloom is sized as a share of the card rather than in pixels —
   620px on the 1124px report is 56% of it. Only the padding stays local: each
   card takes the inset of the row it sits in. */
.dark-card{
  background:var(--ink);color:var(--bone);
  border:none;border-radius:var(--r-lg);
  position:relative;overflow:hidden;
}
.dark-card::before{
  content:"";position:absolute;right:-12%;top:-40%;width:56%;aspect-ratio:1;
  border-radius:50%;pointer-events:none;
  background:radial-gradient(circle,rgba(226,100,60,.22),rgba(226,100,60,0) 64%);
}
.dark-card > *{position:relative;z-index:1}

.report{padding:clamp(34px,5vw,68px)}
.report h2{color:var(--bone);max-width:16ch;margin-bottom:18px}
.report .lede{color:rgba(251,250,247,.66);max-width:54ch}
.rgrid{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;margin-top:44px;background:rgba(251,250,247,.13);border-radius:var(--r-md);overflow:hidden}
@media(max-width:900px){.rgrid{grid-template-columns:repeat(2,1fr)}}
@media(max-width:520px){.rgrid{grid-template-columns:1fr}}
.rcell{background:var(--ink);padding:24px 22px}
.rcell .k{font-family:var(--mono);font-size:11px;letter-spacing:.14em;text-transform:uppercase;color:var(--ember-lit);margin-bottom:11px}
.rcell p{font-size:15px;color:rgba(251,250,247,.72);margin:0;line-height:1.5}
.caveat{margin-top:32px;font-size:14.5px;color:rgba(251,250,247,.68);max-width:64ch}
.caveat b{color:var(--bone);font-weight:600}

/* pricing */
.prices{display:grid;grid-template-columns:1fr 1fr;gap:18px}
@media(max-width:820px){.prices{grid-template-columns:1fr}}
.price{background:var(--paper);border:1px solid var(--stone-200);border-radius:var(--r-lg);padding:clamp(28px,3vw,40px);display:flex;flex-direction:column}
.price.lead{border-color:var(--ember)}
.price h3{font-size:25px;margin-bottom:6px}
.price .sub{font-size:15.5px;color:var(--stone-500);margin:0 0 26px}
/* Prices read as a numeric table: low number, dash, high number, label.
   Each column is right-aligned so $50 sits under $1,500 and $250 under
   $3,000 — digits line up in a column, not just within a line. */
.figures{display:grid;grid-template-columns:auto auto auto auto;justify-content:start;
  column-gap:12px;row-gap:8px;align-items:baseline}
.figure,.fig-a,.fig-b{font-family:var(--mono);font-variant-numeric:tabular-nums;
  font-size:clamp(26px,2.6vw,33px);font-weight:500;letter-spacing:-.03em;line-height:1.15}
.fig-a,.fig-b{text-align:right}
.fig-d{font-family:var(--mono);font-size:clamp(22px,2.2vw,28px);color:var(--stone-400);
  text-align:center;line-height:1.15}
.fig-note{font-family:var(--mono);font-size:13px;font-weight:400;color:var(--stone-500);
  letter-spacing:.02em;line-height:1.15;white-space:nowrap;padding-left:4px}
.figures--single{grid-template-columns:auto auto}

@media(max-width:560px){
  /* keep the numeric columns; the label drops to its own row so the
     alignment survives on a phone */
  .figures{grid-template-columns:auto auto auto;column-gap:10px;row-gap:4px;justify-content:start}
  .fig-note{grid-column:1 / -1;padding-left:0;margin-bottom:10px}
  .figures--single{grid-template-columns:auto}
}
.checks--bare{border:none;background:none;box-shadow:none;padding:0;border-radius:0}
.checks--bare li{padding:9px 0;border-bottom:none;font-size:15.5px}
.price .checks--bare{margin:28px 0 30px}
.price .btn{margin-top:auto;justify-content:center}

/* faq */
.faq{border-top:1px solid var(--stone-200);margin-top:var(--blk-y);padding-top:6px}
.faq details{border-bottom:1px solid var(--stone-200)}
.faq summary{cursor:pointer;list-style:none;padding:26px 46px 26px 0;font-weight:600;font-size:18.5px;position:relative;transition:color .18s var(--ease)}
summary::-webkit-details-marker{display:none}
.faq summary:hover{color:var(--ember-lit)}
.faq summary::after{content:"";position:absolute;right:8px;top:50%;width:11px;height:11px;
  border-right:2px solid var(--stone-400);border-bottom:2px solid var(--stone-400);
  transform:translateY(-70%) rotate(45deg);transition:transform .22s var(--ease)}
.faq details[open] summary::after{transform:translateY(-30%) rotate(-135deg)}
.faq details p{font-size:16.5px;color:var(--stone-500);margin:0 0 26px;max-width:66ch}

/* contact */
.contact{display:grid;grid-template-columns:1fr 1fr;gap:clamp(28px,5vw,64px);align-items:start}
@media(max-width:940px){.contact{grid-template-columns:1fr}}
.contact-alt{margin-top:26px;font-size:16px;color:var(--stone-500)}
.contact-alt a{color:var(--ember-lit);font-weight:600;text-decoration:none}
.contact-alt a:hover{text-decoration:underline}
.form-card{background:var(--paper);border:1px solid var(--stone-200);border-radius:var(--r-lg);padding:clamp(26px,3vw,36px)}
.form-head{font-family:var(--display);font-weight:700;font-size:22px;letter-spacing:-.03em;margin:0 0 22px}
.field-row{display:grid;grid-template-columns:1fr 1fr;gap:14px}
@media(max-width:520px){.field-row{grid-template-columns:1fr}}
.field{margin-bottom:16px;display:flex;flex-direction:column}
.field label{font-size:13.5px;font-weight:600;color:var(--stone-700);margin-bottom:7px}
.field label span[aria-hidden]{color:var(--ember-lit)}
.field .opt{font-weight:400;color:var(--stone-500);font-size:12.5px}
.field input,.field select,.field textarea{
  font-family:var(--body);font-size:16px;color:var(--ink);background:var(--grey-deep);
  border:1px solid var(--stone-200);border-radius:var(--r-md);padding:13px 15px;width:100%;
  transition:border-color .18s var(--ease),box-shadow .18s var(--ease),background .18s var(--ease);
}
.field textarea{resize:vertical;min-height:86px;line-height:1.5}
.field input::placeholder,.field textarea::placeholder{color:var(--stone-400)}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;background:var(--paper);border-color:var(--ember);box-shadow:0 0 0 3px var(--ember-wash)}
.field select{appearance:none;cursor:pointer;padding-right:40px;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 4.5 L6 8 L9.5 4.5' fill='none' stroke='%238A8179' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 15px center;background-size:13px}
.field input.is-bad,.field textarea.is-bad{border-color:var(--ember-lit);background:rgba(226,100,60,.05)}
.err{font-size:13px;color:var(--ember-lit);margin:6px 0 0}
.err:empty{display:none}
.hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}
.btn-submit{width:100%;justify-content:center;margin-top:6px}
.btn-submit:disabled{opacity:.72;cursor:default;transform:none}
.btn-spin{display:inline-flex;align-items:center;gap:9px}
.btn-spin::before{content:"";width:14px;height:14px;border-radius:50%;
  border:2px solid rgba(251,250,247,.3);border-top-color:var(--bone);animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.form-foot{font-size:13px;color:var(--stone-500);margin:14px 0 0;text-align:center}
.form-error{margin:16px 0 0;font-size:14.5px;color:var(--ember-lit);background:var(--ember-wash);
  border:1px solid rgba(226,100,60,.24);border-radius:var(--r-md);padding:12px 14px}
.form-error a{color:var(--ember-lit);font-weight:600}
.form-done{text-align:center;padding:24px 6px 14px;outline:none}
.form-done .done-mark{width:48px;height:48px;border-radius:50%;background:var(--ember-wash);
  display:grid;place-items:center;margin:0 auto 18px;color:var(--ember-lit)}
.form-done .done-mark svg{width:21px;height:21px}
.form-done h3{font-size:25px;margin-bottom:10px}
.form-done p{font-size:16px;color:var(--stone-500);margin:0 auto;max-width:38ch}

/* footer */
footer{position:relative;z-index:1;background:transparent;
  border-top:none;background-image:var(--rule);background-repeat:no-repeat;background-size:100% 1px;
  padding:var(--sec-y) 0;display:flex;justify-content:space-between;
  gap:22px;flex-wrap:wrap;align-items:center}
footer p{font-size:14px;color:var(--stone-500);margin:0}
.foot-contact{display:flex;gap:22px;flex-wrap:wrap}
.foot-contact a{color:var(--stone-500);text-decoration:none;font-size:14px}
.foot-contact a:hover{color:var(--ember-lit)}

/* sticky-nav clearance for in-page jumps */
#top,#websites,#afterhours,#thebuild,#thereport,#compare,#report,#pricing,#faq,#contact{scroll-margin-top:104px}

/* --- motion layer -------------------------------------------------------
   One entrance, played once, and then a slow ambient loop that never resolves.
   Grammar: converge and settle. Nothing bounces, nothing waits on scroll.
   Every resting state is the class-free state, so a stylesheet that never
   arrives still leaves a readable page. */

/* the headline arrives a word at a time from behind its own baseline. Each
   word is masked by its wrapper; the extra padding keeps descenders from
   being sliced off by that mask. */
.h-words .w{display:inline-block;overflow:hidden;vertical-align:bottom;
  padding-bottom:.14em;margin-bottom:-.14em}
.h-words .w > span{display:inline-block;animation:word-up .82s var(--ease) both}
.h-words .w:nth-child(1) > span{animation-delay:.06s}
.h-words .w:nth-child(2) > span{animation-delay:.11s}
.h-words .w:nth-child(3) > span{animation-delay:.16s}
.h-words .w:nth-child(4) > span{animation-delay:.21s}
.h-words .w:nth-child(5) > span{animation-delay:.26s}
.h-words .w:nth-child(6) > span{animation-delay:.31s}
.h-words .w:nth-child(7) > span{animation-delay:.36s}
.h-words .w:nth-child(8) > span{animation-delay:.41s}
.h-words .w:nth-child(9) > span{animation-delay:.46s}
.h-words .w:nth-child(10) > span{animation-delay:.51s}
.h-words .w:nth-child(11) > span{animation-delay:.56s}
.h-words .w:nth-child(12) > span{animation-delay:.61s}
@keyframes word-up{from{transform:translateY(108%)}to{transform:translateY(0)}}

/* the rest of the copy stack follows the headline up */
.rise{animation:rise .7s var(--ease) both}
.hero-label{animation-delay:.44s}
.hero .lede{animation-delay:.5s}
.price-line{animation-delay:.58s}
.hero-act{animation-delay:.66s}
@keyframes rise{from{opacity:0;transform:translateY(16px)}to{opacity:1;transform:none}}

/* the device rises into the constellation, then never quite stops moving */
@keyframes settle{from{opacity:0;transform:translateY(34px) scale(.96)}
                  to{opacity:1;transform:none}}
@keyframes drift{from{transform:translateY(0)}to{transform:translateY(-10px)}}
.phone-mount{animation:settle .95s var(--ease) both .34s}
.phone-float{animation:drift 7.5s ease-in-out 1.4s infinite alternate}

@keyframes badge-in{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
.badge{animation:badge-in .6s var(--ease) both 1.05s}

/* the live dot actually pulses; it is the only thing on the page claiming to
   be live, so it may as well behave like it */
@keyframes dot-pulse{0%{box-shadow:0 0 0 0 rgba(226,100,60,.55)}
                     70%,100%{box-shadow:0 0 0 10px rgba(226,100,60,0)}}
.badge .dot{animation:dot-pulse 2.6s ease-out 1.8s infinite}

/* a sheen crosses the glass every eleven seconds — 12% of the cycle moving,
   88% still, so it reads as a glance of light rather than a loop */
.screen::after{content:"";position:absolute;inset:-40%;z-index:5;pointer-events:none;
  background:linear-gradient(100deg,transparent 42%,rgba(255,255,255,.34) 50%,transparent 58%);
  animation:sheen 11s ease-in-out 2.4s infinite}
@keyframes sheen{0%,88%{transform:translateX(-150%)}100%{transform:translateX(150%)}}

/* each swap replays the rows: the page inside the phone re-renders, it does
   not merely cross-fade */
.screen-view[data-active="true"] .sv-row{animation:rise .5s var(--ease) both .1s}
.screen-view[data-active="true"] .sv-row:nth-child(2){animation-delay:.18s}
.screen-view[data-active="true"] .sv-cta{animation:rise .5s var(--ease) both .06s}

/* Reduced motion: fewer and gentler, never blind. Spatial movement goes;
   feedback, focus, and state changes stay legible. The constellation still
   draws — it simply stops moving (see hero-constellation.js). */
@media (prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  .h-words .w{overflow:visible;padding-bottom:0;margin-bottom:0}
  .h-words .w > span,.rise,.phone-mount,.phone-float,.badge{animation:none}
  .badge .dot,.screen::after{animation:none}
  .screen::after{display:none}
  .screen-view[data-active="true"] .sv-row,
  .screen-view[data-active="true"] .sv-cta{animation:none}
  .btn:hover,.btn-primary:hover,.btn-ember:hover,.offer:hover{transform:none}
  .btn:hover svg{transform:none}
  .btn-spin::before{animation:none}
  .screen-view{transition:none;transform:none}
}

/* language dropdown — sits after the primary CTA, works without JS */
.lang{position:relative;flex:none}
.lang summary{
  list-style:none;cursor:pointer;display:inline-flex;align-items:center;gap:7px;
  font-family:var(--mono);font-size:13px;font-weight:500;letter-spacing:.04em;color:var(--stone-700);
  height:var(--ctrl-h);padding:0 9px;box-sizing:border-box;
  border:1px solid transparent;border-radius:var(--r-pill);
  background:transparent;transition:color .18s var(--ease);
}
.lang summary::-webkit-details-marker{display:none}
.lang summary:hover{color:var(--ink)}
.lang summary:focus-visible{outline:2px solid var(--ember);outline-offset:2px}
.lang summary svg{width:11px;height:11px;transition:transform .2s var(--ease)}
.lang[open] summary{color:var(--ink)}
.lang[open] summary svg{transform:rotate(180deg)}
.lang-menu{
  position:absolute;right:0;top:calc(100% + 8px);z-index:20;min-width:158px;
  background:var(--paper);border:1px solid var(--stone-200);border-radius:var(--r-md);
  box-shadow:var(--sh-lg);padding:6px;display:grid;gap:2px;
}
.lang-menu a{
  display:block;padding:10px 12px;border-radius:calc(var(--r-md) - 6px);
  font-size:15px;font-weight:500;color:var(--stone-700);text-decoration:none;white-space:nowrap;
  transition:background .15s var(--ease),color .15s var(--ease);
}
.lang-menu a:hover{background:var(--bone-dim);color:var(--ink)}
.lang-menu a[aria-current]{color:var(--ink);font-weight:600}
.lang-menu a[aria-current]::after{content:"";float:right;width:6px;height:6px;border-radius:50%;
  background:var(--ember);margin:7px 0 0 10px}
@media (prefers-reduced-motion:reduce){.lang summary svg{transition:none}}

/* the check list is a real list, so a capped sibling stagger is the honest
   reveal. JS adds .reveal, so with no JS the content is simply visible. */
.checks.reveal li{opacity:0;transform:translateY(10px);
  transition:opacity .45s var(--ease),transform .45s var(--ease)}
.checks.reveal li.in{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  .checks.reveal li{opacity:1;transform:none;transition:none}
}

/* ==========================================================================
   SCENES — the illustrated moments, and the scroll that locks them.

   A scene is a tall track with a sticky pin inside it. The pin holds the
   viewport while the track scrolls past, so the artwork stays still long
   enough to be read while its beats arrive. JS only sets data-beat on the
   pin; every beat's resting state is visible, so with no JS (or with reduced
   motion) the scene is simply a section with all of its parts showing.
   ========================================================================== */
.scene{padding:0;border-top:none;background-image:var(--rule);background-repeat:no-repeat;background-size:100% 1px}
.scene-track{position:relative}
/* No pin, no scroll lock: the scene is an ordinary block and its beats play
   themselves the first time it comes into view. Locking the viewport made the
   page three screens longer for three pictures. */
.scene-pin{
  display:grid;grid-template-columns:minmax(0,.86fr) minmax(0,1.14fr);
  gap:clamp(24px,4vw,72px);align-items:center;
  padding-block:var(--sec-y);
}
@media(max-width:960px){
  /* A collage positioned in percentages has nowhere to go in a 346px column —
     it just pushes the page sideways. Below this width the art is an ordinary
     stack: same parts, read top to bottom. */
  .scene-pin{grid-template-columns:1fr}
  /* the parts carry their collage coordinates as inline styles, so unwinding
     them takes !important — nothing else outranks an attribute */
  .scene .art{aspect-ratio:auto;min-height:0;display:grid;gap:14px;margin-top:28px}
  .scene .art > *{position:static!important;inset:auto!important;max-width:100%}
  /* panels and bubbles fill the column; a pane whose only content is
     percentage-width rules has no intrinsic width and would collapse */
  .scene .art > .pane,.scene .art > .bub,.scene .art > .later{width:100%!important}
  .scene .art > .chip,.scene .art > .stamp{width:auto!important;justify-self:start}
  .scene .art .art-orbit,.scene .art .wire{display:none}
  .scene .chip--tail::after{display:none}
  .scene .art .chip{width:42px!important;height:42px!important}
  .scene .bub,.scene .bub--wide{max-width:none}
  .scene .later{justify-content:flex-start}
}
.scene-copy{position:relative;z-index:2}
.scene-copy h2{max-width:15ch;margin-bottom:18px}
.scene-copy .lede{color:var(--stone-500);max-width:44ch}
.scene-eyebrow{
  font-family:var(--mono);font-size:12px;letter-spacing:.16em;text-transform:uppercase;
  color:var(--ember-lit);margin:0 0 18px;
}

/* --- the stage the parts float on --------------------------------------- */
.art{position:relative;aspect-ratio:4/3;width:100%;min-height:380px}
.art .art-orbit{position:absolute;inset:-6% -4%;z-index:0;pointer-events:none;opacity:.8}
.art > *{position:absolute;z-index:2}

/* a dark pane: the same material as the cards, one step quieter */
.pane{
  background:var(--paper);border:1px solid var(--stone-200);
  border-radius:var(--r-md);box-shadow:var(--sh-md);
  padding:14px 15px;
}
@supports ((-webkit-backdrop-filter:blur(1px)) or (backdrop-filter:blur(1px))){
  .pane{background:rgba(255,255,255,.78);-webkit-backdrop-filter:blur(18px);backdrop-filter:blur(18px)}
}

/* a white chip, the way the reference pins an icon to a thread */
.chip{
  width:46px;height:46px;border-radius:12px;background:var(--ink);color:var(--bone);
  display:grid;place-items:center;box-shadow:0 10px 26px rgba(38,32,26,.22);
}
.chip svg{width:20px;height:20px}
/* the little tail that makes a chip point at what it belongs to */
.chip--tail::after{
  content:"";position:absolute;left:14px;bottom:-6px;width:12px;height:12px;
  background:var(--ink);clip-path:polygon(0 0,100% 0,0 100%);
}

/* a timestamp, glowing the way a light does in the dark */
.stamp{
  display:flex;align-items:center;gap:8px;white-space:nowrap;
  font-family:var(--mono);font-size:14px;letter-spacing:.06em;color:var(--stone-700);
}
.stamp svg{width:15px;height:15px;color:var(--ember-lit);flex:none}

/* the message bubbles: the customer speaks in grey, XYROX in ember */
.bub{
  border-radius:16px;padding:15px 18px;font-size:16px;line-height:1.4;max-width:34ch;
  background:var(--bone-dim);border:1px solid var(--stone-200);color:var(--ink);
  box-shadow:var(--sh-sm);
}
.bub--x{
  background:linear-gradient(150deg,rgba(226,100,60,.17),rgba(226,100,60,.07));
  border-color:rgba(226,100,60,.32);
}
.bub--wide{max-width:40ch}

/* the dotted wiring between parts */
.art .wire{position:absolute;inset:0;z-index:1;pointer-events:none;overflow:visible}
.wire path{fill:none;stroke:rgba(20,23,26,.30);stroke-width:1.6;stroke-dasharray:2 7;stroke-linecap:round}
.wire .node{fill:rgba(20,23,26,.30)}

/* --- scene 1: after hours ---------------------------------------------- */
.wave{display:flex;align-items:center;gap:2px;height:26px}
.wave i{display:block;width:2px;border-radius:2px;background:rgba(20,23,26,.45)}
.line{display:block;height:8px;border-radius:99px;background:rgba(20,23,26,.12)}

/* --- scene 2: the two weeks -------------------------------------------- */
.later{
  display:flex;align-items:center;justify-content:center;gap:14px;
  font-family:var(--mono);font-size:15px;letter-spacing:.12em;color:var(--ink);
  border-radius:99px;padding:13px 26px;
  background:linear-gradient(90deg,rgba(226,100,60,.26),rgba(255,184,41,.24),rgba(226,100,60,.12));
  box-shadow:0 8px 30px rgba(226,100,60,.22),inset 0 1px 0 rgba(255,255,255,.7);
}
.later svg{width:17px;height:17px}

/* --- scene 3: the report ------------------------------------------------ */
.rank{display:grid;gap:9px}
.rank li{
  display:flex;gap:12px;align-items:flex-start;list-style:none;
  background:var(--grey-deep);border:1px solid var(--stone-200);
  border-radius:12px;padding:12px 13px;font-size:14.5px;line-height:1.4;
}
.rank b{font-family:var(--mono);font-size:12px;color:var(--ember-lit);flex:none;padding-top:2px}

/* --- the beats ---------------------------------------------------------- */
.beat{opacity:1;transform:none;transition:opacity .5s var(--ease),transform .5s var(--ease)}
[data-beat] .beat[data-at]{opacity:0;transform:translateY(14px)}
[data-beat="0"] .beat[data-at="0"],
[data-beat="1"] .beat[data-at="0"],[data-beat="1"] .beat[data-at="1"],
[data-beat="2"] .beat[data-at="0"],[data-beat="2"] .beat[data-at="1"],[data-beat="2"] .beat[data-at="2"]
{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){
  [data-beat] .beat[data-at]{opacity:1;transform:none;transition:none}
}

/* --- before / with -------------------------------------------------------
   One card, not a bare table on the page. The "with" column is a tinted panel
   inside it, rounded at both ends, so the eye reads a comparison rather than a
   grid — and the header carries the mark on the spark, the way the reference
   heads its own column. */
.vs-card{
  margin-top:var(--blk-y);
  background:var(--paper);border:1px solid var(--stone-200);
  border-radius:var(--r-lg);box-shadow:var(--sh-md);
  padding:clamp(12px,1.5vw,20px);
}
.vs{width:100%;border-collapse:separate;border-spacing:0;margin:0}
.vs th,.vs td{text-align:left;padding:18px 22px;vertical-align:top;
  font-size:15.5px;line-height:1.45}
.vs thead th{
  font-family:var(--body);font-size:12.5px;font-weight:600;letter-spacing:.1em;
  text-transform:uppercase;color:var(--stone-500);padding-block:16px 14px;
}
.vs thead .now{color:var(--ink)}
.vs tbody th,.vs tbody td{border-top:1px solid var(--stone-100)}
.vs tbody tr:first-child th,.vs tbody tr:first-child td{border-top:none}
.vs .rowhead{
  width:20%;white-space:nowrap;font-family:var(--mono);font-size:12px;
  font-weight:400;letter-spacing:.08em;text-transform:uppercase;color:var(--stone-400);
  padding-top:21px;
}
.vs .was{width:40%;color:var(--stone-500)}
/* the tinted column: one continuous panel, capped top and bottom */
.vs .now{width:40%;color:var(--ink);background:rgba(226,100,60,.055)}
.vs thead .now{border-radius:var(--r-md) var(--r-md) 0 0}
.vs tbody tr:last-child .now{border-radius:0 0 var(--r-md) var(--r-md)}
.vs .mark{display:inline-flex;width:16px;height:16px;margin-right:11px;vertical-align:-2px;flex:none}
.vs .was .mark{color:var(--stone-400)}
.vs .now .mark{color:var(--ember-lit)}
/* the mark on the spark, at the head of the column that is ours */
.vs-spark{
  display:inline-grid;place-items:center;width:22px;height:22px;border-radius:7px;
  background:var(--spark);margin-right:10px;vertical-align:-6px;
  box-shadow:0 3px 8px rgba(226,100,60,.28);
}
.vs-spark svg{width:12px;height:12px;color:#fff}

@media(max-width:820px){
  .vs-card{padding:6px 4px}
  .vs,.vs thead,.vs tbody,.vs tr,.vs th,.vs td{display:block;width:auto}
  .vs thead{display:none}
  .vs tbody tr{padding:18px 16px;border-bottom:1px solid var(--stone-100)}
  .vs tbody tr:last-child{border-bottom:none}
  .vs th,.vs td{padding:5px 0;border:none!important}
  .vs .rowhead{color:var(--ember-lit);padding-top:0;padding-bottom:9px}
  .vs .now{background:transparent;border-radius:0}
}

/* The spark. The reference hangs a small gradient tile beside anything its
   product said; this is the same gesture with XYROX's own mark punched out of
   the ember-gold-teal ramp, so the colour lands where the brand is speaking
   rather than as decoration. Built from pseudo-elements: the bubbles are
   already positioned, and none of them needed new markup. */
.bub--x{position:relative}
.bub--x::after{
  content:"";position:absolute;right:-56px;top:calc(50% - 21px);
  width:42px;height:42px;border-radius:12px;background:var(--spark);
  box-shadow:0 12px 30px rgba(0,0,0,.55),inset 0 1px 0 rgba(255,255,255,.28);
}
.bub--x::before{
  content:"";position:absolute;right:-45px;top:calc(50% - 10px);
  width:20px;height:20px;z-index:1;background:var(--bone);
  -webkit-mask:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Cg%20fill%3D%22none%22%20stroke%3D%22%23fff%22%20stroke-width%3D%227%22%3E%3Cpath%20d%3D%22M6%2042%20L6%2020%20A14%2014%200%200%201%2020%206%20L42%206%22%2F%3E%3Cpath%20d%3D%22M58%2022%20L58%2044%20A14%2014%200%200%201%2044%2058%20L22%2058%22%2F%3E%3C%2Fg%3E%3Crect%20x%3D%2224%22%20y%3D%2224%22%20width%3D%2216%22%20height%3D%2216%22%20rx%3D%223%22%20fill%3D%22%23fff%22%2F%3E%3C%2Fsvg%3E") center/contain no-repeat;
          mask:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2064%2064%22%3E%3Cg%20fill%3D%22none%22%20stroke%3D%22%23fff%22%20stroke-width%3D%227%22%3E%3Cpath%20d%3D%22M6%2042%20L6%2020%20A14%2014%200%200%201%2020%206%20L42%206%22%2F%3E%3Cpath%20d%3D%22M58%2022%20L58%2044%20A14%2014%200%200%201%2044%2058%20L22%2058%22%2F%3E%3C%2Fg%3E%3Crect%20x%3D%2224%22%20y%3D%2224%22%20width%3D%2216%22%20height%3D%2216%22%20rx%3D%223%22%20fill%3D%22%23fff%22%2F%3E%3C%2Fsvg%3E") center/contain no-repeat;
}
@media(max-width:960px){
  /* stacked, the bubbles run the full column and there is no margin to hang
     a tile in — it moves inside, at the trailing edge */
  .scene .bub--x{padding-right:64px}
  .bub--x::after{right:12px}
  .bub--x::before{right:23px}
}


/* ==========================================================================
   THE REEL — the marketing film, as the first screen.

   Imported from the Claude Design project "XYROX Marketing Reel". It is a
   React composition on a 1920x1080 stage, so it is loaded lazily and never
   blocks paint (see reel/reel-boot.js). Everything here is about the box it
   plays in and the poster that stands in its place.
   ========================================================================== */
.reel-hero{
  position:relative;
  /* the rail already stands above it, so the screen minus the bar is what
     actually reaches the fold. svh, not vh: on a phone vh is the tallest the
     viewport ever gets, so 100vh starts life taller than the screen. */
  /* The film starts at the very top of the page, not under the bar. The rail
     reserves the nav's height in the flow so ordinary sections clear it; the
     hero pulls back up through that reservation and runs the full screen, and
     the nav floats on the film instead of sitting on a white strip above it. */
  --reel-h:100vh;
  --reel-h:100svh;
  margin-top:calc(-1 * var(--rail-h,70px));
  min-height:var(--reel-h);
  /* edge to edge: out of the sheet entirely, since a film has no margins */
  width:100vw;margin-left:calc(50% - 50vw);
  /* the Hero cut is authored on the light theme, so the box it plays in is
     paper — the same --paper-50 the film paints, so any sub-pixel slack at the
     edges of the cover scale shows nothing at all. */
  background:#FAF7F2;
  overflow:hidden;
}
.reel-stage{position:absolute;inset:0}

/* The engine fits 1920x1080 into whatever box it is handed, reserving 44px of
   it for a playback scrubber, and it centres the stage with a flex box holding
   a flex-shrink:0 SVG. The moment that box is narrower than 1920 the SVG
   overflows, an overflowing flex item is start-aligned rather than centred,
   and scaling it about its centre walks it sideways.

   So the box is its native size instead: 1920 wide and 1080+44 tall. The
   engine's own fit then resolves to exactly 1, nothing overflows, and nothing
   is mis-centred. Covering the screen is done here, with one scale set from
   the hero's real measurements (see reel-boot.js) — max(), not min(), so the
   film always bleeds past the edges rather than letterboxing. The trailing
   translate lifts the 1080 film to the hero's centre, leaving the 44px
   scrubber below the bottom edge where the hero clips it. */
.reel-stage > #reel{
  position:absolute;left:50%;top:50%;
  width:1920px;height:1124px;
  /* the origin is the FILM's centre, not the box's — the box carries 44px of
     scrubber it must not be centred by. Placing the origin there and pulling
     back by exactly half the film means the centring holds at every scale,
     with no fudge factor to drift. */
  transform-origin:960px 540px;
  /* --reel-dx/dy are a measured correction, applied after the scale: the
     engine centres its SVG inside a box it sized for a 44px scrubber that
     actually renders 37, which leaves a few pixels of slack. Measuring beats
     hard-coding a number that belongs to someone else's component. */
  transform:translate(var(--reel-dx,0px),var(--reel-dy,0px))
            translate(-960px,-540px) scale(var(--reel-scale,1));
}

/* the poster is a complete hero on its own — it is what a metered connection,
   a reduced-motion setting, or a failed script is left with */
.reel-poster{
  position:absolute;inset:0;z-index:1;
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:18px;text-align:center;padding:0 24px;
  transition:opacity .9s var(--ease);
}
.reel-stage.is-live .reel-poster{opacity:0;pointer-events:none}
/* ember as TYPE, not as a fill: the design system's own --accent-600 is
   3.33:1 on this ground and the label is 13px. --ember-lit is 5.34:1. */
.reel-label{
  margin:0;font-family:var(--body);font-size:13px;font-weight:600;
  text-transform:uppercase;letter-spacing:.11em;color:var(--ember-lit);
}
.reel-mark{
  margin:0;font-family:var(--display);font-weight:700;
  font-size:clamp(52px,9vw,132px);letter-spacing:.04em;line-height:1;color:var(--ink);
}
.reel-tag{
  margin:0;font-family:var(--mono);font-size:clamp(15px,1.6vw,21px);color:var(--ember-lit);
}
.reel-cta{margin-top:14px}

@media(max-width:560px){
  .reel-poster{gap:14px}
  .reel-cta{width:min(100%,320px);justify-content:center}
}
/* a film that cannot move is just a still: keep the poster */
@media (prefers-reduced-motion:reduce){
  .reel-stage.is-live .reel-poster{opacity:1}
}


/* --- the nav, while it is standing on the film ---------------------------
   The Hero cut is authored light, so the film's ground is the same paper the
   rest of the page is. The bar therefore keeps its ordinary ink-on-light type
   the whole way down and only drops its plate, so that at the very top there
   is nothing between the type and the film. Once the page scrolls it takes the
   normal glass pill back. (Before the light cut this block had to invert the
   whole bar to light-on-dark; a light film makes all of that unnecessary.)
   `.nav-on-reel` is set from the scroll position (see the nav script). */
.nav-on-reel:not(.nav-float){
  background:transparent;border-color:transparent;box-shadow:none;
  /* the filter has to go too, not just the plate. saturate(1.7) over the
     film's warm paper lifts it from #FAF7F2 to #FCF7ED — a rectangle with hard
     edges where the rail ends, which is exactly the strip this hero is not
     supposed to have. Measured, not guessed. */
  -webkit-backdrop-filter:none;backdrop-filter:none;
}
