/* ==========================================================================
   SiteYourStory — scenes
   Compositions inside the continuous space. No card grids, no slide framing.
   Structure is carried by type, hairlines and position — not by boxes.
   ========================================================================== */

/* --- Opening -------------------------------------------------------------
   One continuous shot: the mark holds the frame alone, then gives way to the
   statement as you scroll. Driven by --p (see app.js phases).
   ---------------------------------------------------------------------- */

.opening {
  height: 230svh;
  position: relative;
}

.opening-stage {
  position: sticky;
  top: 0;
  height: 100svh;
  display: grid;
  place-items: center;
  padding-inline: var(--gutter);
}

.opening-layer {
  grid-area: 1 / 1;
  width: 100%;
  max-width: var(--measure);
  will-change: opacity, transform;
}

/* Overture: the mark, given room. Hands over early (--p 0 → 0.26) so the
   statement is fully legible for most of the opening's scroll span rather than
   sitting half-faded through it. */
.overture {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 30px;
  text-align: center;
  opacity: clamp(0, calc((0.26 - var(--p, 0)) / 0.18), 1);
  transform: translate3d(0, calc(var(--p, 0) * -40px), 0)
    scale(calc(1 - var(--p, 0) * 0.06));
}

.overture-mark {
  display: inline-flex;
  align-items: baseline;
  font-size: clamp(1.9rem, 4.6vw, 3.4rem);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 1;
}
.overture-mark .logo-dot {
  width: clamp(7px, 0.85vw, 11px);
  height: clamp(7px, 0.85vw, 11px);
  margin-left: 4px;
  transform: translateY(-2px);
}

.overture-note {
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* Statement: resolves in as the mark leaves, settled by --p 0.44 */
.statement {
  opacity: clamp(0, calc((var(--p, 0) - 0.22) / 0.22), 1);
  transform: translate3d(0, calc((1 - min(var(--p, 0) / 0.44, 1)) * 44px), 0);
}

.statement-head {
  font-size: var(--t-display);
  font-weight: 800;
  line-height: 0.93;
  letter-spacing: -0.048em;
  max-width: 19ch;
}

.statement-foot {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  justify-content: space-between;
  gap: 28px;
  margin-top: clamp(28px, 4vh, 52px);
  padding-top: 22px;
  border-top: 1px solid var(--line);
}
.statement-sub {
  font-size: var(--t-body);
  color: var(--ink-2);
  max-width: 40ch;
}

/* The cue sits at the foot of the opening and leaves once you move. */
.opening-cue {
  position: absolute;
  left: 50%;
  bottom: clamp(22px, 4vh, 44px);
  transform: translateX(-50%);
  opacity: clamp(0, calc((0.16 - var(--p, 0)) / 0.16), 1);
}

/* --- Stats: placed in the space, never a dashboard ---------------------- */

.stats-field {
  position: relative;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
  gap: clamp(30px, 5vw, 76px) clamp(20px, 3vw, 44px);
  align-items: end;
}

.stat {
  position: relative;
  padding-top: 18px;
  border-top: 1px solid var(--line);
}
/* Offsets break the row into a composition rather than a strip of tiles. */
.stat:nth-child(2) { transform: translateY(clamp(0px, 3vw, 38px)); }
.stat:nth-child(3) { transform: translateY(clamp(0px, 1.4vw, 16px)); }
.stat:nth-child(4) { transform: translateY(clamp(0px, 4.4vw, 56px)); }

.stat-num {
  display: block;
  font-size: clamp(2.6rem, 5.6vw, 4.9rem);
  font-weight: 800;
  line-height: 0.9;
  letter-spacing: -0.05em;
  font-variant-numeric: tabular-nums;
}
.stat-unit {
  color: var(--accent-text);
}
.stat-label {
  display: block;
  margin-top: 12px;
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
}

/* --- Wide editorial pairing (used across pages) ------------------------- */

.pair {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 40px);
  align-items: start;
}
.pair-head {
  grid-column: 1 / span 7;
}
.pair-body {
  grid-column: 9 / span 4;
  padding-top: 10px;
}
@media (max-width: 900px) {
  .pair-head { grid-column: 1 / -1; }
  .pair-body { grid-column: 1 / -1; }
}

/* --- Transform list: static site → what it becomes ---------------------- */
/* Reads as a sequence of states, not a set of features. */

