/* Layout: a top-down beach. Sand fills the screen, the sea runs along the bottom edge,
   and each page is writing in the sand that the next wave washes away. */
:root {
  --sand: #f2dcae;
  --groove: #7a5428;       /* writing in the sand (fallback when filters are off) */
  --ink: #0e4a5c;          /* deep sea teal */
  --coral-bright: #f2644e; /* focus rings */

  --font-script: "Yellowtail", "Brush Script MT", "Segoe Script", cursive;
  --font-hand: "Playpen Sans", "Segoe Print", "Bradley Hand", "Comic Sans MS", cursive;
  --font-body: "Figtree", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  --stone-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='g' x='0' y='0' width='100%25' height='100%25'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.045' numOctaves='5' seed='3' stitchTiles='stitch' result='m'/%3E%3CfeColorMatrix in='m' type='saturate' values='0' result='mg'/%3E%3CfeComponentTransfer in='mg' result='mottle'%3E%3CfeFuncR type='linear' slope='1.25' intercept='-.125'/%3E%3CfeFuncG type='linear' slope='1.25' intercept='-.125'/%3E%3CfeFuncB type='linear' slope='1.25' intercept='-.125'/%3E%3CfeFuncA type='linear' slope='0' intercept='1'/%3E%3C/feComponentTransfer%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='1' seed='9' stitchTiles='stitch' result='f'/%3E%3CfeColorMatrix in='f' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 4.2 0 0 0 -2.9' result='dark'/%3E%3CfeColorMatrix in='f' type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 4.2 0 0 -3' result='light'/%3E%3CfeMerge%3E%3CfeMergeNode in='mottle'/%3E%3CfeMergeNode in='dark'/%3E%3CfeMergeNode in='light'/%3E%3C/feMerge%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23g)'/%3E%3C/svg%3E");
  color-scheme: light;
}

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

html, body { height: 100%; }

body {
  margin: 0;
  background: var(--sand);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  -webkit-tap-highlight-color: transparent;
}

.js body { overflow: hidden; overscroll-behavior: none; }

/* ---------- The beach stage ---------- */

.beach {
  position: relative;
  --heart-top: max(calc(env(safe-area-inset-top, 0px) + 0.5rem), 2vh);
  --heart-h: clamp(56px, calc(var(--dry-h, 18vh) - var(--heart-top)), 124px);
}

.js .beach {
  position: fixed;
  inset: 0;
  overflow: hidden;
  touch-action: pinch-zoom;
  user-select: none;
  -webkit-user-select: none;
}

