/* ==========================================================================
   LIMAN — pinned product sequence
   Palette is pulled off the product itself: the can's navy, and the pale sage
   of the liquid as the only accent.
   ========================================================================== */

:root {
  --abyss: #05090f;
  --deep: #0a1220;
  --hull: #16233d;
  --foam: #eef2f6;
  --haze: #77869c;
  --signal: #bfcb94;

  --font-display: 'Archivo', system-ui, -apple-system, sans-serif;
  --font-mono: 'IBM Plex Mono', ui-monospace, 'SF Mono', monospace;

  --gutter: clamp(20px, 4vw, 56px);

  /* Written by the canvas renderer once it knows where the product landed. */
  --frame-left: 0px;
  --frame-top: 0px;
  --frame-width: 100%;
  --frame-height: 100%;
  --waterline: 82%;
}

*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  /* clip, never hidden: overflow:hidden on an ancestor kills position:sticky. */
  overflow-x: clip;
  scrollbar-gutter: stable;
  -webkit-text-size-adjust: 100%;
}

/* Smooth scroll (Lenis) drives the scroll position itself, so native smooth
   behaviour has to stay out of the way. These classes land on <html>. */
html.lenis,
html.lenis body {
  height: auto;
}

.lenis.lenis-smooth {
  scroll-behavior: auto !important;
}

.lenis.lenis-smooth [data-lenis-prevent] {
  overscroll-behavior: contain;
}

body {
  margin: 0;
  overflow-x: clip;
  background: var(--abyss);
  color: var(--foam);
  font-family: var(--font-display);
  font-synthesis-weight: none;
  -webkit-font-smoothing: antialiased;
}

img,
svg,
canvas {
  display: block;
  max-width: 100%;
}

p {
  margin: 0;
}

:focus-visible {
  outline: 2px solid var(--signal);
  outline-offset: 4px;
}

/* --- masthead ----------------------------------------------------------- */

.masthead {
  position: fixed;
  inset: 0 0 auto;
  z-index: 4;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: clamp(18px, 2.6vw, 30px) var(--gutter);
  pointer-events: none;
}

.masthead__mark {
  display: block;
  width: clamp(20px, 1.7vw, 26px);
  color: var(--foam);
  opacity: 0.9;
  pointer-events: auto; /* the mark is a link on the walkthrough page */
}

.masthead__spec {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--haze);
}

/* --- stage -------------------------------------------------------------- */

.stage {
  position: relative;
  height: 520vh;
  height: 520svh; /* svh, not dvh: a dvh section resizes as browser chrome hides */
}

.stage__pin {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
}

.stage__glow {
  position: absolute;
  inset: 0;
  background:
    radial-gradient(38% 42% at 50% 56%, rgba(46, 74, 124, 0.3), transparent 68%),
    radial-gradient(78% 46% at 50% 104%, rgba(12, 21, 38, 0.9), transparent 72%);
}

.stage__canvas {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 900ms ease;
}

.stage.is-ready .stage__canvas {
  opacity: 1;
}

/* --- copy beats --------------------------------------------------------- */

.beats {
  position: absolute;
  inset: 0;
  z-index: 1; /* behind the canvas: the can occludes the type, as it should */
  opacity: 0;
  transition: opacity 900ms ease 200ms;
}

.stage.is-ready .beats {
  opacity: 1;
}

.beat {
  position: absolute;
  opacity: 0;
  visibility: hidden;
  will-change: transform, opacity;
}

.beat__display {
  font-weight: 600;
  font-stretch: 112%; /* Archivo's width axis — the page's one type signature */
  line-height: 0.94;
  text-wrap: balance;
}

.beat__sub {
  margin-top: clamp(12px, 1.4vw, 20px);
  font-family: var(--font-mono);
  font-size: clamp(11px, 0.95vw, 14px);
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--haze);
}

/* --sub ile aynı ses, başlığın altında değil üstünde: bölümü tanıtır. */
.beat__eyebrow {
  margin: 0 0 clamp(10px, 1.2vw, 18px);
  font-family: var(--font-mono);
  font-size: clamp(10px, 0.85vw, 12px);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--signal);
}

/* Cümle değil, spesifikasyon — o yüzden gövde metninden bir tık geride durur. */
.beat__tags {
  margin-top: clamp(14px, 1.6vw, 22px);
  font-family: var(--font-mono);
  font-size: clamp(10px, 0.85vw, 12px);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(191, 203, 148, 0.72);
}

/* Opening and closing titles sit in the empty band above the sealed can, so the
   product is never covered. --product-top is where the can's lid begins. */
.beat--lead,
.beat--final {
  left: 0;
  right: 0;
  top: 0;
  height: var(--product-top, 30%);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
  text-align: center;
  padding: clamp(56px, 8vh, 96px) var(--gutter) clamp(14px, 2.4vh, 30px);
}

.beat--lead .beat__display {
  font-size: clamp(2.8rem, 8vw, 9rem);
  font-stretch: 118%;
  letter-spacing: 0.055em;
  margin-right: -0.055em; /* drop the trailing letter-space so the word centres true */
}

.beat--final .beat__display {
  font-size: clamp(1.9rem, 5vw, 5rem);
  letter-spacing: 0.045em;
  margin-right: -0.045em;
}

.beat--left,
.beat--right {
  top: var(--frame-top);
  height: var(--frame-height);
  width: min(560px, calc((100% - var(--frame-width)) / 2 - var(--gutter) * 1.4));
  display: flex;
  flex-direction: column;
  justify-content: center;
}

.beat--left {
  left: var(--gutter);
}

.beat--right {
  right: var(--gutter);
  text-align: right;
}

.beat--left .beat__display,
.beat--right .beat__display {
  font-size: clamp(2.4rem, 4.6vw, 5rem);
  font-weight: 500;
  font-stretch: 105%;
  letter-spacing: -0.015em;
  line-height: 0.98;
  color: var(--foam);
}

.beat__note {
  margin-top: clamp(16px, 1.8vw, 26px);
  max-width: 52ch; /* ~52 characters: 1ch is a digit, roughly half an em here */
  font-size: clamp(0.95rem, 1.2vw, 1.3rem);
  line-height: 1.5;
  color: var(--haze);
}

.beat--right .beat__note {
  margin-left: auto;
}

/* --- waterline + readout ------------------------------------------------ */

