/*
  Family helper design tokens, after the ShemRivers site: Hevron limestone ground, basalt-umber ink (never grey),
  vine for links, focus and the active state, olive only as a colour field, a pale Shechinah blue for decoration.
  One typeface (Rubik). Flat surfaces framed by thin lines; motion arrives slowly and leaves quickly.
*/
@import url('https://fonts.googleapis.com/css2?family=Rubik:wght@400;500;600&family=Heebo:wght@400;500;600&family=Varela+Round&family=Frank+Ruhl+Libre:wght@400;500;700&display=swap');

:root {
  /* the layers (one scale for everything that floats, so a bubble, a menu or a sheet never lands under the wrong thing):
     the bars 12 · floating figures and players 30 · their bubbles and panels 40 · the owner's messages 45 ·
     menus 50 · sheets and modals 60 · toasts 70 (the lock screen and the pranks' sparks sit above all) */
  --z-bar: 12; --z-float: 30; --z-bubble: 40; --z-msg: 45; --z-menu: 50; --z-sheet: 60; --z-toast: 70;
  --icon-ink: #2e2a1e;   /* the line of the pastel icons: dark ink in both themes, so the pastel fill keeps its colour at night too */
  --chalk: #efeee6;
  --chalk-raised: #f7f6f0;
  --ink: #2e2a1e;
  --vine: #55622f;
  --olive: #c2b04e;
  --olive-ink: color-mix(in srgb, var(--olive) 50%, var(--ink));   /* olive as text: deep enough by day (3:1 and more); the olive itself at night */
  --soil: #9c7a55;
  --tint: #dceaf1;

  --bg: var(--chalk);
  --bg-grad: none;
  --card: var(--chalk-raised);
  --text: var(--ink);
  --muted: #625a45;          /* 6.1:1 on chalk */
  --line: #dcd8c9;
  --line-strong: #c9c4b1;
  --primary: var(--vine);
  --primary-ink: #f7f6f0;
  --accent: var(--olive);    /* a field, always with ink text */
  --accent-ink: var(--ink);
  --danger: #9a3b2a;
  --alert: #cc5a46;   /* the bar's warning triangle: a soft coral red, still 3:1 on the bar */
  --exp: #8f5a0c;     /* the "ניסיוני" tag: a warm amber, a trial and not a warning (4.5:1 as text on its own wash) */
  --soon: #2f5c7a;    /* the "בקרוב" / "בפיתוח" note of a big idea that waits: a calm dusk blue, a promise and not a tool */
  --ok: var(--vine);
  --glass: rgba(247, 246, 240, 0.82);
  --glass-border: rgba(46, 42, 30, 0.12);
  --shadow: none;
  --lift: 0 1px 0 rgba(46, 42, 30, .04), 0 10px 30px rgba(46, 42, 30, .10);
  --radius: 12px;     /* softer, rounder shapes across the hub */
  --radius-sm: 9px;
  --radius-lg: 20px;

  --appbar-h: 60px;
  --tabbar-h: 0px;
  --ease-river: cubic-bezier(0.22, 1, 0.36, 1);
  --ease-leave: cubic-bezier(0.4, 0, 1, 1);
  --dur-press: 120ms;
  --dur-quick: 200ms;
  --dur-draw: 340ms;
  --start: 100%;
  --end: 0%;
  color-scheme: light;
}
/* Night: the night sky – a navy so deep it is almost black, the cards a shade above it; warm off-white text, a touch softer
   than by day (no pure white: less blue light, less glare), so the deeper ground does not make it harsh. */
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
    --bg: #070b14;
    --card: #0e1422;
    --text: #dfd9cb;
    --muted: #a9afbd;
    --line: #1a2335;
    --line-strong: #28344c;
    --primary: #a8c28c;
    --primary-ink: #070b14;
    --danger: #e79a85;
    --alert: #e79a85;
    --exp: #e8b766;
    --soon: #9cc3df;
    --ok: #a8c28c;
    --glass: rgba(14, 20, 34, 0.88);
    --glass-border: rgba(231, 225, 211, 0.10);
    --lift: 0 10px 30px rgba(0, 0, 0, .45);
    --tint: #14203a;
    --olive-ink: var(--olive);
    color-scheme: dark;
  } }
:root[data-theme="dark"] {
    --bg: #070b14;
    --card: #0e1422;
    --text: #dfd9cb;
    --muted: #a9afbd;
    --line: #1a2335;
    --line-strong: #28344c;
    --primary: #a8c28c;
    --primary-ink: #070b14;
    --danger: #e79a85;
    --alert: #e79a85;
    --exp: #e8b766;
    --soon: #9cc3df;
    --ok: #a8c28c;
    --glass: rgba(14, 20, 34, 0.88);
    --glass-border: rgba(231, 225, 211, 0.10);
    --lift: 0 10px 30px rgba(0, 0, 0, .45);
    --tint: #14203a;
    --olive-ink: var(--olive);
    color-scheme: dark;
  }
@media (max-width: 899px) { :root { --tabbar-h: 64px; --appbar-h: 54px; } }
/* Colour themes (הגדרות › ערכות צבעים; settings/apply.js sets <html data-palette>). Each changes the two colours that carry
   the hub: the active one (--primary: buttons, links, what is chosen) and the field (--olive: the "extra", the ring, the
   tags), by day and at night; the stone and the basalt stay, so every page keeps its calm. Text contrast is checked
   for each: the active colour on the page 5:1 and more, ink on the field 6:1 and more (as the default).
     ''         אבן ובזלת      vine and olive (the default)
     sea        ים התיכון      deep sea and sand
     desert     מדבר           terracotta and dune gold
     vineyard   כרם            wine and grape blossom
     dusk       בין הערביים    indigo and lamp amber */