.states {
  margin-top: clamp(38px, 6vh, 76px);
  border-top: 1px solid var(--line);
}
.state {
  display: flex;
  align-items: baseline;
  gap: clamp(14px, 2.4vw, 40px);
  padding: clamp(16px, 2.4vh, 26px) 0;
  border-bottom: 1px solid var(--line);
}
.state-i {
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink-3);
  min-width: 3ch;
  font-variant-numeric: tabular-nums;
}
.state-word {
  font-size: clamp(1.5rem, 3.6vw, 3rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1;
}
.state-note {
  margin-left: auto;
  font-size: var(--t-meta);
  color: var(--ink-3);
  text-align: right;
  max-width: 26ch;
}
@media (max-width: 720px) {
  .state { flex-wrap: wrap; gap: 8px 16px; }
  .state-note { margin-left: 0; text-align: left; width: 100%; }
}

/* --- Speed ------------------------------------------------------------- */

.score {
  display: flex;
  align-items: flex-start;
  gap: clamp(14px, 2vw, 26px);
}
.score-num {
  font-size: clamp(5.5rem, 20vw, 17rem);
  font-weight: 800;
  line-height: 0.82;
  letter-spacing: -0.06em;
  font-variant-numeric: tabular-nums;
}
.score-meta {
  padding-top: clamp(10px, 1.6vw, 22px);
}
.score-label {
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.17em;
  text-transform: uppercase;
  color: var(--ink-3);
  display: block;
}
.score-rule {
  margin-top: 14px;
  width: clamp(60px, 12vw, 150px);
  height: 1px;
  background: var(--line);
  position: relative;
  overflow: hidden;
}
.score-rule::after {
  content: '';
  position: absolute;
  inset: 0;
  background: var(--accent);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform 1.6s var(--ease) 0.2s;
}
.is-in .score-rule::after {
  transform: scaleX(1);
}

/* --- Panels: the one place glass is used as a material ------------------ */

.panel {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--glass);
  backdrop-filter: blur(20px) saturate(130%);
  -webkit-backdrop-filter: blur(20px) saturate(130%);
  overflow: hidden;
}

/* Marks demonstration content so it is never mistaken for a real client. */
.example-tag {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  font-size: 0.62rem;
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-3);
  margin-bottom: 14px;
}
.example-tag::before {
  content: '';
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ink-3);
}

/* Search environment */
.serp {
  max-width: 640px;
  padding: 0;
}
.serp-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 14px 18px;
  border-bottom: 1px solid var(--line);
  font-size: 0.86rem;
  color: var(--ink-2);
}
.serp-bar svg {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
  opacity: 0.5;
}
.serp-list {
  padding: 6px 0;
}
.serp-item {
  padding: 15px 18px;
  border-bottom: 1px solid var(--line-2);
  opacity: 0.42;
  transition: opacity 0.7s var(--ease), background-color 0.7s var(--ease);
}
.serp-item:last-child { border-bottom: 0; }
.serp-item.is-first {
  opacity: 1;
  background: color-mix(in oklab, var(--accent) 5%, transparent);
}
.serp-url {
  font-size: 0.72rem;
  color: var(--ink-3);
  letter-spacing: 0.01em;
}
.serp-item.is-first .serp-url { color: var(--accent-text); }
.serp-title {
  font-size: 0.98rem;
  font-weight: 600;
  margin-top: 3px;
  letter-spacing: -0.015em;
}
.serp-desc {
  font-size: 0.8rem;
  color: var(--ink-3);
  margin-top: 3px;
  line-height: 1.5;
}

/* AI answer environment */
.ai {
  max-width: 620px;
  padding: 22px;
}
.ai-q {
  display: flex;
  gap: 11px;
  font-size: 0.94rem;
  font-weight: 600;
  letter-spacing: -0.015em;
  padding-bottom: 17px;
  border-bottom: 1px solid var(--line);
}
.ai-q::before {
  content: '';
  width: 3px;
  flex-shrink: 0;
  background: var(--ink-3);
  border-radius: 2px;
}
.ai-a {
  display: flex;
  gap: 11px;
  padding-top: 17px;
  font-size: 0.9rem;
  line-height: 1.65;
  color: var(--ink-2);
}
.ai-a::before {
  content: '';
  width: 3px;
  flex-shrink: 0;
  background: var(--accent);
  border-radius: 2px;
}
.ai-a strong {
  color: var(--ink);
  font-weight: 700;
}

