/* The Object home page (Settings → Brand → Home page: object).

   The Design King design, scoped to .object-home: the wrapper the home view renders inside
   the site's own layout, so the logo, header and footer are the same as on every other page.
   On this page the platform's stylesheets load in the `platform` cascade layer (see
   partials/head.ejs), so these unlayered rules always win inside .object-home and nothing
   here reaches outside it. The design's header, menu and footer rules are not carried over. */

/* Fazley — "The Object"
   A 3D design for fazley.org. One idea: the Fazley F is a real object on the workbench.
   It stands lit on warm paper, comes apart on scroll into the things Fazley builds, and
   its rust dot grows until it fills the screen and becomes the "Build. Operate. Compound."
   band. Everything else is type on paper.

   Art direction, frozen:
   - Type: Bricolage Grotesque for display (regular–medium, tight), Inter for reading,
     JetBrains Mono for small data.
   - Colour: paper #F2EFE9, ink #141619, the favicon's rust #A8462A, slate as a quiet second.
   - Motion: one settle ease and one wipe ease; words rise from masks; the object does the rest.
   - The kit of parts: the F is three bars and a dot, and every picture on the site is built from
     the same kit (ink and slate bars, the rust dot, on paper). Posters, service glyphs, the
     compounding chart and the call badge are drawings made of the object's own pieces; the
     chart is hatched like a section on an engineering sheet.
   - The object casts no shadow: the parts stand clean on the paper.
   Reduced motion: the scene never starts; a flat F stands in; nothing moves. */

.object-home {
  --paper: #f2efe9;
  --paper-2: #e9e5dd;
  --card: #fbfaf7;
  --ink: #141619;
  --text-2: #3a3d42;
  --muted: #5c6066;
  --line: rgba(20, 22, 25, 0.14);
  --line-strong: rgba(20, 22, 25, 0.3);
  --rust: #a8462a;
  --rust-deep: #8e3a22;
  --slate: #2f4858;
  --umber: #5b4a35;
  --soft: #bdb8af;            /* the kit's light bar: ink at 25% on paper */
  --display: 'Bricolage Grotesque', 'Inter', system-ui, sans-serif;
  --sans: 'Inter', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, Consolas, monospace;
  --gutter: clamp(18px, 3vw, 48px);
  --container: 1280px;
  --ease: cubic-bezier(0.16, 1, 0.3, 1);
  --ease-io: cubic-bezier(0.76, 0, 0.24, 1);
}

.object-home *, .object-home *::before, .object-home *::after { box-sizing: border-box; margin: 0; padding: 0; }
.object-home {
  background: var(--paper);
  color: var(--ink);
  font: 400 1rem/1.55 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  overflow-x: clip;
}
.object-home a { color: inherit; text-decoration: none; }
.object-home button { font: inherit; color: inherit; background: none; border: 0; cursor: pointer; }
.object-home ul, .object-home ol { list-style: none; }
.object-home img, .object-home svg { display: block; max-width: 100%; }
.object-home ::selection { background: var(--rust); color: var(--paper); }
.object-home :focus-visible { outline: 2px solid var(--rust); outline-offset: 3px; }

/* Paper grain over everything, the object included, so the render reads as printed rather than
   lit on a screen. One static tile of ink-coloured noise; no blend mode, nothing animates. */
.object-home::after {
  content: ''; position: fixed; inset: 0; z-index: 90; pointer-events: none;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.9' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 .08 0 0 0 0 .086 0 0 0 0 .1 1.5 0 0 0 -.62'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E");
  opacity: 0.13;
}

.object-home .container { width: min(100% - 2 * var(--gutter), var(--container)); margin-inline: auto; }

/* ── Type ──────────────────────────────────────────────────────────────── */

.object-home .display {
  font-family: var(--display);
  font-weight: 500;
  letter-spacing: -0.04em;
  line-height: 0.94;
  text-wrap: balance;
}
.object-home .stop { color: var(--rust); }
.object-home .eyebrow {
  display: inline-flex;
  align-items: center;
  gap: 0.6em;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--text-2);
}
.object-home .eyebrow::before { content: ''; width: 0.42em; height: 0.42em; border-radius: 50%; background: var(--rust); }
.object-home .lede { font-size: clamp(1.08rem, 1rem + 0.35vw, 1.3rem); line-height: 1.5; color: var(--text-2); max-width: 38rem; text-wrap: pretty; }
.object-home p { text-wrap: pretty; }

/* Split-text masks (SplitText mask: "lines" wraps each line in an unclassed div) */
.object-home [data-split] > div { padding-bottom: 0.1em; margin-bottom: -0.1em; }

/* ── Buttons ───────────────────────────────────────────────────────────── */

