/* LUMA - celebrations, settings, onboarding (Layer 6)
   Sheet 9 of 9. Source order decides the cascade - see the link tags in luma.html. */

/* ============================================================
   LAYER 6 — CELEBRATIONS · SETTINGS · ONBOARDING
   ============================================================ */

/* ---------- The daily prompt (2026-09-13) ----------
   A bottom sheet, modelled on #sheet: the page stays visible behind a dimmed
   backdrop, and the card rises on the same spring. A reminder that blanks the
   whole screen reads as an emergency; this one reads as a note.

   184/185 sits below #finish-overlay (190) on purpose — a nudge must never
   cover a celebration — and above #celebration (180) and #sheet (151). */
#prompt-backdrop {
  position: fixed;
  inset: 0;
  z-index: 184;
  background: rgba(6, 6, 8, 0.6);
  backdrop-filter: blur(3px);
  -webkit-backdrop-filter: blur(3px);
  opacity: 0;
  transition: opacity var(--dur-mid) var(--ease-out);
}
#prompt-backdrop.open { opacity: 1; }
#prompt-backdrop.gone { display: none; }

#prompt-sheet {
  position: fixed;
  left: 50%;
  /* --kb, like #sheet: iOS anchors fixed elements to the layout viewport, which
     does not shrink for the keyboard. No field here today, but the prompt can
     route into one and the sheet must not be the odd one out. */
  bottom: var(--kb, 0px);
  width: 100%;
  max-width: 480px;
  z-index: 185;
  transform: translateX(-50%) translateY(100%);
  background: var(--surface-2);
  border: 1px solid var(--border-2);
  border-bottom: none;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  padding: 6px var(--pad) calc(var(--pad) + env(safe-area-inset-bottom));
  text-align: center;
  transition: transform var(--dur-slow) var(--ease-spring);
}
#prompt-sheet.open { transform: translateX(-50%) translateY(0); }
#prompt-sheet.gone { display: none; }

.mp-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 2px;
}
.mp-title {
  font-family: var(--font-ka);
  font-size: 15px;
  font-weight: 700;
  color: var(--text-1);
  text-align: left;
}
.mp-x {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  border: none;
  background: none;
  color: var(--text-3);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  padding: 0;
}
.mp-msg {
  font-family: var(--font-ka);
  font-size: 17px;
  font-weight: 600;
  color: var(--text-1);
  line-height: 1.4;
  margin-bottom: 6px;
}
.mp-stat {
  font-family: var(--font-ka);
  font-size: 13px;
  color: var(--text-2);
  margin-bottom: 16px;
}
.mp-stat:empty { display: none; margin-bottom: 10px; }

/* mascot-data-play is 1070x456 — 2.35:1, and the ONLY wide clip in the file.
   This box is fixed px and carries the clip's own ratio, so the cat paints at
   identical size on every screen.

   It is NOT .fin-mascot (180x200, sized for the 288x320 cheer clip): a 2.35:1
   clip in that box paints 180x77 with 61px of dead space above and below.
   And it must never become a percentage — this exact clip was the day-tab hero
   at width:100% and measured 170px on a desktop but 143px on a 375px phone,
   because preserveAspectRatio:meet shrinks BOTH axes.
   300px fits the 335px content column at 375px. Measure it, do not assume. */
.mp-mascot {
  width: 260px;     /* 260 / 111 = 2.342 against the clip's 2.3465 */
  height: 111px;
  margin: 2px auto 8px;
}

/* ---------- Tiered celebration overlay ----------
   `small` never reaches here (it is a toast) and `medium` still uses the
   Layer 2 #celebration card, so the mascot keeps its home. This is the
   large/boss presentation only. */
.celebration-overlay {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(10, 10, 12, 0.92);
  backdrop-filter: blur(16px);
  -webkit-backdrop-filter: blur(16px);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  animation: fadeIn var(--dur-mid) var(--ease-out) both;
}

.celebration-card {
  text-align: center;
  position: relative;
  max-width: 340px;
  animation: popIn var(--dur-slow) var(--ease-spring) both;
}

.celebration-card.boss {
  background: var(--surface);
  border: 1px solid var(--lime);
  border-radius: var(--radius-lg);
  padding: 40px 28px;
  box-shadow: 0 0 40px var(--lime-glow);
}

.cel-emoji {
  font-size: 60px;
  line-height: 1;
  margin-bottom: 18px;
  animation: celBounce var(--dur-slow) var(--ease-spring) both;
}

@keyframes celBounce {
  0%   { transform: scale(0) rotate(-20deg); opacity: 0; }
  70%  { transform: scale(1.15) rotate(5deg); opacity: 1; }
  100% { transform: scale(1) rotate(0); opacity: 1; }
}

.cel-big-title {
  font-family: var(--font-ka);
  font-size: 26px;
  font-weight: 800;
  color: var(--text-1);
  line-height: 1.25;
  margin-bottom: 10px;
}

.cel-big-sub {
  font-family: var(--font-ka);
  font-size: 15px;
  color: var(--text-2);
  line-height: 1.55;
  max-width: 280px;
  margin: 0 auto;
}

.cel-big-btn { margin-top: 26px; padding: 14px 40px; }

.cel-particles {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  border-radius: var(--radius-lg);
}

/* Each particle carries its own left / size / delay / duration inline, which
   is what randomises the burst — there is no --r term to set. */
.cel-particle {
  position: absolute;
  top: 50%;
  border-radius: 2px;
  animation-name: particleBurst;
  animation-timing-function: linear;
  animation-fill-mode: both;
}

@keyframes particleBurst {
  0%   { transform: translateY(0) rotate(0deg); opacity: 1; }
  100% { transform: translateY(-200px) rotate(720deg); opacity: 0; }
}

/* The "don't panic" weight message needs to outlive a normal toast: .toast
   bakes a 2.7s delay into its animation shorthand, so a longer life is a
   class, not a JS timeout. */
.toast-hold {
  animation: toastIn 0.3s var(--ease-spring) both,
             toastOut 0.3s var(--ease-out) 5.2s both;
  cursor: pointer;
  pointer-events: all;
}

/* ---------- Settings tab ---------- */
.settings-header {
  padding-top: calc(env(safe-area-inset-top) + 8px);
  margin-bottom: 16px;
}

.settings-section-label {
  font-family: var(--font-ka);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-3);
  text-transform: uppercase;
  letter-spacing: 0.08em;
  margin: 18px 0 6px;
}

.settings-card { padding: 0 16px; }

.settings-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 13px 0;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  transition: opacity var(--dur-fast) var(--ease-out);
  min-height: 50px;
}

.settings-row:last-child { border-bottom: none; }
.settings-row:active { opacity: 0.65; }
.settings-row.is-static { cursor: default; }
.settings-row.is-static:active { opacity: 1; }

.settings-row-label {
  font-family: var(--font-ka);
  font-size: 15px;
  color: var(--text-1);
}

.settings-row-sub {
  font-family: var(--font-ka);
  font-size: 11px;
  color: var(--text-3);
  margin-top: 2px;
  line-height: 1.4;
}

.settings-row-value {
  font-family: var(--font-num);
  font-size: 15px;
  font-weight: 600;
  color: var(--text-2);
  display: flex;
  align-items: baseline;
  gap: 0.3em;
  flex: 0 0 auto;
}

/* .settings-row-value is a flex container, so the whitespace between a number
   and its unit is dropped — the same trap .tag hit in Layer 3. */
.settings-row-unit { font-size: 12px; color: var(--text-3); }
.settings-row-chev  { color: var(--text-3); font-size: 18px; line-height: 1; }
.settings-row-value.is-lime  { color: var(--lime); }
.settings-row-value.is-amber { color: var(--amber); }
.settings-row-label.is-amber { color: var(--amber); }
.settings-row-label.is-lime  { color: var(--lime); }

.settings-note {
  font-family: var(--font-ka);
  font-size: 11px;
  color: var(--text-3);
  line-height: 1.5;
  padding: 10px 0 12px;
}

/* The "no account? create one" line under the two sign-in fields. It reuses
   .settings-note for the muted type and only needs to read as tappable — and
   it needs a real touch target, so the padding is height, not decoration. */
.auth-switch {
  color: var(--lime);
  text-align: center;
  padding: 14px 0 4px;
  cursor: pointer;
}

/* The eye FLOATS OVER the password box, it is not a second item in the flex row.
   As a flex item it shortened the input, so the password box was visibly
   narrower than the email box above it — Giorgi's "they should be the same
   size". Absolute keeps both `.manual-input`s at an identical width:100%, and
   the input just reserves room for it in padding. */
/* Safari's UA stylesheet gives a form a top margin; zero it or the wrapper
   that exists purely for the password manager pushes the fields down. */
#auth-form { margin: 0; }

.auth-pw-row { position: relative; }
.auth-pw-row .manual-input { padding-right: 42px; }

.auth-eye {
  position: absolute;
  right: 20px;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  padding: 0;
  color: var(--text-3);
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
}

.auth-eye svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.auth-eye.is-on { color: var(--lime); }
.auth-eye .eye-slash { display: none; }
.auth-eye.is-on .eye-slash { display: block; }

.settings-foot {
  text-align: center;
  padding: 26px 0 12px;
  font-family: var(--font-num);
  font-size: 12px;
  color: var(--text-3);
}

.settings-toggle {
  width: 44px;
  height: 26px;
  background: var(--surface-3);
  border-radius: var(--radius-pill);
  position: relative;
  cursor: pointer;
  transition: background var(--dur-mid) var(--ease-out);
  flex: 0 0 auto;
}