/* The signature: a horizon at the can's base. It grounds the product, and its
   centre-out fill is the only progress indicator on the page. */
.waterline {
  position: absolute;
  left: 0;
  right: 0;
  top: var(--waterline);
  z-index: 3;
  height: 1px;
  opacity: 0;
  transition: opacity 900ms ease 300ms;
  background: linear-gradient(
    90deg,
    transparent,
    rgba(119, 134, 156, 0.22) 16%,
    rgba(119, 134, 156, 0.22) 84%,
    transparent
  );
}

.waterline__fill {
  position: absolute;
  inset: 0;
  transform: scaleX(0);
  transform-origin: 50% 50%;
  background: linear-gradient(90deg, transparent, var(--signal) 34%, var(--signal) 66%, transparent);
  opacity: 0.9;
}

/* Page chrome, pinned to the bottom edge — deliberately not attached to the
   waterline, so the band under the product stays clear for copy. */
.statusbar {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(20px, 2.6vh, 30px);
  z-index: 3;
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: baseline;
  gap: 16px;
  padding: 0 var(--gutter);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--haze);
  opacity: 0;
  transition: opacity 900ms ease 300ms;
}

.stage.is-ready .waterline,
.stage.is-ready .statusbar {
  opacity: 1;
}

/* Columns are pinned so hiding the loader doesn't slide the readout inward. */
.statusbar__phase {
  grid-column: 1;
  color: var(--signal);
}

.statusbar__loader {
  grid-column: 2;
  justify-self: center;
}

.statusbar__readout {
  grid-column: 3;
  justify-self: end;
  font-variant-numeric: tabular-nums;
}

/* --- scroll hint -------------------------------------------------------- */

/* The one piece of instruction on the page: scroll is the transport control
   here, not just navigation. It leaves as soon as that has been understood. */
.scroll-hint {
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--waterline) + clamp(26px, 4vh, 52px));
  z-index: 3;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
  opacity: 0;
  visibility: hidden;
  pointer-events: none;
}

.scroll-hint__mouse {
  display: block;
  width: 26px;
  height: 42px;
  border: 1.5px solid rgba(191, 203, 148, 0.55);
  border-radius: 999px;
  position: relative;
  /* The body drifts with the wheel, so the whole thing reads as one gesture
     rather than a dot rattling inside a static outline. */
  animation: scroll-hint-body 2000ms cubic-bezier(0.45, 0, 0.25, 1) infinite;
}

.scroll-hint__mouse i {
  position: absolute;
  top: 8px;
  left: 50%;
  width: 4px;
  height: 4px;
  margin-left: -2px;
  border-radius: 50%;
  background: var(--signal);
  box-shadow: 0 0 8px rgba(191, 203, 148, 0.9);
  animation: scroll-hint-wheel 2000ms cubic-bezier(0.45, 0, 0.25, 1) infinite;
}

@keyframes scroll-hint-wheel {
  0% {
    transform: translateY(0);
    opacity: 0;
  }
  15% {
    opacity: 1;
  }
  60% {
    opacity: 1;
  }
  80% {
    transform: translateY(19px);
    opacity: 0;
  }
  100% {
    transform: translateY(19px);
    opacity: 0;
  }
}

@keyframes scroll-hint-body {
  0%,
  100% {
    transform: translateY(0);
  }
  55% {
    transform: translateY(5px);
  }
}

.scroll-hint__label {
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--haze);
}

/* On the walkthrough there is no product base to hang it from, so it tucks
   under the opening title, inside the radial scrim that keeps type readable. */
.stage--frame .scroll-hint {
  top: 64%;
}

.stage--frame .scroll-hint__label {
  color: rgba(238, 242, 246, 0.8);
  text-shadow: 0 1px 20px rgba(5, 9, 15, 0.9);
}

.stage--frame .scroll-hint__mouse {
  border-color: rgba(238, 242, 246, 0.6);
}

.stage.is-static .scroll-hint {
  display: none;
}

/* The wheel loop cannot be captured a frame at a time — it would freeze at an
   arbitrary phase, sometimes on an empty outline. See tools/record-scroll.mjs. */
[data-capture='on'] .scroll-hint {
  display: none;
}

[data-motion='reduced'] .scroll-hint__mouse,
[data-motion='reduced'] .scroll-hint__mouse i {
  animation: none;
  opacity: 1;
}

/* --- scroll reveals ----------------------------------------------------- */

/* Everything here is scoped to [data-motion='full'], an attribute only the
   motion module sets. So the hidden state cannot outlive the script that is
   supposed to undo it: no JS, or reduced motion, and the content is simply
   there. */
[data-motion='full'] [data-reveal] {
  opacity: 0;
  transform: translate3d(0, 30px, 0);
  transition:
    opacity 900ms cubic-bezier(0.16, 1, 0.3, 1) var(--reveal-delay, 0ms),
    transform 900ms cubic-bezier(0.16, 1, 0.3, 1) var(--reveal-delay, 0ms);
}

[data-motion='full'] [data-reveal].is-in {
  opacity: 1;
  transform: none;
}

/* Stagger lives here rather than in script, so the delays exist before the
   first paint along with the hidden state they belong to. */
[data-reveal-group] > *:nth-child(2) {
  --reveal-delay: 110ms;
}

[data-reveal-group] > *:nth-child(3) {
  --reveal-delay: 220ms;
}

[data-reveal-group] > *:nth-child(4) {
  --reveal-delay: 330ms;
}

[data-reveal-group] > *:nth-child(5) {
  --reveal-delay: 440ms;
}

[data-reveal-group] > *:nth-child(6) {
  --reveal-delay: 550ms;
}

/* Images uncover from their bottom edge upward — the vertical answer to the
   waterline drawing outward in the hero. */
[data-motion='full'] [data-reveal] figure,
[data-motion='full'] figure[data-reveal] {
  clip-path: inset(100% 0 0 0);
  transition: clip-path 1100ms cubic-bezier(0.16, 1, 0.3, 1) var(--reveal-delay, 0ms);
}

[data-motion='full'] [data-reveal].is-in figure,
[data-motion='full'] figure[data-reveal].is-in {
  clip-path: inset(0 0 0 0);
}

/* The frame lifts, the picture inside settles back — the two reaching rest at
   different moments is what stops it reading as one flat card sliding up. */
