/* Fonts are bundled (offline, no third-party requests): @fontsource-variable, see tools/vendor.mjs. */
@font-face { font-family: Fraunces; font-style: normal; font-display: swap; font-weight: 100 900; src: url(fonts/fraunces-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: Fraunces; font-style: normal; font-display: swap; font-weight: 100 900; src: url(fonts/fraunces-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: Inter; font-style: normal; font-display: swap; font-weight: 100 900; src: url(fonts/inter-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: Inter; font-style: normal; font-display: swap; font-weight: 100 900; src: url(fonts/inter-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 {
  --bg: #f6f2ea; --card: #fffdf8; --ink: #1d2a26; --muted: #56625d; --line: #e4ddd0; --lock-ink: #8a4f2a; --danger: #9b3b2a; --h1: #dae8e0; --h2: #b3cfbe; --h3: #cdaa6b; --h4: #ce834e; --h5: #a14c36; /* one ordinal ramp for the check-in swatches, the strip and the calendar: pale sage to clay, 1.3:1 or more a step, ink on 1-4 and paper on Crushing (4.8:1) */
  --pine: #1f3a33; --sage: #7d9b8a; --sage-soft: #dfe8e1; --dawn: #e9b38c; --dawn-soft: #f7e3d3;
  --radius: 20px; --shadow: 0 1px 2px rgba(31,58,51,.06), 0 8px 24px rgba(31,58,51,.06);
  --ease: cubic-bezier(.2,.7,.2,1);
  /* Art tokens (illustrations only): the shade side darker than the lit side in both themes. */
  --art-dark: #1f3a33; --art-mid: #7d9b8a; --art-light: #dfe8e1; --art-soft: #dfe8e1; --art-ground: #f7e3d3; --art-path: #f7e3d3; --art-sun: #e9b38c; --art-paper: #fffdf8; --art-line: #e4ddd0;
  --art-glow: rgba(233,179,140,.16); --art-hi: rgba(255,253,248,.5); --art-shade: rgba(214,150,108,.35); --art-soil: #e3c6aa; /* Wave 5: the sun's glow, the lit side and the shade side of the ground */
}
@media (prefers-color-scheme: dark) {
  :root { --bg: #121a17; --card: #1a2420; --ink: #ece7dd; --muted: #9aa69f; --line: #2a3631;
    --pine: #a9cbb8; --sage: #8fb09d; --sage-soft: #24332c; --dawn: #e9b38c; --dawn-soft: #42312a; --lock-ink: #f0c3a1; --danger: #f0a090; --h1: #33493d; --h2: #497058; --h3: #a3864c; --h4: #dc9459; --h5: #b44e34; /* dark: the ramp rises to a deeper clay, 1.3:1 or more a step (Light to A bit heavy 1.7:1); paper-coloured text on 1-3, dark ink on 4-5 (Crushing 4.7:1) */
    --art-dark: #2f5146; --art-mid: #7d9b8a; --art-light: #a9c4b4; --art-soft: #243a31; --art-ground: rgba(233,179,140,.22); --art-path: #4d3d33; --art-sun: #e9b38c; --art-paper: #ece7dd; --art-line: #3a4a42;
    --art-glow: rgba(169,203,184,.07); --art-hi: rgba(236,231,221,.07); --art-shade: rgba(0,0,0,.2); --art-soil: rgba(233,179,140,.22);
    /* Warm surfaces on the dark card: a dim amber glow, never the brown that mixing --dawn into green gives. */
    --warm-surface: #211f1b; --warm-surface-strong: #24211c; --warm-glow: rgba(242,168,98,.12); --warm-ink: #f3c9a3; }
}
* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; } /* tappables have their own press state */
[hidden] { display: none !important; } /* display rules must not override hidden */
html, body { margin: 0; background: var(--bg); color: var(--ink); font: 16px/1.55 Inter, system-ui, sans-serif; -webkit-font-smoothing: antialiased; }
/* Motion: a screen rises in (8 px, 320 ms), a tab fades in (180 ms); tappables press down; saves draw a check. */
main { max-width: 560px; margin: 0 auto; padding: calc(24px + env(safe-area-inset-top, 0px)) 16px calc(132px + env(safe-area-inset-bottom)); outline: none; animation: rise .32s var(--ease); } main[data-motion="tab"] { animation: fadeIn .18s ease; }
@keyframes rise { from { opacity: 0; transform: translateY(8px); } }
@keyframes grow { from { opacity: 0; transform: scale(.72) translateY(6px); } 60% { transform: scale(1.05); } to { opacity: 1; transform: none; } }
@keyframes tick { from { stroke-dashoffset: 26; } to { stroke-dashoffset: 0; } }
@keyframes flicker { 0%, 100% { transform: scale(1); opacity: 1; } 40% { transform: scale(1.04, .97) translateY(.5px); opacity: .92; } 70% { transform: scale(.98, 1.03); } }
@keyframes tabPulse { 0%, 100% { box-shadow: 0 6px 20px rgba(233,179,140,.5); } 50% { box-shadow: 0 6px 26px rgba(233,179,140,.9), 0 0 0 8px rgba(233,179,140,.28); } }
@keyframes glow { 0%, 100% { box-shadow: 0 0 70px rgba(233,179,140,.5); } 50% { box-shadow: 0 0 130px rgba(233,179,140,.9), 0 0 0 10px rgba(233,179,140,.18); } }
h1, h2, h3 { font-family: Fraunces, Georgia, serif; font-weight: 600; line-height: 1.2; margin: 0 0 8px; letter-spacing: -.01em; }
h1 { font-size: 30px; } h2 { font-size: 22px; } h3 { font-size: 18px; }
p { margin: 0 0 12px; } .muted { color: var(--muted); } .small { font-size: 14px; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px; margin: 14px 0; box-shadow: var(--shadow); }
.card.soft { background: var(--sage-soft); border-color: transparent; box-shadow: none; }
.card.dawn { background: var(--dawn-soft); border-color: transparent; box-shadow: none; }
.card.soft .ghost, .card.dawn .ghost { background: var(--card); } /* ghost edges vanish on tinted cards */
.row { display: flex; gap: 10px; align-items: center; } .between { justify-content: space-between; } .wrap { flex-wrap: wrap; }
.row > button, .row > .btn { flex: none; white-space: nowrap; } /* a pill beside text never wraps into a circle */
.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; } .grid2 > button, .grid2 > .btn { padding-left: 10px; padding-right: 10px; }
button, .btn { font: inherit; font-weight: 600; border: 0; border-radius: 999px; padding: 13px 20px; background: var(--pine); color: var(--bg); cursor: pointer; text-decoration: none; display: inline-flex; align-items: center; justify-content: center; text-align: center; gap: 8px; min-height: 48px; transition: transform .12s ease, opacity .2s; }
:is(button, .btn, .tile, .chip, .lesson, .row-link, a.card, .stat, .strip, .feel):active { transform: scale(.97); } .row-link, .lesson, .strip, a.card { transition: transform .15s ease; }
button.ghost, .btn.ghost { background: transparent; color: var(--pine); border: 1.5px solid var(--line); }
@media (prefers-color-scheme: dark) { button.ghost, .btn.ghost { border-color: color-mix(in srgb, var(--pine) 45%, transparent); } }
button.block, .btn.block { width: 100%; }
button:disabled { opacity: .45; }
button.danger { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, var(--line)); }
.tile { display: block; text-decoration: none; color: inherit; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); padding: 16px; min-height: 104px; box-shadow: var(--shadow); transition: transform .15s ease, box-shadow .15s ease; }
.tile b { display: block; font-family: Fraunces, serif; font-size: 17px; margin-bottom: 4px; }
.tile.wide { display: flex; align-items: center; gap: 12px; min-height: 0; } .tile.wide > span:not(.ic-badge):not(.row-art) { flex: 1; min-width: 0; } .tile.wide b { margin: 2px 0 0; } .tile.wide .ic-badge { margin: 0; }
.tile:active, a.card:active, .stat:active { box-shadow: none; }
input, textarea, select { font: inherit; width: 100%; padding: 13px 14px; border-radius: 14px; border: 1.5px solid var(--line); background: var(--card); color: var(--ink); }
textarea { min-height: 160px; resize: vertical; }
/* Keep: one row of three ways to start writing. */
.create3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; } .tile.mini { min-height: 0; padding: 14px 8px 12px; text-align: center; } .tile.mini .ic-badge { margin: 0 auto 8px; } .tile.mini b { font: 600 16px/1.3 Inter, system-ui, sans-serif; margin: 0; } /* the same label as the Prompts and Hard dates links beside them */
/* A kept letter or entry reads back on its paper. */
.paper-page { margin-top: 14px; padding: 18px 20px 14px; border-radius: 18px; background: var(--card) repeating-linear-gradient(transparent 0 31px, color-mix(in srgb, var(--line) 80%, transparent) 31px 32px); background-position: 0 18px; box-shadow: var(--shadow); font-family: Fraunces, Georgia, serif; font-size: 18px; line-height: 32px; }
.paper-page p { margin: 0 0 32px; } .paper-page .text { white-space: pre-wrap; } .paper-page .salutation { font-weight: 600; } .paper-page .signoff { text-align: right; color: var(--muted); font-size: 15px; margin: 0; } .paper-page .prompt { font-family: Inter, system-ui, sans-serif; line-height: 1.5; margin-bottom: 16px; }
.kept-moment { display: flex; align-items: center; gap: 10px; margin: 14px 0 0; padding: 12px 14px; border-radius: 14px; background: var(--sage-soft); color: var(--pine); font-weight: 500; animation: rise .5s var(--ease) both; } .kept-moment .tick { width: 20px; height: 20px; stroke-width: 2.4; stroke-dasharray: 26; animation: tick .4s ease-out .2s both; }
/* The letter and journal page: serif, ruled like paper, filling the screen above the keyboard. */
textarea.paper { font-family: Fraunces, Georgia, serif; font-size: 18px; line-height: 32px; min-height: 46vh; padding: 14px 18px; border-radius: 18px; box-shadow: var(--shadow);
  background: var(--card) repeating-linear-gradient(transparent 0 31px, color-mix(in srgb, var(--line) 80%, transparent) 31px 32px); background-attachment: local; background-position: 0 14px; }
label, .label { display: block; font-weight: 500; margin: 14px 0 6px; }
label.toggle { display: flex; justify-content: space-between; align-items: center; gap: 12px; min-height: 48px; margin: 6px 0; }
/* Toggles announce like Android switches. */
input.switch { appearance: none; width: 52px; height: 32px; padding: 0; flex: none; border-radius: 999px; border: 0; background: var(--line); position: relative; cursor: pointer; transition: background .2s; }
input.switch::before { content: ''; position: absolute; top: 4px; left: 4px; width: 24px; height: 24px; border-radius: 50%; background: var(--card); box-shadow: 0 1px 3px rgba(0,0,0,.25); transition: transform .2s; }
input.switch:not(:checked) { box-shadow: inset 0 0 0 1.5px var(--muted); } input.switch:not(:checked)::before { background: var(--muted); box-shadow: none; } /* off still reads: a muted ring and knob, 3:1+ on the card in both themes (WCAG 1.4.11) */
input.switch:checked::before { transform: translateX(20px); }
.chips { display: flex; flex-wrap: wrap; gap: 8px; }
.chip { padding: 9px 14px; min-height: 48px; border-radius: 999px; background: var(--card); border: 1.5px solid var(--line); color: var(--ink); font-weight: 500; gap: 6px; transition: transform .15s ease, background .2s, color .2s, border-color .2s; }
/* One selected state per theme (pine on light, mint on dark): chips, the scale, feelings, filters, switches. */
.chip[aria-pressed="true"], .chip[aria-checked="true"], .chip.on, .scale button[aria-pressed="true"], .feel[aria-pressed="true"], .check-item input:checked, input.switch:checked { background: var(--sel); color: var(--sel-ink); border-color: var(--sel); }
.chip.small { min-height: 36px; padding: 6px 12px; font-size: 13px; color: var(--muted); }
.scale { display: grid; grid-template-columns: repeat(5, 1fr); gap: 8px; }
.scale button { padding: 12px 0 8px; flex-direction: column; justify-content: flex-start; gap: 2px; font-size: 13px; background: var(--card); color: var(--ink); border: 1.5px solid var(--line); border-radius: 16px; min-height: 64px; }
.scale button span { font-size: 22px; font-family: Fraunces, serif; }
.scale button small { font-size: 13px; min-height: 2.6em; line-height: 1.3; }
/* Tab bar: icon above label, Wave raised. */
nav#tabs::before { content: ''; position: absolute; left: 0; right: 0; bottom: 100%; height: 52px; background: linear-gradient(transparent, var(--bg) 75%); pointer-events: none; } /* rows fade out above the bar and clear of the Wave orb, which stands 26 px above it with its glow (last content clears it by the main's bottom padding) */
body:has(.save-bar) nav#tabs::before { display: none; } /* a sticky save bar brings its own fade; the tab fade would wash out its buttons and prices */
nav#tabs { position: fixed; left: 0; right: 0; bottom: 0; display: flex; justify-content: space-around; align-items: center; background: color-mix(in srgb, var(--card) 92%, transparent); backdrop-filter: blur(12px); border-top: 1px solid var(--line); padding: 6px 8px calc(6px + env(safe-area-inset-bottom)); z-index: 5; }
nav#tabs a { color: var(--muted); text-decoration: none; font-size: 11.5px; font-weight: 600; letter-spacing: .01em; padding: 6px 8px 4px; min-width: 60px; min-height: 48px; display: inline-flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px; border-radius: 14px; transition: color .2s, transform .15s ease; }
nav#tabs a .ic { width: 24px; height: 24px; transition: transform .2s var(--ease); }
nav#tabs a.on { color: var(--pine); } nav#tabs a.on .ic { stroke-width: 2; transform: translateY(-1px); }
nav#tabs a:active { transform: scale(.94); }
nav#tabs a.wave-tab { background: var(--dawn); color: #2a1a10; border-radius: 999px; padding: 9px 16px 7px; margin-top: -26px; box-shadow: 0 6px 20px rgba(233,179,140,.5); }
nav#tabs a.wave-tab .ic { stroke-width: 2; }
.wave-hero { text-align: center; padding-top: 12px; }
/* A thin ring around the orb fills one breath at a time (an SVG stroke: a @property conic-gradient crashed WebView 133 on a
   theme flip, see ARCHITECTURE.md). */
.orb-wrap { position: relative; width: 248px; height: 248px; margin: 18px auto; display: grid; place-items: center; }
.orb-wrap .ring { position: absolute; inset: 0; width: 100%; height: 100%; transform: rotate(-90deg); opacity: 0; transition: opacity .6s; pointer-events: none; }
.ring circle { fill: none; stroke-width: 2.4; } .ring .track { stroke: color-mix(in srgb, var(--dawn) 35%, transparent); } .ring .fill { stroke: var(--dawn); stroke-dasharray: 100; stroke-dashoffset: var(--off, 100); transition: stroke-dashoffset var(--breath, 14s) linear; } /* sweeps through one whole breath (set by wave.js) */
.chips.patterns { justify-content: safe center; margin-top: 14px; } .patterns .chip { padding: 8px 10px; font-size: 15px; } .chips.patterns { gap: 6px; } /* the first chip stays reachable when the row scrolls */ #pnote { min-height: 2.8em; margin: 8px auto 0; max-width: 34ch; text-align: center; text-wrap: balance; } #pnote summary { cursor: pointer; display: inline-block; min-height: 48px; padding: 14px 12px 0; text-decoration: underline; } #pnote details p { margin: 0; }
.help-now .crisis { margin-bottom: 8px; } .salutation-edit { font-family: Fraunces, Georgia, serif; font-size: 18px; font-weight: 600; margin: 14px 2px 0; }
@media (prefers-color-scheme: dark) { .wave-hero[data-pattern="3am"] .orb { filter: none; } .wave-hero[data-pattern="3am"] .orb:not(.hold) { background: radial-gradient(circle at 35% 30%, #b5653a, #9c5129 32%, #85421f 64%, #6c331a); color: #fff3e4; } .wave-hero[data-pattern="3am"] .orb:not(.in):not(.out) { box-shadow: inset 0 0 0 2px #b8683c, 0 0 28px rgba(200,110,60,.3), 0 0 90px rgba(190,95,50,.38); } main:not(.breathing) .wave-hero[data-pattern="3am"] .orb:not(.hold) { background: radial-gradient(circle at 35% 30%, #a45a34, #8f4a27 32%, #7b3d1f 64%, #67301a); box-shadow: inset 0 0 0 2px #b8683c, 0 0 22px rgba(200,110,60,.24), 0 0 70px rgba(190,95,50,.3); } } /* gentler at night: the dark dawn stops at 86 %, baked in (a filter clipped the 90 px halo to a box); still warm; the Wave button stops outshining the orb while you are on it */
/* A soft halo behind the orb breathes with it, in step with each phase. */
.halo { position: absolute; inset: -12px; border-radius: 50%; background: radial-gradient(circle, color-mix(in srgb, var(--dawn) 30%, transparent) 0 46%, transparent 70%); transform: scale(.55); opacity: 0; transition: transform 4s ease-in-out, opacity 1.2s; pointer-events: none; }
.orb-wrap.on .halo { opacity: 1; } .orb-wrap[data-phase="in"] .halo, .orb-wrap[data-phase="hold"] .halo { transform: scale(1); }
/* A ripple leaves the orb on each in-breath, paced by --breath. */
.orb-wrap::after { content: ''; position: absolute; inset: 14px; border-radius: 50%; border: 2px solid var(--dawn); opacity: 0; pointer-events: none; }
.orb-wrap.on::after { animation: ripple var(--breath, 14s) ease-out infinite; }
@keyframes ripple { 0% { transform: scale(.62); opacity: 0; } 12% { opacity: .4; } 30% { transform: scale(1.06); opacity: 0; } 100% { transform: scale(1.06); opacity: 0; } }
.steps { display: flex; justify-content: center; gap: 6px; margin: 0 0 14px; } .steps i { width: 8px; height: 8px; border-radius: 50%; background: var(--line); } .steps i.on { background: var(--sage); }
.orb-wrap.on .ring { opacity: 1; } .orb-wrap.snap .ring .fill { transition: none; } /* reset to empty without sweeping backwards */
.orb-wrap .orb { margin: 0; }
.orb.hold { background: radial-gradient(circle at 35% 30%, #fbe4cf, #f0c4a0 50%, #d9956a); }
nav#tabs a.wave-tab.pulse { animation: tabPulse 1.8s ease-in-out 4; }
.spot .flame { animation: flicker 2.6s ease-in-out infinite; transform-origin: 50% 100%; transform-box: fill-box; }
/* The orb: dawn at rest, sage breathing in, a glow pulse on hold, pine breathing out; the tints are fading pseudo-elements. */
.orb { position: relative; isolation: isolate; width: 220px; height: 220px; margin: 28px auto; border-radius: 50%; background: radial-gradient(circle at 35% 30%, #f6d2b5, var(--dawn) 55%, #c98a62); box-shadow: 0 0 80px rgba(233,179,140,.55); transform: scale(.6); transition: transform 4s ease-in-out, box-shadow 1.2s ease; display: grid; place-items: center; color: #2a1a10; font-family: Fraunces, serif; font-size: 22px; padding: 0; }
.orb:not(.in):not(.hold):not(.out):not(.done) { font-size: 32px; padding: 0 12px; white-space: nowrap; line-height: 1.1; } /* the label is counter-scaled at rest: ~20 px on screen inside the .6 orb */
.orb::before, .orb::after { content: ''; position: absolute; inset: 0; border-radius: 50%; opacity: 0; transition: opacity 1.4s ease; z-index: -1; }
.orb::before { background: radial-gradient(circle at 35% 30%, #e6efe8, #7d9b8a 58%, #5f7d6c); } /* in: sage */
.orb::after { background: radial-gradient(circle at 35% 30%, #d6c7b9, #9a8f82 55%, #1f3a33); } /* out: pine-tinted */
.orb.in::before { opacity: .85; } .orb.out::after { opacity: .55; } .orb.done::before { opacity: .5; }
.orb:active { transform: scale(.6); }
/* At rest the orb breathes slowly; off while breathing and under reduced motion. */
.orb-wrap:not(.on) .orb:not(.in):not(.hold):not(.out):not(.done) { animation: idle 8s ease-in-out infinite; } @keyframes idle { 0%, 100% { transform: scale(.6); } 50% { transform: scale(.63); } } .orb.in:active, .orb.hold:active { transform: scale(1); } /* keep the breath scale when pressed */
.orb.in { transform: scale(1); box-shadow: 0 0 90px rgba(125,155,138,.55); }
.orb.hold { transform: scale(1); transition-duration: .2s; animation: glow 2s ease-in-out infinite; }
.orb.out { box-shadow: 0 0 60px rgba(31,58,51,.35); }
.orb.done { transform: scale(.85); transition-duration: 1.2s; }
@media (prefers-color-scheme: dark) { .orb:not(.hold) { background: radial-gradient(circle at 35% 30%, #fff3e4, #f6cfae 32%, #e9b38c 64%, #d39a72); } .orb:not(.in):not(.out) { box-shadow: 0 0 28px rgba(246,207,174,.35), 0 0 90px rgba(233,179,140,.5); } } /* dark: a lit dawn core and a soft halo, no more saturated than light */
@media (prefers-reduced-motion: reduce) {
  main { animation: none; }
  .orb { transition: opacity 3s ease, box-shadow 1.2s ease; transform: scale(.85); } /* the breath is an opacity swell, resting at full; only out and rest ease to .72, never a snap */
  .orb.in, .orb.hold, .orb.done { transform: scale(.85); opacity: 1; } .orb.out, .orb.rest { transform: scale(.85); opacity: .72; transition-duration: 5s; }
  .orb-wrap:not(.on) .orb:not(.in):not(.hold):not(.out):not(.done), .orb.hold { animation: none; } .orb:active, .orb.in:active, .orb.hold:active { transform: scale(.85); }
  .tree-art.grow { animation: none; } #toast .tick { animation: none; stroke-dashoffset: 0; } .kept-moment, .kept-moment .tick { animation: none; stroke-dashoffset: 0; }
  #toast { transition: opacity .25s; transform: translateX(-50%); } .ring .fill { transition: none; } .orb-wrap.on::after { animation: none; } .halo { transition: opacity 1.2s; transform: scale(.85); } .spot .flame { animation: none; }
  nav#tabs a.wave-tab.pulse { animation: none; outline: 3px solid var(--dawn); outline-offset: 3px; } /* a still highlight instead of the pulse */
  .tile, .chip, a.card, .lesson, .row-link, .strip, .stat, .feel, button, .btn, nav#tabs a, nav#tabs a .ic { transition: none; }
  :is(button, .btn, .tile, .chip, .lesson, .row-link, a.card, .stat, .strip, .feel, nav#tabs a):active { transform: none; opacity: .8; }
}
/* Icons (sprite in index.html) and illustrations (inlined SVG from app/art), coloured by the variables. */
.ic { width: 1.2em; height: 1.2em; stroke: currentColor; fill: none; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; flex: none; vertical-align: -.25em; }
h3 .ic, h2 .ic { width: 1.05em; height: 1.05em; margin-right: 8px; vertical-align: -.15em; color: var(--sage); }
.badge .ic { width: 14px; height: 14px; margin-right: 4px; vertical-align: -3px; }
.ic.end { margin-left: auto; color: var(--muted); } .ic.muted { color: var(--muted); }
.ic-badge { display: inline-grid; place-items: center; width: 40px; height: 40px; border-radius: 13px; background: var(--sage-soft); color: var(--pine); flex: none; }
.ic-badge .ic { width: 20px; height: 20px; } .tile .ic-badge { margin-bottom: 10px; }
.ic-badge.done { background: var(--pine); color: var(--bg); } .ic-badge.num.lock { background: color-mix(in srgb, var(--line) 55%, var(--card)); color: var(--muted); } /* locked is quiet, not the warm accent: the lock mark alone says it */ .ic-badge.lock { background: var(--dawn-soft); color: var(--lock-ink); }
.card.dawn .ic-badge, .card.soft .ic-badge { background: var(--card); }
.eyebrow { display: flex; align-items: center; gap: 6px; margin-bottom: 4px; } .eyebrow .ic { color: var(--sage); }
.section { display: flex; align-items: center; gap: 8px; margin: 26px 0 -4px; font-family: Fraunces, serif; font-size: 20px; font-weight: 600; color: var(--pine); } .section .ic { color: var(--sage); }
h3.section:has(#add-h) { margin-bottom: 8px; } /* the input below must not clip the heading's descenders */
.tree-art { display: inline-block; line-height: 0; } .tree-art svg { display: block; }
.tree-art.small svg { width: 56px; height: 56px; } .tree-art.large svg { width: 168px; height: 168px; }
.tree-art.grow { animation: grow .6s cubic-bezier(.2,.8,.2,1) both; transform-origin: 50% 90%; }
.spot { max-width: 260px; margin: 0 auto 10px; } .spot svg { display: block; width: 100%; height: auto; } .spot.wide { max-width: 320px; }
.card.empty { text-align: center; padding: 22px 18px; } .card.empty .spot { max-width: 210px; }
.hero { text-align: center; } .hero .spot { margin-top: 6px; }
.stats { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; margin: 14px 0; }
.stat { display: flex; flex-direction: column; align-items: center; gap: 2px; padding: 14px 8px; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); box-shadow: var(--shadow); text-decoration: none; color: inherit; transition: transform .15s ease, box-shadow .15s ease; }
.stat .row-art { width: 32px; height: 32px; margin-bottom: 4px; } .stat b { font-family: Fraunces, serif; font-size: 24px; line-height: 1; }
.links { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px 18px; margin: 18px 0 6px; } .links a { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font-weight: 500; text-decoration: none; }
/* The Path in chapters: a header and one line over its lessons (no progress bar: less to complete). */
.path-spot { max-width: 280px; margin-bottom: 0; } .chapter > .chapter-head > .chapter-art { width: 76px; overflow: hidden; } .chapter > .chapter-head > .chapter-art svg { width: 150%; margin: -9% 0 -9% -25%; } .chapter > .chapter-head > .chapter-art { -webkit-mask: radial-gradient(ellipse 52% 55% at 50% 50%, #000 70%, transparent 100%); mask: radial-gradient(ellipse 52% 55% at 50% 50%, #000 70%, transparent 100%); } .chapter > .chapter-head > .chapter-art svg { -webkit-mask: none; mask: none; } /* the hero art spans the band, centred over its title; a chapter's spot is cropped to its drawing so it sits against the title block, not 20 px short of it */
.chapter { margin-top: 28px; } .chapter .section { margin: 0; }
.chapter-head { display: flex; align-items: center; gap: 14px; } .chapter-art { flex: none; width: 92px; } .chapter-art svg { display: block; width: 100%; height: auto; }
.ic-badge.num { font-family: Fraunces, Georgia, serif; font-size: 17px; font-weight: 600; } /* the lesson's number along the Path */
.chapter .badge.lock { background: transparent; border: 1px solid color-mix(in srgb, var(--lock-ink) 35%, transparent); font-weight: 500; } /* quieter: the lock icon already says it */
.lesson-art { max-width: 190px; margin: 2px auto 10px; }
/* Spot art borrowed for chapters fades at its edges, never a cropped box. */
.chapter-art svg, .lesson-art svg { -webkit-mask: radial-gradient(ellipse 50% 50% at 50% 50%, #000 62%, transparent 100%); mask: radial-gradient(ellipse 50% 50% at 50% 50%, #000 62%, transparent 100%); }
/* The key idea, one way everywhere (the lesson's top, the paywall's preview), on a soft tint. */
.key-idea { margin: 6px 0 20px; padding: 12px 16px 2px; border-radius: 16px; background: var(--sage-soft); } .key-idea .eyebrow { color: var(--pine); font-weight: 600; margin: 0 0 2px; } .key-idea .eyebrow .ic { color: var(--sage); }
.key-text { font-family: Fraunces, Georgia, serif; font-size: 19px; line-height: 1.45; color: var(--pine); margin: 0 0 12px; } .plus-preview .key-text { font-size: 17px; }
/* Exercise tools: one line per answer. */
label.field, p.field { font-size: 14px; font-weight: 600; color: var(--pine); margin: 12px 2px 6px; } input.tool { background: var(--card); margin-bottom: 8px; }
.card.exercise textarea.paper { min-height: 30vh; }
ul.plan { list-style: none; padding: 0; margin: 6px 0 0; font-size: 14px; } ul.plan li { margin: 3px 0; text-wrap: pretty; display: grid; grid-template-columns: 84px 1fr; gap: 0 4px; } ul.plan .muted { font-weight: 600; } /* a long answer wraps under itself, not its label */
figure.story { margin: 20px 0; padding: 16px 18px 4px; border-radius: 16px; background: color-mix(in srgb, var(--dawn-soft) 70%, var(--card)); }
figure.story figcaption { display: flex; align-items: center; gap: 6px; font-size: 13px; font-weight: 600; letter-spacing: .02em; color: var(--muted); margin-bottom: 6px; } figure.story figcaption .ic { color: var(--dawn); width: 16px; height: 16px; }
figure.story p { font-family: Fraunces, Georgia, serif; font-size: 17.5px; line-height: 1.6; }
figure.story.parked { margin: 16px 0 4px; } figure.story.parked p { white-space: pre-wrap; } /* a thought parked at night, on the check-in */
.chapter-line { margin: 8px 0 0; } .card > .lesson:last-child, .plain > .lesson:last-child { border-bottom: 0; }
/* A lesson reads like a page: larger, looser; its exercise a card at the end. */
.lesson-body p { font-size: 17px; line-height: 1.65; margin-bottom: 14px; }
.source { margin-top: 4px; font-style: italic; }
.card.exercise { background: var(--sage-soft); border-color: transparent; box-shadow: none; } .card.exercise textarea { background-color: var(--card); margin-top: 6px; } /* background-color, so the ruled paper lines survive */ .card.exercise h3 { margin-bottom: 4px; } .ex-intro { font-family: Fraunces, Georgia, serif; font-size: 18px; line-height: 1.45; margin: 4px 0 8px; }
.kept { display: flex; gap: 8px; align-items: flex-start; margin: 10px 0; } .kept .ic { color: var(--sage); margin-top: 2px; } .kept.quiet { justify-content: center; margin: 6px 0 4px; }
ul.icons { list-style: none; padding: 0; margin: 0; } ul.icons li { display: flex; align-items: center; gap: 10px; margin: 8px 0; } ul.icons .row-art { width: 32px; height: 32px; }
.wave-cue { display: inline-grid; place-items: center; width: 36px; height: 36px; border-radius: 999px; background: var(--dawn); color: #2a1a10; flex: none; }
.chips.scroll .chip .ic { width: 16px; height: 16px; }
ul.ticks { list-style: none; padding: 0; margin: 0; } ul.ticks li { padding-left: 1.2em; position: relative; margin: 4px 0; }
ul.ticks li::before { content: '·'; position: absolute; left: .3em; font-weight: 700; }
.crisis { display: grid; gap: 8px; margin: 10px 0; } .crisis .btn { justify-content: space-between; text-align: left; } .crisis .btn small { color: var(--muted); font-weight: 500; } .crisis .btn > span { display: inline-flex; align-items: center; gap: 8px; }
.list-item { padding: 14px 0; border-bottom: 1px solid var(--line); } .list-item:last-child { border: 0; }
.lesson { display: flex; justify-content: space-between; align-items: center; gap: 12px; text-decoration: none; color: inherit; padding: 14px 0; border-bottom: 1px solid var(--line); transition: transform .15s ease; }
.lesson .grow, .list-item .grow { flex: 1; min-width: 0; }
.badge { font-size: 12px; font-weight: 600; padding: 4px 10px; border-radius: 999px; background: var(--sage-soft); color: var(--pine); white-space: nowrap; display: inline-flex; align-items: center; }
.badge.lock { background: var(--dawn-soft); color: var(--lock-ink); }
.memory img, img.photo { width: 100%; border-radius: 14px; margin-bottom: 10px; max-height: 320px; object-fit: cover; }
/* Letters thread: notes on paper, one side, full width; never a chat */
.thread { margin-top: 14px; } .thread-name { gap: 6px; margin: 0 2px 4px; } .thread-name .row-art { width: 24px; height: 24px; }
.thread .note { display: block; margin-top: 10px; padding: 16px; border-radius: 16px; background: var(--card); box-shadow: var(--shadow); color: inherit; text-decoration: none; font-family: Fraunces, Georgia, serif; font-size: 17px; line-height: 1.6; overflow-wrap: anywhere; } .thread .note:active { opacity: .85; }
.thread .note .text { display: block; white-space: pre-wrap; } .thread .note time { display: block; margin-bottom: 6px; font-family: Inter, system-ui, sans-serif; font-size: 13px; line-height: 1.4; color: var(--muted); } /* a dateline, as on a letter */ .thread .note .from { gap: 6px; margin-top: 8px; font-family: Inter, system-ui, sans-serif; line-height: 1.5; }
.thread .btn { margin-top: 14px; }
a.card.entry { display: block; color: inherit; text-decoration: none; transition: transform .15s ease, box-shadow .15s ease; }
.more { display: inline-flex; align-items: center; gap: 2px; margin-top: 8px; font-weight: 600; color: var(--pine); }
.chips.scroll { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; margin: 0 -16px; padding: 2px 16px; } .chips.scroll .chip { flex: none; white-space: nowrap; } /* a chip never wraps and stretches the row */ .chips.scroll::-webkit-scrollbar { display: none; } .chips.scroll.overflow { -webkit-mask: linear-gradient(90deg, #000 calc(100% - 72px), transparent 96%); mask: linear-gradient(90deg, #000 calc(100% - 72px), transparent 96%); } /* a soft edge says the row scrolls, only when it does (app.js markOverflow) */ /* filter chips stay on one line and scroll */
.price { position: relative; border: 2px solid var(--line); border-radius: var(--radius); padding: 16px; margin: 10px 0; }
#toast { position: fixed; left: 50%; bottom: 100px; transform: translateX(-50%) translateY(20px); background: var(--pine); color: var(--bg); padding: 12px 18px; border-radius: 16px; opacity: 0; pointer-events: none; transition: .25s; font-weight: 500; width: max-content; max-width: min(90vw, 420px); text-align: center; display: flex; align-items: center; gap: 8px; }
#toast.show { opacity: 1; transform: translateX(-50%); }
#toast .tick { width: 20px; height: 20px; stroke-width: 2.4; stroke-dasharray: 26; animation: tick .3s ease-out .1s both; } /* the "kept" check draws in */
.back { color: var(--muted); text-decoration: none; font-weight: 500; display: inline-flex; align-items: center; gap: 2px; min-height: 48px; padding-right: 12px; margin: 0 0 4px -6px; }
a { color: var(--pine); }
:focus-visible { outline: 3px solid var(--dawn); outline-offset: 2px; }
nav#tabs[hidden] { display: none; }
/* Edge-to-edge (Android 15+): a theme-coloured strip behind the status bar. */
body::before { content: ''; position: fixed; top: 0; left: 0; right: 0; height: env(safe-area-inset-top, 0px); background: var(--bg); z-index: 10; }
main:focus-visible { outline: none; } /* focused to move screen-reader position on route change */
/* Looking back: a weekly line, the month as soft tints (sage to dawn, never a number), feelings, notes. */
.reflect { background: linear-gradient(160deg, var(--sage-soft), var(--card) 80%); } .reflect-text { font-family: Fraunces, Georgia, serif; font-size: 19px; line-height: 1.45; color: var(--pine); margin: 2px 0 0; }
.month-nav { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; } .month-nav h2 { margin: 0; font-size: 20px; text-align: center; flex: 1; }
.icon-btn { width: 48px; min-width: 48px; height: 48px; padding: 0; border-radius: 50%; flex: none; display: inline-grid; place-items: center; }
.cal { display: grid; grid-template-columns: repeat(7, 1fr); gap: 6px; }
.cal-head { text-align: center; font-size: 12px; font-weight: 600; color: var(--muted); padding-bottom: 2px; }
.cal-cell { position: relative; aspect-ratio: 1; border-radius: 12px; display: grid; place-items: center; font-size: 13px; color: var(--muted); text-decoration: none; background: color-mix(in srgb, var(--line) 22%, transparent); transition: transform .15s ease; }
.cal-cell { animation: cellIn .4s var(--ease) both; animation-delay: calc(var(--i, 0) * 12ms); } @keyframes cellIn { from { opacity: 0; transform: scale(.85); } }
.cal-cell.out { background: none; } .cal-cell.future { color: var(--muted); } a.cal-cell { color: var(--ink); font-weight: 600; } a.cal-cell:active { transform: scale(.92); }
.cal-cell.today { box-shadow: 0 0 0 2px var(--card), 0 0 0 4px var(--pine); } /* outside the tint */
.h1.cal-cell, .cal-legend .h1, .tint.h1 { background: var(--h1); }
.h2.cal-cell, .cal-legend .h2, .tint.h2 { background: var(--h2); }
.h3.cal-cell, .cal-legend .h3, .tint.h3 { background: var(--h3); }
.h4.cal-cell, .cal-legend .h4, .tint.h4 { background: var(--h4); }
.h5.cal-cell, .cal-legend .h5, .tint.h5 { background: var(--h5); }
.cal-cell.h5, a.cal-cell.h5, .cal.wk .cal-cell.h5, .cal.yr .cal-cell.h5 { color: #fffdf8; } /* light: paper on the deep Crushing tint; dark sets its own ink below */
.cal-cell .noted { position: absolute; bottom: 4px; left: 50%; width: 5px; height: 5px; margin-left: -2.5px; border-radius: 50%; background: var(--dot, var(--pine)); box-shadow: 0 0 0 1.5px var(--card); } /* the day's own colour, ringed so it shows on its tint */
.cal-cell { --dot: var(--ink); }
.cal:not(.yr) .cal-cell[class*=' h']::after, .cal-legend i[class^='h']::after { content: ''; position: absolute; bottom: 4px; left: 50%; width: calc(var(--w) * 5px); height: 3px; margin-left: calc(var(--w) * -2.5px); border-radius: 2px; background: currentColor; } .cal:not(.wk):not(.yr) .cal-cell .noted { bottom: auto; top: 4px; left: auto; right: 4px; margin: 0; } /* the day's weight as a bar that grows, like the check-in swatches, in the weekday row and the key too; the note dot moves to the corner */ .cal-legend i[class^='h'] { position: relative; color: var(--ink); } .cal-legend i.h5 { color: #fffdf8; } .cal-legend i[class^='h']::after { bottom: 2px; height: 2px; width: calc(var(--w) * 3px); margin-left: calc(var(--w) * -1.5px); } .cal a.cal-cell::before { content: ''; position: absolute; inset: -4px; } /* a 44 px hit area round each 36 px day */ @media (prefers-color-scheme: dark) { .cal-legend i.h3, .cal-legend i.h4 { color: #16201c; } .cal-legend i.h5 { color: #fff3e4; } }
.cal-legend { display: grid; grid-template-columns: repeat(5, 1fr); gap: 4px; margin-top: 14px; font-size: 12px; line-height: 1.25; color: var(--muted); text-align: center; } .cal-legend i { width: 18px; height: 12px; border-radius: 4px; } .cal-legend span { display: flex; flex-direction: column; align-items: center; gap: 4px; }
.cal-cap { margin: 6px 0 6px; font-size: 12px; color: var(--muted); } .cal:not(.wk):not(.yr) + .cal-cap { margin-top: 18px; padding-top: 16px; border-top: 1px solid var(--line); } .cal-cap ~ .cal-cap { margin-top: 14px; } .cal-cap.hint { margin-top: 2px; min-height: 44px; display: block; padding: 11px 0; color: var(--ink); text-decoration: underline; text-underline-offset: 3px; } .cal-cap.hint svg { width: 14px; height: 14px; vertical-align: -2px; margin-left: 2px; } .cal.wk .cal-cell { aspect-ratio: auto; min-height: 44px; border-radius: 999px; display: flex; justify-content: center; align-items: center; gap: 2px; } .cal.wk a.cal-cell svg { width: 12px; height: 12px; } /* pills: the chevron says it opens Hard dates; the ring is only today */ .cal.yr { grid-template-columns: repeat(6, 1fr); gap: 4px; } .cal.yr .cal-cell { aspect-ratio: auto; height: 44px; border-radius: 10px; font-size: 12px; } .cal.yr [aria-current] span::after { content: ''; position: absolute; left: 50%; bottom: 6px; width: 14px; height: 3px; margin-left: -7px; border-radius: 2px; background: currentColor; }
.cal.wk .cal-cell[class*=' h'], .cal.yr .cal-cell[class*=' h'] { color: var(--ink); font-weight: 600; } .cal.yr a.cal-cell.one { color: var(--muted); font-weight: 400; } .cal.yr .one { outline: 1.5px dashed var(--line); outline-offset: -3px; } /* dots mean notes */
.cal.wk .cal-cell.h5, .cal.yr .cal-cell.h5 { color: #fffdf8; } /* after the ink rule above: paper on the Crushing clay (dark theme resets to ink) */
.feelings { display: flex; flex-wrap: wrap; gap: 8px; } .feeling { display: inline-flex; flex-direction: column; padding: 10px 14px; border-radius: 16px; background: var(--sage-soft); min-width: 92px; } .feeling b { font-family: Fraunces, serif; font-size: 16px; color: var(--pine); }
.notes { padding-top: 4px; padding-bottom: 4px; } .note-row { display: flex; align-items: flex-start; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--line); text-decoration: none; color: inherit; } .note-row:last-child { border: 0; }
a.card.entry .tint { flex: none; width: 28px; height: 28px; margin: 2px; border-radius: 50%; box-shadow: inset 0 0 0 1px color-mix(in srgb, var(--ink) 18%, transparent); } /* a check-in card leads with its heaviness colour, level on the date's row */ .note-row .tint { flex: none; width: 12px; height: 12px; border-radius: 50%; margin-top: 5px; } .note-row .grow { flex: 1; min-width: 0; } .note-text { display: block; white-space: pre-wrap; margin-top: 2px; } .note-row .ic.end { margin-top: 4px; }
/* Continuing bonds on Today: something kept, met again. */
.card.bond { display: block; text-decoration: none; color: inherit; background: color-mix(in srgb, var(--dawn-soft) 55%, var(--card)); }
.bond-row { display: flex; align-items: center; gap: 14px; margin-top: 6px; } .bond-row img { width: 76px; height: 76px; border-radius: 14px; object-fit: cover; flex: none; } .bond-row .grow { flex: 1; min-width: 0; }
.bond-row b { display: block; font-family: Fraunces, serif; font-size: 18px; } .bond-text { display: block; margin-top: 4px; color: var(--muted); font-size: 14px; } .bond-text.serif { font-family: Fraunces, Georgia, serif; font-size: 16px; color: var(--ink); }
/* Hard dates: each day opens its plan. */
a.list-item.date-row { text-decoration: none; color: inherit; align-items: flex-start; } a.date-row .ic.end { align-self: center; } .plan-cta { display: flex; width: fit-content; align-items: center; gap: 6px; margin-top: 6px; color: var(--pine); font-weight: 600; } .plan-cta .ic { width: 15px; height: 15px; }
.plan-card h3 { margin-bottom: 4px; } .date-card ul.plan { margin: 4px 0 10px; }
/* Memories: several photos, a swipeable row, thumbnails while writing, a gallery. */
.photo-row { display: flex; overflow-x: auto; scroll-snap-type: x mandatory; gap: 8px; margin-top: 12px; border-radius: 14px; scrollbar-width: none; } .photo-row::-webkit-scrollbar { display: none; }
.photo-row img { flex: 0 0 100%; width: 100%; max-height: 420px; object-fit: cover; border-radius: 14px; scroll-snap-align: center; }
.dots { display: flex; justify-content: center; gap: 6px; margin: 10px 0 0; } .dots i { width: 7px; height: 7px; border-radius: 50%; background: color-mix(in srgb, var(--muted) 45%, transparent); transition: background .2s, transform .2s; } .dots i.on { background: var(--pine); transform: scale(1.15); }
.card-photo { position: relative; display: block; } .card-photo .count { position: absolute; right: 10px; bottom: 20px; display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: 999px; background: rgba(20,30,26,.62); color: #fff; font-size: 12px; font-weight: 600; } .card-photo .count .ic { width: 14px; height: 14px; }
.thumbs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; }
.thumb { position: relative; aspect-ratio: 1; border-radius: 14px; overflow: hidden; background: var(--card); } .thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.thumb .x { position: absolute; top: 0; right: 0; width: 40px; height: 40px; min-height: 0; padding: 0; border-radius: 50%; background: none; color: #fff; } .thumb .x::before { content: ''; position: absolute; inset: 7px; border-radius: 50%; background: rgba(20,30,26,.45); } .thumb .x .ic { position: relative; width: 15px; height: 15px; } /* a 26px mark, a 40px target */
.thumb.add { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px; margin: 0; border: 1.5px dashed var(--line); color: var(--pine); font-weight: 600; cursor: pointer; text-align: center; }
.gallery { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; margin: 14px 0; border-radius: 16px; overflow: hidden; } .gallery a { display: block; aspect-ratio: 1; } .gallery img { width: 100%; height: 100%; object-fit: cover; display: block; transition: opacity .2s; } .gallery a:active img { opacity: .8; }
@media (prefers-color-scheme: dark) { a.cal-cell.h3, .cal-cell.h3, .cal-cell.h4, .cal-cell.h5, a.cal-cell.h4, a.cal-cell.h5, .cal.wk .cal-cell.h3, .cal.yr .cal-cell.h3, .cal.wk .cal-cell.h4, .cal.wk .cal-cell.h5, .cal.yr .cal-cell.h4, .cal.yr .cal-cell.h5 { color: #16201c; } .tint.h5, .tint.h4, .tint.h3 { color: #16201c; } } /* dark: ink on the three warm steps (h3 lifted for a lightness step, 4.8:1) */
/* The Looking back header art, the month header, a quiet line per extra hard date on Today. */
.insights-head { justify-content: space-between; align-items: center; } .insights-head .chapter-art { width: 96px; margin: -8px 0; } .icon-btn.placeholder { visibility: hidden; }
@media (prefers-reduced-motion: reduce) { .cal-cell { animation: none; } }
/* A memory's photos full screen: black, one at a time, close and title over it; the tab bar steps aside. */
body.viewing nav#tabs { display: none; } body.viewing main { padding: 0; max-width: none; animation: none; } /* no rise: a transformed main would pin the fixed viewer */
.viewer { position: fixed; inset: 0; background: #000; z-index: 20; display: flex; flex-direction: column; justify-content: center; }
.viewer .photo-row { margin: 0; border-radius: 0; flex: 1; align-items: center; } .viewer .photo-row img { max-height: 100dvh; height: 100%; object-fit: contain; border-radius: 0; }
.viewer .dots { position: absolute; left: 0; right: 0; bottom: calc(56px + env(safe-area-inset-bottom)); } .viewer .dots i { background: rgba(255,255,255,.4); } .viewer .dots i.on { background: #fff; }
.viewer-title { position: absolute; left: 0; right: 0; bottom: calc(16px + env(safe-area-inset-bottom)); text-align: center; color: #fff; font-family: Fraunces, serif; font-size: 17px; margin: 0; padding: 0 20px; }
.viewer .close { position: absolute; top: calc(12px + env(safe-area-inset-top)); right: 12px; z-index: 2; width: 48px; height: 48px; min-height: 0; padding: 0; border-radius: 50%; background: rgba(255,255,255,.16); color: #fff; } .viewer .close .ic { width: 22px; height: 22px; }
.photo-row img { cursor: zoom-in; }
.viewer .photo-row { touch-action: pan-x; } .viewer .photo-row.zoomed { overflow: hidden; touch-action: none; } .viewer .photo-row img { transition: transform .12s ease-out; will-change: transform; } .viewer .photo-row.touching img { transition: none; } .viewer { transition: opacity .2s; }
/* Writing a memory: tap a thumbnail to make it the cover. */
.thumb .pick { display: block; width: 100%; height: 100%; min-height: 0; padding: 0; border-radius: 0; background: none; } .thumb .pick:active { transform: none; opacity: .85; }
/* Voice: a memory's clips. While writing, a mic pill each; in the memory (and Listen on a lesson) a player: play/pause, bars with
   the position slider laid over them (invisible, so TalkBack reads a slider), the time. */
.voice-pills { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; } /* pills, not squares: a clip is not a photo slot */
.voice-pills .pill { display: inline-flex; align-items: center; gap: 6px; height: 44px; margin: 0; border-radius: 999px; color: var(--pine); font-weight: 600; } .voice-pills .pill > .ic { width: 18px; height: 18px; }
.pill.voice { padding-left: 14px; background: var(--card); box-shadow: inset 0 0 0 1.5px var(--line); } /* inset, so the 44px Remove fits the 44px pill */
.pill.voice .x { width: 44px; height: 44px; min-height: 0; padding: 0; border-radius: 50%; background: none; color: var(--muted); } .pill.voice .x .ic { width: 15px; height: 15px; }
.pill.add { padding: 0 18px 0 14px; border: 1.5px dashed var(--line); cursor: pointer; }
.len { font-variant-numeric: tabular-nums; min-height: 1.4em; }
.clips { display: grid; gap: 10px; margin-top: 12px; }
.clip { display: grid; grid-template-columns: 48px minmax(0, 1fr); align-items: center; gap: 2px 12px; padding: 10px 14px 8px 10px; border-radius: 16px; background: var(--card); border: 1px solid var(--line); }
.clip .play { grid-row: span 2; } .clip .play[aria-pressed="true"] { background: var(--sage-soft); border-color: transparent; }
.clip .wave { position: relative; height: 40px; min-width: 0; border-radius: 6px; } .clip .wave:focus-within { outline: 2px solid var(--sage); outline-offset: 3px; }
.clip .bars { position: absolute; inset: 0; display: flex; align-items: center; gap: 2px; pointer-events: none; }
.clip .bars i { flex: 1 1 0; min-width: 1px; border-radius: 2px; background: color-mix(in srgb, var(--muted) 38%, transparent); transition: background .15s; } .clip .bars i.on { background: var(--pine); }
.clip input[type="range"] { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; opacity: 0; cursor: pointer; }
.clip .time { font-variant-numeric: tabular-nums; } .clip.listen { margin: 6px 0 16px; } .clip.listen .wave { height: 44px; background: linear-gradient(90deg, var(--pine) var(--k, 0%), var(--track, var(--sage-soft)) 0) center / 100% 6px no-repeat; } /* Listen on a lesson: a soft line fills */
.clip.listen .wave::after { content: ''; position: absolute; top: 18px; left: clamp(0px, calc(var(--k, 0%) - 4px), calc(100% - 8px)); width: 8px; height: 8px; border-radius: 50%; background: var(--pine); pointer-events: none; } /* a dot at the fill end: the place reads at 0:00 too */
@media (prefers-color-scheme: dark) { .clip.listen .wave { --track: color-mix(in srgb, var(--sage) 35%, var(--card)); } } /* the unfilled line apart from the dark card */
.cover-tag { position: absolute; left: 6px; bottom: 6px; padding: 2px 8px; border-radius: 999px; background: rgba(20,30,26,.62); color: #fff; font-size: 11px; font-weight: 600; pointer-events: none; } .thumb.cover { box-shadow: 0 0 0 2px var(--dawn); }
.gallery-head { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; margin: 18px 2px 8px; } .gallery-head b { font-family: Fraunces, serif; font-size: 16px; } .gallery-head + .gallery { margin-top: 0; }
button.ghost.danger.quiet { border-color: transparent; } /* Delete stays findable but quieter than Edit */
@media (prefers-reduced-motion: reduce) { .cal-cell, .card.bond, .dots i, .gallery img, .clip .bars i { transition: none; } .plan-bar { transition: none; } a.cal-cell:active { transform: none; opacity: .8; } }
/* Breath first: a smaller orb on the welcome screen, its halo lit while it breathes. */
.breath-first { min-height: calc(100vh - 140px); display: flex; flex-direction: column; justify-content: center; text-align: center; } .breath-first h1 { max-width: 320px; margin: 6px auto 0; }
.orb-wrap.first { width: 232px; height: 232px; margin: 18px auto 4px; } .orb-wrap.first .orb { width: 208px; height: 208px; }
.orb-wrap.first[data-phase] .halo { opacity: 1; } .first-cue { min-height: 4.6em; max-width: 310px; margin: 6px auto 22px; } /* three lines, so the column never moves */
/* The First days checklist: a soft square tick, done items quieter (never struck through). */
.check-item { display: flex; gap: 12px; align-items: flex-start; margin: 0; padding: 12px 0; border-top: 1px solid var(--line); }
.check-item details { flex: 1; min-width: 0; } .check-item summary { display: flex; align-items: center; gap: 8px; min-height: 30px; list-style: none; cursor: pointer; } .check-item summary::-webkit-details-marker { display: none; }
.check-item summary b { flex: 1; } .check-item summary .ic { width: 18px; height: 18px; color: var(--muted); transition: transform .2s; } .check-item details[open] summary .ic { transform: rotate(90deg); }
.check-item details p { margin: 6px 0 2px; line-height: 1.55; }
.check-item .tick { flex: none; margin: -11px; padding: 11px; cursor: pointer; } /* a 48 px target around the 26 px box */
.check-item:has(input:checked) summary b { color: var(--muted); }
.check-item input:checked::after { animation: tick-in .25s ease-out; } @keyframes tick-in { from { transform: translateY(-1px) rotate(45deg) scale(.3); opacity: 0; } }
.check-item:first-child { border-top: 0; padding-top: 2px; } .check-item:last-child { padding-bottom: 2px; }
.check-item input { appearance: none; -webkit-appearance: none; flex: none; width: 26px; height: 26px; margin: 1px 0 0; padding: 0; border-radius: 9px; border: 1.5px solid var(--sage); background: var(--card); display: grid; place-items: center; cursor: pointer; transition: background .2s, border-color .2s; }
.check-item input:checked::after { content: ''; width: 6px; height: 12px; border: solid var(--bg); border-width: 0 2.5px 2.5px 0; transform: translateY(-1px) rotate(45deg); }
.check-item input:focus-visible { outline: 3px solid var(--dawn); outline-offset: 2px; }

/* How to help me: the message on paper. */
textarea.paper.helpme { min-height: 30vh; overflow: hidden; resize: none; }
.breath-first a .ic { margin-right: .35em; vertical-align: -.15em; }
.signpost h3 { margin-top: 2px; } .nw { white-space: nowrap; } /* a phone number never breaks across lines */
@media (prefers-reduced-motion: reduce) { .check-item input, .check-item summary .ic { transition: none; } .check-item input:checked::after { animation: none; } }
/* The signpost on Today: compact, the lines behind one row. */
.sign-art { flex: none; width: 72px; margin: -4px -4px 0 0; } .sign-art svg { display: block; width: 100%; height: auto; -webkit-mask: radial-gradient(ellipse 50% 50% at 50% 50%, #000 62%, transparent 100%); mask: radial-gradient(ellipse 50% 50% at 50% 50%, #000 62%, transparent 100%); }
.sign-lines { margin-top: 10px; } .sign-lines summary { display: flex; align-items: center; gap: 8px; min-height: 48px; padding: 0 16px; border-radius: 999px; border: 1.5px solid var(--line); font-weight: 600; color: var(--pine); list-style: none; cursor: pointer; } .sign-lines summary::-webkit-details-marker { display: none; }
.sign-lines summary .end { margin-left: auto; transition: transform .2s; } .sign-lines[open] summary .end { transform: rotate(90deg); } .sign-lines .crisis { margin-top: 4px; }
.sign-later { margin: 10px 2px 0; } button.link { display: inline; min-height: 0; padding: 0; border: 0; border-radius: 0; background: none; color: var(--pine); font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
.room-line { display: flex; gap: 8px; align-items: flex-start; margin: 10px 4px 0; } .room-line .ic { flex: none; width: 18px; height: 18px; margin-top: 2px; }
@media (prefers-reduced-motion: reduce) { .sign-lines summary .end { transition: none; } }
/* Feelings in four colour families (mist, ember, dusk, leaf), each word with its icon. */
:root { --f-low: #dfe6ec; --f-low-ink: #3b5566; --f-low-strong: #4f6d82; --f-stirred: #f7e1d3; --f-stirred-ink: #8a4f2a; --f-stirred-strong: #a85f37;
  --f-tender: #f1e2e8; --f-tender-ink: #7b4a5d; --f-tender-strong: #8c536a; --f-lighter: #e2ebdf; --f-lighter-ink: #2f5a45; --f-lighter-strong: #4a7559; --f-on: #fffdf8; }
@media (prefers-color-scheme: dark) { :root { --f-low: #233039; --f-low-ink: #b9cbd8; --f-low-strong: #8fb0c6; --f-stirred: #3e2c24; --f-stirred-ink: #f0c3a1; --f-stirred-strong: #e0a27a;
  --f-tender: #3a2731; --f-tender-ink: #e7bfd0; --f-tender-strong: #d39ab2; --f-lighter: #22332a; --f-lighter-ink: #b4d3bf; --f-lighter-strong: #8fbf9f; --f-on: #14100e; } }
.f-low { --fb: var(--f-low); --fi: var(--f-low-ink); --fs: var(--f-low-strong); } .f-stirred { --fb: var(--f-stirred); --fi: var(--f-stirred-ink); --fs: var(--f-stirred-strong); }
.f-tender { --fb: var(--f-tender); --fi: var(--f-tender-ink); --fs: var(--f-tender-strong); } .f-lighter { --fb: var(--f-lighter); --fi: var(--f-lighter-ink); --fs: var(--f-lighter-strong); }
.feel-family { margin: 14px 0 0; } .feel-title { display: flex; align-items: center; gap: 8px; margin: 0 0 8px; font-size: 13px; font-weight: 600; letter-spacing: .02em; color: var(--fi); }
.feel-title i { width: 10px; height: 10px; border-radius: 50%; background: var(--fs); }
.feel-chips { display: flex; flex-wrap: wrap; gap: 8px; }
.feel { display: inline-flex; align-items: center; gap: 8px; min-height: 48px; padding: 6px 16px 6px 6px; border-radius: 999px; border: 0; background: var(--fb); color: var(--fi); font-weight: 600; font-size: 15px; -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; transition: background .2s, color .2s, transform .15s ease; }
.feel-ic { display: inline-grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; background: color-mix(in srgb, var(--card) 70%, transparent); transition: background .2s; } .feel-ic .ic { width: 19px; height: 19px; }
.feel[aria-pressed="true"] .feel-ic { background: var(--fb); color: var(--fi); } /* picked: the shared selected state */
.feel[aria-pressed="true"] .feel-ic .ic { animation: pop .3s var(--ease); } @keyframes pop { 50% { transform: scale(1.18); } }
.feel-meaning { margin: 8px 2px 0; padding: 10px 14px; border-radius: 14px; background: var(--fb); color: var(--ink); animation: rise .25s var(--ease) both; } .feel-meaning b { color: var(--fi); }
span.feel { padding-right: 14px; min-height: 40px; font-size: 14px; } span.feel .feel-ic { width: 30px; height: 30px; }
.feeling.f-low, .feeling.f-stirred, .feeling.f-tender, .feeling.f-lighter { background: var(--fb); } .feeling[class*="f-"] b { color: var(--fi); display: flex; align-items: center; gap: 6px; } .feeling b .ic { width: 16px; height: 16px; }
/* After a check-in: what was kept, said back, then next steps. */
.kept-check { text-align: center; padding-top: 4px; } .kept-check h1 { font-size: 26px; max-width: 340px; margin: 4px auto 8px; } .kept-art { max-width: 170px; margin-bottom: 2px; }
.kept-check .eyebrow .ic { color: var(--sage); } .said { font-family: Fraunces, Georgia, serif; font-size: 19px; color: var(--pine); margin: 0 auto 10px; max-width: 340px; }
.feel-chips.static { justify-content: center; margin: 0 0 12px; }
/* The in-app dialog: a calm sheet over a dimmed page, clear verbs, the safe choice solid. */
body.dialog-open { overflow: hidden; }
.dialog-scrim { position: fixed; inset: 0; z-index: 30; display: flex; align-items: flex-end; justify-content: center; padding: 16px 12px calc(12px + env(safe-area-inset-bottom)); background: rgba(16,24,21,.45); animation: fadeIn .2s ease both; }
.dialog { width: 100%; max-width: 460px; max-height: calc(100dvh - 40px); overflow: auto; background: var(--card); border-radius: 26px; padding: 24px 20px 16px; box-shadow: 0 -4px 40px rgba(16,24,21,.22); animation: sheetIn .3s var(--ease) both; }
.dialog h2 { font-size: 22px; margin: 0 0 10px; } .dialog-body p { margin: 0 0 10px; color: var(--muted); }
.dialog-actions { display: grid; gap: 10px; margin-top: 16px; } .dialog-actions button.danger { background: transparent; }
dl.sides { margin: 0 0 12px; padding: 2px 14px; border-radius: 16px; background: var(--sage-soft); } dl.sides div { padding: 10px 0; border-top: 1px solid color-mix(in srgb, var(--sage) 25%, transparent); } dl.sides div:first-child { border: 0; }
dl.sides dt { font-size: 12px; font-weight: 600; letter-spacing: .02em; color: var(--muted); } dl.sides dd { margin: 2px 0 0; font-weight: 500; }
@keyframes fadeIn { from { opacity: 0; } } @keyframes sheetIn { from { opacity: 0; transform: translateY(24px); } }
@media (prefers-color-scheme: dark) { .dialog-scrim { background: rgba(0,0,0,.6); } .dialog { border: 1px solid var(--line); } }
@media (prefers-reduced-motion: reduce) { .dialog-scrim, .dialog, .feel-meaning, .feel[aria-pressed="true"] .feel-ic .ic { animation: none; } .feel, .feel-ic { transition: none; } }
/* The paywall reads as the Path it opens: chapters, a real first page, what stays free, then plain prices. */
.plus-hero > p.muted { max-width: 440px; margin: 0 auto 4px; } .plus-hero .eyebrow { margin: 2px 0 2px; }
.plus-chapter { padding: 10px 16px; } .plus-hero:not(.compact) .spot.wide { max-width: 236px; } .plus-chapter .chapter-art { position: relative; width: 60px; height: 60px; border-radius: 50%; overflow: hidden; background: var(--art-soft); } .plus-chapter .chapter-art svg { position: absolute; left: 50%; top: 52%; width: 165%; transform: translate(-50%, -50%); -webkit-mask: none; mask: none; } /* framed like the Keep tiles: one circle, one scale */ .plus-chapter h3 { margin: 0 0 2px; }
ul.plus-lessons { list-style: none; padding: 0; margin: 12px 0 2px; display: grid; gap: 8px; font-size: 15px; } ul.plus-lessons li { display: flex; align-items: center; gap: 10px; text-wrap: pretty; }
ul.plus-lessons .n { flex: none; width: 26px; height: 26px; display: inline-grid; place-items: center; border-radius: 9px; background: var(--dawn-soft); color: var(--lock-ink); font-family: Fraunces, Georgia, serif; font-size: 13px; font-weight: 600; }
.plus-preview .lesson-art { max-width: 150px; } .preview-title { font-size: 22px; margin-bottom: 10px; }
.lesson-body.fade { max-height: 13.5em; overflow: hidden; -webkit-mask: linear-gradient(#000 40%, transparent 98%); mask: linear-gradient(#000 40%, transparent 98%); }
.preview-more { display: flex; gap: 8px; align-items: flex-start; margin: 2px 0 0; color: var(--lock-ink); } .preview-more .ic { flex: none; margin-top: 2px; width: 16px; height: 16px; }
ul.free-grid { list-style: none; padding: 0; margin: 4px 0 0; display: grid; grid-template-columns: 1fr 1fr; gap: 10px 12px; font-size: 14px; } ul.free-grid li { display: flex; align-items: center; gap: 8px; } ul.free-grid .row-art { width: 28px; height: 28px; color: var(--pine); }
.price { background: var(--card); } .price .per { margin: 4px 0 0; color: var(--pine); font-weight: 500; } .price p.muted { margin: 6px 0 12px; } .price > .row b:last-child { font-family: Fraunces, Georgia, serif; font-size: 18px; }
.legal { margin-top: 14px; }
/* Paper grain on the illustrations (one SVG filter; animated art like a flame goes without it, so it never runs every frame),
   and a slow sway for the tree on Me (a transform: moved, never redrawn). */
.tree-art svg, .spot svg, .chapter-art svg, .sign-art svg { filter: url(#grain); } .spot svg:has(.flame) { filter: none; }
.tree-art.large { transform-origin: 50% 94%; animation: sway 8s ease-in-out infinite; } .tree-art.large.grow { animation: grow .6s cubic-bezier(.2,.8,.2,1) both, sway 8s ease-in-out .6s infinite; }
@keyframes sway { 0%, 100% { transform: skewX(0); } 30% { transform: skewX(-1.4deg); } 70% { transform: skewX(1deg); } }
@media (prefers-reduced-motion: reduce) { .tree-art.large, .tree-art.large.grow { animation: none; } }
/* Scenes that run to their edges fade out, never a cropped box. */
.spot svg { -webkit-mask: radial-gradient(ellipse 52% 52% at 50% 50%, #000 70%, transparent 100%); mask: radial-gradient(ellipse 52% 52% at 50% 50%, #000 70%, transparent 100%); }
/* The preview ends on the key idea; locked rows carry a small lock, not a pill each. */
.lesson-body.fade { max-height: 9em; }
.lock-mark { display: inline-grid; place-items: center; flex: none; width: 32px; height: 32px; border-radius: 50%; color: var(--lock-ink); background: color-mix(in srgb, var(--dawn) 14%, var(--card)); } .lock-mark .ic { width: 15px; height: 15px; }
@media (prefers-color-scheme: dark) { ul.plus-lessons .n, .ic-badge.lock { background: color-mix(in srgb, var(--dawn) 14%, var(--card)); } .lock-mark { background: color-mix(in srgb, var(--dawn) 12%, var(--card)); } }
/* Dawn cards and story blocks in dark mode: a warm tint, not a brown slab; the paywall's compact header. */
@media (prefers-color-scheme: dark) { .card.dawn { background: var(--card); border-color: color-mix(in srgb, var(--warm-ink) 14%, transparent); } figure.story { background: var(--warm-surface); } }
.plus-hero.compact { text-align: left; } .plus-hero.compact .spot { max-width: 210px; margin: 0 0 4px; } .plus-hero.compact .eyebrow { justify-content: flex-start !important; } .plus-hero.compact h1 { font-size: 26px; } .plus-hero.compact > p.muted { margin: 0 0 4px; }
@media (prefers-color-scheme: dark) { .card.bond { background: var(--card); border-color: color-mix(in srgb, var(--warm-ink) 14%, transparent); } }
@media (prefers-color-scheme: dark) { .card.bond .eyebrow, .card.bond .eyebrow .ic, .card.dawn .eyebrow, .card.dawn .eyebrow .ic { color: var(--warm-ink); } } /* the warm glow is the hard-date band's alone */
/* SNS 24's menu hint; the toast's Undo; the date fix-it; the checklist's source line. */
.crisis .btn .hint { display: block; font-size: 13px; font-weight: 500; color: var(--muted); margin-top: 2px; }
#toast.act { pointer-events: auto; } #toast .undo { color: inherit; font-weight: 700; text-decoration: underline; padding: 6px 4px; margin: -6px 0 -6px 4px; min-height: 44px; }
.fixit { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; margin: 4px 0 14px; } .fixit .chip { margin: 0; }
.checked-line { margin: 0 2px 4px; }
/* Calm surfaces: the scene (a sky for the part of the day; Today, Me), the band (a full-bleed tinted section) and the plain
   list (rows on hairlines, no box). */
:root { --sel: var(--pine); --sel-ink: var(--bg); }
.scene { position: relative; isolation: isolate; overflow: hidden; margin: calc(-24px - env(safe-area-inset-top, 0px)) -16px 0; padding: calc(28px + env(safe-area-inset-top, 0px)) 20px 40px;
  background: linear-gradient(180deg, var(--bg), var(--sky) 26%, color-mix(in srgb, var(--sky) 45%, var(--bg)) 72%, var(--bg)); } /* soft at the top too, under the status bar */
.scene.morning { --sky: var(--dawn-soft); --sun: #f3c39c; --sx: 86%; --sy: 15%; } .scene.day { --sky: var(--sage-soft); --sun: #f7dcc2; --sx: 84%; --sy: 13%; }
.scene.evening { --sky: color-mix(in srgb, var(--dawn) 38%, var(--dawn-soft)); --sun: var(--dawn); --sx: 88%; --sy: 20%; } .scene.night { --sky: color-mix(in srgb, var(--f-low) 85%, var(--bg)); --sun: #f6f1e6; --sx: 80%; --sy: 18%; }
@media (prefers-color-scheme: dark) { .scene:not(.night) { --sun: color-mix(in srgb, var(--dawn) 85%, #fff3e6) !important; } .scene.morning, .scene.evening { --sky: var(--warm-surface-strong); } .scene.day { --sky: color-mix(in srgb, var(--sage) 18%, var(--bg)); } .scene.night { --sky: color-mix(in srgb, #3a5266 45%, var(--bg)); --sun: #e8e2d4; } }
/* The light: a layered glow (bright core, soft fall-off) with the paper grain, so sky and drawing read as one picture. */
.sky-light { position: absolute; z-index: -1; left: var(--sx); top: var(--sy); width: 120px; height: 120px; margin: -60px; border-radius: 50%; background: radial-gradient(closest-side, var(--sun) 0 28%, color-mix(in srgb, var(--sun) 40%, transparent) 46%, transparent 70%); } @media (prefers-color-scheme: dark) { .sky-light { filter: url(#grain); } } /* texture on the dark sky, speckle on paper */
.scene.night .sky-light { background: radial-gradient(closest-side, color-mix(in srgb, var(--sun) 32%, transparent), color-mix(in srgb, var(--sun) 12%, transparent) 45%, transparent 70%); } .scene.night .sky-light::before { content: ''; position: absolute; inset: 42px; border-radius: 50%; box-shadow: inset 9px -5px 0 0 var(--sun); } /* a crescent in the same soft halo */
.hills { position: absolute; z-index: -1; left: 0; bottom: 0; width: 100%; height: 76px; } .hills .far { fill: color-mix(in srgb, var(--art-soft) 80%, var(--sky)); } .hills .near { fill: var(--bg); }
.band { margin: 18px -16px; padding: 20px 20px 18px; background: var(--sage-soft); } .band.dawn { background: var(--dawn-soft); }
.band h3 { margin: 4px 0 6px; } .band .eyebrow { color: var(--pine); font-weight: 600; } .band .ghost, .band .ic-badge { background: var(--card); } .band p:last-child { margin-bottom: 0; }
@media (prefers-color-scheme: dark) { .band.dawn { background: radial-gradient(120% 140% at 100% 0%, var(--warm-glow), transparent 60%), var(--warm-surface-strong); } .band.dawn .eyebrow, .band.dawn .eyebrow .ic { color: var(--warm-ink); } }
.plain { margin: 18px 0; } .plain > .eyebrow { margin: 0 2px 2px; }
.row-link { display: flex; align-items: center; gap: 12px; padding: 14px 2px; color: inherit; text-decoration: none; } .row-link + .row-link { border-top: 1px solid var(--line); }
.row-link .grow { flex: 1; min-width: 0; } .row-link .grow > * { display: block; } .row-link b { font-family: Fraunces, Georgia, serif; font-size: 17px; } :is(.row-link:not(.help-row), .lesson, .tile.wide) b, .plus-chapter h3 { font: 600 17px/1.3 Inter, system-ui, sans-serif; letter-spacing: -.005em; } /* one title for rows that open a screen; the crisis row keeps its own */
/* Today: one hero (the scene, the greeting, one line of state, one action, two weeks as a strip), then modules. */
.today-hero { min-height: 312px; } .today-hero h1 { margin: 2px 0 4px; } .today-hero p { margin: 0; }
html.night-ease, html.night-ease body, html.night-ease :is(main, .card, .scene, nav#tabs, .btn, button) { transition: background-color 1.5s ease, color 1.5s ease, border-color 1.5s ease; } @media (prefers-reduced-motion: reduce) { html.night-ease, html.night-ease * { transition: none !important; } } /* the 23:00/05:00 switch eases; at 360 the tree clears Two weeks */
.today-hero .tree-link { position: absolute; z-index: -1; right: 4px; bottom: 0; line-height: 0; } .today-hero .tree-art.small svg { width: 150px; height: 150px; } @media (max-width: 380px) { .today-hero .tree-link { bottom: 4px; } .today-hero .tree-art.small svg { width: 112px; height: 112px; } } /* the soil ellipse sits on the near hill's ridge (about 19 px up at the tree's x) at every width */ .scene .tree-art { --art-glow: transparent; } /* the sky has its own light */
.hero-state { display: flex; align-items: center; gap: 6px; margin-top: 12px !important; color: var(--pine); font-weight: 500; } .hero-state .ic { color: var(--sage); }
.hero-act { display: flex; flex-direction: column; align-items: flex-start; gap: 10px; margin-top: 16px; } .btn.quiet { background: color-mix(in srgb, var(--card) 75%, transparent); color: var(--pine); border: 1.5px solid var(--line); }
.sign-later button.link, #ci-edit { display: inline-flex; align-items: center; min-height: 44px; } .heavy-help a { padding: 14px 0; } /* small links that still take a thumb; the one inside a sentence grows its hit area, not the line */
.strip { display: inline-flex; align-items: flex-end; gap: 10px; min-height: 44px; color: var(--pine); text-decoration: none; font-weight: 600; } .strip .small { display: inline-flex; align-items: center; } .strip .ic { width: 16px; height: 16px; }
.strip .bars { display: flex; align-items: flex-end; gap: 3px; height: 26px; } .strip i { width: 6px; height: 4px; border-radius: 3px; background: color-mix(in srgb, var(--muted) 30%, transparent); }
.strip i.h1 { height: 8px; background: var(--h1); } .strip i.h2 { height: 12px; background: var(--h2); } .strip i.h3 { height: 16px; background: var(--h3); } .strip i.h4 { height: 21px; background: var(--h4); } .strip i.h5 { height: 26px; background: var(--h5); }
.heavy-line { font-family: Fraunces, Georgia, serif; font-size: 19px; color: var(--pine); } .date-card .since { margin: -2px 0 8px; } .date-card .under { margin: 8px 0 0; } .plan-head { margin: 10px 0 0; }
.date-lines { display: flex; gap: 8px; align-items: flex-start; margin: 14px 0 0; padding-top: 12px; border-top: 1px solid color-mix(in srgb, var(--dawn) 35%, transparent); } .date-lines .ic { flex: none; margin-top: 2px; color: var(--lock-ink); }
.for-today .prompt { font-family: Fraunces, Georgia, serif; font-size: 19px; line-height: 1.35; color: var(--pine); margin-bottom: 4px; }
/* Me and the Path open on a scene or a band. */
.me-scene { text-align: center; } .me-top { text-align: left; } .me-top h1 { margin: 0; } .tree-card h2 { margin: 0 0 4px; } .tree-card p { max-width: 320px; margin: 0 auto; }
.stat { background: color-mix(in srgb, var(--sage-soft) 55%, var(--card)); border: 0; box-shadow: none; }
.path-head { margin-top: calc(-24px - env(safe-area-inset-top, 0px)); padding-top: calc(20px + env(safe-area-inset-top, 0px)); text-align: center; } .path-head .muted:not(.small) { max-width: 460px; margin: 0 auto 8px; } .chapter .plain { margin: 6px 0 0; }
/* Wave: at rest the orb, its patterns, More ways and Help now; breathing is full screen (lib/immersive.js). */
.wave-hero h1 { font-size: 27px; } .wave-foot { text-align: center; margin-top: 4px; } .wave-hero.night + .wave-foot { display: flex; flex-direction: column; } .wave-hero.night + .wave-foot .wave-help { order: -1; border-top: 0; padding-top: 0; margin-bottom: 14px; } .wave-hero.night + .wave-foot .foot-row { border-top: 1px solid var(--line); padding-top: 14px; } /* at 3 am the crisis rows come straight after the orb, above More ways and Park */ .foot-row { display: flex; flex-direction: column; align-items: center; gap: 4px; margin-bottom: 14px; } .crisis-h { font: 400 14px/1.45 Inter, system-ui, sans-serif; color: var(--ink); margin: 0 0 10px; } .crisis-h > * { display: inline; font: inherit; letter-spacing: 0; margin: 0; } .crisis-h h2 { font-weight: 600; } /* a heading and its sentence, read as one line */ a.help-all { display: inline-flex; align-items: center; min-height: 44px; } main:not(.breathing) .wave-hero .orb-wrap:not(.on) { margin: -18px auto -26px; } main:not(.breathing) .wave-hero.night .orb-wrap:not(.on) { margin: -38px auto -42px; } .wave-hero.night .lede { margin-bottom: 4px; } .wave-hero.night #cue { margin-bottom: 4px; } .wave-hero.night #pnote { margin-top: 0; } /* 3 am: the resting orb's empty ring closes up, so the crisis rows stand whole above the tab fade at 360 px */ /* the resting orb gives up its empty rim at any hour (it grows only while breathing, full screen), so the first crisis row clears the tab bar at 360; at night Park sits under More ways */ .wave-help { text-align: left; max-width: 340px; margin: 0 auto; border-top: 1px solid var(--line); padding-top: 14px; }
.help-row { text-align: left; border-top: 1px solid var(--line); } .help-row .ic-badge { background: var(--dawn-soft); color: var(--lock-ink); }
.breath-bar { display: none; } body.immersive nav#tabs, body.immersive::before { display: none; }
/* Behind the breathing: Today's scene, full screen. */
.breath-scene { display: none; } .breath-scene.rest { display: block; position: fixed; inset: 0; z-index: 0; margin: 0; padding: 0; } main:has(> .breath-scene.rest) :is(.wave-hero, .wave-foot) { position: relative; z-index: 1; } /* the 3 am pattern rests under the night sky */
.wave-hero { transition: filter 1.5s, opacity 1.5s; } .wave-hero.ember { filter: brightness(.4); opacity: .4; transition: filter 140s linear, opacity 140s linear; } /* the night fade: a faint ember; a touch brings it back */
@media (prefers-reduced-motion: reduce) { .wave-hero.ember { transition: filter 3s, opacity 3s; } } /* no 140 s drift, but no sudden step at 3 am */
 main.breathing .breath-scene { display: block; position: fixed; inset: 0; z-index: 0; margin: 0; padding: 0; } main.breathing .wave-hero { position: relative; z-index: 1; } .breath-bar { z-index: 2; }
main.breathing h1, main.breathing .lede, main.breathing .patterns, main.breathing #pnote, main.breathing .wave-foot { display: none; }
main.breathing .wave-hero { min-height: calc(100dvh - 120px); display: flex; flex-direction: column; justify-content: center; }
main.breathing .breath-bar { display: flex; justify-content: space-between; position: fixed; left: 0; right: 0; bottom: 0; padding: 12px 16px calc(16px + env(safe-area-inset-bottom)); }
.breath-bar > * { min-height: 44px; padding: 8px 18px; font-size: 15px; background: var(--card); } /* solid: safety controls read over the hills */
/* The sheet (More ways): a dialog of a few quiet sections. */
.sheet-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; } .sheet-head h2 { margin: 0; }
.sheet-sec { padding: 14px 0 6px; border-top: 1px solid var(--line); } .sheet-head + .sheet-sec { border: 0; } .sheet-sec .eyebrow { color: var(--pine); font-weight: 600; } .sheet .toggle .row { gap: 12px; } #gbox h3 { margin: 4px 0 12px; }
/* Onboarding: one question per screen. */
.ask-step h1 { font-size: 28px; margin-top: 4px; } .ask-art { max-width: 180px; } .ask-step input { font-size: 18px; } .step-foot { display: grid; gap: 10px; margin-top: 26px; }
.when .label { margin: 16px 0 8px; font-size: 14px; color: var(--muted); } .years { gap: 8px; } select.chip { width: auto; font-weight: 500; }
.months, .days { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; } .days { grid-template-columns: repeat(7, 1fr); gap: 6px; }
.months .chip, .days .chip { padding: 0; border-radius: 14px; } .days .chip { min-height: 44px; } .chip:disabled { opacity: .35; }
.when-said { min-height: 1.5em; margin: 14px 0 0; font-family: Fraunces, Georgia, serif; font-size: 20px; color: var(--pine); }
.sr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; } .remind { margin: 18px 0 8px; } .remind .row input { flex: 1; min-width: 0; }
@media (prefers-reduced-motion: reduce) { main[data-motion="tab"] { animation: none; } }
/* The kept moment in its scene, the scale's weights, Save in reach. */
.kept-scene { padding-bottom: 60px; } .kept-scene .kept-check { text-align: center; } .kept-foot { margin-top: 8px; }
.scale .weight { width: 22px; height: calc(var(--w) * 4px); margin: 0 auto 4px; border-radius: 3px; background: var(--wc); flex: none; }
.weight.h1, .cal-cell.h1, .cal-legend .h1 { --w: 1; --wc: var(--h1); } .weight.h2, .cal-cell.h2, .cal-legend .h2 { --w: 2; --wc: var(--h2); } .weight.h3, .cal-cell.h3, .cal-legend .h3 { --w: 3; --wc: var(--h3); } .weight.h4, .cal-cell.h4, .cal-legend .h4 { --w: 4; --wc: var(--h4); } .weight.h5, .cal-cell.h5, .cal-legend .h5 { --w: 5; --wc: var(--h5); }
@media (prefers-color-scheme: dark) { .scale button[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--sel); } }
.scale button { justify-content: flex-end; min-height: 92px; } .scale button[aria-pressed="true"] .weight { background: var(--wc); box-shadow: 0 0 0 2px var(--sel-ink); } /* the chosen weight keeps its own colour, ringed so it stands off the selected fill */
.save-bar { position: sticky; bottom: calc(70px + env(safe-area-inset-bottom)); z-index: 2; margin-top: 12px; padding: 12px 0 4px; background: linear-gradient(transparent, var(--bg) 35%); }
.save-bar::after { content: ''; position: absolute; left: 0; right: 0; top: 100%; height: 48px; background: var(--bg); pointer-events: none; } /* fills the gap down to the tab bar: nothing shows through under Save */
html:has(.save-bar:not(.still)) { scroll-padding-bottom: calc(140px + env(safe-area-inset-bottom)); } /* a focused chip scrolls clear of the bar and the tabs; the bar rests in the flow until Save can act (checkin.js) */
.step-foot { position: sticky; bottom: 0; z-index: 2; padding: 18px 0 calc(10px + env(safe-area-inset-bottom)); background: linear-gradient(transparent, var(--bg) 30%); } .step-help { display: inline-flex; gap: 6px; align-items: center; justify-content: center; min-height: 44px; }
.next-read, .heavy-help { display: flex; gap: 8px; align-items: flex-start; margin: 2px 2px 0; color: var(--muted); } .next-read .ic, .heavy-help .ic { flex: none; margin-top: 2px; color: var(--sage); }
.chapter .plain { position: relative; } .chapter .plain::before { content: ''; position: absolute; left: 19px; top: 30px; bottom: 30px; width: 2px; background: var(--sage-soft); } .chapter .lesson .ic-badge { position: relative; }
/* One divider in the sheet, the When step's days clear of its footer, a still halo. */
.sheet-sec > .help-row { border-top: 0; } html:has(.when) { scroll-padding-bottom: 150px; } .step-more { margin-top: 2px; } .ask-art { max-width: 150px; margin-bottom: 4px; }
.row-link .small, .tree-card p, .band p, .heavy-line { text-wrap: pretty; }
@media (prefers-reduced-motion: reduce) { .orb-wrap[data-phase] .halo, .orb-wrap.first[data-phase] .halo { transform: scale(.85); transition: opacity 1.2s; } }
.breath-bar > .ghost { background: var(--card); } .crisis .btn { border-radius: 18px; } .crisis .btn { flex-wrap: wrap; column-gap: 12px; row-gap: 2px; } .crisis .btn small { margin-left: auto; text-align: right; } /* a long line keeps its number whole; its place moves under it, right-aligned */ .scene.me-scene { --sx: 26%; --sy: 30%; } .save-bar.still { position: static; background: none; }
/* The light (the mascot, ui.js firlight()): a warm glow breathing on its wrapper; by the tree on Today, above the resting orb;
   gone while a Wave breathes or the night fade dims; still under reduced motion. */
.firlight { position: absolute; z-index: 0; width: 48px; height: 48px; line-height: 0; pointer-events: none; animation: firlight 7s ease-in-out infinite; } .firlight svg { width: 100%; height: 100%; display: block; }
.firlight.by-tree { right: 168px; bottom: 0; } @media (max-width: 380px) { .firlight.by-tree { right: 94px; bottom: 2px; } } /* at the fir's foot, left of it, on the hill (ART_BIBLE pose 4) */ .firlight.by-orb { top: calc(50% - 82px); left: calc(50% - 76px); z-index: 1; } /* the resting orb is 132 dp (scale .6) in a 248 wrap: off its upper-left shoulder, a few dp clear of the rim */ @media (prefers-reduced-motion: reduce) { .firlight.by-orb { top: calc(50% - 106px); left: calc(50% - 100px); } } /* the still orb is 187 dp: its companion moves out with it (after the base rule, so it wins) */ .scene .tree-art .tip { display: none; } /* in a scene the light is the mascot */
.scene.night .firlight.by-tree { animation-duration: 9s; } .orb-wrap.on .firlight, .wave-hero.ember .firlight { opacity: 0; animation: none; transition: opacity 1.2s; }
@keyframes firlight { 0%, 100% { transform: translate(0, 0); opacity: .85; } 50% { transform: translate(-2px, -3px); opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .firlight { animation: none; opacity: .95; } }
/* The paywall's plans in reach from the first screen; First days on Today as a band. */
.plan-bar { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 10px; transition: opacity .2s, visibility .2s; padding-top: 28px; background: linear-gradient(transparent, var(--bg) 28px); } /* the fade is the 28 px above the buttons; behind and between them the bar is solid, so no card shows through the gap */
.plan-bar > .btn { flex-direction: column; gap: 0; min-height: 56px; padding: 8px 12px; line-height: 1.25; } .plan-bar > .btn.ghost { background: var(--card); }
.plan-bar small { font-size: 13px; font-weight: 500; opacity: .85; } .plan-bar.away { opacity: 0; visibility: hidden; }
.first-band .row-link { padding: 0; align-items: center; } .first-band .row-link .grow > .muted { margin-top: 4px; } .first-band .sign-art { margin: -6px -2px -6px 0; }

.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0; }
.hour-step { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 6px; border: 1px solid var(--line); border-radius: 999px; background: var(--card); } .hour-step select { flex: 1; min-width: 0; min-height: 44px; width: auto; padding: 0 8px; border: 0; background: none; appearance: none; text-align: center; text-align-last: center; font: 600 22px/1 Fraunces, Georgia, serif; font-variant-numeric: tabular-nums; color: var(--ink); } .hour-step select { text-decoration: underline dotted 1.5px; text-underline-offset: 7px; cursor: pointer; } .hour-step .icon-btn { border: 1px solid var(--muted); } /* the hour reads as something to tap: it opens the list */ /* a hard hour's hour: earlier, the hour, later */
body.night-dim::after { content: ''; position: fixed; inset: 0; z-index: 1000; background: #000; opacity: .6; pointer-events: none; animation: nightDim 140s linear both; } @keyframes nightDim { from { opacity: 0; } } #wake-hint { position: fixed; left: 0; right: 0; top: 47vh; z-index: 1001; margin: 0; text-align: center; font: 500 17px/1.4 Inter, system-ui, sans-serif; color: #ece7dd; opacity: .8; pointer-events: none; animation: nightDim 20s linear both; } /* readable over the dim (about 9:1); taps pass through; the status bar keeps body::before */ body.night-undim::after { content: ''; position: fixed; inset: 0; z-index: 1000; background: #000; opacity: 0; pointer-events: none; animation: nightUndim 1.5s ease-out; } @keyframes nightUndim { from { opacity: .6; } } @media (prefers-reduced-motion: reduce) { body.night-dim::after, body.night-undim::after { animation-duration: 1.5s; } } /* no sudden dark or flash at 3 am */ button.park-link { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; } /* the night fade over the whole screen; taps pass through, and any touch lifts it */
.night-sky { position: absolute; left: 0; right: 0; top: 0; width: 100%; height: auto; z-index: -1; pointer-events: none; } .night-sky .tw { animation: twinkle 9s ease-in-out infinite; } @keyframes twinkle { 50% { opacity: .2; } } @media (prefers-reduced-motion: reduce) { .night-sky .tw { animation: none; } } /* the 3 am sky, behind the Wave at rest and while it breathes */
body.night-dim :is(.wave-foot, nav#tabs) { filter: brightness(.8); transition: filter 140s linear; } body :is(.wave-foot, nav#tabs) { transition: filter 1.5s; } /* the foot and the Wave tab dim with the orb, so nothing outshines the ember */
button.block:disabled { opacity: .6; background: color-mix(in srgb, var(--muted) 12%, transparent); border: 1px solid transparent; color: var(--muted); box-shadow: none; cursor: not-allowed; } /* a full-width button waiting for input reads as waiting, not as ready */
.parked-line { margin: 4px 2px 14px; } .parked-line a { display: flex; align-items: center; gap: 8px; min-height: 44px; color: var(--ink); text-decoration: none; } .parked-line a span { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: var(--muted); } .date-card p.small > a:only-child { display: inline-flex; align-items: center; min-height: 44px; } .hero-state a { color: inherit; text-decoration: underline; text-underline-offset: 3px; display: inline-flex; align-items: center; gap: 6px; min-height: 44px; } html.night-dark nav#tabs a.wave-tab, body.night-dim nav#tabs a.wave-tab { background: color-mix(in srgb, var(--dawn) 35%, var(--card)); color: var(--ink); box-shadow: none; } /* the Wave tab no longer outshines the ember */ .parked-line .ic { color: var(--warm-ink, var(--dawn)); flex: none; } /* last night's thought, one quiet line on Today until the check-in brings it back */
.guided { margin: 18px 0 0; } h2.ex-h { font-size: 18px; } .guided h2.ex-h { margin: 4px 0 2px; font-size: 19px; } /* card titles under the lesson's h1, styled as before */ .guided .clip.listen { margin: 10px 0 4px; } .transcript summary { display: inline-flex; align-items: center; min-height: 44px; cursor: pointer; color: var(--muted); text-decoration: underline; text-underline-offset: 3px; } .transcript p { font-size: 15px; } /* a guided practice before its exercise, with its words for reading */
/* S5/S6: the light held (the one reaction to "kept"), row vignettes, and the light's pose through the day. One 600 ms eased movement; still under reduced motion. */
@keyframes held { from { opacity: .35; transform: translateY(5px) scale(.92); } }
.held-light { display: inline-block; flex: none; width: 44px; line-height: 0; animation: held .6s var(--ease) both; } .held-light svg { display: block; width: 100%; height: auto; }
#toast .held-light { width: 52px; margin: -10px -2px -12px -10px; background: radial-gradient(closest-side, var(--bg) 62%, transparent); } /* the toast is dark: the light sits on a pale glow so it reads */ .kept-moment .held-light { margin: -8px 0 -8px -6px; } .kept-art svg { animation: held .6s var(--ease) both; }
.row-vig { flex: none; width: 48px; height: 48px; line-height: 0; color: var(--pine); } .row-vig svg { display: block; width: 100%; height: 100%; }
.vig-title { display: flex; align-items: center; gap: 12px; } .vig-row { display: flex; align-items: center; gap: 12px; margin-bottom: 6px; }
.scene.night .firlight.by-tree { width: 34px; height: 34px; margin: 0 8px 6px 0; animation-name: firlight-dim; } @keyframes firlight-dim { 0%, 100% { opacity: .5; } 50% { opacity: .65; } }
.firlight-letter { position: absolute; z-index: 0; right: 212px; bottom: 12px; width: 22px; height: 22px; line-height: 0; color: var(--pine); opacity: .75; pointer-events: none; } .firlight-letter svg { width: 100%; height: 100%; display: block; } @media (max-width: 380px) { .firlight-letter { right: 140px; bottom: 14px; } }
@media (prefers-color-scheme: dark) { #toast .held-light { background: none; } } /* dark: the toast is pale, the light needs no backing */
@media (prefers-reduced-motion: reduce) { .held-light, .kept-art svg { animation: none; } .scene.night .firlight.by-tree { opacity: .6; } }
.scale { gap: 4px; } .scale button { padding-left: 0; padding-right: 0; } .scale button small { font-size: 12px; letter-spacing: -.02em; overflow-wrap: anywhere; } /* "Crushing" fits its tile at 360 px */
.feel-family:has(+ [hidden]) { padding-bottom: 72px; } /* the last feelings clear the sticky Save bar */

.chips .chip[href] { display: inline-flex; align-items: center; text-decoration: none; } /* a link in the pill style (Keep: Prompts, Hard dates) */
.t3 { display: inline-block; margin-bottom: 4px; font: 600 18px/1.2 Fraunces, Georgia, serif; letter-spacing: -.01em; color: var(--ink); } .t3.vig-title { display: flex; margin: 0; } /* a toggle card's title in the h3 style (Settings: Usage counts) */
.links a { color: var(--ink); } .links { margin-bottom: 18px; } /* the footer links read at full ink and clear the tab bar's fade */
.cal-legend + .cal-cap { margin-top: 18px; } /* the key sits between the month and the weekday row */
/* Round 68: the grain filter's svg is out of the flow (it was a 25 px line above everything, a strip over the Path's band); Today at night fills the screen; Keep's two actions read as links with a chevron, not as filters; Share sits with the footer links. */
.art-defs { position: absolute; }
.today-hero.night { min-height: max(312px, calc(100svh - 340px)); }
.kept-check h1 { text-wrap: balance; }
.chips.go { gap: 4px 22px; } .go-link { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; color: var(--pine); font-weight: 600; text-decoration: none; } .go-link .ic { width: 18px; height: 18px; } .go-link .ic:last-child { width: 16px; height: 16px; opacity: .7; }
.links button.link { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; font-weight: 500; color: var(--ink); text-decoration: none; }
.tint.h5 { color: #fffdf8; } @media (prefers-color-scheme: dark) { .tint.h5 { color: #16201c; } } /* Crushing tint: paper text on the clay, ink on the dark theme's pale coral */
/* Round 69: the usage-counts card is a quiet last line on Today; the night hero sits close under the strip; Me names the stage as a caption; Dates asks the kind first; Help now is one centred link on every onboarding step; the note dot has a key; 3 am sits apart from the durations. */
#ua-card { background: var(--sage-soft); border-color: transparent; box-shadow: none; padding: 12px 16px 2px; margin: 12px 0 4px; } /* a soft tinted note, like First days */ #ua-card p { font-size: 13px; line-height: 1.4; margin: 0; } #ua-card .row { gap: 22px; } #ua-card button.link { display: inline-flex; align-items: center; min-height: 44px; font-size: 14px; }
.today-hero.night { min-height: 312px; }
.for-today .row-link > .ic.lead { flex: none; width: 20px; height: 20px; color: var(--muted); align-self: flex-start; margin-top: 3px; }
.tree-card .stage { margin: 0 auto; max-width: none; } .scene.me-scene { padding-bottom: 8px; } .me-scene + .plain { margin-top: -14px; } .me-scene + .plain + .plain { margin-top: 0; } .me-scene + .plain + .plain > .row-link:first-child { border-top: 1px solid var(--line); } /* with no counters the Mum row and the list below read as one list */
#dk + .label { margin-top: 16px; }
.help-link { display: flex; align-items: center; justify-content: center; gap: 6px; min-height: 44px; margin-top: 6px; color: var(--pine); font-weight: 600; text-decoration: none; } .step-more { display: flex; justify-content: center; margin-top: 2px; }
.cal-legend { grid-template-columns: repeat(6, 1fr); } .cal-legend .noted { position: static; display: block; width: 8px; height: 8px; margin: 2px 0; border-radius: 50%; background: var(--pine); box-shadow: 0 0 0 1.5px var(--card), 0 0 0 2.5px var(--line); } .cal-legend > span[role=img] { display: flex; flex-direction: column; align-items: center; gap: 4px; justify-content: flex-start; }
.cal-cap.hint { text-decoration: none; } .cal-cap.hint .nw { text-decoration: underline; text-underline-offset: 3px; }
.patterns .chip[data-p="box"] { margin-left: 8px; position: relative; } .patterns .chip[data-p="box"]::before { content: ""; position: absolute; left: -8px; top: 22%; bottom: 22%; border-left: 1.5px solid var(--line); } /* the lengths first, then Box and 3 am apart: 3 am is a kind of breath, not a time */
.scene.night .tree-sun, .scene.night .tree-birds { display: none; } /* the night forest has no day sun disc and no birds; the sky shows its crescent */ @media (prefers-color-scheme: dark) { .tree-sun { opacity: .85; } } /* half a peach over the dark hills turned brown: the disc stays peach */
h3.section:has(#add-h) .ic { margin-right: 0; }

/* Round 72: the illustrated places. Tab art 28 px (inactive muted, active full colour), create tiles and row badges carry their own backdrop, grounds end flat blocks. */
.tab-art { display: block; width: 28px; height: 28px; line-height: 0; transition: transform .2s var(--ease), filter .2s, opacity .2s; } .tab-art svg { display: block; width: 100%; height: 100%; }
nav#tabs a:not(.on):not(.wave-tab) .tab-art { opacity: .62; } /* colour kept: greyed out, the small drawings lost their shape */ nav#tabs a.on .tab-art { transform: translateY(-1px); }
nav#tabs a.wave-tab { position: relative; padding: 6px 16px 5px; } nav#tabs a.wave-tab .tab-art { color: #2a1a10; } html.night-dark nav#tabs a.wave-tab .tab-art, body.night-dim nav#tabs a.wave-tab .tab-art { color: var(--ink); }
.tile.mini .tile-art { display: block; width: 60px; height: 60px; margin: 0 auto 6px; line-height: 0; } .tile.mini .tile-art svg { display: block; width: 100%; height: 100%; } .tile.mini { padding-top: 12px; }
.row-art { display: block; flex: none; width: 40px; height: 40px; line-height: 0; } .row-art svg { display: block; width: 100%; height: 100%; }
.for-today .row-link > .row-art.lead-art { width: 32px; height: 32px; align-self: flex-start; margin-top: -2px; }
.ground { line-height: 0; pointer-events: none; } .ground svg { display: block; width: 100%; height: 60px; }
.path-head .ground { margin: 6px -20px -18px; }
.card.empty { overflow: hidden; } .card.empty .ground { margin: 18px -18px -22px; } .card.empty .ground svg { height: 60px; }
/* Today ends on a low strip of land right under its last module, fading out below */
.ground.land { margin: 8px -16px 0; --land: var(--art-mid); } .ground.land.night { --land: var(--art-dark); } .ground.land::after { content: ''; display: block; height: 44px; margin-top: -1px; background: linear-gradient(var(--land), transparent); }
body:has(.ground.land) nav#tabs::before { display: none; }

/* Round 73 */
@media (prefers-color-scheme: dark) { .ground:not(.night) { --art-light: var(--art-soft); --art-mid: #2a463c; } } /* grounds on the dark screens sit on night values, darker than the band they end (the night hills keep their own) */
:root { --h1-edge: #6a907d; } @media (prefers-color-scheme: dark) { :root { --h1-edge: #56786a; } } /* Light is a pale tint: a 1 px edge in its own hue carries the 3:1 (3.5:1 on the cream card, 3.3:1 on the dark one) */
.h1.cal-cell, .cal-legend i.h1, .tint.h1 { outline: 1px solid var(--h1-edge); outline-offset: -1px; } .weight.h1 { outline: 1px solid var(--h1-edge); } .strip i { outline: 1px solid color-mix(in srgb, var(--h1-edge) 85%, var(--ink)); outline-offset: -1px; } /* every bar, and the empty stub, keeps 3:1 on the Today sky by its edge (3.7:1 light, 4.3:1 dark); the gold and orange fills alone were 1.9-2.3:1 on the light sky (r78) */
html.night-dark nav#tabs a.wave-tab, body.night-dim nav#tabs a.wave-tab { background: #8a4527; color: #fbe9d8; box-shadow: inset 0 0 0 1.5px #c0703f, 0 0 16px rgba(192,112,63,.3); } html.night-dark nav#tabs a.wave-tab .tab-art, body.night-dim nav#tabs a.wave-tab .tab-art { color: #fbe9d8; } /* the dimmed Wave tab is a deep ember, not a grey-brown disc: cream on it 6:1, its edge 4.3:1 on the bar */
nav#tabs a.wave-tab[aria-current=page] { box-shadow: 0 0 0 2px var(--bg), 0 0 0 4px var(--pine), 0 6px 20px rgba(233,179,140,.5); transform: scale(1.06); } html.night-dark nav#tabs a.wave-tab[aria-current=page], body.night-dim nav#tabs a.wave-tab[aria-current=page] { box-shadow: inset 0 0 0 1.5px #c0703f, 0 0 0 2px var(--bg), 0 0 0 4px var(--pine), 0 0 16px rgba(192,112,63,.3); } nav#tabs a.wave-tab[aria-current=page]:active { transform: scale(1); } @media (prefers-reduced-motion: reduce) { nav#tabs a.wave-tab[aria-current=page] { transform: none; transition: none; } } /* the Wave tab selected: a 2 px ring, offset, and a touch larger (ring only under reduced motion) */
.firlight.by-tree { width: 64px; height: 64px; right: 160px; bottom: 6px; } .firlight.by-tree::before { content: ''; position: absolute; inset: -14px; border-radius: 50%; background: radial-gradient(closest-side, color-mix(in srgb, var(--art-sun) 50%, transparent), color-mix(in srgb, var(--art-sun) 16%, transparent) 62%, transparent); } @media (max-width: 380px) { .firlight.by-tree { right: 86px; } } .scene.night .firlight.by-tree { width: 52px; height: 52px; margin: 0; right: 166px; bottom: 8px; } .scene.night .firlight.by-tree::before { inset: -10px; background: radial-gradient(closest-side, color-mix(in srgb, var(--art-sun) 26%, transparent), transparent); } @media (max-width: 380px) { .scene.night .firlight.by-tree { right: 92px; } } /* Today's light is a little larger with its own soft halo, like the lantern on Path, so it reads as the light and not a speck */
.go-link .row-art { width: 32px; height: 32px; } .lesson > .row-art { width: 40px; height: 40px; } .list-item.date-row > .row-art { align-self: flex-start; } /* one badge family in the Keep links, First days and Hard dates rows */
@media (prefers-color-scheme: dark) { .cal-cell.h5, a.cal-cell.h5, .cal.wk .cal-cell.h5, .cal.yr .cal-cell.h5, .tint.h5 { color: #fff3e4; } } /* dark Crushing is a deep clay now (1.8:1 from Very heavy): paper text, 4.7:1 */
.badged { display: flex; gap: 12px; align-items: flex-start; } .badged .grow { flex: 1; min-width: 0; } .badged .grow > p:first-child { margin: 0 0 2px; }
.next-read { display: block; margin-left: 46px; } a.card.entry .kind { gap: 8px; } a.card.entry .kind .row-art { width: 32px; height: 32px; } @media (prefers-color-scheme: dark) { a.card.entry .row-art[style*="--hv"] { --art-dark: var(--h1-edge); --hve: var(--h1-edge); } } /* dark: the check-in badge's hill and base keep 3:1 on the card (3.3:1) */ a.card.entry h3.words { margin: 10px 0 0; white-space: pre-wrap; }
main:has(> .ground.land.night) { display: flex; flex-direction: column; min-height: 100svh; padding-bottom: 0; } main:has(> .ground.land.night) > .ground.land.night { flex: 1; display: flex; flex-direction: column; margin-top: 4px; } .ground.land.night::after { flex: 1; min-height: calc(132px + env(safe-area-inset-bottom)); background: linear-gradient(var(--land), color-mix(in srgb, var(--land) 45%, var(--bg)) 30%, var(--bg) 80%); } /* night Today: the land comes up under the prompt and sinks into the night below, no bright slab */ .night-date { display: flex; align-items: center; gap: 8px; min-height: 44px; margin: 0 0 0 46px; color: var(--pine); } .night-date span { text-decoration: underline; text-underline-offset: 3px; } /* the next hard date, quiet under the night prompt */
.save-bar.plan-bar { bottom: calc(94px + env(safe-area-inset-bottom)); } .save-bar.plan-bar::after { height: 72px; } main:has(.plan-bar) { padding-bottom: 180px; } /* 16 px above the Wave orb */
.segs { display: flex; flex-wrap: wrap; column-gap: 13px; overflow: hidden; } .segs .seg { position: relative; white-space: nowrap; } .segs .seg ~ .seg::before { content: "\00b7" / ""; position: absolute; left: -9px; } /* a date row's parts never end a line on a stray dot: the dot leading a wrapped line is clipped */
