/* Fonts self-hosted. 100KB of woff2, no third party. */
@font-face { font-family: "Jost"; font-style: normal; font-weight: 300;
  src: url("/fonts/jost-latin-300-normal.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Jost"; font-style: normal; font-weight: 400;
  src: url("/fonts/jost-latin-400-normal.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Figtree"; font-style: normal; font-weight: 400;
  src: url("/fonts/figtree-latin-400-normal.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Figtree"; font-style: italic; font-weight: 400;
  src: url("/fonts/figtree-latin-400-italic.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Figtree"; font-style: normal; font-weight: 700;
  src: url("/fonts/figtree-latin-700-normal.woff2") format("woff2"); font-display: swap; }
@font-face { font-family: "Figtree"; font-style: italic; font-weight: 700;
  src: url("/fonts/figtree-latin-700-italic.woff2") format("woff2"); font-display: swap; }

/* The Heart-Well Library.
   Values measured off alenalevineyoga.com computed styles.

   The root is 20px, not 16px, because hers is: every size below is relative
   to her body size rather than a browser default, so nothing drifts smaller
   than the running text. Jost stands in for Halyard Display, Figtree for
   Degular, until the Adobe kit exists. */

html { font-size: 20px; -webkit-text-size-adjust: 100%; }

:root {
  --paper:   #E6E4E8;   /* her practice-menu and blog body sections */
  --white:   #FFFFFF;   /* her poolside body, and every footer */
  --dark:    #000000;

  --ink:       #000000;
  --ink-dim:   #2E2A2C;
  --ink-faint: #5E585B;

  --on-dark:       #E9E3E0;   /* not pure white: 50px of #FFF on OLED glares */
  --on-dark-dim:   #B3ABA7;
  --on-dark-faint: #8B827D;

  --accent:    #C79288;   /* her "Book your spot" fill, and her inline emphasis */
  --accent-dp: #A87267;   /* the same rose, dark enough to carry text on paper */
  --accent-lt: #D6A79E;
  --accent-tx: #86544A;   /* rose text, the app's rose-text (5 Nov 2026): 6.2:1 on white, 4.9:1 on paper */

  --rule:      #BBBBBB;
  --raised:    #DFDAD6;   /* a row under the cursor */
  --rule-dark: #4A4346;   /* #2A2523 is 1.4:1 on black and vanishes at low brightness */

  --display: "Jost", "Halyard Display", system-ui, sans-serif;
  --body:    "Figtree", "Degular", system-ui, sans-serif;

  --pad:  clamp(1.1rem, 5vw, 4rem);
  --gut:  clamp(2.2rem, 7vh, 4.4rem);   /* her vertical rhythm is enormous */
  --wide: 62rem;   /* the page container. Running text is capped separately
                      at --read so a paragraph never runs past a comfortable
                      measure inside it. */
  --read: 40rem;
  --bar:  0px;                          /* grows when the mini bar docks */
}

* { box-sizing: border-box; }

/* A display declaration beats the hidden attribute. */
[hidden] { display: none !important; }

body {
  margin: 0;
  background: var(--paper);
  color: var(--ink);
  font-family: var(--body);
  line-height: 1.5;
  letter-spacing: .05em;      /* hers is 1px at 20px */
  -webkit-font-smoothing: antialiased;
  min-height: 100dvh;
  padding-bottom: var(--bar);
}

a { color: inherit; }
:focus-visible { outline: 2px solid var(--accent-dp); outline-offset: 4px; }

.wrap { max-width: var(--wide); margin: 0 auto; padding: 0 var(--pad); }

/* ---------- Header. On the hero's white, in ink (5 Nov 2026) ----------
   It sat transparent over the old photograph, as hers does. Her studio
   photograph is white to its edges, so white type would vanish there: the
   header now sits on the same white, above the picture, never over it. */
.site-head {
  position: relative; z-index: 20;
  padding: clamp(1rem, 3vh, 2rem) 0;
  background: var(--white); color: var(--ink);
}
.site-head .wrap {
  display: flex; align-items: center; justify-content: space-between;
  gap: 1rem; flex-wrap: wrap;
}

.lockup { display: flex; flex-direction: column; gap: .1rem; text-decoration: none; }
.lockup b {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1rem, 2vw, 1.3rem); letter-spacing: .01em; line-height: 1.15;
}
.lockup span {
  font-family: var(--body); font-size: .62rem;   /* 12.4px, her floor */
  letter-spacing: .1em; color: var(--ink-faint); line-height: 1.15;
}

.site-nav { display: flex; align-items: center; gap: clamp(1rem, 2.4vw, 1.9rem); }
.site-nav a {
  font-family: var(--body); font-size: .85rem; letter-spacing: .05em;
  text-decoration: none; white-space: nowrap;
  padding-bottom: .15rem; border-bottom: 1px solid transparent;
}
.site-nav a:hover, .site-nav a:focus-visible { border-bottom-color: currentColor; }

/* Her one filled button, exactly as she has it: a rose block, white type,
   no radius. It is the only fill in the header. */
.site-nav .btn {
  background: var(--accent); color: #FFFFFF;
  padding: .7rem 1.5rem; border: 1px solid var(--accent); border-bottom: 0;
  letter-spacing: .06em; line-height: 1;
  transition: background .2s, border-color .2s;
}
.site-nav .btn:hover, .site-nav .btn:focus-visible {
  background: var(--accent-dp); border-color: var(--accent-dp);
}

/* ---------- Hero ----------
   Her studio photograph (5 Nov 2026), shown whole: never cropped into her,
   never recoloured, its white never blended. The frame is pure white to
   every edge, so it sits on a white field of the same value and has no seam;
   the hero ends in a hairline where the white app section continues.
   Desktop: her words at the left, the picture at the right, running out to
   the edge of the window. Below 1000px: the picture full width, the words
   under it. The <img> carries its own width and height, so the space is
   held before it loads. */
.hero { background: var(--white); color: var(--ink); border-bottom: 1px solid var(--rule); }
.hero-body {
  display: grid;
  /* the words start on the page's own left edge, as .wrap's content does */
  grid-template-columns: max(var(--pad), calc((100vw - var(--wide)) / 2 + var(--pad))) minmax(0, 21rem) clamp(1.5rem, 3vw, 3rem) minmax(0, 1fr);
  grid-template-areas: ". words . picture";
  align-items: center;
  padding: clamp(.5rem, 2vh, 1.5rem) 0 clamp(1rem, 3vh, 2rem);
}
.hero-in {
  grid-area: words;
  display: flex; flex-direction: column; align-items: flex-start;
  gap: .7rem; text-align: left;
}
.hero-img { grid-area: picture; margin: 0; }
.hero-img img { display: block; width: 100%; height: auto; }

@media (max-width: 999px) {
  .hero-body {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: "picture" "words";
    padding: 0 0 var(--gut);
  }
  .hero-in { padding: .4rem var(--pad) 0; }
}

/* ---------- Type. Her scale: 50px title, 30px section, 20px body ---------- */
h1 {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(1.7rem, 4.4vw, 2.5rem);      /* 34 to 50px */
  line-height: 1.18; letter-spacing: .012em; margin: 0; text-wrap: balance;
}
h2 {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(1.24rem, 2.4vw, 1.5rem);     /* 25 to 30px */
  line-height: 1.22; letter-spacing: .02em; margin: 0;
}
/* Her emphasis, as she sets it on her own site: not a smaller note but the
   same size in her rose and a heavier weight. On the light sections `.em`
   does the same job inside a paragraph. */
.hero-em {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(1.02rem, 1.7vw, 1.24rem);
  line-height: 1.42; letter-spacing: .02em;
  color: var(--accent-tx); margin-top: .9rem;
}
.lede {
  font-family: var(--display); font-weight: 300;
  font-size: clamp(1.02rem, 1.7vw, 1.24rem);    /* her 26px lede */
  line-height: 1.42; letter-spacing: .02em; margin: 0;
  color: var(--ink-dim);
  /* Capped so a long lede wraps on the same measure as the heading above it
     rather than running out to the gutter. Without this the phone put the
     last word within 20px of the screen edge, tighter than anything else on
     the page. 34ch computed wider than the phone column, so the cap never
     engaged: 28ch binds at both sizes. */
  max-width: 28ch;
}
p { margin: 0; max-width: 100%; }
.dim { color: var(--ink-dim); max-width: var(--read); }

/* Her signature: one phrase in rose inside an otherwise black line. Used
   once per section, not on every paragraph, or it stops meaning anything. */
.em { color: var(--accent-dp); font-weight: 700; }

/* Her signature: a section heading closed with an em dash. */
.dash::after { content: "\00a0\2014"; }

/* ---------- Buttons ----------
   Her one filled button is a rose rectangle with no radius. The play square
   borrows it, and it is the one filled shape on the bar.
   The deeper rose, because white on #C79288 is 2.66:1, under the 3:1 a
   control needs. */
button, input, select, textarea { font: inherit; }
button { color: inherit; cursor: pointer; border-radius: 0; }

.sq {
  appearance: none; -webkit-appearance: none;
  width: 2.6rem; height: 2.6rem; flex: none; padding: 0;
  display: grid; place-items: center;
  background: var(--accent-dp); border: 1px solid var(--accent-dp); color: #FFFFFF;
  transition: background .2s, border-color .2s;
}
/* Only where there is a pointer to hover with. On a phone the hover state
   sticks after a tap, and the square would sit in the paler rose all the way
   through a practice. */
@media (hover: hover) {
  .sq:hover { background: var(--accent); border-color: var(--accent); }
}
.sq svg { width: 1.15rem; height: 1.15rem; fill: currentColor; }

/* Small uppercase rose. rose-text rather than the accent, which at this size
   does not carry on white or on paper. */
.eyebrow, .pick-tag {
  font-size: .7rem; letter-spacing: .12em; text-transform: uppercase;
  color: var(--accent-tx); line-height: 1.4;
}

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

/* ---------- The app ----------
   Where the stage was, on the white her footers use, with a hairline under
   it where the library begins. A phone drawn in CSS around a real
   screenshot, words and the stores beside it. The phone's rounded corners
   are the page's one exception to square corners: it is a picture of a
   phone, not a control (docs/copy-and-assets.md, deviations). */
.app { background: var(--white); border-bottom: 1px solid var(--rule); }
.app .wrap {
  display: flex; align-items: center; gap: 2rem 3.6rem;
  padding-top: var(--gut); padding-bottom: var(--gut);
}
.phone {
  flex: none; width: min(15rem, 34vw);
  background: #111; padding: .45rem; border-radius: 2.1rem;
}
.phone img { display: block; width: 100%; height: auto; border-radius: 1.7rem; }
.app-copy { flex: 1 1 22rem; min-width: 0; display: flex; flex-direction: column; align-items: flex-start; gap: 1rem; }
/* The icon beside the heading it names, rounded and lifted as an icon is on
   a phone: the second exception to square corners (docs/copy-and-assets.md,
   deviations). On a phone it sits just above the heading instead. */
.app-head { display: flex; align-items: center; gap: 1.1rem; }
.app-icon {
  display: block; flex: none; width: 72px; height: 72px; border-radius: 22.5%;
  box-shadow: 0 1px 2px rgba(0, 0, 0, .06), 0 4px 14px rgba(0, 0, 0, .08);
}
.app-copy .dim { max-width: 32rem; }
.stores { display: flex; flex-wrap: wrap; gap: .8rem 1rem; align-items: center; margin-top: .4rem; }
.badge { display: block; line-height: 0; }
.badge img { display: block; height: 52px; width: auto; }
.soon {
  font-family: var(--display); font-weight: 400; font-size: 1.05rem;
  letter-spacing: .02em; color: var(--accent-tx);
}
.app-small { font-size: .8rem; color: var(--ink-faint); }

/* On a phone the words come first and the phone under them, smaller, so the
   stores are on the first screen of the section. */
@media (max-width: 700px) {
  .app .wrap { flex-direction: column-reverse; align-items: flex-start; }
  .app-copy { flex: none; }
  .app-head { flex-direction: column; align-items: flex-start; gap: .7rem; }
  .phone { width: min(13rem, 60vw); align-self: center; }
}

/* ---------- The library ----------
   Her listings carry no boxes, cards or per-row rules. Whitespace separates
   the rows; the one playing is marked by a white ground and a tag. */
main { padding: var(--gut) 0 calc(var(--gut) * 1.3); }

.colls { display: flex; flex-wrap: wrap; gap: var(--gut) 3.2rem; }
.colls + .colls { margin-top: var(--gut); }
.coll { flex: 1 1 21rem; min-width: 0; }
/* The welcome's row keeps to one column's width, so it lines up with the
   collection under it instead of running the width of the page. */
#start { flex: 0 1 calc(50% - 1.6rem); }
@media (max-width: 900px) { #start { flex-basis: 100%; } }
.coll-lede { margin-top: .6rem; }
.rows { display: flex; flex-direction: column; gap: .2rem; margin-top: 1.1rem; }

/* The three needs the practices are grouped by. Small rose capitals, the
   same voice as the row's tag, so they read as labels on her
   list and not as a fourth level of heading. */
.grp {
  font-family: var(--body); font-weight: 600; font-size: .7rem;
  letter-spacing: .12em; text-transform: uppercase; line-height: 1.3;
  color: var(--accent-tx); margin: 1.7rem 0 0;
}
.coll-lede + .grp { margin-top: 1.5rem; }
/* The app's need rule, 48 by 4 in the need's tone, and her invitation. */
.grp-rule { display: block; width: 48px; height: 4px; margin-top: .5rem; }
.grp-inv { margin-top: .6rem; font-size: .85rem; line-height: 1.45; }
.grp-rule + .rows, .grp-inv + .rows { margin-top: .6rem; }

/* A row and the plus beside it. The row runs a little past the column so its
   white ground has some air; the type still lines up with the headings. */
.pick-row {
  position: relative; display: grid; grid-template-columns: minmax(0, 1fr) auto;
  margin: 0 -.6rem;
}
.pick {
  display: grid; grid-template-columns: 44px minmax(0, 1fr) auto;
  column-gap: .8rem; align-items: center; text-align: left;
  width: 100%; padding: .6rem;
  min-height: 44px;
  background: transparent; border: 0;
  transition: background .2s;
}
.pick[data-live="true"], .pick[data-live="true"] ~ .more, .pick[data-live="true"] ~ .pick-more { background: var(--white); }
.pick.bare { grid-template-columns: minmax(0, 1fr) auto; }
/* The app's row tile: a circle filled with the recording's tone, the mark in
   cream, at least 6:1 on every tone. A deviation from her square corners,
   logged in docs/copy-and-assets.md. Sized by height alone (trap 2). */
.pick-ic {
  width: 44px; height: 44px; border-radius: 50%; align-self: start;
  display: grid; place-items: center; color: #F4EFEA;
}
.pick-ic .mark { height: 100%; width: auto; display: block; }
.pick-text { min-width: 0; }
.pick-t {
  display: block; font-family: var(--display); font-weight: 400;
  font-size: 1.1rem; line-height: 1.28; letter-spacing: .01em;
}
.pick:hover .pick-t, .pick[data-live="true"] .pick-t { color: var(--accent-tx); }
.pick-s { display: block; margin-top: .15rem; font-size: .8rem; line-height: 1.45; letter-spacing: .03em; color: var(--ink-dim); }
.pick-tag { display: block; margin-top: .1rem; }
.pick-tag:empty { display: none; }
.pick-d {
  font-size: .72rem; letter-spacing: .09em; text-transform: uppercase;
  color: var(--ink-faint); font-variant-numeric: tabular-nums; white-space: nowrap;
}
.pick-d:empty { display: none; }

/* The plus. 44px to press, and drawn with the marks' own hairline. Across
   turns into a minus when the detail is held open. */
.more {
  appearance: none; -webkit-appearance: none;
  width: 44px; min-height: 44px; padding: 0; align-self: stretch;
  display: grid; place-items: center;
  background: transparent; border: 0; color: var(--accent-tx);
  transition: background .2s;
}
.more svg { width: 22px; height: 22px; display: block; }
.pick-row[data-pinned="true"] .more-v { display: none; }

/* The detail opens in place, lined up with the row's title. */
.pick-more {
  grid-column: 1 / -1;
  display: flex; flex-direction: column; gap: .45rem;
  padding: 0 .6rem .8rem calc(.6rem + 44px + .8rem);
  font-size: .85rem; line-height: 1.45; letter-spacing: .03em; color: var(--ink-dim);
}

/* Beside the row on a desktop, over the neighbouring column, so the rows below
   never move and are never covered. Touching the row, so the pointer can cross
   onto it. The query matches mountDetails() in app.js. */
@media (hover: hover) and (pointer: fine) and (min-width: 1040px) {
  .pick-more {
    position: absolute; z-index: 30; top: 0; left: 100%; width: 24rem;
    padding: .8rem 1rem;
    background: var(--white); border: 1px solid var(--rule);
  }
  .pick-more[data-up] { top: auto; bottom: 0; }
  #empowerment .pick-more { left: auto; right: 100%; }
}

/* ---------- Footer. Hers is bare ---------- */
.site-foot { background: var(--white); color: var(--ink); padding: var(--gut) 0; }
.site-foot .wrap { display: flex; flex-direction: column; gap: .15rem; }
.site-foot b { font-weight: 400; }
.site-foot a { color: var(--ink); text-decoration: none; }
.site-foot a:hover { text-decoration: underline; }
.site-foot small { display: block; margin-top: 1rem; font-size: .78rem; color: var(--ink-faint); }
/* Privacy sits quiet in the small type, underlined, as Privacy & data does in the app's About. */
.site-foot small a { color: inherit; text-decoration: underline; }

/* ---------- The mini bar ----------
   The player. Docks at the foot once a row has been pressed and stays.
   Hidden outright until then, so it cannot take focus. */
.mini {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 40;
  background: var(--white); border-top: 1px solid var(--rule);
  transform: translateY(101%); visibility: hidden;
  transition: transform .32s cubic-bezier(.2,.7,.3,1), visibility 0s .32s;
  padding-bottom: env(safe-area-inset-bottom);
}
.mini[data-on="true"] { transform: none; visibility: visible; transition-delay: 0s; }
.mini .wrap {
  display: flex; align-items: center; gap: .8rem;
  padding-top: .5rem; padding-bottom: .5rem;
}
.mini-mid { flex: 1 1 auto; min-width: 0; }
.mini-top {
  width: 100%; min-height: 44px; padding: 0;
  display: flex; flex-direction: column; justify-content: center; gap: .35rem;
  background: none; border: 0; text-align: left;
}
.mini-title {
  display: block; font-size: .95rem;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.mini-line { display: block; position: relative; height: 3px; background: var(--paper); }
/* A passage sits lit where it falls in the whole recording, as in the app. */
.mini-span { position: absolute; top: 0; bottom: 0; background: var(--accent-lt); }
.mini-line i { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--accent-dp); }
/* The passage's end: what happened, and where to go. */
.mini-over {
  display: flex; flex-wrap: wrap; align-items: center; gap: 0 1.2rem;
  font-size: .85rem; line-height: 1.3;
}
.mini-said { flex-basis: 100%; color: var(--ink-dim); padding-top: .3rem; }
.mini-link {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0;
  background: none; border: 0; color: var(--accent-tx);
  text-decoration: underline; text-underline-offset: .2em; letter-spacing: .03em;
}
.mini[data-over="true"] .mini-top { min-height: 0; padding-top: .2rem; }
/* The diagnostics panel owns the foot of the screen when it is open. */
.has-diag .mini { bottom: 42vh; }

/* ---------- Diagnostics ---------- */
.diag {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 80;
  background: #060505; border-top: 1px solid var(--rule-dark);
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11px; color: #B4ABA6; letter-spacing: 0;
  max-height: 42vh; display: none; flex-direction: column;
}
.diag[data-on="true"] { display: flex; }
.diag-bar {
  display: flex; gap: .75rem; align-items: center; flex-wrap: wrap;
  padding: .5rem .75rem; border-bottom: 1px solid var(--rule-dark);
}
.diag-bar button {
  background: transparent; border: 1px solid var(--rule-dark); border-radius: 0;
  color: #B4ABA6; font: inherit; padding: .35rem .6rem; cursor: pointer; min-height: 32px;
}
.diag-bar button:hover { color: var(--accent-lt); border-color: var(--accent); }
.diag-log { overflow: auto; padding: .5rem .75rem; white-space: pre-wrap; line-height: 1.45; }
.diag-log .e-error, .diag-log .e-stalled { color: #E08A7A; }
.diag-log .e-play, .diag-log .e-pause { color: var(--accent-lt); }

@media (max-width: 900px) {
  html { font-size: 18px; }
  .site-head .wrap { flex-direction: column; align-items: flex-start; gap: .5rem; }
  .site-nav { flex-wrap: wrap; gap: .9rem 1.1rem; }
}

/* The button always takes a row of its own at the left, however the five
   links wrap above it. */
@media (max-width: 700px) {
  .site-nav { gap: .9rem .8rem; }
  .site-nav::before { content: ""; order: 1; flex-basis: 100%; height: 0; }
  .site-nav .btn { order: 2; margin-top: -.9rem; }   /* the empty row adds a second gap */
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
}
