/* ─────────────────────────────────────────────────────────────────────
   webinar-page.css
   Layer for on-demand webinar landing pages. First use is the Embrava +
   OfficeSpace session recorded 2026-09-09.

   Loads after site.css + articles.css. Those already supply the tokens,
   the .btn family, .section, .article-wrap and .final-cta;
   this file adds the navy hero (teaser, speaker roster and access form),
   the takeaway cards, the FAQ disclosure, the partner block and the
   world-map stat band.

   No new brand values are introduced. Every colour is a site.css token or
   a value already used elsewhere on the site (the .article-hero--gradient
   navy ramp, the .event-card shadow pair).

   NO NODE MOTIF ON THIS PAGE. The teal square accent is deliberately
   absent: no bullet nodes, no node status dots in the meta line, and the
   planned-vs-verified node figure the first draft carried is gone. The
   only square grid left is the world map, which is imagery rather than a
   bullet or a data point.

   .article-tag is not used on this page: the eyebrows are .wb-kicker,
   plain letterspaced text rather than articles.css's filled chip. The
   FAQ is index.css's .faq-item component, ported below.
   ───────────────────────────────────────────────────────────────────── */

:root{
  /* Same ramp as event-page.css / partner-page.css, so the detail
     templates stay in agreement. */
  --t-kicker: 11px;
  --t-micro:  12px;
  --t-fine:   13px;
  --t-small:  14px;
  --t-body:   15px;
  --t-body-lg:16px;
  --t-h4:     17px;
  --t-h3:     20px;
  --t-lede:   clamp(16px, 1.45vw, 19px);

  /* The display end of the same ramp, which used to be five clamps written
     inline at the rules that used them, one of them typed out twice, with
     no single place to read the page's heading sizes off. --t-h3-sm is the
     18px the takeaway cards were already setting as a bare literal, a real
     step between --t-h4 and --t-h3 rather than a stray number.

     There is no --t-h2-lg any more. Section headings had their own clamp
     capping at 40px, the same cap as the h1, and every band now shares
     --t-h2-sm instead: 40 for the headline, 34 for the headings under it.
     See .wb-head h2 for why. */
  --t-h3-sm:   18px;
  --t-h2-sm:   clamp(24px, 2.9vw, 34px);
  --t-h1-hero: clamp(30px, 3.0vw, 40px);
  --t-stat:    clamp(26px, 2.4vw, 34px);

  --measure:       66ch;
  --measure-lede:  58ch;

  /* ONE CONTAINER FOR THE WHOLE PAGE. The hero inner box is 1180px inside
     a 32px gutter; everything under it now matches, so the left edge of
     the h1, the takeaways, the partner card and the closing CTA all land
     on the same line. Before this the two mid-page bands were
     .article-wrap.is-wide (980px), which read as the middle of the page
     being inset ~100px further than the top and the bottom of it. */
  --wb-max:     1180px;
  --wb-gutter:  32px;
  --wb-block:   88px;
}

/* In-page jumps: #watch from the hero CTA and both "Watch on demand"
   buttons, #speakers from the Meet the speakers button in the hero. The
   nav is fixed and about 80px tall, so every target needs clearance or
   its heading arrives underneath it. Only this page loads this file, so
   the bare html rule cannot reach anywhere else.

   96px is also what .wb-form-shell parks at when it sticks, so a jumped-to
   heading and the held card line up on the same invisible rule. Two of the
   three targets (#speakers, #who-should-watch) are .wb-block now rather
   than sections of their own, which is why that rule carries the same
   number. */
@media(prefers-reduced-motion:no-preference){
  html{scroll-behavior:smooth}
}
.wb-page > .section[id]{scroll-margin-top:96px}

/* Scoped to .wb-page so this cannot leak into the other pages that share
   articles.css. Nothing inside the page sets its own horizontal padding:
   add a band as <section class="section">, not as an .article-wrap. */
.wb-page > .section{
  max-width:calc(var(--wb-max) + var(--wb-gutter) * 2);
  padding:var(--wb-block) var(--wb-gutter);
}
.wb-page > .section.is-flush-top{padding-top:0}
/* The band directly under the hero starts closer to it. The hero's own
   bottom padding already separates the two, so the full block spacing
   there was being paid twice, and it was the difference between the next
   heading reading at the fold and not. */
.wb-page > .wb-hero + .section{padding-top:60px}
/* .final-cta ships 56px of side padding for pages where it sits in a
   narrower column. Here the section gutter already does that job, and the
   doubled inset pulled the closing headline visibly in from the hero. */
.wb-page .final-cta{padding-left:0;padding-right:0}
/* The two halves of the closing line always break in the same place
   rather than wherever the viewport puts it. */
.wb-brk{display:inline}

/* ══ NAV, INVERTED OVER THE HERO ════════════════════════════════════
   The white bar is gone from over the navy. It used to sit on top of the
   hero as a solid white strip with a rule under it, which cut the top of
   the page off from the section it introduced and wasted the one place on
   the page where the ground is already the brand colour.

   This is not a new treatment: index.html does exactly this over its own
   dark hero, and every value below is that page's, moved here. The marks
   swap (white wordmark over navy, navy over white), the links and the
   search icon go white, and the Contact us pill inverts to white with
   navy text.

   IT FLIPS BACK. header.nav.scrolled restores the stock white bar the
   moment the nav clears the hero, and the small script at the foot of the
   page toggles that class. This is not optional on this page: the nav
   hides on scroll down and returns on scroll up, so it can reappear over
   any section, and a white-on-transparent nav over the light page would
   be a row of invisible links.

   Scoped with :has(.wb-hero) so none of it can reach the other pages that
   share site.css, the same guard #page-wrap:has(> .wb-hero) already uses
   above. Every rule here is a deliberate override of site.css, so each one
   out-specifies it by the :has() alone. */
body:has(.wb-hero) header.nav{
  background:transparent;border-bottom-color:transparent;
  transition:transform .6s ease-in,border-color .3s ease;
}
/* A scrim rather than a flat fill: over a hero whose top is already the
   darkest part of the gradient it is nearly invisible, and it is what
   keeps the links legible once a real still or a lighter image sits under
   the bar. */
body:has(.wb-hero) header.nav::before{
  background:linear-gradient(180deg,rgba(4,14,26,.38) 0%,rgba(4,14,26,0) 100%);
  backdrop-filter:none;-webkit-backdrop-filter:none;
  transition:background .3s ease,backdrop-filter .3s ease;
}
body:has(.wb-hero) header.nav.scrolled{border-bottom-color:var(--line-soft)}
body:has(.wb-hero) header.nav.scrolled::before{
  background:rgba(255,255,255,.92);
  backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);
}

/* Marks. Both ship in the markup; one is hidden at a time. */
body:has(.wb-hero) .logo .logo-light{display:none}
body:has(.wb-hero) header.nav.scrolled .logo .logo-dark{display:none}
body:has(.wb-hero) header.nav.scrolled .logo .logo-light{display:block}

