/* =====================================================================
   Devexana · The Model Room
   1  faces          2  tokens         3  reset + base     4  type scale
   5  plate system   6  layout         7  chrome           8  CTA garments
   9  index sections 10 editorial     11  motion          12  breakpoints
   13 reduced motion 14 visually hidden
   Colour rule: six hex literals live in :root and nowhere else. Every other
   value is derived with color-mix().
   ===================================================================== */


/* --- 1. faces -------------------------------------------------------- */

@font-face {
  font-family: DM Sans;
  src: url('assets/fonts/dm-sans-latin.woff2') format('woff2');
  font-style: normal;
  font-weight: 100 1000;
  font-display: swap;
}


/* --- 2. tokens ------------------------------------------------------- */

:root {
  color-scheme: dark;
  --void: #08080B;
  --slab: #101218;
  --ink: #F6F5F8;
  --ash: #9C9BA8;
  --rule: #23242C;
  --accent: #CDB6FF;
  --display: 'DM Sans', system-ui, sans-serif;
  --sans: 'DM Sans', system-ui, sans-serif;
  --max: 1240px;
  --gutter: clamp(24px, 5vw, 80px);
  /* The inline padding every full-width band shares. Named so a plate can be
     anchored against the same measure the reading columns are built from. */
  --pad: max(var(--gutter), calc((100% - var(--max)) / 2 + var(--gutter)));
  --band: clamp(88px, 12vw, 180px);
  --easing: cubic-bezier(.22, .61, .36, 1);
}


/* --- 3. reset + base ------------------------------------------------- */

* {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  scroll-padding-top: 96px;
}

body {
  margin: 0;
  background: var(--void);
  color: var(--ink);
  font-family: var(--sans);
  font-size: 16px;
  line-height: 1.65;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body:has(dialog[open]) {
  overflow: hidden;
}

button,
input,
textarea,
select {
  font: inherit;
  color: inherit;
}

button {
  cursor: pointer;
  background: none;
  border: 0;
  padding: 0;
}

a {
  color: inherit;
  text-decoration: none;
}

a,
button,
summary {
  touch-action: manipulation;
  -webkit-tap-highlight-color: transparent;
}

button:disabled {
  cursor: not-allowed;
}

img {
  max-width: 100%;
  display: block;
}

svg {
  display: block;
}

:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 2px;
  border-radius: 1px;
}

::selection {
  background: color-mix(in srgb, var(--accent) 34%, transparent);
  color: var(--ink);
}

.skip-link {
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 60;
  transform: translateY(-260%);
  padding: 12px 18px;
  min-height: 44px;
  display: inline-flex;
  align-items: center;
  background: var(--slab);
  border: 1px solid var(--rule);
  color: var(--ink);
}

.skip-link:focus,
.skip-link:focus-visible {
  transform: translateY(0);
}


/* --- 4. type scale ---------------------------------------------------- */

h1,
h2,
h3 {
  font-family: var(--display);
  margin: 0;
}

/* balance only the headlines that carry no explicit line break */
.start > h2,
.closing h2,
.editorial-content h2 {
  text-wrap: balance;
}

h1 {
  font-size: clamp(2.75rem, 9.2vw, 8.4rem);
  font-weight: 600;
  letter-spacing: -.045em;
  line-height: .92;
}

h2 {
  font-size: clamp(2.5rem, 6vw, 5.5rem);
  font-weight: 600;
  letter-spacing: -.038em;
  line-height: .96;
}

h3 {
  font-size: clamp(1.25rem, 1.6vw, 1.5rem);
  font-weight: 600;
  letter-spacing: -.02em;
  line-height: 1.25;
}

p {
  margin: 0;
  font-size: clamp(1rem, 1.05vw, 1.125rem);
  line-height: 1.65;
  max-width: 62ch;
  color: var(--ash);
}

.section-kicker {
  font-size: .75rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  font-weight: 500;
  color: var(--accent);
  max-width: none;
}

.lead {
  font-size: clamp(1.125rem, 1.6vw, 1.375rem);
  color: var(--ink);
}

.fine-print {
  font-size: .8125rem;
  line-height: 1.6;
  color: color-mix(in srgb, var(--ash) 80%, var(--void));
}

strong,
b {
  font-weight: 600;
  color: var(--ink);
}


/* --- 5. plate system -------------------------------------------------- */
/* One real object per section, photographed on black, at full opacity.
   Never a scrim, a filter, a blend mode, or a pseudo-element overlay. */

/* Sections are full-bleed and centre their content with padding, so a host's
   clip box IS the viewport: a plate can run off the screen edge, and can never
   escape downward into the next section. */
.plate-host {
  position: relative;
  overflow: clip;
  isolation: isolate;
}

.plate-host > *:not(.plate) {
  position: relative;
  z-index: 1;
}

.plate {
  position: absolute;
  z-index: 0;
  pointer-events: none;
  line-height: 0;
}

.plate img,
.plate video {
  width: 100%;
  height: auto;
  opacity: 1;
}