[data-motion='full'] [data-reveal] figure img,
[data-motion='full'] figure[data-reveal] img {
  transform: scale(1.07);
  transition: transform 1500ms cubic-bezier(0.16, 1, 0.3, 1) var(--reveal-delay, 0ms);
}

[data-motion='full'] [data-reveal].is-in figure img,
[data-motion='full'] figure[data-reveal].is-in img {
  transform: scale(1);
}

/* A figure that reveals on its own uncovers in place instead of also rising. */
[data-motion='full'] figure[data-reveal] {
  transform: none;
}

/* ==========================================================================
   Page sections below the sequence
   The stage hands over here: same palette and type scale, but the pinning
   stops and the page behaves like a page.
   ========================================================================== */

.section-head {
  max-width: 1440px;
  margin: 0 auto clamp(40px, 6vh, 76px);
  padding: 0 var(--gutter);
}

/* Roman numerals because the project's own material numbers its chapters —
   the marker carries the client's sequence, it isn't decoration. */
.section-head__eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--signal);
}

.section-head__title {
  margin: clamp(14px, 1.6vw, 22px) 0 0;
  font-size: clamp(1.9rem, 4vw, 3.6rem);
  font-weight: 600;
  font-stretch: 110%;
  line-height: 1.04;
  letter-spacing: -0.015em;
}

/* --- figures band ------------------------------------------------------- */

.figures {
  border-block: 1px solid rgba(119, 134, 156, 0.16);
  padding: clamp(44px, 7vh, 84px) var(--gutter);
}

.figures__list {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: clamp(24px, 3vw, 48px);
  max-width: 1440px;
  margin: 0 auto;
}

.figure {
  text-align: center;
}

.figure__value {
  font-size: clamp(2.4rem, 5vw, 4.4rem);
  font-weight: 600;
  font-stretch: 112%;
  line-height: 1;
  font-variant-numeric: tabular-nums;
}

.figure__label {
  margin: clamp(8px, 1vw, 14px) 0 0;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--haze);
}

/* --- villa types -------------------------------------------------------- */

.types {
  padding: clamp(64px, 12vh, 150px) 0;
}

.types__list {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 3vw, 52px);
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--gutter);
  list-style: none;
}

.type__figure {
  margin: 0 0 clamp(18px, 2vw, 28px);
  overflow: hidden;
  border: 1px solid rgba(119, 134, 156, 0.16);
  background: var(--deep);
}

.type__figure img {
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
}

/* The block letter is how the client already names these houses. */
.type__mark {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  color: var(--signal);
}

.type__name {
  margin: clamp(8px, 1vw, 12px) 0 0;
  font-size: clamp(1.25rem, 1.8vw, 1.75rem);
  font-weight: 500;
  letter-spacing: -0.01em;
}

.type__spec {
  margin: clamp(8px, 0.9vw, 12px) 0 0;
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.08em;
  color: var(--haze);
}

@media (max-width: 900px) {
  .figures__list {
    grid-template-columns: repeat(2, 1fr);
    gap: clamp(28px, 6vw, 44px);
  }

  .types__list {
    grid-template-columns: 1fr;
  }
}

/* --- the object (product stills) ---------------------------------------- */

.object {
  padding: clamp(64px, 12vh, 150px) 0;
}

.object__feature,
.object__details {
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--gutter);
}

.object__feature {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  align-items: center;
  gap: clamp(28px, 4vw, 72px);
}

.object__hero {
  margin: 0;
  overflow: hidden;
  border: 1px solid rgba(119, 134, 156, 0.16);
  background: var(--deep);
}

.object__hero img,
.detail__figure img {
  width: 100%;
  height: auto;
  display: block;
}

.object__text {
  max-width: 46ch;
  font-size: clamp(1.05rem, 1.5vw, 1.4rem);
  line-height: 1.5;
  color: rgba(238, 242, 246, 0.86);
}

.object__spec {
  margin-top: clamp(20px, 2.4vw, 32px);
  padding-top: clamp(16px, 1.8vw, 24px);
  border-top: 1px solid rgba(119, 134, 156, 0.2);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--signal);
}

.object__details {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(24px, 3vw, 52px);
  margin-top: clamp(48px, 8vh, 110px);
  list-style: none;
}

.detail__figure {
  margin: 0 0 clamp(16px, 1.8vw, 24px);
  overflow: hidden;
  border: 1px solid rgba(119, 134, 156, 0.16);
  background: var(--deep);
}

.detail__name {
  margin: 0;
  font-size: clamp(1.1rem, 1.5vw, 1.5rem);
  font-weight: 500;
  letter-spacing: -0.01em;
}

.detail__text {
  margin-top: clamp(8px, 0.9vw, 12px);
  max-width: 34ch;
  font-size: clamp(0.92rem, 1.05vw, 1.05rem);
  line-height: 1.5;
  color: var(--haze);
}

@media (max-width: 900px) {
  .object__feature {
    grid-template-columns: 1fr;
  }

  .object__details {
    grid-template-columns: 1fr;
  }
}

/* --- reduced motion ----------------------------------------------------- */

.stage.is-static {
  height: 100vh;
  height: 100svh;
}

.stage.is-static .waterline,
.stage.is-static .statusbar {
  display: none;
}

.static-copy {
  position: absolute;
  left: var(--gutter);
  right: var(--gutter);
  bottom: clamp(40px, 7vh, 88px);
  text-align: center;
}

.static-copy__display {
  font-size: clamp(2.6rem, 8vw, 6rem);
  font-weight: 600;
  font-stretch: 118%;
  letter-spacing: 0.055em;
  margin-right: -0.055em;
  line-height: 1;
}

.static-copy__sub {
  margin-top: 14px;
  font-size: clamp(1rem, 1.6vw, 1.35rem);
  color: var(--foam);
}

.static-copy__sequence {
  margin-top: 18px;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--haze);
}

/* .waterline and .statusbar, not the old .instrument wrapper they used to
   live inside. */
[data-motion='reduced'] .stage__canvas,
[data-motion='reduced'] .beats,
[data-motion='reduced'] .waterline,
[data-motion='reduced'] .statusbar {
  transition: none;
}

/* --- no javascript ------------------------------------------------------ */

.noscript {
  display: grid;
  place-items: center;
  gap: 28px;
  min-height: 100vh;
  padding: 80px var(--gutter);
  text-align: center;
}

.noscript img {
  height: min(62vh, 620px);
  width: auto;
}

.noscript p {
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--haze);
}

