/* Daili — daili.app
 *
 * Three conventions run through this file, all load-bearing:
 *
 * 1. LOGICAL PROPERTIES, not physical ones. margin-inline-start, not
 *    margin-left. That is what lets the Arabic build mirror itself from a
 *    single stylesheet instead of a generated second copy that drifts.
 *    Transforms have no logical form, so their direction lives in the
 *    --rot-* custom properties below and is flipped in one place.
 *    The redesign mock is written with physical right:/left:; everything
 *    lifted from it is converted on the way in.
 *
 * 2. EVERY COLOUR IS A TOKEN. Nothing below :root hard-codes a colour, which
 *    is what makes the dark-mode block near the end ~20 lines instead of a
 *    second stylesheet.
 *
 * 3. THE FONTS ARE OURS. Both families are served from /assets/fonts/, never
 *    from Google. See the block immediately below.
 */

/* ---------- brand fonts ----------------------------------------------------
 * Sofia Sans Condensed (display) and Figtree (text): the same two faces the
 * app and the web app use. The woff2 subsets are copied verbatim out of the
 * @fontsource packages (figtree 5.3.0, sofia-sans-condensed 5.3.0) into
 * static/assets/fonts/; static/assets/fonts/LICENSE.txt carries both SIL OFL
 * texts. Self-hosted rather than linked from Google Fonts so that the CSP can
 * stay `font-src 'self'` and no reader's browser is made to announce itself to
 * a third party in order to read this page — the same reason this site has no
 * analytics and no cookie banner.
 *
 * Every face keeps the unicode-range of its subset, copied verbatim from the
 * package's own CSS, so a Russian page fetches the Cyrillic cut of the display
 * face and nothing else. Neither family has Arabic, Thai, Devanagari or CJK
 * glyphs, so /ar/, /th/, /hi/, /ja/, /ko/ and the two Chinese builds match no
 * range, download no font at all, and fall through to the system stack at the
 * end of --display / --sans. That is intended: a system font in those scripts
 * beats a Latin display face that cannot render them.
 * ------------------------------------------------------------------------- */