/* The hero plate is a loop of the same object the still shows. The video file
   is an opaque black-ground rectangle rather than an alpha cutout, so its own
   edges are feathered with a radial mask on the VIDEO element only. That mask
   is the single sanctioned exception to the no-scrim rule: it dissolves the
   file's rectangle into the void ground, it never sits over the object, and it
   is never applied to a `.plate img`. Until the file is playing, the still
   plate stands in, so the section is correct with no video, no JavaScript, and
   under reduced motion. */
.plate--video video {
  mask-image: radial-gradient(ellipse 54% 58% at 50% 52%, var(--ink) 60%, transparent 100%);
  -webkit-mask-image: radial-gradient(ellipse 54% 58% at 50% 52%, var(--ink) 60%, transparent 100%);
}

.plate--video:not([data-video-ready]) video {
  display: none;
}

.plate--video[data-video-ready] .plate-fallback {
  display: none;
}

.plate--right {
  right: -4vw;
  bottom: -6vw;
  width: min(70vw, 1180px);
}

/* One box, two states. The plate holds a 16:9 rectangle whether the loop is
   playing or the still is standing in, so the copy above it clears the same
   edge either way and nothing shifts when the video arrives. */
.hero .plate--video {
  right: -3vw;
  bottom: -4vw;
  width: min(56vw, 940px);
  aspect-ratio: 16 / 9;
}

.plate--video video,
.plate--video .plate-fallback {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

.plate--video video {
  object-fit: cover;
}

.plate--video .plate-fallback {
  object-fit: contain;
  object-position: 50% 100%;
}

.plate--left {
  left: -12vw;
  top: 10%;
  width: min(26vw, 520px);
}

.plate--top-right {
  right: -2.5vw;
  top: -7vw;
  width: min(36vw, 520px);
}

/* The town at night holds the bottom-left corner of the closing band. Its
   alpha runs off the left edge (70% of that edge is object) and off the
   bottom (16%), so those are the two edges it is allowed to lose; the cupola
   sits near the top of the frame and always stays inside the band. The band's
   own bottom padding is sized to keep the headline and its button clear of the
   plate's top edge at every width. */
.plate--bottom-left {
  left: -6vw;
  bottom: -9vw;
  width: min(56vw, 1000px);
}


/* --- 6. layout primitives --------------------------------------------- */

/* One inline-padding rule for every full-width band. The content column stays
   var(--max) wide and centred; the band itself reaches both screen edges. */
.section-shell,
main > section,
.site-header,
.site-footer {
  width: 100%;
  padding-inline: var(--pad);
}

main > section {
  padding-block: var(--band);
}

.stack-sm > * + * {
  margin-top: 18px;
}

hr {
  border: 0;
  border-top: 1px solid var(--rule);
  margin: 0;
}


/* --- 7. chrome: header, footer, dialog, noscript ---------------------- */

.site-header {
  position: sticky;
  top: 0;
  z-index: 40;
  height: 76px;
  display: flex;
  align-items: center;
  gap: 24px;
  background: color-mix(in srgb, var(--void) 78%, transparent);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--rule);
  transition: height .25s var(--easing);
}

/* Past the first scroll the bar gives its height back to the page. */
.site-header[data-scrolled] {
  height: 64px;
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
}

.brand img {
  width: 34px;
  height: 34px;
}

.brand span {
  font-family: var(--display);
  font-weight: 600;
  font-size: 1.0625rem;
  letter-spacing: -.03em;
}

.site-header nav {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: clamp(14px, 2vw, 30px);
}

.site-header nav > a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  min-width: 44px;
  font-size: .9375rem;
  color: var(--ash);
  border-bottom: 1px solid transparent;
}

.site-header nav > a:hover {
  color: var(--ink);
}

.site-header nav > a[aria-current=page] {
  color: var(--ink);
  border-bottom-color: var(--accent);
}

.menu-toggle {
  display: none;
  margin-left: auto;
  min-height: 44px;
  padding-inline: 6px;
  font-size: .875rem;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--ash);
}

.site-footer {
  padding-block: clamp(48px, 6vw, 88px);
  border-top: 1px solid var(--rule);
}

.footer-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 20px 40px;
}

.footer-top > p {
  margin: 0;
  color: var(--ash);
  font-size: .9375rem;
}

.footer-top > a:last-child {
  margin-left: auto;
}

.footer-bottom {
  margin-top: 36px;
  padding-top: 22px;
  border-top: 1px solid var(--rule);
  display: flex;
  flex-wrap: wrap;
  gap: 14px 30px;
  align-items: center;
  font-size: .8125rem;
  color: color-mix(in srgb, var(--ash) 82%, var(--void));
}

.footer-bottom nav {
  margin-left: auto;
  display: flex;
  gap: 26px;
  align-items: center;
}

.footer-bottom nav a,
.footer-button {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  font-size: .8125rem;
  color: color-mix(in srgb, var(--ash) 82%, var(--void));
  border-bottom: 1px solid transparent;
}

.footer-bottom nav a:hover,
.footer-button:hover {
  color: var(--ink);
  border-bottom-color: var(--rule);
}

