/* ===== template themes (fonts / radius / spacing) ===== */
body[data-template="professional"] { --fd:"Rubik"; --fui:"Rubik"; --fb:"Assistant"; --radius:22px; --radius-btn:14px; --band-pad:clamp(1rem,2vw,1.75rem); }
body[data-template="corporate"]    { --fd:"Heebo"; --fui:"Heebo"; --fb:"Assistant"; --radius:6px;  --radius-btn:6px;  --band-pad:clamp(1.4rem,2.6vw,2.2rem); }
body[data-template="minimal"]      { --fd:"Heebo"; --fui:"Heebo"; --fb:"Assistant"; --radius:4px;  --radius-btn:4px;  --band-pad:clamp(1.7rem,3.2vw,2.6rem); }
body[data-template="personal"]     { --fd:"Varela Round"; --fui:"Varela Round"; --fb:"Assistant"; --radius:28px; --radius-btn:50px; --band-pad:clamp(1.3rem,2.5vw,2rem); }
body[data-template="services"]     { --fd:"Rubik"; --fui:"Rubik"; --fb:"Heebo"; --radius:12px; --radius-btn:12px; --band-pad:clamp(1.3rem,2.5vw,2rem); }
body[data-template="commerce"]     { --fd:"Heebo"; --fui:"Heebo"; --fb:"Assistant"; --radius:10px; --radius-btn:10px; --band-pad:clamp(1.3rem,2.5vw,2rem); }
body[data-template="artistic"]     { --fd:"Rubik"; --fui:"Rubik"; --fb:"Assistant"; --radius:4px; --radius-btn:4px; --band-pad:clamp(1.5rem,3vw,2.4rem); }
body[data-template="food"]         { --fd:"Suez One"; --fui:"Rubik"; --fb:"Assistant"; --radius:20px; --radius-btn:16px; --band-pad:clamp(1.2rem,2.3vw,1.9rem); }
body[data-template="noir"]         { --fd:"Varela Round"; --fui:"Varela Round"; --fb:"Assistant"; --radius:2px;  --radius-btn:2px;  --band-pad:clamp(1.6rem,3.2vw,2.6rem); }
body[data-template="aurora"]       { --fd:"Rubik"; --fui:"Rubik"; --fb:"Assistant"; --radius:22px; --radius-btn:14px; --band-pad:clamp(1.4rem,3vw,2.4rem); }
body[data-template="botanica"]     { --fd:"Heebo";            --fui:"Varela Round"; --fb:"Assistant"; --radius:32px; --radius-btn:40px; --band-pad:clamp(1.5rem,3vw,2.5rem); }
body[data-template="bauhaus"]      { --fd:"Rubik"; --fui:"Rubik"; --fb:"Heebo"; --radius:0;    --radius-btn:0;    --band-pad:clamp(1.5rem,3vw,2.4rem); }
body[data-template="prism"]        { --fd:"Rubik"; --fui:"Rubik"; --fb:"Assistant"; --radius:0;    --radius-btn:6px;  --band-pad:clamp(1.5rem,3vw,2.4rem); }
body[data-template="wave"]         { --fd:"Rubik";            --fui:"Rubik"; --fb:"Assistant"; --radius:28px; --radius-btn:40px; --band-pad:clamp(1.6rem,3.2vw,2.6rem); }
body[data-template="origami"]      { --fd:"Heebo";            --fui:"Assistant"; --fb:"Assistant"; --radius:0;    --radius-btn:2px;  --band-pad:clamp(1.5rem,3vw,2.4rem); }

/* ===== palettes (15 templates × 3) ===== */
body[data-template="professional"][data-palette="p1"]{--bg:#FFF8F2;--surface:#FFF;--ink:#2B211C;--muted:#6E5F55;--primary:#C2410C;--primary-d:#9A330A;--accent:#F2A65A;--soft:#FCEBDD;--line:#F0E3D6;--wa:#0E7A56;}
body[data-template="professional"][data-palette="p2"]{--bg:#F5FAF1;--surface:#FFF;--ink:#1F2A1B;--muted:#566150;--primary:#2F7D32;--primary-d:#256127;--accent:#9CCB5A;--soft:#E6F2DA;--line:#E2EDD7;--wa:#0E7A56;}
body[data-template="professional"][data-palette="p3"]{--bg:#F0F7FA;--surface:#FFF;--ink:#15282E;--muted:#506068;--primary:#0E6E8A;--primary-d:#0A586F;--accent:#7FC2D8;--soft:#DDEEF4;--line:#D9E9EF;--wa:#0E7A56;}

body[data-template="corporate"][data-palette="p1"]{--bg:#F4F7FB;--surface:#FFF;--ink:#152436;--muted:#4C5A6E;--primary:#1D4E89;--primary-d:#163E6E;--accent:#5B86C4;--soft:#E3EBF5;--line:#DCE5F0;--wa:#0E7A56;}
body[data-template="corporate"][data-palette="p2"]{--bg:#F5F6F7;--surface:#FFF;--ink:#1E2329;--muted:#565E66;--primary:#374550;--primary-d:#2A363F;--accent:#8A98A4;--soft:#E7EAED;--line:#E0E4E8;--wa:#0E7A56;}
body[data-template="corporate"][data-palette="p3"]{--bg:#F2F8F5;--surface:#FFF;--ink:#13261E;--muted:#4B5E55;--primary:#13674A;--primary-d:#0F5239;--accent:#5FA98A;--soft:#DEEEE7;--line:#D8E8E0;--wa:#0E7A56;}

body[data-template="minimal"][data-palette="p1"]{--bg:#FAFAF9;--surface:#FFF;--ink:#1A1A19;--muted:#5C5C58;--primary:#1A1A19;--primary-d:#000;--accent:#A8A29A;--soft:#F0EFEC;--line:#E6E5E1;--wa:#0E7A56;}
body[data-template="minimal"][data-palette="p2"]{--bg:#FAF7F1;--surface:#FFF;--ink:#23201A;--muted:#615C52;--primary:#3D362B;--primary-d:#2A251D;--accent:#B7A88E;--soft:#EFEAE0;--line:#E7E0D3;--wa:#0E7A56;}
body[data-template="minimal"][data-palette="p3"]{--bg:#F6F7F8;--surface:#FFF;--ink:#1F2226;--muted:#585D63;--primary:#2E3338;--primary-d:#1F2226;--accent:#9AA1A8;--soft:#ECEEF0;--line:#E4E6E9;--wa:#0E7A56;}

body[data-template="personal"][data-palette="p1"]{--bg:#F8F6FD;--surface:#FFF;--ink:#262036;--muted:#5E5670;--primary:#6D4CC0;--primary-d:#573B9C;--accent:#B9A6E8;--soft:#EEE8FB;--line:#E7E0F5;--wa:#0E7A56;}
body[data-template="personal"][data-palette="p2"]{--bg:#FFF6F2;--surface:#FFF;--ink:#33231D;--muted:#735C53;--primary:#C0492B;--primary-d:#9E3B22;--accent:#F6B59A;--soft:#FBE4DA;--line:#F6E2D8;--wa:#0E7A56;}
body[data-template="personal"][data-palette="p3"]{--bg:#F1FAF6;--surface:#FFF;--ink:#16271F;--muted:#4E5F57;--primary:#127E5E;--primary-d:#0E6249;--accent:#7CCBAE;--soft:#DCF1E8;--line:#D6ECE0;--wa:#0E7A56;}

body[data-template="services"][data-palette="p1"]{--bg:#FFF7F0;--surface:#FFF;--ink:#2A1E14;--muted:#6E5B49;--primary:#C24F08;--primary-d:#9C3F06;--accent:#FBB36B;--soft:#FCE7D4;--line:#F3E2CF;--wa:#0E7A56;}
body[data-template="services"][data-palette="p2"]{--bg:#F3F7FB;--surface:#FFF;--ink:#152230;--muted:#4C5A68;--primary:#15568C;--primary-d:#10446F;--accent:#5E92C4;--soft:#E2ECF5;--line:#DAE6F0;--wa:#0E7A56;}
body[data-template="services"][data-palette="p3"]{--bg:#F3FAF2;--surface:#FFF;--ink:#16271A;--muted:#4F5E50;--primary:#2B7A2E;--primary-d:#205E23;--accent:#8DC76A;--soft:#E2F1DA;--line:#DBEDD4;--wa:#0E7A56;}

body[data-template="commerce"][data-palette="p1"]{--bg:#FDF5F8;--surface:#FFF;--ink:#2E1A24;--muted:#6E5460;--primary:#B43A6B;--primary-d:#922E56;--accent:#E892B5;--soft:#F8E1EB;--line:#F1DAE3;--wa:#0E7A56;}
body[data-template="commerce"][data-palette="p2"]{--bg:#FAFAFA;--surface:#FFF;--ink:#161616;--muted:#5A5A5A;--primary:#161616;--primary-d:#000;--accent:#C9A24B;--soft:#EFEFEF;--line:#E6E6E6;--wa:#0E7A56;}
body[data-template="commerce"][data-palette="p3"]{--bg:#EFFAFA;--surface:#FFF;--ink:#10282A;--muted:#4B6062;--primary:#0C7B82;--primary-d:#095F65;--accent:#67C3C8;--soft:#D8F0F1;--line:#D2EAEB;--wa:#0E7A56;}

body[data-template="artistic"][data-palette="p1"]{--bg:#F4F1EA;--surface:#FFF;--ink:#1F1B16;--muted:#5B5247;--primary:#2C2620;--primary-d:#1A1611;--accent:#B07B3F;--soft:#ECE6DA;--line:#E3DBCC;--wa:#0E7A56;}
body[data-template="artistic"][data-palette="p2"]{--bg:#F3F3F8;--surface:#FFF;--ink:#1C1B2A;--muted:#54526A;--primary:#34306B;--primary-d:#26234F;--accent:#8B86C4;--soft:#E6E5F1;--line:#DEDDEC;--wa:#0E7A56;}
body[data-template="artistic"][data-palette="p3"]{--bg:#FBF4EF;--surface:#FFF;--ink:#2A1C15;--muted:#6E574B;--primary:#A63E26;--primary-d:#85311D;--accent:#E0926C;--soft:#F6E0D4;--line:#EFDDD0;--wa:#0E7A56;}

body[data-template="food"][data-palette="p1"]{--bg:#FFF6F2;--surface:#FFF;--ink:#2C1813;--muted:#75554B;--primary:#C53122;--primary-d:#A02619;--accent:#F2A65A;--soft:#FBE0D7;--line:#F4DDD2;--wa:#0E7A56;}
body[data-template="food"][data-palette="p2"]{--bg:#FFFAEF;--surface:#FFF;--ink:#2A2410;--muted:#6E6244;--primary:#9E6317;--primary-d:#7A4B10;--accent:#F2C44E;--soft:#FBEED0;--line:#F2E6CB;--wa:#0E7A56;}
body[data-template="food"][data-palette="p3"]{--bg:#F3F8F0;--surface:#FFF;--ink:#1B2814;--muted:#52604A;--primary:#4A7A2A;--primary-d:#395F20;--accent:#9CC766;--soft:#E4F1D8;--line:#DEEBD2;--wa:#0E7A56;}

/* noir - dark luxury (bg is dark, ink is light; btn text is dark via .btn-primary override below) */
body[data-template="noir"][data-palette="p1"]{--bg:#0B0A0B;--surface:#141215;--ink:#F5EFE4;--muted:#A69885;--primary:#D4B36A;--primary-d:#B8965A;--accent:#C9A961;--soft:#1E1A20;--line:#2A2530;--wa:#0E7A56;}
body[data-template="noir"][data-palette="p2"]{--bg:#0F0D10;--surface:#181418;--ink:#F3EDE1;--muted:#A89A84;--primary:#E5D5B7;--primary-d:#C7A87C;--accent:#C7A87C;--soft:#221E22;--line:#2E2830;--wa:#0E7A56;}
body[data-template="noir"][data-palette="p3"]{--bg:#0A0F0D;--surface:#12181A;--ink:#EFF2E9;--muted:#8FA592;--primary:#6FBA95;--primary-d:#4E9678;--accent:#4E9678;--soft:#152220;--line:#233026;--wa:#0E7A56;}

body[data-template="aurora"][data-palette="p1"]{--bg:#F5F4FF;--surface:#FFFFFF;--ink:#1A1836;--muted:#4C4870;--primary:#6B4CF5;--primary-d:#553BC9;--accent:#22D3EE;--soft:#EDEBFC;--line:#DDD8F5;--wa:#0E7A56;}
body[data-template="aurora"][data-palette="p2"]{--bg:#FFF5FB;--surface:#FFFFFF;--ink:#2A1A2E;--muted:#6B4D66;--primary:#9333EA;--primary-d:#7A22C7;--accent:#34D399;--soft:#FCE8F5;--line:#F5D8EA;--wa:#0E7A56;}
body[data-template="aurora"][data-palette="p3"]{--bg:#F0F7FF;--surface:#FFFFFF;--ink:#0F2544;--muted:#4A5C7A;--primary:#2563EB;--primary-d:#1D4ED8;--accent:#FB7185;--soft:#E0EFFC;--line:#CFE0F5;--wa:#0E7A56;}

body[data-template="botanica"][data-palette="p1"]{--bg:#F5F1EB;--surface:#FFFDF7;--ink:#1F2A20;--muted:#5F6B54;--primary:#5F7A5A;--primary-d:#4A6045;--accent:#B08867;--soft:#E8E1D2;--line:#DED5C0;--wa:#0E7A56;}
body[data-template="botanica"][data-palette="p2"]{--bg:#F7F5EE;--surface:#FFFDF6;--ink:#1F241E;--muted:#5C6252;--primary:#4A5D3A;--primary-d:#3A4A2C;--accent:#C89C6F;--soft:#EBE7D8;--line:#DFD9C4;--wa:#0E7A56;}
body[data-template="botanica"][data-palette="p3"]{--bg:#FBF7EE;--surface:#FFFDF6;--ink:#2C2618;--muted:#6E6248;--primary:#6B7735;--primary-d:#525A28;--accent:#E8A579;--soft:#F0E9D2;--line:#E5DDC0;--wa:#0E7A56;}

body[data-template="bauhaus"][data-palette="p1"]{--bg:#FCF5E8;--surface:#FFFFFF;--ink:#1A1811;--muted:#5C4E37;--primary:#B15A1A;--primary-d:#8E4614;--accent:#E8B948;--soft:#F5E6C4;--line:#EAD8A8;--wa:#0E7A56;}
body[data-template="bauhaus"][data-palette="p2"]{--bg:#EEF6F6;--surface:#FFFFFF;--ink:#0D2226;--muted:#4B6062;--primary:#0C6969;--primary-d:#084F4F;--accent:#E85A4F;--soft:#DAECEC;--line:#C4DEDE;--wa:#0E7A56;}
body[data-template="bauhaus"][data-palette="p3"]{--bg:#F5EEE1;--surface:#FFFFFF;--ink:#1F1712;--muted:#5F4F42;--primary:#6B4423;--primary-d:#523419;--accent:#D89552;--soft:#EBE0C8;--line:#DED0AC;--wa:#0E7A56;}

body[data-template="prism"][data-palette="p1"]{--bg:#FAF7FF;--surface:#FFFFFF;--ink:#1D1436;--muted:#4E4570;--primary:#6D28D9;--primary-d:#5820AC;--accent:#F59E0B;--soft:#EEE6FA;--line:#DED0F0;--wa:#0E7A56;}
body[data-template="prism"][data-palette="p2"]{--bg:#FEF5F8;--surface:#FFFFFF;--ink:#2E101F;--muted:#6C4658;--primary:#BE185D;--primary-d:#94154A;--accent:#FBBF24;--soft:#FBE1EC;--line:#F5CFDE;--wa:#0E7A56;}
body[data-template="prism"][data-palette="p3"]{--bg:#F4F6FE;--surface:#FFFFFF;--ink:#101A38;--muted:#465470;--primary:#1E40AF;--primary-d:#17328A;--accent:#14B8A6;--soft:#E0E6F9;--line:#CFD8F0;--wa:#0E7A56;}

body[data-template="wave"][data-palette="p1"]{--bg:#F0F8FB;--surface:#FFFFFF;--ink:#0B2634;--muted:#3E5B6A;--primary:#076687;--primary-d:#054F69;--accent:#F97316;--soft:#DDECF3;--line:#C8DBE5;--wa:#0E7A56;}
body[data-template="wave"][data-palette="p2"]{--bg:#FFF4F7;--surface:#FFFFFF;--ink:#2C0F1E;--muted:#6A4359;--primary:#DB2777;--primary-d:#AE1E5F;--accent:#06B6D4;--soft:#FBDCE7;--line:#F5C7D7;--wa:#0E7A56;}
body[data-template="wave"][data-palette="p3"]{--bg:#F0FAF7;--surface:#FFFFFF;--ink:#0B2A22;--muted:#3F5C52;--primary:#0F766E;--primary-d:#0B5A54;--accent:#F59E0B;--soft:#D8F0E9;--line:#C0E4D9;--wa:#0E7A56;}

body[data-template="origami"][data-palette="p1"]{--bg:#FAF6EE;--surface:#FFFFFF;--ink:#211710;--muted:#5C4A38;--primary:#92400E;--primary-d:#742F09;--accent:#F59E0B;--soft:#EFE3CE;--line:#E2D2B5;--wa:#0E7A56;}
body[data-template="origami"][data-palette="p2"]{--bg:#F6F5F2;--surface:#FFFFFF;--ink:#0F1522;--muted:#4A5162;--primary:#1F2937;--primary-d:#111827;--accent:#F59E0B;--soft:#E5E7EB;--line:#D1D5DB;--wa:#0E7A56;}
body[data-template="origami"][data-palette="p3"]{--bg:#FBF3EF;--surface:#FFFFFF;--ink:#28150C;--muted:#63463A;--primary:#7C2D12;--primary-d:#5F220E;--accent:#EAB308;--soft:#F0DCD0;--line:#E4C6B6;--wa:#0E7A56;}

/* ===== Dark variants (p4/p5/p6) - all templates. Every combination WCAG-AA
   audited via backend/scripts/audit_palettes.py. Design DNA: 7 shared "dark
   theme families" (warm charcoal, cool charcoal, deep navy, deep plum, deep
   emerald, espresso, ink steel) reused across templates - customers see
   different sites because typography + radius + layout differ per template,
   but the color story is intentionally cohesive across the dark set. Only
   noir p1-p3 are "born dark" from earlier; every other template gets 3
   additional dark palettes here on top of its existing p1-p3 light set.
   Adding/removing palettes touches ~6 sync points (see project memory):
   main.js TPL, this file, index.html, backend prompts.py enum,
   palette_match.py primaries dict, and the manual/qa_corpus copy. */
body[data-template="professional"][data-palette="p4"]{--bg:#141210;--surface:#1F1B18;--ink:#F5EFE4;--muted:#B8AA95;--primary:#D4B36A;--primary-d:#B8965A;--accent:#C9A961;--soft:#221E1A;--line:#2E2822;--wa:#0E7A56;}
body[data-template="professional"][data-palette="p5"]{--bg:#111318;--surface:#191C22;--ink:#EDF1F5;--muted:#9CA6B4;--primary:#7BA7DE;--primary-d:#5B87BE;--accent:#7BA7DE;--soft:#1E2128;--line:#2A2E36;--wa:#0E7A56;}
body[data-template="professional"][data-palette="p6"]{--bg:#150E0A;--surface:#211711;--ink:#F5EBDE;--muted:#B8A28C;--primary:#E8B29A;--primary-d:#C88E7A;--accent:#E8B29A;--soft:#231810;--line:#2E2118;--wa:#0E7A56;}
body[data-template="corporate"][data-palette="p4"]{--bg:#0B1428;--surface:#121D35;--ink:#EDF1FA;--muted:#95A5C2;--primary:#C8D0DC;--primary-d:#A8B0BC;--accent:#C8D0DC;--soft:#152140;--line:#20304F;--wa:#0E7A56;}
body[data-template="corporate"][data-palette="p5"]{--bg:#111318;--surface:#191C22;--ink:#EDF1F5;--muted:#9CA6B4;--primary:#7BA7DE;--primary-d:#5B87BE;--accent:#7BA7DE;--soft:#1E2128;--line:#2A2E36;--wa:#0E7A56;}
body[data-template="corporate"][data-palette="p6"]{--bg:#111318;--surface:#191C22;--ink:#EDF1F5;--muted:#9CA6B4;--primary:#4EBE8C;--primary-d:#3E9E72;--accent:#4EBE8C;--soft:#1E2128;--line:#2A2E36;--wa:#0E7A56;}
body[data-template="minimal"][data-palette="p4"]{--bg:#111318;--surface:#191C22;--ink:#EDF1F5;--muted:#9CA6B4;--primary:#EDF1F5;--primary-d:#D5D9DD;--accent:#9CA6B4;--soft:#1E2128;--line:#2A2E36;--wa:#0E7A56;}
body[data-template="minimal"][data-palette="p5"]{--bg:#141210;--surface:#1F1B18;--ink:#F5EFE4;--muted:#B8AA95;--primary:#D4B36A;--primary-d:#B8965A;--accent:#C9A961;--soft:#221E1A;--line:#2E2822;--wa:#0E7A56;}
body[data-template="minimal"][data-palette="p6"]{--bg:#160F1D;--surface:#221828;--ink:#F1E9F5;--muted:#B49CBC;--primary:#C8D0DC;--primary-d:#A8B0BC;--accent:#C8D0DC;--soft:#231A2C;--line:#2E2438;--wa:#0E7A56;}
body[data-template="personal"][data-palette="p4"]{--bg:#160F1D;--surface:#221828;--ink:#F1E9F5;--muted:#B49CBC;--primary:#C99AE3;--primary-d:#A578C6;--accent:#C99AE3;--soft:#231A2C;--line:#2E2438;--wa:#0E7A56;}
body[data-template="personal"][data-palette="p5"]{--bg:#141210;--surface:#1F1B18;--ink:#F5EFE4;--muted:#B8AA95;--primary:#E8B29A;--primary-d:#C88E7A;--accent:#E8B29A;--soft:#221E1A;--line:#2E2822;--wa:#0E7A56;}
body[data-template="personal"][data-palette="p6"]{--bg:#0A1613;--surface:#12211D;--ink:#EAF2ED;--muted:#93B0A2;--primary:#D4B36A;--primary-d:#B8965A;--accent:#D4B36A;--soft:#152220;--line:#213028;--wa:#0E7A56;}
body[data-template="services"][data-palette="p4"]{--bg:#141210;--surface:#1F1B18;--ink:#F5EFE4;--muted:#B8AA95;--primary:#E89468;--primary-d:#C87548;--accent:#E89468;--soft:#221E1A;--line:#2E2822;--wa:#0E7A56;}
body[data-template="services"][data-palette="p5"]{--bg:#111318;--surface:#191C22;--ink:#EDF1F5;--muted:#9CA6B4;--primary:#7BA7DE;--primary-d:#5B87BE;--accent:#7BA7DE;--soft:#1E2128;--line:#2A2E36;--wa:#0E7A56;}
body[data-template="services"][data-palette="p6"]{--bg:#150E0A;--surface:#211711;--ink:#F5EBDE;--muted:#B8A28C;--primary:#E8A648;--primary-d:#C88628;--accent:#E8A648;--soft:#231810;--line:#2E2118;--wa:#0E7A56;}
body[data-template="commerce"][data-palette="p4"]{--bg:#160F1D;--surface:#221828;--ink:#F1E9F5;--muted:#B49CBC;--primary:#E8A78F;--primary-d:#C88770;--accent:#E8A78F;--soft:#231A2C;--line:#2E2438;--wa:#0E7A56;}
body[data-template="commerce"][data-palette="p5"]{--bg:#141210;--surface:#1F1B18;--ink:#F5EFE4;--muted:#B8AA95;--primary:#D4B36A;--primary-d:#B8965A;--accent:#C9A961;--soft:#221E1A;--line:#2E2822;--wa:#0E7A56;}
body[data-template="commerce"][data-palette="p6"]{--bg:#111318;--surface:#191C22;--ink:#EDF1F5;--muted:#9CA6B4;--primary:#4EBE8C;--primary-d:#3E9E72;--accent:#4EBE8C;--soft:#1E2128;--line:#2A2E36;--wa:#0E7A56;}
body[data-template="artistic"][data-palette="p4"]{--bg:#141210;--surface:#1F1B18;--ink:#F5EFE4;--muted:#B8AA95;--primary:#E88F6E;--primary-d:#C87050;--accent:#E88F6E;--soft:#221E1A;--line:#2E2822;--wa:#0E7A56;}
body[data-template="artistic"][data-palette="p5"]{--bg:#160F1D;--surface:#221828;--ink:#F1E9F5;--muted:#B49CBC;--primary:#E8A78F;--primary-d:#C88770;--accent:#E8A78F;--soft:#231A2C;--line:#2E2438;--wa:#0E7A56;}
body[data-template="artistic"][data-palette="p6"]{--bg:#150E0A;--surface:#211711;--ink:#F5EBDE;--muted:#B8A28C;--primary:#A5C6A8;--primary-d:#85A688;--accent:#A5C6A8;--soft:#231810;--line:#2E2118;--wa:#0E7A56;}
body[data-template="food"][data-palette="p4"]{--bg:#150E0A;--surface:#211711;--ink:#F5EBDE;--muted:#B8A28C;--primary:#E8A648;--primary-d:#C88628;--accent:#E8A648;--soft:#231810;--line:#2E2118;--wa:#0E7A56;}
body[data-template="food"][data-palette="p5"]{--bg:#141210;--surface:#1F1B18;--ink:#F5EFE4;--muted:#B8AA95;--primary:#E88F6E;--primary-d:#C87050;--accent:#E88F6E;--soft:#221E1A;--line:#2E2822;--wa:#0E7A56;}
body[data-template="food"][data-palette="p6"]{--bg:#0A1613;--surface:#12211D;--ink:#EAF2ED;--muted:#93B0A2;--primary:#D4B36A;--primary-d:#B8965A;--accent:#D4B36A;--soft:#152220;--line:#213028;--wa:#0E7A56;}
body[data-template="noir"][data-palette="p4"]{--bg:#141210;--surface:#1F1B18;--ink:#F5EFE4;--muted:#B8AA95;--primary:#E8B29A;--primary-d:#C88E7A;--accent:#E8B29A;--soft:#221E1A;--line:#2E2822;--wa:#0E7A56;}
body[data-template="noir"][data-palette="p5"]{--bg:#160F1D;--surface:#221828;--ink:#F1E9F5;--muted:#B49CBC;--primary:#D0D3D8;--primary-d:#B0B3B8;--accent:#D0D3D8;--soft:#231A2C;--line:#2E2438;--wa:#0E7A56;}
body[data-template="noir"][data-palette="p6"]{--bg:#150E0A;--surface:#211711;--ink:#F5EBDE;--muted:#B8A28C;--primary:#E88F6E;--primary-d:#C87050;--accent:#E88F6E;--soft:#231810;--line:#2E2118;--wa:#0E7A56;}
body[data-template="aurora"][data-palette="p4"]{--bg:#0F141B;--surface:#181E28;--ink:#EAF0F7;--muted:#8FA0B2;--primary:#6FA8F5;--primary-d:#4F88D5;--accent:#6FA8F5;--soft:#1B222C;--line:#252E3B;--wa:#0E7A56;}
body[data-template="aurora"][data-palette="p5"]{--bg:#160F1D;--surface:#221828;--ink:#F1E9F5;--muted:#B49CBC;--primary:#C99AE3;--primary-d:#A578C6;--accent:#C99AE3;--soft:#231A2C;--line:#2E2438;--wa:#0E7A56;}
body[data-template="aurora"][data-palette="p6"]{--bg:#111318;--surface:#191C22;--ink:#EDF1F5;--muted:#9CA6B4;--primary:#4EBE8C;--primary-d:#3E9E72;--accent:#4EBE8C;--soft:#1E2128;--line:#2A2E36;--wa:#0E7A56;}
body[data-template="botanica"][data-palette="p4"]{--bg:#0A1613;--surface:#12211D;--ink:#EAF2ED;--muted:#93B0A2;--primary:#A5C6A8;--primary-d:#85A688;--accent:#A5C6A8;--soft:#152220;--line:#213028;--wa:#0E7A56;}
body[data-template="botanica"][data-palette="p5"]{--bg:#150E0A;--surface:#211711;--ink:#F5EBDE;--muted:#B8A28C;--primary:#E8956E;--primary-d:#C87550;--accent:#E8956E;--soft:#231810;--line:#2E2118;--wa:#0E7A56;}
body[data-template="botanica"][data-palette="p6"]{--bg:#141210;--surface:#1F1B18;--ink:#F5EFE4;--muted:#B8AA95;--primary:#D4B36A;--primary-d:#B8965A;--accent:#C9A961;--soft:#221E1A;--line:#2E2822;--wa:#0E7A56;}
body[data-template="bauhaus"][data-palette="p4"]{--bg:#111318;--surface:#191C22;--ink:#EDF1F5;--muted:#9CA6B4;--primary:#E8A648;--primary-d:#C88628;--accent:#E8A648;--soft:#1E2128;--line:#2A2E36;--wa:#0E7A56;}
body[data-template="bauhaus"][data-palette="p5"]{--bg:#0B1428;--surface:#121D35;--ink:#EDF1FA;--muted:#95A5C2;--primary:#C8D0DC;--primary-d:#A8B0BC;--accent:#C8D0DC;--soft:#152140;--line:#20304F;--wa:#0E7A56;}
body[data-template="bauhaus"][data-palette="p6"]{--bg:#141210;--surface:#1F1B18;--ink:#F5EFE4;--muted:#B8AA95;--primary:#E8956E;--primary-d:#C87550;--accent:#E8956E;--soft:#221E1A;--line:#2E2822;--wa:#0E7A56;}
body[data-template="prism"][data-palette="p4"]{--bg:#160F1D;--surface:#221828;--ink:#F1E9F5;--muted:#B49CBC;--primary:#C99AE3;--primary-d:#A578C6;--accent:#C99AE3;--soft:#231A2C;--line:#2E2438;--wa:#0E7A56;}
body[data-template="prism"][data-palette="p5"]{--bg:#0F141B;--surface:#181E28;--ink:#EAF0F7;--muted:#8FA0B2;--primary:#6FA8F5;--primary-d:#4F88D5;--accent:#6FA8F5;--soft:#1B222C;--line:#252E3B;--wa:#0E7A56;}
body[data-template="prism"][data-palette="p6"]{--bg:#0B1428;--surface:#121D35;--ink:#EDF1FA;--muted:#95A5C2;--primary:#E8A78F;--primary-d:#C88770;--accent:#E8A78F;--soft:#152140;--line:#20304F;--wa:#0E7A56;}
body[data-template="wave"][data-palette="p4"]{--bg:#0F141B;--surface:#181E28;--ink:#EAF0F7;--muted:#8FA0B2;--primary:#6FD0E8;--primary-d:#4FB0C8;--accent:#6FD0E8;--soft:#1B222C;--line:#252E3B;--wa:#0E7A56;}
body[data-template="wave"][data-palette="p5"]{--bg:#160F1D;--surface:#221828;--ink:#F1E9F5;--muted:#B49CBC;--primary:#E8A78F;--primary-d:#C88770;--accent:#E8A78F;--soft:#231A2C;--line:#2E2438;--wa:#0E7A56;}
body[data-template="wave"][data-palette="p6"]{--bg:#0A1613;--surface:#12211D;--ink:#EAF2ED;--muted:#93B0A2;--primary:#E8A648;--primary-d:#C88628;--accent:#E8A648;--soft:#152220;--line:#213028;--wa:#0E7A56;}
body[data-template="origami"][data-palette="p4"]{--bg:#111318;--surface:#191C22;--ink:#EDF1F5;--muted:#9CA6B4;--primary:#C8D0DC;--primary-d:#A8B0BC;--accent:#C8D0DC;--soft:#1E2128;--line:#2A2E36;--wa:#0E7A56;}
body[data-template="origami"][data-palette="p5"]{--bg:#150E0A;--surface:#211711;--ink:#F5EBDE;--muted:#B8A28C;--primary:#E8A648;--primary-d:#C88628;--accent:#E8A648;--soft:#231810;--line:#2E2118;--wa:#0E7A56;}
body[data-template="origami"][data-palette="p6"]{--bg:#160F1D;--surface:#221828;--ink:#F1E9F5;--muted:#B49CBC;--primary:#D4B36A;--primary-d:#B8965A;--accent:#C9A961;--soft:#231A2C;--line:#2E2438;--wa:#0E7A56;}

/* ===== base / structure (driven by the variables above) ===== */
* { box-sizing:border-box; }
html { scroll-behavior:smooth; -webkit-text-size-adjust:100%; }
body { margin:0; background:var(--bg); color:var(--ink); font-family:var(--fb), system-ui, sans-serif; font-size:18px; line-height:1.7; transition:background-color .4s ease, color .4s ease; overflow-x:hidden; }
h1,h2,h3 { font-family:var(--fd), serif; line-height:1.12; margin:0; font-weight:700; letter-spacing:-.01em; }
body[data-template="personal"] h1, body[data-template="personal"] h2, body[data-template="personal"] h3,
body[data-template="food"] h1, body[data-template="food"] h2, body[data-template="food"] h3 { font-weight:400; }
p { margin:0 0 1.1rem; }
a { color:var(--primary); }
img { max-width:100%; display:block; }
.sr-only { position:absolute; width:1px; height:1px; padding:0; margin:-1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0; }
:focus-visible { outline:3px solid var(--primary); outline-offset:3px; border-radius:6px; }

.wrap { max-width:1140px; margin:0 auto; padding:0 1.5rem; }
.eyebrow { font-family:var(--fui),sans-serif; font-weight:600; font-size:.9rem; letter-spacing:.03em; color:var(--primary); margin:0 0 1rem; display:inline-flex; align-items:center; gap:.5rem; }
.eyebrow::before { content:""; width:26px; height:3px; border-radius:3px; background:var(--accent); }

.btn { display:inline-flex; align-items:center; gap:.55rem; text-decoration:none; cursor:pointer; border:none; font-family:var(--fui),sans-serif; font-weight:600; font-size:1.05rem; padding:.9rem 1.7rem; border-radius:var(--radius-btn); transition:transform .18s ease, background-color .2s ease; }
.btn:hover { transform:translateY(-2px); }
/* Auto-contrast text on any button whose background is `var(--primary)`:
   extract --primary's oklch lightness (`l`) via relative-color syntax;
   if l > ~0.65 the button is too light for white text (e.g. minimal p4's
   near-white primary), so we flip to near-black. Otherwise we get white.
   Fallback `#fff` covers older browsers that don't support `oklch(from ...)`.
   Supported in Chrome 111+, Safari 16.4+, Firefox 128+ (>= mid-2024).
   The `--primary-ink` var is exposed for template-specific overrides
   (see corporate / minimal / personal / botanica `.hero-cta .btn-light`
   rules which also set bg:var(--primary)). */
/* NOTE: --primary-ink MUST be defined on body, not :root - `--primary` is
   set on body[data-template][data-palette] and custom properties don't
   propagate up the tree, so `oklch(from var(--primary) ...)` at :root
   resolves against an undefined --primary and the whole declaration
   becomes invalid (Chrome/Firefox both silently drop the color:var()
   line, falling back to color:#fff → invisible text on light primaries). */
body { --primary-ink: oklch(from var(--primary) calc(clamp(0%, (0.65 - l) * 10000%, 100%)) 0 0); }
.btn-primary { background:var(--primary); color:#fff; color:var(--primary-ink); }
.btn-primary:hover { background:var(--primary-d); }
.btn-wa { background:var(--wa); color:#fff; }
.btn-ghost { background:var(--surface); color:var(--ink); border:1px solid var(--line); }
.btn-light { background:#fff; color:var(--primary); }

.img-fill { position:relative; overflow:hidden; background:linear-gradient(135deg, var(--primary), var(--accent)); }
.img-fill img { width:100%; height:100%; object-fit:cover; position:relative; z-index:1; transition:transform .8s cubic-bezier(.2,.7,.2,1); }
.img-fill video { width:100%; height:100%; object-fit:cover; position:relative; z-index:1; display:block; background:#000; }
.img-fill .fb { position:absolute; inset:0; display:grid; place-items:center; color:#fff; font-family:var(--fd); font-weight:800; font-size:2.4rem; z-index:0; }

.skip-link { position:fixed; inset-inline-start:1rem; top:-100px; z-index:200; background:var(--primary); color:#fff; padding:.7rem 1.2rem; border-radius:12px; text-decoration:none; transition:top .2s; }
.skip-link:focus { top:1rem; }

header.site { position:sticky; top:0; z-index:60; background:color-mix(in srgb, var(--bg) 90%, transparent); backdrop-filter:blur(10px); border-bottom:1px solid var(--line); }
/* Header stretches wider than the 1140px body cap on desktop so full brand
   names + multi-word menu items ("יצירת קשר") fit on one row without
   ellipsis/wrapping. Still centered (auto margins from `.wrap`), and capped
   at 1600px so ultrawide monitors don't see the nav spread thin edge-to-edge.
   Below the 900px hamburger breakpoint this override is irrelevant — nav
   items are collapsed into the dropdown at that point anyway. */
header.site .wrap.nav-row { max-width:min(96vw, 1600px); }
.nav-row { display:flex; align-items:center; gap:.8rem; height:72px; }
/* Font-size auto-shrinks with viewport width so long brand names (e.g.
   "יניב טולדנו רואה חשבון" - 4-word firm names) don't run into the WA pill
   + hamburger on narrow phones. Desktop stays at 1.3rem via the clamp max;
   phones scale down toward the 0.75rem floor. `min-width:0` lets the brand
   actually shrink inside .nav-row; the ellipsis on .brand-name (below) is
   the final safety net if the floor still isn't small enough. */
.brand { display:inline-flex; align-items:center; gap:.6rem; font-family:var(--fui),sans-serif; font-weight:800; font-size:clamp(0.95rem, 2.9vw, 1.3rem); min-width:0; color:var(--ink); text-decoration:none; position:relative; }
/* Brand name's second span (our no-space signature: "מונג" + "שים",
   "זיו" + "להטוטן") uses `--accent`, NOT `--primary`. Reason: a full
   audit (scripts + tmp/audit_brand_contrast.py 2026-08-13) found 9
   palettes where --primary is set to nearly the same value as --ink
   (contrast < 1.3 — reads as one color), including artistic p1
   (customer feedback on site 9c831993), minimal p1/p3/p4, commerce p2,
   noir p2/p5, origami p2. --accent is designed as the pop highlight
   color and has substantially better ink-contrast on the vast majority
   of palettes; on the handful of dark-bg palettes where accent==primary
   the contrast is unchanged. */
.brand .brand-name span { color:var(--accent); }
/* Fallback for the SSR-baked structure BEFORE ensureBrandStructure() wraps
   the text into `.brand-name` — the URL-import branch renders the nav as
   `<a class="brand"><img class="brand-img"...>First<span>Last</span></a>`
   and there's a paint frame between server delivery and the JS wrap where
   the accent word would otherwise fall back to the ink color.
   Excludes `.brand-name` itself (post-JS the wrapper is a span too and we
   don't want to color the entire brand accent). */
.brand > span:not(.brand-name) { color:var(--accent); }
.brand.brand-name-off .brand-name { display:none; }
/* Keep the brand name on a single row even when tight on mobile - the
   add-logo button + hamburger toggle were squeezing the flex space and
   forcing the last-name span onto a second line. */
.brand { flex-wrap:nowrap; }
/* min-width:0 + overflow ellipsis = safety-net floor when the clamp on
   .brand font-size still can't shrink enough to fit an extreme name on a
   very narrow viewport. Normally the clamp handles it and ellipsis never
   fires. */
.brand .brand-name { white-space:nowrap; min-width:0; overflow:hidden; text-overflow:ellipsis; }
/* Always render logo before name (= right of it in RTL) regardless of DOM order. */
.brand .brand-img { order:1; }
.brand .brand-name { order:2; }

/* Logo image: shown only when .brand-logo-on is set. `flex-shrink:0` locks
   the logo at its intrinsic size so the shrink budget goes to .brand-name
   instead — otherwise a long name would compress the logo too. */
.brand .brand-img { display:none; flex-shrink:0; }
.brand.brand-logo-on .brand-img { display:block; height:60px; width:auto; max-width:360px; }
/* On mobile, if a logo image is present the brand-name text is hidden to
   avoid a cramped header. Applies to BOTH uploaded and AI-generated logos
   since screen real estate is the constraint, not the source. Logo can
   grow to 60px here too — plenty of room once the name is out of the way.
   .brand-logo-empty is set by JS when there's no <img src>, so we skip
   this rule during the empty-state. */
@media (max-width:700px) {
  .brand.brand-logo-on:not(.brand-logo-empty) .brand-name { display:none; }
  .brand.brand-logo-on:not(.brand-logo-empty) .brand-img { height:60px; max-width:calc(100vw - 6rem); }
  /* Small/square logos (rendered <=100px wide at 60px tall) leave room for
     the brand-name text next to them - keep it visible. brand-logo-narrow
     is set by refreshBrandEmptyState in main.js after the img loads. */
  .brand.brand-logo-on:not(.brand-logo-empty).brand-logo-narrow .brand-name { display:inline; }
}
.brand.brand-logo-on .brand-img:not([src]), .brand.brand-logo-on .brand-img[src=""] { display:none; }

/* Legacy pseudo-element placeholder retired - the inline .brand-logo-add
   button below is the new affordance. Empty rule so any cached older CSS
   copies stop rendering it. */
.brand.brand-logo-on.brand-logo-empty::after { content:none; }
/* Inline "add logo" pill - small text label ("הוספת לוגו") next to the
   brand name. No icon, no plus badge - just the text at the same tiny
   size as the nav-WA toggle so both edit affordances read as compact
   inline pills. Doubles as "add" when the logo slot is empty and
   "replace" when a logo is present. */
.brand .brand-logo-add {
  display:none;
  align-items:center; justify-content:center;
  /* Stretch to fill the brand row so the pill's outer box matches the brand
     name's line-box height on every viewport. `!important` guards against
     template mobile overrides that set align-items on the brand row. */
  align-self:stretch !important;
  margin-inline-start:.5rem;
  padding:0 8px;
  border:1px dashed #0284C7;
  border-radius:8px;
  background:#E0F2FE;
  color:#0284C7;
  font-family:var(--fui),sans-serif;
  font-size:.62rem;
  font-weight:700;
  line-height:1.15;
  text-align:center;
  cursor:pointer;
  order:3;
  z-index:10;
}
.brand .brand-logo-add:hover { background:color-mix(in srgb, var(--primary, #0284C7) 14%, transparent); }
.brand .brand-logo-add:focus-visible { outline:2px solid var(--primary, #0284C7); outline-offset:2px; }
/* Shown in edit mode ONLY when the brand has no logo yet — either the
   brand has never been in logo mode, or logo mode is on but the slot is
   empty. Once a logo lands, the button hides: replacement happens by
   clicking the brand image itself (opens the file picker via wireImg),
   removal happens via the small × on hover. Prior "always show, doubles
   as add/replace" behaviour was noisy for URL-import sites where a logo
   is scraped up front.
   !important beats any template-level `.brand *` rules that might display:none
   their children (some templates hide the logo slot on mobile). */
body[data-edit="true"] .brand:not(.brand-logo-on) .brand-logo-add,
body[data-edit="true"] .brand.brand-logo-empty .brand-logo-add { display:inline-flex !important; }
/* Placeholder is an upload affordance — only meaningful in edit mode. */
body:not([data-edit="true"]) .brand.brand-logo-on.brand-logo-empty::after { display:none; }
.brand.brand-logo-on.brand-logo-empty .brand-img { display:none; }
.brand.brand-logo-on.brand-logo-empty .img-edit-hint { display:none; }
.brand.brand-logo-on.brand-logo-empty.drag-over::after { background:color-mix(in srgb, var(--primary) 18%, transparent); }

/* Suppress the generic upload-overlay text on the brand (when no logo) — too small */
.brand .img-edit-hint { font-size:.7rem; padding:.2rem; }
.brand:not(.brand-logo-on) .img-edit-hint { display:none; }
/* Small × button that appears on hover of the brand when a logo is set - lets
   the customer clear the logo (mirrors the gallery-image remove pattern).
   Hidden entirely while the logo slot is empty (the "+" placeholder is the
   affordance in that case). */
.brand { position:relative; }
.brand .brand-logo-clear {
  position:absolute;
  top:-6px; inset-inline-end:-6px;
  width:20px; height:20px; padding:0; border:none;
  border-radius:50%;
  background:#d54; color:#fff;
  font-size:14px; font-weight:700; line-height:1;
  display:none; align-items:center; justify-content:center;
  cursor:pointer;
  z-index:5;
}
body[data-edit="true"] .brand.brand-logo-on:not(.brand-logo-empty):hover .brand-logo-clear { display:inline-flex; }
/* Brand-name inline slide toggle — sits BELOW the brand (absolute) so it
   doesn't push the flex row and force the name to wrap. */
.brand > .inline-toggle {
  position:absolute;
  top:calc(100% + 2px);
  inset-inline-start:0;
  margin-inline-start:0;
  opacity:.75;
  z-index:4;
}
.brand:hover > .inline-toggle,
.brand > .inline-toggle:hover { opacity:1; }
nav.primary { margin-inline-start:auto; }
.nav-links { display:flex; gap:.15rem; list-style:none; margin:0; padding:0; }
/* white-space:nowrap prevents two-word items like "יצירת קשר" from wrapping
   to a second line when the nav is tight — combined with the wider header
   .wrap max-width below, every item stays on one line on desktop. */
.nav-links a { color:var(--ink); text-decoration:none; font-family:var(--fui); font-weight:500; font-size:.98rem; padding:.5rem .7rem; border-radius:10px; white-space:nowrap; }
.nav-links a:hover { background:var(--soft); }
.nav-links a[aria-current="true"] { color:var(--primary); background:var(--soft); }

.tpl-select select,
.lang-select select { font-family:var(--fui); font-weight:600; font-size:.92rem; padding:.5rem .8rem; border:1px solid var(--line); border-radius:10px; background:var(--surface); color:var(--ink); cursor:pointer; }
.palette { display:flex; gap:.4rem; align-items:center; }
/* position:relative so the aria-pressed check badge (::after, below) can
   anchor to the dot's corner. Light-variant dots (data-idx 0-2 = p1-p3)
   keep the white border; dark-variant dots (data-idx 3-5 = p4-p6) get a
   near-black border as an at-a-glance signal that they'll apply a dark
   background. */
.palette-dot { position:relative; width:20px; height:20px; border-radius:50%; background:var(--sw); border:2px solid #fff; box-shadow:0 0 0 1px var(--line); cursor:pointer; padding:0; }
.palette-dot[data-idx="3"],
.palette-dot[data-idx="4"],
.palette-dot[data-idx="5"] { border-color:#111; }
/* Selected palette: replace the previous 2px ink ring with a small green
   check badge floating on the top-right corner. Reads as a clearer "yes,
   this one is active" than the ring, and doesn't compete with the dark-
   variant black border for visual weight. Check SVG is inlined via
   background-image so no extra network request. */
.palette-dot[aria-pressed="true"]::after {
  content:"";
  position:absolute;
  top:-8px; right:-4px;
  width:11px; height:11px;
  border-radius:50%;
  background:#16a34a center/8px 8px no-repeat url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path d='M5 10l3 3 7-7' stroke='white' stroke-width='3.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/></svg>");
  border:1.5px solid #fff;
  box-shadow:0 1px 3px rgba(0,0,0,.35);
  pointer-events:none;
}
.nav-cta { }
.menu-toggle { display:none; }

/* hero */
#hero { position:relative; color:#fff; background:#2B211C; min-height:clamp(560px,88vh,840px); display:flex; align-items:center; overflow:hidden; }
/* In edit mode the sectionBar sits directly before the stat-strip, and the
   strip's -3.5rem pull-up was overlapping the bar. Cancel the lift only in
   edit mode - view mode keeps the original overlap with the hero. */
body[data-edit="true"] .edit-bar.section-bar + .stat-strip { margin-top:0; }
.hero-media { position:absolute; inset:0; z-index:0; }
/* Overlay history: original heavy gradient dropped 2026-08-13 because
   the new bright hero images (backend/ai/image_gen.py bucket rewrite)
   turned into moody night-mode scenes under it. Reinstated 2026-08-18
   at ~80% of the previous alphas — hero images stayed too bright and
   hero copy was hard to read; this scaled-down version keeps images
   visible while giving text a legible dark band toward the bottom.
   Templates that need a heavier overlay (noir, bauhaus) still set
   their own `background:` explicitly further below. */
.hero-media::after { content:""; position:absolute; inset:0; background:linear-gradient(to top, rgba(18,12,8,.45) 0%, rgba(18,12,8,.2) 55%, rgba(18,12,8,0) 100%); }
.hero-media img { width:100%; height:100%; object-fit:cover; transform-origin:65% 35%; }
.hero-inner { position:relative; z-index:1; width:100%; padding:clamp(4rem,9vw,7rem) 1.5rem; }
.hero-tag { display:inline-flex; align-items:center; gap:.55rem; background:rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.28); backdrop-filter:blur(6px); padding:.45rem 1.15rem; border-radius:40px; font-family:var(--fui); font-weight:500; font-size:.9rem; margin-bottom:1.6rem; }
.hero-tag::before { content:""; width:7px; height:7px; border-radius:50%; background:var(--accent); }
#hero h1 { font-size:clamp(1.6rem,5.6vw,4.5rem); font-weight:800; line-height:1.1; white-space:normal; text-wrap:balance; max-width:18ch; text-shadow:0 2px 30px rgba(0,0,0,.3); }
body[data-template="personal"] #hero h1, body[data-template="food"] #hero h1 { font-weight:400; }
#hero h1 .hl { color:var(--accent); }
.hero-lead { font-size:clamp(1.1rem,2.4vw,1.4rem); max-width:56rem; margin:1.4rem 0 2.2rem; color:rgba(255,255,255,.92); }
.hero-cta { display:flex; gap:1rem; flex-wrap:wrap; }
.hero-cta > .btn { min-width:14rem; justify-content:center; }
/* Trust badges under the hero WA button. Desktop: single centered row with
   uniform spacing between the three items. Mobile (≤600): stacked 1-col
   centered. Small, semi-transparent white to sit lightly on the dark hero. */
.hero-trust {
  list-style:none; padding:0; margin:1.25rem 0 0;
  display:flex; flex-wrap:wrap; justify-content:center; align-items:center;
  gap:.4rem 2rem;
  font-size:.95rem; font-weight:500;
  color:rgba(255,255,255,.9);
}
.hero-trust li { display:inline-flex; align-items:center; gap:.35rem; white-space:nowrap; }
@media (max-width:600px) {
  .hero-trust { flex-direction:column; gap:.5rem; font-size:.9rem; }
}

.stat-strip { position:relative; z-index:2; margin-top:-3.5rem; }
/* When the hero is hidden the negative margin has nothing to float over —
   it just slides the strip up UNDER the header (whose z-index:60 doesn't
   apply while position is static in mobile edit mode), hiding the logo +
   menu row. Reset to normal spacing when the hero preceding it is off. */
#hero.is-hidden + .stat-strip { margin-top:0; }
.stat-card { background:var(--surface); border-radius:var(--radius); box-shadow:0 24px 60px -24px rgba(40,25,15,.4); border:1px solid var(--line); display:grid; grid-template-columns:repeat(3,1fr); overflow:hidden; }
.stat { padding:1.6rem 1.2rem; text-align:center; }
.stat + .stat { border-inline-start:1px solid var(--line); }
.stat b { font-family:var(--fd); font-weight:800; font-size:2.2rem; color:var(--primary); display:block; line-height:1; }
.stat span { color:var(--muted); font-size:.95rem; }

section { scroll-margin-top:84px; }
.band { padding:var(--band-pad) 0; }
.section-head { max-width:640px; margin-bottom:2.5rem; }
.section-head h2 { font-size:clamp(2rem,4.5vw,3rem); }
.section-head p { color:var(--muted); font-size:1.15rem; margin-top:.8rem; }

.about-grid { display:grid; grid-template-columns:.85fr 1fr; gap:clamp(2rem,5vw,4rem); align-items:center; }
.about-photo { aspect-ratio:4/5; border-radius:var(--radius); box-shadow:0 30px 60px -30px rgba(40,25,15,.4); }
.chips { display:flex; flex-wrap:wrap; gap:.6rem; margin-top:1.4rem; }
.chip { background:var(--soft); color:var(--primary-d); font-family:var(--fui); font-weight:600; font-size:.92rem; padding:.5rem 1rem; border-radius:30px; }

.cards { display:grid; grid-template-columns:repeat(3,1fr); gap:1.6rem; }
.card { background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; transition:transform .25s ease, box-shadow .25s ease; }
.card:hover { transform:translateY(-6px); box-shadow:0 26px 50px -28px rgba(40,25,15,.45); }
.card .card-img { aspect-ratio:16/11; }
.card-body { padding:1.5rem 1.5rem 1.7rem; }
.card h3 { font-size:1.4rem; margin-bottom:.5rem; }
.card p { color:var(--muted); font-size:1rem; margin:0; }

.pricing-grid { display:grid; grid-template-columns:repeat(auto-fit, minmax(240px, 1fr)); gap:1.6rem; align-items:stretch; }
.price-card { background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); padding:2rem 1.8rem; display:flex; flex-direction:column; transition:transform .25s ease, box-shadow .25s ease; }
.price-card:hover { transform:translateY(-6px); box-shadow:0 26px 50px -28px rgba(40,25,15,.4); }
.price-card.popular { border:1.5px solid var(--primary); box-shadow:0 26px 60px -30px rgba(40,25,15,.5); position:relative; }
.price-badge { position:absolute; top:-14px; left:50%; transform:translateX(-50%); background:var(--primary); color:#fff; font-family:var(--fui); font-weight:600; font-size:.82rem; padding:.32rem 1.1rem; border-radius:30px; white-space:nowrap; }
.price-card h3 { font-size:1.4rem; }
.price-tag { font-family:var(--fd); font-weight:800; font-size:2.4rem; color:var(--primary); line-height:1; margin:.7rem 0 .2rem; }
.price-tag small { font-size:1rem; font-weight:500; color:var(--muted); }
.price-sub { color:var(--muted); font-size:.95rem; margin-bottom:1.3rem; }
.price-feats { list-style:none; padding:0; margin:0 0 1.7rem; display:flex; flex-direction:column; gap:.65rem; }
.price-feats li { display:flex; gap:.6rem; align-items:flex-start; font-size:1rem; }
.price-feats li::before { content:"✓"; color:var(--primary); font-weight:800; flex:0 0 auto; }
.price-card .btn { margin-top:auto; justify-content:center; }

.gallery { display:grid; grid-template-columns:repeat(4,1fr); grid-auto-rows:170px; gap:1rem; grid-auto-flow:dense; }
.gallery .g { border-radius:var(--radius); }
.gallery .g.big { grid-column:span 2; grid-row:span 2; }
.gallery .g.tall { grid-column:span 1; grid-row:span 2; }
body[data-template="artistic"] .gallery { grid-auto-rows:215px; gap:1.3rem; }

#testimonials { background:var(--soft); }
.quotes { display:grid; grid-template-columns:repeat(2,1fr); gap:1.5rem; }
.quote { background:var(--surface); border-radius:var(--radius); padding:1.8rem; box-shadow:0 18px 40px -28px rgba(40,25,15,.35); }
.quote p { font-size:1.12rem; margin:0 0 1.3rem; }
.quote .who { display:flex; align-items:center; gap:.9rem; }
.quote .av { width:46px; height:46px; border-radius:50%; flex:0 0 auto; }
.quote .who b { font-family:var(--fui); display:block; font-size:1.02rem; color:var(--ink); line-height:1.25; }
.quote .who span { color:var(--muted); font-size:.9rem; }
.quote .who b + span { display:block; font-size:.82rem; line-height:1.3; }

.faq { max-width:800px; margin:0 auto; }
.faq details { border:1px solid var(--line); border-radius:var(--radius); background:var(--surface); margin-bottom:.9rem; }
.faq summary { cursor:pointer; padding:1.15rem 1.4rem; font-family:var(--fui); font-weight:600; font-size:1.08rem; list-style:none; display:flex; justify-content:space-between; align-items:center; gap:1rem; }
.faq summary::-webkit-details-marker { display:none; }
.faq summary::after { content:"+"; font-size:1.6rem; line-height:1; color:var(--primary); font-weight:400; transition:transform .2s ease; flex:0 0 auto; }
.faq details[open] summary::after { transform:rotate(45deg); }
.faq .faq-a { padding:0 1.4rem 1.25rem; color:var(--muted); }

.contact-card { background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; display:grid; grid-template-columns:.85fr 1fr; box-shadow:0 30px 70px -34px rgba(40,25,15,.4); }
.contact-map { position:relative; min-height:100%; background:var(--soft); }
.contact-map iframe { width:100%; height:100%; min-height:380px; border:0; display:block; }
/* Fallback shown only when the owner intentionally toggles the map off (edit
   "הצגת מפה" checkbox → adds .is-hidden to the iframe). Seeds with a copy of
   the hero photo so the empty map slot doesn't become a soft-gray hole, and
   is wireImg'd so it's independently replaceable (won't touch the hero above).
   VIEW-MODE behavior: we deliberately do NOT show the fallback for visitors.
   The seeded hero-copy would visually duplicate the about-section photo, and
   because .contact-map collapses to 0 height when the iframe is display:none,
   the absolute-positioned fallback would also overflow past its parent and
   overlap the contact-body below (see or-levy.co.il regression 2026-08-08).
   Instead we collapse the grid to a single column so the contact-body takes
   the full width - clean and unambiguous "no map here". Edit mode still shows
   the fallback so the owner sees the toggle checkbox + a replaceable image. */
.contact-map .contact-map-fallback {
  display:none; position:absolute; inset:0; min-height:380px;
}
body[data-edit="true"] .contact-map:has(iframe.is-hidden) .contact-map-fallback { display:block; }
.contact-map .contact-map-fallback img { width:100%; height:100%; object-fit:cover; }
body:not([data-edit="true"]) .contact-card:has(.contact-map iframe.is-hidden) { grid-template-columns:1fr; }
body:not([data-edit="true"]) .contact-card:has(.contact-map iframe.is-hidden) .contact-map { display:none; }
.contact-body { padding:clamp(1.8rem,4vw,3rem); }
.contact-body h2 { font-size:clamp(1.8rem,4vw,2.6rem); margin-bottom:.6rem; }
.address { display:inline-flex; align-items:center; gap:.6rem; font-family:var(--fui); font-weight:500; margin:1.2rem 0; color:var(--ink); }
.address::before { content:""; width:11px; height:11px; background:var(--primary); border-radius:50% 50% 50% 0; transform:rotate(45deg); flex:0 0 auto; }
.contact-actions { display:flex; gap:.8rem; flex-wrap:wrap; margin:0 0 1.4rem; }
/* tel: button in the contact-actions row runs on its own signal (see
   decorateAndSyncTelFields). Content sizes to natural width (icon + gap +
   digits), and the whole button is pushed to the far visual-left of the row
   via margin-inline-start:auto so it hugs the container edge, opposite the
   WA button on the right. padding-inline-end is trimmed so the icon isn't
   swimming in a wide margin. */
.contact-actions a[href^="tel:"] {
  margin-inline-start:auto;
  padding-inline-end:.9rem;
}
/* Email line: sits directly under the .address line, mirrors its
   typography (same font stack + weight + spacing) so the two look like a
   two-line contact block. LTR since email addresses don't get shaped by
   HE/AR script; overflow-wrap keeps long addresses from blowing out the
   contact card on narrow viewports. */
.contact-email {
  display:flex; width:fit-content; align-items:center; gap:.6rem;
  font-family:var(--fui); font-weight:500; font-size:.82rem;
  margin:-.4rem 0 1rem; color:var(--ink);
  max-width:100%; overflow-wrap:anywhere;
}
.contact-email-link { color:inherit; text-decoration:none; }
.contact-email-link:hover { text-decoration:underline; }
/* Visibility toggle: reuse wireBtnVisibilityToggle's data-viz-off /
   .is-disabled model. The .nav-wa-toggle checkbox is position:absolute by
   default (button use-case); flatten it to an inline flex item here so it
   sits next to the email text in edit mode instead of floating. */
body[data-edit="true"] .contact-email.has-viz-toggle > .nav-wa-toggle {
  position:static; transform:none; bottom:auto; left:auto;
  margin-inline-start:.4rem;
}
body:not([data-edit="true"]) .contact-email.is-disabled { display:none !important; }
body[data-edit="true"] .contact-email.is-disabled { opacity:.5; }
/* Mobile: keep WA + tel side-by-side in one row instead of wrapping.
   Each btn shrinks proportionally so both fit; padding-inline is trimmed
   to buy the horizontal room. The tel btn drops its auto-margin so the
   pair sits flush together rather than the tel getting shoved to the far
   edge (which on narrow screens forced the wrap in the first place).
   Text drops to .88rem so the tel number (11 chars + icon) doesn't force
   the pair back into a wrap on the narrowest phones — the mobile row is
   the whole reason we're sizing down here. */
@media (max-width:520px) {
  .contact-actions { flex-wrap:nowrap; gap:.6rem; }
  .contact-actions .btn {
    flex:1 1 0;
    min-width:0;
    padding-inline:.7rem;
    justify-content:center;
    font-size:.88rem;
    gap:.4rem;
    white-space:nowrap;
    overflow:hidden;
  }
  .contact-actions a[href^="tel:"] { margin-inline-start:0; padding-inline-end:.7rem; }
  .contact-actions a[href^="tel:"] .tel-icon { width:15px; height:15px; }
}
@media (max-width:380px) {
  .contact-actions .btn { font-size:.8rem; padding-inline:.5rem; }
}
.contact-actions a[href^="tel:"] .tel-text { flex:0 0 auto; }
.contact-actions a[href^="tel:"] .tel-icon {
  width:18px; height:18px; flex:0 0 auto;
  color:currentColor;
}
.field { margin-bottom:1rem; }
.field label { display:block; font-family:var(--fui); font-weight:500; font-size:.95rem; margin-bottom:.35rem; }
.field input, .field textarea { width:100%; font:inherit; padding:.8rem 1rem; border:1px solid var(--line); border-radius:12px; background:var(--bg); color:var(--ink); }
#form-status { color:var(--primary); font-weight:600; }

/* corporate */
body[data-template="corporate"] #hero { display:grid; grid-template-columns:1.05fr .95fr; min-height:clamp(520px,76vh,720px); background:var(--bg); color:var(--ink); overflow:hidden; }
body[data-template="corporate"] .hero-media { position:relative; inset:auto; order:2; }
body[data-template="corporate"] .hero-media::after { display:none; }
body[data-template="corporate"] .hero-inner { order:1; display:flex; flex-direction:column; justify-content:center; padding-block:2rem; }
body[data-template="corporate"] #hero h1 { color:var(--ink); text-shadow:none; white-space:normal; max-width:14ch; }
body[data-template="corporate"] .hero-tag { background:var(--soft); border-color:var(--line); color:var(--primary); backdrop-filter:none; }
body[data-template="corporate"] .hero-lead { color:var(--muted); }
body[data-template="corporate"] .hero-cta .btn-light { background:var(--primary); color:#fff; color:var(--primary-ink); }
body[data-template="corporate"] .card { border-top:3px solid var(--primary); }
body[data-template="corporate"] .gallery .g.big { grid-column:span 1; grid-row:span 1; }
body[data-template="corporate"] .about-photo { order:2; }

/* minimal */
body[data-template="minimal"] #hero { display:block; min-height:auto; background:var(--bg); color:var(--ink); }
body[data-template="minimal"] .hero-media { display:none; }
body[data-template="minimal"] .hero-inner { padding:clamp(5rem,13vw,9rem) 0 clamp(2.5rem,6vw,4rem); }
body[data-template="minimal"] #hero h1 { color:var(--ink); text-shadow:none; white-space:normal; max-width:15ch; }
body[data-template="minimal"] .hero-tag { background:transparent; border-color:var(--line); color:var(--muted); backdrop-filter:none; }
body[data-template="minimal"] .hero-lead { color:var(--muted); }
body[data-template="minimal"] .hero-cta .btn-light { background:var(--primary); color:#fff; color:var(--primary-ink); }
body[data-template="minimal"] .stat-strip { margin-top:0; }
body[data-template="minimal"] .stat-card, body[data-template="minimal"] .card, body[data-template="minimal"] .price-card, body[data-template="minimal"] .quote, body[data-template="minimal"] .contact-card { box-shadow:none; }
body[data-template="minimal"] .cards { display:block; }
body[data-template="minimal"] .card { display:block; border:none; border-top:1px solid var(--line); border-radius:0; background:transparent; padding:1.6rem 0; }
body[data-template="minimal"] .card:last-child { border-bottom:1px solid var(--line); }
body[data-template="minimal"] .card:hover { transform:none; }
body[data-template="minimal"] .card .card-img { display:none; }
body[data-template="minimal"] .card-body { padding:0; }
body[data-template="minimal"] .gallery { grid-template-columns:repeat(3,1fr); }
body[data-template="minimal"] .gallery .g.big { grid-column:span 1; grid-row:span 1; }
body[data-template="minimal"] .about-grid { grid-template-columns:1fr; max-width:720px; }
body[data-template="minimal"] .about-photo { display:none; }

/* personal */
body[data-template="personal"] #hero { display:grid; grid-template-columns:1.05fr .95fr; min-height:clamp(520px,76vh,720px); background:var(--bg); color:var(--ink); overflow:hidden; }
body[data-template="personal"] .hero-media { position:relative; inset:auto; order:1; border-radius:0 0 90px 0; overflow:hidden; }
body[data-template="personal"] .hero-media::after { display:none; }
body[data-template="personal"] .hero-inner { order:2; display:flex; flex-direction:column; justify-content:center; padding-block:2rem; }
body[data-template="personal"] #hero h1 { color:var(--ink); text-shadow:none; white-space:normal; max-width:13ch; }
body[data-template="personal"] .hero-tag { background:var(--soft); border-color:var(--line); color:var(--primary); backdrop-filter:none; }
body[data-template="personal"] .hero-lead { color:var(--muted); }
body[data-template="personal"] .hero-cta .btn-light { background:var(--primary); color:#fff; color:var(--primary-ink); }
body[data-template="personal"] .cards { grid-template-columns:repeat(2,1fr); }
body[data-template="personal"] .about-photo { order:2; }

body[data-template="corporate"] #hero, body[data-template="personal"] #hero { column-gap:clamp(1.5rem,4vw,3.5rem); }
body[data-template="corporate"] .hero-inner, body[data-template="personal"] .hero-inner { max-width:none; margin:0; align-items:flex-start; padding:2rem clamp(1.75rem,4.5vw,4.5rem); }
/* Split-hero templates use only 2rem hero-inner padding-block, which is
   less than the base .stat-strip { margin-top:-3.5rem } lift - the strip
   ends up overlapping the hero CTA buttons. Neutralize the float-over
   for these (same as `minimal` at line 604). */
body[data-template="corporate"] .stat-strip,
body[data-template="personal"] .stat-strip { margin-top:0; }

/* services */
body[data-template="services"] .hero-cta .btn { font-size:1.15rem; padding:1rem 2rem; font-weight:700; }
body[data-template="services"] .cards { display:block; }
body[data-template="services"] .card { display:flex; align-items:center; gap:1.2rem; border:none; border-bottom:1px solid var(--line); border-radius:0; background:transparent; box-shadow:none; padding:1.5rem 0; }
body[data-template="services"] .card:hover { transform:none; box-shadow:none; padding-inline-start:.7rem; }
body[data-template="services"] .card .card-img { display:none; }
body[data-template="services"] .card-body { padding:0; flex:1; }
body[data-template="services"] .card::after { content:"\2190"; color:var(--primary); font-size:1.5rem; flex:0 0 auto; }
body[data-template="services"] .gallery .g.big { grid-column:span 1; grid-row:span 1; }

/* commerce */
body[data-template="commerce"] .cards { grid-template-columns:repeat(4,1fr); gap:1rem; }
body[data-template="commerce"] .card-img { aspect-ratio:1/1; }
body[data-template="commerce"] .card-body { padding:1rem; }
body[data-template="commerce"] .card h3 { font-size:1.1rem; }
body[data-template="commerce"] .card p { font-size:.9rem; }
body[data-template="commerce"] .gallery .g.big { grid-column:span 1; grid-row:span 1; }

/* artistic */
body[data-template="artistic"] #hero { min-height:100vh; }
body[data-template="artistic"] .hero-lead { display:none; }
body[data-template="artistic"] #hero h1 { white-space:normal; max-width:14ch; font-size:clamp(2.2rem,8vw,6rem); letter-spacing:0; }
body[data-template="artistic"] .section-head h2 { letter-spacing:0; }
body[data-template="artistic"] .cards { display:block; }
body[data-template="artistic"] .card { display:block; border:none; border-top:1px solid var(--line); border-radius:0; background:transparent; box-shadow:none; padding:1.6rem 0; }
body[data-template="artistic"] .card:hover { transform:none; box-shadow:none; }
body[data-template="artistic"] .card .card-img { display:none; }
body[data-template="artistic"] .card-body { padding:0; }
body[data-template="artistic"] .gallery { grid-auto-rows:260px; gap:1.4rem; }
body[data-template="artistic"] .about-photo { order:2; }

/* food */
body[data-template="food"] .about-grid { grid-template-columns:1fr; }
body[data-template="food"] .about-photo { aspect-ratio:21/9; }
body[data-template="food"] .gallery { grid-auto-rows:200px; }
body[data-template="food"] .pricing-grid { grid-template-columns:1fr; max-width:760px; margin:0 auto; gap:0; background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); padding:clamp(.6rem,2.5vw,1.4rem) clamp(1.25rem,4vw,2.6rem); }
body[data-template="food"] .price-card { flex-direction:row; align-items:baseline; flex-wrap:wrap; border:none; border-bottom:1px dashed var(--line); border-radius:0; box-shadow:none; padding:1.3rem 0; }
body[data-template="food"] .price-card:hover, body[data-template="food"] .price-card.popular { transform:none; box-shadow:none; border:none; border-bottom:1px dashed var(--line); }
body[data-template="food"] .price-card:last-child { border-bottom:none; }
body[data-template="food"] .price-card h3 { font-size:1.35rem; flex:1; }
body[data-template="food"] .price-tag { margin:0; font-size:1.6rem; }
body[data-template="food"] .price-sub { flex-basis:100%; margin:.3rem 0 0; }
body[data-template="food"] .price-feats { flex-basis:100%; margin:.7rem 0 0; }
body[data-template="food"] .price-badge { position:static; transform:none; margin-inline-start:.6rem; }
body[data-template="food"] .price-card .btn { display:none; }

/* ===== noir - dark luxury with gold accents (bg is dark, so many defaults need re-tuning) ===== */
body[data-template="noir"] header.site { background:color-mix(in srgb, var(--bg) 85%, transparent); border-bottom:1px solid var(--line); }
body[data-template="noir"] .nav-links a[aria-current="true"] { color:var(--primary); background:var(--soft); }
body[data-template="noir"] .tpl-select select { background:var(--soft); }
body[data-template="noir"] .palette-dot { border-color:var(--surface); box-shadow:0 0 0 1px var(--primary); }
/* Dark-variant dots keep their black border even inside noir (where surface
   is dark) so the "this is a dark palette" signal doesn't disappear. */
body[data-template="noir"] .palette-dot[data-idx="3"],
body[data-template="noir"] .palette-dot[data-idx="4"],
body[data-template="noir"] .palette-dot[data-idx="5"] { border-color:#111; }
/* aria-pressed on noir: no longer thicken the outer ring — the check badge
   above is the selection indicator. Keep the 1px primary halo from base rule
   so unselected dots stay visible against noir's dark surface. */
body[data-template="noir"] #hero { min-height:clamp(600px,92vh,880px); background:radial-gradient(120% 80% at 50% 20%, color-mix(in srgb, var(--primary) 14%, var(--bg)), var(--bg) 65%); }
body[data-template="noir"] .hero-media::after { background:linear-gradient(to top, rgba(0,0,0,.9) 5%, rgba(0,0,0,.5) 55%, rgba(0,0,0,.8) 100%), radial-gradient(80% 60% at 50% 50%, color-mix(in srgb, var(--primary) 18%, transparent), transparent 70%); }
body[data-template="noir"] #hero h1 { font-family:var(--fd); font-weight:400; letter-spacing:-.02em; font-size:clamp(2rem,6vw,5rem); text-shadow:0 4px 40px rgba(0,0,0,.6); }
body[data-template="noir"] #hero h1 .hl { color:var(--primary); font-style:normal; }
body[data-template="noir"] .hero-tag { background:color-mix(in srgb, var(--primary) 14%, transparent); border-color:color-mix(in srgb, var(--primary) 45%, transparent); color:var(--primary); }
body[data-template="noir"] .btn-primary { color:var(--bg); }
body[data-template="noir"] .btn-light { background:var(--primary); color:var(--bg); }
body[data-template="noir"] .btn-ghost { border-color:var(--primary); }
body[data-template="noir"] .section-head { position:relative; padding-top:1.4rem; }
body[data-template="noir"] .section-head::before { content:""; display:block; width:60px; height:1px; background:var(--primary); margin-bottom:1.4rem; }
body[data-template="noir"] .section-head h2 { font-weight:400; letter-spacing:-.01em; }
body[data-template="noir"] .eyebrow { color:var(--primary); font-family:var(--fui); letter-spacing:.18em; text-transform:uppercase; font-size:.78rem; }
body[data-template="noir"] .eyebrow::before { background:var(--primary); }
body[data-template="noir"] .stat-card, body[data-template="noir"] .card, body[data-template="noir"] .price-card, body[data-template="noir"] .quote, body[data-template="noir"] .contact-card { background:color-mix(in srgb, var(--surface) 88%, transparent); backdrop-filter:blur(10px); border:1px solid var(--line); box-shadow:0 30px 60px -30px rgba(0,0,0,.8); }
body[data-template="noir"] .card:hover, body[data-template="noir"] .price-card:hover { border-color:var(--primary); box-shadow:0 30px 60px -28px rgba(0,0,0,.8), 0 0 0 1px color-mix(in srgb, var(--primary) 30%, transparent); }
body[data-template="noir"] .stat b, body[data-template="noir"] .price-tag { color:var(--primary); }
body[data-template="noir"] .price-card.popular { border-color:var(--primary); box-shadow:0 30px 70px -30px rgba(0,0,0,.9), 0 0 0 1px var(--primary); }
body[data-template="noir"] .chip { background:var(--soft); color:var(--primary); border:1px solid var(--line); }
body[data-template="noir"] #testimonials { background:var(--soft); }
body[data-template="noir"] .faq details { background:var(--surface); }
body[data-template="noir"] .contact-map { background:var(--soft); }
body[data-template="noir"] .address::before { background:var(--primary); }
body[data-template="noir"] footer.site { background:var(--surface); color:color-mix(in srgb, var(--ink) 78%, transparent); border-top:1px solid var(--line); }
body[data-template="noir"] footer.site a { color:var(--ink); }

/* ===== aurora - gradient tech / glassmorphism ===== */
/* Hero shows the actual image with the default dark vignette (inherited from
   base .hero-media::after) for text legibility. The gradient/orbs vibe lives
   in section backgrounds, cards, buttons and headings instead. */
body[data-template="aurora"] #hero { min-height:clamp(560px,86vh,820px); }
body[data-template="aurora"] #hero h1 .hl { color:var(--accent); }
body[data-template="aurora"] .hero-tag { background:rgba(255,255,255,.16); border-color:rgba(255,255,255,.35); }
body[data-template="aurora"] .stat-card { background:color-mix(in srgb, var(--surface) 60%, transparent); backdrop-filter:blur(18px); border:1px solid color-mix(in srgb, var(--primary) 20%, var(--line)); box-shadow:0 24px 60px -24px color-mix(in srgb, var(--primary) 40%, rgba(0,0,0,.2)); }
body[data-template="aurora"] .stat b { background:linear-gradient(90deg, var(--primary), var(--accent)); -webkit-background-clip:text; background-clip:text; color:transparent; }
/* `width:fit-content` on a block-level h2 shrink-wraps the box to the text
   so the gradient background-clip spans just the text width (not the full
   container — otherwise short titles show only the accent end of the
   gradient). `display:block` (rather than the earlier `inline-block`)
   forces it onto its own line so the inline-flex .eyebrow above doesn't
   drag the h2 up onto the same row. */
body[data-template="aurora"] .section-head h2 { display:block; width:fit-content; max-width:100%; background:linear-gradient(90deg, var(--primary), var(--accent)); -webkit-background-clip:text; background-clip:text; color:transparent; }
body[data-template="aurora"] .card, body[data-template="aurora"] .price-card, body[data-template="aurora"] .quote, body[data-template="aurora"] .contact-card { background:color-mix(in srgb, var(--surface) 70%, transparent); backdrop-filter:blur(16px); border:1px solid color-mix(in srgb, var(--primary) 15%, var(--line)); }
body[data-template="aurora"] .card:hover { border-color:color-mix(in srgb, var(--primary) 40%, var(--line)); box-shadow:0 26px 60px -28px color-mix(in srgb, var(--primary) 45%, rgba(0,0,0,.25)); }
body[data-template="aurora"] .price-card:hover { transform:perspective(1000px) translateY(-6px) rotateX(3deg); }
body[data-template="aurora"] .price-card.popular { background:linear-gradient(160deg, color-mix(in srgb, var(--primary) 12%, var(--surface)), var(--surface)); border-color:var(--primary); }
body[data-template="aurora"] .price-tag { background:linear-gradient(90deg, var(--primary), var(--accent)); -webkit-background-clip:text; background-clip:text; color:transparent; }
body[data-template="aurora"] .chip { background:linear-gradient(135deg, color-mix(in srgb, var(--primary) 12%, transparent), color-mix(in srgb, var(--accent) 12%, transparent)); border:1px solid color-mix(in srgb, var(--primary) 25%, transparent); }
body[data-template="aurora"] #testimonials { background:linear-gradient(180deg, var(--bg), color-mix(in srgb, var(--primary) 6%, var(--bg))); }
body[data-template="aurora"] .faq details { background:color-mix(in srgb, var(--surface) 70%, transparent); backdrop-filter:blur(12px); }
body[data-template="aurora"] .btn-primary { background:linear-gradient(135deg, var(--primary), color-mix(in srgb, var(--primary) 60%, var(--accent))); box-shadow:0 12px 30px -12px color-mix(in srgb, var(--primary) 60%, transparent); }

/* ===== botanica - organic wellness (blob shapes, curved section transitions, extra-round radii) ===== */
body[data-template="botanica"] #hero { min-height:clamp(560px,84vh,780px); background:var(--bg); color:var(--ink); display:grid; grid-template-columns:1fr .9fr; align-items:center; overflow:hidden; }
body[data-template="botanica"] .hero-media { position:relative; inset:auto; order:2; border-radius:60% 40% 55% 45% / 50% 60% 40% 50%; margin:2rem clamp(1rem,3vw,2.5rem); overflow:hidden; box-shadow:0 40px 80px -30px color-mix(in srgb, var(--primary) 45%, rgba(0,0,0,.2)); }
body[data-template="botanica"] .hero-media::after { display:none; }
body[data-template="botanica"] .hero-inner { order:1; display:flex; flex-direction:column; justify-content:center; padding-block:2rem; padding-inline:clamp(1.75rem,4.5vw,4.5rem); max-width:none; margin:0; align-items:flex-start; }
body[data-template="botanica"] .stat-strip { margin-top:0; }
body[data-template="botanica"] #hero h1 { color:var(--ink); text-shadow:none; max-width:14ch; font-weight:400; font-size:clamp(2.2rem,5.6vw,4.4rem); letter-spacing:-.02em; }
body[data-template="botanica"] #hero h1 .hl { color:var(--accent); font-style:italic; }
body[data-template="botanica"] .hero-tag { background:var(--soft); border-color:transparent; color:var(--primary); backdrop-filter:none; border-radius:40px; }
body[data-template="botanica"] .hero-lead { color:var(--muted); }
body[data-template="botanica"] .hero-cta .btn-light { background:var(--primary); color:#fff; color:var(--primary-ink); }
body[data-template="botanica"] .section-head h2 { font-weight:400; }
body[data-template="botanica"] .about-photo { border-radius:40% 60% 30% 70% / 50% 40% 60% 50%; box-shadow:0 40px 70px -30px color-mix(in srgb, var(--primary) 40%, rgba(0,0,0,.2)); }
body[data-template="botanica"] .card { border-radius:32px 48px 32px 48px; }
body[data-template="botanica"] .card:nth-child(even) { border-radius:48px 32px 48px 32px; }
body[data-template="botanica"] .card .card-img { border-radius:0; }
body[data-template="botanica"] .price-card { border-radius:36px; }
body[data-template="botanica"] .price-card.popular { border-radius:36px 60px 36px 60px; }
/* botanica testimonials: the ::before pseudo creates a page-bg "wave dip"
   into the top of the soft-colored testimonials band. It must sit flush
   against the section's top edge - the default .band top padding used to
   push it down, leaving a visible page-bg gap between the previous section
   (gallery/services) and the curved decoration. `padding-top:0` removes
   that gap; the ::before's own height provides the visual top spacing. */
body[data-template="botanica"] #testimonials { background:var(--soft); border-radius:0 0 clamp(3rem,10vw,7rem) clamp(3rem,10vw,7rem); margin-bottom:clamp(0.5rem,1vw,1.25rem); padding-top:0; }
body[data-template="botanica"] #testimonials::before { content:""; display:block; height:clamp(3rem,10vw,7rem); background:var(--bg); border-radius:0 0 clamp(3rem,10vw,7rem) clamp(3rem,10vw,7rem); margin-bottom:-1px; }
body[data-template="botanica"] .quote { border-radius:32px 48px 32px 48px; }
body[data-template="botanica"] .quote:nth-child(even) { border-radius:48px 32px 48px 32px; }
body[data-template="botanica"] .quote .av { border-radius:40% 60% 40% 60%; }
body[data-template="botanica"] .faq details { border-radius:24px; }
body[data-template="botanica"] .gallery .g { border-radius:32px; }
body[data-template="botanica"] .gallery .g:nth-child(2n) { border-radius:32px 48px 32px 48px; }
body[data-template="botanica"] .gallery .g:nth-child(3n) { border-radius:48px 32px 48px 32px; }
body[data-template="botanica"] .contact-card { border-radius:36px; }
body[data-template="botanica"] .chip { border-radius:40px; padding:.55rem 1.2rem; }

/* ===== bauhaus - retro poster (hard offset shadows, uppercase bold, geometric decorations) ===== */
body[data-template="bauhaus"] #hero { background:var(--bg); color:var(--ink); min-height:clamp(560px,82vh,760px); }
body[data-template="bauhaus"] .hero-media::after { background:linear-gradient(to top, var(--bg) 0%, color-mix(in srgb, var(--bg) 70%, transparent) 40%, transparent 100%); }
body[data-template="bauhaus"] #hero::before { content:""; position:absolute; width:36vw; height:36vw; max-width:420px; max-height:420px; top:12%; left:6%; background:var(--accent); border-radius:50%; z-index:0; }
body[data-template="bauhaus"] #hero::after { content:""; position:absolute; width:0; height:0; bottom:15%; right:8%; border-left:110px solid transparent; border-right:110px solid transparent; border-bottom:180px solid var(--primary); z-index:0; opacity:.9; }
body[data-template="bauhaus"] #hero h1 { color:var(--ink); text-shadow:none; text-transform:uppercase; letter-spacing:-.02em; font-weight:900; font-size:clamp(2.4rem,7.5vw,6rem); line-height:.98; }
body[data-template="bauhaus"] #hero h1 .hl { background:var(--primary); color:var(--bg); padding:0 .3em; display:inline-block; }
body[data-template="bauhaus"] .hero-tag { background:var(--ink); color:var(--bg); border:none; border-radius:0; text-transform:uppercase; letter-spacing:.15em; font-weight:700; }
body[data-template="bauhaus"] .hero-tag::before { background:var(--accent); }
body[data-template="bauhaus"] .hero-lead { color:var(--ink); font-weight:500; }
body[data-template="bauhaus"] .hero-cta .btn-light { background:var(--ink); color:var(--bg); box-shadow:6px 6px 0 var(--primary); }
body[data-template="bauhaus"] .hero-cta .btn-light:hover { transform:translate(-2px,-2px); box-shadow:8px 8px 0 var(--primary); }
body[data-template="bauhaus"] .section-head h2 { text-transform:uppercase; font-weight:900; letter-spacing:-.02em; }
body[data-template="bauhaus"] .section-head h2 .hl, body[data-template="bauhaus"] .section-head h2::after { color:var(--primary); }
body[data-template="bauhaus"] .eyebrow { text-transform:uppercase; font-weight:800; letter-spacing:.18em; }
body[data-template="bauhaus"] .btn { text-transform:uppercase; font-weight:800; letter-spacing:.05em; }
body[data-template="bauhaus"] .btn-primary { box-shadow:6px 6px 0 var(--ink); }
body[data-template="bauhaus"] .btn-primary:hover { transform:translate(-2px,-2px); box-shadow:8px 8px 0 var(--ink); }
body[data-template="bauhaus"] .btn-ghost { border:3px solid var(--ink); }
body[data-template="bauhaus"] .stat-card { border:3px solid var(--ink); box-shadow:8px 8px 0 var(--primary); border-radius:0; }
body[data-template="bauhaus"] .stat + .stat { border-inline-start:3px solid var(--ink); }
body[data-template="bauhaus"] .card { border:3px solid var(--ink); box-shadow:6px 6px 0 var(--accent); border-radius:0; }
body[data-template="bauhaus"] .card:hover { transform:translate(-3px,-3px); box-shadow:9px 9px 0 var(--accent); }
body[data-template="bauhaus"] .card:nth-child(3n+2) { box-shadow:6px 6px 0 var(--primary); }
body[data-template="bauhaus"] .card:nth-child(3n+2):hover { box-shadow:9px 9px 0 var(--primary); }
body[data-template="bauhaus"] .about-photo { border:4px solid var(--ink); box-shadow:12px 12px 0 var(--primary); border-radius:0; }
body[data-template="bauhaus"] .price-card { border:3px solid var(--ink); box-shadow:6px 6px 0 var(--accent); border-radius:0; }
body[data-template="bauhaus"] .price-card.popular { box-shadow:8px 8px 0 var(--primary); border:3px solid var(--ink); }
body[data-template="bauhaus"] .price-badge { border-radius:0; background:var(--ink); box-shadow:3px 3px 0 var(--accent); font-weight:800; text-transform:uppercase; }
body[data-template="bauhaus"] .quote { border:3px solid var(--ink); box-shadow:6px 6px 0 var(--accent); border-radius:0; }
body[data-template="bauhaus"] .chip { border:2px solid var(--ink); box-shadow:3px 3px 0 var(--primary); border-radius:0; background:var(--bg); color:var(--ink); font-weight:800; text-transform:uppercase; letter-spacing:.05em; }
body[data-template="bauhaus"] .faq details { border:2px solid var(--ink); border-radius:0; }
body[data-template="bauhaus"] .faq summary { font-weight:800; text-transform:uppercase; letter-spacing:.02em; }
body[data-template="bauhaus"] .contact-card { border:3px solid var(--ink); box-shadow:10px 10px 0 var(--primary); border-radius:0; }
body[data-template="bauhaus"] .gallery .g { border-radius:0; border:3px solid var(--ink); }
body[data-template="bauhaus"] #testimonials { background:var(--soft); border-top:3px solid var(--ink); border-bottom:3px solid var(--ink); }
body[data-template="bauhaus"] .field input, body[data-template="bauhaus"] .field textarea { border:2px solid var(--ink); border-radius:0; }

/* ===== prism - chamfered/faceted gem shapes via clip-path ===== */
body[data-template="prism"] #hero { min-height:clamp(560px,84vh,780px); }
body[data-template="prism"] #hero::before { content:""; position:absolute; top:8%; left:5%; width:min(28vw,340px); height:min(28vw,340px); background:linear-gradient(135deg, var(--primary), var(--accent)); clip-path:polygon(50% 0%, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%); opacity:.28; z-index:0; filter:blur(2px); }
body[data-template="prism"] #hero h1 { font-weight:800; letter-spacing:-.02em; }
body[data-template="prism"] #hero h1 .hl { background:linear-gradient(135deg, var(--accent), color-mix(in srgb, var(--accent) 60%, #fff)); -webkit-background-clip:text; background-clip:text; color:transparent; }
body[data-template="prism"] .section-head { position:relative; padding-inline-start:2.4rem; }
body[data-template="prism"] .section-head::before { content:""; position:absolute; inset-inline-start:0; top:.55rem; width:22px; height:22px; background:linear-gradient(135deg, var(--primary), var(--accent)); clip-path:polygon(50% 0%, 95% 25%, 95% 75%, 50% 100%, 5% 75%, 5% 25%); }
body[data-template="prism"] .about-photo { clip-path:polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%); border-radius:0; box-shadow:none; }
body[data-template="prism"] .card, body[data-template="prism"] .price-card, body[data-template="prism"] .quote { clip-path:polygon(0 12px, 12px 0, calc(100% - 12px) 0, 100% 12px, 100% calc(100% - 12px), calc(100% - 12px) 100%, 12px 100%, 0 calc(100% - 12px)); border-radius:0; box-shadow:0 24px 50px -28px color-mix(in srgb, var(--primary) 40%, rgba(0,0,0,.2)); }
body[data-template="prism"] .card:hover { transform:translateY(-6px) scale(1.01); }
body[data-template="prism"] .card:hover { box-shadow:0 28px 60px -26px color-mix(in srgb, var(--primary) 55%, rgba(0,0,0,.25)); }
body[data-template="prism"] .card .card-img { clip-path:polygon(0 0, 100% 0, 100% calc(100% - 20px), 50% 100%, 0 calc(100% - 20px)); }
body[data-template="prism"] .stat-card { clip-path:polygon(0 14px, 14px 0, calc(100% - 14px) 0, 100% 14px, 100% calc(100% - 14px), calc(100% - 14px) 100%, 14px 100%, 0 calc(100% - 14px)); border-radius:0; }
body[data-template="prism"] .chip { clip-path:polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%); border-radius:0; padding:.55rem 1.2rem; }
body[data-template="prism"] .price-card.popular { background:linear-gradient(160deg, color-mix(in srgb, var(--primary) 8%, var(--surface)), var(--surface)); border-color:var(--primary); }
body[data-template="prism"] .price-tag { color:var(--primary); background:linear-gradient(135deg, var(--primary), var(--accent)); -webkit-background-clip:text; background-clip:text; color:transparent; }
body[data-template="prism"] .gallery .g { clip-path:polygon(0 12px, 12px 0, calc(100% - 12px) 0, 100% 12px, 100% calc(100% - 12px), calc(100% - 12px) 100%, 12px 100%, 0 calc(100% - 12px)); border-radius:0; }
body[data-template="prism"] .contact-card { clip-path:polygon(0 16px, 16px 0, calc(100% - 16px) 0, 100% 16px, 100% calc(100% - 16px), calc(100% - 16px) 100%, 16px 100%, 0 calc(100% - 16px)); border-radius:0; }
/* Prism popular card + badge: the card has its own clip-path (line 499),
   which clips any child that extends above the card top edge. The default
   `.price-badge` (top:-14px, half-overhanging the card) would be sliced in
   half. Anchor the badge flush with the card top instead, and pad the card
   so it doesn't collide with the h3. */
body[data-template="prism"] .price-badge { clip-path:polygon(8px 0, calc(100% - 8px) 0, 100% 50%, calc(100% - 8px) 100%, 8px 100%, 0 50%); border-radius:0; top:0; }
body[data-template="prism"] .price-card.popular { padding-top:2.8rem; }
/* Same problem for origami's diagonal clip-path. */
body[data-template="origami"] .price-badge { top:0; }
body[data-template="origami"] .price-card.popular { padding-top:2.8rem; }
body[data-template="prism"] .btn-primary { background:linear-gradient(135deg, var(--primary), color-mix(in srgb, var(--primary) 55%, var(--accent))); box-shadow:0 10px 24px -10px color-mix(in srgb, var(--primary) 55%, transparent); }

/* ===== wave - curved section transitions + oval blob shapes ===== */
body[data-template="wave"] #hero { min-height:clamp(560px,86vh,820px); border-radius:0 0 50% 50% / 0 0 8vw 8vw; overflow:hidden; }
body[data-template="wave"] #hero h1 { font-weight:400; }
body[data-template="wave"] .stat-strip { margin-top:-6vw; }
body[data-template="wave"] .stat-card { border-radius:60px; box-shadow:0 30px 60px -30px color-mix(in srgb, var(--primary) 45%, rgba(0,0,0,.2)); }
body[data-template="wave"] .stat + .stat { border-inline-start:1px dashed color-mix(in srgb, var(--primary) 25%, var(--line)); }
body[data-template="wave"] .section-head h2 { font-weight:400; }
body[data-template="wave"] .about-photo { border-radius:50% 50% 50% 50% / 60% 60% 40% 40%; box-shadow:0 40px 70px -30px color-mix(in srgb, var(--primary) 40%, rgba(0,0,0,.2)); }
body[data-template="wave"] .card { border-radius:60px 60px 28px 28px; overflow:hidden; }
body[data-template="wave"] .card .card-img { border-radius:60px 60px 0 0; }
body[data-template="wave"] .card:hover { transform:translateY(-8px); }
body[data-template="wave"] .price-card { border-radius:60px 28px 60px 28px; }
body[data-template="wave"] .price-card:nth-child(even) { border-radius:28px 60px 28px 60px; }
body[data-template="wave"] .price-card.popular { border-radius:60px; box-shadow:0 40px 80px -32px color-mix(in srgb, var(--primary) 55%, rgba(0,0,0,.25)); }
body[data-template="wave"] .quote { border-radius:40px 40px 40px 12px; }
body[data-template="wave"] .quote:nth-child(even) { border-radius:40px 40px 12px 40px; }
body[data-template="wave"] .quote .av { border-radius:50% 50% 45% 55%; }
body[data-template="wave"] .gallery .g { border-radius:40px; }
body[data-template="wave"] .gallery .g:nth-child(2n) { border-radius:50% 50% 40% 40% / 60% 60% 40% 40%; }
body[data-template="wave"] .gallery .g:nth-child(3n) { border-radius:40px 40px 40px 40px / 60% 60% 40% 40%; }
body[data-template="wave"] #testimonials { background:var(--soft); border-radius:0 0 50% 50% / 0 0 6vw 6vw; padding-bottom:calc(var(--band-pad) + 4vw); }
body[data-template="wave"] #testimonials::before { content:""; display:block; height:0; }
body[data-template="wave"] .contact-card { border-radius:50px; overflow:hidden; }
body[data-template="wave"] .chip { border-radius:40px; padding:.55rem 1.2rem; background:linear-gradient(90deg, color-mix(in srgb, var(--primary) 8%, var(--soft)), var(--soft)); }
body[data-template="wave"] .faq details { border-radius:24px; }
body[data-template="wave"] .btn-primary { border-radius:var(--radius-btn); box-shadow:0 12px 26px -12px color-mix(in srgb, var(--primary) 55%, transparent); }
body[data-template="wave"] .btn { border-radius:40px; }

/* ===== origami - folded paper cuts (asymmetric clip-path + fold triangle overlay) ===== */
body[data-template="origami"] #hero h1 { font-weight:400; }
body[data-template="origami"] #hero h1 .hl { color:var(--accent); }
body[data-template="origami"] .section-head h2 { font-weight:400; }
body[data-template="origami"] .section-head::after { content:""; display:block; width:80px; height:2px; background:linear-gradient(90deg, var(--primary) 40%, transparent); margin-top:.9rem; transform:skewX(-24deg); transform-origin:0 0; }
body[data-template="origami"] .eyebrow::before { transform:skewX(-24deg); }
body[data-template="origami"] .about-photo { clip-path:polygon(0 0, calc(100% - 40px) 0, 100% 40px, 100% 100%, 40px 100%, 0 calc(100% - 40px)); border-radius:0; position:relative; }
/* Cards: folded corner top-right + accent triangle overlay showing the "underside" of the fold */
body[data-template="origami"] .card { clip-path:polygon(0 0, calc(100% - 32px) 0, 100% 32px, 100% 100%, 0 100%); border-radius:0; position:relative; }
body[data-template="origami"] .card::before { content:""; position:absolute; top:0; right:0; width:32px; height:32px; background:linear-gradient(225deg, var(--accent) 50%, transparent 50%); z-index:2; pointer-events:none; }
body[data-template="origami"] .card:nth-child(even) { clip-path:polygon(32px 0, 100% 0, 100% 100%, 0 100%, 0 32px); }
body[data-template="origami"] .card:nth-child(even)::before { right:auto; left:0; background:linear-gradient(135deg, var(--accent) 50%, transparent 50%); }
body[data-template="origami"] .card .card-img { border-radius:0; }
body[data-template="origami"] .price-card { clip-path:polygon(0 0, calc(100% - 28px) 0, 100% 28px, 100% 100%, 0 100%); border-radius:0; position:relative; }
body[data-template="origami"] .price-card::before { content:""; position:absolute; top:0; right:0; width:28px; height:28px; background:linear-gradient(225deg, var(--accent) 50%, transparent 50%); z-index:2; pointer-events:none; }
body[data-template="origami"] .price-card.popular { clip-path:polygon(0 24px, 24px 0, 100% 0, 100% 100%, 0 100%); border-color:var(--primary); }
body[data-template="origami"] .price-card.popular::before { top:0; right:auto; left:0; background:linear-gradient(135deg, var(--primary) 50%, transparent 50%); width:24px; height:24px; }
body[data-template="origami"] .quote { clip-path:polygon(0 0, 100% 0, 100% calc(100% - 30px), calc(100% - 30px) 100%, 0 100%); border-radius:0; position:relative; }
body[data-template="origami"] .quote::after { content:""; position:absolute; bottom:0; right:0; width:30px; height:30px; background:linear-gradient(45deg, var(--accent) 50%, transparent 50%); z-index:2; pointer-events:none; }
body[data-template="origami"] .stat-card { clip-path:polygon(0 0, calc(100% - 30px) 0, 100% 30px, 100% 100%, 0 100%); border-radius:0; position:relative; }
body[data-template="origami"] .stat-card::before { content:""; position:absolute; top:0; right:0; width:30px; height:30px; background:linear-gradient(225deg, var(--accent) 50%, transparent 50%); z-index:2; pointer-events:none; }
body[data-template="origami"] .chip { clip-path:polygon(0 0, calc(100% - 8px) 0, 100% 100%, 8px 100%); border-radius:0; padding:.55rem 1.4rem; }
body[data-template="origami"] .gallery .g { clip-path:polygon(0 0, calc(100% - 24px) 0, 100% 24px, 100% 100%, 0 100%); border-radius:0; position:relative; }
body[data-template="origami"] .gallery .g:nth-child(3n)::after { content:""; position:absolute; top:0; right:0; width:24px; height:24px; background:linear-gradient(225deg, var(--accent) 50%, transparent 50%); z-index:2; pointer-events:none; }
body[data-template="origami"] .gallery .g:nth-child(2n) { clip-path:polygon(24px 0, 100% 0, 100% 100%, 0 100%, 0 24px); }
body[data-template="origami"] .price-badge { clip-path:polygon(8px 0, 100% 0, calc(100% - 8px) 100%, 0 100%); border-radius:0; }
body[data-template="origami"] .contact-card { clip-path:polygon(0 0, calc(100% - 40px) 0, 100% 40px, 100% 100%, 40px 100%, 0 calc(100% - 40px)); border-radius:0; }
body[data-template="origami"] .faq details[open] summary::after { color:var(--accent); }

/* Mobile: bauhaus offset shadows tightened so they don't cause horizontal scroll */
@media (max-width:820px) {
  body[data-template="bauhaus"] .card, body[data-template="bauhaus"] .price-card, body[data-template="bauhaus"] .quote, body[data-template="bauhaus"] .stat-card { box-shadow:4px 4px 0 var(--accent); }
  body[data-template="bauhaus"] .card:nth-child(3n+2) { box-shadow:4px 4px 0 var(--primary); }
  body[data-template="bauhaus"] .about-photo { box-shadow:6px 6px 0 var(--primary); }
  body[data-template="bauhaus"] .contact-card { box-shadow:5px 5px 0 var(--primary); }
  body[data-template="bauhaus"] #hero::before, body[data-template="bauhaus"] #hero::after { display:none; }
  body[data-template="botanica"] #hero { grid-template-columns:1fr; }
  body[data-template="botanica"] .hero-media { order:1; margin:0; border-radius:0 0 40% 60% / 0 0 20% 20%; aspect-ratio:16/10; }
}

/* Footer bg = 80% black tinted with 20% of the palette's primary so we get
   a dark, palette-toned surface that works with the fixed white text
   color across ALL palettes. Using var(--ink) here would flip to a LIGHT
   color on dark palettes (noir, corporate p4-p6, etc.) where --ink is
   the readable-text color — the white text on top would become invisible. */
footer.site { background:color-mix(in srgb, var(--primary) 20%, #050505); color:rgba(255,255,255,.88); padding:2.5rem 0; }
footer.site a { color:#fff; }
.foot-row { display:flex; flex-wrap:wrap; gap:1rem 2rem; justify-content:space-between; align-items:center; font-size:.92rem; }
.foot-links { display:flex; gap:1.4rem; list-style:none; margin:0; padding:0; }
/* "האתר נבנה באמצעות PresentSimple" credit line — appears under every customer
   site's copyright row and always keeps the homepage brand colors regardless
   of the site's own template/palette. */
.foot-credit { padding:5px 0; text-align:center; font-size:.9rem; color:rgba(255,255,255,.75); }
/* ===== Footer socials =====
   Sits in the middle of .foot-row (space-between distributes 3 groups:
   copyright / socials / legal links). In edit mode all 7 icons render at
   low opacity so the owner can click any to paste a URL. In view mode only
   validated icons show; unvalidated ones are stripped from the DOM. */
.foot-socials { display:flex; align-items:center; flex-wrap:wrap; gap:.3rem; justify-content:center; }
.foot-soc {
  display:inline-flex; align-items:center; justify-content:center;
  width:32px; height:32px; padding:0;
  border-radius:50%; border:none; background:transparent;
  color:currentColor;
  opacity:.35;
  cursor:pointer;
  text-decoration:none;
  transition:opacity .15s, background .15s;
}
.foot-soc.validated { opacity:1; }
.foot-soc:hover { opacity:1; background:rgba(255,255,255,.08); }
.foot-soc:focus-visible { outline:2px solid rgba(255,255,255,.4); outline-offset:2px; }

/* ===== Social edit modal ===== */
.soc-edit { text-align:center; }
.soc-edit-preview { display:flex; flex-direction:column; align-items:center; gap:.35rem; margin-bottom:1rem; transition:color .2s; }
.soc-edit-name { font-weight:600; font-size:.95rem; color:var(--ink); }
.soc-color-row { justify-content:center; margin-top:.4rem; }

/* Mobile footer: stack the three groups (copyright / socials / links) with
   each on its own row and centered. Otherwise socials look stranded between
   two right-anchored groups in RTL. */
@media (max-width:640px) {
  .foot-row { justify-content:center; text-align:center; row-gap:.8rem; }
  .foot-socials { flex:0 0 100%; justify-content:center; }
  /* Tighter gap so all 4 legal links fit on one row on typical mobile
     widths; row-gap keeps a comfortable line-gap if they still wrap. */
  .foot-links { flex:0 0 100%; justify-content:center; flex-wrap:wrap; gap:.35rem 1rem; font-size:.9rem; }
}
/* Shrink the footer's own bottom padding when the credit is present so the
   "5px" space the user asked for isn't stacked on top of the footer's 2.5rem. */
footer.site:has(.foot-credit) { padding-bottom:0; }
.foot-credit .brand-mini { display:inline-flex; align-items:baseline; margin-inline-start:.35rem; font-family:'Rubik', system-ui, sans-serif; font-weight:800; font-size:1.02rem; color:#fff; text-decoration:none; letter-spacing:-.005em; }
.foot-credit .brand-mini > span { color:#F2A65A; }
/* Affiliate-program footer link is only relevant for Hebrew visitors — the
   affiliate portal + landing marketing are HE-only for now. Hide the whole
   <li> (not just the <a>) for any non-Hebrew active language so we don't
   leave an empty bullet in the footer. `applyLang()` in i18n.js updates
   `html[lang]` on every language change, so this rule re-evaluates live. */
html:not([lang="he"]) .foot-links li:has(> [data-affiliate-program]) { display: none; }
.foot-credit .brand-mini:hover { text-decoration:underline; text-underline-offset:3px; }

@media (prefers-reduced-motion: no-preference) {
  .reveal { opacity:0; transform:translateY(24px); transition:opacity .7s ease, transform .7s ease; }
  .reveal.in { opacity:1; transform:none; }
  .hero-media img { animation:kenburns 22s ease-in-out infinite alternate; }
  @keyframes kenburns { from { transform:scale(1.04);} to { transform:scale(1.14);} }
  .card:hover .card-img img, .gallery .g:hover img, .about-photo:hover img { transform:scale(1.07); }
}
@media (prefers-reduced-motion: reduce) { html { scroll-behavior:auto; } }

@media (max-width:820px) {
  .about-grid, .cards, .quotes, .contact-card, .pricing-grid { grid-template-columns:1fr; }
  .gallery { grid-template-columns:repeat(2,1fr); }
  .gallery .g.big { grid-column:span 2; grid-row:span 1; }
  /* food template's 21:9 about-photo aspect crops a portrait face down to a
     horizontal strip on narrow screens (site 892d9ed3 2026-08-13 rendered
     just mouth+chin). Snap back to a portrait-friendly ratio on mobile;
     desktop keeps the wide letterbox that fits the side-by-side layout. */
  body[data-template="food"] .about-photo { aspect-ratio:4/5; }
}
@media (max-width:900px) {
  nav.primary .nav-links { display:none; }
  /* Mobile nav WA btn: compact icon-only pill so its visibility toggle stays
     reachable in edit mode (hamburger + dropdown are hidden in edit mode by
     the rule below) and its callable link stays reachable in view mode. The
     "וואטסאפ" text hides via .nav-cta-text; a WA glyph shows via ::before.
     In view mode `.btn.is-disabled` already display:none-s the pill, so if
     the phone is missing or the owner turned it off, the icon disappears. */
  .nav-cta {
    display:inline-flex;
    align-items:center;
    justify-content:center;
    padding:.5rem .55rem;
    min-width:0;
    order:97;               /* before .lang-switcher-visitor (order:98) which
                               is before menu-toggle (order:99), so visual RTL
                               left reads [ham][lang][WA]. Auto-margin lives
                               here (first item in the trailing group by flex
                               order) so the whole cluster gets pushed to the
                               row's end together - no gaps between siblings. */
    margin-inline-start:auto;
  }
  /* Drop the hamburger's own auto push in view mode so it flows adjacent to
     the WA pill instead of also demanding the free space (two auto margins
     would split the gap and separate them). */
  body:not([data-edit="true"]) .menu-toggle { margin-inline-start:0 !important; }
  .nav-cta .nav-cta-text { display:none; }
  .nav-cta::before {
    content:"";
    display:block;
    width:22px; height:22px;
    background-color:currentColor;
    -webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><path d='M16 3.2C8.94 3.2 3.2 8.94 3.2 16c0 2.29.6 4.47 1.75 6.4L3.2 28.8l6.61-1.73A12.76 12.76 0 0 0 16 28.64c7.06 0 12.8-5.74 12.8-12.8S23.06 3.2 16 3.2zm0 23.47c-1.9 0-3.77-.51-5.42-1.48l-.39-.23-4.03 1.06 1.08-3.93-.25-.4A10.6 10.6 0 0 1 5.36 16c0-5.87 4.78-10.64 10.64-10.64 2.84 0 5.51 1.11 7.52 3.12A10.55 10.55 0 0 1 26.64 16c0 5.87-4.78 10.64-10.64 10.64zm5.83-7.97c-.32-.16-1.9-.93-2.19-1.04-.29-.11-.51-.16-.72.16-.21.32-.83 1.04-1.01 1.25-.19.21-.37.24-.69.08-.32-.16-1.35-.5-2.58-1.59-.95-.85-1.6-1.9-1.78-2.22-.19-.32-.02-.49.14-.65.14-.14.32-.37.48-.56.16-.19.21-.32.32-.53.11-.21.05-.4-.03-.56-.08-.16-.72-1.73-.99-2.38-.26-.62-.52-.54-.72-.55l-.61-.01c-.21 0-.56.08-.85.4-.29.32-1.12 1.09-1.12 2.67 0 1.57 1.15 3.09 1.31 3.31.16.21 2.26 3.45 5.47 4.83.76.33 1.36.53 1.83.67.77.24 1.47.21 2.02.13.62-.09 1.89-.77 2.16-1.52.27-.75.27-1.39.19-1.52-.08-.13-.29-.21-.61-.37z'/></svg>") center/contain no-repeat;
    mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'><path d='M16 3.2C8.94 3.2 3.2 8.94 3.2 16c0 2.29.6 4.47 1.75 6.4L3.2 28.8l6.61-1.73A12.76 12.76 0 0 0 16 28.64c7.06 0 12.8-5.74 12.8-12.8S23.06 3.2 16 3.2zm0 23.47c-1.9 0-3.77-.51-5.42-1.48l-.39-.23-4.03 1.06 1.08-3.93-.25-.4A10.6 10.6 0 0 1 5.36 16c0-5.87 4.78-10.64 10.64-10.64 2.84 0 5.51 1.11 7.52 3.12A10.55 10.55 0 0 1 26.64 16c0 5.87-4.78 10.64-10.64 10.64zm5.83-7.97c-.32-.16-1.9-.93-2.19-1.04-.29-.11-.51-.16-.72.16-.21.32-.83 1.04-1.01 1.25-.19.21-.37.24-.69.08-.32-.16-1.35-.5-2.58-1.59-.95-.85-1.6-1.9-1.78-2.22-.19-.32-.02-.49.14-.65.14-.14.32-.37.48-.56.16-.19.21-.32.32-.53.11-.21.05-.4-.03-.56-.08-.16-.72-1.73-.99-2.38-.26-.62-.52-.54-.72-.55l-.61-.01c-.21 0-.56.08-.85.4-.29.32-1.12 1.09-1.12 2.67 0 1.57 1.15 3.09 1.31 3.31.16.21 2.26 3.45 5.47 4.83.76.33 1.36.53 1.83.67.77.24 1.47.21 2.02.13.62-.09 1.89-.77 2.16-1.52.27-.75.27-1.39.19-1.52-.08-.13-.29-.21-.61-.37z'/></svg>") center/contain no-repeat;
  }
  /* Hamburger icon — aligned to inline-end (visually left in RTL) */
  .menu-toggle { display:inline-flex; align-items:center; justify-content:center; margin-inline-start:auto; background:none; border:1px solid var(--line); color:var(--ink); border-radius:10px; cursor:pointer; width:40px; height:40px; padding:0; font-size:0; line-height:0; order:99; }
  .menu-toggle::before { content:""; display:block; width:22px; height:22px; background-color:currentColor; -webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><rect x='3' y='5' width='18' height='2' rx='1' fill='black'/><rect x='3' y='11' width='18' height='2' rx='1' fill='black'/><rect x='3' y='17' width='18' height='2' rx='1' fill='black'/></svg>") center/contain no-repeat; mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><rect x='3' y='5' width='18' height='2' rx='1' fill='black'/><rect x='3' y='11' width='18' height='2' rx='1' fill='black'/><rect x='3' y='17' width='18' height='2' rx='1' fill='black'/></svg>") center/contain no-repeat; }
  /* Header stays a single fixed-height row - nav.primary is just a normal
     flex child holding the hamburger. The drop-down .nav-links opens as
     an absolute overlay relative to the header, spanning full width and
     overlapping the hero below (not pushing it down, per Amir's spec).
     Header stays `position:sticky` (line 112) which IS a positioning
     context for descendant `position:absolute` - no override needed. */
  nav.primary { margin-inline-start:0; position:static; }
  nav.primary .nav-links {
    position:absolute; inset-inline:0; top:100%;
    display:flex; flex-direction:column; gap:0;
    background:var(--surface, #fff);
    border-top:1px solid var(--line);
    border-bottom:1px solid var(--line);
    box-shadow:0 12px 24px -12px rgba(0,0,0,.25);
    padding:.5rem 0 1rem;
    z-index:65;
  }
  nav.primary .nav-links a { padding:.85rem 1.5rem; display:block; text-align:start; }
  nav.primary .nav-links[hidden] { display:none; }
  /* In edit mode on mobile, hide the hamburger + drop-down entirely - the
     per-section edit strips (with their own show/hide toggles and reorder
     arrows) already give the owner full navigation control, and the
     hamburger drop-down was fighting the site-header for space. */
  body[data-edit="true"] .menu-toggle,
  body[data-edit="true"] nav.primary .nav-links { display:none !important; }
  .stat-card { grid-template-columns:1fr; }
  .stat + .stat { border-inline-start:none; border-top:1px solid var(--line); }
  /* Base has `.stat-strip { margin-top:-3.5rem }` for a subtle
     desktop float-over into the hero, and `wave` bumps it to `-6vw`.
     On mobile the hero stacks (CTA buttons wrap onto their own row),
     so the strip lands on top of the CTAs. Neutralize the overlap for
     every template - `body[data-template]` matches attribute-exists at
     the same specificity as `body[data-template="wave"]`, and comes
     later in source order so it wins without needing !important. */
  body[data-template] .stat-strip { margin-top:0; }

  /* Mobile nav layout for long brand names + a logo. Give .brand flex-grow
     so it claims the row's remaining space, and drop the auto-margin on
     .nav-cta that would otherwise consume that space FIRST (flexbox spec:
     auto margins absorb positive free space before flex-grow can act, so
     brand's flex:1 was a no-op while the WA pill still had
     `margin-inline-start:auto`). With that auto-margin gone, brand grows
     to fill, and WA + hamburger get pushed to the row's inline-end (visual
     left in RTL) purely by brand's growth — no auto-margin needed.
     Also stretch the nav-row wrap edge-to-edge: the desktop rule caps it
     at min(96vw, 1600px) + 1.5rem inline padding, which leaves 40-60px
     of dead space on either side of the strip on phones — a long brand
     name + logo need every pixel. Small end-pad (.4rem) keeps the ham
     and logo off the screen bezel without eating meaningful space.
     Result in RTL: [logo(far right)]-[name fills space]-[WA][ham(far left)]. */
  header.site .wrap.nav-row { max-width:100vw; padding-inline:.4rem; }
  .brand { flex:1 1 auto; min-width:0; }
  .brand .brand-name { flex:1 1 auto; min-width:0; }
  .nav-cta { margin-inline-start:0; }

}
@media (max-width:760px) {
  body[data-template="corporate"] #hero, body[data-template="personal"] #hero { grid-template-columns:1fr; min-height:auto; }
  body[data-template="corporate"] .hero-media, body[data-template="personal"] .hero-media { order:2; min-height:240px; }
  body[data-template="corporate"] .hero-inner, body[data-template="personal"] .hero-inner { order:1; padding:clamp(3rem,9vw,5rem) 1.25rem 2rem; }
  body[data-template="personal"] .hero-media { border-radius:0; }
  body[data-template="commerce"] .cards { grid-template-columns:repeat(2,1fr); }
}

/* ===== EDIT TOOLS STRIP (primary chrome row) =====
   Layout: [toggle | theme + palette centered | publish/upgrade]
   Toggle pinned to inline-start (right in RTL) via auto margin, publish
   pinned to inline-end (left in RTL), theme+palette naturally centered
   in the remaining space. */
.edit-tools-strip { position:fixed; top:0; left:0; right:0; z-index:250; display:flex; align-items:center; gap:.9rem; flex-wrap:wrap; background:#E0F2FE; color:#075985; border-bottom:1px solid #BAE6FD; padding:.5rem .35rem; box-shadow:0 4px 10px -4px rgba(0,0,0,.08); }
body.has-edit-tools-strip { padding-top:50px; }

/* ===== DRAFT BANNER (warning row) =====
   Now sits BELOW the strip. In edit mode only, on drafts only. Contains
   just the warning text. `top` is set inline by updateChromePadding based
   on the strip's live height. */
.draft-banner { position:fixed; top:50px; left:0; right:0; z-index:245; background:#E0F2FE; color:#075985; border-bottom:1px solid #BAE6FD; font-family:var(--fui),sans-serif; font-size:.85rem; line-height:1.45; padding:.55rem 1rem; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.25rem; }
.draft-banner[hidden] { display:none; }
.draft-banner-notice { text-align:center; font-weight:700; font-size:.95rem; }
/* Draft-banner variant of the upgrade pill: tightens vertical padding so
   the pill fits comfortably inside the thin banner row without pushing
   layout. Base pill styling (white bg, orange border, gift icon, beam
   shimmer) lives on `.publish-btn.upgrade` further down. */
.draft-banner-upgrade-pill { padding-block:.28rem; }
/* Desktop-only strip pill: hidden by default (mobile shows the pill inline
   inside .draft-banner - the strip pill would just duplicate it). The
   desktop media query below reveals it, and only when the site is a draft
   in view mode - edit mode keeps the existing #publishBtn "הפעלת האתר" CTA in
   that slot instead. Selectors are prefixed with `.edit-tools-strip` so
   they outweigh the `.publish-btn { display:inline-flex }` base rule that
   otherwise wins on equal specificity. */
.edit-tools-strip .draft-banner-upgrade-pill-strip { display:none; }
@media (min-width:701px) {
  body.has-draft-banner:not([data-edit="true"]) .edit-tools-strip .draft-banner-upgrade-pill-strip { display:inline-flex; }
}
.publish-nudge-toast {
  position:fixed; z-index:10001;
  left:1rem; right:1rem; bottom:1.25rem;
  margin-inline:auto;
  width:auto; max-width:560px;
  background:#0F172A; color:#F1F5F9;
  padding:.75rem 1rem; border-radius:.75rem;
  box-shadow:0 8px 24px rgba(0,0,0,.25);
  display:flex; align-items:center; gap:.75rem;
  font-size:.9rem; line-height:1.35;
  animation:presentsimpleNudgeIn .25s ease-out;
}
.publish-nudge-body { flex:1 1 auto; min-width:0; }
.publish-nudge-dismiss {
  flex:0 0 auto;
  background:#22C55E; color:#052E1A;
  border:0; border-radius:.5rem;
  padding:.4rem .8rem;
  font-weight:700; cursor:pointer;
  white-space:nowrap;
}
.publish-nudge-dismiss:hover { background:#16A34A; }
@keyframes presentsimpleNudgeIn {
  from { opacity:0; transform:translateY(12px); }
  to   { opacity:1; transform:translateY(0); }
}
body.has-draft-banner.has-edit-tools-strip { padding-top:92px; }
body[data-edit="true"].has-draft-banner.has-edit-tools-strip { padding-top:116px; }

/* Desktop-only companion to `.draft-banner`: on wide screens the "under
   construction" notice rides inside the edit-tools-strip (centered) instead
   of stacking a second full-width bar. Hidden by default; the desktop media
   query below toggles the pair. Absolute-positioning keeps it centered on
   the strip regardless of the toggle's inline-start pin. */
.draft-banner-notice-strip {
  display:none;
  position:absolute;
  left:50%;
  top:50%;
  transform:translate(-50%,-50%);
  font-family:var(--fui),sans-serif;
  /* Scales down on narrower desktops so the full sentence fits on one line
     without wrapping. `clamp` bottoms out at .65rem around 700px viewport
     and reaches .85rem at ~1400px. */
  font-size:clamp(0.65rem, 1.1vw, 0.85rem);
  font-weight:600;
  color:#075985;
  text-align:center;
  pointer-events:none;
  /* One-line notice on desktop by request - no wrap, no <br>. Kept narrow
     enough that the toggle (inline-start) and publish button (inline-end)
     don't get run over by long translations (Russian in particular).
     Truncates with ellipsis rather than wrapping. */
  white-space:nowrap;
  overflow:hidden;
  text-overflow:ellipsis;
  max-width:calc(100% - 32rem);
}
@media (min-width:701px) {
  body.has-draft-banner:not([data-edit="true"]) .draft-banner-notice-strip { display:block; }
  body.has-draft-banner:not([data-edit="true"]) .draft-banner { display:none; }
}

/* When there's no toggle (auto-edit /edit URL or pre-reset), the strip has
   nothing to show outside edit mode — hide it so the site doesn't render an
   empty blue bar before the user enters their password. */
body:not([data-edit="true"]) .edit-tools-strip.no-toggle { display:none; }
body:not([data-edit="true"]).has-edit-tools-strip:not(.has-draft-banner):has(.edit-tools-strip.no-toggle) { padding-top:0; }

/* Visually fuse the strip + banner (same bg color → seamless). */
body.has-draft-banner.has-edit-tools-strip .edit-tools-strip { border-bottom:none; }

/* Children inside the strip — flat inline pills, no fixed positioning. */
.edit-tools-strip .edit-toggle,
.edit-tools-strip .tpl-select,
.edit-tools-strip .lang-select,
.edit-tools-strip .extra-langs,
.edit-tools-strip .palette,
.edit-tools-strip .publish-btn { position:static; left:auto; right:auto; top:auto; transform:none; }

/* Extra-languages row (paid-plan only). Sits between שפת אתר and פלטת צבעים
   in the edit strip. Each checkbox is a compact pill; the label wraps the
   input so the whole pill is clickable + focusable, and [data-tip] provides
   the same styled tooltip as the help button (see [data-tip]::after
   below). `is-translating` shows the in-flight spinner; `is-done` matches
   the final "already translated" locked look. */
.edit-tools-strip .extra-langs {
  display:inline-flex; align-items:center; gap:.3rem; flex-wrap:wrap;
}
.extra-lang-check {
  display:inline-flex; align-items:center; gap:.28rem;
  padding:.22rem .5rem;
  border:1px solid #BAE6FD;
  border-radius:999px;
  background:#F0F9FF;
  font-family:var(--fui),sans-serif; font-size:.78rem; font-weight:600;
  color:#075985;
  cursor:pointer; user-select:none;
  line-height:1;
}
.extra-lang-check input { margin:0; cursor:pointer; accent-color:#0284C7; }
.extra-lang-check input:disabled { cursor:default; }
.extra-lang-check:has(input:checked) { background:#0284C7; border-color:#0284C7; color:#fff; }
.extra-lang-check.is-translating { opacity:.7; }
/* Spinner lives on the ABBR span (not the label's ::before/::after —
   those are owned by [data-tip] tooltip: arrow + balloon). Checkbox
   <input> is a replaced element so pseudos don't render on it either. */
.extra-lang-check.is-translating .extra-lang-abbr {
  position:relative;
  color:transparent;
}
.extra-lang-check.is-translating .extra-lang-abbr::after {
  content:"";
  position:absolute;
  top:50%; left:50%;
  width:.75rem; height:.75rem;
  margin-top:-.375rem; margin-left:-.375rem;
  border:2px solid rgba(255,255,255,.55); border-top-color:#fff;
  border-radius:50%; animation:extraLangSpin .8s linear infinite;
}
@keyframes extraLangSpin { to { transform:rotate(360deg); } }
.extra-lang-abbr { display:inline-block; min-width:1.5rem; text-align:center; }

/* Pair wrapper: keeps `Template: [select]`, `Site language: [select]`,
   `Colour palette: [dots]` grouped so flex-wrap treats each as one item.
   Prevents the label from orphaning above its select on mobile wrap. */
.edit-tools-strip .edit-strip-pair {
  display: inline-flex;
  align-items: center;
  gap: .5rem;
  flex: 0 0 auto;
}

/* Plain-text labels before the template dropdown and the palette dots. */
.edit-tools-strip .edit-strip-label { font-family:var(--fui),sans-serif; font-size:.85rem; font-weight:600; color:inherit; white-space:nowrap; }

/* Auto margins: toggle → inline-start (right in RTL), publish → inline-end
   (left in RTL). Everything between them (theme + palette) gets centered
   in the leftover space. Applies to both draft and published edit modes. */
.edit-tools-strip .edit-toggle { margin-inline-end:auto; }
.edit-tools-strip .publish-btn { margin-inline-start:auto; }

/* Top-line wrapper: holds toggle + helpBtn + endGroup as a single nowrap
   flex row that ALWAYS occupies row 1 of the strip. `width:100%` (not
   just flex-basis:100%) so the wrapper always fills the strip's row —
   no ambiguity about which "100%" the flexbox resolves to. All other
   strip children (blog pill, pair-selectors, palette) stay siblings of
   the topline and wrap below as row 2+. Applies at every viewport
   (mobile + desktop).

   Layout on desktop: [toggle, helpBtn] glued at inline-start, endGroup
   pushed to inline-end via `margin-inline-start:auto`. Layout on mobile:
   toggle alone at inline-start, [helpBtn, endGroup] pushed to inline-end
   as a cluster (helpBtn gets the auto-margin instead of endGroup —
   see the max-width:700px block near line 1370). */
.edit-tools-strip .edit-tools-strip-topline {
  display:flex !important;
  align-items:center;
  flex-wrap:nowrap !important;
  gap:.55rem;
  width:100% !important;
  min-width:0;
  order:0;
}
.edit-tools-strip .edit-tools-strip-topline .edit-toggle {
  margin-inline-end:0 !important;
  margin-inline-start:0 !important;
  min-width:0;
}
/* Desktop default: helpBtn glued next to toggle at inline-start. */
.edit-tools-strip .edit-tools-strip-topline .help-btn {
  margin-inline-start:0;
  margin-inline-end:0;
}
/* Desktop default: endGroup pushed to inline-end. */
.edit-tools-strip .edit-tools-strip-topline .edit-tools-strip-end {
  flex:0 1 auto;
  min-width:0;
  margin-inline-start:auto !important;
  margin-inline-end:0 !important;
}
/* When the help-button is present, it sits next to the toggle and inherits
   the "push everything after me to the end" role. The toggle drops its own
   auto margin so toggle+help stay glued together. */
.edit-tools-strip:has(.help-btn) .edit-toggle { margin-inline-end:.5rem; }
.edit-tools-strip .help-btn { margin-inline-end:auto; }

/* Desktop: fold the topline wrapper into the strip's own flex context so
   pair-selectors (template / lang / palette) and the collapsed contact
   bar can share row 1 with toggle+help+endGroup instead of wrapping to
   row 2. Mobile keeps the `display:flex + width:100%` base rule above so
   the toggle+endGroup stay pinned to row 1 alone and pair-selectors flow
   below. `order:99` on endGroup pushes it visually last regardless of DOM
   order (endGroup is still a DOM child of topline via display:contents;
   siblings sit between via natural order:0). */
@media (min-width:701px) {
  .edit-tools-strip .edit-tools-strip-topline { display:contents !important; }
  .edit-tools-strip .edit-tools-strip-end { order:99; }
}
/* View mode (only toggle visible): mobile centers it for thumb reach.
   Desktop keeps toggle pinned inline-start via the auto margin above.
   Also tightens the toggle label + draft-banner text so the two stacked
   rows don't dominate the fold on small screens. */
@media (max-width:700px) {
  body:not([data-edit="true"]) .edit-tools-strip { padding:.35rem .35rem; }
  body:not([data-edit="true"]) .edit-tools-strip .edit-toggle { margin-inline-end:0; padding:.15rem .35rem; gap:.4rem; font-size:.78rem; }
  body:not([data-edit="true"]) .draft-banner { padding:.35rem .75rem; gap:.15rem; line-height:1.3; }
  body:not([data-edit="true"]) .draft-banner-notice { font-size:.72rem; font-weight:600; line-height:1.3; }
}

/* Edit mode (all viewports): drop the site header's sticky behavior so the
   customer's brand + nav scroll away with the page. The editor chrome up
   top (fixed .edit-tools-strip) is enough persistent context; the site
   header competing for the fold is just noise while editing. */
body[data-edit="true"] header.site { position:static; top:auto; }

/* Mobile edit mode: banner text is redundant, the top chrome + site header
   scroll with the page instead of sticking, and template + palette share one
   row. updateChromePadding() clears the inline body padding-top / header top
   offsets it normally applies for the fixed-chrome layout. */
@media (max-width:700px) {
  body[data-edit="true"] .draft-banner { display:none; }
  body[data-edit="true"] .edit-tools-strip { position:static; top:auto; box-shadow:none; }
  body[data-edit="true"].has-draft-banner,
  body[data-edit="true"].has-edit-tools-strip,
  body[data-edit="true"].has-draft-banner.has-edit-tools-strip { padding-top:0; }
  body[data-edit="true"] .edit-tools-strip { gap:.35rem .55rem; padding:.5rem .35rem; }
  body[data-edit="true"] .edit-tools-strip .edit-strip-label { font-size:.8rem; }
  /* Row 1: edit-mode toggle on inline-start, publish button on inline-end.
     Auto-margin on the toggle's inline-end pushes the publish wrapper to
     the far edge. Ordering pins them to the top of the wrap. */
  body[data-edit="true"] .edit-tools-strip .edit-toggle {
    order:0; flex:0 1 auto; justify-content:flex-start;
    margin-inline-end:auto;
    min-width:0;
    font-size:.82rem; padding:.2rem .35rem; gap:.4rem;
  }
  body[data-edit="true"] .edit-tools-strip .edit-tools-strip-end {
    order:1; flex:0 1 auto; margin-inline-start:0; min-width:0;
  }
  body[data-edit="true"] .edit-tools-strip .publish-btn {
    flex:0 0 auto; width:auto; margin-inline-start:0;
    /* Shrink to fit the top row alongside toggle + email + ? + G on a
       375px iPhone (base .9rem/1rem padding pushes past ~380px). */
    font-size:.78rem; padding:.35rem .8rem;
  }
  /* Upgrade CTA on mobile: keep toggle + ? at their normal non-published
     positions (toggle at inline-start, ?+cluster at inline-end) and drop
     the upgrade pill onto its own row underneath. Needs three moves:
     1) topline gets flex-wrap:wrap so items inside it can spill to a
        second row (base rule pins nowrap for the toggle+endGroup guarantee).
     2) endGroup becomes display:contents so publishBtn can wrap out of
        it independently — the other endGroup buttons (email / analytics
        if present) stay clustered with helpBtn at inline-end.
     3) #publishBtn.upgrade gets flex:1 1 100% + order:99 so it forces
        onto a new row and lands last visually.
     Scoped to `#publishBtn.upgrade` (free-plan upgrade CTA) so paid
     published sites — which use the same `.publish-btn` element without
     the `upgrade` class — keep their existing single-row layout. */
  body[data-edit="true"] .edit-tools-strip:has(#publishBtn.upgrade) .edit-tools-strip-topline {
    flex-wrap:wrap !important;
  }
  body[data-edit="true"] .edit-tools-strip:has(#publishBtn.upgrade) .edit-tools-strip-end {
    display:contents;
  }
  body[data-edit="true"] .edit-tools-strip:has(#publishBtn.upgrade) #publishBtn.upgrade {
    flex:1 1 100%; order:99;
    width:100%; border-radius:10px; padding-block:.55rem;
  }
  /* Blog pill sits on its own row between row 1 (toggle + publish/domain
     button) and row 2 (תבנית עיצוב / שפת אתר). Order 1 puts it AFTER the
     order-0 toggle and the order-1 end-group in DOM order; flex:100% forces
     a wrap onto its own line. Row 2 (pairs) stays at order 2 as defined
     above and lands after the pill. */
  /* Pill lands on its own row (flex-basis:100% triggers wrap) but shrinks
     to its content width (max-width:fit-content) and centers within the
     row (margin-inline:auto). This keeps the icon snug to the label
     instead of the two sitting at opposite ends of a full-width chip. */
  body[data-edit="true"] .edit-tools-strip .blog-pill {
    order:1; flex:1 1 100%; max-width:fit-content;
    margin:0 auto;
    font-size:.85rem; padding:.4rem .9rem;
  }
  /* Shrink the email button label on mobile to match the blog pill's chip
     sizing and prevent wrap when the provider name is appended. */
  body[data-edit="true"] .edit-tools-strip .email-dns-btn {
    font-size:.72rem; padding:.3rem .7rem;
  }
  /* Row 2: תבנית עיצוב + שפת אתר share the row - each pair takes half. */
  body[data-edit="true"] .edit-tools-strip .edit-strip-pair {
    order:2; flex:1 1 calc(50% - .55rem); min-width:0;
  }
  body[data-edit="true"] .edit-tools-strip .edit-strip-pair select { min-width:0; width:100%; }
  /* Row 3: extra-langs (paid-plan) centered on its own row, above palette. */
  body[data-edit="true"] .edit-tools-strip .edit-strip-pair:has(.extra-langs) {
    order:3; flex:1 1 100%; justify-content:center; flex-wrap:wrap;
  }
  /* Row 4: palette centered on its own row. */
  body[data-edit="true"] .edit-tools-strip .edit-strip-pair:has(.palette) {
    order:4; flex:1 1 100%; justify-content:center;
  }
  /* Analytics G lives inside `.edit-tools-strip-end` — cluster gap
     tightened so 3-4 buttons pack neatly on mobile. Help ? sits as a
     topline sibling instead (see below). */
  body[data-edit="true"] .edit-tools-strip .edit-tools-strip-end {
    gap:.35rem;
  }
  /* Mobile: help ? migrates from its desktop "next to toggle" position
     to cluster with endGroup at inline-end (matches the pre-refactor
     "?/G/publish/email as one cluster" mobile layout). Swap the auto
     margin from endGroup onto helpBtn so helpBtn+endGroup ride together
     at inline-end while toggle stays alone at inline-start. */
  .edit-tools-strip .edit-tools-strip-topline .help-btn {
    margin-inline-start:auto;
  }
  .edit-tools-strip .edit-tools-strip-topline .edit-tools-strip-end {
    margin-inline-start:0 !important;
  }
  /* Tighten topline gap so the helpBtn→endGroup handoff reads as a
     single cluster rather than three loosely-spaced items. */
  .edit-tools-strip .edit-tools-strip-topline {
    gap:.35rem;
  }
  /* Undo desktop's position:fixed pinning for analytics-btn (mobile
     only) since the button lives inside endGroup and needs to flow in
     the flex cluster, not float over it. */
  body[data-edit="true"] .edit-tools-strip .edit-tools-strip-end .analytics-btn {
    position:static;
    inset-inline-end:auto;
    top:auto;
    z-index:auto;
    margin:0;
  }
  /* Help ? on mobile: reset any inherited desktop pinning and drop the
     circle border/background so it reads as a plain inline glyph next
     to the cluster (matches pre-refactor mobile look). */
  .edit-tools-strip .edit-tools-strip-topline .help-btn {
    position:static;
    inset-inline-end:auto;
    top:auto;
    z-index:auto;
    background:transparent;
  }
}

/* ===== EDIT MODE — toggle ===== */
/* Label color = template primary (same as the ? help icon) so the wording
   reads with the same branded weight and, more importantly, doesn't
   inherit `--ink` — which on dark-BG templates (noir, aurora dark) is a
   near-white cream that vanishes against the strip's light-blue #E0F2FE.
   Fallback to the strip's own #075985 keeps the label visible outside a
   themed page (admin views, etc.). */
/* Text color inherits from the parent .edit-tools-strip (dark blue #075985
   on light blue #E0F2FE — always AA contrast). Using var(--primary) here
   broke sites whose palette makes --primary near-white (e.g. minimal p4),
   where near-white text on a light-blue strip vanished entirely. */
.edit-toggle { display:inline-flex; align-items:center; gap:.55rem; padding:.25rem .55rem; background:transparent; border:none; font-family:var(--fui),sans-serif; font-weight:600; font-size:.9rem; color:inherit; cursor:pointer; user-select:none; }
.edit-toggle input { position:absolute; opacity:0; pointer-events:none; }
/* Keyboard users can tab to the (visually-hidden) input — surface the focus
   ring on the switch graphic so they can see where focus is. */
.edit-toggle input:focus-visible + .switch { outline:3px solid var(--primary); outline-offset:3px; }
.edit-toggle .switch { width:36px; height:20px; border-radius:20px; background:var(--line); position:relative; transition:background .2s; flex:0 0 auto; }
/* Slide-toggle convention across the app: thumb sits on the physical RIGHT
   when OFF and slides to the physical LEFT when ON. Achieved with
   right:2px + a negative translateX equal to (trackWidth - thumbWidth - 4)
   on the checked state. Kept consistent for every toggle below. */
.edit-toggle .switch::after { content:""; position:absolute; top:2px; right:2px; width:16px; height:16px; border-radius:50%; background:#fff; transition:transform .2s; box-shadow:0 1px 3px rgba(0,0,0,.3); }
body[data-edit="true"] .edit-toggle .switch { background:var(--primary); }
body[data-edit="true"] .edit-toggle .switch::after { transform:translateX(-16px); }

/* Beating help button ("?") in the top strip. Pulse draws attention to it
   on first visit (the welcome modal points here). Pause on hover so the
   customer can actually aim at it. */
.help-btn {
  display:inline-flex; align-items:center; justify-content:center;
  width:24px; height:24px; padding:0;
  border-radius:50%;
  border:2px solid var(--primary, #059669);
  background:transparent;
  color:var(--primary, #059669);
  font-family:var(--fui), Heebo, system-ui, sans-serif;
  font-weight:800; font-size:.82rem; line-height:1;
  cursor:pointer;
  flex:0 0 auto;
  animation:help-beat 1.6s ease-in-out infinite;
  transition:transform .15s ease, background-color .15s ease, color .15s ease;
}
/* Hover-only so touch taps don't briefly scale/re-color the button
   (iOS Safari lifts the finger off the resized bounds and skips the
   click, leaving the ? modal unopened on first tap). */
@media (hover:hover) {
  .help-btn:hover { animation-play-state:paused; background:var(--primary, #059669); color:#fff; transform:scale(1.08); }
}
.help-btn:focus-visible { outline:3px solid var(--primary); outline-offset:3px; }
@keyframes help-beat {
  0%, 100% { transform:scale(1); box-shadow:0 0 0 0 color-mix(in srgb, var(--primary, #059669) 55%, transparent); }
  50%      { transform:scale(1.12); box-shadow:0 0 0 8px color-mix(in srgb, var(--primary, #059669) 0%, transparent); }
}
@media (prefers-reduced-motion:reduce) {
  .help-btn { animation:none; }
}

/* Google Analytics quick-launch button — sits next to .help-btn in the edit
   tools strip. Shape/size mirrors the ? button (24×24 circle, thin border)
   so the two read as a paired pill duo. Inner Google-G SVG keeps its brand
   colors intact; we only style the wrapper circle. */
.analytics-btn {
  display:inline-flex; align-items:center; justify-content:center;
  width:24px; height:24px; padding:0;
  border-radius:50%;
  border:2px solid var(--primary, #059669);
  background:#fff;
  cursor:pointer;
  flex:0 0 auto;
  transition:transform .15s ease, background-color .15s ease, box-shadow .15s ease;
  box-shadow:0 1px 3px rgba(0,0,0,.08);
}
/* Same touch-vs-hover fix as .help-btn above — scaling the button on
   :hover state confuses iOS Safari into cancelling the tap's click. */
@media (hover:hover) {
  .analytics-btn:hover { transform:scale(1.08); box-shadow:0 3px 8px rgba(0,0,0,.15); }
}
.analytics-btn:focus-visible { outline:3px solid var(--primary); outline-offset:3px; }
/* SVG sizes itself to fill the button interior; kept slightly smaller than
   the circle so the G doesn't touch the border. */
.analytics-btn svg { width:14px; height:14px; display:block; }

/* ===== Analytics + stats modal (openAnalyticsModal) =====
   Dialog is pinned to the wizard's white/blue palette (same pattern as
   .plans-info-dialog) so it looks consistent across all site templates. */
.analytics-modal-dialog.modal-dialog {
  --surface: #fff;
  --ink: #1a1a1e;
  --muted: #64748B;
  --line: #E5E7EB;
  --bg: #f9f9f9;
  --primary: #0284C7;
  --primary-d: #075985;
  --primary-ink: #fff;
  background:#fff;
  color:#1a1a1e;
  max-width:520px;
  /* Explicit box-sizing so the base .modal-dialog padding (1.6rem/1.7rem)
     is included in the width - without this, on a narrow viewport the
     content-box + padding pushes total width past 100% and the modal
     overflows the overlay's inset padding. */
  box-sizing:border-box;
}
/* Mobile: fill the overlay's usable width (viewport minus 2rem overlay
   padding). Reduce the base dialog's chunky padding so the textarea +
   long placeholders have room to breathe. */
@media (max-width:700px) {
  .analytics-modal-dialog.modal-dialog {
    max-width:100%;
    padding:1.2rem 1rem 1rem;
  }
  /* Force any long unbreakable string (URLs in the placeholder, saved-ID
     display, GSV token) to wrap rather than push the modal's min-width
     past the viewport. Textarea keeps its own internal scroll. */
  .analytics-modal-dialog .analytics-current-id,
  .analytics-modal-dialog .analytics-current-id code,
  .analytics-modal-dialog .analytics-security-note,
  .analytics-modal-dialog .analytics-hint {
    overflow-wrap:anywhere;
    word-break:break-word;
  }
  .analytics-modal-dialog .analytics-paste,
  .analytics-modal-dialog .analytics-gsv {
    min-width:0;
    max-width:100%;
  }
  /* Tighter font on section titles so the LTR "Google Analytics / Tag
     Manager" phrase inside a HE title doesn't force horizontal overflow
     on the narrowest viewports. */
  .analytics-modal-dialog .analytics-section-title { font-size:.95rem; }
}
.analytics-modal-dialog.modal-dialog h3 { color:#075985; }
.analytics-modal-dialog .analytics-loading { color:#64748B; text-align:center; padding:1.5rem 0; }

/* Stats list — label on inline-start, value on inline-end, filler space
   in the middle via flex. The default <dl> block layout was stacking dt
   over dd on separate rows; overriding to flex-row per pair keeps them
   inline. `.analytics-stats-list` collapses default UA margin/padding. */
.analytics-modal-dialog .analytics-stats-list {
  margin:0 0 1.25rem;
  padding:0;
  display:flex;
  flex-direction:column;
  gap:.4rem;
}
.analytics-modal-dialog .analytics-stats-row {
  display:flex;
  align-items:baseline;
  justify-content:space-between;
  gap:1rem;
  padding:.35rem 0;
  border-bottom:1px dashed #E5E7EB;
}
.analytics-modal-dialog .analytics-stats-row:last-child { border-bottom:none; }
.analytics-modal-dialog .analytics-stats-row dt {
  font-weight:600; color:#334155;
  font-size:.9rem;
}
.analytics-modal-dialog .analytics-stats-row dd {
  margin:0;
  font-weight:700; color:#0F172A;
  font-size:1.05rem;
  font-variant-numeric:tabular-nums;
}
.analytics-modal-dialog .analytics-stat-locked {
  color:#94A3B8; font-size:.82rem; font-weight:600;
  font-style:italic;
}

/* Config block */
.analytics-modal-dialog .analytics-section-title {
  margin:1rem 0 .35rem;
  font-size:1rem; font-weight:700; color:#075985;
}
.analytics-modal-dialog .analytics-security-note {
  margin:0 0 .7rem;
  font-size:.8rem; color:#64748B; line-height:1.4;
}
.analytics-modal-dialog .analytics-current-id {
  margin:.3rem 0 .6rem;
  font-size:.85rem; color:#0F172A;
}
.analytics-modal-dialog .analytics-current-id code {
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:.85rem;
  background:#F1F5F9;
  padding:.15rem .45rem;
  border-radius:6px;
  color:#075985;
}
.analytics-modal-dialog .analytics-paste,
.analytics-modal-dialog .analytics-gsv {
  width:100%;
  padding:.5rem .7rem;
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size:.82rem;
  line-height:1.4;
  border:1px solid #CBD5E1;
  border-radius:8px;
  background:#F8FAFC;
  color:#0F172A;
  box-sizing:border-box;
}
.analytics-modal-dialog .analytics-paste:focus,
.analytics-modal-dialog .analytics-gsv:focus {
  outline:none;
  border-color:#0284C7;
  box-shadow:0 0 0 3px rgba(2,132,199,.15);
}
.analytics-modal-dialog .analytics-paste { resize:vertical; min-height:6rem; }
.analytics-modal-dialog .analytics-field-label {
  display:block;
  margin:.9rem 0 .3rem;
  font-size:.85rem; font-weight:600; color:#334155;
}
.analytics-modal-dialog .analytics-hint {
  margin:.3rem 0 0;
  font-size:.75rem; color:#64748B; line-height:1.4;
}
.analytics-modal-dialog .analytics-err {
  margin:.6rem 0 0;
  color:#B91C1C; font-size:.85rem; font-weight:600;
}
.analytics-modal-dialog .analytics-ok {
  margin:.6rem 0 0;
  color:#065F46; font-size:.85rem; font-weight:600;
}
.analytics-modal-dialog .analytics-actions {
  display:flex; justify-content:flex-end;
  margin-top:.9rem;
}
/* Mobile: pin ? to the opposite-of-start corner (top-left in RTL / HE-AR,
   top-right in LTR) so it stays reachable regardless of edit mode and
   never overlaps the toggle. `position:fixed` takes it out of the strip's
   flex layout, so the strip's remaining controls fill their space normally.
   White background so it reads against site content when the strip
   (position:static in mobile edit mode) scrolls away. */

/* Save status — floats just under the (effective) strip */
.save-status { position:fixed; top:60px; inset-inline-end:1rem; z-index:1200; font-family:var(--fui),sans-serif; font-size:.82rem; color:var(--muted); background:var(--surface); border:1px solid var(--line); border-radius:30px; padding:.35rem .8rem; opacity:0; transition:opacity .3s; pointer-events:none; text-align:center; }
body.has-draft-banner .save-status { top:calc(60px + 42px); }
.save-status.show { opacity:1; }
.save-status.err { color:#d54; border-color:#d54; }
@media (max-width:700px) { .save-status { inset-inline-end:auto; left:50%; transform:translateX(-50%); top:64px; } body.has-draft-banner .save-status { top:calc(64px + 54px); } }

/* Publish button — sits inline inside the strip. inline-flex + align-items
   keeps the ::before glyph (✓ / ✦) vertically centered with the Hebrew
   text; the plain text + space approach lets glyphs drift off the baseline
   because star / check characters have very different vertical metrics than
   Hebrew letters. `gap` replaces the trailing space in the ::before content. */
.publish-btn { font-family:var(--fui),sans-serif; font-weight:700; font-size:.9rem; padding:.45rem 1rem; border-radius:30px; border:none; background:var(--primary); color:#fff; cursor:pointer; box-shadow:0 4px 12px -6px rgba(0,0,0,.3); transition:transform .15s, background .2s; display:inline-flex; align-items:center; justify-content:center; gap:.35em; line-height:1.15; }
.publish-btn:hover { transform:translateY(-1px); background:var(--primary-d); }
.publish-btn[disabled] { opacity:.7; cursor:not-allowed; }
.publish-btn.published { background:#0e7a56; }
.publish-btn.published::before { content:"✓"; }
/* Published + not yet on paid plan → an "upgrade to premium" pitch button
   in a distinct premium/gold hue so it reads differently from the neutral
   "already published" green and from the primary "publish" blue. */
/* Paid but no domain yet - green CTA that drops the customer into the
   wizard's domain step directly (mode=domain-connect). Distinct emerald
   green so it doesn't read as "done" (that's the .published green) but
   still says "positive next action". */
.publish-btn.connect-domain { background:#059669; }
.publish-btn.connect-domain:hover { background:#047857; }
.publish-btn.connect-domain::before { content:"🌐"; }
/* Upgrade pill (draft banner + edit-tools strip + publish-wizard step 6):
   white bg, orange border, gift icon on the leading edge, and a soft beam
   that sweeps across on a loop to draw the eye. Text uses the same orange
   as the border so the pill reads as a single crisp CTA on any template
   background. Kept as .publish-btn.upgrade (not a new class) so all
   .publish-btn layout (inline-flex, gap, box-shadow) carries over. */
.publish-btn.upgrade {
  position:relative; overflow:hidden;
  background:#fff; color:#B45309;
  border:1.5px solid #F59E0B;
  font-size:.78rem; line-height:1.15;
  padding:.28rem 1.05rem;
  box-shadow:0 4px 14px -6px rgba(217,119,6,.45);
}
/* Publish-wizard step 6: the "want to promote your business?" CTA sits on
   the inline-start side of the actions row (visual right in RTL) while
   Back + Publish stay clumped at flex-end (visual left). Auto margin on
   the inline-end absorbs the free space between the CTA and the pair. */
.modal-actions .p-upgrade-cta { margin-inline-end:auto; }
.publish-btn.upgrade:hover {
  background:#FFF7ED; color:#9A3412; border-color:#D97706;
  box-shadow:0 6px 18px -6px rgba(217,119,6,.55);
}
/* Legacy ✦ pseudo-icon replaced by an inline gift SVG in `.upgrade-pill-icon`
   (see main.js buildUpgradePill). Suppress the ::before so it doesn't render
   an empty box on older cached DOM. */
.publish-btn.upgrade::before { content:none; }
/* Gift icon on the leading edge. `1em` sizing follows the pill's text so
   the icon stays proportional across the (smaller) draft banner and the
   (larger) step-6 CTA. */
.publish-btn.upgrade .upgrade-pill-icon {
  display:inline-flex; align-items:center; justify-content:center;
  font-size:1.15rem; line-height:1; color:#D97706;
  flex:0 0 auto;
}
/* Two-line label wrapper: <br> renders as a real line break inside the
   inline-block, so the gift icon (a flex sibling) stays vertically centered
   next to a two-line text block instead of the icon and each line
   fighting for their own flex row. */
.publish-btn.upgrade .publish-btn-text { display:inline-block; text-align:center; font-weight:700; }
/* Beam / shimmer: a diagonal translucent stripe that sweeps across the
   pill on a loop. Absolutely positioned overlay tied to the pill's
   `overflow:hidden` clip. `pointer-events:none` so it never blocks clicks.
   Skew keeps the beam angled like a light streak. Animation pauses on
   hover so hover state stays visually stable. */
.publish-btn.upgrade .upgrade-pill-beam {
  position:absolute; top:0; bottom:0; inset-inline-start:-40%;
  width:35%; pointer-events:none;
  background:linear-gradient(115deg, transparent 0%, rgba(255,255,255,0) 25%, rgba(255,206,120,.75) 50%, rgba(255,255,255,0) 75%, transparent 100%);
  transform:skewX(-20deg);
  animation:upgradePillBeam 2.6s ease-in-out .8s infinite;
}
.publish-btn.upgrade:hover .upgrade-pill-beam { animation-play-state:paused; }
@keyframes upgradePillBeam {
  0%   { inset-inline-start:-40%; opacity:0; }
  15%  { opacity:1; }
  85%  { opacity:1; }
  100% { inset-inline-start:110%; opacity:0; }
}
@media (prefers-reduced-motion: reduce) {
  .publish-btn.upgrade .upgrade-pill-beam { animation:none; opacity:0; }
}

/* Sale-active variant ("מבצע לזמן מוגבל"): swaps the pale orange sweep for
   a saturated rainbow gradient so the pill visually reads as "limited-time
   offer" without changing layout / size / click target. Toggled by
   .has-sale on .publish-btn.upgrade (set in main.js pill-builders when
   isAffiliateSaleActive() is true). Border + text stay orange so the pill
   still matches the "upgrade" family - just the beam gets colorful. */
.publish-btn.upgrade.has-sale .upgrade-pill-beam {
  background:linear-gradient(115deg,
    transparent 0%,
    rgba(239,68,68,.55) 20%,
    rgba(245,158,11,.65) 35%,
    rgba(34,197,94,.55) 50%,
    rgba(59,130,246,.55) 65%,
    rgba(168,85,247,.55) 80%,
    transparent 100%);
}
/* Sale variant: paint the icon in a hot red so it echoes the beam's
   rainbow-into-red rather than reading as a plain orange gift. */
.publish-btn.upgrade.has-sale .upgrade-pill-icon { color:#DC2626; }

/* Sale-variant plans modal: the title reads "מבצע לזמן מוגבל !!" and
   should be visually urgent - paint it red so the framing lands before
   the customer even reads the words. openModal renders the title as a
   bare <h3> inside .modal-dialog; the extra .plans-info-dialog chain
   beats the blue-title rule at .plans-info-dialog.modal-dialog h3 which
   otherwise wins on same-specificity later-in-source order. Keeps the
   default h3 weight so the title doesn't read heavier than others. */
.plans-info-dialog.plans-upsell-sale.modal-dialog > h3 {
  color:#DC2626;
}

/* Modal overlay */
.modal-overlay { position:fixed; inset:0; z-index:1000; background:rgba(0,0,0,.5); display:grid; place-items:center; padding:1rem; backdrop-filter:blur(2px); }
/* Modal chrome is neutral (white surface, dark ink) regardless of the
   site's template palette. On dark templates the site sets --surface / --ink
   / --muted / --bg / --line to dark values; re-declaring them here scopes
   fresh light values to the dialog subtree so every descendant that reads
   these vars (inputs, body copy, ghost buttons, meta text) stays legible
   without needing per-element overrides. --primary is intentionally NOT
   pinned so branded CTAs still track the site's accent color. */
.modal-dialog { position:relative; background:#fff; color:#1a1a1a; --surface:#fff; --ink:#1a1a1a; --muted:#666; --bg:#f9f9f9; --line:#ddd; border-radius:14px; padding:1.6rem 1.7rem 1.3rem; max-width:440px; width:100%; box-shadow:0 22px 60px -20px rgba(0,0,0,.5); font-family:var(--fui), Heebo, system-ui, sans-serif; max-height:calc(100vh - 2rem); overflow-y:auto; overflow-x:hidden; scrollbar-width:thin; scrollbar-color:#c8d3dc transparent; }
/* Narrow WebKit scrollbar matching Firefox `scrollbar-width:thin`. Fires
   only when the dialog content overflows the viewport - inner scroll
   containers (e.g. .publish-checklist-dialog .modal-body) still handle
   their own scroll independently. Covers the "modal-over-modal" case
   where a nested confirmation dialog was previously clipped without
   any way to reach its buttons on short screens. */
.modal-dialog::-webkit-scrollbar { width:6px; }
.modal-dialog::-webkit-scrollbar-track { background:transparent; }
.modal-dialog::-webkit-scrollbar-thumb { background:#c8d3dc; border-radius:6px; }
.modal-dialog::-webkit-scrollbar-thumb:hover { background:#a4b2be; }
.modal-dialog h3 { font-family:var(--fd, Heebo); font-size:1.35rem; margin:0 0 .7rem; text-decoration:none; }
/* Plan-upgrade payment modal: center the title + billing-meta line so they
   read as a stacked header above the (already-centered) mock iframe. */
.plan-payment-dialog h3,
.plan-payment-dialog .modal-body > .meta:first-child { text-align:center; }
/* "Fill card details in the secure form above" hint sits below the iframe;
   center it so it reads as a caption anchored to the payment surface. */
.plan-payment-dialog .pg-hint {
  text-align:center; margin:.75rem 0 0; color:var(--muted, #4B5563);
}

/* Cart + TOU gate that fronts the payment page. Reuses the publish wizard's
   TOU textarea + checkbox styles by re-declaring them under the modal
   selector (existing rules are scoped to .publish-step-body only).
   Chrome colors (bg, ink, lines, primary btn) are pinned to the publish
   wizard's blue palette rather than template-driven so the checkout looks
   identical across every site template (noir + other dark palettes were
   rendering illegible dark-on-dark cart lines + gold "continue" buttons). */
.plan-cart-dialog.modal-dialog { background:#fff; color:#1a1a1e; }
/* Draft-banner "Discover Plus" plans info modal — same white-bg + blue
   palette pin as .plan-cart-dialog so the cards read the same across
   every site template regardless of the template's --surface / --ink.
   Overriding the CSS custom properties on the dialog scope propagates
   the light values into every nested var() inside .publish-plan rules
   (which otherwise inherit the dark template's --surface / --ink and
   render the cards as dark-on-dark). */
.plans-info-dialog.modal-dialog {
  --surface: #fff;
  --ink: #1a1a1e;
  --muted: #64748B;
  --line: #E5E7EB;
  --bg: #f9f9f9;
  /* Pin the primary color to the publish-wizard's deep blue so .btn-primary
     buttons inside the upsell (e.g. "אני רוצה לשדרג") don't inherit the
     template's --primary — which on warm palettes rendered the CTA as an
     unstyled orange/brown block. --primary-ink keeps text white on both. */
  --primary: #0284C7;
  --primary-d: #075985;
  --primary-ink: #fff;
  background:#fff;
  color:#1a1a1e;
  /* Wider than the default 440px cap so the two plan cubes get breathing
     room side-by-side on desktop; capped max-height + overflow-y so the
     content scrolls on short viewports instead of running off-screen. */
  max-width:720px;
  max-height:85vh;
  overflow-y:auto;
}
.plans-info-dialog.modal-dialog h3 { color:#075985; }
/* Blue "upgrade happens in the publish flow" hint appended under the plus
   card's fineprint. Modal-only - the regular publish wizard's plus card
   doesn't render this line (see openPlansModal in main.js). */
.plans-info-dialog .plans-info-upgrade-hint {
  margin:.6rem 0 0;
  text-align:center;
  font-size:.78rem;
  font-weight:600;
  color:#0284C7;
  line-height:1.35;
}
/* Upsell single-card variant (mode: upgrade | draft, .plans-upsell-dialog).
   Free card is stripped in JS; the remaining Plus card widens to fill the
   modal via .plans-upsell-single. Intro paragraph sits above the card, a
   colorful gift anchors the card top-center, and mode==upgrade replaces
   the static hint with a blue "אני רוצה לשדרג" CTA at the card foot. */
.plans-upsell-dialog .plans-upsell-intro {
  margin:.3rem 0 1rem;
  text-align:center;
  font-size:.95rem;
  font-weight:600;
  color:#075985;
  line-height:1.45;
  text-wrap:balance;
}
/* Override the shared two-col grid when only one card is present -
   otherwise the single Plus card sits in a half-width column with a big
   empty slot next to it. */
.plans-upsell-dialog .publish-plans.plans-upsell-single { grid-template-columns:1fr; max-width:420px; margin-inline:auto; }
/* Colorful gift emoji anchoring the top of the plus card. Big enough to
   read as a hero flourish, decorative only (aria-hidden). Slight negative
   margin lifts it above the "מחיר אחיד לכל החיים" badge for visual pop. */
.plans-upsell-dialog .plans-upsell-gift {
  font-size:2.6rem;
  line-height:1;
  text-align:center;
  margin:.15rem 0 .35rem;
  filter:drop-shadow(0 2px 6px rgba(217,119,6,.35));
}
/* Blue "I want to upgrade" CTA that replaces the info hint in mode==upgrade.
   Full-width inside the card so it reads as the primary card action.
   Base .btn-primary rule only sets bg/color; the button lives inside the
   card (not .modal-actions) so we spell out padding / radius / border /
   cursor / hover here rather than piggy-backing on modal-actions styling. */
.plans-upsell-dialog .plans-upsell-cta {
  display:block;
  width:100%;
  margin-top:.9rem;
  padding:.75rem 1.2rem;
  border:none;
  border-radius:10px;
  background:#0284C7;
  color:#fff;
  font:inherit;
  font-size:1rem;
  font-weight:700;
  line-height:1.2;
  cursor:pointer;
  box-shadow:0 4px 14px -6px rgba(2,132,199,.55);
  transition:background .2s, transform .15s, box-shadow .2s;
}
.plans-upsell-dialog .plans-upsell-cta:hover {
  background:#075985;
  transform:translateY(-1px);
  box-shadow:0 6px 18px -6px rgba(7,89,133,.65);
}
.plans-upsell-dialog .plans-upsell-cta:focus-visible {
  outline:2px solid #0284C7;
  outline-offset:2px;
}
/* Bump the perks list here - the shared .publish-plan-feats runs at .8rem
   in the publish wizard where two cards share the row, but this upsell
   modal shows a single card with plenty of horizontal room and the perks
   ARE the pitch, so they should read comfortably. */
.plans-upsell-dialog .publish-plan-feats { font-size:.95rem; }
.plans-upsell-dialog .publish-plan-feats li { line-height:1.45; }
.plan-cart-dialog .p-cart-table {
  width:100%; border-collapse:collapse; margin:0 0 1rem;
  font-size:.94rem;
}
.plan-cart-dialog .p-cart-table th,
.plan-cart-dialog .p-cart-table td {
  padding:.7rem .6rem; border-bottom:1px solid #E5E7EB;
  text-align:start;
}
.plan-cart-dialog .p-cart-table th {
  font-weight:600; font-size:.82rem; color:#6B7280;
  text-transform:uppercase; letter-spacing:.02em;
}
.plan-cart-dialog .p-cart-table td { color:#1a1a1e; }
.plan-cart-dialog .p-cart-table .p-cart-qty { text-align:center; width:5rem; }
.plan-cart-dialog .p-cart-table .p-cart-total {
  text-align:end; font-weight:700; white-space:nowrap;
}
.plan-cart-dialog .p-cart-vat-breakdown { font-weight:500; color:#6B7280; font-size:.85em; margin-inline-start:.35rem; }
.plan-cart-dialog .p-section-intro {
  margin:.4rem 0 .35rem; font-weight:700; color:#1a1a1e;
}
.plan-cart-dialog .p-tos-textarea {
  width:100%; height:5.5rem; resize:none; font:inherit; font-size:.82rem;
  line-height:1.5; padding:.55rem .75rem; border:1px solid #E5E7EB;
  border-radius:8px; background:#f9f9f9; color:#1a1a1e;
  overflow-y:auto; overflow-x:hidden; white-space:pre-wrap;
  scrollbar-width:thin; scrollbar-color:#b8c0c8 transparent;
}
.plan-cart-dialog .p-tos-textarea:focus-visible {
  outline:2px solid #0284C7; outline-offset:2px;
}
.plan-cart-dialog .p-tos-agree {
  display:flex; align-items:center; gap:.55rem; cursor:pointer;
  padding:.6rem 0 .3rem; font-size:.92rem; color:#1a1a1e;
  user-select:none; font-weight:500;
}
.plan-cart-dialog .p-tos-agree input[type="checkbox"] {
  width:1.1rem; height:1.1rem; flex:0 0 auto; cursor:pointer;
  accent-color:#0284C7;
}
/* Recurring-payment reassurance: appended below .modal-actions (see
   openCartAndTouGate) so it reads as a footer takeaway rather than a
   pre-decision disclosure. Uses the cart CTA's blue so it visually pairs
   with the "המשיכו לתשלום מאובטח" button directly above it. */
.plan-cart-dialog > .p-cart-recurring-note {
  margin:.75rem 0 0; text-align:center; font-size:.85rem; color:#0284C7;
}
/* !important because per-template overrides (e.g. `body[data-template="noir"]
   .btn-primary { color:var(--bg); }`, aurora's linear-gradient background)
   would otherwise leak the template's brand color onto this checkout CTA. */
.plan-cart-dialog .modal-actions .btn-primary {
  background:#0284C7 !important; color:#fff !important;
  display:inline-flex; align-items:center; gap:.45rem;
}
.plan-cart-dialog .modal-actions .btn-primary:hover:not([disabled]) {
  background:#0369A1 !important;
}
.plan-cart-dialog .modal-actions .btn-primary .btn-icon {
  display:inline-flex; align-items:center;
}
.plan-cart-dialog .modal-actions .btn-ghost {
  border-color:#E5E7EB !important; color:#4B5563 !important; background:transparent !important;
}
.plan-cart-dialog .modal-actions .btn-ghost:hover { background:#F1F5F9 !important; }
.plan-cart-dialog .modal-actions button[disabled] {
  opacity:.55; cursor:not-allowed;
}
/* Defensive: the site's template CSS is loaded in the same document, and
   any global text-decoration rule that leaks onto generic h3/label/p tags
   would show through as a stray strikethrough on the modal chrome. Force
   none inside .modal-dialog so template CSS can never bleed. */
.modal-dialog .field label,
.modal-dialog .modal-body p { text-decoration:none; }
.modal-dialog .modal-body { margin-bottom:1.2rem; line-height:1.55; color:var(--muted, #444); }
.modal-dialog .modal-body strong { color:var(--ink, #1a1a1a); }
.modal-dialog .field { margin-bottom:.8rem; }
.modal-dialog .field label { display:block; font-size:.88rem; margin-bottom:.25rem; font-weight:600; }
.modal-dialog .field input { width:100%; font:inherit; padding:.7rem .9rem; border:1px solid var(--line, #ddd); border-radius:10px; background:var(--bg, #f9f9f9); color:inherit; }
.modal-dialog .field .hint { font-size:.78rem; color:var(--muted, #888); margin-top:.3rem; }
.modal-dialog .field .err { font-size:.82rem; color:#d54; margin-top:.3rem; }
.modal-actions { display:flex; gap:.7rem; justify-content:flex-end; }
.modal-actions button { font:inherit; font-weight:600; padding:.6rem 1.2rem; border-radius:10px; border:none; cursor:pointer; }
.modal-actions .btn-ghost { background:transparent; border:1px solid var(--line, #ccc); color:inherit; }
.modal-actions .btn-primary { background:var(--primary, #08c); color:#fff; }
.modal-actions .btn-primary:hover { background:var(--primary-d, #06a); }
.modal-actions .btn-primary[disabled] { opacity:.6; cursor:not-allowed; }
.modal-dialog .reset-link-row { margin:.4rem 0 1rem; font-size:.85rem; color:var(--muted,#666); display:flex; gap:.5rem; flex-wrap:wrap; align-items:center; }
/* display:flex above outranks the browser's default [hidden]{display:none},
   so an empty pre-fetch row would still occupy layout space (and, on some
   RTL Chromium builds, its empty flex baseline caps neighbouring text with
   a stray horizontal line that reads as a strikethrough). Restore hidden. */
.modal-dialog .reset-link-row[hidden] { display:none; }
.modal-dialog .reset-link-row a { color:var(--primary,#08c); text-decoration:underline; }
.modal-dialog .reset-link-row a.sent { color:var(--muted,#888); text-decoration:none; pointer-events:none; }
.modal-dialog .reset-link-row .meta { font-size:.78rem; color:var(--muted,#888); }

/* ===== First-visit welcome modal =====
   Present box + confetti pop-in. Fires once per (uid × browser) via
   showWelcomeModal in main.js. The internal slide toggle proxies clicks to
   the real strip toggle - see showApp for the guard conditions. */
.modal-dialog:has(.welcome-body) { max-width:340px; padding:2rem 1.4rem 1rem; overflow:hidden; text-align:center; }
.modal-dialog:has(.welcome-body) .modal-body { margin-bottom:.8rem; color:var(--ink, #1a1a1a); }
.modal-dialog:has(.welcome-body) .modal-actions { justify-content:center; }
.modal-dialog:has(.welcome-body) .modal-actions .btn-primary { min-width:120px; }
.modal-dialog:has(.publish-reminder-body) { max-width:340px; padding:2rem 1.4rem 1rem; text-align:center; }
.modal-dialog:has(.publish-reminder-body) .modal-body { margin-bottom:.8rem; color:var(--ink, #1a1a1a); }
.modal-dialog:has(.publish-reminder-body) .modal-actions { justify-content:center; }
.modal-dialog:has(.publish-reminder-body) .modal-actions .btn-primary { min-width:120px; }
.publish-reminder-note { margin:0; font-size:.95rem; line-height:1.55; color:var(--ink, #1a1a1a); }

/* Upgrade-nudge modal (main.js showUpgradeNudgeModal). Fires on 2nd+ edit-
   mode entry for free-plan users; sells the paid plan + optional domain.
   Desktop max-width is bumped high enough that the two-sentence pitch fits
   on two lines without the ugly mid-word break we had at 440px. Mobile
   still shrinks to the viewport thanks to the base .modal-dialog rules.
   The transparent 3px border + double-background is the classic gradient-
   border trick: linear (padding-box) paints the solid surface inside;
   conic (border-box) paints the rotating rainbow only in the border ring.
   `--nudge-angle` is animated via @property so the conic actually rotates
   (a plain CSS custom prop can't be interpolated inside a gradient). */
.modal-dialog:has(.upgrade-nudge-body) {
  max-width:560px; padding:1.8rem 1.6rem 1rem;
  border:3px solid transparent;
  background:
    linear-gradient(var(--surface, #fff), var(--surface, #fff)) padding-box,
    conic-gradient(
      from var(--nudge-angle, 0deg),
      #F59E0B, #EF4444, #EC4899, #A855F7, #3B82F6, #10B981, #F59E0B
    ) border-box;
  animation:nudgeBorderSpin 6s linear infinite;
}
@property --nudge-angle {
  syntax:'<angle>';
  initial-value:0deg;
  inherits:false;
}
@keyframes nudgeBorderSpin {
  to { --nudge-angle:360deg; }
}
@media (prefers-reduced-motion: reduce) {
  .modal-dialog:has(.upgrade-nudge-body) { animation:none; }
}
.modal-dialog:has(.upgrade-nudge-body) .modal-body { margin-bottom:.8rem; color:var(--ink, #1a1a1a); }
.modal-dialog:has(.upgrade-nudge-body) .modal-actions { justify-content:center; }
/* Continue CTA mirrors .plans-upsell-cta (the "אני רוצה לשדרג" button on
   the upgrade upsell modal) so both live in the same visual family — same
   sky-blue, same soft glow shadow, same padding, same rounding. Uses
   !important on padding to override the shared .modal-actions button base
   at line ~2010 which would otherwise force a shorter .6rem height. */
.modal-dialog:has(.upgrade-nudge-body) .modal-actions #upgradeNudgeContinue {
  padding:.75rem 1.2rem !important;
  border:none;
  border-radius:10px;
  background:#0284C7;
  color:#fff;
  font-weight:700;
  font-size:1rem;
  line-height:1.2;
  min-width:200px;
  box-shadow:0 4px 14px -6px rgba(2,132,199,.55);
  transition:background .2s, transform .15s, box-shadow .2s;
}
.modal-dialog:has(.upgrade-nudge-body) .modal-actions #upgradeNudgeContinue:hover {
  background:#075985;
  transform:translateY(-1px);
  box-shadow:0 6px 18px -6px rgba(7,89,133,.65);
}
.modal-dialog:has(.upgrade-nudge-body) .modal-actions #upgradeNudgeContinue:focus-visible {
  outline:2px solid #0284C7; outline-offset:2px;
}
/* Close button — match the same vertical height as Continue so both align
   on the same baseline, but keep the subtle ghost styling so the primary
   action still dominates. */
.modal-dialog:has(.upgrade-nudge-body) .modal-actions .btn-ghost {
  padding:.75rem 1.2rem !important;
  border-radius:10px;
  font-size:1rem;
  line-height:1.2;
}
.upgrade-nudge-body { text-align:center; }
.upgrade-nudge-headline {
  font-size:1.1rem; font-weight:700; line-height:1.4;
  color:var(--ink, #1a1a1a);
  margin-bottom:.65rem;
}
.upgrade-nudge-text {
  font-size:.95rem; line-height:1.7;
  color:var(--ink, #1a1a1a);
  margin-bottom:1rem;
}
/* Lead line of the pitch — text on the right (RTL start), rocket at the
   end (left edge). The heartbeat pulses the whole phrase so text + rocket
   thump together, matching the "launch" copy in a physical, organic way. */
.upgrade-nudge-pitch-lead {
  display:inline-block;
  transform-origin:center;
  animation:upgradeNudgeHeartbeat 1.6s ease-in-out infinite;
}
.upgrade-nudge-pitch-lead-text { font-weight:700; }
.upgrade-nudge-rocket {
  display:inline-block; vertical-align:-.1em;
  margin-inline-start:.35rem;
  font-size:1.15em;
}
/* Classic double-thump heartbeat: two quick scale-ups, then a longer rest. */
@keyframes upgradeNudgeHeartbeat {
  0%, 55%, 100% { transform:scale(1); }
  15%           { transform:scale(1.08); }
  30%           { transform:scale(1); }
  40%           { transform:scale(1.06); }
}
@media (prefers-reduced-motion: reduce) {
  .upgrade-nudge-pitch-lead { animation:none; }
}
.upgrade-nudge-domains {
  margin-top:.6rem; padding-top:.9rem;
  border-top:1px solid rgba(0,0,0,.08);
  text-align:center;
}
.upgrade-nudge-domains-intro {
  margin:0 0 .7rem; font-size:.95rem; font-weight:700;
  color:var(--ink, #1a1a1a);
}
/* Fine-print footnote block appended below .modal-actions — each `*` in
   the modal body points down here. All notes render as <br>-separated
   lines inside a single <p> so the whole block reads as one fine-print
   unit with one top separator. */
.upgrade-nudge-footnote {
  margin:.9rem 0 0;
  padding-top:.7rem;
  border-top:1px solid rgba(0,0,0,.08);
  font-size:.78rem; font-weight:400;
  color:rgba(0,0,0,.55);
  text-align:center;
  line-height:1.55;
}
.upgrade-nudge-domains-loading,
.upgrade-nudge-domains-error {
  margin:.4rem 0; font-size:.85rem; color:rgba(0,0,0,.55);
}
.upgrade-nudge-domains-error { color:#c0392b; }
/* Animated "..." trailing the loading text — cycles 1 → 2 → 3 dots and
   repeats. Uses CSS `content` animation (Chrome 79+, Firefox 91+, Safari
   15+); older browsers fall back to a static single dot, which is fine. */
.upgrade-nudge-domains-loading::after {
  content:'.';
  display:inline-block;
  width:1.5ch; text-align:start;
  animation:nudgeLoadingDots 1.4s steps(3, jump-none) infinite;
}
@keyframes nudgeLoadingDots {
  0%   { content:'.'; }
  33%  { content:'..'; }
  66%  { content:'...'; }
}
@media (prefers-reduced-motion: reduce) {
  .upgrade-nudge-domains-loading::after { animation:none; content:'...'; }
}
/* Inline domain list: not buttons — plain clickable text items separated by
   thin middots, everything on one row on desktop. Wraps naturally on narrow
   viewports. Selected item picks up brand color + weight so the pick is
   obvious without any button chrome. */
.upgrade-nudge-list {
  display:flex; flex-wrap:wrap; justify-content:center;
  align-items:baseline; gap:.35rem .55rem;
  margin-top:.4rem; font-size:.95rem;
  color:var(--ink, #1a1a1a);
}
.upgrade-nudge-list-item { direction:ltr; font-weight:600; }
.upgrade-nudge-list-sep { color:rgba(0,0,0,.35); user-select:none; }

/* Publish wizard step-5 suggestion bar — same live suggestions the nudge
   showed, now clickable to pre-fill the search input + trigger check. */
.p-domain-suggestions {
  display:flex; flex-wrap:wrap; align-items:baseline;
  gap:.4rem .55rem; margin-top:.5rem;
  font-size:.9rem; color:var(--ink, #1a1a1a);
}
.p-domain-suggestions-label { color:rgba(0,0,0,.6); font-weight:500; }
.p-domain-suggestions-list {
  display:inline-flex; flex-wrap:wrap; align-items:baseline;
  gap:.35rem .5rem;
}
.p-domain-suggestion {
  background:none; border:none; padding:0; margin:0; font:inherit;
  color:var(--brand-ink, #B45309); font-weight:600; direction:ltr;
  cursor:pointer;
  text-decoration:underline; text-underline-offset:3px;
  text-decoration-color:rgba(180,83,9,.35);
  transition:text-decoration-color .15s ease, color .15s ease;
}
.p-domain-suggestion:hover {
  color:#7C3D0A;
  text-decoration-color:var(--brand-ink, #B45309);
}
.p-domain-suggestions-sep { color:rgba(0,0,0,.35); user-select:none; }
.upgrade-nudge-pill-name {
  font-weight:600; font-size:.92rem;
  color:var(--ink, #1a1a1a); direction:ltr;
}
.upgrade-nudge-pill-price {
  font-size:.75rem; color:rgba(0,0,0,.55);
}

.welcome-body { position:relative; padding:.2rem 0 0; }
.welcome-confetti {
  position:absolute; inset-inline:0; top:-2rem; height:240px;
  overflow:hidden; pointer-events:none; z-index:0;
}
.welcome-confetti .cft {
  position:absolute; top:-14px;
  width:8px; height:12px; border-radius:2px;
  opacity:0;
  animation:cft-fall 2.2s ease-in forwards;
}
@keyframes cft-fall {
  0%   { transform:translateY(-30px) rotate(0deg); opacity:0; }
  8%   { opacity:1; }
  100% { transform:translateY(320px) rotate(720deg); opacity:0; }
}
.welcome-gift {
  position:relative; z-index:1;
  display:block; margin:0 auto .2rem;
  animation:gift-pop .9s cubic-bezier(.34,1.56,.64,1) both;
  transform-origin:center bottom;
}
@keyframes gift-pop {
  0%   { transform:scale(.4) translateY(20px); opacity:0; }
  60%  { transform:scale(1.12) translateY(-6px); opacity:1; }
  100% { transform:scale(1) translateY(0); opacity:1; }
}
.welcome-title {
  position:relative; z-index:1;
  font-family:var(--fd, Heebo), system-ui, sans-serif;
  font-weight:800; font-size:1.45rem; letter-spacing:-.01em;
  margin:.2rem 0 .55rem;
  color:var(--ink, #1a1a1a);
}
.welcome-lead {
  position:relative; z-index:1;
  font-size:1rem; margin:0 0 .8rem;
  color:var(--ink, #1a1a1a);
}
.welcome-instr {
  position:relative; z-index:1;
  font-size:.95rem; margin:0 0 .3rem;
  color:var(--ink, #1a1a1a);
  font-weight:600;
}
.welcome-corner-hint {
  position:relative; z-index:1;
  font-size:.88rem; margin:0 0 .6rem;
  color:var(--muted, #555);
}
.welcome-publish-note {
  position:relative; z-index:1;
  font-size:.9rem; margin:0 0 .8rem;
  padding:.55rem .7rem;
  background:rgba(220, 38, 38, .06);
  border:1px solid rgba(220, 38, 38, .18);
  border-radius:8px;
  color:var(--ink, #1a1a1a);
  line-height:1.5;
}
.welcome-help {
  position:relative; z-index:1;
  font-size:.9rem; color:var(--muted, #555);
  margin:0;
  line-height:1.5;
}
.welcome-q-icon {
  display:inline-flex; align-items:center; justify-content:center;
  width:20px; height:20px; border-radius:50%;
  border:2px solid var(--primary, #059669);
  color:var(--primary, #059669);
  font-weight:800; font-size:.78rem; line-height:1;
  vertical-align:middle;
  margin:0 .15rem;
}
@media (prefers-reduced-motion:reduce) {
  .welcome-gift { animation:none; }
  .welcome-confetti .cft { animation:none; opacity:0; }
}

/* ===== Help walkthrough modal (?) =====
   Opened by showHelpModal in main.js. One step visible at a time with
   clickable dot navigation, prev/next chevrons, a step counter, and a
   link to the full HTML manual. Position persists in localStorage per
   uid so returning users land on the last-viewed step. */
.modal-dialog.help-dialog { max-width:440px; }
/* Brand-colored suffix in the help modal title. Rendered by wrapping the
   {b}...{/b} segment in the i18n string (see showHelpModal). Hardcoded
   PresentSimple green - stays consistent across whatever template palette the
   customer's site is using. */
.modal-dialog.help-dialog h3 .help-title-brand { color:#059669; }
.help-walkthrough { display:block; }
.help-step { min-height:130px; padding:.2rem 0 .8rem; }
.help-step-title {
  font-family:var(--fd, Heebo), system-ui, sans-serif;
  font-weight:800; font-size:1.15rem;
  margin:0 0 .55rem;
  color:var(--ink, #1a1a1a);
  text-align:center;
}
.help-step-body {
  font-size:.98rem; line-height:1.6;
  color:var(--ink, #1a1a1a);
  margin:0;
  /* Preserve `\n` in step bodies as visual line breaks. Steps without `\n`
     (most of them) still wrap naturally at whitespace - this only forces
     breaks where the source string explicitly asks for one. Step 2 uses
     this to put each bullet + inline demo on its own row. */
  white-space:pre-line;
}
.help-nav {
  display:flex; align-items:center; justify-content:space-between;
  gap:.7rem;
  margin-top:1rem;
  padding-top:.9rem;
  border-top:1px solid var(--line, #e5e7eb);
}
.help-nav-btn {
  display:inline-flex; align-items:center; justify-content:center;
  width:34px; height:34px; padding:0;
  border:1px solid var(--line, #e5e7eb);
  border-radius:50%;
  background:var(--surface, #fff);
  color:var(--ink, #1a1a1a);
  cursor:pointer;
  transition:background-color .15s, border-color .15s, transform .1s;
  flex:0 0 auto;
}
.help-nav-btn:hover:not(:disabled) { background:var(--soft, #f0f4f9); border-color:var(--primary, #059669); color:var(--primary, #059669); }
.help-nav-btn:disabled { opacity:.3; cursor:default; }
.help-nav-btn:focus-visible { outline:2px solid var(--primary, #059669); outline-offset:2px; }
/* Chevrons: rendered pointing L/R for LTR by the JS. Flip both for RTL so
   "prev" always points toward the reading start and "next" the opposite. */
html[dir="rtl"] .help-nav-btn svg { transform:scaleX(-1); }

.help-dots { display:flex; align-items:center; gap:.5rem; flex:1 1 auto; justify-content:center; }
.help-dot {
  width:8px; height:8px; padding:0;
  border:none; border-radius:50%;
  background:#cbd5e1;
  cursor:pointer;
  transition:background-color .15s, transform .15s, width .15s, height .15s;
}
.help-dot:hover { background:color-mix(in srgb, #059669 55%, #cbd5e1); }
.help-dot.active {
  width:14px; height:14px;
  background:#059669;
}
.help-dot:focus-visible { outline:2px solid #059669; outline-offset:3px; }

.help-step-counter {
  text-align:center;
  font-size:.78rem;
  color:var(--muted, #64748b);
  margin-top:.55rem;
  font-variant-numeric:tabular-nums;
}
.help-full-manual {
  display:block;
  text-align:center;
  margin-top:.4rem;
  font-size:.82rem;
  color:#059669;
  text-decoration:underline;
  text-underline-offset:2px;
}
.help-full-manual:hover { text-decoration:none; }

/* Inline demo widgets embedded in help-step bodies via {demo:X} tokens.
   Compact mockups of real edit-mode controls (WA-button + מוצג checkbox,
   section slide toggle, ↑↓ reorder, + add-section). Rendered next to the
   phrase describing them so the walkthrough text can point at what to look
   for without a separate legend. Colors match the actual chrome so users
   can visually connect the demo to the real thing on the page. */
.help-step-body .help-demo {
  display:inline-flex;
  align-items:center;
  vertical-align:middle;
  gap:.3rem;
  margin:0 .2rem;
  line-height:1;
}
/* WA button + מוצג checkbox - all grayscale, no chrome background. */
.help-demo-wa-pill {
  display:inline-flex; align-items:center; justify-content:center;
  padding:.12rem .5rem;
  border-radius:999px;
  background:#4B5563;
  color:#fff;
  font-family:var(--fui), sans-serif;
  font-size:.68rem; font-weight:700;
  line-height:1;
  white-space:nowrap;
}
.help-demo-wa-chk {
  display:inline-flex; align-items:center; gap:.2rem;
  font-size:.7rem; color:#4B5563; font-weight:600;
}
.help-demo-checkbox {
  display:inline-flex; align-items:center; justify-content:center;
  width:11px; height:11px;
  border:1.5px solid #4B5563;
  border-radius:2px;
  background:#4B5563;
  color:#fff;
  font-size:9px;
  font-weight:900;
  line-height:1;
}
.help-demo-checkbox::before {
  content:"✓";
  display:block;
  transform:translateY(-0.5px);
}
/* Section slide toggle (rendered in "on" state) */
.help-demo-switch {
  position:relative;
  display:inline-block;
  width:24px; height:14px;
  border-radius:14px;
  background:#6B7280;
}
.help-demo-switch-dot {
  position:absolute; top:2px;
  width:10px; height:10px;
  border-radius:50%;
  background:#fff;
  box-shadow:0 1px 2px rgba(0,0,0,.25);
}
html[dir="rtl"] .help-demo-switch-dot { left:2px; }
html:not([dir="rtl"]) .help-demo-switch-dot { right:2px; }

/* Up/down reorder arrows + add-section plus - miniaturized, grayscale. */
.help-demo-mini-btn {
  display:inline-flex; align-items:center; justify-content:center;
  width:18px; height:18px;
  border:1px solid #9CA3AF;
  background:#F3F4F6;
  color:#4B5563;
  font-family:var(--fui), sans-serif;
  font-size:.75rem; font-weight:800; line-height:1;
  border-radius:4px;
}
.help-demo-arrows { gap:.2rem; }
.help-demo-mini-btn-add {
  font-size:.9rem;
}

/* Publish checklist — wider modal + horizontal stepper. Cap the height so
   the step 2 (נגישות) questionnaire — which can grow to a long list of
   nested toggles — scrolls inside the modal rather than pushing the actions
   below the fold. The narrow custom scrollbar keeps the chrome minimal. */
.publish-checklist-dialog {
  max-width:760px;
  max-height:min(88vh,780px);
  display:flex;
  flex-direction:column;
  position:relative; /* anchor for the top-inline-start close X */
  font-family:'Open Sans', 'Assistant', system-ui, sans-serif;
  /* Force a fixed light theme regardless of the customer template palette
     underneath. Dark templates set --surface/--bg/--ink to dark values which
     otherwise bleed into this modal (dark inputs, invisible labels, etc.).
     Redeclaring the tokens here re-scopes them to all descendants that read
     var(--surface|--bg|--ink|--muted|--line|--primary). */
  --surface:#fff;
  --bg:#F8FAFC;
  --ink:#0F172A;
  --muted:#4B5563;
  --line:#E5E7EB;
  --primary:#0284C7;
  --primary-d:#075985;
  background:#fff;
  color:#0F172A;
}
/* Force Open Sans on all descendants of the publish modal - the wizard is
   system UI, so it should not inherit the customer template's --fui token. */
.publish-checklist-dialog input,
.publish-checklist-dialog textarea,
.publish-checklist-dialog select,
.publish-checklist-dialog button,
.publish-checklist-dialog h3,
.publish-checklist-dialog label,
.publish-checklist-dialog p,
.publish-checklist-dialog span,
.publish-checklist-dialog div {
  font-family:'Open Sans', 'Assistant', system-ui, sans-serif;
}
/* OTP code input keeps monospace for that "input a code" feel. */
.publish-checklist-dialog .p-otp-code {
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
}
/* Dialog header ("פרסום האתר" / "Publish site") - deep-blue accent so it
   reads as the same visual family as the step titles (.publish-step-title,
   .a11y-subtitle). Same color token used across the wizard for hierarchy. */
.publish-checklist-dialog > h3 { color:#075985; }
/* Close X in the top-left corner (visually) of the modal. In RTL "left" is
   the end of the inline axis, so we use inset-inline-end. In LTR contexts
   the same rule puts it on the right, mirroring the title on the other side. */
.modal-dialog .modal-close-btn {
  position:absolute;
  top:.9rem;
  inset-inline-end:.9rem;
  width:34px;
  height:34px;
  padding:0;
  border:none;
  background:transparent;
  color:#4B5563;
  border-radius:8px;
  cursor:pointer;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  transition:background .15s, color .15s;
  z-index:2;
}
.modal-dialog .modal-close-btn:hover {
  background:#F1F5F9;
  color:#0F172A;
}
.modal-dialog .modal-close-btn:focus-visible {
  outline:2px solid #0284C7;
  outline-offset:2px;
}
/* overflow-y:auto creates a clipping context. Inputs inside get a focus
   outline that would otherwise be sliced off on the inline edges. Add
   inline padding + negative inline margin so the modal-body keeps the same
   outer footprint but has an 8-px breathing gutter on the sides for
   outlines / outline-offsets to render into. */
.publish-checklist-dialog .modal-body {
  overflow-y:auto;
  scrollbar-width:thin;
  scrollbar-color:#c8d3dc transparent;
  padding-inline:.5rem;
  margin-inline:-.5rem;
}
.publish-checklist-dialog .modal-body::-webkit-scrollbar { width:6px; }
.publish-checklist-dialog .modal-body::-webkit-scrollbar-track { background:transparent; }
.publish-checklist-dialog .modal-body::-webkit-scrollbar-thumb { background:#c8d3dc; border-radius:6px; }
.publish-checklist-dialog .modal-body::-webkit-scrollbar-thumb:hover { background:#a4b2be; }

/* Accessibility questionnaire (publish step 2 — נגישות): slide toggles that
   reveal nested sections. Same visual language as .p-plan-toggle, but the
   layout starts flush-right so it reads as a checklist. Deeper indents shrink
   the font as you nest — matches the "smaller text" mockup. */
.publish-step-body .a11y-toggle,
.publish-step-body .a11y-mini {
  display:flex;
  align-items:center;
  gap:.6rem;
  cursor:pointer;
  font-weight:600;
  color:#075985;
  user-select:none;
  padding:.5rem 0;
}
.publish-step-body .a11y-mini { font-size:.9rem; font-weight:500; }
.publish-step-body .a11y-toggle input,
.publish-step-body .a11y-mini input { position:absolute; opacity:0; pointer-events:none; }
.publish-step-body .a11y-toggle .switch,
.publish-step-body .a11y-mini .switch {
  width:40px; height:22px; border-radius:22px;
  background:var(--line, #ccc);
  position:relative; transition:background .2s;
  flex:0 0 auto;
}
.publish-step-body .a11y-mini .switch { width:34px; height:19px; }
.publish-step-body .a11y-toggle .switch::after,
.publish-step-body .a11y-mini .switch::after {
  content:""; position:absolute; top:2px; right:2px;
  width:18px; height:18px; border-radius:50%;
  background:#fff; transition:transform .2s;
  box-shadow:0 1px 3px rgba(0,0,0,.3);
}
.publish-step-body .a11y-mini .switch::after { width:15px; height:15px; }
.publish-step-body .a11y-toggle input:checked + .switch,
.publish-step-body .a11y-mini input:checked + .switch { background:#0284C7; }
.publish-step-body .a11y-toggle input:checked + .switch::after { transform:translateX(-18px); }
.publish-step-body .a11y-mini input:checked + .switch::after { transform:translateX(-15px); }
.publish-step-body .a11y-toggle input:focus-visible + .switch,
.publish-step-body .a11y-mini input:focus-visible + .switch { outline:3px solid #0284C7; outline-offset:3px; }
/* Indented sub-sections. Each level tightens the font a notch — no
   vertical rule; the indent + shrinking type carries the hierarchy. */
.publish-step-body .a11y-sub  { margin-inline-start:1rem; font-size:.92rem; }
.publish-step-body .a11y-sub2 { margin-inline-start:1rem; font-size:.88rem; }
.publish-step-body .a11y-sub3 { margin-inline-start:1rem; font-size:.85rem; }
.publish-step-body .a11y-sub[hidden],
.publish-step-body .a11y-sub2[hidden],
.publish-step-body .a11y-sub3[hidden] { display:none; }
/* Sub-level toggle rows: same slide UI but smaller switch + tighter row so
   nested toggles read as details of the parent, not peer questions. */
.publish-step-body .a11y-sub .a11y-toggle,
.publish-step-body .a11y-sub .a11y-mini,
.publish-step-body .a11y-sub2 .a11y-mini,
.publish-step-body .a11y-sub3 .a11y-mini { padding:.3rem 0; font-size:inherit; font-weight:500; }
.publish-step-body .a11y-sub .a11y-toggle .switch,
.publish-step-body .a11y-sub .a11y-mini .switch,
.publish-step-body .a11y-sub2 .a11y-mini .switch,
.publish-step-body .a11y-sub3 .a11y-mini .switch { width:30px; height:17px; }
.publish-step-body .a11y-sub .a11y-toggle .switch::after,
.publish-step-body .a11y-sub .a11y-mini .switch::after,
.publish-step-body .a11y-sub2 .a11y-mini .switch::after,
.publish-step-body .a11y-sub3 .a11y-mini .switch::after { width:13px; height:13px; }
.publish-step-body .a11y-sub .a11y-toggle input:checked + .switch::after,
.publish-step-body .a11y-sub .a11y-mini input:checked + .switch::after,
.publish-step-body .a11y-sub2 .a11y-mini input:checked + .switch::after,
.publish-step-body .a11y-sub3 .a11y-mini input:checked + .switch::after { transform:translateX(-13px); }
/* Compact detail inputs inside the questionnaire — parking location, stairs
   count, floor number. Roughly one-third the height of the default modal
   input so they read as "just a detail" next to the toggle that revealed
   them. */
.publish-step-body .a11y-detail-input { padding:.25rem .6rem; font-size:.78rem; line-height:1.25; border-radius:8px; }
.publish-step-body .a11y-sub2 .field,
.publish-step-body .a11y-sub3 .field { margin-bottom:.4rem; }
/* Sub-title inside a11y questionnaire — plain heading, no toggle. */
.publish-step-body .a11y-subtitle { font-size:.95rem; font-weight:700; color:#075985; margin:.6rem 0 .2rem; }
/* Lead paragraph at the top of step 2 (נגישות). Rendered in the same
   deep-blue accent as the sub-titles so it reads as a section header. */
.publish-step-body .a11y-lead { color:#075985; font-weight:600; margin:0 0 .6rem; }

/* Publish step 6 (סיסמה + פרסום) — PresentSimple ToS review block: read-only
   textarea + agree checkbox + review-your-site-legal links. Gates the
   "פרסם" button on top of the password validation. */
/* Shared bold header used by both the ToS-review intro and the
   password-set intro so the two sections of step 6 read as peers. */
.publish-step-body .p-section-intro { margin:0 0 .35rem; font-weight:700; color:#1a1a1e; }
.publish-step-body .p-tos-intro { color:#1a1a1e; }
.publish-step-body .p-tos-textarea {
  width:100%; height:5.5rem; resize:none; font:inherit; font-size:.82rem;
  line-height:1.5; padding:.55rem .75rem; border:1px solid var(--line, #ddd);
  border-radius:8px; background:var(--bg, #f9f9f9); color:var(--ink, #1a1a1e);
  overflow-y:auto; overflow-x:hidden; white-space:pre-wrap;
  scrollbar-width:thin; scrollbar-color:#b8c0c8 transparent;
}
.publish-step-body .p-tos-textarea::-webkit-scrollbar { width:6px; }
.publish-step-body .p-tos-textarea::-webkit-scrollbar-track { background:transparent; }
.publish-step-body .p-tos-textarea::-webkit-scrollbar-thumb {
  background:#b8c0c8; border-radius:3px;
}
.publish-step-body .p-tos-textarea::-webkit-scrollbar-thumb:hover { background:#a4b2be; }
.publish-step-body .p-tos-textarea:focus-visible {
  outline:2px solid #0284C7; outline-offset:2px;
}
.publish-step-body .p-tos-agree {
  display:flex; align-items:center; justify-content:center; gap:.55rem;
  cursor:pointer; padding:.7rem 1rem; margin:.35rem auto .25rem;
  font-size:.95rem; color:var(--ink, #1a1a1e);
  user-select:none; font-weight:700;
  background:rgba(220, 38, 38, .06);
  border:1px solid rgba(220, 38, 38, .18); border-radius:8px;
  transition:background-color .2s, border-color .2s, color .2s;
}
.publish-step-body .p-tos-agree input[type="checkbox"] {
  width:1.2rem; height:1.2rem; flex:0 0 auto; cursor:pointer;
  accent-color:#0284C7;
}
.publish-step-body .p-tos-agree input[type="checkbox"]:focus-visible {
  outline:2px solid #0284C7; outline-offset:2px;
}
/* Flashed on when the user tries to submit without ticking the box —
   the primary button is disabled so the click can't proceed, but the
   red highlight tells them WHY nothing happened. Cleared as soon as
   they tick the box. */
.publish-step-body .p-tos-agree.needs-attention {
  border-color:#d54; background:#fff2f0; color:#b91c1c;
  animation:p-tos-shake .35s ease-in-out;
}
.publish-step-body .p-tos-agree.needs-attention input[type="checkbox"] {
  accent-color:#d54; outline:2px solid #d54; outline-offset:2px;
}
@keyframes p-tos-shake {
  0%,100% { transform:translateX(0); }
  25% { transform:translateX(-5px); }
  75% { transform:translateX(5px); }
}
/* Let clicks on the disabled publish button still register so we can
   flash the ToS row red (see needs-attention above). Without this,
   Chrome swallows pointer events on disabled buttons and the user
   gets no feedback at all. */
.publish-step-body .p-publish-btn[disabled] { pointer-events:auto; }
.publish-step-body .p-review-intro,
.publish-step-body .p-publish-note {
  margin:.4rem 0 .3rem; font-size:.88rem; color:#4B5563;
}
/* Password + confirm-password sit on one row on desktop, stack under 520px
   where a 2-col grid gets cramped inside the wizard modal. */
.publish-step-body .p-pw-row {
  display:grid; grid-template-columns:1fr 1fr; gap:.6rem 1rem;
}
@media (max-width:520px) {
  .publish-step-body .p-pw-row { grid-template-columns:1fr; }
}
.publish-step-body .p-review-links {
  list-style:none; padding:0; margin:0 0 .25rem;
  display:flex; flex-wrap:wrap; gap:.4rem 1.2rem;
}
.publish-step-body .p-review-links a {
  color:#075985; text-decoration:underline; font-size:.9rem;
}
.publish-step-body .p-review-links a:hover { color:#0369A1; }
.publish-step-body .p-review-links a:focus-visible {
  outline:2px solid #0284C7; outline-offset:2px; border-radius:3px;
}
/* Mobile: stack the review links one per row for easier tap targets. */
@media (max-width: 520px) {
  .publish-step-body .p-review-links { flex-direction:column; gap:.35rem; }
}
.publish-step-body .p-tos-sep {
  border:none; border-top:1px solid var(--line, #e5e5e5);
  margin:1rem 0 .8rem;
}

/* Publish step 3 (תוכנית) + standalone upgrade modal — two-cube plan
   comparison. Mirrors the .pricing-grid.two-col look on the home template
   but scoped to the publish modal so it can't leak. DOM order is [free,
   plus]; RTL grid puts the plus card on the visual left with the "selected"
   halo + "כן, אני רוצה" button. */
.publish-step-body .publish-plans { display:grid; grid-template-columns:repeat(2, 1fr); gap:1rem; margin:.4rem 0 1rem; padding-top:.8rem; }
.publish-step-body .publish-plan {
  background:var(--surface,#fff); border:1px solid var(--line,#ddd);
  border-radius:14px; padding:1.1rem 1rem 1rem;
  display:flex; flex-direction:column; position:relative;
  cursor:pointer; transition:border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.publish-step-body .publish-plan:hover { transform:translateY(-2px); }
.publish-step-body .publish-plan:focus-visible { outline:3px solid rgba(2,132,199,.35); outline-offset:2px; }
.publish-step-body .publish-plan.selected { border:1.5px solid #0284C7; box-shadow:0 14px 34px -16px rgba(2,132,199,.35); }
.publish-step-body .publish-plan-badge { position:absolute; top:-13px; left:50%; transform:translateX(-50%); background:#0284C7; color:#fff; font-weight:600; font-size:.72rem; padding:.28rem .8rem; border-radius:20px; white-space:nowrap; }
.publish-step-body .publish-plan h3 { font-size:1.05rem; margin:0 0 .3rem; color:var(--ink,#1a1a1a); text-align:center; }
/* Font-family intentionally omitted: the plan cube used to inherit the
   template's display font via var(--fd), which made the price look wildly
   different (Suez One on "food", Frank Ruhl Libre on "artistic", etc.). The
   plan cube is a modal-scoped UI element, so let it inherit .modal-dialog's
   font instead — consistent across every template. */
.publish-step-body .publish-plan-price { font-weight:800; font-size:1.55rem; color:#0284C7; line-height:1.1; margin:.1rem 0 .1rem; text-align:center; }
.publish-step-body .publish-plan-price small { font-size:.68rem; font-weight:500; color:var(--muted,#888); margin-inline-start:.15rem; }
.publish-step-body .publish-plan-price s { font-size:.75rem; font-weight:500; color:var(--muted,#888); text-decoration:line-through; margin-inline-end:.3rem; }
.publish-step-body .publish-plan-sub { color:var(--muted,#666); font-size:.75rem; margin:0 0 .8rem; text-align:center; }
.publish-step-body .publish-plan-sub-accent { color:#0284C7; font-weight:600; }
/* Friendly first-open intro slide for the publish wizard — greets the customer
   before the numbered stepper, reassures them publishing is free + fast,
   frames the optional plus upgrade as a no-obligation extra. Only rendered
   on the very first click; subsequent opens resume mid-wizard. */
.publish-step-body .p-intro { padding:.4rem 0 .1rem; }
.publish-step-body .p-intro-what-next { color:#0369A1; font-weight:700; font-size:1.1rem; margin:.4rem 0 .5rem; }
.publish-step-body .p-intro-lead { color:#0F172A; font-size:1.1rem; margin:.3rem 0 .6rem; line-height:1.55; }
.publish-step-body .p-intro-body { color:#334155; font-size:1.02rem; margin:.3rem 0 .9rem; line-height:1.6; }
.publish-step-body .p-intro-upgrade { color:#475569; font-size:.95rem; margin:.8rem 0 .4rem; line-height:1.55; padding:.8rem 1rem; background:#F1F5F9; border-radius:10px; border-inline-start:3px solid #0284C7; }
.publish-step-body .p-intro-actions { margin-top:auto; padding-top:1.2rem; display:flex; gap:.6rem; flex-wrap:wrap; justify-content:space-between; align-items:center; }
.publish-step-body .p-intro-actions .btn-primary { background:#0369A1; color:#fff; border:none; padding:.8rem 1.3rem; font-weight:700; font-size:1rem; border-radius:10px; cursor:pointer; transition:background .15s; }
.publish-step-body .p-intro-actions .btn-primary:hover { background:#075985; }
.publish-step-body .p-intro-actions .btn-primary:focus-visible { outline:3px solid #0284C7; outline-offset:2px; }
.publish-step-body .p-intro-actions .btn-ghost { background:#fff; color:#475569; border:1px solid #CBD5E1; padding:.8rem 1.3rem; font-weight:500; font-size:.95rem; border-radius:10px; cursor:pointer; transition:background .15s, border-color .15s; }
.publish-step-body .p-intro-actions .btn-ghost:hover { background:#F8FAFC; border-color:#94A3B8; }
.publish-step-body .p-intro-actions .btn-ghost:focus-visible { outline:2px solid #0284C7; outline-offset:2px; }
/* Intro-active state: promote the greeting from body text into the header
   row — centered on the same visual line as the close X, with symmetrical
   inline padding so it clears the X on both sides. Default h3 title
   ("פרסום האתר") is populated in JS with the headline copy for this state;
   here we just center + size it. No min-height on the dialog so the modal
   hugs its natural content instead of leaving dead space below the buttons. */
.publish-checklist-dialog.p-intro-active > h3 {
  text-align:center;
  color:#075985;
  font-weight:800;
  font-size:1.2rem;
  line-height:1.3;
  margin:0 3.2rem .8rem;
  padding-top:.15rem;
}
@media (max-width:520px) {
  /* Tighten the top of the modal on mobile: less dialog top-padding, smaller
     h3 bottom-margin, and .p-intro / what-next collapse their top gap so the
     greeting-→-body handoff feels snug on a small viewport. */
  .publish-checklist-dialog.p-intro-active { padding-top:1rem; }
  .publish-checklist-dialog.p-intro-active > h3 { font-size:1.05rem; margin:0 3rem .35rem; }
  .publish-checklist-dialog.p-intro-active .p-intro { padding-top:0; }
  .publish-step-body .p-intro-what-next { margin-top:.15rem; }
  .publish-step-body .p-intro-lead { font-size:1rem; }
  .publish-step-body .p-intro-body { font-size:.95rem; }
  .publish-step-body .p-intro-upgrade { font-size:.88rem; }
  /* Column stack. Explicit `order` puts primary (יאללה מפעילים) on top and
     ghost (רגע לא סיימתי) below it, regardless of DOM order — the ghost
     button is DOM-first so the desktop RTL start-alignment works, but on
     mobile we want the CTA to lead. */
  .publish-step-body .p-intro-actions { flex-direction:column; align-items:stretch; gap:.5rem; }
  .publish-step-body .p-intro-actions .btn-primary { order:1; width:100%; }
  .publish-step-body .p-intro-actions .btn-ghost { order:2; width:100%; }
}
/* Section title above the plan cards ("בחר/י מסלול") — same deep-blue accent
   as the a11y sub-titles for visual consistency across the wizard. Aligned
   to inline-start (right in HE/AR, left elsewhere) so it reads on the same
   edge as the dialog's own header, mirroring the close-X on the opposite
   inline-end corner. */
.publish-step-body .publish-step-title { color:#075985; font-weight:700; font-size:1.05rem; margin:.2rem 0 .5rem; text-align:start; }
.publish-step-body .publish-plan-feats { list-style:none; padding:0; margin:0 0 1rem; display:flex; flex-direction:column; gap:.35rem; font-size:.8rem; }
.publish-step-body .publish-plan-feats li { display:flex; gap:.4rem; align-items:flex-start; line-height:1.35; }
.publish-step-body .publish-plan-feats li::before { content:"✓"; color:#0284C7; font-weight:800; flex:0 0 auto; }
/* Small gray cancellation reassurance under the plus-card features. */
.publish-step-body .publish-plan-fineprint { margin:0; text-align:center; font-size:.72rem; color:#64748B; font-weight:400; }
.publish-step-body .publish-plan-btn { margin-top:auto; font:inherit; font-weight:600; background:#0284C7; color:#fff; border:none; border-radius:10px; padding:.6rem 1rem; cursor:pointer; transition:background .18s ease; }
.publish-step-body .publish-plan-btn:hover { background:#0369a1; }
.publish-step-body .publish-plan-btn:disabled { opacity:.55; cursor:not-allowed; }
@media (max-width:520px) {
  .publish-step-body .publish-plans { grid-template-columns:1fr; gap:1.6rem; padding-top:.4rem; }
}
/* Intro helper text that sits under the receives_public toggle when it flips
   on — small-print, muted, with a bolded lead-in line. */
.publish-step-body .a11y-intro { font-size:.78rem; line-height:1.45; margin:.4rem 0 .6rem; }
.publish-step-body .a11y-intro strong { color:#075985; font-weight:700; }
/* Inline row: a mini-toggle sits next to a compact number input on the same
   line (used for רמפה+מס' מדרגות and מעלית+מספר קומה). */
.publish-step-body .a11y-inline-row { display:flex; align-items:center; gap:1rem; flex-wrap:wrap; }
.publish-step-body .a11y-inline-row .a11y-mini { padding:0; margin:0; }
.publish-step-body .a11y-inline-field { display:inline-flex; align-items:center; gap:.4rem; margin:0; }
.publish-step-body .a11y-inline-field .meta { white-space:nowrap; }
.publish-step-body .a11y-inline-input { width:4rem; text-align:center; }

/* Stepper row: circles + connector lines on one continuous line; labels sit
   below each circle without breaking the connector. */
/* Labels are absolutely positioned below the circles (see .p-step-label
   below) so each `.p-step` column shrinks to the circle's width. That lets
   the flex `.p-step-line` between siblings fill the entire gap between
   two circles, giving a single continuous connector line — no visual
   gap between circle edge and line start. `padding-bottom` reserves
   space for the out-of-flow label. */
/* Upgrade mode: reuses the same publish-wizard dialog but only walks the
   plan + domain steps, so the stepper visual is pointless clutter. */
.publish-checklist-dialog.no-stepper .publish-stepper { display:none; }
.publish-stepper { display:flex; align-items:flex-start; gap:0; margin:0 0 1.4rem; padding:.2rem 0 1.6rem; flex-wrap:nowrap; }
.publish-stepper .p-step { display:flex; flex-direction:column; align-items:center; flex:0 0 auto; position:relative; }
.publish-stepper .p-step-circle { width:34px; height:34px; border-radius:50%; background:#fff; border:2px solid #BAE6FD; color:#075985; display:inline-flex; align-items:center; justify-content:center; font-weight:700; font-size:.95rem; transition:all .2s; position:relative; z-index:1; }
.publish-stepper .p-step.active .p-step-circle { background:#0284C7; color:#fff; border-color:#0284C7; box-shadow:0 0 0 4px rgba(2,132,199,.15); }
/* Done steps + their trailing connector line share the same accent-blue as
   the active step (#0284C7). Active is still distinguishable — it carries
   a halo box-shadow and shows the step number, while done shows ✓. */
.publish-stepper .p-step.done .p-step-circle { background:#0284C7; color:#fff; border-color:#0284C7; }
/* Optional step 5 that was skipped (no paid-plan opt-in) — a plain gray
   circle with no ✓ so it visually reads "did not take this step" rather
   than "completed". */
.publish-stepper .p-step.skipped .p-step-circle {
  background:#E5E7EB;
  color:#9CA3AF;
  border-color:#E5E7EB;
}
.publish-stepper .p-step-label {
  position:absolute;
  top:100%;
  left:50%;
  transform:translateX(-50%);
  margin-top:.35rem;
  font-size:.72rem;
  color:#075985;
  text-align:center;
  line-height:1.2;
  white-space:nowrap;
}
.publish-stepper .p-step.active .p-step-label { font-weight:700; }
/* Past steps (done or skipped) are click-to-return - cursor + subtle hover
   lift on the circle, plus a keyboard focus ring for a11y. Active/future
   steps stay non-interactive. */
.publish-stepper .p-step.clickable { cursor:pointer; }
.publish-stepper .p-step.clickable .p-step-circle { transition:transform .15s, box-shadow .15s; }
.publish-stepper .p-step.clickable:hover .p-step-circle { transform:scale(1.08); box-shadow:0 3px 10px -3px rgba(2,132,199,.4); }
.publish-stepper .p-step.clickable:hover .p-step-label { text-decoration:underline; }
.publish-stepper .p-step.clickable:focus-visible { outline:none; }
.publish-stepper .p-step.clickable:focus-visible .p-step-circle {
  box-shadow:0 0 0 4px rgba(2,132,199,.35);
}
/* First (rightmost in RTL) and last (leftmost) steps' labels can extend past
   the modal edge and get clipped - "פרטי התקשרות" showed as "טי התקשרות".
   Anchor those labels to the step's outer edge so overflow always goes toward
   the stepper's interior, never past the modal boundary. */
.publish-stepper .p-step:first-child .p-step-label {
  left:auto;
  right:0;
  transform:none;
  text-align:end;
}
.publish-stepper .p-step:last-child .p-step-label {
  left:0;
  right:auto;
  transform:none;
  text-align:start;
}
/* Connector line: sits at the vertical center of the 34px circle (17px
   from top) and now stretches the FULL gap between neighboring circles
   without any negative-margin hack. */
.publish-stepper .p-step-line { flex:1; height:2px; background:#BAE6FD; min-width:14px; margin-top:17px; align-self:flex-start; }
.publish-stepper .p-step-line.done { background:#0284C7; }
/* Persistent plan-affirmation strip that lives under the numbered circles
   and stays visible across all wizard steps. `data-state` flips between
   `free` (green) and `paid` (red) as the customer picks a plan at step 4.
   On desktop, the strip is lifted out of the body flow and pinned to the
   inline-end of the dialog title row (opposite the "פרסום האתר" heading)
   so both read on the same line. On mobile it stays as a stacked row
   between the stepper and the step body. */
.publish-plan-strip {
  margin:.2rem 0 1.2rem;
  padding:.55rem .85rem;
  border-radius:.55rem;
  text-align:center;
  font-size:.9rem;
  font-weight:600;
  line-height:1.35;
  border:1px solid transparent;
}
.publish-plan-strip[data-state="free"] {
  color:#065F46; background:#ECFDF5; border-color:#A7F3D0;
}
.publish-plan-strip[data-state="paid"] {
  color:#7F1D1D; background:#FEF2F2; border-color:#FECACA;
}
@media (min-width:701px) {
  .publish-checklist-dialog .publish-plan-strip {
    position:absolute;
    top:1.6rem;
    /* Clear the .modal-close-btn (34px wide at .9rem inset-inline-end,
       reaching ~3.05rem into the dialog). Anchor the strip past that
       and cap its width so it doesn't crowd the title on the opposite
       side of the row. */
    inset-inline-end:3.5rem;
    inset-inline-start:auto;
    margin:0;
    padding:.35rem .7rem;
    font-size:.82rem;
    max-width:calc(100% - 14rem);
    z-index:2;
  }
  /* Desktop: compress the vertical rhythm of the wizard so the intro row
     (e.g. "בחירת או חיבור דומיין ...") sits close to the numbered circles
     instead of leaving a wide dead band between the stepper and the step
     body. Mobile keeps its default spacing (label rows need the room). */
  .publish-checklist-dialog .publish-stepper {
    margin:0 0 .6rem;
    padding:.15rem 0 1.1rem;
  }
  .publish-checklist-dialog .publish-step-body .publish-step-title {
    margin:0 0 .3rem;
  }
  .publish-checklist-dialog .publish-step-body .p-plan > p {
    margin:.1rem 0 .3rem;
  }
}
.publish-step-body .field { margin-bottom:.8rem; }
.publish-step-body .modal-actions { margin-top:1.2rem; }
/* Mobile: step-6 has three CTAs (upgrade cta, back, publish) that get
   squished side-by-side on narrow screens. Stack them vertically, full-
   width, so each button reads clearly and the primary "publish" CTA sits
   at the top for thumb reach. `.p-publish-btn` (inline-flex column with
   its own free badge) stays as-is - `width:100%` just gives it the row. */
@media (max-width: 700px) {
  .publish-step-body .modal-actions {
    flex-direction: column;
    align-items: stretch;
    gap: .55rem;
  }
  .publish-step-body .modal-actions > button {
    width: 100%;
  }
  /* Reorder: primary publish first, then upgrade CTA, then back (least-
     used). Uses `order` so we don't touch the DOM order relied on by the
     desktop flex-row layout. */
  .publish-step-body .modal-actions #pFinalBtn { order: 1; }
  .publish-step-body .modal-actions .p-upgrade-cta { order: 2; margin-inline-end: 0; }
  .publish-step-body .modal-actions #pBack { order: 3; }
}

/* ===== Publish - Step 1 (פרטי התקשרות) =====
   Colors here are the wizard's own system palette (blue #075985, green
   #0E7A56, sky-100 tints), NOT the customer template's --primary. The wizard
   is chrome around the site, so it should look consistent regardless of which
   template/palette the customer picked. All fg/bg pairs verified ≥AA:
   - #075985 on #FFF        = 7.24:1  (AAA normal)   → headline
   - #FFFFFF on #0E7A56     = 5.26:1  (AA normal)    → Continue button
   - #FFFFFF on #0B6045     = 6.30:1  (AAA normal)   → Continue hover
   - #075985 on #E0F2FE     = 6.75:1  (AAA normal)   → recommend pill body
   - #4B5563 on #FFF        = 8.59:1  (AAA normal)   → subtitle              */
.publish-step-body .p-step1-headline {
  color:#075985;
  font-size:clamp(1.35rem,3.8vw,1.75rem);
  font-weight:800;
  line-height:1.25;
  margin:.2rem 0 .35rem;
  text-wrap:balance;
}
.publish-step-body .p-step1-subtitle {
  color:#4B5563;
  font-size:.95rem;
  margin:0 0 .5rem;
}
/* Unified context paragraph explaining why both fields are collected. Sits
   above the two-column grid so it applies to both channels at once. Text
   uses the same body color as the modal (--ink token) for comfortable read. */
.publish-step-body .p-step1-context {
  color:#374151;
  font-size:.9rem;
  line-height:1.6;
  margin:0 0 1.3rem;
}
/* Compact text-link used inside OTP-sent meta ("שינוי אימייל" / "שינוי נייד").
   #075985 on white = 7.24:1 (AAA). */
.publish-step-body .p-edit-link {
  background:transparent;
  border:none;
  color:#075985;
  text-decoration:underline;
  cursor:pointer;
  padding:0;
  font:inherit;
  font-size:.85rem;
  margin-inline-start:.3rem;
}
.publish-step-body .p-edit-link:hover { color:#0369A1; }
.publish-step-body .p-edit-link:focus-visible {
  outline:2px solid #0284C7;
  outline-offset:2px;
  border-radius:3px;
}
/* "שנה" link sits inside the small ✓ מאומת badge - match its size so the
   row of "אימייל ✓ מאומת שנה" reads as one visual unit. */
.publish-step-body .p-verified-mark .p-edit-link {
  font-size:.78rem;
  margin-inline-start:.25rem;
}
.publish-step-body .p-verified-mark {
  color:#0E7A56;
  font-size:.78rem;
  font-weight:600;
  margin-inline-start:.4rem;
  white-space:nowrap;
}
/* Compact "שלח קוד" trigger inside .p-otp-row. Soft-blue so it reads as a
   secondary action next to the primary green Continue button below.
   #075985 on #E0F2FE = ~6.3:1 (AA normal); border keeps it discoverable. */
.publish-step-body .p-otp-row .p-send-btn {
  flex:0 0 auto;
  padding:.55rem 1rem;
  border-radius:10px;
  border:1px solid #BAE6FD;
  background:#E0F2FE;
  color:#075985;
  font:inherit;
  font-weight:600;
  font-size:.9rem;
  cursor:pointer;
  white-space:nowrap;
  transition:background .12s, border-color .12s;
}
.publish-step-body .p-otp-row .p-send-btn:hover:not(:disabled) {
  background:#BAE6FD;
  border-color:#7DD3FC;
}
.publish-step-body .p-otp-row .p-send-btn:focus-visible {
  outline:2px solid #0284C7;
  outline-offset:2px;
}
.publish-step-body .p-otp-row .p-send-btn:disabled {
  opacity:.55;
  cursor:not-allowed;
}
/* Soft-blue info pill. Sky-100 background with the same blue text/accent as
   the headline - reads as a "hint" without alarming. */
.publish-step-body .p-step1-recommend {
  color:#075985;
  background:#E0F2FE;
  border-inline-start:3px solid #0284C7;
  padding:.6rem .85rem;
  border-radius:8px;
  font-size:.9rem;
  margin:.4rem 0 .9rem;
  line-height:1.5;
}
/* Read-only display of the strip's email/phone value in step 1. */
.publish-step-body .p-step1-value {
  margin:.3rem 0 0;
  padding:.55rem .75rem;
  background:#F1F5F9;
  border-radius:8px;
  font-size:.95rem;
  color:#0F172A;
  direction:ltr;
  text-align:start;
  min-height:1.5rem;
}
.publish-step-body .p-step1-value.p-step1-missing {
  color:#6B7280;
  font-style:italic;
  direction:rtl;
}
/* Actions row holds two buttons on top of each other (mobile) or side-by-side
   (desktop). בצע אימות is the primary CTA in blue (needs action from user),
   Continue is in green (the finalize/publish direction). */
.publish-step-body .p-step1-actions { justify-content:stretch; flex-wrap:wrap; gap:.6rem; }
.publish-step-body .p-verify-all-btn {
  flex:1 1 100%;
  width:100%;
  padding:.9rem 1.2rem;
  font-size:1rem;
  font-weight:700;
  border-radius:12px;
  background:#0369A1;
  color:#fff;
  border:none;
  cursor:pointer;
  transition:background .15s;
}
.publish-step-body .p-verify-all-btn:hover:not(:disabled) { background:#075985; }
.publish-step-body .p-verify-all-btn:disabled { opacity:.65; cursor:not-allowed; }
.publish-step-body .p-verify-all-btn:focus-visible {
  outline:3px solid #0284C7;
  outline-offset:3px;
}
/* Full-width action button - blue to match the "active step" circle color in
   the stepper (#0284C7 base, darkened to #0369A1 for AA contrast on button
   text). Same blue applies whether the button reads "בצע אימות" or "המשך",
   because the mental model is "advance this step", not "success/finalize".
   AA math: white on #0369A1 = 5.87:1 (AA normal); hover #075985 = 7.24:1 (AAA). */
.publish-step-body .p-continue-btn.btn-primary,
.publish-step-body .p-continue-btn {
  flex:1 1 100%;
  width:100%;
  padding:.95rem 1.2rem;
  font-size:1.05rem;
  font-weight:700;
  border-radius:12px;
  background:#0369A1;
  color:#fff;
  border:none;
  cursor:pointer;
  transition:background .15s;
}
.publish-step-body .p-continue-btn:hover:not(:disabled):not(.looks-disabled) { background:#075985; }
/* Small fineprint sub-line inside the primary CTA (e.g. "קוד אימות יישלח…"
   under "המשך.י לאימות אימייל"). Renders as a translucent second line so
   the main label stays the dominant hit target. */
.publish-step-body .p-continue-btn .p-action-btn-sub { display:block; margin-top:.35rem; font-size:.72rem; font-weight:400; color:rgba(255,255,255,.8); line-height:1.35; }
/* Skip button next to the OTP verify button: rendered as an underlined
   text link so the user reads it as an off-ramp, not a peer of the primary
   action. The [data-tip] hover balloon explains what skipping means. */
.publish-step-body .p-otp-skip-link { text-decoration:underline; text-underline-offset:3px; }
/* Small gray reassurance line below the "פרסם את האתר" button on step 5,
   telling the user an SMS with the site details is on the way. */
/* Publish button on step 5 stacks a bold primary label on top and a small
   sub-note ("An SMS will be sent...") below, so the informational text
   travels with the CTA instead of being a stray line under the button. */
.publish-step-body .p-publish-btn { display:inline-flex; flex-direction:column; align-items:center; line-height:1.2; padding-block:.65rem; gap:.25rem; }
.publish-step-body .p-publish-btn-main { font-weight:700; }
.publish-step-body .p-publish-btn-sub { font-size:.72rem; font-weight:400; opacity:.85; }
.publish-step-body .p-publish-btn-free-badge {
  display:inline-block; font-size:.7rem; font-weight:600; letter-spacing:.02em;
  padding:.1rem .5rem; border-radius:999px;
  background:rgba(255,255,255,.22); color:#fff;
}
.publish-step-body .p-continue-btn:disabled,
.publish-step-body .p-continue-btn.looks-disabled {
  background:#94A3B8;
  color:#F1F5F9;
  cursor:not-allowed;
}
/* Brief horizontal shake when clicking the visually-disabled continue button
   with invalid inputs - makes it clear the click registered and there's a
   reason for the block (which is written to #pErr immediately above). */
@keyframes pWizBtnShake {
  0%, 100% { transform:translateX(0); }
  20% { transform:translateX(-6px); }
  40% { transform:translateX(6px); }
  60% { transform:translateX(-4px); }
  80% { transform:translateX(4px); }
}
.publish-step-body .p-continue-btn.shake { animation:pWizBtnShake .35s ease-in-out; }
.publish-step-body .p-continue-btn:focus-visible {
  outline:3px solid #0284C7;
  outline-offset:3px;
}
/* All "המשך" primary buttons across the remaining publish steps (step 3
   נגישות, step 4 תוכנית, step 5 דומיין) - same active-step blue for visual
   consistency. Excludes:
     • .p-continue-btn / .p-action-btn (step 1's dedicated mode-swapping button)
     • #pFinalBtn (step 6 "הפעלת האתר" - final action, keeps its own color). */
.publish-step-body .modal-actions .btn-primary:not(.p-continue-btn):not(.p-action-btn):not(#pFinalBtn) {
  background:#0369A1;
  color:#fff;
  border:none;
}
.publish-step-body .modal-actions .btn-primary:not(.p-continue-btn):not(.p-action-btn):not(#pFinalBtn):hover:not(:disabled) {
  background:#075985;
}
.publish-step-body .modal-actions .btn-primary:not(.p-continue-btn):not(.p-action-btn):not(#pFinalBtn):focus-visible {
  outline:3px solid #0284C7;
  outline-offset:2px;
}
/* Small "(אופציונלי)" hint after the שם העסק label. */
.publish-step-body .p-field-optional {
  color:#6B7280;
  font-size:.78rem;
  font-weight:400;
  margin-inline-start:.3rem;
}
/* Receives-public toggle block above the המשך button in step 1. Slight
   top separation from the error paragraph so the toggle stands as its
   own decision, not a footnote. */
.publish-step-body .p-step1-receives {
  margin:1rem 0 .4rem;
  padding:.7rem .85rem;
  background:#F1F5F9;
  border-radius:8px;
}
.publish-step-body .p-step1-receives .a11y-toggle { margin:0; }
.publish-step-body .p-step1-receives .meta {
  margin:.4rem 0 0;
  font-size:.82rem;
  color:#4B5563;
  line-height:1.5;
}

/* Two-column layout for email + phone on desktop. Each column keeps its own
   OTP field directly below the input so revealing an OTP box doesn't shift
   the other column. Stacks to a single column below 720px viewport width. */
.publish-step-body .p-step1-grid {
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:1rem;
  margin-bottom:.6rem;
}
.publish-step-body .p-step1-col { display:flex; flex-direction:column; }
/* display:flex above overrides the UA `[hidden]{display:none}` default -
   without this rule, JS toggling `col.hidden` had no visual effect. */
.publish-step-body .p-step1-col[hidden] { display:none; }
@media (max-width:720px) {
  .publish-step-body .p-step1-grid { grid-template-columns:1fr; gap:0; }
}

/* Entity-type block (אדם פרטי / חברה בע"מ) sitting in the second column of
   the top grid. Label mimics the standard field label so it reads at the
   same weight as "שם מלא" beside it. Radios stack inline in an accessible
   pill row that visually groups the two options. */
.publish-step-body .p-entity-label {
  display:block;
  font-weight:600;
  color:#1F2937;
  margin-bottom:.35rem;
  font-size:.95rem;
}
.publish-step-body .p-entity-radio {
  display:flex;
  gap:.5rem;
  align-items:stretch;
}
.publish-step-body .p-entity-radio label {
  flex:1;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:.4rem;
  padding:.55rem .8rem;
  border:1px solid #CBD5E1;
  border-radius:8px;
  background:#F8FAFC;
  cursor:pointer;
  transition:background .12s, border-color .12s;
  font-size:.9rem;
  color:#334155;
}
.publish-step-body .p-entity-radio label:hover { background:#EFF6FF; }
.publish-step-body .p-entity-radio input {
  position:absolute; opacity:0; pointer-events:none;
}
.publish-step-body .p-entity-radio label:has(input:checked) {
  background:#E0F2FE;
  border-color:#0284C7;
  color:#075985;
  font-weight:600;
}
/* Explicit checkmark on the selected pill so the "which is picked" state
   isn't left to background-color alone (users missed the fill). */
.publish-step-body .p-entity-radio label:has(input:checked)::before {
  content:"✓";
  font-weight:800;
  color:#0284C7;
  margin-inline-end:.15rem;
}
/* Required-field marker on the label. Company fields get this the moment
   חברה בע"מ is selected (JS toggles the [data-required] on the .field). */
.publish-step-body .field[data-required] > label::after {
  content:" *";
  color:#DC2626;
  font-weight:700;
}
.publish-step-body .p-entity-radio label:has(input:focus-visible) {
  outline:3px solid #0284C7;
  outline-offset:2px;
}

@media (max-width:480px) {
  .publish-step-body .p-step1-headline { font-size:1.25rem; }
  .publish-step-body .p-step1-subtitle { font-size:.9rem; margin-bottom:1rem; }
  .publish-step-body .p-continue-btn { padding:.85rem 1rem; font-size:1rem; }
}
.publish-step-body .meta,
.modal-dialog .meta { color:var(--muted,#888); font-size:.78rem; }
.publish-step-body .err { color:#d54; font-size:.85rem; margin:.4rem 0; }
/* Input + inline "שלח" button used by the OTP fields (publish step 1 for
   both email and phone, and the standalone WA-number-change modal). */
.publish-step-body .p-otp-row { display:flex; gap:.5rem; align-items:stretch; }
.publish-step-body .p-otp-row input { flex:1 1 auto; min-width:0; }
.publish-step-body .p-otp-row button { flex:0 0 auto; padding:.6rem 1.2rem; border-radius:10px; border:none; font:inherit; font-weight:600; cursor:pointer; white-space:nowrap; }
.publish-step-body .p-otp-row button:disabled { cursor:not-allowed; opacity:.55; }
.publish-step-body .p-otp-row .btn-primary { background:var(--primary,#08c); color:#fff; }
/* 6-digit OTP code entry: narrow enough to just fit six spaced digits so it
   reads as a code box rather than a full-width text field. type="tel" on the
   input pops the numeric keypad on mobile. */
.publish-step-body .p-otp-code {
  width:auto;
  max-width:8em;
  text-align:center;
  letter-spacing:.35em;
  font-family:ui-monospace, SFMono-Regular, Menlo, monospace;
  padding-inline-end:.6rem;
}

/* ===== Publish step 5: paid-plan / domain opt-in =====
   Compact layout: single-line title, 2-column feature grid (3 items each),
   centered toggle, revealed domain row below. */
.p-plan { display:flex; flex-direction:column; gap:.8rem; }

.p-plan-title {
  font-family:var(--fui, Heebo), sans-serif;
  font-size:1rem;
  font-weight:700;
  color:var(--ink, #1a1a1a);
  text-align:center;
  margin:0;
  line-height:1.35;
}

.p-plan-feats {
  list-style:none;
  margin:0;
  padding:0;
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:.15rem 1.2rem;
  font-size:.82rem;
  color:var(--muted, #444);
}
.p-plan-feats li { padding:0; line-height:1.4; position:relative; padding-inline-start:1.1rem; }
.p-plan-feats li::before {
  content:"✓";
  position:absolute;
  inset-inline-start:0;
  top:0;
  color:#0E7A56;
  font-weight:700;
  font-size:.9rem;
}

.p-plan-toggle {
  display:flex;
  align-items:center;
  justify-content:center;
  gap:.6rem;
  cursor:pointer;
  font-weight:600;
  color:#075985;
  user-select:none;
  padding:.35rem 0;
}
.p-plan-toggle input { position:absolute; opacity:0; pointer-events:none; }
.p-plan-toggle .switch {
  width:40px; height:22px; border-radius:22px;
  background:var(--line, #ccc);
  position:relative; transition:background .2s;
  flex:0 0 auto;
}
.p-plan-toggle .switch::after {
  content:""; position:absolute; top:2px; right:2px;
  width:18px; height:18px; border-radius:50%;
  background:#fff; transition:transform .2s;
  box-shadow:0 1px 3px rgba(0,0,0,.3);
}
.p-plan-toggle input:checked + .switch { background:#0284C7; }
.p-plan-toggle input:checked + .switch::after { transform:translateX(-18px); }
.p-plan-toggle input:focus-visible + .switch { outline:3px solid #0284C7; outline-offset:3px; }

/* Step 5 - tighten the paid-flow intro paragraph and the "what is a
   domain?" explainer + current-URL display. Sits between the intro
   paragraph and the radio choices. */
.publish-step-body .p-plan > p {
  margin:.15rem 0 .35rem;
  line-height:1.3;
}
.p-domain-what-is {
  font-size:.82rem; color:#334155; margin:.15rem 0 .2rem;
  padding:.3rem .55rem; background:#F1F5F9; border-radius:.4rem;
  line-height:1.3;
}
.p-domain-current-url {
  display:flex; align-items:center; flex-wrap:wrap;
  column-gap:.35rem; row-gap:.1rem;
  margin:.1rem 0 .45rem;
  font-size:.85rem; color:#334155;
  line-height:1.25;
}
.p-domain-current-url-label { font-weight:600; }
.p-domain-current-url-link {
  color:#0284C7; font-weight:600; text-decoration:none;
  word-break:break-all;
}
.p-domain-current-url-link:hover { text-decoration:underline; }

/* Step 5 - small pros lists under each radio option so the free vs
   own-domain tradeoff reads at a glance. Uses check-mark bullets via
   ::marker so RTL and LTR both render cleanly. */
.p-domain-pros {
  list-style:none;
  margin:.15rem 0 .6rem 2rem;
  padding:0;
  font-size:.82rem;
  color:#475569;
  line-height:1.45;
}
.p-domain-pros li {
  position:relative;
  padding-inline-start:1.1rem;
  margin-block:.1rem;
}
.p-domain-pros li::before {
  content:"✓";
  position:absolute;
  inset-inline-start:0;
  color:#059669;
  font-weight:700;
}
/* Step 5 - side-by-side comparison cards for the two main choices
   (own domain vs stay on free URL). opt2 (existing domain) stays as a
   full-width row below the pair. On mobile the cards stack vertically. */
.p-domain-cards-row {
  display:grid;
  grid-template-columns:1fr 1fr;
  gap:.75rem;
  margin-bottom:.7rem;
}
.p-domain-card {
  display:flex; flex-direction:column;
  border:1px solid #BAE6FD;
  border-radius:12px;
  background:#fff;
  padding:.65rem .8rem;
}
.p-domain-card:has(input:checked) {
  border-color:#0284C7;
  background:#F0F9FF;
  box-shadow:0 0 0 3px rgba(2,132,199,.12);
}
.p-domain-card .p-domain-choice {
  border:none; padding:0; background:transparent; margin-bottom:.3rem;
}
.p-domain-card .p-domain-choice:hover { background:transparent; }
.p-domain-card .p-domain-pros { margin-inline-start:.4rem; margin-block:.35rem; }
@media (max-width:700px) {
  .p-domain-cards-row { grid-template-columns:1fr; gap:.55rem; }
}

/* "Have existing domain" option: full-width row below the two main cards,
   less prominent (smaller font, subdued border) so the two comparison cards
   remain the primary CTAs. */
.p-domain-choice.p-domain-choice-existing {
  font-size:.85rem;
  border-color:#E2E8F0;
  background:#F8FAFC;
}

/* Step 5 radio-choice group ("I want a domain" / "I already own one" /
   "keep current URL"). Each choice sits over its inline reveal so the
   revealed input row is visually attached to the selected radio. */
.p-domain-choices {
  display:flex; flex-direction:column; gap:.55rem;
  border:none; padding:0; margin:0;
}
.p-domain-choice {
  display:flex; align-items:flex-start; gap:.55rem;
  padding:.65rem .85rem;
  border:1px solid #BAE6FD;
  border-radius:12px;
  background:#fff;
  cursor:pointer;
  transition:border-color .15s, box-shadow .15s, background .15s;
  font-size:.95rem;
  line-height:1.35;
}
.p-domain-choice:hover { border-color:#0284C7; background:#F0F9FF; }
.p-domain-choice:has(input:checked) {
  border-color:#0284C7;
  background:#F0F9FF;
  box-shadow:0 6px 18px -12px rgba(2,132,199,.5);
}
.p-domain-choice input[type="radio"] {
  margin:.15rem 0 0;
  flex:0 0 auto;
  cursor:pointer;
  accent-color:#0284C7;
}
.p-domain-choice input[type="radio"]:disabled { cursor:not-allowed; }
/* Fade the radio + label copy only (not the whole row) so the "מקצועי
   פלוס" upgrade pill sitting inside a disabled row stays fully visible. */
.p-domain-choice:has(input:disabled) { cursor:not-allowed; }
.p-domain-choice:has(input:disabled) > input[type="radio"],
.p-domain-choice:has(input:disabled) > span { opacity:.55; }
.p-domain-choice span { flex:1 1 auto; }
/* Inline hint chip showing the origin domain scraped from the URL-import
   flow, e.g. "יש לי דומיין קיים (b2cprint.co.il)". Small + muted so it
   doesn't compete with the primary label. dir=ltr because domains are
   always Latin. */
.p-domain-choice .p-domain-origin-hint {
  display:inline-block;
  font-size:.78rem;
  font-weight:500;
  color:#0369A1;
  background:#F0F9FF;
  border:1px solid #BAE6FD;
  border-radius:999px;
  padding:.1rem .5rem;
  margin-inline-start:.35rem;
  vertical-align:baseline;
  white-space:nowrap;
}
/* "מקצועי פלוס" pill next to disabled paid-only options → click jumps
   back to step 4 (plan). */
.p-domain-choice .p-domain-plus-pill {
  flex:0 0 auto; align-self:center;
  font:600 .78rem/1 var(--fui, Heebo, system-ui, sans-serif);
  padding:.35rem .7rem; border-radius:999px;
  background:#0284C7; color:#fff; border:none;
  cursor:pointer;
  transition:background .15s, transform .1s;
  white-space:nowrap;
}
.p-domain-choice .p-domain-plus-pill:hover { background:#0369A1; }
.p-domain-choice .p-domain-plus-pill:active { transform:scale(.97); }
.p-domain-choice .p-domain-plus-pill:focus-visible {
  outline:2px solid #0284C7; outline-offset:2px;
}
/* Inline reveal panel below a selected radio - the search row or the
   existing-domain input row. Padded to sit indented under the radio bubble. */
.p-domain-reveal {
  padding:.2rem .3rem .1rem calc(.85rem + 1.2rem);
  margin-top:-.15rem;
}
.p-domain-reveal[hidden] { display:none; }
.p-domain-reveal .p-existing-domain-ack {
  display:block;
  color:#0E7A56;
  font-weight:600;
  font-size:.9rem;
  padding:.4rem .1rem 0;
}

.p-domain-box { display:flex; flex-direction:column; gap:.4rem; }
/* .p-domain-box uses display:flex which outranks the browser's default
   `[hidden] { display: none }` — restore hidden semantics explicitly so the
   domain row only appears when the "כן, אני רוצה" toggle is on. */
.p-domain-box[hidden] { display:none; }
/* Grayed-out state when step 5 is entered without a paid plan (step 4 was
   skipped). Dims the whole box and blocks pointer interactions on the
   read-only inputs. */
.p-domain-box.is-disabled { opacity:.55; pointer-events:none; }
.p-domain-box.is-disabled input,
.p-domain-box.is-disabled select,
.p-domain-box.is-disabled button { cursor:not-allowed; }
.p-domain-row {
  display:flex; gap:.4rem; align-items:stretch; flex-wrap:wrap;
}
.p-domain-row input[type="text"] {
  flex:1 1 160px; min-width:0;
  font:inherit; font-size:.95rem;
  padding:.55rem .8rem;
  border:1px solid #BAE6FD;
  border-radius:999px;
  background:#fff;
  color:#075985;
  direction:ltr;
  text-align:left;
}
.p-domain-row input[type="text"]:focus { outline:2px solid #0284C7; outline-offset:1px; }
.p-domain-row select {
  flex:0 0 auto;
  font:inherit; font-size:.95rem;
  padding:.55rem 1rem .55rem .7rem;
  border:1px solid #BAE6FD;
  border-radius:999px;
  background:#fff;
  color:#075985;
  cursor:pointer;
  direction:ltr;
}
.p-domain-row button {
  flex:0 0 auto;
  padding:.55rem 1.4rem;
  font-size:.9rem;
  border-radius:999px;
  display:inline-flex;
  align-items:center;
  gap:.5rem;
  cursor:pointer;
}
.p-domain-row button.is-loading { cursor:progress; opacity:.85; }
.p-domain-row button:disabled { cursor:not-allowed; }
/* The "רישום ומעבר לתוכנית" button only appears when a domain is confirmed
   available — paint it green (positive action / go-ahead), overriding the
   default modal-primary blue. */
#pDomainRegister { background:#0E7A56; color:#fff; }
#pDomainRegister:hover { background:#0c6a4a; }
#pDomainRegister:disabled { background:#0E7A56; opacity:.65; }
/* Tiny inline spinner — inherits the button's foreground color so it works
   on both the primary "חפש" button and any variants. */
.btn-spinner {
  display:inline-block;
  width:.85em; height:.85em;
  border:2px solid currentColor;
  border-inline-start-color:transparent;
  border-radius:50%;
  animation:btn-spin .7s linear infinite;
  flex:0 0 auto;
}
@keyframes btn-spin { to { transform:rotate(360deg); } }
@media (prefers-reduced-motion:reduce) {
  .btn-spinner { animation:none; border-inline-start-color:currentColor; opacity:.5; }
}

.p-domain-status {
  font-size:.9rem;
  padding:.5rem .7rem;
  border-radius:8px;
  margin:.2rem 0 0;
  line-height:1.4;
}
.p-domain-status.ok    { background:#DCFCE7; color:#166534; border:1px solid #86EFAC; }
.p-domain-status.taken { background:#FEE2E2; color:#991B1B; border:1px solid #FCA5A5; }

/* "יש לך דומיין קיים?" alternate CTA — visually a bordered pill so it reads
   as a secondary option to the primary domain-search flow. Sits inside the
   .p-domain-box so it's revealed only when the "כן, אני רוצה" toggle is on.
   WhatsApp green comes from --wa (defined per palette). */
.p-existing-domain {
  display:block;
  width:100%;
  margin:.4rem 0 .2rem;
  padding:.65rem 1rem;
  background:transparent;
  border:1px solid var(--wa, #0E7A56);
  border-radius:12px;
  color:var(--wa, #0E7A56);
  text-align:center;
}
.p-existing-domain-title { display:block; font-weight:600; font-size:.95rem; }
.p-existing-domain-check {
  display:inline-flex;
  align-items:center;
  gap:.4rem;
  font-size:.85rem;
  margin-top:.35rem;
  cursor:pointer;
}
.p-existing-domain-check input[type="checkbox"] { margin:0; cursor:pointer; }
.p-existing-domain-check input[type="checkbox"]:disabled { cursor:progress; }
.p-existing-domain-check:has(input:disabled) { opacity:.6; cursor:progress; }
.p-existing-domain-ack { display:block; font-weight:600; font-size:.95rem; text-align:center; }
/* Explicit [hidden] override: the display:block rules above (both here and
   inside .p-domain-reveal) outrank the browser default [hidden]{display:none},
   so the ack would leak through as visible on initial render. */
.p-existing-domain-ack[hidden] { display:none; }
.p-existing-domain-thanks { text-align:center; font-size:1.05rem; padding:.4rem 0 .2rem; margin:0; }

.p-plan-fineprint {
  font-size:.72rem;
  color:var(--muted, #888);
  line-height:1.45;
  margin:0;
  text-align:center;
}

/* Single-column feature list on very narrow screens. */
@media (max-width:420px) {
  .p-plan-feats { grid-template-columns:1fr; }
}
@media (max-width:560px) {
  /* Tight mobile stepper: shrink circles + hide non-active labels so the six
     circles fit cleanly on ~320-400px viewports. Labels are already
     absolutely positioned in the base rules (so no layout math needed) —
     we just visually reveal only the active step's caption. */
  .publish-stepper { margin-bottom:1rem; padding-bottom:1.4rem; }
  .publish-stepper .p-step-circle { width:26px; height:26px; font-size:.8rem; }
  .publish-stepper .p-step-line { margin-top:13px; min-width:10px; }
  .publish-stepper .p-step:not(.active) .p-step-label { display:none; }
  .publish-stepper .p-step.active .p-step-label {
    font-size:.72rem;
    color:#0284C7;
    margin-top:.2rem;
  }
}

/* Legal modal — wider, with pre-wrapped body / tall textarea */
.modal-dialog:has(.legal-body), .modal-dialog:has(.legal-textarea) { max-width:680px; }
.legal-body { white-space:pre-wrap; overflow-wrap:anywhere; word-break:break-word; line-height:1.65; color:var(--ink, #1a1a1a); font-size:.96rem; max-height:60vh; overflow-y:auto; padding-inline-end:.4rem; }
.legal-edit-hint { font-size:.85rem; color:var(--muted, #777); margin:0 0 .5rem; }
.legal-textarea { width:100%; min-height:320px; font:inherit; font-family:var(--fui, Heebo), sans-serif; padding:.7rem .9rem; border:1px solid var(--line, #ddd); border-radius:10px; background:var(--bg, #f9f9f9); color:inherit; resize:vertical; line-height:1.55; }


body:not([data-edit="true"]) .edit-only { display:none !important; }
/* Hide the legacy pricing-sample disclaimer baked into older saved sites. */
.price-disclaimer { display:none !important; }
body[data-edit="true"] .is-hidden { opacity:.35; outline:2px dashed #d54; outline-offset:4px; }
body:not([data-edit="true"]) .is-hidden { display:none !important; }
/* Sections hidden via the menu are fully removed (not just faded) even in edit mode.
   Re-enable from the menu toolbar at the top of the page.
   `.stat-strip` matches so the data band (a <div>, not <section>) hides
   consistently with the other bands - the standalone edit-bar sits before
   it and stays visible for re-enabling. */
body[data-edit="true"] section.is-hidden,
body[data-edit="true"] .stat-strip.is-hidden { display:none !important; }
/* In edit mode the hidden marker on top-nav <li>s shouldn't leave a dimmed
   stub in the menu — fully hide so what's in the bar matches the menu. */
body[data-edit="true"] #primary-nav > li.is-hidden { display:none !important; }

body[data-edit="true"] [contenteditable="true"] { outline:1px dashed color-mix(in srgb, var(--primary) 50%, transparent); outline-offset:3px; border-radius:4px; cursor:text; transition:background .15s, outline-color .15s; }
body[data-edit="true"] [contenteditable="true"]:hover { background:color-mix(in srgb, var(--accent) 18%, transparent); }
body[data-edit="true"] [contenteditable="true"]:focus { outline:2px solid var(--primary); background:color-mix(in srgb, var(--accent) 22%, transparent); }

.edit-bar { display:flex; flex-wrap:wrap; gap:.5rem 1rem; align-items:center; background:#E0F2FE; border:1px dashed #BAE6FD; border-radius:12px; padding:.55rem .85rem; margin-bottom:1rem; font-family:var(--fui),sans-serif; font-size:.88rem; color:#075985; }
/* Section-bar cluster: everything packs at the inline-start (right in RTL,
   left in LTR). Neutralises the auto-margins that .section-toggle /
   .section-reorder carry from the generic strip layout above so the whole
   row (toggle → arrows → + → name → controls → ×) reads as one tight
   cluster instead of splitting into two groups. */
.edit-bar.section-bar > .section-toggle,
.edit-bar.section-bar > .section-reorder { margin-inline-start:0; }
.edit-bar.section-bar > .section-reorder + .section-toggle { margin-inline-start:0; }
/* Per-section edit strip with a slide toggle at its end that controls that
   section's visibility. Toggle hugs the strip's inline-end edge via auto-
   margin so it renders on the visual left in RTL, right in LTR. */
.edit-bar .section-toggle { margin-inline-start:auto; display:inline-flex; align-items:center; cursor:pointer; }
/* Up/down reorder arrows sit right before the end-toggle so the toggle
   keeps its far-end position. Styled as proper pill buttons - visible
   border, filled hover state, small drop shadow. */
.edit-bar .section-reorder { display:inline-flex; gap:.35rem; align-items:center; margin-inline-start:auto; }
.edit-bar .section-reorder + .section-toggle { margin-inline-start:.5rem; }
.edit-bar .section-reorder-btn {
  display:inline-flex; align-items:center; justify-content:center;
  width:26px; height:26px;
  padding:0;
  border:1px solid #BAE6FD;
  background:#F0F9FF;
  color:#0369A1;
  font-size:.85rem; font-weight:800; line-height:1;
  border-radius:6px;
  cursor:pointer;
  box-shadow:0 1px 2px rgba(3,105,161,.15);
  transition:background .12s, border-color .12s, transform .06s;
}
.edit-bar .section-reorder-btn:hover { background:#0284C7; color:#fff; border-color:#0284C7; }
.edit-bar .section-reorder-btn:active { transform:scale(.94); }
.edit-bar .section-reorder-btn:focus-visible { outline:2px solid #0284C7; outline-offset:2px; }
/* Add-block "+" button on each section-bar. Uses the same pill styling as the
   reorder arrows but with a stronger accent so it reads as an action button. */
.edit-bar .section-add-btn,
.edit-bar .section-del-btn {
  display:inline-flex; align-items:center; justify-content:center;
  width:26px; height:26px;
  padding:0;
  border:1px solid #BAE6FD;
  background:#F0F9FF;
  color:#0369A1;
  font-size:1.05rem; font-weight:800; line-height:1;
  border-radius:6px;
  cursor:pointer;
  box-shadow:0 1px 2px rgba(3,105,161,.15);
  transition:background .12s, border-color .12s, transform .06s;
}
.edit-bar .section-add-btn:hover { background:#0284C7; color:#fff; border-color:#0284C7; }
.edit-bar .section-add-btn:active,
.edit-bar .section-del-btn:active { transform:scale(.94); }
.edit-bar .section-add-btn:focus-visible,
.edit-bar .section-del-btn:focus-visible { outline:2px solid #0284C7; outline-offset:2px; }
.edit-bar .section-del-btn { color:#B91C1C; border-color:#FCA5A5; background:#FEF2F2; }
.edit-bar .section-del-btn:hover { background:#DC2626; color:#fff; border-color:#DC2626; }

/* Block-picker modal: 2-3 col grid of type cards */
.block-picker-grid {
  display:grid;
  grid-template-columns:repeat(auto-fit, minmax(180px, 1fr));
  gap:.7rem;
  margin-top:.4rem;
}
/* On narrow viewports the 8 type cards stack into a single column tall
   enough to push the modal past the fold. Cap the grid height + scroll
   internally so the modal title + Cancel button stay visible above and
   below the list. `overscroll-behavior: contain` prevents the scroll
   from chaining into the page body when the list bottom is reached. */
@media (max-width:700px) {
  .block-picker-grid {
    max-height:60vh;
    overflow-y:auto;
    -webkit-overflow-scrolling:touch;
    overscroll-behavior:contain;
    padding-inline-end:.3rem;
  }
}
.block-picker-card {
  display:flex; flex-direction:column; align-items:flex-start; gap:.3rem;
  padding:.9rem 1rem;
  border:1.5px solid #E2E8F0;
  border-radius:10px;
  background:#fff;
  cursor:pointer;
  text-align:start;
  font:inherit; color:inherit;
  transition:border-color .12s, background .12s, transform .06s;
}
.block-picker-card:hover { border-color:#0284C7; background:#F0F9FF; }
.block-picker-card:active { transform:scale(.98); }
.block-picker-card:focus-visible { outline:2px solid #0284C7; outline-offset:2px; }
.block-picker-card b { font-size:1rem; color:#0F172A; }
.block-picker-card span { font-size:.82rem; color:#64748B; }
.block-picker-subtitle { margin:0 0 .8rem; color:#475569; font-size:.9rem; }

/* Full-width single-image / video blocks inserted via the picker */
.block-image .img-fill {
  width:100%;
  aspect-ratio: 16 / 9;
  border-radius:12px;
  overflow:hidden;
}
.block-video .video-frame {
  position:relative; width:100%;
  aspect-ratio: 16 / 9;
  border-radius:12px;
  overflow:hidden;
  background:#000;
}
.block-video .video-frame iframe {
  position:absolute; inset:0;
  width:100%; height:100%;
  border:0;
}
.block-video .video-url-input {
  display:flex; align-items:center; gap:.4rem; flex-wrap:wrap;
  margin-bottom:.7rem;
  font-family:var(--fui),sans-serif; font-size:.86rem; color:#075985;
}
.block-video .video-url-input input {
  font:inherit; font-size:.86rem; padding:.3rem .55rem;
  border:1px solid #BAE6FD; border-radius:6px;
  background:#fff; color:#075985; min-width:280px; flex:1;
}
/* Section bar sits FLUSH against the section it introduces (no gap on the
   bottom side) - the bar visually caps the top of its section. When a bar
   follows another section though, we want a small gap so the strip doesn't
   feel wedged against the previous section's content. */
.edit-bar.section-bar { margin-top:0; margin-bottom:0; }
body[data-edit="true"] section + .edit-bar.section-bar,
body[data-edit="true"] .stat-strip + .edit-bar.section-bar { margin-top:1.5rem; }
.section-toggle input { position:absolute; opacity:0; pointer-events:none; }
.section-toggle .switch {
  width:36px; height:20px; border-radius:20px;
  background:#94A3B8; position:relative; transition:background .2s;
  flex:0 0 auto;
}
.section-toggle .switch::after {
  content:""; position:absolute; top:2px; right:2px;
  width:16px; height:16px; border-radius:50%;
  background:#fff; box-shadow:0 1px 3px rgba(0,0,0,.3);
  transition:transform .2s;
}
.section-toggle input:checked + .switch { background:#0284C7; }
/* Match `.edit-toggle`: knob starts on the physical right and slides left
   when on. Direction-independent; in the HE/AR RTL layout the app is
   designed around, this maps to leading-edge = on / trailing-edge = off. */
.section-toggle input:checked + .switch::after { transform:translateX(-16px); }
.section-toggle input:focus-visible + .switch { outline:3px solid #0284C7; outline-offset:3px; }
/* Small inline slide - used to attach a visibility toggle right next to the
   element it controls (brand name in the header, nav-end WA button, etc.). */
.inline-toggle { display:inline-flex; align-items:center; margin-inline-start:.35rem; cursor:pointer; vertical-align:middle; }
.inline-toggle input { position:absolute; opacity:0; pointer-events:none; }
.inline-toggle .switch { width:28px; height:16px; border-radius:16px; background:#94A3B8; position:relative; transition:background .2s; flex:0 0 auto; }
.inline-toggle .switch::after { content:""; position:absolute; top:2px; inset-inline-end:2px; width:12px; height:12px; border-radius:50%; background:#fff; box-shadow:0 1px 2px rgba(0,0,0,.25); transition:transform .2s; }
.inline-toggle input:checked + .switch { background:#0284C7; }
[dir="rtl"] .inline-toggle input:checked + .switch::after,
html[dir="rtl"] .inline-toggle input:checked + .switch::after { transform:translateX(12px); }
[dir="ltr"] .inline-toggle input:checked + .switch::after,
html:not([dir="rtl"]) .inline-toggle input:checked + .switch::after { transform:translateX(-12px); }
/* Master edit strip (the one that gets .wrap for centering) needs extra room
   so the address label + input stay on one row instead of wrapping. Only the
   master bar carries .wrap - inline .edit-bars inside sections don't. */
.edit-bar.wrap { max-width:none; padding-inline:1.1rem; position:relative; justify-content:center; }

/* Pricing-card edit strip (הסתר + הכי משתלם) must always own its own row
   at the top of the card. Otherwise on horizontal `.price-card` layouts
   (food template makes each card a flex row) the strip lands next to the
   title and visually collides with it — see the bug report screenshot. */
.price-card > .price-card-ctrls { flex-basis:100%; width:100%; }

/* Per-content visibility checkboxes pulled out of the section-bar strips
   so they overlay the element they control at the top inline-start corner
   (physical top-right in RTL, top-left in LTR). Compact pill styling
   makes them read as an edit affordance without competing with page
   content. Both carry .edit-only + .edit-dynamic so they hide in view
   mode and get stripped from saved HTML.
     .about-photo-toggle  — overlay on the about photo
     .map-toggle          — overlay on the contact map */
.about-photo-toggle,
.map-toggle {
  position:absolute;
  top:8px;
  inset-inline-start:8px;
  z-index:5;
  display:inline-flex;
  align-items:center;
  gap:.35rem;
  padding:.3rem .55rem;
  background:#fff;
  border:1px solid #BAE6FD;
  border-radius:6px;
  font-family:var(--fui),sans-serif;
  font-size:.8rem;
  font-weight:600;
  color:#075985;
  cursor:pointer;
  box-shadow:0 2px 4px rgba(0,0,0,.1);
  pointer-events:auto;
}
.about-photo-toggle input,
.map-toggle input { cursor:pointer; margin:0; accent-color:#0284C7; }
/* Positioning contexts for the overlays. `.contact-map` also gets an
   explicit min-height so its box (and the toggle) stays visible even
   after the iframe inside has been toggled off. */
body[data-edit="true"] .about-photo { position:relative; }
body[data-edit="true"] .contact-map { position:relative; min-height:380px; }
/* Any btn wired with wireBtnVisibilityToggle gets the .has-viz-toggle marker.
   Rather than fight template-specific `padding:` shorthands (services template
   overwrites `.hero-cta .btn { padding: … }`, killing our reserved bottom
   room), we let the btn wrap and give the toggle `flex-basis:100%` so it
   drops onto its own row underneath whatever content the btn already has.
   Works uniformly for text-only btns (nav / hero WA / hero contact) and for
   the tel btn (icon + digits stay on row 1, toggle sits on row 2). */
body[data-edit="true"] .btn.has-viz-toggle {
  flex-wrap:wrap;
  justify-content:center;
  row-gap:.2rem;
  padding-block:.5rem;
}
body[data-edit="true"] .btn.has-viz-toggle > .nav-wa-toggle {
  position:static;
  transform:none;
  bottom:auto;
  left:auto;
  flex-basis:100%;
  justify-content:center;
}

/* Hero pill (.hero-tag) also uses the shared viz-toggle - the מוצג checkbox
   wraps below the pill's text in edit mode. Hidden entirely from public
   visitors when the owner toggles it off. */
body:not([data-edit="true"]) .hero-tag.is-disabled { display:none !important; }
body[data-edit="true"] .hero-tag.has-viz-toggle {
  flex-wrap:wrap;
  justify-content:center;
  row-gap:.25rem;
}
body[data-edit="true"] .hero-tag.has-viz-toggle > .nav-wa-toggle {
  position:static;
  transform:none;
  bottom:auto;
  left:auto;
  flex-basis:100%;
  justify-content:center;
}
body[data-edit="true"] .hero-tag.is-disabled { opacity:.5; }

/* Nav WA toggle — a small native checkbox with a state-label ("מוצג" /
   "מוסתר") centered under the button's own text. Sits at the bottom of
   the .nav-cta button so the button's "וואטסאפ" text stays readable
   above it. No pill background/border - the label reads directly on the
   button surface, and `color:inherit` picks up whatever color the button's
   own text uses so it always matches. */
.nav-wa-toggle {
  position:absolute;
  bottom:3px;
  left:50%;
  transform:translateX(-50%);
  z-index:5;
  display:inline-flex;
  align-items:center;
  gap:.25rem;
  padding:0;
  background:transparent;
  border:none;
  box-shadow:none;
  font-family:var(--fui),sans-serif;
  font-size:.62rem;
  font-weight:700;
  color:inherit;
  line-height:1;
  cursor:pointer;
  pointer-events:auto;
  user-select:none;
  white-space:nowrap;
}
.nav-wa-toggle input {
  margin:0;
  width:11px;
  height:11px;
  cursor:pointer;
  accent-color:currentColor;
  flex:0 0 auto;
}
.nav-wa-toggle-text { line-height:1; color:inherit; }

/* Generic "visibly disabled" affordance for buttons — used by the nav WA
   btn when the master toggle is off (see wireNavWaToggle) and by the hero
   "book intro" btn when the contact section is hidden (see
   refreshHeroBookIntroState).
     - View mode: fully hidden (no reason to show a dead button to
       visitors; if the master WA toggle is off, we don't want a mystery
       greyed pill in the top nav either).
     - Edit mode: color-shifted to a muted pill (deliberately NOT using
       `opacity` because that would cascade to the overlay checkbox
       inside the nav WA btn and dim the toggle too). Non-interactive
       via pointer-events:none, but the overlay child re-enables its own
       pointer events so the owner can flip the toggle back on. */
body:not([data-edit="true"]) .btn.is-disabled { display:none !important; }
body[data-edit="true"] .btn.is-disabled {
  pointer-events:none;
  cursor:not-allowed;
  background-color:#E2E8F0;
  color:#94A3B8;
  border-color:#CBD5E1;
  box-shadow:none;
}
body[data-edit="true"] .btn.is-disabled > .nav-wa-toggle { pointer-events:auto; }

/* When the toggle itself is blocked (phone missing / contact section off),
   keep the checkbox interactive for the tooltip trigger even though the
   input inside is disabled. */
body[data-edit="true"] .btn.is-disabled[data-viz-blocked] > .nav-wa-toggle {
  pointer-events:auto;
  cursor:not-allowed;
}
body[data-edit="true"] .btn.is-disabled[data-viz-blocked] > .nav-wa-toggle input {
  cursor:not-allowed;
}

/* Custom tooltip - black rounded balloon with a small triangle notch on the
   bottom. Attached to any [data-tip] element; the copy is read from the
   attribute value. Renders below the target so it doesn't collide with the
   fixed edit chrome above. */
[data-tip] { position:relative; }
[data-tip]::after,
[data-tip]::before {
  position:absolute;
  opacity:0;
  visibility:hidden;
  pointer-events:none;
  transition:opacity .15s ease .05s, visibility .15s ease .05s;
  z-index:200;
}
[data-tip]::after {
  content:attr(data-tip);
  top:calc(100% + 8px);
  left:50%;
  transform:translateX(-50%);
  max-width:280px;
  width:max-content;
  padding:.5rem .75rem;
  background:#0F172A;
  color:#F8FAFC;
  font-family:var(--fui, system-ui), sans-serif;
  font-size:.78rem;
  font-weight:500;
  line-height:1.4;
  border-radius:8px;
  box-shadow:0 8px 24px -8px rgba(0,0,0,.5);
  white-space:normal;
  text-align:center;
  direction:inherit;
}
[data-tip]::before {
  content:"";
  top:calc(100% + 2px);
  left:50%;
  transform:translateX(-50%);
  border:6px solid transparent;
  border-bottom-color:#0F172A;
}
/* The whole action cluster (toggle + arrows + / × ×) now sits at the strip's
   inline-START edge, which is the viewport-edge side (right in RTL, left in
   LTR). A centered tooltip clips past the viewport there — anchor each
   tooltip's inline-START to the button's inline-START so the balloon opens
   inward (leftward in RTL, rightward in LTR). */
.edit-bar.section-bar .section-toggle[data-tip]::after,
.edit-bar.section-bar .section-reorder-btn[data-tip]::after,
.edit-bar.section-bar .section-add-btn[data-tip]::after,
.edit-bar.section-bar .section-del-btn[data-tip]::after {
  left:auto; right:auto;
  transform:none;
  inset-inline-start:0;
}
.edit-bar.section-bar .section-toggle[data-tip]::before,
.edit-bar.section-bar .section-reorder-btn[data-tip]::before,
.edit-bar.section-bar .section-add-btn[data-tip]::before,
.edit-bar.section-bar .section-del-btn[data-tip]::before {
  left:auto; right:auto;
  transform:none;
  inset-inline-start:8px;
}
/* Mirror-image case: analytics `G` sits at the strip's inline-END
   (physical LEFT in RTL, RIGHT in LTR) at every viewport, and the help
   `?` joins it there on mobile. A centered tooltip would extend past
   the viewport edge, so anchor its inline-END to the button's
   inline-END and let it open inward (toward inline-start). Help
   tooltip on desktop stays centered — its position next to the toggle
   leaves plenty of room on both sides. */
.edit-tools-strip .edit-tools-strip-end .analytics-btn[data-tip]::after {
  left:auto; right:auto;
  transform:none;
  inset-inline-end:0;
}
.edit-tools-strip .edit-tools-strip-end .analytics-btn[data-tip]::before {
  left:auto; right:auto;
  transform:none;
  inset-inline-end:8px;
}
@media (max-width:700px) {
  .edit-tools-strip .edit-tools-strip-topline .help-btn[data-tip]::after {
    left:auto; right:auto;
    transform:none;
    inset-inline-end:0;
  }
  .edit-tools-strip .edit-tools-strip-topline .help-btn[data-tip]::before {
    left:auto; right:auto;
    transform:none;
    inset-inline-end:8px;
  }
}
/* Show styled tooltip on hover for ALL data-tip hosts. Previously wrapped
   in `@media (hover:hover)` to dodge a touch-tap flash on iOS Safari, but
   that also disabled tooltips on Chrome/Windows laptops with a touchscreen
   (Chrome flips the primary-input hint to "none" once you've tapped the
   screen once — even if you're mousing again). The touch flash mitigation
   is now scoped to the specific corner-of-strip buttons that had the
   off-screen overflow problem (analytics G / help ?) below. */
[data-tip]:hover::after,
[data-tip]:hover::before { opacity:1; visibility:visible; }
/* Suppress the brief hover flash on true touch-only devices for the
   corner-of-strip buttons whose centered tooltip extends past the viewport
   and made iOS Safari scroll on tap. Keyboard users still get :focus-visible. */
@media (hover:none) {
  .edit-tools-strip .edit-tools-strip-topline .help-btn[data-tip]:hover::after,
  .edit-tools-strip .edit-tools-strip-topline .help-btn[data-tip]:hover::before,
  .edit-tools-strip .edit-tools-strip-end .analytics-btn[data-tip]:hover::after,
  .edit-tools-strip .edit-tools-strip-end .analytics-btn[data-tip]:hover::before {
    opacity:0; visibility:hidden;
  }
}
/* :focus-visible on the tip host itself is fine for keyboard-nav discovery,
   but :focus-within would stick the balloon open the whole time the nested
   input is focused (typing a phone number keeps the tooltip fixed over the
   field). Only trigger on real hover or when the tip host itself is
   focused via keyboard. */
[data-tip]:focus-visible::after,
[data-tip]:focus-visible::before { opacity:1; visibility:visible; }
/* Both collapse/expand buttons share the pill styling - always-on soft blue
   background so the affordance is discoverable even before hover. */
.edit-bar-collapse-btn,
.edit-bar-expand-btn {
  width:32px;
  height:28px;
  border:1px solid #BAE6FD;
  background:rgba(2,132,199,.16);
  color:#075985;
  border-radius:8px;
  cursor:pointer;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  transition:background .12s, box-shadow .12s;
  box-shadow:0 2px 6px -2px rgba(2,132,199,.35);
}
.edit-bar-collapse-btn:hover,
.edit-bar-expand-btn:hover { background:rgba(2,132,199,.28); box-shadow:0 3px 10px -2px rgba(2,132,199,.5); }
.edit-bar-collapse-btn:focus-visible,
.edit-bar-expand-btn:focus-visible { outline:2px solid #0284C7; outline-offset:2px; }

/* Collapse button anchored to the bottom-inline-end corner (visually
   bottom-left in RTL). Sits fully inside the strip's bottom-padding area so
   it never overhangs the dashed container border. */
.edit-bar-collapse-btn {
  position:absolute;
  bottom:.4rem;
  inset-inline-end:1rem;
  z-index:2;
}
/* Give the master strip a bit of extra bottom padding so its own content
   doesn't crowd against the collapse handle. */
.edit-bar.wrap { padding-block-end:.9rem; }

/* Expand button + publish button share the .edit-tools-strip-end wrapper.
   The wrapper carries the auto-margin so both sit as an adjacent pair at
   the far inline-end (visually the left edge in RTL). Inside the wrapper
   the two buttons flex-row with a small gap; publish's own auto-margin is
   neutralized so it doesn't grow at the expand button's expense. */
.edit-tools-strip-end {
  display:inline-flex;
  align-items:center;
  gap:.5rem;
  margin-inline-start:auto;
}
.edit-tools-strip-end .publish-btn { margin-inline-start:0 !important; }
.edit-bar-expand-btn { display:none; }
body.edit-bars-collapsed .edit-bar-expand-btn { display:inline-flex; }

/* Collapsed state: hide the master strip AND the draft banner. Only the top
   edit-tools strip stays visible, holding the expand button. */
body.edit-bars-collapsed #editMasterBar,
body.edit-bars-collapsed #draftBanner { display:none !important; }
/* Hide the in-strip collapse button when its host strip is hidden - the
   redundancy protects against a stray display:block from another rule. */
body.edit-bars-collapsed .edit-bar-collapse-btn { display:none; }
/* Body padding-top defaults (see above) reserve space for the strip + the
   banner. When the banner is collapsed away, tighten to just the strip's
   height so there's no empty gap between the strip and the site header.
   This is the initial-paint value; updateChromePadding() then writes an
   exact px value as an inline style once the JS reads live heights. */
body.edit-bars-collapsed.has-draft-banner.has-edit-tools-strip,
body.edit-bars-collapsed[data-edit="true"].has-draft-banner.has-edit-tools-strip { padding-top:50px; }
.edit-bar label { display:inline-flex; align-items:center; gap:.35rem; cursor:pointer; margin:0; }
.edit-bar input { accent-color:#0284C7; }
.edit-bar-textinput { display:inline-flex; align-items:center; gap:.4rem; flex-wrap:wrap; }
.edit-bar-textinput > span { font-weight:600; color:#075985; white-space:nowrap; }
.edit-bar-textinput input { font:inherit; font-size:.86rem; padding:.25rem .5rem; border:1px solid #BAE6FD; border-radius:6px; background:#fff; color:#075985; min-width:140px; }
.edit-bar-textinput input:focus { outline:2px solid #0284C7; outline-offset:1px; }
/* Pencil button next to the WA number field on published sites — signals
   that a click opens the SMS-verify modal instead of editing inline. */
.edit-bar-inline-btn { font:inherit; font-size:.95rem; line-height:1; padding:.25rem .45rem; border:1px solid #BAE6FD; border-radius:6px; background:#fff; color:#075985; cursor:pointer; }
.edit-bar-inline-btn:hover { background:#E0F2FE; }
/* Mobile edit mode: each `label: input` control gets its own row with the
   input stretched to a shared left edge, so the column of inputs lines up
   neatly instead of scattering at whatever width each was configured to. */
@media (max-width: 640px) {
  .edit-bar-textinput { display:flex; width:100%; justify-content:space-between; align-items:center; flex-wrap:nowrap; }
  .edit-bar-textinput input { flex:1 1 auto !important; width:auto !important; max-width:none !important; min-width:0 !important; }
}

/* "סגור" button inside the master strip - inline text button on both
   desktop and mobile, sitting right after the "אזורי פעילות" field in the
   strip's flow. Click collapses the master contact strip AND the top
   strip's template/language/palette pairs so the whole configuration
   group folds into a single narrow bar - saving one row of vertical space. */
.contact-confirm-btn {
  padding:.35rem 1rem;
  border:1px solid #0284C7;
  border-radius:8px;
  background:#0284C7;
  color:#fff;
  font-family:var(--fui),sans-serif;
  font-size:.82rem;
  font-weight:700;
  line-height:1.2;
  cursor:pointer;
  white-space:nowrap;
}
.contact-confirm-btn:hover { background:#026aa3; }
.contact-confirm-btn:focus-visible { outline:2px solid #0284C7; outline-offset:2px; }
.contact-confirm-hint { display:none; }
@media (max-width: 700px) {
  .contact-confirm-btn {
    display:block;
    flex-basis:100%;
    margin:.4rem auto 0;
    padding:.4rem 1.4rem;
    font-size:.86rem;
    max-width:140px;
  }
  /* Reassurance hint directly under the confirm button. Same wrap treatment
     (flex-basis:100%, centered) so it sits on its own row hugging the btn. */
  .contact-confirm-hint {
    display:block;
    flex-basis:100%;
    margin:.25rem auto 0;
    text-align:center;
    font-family:var(--fui), sans-serif;
    font-size:.72rem;
    color:#0369A1;
    opacity:.85;
  }
}

/* Narrow "פרטי התקשרות ▼" bar shown in place of the master strip after
   the owner confirms. Mobile-only — desktop always shows the full strip.
   Sits right above the site header, matches the strip's chrome color so
   the swap doesn't feel jarring. */
.contact-collapsed-bar {
  display:none;
  position:relative;
  width:100%;
  padding:.4rem 1rem;
  border:none;
  border-bottom:1px solid #BAE6FD;
  background:#E0F2FE;
  color:#075985;
  font-family:var(--fui),sans-serif;
  font-size:.85rem;
  font-weight:700;
  cursor:pointer;
  align-items:center;
  justify-content:center;
  gap:.5rem;
  text-align:center;
}
/* Desktop only: when the bar is moved INTO the edit-tools-strip (see
   setContactStripCollapsed in main.js), style it as a flex item filling
   the strip's empty middle space between the toggle+help and the publish
   button. Drops its own background/border/padding since the strip already
   provides the chrome. */
.edit-tools-strip > .contact-collapsed-bar {
  flex:1 1 auto;
  width:auto;
  background:transparent;
  border:none;
  padding:.2rem .75rem;
  color:inherit;
  font-size:.82rem;
}
.edit-tools-strip > .contact-collapsed-bar:hover { background:rgba(3,105,161,.06); border-radius:6px; }
/* Mobile: inline caret sits at the end of the "לחץ.י לעדכון..." label. */
.contact-collapsed-bar-caret { font-size:.7rem; line-height:1; opacity:.75; }
/* Desktop: dress the inline caret as the same circular button used on the
   open-state ▲ peek. The user-facing symbol is symmetric (▼ to re-open ⟷
   ▲ to collapse) and both bars now surface exactly one affordance in the
   same visual location - no separate floating peek. */
@media (min-width: 701px) {
  .contact-collapsed-bar-caret {
    display:inline-flex;
    align-items:center;
    justify-content:center;
    width:28px; height:28px;
    border-radius:50%;
    background:#F0F9FF;
    border:1px solid #BAE6FD;
    color:#0369A1;
    font-size:12px;
    font-weight:700;
    line-height:1;
    opacity:1;
    box-shadow:0 2px 6px rgba(3,105,161,.25);
  }
}

/* Collapse swap: hide the master contact strip AND the top strip's
   template / language / palette pairs, and surface the narrow bar in the
   master strip's place. The collapsed bar's label already covers all three
   ("לחץ.י לעדכון תבנית, שפה ופרטי התקשרות"), so folding both strips into
   the single narrow bar saves a whole row of vertical space. */
body[data-contact-collapsed="true"][data-edit="true"] #editMasterBar { display:none !important; }
body[data-contact-collapsed="true"][data-edit="true"] #contactCollapsedBar { display:flex; }
body[data-contact-collapsed="true"][data-edit="true"] .edit-tools-strip .edit-strip-pair,
body[data-contact-collapsed="true"][data-edit="true"] .edit-tools-strip .blog-pill { display:none !important; }
.edit-bar-rowbreak { flex-basis:100%; height:0; margin:0; padding:0; }
/* Small hint text under the WhatsApp / email / address row. Blue to blend
   with the rest of the strip's chrome; tight top margin so it hugs the row
   above without adding extra vertical padding. */
.edit-bar .edit-bar-hint {
  flex-basis:100%;
  color:#075985;
  font-size:.78rem;
  line-height:1.4;
  padding:0;
  margin-top:.2rem;
}
.edit-bar .tag { font-weight:700; color:#075985; margin-inline-end:.4rem; }

.edit-btn { background:var(--primary); color:#fff; border:none; border-radius:50%; width:28px; height:28px; font-size:1.15rem; line-height:1; cursor:pointer; display:inline-flex; align-items:center; justify-content:center; box-shadow:0 4px 10px -2px rgba(0,0,0,.3); transition:transform .15s; padding:0; font-family:var(--fui),sans-serif; }
.edit-btn:hover { transform:scale(1.12); }
.edit-btn.del { background:#d54; }

.edit-host { position:relative; }
.edit-host > .edit-host-tools { position:absolute; top:.4rem; inset-inline-end:.4rem; display:none; gap:.3rem; z-index:15; }
body[data-edit="true"] .edit-host:hover > .edit-host-tools, body[data-edit="true"] .edit-host:focus-within > .edit-host-tools { display:inline-flex; }
.chip.edit-host > .edit-host-tools { top:-9px; inset-inline-end:-9px; }
.chip.edit-host > .edit-host-tools .edit-btn { width:20px; height:20px; font-size:.85rem; }
/* FAQ details already have a ± toggle in the summary's inline-end corner —
   moving the delete out to a floating badge above the top-inline-end edge
   so it doesn't overlap and get mis-clicked when the user just wants to
   open/close the question. */
.faq details.edit-host > .edit-host-tools { top:-14px; inset-inline-end:-10px; }
.faq details.edit-host > .edit-host-tools .edit-btn { width:24px; height:24px; font-size:1rem; }
/* Drag handle for reordering FAQ items — mirrors the nav drag pattern.
   The handle lives inside <summary> (not <details>) so it stays visible
   when the question is collapsed. It's the first flex child on the RTL-
   start side, before the question text. */
body[data-edit="true"] .faq details.faq-reorderable > summary > .faq-drag-handle {
  cursor:grab;
  touch-action:none;
  user-select:none;
  color:color-mix(in srgb, var(--primary) 65%, var(--muted));
  font-size:.9rem;
  line-height:1;
  letter-spacing:1px;
  padding:.2rem .35rem;
  border-radius:4px;
  flex:0 0 auto;
}
body[data-edit="true"] .faq details.faq-reorderable > summary > .faq-drag-handle:hover {
  background:color-mix(in srgb, var(--primary) 15%, transparent);
  color:var(--primary);
}
body[data-edit="true"] .faq details.faq-dragging,
body[data-edit="true"] .faq .faq-item.faq-dragging {
  opacity:.95;
  cursor:grabbing;
  box-shadow:0 14px 32px -12px rgba(0,0,0,.35);
}
.faq-drop-placeholder {
  background:color-mix(in srgb, var(--primary) 10%, transparent);
  border:1px dashed color-mix(in srgb, var(--primary) 50%, transparent);
  border-radius:var(--radius);
  margin-bottom:.9rem;
  box-sizing:border-box;
}

/* FAQ edit UX. Question editing happens via a dedicated <input> laid over
   the summary text — putting a contenteditable inside <summary> would fail
   Chrome's a11y check (summary is itself the toggle button; nested
   interactivity is forbidden). `.faq-item` wraps each <details> so we have
   an anchor for absolute-positioning the overlay input, and stays a plain
   inline-layout wrapper in view mode (no visual change). */
.faq-item { position:relative; }
/* Overlay input covers the summary text region. Positioned to sit inside
   the summary's inner padding, leaving room for the leading drag-handle
   (inline-start in RTL) and the trailing +/- marker (now hidden in edit
   mode — see below — so we only need the drag-handle gap). */
body[data-edit="true"] .faq-q-edit-wrap {
  position:absolute;
  top:0;
  inset-inline-start:3rem;     /* clears the drag handle with breathing room */
  inset-inline-end:1.4rem;     /* aligns with summary's inner padding */
  height:calc(1.15rem * 2 + 1.08rem * 1.4);  /* mirrors summary padding + line-height */
  display:flex;
  align-items:center;
  pointer-events:none;         /* wrap is inert; only the input inside catches events */
  z-index:2;
}
body[data-edit="true"] .faq-q-edit {
  width:100%;
  pointer-events:auto;
  background:color-mix(in srgb, var(--surface) 92%, transparent);
  border:1px dashed color-mix(in srgb, var(--primary) 55%, transparent);
  border-radius:6px;
  padding:.35rem .55rem;
  font-family:var(--fui);
  font-weight:600;
  font-size:1.08rem;
  color:var(--ink);
  outline:none;
  transition:border-color .15s, background .15s;
}
body[data-edit="true"] .faq-q-edit:focus {
  border-color:var(--primary);
  background:color-mix(in srgb, var(--accent) 18%, var(--surface));
}
/* In edit mode, the summary's own text is hidden — the overlay input is the
   canonical display + edit target. Using transparent color instead of
   display:none so summary keeps its size/spacing intact. */
body[data-edit="true"] .faq summary {
  color:transparent;
}
/* Hide the +/- toggle marker in edit mode — every FAQ item is force-open
   below, so the toggle affordance is misleading. */
body[data-edit="true"] .faq summary::after {
  display:none;
}
body[data-edit="true"] .faq summary > .faq-drag-handle {
  color:color-mix(in srgb, var(--primary) 65%, var(--muted));  /* restore handle color */
}
/* Force every FAQ answer visible in edit mode so the owner can edit both Q
   and A without hunting for the toggle. Overrides the browser's default
   `details:not([open]) > *:not(summary) { display:none }` UA style. */
body[data-edit="true"] .faq details > *:not(summary) {
  display:block;
}

/* Gallery reorder — a small ⋮⋮ grip pinned to the inline-start-top corner
   of each tile. Same "handle owns drag / tile body still handles click +
   long-press crop" split as the nav and FAQ variants. The tile itself gets
   position:relative in edit mode so the absolute handle anchors correctly. */
body[data-edit="true"] .gallery.gallery-reorderable > .g { position:relative; }
body[data-edit="true"] .gallery.gallery-reorderable > .g > .gallery-drag-handle {
  position:absolute;
  top:6px;
  inset-inline-start:6px;
  z-index:6;
  cursor:grab;
  touch-action:none;
  user-select:none;
  color:#fff;
  background:rgba(0,0,0,.55);
  font-size:1rem;
  line-height:1;
  letter-spacing:1px;
  padding:3px 6px;
  border-radius:4px;
  pointer-events:auto;
}
body[data-edit="true"] .gallery.gallery-reorderable > .g > .gallery-drag-handle:hover {
  background:rgba(0,0,0,.75);
}
body[data-edit="true"] .gallery.gallery-reorderable > .g.gallery-dragging {
  cursor:grabbing;
  opacity:.95;
  box-shadow:0 20px 40px -12px rgba(0,0,0,.4);
}
.gallery-drop-placeholder {
  background:color-mix(in srgb, var(--primary) 10%, transparent);
  border:1px dashed color-mix(in srgb, var(--primary) 50%, transparent);
  border-radius:var(--radius);
  box-sizing:border-box;
}

/* Testimonial reorder - same corner-pinned grip pattern as gallery.
   The .quote tile gets position:relative in edit mode so the absolute
   handle anchors correctly. Handle owns drag; the quote text and avatar
   still handle inline edits + image swap. */
body[data-edit="true"] .quotes.testimonial-reorderable > .quote { position:relative; }
body[data-edit="true"] .quotes.testimonial-reorderable > .quote > .testimonial-drag-handle {
  position:absolute;
  top:6px;
  inset-inline-start:6px;
  z-index:6;
  cursor:grab;
  touch-action:none;
  user-select:none;
  color:#fff;
  background:rgba(0,0,0,.55);
  font-size:1rem;
  line-height:1;
  letter-spacing:1px;
  padding:3px 6px;
  border-radius:4px;
  pointer-events:auto;
}
body[data-edit="true"] .quotes.testimonial-reorderable > .quote > .testimonial-drag-handle:hover {
  background:rgba(0,0,0,.75);
}
body[data-edit="true"] .quotes.testimonial-reorderable > .quote.testimonial-dragging {
  cursor:grabbing;
  opacity:.95;
  box-shadow:0 20px 40px -12px rgba(0,0,0,.4);
}
.testimonial-drop-placeholder {
  background:color-mix(in srgb, var(--primary) 10%, transparent);
  border:1px dashed color-mix(in srgb, var(--primary) 50%, transparent);
  border-radius:var(--radius);
  box-sizing:border-box;
}
.testimonial-drag-handle-label { display:none; }

/* ===== Mobile edit-only labels + centered move handle =====
   Desktop keeps the compact icon-only chrome. On mobile touch owners get
   a labeled affordance under each icon so it's obvious what each does
   without a hover tooltip:
     × (top-inline-end)   → "מחק"
     ⋮⋮ (top-inline-start) → "מקם"
     ✥ (center)            → "הזז" - long-press to reposition the crop
   Desktop hides the labels + the center handle; mobile shows them. */
.edit-btn-label,
.edit-btn-trash,
.gallery-drag-handle-label,
.img-move-handle { display:none; }

body[data-edit="true"] .img-move-handle {
  /* Rendered on every .img-edit host and visible in edit mode on both
     desktop and mobile — owners can reposition the image crop from any
     viewport. Centered inside the tile via absolute+transform. */
  display:inline-flex;
  position:absolute;
  top:50%;
  left:50%;
  transform:translate(-50%, -50%);
  z-index:5;
  pointer-events:auto;
  cursor:grab;
  touch-action:none;
  user-select:none;
  color:#fff;
  background:rgba(0,0,0,.55);
  padding:8px 10px 6px;
  border-radius:8px;
  align-items:center;
  justify-content:center;
  flex-direction:column;
  gap:2px;
  font-family:var(--fui),sans-serif;
  font-size:.62rem;
  font-weight:700;
  line-height:1;
}
/* Hero variant — both affordances are ALWAYS visible on desktop AND
   mobile (unlike other image tiles, where the handle is mobile-only and
   the hint is hover-only on desktop). The hero has heavy text overlay
   (H1 + CTAs) so a hover-only "לחץ/י להחלפה" hint is easy to miss, and
   a centered move handle would sit on top of that text. Instead we mirror
   the top-left hint pill on the top-right corner with a matching "הזז"
   pill — both stay above the H1/CTAs, both always visible. */
body[data-edit="true"] .hero-media > .img-move-handle {
  display:inline-flex;
  top:1rem;
  right:1rem;
  left:auto;
  bottom:auto;
  transform:none;
  flex-direction:row;
  gap:5px;
  padding:.35rem .75rem;
  background:rgba(0,0,0,.7);
  border-radius:999px;
  font-size:.78rem;
}
body[data-edit="true"] .hero-media > .img-move-handle svg { width:14px; height:14px; }
/* Force the hint pill on desktop too (base rule only shows it on hover). */
body[data-edit="true"] .hero-media > .img-edit-hint { opacity:1; }
body[data-edit="true"] .img-move-handle:active { cursor:grabbing; background:rgba(0,0,0,.75); }
body[data-edit="true"] .img-edit.img-repositioning > .img-move-handle {
  background:rgba(2,132,199,.9);
}

@media (max-width: 700px) {
  /* Gallery tile ONLY - other delete-tool contexts (chips, cards, FAQ,
     testimonials) keep the compact round × icon. The three-corner labeled
     UX was requested for the image gallery, so the pill-grow + "מחק"
     caption are scoped to `.gallery .g` descendants only. */
  body[data-edit="true"] .gallery .g > .edit-host-tools .edit-btn.del {
    width:auto; height:auto;
    min-width:36px;
    border-radius:8px;
    padding:2px 6px 3px;
    flex-direction:column;
    gap:0;
    line-height:1;
  }
  /* Gallery-mobile swaps the × glyph for the trash SVG. */
  body[data-edit="true"] .gallery .g > .edit-host-tools .edit-btn.del .edit-btn-glyph { display:none; }
  body[data-edit="true"] .gallery .g > .edit-host-tools .edit-btn.del .edit-btn-trash {
    display:block;
    width:16px;
    height:16px;
  }
  body[data-edit="true"] .gallery .g > .edit-host-tools .edit-btn.del .edit-btn-label {
    display:block;
    font-family:var(--fui),sans-serif;
    font-size:.6rem;
    font-weight:700;
    line-height:1;
    margin-top:1px;
  }
  /* Touch has no hover, so the desktop rule that only reveals
     .edit-host-tools on hover leaves them invisible on mobile. Force
     them visible for every .edit-host on mobile (services cards, chips,
     FAQ, testimonials, and gallery tiles) so owners can still delete. */
  body[data-edit="true"] .edit-host > .edit-host-tools { display:inline-flex; }

  /* Drag handle gets the "מקם" caption stacked under the ⋮⋮ glyph. */
  body[data-edit="true"] .gallery.gallery-reorderable > .g > .gallery-drag-handle {
    display:inline-flex;
    flex-direction:column;
    align-items:center;
    gap:1px;
    padding:3px 6px 4px;
  }
  body[data-edit="true"] .gallery-drag-handle-glyph {
    display:block;
    font-size:1rem;
    line-height:1;
    letter-spacing:1px;
  }
  body[data-edit="true"] .gallery-drag-handle-label {
    display:block;
    font-family:var(--fui),sans-serif;
    font-size:.6rem;
    font-weight:700;
    line-height:1;
  }

  /* Testimonial handle picks up the same stacked glyph+label treatment. */
  body[data-edit="true"] .quotes.testimonial-reorderable > .quote > .testimonial-drag-handle {
    display:inline-flex;
    flex-direction:column;
    align-items:center;
    gap:1px;
    padding:3px 6px 4px;
  }
  body[data-edit="true"] .testimonial-drag-handle-glyph {
    display:block;
    font-size:1rem;
    line-height:1;
    letter-spacing:1px;
  }
  body[data-edit="true"] .testimonial-drag-handle-label {
    display:block;
    font-family:var(--fui),sans-serif;
    font-size:.6rem;
    font-weight:700;
    line-height:1;
  }

}

.edit-add-row { display:flex; justify-content:center; margin-top:1.2rem; }
.edit-add-row .edit-btn { width:38px; height:38px; font-size:1.5rem; }

/* Skeleton shimmer overlay while an image is uploading + being Gemini-
   processed on the backend. Added by setImageFromFile at start of the
   fetch and removed in its `finally` block. Matters most for multi-file
   gallery uploads where tiles fill in one-at-a-time - the queued tiles
   would otherwise look like broken/empty boxes for several seconds each.
   Positioned via ::after so we don't disturb any pre-existing children
   (fallback badge, edit-host-tools). */
.img-loading { position:relative; overflow:hidden; }
.img-loading::after {
  content:"";
  position:absolute;
  inset:0;
  z-index:3;
  background:linear-gradient(100deg,
    color-mix(in srgb, var(--soft, #E2E8F0) 92%, #fff) 0%,
    color-mix(in srgb, var(--soft, #E2E8F0) 65%, #fff) 45%,
    color-mix(in srgb, var(--soft, #E2E8F0) 92%, #fff) 90%);
  background-size:200% 100%;
  animation:img-skeleton-shimmer 1.4s ease-in-out infinite;
  pointer-events:none;
}
/* Corner spinner sitting on top of the shimmer — the shimmer alone can
   blend into a light-toned surrounding, so the spinner is a persistent
   visual anchor telling the uploader which tile is loading. Positioned
   via inset-inline-end so it lands top-right in LTR and top-left in
   RTL (HE/AR) without extra rules. */
.img-loading::before {
  content:"";
  position:absolute;
  top:8px;
  inset-inline-end:8px;
  z-index:4;
  width:22px; height:22px;
  border-radius:50%;
  border:3px solid #CBD5E1;
  border-top-color:#64748B;
  background:rgba(241,245,249,.92);
  box-shadow:0 1px 4px rgba(15,23,42,.15);
  animation:presentsimple-spin 0.9s linear infinite;
  pointer-events:none;
}
@keyframes img-skeleton-shimmer {
  0%   { background-position:200% 0; }
  100% { background-position:-200% 0; }
}

/* `touch-action: pan-y` lets a mobile user scroll the page vertically even
   when their finger lands on an editable image — otherwise every image was
   a scroll dead-zone in edit mode. Drag/reposition kicks in only after a
   long-press: JS adds `.img-repositioning`, which promotes touch-action to
   `none` so the subsequent finger motion is captured for repositioning
   instead of triggering a scroll. Desktop mouse users are unaffected by
   touch-action. */
body[data-edit="true"] .img-edit { cursor:grab; touch-action:pan-y; }
body[data-edit="true"] .img-edit.img-repositioning { cursor:grabbing; touch-action:none; }
body[data-edit="true"] .img-edit.img-repositioning > .img-edit-hint { opacity:0 !important; }
/* Bottom-anchored hint bar so it never collides with the centered move
   handle (see .img-move-handle above). Full-cover overlay retired - it
   made the crop reposition affordance unreadable on mobile. */
.img-edit-hint { position:absolute; left:0; right:0; bottom:0; z-index:4; background:rgba(0,0,0,.6); color:#fff; opacity:0; font-family:var(--fui),sans-serif; font-weight:600; transition:opacity .2s; padding:.35rem .6rem; text-align:center; pointer-events:none; font-size:.78rem; line-height:1.2; }
body:not([data-edit="true"]) .img-edit-hint { display:none; }
body[data-edit="true"] .img-edit:hover > .img-edit-hint { opacity:1; }
body[data-edit="true"] .img-edit.drag-over > .img-edit-hint { opacity:1; background:color-mix(in srgb, var(--primary) 80%, transparent); }
/* Mobile has no hover — surface the hint bar all the time in edit mode so
   the owner sees "לחץ/י להחלפה" without needing to trigger sticky-hover. */
@media (max-width: 700px) {
  body[data-edit="true"] .img-edit > .img-edit-hint { opacity:1; }
}
/* Testimonial avatar (`.av`) is a 46-60px circle - shrink the hint bar's
   type + padding so the "החלף" label doesn't dwarf the image. */
body[data-edit="true"] .img-edit.av > .img-edit-hint {
  font-size:.55rem;
  padding:1px 3px;
  border-bottom-left-radius:50%;
  border-bottom-right-radius:50%;
}
body[data-edit="true"] .quote .av { width:60px; height:60px; }
/* The hero image overlay must outrank the existing .hero-media::after gradient. */
body[data-edit="true"] .hero-media > .img-edit-hint { z-index:5; }
/* Hero variant of the edit-hint: a small badge pinned to the top-left corner
   instead of a full-cover overlay, so it stops sitting on top of the H1 and
   the CTAs. The dark full-height overlay is dropped in favour of a compact
   pill with its own background. */
body[data-edit="true"] .hero-media > .img-edit-hint {
  inset:auto auto auto auto;
  top:1rem;
  left:1rem;
  right:auto;
  display:inline-block;
  width:auto;
  height:auto;
  padding:.35rem .75rem;
  background:rgba(0,0,0,.7);
  border-radius:999px;
  font-size:.78rem;
  text-align:start;
  white-space:nowrap;
}
body[data-edit="true"] .hero-media.drag-over > .img-edit-hint {
  background:color-mix(in srgb, var(--primary) 85%, transparent);
}

/* ===== EDIT MODE — menu drag reorder =====
   Each nav <li> gets a grab handle (⋮⋮) visible only in edit mode. Handles
   start the drag via pointer events (see setupNavReorder); clicking the
   link text still places the caret for inline editing. */
body[data-edit="true"] #primary-nav.nav-reorderable > li { position:relative; padding-inline-start:1.35rem; border-radius:8px; transition:background .12s; }
body[data-edit="true"] #primary-nav.nav-reorderable > li:hover { background:color-mix(in srgb, var(--accent) 12%, transparent); }
body[data-edit="true"] #primary-nav.nav-reorderable > li > .nav-drag-handle {
  position:absolute; inset-inline-start:.25rem; top:50%; transform:translateY(-50%);
  cursor:grab; touch-action:none; user-select:none;
  color:color-mix(in srgb, var(--primary) 65%, var(--muted));
  font-size:.75rem; line-height:1; letter-spacing:1px;
  padding:.15rem .1rem; border-radius:4px;
}
body[data-edit="true"] #primary-nav.nav-reorderable > li > .nav-drag-handle:hover {
  background:color-mix(in srgb, var(--primary) 15%, transparent);
  color:var(--primary);
}
body[data-edit="true"] #primary-nav.nav-reorderable > li.nav-dragging,
body #primary-nav > li.nav-dragging {
  /* The dragging LI is reparented to <body> mid-drag (see setupNavReorder for
     the backdrop-filter containing-block reason), so we can't rely on the
     `body[data-edit="true"] #primary-nav …` selector chain — style directly. */
  opacity:.95; cursor:grabbing;
  box-shadow:0 10px 28px -10px rgba(0,0,0,.35);
  background:var(--surface, #fff);
  border-radius:8px;
  padding:.4rem .7rem;
  list-style:none;
}
/* Placeholder that occupies the drop slot inside the nav while the LI floats
   in <body>. Same size as the LI so the surrounding items don't compress. */
.nav-drop-placeholder {
  list-style:none;
  background:color-mix(in srgb, var(--primary) 12%, transparent);
  border:1px dashed color-mix(in srgb, var(--primary) 50%, transparent);
  border-radius:8px;
  box-sizing:border-box;
}
/* Give items a bit more breathing room in edit mode so the handle + link
   don't jam against each other. */
body[data-edit="true"] #primary-nav.nav-reorderable { gap:.35rem; }

/* (hero visibility toggle now lives inside the master "מה להציג באתר" bar in
   the header — see wireHeader — so it's reachable even when the section is
   hidden. No separate strip needed.) */

/* ===== ACCESSIBILITY WIDGET + WHATSAPP FAB ===== */
:root { --a11y-font-scale: 1; }
html { font-size: calc(16px * var(--a11y-font-scale, 1)); }

.a11y-fab {
  position: fixed; bottom: 1rem; left: 1rem; z-index: 300;
  width: 48px; height: 48px; border-radius: 50%; border: none;
  background: #111; color: #fff;
  display: inline-flex; align-items: center; justify-content: center;
  cursor: pointer; box-shadow: 0 6px 20px -6px rgba(0,0,0,.4);
  transition: transform .2s;
}
.a11y-fab:hover { transform: scale(1.08); }
.a11y-fab svg { width: 24px; height: 24px; }

.a11y-menu {
  position: fixed; bottom: 4.5rem; left: 1rem; z-index: 299;
  width: 240px; background: #fff; color: #1a1a1a;
  border: 1px solid #e0e0e0; border-radius: 14px; padding: .6rem;
  box-shadow: 0 12px 36px -10px rgba(0,0,0,.35);
  font-family: Heebo, system-ui, sans-serif; font-size: .92rem;
}
.a11y-menu[hidden] { display: none; }
.a11y-title { font-weight: 700; padding: .25rem .5rem .5rem; color: #111; }
.a11y-opt {
  width: 100%; display: flex; align-items: center; justify-content: space-between;
  padding: .55rem .65rem; background: transparent; border: none; cursor: pointer;
  border-radius: 8px; font: inherit; color: inherit; text-align: start; margin: 0;
}
.a11y-opt + .a11y-opt { margin-top: 2px; }
.a11y-opt:hover { background: #f2f2f2; }
.a11y-arrow { font-weight: 800; color: #111; min-width: 1.2em; text-align: center; }
.a11y-pill {
  width: 30px; height: 16px; border-radius: 10px; background: #d0d0d0; position: relative;
  transition: background .2s; flex: 0 0 auto;
}
.a11y-pill::after {
  content: ""; position: absolute; top: 2px; right: 2px;
  width: 12px; height: 12px; border-radius: 50%; background: #fff;
  transition: transform .2s;
}
.a11y-pill.on { background: #111; }
.a11y-pill.on::after { transform: translateX(-14px); }
.a11y-reset { color: #c33; font-weight: 600; }

/* High contrast — override the template/palette CSS vars for the per-user site */
html.a11y-high-contrast body[data-template][data-palette] {
  --bg: #000; --surface: #0a0a0a; --ink: #fff; --muted: #ddd;
  --primary: #ffd000; --primary-d: #ffec55; --accent: #00e5ff;
  --soft: #1a1a1a; --line: #555; --wa: #25D366;
}
html.a11y-high-contrast .landing { background: #000; color: #fff; }
html.a11y-high-contrast .landing h1 { color: #ffd000; }
html.a11y-high-contrast .landing .sub { color: #ddd; }
html.a11y-high-contrast .landing li a { background: #0a0a0a; color: #fff; border-color: #555; }
html.a11y-high-contrast .landing li a:hover { background: #181818; }
html.a11y-high-contrast .landing li a .meta { color: #aaa; }

/* Readable font */
html.a11y-readable-font, html.a11y-readable-font * {
  font-family: Arial, sans-serif !important;
  letter-spacing: .02em;
}

/* WhatsApp floating CTA — bottom-right */
.wa-fab {
  position: fixed; bottom: 1rem; right: 1rem; z-index: 300;
  width: 56px; height: 56px; border-radius: 50%;
  background: #25D366; color: #fff; text-decoration: none;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 22px -6px rgba(0,0,0,.4);
  transition: transform .2s;
}
.wa-fab:hover { transform: scale(1.08); }
.wa-fab svg { width: 30px; height: 30px; }

/* ===== HOME (marketing) PAGE ===== */
.home { font-family:var(--fb), system-ui, sans-serif; }
/* Reserve inline-end space for the fixed .lang-switcher (42px wide, sits
   14px from the corner via the rules at style.css:4344-4345). Without this,
   the WA nav-cta + menu items can slide UNDER the flag icon on tablets and
   narrow desktops — visual overlap even though flex says there's room.
   The @media(<=600px) rules below already move the switcher inward next
   to the hamburger and hide .nav-cta, so we drop this padding there. */
.home .nav-row { height:72px; display:flex; align-items:center; gap:.8rem; padding-inline-end:68px; }
/* Homepage brand is a plain `<a class="brand">text<span>colored</span></a>` —
   override the editor's `.brand .brand-name span` rule for the inline structure. */
.home .brand { display:inline-flex; align-items:baseline; gap:0; font-family:var(--fui),sans-serif; font-weight:800; font-size:1.87rem; color:var(--ink); text-decoration:none; }
.home .brand > span { color:var(--primary); }
/* Inline brand mention inside body copy - matches the split-color pattern
   of `.brand` (the top nav): first part inherits ink color, only the trailing
   `<span>` (`שים` / `him` / `шим` etc.) is painted with the brand green. */
.home .brand-word { font-weight:800; }
.home .brand-word > span { color:var(--primary); }
/* Sub-heading between the "who" paragraphs and the team cards - needs
   top spacing since the default .section-head is meant to open a section,
   and a tighter margin-bottom so the eyebrow visually anchors to the
   team photos below it rather than floating between two equal gaps. */
.home .team-head { margin-top:2.5rem; margin-bottom:1.5rem; }
.home .team-head .eyebrow { margin-bottom:0; }
/* Longer text ("שלחו תיאור ותוך שניות קבלו אתר מונגש בחינם!") →
   font sizes across all breakpoints are ~×0.74 of the previous values so the
   button widths stay put. Mobile (≤600px) hides the `.cta-prefix` — visible
   text drops back to just the tail, so font-size returns to normal there. */
.home .home-cta { display:inline-flex; white-space:nowrap; font-size:.71rem; padding:.6rem 1rem; gap:.45rem; }
.home .menu-toggle { display:none; }
.home .menu-toggle::before { content:none; }
.home .menu-toggle .burger line { transition:transform .2s ease, opacity .2s ease; transform-origin:center; }
.home .menu-toggle[aria-expanded="true"] .burger line:nth-child(1) { transform:translateY(5px) rotate(45deg); }
.home .menu-toggle[aria-expanded="true"] .burger line:nth-child(2) { opacity:0; }
.home .menu-toggle[aria-expanded="true"] .burger line:nth-child(3) { transform:translateY(-5px) rotate(-45deg); }
.home .nav-links a { color:var(--ink); text-decoration:none; font-family:var(--fui); font-weight:500; font-size:clamp(.78rem,1.6vw,.98rem); padding:.5rem clamp(.35rem,1vw,.7rem); border-radius:10px; white-space:nowrap; }
.home .nav-links a:hover { background:var(--soft); }
.home .nav-links a[aria-current="true"] { color:var(--primary); background:var(--soft); }

/* hero (dark gradient with floating image) */
/* Marketing page uses a larger base than the editor (18px / 1.7) — scope it
   to .home so the per-user editor stays 16px / 1.5. */
body:has(#landing:not([hidden])) { font-size:18px; line-height:1.7; }
.home p { margin:0 0 1.1rem; }
.home .section-head { max-width:none; margin-bottom:2.5rem; }
.home .section-head h2 { font-size:clamp(1.7rem,3.6vw,2.6rem); text-wrap:balance; max-width:900px; }
.home .section-head p { color:var(--muted); font-size:clamp(1rem,1.8vw,1.15rem); margin-top:.8rem; max-width:none; }
/* Homepage section eyebrows (איך זה עובד / מה מקבלים / …). Starting size
   was 2x the shared editor size (.9rem → 1.8rem); then trimmed ×0.75
   (→ 1.35rem) and again ×0.85 to land at 1.15rem. Accent line before the
   text stays scaled up so it doesn't disappear next to the larger text. */
.home .eyebrow { font-size:1.15rem; }
.home .eyebrow::before { width:34px; height:4px; }
/* This eyebrow is now the first visible element inside the contact card
   (the "התחילו עכשיו" / h2 / p1 above it are hidden). Keep it flush to the
   top of the card so there's no dead space above the text. */
.home .contact-body .contact-form-eyebrow { margin-top:0; }
/* "PresentSimple" appears mid-sentence inside .address — split the last syllable
   into <span class="brand-tail"> so it gets the brand-green treatment like
   the header/footer logo. */
.home .contact-body .address .brand-tail { color:var(--primary); font-weight:700; }
/* .address is inline-flex (pin ::before + text), which swallows <br>. Wrap the
   text in .address-text so it becomes a single flex item that flows normally
   and honors the <br> line-break between the company row and the street row. */
.home .contact-body .address .address-text { line-height:1.45; }
/* .eyebrow / h2 / p have their own display rules that outrank the browser's
   default [hidden] { display:none } - re-assert it here so `hidden` on the
   contact-card headings actually hides them. */
.home .contact-body [hidden] { display:none !important; }

.home #hero-home { position:relative; color:#fff; background:#2B211C; min-height:clamp(360px,54vh,640px); display:flex; align-items:center; overflow:hidden; }
@media (min-width:601px) { .home #hero-home { min-height:clamp(420px,64vh,640px); } }
@media (max-width:600px)  { .home #hero-home { min-height:auto; } }
/* Top padding matches the `.hero-tag` margin-bottom (1.6rem) so the empty
   space ABOVE the pill visually equals the gap BELOW it (pill → h1). The
   bottom padding just needs to clear the .stat-strip's -3.5rem overlap so
   the CTA/hero-trust line doesn't sit under the stat card. */
.home #hero-home .hero-inner { position:relative; z-index:1; width:100%; padding-block:1.2rem clamp(3rem,6vw,4.5rem); }
/* Mobile keeps a bit more bottom padding for the stat-strip overlap. */
@media (max-width:600px) { .home #hero-home .hero-inner { padding-block:1.6rem 4rem; padding-inline:1.25rem; } }
.home #hero-home .hero-tag { display:flex; width:fit-content; max-width:92vw; margin-inline:auto; align-items:center; justify-content:center; gap:.55rem; background:rgba(255,255,255,.1); border:1px solid rgba(255,255,255,.28); backdrop-filter:blur(6px); padding:.45rem 1.15rem; border-radius:40px; font-family:var(--fui); font-weight:500; font-size:.9rem; margin-bottom:1.6rem; text-align:center; }
@media (max-width:480px) { .home #hero-home .hero-tag { font-size:.78rem; padding:.4rem .9rem; gap:.4rem; white-space:normal; line-height:1.5; } }
.home #hero-home .hero-tag::before { content:""; width:7px; height:7px; border-radius:50%; background:var(--accent); }
.home #hero-home h1 { font-size:clamp(2.2rem,6.4vw,5rem); font-weight:800; line-height:1.2; text-shadow:0 2px 30px rgba(0,0,0,.3); text-align:center; text-wrap:balance; color:#fff; margin:0; }
.home #hero-home .hl { color:#7ED957; }
.home #hero-home .hero-lead { font-size:clamp(1.35rem,3.2vw,1.75rem); max-width:56rem; margin:1.4rem auto 2.2rem; color:rgba(255,255,255,.92); text-align:center; text-wrap:balance; }
.home #hero-home .hero-cta { display:flex; gap:1rem; flex-wrap:wrap; justify-content:center; }
/* Hero CTA now uses .btn-wa (green bg + white text). The override here just
   scales it up and adds the halo — color stays white from .btn-wa itself. */
.home .hero-main-cta { white-space:nowrap; font-size:.86rem; padding:1.1rem 2.1rem; box-shadow:0 0 0 4px rgba(255,255,255,.12), 0 16px 40px -10px rgba(0,0,0,.5); }
@media (max-width:480px) { .home .hero-main-cta { font-size:.73rem; padding:.85rem 1.3rem; gap:.4rem; } .home .hero-main-cta svg { width:20px; height:20px; } }

.home .chip { background:var(--soft); color:var(--primary-d); font-family:var(--fui); font-weight:600; font-size:.92rem; padding:.5rem 1rem; border-radius:30px; }

/* Service cards sizes */
.home .cards { display:grid; grid-template-columns:repeat(3,1fr); gap:1.6rem; }
.home .card { background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; transition:transform .25s ease, box-shadow .25s ease; }
.home .card:hover { transform:translateY(-6px); box-shadow:0 26px 50px -28px rgba(40,25,15,.45); }
.home .card .card-body { padding:1.5rem 1.5rem 1.7rem; }
.home .card h3 { font-size:clamp(1.3rem,2.4vw,1.5rem); margin-bottom:.5rem; text-wrap:balance; }
.home .card p { color:var(--muted); font-size:clamp(.95rem,1.8vw,1.05rem); margin:0; }

/* Pricing card sizes */
.home .price-card { background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); padding:2rem 1.8rem; display:flex; flex-direction:column; transition:transform .25s ease, box-shadow .25s ease; }
@media (max-width:480px) { .home .price-card { padding:1.6rem 1.2rem; } }
.home .price-card:hover { transform:translateY(-6px); box-shadow:0 26px 50px -28px rgba(40,25,15,.4); }
.home .price-card.popular { border:1.5px solid var(--primary); box-shadow:0 26px 60px -30px rgba(40,25,15,.5); position:relative; }
.home .price-badge { position:absolute; top:-14px; left:50%; transform:translateX(-50%); background:var(--primary); color:#fff; font-family:var(--fui); font-weight:600; font-size:.82rem; padding:.32rem 1.1rem; border-radius:30px; white-space:nowrap; }
.home .price-card h3 { font-size:1.4rem; }
.home .price-tag { font-family:var(--fd); font-weight:800; font-size:clamp(1.9rem,7vw,2.4rem); color:var(--primary); line-height:1; margin:.7rem 0 .2rem; }
.home .price-tag small { font-size:1rem; font-weight:500; color:var(--muted); }
.home .price-sub { color:var(--muted); font-size:.95rem; margin-bottom:1.3rem; }
/* Accent variant for the plus card's sub-line ("הצעה משתלמת במיוחד") — uses
   the WhatsApp green tone that's already the home template's action color,
   painted bolder so it reads as a highlight. */
.home .price-sub-accent { color:var(--wa,#0E7A56); font-weight:700; }
/* Whole price-card is clickable — opens WhatsApp. Keep the hover lift the
   base rule already provides. */
.home .price-card { cursor:pointer; }
.home .price-card:focus-visible { outline:3px solid rgba(2,132,199,.35); outline-offset:2px; }
.home .price-feats { list-style:none; padding:0; margin:0 0 1.7rem; display:flex; flex-direction:column; gap:.65rem; }
.home .price-feats li { display:flex; gap:.6rem; align-items:flex-start; font-size:1rem; }
.home .price-feats li::before { content:"✓"; color:var(--primary); font-weight:800; flex:0 0 auto; }
.home .price-card .btn { margin-top:auto; justify-content:center; }

/* Stat strip sizes */
.home .stat-strip { position:relative; z-index:2; margin-top:-3.5rem; }
.home .stat-card { background:var(--surface); border-radius:var(--radius); box-shadow:0 24px 60px -24px rgba(40,25,15,.4); border:1px solid var(--line); display:grid; grid-template-columns:repeat(3,1fr); overflow:hidden; }
.home .stat { padding:1.6rem 1.2rem; text-align:center; }
.home .stat + .stat { border-inline-start:1px solid var(--line); }
.home .stat b { font-family:var(--fd); font-weight:800; font-size:2.2rem; color:var(--primary); display:block; line-height:1; }
.home .stat span { color:var(--muted); font-size:.95rem; }

/* FAQ */
.home .faq { max-width:800px; margin:0 auto; }
.home .faq details { border:1px solid var(--line); border-radius:var(--radius); background:var(--surface); margin-bottom:.9rem; }
.home .faq summary { cursor:pointer; padding:1.15rem 1.4rem; font-family:var(--fui); font-weight:600; font-size:clamp(.98rem,2.4vw,1.08rem); list-style:none; display:flex; justify-content:space-between; align-items:center; gap:1rem; }
.home .faq summary::-webkit-details-marker { display:none; }
.home .faq summary::after { content:"+"; font-size:1.6rem; line-height:1; color:var(--primary); font-weight:400; transition:transform .2s ease; flex:0 0 auto; }
.home .faq details[open] summary::after { transform:rotate(45deg); }
.home .faq .faq-a { padding:0 1.4rem 1.25rem; color:var(--muted); }

/* Address pin */
.home .address { display:inline-flex; align-items:center; gap:.6rem; font-family:var(--fui); font-weight:500; margin:1.2rem 0; color:var(--ink); }
.home .address::before { content:""; width:11px; height:11px; background:var(--primary); border-radius:50% 50% 50% 0; transform:rotate(45deg); flex:0 0 auto; }
.home .contact-actions { display:flex; gap:.8rem; flex-wrap:wrap; margin:0 0 1.4rem; }
.home #home-contact-form .field { margin-bottom:1rem; }
.home #home-contact-form .field label { display:block; font-family:var(--fui); font-weight:500; font-size:.95rem; margin-bottom:.35rem; }
.home #home-contact-form .field input, .home #home-contact-form .field textarea { width:100%; font:inherit; padding:.8rem 1rem; border:1px solid var(--line); border-radius:12px; background:var(--bg); color:var(--ink); }
.home #home-contact-form .field input:focus, .home #home-contact-form .field textarea:focus { outline:2px solid var(--primary); outline-offset:1px; }
.home #home-contact-form button { margin-top:.4rem; }
.home #home-contact-form #hc-status { font-weight:600; margin:.6rem 0 0; }
/* Two-column row for טלפון + אימייל on desktop; stacks under narrow widths. */
.field-row { display:grid; grid-template-columns:1fr 1fr; gap:0 1rem; }
.field-row .field { margin-bottom:1rem; }
@media (max-width: 640px) { .field-row { grid-template-columns:1fr; gap:0; } }

.home section { scroll-margin-top:84px; }
.home .band { padding:var(--band-pad) 0; }

/* /affiliateProgram — referral partner pitch page. Reuses landing shell
   (header/footer/palette); only the sections below live inside
   #affiliate-program-view. :not([hidden]) so the block doesn't override
   the HTML hidden attribute when the homepage is showing. */
.home .affiliate-view:not([hidden]) { display:block; }

/* Strip the landing's navigation surface on the affiliate page — no menu
   links, no lang switcher, no header WA CTA, no hamburger. Brand stays
   for identity; footer stays for legal/back-to-home. */
body.affiliate-only #landing header.site nav.primary,
body.affiliate-only #landing header.site .home-cta,
body.affiliate-only #landing header.site .menu-toggle,
body.affiliate-only #lang-switcher { display:none !important; }

/* Portal-login pill in the header — only rendered on /affiliateProgram
   (body.affiliate-only). `margin-inline-start:auto` pushes it to the
   opposite end of the flex row from .brand, so it sits top-left in RTL
   and top-right in LTR. */
.aff-portal-login { display:none; }
body.affiliate-only .aff-portal-login {
  display:inline-flex; align-items:center; gap:.4rem;
  margin-inline-start:auto;
  padding:.5rem .9rem; border-radius:999px;
  background:#fff; color:var(--primary); text-decoration:none;
  border:1px solid var(--line);
  font-weight:600; font-size:.9rem;
  transition:background .15s ease, border-color .15s ease, color .15s ease;
}
body.affiliate-only .aff-portal-login:hover {
  background:var(--primary); color:#fff; border-color:var(--primary);
}
body.affiliate-only .aff-portal-login:focus-visible {
  outline:2px solid var(--primary); outline-offset:2px;
}
@media (max-width:520px) {
  body.affiliate-only .aff-portal-login { padding:.35rem .65rem; font-size:.78rem; gap:.3rem; }
}

/* Homepage sections still get [hidden] set imperatively, but rules like
   `.home #hero-home { display:flex }` outrank the attribute. Force them
   off with a body-scoped rule so only #affiliate-program-view is visible
   inside #home-main. */
body.affiliate-only #home-main > *:not(#affiliate-program-view) { display:none !important; }
.home #affiliate-hero { padding:clamp(1.8rem, 3.5vw, 2.6rem) 0; background:linear-gradient(135deg, var(--primary) 0%, var(--primary-dark, var(--primary)) 100%); color:#fff; position:relative; overflow:hidden; }
/* Kill .hero-inner's default 4-7rem vertical padding — the section already
   controls its own spacing. Keep horizontal padding for gutters. */
.home #affiliate-hero .hero-inner { padding-block:0; padding-inline:1.5rem; }
.home #affiliate-hero .hero-tag { background:rgba(255,255,255,.14); border-color:rgba(255,255,255,.32); color:#fff; }
.home #affiliate-hero h1 { font-size:clamp(2.2rem, 5vw, 3.6rem); line-height:1.15; margin:0 0 1rem; color:#fff; }
.home #affiliate-hero .hero-lead { color:rgba(255,255,255,.94); max-width:none; }
/* Desktop: single-row lead. Tighter font so the ~100-char sentence fits
   inside .wrap (1140px). Mobile keeps the responsive .hero-lead default. */
@media (min-width:900px) {
  .home #affiliate-hero .hero-lead { font-size:1.15rem; white-space:nowrap; }
}
.home #affiliate-hero .btn-ghost { color:var(--primary); border-color:#fff; background:#fff; }
.home #affiliate-hero .btn-ghost:hover { background:rgba(255,255,255,.9); }
/* דברו איתנו — darker green outline against the green hero band gives the
   WA button a crisp edge instead of blending into the gradient. */
.home #affiliate-hero .btn-wa { border:1px solid #075E42; }
/* הצטרפו כעת — self-registration CTA. Same row as the other two but pushed
   to the visual left of the flex row via margin-inline-start:auto (so in
   RTL it sits opposite the WA button). Amber accent + pulsing halo to
   distinguish it from the WA green + white ghost and pull the eye. */
.home #affiliate-hero .affiliate-join-cta {
  margin-inline-start:auto;
  display:inline-flex; align-items:center; gap:.55rem;
  background:#F59E0B; color:#1a1a1a; border:1px solid #B45309;
  font-weight:700; position:relative;
  animation:affiliateJoinBeam 2.2s ease-in-out infinite;
}
.home #affiliate-hero .affiliate-join-cta:hover {
  background:#FBBF24; color:#1a1a1a;
  animation-play-state:paused;
  box-shadow:0 8px 24px -8px rgba(0,0,0,.4), 0 0 0 4px rgba(251,191,36,.35);
}
@keyframes affiliateJoinBeam {
  0%, 100% { box-shadow:0 0 0 0 rgba(251,191,36,.55), 0 4px 14px -6px rgba(0,0,0,.4); }
  50%      { box-shadow:0 0 0 8px rgba(251,191,36,0),   0 6px 18px -6px rgba(0,0,0,.45); }
}
@media (prefers-reduced-motion:reduce) {
  .home #affiliate-hero .affiliate-join-cta { animation:none; }
}
@media (max-width:640px) {
  /* On phones the CTAs stack, so kill the auto-margin push - it would
     leave a big empty band above the "הצטרפו" button. */
  .home #affiliate-hero .affiliate-join-cta { margin-inline-start:0; }
}

.home .affiliate-steps { grid-template-columns:repeat(3, 1fr); }
@media (max-width: 900px) { .home .affiliate-steps { grid-template-columns:1fr; } }
.home .affiliate-step { position:relative; padding:1.8rem 1.6rem 1.6rem; }
.home .affiliate-step .affiliate-step-num { position:absolute; top:1.2rem; inset-inline-end:1.4rem; font-family:var(--fui); font-weight:800; font-size:2.4rem; line-height:1; color:var(--primary); opacity:.28; }
.home .affiliate-step .card-body { padding:0; }
.home .affiliate-step h3 { font-size:1.25rem; margin:0 0 .55rem; padding-inline-end:2.4rem; }
.home .affiliate-step p { color:var(--muted); margin:0; }

.home .affiliate-list { list-style:none; padding:0; margin:0; display:grid; gap:.85rem; max-width:52rem; }
.home .affiliate-list li { position:relative; padding-inline-start:2rem; font-size:1.08rem; color:var(--ink); line-height:1.55; }
.home .affiliate-list li::before { content:""; position:absolute; inset-inline-start:0; top:.55rem; width:14px; height:14px; border-radius:50%; background:var(--primary); }
.home .affiliate-list li::after { content:""; position:absolute; inset-inline-start:4px; top:.85rem; width:6px; height:3px; border:solid #fff; border-width:0 0 2px 2px; transform:rotate(-45deg); }
.home .affiliate-perks-list li strong { color:var(--ink); font-family:var(--fui); }

.home .affiliate-notice-card { background:var(--surface); border:1px solid var(--line); border-inline-start:4px solid var(--primary); border-radius:var(--radius); padding:clamp(1.5rem, 3vw, 2.2rem); }
.home .affiliate-notice-card h2 { font-size:clamp(1.4rem, 3vw, 1.8rem); margin:.4rem 0 .6rem; }
.home .affiliate-notice-card p { color:var(--muted); margin:0; font-size:1.05rem; line-height:1.6; }

/* Affiliate contact card has no map sibling - override the base .contact-card
   2-col grid (.85fr 1fr) so the .contact-body stretches full width instead of
   being squished into the first .85fr column with a blank half beside it.
   Uses .home .contact-card.affiliate-contact-card (specificity 0,3,0) to beat
   the later .home .contact-card rule (0,2,0) that would otherwise reinstate
   the 2-column layout. */
.home .contact-card.affiliate-contact-card { grid-template-columns:1fr; }
.home .contact-card.affiliate-contact-card .contact-body { padding:clamp(1.8rem, 4vw, 3rem); }
.home #affiliate-form .field { margin-bottom:1rem; }
.home #affiliate-form .field label { display:block; font-family:var(--fui); font-weight:500; font-size:.95rem; margin-bottom:.35rem; }
.home #affiliate-form .field input, .home #affiliate-form .field textarea { width:100%; font:inherit; padding:.8rem 1rem; border:1px solid var(--line); border-radius:12px; background:var(--bg); color:var(--ink); }
.home #affiliate-form .field input:focus, .home #affiliate-form .field textarea:focus { outline:2px solid var(--primary); outline-offset:1px; }
.home #affiliate-form button { margin-top:.4rem; }
.home #affiliate-form #af-status { font-weight:600; margin:.6rem 0 0; }
.home .affiliate-fineprint { margin:1.3rem 0 0; color:var(--muted); font-size:.88rem; line-height:1.55; }

/* "איך זה עובד" section — two-column: text on the right (start in RTL),
   illustration on the left (end in RTL). Checklist sits under the copy
   in the text column. Composition is the phone + browser mock overlay. */
.home .about-grid { display:grid; grid-template-columns:1fr 1fr; grid-template-areas:"text photo"; gap:clamp(2rem,5vw,4rem); align-items:center; }
.home .about-text { grid-area:text; }
.home .about-text h2 { font-size:clamp(2rem,4.4vw,3rem); margin-bottom:1rem; text-wrap:balance; }
.home .about-text p { font-size:clamp(1rem,1.85vw,1.15rem); text-wrap:pretty; }
.home .about-text p + p { margin-top:.9rem; }
.home .about-text .how-checks { margin-top:1.8rem; }

.home .about-photo { grid-area:photo; align-self:center; justify-self:center; width:min(500px, 100%); aspect-ratio:1/1; position:relative; overflow:visible; margin:0; border-radius:0; box-shadow:none; background:none; }

/* Homepage — "איך זה עובד" checkpoint list. Bare icon (no gradient badge)
   with an integrated check circle drawn in the top-right of each SVG.
   Icon line color is set per-item via CSS `color` (SVG strokes use
   currentColor); the check circle also uses fill=currentColor so each
   badge picks up its icon's color (violet for AI, green for accessibility,
   burnt-orange for edit), with a white check inside for contrast. */
.home .how-checks { list-style:none; padding:0; margin:1.6rem 0 0; display:flex; flex-direction:column; gap:.9rem; }
.home .how-checks li { display:flex; align-items:center; gap:.95rem; font-family:var(--fui),sans-serif; font-weight:600; font-size:clamp(1rem,1.7vw,1.15rem); color:var(--ink); }
.home .how-checks .how-check-ico { display:inline-flex; width:56px; height:56px; align-items:center; justify-content:center; flex:0 0 auto; }
.home .how-checks .how-check-ico svg { width:100%; height:100%; }
.home .how-checks .how-check-ico.g-ai { color:#5B48B8; }
.home .how-checks .how-check-ico.g-access { color:#0E7A56; }
.home .how-checks .how-check-ico.g-edit { color:#C46B1B; }
.home .how-checks .how-check-label { flex:1 1 auto; }

/* ===== Homepage "how it works" composition =====
   Structure:
     .about-photo.wa-showcase.phone-live (outer, aspect 1/1, no visible frame)
       .wa-callout.wa-callout-msg     (label above phone)
       .wa-phone > .phone-frame > .phone-notch + .phone-screen
                                  > .phone-stage-chat  (WA bubbles)
       .wa-site > .browser-chrome (URL bar) + .browser-screen > .wa-site-img
       .wa-callout.wa-callout-site    (label above browser)
   Chat plays a scripted 4-bubble exchange (~7.5s). At ~8.8s the browser
   mock fades in — the "delivered site" moment. main.js flips
   .phone-live[data-play="on"] on scroll-in and re-triggers the sequence
   every 14.5s (chat + reveal + hold) via a plain setTimeout.
*/
/* Phone: right side, upper. Width chosen so the phone sits BESIDE the
   browser (no horizontal overlap) — phone 44% + browser 56% = 100% of
   the composition width. In a square (1/1) container, a 44% wide phone
   at 9/19 aspect is ~93% of container height — fits with a little room
   above for the callout. */
.wa-showcase .wa-phone { position:absolute; top:0; right:0; width:44%; aspect-ratio:9/19; z-index:3; overflow:visible; border-radius:32px; background:linear-gradient(135deg,#0F172A,#1E293B); container-type:inline-size; }

/* Browser: left side, lower. Portrait aspect (3/4) shows a taller strip
   of the delivered mobile site — matching botil where the preview shows
   multiple sections at once. All children are absolutely positioned so
   the image's huge intrinsic height (786x14590) can't push .browser-screen
   past its intended size. Layered BEHIND the phone (z-index:2 vs phone:3)
   so the phone stays the hero and the desktop preview peeks out from
   behind it. Thin border + drop shadow give it monitor-like depth. */
.wa-showcase .wa-site { position:absolute; left:0; bottom:0; width:62%; aspect-ratio:3/4; z-index:2; opacity:1; transform:none; border-radius:12px; background:#fff; border:3px solid #0F172A; box-shadow:0 6px 18px -6px rgba(15,23,42,.22); }

.wa-site .browser-chrome { position:absolute; top:0; left:0; right:0; height:24px; background:#F1F5F9; display:flex; align-items:center; gap:6px; padding:0 10px; border-bottom:1px solid #E2E8F0; border-top-left-radius:12px; border-top-right-radius:12px; z-index:1; }
.wa-site .browser-dot { width:9px; height:9px; border-radius:50%; background:#CBD5E1; flex:0 0 auto; }
.wa-site .browser-dot.dot-r { background:#F87171; }
.wa-site .browser-dot.dot-y { background:#FBBF24; }
.wa-site .browser-dot.dot-g { background:#34D399; }
.wa-site .browser-url { flex:1 1 auto; margin:0 6px; height:15px; padding:0 8px; border-radius:6px; background:#fff; border:1px solid #E2E8F0; color:#64748B; font-size:.58rem; font-family:var(--fui),sans-serif; display:flex; align-items:center; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; direction:ltr; }

/* Browser screen — fixed slot below the chrome; overflow:hidden clips
   the tall mobile screenshot as it auto-scrolls from top to bottom. */
.wa-site .browser-screen { position:absolute; top:24px; left:0; right:0; bottom:0; overflow:hidden; background:#fff; border-bottom-left-radius:12px; border-bottom-right-radius:12px; }
.wa-site .wa-site-img { position:absolute; top:0; left:0; width:100%; height:auto; display:block; transform:translateY(0); }

/* Auto-scroll the delivered site image once the browser has revealed.
   --wa-scroll-y is measured in JS after the image loads (imgH - screenH)
   so the scroll stops exactly at the bottom without exposing whitespace.
   `infinite alternate` gives a ping-pong: 22s scroll down, 22s scroll
   back up, forever. ease-in-out smooths the reversals at each end so
   they don't feel like a bounce. */
.wa-showcase[data-play="on"] .wa-site-img { animation:wa-site-scroll 22s ease-in-out 9.6s infinite alternate; }
@keyframes wa-site-scroll {
  from { transform:translateY(0); }
  to   { transform:translateY(var(--wa-scroll-y, -80%)); }
}
.phone-live:hover .wa-site-img { animation-play-state:paused; }

/* Callout pill — green dot + short label. One inside .wa-phone (above
   the phone's top edge) and one inside .wa-site (above the browser's
   top edge). Both wrappers are overflow:visible so the pill hangs out. */
.wa-showcase .wa-callout { position:absolute; display:inline-flex; align-items:center; gap:.5rem; padding:.4rem .8rem; background:#0F172A; color:#fff; border-radius:999px; font-family:var(--fui),sans-serif; font-weight:600; font-size:.82rem; line-height:1; z-index:5; white-space:nowrap; }
.wa-showcase .wa-callout::before { content:""; width:8px; height:8px; border-radius:50%; background:#25D366; box-shadow:0 0 0 3px rgba(37,211,102,.25); flex:0 0 auto; }
.wa-showcase .wa-callout-msg { top:0; left:50%; transform:translate(-50%,-60%); }
.wa-showcase .wa-callout-site { top:0; left:50%; transform:translate(-50%,-60%); }

.phone-live .phone-frame { position:absolute; inset:5px; border-radius:28px; overflow:hidden; background:#0F172A; }
.phone-live .phone-notch { position:absolute; top:5px; left:50%; transform:translateX(-50%); width:46px; height:5px; border-radius:3px; background:#000; z-index:3; }
.phone-live .phone-screen { position:absolute; inset:12px 4px 4px; border-radius:22px; overflow:hidden; background:#E0F2FE; }
.phone-live .phone-stage { position:absolute; inset:0; }
.phone-live .phone-stage-chat { display:flex; flex-direction:column; }

/* Chat stage — sizes use `cqi` (container query inline-size on .wa-phone)
   so the whole chat scales with the phone's actual width. That keeps b4
   visible on narrow phones and grows the text on wider desktop layouts,
   instead of a fixed rem size that overflows small and looks tiny big. */
.phone-live .phone-wa-header { display:flex; align-items:center; gap:2.5cqi; padding:2.5cqi 3.5cqi; background:#075985; color:#fff; }
.phone-live .phone-wa-avatar { width:12cqi; height:12cqi; border-radius:50%; background:#fff; color:#075985; display:inline-flex; align-items:center; justify-content:center; font-weight:700; font-size:4.5cqi; }
.phone-live .phone-wa-title { font-weight:700; font-size:5cqi; }
.phone-live .phone-wa-body { flex:1; padding:3cqi 2.8cqi; display:flex; flex-direction:column; gap:2cqi; overflow:hidden; }
.phone-live .phone-bubble { max-width:82%; padding:2cqi 3.2cqi 1.6cqi; border-radius:6cqi; font-size:5cqi; line-height:1.35; color:#0F172A; box-shadow:0 1px 2px rgba(0,0,0,.06); opacity:0; transform:translateY(6px); }
.phone-live .phone-bubble p { margin:0; }
.phone-live .phone-bubble-in { background:#fff; align-self:flex-start; border-top-left-radius:2px; }
.phone-live .phone-bubble-out { background:#DCFCE7; align-self:flex-end; border-top-right-radius:2px; }
.phone-live .phone-ts { display:block; margin-top:.6cqi; font-size:3.8cqi; color:#64748B; }
.phone-live .phone-ts-out { color:#15803D; }
.phone-live .phone-strong { font-weight:700; }
.phone-live .phone-link { color:#0284C7; text-decoration:underline; }
/* Typing indicators start collapsed (0-height, invisible). Each one gets a
   scripted show/hide window; the base state means they never overlap even
   before their animations kick in. */
.phone-live .phone-typing { align-self:flex-start; background:#fff; border-radius:6cqi; border-top-left-radius:2px; overflow:hidden; height:0; opacity:0; padding:0 3.2cqi; box-shadow:0 1px 2px rgba(0,0,0,.06); display:flex; align-items:center; }
.phone-live .phone-typing span { display:inline-block; width:2.4cqi; height:2.4cqi; margin:0 .7cqi; border-radius:50%; background:#94A3B8; animation:phone-typing-dot 1s infinite ease-in-out; }
.phone-live .phone-typing span:nth-child(2) { animation-delay:.15s; }
.phone-live .phone-typing span:nth-child(3) { animation-delay:.3s; }
@keyframes phone-typing-dot { 0%,100% { transform:translateY(0); opacity:.5; } 50% { transform:translateY(-3px); opacity:1; } }
.phone-live .phone-wa-input { display:flex; align-items:center; gap:2.5cqi; padding:2.2cqi 3cqi; background:#F1F5F9; }
.phone-live .phone-wa-inputbox { flex:1; height:9cqi; border-radius:5cqi; background:#fff; border:1px solid #E2E8F0; }
.phone-live .phone-wa-send { flex:0 0 auto; width:11cqi; height:11cqi; border-radius:50%; background:#0E7A56; color:#fff; display:flex; align-items:center; justify-content:center; font-size:4cqi; }

/* --- Animation timing --- Chat animations trigger on `.chat-play` (toggled
   by JS every ~10s to loop the chat forever) rather than `[data-play="on"]`
   so the browser reveal + ping-pong scroll stay on the one-shot data-play
   attribute while the chat repeats independently. */
.phone-live.chat-play .phone-bubble { animation:phone-bubble-pop .35s cubic-bezier(.2,.7,.3,1.2) both; }
.phone-live.chat-play .phone-b-1 { animation-delay:.4s; }
.phone-live.chat-play .phone-b-2 { animation-delay:2.7s; }
.phone-live.chat-play .phone-b-3 { animation-delay:4s; }
.phone-live.chat-play .phone-b-4 { animation-delay:6.8s; }
.phone-live.chat-play .phone-typ-1 { animation:phone-typing-show 1.4s ease-in-out both 1.3s; }
.phone-live.chat-play .phone-typ-2 { animation:phone-typing-show 1.6s ease-in-out both 5.1s; }
.phone-live.chat-play .phone-link { animation:phone-link-pulse .6s ease-out both 8.2s; }

/* Pause every running animation while the visitor's cursor is over the
   composition — lets them read the delivered chat + site preview at their
   own pace without the loop restarting mid-read. */
.phone-live:hover .phone-bubble,
.phone-live:hover .phone-typing,
.phone-live:hover .phone-typing span,
.phone-live:hover .phone-link,
.phone-live:hover .wa-site { animation-play-state:paused; }

@keyframes phone-bubble-pop { from { opacity:0; transform:translateY(6px) scale(.98); } to { opacity:1; transform:translateY(0) scale(1); } }
@keyframes phone-typing-show {
  0% { opacity:0; height:0; padding-top:0; padding-bottom:0; }
  15% { opacity:1; height:9cqi; padding-top:2cqi; padding-bottom:2cqi; }
  85% { opacity:1; height:9cqi; padding-top:2cqi; padding-bottom:2cqi; }
  100% { opacity:0; height:0; padding-top:0; padding-bottom:0; }
}
@keyframes phone-link-pulse { 0% { background:transparent; } 25% { background:#FEF08A; } 100% { background:transparent; } }

/* Reduced motion — show the fully-populated end state instantly instead
   of playing the sequence. No bubble pop-in, no typing indicators, and
   the browser mock is fully visible from the start. */
@media (prefers-reduced-motion: reduce) {
  .phone-live .phone-bubble { opacity:1; transform:none; }
  .phone-live .phone-typing { display:none; }
  .wa-showcase .wa-site { opacity:1; transform:none; animation:none !important; }
}

/* card image placeholders (gradient + emoji overlay, no external image needed) */
.home .card-img { aspect-ratio:16/11; position:relative; overflow:hidden; }
/* Fill the card frame with the photo when the team card carries an <img>
   (מי אנחנו section — Refael.png / Amir.png) instead of the emoji icon-over. */
.home .card-img img { width:100%; height:100%; object-fit:cover; display:block; }
/* (Team-card portrait styling moved lower; see the float-based layout
   further down that lets the bio text wrap around the image + name.) */
.home .card-img.g-ai { background:linear-gradient(135deg,#667eea,#764ba2); }
.home .card-img.g-access { background:linear-gradient(135deg,#11998e,#38ef7d); }
.home .card-img.g-edit { background:linear-gradient(135deg,#f7971e,#ffd200); }
.home .g-biz1 { background:linear-gradient(135deg,#1a1a2e,#16213e,#0f3460); }
.home .g-biz2 { background:linear-gradient(135deg,#4b6cb7,#182848); }
.home .g-biz3 { background:linear-gradient(135deg,#11998e,#38ef7d); }
.home .g-biz4 { background:linear-gradient(135deg,#c94b4b,#4b134f); }
.home .g-biz5 { background:linear-gradient(135deg,#f7971e,#ffd200); }
.home .icon-over { position:absolute; inset:0; display:flex; flex-direction:column; align-items:center; justify-content:center; gap:.7rem; z-index:2; background:linear-gradient(180deg,rgba(0,0,0,.15),rgba(0,0,0,.45)); }
.home .icon-over .ico { font-size:3rem; line-height:1; }
/* Custom SVG illustration for the "מה מקבלים" cards. Renders 100px tall
   with a subtle glow so it reads clearly on the gradient background;
   `stroke: currentColor` + `color: #fff` inherit → white line work. */
.home .icon-over .svc-icon { width:100px; height:100px; color:#fff; filter:drop-shadow(0 6px 14px rgba(0,0,0,.25)); }
.home .icon-over .lbl { font-size:.85rem; font-weight:600; font-family:var(--fui),sans-serif; color:rgba(255,255,255,.85); letter-spacing:.05em; }

/* pricing wide layout */
.home .pricing-grid.two-col { max-width:780px; margin:0 auto; grid-template-columns:repeat(2,1fr); }
.home .pricing-grid.three-col { max-width:1180px; margin:0 auto; grid-template-columns:repeat(3,1fr); align-items:stretch; }
@media (max-width:1024px) { .home .pricing-grid.three-col { grid-template-columns:1fr; max-width:520px; } }
/* At the 3-col desktop width each card is ~380px, which is a bit tight for the
   pricing.plus.note first-line ("השדרוג זמין מתוך האתר לאחר הבנייה") - it
   wrapped mid-phrase. Keep the first line as one row (nowrap) and let the
   fineprint sub-line wrap normally underneath the <br>. */
@media (min-width:1025px) {
  .home .pricing-grid.three-col .price-upgrade-note { white-space:nowrap; padding-inline:.3rem; font-size:1rem; }
  .home .pricing-grid.three-col .price-upgrade-note .upgrade-fineprint { white-space:normal; }
}
.home .price-upgrade-note { margin:auto 0 0; color:var(--wa); font-weight:700; font-size:1.05rem; text-align:center; padding:.9rem 1.7rem; }
/* Second line inside .price-upgrade-note (via <br><span>): small, gray,
   normal-weight reassurance about cancellation terms. */
.home .price-upgrade-note .upgrade-fineprint { display:block; margin-top:.35rem; color:var(--muted); font-weight:400; font-size:.85rem; }

/* Successibility promo card (3rd pricing card): stacks two offers
   (free lead-magnet on top, paid widget upsell on bottom) with an "או"
   divider. Uses the same .price-card frame as its siblings so the
   template overrides (bauhaus/noir/wave/etc.) apply automatically. */
.home .price-card-sux { border:1.5px solid #0EA5E9; box-shadow:0 26px 60px -30px rgba(14,165,233,.4); position:relative; padding-top:2.6rem; }
.home .price-card-sux .sux-badge { position:absolute; top:-14px; left:50%; transform:translateX(-50%); background:linear-gradient(90deg, #0EA5E9, #7C3AED); color:#fff; font-family:var(--fui); font-weight:700; font-size:.82rem; padding:.32rem 1rem; border-radius:30px; white-space:nowrap; display:inline-flex; align-items:center; gap:.4rem; }
.home .price-card-sux .sux-badge svg { width:14px; height:14px; }
.home .price-card-sux h3 { font-size:1.15rem; line-height:1.3; margin:0 0 .55rem; }
.home .price-card-sux .sux-offer-desc { margin:0 0 1rem; font-size:.95rem; line-height:1.5; }
.home .price-card-sux .sux-free-cta { justify-content:center; width:100%; }
.home .price-card-sux .sux-or-divider { display:flex; align-items:center; gap:.9rem; margin:1.3rem 0; color:var(--muted); font-weight:600; font-size:.9rem; }
.home .price-card-sux .sux-or-divider::before,
.home .price-card-sux .sux-or-divider::after { content:""; flex:1; height:1px; background:var(--line); }
.home .price-card-sux .sux-price-tag { color:#0EA5E9; font-size:1.9rem; margin:.5rem 0 .1rem; }
.home .price-card-sux .sux-offer-sub { margin:0 0 .9rem; font-size:.95rem; color:#0EA5E9; font-weight:700; }
.home .price-card-sux .sux-feats { margin-bottom:1.1rem; }
.home .price-card-sux .sux-feats li { font-size:.94rem; }
.home .price-card-sux .sux-paid-cta { justify-content:center; margin-top:auto; width:100%; background:linear-gradient(90deg, #0EA5E9, #7C3AED); border-color:transparent; color:#fff; }
.home .price-card-sux .sux-paid-cta:hover { filter:brightness(1.05); }
/* Keep the SUX fine note using the same padding as .price-upgrade-note on
   the מקצועי פלוס card so their text baselines align vertically across the
   three-column pricing row. Only the accent color is customized. */
.home .price-card-sux .sux-fine { color:#0EA5E9; }

/* gallery (decorative panels).
   3-col grid: big desktop-shape cube (2fr) + two phone-shape cubes (1fr
   each). Aspect ratios drive per-cube height so the desktop cube reads as a
   landscape browser and the tall cubes read as phones next to it.
   `align-items:end` bottom-aligns all three so they sit on the same
   baseline.

   The overrides are required because the generic .gallery rule (used by
   user sites) sets grid-auto-rows:170px + grid-auto-flow:dense, .big to
   span 2 / span 2, .tall to span 1 / span 2 — all of which would collapse
   the tracks below the cubes' natural size and blow up this 3-col layout. */
.home .gallery { display:grid; grid-template-columns:2fr 1fr 1fr; grid-auto-rows:auto; grid-auto-flow:row; gap:1rem; align-items:start; }
.home .gallery .g { border-radius:var(--radius); position:relative; overflow:hidden; }
.home .gallery .g.big { grid-column:auto; grid-row:auto; aspect-ratio:18 / 19; }
.home .gallery .g.tall { grid-column:auto; grid-row:auto; aspect-ratio:9 / 19; }

/* Demosite cubes — full-page website screenshots the visitor can scroll
   manually with the wheel (no auto-scroll). Matches the phone-live wheel
   interaction above.

   Structure per cube:
     .demosite-frame              — outer "device" body (browser or phone case)
       .demosite-screen           — the clipping viewport (rounded, overflow:hidden)
         img.demosite-img         — the tall screenshot

   Position within the screen is driven by --manual-y (a negative px value)
   set by main.js on wheel events. */
.home .gallery .g.demosite-frame {
  background:#0F172A;
  box-shadow:0 22px 46px -22px rgba(40,25,15,.45);
}
.home .demosite-frame .demosite-screen {
  position:relative;
  width:100%;
  height:100%;
  overflow:hidden;
  border-radius:inherit;
  background:#fff;
  cursor:ns-resize;
}
.home .demosite-frame .demosite-img {
  display:block; width:100%; height:auto;
  transform:translateY(var(--manual-y, 0));
}
/* Neutralise the generic `.gallery .g:hover img { transform:scale(1.07); }`
   for demosite tiles — the scale-up was fighting our translate transform
   and made the tiles "jump" on hover. Keep our translate on hover so the
   scroll position sticks. */
.home .gallery .g.demosite-frame:hover .demosite-img { transform:translateY(var(--manual-y, 0)); }
/* Big cube — desktop-style rounded browser tile, no bezel. */
.home .gallery .g.big.demosite-frame {
  border-radius:14px;
  border:2px solid rgba(40,25,15,.2);
}
/* Tall cubes — phone case. Padding creates the bezel (frame appears around
   the screen), inset shadow gives it depth, ::before draws the centered
   notch bar (matches .phone-live styling above). */
.home .gallery .g.tall.demosite-frame {
  padding:14px 8px 10px;
  border-radius:32px;
  background:linear-gradient(135deg,#0F172A,#1E293B);
  box-shadow:inset 0 0 0 2px #1E293B, 0 22px 46px -22px rgba(40,25,15,.45);
}
.home .gallery .g.tall.demosite-frame .demosite-screen { border-radius:20px; background:#E0F2FE; }
.home .gallery .g.tall.demosite-frame::before {
  content:"";
  position:absolute;
  top:6px;
  left:50%;
  transform:translateX(-50%);
  width:48px;
  height:5px;
  border-radius:3px;
  background:#000;
  z-index:5;
}

/* testimonials (soft band) */
.home #testimonials-home { background:var(--soft); }
.home #testimonials-home .quotes { display:grid; grid-template-columns:repeat(2,1fr); gap:1.5rem; }
.home .quote { background:var(--surface); border-radius:var(--radius); padding:1.8rem; box-shadow:0 18px 40px -28px rgba(40,25,15,.35); }
.home .quote p { font-size:clamp(1.05rem,2vw,1.2rem); margin:0 0 1.3rem; text-wrap:balance; }
.home .quote .who { display:flex; align-items:center; gap:.9rem; }
.home .quote .av { width:46px; height:46px; border-radius:50%; flex:0 0 auto; }
.home .quote .av .fb { display:grid; place-items:center; height:100%; color:#fff; font-family:var(--fui); font-size:1.4rem; font-weight:700; }
.home .quote .who b { font-family:var(--fui); display:block; }
.home .quote .who span { color:var(--muted); font-size:.9rem; }

/* team cards (who) */
.home .team-cards { grid-template-columns:repeat(2,1fr); max-width:820px; margin:0 auto; gap:1.6rem; }
.home .team-card .card-img { aspect-ratio:16/9; }
/* Team cards: floated image + centered name at RTL-start, description text
   flows to the LEFT of the image and continues UNDER it when it overruns
   the image height (classic figure-with-wrapping-text layout).
   `float: inline-start` maps to `float: right` in RTL. */
.home .team-card { display:block; padding:1.4rem 1.5rem 1.6rem; }
.home .team-card::after { content:""; display:block; clear:both; }
.home .team-card .card-img {
  float:inline-start;
  aspect-ratio:auto;
  /* Negative inline-start margin lets the portrait bleed past the card's
     right padding so it sits flush against the RTL-start edge, without
     touching the bio's left margin (that's what `margin-inline-end` is
     for). */
  margin-inline-start:-1rem;
  margin-inline-end:1.2rem;
  margin-bottom:.6rem;
  padding:0;
  background:transparent;
  text-align:center;
  overflow:visible;
}
.home .team-card .card-img img {
  width:auto; height:auto; max-width:100%;
  object-fit:none;
  display:block;
  margin:0 auto;
}
.home .team-card .card-img h3 {
  margin:.55rem 0 0;
  font-size:1.15rem;
  text-align:center;
}
.home .team-card .card-body { padding:0; }
.home .team-role { color:var(--primary); font-weight:600; font-size:.75rem; margin:0 0 .5rem; white-space:nowrap; }
/* Team-role responsive break:
   - Desktop → one-liner: middle dot visible, <br> hidden.
   - Mobile  → two lines: <br> visible, middle dot hidden, wrap allowed. */
.home .team-role .role-br { display:none; }
.home .team-card .card-body .desktop-br { display:inline; }
@media (max-width:600px) {
  .home .team-role { white-space:normal; }
  .home .team-role .role-sep { display:none; }
  .home .team-role .role-br { display:inline; }
  .home .team-card .card-body .desktop-br { display:none; }
}
/* Team-card bio paragraph — sized 10% up from the initial pass so it holds
   its own alongside the portrait. `:not(.team-role)` keeps the role line at
   its own explicit size + nowrap. */
.home .team-card .card-body p:not(.team-role) { font-size:clamp(.9rem,1.65vw,1rem); line-height:1.55; }

/* contact + map */
.home .contact-card { background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); overflow:hidden; display:grid; grid-template-columns:.85fr 1fr; box-shadow:0 30px 70px -34px rgba(40,25,15,.4); }
.home .contact-map { min-height:100%; background:var(--soft); }
.home .contact-map iframe { width:100%; height:100%; min-height:380px; border:0; display:block; }
.home .contact-body { padding:clamp(1.8rem,4vw,3rem); }
.home .contact-body h2 { font-size:clamp(1.8rem,4vw,2.6rem); margin-bottom:.6rem; }

/* footer */
.home footer.site { background:var(--ink); color:rgba(255,255,255,.85); padding:2.5rem 0; }
.home footer.site a { color:#fff; }
.home .foot-row { display:flex; flex-wrap:wrap; gap:1rem 2rem; justify-content:space-between; align-items:center; font-size:.92rem; }
.home .foot-links { display:flex; gap:1.4rem; list-style:none; margin:0; padding:0; }

/* responsive: <=900px hamburger + stacked nav */
@media (max-width:900px) {
  /* Flex layout (not grid) so brand+CTA+hamburger reliably stay on one row
     regardless of nav.primary's display state. */
  .home .nav-row { display:flex; align-items:center; gap:.6rem; height:72px; }
  .home .brand { flex:0 0 auto; margin-inline-end:auto; }
  .home nav.primary { flex:0 0 auto; }
  .home .home-cta { flex:0 1 auto; font-size:.61rem; padding:.45rem .7rem; gap:.35rem; min-width:0; }
  .home .home-cta svg { width:18px; height:18px; flex-shrink:0; }
  .home .menu-toggle { flex:0 0 auto; display:inline-flex; align-items:center; justify-content:center; background:var(--soft); border:1.5px solid var(--primary); color:var(--primary-d); border-radius:10px; width:42px; height:42px; padding:0; cursor:pointer; }
  /* The nav UL is the visible menu — hidden by default, shown as a fixed
     full-width overlay when the hamburger toggle un-hides it. */
  .home #home-nav { display:none; list-style:none; margin:0; padding:0; }
  .home #home-nav:not([hidden]) { display:flex; flex-direction:column; gap:0; position:fixed; inset-inline:0; top:72px; background:var(--bg); border-bottom:1px solid var(--line); padding:.5rem 1.5rem 1.2rem; z-index:60; }
  .home #home-nav a { padding:.85rem .5rem; font-size:1rem; }
  /* Single-column stats card on narrow screens (was overflowing) */
  .home .stat-card { grid-template-columns:1fr; }
  .home .stat + .stat { border-inline-start:none; border-top:1px solid var(--line); }
}
@media (max-width:820px) {
  .home #testimonials-home .quotes, .home .contact-card { grid-template-columns:1fr; }
  .home .pricing-grid, .home .pricing-grid.two-col, .home .cards, .home .team-cards { grid-template-columns:1fr !important; }
  .home .gallery { grid-template-columns:repeat(2,1fr); align-items:start; }
  .home .gallery .g.big { grid-column:span 2; grid-row:auto; aspect-ratio:16 / 9; }
  .home .gallery .g.tall { grid-column:auto; grid-row:auto; aspect-ratio:9 / 19; }
  /* Stack the two-column about section: illustration first, text below.
     The composition itself stays side-by-side (phone + browser inside).
     Callouts and URL bar shrink so they still fit on narrow screens. */
  .home .about-grid { grid-template-columns:1fr; grid-template-areas:"photo" "text"; gap:2rem; }
  .home .about-photo { width:min(420px, 100%); }
  .wa-showcase .wa-callout { font-size:.72rem; padding:.32rem .65rem; }
}
@media (max-width:520px) {
  .wa-showcase .wa-callout { font-size:.62rem; padding:.25rem .55rem; }
  .wa-showcase .wa-callout::before { width:6px; height:6px; box-shadow:0 0 0 2px rgba(37,211,102,.25); }
  .wa-site .browser-url { font-size:.5rem; }
}
@media (max-width:600px) {
  /* Switcher moves next to the hamburger below 600px (see rule at
     style.css:4425-4441) and .home-cta is hidden — no reserved space
     needed. Restore the standard .wrap inline-end padding. */
  .home .nav-row { padding-inline-end:1.5rem; }
  .home .home-cta { white-space:normal; text-align:center; line-height:1.2; font-size:.85rem; padding:.45rem .7rem; max-width:60vw; }
  .home .home-cta .cta-prefix { display:none; }
}
@media (max-width:380px) {
  .home .nav-row { gap:.4rem; }
  .home .brand { font-size:1.58rem; }
  .home .home-cta { font-size:.82rem; padding-inline:.6rem; }
  .home .home-cta svg { width:16px; height:16px; }
  .home .menu-toggle { width:38px; height:38px; }
}

/* ===== Language switcher (landing only) ===== */
/* Circular trigger + drop-down list of languages. Position swaps sides based
   on the language direction: RTL languages (he, ar) → top-inline-end which
   renders on the LEFT, LTR languages → top-inline-end which renders on the
   RIGHT. Using inline-* keeps a single rule under both directions. */
.lang-switcher {
  position: fixed;
  top: 14px;
  inset-inline-end: 14px;
  z-index: 100;
  font-family: 'Rubik', system-ui, sans-serif;
}
html[dir="rtl"] .lang-switcher { inset-inline-end: auto; left: 14px; }
html[dir="ltr"] .lang-switcher { inset-inline-end: auto; right: 14px; }

/* Paid-site visitor switcher: sits inside header.site .nav-row as a flex
   sibling of the WA nav-cta (and mobile hamburger), rather than fixed-
   positioned over the corner. Explicit `order` places it between the
   hamburger (order:99) and the WA pill (order:97 on mobile / default 0
   desktop) so visual RTL reads [ham][lang][wa] mobile / [lang][wa] desktop.
   Overrides the base `.lang-switcher { position:fixed; top:14px; ... }`
   rule + both dir-specific corner offsets above. */
.lang-switcher-visitor {
  position: relative;
  top: auto;
  inset-inline-end: auto;
  left: auto;
  right: auto;
  order: 98;
  flex: 0 0 auto;
  align-self: center;
  width: auto;
  height: auto;
}
html[dir="rtl"] .lang-switcher-visitor,
html[dir="ltr"] .lang-switcher-visitor { left: auto; right: auto; inset-inline-end: auto; }
/* Size + shadow overrides for the visitor variant so the flag button matches
   the hamburger + WA pill: both siblings are 40x40 in the mobile nav
   (menu-toggle explicit 40px; nav-cta ~40px via `.5rem .55rem` padding
   around a 22px glyph). The base `.lang-trigger` rule drops to 36px at
   ≤600px which centers ~2px higher than its neighbours. Muted shadow so
   the flag doesn't visually "float" above its rectangular siblings. */
.lang-switcher-visitor .lang-trigger {
  width: auto;
  height: auto;
  min-height: 32px;
  color: inherit;
  box-shadow: none;
  vertical-align: middle;
}
.lang-switcher-visitor .lang-trigger:hover { background: rgba(0,0,0,.06); box-shadow: none; transform: none; }
/* Anchor the drop-down BELOW the trigger. The switcher wrapper is 40x40 with
   the trigger filling it, so absolute-positioned `.lang-menu` needs an
   explicit `top:100%` — otherwise `top:auto` on absolute positioning falls
   back to the element's static position, which for a normal-flow child of
   an inline-block/flex-item switcher lands NEXT TO the button, not below.
   Sides stay: RTL anchors menu's LEFT to switcher's LEFT so the menu opens
   RIGHTWARD toward the header's center (the switcher itself is at the
   nav-row's flex-end, physically near the viewport's left edge in RTL, so
   opening leftward would overflow off-screen). LTR is mirrored. */
.lang-switcher-visitor .lang-menu {
  position: absolute;
  top: 100%;
  margin-top: 8px;
}
html[dir="rtl"] .lang-switcher-visitor .lang-menu { left: 0; right: auto; }
html[dir="ltr"] .lang-switcher-visitor .lang-menu { right: 0; left: auto; }

.lang-trigger {
  min-height: 32px;
  border-radius: 8px;
  border: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
  padding: 4px 8px;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font: inherit;
  font-weight: 700;
  font-size: .95rem;
  line-height: 1;
  transition: background .15s ease, transform .15s ease;
}
.lang-trigger:hover { background: rgba(0,0,0,.06); }
.lang-trigger:focus-visible { outline: 2px solid #7ED957; outline-offset: 2px; }
.lang-trigger .lang-abbr { display: inline-flex; align-items: center; letter-spacing: .02em; }
.lang-trigger .lang-chevron { width: 10px; height: 6px; opacity: .85; transition: transform .15s ease; flex: 0 0 auto; }
.lang-trigger[aria-expanded="true"] .lang-chevron { transform: rotate(180deg); }

.lang-menu {
  margin-top: 10px;
  background: #1a1a1e;
  color: #fff;
  border-radius: 14px;
  padding: 8px;
  min-width: 220px;
  box-shadow: 0 18px 44px rgba(0,0,0,.4);
  border: 1px solid rgba(255,255,255,.08);
  display: flex;
  flex-direction: column;
  gap: 2px;
  position: absolute;
}
html[dir="rtl"] .lang-menu { left: 0; }
html[dir="ltr"] .lang-menu { right: 0; }
.lang-menu[hidden] { display: none; }

.lang-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 10px;
  border: 0;
  background: transparent;
  color: #fff;
  border-radius: 10px;
  cursor: pointer;
  text-align: start;
  font: inherit;
  font-size: 1.02rem;
}
html[dir="rtl"] .lang-item { direction: rtl; }
html[dir="ltr"] .lang-item { direction: ltr; }
.lang-item:hover, .lang-item:focus-visible { background: rgba(255,255,255,.08); outline: none; }
.lang-item .lang-abbr {
  min-width: 28px;
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
  font-size: .95rem;
  letter-spacing: .02em;
  color: rgba(255,255,255,.85);
}
.lang-item .lang-name { flex: 1; }

/* Mobile: hide the nav WA CTA (the hero CTA covers this intent already),
   and park the switcher right beside the hamburger on the same side. The
   hamburger sits at flex-end of the nav-row - visually left in RTL, right
   in LTR - so the switcher offsets inward from that edge by ~hamburger
   width + gap. */
@media (max-width: 600px) {
  .home .home-cta { display: none !important; }

  /* Hamburger on mobile-landing is 42px wide and sits at .wrap padding
     (1.5rem = 24px) from the flex-end edge. Switcher offsets past it by
     42 + 24 + ~10px gap = ~76px from that same edge. */
  .lang-switcher:not(.lang-switcher-visitor) { top: 18px; }
  html[dir="rtl"] .lang-switcher:not(.lang-switcher-visitor) { left: 76px; right: auto; }
  html[dir="ltr"] .lang-switcher:not(.lang-switcher-visitor) { right: 76px; left: auto; }
  .lang-menu { min-width: 200px; }
  /* Drop-down anchors under the trigger toward the middle of the header so
     it doesn't drift off-screen next to the hamburger edge. */
  html[dir="rtl"] .lang-menu { left: 0; right: auto; }
  html[dir="ltr"] .lang-menu { right: 0; left: auto; }
}
@media (max-width: 380px) {
  html[dir="rtl"] .lang-switcher:not(.lang-switcher-visitor) { left: 70px; }
  html[dir="ltr"] .lang-switcher:not(.lang-switcher-visitor) { right: 70px; }
}

/* ===== Translating modal (Phase 4) ===== */
.translating-modal-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 1rem;
  padding: 1rem 0.5rem;
  text-align: center;
}
.translating-modal-body p { margin: 0; }
.translating-modal-body .translating-modal-hint {
  color: var(--muted, #6E5F55);
  font-size: 0.9rem;
}
.spinner {
  border: 3px solid var(--line, #e5e5e5);
  border-top-color: var(--primary, #2F7D32);
  border-radius: 50%;
  width: 28px;
  height: 28px;
  animation: presentsimple-spin 0.9s linear infinite;
}
.spinner-lg { width: 44px; height: 44px; border-width: 4px; }
@keyframes presentsimple-spin {
  to { transform: rotate(360deg); }
}

/* Arabic font: apply Noto Sans Arabic when the page is Arabic so all
   templates render properly regardless of the template's font stack.
   Only affects landing + user sites tagged `<html lang="ar">`. */
html[lang="ar"], html[lang="ar"] body, html[lang="ar"] .brand, html[lang="ar"] h1, html[lang="ar"] h2, html[lang="ar"] h3 {
  font-family: 'Noto Sans Arabic', 'Rubik', system-ui, sans-serif !important;
}

/* Legal-edit modal in-modal lang switcher */
.legal-lang-switch { display: flex; align-items: center; gap: .5rem; margin-bottom: .75rem; }
.legal-lang-switch label { font-size: .9rem; color: var(--muted, #6E5F55); font-weight: 600; }
.legal-lang-switch select { padding: .3rem .5rem; border: 1px solid var(--line, #e5e5e5); border-radius: 8px; background: var(--surface, #fff); color: var(--ink, #1a1a1e); font-family: inherit; }

/* ===== Bloggpt integration UI ===== */

/* Edit-strip pill "כתבה חדשה לאישור בבלוג" - sits inside .edit-tools-strip-end
   next to the publish button. Metrics (font-size / padding / border-radius /
   line-height) mirror .publish-btn so the two chips read as siblings; only
   the color palette differs (amber = attention, not danger). */
.blog-pill {
  font-family: var(--fui), sans-serif; font-weight: 700; font-size: .9rem;
  padding: .45rem 1rem; line-height: 1.15;
  border-radius: 30px; border: none;
  background: linear-gradient(135deg, #FBBF24, #F59E0B);
  color: #fff;
  cursor: pointer;
  display: inline-flex; align-items: center; justify-content: center; gap: .35em;
  box-shadow: 0 4px 12px -6px rgba(180, 83, 9, .55);
  transition: transform .15s, background .2s;
}
/* Class-level `display: inline-flex` outranks the browser's default
   `[hidden] { display: none }` rule (attribute selectors have lower
   specificity than class selectors). Restore the hidden behaviour explicitly
   so `pill.hidden = true` from blog.js actually removes the pill from view. */
.blog-pill[hidden] { display: none; }
.blog-pill::before { content: "📝"; font-size: 1rem; line-height: 1; }
.blog-pill:hover { transform: translateY(-1px); background: linear-gradient(135deg, #F59E0B, #D97706); }
.blog-pill:focus-visible { outline: 2px solid #B45309; outline-offset: 2px; }
.blog-pill .blog-pill-count { font-weight: 800; }

/* ---- Full-screen overlay chrome (used by both reader + editor) ----
   Chrome colors are pinned (not template-driven) so the reader stays legible
   on dark templates like noir, whose palette left the close button and card
   titles as light-on-light or dark-on-dark. Articles live on the site but
   the overlay itself is app UI, so it uses the same white/blue chrome as
   the rest of the wizard modals. */
.blog-overlay {
  position: fixed; inset: 0; z-index: 1100;
  background: #fff; color: #1a1a1e;
  display: grid; grid-template-rows: auto 1fr;
  overflow: hidden;
}
body.blog-overlay-open { overflow: hidden; }
.blog-overlay-head {
  display: flex; align-items: center; gap: 1rem;
  padding: .9rem 1.25rem;
  border-bottom: 1px solid #E5E7EB;
  background: #F8FAFC;
}
.blog-overlay-title {
  margin: 0; font-size: 1.15rem; font-weight: 700; flex: 1 1 auto;
  color: #1a1a1e;
}
.blog-overlay-close {
  background: transparent; border: 1px solid #E5E7EB; border-radius: 8px;
  width: 36px; height: 36px; display: inline-flex; align-items: center; justify-content: center;
  color: #4B5563; cursor: pointer;
}
.blog-overlay-close:hover { background: #F1F5F9; color: #0F172A; }
.blog-overlay-body {
  overflow-y: auto; padding: 1.25rem;
  /* Narrow scrollbar - Firefox uses the standard property; WebKit needs
     the vendor-prefixed selectors just below. */
  scrollbar-width: thin;
  scrollbar-color: rgba(148, 163, 184, .55) transparent;
}
.blog-overlay-body::-webkit-scrollbar { width: 8px; }
.blog-overlay-body::-webkit-scrollbar-track { background: transparent; }
.blog-overlay-body::-webkit-scrollbar-thumb { background: rgba(148, 163, 184, .55); border-radius: 999px; }
.blog-overlay-body::-webkit-scrollbar-thumb:hover { background: rgba(100, 116, 139, .75); }

/* ---- Public reader overlay ---- */
.blog-reader { max-width: 900px; margin: 0 auto; }
.blog-reader-loading, .blog-reader-empty { color: #6B7280; text-align: center; padding: 3rem 1rem; }
.blog-reader-card {
  border: 1px solid #E5E7EB; border-radius: 12px;
  margin-bottom: .8rem; overflow: hidden; background: #fff;
}
.blog-reader-head {
  display: grid; grid-template-columns: auto 1fr auto; align-items: center;
  gap: 1rem; width: 100%; padding: .75rem 1rem;
  background: transparent; border: 0; text-align: inherit;
  cursor: pointer; font: inherit; color: #1a1a1e;
}
.blog-reader-head:hover { background: rgba(0,0,0,.02); }
.blog-reader-hero { width: 72px; height: 72px; border-radius: 8px; overflow: hidden; background: #f1f5f9; }
.blog-reader-hero img { width: 100%; height: 100%; object-fit: cover; display: block; }
.blog-reader-head-text h4 { margin: 0 0 .2rem; font-size: 1.05rem; font-weight: 700; color: #1a1a1e; }
.blog-reader-dt { margin: 0; color: #6B7280; font-size: .8rem; }
.blog-reader-meta { margin: .3rem 0 0; color: #4B5563; font-size: .9rem; line-height: 1.4; }
.blog-reader-toggle {
  font-size: 1.4rem; font-weight: 700;
  width: 32px; height: 32px; line-height: 30px; text-align: center;
  color: #4B5563; background: #F1F5F9; border-radius: 50%;
}
.blog-reader-body {
  padding: 0 1.25rem 1.25rem;
  line-height: 1.7; color: #1a1a1e;
  border-top: 1px solid #E5E7EB;
}
.blog-reader-body h1, .blog-reader-body h2, .blog-reader-body h3 { margin-top: 1.2rem; }
.blog-reader-body p { margin: .7rem 0; }

/* ---- Admin list view (owner's list of articles) ---- */
.blog-admin-list { max-width: 900px; margin: 0 auto; display: flex; flex-direction: column; gap: .6rem; }
.blog-admin-row {
  display: grid; grid-template-columns: 72px 1fr auto; align-items: center;
  gap: 1rem;
  padding: .7rem 1rem;
  border: 1px solid #E5E7EB; border-radius: 12px;
  background: #fff; color: #1a1a1e;
}
.blog-admin-row[data-status="draft"] { border-inline-start: 4px solid #F59E0B; }
.blog-admin-row[data-status="active"] { border-inline-start: 4px solid #16A34A; }
.blog-admin-row[data-status="cancelled"] { border-inline-start: 4px solid #94A3B8; opacity: .75; }
.blog-admin-row-thumb {
  width: 72px; height: 72px; border-radius: 8px; overflow: hidden;
  background: #f1f5f9; display: flex; align-items: center; justify-content: center;
}
.blog-admin-row-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.blog-admin-row-thumb-empty { color: #6B7280; font-weight: 700; }
.blog-admin-row-title { margin: 0 0 .25rem; font-size: 1rem; font-weight: 700; line-height: 1.3; color: #1a1a1e; }
.blog-admin-row-meta { display: flex; flex-wrap: wrap; gap: .55rem; align-items: center; }
.blog-admin-row-dt { color: #6B7280; font-size: .8rem; }
.blog-admin-row-countdown {
  font-size: .78rem; font-weight: 600; color: #92400E;
  background: rgba(245, 158, 11, .12); padding: .15rem .5rem; border-radius: 999px;
}
.blog-admin-row-edit {
  font-family: var(--fui), sans-serif; font-weight: 700; font-size: .85rem;
  padding: .4rem 1rem; line-height: 1.15;
  border: 1px solid #E5E7EB; border-radius: 999px;
  background: #fff; color: #1a1a1e;
  cursor: pointer; transition: background .15s;
}
.blog-admin-row-edit:hover { background: #F1F5F9; }

/* Back-to-list bar shown above the single-article editor. */
.blog-admin-back-bar { max-width: 900px; margin: 0 auto .8rem; }
.blog-admin-back {
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .35rem .75rem;
  background: transparent; border: 1px solid #E5E7EB; border-radius: 999px;
  color: #1a1a1e; font: inherit; font-weight: 600; font-size: .85rem;
  cursor: pointer;
}
.blog-admin-back:hover { background: #F1F5F9; }

/* ---- Editor overlay ---- */
.blog-editor { max-width: 900px; margin: 0 auto; }
.blog-editor-loading, .blog-editor-empty, .blog-editor-error {
  color: var(--muted, #6E5F55); text-align: center; padding: 3rem 1rem;
}
.blog-editor-error { color: #B91C1C; font-weight: 600; }
.blog-editor-card {
  border: 1px solid var(--line, #E5E5E5); border-radius: 12px;
  padding: 1rem 1.25rem; margin-bottom: 1rem;
  background: var(--surface, #fff);
}
.blog-editor-card[data-status="draft"] { border-inline-start: 4px solid #F59E0B; }
.blog-editor-card[data-status="active"] { border-inline-start: 4px solid #16A34A; }
.blog-editor-card[data-status="cancelled"] { border-inline-start: 4px solid #94A3B8; opacity: .75; }
.blog-editor-card-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: .55rem;
  margin-bottom: .8rem;
  padding-bottom: .5rem; border-bottom: 1px dashed var(--line, #E5E5E5);
}
/* Status badge colors apply to both the editor card AND the admin list row.
   Base color is amber (draft = "on its way up"). Active flips to green,
   cancelled to red. Written as a single set of rules using [data-status] on
   any ancestor (works because `[data-status="X"] .blog-editor-status`
   matches inside both `.blog-admin-row` and `.blog-editor-card`). */
.blog-editor-status {
  display: inline-block; padding: .2rem .55rem;
  background: rgba(245, 158, 11, .12); color: #92400E;
  border-radius: 999px; font-size: .8rem; font-weight: 700;
}
[data-status="active"] .blog-editor-status {
  background: rgba(22, 163, 74, .12); color: #14532D;
}
[data-status="cancelled"] .blog-editor-status {
  background: rgba(220, 38, 38, .12); color: #991B1B;
}
.blog-editor-countdown {
  font-size: .8rem; font-weight: 600; color: #92400E;
  background: rgba(245, 158, 11, .12); padding: .2rem .55rem; border-radius: 999px;
}
.blog-editor-dt { margin-inline-start: auto; }
.blog-editor-dt { color: var(--muted, #6E5F55); font-size: .85rem; }
.blog-editor-field { display: block; margin: .7rem 0; }
.blog-editor-field > span {
  display: block; margin-bottom: .3rem;
  font-weight: 600; font-size: .9rem; color: var(--muted, #6E5F55);
}
.blog-editor-field input, .blog-editor-field textarea {
  width: 100%; padding: .5rem .7rem;
  border: 1px solid var(--line, #E5E5E5); border-radius: 8px;
  font: inherit; background: var(--surface, #fff); color: var(--ink, #1a1a1e);
  box-sizing: border-box;
}
.blog-editor-field textarea { resize: vertical; min-height: 4rem; font-family: inherit; }
.blog-editor-hero { margin: .8rem 0; }
.blog-editor-hero-label { display: block; margin-bottom: .3rem; font-weight: 600; font-size: .9rem; color: var(--muted, #6E5F55); }
.blog-editor-hero-preview {
  width: 100%; max-width: 400px; aspect-ratio: 16 / 9;
  background: #f1f5f9; border-radius: 8px; overflow: hidden;
  display: flex; align-items: center; justify-content: center;
  margin-bottom: .5rem;
}
.blog-editor-hero-preview img { width: 100%; height: 100%; object-fit: cover; display: block; }
.blog-editor-hero-empty { color: var(--muted, #6E5F55); font-size: .9rem; }
.blog-editor-hero-upload { display: inline-flex; align-items: center; gap: .8rem; cursor: pointer; }
.blog-editor-hero-btn {
  display: inline-block; padding: .4rem .9rem;
  border: 1px solid var(--line, #E5E5E5); border-radius: 999px;
  background: var(--surface, #fff); color: var(--ink, #1a1a1e);
  font: inherit; font-weight: 600; font-size: .85rem;
}
.blog-editor-hero-btn:hover { background: rgba(0,0,0,.03); }
.blog-editor-hero-msg { color: var(--muted, #6E5F55); font-size: .85rem; }
.blog-editor-card-actions {
  display: flex; flex-wrap: wrap; align-items: center; gap: .8rem;
  margin-top: 1rem; padding-top: .8rem;
  border-top: 1px dashed var(--line, #E5E5E5);
}
.blog-editor-status-toggle {
  display: flex; flex-wrap: wrap; align-items: center; gap: .8rem;
  font-size: .9rem;
}
.blog-editor-status-toggle label { display: inline-flex; align-items: center; gap: .25rem; cursor: pointer; }
.blog-editor-save {
  font-family: var(--fui), sans-serif; font-weight: 700; font-size: .9rem;
  padding: .5rem 1.2rem; line-height: 1.15;
  border: none; border-radius: 999px;
  background: var(--primary, #0284C7); color: #fff;
  cursor: pointer;
  transition: transform .15s, background .2s;
  box-shadow: 0 4px 12px -6px rgba(0,0,0,.35);
}
.blog-editor-save:hover:not([disabled]) { transform: translateY(-1px); background: var(--primary-d, #0369A1); }
.blog-editor-save[disabled] { opacity: .7; cursor: not-allowed; }
.blog-editor-save-msg { color: var(--muted, #6E5F55); font-size: .85rem; margin-inline-start: auto; }

@media (max-width: 640px) {
  .blog-reader-hero { width: 56px; height: 56px; }
  .blog-overlay-body { padding: 1rem .8rem; }
  .blog-editor-card-actions { justify-content: flex-start; }
  .blog-editor-save-msg { margin-inline-start: 0; }
  .blog-editor-dt { margin-inline-start: 0; }
}

/* ==== Site-URL chip in the edit strip ==================================== */
/* Compact pill showing the current live URL + copy button. Free-plan sites
   show presentsimple.app/sites/<uid>; sites with an active custom domain show
   the domain. Tooltip carries the free-URL vs custom-domain explainer. */
.site-url-chip {
  display: inline-flex; align-items: center; gap: .3rem;
  padding: .28rem .55rem; border-radius: 20px;
  background: rgba(255,255,255,.6);
  border: 1px solid rgba(2,132,199,.28);
  font-family: var(--fui), sans-serif; font-size: .78rem;
  max-width: 42vw; min-width: 0;
  position: relative;
}
/* Styled hover tooltip - replaces the native browser `title` box. Hidden by
   default; fades in after a short delay when the chip is hovered or keyboard-
   focused. Anchored to the chip's inline-start edge so it always extends
   INWARD from the screen edge in both RTL (chip near right edge → extends
   left) and LTR (chip near left edge → extends right). Never overflows the
   viewport past the visible margin. */
.site-url-chip-tip {
  position: absolute;
  top: calc(100% + .35rem);
  inset-inline-start: 0;
  background: #0F172A;
  color: #F1F5F9;
  font-family: var(--fui), sans-serif;
  font-size: .74rem;
  line-height: 1.3;
  padding: .45rem .65rem;
  border-radius: .45rem;
  box-shadow: 0 6px 18px rgba(0,0,0,.22);
  width: max-content;
  max-width: min(280px, calc(100vw - 2rem));
  text-align: start;
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .15s .25s, visibility 0s .4s;
  z-index: 10002;
  white-space: normal;
}
.site-url-chip:hover .site-url-chip-tip,
.site-url-chip:focus-within .site-url-chip-tip {
  opacity: 1;
  visibility: visible;
  transition: opacity .15s .25s, visibility 0s;
}
.site-url-chip[data-state="own"] {
  border-color: rgba(14,122,86,.5);
  background: rgba(14,122,86,.08);
}
.site-url-chip-link {
  color: #0284C7; font-weight: 600; text-decoration: none;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
  min-width: 0; direction: ltr; unicode-bidi: isolate;
}
.site-url-chip[data-state="own"] .site-url-chip-link { color: #0e7a56; }
.site-url-chip-link:hover { text-decoration: underline; }
.site-url-chip-copy {
  background: transparent; border: 0; cursor: pointer;
  font-size: .95rem; line-height: 1; padding: .1rem .25rem;
  border-radius: 6px; color: inherit;
}
.site-url-chip-copy:hover { background: rgba(2,132,199,.12); }
.site-url-chip-copy.copied { font-size: .72rem; font-weight: 600; color: #0e7a56; }
/* Mobile: hide the URL chip entirely. Screen real estate is too tight to
   host the pill + tooltip without pushing the publish button off the top
   row, and mobile users are more likely to hit the site via a fresh WA
   message (which carries the URL) than to copy from the edit chrome. */
@media (max-width: 700px) {
  .site-url-chip { display: none !important; }
}

/* ==== Business-email DNS seeding (edit strip button + modal) ============= */
.email-dns-btn {
  font-family: var(--fui), sans-serif; font-weight: 600; font-size: .82rem;
  padding: .35rem .8rem; border-radius: 24px; border: 1.5px solid var(--primary);
  background: transparent; color: var(--primary); cursor: pointer;
  transition: background .15s, color .15s; white-space: nowrap;
}
.email-dns-btn:hover { background: var(--primary); color: #fff; }
.email-dns-btn::before { content: "✉"; margin-inline-end: .35em; }
.email-dns-btn.connected { border-color: #0e7a56; color: #0e7a56; }

/* Modal - grow wider than the default 440px to fit the records table */
.modal-dialog:has(.email-dns-modal-inner) { max-width: 640px; }

.email-dns-modal-inner .email-modal-intro {
  font-size: .95rem; color: var(--muted, #6E5F55); margin: 0 0 .8rem;
}
.email-dns-modal-inner .email-modal-pick { margin: 0 0 .6rem; font-weight: 600; }

.email-connected-banner {
  background: #ECFDF5; color: #065F46; border: 1px solid #A7F3D0;
  border-radius: 8px; padding: .55rem .8rem; margin: 0 0 .9rem;
  font-size: .88rem;
}

.email-provider-grid {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: .7rem; margin: 0 0 .5rem;
}
.email-provider-card {
  border: 2px solid #E5E7EB; border-radius: 10px; padding: .8rem .9rem;
  cursor: pointer; transition: border-color .15s, background .15s;
  display: flex; flex-direction: column; gap: .35rem;
}
.email-provider-card:hover { border-color: var(--primary); background: #FAFBFC; }
.email-provider-card.selected { border-color: var(--primary); background: #F0F5FF; }
.email-provider-card h4 { margin: 0; font-size: 1rem; }
.email-provider-card p { margin: 0; font-size: .82rem; color: var(--muted, #6E5F55); }
.email-provider-card a {
  font-size: .78rem; color: var(--primary); text-decoration: none;
  margin-top: auto; align-self: flex-start;
}
.email-provider-card a:hover { text-decoration: underline; }

.email-records-table {
  width: 100%; border-collapse: collapse; margin: .6rem 0 .9rem; font-size: .82rem;
}
.email-records-table th, .email-records-table td {
  border-bottom: 1px solid #F0F0F0; padding: .35rem .5rem; text-align: start;
  vertical-align: top;
}
.email-records-table th {
  font-weight: 600; color: var(--muted, #6E5F55); font-size: .75rem;
  text-transform: uppercase; letter-spacing: .04em;
}
.email-records-table td.content { word-break: break-all; }
.email-records-table code { background: #F5F6F8; padding: .1rem .3rem; border-radius: 3px; }

.email-field { display: block; margin: .6rem 0; }
.email-field > span { display: block; font-weight: 600; font-size: .85rem; margin-bottom: .25rem; }
.email-field > input {
  width: 100%; padding: .5rem .7rem; border: 1px solid #D1D5DB; border-radius: 6px;
  font: inherit;
}
.email-field > small { display: block; color: var(--muted, #6E5F55); font-size: .75rem; margin-top: .2rem; }

.email-advanced { margin-top: .6rem; }
.email-advanced summary { cursor: pointer; font-size: .85rem; color: var(--primary); user-select: none; }

.email-loading, .email-error { font-size: .9rem; padding: .8rem 0; }
.email-error { color: #B91C1C; }

.email-result-success { color: #065F46; font-weight: 600; margin: 0 0 .5rem; }
.email-result-partial { color: #B45309; font-weight: 600; margin: 0 0 .5rem; }

.email-result-records, .email-verify-records {
  list-style: none; padding: 0; margin: .5rem 0 1rem; font-size: .82rem;
}
.email-result-records li, .email-verify-records li {
  padding: .3rem .4rem; border-radius: 4px; margin-bottom: .2rem;
}
.email-result-records li.ok, .email-verify-records li.ok { background: #ECFDF5; }
.email-result-records li.fail, .email-verify-records li.fail { background: #FEF2F2; }
.email-verify-records li.mismatch { background: #FFFBEB; }

.email-followup {
  background: #F9FAFB; border-radius: 8px; padding: .8rem 1rem; margin-top: .8rem;
  font-size: .87rem;
}
.email-followup h4 { margin: 0 0 .4rem; font-size: .95rem; }
.email-followup p { margin: .3rem 0; }
.email-followup code {
  background: #ECEFF3; padding: .1rem .3rem; border-radius: 3px; font-size: .8rem;
}

/* ============================================================================
   AI Logo generator (paid plan) — 3 modals
   ============================================================================ */
.logo-modal { display: flex; flex-direction: column; gap: 1rem; }
.logo-modal .logo-upload-zone {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: .5rem; padding: 1.6rem 1rem;
  border: 2px dashed #c8d3dc; border-radius: 12px;
  background: #f7fafc; color: #37474f;
  cursor: pointer; transition: background .15s, border-color .15s, transform .1s;
  text-align: center;
}
.logo-modal .logo-upload-zone:hover,
.logo-modal .logo-upload-zone:focus-visible { background: #eef4f8; border-color: #7fa5c0; outline: none; }
.logo-modal .logo-upload-zone.drag-over { background: #e0f0ff; border-color: #3182ce; transform: scale(1.01); }
.logo-modal .logo-upload-icon { color: #7fa5c0; }
.logo-modal .logo-upload-title { font-weight: 600; font-size: 1rem; }
.logo-modal .logo-upload-hint { font-size: .82rem; color: #789; }
.logo-modal .logo-modal-sep {
  display: flex; align-items: center; gap: .8rem;
  color: #789; font-size: .85rem;
}
.logo-modal .logo-modal-sep::before, .logo-modal .logo-modal-sep::after {
  content: ""; flex: 1; height: 1px; background: #dae3ea;
}
.logo-modal .logo-gen-cta {
  display: flex; align-items: center; justify-content: center; gap: .6rem;
  padding: .85rem 1rem; border-radius: 10px;
  background: #f7fafc; color: #1f2937;
  border: 1px solid #e2e8ec;
  font-weight: 600; font-size: 1rem;
  cursor: pointer; transition: background .12s, border-color .12s, transform .1s;
  font-family: inherit;
}
.logo-modal .logo-gen-cta:hover { background: #eef4f8; border-color: #7fa5c0; }
.logo-modal .logo-gen-cta:active { transform: scale(.99); }
.logo-modal .logo-gen-cta.is-locked { color: #37474f; }
.logo-modal .logo-gen-cta-icon { font-size: 1.15rem; }
/* Premium-plan badge on the AI logo generator CTA — mirrors the exact same
   visual language as `.badge.badge-pro` in the customer manual
   (frontend/public/manual/index.html ~349): mint-tint background + dark
   emerald text. Kept as a decorative <span> here since the whole CTA
   button already handles the "not-paid" click (shows an upgrade toast). */
.logo-modal .badge.badge-pro.logo-gen-badge-pro {
  display: inline-block; flex: 0 0 auto; align-self: center;
  font-size: .72rem; font-weight: 700;
  padding: 3px 10px; border-radius: 999px;
  background: color-mix(in srgb, #059669 14%, transparent);
  color: #047857;
  letter-spacing: .02em; white-space: nowrap; line-height: 1.5;
  margin-inline-start: .3rem;
}

/* Loader */
.logo-loader { align-items: center; padding: 1.5rem .5rem 1rem; text-align: center; }
.logo-loader-title { font-weight: 600; font-size: 1.05rem; margin-top: .8rem; }
.logo-loader-hint { color: #789; font-size: .88rem; }
.logo-spinner {
  display: inline-block; position: relative; width: 64px; height: 64px;
}
.logo-spinner div {
  position: absolute; width: 51px; height: 51px; margin: 6px;
  border: 5px solid #6b46c1; border-radius: 50%;
  animation: logo-spinner-anim 1.2s cubic-bezier(0.5,0,0.5,1) infinite;
  border-color: #6b46c1 transparent transparent transparent;
}
.logo-spinner div:nth-child(1) { animation-delay: -0.45s; }
.logo-spinner div:nth-child(2) { animation-delay: -0.3s; }
.logo-spinner div:nth-child(3) { animation-delay: -0.15s; }
@keyframes logo-spinner-anim {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

/* 5-logo grid */
.logo-grid-hint { color: #556; font-size: .9rem; margin-bottom: .8rem; }
.logo-grid {
  display: grid; grid-template-columns: 1fr; gap: .8rem;
}
@media (min-width: 640px) {
  .logo-grid { grid-template-columns: 1fr 1fr; }
}
/* Tile is a flex row: narrow actions column beside the logo image (never
   over it, so the mark is fully visible). In RTL contexts the actions
   land visually on the OUTER edge naturally via `flex-direction: row`. */
.logo-tile {
  display: flex; align-items: stretch;
  border: 1px solid #e2e8ec; border-radius: 10px; overflow: hidden;
  background: #fff; cursor: default;
  transition: border-color .15s, box-shadow .15s;
}
.logo-tile:hover { border-color: #6b46c1; box-shadow: 0 4px 12px -4px rgba(107,70,193,.25); }
.logo-tile.is-picked { border-color: #059669; box-shadow: 0 0 0 2px color-mix(in srgb, #059669 25%, transparent); }
.logo-tile.is-picked .logo-tile-actions { background: color-mix(in srgb, #059669 8%, #fafbfc); }
.logo-tile-actions {
  flex: 0 0 auto; width: 44px;
  display: flex; flex-direction: column; gap: 6px;
  padding: 6px; border-inline-end: 1px solid #eef2f5;
  background: #fafbfc;
}
.logo-tile-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; border-radius: 8px;
  background: #fff; color: #556;
  border: 1px solid #e2e8ec;
  cursor: pointer; text-decoration: none;
  transition: background .12s, color .12s, border-color .12s, transform .1s;
}
.logo-tile-btn:hover { background: #f5f0ff; color: #6b46c1; border-color: #cbb8ee; }
.logo-tile-btn:active { transform: scale(.95); }
.logo-tile-btn:focus-visible { outline: 2px solid #6b46c1; outline-offset: 2px; }
.logo-tile-image {
  flex: 1; position: relative;
  aspect-ratio: 3 / 1; min-width: 0;
  background: repeating-conic-gradient(#f2f5f7 0% 25%, #fff 0% 50%) 50% / 20px 20px;
  cursor: pointer;
}
.logo-tile-image img {
  width: 100%; height: 100%; object-fit: contain; display: block;
  padding: 8px; background: transparent;
}
.logo-tile-hover {
  position: absolute; inset: 0; display: flex; align-items: center; justify-content: center;
  background: rgba(107,70,193,.85); color: #fff;
  opacity: 0; transition: opacity .15s; pointer-events: none;
}
.logo-tile-image:hover .logo-tile-hover { opacity: 1; }
.logo-tile-pick {
  background: #fff; color: #6b46c1; border: none; padding: .55rem 1rem;
  border-radius: 999px; font-weight: 600; font-size: .9rem; cursor: pointer;
  font-family: inherit; pointer-events: auto;
}

/* Settings modal */
.logo-settings { gap: .9rem; }
.logo-settings-preview {
  background: repeating-conic-gradient(#f2f5f7 0% 25%, #fff 0% 50%) 50% / 20px 20px;
  border-radius: 10px; padding: 1rem; text-align: center;
  min-height: 140px; display: flex; align-items: center; justify-content: center;
}
.logo-settings-preview img { max-width: 100%; max-height: 130px; object-fit: contain; }
.logo-slider-row { display: flex; align-items: center; gap: .8rem; }
.logo-slider-row label {
  min-width: 72px; font-size: .9rem; font-weight: 500; color: #445;
}
.logo-slider-row input[type=range] {
  flex: 1; height: 28px; accent-color: #6b46c1;
}

/* Mobile — centered card, not a bottom sheet. Parent .modal-overlay already
   handles centering via `place-items: center`; we just cap the width and
   keep the tap targets comfortable. */
@media (max-width: 560px) {
  .modal-overlay:has(.logo-modal) { align-items: center; padding-top: 1rem; padding-bottom: 1rem; }
  .modal-dialog:has(.logo-modal) { max-width: 100%; }
  .logo-modal .logo-upload-zone { padding: 1.2rem .8rem; }
  .logo-modal .logo-gen-cta { padding: 1rem 1rem; }  /* larger tap target */
  .logo-tile-image { aspect-ratio: 3.2 / 1; }
  .logo-tile-actions { width: 52px; }
  .logo-tile-btn { width: 40px; height: 40px; }  /* 44px is Apple's HIG min */
  .logo-tile-pick { padding: .8rem 1.4rem; }
  .logo-slider-row { flex-wrap: wrap; }
  .logo-slider-row label { min-width: 0; flex-basis: 100%; }
  .logo-slider-row input[type=range] { flex-basis: 100%; }
}

/* ===== Gallery lightbox =====
   Click-to-enlarge overlay for #app .gallery tiles (view mode only). Icon-
   only arrows carry their wording in aria-label; keyboard (←/→/Esc) and
   touch-swipe navigation are wired in main.js. RTL positions the "prev"
   button on the right edge and "next" on the left. */
body.lb-open { overflow: hidden; }
body:not([data-edit="true"]) #app .gallery .g { cursor: zoom-in; }

.lightbox {
  position: fixed; inset: 0; z-index: 10050;
  background: rgba(10, 10, 12, .92);
  display: flex; align-items: center; justify-content: center;
  padding: 3.5rem 4.5rem;
  animation: lb-in .18s ease-out;
}
@keyframes lb-in { from { opacity: 0; } to { opacity: 1; } }

.lightbox__stage {
  position: relative;
  max-width: 100%; max-height: 100%;
  display: flex; align-items: center; justify-content: center;
}

.lightbox__img {
  display: block;
  max-width: 100%;
  max-height: calc(100vh - 7rem);
  object-fit: contain;
  border-radius: 8px;
  box-shadow: 0 30px 70px rgba(0, 0, 0, .55);
  animation: lb-imgin .22s ease-out;
}

/* Video player in the lightbox — matches image sizing so nav / close buttons
   don't jump when arrowing between an image and a video slide. Native
   controls handle play/pause + scrubbing; we intentionally don't overlay
   custom UI. */
.lightbox__video {
  display: block;
  max-width: 100%;
  max-height: calc(100vh - 7rem);
  border-radius: 8px;
  box-shadow: 0 30px 70px rgba(0, 0, 0, .55);
  background: #000;
  animation: lb-imgin .22s ease-out;
  outline: none;
}

/* Video tile in the gallery grid: overlay a play glyph over the first
   frame so visitors know it's playable (and to distinguish from a still
   image). The glyph fades on hover to hint the click-to-enlarge affordance.
   Suppressed in edit mode so it doesn't get in the way of the delete /
   reorder handles. */
.gallery .g.video-tile { position: relative; }
.gallery .g.video-tile::after {
  content: "";
  position: absolute; inset: 0;
  background:
    radial-gradient(circle at center, rgba(0,0,0,.28), rgba(0,0,0,0) 45%),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 64 64'><circle cx='32' cy='32' r='28' fill='rgba(0,0,0,0.55)'/><polygon points='26,20 26,44 46,32' fill='white'/></svg>") center/56px 56px no-repeat;
  pointer-events: none;
  z-index: 2;
  transition: opacity .2s ease;
}
.gallery .g.video-tile:hover::after { opacity: .55; }
body[data-edit="true"] .gallery .g.video-tile::after { display: none; }
@keyframes lb-imgin { from { transform: scale(.96); opacity: 0; } to { transform: scale(1); opacity: 1; } }

.lightbox__nav,
.lightbox__close {
  position: absolute;
  width: 52px; height: 52px;
  border-radius: 50%;
  border: none;
  background: rgba(255, 255, 255, .14);
  color: #fff;
  display: grid; place-items: center;
  cursor: pointer;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
  transition: background .2s ease, transform .15s ease;
  z-index: 2;
}
.lightbox__nav:hover,
.lightbox__close:hover { background: rgba(255, 255, 255, .26); }
.lightbox__nav:active,
.lightbox__close:active { transform: scale(.94); }
.lightbox__nav:focus-visible,
.lightbox__close:focus-visible { outline: 2px solid #fff; outline-offset: 3px; }

.lightbox__nav { top: 50%; transform: translateY(-50%); }
.lightbox__nav:active { transform: translateY(-50%) scale(.94); }
.lightbox__nav--prev { left: 1rem; }
.lightbox__nav--next { right: 1rem; }
[dir="rtl"] .lightbox__nav--prev { left: auto; right: 1rem; }
[dir="rtl"] .lightbox__nav--next { right: auto; left: 1rem; }
/* Mirror the chevron glyphs in RTL so a right-edge button shows a right-
   pointing arrow (the previous image visually sits to the right in RTL). */
[dir="rtl"] .lightbox__nav svg { transform: scaleX(-1); }

.lightbox__close { top: 1rem; right: 1rem; }
[dir="rtl"] .lightbox__close { right: auto; left: 1rem; }

.lightbox__counter {
  position: absolute; top: 1.1rem; left: 50%;
  transform: translateX(-50%);
  padding: .35rem .8rem;
  border-radius: 999px;
  background: rgba(0, 0, 0, .4);
  color: #fff; font-size: .85rem;
  font-variant-numeric: tabular-nums;
  z-index: 2;
}

@media (max-width: 640px) {
  .lightbox { padding: 3rem .6rem; }
  .lightbox__img,
  .lightbox__video { max-height: calc(100vh - 6rem); border-radius: 6px; }
  .lightbox__nav,
  .lightbox__close { width: 44px; height: 44px; }
  .lightbox__nav--prev { left: .4rem; }
  .lightbox__nav--next { right: .4rem; }
  [dir="rtl"] .lightbox__nav--prev { left: auto; right: .4rem; }
  [dir="rtl"] .lightbox__nav--next { right: auto; left: .4rem; }
  .lightbox__close { top: .5rem; right: .5rem; }
  [dir="rtl"] .lightbox__close { right: auto; left: .5rem; }
  .lightbox__counter { top: .6rem; font-size: .8rem; padding: .3rem .7rem; }
}

@media (prefers-reduced-motion: reduce) {
  .lightbox, .lightbox__img, .lightbox__video { animation: none; }
}

/* ==========================================================================
   Shop (חנות) -- paid-plan storefront: edit-mode manage modal (3 tabs) +
   public cart FAB + public shop/cart/checkout modals.
   ========================================================================== */

/* ----- Edit-strip cart button ----- (matches .email-dns-btn / .publish-btn pill) */
.shop-manage-btn {
  position: relative;
  font-family: var(--fui), sans-serif; font-weight: 600; font-size: .82rem;
  display: inline-flex; align-items: center; gap: .35rem;
  padding: .35rem .8rem; border-radius: 24px; border: 1.5px solid var(--primary);
  background: transparent; color: var(--primary); cursor: pointer;
  transition: background .15s, color .15s; white-space: nowrap;
}
.shop-manage-btn:hover { background: var(--primary); color: #fff; }
.shop-manage-btn svg { flex: 0 0 auto; }

/* Numeric badge showing count of new orders (top-inline-end of the pill). */
.shop-manage-btn-badge {
  position: absolute;
  top: -6px; inset-inline-end: -6px;
  min-width: 18px; height: 18px; padding: 0 5px;
  border-radius: 999px;
  background: #dc2626; color: #fff;
  font-size: .7rem; font-weight: 800; line-height: 18px;
  display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 0 0 2px #fff;
}
.shop-manage-btn-badge[hidden] { display: none; }

/* Beam / pulse when unattended orders are waiting. Two layers so the pulse
   is visible from a distance AND the button itself gets a subtle glow. */
.shop-manage-btn.has-new-orders {
  border-color: #dc2626; color: #dc2626;
  animation: shopManageBeamGlow 1.8s ease-in-out infinite;
}
.shop-manage-btn.has-new-orders:hover { background: #dc2626; color: #fff; }
.shop-manage-btn.has-new-orders::before {
  content: ""; position: absolute; inset: -3px;
  border-radius: 999px;
  box-shadow: 0 0 0 0 rgba(220, 38, 38, .55);
  animation: shopManageBeamPulse 1.8s ease-out infinite;
  pointer-events: none;
}
.shop-manage-btn.has-new-orders .shop-manage-btn-badge {
  animation: shopManageBeamBadge 1.8s ease-in-out infinite;
}
@keyframes shopManageBeamGlow {
  0%, 100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0); }
  50%      { box-shadow: 0 0 8px 1px rgba(220, 38, 38, .45); }
}
@keyframes shopManageBeamPulse {
  0%   { box-shadow: 0 0 0 0 rgba(220, 38, 38, .55); }
  70%  { box-shadow: 0 0 0 10px rgba(220, 38, 38, 0); }
  100% { box-shadow: 0 0 0 0 rgba(220, 38, 38, 0); }
}
@keyframes shopManageBeamBadge {
  0%, 100% { transform: scale(1); }
  50%      { transform: scale(1.12); }
}
@media (prefers-reduced-motion: reduce) {
  .shop-manage-btn.has-new-orders,
  .shop-manage-btn.has-new-orders::before,
  .shop-manage-btn.has-new-orders .shop-manage-btn-badge { animation: none; }
}

@media (max-width: 720px) {
  .shop-manage-btn { font-size: .72rem; padding: .3rem .7rem; }
  .shop-manage-btn-label { display: none; }
}

/* ----- Manage modal shell ----- */
/* Base .modal-dialog caps at 440px which is too narrow for the shop's
   3-tab UI + product/order tables. shop-modal-dialog widens per breakpoint
   (mirrors analytics-modal-dialog / plans-info-dialog pattern). */
.modal-dialog.shop-modal-dialog {
  /* Reserve 16px of gutter on each side of the viewport so the modal never
     sits flush against the screen edge (mobile Safari + Chrome both look
     glued-in without this). Base .modal-dialog uses width:100% + fixed
     max-width, which on narrow screens produces zero side padding. */
  width: min(820px, calc(100vw - 32px));
  max-width: none;
  /* Narrow scrollbar for owner modal + public shop/cart/checkout. Reinforces
     the base .modal-dialog rule with a slightly softer color and, for
     Firefox, explicit `scrollbar-width: thin`. */
  scrollbar-width: thin;
  scrollbar-color: #c8d3dc transparent;
}
@media (min-width: 1280px) {
  .modal-dialog.shop-modal-dialog { width: 960px; }
}

/* Checkout modal (customer form + PayPal Smart Buttons) is content-focused
   -- narrow it so the buttons don't stretch across a 960px canvas and the
   form fields stay at a comfortable reading width. */
.modal-dialog.shop-modal-dialog.shop-checkout-dialog,
.modal-dialog.shop-modal-dialog.shop-checkout-dialog {
  width: min(460px, calc(100vw - 32px));
}
@media (min-width: 1280px) {
  .modal-dialog.shop-modal-dialog.shop-checkout-dialog { width: 460px; }
}
.modal-dialog.shop-modal-dialog::-webkit-scrollbar { width: 6px; height: 6px; }
.modal-dialog.shop-modal-dialog::-webkit-scrollbar-track { background: transparent; }
.modal-dialog.shop-modal-dialog::-webkit-scrollbar-thumb {
  background: #c8d3dc; border-radius: 3px;
}
.modal-dialog.shop-modal-dialog::-webkit-scrollbar-thumb:hover { background: #a0acb8; }

/* Same treatment for any nested scrollable surface inside the shop modal
   (e.g. orders table wrap when the row count overflows, product list when
   many products are added). */
.shop-modal .shop-pane,
.shop-orders-table-wrap,
.shop-products-list,
.shop-cart-lines,
.shop-public-grid {
  scrollbar-width: thin;
  scrollbar-color: #c8d3dc transparent;
}
.shop-modal .shop-pane::-webkit-scrollbar,
.shop-orders-table-wrap::-webkit-scrollbar,
.shop-products-list::-webkit-scrollbar,
.shop-cart-lines::-webkit-scrollbar,
.shop-public-grid::-webkit-scrollbar { width: 6px; height: 6px; }
.shop-modal .shop-pane::-webkit-scrollbar-track,
.shop-orders-table-wrap::-webkit-scrollbar-track,
.shop-products-list::-webkit-scrollbar-track,
.shop-cart-lines::-webkit-scrollbar-track,
.shop-public-grid::-webkit-scrollbar-track { background: transparent; }
.shop-modal .shop-pane::-webkit-scrollbar-thumb,
.shop-orders-table-wrap::-webkit-scrollbar-thumb,
.shop-products-list::-webkit-scrollbar-thumb,
.shop-cart-lines::-webkit-scrollbar-thumb,
.shop-public-grid::-webkit-scrollbar-thumb {
  background: #c8d3dc; border-radius: 3px;
}
.shop-modal .shop-pane::-webkit-scrollbar-thumb:hover,
.shop-orders-table-wrap::-webkit-scrollbar-thumb:hover,
.shop-products-list::-webkit-scrollbar-thumb:hover,
.shop-cart-lines::-webkit-scrollbar-thumb:hover,
.shop-public-grid::-webkit-scrollbar-thumb:hover { background: #a0acb8; }

.shop-modal { width: 100%; }
.shop-tabs {
  display: flex; gap: .3rem; border-bottom: 1px solid #e5e7eb; margin-bottom: 12px;
  overflow-x: auto;
}
.shop-tab {
  border: 0; background: transparent; padding: 8px 14px; cursor: pointer;
  font: inherit; font-weight: 600; color: #6b7699;
  border-bottom: 2px solid transparent; display: inline-flex; align-items: center; gap: .35rem;
  white-space: nowrap; /* keep "ניהול מוצרים" on one line even on 320px screens */
}
.shop-tab:hover { color: #1e2246; }
.shop-tab.is-active { color: #0e9f6e; border-bottom-color: #0e9f6e; }
.shop-tab.is-disabled { opacity: .55; cursor: not-allowed; }
.shop-tab-indicator { display: inline-flex; align-items: center; color: #0e9f6e; }
.shop-tab.is-disabled .shop-tab-indicator { color: #6b7699; }
.shop-tab-icon { display: inline-flex; align-items: center; opacity: .85; }
.shop-tab.is-active .shop-tab-icon { opacity: 1; }
.shop-pane { min-height: 320px; }

/* Display-mode picker (Settings tab, above PayPal card) */
.shop-display-mode-block .shop-display-mode-options {
  display: flex; flex-direction: column; gap: .35rem;
  margin-top: .4rem;
}
.shop-display-mode-opt {
  display: flex; align-items: flex-start; gap: .55rem;
  padding: .55rem .75rem;
  border: 1px solid #e5e7eb; border-radius: 8px;
  cursor: pointer; transition: background .15s, border-color .15s;
  line-height: 1.35;
}
.shop-display-mode-opt:hover { background: #f8fafc; }
.shop-display-mode-opt input[type="radio"] { margin-top: .2rem; accent-color: #0e9f6e; }
.shop-display-mode-opt input[type="radio"]:checked ~ span { color: #0e9f6e; font-weight: 600; }
.shop-display-mode-opt:has(input[type="radio"]:checked) { border-color: #0e9f6e; background: #ecfdf5; }

/* Shop-swap card sizing: applied to whichever section is the swap target
   (#pricing .pricing-grid OR #gallery .gallery). Both get the same
   auto-fill grid + centered layout + card cap so gallery replacement looks
   identical to pricing replacement. */
.pricing-grid.shop-swap-grid,
.gallery.shop-swap-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 340px));
  grid-auto-rows: auto;
  justify-content: center;
  gap: 1.6rem;
}
.shop-swap-card.price-card { max-width: 340px; }
.shop-swap-price-img {
  margin: -1rem -.6rem 1rem;
  border-radius: 10px; overflow: hidden;
  aspect-ratio: 4 / 3; background: rgba(0,0,0,.04);
}
.shop-swap-price-img img { display: block; width: 100%; height: 100%; object-fit: cover; }

/* ----- Buttons inside the shop-manage modal ----- */
/* Force explicit colors so buttons render consistently regardless of the
   site template palette variables (which may not be defined at edit-modal
   context, leaving .btn-primary invisible). */
.shop-modal-dialog .btn-primary {
  background: #0e9f6e; color: #fff;
  border: 0; border-radius: 8px;
  padding: .5rem 1.1rem;
  font: inherit; font-weight: 600; cursor: pointer;
  transition: background .15s;
}
.shop-modal-dialog .btn-primary:hover { background: #0c8c60; }
.shop-modal-dialog .btn-primary:disabled,
.shop-modal-dialog .btn-primary.is-disabled { background: #a7d7c1; cursor: not-allowed; }
.shop-modal-dialog .btn-ghost {
  background: transparent; color: #1e2246;
  border: 1px solid #d1d5db; border-radius: 8px;
  padding: .4rem .9rem;
  font: inherit; font-weight: 500; cursor: pointer;
  transition: background .15s;
}
.shop-modal-dialog .btn-ghost:hover { background: #f1f5f9; }
/* Compact "+" style for row-add buttons (הוסף משלוח / הוסף מוצר). */
.shop-modal-dialog .shop-shipment-add,
.shop-modal-dialog .shop-add-btn {
  align-self: flex-start;
  background: transparent; color: #0e9f6e;
  border: 1.5px dashed #0e9f6e; border-radius: 8px;
  padding: .35rem .9rem; font-size: .88rem; font-weight: 600;
  cursor: pointer; font-family: inherit;
  transition: background .15s;
}
.shop-modal-dialog .shop-shipment-add:hover,
.shop-modal-dialog .shop-add-btn:hover { background: #ecfdf5; }

/* PayPal connect button gets the pill treatment to match other primary CTAs. */
.shop-modal-dialog .shop-paypal-connect {
  background: #0070ba; color: #fff;
  padding: .55rem 1.4rem;
  border-radius: 24px; font-weight: 700;
  display: inline-flex; align-items: center; gap: .4rem;
}
.shop-modal-dialog .shop-paypal-connect:hover { background: #005e9e; }
.shop-modal-dialog .shop-paypal-connect::before {
  content: ""; width: 14px; height: 14px; background: #fff;
  mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M7 21h4l1-6h3a5 5 0 0 0 0-10H8L5 21h2zM10 9h4a2 2 0 1 1 0 4h-3l-1 6' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>") no-repeat center / contain;
  -webkit-mask: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'><path d='M7 21h4l1-6h3a5 5 0 0 0 0-10H8L5 21h2zM10 9h4a2 2 0 1 1 0 4h-3l-1 6' fill='none' stroke='white' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/></svg>") no-repeat center / contain;
}
.shop-modal-dialog .shop-paypal-disconnect {
  color: #b91c1c; border-color: #fecaca;
}

/* Settings pane -- currency + owner-email share the same row on desktop. */
.shop-settings-row {
  display: grid; grid-template-columns: minmax(140px, 200px) 1fr; gap: 14px;
}
@media (max-width: 640px) {
  .shop-settings-row { grid-template-columns: 1fr; }
}

/* Shipments field header: label on inline-end (right in RTL), "+ הוסף משלוח"
   floats to inline-start (left in RTL). */
.shop-field-header {
  display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin-bottom: 6px;
}
.shop-field-header .shop-shipment-add { margin: 0; }

/* ----- Products pane ----- */
.shop-pane-head { display: flex; justify-content: flex-end; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.shop-products-list { display: flex; flex-direction: column; gap: 10px; }
.shop-empty-hint { text-align: center; color: #6b7699; margin: 24px 0; }
.shop-prod-row {
  display: flex; flex-direction: column; gap: 8px;
  border: 1px solid #e5e7eb; border-radius: 10px; padding: 10px; background: #fff;
  touch-action: none;
}
.shop-prod-row.is-dragging { opacity: .8; box-shadow: 0 6px 18px rgba(0,0,0,.14); }
.shop-prod-row-top {
  display: grid;
  grid-template-columns: auto 1fr auto auto auto;
  gap: 8px; align-items: center;
}
.shop-prod-row-bot {
  display: grid; grid-template-columns: 96px 1fr; gap: 10px; align-items: stretch;
}
.shop-drag-handle {
  border: 0; background: transparent; cursor: grab; color: #94a3b8;
  padding: 4px 6px; font-size: 1.2rem; touch-action: none;
}
.shop-prod-thumb {
  width: 96px; height: 96px; border: 2px dashed #cbd5e1; border-radius: 8px;
  display: flex; align-items: center; justify-content: center; overflow: hidden;
  cursor: pointer; background: #f8fafc; text-align: center;
}
.shop-prod-thumb img { width: 100%; height: 100%; object-fit: cover; }
.shop-prod-thumb.drag-over { border-color: #0e9f6e; background: #ecfdf5; }
.shop-prod-thumb-hint { color: #94a3b8; font-size: .75rem; padding: 6px; }
.shop-prod-row .shop-prod-name,
.shop-prod-row .shop-prod-desc {
  border: 1px solid #d1d5db; border-radius: 6px; padding: 6px 10px; font: inherit;
  width: 100%; box-sizing: border-box;
}
.shop-prod-row .shop-prod-desc { resize: vertical; min-height: 60px; }
.shop-price-input {
  display: inline-flex; align-items: center; gap: 4px;
  border: 1px solid #d1d5db; border-radius: 6px; padding: 0 8px 0 0;
  background: #fff;
}
.shop-price-input input {
  border: 0; outline: none; width: 90px; padding: 6px 4px; text-align: end;
  font: inherit; background: transparent;
}
.shop-currency { color: #6b7699; font-weight: 700; font-size: .95rem; }
.shop-active-toggle { display: inline-flex; align-items: center; padding: 0 4px; }

/* Red trash-icon delete button (products + shipments + cart lines). */
.shop-prod-remove, .shop-ship-remove, .shop-cart-line-remove {
  border: 0; background: transparent; cursor: pointer;
  color: #6b7699; padding: 6px; border-radius: 6px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: background .15s, color .15s;
}
.shop-prod-remove:hover, .shop-ship-remove:hover, .shop-cart-line-remove:hover {
  color: #dc2626; background: #fef2f2;
}
.shop-prod-placeholder { border: 2px dashed #94a3b8; border-radius: 10px; background: #f1f5f9; margin: 4px 0; }

/* Delete-confirm dialog: narrower than the main shop modal + a red primary
   button so "מחק" reads clearly as destructive. */
.modal-dialog.shop-confirm-dialog { max-width: 420px; }
.shop-confirm-body { margin: 0 0 8px; line-height: 1.55; }
.shop-confirm-dialog .btn-primary {
  background: #dc2626; color: #fff;
  border: 0; border-radius: 8px;
  padding: .5rem 1.4rem;
  font: inherit; font-weight: 600; cursor: pointer;
}
.shop-confirm-dialog .btn-primary:hover { background: #b91c1c; }
.shop-confirm-dialog .btn-ghost {
  background: transparent; color: #1e2246;
  border: 1px solid #d1d5db; border-radius: 8px;
  padding: .45rem 1.1rem;
  font: inherit; font-weight: 500; cursor: pointer;
}

/* ----- Settings pane ----- */
.shop-settings { display: flex; flex-direction: column; gap: 14px; }
.shop-field { display: flex; flex-direction: column; gap: 4px; }
.shop-field-label { font-weight: 600; color: #1e2246; }
.shop-field-hint { color: #6b7699; margin: 2px 0 4px; font-size: .9rem; }
.shop-field input, .shop-field select, .shop-field textarea {
  border: 1px solid #d1d5db; border-radius: 6px; padding: 8px 10px; font: inherit;
}
.shop-shipments-list { display: flex; flex-direction: column; gap: 6px; margin: 6px 0; }
.shop-ship-row {
  display: grid;
  grid-template-columns: 1fr auto auto auto;
  gap: 10px; align-items: center;
  border: 1px solid #e5e7eb; border-radius: 8px; padding: 8px 10px; background: #fff;
}
.shop-ship-row input.shop-ship-name {
  border: 1px solid #d1d5db; border-radius: 6px; padding: 6px 10px; font: inherit;
  width: 100%; box-sizing: border-box;
}
.shop-paypal-block { border: 1px solid #e5e7eb; border-radius: 10px; padding: 12px; background: #f8fafc; }
.shop-paypal-email-row {
  display: grid;
  grid-template-columns: auto 1fr auto;
  gap: 8px; align-items: center; margin-top: 10px;
}
.shop-paypal-email-label { font-weight: 600; color: #1e2246; font-size: .9rem; }
.shop-paypal-email-row input {
  border: 1px solid #d1d5db; border-radius: 6px; padding: 6px 10px; font: inherit;
  width: 100%; box-sizing: border-box;
}
.shop-paypal-connect-btn {
  border: 0; border-radius: 8px; cursor: pointer;
  padding: .45rem .95rem; font: inherit; font-weight: 600;
  transition: background .15s, color .15s;
  display: inline-flex; align-items: center; gap: .35rem;
  background: #0070ba; color: #fff;
  min-width: 96px; justify-content: center;
}
.shop-paypal-connect-btn:hover { background: #005e9e; }
.shop-paypal-connect-btn[data-state="checking"] {
  background: #94a3b8; cursor: wait;
}
.shop-paypal-connect-btn[data-state="connected"] {
  background: #dcfce7; color: #166534; cursor: default;
}
.shop-paypal-connect-btn[data-state="connected"]:hover { background: #dcfce7; }
.shop-paypal-connect-btn > span { display: none; }
.shop-paypal-connect-btn[data-state="idle"] .shop-paypal-connect-btn-idle,
.shop-paypal-connect-btn[data-state="checking"] .shop-paypal-connect-btn-checking,
.shop-paypal-connect-btn[data-state="connected"] .shop-paypal-connect-btn-connected {
  display: inline-flex; align-items: center; gap: .3rem;
}
@media (max-width: 640px) {
  .shop-paypal-email-row { grid-template-columns: 1fr; }
  .shop-paypal-email-label { margin-bottom: -4px; }
}
.shop-paypal-help { margin-top: 10px; color: #6b7699; }
.shop-paypal-help summary { cursor: pointer; font-weight: 600; color: #1e2246; }
.shop-paypal-help ol {
  margin: 6px 0 0;
  padding-inline-start: 1.6rem;
  padding-inline-end: 0;
  line-height: 1.7;
  list-style-position: outside;
}
.shop-paypal-help ol li { padding-inline-start: 4px; }
.shop-fee-notice {
  display: flex; gap: 8px; align-items: flex-start;
  background: #eff6ff; border: 1px solid #bfdbfe; color: #1e3a8a;
  padding: 8px 10px; border-radius: 8px; margin: 8px 0 12px;
  font-size: .78rem; line-height: 1.45;
}
.shop-fee-notice svg { flex: 0 0 auto; margin-top: 2px; width: 14px; height: 14px; }

/* ----- Orders pane ----- */
/* Grid gives every filter column the same 2-row structure (label at top,
   input at bottom). All labels line up at the same y-offset; all inputs
   share the same height, so the row reads as one clean band. Income
   card mirrors this with a value styled to match input height. */
.shop-orders-filters {
  display: grid;
  grid-template-columns: repeat(3, auto) 1fr;
  gap: 12px 14px;
  align-items: end;
  margin-bottom: 14px;
}
.shop-field-inline {
  display: flex; flex-direction: column; gap: 4px;
  font-size: .85rem; color: #6b7699;
}
.shop-field-inline > span { line-height: 1; font-weight: 600; }
.shop-field-inline > input, .shop-field-inline > select {
  border: 1px solid #d1d5db; border-radius: 6px;
  padding: 0 10px; font: inherit;
  height: 34px; box-sizing: border-box; background: #fff;
}
.shop-orders-income { justify-self: end; text-align: end; }
.shop-orders-income-label { color: #6b7699; font-size: .85rem; font-weight: 600; line-height: 1; }
.shop-orders-income-value {
  font-weight: 800; color: #0e9f6e; font-size: 1.15rem;
  height: 34px; line-height: 34px; display: inline-flex; align-items: center;
  justify-content: flex-end;
}
@media (max-width: 640px) {
  .shop-orders-filters { grid-template-columns: 1fr 1fr; }
  .shop-orders-income { grid-column: 1 / -1; }
}

/* ==========================================================================
   Mobile refinements for the shop-manage modal (<= 640px viewport).
   Everything below is a compaction pass: smaller inputs, tighter paddings,
   tighter thumbnails, tighter row-gaps. On very narrow screens (<= 400px)
   we go even further -- dates stack one-per-row so they stop overflowing.
   ========================================================================== */
@media (max-width: 640px) {
  /* Modal chrome */
  .modal-dialog.shop-modal-dialog { padding: .95rem .85rem .8rem; border-radius: 12px; }
  .shop-tabs { gap: 0; margin-bottom: 8px; }
  .shop-tab { padding: 6px 8px; font-size: .82rem; }

  /* Universal input/select/textarea trim */
  .shop-prod-row .shop-prod-name,
  .shop-prod-row .shop-prod-desc,
  .shop-ship-row input.shop-ship-name,
  .shop-price-input input,
  .shop-set-currency,
  .shop-set-owner-email,
  .shop-set-paypal-email,
  .shop-field-inline > input,
  .shop-field-inline > select {
    font-size: .88rem; padding: 5px 8px; height: 32px;
  }
  .shop-prod-row .shop-prod-desc { height: auto; min-height: 44px; padding: 6px 8px; }
  .shop-field-label { font-size: .82rem; }
  .shop-field-hint { font-size: .78rem; }

  /* Buttons -- add-btn / shipment-add tighter */
  .shop-modal-dialog .shop-add-btn,
  .shop-modal-dialog .shop-shipment-add {
    padding: .3rem .7rem; font-size: .8rem;
  }

  /* Product row */
  .shop-prod-row { padding: 8px; gap: 6px; }
  .shop-prod-row-top {
    grid-template-columns: auto 1fr auto;
    grid-template-areas:
      "drag  name  trash"
      "price price toggle";
    row-gap: 4px; column-gap: 6px;
  }
  .shop-prod-row-top .shop-drag-handle  { grid-area: drag; font-size: 1rem; padding: 2px 4px; }
  .shop-prod-row-top .shop-prod-name    { grid-area: name; min-width: 0; }
  .shop-prod-row-top .shop-prod-remove  { grid-area: trash; padding: 4px; }
  .shop-prod-row-top .shop-price-input  { grid-area: price; justify-self: start; }
  .shop-prod-row-top .shop-price-input input { width: 70px; }
  .shop-prod-row-top .shop-active-toggle{ grid-area: toggle; }
  .shop-prod-row-bot { grid-template-columns: 60px 1fr; gap: 6px; }
  .shop-prod-thumb   { width: 60px; height: 60px; border-radius: 6px; }
  .shop-prod-thumb-hint { font-size: .65rem; padding: 4px; }

  /* Shipments -- one row on mobile too, tighter */
  .shop-ship-row {
    grid-template-columns: 1fr auto auto;
    grid-template-areas:
      "name  name    trash"
      "price toggle  toggle";
    row-gap: 4px; column-gap: 6px; padding: 6px 8px;
  }
  .shop-ship-row .shop-ship-name     { grid-area: name; }
  .shop-ship-row .shop-price-input   { grid-area: price; justify-self: start; }
  .shop-ship-row .shop-price-input input { width: 80px; }
  .shop-ship-row .shop-active-toggle { grid-area: toggle; }
  .shop-ship-row .shop-ship-remove   { grid-area: trash; padding: 4px; }

  /* Settings row + PayPal email */
  .shop-settings { gap: 10px; }
  .shop-settings-row { gap: 10px; }
  .shop-shipments-list { gap: 5px; }
  .shop-paypal-block { padding: 10px; }
  .shop-paypal-email-row { grid-template-columns: 1fr; row-gap: 5px; }
  .shop-paypal-connect-btn { justify-self: end; padding: .4rem .9rem; font-size: .85rem; min-width: 82px; }
  .shop-fee-notice { font-size: .74rem; padding: 6px 8px; }
  .shop-paypal-help summary { font-size: .82rem; }
  .shop-paypal-help ol      { font-size: .78rem; }

  /* Orders filters — 2×2 grid: dates on top row; income (right, RTL) +
     status (left, RTL) share row 2. `grid-template-areas` locks the visual
     order regardless of DOM child order. */
  .shop-orders-filters {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "from   to"
      "status income";
    gap: 8px 10px; margin-bottom: 10px;
  }
  .shop-orders-filters .shop-field-inline:nth-child(1) { grid-area: from; }
  .shop-orders-filters .shop-field-inline:nth-child(2) { grid-area: to; }
  .shop-orders-filters .shop-field-inline:nth-child(3) { grid-area: status; }
  .shop-orders-income { grid-area: income; justify-self: stretch; text-align: end; }
  .shop-field-inline > span { font-size: .74rem; }
  .shop-orders-income-value { font-size: .95rem; height: 32px; line-height: 32px; }
  .shop-orders-income-label { font-size: .72rem; }
  /* Orders table -- extra-compact so all 5 columns fit inside the modal
     without wrapping the customer-name or date columns. */
  .shop-orders-table { font-size: .74rem; }
  .shop-orders-table th, .shop-orders-table td { padding: 4px 3px; }
  .shop-orders-table th { font-size: .7rem; letter-spacing: -.01em; }
  .shop-orders-table td { line-height: 1.25; }
  .shop-orders-table .shop-order-status {
    padding: 2px 6px; font-size: .68rem;
  }
}

/* Extra-narrow phones (<= 400px): dates share the top row, status + income
   the second row. In RTL, `income` renders visually right (start-side) and
   `status` visually left. */
@media (max-width: 400px) {
  .shop-orders-filters {
    grid-template-columns: 1fr 1fr;
    grid-template-areas:
      "from   to"
      "status income";
  }
  .shop-orders-filters .shop-field-inline:nth-child(1) { grid-area: from; }
  .shop-orders-filters .shop-field-inline:nth-child(2) { grid-area: to; }
  .shop-orders-filters .shop-field-inline:nth-child(3) { grid-area: status; }
  .shop-orders-income { grid-area: income; grid-column: auto; grid-row: auto; }
}

/* -------------------- Custom dd/mm/yyyy date picker -------------------- */
.shop-date-picker {
  position: relative;
  display: inline-flex; align-items: center;
  border: 1px solid #d1d5db; border-radius: 6px; background: #fff;
  overflow: hidden;
}
.shop-date-picker .shop-date-text {
  border: 0; outline: none;
  padding: 6px 10px; font: inherit;
  height: 32px; box-sizing: border-box;
  width: 100%; min-width: 0;
  background: transparent;
  text-align: start;
}
.shop-date-picker .shop-date-native {
  /* Hide native input entirely; we only use it as the picker source. Keeping
     it in-flow (with clip-path) means showPicker() can anchor to its
     bounding box near the visible text input. */
  position: absolute; inset: 0;
  opacity: 0; pointer-events: none;
  width: 0; height: 0;
}
.shop-date-picker .shop-date-btn {
  flex: 0 0 auto;
  border: 0; background: transparent; cursor: pointer;
  color: #6b7699;
  padding: 0 8px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  transition: color .15s, background .15s;
}
.shop-date-picker .shop-date-btn:hover { color: #1e2246; background: #f1f5f9; }
/* Fill the parent .shop-field-inline column, matching status <select>. */
.shop-field-inline .shop-date-picker { width: 100%; }

/* Table dates -- no wrapping so "25.08.2026" stays on one line. */
.shop-orders-table td:nth-child(2),
.shop-orders-table th:nth-child(2) { white-space: nowrap; }
@media (max-width: 640px) {
  .shop-date-picker .shop-date-text { font-size: .82rem; padding: 4px 8px; height: 30px; }
  .shop-date-picker .shop-date-btn  { padding: 0 6px; height: 30px; }
  /* Order # column (col 1) and date column (col 2) share a compact size so
     the row fits inside the modal width without wrapping. */
  .shop-orders-table td:nth-child(1),
  .shop-orders-table td:nth-child(2) { font-size: .68rem; white-space: nowrap; }
}
.shop-orders-table { width: 100%; border-collapse: collapse; font-size: .9rem; }
.shop-orders-table th, .shop-orders-table td { padding: 8px 10px; text-align: start; border-bottom: 1px solid #f1f5f9; }
.shop-orders-table thead th { background: #f8fafc; font-weight: 700; color: #364152; }
.shop-orders-table tbody tr { cursor: pointer; }
.shop-orders-table tbody tr:hover { background: #f8fafc; }
.shop-order-status {
  border: 0; border-radius: 999px; padding: 4px 12px; font-weight: 700; font-size: .8rem;
  cursor: pointer;
}
.shop-order-status-new        { background: #dcfce7; color: #166534; }
.shop-order-status-in_process { background: #ffedd5; color: #9a3412; }
.shop-order-status-completed  { background: #e5e7eb; color: #364152; }
.shop-order-status-canceled   { background: #fee2e2; color: #991b1b; }
.shop-order-detail-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 12px; margin-bottom: 10px; }
.shop-order-detail-status { display: inline-block; padding: 3px 10px; border-radius: 999px; font-weight: 700; font-size: .8rem; }
.shop-order-detail-date { color: #6b7699; font-size: .85rem; margin: 4px 0 0; }
.shop-order-detail-contacts { line-height: 1.6; }
.shop-order-items { width: 100%; border-collapse: collapse; margin: 8px 0; font-size: .9rem; }
.shop-order-items th, .shop-order-items td { padding: 6px 10px; border-bottom: 1px solid #f1f5f9; text-align: start; }

/* ----- Public shop -- card grid ----- */
.shop-public-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 14px; }
.shop-card {
  display: flex; flex-direction: column; border: 1px solid #e5e7eb; border-radius: 12px;
  overflow: hidden; background: #fff; box-shadow: 0 1px 4px rgba(0,0,0,.03);
}
.shop-card-img { width: 100%; height: 160px; object-fit: cover; background: #f1f5f9; }
.shop-card-img-placeholder { display: block; }
.shop-card-body { padding: 10px 12px; flex: 1; }
.shop-card-body h4 { margin: 0 0 4px; font-size: 1rem; }
.shop-card-desc { color: #6b7699; font-size: .85rem; margin: 0 0 6px; }
.shop-card-price { font-weight: 700; color: #1e2246; margin: 6px 0 0; }
.shop-card-add { margin: 0 12px 12px; }

/* ----- Cart floating action button ----- */
.shop-cart-fab {
  position: fixed; top: 80px; z-index: 4000;
  /* Default LTR: pin to left. HE/AR (RTL): pin to the visually-left edge
     too, which in RTL is inset-inline-end. Net effect: FAB is always on
     the visual LEFT of the viewport regardless of writing direction. */
  left: 16px;
  width: 52px; height: 52px; border-radius: 50%; border: 0; cursor: pointer;
  background: #0e9f6e; color: #fff; display: inline-flex; align-items: center; justify-content: center;
  box-shadow: 0 6px 18px rgba(14,159,110,.35);
}
[dir="rtl"] .shop-cart-fab { left: 16px; right: auto; }
.shop-cart-fab:hover { transform: translateY(-2px); }
.shop-cart-fab-badge {
  position: absolute; top: -6px; inset-inline-end: -6px;
  background: #dc2626; color: #fff; border-radius: 999px; min-width: 22px; height: 22px;
  padding: 0 6px; font-weight: 700; font-size: .75rem; display: inline-flex; align-items: center; justify-content: center;
}
.shop-cart-fab:not(.has-items) .shop-cart-fab-badge { display: none; }
.shop-cart-fab[hidden] { display: none; }
.shop-cart-fab.pulse { animation: shopCartPulse .6s ease-out; }
@keyframes shopCartPulse {
  0%   { transform: scale(1); }
  40%  { transform: scale(1.18); }
  100% { transform: scale(1); }
}

/* Cart line items */
.shop-cart-lines { display: flex; flex-direction: column; gap: 8px; }
.shop-cart-line {
  display: grid; grid-template-columns: 56px 1fr auto auto; gap: 10px; align-items: center;
  border: 1px solid #e5e7eb; border-radius: 10px; padding: 8px;
}
.shop-cart-line img, .shop-cart-line-imgph { width: 56px; height: 56px; object-fit: cover; border-radius: 6px; background: #f1f5f9; }
.shop-cart-line-name { margin: 0; font-weight: 600; }
.shop-cart-line-price { margin: 0; color: #6b7699; font-size: .85rem; }
.shop-cart-line-qty { display: inline-flex; align-items: center; gap: 4px; }
.shop-qty-btn { border: 1px solid #d1d5db; border-radius: 6px; background: #fff; width: 28px; height: 28px; cursor: pointer; font-weight: 700; }
.shop-qty-input { width: 46px; text-align: center; border: 1px solid #d1d5db; border-radius: 6px; padding: 4px; }
.shop-cart-shipment { margin: 12px 0; }
.shop-cart-shipment select { border: 1px solid #d1d5db; border-radius: 6px; padding: 6px 8px; width: 100%; font: inherit; }
.shop-cart-totals { margin-top: 10px; }
.shop-cart-totals p {
  display: flex; justify-content: flex-end; align-items: baseline;
  gap: 6px; margin: 3px 0;
  color: #6b7699; font-size: .95rem;
}
.shop-cart-totals p > span { color: #1e2246; font-weight: 600; min-width: 68px; text-align: end; }
.shop-cart-total-grand {
  margin-top: 8px !important;
  padding-top: 8px;
  border-top: 1px solid #e5e7eb;
  font-size: 1.05rem !important; color: #1e2246 !important; font-weight: 800 !important;
}
.shop-cart-total-grand > span { color: #0e9f6e !important; font-weight: 800; font-size: 1.15rem; }
.shop-cart-tou { display: flex; align-items: center; gap: 8px; margin: 12px 0 0; font-size: .95rem; }
.shop-cart-tou-link { color: #0e9f6e; text-decoration: underline; cursor: pointer; }
.shop-cart-tou-link:hover { color: #0c8c60; }

/* Checkout form + PayPal buttons area */
/* Selector excludes [hidden] because `display:flex` otherwise beats the
   browser's implicit `hidden { display:none }` -- the form would stay
   visible after JS sets form.hidden = true. Same for the other blocks. */
.shop-checkout-form:not([hidden]) { display: flex; flex-direction: column; gap: 8px; }
.shop-checkout-form .shop-field { display: flex; flex-direction: column; gap: 3px; }
.shop-checkout-continue {
  margin-top: 8px;
  border: 0; border-radius: 8px;
  padding: .7rem 1.4rem;
  font: inherit; font-weight: 700; font-size: 1rem;
  cursor: pointer;
  background: #0070ba; color: #fff;      /* PayPal brand blue */
  transition: background .15s, opacity .15s;
}
.shop-checkout-continue:hover:not(:disabled) { background: #005e9e; }
.shop-checkout-continue:disabled,
.shop-checkout-continue[aria-disabled="true"] {
  opacity: .55; cursor: not-allowed; background: #94a3b8;
}
.shop-checkout-form input[dir="ltr"] {
  text-align: start; /* matches the input's own dir (LTR here), not the modal's RTL */
}
.shop-checkout-form input:invalid:not(:placeholder-shown) {
  border-color: #dc2626;
}
.shop-checkout-paypal { margin-top: 14px; }
.shop-checkout-status { color: #6b7699; text-align: center; margin: 8px 0; }
.shop-checkout-success { color: #166534; font-weight: 700; text-align: center; padding: 20px 0; font-size: 1.05rem; }
.shop-checkout-error   { color: #991b1b; font-weight: 700; text-align: center; padding: 20px 0; }

/* Fly-to-cart ghost element */
.shop-fly-ghost {
  position: fixed; z-index: 6000; pointer-events: none;
  border-radius: 8px; object-fit: cover;
  transition: transform .55s cubic-bezier(.55,.05,.55,1.4), opacity .55s ease-out;
}

/* Disabled action button (checkout w/o TOU / empty cart) */
button.is-disabled, button:disabled { opacity: .5; cursor: not-allowed; }

/* ==========================================================================
   Landing plan card -- "beam" sweep on the 3 headline paid features.
   Renders a diagonal shine that travels across the <li> every 4.8s.
   Applied via .price-feat-beam on individual list items in index.html so
   only the homepage plan card shows it; the in-app upgrade modal (rendered
   from PLAN_CARDS_I18N in main.js) intentionally omits the effect.
   ========================================================================== */
.price-feats .price-feat-beam {
  position: relative;
  overflow: hidden;
  isolation: isolate;
  font-weight: 600;
  border-radius: 6px;
  padding: 2px 6px;
  margin-inline-start: -6px;
  background: linear-gradient(90deg,
    color-mix(in srgb, var(--primary, #0e9f6e) 8%, transparent),
    transparent 65%);
}
.price-feats .price-feat-beam::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: linear-gradient(
    115deg,
    transparent 35%,
    color-mix(in srgb, var(--primary, #0e9f6e) 55%, white) 48%,
    color-mix(in srgb, var(--primary, #0e9f6e) 20%, white) 50%,
    color-mix(in srgb, var(--primary, #0e9f6e) 55%, white) 52%,
    transparent 65%
  );
  transform: translateX(-140%);
  animation: priceFeatBeam 4.8s ease-in-out infinite;
  opacity: .55;
  mix-blend-mode: screen;
  z-index: 1;
}
[dir="rtl"] .price-feats .price-feat-beam::after {
  transform: translateX(140%);
  animation-name: priceFeatBeamRtl;
}
[dir="rtl"] .price-feats .price-feat-beam {
  background: linear-gradient(-90deg,
    color-mix(in srgb, var(--primary, #0e9f6e) 8%, transparent),
    transparent 65%);
}
@keyframes priceFeatBeam {
  0%   { transform: translateX(-140%); }
  55%  { transform: translateX(140%); }
  100% { transform: translateX(140%); }
}
@keyframes priceFeatBeamRtl {
  0%   { transform: translateX(140%); }
  55%  { transform: translateX(-140%); }
  100% { transform: translateX(-140%); }
}
@media (prefers-reduced-motion: reduce) {
  .price-feats .price-feat-beam::after { animation: none; opacity: 0; }
}

/* Shop feature sub-line ("Learn more" + PayPal PP mini-logo).
   Renders on a new line under the feature label, both on the landing
   pricing card (.price-feats) and inside the publish/upgrade modal
   plan card (.publish-plan-feats). */
.price-feat-body,
.publish-plan-feat-body { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.price-feat-sub,
.publish-plan-feat-sub {
  display: inline-flex; align-items: center; gap: 5px;
  font-size: .72em; font-weight: 400; line-height: 1.2;
  position: relative; z-index: 2;
}
.price-feat-sub a,
.publish-plan-feat-sub a {
  color: #4b5563; text-decoration: underline;
  text-underline-offset: 2px;
}
.price-feat-sub a:hover,
.publish-plan-feat-sub a:hover { color: #0284C7; }
.pp-mini { display: inline-block; vertical-align: middle; flex: 0 0 auto; }

