*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  scroll-behavior: smooth;
  color-scheme: dark;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

body {
  margin: 0;
  background: #070707;
  color: #f3eee6;
  font-family: Outfit, "Avenir Next", "Segoe UI", sans-serif;
  font-weight: 300;
  line-height: 1.5;
}

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

button,
a {
  font: inherit;
  color: inherit;
}

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

p,
h1,
h2,
figure {
  margin: 0;
}

:focus-visible {
  outline: 2px solid #e0c992;
  outline-offset: 3px;
}

::selection {
  background: #e0c992;
  color: #16140f;
}

.header {
  position: fixed;
  z-index: 40;
  top: 0;
  left: 0;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(12px + env(safe-area-inset-top)) 18px 12px;
  background: rgba(7, 7, 7, 0.78);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
}

.brand {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  font-size: 12px;
  font-weight: 500;
}

.brand svg {
  display: block;
}

.langs {
  display: flex;
  gap: 2px;
}

.langs button {
  min-width: 48px;
  min-height: 48px;
  letter-spacing: 0.16em;
  font-size: 11px;
  font-weight: 500;
  color: rgba(243, 238, 230, 0.42);
}

.langs button[aria-pressed="true"] {
  color: #f3eee6;
}

.progress {
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  transform: scaleX(0);
  transform-origin: 0 50%;
  background: linear-gradient(90deg, #8d7040, #f3e6c8);
}

.kicker {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.26em;
  text-transform: uppercase;
  color: #e0c992;
}

.display {
  font-family: "Cormorant Garamond", "Iowan Old Style", Palatino, Georgia, serif;
  font-weight: 500;
  font-size: clamp(40px, 11vw, 92px);
  line-height: 0.92;
  letter-spacing: 0.045em;
}

.bio {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  align-items: center;
  padding: calc(84px + env(safe-area-inset-top)) 22px 48px;
}

.bio__inner {
  width: min(100%, 1080px);
  margin: 0 auto;
}

.portrait {
  width: min(72vw, 300px);
  aspect-ratio: 4 / 5;
  margin-bottom: 28px;
  overflow: hidden;
  border-radius: 2px;
  box-shadow: 0 30px 70px rgba(0, 0, 0, 0.35);
}

.portrait img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 72% 18%;
}

.bio__copy .kicker {
  margin-bottom: 10px;
}

.bio__text {
  max-width: 36em;
  margin-top: 18px;
  font-size: 15.5px;
  line-height: 1.65;
  color: rgba(243, 238, 230, 0.78);
}

.scrollhint {
  margin-top: 28px;
}

.scrollhint span {
  display: inline-flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.28em;
  text-transform: uppercase;
  color: rgba(243, 238, 230, 0.5);
}