/* --- Trust markers ----------------------------------------------------- */

.marks {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 12px;
  margin-top: clamp(26px, 4vh, 44px);
}
.mark {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 9px 17px;
  border: 1px solid var(--line);
  border-radius: 999px;
  font-size: var(--t-meta);
  font-weight: 500;
  color: var(--ink-2);
}
.mark-dot {
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--accent);
  flex-shrink: 0;
}

/* --- Screens (device proportions) -------------------------------------- */

.screens {
  display: flex;
  gap: clamp(18px, 3vw, 42px);
  align-items: baseline;
  margin-top: clamp(30px, 5vh, 56px);
}
.screen {
  font-size: clamp(1.15rem, 2.4vw, 1.9rem);
  font-weight: 800;
  letter-spacing: -0.035em;
  color: var(--ink-3);
  opacity: 0.4;
  transition: opacity 0.6s var(--ease), color 0.6s var(--ease);
}
.screen.is-active {
  opacity: 1;
  color: var(--ink);
}
.screen.is-active::after {
  content: '';
  display: block;
  height: 2px;
  margin-top: 8px;
  background: var(--accent);
}

/* --- Track: a tall scene that steps through items ---------------------- */

.track {
  position: relative;
}
.track-stage {
  position: sticky;
  top: 0;
  min-height: 100svh;
  display: flex;
  align-items: center;
  padding-block: clamp(80px, 12vh, 130px);
}

/* Process — numbered, one live at a time */
.steps {
  width: 100%;
  border-top: 1px solid var(--line);
}
.step {
  display: grid;
  grid-template-columns: 4.5rem 1fr;
  gap: clamp(14px, 2.6vw, 44px);
  padding: clamp(18px, 2.6vh, 30px) 0;
  border-bottom: 1px solid var(--line);
  opacity: 0.34;
  transition: opacity 0.7s var(--ease), transform 0.7s var(--ease);
}
.step.is-active {
  opacity: 1;
  transform: translateX(clamp(0px, 1vw, 12px));
}
.step-n {
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
  padding-top: 8px;
}
.step.is-active .step-n {
  color: var(--accent-text);
}
.step-t {
  font-size: clamp(1.35rem, 3.1vw, 2.5rem);
  font-weight: 800;
  letter-spacing: -0.04em;
  line-height: 1.05;
}
.step-d {
  margin-top: 8px;
  font-size: var(--t-body);
  color: var(--ink-2);
  max-width: 48ch;
  max-height: 0;
  opacity: 0;
  overflow: hidden;
  transition: max-height 0.8s var(--ease), opacity 0.6s var(--ease);
}
.step.is-active .step-d {
  max-height: 8rem;
  opacity: 1;
}
@media (max-width: 640px) {
  .step { grid-template-columns: 2.6rem 1fr; }
  .step-d { max-height: none; opacity: 1; }
}

/* --- Industry navigator ------------------------------------------------ */
/* One visual system: the environment shifts, the type stays disciplined. */

.industries {
  width: 100%;
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 40px);
  align-items: center;
}
.industry-list {
  grid-column: 1 / span 6;
  position: relative;
}
.industry {
  display: block;
  padding: clamp(5px, 0.9vh, 10px) 0;
  font-size: clamp(1.45rem, 4vw, 3.3rem);
  font-weight: 800;
  letter-spacing: -0.045em;
  line-height: 1.06;
  color: var(--ink);
  opacity: 0.22;
  transition: opacity 0.6s var(--ease), transform 0.7s var(--ease);
}
.industry.is-active {
  opacity: 1;
  transform: translateX(clamp(0px, 1.4vw, 18px));
}
.industry-detail {
  grid-column: 8 / span 5;
  position: relative;
  min-height: 12rem;
}
.industry-card {
  position: absolute;
  inset: 0;
  opacity: 0;
  transform: translateY(16px);
  transition: opacity 0.6s var(--ease), transform 0.7s var(--ease);
  pointer-events: none;
}
.industry-card.is-active {
  opacity: 1;
  transform: none;
  pointer-events: auto;
}
.industry-card .label {
  color: var(--accent-text);
}
.industry-card p {
  margin-top: 14px;
  color: var(--ink-2);
  max-width: 40ch;
}
.industry-traits {
  display: flex;
  flex-wrap: wrap;
  gap: 7px;
  margin-top: 20px;
}
.industry-traits span {
  font-size: 0.68rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ink-3);
  padding: 6px 12px;
  border: 1px solid var(--line);
  border-radius: 999px;
}

