/* Haven's life (5.56): the motion the owner chose in the motion lab (mockups/7.4-motion-lab), nothing else.
 * Three levels on <html data-motion>: "alive" is all of it, "calm" is only what answers a touch (nothing moves on
 * its own), "still" is none. The phone's own reduce-motion setting wins over all three (the ambient rules below sit
 * inside prefers-reduced-motion: no-preference, and js/haven-motion.js treats it as "still").
 * Only transforms and opacity move, so none of it costs a repaint of the page. Haven only: the other looks are untouched. */

/* ---- the sky follows the hour: js/haven-motion.js sets --hv-sky-live ---- */
:root[data-style="haven"][data-sky-live] body::before { background: linear-gradient(180deg, var(--hv-sky-live) 0, var(--hv-paper) 100%); }

/* ---- the tide: it breathes, its edge glows, the mood sets the pace (alive) ---- */
@media (prefers-reduced-motion: no-preference) {
  :root[data-style="haven"][data-motion="alive"] .tide { --hv-pace: 1; }
  :root[data-style="haven"][data-motion="alive"] .tide[data-mood="watch"] { --hv-pace: 0.8; }
  :root[data-style="haven"][data-motion="alive"] .tide[data-mood="low"] { --hv-pace: 0.6; }
  :root[data-style="haven"][data-motion="alive"] .tide .swell { animation: hv-breath calc(6.5s * var(--hv-pace, 1) * var(--hv-doze, 1)) ease-in-out infinite; }
  :root[data-style="haven"][data-motion="alive"] .tide .wave { animation-duration: calc(7s * var(--hv-doze, 1)); }
  :root[data-style="haven"][data-motion="alive"] .tide .wave.b { animation-duration: calc(11s * var(--hv-doze, 1)); }
  :root[data-style="haven"][data-motion="alive"] .tide .sh-glow { animation: hv-edge calc(6.5s * var(--hv-pace, 1) * var(--hv-doze, 1)) ease-in-out infinite; }
  /* "Almost out": the edge pulses softly, red and never a flash. */
  :root[data-style="haven"][data-motion="alive"] .tide[data-mood="low"] .sh-glow { stroke: oklch(66% 0.2 27); animation: hv-lowpulse 2.5s ease-in-out infinite; }
}
:root[data-style="haven"] .tide .sh-glow { fill: none; stroke: var(--hv-tide-b); stroke-width: 5; stroke-linejoin: round; opacity: 0; }
@keyframes hv-breath { 50% { transform: translateY(0.7px); } }
@keyframes hv-edge { 50% { opacity: 0.25; } }
@keyframes hv-lowpulse { 50% { opacity: 0.5; } }

/* ---- icons catch the light, one at a time (alive) ---- */
:root[data-style="haven"] .hv-gem { overflow: hidden; }
:root[data-style="haven"] .hv-gem.shine::after {
  content: ""; position: absolute; inset: 0; pointer-events: none; transform: translateX(-120%);
  background: linear-gradient(110deg, transparent 30%, oklch(100% 0 0 / calc(0.8 * var(--s, 0.3))) 50%, transparent 70%);
  animation: hv-sheen 900ms ease-out forwards;
}
@keyframes hv-sheen { to { transform: translateX(120%); } }

/* ---- it dozes when left alone: dimmer, slower, and a small stretch when touched (alive) ---- */
.hv-doze { position: fixed; inset: 0; z-index: 38; pointer-events: none; background: oklch(0% 0 0); opacity: 0; transition: opacity 800ms ease; }
:root[data-style="haven"][data-motion="alive"][data-dozing] { --hv-doze: 2; }
:root[data-style="haven"][data-motion="alive"][data-dozing] .hv-doze { opacity: 0.14; }
:root[data-style="haven"] .hv-vault.hv-wake { animation: hv-wake 520ms var(--hv-spring-soft, ease-out); }
@keyframes hv-wake { 40% { transform: scale(1.035); } }

/* ---- pressing: a card sinks 6% and springs back; a ripple spreads from the touch (alive and calm) ---- */
:root[data-style="haven"]:not([data-motion="still"]) :is(.hv-chip, button.hv-row, .hv-row[data-hv-go], .hv-bill__open, button.hv-note, .hv-sum__keys button) {
  position: relative; overflow: clip; transition: transform 500ms var(--hv-spring-snap), background var(--hv-d-fast) var(--hv-ease-out);
}
:root[data-style="haven"]:not([data-motion="still"]) .hv-down { transform: scale(0.94); transition: transform 120ms ease-out; }
.hv-rip { position: absolute; width: 10px; height: 10px; margin: -5px; border-radius: 50%; background: var(--hv-link, currentColor); opacity: 0.28; pointer-events: none; animation: hv-ripple 700ms ease-out forwards; }
@keyframes hv-ripple { to { transform: scale(34); opacity: 0; } }

