/* ============================================================================
   SABRR &mdash; the opening breath
   ----------------------------------------------------------------------------
   Offered on request from the [data-breathe] controls &mdash; never sprung on
   someone at load, which is what it used to do.

   Four rounds of 4-7-8: in for four, hold for seven, out for eight. The long
   hold and the longer exhale are what separate it from simply breathing
   slowly, and it is the pattern the retreat itself teaches.

   Skippable at every moment; the exit sits in the middle of the screen where
   a thumb can reach it. Four rounds takes 76 seconds.
   ========================================================================= */

.breathe-gate {
  /* Its own palette, on purpose. These used to be the --forest-* tokens, which
     the sunrise palette maps onto a bright red - a full screen of it, for a
     minute, while somebody is trying to settle. It also gave the orb nothing
     to glow against. Deep ember instead: the same warmth, at night. */
  --gate-ground: #190806;
  --gate-rise:   #40150E;
  --gate-ember:  #8A2C18;
  --gate-glow:   #F3B87C;
  --gate-light:  #FFE9D2;

  position: fixed; inset: 0; z-index: 400;
  display: grid; grid-template-rows: auto 1fr auto;
  background:
    /* the ground lifts just behind the orb, so the light has somewhere to fall */
    radial-gradient(120% 84% at 50% 46%, var(--gate-rise) 0%, transparent 62%),
    radial-gradient(90% 62% at 50% 46%, color-mix(in oklab, var(--gate-ember) 55%, transparent) 0%, transparent 48%),
    radial-gradient(70% 50% at 86% 4%,  color-mix(in oklab, var(--gate-glow) 12%, transparent) 0%, transparent 60%),
    radial-gradient(70% 55% at 10% 98%, color-mix(in oklab, var(--gate-ember) 22%, transparent) 0%, transparent 62%),
    var(--gate-ground);
  color: var(--gate-light);
  overflow: hidden;
  transition: opacity 1s var(--ease-out), visibility 1s;
}
.breathe-gate[hidden] { display: none; }
.breathe-gate[data-state="closing"] { opacity: 0; visibility: hidden; pointer-events: none; }

/* the drifting field of motes &mdash; it breathes with you */
.gate-field {
  position: absolute; inset: 0; z-index: 0;
  width: 100%; height: 100%;
  pointer-events: none;
}

/* --- header -------------------------------------------------------------- */
.gate-head {
  position: relative; z-index: 3;
  display: flex; align-items: center; justify-content: space-between; gap: 1.5rem;
  padding: clamp(1.1rem, 3vw, 2rem) clamp(1.25rem, 4vw, 3rem);
}
.gate-mark {
  width: 104px; height: 56px; flex: none;
  background-color: var(--peach);
  opacity: .92;
}
.gate-skip {
  border: 1px solid color-mix(in oklab, var(--paper) 34%, transparent);
  background: transparent; color: var(--paper);
  border-radius: 999px; cursor: pointer;
  padding: .62em 1.35em;
  font-size: .74rem; letter-spacing: .18em; text-transform: uppercase;
  transition: background .35s var(--ease-out), border-color .35s var(--ease-out);
}
.gate-skip:hover { background: color-mix(in oklab, var(--paper) 15%, transparent); border-color: var(--paper); }

/* --- the breath ---------------------------------------------------------- */
.gate-stage {
  position: relative; z-index: 2;
  display: grid; place-items: center; align-content: center;
  gap: clamp(1.1rem, 2.6vw, 2rem);
  padding-inline: clamp(1.25rem, 4vw, 3rem);
  text-align: center;
}
.gate-tagline {
  font-family: var(--font-display); font-weight: 500; font-style: italic;
  font-size: clamp(1.35rem, 1rem + 1.9vw, 2.4rem);
  line-height: 1.2; margin: 0; max-width: 20ch;
  color: color-mix(in oklab, var(--paper) 94%, transparent);
  text-wrap: balance;
}
.gate-tagline b { font-style: normal; font-weight: 400; color: var(--gold-soft); }

.gate-orb-wrap {
  position: relative;
  width: min(46vmin, 320px); aspect-ratio: 1;
  display: grid; place-items: center;
}

