/* ─────────────────────────────────────────────
   Tokens
   ───────────────────────────────────────────── */
:root{
  /* Both values are sampled straight from the logo file: the wordmark is
     #1A1A1A and the asterisk is #0B5ED7. Everything else is derived. */
  --ink:#1A1A1A;
  --ink-deep:#101010;
  --ink-soft:#2E2E2E;
  --blue:#0B5ED7;
  --blue-deep:#0A4CAC;
  /* The brand blue only reaches 3:1 against the near-black, so dark surfaces
     borrow a lifted tint for anything at text size. */
  --blue-lift:#6BA5F5;
  /* Same problem as the blue: a true red sinks into the near-black, so the
     dark surfaces take a lifted tint for error borders and error text. */
  --rose:#F2887A;
  /* A hair of warmth keeps the black-and-blue pairing off the cold, clinical
     end that a dead-neutral grey lands on. */
  --offwhite:#F6F5F3;
  --paper:#FFFFFF;
  --slate:#5E5C58;
  --hairline:rgba(26,26,26,.13);
  --hairline-dark:rgba(246,245,243,.16);

  --display:"Merriweather",Georgia,"Times New Roman",serif;
  --body:"Instrument Sans",system-ui,sans-serif;
  --mono:"IBM Plex Mono",ui-monospace,monospace;

  --gutter:clamp(20px,5vw,64px);
  --measure:1240px;
  --pad-section:clamp(68px,7.6vw,112px);
  --r:14px;
}

*,*::before,*::after{box-sizing:border-box}
figure,blockquote{margin:0}
html{-webkit-text-size-adjust:100%}
body{
  margin:0;
  background:var(--offwhite);
  color:var(--ink);
  font-family:var(--body);
  font-size:clamp(16px,1.02vw,17.5px);
  line-height:1.6;
  -webkit-font-smoothing:antialiased;
}
img{max-width:100%;display:block}
a{color:inherit}

.skip{
  position:absolute;left:-9999px;top:0;z-index:99;
  background:var(--blue);color:#fff;
  padding:12px 18px;font-family:var(--mono);font-size:13px;border-radius:0 0 8px 0;
}
.skip:focus{left:0}

/* Reaches a screen reader without taking space — used to say a link leaves the
   page, which the arrow glyph only conveys visually. */
.vh{
  position:absolute;width:1px;height:1px;padding:0;margin:-1px;
  overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0;
}

:focus-visible{outline:2px solid var(--blue);outline-offset:3px;border-radius:4px}
/* The brand blue disappears against the dark bands, so those surfaces take
   the lifted tint instead. */
.section--ink :focus-visible,.ledger :focus-visible,
.foot :focus-visible{outline-color:var(--blue-lift)}

.wrap{width:100%;max-width:var(--measure);margin-inline:auto;padding-inline:var(--gutter)}

/* ─────────────────────────────────────────────
   Type primitives
   ───────────────────────────────────────────── */
/* Every appearance of the mark below is drawn as a mask rather than an <img>.
   The file is flat #0B5ED7 on transparent, which would sit at 3:1 on the dark
   bands; masking lets background-color carry it, so each placement obeys the
   same tokens as the text beside it. */
.eyebrow{
  font-family:var(--body);font-weight:500;font-size:12.5px;letter-spacing:.13em;text-transform:uppercase;
  color:var(--slate);margin:0 0 20px;display:flex;align-items:center;gap:9px;
}
/* Was a 26px rule; the mark says the same thing and signs it. */
.eyebrow::before{
  content:"";width:11px;height:11px;flex:none;background:var(--blue);
  -webkit-mask:url(assets/zoomie-mark.png) center/contain no-repeat;
          mask:url(assets/zoomie-mark.png) center/contain no-repeat;
}
.eyebrow--dark{color:var(--blue-lift)}
.eyebrow--dark::before{background:var(--blue-lift)}

/* Merriweather carries a large x-height, so display sizes run smaller and
   leading runs tighter than they would on a narrower serif. */
.h1{
  font-family:var(--display);font-weight:700;
  font-size:clamp(30px,3.6vw,46px);line-height:1.16;letter-spacing:-.022em;
  margin:0 0 24px;text-wrap:balance;
}
.h2{
  font-family:var(--display);font-weight:700;
  font-size:clamp(25px,3vw,39px);line-height:1.2;letter-spacing:-.018em;
  margin:0 0 20px;text-wrap:balance;
}
.h3{
  font-family:var(--display);font-weight:700;
  font-size:clamp(17px,1.45vw,20px);line-height:1.36;letter-spacing:-.008em;margin:0 0 10px;
}
.lede{font-size:clamp(17px,1.25vw,20px);line-height:1.55;color:var(--slate);margin:0 0 32px;max-width:56ch}
.lede--dark{color:rgba(246,245,243,.74)}

.tint{color:var(--blue)}
/* Keeps a hyphenated compound off a line break, where "real-/time" reads as a
   typo rather than as a word. */
.nb{white-space:nowrap}

/* ─────────────────────────────────────────────
   Buttons
   ───────────────────────────────────────────── */