/* ==========================================================================
   Walkthrough stage (arch.html)
   Same machinery, inverted figure/ground: the footage fills the viewport and
   the copy sits on top of it, so everything here is about keeping type legible
   over a bright interior without flattening the architecture.
   ========================================================================== */

.stage--frame {
  height: 700vh;
  height: 700svh;
}

.stage--frame .stage__canvas {
  z-index: 0;
}

.stage--frame .beats {
  z-index: 2;
}

/* Shade for the masthead and the status bar only — the middle of the image
   stays untouched. */
.stage__scrim {
  position: absolute;
  inset: 0;
  z-index: 1;
  background:
    linear-gradient(to bottom, rgba(5, 9, 15, 0.6), transparent 18%),
    linear-gradient(to top, rgba(5, 9, 15, 0.72), transparent 26%);
}

/* Each side beat brings its own column of shade, anchored to the screen edge,
   so only the half of the frame it occupies is darkened. */
.stage--frame .beat--left,
.stage--frame .beat--right {
  top: 0;
  height: 100%;
  width: min(960px, 54vw);
  justify-content: center;
}

.stage--frame .beat--left {
  left: 0;
  padding: 0 clamp(40px, 5vw, 96px) 0 var(--gutter);
  background: linear-gradient(to right, rgba(5, 9, 15, 0.94), rgba(5, 9, 15, 0.86) 62%, transparent);
}

.stage--frame .beat--right {
  right: 0;
  padding: 0 var(--gutter) 0 clamp(40px, 5vw, 96px);
  background: linear-gradient(to left, rgba(5, 9, 15, 0.94), rgba(5, 9, 15, 0.86) 62%, transparent);
}

.stage--frame .beat__note,
.stage--frame .beat__sub {
  color: rgba(238, 242, 246, 0.86);
}

.stage--frame .beat__note {
  max-width: 62ch;
}

/* Belt and braces over daylight: the scrim carries most of it, this catches
   the tail of a line that runs past the fade. */
.stage--frame .beat__display,
.stage--frame .beat__note,
.stage--frame .beat__sub {
  text-shadow: 0 1px 22px rgba(5, 9, 15, 0.85);
}

/* Lifted off --haze: the copy here sits over daylight, not over the dark stage. */
.stage--frame .beat__note {
  color: rgba(238, 242, 246, 0.8);
}

.stage--frame .beat--lead,
.stage--frame .beat--final {
  top: 0;
  height: 100%;
  justify-content: center;
  padding: 0 var(--gutter);
  background: radial-gradient(58% 38% at 50% 50%, rgba(5, 9, 15, 0.74), transparent 74%);
}

.stage--frame .beat--lead .beat__display {
  font-size: clamp(2.4rem, 7vw, 7.5rem);
}

/* No product to stand on here, so the horizon becomes a plain progress rule
   just above the status bar. */
.stage--frame .waterline {
  top: auto;
  bottom: clamp(52px, 6.5vh, 80px);
}

/* --- narrow screens ----------------------------------------------------- */

/* Below this there is no clear space beside the can, so every beat moves into
   the band under the waterline and the sequence stays centred. */
@media (max-width: 1000px) {
  .beat--left,
  .beat--right,
  .beat--lead,
  .beat--final {
    left: var(--gutter);
    right: var(--gutter);
    top: calc(var(--waterline) + clamp(56px, 9vh, 96px));
    width: auto;
    height: auto;
    display: block;
    padding: 0;
    text-align: center;
  }

  .beat--lead .beat__display {
    font-size: clamp(3.4rem, 17vw, 7rem);
  }

  .beat--final .beat__display {
    font-size: clamp(2rem, 9vw, 4rem);
  }

  .beat--left .beat__display,
  .beat--right .beat__display {
    font-size: clamp(1.6rem, 6.4vw, 2.6rem);
  }

  /* Dropped on narrow screens rather than squeezed in.
     The band under the product already carries the copy, and the hint needs 67px
     of it — measured at 390x844 it overlapped the beat by 8px on the walkthrough
     pages and cleared the product page by only 47px, which a shorter phone or a
     longer line would eat. Anchoring it lower just moved the collision onto the
     status bar.
     It is also the wrong affordance here: a mouse wheel means nothing on a touch
     screen, and the first swipe already demonstrates what the hint was promising. */
  .scroll-hint {
    display: none;
  }

  /* The walkthrough fills the frame edge to edge, so beats stack into the
     shaded band at its foot and keep the scrim that makes them readable. */
  .stage--frame .beat--left,
  .stage--frame .beat--right,
  .stage--frame .beat--lead,
  .stage--frame .beat--final {
    left: 0;
    right: 0;
    top: auto;
    bottom: clamp(92px, 15vh, 148px);
    width: auto;
    height: auto;
    display: block;
    padding: 0 var(--gutter);
    background: none;
    text-align: left;
  }

  .stage--frame .beat--lead,
  .stage--frame .beat--final {
    text-align: center;
  }

  .stage__scrim {
    background:
      linear-gradient(to bottom, rgba(5, 9, 15, 0.6), transparent 16%),
      linear-gradient(to top, rgba(5, 9, 15, 0.86), transparent 46%);
  }
}

/* ==========================================================================
   Lab 04 — cursor reactive character (lab-cat.html)
   The source is a full room scene, not a cut-out, so it fills the viewport the
   way the walkthrough does rather than sitting as an object on a dark stage.
   ========================================================================== */

.pose {
  position: relative;
  height: 100vh;
  height: 100svh;
  overflow: hidden;
  background: var(--abyss);
}

.pose__canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  transition: opacity 700ms ease;
}

.pose.is-ready .pose__canvas {
  opacity: 1;
}

/* Shade only the foot of the frame, where the label sits. */
.pose::after {
  content: '';
  position: absolute;
  inset: auto 0 0;
  height: 26%;
  background: linear-gradient(to top, rgba(5, 9, 15, 0.72), transparent);
  pointer-events: none;
}

.pose__hint {
  position: absolute;
  left: 0;
  right: 0;
  bottom: clamp(28px, 6vh, 64px);
  z-index: 2;
  text-align: center;
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: rgba(238, 242, 246, 0.82);
  text-shadow: 0 1px 20px rgba(5, 9, 15, 0.9);
}

@media (hover: none) {
  .pose__hint::after {
    content: ' — or drag';
  }
}

