/* ==========================================================================
   ABGARMKON — UI v3
   Design system built on the ColorHunt palette
   F0E5CF  ·  F7F6F2  ·  C8C6C6  ·  4B6587
   Light, warm, paper-like. Zero remote assets. RTL + LTR from one sheet.
   ========================================================================== */

/* ---------- Font (self hosted, no CDN) -----------------------------------
   Vazirmatn — SIL Open Font License 1.1, github.com/rastikerdar/vazirmatn.
   The de-facto standard free Persian webfont and the successor to Vazir.
   One variable file covers 100-900, so five weights cost a single 111 KB
   request instead of five separate ~50 KB downloads.
   ------------------------------------------------------------------------ */
@font-face{
	font-family:'Vazirmatn';
	src:url('fonts/Vazirmatn-Variable.woff2') format('woff2') tech('variations'),
	    url('fonts/Vazirmatn-Variable.woff2') format('woff2-variations');
	font-weight:100 900;
	font-display:swap;
}
/* static fallback for the few engines without variable-font support */
@font-face{
	font-family:'Vazirmatn Static';
	src:url('fonts/Vazirmatn-Regular.woff2') format('woff2');
	font-weight:400;
	font-display:swap;
}

/* ==========================================================================
   1. TOKENS
   ========================================================================== */
:root{
	/* -- raw palette ------------------------------------------------------ */
	--cream:      #F0E5CF;
	--paper:      #F7F6F2;
	--stone:      #C8C6C6;
	--slate:      #4B6587;

	/* -- surfaces --------------------------------------------------------- */
	--bg:          #F7F6F2;
	--bg-deep:     #EFEDE6;
	--surface:     #FFFFFF;
	--surface-2:   #FBFAF7;
	--surface-3:   #F2F0EA;
	--surface-cream:#F0E5CF;
	--cream-hover:  #EADDC1;
	--select:       #F0E5CF;
	--surface-ink: #16202B;

	/* -- lines ------------------------------------------------------------ */
	--line:        #E4E1D9;
	--line-strong: #C8C6C6;
	--line-slate:  rgba(75,101,135,.22);

	/* -- text (all AA or better on --bg, --surface and --cream) ----------- */
	--ink:    #16202B;
	--ink-2:  #46566B;
	--ink-3:  #5C6875;
	--ink-on-dark:#F4F2ED;

	/* -- accent ----------------------------------------------------------- */
	--accent:      #4B6587;
	--accent-700:  #3A5170;
	--accent-800:  #2C3F58;
	--accent-100:  #E7EBF1;
	--accent-050:  #F1F3F7;
	--accent-ring: rgba(75,101,135,.30);
	/* light thrown by the lit plan tile — three layers, progressively blurred.
	   Kept low in the light theme so the text over it never loses contrast. */
	--cast-1: .13; --cast-2: .085; --cast-3: .055;

	/* -- status ----------------------------------------------------------- */
	--ok:      #2F6F55;
	--ok-bg:   #E7F1EC;
	--warn:    #8A5D1E;
	--warn-bg: #F7EEDD;
	--danger:  #A33B33;
	--danger-bg:#F8EAE8;

	/* -- radii ------------------------------------------------------------ */
	--r-xs:8px; --r-sm:12px; --r-md:16px; --r-lg:22px; --r-xl:28px; --r-2xl:34px;
	--r-pill:999px;

	/* -- elevation (warm-tinted shadows, never neutral black) ------------- */
	--sh-1:0 1px 2px rgba(30,38,50,.05), 0 1px 1px rgba(30,38,50,.04);
	--sh-2:0 2px 4px rgba(30,38,50,.05), 0 6px 16px -6px rgba(30,38,50,.10);
	--sh-3:0 4px 8px rgba(30,38,50,.05), 0 18px 38px -12px rgba(30,38,50,.16);
	--sh-4:0 8px 16px rgba(30,38,50,.06), 0 34px 64px -20px rgba(30,38,50,.24);
	--sh-accent:0 12px 28px -10px rgba(75,101,135,.55);
	--mark:#D9B478;
	--glass:rgba(255,255,255,.82);
	--glass-strong:rgba(255,255,255,.94);
	--veil:rgba(22,32,43,.28);
	--veil-strong:rgba(22,32,43,.42);
	--veil-soft:rgba(244,241,233,.72);
	--topbar-bg:rgba(247,246,242,.86);
	--onglass:rgba(255,255,255,.72);
	--onglass-hi:rgba(255,255,255,.9);
	--on-accent:#FFFFFF;

	/* -- motion ----------------------------------------------------------- */
	--ease:cubic-bezier(.22,1,.36,1);
	--ease-spring:cubic-bezier(.34,1.4,.5,1);
	--ease-io:cubic-bezier(.65,0,.35,1);
	--t-fast:.16s; --t:.28s; --t-slow:.5s;

	/* -- type scale -------------------------------------------------------
	   Base is 16px: the browser default, the accessibility floor most cited,
	   and inside the 16-18px band recommended for interaction-heavy UI on
	   both phone and desktop. Nothing in the interface goes below 13px. */
	--fs-xs:  .8125rem;  /* 13px — dense metadata, pills, timestamps */
	--fs-sm:  .875rem;   /* 14px — secondary text, captions, hints    */
	--fs-md:  .9375rem;  /* 15px — supporting copy, list rows         */
	--fs-base:1rem;      /* 16px — body, labels, buttons, inputs      */
	--fs-lg:  1.0625rem; /* 17px — card and section titles            */
	--fs-xl:  1.125rem;  /* 18px — prominent titles                   */
	--lh-tight:1.35;
	--lh-body:1.75;      /* Persian sits better with a taller default */

	/* -- metrics ---------------------------------------------------------- */
	--rail:264px;
	--gutter:clamp(16px, 4vw, 40px);
	--tabbar-h:66px;
	--topbar-h:60px;
	--safe-b:env(safe-area-inset-bottom, 0px);
}


/* ==========================================================================
   1b. DARK THEME
   Two doors into the same palette: the viewer's OS setting, and an
   explicit choice stored on <html data-theme>. The explicit choice wins
   in both directions, so light survives a dark OS and vice versa.
   ========================================================================== */
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
	/* surfaces — each step is a visible tier above the one below it */
	--bg:          #10151C;
	--bg-deep:     #0B1016;
	--surface:     #1B222C;
	--surface-2:   #202833;
	--surface-3:   #28313D;
	--surface-cream:#272117;
	--cream-hover: #322A1E;
	--surface-ink: #EDE9E0;
	--select:      #2A384A;

	--line:        #2C3542;
	--line-strong: #38424F;
	--line-slate:  rgba(140,167,204,.28);

	/* text — every one of these clears 4.5:1 on all four surfaces above */
	--ink:    #EDE9E0;
	--ink-2:  #B6BFCA;
	--ink-3:  #939DA9;
	--ink-on-dark:#10151C;

	/* the accent lightens so it can carry text; filled buttons flip to a light
	   fill with a dark label, which is what actually reads on a dark ground */
	--accent:      #8CA7CC;
	--accent-700:  #A6BBD9;
	--accent-800:  #C3D2E6;
	--accent-100:  #26313F;
	--accent-050:  #1E2733;
	--accent-ring: rgba(140,167,204,.34);
	--cast-1: .26; --cast-2: .17; --cast-3: .11;

	--ok:      #6FD1A4;  --ok-bg:    #132A22;
	--warn:    #E5B76E;  --warn-bg:  #2C2416;
	--danger:  #F0938A;  --danger-bg:#2E1A19;

	--mark:#E3C48C;

	/* shadows read as depth only if they are darker than the surface */
	--sh-1:0 1px 2px rgba(0,0,0,.45), 0 1px 1px rgba(0,0,0,.3);
	--sh-2:0 2px 4px rgba(0,0,0,.4), 0 6px 16px -6px rgba(0,0,0,.55);
	--sh-3:0 4px 8px rgba(0,0,0,.4), 0 18px 38px -12px rgba(0,0,0,.6);
	--sh-4:0 8px 16px rgba(0,0,0,.45), 0 34px 64px -20px rgba(0,0,0,.7);
	--sh-accent:0 12px 28px -12px rgba(140,167,204,.45);

	--glass:rgba(27,34,44,.86);
	--glass-strong:rgba(27,34,44,.95);
	--veil:rgba(5,8,12,.5);
	--veil-strong:rgba(5,8,12,.62);
	--veil-soft:rgba(11,16,22,.78);
	--topbar-bg:rgba(16,21,28,.88);
	--onglass:rgba(255,255,255,.09);
	--onglass-hi:rgba(255,255,255,.16);
	--on-accent:#0F141B;
}
}
:root[data-theme="dark"]{
	/* surfaces — each step is a visible tier above the one below it */
	--bg:          #10151C;
	--bg-deep:     #0B1016;
	--surface:     #1B222C;
	--surface-2:   #202833;
	--surface-3:   #28313D;
	--surface-cream:#272117;
	--cream-hover: #322A1E;
	--surface-ink: #EDE9E0;
	--select:      #2A384A;

	--line:        #2C3542;
	--line-strong: #38424F;
	--line-slate:  rgba(140,167,204,.28);

	/* text — every one of these clears 4.5:1 on all four surfaces above */
	--ink:    #EDE9E0;
	--ink-2:  #B6BFCA;
	--ink-3:  #939DA9;
	--ink-on-dark:#10151C;

	/* the accent lightens so it can carry text; filled buttons flip to a light
	   fill with a dark label, which is what actually reads on a dark ground */
	--accent:      #8CA7CC;
	--accent-700:  #A6BBD9;
	--accent-800:  #C3D2E6;
	--accent-100:  #26313F;
	--accent-050:  #1E2733;
	--accent-ring: rgba(140,167,204,.34);
	--cast-1: .26; --cast-2: .17; --cast-3: .11;

	--ok:      #6FD1A4;  --ok-bg:    #132A22;
	--warn:    #E5B76E;  --warn-bg:  #2C2416;
	--danger:  #F0938A;  --danger-bg:#2E1A19;

	--mark:#E3C48C;

	/* shadows read as depth only if they are darker than the surface */
	--sh-1:0 1px 2px rgba(0,0,0,.45), 0 1px 1px rgba(0,0,0,.3);
	--sh-2:0 2px 4px rgba(0,0,0,.4), 0 6px 16px -6px rgba(0,0,0,.55);
	--sh-3:0 4px 8px rgba(0,0,0,.4), 0 18px 38px -12px rgba(0,0,0,.6);
	--sh-4:0 8px 16px rgba(0,0,0,.45), 0 34px 64px -20px rgba(0,0,0,.7);
	--sh-accent:0 12px 28px -12px rgba(140,167,204,.45);

	--glass:rgba(27,34,44,.86);
	--glass-strong:rgba(27,34,44,.95);
	--veil:rgba(5,8,12,.5);
	--veil-strong:rgba(5,8,12,.62);
	--veil-soft:rgba(11,16,22,.78);
	--topbar-bg:rgba(16,21,28,.88);
	--onglass:rgba(255,255,255,.09);
	--onglass-hi:rgba(255,255,255,.16);
	--on-accent:#0F141B;
}