.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:10px;
  font-family:var(--body);font-weight:600;font-size:15.5px;
  padding:15px 26px;border-radius:999px;border:1px solid transparent;
  text-decoration:none;cursor:pointer;transition:transform .18s ease,background .18s ease,border-color .18s ease,color .18s ease;
  white-space:nowrap;
}
.btn:hover{transform:translateY(-2px)}
/* The primary action carries the logo blue exactly; hover settles deeper. */
.btn--primary{background:var(--blue);color:#fff}
.btn--primary:hover{background:var(--blue-deep)}
/* On the near-black sections the primary action inverts rather than losing
   its prominence. */
.section--ink .btn--primary{background:var(--offwhite);color:var(--ink)}
.section--ink .btn--primary:hover{background:#fff}
.btn--ghost-dark{border-color:var(--hairline-dark);color:var(--offwhite)}
.btn--ghost-dark:hover{border-color:var(--blue-lift);color:var(--blue-lift)}
.btn--ghost{border-color:var(--hairline);color:var(--ink)}
.btn--ghost:hover{border-color:var(--ink);}
.btn--ink{background:var(--ink);color:var(--offwhite)}
.btn--ink:hover{background:var(--ink-soft)}
.btn--sm{padding:11px 20px;font-size:14.5px}

/* ─────────────────────────────────────────────
   Nav
   ───────────────────────────────────────────── */
.nav{
  position:sticky;top:0;z-index:40;
  background:rgba(246,245,243,.88);backdrop-filter:blur(12px);
  border-bottom:1px solid var(--hairline);
}
.nav__inner{display:flex;align-items:center;gap:28px;height:72px}
.mark{display:inline-flex;align-items:center;text-decoration:none}
.mark img{height:25px;width:auto}
/* The nav lockup sets the asterisk beside the wordmark rather than above it, so
   the wordmark fills 95% of the file height instead of 65%. Left at 25px it
   would render half again as large as the footer's; 18px matches it optically. */
.nav .mark img{height:18px}
.nav__links{display:flex;gap:30px;margin-left:auto}
.nav__link{
  font-family:var(--body);font-size:15px;color:var(--slate);
  text-decoration:none;transition:color .18s ease;
}
.nav__link:hover{color:var(--ink)}
/* The light variant of the lockup, so the asterisk keeps its blue instead of
   being flattened to white by a filter. Sized to match the nav optically —
   its wordmark fills 93% of the file height, the nav's 95%. */
.foot .mark img{height:18px}
.nav__cta{margin-left:8px}

/* ─────────────────────────────────────────────
   Hero
   ───────────────────────────────────────────── */
.hero{
  background:var(--offwhite);color:var(--ink);
  padding-block:clamp(60px,7vw,102px) clamp(68px,7.6vw,112px);
  position:relative;overflow:hidden;
}
/* The headline sits in the left column so the card can start level with the
   eyebrow; running it full width left a hole beside it. */
.hero__grid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:clamp(36px,4.5vw,64px)}
.hero__grid > *{align-self:start}
.hero__cta{display:flex;flex-wrap:wrap;gap:14px;align-items:center}

/* ── The Experiences case, shown only on that tab ──
   Each line rises in turn so the list arrives with the card rather than
   appearing under it fully formed. */
.whys{list-style:none;margin:34px 0 0;padding:26px 0 0;border-top:1px solid var(--hairline);display:grid;gap:15px}
.whys[hidden]{display:none}
.whys li{
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:12px;align-items:start;
  font-size:15.5px;line-height:1.5;color:var(--ink);max-width:44ch;
}
.whys li::before{
  content:"";width:11px;height:11px;margin-top:.36em;background:var(--blue);
  -webkit-mask:url(assets/zoomie-mark.png) center/contain no-repeat;
          mask:url(assets/zoomie-mark.png) center/contain no-repeat;
}
.whys.is-in li{animation:whyIn .42s ease both}
.whys.is-in li:nth-child(2){animation-delay:.09s}
.whys.is-in li:nth-child(3){animation-delay:.18s}
@keyframes whyIn{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}

/* ── Signature: the guest desk card ── */
.desk{
  background:var(--paper);
  border:1px solid var(--hairline);
  border-radius:var(--r);
  overflow:hidden;
  /* On offwhite the border carries the edge, so the drop only lifts the card
     rather than drawing it. */
  box-shadow:0 24px 52px -36px rgba(26,26,26,.42);
}
/* One header slot, shared by both panes: the channel on the messaging side, the
   hotel's subdomain on the Experiences side. Same padding, same hairline, same
   height, so the two read as one frame across the tab switch. min-height holds
   it open before JS paints the channel in. */
.desk__head{
  display:flex;align-items:center;gap:11px;
  padding:15px 20px;border-bottom:1px solid var(--hairline);
  min-height:56px;
}
/* The frame stays neutral while the logo carries the platform colour, so the
   header doesn't turn green then pink then blue as the conversation rotates.
   JS sets --chan per message; the channel list sets the same hook per row. */
.desk__head svg{flex:none;color:var(--chan,var(--blue))}
.desk__head span{
  font-family:var(--body);font-weight:600;font-size:17px;letter-spacing:-.01em;
  color:var(--ink);min-width:0;
}
/* A domain is not a name — it reads as an address, so it takes the mono. */
.desk__head--url .livelink{
  display:inline-flex;align-items:center;gap:7px;min-width:0;
  font-family:var(--mono);font-weight:400;font-size:13px;letter-spacing:0;
  color:var(--slate);text-decoration:none;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  transition:color .18s ease;
}
.desk__head--url .livelink:hover{color:var(--blue-deep);text-decoration:underline;text-underline-offset:3px}
.desk__head--url svg{color:var(--blue)}
/* The arrow is the only thing saying "this leaves the page", so it holds its
   size when the address itself is truncated. */
.livelink svg{flex:none;opacity:.75}
.livelink:hover svg{opacity:1}

.desk__body{padding:clamp(22px,2.4vw,30px)}

/* ── The typed conversation ── */
.turn{position:relative}
.turn + .turn{margin-top:24px;padding-top:22px;border-top:1px solid var(--hairline)}
.turn__who{
  font-family:var(--mono);font-size:11px;letter-spacing:.12em;text-transform:uppercase;
  color:rgba(26,26,26,.42);margin:0 0 10px;
}
/* The mark signs the reply — it brands the one moment the product is seen
   working. The guest stays unmarked, so the two turns read as two parties. */
.turn__who--ai{color:var(--blue);display:flex;align-items:center;gap:6px}
.turn__who--ai::before{
  content:"";width:12px;height:12px;flex:none;background:var(--blue);
  -webkit-mask:url(assets/zoomie-mark.png) center/contain no-repeat;
          mask:url(assets/zoomie-mark.png) center/contain no-repeat;
}
.turn__txt{
  margin:0;font-size:17.5px;line-height:1.55;color:rgba(26,26,26,.82);
  /* Held open by JS at the tallest message in the active language, so the card
     never resizes mid-sentence and shoves the hero around. */
  min-height:var(--reserve,1.55em);
}
.turn__txt--q{font-weight:500;color:var(--ink)}
.turn__w{opacity:0;animation:wordIn .26s ease forwards}
@keyframes wordIn{from{opacity:0;transform:translateY(.14em)}to{opacity:1;transform:none}}

/* The cursor rides the end of whichever line is being written. */
.turn__txt.is-typing::after,.turn__txt.is-waiting::after{
  content:"";display:inline-block;vertical-align:-2px;
  width:2px;height:1.05em;margin-left:3px;
  background:var(--blue);animation:caret 1.05s steps(1) infinite;
}
@keyframes caret{0%,49%{opacity:1}50%,100%{opacity:0}}

/* The dots sit over the first line of the empty reply rather than above it, so
   the card doesn't lose their height the instant the answer starts. */
.turn__slot{position:relative}
.think{
  position:absolute;top:0;left:0;height:1.55em;margin:0;
  display:none;align-items:center;gap:5px;
}
.think.is-on{display:flex}
.think i{
  width:6px;height:6px;border-radius:50%;background:var(--blue);
  animation:think 1.15s ease-in-out infinite;
}
.think i:nth-child(2){animation-delay:.16s}
.think i:nth-child(3){animation-delay:.32s}
@keyframes think{0%,60%,100%{opacity:.3;transform:translateY(0)}30%{opacity:1;transform:translateY(-3px)}}

/* Sits under 17.5px conversation type now, so it drops its box and reads as a
   footnote rather than competing with the reply it annotates. */
.desk__act{
  display:inline-flex;align-items:center;gap:8px;margin-top:18px;
  font-family:var(--mono);font-size:12px;letter-spacing:.04em;
  color:var(--blue-deep);
  opacity:0;transition:opacity .3s ease;
}
.desk__act.is-in{opacity:1}
.desk__act svg{flex:none}

/* ── Two products, one frame ── */
/* fit-content + auto margins rather than inline-flex: the switcher belongs over
   the middle of the card, and justify-self did nothing here — the parent is a
   plain block, not a grid. */
.duo{
  display:flex;width:fit-content;gap:5px;padding:5px;margin:0 auto 15px;
  border:1px solid var(--hairline);border-radius:999px;background:var(--paper);
}
.duo__t{
  display:inline-flex;align-items:center;gap:8px;
  font-family:var(--body);font-weight:500;font-size:13.5px;line-height:1;
  padding:10px 16px;border-radius:999px;border:0;background:none;color:var(--slate);
  cursor:pointer;transition:background .18s ease,color .18s ease;
}
.duo__t:hover{color:var(--ink)}
.duo__t.is-on{background:var(--blue);color:#fff}
.duo__t svg{flex:none}

/* Only the active pane is in flow, so the card is as tall as what it is actually
   showing rather than as tall as the taller of the two. The trade is that the
   page below shifts on a tab switch — deliberate, so the conversation isn't
   padded out by the height of the phone mock beside it. */
.pane{display:none;flex-direction:column;min-width:0}
.pane.is-on{display:flex;animation:paneIn .26s ease both}
@keyframes paneIn{from{opacity:0}to{opacity:1}}
.pane .desk__body{flex:1}

/* ── The guest's phone: the whitelabel Experiences site ── */
.phone{
  width:100%;max-width:302px;margin-inline:auto;
  border:1px solid var(--hairline);border-radius:28px;padding:9px;background:var(--offwhite);
}
.phone__screen{background:var(--paper);border-radius:21px;padding:15px 13px 74px;position:relative;overflow:hidden}
/* Film fills the screen edge to edge — the recording carries the site's own
   padding, and a second inset would read as a border inside the bezel. */
.phone__screen--film{padding:0;line-height:0}
.film{display:block;width:100%;height:auto}
/* The screen is film now; the drawn mock that used to live here is gone. */

/* ─────────────────────────────────────────────
   Ledger strip
   ───────────────────────────────────────────── */
.ledger{background:var(--ink-deep);color:var(--offwhite)}
.ledger__grid{display:grid;grid-template-columns:repeat(4,1fr);border-left:1px solid var(--hairline-dark)}
.ledger__cell{padding:34px clamp(16px,2vw,30px);border-right:1px solid var(--hairline-dark);text-align:center}
/* The glyph sits on the figure's own line so it annotates the number rather
   than floating above the cell as decoration. Off-white rather than the lifted
   blue, which read dim against #101010 — held below pure offwhite so it
   emphasises without glaring, and the icon lifts with it via currentColor. */
.ledger__fig{
  font-family:var(--display);font-size:clamp(25px,2.6vw,34px);font-weight:700;letter-spacing:-.022em;
  color:rgba(246,245,243,.92);
  display:flex;align-items:center;justify-content:center;gap:11px;margin-bottom:10px;line-height:1.16;
}
.ledger__fig svg{flex:none}
.ledger__lab{font-size:14px;line-height:1.45;color:rgba(246,245,243,.62);margin:0}
/* Two figures per product, labelled, so neither half looks like the whole. */
.ledger__tag{
  display:block;margin-bottom:12px;
  font-family:var(--mono);font-size:10.5px;letter-spacing:.12em;text-transform:uppercase;
  color:rgba(246,245,243,.42);
}

/* ─────────────────────────────────────────────
   Product bands
   ───────────────────────────────────────────── */
.band{padding-block:clamp(46px,5vw,72px) 0}
/* The band already opens the block, so the section under it starts closer. */
.band + .section{padding-top:clamp(40px,4.2vw,62px)}
/* Centred, not baseline-aligned: these three run at 12px, 30px and 15.5px, so a
   shared baseline drops the label to the heading's foot and leaves the
   description's second line hanging below it. */
.band__in{display:flex;align-items:center;gap:clamp(16px,2.6vw,34px);flex-wrap:wrap}
.band__no{
  font-family:var(--mono);font-size:12px;letter-spacing:.14em;text-transform:uppercase;
  color:var(--blue);flex:none;
}
.band__n{font-family:var(--display);font-weight:900;font-size:clamp(22px,2.4vw,30px);letter-spacing:-.02em;flex:none}
.band__d{margin:0;font-size:15.5px;line-height:1.5;color:var(--slate);max-width:46ch}

/* ── Better together ── */
.together{background:var(--ink);color:var(--offwhite);padding-block:clamp(44px,4.6vw,64px)}

/* ── Watermark ──
   The two dark bands are where the page speaks as Zoomie rather than about a
   feature, so the mark bleeds off the edge behind the copy. Decorative only,
   so it lives on a pseudo-element and stays out of the accessibility tree. */
.together,.section--ink{position:relative;overflow:hidden}
.together::before,.section--ink::before{
  content:"";position:absolute;pointer-events:none;
  right:-90px;top:50%;transform:translateY(-50%);
  background:var(--offwhite);opacity:.05;
  -webkit-mask:url(assets/zoomie-mark.png) center/contain no-repeat;
          mask:url(assets/zoomie-mark.png) center/contain no-repeat;
}
/* Sized under each band's own height. Clipped top and bottom the asterisk stops
   reading as a mark and starts reading as stray diagonals, so it stays inside. */
.together::before{width:200px;height:200px}
.section--ink::before{width:420px;height:420px}
/* Scoped to these two sections: .wrap is used on every section on the page. */
.together > .wrap,.section--ink > .wrap{position:relative;z-index:1}
.together__in{display:grid;grid-template-columns:minmax(0,.9fr) minmax(0,1.1fr);gap:clamp(24px,4vw,60px);align-items:center}
.together__h{font-family:var(--display);font-weight:700;font-size:clamp(21px,2.1vw,27px);letter-spacing:-.02em;margin:0}
.together__p{margin:0;color:rgba(246,245,243,.74);font-size:15.5px;line-height:1.6}
.together__p b{color:var(--blue-lift);font-weight:500}

/* ── Two tracks, one per product ── */
.tracks{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--hairline);border:1px solid var(--hairline);border-radius:var(--r);overflow:hidden}
.track{background:var(--paper);padding:clamp(24px,2.4vw,34px)}
.track__h{display:flex;align-items:center;gap:10px;margin-bottom:24px;color:var(--blue)}
.track__n{font-family:var(--display);font-weight:700;font-size:18px;letter-spacing:-.018em;margin:0;color:var(--ink)}
.track__l{list-style:none;margin:0;padding:0;display:grid;gap:20px}
.track__l li{display:grid;grid-template-columns:auto 1fr;gap:14px;align-items:start}
.track__no{
  font-family:var(--mono);font-size:11px;letter-spacing:.08em;color:var(--blue);
  border:1px solid var(--hairline);border-radius:6px;padding:4px 7px;line-height:1;margin-top:2px;
}
.track__t{font-weight:600;font-size:15px;margin:0 0 5px;line-height:1.35}
.track__p{margin:0;font-size:14.5px;line-height:1.55;color:var(--slate)}

/* ─────────────────────────────────────────────
   Sections
   ───────────────────────────────────────────── */
.section{padding-block:var(--pad-section)}
/* Where two sections share a surface there is no colour change to mark the
   seam, so at full padding the pair stacks into one long void — ~218px at
   1440px. Both sides give up padding at the join: the first closes early, the
   second opens tight, landing at roughly 86px. */
.section--seam-end{padding-bottom:clamp(34px,3.6vw,52px)}
.section--seam{padding-top:clamp(24px,2.4vw,36px)}
.section--paper{background:var(--paper)}
.section--ink{background:var(--ink);color:var(--offwhite)}
.section__head{max-width:60ch;margin-bottom:clamp(40px,4.5vw,64px)}
.section__head--center{margin-inline:auto;text-align:center}
.section__head--center .eyebrow{justify-content:center}
.section__head--center .lede{margin-inline:auto}

.split{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.1fr);gap:clamp(36px,5vw,80px);align-items:center}
.split--flip .split__media{order:-1}
/* Centring drops the media ~60px below its own heading wherever the copy runs
   taller. Only the availability section has that imbalance. */