/* ==========================================================================
   Hub (index.html)
   The four experiments in one place. The structural device is the primitive
   line under each title — what a card actually demonstrates is the control it
   hands to the visitor, which is the only thing that differs between them.
   ========================================================================== */

.hub-page {
  /* No pinned stage here, so the page keeps its own scroll height. */
  min-height: 100vh;
}

.hub__intro {
  max-width: 1440px;
  margin: 0 auto;
  padding: clamp(140px, 22vh, 260px) var(--gutter) clamp(56px, 10vh, 120px);
}

.hub__eyebrow {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--signal);
}

.hub__title {
  margin: clamp(16px, 2vw, 28px) 0 0;
  max-width: 22ch;
  font-size: clamp(2.4rem, 6.5vw, 6rem);
  font-weight: 600;
  font-stretch: 112%;
  line-height: 0.98;
  letter-spacing: -0.02em;
}

.hub__lede {
  margin: clamp(22px, 3vw, 40px) 0 0;
  max-width: 62ch;
  font-size: clamp(1rem, 1.3vw, 1.35rem);
  line-height: 1.55;
  color: var(--haze);
}

.hub__list {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(28px, 4vw, 72px) clamp(24px, 3vw, 56px);
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--gutter) clamp(80px, 14vh, 180px);
  list-style: none;
}

.card__link {
  display: block;
  color: inherit;
  text-decoration: none;
}

.card__figure {
  margin: 0 0 clamp(18px, 2vw, 28px);
  overflow: hidden;
  border: 1px solid rgba(119, 134, 156, 0.16);
  background: var(--deep);
}

.card__figure img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  transition: transform 900ms cubic-bezier(0.16, 1, 0.3, 1);
}

.card__link:hover .card__figure img,
.card__link:focus-visible .card__figure img {
  transform: scale(1.035);
}

.card__index {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.24em;
  color: var(--haze);
}

.card__title {
  margin: clamp(8px, 1vw, 12px) 0 0;
  font-size: clamp(1.3rem, 2.1vw, 2.1rem);
  font-weight: 500;
  letter-spacing: -0.015em;
}

/* The one thing that separates these four from each other. */
.card__primitive {
  margin: clamp(10px, 1.1vw, 14px) 0 0;
  padding-top: clamp(10px, 1.1vw, 14px);
  border-top: 1px solid rgba(119, 134, 156, 0.2);
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--signal);
}

.card__text {
  margin: clamp(10px, 1.1vw, 14px) 0 0;
  max-width: 46ch;
  font-size: clamp(0.92rem, 1.05vw, 1.05rem);
  line-height: 1.55;
  color: var(--haze);
}

@media (max-width: 900px) {
  .hub__list {
    grid-template-columns: 1fr;
  }
}

/* ==========================================================================
   Bandırma şehir turu (bandirma.html)

   Kaynak 9:16 dikey. Bu yüzden sayfa iki farklı yerleşim taşıyor: geniş
   ekranda kare bütün haliyle ortada durur (contain) ve metin YANINDAKİ
   boşluğa girer; dik ekranda kare baştan başa doldurur (cover) ve metin
   alt banda iner. Dikey kaynağı 16:9'a kırpmak kadrajın üçte ikisini atardı
   ve landmarklar tam o yükseklik boyunca dağılmış durumda.
   ========================================================================== */

.stage--bandirma {
  /* 240 kare / 500vh ≈ 2,1vh per kare ortalama; hero'lar ağırlıklı olduğu
     için bir yapının karşısında ~2,7vh, geçişlerde ~1,1vh düşüyor.
     Kaydırma çok uzun/kısa gelirse ayar noktası burası — timeline'a
     dokunmadan değişir. */
  height: 500vh;
  height: 500svh;
}

.stage--bandirma .stage__canvas {
  background: var(--abyss);
}

/* Kareler gündüz ve parlak; metin onların üstünde duruyor. Kenarlarda
   kontrast kazandıran, ortayı karartmayan bir perde. */
.stage--bandirma .stage__scrim {
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(to bottom, rgba(5, 9, 15, 0.5) 0%, rgba(5, 9, 15, 0) 24%),
    linear-gradient(to top, rgba(5, 9, 15, 0.8) 0%, rgba(5, 9, 15, 0) 42%);
}

/* --- landmark metinleri -------------------------------------------------- */

.cues {
  position: absolute;
  inset: 0;
  pointer-events: none;
  opacity: 0;
  transition: opacity 700ms ease 200ms;
}

.stage.is-ready .cues {
  opacity: 1;
}

/* Hepsi üst üste duruyor; hangisinin görüneceğine scroll karar veriyor.
   Aynı anda yalnızca biri görünür — pencereler bandirma-config.js'te
   çakışmayacak şekilde ölçüldü. */
.cue,
.closing {
  position: absolute;
  will-change: opacity;
}

.cue__eyebrow {
  font-family: var(--font-mono);
  font-size: clamp(10px, 0.85vw, 12px);
  letter-spacing: 0.24em;
  text-transform: uppercase;
  color: var(--signal);
  text-shadow: 0 1px 12px rgba(5, 9, 15, 0.9);
}

.cue__title {
  margin: 0.55em 0 0;
  font-size: clamp(1.7rem, 2.6vw, 3.1rem);
  font-weight: 400;
  line-height: 1.12;
  letter-spacing: -0.02em;
  text-shadow: 0 2px 28px rgba(5, 9, 15, 0.85);
  will-change: transform;
}

.cue__desc {
  margin: 0.85em 0 0;
  max-width: 34ch;
  font-size: clamp(0.9rem, 1.05vw, 1.05rem);
  line-height: 1.55;
  color: rgba(238, 242, 246, 0.86);
  text-shadow: 0 2px 18px rgba(5, 9, 15, 0.9);
}

.closing__title {
  font-size: clamp(1.1rem, 1.5vw, 1.5rem);
  font-weight: 400;
  letter-spacing: -0.01em;
  text-shadow: 0 2px 22px rgba(5, 9, 15, 0.85);
}

.closing__note {
  margin-top: 0.6em;
  font-family: var(--font-mono);
  font-size: 10px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--haze);
}

/* --- landmark şeridi ----------------------------------------------------- */

.rail {
  position: absolute;
  right: var(--gutter);
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: clamp(10px, 1.4vh, 16px);
  opacity: 0;
  transition: opacity 700ms ease 300ms;
}