.noscript-note {
  margin: 0 auto;
  padding-block: 20px 60px;
  padding-inline: max(var(--gutter), calc((100% - var(--max)) / 2 + var(--gutter)));
  color: var(--ash);
  font-size: .9375rem;
}

.noscript-note a {
  border-bottom: 1px solid var(--accent);
}

dialog {
  width: min(640px, calc(100vw - 32px));
  max-height: min(86vh, 780px);
  padding: clamp(26px, 4vw, 44px);
  border: 1px solid var(--rule);
  background: var(--slab);
  color: var(--ink);
  overflow: auto;
}

dialog::backdrop {
  background: color-mix(in srgb, var(--void) 80%, transparent);
}

.dialog-head {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-bottom: 26px;
}

.dialog-head > span {
  font-size: .75rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
}

.icon-button {
  margin-left: auto;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1.375rem;
  line-height: 1;
  border: 1px solid var(--rule);
  color: var(--ash);
}

.icon-button:hover {
  color: var(--ink);
  border-color: color-mix(in srgb, var(--accent) 55%, var(--rule));
}

dialog h2 {
  font-size: clamp(1.75rem, 3.4vw, 2.5rem);
  margin-bottom: 18px;
}

dialog p {
  margin-bottom: 16px;
}

dialog ul {
  margin: 0 0 22px;
  padding-left: 20px;
  color: var(--ash);
  font-size: .9375rem;
}

dialog ul li + li {
  margin-top: 8px;
}

dialog .actions {
  margin-bottom: 20px;
}

.actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 16px 26px;
}


/* --- 8. CTA garments --------------------------------------------------- */
/* Four intents, four labels, four garments. No shared pill, no accent fill. */

/* Book a walkthrough: a drawn rectangle. */
.cta-book,
.button {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 0 26px;
  border: 1px solid var(--rule);
  background: none;
  color: var(--ink);
  font-size: .9375rem;
  font-weight: 500;
  letter-spacing: -.005em;
  transition: border-color .2s var(--easing), color .2s var(--easing);
}

.cta-book:hover,
.button:hover {
  border-color: var(--accent);
  color: var(--ink);
}

.cta-book:active,
.button:active {
  transform: translateY(1px);
}

.cta-book--small,
.button-small {
  min-height: 44px;
  padding: 0 18px;
  font-size: .875rem;
}

/* Open the demo: display-scale, underlined, the arrow steps out on hover. */
.cta-demo {
  display: inline-flex;
  align-items: baseline;
  gap: 14px;
  min-height: 44px;
  font-family: var(--display);
  font-size: clamp(1.375rem, 2.4vw, 2rem);
  font-weight: 500;
  letter-spacing: -.03em;
  color: var(--ink);
  border-bottom: 1px solid var(--accent);
  padding-bottom: 4px;
}

.cta-demo .cta-arrow {
  display: inline-block;
  color: var(--accent);
  transition: transform .24s var(--easing);
}

.cta-demo:hover .cta-arrow {
  transform: translate(4px, -4px);
}

.hero-actions .cta-demo:hover .cta-arrow {
  transform: translateY(4px);
}

/* Try it right here: the same garment worn by a button, sitting on the still
   it is about to replace, so it needs a ground of its own. */
.cta-demo--button {
  align-items: center;
  padding: 10px 24px 10px 26px;
  border: 1px solid var(--rule);
  border-bottom: 1px solid var(--accent);
  background: var(--slab);
  font-size: clamp(1.125rem, 1.8vw, 1.5rem);
  transition: border-color .2s var(--easing);
}

.cta-demo--button:hover {
  border-color: var(--accent);
}

.cta-demo--button:active {
  transform: translateY(1px);
}

/* Read the security architecture: an inline link whose rule draws in. */
.cta-security,
.cta-open,
.inline-link {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  position: relative;
  font-size: .9375rem;
  font-weight: 500;
  color: var(--ink);
}

.cta-security::before,
.cta-open::before,
.inline-link::before {
  content: '';
  position: absolute;
  left: 0;
  bottom: 10px;
  width: 100%;
  height: 1px;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .3s var(--easing);
}

.cta-security:hover::before,
.cta-security:focus-visible::before,
.cta-open:hover::before,
.cta-open:focus-visible::before,
.inline-link:hover::before,
.inline-link:focus-visible::before {
  transform: scaleX(1);
}

/* Email Amadeo: a plain underline, nothing more. */
.cta-email {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  font-size: .9375rem;
  color: var(--ash);
  border-bottom: 1px solid var(--rule);
}

.cta-email:hover {
  color: var(--ink);
  border-bottom-color: var(--accent);
}


/* --- 9. index sections ------------------------------------------------- */

/* 9.1 hero */
/* The bottom band is the plate's room: it is sized so the loop's top edge
   lands just under the last line of copy at every width. */
.hero {
  padding-block: clamp(72px, 10vw, 150px) clamp(250px, 32vw, 470px);
}

.hero-copy {
  max-width: none;
}

.hero-sub {
  margin-top: clamp(24px, 3vw, 40px);
  max-width: min(56vw, 46ch);
  font-size: clamp(1.0625rem, 1.4vw, 1.3125rem);
  color: var(--ash);
}