.split--top{align-items:start}
/* The column is centred against its neighbour, so a trailing margin on the last
   paragraph would push the whole block up off true. */
.split__copy > :last-child{margin-bottom:0}

/* ─────────────────────────────────────────────
   Channels
   ───────────────────────────────────────────── */
/* A list rather than a four-card grid: these are four names and a line each,
   which never needed a panel. Hairlines carry the separation. */
.chanlist{list-style:none;margin:0;padding:0;border-top:1px solid var(--hairline)}
.chanrow{
  display:grid;grid-template-columns:auto minmax(0,1fr);gap:16px;align-items:start;
  padding:20px 0;border-bottom:1px solid var(--hairline);
}
/* Each row carries its own platform colour through --chan, the same hook the
   hero header uses, so the two places can't drift apart. */
.chanrow__ico{color:var(--chan,var(--blue));display:flex;margin-top:1px}
.chanrow__n{font-family:var(--display);font-weight:700;font-size:16.5px;letter-spacing:-.015em;margin:0 0 5px}
.chanrow__p{margin:0;font-size:14.5px;line-height:1.5;color:var(--slate)}

/* ── Integration strip ── */
.integs{display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-top:clamp(36px,4vw,56px)}
/* Full measure now, so each box has room to run the logo beside the copy
   rather than stacked above it. */
