:root {
  --wb-ink: #153f4a;
  --wb-rain-ink: rgba(253, 255, 255, 0.99);
  --wb-rain-shadow:
    0 0 12px rgba(255, 255, 255, 0.52),
    0 3px 12px rgba(4, 57, 80, 0.28);
}

html,
body,
.rain-preview,
.underwater-stage {
  min-height: 100dvh;
}

/* Keep one authoritative two-size rain scale so later styles do not shrink it. */
.worry-piece {
  font-size: clamp(1rem, 1.15vw, 1.125rem);
}

.worry-rain.is-featured .worry-piece,
.worry-rain[data-depth="near"] .worry-piece {
  font-size: clamp(1.06rem, 1.22vw, 1.2rem);
}

/* The public rain and the submitted sentence belong to the same visual voice.
   Depth changes visibility, not the ink or edge treatment. */
.worry-rain,
.submitted-worry {
  color: var(--wb-rain-ink);
  text-shadow: var(--wb-rain-shadow);
}

.rain-field.is-reading.has-focus-target .worry-rain:not(.is-reading-target) {
  opacity: 0.28 !important;
  filter: blur(0.35px);
}

.rain-field.is-reading .worry-rain.is-reading-target {
  z-index: 8;
  color: #fff;
  opacity: 1 !important;
  filter: none;
  text-shadow: 0 3px 22px rgba(18, 77, 92, 0.34), 0 0 18px rgba(255, 255, 255, 0.7);
}

.ocean-tool {
  min-width: 44px;
  min-height: 44px;
}

/* The rain field itself stays transparent to input. Only visible sentences
   become touch targets; the z-index 6 ocean tools remain above them. */
@media (hover: none), (pointer: coarse), (any-pointer: coarse) {
  /* A continuously translating button can move between touch-down and
     touch-up on phones. Keep both destinations stationary on touch devices;
     the surrounding rain remains animated. */
  .ocean-tool {
    animation: none !important;
  }

  body:not(.cover-open):not(.story-active):not(.story-diving):not(.profile-layer-open)
    .rain-field .worry-rain:not(.is-density-rest) {
    min-width: 44px;
    min-height: 44px;
    pointer-events: auto;
    touch-action: manipulation;
    -webkit-tap-highlight-color: transparent;
  }

  /* A tap holds one sentence still for reading, but it must not erase the
     surrounding rain or ask a mobile GPU to blur every other sentence. */
  .rain-field.is-reading.has-focus-target .worry-rain:not(.is-reading-target) {
    opacity: var(--depth-opacity, 0.7) !important;
    filter: none;
  }

  /* Do not reserve a separate filtered compositor layer for every character
     while the first rain is entering. The short water-contact dissolve can
     promote only the characters that are actually impacting. */
  .worry-group {
    will-change: transform, opacity;
  }
  .worry-char {
    will-change: auto;
  }
  .worry-rain.is-impacting .worry-char {
    will-change: transform, opacity, filter;
  }
}

@media (max-width: 760px) {
  .worry-piece,
  .worry-rain.is-featured .worry-piece {
    font-size: 0.94rem;
  }

  .worry-rain.is-featured .worry-piece,
  .worry-rain[data-depth="near"] .worry-piece {
    font-size: 1rem;
  }
}

@media (prefers-reduced-motion: reduce) {
  .rain-field.is-reading.has-focus-target .worry-rain:not(.is-reading-target) {
    filter: none;
  }
}

/* Keep the selected sentence inside the narrow visual viewport. */
@media (orientation: portrait) and (max-width: 430px) {
  .rain-field.is-reading.has-focus-target .worry-rain.is-reading-target {
    translate: 0 var(--reading-shift-y, 0px);
  }
}

/* In a short landscape viewport, compact only the selected longer sentence
   and translate it as a whole so reading never changes the rain animation. */
@media (orientation: landscape) and (max-height: 430px) {
  .rain-field.is-reading.has-focus-target .worry-rain.is-reading-target {
    translate: 0 var(--reading-shift-y, 0px);
  }

  .rain-field.is-reading.has-focus-target .worry-rain.is-reading-target:is(.is-medium-copy, .is-long-copy) .worry-piece {
    font-size: 0.86rem;
    letter-spacing: 0.08em;
  }
}