.settings-toggle.on { background: var(--lime); }

.settings-toggle-knob {
  position: absolute;
  top: 3px;
  left: 3px;
  width: 20px;
  height: 20px;
  background: #FFFFFF;
  border-radius: 50%;
  transition: transform var(--dur-mid) var(--ease-spring);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}

.settings-toggle.on .settings-toggle-knob { transform: translateX(18px); }

/* ---------- InBody day banner (day tab) ---------- */
#inbody-day-banner {
  background: var(--amber-dim);
  border-color: var(--amber);
  margin-bottom: 14px;
  padding: 14px 16px;
}

.inbody-day-title {
  font-family: var(--font-ka);
  font-size: 14px;
  font-weight: 700;
  color: var(--amber);
  margin-bottom: 6px;
}

.inbody-day-desc {
  font-family: var(--font-ka);
  font-size: 13px;
  color: var(--text-2);
  line-height: 1.5;
}

.inbody-day-btn {
  margin-top: 12px;
  border-color: var(--amber);
  color: var(--amber);
}

/* ---------- Install (PWA) ---------- */
#install-banner {
  background: var(--lime-dim);
  border-color: var(--lime);
  margin-bottom: 14px;
  padding: 14px 16px;
}

.install-title {
  font-family: var(--font-ka);
  font-size: 14px;
  font-weight: 700;
  color: var(--lime);
  margin-bottom: 6px;
}

.install-desc {
  font-family: var(--font-ka);
  font-size: 13px;
  color: var(--text-2);
  line-height: 1.5;
}

.install-btns {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}

.install-btn-yes {
  border-color: var(--lime);
  color: var(--lime);
}

/* The sheet's numbered steps. The share glyph sits inline in step 1 because
   naming the button is not enough — on iOS it carries no label. */
.install-step {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin-bottom: 12px;
}

.install-step-n {
  flex: none;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: var(--lime-dim);
  color: var(--lime);
  font-family: var(--font-num);
  font-size: 12px;
  font-weight: 700;
  display: grid;
  place-items: center;
  margin-top: 1px;
}

.install-step-txt {
  font-family: var(--font-ka);
  font-size: 14px;
  color: var(--text-1);
  line-height: 1.45;
}

.install-share {
  width: 15px;
  height: 15px;
  stroke: var(--lime);
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  vertical-align: -2px;
  margin: 0 2px;
}

.install-note {
  font-family: var(--font-ka);
  font-size: 12px;
  color: var(--text-3);
  line-height: 1.5;
  margin-top: 14px;
  padding-top: 12px;
  border-top: 1px solid var(--border);
}

/* ---------- Onboarding ---------- */
#onboarding-overlay {
  position: fixed;
  inset: 0;
  z-index: 95;
  background: var(--bg);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 24px;
  animation: fadeIn var(--dur-slow) var(--ease-out) both;
}

.ob-inner { text-align: center; max-width: 320px; width: 100%; }

.ob-emoji {
  font-size: 60px;
  line-height: 1;
  margin-bottom: 24px;
  animation: celBounce var(--dur-slow) var(--ease-spring) both;
}

.ob-title {
  font-family: var(--font-ka);
  font-size: 25px;
  font-weight: 800;
  color: var(--text-1);
  line-height: 1.25;
  margin-bottom: 14px;
}

.ob-sub {
  font-family: var(--font-ka);
  font-size: 15px;
  color: var(--text-2);
  line-height: 1.65;
  margin-bottom: 36px;
}

.ob-dots {
  display: flex;
  gap: 6px;
  justify-content: center;
  margin-bottom: 30px;
}

.ob-dot {
  width: 6px;
  height: 6px;
  border-radius: var(--radius-pill);
  background: var(--surface-3);
  transition: width var(--dur-mid) var(--ease-out),
              background var(--dur-mid) var(--ease-out);
}

.ob-dot.on { width: 20px; background: var(--lime); }

.ob-back { margin-top: 10px; }

/* ============================================================
   THE PROFILE PAGE (2026-09-22)
   Opened by the round picture in the day header. Everything that used to be the
   S.navSettings tab lives in here now, plus her identity at the top.

   z-index 150: above the tabs and the bottom nav, below the sheets (150/151 is
   the sheet pair, and openSheet() can be raised FROM this page — the account
   card and every settings editor open on top of it). Below #finish-overlay (190)
   and the prompt (184/185), neither of which should ever be buried by it.
   ============================================================ */
.profile-page {
  position: fixed;
  inset: 0;
  z-index: 150;
  background: var(--bg);
  opacity: 0;
  /* 2026-09-24 — slides in from the right like every other full page. The
     transition that runs is the one on the state being ENTERED: this one on the
     way out (closeProfilePage() hides it after 300ms = --dur-page-out), the
     .open one on the way in. */
  transform: translateX(100%);
  transition: transform var(--dur-page-out) var(--ease-in-out),
              opacity var(--dur-page-out) var(--ease-in-out);
}
.profile-page.open {
  opacity: 1;
  transform: translateX(0);
  transition: transform var(--dur-page) var(--ease-out),
              opacity var(--dur-mid) var(--ease-out);
}
.profile-page.gone { display: none; }
/* BUG FIX (2026-09-24): the log-out button "did nothing". confirmSheet() and every
   openBottomSheet() build a .modal-bg at z-index 80, so opened FROM this page (150)
   the confirm sat underneath it, invisible — the tap worked and nobody could see
   the question it asked. The same trap hid the reset confirm and the coach page.
   While the page is open, any .modal-bg goes above it (still under the toasts, 200). */
html:has(#profile-page.open) .modal-bg { z-index: 160; }

.profile-sheet {
  position: absolute;
  inset: 0;
  max-width: 480px;
  margin: 0 auto;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  padding: calc(env(safe-area-inset-top) + 10px) var(--pad)
           calc(env(safe-area-inset-bottom) + 40px);
}

.profile-bar { display: flex; justify-content: flex-end; }

.profile-id {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 6px 0 22px;
}

/* 88px, and the picture is the button. A separate "change picture" row would be
   a string we do not have; tapping the picture is what every app does. */
.profile-avatar {
  position: relative;
  width: 88px;
  height: 88px;
  border-radius: 50%;
  border: 1px solid var(--border-2);
  background: linear-gradient(180deg, #2A2420 0%, var(--hdr-cat) 78%);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.07);
  display: grid;
  place-items: center;
  /* NOT overflow:hidden — .profile-avatar-edit sits on the rim and was being
     shaved in half by it. Only the photo needs clipping and it clips itself. */
  cursor: pointer;
  padding: 0;
  transition: transform var(--dur-fast) var(--ease-spring);
}
.profile-avatar:active { transform: scale(0.95); }

.profile-avatar-letter {
  font-size: 34px;
  font-weight: 700;
  color: var(--lime);
  line-height: 1;
}
/* The <img> has no src until hydrateAvatar() finds one, and an img with no src
   still occupies its box and draws a broken-image glyph in some engines. It is
   display:none until the class says otherwise. */
.profile-avatar-img,
.hdr-avatar-img { display: none; }
.profile-avatar-img.has-photo,
.hdr-avatar-img.has-photo {
  display: block;
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;          /* it clips itself; its parent must not */
}
/* With a photo on, the letter underneath must not show through its corners. */
.profile-avatar.has-photo .profile-avatar-letter,
.hdr-auth.has-photo .hdr-auth-text,
.hdr-auth.has-photo .hdr-auth-mark { visibility: hidden; }

.profile-avatar-edit {
  position: absolute;
  right: -1px;
  bottom: -1px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  background: var(--lime);
  border: 2px solid var(--bg);
  display: grid;
  place-items: center;
}
.profile-avatar-edit svg {
  width: 14px;
  height: 14px;
  fill: none;
  stroke: #0A0A0C;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}

.profile-name {
  font-family: var(--font-ka);
  font-size: 21px;
  font-weight: 700;
  color: var(--text-1);
  margin-top: 12px;
}
/* Tapping it opens the account card — email, backup state, sign out. */
.profile-sub {
  font-family: var(--font-ka);
  font-size: 13px;
  color: var(--text-3);
  cursor: pointer;
}

/* ---- Health ---- */
/* A small signed delta beside a figure. It is not coloured good/bad: whether a
   number going up is good depends on which number it is, and the app does not
   say anywhere else on this screen. */
.profile-delta {
  font-family: var(--font-num);
  font-size: 11px;
  font-weight: 600;
  color: var(--text-3);
  margin-left: 6px;
}


/* ============================================================
   THE STREAK PAGE (2026-09-23)
   Giorgi's reference: warm black, a big living flame with embers, the number, the
   week joined by a glowing track, the next milestone, an orange Continue.

   Phone-shaped like every full-screen motion here: the page is the 480px column,
   and outside it on a desktop is plain dark.

   Warm on purpose — this is the one screen where the fire colours lead. The lime
   still means "earned" everywhere else, and the tick on a perfect day is gold, not
   lime, so the two languages do not cross.
   ============================================================ */
.streak-page {
  position: fixed;
  inset: 0;
  z-index: 90;
  background: rgba(5, 4, 3, 0.94);
  opacity: 0;
  transition: opacity var(--dur-mid) var(--ease-out);
}
.streak-page.is-open { opacity: 1; }
.streak-page.is-closing { opacity: 0; transition-duration: var(--dur-drop); }

.sp-shell {
  position: relative;
  max-width: 480px;
  height: 100%;
  margin: 0 auto;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: calc(env(safe-area-inset-top) + 14px) var(--pad) calc(env(safe-area-inset-bottom) + 22px);
  display: flex;
  flex-direction: column;
  background:
    radial-gradient(120% 60% at 50% 0%, rgba(242, 84, 27, 0.22), rgba(242, 84, 27, 0) 60%),
    #0B0806;
  /* 2026-09-23 — rises the full height from the bottom edge, as a sheet with
     rounded top corners that square off once it has landed. It used to arrive
     from 24px below, which read as a fade rather than as a page arriving. */
  transform: translateY(100%);
  border-radius: 28px 28px 0 0;
  transition: transform var(--dur-rise) var(--ease-out),
              border-radius var(--dur-mid) var(--ease-out);
}
.streak-page.is-open .sp-shell { transform: none; }
.streak-page.is-landed .sp-shell { border-radius: 0; }
.streak-page.is-closing .sp-shell {
  transition: transform var(--dur-drop) var(--ease-in-out);
  border-radius: 28px 28px 0 0;
}
/* Nothing on the page plays until it has landed. `both` fill holds each piece at
   its from-state meanwhile, so the flame, the number sliding in and the cards
   rising all happen in view instead of during the rise. */
.streak-page:not(.is-landed) .sp-shell * { animation-play-state: paused; }

/* A slow breathing bloom behind the flame. */
.sp-glow {
  position: absolute;
  left: 50%; top: 40px;
  width: 340px; height: 340px;
  margin-left: -170px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 150, 60, 0.28), rgba(255, 150, 60, 0) 65%);
  pointer-events: none;
  animation: spBreathe 3.6s var(--ease-in-out) infinite alternate;
}
@keyframes spBreathe {
  from { transform: scale(0.9);  opacity: 0.7; }
  to   { transform: scale(1.08); opacity: 1; }
}

/* 2026-09-24, Giorgi: the back button "does not look good". It was a lone chevron
   in a see-through circle, washed into the orange glow. It is now the app's own
   back button — the ← arrow every other full page uses — on a dark frosted disc so
   it holds its edge against the glow. */
.sp-back {
  position: relative;
  z-index: 1;
  align-self: flex-start;
  width: 42px; height: 42px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: rgba(14, 12, 12, 0.55);
  border: 1px solid rgba(255, 255, 255, 0.14);
  box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.06);
  -webkit-backdrop-filter: blur(12px);
          backdrop-filter: blur(12px);
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-spring);
}
.sp-back:active { transform: scale(0.9); }
.sp-back svg { width: 20px; height: 20px; fill: none; stroke: var(--text-1); stroke-width: 2;
  stroke-linecap: round; stroke-linejoin: round; }