.integ{
  padding:20px 24px;border-radius:var(--r);
  display:flex;align-items:center;gap:22px;
  /* Solid means live, dashed means not yet — so the two states aren't read as
     two equal claims. */
  border:1px solid var(--hairline);
}
.integ--soon{border-style:dashed}
/* Cloudbeds ships a vertical lockup — mark over wordmark — so it cannot go
   small without the wordmark giving out. */
.integ__logo{height:48px;width:auto;flex:none}
.integ__ico{height:48px;display:flex;align-items:center;color:var(--blue);flex:none}
.integ__txt{font-family:var(--body);font-size:14.5px;line-height:1.5;color:var(--slate);margin:0}
.integ__txt b{display:block;font-weight:600;color:var(--ink);margin-bottom:2px}

/* ─────────────────────────────────────────────
   Steps (a real sequence — numbering earns its place)
   ───────────────────────────────────────────── */
.steps{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--hairline);border-block:1px solid var(--hairline)}
.step{background:var(--offwhite);padding:34px clamp(18px,2vw,30px)}
.step__no{font-family:var(--mono);font-size:12px;letter-spacing:.14em;color:var(--blue);display:block;margin-bottom:16px}
.step__t{font-family:var(--display);font-weight:700;font-size:17.5px;line-height:1.36;margin:0 0 10px;letter-spacing:-.015em}
.step__p{margin:0;font-size:14.5px;line-height:1.55;color:var(--slate)}