/* Links */
body:has(.wb-hero) header.nav nav ul{color:rgba(255,255,255,.88);transition:color .3s ease}
body:has(.wb-hero) header.nav nav a:hover{color:#fff}
body:has(.wb-hero) header.nav.scrolled nav ul{color:#334456}
body:has(.wb-hero) header.nav.scrolled nav a:hover{color:var(--ink)}

/* Contact us: white pill with navy type over the hero, navy pill with
   white type once the bar is over the page. No hover glow either way, the
   same trade site.css documents for the stock header CTA. */
body:has(.wb-hero) header.nav .nav-cta .btn-primary,
body:has(.wb-hero) header.nav .nav-cta .btn-primary:hover{
  background:#fff;color:var(--ink);box-shadow:none;
  transition:background .35s ease,color .35s ease;
}
body:has(.wb-hero) header.nav.scrolled .nav-cta .btn-primary,
body:has(.wb-hero) header.nav.scrolled .nav-cta .btn-primary:hover{background:var(--ink);color:#fff}

/* Search icon. It is a mask, so it takes the colour straight. Forced navy
   while the input is open at any scroll position: the input pill is white
   and a white icon on it is invisible. */
body:has(.wb-hero) header.nav .nav-search-icon{background-color:#fff}
body:has(.wb-hero) header.nav.scrolled .nav-search-icon{background-color:var(--ink)}
body:has(.wb-hero) header.nav .nav-search.open .nav-search-icon{background-color:var(--ink)}
body:has(.wb-hero) header.nav:not(.scrolled) .nav-search-btn:hover{background:rgba(255,255,255,.14)}

/* The hamburger is drawn by mobile-nav-unified.js in a stylesheet it
   appends at runtime, so it lands after this file and only a more
   specific selector can reach it. Navy bars on navy would be an invisible
   menu button on a phone. */
body:has(.wb-hero) header.nav:not(.scrolled) .hamburger .bars::before,
body:has(.wb-hero) header.nav:not(.scrolled) .hamburger .bars::after,
body:has(.wb-hero) header.nav:not(.scrolled) .hamburger .bars span{background:#fff}
body:has(.wb-hero) header.nav:not(.scrolled) .hamburger:hover{background:rgba(255,255,255,.12)}

/* ══ HERO ═══════════════════════════════════════════════════════════
   Navy ground, inverted type, modelled on .ev-hero (event-page.css):
   same ground, same self-carried nav clearance. The nav stays the stock
   white bar over it, the same deliberate trade event-page.css documents.

   Three rows: the headline block full width, then the teaser and the
   speaker roster in the left column with the access form in the right.
   The teaser is what someone came for and the roster is who is in it, so
   both sit beside the ask rather than below it. */
#page-wrap:has(> .wb-hero){padding-top:0}

/* The clip is back and the bottom padding is back to what the hero's own
   balance wants. Both were bent around a popover that opened below the
   roster and needed room to hang; the biography lives on the back of the
   card now, so nothing leaves the section. */
/* PADDING TUNED TO A LAPTOP. 124/76 put the bottom of the roster just
   under the fold at 1280x800, so the four cards were cut across the job
   titles: the worst place to cut, since a half-card reads as a rendering
   fault rather than as more page below. The hero is not forced to a full
   100vh, which would leave a short viewport scrolling inside a screen of
   navy and a tall one padding it out; it is trimmed until the roster
   clears the fold on the common size and left to be its own height.

   The top is 152px rather than the 108px that merely cleared the nav. The
   bar is transparent now, so that clearance is navy rather than white and
   reads as the hero's own top margin: at 108 the headline started ~28px
   under a bar it was no longer separated from, which looked like a
   mistake rather than a margin. The bottom loses 4px to pay part of it
   back. */
.wb-hero{
  position:relative;
  /* Trimmed so the band below is legible at the fold, not just visible:
     on a 13-inch laptop "What you'll learn" was arriving as a sliver of
     letterforms. 120px still clears the fixed nav by 40. */
  padding:120px 32px 44px;
  background:linear-gradient(180deg,#0D2E51 0%,#0A2543 100%);
  overflow:hidden;
}
.wb-hero-inner{position:relative;z-index:1;max-width:1180px;margin:0 auto}

/* Copy column. The headline is smaller than a full-width hero h1 would
   be: at 50px in half the page it ran six lines and the lede lost the
   fight with it.

   No max-width of its own any more: the column is an even half of the
   grid and the copy fills it. The old 540px cap was holding the text
   narrower than the track it sat in, which was part of what made the
   headline run three lines beside a frame that had room to spare. */
.wb-hero-copy{max-width:none}
/* LEADING IS NOT THE SITE'S 1.02. The other display headings
   (.sw-h1, .cmp-h1, .hero-h1) cap at 67px and set 1.02-1.06, which is
   right for type that size: the taller the line, the less air it needs
   between them. This one caps at 40px, 60% of that, and inherited the
   tight end of the ramp without the size that earns it.

   At 1.1 the three lines measured 5.2px of ink between them: Inter's
   descender is .242em and its cap height .727em, so 1.1 leaves
   (1.1 - .727 - .242) = .131em of gap, and every line of this headline
   has both a descender and a cap. The "g" of "Bringing" was closing on
   the "L" of "Life". 1.15 opens it to .181em and matches .nv-title,
   the one other mid-size display heading on the site. Costs 6px of
   hero height per line, which the fold has. */
.wb-h1{
  font-size:var(--t-h1-hero);
  line-height:1.04;letter-spacing:-.042em;font-weight:600;
  color:#fff;text-wrap:balance;margin-bottom:18px;
}
.wb-lede{
  font-size:var(--t-lede);line-height:1.55;
  color:rgba(255,255,255,.75);
}
/* Plain text, not pills. As pill-shaped chips these three facts read as
   three buttons and invited a click that led nowhere. */
.wb-metaline{
  margin-top:20px;
  font-size:var(--t-fine);font-weight:500;
  color:rgba(255,255,255,.58);
}
.wb-metaline span{white-space:nowrap}
.wb-metaline i{font-style:normal;padding:0 10px;opacity:.5}

/* Say it on the left, show it on the right, TOP-ALIGNED. They used to be
   centred against each other because the right column carried the roster
   as well as the frame and ran ~240px taller, which left the headline
   starting a third of the way down the screen with nothing above it and
   no edge anywhere for the eye to hang the two columns on.

   With the roster moved out to its own full-width row the two columns are
   within ~10px of each other, so a shared top edge is the honest
   alignment: the cap-height of the h1 and the top of the frame land on
   the same line.

   EVEN SPLIT. The media column used to take the larger share, on the
   argument that a wider frame is the point of a recording. It is not,
   while the frame is an empty placeholder: at .82/1.18 the largest thing
   on the page was a blank rectangle and the headline was squeezed onto
   three lines beside it. An even split shrinks the empty frame, gives the
   headline and the lede the width they want, and still leaves the frame
   the larger single object in the hero. Worth revisiting once a real
   still is in it. */
.wb-hero-grid{display:grid;grid-template-columns:1fr 1fr;gap:48px;align-items:start}
.wb-hero-media{display:flex;flex-direction:column}
.wb-hero-cta{margin-top:30px;align-self:flex-start}
/* Same reason as .wb-player[hidden]: this button is display'd by .btn and
   again by the narrow-screen rule near the bottom of this file, so the
   [hidden] the unlock script sets needs a selector that outranks both. */
.wb-hero-cta[hidden]{display:none}

/* ── Teaser ────────────────────────────────────────────────────────
   What stands in the hero's frame until the access form is filled.
   Clicking it moves focus to that form, which is the only thing that can
   release the recording; on success it is hidden and .wb-player below
   takes this exact frame. */
/* THE TOP BAR IS MARKUP, NOT ARTWORK. It was baked into the still, which
   forced two near-identical JPEGs, because this frame sits on the navy
   hero and wants a white bar while the hub card sits on a white card and
   wants a navy one. Now there is one image, cropped to the artwork alone
   (1600x788), and each page draws its own bar over it. The copy is
   editable text rather than pixels.

   The geometry is the baked bar's, measured off it: 7% of the frame's
   width tall, insets of 4.4%, caps of 2.49% and 2.32%. In cqw those hold
   at any size, which is why the frame is a container. 16/9 less a bar of
   7cqw leaves the artwork 2.0305:1, the file's own ratio, so it fits
   with nothing cropped.

   padding:0 because this is a <button> and the UA's own padding would
   otherwise hold the bar off the frame's edges. The radial stays
   underneath as the colour the frame falls back to before the image
   decodes, or if it ever 404s. */
.wb-teaser{
  position:relative;display:flex;flex-direction:column;width:100%;padding:0;
  aspect-ratio:16/9;border-radius:16px;overflow:hidden;
  border:1px solid rgba(255,255,255,.18);
  container-type:inline-size;
  background:radial-gradient(ellipse 120% 130% at 50% 118%,rgba(65,154,248,.55) 0%,rgba(13,46,81,.92) 58%,#07182B 100%);
  cursor:pointer;transition:border-color .2s ease,transform .2s ease;
}
/* White ground, navy type, the inverse of the hub card's: against this
   navy hero it is what gives the frame its top edge. */
.wb-teaser-bar{
  flex:none;height:7cqw;
  display:flex;align-items:center;justify-content:space-between;gap:3cqw;
  padding:0 4.4cqw;
  background:#fff;color:var(--ink);
  font-weight:700;line-height:1;white-space:nowrap;
}
.wb-teaser-kicker{font-size:max(9px,2.49cqw);letter-spacing:.03em;text-transform:uppercase}
.wb-teaser-when{font-size:max(9px,2.32cqw)}
.wb-teaser-art{
  flex:1;min-height:0;
  background:url('/assets/img/webinar-officespace-teaser.jpg') center/cover no-repeat;
}
.wb-teaser:hover{border-color:rgba(255,255,255,.42);transform:translateY(-2px)}
.wb-teaser:focus-visible{outline:3px solid var(--teal);outline-offset:3px}
/* SOLID WHITE, NAVY GLYPH. It was a translucent white disc with a white
   glyph, which worked while the frame behind it was the navy placeholder
   gradient. The still that replaced that gradient is a floor plan on
   white, so a white button on 18% white over it was invisible: the
   centre of the frame is the lightest part of the image. Opaque white
   with a navy triangle reads on either, and it is the same button the
   share card carries, so the frame and the card that represents it off
   site agree. */
.wb-teaser-play{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:74px;height:74px;border-radius:999px;
  background:#fff;box-shadow:0 6px 20px rgba(13,46,81,.30),0 0 0 10px rgba(255,255,255,.22);
  display:flex;align-items:center;justify-content:center;
  transition:box-shadow .2s ease,transform .2s ease;
}
.wb-teaser-play svg{fill:var(--ink);margin-left:3px}
.wb-teaser:hover .wb-teaser-play{
  box-shadow:0 8px 26px rgba(13,46,81,.36),0 0 0 14px rgba(255,255,255,.28);
  transform:translate(-50%,-50%) scale(1.06);
}
/* The credit and the runtime sit inside the frame, on one row along its
   bottom edge, rather than as a caption line under it. That line was a
   whole row of hero height spent on a sentence the frame can carry
   itself, and losing it is most of what brings the roster back above the
   fold on a laptop.

   The scrim is on this row rather than on the frame, so it still reads
   once a real still is dropped in behind it. */
.wb-teaser-meta{
  position:absolute;left:0;right:0;bottom:0;
  display:flex;align-items:center;justify-content:space-between;gap:14px;
  padding:34px 14px 14px;
  background:linear-gradient(180deg,rgba(4,14,26,0) 0%,rgba(4,14,26,.62) 100%);
}
.wb-teaser-credit{
  font-size:var(--t-micro);font-weight:600;letter-spacing:.01em;
  color:rgba(255,255,255,.88);text-align:left;
}
.wb-teaser-time{
  flex:none;
  background:rgba(4,14,26,.72);color:#fff;
  font-size:var(--t-kicker);font-weight:700;letter-spacing:.06em;
  padding:5px 11px;border-radius:999px;
}

/* ── The recording, once the gate is open ─────────────────────────
   The teaser's frame, to the pixel: same width from the flex column,
   same 16/9, same 16px radius, same hairline. Swapping one for the other
   is then invisible as layout, which is the whole point of putting the
   player here rather than somewhere the page has to grow to fit.

   No aspect-ratio on the wrapper, only on the frame: the pending line
   sits under the frame when there is no URL yet, and a ratio on the
   wrapper would have squashed the frame to make room for it. */
.wb-player{display:flex;flex-direction:column;gap:12px;scroll-margin-top:96px}
/* THE [hidden] RULES EARN THEIR KEYWORD. Both frames set display, which
   beats the UA's own [hidden]{display:none} on specificity alone, so
   without these the player would sit in the hero from page load and the
   teaser would stay under it after the unlock. The attribute is how the
   gate is expressed in the markup; these are what make it mean anything.
   Specificity, not !important: .wb-player[hidden] outranks .wb-player. */
.wb-player[hidden]{display:none}
.wb-teaser[hidden]{display:none}
.wb-player-frame{
  position:relative;width:100%;aspect-ratio:16/9;
  border-radius:16px;overflow:hidden;
  border:1px solid rgba(255,255,255,.18);
  background:radial-gradient(ellipse 120% 130% at 50% 118%,rgba(65,154,248,.55) 0%,rgba(13,46,81,.92) 58%,#07182B 100%);
}
/* The iframe arrives from script and carries no attributes of its own. */
.wb-player-frame iframe{
  position:absolute;inset:0;width:100%;height:100%;border:0;display:block;
}
/* Only while data-recording-src is still empty. An unlocked visitor sees
   a sentence rather than a black rectangle, and the line disappears the
   moment the URL is pasted in. */
.wb-player-pending{display:none}
.wb-player.is-pending .wb-player-pending{
  display:block;
  font-size:var(--t-small);line-height:1.6;
  color:rgba(255,255,255,.72);
}

/* ── Meet the speakers, in the hero ───────────────────────────────
   A text link under the video, pointing at the roster in the rail below.
   It carried the four portraits and was a ghost pill; both are gone. The
   portraits were a thumbnail of a block one scroll away that shows the
   same faces at a legible size, and the pill made it read as a second
   button of nearly the primary CTA's weight, which is too loud for a
   link that only moves the reader down its own page. What is left is
   the part that was doing the work: a verb, a destination, and an arrow
   pointing the way. It points down, not along, because the roster is
   further down this same page rather than at the end of a link, and it
   nudges down on hover for the same reason.

   A real <a>, so it keeps keyboard focus and open-in-new-tab for free.
   align-self, because .wb-hero-media is a flex column: left to stretch
   the link's focus ring would run the full width of the video frame. */
.wb-cast{
  display:inline-flex;align-self:flex-start;align-items:center;gap:7px;
  margin-top:16px;
  font-size:var(--t-fine);font-weight:600;line-height:1;
  text-decoration:none;color:#fff;white-space:nowrap;
}
.wb-cast svg{width:14px;height:14px;transition:transform .2s ease}
.wb-cast:hover svg{transform:translateY(3px)}
.wb-cast:focus-visible{outline:2px solid var(--teal);outline-offset:3px;border-radius:4px}

/* ── Speaker roster, its own band on the light page ───────────────
   Four cards in one row. Each card carries the speaker on its front and
   their §11 biography on its back, and crossfades between the two on
   hover, focus or tap.

   This replaced a floating tooltip card that appeared under the hovered
   speaker. A detached white panel with a drop shadow hanging over the
   navy read as a browser tooltip rather than as part of the page, it
   covered whatever was beneath it, and on a phone it could not fire at
   all. Changing the card the reader is already pointing at has none of
   those problems.

   A crossfade, not a 3D flip. Four cards flipping in sequence as the
   mouse crosses the row reads as a widget demo, and a flip has to solve
   backface-visibility and a mid-rotation blur to buy nothing the fade
   does not already give. */
/* Its own band now, not the foot of the hero. At ~280px a card sets the
   job title on one or two lines instead of three, so the card does not
   have to be 172px tall to hold a front face. */
.wb-roster{
  display:grid;grid-template-columns:repeat(4,1fr);gap:16px;
  list-style:none;
}
/* The card surface is what makes a face change legible. Without one,
   text swapping in mid-air reads as a glitch.

   These were translucent white over the navy hero. On the page's own
   light ground they are the .wb-takeaway card instead, the same white,
   line and soft shadow the takeaways and the form already use, so the
   roster does not introduce a fifth card treatment. */
.wb-speaker{
  position:relative;display:grid;width:100%;height:162px;
  /* 26px of side padding, not 14. At ~283px wide the card had more room
     than it was using, and the biography on the back face was running to
     both edges. The wider inset also buys the front face something: the
     longest job title now sets on one line instead of two. */
  padding:18px 26px;border-radius:16px;
  background:#fff;border:1px solid var(--line);
  box-shadow:0 4px 16px rgba(13,46,81,.06);
  font:inherit;color:inherit;text-align:center;cursor:pointer;
  transition:box-shadow .22s ease,border-color .22s ease,transform .22s ease;
}
.wb-speaker:hover,
.wb-speaker:focus-visible,
.wb-speaker.is-open{
  box-shadow:0 12px 40px rgba(13,46,81,.10);
  border-color:rgba(65,154,248,.45);transform:translateY(-2px);
}
.wb-speaker:focus-visible{outline:2px solid var(--teal);outline-offset:2px}

/* Both faces sit in the same grid cell and the card height is fixed, so
   the row cannot reflow no matter which card is open or how long that
   speaker's biography runs.

   162px is the front face plus a little slack. The front is the taller
   of the two: a 52px portrait, the name, and a job title over two lines
   comes to 118px, which with 36px of padding wants 154. It was set to 150
   and the front was quietly spilling 6px into its own bottom padding.
   Sizing it to exactly 154 left zero headroom, which a font fallback
   would spend immediately, so there are 6px in hand. The back face
   needs 96px at its worst, David's, which is the longest §11 biography of
   the four; the spare room is the front face's, not the back's. */
.wb-face{
  grid-area:1 / 1;display:flex;flex-direction:column;align-items:center;
  transition:opacity .2s ease;
}
.wb-face img{
  width:52px;height:52px;border-radius:999px;display:block;
  object-fit:cover;object-position:center top;
  background:var(--teal-soft);margin-bottom:10px;
}
.wb-name{font-size:var(--t-fine);font-weight:700;letter-spacing:-.01em;color:var(--ink);margin-bottom:4px}
.wb-role{font-size:var(--t-micro);line-height:1.4;color:var(--teal-ink)}
.wb-co{font-size:var(--t-micro);line-height:1.4;color:var(--muted)}

/* The name stays on the back. Without it the reader loses track of whose
   biography they are half way through. */
.wb-back{justify-content:center;text-align:left;opacity:0}
.wb-back-name{
  font-size:var(--t-kicker);font-weight:700;letter-spacing:.1em;
  text-transform:uppercase;color:var(--teal-ink);margin-bottom:8px;
}
.wb-bio{font-size:var(--t-micro);line-height:1.55;color:var(--muted)}

.wb-speaker:hover .wb-front,
.wb-speaker:focus-visible .wb-front,
.wb-speaker.is-open .wb-front{opacity:0}
.wb-speaker:hover .wb-back,
.wb-speaker:focus-visible .wb-back,
.wb-speaker.is-open .wb-back{opacity:1}

@media(prefers-reduced-motion:reduce){
  .wb-speaker,.wb-face,.wb-cast svg{transition:none}
}

/* ── Access form ──────────────────────────────────────────────────
   Lives beside the takeaways now, not in the hero, so it sits on the
   page's own light ground: a line and a soft shadow instead of the heavy
   drop shadow it needed to lift off the navy.

   IT STICKS AGAIN, AND THE REASON IT DID NOT IS WHY IT CAN NOW. The card
   was unstuck when the column beside it was three takeaway cards tall:
   over that little distance the two halves of the band moved at different
   speeds for a few hundred pixels and read as a glitch. The rail is four
   blocks and roughly 2,400px now, which is long enough that a card
   holding its place reads as an anchored ask instead of a stutter.

   On success this card does not disappear: .is-success empties it of
   every asking row and leaves the confirmation, so the column keeps its
   width and the sticky card keeps its place while the reader watches the
   recording the card just released. */
/* The shell carries the glow; the card sits on top of it. Splitting them
   is what lets the glow read from under the card: a ::before on .wb-form
   itself paints above the card's own white background, not behind it. */
/* 96px is the page's own anchor offset (.wb-page > .section[id] sets the
   same number as scroll-margin-top), so the card parks exactly where a
   jumped-to heading parks: clear of the fixed nav, by the same gap.
   position:sticky doubles as the position:relative the glow needs. */
.wb-form-shell{position:sticky;top:96px;align-self:start}
/* Only when the viewport can hold the whole card. Below this the submit
   button would be parked under the fold with no way to scroll to it,
   which is worse than a card that scrolls normally.

   THE NUMBER MOVED WITH THE CARD. It was 620px, tuned when the card was
   the ~450px unwired version. Wiring the gate added the reCAPTCHA note
   and the widget forms.js injects above the button: measured at the real
   448px column width the card is 586px at rest and 678px once the widget
   renders. 678 + the 96px offset + a 24px bottom margin is 798, so 800px
   is the shortest viewport that can still show the button. Anything
   shorter scrolls normally. Re-measure this if the card gains a row. */
@media(max-height:799px){
  .wb-form-shell{position:relative;top:auto}
}
/* GLOW. The .ev-meet-section halo from event-page.css, same gradient and
   the same stops, re-sized for a card this shape. The first pass put a
   periwinkle blob under the card: a colour the site does not use, sitting
   below the card rather than around it, which read as a shadow that had
   gone wrong. This is the treatment the events page already ships, and
   every value in it is --teal or the homepage's cyan.

   Sized well past the card on purpose. The card is opaque, so everything
   inside its footprint is invisible and at the card's own size only the
   faint outer tail shows. The events page puts a 1610px halo around a
   1320px card, roughly 290px of light on each side; this card is half
   that width, so matching its percentage would have given half the
   spread and half the glow. 176% x 195% restores the absolute reach. */
.wb-form-shell::before{
  content:"";position:absolute;z-index:0;pointer-events:none;
  top:50%;left:50%;transform:translate(-50%,-50%);
  width:min(1020px,176%);height:195%;
  background:radial-gradient(ellipse farthest-side,
    rgba(65,154,248,.315) 0%,
    rgba(101,213,236,.21) 18%,
    rgba(65,154,248,.126) 36%,
    rgba(65,154,248,.063) 54%,
    rgba(65,154,248,.021) 72%,
    rgba(65,154,248,0) 90%);
}
.wb-form{
  position:relative;z-index:1;
  background:#fff;color:var(--ink);border-radius:16px;padding:30px 28px;
  border:1px solid var(--line);
  /* The .ev-meet pair: a blue-tinted near shadow that belongs to the glow
     plus a neutral far one, instead of one grey drop. */
  box-shadow:0 16px 40px rgba(65,154,248,.14),0 30px 60px rgba(13,46,81,.05);
  display:flex;flex-direction:column;gap:14px;
}
.wb-form h2{font-size:var(--t-h3);font-weight:600;letter-spacing:-.02em;color:var(--ink)}
.wb-form > p{font-size:var(--t-small);line-height:1.6;color:var(--muted);margin-top:-6px}
.wb-row{display:flex;gap:12px}
.wb-field{display:flex;flex-direction:column;gap:6px;flex:1;min-width:0}
.wb-field label{font-size:var(--t-micro);font-weight:600;color:var(--ink)}
.wb-field input{
  border:1px solid rgba(13,46,81,.15);border-radius:10px;
  padding:11px 13px;font-size:var(--t-small);font-family:inherit;
  color:var(--ink);background:#fff;width:100%;
}
.wb-field input::placeholder{color:var(--faint)}
.wb-field input:focus{outline:none;border-color:var(--teal);box-shadow:0 0 0 3px rgba(65,154,248,.18)}
.wb-consent{display:flex;gap:10px;align-items:flex-start;font-size:var(--t-micro);line-height:1.55;color:var(--muted)}
.wb-consent input{margin-top:2px;accent-color:var(--teal);flex:none}
.wb-consent a{color:var(--teal-ink);text-decoration:underline}
.wb-form .btn{justify-content:center;width:100%}
.wb-fine{font-size:var(--t-micro);color:var(--faint);text-align:center}
/* site.css's .recaptcha-note is written for the grid forms and spans all
   columns there. This card is a flex column: the grid span comes off, and
   the size drops a step below the ramp floor (--t-kicker is 11px) so the
   legal line stays quiet against the ask. The rest of the type carries
   over. */
.wb-form .recaptcha-note{grid-column:auto;margin-top:0;font-size:10px}
/* Honeypot. Off-screen rather than display:none, which some bots skip. */
.wb-form .hp{position:absolute;left:-9999px;width:1px;height:1px;opacity:0;pointer-events:none}

/* ── The card's two states ─────────────────────────────────────────
   Resting, it is the ask. Submitted, it is the receipt. The switch is
   one rule: every direct child except the confirmation goes, which
   covers the heading, the fields, the consent row, the button, the fine
   print, the reCAPTCHA note and the widget forms.js injects, without
   this file having to name each one or know the injected div's shape. */
.wb-form .form-status,
.wb-form .form-error{display:none}
.wb-form.is-success > *{display:none}
.wb-form.is-success > .form-status{
  display:flex;flex-direction:column;gap:10px;align-items:flex-start;
}
.wb-form.is-error > .form-error{display:block}
/* The confirmation reads as the card's own content, not a banner inside
   it: the card is already white, bordered and glowing, and a second
   framed box inside that was a box in a box. */
.wb-form .form-status strong{
  font-size:var(--t-h3);font-weight:600;letter-spacing:-.02em;color:var(--ink);
}
.wb-form .form-status span{
  font-size:var(--t-small);line-height:1.6;color:var(--muted);
}
.wb-form .form-status .btn{margin-top:4px}
/* Same keyword problem as the hero CTA: .btn sets display, so the
   [hidden] the unlock script sets while there is still no recording URL
   needs a selector that outranks it. */
.wb-form .form-status .btn[hidden]{display:none}
.wb-form .form-error{
  font-size:var(--t-small);line-height:1.55;
  border-radius:12px;padding:12px 14px;
  background:rgba(239,68,68,.08);border:1px solid rgba(239,68,68,.32);
  color:#9B1C1C;
}
/* A submit that failed must not look like one that worked. */
.wb-form.is-loading .btn[type=submit]{opacity:.7;cursor:progress}

/* ══ EYEBROW ════════════════════════════════════════════════════════
   Same treatment as the .kicker on /platform: letterspaced uppercase in
   --teal, no pill. articles.css's .article-tag is a filled chip, which on
   this page read as a third button style competing with the real CTAs.
   Values are platform.css's, not new ones. */
.wb-kicker{
  display:inline-block;margin-bottom:16px;
  font-size:var(--t-kicker);font-weight:700;letter-spacing:.18em;
  text-transform:uppercase;color:var(--teal);
}

/* ══ SECTION HEADS ══════════════════════════════════════════════════
   Most sections run heading-only. The eyebrow is not decoration and it
   is not owed to every band: it goes where the H2 argues something
   rather than naming something, and is therefore not by itself an answer
   to "where am I". §7 ("Your booking system and your building do not
   always agree") and §9 ("For the people who manage where work happens")
   are claims, so each takes a two-word label above it. "What you'll
   learn" and "Who is in this session" already name themselves, and an
   eyebrow over either would be the same words twice. */
/* 28px, not 40. A heading followed by naked prose spends the whole gap
   as visible white, so 40px read as a hole under "Booked isn't the same
   as used." while the same 40px under a card row did not. */
.wb-head{max-width:660px;margin-bottom:28px}
/* Prose gets less than a card row does, not more. A card draws a visible
   border, so the eye measures the gap to that edge and the card's own
   padding counts for nothing; prose has no edge, so the gap runs all the
   way to the first line of text and picks up the leading above it on the
   way. Same perceived distance, two different numbers: 28 to a border,
   20 to a line of type. */
.wb-head:has(+ .wb-prose){margin-bottom:20px}
.wb-head.is-center{margin-left:auto;margin-right:auto;text-align:center}
.wb-head .wb-kicker{margin-bottom:14px}
/* ONE SECTION-HEADING SIZE, AND IT SITS UNDER THE H1. This was its own
   clamp capping at 40px, which is also where .wb-h1 caps, so from 1333px
   up the page set its title and its section headings at exactly the same
   size. Below that it was worse rather than better: the two clamps ramp at
   different rates, 3.6vw here against 3.0vw on the h1, so between about
   980 and 1333px these headings were visibly LARGER than the headline.
   The hero was carrying its primacy on position and the navy ground alone.

   --t-h2-sm is the size the partner and About bands were already setting,
   so this is the ramp the page mostly had: 40 for the h1, 34 for every
   section heading under it. The leading comes with it. 1.08 at 34px leaves
   (1.08 - .727 - .242) = .111em between lines, tighter than the 1.1 the h1
   was moved off for closing up its descenders, and these headings wrap to
   two lines. 1.12 is what the other two bands already set. */
.wb-head h2{
  font-size:var(--t-h2-sm);font-weight:600;
  letter-spacing:-.03em;line-height:1.12;color:var(--ink);
  text-wrap:balance;
}
.wb-head p{
  margin-top:16px;font-size:var(--t-h4);line-height:1.65;
  color:var(--muted);max-width:var(--measure);
}
.wb-head.is-center p{margin-left:auto;margin-right:auto}

/* ══ OVERVIEW ═══════════════════════════════════════════════════════
   Single column since the planned-vs-verified node figure was removed.
   Held to a measure so the paragraphs do not run the full 980px. */
.wb-prose p{font-size:var(--t-body-lg);line-height:1.75;color:var(--muted);max-width:var(--measure)}
.wb-prose p + p{margin-top:18px}
.wb-prose h3{
  font-size:var(--t-h3);font-weight:600;letter-spacing:-.02em;
  color:var(--ink);margin:32px 0 12px;
}

/* ══ TAKEAWAYS + ACCESS FORM ════════════════════════════════════════
   The reasons to watch on the left, the ask on the right. Three cards
   across read as decoration under the hero; the same three as a list
   beside the form are the argument for filling it in. */
/* Three cells, two rows: the heading sits alone in row 1 of the left
   column and the card list and the form share row 2. The form's top edge
   therefore lands on the first takeaway card's top edge no matter how
   many lines the heading takes, which a two-column grid with the heading
   inside the left column could not do. */
/* The left column is wider than the right now. It holds four blocks
   including a two-up card grid and two measured columns of prose, and the
   form needs about 440px, not half the page. */
.wb-offer{
  display:grid;grid-template-columns:1.2fr .8fr;
  column-gap:60px;align-items:start;
}
/* The child combinator matters: the rail's own .wb-head blocks are not
   grid items and must not be dragged into row 1. */
.wb-offer > .wb-head{grid-column:1;grid-row:1}
.wb-offer-main{grid-column:1;grid-row:2}
.wb-form-shell{grid-column:2;grid-row:2}
/* THE RAIL. Four blocks, one under the other, with the form beside all
   four of them. 88px between: they were separate <section>s with the
   page's own band padding between them, and a rail that keeps them
   closer than that reads as one long column of argument, which is what
   it now is. */
.wb-offer-main{display:flex;flex-direction:column;gap:88px}
/* Each block keeps the anchor offset it had as a section of its own. */
.wb-block{scroll-margin-top:96px}
/* Two up, not four. At half the page a four-card row gives each card
   ~150px, which is narrower than a job title. */
.wb-offer-main .wb-roster{grid-template-columns:1fr 1fr}
.wb-takeaways{list-style:none;display:flex;flex-direction:column;gap:14px}
.wb-takeaway{
  display:grid;grid-template-columns:44px 1fr;gap:18px;align-items:start;
  background:#fff;border:1px solid var(--line);border-radius:16px;
  padding:24px 26px;box-shadow:0 4px 16px rgba(13,46,81,.06);
  transition:box-shadow .2s,transform .2s;
}
.wb-takeaway:hover{box-shadow:0 12px 40px rgba(13,46,81,.10);transform:translateY(-2px)}
.wb-card-icon{
  width:44px;height:44px;border-radius:12px;background:var(--teal-soft);
  display:flex;align-items:center;justify-content:center;flex:none;
}
.wb-takeaway h3{
  font-size:var(--t-h3-sm);font-weight:600;letter-spacing:-.02em;
  line-height:1.3;color:var(--ink);margin-bottom:8px;
}
.wb-takeaway p{font-size:var(--t-body);line-height:1.65;color:var(--muted)}

/* ══ FAQ ════════════════════════════════════════════════════════════
   The homepage FAQ component, ported verbatim from index.css (the
   .faq-item card, the gradient-filled open state with its gradient
   border, and the plus that rotates into a minus). This page does not
   load index.css, so the rules are repeated here rather than referenced;
   they are scoped under .wb-page so they cannot collide anywhere else.
   If the homepage component changes, change it here too.

   The bare-rule .wb-faq-* disclosure this replaces is gone: it was a
   second FAQ look on a site that already has one. */
/* Its own band now, not the right-hand column of the audience block.
   Centred and measured, because it is the one thing on the page that is
   not an argument for watching: it answers what is left after the reader
   has decided, and a centred column is what says the arguing is over.
   Left full width the questions ran to 1180px and the answers under them
   read as a paragraph of small print. */
.wb-faq{max-width:820px;margin-left:auto;margin-right:auto}

.wb-page .faq-single{display:flex;flex-direction:column;gap:14px}
.wb-page .faq-item{
  padding:0;border-radius:16px;background:#fff;
  border:1px solid var(--line-soft);
  transition:background .2s,border-color .2s;
}
.wb-page .faq-item.is-open{
  border:1px solid transparent;
  background:linear-gradient(180deg,rgba(65,154,248,.16),rgba(65,154,248,0) 70%) padding-box,
             linear-gradient(#fff,#fff) padding-box,
             linear-gradient(180deg,rgba(65,154,248,.59),rgba(65,154,248,.2)) border-box;
}
.wb-page .faq-q{
  width:100%;font:inherit;font-weight:600;font-size:var(--t-body);cursor:pointer;
  display:flex;justify-content:space-between;align-items:center;gap:16px;
  text-align:left;color:var(--ink);background:none;border:0;
  transition:color .15s;padding:22px 26px;
}
.wb-page .faq-item:hover .faq-q,.wb-page .faq-q:hover{color:var(--teal)}
.wb-page .faq-icon{flex-shrink:0;width:16px;height:16px;position:relative}
.wb-page .faq-icon-dash{
  position:absolute;top:50%;left:0;width:100%;height:2px;border-radius:1px;
  background:currentColor;transform:translateY(-50%);
}
.wb-page .faq-icon-dash--v{
  width:2px;height:100%;top:0;left:50%;transform:translateX(-50%);
  transition:transform .4s cubic-bezier(.165,.84,.44,1),opacity .4s;
}
.wb-page .faq-item.is-open .faq-icon-dash--v{transform:translateX(-50%) rotate(90deg);opacity:0}
/* Smooth open/close via the grid-template-rows 0fr->1fr trick (native
   details/summary can't animate height:auto). */
.wb-page .faq-pane{
  display:grid;grid-template-columns:1fr;grid-template-rows:0fr;
  overflow:hidden;transition:grid-template-rows .6s cubic-bezier(.165,.84,.44,1);
}
.wb-page .faq-item.is-open .faq-pane{grid-template-rows:1fr}
.wb-page .faq-pane-mask{overflow:hidden}
.wb-page .faq-pane-content{
  padding:0 26px 22px;font-size:var(--t-small);color:var(--muted);line-height:1.65;
  opacity:0;transform:translateY(1rem);
  transition:transform .8s cubic-bezier(.165,.84,.44,1),opacity .6s;
}
.wb-page .faq-item.is-open .faq-pane-content{opacity:1;transform:translateY(0)}
@media(prefers-reduced-motion:reduce){
  .wb-page .faq-pane,.wb-page .faq-pane-content,.wb-page .faq-icon-dash--v{transition:none}
}

/* ══ ABOUT OFFICESPACE ══════════════════════════════════════════════
   The same two-column band as About Embrava below it, mirrored: copy
   left, visual right, no frame. Alternating the hands keeps the reader
   from tracking down the same column twice in a row. It was a bordered white card, which made a section
   It was a bordered white card, which made a section about the partner
   read as a co-branded banner and broke the rhythm of the two partner
   sections, which now match.

   THE EYEBROW IS BACK AND THE MARK IS NOT. This band used to open with the
   OfficeSpace logo and a letterspaced "confirmed Embrava alliance partner"
   badge, on the argument that the row carried the same uppercase weight in
   the same place as "About Embrava" does below. It did not read that way:
   a logo lockup is a heavier object than a line of type, so the two bands
   opened differently, and the badge restated a claim the second paragraph
   already makes in full. An "About OfficeSpace" .wb-kicker is the same
   component the band below uses, so the two now match exactly. The mark
   moves into the figure, which is where the reader is looking for it. */
.wb-partner{display:grid;grid-template-columns:.96fr 1.04fr;gap:52px;align-items:center}
/* Still a placeholder: OfficeSpace has not supplied an approved visual, so
   the frame holds their mark and says so. When the real floor plan or
   product view arrives, drop it in as a background-image or an <img>, then
   delete the mark, the note and the dashed border. */
.wb-partner-figure{
  aspect-ratio:4/3;border-radius:18px;
  border:1px dashed rgba(13,46,81,.22);
  background:linear-gradient(160deg,var(--teal-soft) 0%,var(--bg) 100%);
  display:flex;flex-direction:column;align-items:center;justify-content:center;
  gap:14px;text-align:center;padding:20px;
}
/* Sized off the frame rather than set in px: the band is two even-ish
   columns, so a mark pinned to one size is either lost at 1400px or
   crowding the dashed edge at 1000. */
.wb-partner-mark{
  width:min(58%,260px);height:auto;object-fit:contain;
}
.wb-ph-note{font-size:var(--t-micro);line-height:1.5;color:var(--faint);max-width:24ch}
/* Matched to .wb-about-copy h2 so the two bands set their headings at
   the same size. */
.wb-partner h2{
  font-size:var(--t-h2-sm);font-weight:600;letter-spacing:-.035em;
  line-height:1.06;color:var(--ink);margin:0 0 18px;text-wrap:balance;
}
.wb-partner p{font-size:var(--t-body-lg);line-height:1.75;color:var(--muted)}
.wb-partner p + p{margin-top:16px}

/* ══ ABOUT EMBRAVA ══════════════════════════════════════════════════
   The reach map and its three numbers on the left, the approved
   boilerplate on the right. Centred under a centred heading the map band
   left a wide empty gutter beside it and the boilerplate had nowhere to
   sit that was not a fourth stacked paragraph; this puts the copy in the
   space the map was already leaving. The eyebrow travels with the copy,
   so it is no longer centred above the heading. */
.wb-about{display:grid;grid-template-columns:1.04fr .96fr;gap:52px;align-items:center}
.wb-about-copy h2{
  font-size:var(--t-h2-sm);font-weight:600;letter-spacing:-.035em;
  line-height:1.06;color:var(--ink);margin-bottom:18px;text-wrap:balance;
}
.wb-about-copy p{font-size:var(--t-body-lg);line-height:1.75;color:var(--muted)}

/* ══ WORLD MAP STAT BAND ════════════════════════════════════════════
   The map is tinted through a CSS mask rather than baked into the file,
   the same technique site.css uses for .nav-search-icon, so the artwork
   follows --teal if the token ever moves. It is decorative: the numbers
   in front of it carry the meaning, so it is hidden from assistive tech. */
.wb-reach{
  position:relative;
  min-height:420px;padding:40px 0;
  display:flex;align-items:center;
  /* The map is deliberately wider than the band on small screens; clip it
     here rather than leaning on html{overflow-x:clip}. */
  overflow:hidden;
}
.wb-reach-map{
  position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
  width:100%;max-width:1060px;aspect-ratio:87/34;
  background-color:var(--teal);opacity:.5;
  -webkit-mask-image:url('/assets/img/world-map-dots.svg');
          mask-image:url('/assets/img/world-map-dots.svg');
  -webkit-mask-size:contain;mask-size:contain;
  -webkit-mask-repeat:no-repeat;mask-repeat:no-repeat;
  -webkit-mask-position:center;mask-position:center;
  pointer-events:none;
}
.wb-stats{
  position:relative;z-index:1;width:100%;
  display:grid;grid-template-columns:repeat(3,1fr);gap:18px;
  max-width:820px;margin:0 auto;list-style:none;
}
.wb-stat{
  border-radius:18px;padding:24px 26px;
  background:rgba(255,255,255,.72);
  border:1px solid rgba(255,255,255,.85);
  box-shadow:0 10px 34px rgba(13,46,81,.10);
  backdrop-filter:blur(10px);-webkit-backdrop-filter:blur(10px);
}
.wb-stat span{
  display:block;font-size:var(--t-small);font-weight:600;
  color:var(--muted);margin-bottom:6px;
}
.wb-stat b{
  display:block;font-size:var(--t-stat);font-weight:800;
  letter-spacing:-.04em;line-height:1;color:var(--ink);
}
/* In half a page the three cards are ~170px each, so they carry less
   padding and a smaller number than they did full width. */
.wb-about .wb-stats{max-width:none}
.wb-about .wb-stat{padding:18px 18px}

/* ══ RESPONSIVE ═════════════════════════════════════════════════════ */
@media(max-width:980px){
  /* Every pair collapses to one column in reading order: what the thing
     is, then the ask. The form still lands about one screen down. */
  .wb-hero-grid{grid-template-columns:1fr;gap:36px}
  .wb-hero-copy{max-width:none}
  .wb-hero-cta{margin-top:24px}
  /* Two up: at one column the cards are wide enough that four across
     would set each job title in about 190px for no reason. */
  /* Two up. The card keeps the base height: a wider card does not make
     the front face shorter, because its height is the portrait plus three
     lines of text either way. */
  .wb-roster{grid-template-columns:1fr 1fr}
  /* One column: drop the explicit row/column placement or all three
     cells stack into the same grid area. */
  /* One column, and the form stops sticking with it: stacked, the card
     is no longer beside anything, so a card that held still would just be
     a block that refused to scroll. It goes back to where it belongs in
     the reading order, under the takeaways it is the ask for. */
  .wb-offer{grid-template-columns:1fr;gap:36px}
  .wb-offer > .wb-head,
  .wb-offer .wb-offer-main,
  .wb-offer .wb-form-shell{grid-column:1}
  .wb-form-shell{position:relative;top:auto}
  /* THE FORM GOES FIRST, ABOVE THE HEADING. Left in source order it
     lands under all four blocks, roughly two screens below the top of
     the band, and every "Watch on demand" anchor points at the top of
     the band: the reader would tap the button, arrive at a heading and
     see no form at all. The band is named #watch because the form is
     what it is for, so on a phone the form is what the anchor should
     land on. The four reasons follow it, which is the order a phone
     reads anyway, scroll-to-decide rather than glance-across. */
  .wb-offer{grid-template-rows:auto auto auto}
  .wb-offer .wb-form-shell{grid-row:1}
  .wb-offer > .wb-head{grid-row:2}
  .wb-offer .wb-offer-main{grid-row:3}
  .wb-offer-main{gap:64px}
  .wb-partner{grid-template-columns:1fr;gap:32px}
  .wb-partner-figure{aspect-ratio:16/9}
  .wb-about{grid-template-columns:1fr;gap:32px}
  .wb-reach{min-height:340px}
  .wb-reach-map{width:150%;max-width:none;opacity:.38}
}
@media(max-width:680px){
  .wb-page > .section{padding:56px 20px}
  .wb-hero{padding:104px 20px 52px}
  /* .wb-hero-copy is not a flex parent, so align-self does nothing here:
     set the width directly. */
  .wb-hero-cta{display:flex;width:100%;justify-content:center}
  /* One up. The card is now full width, so both faces fit side by side
     and nothing has to be hidden: the portrait sits left, the name, role
     and biography all read at once. The flip is retired rather than
     reproduced, because a phone has no hover to reproduce it with. */
  .wb-roster,.wb-offer-main .wb-roster{grid-template-columns:1fr;gap:10px}
  .wb-speaker{
    height:auto;grid-template-columns:52px 1fr;
    column-gap:14px;row-gap:3px;
    text-align:left;padding:14px;cursor:default;
  }
  /* display:contents dissolves both faces into the card's own grid, so
     the four text lines become four rows in column two and the portrait
     spans all of them. */
  .wb-face{grid-area:auto;display:contents}
  .wb-face img{grid-row:1 / span 4;align-self:start;margin-bottom:0}
  .wb-back{opacity:1}
  .wb-back-name{display:none}
  .wb-bio{grid-column:2;margin-top:6px;color:var(--muted)}
  .wb-speaker:hover .wb-front,
  .wb-speaker.is-open .wb-front{opacity:1}
  .wb-speaker:hover,
  .wb-speaker.is-open{transform:none;box-shadow:0 4px 16px rgba(13,46,81,.06);border-color:var(--line)}
  .wb-cast{margin-top:22px}
  /* The credit wraps to two lines inside a phone-width frame; it keeps
     its own line height rather than pushing the runtime pill around. */
  .wb-teaser-meta{padding:28px 10px 10px;gap:10px}
  .wb-teaser-credit{font-size:var(--t-kicker);line-height:1.35}
  .wb-page .faq-q{padding:18px 20px;font-size:var(--t-small)}
  .wb-page .faq-pane-content{padding:0 20px 18px}
  .wb-row{flex-direction:column}
  .wb-takeaway{grid-template-columns:1fr;gap:14px;padding:22px 22px}
  .wb-reach{min-height:0;padding:24px 0}
  .wb-reach-map{width:190%;opacity:.3}
  .wb-stats{grid-template-columns:1fr;max-width:none}
  .wb-stat,.wb-about .wb-stat{display:flex;align-items:baseline;justify-content:space-between;gap:16px;padding:18px 22px}
  .wb-stat span{margin-bottom:0}
  .wb-head{margin-bottom:28px}
  .wb-form{padding:24px 20px}
  /* The frame is full width on a phone, so the mark can take less of it. */
  .wb-partner-mark{width:min(46%,200px)}
  .final-cta{margin-top:16px;padding:24px 0 40px}
}
@media(max-width:560px){
  /* The closing line wraps on its own at this width, so the forced break
     would only add a third line. */
  .wb-brk{display:none}
}
/* Card counts by width: four across in the hero's right column, two up
   once the hero is a single column, one up on a phone, where the card is
   wide enough to show both faces at once and the flip retires. */

/* ══ ORPHANS ══════════════════════════════════════════════════════════
   A single word stranded on a last line is this page's most common
   typographic snag: it is long-form copy in narrow columns, and there
   are a lot of last lines.

   It is a hint, not a hand-set fix, and that is deliberate. An orphan is
   a property of the width the text is read at, not of the sentence: the
   word left behind at 1440 is not the word left behind at 1100, and
   &nbsp;-binding the pair that fails on a laptop can force an overflow
   on a phone. text-wrap:pretty asks the browser to solve it at whatever
   width it is actually at, and costs nothing where it is unsupported.

   It does not catch everything. Chrome only reconsiders the last few
   lines, so a very narrow column can still strand a word. The ones that
   survive at desktop widths are bound by hand in the markup as well. */
/* Prose gets pretty, display headings get balance. They are different
   problems: a paragraph wants its last line not to be one word, and
   pretty adjusts only the end of it. A heading is short enough to set as
   a shape, and balance evens every line, which is what takes the hero
   h1 from "…to Life with Embrava + / OfficeSpace" to three even lines
   breaking at "with". Balance is capped at a few lines in Chrome, so it
   is for headings only; on a long paragraph it would do nothing. */
.wb-page h1,.wb-page h2{
  text-wrap:balance;
}
.wb-page h3,.wb-page h4,
.wb-page p,.wb-page li,
.wb-page .wb-bio,.wb-page .wb-role,.wb-page .wb-name{
  text-wrap:pretty;
}