/* concentric rings, each a beat behind the last, so the expansion ripples */
.gate-ring {
  position: absolute; inset: 0; border-radius: 50%;
  border: 1px solid color-mix(in oklab, var(--gate-glow) 30%, transparent);
  transform: scale(.56);
  opacity: .2;
}
.gate-ring:nth-of-type(2) { inset: 8%; }
.gate-ring:nth-of-type(3) { inset: 16%; }
.gate-ring:nth-of-type(4) { inset: 24%; }

/* the phase arc &mdash; one sweep per inhale and per exhale */
.gate-arc {
  position: absolute; inset: 0; z-index: 2;
  transform: rotate(-90deg);
  pointer-events: none;
}
.gate-arc circle { fill: none; stroke-width: 1.2; }
.gate-arc-track { stroke: color-mix(in oklab, var(--gate-light) 10%, transparent); }
.gate-arc-bar {
  stroke: var(--gate-glow); stroke-linecap: round;
  transition: stroke-dashoffset .12s linear;
  filter: drop-shadow(0 0 8px color-mix(in oklab, var(--gate-glow) 60%, transparent));
}

.gate-orb {
  position: relative; z-index: 3;
  width: 54%; aspect-ratio: 1; border-radius: 50%;
  /* A small bright core and a long falloff. The old one held near-white out to
     a third of its radius and then dropped off in the last fifth, which paints
     a disc with a fuzzy rim - light does the opposite. */
  background: radial-gradient(closest-side,
    rgb(255 252 248 / .98) 0%,
    rgb(255 244 228 / .92) 12%,
    color-mix(in oklab, var(--gate-glow) 92%, white) 26%,
    color-mix(in oklab, var(--gate-glow) 62%, transparent) 46%,
    color-mix(in oklab, var(--gate-ember) 42%, transparent) 68%,
    color-mix(in oklab, var(--gate-ember) 14%, transparent) 84%,
    transparent 100%);
  box-shadow:
    0 0 70px -10px color-mix(in oklab, var(--gate-glow) 40%, transparent),
    0 0 160px 10px color-mix(in oklab, var(--gate-ember) 26%, transparent);
  transform: scale(.6);
  transition: box-shadow 2.4s ease-in-out;
}
/* The inhale is the only time it truly blooms, so the swell is something you
   feel rather than something you have to watch for. */
.gate-orb[data-phase="in"] {
  box-shadow:
    0 0 110px -6px color-mix(in oklab, var(--gate-glow) 62%, transparent),
    0 0 260px 24px color-mix(in oklab, var(--gate-ember) 40%, transparent);
}
.gate-orb[data-phase="out"] {
  box-shadow:
    0 0 60px -14px color-mix(in oklab, var(--gate-glow) 30%, transparent),
    0 0 130px 6px color-mix(in oklab, var(--gate-ember) 18%, transparent);
}

/* The instruction used to live inside the orb, where a long line ran past the
   circle and was cut off. Below it, the words have the width of the screen and
   the orb is free to be nothing but light. */
.gate-read { display: grid; gap: .45rem; justify-items: center; }
.gate-word {
  margin: 0;
  font-size: clamp(.86rem, .78rem + .35vw, 1.05rem);
  letter-spacing: .42em; text-indent: .42em;
  text-transform: uppercase; font-weight: 600;
  color: var(--paper);
}
.gate-sub {
  margin: 0;
  font-size: clamp(.72rem, .68rem + .2vw, .82rem);
  letter-spacing: .08em;
  color: color-mix(in oklab, var(--paper) 76%, transparent);
}
.gate-count {
  margin: .5rem 0 0;
  font-size: .7rem; letter-spacing: .26em; text-transform: uppercase;
  color: color-mix(in oklab, var(--paper) 60%, transparent);
  white-space: nowrap;
}