.stage.is-ready .rail {
  opacity: 1;
}

.rail__stop {
  display: flex;
  align-items: baseline;
  gap: 10px;
  padding: 2px 0;
  border: 0;
  background: none;
  color: inherit;
  cursor: pointer;
  pointer-events: auto;
  font-family: var(--font-mono);
  text-align: right;
}

.rail__index {
  font-size: 10px;
  letter-spacing: 0.14em;
  color: rgba(238, 242, 246, 0.4);
  transition: color 240ms ease;
}

.rail__name {
  font-size: 10px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(238, 242, 246, 0.4);
  transition:
    color 240ms ease,
    opacity 240ms ease;
}

.rail__stop:hover .rail__index,
.rail__stop:hover .rail__name {
  color: rgba(238, 242, 246, 0.8);
}

.rail__stop.is-active .rail__index {
  color: var(--signal);
}

.rail__stop.is-active .rail__name {
  color: var(--foam);
}

/* --- geniş ekran: kare ortada, metin yanındaki boşlukta ------------------- */

/* --frame-left ve --frame-width canvas renderer tarafından yazılıyor, yani
   metin sütunu karenin gerçekte nereye oturduğuna göre daralıp genişliyor —
   sabit bir yüzdeyle tahmin edilmiyor. */
@media (min-aspect-ratio: 1/1) {
  .stage--bandirma .cue,
  .stage--bandirma .closing {
    left: var(--gutter);
    top: 50%;
    transform: translateY(-50%);
    width: min(36ch, max(220px, calc(var(--frame-left) - var(--gutter) * 2)));
  }

  .stage--bandirma .closing {
    top: auto;
    bottom: clamp(96px, 13vh, 150px);
    transform: none;
  }
}

/* --- dik ekran: kare tam ekran, metin alt bantta ------------------------- */

@media (max-aspect-ratio: 1/1) {
  .stage--bandirma .cue {
    left: var(--gutter);
    right: var(--gutter);
    bottom: clamp(104px, 15vh, 168px);
    width: auto;
  }

  .stage--bandirma .closing {
    left: var(--gutter);
    right: var(--gutter);
    bottom: clamp(104px, 15vh, 168px);
  }

  .stage--bandirma .cue__desc {
    max-width: 30ch;
  }

  /* Telefonda isimler yer kaplıyor; numaralar sırayı zaten anlatıyor. */
  .stage--bandirma .rail__name {
    display: none;
  }

  .stage--bandirma .rail {
    gap: clamp(12px, 1.8vh, 18px);
  }
}

.stage--bandirma .waterline {
  top: auto;
  bottom: clamp(52px, 6.5vh, 80px);
}

/* The static fallback writes its copy into [data-cues], so that container has
   to stay — only the rail goes, since there is nothing to scrub to. */
.stage--bandirma.is-static .rail {
  display: none;
}

/* --- turun altındaki bölümler (bandirma.html) ---------------------------- */

.stops-section {
  padding: clamp(64px, 12vh, 150px) 0;
  border-top: 1px solid rgba(119, 134, 156, 0.14);
}

.stops {
  display: grid;
  gap: clamp(16px, 2vw, 26px);
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 210px), 1fr));
  max-width: 1240px;
  margin: 0 auto;
  padding: 0 var(--gutter);
  list-style: none;
}

.stop {
  padding: clamp(18px, 2vw, 26px);
  border: 1px solid rgba(119, 134, 156, 0.16);
  background: var(--deep);
}

.stop__index {
  font-family: var(--font-mono);
  font-size: 11px;
  letter-spacing: 0.22em;
  color: var(--signal);
}

.stop__name {
  margin: 0.7em 0 0;
  font-size: clamp(1rem, 1.4vw, 1.25rem);
  font-weight: 500;
}

.stop__note {
  margin: 0.8em 0 0;
  font-size: 0.9rem;
  line-height: 1.55;
  color: var(--haze);
}

.cta {
  padding: clamp(64px, 12vh, 150px) var(--gutter);
  text-align: center;
  border-top: 1px solid rgba(119, 134, 156, 0.14);
  background: linear-gradient(to bottom, var(--abyss), var(--deep));
}

.cta__title {
  max-width: 24ch;
  margin: 0 auto;
  font-size: clamp(1.7rem, 3.4vw, 3.2rem);
  font-weight: 300;
  line-height: 1.15;
  letter-spacing: -0.02em;
}

.cta__note {
  max-width: 54ch;
  margin: 1.2em auto 0;
  font-size: clamp(0.92rem, 1.05vw, 1.05rem);
  line-height: 1.6;
  color: var(--haze);
}

.cta__action {
  display: inline-block;
  margin-top: clamp(28px, 4vh, 48px);
  padding: 15px 34px;
  border: 1px solid var(--signal);
  color: var(--signal);
  font-family: var(--font-mono);
  font-size: 12px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-decoration: none;
  transition:
    background 240ms ease,
    color 240ms ease;
}

.cta__action:hover {
  background: var(--signal);
  color: var(--abyss);
}

/* --- masaüstünde telefon gibi (bandirma.html) ---------------------------- */

/* Kaynak 9:16 ve tamamen mobil için üretildi. Geniş ekranda onu kırpmak yerine
   ne olduğunu göstererek sunuyoruz: ortada, köşeleri yuvarlatılmış, gölgeli bir
   panel. Konum canvas renderer'ın yazdığı --frame-* değişkenlerinden geliyor;
   köşe yarıçapı da bandirma-config.js'teki `radius` ile aynı oran (0.055),
   yoksa çerçeve ile görüntünün köşeleri birbirini tutmaz. */
.stage--bandirma .device {
  position: absolute;
  left: var(--frame-left);
  top: var(--frame-top);
  width: var(--frame-width);
  height: var(--frame-height);
  border: 1px solid rgba(238, 242, 246, 0.16);
  border-radius: calc(var(--frame-width) * 0.055);
  box-shadow: 0 50px 140px rgba(0, 0, 0, 0.62);
  pointer-events: none;
  opacity: 0;
  transition: opacity 900ms ease;
}

.stage--bandirma.is-ready .device {
  opacity: 1;
}

/* Dik ekranda kare zaten baştan başa; çerçevelenecek bir şey yok. */
@media (max-aspect-ratio: 1/1) {
  .stage--bandirma .device {
    display: none;
  }
}