/* Optional art plate inside a card — mounted by app.js only if the file under
   assets/img/industries/ actually loads. The card is complete without it. */
.industry-plate {
  margin-top: 22px;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--line);
  max-width: 300px;
  opacity: 0;
  transform: translateY(10px);
  transition: opacity 0.9s var(--ease), transform 0.9s var(--ease);
}
.industry-plate.is-mounted {
  opacity: 1;
  transform: none;
}
.industry-plate img {
  display: block;
  width: 100%;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  filter: saturate(0.82) contrast(1.04);
}
@media (max-width: 900px) {
  .industries { display: block; }
  .industry-list { margin-bottom: 26px; }
  .industry-detail { min-height: 15rem; }
  .industry { font-size: clamp(1.35rem, 7vw, 2rem); }
}

/* --- Capability rows (Work / Services) --------------------------------- */

.rows {
  border-top: 1px solid var(--line);
}
.row {
  display: grid;
  grid-template-columns: 4.5rem 1fr auto;
  gap: clamp(14px, 2.6vw, 40px);
  align-items: baseline;
  padding: clamp(22px, 3.4vh, 40px) 0;
  border-bottom: 1px solid var(--line);
  transition: background-color 0.6s var(--ease);
}
.row-n {
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  color: var(--ink-3);
  font-variant-numeric: tabular-nums;
}
.row-t {
  font-size: clamp(1.5rem, 3.4vw, 2.9rem);
  font-weight: 800;
  letter-spacing: -0.042em;
  line-height: 1.04;
}
.row-d {
  margin-top: 10px;
  color: var(--ink-2);
  max-width: 52ch;
}
.row-meta {
  font-size: var(--t-meta);
  color: var(--ink-3);
  text-align: right;
  white-space: nowrap;
}
@media (max-width: 760px) {
  .row { grid-template-columns: 2.6rem 1fr; }
  .row-meta { grid-column: 2; text-align: left; margin-top: 10px; }
}

/* --- Close / CTA ------------------------------------------------------- */

.close-head {
  font-size: var(--t-display);
  font-weight: 800;
  line-height: 0.94;
  letter-spacing: -0.048em;
  max-width: 17ch;
}

.close-grid {
  display: grid;
  grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(28px, 4vw, 64px);
  align-items: start;
  margin-top: clamp(44px, 7vh, 88px);
}
.close-say {
  grid-column: 1 / span 5;
}
.close-form {
  grid-column: 7 / span 6;
}
@media (max-width: 960px) {
  .close-say, .close-form { grid-column: 1 / -1; }
}

/* --- Form -------------------------------------------------------------- */

.form {
  display: flex;
  flex-direction: column;
  gap: 18px;
}
.field {
  display: flex;
  flex-direction: column;
  gap: 8px;
}
.field label {
  font-size: var(--t-label);
  font-weight: 600;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ink-3);
}
.field input,
.field select {
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: color-mix(in oklab, var(--paper) 92%, var(--ink) 8%);
  color: var(--ink);
  font-size: 0.96rem;
  transition: border-color 0.3s var(--ease), background-color 0.3s var(--ease);
}
.field input::placeholder {
  color: var(--ink-3);
  opacity: 0.75;
}

/* A textarea falls through the input/select selectors above and lands on the
   browser default — a white box with light text, unreadable on the dark
   ground. It takes the same treatment, plus a vertical-only resize. */
.field textarea {
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: color-mix(in oklab, var(--paper) 92%, var(--ink) 8%);
  color: var(--ink);
  font-family: inherit;
  font-size: 0.96rem;
  line-height: 1.55;
  min-height: 116px;
  resize: vertical;
  transition: border-color 0.3s var(--ease), background-color 0.3s var(--ease);
}
.field textarea::placeholder { color: var(--ink-3); opacity: 0.75; }
.field textarea:focus { outline: none; border-color: var(--accent); }

