/* Ritual · web
   The same system the apps are built from: warm ink, a serif for titles and figures,
   a quiet sans for the interface, twelve muted jewel accents. Values come straight
   from design/canvas/Estilo.dc.html. */

/* The faces the design specifies, served from this site rather than from Google's: a
   page that says nothing leaves your phone should not hand every reader's address to a
   font server either. Instrument Sans is one variable file across 400 to 600. Both are
   under the SIL Open Font License, which is in fonts/ beside them. Each comes in two
   pieces, Latin and the rest of Latin, so a page in Spanish or English loads only the
   first. */
@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/instrument-serif-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/instrument-serif-italic-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("fonts/instrument-sans-latin.woff2") format("woff2");
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/instrument-serif-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Instrument Serif";
  font-style: italic;
  font-weight: 400;
  font-display: swap;
  src: url("fonts/instrument-serif-italic-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: "Instrument Sans";
  font-style: normal;
  font-weight: 400 600;
  font-display: swap;
  src: url("fonts/instrument-sans-latin-ext.woff2") format("woff2");
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

:root {
  --ink: #12100E;
  --surface: #1A1714;
  --surface-hi: #221E19;
  --hairline: #241F1A;
  --rule: #302A24;
  --ring-idle: #4A423A;
  --faint: #6E655B;
  --muted: #A79E92;
  --dimmed: #CFC7BB;
  --bone: #F2EDE4;
  --empty: #201C17;
  --future: #191612;
  --brass: #C09B69;
  --brass-dim: #8C714E;
  --brass-hi: #D8B584;
  --wall: #3A342E;

  --serif: "Instrument Serif", "Iowan Old Style", Georgia, serif;
  --sans: "Instrument Sans", "Helvetica Neue", Arial, sans-serif;

  --gutter: clamp(16px, 4vw, 48px);
  --max: 1120px;

  /* Springs, sampled into linear() so CSS can play them: critically damped (response
     0.4) for anything that just arrives, and a little bounce only where a tap caused it. */
  --spring: linear(0, 0.0596, 0.186, 0.3294, 0.4656, 0.584, 0.6819, 0.7601, 0.821, 0.8677, 0.9029, 0.9292, 0.9487,
      0.963, 0.9734, 0.9809, 0.9864, 0.9903, 0.9931, 0.9951, 0.9966, 0.9976, 0.9983, 0.9988, 1);
  --spring-t: 600ms;
  --bounce: linear(0, 0.0624, 0.2017, 0.3663, 0.5257, 0.6644, 0.7763, 0.8613, 0.9223, 0.9637, 0.9898, 1.0049,
      1.0124, 1.015, 1.0147, 1.0129, 1.0105, 1.008, 1.0057, 1.0039, 1.0025, 1.0014, 1.0007, 1.0003, 1);
  --bounce-t: 800ms;
  --ease-out: cubic-bezier(0.22, 1, 0.36, 1);
}

@supports not (transition-timing-function: linear(0, 1)) {
  :root { --spring: var(--ease-out); --bounce: cubic-bezier(0.34, 1.3, 0.64, 1); }
}

/* Accents. Only the hue changes between them; the ramp is the hue mixed over the
   empty-day ink at fixed fractions, so a row's week strip and its ring agree. */
[data-accent="brass"]   { --a: #C09B69; --a-dim: #8C714E; --r1: #3D3326; --r2: #604F38; --r3: #8B714E; }
[data-accent="jade"]    { --a: #79AB90; --a-dim: #5C7C68; --r1: #30362D; --r2: #445547; --r3: #5C7C68; }
[data-accent="granate"] { --a: #C79093; --a-dim: #906A6A; --r1: #3E312D; --r2: #634A49; --r3: #906A6A; }
[data-accent="night"]   { --a: #93A0C7; --a-dim: #6D748D; --r1: #353437; --r2: #4E515D; --r3: #6D748D; }
[data-accent="olive"]   { --a: #B0AA70; --a-dim: #807B53; --r1: #3A3627; --r2: #5A553B; --r3: #807B53; }
[data-accent="lagoon"]  { --a: #74A8BC; --a-dim: #587A86; --r1: #2F3535; --r2: #425459; --r3: #587A86; }

/* ───────────────────────── Base ───────────────────────── */

* { box-sizing: border-box; }
/* Whatever a rule says about display, hidden wins: the languages a page is not being read
   in, and a download that has nowhere to point yet. */
[hidden] { display: none !important; }
html { background: var(--ink); scroll-behavior: smooth; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  color: var(--dimmed);
  font: 400 17px/1.6 var(--sans);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { display: block; max-width: 100%; height: auto; }
a { color: var(--brass); text-decoration: none; }
a:hover { color: var(--brass-hi); }
:focus-visible { outline: 2px solid var(--brass); outline-offset: 3px; border-radius: 4px; }

.lab {
  font: 500 11px/1 var(--sans);
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.wrap { max-width: var(--max); margin: 0 auto; padding-left: var(--gutter); padding-right: var(--gutter); }

h1, h2, h3 { font-family: var(--serif); font-weight: 400; color: var(--bone); margin: 0; }
h1 { font-size: clamp(46px, 6.6vw, 92px); line-height: 0.98; letter-spacing: -0.01em; }
h1 em { font-style: italic; display: block; }
h2 { font-size: clamp(34px, 4.6vw, 58px); line-height: 1.04; letter-spacing: -0.01em; max-width: 20ch; }
h3 { font-size: 26px; line-height: 1.15; }

.kicker { color: var(--faint); margin: 0 0 18px; }
.sub { color: var(--muted); font-size: 18px; max-width: 54ch; margin: 22px 0 0; }
p { margin: 0; }

/* ───────────────────────── Header ─────────────────────────
   A glass layer the page scrolls under. At the top there is nothing under it, so it is
   just the page; once the page moves it gains the material and a soft edge. */

.bar {
  position: sticky; top: 0; z-index: 50;
  transition: background-color .25s, box-shadow .25s, backdrop-filter .25s, -webkit-backdrop-filter .25s;
}
.bar[data-scrolled="true"] {
  background: rgba(18, 16, 14, 0.72);
  -webkit-backdrop-filter: saturate(160%) blur(20px);
  backdrop-filter: saturate(160%) blur(20px);
  box-shadow: 0 1px 0 rgba(242, 237, 228, 0.05);
}
.bar[data-scrolled="true"] .top { padding-top: 14px; padding-bottom: 14px; }
.top { transition: padding .3s var(--spring); }

.top {
  max-width: var(--max);
  margin: 0 auto;
  padding: 22px var(--gutter);
  display: flex; align-items: center; justify-content: space-between; gap: 24px;
}
.brand { display: inline-flex; align-items: center; gap: 12px; color: var(--bone); font: 400 24px/1 var(--serif); }
.brand img { border-radius: 8px; }
.top nav { display: flex; align-items: center; gap: 28px; }
.top nav a { color: var(--muted); }
.top nav a:hover { color: var(--bone); }
.pill-link { padding: 12px 18px; border: 1px solid var(--rule); border-radius: 999px; color: var(--bone) !important; }
.pill-link:hover { border-color: var(--brass-dim); }
@media (max-width: 720px) { .top nav > a:not(.pill-link) { display: none; } }

/* The language menu: a globe, the code, and two real links underneath. */
.lang { position: relative; }
.lang-button {
  display: inline-flex; align-items: center; gap: 8px;
  height: 40px; padding: 0 6px; border: 0; background: none; cursor: pointer;
  color: var(--muted); font: 500 11px/1 var(--sans); letter-spacing: 0.18em; text-transform: uppercase;
}
.lang-button:hover { color: var(--bone); }
.lang-button svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.lang-button .chev { width: 12px; height: 12px; transition: transform .2s; }
.lang.open .chev { transform: rotate(180deg); }
.lang-menu {
  position: absolute; right: 0; top: calc(100% + 8px); z-index: 10;
  min-width: 160px; margin: 0; padding: 6px; list-style: none;
  background: var(--surface-hi); border: 1px solid var(--rule); border-radius: 16px;
  box-shadow: 0 20px 40px rgba(0, 0, 0, 0.45);
  transform-origin: top right;
  opacity: 0; transform: scale(0.92); filter: blur(4px); pointer-events: none;
  transition: opacity .18s var(--ease-out), transform .4s var(--spring), filter .25s var(--ease-out);
}
.lang.open .lang-menu { opacity: 1; transform: none; filter: none; pointer-events: auto; }
.lang-menu a {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  padding: 10px 12px; border-radius: 10px; color: var(--dimmed);
  font: 400 15px/1 var(--sans); letter-spacing: 0; text-transform: none;
}
.lang-menu a:hover { background: var(--surface); color: var(--bone); }
.lang-menu a[aria-current="true"] { color: var(--bone); }
.lang-menu a[aria-current="true"]::after { content: "✓"; color: var(--brass); }

/* The offer of the reader's own language, above everything, easy to wave away. */
.suggest {
  max-width: var(--max); margin: 0 auto 8px; padding: 14px var(--gutter);
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px 24px;
  color: var(--dimmed);
}
.suggest[hidden] { display: none; }
.suggest-actions { display: flex; gap: 8px; }
.btn.small { height: 40px; padding: 0 18px; font-size: 11px; }

/* ───────────────────────── Buttons ───────────────────────── */

.btn {
  display: inline-flex; align-items: center; justify-content: center;
  height: 56px; padding: 0 28px; border-radius: 28px;
  background: var(--brass); color: var(--ink);
  font: 500 12px/1 var(--sans); letter-spacing: 0.16em; text-transform: uppercase;
  transition: background .2s, transform 100ms ease-out;
  -webkit-tap-highlight-color: transparent;
}
.btn:hover { background: var(--brass-hi); color: var(--ink); }
.btn:active, .pill-link:active, .store:not(.soon):active, .lang-button:active { transform: scale(0.97); }
.pill-link, .lang-button { transition: transform 100ms ease-out, border-color .2s, color .2s; -webkit-tap-highlight-color: transparent; }
.btn.ghost { background: transparent; color: var(--brass); box-shadow: inset 0 0 0 1px var(--brass-dim); }
.btn.ghost:hover { background: rgba(192, 155, 105, 0.08); color: var(--brass-hi); }
.btn.soon { color: var(--faint); box-shadow: inset 0 0 0 1px var(--rule); cursor: default; }
.btn.soon:hover { background: transparent; color: var(--faint); }
/* What is not out yet is said, not drawn as a button that does nothing. */
.soon-note {
  display: inline-flex; align-items: center; height: 56px; padding: 0 6px;
  color: var(--faint); font: 500 12px/1 var(--sans); letter-spacing: 0.16em; text-transform: uppercase;
}

/* ───────────────────────── Hero ───────────────────────── */

.hero {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 44px;
  padding-top: clamp(24px, 5vw, 64px);
  padding-bottom: clamp(56px, 8vw, 120px);
}
@media (min-width: 900px) {
  .hero { grid-template-columns: minmax(0, 11fr) minmax(0, 10fr); align-items: center; gap: 56px; min-height: min(calc(100vh - 100px), 820px); }
}
.hero-copy .kicker { margin-bottom: 26px; }
.hero .ground { --pad: clamp(24px, 4vw, 44px); }
.lede { color: var(--muted); font-size: clamp(18px, 1.6vw, 21px); line-height: 1.55; max-width: 44ch; margin-top: 28px; }
.ctas { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 40px; }
.stage-note { color: var(--faint); text-align: center; margin-top: 18px; transition: opacity .3s; }
.stage-note.swap { opacity: 0; }

/* What there is not, said once, quietly, under the ask. */
.promises { display: flex; flex-wrap: wrap; gap: 8px 22px; margin: 26px 0 0; padding: 0; list-style: none; color: var(--faint); font-size: 15px; }
.promises li { display: inline-flex; align-items: center; gap: 8px; }
.promises li::before { content: ""; width: 5px; height: 5px; border-radius: 50%; background: var(--brass-dim); }

/* The ground a widget sits on: the warm grey wallpaper of the artboards, with a little
   light falling on it from the top left. It is a container, so the widget inside can
   size itself to the room there is. */
.ground {
  --pad: 22px;
  container-type: inline-size;
  border-radius: 36px;
  padding: var(--pad);
  background: radial-gradient(120% 95% at 28% 18%, #4A4139 0%, var(--wall) 46%, #2C2723 100%);
  display: grid; place-items: center;
  box-shadow: inset 0 0 0 1px rgba(242, 237, 228, 0.04);
}
.ground > .wg {
  /* cqw is the ground's content box, so the padding is already out of it. */
  --u: clamp(0.62px, calc(100cqw / var(--fit)), var(--max-s, 1.2px));
  font-size: var(--u);
}

/* ───────────────────────── Widgets, live ─────────────────────────
   Every dimension inside a widget is in em with 1em = 1px at scale one, so the whole
   thing is one font-size away from any size the page needs. */

.wg {
  --u: 1px;                 /* one widget pixel; em is the same thing on anything that keeps the widget's font-size */
  position: relative;
  font-family: var(--sans);
  background: var(--ink);
  border: 1em solid #2A241E;
  border-radius: 26em;
  color: var(--bone);
  user-select: none;
  -webkit-user-select: none;
}
.wg .lab { font-size: 9em; letter-spacing: 0.18em; }
.wg .ring {
  flex: 0 0 auto;
  width: 26em; height: 26em; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: inset 0 0 0 1.5em var(--ring-idle);
  transition: background .25s, box-shadow .25s, transform 100ms ease-out;
}
.wg .ring svg { width: 14em; height: 14em; fill: none; stroke: var(--ink); stroke-width: 3; stroke-linecap: round; stroke-linejoin: round; }
.wg .ring svg path { stroke-dasharray: 24; stroke-dashoffset: 24; transition: stroke-dashoffset .28s ease-out .08s; }
.wg .row.kept .ring { background: var(--a); box-shadow: inset 0 0 0 1.5em var(--a); animation: pop .5s cubic-bezier(.34, 1.56, .64, 1); }
.wg .row.kept .ring svg path { stroke-dashoffset: 0; }
@keyframes pop { 0% { transform: scale(0.82); } 100% { transform: scale(1); } }

/* Every widget on the page can be touched: the loop hands over at the first press. */
.wg .row, .wg-toggle, .wg-cal .grid i:not(.f) { cursor: pointer; -webkit-tap-highlight-color: transparent; }
.wg .row:active .ring { transform: scale(0.88); }
.wg-toggle:active { transform: scale(0.97); }
.wg.wg-toggle, .wg.wg-group.small { transition: background .45s ease, transform 100ms ease-out; }
.wg-cal .grid i:not(.f):active { transform: scale(0.88); }
.wg-cal .grid i:not(.f) { transition: background .3s, color .3s, transform 100ms ease-out; }
.wg .row:focus-visible, .wg-cal .grid i:focus-visible { outline: 2em solid var(--bone); outline-offset: 2em; }

/* The finger: a soft disc that lands on whatever is about to be tapped. */
.finger {
  position: absolute; left: 0; top: 0;
  width: 38em; height: 38em; border-radius: 50%;
  margin: -19em 0 0 -19em;
  background: rgba(242, 237, 228, 0.26);
  box-shadow: 0 0 0 1em rgba(242, 237, 228, 0.28), 0 6em 18em rgba(0, 0, 0, 0.35);
  opacity: 0; transform: scale(1.25);
  transition: opacity .2s, transform .2s;
  pointer-events: none;
}
.finger.show { opacity: 1; transform: scale(1); }
.finger.press { transform: scale(0.84); background: rgba(242, 237, 228, 0.36); }

/* Hoy */
.wg-today { width: 344em; padding: 16em 18em 14em; }
.wg-head { display: flex; align-items: baseline; justify-content: space-between; }
.wg-head .date { color: var(--muted); }
.tally { font: 400 16em/1 var(--serif); color: var(--brass); display: inline-block; }
.tally.bump { animation: bump .4s cubic-bezier(.34, 1.56, .64, 1); }
@keyframes bump { 0% { transform: translateY(0.35em); opacity: .4; } 100% { transform: translateY(0); opacity: 1; } }
.wg-today .rows { display: flex; flex-direction: column; margin-top: 8em; }
.wg-today .row { display: flex; align-items: center; gap: 10em; height: 44em; }
.wg-today .txt { display: flex; flex-direction: column; gap: 4em; min-width: 0; flex: 1 1 auto; }
.wg .name { font: 400 15em/1.15 var(--serif); color: #BDB4A8; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: color .25s; }
.wg .row.kept .name { color: var(--bone); }
.meta { display: flex; align-items: center; gap: 7em; }
.week { display: inline-flex; gap: 2.5em; }
.week i { width: 7em; height: 7em; border-radius: 2em; background: var(--empty); transition: background .3s; }
.week i[data-l="1"] { background: var(--r1); }
.week i[data-l="2"] { background: var(--r2); }
.week i[data-l="3"] { background: var(--r3); }
.week i[data-l="4"] { background: var(--a); }
.wg .streak { color: var(--a-dim); }
.wg .streak.none { color: var(--ring-idle); }
.wg.dawn .rows { opacity: 0.35; transition: opacity .35s; }
.wg .rows { transition: opacity .5s; }

/* Un hábito */
.wg-toggle {
  width: 150em; height: 150em; padding: 10em;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8em;
  transition: background .45s ease;
}
.wg-toggle .dial { position: relative; width: 62em; height: 62em; display: inline-flex; align-items: center; justify-content: center; }
.wg-toggle .dial > svg:first-child { position: absolute; inset: 0; width: 100%; height: 100%; }
.wg-toggle .track { fill: none; stroke: var(--ring-idle); stroke-width: 5; transition: stroke .45s; }
.wg-toggle .arc {
  fill: none; stroke: var(--a); stroke-width: 5; stroke-linecap: round;
  stroke-dasharray: 179.07; stroke-dashoffset: 179.07;
  transition: stroke-dashoffset .55s cubic-bezier(.2, .7, .2, 1), stroke .45s;
}
.wg-toggle .check { width: 25em; height: 25em; fill: none; stroke: var(--ink); stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round; opacity: 0; transform: scale(.6); transition: opacity .3s, transform .4s cubic-bezier(.34, 1.56, .64, 1); position: relative; }
.wg-toggle .nm { font: 400 13em/1.25 var(--sans); color: #BDB4A8; text-align: center; transition: color .45s; }
.wg-toggle.sweep .arc { stroke-dashoffset: 0; }
.wg-toggle.done { background: var(--a); }
.wg-toggle.done .track { stroke: rgba(18, 16, 14, 0.28); }
.wg-toggle.done .arc { stroke: var(--ink); }
.wg-toggle.done .check { opacity: 1; transform: scale(1); }
.wg-toggle.done .nm { color: var(--ink); }
.wg-toggle.reset, .wg-toggle.reset * { transition: none !important; }

/* Calendario: the wall calendar both apps draw. A row per weekday and a column per week,
   newest on the right, the month written over the column it opens in, the weekdays down
   the right-hand side, and the streak beside the name with a twin nobody sees on the
   other side to keep the name over the middle. The days arrive in date order and the
   grid lays them down a column at a time, so each column is a week. */
.wg-cal { width: 227em; height: 216em; padding: 10em 12em; border-radius: 24em; display: flex; flex-direction: column; }
.cal-head { display: flex; align-items: center; height: 26em; gap: 6em; }
.cal-head .nm { flex: 1 1 auto; min-width: 0; text-align: center; font-family: var(--serif); font-size: calc(15 * var(--u)); line-height: calc(19 * var(--u)); color: var(--bone); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.cal-streak { flex: 0 0 auto; font: 500 calc(9 * var(--u))/1 var(--sans); letter-spacing: 0.16em; text-transform: uppercase; color: var(--a-dim); white-space: nowrap; }
.cal-streak.twin { visibility: hidden; }
.streak-n { font: inherit; color: inherit; }
.cal-months { position: relative; height: 13em; }
.cal-months span { position: absolute; left: calc(var(--col) * 25.3 * var(--u)); bottom: calc(2 * var(--u)); font: 500 calc(9 * var(--u))/1 var(--sans); letter-spacing: 0.16em; text-transform: uppercase; color: var(--faint); white-space: nowrap; }
.cal-body { display: flex; }
.dh { display: flex; flex-direction: column; width: 26em; }
.dh i { height: calc(22.4 * var(--u)); display: flex; align-items: center; justify-content: center; font-family: var(--sans); font-weight: 500; font-style: normal; font-size: calc(9 * var(--u)); letter-spacing: 0.1em; text-transform: uppercase; color: var(--faint); }
.wg-cal .grid { display: grid; grid-auto-flow: column; grid-template-rows: repeat(7, 22.4em); grid-auto-columns: 25.3em; }
.wg-cal .grid i {
  place-self: center;
  width: calc(19.4 * var(--u)); height: calc(19.4 * var(--u)); border-radius: calc(5.2 * var(--u));
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--sans); font-style: normal; font-size: calc(8.2 * var(--u)); line-height: 1;
  background: var(--empty); color: var(--faint);
  transition: background .3s, color .3s;
}
.wg-cal .grid .k { background: var(--a); color: var(--ink); }
.wg-cal .grid .h { background: var(--a-dim); color: var(--ink); }
.wg-cal .grid .f { background: var(--future); color: #332E28; }
.wg-cal .grid .today { font-weight: 700; box-shadow: inset 0 0 0 calc(1.5 * var(--u)) var(--bone); }
.wg-cal .grid .today.kept { background: var(--a); color: var(--ink); }
.wg-cal .grid .today.pop { animation: pop .5s cubic-bezier(.34, 1.56, .64, 1); }

/* Grupo */
.wg-group { width: 344em; height: 160em; padding: 12em 14em; display: flex; align-items: center; gap: 10em; }
.dial-col { width: 78em; flex: 0 0 auto; display: flex; flex-direction: column; align-items: center; gap: 8em; }
.gdial { position: relative; width: 64em; height: 64em; display: inline-flex; align-items: center; justify-content: center; }
.gdial > svg:first-child { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); }
.piece {
  fill: none; stroke: var(--ring-idle); stroke-width: 5.5; stroke-linecap: butt;
  /* Circumference 175.93, four pieces with a gap of 6 between them. */
  stroke-dasharray: 37.98 137.95;
  stroke-dashoffset: calc(var(--i) * -43.98);
  transition: stroke .35s;
}
.piece.kept { stroke: var(--a); }
.gdial .count { position: relative; font: 400 15em/1 var(--serif); color: var(--bone); transition: opacity .2s; }
.gdial .check { position: absolute; width: 27em; height: 27em; fill: none; stroke: var(--a); stroke-width: 2.6; stroke-linecap: round; stroke-linejoin: round; opacity: 0; transform: scale(.6); transition: opacity .3s, transform .4s cubic-bezier(.34, 1.56, .64, 1); }
.wg-group.done .count { opacity: 0; }
.wg-group.done .check { opacity: 1; transform: scale(1); }
.gname { font: 400 12em/1.2 var(--sans); color: #BDB4A8; text-align: center; transition: color .3s; }
.wg-group.done .gname { color: var(--bone); }
.wg-group .rows { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.wg-group .row { display: flex; align-items: center; gap: 10em; height: 34em; }
.wg-group .ring { width: 22em; height: 22em; }
.wg-group .ring svg { width: 12em; height: 12em; }
.wg-group .name { font-size: 14em; flex: 1 1 auto; }

/* ───────────────────────── Sections ───────────────────────── */

.sec { padding-top: clamp(72px, 9vw, 130px); padding-bottom: clamp(72px, 9vw, 130px); border-top: 1px solid var(--hairline); }

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 28px;
  margin-top: 56px;
}
.plate { margin: 0; display: flex; flex-direction: column; gap: 18px; }
.plate .ground { min-height: 300px; }   /* the same height for all three, so the captions line up */
.plate figcaption .lab { color: var(--faint); display: block; margin-bottom: 8px; }
.plate figcaption p { color: var(--muted); font-size: 16px; }
/* Each plate gets room in proportion to the widget it holds — the group is the wide
   one — and the whole row when there are only two columns. */
@media (min-width: 640px) {
  .plate.wide { grid-column: 1 / -1; }
}
@media (min-width: 1000px) {
  .gallery { grid-template-columns: 1fr 1.4fr 2fr; }
  .plate.wide { grid-column: auto; }
}

.split { display: grid; grid-template-columns: minmax(0, 1fr); gap: 44px; align-items: center; }
@media (min-width: 880px) { .split { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 72px; } }
.split-copy > p:not(.kicker) { color: var(--muted); font-size: 18px; margin-top: 22px; max-width: 48ch; }
.split-copy h3 { font-size: clamp(28px, 3.2vw, 40px); }
.iphone-real { margin-top: clamp(72px, 9vw, 120px); }

/* ───────────────────────── The iPhone ─────────────────────────
   A phone drawn to the point: 393 × 852 of screen, in --p units, with the widgets on a
   tinted home screen the way iOS lays them out — one medium, two small. */

.phone-stage { container-type: inline-size; position: relative; display: grid; place-items: center; padding: 24px 0; }
.phone-stage::before {
  content: ""; position: absolute; inset: 10% 5%;
  background: radial-gradient(50% 50% at 50% 45%, rgba(116, 168, 188, 0.35), transparent 70%);
  filter: blur(30px); pointer-events: none;
}
.phone {
  --p: clamp(0.5px, calc(100cqw / 440), 0.9px);
  position: relative;
  width: calc(417 * var(--p)); height: calc(876 * var(--p));
  padding: calc(12 * var(--p));
  border-radius: calc(64 * var(--p));
  background: linear-gradient(150deg, #3a3a3e, #131315 45%, #232326);
  box-shadow: 0 0 0 1px rgba(255, 255, 255, 0.09) inset, 0 0 0 2px #0a0a0b, 0 40px 90px -30px rgba(0, 0, 0, 0.8);
  font-family: -apple-system, "SF Pro Text", var(--sans);
}
.phone::before, .phone::after {
  content: ""; position: absolute; background: #2a2a2e; border-radius: 2px;
}
.phone::before { left: calc(-3 * var(--p)); top: calc(170 * var(--p)); width: calc(3 * var(--p)); height: calc(60 * var(--p)); box-shadow: 0 calc(80 * var(--p)) 0 #2a2a2e; }
.phone::after { right: calc(-3 * var(--p)); top: calc(210 * var(--p)); width: calc(3 * var(--p)); height: calc(90 * var(--p)); }
.screen {
  position: relative; height: 100%; overflow: hidden;
  border-radius: calc(52 * var(--p));
  background:
    radial-gradient(55% 40% at 18% 12%, #b9e3da 0%, transparent 65%),
    radial-gradient(45% 35% at 88% 28%, #6f9bd8 0%, transparent 62%),
    radial-gradient(60% 45% at 50% 95%, #d7e9e2 0%, transparent 70%),
    linear-gradient(165deg, #e6eff2 0%, #a3c9dd 45%, #7bb0d4 100%);
  color: #fff;
  isolation: isolate;
}
.status {
  position: relative; height: calc(54 * var(--p)); display: flex; align-items: center; justify-content: space-between;
  padding: 0 calc(34 * var(--p)) 0 calc(42 * var(--p));
  font-size: calc(16 * var(--p)); font-weight: 600; color: #111;
}
.island { position: absolute; left: 50%; top: calc(11 * var(--p)); width: calc(126 * var(--p)); height: calc(37 * var(--p)); margin-left: calc(-63 * var(--p)); border-radius: 999px; background: #000; }
.glyphs { display: inline-flex; align-items: center; gap: calc(6 * var(--p)); }
.glyphs i { display: block; background: #111; }
.glyphs .sig { width: calc(18 * var(--p)); height: calc(11 * var(--p)); clip-path: polygon(0 70%, 25% 70%, 25% 100%, 0 100%, 30% 100%, 30% 45%, 50% 45%, 50% 100%, 55% 100%, 55% 20%, 75% 20%, 75% 100%, 80% 100%, 80% 0, 100% 0, 100% 100%, 0 100%); }
.glyphs .wifi { width: calc(16 * var(--p)); height: calc(11 * var(--p)); border-radius: 50% 50% 0 0; clip-path: polygon(0 40%, 50% 100%, 100% 40%, 100% 0, 0 0); }
.glyphs .bat { width: calc(26 * var(--p)); height: calc(12 * var(--p)); border-radius: calc(3 * var(--p)); background: linear-gradient(90deg, #111 78%, rgba(17, 17, 17, 0.3) 78%); }
.home { padding: calc(14 * var(--p)) calc(27 * var(--p)) 0; display: flex; flex-direction: column; align-items: center; }
.phone .wg { --u: var(--p); font-size: var(--p); border: 0; box-shadow: 0 8em 24em rgba(0, 0, 0, 0.18); }
.phone .wg-today { width: 338em; height: 158em; padding: 14em 16em 10em; }
.phone .wg-today .rows { margin-top: 6em; }
.phone .wg-today .row { height: 38em; }
.wlabel { display: block; margin-top: calc(6 * var(--p)); font-size: calc(12 * var(--p)); font-weight: 500; color: #fff; text-shadow: 0 1px 6px rgba(0, 0, 0, 0.35); }
.pair { display: flex; gap: 22em; margin-top: calc(22 * var(--p)); font-size: var(--p); }
.pair-labels { display: flex; width: calc(338 * var(--p)); }
.pair-labels .wlabel { flex: 1 1 0; text-align: center; }
.phone .wg-toggle { width: 158em; height: 158em; }
.wg-group.small { width: 158em; height: 158em; padding: 12em; flex-direction: column; justify-content: center; gap: 8em; }
.wg-group.small .gdial { width: 78em; height: 78em; }
.wg-group.small .gdial .count { font-size: 18em; }
.wg-group.small .gdial .check { width: 32em; height: 32em; }
.wg-group.small .gname { font-size: 13em; }
.icons { display: flex; justify-content: space-between; width: calc(338 * var(--p)); margin-top: calc(26 * var(--p)); }
.app { display: flex; flex-direction: column; align-items: center; gap: calc(6 * var(--p)); width: calc(60 * var(--p)); font-size: calc(12 * var(--p)); font-weight: 500; }
.app img { width: calc(60 * var(--p)); height: calc(60 * var(--p)); border-radius: calc(14 * var(--p)); box-shadow: 0 4px 14px rgba(0, 0, 0, 0.2); }
.app b { font-weight: 500; text-shadow: 0 1px 6px rgba(0, 0, 0, 0.35); }
.app.glass { height: calc(60 * var(--p)); border-radius: calc(14 * var(--p)); background: rgba(255, 255, 255, 0.45); box-shadow: inset 0 0 0 1px rgba(255, 255, 255, 0.5), 0 4px 14px rgba(0, 0, 0, 0.12); backdrop-filter: blur(10px); }
.dots { display: flex; gap: calc(8 * var(--p)); margin-top: calc(28 * var(--p)); }
.dots i { width: calc(7 * var(--p)); height: calc(7 * var(--p)); border-radius: 50%; background: rgba(0, 0, 0, 0.25); }
.dots i.on { background: rgba(0, 0, 0, 0.6); }
.dock {
  position: absolute; left: calc(16 * var(--p)); right: calc(16 * var(--p)); bottom: calc(14 * var(--p));
  height: calc(92 * var(--p)); border-radius: calc(32 * var(--p));
  background: rgba(255, 255, 255, 0.35); backdrop-filter: blur(20px);
  display: flex; align-items: center; justify-content: space-evenly;
}
.dock .app.glass { background: rgba(255, 255, 255, 0.55); }

.phones {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(240px, 1fr);
  gap: 24px;
  margin: 56px calc(-1 * var(--gutter)) 0;
  padding: 0 var(--gutter) 8px;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;
}
.phones::-webkit-scrollbar { display: none; }
.phones figure { margin: 0; scroll-snap-align: start; display: flex; flex-direction: column; gap: 16px; }
.phones img { border-radius: 34px; border: 1px solid var(--rule); background: var(--surface); }
.phones figcaption { color: var(--faint); }

.points { margin: 40px 0 0; display: flex; flex-direction: column; gap: 26px; }
.points div { padding-top: 22px; border-top: 1px solid var(--hairline); }
.points dt { font: 400 24px/1.2 var(--serif); color: var(--bone); }
.points dd { margin: 8px 0 0; color: var(--muted); max-width: 46ch; }

.weeks-card { background: var(--surface); border: 1px solid var(--hairline); border-radius: 28px; padding: 28px; }
.weeks-head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; color: var(--faint); }
.weeks-n { font: 400 22px/1 var(--serif); color: var(--brass); }
.weeks { display: grid; grid-template-columns: repeat(12, 1fr); gap: 6px; margin-top: 22px; }
.weeks i {
  aspect-ratio: 1; border-radius: 22%;
  display: inline-flex; align-items: center; justify-content: center;
  font: 400 clamp(13px, 1.6vw, 18px)/1 var(--serif); font-style: normal;
  background: var(--empty); color: var(--faint);
  transition: background .4s, color .4s, box-shadow .4s;
  transition-delay: calc(var(--i) * 70ms);
}
.is-in .weeks i { background: var(--brass); color: var(--ink); }
.weeks i.now { background: transparent; color: var(--brass); box-shadow: inset 0 0 0 1.5px var(--rule); }
.is-in .weeks i.now { background: transparent; color: var(--brass); box-shadow: inset 0 0 0 1.5px var(--brass); }
.weeks-note { color: var(--muted); margin-top: 20px; font-size: 16px; }

.ways { display: grid; grid-template-columns: repeat(auto-fit, minmax(230px, 1fr)); gap: 28px; margin-top: 56px; }
.way { padding-top: 24px; border-top: 1px solid var(--hairline); }
.way svg { width: 26px; height: 26px; fill: none; stroke: var(--brass); stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.way h3 { font-size: 24px; margin-top: 18px; }
.way p { color: var(--muted); margin-top: 8px; font-size: 16px; }

/* The one light thing on the page: the printed report, a year of a ritual on bone paper. */
.paper {
  background: #F6F1E7; color: #1C1A17;
  border-radius: 6px; padding: 26px 28px 22px;
  box-shadow: 0 30px 60px rgba(0, 0, 0, 0.45), 0 1px 0 rgba(255, 255, 255, 0.5) inset;
  max-width: 520px; margin: 0 auto;
  transform: rotate(-1.2deg);
  transition: transform 900ms var(--spring);
}
.js .split-vis:not(.is-in) .paper { transform: rotate(-4deg) translateY(14px); }
.js .paper-grid > * { opacity: 0; transition: opacity .25s ease-out calc(var(--c, 0) * 12ms + 200ms); }
.js .is-in .paper-grid > * { opacity: 1; }
.paper-head { display: flex; align-items: baseline; justify-content: space-between; }
.paper-title { font: 400 22px/1 var(--serif); }
.paper-year { font: 500 11px/1 var(--sans); letter-spacing: 0.18em; color: #867B67; }
.paper-grid { display: grid; grid-template-columns: repeat(52, minmax(0, 1fr)); gap: 3px; margin-top: 18px; }
.paper-grid i { display: block; width: 100%; aspect-ratio: 1; border-radius: 1.5px; background: #E6DECD; }
.paper-grid i[data-l="2"] { background: #C9B899; }
.paper-grid i[data-l="3"] { background: #A98E68; }
.paper-grid i[data-l="4"] { background: #7A5F3B; }
.paper-foot { display: flex; gap: 22px; margin-top: 18px; font: 500 10px/1 var(--sans); letter-spacing: 0.16em; text-transform: uppercase; color: #6B6152; }

.center { text-align: center; }
.center h2 { margin-left: auto; margin-right: auto; }
.stores { display: flex; flex-wrap: wrap; justify-content: center; gap: 14px; margin-top: 44px; }
.store {
  display: inline-flex; align-items: center; gap: 12px;
  min-height: 64px; padding: 0 28px 0 20px; border-radius: 32px;
  background: var(--bone); color: var(--ink);
  font: 500 16px/1.2 var(--sans); text-align: left;
  transition: transform 100ms ease-out, background .2s;
  -webkit-tap-highlight-color: transparent;
}
.store:hover { background: #fff; color: var(--ink); }
.store svg { width: 24px; height: 24px; flex: 0 0 auto; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.store[data-store="appStore"] svg { fill: currentColor; stroke: none; }
.store span { display: grid; }
.store small { font: 500 10px/1 var(--sans); letter-spacing: 0.16em; text-transform: uppercase; opacity: 0.6; margin-top: 4px; }
/* Not out yet: the name and the word, with no pill around them to press. */
.store.soon { background: transparent; color: var(--muted); padding: 0 16px; cursor: default; }
.store.soon:hover { background: transparent; color: var(--muted); }

/* ───────────────────────── Questions ───────────────────────── */

/* Ritual+'s four blocks in pairs, so none is left alone on a row of its own. */
#plus .ways { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 640px) { #plus .ways { grid-template-columns: minmax(0, 1fr); } }
.plans { display: grid; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); gap: 16px; margin-top: 56px; }
.plan { display: flex; flex-direction: column; gap: 8px; padding: 22px; border: 1px solid var(--rule); border-radius: 18px; }
.plan.main { border-color: var(--brass-dim); background: var(--surface); }
.plan .lab { color: var(--faint); }
.plan-price { font: 400 44px/1 var(--serif); color: var(--bone); }
.plan.main .plan-price { color: var(--brass); }
.plan-note { color: var(--muted); font-size: 15px; }
.plans-promise { font: italic 400 22px/1.4 var(--serif); color: var(--dimmed); max-width: 52ch; margin: 36px 0 0; }
#plus .hint { margin-top: 20px; }

.faq-split { align-items: start; }
.faq { display: flex; flex-direction: column; }
.faq details { border-top: 1px solid var(--hairline); }
.faq details:last-child { border-bottom: 1px solid var(--hairline); }
.faq summary {
  list-style: none; cursor: pointer;
  display: flex; align-items: center; justify-content: space-between; gap: 20px;
  padding: 22px 0; font: 400 22px/1.25 var(--serif); color: var(--bone);
  -webkit-tap-highlight-color: transparent;
}
.faq summary::-webkit-details-marker { display: none; }
.faq summary::after {
  content: ""; flex: 0 0 auto; width: 10px; height: 10px; margin-right: 4px;
  border-right: 1.5px solid var(--brass); border-bottom: 1.5px solid var(--brass);
  transform: translateY(-3px) rotate(45deg); transition: transform .45s var(--spring);
}
.faq details[open] summary::after { transform: translateY(2px) rotate(225deg); }
.faq details p { color: var(--muted); max-width: 52ch; padding: 0 0 24px; }
.faq details[open] p { animation: faq-in .45s var(--spring); }
@keyframes faq-in { from { opacity: 0; transform: translateY(-6px); } }

/* ───────────────────────── Arriving, leaving ─────────────────────────
   Content settles into place every time it scrolls into view, and is hidden again only
   once it has left the screen entirely, so nothing ever vanishes in front of the reader.
   It remembers the edge it left by: scrolling back up, it comes down from above instead
   of rising from below. Hidden only once the script is known to run. The list is the
   same as REVEAL in site.js. */

.js :is(.hero-copy > *, .hero-stage, .sec .kicker, .sec h2, .sec .sub, .plate, .split-copy, .split-vis, .phone-stage, .phones, .points > div, .way, .faq details, .stores, .foot .wrap > *) {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity 500ms var(--ease-out) var(--d, 0ms), transform var(--spring-t) var(--spring) var(--d, 0ms);
}
.js [data-side="above"] { transform: translateY(-26px) !important; }
.js :is(.hero-copy > *, .hero-stage, .sec .kicker, .sec h2, .sec .sub, .plate, .split-copy, .split-vis, .phone-stage, .phones, .points > div, .way, .faq details, .stores, .foot .wrap > *).is-in {
  opacity: 1;
  transform: none;
}

/* Scrolled past, the hero's widget sinks back instead of being cut off by the edge; the
   renders in the row ease away as they slide off either side. The browser drives both
   from the scroll itself, so they can never lag the finger. */
@supports (animation-timeline: view()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero .ground {
      animation: recede linear both;
      animation-timeline: view();
      animation-range: exit 0% exit 90%;
    }
    @keyframes recede { to { transform: scale(0.92); opacity: 0.35; } }

    .phones figure {
      animation: edge linear both;
      animation-timeline: view(inline);
    }
    @keyframes edge {
      0% { opacity: 0.35; transform: scale(0.9); }
      24%, 76% { opacity: 1; transform: none; }
      100% { opacity: 0.35; transform: scale(0.9); }
    }
  }
}

/* ───────────────────────── The help, privacy and terms pages ─────────────────────────
   Long reading in the page's own type, narrow enough to follow line to line. */

.legal { padding-top: clamp(24px, 5vw, 64px); padding-bottom: clamp(56px, 8vw, 110px); }
.legal article { max-width: 68ch; }
.legal h1 { font-size: clamp(40px, 5.4vw, 68px); line-height: 1.02; }
.legal h2 { font-size: clamp(24px, 2.6vw, 30px); line-height: 1.15; max-width: none; margin: 48px 0 0; }
.legal p, .legal ul, .legal dl { margin: 16px 0 0; color: var(--muted); }
.legal .lede { color: var(--dimmed); margin-top: 28px; }
.legal .updated { color: var(--faint); font-size: 15px; margin-top: 14px; }
.legal ul { padding-left: 1.1em; }
.legal li { margin-top: 10px; }
.legal li::marker { color: var(--brass-dim); }
.legal strong { color: var(--dimmed); font-weight: 500; }
.legal .qa dt { color: var(--bone); font: 400 21px/1.3 var(--serif); margin-top: 26px; }
.legal .qa dd { margin: 8px 0 0; }

/* ───────────────────────── Footer ───────────────────────── */

/* Room under the last line, so it reaches far enough up the screen to settle in. */
.foot { border-top: 1px solid var(--hairline); padding: 56px 0 104px; }
.accents { display: flex; gap: 10px; flex-wrap: wrap; }
.accents i { width: 14px; height: 14px; border-radius: 50%; background: var(--c); }
.foot-line { margin-top: 26px; color: var(--faint); }
.foot-links { display: flex; flex-wrap: wrap; gap: 10px 26px; margin-top: 22px; }
.foot-links a { color: var(--muted); }
.foot-links a:hover { color: var(--bone); }
.brand-word { font: 400 20px/1 var(--serif); color: var(--bone); }

/* ───────────────────────── Motion off ───────────────────────── */

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  .finger { display: none; }
  .js :is(.hero-copy > *, .hero-stage, .sec .kicker, .sec h2, .sec .sub, .plate, .split-copy, .split-vis, .phone-stage, .phones, .points > div, .way, .faq details, .stores, .foot .wrap > *),
  .js [data-side="above"] { opacity: 1; transform: none !important; }
  .js .paper-grid > * { opacity: 1; }
  .js .split-vis:not(.is-in) .paper { transform: rotate(-1.2deg); }
}

/* Glass is a nicety: solid for a reader who asked for less transparency or more contrast. */
@media (prefers-reduced-transparency: reduce) {
  .bar[data-scrolled="true"] { background: var(--ink); -webkit-backdrop-filter: none; backdrop-filter: none; }
}
@media (prefers-contrast: more) {
  .bar[data-scrolled="true"] { background: var(--ink); box-shadow: 0 1px 0 var(--rule); }
}

#plus .way.wide { grid-column: 1 / -1; }