/* --- Pieces that carry their own colour and cannot ride on a token alone.
       Written once and emitted twice: inside the media query for viewers who
       have not chosen, and on the attribute for viewers who have. (An earlier
       version generated these line by line, which closed the media query
       immediately after each selector and silently broke every multi-line
       rule — the balance card kept its light gradient in dark mode.) --- */
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]) .btn-primary{ --btn-bg:var(--accent); --btn-fg:#0F141B; }
:root:not([data-theme="light"]) .btn-primary:hover{ background:var(--accent-700); }
:root:not([data-theme="light"]) .switch .track::after{ background:#E9EDF2; }
:root:not([data-theme="light"]) .notice-ok{ color:#BFE6D3; }
:root:not([data-theme="light"]) .notice-warn{ color:#EDD5A9; }
:root:not([data-theme="light"]) .notice-danger{ color:#F5C0BA; }
:root:not([data-theme="light"]) .meter > i{ background:linear-gradient(90deg,var(--accent),#B9CBE4); }
:root:not([data-theme="light"]) .toast .gl{ color:#2F6F55; }
/* a QR keeps a white quiet zone whatever the theme, or it stops scanning */
:root:not([data-theme="light"]) .qr{ background:#fff; }

:root:not([data-theme="light"]) .hero-card{
	background:
		radial-gradient(130% 160% at 100% 0%, rgba(190,150,84,.16) 0%, rgba(190,150,84,0) 58%),
		linear-gradient(150deg, #202834 0%, #1B222C 100%);
	border-color:#333D4B;
}
:root:not([data-theme="light"]) .hero-card::after{
	background:radial-gradient(circle at 50% 50%, rgba(206,161,92,.16), rgba(206,161,92,0) 70%);
}

/* --- login scene --- */
:root:not([data-theme="light"]) .auth{ background:var(--bg-deep); }
:root:not([data-theme="light"]) .auth-bg::before{
	background:
		radial-gradient(90% 70% at 78% 8%,  rgba(88,72,44,.5) 0%, rgba(88,72,44,0) 62%),
		radial-gradient(75% 60% at 12% 92%, rgba(75,101,135,.36) 0%, rgba(75,101,135,0) 60%),
		radial-gradient(60% 50% at 96% 88%, rgba(120,92,48,.3) 0%, rgba(120,92,48,0) 66%),
		linear-gradient(168deg,#161C25 0%,#121821 46%,#0C1017 100%);
}
:root:not([data-theme="light"]) .auth-hills path:nth-child(1){ fill:#1B2029; }
:root:not([data-theme="light"]) .auth-hills path:nth-child(2){ fill:#171C24; }
:root:not([data-theme="light"]) .auth-hills path:nth-child(3){ fill:#12161D; }
:root:not([data-theme="light"]) .auth-orb.a{ background:rgba(150,116,60,.4); }
:root:not([data-theme="light"]) .auth-orb.b{ background:rgba(75,101,135,.4); }
:root:not([data-theme="light"]) .auth-orb.c{ background:rgba(90,76,52,.45); }
:root:not([data-theme="light"]) .auth-grain{ mix-blend-mode:overlay; opacity:.2; }
:root:not([data-theme="light"]) .auth-panel{
	background:rgba(27,34,44,.55);
	border-color:rgba(255,255,255,.10);
	box-shadow:0 40px 90px -30px rgba(0,0,0,.75), 0 2px 10px rgba(0,0,0,.4);
}
:root:not([data-theme="light"]) .auth-form{ background:rgba(24,30,39,.9); }
:root:not([data-theme="light"]) .auth-art{
	background:linear-gradient(150deg, rgba(60,50,32,.5), rgba(40,34,22,.3));
	border-inline-start-color:rgba(255,255,255,.08);
}
:root:not([data-theme="light"]) .auth-device{
	background:linear-gradient(160deg,#242C37,#1B212B);
	border-color:rgba(255,255,255,.10);
	box-shadow:0 30px 60px -22px rgba(0,0,0,.75);
}
:root:not([data-theme="light"]) .auth-device-screen{
	background:radial-gradient(110% 90% at 30% 12%, #6E5C39, #40361F);
	box-shadow:inset 0 0 0 1px rgba(140,167,204,.18);
}
:root:not([data-theme="light"]) .auth-device-foot i{ background:var(--line-strong); }
:root:not([data-theme="light"]) .auth-device-foot i:first-child{ background:var(--accent); }
}

:root[data-theme="dark"] .btn-primary{ --btn-bg:var(--accent); --btn-fg:#0F141B; }
:root[data-theme="dark"] .btn-primary:hover{ background:var(--accent-700); }
:root[data-theme="dark"] .switch .track::after{ background:#E9EDF2; }
:root[data-theme="dark"] .notice-ok{ color:#BFE6D3; }
:root[data-theme="dark"] .notice-warn{ color:#EDD5A9; }
:root[data-theme="dark"] .notice-danger{ color:#F5C0BA; }
:root[data-theme="dark"] .meter > i{ background:linear-gradient(90deg,var(--accent),#B9CBE4); }
:root[data-theme="dark"] .toast .gl{ color:#2F6F55; }
/* a QR keeps a white quiet zone whatever the theme, or it stops scanning */
:root[data-theme="dark"] .qr{ background:#fff; }

:root[data-theme="dark"] .hero-card{
	background:
		radial-gradient(130% 160% at 100% 0%, rgba(190,150,84,.16) 0%, rgba(190,150,84,0) 58%),
		linear-gradient(150deg, #202834 0%, #1B222C 100%);
	border-color:#333D4B;
}
:root[data-theme="dark"] .hero-card::after{
	background:radial-gradient(circle at 50% 50%, rgba(206,161,92,.16), rgba(206,161,92,0) 70%);
}

/* --- login scene --- */
:root[data-theme="dark"] .auth{ background:var(--bg-deep); }
:root[data-theme="dark"] .auth-bg::before{
	background:
		radial-gradient(90% 70% at 78% 8%,  rgba(88,72,44,.5) 0%, rgba(88,72,44,0) 62%),
		radial-gradient(75% 60% at 12% 92%, rgba(75,101,135,.36) 0%, rgba(75,101,135,0) 60%),
		radial-gradient(60% 50% at 96% 88%, rgba(120,92,48,.3) 0%, rgba(120,92,48,0) 66%),
		linear-gradient(168deg,#161C25 0%,#121821 46%,#0C1017 100%);
}
:root[data-theme="dark"] .auth-hills path:nth-child(1){ fill:#1B2029; }
:root[data-theme="dark"] .auth-hills path:nth-child(2){ fill:#171C24; }
:root[data-theme="dark"] .auth-hills path:nth-child(3){ fill:#12161D; }
:root[data-theme="dark"] .auth-orb.a{ background:rgba(150,116,60,.4); }
:root[data-theme="dark"] .auth-orb.b{ background:rgba(75,101,135,.4); }
:root[data-theme="dark"] .auth-orb.c{ background:rgba(90,76,52,.45); }
:root[data-theme="dark"] .auth-grain{ mix-blend-mode:overlay; opacity:.2; }
:root[data-theme="dark"] .auth-panel{
	background:rgba(27,34,44,.55);
	border-color:rgba(255,255,255,.10);
	box-shadow:0 40px 90px -30px rgba(0,0,0,.75), 0 2px 10px rgba(0,0,0,.4);
}
:root[data-theme="dark"] .auth-form{ background:rgba(24,30,39,.9); }
:root[data-theme="dark"] .auth-art{
	background:linear-gradient(150deg, rgba(60,50,32,.5), rgba(40,34,22,.3));
	border-inline-start-color:rgba(255,255,255,.08);
}
:root[data-theme="dark"] .auth-device{
	background:linear-gradient(160deg,#242C37,#1B212B);
	border-color:rgba(255,255,255,.10);
	box-shadow:0 30px 60px -22px rgba(0,0,0,.75);
}
:root[data-theme="dark"] .auth-device-screen{
	background:radial-gradient(110% 90% at 30% 12%, #6E5C39, #40361F);
	box-shadow:inset 0 0 0 1px rgba(140,167,204,.18);
}
:root[data-theme="dark"] .auth-device-foot i{ background:var(--line-strong); }
:root[data-theme="dark"] .auth-device-foot i:first-child{ background:var(--accent); }

/* ==========================================================================
   2. RESET
   ========================================================================== */
*,*::before,*::after{ box-sizing:border-box; }
*{ margin:0; padding:0; }
html{
	-webkit-text-size-adjust:100%;
	text-size-adjust:100%;
	scroll-behavior:smooth;
}
html,body{ max-width:100%; overflow-x:clip; }
body{
	min-height:100dvh;
	background:var(--bg);
	color:var(--ink);
	font-family:'Vazirmatn','Vazirmatn Static','Segoe UI',system-ui,-apple-system,'Helvetica Neue',Tahoma,sans-serif;
	font-size:16px;
	line-height:var(--lh-body);
	-webkit-font-smoothing:antialiased;
	-moz-osx-font-smoothing:grayscale;
	font-variant-numeric:tabular-nums;
}
/* Vazirmatn's Latin is a well-drawn companion, so English keeps the same face
   and the interface does not shift shape when the language is switched. */
html[lang="en"] body{ line-height:1.65; }
img,svg,video{ display:block; max-width:100%; }
/* A component that sets its own `display` outranks the UA rule for [hidden],
   so hiding it from script had no effect — which is why the install banner's
   close button appeared to do nothing. */
[hidden]{ display:none !important; }
button,input,select,textarea{ font:inherit; color:inherit; }
button{ background:none; border:none; cursor:pointer; }
a{ color:inherit; text-decoration:none; }
ul,ol{ list-style:none; }
:focus-visible{
	outline:2.5px solid var(--accent);
	outline-offset:2px;
	border-radius:6px;
}
::selection{ background:var(--select); color:var(--ink); }

/* numbers always read LTR, even inside RTL copy */
.num,.mono{ direction:ltr; unicode-bidi:isolate; }
.mono{ font-family:ui-monospace,'SF Mono',Menlo,Consolas,monospace; }

/* ==========================================================================
   3. TYPOGRAPHY
   ========================================================================== */
h1,h2,h3,h4{ line-height:1.25; font-weight:800; letter-spacing:-.015em; }
.t-display{ font-size:clamp(2rem,6.5vw,3.4rem); font-weight:800; letter-spacing:-.03em; line-height:1.1; }
.t-h1{ font-size:clamp(1.4rem,3.6vw,2rem); font-weight:800; letter-spacing:-.02em; }
.t-h2{ font-size:clamp(1.2rem,2.4vw,1.4rem); font-weight:800; letter-spacing:-.015em; }
.t-h3{ font-size:1rem; font-weight:700; }
.t-body{ font-size:1rem; color:var(--ink-2); }
.t-sm{ font-size:.9375rem; }
.t-xs{ font-size:.875rem; }
.t-muted{ color:var(--ink-3); }
.t-dim{ color:var(--ink-2); }
.t-eyebrow{
	font-size:.8125rem; font-weight:700; letter-spacing:.14em;
	text-transform:uppercase; color:var(--ink-3);
}
html[lang="fa"] .t-eyebrow{ letter-spacing:.04em; }

/* ==========================================================================
   4. LAYOUT SHELL
   ========================================================================== */
.shell{ display:flex; min-height:100dvh; align-items:stretch; }

.main{
	flex:1 1 auto;
	min-width:0;
	padding:calc(var(--topbar-h) + 8px) var(--gutter)
	        calc(var(--tabbar-h) + var(--safe-b) + 28px);
	display:flex; flex-direction:column; gap:18px;
}
.main-inner{ width:100%; max-width:1180px; margin-inline:auto; display:flex; flex-direction:column; gap:18px; }

@media (min-width:1024px){
	.main{ padding:28px var(--gutter) 56px; margin-inline-start:var(--rail); }
	.shell.no-rail .main{ margin-inline-start:0; }
}

/* ---------- Page header --------------------------------------------------- */
.page-head{
	display:flex; align-items:flex-start; justify-content:space-between;
	gap:16px; flex-wrap:wrap; margin-bottom:2px;
}
.page-head-text{ min-width:0; }
.page-title{
	display:flex; align-items:center; gap:10px;
	font-size:clamp(1.45rem,3.4vw,1.95rem); font-weight:800; letter-spacing:-.02em;
}
.page-title .gl{ color:var(--accent); flex:none; }
.page-sub{ color:var(--ink-3); font-size:.9375rem; margin-top:2px; }
.page-head-actions{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }

/* ---------- Section header (collapsible, from the services reference) ------ */
.section{ display:flex; flex-direction:column; gap:12px; }
.section-head{
	display:flex; align-items:center; gap:8px;
	font-size:1rem; font-weight:700; color:var(--ink-2);
	cursor:pointer; user-select:none;
	/* a real tap target, not just a text run */
	min-height:38px; padding:4px 10px 4px 4px; width:fit-content;
	margin-inline-start:-4px; border-radius:var(--r-sm);
	background:none; border:none;
	transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
html[dir="rtl"] .section-head{ padding:4px 4px 4px 10px; }
.section-head:hover{ background:var(--surface-3); color:var(--ink); }
.section-head .chev{
	transition:transform var(--t) var(--ease);
	color:var(--ink-3); flex:none;
}
.section-head[aria-expanded="false"] .chev{ transform:rotate(-90deg); }
html[dir="rtl"] .section-head[aria-expanded="false"] .chev{ transform:rotate(90deg); }
.section-head .count{
	font-size:.8125rem; font-weight:700; color:var(--ink-3);
	background:var(--surface-3); border-radius:var(--r-pill);
	padding:1px 8px; margin-inline-start:2px;
}
.section-body{
	display:grid; grid-template-rows:1fr;
	transition:grid-template-rows var(--t-slow) var(--ease), opacity var(--t) var(--ease);
}
.section-body > div{ min-height:0; overflow:hidden; }
.section.collapsed .section-body{ grid-template-rows:0fr; opacity:0; }

/* ==========================================================================
   5. SIDEBAR RAIL (desktop)
   ========================================================================== */
.rail{
	position:fixed; inset-block:0; inset-inline-start:0;
	width:var(--rail); z-index:60;
	display:none; flex-direction:column;
	background:var(--surface);
	border-inline-end:1px solid var(--line);
	padding:20px 14px 16px;
}
@media (min-width:1024px){ .rail{ display:flex; } }

.brand{
	display:flex; align-items:center; gap:10px;
	padding:4px 8px 20px; font-weight:800; font-size:1.125rem; letter-spacing:-.02em;
}
.brand-mark{
	width:34px; height:34px; border-radius:11px; flex:none;
	background:linear-gradient(150deg,var(--accent),var(--accent-800));
	display:grid; place-items:center; color:#fff;
	box-shadow:var(--sh-accent);
}
.brand-mark svg{ width:19px; height:19px; }
.brand-sub{ font-size:.8125rem; font-weight:600; color:var(--ink-3); letter-spacing:.02em; }

/* the sliding pill that follows the active nav item */
.nav{ position:relative; display:flex; flex-direction:column; gap:2px; }
.nav-pill{
	position:absolute; inset-inline:0; height:0; top:0;
	border-radius:var(--r-sm);
	background:var(--accent-050);
	border:1px solid var(--line-slate);
	opacity:0; pointer-events:none;
	transition:transform var(--t-slow) var(--ease-spring),
	           height var(--t-slow) var(--ease-spring),
	           opacity var(--t) var(--ease);
	z-index:0;
}
.nav-group{
	padding:20px 10px 6px;
	font-size:.8125rem; font-weight:700; letter-spacing:.12em; text-transform:uppercase;
	color:var(--ink-3);
}
html[lang="fa"] .nav-group{ letter-spacing:.02em; }
.nav-item{
	position:relative; z-index:1;
	display:flex; align-items:center; gap:11px;
	padding:10px 11px; border-radius:var(--r-sm);
	font-size:.9375rem; font-weight:600; color:var(--ink-2);
	transition:color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.nav-item .gl{ flex:none; color:var(--ink-3); transition:color var(--t-fast) var(--ease); }
.nav-item:hover{ color:var(--ink); }
.nav-item:hover .gl{ color:var(--ink-2); }
.nav-item.active{ color:var(--accent-800); font-weight:700; }
.nav-item.active .gl{ color:var(--accent); }
.nav-item .badge{ margin-inline-start:auto; }
/* without JS the sliding pill never appears, so paint the active item itself */
html:not(.js) .nav-item.active{ background:var(--accent-050); box-shadow:inset 0 0 0 1px var(--line-slate); }

.rail-foot{ margin-top:auto; padding-top:16px; display:flex; flex-direction:column; gap:2px; }
.rail-sep{ height:1px; background:var(--line); margin:12px 4px; }

/* user card at the bottom of the rail (from the dashboard reference) */
.user-card{
	display:flex; align-items:center; gap:10px;
	padding:9px 10px; border-radius:var(--r-md);
	background:var(--surface-2); border:1px solid var(--line);
}
.avatar{
	width:34px; height:34px; border-radius:11px; flex:none;
	background:var(--surface-cream); color:var(--accent-800);
	display:grid; place-items:center; font-weight:800; font-size:.875rem;
	border:1px solid var(--line-slate);
}
.user-card-text{ min-width:0; flex:1; }
.user-card-name{
	display:block;
	font-size:.9375rem; font-weight:700; white-space:nowrap;
	overflow:hidden; text-overflow:ellipsis;
}
.user-card-meta{ display:block; font-size:.8125rem; color:var(--ink-3); }

/* ==========================================================================
   6. TOP BAR (mobile / tablet)
   ========================================================================== */
.topbar{
	position:fixed; inset-block-start:0; inset-inline:0; z-index:55;
	height:var(--topbar-h);
	display:flex; align-items:center; gap:10px;
	padding-inline:var(--gutter);
	background:var(--topbar-bg);
	-webkit-backdrop-filter:saturate(180%) blur(14px);
	backdrop-filter:saturate(180%) blur(14px);
	border-bottom:1px solid transparent;
	transition:border-color var(--t) var(--ease), background var(--t) var(--ease);
}
.topbar.stuck{ border-bottom-color:var(--line); }
.topbar .brand{ padding:0; font-size:1.0625rem; }
.topbar-spacer{ flex:1; }
@media (min-width:1024px){ .topbar{ display:none; } }

/* ==========================================================================
   7. BUTTONS
   ========================================================================== */
.btn{
	--btn-bg:var(--surface); --btn-fg:var(--ink); --btn-bd:var(--line-strong);
	position:relative; display:inline-flex; align-items:center; justify-content:center;
	gap:8px; padding:11px 18px; border-radius:var(--r-sm);
	background:var(--btn-bg); color:var(--btn-fg);
	box-shadow:inset 0 0 0 1px var(--btn-bd);
	font-size:.9375rem; font-weight:700; line-height:1.2;
	white-space:nowrap; text-align:center;
	transition:transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease),
	           background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
	-webkit-tap-highlight-color:transparent;
}
.btn:hover{ background:var(--surface-2); }
.btn:active{ transform:scale(.975); }
.btn:disabled,.btn[aria-disabled="true"]{ opacity:.5; pointer-events:none; }
.btn .gl{ flex:none; }

.btn-primary{
	--btn-bg:var(--accent); --btn-fg:#fff; --btn-bd:transparent;
	box-shadow:var(--sh-accent);
}
.btn-primary:hover{ background:var(--accent-700); box-shadow:0 14px 32px -10px rgba(75,101,135,.62); }

.btn-cream{ --btn-bg:var(--surface-cream); --btn-fg:var(--accent-800); --btn-bd:var(--line-slate); }
.btn-cream:hover{ background:var(--cream-hover); }

.btn-ghost{ --btn-bg:transparent; --btn-bd:var(--line-strong); }
.btn-ghost:hover{ background:var(--surface-3); }

.btn-quiet{ --btn-bg:transparent; --btn-bd:transparent; color:var(--ink-2); }
.btn-quiet:hover{ background:var(--surface-3); color:var(--ink); }

/* sits on a tinted or glass panel, so it needs its own translucent fill rather
   than a hard-coded white one that inverts badly in dark */
.btn-onglass{ --btn-bg:var(--onglass); --btn-bd:var(--line-slate); }
.btn-onglass:hover{ background:var(--onglass-hi); }

.btn-danger{ --btn-bg:var(--danger-bg); --btn-fg:var(--danger); --btn-bd:rgba(163,59,51,.24); }
.btn-danger:hover{ background:#F3DDDA; }

.btn-block{ width:100%; }
.btn-sm{ padding:8px 13px; font-size:.875rem; border-radius:var(--r-xs); }
.btn-lg{ padding:14px 22px; font-size:1.0625rem; border-radius:var(--r-md); }

/* icon-only */
.btn-icon{ padding:0; width:40px; height:40px; border-radius:var(--r-sm); flex:none; }
.btn-icon.btn-sm{ width:34px; height:34px; }

/* loading state */
.btn.is-loading{ color:transparent !important; pointer-events:none; }
.btn.is-loading::after{
	content:''; position:absolute; inset-block-start:50%; inset-inline-start:50%;
	width:17px; height:17px; margin-block-start:-8.5px; margin-inline-start:-8.5px;
	border:2.2px solid currentColor; border-top-color:transparent; border-radius:50%;
	color:var(--btn-fg); opacity:.9;
	animation:spin .62s linear infinite;
}
.btn-primary.is-loading::after{ color:#fff; }
@keyframes spin{ to{ transform:rotate(360deg); } }

/* ==========================================================================
   8. CARDS
   ========================================================================== */
.card{
	background:var(--surface);
	border:1px solid var(--line);
	border-radius:var(--r-lg);
	padding:clamp(16px,3vw,22px);
	box-shadow:var(--sh-1);
}
.card-flat{ box-shadow:none; }
.card-2{ background:var(--surface-2); }
.card-cream{ background:var(--surface-cream); border-color:rgba(75,101,135,.14); }
.card-head{
	display:flex; align-items:center; gap:9px; flex-wrap:wrap;
	font-size:1.0625rem; font-weight:700; letter-spacing:-.01em;
	margin-bottom:14px;
}
.card-head .gl{ color:var(--accent); flex:none; }
.card-head .spacer{ flex:1; }
.card-note{ font-size:.875rem; color:var(--ink-3); line-height:1.85; }

/* ---------- Notched hero card (the "current plan" card in the reference) --- */
.hero-grid{
	display:grid; gap:14px;
	grid-template-columns:1fr;
}
@media (min-width:880px){ .hero-grid{ grid-template-columns:1.45fr 1fr; } }

.hero-card{
	position:relative; overflow:hidden;
	border-radius:var(--r-lg);
	border:1px solid var(--line);
	/* The warm bloom is decoration and stays in the far corner; the half of the
	   card that carries the balance and the key/value rows stays close to plain
	   white so the text keeps its full contrast. */
	background:
		radial-gradient(120% 150% at 100% 0%, rgba(240,229,207,.8) 0%, rgba(240,229,207,0) 52%),
		linear-gradient(150deg, #FFFFFF 0%, #FCFBF9 70%, #F8F6F0 100%);
	box-shadow:var(--sh-2);
	padding:clamp(18px,3vw,24px);
	display:flex; flex-direction:column; gap:14px;
	min-height:150px;
}
/* the warm bloom in the far corner, echoing the reference's gradient panel */
.hero-card::after{
	content:''; position:absolute; z-index:0;
	inset-block-start:-40%; inset-inline-end:-18%;
	width:min(58%,340px); aspect-ratio:1;
	background:radial-gradient(circle at 50% 50%, rgba(224,182,120,.3), rgba(224,182,120,0) 70%);
	pointer-events:none;
}
.hero-card > *{ position:relative; z-index:1; }
.hero-top{ display:flex; align-items:flex-start; justify-content:space-between; gap:12px; }
.hero-label{ font-size:.875rem; font-weight:700; color:var(--ink-2); display:flex; align-items:center; gap:7px; }
.hero-value{
	font-size:clamp(1.9rem,5.6vw,2.6rem); font-weight:800; letter-spacing:-.035em;
	line-height:1.05; display:flex; align-items:baseline; gap:8px; flex-wrap:wrap;
}
.hero-value .unit{ font-size:.9375rem; font-weight:700; color:var(--ink-3); letter-spacing:0; }
.hero-rows{ display:flex; flex-direction:column; gap:7px; }
.hero-row{
	display:flex; align-items:center; justify-content:space-between; gap:12px;
	font-size:.875rem; color:var(--ink-2);
}
.hero-row .k{ display:flex; align-items:center; gap:7px; color:var(--ink-3); }
.hero-row .v{ font-weight:700; color:var(--ink); }
.hero-actions{ display:flex; gap:8px; flex-wrap:wrap; margin-top:2px; }

/* ---------- Metric / meter card ------------------------------------------ */
.meter-card{ display:flex; flex-direction:column; gap:12px; justify-content:center; }
.meter-value{
	font-size:clamp(1.7rem,5vw,2.3rem); font-weight:800; letter-spacing:-.035em; line-height:1;
	display:flex; align-items:baseline; gap:7px; flex-wrap:wrap;
}
.meter-value .unit{ font-size:.875rem; font-weight:700; color:var(--ink-3); letter-spacing:0; }
.meter{
	height:7px; border-radius:var(--r-pill); background:var(--surface-3);
	overflow:hidden; box-shadow:inset 0 0 0 1px var(--line);
}
.meter > i{
	display:block; height:100%; border-radius:inherit;
	background:linear-gradient(90deg,var(--accent),#6E88AC);
	width:0; transition:width 1.1s var(--ease);
}
.meter-legend{ display:flex; justify-content:space-between; font-size:.8125rem; color:var(--ink-3); }

/* ---------- Stat strip ---------------------------------------------------- */
.stats{ display:grid; gap:12px; grid-template-columns:repeat(auto-fit,minmax(150px,1fr)); }
.stat{
	background:var(--surface); border:1px solid var(--line); border-radius:var(--r-md);
	padding:14px 16px; display:flex; flex-direction:column; gap:6px;
}
.stat-label{ display:flex; align-items:center; gap:7px; font-size:.8125rem; color:var(--ink-3); font-weight:600; }
.stat-value{ font-size:1.25rem; font-weight:800; letter-spacing:-.03em; display:flex; align-items:baseline; gap:6px; }
.stat-value .unit{ font-size:.8125rem; font-weight:700; color:var(--ink-3); letter-spacing:0; }

/* ==========================================================================
   9. PLAN CARDS (the pricing row from the dashboard reference)
   ========================================================================== */
/* The plan row is a carousel: it scrolls and snaps rather than cramming five
   cards into a width that fits three. Arrows appear only when it can scroll. */
.plan-rail{ position:relative; }
.plans{
	display:flex; gap:12px;
	overflow-x:auto; overscroll-behavior-x:contain;
	scroll-snap-type:x mandatory;
	scroll-padding-inline:2px;
	padding:4px 2px 10px;
	scrollbar-width:thin; scrollbar-color:var(--line-strong) transparent;
	-webkit-overflow-scrolling:touch;
}
.plans::-webkit-scrollbar{ height:6px; }
.plans::-webkit-scrollbar-thumb{ background:var(--line-strong); border-radius:var(--r-pill); }
.plans::-webkit-scrollbar-track{ background:transparent; }
.plans > *{ scroll-snap-align:start; flex:0 0 clamp(178px, 52vw, 216px); }
@media (min-width:1024px){ .plans > *{ flex:0 0 216px; } }
/* with only a few plans the row should sit still and fill the width */
.plans.fits{ overflow-x:visible; display:grid; grid-template-columns:repeat(auto-fit,minmax(178px,1fr)); }
.plans.fits > *{ flex:initial; }

.plan-nav{
	position:absolute; z-index:3; inset-block-start:calc(50% - 20px);
	width:38px; height:38px; border-radius:50%;
	display:grid; place-items:center;
	background:var(--surface); color:var(--ink-2);
	border:1px solid var(--line-strong); box-shadow:var(--sh-2);
	opacity:0; pointer-events:none;
	transition:opacity var(--t) var(--ease), background var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.plan-nav:hover{ background:var(--surface-2); }
.plan-nav:active{ transform:scale(.92); }
.plan-nav.show{ opacity:1; pointer-events:auto; }
.plan-nav.prev{ inset-inline-start:-6px; }
.plan-nav.next{ inset-inline-end:-6px; }
@media (max-width:767px){ .plan-nav{ display:none; } }

/* the whole card is the submit control — one button, no nested interactives */
.plan{
	position:relative; text-align:start; width:100%;
	font:inherit; color:inherit; cursor:pointer;
	display:flex; flex-direction:column; gap:12px;
	background:var(--surface); border:1px solid var(--line);
	border-radius:var(--r-md); padding:16px 15px;
	touch-action:pan-x pan-y;
	transition:transform var(--t) var(--ease), box-shadow var(--t) var(--ease),
	           border-color var(--t) var(--ease), opacity var(--t-fast) var(--ease);
}
.plan-form{ display:flex; min-width:0; }
.plan-form > .plan{ flex:1; }

/* drag to reorder */
.plan.dragging{
	opacity:.9; cursor:grabbing;
	transform:scale(1.04) rotate(.6deg);
	box-shadow:var(--sh-4); border-color:var(--accent);
	z-index:5; position:relative;
}
.plans.reordering{ scroll-snap-type:none; cursor:grabbing; }
.plans.reordering .plan:not(.dragging){ transition:transform var(--t) var(--ease); }
.plan-hint{
	display:flex; align-items:center; gap:6px;
	font-size:var(--fs-xs); color:var(--ink-3); margin-top:2px;
}
.plan-reset{ color:var(--accent); font-weight:700; text-decoration:underline; }
.plan:hover{ transform:translateY(-3px); box-shadow:var(--sh-3); border-color:var(--line-strong); }

/* The blue frame marks "the plan you are looking at", so it follows the
   pointer and the keyboard rather than staying pinned to the best-value card.
   The "best value" badge stays put — that is a fact about the plan, not a
   pointer state. When nothing is hovered the frame returns to the default. */
.plan.is-featured,
.plan:hover,
.plan:focus-visible{
	border-color:var(--accent);
	box-shadow:0 0 0 3px var(--accent-ring), var(--sh-2);
}
.plan:hover,
.plan:focus-visible{ box-shadow:0 0 0 3px var(--accent-ring), var(--sh-3); }

.plan.is-featured .plan-cta,
.plan:hover .plan-cta,
.plan:focus-visible .plan-cta{
	background:var(--accent); color:var(--on-accent); box-shadow:var(--sh-accent);
}

@media (hover:hover){
	/* Hand the frame over only when another card actually has the pointer or
	   focus — keyed on :has(), not on :hover of the row, because the row also
	   covers the gaps between cards and the highlight used to vanish entirely
	   while the pointer sat in one of them. */
	.plans:has(.plan:hover) .plan.is-featured:not(:hover),
	.plans:has(.plan:hover) .plan.is-lit:not(:hover),
	.plans:has(.plan:focus-visible) .plan.is-featured:not(:focus-visible):not(:hover),
	.plans:has(.plan:focus-visible) .plan.is-lit:not(:focus-visible):not(:hover){
		border-color:var(--line);
		box-shadow:var(--sh-1);
	}
	.plans:has(.plan:hover) .plan.is-featured:not(:hover) .plan-cta,
	.plans:has(.plan:hover) .plan.is-lit:not(:hover) .plan-cta,
	.plans:has(.plan:focus-visible) .plan.is-featured:not(:focus-visible):not(:hover) .plan-cta,
	.plans:has(.plan:focus-visible) .plan.is-lit:not(:focus-visible):not(:hover) .plan-cta{
		background:var(--surface); color:var(--ink);
		box-shadow:inset 0 0 0 1px var(--line-strong);
	}
}
/* while a card is being dragged, nothing else should light up */
.plans.reordering .plan:not(.dragging){ box-shadow:var(--sh-1) !important; }
.plan-top{ display:flex; align-items:center; gap:6px 8px; justify-content:space-between; flex-wrap:wrap; min-height:24px; }
.plan-top .pill{ font-size:.8125rem; padding:2px 8px; }
.plan-name{ font-size:.9375rem; font-weight:700; color:var(--ink-2); }
.plan-price{
	display:flex; align-items:baseline; gap:5px; flex-wrap:wrap;
	font-size:clamp(1.35rem,3.4vw,1.65rem); font-weight:800; letter-spacing:-.035em; line-height:1.1;
}
.plan-price .cur{ font-size:.8125rem; font-weight:700; color:var(--ink-3); letter-spacing:0; }
.plan-price .per{ font-size:.8125rem; font-weight:600; color:var(--ink-3); letter-spacing:0; }
.plan-old{ font-size:.8125rem; color:var(--ink-3); text-decoration:line-through; }
.plan-feats{ display:flex; flex-direction:column; gap:7px; padding-top:12px; border-top:1px solid var(--line); }
.plan-feat{ display:flex; align-items:center; gap:8px; font-size:.875rem; color:var(--ink-2); }
.plan-feat .gl{ color:var(--ink-3); flex:none; }

/* --------------------------------------------------------------------------
   Switching between plans — the light cast
   (collectui: "casting icon shadows with progressive blur")

   The card you are pointing at is lit from its own tile: the tile turns on, a
   crisp bar of light appears at its lower lip, and the light spills down the
   body of the card — widening and going blurrier the further it falls. Only
   one card can be lit, so moving the pointer moves the light from card to
   card. That movement IS the switch; there is no separate indicator.

   True progressive blur is a stack: three ellipses, each bigger, blurrier and
   fainter than the one above it. A single blurred shape reads flat.
   -------------------------------------------------------------------------- */
.plan > *{ position:relative; z-index:1; }

.plan .plan-cast{
	position:absolute; z-index:0; inset:0;
	border-radius:calc(var(--r-md) - 1px);
	overflow:hidden; pointer-events:none;
}
.plan-cast > span{
	position:absolute;
	inset-block-start:var(--y);
	/* the light starts at the tile, so the stack is anchored to the tile's
	   centre (15px of padding + half of a 40px tile) rather than to the middle
	   of the card — logical, so it mirrors correctly in RTL */
	inset-inline-start:35px;
	width:var(--w); height:var(--h);
	margin-inline-start:calc(var(--w) / -2);
	border-radius:50%;
	background:var(--accent);
	filter:blur(var(--b));
	opacity:0;
	transform:translateY(-12px) scale(.84);
	transition:opacity var(--t-slow) var(--ease), transform var(--t-slow) var(--ease);
}
/* nearest the tile: tight, barely blurred, brightest */
.plan-cast > span:nth-child(1){ --y:44px;  --w:104px; --h:46px;  --b:12px; }
/* mid-fall */
.plan-cast > span:nth-child(2){ --y:58px;  --w:176px; --h:96px;  --b:28px; }
/* far: the wash across the lower half of the card */
.plan-cast > span:nth-child(3){ --y:88px;  --w:250px; --h:150px; --b:52px; }

/* the tile the light comes from */
.plan-tile{
	position:relative;
	width:40px; height:40px; border-radius:13px;
	display:grid; place-items:center; flex:none;
	background:var(--surface-2); color:var(--ink-3);
	box-shadow:inset 0 0 0 1px var(--line);
	transition:background var(--t) var(--ease), color var(--t) var(--ease),
	           box-shadow var(--t) var(--ease), transform var(--t) var(--ease);
}
/* the crisp lip of light under the tile — the one hard edge in the whole
   effect, which is what keeps the blurred part reading as spill and not fog */
.plan-tile::after{
	content:''; position:absolute;
	inset-inline:8px; inset-block-end:-1px; height:2px;
	border-radius:2px;
	background:var(--accent-800);
	box-shadow:0 0 9px 1px var(--accent-800);
	opacity:0; transform:scaleX(.55);
	transition:opacity var(--t) var(--ease), transform var(--t) var(--ease);
}

/* ---- lit state: the featured card by default, whatever is hovered/focused
        otherwise (the handoff below takes the light off the featured one) ---- */
/* `.is-lit` is set by the script on the card the carousel has scrolled to —
   that is how the light switches on a phone, where there is no pointer. While
   the script is driving (`.js-lit` on the row) the best-value card no longer
   claims the light on its own. */
.plan.is-featured .plan-cast > span:nth-child(1),
.plan.is-lit      .plan-cast > span:nth-child(1),
.plan:hover        .plan-cast > span:nth-child(1),
.plan:focus-visible .plan-cast > span:nth-child(1){ opacity:var(--cast-1); transform:none; }
.plan.is-featured .plan-cast > span:nth-child(2),
.plan.is-lit      .plan-cast > span:nth-child(2),
.plan:hover        .plan-cast > span:nth-child(2),
.plan:focus-visible .plan-cast > span:nth-child(2){ opacity:var(--cast-2); transform:none; }
.plan.is-featured .plan-cast > span:nth-child(3),
.plan.is-lit      .plan-cast > span:nth-child(3),
.plan:hover        .plan-cast > span:nth-child(3),
.plan:focus-visible .plan-cast > span:nth-child(3){ opacity:var(--cast-3); transform:none; }

.plan.is-featured .plan-tile,
.plan.is-lit .plan-tile,
.plan:hover .plan-tile,
.plan:focus-visible .plan-tile{
	background:var(--accent); color:var(--on-accent);
	box-shadow:inset 0 0 0 1px var(--accent), var(--sh-accent);
}
.plan.is-featured .plan-tile::after,
.plan.is-lit .plan-tile::after,
.plan:hover .plan-tile::after,
.plan:focus-visible .plan-tile::after{ opacity:1; transform:none; }

/* script driving: only the scrolled-to card is lit */
.plans.js-lit .plan.is-featured:not(.is-lit) .plan-cast > span{
	opacity:0; transform:translateY(-12px) scale(.84);
}
.plans.js-lit .plan.is-featured:not(.is-lit) .plan-tile{
	background:var(--surface-2); color:var(--ink-3);
	box-shadow:inset 0 0 0 1px var(--line);
}
.plans.js-lit .plan.is-featured:not(.is-lit) .plan-tile::after{ opacity:0; transform:scaleX(.55); }
/* the blue frame follows the light too, so the two never disagree */
.plan.is-lit{ border-color:var(--accent); box-shadow:0 0 0 3px var(--accent-ring), var(--sh-2); }
.plans.js-lit .plan.is-featured:not(.is-lit){ border-color:var(--line); box-shadow:var(--sh-1); }
.plan.is-lit .plan-cta{ background:var(--accent); color:var(--on-accent); box-shadow:var(--sh-accent); }
.plans.js-lit .plan.is-featured:not(.is-lit) .plan-cta{
	background:var(--surface); color:var(--ink);
	box-shadow:inset 0 0 0 1px var(--line-strong);
}

@media (hover:hover){
	/* pointer or keyboard on another card → the featured card goes dark, so
	   the light is only ever in one place */
	.plans:has(.plan:hover) .plan.is-featured:not(:hover) .plan-cast > span,
	.plans:has(.plan:hover) .plan.is-lit:not(:hover) .plan-cast > span,
	.plans:has(.plan:focus-visible) .plan.is-featured:not(:focus-visible):not(:hover) .plan-cast > span,
	.plans:has(.plan:focus-visible) .plan.is-lit:not(:focus-visible):not(:hover) .plan-cast > span{
		opacity:0; transform:translateY(-12px) scale(.84);
	}
	.plans:has(.plan:hover) .plan.is-featured:not(:hover) .plan-tile,
	.plans:has(.plan:hover) .plan.is-lit:not(:hover) .plan-tile,
	.plans:has(.plan:focus-visible) .plan.is-featured:not(:focus-visible):not(:hover) .plan-tile,
	.plans:has(.plan:focus-visible) .plan.is-lit:not(:focus-visible):not(:hover) .plan-tile{
		background:var(--surface-2); color:var(--ink-3);
		box-shadow:inset 0 0 0 1px var(--line);
	}
	.plans:has(.plan:hover) .plan.is-featured:not(:hover) .plan-tile::after,
	.plans:has(.plan:hover) .plan.is-lit:not(:hover) .plan-tile::after,
	.plans:has(.plan:focus-visible) .plan.is-featured:not(:focus-visible):not(:hover) .plan-tile::after,
	.plans:has(.plan:focus-visible) .plan.is-lit:not(:focus-visible):not(:hover) .plan-tile::after{
		opacity:0; transform:scaleX(.55);
	}
}
/* nothing lights up while a card is being dragged into a new position */
.plans.reordering .plan .plan-cast > span{ opacity:0 !important; }
.plans.reordering .plan:not(.dragging) .plan-tile::after{ opacity:0; }

/* the blur stack is decoration; with reduced motion it simply stops moving */
@media (prefers-reduced-motion:reduce){
	.plan-cast > span{ transform:none; }
}

.plan-cta{
	display:flex; align-items:center; justify-content:center; gap:7px;
	width:100%; min-height:38px; padding:9px 13px;
	border-radius:var(--r-xs); font-size:var(--fs-sm); font-weight:700;
	background:var(--surface); color:var(--ink);
	box-shadow:inset 0 0 0 1px var(--line-strong);
	transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.plan:hover .plan-cta,
.plan:focus-visible .plan-cta{ background:var(--accent-700); }

/* ==========================================================================
   10. OBJECT CARDS (the "knowledge bases" grid from the services reference)
   ========================================================================== */
.obj-grid{
	display:grid; gap:10px;
	grid-template-columns:repeat(auto-fill,minmax(268px,1fr));
}
@media (max-width:479px){ .obj-grid{ grid-template-columns:1fr; } }

.obj{
	position:relative;
	display:flex; align-items:center; gap:13px;
	padding:13px 15px; border-radius:var(--r-md);
	background:var(--surface); border:1px solid var(--line);
	transition:background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease),
	           transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease);
}
.obj:hover{ background:var(--surface-2); border-color:var(--line-strong); transform:translateY(-2px); box-shadow:var(--sh-2); }
.obj-glyph{
	flex:none; width:38px; height:38px; border-radius:11px;
	display:grid; place-items:center;
	background:var(--surface-3); color:var(--ink-3);
	transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.obj:hover .obj-glyph{ background:var(--surface-cream); color:var(--accent-800); }
.obj-glyph.tone-accent{ background:var(--accent-050); color:var(--accent); }
.obj-glyph.tone-cream{ background:var(--surface-cream); color:var(--accent-800); }
.obj-glyph.on-cream{ background:var(--onglass); color:var(--accent-800); }
.obj-body{ min-width:0; flex:1; }
.obj-name{
	display:block;
	font-size:.9375rem; font-weight:700; letter-spacing:-.01em;
	white-space:nowrap; overflow:hidden; text-overflow:ellipsis;
}
.obj-meta{
	display:flex; align-items:center; gap:12px; flex-wrap:wrap;
	margin-top:3px; font-size:.8125rem; color:var(--ink-3);
}
.obj-meta > span{ display:inline-flex; align-items:center; gap:4px; white-space:nowrap; }
.obj-meta .gl{ flex:none; opacity:.85; }
.obj-mark{ flex:none; color:var(--mark); }
.obj-go{ flex:none; color:var(--ink-3); transition:transform var(--t-fast) var(--ease), color var(--t-fast) var(--ease); }
.obj:hover .obj-go{ color:var(--accent); transform:translateX(3px); }
html[dir="rtl"] .obj:hover .obj-go{ transform:translateX(-3px); }

/* ==========================================================================
   11. PILLS, BADGES, TAGS
   ========================================================================== */
.pill{
	display:inline-flex; align-items:center; gap:6px;
	padding:3px 10px; border-radius:var(--r-pill);
	font-size:.8125rem; font-weight:700; line-height:1.7;
	background:var(--surface-3); color:var(--ink-2);
	white-space:nowrap;
}
.pill .dot{ width:6px; height:6px; border-radius:50%; background:currentColor; flex:none; }
.pill-ok{ background:var(--ok-bg); color:var(--ok); }
.pill-warn{ background:var(--warn-bg); color:var(--warn); }
.pill-danger{ background:var(--danger-bg); color:var(--danger); }
.pill-accent{ background:var(--accent); color:var(--on-accent); }
.pill-cream{ background:var(--surface-cream); color:var(--accent-800); }
.pill-outline{ background:transparent; box-shadow:inset 0 0 0 1px var(--line-strong); }

.badge{
	display:inline-grid; place-items:center; min-width:20px; height:20px;
	padding-inline:6px; border-radius:var(--r-pill);
	background:var(--accent); color:#fff; font-size:.8125rem; font-weight:800;
}

/* live status dot with a soft pulse */
.live{ position:relative; display:inline-flex; width:8px; height:8px; flex:none; }
.live::before,.live::after{ content:''; position:absolute; inset:0; border-radius:50%; background:var(--ok); }
.live::before{ animation:ping 2s var(--ease-io) infinite; opacity:.55; }
@keyframes ping{ 70%,100%{ transform:scale(2.6); opacity:0; } }

/* ==========================================================================
   12. FORMS
   ========================================================================== */
.field{ display:flex; flex-direction:column; gap:6px; }
.label{ font-size:.875rem; font-weight:700; color:var(--ink-2); }
.hint{ font-size:.8125rem; color:var(--ink-3); display:flex; align-items:center; gap:5px; }

.input,.textarea,.select{
	width:100%; padding:12px 14px;
	background:var(--surface); color:var(--ink);
	border:1px solid var(--line-strong); border-radius:var(--r-sm);
	font-size:1rem; line-height:1.5;
	transition:border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease),
	           background var(--t-fast) var(--ease);
}
.input::placeholder,.textarea::placeholder{ color:var(--ink-3); opacity:.75; }
.input:focus,.textarea:focus,.select:focus{
	outline:none; border-color:var(--accent);
	box-shadow:0 0 0 3.5px var(--accent-ring);
}
.textarea{ min-height:88px; resize:vertical; font-family:inherit; }
.input-lg{ padding:15px 16px; font-size:1rem; border-radius:var(--r-md); }
/* The field holds 16px at every width: below that iOS zooms the whole page
   when the input takes focus, which is a worse trade than a shorter hint.
   When the 24-character mask will not fit, ui.js measures it and swaps in a
   shortened placeholder — a measurement, not a breakpoint guess. */
.input-code{
	text-align:center; font-weight:700;
	font-family:ui-monospace,'SF Mono',Menlo,Consolas,monospace;
	direction:ltr;
	font-size:1rem; letter-spacing:.08em;
}
/* the placeholder is a sentence, not a mask, so it uses the UI face and sits
   in the reading direction of the page */
.input-code::placeholder{
	font-family:inherit; font-weight:600; letter-spacing:normal;
	font-size:.9375rem; opacity:.7;
}
html[dir="rtl"] .input-code::placeholder{ direction:rtl; }
@media (max-width:479px){ .input-lg.input-code{ padding-inline:10px; } }

/* leading adornment, like the "$" field in the reference */
.input-wrap{ position:relative; display:flex; align-items:center; }
.input-wrap .adorn{
	position:absolute; inset-inline-start:14px;
	color:var(--ink-3); font-weight:700; font-size:.9375rem; pointer-events:none;
	display:inline-flex; align-items:center;
}
.input-wrap .adorn-end{ inset-inline-start:auto; inset-inline-end:14px; }
.input-wrap.has-adorn .input{ padding-inline-start:38px; }
.input-wrap.has-adorn-end .input{ padding-inline-end:74px; }

.select{
	appearance:none; -webkit-appearance:none;
	padding-inline-end:38px; cursor:pointer;
	background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%235C6875' stroke-width='2.2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
	background-repeat:no-repeat; background-size:16px;
	background-position:right 13px center;
}
html[dir="rtl"] .select{ background-position:left 13px center; }

/* file dropzone */
.dropzone{
	display:flex; flex-direction:column; align-items:center; justify-content:center;
	gap:8px; padding:26px 18px; text-align:center;
	border:1.5px dashed var(--line-strong); border-radius:var(--r-md);
	background:var(--surface-2); color:var(--ink-2);
	font-size:.9375rem; cursor:pointer;
	transition:border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.dropzone:hover,.dropzone.is-over{ border-color:var(--accent); background:var(--accent-050); color:var(--accent-800); }
.dropzone.has-file{ border-style:solid; border-color:var(--ok); background:var(--ok-bg); color:var(--ok); }
.dropzone .gl{ opacity:.8; }

/* choice tiles — used for amounts and payment methods */
.choices{ display:grid; gap:10px; grid-template-columns:repeat(auto-fill,minmax(160px,1fr)); }
/* a 4-item action set stays a balanced 2x2 instead of collapsing to 3 + 1 */
.choices.cols-2{ grid-template-columns:1fr; }
@media (min-width:420px){ .choices.cols-2{ grid-template-columns:repeat(2,1fr); } }
.choice{
	display:flex; align-items:center; gap:11px; width:100%; text-align:start;
	padding:13px 14px; border-radius:var(--r-md);
	background:var(--surface); border:1px solid var(--line);
	transition:transform var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease),
	           border-color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.choice:hover{ border-color:var(--accent); background:var(--accent-050); transform:translateY(-2px); box-shadow:var(--sh-2); }
.choice-ic{
	flex:none; width:36px; height:36px; border-radius:11px; display:grid; place-items:center;
	background:var(--surface-3); color:var(--ink-2);
	transition:background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.choice:hover .choice-ic{ background:var(--surface-cream); color:var(--accent-800); }
.choice-body{ min-width:0; flex:1; }
.choice-title{ display:block; font-size:.9375rem; font-weight:700; line-height:1.4; }
.choice-sub{ display:block; font-size:.8125rem; color:var(--ink-3); margin-top:1px; line-height:1.5; }
.choice-go{ flex:none; color:var(--ink-3); }

/* real switch */
.switch{ display:inline-flex; align-items:center; gap:10px; cursor:pointer; user-select:none; }
.switch input{ position:absolute; opacity:0; width:0; height:0; }
.switch .track{
	width:40px; height:23px; border-radius:var(--r-pill); flex:none;
	background:var(--line-strong); position:relative;
	transition:background var(--t) var(--ease);
}
.switch .track::after{
	content:''; position:absolute; inset-block-start:2.5px; inset-inline-start:2.5px;
	width:18px; height:18px; border-radius:50%; background:#fff;
	box-shadow:var(--sh-1);
	transition:transform var(--t) var(--ease-spring);
}
.switch input:checked + .track{ background:var(--accent); }
.switch input:checked + .track::after{ transform:translateX(17px); }
html[dir="rtl"] .switch input:checked + .track::after{ transform:translateX(-17px); }
.switch input:focus-visible + .track{ box-shadow:0 0 0 3.5px var(--accent-ring); }

/* checkbox */
.check{ display:inline-flex; align-items:flex-start; gap:9px; cursor:pointer; font-size:.875rem; color:var(--ink-2); line-height:1.6; }
.check input{ position:absolute; opacity:0; width:0; height:0; }
.check .box{
	width:18px; height:18px; border-radius:5px; flex:none; margin-top:2px;
	border:1.5px solid var(--line-strong); background:var(--surface);
	display:grid; place-items:center;
	transition:background var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease);
}
.check .box svg{ opacity:0; transform:scale(.6); transition:opacity var(--t-fast) var(--ease), transform var(--t-fast) var(--ease-spring); color:#fff; }
.check input:checked + .box{ background:var(--accent); border-color:var(--accent); }
.check input:checked + .box svg{ opacity:1; transform:scale(1); }
.check input:focus-visible + .box{ box-shadow:0 0 0 3.5px var(--accent-ring); }

/* ==========================================================================
   13. LISTS / ROWS
   ========================================================================== */
.rows{ display:flex; flex-direction:column; }
.row{
	display:flex; align-items:center; gap:12px;
	padding:12px 2px; border-bottom:1px solid var(--line);
}
.row:last-child{ border-bottom:none; }
.row-k{ color:var(--ink-3); font-size:.9375rem; display:flex; align-items:center; gap:7px; }
.row-v{ margin-inline-start:auto; font-weight:700; font-size:.9375rem; text-align:end; }

.ledger-row{
	display:flex; align-items:center; gap:12px;
	padding:12px 2px; border-bottom:1px solid var(--line);
}
.ledger-row:last-child{ border-bottom:none; }
.ledger-ic{
	flex:none; width:36px; height:36px; border-radius:11px; display:grid; place-items:center;
	background:var(--surface-3); color:var(--ink-2);
}
.ledger-ic.in{ background:var(--ok-bg); color:var(--ok); }
.ledger-body{ min-width:0; flex:1; }
.ledger-title{ display:block; font-size:.9375rem; font-weight:700; }
.ledger-date{ display:block; font-size:.8125rem; color:var(--ink-3); }
.ledger-amt{ font-weight:800; font-size:.9375rem; white-space:nowrap; }
.ledger-amt.in{ color:var(--ok); }
.ledger-amt .unit{ font-size:.8125rem; font-weight:600; color:var(--ink-3); }

/* ==========================================================================
   14. NOTICES & EMPTY STATES
   ========================================================================== */
.notice{
	display:flex; align-items:flex-start; gap:11px;
	padding:13px 15px; border-radius:var(--r-md);
	background:var(--accent-050); border:1px solid var(--line-slate);
	font-size:.9375rem; line-height:1.75; color:var(--ink-2);
}
.notice .gl{ flex:none; margin-top:2px; color:var(--accent); }
.notice-ok{ background:var(--ok-bg); border-color:rgba(47,111,85,.22); color:#28513F; }
.notice-ok .gl{ color:var(--ok); }
.notice-warn{ background:var(--warn-bg); border-color:rgba(138,93,30,.22); color:#6D4A18; }
.notice-warn .gl{ color:var(--warn); }
.notice-danger{ background:var(--danger-bg); border-color:rgba(163,59,51,.22); color:#7E2E28; }
.notice-danger .gl{ color:var(--danger); }
.notice-body{ min-width:0; flex:1; }
.notice-title{ font-weight:700; color:inherit; margin-bottom:2px; }

.empty{
	display:flex; flex-direction:column; align-items:center; gap:10px;
	padding:38px 20px; text-align:center; color:var(--ink-3);
}
.empty-glyph{
	width:54px; height:54px; border-radius:17px; display:grid; place-items:center;
	background:var(--surface-3); color:var(--ink-3);
}
.empty-title{ display:block; font-size:1rem; font-weight:700; color:var(--ink-2); }
.empty-text{ display:block; font-size:.875rem; max-width:32ch; }

/* code / link box */
.codebox{
	background:var(--surface-2); border:1px dashed var(--line-strong);
	border-radius:var(--r-sm); padding:12px 14px;
	font-family:ui-monospace,'SF Mono',Menlo,Consolas,monospace;
	font-size:.875rem; line-height:1.75; word-break:break-all;
	direction:ltr; text-align:start; color:var(--ink-2);
	max-height:150px; overflow:auto; overscroll-behavior:contain;
}

/* ==========================================================================
   15. MOBILE TAB BAR + EXPANDING MENU
   (rebuilt from the menu-animation reference)
   ========================================================================== */
.tabbar{
	position:fixed; z-index:70;
	inset-inline:0; inset-block-end:calc(10px + var(--safe-b));
	display:flex; justify-content:center; pointer-events:none;
	padding-inline:12px;
}
@media (min-width:1024px){ .tabbar{ display:none; } }

.tabbar-inner{
	pointer-events:auto; position:relative;
	display:flex; align-items:center; gap:2px;
	padding:6px; border-radius:var(--r-pill);
	background:var(--glass);
	-webkit-backdrop-filter:saturate(180%) blur(18px);
	backdrop-filter:saturate(180%) blur(18px);
	border:1px solid var(--line);
	box-shadow:var(--sh-3);
	max-width:100%;
}
.tab-ind{
	position:absolute; inset-block:6px;
	/* physical `left` on purpose — ui.js drives this with translateX(offsetLeft),
	   which is physical; a logical inset put it outside the bar in RTL. */
	left:0;
	border-radius:var(--r-pill); background:var(--accent);
	box-shadow:var(--sh-accent);
	opacity:0; z-index:0;
	transition:transform var(--t-slow) var(--ease-spring),
	           width var(--t-slow) var(--ease-spring),
	           opacity var(--t) var(--ease);
}
.tab{
	position:relative; z-index:1;
	display:flex; align-items:center; gap:7px;
	padding:9px 13px; border-radius:var(--r-pill);
	color:var(--ink-2); font-size:.875rem; font-weight:700;
	white-space:nowrap; min-height:42px;
	transition:color var(--t) var(--ease);
	-webkit-tap-highlight-color:transparent;
}
.tab .gl{ flex:none; }
.tab-label{
	max-width:0; overflow:hidden; opacity:0;
	transition:max-width var(--t-slow) var(--ease), opacity var(--t) var(--ease);
}
.tab.active{ color:#fff; }
.tab.active .tab-label{ max-width:96px; opacity:1; }
html:not(.js) .tab.active{ background:var(--accent); border-radius:var(--r-pill); }
html:not(.js) .tab.active .tab-label{ max-width:96px; opacity:1; }

/* the panel that grows out of the bar */
.menu-sheet{
	position:fixed; z-index:69;
	inset-inline:12px; inset-block-end:calc(var(--tabbar-h) + var(--safe-b) + 14px);
	margin-inline:auto; max-width:340px;
	background:var(--glass-strong);
	-webkit-backdrop-filter:saturate(180%) blur(22px);
	backdrop-filter:saturate(180%) blur(22px);
	border:1px solid var(--line);
	border-radius:var(--r-2xl);
	box-shadow:var(--sh-4);
	padding:10px;
	transform-origin:bottom center;
	opacity:0; transform:translateY(14px) scale(.9);
	pointer-events:none; visibility:hidden;
	transition:opacity var(--t) var(--ease),
	           transform var(--t-slow) var(--ease-spring),
	           visibility 0s linear var(--t-slow);
}
.menu-sheet.open{
	opacity:1; transform:translateY(0) scale(1);
	pointer-events:auto; visibility:visible;
	transition:opacity var(--t) var(--ease),
	           transform var(--t-slow) var(--ease-spring),
	           visibility 0s;
}
@media (min-width:1024px){ .menu-sheet{ display:none; } }

.menu-sheet-pill{
	position:absolute; inset-inline:10px; height:0; top:0;
	border-radius:var(--r-md); background:var(--accent-050);
	border:1px solid var(--line-slate);
	opacity:0; z-index:0; pointer-events:none;
	transition:transform var(--t) var(--ease-spring), height var(--t) var(--ease-spring), opacity var(--t-fast) var(--ease);
}
.menu-item{
	position:relative; z-index:1;
	display:flex; align-items:center; gap:12px;
	padding:12px 13px; border-radius:var(--r-md);
	font-size:.9375rem; font-weight:600; color:var(--ink-2);
	opacity:0; transform:translateY(9px);
	transition:color var(--t-fast) var(--ease);
}
.menu-sheet.open .menu-item{
	animation:menuIn .42s var(--ease-spring) forwards;
	animation-delay:calc(var(--i,0) * 34ms + 40ms);
}
@keyframes menuIn{ to{ opacity:1; transform:translateY(0); } }
.menu-item .gl{ flex:none; color:var(--ink-3); }
.menu-item.active{ color:var(--accent-800); font-weight:700; }
.menu-item.active .gl{ color:var(--accent); }
.menu-item.is-danger{ color:var(--danger); }
.menu-item.is-danger .gl{ color:var(--danger); }
.menu-sep{ height:1px; background:var(--line); margin:7px 12px; }

.scrim{
	position:fixed; inset:0; z-index:68;
	background:var(--veil);
	-webkit-backdrop-filter:blur(2px); backdrop-filter:blur(2px);
	opacity:0; pointer-events:none; visibility:hidden;
	transition:opacity var(--t) var(--ease), visibility 0s linear var(--t);
}
.scrim.open{ opacity:1; pointer-events:auto; visibility:visible; transition:opacity var(--t) var(--ease), visibility 0s; }

/* ==========================================================================
   16. MODAL
   ========================================================================== */
.modal{
	position:fixed; inset:0; z-index:100;
	display:grid; place-items:center; padding:20px;
	background:var(--veil-strong);
	-webkit-backdrop-filter:blur(5px); backdrop-filter:blur(5px);
	opacity:0; pointer-events:none; visibility:hidden;
	transition:opacity var(--t) var(--ease), visibility 0s linear var(--t);
}
.modal.open{ opacity:1; pointer-events:auto; visibility:visible; transition:opacity var(--t) var(--ease), visibility 0s; }
.modal-card{
	width:100%; max-width:340px;
	background:var(--surface); border:1px solid var(--line);
	border-radius:var(--r-xl); padding:20px;
	box-shadow:var(--sh-4);
	transform:scale(.93) translateY(10px);
	transition:transform var(--t-slow) var(--ease-spring);
	max-height:88dvh; overflow:auto;
}
.modal.open .modal-card{ transform:none; }
.modal-head{ display:flex; align-items:center; justify-content:space-between; gap:12px; margin-bottom:14px; }
.modal-title{ font-size:1rem; font-weight:800; }

/* ==========================================================================
   17. TOAST
   ========================================================================== */
.toast-wrap{
	position:fixed; z-index:120; inset-inline:0;
	inset-block-end:calc(var(--tabbar-h) + var(--safe-b) + 20px);
	display:flex; flex-direction:column; align-items:center; gap:8px;
	pointer-events:none; padding-inline:16px;
}
@media (min-width:1024px){ .toast-wrap{ inset-block-end:24px; } }
.toast{
	display:flex; align-items:center; gap:9px;
	padding:11px 16px; border-radius:var(--r-pill);
	background:var(--surface-ink); color:var(--ink-on-dark);
	font-size:.9375rem; font-weight:600;
	box-shadow:var(--sh-4);
	animation:toastIn .38s var(--ease-spring);
	max-width:min(92vw,420px);
}
.toast.out{ animation:toastOut .28s var(--ease) forwards; }
.toast .gl{ flex:none; color:#9FE3C2; }
@keyframes toastIn{ from{ opacity:0; transform:translateY(14px) scale(.94); } }
@keyframes toastOut{ to{ opacity:0; transform:translateY(8px) scale(.96); } }

/* ==========================================================================
   18. LANGUAGE SWITCH
   ========================================================================== */
.lang{
	display:inline-flex; padding:3px; border-radius:var(--r-pill);
	background:var(--surface-3); border:1px solid var(--line);
	position:relative;
}
.lang a{
	display:inline-flex; align-items:center; justify-content:center;
	min-height:32px; min-width:40px;
	padding:5px 12px; border-radius:var(--r-pill);
	font-size:.8125rem; font-weight:700; color:var(--ink-3);
	transition:color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
	line-height:1.2;
}
.lang a.on{ background:var(--surface); color:var(--ink); box-shadow:var(--sh-1); }
.lang a:not(.on):hover{ color:var(--ink-2); }

/* theme switch — same shape as the language switch so the two read as a pair */
.seg{
	display:inline-flex; padding:3px; border-radius:var(--r-pill);
	background:var(--surface-3); border:1px solid var(--line);
}
.seg button{
	display:inline-flex; align-items:center; justify-content:center;
	min-height:32px; min-width:38px; padding:5px 10px;
	border-radius:var(--r-pill); color:var(--ink-3);
	transition:color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.seg button.on{ background:var(--surface); color:var(--ink); box-shadow:var(--sh-1); }
.seg button:not(.on):hover{ color:var(--ink-2); }

/* Two switches plus the brand do not fit a 320px bar at full size, so the
   controls tighten rather than one of them disappearing. */
@media (max-width:399px){
	.topbar .brand span{ display:none; }
	.seg button{ min-width:32px; padding:5px 7px; }
	.lang a{ min-width:34px; padding:5px 8px; }
	.topbar{ gap:6px; }
}

/* ==========================================================================
   19. REVEAL ANIMATIONS
   ========================================================================== */
/* Content is visible by default; the .js flag (set inline, before paint) opts
   into the animation, so a failed script can never leave the page blank. */
.rv{ opacity:1; transform:none; }
html.js .rv{ opacity:0; transform:translateY(12px); }
html.js .rv.in{ animation:rvIn .62s var(--ease) forwards; animation-delay:calc(var(--d,0) * 55ms); }
/* `shown` means "be visible now, do not perform" — used on a back/forward
   restore, under reduced motion, and by the safety sweep. Without it even an
   instantly-revealed element still faded up from zero for half a second. */
html.js .rv.shown{ opacity:1 !important; transform:none !important; animation:none !important; }
@keyframes rvIn{ to{ opacity:1; transform:none; } }

/* ==========================================================================
   20. LOGIN PAGE
   (rebuilt from the sign-up reference: cinematic ground + floating split panel)
   ========================================================================== */
.auth{
	min-height:100dvh; position:relative; overflow:hidden;
	display:grid; place-items:center;
	padding:clamp(14px,3vw,32px);
	background:var(--bg-deep);
}
/* the "landscape": layered warm gradients, no image files */
.auth-bg{ position:absolute; inset:0; z-index:0; pointer-events:none; overflow:hidden; }
.auth-bg::before{
	content:''; position:absolute; inset:0;
	background:
		radial-gradient(90% 70% at 78% 8%,  rgba(240,229,207,.95) 0%, rgba(240,229,207,0) 62%),
		radial-gradient(75% 60% at 12% 92%, rgba(75,101,135,.28) 0%, rgba(75,101,135,0) 60%),
		radial-gradient(60% 50% at 96% 88%, rgba(222,187,132,.42) 0%, rgba(222,187,132,0) 66%),
		linear-gradient(168deg,#FCFBF8 0%,#F4F1E9 46%,#E8E4DA 100%);
}
/* rolling hill silhouettes, echoing the reference photograph */
.auth-hills{ position:absolute; inset-inline:0; inset-block-end:0; height:52%; }
.auth-hills svg{ width:100%; height:100%; }
/* soft floating orbs */
.auth-orb{
	position:absolute; border-radius:50%; filter:blur(46px); opacity:.55;
	animation:float 16s var(--ease-io) infinite alternate;
}
.auth-orb.a{ width:min(46vw,380px); aspect-ratio:1; inset-block-start:-8%; inset-inline-end:-6%; background:rgba(226,190,134,.7); }
.auth-orb.b{ width:min(38vw,300px); aspect-ratio:1; inset-block-end:2%; inset-inline-start:-8%; background:rgba(75,101,135,.42); animation-duration:21s; animation-delay:-6s; }
.auth-orb.c{ width:min(30vw,240px); aspect-ratio:1; inset-block-start:38%; inset-inline-start:42%; background:rgba(240,229,207,.9); animation-duration:26s; animation-delay:-11s; }
@keyframes float{ to{ transform:translate3d(3%,-5%,0) scale(1.12); } }
/* film grain, inline SVG so nothing is fetched */
.auth-grain{
	position:absolute; inset:0; opacity:.32; mix-blend-mode:multiply;
	background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3' stitchTiles='stitch'/%3E%3CfeColorMatrix type='saturate' values='0'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='.5'/%3E%3C/svg%3E");
}

.auth-panel{
	position:relative; z-index:2;
	width:100%; max-width:940px;
	display:grid; grid-template-columns:1fr;
	border-radius:var(--r-2xl); overflow:hidden;
	border:1px solid rgba(255,255,255,.7);
	box-shadow:0 40px 90px -30px rgba(30,38,50,.34), 0 2px 10px rgba(30,38,50,.06);
	background:rgba(255,255,255,.42);
	-webkit-backdrop-filter:saturate(150%) blur(22px);
	backdrop-filter:saturate(150%) blur(22px);
}
@media (min-width:900px){ .auth-panel{ grid-template-columns:1fr 1fr; min-height:590px; } }

/* form half */
.auth-form{
	position:relative;
	background:rgba(255,255,255,.78);
	padding:clamp(24px,4.4vw,42px);
	display:flex; flex-direction:column;
	gap:0;
}
@media (min-width:900px){ .auth-form{ justify-content:space-between; } }
.auth-brand{ display:flex; align-items:center; gap:10px; font-weight:800; letter-spacing:-.02em; }
.auth-brand .brand-mark{ width:32px; height:32px; border-radius:10px; }
.auth-lede{ margin-block:clamp(26px,6vw,58px) 22px; }
.auth-title{ font-size:clamp(1.5rem,4.6vw,1.95rem); font-weight:800; letter-spacing:-.03em; line-height:1.2; }
.auth-desc{ margin-top:7px; font-size:.9375rem; color:var(--ink-3); line-height:1.8; max-width:34ch; }
.auth-body{ display:flex; flex-direction:column; gap:13px; }
.auth-sep{
	display:flex; align-items:center; gap:12px;
	font-size:.8125rem; color:var(--ink-3); margin-block:4px;
}
.auth-sep::before,.auth-sep::after{ content:''; flex:1; height:1px; background:var(--line); }
.auth-alt{ display:grid; gap:8px; grid-template-columns:1fr; }
@media (min-width:420px){ .auth-alt{ grid-template-columns:1fr 1fr; } }
.auth-alt .btn{ font-size:.875rem; padding:11px 12px; }
.auth-foot{ margin-top:20px; font-size:.875rem; color:var(--ink-3); text-align:center; }
.auth-foot a{ display:inline-block; padding:6px 2px; color:var(--accent); font-weight:700; }

/* The corner controls float over a photographic-looking ground, so they carry
   their own solid surface — a bare ghost button was nearly invisible there,
   and icon-only gave no clue what it did. */
.auth-top{
	position:absolute; inset-block-start:14px; inset-inline:14px; z-index:3;
	display:flex; align-items:center; justify-content:space-between; gap:10px;
}
.auth-top .lang,
.auth-top .seg{ background:var(--surface); border-color:var(--line-strong); box-shadow:var(--sh-2); }
.btn-back{
	--btn-bg:var(--surface); --btn-fg:var(--ink); --btn-bd:var(--line-strong);
	box-shadow:var(--sh-2); font-weight:700;
}
.btn-back:hover{ background:var(--surface-2); }
.btn-back .gl{ color:var(--accent); }
.auth-foot a:hover{ text-decoration:underline; }

/* art half */
.auth-art{
	position:relative; display:none; overflow:hidden;
	background:linear-gradient(150deg, rgba(240,229,207,.5), rgba(226,190,134,.28));
	border-inline-start:1px solid rgba(255,255,255,.6);
	padding:clamp(24px,4vw,40px);
}
@media (min-width:900px){ .auth-art{ display:flex; flex-direction:column; justify-content:flex-end; gap:18px; } }
.auth-art-copy{ position:relative; z-index:2; }
.auth-art-eyebrow{
	font-size:.8125rem; font-weight:700; letter-spacing:.14em; text-transform:uppercase;
	color:var(--accent-800); opacity:.75;
}
.auth-art-title{ margin-top:8px; font-size:1.25rem; font-weight:800; letter-spacing:-.02em; line-height:1.4; max-width:22ch; color:var(--ink); }
.auth-art-list{ margin-top:14px; display:flex; flex-direction:column; gap:9px; }
.auth-art-list li{ display:flex; align-items:center; gap:9px; font-size:.9375rem; color:var(--ink-2); }
.auth-art-list .gl{ color:var(--accent); flex:none; }

/* the floating "device" that the reference centres in its art half */
.auth-device{
	position:absolute; z-index:1;
	inset-block-start:14%;
	/* physical `left` on purpose: the centring transform below is physical, so a
	   logical inset would push this off-centre in RTL. */
	left:50%;
	transform:translateX(-50%) rotate(-6deg);
	width:min(74%,272px);
	border-radius:22px; padding:14px;
	background:linear-gradient(160deg,#FFFFFF,#F3EFE5);
	border:1px solid rgba(255,255,255,.9);
	box-shadow:0 30px 60px -22px rgba(30,38,50,.4);
	animation:hover 7s var(--ease-io) infinite alternate;
}
.auth-device-screen{
	aspect-ratio:4/3; border-radius:14px;
	background:radial-gradient(110% 90% at 30% 12%, #F0E5CF, #DCC79B);
	display:grid; place-items:center;
	box-shadow:inset 0 0 0 1px rgba(75,101,135,.14);
}
.auth-device-screen .brand-mark{ width:46px; height:46px; border-radius:14px; }
.auth-device-screen .brand-mark svg{ width:26px; height:26px; }
.auth-device-foot{ display:flex; align-items:center; justify-content:center; gap:5px; margin-top:11px; }
.auth-device-foot i{ width:5px; height:5px; border-radius:50%; background:var(--line-strong); display:block; }
.auth-device-foot i:first-child{ width:22px; border-radius:var(--r-pill); background:var(--accent); }
@keyframes hover{ to{ transform:translateX(-50%) rotate(-3.5deg) translateY(-14px); } }
/* same reason: keep the orb offsets physical so they sit identically in both directions */
.auth-orb.a{ inset-inline-end:auto; right:-6%; }
.auth-orb.b{ inset-inline-start:auto; left:-8%; }
.auth-orb.c{ inset-inline-start:auto; left:42%; }

/* step overlays */
.step-overlay{
	position:fixed; inset:0; z-index:200;
	display:grid; place-items:center; padding:20px;
	background:var(--veil-soft);
	-webkit-backdrop-filter:blur(8px); backdrop-filter:blur(8px);
	opacity:0; pointer-events:none; visibility:hidden;
	transition:opacity var(--t) var(--ease), visibility 0s linear var(--t);
}
.step-overlay.on{ opacity:1; pointer-events:auto; visibility:visible; transition:opacity var(--t) var(--ease), visibility 0s; }
.step-card{
	width:100%; max-width:290px; text-align:center;
	background:var(--surface); border:1px solid var(--line);
	border-radius:var(--r-xl); padding:30px 24px;
	box-shadow:var(--sh-4);
	transform:scale(.92); transition:transform var(--t-slow) var(--ease-spring);
}
.step-overlay.on .step-card{ transform:none; }
.step-ic{
	width:60px; height:60px; margin:0 auto 16px; border-radius:19px;
	display:grid; place-items:center;
	background:var(--accent-050); color:var(--accent);
	border:1px solid var(--line-slate);
}
.step-ic.ok{ background:var(--ok-bg); color:var(--ok); border-color:rgba(47,111,85,.24); animation:pop .5s var(--ease-spring); }
@keyframes pop{ from{ transform:scale(.5); opacity:0; } }
.step-title{ font-size:1.125rem; font-weight:800; }
.step-sub{ font-size:.875rem; color:var(--ink-3); margin-top:5px; }
.step-dots{ display:flex; justify-content:center; gap:5px; margin-top:14px; }
.step-dots i{ width:6px; height:6px; border-radius:50%; background:var(--accent); display:block; animation:bounce 1.1s var(--ease-io) infinite; }
.step-dots i:nth-child(2){ animation-delay:.14s; }
.step-dots i:nth-child(3){ animation-delay:.28s; }
@keyframes bounce{ 0%,60%,100%{ transform:translateY(0); opacity:.4; } 30%{ transform:translateY(-6px); opacity:1; } }

/* ==========================================================================
   21. QR
   ========================================================================== */
/* A QR has to stay square and stay scannable: it scales with the viewport but
   never below the size a phone camera can resolve, and keeps a white quiet
   zone in both themes. */
.qr{
	background:#fff; border-radius:var(--r-md); padding:10px;
	border:1px solid var(--line); box-shadow:var(--sh-1);
	width:clamp(124px, 34vw, 168px);
	aspect-ratio:1; height:auto; flex:none;
}
.qr img{ width:100%; height:100%; display:block; }
@media (max-width:479px){
	/* on a phone the code goes full width above the link rather than beside it */
	.qr{ width:min(220px, 62vw); margin-inline:auto; }
}
.qr-modal-img{
	width:100%; max-width:280px; margin-inline:auto;
	aspect-ratio:1; height:auto; display:block;
}

/* ==========================================================================
   22. UTILITIES
   ========================================================================== */
.stack{ display:flex; flex-direction:column; gap:14px; }
.stack-sm{ display:flex; flex-direction:column; gap:8px; }
.cluster{ display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.between{ display:flex; align-items:center; justify-content:space-between; gap:12px; flex-wrap:wrap; }
.grow{ flex:1; min-width:0; }
.two-col{ display:grid; gap:14px; grid-template-columns:1fr; }
@media (min-width:860px){ .two-col{ grid-template-columns:1fr 1fr; align-items:start; } }
.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;
}
.hide-sm{ display:none; }
@media (min-width:600px){ .hide-sm{ display:initial; } }
.truncate{ white-space:nowrap; overflow:hidden; text-overflow:ellipsis; min-width:0; }
.gl{ display:inline-flex; align-items:center; justify-content:center; }

/* ==========================================================================
   23. PWA / PUSH BANNERS
   ========================================================================== */
/* One fixed stack, so a second banner never lands on top of the first. */
.sysbanner-stack{
	position:fixed; z-index:90;
	inset-inline:12px; inset-block-end:calc(var(--tabbar-h) + var(--safe-b) + 16px);
	margin-inline:auto; max-width:420px;
	display:flex; flex-direction:column-reverse; gap:8px;
	pointer-events:none;
	transition:opacity var(--t) var(--ease), transform var(--t) var(--ease);
}
@media (min-width:1024px){
	.sysbanner-stack{ inset-block-end:20px; inset-inline-end:20px; inset-inline-start:auto; margin-inline:0; }
}
/* while the mobile menu is open the banners step aside rather than cover it */
body.menu-open .sysbanner-stack{ opacity:0; transform:translateY(10px); pointer-events:none; }

.sysbanner{
	pointer-events:auto;
	display:flex; align-items:center; gap:11px;
	padding:13px 14px; border-radius:var(--r-lg);
	background:var(--surface); border:1px solid var(--line);
	box-shadow:var(--sh-4);
	animation:rvIn .5s var(--ease) both;
}
.sysbanner-ic{ width:42px; height:42px; border-radius:13px; flex:none; }
.sysbanner-body{ min-width:0; flex:1; }
.sysbanner-title{ display:block; font-size:.9375rem; font-weight:700; }
.sysbanner-text{ display:block; font-size:.8125rem; color:var(--ink-3); line-height:1.65; }
.sysbanner-steps{ margin:9px 0 0; padding-inline-start:18px; font-size:.8125rem; color:var(--ink-2); line-height:1.9; list-style:decimal; }

/* ==========================================================================
   24. PRINT & REDUCED MOTION
   ========================================================================== */
@media (prefers-reduced-motion:reduce){
	*,*::before,*::after{
		animation-duration:.001ms !important;
		animation-iteration-count:1 !important;
		transition-duration:.001ms !important;
		scroll-behavior:auto !important;
	}
	.rv{ opacity:1; transform:none; }
	.menu-sheet.open .menu-item{ opacity:1; transform:none; }
}
@media print{
	.rail,.topbar,.tabbar,.menu-sheet,.scrim,.sysbanner{ display:none !important; }
	.main{ margin:0; padding:0; }
	.card{ break-inside:avoid; box-shadow:none; }
}