:root[data-palette="sea"] { --vine: #1f5f7a; --primary: #1f5f7a; --olive: #8fc7d4; --tint: #d8ecf2; }
:root[data-palette="desert"] { --vine: #9a4a24; --primary: #9a4a24; --olive: #e0a85a; --tint: #f5e4cf; }
:root[data-palette="vineyard"] { --vine: #6b2a4a; --primary: #6b2a4a; --olive: #c9a0c0; --tint: #f0e0ea; }
:root[data-palette="dusk"] { --vine: #3d4a8a; --primary: #3d4a8a; --olive: #e8b26a; --tint: #e2e5f5; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"])[data-palette="sea"] { --primary: #8cc4d8; --ok: #8cc4d8; --tint: #10283a; }
  :root:not([data-theme="light"])[data-palette="desert"] { --primary: #e6a17a; --ok: #e6a17a; --tint: #2e1c14; }
  :root:not([data-theme="light"])[data-palette="vineyard"] { --primary: #d9a0bf; --ok: #d9a0bf; --tint: #2a1624; }
  :root:not([data-theme="light"])[data-palette="dusk"] { --primary: #a9b4ec; --ok: #a9b4ec; --tint: #161c3a; }
}
:root[data-theme="dark"][data-palette="sea"] { --primary: #8cc4d8; --ok: #8cc4d8; --tint: #10283a; }
:root[data-theme="dark"][data-palette="desert"] { --primary: #e6a17a; --ok: #e6a17a; --tint: #2e1c14; }
:root[data-theme="dark"][data-palette="vineyard"] { --primary: #d9a0bf; --ok: #d9a0bf; --tint: #2a1624; }
:root[data-theme="dark"][data-palette="dusk"] { --primary: #a9b4ec; --ok: #a9b4ec; --tint: #161c3a; }

/* Themes that change the background too (vision batch 5): the whole room in another light – its ground, its cards, its
   lines and its ink – by day and at night. Contrast checked: text 12:1 and more, the active colour 5.5:1, ink on the field 7:1.
     sand   חול     a warm dune: sand ground, terracotta
     sage   מרווה   a garden: sage ground, deep leaf green
     mist   ערפל    a cool morning: mist-grey ground, slate blue */
:root[data-palette="sand"] { --bg: #efe5d1; --card: #f9f3e7; --chalk: #efe5d1; --chalk-raised: #f9f3e7; --text: #2e2418; --ink: #2e2418; --muted: #66543a;
  --line: #ddd0b6; --line-strong: #c9b998; --vine: #8a461c; --primary: #8a461c; --olive: #dba65a; --tint: #f5e4cf; --glass: rgba(249, 243, 231, .84); }
:root[data-palette="sage"] { --bg: #e5ebdf; --card: #f3f6ef; --chalk: #e5ebdf; --chalk-raised: #f3f6ef; --text: #232b20; --ink: #232b20; --muted: #525e4a;
  --line: #d0dac8; --line-strong: #b9c7ae; --vine: #3b6634; --primary: #3b6634; --olive: #adc58c; --tint: #dfeedd; --glass: rgba(243, 246, 239, .84); }
:root[data-palette="mist"] { --bg: #e8e9ee; --card: #f5f6f9; --chalk: #e8e9ee; --chalk-raised: #f5f6f9; --text: #23252e; --ink: #23252e; --muted: #545867;
  --line: #d4d6df; --line-strong: #bfc2ce; --vine: #3a4d82; --primary: #3a4d82; --olive: #b7c2e2; --tint: #e0e5f5; --glass: rgba(245, 246, 249, .84); }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"])[data-palette="sand"] { --bg: #15100a; --card: #201912; --text: #ecdfc8; --muted: #b8a688; --line: #2e251a; --line-strong: #43372a; --primary: #e8a878; --ok: #e8a878; --primary-ink: #15100a; --tint: #2e1c14; --glass: rgba(32, 25, 18, .88); }
  :root:not([data-theme="light"])[data-palette="sage"] { --bg: #0a110c; --card: #121b14; --text: #dde6d6; --muted: #a6b4a0; --line: #1c2a1f; --line-strong: #2b3e2f; --primary: #9fd29a; --ok: #9fd29a; --primary-ink: #0a110c; --tint: #142a18; --glass: rgba(18, 27, 20, .88); }
  :root:not([data-theme="light"])[data-palette="mist"] { --bg: #0b0d14; --card: #141722; --text: #dfe1ea; --muted: #a9adbd; --line: #1e2232; --line-strong: #2d3349; --primary: #a8b8ee; --ok: #a8b8ee; --primary-ink: #0b0d14; --tint: #161c3a; --glass: rgba(20, 23, 34, .88); }
}
:root[data-theme="dark"][data-palette="sand"] { --bg: #15100a; --card: #201912; --text: #ecdfc8; --muted: #b8a688; --line: #2e251a; --line-strong: #43372a; --primary: #e8a878; --ok: #e8a878; --primary-ink: #15100a; --tint: #2e1c14; --glass: rgba(32, 25, 18, .88); }
:root[data-theme="dark"][data-palette="sage"] { --bg: #0a110c; --card: #121b14; --text: #dde6d6; --muted: #a6b4a0; --line: #1c2a1f; --line-strong: #2b3e2f; --primary: #9fd29a; --ok: #9fd29a; --primary-ink: #0a110c; --tint: #142a18; --glass: rgba(18, 27, 20, .88); }
:root[data-theme="dark"][data-palette="mist"] { --bg: #0b0d14; --card: #141722; --text: #dfe1ea; --muted: #a9adbd; --line: #1e2232; --line-strong: #2d3349; --primary: #a8b8ee; --ok: #a8b8ee; --primary-ink: #0b0d14; --tint: #161c3a; --glass: rgba(20, 23, 34, .88); }
/* A theme of one's own (data-palette="custom"): settings sets --primary, --olive, --bg and --card on <html> from
   H.palette.derive() (palette.js), which already keeps the contrast; by night the derived night values come in the same way. */

/* The fonts to choose from (data-font): Rubik is the hub's own; each of the others loads only for whoever picks it. */
:root[data-font="heebo"] body, :root[data-font="heebo"] :is(button, input, select, textarea) { font-family: 'Heebo', system-ui, 'Ohel Ivri', sans-serif; }
:root[data-font="round"] body, :root[data-font="round"] :is(button, input, select, textarea) { font-family: 'Varela Round', 'Rubik', system-ui, 'Ohel Ivri', sans-serif; }
:root[data-font="serif"] body, :root[data-font="serif"] :is(button, input, select, textarea) { font-family: 'Frank Ruhl Libre', 'David', 'Ohel Ivri', serif; }
:root[data-font="serif"] :is(h1, h2, h3) { font-weight: 700; }
:root[data-font="alef"] body, :root[data-font="alef"] :is(button, input, select, textarea) { font-family: 'Alef', 'Rubik', system-ui, 'Ohel Ivri', sans-serif; }

/* Reading comfort (הגדרות › נגישות; settings/apply.js marks <html>): the text size is the root's font size (every rem grows
   with it); these are the rest. */
:root[data-spacing="wide"] body { line-height: 1.8; word-spacing: .14em; letter-spacing: .015em; }
:root[data-spacing="wide"] :is(p, li, dd, label, small, .muted) { line-height: 1.8; }
:root[data-font="readable"] body, :root[data-font="readable"] :is(button, input, select, textarea) { font-family: Arial, 'Segoe UI', system-ui, 'Ohel Ivri', sans-serif; }
:root[data-contrast="high"] { --text: #14120c; --muted: #3b3528; --line: #a9a28c; --line-strong: #77705b; }
:root[data-contrast="high"][data-theme="dark"] { --text: #f6f1e6; --muted: #d6dae2; --line: #3d4b68; --line-strong: #63749a; }
@media (prefers-color-scheme: dark) { :root[data-contrast="high"]:not([data-theme="light"]) { --text: #f6f1e6; --muted: #d6dae2; --line: #3d4b68; --line-strong: #63749a; } }
:root[data-contrast="high"] :is(.card, .btn, input, select, textarea) { border-width: 1.5px; }
/* less motion than the device asks for: as prefers-reduced-motion does, for whoever chose it here */
:root[data-motion="reduce"] *, :root[data-motion="reduce"] *::before, :root[data-motion="reduce"] *::after {
  animation-duration: .01ms !important; animation-iteration-count: 1 !important; transition-duration: .01ms !important; scroll-behavior: auto !important; }


* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent; background: var(--bg); overflow-x: clip; }
body { overflow-x: clip; }   /* nothing may widen a page sideways on a phone; clip keeps sticky headers working */
body {
  margin: 0;
  font-family: 'Rubik', system-ui, -apple-system, 'Segoe UI', Arial, 'Ohel Ivri', sans-serif;
  font-size: 1.0625rem;
  line-height: 1.6;
  background: var(--bg);
  color: var(--text);
  min-block-size: 100dvh;
  padding-block-end: calc(var(--tabbar-h) + env(safe-area-inset-bottom));
  text-rendering: optimizeLegibility;
}
::selection { background: var(--tint); color: var(--ink); }
:focus-visible { outline: 2px solid var(--primary); outline-offset: 3px; }
h1, h2, h3 { font-weight: 500; text-wrap: balance; letter-spacing: -0.005em; }
p { text-wrap: pretty; }
a { color: var(--primary); text-decoration-thickness: 1.5px; text-underline-offset: 3px; }
body.modal-open { overflow: hidden; }
main { max-width: 760px; margin: 0 auto; padding: 0 16px 96px; }
main.wide { max-width: 1200px; }

/* ---------- app shell: a top bar everywhere, the navigation in it on PC, a tab bar at the bottom on phones ---------- */
.appbar {
  position: sticky; top: 0; z-index: var(--z-bar);
  block-size: calc(var(--appbar-h) + env(safe-area-inset-top));
  padding: env(safe-area-inset-top) 20px 0;
  display: flex; align-items: center; gap: 20px;
  background: color-mix(in srgb, var(--bg) 92%, transparent);
  backdrop-filter: blur(10px); -webkit-backdrop-filter: blur(10px);
  border-block-end: 1px solid var(--line);
}
.brand { display: inline-flex; align-items: center; gap: 10px; color: var(--text); text-decoration: none; font-weight: 500; font-size: 1.05rem; white-space: nowrap; }
.brand-mark { block-size: 26px; inline-size: calc(26px * 405.4 / 159.4); flex: none; color: var(--text); }   /* the owner's logo, אהל in the old script */
/* the name, הָאֹ֔הֶל: short, so it can be big; room above and below for its vowels and its accent */
.brand-text { font-size: 1.7rem; font-weight: 600; line-height: 1.3; padding-block: 2px 4px; }
.appbar .page-title { display: none; font-weight: 500; font-size: 1.05rem; margin: 0; }
.topnav { display: flex; align-items: center; gap: 22px; margin-inline-start: 12px; }
.topnav a { color: var(--text); text-decoration: none; font-size: .98rem; padding-block: 6px; white-space: nowrap; }
/* nine entries on a narrow PC window: a little tighter, so the names stay on one line */
@media (min-width: 900px) and (max-width: 1099px) { .topnav { gap: 14px; margin-inline-start: 4px; } .topnav a { font-size: .92rem; } }
.ink-nav {
  background-image: linear-gradient(var(--primary), var(--primary));
  background-repeat: no-repeat; background-position: var(--end) 100%; background-size: 0% 2px;
  transition: background-size var(--dur-draw) var(--ease-river), color var(--dur-quick) var(--ease-river);
}
.ink-nav:hover, .ink-nav:focus-visible, .ink-nav[aria-current="page"] { background-position: var(--start) 100%; background-size: 100% 2px; }
.ink-nav:hover, .ink-nav[aria-current="page"] { color: var(--primary); }
.appbar .spacer { flex: 1; }
.userchip { display: inline-flex; align-items: center; gap: 8px; font: inherit; font-size: .9rem; color: var(--text); background: none; border: 1px solid var(--line-strong); border-radius: 999px; padding: 5px 12px; cursor: pointer; }
.userchip:hover { border-color: var(--primary); color: var(--primary); }
.userchip:has(.mi-dot, .dm-dot) { position: relative; }   /* a new reply in the person's inbox (reports.css): a small red dot on the chip */
.mi-dot { position: absolute; inset-block-start: -3px; inset-inline-end: -3px; inline-size: 11px; block-size: 11px; border-radius: 50%; background: #c2412d; box-shadow: 0 0 0 2px var(--bg); pointer-events: none; }
.dm-dot { position: absolute; inset-block-end: -3px; inset-inline-end: -3px; inline-size: 11px; block-size: 11px; border-radius: 50%; background: #c2412d; box-shadow: 0 0 0 2px var(--bg); pointer-events: none; }   /* an unread message (dm.js), at the chip's lower corner */

/* ── The warning triangle in the top bar (the owner, 2026-11-13; moved from reports.css so /welcome/ shows the same one): beside the settings chip, it opens the report sheet.
   <button class="rp-alert" type="button" aria-label="דיווח על תקלה או הצעה לשיפור"></button>  (no children needed: the triangle is
   drawn here; an H.icon put inside is hidden). Only the triangle, in a soft pastel red (--alert), with no circle around it
   (the owner, 2026-11-13); the button stays a 44×44 target. A ring shows only on keyboard focus. */
.rp-alert { display: inline-grid; place-items: center; flex: none; inline-size: 44px; block-size: 44px; margin-block: -4px; margin-inline: -2px;
  padding: 0; border: 0; border-radius: 50%; background: none; color: var(--alert, #cc5a46); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.rp-alert::after { content: ""; inline-size: 24px; block-size: 24px; background: currentColor; transition: scale var(--dur-quick, .15s) ease;
  -webkit-mask: url(/assets/bd-icons/alert.svg) center / contain no-repeat; mask: url(/assets/bd-icons/alert.svg) center / contain no-repeat; }
.rp-alert > :is(svg, .icon) { display: none; }
@media (hover: hover) { .rp-alert:hover::after { scale: 1.1; } }
.rp-alert:active::after { scale: .92; }
.rp-alert:focus-visible { outline: 3px solid color-mix(in srgb, var(--alert, #cc5a46) 55%, transparent); outline-offset: -3px; }
.rp-alert[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .rp-alert::after { transition: none; } }
/* ── The messages inbox in the top bar (the owner, 2026-11-13): beside the triangle and the settings chip, it opens /messages/.
   <button class="dm-inbox" type="button" aria-label="הודעות"></button>  (dm.js, ai-features; empty: the envelope is drawn here)
   and, while a conversation waits, <span class="dm-dot" aria-hidden="true"></span> inside it.
   The triangle's twin: the same 44×44 target, a 24px line icon at the same weight (bd-icons/envelope.svg, stroke 1.9), no circle,
   in the text's ink (the triangle alone keeps the red); the vine on hover like the chip. The two icons sit a little closer to
   each other than to the chip, so they read as one pair. The unread dot rides the envelope's corner. */
.dm-inbox { position: relative; display: inline-grid; place-items: center; flex: none; inline-size: 44px; block-size: 44px; margin-block: -4px; margin-inline: -2px;
  padding: 0; border: 0; border-radius: 50%; background: none; color: var(--text); cursor: pointer; -webkit-tap-highlight-color: transparent; }
.dm-inbox::after { content: ""; inline-size: 24px; block-size: 24px; background: currentColor; transition: scale var(--dur-quick, .15s) ease;
  -webkit-mask: url(/assets/bd-icons/envelope.svg) center / contain no-repeat; mask: url(/assets/bd-icons/envelope.svg) center / contain no-repeat; }
.dm-inbox > :is(svg, .icon) { display: none; }
@media (hover: hover) { .dm-inbox:hover { color: var(--primary); } .dm-inbox:hover::after { scale: 1.1; } }
.dm-inbox:active::after { scale: .92; }
.dm-inbox[aria-current="page"] { color: var(--primary); }
.dm-inbox:focus-visible { outline: 3px solid color-mix(in srgb, var(--primary) 45%, transparent); outline-offset: -3px; }
.dm-inbox[hidden] { display: none; }
.dm-inbox > .dm-dot { inset-block-start: 9px; inset-block-end: auto; inset-inline-end: 6px; inline-size: 10px; block-size: 10px; }
.appbar :is(.rp-alert, .dm-inbox) + :is(.rp-alert, .dm-inbox) { margin-inline-start: -12px; }
@media (max-width: 899px) { .appbar :is(.rp-alert, .dm-inbox) + :is(.rp-alert, .dm-inbox) { margin-inline-start: -8px; } }
@media (prefers-reduced-motion: reduce) { .dm-inbox::after { transition: none; } }
/* Light / dark switch: a little pill, the sun on one side and the moon on the other, a knob that slides between them. */
.theme-switch { position: relative; inline-size: 58px; block-size: 30px; flex-shrink: 0; border-radius: 999px; border: 1px solid var(--line-strong); padding: 0; cursor: pointer;
  background: linear-gradient(90deg, #f6d37a, #f2b36b); display: flex; align-items: center; justify-content: space-between; padding-inline: 7px; transition: background .4s var(--ease-river); }
.theme-switch[aria-checked="true"] { background: linear-gradient(90deg, #2a3358, #151a33); }
.theme-switch svg { inline-size: 15px; block-size: 15px; fill: none; stroke-width: 2; stroke-linecap: round; position: relative; z-index: 1; }
.theme-switch .sun { stroke: #8a4b0a; fill: #ffe9a8; }
.theme-switch .moon { stroke: #e9e4c8; fill: #e9e4c8; opacity: .5; }
.theme-switch[aria-checked="true"] .moon { opacity: 1; }
.theme-switch[aria-checked="true"] .sun { opacity: .45; }
.theme-switch .knob { position: absolute; inset-block-start: 3px; inset-inline-start: 3px; inline-size: 22px; block-size: 22px; border-radius: 50%; background: #fffaf0;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .3); transition: translate .4s var(--ease-river), background .4s; }
/* it slides by transform (no layout on each frame): 58 wide − 22 knob − 2×3 inset − 2 border = 28px */
.theme-switch[aria-checked="true"] .knob { translate: 28px 0; background: #c9cde0; }
:root[dir="rtl"] .theme-switch[aria-checked="true"] .knob { translate: -28px 0; }
.theme-switch:hover { border-color: var(--primary); }
html.theme-fade, html.theme-fade * { transition: background-color .45s ease, color .45s ease, border-color .45s ease !important; }

.tabbar { display: none; }
@media (max-width: 899px) {
  .appbar { padding-inline: 16px; gap: 12px; }
  .topnav { display: none; }
  .appbar .brand-text { display: none; }
  .appbar .page-title { display: block; }
  /* The phone's tab bar: a soft capsule floating over the page (glass, like the menus), our own round icons
     (/assets/tab-icons/, drawn as masks in the text's colour); the current tab sits in a small pale-vine pebble with its
     icon filled in, the pebble arriving with a gentle spring. Each tab ≥ 56 × 64 px; the home indicator stays clear. */
  .tabbar {
    display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
    position: fixed; z-index: var(--z-bar);
    inset-inline: max(10px, env(safe-area-inset-left)) max(10px, env(safe-area-inset-right));
    inset-block-end: max(8px, env(safe-area-inset-bottom));
    block-size: calc(var(--tabbar-h) - 8px); padding-inline: 4px;
    border-radius: 24px; background: var(--glass); border: 1px solid var(--glass-border);
    backdrop-filter: blur(18px) saturate(1.2); -webkit-backdrop-filter: blur(18px) saturate(1.2);
    box-shadow: var(--lift), inset 0 1px 0 color-mix(in srgb, var(--card) 70%, transparent);
  }
  .tabbar > a, .tabbar > .tab-pick, .tabbar > .mu-tab { display: grid; place-items: center; align-content: center; gap: 3px; position: relative; min-inline-size: 0;
    color: var(--muted); text-decoration: none; font: inherit; font-size: .72rem; background: none; border: 0; padding: 0; cursor: pointer;
    -webkit-tap-highlight-color: transparent; }
  .tabbar > a > span, .tabbar > .tab-pick > span { max-inline-size: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding-inline: 1px; }
  .tabbar svg { inline-size: 24px; block-size: 24px; }
  @media (max-width: 400px) { .tabbar > a, .tabbar > .tab-pick, .tabbar > .mu-tab { font-size: .66rem; } }
  /* our icons in place of the generic ones, keyed by the tab (data-guide is set by common.js); an unknown tab keeps its svg */
  .tabbar [data-guide^="tab-"] > svg { display: none; }
  .tabbar [data-guide^="tab-"]::after { content: ""; order: -1; inline-size: 26px; block-size: 26px; background: currentColor;
    -webkit-mask: var(--tab-ic) center / contain no-repeat; mask: var(--tab-ic) center / contain no-repeat;
    transition: transform .3s cubic-bezier(.3, 1.6, .5, 1); }
  .tabbar [data-guide="tab-home"] { --tab-ic: url(/assets/tab-icons/home.svg); }
  .tabbar [data-guide="tab-family"] { --tab-ic: url(/assets/tab-icons/family.svg); }
  .tabbar [data-guide="tab-compass"] { --tab-ic: url(/assets/tab-icons/compass.svg); }
  .tabbar [data-guide="tab-tools"] { --tab-ic: url(/assets/tab-icons/tools.svg); }
  .tabbar [data-guide="tab-settings"] { --tab-ic: url(/assets/tab-icons/settings.svg); }
  .tabbar [data-guide="tab-home"]:is([aria-current="page"], [aria-expanded="true"]) { --tab-ic: url(/assets/tab-icons/home-on.svg); }
  .tabbar [data-guide="tab-family"]:is([aria-current="page"], [aria-expanded="true"]) { --tab-ic: url(/assets/tab-icons/family-on.svg); }
  .tabbar [data-guide="tab-compass"]:is([aria-current="page"], [aria-expanded="true"]) { --tab-ic: url(/assets/tab-icons/compass-on.svg); }
  .tabbar [data-guide="tab-tools"]:is([aria-current="page"], [aria-expanded="true"]) { --tab-ic: url(/assets/tab-icons/tools-on.svg); }
  .tabbar [data-guide="tab-settings"]:is([aria-current="page"], [aria-expanded="true"]) { --tab-ic: url(/assets/tab-icons/settings-on.svg); }
  /* the current tab (or the open menu): its colour, a little bolder, and the pebble behind the icon */
  .tabbar > :is([aria-current="page"], [aria-expanded="true"]) { color: var(--primary); font-weight: 600; }
  .tabbar > :is(a, .tab-pick)::before { content: ""; position: absolute; z-index: -1; inset-block-start: calc(50% - 25px); inset-inline-start: 50%;
    inline-size: 54px; block-size: 32px; margin-inline-start: -27px; border-radius: 999px;
    background: color-mix(in srgb, var(--primary) 16%, transparent); opacity: 0; transform: scale(.4, .7); }
  .tabbar > :is([aria-current="page"], [aria-expanded="true"])::before { opacity: 1; transform: none; animation: tab-pebble 240ms cubic-bezier(.3, 1.5, .5, 1); }
  @keyframes tab-pebble { from { opacity: 0; transform: scale(.4, .7); } }
  .tabbar > :is(a, .tab-pick):active::after { transform: scale(.86); }
  .tabbar > :is(a, .tab-pick):focus-visible { outline: none; }
  .tabbar > :is(a, .tab-pick):focus-visible::before { opacity: 1; transform: none; box-shadow: 0 0 0 2px var(--primary); }
}
/* The top bar's menus (ניווט, כלים): a button like the links, its caret turning as it opens; the menu is a glass panel
   that arrives softly under it (on transform and opacity only) – each place an icon on its own pale tile and its name;
   the tools in two columns on a computer. On a phone the menu rises above the tab bar as a grid, like a phone's apps. */
.topnav .nav-menu { font: inherit; font-size: .98rem; color: var(--text); background-color: transparent; border: 0; padding: 6px 0; cursor: pointer; white-space: nowrap;
  display: inline-flex; align-items: center; gap: 5px; }
.topnav .nav-menu[aria-expanded="true"] { color: var(--primary); }
/* "עץ המשפחה" on two lines, one word over the other (the master's markup in common.js): centred, close, a touch smaller than one line */
.topnav .nav-two { display: inline-grid; justify-items: center; line-height: 1.06; text-align: center; font-size: .92em; }
.nav-caret { display: inline-block; font-size: .7em; opacity: .7; transition: transform .25s var(--ease-river); }
.nav-menu[aria-expanded="true"] .nav-caret { transform: rotate(180deg); opacity: 1; }
.navmenu { position: fixed; z-index: var(--z-menu); min-inline-size: 240px; max-inline-size: min(340px, calc(100vw - 32px)); max-block-size: min(72vh, 540px); overflow: auto;
  padding: 8px; border-radius: 20px; color: var(--text); background: color-mix(in srgb, var(--card) 94%, transparent); border: 1px solid var(--glass-border);
  -webkit-backdrop-filter: blur(20px) saturate(1.1); backdrop-filter: blur(20px) saturate(1.1); box-shadow: var(--lift), 0 2px 0 rgba(46, 42, 30, .03);
  transform-origin: 50% 0; animation: navmenu-in .2s var(--ease-river) both; overscroll-behavior: contain; }
@keyframes navmenu-in { from { opacity: 0; transform: translateY(-6px) scale(.98); } }
.navmenu ul { list-style: none; margin: 0; padding: 0; display: grid; gap: 2px; }
.navmenu a { display: flex; align-items: center; gap: 12px; padding: 7px 10px 7px 12px; border-radius: 14px; color: var(--text); text-decoration: none; font-size: .98rem;
  transition: transform var(--dur-press) var(--ease-river), background-color .15s; }
/* the icon on its own pale tile */
.navmenu li > a > .icon { box-sizing: content-box; inline-size: 20px; block-size: 20px; padding: 7px; border-radius: 11px; flex: none;
  color: var(--icon-ink); background: color-mix(in srgb, var(--olive) 26%, #f7f6f0); stroke-width: 1.7; }   /* a pastel tile, in ink, by day and at night */
.navmenu a:hover, .navmenu a:focus-visible { background: color-mix(in srgb, var(--primary) 10%, transparent); color: var(--primary); outline: none; }
.navmenu a:focus-visible { box-shadow: inset 0 0 0 2px var(--primary); }
.navmenu a[aria-current="page"] { color: var(--primary); font-weight: 500; }
.navmenu a[aria-current="page"] > .icon { background: color-mix(in srgb, #55622f 28%, #f7f6f0); }
.navmenu .navmenu-all { justify-content: center; gap: 6px; margin-block-start: 6px; padding-block: 10px; border-radius: 12px; font-size: .9rem; color: var(--muted);
  background: color-mix(in srgb, var(--text) 4%, transparent); }
/* the tools: two columns on a computer */
@media (min-width: 900px) { #navmenu-tools { min-inline-size: 440px; max-inline-size: min(480px, calc(100vw - 32px)); } #navmenu-tools ul { grid-template-columns: 1fr 1fr; } }
/* a phone: above the tab bar, a grid of places (icon on top, name under it) */
.navmenu-phone { inset-inline: 12px; inset-block-start: auto !important; inset-block-end: calc(var(--tabbar-h) + env(safe-area-inset-bottom) + 10px); max-inline-size: none;
  min-inline-size: 0; padding: 10px; border-radius: 24px; transform-origin: 50% 100%; animation-name: navmenu-up; }
@keyframes navmenu-up { from { opacity: 0; transform: translateY(10px) scale(.98); } }
.navmenu-phone ul { grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 4px; }
.navmenu-phone li > a { flex-direction: column; justify-content: flex-start; gap: 6px; padding: 10px 4px 9px; text-align: center; font-size: .84rem; line-height: 1.25; }
.navmenu-phone li > a > .icon { inline-size: 24px; block-size: 24px; padding: 10px; border-radius: 15px; }
.navmenu-phone li > a > span { overflow-wrap: anywhere; }
.navmenu-phone .navmenu-all { flex-direction: row; }
/* the settings: the person's chip, its gear turning a little under the pointer */
.userchip .icon { inline-size: 17px; block-size: 17px; transition: transform var(--dur-quick) var(--ease-river); }
.userchip:hover .icon { transform: rotate(60deg); }
.userchip[aria-current="page"] { border-color: var(--primary); color: var(--primary); }
@media (prefers-reduced-motion: reduce) { .navmenu, .navmenu-phone { animation: none; } .nav-caret, .userchip .icon { transition: none; } }
/* the tools menu as an accordion of the toolbox's categories: one open at a time. The JS (common.js) animates the open, the close
   and the glide of the rows below with WAAPI (transform and opacity only); the CSS gives the rows, the caret and the origin. */
.nm-cats { display: grid; }
.nm-cat + .nm-cat { border-block-start: 1px solid var(--line); }
.nm-cat-btn { display: flex; align-items: center; gap: 10px; inline-size: 100%; min-block-size: 48px; padding: 6px 12px; border: 0; border-radius: 14px;
  background: none; color: var(--text); font: inherit; font-size: .98rem; font-weight: 500; text-align: start; cursor: pointer;
  transition: transform var(--dur-press) var(--ease-river); }
.nm-cat-btn:hover, .nm-cat-btn:focus-visible { background: color-mix(in srgb, var(--primary) 8%, transparent); outline: none; }
.nm-cat-btn:focus-visible { box-shadow: inset 0 0 0 2px var(--primary); }
.nm-cat-btn:active { transform: scale(.985); }
.nm-cat-name { flex: 1; min-inline-size: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.nm-cat-n { flex: none; min-inline-size: 24px; padding: 1px 7px; border-radius: 999px; text-align: center; font-size: .78rem; font-weight: 500;
  font-variant-numeric: tabular-nums; color: var(--muted); background: color-mix(in srgb, var(--text) 6%, transparent); }
.nm-cat-caret { flex: none; display: inline-grid; place-items: center; inline-size: 20px; block-size: 20px; color: var(--muted); font-size: .9rem; line-height: 1;
  transition: transform var(--dur-quick) var(--ease-river); }
.nm-cat.open > .nm-cat-btn { color: var(--primary); }
.nm-cat.open > .nm-cat-btn .nm-cat-n { color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); }
.nm-cat.open .nm-cat-caret { transform: rotate(180deg); color: var(--primary); }
.nm-cat-list { transform-origin: 50% 0; padding-block: 2px 8px; }
.nm-cat-list[hidden] { display: none; }
.navmenu-phone .nm-cat-btn { min-block-size: 50px; font-size: .95rem; }
@media (prefers-reduced-motion: reduce) { .nm-cat-caret, .nm-cat-btn { transition: none; } }
:root[data-motion="reduce"] :is(.nm-cat-caret, .nm-cat-btn) { transition: none; }
.icon { inline-size: 20px; block-size: 20px; flex: none; stroke: currentColor; fill: none; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round; }

.stats { color: var(--muted); font-size: .9rem; white-space: nowrap; }
.card { background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); margin: 14px 0; }

/* ---------- forms ---------- */
input[type="text"], input[type="search"], input[type="url"], input[type="email"], select, textarea {
  font: inherit; font-size: 1rem; color: var(--text); background: var(--card);
  border: 1px solid var(--line-strong); border-radius: var(--radius); padding: 10px 12px; min-width: 0;
  transition: border-color var(--dur-quick) var(--ease-river), box-shadow var(--dur-quick) var(--ease-river);
}
input:focus, select:focus, textarea:focus { outline: none; border-color: var(--primary); box-shadow: inset 0 -2px 0 var(--primary); }
textarea { width: 100%; resize: vertical; }
.add-form, .recipe-form { display: flex; flex-wrap: wrap; gap: 8px; padding: 12px; }
.add-form input, .recipe-form input { flex: 1 1 220px; }
.add-form select { flex: 0 1 190px; }
.hint { flex-basis: 100%; color: var(--muted); font-size: .85rem; min-height: 1.1em; }
.field { display: grid; gap: 4px; margin: 10px 0; }
.field > span { font-size: .85rem; color: var(--muted); }
.field input, .field select { width: 100%; }

.btn {
  font: inherit; font-size: .98rem; font-weight: 500; cursor: pointer; border: 1px solid transparent; border-radius: var(--radius);
  padding: 10px 16px; background: transparent; color: var(--text); white-space: nowrap; text-decoration: none; display: inline-flex; align-items: center; gap: 8px;
  transition: background-color var(--dur-quick) var(--ease-river), border-color var(--dur-quick) var(--ease-river), color var(--dur-quick) var(--ease-river), transform var(--dur-press) var(--ease-river);
}
.btn:active { transform: scale(.97); }
.btn.primary { background: var(--primary); color: var(--primary-ink); }
.btn.primary:hover { background: color-mix(in srgb, var(--primary) 88%, var(--ink)); }
.btn.accent { background: var(--accent); color: var(--accent-ink); }
.btn.accent:hover { background: color-mix(in srgb, var(--accent) 88%, var(--ink)); }
.btn.ghost { border-color: var(--line-strong); }
/* a plain button (no primary, accent, ghost or ✨): a soft fill and a quiet edge, so a secondary action reads as a button
   and not as bare text – by day and at night (it used to be transparent with no edge) */
.btn:where(:not(.primary, .accent, .ghost, .ai-up)) { background: color-mix(in srgb, var(--text) 6%, var(--card)); border-color: color-mix(in srgb, var(--text) 14%, transparent); }
.btn:where(:not(.primary, .accent, .ghost, .ai-up)):hover { background: color-mix(in srgb, var(--text) 10%, var(--card)); border-color: var(--primary); }
.btn:where(:not(.primary, .accent, .ghost, .ai-up)):disabled { opacity: .55; }
.btn.ghost:hover { border-color: var(--primary); color: var(--primary); }
.btn.small { padding: 6px 12px; font-size: .88rem; }
.btn:disabled { opacity: .55; cursor: default; }

.toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.toggle { display: inline-flex; gap: 8px; align-items: center; margin-inline-end: auto; color: var(--muted); font-size: .92rem; }
.toggle input { accent-color: var(--primary); inline-size: 18px; block-size: 18px; }

.banner { padding: 10px 12px; display: flex; flex-wrap: wrap; gap: 6px; align-items: center; border: 1px solid var(--olive); background: color-mix(in srgb, var(--olive) 14%, var(--card)); }
.chip { font: inherit; font-size: .88rem; cursor: pointer; border-radius: 999px; border: 1px solid var(--line-strong); background: var(--card); color: var(--text); padding: 5px 12px; transition: border-color var(--dur-quick), transform var(--dur-press) var(--ease-river); }
.chip:hover { border-color: var(--primary); color: var(--primary); }
/* A person's name with their one title and the badges they chose to show (business, 2026-11-13: the profile, the tree,
   the RSVPs). <span class="who"><b>שם</b> <span class="who-title founder">חבר מייסד</span>
   <span class="who-badges"><img src="/assets/badges/peg.webp" alt="יתד ראשונה">…</span></span>
   Titles: plain (מהעשרה / מהחמישים / מהמאה הראשונים, תומך קבוע, מלאך…), .founder (חבר/ה מייסד/ת, תומך/ת מייסד/ת, האור לפני
   המחנה), .gold (the one-off "המיליון"). Up to five badges; their names are the images' alt. */
.who { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-inline-size: 0; }
.who-title { display: inline-flex; align-items: center; padding: 1px 9px; border-radius: 999px; font-size: .74rem; font-weight: 600; line-height: 1.5; white-space: nowrap;
  background: color-mix(in srgb, var(--text) 7%, var(--card)); color: var(--text); border: 1px solid color-mix(in srgb, var(--text) 12%, transparent); }
.who-title.founder { background: color-mix(in srgb, var(--olive) 28%, var(--card)); border-color: color-mix(in srgb, var(--olive) 60%, transparent); }
.who-title.gold { background: linear-gradient(135deg, #f6d77a, #d9a63a); border-color: #b9862a; color: #3a2a0c; }
.who-badges { display: inline-flex; align-items: center; }
.who-badges img { inline-size: 22px; block-size: 22px; object-fit: contain; filter: drop-shadow(0 1px 1px rgba(30, 20, 10, .25)); }
.who-badges img + img { margin-inline-start: -4px; }
.chip[aria-pressed="true"], .chip[aria-checked="true"] { background: var(--primary); border-color: var(--primary); color: var(--primary-ink); }
.chip[aria-pressed="true"]:hover, .chip[aria-checked="true"]:hover { background: color-mix(in srgb, var(--primary) 88%, var(--text)); color: var(--primary-ink); }

/* ---------- the glass sheet (recipes and dialogs) ---------- */
.modal { position: fixed; inset: 0; z-index: var(--z-sheet); display: grid; place-items: center; padding: 16px; }
.modal[hidden] { display: none; }
.modal-backdrop { position: absolute; inset: 0; background: rgba(46, 42, 30, .28); backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px); animation: fade var(--dur-quick) ease; }
.modal-glass {
  position: relative; width: min(700px, 100%); max-height: min(86vh, 900px); overflow: hidden;
  display: flex; flex-direction: column;
  background: var(--glass); backdrop-filter: blur(22px) saturate(1.3); -webkit-backdrop-filter: blur(22px) saturate(1.3);
  border: 1px solid var(--glass-border); border-radius: var(--radius-lg); box-shadow: var(--lift);
  animation: arrive var(--dur-draw) var(--ease-river) both;
}
/* a window opened from a thing on the page (H.modalFrom: a pie, a card) grows out of it and shrinks back into it;
   common.js animates the glass with the Web Animations API, so the CSS only steps aside and fades the backdrop */
.modal.grow .modal-glass { animation: none; }
.modal.shrinking { pointer-events: none; }
.modal.shrinking .modal-backdrop { opacity: 0; transition: opacity 200ms var(--ease-leave); }
#modalBody { overflow-y: auto; padding: 22px 22px 26px; -webkit-overflow-scrolling: touch; }
/* On a phone the window is an app-style sheet that rises from the bottom: opaque (long forms stay readable) and full width. */
@media (max-width: 520px) {
  .modal { padding: 0; place-items: end stretch; }
  .modal-glass { width: 100%; max-height: 94dvh; border-radius: 22px 22px 0 0; background: var(--card); border-block-end: 0; backdrop-filter: none; -webkit-backdrop-filter: none; }
  #modalBody { padding: 18px 16px calc(24px + env(safe-area-inset-bottom)); }
}
.modal-close { position: absolute; top: 12px; inset-inline-end: 12px; z-index: 1; font: inherit; inline-size: 36px; block-size: 36px; border-radius: 50%; border: 1px solid var(--line-strong); background: var(--card); color: var(--text); cursor: pointer; }
.modal-close:hover { border-color: var(--primary); color: var(--primary); }
#modalBody h3 { margin: 0 0 6px; padding-inline-end: 44px; font-size: 1.3rem; }
#modalBody h4 { margin: 20px 0 6px; font-size: 1.02rem; }
.loading { display: flex; gap: 12px; align-items: center; padding: 24px 4px; color: var(--muted); }
.spinner { inline-size: 18px; block-size: 18px; border-radius: 50%; border: 2px solid var(--line-strong); border-block-start-color: var(--primary); animation: spin .8s linear infinite; }
.results { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; margin-top: 12px; }
.result { font: inherit; color: var(--text); cursor: pointer; text-align: start; padding: 0; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--card); transition: border-color var(--dur-quick); }
.result:hover { border-color: var(--primary); }
.result img { width: 100%; aspect-ratio: 1; object-fit: cover; display: block; }
.result span { display: block; padding: 8px 10px; font-size: .88rem; direction: ltr; text-align: left; }
.back { margin-bottom: 10px; }
.recipe-head { display: flex; gap: 16px; align-items: flex-start; }
.recipe-head img { width: 124px; height: 124px; object-fit: cover; border-radius: var(--radius); flex: none; }
.recipe-head h3 { direction: ltr; text-align: right; }
.links { display: flex; flex-wrap: wrap; gap: 14px; font-size: .92rem; }
.ing-tools { display: flex; gap: 6px; margin-bottom: 4px; }
.ingredients { list-style: none; padding: 0; margin: 0 0 14px; }
.ingredients li { border-bottom: 1px solid var(--line); }
.ingredients label { display: flex; align-items: center; gap: 10px; padding: 8px 2px; cursor: pointer; flex-wrap: wrap; }
.ingredients input { width: 20px; height: 20px; accent-color: var(--primary); }
.measure { color: var(--muted); margin-inline-start: auto; direction: ltr; }
.steps { padding-left: 20px; text-align: left; font-size: .95rem; }
.steps li { margin-bottom: 8px; }
@media (max-width: 899px) {
  .modal { padding: 0; align-items: end; }
  .modal-glass { border-radius: 22px 22px 0 0; max-height: calc(92dvh - env(safe-area-inset-top)); }
  #modalBody { padding-block-end: calc(26px + env(safe-area-inset-bottom)); }
  .recipe-head img { width: 88px; height: 88px; }
}

/* ---------- messages ---------- */
/* A pop-up message (H.toast; vision batch 17, docs/design/toast.md): a light glass pill at the top of the screen, short-lived.
   It goes on a swipe (up or sideways) on a phone and on a click on the PC. While a finger drags it, common.js sets the
   inline `translate` (which adds to the transform here) and `opacity`, and the class .dragging; a small nudge springs back. */
.toast {
  position: fixed; z-index: var(--z-toast); inset-block-start: calc(var(--appbar-h, 0px) + env(safe-area-inset-top, 0px) + 8px);
  inset-inline: 0; margin-inline: auto;      /* centred without a sideways transform, so `translate` is the swipe alone */
  display: flex; gap: 10px; align-items: center; box-sizing: border-box;
  inline-size: max-content; max-inline-size: min(480px, calc(100% - 32px)); min-block-size: 40px; padding: 8px 18px;
  border-radius: 22px; font-size: .9rem; line-height: 1.35; color: var(--text);
  background: color-mix(in srgb, var(--card) 66%, transparent);
  -webkit-backdrop-filter: blur(18px) saturate(1.4); backdrop-filter: blur(18px) saturate(1.4);
  border: 1px solid var(--glass-border); box-shadow: 0 6px 22px rgba(0, 0, 0, .12);
  cursor: pointer; user-select: none; -webkit-user-select: none; touch-action: none; pointer-events: none;
  opacity: 0; transform: translateY(calc(-100% - 16px));
  transition: transform var(--dur-draw) var(--ease-river), translate var(--dur-draw) var(--ease-river), opacity 220ms ease;
}
.toast > span { min-inline-size: 0; }
.toast.show { pointer-events: auto; opacity: 1; transform: none; }
.toast.dragging { transition: none; }
.toast .btn { flex: none; min-block-size: 32px; padding: 4px 12px; border-radius: 999px; font-weight: 600;
  color: var(--primary); background: color-mix(in srgb, var(--primary) 12%, transparent); border: 0; }
.toast .btn:hover { background: color-mix(in srgb, var(--primary) 20%, transparent); }
@media (hover: hover) { .toast.show:hover { background: color-mix(in srgb, var(--card) 86%, transparent); } }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .toast { box-shadow: 0 8px 26px rgba(0, 0, 0, .4); } }
:root[data-theme="dark"] .toast { box-shadow: 0 8px 26px rgba(0, 0, 0, .4); }
/* no backdrop blur (old browsers): a solid card, so the words stay readable */
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) { .toast { background: var(--card); } }
@media (prefers-reduced-motion: reduce) { .toast { transform: none; transition: opacity 160ms linear; } }
:root[data-motion="reduce"] .toast { transform: none; transition: opacity 160ms linear; }

@keyframes arrive { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes fade { from { opacity: 0; } }
@keyframes spin { to { transform: rotate(360deg); } }
@media (prefers-reduced-motion: reduce) { * { animation: none !important; transition: none !important; } }

/* ---------- moving between the tent's pages: a quiet turn of the page ----------
   Cross-document View Transitions: the page fades and moves a few pixels the way a Hebrew page turns (the next one
   arrives from the left), about a fifth of a second. The top bar and the phone's tab bar stay put, as if only the
   page under them changed. Browsers without it navigate as before; with less motion (the device's or the app's) none. */
@view-transition { navigation: auto; }
.appbar { view-transition-name: appbar; }
.tabbar { view-transition-name: tabbar; }
::view-transition-group(appbar), ::view-transition-group(tabbar) { animation: none; }
::view-transition-old(appbar), ::view-transition-old(tabbar), ::view-transition-new(appbar), ::view-transition-new(tabbar) { animation-duration: 120ms; }
/* a shared axis (Telegram's way): the old page leaves 20 px along the reading axis while it fades, the new one arrives from the other side.
   Forward = the new page from the start side's far edge (RTL: from the left); html[data-vt="back"] reverses it (set by the master's pageswap
   listener: going to an earlier tab, or the browser's back). Without View Transitions the page just loads, as before. */
::view-transition-old(root) { animation: page-out 140ms var(--ease-leave) both; }
::view-transition-new(root) { animation: page-in 220ms var(--ease-river) 40ms both; }
@keyframes page-out { to { opacity: 0; transform: translateX(20px); } }
@keyframes page-in { from { opacity: 0; transform: translateX(-20px); } }
:root[data-vt="back"]::view-transition-old(root) { animation-name: page-out-back; }
:root[data-vt="back"]::view-transition-new(root) { animation-name: page-in-back; }
@keyframes page-out-back { to { opacity: 0; transform: translateX(-20px); } }
@keyframes page-in-back { from { opacity: 0; transform: translateX(20px); } }
@media (prefers-reduced-motion: reduce) { @view-transition { navigation: none; } }
:root[data-motion="reduce"]::view-transition-group(*), :root[data-motion="reduce"]::view-transition-old(*), :root[data-motion="reduce"]::view-transition-new(*) { animation: none !important; }

/* ---------- shared bits ---------- */
.tabs { display: flex; gap: 22px; margin: 18px 0 0; border-block-end: 1px solid var(--line); }
.tabs button { font: inherit; cursor: pointer; border: 0; background: none; color: var(--muted); padding: 10px 0; position: relative; }
.tabs button[aria-selected="true"] { color: var(--primary); font-weight: 500; }
.tabs button[aria-selected="true"]::after { content: ''; position: absolute; inset-inline: 0; inset-block-end: -1px; block-size: 2px; background: var(--primary); }
/* a tab that opens a menu of its own (vision batch 16: the recipe book, "שלי" or "ששותפו איתי"). The menu is a sibling of
   .tabs inside .tabs-wrap, never inside .tabs, which scrolls sideways on a phone and would clip it. --x is set from the
   tab's place (docs/design/recipe-book-menu.md); the menu never leaves the wrap. */
.tabs-wrap { position: relative; }
.tabs button[aria-haspopup] { display: inline-flex; align-items: center; gap: 4px; }
.tab-caret { inline-size: 16px; block-size: 16px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round;
  transition: transform var(--dur-quick) var(--ease-river); }
.tabs button[aria-expanded="true"] .tab-caret { transform: rotate(180deg); }
.tab-dot { inline-size: 8px; block-size: 8px; border-radius: 50%; background: var(--primary); flex: none; margin-inline-start: 2px; }
.tab-menu { position: absolute; z-index: 30; inset-block-start: calc(100% + 6px); inline-size: min(300px, 100%);
  inset-inline-start: clamp(0px, var(--x, 0px), calc(100% - min(300px, 100%)));
  display: grid; gap: 2px; padding: 6px; background: var(--card); border: 1px solid var(--line); border-radius: var(--radius);
  box-shadow: var(--lift); transform-origin: top; animation: tab-menu-in var(--dur-quick) var(--ease-river) both; }
.tab-menu[hidden] { display: none; }
@keyframes tab-menu-in { from { opacity: 0; transform: translateY(-4px) scale(.98); } }
.tab-menu button { font: inherit; color: var(--text); text-align: start; cursor: pointer; border: 0; background: none; border-radius: calc(var(--radius) - 4px);
  display: flex; align-items: center; gap: 12px; min-block-size: 52px; padding: 8px 10px; }
.tab-menu button:hover { background: color-mix(in srgb, var(--text) 5%, transparent); }
.tab-menu button:focus-visible { outline: 2px solid var(--primary); outline-offset: -2px; }
.tab-menu button > .icon { inline-size: 22px; block-size: 22px; flex: none; color: var(--muted); fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linecap: round; stroke-linejoin: round; }
.tab-menu button > span { flex: 1; min-inline-size: 0; display: grid; }
.tab-menu b { font-weight: 500; }
.tab-menu small { font-size: .84rem; color: var(--muted); }
.tab-menu .tab-menu-n { flex: none; min-inline-size: 26px; padding: 1px 8px; border-radius: 999px; text-align: center; font-size: .82rem; font-weight: 600;
  font-variant-numeric: tabular-nums; background: color-mix(in srgb, var(--text) 7%, transparent); color: var(--muted); }
/* the chosen one: the vine, as everything chosen in the hub */
.tab-menu [aria-checked="true"] { background: color-mix(in srgb, var(--primary) 10%, transparent); }
.tab-menu [aria-checked="true"] > .icon, .tab-menu [aria-checked="true"] b { color: var(--primary); }
.tab-menu [aria-checked="true"] .tab-menu-n { background: color-mix(in srgb, var(--primary) 16%, transparent); color: var(--primary); }
:root[data-motion="reduce"] .tab-menu, :root[data-motion="reduce"] .tab-caret { animation: none; transition: none; }
@media (prefers-reduced-motion: reduce) { .tab-menu, .tab-caret { animation: none; transition: none; } }
.row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.spacer { flex: 1; }
.notice { padding: 12px 16px; border-radius: var(--radius); background: var(--card); border: 1px solid var(--line); border-inline-start: 3px solid var(--primary); }
.notice.warn { border-inline-start-color: var(--olive); background: color-mix(in srgb, var(--olive) 10%, var(--card)); }
.muted { color: var(--muted); }
.mini { font: inherit; cursor: pointer; border: 1px solid transparent; background: transparent; color: var(--muted); inline-size: 34px; block-size: 34px; border-radius: var(--radius-sm); flex: none; display: inline-grid; place-items: center; transition: border-color var(--dur-quick), color var(--dur-quick); }
.mini:hover { border-color: var(--line-strong); color: var(--text); }
.mini.danger:hover { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 40%, transparent); }

/* a page shown inside another page's window (?embed=1): no bars of its own */
html.embedded .appbar, html.embedded .tabbar { display: none !important; }
html.embedded body { padding-block-end: 0; }

/* "שמירה כפתק" by a text selection (assets/capture.js) */
.cap-btn { position: fixed; z-index: var(--z-float); inset-block-start: 0; left: 0; padding: 7px 14px; border-radius: 999px; border: 1px solid var(--glass-border); font: inherit; font-size: .9rem; font-weight: 500;
  background: var(--text); color: var(--bg); box-shadow: var(--lift); cursor: pointer; animation: cap-in .18s ease-out; }
.cap-btn[hidden] { display: none; }
@keyframes cap-in { from { opacity: 0; transform: translateY(4px); } }
/* the AI invitation (ai-invite.js): when someone's AI credit runs out it is not an error but an invitation – Ibn Ezra's
   face on a warm round field, a kind sentence, and the way on */
.ai-invite { display: grid; justify-items: center; text-align: center; gap: 10px; padding-block: 6px 2px; max-inline-size: 420px; margin-inline: auto; }
.ai-invite::before { content: ""; inline-size: 96px; block-size: 96px; border-radius: 50%;
  background: url(/assets/ibn-ezra-face.webp) center 30% / 84% no-repeat, radial-gradient(circle at 50% 40%, color-mix(in srgb, var(--olive) 38%, var(--card)), color-mix(in srgb, var(--tint) 70%, var(--card)));
  box-shadow: 0 0 0 6px color-mix(in srgb, var(--olive) 14%, transparent), 0 12px 26px -14px rgba(46, 42, 30, .5); }
.ai-invite h2 { margin: 4px 0 0; font-size: 1.35rem; text-wrap: balance; }
.ai-invite p { margin: 0; line-height: 1.6; color: var(--muted); max-inline-size: 34ch; }
.ai-invite .sky-acts { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; margin-block-start: 8px; inline-size: 100%; }
.ai-invite .sky-acts .btn { flex: 1 1 140px; justify-content: center; min-block-size: 44px; }
/* A tool without AI is a whole tool; the AI is an upgrade inside it (docs/design/ai-upgrade.md): the plain action and its
   ✨ upgrade side by side, the upgrade quieter, in the olive field; with no AI it is an offer (a small "חדש"), never a lock;
   and what the AI made is marked under it */
.ai-pair { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.btn.ai-up { background: color-mix(in srgb, var(--accent) 22%, var(--card)); border-color: color-mix(in srgb, var(--accent) 55%, var(--line)); color: var(--text); }
.btn.ai-up:hover { background: color-mix(in srgb, var(--accent) 34%, var(--card)); border-color: var(--accent); }
.btn.ai-up.offer { position: relative; }
.btn.ai-up.offer::after { content: "חדש"; position: absolute; inset-block-start: -8px; inset-inline-end: -6px; padding: 1px 7px; border-radius: 999px;
  font-size: .68rem; font-weight: 600; background: var(--accent); color: var(--accent-ink); box-shadow: 0 2px 6px rgba(0, 0, 0, .15); }
.ai-note { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin: 6px 0 0; font-size: .82rem; color: var(--muted); }
.ai-note button { font: inherit; border: 0; background: none; padding: 0; color: var(--primary); cursor: pointer; text-decoration: underline; text-underline-offset: 3px; }

/* ---------- the owner's messages (messages.js): cards floating above the tab bar, so nothing on the page moves (CLS) ---------- */
.owner-msgs { position: fixed; z-index: var(--z-msg); inset-inline: 12px; inset-block-end: calc(var(--tabbar-h, 0px) + env(safe-area-inset-bottom) + 12px);
  max-inline-size: 560px; margin-inline: auto; display: grid; gap: 8px; pointer-events: none; }
/* a page with a floating button (the groceries' cart): the messages stand above it, never over it */
.owner-msgs[hidden], .owner-msg[hidden] { display: none; }
body:has(.fab-wrap) .owner-msgs { inset-block-end: calc(var(--tabbar-h, 0px) + env(safe-area-inset-bottom) + 18px + 58px + 14px); }
.owner-msg { pointer-events: auto; display: flex; align-items: center; gap: 10px; margin: 0; padding-block: 9px; padding-inline: 12px 6px; border-radius: 16px;
  background: var(--card); border: 1px solid var(--line); border-inline-start: 4px solid var(--primary); line-height: 1.45;
  box-shadow: 0 12px 30px -10px rgba(30, 24, 12, .38), 0 2px 6px rgba(30, 24, 12, .08); }
.owner-msg > span:nth-child(2) { flex: 1; min-inline-size: 0; overflow-wrap: anywhere; }
.owner-msg a { color: inherit; font-weight: 600; text-decoration-color: color-mix(in srgb, var(--primary) 60%, transparent); text-underline-offset: 3px; }
/* its mark: our own drawn sign by level (.info, .party, .warn) in place of an emoji */
.owner-msg-ico { flex: none; display: grid; place-items: center; inline-size: 30px; block-size: 30px; border-radius: 50%; background: color-mix(in srgb, var(--primary) 14%, var(--card)); }
.owner-msg-ico::before { content: ""; inline-size: 17px; block-size: 17px; background: var(--primary);
  -webkit-mask: var(--om-ico) center / contain no-repeat; mask: var(--om-ico) center / contain no-repeat; }
.owner-msg { --om-ico: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M4 4h16a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2h-9l-5 4v-4H4a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2z'/></svg>"); }
.owner-msg.party { --om-ico: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M12 1.5l2.6 7.1 7.4.4-5.8 4.7 2 7.3L12 16.9 5.8 21l2-7.3L2 9l7.4-.4z'/></svg>"); }
.owner-msg.warn { --om-ico: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path fill-rule='evenodd' d='M12 2.5 1.5 21h21zM11 9h2v6h-2zm0 8h2v2h-2z'/></svg>");
  border-inline-start-color: #c98a1e; background: color-mix(in srgb, #e0a83a 9%, var(--card)); }
.owner-msg.warn .owner-msg-ico { background: color-mix(in srgb, #e0a83a 20%, var(--card)); }
.owner-msg.warn .owner-msg-ico::before { background: #b5791a; }
.owner-msg > .btn { flex: none; }

/* ── The back door's tab (admin-tab.js, on every page while the owner's back door is open): a vine tag at the inline-start
   edge under the top bar; the companion's tab is at the other edge. A door line icon (the emoji in .ad-edge-ic is hidden);
   on a phone only the icon shows, the words open on hover or focus. <a class="ad-edge" href="/admin/" [hidden]>
   <span class="ad-edge-ic">🚪</span><span class="ad-edge-text">דלת אחורית</span></a> */
.ad-edge { position: fixed; z-index: var(--z-float); inset-inline-start: 0; inset-block-start: calc(var(--appbar-h) + env(safe-area-inset-top, 0px) + 14px);
  display: flex; align-items: center; gap: 7px; min-block-size: 44px; padding-block: 0; padding-inline: max(12px, env(safe-area-inset-right, 0px)) 14px;
  background: var(--primary); color: var(--primary-ink); border-start-end-radius: 999px; border-end-end-radius: 999px;
  font-size: .86rem; font-weight: 600; text-decoration: none; box-shadow: var(--lift); transition: padding var(--dur-quick) var(--ease-river); }
.ad-edge[hidden] { display: none; }
.ad-edge-ic { flex: none; inline-size: 20px; block-size: 20px; font-size: 0; background: currentColor;
  -webkit-mask: url(/assets/bd-icons/door.svg) center / contain no-repeat; mask: url(/assets/bd-icons/door.svg) center / contain no-repeat; }
.ad-edge:hover { color: var(--primary-ink); background: color-mix(in srgb, var(--primary) 88%, var(--text)); }
.ad-edge:focus-visible { outline: 3px solid color-mix(in srgb, var(--primary) 45%, transparent); outline-offset: 2px; }
@media (max-width: 599px) {
  .ad-edge { padding-inline-end: 12px; }
  .ad-edge:not(:hover, :focus-visible) .ad-edge-text { display: none; }
}
@media (prefers-reduced-motion: reduce) { .ad-edge { transition: none; } }

/* ── The surprise egg (the owner, 2026-11-13; managed in the back door's עץ מבנה, placed by ai-features' script).
   Small and quiet: it sits where the script puts it, rocks a little now and then, and cracks open when found.
   <button class="egg" type="button" aria-label="ביצת הפתעה"></button>              in the flow (beside a heading, in a corner of a card)
   <button class="egg float" style="--x:24px; --y:140px" …></button>               or pinned to the screen: --x from the inline start, --y from the top
   found:  .egg.found, and <div class="egg-note" role="status">מצאתם את ביצת החנוכה!</div> appended to <body> (a bubble over the tab bar,
           never off the screen); the script removes both after ~2.6s.
   The two halves are the same drawing (/assets/egg/egg.svg) cut along a zigzag, so the shell splits where the band is. */
.egg { --egg-w: 24px; position: relative; display: inline-grid; place-items: center; inline-size: 44px; block-size: 44px; padding: 0; margin: -6px 0;
  vertical-align: middle; border: 0; border-radius: 50%; background: none; cursor: pointer; -webkit-tap-highlight-color: transparent;
  animation: egg-rock 7s ease-in-out infinite; transform-origin: 50% 82%; }
.egg.float { position: fixed; z-index: var(--z-float, 30); margin: 0; inset-block-start: var(--y, 50%); inset-inline-start: var(--x, 16px); }
.egg::before, .egg::after { content: ""; position: absolute; inset: 0; margin: auto; inline-size: var(--egg-w); block-size: calc(var(--egg-w) * 1.25);
  background: url(/assets/egg/egg.svg) center / contain no-repeat; filter: drop-shadow(0 2px 2px rgba(30, 24, 12, .3));
  transition: translate .5s cubic-bezier(.3, 1.6, .5, 1), rotate .5s cubic-bezier(.3, 1.6, .5, 1), opacity .4s ease; }
.egg::before { clip-path: polygon(0 0, 100% 0, 100% 53%, 87.5% 47%, 75% 53%, 62.5% 47%, 50% 53%, 37.5% 47%, 25% 53%, 12.5% 47%, 0 53%); }
.egg::after { clip-path: polygon(0 53%, 12.5% 47%, 25% 53%, 37.5% 47%, 50% 53%, 62.5% 47%, 75% 53%, 87.5% 47%, 100% 53%, 100% 100%, 0 100%); }
@keyframes egg-rock { 0%, 86%, 100% { rotate: 0deg; } 89% { rotate: -9deg; } 92% { rotate: 7deg; } 95% { rotate: -4deg; } 97.5% { rotate: 2deg; } }
@media (hover: hover) { .egg:hover { animation: none; } .egg:hover::before, .egg:hover::after { translate: 0 -2px; } }
.egg:focus-visible { outline: 3px solid color-mix(in srgb, var(--primary) 45%, transparent); outline-offset: -2px; }
:root[data-theme="dark"] .egg::before, :root[data-theme="dark"] .egg::after { filter: drop-shadow(0 0 1px rgba(255, 236, 210, .5)) drop-shadow(0 2px 3px rgba(0, 0, 0, .5)); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) .egg::before, :root:not([data-theme="light"]) .egg::after { filter: drop-shadow(0 0 1px rgba(255, 236, 210, .5)) drop-shadow(0 2px 3px rgba(0, 0, 0, .5)); } }
/* found: a warm glow, the top flies up and tips, then the note rises */
.egg.found { animation: egg-glow 1.2s ease-out both; cursor: default; pointer-events: none; }
.egg.found::before { translate: 3px -11px; rotate: 24deg; }
.egg.found::after { animation: egg-out .5s ease 1.9s both; }
.egg.found::before { animation: egg-out .5s ease 1.9s both; }
@keyframes egg-glow { 0% { background: radial-gradient(closest-side, rgba(255, 200, 90, .85), rgba(255, 170, 60, .35) 60%, transparent); scale: .8; }
  60% { background: radial-gradient(closest-side, rgba(255, 200, 90, .45), rgba(255, 170, 60, .15) 60%, transparent); scale: 1.4; }
  100% { background: radial-gradient(closest-side, transparent, transparent); scale: 1; } }
@keyframes egg-out { to { opacity: 0; } }
.egg-note { position: fixed; z-index: var(--z-toast, 70); inset-inline: 16px; inset-block-end: calc(var(--tabbar-h, 0px) + max(20px, env(safe-area-inset-bottom, 0px)));
  inline-size: max-content; max-inline-size: min(340px, calc(100vw - 32px)); margin-inline: auto; display: flex; align-items: center; gap: 10px;
  padding: 8px 16px 8px 12px; padding-inline: 10px 16px; border-radius: 999px; border: 1px solid color-mix(in srgb, #e3ad3c 55%, var(--line)); background: var(--card); color: var(--text);
  font-family: inherit; font-size: .95rem; font-weight: 600; line-height: 1.35; box-shadow: 0 10px 26px -8px rgba(30, 24, 12, .45); pointer-events: none;
  animation: egg-note 2.6s var(--ease-river) both; }
.egg-note::before { content: ""; flex: none; inline-size: 22px; block-size: 28px; background: url(/assets/egg/egg.svg) center / contain no-repeat; }
@keyframes egg-note { 0% { opacity: 0; transform: translateY(8px) scale(.9); } 14%, 80% { opacity: 1; transform: none; } 100% { opacity: 0; transform: translateY(-6px); } }
@media (prefers-reduced-motion: reduce) {
  .egg, .egg.found { animation: none; } .egg::before, .egg::after { transition: opacity .3s ease; }
  .egg.found::before { translate: none; rotate: none; } .egg-note { animation: egg-note-still 2.4s linear both; }
}
@keyframes egg-note-still { 0%, 85% { opacity: 1; } 100% { opacity: 0; } }

/* ---------- "חבר עוזר חינמי": connecting a free Gemini key in three steps (ai-invite.js; the logic is ai-features') ----------
   Made for older eyes: big type, few words, one big button at a time. It opens in H.modal (or inside settings' #services).
     <div class="gk" data-state="steps">                       (data-state="done" once the key is checked)
       <header class="gk-head"><span class="gk-free">חינם</span><h2>חבר עוזר חינמי</h2><p>שלושה צעדים, בערך דקה</p></header>
       <ol class="gk-steps">
         <li class="gk-step" data-pic="signin" aria-current="step">      (the step you are on; a finished one gets data-done)
           <span class="gk-pic" aria-hidden="true"></span>
           <div class="gk-txt"><b>נכנסים ל־Google</b><small>עם החשבון הרגיל שלכם</small></div>
           <a class="btn primary gk-go" href="https://aistudio.google.com/apikey" target="_blank" rel="noopener">פתיחת Google</a>
         </li>
         <li class="gk-step" data-pic="key">…<b>לוחצים <span class="gk-en">Create API key</span> ומעתיקים</b>…</li>
         <li class="gk-step" data-pic="paste">…<b>חוזרים לאוהל ולוחצים „הדבק”</b>… <button class="btn primary gk-go">הדבק</button></li>
       </ol>
       <p class="gk-err" role="alert" hidden>המפתח לא עבד. נסו להעתיק שוב.</p>
       <div class="gk-done" role="status"><span class="gk-ok">מחובר ✓</span><p>העוזר החכם עובד עכשיו על החשבון שלכם, בחינם.</p>
         <button class="btn primary gk-go" type="button">סיום</button></div>
       <button class="btn ghost gk-later" type="button">לא עכשיו</button>
     </div>
   Only the current step shows its button (big, primary); the others show their drawing and words. A step with no
   aria-current anywhere shows every button. The connected tag alone, for a settings row: <span class="gk-ok small">מחובר ✓</span>. */
.gk { display: grid; gap: 16px; max-inline-size: 460px; margin-inline: auto; font-size: 1.12rem; line-height: 1.5; padding-block: 4px; }
.gk-head { display: grid; justify-items: center; text-align: center; gap: 6px; }
.gk-head h2 { margin: 0; font-size: 1.6rem; line-height: 1.25; text-wrap: balance; }
.gk-head p { margin: 0; color: var(--muted); font-size: 1.05rem; }
.gk-free { padding-block: 3px; padding-inline: 14px; border-radius: 999px; font-size: .95rem; font-weight: 600; letter-spacing: .02em;
  color: var(--gk-free-ink); background: color-mix(in srgb, var(--olive) 30%, var(--card)); }
:root { --gk-free-ink: color-mix(in srgb, var(--olive) 28%, var(--ink)); }
:root[data-theme="dark"] { --gk-free-ink: color-mix(in srgb, var(--olive) 70%, #fff); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --gk-free-ink: color-mix(in srgb, var(--olive) 70%, #fff); } }

.gk-steps { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; counter-reset: gk; }
.gk-step { counter-increment: gk; position: relative; display: grid; grid-template-columns: 64px 1fr; align-items: center; gap: 12px 14px;
  padding: 14px 16px; border-radius: 18px; border: 1px solid var(--line); background: var(--card); }
.gk-step[aria-current="step"] { border: 2px solid var(--primary); padding: 13px 15px; background: color-mix(in srgb, var(--primary) 5%, var(--card));
  box-shadow: 0 10px 24px -18px color-mix(in srgb, var(--primary) 70%, #000); }
.gk-pic { position: relative; inline-size: 64px; block-size: 64px; border-radius: 50%; display: grid; place-items: center;
  background: color-mix(in srgb, var(--olive) 20%, var(--card)); color: var(--primary); }
.gk-pic::before { content: ""; inline-size: 42px; block-size: 42px; background: currentColor;
  -webkit-mask: var(--gk-pic) center / contain no-repeat; mask: var(--gk-pic) center / contain no-repeat; }
.gk-pic::after { content: counter(gk); position: absolute; inset-block-start: -4px; inset-inline-start: -4px; inline-size: 26px; block-size: 26px; border-radius: 50%;
  display: grid; place-items: center; font-size: .9rem; font-weight: 700; line-height: 1; color: var(--card); background: var(--primary); border: 2px solid var(--card); }
.gk-step[data-pic="signin"] { --gk-pic: url(/assets/ai-invite/signin.svg); }
.gk-step[data-pic="key"] { --gk-pic: url(/assets/ai-invite/key.svg); }
.gk-step[data-pic="paste"] { --gk-pic: url(/assets/ai-invite/paste.svg); }
.gk-txt { display: grid; gap: 2px; min-inline-size: 0; }
.gk-txt b { font-size: 1.18rem; font-weight: 600; line-height: 1.35; text-wrap: balance; }
.gk-txt small { font-size: 1rem; color: var(--muted); }
.gk-en { direction: ltr; unicode-bidi: isolate; display: inline-block; padding-inline: 6px; border-radius: 6px; font-weight: 600;
  background: color-mix(in srgb, var(--primary) 12%, transparent); }
.gk-go { grid-column: 1 / -1; display: flex; align-items: center; justify-content: center; gap: 8px; min-block-size: 56px; font-size: 1.15rem; font-weight: 600; }
.gk-steps:has([aria-current]) .gk-step:not([aria-current]) .gk-go { display: none; }
/* a finished step: its number becomes a check and the step quiets down */
.gk-step[data-done] { opacity: .72; }
.gk-step[data-done] .gk-pic::after { content: "✓"; background: var(--ok); }
.gk-err { margin: 0; padding: 12px 14px; border-radius: 14px; font-size: 1.05rem; font-weight: 500;
  color: var(--danger); background: color-mix(in srgb, var(--danger) 9%, var(--card)); border: 1px solid color-mix(in srgb, var(--danger) 35%, transparent); }
.gk-later { justify-self: center; min-block-size: 44px; font-size: 1rem; }

/* connected */
.gk-done { display: none; justify-items: center; text-align: center; gap: 12px; padding: 18px 16px; border-radius: 18px;
  background: color-mix(in srgb, var(--ok) 10%, var(--card)); border: 1px solid color-mix(in srgb, var(--ok) 40%, transparent); }
.gk-done::before { content: ""; inline-size: 84px; block-size: 84px; background: var(--ok);
  -webkit-mask: url(/assets/ai-invite/done.svg) center / contain no-repeat; mask: url(/assets/ai-invite/done.svg) center / contain no-repeat;
  animation: gk-ok .6s var(--ease-river, ease-out); }
.gk-done p { margin: 0; font-size: 1.08rem; max-inline-size: 30ch; }
.gk-done .gk-go { inline-size: 100%; }
.gk-ok { display: inline-flex; align-items: center; gap: 6px; font-size: 1.4rem; font-weight: 700; color: var(--ok); }
.gk-ok.small { font-size: .95rem; padding-block: 2px; padding-inline: 10px; border-radius: 999px; background: color-mix(in srgb, var(--ok) 14%, var(--card)); }
.gk[data-state="done"] :is(.gk-steps, .gk-err, .gk-later) { display: none; }
.gk[data-state="done"] .gk-done { display: grid; }
.gk[data-state="done"] .gk-head p { display: none; }
@keyframes gk-ok { from { opacity: 0; scale: .6; } 70% { scale: 1.06; } to { opacity: 1; scale: 1; } }
@media (prefers-reduced-motion: reduce) { .gk-done::before { animation: none; } }
:root[data-motion="reduce"] .gk-done::before { animation: none; }
@media (max-width: 379px) {
  .gk-step { grid-template-columns: 52px 1fr; gap: 10px 12px; padding: 12px 13px; }
  .gk-step[aria-current="step"] { padding: 11px 12px; }
  .gk-pic { inline-size: 52px; block-size: 52px; }
  .gk-pic::before { inline-size: 34px; block-size: 34px; }
  .gk-head h2 { font-size: 1.45rem; }
}

/* ---------- מצב רציניים (vision batch 11, the owner 2026-11-13): a plain, professional face over the same tokens ----------
   <html data-style="serious"> is set from the person's prefs (look.style = 'serious'; apply.js and common.js's early
   settings, like data-font); data-pillows="keep" is the second switch, which keeps the cushion icons on the serious home.
   What goes: anything a page marks .deco (drawings, illustrations, scenery), the companion figure, the illustrated faces.
   What stays: every tool and its data, the animations, the sounds and the haptics (the owner's choice).
   Shapes get tighter corners, a hairline instead of a soft shadow, and firmer headings.
   The serious home (index.html builds it from H.APPS in apps.js, in place of the tent and the campfire):
     <main class="sr-home">
       <header class="sr-head"><h1>שלום, נעמה</h1><p>כל הכלים במקום אחד</p></header>
       <label class="sr-search"><svg class="icon">(H.icon('lens'))</svg><input type="search" placeholder="חיפוש כלי" aria-label="חיפוש כלי"></label>
       <section class="sr-group"><h2>המקומות</h2>
         <ul class="sr-tools" data-view="grid">                  (data-view="list": one tool to a row, with its line under the name)
           <li><a class="sr-tool" href="/food/">
             <span class="sr-ic">(H.icon(ic)) or, with data-pillows="keep", <img src="/assets/pillows/p13.webp" alt=""></span>
             <span class="sr-txt"><b>אוכל</b><small>רשימת קניות, ספר מתכונים, דיאטה והמקרר</small></span></a></li>
         </ul></section>
       <p class="sr-none" hidden>לא נמצא כלי בשם הזה</p>
       <div class="sr-view" role="group" aria-label="תצוגה"><button aria-pressed="true" data-view="grid">רשת</button><button aria-pressed="false" data-view="list">רשימה</button></div>
     </main> */
:root[data-style="serious"] { --radius: 8px; --radius-sm: 6px; --radius-lg: 12px; --lift: 0 0 0 1px var(--line); }
:root[data-style="serious"] :is(.deco, .dm-stage) { display: none !important; }
:root[data-style="serious"] .ai-invite::before { display: none; }
:root[data-style="serious"] :is(h1, h2, h3) { font-weight: 600; letter-spacing: 0; }

.sr-home { display: grid; gap: 18px; max-inline-size: 980px; margin-inline: auto; padding-block: 20px 28px; padding-inline: 16px; }
.sr-head h1 { margin: 0; font-size: 1.7rem; line-height: 1.25; }
.sr-head p { margin: 2px 0 0; color: var(--muted); }
.sr-search { position: relative; display: flex; align-items: center; }
.sr-search .icon { position: absolute; inset-inline-start: 14px; inline-size: 20px; block-size: 20px; color: var(--muted); pointer-events: none; }
.sr-search input { inline-size: 100%; min-block-size: 50px; padding-block: 10px; padding-inline: 44px 14px; font: inherit; font-size: 1.05rem;
  color: var(--text); background: var(--card); border: 1px solid var(--line); border-radius: var(--radius); }
.sr-search input:focus-visible { outline: 2px solid var(--primary); outline-offset: 1px; border-color: transparent; }
.sr-group { display: grid; gap: 8px; }
.sr-group h2 { margin: 0; font-size: .95rem; color: var(--muted); letter-spacing: .02em; }
.sr-tools { list-style: none; margin: 0; padding: 0; display: grid; gap: 10px; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }
.sr-tool { display: grid; justify-items: start; align-content: start; gap: 10px; min-block-size: 108px; padding: 14px; border-radius: var(--radius);
  background: var(--card); border: 1px solid var(--line); color: var(--text); text-decoration: none;
  transition: border-color .15s, background-color .15s; }
.sr-tool:hover { border-color: color-mix(in srgb, var(--primary) 45%, var(--line)); background: color-mix(in srgb, var(--primary) 4%, var(--card)); }
.sr-tool:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
.sr-ic { display: grid; place-items: center; inline-size: 40px; block-size: 40px; border-radius: var(--radius-sm);
  color: var(--primary); background: color-mix(in srgb, var(--primary) 9%, var(--card)); }
.sr-ic .icon { inline-size: 22px; block-size: 22px; }
.sr-ic img { inline-size: 40px; block-size: 40px; object-fit: contain; }
:root[data-pillows="keep"] .sr-ic:has(img) { background: none; }
.sr-txt { display: grid; gap: 2px; min-inline-size: 0; }
.sr-txt b { font-weight: 600; font-size: 1.05rem; line-height: 1.3; }
.sr-txt small { display: none; color: var(--muted); font-size: .9rem; line-height: 1.4; }
/* the list: one tool to a row, its line under the name */
.sr-tools[data-view="list"] { grid-template-columns: 1fr; gap: 0; border: 1px solid var(--line); border-radius: var(--radius); background: var(--card); overflow: hidden; }
.sr-tools[data-view="list"] li + li { border-block-start: 1px solid var(--line); }
.sr-tools[data-view="list"] .sr-tool { grid-template-columns: 40px 1fr; align-items: center; justify-items: stretch; gap: 14px;
  min-block-size: 64px; padding-block: 10px; padding-inline: 14px; border: 0; border-radius: 0; }
.sr-tools[data-view="list"] .sr-tool:focus-visible { outline-offset: -2px; }
.sr-tools[data-view="list"] .sr-txt small { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sr-none { margin: 0; padding: 18px; text-align: center; color: var(--muted); border: 1px dashed var(--line); border-radius: var(--radius); }
.sr-view { justify-self: center; display: inline-flex; border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; background: var(--card); }
.sr-view button { min-block-size: 40px; padding-inline: 16px; font: inherit; font-size: .95rem; color: var(--muted); background: none; border: 0; cursor: pointer; }
.sr-view button + button { border-inline-start: 1px solid var(--line); }
.sr-view button[aria-pressed="true"] { color: var(--primary); font-weight: 600; background: color-mix(in srgb, var(--primary) 9%, var(--card)); }
@media (max-width: 599px) {
  .sr-tools:not([data-view="list"]) { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .sr-head h1 { font-size: 1.45rem; }
}

/* ---------- the fonts kept here (public/assets/fonts/, OFL, the licences beside them), so they need no outside site ----------
   Alef: a clear Hebrew sans, one more choice of font (<html data-font="alef">, like heebo / round / serif).
   Noto Sans Phoenician as 'Ohel Ivri': the ancient Hebrew script, the owner's own (vision batch 11). Only for those the owner
   granted it to; the server decides who gets the markup. The letters are Unicode's Phoenician block (U+10900–10915, in the
   order of the alef-bet: א → U+10900 … ת → U+10915; a final letter is its plain form; niqqud is dropped), and the Hebrew
   always stays beside them, for screen readers and for a tap:
     <span class="ivri" tabindex="0" role="button" aria-label="שלום"><span class="ivri-old" aria-hidden="true">𐤔𐤋𐤅𐤌</span><span class="ivri-he">שלום</span></span>
   A tap (or Enter) toggles .open on .ivri, which shows the Hebrew instead. The page JS writes the letters (a toIvri() is in
   docs/design/prototype/ivri.html). */
@font-face { font-family: 'Alef'; font-weight: 400; font-display: swap; src: url(/assets/fonts/alef-400-hebrew.woff2) format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F; }
@font-face { font-family: 'Alef'; font-weight: 400; font-display: swap; src: url(/assets/fonts/alef-400-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: 'Alef'; font-weight: 700; font-display: swap; src: url(/assets/fonts/alef-700-hebrew.woff2) format('woff2');
  unicode-range: U+0307-0308, U+0590-05FF, U+200C-2010, U+20AA, U+25CC, U+FB1D-FB4F; }
@font-face { font-family: 'Alef'; font-weight: 700; font-display: swap; src: url(/assets/fonts/alef-700-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: 'Ohel Ivri'; font-display: swap; src: url(/assets/fonts/phoenician.woff2) format('woff2'); unicode-range: U+10900-1091F; }
.ivri { display: inline-block; cursor: pointer; border-radius: 4px; -webkit-tap-highlight-color: transparent; }
.ivri-old { font-family: 'Ohel Ivri', 'Noto Sans Phoenician', sans-serif; letter-spacing: .06em; font-weight: 400; unicode-bidi: isolate; }
.ivri-he { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
.ivri.open .ivri-old { display: none; }
.ivri.open .ivri-he { position: static; inline-size: auto; block-size: auto; overflow: visible; clip-path: none; white-space: normal; }
.ivri:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }

/* "ניסיוני": a tool still on trial (H.APPS tag). A small amber pill with a flask; on a tile in the tools list, on a cushion
   on the ring and in the arrange tray it sits on the top corner (.app .tag-exp, .wheel-item .tag-exp, .arr-item .tag-exp). */
.tag-exp, .app-tag, .tag-soon { display: inline-flex; align-items: center; gap: 3px; padding: 1px 8px 1px 7px; border-radius: 999px; font-size: .72rem; font-weight: 600; line-height: 1.5;
  white-space: nowrap; color: var(--exp); background: color-mix(in srgb, var(--exp) 13%, var(--card)); border: 1px solid color-mix(in srgb, var(--exp) 45%, transparent); }
.tag-exp svg { inline-size: 12px; block-size: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
:is(.app, .wheel-item, .arr-item) > .tag-exp, .wheel-item .pillow > .tag-exp { position: absolute; inset-block-start: -6px; inset-inline-end: 0; z-index: 2;
  box-shadow: 0 2px 6px rgba(0, 0, 0, .12); pointer-events: none; }
.wheel-item .pillow > .tag-exp { inset-block-start: 2px; inset-inline-end: -4px; }
.wheel-item.back .tag-exp { opacity: 0; }

/* "חיפוש בגוגל": in place of a bare Google link in a card. A quiet outlined pill with a magnifier; it opens a new tab. */
.g-search { display: inline-flex; align-items: center; gap: 6px; min-block-size: 36px; padding: 5px 14px 5px 12px; border-radius: 999px; font-size: .9rem; font-weight: 500;
  line-height: 1.3; color: var(--text); background: var(--card); border: 1px solid var(--line-strong); text-decoration: none; white-space: nowrap; vertical-align: middle;
  transition: border-color var(--dur-quick) var(--ease-river), color var(--dur-quick) var(--ease-river); -webkit-tap-highlight-color: transparent; }
.g-search .icon { inline-size: 17px; block-size: 17px; stroke-width: 2; }
.g-search:hover { border-color: var(--primary); color: var(--primary); }
.g-search:focus-visible { outline: 3px solid var(--primary); outline-offset: 2px; }
.g-search:active { transform: translateY(1px); }
.g-search .g-q { max-inline-size: 18ch; overflow: hidden; text-overflow: ellipsis; color: var(--muted); font-weight: 400; }

/* The serious home: the tag right after the tool's name (index.html: .sr-txt b > span.app-tag). Same look as .tag-exp, no icon. */
.sr-txt b > :is(.app-tag, .tag-soon) { margin-inline-start: 6px; vertical-align: .1em; }

/* "בקרוב" / "בפיתוח": the one note for every big idea that waits (vision batch 15). The same pill as .tag-exp in a dusk blue;
   the word comes from H.SOON's `note`, the sprout says "growing", the same for either word. */
.tag-soon { color: var(--soon); background: color-mix(in srgb, var(--soon) 12%, var(--card)); border-color: color-mix(in srgb, var(--soon) 45%, transparent); }
.tag-soon svg { inline-size: 12px; block-size: 12px; flex: none; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

/* The home: a strip under the ring, "בקרוב ליד האוהל", one card to each idea in H.SOON. Dashed: drawn, not built yet. */
.soon-row { display: grid; gap: 8px; inline-size: min(100%, 520px); margin-block-start: 10px; }
.soon-row h2 { margin: 0; text-align: center; font-size: .9rem; font-weight: 500; color: var(--muted); letter-spacing: .02em; }
.soon-row ul { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 12px; }
.soon-card { position: relative; display: grid; justify-items: center; gap: 4px; inline-size: 100%; min-block-size: 44px; padding: 10px 10px 12px;
  font: inherit; color: var(--text); text-align: center; cursor: pointer; border-radius: var(--radius-lg);
  background: color-mix(in srgb, var(--soon) 4%, var(--card)); border: 1.5px dashed color-mix(in srgb, var(--soon) 40%, var(--line-strong));
  transition: border-color var(--dur-quick), background-color var(--dur-quick); }
.soon-card img { inline-size: min(100%, 150px); aspect-ratio: 4 / 3; block-size: auto; transition: transform var(--dur-draw) var(--ease-river); }
.soon-card b { font-weight: 600; font-size: 1rem; line-height: 1.3; }
.soon-card:hover { border-color: var(--soon); background: color-mix(in srgb, var(--soon) 8%, var(--card)); }
.soon-card:hover img { transform: translateY(-3px); }
.soon-card:focus-visible { outline: 2px solid var(--primary); outline-offset: 2px; }
/* the serious home: a last group "בקרוב", the same rows as the tools, dashed, with the picture for an icon */
button.sr-tool { inline-size: 100%; font: inherit; text-align: start; cursor: pointer; }
.sr-soon .sr-tool { border-style: dashed; }
.sr-soon .sr-ic { background: none; }
.sr-soon .sr-ic img { inline-size: 48px; block-size: 40px; object-fit: contain; }

/* The tap: H.modal(.soon-sheet) with the picture, the name, the note and the one sentence of `line`. Nothing else. */
.soon-sheet { display: grid; justify-items: center; gap: 8px; text-align: center; padding-block: 4px 2px; }
.soon-sheet img { inline-size: min(100%, 260px); aspect-ratio: 4 / 3; block-size: auto; }
.soon-sheet h2 { margin: 4px 0 0; font-size: 1.35rem; }
.soon-sheet p { margin: 0; max-inline-size: 32ch; color: var(--muted); font-size: 1.02rem; line-height: 1.55; }
@media (prefers-reduced-motion: reduce) { .soon-card img { transition: none; } }
:root[data-motion="reduce"] .soon-card img { transition: none; }

/* the polite page for a tool not open to you (gate.js, ai-features): a calm card in the middle, the name, why, and the way back.
   Mirrors the inline stopgap in gate.js, which ai-features drops (decisions.md). */
.gate-closed { display: grid; gap: 10px; justify-items: center; max-inline-size: 34rem; margin: 48px auto; padding: 32px 24px 26px;
  text-align: center; border-block-start: 3px solid color-mix(in srgb, var(--soon, var(--primary)) 55%, transparent); }
.gate-closed h1 { margin: 0; font-size: clamp(1.4rem, 1.2rem + 1vw, 1.8rem); }
.gate-closed p { margin: 0; max-inline-size: 36ch; line-height: 1.6; }
.gate-closed .lead { font-size: 1.08rem; color: var(--text); }
.gate-closed .muted { color: var(--muted); }
.gate-closed .btn { margin-block-start: 8px; min-block-size: 44px; }

/* ---------- The tent's moods (docs/design/switchboard.md), set from the back door's switchboard on <html>, on every page ----------
   data-mood="party": a warm gold accent, and on opening ai-features' .mood-fx confetti and balloons.
   data-mood="mourning": a faded, quiet palette; pictures desaturated; an optional candle note (.mood-note).
   data-kodesh: a calm Shabbat look, tokens only. The moods come last, so they win over the person's palette;
   mourning wins over kodesh (a look default only: what קודש means is the owner's decision). */
:root[data-mood="party"] { --olive: #e0a12a; --tint: #fbe9c2; }
:root[data-theme="dark"][data-mood="party"] { --olive: #f0c060; --tint: #2e2410; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"])[data-mood="party"] { --olive: #f0c060; --tint: #2e2410; } }

:root[data-kodesh] { --bg: #f4f1e8; --chalk: #f4f1e8; --card: #fbf9f3; --chalk-raised: #fbf9f3; --text: #22243a; --ink: #22243a; --muted: #55586c;
  --line: #dedbd0; --line-strong: #cbc7b8; --primary: #33437a; --vine: #33437a; --primary-ink: #fbf9f3; --olive: #c9a54a; --tint: #e6e8f3; }
:root[data-theme="dark"][data-kodesh] { --bg: #090c18; --card: #111628; --text: #e8e3d4; --muted: #b0b1c0; --line: #1b2136; --line-strong: #2a3150;
  --primary: #dcc27e; --ok: #dcc27e; --primary-ink: #090c18; --olive: #dcc27e; --tint: #161c34; --glass: rgba(17, 22, 40, .88); }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"])[data-kodesh] { --bg: #090c18; --card: #111628; --text: #e8e3d4; --muted: #b0b1c0;
  --line: #1b2136; --line-strong: #2a3150; --primary: #dcc27e; --ok: #dcc27e; --primary-ink: #090c18; --olive: #dcc27e; --tint: #161c34; --glass: rgba(17, 22, 40, .88); } }

:root[data-mood="mourning"] { --bg: #ebeae7; --chalk: #ebeae7; --card: #f5f4f2; --chalk-raised: #f5f4f2; --text: #26272b; --ink: #26272b; --muted: #595a60;
  --line: #d8d7d3; --line-strong: #c3c2bd; --primary: #4b505c; --vine: #4b505c; --primary-ink: #f5f4f2; --olive: #9b998f; --tint: #e3e3e5; --soil: #7d7a74; --bg-grad: none; }
:root[data-theme="dark"][data-mood="mourning"] { --bg: #0c0c0e; --card: #161619; --text: #dcdcdf; --muted: #a7a7ae; --line: #232327; --line-strong: #34343a;
  --primary: #b6b9c3; --ok: #b6b9c3; --primary-ink: #0c0c0e; --olive: #8d8b84; --tint: #1c1c21; --glass: rgba(22, 22, 25, .9); --bg-grad: none; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"])[data-mood="mourning"] { --bg: #0c0c0e; --card: #161619; --text: #dcdcdf; --muted: #a7a7ae;
  --line: #232327; --line-strong: #34343a; --primary: #b6b9c3; --ok: #b6b9c3; --primary-ink: #0c0c0e; --olive: #8d8b84; --tint: #1c1c21; --glass: rgba(22, 22, 25, .9); --bg-grad: none; } }
:root[data-mood="mourning"] :is(main img, main picture, main video, .deco) { filter: saturate(.35); }

/* the mourning note: a candle with a gently flickering flame */
.mood-note { display: flex; align-items: center; gap: 12px; margin: 0 0 16px; padding: 10px 16px; border-radius: 14px; border: 1px solid var(--line);
  background: var(--card); color: var(--text); font-size: .95rem; }
.mood-candle { position: relative; flex: none; inline-size: 18px; block-size: 34px; background: url(/assets/tree/candle.svg) bottom / 18px 27px no-repeat; }
.mood-candle::before { content: ""; position: absolute; inset-block-start: 0; inset-inline-start: 4px; inline-size: 10px; block-size: 14px;
  background: url(/assets/tree/flame.svg) center / contain no-repeat; transform-origin: 50% 100%; animation: mood-flicker 2.6s ease-in-out infinite; }
@keyframes mood-flicker { 0%, 100% { transform: scale(1) rotate(0); opacity: 1; } 30% { transform: scale(.94, 1.06) rotate(-3deg); opacity: .9; }
  60% { transform: scale(1.04, .95) rotate(2deg); opacity: 1; } }

/* the effects layer (ai-features' switches.js draws it and animates it with transform and opacity, nothing under reduced
   motion): <div class="mood-fx" aria-hidden="true">. The JS sets --x (and --c, --r) on each piece; the CSS gives the shapes. */
.mood-fx { position: fixed; inset: 0; z-index: 65; pointer-events: none; overflow: hidden; contain: strict; }
.mood-confetti { position: absolute; inset-block-start: 0; inset-inline-start: var(--x, 50%); inline-size: 8px; block-size: 12px; border-radius: 2px;
  background: var(--c, #e0a12a); rotate: var(--r, 0deg); will-change: transform, opacity; }
.mood-balloon { position: absolute; inset-block-start: 100%; inset-inline-start: var(--x, 50%); inline-size: 38px; block-size: 48px; border-radius: 50% 50% 48% 48%;
  background: radial-gradient(circle at 34% 30%, rgba(255, 255, 255, .55) 0 12%, transparent 13%), var(--c, #e86f5a); will-change: transform, opacity; }
.mood-balloon::before { content: ""; position: absolute; inset-block-start: calc(100% - 2px); inset-inline-start: calc(50% - 4px); inline-size: 8px; block-size: 6px;
  background: var(--c, #e86f5a); clip-path: polygon(50% 0, 100% 100%, 0 100%); }   /* the knot */
.mood-string { position: absolute; inset-block-start: calc(100% + 4px); inset-inline-start: calc(50% - .75px); inline-size: 1.5px; block-size: 44px;
  background: color-mix(in srgb, var(--c, #e86f5a) 55%, #555); }
/* mourning: two candles resting in the bottom inline-end corner for the visit, above the tab bar on a phone */
.mood-candles { position: absolute; inset-inline-end: 16px; inset-block-end: calc(var(--tabbar-h, 0px) + env(safe-area-inset-bottom) + 14px);
  display: flex; align-items: flex-end; gap: 8px; opacity: .92; }
.mood-candle { position: relative; inline-size: 18px; block-size: 34px; background: url(/assets/tree/candle.svg) bottom / 18px 27px no-repeat; }
.mood-candle + .mood-candle { block-size: 30px; background-size: 16px 23px; }
.mood-flame { position: absolute; inset-block-start: 0; inset-inline-start: 4px; inline-size: 10px; block-size: 14px;
  background: url(/assets/tree/flame.svg) center / contain no-repeat; transform-origin: 50% 100%; animation: mood-flicker 2.6s ease-in-out infinite; }
.mood-candle + .mood-candle .mood-flame { inset-inline-start: 3px; animation-duration: 3.1s; animation-delay: -1.2s; }
@media (min-width: 900px) { .mood-candles { inset-block-end: 18px; } }
@media (prefers-reduced-motion: reduce) { .mood-flame { animation: none; } }
@media (prefers-reduced-motion: reduce) { .mood-candle::before { animation: none; } }
}

/* ---------- The sky: one global layer behind every scene (docs/design/sky.md) ----------
   Full-bleed: fixed over the whole window at any width and height, so it never ends in a box. A scene (the tent now; the
   garage and the hill later) turns it on with .sky inside it or data-scene on <html>, and only places its own picture on it.
   By day a soft blue at the top; at night a deep navy with stars that twinkle by opacity only. A season or a mood changes
   only the tokens (--sky-top, --sky-mid, --sky-stars). */
:root { --sky-top: rgba(130, 178, 222, .16); --sky-mid: rgba(130, 178, 222, 0); --sky-stars: 0; }
:root[data-theme="dark"] { --sky-top: rgba(4, 8, 22, .55); --sky-mid: rgba(20, 30, 70, .12); --sky-stars: 1; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) { --sky-top: rgba(4, 8, 22, .55); --sky-mid: rgba(20, 30, 70, .12); --sky-stars: 1; } }
:root:is(:has(.sky), [data-scene]) body { background: transparent; }   /* (html keeps --bg; the layer sits between them) */
:root:is(:has(.sky), [data-scene]) body::before,
:root:is(:has(.sky), [data-scene]) body::after { content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none; }
:root:is(:has(.sky), [data-scene]) body::before {
  background: linear-gradient(to bottom, var(--sky-top), var(--sky-mid) 55%, transparent 85%); }
/* the stars: two tiled fields of small dots at sizes that do not repeat together, so no pattern shows at any width;
   the second field breathes (opacity) so the sky twinkles. Fewer, fainter towards the bottom. */
:root:is(:has(.sky), [data-scene]) body::after {
  --st: #f3f0e4;
  background:
    radial-gradient(1.4px 1.4px at 12% 18%, var(--st), transparent), radial-gradient(1px 1px at 47% 9%, var(--st), transparent),
    radial-gradient(1.6px 1.6px at 78% 31%, #dce8ff, transparent), radial-gradient(1px 1px at 29% 57%, var(--st), transparent),
    radial-gradient(1.2px 1.2px at 63% 74%, var(--st), transparent), radial-gradient(1px 1px at 91% 83%, var(--st), transparent);
  background-size: 331px 263px;
  opacity: calc(var(--sky-stars) * .85); transition: opacity 1.6s;
  -webkit-mask-image: linear-gradient(to bottom, #000 30%, rgba(0, 0, 0, .25) 80%, transparent); mask-image: linear-gradient(to bottom, #000 30%, rgba(0, 0, 0, .25) 80%, transparent); }
:root:is(:has(.sky), [data-scene]) main::before { content: ""; position: fixed; inset: 0; z-index: -1; pointer-events: none;
  background:
    radial-gradient(1.8px 1.8px at 22% 26%, #dce8ff, transparent), radial-gradient(1.2px 1.2px at 71% 12%, #f3f0e4, transparent),
    radial-gradient(1px 1px at 54% 48%, #f3f0e4, transparent), radial-gradient(1.4px 1.4px at 8% 66%, #f3f0e4, transparent);
  background-size: 457px 389px; opacity: 0; transition: opacity 1.6s;
  -webkit-mask-image: linear-gradient(to bottom, #000 30%, rgba(0, 0, 0, .2) 75%, transparent); mask-image: linear-gradient(to bottom, #000 30%, rgba(0, 0, 0, .2) 75%, transparent); }
:root[data-theme="dark"]:is(:has(.sky), [data-scene]) main::before { animation: sky-twinkle 6s ease-in-out infinite; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]):is(:has(.sky), [data-scene]) main::before { animation: sky-twinkle 6s ease-in-out infinite; } }
@keyframes sky-twinkle { 0%, 100% { opacity: .25; } 50% { opacity: .9; } }

/* the tent's own sky box (index.html) keeps only the sun, the moon and their glow: its tint and its stars are the global
   layer's now, and on a wide window its sides and its low hills fade out, so no edge or strip shows */
:root .sky { background: radial-gradient(60% 55% at var(--sun-x, 50%) var(--sun-y, 100%), var(--sky-glow, transparent), transparent 70%); }
:root .sky .stars { display: none; }
@media (min-width: 700px) {
  :root .sky { background: radial-gradient(560px 360px at var(--sun-x, 50%) var(--sun-y, 100%), var(--sky-glow, transparent), transparent 70%);
    -webkit-mask-image: linear-gradient(to bottom, #000 calc(100% - 3px), transparent), linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
    -webkit-mask-composite: source-in; mask-image: linear-gradient(to bottom, #000 calc(100% - 3px), transparent), linear-gradient(to right, transparent, #000 14%, #000 86%, transparent);
    mask-composite: intersect; }
}
@media (prefers-reduced-motion: reduce) { :root:is(:has(.sky), [data-scene]) main::before { animation: none !important; opacity: calc(var(--sky-stars) * .6); } }

/* ---------- Who sees it: the four-level privacy picker (docs/design/privacy-picker.md) ----------
   Every published item (a story, a picture, a memory, a recipe…) carries one of four levels, set by data-level:
   all (כולם) · friends (חברים ומשפחה) · family (רק משפחה) · me (רק אני). Each level has its own colour (--lv) and icon.
   Three forms: the full picker (fieldset of radios), a compact chip that opens it, and a small tag for lists. */
[data-level="all"]     { --lv: #3d7ea6; --lv-ic: url(/assets/priv-icons/all.svg); }
[data-level="friends"] { --lv: #c0577d; --lv-ic: url(/assets/priv-icons/friends.svg); }
[data-level="family"]  { --lv: var(--primary); --lv-ic: url(/assets/priv-icons/family.svg); }
[data-level="me"]      { --lv: #5f636c; --lv-ic: url(/assets/priv-icons/me.svg); }
:root[data-theme="dark"] [data-level="all"] { --lv: #7db4d6; }
:root[data-theme="dark"] [data-level="friends"] { --lv: #e595b3; }
:root[data-theme="dark"] [data-level="me"] { --lv: #a9aeb8; }
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) [data-level="all"] { --lv: #7db4d6; }
  :root:not([data-theme="light"]) [data-level="friends"] { --lv: #e595b3; }
  :root:not([data-theme="light"]) [data-level="me"] { --lv: #a9aeb8; }
}
.priv-ic { flex: none; display: inline-block; inline-size: 22px; block-size: 22px; background: var(--lv, currentColor);
  -webkit-mask: var(--lv-ic) center / contain no-repeat; mask: var(--lv-ic) center / contain no-repeat; }

/* the full picker: 2×2 on a phone, four across from 640 px; the chosen one gets its level's border and tint */
.priv-pick { margin: 0; padding: 0; border: 0; min-inline-size: 0; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.priv-pick > legend { grid-column: 1 / -1; padding: 0; margin-block-end: 6px; font-weight: 600; font-size: .95rem; }
.priv-opt { position: relative; display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 2px 8px; align-items: center; min-block-size: 64px;
  padding: 10px 12px; border: 1.5px solid var(--line); border-radius: 14px; background: var(--card); cursor: pointer;
  transition: transform var(--dur-press, .12s) var(--ease-river, ease), opacity var(--dur-quick, .2s); }
.priv-opt:active { transform: scale(.98); }
.priv-opt > input { position: absolute; opacity: 0; inline-size: 1px; block-size: 1px; pointer-events: none; }
.priv-opt > .priv-ic { grid-row: 1 / span 2; }
.priv-opt > b { font-weight: 600; font-size: .98rem; line-height: 1.25; }
.priv-opt > small { grid-column: 2; color: var(--muted); font-size: .8rem; line-height: 1.3; }
.priv-opt:has(input:checked) { border-color: var(--lv); background: color-mix(in srgb, var(--lv) 11%, var(--card)); }
.priv-opt:has(input:checked) > b { color: color-mix(in srgb, var(--lv) 70%, var(--text)); }
.priv-opt:has(input:checked)::after { content: ""; position: absolute; inset-block-start: 8px; inset-inline-end: 8px; inline-size: 16px; block-size: 16px;
  background: var(--lv); -webkit-mask: url(/assets/bd-icons/check.svg) center / contain no-repeat; mask: url(/assets/bd-icons/check.svg) center / contain no-repeat; }
.priv-opt:has(input:focus-visible) { outline: 3px solid color-mix(in srgb, var(--lv) 45%, transparent); outline-offset: 2px; }
.priv-opt:has(input:disabled) { opacity: .5; cursor: not-allowed; }
.priv-opt:has(input:disabled):active { transform: none; }
.priv-pick > .priv-note { grid-column: 1 / -1; margin: 2px 0 0; color: var(--muted); font-size: .82rem; }
@media (min-width: 640px) {
  .priv-pick { grid-template-columns: repeat(4, minmax(0, 1fr)); }
  .priv-opt { grid-template-columns: minmax(0, 1fr); justify-items: start; align-content: start; min-block-size: 96px; }
  .priv-opt > .priv-ic { grid-row: auto; margin-block-end: 4px; }
  .priv-opt > small { grid-column: 1; }
}

/* the compact chip by a publish button: shows the current level, opens the picker (H.modal or a popover) */
.priv-chip { display: inline-flex; align-items: center; gap: 6px; min-block-size: 44px; padding: 0 14px 0 12px; border-radius: 999px;
  border: 1.5px solid color-mix(in srgb, var(--lv, var(--line-strong)) 55%, var(--line)); background: color-mix(in srgb, var(--lv, var(--muted)) 8%, var(--card));
  color: var(--text); font: inherit; font-size: .9rem; font-weight: 500; cursor: pointer;
  transition: transform var(--dur-press, .12s) var(--ease-river, ease); }
.priv-chip:active { transform: scale(.97); }
.priv-chip > .priv-ic { inline-size: 18px; block-size: 18px; }
.priv-chip::after { content: ""; inline-size: 7px; block-size: 7px; margin-inline-start: 2px; border-block-end: 1.8px solid currentColor;
  border-inline-start: 1.8px solid currentColor; transform: translateY(-2px) rotate(45deg); opacity: .6; }   /* a down chevron (RTL) */
.priv-chip:focus-visible { outline: 3px solid color-mix(in srgb, var(--lv, var(--primary)) 45%, transparent); outline-offset: 2px; }

/* the small tag in lists and on cards: icon + short name; .priv-tag.bare is the icon alone (with aria-label / title) */
.priv-tag { display: inline-flex; align-items: center; gap: 4px; padding: 2px 8px 2px 6px; border-radius: 999px; vertical-align: middle;
  background: color-mix(in srgb, var(--lv, var(--muted)) 12%, transparent); color: color-mix(in srgb, var(--lv, var(--muted)) 75%, var(--text));
  font-size: .76rem; font-weight: 500; line-height: 1.5; white-space: nowrap; }
.priv-tag > .priv-ic { inline-size: 14px; block-size: 14px; }
.priv-tag.bare { padding: 3px; }

/* ---------- Motion: the "Telegram test" across the whole tent (vision batch 30, docs/design/motion.md) ----------
   Instant feedback, nothing jumps, nothing spins for a fast answer. Only transform and opacity move. The JS of the
   gestures (swipe, long-press, the sheet's drag, hold-to-speed) sets the variables; the CSS gives the look and the settle. */
:root {
  --ease-spring: linear(0, .009, .035 2.1%, .141 4.4%, .723 12.9%, .938 16.7%, 1.017 19.4%, 1.067, 1.099 24.3%, 1.108 26%, 1.103, 1.085 30.5%,
    1.024 37.5%, 1.003 41.4%, .992 45.5%, .996 55.4%, 1.001 66%, 1);   /* a soft spring: a sheet or a row that settles */
  --dur-settle: 340ms;   /* the spring does most of its way in the first ~200 ms; the rest is the settle */
}
/* instant: no 300 ms double-tap wait on anything pressable, and no grey flash */
:where(a, button, [role="button"], [role="tab"], [role="switch"], [role="radio"], summary, label, .chip, .btn) { touch-action: manipulation; }
/* smooth scrolling for jumps inside a page; panes that scroll keep the page still behind them */
@media (prefers-reduced-motion: no-preference) { html { scroll-behavior: smooth; } }
:where(.dm-msgs, .gl-ask-log, .dm-grp-pick, .dm-pick, #modalBody) { overscroll-behavior: contain; }
/* no spinner for a fast answer: the spinner waits 400 ms in silence, then fades in */
.spinner { animation: spin .8s linear infinite, wait-show var(--dur-quick) ease 400ms both; }
.loading > :not(.spinner) { animation: wait-show var(--dur-quick) ease 400ms both; }
@keyframes wait-show { from { opacity: 0; } }

/* the shape of what is coming: skeleton lines and blocks with a slow sheen (transform) */
.skel { position: relative; overflow: hidden; border-radius: 10px; background: color-mix(in srgb, var(--text) 7%, transparent); color: transparent; user-select: none; }
.skel::after { content: ""; position: absolute; inset: 0; transform: translateX(100%);
  background: linear-gradient(90deg, transparent, color-mix(in srgb, var(--card) 55%, transparent), transparent); animation: skel-sheen 1.4s ease-in-out infinite; }
.skel.line { block-size: .9em; margin-block: .35em; inline-size: var(--w, 100%); }
.skel.round { border-radius: 50%; }
@keyframes skel-sheen { to { transform: translateX(-100%); } }
@media (prefers-reduced-motion: reduce) { .skel::after { animation: none; opacity: 0; } }

/* anything that arrives: a list, new content after a fetch. --i on each item staggers it (cap it at ~8 in the JS) */
.arrive > * { animation: arrive var(--dur-draw) var(--ease-river) both; animation-delay: calc(min(var(--i, 0), 8) * 28ms); }
.swap-in { animation: fade var(--dur-quick) ease both; }

/* pressable cards and rows: a small give under the finger */
:where(a.card, button.card, .tap, .dm-row, .fr-card, .gl-goal, .result) { transition: transform var(--dur-press) var(--ease-river); }
:where(a.card, button.card, .tap, .dm-row, .result):active { transform: scale(.985); }

/* swipe a row: to reply (a message) or to act (a list row). The JS sets --dx in px while dragging and adds .dragging;
   on release it removes .dragging (the row springs back or away) and fires the action past the threshold. */
.swipe { position: relative; overflow: hidden; touch-action: pan-y; }
.swipe-body { position: relative; z-index: 1; transform: translateX(var(--dx, 0px)); transition: transform var(--dur-settle) var(--ease-spring); background: inherit; }
.swipe.dragging .swipe-body { transition: none; }
.swipe-acts { position: absolute; inset: 0; display: flex; align-items: stretch; justify-content: flex-end; }
.swipe-acts > button { min-inline-size: 76px; border: 0; font: inherit; font-size: .84rem; font-weight: 600; color: var(--act-ink, var(--primary-ink)); background: var(--act, var(--primary));
  display: grid; place-items: center; gap: 2px; cursor: pointer; }
.swipe-acts > button.danger { --act: color-mix(in srgb, var(--danger) 78%, #000); --act-ink: #fff; }
/* swipe to reply: the reply arrow grows in as the drag nears the threshold (--p: 0–1) */
.swipe-reply { position: absolute; inset-block: 0; inset-inline-start: 8px; margin-block: auto; inline-size: 32px; block-size: 32px; border-radius: 50%;
  background: color-mix(in srgb, var(--text) 10%, var(--card)); opacity: var(--p, 0); transform: scale(calc(.5 + var(--p, 0) * .5)); }
.swipe-reply::before { content: ""; position: absolute; inset: 9px; border-block-start: 2px solid var(--text); border-inline-start: 2px solid var(--text);
  transform: rotate(-45deg); border-start-start-radius: 2px; }
.swipe.armed .swipe-reply { background: var(--primary); }
.swipe.armed .swipe-reply::before { border-color: var(--primary-ink); }

/* long-press: the pressed thing lifts, the page dims, the menu grows from the finger (--ox/--oy set by the JS) */
.lp-lift { position: relative; z-index: calc(var(--z-sheet, 80) + 1); transform: scale(1.03); transition: transform var(--dur-quick) var(--ease-spring); }
.lp-dim { position: fixed; inset: 0; z-index: var(--z-sheet, 80); background: rgba(10, 12, 20, .32); animation: fade var(--dur-quick) ease both; }
.lp-menu { position: fixed; z-index: calc(var(--z-sheet, 80) + 2); min-inline-size: 200px; max-inline-size: min(280px, calc(100vw - 32px)); padding: 6px;
  border-radius: 16px; background: var(--card); border: 1px solid var(--line); box-shadow: var(--lift); transform-origin: var(--ox, 50%) var(--oy, 0%);
  animation: lp-in var(--dur-quick) var(--ease-spring) both; display: grid; }
.lp-menu > button { display: flex; align-items: center; gap: 12px; min-block-size: 44px; padding: 0 12px; border: 0; border-radius: 10px; background: none;
  color: var(--text); font: inherit; text-align: start; cursor: pointer; }
.lp-menu > button:hover, .lp-menu > button:focus-visible { background: color-mix(in srgb, var(--text) 6%, transparent); outline: none; }
.lp-menu > button.danger { color: var(--danger); }
.lp-menu > hr { margin: 4px 8px; border: 0; border-block-start: 1px solid var(--line); }
@keyframes lp-in { from { opacity: 0; transform: scale(.86); } }

/* the phone's sheet (.modal on ≤520 px) follows the finger down and closes past a third: the JS sets --drag (px) and .dragging */
.sheet-grip { display: none; }
@media (max-width: 520px) {
  .sheet-grip { display: block; position: absolute; inset-block-start: 0; inset-inline: 0; block-size: 22px; z-index: 2; touch-action: none; cursor: grab; }
  .sheet-grip::before { content: ""; position: absolute; inset-block-start: 8px; inset-inline-start: calc(50% - 18px); inline-size: 36px; block-size: 4px; border-radius: 4px;
    background: var(--line-strong); }
  .modal-glass { animation: sheet-up var(--dur-settle) var(--ease-spring) both; transform: translateY(var(--drag, 0px)); transition: transform var(--dur-settle) var(--ease-spring); }
  .modal.dragging .modal-glass { transition: none; }
  .modal.dragging .modal-backdrop { opacity: calc(1 - var(--drag-p, 0)); }
  @keyframes sheet-up { from { transform: translateY(100%); } }
}

/* every video: hold to speed up, slide to go faster. The JS sets the rate and the label; the pill shows while held */
.vid-speed { position: absolute; inset-block-start: 12px; inset-inline-start: 50%; translate: -50% 0; z-index: 2; pointer-events: none;
  display: inline-flex; align-items: center; gap: 6px; padding: 5px 12px; border-radius: 999px; background: rgba(10, 12, 20, .62); color: #fff;
  font-size: .86rem; font-weight: 600; font-variant-numeric: tabular-nums; opacity: 0; transform: translateY(-6px);
  transition: opacity var(--dur-quick) ease, transform var(--dur-quick) var(--ease-river); }
.vid-speed::before { content: "»"; font-size: 1.1em; }
.vid-speed.on { opacity: 1; transform: none; }
:root[dir="rtl"] .vid-speed { translate: 50% 0; }

@media (prefers-reduced-motion: reduce) {
  .arrive > *, .lp-menu, .lp-dim { animation: none; }
  .swipe-body, .lp-lift, .modal-glass { transition: none; }
  .lp-lift { transform: none; }
}

/* ---------- "רמת הניג'וס": the notification level of a tool or an item (vision batch 31, docs/design/nag-level.md) ----------
   Four levels: off, quiet (only in the daily summary), normal, nag (repeats until handled). [data-nag] sets the colour and the bell. */
[data-nag="off"]    { --nv: var(--muted); --nv-ic: url(/assets/nag-icons/off.svg); }
[data-nag="quiet"]  { --nv: color-mix(in srgb, var(--olive) 55%, var(--text)); --nv-ic: url(/assets/nag-icons/quiet.svg); }
[data-nag="normal"] { --nv: var(--primary); --nv-ic: url(/assets/nag-icons/normal.svg); }
[data-nag="nag"]    { --nv: #b5542a; --nv-ic: url(/assets/nag-icons/nag.svg); }
:root[data-theme="dark"] [data-nag="nag"] { --nv: #e98a5c; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) [data-nag="nag"] { --nv: #e98a5c; } }
.nag-ic { display: inline-block; flex: none; inline-size: 20px; block-size: 20px; background: var(--nv, currentColor);
  -webkit-mask: var(--nv-ic, url(/assets/nag-icons/normal.svg)) center / contain no-repeat; mask: var(--nv-ic, url(/assets/nag-icons/normal.svg)) center / contain no-repeat; }

/* the picker: four segments in one row (fieldset > legend + label.nag-opt[data-nag] > input[type=radio] + .nag-ic + span) */
.nag { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 3px; margin: 0; padding: 3px; border: 1px solid var(--line); border-radius: 14px;
  background: color-mix(in srgb, var(--text) 4%, var(--card)); min-inline-size: 0; }
.nag > legend { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); }
.nag-opt { position: relative; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; min-block-size: 50px; padding: 4px 2px;
  border-radius: 11px; cursor: pointer; font-size: .8rem; color: var(--muted); text-align: center; }
.nag-opt > input { position: absolute; opacity: 0; inset: 0; margin: 0; cursor: pointer; }
.nag-opt > .nag-ic { inline-size: 18px; block-size: 18px; background: currentColor; }
.nag-opt:hover { color: var(--text); }
.nag-opt:has(input:checked) { background: var(--card); color: var(--nv); font-weight: 600; box-shadow: 0 1px 3px rgba(20, 18, 12, .14), inset 0 0 0 1.5px color-mix(in srgb, var(--nv) 55%, transparent); }
.nag-opt:has(input:focus-visible) { outline: 2px solid var(--primary); outline-offset: 1px; }
.nag-opt:has(input:disabled) { cursor: not-allowed; opacity: .6; }
.nag-opt:active { transform: scale(.96); }
.nag-opt { transition: background-color var(--dur-quick) ease, color var(--dur-quick) ease, transform var(--dur-press) var(--ease-river); }
.nag-note { margin: 6px 0 0; font-size: .8rem; color: var(--muted); }   /* one line on the chosen level: "רק בסיכום היומי" */

/* the bell in a tool's head: shows the tool's level, opens the picker (in H.modal or a .lp-menu).
   .own: this tool or item differs from the general setting, a small dot says so */
.nag-bell { position: relative; display: inline-grid; place-items: center; inline-size: 44px; block-size: 44px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--card); color: var(--nv, var(--text)); cursor: pointer; transition: transform var(--dur-press) var(--ease-river); }
.nag-bell > .nag-ic { background: currentColor; }
.nag-bell:active { transform: scale(.94); }
.nag-bell.own::after { content: ""; position: absolute; inset-block-start: 6px; inset-inline-end: 6px; inline-size: 9px; block-size: 9px; border-radius: 50%;
  background: var(--nv, var(--primary)); box-shadow: 0 0 0 2px var(--card); }
/* an item that differs from its tool (one goal on "נודניק"): a small tag beside its name */
.nag-mark { display: inline-flex; align-items: center; gap: 4px; padding: 1px 8px 1px 6px; border-radius: 999px; vertical-align: middle; white-space: nowrap;
  font-size: .74rem; font-weight: 500; color: var(--nv); background: color-mix(in srgb, var(--nv) 12%, transparent); }
.nag-mark > .nag-ic { inline-size: 14px; block-size: 14px; background: currentColor; }
/* in the picker of an item: "כמו הממשק (רגיל)" to go back to the tool's level */
.nag-inherit { display: flex; align-items: center; gap: 8px; min-block-size: 44px; margin-block-start: 6px; font-size: .86rem; color: var(--muted); cursor: pointer; }
.nag-inherit input { inline-size: 20px; block-size: 20px; accent-color: var(--primary); }

/* ---------- Telegram-smooth, part 2 (the owner's priority, docs/decisions.md 2026-11-14; spec in docs/design/motion.md "Smooth: the patterns") ----------
   Sheets rise 240 ms and leave 170 ms; menus grow from their trigger; the active tab's pebble slides to the next page's tab; every
   tappable thing gives under the finger. Only transform and opacity. */
:root { --ease-sheet: cubic-bezier(.2, .9, .25, 1); --dur-sheet-in: 240ms; --dur-sheet-out: 170ms; }
html { -webkit-tap-highlight-color: transparent; }

/* sheets and windows: in, and out (the JS adds .closing for 170 ms before it hides; see the patch in the notes) */
@keyframes pop-in { from { opacity: 0; transform: scale(.96); } }
@keyframes pop-out { to { opacity: 0; transform: scale(.97); } }
@keyframes fade-out { to { opacity: 0; } }
.modal-glass { animation: pop-in var(--dur-quick) var(--ease-sheet) both; transform-origin: 50% 60%; }
.modal-backdrop { animation: fade var(--dur-quick) ease both; }
.modal.closing { pointer-events: none; }
.modal.closing .modal-glass { animation: pop-out var(--dur-sheet-out) var(--ease-leave) both; }
.modal.closing .modal-backdrop { animation: fade-out var(--dur-sheet-out) ease both; }
.modal.grow .modal-glass { animation: none; }
@media (max-width: 520px) {
  .modal-glass { animation: sheet-up var(--dur-sheet-in) var(--ease-sheet) both; transform-origin: 50% 100%; }   /* the drag's spring-back (transition on transform, --dur-settle / --ease-spring) stays as batch 30 set it */
  .modal.closing .modal-glass { animation: sheet-down var(--dur-sheet-out) var(--ease-leave) both; }
  @keyframes sheet-down { to { transform: translateY(100%); } }
}
@media (prefers-reduced-motion: reduce) { .modal.closing .modal-glass { animation: none; opacity: 0; } }

/* menus and popovers grow from their trigger: the JS sets --ox / --oy (the trigger's centre in the menu's own box); .closing leaves in 120 ms */
@keyframes menu-in { from { opacity: 0; transform: scale(.96); } }
@keyframes menu-out { to { opacity: 0; transform: scale(.96); } }
.navmenu, .lp-menu, .tr-menu { transform-origin: var(--ox, 50%) var(--oy, 0%); }
.navmenu { animation: menu-in var(--dur-quick) var(--ease-sheet) both; }
.navmenu.closing, .lp-menu.closing, .tr-menu.closing { animation: menu-out 120ms var(--ease-leave) both; pointer-events: none; }

/* the tab bar's pebble slides from the old page's tab to the new one's (a view transition of its own, so it travels while the page turns) */
@media (max-width: 899px) {
  .tabbar > a[aria-current="page"]::before, .tabbar > .tab-pick[aria-current="page"]::before { view-transition-name: tab-pebble; }
}
::view-transition-group(tab-pebble) { animation-duration: 280ms; animation-timing-function: var(--ease-river); }
@supports (view-transition-name: x) { .tabbar > :is(a, .tab-pick)[aria-current="page"]::before { animation: none; } }

/* press feedback on what had none: chips, tabs, the window's close, menu rows, bar links (a short give, 120 ms, on transform) */
:where(.tabs button, .modal-close, .topnav a, .nav-menu, .lp-menu > button, .tr-menu button):not(:disabled) { transition: transform var(--dur-press) var(--ease-river); }   /* (.chip and .navmenu a carry transform in their own transition) */
:where(.chip, .tabs button, .modal-close, .navmenu a, .topnav a, .nav-menu, .lp-menu > button, .tr-menu button):not(:disabled):active { transform: scale(.96); }

/* the pillows: each picture keeps its own shape before it loads (so nothing jumps, and the audit sees a size) */
img[src$="/pillows/p01.webp"] { aspect-ratio: 270 / 250; }
img[src$="/pillows/p02.webp"] { aspect-ratio: 351 / 250; }
img[src$="/pillows/p03.webp"] { aspect-ratio: 331 / 250; }
img[src$="/pillows/p04.webp"] { aspect-ratio: 420 / 247; }
img[src$="/pillows/p05.webp"] { aspect-ratio: 303 / 250; }
img[src$="/pillows/p06.webp"] { aspect-ratio: 349 / 250; }
img[src$="/pillows/p07.webp"] { aspect-ratio: 340 / 250; }
img[src$="/pillows/p08.webp"] { aspect-ratio: 420 / 216; }
img[src$="/pillows/p09.webp"] { aspect-ratio: 304 / 250; }
img[src$="/pillows/p10.webp"] { aspect-ratio: 331 / 250; }
img[src$="/pillows/p11.webp"] { aspect-ratio: 357 / 250; }
img[src$="/pillows/p12.webp"] { aspect-ratio: 380 / 250; }
img[src$="/pillows/p13.webp"] { aspect-ratio: 348 / 250; }
img[src$="/pillows/p14.webp"] { aspect-ratio: 348 / 250; }
img[src$="/pillows/p15.webp"] { aspect-ratio: 420 / 190; }
img[src$="/pillows/p16.webp"] { aspect-ratio: 270 / 250; }

/* ---------- silhouettes for a person who has not signed in yet (the owner, 2026-11-14) ----------
   <span class="sil" data-sil="m|f|x" aria-hidden="true"></span> inside a round frame (.fv-pic, .mc-avatar, .fs-face, and the tree's faces):
   the shape (assets/sil-m.svg, sil-f.svg, sil-x.svg) is a mask, so it takes the frame's own colour and is right in light and dark.
   The same files also work as a plain <img src="/assets/sil-x.svg"> (a warm brown). Initials stay for someone who has them to show. */
.sil { display: block; inline-size: 100%; block-size: 100%; background-color: currentColor; opacity: .72;
  -webkit-mask: url(/assets/sil-x.svg) center bottom / 86% no-repeat; mask: url(/assets/sil-x.svg) center bottom / 86% no-repeat; }
.sil[data-sil="m"] { -webkit-mask-image: url(/assets/sil-m.svg); mask-image: url(/assets/sil-m.svg); }
.sil[data-sil="f"] { -webkit-mask-image: url(/assets/sil-f.svg); mask-image: url(/assets/sil-f.svg); }
:is(.fv-pic, .mc-avatar, .fs-face, .tr-face) > .sil { align-self: end; }