.sp-hero {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  margin-top: 4px;
}

.sp-flame {
  position: relative;
  width: 150px; height: 150px;
  display: grid;
  place-items: center;
  animation: spPop 700ms var(--ease-spring) 80ms both;
}
@keyframes spPop {
  from { transform: scale(0.4); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}
/* The dotted ring of sparks round the flame in the reference, turning slowly. */
.sp-ring {
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background:
    radial-gradient(circle, rgba(255, 170, 70, 0.7) 1.2px, transparent 1.8px) 0 0 / 14px 14px;
  -webkit-mask: radial-gradient(circle, transparent 60%, #000 62%, #000 70%, transparent 72%);
          mask: radial-gradient(circle, transparent 60%, #000 62%, #000 70%, transparent 72%);
  opacity: 0.55;
  animation: spSpin 24s linear infinite;
}
@keyframes spSpin { to { transform: rotate(360deg); } }

.sp-flame-svg {
  position: relative;
  width: 104px; height: 104px;
  overflow: visible;
  filter: drop-shadow(0 0 22px rgba(255, 120, 40, 0.65)) drop-shadow(0 0 6px rgba(255, 200, 90, 0.5));
}
/* Two layers flickering at different rates, both anchored at the base, so the
   flame moves like fire rather than bouncing like a sticker. */
.sp-flame-outer {
  transform-origin: 12px 23px;
  animation: spFlicker 1.9s var(--ease-in-out) infinite;
}
.sp-flame-core {
  transform-origin: 12px 21px;
  animation: spFlickerCore 1.15s var(--ease-in-out) infinite;
}
@keyframes spFlicker {
  0%, 100% { transform: scale(1, 1) skewX(0deg); }
  25%      { transform: scale(0.97, 1.04) skewX(-2deg); }
  50%      { transform: scale(1.02, 0.97) skewX(1.5deg); }
  75%      { transform: scale(0.98, 1.03) skewX(-1deg); }
}
@keyframes spFlickerCore {
  0%, 100% { transform: scale(1, 1); opacity: 0.95; }
  40%      { transform: scale(0.9, 1.12); opacity: 1; }
  70%      { transform: scale(1.06, 0.92); opacity: 0.85; }
}

.sp-embers { position: absolute; left: 50%; bottom: 36px; width: 0; height: 0; }
.sp-embers i {
  position: absolute;
  left: 0; top: 0;
  width: var(--s); height: var(--s);
  border-radius: 50%;
  background: #FFC266;
  box-shadow: 0 0 6px 1px rgba(255, 150, 60, 0.9);
  opacity: 0;
  animation: spEmber var(--t) var(--ease-out) var(--dl) infinite;
}
@keyframes spEmber {
  0%   { transform: translate(0, 0) scale(1); opacity: 0; }
  12%  { opacity: 1; }
  100% { transform: translate(var(--x), -120px) scale(0.3); opacity: 0; }
}

/* 2026-09-23 — poster size, the one change that carries most of the "premium"
   look in the CargoX reference: 68px -> 124px, lines packed tight, tracking pulled
   in. Still Inter (rule 3). Tucked up under the flame so the page gets no taller
   than the gain in type. "100" measures ~225px, inside a 335px column at 375. */
.sp-num {
  margin-top: -10px;
  font-family: var(--font-num);
  font-size: 124px;
  font-weight: 800;
  line-height: 0.86;
  letter-spacing: -0.055em;
  /* the negative tracking also trails the last digit; this re-centres it */
  padding-right: 0.055em;
  animation: slideInL var(--dur-slide) var(--ease-out) 120ms both;
  color: #fff;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 30px rgba(255, 140, 50, 0.35);
}
.sp-label {
  margin-top: 6px;
  font-family: var(--font-ka);
  font-size: 16px;
  font-weight: 700;
  color: var(--text-1);
}
.sp-sub {
  margin: 8px auto 0;
  max-width: 290px;
  font-family: var(--font-ka);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-2);
}
.sp-label, .sp-sub, .sp-card, .sp-continue { animation: spRise 600ms var(--ease-out) both; }
/* the label answers the number from the other edge, one stagger behind it */
.sp-label { animation: slideInR var(--dur-slide) var(--ease-out)
            calc(120ms + var(--slide-stagger)) both; }
.sp-sub   { animation-delay: 220ms; }
.sp-card-week  { animation-delay: 280ms; }
.sp-card-tiers { animation-delay: 360ms; }
.sp-continue   { animation-delay: 440ms; }
@keyframes spRise {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: translateY(0); }
}

.sp-card {
  position: relative;
  z-index: 1;
  margin-top: 18px;
  padding: 16px 14px;
  border-radius: 20px;
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid rgba(255, 255, 255, 0.08);
}

/* ---- the week ---- */
.sp-dows, .sp-days { display: grid; grid-template-columns: repeat(7, 1fr); }
.sp-dow {
  text-align: center;
  font-family: var(--font-ka);
  font-size: 11.5px;
  color: var(--text-3);
}
.sp-dow.is-today { color: #FF9B4A; font-weight: 700; }
.sp-days { position: relative; margin-top: 10px; height: 44px; align-items: center; }

/* The chain. It GROWS across its run from the left, one run after another, so
   opening the page reads as the streak travelling through the week. */
.sp-track {
  position: absolute;
  top: 50%;
  height: 36px;
  margin-top: -18px;
  border-radius: 18px;
  background: linear-gradient(90deg, rgba(242, 84, 27, 0.55), rgba(255, 170, 70, 0.55));
  box-shadow: 0 0 16px -2px rgba(255, 120, 40, 0.6);
  transform-origin: left center;
  transform: scaleX(0);
  animation: spTrack calc(var(--len) * 140ms + 160ms) var(--ease-out) var(--d) forwards;
}
@keyframes spTrack { to { transform: scaleX(1); } }

.sp-day {
  position: relative;
  z-index: 1;
  justify-self: center;
  width: 30px; height: 30px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-num);
  font-size: 13px;
  color: var(--text-2);
}
.sp-day.is-future { color: var(--text-3); }
.sp-day.is-on {
  background: linear-gradient(160deg, #FFB255, #F2541B);
  box-shadow: 0 2px 8px rgba(242, 84, 27, 0.5);
  animation: spDayPop 420ms var(--ease-spring) var(--d) both;
}
.sp-day svg { width: 16px; height: 16px; fill: none; stroke: #fff; stroke-width: 3;
  stroke-linecap: round; stroke-linejoin: round; }
/* A perfect day is GOLD with a white core ring — the extra mark on top of the
   forgiving rule. */
.sp-day.is-perfect {
  background: linear-gradient(160deg, #FFE08A, #F5B120);
  box-shadow: 0 0 0 2px rgba(255, 224, 138, 0.35), 0 0 14px rgba(255, 200, 80, 0.8);
}
.sp-day.is-perfect svg { stroke: #3A2600; }
@keyframes spDayPop {
  from { transform: scale(0.3); opacity: 0; }
  to   { transform: scale(1);   opacity: 1; }
}
/* Today, not yet logged: a pulsing ring — the day is still open. */
.sp-day.is-today:not(.is-on) {
  color: #fff;
  box-shadow: inset 0 0 0 2px #FF9B4A;
  animation: spToday 1.6s var(--ease-in-out) infinite;
}
@keyframes spToday {
  0%, 100% { box-shadow: inset 0 0 0 2px #FF9B4A, 0 0 0 0 rgba(255, 155, 74, 0.45); }
  50%      { box-shadow: inset 0 0 0 2px #FF9B4A, 0 0 0 7px rgba(255, 155, 74, 0); }
}
.sp-day.is-today.is-on { box-shadow: 0 0 0 3px rgba(255, 255, 255, 0.9), 0 0 16px rgba(255, 150, 60, 0.8); }

.sp-legend {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 7px;
  margin-top: 12px;
  font-family: var(--font-ka);
  font-size: 11.5px;
  color: var(--text-3);
}
.sp-legend-dot {
  width: 9px; height: 9px;
  border-radius: 50%;
  background: linear-gradient(160deg, #FFE08A, #F5B120);
  box-shadow: 0 0 8px rgba(255, 200, 80, 0.8);
}

/* ---- the milestones ---- */
.sp-tiers-title {
  text-align: center;
  font-family: var(--font-ka);
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.04em;
  color: var(--text-2);
}
.sp-tier-row {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 8px;
  margin-top: 12px;
}
.sp-tier {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 2px;
  padding: 10px 4px;
  border-radius: 14px;
  background: rgba(255, 255, 255, 0.03);
  border: 1px solid rgba(255, 255, 255, 0.06);
}
.sp-tier-n { font-family: var(--font-num); font-size: 20px; font-weight: 800; color: var(--text-1); }
.sp-tier-l { font-family: var(--font-ka); font-size: 11px; color: var(--text-3); }
.sp-tier.is-passed .sp-tier-n { color: var(--text-3); text-decoration: line-through; text-decoration-thickness: 2px; }
.sp-tier.is-next {
  border: 1.5px dashed #FF9B4A;
  background: rgba(255, 155, 74, 0.10);
  box-shadow: 0 0 20px -6px rgba(255, 140, 50, 0.7);
  animation: spNext 2.4s var(--ease-in-out) infinite;
}
.sp-tier.is-next .sp-tier-n { color: #FFB255; }
@keyframes spNext {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(-3px); }
}
.sp-tier-ok {
  position: absolute;
  top: -6px; right: -6px;
  width: 18px; height: 18px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  background: #F2541B;
}
.sp-tier-ok svg { width: 11px; height: 11px; fill: none; stroke: #fff; stroke-width: 3.2;
  stroke-linecap: round; stroke-linejoin: round; }
.sp-best {
  margin-top: 12px;
  text-align: center;
  font-family: var(--font-ka);
  font-size: 12.5px;
  color: var(--text-2);
}

.sp-continue {
  position: relative;
  z-index: 1;
  margin-top: auto;
  width: 100%;
  min-height: 56px;
  border: 0;
  border-radius: 28px;
  background: linear-gradient(180deg, #FF8A2B, #F2541B);
  box-shadow: 0 10px 28px -8px rgba(242, 84, 27, 0.8), inset 0 1px 0 rgba(255, 255, 255, 0.3);
  font-family: var(--font-ka);
  font-size: 16px;
  font-weight: 700;
  color: #fff;
  cursor: pointer;
  transition: transform var(--dur-fast) var(--ease-spring);
}
/* margin-top:auto pins it to the bottom on a tall phone; the tiers card keeps a
   floor under itself for a short one. */
.sp-card-tiers { margin-bottom: 22px; }
.sp-continue:active { transform: scale(0.96); }

/* The hero flame is a door now — say so on press. */
#hero-streak { cursor: pointer; transition: transform var(--dur-fast) var(--ease-spring); }
#hero-streak:active { transform: scale(0.95); }

/* ---------- The mood week on Health (2026-09-23) ----------
   Seven still faces from the mood slider, oldest left, that morning's sleep under
   each. Repeats .card.settings-card so .card[data-accent]-style later rules cannot
   win the padding back. The face's own colours come from .mf-* in 04-widgets.css. */
.card.settings-card.mood-week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 4px;
  padding: 14px 10px 12px;
}
.mw-day {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  min-width: 0;
}
.mw-dow {
  font-family: var(--font-ka);
  font-size: 11px;
  color: var(--text-3);
}
.mw-day.is-today .mw-dow { color: var(--text-1); font-weight: 600; }
.mood-face-mini,
.mw-empty {
  width: 34px;
  height: 34px;
  display: block;
}
.mw-empty {
  border-radius: 50%;
  border: 1.5px dashed var(--border-2);
}
.mw-sleep {
  font-family: var(--font-num);
  font-size: 12px;
  color: var(--text-2);
  white-space: nowrap;
}
.mw-unit {
  font-family: var(--font-ka);
  font-size: 9px;
  color: var(--text-3);
  margin-left: 1px;
}

/* ---------- Health: the mood screen (2026-09-24) ----------
   Mockup B, on Giorgi's pick. The hero is the whole first screen above the tab bar;
   the week sits under it. JS writes --hm (the blended colour) and --hm-rgb (its
   triplet, for the alpha washes). Built by js/15-health-mood.js. */
/* On the welcome the kicker carries the name; inside, the normal title is back. */
#tab-health.is-welcome .settings-header { display: none; }
/* The hero is exactly one screen tall and cancels the tab's top and side padding;
   the bottom padding left a strip of dead scroll under it (2026-09-24). */
#tab-health.is-welcome { padding-bottom: 0; }

.hm-hero {
  --hm: var(--mood-none);
  --hm-rgb: 122, 122, 136;
  position: relative;
  isolation: isolate;
  display: flex;
  flex-direction: column;
  align-items: center;
  margin: calc(-1 * var(--pad)) calc(-1 * var(--pad)) 0;
  padding: calc(env(safe-area-inset-top) + 18px) var(--pad) 26px;
  min-height: calc(100vh - 72px - env(safe-area-inset-bottom));
  min-height: calc(100svh - 72px - env(safe-area-inset-bottom));
  overflow: hidden;
}
.hm-wash {
  position: absolute;
  inset: 0;
  z-index: -1;
  pointer-events: none;
  background:
    radial-gradient(120% 60% at 50% 46%, rgba(var(--hm-rgb), 0.30), rgba(var(--hm-rgb), 0) 70%),
    radial-gradient(90% 40% at 50% 100%, rgba(var(--hm-rgb), 0.10), rgba(var(--hm-rgb), 0) 80%);
  /* Fade out at the bottom, or the glow ends in a hard line above the week. */
  -webkit-mask-image: linear-gradient(#000 78%, transparent);
  mask-image: linear-gradient(#000 78%, transparent);
}
.hm-kicker {
  align-self: stretch;
  display: flex;
  justify-content: space-between;
  align-items: center;
  min-height: 28px;
  font-family: var(--font-num);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--text-2);
}
.hm-q {
  margin-top: 14px;
  font-family: var(--font-ka);
  font-size: 28px;
  font-weight: 800;
  line-height: 1.25;
  text-align: center;
  color: var(--text-1);
}
/* Height-led, so a short phone (the SE) shrinks the character rather than
   pushing the save button under the tab bar. */
.hm-stage {
  height: min(290px, 37svh);
  max-width: 100%;
  aspect-ratio: 32 / 29;
  margin: auto 0;
  pointer-events: none;
}
.hm-stage svg { width: 100%; height: 100%; overflow: visible; display: block; }
.hm-word {
  min-height: 38px;
  font-family: var(--font-ka);
  font-size: 26px;
  font-weight: 800;
  color: var(--hm);
  text-shadow: 0 0 24px rgba(var(--hm-rgb), 0.45);
}
.hm-word.pop { animation: moodPop var(--dur-slow) var(--ease-spring); }

.hm-slider {
  position: relative;
  align-self: stretch;
  height: 64px;
  margin-top: 18px;
  border-radius: var(--radius-pill);
  background: rgba(255, 255, 255, 0.05);
  border: 1px solid var(--border-2);
  box-shadow: inset 0 2px 10px rgba(0, 0, 0, 0.5);
  touch-action: none;
  cursor: grab;
  -webkit-user-select: none;
  user-select: none;
}
.hm-slider:focus-visible { outline: 2px solid var(--border-2); outline-offset: 2px; }
.hm-fill {
  position: absolute;
  left: 5px;
  top: 5px;
  bottom: 5px;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, rgba(var(--hm-rgb), 0.35), var(--hm));
  box-shadow: 0 0 26px -2px rgba(var(--hm-rgb), 0.7);
  transition: opacity var(--dur-mid) var(--ease-out);
}
.hm-thumb {
  position: absolute;
  left: 5px;
  top: 7px;
  width: 72px;
  height: 48px;
  border-radius: var(--radius-pill);
  background: linear-gradient(180deg, #fff, #e9e9ee);
  box-shadow: 0 6px 16px rgba(0, 0, 0, 0.45), inset 0 -2px 0 rgba(0, 0, 0, 0.08);
  transition: scale var(--dur-mid) var(--ease-spring);
}
.hm-thumb::before,
.hm-thumb::after {
  content: '';
  position: absolute;
  top: 16px;
  bottom: 16px;
  width: 3px;
  border-radius: 2px;
  background: rgba(0, 0, 0, 0.14);
  left: 30px;
}
.hm-thumb::after { left: 38px; }
.hm-hero.is-dragging .hm-thumb { scale: 1.08; }
/* Before she sets today: no fill, and the handle says "drag me". */
.hm-hero.is-unset .hm-fill { opacity: 0; }
.hm-hero.is-unset .hm-thumb { animation: moodNudge var(--mood-nudge) var(--ease-in-out) infinite; }
.hm-ends {
  align-self: stretch;
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
  padding: 0 8px;
  font-family: var(--font-ka);
  font-size: 13px;
  font-weight: 600;
  color: var(--text-2);
}

/* The week. Repeats .card so .card[data-accent]-style later rules cannot win. */
.card.hm-week {
  display: grid;
  grid-template-columns: repeat(7, minmax(0, 1fr));
  gap: 2px;
  padding: 12px 8px;
}
.hm-day {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  min-width: 0;
  padding: 6px 0 8px;
  border-radius: 14px;
}
.hm-day.is-today { background: rgba(255, 255, 255, 0.05); }
.hm-dow { font-family: var(--font-ka); font-size: 11px; font-weight: 600; color: var(--text-3); }
.hm-day.is-today .hm-dow { color: var(--lime); }
.hm-mini { width: 40px; height: 40px; }
.hm-mini svg { width: 100%; height: 100%; overflow: visible; display: block; }
.hm-mini.is-empty { position: relative; }
.hm-mini.is-empty svg { display: none; }
.hm-mini.is-empty::after {
  content: '';
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  border: 1.5px dashed var(--border-2);
}
.hm-sleep { font-family: var(--font-num); font-size: 12px; color: var(--text-2); white-space: nowrap; }
.hm-unit { font-family: var(--font-ka); font-size: 9px; color: var(--text-3); margin-left: 1px; }

/* The save button, and the welcome lifting away once it is pressed. */
.btn.btn-primary.hm-save {
  align-self: stretch;
  margin-top: 18px;
  min-height: 54px;
  font-family: var(--font-ka);
  font-size: 16px;
  font-weight: 700;
  transition: opacity var(--dur-mid) var(--ease-out), transform var(--dur-fast) var(--ease-spring);
}
.btn.btn-primary.hm-save:disabled { opacity: 0.3; pointer-events: none; }
.hm-hero.is-leaving {
  animation: hmLeave var(--dur-page) var(--ease-in-out) both;
  pointer-events: none;
}
@keyframes hmLeave { to { opacity: 0; transform: translateY(-28px) scale(0.97); } }

/* The inside of Health: today's mood as one card, tap to change it. */
.card.hm-today {
  --hm: var(--mood-mid);
  display: flex;
  align-items: center;
  gap: 14px;
  width: 100%;
  padding: 14px 16px;
  margin: 0 0 4px;
  text-align: left;
  color: inherit;
  font: inherit;
  cursor: pointer;
  border: 1px solid color-mix(in srgb, var(--hm) 30%, var(--border));
  background:
    radial-gradient(120% 140% at 0% 50%, color-mix(in srgb, var(--hm) 18%, transparent), transparent 70%),
    var(--surface);
  transition: transform var(--dur-fast) var(--ease-spring);
}
.card.hm-today:active { transform: scale(0.98); }
.hm-today-mini { width: 64px; height: 64px; flex: 0 0 64px; }
.hm-today-mini svg { width: 100%; height: 100%; overflow: visible; display: block; }
.hm-today-txt { display: flex; flex-direction: column; gap: 2px; flex: 1 1 auto; min-width: 0; }
.hm-today-q { font-family: var(--font-ka); font-size: 13px; color: var(--text-2); }
.hm-today-word { font-family: var(--font-ka); font-size: 22px; font-weight: 800; color: var(--hm); }
.hm-today-go { width: 22px; height: 22px; color: var(--text-3); flex: 0 0 auto; }

/* Log out on the profile page (2026-09-24). */
.btn.btn-ghost.profile-signout {
  margin-top: 22px;
  min-height: 52px;
  font-family: var(--font-ka);
  font-weight: 600;
  color: var(--red);
  border-color: rgba(224, 85, 85, 0.35);
}
.btn.btn-ghost.profile-signout[hidden] { display: none; }

/* The streak page's button is ALWAYS on screen (2026-09-24). It was the last thing
   in a scrolling column, so on a phone the height of Giorgi's it sat just below
   the fold. Sticky inside .sp-shell: the cards scroll up under it, and a fade of
   the page's own ground behind it keeps them from showing through. */
.sp-foot {
  position: sticky;
  bottom: calc(-1 * (env(safe-area-inset-bottom) + 22px));
  z-index: 2;
  flex-shrink: 0;
  margin: auto calc(-1 * var(--pad)) calc(-1 * (env(safe-area-inset-bottom) + 22px));
  padding: 28px var(--pad) calc(env(safe-area-inset-bottom) + 22px);
  background: linear-gradient(rgba(11, 8, 6, 0), #0B0806 28px);
  pointer-events: none;
}
.sp-foot .sp-continue { pointer-events: auto; margin-top: 0; }

/* ============================================================
   THE DAILY PRACTICE on Health (2026-09-24) — js/16-health-daily.js
   Headspace-bright scenes inside the dark app. Every ground is a --hd-* token
   (css/01-tokens.css); the scenes are written in --hd-ink, or white where the
   ground is dark (.is-light). The mockup is mockups/health-daily.html.
   ============================================================ */

/* ---------- inside Health: the card, the tip, the month ---------- */
.hd-today {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin: 18px 0 8px;
}
.hd-head { display: flex; align-items: baseline; justify-content: space-between; padding: 0 4px; }
.hd-dayof { font-family: var(--font-ka); font-size: 13px; font-weight: 600; color: var(--text-2); letter-spacing: 0.02em; }
.hd-dayof .num { color: var(--text-1); font-weight: 800; }

.hd-card {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  width: 100%;
  min-height: 318px;
  padding: 18px 18px 20px;
  border: 0;
  border-radius: 28px;
  overflow: hidden;
  text-align: left;
  font: inherit;
  cursor: pointer;
  color: var(--hd-ink);
  background: var(--hd-bg);
  box-shadow: 0 18px 40px -18px color-mix(in srgb, var(--hd-bg) 70%, transparent);
  transition: transform var(--dur-fast) var(--ease-spring);
  -webkit-tap-highlight-color: transparent;
}
.hd-card.is-light { color: #fff; }
.hd-card:active { transform: scale(0.98); }
.hd-chip {
  position: relative;
  z-index: 2;
  padding: 4px 11px;
  border-radius: 99px;
  font-family: var(--font-ka);
  font-size: 12px;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.5);
}
.hd-card.is-light .hd-chip { background: rgba(255, 255, 255, 0.2); }
.hd-card-title {
  position: relative;
  z-index: 2;
  max-width: 92%;
  margin-top: 2px;
  font-family: var(--font-ka);
  font-size: 21px;
  font-weight: 800;
  line-height: 1.25;
  text-wrap: balance;
}
.hd-card-task {
  position: relative;
  z-index: 2;
  max-width: 88%;
  font-family: var(--font-ka);
  font-size: 13.5px;
  line-height: 1.45;
  opacity: 0.82;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}
.hd-card-hill { position: absolute; left: 0; right: 0; bottom: 0; width: 100%; height: 104px; z-index: 0; }
.hd-card-hill path { fill: var(--hd-hill-c); }
.hd-card-guide {
  position: absolute;
  left: 20px;
  bottom: 30px;
  z-index: 1;
  width: 112px;
  height: 112px;
  animation: hdIdle var(--dur-hd-idle) var(--ease-in-out) infinite alternate;
}
.hd-card-guide svg { display: block; overflow: visible; }
.hd-go {
  position: absolute;
  right: 16px;
  bottom: 16px;
  z-index: 3;
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 9px 16px 9px 9px;
  border-radius: 99px;
  font-family: var(--font-ka);
  font-size: 14px;
  font-weight: 700;
  color: #fff;
  background: var(--hd-ink);
}
.hd-go-ic { width: 26px; height: 26px; border-radius: 50%; background: #fff; display: grid; place-items: center; }
.hd-go-ic svg { width: 12px; height: 12px; }
.hd-go-ic path { fill: var(--hd-ink); }
.hd-go-ic.is-tick path { fill: none; stroke: #111; stroke-width: 2.2; stroke-linecap: round; stroke-linejoin: round; }
.hd-card.is-done .hd-go { background: var(--lime); color: #111; }
.hd-card.is-done .hd-go-ic { background: rgba(0, 0, 0, 0.12); }

@keyframes hdIdle { from { transform: scale(1); } to { transform: scale(1.08) translateY(-2px); } }

/* The tip: a leaf-shaped card, the leaf swaying. */
.hd-tip {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: 15px 18px 16px 58px;
  border-radius: 30px 8px 30px 8px;
  border: 1px solid rgba(123, 224, 166, 0.22);
  background: linear-gradient(135deg, #123D2A, #0F2A22);
}
.hd-leaf { position: absolute; left: 17px; top: 16px; width: 28px; height: 28px; overflow: visible; }
.hd-leaf g { transform-origin: 14px 26px; animation: hdSway var(--dur-hd-sway) var(--ease-in-out) infinite; }
.hd-leaf path { fill: var(--hd-mint); }
.hd-leaf .hd-leaf-vein { fill: none; stroke: #0F2A22; stroke-width: 1.6; stroke-linecap: round; }
@keyframes hdSway { 0%, 100% { transform: rotate(-6deg); } 50% { transform: rotate(7deg); } }
.hd-tip-label { font-family: var(--font-ka); font-size: 12px; font-weight: 700; color: var(--hd-mint); letter-spacing: 0.03em; }
.hd-tip-text { font-family: var(--font-ka); font-size: 15px; line-height: 1.45; color: var(--text-1); }

/* The month: thirty dots, done ones in their practice's colour. */
.card.hd-journey { padding: 14px 16px 16px; }
.hd-journey-top {
  display: flex;
  justify-content: space-between;
  margin-bottom: 11px;
  font-family: var(--font-ka);
  font-size: 13px;
  color: var(--text-2);
}
.hd-journey-top .num { color: var(--text-1); font-weight: 700; }
.hd-dots { display: grid; grid-template-columns: repeat(10, minmax(0, 1fr)); gap: 7px; }
.hd-dot { aspect-ratio: 1; border-radius: 50%; background: var(--surface-3); }
.hd-dot.is-done { background: var(--c, var(--lime)); }
.hd-dot.is-today { background: transparent; box-shadow: inset 0 0 0 2px var(--lime); animation: hdPulse var(--dur-hd-idle) var(--ease-in-out) infinite; }
@keyframes hdPulse { 50% { box-shadow: inset 0 0 0 2px var(--lime), 0 0 0 5px var(--lime-dim); } }

/* ---------- the player page ---------- */
.hd-page {
  position: fixed;
  inset: 0;
  z-index: 120;
  background: rgba(5, 5, 8, 0.72);
  opacity: 0;
  transition: opacity var(--dur-mid) var(--ease-out);
}
.hd-page.show { opacity: 1; }
.hd-page.page-leaving { opacity: 0; pointer-events: none; transition: opacity var(--dur-page-out) var(--ease-in-out); }
.hd-shell {
  position: relative;
  height: 100%;
  max-width: 480px;
  margin: 0 auto;
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  color: var(--hd-ink);
  background: var(--hd-bg);
  animation: pageIn var(--dur-page) var(--ease-out) both;
  transition: background-color var(--dur-slow) var(--ease-in-out);
  font-family: var(--font-ka);
}
.hd-shell.is-light { color: #fff; }
.hd-page.page-leaving .hd-shell { animation: pageOut var(--dur-page-out) var(--ease-in-out) both; }

.hd-bar {
  position: sticky;
  top: 0;
  z-index: 6;
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: calc(env(safe-area-inset-top) + 12px) 16px 6px;
  pointer-events: none;
}
.hd-bar > * { pointer-events: auto; }
.hd-bar-btn {
  width: 40px;
  height: 40px;
  border: 0;
  border-radius: 50%;
  display: grid;
  place-items: center;
  color: inherit;
  cursor: pointer;
  background: rgba(43, 34, 51, 0.1);
  -webkit-backdrop-filter: blur(8px);
  backdrop-filter: blur(8px);
}
.hd-shell.is-light .hd-bar-btn { background: rgba(255, 255, 255, 0.16); }
.hd-shell .hd-bar-btn.is-ghost { visibility: hidden; }
.hd-bar-btn svg { width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; }
.hd-sound .hd-spk { fill: currentColor; stroke: none; }
.hd-sound.is-off { opacity: 0.55; }
.hd-bar-day {
  padding: 6px 12px;
  border-radius: 99px;
  font-size: 13px;
  font-weight: 600;
  background: rgba(43, 34, 51, 0.08);
}
.hd-shell.is-light .hd-bar-day { background: rgba(255, 255, 255, 0.14); }
.hd-bar-day .num { font-weight: 800; }

.hd-title {
  position: relative;
  z-index: 2;
  margin: 0;
  padding: 0 24px;
  font-size: 23px;
  font-weight: 800;
  line-height: 1.24;
  text-align: center;
  text-wrap: balance;
}
.hd-stage {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: center;
  min-height: calc(100svh - 58px - env(safe-area-inset-top));
  padding: 8px 0 26px;
}

/* The booklet's page, under the practice. */
.hd-why {
  margin: 4px 16px calc(env(safe-area-inset-bottom) + 28px);
  padding: 18px 18px 6px;
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.34);
}
.hd-shell.is-light .hd-why { background: rgba(0, 0, 0, 0.16); }
.hd-shell.is-write .hd-why, .hd-shell.is-review .hd-why { background: var(--surface); color: var(--text-1); }
.hd-why-label {
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  opacity: 0.7;
}
.hd-why-text { margin: 6px 0 16px; font-size: 14.5px; line-height: 1.6; white-space: pre-line; }

/* ---------- breathe and sit ---------- */
.hd-waves { position: absolute; inset: 0; overflow: hidden; pointer-events: none; }
.hd-wave { position: absolute; left: 0; width: 200%; }
.hd-wave.w1 { top: 0; height: 30%; animation: hdDrift var(--dur-hd-drift) linear infinite; }
.hd-wave.w1 path { fill: color-mix(in srgb, var(--hd-sun) 78%, var(--hd-tang)); }
.hd-wave.w2 { bottom: 0; height: 46%; animation: hdDrift calc(var(--dur-hd-drift) * 1.4) linear infinite reverse; }
.hd-wave.w2 path { fill: color-mix(in srgb, var(--hd-sun-2) 55%, #fff); }
.hd-wave.w3 { bottom: 0; height: 22%; animation: hdDrift calc(var(--dur-hd-drift) * 0.8) linear infinite; }
.hd-wave.w3 path { fill: color-mix(in srgb, var(--hd-tang) 50%, var(--hd-sun)); }
@keyframes hdDrift { to { transform: translateX(-50%); } }
.hd-meta { position: relative; z-index: 2; margin-top: 4px; font-size: 13px; font-weight: 600; opacity: 0.7; }
.hd-orb {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 250px;
  height: 250px;
  margin-top: 22px;
}
.hd-ring { position: absolute; inset: 0; width: 100%; height: 100%; }
.hd-ring-track { fill: none; stroke: rgba(43, 34, 51, 0.12); stroke-width: 7; }
.hd-ring-fill { fill: none; stroke: var(--hd-ink); stroke-width: 7; stroke-linecap: round; }
.hd-ball { width: 124px; height: 124px; will-change: transform; }
.hd-ball svg { display: block; overflow: visible; }
.hd-phase {
  position: relative;
  z-index: 2;
  min-height: 38px;
  margin-top: 14px;
  font-size: 27px;
  font-weight: 800;
}
.hd-phase.is-new { animation: hdPhaseIn var(--dur-mid) var(--ease-out); }
@keyframes hdPhaseIn { from { opacity: 0; transform: translateY(6px); } }
.hd-play {
  position: relative;
  z-index: 2;
  display: grid;
  place-items: center;
  width: 72px;
  height: 72px;
  margin-top: 14px;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  background: var(--hd-ink);
  box-shadow: 0 12px 28px -10px rgba(43, 34, 51, 0.6);
  transition: transform var(--dur-fast) var(--ease-spring);
}
.hd-play:active { transform: scale(0.92); }
.hd-play svg { width: 28px; height: 28px; fill: #fff; stroke: #fff; }
.hd-prog { position: relative; z-index: 2; width: calc(100% - 44px); margin-top: auto; padding-top: 22px; }
.hd-track { position: relative; height: 5px; border-radius: 9px; background: rgba(43, 34, 51, 0.18); }
.hd-track i { position: absolute; left: 0; top: 0; bottom: 0; width: 0; border-radius: 9px; background: var(--hd-ink); }
.hd-track b { position: absolute; top: 50%; left: 0; width: 15px; height: 15px; margin: -7.5px 0 0 -7.5px; border-radius: 50%; background: var(--hd-ink); }
.hd-times { display: flex; justify-content: space-between; margin-top: 7px; font-size: 12px; font-weight: 600; }

/* ---------- senses ---------- */
.hd-sn-big {
  position: relative;
  display: grid;
  place-items: center;
  width: 210px;
  height: 210px;
  margin-top: 30px;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  background: rgba(255, 255, 255, 0.16);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.18);
  -webkit-tap-highlight-color: transparent;
}
.hd-sn-ic svg { width: 108px; height: 108px; display: block; }
.hd-sn-n {
  position: absolute;
  right: 4px;
  top: 4px;
  display: grid;
  place-items: center;
  width: 58px;
  height: 58px;
  border-radius: 50%;
  font-size: 26px;
  font-weight: 800;
  color: var(--hd-ink);
  background: #fff;
}
.hd-sn-line { min-height: 50px; margin: 24px 28px 10px; font-size: 17px; font-weight: 700; text-align: center; line-height: 1.4; }
.hd-sn-dots { display: flex; gap: 10px; min-height: 16px; }
.hd-sn-dots i { width: 14px; height: 14px; border-radius: 50%; background: rgba(255, 255, 255, 0.3); transition: transform var(--dur-mid) var(--ease-spring), background var(--dur-mid); }
.hd-sn-dots i.on { background: #fff; transform: scale(1.25); }
.hd-sn-hint { margin-top: 14px; font-size: 13px; opacity: 0.78; text-align: center; padding: 0 24px; }
.hd-sn-rail { display: flex; gap: 10px; margin-top: auto; padding-top: 26px; }
/* The circle and its lines sit in the middle of the space; the rail stays at the bottom. */
.hd-senses .hd-sn-big { margin-top: auto; }
.hd-senses .hd-title { margin-bottom: 20px; }
.hd-sn-rail span {
  display: grid;
  place-items: center;
  width: 46px;
  height: 46px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.14);
  transition: transform var(--dur-mid) var(--ease-spring), background var(--dur-mid);
}
.hd-sn-rail span svg { width: 24px; height: 24px; }
.hd-sn-rail span.cur { background: rgba(255, 255, 255, 0.42); transform: translateY(-6px); }
.hd-sn-rail span.done { background: rgba(255, 255, 255, 0.28); }

/* ---------- write and the month review ---------- */
.hd-shell.is-write, .hd-shell.is-review {
  background: linear-gradient(var(--hd-bg) 0 236px, var(--bg) 236px);
}
.hd-shell.is-write .hd-bar-btn, .hd-shell.is-review .hd-bar-btn { background: rgba(43, 34, 51, 0.12); }
.hd-wr-top { position: relative; min-height: 178px; padding: 2px 0 0; }
.hd-wr-top .hd-title { text-align: left; max-width: 72%; padding-right: 0; }
.hd-wr-guide { position: absolute; right: 14px; top: 34px; width: 116px; height: 116px; }
.hd-wr-guide svg { display: block; overflow: visible; }
.hd-wr { display: flex; flex-direction: column; gap: 10px; padding: 18px 16px; color: var(--text-1); }
.hd-wr-row {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 3px 8px 3px 14px;
  border: 1px solid var(--border);
  border-radius: 16px;
  background: var(--surface);
  transition: border-color var(--dur-slow) var(--ease-out), box-shadow var(--dur-slow) var(--ease-out);
}
.hd-wr-n { width: 18px; flex: 0 0 18px; font-weight: 800; color: var(--text-3); text-align: center; }
.hd-wr-row input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 13px 0;
  border: 0;
  outline: none;
  background: none;
  color: var(--text-1);
  font-family: var(--font-ka);
  font-size: 16px;   /* 16px or iOS zooms the page on focus */
}
.hd-wr-row.is-filled { border-color: color-mix(in srgb, var(--hd-yolk) 55%, transparent); box-shadow: 0 0 22px -4px color-mix(in srgb, var(--hd-yolk) 30%, transparent); }
.hd-wr-row.is-filled .hd-wr-n { color: var(--hd-yolk); }
.hd-wr-row.is-picked { border-color: var(--lime); box-shadow: 0 0 22px -4px var(--lime-glow); }
.hd-wr-star { flex: 0 0 38px; width: 38px; height: 38px; border: 0; border-radius: 50%; background: none; cursor: pointer; display: grid; place-items: center; }
.hd-wr-star svg { width: 20px; height: 20px; fill: none; stroke: var(--text-3); stroke-width: 1.8; stroke-linejoin: round; }
.hd-wr-row.is-picked .hd-wr-star svg { fill: var(--lime); stroke: var(--lime); }
.hd-wr-add {
  align-self: flex-start;
  padding: 8px 4px;
  border: 0;
  background: none;
  cursor: pointer;
  font-family: var(--font-ka);
  font-size: 14px;
  font-weight: 700;
  color: var(--hd-yolk);
}
.hd-wr-pickhint { font-size: 13px; color: var(--text-2); padding: 0 4px; }
.hd-wr-count { display: flex; justify-content: space-between; padding: 2px 4px; font-size: 13px; color: var(--text-2); }
.hd-wr-count .num { color: var(--text-1); font-weight: 700; }
.btn.btn-primary.hd-save { min-height: 54px; margin-top: 4px; font-family: var(--font-ka); font-size: 16px; font-weight: 700; }
.btn.btn-primary.hd-save:disabled { opacity: 0.3; pointer-events: none; }
.hd-review { margin: 0 16px; padding: 14px 16px 16px; border-radius: 22px; background: var(--surface); color: var(--text-1); }
.hd-review-n { margin-bottom: 11px; font-size: 14px; color: var(--text-2); }
.hd-review-n .num { color: var(--text-1); font-weight: 800; }

/* ---------- let it go ---------- */
.hd-shell.is-release { background: radial-gradient(120% 70% at 50% 100%, #3A1F8A, var(--hd-night) 60%, #120830); }
.hd-stars { position: absolute; inset: 0; width: 100%; height: 100%; pointer-events: none; }
.hd-thought {
  position: relative;
  z-index: 2;
  width: calc(100% - 52px);
  margin-top: 30px;
  padding: 14px 18px;
  border-radius: 26px;
  border: 1px solid color-mix(in srgb, var(--hd-lav) 40%, transparent);
  background: rgba(255, 255, 255, 0.09);
  transition: transform var(--dur-hd-float) var(--ease-in-out), opacity var(--dur-hd-float) var(--ease-in-out), filter var(--dur-hd-float) var(--ease-in-out);
}
.hd-thought textarea {
  display: block;
  width: 100%;
  min-height: 84px;
  border: 0;
  outline: none;
  resize: none;
  background: none;
  color: #fff;
  font-family: var(--font-ka);
  font-size: 16px;
  line-height: 1.45;
}
.hd-thought textarea::placeholder { color: rgba(255, 255, 255, 0.5); }
.hd-thought.is-gone { transform: translateY(-240px) scale(0.6); opacity: 0; filter: blur(8px); }
.hd-released {
  position: relative;
  z-index: 2;
  min-height: 30px;
  margin-top: -80px;
  font-size: 20px;
  font-weight: 800;
  opacity: 0;
  transition: opacity var(--dur-slow) var(--ease-out);
  pointer-events: none;
}
.hd-released.is-on { opacity: 1; }
.hd-rel-guide { position: relative; z-index: 2; width: 128px; height: 128px; margin-top: 70px; animation: hdIdle var(--dur-hd-idle) var(--ease-in-out) infinite alternate; }
.hd-rel-guide svg, .hd-do-guide svg { display: block; overflow: visible; }
.hd-pill {
  position: relative;
  z-index: 2;
  width: min(260px, calc(100% - 64px));
  height: 62px;
  margin-top: auto;
  overflow: hidden;
  border: 0;
  border-radius: 99px;
  cursor: pointer;
  color: #fff;
  font-family: var(--font-ka);
  font-size: 16px;
  font-weight: 700;
  background: #0B0620;
  box-shadow: 0 0 0 1px rgba(120, 120, 255, 0.45), 0 0 28px rgba(90, 80, 255, 0.55), 0 0 60px rgba(90, 80, 255, 0.28);
  touch-action: none;
  -webkit-touch-callout: none;
  user-select: none;
}
.hd-pill canvas { position: absolute; inset: 0; width: 100%; height: 100%; }
.hd-pill-fill { position: absolute; left: 0; top: 0; bottom: 0; width: 0; background: linear-gradient(90deg, rgba(90, 110, 255, 0.55), color-mix(in srgb, var(--hd-lav) 75%, transparent)); }
.hd-pill span { position: relative; }

/* ---------- go and do it · the timer · counting ---------- */
.hd-shell.is-doit, .hd-shell.is-timer, .hd-shell.is-count {
  background: linear-gradient(170deg, color-mix(in srgb, var(--hd-leaf) 80%, #fff), var(--hd-leaf) 45%, color-mix(in srgb, var(--hd-leaf) 80%, #000));
}
.hd-task { position: relative; z-index: 2; max-width: 32ch; margin: 10px 24px 24px; font-size: 15px; line-height: 1.55; text-align: center; opacity: 0.92; }
.hd-do-guide { position: relative; z-index: 2; width: 150px; height: 150px; margin-top: auto; animation: hdIdle var(--dur-hd-idle) var(--ease-in-out) infinite alternate; }
.hd-do.is-dance .hd-do-guide { animation: hdBop var(--dur-hd-bop) var(--ease-in-out) infinite alternate; }
@keyframes hdBop { from { transform: translateY(0) rotate(-5deg); } to { transform: translateY(-14px) rotate(5deg); } }
.hd-shell .is-cheer { animation: hdCheer var(--dur-slow) var(--ease-spring); }
@keyframes hdCheer { 40% { transform: translateY(-34px) scale(1.1); } }
.hd-notes { position: absolute; inset: 0; pointer-events: none; }
.hd-notes i { position: absolute; top: 46%; font-style: normal; font-size: 22px; opacity: 0; animation: hdNote calc(var(--dur-hd-bop) * 6) linear infinite; }
.hd-notes i:nth-child(1) { left: 20%; }
.hd-notes i:nth-child(2) { left: 38%; animation-delay: calc(var(--dur-hd-bop) * 1.5); }
.hd-notes i:nth-child(3) { left: 60%; animation-delay: calc(var(--dur-hd-bop) * 3); }
.hd-notes i:nth-child(4) { left: 76%; animation-delay: calc(var(--dur-hd-bop) * 4.5); }
@keyframes hdNote { 0% { opacity: 0; transform: translateY(0); } 20% { opacity: 0.9; } 100% { opacity: 0; transform: translateY(-120px) rotate(20deg); } }
.hd-soft-btn {
  position: relative;
  z-index: 2;
  margin-top: 18px;
  padding: 12px 22px;
  border: 0;
  border-radius: 99px;
  cursor: pointer;
  color: inherit;
  font-family: var(--font-ka);
  font-size: 15px;
  font-weight: 700;
  background: rgba(255, 255, 255, 0.2);
  box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.28);
}
.hd-soft-btn.is-on { background: #fff; color: var(--hd-ink); }
.hd-timer { position: relative; z-index: 2; display: flex; align-items: baseline; gap: 8px; margin-top: 18px; }
.hd-timer-t { font-size: 46px; font-weight: 800; letter-spacing: -0.02em; }
.hd-timer-of { font-size: 15px; opacity: 0.7; }
.hd-count {
  position: relative;
  z-index: 2;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 150px;
  height: 150px;
  margin-top: 18px;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  color: var(--hd-ink);
  background: var(--hd-yolk);
  box-shadow: 0 16px 34px -12px rgba(0, 0, 0, 0.35);
}
.hd-count-n { font-size: 48px; font-weight: 800; line-height: 1; }
.hd-count-l { margin-top: 6px; font-family: var(--font-ka); font-size: 13px; font-weight: 700; }
.hd-count-hint { position: relative; z-index: 2; max-width: 30ch; margin-top: 14px; font-size: 13px; text-align: center; opacity: 0.85; }

/* Hold-to-finish, the same on every doing screen. */
.hd-hold-wrap { position: relative; z-index: 2; display: flex; flex-direction: column; align-items: center; gap: 14px; margin-top: auto; padding-top: 22px; }
.hd-hold-cap { font-size: 13px; opacity: 0.85; text-align: center; padding: 0 24px; }
.hd-hold {
  position: relative;
  display: grid;
  place-items: center;
  width: 96px;
  height: 96px;
  border: 0;
  border-radius: 50%;
  cursor: pointer;
  color: var(--hd-ink);
  font-family: var(--font-ka);
  font-size: 12px;
  font-weight: 700;
  background: #fff;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.25);
  touch-action: none;
  -webkit-touch-callout: none;
  user-select: none;
  transition: background var(--dur-mid) var(--ease-out), transform var(--dur-fast) var(--ease-spring);
}
.hd-hold:active { transform: scale(0.96); }
.hd-hold svg { position: absolute; inset: -8px; width: 112px; height: 112px; transform: rotate(-90deg); pointer-events: none; }
.hd-hold-track { fill: none; stroke: rgba(255, 255, 255, 0.35); stroke-width: 6; }
.hd-shell:not(.is-light) .hd-hold-track { stroke: rgba(43, 34, 51, 0.15); }
.hd-hold-ring { fill: none; stroke: var(--lime); stroke-width: 6; stroke-linecap: round; }
.hd-hold.is-done { background: var(--lime); color: #111; }

/* ---------- the balance wheel ---------- */
.hd-wheel-hint { position: relative; z-index: 2; margin-top: 6px; font-size: 13px; opacity: 0.75; }
.hd-wheel-svg { width: min(320px, calc(100% - 32px)); height: auto; aspect-ratio: 1; margin-top: 8px; }
.hd-wheel-grid { fill: none; stroke: rgba(43, 34, 51, 0.12); }
.hd-slice { cursor: pointer; stroke: var(--hd-coral); stroke-width: 2; }
.hd-slice-n { font-family: var(--font-num); font-size: 15px; font-weight: 800; fill: var(--hd-ink); text-anchor: middle; pointer-events: none; }
.hd-wheel-leg { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 12px; width: calc(100% - 40px); margin-top: 12px; font-size: 12.5px; font-weight: 600; }
.hd-wheel-leg span { display: flex; align-items: center; gap: 7px; min-width: 0; }
.hd-wheel-leg i { flex: 0 0 11px; width: 11px; height: 11px; border-radius: 3px; }

/* ---------- the intro before every practice (2026-09-24, round 2) ----------
   The page opens on .is-intro: what this is, what the screen will do, the booklet's
   full task and why, and one start button that stays on screen. */
.hd-shell.is-intro .hd-body { display: none; }
.hd-shell:not(.is-intro) .hd-intro { display: none; }
.hd-shell:not(.is-intro) .hd-body { animation: hdStageIn var(--dur-page) var(--ease-out) both; }
@keyframes hdStageIn { from { opacity: 0; transform: translateY(18px); } }
.hd-bar-end { display: flex; gap: 8px; }
.hd-info circle, .hd-info path { fill: none; }
.hd-shell.is-intro .hd-info { opacity: 0.5; }

.hd-intro {
  display: flex;
  flex-direction: column;
  gap: 14px;
  min-height: calc(100svh - 58px - env(safe-area-inset-top));
  padding: 0 16px;
  animation: hdStageIn var(--dur-page) var(--ease-out) both;
}
.hd-intro-hero {
  position: relative;
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  min-height: 150px;
  padding: 6px 118px 4px 4px;
}
.hd-shell.is-light .hd-intro-hero .hd-chip { background: rgba(255, 255, 255, 0.2); }
.hd-intro-title {
  margin: 0;
  font-size: 25px;
  font-weight: 800;
  line-height: 1.22;
  text-wrap: balance;
}
.hd-intro-guide {
  position: absolute;
  right: 0;
  top: 24px;
  width: 110px;
  height: 110px;
  animation: hdIdle var(--dur-hd-idle) var(--ease-in-out) infinite alternate;
}
.hd-intro-guide svg { display: block; overflow: visible; }
.hd-intro-card {
  padding: 18px 18px 4px;
  border-radius: 24px;
  background: rgba(255, 255, 255, 0.4);
}
.hd-shell.is-light .hd-intro-card { background: rgba(0, 0, 0, 0.17); }
.hd-shell.is-write .hd-intro-card, .hd-shell.is-review .hd-intro-card { background: var(--surface); color: var(--text-1); }
.hd-how {
  margin: 10px 0 16px;
  padding: 0;
  list-style: none;
  counter-reset: hdhow;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.hd-how li {
  counter-increment: hdhow;
  position: relative;
  padding-left: 36px;
  font-size: 15.5px;
  line-height: 1.5;
  font-weight: 500;
}
.hd-how li::before {
  content: counter(hdhow);
  position: absolute;
  left: 0;
  top: 0;
  width: 25px;
  height: 25px;
  border-radius: 50%;
  display: grid;
  place-items: center;
  font-family: var(--font-num);
  font-size: 12.5px;
  font-weight: 800;
  color: #fff;
  background: var(--hd-ink);
}
.hd-shell.is-light .hd-how li::before { color: var(--hd-ink); background: #fff; }
.hd-shell.is-write .hd-how li::before, .hd-shell.is-review .hd-how li::before { color: #111; background: var(--hd-yolk); }
.hd-headphones {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  margin: 0 0 16px;
  padding: 12px 14px;
  border-radius: 16px;
  font-size: 13.5px;
  line-height: 1.45;
  background: rgba(43, 34, 51, 0.08);
}
.hd-headphones svg { flex: 0 0 22px; width: 22px; height: 22px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; }
.hd-intro-foot {
  position: sticky;
  bottom: 0;
  z-index: 4;
  margin: auto -16px 0;
  padding: 26px 16px calc(env(safe-area-inset-bottom) + 18px);
  background: linear-gradient(color-mix(in srgb, var(--hd-bg) 0%, transparent), var(--hd-bg) 26px);
}
.hd-shell.is-write .hd-intro-foot, .hd-shell.is-review .hd-intro-foot { background: linear-gradient(rgba(10, 10, 12, 0), var(--bg) 26px); }
.hd-shell.is-release .hd-intro-foot { background: linear-gradient(rgba(18, 8, 48, 0), #1E0F4A 26px); }
.hd-intro-go {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 10px;
  width: 100%;
  min-height: 58px;
  border: 0;
  border-radius: 99px;
  cursor: pointer;
  font-family: var(--font-ka);
  font-size: 17px;
  font-weight: 800;
  color: #fff;
  background: var(--hd-ink);
  box-shadow: 0 14px 30px -12px rgba(0, 0, 0, 0.5);
  transition: transform var(--dur-fast) var(--ease-spring);
}
.hd-intro-go:active { transform: scale(0.97); }
.hd-shell.is-write .hd-intro-go, .hd-shell.is-review .hd-intro-go { color: #111; background: var(--lime); }
.hd-shell.is-write .hd-intro-go .hd-go-ic, .hd-shell.is-review .hd-intro-go .hd-go-ic { background: #111; }
.hd-shell.is-write .hd-intro-go .hd-go-ic path, .hd-shell.is-review .hd-intro-go .hd-go-ic path { fill: var(--lime); }
.hd-shell.is-release .hd-intro-go { color: var(--hd-ink); background: var(--hd-lav); }
.hd-shell.is-release .hd-intro-go .hd-go-ic { background: var(--hd-ink); }
.hd-shell.is-release .hd-intro-go .hd-go-ic path { fill: var(--hd-lav); }

/* The 3 · 2 · 1 before breathing and meditation (2026-09-24). The ball steps back and
   one big number pops in its place per beat. */
.hd-cd {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  font-size: 96px;
  font-weight: 800;
  line-height: 1;
  color: var(--hd-ink);
  pointer-events: none;
}
.hd-cd.is-pop { animation: hdCdPop var(--dur-hd-count) var(--ease-out) both; }
@keyframes hdCdPop {
  0%   { opacity: 0; transform: scale(0.55); }
  22%  { opacity: 1; transform: scale(1.06); }
  70%  { opacity: 1; transform: scale(1); }
  100% { opacity: 0; transform: scale(0.92); }
}
.hd-ball { transition: opacity var(--dur-mid) var(--ease-out); }
.hd-shell.is-counting .hd-ball { opacity: 0.08; }