.scrollhint span::after {
  content: "";
  width: 1px;
  height: 42px;
  margin-left: 1.2em;
  background: linear-gradient(#e0c992, transparent);
}

/* The intro repeats the bio's scroll cue, pinned near the foot of the pinned
   panel. The centring above it leaves a band of empty screen there, and this is
   what that band is for: it tells the reader the page continues, and the hint
   fades out with the first scroll. */
html.is-enhanced:not(.is-reduced) .scrollhint--intro {
  position: absolute;
  z-index: 1;
  left: 0;
  right: 0;
  bottom: calc(18px + env(safe-area-inset-bottom));
  margin-top: 0;
  display: flex;
  justify-content: center;
  pointer-events: none;
}

/* On phones, and in the stacked reduced-motion layout, the chooser reaches the
   foot of the panel and there is no free band for the hint. */
@media (max-width: 560px) {
  html.is-enhanced:not(.is-reduced) .scrollhint--intro {
    display: none;
  }
}

html.is-reduced .scrollhint--intro {
  display: none;
}

.story__pin {
  position: relative;
}

.select-layer,
.file-layer {
  position: relative;
}

.select-layer {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  /* `safe` keeps the top of the intro reachable on short viewports: the grid,
     the chooser and the copy together are taller than a laptop panel, and plain
     centring would push the headline up underneath the fixed header. */
  justify-content: safe center;
  gap: 16px;
  padding: calc(88px + env(safe-area-inset-top)) 16px 28px;
}

.select-copy {
  width: min(100%, 980px);
  margin: 0 auto;
  text-align: center;
}

.tap-hint {
  margin-top: 8px;
  font-size: 12px;
  letter-spacing: 0.08em;
  color: rgba(243, 238, 230, 0.5);
}

.gem-grid {
  width: min(100%, 980px);
  margin: 0 auto;
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.gem {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  min-height: 56px;
  padding: 16px 10px 18px;
  border-radius: 18px;
  border: 1px solid rgba(243, 238, 230, 0.12);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(255, 255, 255, 0.06), transparent 58%),
    #100f0d;
  text-align: center;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.gem[aria-pressed="true"] {
  border-color: rgba(224, 201, 146, 0.9);
  box-shadow: inset 0 0 0 1px rgba(224, 201, 146, 0.35);
}

.gem-grid.is-departing .gem {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}

/* The cards dissolve as the chosen stone falls; a button that is no longer there
   must not keep taking taps. The chooser below stays live. */
.gem-grid.is-departing,
.gem-grid.is-departing .gem {
  pointer-events: none;
}

.gem__stage {
  width: 100%;
  height: clamp(104px, 24vh, 172px);
  display: grid;
  place-items: center;
  perspective: 700px;
}

.gem__tilt {
  width: 100%;
  height: 100%;
  min-height: 0;
  /* Must be flex, not grid: a grid item's percentage height resolves against a
     grid area that is itself derived from the percentage-sized stage, so the
     92% height on .gem__svg silently failed. Tall stones (diamond 100x168,
     tourmaline 120x156) then fell back to aspect-ratio sizing, grew to ~250px
     inside a 180px stage and covered the stone name underneath. As a flex item
     the percentage resolves against the stage, so every stone fits. */
  display: flex;
  align-items: center;
  justify-content: center;
  animation: tilt 7.5s ease-in-out infinite;
  transform-origin: center;
}

.gem:nth-child(2) .gem__tilt { animation-duration: 8.6s; animation-delay: -2s; }
.gem:nth-child(3) .gem__tilt { animation-duration: 6.8s; animation-delay: -3.4s; }
.gem:nth-child(4) .gem__tilt { animation-duration: 9.2s; animation-delay: -1.2s; }

/* Off-screen holder for the shared <symbol> stone artwork that the big cards and
   the chooser buttons both reference. */
.gem-sprite {
  position: absolute;
  width: 0;
  height: 0;
  overflow: hidden;
}

.gem__svg {
  width: 74%;
  height: 92%;
  overflow: visible;
  filter: drop-shadow(0 16px 16px rgba(0, 0, 0, 0.45));
}

/* Star flares breathe very slowly — real sparkle does not blink. */
.glint {
  animation: glint 7s ease-in-out infinite;
}

.gem__name,
.gem__cut {
  display: block;
}

.gem__name {
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}

.gem__cut {
  margin-top: 2px;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(224, 201, 146, 0.8);
}

.file-layer {
  min-height: 100vh;
  min-height: 100dvh;
  display: flex;
  flex-direction: column;
  padding:
    calc(88px + env(safe-area-inset-top))
    18px
    calc(112px + env(safe-area-inset-bottom));
  background:
    radial-gradient(ellipse at 50% 42%, rgba(255, 248, 235, 0.05), transparent 46%);
  /* The cut file has nothing to click, and it is painted over the foot of the
     pinned panel where the chooser lives: it must not eat the chooser's taps. */
  pointer-events: none;
}

.file-layer.is-reveal {
  background:
    radial-gradient(ellipse at 50% 40%, rgba(255, 246, 226, 0.09), transparent 42%),
    radial-gradient(ellipse at 50% 88%, rgba(0, 0, 0, 0.28), transparent 42%);
}

/* Finished-piece reveal. The source clip is shot on a bright studio backdrop,
   so it is dimmed and radially masked: it reads as a soft glow behind the
   completed ring instead of a hard white rectangle on the black page. Opacity
   is driven from app.js so it stays in step with the scroll. */
.file-video {
  position: absolute;
  inset: 0;
  z-index: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 44%;
  opacity: 0;
  pointer-events: none;
  filter: brightness(0.52) saturate(0.88);
  -webkit-mask-image: radial-gradient(ellipse 82% 72% at 50% 44%, #000 0%, rgba(0, 0, 0, 0.72) 58%, transparent 100%);
  mask-image: radial-gradient(ellipse 82% 72% at 50% 44%, #000 0%, rgba(0, 0, 0, 0.72) 58%, transparent 100%);
}

.file-layer > .file-top,
.file-layer > .ring-wrap,
.file-layer > .caption,
.file-layer > .brackets {
  z-index: 1;
}

.file-top,
.ring-wrap,
.caption {
  position: relative;
}

.chrome {
  transition: opacity 0.2s linear;
}

.file-top {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 12px;
  width: min(100%, 640px);
  margin: 0 auto;
}

.file-stone {
  margin-top: 4px;
  font-family: "Cormorant Garamond", Palatino, Georgia, serif;
  font-size: clamp(26px, 7vw, 40px);
  line-height: 0.95;
}

.file-ref {
  font-size: 11px;
  letter-spacing: 0.18em;
  color: rgba(243, 238, 230, 0.55);
}

.brackets {
  position: absolute;
  inset: calc(80px + env(safe-area-inset-top)) 12px calc(96px + env(safe-area-inset-bottom));
  pointer-events: none;
}

.brackets span {
  position: absolute;
  width: 16px;
  height: 16px;
  border: 1px solid rgba(224, 201, 146, 0.72);
}

.brackets span:nth-child(1) { top: 0; left: 0; border-right: 0; border-bottom: 0; }
.brackets span:nth-child(2) { top: 0; right: 0; border-left: 0; border-bottom: 0; }
.brackets span:nth-child(3) { bottom: 0; left: 0; border-right: 0; border-top: 0; }
.brackets span:nth-child(4) { bottom: 0; right: 0; border-left: 0; border-top: 0; }

.ring-wrap {
  position: relative;
  flex: 1;
  min-height: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  width: min(100%, 640px);
  margin: 0 auto;
}

.seat {
  position: absolute;
  left: 50%;
  top: 47.5%;
  width: 1px;
  height: 1px;
}

.ring-svg {
  width: auto;
  height: 100%;
  max-width: 100%;
  max-height: 100%;
  overflow: visible;
}

.draw {
  fill: none;
  stroke: #e6d7b8;
  stroke-width: 1.35;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 1;
  stroke-dashoffset: 1;
}

.melee {
  opacity: 0;
}

/* Soft golden halo under the CAD drawing; stays put through the reveal so the
   finished-piece video blooms out of a lit seat rather than appearing from black. */
.seat-glow {
  opacity: 0.85;
}

.caption {
  position: relative;
  display: grid;
  place-items: center;
  width: min(100%, 640px);
  min-height: 96px;
  margin: 0 auto;
  text-align: center;
}

.caption > * {
  grid-area: 1 / 1;
  width: 100%;
}

.step {
  display: none;
  font-size: 13px;
  letter-spacing: 0.04em;
  color: rgba(243, 238, 230, 0.78);
}

/* Both caption states share the band above the chooser and overhang it a little.
   Neither is interactive, and without this the invisible statement would swallow
   taps meant for the chooser buttons underneath it. */
.caption {
  pointer-events: none;
}

.statement__kicker {
  margin-bottom: 8px;
  font-size: 10px;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #e0c992;
}

.statement__lead {
  font-family: "Cormorant Garamond", Palatino, Georgia, serif;
  font-style: italic;
  font-weight: 500;
  font-size: clamp(28px, 7.6vw, 48px);
  line-height: 1.05;
}

.statement__body {
  max-width: 18em;
  margin: 10px auto 0;
  font-family: "Cormorant Garamond", Palatino, Georgia, serif;
  font-size: clamp(18px, 4.5vw, 26px);
  line-height: 1.25;
  color: rgba(243, 238, 230, 0.86);
}

/* Short panels: the chooser takes a fixed slice off the bottom of the pinned
   panel, and every pixel the statement gives up is a pixel the CAD ring gets. */
@media (max-height: 860px) {
  .caption {
    min-height: 72px;
  }

  .statement__lead {
    font-size: clamp(26px, 6vw, 40px);
  }

  .statement__body {
    margin-top: 8px;
    font-size: clamp(17px, 3.4vw, 22px);
  }
}

/* The chooser is live for the whole story: it picks the stone for the intro and
   stays the only picker once the grid has receded into the cut file. */
.gem-bar {
  transition: opacity 0.4s ease;
}

.colophon {
  padding: 88px 24px calc(56px + env(safe-area-inset-bottom));
  text-align: center;
}

.colophon .display {
  font-size: clamp(36px, 9vw, 64px);
}

.colophon p + p {
  margin-top: 12px;
  font-size: 12px;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(243, 238, 230, 0.5);
}

@keyframes tilt {
  0%,
  100% { transform: rotateY(-15deg) rotateX(7deg) translateY(0); }
  50% { transform: rotateY(14deg) rotateX(-6deg) translateY(-8px); }
}

@keyframes glint {
  0%,
  100% { opacity: 0.68; }
  50% { opacity: 1; }
}

html.is-enhanced:not(.is-reduced) .story {
  height: 680vh;
}

html.is-enhanced:not(.is-reduced) .story__pin {
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow: hidden;
}

html.is-enhanced:not(.is-reduced) .select-layer,
html.is-enhanced:not(.is-reduced) .file-layer {
  position: absolute;
  inset: 0;
  min-height: 0;
}

/* Explicit layering: the settled stone lives in .select-layer and must sit
   underneath the cut file, so the CAD ring closes around it. Without this the
   gem's own z-index (set in app.js) would paint it over the ring instead. */
html.is-enhanced:not(.is-reduced) .select-layer {
  z-index: 1;
}

html.is-enhanced:not(.is-reduced) .file-layer {
  z-index: 2;
}

html.is-enhanced:not(.is-reduced) .file-layer {
  opacity: 0;
}

html.is-enhanced:not(.is-reduced) .chrome {
  opacity: var(--chrome, 0);
}

html.is-enhanced:not(.is-reduced) .step {
  display: block;
}

/* Floating WhatsApp button. The chooser owns the full width at the foot of the
   page, so the button sits above it and stays clear — `--bar` is that chooser's
   measured height, written by app.js. At rest it is a small disc; the name only
   unfolds on hover or keyboard focus, rather than sitting there as a badge
   competing with the jewelry. */
.wa {
  position: fixed;
  z-index: 30;
  right: calc(16px + env(safe-area-inset-right));
  bottom: calc(var(--bar, 0px) + 24px + env(safe-area-inset-bottom));
  display: inline-flex;
  align-items: center;
  gap: 0;
  min-height: 52px;
  padding: 12px;
  border-radius: 999px;
  border: 1px solid rgba(224, 201, 146, 0.4);
  background: rgba(16, 15, 13, 0.9);
  -webkit-backdrop-filter: blur(10px);
  backdrop-filter: blur(10px);
  text-decoration: none;
  box-shadow: 0 14px 30px rgba(0, 0, 0, 0.45);
  transition:
    border-color 0.3s ease,
    background-color 0.3s ease,
    box-shadow 0.3s ease;
}

.wa__icon {
  flex: none;
  width: 24px;
  height: 24px;
  color: #e0c992;
}

.wa__label {
  max-width: 0;
  overflow: hidden;
  white-space: nowrap;
  font-size: 11px;
  font-weight: 500;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: #f3eee6;
  opacity: 0;
  transition: max-width 0.35s ease, opacity 0.25s ease, margin-left 0.35s ease;
}

@media (hover: hover) {
  .wa:hover {
    border-color: rgba(224, 201, 146, 0.9);
    background: rgba(24, 22, 18, 0.94);
    box-shadow: 0 16px 34px rgba(0, 0, 0, 0.55);
  }

  .wa:hover .wa__label {
    max-width: 16ch;
    margin-left: 10px;
    opacity: 1;
  }
}

.wa:focus-visible .wa__label {
  max-width: 16ch;
  margin-left: 10px;
  opacity: 1;
}

.wa:focus-visible {
  outline: 2px solid #e0c992;
  outline-offset: 3px;
}

/* Phones: smaller disc, and the folded name is dropped rather than unfolding over
   the two-row chooser, where there is no room for it. */
@media (max-width: 560px) {
  .wa {
    right: calc(12px + env(safe-area-inset-right));
    bottom: calc(var(--bar, 0px) + 28px + env(safe-area-inset-bottom));
    min-height: 46px;
    padding: 11px;
  }

  .wa__icon {
    width: 20px;
    height: 20px;
  }

  .wa__label,
  .wa:hover .wa__label,
  .wa:focus-visible .wa__label {
    display: none;
  }
}

/* Same panel shape as the two-row chooser: the folded name would reach into it. */
@media (max-height: 780px) and (min-width: 561px) {
  .wa__label,
  .wa:hover .wa__label,
  .wa:focus-visible .wa__label {
    display: none;
  }
}

html.is-enhanced:not(.is-reduced) .statement {
  opacity: 0;
}

/* Once the cut file is up, the chooser holds the foot of the pinned panel and the
   caption sits in the band above it. The caption is pinned to the foot of the
   column, so its distance to the chooser is set by the bottom padding alone —
   independent of how large the ring ends up. The padding clears the prompt line
   of the chooser as well as its buttons. */
html.is-enhanced:not(.is-reduced) .file-layer {
  padding-bottom: calc(160px + var(--bar, 0px) + env(safe-area-inset-bottom));
}

html.is-enhanced:not(.is-reduced) .ring-svg {
  max-height: min(40vh, 380px);
}

html.is-enhanced:not(.is-reduced) .caption {
  margin-top: auto;
}

/* The chooser belongs to the selection screen. As soon as the chosen stone starts
   to fall into the cut file it is gone — it must not float over the animation —
   and app.js restores it when the reader scrolls back to the top. Its space in
   the pinned panel stays reserved, so the caption below keeps its place. */
html.is-enhanced:not(.is-reduced) .gem-bar {
  transition: opacity 0.35s ease;
}

html.is-enhanced:not(.is-reduced).is-past-select .gem-bar {
  opacity: 0;
  pointer-events: none;
}

/* The floating chat button leaves the screen with it: during the cut-file story
   the drawing is the only thing meant to be there. */
html.is-enhanced:not(.is-reduced).is-past-select .wa {
  opacity: 0;
  pointer-events: none;
}

html.is-reduced .story__pin {
  display: flex;
  flex-direction: column;
}

html.is-reduced .ring-wire {
  display: none;
}

html.is-reduced .step {
  display: none;
}

/* Reduced motion keeps the plain stacked layout: no pinning, so the chooser sits
   in the flow right under the grid instead of overlaying the foot of the layer. */
html.is-reduced .gem-bar {
  position: relative;
  left: auto;
  right: auto;
  bottom: auto;
  margin: 4px 0 28px;
  opacity: 1;
  visibility: visible;
}

html.is-reduced .select-layer {
  padding-bottom: 32px;
}

@media (hover: hover) {
  .gem:hover {
    border-color: rgba(224, 201, 146, 0.45);
  }
}

@media (max-height: 700px) {
  .gem__stage {
    height: 124px;
  }

  .select-layer {
    gap: 12px;
    /* `safe` keeps the heading reachable when the intro still overflows. */
    justify-content: safe center;
  }

  .portrait {
    width: min(46vw, 200px);
    margin-bottom: 16px;
  }
}

@media (min-width: 900px) {
  .bio__inner {
    display: grid;
    grid-template-columns: minmax(260px, 0.8fr) 1.1fr;
    gap: 72px;
    align-items: center;
  }

  .portrait {
    width: 100%;
    max-width: 440px;
    margin-bottom: 0;
  }

  .gem-grid {
    grid-template-columns: repeat(4, 1fr);
    gap: 16px;
  }

  .gem__stage {
    height: 208px;
  }

  .select-layer {
    padding-left: 32px;
    padding-right: 32px;
  }
}

/* Short, wide viewports (landscape phones): two rows of taller cards cannot fit
   the pinned 100dvh panel, so go to a single row of four. */
@media (max-height: 560px) and (min-width: 600px) {
  .gem-grid {
    grid-template-columns: repeat(4, 1fr);
    gap: 10px;
  }

  .gem__stage {
    height: 92px;
  }
}

/* Button chooser: the prompt and the four stone buttons sit underneath the
   selection grid and point at the very same stones the cards above show. It is
   the only picker while the scroll story runs, so it keeps working once the
   chosen stone has travelled into the cut file and the grid is gone. */
.gem-bar {
  width: min(100%, 980px);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  gap: 10px;
  user-select: none;
  -webkit-tap-highlight-color: transparent;
}

.gem-bar__prompt {
  font-size: 10px;
  letter-spacing: 0.24em;
  text-transform: uppercase;
  text-align: center;
  color: rgba(243, 238, 230, 0.42);
}

.gem-bar__row {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 10px;
}

.gem-chip {
  display: flex;
  align-items: center;
  gap: 11px;
  min-width: 0;
  min-height: 62px;
  padding: 9px 11px;
  border-radius: 18px;
  border: 1px solid rgba(243, 238, 230, 0.12);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(255, 255, 255, 0.06), transparent 58%),
    #100f0d;
  text-align: left;
  transition: border-color 0.3s ease, background-color 0.3s ease;
}

.gem-chip__art {
  position: relative;
  flex: none;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
}

/* The haze is a pseudo-element rather than a box-shadow so it can hang outside
   the art box without the SVG's drop-shadow filter clipping it. */
.gem-chip__art::after {
  content: "";
  position: absolute;
  inset: -14px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 255, 255, 0.1), rgba(255, 255, 255, 0) 70%);
  pointer-events: none;
}

/* The chip art is a real stone, not a glyph: at 26px the flat-coloured cuts
   (emerald, topaz) read as coloured smudges in a dark room. */
.gem-chip__svg {
  position: relative;
  z-index: 1;
  width: 36px;
  height: 36px;
  overflow: visible;
  filter: drop-shadow(0 3px 4px rgba(0, 0, 0, 0.45)) saturate(1.06) brightness(1.08);
}

.gem-chip__meta {
  min-width: 0;
}

.gem-chip__name,
.gem-chip__cut {
  display: block;
}

.gem-chip__name {
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.13em;
  text-transform: uppercase;
  color: rgba(243, 238, 230, 0.82);
}

.gem-chip__cut {
  margin-top: 3px;
  font-size: 10px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: rgba(224, 201, 146, 0.78);
}

/* Gold outline instead of a gold fill: the button carries the stone itself and
   a solid fill would swallow the artwork. */
.gem-chip[aria-pressed="true"] {
  border-color: rgba(224, 201, 146, 0.9);
  background:
    radial-gradient(120% 90% at 50% 0%, rgba(224, 201, 146, 0.12), transparent 62%),
    #12110e;
}

.gem-chip[aria-pressed="true"] .gem-chip__name {
  color: #f3eee6;
}

.gem-chip[aria-pressed="true"] .gem-chip__art::after {
  background: radial-gradient(circle, rgba(224, 201, 146, 0.24), rgba(224, 201, 146, 0) 70%);
}

@media (hover: hover) {
  .gem-chip:hover {
    border-color: rgba(224, 201, 146, 0.55);
    background-color: #141310;
  }
}

/* In the pinned intro the chooser sits under the stone grid, so the shorter the
   viewport the tighter it has to pack. On phones four side-by-side buttons leave
   no room for the stone names, so the row is a square of four instead. */
@media (max-height: 700px), (max-width: 560px) {
  .gem-bar {
    gap: 8px;
  }

  .gem-bar__row {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: 8px;
  }

  .gem-chip {
    gap: 9px;
    padding: 8px 10px;
  }

  .gem-chip__art {
    width: 38px;
    height: 38px;
  }

  .gem-chip__svg {
    width: 30px;
    height: 30px;
  }
}

@media (max-height: 700px) {
  .select-layer {
    padding-bottom: calc(168px + env(safe-area-inset-bottom));
  }
}

/* A short but wide panel (a small laptop) still has room for the chooser as one
   row of four, which costs half the height of the square and leaves the CAD ring
   the space it needs. */
@media (max-height: 780px) and (min-width: 561px) {
  .gem-bar__prompt {
    display: none;
  }

  .gem-bar__row {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }

  .gem-chip__cut {
    display: none;
  }
}

@media (min-width: 900px) {
  .gem-bar__row {
    gap: 16px;
  }
}

/* Landscape phones: one row of four stones, prompt hidden, art only. */
@media (max-height: 560px) and (min-width: 600px) {
  .select-layer {
    padding-bottom: 24px;
  }

  .gem-bar__prompt {
    display: none;
  }

  .gem-bar__row {
    grid-template-columns: repeat(4, minmax(0, 1fr));
    gap: 10px;
  }

  .gem-chip {
    gap: 8px;
    padding: 6px 10px;
  }

  .gem-chip__art {
    width: 30px;
    height: 30px;
  }

  .gem-chip__svg {
    width: 24px;
    height: 24px;
  }

  .gem-chip__cut {
    display: none;
  }
}

/* Phones: the chooser is a square of four there, so the cut file is tightened to
   keep the ring and its caption above it. The bottom padding itself comes from the
   chooser-aware rule above, which is not overridden here. */
@media (max-width: 560px) {
  .file-layer {
    padding-top: calc(64px + env(safe-area-inset-top));
    padding-left: 16px;
    padding-right: 16px;
    gap: 4px;
  }

  .file-top {
    margin-bottom: 2px;
  }

  .file-stone {
    font-size: clamp(22px, 6.4vw, 32px);
  }

  .ring-svg {
    max-height: min(38vh, 320px);
  }

  .statement__lead {
    font-size: clamp(15px, 4.2vw, 19px);
  }

  .statement__body {
    max-width: 22em;
    font-size: clamp(16px, 4.6vw, 22px);
  }
}

@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .gem__tilt,
  .glint { animation: none; }
}