/* ─────────────────────────────────────────────
   Mock UI
   ───────────────────────────────────────────── */
.mock{
  background:var(--paper);border:1px solid var(--hairline);border-radius:var(--r);
  overflow:hidden;box-shadow:0 30px 60px -40px rgba(26,26,26,.38);
}
.mock--onpaper{background:var(--offwhite)}
.mock__bar{
  display:flex;align-items:center;gap:9px;padding:12px 16px;border-bottom:1px solid var(--hairline);
  font-family:var(--mono);font-size:11.5px;color:var(--slate);
}
/* Also a live link, so the fake browser chrome behaves like a real one. */
.mock__url{
  flex:1;background:var(--offwhite);border-radius:6px;padding:5px 11px;
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  display:inline-flex;align-items:center;gap:7px;min-width:0;
  color:var(--slate);text-decoration:none;transition:color .18s ease;
}
.mock__url:hover{color:var(--blue-deep)}
.mock--onpaper .mock__url{background:var(--paper)}
.mock__dots{display:flex;gap:5px}
.mock__dots i{width:8px;height:8px;border-radius:50%;background:var(--hairline)}
.mock__body{padding:clamp(18px,2vw,26px)}
/* A screenshot brings its own margins, so it runs edge to edge under the bar. */
.mock__body--shot{padding:0;line-height:0}
.shot{width:100%;height:auto}