.hero-actions {
  margin-top: clamp(36px, 4.5vw, 60px);
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 22px 44px;
  max-width: min(56vw, 640px);
}

/* 9.2 the room */
.room {
  padding-block: clamp(96px, 13vw, 200px);
}

/* The packed box of records is the object of this section, not a garnish. Its
   alpha runs off the left edge of the file (81% of that edge is object) and off
   the bottom (54%), so a left bleed is the cut it was made for: the binders lose
   their spines to the screen edge while the open box, the mug, the keys and the
   coiled cable all stay whole. Its right edge is anchored to the same measure
   the numerals column is built from, capped at 28vw, so type can never reach it
   however wide the window gets. It is hung from the band's bottom rather than
   its top: the offset is this section's own bottom padding plus the height of
   the vendor block above its rule, so the box's cut base lands ON that hairline
   rather than being sliced in mid air, and the vendor type below the rule is
   never crossed. Measured visible width: 62% from 1081 to 1600 and 69% at
   1920; below 1080 the plate goes static above the copy. */
.room .plate--left {
  /* the one measure both the plate's edge and its size are built from, so the
     visible fraction stays 62% instead of collapsing at narrow desktop widths */
  --anchor: max(calc(100% - 28vw), calc(var(--pad) + 764px));
  left: auto;
  right: var(--anchor);
  top: auto;
  bottom: calc(clamp(96px, 13vw, 200px) + 176px);
  width: min(780px, calc(1.6 * (100% - var(--anchor))));
}

.room-copy {
  margin-left: auto;
  width: min(100%, 860px);
}

.room-copy > p {
  margin-top: 28px;
}

.room-steps {
  list-style: none;
  margin: clamp(64px, 9vw, 120px) 0 0;
  padding: 0;
  width: min(100%, 740px);
  margin-left: auto;
}

.room-steps li {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr);
  gap: 8px clamp(24px, 3vw, 46px);
  align-items: start;
  padding-block: clamp(26px, 3vw, 40px);
  border-top: 1px solid var(--rule);
}

/* The ordinals are a graphic, not content: the ordered list already carries
   the sequence, so they are drawn from CSS at hairline weight rather than
   sitting in the DOM as text no reader is meant to hear or resolve. */
.room-steps li::before {
  font-family: var(--display);
  font-size: clamp(3rem, 6vw, 5.5rem);
  font-weight: 300;
  letter-spacing: -.04em;
  line-height: .8;
  color: var(--rule);
  transition: color .25s var(--easing);
}

/* Reading a step lights its numeral. The step is not a control, so the only
   trigger is the pointer or a focus landing inside it. */
.room-steps li:hover::before,
.room-steps li:focus-within::before {
  color: var(--accent);
}

.room-steps li:nth-child(1)::before {
  content: '01';
}

.room-steps li:nth-child(2)::before {
  content: '02';
}

.room-steps li:nth-child(3)::before {
  content: '03';
}

.room-steps h3 {
  margin-bottom: 10px;
}

.room-audience {
  margin: clamp(40px, 5vw, 64px) 0 0 auto;
  width: min(100%, 740px);
  font-size: clamp(1rem, 1.3vw, 1.1875rem);
  color: var(--ink);
}

.vendor-band {
  margin-top: clamp(64px, 8vw, 110px);
  padding-top: 30px;
  border-top: 1px solid var(--rule);
}

.vendor-heading {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 20px;
  font-size: .75rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ash) 80%, var(--void));
}

.marquee-toggle {
  margin-left: auto;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  min-height: 44px;
  padding-inline: 14px;
  border: 1px solid var(--rule);
  font-size: .6875rem;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--ash);
}

.marquee-toggle:hover {
  color: var(--ink);
  border-color: color-mix(in srgb, var(--accent) 50%, var(--rule));
}

.vendor-marquee {
  margin-top: 22px;
  overflow: hidden;
  mask-image: linear-gradient(to right, transparent, var(--ink) 8%, var(--ink) 92%, transparent);
  -webkit-mask-image: linear-gradient(to right, transparent, var(--ink) 8%, var(--ink) 92%, transparent);
}

.vendor-track {
  display: flex;
  width: max-content;
  animation: vendor-drift 44s linear infinite;
}

.vendor-track.paused {
  animation-play-state: paused;
}

.vendor-track ul {
  display: flex;
  align-items: center;
  gap: clamp(36px, 5vw, 72px);
  margin: 0;
  padding: 0 clamp(18px, 2.5vw, 36px);
  list-style: none;
}

.vendor-track li {
  font-family: var(--display);
  font-size: clamp(1.125rem, 1.9vw, 1.625rem);
  font-weight: 500;
  letter-spacing: -.025em;
  white-space: nowrap;
  color: color-mix(in srgb, var(--ash) 88%, var(--void));
}

.vendor-note {
  margin-top: 22px;
  font-size: .8125rem;
  color: color-mix(in srgb, var(--ash) 76%, var(--void));
}