/* Philosophy: the long read of the page. A narrow measure keeps the blocks of
   prose readable — columns wider than about 65 characters look like a wall of
   text at this size — and the type is deliberately quiet, because the subject
   (being deceived) carries the weight, not the styling. */
.philosophy {
  padding: 120px 22px 112px;
}

.philosophy__inner {
  width: min(100%, 900px);
  margin: 0 auto;
  text-align: center;
}

.philosophy .display {
  margin-bottom: 40px;
}

.philosophy__lead {
  max-width: 26em;
  margin: 0 auto;
  font-family: "Cormorant Garamond", Palatino, Georgia, serif;
  font-size: clamp(24px, 3.6vw, 34px);
  line-height: 1.25;
  color: rgba(243, 238, 230, 0.92);
}

/* Justified inside a deliberately narrow measure, with hyphenation: that is how
   the text ends up in clean blocks instead of a ragged edge, which is what a
   catalogue of this kind looks like. Chrome hyphenates from the document's lang
   attribute, so this works for German and English alike. */
.philosophy__text {
  max-width: 44em;
  margin: 26px auto 0;
  text-align: justify;
  -webkit-hyphens: auto;
  hyphens: auto;
  font-size: 17px;
  line-height: 1.75;
  color: rgba(243, 238, 230, 0.68);
}