/* ---- holding a row lifts it off the page (alive and calm) ---- */
:root[data-style="haven"] .hv-lifts { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
:root[data-style="haven"]:not([data-motion="still"]) .hv-lifted {
  transform: translateY(-5px) scale(1.025) !important; border-radius: 22px; position: relative; z-index: 3; background: var(--hv-core, inherit);
  box-shadow: 0 20px 40px -8px oklch(22% 0.08 266 / 0.5), 0 0 0 1px var(--hv-hair) !important; transition: transform 420ms var(--hv-spring-snap), box-shadow 300ms !important;
}
:root[data-style="haven"] :is(.hv-core, .hv-clist, .hv-shell):has(.hv-lifted, .hv-swiping) { overflow: visible; }

/* ---- swiping a bill: right marks it paid, left skips it; it stretches like elastic ---- */
:root[data-style="haven"] .hv-bill[data-kind="topay"] { touch-action: pan-y; }
:root[data-style="haven"] .hv-swbg { position: absolute; left: 0; right: 0; z-index: 0; display: flex; align-items: center; padding: 0 22px; font-weight: 650; font-size: var(--hv-fs-label, 13px); color: #fff; pointer-events: none; }
:root[data-style="haven"] .hv-swbg.pay { background: var(--hv-good); justify-content: flex-start; }
:root[data-style="haven"] .hv-swbg.skip { background: var(--hv-warn); justify-content: flex-end; }
:root[data-style="haven"] .hv-bill.hv-swiping { position: relative; z-index: 1; background: var(--hv-core, inherit); }
:root[data-style="haven"] .hv-clist { position: relative; }

/* ---- marking paid: the row fades away, the bar above slides across ---- */
:root[data-style="haven"] .hv-bill.hv-fading { opacity: 0; transition: opacity 700ms var(--hv-ease-settle); pointer-events: none; }
:root[data-style="haven"]:not([data-motion="still"]) .hv-sum__bar i { transition: flex-grow 700ms var(--hv-spring-soft, ease), opacity var(--hv-d-base) var(--hv-ease-settle); }

/* ---- a payment lands in the shield; a month closed under budget glows once ---- */
.hv-coin {
  position: absolute; left: 50%; top: 0; z-index: 3; width: 22px; height: 22px; margin-left: -11px; border-radius: 50%; pointer-events: none;
  display: grid; place-items: center; font: 700 12px var(--hv-font, inherit); color: #7a4a05;
  background: radial-gradient(circle at 35% 30%, #ffe9a8, #e0a21b); box-shadow: 0 0 0 2px #b9780f inset;
}
.hv-drain { position: absolute; left: 50%; top: 0; z-index: 4; padding: 2px 9px; border-radius: 999px; font: 700 13px var(--hv-font, inherit); font-style: normal; white-space: nowrap; pointer-events: none;
  color: oklch(100% 0 0); background: oklch(30% 0.07 255 / 0.88); box-shadow: 0 0 0 1px oklch(100% 0 0 / 0.25); }
.hv-drain.is-up { background: oklch(42% 0.12 158 / 0.92); }
.hv-ring { position: absolute; left: 50%; z-index: 3; width: 14px; height: 14px; margin: -7px; border-radius: 50%; border: 2px solid oklch(100% 0 0 / 0.75); pointer-events: none; }
/* the steam is cut to the shield's own outline, so it never leaves it */
:root[data-style="haven"] .tide .hv-steam svg { width: 8px; height: 11px; overflow: visible; }
.hv-steam { position: absolute; inset: 0; clip-path: polygon(50% 5%, 94% 16%, 94% 47%, 85% 70%, 50% 94%, 15% 70%, 6% 47%, 6% 16%); pointer-events: none; z-index: 3; }
.hv-spark { position: absolute; z-index: 3; width: 5px; height: 5px; border-radius: 50%; background: #bff3ff; pointer-events: none; }
:root[data-style="haven"] .hv-vault.hv-glowing { animation: hv-closed 2400ms ease-in-out; }
@keyframes hv-closed { 50% { box-shadow: inset 0 1px 0 oklch(100% 0 0 / 0.2), 0 0 28px 4px oklch(85% 0.12 205 / 0.55); } }

/* ---- the figure follows you: a slim bar once the vault has scrolled away ---- */
.hv-mini {
  position: fixed; left: 14px; right: 14px; z-index: 31; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  height: 52px; padding: 0 18px; border-radius: 999px; background: var(--hv-core, #fff); box-shadow: 0 0 0 1px var(--hv-hair), 0 14px 26px -14px var(--hv-sh-4, rgb(0 0 0 / 0.4));
  opacity: 0; transform: translateY(-14px) scale(0.96); pointer-events: none; transition: opacity 260ms ease, transform 420ms var(--hv-spring-snap);
}
.hv-mini.on { opacity: 1; transform: none; pointer-events: auto; }
.hv-mini span { font-size: var(--hv-fs-label, 13px); color: var(--hv-ink-3); }
.hv-mini b { font-size: 22px; font-weight: 650; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; color: var(--hv-ink); }
.hv-mini i { position: absolute; left: 18px; right: 18px; bottom: 6px; height: 3px; border-radius: 2px; background: var(--hv-well); overflow: hidden; }
.hv-mini i::after { content: ""; position: absolute; inset: 0; transform-origin: left; transform: scaleX(var(--p, 0)); background: linear-gradient(90deg, var(--hv-tide-a), var(--hv-tide-b)); border-radius: 2px; }

/* ---- pull to refresh: a rising tide instead of the spinner ---- */
:root[data-style="haven"]:not([data-motion="still"]) .ptr { display: none; }
.hv-ptr { position: fixed; left: 0; right: 0; bottom: 0; z-index: 29; height: 0; overflow: hidden; pointer-events: none; }
.hv-ptr svg { position: absolute; left: 0; bottom: 0; width: 100%; height: 100%; }
.hv-ptr path { fill: color-mix(in oklab, var(--hv-tide-b, #4cc) 40%, transparent); }

/* ---- the undo toast counts down in a ring ---- */
@property --a { syntax: "<angle>"; inherits: false; initial-value: 360deg; }
:root[data-style="haven"]:not([data-motion="still"]) .toast--action .toast__bar {
  position: static; display: inline-block; vertical-align: middle; width: 22px; height: 22px; margin-left: 10px; border-radius: 50%; transform: none;
  background: conic-gradient(currentColor var(--a), color-mix(in oklab, currentColor 25%, transparent) 0);
  -webkit-mask: radial-gradient(circle 8px at center, transparent 97%, #000 100%); mask: radial-gradient(circle 8px at center, transparent 97%, #000 100%);
  animation-name: hv-ring; animation-timing-function: linear; animation-fill-mode: forwards;
}
@keyframes hv-ring { from { --a: 360deg; } to { --a: 0deg; } }

/* ---- loading placeholders pulse once a second; screens arrive in a cascade ---- */
:root[data-style="haven"]:not([data-motion="still"]) .view-skeleton .sk { background-image: none; animation: hv-skpulse 1s ease-in-out infinite; }
@keyframes hv-skpulse { 0%, 100% { opacity: 0.5; } 50% { opacity: 1; } }
:root[data-style="haven"]:not([data-motion="still"]) .hv-screen.enter .hv-rise { animation: hv-rise2 400ms var(--hv-ease-out) calc(var(--i, 0) * 90ms) both; }
@keyframes hv-rise2 { from { opacity: 0; transform: translateY(20px) scale(0.985); filter: blur(4px); } to { opacity: 1; transform: none; filter: blur(0); } }
/* Over a screen change (.hv-vt-screen, js/app.js) the cross-fade already brings the screen in: the blocks only rise 12 px, never from opacity 0 or blurred. */
@keyframes hv-rise3 { from { opacity: 1; transform: translateY(12px); } to { opacity: 1; transform: none; } }
:root[data-style="haven"]:not([data-motion="still"]) .hv-vt-screen .hv-screen.enter .hv-rise { animation: hv-rise3 360ms var(--hv-ease-out) calc(var(--i, 0) * 50ms) both; }

/* "Still", or a phone set to reduce motion: the effects that are drawn by script are not drawn. */
@media (prefers-reduced-motion: reduce) { .hv-rip, .hv-coin, .hv-drain, .hv-ring, .hv-spark, .hv-ptr { display: none; } }
:root[data-style="haven"][data-motion="still"] :is(.hv-rip, .hv-coin, .hv-drain, .hv-ring, .hv-spark, .hv-ptr, .hv-doze) { display: none; }


/* ================================================================== lab 2 (5.58) */
/* ---- what fills the shield (Settings -> Motion's neighbour); low money still turns warm ---- */
:root[data-style="haven"][data-liquid="chai"] .tide[data-mood="calm"] { --hv-tide-a: oklch(46% 0.09 55); --hv-tide-b: oklch(68% 0.11 70); }
:root[data-style="haven"][data-liquid="gold"] .tide[data-mood="calm"] { --hv-tide-a: oklch(58% 0.13 80); --hv-tide-b: oklch(84% 0.14 95); }
:root[data-style="haven"][data-liquid="sunset"] .tide[data-mood="calm"] { --hv-tide-a: oklch(56% 0.2 20); --hv-tide-b: oklch(78% 0.15 55); }
:root[data-style="haven"][data-liquid="mint"] .tide[data-mood="calm"] { --hv-tide-a: oklch(52% 0.12 170); --hv-tide-b: oklch(80% 0.13 165); }

/* ---- days ahead of pace: a small chip in the vault's top row ---- */
:root[data-style="haven"] .hv-streak { display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 10px 0 7px; border-radius: 999px; background: oklch(100% 0 0 / 0.14); font-size: 12px; font-weight: 650; color: var(--hv-on-navy); margin-inline-end: auto; }
/* ---- the evening note and the "Hidden" word share one quiet line under the figure ---- */
:root[data-style="haven"] .hv-vault__eve { min-height: 16px; margin-top: 4px; font-size: var(--hv-fs-label, 13px); color: var(--hv-on-navy-2); }
:root[data-style="haven"] .hv-vault__eve:empty { min-height: 0; margin: 0; }
/* ---- double-tap the figure: it blurs ---- */
:root[data-style="haven"][data-hide-fig] .hv-vault__fig .hv-fig { filter: blur(14px); opacity: 0.85; }
:root[data-style="haven"] .hv-vault__fig .hv-fig { transition: filter 360ms var(--hv-ease-settle), opacity 360ms var(--hv-ease-settle); }

/* ---- pull down: yesterday waits in the gap above the screen ---- */
:root[data-style="haven"] :is(#view-container, .view-still) { position: relative; }
:root[data-style="haven"] .hv-peek {
  position: absolute; left: 0; right: 0; top: -34px; height: 28px; display: flex; align-items: center; justify-content: space-between; padding: 0 22px;
  font-size: var(--hv-fs-label, 13px); color: var(--hv-ink-2); opacity: var(--peek, 0); pointer-events: none; visibility: hidden; transition: opacity 200ms ease, visibility 0s linear 200ms;
}
:root[data-style="haven"] .hv-peek.on { visibility: visible; transition-delay: 0s; }
:root[data-style="haven"] .hv-peek b { color: var(--hv-ink); font-weight: 650; }
:root[data-style="haven"][data-motion="still"] .hv-peek { display: none; }

/* ---- a bill is near: a dot on the Plan tab ---- */
:root[data-style="haven"] #tabs .nav-btn[data-view="plan"] { position: relative; }
.hv-dot { position: absolute; top: 9px; right: calc(50% - 20px); width: 9px; height: 9px; border-radius: 50%; background: var(--hv-bad, #e0574f); box-shadow: 0 0 0 2px var(--hv-bar-bg, #fff); pointer-events: none; }
@media (prefers-reduced-motion: no-preference) {
  :root[data-style="haven"]:not([data-motion="still"]) .hv-dot { animation: hv-dotpulse 1.5s ease-out infinite; }
}
@keyframes hv-dotpulse { 0% { box-shadow: 0 0 0 2px var(--hv-bar-bg, #fff), 0 0 0 0 oklch(66% 0.2 27 / 0.7); } 100% { box-shadow: 0 0 0 2px var(--hv-bar-bg, #fff), 0 0 0 9px oklch(66% 0.2 27 / 0); } }

/* ---- a salary landed ---- */
.hv-chip-up { position: absolute; left: 50%; top: 78%; z-index: 4; padding: 5px 12px; border-radius: 999px; background: var(--hv-good); color: #fff; font-size: 12px; font-weight: 650; white-space: nowrap; pointer-events: none; }

/* ---- shake: "Undo it?" ---- */
.hv-ask { position: fixed; left: 50%; top: calc(env(safe-area-inset-top, 0px) + 70px); z-index: 60; transform: translate(-50%, -30px); opacity: 0; display: flex; gap: 10px; align-items: center; padding: 10px 12px 10px 16px; border-radius: 18px; background: var(--hv-toast-bg, #1d2a55); color: #fff; font-size: 13px; font-weight: 600; max-width: calc(100vw - 24px); transition: transform 460ms var(--hv-spring-snap), opacity 260ms; }
.hv-ask.on { transform: translate(-50%, 0); opacity: 1; }
.hv-ask span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.hv-ask button { height: 32px; min-width: 44px; padding: 0 12px; border: 0; border-radius: 999px; background: oklch(100% 0 0 / 0.2); color: #fff; font: inherit; font-weight: 650; }

/* ---- goals: a small shield beside each ---- */
:root[data-style="haven"] .hv-goal { width: 100%; text-align: left; grid-template-columns: auto 1fr; }
:root[data-style="haven"] .hv-goal .tide.hv-goal__tide { width: 44px; height: 54px; flex: none; }

/* ---- the chart: last month, faint, while pressed ---- */
.waves__ghost { fill: none; stroke: var(--hv-ink-3, #889); stroke-width: 2.2; stroke-dasharray: 3 5; stroke-linecap: round; opacity: 0; transition: opacity 500ms; pointer-events: none; }
.waves__ghost-t { font-size: 10px; fill: var(--hv-ink-3, #889); opacity: 0; transition: opacity 500ms; pointer-events: none; }
.hv-ghost-on .waves__ghost { opacity: 0.8; }
.hv-ghost-on .waves__ghost-t { opacity: 1; }

/* ---- the setup card: the shield fills as the steps are done ---- */
:root[data-style="haven"] .setup-card__top { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
:root[data-style="haven"] .hv-setup__tide { width: 52px; height: 64px; flex: none; position: relative; }
:root[data-style="haven"] .setup-card .setup-progress { display: none; }

/* ================================================================== lab 3 (5.60): js/haven-life.js */
/* ---- a limit kept by hand, and the one being tried ---- */
:root[data-style="haven"] .hv-vault__cap { margin-top: 3px; font-size: var(--hv-fs-label, 13px); color: var(--hv-on-navy-2); }
:root[data-style="haven"] .hv-vault__cap b { color: var(--hv-on-navy); font-weight: 600; cursor: pointer; text-decoration: underline dotted; }
:root[data-style="haven"] .hv-keepcap { margin-top: 8px; height: 32px; padding: 0 14px; border: 0; border-radius: 999px; background: oklch(100% 0 0 / 0.2); color: var(--hv-on-navy); font: inherit; font-size: 13px; font-weight: 650; }
:root[data-style="haven"] .hv-keepcap[hidden] { display: none; }
:root[data-style="haven"] .hv-vault .tide { cursor: ns-resize; }
/* ---- a quiet month: the shield sleeps ---- */
:root[data-style="haven"] .hv-vault__sleep { margin-top: 4px; font-size: var(--hv-fs-label, 13px); color: var(--hv-on-navy-2); }
.hv-z { position: absolute; left: 58%; top: 26%; z-index: 3; font: 700 14px var(--hv-font, inherit); color: var(--hv-on-navy, #fff); opacity: 0; pointer-events: none; }
.hv-sleep { position: relative; width: 52px; height: 64px; margin: 0 auto 8px; }
/* ---- small badges ---- */
:root[data-style="haven"] .hv-medal { display: inline-grid; place-items: center; width: 26px; height: 26px; border-radius: 50%; background: oklch(100% 0 0 / 0.14); overflow: hidden; position: relative; }
:root[data-style="haven"] .hv-medal.is-new::after { content: ""; position: absolute; inset: 0; background: linear-gradient(110deg, transparent 30%, rgba(255, 255, 255, 0.7) 50%, transparent 70%); transform: translateX(-120%); animation: hv-sheen 900ms ease-out 500ms forwards; }
/* ---- the Sunday card ---- */
.hv-recap { position: fixed; left: 14px; right: 14px; bottom: calc(96px + env(safe-area-inset-bottom, 0px)); z-index: 36; max-width: 480px; margin: 0 auto; padding: 14px 16px; border-radius: 24px; background: linear-gradient(180deg, var(--hv-core), var(--hv-core-2)); box-shadow: 0 0 0 1px var(--hv-hair), var(--hv-lift); display: grid; gap: 8px; color: var(--hv-ink); }
.hv-recap__h { display: flex; justify-content: space-between; align-items: baseline; }
.hv-recap__h b { font-size: 15px; }
.hv-recap__h span { font-size: 12px; color: var(--hv-ink-3); }
.hv-recap__fig { font-size: 26px; font-weight: 650; letter-spacing: -0.03em; }
.hv-recap__fig small { font-size: 13px; font-weight: 500; color: var(--hv-ink-2); letter-spacing: 0; }
.hv-recap__bars { display: flex; gap: 5px; align-items: flex-end; height: 44px; }
.hv-recap__bars i { flex: 1; border-radius: 5px; background: var(--hv-tide-b); transform-origin: bottom; }
.hv-recap__bars i.big { background: var(--hv-warn); }
.hv-recap__f { font-size: 13px; color: var(--hv-ink-2); }
/* ---- the month told in cards ---- */
.hv-story { position: fixed; inset: 0; z-index: 70; display: grid; place-items: center; background: oklch(18% 0.06 266 / 0.55); backdrop-filter: blur(6px); }
.hv-story__card { width: min(280px, 80vw); min-height: 180px; border-radius: 28px; padding: 22px; display: grid; align-content: center; gap: 6px; background: var(--hv-vault); background-color: #11234f; color: #fff; box-shadow: var(--hv-lift-hero); position: relative; }
.hv-story__a { font-size: 13px; color: var(--hv-on-navy-2); }
.hv-story__b { font-size: 32px; font-weight: 650; letter-spacing: -0.03em; line-height: 1.05; }
.hv-story__d { font-size: 14px; color: var(--hv-on-navy-2); }
.hv-story__dots { position: absolute; left: 0; right: 0; bottom: 18%; display: flex; gap: 5px; justify-content: center; }
.hv-story__dots i { width: 6px; height: 6px; border-radius: 3px; background: oklch(100% 0 0 / 0.4); transition: width 300ms var(--hv-spring-snap); }
.hv-story__dots i.on { width: 18px; background: #fff; }
/* ---- the month as a patch of colour ---- */
.hv-cal__w, .hv-cal__g { display: grid; grid-template-columns: repeat(7, 1fr); gap: 5px; }
.hv-cal__w span { text-align: center; font-size: 11px; color: var(--hv-ink-3); }
.hv-cal__g { margin-top: 6px; }
.hv-cal__g i.blank { height: 38px; }
.hv-cal__d { display: grid; place-items: center; height: 38px; border: 0; border-radius: 10px; font-size: 11px; color: var(--hv-ink-2); background: color-mix(in oklab, var(--hv-tide-b) calc(15% + var(--k, 0) * 80%), var(--hv-well)); box-shadow: inset 0 0 0 1px var(--hv-hair); transition: transform 360ms var(--hv-spring-snap), box-shadow 300ms; }
.hv-cal__d.lift { transform: translateY(-5px) scale(1.12); box-shadow: 0 10px 18px -6px var(--hv-sh-3), inset 0 0 0 1px var(--hv-hair-strong); position: relative; z-index: 2; }
.hv-cal__t { margin-top: 8px; min-height: 18px; font-size: 13px; color: var(--hv-ink-2); text-align: center; }
/* ---- a payment row that opens into itself ---- */
:root[data-style="haven"] .hv-lp + .hv-lp { box-shadow: inset 0 1px 0 var(--hv-hair); }
:root[data-style="haven"] .hv-lp > .hv-row { width: 100%; box-shadow: none; }
.hv-lp__d { height: 0; overflow: hidden; }
.hv-lp__in { padding: 0 16px 14px 74px; display: grid; gap: 6px; font-size: 13px; color: var(--hv-ink-2); justify-items: start; }
.hv-lp__in b { color: var(--hv-ink); font-weight: 600; }
.hv-lp__in .hv-pillbtn { margin-top: 2px; }
/* ---- a category near its limit: a thin ring goes out from its icon now and then ---- */
.hv-ringout { position: absolute; inset: -2px; border-radius: inherit; border: 2px solid var(--hv-warn); pointer-events: none; }
:root[data-style="haven"] .hv-bill[data-near] .hv-gem { overflow: visible; }
/* ---- the Add keypad ---- */
:root[data-style="haven"] .hv-words { min-height: 20px; margin-top: 6px; text-align: center; font-size: var(--hv-fs-label, 13px); color: var(--hv-ink-2); }
:root[data-style="haven"] .hv-words.warn { color: var(--hv-warn); }
:root[data-style="haven"] .hv-amountbig .val, :root[data-style="haven"] .hv-addform .hv-amountbig .val { font-size: calc(54px * var(--fit, 1)); }
.hist-guess { color: var(--hv-ink-2); margin-left: 6px; }
.hist-guess b { color: var(--hv-link); font-weight: 600; }
:root[data-style="haven"] .hist-row[data-swipe="ready"] { background: color-mix(in oklab, var(--hv-good) 22%, transparent); }
:root[data-style="haven"] .hist-row[data-swipe="pulling"] { background: color-mix(in oklab, var(--hv-good) 10%, transparent); }
.hv-fly { position: fixed; z-index: 60; font: 650 20px var(--hv-font, inherit); color: var(--hv-ink); pointer-events: none; }

/* ---- the chart takes no frame from a tap (the keyboard still shows where it is) ---- */
svg.waves { outline: none; -webkit-tap-highlight-color: transparent; }
svg.waves:focus-visible:not(.by-pointer) { outline: 2px solid var(--hv-link, currentColor); outline-offset: 2px; border-radius: 12px; }

/* ================================================================== Settings, compact (5.63) */
/* The version and the update check: one line at the very top. */
:root[data-style="haven"] .version-line { display: flex; justify-content: space-between; align-items: center; gap: 10px; margin: 0 4px 8px; padding: 0; border: 0; font-size: 13px; color: var(--hv-ink-2); }
:root[data-style="haven"] .version-line b, :root[data-style="haven"] #version-text { font-weight: 650; color: var(--hv-ink); }
:root[data-style="haven"] .version-note { margin-left: 6px; color: var(--hv-ink-3); }
:root[data-style="haven"] .version-note.stale { color: var(--hv-warn); font-weight: 650; }
:root[data-style="haven"] .version-line .icon-btn { height: 34px; padding: 0 12px; border-radius: 999px; background: var(--hv-well); box-shadow: inset 0 0 0 1px var(--hv-hair); color: var(--hv-ink); font-size: 12.5px; font-weight: 600; width: auto; min-height: 44px; }
/* Your data's shield: a small shield with a lock, calm green, amber when it has been a week. */
.hv-safe { display: grid; grid-template-columns: auto 1fr auto; align-items: center; gap: 12px; padding: 10px 12px; margin-bottom: 8px; border-radius: 20px; background: linear-gradient(180deg, var(--hv-core), var(--hv-core-2)); box-shadow: 0 0 0 1px var(--hv-hair), var(--hv-lift); }
.hv-safe b { display: block; font-size: 15px; font-weight: 650; letter-spacing: -0.01em; }
.hv-safe span { font-size: 12.5px; color: var(--hv-ink-2); }
.hv-safe__s { fill: color-mix(in oklab, var(--hv-good) 22%, transparent); stroke: var(--hv-good); stroke-width: 1.6; stroke-linejoin: round; }
.hv-safe__l { fill: var(--hv-good); }
.hv-safe__h { stroke: var(--hv-good); stroke-width: 1.6; stroke-linecap: round; }
.hv-safe.is-amber .hv-safe__s { fill: color-mix(in oklab, oklch(78% 0.15 70) 25%, transparent); stroke: oklch(70% 0.15 65); }
.hv-safe.is-amber .hv-safe__l { fill: oklch(70% 0.15 65); }
.hv-safe.is-amber .hv-safe__h { stroke: oklch(70% 0.15 65); }
@media (prefers-reduced-motion: no-preference) {
  :root[data-style="haven"][data-motion="alive"] .hv-safe.is-amber svg { animation: hv-amber 2.2s ease-in-out infinite; }
}
@keyframes hv-amber { 50% { filter: drop-shadow(0 0 8px oklch(78% 0.15 70 / 0.7)); } }
.hv-safe .hv-pillbtn { min-height: 44px; }
/* Fewer pixels for what is only a line or two: the whole Settings screen, tighter. */
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) h3 { margin: 14px 4px 6px; font-size: 14px; letter-spacing: 0; }
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .group-subtitle { display: none; }
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .totals-card { padding: 4px 12px; margin-bottom: 8px; }
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .totals-row { padding: 5px 0; min-height: 0; }
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .backup-row { padding: 8px 0; min-height: 52px; }
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .k-row, :root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .k-switch-row { min-height: 48px; padding-block: 6px; gap: 10px; }
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .k-row__sub, :root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .k-switch-row__sub { font-size: 12px; line-height: 1.25; }
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .k-icon { width: 30px; height: 30px; border-radius: 10px; }
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .k-icon svg { width: 17px; height: 17px; }
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .muted-note { margin: 4px 0; font-size: 12px; }
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .section-fold > summary { min-height: 44px; padding-block: 4px; }
:root[data-style="haven"] :is(#view-container, .view-still):has(.settings-k) .settings-foot { margin-top: 10px; }
/* Add: ways in other than typing, right under the way the money went. */
:root[data-style="haven"] .money-kinds { display: grid; grid-template-columns: repeat(6, 1fr); gap: 6px; }
/* Five ways of being paid: three on the first row, two wider ones below, never one left alone. */
:root[data-style="haven"] .money-kind { grid-column: span 2; }
:root[data-style="haven"] .money-kind:nth-child(n+4) { grid-column: span 3; }
:root[data-style="haven"] .money-kind { min-height: 44px; padding: 4px 6px; font-size: 12.5px; line-height: 1.15; }
:root[data-style="haven"] .money-label { margin: 4px 0 6px; font-size: 12.5px; }
:root[data-style="haven"] .money-label-gap { margin-top: 10px; }
:root[data-style="haven"] :is(#view-container, .view-still) .k.settings-k { padding-inline: 0; margin-inline: 0; }

/* ================================================================== Accounts (5.64) */
:root[data-style="haven"] .hv-hold-wrap { display: grid; gap: 8px; margin-bottom: 10px; }
:root[data-style="haven"] .hv-hold { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
:root[data-style="haven"] .hv-hold > div { display: grid; gap: 2px; padding: 10px 14px; border-radius: 20px; background: var(--hv-shell); box-shadow: 0 0 0 1px var(--hv-hair); }
:root[data-style="haven"] .hv-hold small { font-size: 12px; color: var(--hv-ink-3); }
:root[data-style="haven"] .hv-hold b { font-size: 22px; font-weight: 650; letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
:root[data-style="haven"] .hv-filter { display: flex; gap: 8px; overflow-x: auto; scrollbar-width: none; align-items: center; }
:root[data-style="haven"] .hv-filter [data-f] { flex: none; min-height: 44px; padding: 0 16px; border: 0; border-radius: 999px; background: var(--hv-shell); box-shadow: 0 0 0 1px var(--hv-hair); font: inherit; font-weight: 600; color: var(--hv-ink-2); transition: transform 400ms var(--hv-spring-snap); }
:root[data-style="haven"] .hv-filter [data-f].on { background: var(--hv-primary); color: var(--hv-on-primary); box-shadow: none; transform: scale(1.04); }
:root[data-style="haven"] .hv-sortsel { margin-left: auto; flex: none; }
/* each account is its own card; the group's pane stops being one big box */
:root[data-style="haven"] .account-group.k-pane { display: grid; gap: 8px; padding: 0; background: none; box-shadow: none; border: 0; }
:root[data-style="haven"] .account-group-label { margin: 10px 6px 6px; font-size: 13px; color: var(--hv-ink-3); }
:root[data-style="haven"] .account-block { position: relative; border-radius: 22px; background: linear-gradient(180deg, var(--hv-core), var(--hv-core-2)); box-shadow: 0 0 0 1px var(--hv-hair), var(--hv-lift); overflow: hidden; }
:root[data-style="haven"] .account-block .k-row.account-row { position: relative; min-height: 64px; padding: 10px 14px; background: none; box-shadow: none; border: 0; border-radius: 0; transition: color 400ms; }
:root[data-style="haven"] .account-block.is-open .account-row { background: var(--hv-vault); background-color: #11234f; color: #fff; }
:root[data-style="haven"] .account-block.is-open .account-row :is(.k-row__title, .k-row__value, .account-balance) { color: #fff; }
:root[data-style="haven"] .account-block.is-open .account-row .k-row__meta { color: var(--hv-on-navy-2); }
.hv-rowwater { position: absolute; inset: 0; pointer-events: none; background: linear-gradient(180deg, transparent 55%, rgba(110, 200, 235, 0.3)); }
:root[data-style="haven"] .account-block .account-detail { padding: 8px 14px 12px; }
:root[data-style="haven"] .hv-lead { flex: none; display: grid; place-items: center; }

/* ---- where it went (layers) and the budget tanks ---- */
.hv-ins__layers { display: grid; grid-template-columns: auto 1fr; gap: 14px; align-items: center; }
.hv-lkeys { display: grid; gap: 2px; }
.hv-lkey { display: grid; grid-template-columns: 10px 1fr auto; gap: 8px; align-items: center; min-height: 44px; padding: 0 4px; border: 0; background: none; font: inherit; font-size: 13px; color: var(--hv-ink); text-align: left; transition: opacity .3s; }
.hv-lkey i { width: 10px; height: 10px; border-radius: 3px; }
.hv-lkey b { font-variant-numeric: tabular-nums; font-weight: 600; }
.hv-ins__layers [data-layer] { cursor: pointer; }
.hv-ins__tanks { display: flex; gap: 12px; align-items: flex-end; overflow-x: auto; padding: 2px 2px 4px; scrollbar-width: none; }
.hv-tank { display: grid; gap: 5px; justify-items: center; font-size: 11px; color: var(--hv-ink-2); flex: none; }
/* ---- lab 4 (5.62): fireflies, the day-night sweep, today's ring, the way to salary, this month beside last, the chart's flag ---- */
.hv-flies { position: fixed; inset: 0; z-index: -1; pointer-events: none; overflow: hidden; overflow: clip; contain: paint; }
.hv-flies i { position: absolute; width: 4px; height: 4px; border-radius: 50%; background: #ffe9a8; box-shadow: 0 0 10px 3px rgba(255, 230, 150, 0.45); }
:root[data-style="haven"][data-motion="still"] .hv-flies { display: none; }
html.hv-sweeping::view-transition-old(root), html.hv-sweeping::view-transition-new(root) { animation: none; mix-blend-mode: normal; }
html.hv-sweeping::view-transition-old(root) { z-index: 1; }
html.hv-sweeping::view-transition-new(root) { z-index: 2; }
.hv-ins { display: grid; gap: 16px; }
.hv-ins__ring { position: relative; display: grid; place-items: center; }
.hv-ins__t { position: absolute; display: grid; text-align: center; }
.hv-ins__t b { font-size: 22px; font-weight: 650; letter-spacing: -0.03em; }
.hv-ins__t span { font-size: 12px; color: var(--hv-ink-3); }
.hv-ins__s { text-align: center; font-size: 13px; color: var(--hv-ink-2); margin-top: -4px; }
.hv-ins__cmp { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; text-align: center; }
.hv-ins__cmp > div { display: grid; justify-items: center; gap: 3px; }
.hv-ins__cmp > div > span { font-size: 12px; color: var(--hv-ink-3); }
.hv-ins__cmp > p { grid-column: 1 / -1; margin: 4px 0 0; font-weight: 650; font-size: 14px; }
.hv-ins__shield { position: relative; width: 74px; height: 92px; }
.waves__pole { stroke: var(--hv-ink); stroke-width: 1.4; }
.waves__pennant { fill: var(--hv-primary); }
.waves__pt { font-size: 9.5px; font-weight: 650; fill: var(--hv-on-primary); }
@media (prefers-reduced-motion: no-preference) { :root[data-style="haven"][data-motion="alive"] .waves__pennant { animation: hv-flagwave 2.4s ease-in-out infinite; transform-box: fill-box; transform-origin: left center; } }
@keyframes hv-flagwave { 50% { transform: skewY(3deg); } }

/* ---- a pasted message: the words are underlined only; and the shield while a statement is read ---- */
:root[data-style="haven"] .alert-sms mark { animation: none; box-shadow: inset 0 -2px 0 var(--hv-link); color: var(--hv-ink); }
.hv-flychip { position: fixed; z-index: 60; padding: 1px 6px; border-radius: 6px; background: color-mix(in oklab, var(--hv-link) 25%, var(--hv-core)); color: var(--hv-ink); font-size: 12px; pointer-events: none; }
.hv-readshield { display: inline-flex; align-items: center; gap: 12px; }
.hv-readshield .tide { position: relative; width: 44px; height: 54px; flex: none; }
:root[data-style="haven"] .hv-ins > * { min-width: 0; }
.hv-ins__tanks { max-width: 100%; }
.hv-ins__layers { grid-template-columns: auto minmax(0, 1fr); }
.hv-lkey span { min-width: 0; overflow-wrap: anywhere; line-height: 1.2; }
/* At 320 the shield left its names about 23px, "Tra nsf er" (1 Nov 2026, Where it went on Summary): the names go under it. */
@media (max-width: 360px) {
  .hv-ins__layers { grid-template-columns: minmax(0, 1fr); justify-items: center; }
  .hv-ins__layers .hv-lkeys { width: 100%; }
}
:root[data-style="haven"] .hv-filter { flex-wrap: wrap; overflow: visible; }
:root[data-style="haven"] .hv-hold-wrap { min-width: 0; }
:root[data-style="haven"] .hv-acctchips { flex-wrap: wrap; }

/* Add: the other ways in, as one quiet line under the main button. */

/* A closed account is its row and nothing else (a one-line warning may stay); the rest opens with a tap. */
:root[data-style="haven"] .account-block:not(.is-open) > :not(.account-row):not(.account-note) { display: none; }
:root[data-style="haven"] .account-block .account-row[role="button"] { cursor: pointer; }
:root[data-style="haven"] .account-block .account-row[role="button"]:focus-visible { outline: 2px solid var(--hv-link); outline-offset: -2px; border-radius: 22px; }
:root[data-style="haven"] .account-block .account-note { margin: 0; padding: 0 14px 8px; font-size: 12.5px; }

/* Cards: whatever sits in an account's card apart from its row keeps the card's own side space. */
:root[data-style="haven"] .account-block > :not(.account-row):not(.account-detail):not(.account-note) { padding-inline: 14px; box-sizing: border-box; }
:root[data-style="haven"] .account-block > :not(.account-row) { max-width: 100%; }
:root[data-style="haven"] .account-block .account-detail { padding-inline: 14px; }
:root[data-style="haven"] .account-block .account-detail .k-btn { min-height: 44px; }
/* The header gets a soft ground once the page has scrolled under it, so nothing is seen through its buttons. */
:root[data-style="haven"] .app-header.is-scrolled { background: color-mix(in oklab, var(--hv-paper) 82%, transparent); -webkit-backdrop-filter: blur(14px); backdrop-filter: blur(14px); box-shadow: 0 1px 0 var(--hv-hair); }
:root[data-style="haven"] .app-header { transition: background 200ms, box-shadow 200ms; }
/* Links at the foot of an open card start where its text starts: no extra indent, none centred. */
:root[data-style="haven"] .account-block .account-actions-inline { margin: 0; padding-inline: 14px; justify-content: flex-start; gap: 20px; }
:root[data-style="haven"] .account-block .account-actions-inline .k-btn,
:root[data-style="haven"] .account-block .account-see-all { padding-inline: 0; justify-content: flex-start; min-height: 44px; }
:root[data-style="haven"] .account-block .account-see-all { display: flex; margin: 0; }

/* Accounts: a card opens and closes by growing and shrinking, so its row keeps its colour until the end. */
:root[data-style="haven"] .account-block { overflow-anchor: none; }
/* The foot links of an open card already sit inside its details' side space: no second indent. */
:root[data-style="haven"] .account-block .account-detail .account-actions-inline { padding-inline: 0; }

/* ---- compact pages (5.68): the same rules the options page follows, on every page --------------------------------------
 * History rows sit close (still 44px to touch), the home-screen card is one short line, a double-cost warning is one line
 * until opened. */
:root[data-style="haven"] .hist-row { padding-block: 0; }
:root[data-style="haven"] .hist-row .hist-main { padding-block: 5px; min-height: 48px; }
:root[data-style="haven"] .k .hist-day-head { margin: 6px 6px 4px; }
:root[data-style="haven"] .k .hist-day { margin-bottom: 4px; }
:root[data-style="haven"] .install-card { padding-block: 10px; }
:root[data-style="haven"] .dupe-fold { margin: 0 0 8px; }
:root[data-style="haven"] .dupe-fold .totals-card { margin-top: 6px; }
:root[data-style="haven"] .dupe-pair .btn-tiny { min-height: 44px; }

/* ---- record a run (5.69, js/haven-record.js): hidden until the version is tapped five times ---- */
.hv-recrow { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 8px 0; padding: 10px 14px; border-radius: 16px; background: var(--hv-core); box-shadow: 0 0 0 1px var(--hv-hair); color: var(--hv-ink); }
.hv-recrow small { display: block; color: var(--hv-ink-2); font-size: 12.5px; }
.hv-recrow button, .hv-rec button, .hv-recdlg button { min-height: 44px; padding: 0 16px; border-radius: 999px; border: 0; font: inherit; font-weight: 600; background: var(--hv-link); color: #fff; }
.hv-rec { position: fixed; z-index: 90; left: 50%; transform: translateX(-50%); bottom: calc(96px + env(safe-area-inset-bottom)); display: flex; align-items: center; gap: 8px; padding: 6px 8px 6px 14px; border-radius: 999px; background: #1c2230; color: #fff; box-shadow: 0 8px 28px #0006; font-variant-numeric: tabular-nums; }
.hv-rec button { background: #ffffff1f; padding: 0 12px; }
.hv-rec .hv-rec__stop { background: #d93a3a; }
.hv-rec__dot { width: 10px; height: 10px; border-radius: 50%; background: #ff4d4d; animation: hv-recblink 1.2s ease-in-out infinite; }
@keyframes hv-recblink { 50% { opacity: 0.3; } }
.hv-recdlg { position: fixed; inset: 0; z-index: 95; display: grid; place-items: center; background: #0008; padding: 16px; }
.hv-recdlg__box { width: min(360px, 100%); padding: 18px; border-radius: 22px; background: var(--hv-core); color: var(--hv-ink); box-shadow: 0 0 0 1px var(--hv-hair); }
.hv-recdlg h2 { margin: 0 0 6px; font-size: 20px; }
.hv-recdlg p { margin: 0 0 14px; color: var(--hv-ink-2); font-size: 14px; }
.hv-recdlg__acts { display: flex; flex-wrap: wrap; gap: 8px; }
.hv-recdlg .quiet { background: transparent; color: var(--hv-ink-2); box-shadow: inset 0 0 0 1px var(--hv-hair); }
/* The header lets the sky show until the page scrolls under it (dna.css gave it a solid ground, which hid the sky). */
html:root[data-style="haven"] body:has(#view-container.k) .app-header:not(.is-scrolled) { background: none; }
html:root[data-style="haven"] body:has(#view-container.k) .app-header.is-scrolled { background: color-mix(in oklab, var(--hv-paper) 82%, transparent); }

/* The page itself lets the sky and the night lights show: dna.css gave every screen a solid ground of its own, which cut the sky
 * off at the header on all screens but Settings. The body has the same colour, so nothing else changes. */
html:root[data-style="haven"] .view-container.k { background: transparent; }
/* Record a run sits right under the version, one short row. */
.hv-recrow { margin: 0 0 8px; padding: 6px 6px 6px 14px; }

/* The line an account says about itself ("billed 25 Sep, statement not imported", cash not written down) sits inside the card:
 * no box of its own, the same side space as the row, one hairline above it. */
:root[data-style="haven"] .account-block .account-note { margin: 0; padding: 8px 14px 10px 14px; border: 0; border-top: 1px solid var(--hv-hair); border-radius: 0; background: color-mix(in oklab, var(--hv-warn) 9%, transparent); font-size: 12.5px; line-height: 1.4; color: var(--hv-ink-2); box-sizing: border-box; max-width: 100%; overflow-wrap: anywhere; }

/* ---- Teal and ink (5.72): the colours of mockups/7.11-colours, option C --------------------------------------------------
 * One brand teal in steps for charts, quiet chips for icons, amber only for warnings. Nothing else in the app has its own rainbow. */
:root[data-style="haven"] {
  --hv-L1: #0a7f99; --hv-L2: #2a98b1; --hv-L3: #58b2c6; --hv-L4: #8accd9; --hv-L5: #bde3ea; --hv-L6: #9aa3b8;
  --hv-gem-bg: #dff1f5; --hv-gem-ink: #0a7f99; --hv-water: #1596b3; --hv-amber: #b9791f;
  --hv-tide-a: #0f7f9a; --hv-tide-b: #2aa6c0;
}
:root[data-style="haven"][data-theme="dark"] {
  --hv-L1: #5ad0e6; --hv-L2: #3aa7c4; --hv-L3: #2d82a0; --hv-L4: #25607a; --hv-L5: #1d4558; --hv-L6: #6b7690;
  --hv-gem-bg: #1e2c55; --hv-gem-ink: #7fd9ec; --hv-water: #4fc7de; --hv-amber: #f0b968;
  --hv-tide-a: #2d9cb8; --hv-tide-b: #58cde3;
}
/* the moods keep their own colours: "watch" amber, "low" red */
:root[data-style="haven"] .tide[data-mood="watch"] { --hv-tide-a: oklch(60% 0.15 62); --hv-tide-b: oklch(80% 0.14 84); }
:root[data-style="haven"] .tide[data-mood="low"] { --hv-tide-a: oklch(50% 0.19 27); --hv-tide-b: oklch(70% 0.17 32); }
/* every icon tile is the same quiet chip; the icon says which category, not a colour */
:root[data-style="haven"] .hv-gem { background: var(--hv-gem-bg); color: var(--hv-gem-ink); box-shadow: inset 0 0 0 1px var(--hv-hair); }
:root[data-style="haven"] .account-block.is-open .hv-gem { background: oklch(100% 0 0 / 0.14); color: #fff; box-shadow: none; }
:root[data-style="haven"] .cat-chip { --chip-color: var(--hv-gem-ink) !important; }
/* little shields for the budgets */
.hv-ins__tanks { gap: 14px; }
.hv-tank svg { width: 62px; height: 76px; display: block; }
.hv-tank__bg { fill: var(--hv-core-2, var(--hv-well)); }
.hv-tank__rim { fill: none; stroke: var(--hv-ink-2); stroke-opacity: 0.55; stroke-width: 2; }
.hv-tank [data-f] { fill: var(--hv-water); opacity: 0.92; }
.hv-tank.warm [data-f] { fill: var(--hv-amber); }
.hv-tank { font-size: 12px; }

/* Add (5.73): the page and the + sheet are the same form with the same two small chips on top. The old banner is gone everywhere. */
:root[data-style="haven"] .k-add-sms { display: none; }
:root[data-style="haven"] .hv-addways { grid-template-columns: repeat(2, minmax(0, 1fr)); margin-bottom: 2px; }

/* ---- Accounts as a stack of cards (5.74, mockups/7.12-cards-and-ring) ---- */
:root[data-style="haven"] { --hv-card-a: #1c4aa8; --hv-card-b: #10306f; }
:root[data-style="haven"][data-theme="dark"] { --hv-card-a: #1a3a78; --hv-card-b: #0f2352; }
.hv-deckwrap { margin: 2px 0 6px; }
.hv-dk { position: relative; height: 178px; margin: 6px 28px 0 6px; touch-action: pan-y; user-select: none; -webkit-user-select: none; outline-offset: 6px; }
.hv-count { display: inline-block; min-width: 18px; height: 18px; margin-left: 6px; padding: 0 5px; border-radius: 9px; background: var(--hv-bad); color: var(--hv-on-navy); font: 650 11px/18px var(--hv-font); font-style: normal; text-align: center; }
html:root[data-style="haven"] #tabs .nav-btn[data-view="add"] .nav-icon { position: relative; }
html:root[data-style="haven"] #tabs .nav-btn[data-view="add"][data-waiting] .nav-icon::after { content: ""; position: absolute; top: 2px; right: 2px; width: 14px; height: 14px; border-radius: 50%; background: var(--hv-bad); box-shadow: 0 0 0 3px var(--hv-paper); }
.hv-sr { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; clip-path: inset(50%); white-space: nowrap; }

/* ---- History's ring (5.74, mockups/7.12-cards-and-ring) ---- */
.hv-ringcard { background: linear-gradient(180deg, var(--hv-core), var(--hv-core-2)); border-radius: 24px; padding: 12px 10px 14px; margin: 4px 0 10px; box-shadow: 0 0 0 1px var(--hv-hair); }
.hv-ringcard[hidden], .hv-pair[hidden] { display: none; }
.hv-ring__wrap { position: relative; width: min(300px, 100%); aspect-ratio: 1; margin: 0 auto; }
.hv-ring__svg { width: 100%; height: 100%; display: block; transform: rotate(-90deg); }
.hv-ring__arc { fill: none; stroke-width: 26; cursor: pointer; transition: opacity .25s, stroke-width .25s; }
.hv-ring__arc.dim { opacity: 0.25; }
.hv-ring__arc.on { stroke-width: 32; }
.hv-ring__mid { position: absolute; inset: 0; display: grid; place-content: center; text-align: center; pointer-events: none; padding: 0 70px; }
.hv-ring__mid b { font-size: 30px; letter-spacing: -0.03em; color: var(--hv-ink); line-height: 1.1; }
.hv-ring__mid span { font-size: 13px; color: var(--hv-ink-2); }
.hv-ring__mid em { font-style: normal; font-size: 13px; font-weight: 600; color: var(--hv-L1); }
.hv-ring__badge { position: absolute; width: 44px; height: 44px; margin: -22px 0 0 -22px; padding: 0; border: 0; background: none; display: grid; place-items: center; cursor: pointer; transition: transform .25s, opacity .25s; }
.hv-ring__badge .hv-ic { width: 36px; height: 36px; border-radius: 50%; background: var(--hv-core); box-shadow: 0 0 0 1px var(--hv-hair), 0 4px 12px #0004; color: var(--hv-gem-ink); }
.hv-ring__badge .hv-ic svg { width: 18px; height: 18px; }
.hv-ring__badge.dim { opacity: 0.35; }
.hv-ring__badge.on { transform: scale(1.15); }
.hv-ring__badge.on .hv-ic { box-shadow: 0 0 0 2px var(--hv-L1), 0 6px 16px #0005; }
.hv-pair { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; margin: 0 0 10px; }
.hv-histfold { margin: 0 0 10px; }

/* The app does not zoom: a two-finger pinch or a double tap changes nothing (5.74.1). */
html, body { touch-action: pan-x pan-y; }
/* Changing screen: the old header and tab bar are not shown at all (they were drawn under the new ones now that they are see-through). */
@supports (view-transition-name: none) {
  ::view-transition-old(kv-header), ::view-transition-old(kv-nav) { display: none; }
}
/* Stepping a month (5.91, js/ui.js monthSwap): 16 px, 260 ms, both pictures together so the screen is never empty. */
@supports (view-transition-class: x) {
  ::view-transition-old(.kv-month) { animation: hv-month-out 260ms cubic-bezier(0.33, 0, 0.2, 1) both; }
  ::view-transition-new(.kv-month) { animation: hv-month-in 260ms cubic-bezier(0.33, 0, 0.2, 1) both; }
}
@keyframes hv-month-out { to { opacity: 0; transform: translateX(calc(var(--hv-month-dir, 1) * -16px)); } }
@keyframes hv-month-in { from { opacity: 0; transform: translateX(calc(var(--hv-month-dir, 1) * 16px)); } }

/* One palette everywhere (5.74.1): icon tiles are the quiet chip, usage bars and the in / out bars are teal, and a legend always matches its bars. */
:root[data-style="haven"] .k-icon { background: var(--hv-gem-bg); color: var(--hv-gem-ink); border: 0; box-shadow: inset 0 0 0 1px var(--hv-hair); }
:root[data-style="haven"] .cat-share-track i { background: var(--hv-L2) !important; }
:root[data-style="haven"] .bar-in { fill: var(--hv-L1) !important; }
:root[data-style="haven"] .bar-out { fill: var(--hv-L4) !important; }
:root[data-style="haven"] .key-in { background: var(--hv-L1) !important; }
:root[data-style="haven"] .key-out { background: var(--hv-L4) !important; }
:root[data-style="haven"] .k-icon.coach-q-icon, :root[data-style="haven"] .coach-q-icon { background: var(--hv-gem-bg) !important; background-image: none !important; color: var(--hv-gem-ink) !important; box-shadow: inset 0 0 0 1px var(--hv-hair) !important; }

/* a payment listed on an account is a button: tap it to open it in History, ready to edit */
button.account-recent-row { width: 100%; text-align: left; background: none; border: 0; font: inherit; color: inherit; cursor: pointer; min-height: 56px; }
button.account-recent-row:active { background: var(--hv-hair); }

/* a passphrase that is allowed but short gets a quiet hint, not a red error */
.field-error-text.is-hint { color: var(--text-muted); font-weight: 500; }

/* the four account filters share the width evenly, edge to edge; the sort choice, when there is one, sits on its own line */
:root[data-style="haven"] .hv-filter { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; overflow: visible; }
:root[data-style="haven"] .hv-filter [data-f] { width: 100%; padding: 0 4px; text-align: center; }
:root[data-style="haven"] .hv-filter .hv-sortsel { grid-column: 1 / -1; justify-self: end; margin-left: 0; }
/* a payment opened from another screen lights up for a moment so the eye finds it */
@keyframes hv-found-glow { from { box-shadow: 0 0 0 2px var(--hv-link); } to { box-shadow: 0 0 0 2px transparent; } }
.hist-row--found { animation: hv-found-glow 1.8s ease-out; border-radius: 16px; }

/* Kept back (Summary, under Left to spend): one slim line, opening in place to a line for each set-aside with a thin bar */
.hv-kept { margin: calc(8px - var(--hv-s4, 20px)) 4px 0; border-radius: 16px; background: var(--hv-well); box-shadow: 0 0 0 1px var(--hv-hair); }
.hv-kept__head { width: 100%; display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 14px; background: none; border: 0; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.hv-kept__ic { display: grid; place-items: center; width: 22px; height: 22px; color: var(--hv-link); flex: none; }
.hv-kept__ic svg { width: 20px; height: 20px; }
.hv-kept__t { font-weight: 600; font-size: 15px; }
.hv-kept__v { margin-left: auto; font-weight: 700; font-size: 15px; }
.hv-kept__chev { color: var(--hv-ink-3); flex: none; transition: transform .3s; }
.hv-kept.open .hv-kept__chev { transform: rotate(180deg); }
.hv-kept__list { height: 0; overflow: hidden; }
.hv-kept__in { padding: 0 14px 10px 46px; }
.hv-kept__item { padding: 5px 0 6px; }
.hv-kept__top { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; font-size: 14px; }
.hv-kept__name { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.hv-kept__left { font-size: 13px; opacity: .8; white-space: nowrap; }
.hv-kept__left b { font-weight: 700; font-size: 14px; }
.hv-kept__track { height: 4px; border-radius: 99px; background: var(--hv-hair); margin-top: 5px; overflow: hidden; }
.hv-kept__track i { display: block; height: 100%; border-radius: 99px; background: var(--hv-link); }
.hv-kept__item.is-warn .hv-kept__track i { background: var(--hv-warn); }
.hv-kept__item.is-over .hv-kept__track i { background: var(--hv-bad); }
.hv-kept__used > summary { list-style: none; font-size: 13px; padding: 4px 0 2px; color: var(--hv-link); cursor: pointer; min-height: 44px; display: flex; align-items: center; }
.hv-kept__used > summary::-webkit-details-marker { display: none; }
@media (prefers-reduced-motion: reduce) { .hv-kept__chev { transition: none; } }

/* ---- How it looks (5.93): one card, five choices. A row of buttons is a radio group underneath; the label is the 44px target, the lit pill inside it 36 ---- */
.hl-card { display: grid; padding: 2px 12px; border-radius: 16px; background: var(--hv-core); box-shadow: 0 0 0 1px var(--hv-hair); }
.hl-card--in { margin-top: 6px; }
.hl-group { display: grid; gap: 6px; padding: 10px 0; }
.hl-group + .hl-group { border-top: 1px solid var(--hv-hair); }
.hl-label { font-size: 13px; font-weight: 600; color: var(--hv-ink-2); }
.hl-seg { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; border-radius: 13px; background: var(--hv-well); box-shadow: inset 0 0 0 1px var(--hv-hair); }
.hl-opt { position: relative; display: grid; min-height: 44px; font-size: 14px; font-weight: 600; color: var(--hv-ink-2); cursor: pointer; }
.hl-opt > span { display: grid; place-items: center; margin: 4px 3px; border-radius: 10px; }
.hl-opt input { position: absolute; opacity: 0; inset: 0; width: 100%; height: 100%; margin: 0; }
.hl-opt:has(input:checked) > span { background: var(--hv-primary); color: var(--hv-on-primary); }
.hl-opt:has(input:focus-visible) > span { outline: 2px solid var(--hv-link); outline-offset: 1px; }
.hl-note { margin: 0; font-size: 12px; color: var(--hv-ink-3); }
.hl-where { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; }
.hl-where .k-select, .hl-pick { min-height: 44px; border-radius: 11px; }
.hl-btn { min-height: 44px; padding: 0 12px; border: 0; border-radius: 11px; background: var(--hv-core-2); box-shadow: 0 0 0 1px var(--hv-hair); color: var(--hv-ink); font: inherit; font-size: 14px; font-weight: 600; }
.hl-fold { margin-top: 8px; }
.hl-fold > summary { min-height: 44px; display: flex; align-items: center; color: var(--hv-ink-2); font-size: 14px; font-weight: 600; cursor: pointer; }
.hl-where .k-select, .hl-pick { -webkit-appearance: none; appearance: none; padding-right: 34px; background-repeat: no-repeat !important; background-position: right 12px center !important; background-size: 14px !important; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238a95a8' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") !important; }