/* 9.3 demo */
.demo > h2 {
  margin-top: 18px;
}

.demo {
  overflow: clip;
}

.demo-sub {
  margin-top: 26px;
}

/* The frame holds a still until someone asks for the product, then the same
   frame holds the product. One box, two states, so nothing on the page moves
   when the demo arrives. */
.demo-frame {
  position: relative;
  width: 100vw;
  margin-left: calc(50% - 50vw);
  margin-top: clamp(48px, 6vw, 84px);
  aspect-ratio: 16 / 10;
  min-height: 640px;
  max-height: 92vh;
  background: var(--slab);
  border-top: 1px solid var(--rule);
  border-bottom: 1px solid var(--rule);
  overflow: hidden;
}

.demo-still {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 22%;
}

.demo-frame iframe {
  display: block;
  width: 100%;
  height: 100%;
  border: 0;
}

.demo-frame .cta-demo--button {
  position: absolute;
  left: max(var(--gutter), calc((100vw - var(--max)) / 2 + var(--gutter)));
  bottom: 30px;
  min-height: 52px;
}

.demo-foot {
  margin-top: clamp(40px, 5vw, 66px);
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 18px 48px;
}

.demo-foot p {
  font-size: .875rem;
  color: color-mix(in srgb, var(--ash) 80%, var(--void));
}

/* 9.4 evidence */
/* The headline is held short of the ledger plate's left edge at every width,
   so the two never meet. */
.evidence h2 {
  max-width: min(100%, 920px);
}

/* The ledger enters through the top-right corner and stops inside the band's
   own top padding, so the headline can run its full two lines beneath it. That
   padding is deeper than the shared band rhythm for exactly this reason: the
   open book is 1300x924 and needs the height, and the alternative is a plate
   small enough to read as a scrap. */
.evidence {
  padding-block: clamp(120px, 21vw, 320px) var(--band);
}

.evidence-sub {
  margin-top: 26px;
}

.evidence-rows {
  list-style: none;
  margin: clamp(48px, 6vw, 80px) 0 clamp(40px, 5vw, 64px);
  padding: 0;
  width: min(100%, 820px);
  border-top: 1px solid var(--rule);
}

.evidence-rows li {
  border-bottom: 1px solid var(--rule);
  transition: border-color .25s var(--easing);
}

/* the one accent in this section: the hairline under the open row */
.evidence-rows li:has(.row[aria-expanded=true]) {
  border-bottom-color: var(--accent);
}

.row {
  display: flex;
  align-items: baseline;
  gap: 24px;
  width: 100%;
  min-height: 44px;
  padding-block: clamp(20px, 2.4vw, 30px);
  text-align: left;
}

.row-label {
  font-family: var(--display);
  font-size: clamp(1.0625rem, 1.5vw, 1.375rem);
  font-weight: 600;
  letter-spacing: -.02em;
  color: var(--ash);
  transition: color .2s var(--easing);
}

.row:hover .row-label,
.row:focus-visible .row-label,
.row[aria-expanded=true] .row-label {
  color: var(--ink);
}

.row-chevron {
  margin-left: auto;
  flex: none;
  color: var(--rule);
  transition: transform .32s var(--easing), color .2s var(--easing);
}

.row:hover .row-chevron,
.row:focus-visible .row-chevron {
  color: var(--ash);
}

.row[aria-expanded=true] .row-chevron {
  transform: rotate(180deg);
}

/* A grid row collapsed to 0fr: it opens to its own content height with no
   measured pixel value and no JavaScript animation. */
.row-detail {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows .32s cubic-bezier(.32, .72, 0, 1);
}

.row-detail > div {
  overflow: hidden;
  min-height: 0;
}

.row-detail p {
  padding-bottom: clamp(20px, 2.4vw, 28px);
  max-width: 58ch;
  font-size: .9375rem;
}

.row[aria-expanded=true] + .row-detail {
  grid-template-rows: 1fr;
}

/* On a real pointer, hovering the row previews it. A click still commits. */
@media (hover: hover) and (pointer: fine) {
  .row:hover + .row-detail {
    grid-template-rows: 1fr;
  }
}

/* 9.5 start */
.start > h2 {
  margin-top: 18px;
}

.start-grid {
  margin-top: clamp(56px, 7vw, 96px);
  display: grid;
  grid-template-columns: minmax(0, .85fr) minmax(0, 1fr);
  gap: clamp(48px, 7vw, 110px);
  align-items: start;
}

.start-steps {
  list-style: none;
  margin: 0;
  padding: 0;
}

.start-steps li {
  display: grid;
  gap: 6px;
}

.start-steps li + li {
  margin-top: clamp(34px, 4vw, 52px);
}

.start-numeral {
  font-family: var(--display);
  font-size: .8125rem;
  letter-spacing: .16em;
  color: var(--accent);
}

.start-steps strong {
  font-family: var(--display);
  font-size: clamp(1.125rem, 1.5vw, 1.3125rem);
  letter-spacing: -.02em;
}

.start-steps span:last-child {
  font-size: .9375rem;
  color: var(--ash);
  max-width: 44ch;
}