/* The prose is one argument in four steps, so the paragraphs sit closer to each
   other than to the lead and the closing statement around them. */
.philosophy__text + .philosophy__text {
  margin-top: 18px;
}

.philosophy__statement {
  max-width: 30em;
  margin: 52px auto 0;
  padding-top: 40px;
  border-top: 1px solid rgba(224, 201, 146, 0.22);
  font-family: "Cormorant Garamond", Palatino, Georgia, serif;
  font-size: clamp(20px, 3vw, 28px);
  line-height: 1.35;
  color: #e0c992;
}

@media (max-width: 560px) {
  .philosophy {
    padding: 88px 18px 80px;
  }

  .philosophy .display {
    margin-bottom: 28px;
  }

  .philosophy__text {
    font-size: 16px;
    line-height: 1.7;
  }

  .philosophy__statement {
    margin-top: 40px;
    padding-top: 28px;
  }
}

.contact {
  padding: 120px 22px;
  background: #070707;
  text-align: center;
}

.contact__inner {
  width: min(100%, 1080px);
  margin: 0 auto;
}

.contact__header {
  margin-bottom: 64px;
}

.contact__header .display {
  margin-bottom: 24px;
}

.contact__text {
  max-width: 42em;
  margin: 0 auto;
  font-size: 18px;
  line-height: 1.6;
  color: rgba(243, 238, 230, 0.65);
}