.object-home .btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 0.5em;
  padding: 0.78em 1.3em; border-radius: 6px; border: 1px solid var(--line-strong);
  font-weight: 550; font-size: 0.95rem; letter-spacing: -0.005em; white-space: nowrap;
  transition: background-color 220ms var(--ease), color 220ms var(--ease), border-color 220ms var(--ease);
}
.object-home .btn-primary { background: var(--ink); color: var(--paper); border-color: var(--ink); }
.object-home .btn-primary:hover { background: var(--rust); border-color: var(--rust); }
.object-home .btn-ghost:hover { border-color: var(--ink); }
.object-home .btn-lg { padding: 0.95em 1.6em; font-size: 1rem; }
.object-home .btn-sm { padding: 0.55em 0.95em; font-size: 0.85rem; }

/* ── The stage: one fixed canvas behind the page ───────────────────────── */

.object-home .stage {
  position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: 0;
  pointer-events: none; display: block;
}
.gl .object-home .hero__fallback { display: none; }

/* Labels pinned to the exploded parts; positioned from the scene each frame. */
.object-home .labels { position: fixed; inset: 0; z-index: 2; pointer-events: none; }
.object-home .label {
  position: absolute; left: 0; top: 0;
  display: grid; gap: 0.1rem;
  padding-left: 2.6rem;
  width: max-content; max-width: 21rem;   /* one line each, so no label reaches down onto the dot */
  font-size: 0.95rem; line-height: 1.25;
  opacity: 0; translate: 0 6px;
  transition: opacity 500ms var(--ease), translate 700ms var(--ease);
}
.object-home .label b { font-family: var(--display); font-weight: 500; font-size: 1.15rem; letter-spacing: -0.02em; }
.object-home .label i { font-style: normal; color: var(--muted); font-size: 0.85rem; }
.object-home .label::before { content: ''; position: absolute; left: 0.35rem; top: 0.72rem; width: 2rem; height: 1px; background: var(--line-strong); }
.object-home .label::after { content: ''; position: absolute; left: 0; top: 0.5rem; width: 0.45rem; height: 0.45rem; border-radius: 50%; background: var(--ink); }
.object-home .label[data-side='left'] { padding-left: 0; padding-right: 2.6rem; text-align: right; translate: -100% 6px; }
.object-home .label[data-side='left']::before { left: auto; right: 0.35rem; }
.object-home .label[data-side='left']::after { left: auto; right: 0; }
.object-home .label.is-on { opacity: 1; translate: 0 0; }
.object-home .label[data-side='left'].is-on { translate: -100% 0; }

/* Fazley, the guide: his own canvas above the page (the F's sits under the paper), drawn only while
   he is out, and a speech bubble that guide.js keeps above his head. */
.object-home .guide-stage {
  position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: 3;
  pointer-events: none; display: block; visibility: hidden;
}
.object-home .guide-bubble {
  position: fixed; left: 0; top: 0; z-index: 4; pointer-events: none;
  width: max-content; max-width: 15rem; padding: 0.7em 0.95em; border-radius: 14px;
  background: var(--ink); color: var(--paper); font: 500 0.92rem/1.38 var(--sans); text-wrap: pretty;
  opacity: 0; transition: opacity 300ms var(--ease);
}
.object-home .guide-bubble::after {
  content: ''; position: absolute; left: var(--tail, 50%); bottom: -5px; width: 12px; height: 12px;
  border-radius: 2px; background: var(--ink); translate: -50% 0; rotate: 45deg;
}
.object-home .guide-bubble.is-on { opacity: 1; }
.object-home .guide-bubble.pop { animation: bubble-pop 450ms var(--ease); }
@keyframes bubble-pop { from { scale: 0.86; } }

/* ── Hero ──────────────────────────────────────────────────────────────── */

.object-home__main { position: relative; z-index: 1; }

.object-home .hero { position: relative; min-height: 100svh; display: flex; align-items: center; padding: 9rem 0 5rem; }
.object-home .hero h1 .stop { color: var(--rust); }
.object-home .hero__grid { display: grid; grid-template-columns: minmax(0, 1.05fr) minmax(0, 0.95fr); align-items: center; gap: var(--gutter); }
.object-home .hero__copy { max-width: 34rem; }
.object-home .hero h1 {
  font-size: clamp(3rem, 6.6vw, 7.2rem);
  margin-top: 1.4rem;
  max-width: 12ch;
  letter-spacing: -0.045em;
  line-height: 0.92;
}
.object-home .hero__sub {
  margin-top: 2rem; padding-top: 1.4rem; border-top: 1px solid var(--line-strong);
  font-size: clamp(1.05rem, 0.98rem + 0.3vw, 1.2rem); color: var(--text-2); line-height: 1.55; max-width: 32rem;
}
.object-home .hero__actions { display: flex; flex-wrap: wrap; gap: 0.75rem; margin-top: 1.75rem; }
.object-home .hero__facts { display: flex; flex-wrap: wrap; gap: 0.4rem 1.6rem; margin-top: 2rem; font-size: 0.88rem; font-weight: 500; color: var(--muted); }
.object-home .hero__facts li { display: inline-flex; align-items: center; gap: 0.55rem; }
.object-home .hero__facts li::before { content: ''; width: 0.36rem; height: 0.36rem; border-radius: 50%; background: var(--line-strong); }
.object-home .hero__fallback { width: min(100%, 26rem); justify-self: center; }
.object-home .hero__hint {
  position: absolute; left: var(--gutter); bottom: 1.6rem;
  font-family: var(--mono); font-size: 0.78rem; color: var(--muted);
  opacity: 0; transition: opacity 600ms var(--ease) 1.8s;
}
.gl .object-home .hero__hint { opacity: 1; }