/* availability */
.avail__q{
  font-size:15px;line-height:1.5;padding:13px 16px;border-radius:12px 12px 12px 3px;
  background:var(--offwhite);margin:0 0 8px;max-width:82%;
}
.mock--onpaper .avail__q{background:var(--paper)}
.avail__meta{font-family:var(--mono);font-size:11px;letter-spacing:.08em;text-transform:uppercase;color:var(--slate);margin:0 0 20px}
/* The reply mirrors the guest bubble — tail on the other corner, pushed right,
   carrying the brand tint — so the pair reads as one thread. */
.avail__a{
  font-size:15px;line-height:1.5;padding:13px 16px;border-radius:12px 12px 3px 12px;
  background:rgba(11,94,215,.08);color:var(--ink);
  margin:20px 0 8px;max-width:88%;margin-left:auto;
}
.avail__meta--ai{text-align:right;margin:0}
.avail__rows{display:grid;gap:1px;background:var(--hairline);border:1px solid var(--hairline);border-radius:10px;overflow:hidden;margin-bottom:16px}
.avail__row{display:flex;align-items:center;gap:14px;background:var(--paper);padding:13px 16px}
.mock--onpaper .avail__row{background:var(--offwhite)}
.avail__room{font-weight:600;font-size:14.5px}
.avail__left{font-family:var(--mono);font-size:11.5px;color:var(--slate);margin-left:auto}
.avail__rate{font-family:var(--mono);font-size:14px;color:var(--ink);min-width:64px;text-align:right}
.avail__row--out .avail__room,.avail__row--out .avail__rate{color:#9A9895;text-decoration:line-through}
.avail__src{display:flex;align-items:center;gap:8px;font-family:var(--mono);font-size:11px;letter-spacing:.06em;text-transform:uppercase;color:var(--blue)}

/* The drawn activity grid and its brand bar are gone: both Experiences surfaces
   now carry real captures of the running site. */

/* dashboard table */
.tbl{width:100%;border-collapse:collapse;font-size:14px}
.tbl__h{font-family:var(--mono);font-size:10.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--slate);text-align:left;font-weight:400;padding:0 12px 12px;border-bottom:1px solid var(--hairline)}
.tbl__c{padding:13px 12px;border-bottom:1px solid var(--hairline)}
.tbl__c--n{font-weight:600}
.tbl__c--m{font-family:var(--mono);font-size:13px;color:var(--slate)}
.pill{display:inline-flex;align-items:center;gap:6px;font-family:var(--mono);font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;padding:4px 9px;border-radius:5px}
.pill--on{background:rgba(11,94,215,.11);color:var(--blue-deep)}
.pill--off{background:rgba(26,26,26,.07);color:var(--slate)}

.checks{list-style:none;margin:0;padding:0;display:grid;gap:13px}
.checks li{display:flex;gap:12px;align-items:flex-start;font-size:15.5px;line-height:1.5}
.checks svg{flex:none;margin-top:4px;color:var(--blue)}

/* ─────────────────────────────────────────────
   Testimonials
   ───────────────────────────────────────────── */
.quotes{display:grid;grid-template-columns:repeat(3,1fr);gap:20px}
.quote{background:var(--offwhite);border:1px solid var(--hairline);border-radius:var(--r);padding:30px 28px;display:flex;flex-direction:column}
.quote__t{font-family:var(--display);font-weight:400;font-size:16.5px;line-height:1.62;letter-spacing:-.004em;margin:0 0 22px}
.quote__by{margin-top:auto;display:flex;flex-direction:column;gap:3px}
.quote__nm{font-weight:600;font-size:14.5px}
.quote__ro{font-family:var(--body);font-size:13.5px;color:var(--slate)}

/* ─────────────────────────────────────────────
   Pricing
   ───────────────────────────────────────────── */