/* --- katman sırası (bandirma.html) --------------------------------------- */

/* Kutu sayfasında `.beats` bilerek canvas'ın ALTINDA (z-index 1): orada kare
   bir NESNE ve ürünün yazıyı örtmesi isteniyor. Burada kare bir PENCERE —
   şehrin kendisi — ve metin onun üstünde durmalı. Canvas z-index 2 olduğu için
   bu sayfanın bütün katmanları onun üstüne alınıyor.
   Bu verilmediğinde metin DOM'da opacity 1 ile duruyor ama ekranda hiç
   görünmüyor; `elementFromPoint` canvas'ı döndürüyor. */
.stage--bandirma .stage__scrim {
  z-index: 3;
}

.stage--bandirma .device {
  z-index: 4;
}

.stage--bandirma .cues,
.stage--bandirma .rail {
  z-index: 5;
}

.stage--bandirma .waterline,
.stage--bandirma .statusbar,
.stage--bandirma .scroll-hint {
  z-index: 6;
}

/* --- dik ekranda okunabilirlik (bandirma.html) --------------------------- */

/* Dik ekranda kare baştan başa doldurduğu için metin doğrudan yapının üstüne
   düşüyor — ve bu kareler gündüz, açık renkli, yüksek parlaklıkta. Ölçtük:
   camide alt metin aydınlık kaldırım zemininin üstünde okunmuyordu.
   Çözüm kutu değil, alttaki perdeyi metnin oturduğu yerde güçlendirmek —
   büyük bir panel görüntüyü kapatırdı. */
@media (max-aspect-ratio: 1/1) {
  .stage--bandirma .stage__scrim {
    background:
      linear-gradient(to bottom, rgba(5, 9, 15, 0.55) 0%, rgba(5, 9, 15, 0) 20%),
      linear-gradient(
        to top,
        rgba(5, 9, 15, 0.92) 0%,
        rgba(5, 9, 15, 0.72) 22%,
        rgba(5, 9, 15, 0.3) 42%,
        rgba(5, 9, 15, 0) 58%
      );
  }

  /* Şerit gökyüzünün ya da açık bir cephenin üstüne denk gelebiliyor; kendi
     gölgesini taşıması gerekiyor, çünkü altındaki perde oraya ulaşmıyor. */
  .stage--bandirma .rail__index {
    color: rgba(238, 242, 246, 0.62);
    text-shadow: 0 1px 10px rgba(5, 9, 15, 0.95);
  }

  .stage--bandirma .rail__stop.is-active .rail__index {
    color: var(--signal);
    font-weight: 500;
  }

  /* Aktif olanı numara tek başına yeterince ayırmıyor; ince bir çizgi ekliyor. */
  .stage--bandirma .rail__stop.is-active::after {
    content: '';
    width: 14px;
    height: 1px;
    background: var(--signal);
  }
}

/* --- ikinci kesim: yatay şerit (bandirma2.html) --------------------------- */

/* Bu kesimde kamera kesintisiz YATAY ilerliyor; dikey bir durak listesi
   hareketin yönüne ters düşüyordu. Şerit de yatay: soldan sağa, kameranın
   gittiği yöne. Geri kalan her şey .stage--bandirma'dan geliyor. */
.stage--bandirma2 .rail {
  right: var(--gutter);
  left: var(--gutter);
  top: auto;
  bottom: clamp(74px, 9vh, 104px);
  transform: none;
  flex-direction: row;
  align-items: center;
  justify-content: space-between;
  gap: 0;
}

.stage--bandirma2 .rail__stop {
  flex-direction: column;
  align-items: center;
  gap: 5px;
  text-align: center;
}

.stage--bandirma2 .rail__index {
  font-size: 11px;
}

/* Aktif durağın altına, gidiş yönünde kısa bir çizgi. */
.stage--bandirma2 .rail__stop.is-active::after {
  content: '';
  width: 18px;
  height: 1px;
  background: var(--signal);
}

@media (max-aspect-ratio: 1/1) {
  /* Dik ekranda altı isim yan yana sığmıyor; numaralar sırayı zaten anlatıyor
     ve yatay dizilim hareketin yönünü korumaya devam ediyor. */
  .stage--bandirma2 .rail__name {
    display: none;
  }

  .stage--bandirma2 .rail {
    bottom: clamp(70px, 8.5vh, 92px);
  }
}

/* Şerit yatay olduğu için metin bandı onun üstüne çıkmalı, yoksa çakışır. */
@media (max-aspect-ratio: 1/1) {
  .stage--bandirma2 .cue,
  .stage--bandirma2 .closing {
    bottom: clamp(124px, 17vh, 190px);
  }
}

/* ==========================================================================
   SonarSea dalışı (sonarsea.html)
   Kaynak 9:16. Dar ekranda .stage--frame'in kaplama tasarımı zaten doğru şey,
   olduğu gibi kalıyor; burada yalnız geniş ekranın contain hâli kuruluyor:
   kare ortada dikey bir pano, metin onun yanındaki gerçek boşlukta.
   ========================================================================== */

.stage--sonarsea {
  /* 381 kare / 800vh ≈ 2,1vh per kare — Bandırma ile aynı yoğunluk. Kaydırma
     uzun/kısa gelirse ayar noktası burası, timeline'a dokunmadan değişir. */
  height: 800vh;
  height: 800svh;
}

.stage--sonarsea .stage__canvas {
  background: var(--abyss);
}

/* Açılış ve kapanış artık bir marka adı değil, birer CÜMLE. .stage--frame'in
   dev punto ayarı (7vw / 17vw) bir kelime için doğru, bir cümleyi ekrandan
   taşırıyor — burada punto düşüyor ve satır uzunluğu sınırlanıyor. */
/* margin-right: taban kural harf aralığını kapatmak için negatif marj veriyor
   (`margin-right: -0.055em`). Burada harf aralığı değiştiği için o marj da
   sıfırlanmalı — ama `auto` olarak, `0` olarak değil: aşağıdaki `> *` kuralı
   yalnız margin-left'e auto verip metni sağa kaydırıyordu. */
.stage--sonarsea .beat--lead .beat__display {
  font-size: clamp(1.9rem, 3.6vw, 3.6rem);
  letter-spacing: -0.01em;
  margin-right: auto;
}

.stage--sonarsea .beat--final .beat__display {
  font-size: clamp(1.7rem, 3.2vw, 3.2rem);
  letter-spacing: -0.01em;
  margin-right: auto;
}