.start-faq details + details {
  margin-top: clamp(22px, 2.6vw, 34px);
}

/* 9.6 closing */
/* The bottom padding is the plate's room: the town runs off the bottom-left
   corner, and this is the clearance that keeps its top edge below the button. */
.closing {
  text-align: center;
  padding-block: clamp(140px, 16vw, 240px) clamp(200px, 28vw, 470px);
}

.closing h2 {
  font-size: clamp(3rem, 8.5vw, 8rem);
  margin-inline: auto;
  max-width: 16ch;
}

.closing .cta-book {
  margin-top: clamp(40px, 5vw, 64px);
}

/* shared: disclosure rows (index FAQ and the security page) */
details {
  border-bottom: 1px solid var(--rule);
  padding-bottom: 16px;
}

summary {
  display: flex;
  align-items: center;
  gap: 20px;
  min-height: 44px;
  cursor: pointer;
  list-style: none;
  font-family: var(--display);
  font-size: clamp(1rem, 1.3vw, 1.1875rem);
  font-weight: 500;
  letter-spacing: -.02em;
  color: var(--ink);
}

summary::-webkit-details-marker {
  display: none;
}

summary > span {
  margin-left: auto;
  color: var(--accent);
  font-size: 1.125rem;
  transition: transform .24s var(--easing);
}

details[open] summary > span {
  transform: rotate(45deg);
}

details p {
  margin-top: 12px;
  font-size: .9375rem;
}

details[open] {
  background: none;
}


/* --- 10. editorial pages (company, security) --------------------------- */

.editorial-hero {
  padding-block: clamp(64px, 9vw, 130px) clamp(48px, 6vw, 80px);
}

.editorial-hero h1 {
  margin-top: 20px;
  font-size: clamp(2.5rem, 5.4vw, 4.75rem);
}

.editorial-hero .lead {
  margin-top: 28px;
}

.editorial-hero .fine-print {
  margin-top: 26px;
  max-width: 72ch;
}

/* 10.1 company hero: the founder is a portrait held in a circle beside the
   headline. The circle's own edge does every bit of the cropping, so the
   cutout's flat bottom edge never reaches the screen; the ring is a hairline
   in --rule, never the accent, and the image is never faded or filtered. */
.company-hero {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 48px;
}

/* The circle takes a bite out of the measure, so the display cap here is one
   step under the shared editorial scale: it is the largest size that still
   holds "behind public service." on one line beside the portrait. Above 1080
   the circle leaves the column and the shared scale comes back. */
.company-hero h1 {
  font-size: clamp(2.5rem, 4.6vw, 4rem);
}

.company-hero .editorial-hero-copy {
  flex: 1 1 auto;
  min-width: 0;
  max-width: 740px;
}

.founder-circle {
  flex: 0 0 auto;
  margin: 0;
  width: clamp(220px, 27vw, 400px);
  height: clamp(220px, 27vw, 400px);
  border: 1px solid var(--rule);
  border-radius: 50%;
  overflow: hidden;
  background: var(--slab);
}

/* The frame is square and the source is a 900x1128 portrait, so cover fills
   the width and the vertical offset is the only crop tuning: 18% down the
   overflow puts the crown inside the upper arc and leaves the shoulders
   filling the bottom, with the circle's edge doing all the cutting. The 106%
   width is the horizontal recentre: the head in the source sits at 45.9% of
   the frame, and the small overwidth carries it onto the circle's own axis. */
.founder-circle img {
  display: block;
  width: 106%;
  max-width: none;
  height: 100%;
  object-fit: cover;
  object-position: 50% 24%;
}

/* 10.2 security hero: the appliance bleeds off the left edge at a third of
   the band, the headline sits in the right-hand column. */
.security-hero {
  min-height: min(70vh, 620px);
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.security-hero .plate--left {
  left: -8vw;
  right: auto;
  top: 50%;
  transform: translateY(-50%);
  width: min(36vw, 540px);
}

.security-hero .editorial-hero-copy {
  margin-left: auto;
  width: min(70%, 780px);
}

/* 10.3 editorial heroes on a narrow screen: the circle leaves the headline's
   side and stacks above it, and the security plate goes static above the
   copy, so no headline ever shares a column with an image. */
@media (max-width: 1080px) {
  .company-hero {
    flex-direction: column;
    align-items: flex-start;
    gap: 0;
  }

  .company-hero .editorial-hero-copy {
    max-width: none;
  }

  .company-hero h1 {
    font-size: clamp(2.5rem, 5.4vw, 4.75rem);
  }

  .founder-circle {
    order: -1;
    width: clamp(200px, 26vw, 300px);
    height: clamp(200px, 26vw, 300px);
    margin-bottom: clamp(24px, 4vw, 40px);
  }
}

@media (max-width: 720px) {
  .security-hero {
    min-height: 0;
    justify-content: flex-start;
  }

  .security-hero .editorial-hero-copy {
    max-width: none;
    width: auto;
    margin-left: 0;
  }

  .founder-circle {
    width: 200px;
    height: 200px;
    margin-inline: auto;
    align-self: center;
  }

  .security-hero .plate--left {
    left: auto;
    top: auto;
    transform: none;
    width: 118%;
  }
}

.editorial-grid {
  display: grid;
  grid-template-columns: minmax(0, 220px) minmax(0, 1fr);
  gap: clamp(40px, 6vw, 96px);
  align-items: start;
  padding-bottom: clamp(88px, 11vw, 160px);
}

.page-index {
  position: sticky;
  top: 108px;
  display: flex;
  flex-direction: column;
  gap: 2px;
  border-left: 1px solid var(--rule);
  padding-left: 20px;
}

.page-index > span {
  font-size: .75rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--accent);
  margin-bottom: 12px;
}