.plans{display:grid;grid-template-columns:repeat(3,1fr);gap:20px;align-items:stretch}
.plan{
  background:var(--paper);border:1px solid var(--hairline);border-radius:var(--r);
  padding:32px 28px;display:flex;flex-direction:column;
}
.plan--pick{border-color:var(--blue);box-shadow:0 0 0 1px var(--blue)}
.plan__tag{font-family:var(--body);font-weight:500;font-size:12px;letter-spacing:.11em;text-transform:uppercase;color:var(--blue);margin-bottom:14px;height:16px}
.plan__n{font-family:var(--display);font-weight:700;font-size:21px;letter-spacing:-.02em;margin:0 0 10px}
.plan__d{font-size:14.5px;line-height:1.5;color:var(--slate);margin:0 0 22px;min-height:4.5em}
/* Stacked, not a baseline row. The row worked while every amount was a short
   number ("$149") with a short qualifier beside it. Word amounts wrap against
   the qualifier and leave the three cards' hairlines at different heights,
   which throws the feature lists out of alignment. Stacking gives every card
   the same two lines whatever the amount says. */
.plan__p{display:flex;flex-direction:column;align-items:flex-start;gap:3px;margin-bottom:26px;padding-bottom:24px;border-bottom:1px solid var(--hairline)}
.plan__amt{font-family:var(--display);font-weight:700;font-size:32px;letter-spacing:-.028em}
.plan__per{font-family:var(--body);font-size:13.5px;color:var(--slate)}
.plan__f{list-style:none;margin:0 0 28px;padding:0;display:grid;gap:11px}
.plan__f li{display:flex;gap:10px;font-size:14.5px;line-height:1.45}
.plan__f svg{flex:none;margin-top:4px;color:var(--blue)}
.plan .btn{width:100%;margin-top:auto}

/* ─────────────────────────────────────────────
   FAQ
   ───────────────────────────────────────────── */
.faq{max-width:840px;margin-inline:auto;border-top:1px solid var(--hairline)}
.qa{border-bottom:1px solid var(--hairline)}
.qa__q{
  cursor:pointer;list-style:none;padding:24px 44px 24px 0;position:relative;
  font-family:var(--display);font-weight:700;font-size:clamp(15.5px,1.25vw,18px);letter-spacing:-.015em;
}
.qa__q::-webkit-details-marker{display:none}
.qa__q::after{
  content:"";position:absolute;right:6px;top:50%;width:11px;height:11px;
  border-right:1.5px solid var(--blue);border-bottom:1.5px solid var(--blue);
  transform:translateY(-70%) rotate(45deg);transition:transform .22s ease;
}
.qa[open] .qa__q::after{transform:translateY(-25%) rotate(-135deg)}
.qa__a{margin:0 0 26px;max-width:70ch;color:var(--slate);font-size:15.5px;line-height:1.6}

/* ─────────────────────────────────────────────
   Close + footer
   ───────────────────────────────────────────── */
.close{text-align:center;max-width:720px;margin-inline:auto}
.close .lede{margin-inline:auto}
.close__cta{display:flex;gap:14px;justify-content:center;flex-wrap:wrap}

.foot{background:var(--ink-deep);color:rgba(246,245,243,.6);padding-block:56px 40px;border-top:1px solid var(--hairline-dark)}
.foot__grid{display:grid;grid-template-columns:1.4fr repeat(3,1fr);gap:36px;padding-bottom:36px;border-bottom:1px solid var(--hairline-dark)}
.foot__blurb{font-size:14.5px;line-height:1.55;max-width:32ch;margin:16px 0 0}
.foot__h{font-family:var(--body);font-weight:500;font-size:12px;letter-spacing:.11em;text-transform:uppercase;color:var(--blue-lift);margin:0 0 16px}
.foot__l{list-style:none;margin:0;padding:0;display:grid;gap:10px;font-size:14.5px}
.foot__l a{text-decoration:none;transition:color .18s ease}
.foot__l a:hover{color:var(--blue-lift)}
.foot__base{display:flex;justify-content:space-between;gap:16px;flex-wrap:wrap;padding-top:26px;font-family:var(--body);font-size:13.5px}

/* ─────────────────────────────────────────────
   Reveal
   ───────────────────────────────────────────── */
.rv{opacity:0;transform:translateY(18px);transition:opacity .7s ease,transform .7s cubic-bezier(.2,.7,.3,1)}
.rv.is-in{opacity:1;transform:none}

/* ─────────────────────────────────────────────
   Responsive
   ───────────────────────────────────────────── */
/* ── Demo form ────────────────────────────────────────────────────────────
   The design shipped no form styling at all; this is the whole of it. Controls
   are selected by element inside .form rather than by a class, because the
   template renders Django's widgets bare -- that keeps class strings out of
   forms.py, where nobody would think to look for styling.

   Placed here, before the media queries, for two reasons of source order:
   the :focus-visible rule near the top of this file also sets a 4px radius at
   equal specificity, so these rules must come after it to keep their own; and
   the reduced-motion block below must come after these to neutralise the
   transition.
   ───────────────────────────────────────────────────────────────────────── */