/* Açılıştaki marka adı: yukarıdaki punto düşüşü cümleler için, bu tek kelime
   ve sayfanın ilk gördüğü şey — taban `lead` ölçeğine geri çıkıyor. */
.stage--sonarsea .beat--mark .beat__display {
  font-size: clamp(3rem, 8vw, 8.5rem);
}

.stage--sonarsea .beat--lead > *,
.stage--sonarsea .beat--final > * {
  max-width: min(22ch, 92vw);
  margin-left: auto;
  margin-right: auto;
}

/* Perde yalnız geniş ekranda hafifletiliyor: orada metin karenin YANINDA, koyu
   zeminin üstünde duruyor, görüntüyü karartmaya gerek yok. Dar ekranda metin
   karenin ÜSTÜNDE ve kareler gündüz gibi parlak — oradaki kural aşağıda, ve
   .stage--frame'in dar ekran perdesinden daha da güçlü. Bu ikisi tek bir
   `.stage--sonarsea .stage__scrim` kuralına indirilirse (denendi) dar ekranda
   metin okunmaz hâle geliyor: bu seçici, medya sorgusu içindeki sade
   `.stage__scrim` kuralını özgüllükle eziyor. */
@media (max-width: 1000px) {
  .stage--sonarsea .stage__scrim {
    background:
      linear-gradient(to bottom, rgba(5, 9, 15, 0.62), transparent 15%),
      linear-gradient(to top, rgba(5, 9, 15, 0.92), rgba(5, 9, 15, 0.55) 30%, transparent 54%);
  }
}

@media (min-aspect-ratio: 1/1) {
  .stage--sonarsea .stage__scrim {
    background:
      linear-gradient(to bottom, rgba(5, 9, 15, 0.55), transparent 16%),
      linear-gradient(to top, rgba(5, 9, 15, 0.72), transparent 24%);
  }

  /* Açılış ve kapanış başlıkları karenin üst bandına çekiliyor. .stage--frame
     onları dikey ortaya koyuyor — kaplama tasarımında doğru, burada değil:
     finalde şamandıra tam ortada duruyor ve başlık ürünün üstüne oturuyor. */
  .stage--sonarsea .beat--lead,
  .stage--sonarsea .beat--final {
    top: var(--frame-top);
    height: calc(var(--frame-height) * 0.32);
    justify-content: flex-end;
    padding: 0 var(--gutter) clamp(10px, 1.6vh, 20px);
    background: radial-gradient(62% 120% at 50% 100%, rgba(5, 9, 15, 0.6), transparent 72%);
  }

  /* .stage--frame metni ekran kenarına yapışık, gradyanlı tam boy sütunlara
     alıyor — o kaplama içindir. Burada kare ortada durduğu için metin taban
     kuralına dönüyor: --frame-* değerlerini canvas renderer yazıyor. */
  .stage--sonarsea .beat--left,
  .stage--sonarsea .beat--right {
    top: var(--frame-top);
    height: var(--frame-height);
    width: min(520px, calc((100% - var(--frame-width)) / 2 - var(--gutter) * 1.4));
    background: none;
  }

  /* Taban punto (4.6vw) kısa başlıklar için ayarlı — bu sayfanın başlıkları
     cümle uzunluğunda ve yan sütun 9:16 pano yüzünden dar, o puntoda beş
     satıra bölünüyorlar. */
  .stage--sonarsea .beat--left .beat__display,
  .stage--sonarsea .beat--right .beat__display {
    font-size: clamp(1.6rem, 2.6vw, 2.9rem);
    line-height: 1.04;
  }

  .stage--sonarsea .beat--left {
    left: var(--gutter);
    padding: 0;
  }

  .stage--sonarsea .beat--right {
    right: var(--gutter);
    padding: 0;
  }

  /* Çizilen karenin sınırı. Yarıçap sonarsea-config.js'teki `radius` ile aynı
     oran (0.05) olmalı, yoksa çerçeve ile görüntünün köşeleri birbirini tutmaz. */
  .stage--sonarsea .stage__pin::after {
    content: '';
    position: absolute;
    left: var(--frame-left);
    top: var(--frame-top);
    width: var(--frame-width);
    height: var(--frame-height);
    border: 1px solid rgba(238, 242, 246, 0.16);
    border-radius: calc(var(--frame-width) * 0.05);
    box-shadow: 0 40px 120px rgba(5, 9, 15, 0.6);
    pointer-events: none;
    z-index: 1;
  }
}

/* --- kapanış: ürün kategorileri + künye -------------------------------- */

.ss-close {
  padding: clamp(64px, 12vh, 150px) 0 clamp(48px, 9vh, 110px);
}

.ss-grid {
  max-width: 1440px;
  margin: 0 auto;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(20px, 2.6vw, 40px);
  list-style: none;
}

.ss-card {
  padding: clamp(20px, 2vw, 30px);
  border: 1px solid rgba(119, 134, 156, 0.18);
  background: var(--deep);
}

.ss-card__name {
  margin: 0;
  font-size: clamp(1.05rem, 1.5vw, 1.35rem);
  font-weight: 600;
  font-stretch: 106%;
  color: var(--foam);
}

.ss-card__text {
  margin: clamp(10px, 1.1vw, 14px) 0 0;
  font-size: clamp(0.9rem, 1.05vw, 1.02rem);
  line-height: 1.5;
  color: var(--haze);
}

.ss-note {
  max-width: 1440px;
  margin: clamp(40px, 6vh, 76px) auto 0;
  padding: 0 var(--gutter);
  display: grid;
  grid-template-columns: minmax(0, 1.3fr) minmax(0, 1fr);
  gap: clamp(28px, 4vw, 72px);
  align-items: start;
}

.ss-note__text {
  margin: 0;
  max-width: 56ch;
  font-size: clamp(1rem, 1.35vw, 1.25rem);
  line-height: 1.55;
  color: rgba(238, 242, 246, 0.86);
}

.ss-contact {
  margin: 0;
  font-family: var(--font-mono);
  font-size: clamp(11px, 0.95vw, 13px);
  line-height: 2;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--signal);
}

.ss-contact a {
  color: inherit;
}

@media (max-width: 900px) {
  .ss-grid {
    grid-template-columns: 1fr;
  }

  .ss-note {
    grid-template-columns: 1fr;
  }
}
