/* oYmer BIM VR Suite - plum hero (same box as every other hero) + four colored 3D panels.
   Each window is a lit bezel with a screen recessed into it, its own hue, and a centered one-liner. */

.bs, .suite{
  --plum1:#191130; --plum2:#221743; --plum3:#2b1e52;
  --vio:#8b6cf0; --vio-lt:#c3b3ff;
  --orange:#ff7a00; --orange-ink:#1a0f00;
  --ink:#181329; --body:#544d68; --mut:#8f889f;
  --ground:#f7f5fb; --rule:#e6e2f0; --rule2:#d3cde4;
}

/* ============================ hero ============================ */
/* ONE box for every product hero - the same one the live site pages use
   (PreRecordedTours etc): 465 total, content centred, symmetric 80px padding so the
   fixed header never covers the title. Everything is border-box here, so min-height
   465 IS the finished height. VR Tours and 3D Lab are deliberately outside this. */
.bs-hero{
  position:relative; min-height:465px; display:flex; flex-direction:column; justify-content:center;
  padding:80px 0; overflow:hidden;
  background:
    radial-gradient(880px 420px at 18% 8%, rgba(139,108,240,.20), transparent 62%),
    radial-gradient(760px 400px at 84% 88%, rgba(255,122,0,.07), transparent 64%),
    linear-gradient(150deg,#191130 0%,#221743 46%,#2b1e52 100%);
}
/* HARD height above mobile. with min-height the hero grew on the FIRST load: the
   fallback font is wider than Rubik, the title wrapped to two lines, and the box only
   settled back to 465 once the webfont was cached. a fixed height + overflow:hidden
   means the swap can never move the box. */
@media (min-width:641px){.bs-hero{height:465px}}

/* the angled side panels rescaled to the shorter box so nothing gets cropped */
.bs-hero .bs-herobg .p1{top:24%;width:141px;height:290px}
.bs-hero .bs-herobg .p2{top:22%;width:145px;height:300px}

.bs-herobg{position:absolute;inset:0;overflow:visible;pointer-events:none}
.bs-herobg .p{
  position:absolute;display:block;background-repeat:no-repeat;background-size:100% 100%;
  border-radius:10px;filter:brightness(.92) saturate(.55) hue-rotate(-18deg);
  box-shadow:0 22px 55px rgba(12,6,30,.55);
}
/* the panels are the suite's own tools, not the old VR-tour editor: the Family Creator's
   parameter table on one side, the Viewer's element-info HUD on the other, and the
   oYmer ribbon itself floating top and bottom. same treatment as before - tilted,
   dimmed, edge-masked - only the source changed. */
.bs-herobg .p1{left:2.5%;top:26%;width:196px;height:403px;opacity:.34;
  background-image:url("media/hero-family.jpg");
  transform:perspective(1300px) rotateY(27deg) rotate(-5deg);
  -webkit-mask-image:linear-gradient(to right,#000 38%,transparent 100%);
          mask-image:linear-gradient(to right,#000 38%,transparent 100%)}
.bs-herobg .p2{right:2.5%;top:31%;width:206px;height:426px;opacity:.34;
  background-image:url("media/hero-viewer.jpg");
  transform:perspective(1300px) rotateY(-27deg) rotate(5deg);
  -webkit-mask-image:linear-gradient(to left,#000 38%,transparent 100%);
          mask-image:linear-gradient(to left,#000 38%,transparent 100%)}
/* the ribbon is 5:3, not a sliver - it gets a real panel and a gentler tilt so the
   four button names stay readable as a ghost behind the title */
.bs-herobg .p3{right:2%;top:6%;width:250px;height:150px;opacity:.30;
  background-image:url("media/hero-ribbon.jpg");
  transform:perspective(1100px) rotateX(20deg) rotate(-3deg);
  -webkit-mask-image:radial-gradient(120% 120% at 50% 40%,#000 42%,transparent 100%);
          mask-image:radial-gradient(120% 120% at 50% 40%,#000 42%,transparent 100%)}
.bs-herobg .p4{left:2%;bottom:6%;width:230px;height:138px;opacity:.24;
  background-image:url("media/hero-ribbon.jpg");
  transform:perspective(1100px) rotateX(-18deg) rotate(3deg);
  -webkit-mask-image:radial-gradient(120% 120% at 50% 60%,#000 42%,transparent 100%);
          mask-image:radial-gradient(120% 120% at 50% 60%,#000 42%,transparent 100%)}
@media (max-width:900px){.bs-herobg{display:none}}

.bs-hero .inner{position:relative;z-index:10;max-width:1180px;margin:0 auto;padding:0 28px;text-align:center}
.bs-hero h1{
  direction:ltr;unicode-bidi:isolate;
  font-family:"Rubik","Heebo",sans-serif;color:#fff;font-weight:800;
  font-size:clamp(34px,5.4vw,64px);line-height:1.04;letter-spacing:-.03em;margin:0;
}
/* M17. VR Tours and VR Lab predate .bs-hero and were still on the Tailwind default
   stack: measured against the product pages' Rubik 64px/800/-1.92px they came out
   ui-sans-serif 60px/700/normal and 70.4px/800/normal - three different titles across
   four sibling products. One rule, applied by page rather than by re-tagging their
   markup, so neither hero has to be rebuilt. */
.oymer-hero h1,
.oyl-hero h1{
  direction:ltr;unicode-bidi:isolate;
  font-family:"Rubik","Heebo",sans-serif;color:#fff;font-weight:800;
  font-size:clamp(34px,5.4vw,64px);line-height:1.04;letter-spacing:-.03em}

/* parent-brand tag above each product name, so a product page still reads as part
   of the suite. links back to the suite. */
/* inline-block, NOT inline-flex - flex would make the <span class="y"> its own flex
   item and break "oYmer" apart into separate boxes */
/* no pill - just the wordmark, sitting above the product name */
.bs-suitetag{display:inline-block;direction:ltr;unicode-bidi:isolate;line-height:1.45;
  font-family:"Rubik","Heebo",sans-serif;font-weight:800;font-size:15px;letter-spacing:.005em;
  color:#fff;margin:0 0 16px;opacity:.92;transition:opacity .2s ease}
.bs-suitetag:hover{opacity:1}
.bs-suitetag .y{color:var(--orange)}
/* "BIM VR" carries the label - set larger than the wordmark either side of it */
.bs-suitetag b{font-weight:800;font-size:1.24em;letter-spacing:.01em}
@media (max-width:640px){.bs-suitetag{font-size:13px;margin-bottom:12px}}

/* the mark itself - small, raised, never louder than the name */
/* the mark trails the name on the right. the titles are declared LTR runs (below /
   in bimsuite-mockup.css), otherwise the RTL page would fling it to the far left. */
.oyc{font-size:clamp(9px,.32em,20px);font-weight:700;vertical-align:super;line-height:0;
  letter-spacing:0;margin-inline-start:.1em;opacity:.8;direction:ltr;unicode-bidi:isolate}
/* "oYmer" is the brand prefix - it reads smaller than the product name it introduces */
/* keeps the suite-title proportion (.68) on big type, but never drops below 11.5px -
   at a 14-16px base .68em was too small to read */
.oy{font-size:max(11.5px,.68em)}
.bs-suitetag .oyc{font-size:.55em;opacity:.72}

.yflash{color:var(--orange);animation:yfl 3.4s ease-in-out infinite}
@keyframes yfl{0%,100%{color:#ff7a00}50%{color:#ffb266}}

/* ---------------- animated hero title (word-by-word rise + sheen) --------------- */
.bs-title{display:flex;flex-wrap:wrap;justify-content:center;align-items:baseline;gap:0 .26em;direction:ltr}
/* "oYmer" and "Suite" are the small words either side - "BIM VR" carries the title.
   same proportion the suite tag already uses, so the two marks agree. */
.bs-title .oyw,.bs-title .sm{font-size:max(11.5px,.68em)}
.bs-title .w{
  display:inline-block;opacity:0;transform:translateY(30px) rotateX(-45deg);
  transform-origin:50% 100%;
  animation:bsw .72s cubic-bezier(.2,.75,.2,1) forwards;
  animation-delay:calc(var(--i) * .11s + .18s);
}
@keyframes bsw{to{opacity:1;transform:none}}

/* slow highlight sweeping across the white words - guarded so a browser without
   background-clip:text keeps plain white text instead of an invisible title */
@supports ((-webkit-background-clip:text) or (background-clip:text)){
  .bs-title .w{
    background-image:linear-gradient(100deg,#fff 42%,#d8c8ff 50%,#fff 58%);
    background-size:320% 100%;background-position:-120% 0;
    -webkit-background-clip:text;background-clip:text;
    -webkit-text-fill-color:transparent;color:transparent;
    animation:
      bsw .72s cubic-bezier(.2,.75,.2,1) calc(var(--i) * .11s + .18s) forwards,
      bssheen 7s linear 1.6s infinite;
  }
  /* the orange Y keeps its own colour - it must opt out of the clipped-text fill */
  .bs-title .yflash{-webkit-text-fill-color:currentColor;background:none}
  @keyframes bssheen{0%{background-position:-120% 0}55%,100%{background-position:120% 0}}
}
/* the Y in the suite title is a STEADY upright orange, like the original wordmark -
   no colour flash, no tilt. outside the @supports block so it holds either way. */
.bs-title .yflash{animation:none;color:var(--orange);font-style:normal;display:inline}

/* AI accent, now in the sub-line */
.bs-hero .ai{direction:ltr;unicode-bidi:isolate}
.bs-hero .ai i{
  font-style:normal;display:inline-block;color:var(--orange);
  animation:aiglow 2.8s ease-in-out infinite;
}
@keyframes aiglow{
  0%,100%{color:#ff7a00;text-shadow:0 0 18px rgba(255,122,0,.35)}
  50%{color:#ffb266;text-shadow:0 0 30px rgba(255,150,40,.75),0 0 60px rgba(255,122,0,.30)}
}
/* the sub-line now carries TWO latin acronyms. VR gets the same pulse in the suite violet,
   so AI and VR read as a pair instead of one of them shouting over the other. */
.bs-hero .ai.vr i{color:var(--vio-lt);animation:vrglow 2.8s ease-in-out infinite}
@keyframes vrglow{
  0%,100%{color:#8b6cf0;text-shadow:0 0 18px rgba(139,108,240,.35)}
  50%{color:#c3b3ff;text-shadow:0 0 30px rgba(160,130,255,.75),0 0 60px rgba(139,108,240,.30)}
}

@media (prefers-reduced-motion:reduce){
  .bs-title .w,.bs-hero .ai i,.bs-hero .ai.vr i{animation:none;opacity:1;transform:none}
  .bs-title .w{-webkit-text-fill-color:#fff;color:#fff}
  .bs-title .yflash{-webkit-text-fill-color:var(--orange)}
}
.bs-hero .sub{
  color:#b4a9cf;font-family:"Rubik","Heebo",sans-serif;font-weight:500;
  font-size:clamp(15px,1.5vw,19px);letter-spacing:.01em;margin:18px auto 0;
}

/* ============================ page ============================ */
.suite{
  background:var(--ground); color:var(--body); direction:rtl;
  font-family:"Heebo",ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  -webkit-font-smoothing:antialiased;
}
.suite .inner{max-width:1180px;margin:0 auto;padding:0 28px}
.suite .ltr{direction:ltr;unicode-bidi:embed;display:inline-block}
.suite a{text-decoration:none;color:inherit}

.rev{opacity:0;transform:translateY(24px);transition:opacity .65s cubic-bezier(.2,.7,.2,1),transform .65s cubic-bezier(.2,.7,.2,1)}
.rev.in{opacity:1;transform:none}

.products{position:relative;padding:70px 0 120px;overflow:hidden}
.products .inner{position:relative}
.wins{
  position:relative;z-index:2;
  display:grid;grid-template-columns:repeat(auto-fit,minmax(470px,1fr));gap:52px 38px;
  perspective:1500px;
}
@media (max-width:560px){.wins{grid-template-columns:1fr;gap:32px}}

/* ============ animated BIM field: plan lines, iso wireframe, halftone dots, live drafting ============
   sits directly in .products (not in .inner), so it runs the full width of the page. */
.bimbg{position:absolute;inset:0;z-index:0;pointer-events:none;overflow:hidden}
.bimbg > span{position:absolute;inset:-120px;display:block}

/* lines that draw themselves, hold, then rub out - a drafter working behind the cards */
.draw{position:absolute;inset:0;width:100%;height:100%;display:block}
.draw g{fill:none;stroke:#181329;stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
.draw .dg path,.draw .dg circle{
  stroke-dasharray:1;stroke-dashoffset:1;opacity:0;
  animation:draftLine 13s cubic-bezier(.55,.05,.35,1) infinite;
  animation-delay:inherit;
}
.draw .dg{animation:none}
.draw .dg > *:nth-child(2){animation-delay:inherit;animation-duration:13.6s}
.draw .dg > *:nth-child(3){animation-duration:14.2s}
.draw .dg > *:nth-child(4){animation-duration:14.8s}
.draw .dg > *:nth-child(5){animation-duration:15.4s}
@keyframes draftLine{
  0%  {stroke-dashoffset:1;opacity:0}
  5%  {opacity:.34}
  34% {stroke-dashoffset:0;opacity:.34}
  72% {stroke-dashoffset:0;opacity:.34}
  88% {stroke-dashoffset:0;opacity:0}
  100%{stroke-dashoffset:1;opacity:0}
}
@media (prefers-reduced-motion:reduce){
  .draw .dg path,.draw .dg circle{animation:none;stroke-dashoffset:0;opacity:.2}
}

/* floor-plan line work, drifting slowly to the left */
.bimbg .plan{
  opacity:.16;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='260' height='260' viewBox='0 0 260 260'><g fill='none' stroke='%23181329' stroke-width='1.3'><rect x='24' y='24' width='96' height='74'/><rect x='142' y='24' width='94' height='48'/><rect x='24' y='120' width='212' height='116'/><path d='M120 60h22M72 98v22M236 96v24'/><path d='M158 120a34 34 0 0 1 34 34'/><path d='M24 250h212M250 24v212' stroke-dasharray='7 7' stroke-width='1'/><circle cx='192' cy='178' r='16'/></g></svg>");
  background-size:260px 260px;
  animation:bimDriftA 92s linear infinite;
}
/* isometric wireframe, drifting the other way and slower - gives the field depth */
.bimbg .iso{
  opacity:.13;
  background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='170' height='196' viewBox='0 0 170 196'><g fill='none' stroke='%231f1a3a' stroke-width='1.1'><path d='M85 2 168 50 168 146 85 194 2 146 2 50Z'/><path d='M85 2 85 98M85 98 168 146M85 98 2 146'/></g></svg>");
  background-size:170px 196px;
  animation:bimDriftB 140s linear infinite reverse;
}
/* two dot grids of different weight = the halftone, densest toward the middle */
.bimbg .dots{
  background-image:radial-gradient(circle, rgba(24,19,41,.55) 1.5px, transparent 1.6px);
}
.bimbg .d1{
  background-size:13px 13px;opacity:.30;
  -webkit-mask-image:radial-gradient(70% 55% at 50% 46%, #000 0%, rgba(0,0,0,.35) 55%, transparent 82%);
          mask-image:radial-gradient(70% 55% at 50% 46%, #000 0%, rgba(0,0,0,.35) 55%, transparent 82%);
  animation:bimDriftC 60s linear infinite;
}
.bimbg .d2{
  background-size:27px 27px;opacity:.22;
  background-image:radial-gradient(circle, rgba(139,108,240,.75) 2.4px, transparent 2.5px);
  -webkit-mask-image:linear-gradient(135deg, #000 0%, transparent 62%);
          mask-image:linear-gradient(135deg, #000 0%, transparent 62%);
  animation:bimDriftD 78s linear infinite reverse;
}
@keyframes bimDriftA{to{background-position:-260px 130px}}
@keyframes bimDriftB{to{background-position:170px 196px}}
@keyframes bimDriftC{to{background-position:-130px 65px}}
@keyframes bimDriftD{to{background-position:135px -108px}}
@media (prefers-reduced-motion:reduce){
  .bimbg .plan,.bimbg .iso,.bimbg .dots{animation:none}
}

/* ---- quiet field: the reels ARE the motion on a product page ----
   nothing behind them drifts or draws itself, and every layer is taken down to a
   watermark - just enough tooth to stop the ground reading as flat white paint.
   half strength was still too present; these are roughly a quarter of that again. */
.bimbg.quiet .plan,.bimbg.quiet .iso,.bimbg.quiet .dots{animation:none}
.bimbg.quiet .draw .dg path,.bimbg.quiet .draw .dg circle{
  animation:none;stroke-dashoffset:0;opacity:.045;
}
.bimbg.quiet .plan{opacity:.022}
.bimbg.quiet .iso{opacity:.016}
.bimbg.quiet .d1{opacity:.045}
.bimbg.quiet .d2{opacity:.03}

/* ---------------- one hue per window ---------------- */
.suite .c1{--c:255,122,0;   --cd:196,88,0;   --con:#1a0f00}   /* DecisionMaker - orange  */
.suite .c2{--c:139,108,240; --cd:92,64,190;  --con:#ffffff}   /* Viewer         - violet  */
.suite .c3{--c:79,125,255;  --cd:44,82,196;  --con:#ffffff}   /* Family Creator - azure   */
.suite .c4{--c:43,179,163;  --cd:22,124,113; --con:#052b27}   /* Type Studio    - teal    */

/* ---------------- frame, lit from behind ---------------- */
.winwrap{position:relative;transform-style:preserve-3d}
.glow{
  position:absolute;z-index:0;inset:20px 14px -30px 14px;border-radius:36px;
  filter:blur(38px);opacity:.55;pointer-events:none;
  background:radial-gradient(62% 62% at 50% 64%, rgba(var(--c),.92), rgba(var(--c),0) 72%);
  transition:opacity .35s ease, transform .35s cubic-bezier(.2,.7,.2,1), filter .35s;
}
.winwrap:hover .glow{opacity:1;filter:blur(46px)}

.win{
  position:relative;z-index:1;display:flex;flex-direction:column;
  border-radius:26px;will-change:transform;
  /* the bezel material: lit from the top-right, falling into shadow bottom-left */
  background:
    linear-gradient(155deg,
      rgba(var(--c),.30) 0%,
      rgba(var(--c),.16) 34%,
      rgba(255,255,255,.96) 62%,
      rgba(var(--c),.10) 100%),
    #ffffff;
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,.95),
    inset 2px 0 0 rgba(255,255,255,.55),
    inset 0 -2px 0 rgba(var(--cd),.30),
    inset -2px 0 0 rgba(var(--cd),.16),
    0 1px 2px rgba(24,19,41,.10),
    0 12px 24px rgba(var(--cd),.16),
    0 30px 56px rgba(24,19,41,.14);
  transition:transform .3s cubic-bezier(.2,.7,.2,1), box-shadow .3s;
}
.winwrap:hover .win{
  box-shadow:
    inset 0 2px 0 rgba(255,255,255,1),
    inset 2px 0 0 rgba(255,255,255,.6),
    inset 0 -2px 0 rgba(var(--cd),.38),
    inset -2px 0 0 rgba(var(--cd),.2),
    0 2px 3px rgba(24,19,41,.12),
    0 24px 44px rgba(var(--cd),.26),
    0 54px 92px rgba(24,19,41,.22);
}
.winwrap:hover .win:not([style*="rotate"]){transform:translateY(-8px)}

/* the screen sits sunk into the bezel */
.bezel{display:block;padding:14px 14px 0}
.screen{
  position:relative;display:block;background:#0f0a20;aspect-ratio:16/10;overflow:hidden;
  border-radius:16px;
  box-shadow:
    inset 0 3px 10px rgba(0,0,0,.65),
    inset 0 0 0 1px rgba(var(--cd),.55),
    0 1px 0 rgba(255,255,255,.8);
}
.screen video{display:block;width:100%;height:100%;object-fit:cover;
  transition:transform .6s cubic-bezier(.2,.7,.2,1), filter .4s}
.winwrap:hover .screen video{transform:scale(1.05)}
.screen::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:
    radial-gradient(120% 90% at 50% 50%, rgba(var(--cd),.06) 0%, rgba(10,6,22,.62) 62%, rgba(10,6,22,.88) 100%),
    linear-gradient(200deg, rgba(255,255,255,.14) 0%, rgba(255,255,255,0) 34%);  /* glass sheen */
}

.cix{
  position:absolute;top:14px;right:14px;z-index:3;
  font-family:"Rubik",sans-serif;font-size:11px;font-weight:800;direction:ltr;letter-spacing:.08em;
  color:#fff;background:rgba(var(--c),.42);border:1px solid rgba(var(--c),.75);
  border-radius:8px;padding:4px 9px;backdrop-filter:blur(6px);
}
.wbadge{
  position:absolute;top:14px;left:14px;z-index:3;
  font-family:"Rubik",sans-serif;font-size:10.5px;font-weight:800;border-radius:999px;
  padding:5px 12px;white-space:nowrap;backdrop-filter:blur(6px);
}
.wbadge.flag{background:rgb(var(--c));color:var(--con)}
.wbadge.free{background:rgba(var(--c),.42);color:#fff;border:1px solid rgba(var(--c),.8)}
.wbadge.wip{background:rgba(12,8,26,.5);color:#d8f2ee;border:1px dashed rgba(var(--c),.7)}

/* ---------------- the centered one-liner ---------------- */
.center{
  position:absolute;inset:0;z-index:3;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;padding:0 26px;pointer-events:none;
}
.pname{
  font-family:"Rubik",sans-serif;font-size:11.5px;font-weight:700;letter-spacing:.2em;
  color:rgba(var(--c),1);text-shadow:0 1px 10px rgba(0,0,0,.6);margin-bottom:14px;
  opacity:0;transform:translateY(8px);transition:opacity .5s .05s ease, transform .5s .05s cubic-bezier(.2,.7,.2,1);
}
.winwrap.in .pname{opacity:1;transform:none}

.oneline{
  font-family:"Rubik","Heebo",sans-serif;color:#fff;font-weight:800;
  font-size:clamp(21px,2.5vw,31px);line-height:1.25;letter-spacing:-.025em;
  text-shadow:0 3px 26px rgba(6,3,16,.75);
  display:block;
}
.oneline b{display:inline-block;font-weight:800;opacity:0;transform:translateY(16px) rotateX(-40deg);transform-origin:50% 100%}
.winwrap.in .oneline b{animation:wordUp .62s cubic-bezier(.2,.75,.2,1) forwards}
.winwrap.in .oneline b:nth-child(1){animation-delay:.18s}
.winwrap.in .oneline b:nth-child(2){animation-delay:.27s}
.winwrap.in .oneline b:nth-child(3){animation-delay:.36s}
.winwrap.in .oneline b:nth-child(4){animation-delay:.45s}
.winwrap.in .oneline b:nth-child(5){animation-delay:.54s}
.winwrap.in .oneline b:nth-child(6){animation-delay:.63s}
@keyframes wordUp{to{opacity:1;transform:none}}

.uline{
  display:block;height:3px;width:0;border-radius:2px;margin-top:16px;
  background:linear-gradient(to left, rgba(var(--c),0), rgb(var(--c)), rgba(var(--c),0));
  transition:width .5s cubic-bezier(.2,.7,.2,1);
}
.winwrap.in .uline{width:86px;transition-delay:.7s}
.winwrap:hover .uline{width:190px;transition-delay:0s}

@media (prefers-reduced-motion:reduce){
  .yflash{animation:none}
  .oneline b{opacity:1;transform:none;animation:none}
  .pname{opacity:1;transform:none}
}

/* ---------------- the product name, centred ABOVE its window ---------------- */
/* the name is the label of the whole panel, so it sits on the bezel above the screen -
   not squeezed into the press strip. the strip below now says one thing only. */
.wtop{display:block;text-align:center;padding:18px 20px 6px}
.wtop .rname{
  font-family:"Rubik",sans-serif;font-weight:800;font-size:clamp(21px,2.3vw,27px);
  letter-spacing:-.025em;color:rgb(var(--cd));text-shadow:none;
}
.wtop .oy{opacity:.72}
.wtop .oyc{opacity:.6}

/* ---------------- bottom strip: the one instruction, asking to be pressed ---------------- */
/* deliberately slim. the text keeps its size - it is the FRAME that gives way, so the
   screen owns more of the panel than its chrome does. */
.wbody{display:block;padding:9px 14px 11px}
/* M4. The Revit mark takes the place the 01-04 index used to hold, top corner of the
   screen - the SAME drawing that now sits on the ribbon, so anyone who has seen the
   toolbar recognises it. It replaces the number rather than joining it: the number was
   only ever an ordinal, the mark says which tool this is.
   It keeps .cix for position but drops the chip's own pill - the mark carries its own
   shape, and a box around it read as a sticker. */
img.cix.wmark{
  width:38px;height:38px;padding:0;border:0;border-radius:0;
  background:none;backdrop-filter:none;
  filter:drop-shadow(0 3px 9px rgba(3,6,20,.6));
  transition:transform .25s ease}
.winwrap:hover img.cix.wmark{transform:translateY(-2px) scale(1.07)}
@media (max-width:560px){img.cix.wmark{width:32px;height:32px}}
@media (prefers-reduced-motion:reduce){img.cix.wmark{transition:none}}
.ribbon{
  position:relative;display:flex;align-items:center;justify-content:center;gap:14px;
  background:linear-gradient(150deg, rgba(var(--cd),.98) 0%, rgba(var(--cd),.82) 100%);
  color:#fff;border-radius:13px;padding:7px 20px;overflow:hidden;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.35), 0 6px 14px rgba(var(--cd),.30);
  transition:box-shadow .22s, filter .22s;
  animation:pressPulse 2.6s ease-out infinite;
}
/* a light sweeps across the ribbon every few seconds - the "press me" tell */
.ribbon::after{
  content:"";position:absolute;top:0;bottom:0;width:45%;z-index:1;pointer-events:none;
  background:linear-gradient(105deg, transparent 0%, rgba(255,255,255,.34) 48%, transparent 100%);
  animation:ribbonSweep 3.8s cubic-bezier(.5,0,.3,1) infinite;
}
@keyframes ribbonSweep{0%{right:-50%}55%,100%{right:105%}}
@keyframes pressPulse{
  0%{box-shadow:inset 0 1px 0 rgba(255,255,255,.35), 0 6px 14px rgba(var(--cd),.30), 0 0 0 0 rgba(var(--c),.5)}
  70%{box-shadow:inset 0 1px 0 rgba(255,255,255,.35), 0 6px 14px rgba(var(--cd),.30), 0 0 0 13px rgba(var(--c),0)}
  100%{box-shadow:inset 0 1px 0 rgba(255,255,255,.35), 0 6px 14px rgba(var(--cd),.30), 0 0 0 0 rgba(var(--c),0)}
}

.rname{
  position:relative;z-index:2;
  font-family:"Rubik",sans-serif;font-weight:800;font-size:clamp(16px,1.7vw,19px);
  letter-spacing:-.02em;color:#fff;text-shadow:0 1px 8px rgba(0,0,0,.25);
}
.press{
  position:relative;z-index:2;display:inline-flex;align-items:center;gap:9px;flex:0 0 auto;
  font-family:"Rubik",sans-serif;font-weight:700;font-size:14px;letter-spacing:.02em;
  color:rgba(255,255,255,.92);
}
.press .arw{
  width:26px;height:26px;border-radius:50%;display:grid;place-items:center;flex:0 0 auto;
  background:#fff;color:rgb(var(--cd));font-size:15px;font-style:normal;
  box-shadow:0 2px 6px rgba(0,0,0,.2);
  animation:arwNudge 1.7s ease-in-out infinite;
  transition:transform .22s cubic-bezier(.2,.7,.2,1);
}
@keyframes arwNudge{0%,100%{transform:translateX(0)}50%{transform:translateX(-5px)}}

.winwrap:hover .ribbon{
  filter:brightness(1.1);animation-play-state:paused;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.45), 0 12px 26px rgba(var(--cd),.42);
}
.winwrap:hover .press .arw{animation:none;transform:translateX(-8px)}

/* the unshipped one does not beg */
.ribbon.soon{
  background:linear-gradient(150deg,#efeaf7 0%,#e6e0f2 100%);color:var(--mut);animation:none;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.9), 0 3px 8px rgba(24,19,41,.08);
}
.ribbon.soon::after{animation:none;display:none}
.ribbon.soon .rname{color:#6c6486;text-shadow:none}
.ribbon.soon .press{color:#a49dba}
.ribbon.soon .press .arw{background:#fff;color:var(--mut);animation:none;box-shadow:0 1px 4px rgba(0,0,0,.1)}
.winwrap:hover .ribbon.soon{filter:none;box-shadow:inset 0 1px 0 rgba(255,255,255,.9), 0 6px 14px rgba(24,19,41,.12)}
.winwrap:hover .ribbon.soon .press .arw{transform:none}

/* ---- the four strips must never beat together ----
   measured: pressPulse, ribbonSweep and arwNudge were all at currentTime 0 on every
   window - spread 0ms across the grid. four ribbons throbbing in exact unison reads as
   one redundant page-wide pulse, and it lands right as the returning card settles.
   negative delays start each window mid-cycle, so they are permanently out of phase
   and nothing has to wait to begin. quarter-cycle apart: 2.6s / 3.8s / 1.7s. */
.suite .c2 .ribbon{animation-delay:-.65s}
.suite .c3 .ribbon{animation-delay:-1.30s}
.suite .c4 .ribbon{animation-delay:-1.95s}
.suite .c2 .ribbon::after{animation-delay:-.95s}
.suite .c3 .ribbon::after{animation-delay:-1.90s}
.suite .c4 .ribbon::after{animation-delay:-2.85s}
.suite .c2 .press .arw{animation-delay:-.42s}
.suite .c3 .press .arw{animation-delay:-.85s}
.suite .c4 .press .arw{animation-delay:-1.27s}

@media (prefers-reduced-motion:reduce){
  .ribbon{animation:none}
  .ribbon::after,.press .arw{animation:none}
}

/* ==================================================================================
   back to the suite - the visible way out at the end of a product page
   ==================================================================================
   the suite tag up in the hero is the elegant way back, but it only announces itself
   on hover, and touch has no hover. this one is always visible and needs no pointer,
   so a phone visitor is never stranded on a product page. */

/* the hue on its own, not depending on being inside .suite - on DecisionMaker the back
   section sat outside that subtree, so --c/--cd resolved EMPTY and the link fell back
   to near-black instead of the product colour. */
.backsuite.c1{--c:255,122,0;--cd:196,88,0;--con:#1a0f00}
.backsuite.c2{--c:139,108,240;--cd:92,64,190;--con:#ffffff}
.backsuite.c3{--c:79,125,255;--cd:44,82,196;--con:#ffffff}
.backsuite.c4{--c:43,179,163;--cd:22,124,113;--con:#052b27}
.backsuite{background:var(--ground);padding:0 0 78px;text-align:center}
/* M11. `.ltr` is declared as `.suite .ltr`, and .backsuite is a SIBLING of .suite, not a
   child - so the class did nothing here and the run stayed RTL. Measured: the word "Suite"
   sat at x 691-762 while its own copyright mark sat at x 529, i.e. at the visual START of
   the line. Same scoping trap as --c/--cd/--con on this section. isolate, not embed, so the
   mark cannot escape the LTR run. */
.backsuite .ltr{direction:ltr;unicode-bidi:isolate;display:inline-block}
/* no frame, no pill - it reads as a title, in the same Rubik weight and hue as the
   name above each window. .suite a{color:inherit} outranks a single class, so this
   has to be at least as specific or the label falls back to the body grey. */
.suite .backsuite__link,.backsuite__link{
  display:inline-flex;align-items:baseline;gap:14px;
  font-family:"Rubik","Heebo",sans-serif;font-weight:800;
  font-size:clamp(21px,2.3vw,27px);letter-spacing:-.025em;
  color:rgb(var(--cd));background:none;box-shadow:none;padding:0;
  transition:color .22s ease, transform .22s cubic-bezier(.2,.7,.2,1);
}
.backsuite__link:hover{color:rgb(var(--c));transform:translateY(-2px)}
/* the page's own arrow language, mirrored: the ribbon's arw points forward (left, in
   RTL), so the way back points the other way. bare glyph - a disc would be a frame. */
.backsuite__arw{
  font-size:.86em;line-height:1;flex:0 0 auto;opacity:.75;
  transition:transform .22s cubic-bezier(.2,.7,.2,1), opacity .22s ease;
}
.backsuite__link:hover .backsuite__arw{transform:translateX(6px);opacity:1}
.backsuite__txt .oy{font-size:max(11.5px,.68em);opacity:.75}
.backsuite__txt .oyc{opacity:.6}

/* the return fold: the REAL document turns away, so what folds is the screen you were
   actually looking at. perspective goes on the parent of the transformed element, and
   the pivot is set inline from JS to the centre of the visible area, because the page
   is scrolled and much taller than the viewport.
   deliberately NOT touching overflow here - hiding the scrollbar mid-fold reflows the
   page by its width and shows up as a jump on the first frame. */
html.morphing body{perspective:1600px}
html.morphing .min-h-screen{backface-visibility:hidden;will-change:transform;
  position:relative;z-index:1}          /* stays above the suite backdrop while it folds */

/* the suite, rendered behind the folding page so the return has somewhere to land.
   left:0 + an inline top of scrollY - see the containing-block note in suite-morph.js.
   It starts invisible and is switched on by its own load event, so a backdrop that
   never arrives simply leaves the old behaviour rather than flashing a blank frame. */
#bgstage{position:absolute;left:0;z-index:0;border:0;pointer-events:none;
  opacity:0;background:var(--ground)}
#bgstage.on{opacity:1}

/* The destination page, rendered during the flip so the navigation lands on
   something already painted. Fixed at the viewport, z-index 44 - directly under
   #morph (45) and the header (50), so it is covered for the whole animation. */
#prestage{position:fixed;left:0;top:0;z-index:44;border:0;pointer-events:none}
/* the backdrop copy of the suite is scenery, never a target */
html.bgstage{pointer-events:none}

/* ==================================================================================
   the window flips into its own page  (see suite-morph.js)
   ================================================================================== */
/* each product page's hero wears its own hue over the plum - this is the colour the
   transition washes INTO, so the last frame of the flip and the loaded page agree. */
.bs-hero.hue-c2,.mh-wash.hue-c2{
  background:
    radial-gradient(920px 460px at 18% 6%, rgba(139,108,240,.52), transparent 62%),
    radial-gradient(780px 420px at 86% 92%, rgba(190,160,255,.18), transparent 64%),
    linear-gradient(150deg,#140d30 0%,#2a1a6e 46%,#3f29a4 100%);
}

/* DecisionMaker wears its own orange over the plum - same idea as the azure below.
   the flag product gets the warmest hero in the suite. */
.bs-hero.hue-c1,.mh-wash.hue-c1{
  background:
    radial-gradient(920px 460px at 18% 6%, rgba(255,122,0,.44), transparent 62%),
    radial-gradient(780px 420px at 86% 92%, rgba(255,176,70,.16), transparent 64%),
    linear-gradient(150deg,#2a1206 0%,#5c2508 46%,#8d3c09 100%);
}

/* deliberately a LONG way from the plum. the first pass sat at #121233->#1e2b66, which
   is still a purple-navy - next to the hub's plum it read as "no colour change at all".
   this is unmistakably the Family Creator azure. */
.bs-hero.hue-c3,.mh-wash.hue-c3{
  background:
    radial-gradient(920px 460px at 18% 6%, rgba(79,125,255,.55), transparent 62%),
    radial-gradient(780px 420px at 86% 92%, rgba(0,208,255,.20), transparent 64%),
    linear-gradient(150deg,#081230 0%,#0d2a6e 46%,#123f96 100%);
}

/* Type Studio gets the SAME hero recipe as the Family Creator above - same stop
   positions, same radii, same opacities - only the hue is its own teal. The two
   products now read as one pair of pages that differ by colour, not by treatment. */
.bs-hero.hue-c4,.mh-wash.hue-c4{
  background:
    radial-gradient(920px 460px at 18% 6%, rgba(43,179,163,.55), transparent 62%),
    radial-gradient(780px 420px at 86% 92%, rgba(0,255,214,.20), transparent 64%),
    linear-gradient(150deg,#03211d 0%,#074a41 46%,#0a6f61 100%);
}

/* z-index 45 keeps the fixed white header (z-50) on top the whole way, exactly as it
   sits on both the page we leave and the page we land on. */
#morph{
  position:fixed;inset:0;z-index:45;pointer-events:none;
  perspective:1600px;visibility:hidden;
}
#morph.on{visibility:visible}
#morph .mface{
  position:fixed;transform-origin:50% 50%;will-change:transform;
  backface-visibility:hidden;-webkit-backface-visibility:hidden;
}
#morph .mcard{border-radius:26px}
#morph .mcard .win{width:100%;height:100%;transform:none!important}
/* width/height are set from clientWidth/clientHeight in JS - 100vw counts the scrollbar
   and the destination's content box does not, which knocked the landing 7px off centre */
/* the ground is HARDCODED, not var(--ground): #morph is a child of <body>, outside
   .bs/.suite, so the variable never resolved and everything below the hero band was
   transparent - you were seeing the hub's own cards through the "page" mid-flip. */
#morph .mhero{left:0;top:0;background:#f7f5fb;overflow:hidden}
#morph .mh-band{width:100%}
/* z-index 0, NOT 1. The wash is a LATER sibling than .bs-herobg and its hue gradients
   are fully opaque, so at z-index 1 it finished the flip painted straight OVER the four
   hero side panels - the product hero landed clean, and the panels only "appeared" when
   the real page took over. On the real page the hue is the section's own background,
   i.e. BEHIND the panels; this puts the clone in the same order. .inner is z-index 10,
   so the title and tag still sit on top of both. */
#morph .mh-wash{position:absolute;inset:0;z-index:0;opacity:0;pointer-events:none}
#morph .mhero .bs-herobg{z-index:1}
#morph .mh-band .inner{position:relative;z-index:10}
/* the cloned card is detached from .winwrap.in, so its reveal states never resolved -
   force the finished look, otherwise the front face flips over holding a blank screen */
#morph .oneline b{opacity:1;transform:none;animation:none}
#morph .uline{width:86px;transition:none}
#morph .rev{opacity:1;transform:none}
#morph .mh-suite{display:inline-block;margin:0 0 16px}

/* the page we hand over to skips its own entrance, so the landing is a continuation
   of the flip rather than a second animation starting from zero */
.fromsuite .rev{opacity:1!important;transform:none!important;transition:none!important}
.fromsuite .bs-title .w{opacity:1!important;transform:none!important;animation:none!important}
/* and the same coming the other way: arriving back at the suite, the windows are
   already there - only the one we folded out of gets to move. */
.fromproduct .rev{opacity:1!important;transform:none;transition:none!important}
.fromproduct .oneline b{opacity:1!important;transform:none!important;animation:none!important}
.fromproduct .uline{width:86px!important}
.fromproduct .bs-title .w{opacity:1!important;transform:none!important;animation:none!important}

/* lineage: the suite is the PARENT, the product hangs off it. two hairlines fanning
   from the suite tag down to the product name, so the relationship is drawn, not implied. */
.bs-lineage{position:absolute;display:none;margin:0;overflow:visible;pointer-events:none;z-index:0}
.bs-lineage path{fill:none;stroke:#fff;stroke-width:1;opacity:.12;
  vector-effect:non-scaling-stroke;stroke-linecap:round}
@media (max-width:640px){.bs-lineage{position:absolute;display:none;margin:0;overflow:visible;pointer-events:none;z-index:0}}

/* the title sits ABOVE the rays now that they run its full height */
.bs-hero h1{position:relative;z-index:2}