/* .close centres its children, which would otherwise centre every label. */
.form{text-align:left;display:grid;gap:18px;max-width:520px;margin:34px auto 0}
.form__row{display:grid;grid-template-columns:1fr 1fr;gap:18px}
/* align-content:start matters in the two-up row: without it the grid stretches
   both columns to equal height, so an error message under one field silently
   grows the input beside it. */
.form__field{display:grid;gap:7px;align-content:start}
.form__label{font-family:var(--body);font-size:14px;font-weight:500;color:var(--offwhite)}
/* Marking the one optional field beats asterisking the three required ones,
   which is noise plus a legend nobody reads. */
.form__opt{color:rgba(246,245,243,.55);font-weight:400}

.form input[type=text],
.form input[type=email],
.form textarea{
  /* 16px hard, deliberately not a clamp() like every other size on this page:
     iOS Safari zooms the viewport when focusing an input under 16px and never
     zooms back out. Please do not harmonise this with the fluid scale. */
  font-size:16px;
  /* Browsers default form controls to the system UI font, which would quietly
     drop Instrument Sans on the one part of the page people type into. */
  font-family:var(--body);
  width:100%;
  color:var(--offwhite);
  background:rgba(246,245,243,.06);
  border:1px solid var(--hairline-dark);
  /* --r (14px) reads as a card and 999px reads as a button; an input is neither. */
  border-radius:10px;
  padding:12px 14px;
  transition:border-color .18s ease;
}
.form textarea{resize:vertical;min-height:104px;line-height:1.5}
.form ::placeholder{color:rgba(246,245,243,.45)}
.form input[type=text]:hover,
.form input[type=email]:hover,
.form textarea:hover{border-color:rgba(246,245,243,.28)}

/* No focus rule here on purpose: the global :focus-visible plus the
   .section--ink override already give these the lifted blue. */

/* Chrome paints autofilled fields with its own near-white background, which
   looks broken on ink. An inset shadow is the only thing that overrides it. */
.form input:-webkit-autofill,
.form input:-webkit-autofill:hover,
.form input:-webkit-autofill:focus{
  -webkit-text-fill-color:var(--offwhite);
  box-shadow:0 0 0 1000px #232323 inset;
}

.form__field--err input,
.form__field--err textarea{border-color:var(--rose)}
.form__err{font-family:var(--body);font-size:13.5px;color:var(--rose);margin:0}
.form__alert{
  font-family:var(--body);font-size:14px;color:var(--rose);margin:0;
  border:1px solid var(--rose);border-radius:10px;padding:11px 14px;
}

/* The honeypot. Off-screen rather than display:none -- the bots that skip
   hidden inputs skip display:none too, and a headless browser resolves it
   instantly. This keeps the field in the render tree and out of everyone's way. */
.form__trap{position:absolute;left:-10000px;width:1px;height:1px;overflow:hidden}

.form__actions{margin-top:4px}

@media (max-width:1040px){
  .hero__grid{grid-template-columns:1fr;gap:44px}
  .split,.split--flip .split__media{grid-template-columns:1fr;order:0}
  .ledger__grid{grid-template-columns:repeat(2,1fr)}
  .ledger__cell{border-bottom:1px solid var(--hairline-dark)}
  .steps{grid-template-columns:repeat(2,1fr)}
  .quotes,.plans,.tracks,.together__in{grid-template-columns:1fr}
  /* Off-centre once the copy stacks, so it stops sitting behind the heading. */
  .together::before,.section--ink::before{width:300px;height:300px;right:-130px;top:auto;bottom:-90px;transform:none}
  .band__in{gap:8px clamp(16px,2.6vw,34px)}
  .band__d{flex-basis:100%}
  .foot__grid{grid-template-columns:1fr 1fr}
  .nav__links{display:none}
}
@media (max-width:640px){
  .form__row{grid-template-columns:1fr}
  .ledger__grid,.steps{grid-template-columns:1fr}
  .nav__inner{height:64px}
  .nav__cta{margin-left:auto}
  .desk__body{padding:20px}
  /* The two tabs split the width rather than wrapping onto a second line. */
  .duo{display:grid;grid-template-columns:1fr 1fr;width:100%}
  .duo__t{justify-content:center;padding:10px 8px;font-size:13px}
  .desk__head{padding:13px 16px;min-height:52px;gap:9px}
  .desk__head span{font-size:15.5px}
  /* The long subdomain truncates rather than pushing the frame wide. */
  .desk__head--url span{font-size:11.5px}
  .turn__txt{font-size:16.5px}
  .integs{grid-template-columns:1fr}
  /* Too narrow to run side by side — the logo goes back above the copy. */
  .integ{flex-direction:column;align-items:flex-start;gap:12px;padding:16px 18px}
  .foot__grid{grid-template-columns:1fr}
  .btn{padding:14px 22px}
}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
  .rv{opacity:1;transform:none}
}
html{scroll-behavior:smooth}
/* The nav is sticky, so anchor targets stop below it rather than under it. */
section[id]{scroll-margin-top:86px}