.sand {
  position: absolute;
  inset: 0;
  background-color: var(--sand);
  background-image:
    var(--grain, linear-gradient(transparent, transparent)),
    radial-gradient(110% 60% at 18% 8%, rgba(255, 249, 232, 0.6), transparent 60%),
    radial-gradient(80% 55% at 88% 55%, rgba(214, 176, 112, 0.28), transparent 65%),
    radial-gradient(70% 40% at 10% 80%, rgba(230, 196, 140, 0.35), transparent 70%),
    linear-gradient(to bottom, #f7e6c1 0%, #f1d9a9 65%, #e8c993 100%);
  background-size: 240px 240px, auto, auto, auto, auto;
}

.ground, .sea {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  display: block;
}

.wet { position: absolute; left: 0; top: 0; pointer-events: none; display: block; }

.critters { position: absolute; inset: 0; pointer-events: none; }

.decor { position: absolute; inset: 0; pointer-events: none; }
.decor__item { position: absolute; height: auto; filter: drop-shadow(0 2px 1.5px rgba(120, 85, 40, 0.25)); }
.decor__scallop { width: 34px; left: -6px; top: 24%; transform: rotate(-18deg); }
.decor__starfish { width: 44px; left: 5%; top: 69%; transform: rotate(14deg); }
.decor__spiral { width: 30px; left: 9%; top: 9%; transform: rotate(-30deg); }
.decor__pebbles { width: 52px; left: 12%; top: 90.5%; }
.decor__dollar { width: 28px; left: 22%; top: 80%; transform: rotate(20deg); }
.monogram {
  position: absolute;
  left: 50%;
  top: var(--heart-top);
  height: var(--heart-h);
  width: auto;
  overflow: visible;
  color: var(--groove);
  transform: translateX(-50%) rotate(-5deg);
  filter: url(#sand-lg);
}
.sand-filters { position: absolute; width: 0; height: 0; overflow: hidden; }
.nest { position: absolute; width: 66px; height: auto; left: 0; top: 0; transform: translate(-50%, -50%); transition: opacity 0.6s ease; }
.is-playground .nest { opacity: 0; }   /* the playground pebbles sit in that corner, and the turtle is long gone */

/* ---------- Pages: writing in the wet sand ---------- */

.js .pages { position: absolute; inset: 0; pointer-events: none; }

.page {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 12vh 24px;
  min-height: 100vh;
  outline: none;
}

/* Waves run about three quarters of the way up the beach, so the writing sits below
   that line. If a page is too tall it grows upwards and the waves reach further. */
.js .page {
  position: absolute;
  inset: 0;
  min-height: 0;
  flex-direction: column;
  justify-content: flex-end;
  padding:
    max(var(--wet-top, 34vh), calc(env(safe-area-inset-top, 0px) + 1rem))
    max(28px, calc(env(safe-area-inset-right, 0px) + 16px))
    calc(var(--shore-gap, 16vh) + 4rem)
    max(34px, calc(env(safe-area-inset-left, 0px) + 22px));
  visibility: hidden;
}

.js .page.is-active { visibility: visible; }
.js .page a, .js .page button { pointer-events: auto; }

.page__inner {
  width: 100%;
  max-width: 36rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: clamp(0.4rem, 1.5vh, 0.95rem);
  text-align: center;
}

.js .page__inner { margin-block: auto; will-change: transform; }
.page__inner > * { margin: 0; }

/* Everything written in the sand is carved by one of the SVG filters in index.html */
.names, .calendar__day { filter: url(#sand-xl); }
.script, .venue { filter: url(#sand-lg); }
.eyebrow, .lede, .date-chip, .calendar__side, .detail, .note, .hashtag, .couple__parents { filter: url(#sand-sm); }

.names, .calendar__day, .script, .venue, .eyebrow, .lede, .date-chip, .calendar__side, .couple__parents,
.detail, .note, .hashtag {
  color: var(--groove);
}

.eyebrow {
  font-family: var(--font-hand);
  font-weight: 600;
  font-size: clamp(0.78rem, 0.62rem + 0.6vw, 0.98rem);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  text-wrap: balance;
}

.names {
  font-family: var(--font-script);
  font-weight: 400;
  font-size: clamp(3.1rem, min(1.6rem + 8vw, 11.5vh), 7.4rem);
  line-height: 1.04;
  text-wrap: balance;
  padding-inline: 0.2em;
}
.names--small { font-size: clamp(2.6rem, min(1.2rem + 6.5vw, 9vh), 5.4rem); }

/* Welcome: each name on its own line with their parents written small underneath */
.couple {
  display: flex;
  flex-direction: column;
  align-items: center;
  font-size: 1rem;
}
.couple__person { display: flex; flex-direction: column; align-items: center; }
.couple .names { font-size: clamp(2.7rem, min(1.4rem + 7vw, 8.6vh), 5.6rem); line-height: 1; }
.couple .names__amp { font-size: clamp(2.2rem, min(1.2rem + 4.6vw, 6.2vh), 3.6rem); margin-top: 0.08em; filter: url(#sand-lg); }
.couple__parents {
  font-family: var(--font-hand);
  font-weight: 500;
  font-size: clamp(0.9rem, 0.78rem + 0.45vw, 1.08rem);
  line-height: 1.3;
  text-wrap: balance;
}

.lede {
  font-family: var(--font-hand);
  font-weight: 500;
  font-size: clamp(1.08rem, 0.9rem + 0.7vw, 1.4rem);
  line-height: 1.35;
  text-wrap: balance;
  max-width: 26ch;
}

.date-chip {
  margin-top: 0.35rem !important;
  font-family: var(--font-hand);
  font-weight: 700;
  font-size: clamp(0.82rem, 0.66rem + 0.7vw, 1rem);
  letter-spacing: 0.12em;
  text-transform: uppercase;
  border: 2.5px solid currentColor;
  border-radius: 999px;
  padding: 0.55em 1.25em;
}

.script {
  font-family: var(--font-script);
  font-weight: 400;
  font-size: clamp(2.2rem, min(1.2rem + 5vw, 7.2vh), 4rem);
  line-height: 1.06;
  text-wrap: balance;
  padding-inline: 0.2em;
}

.calendar {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: clamp(0.8rem, 3vw, 1.4rem);
  line-height: 1;
}
.calendar__side {
  font-family: var(--font-hand);
  font-weight: 600;
  font-size: clamp(0.85rem, 0.7rem + 0.6vw, 1.05rem);
  letter-spacing: 0.16em;
  text-transform: uppercase;
  line-height: 1.3;
  width: 6.6em;
  padding-block: 0.4em;
  border-block: 2px solid currentColor;
  filter: url(#sand-sm);
}
.calendar__day {
  font-family: var(--font-hand);
  font-weight: 700;
  font-size: clamp(3.6rem, min(2rem + 8vw, 10vh), 6rem);
  line-height: 0.9;
}

.detail {
  font-family: var(--font-hand);
  font-weight: 500;
  font-size: clamp(1.02rem, 0.92rem + 0.5vw, 1.22rem);
  text-wrap: balance;
}
.detail strong { font-weight: 700; }

.countdown {
  font-weight: 700;
  font-size: 0.84rem;
  line-height: 1;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  padding: 0.85em 1.5em 0.9em;
  border-radius: 1.9em 2.3em 2em 2.4em / 1.35em 1.5em 1.4em 1.3em;
  transform: rotate(1.5deg);
}

.venue {
  font-family: var(--font-hand);
  font-weight: 600;
  font-size: clamp(1.55rem, min(1.1rem + 2.6vw, 4.6vh), 2.4rem);
  line-height: 1.18;
  text-wrap: balance;
}

.note {
  font-family: var(--font-hand);
  font-weight: 500;
  font-size: clamp(0.95rem, 0.88rem + 0.3vw, 1.08rem);
  line-height: 1.45;
  max-width: 30rem;
  text-wrap: pretty;
}

.hashtag { font-family: var(--font-hand); font-weight: 600; letter-spacing: 0.03em; }

/* ---------- Pebbles ----------
   Buttons and little markers are smooth beach stones: an uneven rounded shape, speckled grain,
   a wet shine on top, shade underneath and a soft shadow on the sand. Lettering is painted on. */
.btn, .countdown, .hint, .sandnote, .playtool, .dots button::before {
  --stone-light: #a3adae;
  --stone: #66767a;
  --stone-dark: #364347;
  --stone-drop: 0 5px 7px -2px rgba(74, 48, 18, 0.5), 0 1px 1px rgba(74, 48, 18, 0.3);
  --shine: 0.32;
  background:
    radial-gradient(46% 36% at 34% 24%, rgba(255, 255, 255, var(--shine)), transparent 72%),
    var(--stone-grain),
    radial-gradient(130% 150% at 28% 16%, var(--stone-light), var(--stone) 46%, var(--stone-dark));
  background-size: auto, 220px 220px, auto;
  background-blend-mode: normal, soft-light, normal;
  box-shadow:
    inset 0 2px 1px rgba(255, 255, 255, 0.3),
    inset 0 -4px 6px rgba(0, 0, 0, 0.26),
    var(--stone-drop);
}

.btn, .countdown, .hint, .sandnote, .playtool {
  font-family: var(--font-hand);
  color: var(--paint, #fbf6ea);
  text-shadow: var(--paint-shadow, 0 1px 0 rgba(0, 0, 0, 0.3));
}

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.5em;
  margin-top: 0.45rem !important;
  font-weight: 700;
  font-size: 1.02rem;
  line-height: 1;
  letter-spacing: 0.02em;
  border: 0;
  border-radius: 2.2em 3em 2.5em 3.4em / 1.45em 1.95em 1.65em 1.3em;
  padding: 1.1em 1.8em 1.15em;
  text-decoration: none;
  cursor: pointer;
  --paint: #fbf6ea;
  --paint-shadow: 0 1px 0 rgba(0, 0, 0, 0.3);
  --tilt: -1.2deg;
  transform: rotate(var(--tilt));
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.btn:hover {
  transform: rotate(var(--tilt)) translateY(-2px);
  --stone-drop: 0 10px 14px -4px rgba(74, 48, 18, 0.42), 0 2px 2px rgba(74, 48, 18, 0.22);
}
.btn:active {
  transform: rotate(var(--tilt)) translateY(2px);
  --stone-drop: 0 2px 3px -1px rgba(74, 48, 18, 0.55);
}

/* golden sandstone for the countdown */
.countdown {
  --stone-light: #f8d68a;
  --stone: #dcaa4c;
  --stone-dark: #a2721f;
  --paint: #43290c;
  --paint-shadow: 0 1px 0 rgba(255, 240, 200, 0.45);
}

/* red jasper for the one that matters most */
.btn--big {
  font-size: 1.14rem;
  border-radius: 3em 2.3em 3.3em 2.4em / 1.9em 1.4em 1.35em 1.75em;
  --tilt: 1deg;
  --stone-light: #e48d6b;
  --stone: #b8573b;
  --stone-dark: #763020;
}

/* pale limestone */
.btn--ghost {
  border-radius: 2.4em 3.2em 2.2em 2.9em / 1.4em 1.85em 1.7em 1.55em;
  --tilt: 0.8deg;
  --stone-light: #f6efe3;
  --stone: #d9cdb8;
  --stone-dark: #a69779;
  --paint: #4a3b26;
  --paint-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
}

:focus-visible { outline: 3px solid var(--coral-bright); outline-offset: 3px; }

/* ---------- Navigation ---------- */

.dots {
  position: absolute;
  left: max(6px, env(safe-area-inset-left, 0px));
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  flex-direction: column;
  gap: 2px;
  z-index: 5;
}
.dots button {
  width: 24px;
  height: 24px;
  display: grid;
  place-items: center;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}
.dots button::before {
  content: "";
  width: 9px;
  height: 8px;
  border-radius: 50% 50% 46% 54% / 58% 52% 48% 42%;
  --stone-light: #d3cbbc;
  --stone: #9b9284;
  --stone-dark: #645c50;
  --shine: 0.45;
  box-shadow: inset 0 -1px 2px rgba(0, 0, 0, 0.3), 0 2px 2px -1px rgba(74, 48, 18, 0.55);
  transition: width 0.3s ease, height 0.3s ease;
}
.dots button:hover::before { --stone: #7f7669; }
.dots button[aria-current="step"]::before {
  width: 14px;
  height: 12px;
  --stone-light: #e48d6b;
  --stone: #b8573b;
  --stone-dark: #763020;
}

.hint {
  position: absolute;
  left: 50%;
  bottom: calc(var(--shore-gap, 16vh) + 0.35rem);
  transform: translateX(-50%) rotate(-1deg);
  z-index: 5;
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  gap: 0.15rem;
  padding: 0.8rem 1.4rem 0.5rem;
  border: 0;
  border-radius: 3.2em 3.8em 3.5em 4em / 2.4em 2.6em 2.3em 2.2em;
  font-weight: 700;
  font-size: 0.72rem;
  line-height: 1;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  cursor: pointer;
  white-space: nowrap;
  transition: opacity 0.4s ease;
  --stone-light: #f6efe3;
  --stone: #dccfba;
  --stone-dark: #ab9c7f;
  --paint: #4a3b26;
  --paint-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
}
.hint__icon { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; animation: bob 1.6s ease-in-out infinite; }
.hint.is-hidden, .is-busy .hint { opacity: 0; pointer-events: none; }

@keyframes bob { 50% { transform: translateY(4px); } }

/* ---------- Turtle ---------- */

.turtle {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--tw, 50px);
  height: calc(var(--tw, 50px) * 1.4);
  margin: calc(var(--tw, 50px) * -0.7) 0 0 calc(var(--tw, 50px) * -0.5);
  will-change: transform, opacity;
}
.turtle svg { display: block; width: 100%; height: 100%; overflow: visible; }
.turtle .flip { transition: transform 0.4s ease; }
.turtle.is-swimming { opacity: 0.9; filter: saturate(0.9) brightness(1.04); }
.turtle.is-crawling .flip-fl { animation: crawl-front-l 0.7s ease-in-out infinite; }
.turtle.is-crawling .flip-fr { animation: crawl-front-r 0.7s ease-in-out infinite; }
.turtle.is-crawling .flip-bl { animation: crawl-back 0.7s ease-in-out infinite; }
.turtle.is-crawling .flip-br { animation: crawl-back 0.7s ease-in-out infinite reverse; }
.turtle.is-crawling .body { animation: sway 0.7s ease-in-out infinite; }
.turtle.is-swimming .flip-fl { animation: swim-l 1.6s ease-in-out infinite; }
.turtle.is-swimming .flip-fr { animation: swim-r 1.6s ease-in-out infinite; }
.turtle.is-resting .head { animation: peek 4.5s ease-in-out infinite; }

@keyframes crawl-front-l { 0%, 100% { transform: rotate(-26deg); } 50% { transform: rotate(18deg); } }
@keyframes crawl-front-r { 0%, 100% { transform: rotate(-18deg); } 50% { transform: rotate(26deg); } }
@keyframes crawl-back { 0%, 100% { transform: rotate(-14deg); } 50% { transform: rotate(14deg); } }
@keyframes sway { 0%, 100% { transform: rotate(-3deg); } 50% { transform: rotate(3deg); } }
@keyframes swim-l { 0%, 100% { transform: rotate(-34deg); } 50% { transform: rotate(22deg); } }
@keyframes swim-r { 0%, 100% { transform: rotate(34deg); } 50% { transform: rotate(-22deg); } }
@keyframes peek { 0%, 70%, 100% { transform: translateY(0); } 78%, 90% { transform: translateY(-2px); } }

/* ---------- Crabs ---------- */

.crab {
  position: absolute;
  left: 0;
  top: 0;
  width: 22px;
  height: 16px;
  margin: -8px 0 0 -11px;
  pointer-events: auto;
  cursor: pointer;
  will-change: transform;
}
.crab svg { display: block; width: 100%; height: 100%; overflow: visible; }
.crab::before { content: ""; position: absolute; inset: -12px; } /* easier to tap */
.crab .leg-a { animation: leg 0.16s ease-in-out infinite alternate; }
.crab .leg-b { animation: leg 0.16s ease-in-out infinite alternate-reverse; }
.crab.is-paused .leg-a, .crab.is-paused .leg-b { animation-play-state: paused; }
.crab.is-paused .claw-l { animation: snap-l 0.45s ease-in-out infinite alternate; }
.crab.is-paused .claw-r { animation: snap-l 0.45s ease-in-out infinite alternate; }
.crab.is-panic .leg-a, .crab.is-panic .leg-b { animation-duration: 0.07s; }
.crab.is-panic .claw-l { animation: snap-l 0.12s ease-in-out infinite alternate; }
.crab.is-panic .claw-r { animation: snap-l 0.12s ease-in-out infinite alternate; }

@keyframes leg { from { transform: rotate(-10deg); } to { transform: rotate(10deg); } }
@keyframes snap-l { from { transform: rotate(0deg); } to { transform: rotate(-16deg); } }

/* ---------- Sand playground ---------- */

.sandpad {
  position: absolute;
  inset: 0;
  display: none;
  touch-action: none;
  cursor: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24'%3E%3Ccircle cx='12' cy='12' r='5.5' fill='rgba(255,247,226,0.6)' stroke='%235b3c19' stroke-width='1.6'/%3E%3C/svg%3E") 12 12, crosshair;
  transition: opacity 0.8s ease;
}
.is-playground .sandpad { display: block; }
.sandpad.is-leaving { opacity: 0; }
.sandpad canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; transition: opacity 1.2s ease; }
.sandpad__rim { opacity: 0.6; filter: blur(0.8px); }
.sandpad__groove { opacity: 0.85; }
.sandpad.is-fading canvas { opacity: 0; }

/* the instructions: a message painted on a big flat stone, put away with "Okay" */
.sandnote {
  pointer-events: auto;
  width: min(100%, 22rem);
  display: grid;
  justify-items: center;
  gap: 0.5rem;
  padding: 1.5rem 1.6rem 1.35rem;
  border-radius: 3.2em 4.2em 3.6em 4.6em / 2.8em 3.4em 3em 2.6em;
  transform: rotate(-1deg);
  transition: opacity 0.35s ease, transform 0.35s ease;
  --stone-light: #f8f2e8;
  --stone: #e2d7c3;
  --stone-dark: #b3a385;
  --shine: 0.22;
  --stone-drop: 0 12px 20px -8px rgba(74, 48, 18, 0.5), 0 2px 2px rgba(74, 48, 18, 0.25);
  --paint: #4a3b26;
  --paint-shadow: 0 1px 0 rgba(255, 255, 255, 0.45);
}
.sandnote > * { margin: 0; }
.sandnote__title {
  font-family: var(--font-script);
  font-weight: 400;
  font-size: clamp(2.1rem, 1.6rem + 2vw, 2.6rem);
  line-height: 1.05;
  color: #a5432a;
}
.sandnote__text { font-weight: 500; font-size: 0.98rem; line-height: 1.45; max-width: 19rem; text-wrap: pretty; }
.sandnote__ok { min-width: 7.5em; }
.sandnote.is-closing { opacity: 0; transform: rotate(-1deg) translateY(10px) scale(0.94); }

/* "Sand playground", written in the dry sand under the heart: it's written in from left
   to right when the page arrives and fades as a wave carries guests away */
.playground-title {
  position: absolute;
  left: 50%;
  top: calc(var(--heart-top) + var(--heart-h) - 0.1rem);
  margin: 0;
  padding: 0.1em 0.4em 0.3em;   /* room for the script's flourishes, which the write-on mask would trim */
  font-family: var(--font-script);
  font-weight: 400;
  font-size: clamp(1.9rem, 1.5rem + 1.6vw, 2.5rem);
  line-height: 1.1;
  white-space: nowrap;
  color: var(--groove);
  filter: url(#sand-lg);
  transform: translateX(-50%) rotate(-2deg);
  transition: opacity 0.7s ease;
  -webkit-mask-image: linear-gradient(90deg, #000 45%, transparent 55%);
  mask-image: linear-gradient(90deg, #000 45%, transparent 55%);
  -webkit-mask-size: 230% 100%;
  mask-size: 230% 100%;
  -webkit-mask-position: 0 0;
  mask-position: 0 0;
}
.js .page--playground.is-active .playground-title { animation: write-on 1.6s ease-out 0.5s both; }
.page.is-leaving .playground-title { opacity: 0; }

@keyframes write-on {
  from { -webkit-mask-position: 100% 0; mask-position: 100% 0; }
  to { -webkit-mask-position: 0 0; mask-position: 0 0; }
}

/* corner pebbles: crab on/off in the top left, a wave to reset the sand in the top right */
.playtools {
  position: absolute;
  top: max(10px, calc(env(safe-area-inset-top, 0px) + 8px));
  left: max(10px, calc(env(safe-area-inset-left, 0px) + 8px));
  right: max(10px, calc(env(safe-area-inset-right, 0px) + 8px));
  z-index: 5;
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  pointer-events: none;   /* the sand between the two pebbles stays drawable */
  opacity: 0;
  visibility: hidden;
  transition: opacity 0.5s ease, visibility 0s linear 0.5s;
}
.is-playground .playtools { opacity: 1; visibility: visible; transition: opacity 0.5s ease 0.3s, visibility 0s; }
.playtool {
  pointer-events: auto;
  display: grid;
  justify-items: center;
  gap: 0.2rem;
  width: 4.3rem;
  padding: 0.55rem 0.3rem 0.5rem;
  border: 0;
  border-radius: 1.6rem 1.9rem 1.7rem 2rem / 1.4rem 1.6rem 1.5rem 1.3rem;
  font-weight: 700;
  font-size: 0.62rem;
  line-height: 1;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  cursor: pointer;
  transform: rotate(var(--tilt));
  transition: transform 0.18s ease, box-shadow 0.18s ease;
}
.playtool:hover {
  transform: rotate(var(--tilt)) translateY(-2px);
  --stone-drop: 0 10px 14px -4px rgba(74, 48, 18, 0.42), 0 2px 2px rgba(74, 48, 18, 0.22);
}
.playtool:active {
  transform: rotate(var(--tilt)) translateY(2px);
  --stone-drop: 0 2px 3px -1px rgba(74, 48, 18, 0.55);
}
.playtool__icon {
  width: 1.45rem;
  height: 1.45rem;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.8;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.playtool__icon circle { fill: currentColor; stroke: none; }
.playtool__slash { display: none; stroke-width: 2.4; }
.playtool__off { display: none; }

/* crab on: red jasper with the crab painted white */
.playtool--crab {
  --tilt: 4deg;
  --stone-light: #e48d6b;
  --stone: #b8573b;
  --stone-dark: #763020;
  --paint: #fbf6ea;
  --paint-shadow: 0 1px 0 rgba(0, 0, 0, 0.3);
}
/* crab off: a pale stone, the crab crossed out */
.playtool--crab[aria-checked="false"] {
  --stone-light: #f6efe3;
  --stone: #d9cdb8;
  --stone-dark: #a69779;
  --paint: #4a3b26;
  --paint-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
}
.playtool--crab[aria-checked="false"] .playtool__slash { display: inline; }
.playtool--crab[aria-checked="false"] .playtool__on { display: none; }
.playtool--crab[aria-checked="false"] .playtool__off { display: inline; }

/* reset: a blue-grey stone with waves painted on */
.playtool--reset {
  --tilt: -3deg;
  --stone-light: #a3c0c6;
  --stone: #5f8791;
  --stone-dark: #31515a;
  --paint: #fbf6ea;
  --paint-shadow: 0 1px 0 rgba(0, 0, 0, 0.3);
}

/* the big crab that tidies up */
.big-crab {
  position: absolute;
  left: 0;
  top: 0;
  width: var(--bw, 120px);
  height: calc(var(--bw, 120px) * 0.75);
  margin: calc(var(--bw, 120px) * -0.375) 0 0 calc(var(--bw, 120px) * -0.5);
  pointer-events: none;
  display: none;
  will-change: transform;
}
.big-crab.is-out { display: block; }
.big-crab svg { display: block; width: 100%; height: 100%; overflow: visible; }
.big-crab .leg-a { animation: leg 0.13s ease-in-out infinite alternate; }
.big-crab .leg-b { animation: leg 0.13s ease-in-out infinite alternate-reverse; }
.big-crab.is-fleeing .leg-a, .big-crab.is-fleeing .leg-b { animation-duration: 0.07s; }
.big-crab.is-scrubbing .claw-l { animation: scrub 0.11s ease-in-out infinite alternate; }
.big-crab.is-scrubbing .claw-r { animation: scrub 0.11s ease-in-out infinite alternate-reverse; }
.big-crab.is-scrubbing .body { animation: jiggle 0.09s ease-in-out infinite alternate; }

@keyframes scrub { from { transform: rotate(-14deg); } to { transform: rotate(16deg); } }
@keyframes jiggle { from { transform: translateX(-1px); } to { transform: translateX(1px); } }

.sand-puff {
  position: absolute;
  left: 0;
  top: 0;
  width: 5px;
  height: 5px;
  margin: -2.5px 0 0 -2.5px;
  border-radius: 50%;
  background: #e8cf9f;
  pointer-events: none;
  animation: puff 0.55s ease-out forwards;
}

@keyframes puff {
  from { transform: translate(var(--x), var(--y)) scale(1); opacity: 0.95; }
  to { transform: translate(calc(var(--x) + var(--dx)), calc(var(--y) + var(--dy))) scale(0.3); opacity: 0; }
}

/* ---------- Utilities and fallbacks ---------- */

[hidden] { display: none !important; }

.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}

html:not(.js) .sand { position: fixed; z-index: -1; }
html:not(.js) .sea,
html:not(.js) .ground,
html:not(.js) .wet,
html:not(.js) .decor,
html:not(.js) .dots,
html:not(.js) .hint,
html:not(.js) .playtools,
html:not(.js) .page--playground { display: none; }

@media (max-height: 640px) {
  .monogram { display: none; }
  .playground-title { top: var(--heart-top); }
  .page__inner { gap: 0.4rem; }
}

@media (prefers-reduced-motion: reduce) {
  .hint__icon,
  .turtle *,
  .crab * { animation: none !important; }
  .sandnote, .sandnote.is-closing { transform: rotate(-1deg); }
  .js .page--playground.is-active .playground-title { animation: none; }
  .js .page.is-active .page__inner { animation: fade-in 0.6s ease both; }
}

@keyframes fade-in { from { opacity: 0; } }