/* The hero copy waits for the script; if it never runs, it shows after 1.2s. */
.object-home .hero:not(.is-ready) .hero__copy { animation: safety 1ms linear 1.2s both; }
@keyframes safety { from { opacity: 0; } to { opacity: 1; } }
.object-home .wait .eyebrow, .object-home .wait .hero__sub, .object-home .wait .hero__actions, .object-home .wait .hero__facts, .object-home .wait .lede { opacity: 0; translate: 0 10px; }
.object-home .wait.is-in .eyebrow, .object-home .wait.is-in .hero__sub, .object-home .wait.is-in .hero__actions, .object-home .wait.is-in .hero__facts, .object-home .wait.is-in .lede {
  opacity: 1; translate: 0 0;
  transition: opacity 700ms var(--ease) 600ms, translate 900ms var(--ease) 600ms;
}
.object-home .wait.is-in .eyebrow { transition-delay: 0ms; }

/* ── Parts: the sticky plate where the object comes apart ──────────────── */

.object-home .parts { height: 330vh; }   /* two thirds to come apart, then the dot hops, bursts and Fazley lands */
.object-home .parts__sticky { position: sticky; top: 0; height: 100vh; padding-top: 7.5rem; }
.object-home .parts h2 { font-size: clamp(2rem, 4.2vw, 4rem); margin-top: 0.8rem; max-width: 14ch; }

/* ── Services list ─────────────────────────────────────────────────────── */

.object-home .services { position: relative; background: var(--paper); padding: clamp(4rem, 8vw, 7rem) 0 clamp(5rem, 9vw, 8rem); }
.object-home .section-head {
  display: grid; grid-template-columns: minmax(9rem, 0.28fr) minmax(0, 1fr);
  column-gap: clamp(2rem, 5vw, 5rem); align-items: start;
  margin-bottom: clamp(2.25rem, 5vw, 4rem);
}
.object-home .section-head .eyebrow { grid-column: 1; grid-row: 1 / span 2; padding-top: 0.6em; }
.object-home .section-head h2 { grid-column: 2; font-size: clamp(2.1rem, 4.3vw, 4.3rem); max-width: 17ch; }
.object-home .section-head > p:not(.eyebrow) { grid-column: 2; margin-top: 1.1rem; font-size: 1.1rem; color: var(--text-2); max-width: 40rem; }

/* With the script on, Fazley takes the rail column beside the list (the same columns as the
   section head, so the list sits under the heading); without it, or without WebGL, it folds away. */
.object-home .guide { display: none; }
.js:not(.guide-off) .object-home .services__body {
  display: grid; grid-template-columns: minmax(9rem, 0.28fr) minmax(0, 1fr);
  column-gap: clamp(2rem, 5vw, 5rem); align-items: start;
}
.js:not(.guide-off) .object-home .guide { display: block; position: sticky; top: 14vh; height: min(70vh, 36rem); }
.object-home .service-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 clamp(2rem, 5vw, 4.5rem); counter-reset: svc; }
.object-home .service-list > li { position: relative; counter-increment: svc; border-top: 1px solid var(--line-strong); padding: 1.6rem 0 2.4rem; transition: border-color 300ms var(--ease); }
.object-home .service-list > li:hover { border-top-color: var(--ink); }
.object-home .service-list > li::before { content: counter(svc, decimal-leading-zero); display: block; margin-bottom: 1.4rem; font: 500 0.78rem/1 var(--mono); letter-spacing: 0.04em; color: var(--rust); }
.object-home .service-list h3 { font: 500 clamp(1.45rem, 2.2vw, 2rem)/1.1 var(--display); letter-spacing: -0.035em; margin-bottom: 0.6rem; padding-right: 4rem; }

/* Service glyphs: each one is the F's kit (ink bars, a light bar, the rust dot) arranged as the
   service, and on hover the parts do the job: the cursor clicks, the block is dragged, the
   modules come apart, the dot flows, the lead drops, the bars grow. */