.contact__links-container {
  display: flex;
  justify-content: center;
}

.contact__links {
  align-items: center;
  display: flex;
  flex-direction: column;
  gap: 16px;
  width: min(340px, 100%);
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 56px;
  padding: 22px 40px;
  border-radius: 2px;
  text-decoration: none;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: all 0.3s ease;
  border: 1px solid rgba(224, 201, 146, 0.3);
  background: transparent;
  color: #f3eee6;
}

.btn:hover {
  background: #e0c992;
  color: #16140f;
  border-color: #e0c992;
}

.footer-note {
  margin-top: 40px;
  font-size: 10px;
  line-height: 1.6;
  letter-spacing: 0.04em;
  color: rgba(243, 238, 230, 0.35);
  max-width: 600px;
  margin-left: auto;
  margin-right: auto;
}

.contact__email {
  display: block;
  padding: 12px 0;
  margin-bottom: 4px;
  font-size: 14px;
  letter-spacing: 0.05em;
  color: rgba(243, 238, 230, 0.65);
  text-decoration: none;
  transition: color 0.3s ease;
  font-family: "Cormorant Garamond", serif;
  font-style: italic;
}

.contact__email:hover {
  color: #e0c992;
}

.bio {
  position: relative;
  overflow: hidden;
}

/* Still hero backdrop. Replaces the old 7 MB autoplay background video, which
   now plays once as the finished-piece reveal at the end of the scroll story. */