/* Figtree — body text */
@font-face{font-family:Figtree;font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/figtree-latin-400-normal.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:Figtree;font-style:normal;font-weight:400;font-display:swap;src:url(/assets/fonts/figtree-latin-ext-400-normal.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:Figtree;font-style:normal;font-weight:500;font-display:swap;src:url(/assets/fonts/figtree-latin-500-normal.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:Figtree;font-style:normal;font-weight:600;font-display:swap;src:url(/assets/fonts/figtree-latin-600-normal.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:Figtree;font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/figtree-latin-700-normal.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:Figtree;font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/figtree-latin-ext-700-normal.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}

/* Sofia Sans Condensed — headlines, the wordmark, the language codes.
   500/600 are never asked for; 700 and 800 are the only weights the design
   uses, in four scripts (Latin runs the whole site, Cyrillic is /ru/, Greek is
   here because the family ships it and a stray ° or Ω in any locale would
   otherwise fall out of the face mid-word). */
@font-face{font-family:"Sofia Sans Condensed";font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/sofia-sans-condensed-latin-700-normal.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:"Sofia Sans Condensed";font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/sofia-sans-condensed-latin-ext-700-normal.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Sofia Sans Condensed";font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/sofia-sans-condensed-cyrillic-700-normal.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:"Sofia Sans Condensed";font-style:normal;font-weight:700;font-display:swap;src:url(/assets/fonts/sofia-sans-condensed-greek-700-normal.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}
@font-face{font-family:"Sofia Sans Condensed";font-style:normal;font-weight:800;font-display:swap;src:url(/assets/fonts/sofia-sans-condensed-latin-800-normal.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:"Sofia Sans Condensed";font-style:normal;font-weight:800;font-display:swap;src:url(/assets/fonts/sofia-sans-condensed-latin-ext-800-normal.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:"Sofia Sans Condensed";font-style:normal;font-weight:800;font-display:swap;src:url(/assets/fonts/sofia-sans-condensed-cyrillic-800-normal.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:"Sofia Sans Condensed";font-style:normal;font-weight:800;font-display:swap;src:url(/assets/fonts/sofia-sans-condensed-greek-800-normal.woff2) format("woff2");unicode-range:U+0370-0377,U+037A-037F,U+0384-038A,U+038C,U+038E-03A1,U+03A3-03FF}

:root{
  /* The redesign palette, lifted from claude-prompts/2026-09-05/redesign-mock.html */
  --paper:#FBF9F2; --card:#FFFFFF; --ink:#10201A; --body:#2B3A32; --muted:#5E6D64;
  --forest:#04613C; --forest-deep:#0B4A30; --on-forest:#FFFFFF;
  --mint:#DCEFDF; --mint-strong:#A9D9B8; --mint-soft:#EEF6EF;
  --amber:#E9A93B; --amber-soft:#FBF0D6;
  --line:#E4DFD1;

  --frame:#10201A;                 /* the phone bezel — must stay dark in dark mode */
  --shadow:16,29,22;
  --display:"Sofia Sans Condensed","Arial Narrow",Impact,sans-serif;
  --sans:Figtree,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  --ease:cubic-bezier(.22,.8,.3,1);
  color-scheme:light;

  /* Blog and legal furniture: the cream ground behind a post hero, a
     blockquote and a table head, and the radius they share. */
  --cream:#F4EDDE; --radius:22px;

  /* Direction-dependent geometry. Transforms cannot be expressed logically, so
     the sign lives here and [dir="rtl"] flips it exactly once. */
  --rot-brand-hover:-8deg;
}

[dir="rtl"]{
  --rot-brand-hover:8deg;
}

*{margin:0;padding:0;box-sizing:border-box}
html{scroll-behavior:smooth}
/* clip, not hidden: `overflow-x:hidden` on an ancestor silently kills
   position:sticky, which is what holds the header up. */
html,body{overflow-x:clip}
body{font-family:var(--sans);background:var(--paper);color:var(--ink);line-height:1.6;font-size:16px;-webkit-font-smoothing:antialiased}
/* height:auto is required now that every <img> carries width/height attributes:
   without it the attribute height wins over the CSS width and images squash. */
img{max-width:100%;height:auto;display:block}
a{color:var(--forest)}
p{color:var(--body)}
h1,h2,h3{font-family:var(--display);font-weight:800;line-height:1.02;letter-spacing:-.01em;text-wrap:balance}
h3{font-weight:700}
.wrap{max-width:1120px;margin:0 auto;padding-inline:22px}
/* A heading a screen reader needs and the design does not show. */
.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}

/* 1.02 is right for display type at 3rem and up. Everything set smaller — the
   legal pages — needs air or two lines touch, and most of these wrap in German. */
.legal :is(h1,h2,h3){line-height:1.2}

/* Arabic and Thai need more leading than Latin at the same size. */
[lang="ar"] body,[lang="th"] body,body[lang="ar"],body[lang="th"]{line-height:1.85}
:is([lang="ar"],[lang="th"]) body{line-height:1.85}

/* Negative tracking makes CJK glyphs collide; unspaced strings must still wrap. */
:is([lang="ja"],[lang="ko"],[lang^="zh"]) h1,
:is([lang="ja"],[lang="ko"],[lang^="zh"]) h2,
:is([lang="ja"],[lang="ko"],[lang^="zh"]) h3{letter-spacing:0}
h1,h2,h3,p,li,summary,figcaption{overflow-wrap:anywhere}

/* Visible focus. There was none at all before, which made the whole site
   unusable by keyboard. :focus-visible so it never shows on a mouse click. */
:focus-visible{outline:3px solid var(--forest);outline-offset:3px;border-radius:6px}

.skip{position:absolute;inset-inline-start:-9999px;top:0;z-index:100;background:var(--forest);color:var(--on-forest);padding:10px 18px;border-radius:0 0 12px 0;text-decoration:none}
.skip:focus{inset-inline-start:0}

/* ---------- header ----------------------------------------------------------
 * The floating pill of the 2026-09-28 home page, on every page. The <header>
 * is a sticky, see-through strip that lets clicks through; only the pill
 * (.nav) is solid. Sticky rather than fixed, so every page keeps its header
 * room in the flow and nothing below had to move.
 *
 * DOM order and visual order: brand · the links · the language chip · Get
 * the app · burger. .menu is the burger's panel; on desktop it is
 * `display:contents`, so the links sit in the pill as plain flex items. Below
 * 860px .menu becomes a real box under the pill and the chip, the Get-the-app
 * pill and the burger stay in the bar.
 * ------------------------------------------------------------------------- */
header{position:sticky;top:0;z-index:30;padding-block-start:14px;pointer-events:none}
.nav{pointer-events:auto;position:relative;display:flex;align-items:center;gap:6px;width:max-content;max-width:calc(100% - 24px);margin-inline:auto;padding:7px;padding-inline-start:14px;border-radius:999px;background:color-mix(in srgb,var(--card) 74%,transparent);backdrop-filter:blur(18px) saturate(1.6);-webkit-backdrop-filter:blur(18px) saturate(1.6);border:1px solid color-mix(in srgb,var(--ink) 8%,transparent);box-shadow:0 8px 30px -12px rgba(var(--shadow),.25)}
/* The wordmark: bare lowercase "daili", the mock's Figtree 700. */
.brand{display:flex;align-items:center;gap:8px;margin-inline-end:14px;text-decoration:none;color:var(--ink);font-family:var(--sans);font-weight:700;font-size:19px;letter-spacing:-.02em;line-height:1}
.brand img{width:26px;height:26px;border-radius:7px;transition:transform .5s var(--ease)}
.brand:hover img{transform:rotate(var(--rot-brand-hover)) scale(1.06)}

.menu{display:contents}
.links{order:1;display:flex;align-items:center;gap:0}
.links a.nl{text-decoration:none;color:var(--muted);font-weight:500;font-size:14px;line-height:1.2;padding:8px 11px;border-radius:999px;white-space:nowrap;transition:background .2s,color .2s}
.links a.nl:hover{background:color-mix(in srgb,var(--ink) 6%,transparent);color:var(--ink)}
.langpicker{order:2}
.dl{order:3}
.burger{order:4}

/* The two-locale pill. Dead at 23 locales, kept because LOCALES is a list
   anyone may shorten. */
.lang{border:1.5px solid var(--line);border-radius:999px;padding:6px 12px;font-size:.85rem;background:var(--card);text-decoration:none;color:var(--ink);transition:background .3s,border-color .3s}
.lang:hover{background:var(--mint-soft);border-color:var(--mint-strong)}

/* ---------- language picker ---------- */
.langpicker{position:relative}
/* A 38px round button inside the pill. It keeps the language code beside the
   globe — the one hint a reader in the wrong language can read. */
.langpicker summary{list-style:none;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;gap:6px;height:38px;min-width:38px;border:1px solid transparent;border-radius:999px;padding-inline:10px;font-size:.8rem;font-weight:700;letter-spacing:.06em;background:transparent;color:var(--muted);transition:background .3s,border-color .3s}
.langpicker summary::-webkit-details-marker{display:none}
.langpicker summary:hover{background:color-mix(in srgb,var(--ink) 6%,transparent);color:var(--ink)}
.langpicker summary svg{width:18px;height:18px;stroke:currentColor;fill:none;stroke-width:1.8;flex:none}
.langpicker summary .chev{display:none}
.langpicker-menu{position:absolute;inset-inline-end:0;top:calc(100% + 14px);background:var(--card);border:1px solid var(--line);border-radius:16px;padding:12px;box-shadow:0 22px 48px rgba(var(--shadow),.16);z-index:40;width:min(560px,88vw)}
.langpicker-menu ul{list-style:none;display:grid;grid-template-columns:repeat(3,1fr);gap:2px 10px}
.langpicker-menu a{display:flex;align-items:center;gap:10px;padding:7px 10px;border-radius:9px;text-decoration:none;color:var(--ink);font-size:.9rem;white-space:nowrap;overflow:hidden}
/* The code is set in the display face, which is condensed: 2.6em of it holds
   every two-letter code at this size without the endonyms losing their column. */
.langpicker-menu a small{font-family:var(--display);font-weight:700;letter-spacing:.06em;font-size:.72rem;color:var(--muted);width:2.6em;flex:none}
.langpicker-menu a:hover{background:var(--mint-soft)}
.langpicker-menu a[aria-current]{background:var(--mint);font-weight:600}

/* ---------- burger ---------- */
/* display:none until 860px, and `align-items` is set here rather than in the
   media query so the flex centring survives the display flip. */
.burger{display:none;align-items:center;justify-content:center;width:40px;height:40px;flex:none;border:0;background:transparent;border-radius:999px;cursor:pointer;transition:background .3s}
.burger:hover{background:color-mix(in srgb,var(--ink) 6%,transparent)}
.burger svg{width:20px;height:20px;stroke:var(--ink);fill:none;stroke-width:2}

/* download dropdown: the dark "Get the app" pill opens the store badges */
.dl{position:relative}
.dl-btn{display:inline-flex;align-items:center;gap:8px;background:var(--forest);color:var(--on-forest);border:1.5px solid transparent;border-radius:999px;padding:11px 22px;font-family:var(--sans);font-size:.98rem;font-weight:600;cursor:pointer;text-decoration:none;white-space:nowrap;transition:background .25s,transform .25s var(--ease),box-shadow .25s}
.dl-btn:hover{background:var(--forest-deep);transform:translateY(-1px);box-shadow:0 10px 24px rgba(4,97,60,.22);color:var(--on-forest)}
.nav .dl-btn{background:var(--frame);color:#fff;font-size:14px;padding:10px 16px;border:0}
.nav .dl-btn:hover{background:#000;color:#fff;box-shadow:none}
.nav .dl-btn svg{width:16px;height:16px;flex:none}
.dl-menu{position:absolute;inset-inline-end:0;top:calc(100% + 14px);background:var(--card);border:1px solid var(--line);border-radius:18px;padding:16px;box-shadow:0 22px 48px rgba(var(--shadow),.16);min-width:250px;display:none;flex-direction:column;gap:10px;z-index:40}
.dl.open .dl-menu{display:flex;animation:menuIn .3s var(--ease)}
@keyframes menuIn{from{opacity:0;transform:translateY(-8px)}to{opacity:1;transform:none}}
.dl-menu .store-badge{width:100%;justify-content:start}
.dl-menu small{color:var(--muted);font-size:.78rem;line-height:1.4}
/* The web-app button under (and beside) the store badges: the badge's height
   and radius, white with a dark outline. Also the home page's hero and final
   rows (home.css makes the hero's transparent). */
.web-btn{box-sizing:border-box;display:inline-flex;align-items:center;gap:10px;height:48px;padding-inline:14px 18px;border-radius:13px;background:#fff;color:#15271F;border:1.5px solid #15271F;font-family:var(--sans);font-weight:600;font-size:.98rem;line-height:1.15;text-decoration:none;white-space:nowrap;transition:background .2s,transform .3s var(--ease)}
.web-btn:hover{background:#F1F3EE;color:#15271F;transform:translateY(-1px)}
.web-btn svg{width:22px;height:22px;flex:none}
/* The menu's badges are 51 px tall (their small line is .78rem/1.4 above). */
.dl-menu .web-btn{width:100%;height:51px}

/* Between the burger and a wide screen, seven links in Ukrainian or Romanian
   do not fit the pill at the mock's spacing: it tightens instead. */
@media(min-width:861px) and (max-width:1080px){
  .brand{margin-inline-end:6px}
  .links a.nl{padding-inline:7px;font-size:13.5px}
  .langpicker summary{padding-inline:7px}
  .nav .dl-btn{padding-inline:13px}
  .nav .dl-btn svg{display:none}
}
@media(max-width:860px){
  header{padding-block-start:10px}
  .nav{width:auto;max-width:none;margin-inline:12px;padding-inline-start:12px}
  .brand{margin-inline-end:auto}
  .menu{display:none}
  .burger{display:inline-flex}
  /* The panel drops out under the pill, full width of it, and overlays the
     page instead of shoving it down. In RTL `inset-inline` covers both edges,
     so nothing to mirror. */
  body.menu-open .menu{display:flex;flex-direction:column;align-items:stretch;
    position:absolute;top:calc(100% + 8px);inset-inline:0;
    background:var(--card);border:1px solid var(--line);border-radius:22px;
    padding:10px;gap:4px;
    box-shadow:0 30px 50px rgba(var(--shadow),.14)}
  body.menu-open .links{flex-direction:column;align-items:stretch;gap:2px}
  body.menu-open .links a.nl{font-size:1.05rem;padding:12px 14px;color:var(--ink)}
  .langpicker-menu ul{grid-template-columns:repeat(2,1fr)}
}
@media(max-width:420px){
  .nav{gap:2px}
  .nav .dl-btn{padding-inline:13px}
  .nav .dl-btn svg{display:none}
  .langpicker summary{padding-inline:8px}
}

/* ---------- buttons ---------- */
.btn{display:inline-flex;align-items:center;gap:8px;border:1.5px solid transparent;border-radius:999px;padding-block:12px;padding-inline:22px;font-size:.98rem;font-weight:600;text-decoration:none;transition:transform .25s var(--ease),background .25s,box-shadow .25s}
/* The white outlined button beside the store badges in the home page's last section. */
.btn-ghost{background:var(--card);color:var(--ink);border-color:var(--line)}
.btn-ghost:hover{border-color:var(--mint-strong);background:var(--mint-soft);color:var(--ink)}
/* ---------- store badges ---------- */
/* .ctas is the row; .badges is what script.js looks for when it promotes the
   store the visitor is actually on. */
.ctas{display:flex;gap:12px;flex-wrap:wrap;align-items:center}
.store-badge{display:inline-flex;align-items:center;gap:10px;background:var(--frame);color:#fff;border-radius:13px;padding-block:9px;padding-inline:13px 16px;text-decoration:none;line-height:1.15;cursor:pointer;transition:opacity .15s,transform .3s var(--ease)}
.store-badge:hover{opacity:.85;color:#fff;transform:translateY(-1px)}
.store-badge svg{width:22px;height:22px;fill:#fff;flex:none}
.store-badge small{display:block;font-size:.65rem;font-weight:400;opacity:.8;color:#fff}
.store-badge span{font-weight:600;font-size:.98rem}
/* The platform the visitor is actually on gets the emphasis; the other stays
   available. Applied by script.js — with no JS both simply render equal. */
.store-badge.primary{outline:2px solid var(--mint-strong);outline-offset:2px}
.store-badge.secondary{opacity:.72}
.store-badge.secondary:hover{opacity:1}
/* A store that is not live yet: a <button>, not a link. Same box as a real
   badge so the row does not shift when the flag flips, visibly dimmed so it
   never reads as the thing to tap, and no hover lift — there is nowhere to
   go. script.js never adds .primary to it; the reset below is the belt to
   that braces, so a stray class can't outline a dead store. */
button.store-badge{border:0;margin:0;font-family:inherit;font-size:inherit;text-align:inherit;-webkit-appearance:none;appearance:none}
.store-badge.soon{opacity:.6}
.store-badge.soon:hover{opacity:.6;transform:none}
.store-badge.soon.primary{outline:none}
/* Full-width under the badge row in .ctas (a wrapping flex row) and a normal
   block in the nav's .dl-menu column. Logical properties only — this sits
   under an RTL badge row in /ar/ too. */
.store-soon{flex-basis:100%;width:100%;margin-block-start:10px;font-size:.85rem;line-height:1.4;color:var(--muted);text-align:start}

/* The same paragraph, promoted to a popover anchored to the chip.
 *
 * Everything below hangs off .soon-pop / .soon-anchor, which ONLY script.js
 * adds. With JavaScript off not one of these rules matches and the sentence
 * stays the plain line above — which is the whole reason the note ships
 * visible in the HTML rather than being built here.
 *
 * .soon-anchor is the chip's container (.badges). script.js applies it only
 * where the container is still position:static: .dl-menu is already absolute
 * and is its own containing block, and turning it relative would drop the nav
 * dropdown into the flow. The z-index keeps the card above the ✓ line that
 * follows it in the hero. */
.soon-anchor{position:relative;z-index:35}
.store-soon.soon-pop{
  position:absolute;z-index:35;                      /* under .sticky-cta (40) */
  inset-block-start:0;inset-inline-start:0;          /* both set by script.js */
  /* At 360px in English the badge row wraps and the card lands on top of the
     Google Play badge — the one thing on the page that is actually tappable.
     pointer-events:none means the tap goes straight through to Play and the
     document handler dismisses the card on the way, instead of the card
     swallowing it. Purely informational, so it gives up nothing but the
     ability to select the sentence. */
  pointer-events:none;
  width:max-content;max-width:min(280px,calc(100vw - 32px));
  margin-block-start:0;padding:11px 14px;
  background:var(--card);color:var(--body);
  border:1px solid var(--line);border-radius:14px;
  box-shadow:0 14px 34px rgba(var(--shadow),.18);
  font-size:.85rem;line-height:1.45;text-align:start;
  animation:soonIn .18s var(--ease)}
@keyframes soonIn{from{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:none}}
/* The arrow: a 12px square rotated onto its corner, half of it tucked under
   the card so its own background hides the card's top border.
   Its borders are PHYSICAL on purpose. rotate() does not mirror in RTL (see
   the --rot-* note at the top of this file), so top+left is what puts the tip
   at the top in both directions; border-inline-start would point it sideways
   in /ar/. Only the offset along the row is logical, and script.js overrides
   it so the tip keeps tracking the chip when the card has been clamped. */
.store-soon.soon-pop::before{
  content:"";position:absolute;
  top:-6px;inset-inline-start:var(--soon-arrow,16px);
  width:12px;height:12px;
  background:var(--card);
  border-top:1px solid var(--line);border-left:1px solid var(--line);
  transform:rotate(45deg)}

/* ---------- sticky mobile CTA ---------- */
.sticky-cta{position:fixed;inset-inline:0;bottom:0;z-index:40;display:none;align-items:center;gap:10px;justify-content:center;padding:12px 16px calc(12px + env(safe-area-inset-bottom));background:color-mix(in srgb,var(--paper) 94%,transparent);backdrop-filter:blur(10px);border-top:1px solid var(--line)}
.sticky-cta[hidden]{display:none}
.sticky-cta .dl-btn{flex:1;max-width:22rem;text-align:center}
/* Not a link and not styled as one: on iOS there is nothing to link to. */
.sticky-soon{flex:1;max-width:22rem;text-align:center;color:var(--body);font-size:.92rem;line-height:1.35}
.sticky-close{background:none;border:none;font-size:1.5rem;line-height:1;color:var(--muted);cursor:pointer;padding:4px 8px}

/* ---------- footer ---------- */
footer{border-top:1px solid var(--line);margin-top:90px;padding:38px 0 44px;font-size:.9rem;color:var(--muted)}
footer .cols{display:flex;gap:20px;flex-wrap:wrap;align-items:center;justify-content:space-between}
/* The links are a row with its own gaps rather than a sentence with separators:
   at 390px the row wraps to three lines and a trailing "·" at the end of a line
   reads as a typo. */
footer .flinks{display:flex;gap:6px 18px;flex-wrap:wrap}
footer a{color:var(--muted);text-decoration:none;transition:color .25s}
footer a:hover{color:var(--forest);text-decoration:underline;text-underline-offset:3px}

/* ---------- legal pages ---------- */
.legal{max-width:760px;margin:0 auto;padding:48px 20px}
.legal h1{font-size:2rem;margin-bottom:6px}
.legal .updated{color:var(--muted);font-size:.9rem;margin-bottom:26px}
.legal h2{font-size:1.25rem;margin:28px 0 8px}
.legal h3{font-size:1.08rem;margin:22px 0 8px}
.legal p,.legal li{color:var(--body);font-size:.98rem}
.legal ul{margin-block:8px;margin-inline-start:22px}
/* The binding-language note at the top of every translated legal body. Muted
   and small on purpose: it is a disclaimer above the title, not a headline. */
.legal .translated{color:var(--muted);font-size:.88rem;margin-bottom:18px}
.notice{background:var(--mint);border:1px solid var(--mint-strong);border-radius:14px;padding:12px 16px;margin:18px 0;font-size:.92rem}

@media(max-width:820px){
  /* Only shown on small screens, and only after script.js unhides it. */
  .sticky-cta:not([hidden]){display:flex}
  body{padding-bottom:76px}
}
/* ---------- dark mode ---------- */
/* Only the tokens are redefined. Everything above inherits, which is the whole
   point of having tokenised the palette. */
@media(prefers-color-scheme:dark){
  /* Not on the home page: it is designed light, with its own dark blocks. */
  :root:not(.landing){
    --paper:#0E1712; --card:#16211A; --ink:#EDF2EC; --body:#CBD6CE; --muted:#93A498;
    --forest:#5EC08F; --forest-deep:#7BD3A6; --on-forest:#08160F;
    --mint:#1D3327; --mint-strong:#2E4F3C; --mint-soft:#152219;
    --amber:#F0BC5E; --amber-soft:#2E2718;
    --line:#263A2E;
    /* --frame stays dark: a phone bezel that inverts to white reads as a
       rendering bug, and the store badges sit on it with white text. */
    --frame:#0A110D;
    --shadow:0,0,0;
    color-scheme:dark;
    --cream:#141D18;
    }
  .store-badge{background:#000;border:1px solid var(--line)}
  /* The border above comes from a shorthand the <button> reset zeroes out. */
  button.store-badge{border:1px solid var(--line)}
  .store-badge.soon{opacity:.62}
  .store-badge.soon:hover{opacity:.62}
  /* The popover's fill, text, border and arrow are all tokens that flip above,
     so --card on --paper keeps the card a shade lighter than the page here
     too. The shadow is the one thing that does not carry over: --shadow turns
     into 0,0,0 and .18 of black on a near-black page is invisible, which would
     leave the card floating with only its 1px border. */
  .store-soon.soon-pop{box-shadow:0 16px 40px rgba(var(--shadow),.55)}
  /* The Get-the-app pill is --frame, near-black: on a dark header it needs
     the accent to stay a button. */
  .nav .dl-btn{background:var(--forest);color:var(--on-forest)}
  .nav .dl-btn:hover{background:var(--forest-deep);color:var(--on-forest)}
}

/* ---------- reduced motion ---------- */
@media(prefers-reduced-motion:reduce){
  *,*::before,*::after{animation:none!important;transition:none!important}
  /* The hover lifts are the only motion left on the page that a transition
     rule does not already stop — a transform with no transition still jumps. */
  .store-badge:hover,.dl-btn:hover,.web-btn:hover{transform:none}
  html{scroll-behavior:auto}
}

/* ---------- blog post ---------- */
/* Every rule here is built on the tokens redefined in the dark-mode block
   above, so the post gets dark mode for free — no colour literal below. */
.post{max-width:68ch;margin:0 auto;padding:40px 20px 64px}
.post-hero{margin-bottom:26px;border-radius:var(--radius);overflow:hidden;background:var(--cream)}
.post-hero img{width:100%}
.post h1{font-size:clamp(1.7rem,4.6vw,2.3rem);line-height:1.2;letter-spacing:-.02em;margin-bottom:10px}
.post-byline{color:var(--muted);font-size:.9rem;margin-bottom:28px;padding-bottom:18px;border-bottom:1px solid var(--line)}
.post h2{font-size:1.38rem;line-height:1.3;letter-spacing:-.01em;margin:38px 0 12px}
.post h3{font-size:1.06rem;margin:24px 0 6px}
.post p,.post li{color:var(--body);font-size:1.02rem}
.post p{margin-bottom:16px}
.post ul,.post ol{margin-bottom:18px;padding-inline-start:24px}
.post li{margin-bottom:9px}
.post strong{color:var(--ink)}
.post a{text-underline-offset:3px}
/* Post 2 names files inline (`emma-vaccinations`, not IMG_4471). Without a
   rule the UA's monospace default shrinks them mid-sentence. Monospace alone is
   enough to mark a filename in prose — a boxed chip reads as developer docs and
   its padding leaves the following full stop floating away from the word. */
.post code{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:.9em;color:var(--ink)}

/* Post 11 is the first post to carry a blockquote, and it is not a quotation —
   it is a letter template the reader is meant to copy or print. So it is marked
   as a block the eye can lift off the page rather than as an aside: the cream
   ground and the rule down the leading edge say "this part is the document".
   The UA's own blockquote margin is dropped; padding does that job here, and
   40px of it would push the ruled edge away from the measure on a phone.
   `padding-inline-start` and a border on the inline edge, not left, so the RTL
   locales the rest of this file is careful about would flip it correctly if the
   blog ever gains one. */
.post blockquote{margin:0 0 22px;padding:20px 22px;background:var(--cream);border-inline-start:3px solid var(--line);border-radius:calc(var(--radius) - 8px)}
.post blockquote p:last-child{margin-bottom:0}

/* The one table in the post is wider than a phone. It scrolls inside its own
   box; the page itself must never scroll sideways. */
.table-wrap{overflow-x:auto;margin-bottom:22px;border:1px solid var(--line);border-radius:14px}
.post-table{border-collapse:collapse;width:100%;min-width:500px;font-size:.93rem}
.post-table th,.post-table td{border-bottom:1px solid var(--line);padding:11px 14px;text-align:start;color:var(--body)}
.post-table thead th{background:var(--cream);font-size:.76rem;text-transform:uppercase;letter-spacing:.05em;color:var(--muted);font-weight:700}
.post-table tbody th{font-weight:600;color:var(--ink)}
.post-table tbody tr:last-child>*{border-bottom:0}

/* The FAQ is the last section of the article, not a widget bolted on after it:
   same type scale as the prose above, one rule to mark the seam. */
.post-faq{margin-top:42px;padding-top:24px;border-top:1px solid var(--line)}

.post-cta{margin-top:42px;background:var(--mint);border:1px solid var(--mint-strong);border-radius:calc(var(--radius) - 4px);padding:26px 24px}
.post-cta h2{margin-top:0;font-size:1.18rem;color:var(--forest-deep)}
.post-cta p:last-child{margin-bottom:0}
.post-cta-link a{font-weight:600}

/* The newsletter sign-up, directly under the CTA. Same card geometry as
   .post-cta — border, radius, padding — on the quieter mint, so two panels in
   a row read as two things rather than one long one and the CTA above stays
   the louder of the pair. Every value is a token, so dark mode and the print
   sheet below both come for free. */
.post-newsletter{margin-top:24px;background:var(--mint-soft);border:1px solid var(--mint-strong);border-radius:calc(var(--radius) - 4px);padding:26px 24px}
.post-newsletter h2{margin-top:0;font-size:1.18rem;color:var(--forest-deep)}
.nl-label{display:block;font-size:.92rem;font-weight:600;color:var(--ink);margin-bottom:6px}
/* One row while there is room for it, stacked on a phone (below): an input
   squeezed down to leave space for a button beside it is the wrong trade on
   the one screen where the address is actually typed. */
.nl-row{display:flex;gap:10px;flex-wrap:wrap}
.nl-input{flex:1 1 220px;min-width:0;background:var(--card);color:var(--ink);border:1.5px solid var(--line);border-radius:999px;padding:11px 18px;font-family:var(--sans);font-size:1rem}
.nl-input::placeholder{color:var(--muted)}
.nl-input:hover{border-color:var(--mint-strong)}
/* Same shape as .btn-primary, written out rather than reused: the blog post is
   the one place a <button> submits a form, and .btn carries link rules it does
   not need. The focus ring is the global :focus-visible outline near the top of
   this file — both the field and the button get it for free. */
.nl-btn{flex:0 0 auto;background:var(--forest);color:var(--on-forest);border:1.5px solid transparent;border-radius:999px;padding:11px 24px;font-family:var(--sans);font-size:.98rem;font-weight:600;cursor:pointer;transition:background .25s,transform .25s var(--ease)}
.nl-btn:hover{background:var(--forest-deep);transform:translateY(-1px)}
/* The honeypot, hidden by the WRAPPER rather than by display:none on the input
   itself: a field the browser never lays out is one a bot can recognise as a
   trap, while a clipped one is laid out, focusable in principle, and filled.
   tabindex="-1" and aria-hidden on the wrapper keep it away from people. */
.nl-hp{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip-path:inset(50%);white-space:nowrap;border:0}
.post-newsletter .nl-small{margin:14px 0 0;font-size:.86rem;color:var(--muted)}

@media(max-width:560px){
  .post{padding:22px 18px 48px}
  .post-hero{border-radius:16px}
  .post-cta{padding:22px 18px}
  .post-newsletter{padding:22px 18px}
  /* Full-width field over full-width button: wrapping alone would leave a
     "Subscribe" pill the width of its own label under a full-width input.
     The field's flex must be reset with the direction — a 220px basis is a
     width in a row and a 220px-TALL text box in a column. */
  .nl-row{flex-direction:column}
  .nl-input{flex:0 0 auto;width:100%}
  .nl-btn{width:100%}
}

/* ---------- printing a post ---------- */
/* Post 3 is a 27-item checklist, and a checklist is printed and stuck to the
   inside of a cupboard door. That is the whole reason the post exists — people
   link to what prints well — so the print sheet is part of the article, not a
   nicety.

   What goes: the header (and with it the language picker), the footer, the skip
   link, the hero photo, the CTA and the newsletter form. None of them are the
   checklist, the hero alone is half a sheet of ink, and a form that cannot be
   submitted from paper is worse than absent. What stays: the h1, the byline,
   the prose and every numbered item.

   The ☐ is scoped to .doc-checklist rather than to .post ol, so a future post
   with an ordinary numbered list does not print as a to-do list. The list
   marker still supplies the number; the box sits after it. */
@page{margin:16mm}

@media print{
  /* Black on white whatever the screen was doing. The dark-mode block above is
     a media query, not a class, so a laptop set to dark would otherwise print
     the checklist as pale grey on near-black — 27 items of it. Every rule in
     this file reads a token, so putting the tokens back here is the whole fix;
     this block comes later in the file, so it wins. */
  :root{
    --paper:#fff; --card:#fff; --cream:#fff;
    --ink:#000; --body:#1a1a1a; --muted:#3f3f3f; --line:#b9b9b9;
  }
  html,body{background:#fff}

  header,footer,.skip,.post-hero,.post-cta,.post-newsletter{display:none}

  .post{max-width:none;margin:0;padding:0}
  .post h1{font-size:19pt}
  .post h2{font-size:13pt;margin:18pt 0 6pt}
  .post h3{font-size:11.5pt}
  .post p,.post li{font-size:10.5pt}
  .post-byline{margin-bottom:14pt;padding-bottom:8pt}

  /* A printed link cannot be clicked, and blue underlines all down a checklist
     read as noise. The href is not printed after the text either: three of them
     are internal and one is a 130-character German URL. */
  .post a{color:inherit;text-decoration:none}

  .doc-checklist li{margin-bottom:6pt;break-inside:avoid}
  .doc-checklist li::before{content:"\2610\00a0\00a0"}

  /* A heading stranded at the foot of a page takes its section's first items
     with it and the printed list stops looking like one list. */
  .post h2{break-after:avoid}

  /* Post 11's consent letter is the one block on the blog people print in order
     to fill it in, so it gets the two rules that matter on paper. It must not
     split across a page break — half a letter on each sheet is not a letter —
     and it needs a real box: the tokens above turn every ground white, which
     would leave the cream panel invisible and the template indistinguishable
     from the prose around it. */
  .post blockquote{background:none;border:1px solid var(--line);padding:11pt 13pt;break-inside:avoid}
}

/* ---------- what's new (release notes) ---------- */
/* Built on .legal, so measure, headings and dark mode all come for free; these
   are only the rules that separate one release block from the next. */
.release+.release{margin-top:30px;padding-top:26px;border-top:1px solid var(--line)}
.release h2{display:flex;flex-wrap:wrap;align-items:baseline;gap:8px}
.release h2 small{font-size:.82rem;font-weight:500;color:var(--muted)}
.release ul{margin-block:10px}

/* The nav no longer hides the Blog link below 560px. That rule existed because
   the old header wrapped: six items ran off the right edge in Arabic and grew a
   third row in five other locales. Under 860px the links are now a panel, one
   per line, so width is no longer what decides whether the link fits — and the
   Blog link is reachable in every locale at every size, which the footer alone
   used to have to cover. */

/* ---------- blog index ---------- */
.blogindex{max-width:820px;padding-block:44px 64px}
.blogindex h1{font-size:clamp(1.8rem,5vw,2.4rem);letter-spacing:-.02em;margin-bottom:8px}
.blogindex-intro{color:var(--muted);font-size:1.02rem;max-width:60ch;margin-bottom:34px}
.postlist{list-style:none}
.postlist-item{display:grid;grid-template-columns:220px 1fr;gap:22px;align-items:start;padding:24px 0;border-top:1px solid var(--line)}
.postlist-art{display:block;border-radius:14px;overflow:hidden;background:var(--cream)}
.postlist-art img{width:100%}
.postlist-txt h2{font-size:1.22rem;line-height:1.32;letter-spacing:-.01em;margin-bottom:8px}
.postlist-txt h2 a{color:var(--ink);text-decoration:none}
.postlist-txt h2 a:hover{color:var(--forest);text-decoration:underline;text-underline-offset:3px}
.postlist-txt p{color:var(--body);font-size:.97rem;margin-bottom:10px}
.postlist-txt time{color:var(--muted);font-size:.86rem}
@media(max-width:640px){
  .postlist-item{grid-template-columns:1fr;gap:14px}
  .postlist-art{max-width:100%}
}

/* ---------- help center ----------
 * /help/, /help/<topic>/ and /help/<topic>/<slug>/. The blog post is the
 * model: same measure, same type scale, same tokens — so dark mode and RTL
 * come for free from the blocks above. The shapes (topic cards with an icon
 * badge, rows with a chevron, round step numbers, a soft note box) follow the
 * app's own Help screen, because the same articles are shown there. */
.help{max-width:760px;padding-block:40px 64px}
.help h1{font-size:clamp(1.8rem,5vw,2.4rem);line-height:1.12;letter-spacing:-.02em;margin-bottom:8px}
.help h2{font-size:1.2rem;line-height:1.3;margin:34px 0 12px}
.help-lede{color:var(--muted);font-size:1.04rem;max-width:60ch}
.help-crumb{display:inline-block;font-size:.9rem;font-weight:600;text-decoration:none;margin-bottom:12px}
.help-crumb::before{content:"← "}
[dir="rtl"] .help-crumb::before{content:"→ "}
.help-crumb:hover{text-decoration:underline;text-underline-offset:3px}

/* Minzi sits beside the title, vertically centred; under it on a phone. */
.help-hero{display:flex;align-items:center;justify-content:space-between;gap:20px}
.help-minzi{width:96px;height:96px;flex:none}

.help-search{margin-top:24px}
.help-search label{display:block;font-weight:600;font-size:.92rem;margin-bottom:6px;color:var(--ink)}
.help-search input{width:100%;font:inherit;font-size:1.02rem;color:var(--ink);background:var(--card);border:1px solid var(--line);border-radius:14px;padding:13px 16px;-webkit-appearance:none;appearance:none}
.help-search input::placeholder{color:var(--muted)}
.help-search input:focus{outline:2px solid var(--forest);outline-offset:1px;border-color:transparent}
.help-none{color:var(--muted);font-size:.95rem}

/* The icon badge: a mint chip, like the app's topic tiles. */
.help-ico{display:inline-grid;place-items:center;width:44px;height:44px;border-radius:13px;background:var(--mint);flex:none}
.help-ico svg{width:22px;height:22px;fill:none;stroke:var(--forest);stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}

.help-grid{list-style:none;display:grid;grid-template-columns:1fr 1fr;gap:12px}
.help-card{display:flex;flex-direction:column;align-items:flex-start;gap:4px;height:100%;padding:18px;background:var(--card);border:1px solid var(--line);border-radius:18px;text-decoration:none;color:var(--ink);transition:border-color .15s,transform .3s var(--ease)}
.help-card .help-ico{margin-bottom:8px}
.help-card b{font-size:1.02rem;line-height:1.3}
.help-card small{color:var(--muted);font-size:.88rem}
.help-card:hover{border-color:var(--mint-strong);transform:translateY(-1px)}
.help-card-stuck{background:transparent;border-style:dashed;border-width:1.5px}

/* A list of articles: one card, rows divided by a hairline, a chevron each. */
.help-list{list-style:none;background:var(--card);border:1px solid var(--line);border-radius:18px;overflow:hidden}
.help-list li+li{border-top:1px solid var(--line)}
.help-row{display:flex;align-items:center;gap:14px;padding:15px 18px;text-decoration:none;color:var(--ink)}
.help-row span{flex:1;min-width:0}
.help-row b{display:block;font-size:1rem;line-height:1.35}
.help-row small{display:block;color:var(--muted);font-size:.9rem;line-height:1.45;margin-top:2px}
.help-row:hover{background:var(--mint-soft)}
.help-chev{width:18px;height:18px;flex:none;fill:none;stroke:var(--muted);stroke-width:2;stroke-linecap:round;stroke-linejoin:round}
[dir="rtl"] .help-chev{transform:scaleX(-1)}
.help-topic-head{display:flex;align-items:center;gap:16px;margin-bottom:26px}
.help-topic-head h1{margin-bottom:4px}

/* The article. */
.help-article{max-width:68ch}
.help-article .help-lede{margin-bottom:24px;padding-bottom:18px;border-bottom:1px solid var(--line)}
.help-article p{color:var(--body);font-size:1.02rem;margin-bottom:16px}
.help-article strong{color:var(--ink);font-weight:700}
.help-steps{list-style:none;counter-reset:step;margin:0 0 22px}
.help-steps li{counter-increment:step;position:relative;padding-inline-start:44px;margin-bottom:14px;color:var(--body);font-size:1.02rem;min-height:30px;padding-top:2px}
.help-steps li::before{content:counter(step);position:absolute;inset-inline-start:0;top:0;width:30px;height:30px;border-radius:50%;display:grid;place-items:center;background:var(--forest);color:var(--on-forest);font-weight:700;font-size:.9rem}
.help-fig{margin:6px 0 24px;background:var(--cream);border-radius:var(--radius);padding:14px}
.help-fig img{margin-inline:auto;max-height:560px;width:auto;border-radius:14px}
.help-fig figcaption{text-align:center;color:var(--muted);font-size:.88rem;margin-top:10px}
.help-note{background:var(--mint-soft);border:1px solid var(--mint-strong);border-radius:14px;padding:14px 16px}
.help-note b{color:var(--forest-deep)}
.help-stuck{margin-top:36px;background:var(--mint);border:1px solid var(--mint-strong);border-radius:calc(var(--radius) - 4px);padding:22px 24px}
.help-stuck h2{margin:0 0 6px;font-size:1.15rem;color:var(--forest-deep)}
.help-stuck p{margin-bottom:0}
.help-stuck a{font-weight:600}
.help-updated{color:var(--muted);font-size:.9rem;margin-top:22px}
.help-article .help-updated{color:var(--muted);font-size:.9rem}
.help-badges{display:flex;flex-wrap:wrap;gap:10px;margin-top:18px}
/* "Was this helpful?": outlined pill buttons, like the app's. */
.help-helpful{display:flex;flex-wrap:wrap;align-items:center;gap:10px 14px;margin-top:28px}
.help-helpful[hidden]{display:none}
.help-article .help-helpful-q{margin:0;font-weight:600;color:var(--ink)}
.help-helpful-btns{display:flex;gap:10px}
.help-helpful-btn{display:inline-grid;place-items:center;width:56px;height:40px;border-radius:999px;background:transparent;border:1.5px solid var(--mint-strong);color:var(--forest);cursor:pointer;transition:background .15s,border-color .15s}
.help-helpful-btn svg{width:20px;height:20px;fill:none;stroke:currentColor;stroke-width:1.8;stroke-linecap:round;stroke-linejoin:round}
.help-helpful-btn:hover:not(:disabled){background:var(--mint-soft);border-color:var(--forest)}
.help-helpful-btn:focus-visible{outline:2px solid var(--forest);outline-offset:2px}
.help-helpful-btn:disabled{opacity:.5;cursor:default}
.help-article .help-helpful-thanks{margin:0;color:var(--forest);font-weight:600}

@media(max-width:380px){.help-hero{flex-direction:column;align-items:flex-start}}
@media(max-width:560px){
  .help-minzi{width:80px;height:80px}
  .help-card{padding:14px}
  .help-fig img{max-height:460px}
}
@media(max-width:340px){.help-grid{grid-template-columns:1fr}}