.object-home .glyph { position: absolute; top: 1.5rem; right: 0; width: 3rem; height: 3rem; overflow: visible; }
.object-home .glyph .k-ink { fill: var(--ink); }
.object-home .glyph .k-soft { fill: var(--soft); }
.object-home .glyph .k-dot { fill: var(--rust); }
.object-home .glyph * { transform-box: fill-box; transition: transform 700ms var(--ease); }
.object-home li:hover > .glyph--web .k-dot { transform: translate(-7px, -12px); }
.object-home li:hover > .glyph--cms .k-drag { transform: translateX(5px); }
.object-home li:hover > .glyph--saas .k-m1 { transform: translate(-3px, -3px); }
.object-home li:hover > .glyph--saas .k-m2 { transform: translate(3px, -3px); }
.object-home li:hover > .glyph--saas .k-m3 { transform: translate(-3px, 3px); }
.object-home li:hover > .glyph--saas .k-dot { transform: translate(3px, 3px); }
.object-home li:hover > .glyph--flow .k-dot { transform: translateX(20px); }
.object-home li:hover > .glyph--lead .k-dot { animation: drop 900ms var(--ease) both; }
@keyframes drop { 0% { transform: translateY(-34px); opacity: 0; } 30% { opacity: 1; } 100% { transform: none; } }
.object-home .glyph--grow .k-bar { transform-origin: 50% 100%; }
.object-home li:hover > .glyph--grow .k-b1 { transform: scaleY(1.6); }
.object-home li:hover > .glyph--grow .k-b2 { transform: scaleY(1.32); }
.object-home li:hover > .glyph--grow .k-b3 { transform: scaleY(1.12); }
.object-home li:hover > .glyph--grow .k-dot { transform: translateY(-3px); }
.object-home .service-list > li > p { color: var(--text-2); max-width: 32rem; }
.object-home .service-list ul { display: flex; flex-wrap: wrap; gap: 0.35rem 1.25rem; margin-top: 1rem; font-size: 0.9rem; color: var(--muted); }
.object-home .service-list ul li::before { content: '– '; color: var(--rust); }

/* ── The bridge and the band ───────────────────────────────────────────── */

.object-home .bridge { height: 190vh; background: color-mix(in srgb, var(--rust) calc(var(--fill, 0) * 100%), transparent); }
.object-home .model {
  position: relative; background: var(--rust); color: var(--paper);
  min-height: 100vh; display: flex; align-items: center; padding: clamp(5rem, 10vw, 9rem) 0;
}
.object-home .model .eyebrow { color: color-mix(in srgb, var(--paper) 80%, transparent); }
.object-home .model .eyebrow::before { background: var(--paper); }
.object-home .model__grid { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: clamp(2rem, 6vw, 6rem); align-items: start; }
.object-home .model__grid .eyebrow, .object-home .model__grid h2 { grid-column: 1 / -1; }
.object-home .model h2 { font-size: clamp(3rem, 9vw, 9.5rem); letter-spacing: -0.05em; line-height: 0.9; margin: 1.4rem 0 clamp(2rem, 4vw, 3.5rem); max-width: 10ch; }
.object-home .model h2 .stop { color: var(--ink); }
.object-home .model__body { font-size: 1.15rem; line-height: 1.5; max-width: 32rem; color: color-mix(in srgb, var(--paper) 90%, transparent); }
.object-home .model__list li { padding: 0.9rem 0; border-top: 1px solid color-mix(in srgb, var(--paper) 28%, transparent); display: flex; gap: 0.8rem; align-items: baseline; font-size: 1rem; }
.object-home .model__list li::before { content: ''; flex: 0 0 auto; width: 0.42rem; height: 0.42rem; border-radius: 50%; background: var(--ink); transform: translateY(-0.1em); }
.object-home .model .btn { margin-top: 1.5rem; }

/* The compounding chart: an illustration, not data. Ink line and dots on the rust, the area under
   it hatched like a section on a drawing; scroll draws it from left to right. */
