/* Zetareh — warm family identity. Light/dark aware, RTL-safe. */
:root{
  --card2:#ecebe4; --paper:#f5f3ec; --card:#fffdf7; --ink:#1b2621; --mut:#5f6f66;
  --line:#e5e0d3; --green:#2f5d4a; --green-ink:#24493a; --honey:#b6791f;
  --brick:#a8503a; --good:#3f7d5a; --radius:14px; --shadow:0 12px 34px rgba(28,44,36,.10);
  --nav-h:62px;
}
@media (prefers-color-scheme:dark){:root{
  --card2:#232b27; --paper:#0e1411; --card:#18211d; --ink:#edf2ef; --mut:#9fb3aa;
  --line:#293630; --green:#7ab99a; --green-ink:#bfe6d1; --honey:#dca457;
  --brick:#d97b60; --good:#5fae86; --shadow:0 18px 48px rgba(0,0,0,.45);
}}
:root[data-theme="light"]{--paper:#f5f3ec;--card:#fffdf7;--ink:#1b2621;--mut:#5f6f66;--line:#e5e0d3;--green:#2f5d4a;--green-ink:#24493a;--honey:#b6791f;--brick:#a8503a;--good:#3f7d5a;--shadow:0 12px 34px rgba(28,44,36,.10);}
:root[data-theme="dark"]{--card2:#232b27;/* --card2 WAS MISSING HERE. It had a light value in :root and a dark one only inside
   @media(prefers-color-scheme:dark), so a phone in LIGHT mode running the app in dark kept the
   LIGHT #ecebe4 -- which is exactly how the call line became grey-on-grey. Any token set in the
   media query must also be set here, or it silently reverts for the people who chose dark. */--paper:#0e1411;--card:#18211d;--ink:#edf2ef;--mut:#9fb3aa;--line:#293630;--green:#7ab99a;--green-ink:#bfe6d1;--honey:#dca457;--brick:#d97b60;--good:#5fae86;--shadow:0 18px 48px rgba(0,0,0,.45);}

*{box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
body{margin:0;background:var(--paper);color:var(--ink);font-size:16.5px;line-height:1.6;
  font-family:system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;-webkit-font-smoothing:antialiased}
h1,h2,h3{font-family:"Iowan Old Style",Georgia,"Times New Roman",serif;line-height:1.15;
  text-wrap:balance;letter-spacing:-.01em;margin:0 0 .3em}
a{color:var(--green);text-decoration:none}
.muted{color:var(--mut)}
.eyebrow{font-size:12.5px;letter-spacing:.15em;text-transform:uppercase;color:var(--honey);font-weight:700}
:where(a,button,input,select,textarea):focus-visible{outline:2px solid var(--honey);outline-offset:2px;border-radius:6px}

/* top bar */
/* ⚠ THE STATUS BAR IS NOT FREE SPACE. layout.php declares
     <meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
   which tells iOS the web content owns the full screen INCLUDING the strip holding the clock, the
   signal and the battery — and nothing then compensated for it. env(safe-area-inset-top) appeared
   ZERO times in the whole layout, so on every notched iPhone the header was drawn underneath the
   clock. Masud, 2026-08-09, from a screenshot of it.

   ⚠ AND IT IS ALSO WHY THE HALLWAY BOX LANDED ON PAGE HEADINGS. hallway.js positions itself at
   env(safe-area-inset-top) + 10px and already reserves a 58px gutter inside .topbar for exactly this
   reason. But an inset-ignoring topbar is SHORTER than that offset, so the box fell past it and onto
   the <h1> below. Give the bar its inset and the box lands inside the gutter that was always there.
   One cause, two symptoms — which is why this is not fixed in the two pages where it was noticed. */
.topbar{position:sticky;top:0;z-index:20;background:var(--paper);
  border-bottom:1px solid var(--line);
  padding-top:env(safe-area-inset-top,0px)}
.bar-inner{max-width:1140px;margin:0 auto;padding:0 20px;min-height:var(--nav-h);
  display:flex;align-items:center;gap:18px}
.brand{font-family:"Iowan Old Style",Georgia,serif;font-weight:800;font-size:22px;color:var(--green-ink);letter-spacing:-.5px}
.brand span{color:var(--green-ink)}.brand .humanity{color:var(--honey)}

/* "is Humanity" — same serif face as Zetareh, a little LARGER than the name, in SMALL CAPS
   (lowercase drawn as capitals at x-height). Iowan Old Style ships real small caps; Georgia
   does not, so Windows/Android get the browser's synthesized ones.
   Colour is var(--honey) — the same token that paints "Tribe" — so the tagline tracks the
   brand and follows it into dark mode without a hardcoded override. No outline. */
.humanity{font-size:1.12em;font-weight:800;letter-spacing:.2px;margin-inline-start:14px;
  white-space:nowrap;color:var(--honey);vertical-align:baseline;
  font-variant-caps:small-caps;font-feature-settings:"smcp" 1}
.hword{font-weight:inherit}   /* kept as a hook: "Humanity" is the word a logo will replace */

@media (max-width:520px){
  /* the tagline is bigger than the name; on a narrow phone the pair would push the
     avatar and language picker off the bar */
  .humanity{font-size:.92em;margin-inline-start:8px}
}
.mainnav{display:flex;gap:4px;flex-wrap:wrap;margin-inline-start:8px}
.mainnav a{color:var(--mut);font-weight:600;font-size:14.5px;padding:8px 12px;border-radius:9px}
.mainnav a:hover{color:var(--ink);background:color-mix(in srgb,var(--green) 10%,transparent)}
.mainnav a.active{color:var(--green-ink);background:color-mix(in srgb,var(--green) 15%,transparent)}
.navright{margin-inline-start:auto;display:flex;align-items:center;gap:10px}
.navav{width:34px;height:34px;border-radius:50%;overflow:hidden;display:grid;place-items:center;
  flex:0 0 auto;border:1px solid var(--line);font-weight:700;font-size:13px;color:#fff;
  background:hsl(var(--hue,150) 42% 42%);text-decoration:none}
.navav img{width:100%;height:100%;aspect-ratio:1/1;object-fit:cover;object-position:center;display:block}
.navav:hover{border-color:var(--green)}
.langsw{display:inline-flex;align-items:center;gap:6px;border:1px solid var(--line);border-radius:999px;
  background:var(--card);padding:4px 10px 4px 11px}
.langsw:hover{border-color:color-mix(in srgb,var(--green) 45%,var(--line))}
.langsw-ic{display:inline-flex;color:var(--mut)}
.langsw-ic .mtic{width:15px;height:15px;vertical-align:0}
/* Strip the OS chrome off the select and draw our own chevron, so it matches the pill instead of
   looking like a raw form control dropped into the nav. */
.langsw select{appearance:none;-webkit-appearance:none;border:0;outline:0;background:transparent;
  color:var(--ink);font:inherit;font-size:13px;font-weight:600;cursor:pointer;
  padding:1px 16px 1px 0;line-height:1.4;
  background-image:linear-gradient(45deg,transparent 50%,currentColor 50%),linear-gradient(135deg,currentColor 50%,transparent 50%);
  background-position:calc(100% - 6px) 52%,calc(100% - 2px) 52%;
  background-size:4px 4px,4px 4px;background-repeat:no-repeat}
.langsw select:focus-visible{outline:2px solid var(--green);outline-offset:3px;border-radius:6px}
/* ⚠ THE OPEN LIST IS DRAWN BY THE OS, NOT BY US (Masud, 2026-09-15, on a PC: "there is contrast between
   background and text, at least when selecting language"). The closed pill takes --ink and a transparent
   background, and Windows then paints the dropped-down <option>s with that same near-white ink on the
   system's WHITE list background — unreadable in dark mode. color-scheme tells the OS which palette to
   paint the list in, and the options carry an explicit pair of their own so neither half is inherited. */
.langsw select{color-scheme:light}
.langsw select option{color:#1b2621;background:#fffdf7}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .langsw select{color-scheme:dark}
  :root:not([data-theme="light"]) .langsw select option{color:#e8ece9;background:#232b27}}
:root[data-theme="dark"] .langsw select{color-scheme:dark}
:root[data-theme="dark"] .langsw select option{color:#e8ece9;background:#232b27}
.langsw-go{margin-left:4px;border:0;background:var(--green);color:#fff;border-radius:999px;padding:2px 8px;cursor:pointer}

/* buttons */
.btn{display:inline-flex;align-items:center;gap:8px;background:var(--green);color:#fff;font-weight:600;
  font-size:14.5px;padding:9px 16px;border-radius:10px;border:1px solid transparent;cursor:pointer}
.btn:hover{filter:brightness(1.06)}
.btn.ghost{background:transparent;color:var(--ink);border-color:var(--line)}
.btn.ghost:hover{border-color:var(--green);color:var(--green-ink);filter:none}
.btn.big{font-size:16px;padding:12px 22px;border-radius:12px}
.btn.sm{font-size:13px;padding:6px 12px}

main{max-width:1140px;margin:0 auto;padding:28px 20px 60px}
main.landing{max-width:960px;text-align:center}

/* landing */
.hero{padding:56px 0 30px}
.hero h1{font-size:clamp(32px,6vw,54px);margin:16px auto 12px;max-width:16ch}
.hero .lede{font-size:19px;color:var(--mut);max-width:56ch;margin:0 auto 30px}
.hero-cta{display:flex;gap:12px;justify-content:center;flex-wrap:wrap}
.features{display:grid;grid-template-columns:repeat(3,1fr);gap:16px;margin-top:56px;text-align:start}
.feat{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:24px;box-shadow:var(--shadow)}
.feat .ic{font-size:20px}.feat h3{font-size:19px;margin:10px 0 6px}.feat p{color:var(--mut);font-size:14.5px;margin:0}

/* auth + forms */
/* A COLUMN, not a row. This was written for a page with ONE centred card -- login, register --
   and it is a flex ROW with no wrap, so a page with several top-level cards laid them out
   SIDE BY SIDE and ran off both edges of the phone. Preferences has three (Preferences,
   Region, Face ID) and was unusable: you saw the middle one and slivers of its neighbours.
   Column + align-items:center centres a single card exactly as before -- a flex item never
   grew to fill the row anyway -- and stacks the rest instead of overflowing. 2026-07-29. */
.authpage,.formpage{display:flex;flex-direction:column;align-items:center;gap:16px}
.authcard,.formcard{background:var(--card);border:1px solid var(--line);border-radius:18px;
  padding:34px 32px;box-shadow:var(--shadow);width:100%;max-width:440px;margin-top:24px}
.formcard{max-width:720px}.authcard.wide{max-width:520px}
.authcard h1,.formcard h1{font-size:26px;margin-bottom:14px}
/* Add-a-relative heading: SMALL CAPS, branch icon and sentence on ONE line, always.
   The font-size here is only a FALLBACK for no-JS. The real sizing is done by fitHeading()
   in add_relative.php, which MEASURES the rendered text against the space available and
   shrinks until it fits. A hand-picked vw factor cannot do this: it scales with the screen
   but is blind to the TEXT, so a longer translation (or a wider font) silently clips. */
.ar-h1{font-variant-caps:small-caps;font-feature-settings:"smcp" 1;letter-spacing:.4px;
  white-space:nowrap;overflow:hidden;font-size:clamp(15px,4.4vw,26px)}
/* Narrow phones: claw back side padding so the one-line heading has room to be readable. */
@media (max-width:420px){.formcard{padding:26px 18px}}
.stack{display:flex;flex-direction:column;gap:14px;margin-top:16px}
.stack.grid2,.grid2{display:grid;grid-template-columns:1fr 1fr;gap:14px}
.grid2 .full,.stack .full{grid-column:1/-1}
label{display:flex;flex-direction:column;gap:6px;font-size:13.5px;font-weight:600;color:var(--mut)}
label.check{flex-direction:row;align-items:center;gap:8px}
input,select,textarea{font:inherit;font-weight:400;color:var(--ink);background:var(--paper);
  border:1px solid var(--line);border-radius:10px;padding:11px 12px;width:100%}
input:focus,select:focus,textarea:focus{border-color:var(--green);background:var(--card)}
textarea{resize:vertical}
.formerr{background:color-mix(in srgb,var(--brick) 14%,transparent);color:var(--brick);
  border:1px solid color-mix(in srgb,var(--brick) 30%,transparent);padding:10px 14px;border-radius:10px;font-size:14px}
.formok{background:color-mix(in srgb,var(--good) 14%,transparent);color:var(--good);
  border:1px solid color-mix(in srgb,var(--good) 30%,transparent);padding:12px 16px;border-radius:10px}
.invitebadge{color:var(--good);font-size:14px}
.authalt{margin-top:18px;font-size:14px;color:var(--mut)}
.or{color:var(--mut);font-size:13px;text-align:center;margin:2px 0}

/* app shell */
.hero-sm{margin:6px 0 26px}
.hero-sm h1{font-size:clamp(26px,4vw,36px)}
.block{margin-top:34px}.block h2{font-size:22px;margin-bottom:16px}
.cards3{display:grid;grid-template-columns:1.4fr 1fr 1fr;gap:16px}
.card{background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:20px;box-shadow:var(--shadow)}
.card h3{font-size:17px;margin:0}
.card.link{display:flex;flex-direction:column;justify-content:center;align-items:flex-start;gap:8px;transition:transform .12s}
.card.link:hover{transform:translateY(-2px);border-color:var(--green)}
.card.link .ic{font-size:20px}
.card.you{display:flex;flex-direction:column;gap:12px}
.card.you .btn{align-self:flex-start}

/* person cards + grids */
/* People grid — Instagram/Facebook style: borderless, photo-forward, recognizable avatars */
.mgrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(96px,1fr));gap:14px 10px}
.mgrid.sm{grid-template-columns:repeat(auto-fill,minmax(84px,1fr))}
/* ONE PERSON PER ROW — MyTribe's member list, matching Zetareh People.
   ⚠ Only applied where the markup asks for it (public/members.php). .mgrid is shared with the tree
   and the couple cards, so the grid behaviour above must stay exactly as it is.
   ⚠ NO SEPARATORS. A hairline between every row draws the eye to the gaps rather than to the people,
   and at this density the rows read as a list without one. Spacing is the row's own padding and
   nothing else — the least that keeps two circles from touching. */
.mgrid.mstack{grid-template-columns:1fr;gap:0}
.mstack .pcard{flex-direction:row;align-items:center;text-align:left;gap:11px;
  padding:5px 8px;border-radius:9px}
.mstack .pcard .av{width:44px;height:44px;font-size:15px;flex:none}
.mstack .pcard .ptxt{display:flex;flex-direction:column;gap:1px;min-width:0;flex:1}
.mstack .pcard .pn{font-size:15.5px;line-height:1.2}
/* Their most recent words. ONE LINE, whatever fits — a second line would make the rows uneven and
   turn a scannable list into a wall. min-width:0 on the column is what lets ellipsis happen at all
   inside a flex row; without it the text forces the row wider instead of clipping. */
.mstack .pcard .pl{font-size:12.5px;line-height:1.25;color:var(--mut);
  white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
/* No years in the member list. They belong on a tree card, where a life span is the point;
   in a flat list of living members they are noise in front of every name. Hidden, not removed:
   person_card() still renders them for the tree. */
.mstack .pcard .py{display:none}
/* The name column takes the rest of the width so long names wrap instead of squeezing the circle. */
.mstack .pcard > :not(.av){min-width:0}
.mstack .pcard.addcard .av{font-size:18px}
.pcard{display:flex;flex-direction:column;align-items:center;text-align:center;gap:6px;
  background:transparent;border:none;border-radius:12px;padding:6px 4px;color:var(--ink)}
.pcard:hover{background:color-mix(in srgb,var(--green) 9%,transparent)}
/* NOTE the overflow:visible. The green "profile complete" ✓ badge is positioned at bottom:-2px,
   right:-2px -- deliberately hanging OUTSIDE the circle. With overflow:hidden the round avatar SLICED
   it, and what survived was a green wedge cutting across the person's face. Clip the IMAGE instead of
   the box: border-radius still rounds the background (so the initials avatar stays a circle) and the
   badge is free to sit on the rim where it belongs. Do not put overflow:hidden back. */
.pcard .av{width:62px;height:62px;border-radius:50%;display:grid;place-items:center;overflow:visible;
  font-weight:700;font-size:20px;color:#fff;background:hsl(var(--hue,150) 42% 42%);position:relative}
/* The image must be a SQUARE the size of the circle, and it must NOT depend on a percentage
   height: .av is display:grid, and iOS WebKit resolves height:100% on a grid item to auto --
   so PORTRAIT photos kept their natural aspect, grew past the 62px circle and spilled over the
   name (square photos happened to look fine, which is what hid this). aspect-ratio pins the box
   from the WIDTH alone, so object-fit:cover can do its job on any shape of photo. */
.pcard .av img{width:100%;height:100%;aspect-ratio:1/1;align-self:stretch;justify-self:stretch;
  object-fit:cover;object-position:center;border-radius:50%;display:block}
.pcard .pn{font-weight:600;font-size:13px;line-height:1.2}
.pcard .py{font-size:11px;color:var(--mut);font-variant-numeric:tabular-nums}
/* Deceased: a black ring around the circle. The photo itself shows normally
   (no grayscale) — the ring is the only signal. inset box-shadow, not a border,
   so the avatar image is neither shrunk nor clipped. */
.pcard.deceased .av{box-shadow:inset 0 0 0 3px #000, 0 0 0 1px rgba(0,0,0,.25)}
@media (prefers-color-scheme: dark){
  .pcard.deceased .av{box-shadow:inset 0 0 0 3px #000, 0 0 0 1px rgba(255,255,255,.35)}
}
.pcard.addcard{color:var(--mut)}
.pcard.addcard .av{background:transparent;color:var(--green);border:1.5px dashed var(--green);font-size:22px}

/* profile */
.phead{display:flex;gap:22px;align-items:center;flex-wrap:wrap;padding:8px 0 22px;border-bottom:1px solid var(--line)}
.bigav{width:60px;height:60px;border-radius:50%;display:grid;place-items:center;color:#fff;
  font-weight:700;font-size:22px;background:hsl(var(--hue,150) 42% 42%)}
.pmeta h1{font-size:30px;margin:0}
.maiden{color:var(--mut);font-weight:400;font-size:.7em}
.pspan{display:flex;gap:16px;flex-wrap:wrap;color:var(--mut);font-size:14px;margin:6px 0 0}
.livedot{color:var(--good)}
.pactions{display:flex;gap:8px;margin-top:12px}
.pcols{display:grid;grid-template-columns:1.3fr 1fr;gap:28px;margin-top:24px}
.fields{display:grid;grid-template-columns:auto 1fr;gap:8px 18px;margin:0 0 20px}
.fields dt{color:var(--mut);font-size:13.5px;font-weight:600}
.fields dd{margin:0;font-size:15px}
.bio{font-size:15.5px}
.prel .relgroup{margin-bottom:22px}
.prel h3{font-size:15px;color:var(--mut);text-transform:uppercase;letter-spacing:.05em;margin-bottom:10px}
.soon-inline{color:var(--mut);font-size:14px}

/* photos */
.bigav.hasimg{padding:0;overflow:hidden}
.bigav.hasimg img{width:100%;height:100%;aspect-ratio:1/1;object-fit:cover;object-position:center;display:block}
.photofield .avthumb{display:block;width:64px;height:64px;border-radius:10px;object-fit:cover;margin-bottom:6px;border:1px solid var(--line)}
.photogrid{display:grid;grid-template-columns:repeat(auto-fill,minmax(88px,1fr));gap:8px;margin:4px 0 12px}
.photoitem{display:block;aspect-ratio:1/1;border-radius:10px;overflow:hidden;border:1px solid var(--line);background:var(--paper)}
.photoitem img{width:100%;height:100%;object-fit:cover;display:block}
.photoitem:hover{border-color:var(--green)}
.photoadd{margin-top:4px}
.filebtn{cursor:pointer;display:inline-flex;align-items:center;gap:6px}
.filebtn input[type=file]{display:none}

/* family tree (nested lists with connectors) */
.treewrap{overflow-x:auto;padding:20px 6px 30px}
.familytree{min-width:max-content;margin:0 auto}
.familytree ul{display:flex;justify-content:center;gap:8px;padding:22px 0 0;margin:0;position:relative}
.familytree li{list-style:none;position:relative;padding:22px 10px 0;display:flex;flex-direction:column;align-items:center}
.familytree li::before,.familytree li::after{content:"";position:absolute;top:0;height:22px;width:50%;
  border-top:2px solid var(--line)}
.familytree li::before{inset-inline-start:0;border-inline-end:2px solid var(--line)}
.familytree li::after{inset-inline-end:0}
.familytree li:only-child::before,.familytree li:only-child::after{display:none}
.familytree li:first-child::before,.familytree li:last-child::after{border-top:0}
.familytree ul ul::before{content:"";position:absolute;top:0;inset-inline-start:50%;height:22px;border-inline-start:2px solid var(--line)}
.familytree>ul>li::before,.familytree>ul>li::after{display:none}
.couple{display:flex;align-items:flex-start;gap:6px}
.couple .amp{align-self:center;color:var(--mut);font-size:18px;padding:0 2px}
.couple .pcard{padding:8px;min-width:92px}
.couple .pcard .av{width:46px;height:46px;font-size:15px}

/* approvals */
.aplist{display:flex;flex-direction:column;gap:12px}
.aprow{display:flex;justify-content:space-between;align-items:center;gap:16px;flex-wrap:wrap;
  background:var(--card);border:1px solid var(--line);border-radius:var(--radius);padding:14px 16px}
.apwho{display:flex;gap:12px;align-items:center}
.apwho .av{width:40px;height:40px;border-radius:50%;display:grid;place-items:center;color:#fff;
  font-weight:700;background:hsl(var(--hue,150) 42% 42%);flex:0 0 auto}
.apwho b{display:block;font-size:15px}
.apwho span{display:block;font-size:12.5px;color:var(--mut)}
.apwho .apmsg{color:var(--ink);font-style:italic;margin-top:3px}
.apactions{display:flex;gap:8px}
.btn.ghost.danger{color:var(--brick);border-color:color-mix(in srgb,var(--brick) 35%,var(--line))}
.btn.ghost.danger:hover{border-color:var(--brick);color:var(--brick);filter:none}
.mainnav a[href="/approvals.php"]{color:var(--honey)}

/* contact autocomplete */
.ac-wrap{position:relative;display:block}
.ac-list{position:absolute;top:100%;inset-inline:0;z-index:30;background:var(--card);
  border:1px solid var(--line);border-radius:10px;margin-top:4px;box-shadow:var(--shadow);display:none;overflow:hidden}
.ac-item{padding:9px 12px;cursor:pointer;font-size:14px;display:flex;gap:8px;align-items:baseline}
.ac-item:hover{background:color-mix(in srgb,var(--green) 10%,transparent)}
.ac-item b{font-weight:600}
.ac-item span{color:var(--mut);font-size:12.5px}

/* invites */
.invlist{display:flex;flex-direction:column;gap:8px}
.invrow{display:flex;justify-content:space-between;align-items:center;gap:12px;
  background:var(--paper);border:1px solid var(--line);border-radius:10px;padding:10px 14px}
.invrow b{font-size:14.5px}
.linkshare{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin:10px 0 4px}
.linkshare input{flex:1 1 220px;font-size:13px;font-family:ui-monospace,monospace;background:var(--paper)}

/* soon */
.soonpage{text-align:center;padding:70px 20px}
.soonpage .ic{font-size:38px}.soonpage h1{font-size:30px;margin:14px 0 8px}
.soonpage .btn{margin-top:20px}
.empty{color:var(--mut);padding:40px 0;text-align:center}

/* footer */
.sitefoot{border-top:1px solid var(--line);margin-top:40px}
.foot-inner{max-width:1140px;margin:0 auto;padding:24px 20px;color:var(--mut);font-size:13px}
.fbrand{font-family:Georgia,serif;font-weight:800;color:var(--green-ink)}.fbrand span{color:var(--green-ink)}.fbrand .humanity{color:var(--honey)}

/* rtl */
[dir="rtl"] .navright{margin-inline-start:auto}
[dir="rtl"] body{font-family:"Segoe UI","Vazirmatn",Tahoma,system-ui,sans-serif}

@media(max-width:820px){
  .features,.cards3,.pcols{grid-template-columns:1fr}
  .mainnav{display:none}
}
@media(max-width:520px){
  .stack.grid2,.grid2{grid-template-columns:1fr}
  .phead{gap:16px}.bigav{width:76px;height:76px;font-size:26px}
}

/* Bulk-invite collapsible */
.bulkbox{border:1px solid var(--line,#e3ddd0);border-radius:12px;padding:12px 16px;margin:14px 0 4px;background:var(--paper)}
.bulkbox>summary{cursor:pointer;font-weight:600;list-style:none}
.bulkbox>summary::-webkit-details-marker{display:none}
.bulkbox[open]>summary{margin-bottom:8px}
.bulkbox textarea{width:100%;font-family:ui-monospace,monospace;font-size:13px}

/* Bulk invite: links-only results + checkbox */
label.chk{display:flex;align-items:flex-start;gap:8px;font-weight:400;cursor:pointer}
label.chk input{width:auto;margin-top:2px}
.bulkresults{margin:6px 0 14px;padding:12px 14px;border:1px solid var(--line,#e3ddd0);border-radius:12px;background:var(--card,#fff)}
.bulkresults textarea{width:100%;font-family:ui-monospace,monospace;font-size:12px;margin:8px 0}
.reslist{display:flex;flex-direction:column;gap:6px}
.resrow{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.resrow input{flex:1 1 220px;font-size:12px;font-family:ui-monospace,monospace;background:var(--paper)}

/* Invite ✉ badge on empty-avatar (accountless) people in the family tree */
.pcard{position:relative}
.pinv{position:absolute;top:-2px;right:-2px;width:22px;height:22px;border-radius:50%;
  display:grid;place-items:center;font-size:12px;line-height:1;cursor:pointer;
  background:var(--green,#3f7d5a);color:#fff;border:2px solid var(--paper,#fff);
  opacity:0;transform:scale(.6);transition:opacity .15s ease,transform .15s ease;z-index:3}
.pcard:hover .pinv,.pcard:focus-within .pinv,.pinv:focus{opacity:1;transform:scale(1)}
.pinv:hover{filter:brightness(1.1)}
@media (hover:none){.pinv{opacity:1;transform:scale(1)}}  /* touch: always visible */

/* iOS Safari auto-zooms into any input/textarea/select whose font-size is under
   16px when it gets focus, which shoves the page sideways. Keep all form fields
   at 16px on phones to prevent that zoom entirely. */
@media (max-width:760px){
  input:not([type=checkbox]):not([type=radio]), textarea, select { font-size:16px !important }
}

/* Desktop: the wordmark keeps the left of its own row and the menus sit UNDER it.
   Source order is brand, toggle, mainnav, navright — `order` moves the nav to a second
   row without touching the markup, and flex-basis:100% forces the wrap. Phones keep the
   single-row bar + bottom nav, so this is deliberately min-width only. */
@media (min-width:761px){
  .bar-inner{flex-wrap:wrap;row-gap:0;align-items:center;min-height:auto;padding-top:9px;padding-bottom:2px}
  .brand{order:1}
  .navright{order:2}
  .mainnav{order:3;flex-basis:100%;margin-inline-start:-12px;margin-top:1px}  /* -12px: undo the first link's padding so it lines up with the M */
}

/* Super Admin switch + banner */
.sa-link{color:#a9683a}
.sa-link.on{color:#2f7a52;font-weight:700}
.sabanner{background:#432612;color:#ffd9a8;text-align:center;font-size:13px;padding:6px 12px}
.sabanner a{color:#ffd9a8;text-decoration:underline;margin-inline-start:6px}

/* Landing hero tree logo (branches=descendants, roots=ancestors) */
.hero-tree{display:block;margin:0 auto 4px;width:112px;height:112px;transform-origin:50% 62%;animation:heroSprout 1s cubic-bezier(.2,.8,.2,1) both}
@keyframes heroSprout{from{transform:scale(.72);opacity:0}to{transform:scale(1);opacity:1}}
@media(prefers-reduced-motion:reduce){.hero-tree{animation:none}}
/* Duplicate-guard question on add_relative: "you already have a father — same person?" */
.dupq{font-size:20px;margin:0 0 4px}
.dupb{color:var(--mut);font-size:14px;margin:0 0 14px}
.dupcard{display:flex;align-items:center;justify-content:space-between;gap:12px;
  border:1px solid var(--line);border-radius:12px;padding:12px 14px;margin-bottom:10px}
.dupname{font-weight:700}
/* Admin-mode switch inside the avatar menu. */
.avdrop-menu .admmode{margin:0}
.avdrop-menu .admmode button{display:block;width:100%;text-align:left;background:none;border:0;
  font:inherit;color:inherit;padding:9px 12px;cursor:pointer}
.avdrop-menu .admmode button:hover{background:color-mix(in srgb,var(--green) 10%,transparent)}
/* An ancestor's work: the scan beside the transcription. */
.wkhead{margin:6px 0 14px}
.wktitle{font-size:26px;margin:0;direction:rtl}
.wkby{margin:2px 0 0;color:var(--ink)}
.wkmeta{margin:2px 0 8px;font-size:12.5px;color:var(--mut)}
.wkbar{height:6px;border-radius:999px;background:var(--line);overflow:hidden;max-width:420px}
.wkbar span{display:block;height:100%;background:var(--green)}
.wkgrid{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,420px);gap:18px;align-items:start}
@media (max-width:900px){.wkgrid{grid-template-columns:1fr}}
.wkscan{background:#111;border-radius:14px;overflow:hidden;display:flex;justify-content:center}
.wkscan img{max-width:100%;height:auto;display:block}
.wkside{position:sticky;top:12px;display:flex;flex-direction:column;gap:12px}
.wkform{display:flex;flex-direction:column;gap:8px}
.wklbl{display:flex;align-items:center;gap:8px;font-weight:700;font-size:13.5px}
.wkst{font-size:11px;text-transform:uppercase;letter-spacing:.05em;padding:2px 8px;border-radius:999px;
  background:var(--line);color:var(--mut);font-weight:700}
.wkst-drafted{background:#fdf0d5;color:#8a5a00}
.wkst-reviewed{background:#e3f4e9;color:#1f6b40}
/* The verse is Persian: right-to-left, and big enough to actually read against the scan. */
.wktext{width:100%;direction:rtl;text-align:right;font-size:17px;line-height:2;padding:12px;
  border:1px solid var(--line);border-radius:12px;background:var(--card);color:var(--ink);resize:vertical}
.wknote{font-size:12px;color:var(--mut);margin:0}
.wkbtns{display:flex;gap:8px}
.wknav{display:flex;align-items:center;gap:8px;justify-content:space-between}
.wkjump{display:flex;gap:6px}
.wkjump input{width:80px;padding:6px 8px;border:1px solid var(--line);border-radius:8px;background:var(--card);color:var(--ink)}
.btn.off{opacity:.4;pointer-events:none}
.pworks{margin:14px 0}
.pworks h3{margin:0 0 8px;font-size:15px}
.pwork{display:block;border:1px solid var(--line);border-radius:12px;padding:11px 13px;margin-bottom:8px;background:var(--card)}
.pwork:hover{border-color:color-mix(in srgb,var(--green) 45%,var(--line))}
.pwork b{display:block;font-size:17px}
.pwork span{font-size:12.5px;color:var(--mut)}
/* Circular (fan) tree: ancestors as rings. Plain SVG -- no chart library, so it renders on a weak
   phone on a bad connection, and it will still open in twenty years. */
.fanhead h1{margin:0 0 2px;font-size:22px}
.fanhead .muted{margin:0 0 10px;font-size:13px}
.fangens{display:flex;gap:6px;margin-bottom:10px}
.fangens .btn.on{background:var(--green);color:#fff;border-color:transparent}
.fanwrap{width:100%;overflow:auto;background:var(--card);border:1px solid var(--line);border-radius:16px;padding:10px}
.fan{display:block;width:100%;height:auto;max-width:900px;margin:0 auto}
.fan path{stroke:var(--card);stroke-width:1.5}
.fan .fp{fill:color-mix(in srgb,var(--green) 22%,#fff)}      /* father's line  */
.fan .fm{fill:color-mix(in srgb,#c98a3a 20%,#fff)}           /* mother's line  */
.fan .fe{fill:color-mix(in srgb,var(--line) 45%,#fff)}       /* not yet known  */
.fan a:hover path{filter:brightness(.95)}
.fan .ft{text-anchor:middle;dominant-baseline:middle;fill:var(--ink);font-weight:600}
.fan a .ft{cursor:pointer}
.fan a:hover .ft{text-decoration:underline}
.fan .fc{fill:var(--green)}
.fan .fct{text-anchor:middle;fill:#fff;font-weight:800}
.fankey{display:flex;align-items:center;gap:8px;font-size:12.5px;color:var(--mut);margin-top:10px;flex-wrap:wrap}
.fankey .k{width:13px;height:13px;border-radius:4px;display:inline-block;margin-left:8px}
.fankey .kp{background:color-mix(in srgb,var(--green) 22%,#fff);border:1px solid var(--line)}
.fankey .km{background:color-mix(in srgb,#c98a3a 20%,#fff);border:1px solid var(--line)}
.fankey .ke{background:color-mix(in srgb,var(--line) 45%,#fff);border:1px solid var(--line)}
/* "You were signed out" — a notice, not an error. Nothing went wrong; you just need to sign in. */
.formnote{background:#fdf6e3;border:1px solid #e8d9a8;color:#7a5c00;border-radius:10px;
  padding:10px 12px;font-size:13.5px;margin:0 0 12px}
/* Edit / delete on a comment. Quiet until you look for them — a family feed should not bristle
   with buttons — and the (edited) mark is never optional. */
/* Visible WITHOUT hover. A phone has no hover, so hover-only buttons are invisible buttons -- and
   35% opacity was easy to miss even on a laptop. */
.cmt-act{display:inline-flex;gap:2px;margin-left:6px;opacity:.75}
.cmt:hover .cmt-act,.cmt-act:focus-within{opacity:1}
/* Rides the post's own timestamp line, just above the post. Right-aligned so it never crowds the text.
   Kept DELIBERATELY small: this row used to be a 12px grey timestamp, and dropping 15px emoji buttons
   with padding into it made it several times taller -- a fat white band above every photo. The row must
   stay the height of the text it was, so the buttons are sized to fit the line, not the other way round. */
.slide-time{display:flex;align-items:center;gap:6px;min-height:0;line-height:1.3}
.post-act{display:inline-flex;gap:2px;margin-left:auto;opacity:.7}
.slide:hover .post-act,.post-act:focus-within{opacity:1}
.post-act button{border:0;background:none;cursor:pointer;font-size:12px;padding:0 3px;margin:0;
  border-radius:6px;line-height:1.3;height:auto}
.post-act button:hover{background:color-mix(in srgb,var(--green) 12%,transparent)}
.cmt-act button{border:0;background:none;cursor:pointer;font-size:12px;padding:0 3px;border-radius:6px;line-height:1.3}
.cmt-act button:hover{background:color-mix(in srgb,var(--green) 12%,transparent)}
.cmt-edited{font-size:11px;color:var(--mut);margin-left:5px}
/* Unread badge on the Messages nav item, and the toast when one arrives. */
.mt-badge{display:inline-flex;align-items:center;justify-content:center;min-width:18px;height:18px;
  padding:0 5px;margin-left:6px;border-radius:999px;background:#e0392b;color:#fff;
  font-size:11px;font-weight:800;line-height:1}
.mt-toast{position:fixed;left:50%;bottom:22px;transform:translate(-50%,20px);z-index:10001;
  display:flex;align-items:center;gap:7px;max-width:min(420px,92vw);
  background:#12201a;color:#fff;text-decoration:none;border-radius:14px;padding:12px 16px;
  box-shadow:0 10px 34px rgba(0,0,0,.42);opacity:0;transition:opacity .22s,transform .22s;
  font-size:14px}
.mt-toast.in{opacity:1;transform:translate(-50%,0)}
.mt-toast b{font-weight:800}
.mt-toast span{opacity:.85;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* "Which one is you?" — the face chooser. The boxes are drawn in PERCENTAGES so they stay glued to
   the faces however the photo is scaled. */
.af-h1{font-size:22px;margin:0 0 4px}
.af-sub{color:var(--mut);font-size:13.5px;margin:0 0 12px}
.af-both{margin-top:14px}
.af-wrap{position:relative;display:inline-block;max-width:100%;border-radius:14px;overflow:hidden;
  border:1px solid var(--line)}
.af-img{display:block;max-width:100%;height:auto}
.af-box{position:absolute;margin:0}
.af-box button{width:100%;height:100%;border:3px solid #fff;border-radius:10px;cursor:pointer;
  background:color-mix(in srgb,var(--green) 22%,transparent);
  box-shadow:0 0 0 2px color-mix(in srgb,var(--green) 70%,transparent),0 4px 14px rgba(0,0,0,.35);
  display:grid;place-items:center;padding:0}
.af-box button:hover{background:color-mix(in srgb,var(--green) 45%,transparent)}
.af-box span{background:#fff;color:var(--ink);font-weight:800;font-size:12px;line-height:1;
  border-radius:999px;padding:3px 7px}
.af-picks{display:flex;flex-wrap:wrap;gap:8px;margin-top:12px}

/* ---------------------------------------------------------------- the family blog
   An article is a post, so it reuses the post styles. What it adds is the QUIET of a page you
   read: a wide measure, a bigger line-height, and nothing blinking beside it. */
.composer-kind{display:inline-flex;align-items:center;gap:6px;font-size:14px;font-weight:600;
  color:var(--green,#2f6a48);cursor:pointer;padding:6px 10px;border-radius:10px}
.composer-kind:hover{background:rgba(47,106,72,.08)}
.composer-title{width:100%;box-sizing:border-box;font-size:18px;font-weight:700;padding:10px 12px;
  margin-bottom:8px;border:1px solid #d8ddd6;border-radius:10px;background:var(--card)}
.composer-title:focus{outline:2px solid var(--green,#2f6a48);outline-offset:-1px}

/* the article, as the FEED shows it: a promise, not the piece itself */
.post-article{display:block;text-decoration:none;color:inherit;border:1px solid #e2e7df;
  border-left:4px solid var(--green,#2f6a48);border-radius:12px;padding:12px 14px;margin:6px 0 10px;
  background:linear-gradient(180deg,#fbfdfa,#f4f7f1)}
.post-article:hover{background:#f0f5ec}
.pa-kind{display:block;font-size:11px;font-weight:800;letter-spacing:.06em;text-transform:uppercase;
  color:var(--green,#2f6a48);margin-bottom:4px}
.pa-title{display:block;font-size:19px;line-height:1.3;margin-bottom:6px}
.pa-excerpt{display:block;color:#4a5348;line-height:1.55;font-size:15px}
.pa-read{display:block;margin-top:8px;font-weight:700;color:var(--green,#2f6a48);font-size:14px}
.pa-read .muted{font-weight:400}

/* /blog.php — the container */
.blogwrap{max-width:760px;margin:0 auto;padding:0 12px}
.blog-head h1{margin:14px 0 4px;font-size:26px}
.blog-head .muted{margin:0 0 16px;line-height:1.5}
.blog-err{background:#fff4e5;border:1px solid #f0c98a;border-radius:10px;padding:10px 12px}
.blog-write{margin-bottom:18px;border:1px solid #e2e7df;border-radius:12px;background:#fbfdfa}
.blog-write>summary{cursor:pointer;padding:12px 14px;font-weight:700;color:var(--green,#2f6a48);
  list-style:none}
.blog-write>summary::-webkit-details-marker{display:none}
.blog-write>summary:hover{background:#f0f5ec;border-radius:12px}
.blog-write .composer{margin:0;padding:0 14px 14px;border:0;background:none}
.blog-filter{display:flex;flex-wrap:wrap;gap:8px;margin-bottom:16px}
.blog-filter .chip{font-size:13px;padding:5px 11px;border-radius:999px;border:1px solid #d8ddd6;
  background:#fff;color:#4a5348;text-decoration:none}
.blog-filter .chip.on{background:var(--green,#2f6a48);border-color:var(--green,#2f6a48);color:#fff;font-weight:700}

.bcard{display:flex;gap:14px;padding:14px 0;border-bottom:1px solid #e6eae2}
.bcard-cover{flex:0 0 140px;display:block}
.bcard-cover img{width:140px;height:100px;object-fit:cover;border-radius:10px;display:block}
.bcard-body{min-width:0;flex:1}
.bcard-body h2{margin:0 0 4px;font-size:20px;line-height:1.3}
.bcard-body h2 a{color:inherit;text-decoration:none}
.bcard-body h2 a:hover{color:var(--green,#2f6a48)}
.bcard-meta{margin:0 0 6px;font-size:13px;color:#79826f}
.bcard-meta a{color:#79826f}
.bcard-excerpt{margin:0 0 6px;color:#4a5348;line-height:1.55}
.bcard-read{font-weight:700;color:var(--green,#2f6a48);text-decoration:none;font-size:14px}

/* /article.php — the read */
.artwrap{max-width:680px;margin:0 auto;padding:0 14px 40px}
.art-back{margin:12px 0}
.art-back a{color:var(--green,#2f6a48);text-decoration:none;font-weight:600}
.art-title{font-size:32px;line-height:1.2;margin:6px 0 14px}
.art-by{display:flex;align-items:center;gap:10px;margin-bottom:20px;
  padding-bottom:14px;border-bottom:1px solid #e6eae2}
.art-by .art-meta{display:block;font-size:13px;color:#79826f}
.art-act{margin-inline-start:auto}
.art-body{font-size:18px;line-height:1.75;color:#26301f}
.art-body p{margin:0 0 1.1em}
.art-photo{display:block;width:100%;border-radius:12px;margin:18px 0}
.art-rx{display:flex;align-items:center;gap:10px;flex-wrap:wrap;margin:22px 0;
  padding-top:14px;border-top:1px solid #e6eae2}
.art-rx .tally{font-size:15px}
.art-cmts h2{font-size:18px;margin:0 0 10px}
.art-cmts .cmt{padding:8px 0;border-bottom:1px solid #f0f2ee;line-height:1.5}
.art-cmts .cmt b{margin-inline-end:6px}
.art-cmts .cmt-photo{display:block;max-width:220px;border-radius:8px;margin-top:6px}
.cmt-form{display:flex;gap:8px;margin-top:12px}
.cmt-form input[type=text]{flex:1;padding:10px 12px;border:1px solid #d8ddd6;border-radius:10px;
  font-size:16px;background:#fff}

@media (max-width:560px){
  .bcard{flex-direction:column;gap:8px}
  .bcard-cover,.bcard-cover img{flex:none;width:100%;height:170px}
  .art-title{font-size:26px}
  .art-body{font-size:17px}
}


/* The notice that stands where a composer or comment box would have been. A quieted member is told
   what they may not do and why -- never left tapping a form that silently refuses. */
.ban-note{display:flex;flex-direction:column;gap:3px;background:#fdf3f3;border:1px solid #f0d9d9;
  border-radius:12px;padding:12px 15px;margin:10px 0;color:#8a4a4a;font-size:14px}
.ban-note b{color:#7a3f3f}
.ban-note .ban-why{color:#6b5555}
.ban-note .ban-ask{font-size:12.5px;color:#9a8686}
.ban-alt{margin:0 0 12px;font-size:14px}
.ban-alt a{color:var(--green,#2f5d4a);font-weight:700;text-decoration:none}


/* ---- the help bubble: a site expert, on every page, in every language ---- */
.support-bubble{overflow:hidden;padding:0;position:fixed;inset-inline-end:16px;bottom:76px;z-index:60;width:46px;height:46px;border:0;
  border-radius:50%;background:var(--green,#2f5d4a);color:#fff;font-size:22px;font-weight:800;cursor:pointer;
  box-shadow:0 6px 18px rgba(0,0,0,.22)}
/* display:flex beats the browser's own [hidden]{display:none} — so say it here, or the
   panel can never be closed and the whole toggle is a lie. */
.support-panel[hidden]{display:none !important}
.support-panel{position:fixed;inset-inline-end:16px;bottom:130px;z-index:60;width:min(360px,calc(100vw - 32px));
  max-height:min(60vh,520px);display:flex;flex-direction:column;background:var(--card);border:1px solid rgba(0,0,0,.12);
  border-radius:16px;box-shadow:0 18px 44px rgba(0,0,0,.22);overflow:hidden}
.support-panel .sp-head{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;
  background:var(--green,#2f5d4a);color:#fff}
.support-panel .sp-head button{background:none;border:0;color:#fff;font-size:16px;cursor:pointer}
.support-panel .sp-log{flex:1;overflow-y:auto;padding:12px 14px;display:flex;flex-direction:column;gap:8px}
.support-panel .sp-hi{margin:0;font-size:13px;color:#7d8a83;line-height:1.5}
.support-panel .sp-msg{padding:9px 12px;border-radius:12px;font-size:14px;line-height:1.5;white-space:pre-wrap;
  max-width:88%;word-break:break-word}
.support-panel .sp-msg.me{align-self:flex-end;background:#e7f0ea;color:#1b2621}
.support-panel .sp-msg.bot{align-self:flex-start;background:#f3f4f2;color:#1b2621}
.support-panel .sp-ask{display:flex;gap:8px;padding:10px;border-top:1px solid rgba(0,0,0,.10)}
.support-panel .sp-ask input{flex:1;padding:10px 12px;border:1px solid rgba(0,0,0,.16);border-radius:10px;font:inherit}
.support-panel .sp-ask button{border:0;border-radius:10px;padding:10px 14px;background:var(--green,#2f5d4a);
  color:#fff;font-weight:700;cursor:pointer}
[dir="rtl"] .support-panel .sp-msg.me{align-self:flex-start}
[dir="rtl"] .support-panel .sp-msg.bot{align-self:flex-end}

.support-bubble img{width:100%;height:100%;display:block;border-radius:50%}
.support-panel .sp-head{gap:8px}
.support-panel .sp-head img{border-radius:50%;flex:none}
.support-panel .sp-head b{font-size:14px}
.support-panel .sp-head .sp-sub{font-size:11.5px;opacity:.85;margin-inline-end:auto}

/* AN EMPTY AVATAR IS STILL A PERSON. The placeholder must read as a filled disc against BOTH --paper and
   --card, or a member with no photo disappears from the page. Painted on the SPAN, because that is where
   --hue is set (it inherits down, not up -- which is why every circle used to be the same colour). */
.navav > span,
.pcard .av > span,
.bigav > span{
  width:100%;height:100%;display:grid;place-items:center;
  background:hsl(var(--hue,150) 45% 45%);color:#fff;font-weight:700;
  box-shadow:inset 0 0 0 1px rgba(0,0,0,.14);
}
.navav,.pcard .av,.bigav{background:hsl(var(--hue,150) 45% 45%)}
@media (prefers-color-scheme: dark){
  .navav > span,.pcard .av > span,.bigav > span{box-shadow:inset 0 0 0 1px rgba(255,255,255,.18)}
}

/* password show/hide -- one control, site-wide */
.pwfield{position:relative;display:block;width:100%}
.pwfield input{padding-right:44px}
.pweye{position:absolute;top:0;right:0;height:100%;width:42px;display:grid;place-items:center;background:none;border:0;cursor:pointer;font-size:18px;line-height:1;padding:0;color:var(--mut)}
.pweye:hover{color:var(--ink)}

/* ============================================================================
   THE PAGE MUST NOT PAN SIDEWAYS  (2026-07-24)
   In the Zetareh iOS app there is no address bar and no scrollbar, so a single
   element one pixel wider than the phone turns the whole page into a horizontal
   scroller: you touch it, it slides left/right, and the text walks out from
   under the sticky top bar and the fixed foot bar (which are pinned to the
   VIEWPORT and do not travel with it). Masud: "wiggles so much that it hides
   the content".
   `overflow-x:clip` and NOT `hidden`: `hidden` makes html/body a scroll
   container, which kills `position:sticky` on .topbar and the fixed .botnav.
   `clip` stops the pan and leaves both alone. (iOS 16+; on anything older the
   declaration is simply ignored — no fix, but no regression either.)
   This is a GUARD, not a cure: if a page still clips something off its right
   edge, the over-wide element itself must be found and made fluid.
   ========================================================================== */
html{overflow-x:clip}
body{overflow-x:clip;max-width:100%;overflow-wrap:break-word}
/* the usual offenders: media and embeds that carry their own intrinsic width */
img,video,canvas,iframe,embed,object,table{max-width:100%}

/* ==================================================================================================
 * ONE BRAND: zetareh.com's colours and fonts, on Zetareh People.   (Masud, 2026-07-28)
 *
 * "Zetareh.com is the main website and we should follow a consistent colour and fonts scheme for
 * every site, especially for the most important one."
 *
 * The doors were cream and forest green while the site people arrive FROM is black and teal, so
 * signing up felt like being handed to somebody else's website halfway through. This is the same
 * palette zetareh.com uses, token for token.
 *
 * WHY IT IS APPENDED RATHER THAN EDITED IN PLACE. Everything above paints from CSS variables, so
 * re-pointing them repaints the platform. Appending means the original palette is still there,
 * unmodified, and reverting is deleting this block -- not unpicking edits from 31 places.
 *
 * THE [data-theme] SELECTORS ARE NAMED EXPLICITLY. `:root[data-theme="dark"]` outranks a plain
 * `:root`, so a later rule that only said `:root` would lose to them and the old cream would come
 * back for anyone whose browser had set the attribute. Nothing in the UI sets it today, which is
 * exactly the kind of thing that is true until it isn't.
 *
 * ONE PALETTE, NOT TWO. zetareh.com has no light mode, so neither does this: all three blocks carry
 * the same values, and the OS preference no longer changes the brand. That is a real loss of choice
 * and is stated here rather than discovered -- a light variant in these blues is straightforward if
 * it is ever wanted.
 * ================================================================================================ */

:root,
:root[data-theme="light"],
:root[data-theme="dark"]{
  --paper:#05070d; --card:#0c1220; --ink:#e9f0f4; --mut:#9fb4c4;
  /* card2 IS IN THIS LIST FOR THE SECOND TIME IN THIS FILE'S LIFE. It was left out again, so it kept
     the cream #ecebe4 from the original :root while every surface around it went to night blue --
     a beige pill on the feed, and a beige country on the journey map. The note further up records
     the same omission being fixed in the [data-theme] blocks. It is not a coincidence: card2 is the
     one token nobody remembers because nothing obviously breaks, it just looks wrong somewhere else. */
  --card2:#111a2b;
  --line:rgba(126,168,190,.20); --green:#67cfe0; --green-ink:#a9ecf6; --honey:#67cfe0;
  --brick:#e0787a; --good:#5fd39a; --shadow:0 18px 48px rgba(0,0,0,.55);
}

/* The same night sky as the homepage, rather than a flat fill. */
body{
  background:
    radial-gradient(1200px 700px at 78% -8%, rgba(103,207,224,.10), transparent 60%),
    radial-gradient(900px 600px at 8% 4%,   rgba(155,138,230,.10), transparent 55%),
    linear-gradient(180deg,#05070d,#0a0f1b);
  background-attachment:fixed;
  min-height:100vh;
}

/* THE FONTS. Vazirmatn is the face zetareh.com uses and the one that carries Persian, Arabic, Pashto
   and Urdu properly; the Latin stack behind it is unchanged from the main site. Served from the same
   place zetareh.com serves it, so a visitor who has seen the homepage already has it cached. */
@font-face{font-family:Vazirmatn;font-weight:400;font-display:swap;
  src:url(https://visions.zetareh.com/fonts/vazirmatn-400.woff2) format("woff2");
  unicode-range:U+0600-06FF,U+0750-077F,U+08A0-08FF,U+200C-200D,U+FB50-FDFF,U+FE70-FEFF}
@font-face{font-family:Vazirmatn;font-weight:500 700;font-display:swap;
  src:url(https://visions.zetareh.com/fonts/vazirmatn-700.woff2) format("woff2");
  unicode-range:U+0600-06FF,U+0750-077F,U+08A0-08FF,U+200C-200D,U+FB50-FDFF,U+FE70-FEFF}

body{font-family:Vazirmatn,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}
h1,h2,h3,.brand,.authcard h1,.formcard h1{
  font-family:Vazirmatn,"Iowan Old Style","Palatino Linotype",Georgia,serif}

/* ---- the handful of rules that assumed a light page ------------------------------------------
   Variables cannot reach these: they hardcode white, which was legible on forest green and is not
   on teal, or paint a white box that would now glare out of a dark page. */
.btn{color:#05070d;background:linear-gradient(180deg,#a9ecf6,#67cfe0);border-color:transparent}
.btn:hover{filter:brightness(1.04)}
.btn.ghost{background:none;color:#a9ecf6;border-color:rgba(126,168,190,.35)}
.btn.ghost:hover{border-color:#67cfe0;color:#a9ecf6;background:rgba(103,207,224,.08)}
.langsw-go{color:#05070d}
.fangens .btn.on{color:#05070d}
.af-box span{background:#0c1220;color:var(--ink)}
.af-box textarea,.af-box input[type=text]{background:#0a0f1b;border-color:rgba(126,168,190,.28)}

/* Fields: the default input background is var(--paper), which is now the page colour -- a field you
   cannot see the edge of is a field people do not know is there. */
input,select,textarea{background:#0a0f1b;border-color:rgba(126,168,190,.28);color:var(--ink)}
input::placeholder,textarea::placeholder{color:#6f8492}

.topbar{background:rgba(5,7,13,.72);backdrop-filter:blur(12px);border-bottom-color:rgba(126,168,190,.16)}

/* .formnote hardcodes cream on parchment, so it stayed light when everything around it went dark --
   two of these were glaring out of the friend-join page. It is used on login.php and
   signin_request.php as well, so this is fixed at the class rather than page by page. */
.formnote{background:rgba(103,207,224,.07);border-color:rgba(126,168,190,.28);color:var(--dim,#a6b6c2)}


/* THE LANGUAGE SELECTOR HAD NO RULE AT ALL -- it was a raw <select>, which is why it sat in the bar
   at whatever size the platform felt like. A pill, on the left, sized to the bar rather than to the
   longest language name.
   The full "EN - English" labels are KEPT inside the list on purpose: a menu of twenty-two
   two-letter codes is smaller and worse. The pill clips to its own width, so the closed state reads
   as the code and the open state stays legible. */
.barlang{order:0;display:flex;align-items:center;margin-inline-end:2px}
.langdd{appearance:none;-webkit-appearance:none;font:inherit;font-size:12.5px;font-weight:700;
  line-height:1;color:var(--green-ink);cursor:pointer;
  background:color-mix(in srgb,var(--green) 10%,transparent);
  border:1px solid color-mix(in srgb,var(--green) 32%,transparent);border-radius:999px;
  padding:6px 25px 6px 11px;max-width:104px;text-overflow:ellipsis;white-space:nowrap;
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232f5d4a' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat:no-repeat;background-position:right 8px center;background-size:11px}
.langdd:focus-visible{outline:2px solid var(--green);outline-offset:2px}
:root[data-theme="dark"] .langdd{
  background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237ab99a' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E")}


/* Group rule inside the family menu. No text -- see the note in layout.php: a heading would need
   twenty-two translations before it could ship, and a hairline groups just as well. */
.mainnav .navsep{height:1px;background:var(--line);margin:7px 12px;opacity:.9}
@media (min-width:860px){.mainnav .navsep{width:1px;height:20px;margin:0 6px}}

/* The menu icons. currentColor means they are white on the dark theme and ink on the light one --
   high contrast in both without a second set. Slightly under the cap height so they sit on the text
   line rather than above it. */
.mainnav a .nvi{width:19px;height:19px;flex:none;margin-inline-end:10px;vertical-align:-4px;opacity:.92}
.mainnav a{display:flex;align-items:center}
.mainnav a.active .nvi{opacity:1}

/* THE RAW CHECKBOX IS GONE (Masud, 2026-08-03: "remove the check box").
   A native checkbox renders as a big white square on the dark theme -- it was the brightest thing
   in the composer and it looked broken. The input still EXISTS, because it is what carries the
   article/post state into the form; it is just no longer drawn. The label around it becomes a pill
   like Photo and Video, and lights up when it is on, so the state is still visible -- it is simply
   shown the way the neighbouring controls are. */
.composer-kind input[type=checkbox]{position:absolute;opacity:0;width:0;height:0;pointer-events:none}
.composer-kind{border:1px solid var(--line);background:transparent;transition:background .15s,border-color .15s}
.composer-kind:has(input:checked){background:var(--green);border-color:var(--green);color:#fff}
.composer-kind:focus-within{outline:2px solid var(--green);outline-offset:2px}

/* Scroll-play with no words: a round tap target rather than a wide pill with nothing in it.
   44px because that is the smallest thing a thumb reliably hits. */
/* 34px to match .cmp-ico and the Post pill. It was 44 -- the largest thing in the row, which is
   why it read as the loudest. The glyph comes down with it; an emoji at 20px inside a 34px circle
   fills the whole button and looks like a mistake. */
/* No ring here either -- see the note in home.php. The width and height remain as the tap area. */
.sp-btn.sp-solo{width:30px;height:34px;min-width:0;padding:0;border:0;background:none;border-radius:0;
  display:inline-flex;align-items:center;justify-content:center;gap:0}
.sp-btn.sp-solo:hover{background:none;filter:none;opacity:.75}
.sp-btn.sp-solo .sp-ic{font-size:17px;line-height:1}
.sp-btn.sp-solo.off{opacity:.55}

/* Two drawings, one shown. The muted note is the same note with a stroke through it, so the shape
   does not jump when it toggles -- only the slash appears. */
.sp-btn .sp-off{display:none}
.sp-btn.off .sp-on{display:none}
.sp-btn.off .sp-off{display:inline-block}
.sp-btn .sp-ic{display:inline-flex;align-items:center;justify-content:center}

/* ui_icon() outside the menu: sized to sit on a line of text next to a label, and inheriting the
   colour of whatever it is inside -- every stroke is currentColor, so a ghost button, a comment bar
   and the now-playing strip each get the icon in their own colour without a rule apiece. */
.uic{width:18px;height:18px;flex:none;vertical-align:-3px}
.cmt-cam .uic{width:19px;height:19px;vertical-align:-4px}
.np-off .uic{width:16px;height:16px;vertical-align:-3px}

/* Post/Publish as a mark rather than a filled block, on the pages that were not the tribe composer.
   .cmp-ico is declared inline in home.php, so these pages get their own copy of the shape -- one
   more argument for moving that block into this file, which is on the list. */
.btn.cmp-ico,.composer-post.cmp-ico,.ppc-post.cmp-ico{
  width:34px;height:34px;min-width:0;padding:0;border:0;background:none;border-radius:0;
  display:inline-flex;align-items:center;justify-content:center;color:var(--green,#2f6a48)}
.btn.cmp-ico:hover,.composer-post.cmp-ico:hover,.ppc-post.cmp-ico:hover{background:none;opacity:.75;filter:none}
.btn.cmp-ico .uic,.composer-post.cmp-ico .uic,.ppc-post.cmp-ico .uic{width:20px;height:20px}

/* Back to the members grid from a profile. Sits above the header block, out of the way of the
   avatar, and reads as a route rather than an action -- no button chrome. */
.pback{display:inline-flex;align-items:center;margin:2px 0 12px;font-size:14px;font-weight:600;
  color:var(--green,#2f6a48);text-decoration:none}
.pback:hover{text-decoration:underline}

/* Post and comment controls: the same outline set, sized for a line of text. currentColor means each
   one takes the colour of the row it is in -- the delete button stays red because its own rule says
   so, without needing a second red icon. */
.post-msg .uic,.cmt-msg .uic{width:17px;height:17px;vertical-align:-3px}
.pact .uic,.cmt-act .uic{width:16px;height:16px;vertical-align:-3px}
.ct-ic .uic{width:17px;height:17px;vertical-align:-3px}
.ct-dot .uic{width:9px;height:9px;vertical-align:0;color:#c0392b}
.ct-arw .uic{width:16px;height:16px;transition:transform .18s}
.cmt-toggle.open .ct-arw .uic{transform:rotate(180deg)}
.ct-ic,.ct-dot,.ct-arw{display:inline-flex;align-items:center}
.ct-dot{margin-inline-end:5px}

/* ==================================================================================================
   DIRECTION COMES FROM THE TEXT (Masud, 2026-08-04: "in Farsi the text should align to right and in
   Latin to the left, globally").

   unicode-bidi:plaintext makes each PARAGRAPH take its direction from its own first strong character,
   and text-align:start then aligns to whichever edge that direction begins at. Farsi, Arabic, Urdu
   and Pashto go right; Latin and Cyrillic go left; and a message in one language sitting in a UI set
   to the other is correct without anyone deciding.

   WHY NOT is_farsi_text(). That helper exists and is used for translation, but as a layout rule it
   only knows Farsi -- Arabic and Urdu are already in MT_LANGS and would have been missed, and every
   new RTL language after that would need remembering. This rule needs remembering once.

   WHY NOT dir="auto" ON EVERY ELEMENT. Same result, but it would have to be added to each place text
   is printed and re-added by whoever writes the next one. CSS applies to the markup that does not
   exist yet.

   ⚠ text-align:start, NOT left. On an RTL page `left` fights the direction it is meant to follow --
   which is how a "fix" for Farsi ends up breaking English on the same screen.
   ================================================================================================== */
.post-body,.art-body,.cmt-txt,.cmt,.msg,.msgtext,.bubble,.blog-body,.post-title,.art-title,
.feed-post .body,.fp-ctext,.cmt-add input,.composer textarea,
textarea,input[type=text],input[type=search]{
  unicode-bidi:plaintext;
  text-align:start;
}

/* The placeholder should sit where the typing will start, not on the far side of an empty box. */
textarea::placeholder,input::placeholder{text-align:start}

/* ══ SKINS ════════════════════════════════════════════════════════════════════════════════════════
   A group picks one of these; Zetareh writes them. There is no path that creates a skin at runtime —
   no upload, no admin form, no per-group file — so a skin is reviewed like any other code.

   ⚠ TWO INDEPENDENT AXES, AND THEY MUST NOT FIGHT:
        data-skin   which palette   (the GROUP chooses)
        data-theme  light or dark   (the PERSON chooses; absent = follow the phone)
     data-theme was already taken by the light/dark blocks above. Had the group's palette gone there,
     a tribe choosing a skin would have thrown away every member's light/dark preference.

   ⚠ EVERY SKIN DEFINES BOTH HALVES, AND THE DARK HALF TWICE — once under the media query for phones
     following the system, once under [data-theme="dark"] for people who chose it explicitly. That is
     the --card2 bug written down: a token set in one place and not the other silently reverts, which
     is how the call line became grey-on-grey. tools/test_themes.php enforces it.

   ⚠ THE TOKEN NAMES KEEP THEIR ORIGINAL HUES (--green, --honey, --brick). They are used in hundreds
     of places; renaming them to --accent across the codebase is a large change for no behavioural
     gain, and a half-finished rename would be far worse than an oddly-named variable. In a plum skin,
     --green holds plum. Read them as roles, not colours.

   ⚠ SPECIFICITY IS DELIBERATE, not incidental. :root[data-skin=..] (0,2,0) beats :root (0,1,0); the
     explicit-dark rule carries both attributes (0,3,0) so it beats :root[data-theme="dark"] (0,2,0).
     The skins therefore win regardless of where they sit in the file.

   The house palette is NOT here: no data-skin attribute means :root above. Duplicating its values
   into a "default" block would create the second copy this whole file exists to avoid.
   ════════════════════════════════════════════════════════════════════════════════════════════════ */

/* ── slate — cool and quiet, for groups that want the app to recede ──────────────────────────────*/
:root[data-skin="slate"]{
  --card2:#e8ecf0; --paper:#f2f4f6; --card:#ffffff; --ink:#16202a; --mut:#5a6b7a;
  --line:#dde3e9; --green:#2f5468; --green-ink:#23414f; --honey:#9a7b2e;
  --brick:#a04f45; --good:#3f7d7d; --shadow:0 12px 34px rgba(20,32,44,.10);
}
@media (prefers-color-scheme:dark){:root[data-skin="slate"]:not([data-theme="light"]){
  --card2:#202a33; --paper:#0d1319; --card:#161e26; --ink:#e9eef3; --mut:#9db0c0;
  --line:#26313b; --green:#79aec6; --green-ink:#bcdcea; --honey:#d8a95c;
  --brick:#d4796c; --good:#5fa9a9; --shadow:0 18px 48px rgba(0,0,0,.45);
}}
:root[data-skin="slate"][data-theme="dark"]{
  --card2:#202a33; --paper:#0d1319; --card:#161e26; --ink:#e9eef3; --mut:#9db0c0;
  --line:#26313b; --green:#79aec6; --green-ink:#bcdcea; --honey:#d8a95c;
  --brick:#d4796c; --good:#5fa9a9; --shadow:0 18px 48px rgba(0,0,0,.45);
}

/* ── plum — deep and warm, evening-leaning ───────────────────────────────────────────────────────*/
:root[data-skin="plum"]{
  --card2:#ece5ea; --paper:#f6f2f5; --card:#fffcfe; --ink:#241a22; --mut:#6b5a65;
  --line:#e6dce2; --green:#6b2f57; --green-ink:#532442; --honey:#a8762a;
  --brick:#a8453f; --good:#4b7d5a; --shadow:0 12px 34px rgba(40,26,36,.10);
}
@media (prefers-color-scheme:dark){:root[data-skin="plum"]:not([data-theme="light"]){
  --card2:#281d24; --paper:#140e12; --card:#1e161c; --ink:#f0e9ee; --mut:#b6a2ae;
  --line:#33262e; --green:#c78cb0; --green-ink:#e3c2d6; --honey:#d9a75e;
  --brick:#d8746c; --good:#6fae86; --shadow:0 18px 48px rgba(0,0,0,.45);
}}
:root[data-skin="plum"][data-theme="dark"]{
  --card2:#281d24; --paper:#140e12; --card:#1e161c; --ink:#f0e9ee; --mut:#b6a2ae;
  --line:#33262e; --green:#c78cb0; --green-ink:#e3c2d6; --honey:#d9a75e;
  --brick:#d8746c; --good:#6fae86; --shadow:0 18px 48px rgba(0,0,0,.45);
}

/* ── sand — desert neutrals with a terracotta accent ─────────────────────────────────────────────*/
:root[data-skin="sand"]{
  --card2:#efe8dc; --paper:#f7f3ec; --card:#fffdf8; --ink:#2a2119; --mut:#6f6353;
  --line:#e8dfd0; --green:#9c5638; --green-ink:#7d4229; --honey:#b8862a;
  --brick:#a4472f; --good:#6b7f4a; --shadow:0 12px 34px rgba(44,34,22,.10);
}
@media (prefers-color-scheme:dark){:root[data-skin="sand"]:not([data-theme="light"]){
  --card2:#2a231a; --paper:#14100b; --card:#1f1a14; --ink:#f2ece2; --mut:#b6a894;
  --line:#332c22; --green:#d99a76; --green-ink:#edc0a4; --honey:#dcae5c;
  --brick:#d97a5c; --good:#a3b573; --shadow:0 18px 48px rgba(0,0,0,.45);
}}
:root[data-skin="sand"][data-theme="dark"]{
  --card2:#2a231a; --paper:#14100b; --card:#1f1a14; --ink:#f2ece2; --mut:#b6a894;
  --line:#332c22; --green:#d99a76; --green-ink:#edc0a4; --honey:#dcae5c;
  --brick:#d97a5c; --good:#a3b573; --shadow:0 18px 48px rgba(0,0,0,.45);
}

/* ⚠ THE AI DISCLOSURE (AI Act Art. 50(1)). Theme tokens, not a light panel — style.css already carries
   the lesson a few lines from these tokens: a hardcoded pale background inherits the near-white --ink
   in dark mode and renders pink-on-pink, so the one line that must be read is the one nobody can. */
.ai-note{
  margin:0 0 10px; padding:7px 11px; border-radius:10px; font-size:13px; line-height:1.45;
  background:color-mix(in srgb, var(--teal,#2b6472) 10%, var(--card,#fffdf7));
  border:1px solid var(--teal,#2b6472); color:var(--ink,#1b2621);
}

/* The language filter on a shelf listing (app/shelves.php · shelf_lang_of). Theme tokens, never a
   hardcoded panel — the same reason the AI notice above uses them. */
.langfilter{display:flex;gap:7px;align-items:center;flex-wrap:wrap;margin:2px 0 12px}
.langfilter .lf{display:inline-block;padding:4px 11px;border-radius:999px;font-size:13px;
  text-decoration:none;border:1px solid var(--line,#ddd8cb);color:var(--ink,#1b2621);
  background:var(--card,#fffdf7)}
.langfilter .lf.on{border-color:var(--teal,#2b6472);font-weight:700;
  background:color-mix(in srgb, var(--teal,#2b6472) 12%, var(--card,#fffdf7))}
.langfilter .lfnote{font-size:12.5px;color:var(--mut,#6b6a5e)}