.bio__media {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 62% 44%;
  z-index: -2;
}

.bio::before {
  content: "";
  position: absolute;
  inset: 0;
  background: linear-gradient(
    to bottom,
    rgba(7, 7, 7, 0.6),
    rgba(7, 7, 7, 0.8),
    rgba(7, 7, 7, 0.9)
  );
  z-index: -1;
}

.bio__inner {
  position: relative;
  z-index: 1;
}

/* ---------- Portfolio / Galerie (brief module 4) ---------- */
.gallery {
  padding: 104px 22px 20px;
  background: #070707;
}

.gallery__inner {
  width: min(100%, 1080px);
  margin: 0 auto;
}

.gallery__header {
  margin-bottom: 48px;
  text-align: center;
}

.gallery__header .display {
  margin-top: 12px;
  font-size: clamp(30px, 7.4vw, 58px);
  line-height: 1;
}

.gallery__text {
  max-width: 44em;
  margin: 18px auto 0;
  font-size: 15.5px;
  line-height: 1.65;
  color: rgba(243, 238, 230, 0.65);
}

.gallery__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 12px;
}

.gallery__tile {
  position: relative;
  overflow: hidden;
  aspect-ratio: 4 / 5;
  border-radius: 2px;
  background: #100f0d;
}

.gallery__tile img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  transition: transform 0.7s ease;
}