.object-home .model__chart { grid-column: 1 / -1; margin-top: clamp(3.5rem, 7vw, 6rem); }
.object-home .model__chart svg { width: 100%; height: auto; overflow: visible; }
.object-home .model__chart .axis { stroke: color-mix(in srgb, var(--paper) 45%, transparent); stroke-width: 1; }
.object-home .model__chart .phase { stroke: color-mix(in srgb, var(--paper) 30%, transparent); stroke-width: 1; stroke-dasharray: 3 5; }
.object-home .model__chart .line { fill: none; stroke: var(--ink); stroke-width: 2.5; stroke-linejoin: round; }
.object-home .model__chart .area { fill: url(#hatch); opacity: 0.3; }
.object-home .model__chart .hatch-line { fill: var(--ink); }
.object-home .model__chart .dots { fill: var(--ink); }
.object-home .model__phases { display: grid; grid-template-columns: 3fr 4fr 5fr; margin-top: 1rem; }   /* the 300 / 400 / 500 split of the drawing */
.object-home .model__phases span { display: grid; align-content: start; gap: 0.35rem; padding: 0 1rem 0 0.7rem; font-size: 0.92rem; color: color-mix(in srgb, var(--paper) 82%, transparent); }
.object-home .model__phases span:first-child { padding-left: 0; }
.object-home .model__phases b { font: 500 0.78rem/1 var(--mono); letter-spacing: 0.04em; text-transform: uppercase; color: var(--paper); }
.object-home .model__phases i { font-style: normal; }

/* ── The marquee: two rows of type that slide against each other with the scroll ── */

.object-home .marquee { position: relative; background: var(--paper); overflow: hidden; padding: clamp(3.5rem, 7vw, 6rem) 0 clamp(1rem, 2vw, 2rem); }
.object-home .marquee__row {
  width: max-content; white-space: nowrap;
  font: 500 clamp(3.4rem, 10.5vw, 10.5rem)/1 var(--display); letter-spacing: -0.05em;
}
.object-home .marquee__row + .marquee__row { margin-top: 0.06em; }
.object-home .marquee__row--quiet { color: var(--soft); }   /* not an outline: text-stroke traces the variable font's overlapping contours */
.object-home .marquee__row i { display: inline-block; width: 0.17em; height: 0.17em; margin: 0 0.32em; border-radius: 50%; background: var(--rust); vertical-align: 0.12em; }

/* ── Products: poster covers ───────────────────────────────────────────── */

.object-home .products, .object-home .principles, .object-home .journal, .object-home .faq, .object-home .close { position: relative; background: var(--paper); }
.object-home .products { padding: clamp(3rem, 6vw, 5rem) 0 clamp(4.5rem, 9vw, 8rem); }   /* the marquee sits above */
.object-home .poster-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: clamp(1.5rem, 3vw, 2.5rem); perspective: 1600px; }
.object-home .poster { display: grid; gap: 0.55rem; align-content: start; transform-style: preserve-3d; }
.object-home .poster__cover {
  position: relative; display: block; aspect-ratio: 4 / 5; border-radius: 6px; overflow: hidden;
  background: var(--rust); color: var(--paper); container-type: inline-size;
  transition: transform 700ms var(--ease), box-shadow 700ms var(--ease);
  transform: rotateX(var(--rx, 0deg)) rotateY(var(--ry, 0deg));
  box-shadow: 0 30px 60px -40px rgba(20, 22, 25, 0.45);
}
.object-home .poster[data-tone='slate'] .poster__cover { background: var(--slate); }
.object-home .poster[data-tone='ink'] .poster__cover { background: var(--ink); }
.object-home .poster[data-tone='umber'] .poster__cover { background: var(--umber); }

/* Poster art: each cover is a figure drawn from the kit that tells what the product does, with a
   caption on top and a legend below, like a plate in a field guide. Three states: before it has
   been seen (only once the script runs), at rest, and on hover, where the product does its job. */
.object-home .art { position: absolute; inset: 0; width: 100%; height: 100%; }
.object-home .art .rust { fill: var(--rust); }
.object-home .art .ink { fill: var(--ink); }
.object-home .art .days { font: 500 11px var(--mono); fill: currentColor; fill-opacity: 0.5; text-anchor: middle; }
.object-home .art__cap, .object-home .art__key {
  position: absolute; left: 7cqw; right: 7cqw; display: flex; justify-content: space-between; gap: 1em;
  font: 500 max(0.62rem, 3.1cqw)/1 var(--mono); letter-spacing: 0.05em; text-transform: uppercase;
  color: color-mix(in srgb, currentColor 72%, transparent);
}
.object-home .art__cap { top: 7cqw; padding-bottom: 3cqw; border-bottom: 1px solid color-mix(in srgb, currentColor 22%, transparent); }
.object-home .art__key { bottom: 6cqw; justify-content: flex-start; gap: 1.4em; }
.object-home .art__key span { display: inline-flex; align-items: center; gap: 0.5em; }
.object-home .art__key span::before { content: ''; width: 0.75em; height: 0.75em; border-radius: 50%; background: currentColor; }
.object-home .art__key .is-ring::before { background: none; box-shadow: inset 0 0 0 1.5px currentColor; }
.object-home .art__key .is-dash::before { width: 0.9em; height: 0.22em; border-radius: 2px; background: var(--ink); }
.object-home .art__key .is-rust::before { background: var(--rust); }
.object-home .art__key .is-cell::before { border-radius: 2px; background: none; box-shadow: inset 0 0 0 1px currentColor; }

/* 01 Verify: a list of addresses; the scan bar passes and leaves them verified or struck out. */
.object-home .poster__cover { --scan: 50%; --reach: 37%; }
.object-home .art--clean { clip-path: inset(0 calc(100% - var(--scan)) 0 0); transition: clip-path 1.3s var(--ease); }
.object-home .art__scan {
  position: absolute; top: 16.5%; height: 72%; left: var(--scan); width: 1.6%; translate: -50% 0;
  border-radius: 99px; background: var(--ink); transition: left 1.3s var(--ease);
}
/* 02 Reach: outreach rings from the rust dot; every prospect inside the reach is filled. */
.object-home .art--reach { clip-path: circle(var(--reach) at 25% 78%); transition: clip-path 1.4s var(--ease); }
.object-home .art .rings { transform-box: view-box; transform-origin: 100px 390px; transition: transform 1.4s var(--ease); }
/* 03 Book: leads narrow through the funnel and the rust dot drops into a calendar slot. */
.object-home .art .funnel rect { transform-box: fill-box; transform-origin: 50% 50%; transition: transform 900ms var(--ease) calc(var(--i) * 70ms); }
.object-home .art .lead { transition: transform 1.1s var(--ease), opacity 400ms var(--ease); }
.object-home .art .slot { transition: stroke 400ms var(--ease), stroke-opacity 400ms var(--ease); }

.js .object-home .poster:not(.is-in) .poster__cover { --scan: 6%; --reach: 3%; }
.js .object-home .poster:not(.is-in) .rings { transform: scale(0.55); }
.js .object-home .poster:not(.is-in) .funnel rect { transform: scaleX(0); }
.js .object-home .poster:not(.is-in) .lead { transform: translateY(-200px); opacity: 0; }
.object-home .poster.is-in .lead { transition-delay: 450ms, 450ms; }
.object-home .poster:is(:hover, :focus-visible) .poster__cover { --scan: 93%; --reach: 72%; }
.object-home .poster:is(:hover, :focus-visible) .rings { transform: scale(1.12); }
.object-home .poster:is(:hover, :focus-visible) .lead { transform: translateY(104px); transition-delay: 0ms; }
.object-home .poster:is(:hover, :focus-visible) .slot { stroke: var(--rust); stroke-opacity: 1; }
.object-home .poster__meta { display: flex; gap: 0.4rem; margin-top: 0.7rem; }
.object-home .tag { border: 1px solid var(--line-strong); border-radius: 999px; padding: 0.15em 0.65em; font-size: 0.76rem; color: var(--text-2); }
.object-home .poster h3 { font: 500 clamp(1.4rem, 1.9vw, 1.75rem)/1.1 var(--display); letter-spacing: -0.035em; }
.object-home .poster:hover h3 { color: var(--rust); }
.object-home .poster p { color: var(--text-2); font-size: 0.97rem; }
.object-home .poster__foot { display: flex; justify-content: space-between; gap: 1rem; padding-top: 0.85rem; border-top: 1px solid var(--line-strong); font-size: 0.84rem; color: var(--muted); font-family: var(--mono); }

/* ── Principles ────────────────────────────────────────────────────────── */

.object-home .principles { padding: clamp(3rem, 6vw, 5rem) 0 clamp(5rem, 9vw, 8rem); }
.object-home .principle-list { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 2rem clamp(1.5rem, 3vw, 2.5rem); counter-reset: rule; }
.object-home .principle-list li { counter-increment: rule; border-top: 2px solid var(--ink); padding-top: 1.25rem; transition: border-color 300ms var(--ease); }
.object-home .principle-list li:hover { border-top-color: var(--rust); }
.object-home .principle-list li::before {
  content: counter(rule, decimal-leading-zero); display: block; margin-bottom: 2.6rem;
  font: 500 clamp(3rem, 5vw, 4.6rem)/0.8 var(--display); letter-spacing: -0.05em;
  color: transparent; -webkit-text-stroke: 1.2px var(--ink); transition: color 400ms var(--ease);
}
.object-home .principle-list li:hover::before { color: var(--rust); -webkit-text-stroke-color: var(--rust); }
.object-home .principle-list h3 { font: 500 clamp(1.25rem, 1.6vw, 1.5rem)/1.1 var(--display); letter-spacing: -0.03em; margin-bottom: 0.5rem; }
.object-home .principle-list p { color: var(--text-2); font-size: 0.97rem; }

/* ── Journal ───────────────────────────────────────────────────────────── */

.object-home .journal { padding: clamp(3rem, 6vw, 5rem) 0 clamp(5rem, 9vw, 8rem); }
.object-home .journal__grid, .object-home .faq__grid { display: grid; grid-template-columns: minmax(0, 0.8fr) minmax(0, 1.2fr); column-gap: clamp(2rem, 6vw, 6rem); align-items: start; }
.object-home .journal__grid .section-head, .object-home .faq__grid .section-head { display: block; position: sticky; top: 7rem; margin: 0; }
.object-home .journal__grid .section-head h2, .object-home .faq__grid .section-head h2 { margin-top: 0.9rem; }
.object-home .post-list li { border-top: 1px solid var(--line-strong); }
.object-home .post-list a { position: relative; display: grid; gap: 0.5rem; padding: 1.4rem 3.5rem 1.6rem 0; }
.object-home .post-list a::after {
  content: '→'; position: absolute; right: 0.2rem; top: 50%; translate: -0.8rem -50%; opacity: 0;
  font: 400 1.6rem/1 var(--sans); color: var(--rust); transition: translate 500ms var(--ease), opacity 300ms var(--ease);
}
.object-home .post-list a:hover::after, .object-home .post-list a:focus-visible::after { translate: 0 -50%; opacity: 1; }
.object-home .post__meta { font-size: 0.85rem; color: var(--muted); }
.object-home .post-list h3 { font: 500 clamp(1.35rem, 1.9vw, 1.75rem)/1.12 var(--display); letter-spacing: -0.03em; }
.object-home .post-list a:hover h3 { text-decoration: underline; text-decoration-color: var(--rust); text-decoration-thickness: 2px; text-underline-offset: 0.18em; }
.object-home .post-list p { color: var(--text-2); max-width: 36rem; }

/* ── FAQ ───────────────────────────────────────────────────────────────── */

.object-home .faq { padding: clamp(3rem, 6vw, 5rem) 0 clamp(5rem, 9vw, 8rem); }
.object-home .faq-list { border-bottom: 1px solid var(--line-strong); }
.object-home .faq-list details { border-top: 1px solid var(--line-strong); }
.object-home .faq-list summary {
  list-style: none; cursor: pointer; padding: 1.35rem 0; display: flex; justify-content: space-between; gap: 1rem; align-items: center;
  font: 500 clamp(1.15rem, 1.5vw, 1.4rem)/1.2 var(--display); letter-spacing: -0.025em;
}
.object-home .faq-list summary::-webkit-details-marker { display: none; }
.object-home .faq-list summary::after { content: '+'; font-family: var(--sans); font-weight: 300; font-size: 1.6rem; color: var(--rust); transition: transform 300ms var(--ease); }
.object-home .faq-list details[open] summary::after { transform: rotate(45deg); }
.object-home .faq-list summary:hover { color: var(--rust); }
.object-home .faq-list details[open] summary { color: var(--ink); }
.object-home .faq-list p { padding: 0 0 1.5rem; color: var(--text-2); max-width: 42rem; }

/* ── The close ─────────────────────────────────────────────────────────── */

.object-home .close { padding: clamp(4rem, 8vw, 7rem) 0 clamp(5rem, 10vw, 9rem); }
.object-home .close .container { position: relative; border-top: 2px solid var(--ink); padding-top: clamp(2.5rem, 6vw, 5rem); }

/* The call badge: the rust dot with the offer set round it. Scroll turns the ring. */
.object-home .badge {
  position: absolute; right: 0; top: clamp(4rem, 9vw, 8rem);
  display: grid; place-items: center; width: clamp(9rem, 14vw, 12.5rem); aspect-ratio: 1;
}
.object-home .badge__ring { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible; }
.object-home .badge__ring text { font: 500 15px var(--mono); letter-spacing: 0.06em; text-transform: uppercase; fill: var(--ink); }
.object-home .badge__dot {
  display: grid; place-items: center; width: 50%; aspect-ratio: 1; border-radius: 50%;
  background: var(--rust); color: var(--paper); font: 400 clamp(1.6rem, 2.4vw, 2.2rem)/1 var(--sans);
  transition: scale 600ms var(--ease), background-color 300ms var(--ease);
}
.object-home .badge__dot span { display: block; transition: rotate 600ms var(--ease); }
.object-home .badge:hover .badge__dot { scale: 1.1; background: var(--ink); }
.object-home .badge:hover .badge__dot span { rotate: 45deg; }
.object-home .close h2 { font-size: clamp(2.8rem, 7.4vw, 7.8rem); letter-spacing: -0.05em; line-height: 0.92; margin-top: 1.2rem; max-width: 13ch; }
.object-home .close__body { margin-top: 1.5rem; font-size: 1.15rem; color: var(--text-2); max-width: 34rem; }

/* ── The poster cursor: a disc that says where the poster goes (mouse only, added by script) ── */

/* GSAP moves the outer element; CSS scales the inner disc (GSAP would fold a `scale` on its own
   target into the transform it writes, and the transition would never run). */
.object-home .cursor { position: fixed; left: 0; top: 0; z-index: 70; pointer-events: none; }
.object-home .cursor span {
  display: grid; place-items: center; width: 5.5rem; height: 5.5rem; margin: -2.75rem 0 0 -2.75rem; border-radius: 50%;
  background: var(--ink); color: var(--paper); font: 500 0.74rem/1 var(--mono); letter-spacing: 0.06em; text-transform: uppercase;
  scale: 0; transition: scale 500ms var(--ease), background-color 300ms var(--ease);
}
.object-home .cursor.is-on span { scale: 1; }
.object-home .cursor:is([data-tone='ink'], [data-tone='slate']) span { background: var(--rust); }

/* ── Responsive ────────────────────────────────────────────────────────── */

@media (max-width: 1000px) {
  .object-home .principle-list { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .object-home .poster-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 900px) {
  .object-home .hero { padding: 7rem 0 52svh; align-items: start; }
  .object-home .hero__grid { grid-template-columns: 1fr; }
  .object-home .hero__fallback { position: absolute; left: 50%; bottom: 3rem; translate: -50% 0; width: min(60vw, 18rem); }
  .object-home .section-head, .object-home .journal__grid, .object-home .faq__grid, .object-home .model__grid { display: block; }
  .object-home .section-head h2, .object-home .journal__grid .section-head h2 { margin-top: 0.9rem; }
  .object-home .journal__grid .section-head, .object-home .faq__grid .section-head { position: static; margin-bottom: 2rem; }
  .object-home .service-list { grid-template-columns: 1fr; }
  .object-home .model__list { margin-top: 2rem; }
  .object-home .labels { display: none; }   /* on a phone the parts are labelled by the list that follows */
  .object-home .parts { height: 300vh; }
  /* no room for a column: Fazley guides from the bottom corner, reacting to the service mid-screen */
  .js:not(.guide-off) .object-home .services__body { display: block; }
  .js:not(.guide-off) .object-home .guide { position: fixed; top: auto; right: 0.25rem; bottom: 0.5rem; width: 6.5rem; height: 8.5rem; }
  .object-home .guide-bubble { max-width: 13rem; font-size: 0.86rem; }
  .object-home .badge { position: relative; top: auto; margin-top: 2.5rem; width: 8.5rem; }
  .object-home .principle-list li::before { margin-bottom: 1.4rem; }
}
@media (max-width: 600px) {
  .object-home .poster-grid, .object-home .principle-list { grid-template-columns: 1fr; }
  .object-home .hero__actions .btn { flex: 1 1 auto; }
  .object-home .model__phases i { display: none; }   /* the phase names stay; the notes need more width */
  .object-home .model__phases b { font-size: 0.68rem; }
}

/* ── Reduced motion ────────────────────────────────────────────────────── */

@media (prefers-reduced-motion: reduce) {
  .object-home *, .object-home *::before, .object-home *::after { animation-duration: 0.01ms !important; transition-duration: 0.01ms !important; }
  .object-home .wait .eyebrow, .object-home .wait .hero__sub, .object-home .wait .hero__actions, .object-home .wait .hero__facts, .object-home .wait .lede { opacity: 1; translate: none; }
  .object-home .hero__hint { display: none; }
  .object-home .parts { height: auto; }
  .object-home .parts__sticky { position: static; height: auto; padding: clamp(4rem, 8vw, 7rem) 0 0; }
  .object-home .bridge { display: none; }
  .object-home .glyph * { animation: none !important; }
}

/* ── Inside the site layout ────────────────────────────────────────────── */

/* The design's fixed layers (the stage, the labels, Fazley, the grain) stay inside this box:
   the clip keeps them off the site header and footer, isolation keeps their z-indexes local.
   The clip stops 1px short of the bottom: its edge is anti-aliased at fractional positions
   while the sections' paper snaps to whole pixels, and the canvas showed through between. */
.object-home { position: relative; isolation: isolate; clip-path: inset(0 0 1px 0); font-synthesis-weight: auto; }

/* The site header sits in the flow above the hero, where the design's own header floated over
   it, so the hero gives that height back and still fills the first screen. */
.object-home { --site-header-h: 4.45rem; }
.object-home .hero { min-height: calc(100svh - var(--site-header-h)); padding-top: calc(9rem - var(--site-header-h)); }
@media (max-width: 900px) {
  .object-home .hero { padding-top: calc(7rem - var(--site-header-h)); }
}

/* The platform styles some of the same class names and every heading. Its layer loses to the
   rules above wherever they set a property; these put back the few they leave unset. */
.object-home :where(h1, h2, h3, h4, h5, h6) { font-weight: revert; line-height: revert; letter-spacing: revert; text-wrap: revert; }
.object-home :where(.eyebrow) { font-family: inherit; letter-spacing: normal; text-transform: none; }
.object-home :where(.btn) { background: none; color: inherit; }
.object-home :where(.btn:hover, .btn:active) { transform: none; }
.object-home :where(.hero) { border: 0; }
.object-home :where(.section-head) { max-width: none; }
.object-home :where(.marquee) { border: 0; mask-image: none; }
.object-home :where(.tag) { font-family: inherit; background: none; }
.object-home :where(.faq-list) { display: block; gap: normal; max-width: none; }
.object-home :where(.badge) { gap: 0; border: 0; border-radius: 0; background: none; font: inherit; letter-spacing: normal; color: inherit; white-space: normal; }