.page-index a {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-size: .9375rem;
  color: var(--ash);
}

.page-index a:hover {
  color: var(--ink);
}

.editorial-content section + section {
  margin-top: clamp(56px, 7vw, 96px);
  padding-top: clamp(56px, 7vw, 96px);
  border-top: 1px solid var(--rule);
}

.editorial-content h2 {
  font-size: clamp(1.875rem, 3.2vw, 2.75rem);
  margin-bottom: 22px;
}

.editorial-content h3 {
  margin: 34px 0 14px;
}

.editorial-content p + p {
  margin-top: 16px;
}

.editorial-content ul {
  margin: 20px 0 0;
  padding-left: 20px;
  color: var(--ash);
  font-size: .9375rem;
}

.editorial-content ul li + li {
  margin-top: 8px;
}

.editorial-content .actions,
.editorial-content .cta-security,
.editorial-content .cta-demo,
.editorial-content .cta-book {
  margin-top: 26px;
}

/* the one display-scale link inside a reading column is tempered a step */
.editorial-content .cta-demo {
  font-size: clamp(1.25rem, 1.8vw, 1.625rem);
}

.control-note {
  margin-top: 26px;
  padding: 20px 24px;
  border-left: 1px solid var(--accent);
  background: var(--slab);
  font-size: .9375rem;
  color: var(--ash);
}

.company-facts {
  margin: clamp(40px, 5vw, 64px) 0 0;
  display: flex;
  flex-wrap: wrap;
  gap: 12px clamp(40px, 6vw, 80px);
  border-top: 1px solid var(--rule);
  padding-top: 26px;
}

.company-facts dt {
  font-size: .75rem;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: color-mix(in srgb, var(--ash) 80%, var(--void));
}

.company-facts dd {
  margin: 6px 0 0;
  font-family: var(--display);
  font-size: 1.0625rem;
  font-weight: 500;
  letter-spacing: -.02em;
  color: var(--ink);
}


/* --- 11. motion -------------------------------------------------------- */
/* One signature: the uncover. It only ever reveals, so the resting state of
   every headline is fully visible with JavaScript off. */

@keyframes uncover {
  from {
    clip-path: inset(0 100% 0 0);
  }
  to {
    clip-path: inset(0 0 0 0);
  }
}

[data-uncover] {
  animation: uncover .58s var(--easing) backwards;
}

/* the numerals uncover behind their step, staggered from JavaScript */
[data-numeral-uncover]::before {
  animation: uncover .58s var(--easing) backwards;
}

/* Scroll-linked drift. Transform only: a plate is never faded, and with no
   support for view() timelines every plate simply rests where it is. The hero
   video is excluded because it already moves. */
@keyframes plate-drift {
  from {
    transform: translateY(6%);
  }
  to {
    transform: translateY(-6%);
  }
}

@supports (animation-timeline: view()) {
  .plate img,
  .plate video {
    animation: plate-drift linear both;
    animation-timeline: view();
    animation-range: entry 0% exit 100%;
  }

  .plate--video img,
  .plate--video video {
    animation: none;
  }
}

@keyframes vendor-drift {
  to {
    transform: translate3d(-50%, 0, 0);
  }
}

@keyframes dialog-in {
  from {
    opacity: 0;
    transform: translateY(10px);
  }
  to {
    opacity: 1;
    transform: translateY(0);
  }
}

dialog[open] {
  animation: dialog-in .28s var(--easing);
}


/* --- 12. breakpoints ---------------------------------------------------- */

@media (min-width: 1600px) {
  :root {
    --max: 1400px;
  }

  .hero-sub,
  .hero-actions {
    max-width: min(52vw, 700px);
  }

  .plate--right {
    right: -3vw;
    width: min(48vw, 1020px);
  }
}