.field input:focus,
.field select:focus {
  outline: none;
  border-color: var(--accent);
}
.field select {
  appearance: none;
  background-image: linear-gradient(45deg, transparent 50%, currentColor 50%),
    linear-gradient(135deg, currentColor 50%, transparent 50%);
  background-position: calc(100% - 19px) calc(50% + 1px),
    calc(100% - 14px) calc(50% + 1px);
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  padding-right: 40px;
}

/* The site-URL question only appears once it applies. */
.field-url {
  display: grid;
  grid-template-rows: 0fr;
  opacity: 0;
  transition: grid-template-rows 0.55s var(--ease), opacity 0.4s var(--ease),
    margin-top 0.55s var(--ease);
  margin-top: -18px;
}
.field-url > div {
  overflow: hidden;
  min-height: 0;
}
.field-url.show {
  grid-template-rows: 1fr;
  opacity: 1;
  margin-top: 0;
}

.form-note {
  font-size: var(--t-meta);
  color: var(--ink-3);
}
.form-status {
  font-size: var(--t-meta);
  color: var(--ink-3);
  min-height: 1.2em;
}
.form-status.is-error {
  color: var(--accent-text);
}
.form-status a {
  color: var(--accent-text);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.form-done {
  font-size: var(--t-body-l);
  font-weight: 700;
  letter-spacing: -0.02em;
  color: var(--accent-text);
  padding: 22px 0;
}
.form .btn {
  align-self: flex-start;
}

.reach {
  margin-top: 26px;
  padding-top: 22px;
  border-top: 1px solid var(--line);
  font-size: var(--t-meta);
  color: var(--ink-3);
}
.reach a {
  color: var(--accent-text);
  font-weight: 600;
}
.reach a:hover {
  text-decoration: underline;
  text-underline-offset: 3px;
}

/* --- Page opening (inner pages) ---------------------------------------- */

.page-head {
  min-height: 78svh;
  display: flex;
  align-items: flex-end;
  padding-bottom: clamp(40px, 7vh, 90px);
  padding-top: clamp(120px, 18vh, 200px);
}
.page-head-in {
  width: 100%;
}
.page-title {
  font-size: var(--t-display);
  font-weight: 800;
  line-height: 0.93;
  letter-spacing: -0.048em;
  max-width: 18ch;
}
.page-lede {
  margin-top: clamp(22px, 3.4vh, 40px);
  padding-top: 22px;
  border-top: 1px solid var(--line);
  font-size: var(--t-body-l);
  color: var(--ink-2);
  max-width: 52ch;
}

/* --- Quiet statement scene (used to break rhythm) ---------------------- */

.utter {
  min-height: 88svh;
  display: grid;
  place-items: center;
  text-align: center;
}
.utter p {
  font-size: var(--t-head);
  font-weight: 800;
  letter-spacing: -0.042em;
  line-height: 1.06;
  max-width: 24ch;
}

/* --- Reduced motion ---------------------------------------------------- */

@media (prefers-reduced-motion: reduce) {
  /* Hold the opening composed rather than mid-crossfade. */
  .opening { height: auto; }
  .opening-stage {
    position: relative;
    height: auto;
    display: block;
    padding-block: clamp(120px, 18vh, 190px) clamp(60px, 9vh, 100px);
  }
  /* grid-area goes inert once the stage is no longer a grid, so the layers
     need no display override here — overriding it would flatten .overture's
     own flex column. */
  .overture {
    opacity: 1;
    transform: none;
    align-items: flex-start;
    text-align: left;
    margin-bottom: 56px;
  }
  .statement {
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
  .opening-cue { display: none; }

  .track-stage { position: relative; min-height: 0; }
  .step, .industry, .screen { opacity: 1; }
  .step-d { max-height: none; opacity: 1; }
  .industry-card {
    position: relative;
    opacity: 1;
    transform: none;
    pointer-events: auto;
  }
  .industry-card + .industry-card { margin-top: 30px; }
  .industry-detail { min-height: 0; }
  .stat:nth-child(n) { transform: none; }
  .score-rule::after { transform: scaleX(1); }
}

/* ==========================================================================
   DEPTH — true parallax staging
   A stage holds layers at different depths; app.js moves each at its own rate.
   Layers are inert scenery: never interactive, never in the tab order.
   ========================================================================== */

.stage {
  position: relative;
  isolation: isolate;
}

.layer {
  position: absolute;
  inset: 0;
  pointer-events: none;
  will-change: transform;
  z-index: 0;
}
/* Layers overshoot the stage so a parallax offset can never expose an edge. */
.layer--bleed {
  inset: -18% -6%;
}
.stage > .stage-content {
  position: relative;
  z-index: 3;
  will-change: transform;
}

/* --------------------------------------------------------------------------
   PLATES — the visual material, drawn rather than photographed.
   Every plate is built from the brand palette so the whole set reads as one
   campaign, and each one carries an actual material idea rather than being a
   decorative gradient.
   -------------------------------------------------------------------------- */

.plate {
  position: absolute;
  inset: 0;
  overflow: hidden;
  border-radius: 2px;
}

/* A soft-edged rectangle. Every plate uses this: a hard rectangular boundary
   is what makes a drawn plate read as a grey box instead of as a photograph of
   a surface, and it is the single thing that gives these away. */
.plate {
  -webkit-mask-image:
    linear-gradient(90deg, transparent 0, #000 14%, #000 86%, transparent 100%),
    linear-gradient(180deg, transparent 0, #000 16%, #000 84%, transparent 100%);
  -webkit-mask-composite: source-in;
  mask-image:
    linear-gradient(90deg, transparent 0, #000 14%, #000 86%, transparent 100%),
    linear-gradient(180deg, transparent 0, #000 16%, #000 84%, transparent 100%);
  mask-composite: intersect;
}

/* A fine architectural grid, faded with distance. The technical substrate. */
.plate--grid {
  background:
    repeating-linear-gradient(90deg,
      color-mix(in oklab, var(--ink) 20%, transparent) 0 1px, transparent 1px 84px),
    repeating-linear-gradient(0deg,
      color-mix(in oklab, var(--ink) 20%, transparent) 0 1px, transparent 1px 84px);
  -webkit-mask-image: radial-gradient(70% 70% at 50% 45%, #000 0%, transparent 78%);
  mask-image: radial-gradient(70% 70% at 50% 45%, #000 0%, transparent 78%);
  -webkit-mask-composite: source-in;
  mask-composite: intersect;
  opacity: 0.6;
}

/* Atmospheric haze that sits between depth layers and softens the stack. */
.plate--haze {
  background: radial-gradient(75% 60% at 50% 50%,
    color-mix(in oklab, var(--paper) 62%, transparent) 0%, transparent 70%);
}

/* An optional photographic plate. Mounted by app.js only when a real file
   loads, so a missing asset leaves the drawn plates doing the work instead of
   a blank rectangle. */
.plate--photo {
  background-position: center;
  background-size: cover;
  opacity: 0;
  transition: opacity 1.2s var(--ease-io);
}
.plate--photo.is-loaded {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .layer,
  .stage > .stage-content {
    transform: none !important;
    will-change: auto;
  }
}

/* --- Chapter: a scene carried by its visual layers ---------------------- */

.chapter {
  min-height: 124svh;
  display: flex;
  align-items: center;
  overflow: hidden;
}
.chapter-copy {
  max-width: 34ch;
}
/* Its own step down the scale: the display size belongs to the opening, and at
   this column width it fragments into too many lines. */
.chapter-copy .head {
  font-size: clamp(1.9rem, 3.5vw, 3.3rem);
}
/* The turn in the sentence gets the weight, not a second heading. */
.chapter-turn {
  margin-top: clamp(20px, 3vh, 34px);
  font-size: var(--t-sub);
  font-weight: 700;
  line-height: 1.16;
  letter-spacing: -0.028em;
  color: var(--accent-text);
  max-width: 26ch;
}
.chapter-copy .body {
  margin-top: clamp(18px, 2.6vh, 28px);
}

@media (max-width: 900px) {
  /* Fewer, larger depth layers on small screens: the fine grid and the haze
     stop reading at this size and only cost fill rate. */
  .chapter { min-height: 104svh; }
  .chapter .layer[data-depth="0.26"],
  .chapter .layer[data-depth="0.44"] { display: none; }
  .chapter-copy { max-width: 100%; }
}


/* --- Media plates ------------------------------------------------------- */
/* Mounted by initMedia() only when a real file loads. Empty sockets have no
   styling at all, so an absent asset leaves no trace. */

.media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  opacity: 0;
  transition: opacity 1.4s var(--ease-io);
}
.media.is-mounted {
  opacity: 1;
}
.media > img,
.media > video {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.media--contain > img,
.media--contain > video {
  object-fit: contain;
}

/* Footage sits behind the words, so it is graded down and the ground colour is
   allowed to come through it. Without this the type stops being readable the
   moment a real image lands. */
.layer .media {
  opacity: 0;
}
.layer .media.is-mounted {
  opacity: 0.62;
}
.layer .media > img,
.layer .media > video {
  filter: saturate(0.72) contrast(1.04);
}
[data-env-zone='dark'] .layer .media.is-mounted {
  opacity: 0.5;
}

/* An industry card's plate: a fixed editorial crop under the copy. */
.industry-card .media {
  position: relative;
  inset: auto;
  margin-top: 22px;
  aspect-ratio: 3 / 2;
  border-radius: 3px;
}
.industry-card .media.is-mounted {
  opacity: 1;
}

/* Hero footage socket: the deepest plane of the opening, pinned behind the
   sticky stage so the mark and statement always sit in front of it. */
.opening-media {
  position: sticky;
  top: 0;
  height: 100svh;
  margin-bottom: -100svh; /* takes no space; the stage owns the layout */
  overflow: hidden;
  z-index: 0;
}
.opening-media .media.is-mounted {
  opacity: 0.42;
}
/* A scrim between the footage and the words. Without it, whatever footage
   lands here decides the headline's contrast — and mid-tone footage drops it
   below legible. Weighted to the left and bottom, where the type actually
   sits, so the open right side of the frame keeps the picture. */
.opening-media::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  pointer-events: none;
  background:
    linear-gradient(100deg,
      var(--paper) 0%,
      color-mix(in oklab, var(--paper) 88%, transparent) 30%,
      color-mix(in oklab, var(--paper) 46%, transparent) 62%,
      color-mix(in oklab, var(--paper) 14%, transparent) 100%),
    linear-gradient(0deg, var(--paper) 0%, transparent 46%);
}
.opening-media .media > img,
.opening-media .media > video {
  filter: saturate(0.7) contrast(1.05);
}

/* A scene-level footage socket. Same contract as the hero: empty by default,
   scrimmed when filled so the copy's contrast never depends on the footage. */
.scene-media {
  position: absolute;
  inset: 0;
  overflow: hidden;
  z-index: 0;
  pointer-events: none;
}
.scene-media .media.is-mounted {
  opacity: 0.4;
}
.scene-media::after {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 2;
  background:
    linear-gradient(100deg,
      var(--paper) 0%,
      color-mix(in oklab, var(--paper) 86%, transparent) 32%,
      color-mix(in oklab, var(--paper) 40%, transparent) 66%,
      color-mix(in oklab, var(--paper) 10%, transparent) 100%);
}
.scene-media ~ .wrap,
.scene-media ~ * {
  position: relative;
  z-index: 1;
}

/* --- Convergence -------------------------------------------------------- */
/* A world-led scene. The type is deliberately one line and low-contrast-ish so
   the environment carries it — the opposite balance to every other scene, which
   is what makes the rhythm read as rhythm rather than as uniform dimming. */

.converge {
  position: relative;
  min-height: 126svh;
  display: flex;
  align-items: center;
}
/* The formation is centred here rather than pushed aside, so the copy needs its
   own ground. Left-weighted, so the structure keeps the middle and the right of
   the frame while the line stays solid. */
.converge::before {
  content: '';
  position: absolute;
  inset: 0;
  z-index: 0;
  pointer-events: none;
  background: linear-gradient(96deg,
    var(--paper) 0%,
    color-mix(in oklab, var(--paper) 92%, transparent) 26%,
    color-mix(in oklab, var(--paper) 44%, transparent) 46%,
    transparent 62%);
}
.converge > .wrap {
  position: relative;
  z-index: 1;
}
.converge-line {
  margin-top: clamp(20px, 3vh, 34px);
  font-size: clamp(1.6rem, 3.4vw, 3rem);
  font-weight: 800;
  line-height: 1.1;
  letter-spacing: -0.04em;
  max-width: 22ch;
}
.converge-line br {
  display: block;
}
@media (max-width: 640px) {
  .converge { min-height: 100svh; }
}