/* --- footer -------------------------------------------------------------- */
.gate-foot {
  position: relative; z-index: 3;
  display: grid; justify-items: center; gap: .8rem;
  padding: clamp(.8rem, 2vw, 1.6rem) clamp(1.25rem, 4vw, 3rem) clamp(1.6rem, 4vw, 2.6rem);
}
.gate-dots { display: flex; gap: .6rem; }
.gate-dots i {
  width: 7px; height: 7px; border-radius: 50%;
  background: color-mix(in oklab, var(--paper) 26%, transparent);
  transition: background .6s var(--ease-out), transform .6s var(--ease-out), box-shadow .6s;
}
.gate-dots i[data-done="true"] { background: var(--gold); }
.gate-dots i[data-active="true"] {
  background: var(--peach); transform: scale(1.55);
  box-shadow: 0 0 12px color-mix(in oklab, var(--peach) 70%, transparent);
}
.gate-note {
  font-size: .76rem; line-height: 1.6;
  color: color-mix(in oklab, var(--paper) 60%, transparent);
  max-width: 44ch; text-align: center; margin: 0;
}

/* --- the closing beat ---------------------------------------------------- */
.gate-done {
  position: absolute; inset: 0; z-index: 4;
  display: grid; place-items: center; align-content: center; gap: 1.1rem;
  text-align: center; padding-inline: 2rem;
  background: inherit;
  opacity: 0; visibility: hidden;
  transition: opacity .8s var(--ease-out), visibility .8s;
}
.gate-done[data-show="true"] { opacity: 1; visibility: visible; }
.gate-done p {
  font-family: var(--font-display); font-style: italic; font-weight: 500;
  font-size: clamp(1.5rem, 1.1rem + 2vw, 2.6rem); line-height: 1.2;
  margin: 0; max-width: 18ch; color: var(--paper);
}

/* --- reduced motion: offer it, do not perform it ------------------------- */
@media (prefers-reduced-motion: reduce) {
  .gate-field { display: none; }
  .gate-orb { transition: none; transform: scale(.8) !important; }
  .gate-ring { transform: scale(.8) !important; }
  .gate-arc-bar { transition: none; }
}

/* --- a way back to it from the site -------------------------------------- */
/* This was a bare row of text under two proper buttons, and read as a caption
   somebody had forgotten to finish. It is the only control on the page that
   does something rather than going somewhere, which is worth an invitation.
   A pill on its own ground, quieter than "Book your place" above it. */
/* Under the photograph rather than under the headline. The quote floats over
   the foot of the picture, so this lands below both and reads as the last,
   gentlest thing in the hero. Centred on the picture's own width, and allowed
   to wrap on a narrow column rather than push the layout sideways. */
/* The quote is absolutely positioned against the foot of the picture. Without
   a frame of its own it anchored to the whole column instead, so adding the
   button below simply moved the quote down on top of it. */
.hero-frame { position: relative; }

.hero-breathe {
  margin-top: 1.15rem;
  display: flex; justify-content: center;
}
.hero-breathe .breathe-again { max-width: 100%; }