@media (max-width: 1080px) {
  .site-header {
    gap: 16px;
  }

  .site-header nav {
    gap: 16px;
  }

  .hero {
    padding-block: clamp(48px, 8vw, 96px) clamp(210px, 38vw, 340px);
  }

  .hero-sub,
  .hero-actions {
    max-width: 74vw;
  }

  .plate--right {
    right: -10vw;
    bottom: -8vw;
    width: min(72vw, 760px);
  }

  .room {
    display: flex;
    flex-direction: column;
  }

  /* the desk plate is nearly square, so it is capped tighter than a landscape
     plate would be: at 76% it would push the copy most of a screen down */
  .room .plate {
    position: static;
    order: -1;
    width: 54%;
    max-width: 420px;
    margin: 0 0 clamp(24px, 5vw, 48px) -6%;
  }

  .room-copy,
  .room-steps,
  .room-audience {
    margin-left: 0;
    width: 100%;
  }

  .evidence h2,
  .evidence-rows {
    max-width: 62%;
  }

  .evidence-rows {
    width: auto;
  }

  .start-grid {
    grid-template-columns: minmax(0, 1fr);
    gap: clamp(48px, 7vw, 72px);
  }

  .editorial-grid {
    grid-template-columns: minmax(0, 1fr);
  }

  .page-index {
    position: static;
    flex-direction: row;
    flex-wrap: wrap;
    gap: 4px 22px;
    border-left: 0;
    border-top: 1px solid var(--rule);
    padding: 16px 0 0;
  }

  .page-index > span {
    width: 100%;
    margin-bottom: 0;
  }
}

@media (max-width: 720px) {
  .menu-toggle {
    display: inline-flex;
  }

  .site-header {
    height: 68px;
  }

  .site-header nav {
    position: absolute;
    top: 100%;
    left: 0;
    right: 0;
    display: none;
    flex-direction: column;
    align-items: stretch;
    gap: 0;
    padding: 12px var(--gutter) 26px;
    background: var(--void);
    border-bottom: 1px solid var(--rule);
  }

  .site-header nav[data-open] {
    display: flex;
  }

  .site-header nav > a {
    min-height: 52px;
    border-bottom: 1px solid var(--rule);
    font-size: 1.0625rem;
  }

  .site-header nav .cta-book {
    margin-top: 18px;
    justify-content: center;
  }

  /* plates go static below the copy, oversized, except the hero which keeps
     its absolute placement against reserved padding */
  .plate-host {
    display: flex;
    flex-direction: column;
  }

  .plate {
    position: static;
    width: 118%;
    max-width: none;
    margin-left: -9%;
    order: -1;
    margin-bottom: clamp(28px, 7vw, 48px);
  }

  .hero {
    display: block;
    padding-block: 40px clamp(230px, 66vw, 470px);
  }

  .hero .plate {
    position: absolute;
    order: 0;
    left: -9%;
    right: auto;
    bottom: -4vw;
    width: 118%;
    margin: 0;
  }

  .hero-copy,
  .hero-sub,
  .hero-actions {
    max-width: none;
  }

  /* square plate: 118% of a phone is half a screen of cardboard before a word
     of copy, so the desk keeps a hard cap here too */
  .room .plate {
    width: 74%;
    max-width: 360px;
    margin: 0 0 clamp(28px, 7vw, 48px) -6%;
  }

  /* the ledger is stacked above the copy on a phone, so the band's extra top
     padding has nothing left to hold */
  .evidence {
    padding-block: var(--band);
  }

  .room-steps li {
    grid-template-columns: minmax(0, 1fr);
    gap: 6px;
  }

  .room-steps li::before {
    font-size: 3rem;
    line-height: 1;
  }

  .evidence h2,
  .evidence-rows {
    max-width: none;
  }

  .row {
    gap: 16px;
  }

  .demo-frame {
    min-height: 520px;
    max-height: none;
  }

  .demo-frame .cta-demo--button {
    left: var(--gutter);
    bottom: 18px;
    padding: 8px 18px;
  }

  .footer-top > a:last-child {
    margin-left: 0;
    width: 100%;
  }

  .footer-bottom nav {
    margin-left: 0;
    gap: 18px;
  }

  .company-facts {
    gap: 18px 40px;
  }
}

@media (max-width: 400px) {
  :root {
    --gutter: 20px;
  }

  h1 {
    font-size: 3rem;
  }

  .hero-actions {
    gap: 18px;
  }

  .cta-demo {
    font-size: 1.25rem;
  }

  .closing h2 {
    font-size: 2.75rem;
  }

  .vendor-heading {
    font-size: .6875rem;
  }
}


/* --- 13. reduced motion -------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  html {
    scroll-behavior: auto;
  }

  *,
  *::before,
  *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
    scroll-behavior: auto !important;
  }

  .vendor-track {
    animation: none;
    width: 100%;
    justify-content: center;
    flex-wrap: wrap;
  }

  .vendor-track ul[aria-hidden] {
    display: none;
  }

  .vendor-marquee {
    overflow: visible;
    mask-image: none;
    -webkit-mask-image: none;
  }

  .marquee-toggle {
    display: none;
  }

  /* A scroll timeline ignores animation-duration, so the drift has to be
     switched off by name, and the transform it left behind reset. */
  .plate img,
  .plate video {
    animation: none !important;
    animation-timeline: auto !important;
    transform: none !important;
  }

  /* No hero loop at all: the still plate is the whole hero. */
  .plate--video video {
    display: none !important;
  }

  .row-chevron,
  .row-detail {
    transition: none;
  }
}


/* --- 14. visually hidden -------------------------------------------------- */

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  clip-path: inset(50%);
  white-space: nowrap;
}