@media (hover: hover) {
  .gallery__tile:hover img {
    transform: scale(1.04);
  }
}

/* Placeholder tile from the brief: one sparkling stone plus an invitation. */
.gallery__tile--cta img {
  opacity: 0.45;
}

.gallery__cta {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 28px 22px;
  text-align: center;
  background: radial-gradient(ellipse at 50% 50%, rgba(7, 7, 7, 0.5), rgba(7, 7, 7, 0.88));
}

.gallery__cta-title {
  font-family: "Cormorant Garamond", Palatino, Georgia, serif;
  font-size: clamp(24px, 6vw, 32px);
  line-height: 1.05;
}

.gallery__cta-body {
  max-width: 20em;
  font-size: 13.5px;
  line-height: 1.55;
  color: rgba(243, 238, 230, 0.75);
}

.gallery__cta .btn {
  width: 100%;
  max-width: 300px;
  min-height: 52px;
  padding: 16px 20px;
  font-size: 11px;
}

@media (min-width: 620px) {
  .gallery__grid {
    grid-template-columns: repeat(2, 1fr);
    gap: 14px;
  }
}

@media (min-width: 1000px) {
  .gallery__grid {
    grid-template-columns: repeat(3, 1fr);
    gap: 16px;
  }
}

@media (prefers-reduced-motion: reduce) {
  .gallery__tile img,
  .gallery__tile:hover img {
    transition: none;
    transform: none;
  }
}