.breathe-again {
  display: inline-flex; align-items: center; gap: .7rem;
  padding: .85rem 1.5rem;
  cursor: pointer;
  border-radius: 999px;
  /* Filled, not washed. It used to be translucent paper on a pale hero with a
     hairline border, which put an invitation on the page in the quietest voice
     available. This is the same weight as every other primary control here. */
  background: linear-gradient(140deg,
    color-mix(in oklab, var(--accent) 92%, #FFFFFF) 0%,
    var(--accent) 46%,
    color-mix(in oklab, var(--accent) 86%, #2A0A08) 100%);
  border: 1px solid color-mix(in oklab, var(--accent) 86%, #2A0A08);
  color: #FFF6EF;
  box-shadow:
    0 1px 0 color-mix(in oklab, #FFFFFF 22%, transparent) inset,
    0 18px 38px -20px rgb(90 25 15 / .62);
  font-size: var(--step--1); font-weight: 500;
  letter-spacing: .03em; text-transform: uppercase;
  text-align: left; white-space: nowrap;
  transition: transform .45s var(--ease-out), box-shadow .45s var(--ease-out),
              filter .45s var(--ease-out);
}
/* One line, always. The hero column is 409px on a laptop and the label wanted
   more than that at the old tracking, so the button arrived as two lines with
   the minutes stranded beside the second one. Tighter tracking fits it at
   every width the column takes, and the type steps down rather than wrapping
   once the screen gets narrow enough to matter. */
.breathe-again > span { white-space: nowrap; }
.breathe-again:focus-visible { outline: 2px solid var(--accent); outline-offset: 3px; }

/* The duration is set apart, because "how long is this going to take" is the
   only thing standing between somebody and pressing it. */
.breathe-mins {
  padding-left: .7rem;
  border-left: 1px solid color-mix(in oklab, currentColor 30%, transparent);
  opacity: .78; letter-spacing: .04em; white-space: nowrap;
}

/* A ring that breathes, rather than a dot that blinks. It runs the same shape
   the button is offering - four seconds opening, eight closing - so the
   control demonstrates itself while it sits there. */
.breathe-again .pulse {
  position: relative; flex: none;
  width: 13px; height: 13px; border-radius: 50%;
  background: color-mix(in oklab, currentColor 92%, transparent);
  animation: breathe-core 12s cubic-bezier(.37,0,.63,1) infinite;
}
.breathe-again .pulse::after {
  content: ""; position: absolute; inset: -6px;
  border-radius: 50%; border: 1px solid currentColor;
  animation: breathe-ring 12s cubic-bezier(.37,0,.63,1) infinite;
}
/* 4 in, 7 held, 8 out over twelve seconds: 0-33% opening, 33-58% held,
   58-100% letting go. */
@keyframes breathe-core {
  0%   { transform: scale(.52); opacity: .5; }
  33%  { transform: scale(1);   opacity: 1; }
  58%  { transform: scale(1);   opacity: 1; }
  100% { transform: scale(.52); opacity: .5; }
}
@keyframes breathe-ring {
  0%   { transform: scale(.5);  opacity: 0; }
  33%  { transform: scale(1);   opacity: .55; }
  58%  { transform: scale(1.05); opacity: .45; }
  100% { transform: scale(.5);  opacity: 0; }
}

.breathe-again:hover {
  transform: translateY(-2px);
  filter: brightness(1.06);
  box-shadow:
    0 1px 0 color-mix(in oklab, #FFFFFF 26%, transparent) inset,
    0 26px 46px -20px rgb(90 25 15 / .7);
}
.breathe-again:active { transform: translateY(0); }
@media (prefers-reduced-motion: reduce) {
  .breathe-again .pulse, .breathe-again .pulse::after { animation: none; }
  .breathe-again .pulse::after { opacity: .5; transform: scale(1); }
}

/* On a phone the label was breaking across two lines with the minutes left
   hanging off the end of the second one. */
@media (max-width: 34rem) {
  .breathe-again {
    width: 100%; justify-content: center;
    padding: .82rem 1rem; gap: .5rem;
    font-size: clamp(.66rem, .5rem + 1.1vw, .82rem);
    letter-spacing: .02em;
  }
  .breathe-again .pulse { width: 11px; height: 11px; }
  .breathe-again .pulse::after { inset: -5px; }
  .breathe-mins { padding-left: .5rem; }
}


/* --- 4-7-8: three phases, and the reading inside the circle ---------------
   The words used to sit under the orb, so the eye left the thing it was
   following. They are centred in it now, with the seconds beneath them — a
   seven-second hold with no number on it reads as a page that has stalled. */
.gate-orb-wrap .gate-read {
  position: absolute; inset: 0;
  display: grid; place-content: center; justify-items: center;
  gap: .15rem;
  text-align: center;
  pointer-events: none;
  z-index: 3;
}
.gate-orb-wrap .gate-word { margin: 0; }
.gate-timer {
  margin: 0;
  font-family: var(--font-display);
  font-size: clamp(2.4rem, 8vw, 3.8rem);
  line-height: 1;
  font-variant-numeric: tabular-nums;
  /* it sits on the brightest part of the orb, so it carries its own weight
     and a shadow rather than washing out where the eye is looking */
  color: #FFF6E8;
  text-shadow: 0 2px 18px rgb(40 6 2 / .55);
}
.gate-orb-wrap .gate-word,
.gate-orb-wrap .gate-sub { text-shadow: 0 1px 12px rgb(40 6 2 / .45); }
.gate-orb-wrap .gate-sub { margin: 0; }

/* The hold sits still — neither drawing in nor letting go. */
.gate-orb[data-phase="hold"] { transform: scale(1); }

/* The way out is under the circle and centred, not in a corner: on a phone
   people were not finding it. */
.gate-foot { display: grid; justify-items: center; gap: 1rem; text-align: center; }
.gate-foot .gate-skip { margin-top: .2rem; }
