/* R-02: Montserrat, self-hosted (docs/vidya-b/09-architecture.md §5.2), in place of the Google Fonts stylesheet vidya-web
   linked (src/head.html:11-12; src/onboard.head.html:12-13; src/landing.html:10-11), so Google's font hosts leave the
   processor list and font-src is 'self'. These are the variable files Google serves for
   that request (family=Montserrat:ital,wght@0,300..700;1,300..500&display=swap): five unicode-range subsets per style,
   with the weight ranges the request declared (normal 300-700, italic 300-500), so a weight outside them renders as it
   did there. The woff2 files come from @fontsource-variable/montserrat 5.3.0 (Google Fonts v31; OFL-1.1, see
   public/fonts/OFL.txt) and are checked in under public/fonts; nothing loads them from npm or a CDN at run time.
   web/build.mjs puts these rules at the top of every page's stylesheet. */
/* cyrillic-ext */
@font-face{font-family:Montserrat;font-style:normal;font-weight:300 700;font-display:swap;src:url(/fonts/montserrat-cyrillic-ext-wght-normal.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}
/* cyrillic */
@font-face{font-family:Montserrat;font-style:normal;font-weight:300 700;font-display:swap;src:url(/fonts/montserrat-cyrillic-wght-normal.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
/* vietnamese */
@font-face{font-family:Montserrat;font-style:normal;font-weight:300 700;font-display:swap;src:url(/fonts/montserrat-vietnamese-wght-normal.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
/* latin-ext */
@font-face{font-family:Montserrat;font-style:normal;font-weight:300 700;font-display:swap;src:url(/fonts/montserrat-latin-ext-wght-normal.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
/* latin */
@font-face{font-family:Montserrat;font-style:normal;font-weight:300 700;font-display:swap;src:url(/fonts/montserrat-latin-wght-normal.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
/* cyrillic-ext */
@font-face{font-family:Montserrat;font-style:italic;font-weight:300 500;font-display:swap;src:url(/fonts/montserrat-cyrillic-ext-wght-italic.woff2) format("woff2");unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}
/* cyrillic */
@font-face{font-family:Montserrat;font-style:italic;font-weight:300 500;font-display:swap;src:url(/fonts/montserrat-cyrillic-wght-italic.woff2) format("woff2");unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
/* vietnamese */
@font-face{font-family:Montserrat;font-style:italic;font-weight:300 500;font-display:swap;src:url(/fonts/montserrat-vietnamese-wght-italic.woff2) format("woff2");unicode-range:U+0102-0103,U+0110-0111,U+0128-0129,U+0168-0169,U+01A0-01A1,U+01AF-01B0,U+0300-0301,U+0303-0304,U+0308-0309,U+0323,U+0329,U+1EA0-1EF9,U+20AB}
/* latin-ext */
@font-face{font-family:Montserrat;font-style:italic;font-weight:300 500;font-display:swap;src:url(/fonts/montserrat-latin-ext-wght-italic.woff2) format("woff2");unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
/* latin */
@font-face{font-family:Montserrat;font-style:italic;font-weight:300 500;font-display:swap;src:url(/fonts/montserrat-latin-wght-italic.woff2) format("woff2");unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}



/* ============================================================
   Vidya core: Obsidian, humanized (DESIGN.md).
   Cool graphite monochrome, inverted-ink primary actions, pearl
   Twins, real glass on floating layers, Montserrat everywhere, with a
   light italic turn for display lines and italic for quoted human words.
   Tokens first; dark values are authored once between the @dark
   markers and build.mjs mirrors them into prefers-color-scheme.
   ============================================================ */
:root{
  /* graphite ramp (hue 220 to 235, saturation under 8%): primitives only */
  --ink-950:#08090A;--ink-900:#0B0C0E;--ink-800:#131418;--ink-700:#1A1B20;--ink-600:#26282E;--ink-500:#3A3D45;
  --ink-400:#62656E;--ink-300:#8B8F98;--ink-200:#C4C6CC;--ink-100:#E6E7EA;--ink-50:#F4F4F6;
  --paper:#F7F7F8;--white:#FFFFFF;

  /* surfaces, lines, text */
  --bg:#F7F7F8;--surface:#FFFFFF;--sunken:#F1F1F3;--raised:#FFFFFF;
  --line:#E6E6E9;--line-2:#D6D7DB;
  --fg:#0B0C0E;--fg-2:#4A4D55;--fg-3:#5F626B;--fg-4:#A1A3AA;   /* fg-4 is for non-text only */

  /* ink actions: there is no chromatic accent, accent is ink */
  --accent:#0B0C0E;--on-accent:#FFFFFF;--accent-text:#0B0C0E;
  --accent-mid:#2A2C32;--accent-strong:#0B0C0E;--accent-soft:#EEEEF1;
  --btn:#0B0C0E;--on-btn:#FFFFFF;--focus:#0B0C0E;
  --user:#EFEFF2;

  /* status: success is ink (never green), warn is amber, danger is red */
  --sage:#1F2025;--sage-soft:#EEEEF1;--sage-ink:#0B0C0E;
  --amber:#D97706;--amber-soft:#FDF3E1;--amber-ink:#8A4A05;
  --clay:#DC2626;--clay-soft:#FDECEC;--clay-ink:#A51C1C;

  /* charts */
  --forming:#8B8F98;--hatch:rgba(255,255,255,.55);
  --bar-strong:linear-gradient(180deg,#5B5F69 0%,#2A2C32 100%);

  /* depth */
  --deep:linear-gradient(155deg,#43464F 0%,#17181C 46%,#0B0C0E 100%);
  --scrim:rgba(10,11,13,.14);
  --shadow-1:0 1px 2px rgba(10,11,14,.06);
  --shadow-2:0 16px 40px -22px rgba(10,11,14,.26),0 1px 2px rgba(10,11,14,.05);
  --shadow-3:0 36px 90px -30px rgba(10,11,14,.34),0 6px 20px -8px rgba(10,11,14,.08);
  --thumb:#FFFFFF;

  /* AI moments only: white light split, green cut out on purpose */
  --prism:linear-gradient(90deg,#8EA2FF 0%,#B79CFF 30%,#F29CCB 64%,#FFC58C 100%);
  --em-fill:linear-gradient(180deg,#5B5F69 0%,#1A1B20 100%);
  --sel:rgba(120,138,255,.22);

  /* glass */
  --g-fill:rgba(255,255,255,.72);
  --g-fill-2:rgba(255,255,255,.80);
  --g-chip:rgba(255,255,255,.62);
  --g-line:rgba(12,13,16,.09);
  --g-hi:rgba(255,255,255,.95);
  --g-glow:radial-gradient(120% 70% at 50% -14%,rgba(255,255,255,.62) 0%,rgba(255,255,255,0) 62%);
  --g-rim:linear-gradient(160deg,rgba(255,255,255,1) 0%,rgba(255,255,255,.45) 20%,rgba(255,255,255,0) 44%,rgba(255,255,255,0) 72%,rgba(255,255,255,.7) 100%);
  --g-shadow:0 30px 80px -30px rgba(10,11,14,.30),0 8px 22px -10px rgba(10,11,14,.10);
  --g-shadow-sm:0 1px 2px rgba(10,11,14,.06),0 8px 20px -10px rgba(10,11,14,.18);
  --g-blur:blur(30px) saturate(190%);
  --edge:linear-gradient(to bottom,rgba(247,247,248,.86) 0%,rgba(247,247,248,.62) 55%,rgba(247,247,248,0) 100%);

  /* ambient light fields behind the glass (a trace on light) */
  --amb:radial-gradient(58% 46% at 50% -8%,rgba(150,160,215,.07) 0%,rgba(150,160,215,0) 70%),
        radial-gradient(36% 40% at 6% 4%,rgba(176,156,255,.05) 0%,rgba(176,156,255,0) 70%),
        radial-gradient(34% 36% at 96% 6%,rgba(255,168,204,.04) 0%,rgba(255,168,204,0) 72%),
        radial-gradient(40% 40% at 88% 96%,rgba(255,206,160,.035) 0%,rgba(255,206,160,0) 70%);
  --grain-o:0;

  /* voice: black-pearl mic on light */
  --mic-bg:radial-gradient(circle at 33% 22%,rgba(255,255,255,.62) 0,rgba(255,255,255,.14) 15%,rgba(255,255,255,0) 34%),
           radial-gradient(circle at 74% 86%,rgba(142,162,255,.52) 0,rgba(142,162,255,0) 44%),
           radial-gradient(circle at 22% 84%,rgba(242,156,203,.30) 0,rgba(242,156,203,0) 40%),
           radial-gradient(circle at 90% 42%,rgba(255,197,140,.20) 0,rgba(255,197,140,0) 32%),
           linear-gradient(165deg,#60646E 0%,#2A2C32 42%,#0B0C0E 100%);
  --mic-fg:#FFFFFF;
  --mic-sh:inset 0 0 0 1px rgba(255,255,255,.16),inset 0 -12px 20px rgba(0,0,0,.42),inset 0 8px 14px rgba(255,255,255,.10),
           0 18px 36px -14px rgba(10,11,14,.55),0 0 0 1px rgba(10,11,14,.10),0 0 44px rgba(142,162,255,.22);
  --mic-sh-hover:inset 0 0 0 1px rgba(255,255,255,.2),inset 0 -12px 20px rgba(0,0,0,.42),inset 0 8px 14px rgba(255,255,255,.12),
           0 22px 40px -14px rgba(10,11,14,.6),0 0 0 1px rgba(10,11,14,.10),0 0 60px rgba(142,162,255,.34);
  --mic-sh-hold:inset 0 0 0 1px rgba(255,255,255,.22),inset 0 -12px 20px rgba(0,0,0,.4),inset 0 8px 14px rgba(255,255,255,.14),
           0 18px 36px -12px rgba(10,11,14,.6),0 0 0 1px rgba(10,11,14,.10),0 0 90px rgba(160,150,255,.55);
  --sun:radial-gradient(closest-side,rgba(142,162,255,.22) 0%,rgba(183,156,255,.12) 38%,rgba(242,156,203,.06) 64%,rgba(242,156,203,0) 100%);
  --dock-glow:radial-gradient(56% 115% at 50% 100%,rgba(150,158,210,.12),rgba(150,158,210,0) 72%);
  --cor:rgba(142,162,255,.55);
  --pv1:#5A5E68;--pv2:#0B0C0E;--pvr:#2A2C32;   /* the Vidya planet */

  /* type */
  /* one family everywhere: Montserrat. The other tokens stay as aliases so existing rules keep working. */
  --font:'Montserrat',ui-sans-serif,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif;
  --mono:var(--font);         /* numerics: Montserrat with tabular figures (set where used) */
  --serif:var(--font);        /* display turn: Montserrat light italic */
  --serif-text:var(--font);   /* quoted human words: Montserrat italic */

  /* motion: exponential ease-outs, no overshoot anywhere */
  --ease-out:cubic-bezier(.16,1,.3,1);
  --ease-soft:cubic-bezier(.32,.72,0,1);
  --ease-in:cubic-bezier(.4,0,1,1);
  --ease-in-out:cubic-bezier(.65,0,.35,1);

  --r-card:16px;--r-sheet:28px;
  color-scheme:light;
}

/*@dark-begin*/
:root[data-theme="dark"]{
  --bg:#0A0A0C;--surface:#111215;--sunken:#17181C;--raised:#1B1C21;
  --line:#212329;--line-2:#2F3138;
  --fg:#EDEEF0;--fg-2:#A7AAB2;--fg-3:#8A8E97;--fg-4:#5C5F68;
  --accent:#F4F4F5;--on-accent:#0B0C0E;--accent-text:#F4F4F5;
  --accent-mid:#D2D4DA;--accent-strong:#ECEDF0;--accent-soft:rgba(255,255,255,.075);
  --btn:#F4F4F5;--on-btn:#0B0C0E;--focus:#F4F4F5;
  --user:#1C1D22;
  --sage:#C9CCD3;--sage-soft:rgba(255,255,255,.08);--sage-ink:#F4F4F5;
  --amber:#F5A524;--amber-soft:rgba(245,165,36,.13);--amber-ink:#FBC66A;
  --clay:#EF4444;--clay-soft:rgba(239,68,68,.14);--clay-ink:#FF9D9D;
  --forming:#6A6E78;--hatch:rgba(10,10,12,.45);
  --bar-strong:linear-gradient(180deg,#E2E4E9 0%,#858994 100%);
  --deep:linear-gradient(155deg,#4A4D57 0%,#1A1B20 46%,#0B0C0E 100%);
  --scrim:rgba(0,0,0,.5);
  --shadow-1:0 1px 2px rgba(0,0,0,.4);
  --shadow-2:0 16px 40px -20px rgba(0,0,0,.8),0 1px 0 rgba(255,255,255,.02) inset;
  --shadow-3:0 36px 90px -28px rgba(0,0,0,.85),0 8px 24px -10px rgba(0,0,0,.5);
  --thumb:#2A2C33;
  --em-fill:linear-gradient(180deg,#FFFFFF 0%,#C9CCD4 55%,#8E939E 100%);
  --sel:rgba(142,162,255,.30);
  --g-fill:rgba(26,27,32,.50);
  --g-fill-2:rgba(22,23,28,.62);
  --g-chip:rgba(255,255,255,.05);
  --g-line:rgba(255,255,255,.09);
  --g-hi:rgba(255,255,255,.16);
  --g-glow:radial-gradient(120% 70% at 50% -14%,rgba(255,255,255,.11) 0%,rgba(255,255,255,0) 62%);
  --g-rim:linear-gradient(160deg,rgba(255,255,255,.42) 0%,rgba(255,255,255,.12) 22%,rgba(255,255,255,0) 44%,rgba(255,255,255,0) 70%,rgba(255,255,255,.16) 100%);
  --g-shadow:0 36px 90px -26px rgba(0,0,0,.8),0 10px 28px -12px rgba(0,0,0,.55);
  --g-shadow-sm:0 1px 2px rgba(0,0,0,.4),0 8px 22px -10px rgba(0,0,0,.6);
  --g-blur:blur(30px) saturate(200%);
  --edge:linear-gradient(to bottom,rgba(10,10,12,.86) 0%,rgba(10,10,12,.6) 55%,rgba(10,10,12,0) 100%);
  --amb:radial-gradient(56% 44% at 50% -10%,rgba(190,198,240,.13) 0%,rgba(190,198,240,0) 70%),
        radial-gradient(34% 38% at 4% 2%,rgba(140,120,255,.10) 0%,rgba(140,120,255,0) 70%),
        radial-gradient(32% 34% at 98% 4%,rgba(255,120,180,.06) 0%,rgba(255,120,180,0) 72%),
        radial-gradient(44% 40% at 90% 100%,rgba(120,140,255,.06) 0%,rgba(120,140,255,0) 70%);
  --grain-o:.05;
  /* voice: chrome-pearl mic on dark */
  --mic-bg:radial-gradient(circle at 33% 24%,rgba(255,255,255,1) 0%,rgba(255,255,255,.92) 12%,rgba(255,255,255,0) 38%),
           radial-gradient(circle at 74% 84%,rgba(142,162,255,.40) 0%,rgba(142,162,255,0) 42%),
           radial-gradient(circle at 24% 86%,rgba(242,156,203,.26) 0%,rgba(242,156,203,0) 40%),
           radial-gradient(circle at 88% 44%,rgba(255,197,140,.20) 0%,rgba(255,197,140,0) 34%),
           linear-gradient(172deg,#FBFBFC 0%,#DCDEE3 36%,#A6AAB4 54%,#C9CCD3 68%,#EEEFF2 100%);
  --mic-fg:#0B0C0E;
  --mic-sh:inset 0 0 0 1px rgba(255,255,255,.75),inset 0 -12px 20px rgba(24,26,34,.22),inset 0 8px 12px rgba(255,255,255,.55),
           0 18px 36px -16px rgba(0,0,0,.7),0 0 0 1px rgba(0,0,0,.2),0 0 46px rgba(170,178,230,.22);
  --mic-sh-hover:inset 0 0 0 1px rgba(255,255,255,.8),inset 0 -12px 20px rgba(24,26,34,.22),inset 0 8px 12px rgba(255,255,255,.55),
           0 22px 40px -16px rgba(0,0,0,.75),0 0 0 1px rgba(0,0,0,.2),0 0 60px rgba(170,178,240,.34);
  --mic-sh-hold:inset 0 0 0 1px rgba(255,255,255,.85),inset 0 -12px 20px rgba(24,26,34,.2),inset 0 8px 12px rgba(255,255,255,.6),
           0 18px 36px -12px rgba(0,0,0,.75),0 0 0 1px rgba(0,0,0,.2),0 0 90px rgba(180,170,255,.55);
  --sun:radial-gradient(closest-side,rgba(230,233,245,.17) 0%,rgba(160,168,240,.09) 36%,rgba(200,150,240,.05) 58%,rgba(255,150,200,.03) 76%,rgba(255,150,200,0) 100%);
  --dock-glow:radial-gradient(56% 115% at 50% 100%,rgba(170,178,240,.085),rgba(170,178,240,0) 72%);
  --cor:rgba(190,196,225,.7);
  --pv1:#5C606B;--pv2:#0B0C0E;--pvr:#E6E8EE;
  color-scheme:dark;
}
/* dark only: the drawer is the widest glass and carries the most secondary text, and on dark a white primary
   button blurred under it is the brightest thing in the page, so its smoke is a little heavier (DESIGN 5.4) */
:root[data-theme="dark"] .d .drawer{background:var(--g-glow),color-mix(in srgb,var(--surface) 74%,transparent)}
/*@dark-end*/
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
  --bg:#0A0A0C;--surface:#111215;--sunken:#17181C;--raised:#1B1C21;
  --line:#212329;--line-2:#2F3138;
  --fg:#EDEEF0;--fg-2:#A7AAB2;--fg-3:#8A8E97;--fg-4:#5C5F68;
  --accent:#F4F4F5;--on-accent:#0B0C0E;--accent-text:#F4F4F5;
  --accent-mid:#D2D4DA;--accent-strong:#ECEDF0;--accent-soft:rgba(255,255,255,.075);
  --btn:#F4F4F5;--on-btn:#0B0C0E;--focus:#F4F4F5;
  --user:#1C1D22;
  --sage:#C9CCD3;--sage-soft:rgba(255,255,255,.08);--sage-ink:#F4F4F5;
  --amber:#F5A524;--amber-soft:rgba(245,165,36,.13);--amber-ink:#FBC66A;
  --clay:#EF4444;--clay-soft:rgba(239,68,68,.14);--clay-ink:#FF9D9D;
  --forming:#6A6E78;--hatch:rgba(10,10,12,.45);
  --bar-strong:linear-gradient(180deg,#E2E4E9 0%,#858994 100%);
  --deep:linear-gradient(155deg,#4A4D57 0%,#1A1B20 46%,#0B0C0E 100%);
  --scrim:rgba(0,0,0,.5);
  --shadow-1:0 1px 2px rgba(0,0,0,.4);
  --shadow-2:0 16px 40px -20px rgba(0,0,0,.8),0 1px 0 rgba(255,255,255,.02) inset;
  --shadow-3:0 36px 90px -28px rgba(0,0,0,.85),0 8px 24px -10px rgba(0,0,0,.5);
  --thumb:#2A2C33;
  --em-fill:linear-gradient(180deg,#FFFFFF 0%,#C9CCD4 55%,#8E939E 100%);
  --sel:rgba(142,162,255,.30);
  --g-fill:rgba(26,27,32,.50);
  --g-fill-2:rgba(22,23,28,.62);
  --g-chip:rgba(255,255,255,.05);
  --g-line:rgba(255,255,255,.09);
  --g-hi:rgba(255,255,255,.16);
  --g-glow:radial-gradient(120% 70% at 50% -14%,rgba(255,255,255,.11) 0%,rgba(255,255,255,0) 62%);
  --g-rim:linear-gradient(160deg,rgba(255,255,255,.42) 0%,rgba(255,255,255,.12) 22%,rgba(255,255,255,0) 44%,rgba(255,255,255,0) 70%,rgba(255,255,255,.16) 100%);
  --g-shadow:0 36px 90px -26px rgba(0,0,0,.8),0 10px 28px -12px rgba(0,0,0,.55);
  --g-shadow-sm:0 1px 2px rgba(0,0,0,.4),0 8px 22px -10px rgba(0,0,0,.6);
  --g-blur:blur(30px) saturate(200%);
  --edge:linear-gradient(to bottom,rgba(10,10,12,.86) 0%,rgba(10,10,12,.6) 55%,rgba(10,10,12,0) 100%);
  --amb:radial-gradient(56% 44% at 50% -10%,rgba(190,198,240,.13) 0%,rgba(190,198,240,0) 70%),
        radial-gradient(34% 38% at 4% 2%,rgba(140,120,255,.10) 0%,rgba(140,120,255,0) 70%),
        radial-gradient(32% 34% at 98% 4%,rgba(255,120,180,.06) 0%,rgba(255,120,180,0) 72%),
        radial-gradient(44% 40% at 90% 100%,rgba(120,140,255,.06) 0%,rgba(120,140,255,0) 70%);
  --grain-o:.05;
  /* voice: chrome-pearl mic on dark */
  --mic-bg:radial-gradient(circle at 33% 24%,rgba(255,255,255,1) 0%,rgba(255,255,255,.92) 12%,rgba(255,255,255,0) 38%),
           radial-gradient(circle at 74% 84%,rgba(142,162,255,.40) 0%,rgba(142,162,255,0) 42%),
           radial-gradient(circle at 24% 86%,rgba(242,156,203,.26) 0%,rgba(242,156,203,0) 40%),
           radial-gradient(circle at 88% 44%,rgba(255,197,140,.20) 0%,rgba(255,197,140,0) 34%),
           linear-gradient(172deg,#FBFBFC 0%,#DCDEE3 36%,#A6AAB4 54%,#C9CCD3 68%,#EEEFF2 100%);
  --mic-fg:#0B0C0E;
  --mic-sh:inset 0 0 0 1px rgba(255,255,255,.75),inset 0 -12px 20px rgba(24,26,34,.22),inset 0 8px 12px rgba(255,255,255,.55),
           0 18px 36px -16px rgba(0,0,0,.7),0 0 0 1px rgba(0,0,0,.2),0 0 46px rgba(170,178,230,.22);
  --mic-sh-hover:inset 0 0 0 1px rgba(255,255,255,.8),inset 0 -12px 20px rgba(24,26,34,.22),inset 0 8px 12px rgba(255,255,255,.55),
           0 22px 40px -16px rgba(0,0,0,.75),0 0 0 1px rgba(0,0,0,.2),0 0 60px rgba(170,178,240,.34);
  --mic-sh-hold:inset 0 0 0 1px rgba(255,255,255,.85),inset 0 -12px 20px rgba(24,26,34,.2),inset 0 8px 12px rgba(255,255,255,.6),
           0 18px 36px -12px rgba(0,0,0,.75),0 0 0 1px rgba(0,0,0,.2),0 0 90px rgba(180,170,255,.55);
  --sun:radial-gradient(closest-side,rgba(230,233,245,.17) 0%,rgba(160,168,240,.09) 36%,rgba(200,150,240,.05) 58%,rgba(255,150,200,.03) 76%,rgba(255,150,200,0) 100%);
  --dock-glow:radial-gradient(56% 115% at 50% 100%,rgba(170,178,240,.085),rgba(170,178,240,0) 72%);
  --cor:rgba(190,196,225,.7);
  --pv1:#5C606B;--pv2:#0B0C0E;--pvr:#E6E8EE;
  color-scheme:dark;
}
/* dark only: the drawer is the widest glass and carries the most secondary text, and on dark a white primary
   button blurred under it is the brightest thing in the page, so its smoke is a little heavier (DESIGN 5.4) */
:root:not([data-theme="light"]) .d .drawer{background:var(--g-glow),color-mix(in srgb,var(--surface) 74%,transparent)}
}

/* ---------- base ---------- */
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}
html,body{height:100%}
body{font-family:var(--font);background:var(--bg);color:var(--fg);font-size:15px;line-height:1.5;letter-spacing:-.006em;
  -webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility}
button{font:inherit;letter-spacing:inherit;color:inherit;background:none;border:0;cursor:pointer;-webkit-tap-highlight-color:transparent;text-align:inherit}
input,textarea,select{font:inherit;letter-spacing:inherit;color:inherit}
::placeholder{color:var(--fg-3);opacity:1}
a{color:var(--accent-text);text-decoration:underline;text-decoration-color:color-mix(in srgb,currentColor 30%,transparent);text-underline-offset:3px;
  transition:text-decoration-color .16s var(--ease-out)}
a:hover{text-decoration-color:currentColor}
a.btn,a.chip,a.navrow,a.linkbtn,a.pill{text-decoration:none}
:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
/* headings and messages that only receive focus programmatically (overlay titles, a call summary) are not controls:
   no ring; a focused message gets the hlPulse flash instead (V.focusMsg) */
:is(h1,h2,h3,.msg)[tabindex="-1"]:focus-visible{outline:none}
::selection{background:var(--sel);color:var(--fg)}
[hidden]{display:none!important}
*{scrollbar-color:var(--line-2) transparent}
.i{width:20px;height:20px;stroke:currentColor;stroke-width:1.7;fill:none;stroke-linecap:round;stroke-linejoin:round;flex:0 0 auto;display:block}
.i.s16{width:16px;height:16px}.i.s18{width:18px;height:18px}.i.s22{width:22px;height:22px}.i.s24{width:24px;height:24px}
.mk{fill:currentColor;display:block;flex:0 0 auto}
.sr{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.tnum{font-variant-numeric:tabular-nums}
.muted{color:var(--fg-2)}.faint{color:var(--fg-3)}
.small{font-size:13px}.xs{font-size:12px}
.row-gap{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
.spacer{flex:1 1 auto}
/* viewport utilities (F9): shown only at phone width, or hidden at phone width */
@media (min-width:761px){.only-phone{display:none!important}}
@media (max-width:760px){.hide-phone{display:none!important}}

/* ---------- type ---------- */
/* labels: tracked Montserrat caps */
.eyebrow{font-family:var(--font);font-size:11px;font-weight:600;letter-spacing:.14em;text-transform:uppercase;color:var(--fg-3)}
.eyebrow.accent{color:var(--fg-2)}
.display{font-weight:300;letter-spacing:-.025em;line-height:1.1;text-wrap:balance}
.greet{font-size:42px;font-weight:300;letter-spacing:-.025em;line-height:1.12;text-wrap:balance}
.h2{font-size:20px;font-weight:600;letter-spacing:-.01em;line-height:1.25}
.h3{font-size:16px;font-weight:600;letter-spacing:-.005em}
/* the emphasis turn: Montserrat light italic, one step softer than the line it finishes (solid, no gradient text) */
.display em,.greet em{font-family:var(--font);font-style:italic;font-weight:300;letter-spacing:-.02em;color:var(--fg-2)}
/* quoted human words: Montserrat italic */
.quote,.twcard .smp{font-family:var(--font);font-style:italic;font-weight:400;letter-spacing:0}
/* numerics line up */
.tnum,.kbd,[data-count]{font-variant-numeric:tabular-nums}
.kbd{font-family:var(--mono);font-size:11px;font-weight:500;letter-spacing:0;padding:2px 6px;border-radius:6px;border:1px solid var(--line-2);
  background:var(--surface);color:var(--fg-2);box-shadow:0 1px 0 var(--line)}

/* ---------- theme transition ---------- */
::view-transition-old(root),::view-transition-new(root){animation:none;mix-blend-mode:normal}
html.theming *{transition:background-color .35s var(--ease-out),border-color .35s var(--ease-out),color .35s var(--ease-out),fill .35s,stroke .35s!important}

/* ---------- glass (DESIGN 5.1): only for layers that float over content ---------- */
.glass{background:var(--g-glow),var(--g-fill);border:1px solid var(--g-line);
  -webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow)}
.glass.dense{background:var(--g-glow),var(--g-fill-2)}
.glass.chip{background:var(--g-chip);box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow-sm);
  -webkit-backdrop-filter:blur(16px) saturate(160%);backdrop-filter:blur(16px) saturate(160%)}
/* edge light: a 1px masked ring. The host must be positioned and must not be the scroll container */
.glass-rim::after,.sidep::after,.pop::after,.smenu::after,.modal::after,.pal::after,.toast::after,.tobottom::after,.composer::after,
.topbar .iconbtn::after,.topbar .pill::after,.topbar .kbdhint::after{
  content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;pointer-events:none;z-index:3;background:var(--g-rim);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude}
.tobottom::after,.topbar .iconbtn::after,.topbar .pill::after,.topbar .kbdhint::after{opacity:.8}

/* ---------- buttons ---------- */
.btn{height:40px;display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:0 16px;border-radius:999px;
  font-size:13.5px;font-weight:500;letter-spacing:-.005em;white-space:nowrap;border:1px solid var(--line-2);background:var(--surface);color:var(--fg);
  box-shadow:0 1px 0 rgba(10,11,14,.03);user-select:none;
  transition:transform .16s var(--ease-out),background-color .2s var(--ease-out),border-color .2s var(--ease-out),box-shadow .2s var(--ease-out),filter .2s var(--ease-out),opacity .2s}
.btn:hover{border-color:var(--fg-4);background:var(--sunken)}
.btn:active{transform:scale(.97)}
.btn.primary,.btn.accent{background:var(--btn);border-color:var(--btn);color:var(--on-btn);box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 1px 2px rgba(0,0,0,.18)}
.btn.primary:hover,.btn.accent:hover{background:var(--btn);border-color:var(--btn);box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 6px 18px -8px rgba(0,0,0,.45);filter:brightness(1.12)}
.btn.soft{background:var(--accent-soft);border-color:transparent;color:var(--fg);box-shadow:none}
.btn.soft:hover{background:color-mix(in srgb,var(--fg) 9%,transparent)}
.btn.text{background:transparent;border-color:transparent;color:var(--fg-2);box-shadow:none}
.btn.text:hover{background:var(--accent-soft);color:var(--fg)}
.btn.danger{background:var(--clay);border-color:var(--clay);color:#fff;box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 1px 2px rgba(0,0,0,.18)}
.btn.danger:hover{background:var(--clay);border-color:var(--clay);filter:brightness(1.06)}
.btn.sm{height:34px;padding:0 13px;font-size:12.5px}
.btn.lg{height:48px;padding:0 22px;font-size:15px}
.btn.block{width:100%}
.btn .i{width:17px;height:17px}
.btn .spinner{width:14px;height:14px;border-width:1.75px}
/* unavailable and busy (F3): the real disabled attribute blocks input; aria-disabled keeps the click so the
   delegate can explain why (data-lockmsg), so it must never set pointer-events:none */
.btn[disabled],.btn.disabled{opacity:.45;pointer-events:none;box-shadow:none;filter:none}
.btn[aria-disabled="true"]{opacity:.45;cursor:not-allowed;box-shadow:none;filter:none}
.btn[aria-disabled="true"]:active{transform:none}
.btn[aria-busy="true"],.btn.is-busy{opacity:1;cursor:progress;filter:none}
.btn.primary[aria-busy="true"],.btn.accent[aria-busy="true"],.btn.primary.is-busy,.btn.accent.is-busy{background:color-mix(in srgb,var(--btn) 82%,var(--bg))}
.iconbtn{width:44px;height:44px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  background:var(--surface);border:1px solid var(--line);color:var(--fg-2);position:relative;box-shadow:var(--shadow-1);
  transition:transform .16s var(--ease-out),box-shadow .2s var(--ease-out),background-color .2s var(--ease-out),border-color .2s var(--ease-out),color .2s var(--ease-out)}
.iconbtn:hover{color:var(--fg);border-color:var(--line-2)}
.iconbtn:active{transform:scale(.94)}
.iconbtn.ghost{background:transparent;border-color:transparent;box-shadow:none;color:var(--fg-2)}
.iconbtn.ghost:hover{background:var(--accent-soft);color:var(--fg)}
.iconbtn.sm{width:36px;height:36px}
.iconbtn.on{box-shadow:0 0 0 3px var(--accent-soft)}
.iconbtn[disabled],.iconbtn[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
.iconbtn .badge{position:absolute;top:8px;right:9px;min-width:9px;height:9px;border-radius:99px;background:var(--fg);
  box-shadow:0 0 0 2px var(--bg);transition:transform .3s var(--ease-out)}
.iconbtn .badge.num{min-width:20px;height:20px;top:-4px;right:-4px;font-size:12px;font-weight:600;color:var(--on-btn);
  display:flex;align-items:center;justify-content:center;padding:0 5px;background:var(--btn);font-variant-numeric:tabular-nums}
.iconbtn .badge.pop{animation:pop .32s var(--ease-out)}
.linkbtn{color:var(--fg);font-weight:500;font-size:13px;display:inline-flex;align-items:center;gap:5px;white-space:nowrap}
.linkbtn .i{color:var(--fg-3);transition:transform .2s var(--ease-out)}
.linkbtn:hover{text-decoration:underline;text-decoration-color:color-mix(in srgb,currentColor 30%,transparent);text-underline-offset:3px}
.linkbtn:hover .i{transform:translateX(2px)}

/* ---------- chips, tags, avatars ---------- */
.chip{height:36px;display:inline-flex;align-items:center;gap:7px;padding:0 14px;border-radius:999px;border:1px solid var(--line-2);
  background:var(--surface);color:var(--fg-2);font-size:13px;font-weight:500;white-space:nowrap;
  transition:color .2s var(--ease-out),background-color .2s var(--ease-out),border-color .2s var(--ease-out),transform .16s var(--ease-out)}
.chip:hover{color:var(--fg);border-color:var(--fg-4)}
.chip:active{transform:scale(.97)}
.chip.on,.chip[aria-pressed="true"]{background:var(--btn);border-color:var(--btn);color:var(--on-btn)}
.chip[disabled],.chip[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
.chip .n{font-size:12px;opacity:.7;font-variant-numeric:tabular-nums}
.tag{display:inline-flex;align-items:center;gap:6px;height:24px;padding:0 10px;border-radius:999px;font-size:12px;font-weight:500;letter-spacing:0;white-space:nowrap}
.tag .dot{width:6px;height:6px;border-radius:50%;background:currentColor;flex:0 0 auto}
.tag.tide{background:var(--accent-soft);color:var(--fg);box-shadow:inset 0 0 0 1px var(--line)}
.tag.sage{background:var(--sage-soft);color:var(--sage-ink);box-shadow:inset 0 0 0 1px var(--line)}
.tag.amber{background:var(--amber-soft);color:var(--amber-ink)}
.tag.clay{background:var(--clay-soft);color:var(--clay-ink)}
.tag.neutral{background:var(--sunken);color:var(--fg-2)}
.tag.live .dot{background:var(--fg);box-shadow:0 0 0 3px color-mix(in srgb,var(--fg) 16%,transparent);animation:pulse 1.8s var(--ease-in-out) infinite}
.tag.amber.live .dot{background:var(--amber);box-shadow:0 0 0 3px color-mix(in srgb,var(--amber) 22%,transparent)}
/* "Always on" beside a locked setting (referenced by the toggle's aria-describedby) */
.tag.always{height:20px;padding:0 8px;margin-left:8px;vertical-align:1px;font-size:12px;font-weight:600;letter-spacing:.01em;
  background:var(--sunken);color:var(--fg-2);box-shadow:inset 0 0 0 1px var(--line)}
.av{width:32px;height:32px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  background:var(--accent-soft);color:var(--fg);box-shadow:inset 0 0 0 1px var(--line);font-size:11.5px;font-weight:600;letter-spacing:.02em}
.av.s24{width:24px;height:24px;font-size:9.5px}.av.s28{width:28px;height:28px;font-size:10.5px}
.av.s36{width:36px;height:36px;font-size:12px}.av.s40{width:40px;height:40px;font-size:13px}
.av.s48{width:48px;height:48px;font-size:15px}.av.s56{width:56px;height:56px;font-size:17px}.av.s72{width:72px;height:72px;font-size:21px}
.av.sq{border-radius:30%}
/* chrome pearl (the student's own face) */
.av.solid{color:#0B0C0E;background:radial-gradient(circle at 30% 22%,rgba(255,255,255,.95) 0,rgba(255,255,255,0) 40%),radial-gradient(circle at 76% 88%,rgba(142,162,255,.30) 0,rgba(142,162,255,0) 46%),linear-gradient(165deg,#FBFBFC 0%,#DADCE2 48%,#AEB2BC 100%);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.7),inset 0 -6px 12px rgba(20,22,30,.12),0 8px 20px -12px rgba(0,0,0,.5)}
.av.ink{background:var(--btn);color:var(--on-btn);box-shadow:none}
.av.muted{background:var(--sunken);color:var(--fg-2)}
/* logo tile: obsidian glass with a white mark */
.tile{width:28px;height:28px;border-radius:9px;background:var(--deep);color:#FFFFFF;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22),inset 0 0 0 1px rgba(255,255,255,.10),0 2px 6px -2px rgba(0,0,0,.35)}
.tile .mk{width:62%;height:62%}
.tile.s24{width:24px;height:24px;border-radius:8px}.tile.s32{width:32px;height:32px;border-radius:10px}
.tile.s36{width:36px;height:36px;border-radius:11px}.tile.s44{width:44px;height:44px;border-radius:13px}
.tile.spin .mk{animation:spin 1.8s linear infinite}

/* ---------- Twins are planets (DESIGN 9): one hue family per tone, none of them green ----------
   Each Twin's planet is designed in the planet library (web-voice.js: PLANETS) and rendered there once, in
   3D, to a data URL. Anything the app draws with a tone class (.av, @-menu faces) is matched to its Twin and
   given that render as --pl-img; the family default (--pl-tone-*, set on :root by the library) covers the
   rest, and the tone's own gradient stands in until a render exists. --pd is the tone's deep shade (r,g,b). */
.t-vid,.t-tide,.t-sage,.t-amber,.t-clay,.t-ink{
  --pearl:var(--pl-img) center/100% 100% no-repeat;
  --pearl-av:var(--pearl);
  --pl-sh:0 10px 18px -10px var(--pg),0 2px 5px -2px rgba(var(--pd),.3)}
.t-vid{--p1:var(--pv1);--p2:var(--pv2);--pi:#FFFFFF;--pg:rgba(0,0,0,.6);--pr:var(--pvr);--pd:0,0,0;
  --pl-img:var(--pl-tone-vid,radial-gradient(circle at 36% 30%,#5B5F69 0%,#2B2D34 34%,#111216 68%,#08090A 100%))}
.t-tide {--p1:#F2F5FF;--p2:#9DAEEA;--pi:#1F2C74;--pg:rgba(95,118,225,.55);--pr:#8EA2F0;--pd:34,46,128;
  --pl-img:var(--pl-tone-tide,radial-gradient(circle at 34% 28%,#F2F5FF,#9DAEEA 80%))}
.t-sage {--p1:#F7F2FF;--p2:#BBA5EE;--pi:#452A82;--pg:rgba(140,100,225,.5);--pr:#B39AF0;--pd:66,38,134;
  --pl-img:var(--pl-tone-sage,radial-gradient(circle at 34% 28%,#F7F2FF,#BBA5EE 80%))}
.t-amber{--p1:#FFF8EC;--p2:#E3C28A;--pi:#6A460E;--pg:rgba(205,150,60,.5);--pr:#E2B669;--pd:104,66,16;
  --pl-img:var(--pl-tone-amber,radial-gradient(circle at 34% 28%,#FFF8EC,#E3C28A 80%))}
.t-clay {--p1:#FFF2F5;--p2:#E9A7B9;--pi:#7C2240;--pg:rgba(220,100,140,.48);--pr:#EE9AB0;--pd:120,36,70;
  --pl-img:var(--pl-tone-clay,radial-gradient(circle at 34% 28%,#FFF2F5,#E9A7B9 80%))}
.t-ink  {--p1:#FBFBFC;--p2:#B5B8C0;--pi:#24262C;--pg:rgba(10,11,14,.38);--pr:#B4B8C1;--pd:22,24,32;
  --pl-img:var(--pl-tone-ink,radial-gradient(circle at 34% 28%,#FBFBFC,#B5B8C0 80%))}
/* list avatars and @-menu faces wear the same planet; Twin faces are round, the Vidya face stays the logo tile */
.av:is(.t-vid,.t-tide,.t-sage,.t-amber,.t-clay,.t-ink),.sopt .aface:is(.t-tide,.t-sage,.t-amber,.t-clay,.t-ink){
  background:var(--pearl-av);color:var(--pi);box-shadow:0 2px 5px -3px rgba(var(--pd),.45)}
.sopt .aface:is(.t-tide,.t-sage,.t-amber,.t-clay,.t-ink){border-radius:50%}
.av.t-vid{box-shadow:0 2px 6px -3px rgba(0,0,0,.5)}

/* ---------- surfaces ---------- */
.card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-card);padding:16px 18px;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.035),0 1px 2px rgba(10,11,14,.04)}
.card.flat{background:var(--sunken);border-color:transparent;box-shadow:none}
.card.pad-l{padding:20px 22px}
.card.tap{transition:transform .18s var(--ease-out),box-shadow .2s var(--ease-out),border-color .2s var(--ease-out);cursor:pointer}
.card.tap:hover{border-color:var(--line-2);box-shadow:var(--shadow-2)}
.card.tap:active{transform:scale(.99)}
.sec{display:flex;flex-direction:column;gap:12px}
.sec-head{display:flex;align-items:baseline;justify-content:space-between;gap:12px}
.list{display:flex;flex-direction:column}
.row{display:flex;align-items:center;gap:12px;padding:12px 2px;border-top:1px solid var(--line);min-width:0}
.row:first-child{border-top:0}
.row .body{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;gap:2px}
.row .t{font-size:14px;font-weight:600;line-height:1.35}
.row .s{font-size:12.5px;color:var(--fg-3);line-height:1.4}
.row.tap{cursor:pointer;border-radius:12px;transition:background-color .15s var(--ease-out)}
.row.tap:hover{background:var(--accent-soft)}
.iconsq{width:36px;height:36px;border-radius:11px;background:var(--sunken);color:var(--fg-2);box-shadow:inset 0 0 0 1px var(--line);
  display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto}
.iconsq.tide{background:var(--accent-soft);color:var(--fg)}
.kv{display:flex;justify-content:space-between;gap:12px;padding:10px 0;border-top:1px solid var(--line);font-size:13.5px}
.kv:first-child{border-top:0}
.kv .k{color:var(--fg-2)}.kv .v{font-weight:600;text-align:right;font-variant-numeric:tabular-nums}
.divider{height:1px;background:var(--line);margin:4px 0}

/* ---------- form controls ---------- */
.field{display:flex;flex-direction:column;gap:6px}
.field label{font-size:12.5px;font-weight:600;color:var(--fg-2)}
.input{height:46px;border-radius:14px;border:1px solid var(--line-2);background:var(--surface);padding:0 14px;font-size:15px;outline:none;width:100%;
  transition:border-color .2s var(--ease-out),box-shadow .2s var(--ease-out)}
.input:focus{border-color:var(--fg-3);box-shadow:0 0 0 4px var(--accent-soft)}
textarea.input{height:auto;padding:12px 14px;line-height:1.55;resize:none}
.search{display:flex;align-items:center;gap:10px;height:46px;border-radius:14px;background:var(--surface);padding:0 14px;color:var(--fg-3);
  border:1px solid var(--line-2);box-shadow:0 1px 0 rgba(10,11,14,.02);transition:border-color .2s var(--ease-out),box-shadow .2s var(--ease-out)}
.search:focus-within{border-color:var(--fg-3);box-shadow:0 0 0 4px var(--accent-soft)}
.search input{flex:1;border:0;outline:none;background:transparent;font-size:15px;color:var(--fg);min-width:0}
.search input::placeholder{color:var(--fg-3)}
.toggle{width:46px;height:28px;border-radius:99px;background:var(--line-2);position:relative;flex:0 0 auto;transition:background-color .25s var(--ease-out)}
.toggle::after{content:"";position:absolute;left:3px;top:3px;width:22px;height:22px;border-radius:50%;background:var(--white);
  box-shadow:0 1px 3px rgba(0,0,0,.35);transition:transform .28s var(--ease-out),background-color .25s var(--ease-out)}
.toggle[aria-checked="true"]{background:var(--btn)}
.toggle[aria-checked="true"]::after{transform:translateX(18px);background:var(--on-btn)}
/* locked: stays solid, carries a lock on the thumb (.lk in markup) and an "Always on" tag after the title */
.toggle.locked,.toggle[aria-disabled="true"]{opacity:1;cursor:not-allowed}
.toggle[disabled]{opacity:.45;cursor:not-allowed}
.toggle .lk{position:absolute;left:3px;top:3px;z-index:1;width:22px;height:22px;display:flex;align-items:center;justify-content:center;
  color:var(--ink-900);pointer-events:none;transition:transform .28s var(--ease-out)}
.toggle[aria-checked="true"] .lk{transform:translateX(18px);color:var(--btn)}
.toggle .lk .i,.toggle .lk svg{width:12px;height:12px;stroke-width:2.4}
.seg{display:inline-flex;gap:2px;padding:3px;border-radius:999px;background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line);position:relative}
.seg button{height:32px;padding:0 13px;border-radius:999px;font-size:12.5px;font-weight:500;color:var(--fg-2);position:relative;z-index:1;transition:color .2s var(--ease-out)}
.seg button:hover{color:var(--fg)}
.seg button.on,.seg button[aria-pressed="true"]{color:var(--fg);font-weight:600}
.seg button[disabled],.seg button[aria-disabled="true"]{opacity:.45;cursor:not-allowed}
/* the thumb's width is set without a transition; it moves with transform only (translateX from left:0) */
.seg .thumb{position:absolute;top:3px;bottom:3px;left:0;border-radius:999px;background:var(--thumb);
  box-shadow:0 1px 3px rgba(10,11,14,.14),inset 0 0 0 1px var(--line);transition:transform .34s var(--ease-out);z-index:0}
.setrow{display:flex;align-items:center;gap:14px;padding:14px 0;border-top:1px solid var(--line);flex-wrap:wrap}
.setrow:first-child{border-top:0}
.setrow .body{flex:1 1 200px;min-width:0}
.setrow .t{font-size:14px;font-weight:600}
.setrow .s{font-size:12.5px;color:var(--fg-3);margin-top:2px;line-height:1.45}

/* ---------- progress, bands, rings (luminance encodes, amber flags, nothing green) ---------- */
.bar{height:6px;border-radius:99px;background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line);overflow:hidden;position:relative}
.bar>i{position:absolute;left:0;top:0;bottom:0;border-radius:99px;background:var(--accent-mid);transform-origin:left;
  animation:growX .9s var(--ease-out) both}
.bands{display:flex;flex-direction:column;gap:10px}
.band{display:grid;grid-template-columns:minmax(96px,34%) 1fr auto;align-items:center;gap:12px;font-size:13px}
.band .l{color:var(--fg-2);font-weight:500}
.band .st{font-size:12px;font-weight:600;color:var(--fg-3);min-width:56px;text-align:right}
.band .bar i.strong{background:var(--bar-strong)}
.band .bar i.forming{background:var(--forming)}
.band .bar i.thin{background:var(--amber)}
.gapnote{font-size:12px;color:var(--fg-3);margin-top:-4px;padding-left:calc(34% + 12px)}
.ring{--p:0;--c:var(--fg);width:64px;height:64px;position:relative;flex:0 0 auto}
.ring svg{width:100%;height:100%;transform:rotate(-90deg)}
.ring .track{stroke:var(--line)}
.ring .val{stroke:var(--c);stroke-linecap:round;transition:stroke-dashoffset 1.2s var(--ease-out)}
.ring .lbl{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-weight:500;font-size:15px;letter-spacing:-.02em;font-variant-numeric:tabular-nums}

/* ---------- thread ---------- */
.thread{display:flex;flex-direction:column;gap:26px}
.daymark{display:flex;align-items:center;gap:12px;margin:8px 0 -6px}
.daymark span{font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3);white-space:nowrap}
.daymark::after{content:"";flex:1;height:1px;background:var(--line)}
.msg{animation:rise .46s var(--ease-out) both}
.msg.static{animation:none}
.msg.flash{animation:flash 1.9s var(--ease-out);border-radius:16px}
.u{display:flex;justify-content:flex-end}
.bub{background:var(--user);color:var(--fg);box-shadow:inset 0 0 0 1px var(--line);padding:11px 16px;border-radius:22px 22px 6px 22px;max-width:min(82%,540px);
  font-size:15px;line-height:1.55;overflow-wrap:anywhere}
.bub .vn{display:flex;align-items:center;gap:8px;margin-bottom:6px;font-size:12px;font-weight:600;color:var(--fg-2)}
.bub .vn .mini{display:flex;align-items:center;gap:2px;height:14px}
.bub .vn .mini i{width:2.5px;border-radius:2px;background:var(--fg-3)}
.a{display:flex;flex-direction:column;gap:10px;min-width:0}
.a-head{display:flex;align-items:center;gap:9px;min-width:0}
.a-head .who{font-size:13px;font-weight:600;cursor:pointer;white-space:nowrap;flex:0 0 auto}
.a-head .who:hover{text-decoration:underline;text-decoration-color:color-mix(in srgb,currentColor 30%,transparent);text-underline-offset:3px}
.a-head .meta{font-size:12px;color:var(--fg-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.a-body{font-size:16px;line-height:1.7;letter-spacing:-.006em;color:var(--fg)}
.a-body p+p{margin-top:10px}
.a-body strong{font-weight:600}
.a-body .hl{color:var(--fg);font-weight:600}
/* citations are the trust mechanic: a course reference ("L9 · slide 21"), never a code token */
.cite{display:inline-flex;align-items:center;height:22px;padding:0 8px;margin:0 2px;border-radius:7px;background:var(--sunken);color:var(--fg);
  font:600 12px/1 var(--font);letter-spacing:-.005em;vertical-align:2px;white-space:nowrap;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--fg) 26%,transparent);
  transition:transform .15s var(--ease-out),background-color .16s var(--ease-out),color .16s var(--ease-out),box-shadow .16s var(--ease-out);
  animation:pop .32s var(--ease-out) both}
.cite:hover{background:var(--btn);color:var(--on-btn);box-shadow:inset 0 0 0 1px var(--btn)}
.cite:active{transform:scale(.95)}
.caret{display:inline-block;width:8px;height:16px;margin-left:2px;border-radius:2px;background:var(--prism);background-size:100% 100%;vertical-align:-2px;animation:blink 1s steps(2) infinite}
.a-actions{display:flex;gap:2px;margin-left:-10px;flex-wrap:wrap;animation:fadeIn .5s var(--ease-out) both}
.a-actions button{height:32px;display:inline-flex;align-items:center;gap:6px;padding:0 10px;border-radius:999px;color:var(--fg-3);font-size:12px;font-weight:500;
  transition:background-color .15s var(--ease-out),color .15s var(--ease-out)}
.a-actions button:hover{background:var(--accent-soft);color:var(--fg)}
.a-actions button.on{color:var(--fg)}
.a-actions .i{width:16px;height:16px}
.thinking{display:flex;align-items:center;gap:10px}
/* "Thinking": quiet text that breathes (no gradient text) */
.shimmer{font-size:13px;font-weight:500;color:var(--fg-3);animation:breatheText 1.6s var(--ease-in-out) infinite}
.banner{display:flex;align-items:center;gap:10px;padding:10px 14px;border-radius:14px;background:var(--accent-soft);color:var(--fg);box-shadow:inset 0 0 0 1px var(--line);
  font-size:13.5px;font-weight:500;animation:rise .4s var(--ease-out)}
.banner .spacer{flex:1}
.banner button{font-size:12.5px;font-weight:600;color:var(--fg)}

/* brief (today) */
.brief{display:flex;flex-direction:column;gap:14px}
.brief .greet{font-size:40px}
.due{display:flex;flex-direction:column;border:1px solid var(--line);border-radius:18px;background:var(--surface);overflow:hidden;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.035),0 1px 2px rgba(10,11,14,.04)}
.due .row{padding:12px 14px}
.due .row .t{font-size:14px}
.resume{display:flex;align-items:center;gap:12px;padding:12px 14px;border-radius:16px;background:var(--sunken);cursor:pointer;transition:background-color .2s var(--ease-out)}
.resume:hover{background:var(--accent-soft)}

/* proposal (needs your OK) */
.proposal{border:1px solid var(--line);border-radius:20px;background:var(--surface);padding:14px 16px 16px;
  box-shadow:var(--shadow-2),inset 0 1px 0 rgba(255,255,255,.035);transition:box-shadow .3s var(--ease-out)}
.proposal .p-top{display:flex;align-items:center;justify-content:space-between;gap:8px;flex-wrap:wrap}
.proposal .p-item{display:flex;align-items:center;gap:12px;padding:11px 0;border-top:1px solid var(--line)}
.proposal .p-item:first-of-type{border-top:0}
.proposal .p-acts{display:flex;gap:8px;margin-top:10px;flex-wrap:wrap}
.proposal .chk{width:24px;height:24px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:var(--btn);color:var(--on-btn);flex:0 0 auto}
.proposal .chk path{stroke-dasharray:24;stroke-dashoffset:24;animation:draw .5s .15s var(--ease-out) forwards}
.proposal.done{box-shadow:inset 0 1px 0 rgba(255,255,255,.035),0 1px 2px rgba(10,11,14,.04)}
.proposal.done .p-acts{display:none}
.proposal .preview{margin-top:8px;padding:12px 14px;border-radius:14px;background:var(--sunken);font-size:13.5px;line-height:1.6;color:var(--fg-2)}

/* refusal, policy, pending, returned, care */
.refusal{background:var(--sunken);border-radius:18px;padding:14px 16px 16px}
.refusal .r-t{display:flex;align-items:center;gap:8px;font-size:15px;font-weight:600}
.refusal p{margin-top:6px;font-size:14px;line-height:1.6;color:var(--fg-2)}
.refusal .r-acts{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}
.slab{border-radius:18px;padding:14px 16px;background:var(--surface);border:1px solid var(--line);font-size:13.5px;line-height:1.6;color:var(--fg-2)}
.slab .acts{display:flex;gap:8px;margin-top:12px;flex-wrap:wrap}
.slab.calm{background:var(--accent-soft);border-color:transparent;color:var(--fg)}
.slab.warm{background:var(--amber-soft);border-color:transparent;color:var(--fg)}
.pend{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.care{border-radius:20px;padding:16px;background:var(--accent-soft);box-shadow:inset 0 0 0 1px var(--line);display:flex;flex-direction:column;gap:10px}
.care .h{font-size:15px;font-weight:600}

/* quiz */
.quiz{border:1px solid var(--line);border-radius:20px;background:var(--surface);padding:16px;box-shadow:inset 0 1px 0 rgba(255,255,255,.035),0 1px 2px rgba(10,11,14,.04)}
.quiz .q{font-size:15.5px;font-weight:600;line-height:1.45;margin:8px 0 12px}
.quiz .opts{display:flex;flex-direction:column;gap:8px}
.quiz .opt{display:flex;align-items:center;gap:12px;min-height:48px;padding:10px 14px;border-radius:14px;border:1px solid var(--line);
  background:var(--surface);font-size:14px;text-align:left;
  transition:border-color .25s var(--ease-out),background-color .25s var(--ease-out),opacity .25s var(--ease-out),transform .16s var(--ease-out)}
.quiz .opt:hover{border-color:var(--line-2);background:var(--sunken)}
.quiz .opt .k{width:26px;height:26px;border-radius:8px;background:var(--sunken);display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;flex:0 0 auto;
  transition:background-color .25s var(--ease-out),color .25s var(--ease-out)}
.quiz .opt.right{border-color:var(--fg);background:var(--accent-soft)}
.quiz .opt.right .k{background:var(--btn);color:var(--on-btn)}
.quiz .opt.wrong{border-color:var(--clay);background:var(--clay-soft);animation:shake .4s var(--ease-out)}
.quiz .opt.wrong .k{background:var(--clay);color:#fff}
.quiz .opt.dim{opacity:.5}
/* revealed content shows at its full height at once and fades up 6px (no animated height) */
.quiz .explain{display:none}
.quiz .explain.on{display:block;animation:fadeUp .2s var(--ease-out) both}
.quiz .explain p{margin-top:12px;font-size:14px;line-height:1.6;color:var(--fg-2)}

/* audio + transcript */
.audio{display:flex;align-items:center;gap:12px;padding:8px 14px 8px 8px;border-radius:999px;background:var(--accent-soft);max-width:340px}
.audio .play{width:34px;height:34px;border-radius:50%;background:var(--btn);color:var(--on-btn);display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  transition:transform .15s var(--ease-out)}
.audio .play:active{transform:scale(.92)}
.audio .play .i{width:15px;height:15px;fill:currentColor;stroke:none}
.audio .wv{flex:1;display:flex;align-items:center;gap:2.5px;height:24px}
.audio .wv i{flex:1;border-radius:2px;background:var(--fg);opacity:.28;transition:opacity .2s var(--ease-out)}
.audio .wv i.on{opacity:1}
.audio .dur{font-family:var(--mono);font-size:12px;font-weight:500;color:var(--fg-2);font-variant-numeric:tabular-nums}
.fold{display:none}
.fold.on{display:block;animation:fadeUp .2s var(--ease-out) both}
.transcript{margin-top:8px;padding:12px 14px;border-radius:14px;background:var(--sunken);font-size:13.5px;line-height:1.6;color:var(--fg-2)}
.transcript b{color:var(--fg);font-weight:600}

/* sources: the professor's slide stays paper-white in both themes, drawn in graphite */
.src{display:flex;flex-direction:column;gap:12px}
.slide{border:1px solid var(--line);border-radius:14px;background:#FFFFFF;color:#0B0C0E;box-shadow:0 1px 2px rgba(10,11,14,.05);
  padding:14px 16px 12px;aspect-ratio:16/9;display:flex;flex-direction:column;gap:8px;overflow:hidden}
.slide.text{aspect-ratio:auto;min-height:120px}
.slide .st{font-size:13px;font-weight:600;color:#0B0C0E}
.slide ul{list-style:none;display:flex;flex-direction:column;gap:6px;font-size:12.5px;color:#4A4D55}
.slide ul li::before{content:"";display:inline-block;width:5px;height:5px;border-radius:50%;background:#2A2C32;margin-right:8px;vertical-align:2px}
.slide svg{width:100%;height:auto;flex:1;min-height:0}
.slide .notes{font-size:12.5px;line-height:1.6;color:#4A4D55}
.quote{background:var(--sunken);color:var(--fg);border-radius:4px 12px 12px 4px;padding:11px 14px 11px 16px;font-size:15px;line-height:1.55;
  box-shadow:inset 2px 0 0 var(--fg)}

/* twin profile */
.tp-head{display:flex;align-items:center;gap:14px}
.sample{background:var(--sunken);border-radius:18px;padding:16px 18px;font-size:15.5px;line-height:1.6;font-weight:400}
.sample .by{margin-top:10px;display:flex;align-items:center;gap:10px}
/* the Twin's sample line is quoted human words, like .twcard .smp; its Listen row stays UI */
.sample{font-family:var(--serif-text);font-style:italic;font-variation-settings:"opsz" 14;font-size:16.5px;color:var(--fg)}
.sample .by{font-family:var(--font);font-style:normal;font-variation-settings:normal;font-size:13px}

/* stats */
.stat{display:flex;flex-direction:column;gap:4px}
.stat .n{font-size:30px;font-weight:350;letter-spacing:-.045em;line-height:1;font-variant-numeric:tabular-nums}
.stat .l{font-size:12.5px;color:var(--fg-3)}
.stat .d{font-size:12px;font-weight:600;display:inline-flex;align-items:center;gap:5px}
.stat .d.up{color:var(--fg)}.stat .d.dn{color:var(--clay-ink)}

/* toast: dense glass with an edge-lit rim (F2 action slot lives in engine.css) */
.toast{position:absolute;left:50%;top:18px;transform:translate(-50%,-14px);z-index:500;
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow);color:var(--fg);
  font-size:13.5px;font-weight:500;padding:11px 18px;border-radius:999px;opacity:0;pointer-events:none;width:max-content;
  transition:opacity .22s var(--ease-out),transform .28s var(--ease-out);display:flex;align-items:center;gap:8px;max-width:min(92%,480px);line-height:1.35}
.toast .i{color:var(--fg-2)}
.toast.on{opacity:1;transform:translate(-50%,0)}

/* ---------- empty + skeleton ---------- */
.empty{padding:48px 20px;text-align:center;color:var(--fg-3);font-size:14px}
.empty .big{display:block;font-size:20px;font-weight:500;letter-spacing:-.015em;color:var(--fg-2);margin-bottom:6px}
.skel{background:var(--sunken);border-radius:8px;animation:breatheText 1.4s var(--ease-in-out) infinite}

/* ---------- charts ---------- */
.hbars{display:flex;flex-direction:column;gap:12px}
.hbar{display:flex;flex-direction:column;gap:6px}
.hbar .top{display:flex;justify-content:space-between;gap:10px;font-size:13.5px}
.hbar .top b{font-weight:600}
.hbar .top span{color:var(--fg-3);font-size:12.5px;white-space:nowrap;font-variant-numeric:tabular-nums}
/* coverage columns: geometry here; state colours (strong, forming, thin, future) belong to professor.css */
.cov{display:flex;align-items:flex-end;gap:6px;height:120px}
.cov .wk{flex:1;display:flex;flex-direction:column;align-items:center;gap:6px;height:100%;justify-content:flex-end}
.cov .col{width:64%;border-radius:4px 4px 1px 1px;background:var(--accent-mid);transform-origin:bottom;animation:growY .8s var(--ease-out) both}
.cov .wl{font-family:var(--mono);font-size:12px;font-weight:500;letter-spacing:0;color:var(--fg-3)}
.heat{display:grid;gap:4px}
.heat .c{aspect-ratio:1;border-radius:5px;background:var(--accent-mid);animation:fadeIn .6s var(--ease-out) both}

/* ---------- keyframes: exponential ease-outs, no overshoot ---------- */
@keyframes rise{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes fadeIn{from{opacity:0}to{opacity:1}}
@keyframes fadeUp{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
@keyframes pop{from{transform:scale(.9);opacity:0}to{transform:none;opacity:1}}
@keyframes spin{to{transform:rotate(360deg)}}
@keyframes breatheText{0%,100%{opacity:1}50%{opacity:.45}}
@keyframes blink{50%{opacity:0}}
@keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.8)}}
@keyframes draw{to{stroke-dashoffset:0}}
@keyframes growX{from{transform:scaleX(0)}to{transform:scaleX(1)}}
@keyframes growY{from{transform:scaleY(0)}to{transform:scaleY(1)}}
@keyframes flash{0%{background-color:transparent;box-shadow:0 0 0 12px transparent}18%{background-color:var(--accent-soft);box-shadow:0 0 0 12px var(--accent-soft)}100%{background-color:transparent;box-shadow:0 0 0 12px transparent}}
@keyframes shake{0%,100%{transform:translateX(0)}25%{transform:translateX(-4px)}75%{transform:translateX(4px)}}
@keyframes ripple{0%{transform:scale(.9);opacity:.75}100%{transform:scale(1.9);opacity:0}}
@keyframes breathe{0%,100%{opacity:.8;transform:translateX(-50%) scale(1)}50%{opacity:1;transform:translateX(-50%) scale(1.05)}}
@keyframes wiggle{0%,100%{transform:rotate(0)}20%{transform:rotate(-12deg)}40%{transform:rotate(10deg)}60%{transform:rotate(-6deg)}80%{transform:rotate(3deg)}}
@keyframes slideUp{from{transform:translateY(100%)}to{transform:none}}
@keyframes tick{0%{transform:translateY(0)}30%{transform:translateY(-2px)}100%{transform:none}}
@keyframes hlPulse{0%{box-shadow:0 0 0 0 rgba(186,192,214,.7)}70%{box-shadow:0 0 0 16px rgba(186,192,214,0)}100%{box-shadow:0 0 0 0 rgba(186,192,214,0)}}
@keyframes fadeSwap{from{opacity:0;transform:translateY(8px)}to{opacity:1;transform:none}}
@keyframes titleIn{from{opacity:0;transform:translateY(-5px)}to{opacity:1;transform:none}}
@keyframes memGone{to{opacity:0;transform:translateX(20px)}}

@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.001ms!important;scroll-behavior:auto!important}
}

/* ---------- navigation (drawer content, shared by both shells) ---------- */
.dhead{display:flex;align-items:center;justify-content:space-between;gap:10px;padding:0 2px 0 8px;height:44px}
.brandlock{display:flex;align-items:center;gap:10px;color:var(--fg)}
.brandlock span{font-size:14px;font-weight:600;letter-spacing:.24em;color:var(--fg)}
.brandlock .mk{width:24px;height:24px}
.note{display:flex;gap:8px;align-items:flex-start;font-size:12px;line-height:1.5;color:var(--fg-3)}
.note .i{margin-top:1px}
.navrow{display:flex;align-items:center;gap:12px;padding:9px 10px;border-radius:14px;width:100%;text-align:left;transition:background-color .18s var(--ease-out);position:relative}
.navrow:hover{background:var(--accent-soft)}
.navrow.on{background:var(--accent-soft);box-shadow:inset 0 0 0 1px var(--line)}
.navrow .body{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
/* a long course name wraps to a second line instead of losing its end ("Senior Seminar in Chemi...") */
.navrow .t{font-size:14px;font-weight:600;line-height:1.35;overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}
.navrow .s{font-size:12px;line-height:1.4;color:var(--fg-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.navrow.on .s{color:var(--fg-2)}
.navrow .cnt{font-size:12px;color:var(--fg-3);font-weight:600;flex:0 0 auto;font-variant-numeric:tabular-nums}
.navrow .ico{width:32px;height:32px;border-radius:10px;display:inline-flex;align-items:center;justify-content:center;background:var(--sunken);color:var(--fg-2);flex:0 0 auto}
.navrow.on .ico{background:var(--surface);color:var(--fg);box-shadow:inset 0 0 0 1px var(--line)}
.navsec{font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3);margin:18px 10px 6px}
.chips{display:flex;gap:6px;flex-wrap:wrap;padding:2px 8px}
.chips .chip{height:32px;font-size:12.5px;padding:0 12px}
.dfoot{display:flex;align-items:center;gap:12px;padding:14px 8px 4px;border-top:1px solid var(--g-line);margin-top:18px}
.stag{animation:rise .5s var(--ease-out) both}

/* ---------- pages ---------- */
.page{display:flex;flex-direction:column;gap:22px}
.page-head{display:flex;flex-direction:column;gap:8px}
.page-head .display{font-size:34px}
.page-head p{color:var(--fg-2);font-size:14.5px;line-height:1.6;max-width:60ch}
.cards{display:grid;gap:12px}
.twcard{display:flex;flex-direction:column;gap:12px}
.twcard .top{display:flex;align-items:center;gap:12px}
.twcard .nm{font-size:15px;font-weight:600}
.twcard .rl{font-size:12.5px;color:var(--fg-3);margin-top:1px}
.twcard .smp{font-size:15px;line-height:1.5;color:var(--fg-2)}
.minicov{display:flex;gap:3px}
.minicov i{height:5px;flex:1;border-radius:99px;background:var(--sunken)}
.minicov i.strong{background:var(--bar-strong)}.minicov i.forming{background:var(--forming)}.minicov i.thin{background:var(--amber)}
/* single choice (plans, course picker, invites) is a radio group: a leading radio, a filled chosen state */
.plans{display:grid;gap:10px}
.plan{border:1px solid var(--line);border-radius:18px;padding:14px 16px;display:flex;align-items:center;gap:14px;text-align:left;width:100%;background:var(--surface);
  transition:border-color .25s var(--ease-out),background-color .25s var(--ease-out),box-shadow .25s var(--ease-out),transform .2s var(--ease-out)}
.plan:hover{border-color:var(--line-2)}
.plan:active{transform:scale(.99)}
.plan.on,.plan[aria-checked="true"]{border-color:var(--fg);background:var(--accent-soft);box-shadow:inset 0 0 0 .5px var(--fg)}
.plan .radio{width:20px;height:20px;border-radius:50%;flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;color:transparent;
  box-shadow:inset 0 0 0 1.5px var(--line-2);transition:background-color .2s var(--ease-out),box-shadow .2s var(--ease-out),color .2s var(--ease-out)}
.plan .radio .i,.plan .radio svg{width:12px;height:12px;stroke-width:3}
.plan.on .radio,.plan[aria-checked="true"] .radio{background:var(--btn);color:var(--on-btn);box-shadow:none}
.plan.dim .radio{opacity:.5}
.plan .pn{font-size:15px;font-weight:600}
.plan .pd{font-size:12.5px;color:var(--fg-3)}
.plan .pp{margin-left:auto;text-align:right;flex:0 0 auto}
.plan .pp span{white-space:nowrap}
.plan .pp b{font-size:18px;font-weight:600;display:block;font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.plan .pp span{font-size:12px;color:var(--fg-3)}
.packs{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.pack{border:1px solid var(--line);border-radius:16px;padding:12px;display:flex;flex-direction:column;gap:2px;text-align:left;background:var(--surface);
  transition:border-color .25s var(--ease-out),background-color .25s var(--ease-out),box-shadow .25s var(--ease-out),opacity .25s var(--ease-out),transform .2s var(--ease-out)}
.pack:hover{border-color:var(--line-2)}
.pack:active{transform:scale(.98)}
.pack b{font-size:17px;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.pack span{font-size:12px;color:var(--fg-3)}
.pack.on,.pack[aria-checked="true"],.pack[aria-pressed="true"]{border-color:var(--fg);background:var(--accent-soft);box-shadow:inset 0 0 0 .5px var(--fg)}
.pack.dim{opacity:.45}
.success{display:flex;flex-direction:column;align-items:center;text-align:center;gap:10px;padding:20px 8px}
.success .ok{width:64px;height:64px;border-radius:50%;background:var(--btn);color:var(--on-btn);display:flex;align-items:center;justify-content:center;animation:pop .42s var(--ease-out)}
.success .ok path{stroke-dasharray:24;stroke-dashoffset:24;animation:draw .55s .25s var(--ease-out) forwards}
.spinner{width:18px;height:18px;border-radius:50%;border:2px solid currentColor;border-right-color:transparent;animation:spin .7s linear infinite;display:inline-block;flex:0 0 auto}
.memrow{display:flex;align-items:center;gap:12px;padding:12px 0;border-top:1px solid var(--line)}
.memrow:first-child{border-top:0}
.memrow .t{flex:1;font-size:14px;line-height:1.5}
.memrow.gone{animation:memGone .18s var(--ease-in) forwards;pointer-events:none}
.tips{display:flex;flex-direction:column;gap:10px}
.tips li{list-style:none;display:flex;gap:10px;align-items:flex-start;font-size:13.5px;line-height:1.5;color:var(--fg-2)}
.tips li .iconsq{width:28px;height:28px;border-radius:9px}

/* ---------- shared shell bits ---------- */
.pill{position:relative;height:44px;display:inline-flex;align-items:center;gap:8px;padding:0 15px 0 12px;border-radius:999px;background:var(--surface);border:1px solid var(--line);
  box-shadow:var(--shadow-1);font-size:14px;font-weight:600;color:var(--fg);transition:transform .16s var(--ease-out),box-shadow .2s var(--ease-out),border-color .2s var(--ease-out)}
.pill:hover{border-color:var(--line-2)}
.pill .i{color:var(--fg-2)}
.pill .pl{font-size:13px;font-weight:500;color:var(--fg-2)}
.pill:active{transform:scale(.97)}
.pill.on{box-shadow:0 0 0 3px var(--accent-soft)}
.pill b{display:inline-block;font-family:var(--mono);font-weight:500;font-size:13.5px;letter-spacing:-.02em;font-variant-numeric:tabular-nums}
.pill.tick b{animation:tick .5s var(--ease-out)}
.title{flex:1;min-width:0;display:flex;align-items:center;gap:10px}
.title.swap{animation:titleIn .38s var(--ease-out)}
.title .tw{display:flex;flex-direction:column;min-width:0}
.title .tt{font-size:15px;font-weight:600;letter-spacing:-.01em;line-height:1.28;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.title .ts{font-size:12px;color:var(--fg-3);line-height:1.3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sh-t{flex:1;min-width:0}
.sh-t .t{font-size:16.5px;font-weight:600;letter-spacing:-.015em;line-height:1.3}
.sh-t .s{font-size:12.5px;color:var(--fg-3);margin-top:1px}
.scope{height:36px;display:inline-flex;align-items:center;gap:7px;padding:0 11px 0 6px;border-radius:999px;background:var(--accent-soft);color:var(--fg);
  box-shadow:inset 0 0 0 1px var(--line);font-size:13px;font-weight:500;min-width:0;max-width:100%;
  transition:transform .2s var(--ease-out),background-color .25s var(--ease-out),color .25s var(--ease-out)}
.scope>span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.scope:active{transform:scale(.97)}
.scope.open,.scope[aria-expanded="true"]{background:var(--btn);color:var(--on-btn);box-shadow:none}
.scope.bump{animation:pop .32s var(--ease-out)}
.scope .unpin{display:inline-flex;width:22px;height:22px;border-radius:50%;align-items:center;justify-content:center;margin-right:-5px;flex:0 0 auto;
  background:color-mix(in srgb,var(--fg) 10%,transparent);transition:background-color .2s var(--ease-out)}
.scope .unpin:hover{background:color-mix(in srgb,var(--fg) 18%,transparent)}
.scope .tile,.scope .av{flex:0 0 auto}
.attchip{display:inline-flex;align-items:center;gap:7px;height:32px;padding:0 6px 0 11px;border-radius:10px;background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line);
  font-size:12.5px;font-weight:500;color:var(--fg-2);animation:pop .3s var(--ease-out);min-width:0}
.attchip span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.attchip button{width:24px;height:24px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--fg-3)}
.attchip button:hover{background:var(--line);color:var(--fg)}
.att-card{display:flex;align-items:center;gap:8px;margin:-2px -6px 8px;padding:8px 10px;border-radius:12px;background:var(--surface);font-size:12.5px;font-weight:500;color:var(--fg-2)}
.tobottom{position:absolute;left:50%;bottom:calc(100% + 6px);width:40px;height:40px;margin-left:-20px;border-radius:50%;
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--shadow-2);display:flex;align-items:center;justify-content:center;color:var(--fg-2);
  opacity:0;transform:translateY(10px) scale(.94);pointer-events:none;transition:opacity .25s var(--ease-out),transform .32s var(--ease-out),color .2s;z-index:2}
.tobottom:hover{color:var(--fg)}
.tobottom.on{opacity:1;transform:none;pointer-events:auto}
.hl{animation:hlPulse 1.6s var(--ease-out)!important}
.swap{animation:fadeSwap .38s var(--ease-out)}
.rec{display:flex;align-items:center;gap:10px}
.rec .rdot{width:10px;height:10px;border-radius:50%;background:var(--clay);animation:pulse 1s var(--ease-in-out) infinite;flex:0 0 auto}
.rec .rtime{font-family:var(--mono);font-size:13.5px;font-weight:500;font-variant-numeric:tabular-nums;min-width:36px}
.rec .rbars{display:flex;align-items:center;gap:2px;height:26px;flex:1;min-width:0;overflow:hidden;justify-content:flex-end}
/* level bars keep a fixed box and scale (--h is the level, 0 to 1) */
.rec .rbars i{width:3px;height:100%;border-radius:2px;background:var(--fg-2);flex:0 0 auto;transform:scaleY(var(--h,.15));transition:transform .09s linear}
.rec .rcancel{font-size:12px;font-weight:500;color:var(--fg-3);white-space:nowrap;display:flex;align-items:center;gap:2px;transform:translateX(var(--dx,0));transition:color .2s var(--ease-out)}
.rec.cancel .rcancel{color:var(--clay-ink)}
.rec.cancel .rbars i{background:var(--clay)}

/* the name on top of a chat opens its profile, like any messaging app */
.title .chatid{display:flex;align-items:center;gap:inherit;min-width:0;max-width:100%;padding:4px 8px 4px 4px;margin:-4px 0 -4px -4px;border:0;border-radius:14px;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer;
  -webkit-tap-highlight-color:transparent;transition:background-color .2s var(--ease-out),transform .18s var(--ease-out)}
.title .chatid:hover{background:color-mix(in srgb,var(--fg) 6%,transparent)}
.title .chatid:active{transform:scale(.98)}
.title .chatid .tt{display:flex;align-items:center;min-width:0}
.title .chatid .tn{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.title .chatid .tt .i{flex:0 0 auto;display:inline-block;width:14px;height:14px;margin-left:2px;vertical-align:-2px;color:var(--fg-3)}
/* a Twin's profile leads with its numbers */
.tstats{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:8px}
.tstats>div{display:flex;flex-direction:column;gap:3px;min-width:0;padding:12px 12px 11px;border-radius:16px;background:var(--sunken)}
.tstats b{font-size:21px;font-weight:500;letter-spacing:-.03em;line-height:1.15;color:var(--fg);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;font-variant-numeric:tabular-nums}
.tstats b.sm{font-size:14.5px;line-height:1.65;letter-spacing:-.01em}
.tstats span{font-size:12px;line-height:1.3;color:var(--fg-3)}
/* a Twin's test chat before the first question */
.twinempty{display:flex;flex-direction:column;align-items:center;gap:6px;line-height:1.55}
.twinempty .av{margin-bottom:6px}
.twinempty>span:not(.big):not(.av){max-width:36ch}
.twinempty .chips{justify-content:center;padding:0;margin-top:14px}

/* ============================================================
   Vidya · Web shell: one menu button, a floating drawer, a centred
   conversation, a right panel for sources and profiles, popovers,
   modals and a command palette. Content scrolls under a transparent
   top bar; every floating layer is glass.
   ============================================================ */
body.d{overflow:hidden}
.d .app{position:fixed;inset:0;display:flex;flex-direction:column;background:var(--bg);--sideW:460px;--dockH:150px;--topPad:92px;padding-top:env(safe-area-inset-top,0px)}
/* ambient light fields (so the glass has something to bend), and grain on dark */
.d .app::before{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;background:var(--amb)}
.d .app::after{content:"";position:absolute;inset:0;z-index:-1;pointer-events:none;opacity:var(--grain-o);
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='160' height='160'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='2' stitchTiles='stitch'/%3E%3CfeColorMatrix values='0 0 0 0 1  0 0 0 0 1  0 0 0 0 1  0 0 0 .55 0'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

/* top bar: floats over the page; a masked scroll edge fades in once content slides under it */
.topbar{position:absolute;top:env(safe-area-inset-top,0px);left:0;right:0;z-index:30;height:78px;display:flex;align-items:center;justify-content:space-between;gap:16px;
  padding:0 24px;background:transparent}
.topbar-edge{position:absolute;left:0;right:0;top:0;height:calc(100% + 28px);pointer-events:none;opacity:0;background:var(--edge);
  -webkit-backdrop-filter:blur(20px) saturate(170%);backdrop-filter:blur(20px) saturate(170%);
  -webkit-mask-image:linear-gradient(to bottom,#000 0%,#000 56%,transparent 100%);mask-image:linear-gradient(to bottom,#000 0%,#000 56%,transparent 100%);
  transition:opacity .35s var(--ease-out)}
.topbar.scrolled .topbar-edge{opacity:1}
.topbar .tl{position:relative;z-index:1;display:flex;align-items:center;gap:14px;min-width:0;flex:1}
.topbar .tr{position:relative;z-index:1;display:flex;align-items:center;gap:10px;flex:0 0 auto}
.topbar .title .tt{font-size:15.5px}
.topbar .title .tag{margin-left:6px}
/* top-bar controls are glass chips with an edge-lit rim */
.topbar .iconbtn,.topbar .pill,.topbar .kbdhint{background:var(--g-chip);border-color:var(--g-line);box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow-sm);
  -webkit-backdrop-filter:blur(16px) saturate(160%);backdrop-filter:blur(16px) saturate(160%)}
.topbar .iconbtn:hover,.topbar .pill:hover,.topbar .kbdhint:hover{border-color:var(--line-2)}
.topbar .iconbtn.on,.topbar .pill.on{box-shadow:inset 0 1px 0 var(--g-hi),0 0 0 3px var(--accent-soft)}
.kbdhint{position:relative;display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 12px 0 14px;border-radius:999px;color:var(--fg-3);font-size:13px;font-weight:500;
  border:1px solid var(--line);background:var(--surface);transition:color .2s var(--ease-out),border-color .2s var(--ease-out)}
.kbdhint:hover{color:var(--fg);border-color:var(--line-2)}

/* body: screens, dock, right panel. Scoped to the shell element: a bare .d .body also matched every row's .body
   (setrow, row, sopt...) and, loading later, overrode their flex basis, so label columns never wrapped on phones */
.d #dbody{position:relative;flex:1;min-height:0}
#screens{position:absolute;inset:0}
.d .app.side-on #screens{right:var(--sideW)}
.screen{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;padding:86px 32px 72px}
.screen .page{max-width:900px;margin:0 auto}
.screen.thread-screen{padding:0;overflow:hidden}
/* the thread reserves the dock box; while the orbit is up (#app.dock-up) it reserves the orbit too, set not animated */
.thread-screen .scroll{position:absolute;inset:0;overflow-y:auto;overflow-x:hidden;padding:98px 32px calc(var(--dockH) + 40px);
  scroll-padding-top:98px;scroll-padding-bottom:calc(var(--dockReach, var(--dockH)) + 24px)}
#app.dock-up .thread-screen .scroll{padding-bottom:calc(var(--dockReach, var(--dockH)) + 40px)}
.thread-screen .thread{max-width:760px;margin:0 auto}
.screen.enter{animation:dIn .42s var(--ease-out) both}
.screen.leave{animation:dOut .18s var(--ease-in) both;pointer-events:none}
@keyframes dIn{from{opacity:0;transform:translateY(12px)}to{opacity:1;transform:none}}
@keyframes dOut{to{opacity:0;transform:translateY(-6px)}}
.screen::-webkit-scrollbar,.thread-screen .scroll::-webkit-scrollbar,.sp-body::-webkit-scrollbar,.pop-body::-webkit-scrollbar,.modal .sh-body::-webkit-scrollbar{width:10px}
.screen::-webkit-scrollbar-thumb,.thread-screen .scroll::-webkit-scrollbar-thumb,.sp-body::-webkit-scrollbar-thumb,.pop-body::-webkit-scrollbar-thumb,.modal .sh-body::-webkit-scrollbar-thumb{
  background:var(--line-2);border-radius:10px;border:3px solid transparent;background-clip:padding-box}
.d .thread{gap:28px}
.d .brief .due .row{padding:13px 16px}

/* dock + composer: the band under the dock frosts what slides beneath it, then settles into the page colour */
.d .dock{position:absolute;left:0;right:0;bottom:0;z-index:20;padding:0 32px calc(22px + env(safe-area-inset-bottom,0px));pointer-events:none;
  transition:transform .45s var(--ease-soft),opacity .3s var(--ease-out)}
.d .app.side-on .dock{right:var(--sideW)}
.d .dock::before{content:"";position:absolute;left:0;right:0;bottom:0;height:calc(100% + 34px);pointer-events:none;
  background:linear-gradient(to bottom,color-mix(in srgb,var(--bg) 0%,transparent) 0,color-mix(in srgb,var(--bg) 70%,transparent) 28px,var(--bg) 46px);
  -webkit-backdrop-filter:blur(10px) saturate(140%);backdrop-filter:blur(10px) saturate(140%);
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 30px);mask-image:linear-gradient(to bottom,transparent 0,#000 30px)}
.d .dock.hide{transform:translateY(50px);opacity:0}
.d .dock.hide *{pointer-events:none!important}
.dock-in{position:relative;max-width:760px;margin:0 auto}
.composer{position:relative;pointer-events:auto;border-radius:26px;padding:14px 12px 10px 20px;display:flex;flex-direction:column;gap:8px;
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow);transition:border-color .2s var(--ease-out),box-shadow .25s var(--ease-out)}
.composer:focus-within{border-color:var(--line-2);box-shadow:0 0 0 4px var(--accent-soft),inset 0 1px 0 var(--g-hi),var(--g-shadow)}
.composer .att-row{display:flex;gap:8px;margin-left:-6px}
.composer .att-row:empty{display:none}
.composer textarea{width:100%;border:0;outline:none;background:transparent;resize:none;font-size:16px;line-height:1.55;height:26px;max-height:220px;color:var(--fg);padding:0}
.composer textarea::placeholder{color:var(--fg-3)}
.c-row{display:flex;align-items:center;justify-content:space-between;gap:10px;margin-left:-8px}
.c-l,.c-r{display:flex;align-items:center;gap:8px;min-width:0}
.cbtn{width:38px;height:38px;border-radius:50%;border:1px solid var(--line);display:inline-flex;align-items:center;justify-content:center;color:var(--fg-2);flex:0 0 auto;
  transition:background-color .2s var(--ease-out),color .2s var(--ease-out),border-color .2s var(--ease-out),transform .15s var(--ease-out)}
.cbtn.ghost{border-color:transparent}
.cbtn:hover{background:var(--accent-soft);color:var(--fg)}
.cbtn:active{transform:scale(.94)}
.cbtn.on{background:var(--accent-soft);color:var(--fg);border-color:transparent}
.cbtn.on .i{animation:pulse 1.1s var(--ease-in-out) infinite}
.c-hint{font-size:12px;color:var(--fg-3);opacity:0;transition:opacity .25s var(--ease-out);white-space:nowrap}
.composer:focus-within .c-hint{opacity:1}
.talk{height:44px;display:inline-flex;align-items:center;gap:8px;padding:0 18px 0 14px;border-radius:999px;background:var(--btn);color:var(--on-btn);font-size:14px;font-weight:500;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16),0 8px 20px -10px rgba(0,0,0,.5);
  transition:transform .25s var(--ease-out),background-color .25s var(--ease-out),color .25s var(--ease-out),box-shadow .25s var(--ease-out),filter .2s var(--ease-out);position:relative;
  user-select:none;-webkit-user-select:none;touch-action:none;flex:0 0 auto}
.talk:hover{box-shadow:inset 0 1px 0 rgba(255,255,255,.16),0 12px 26px -10px rgba(0,0,0,.6);filter:brightness(1.1)}
.talk:active{transform:scale(.97)}
.talk .i{width:20px;height:20px;stroke-width:2}
.talk .lb{display:inline-flex;align-items:center;gap:8px}
.talk .lb.swap{animation:pop .3s var(--ease-out)}
.talk.send{background:var(--btn);color:var(--on-btn)}
.talk.hold{transform:scale(1.04);background:var(--btn);color:var(--on-btn)}
.talk .o-ring{position:absolute;inset:-5px;border-radius:999px;border:2px solid var(--fg-3);opacity:0;pointer-events:none}
.talk.hold .o-ring{animation:ripple 1.4s var(--ease-out) infinite}
.talk.nope{animation:shake .4s var(--ease-out)}
.composer .rec{position:absolute;left:14px;right:14px;top:10px;height:38px;padding:0 6px;background:var(--g-fill-2);opacity:0;transform:translateY(-4px);pointer-events:none;
  transition:opacity .2s var(--ease-out),transform .3s var(--ease-out)}
.composer.recording .rec{opacity:1;transform:none}
.composer.recording textarea{visibility:hidden}
.composer.hl{border-color:var(--fg-3)}
.d .tobottom{bottom:calc(100% + 12px)}

/* right panel (sources, profiles): glass with an edge-lit rim; it scrolls inside .sp-body */
.sidep{position:absolute;top:86px;right:16px;bottom:16px;width:calc(var(--sideW) - 32px);z-index:25;border-radius:22px;
  background:var(--g-glow),var(--g-fill);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow);display:flex;flex-direction:column;overflow:hidden;
  transform:translateX(calc(100% + 40px));visibility:hidden;transition:transform .5s var(--ease-soft),visibility 0s linear .5s}
.d .app.side-on .sidep{transform:none;visibility:visible;transition:transform .5s var(--ease-soft),visibility 0s}
.sp-head{display:flex;align-items:center;gap:12px;padding:16px 14px 14px 20px;border-bottom:1px solid var(--g-line);flex:0 0 auto}
.sp-body{flex:1;overflow-y:auto;padding:20px 22px 30px;min-height:0}
.pop .card.flat{background:color-mix(in srgb,var(--sunken) 72%,transparent)}
@media (max-width:1180px){.d .app.side-on #screens,.d .app.side-on .dock{right:0}}

/* floating drawer: dense glass (DESIGN 5.4: a bright primary button blurred under it cost AA on dark, so it is
   raised to dense); it scrolls, so its edge light is an inset highlight instead of a rim */
.d .drawer{position:absolute;top:12px;left:12px;bottom:12px;width:340px;max-width:calc(100vw - 24px);z-index:60;border-radius:22px;
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),inset 1px 0 0 color-mix(in srgb,var(--g-hi) 45%,transparent),var(--g-shadow);
  padding:14px 12px 16px;overflow-y:auto;transform:translateX(calc(-100% - 30px));visibility:hidden;
  transition:transform .48s var(--ease-soft),visibility 0s linear .48s}
.d .app.drawer-on .drawer{transform:none;visibility:visible;transition:transform .48s var(--ease-soft),visibility 0s}
.d .drawer .stag{animation:none}
.d .app.drawer-on .drawer .stag{animation:rise .45s var(--ease-out) both}
/* scrims soften the page as well as dimming it */
.d .d-scrim{position:absolute;inset:0;z-index:55;background:var(--scrim);-webkit-backdrop-filter:blur(6px) saturate(120%);backdrop-filter:blur(6px) saturate(120%);
  opacity:0;pointer-events:none;transition:opacity .35s var(--ease-out)}
.d .app.drawer-on .d-scrim{opacity:.7;pointer-events:auto}

/* popovers: glass with an edge-lit rim; plans and packs inside are translucent */
.pops{position:absolute;inset:0;z-index:80;pointer-events:none}
.pop{position:absolute;pointer-events:auto;border-radius:18px;display:flex;flex-direction:column;max-width:calc(100vw - 24px);max-height:calc(100vh - 110px);
  background:var(--g-glow),var(--g-fill);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow);animation:popIn .34s var(--ease-out) both}
.pop.up{animation-name:popUp}
.pop.out{animation:popOut .16s var(--ease-in) forwards}
@keyframes popIn{from{opacity:0;transform:scale(.96) translateY(-6px)}to{opacity:1;transform:none}}
@keyframes popUp{from{opacity:0;transform:scale(.96) translateY(6px)}to{opacity:1;transform:none}}
@keyframes popOut{to{opacity:0;transform:scale(.98) translateY(-4px)}}
.pop-head{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:16px 14px 8px 20px;flex:0 0 auto}
.pop-head .t{font-size:15.5px;font-weight:600;letter-spacing:-.012em}
.pop-body{overflow-y:auto;padding:6px 20px 20px;min-height:0}
.pop-body.swap{animation:fadeSwap .35s var(--ease-out)}
.pop .plan:not(.on):not([aria-checked="true"]),.pop .pack:not(.on):not([aria-checked="true"]),
.modal .plan:not(.on):not([aria-checked="true"]){background:color-mix(in srgb,var(--surface) 58%,transparent)}

/* @-menu (who answers): dense glass, it sits over the orb and planets */
.smenu{position:absolute;z-index:85;width:360px;max-width:calc(100vw - 24px);border-radius:18px;padding:8px;
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow);transform-origin:24px 100%;animation:popUp .3s var(--ease-out) both}
.smenu.out{animation:popOut .16s var(--ease-in) forwards}
.smenu .sm-h{display:flex;justify-content:space-between;align-items:center;padding:8px 12px 6px}
.sopt{display:flex;align-items:center;gap:12px;width:100%;padding:8px 10px;border-radius:12px;text-align:left;transition:background-color .15s var(--ease-out)}
.sopt:hover{background:color-mix(in srgb,var(--fg) 5%,transparent)}
.sopt .aface{width:36px;height:36px;border-radius:11px;display:flex;align-items:center;justify-content:center;background:var(--accent-soft);color:var(--fg);
  font-size:12.5px;font-weight:600;flex:0 0 auto}
.sopt .aface.vid{background:var(--deep);color:#FFFFFF;box-shadow:inset 0 1px 0 rgba(255,255,255,.22),inset 0 0 0 1px rgba(255,255,255,.10)}
.sopt .aface.vid .mk{width:58%;height:58%}
.sopt .aface.find{background:var(--sunken);color:var(--fg-2);box-shadow:inset 0 0 0 1px var(--line)}
.sopt .body{flex:1;min-width:0;display:flex;flex-direction:column;gap:1px}
.sopt .t{font-size:14px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sopt .s{font-size:12px;color:var(--fg-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.sopt.act{background:var(--accent-soft)}
.sopt .ck{color:var(--fg);opacity:0;flex:0 0 auto}
.sopt.on .ck{opacity:1}
.sopt:focus-visible{outline-offset:-2px}
.smenu .sm-f{font-size:12px;color:var(--fg-3);padding:10px 12px 4px;border-top:1px solid var(--g-line);margin-top:6px;display:flex;align-items:center;gap:6px}
.smenu .empty{padding:18px 12px}

/* modals: dense glass with an edge-lit rim */
.modals{position:absolute;inset:0;z-index:90;pointer-events:none}
.modal-wrap{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:40px;pointer-events:auto}
.modal-scrim{position:absolute;inset:0;background:var(--scrim);-webkit-backdrop-filter:blur(6px) saturate(120%);backdrop-filter:blur(6px) saturate(120%);animation:fadeIn .25s var(--ease-out) both}
.modal{position:relative;width:min(560px,100%);max-height:calc(100vh - 80px);border-radius:24px;display:flex;flex-direction:column;
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow);animation:modalIn .42s var(--ease-out) both}
.modal.lg{width:min(780px,100%)}
.modal .sh-head{display:flex;align-items:center;gap:12px;padding:20px 18px 12px 26px;flex:0 0 auto}
.modal .sh-body{overflow-y:auto;padding:6px 26px 26px;min-height:0}
@keyframes modalIn{from{opacity:0;transform:translateY(18px) scale(.96)}to{opacity:1;transform:none}}
.modal-wrap.out .modal{animation:modalOut .18s var(--ease-in) forwards}
.modal-wrap.out .modal-scrim{animation:fadeOut .18s var(--ease-in) forwards}
@keyframes modalOut{to{opacity:0;transform:translateY(8px) scale(.98)}}
@keyframes fadeOut{to{opacity:0}}

/* command palette: dense glass with an edge-lit rim */
.palette{position:absolute;inset:0;z-index:95;display:none;align-items:flex-start;justify-content:center;padding-top:13vh}
.palette.on{display:flex}
.pal-scrim{position:absolute;inset:0;background:var(--scrim);-webkit-backdrop-filter:blur(6px) saturate(120%);backdrop-filter:blur(6px) saturate(120%);animation:fadeIn .2s var(--ease-out) both}
.pal{position:relative;width:min(640px,92vw);border-radius:20px;overflow:hidden;
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow);animation:modalIn .32s var(--ease-out) both}
.pal-in{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--g-line);color:var(--fg-3)}
.pal-in input{flex:1;border:0;outline:none;background:transparent;font-size:17px;letter-spacing:-.01em;color:var(--fg);min-width:0}
.pal-in input::placeholder{color:var(--fg-3)}
.pal-list{max-height:min(440px,56vh);overflow-y:auto;padding:8px}
.pal-g{font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3);padding:10px 12px 4px}
.pal-it{display:flex;align-items:center;gap:12px;width:100%;padding:8px 12px;border-radius:12px;text-align:left}
.pal-it .t{flex:1;font-size:14px;font-weight:500;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pal-it .s{font-size:12px;color:var(--fg-3)}
.pal-it.on{background:var(--accent-soft);box-shadow:inset 0 0 0 1px var(--g-line)}
.pal-it.on .s{color:var(--fg-2)}
.pal-foot{display:flex;gap:18px;padding:10px 20px;border-top:1px solid var(--g-line);font-size:12px;color:var(--fg-3)}
.pal-foot span{display:inline-flex;align-items:center;gap:6px}

/* ---------- legibility floor: nothing a person reads is under 12px, at any width ----------
   Labels keep their weight and em-based tracking. The label and keyboard-hint sizes live in the type block above;
   this lifts them without touching it. Avatar monograms are glyphs inside a planet and keep their size. */
.eyebrow,.kbd{font-size:12px}

/* ---------- touch (DESIGN 0 #15): phones, tablets, landscape phones, any coarse pointer ----------
   Every control answers a 44px fingertip. Controls drawn smaller keep their look and carry an invisible hit
   area: a ::before centred on them, at least 44px each way. Groups of small controls are spaced so those areas
   never overlap. Inline citations keep their 22px chip inside the text line and take the same invisible 44px area. */
@media (max-width:760px),(pointer:coarse){
  :where(.btn,.chip,.linkbtn,.iconbtn,.pill,.kbdhint,.toggle,.seg button,.pop-x,.a-actions button,.a-head .who,.title .chatid,.audio .play,
    .p-link,.p-mv .iconbtn,.rcpt-b,.vn-undo,.a-stopped button,.toast-act,.attchip button,.banner button,.tobottom,.cite){position:relative}
  :where(.btn,.chip,.linkbtn,.iconbtn,.pill,.kbdhint,.toggle,.seg button,.pop-x,.a-actions button,.a-head .who,.title .chatid,.audio .play,
    .p-link,.p-mv .iconbtn,.rcpt-b,.vn-undo,.a-stopped button,.toast-act,.attchip button,.banner button,.tobottom,.cite)::before{
    content:"";position:absolute;top:min(0px,calc(50% - 22px));bottom:min(0px,calc(50% - 22px));left:min(0px,calc(50% - 22px));right:min(0px,calc(50% - 22px))}
  /* touch sizes: buttons at the platform's 44, small ones never under 36 with the hit area making up the rest */
  .btn{height:44px}
  .btn.sm{height:36px}
  .btn.lg{height:48px}
  .chip{height:38px}
  .chips .chip,.p-chips .chip{height:36px}
  .chips,.p-chips{row-gap:8px}
  /* the action row sits a little lower, so a citation on the answer's last line keeps its own hit area */
  .a-actions{row-gap:8px;margin-top:6px}
  .a-actions button{height:36px}
  .p-mv{gap:4px}
  .p-mv .iconbtn{width:40px;height:40px}
  .seg button{height:36px}
  /* a search field is one target, edge to edge, not a 23px line of text inside a 46px box */
  .search input{align-self:stretch}
  .pal-in{padding-top:0;padding-bottom:0;min-height:58px}
  .pal-in input{align-self:stretch}
  /* keyboard hints mean nothing to a thumb */
  .pal-foot,.pal-in .kbd,.search .kbd{display:none}
  /* a lone link between blocks (Read the transcript) keeps its hit area clear of the action row under it */
  .a>.linkbtn{margin:8px 0}
  .pal-it{min-height:48px}
  /* key-value rows that carry an inline Edit or Change link sit 44px apart, so two links never share a hit area */
  .kv{padding-top:12px;padding-bottom:12px}
}

/* ---------- phone widths ---------- */
@media (max-width:760px){
  /* setting rows: short controls (toggle, tag, small button) stay on the label's line; a segmented choice
     takes its own full-width line under the label, split evenly like a native segmented control */
  .setrow .body{flex-basis:0%}
  .setrow>.seg{flex:1 1 100%;display:flex}
  .setrow>.seg>button{flex:1 1 auto;padding:0 6px;text-align:center;white-space:nowrap}
  .greet,.brief .greet{font-size:29px}
  .page-head .display{font-size:30px}
  /* top bar: 44px controls. The title takes whatever the controls leave (never a fixed half), so the right
     cluster never slides off the bar; titles carry short phone copy where the long form would clip */
  .d .app{--topPad:80px}
  .topbar{height:68px;padding:0 12px;gap:8px}
  .topbar .tl{gap:8px;flex:1 1 auto;min-width:0}
  .topbar .tr{gap:4px;flex:0 0 auto}
  .topbar .pill{padding:0 12px}
  .topbar .pill .i,.topbar .pill .pl,.kbdhint{display:none}
  /* subtitles show on phones only where a screen marks them as carrying meaning (.ts-keep: a pinned Twin's
     course, a filter, a search, incognito); decorative ones give their line back to the title */
  .topbar .title .ts:not(.ts-keep){display:none}
  .screen{padding:76px 16px 60px}
  .thread-screen .scroll{padding:84px 16px calc(var(--dockH) + 30px);scroll-padding-top:84px}
  #app.dock-up .thread-screen .scroll{padding-bottom:calc(var(--dockReach, var(--dockH)) + 30px)}
  .d .dock{padding:0 12px 12px}
  .c-hint{display:none}
  /* section heads: the label keeps its line, the note beside it drops under it when there is no room */
  .sec-head{flex-wrap:wrap;row-gap:2px}
  .sec-head>.eyebrow{white-space:nowrap}
  /* topic bands: the name and its state share a line, the bar runs full width under them, so a long topic
     ("Thermochemistry") never runs into its bar */
  .band{grid-template-columns:minmax(0,1fr) auto;row-gap:6px;column-gap:12px}
  .band .bar{grid-column:1/-1;grid-row:2}
  .gapnote{padding-left:0;margin-top:-2px}
  /* thread: the answer's byline wraps rather than clipping what it says about the source */
  .a-head .meta{white-space:normal;line-height:1.35}
  /* action rows (the founder's reference): the primary and the secondary share a line at equal widths, a quiet
     third ("Not now", "Cancel") takes its own line, centred, and every one of them is 44px. A long label keeps
     its width and its partner takes the rest; a third real button wraps to a full-width line */
  :is(.p-acts,.r-acts,.fr-acts,.slab .acts,.co-acts){display:flex;flex-wrap:wrap;gap:8px}
  :is(.p-acts,.r-acts,.fr-acts,.slab .acts,.co-acts)>.btn{flex:1 1 0;padding:0 14px}
  :is(.p-acts,.r-acts,.fr-acts,.slab .acts,.co-acts)>.btn:not(.lg){height:44px}
  :is(.p-acts,.r-acts,.fr-acts,.slab .acts,.co-acts)>.btn.text{flex:1 0 100%}
  .r-line .btn{height:36px}
  /* the side panel becomes a sheet that fits the screen (B19) */
  .sidep{top:76px;left:8px;right:8px;bottom:8px;width:auto;border-radius:20px}
  .sp-body{padding:18px 18px calc(26px + env(safe-area-inset-bottom,0px))}
  .smenu{width:min(360px,calc(100vw - 24px))}
  /* modals rise from the bottom as sheets, like the popovers (shell.css): full width, a grabber, the thumb's reach */
  .modal-wrap{padding:0;align-items:flex-end}
  .modal,.modal.lg{width:100%;max-height:calc(100vh - 24px);max-height:calc(100dvh - 24px - env(safe-area-inset-top,0px));
    border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:0;animation:shSheetIn .46s var(--ease-soft) both}
  .modal-wrap.out .modal{animation:shSheetOut .18s var(--ease-in) forwards}
  .modal::before{content:"";position:absolute;top:8px;left:50%;width:36px;height:4px;margin-left:-18px;border-radius:2px;background:var(--fg-4);opacity:.6;pointer-events:none}
  .modal .sh-head{padding:22px 12px 10px 20px}
  .modal .sh-body{padding:6px 20px calc(22px + env(safe-area-inset-bottom,0px))}
  /* the palette sits at the top, clear of the keyboard, and gives its list the rest of the screen */
  .palette{padding:8px 8px 0}
  .pal{width:100%}
  .pal-list{max-height:calc(100vh - 110px);max-height:calc(100dvh - 110px)}
  .pal-it .t{white-space:normal;line-height:1.35}
  /* a Twin's numbers: a worded value ("2 days ago") wraps inside its tile instead of clipping */
  .tstats{gap:6px}
  .tstats>div{padding:11px 10px 10px}
  .tstats b.sm{white-space:normal;overflow:visible;line-height:1.35;padding-top:2px}
  .toast{top:74px;max-width:calc(100vw - 24px)}
}
/* phones: the page glyph (logo tile, icon square, a Twin's planet) gives way before the title does */
@media (max-width:480px){
  .topbar .title :is(.tile,.iconsq,.av){display:none}
  .title .chatid{gap:0}
}
/* phone landscape and any short window: a slimmer bar, and every sheet, panel and list fits the height */
@media (max-height:520px) and (orientation:landscape){
  .d .app{--topPad:54px}
  .topbar{height:52px;padding:0 16px}
  .topbar .title .ts{line-height:1.2}
  .screen{padding-top:56px;padding-bottom:24px}
  .thread-screen .scroll{padding-top:58px;scroll-padding-top:58px;padding-bottom:calc(var(--dockH) + 12px)}
  #app.dock-up .thread-screen .scroll{padding-bottom:calc(var(--dockReach, var(--dockH)) + 12px)}
  .sidep{top:56px;bottom:8px}
  .greet,.brief .greet{font-size:30px}
  .page-head .display{font-size:28px}
  .modal-wrap{padding:8px}
  .modal{max-height:calc(100vh - 16px);max-height:calc(100dvh - 16px)}
  .modal .sh-head{padding-top:14px}
  .palette{padding-top:8px}
  .pal-list{max-height:calc(100vh - 96px);max-height:calc(100dvh - 96px)}
  .d .drawer{top:8px;bottom:8px}
  .toast{top:58px}
}

/* ---------- fallbacks: no backdrop-filter, or the viewer asked for less transparency ---------- */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .glass,.glass.dense,.glass.chip,.d .drawer,.sidep,.pop,.smenu,.modal,.pal,.toast,.tobottom,.composer,.composer .rec{background:var(--surface)}
  .topbar .iconbtn,.topbar .pill,.topbar .kbdhint{background:var(--surface)}
  .topbar-edge{background:var(--bg);-webkit-mask-image:none;mask-image:none;height:100%;box-shadow:0 1px 0 var(--line)}
  .d .dock::before{-webkit-mask-image:none;mask-image:none}
  .pop .plan:not(.on):not([aria-checked="true"]),.pop .pack:not(.on):not([aria-checked="true"]),.modal .plan:not(.on):not([aria-checked="true"]){background:var(--surface)}
  .pop .card.flat{background:var(--sunken)}
  :root .d .app .drawer{background:var(--surface)}   /* outranks the dark-only drawer smoke */
}
@media (prefers-reduced-transparency:reduce){
  .glass,.glass.dense,.glass.chip,.d .drawer,.sidep,.pop,.smenu,.modal,.pal,.toast,.tobottom,.composer,
  .topbar .iconbtn,.topbar .pill,.topbar .kbdhint{background:var(--surface);-webkit-backdrop-filter:none;backdrop-filter:none}
  .composer .rec{background:var(--surface)}
  .topbar-edge{background:var(--bg);-webkit-backdrop-filter:none;backdrop-filter:none;-webkit-mask-image:none;mask-image:none;height:100%;box-shadow:0 1px 0 var(--line)}
  .d .dock::before,.d .d-scrim,.modal-scrim,.pal-scrim{-webkit-backdrop-filter:none;backdrop-filter:none}
  .d .dock::before{-webkit-mask-image:none;mask-image:none}
  .pop .plan:not(.on):not([aria-checked="true"]),.pop .pack:not(.on):not([aria-checked="true"]),.modal .plan:not(.on):not([aria-checked="true"]){background:var(--surface)}
  .pop .card.flat{background:var(--sunken)}
  .d .app::before,.d .app::after{display:none}
  :root .d .app .drawer{background:var(--surface)}
}

/* ============================================================
   Colour: the accent a viewer picks in Settings, Appearance (docs: DESIGN.md 14).
   Graphite is the default and sets no attribute; every other colour is <html data-colour="...">, remembered on
   this device like the theme (engine.js V.setColour; the head scripts apply it before the first paint).
   A colour recolours actions, links, focus, selection, soft highlights and charts. The Twin planets keep their
   own tones, and status colours (amber warn, red danger) stay as they are.
   Light values here, dark values in the @dark block (build.mjs mirrors it for an OS-dark viewer). Every pair is
   checked for contrast in tests/colours.test.js; the swatches in engine.js V.COLOURS use the same shades.
   ============================================================ */
:root[data-colour="vidya"]{--accent:#0C6170;--on-accent:#FFFFFF;--accent-text:#0C6170;--accent-mid:#1B9486;--accent-strong:#0C6170;--accent-soft:#DBF5F0;--btn:#0C6170;--on-btn:#FFFFFF;--focus:#0C6170;--sel:rgba(27,148,134,.22);--bar-strong:linear-gradient(180deg,#1B9486 0%,#0C6170 100%)}
:root[data-colour="blue"]{--accent:#3446A8;--on-accent:#FFFFFF;--accent-text:#3446A8;--accent-mid:#6A7DD6;--accent-strong:#3446A8;--accent-soft:#EEF2FF;--btn:#3446A8;--on-btn:#FFFFFF;--focus:#3446A8;--sel:rgba(106,125,214,.22);--bar-strong:linear-gradient(180deg,#6A7DD6 0%,#3446A8 100%)}
:root[data-colour="sky"]{--accent:#0B6594;--on-accent:#FFFFFF;--accent-text:#0B6594;--accent-mid:#3E93C4;--accent-strong:#0B6594;--accent-soft:#EAF5FC;--btn:#0B6594;--on-btn:#FFFFFF;--focus:#0B6594;--sel:rgba(62,147,196,.22);--bar-strong:linear-gradient(180deg,#3E93C4 0%,#0B6594 100%)}
:root[data-colour="lilac"]{--accent:#5B3A9E;--on-accent:#FFFFFF;--accent-text:#5B3A9E;--accent-mid:#9276D8;--accent-strong:#5B3A9E;--accent-soft:#F5EFFF;--btn:#5B3A9E;--on-btn:#FFFFFF;--focus:#5B3A9E;--sel:rgba(146,118,216,.22);--bar-strong:linear-gradient(180deg,#9276D8 0%,#5B3A9E 100%)}
:root[data-colour="plum"]{--accent:#87307A;--on-accent:#FFFFFF;--accent-text:#87307A;--accent-mid:#B8609F;--accent-strong:#87307A;--accent-soft:#FBEFF8;--btn:#87307A;--on-btn:#FFFFFF;--focus:#87307A;--sel:rgba(184,96,159,.22);--bar-strong:linear-gradient(180deg,#B8609F 0%,#87307A 100%)}
:root[data-colour="rose"]{--accent:#A3345A;--on-accent:#FFFFFF;--accent-text:#A3345A;--accent-mid:#C9708C;--accent-strong:#A3345A;--accent-soft:#FFF0F4;--btn:#A3345A;--on-btn:#FFFFFF;--focus:#A3345A;--sel:rgba(201,112,140,.22);--bar-strong:linear-gradient(180deg,#C9708C 0%,#A3345A 100%)}
:root[data-colour="coral"]{--accent:#A83F27;--on-accent:#FFFFFF;--accent-text:#A83F27;--accent-mid:#D9745A;--accent-strong:#A83F27;--accent-soft:#FFF0EB;--btn:#A83F27;--on-btn:#FFFFFF;--focus:#A83F27;--sel:rgba(217,116,90,.22);--bar-strong:linear-gradient(180deg,#D9745A 0%,#A83F27 100%)}
:root[data-colour="amber"]{--accent:#835510;--on-accent:#FFFFFF;--accent-text:#835510;--accent-mid:#B8863E;--accent-strong:#835510;--accent-soft:#FFF5E3;--btn:#835510;--on-btn:#FFFFFF;--focus:#835510;--sel:rgba(184,134,62,.22);--bar-strong:linear-gradient(180deg,#B8863E 0%,#835510 100%)}

/*@dark-begin*/
:root[data-theme="dark"][data-colour="vidya"]{--accent:#A4E5E0;--on-accent:#0B0C0E;--accent-text:#A4E5E0;--accent-mid:#37BEB0;--accent-strong:#A4E5E0;--accent-soft:rgba(55,190,176,.14);--btn:#A4E5E0;--on-btn:#0B0C0E;--focus:#A4E5E0;--sel:rgba(55,190,176,.30);--bar-strong:linear-gradient(180deg,#A4E5E0 0%,#37BEB0 100%)}
:root[data-theme="dark"][data-colour="blue"]{--accent:#AAB9EE;--on-accent:#0B0C0E;--accent-text:#AAB9EE;--accent-mid:#8EA2F0;--accent-strong:#AAB9EE;--accent-soft:rgba(142,162,240,.14);--btn:#AAB9EE;--on-btn:#0B0C0E;--focus:#AAB9EE;--sel:rgba(142,162,240,.30);--bar-strong:linear-gradient(180deg,#AAB9EE 0%,#8EA2F0 100%)}
:root[data-theme="dark"][data-colour="sky"]{--accent:#9FD2F0;--on-accent:#0B0C0E;--accent-text:#9FD2F0;--accent-mid:#6DB9E6;--accent-strong:#9FD2F0;--accent-soft:rgba(109,185,230,.14);--btn:#9FD2F0;--on-btn:#0B0C0E;--focus:#9FD2F0;--sel:rgba(109,185,230,.30);--bar-strong:linear-gradient(180deg,#9FD2F0 0%,#6DB9E6 100%)}
:root[data-theme="dark"][data-colour="lilac"]{--accent:#C5AFF1;--on-accent:#0B0C0E;--accent-text:#C5AFF1;--accent-mid:#B39AF0;--accent-strong:#C5AFF1;--accent-soft:rgba(179,154,240,.14);--btn:#C5AFF1;--on-btn:#0B0C0E;--focus:#C5AFF1;--sel:rgba(179,154,240,.30);--bar-strong:linear-gradient(180deg,#C5AFF1 0%,#B39AF0 100%)}
:root[data-theme="dark"][data-colour="plum"]{--accent:#E7A9DD;--on-accent:#0B0C0E;--accent-text:#E7A9DD;--accent-mid:#D98ACD;--accent-strong:#E7A9DD;--accent-soft:rgba(217,138,205,.14);--btn:#E7A9DD;--on-btn:#0B0C0E;--focus:#E7A9DD;--sel:rgba(217,138,205,.30);--bar-strong:linear-gradient(180deg,#E7A9DD 0%,#D98ACD 100%)}
:root[data-theme="dark"][data-colour="rose"]{--accent:#EFB6C6;--on-accent:#0B0C0E;--accent-text:#EFB6C6;--accent-mid:#EE9AB0;--accent-strong:#EFB6C6;--accent-soft:rgba(238,154,176,.14);--btn:#EFB6C6;--on-btn:#0B0C0E;--focus:#EFB6C6;--sel:rgba(238,154,176,.30);--bar-strong:linear-gradient(180deg,#EFB6C6 0%,#EE9AB0 100%)}
:root[data-theme="dark"][data-colour="coral"]{--accent:#F4A58E;--on-accent:#0B0C0E;--accent-text:#F4A58E;--accent-mid:#EE8E72;--accent-strong:#F4A58E;--accent-soft:rgba(238,142,114,.14);--btn:#F4A58E;--on-btn:#0B0C0E;--focus:#F4A58E;--sel:rgba(238,142,114,.30);--bar-strong:linear-gradient(180deg,#F4A58E 0%,#EE8E72 100%)}
:root[data-theme="dark"][data-colour="amber"]{--accent:#E9CB95;--on-accent:#0B0C0E;--accent-text:#E9CB95;--accent-mid:#E2B669;--accent-strong:#E9CB95;--accent-soft:rgba(226,182,105,.14);--btn:#E9CB95;--on-btn:#0B0C0E;--focus:#E9CB95;--sel:rgba(226,182,105,.30);--bar-strong:linear-gradient(180deg,#E9CB95 0%,#E2B669 100%)}
/*@dark-end*/
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"])[data-colour="vidya"]{--accent:#A4E5E0;--on-accent:#0B0C0E;--accent-text:#A4E5E0;--accent-mid:#37BEB0;--accent-strong:#A4E5E0;--accent-soft:rgba(55,190,176,.14);--btn:#A4E5E0;--on-btn:#0B0C0E;--focus:#A4E5E0;--sel:rgba(55,190,176,.30);--bar-strong:linear-gradient(180deg,#A4E5E0 0%,#37BEB0 100%)}
:root:not([data-theme="light"])[data-colour="blue"]{--accent:#AAB9EE;--on-accent:#0B0C0E;--accent-text:#AAB9EE;--accent-mid:#8EA2F0;--accent-strong:#AAB9EE;--accent-soft:rgba(142,162,240,.14);--btn:#AAB9EE;--on-btn:#0B0C0E;--focus:#AAB9EE;--sel:rgba(142,162,240,.30);--bar-strong:linear-gradient(180deg,#AAB9EE 0%,#8EA2F0 100%)}
:root:not([data-theme="light"])[data-colour="sky"]{--accent:#9FD2F0;--on-accent:#0B0C0E;--accent-text:#9FD2F0;--accent-mid:#6DB9E6;--accent-strong:#9FD2F0;--accent-soft:rgba(109,185,230,.14);--btn:#9FD2F0;--on-btn:#0B0C0E;--focus:#9FD2F0;--sel:rgba(109,185,230,.30);--bar-strong:linear-gradient(180deg,#9FD2F0 0%,#6DB9E6 100%)}
:root:not([data-theme="light"])[data-colour="lilac"]{--accent:#C5AFF1;--on-accent:#0B0C0E;--accent-text:#C5AFF1;--accent-mid:#B39AF0;--accent-strong:#C5AFF1;--accent-soft:rgba(179,154,240,.14);--btn:#C5AFF1;--on-btn:#0B0C0E;--focus:#C5AFF1;--sel:rgba(179,154,240,.30);--bar-strong:linear-gradient(180deg,#C5AFF1 0%,#B39AF0 100%)}
:root:not([data-theme="light"])[data-colour="plum"]{--accent:#E7A9DD;--on-accent:#0B0C0E;--accent-text:#E7A9DD;--accent-mid:#D98ACD;--accent-strong:#E7A9DD;--accent-soft:rgba(217,138,205,.14);--btn:#E7A9DD;--on-btn:#0B0C0E;--focus:#E7A9DD;--sel:rgba(217,138,205,.30);--bar-strong:linear-gradient(180deg,#E7A9DD 0%,#D98ACD 100%)}
:root:not([data-theme="light"])[data-colour="rose"]{--accent:#EFB6C6;--on-accent:#0B0C0E;--accent-text:#EFB6C6;--accent-mid:#EE9AB0;--accent-strong:#EFB6C6;--accent-soft:rgba(238,154,176,.14);--btn:#EFB6C6;--on-btn:#0B0C0E;--focus:#EFB6C6;--sel:rgba(238,154,176,.30);--bar-strong:linear-gradient(180deg,#EFB6C6 0%,#EE9AB0 100%)}
:root:not([data-theme="light"])[data-colour="coral"]{--accent:#F4A58E;--on-accent:#0B0C0E;--accent-text:#F4A58E;--accent-mid:#EE8E72;--accent-strong:#F4A58E;--accent-soft:rgba(238,142,114,.14);--btn:#F4A58E;--on-btn:#0B0C0E;--focus:#F4A58E;--sel:rgba(238,142,114,.30);--bar-strong:linear-gradient(180deg,#F4A58E 0%,#EE8E72 100%)}
:root:not([data-theme="light"])[data-colour="amber"]{--accent:#E9CB95;--on-accent:#0B0C0E;--accent-text:#E9CB95;--accent-mid:#E2B669;--accent-strong:#E9CB95;--accent-soft:rgba(226,182,105,.14);--btn:#E9CB95;--on-btn:#0B0C0E;--focus:#E9CB95;--sel:rgba(226,182,105,.30);--bar-strong:linear-gradient(180deg,#E9CB95 0%,#E2B669 100%)}
}

/* the picker: one pill per colour, a swatch dot and its name; the chosen one wears an ink ring */
.swatches{flex:1 1 100%;display:flex;flex-wrap:wrap;gap:8px}
.swatch{display:inline-flex;align-items:center;gap:8px;height:34px;padding:0 13px 0 7px;border-radius:999px;background:var(--sunken);
  box-shadow:inset 0 0 0 1px var(--line);font-size:12.5px;font-weight:500;color:var(--fg-2);cursor:pointer;
  transition:box-shadow .2s var(--ease-out),color .2s var(--ease-out)}
.swatch:hover{color:var(--fg)}
.swatch .sw{width:20px;height:20px;border-radius:50%;background:var(--sw);box-shadow:inset 0 0 0 1px rgba(0,0,0,.14);flex:0 0 auto}
.swatch.on{color:var(--fg);box-shadow:inset 0 0 0 1.5px var(--fg)}
.swatch:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
@media (pointer:coarse){.swatch{height:40px}}

/* Engine-owned styles: thread and renderer states, toast action slot, stop and continue, attached replies.
   Tokens only (DESIGN §4). Existing core selectors are never restyled bare; everything here hangs off an engine class. */

/* ---------- F2 · toast action slot (the toast glass itself is core) ---------- */
.toast .toast-msg{flex:1 1 auto;min-width:0}
.toast.has-act.on{pointer-events:auto}
.toast-act{flex:0 0 auto;height:30px;margin:-6px -8px -6px 4px;padding:0 13px;border-radius:999px;font:inherit;font-size:13px;font-weight:600;color:inherit;
  background:color-mix(in srgb,currentColor 9%,transparent);box-shadow:inset 0 0 0 1px color-mix(in srgb,currentColor 12%,transparent);
  transition:background-color .16s var(--ease-out),transform .16s var(--ease-out)}
.toast-act:hover{background:color-mix(in srgb,currentColor 15%,transparent)}
.toast-act:active{transform:scale(.97)}

/* ---------- user messages: moved caption, voice note sending with Undo (U15, U16) ---------- */
.u-col{display:flex;flex-direction:column;align-items:flex-end;gap:6px;width:100%;min-width:0}
.moved-cap{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:500;color:var(--fg-3)}
.moved-cap .i{width:14px;height:14px}
.vn-sending{display:inline-flex;align-items:center;gap:7px;min-height:28px;font-size:12px;color:var(--fg-3);animation:fadeIn .3s var(--ease-out) both}
.vn-sending .spinner{width:12px;height:12px;border-width:1.5px}
.vn-undo{height:28px;padding:0 10px;margin-left:-4px;border-radius:999px;font-size:12px;font-weight:600;color:var(--fg);
  transition:background-color .16s var(--ease-out)}
.vn-undo:hover{background:var(--accent-soft)}
.vn-undo[disabled]{color:var(--fg-3)}

/* ---------- routing receipt (U21) ---------- */
.a-head.has-rcpt{flex-wrap:wrap;row-gap:1px}
.rcpt{flex-basis:100%;display:flex;align-items:center;flex-wrap:wrap;gap:0 5px;padding-left:33px;font-size:12px;color:var(--fg-3);min-width:0}
.rcpt-b{display:inline-flex;align-items:center;gap:1px;height:22px;padding:0 5px 0 6px;margin-left:-6px;border-radius:7px;font-size:12px;font-weight:600;color:var(--fg-2);
  transition:background-color .16s var(--ease-out),color .16s var(--ease-out)}
.rcpt-b:hover{background:var(--accent-soft);color:var(--fg)}
.rcpt-b .i{width:14px;height:14px}

/* ---------- replies attached under a message (F8) ---------- */
.msg.attached{position:relative;padding-left:18px;margin-top:-4px}
.msg.attached::before{content:"";position:absolute;left:3px;top:3px;bottom:3px;width:2px;border-radius:2px;background:var(--line-2)}

/* ---------- stop and continue (U34) ---------- */
.a-stopped{display:flex;align-items:center;gap:7px;font-size:12.5px;color:var(--fg-3);animation:fadeIn .25s var(--ease-out) both}
.a-stopped .i{width:12px;height:12px;color:var(--fg-3)}
.a-stopped button{height:28px;padding:0 10px;margin-left:-4px;border-radius:999px;font-size:12.5px;font-weight:600;color:var(--fg);
  transition:background-color .16s var(--ease-out)}
.a-stopped button:hover{background:var(--accent-soft)}

/* ---------- search hits (U17): amber means "look at this" ---------- */
mark.hit{background:var(--amber-soft);color:var(--fg);border-radius:4px;padding:0 1px;box-shadow:inset 0 -1.5px 0 var(--amber)}

/* ---------- proposal states (U04, U05) ---------- */
.p-lead,.p-trail{display:inline-flex;align-items:center;gap:8px;min-width:0}
.p-trail{gap:12px}
.p-tag{display:inline-flex;align-items:center;gap:4px;height:20px;padding:0 8px;border-radius:999px;background:var(--sunken);color:var(--fg-2);
  font-size:12px;font-weight:600;letter-spacing:0;text-transform:none;box-shadow:inset 0 0 0 1px var(--line)}
.p-tag .i{width:12px;height:12px}
.p-link{display:inline-flex;align-items:center;gap:4px;font-size:12.5px;font-weight:600;color:var(--fg);border-radius:6px;
  text-decoration:underline;text-decoration-color:color-mix(in srgb,currentColor 30%,transparent);text-underline-offset:3px}
.p-link:hover{text-decoration-color:currentColor}
.p-link .i{width:14px;height:14px}
.p-body{flex:1;min-width:0}
.p-t{font-size:14px;font-weight:600;line-height:1.35;color:var(--fg)}
.p-s{margin-top:2px;font-size:12px;line-height:1.4;color:var(--fg-3)}
.p-mv{display:inline-flex;gap:2px;flex:0 0 auto}
.p-mv .iconbtn{width:32px;height:32px;background:transparent;box-shadow:none;border-color:transparent;color:var(--fg-2)}
.p-mv .iconbtn:hover{background:var(--accent-soft);color:var(--fg)}
.p-mv .iconbtn[disabled]{opacity:.32;pointer-events:none}
[data-prop] .p-item[tabindex]{border-radius:10px;outline-offset:3px}
[data-prop] .p-item[tabindex]:focus-visible{outline:2px solid var(--focus)}
.p-pick{display:flex;flex-direction:column;gap:8px;padding:0 0 12px 48px;animation:fadeIn .25s var(--ease-out) both}
.p-chips{display:flex;flex-wrap:wrap;gap:6px}
.p-chips .chip{height:32px;padding:0 12px;font-size:12.5px}
.p-editbox{display:flex;flex-direction:column;gap:8px;margin-top:8px}
.input.p-edit{min-height:108px;max-height:340px;resize:vertical;font-size:14px;line-height:1.6;field-sizing:content}
.p-editbar{display:flex;align-items:center;gap:6px}
.p-sp{flex:1}
.p-count{font-variant-numeric:tabular-nums}
.ph{display:inline;padding:0 4px;border-radius:5px;background:var(--amber-soft);color:var(--amber-ink);font-weight:600;
  box-shadow:inset 0 0 0 1px color-mix(in srgb,var(--amber) 40%,transparent);-webkit-box-decoration-break:clone;box-decoration-break:clone}
.p-hint{display:flex;align-items:center;gap:6px;margin-top:10px;font-size:12.5px;color:var(--amber-ink)}
.p-hint .i{width:14px;height:14px}
.p-dismissed{display:flex;align-items:center;gap:8px;min-height:32px;font-size:13px;color:var(--fg-3);animation:fadeIn .3s var(--ease-out) both}
.p-dismissed > .i{width:14px;height:14px}
@media (max-width:760px){.p-pick{padding-left:0}}

/* ---------- quiz picked state (U04) ---------- */
[data-quiz] .opt.wrong:not(.fresh){animation:none}
[data-quiz] .opt[aria-disabled="true"]{cursor:default}
[data-quiz] .verdict{color:var(--fg);font-weight:600}
.qz-more{margin-top:12px}

/* ---------- refusal states (U03, U15, U24) ---------- */
.r-ic{display:inline-flex;color:var(--fg-2)}
.r-asked{display:flex;flex-direction:column;gap:10px}
.r-asked .r-note{margin:0;font-size:13.5px;line-height:1.55;color:var(--fg-2)}
.r-nl{display:block;margin-bottom:2px;font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3)}
.r-foot{display:flex;align-items:center;justify-content:space-between;gap:6px 12px;flex-wrap:wrap}
.r-shield{display:inline-flex;align-items:flex-start;gap:7px;min-width:0;font-size:12.5px;line-height:1.45;color:var(--fg-2)}
.r-shield .i{width:15px;height:15px;margin-top:1px;flex:0 0 auto}
.refusal.r-line{display:flex;align-items:center;gap:8px;padding:10px 12px 10px 14px;font-size:13.5px;color:var(--fg-2)}
.r-line > .i{width:15px;height:15px;color:var(--fg-3)}
.r-line .btn{margin-left:auto}

/* ---------- care ---------- */
.care-t{font-size:13.5px;line-height:1.6;color:var(--fg-2)}

/* ---------- incognito (engine: V.setIncognito) ----------
   The frame is a bezel in the opposite ink: near-black on light, near-white on dark (--btn is exactly #0B0C0E / #F4F4F5,
   so auto, forced and live theme switches all follow with no script). One fixed layer, above everything, never hit-testable.
   Its outer spread fills the gutter to the screen edge, so the page reads as a lit screen set inside a device. */
.incog-frame{--inc-ink:var(--btn);position:fixed;inset:6px;z-index:900;pointer-events:none;border-radius:22px;
  box-shadow:0 0 0 48px var(--inc-ink),inset 0 0 0 .5px color-mix(in srgb,var(--inc-ink) 40%,transparent),inset 0 0 22px -12px color-mix(in srgb,var(--inc-ink) 34%,transparent);
  opacity:0;visibility:hidden;transform:scale(1.012);
  transition:opacity .18s var(--ease-in),transform .18s var(--ease-in),visibility 0s linear .18s}
html.is-incognito .incog-frame{opacity:1;visibility:visible;transform:none;
  transition:opacity .24s var(--ease-out),transform .24s var(--ease-out),visibility 0s}
@media (max-width:760px){.incog-frame{inset:4px;border-radius:18px}}
/* scrollbars at the screen edge would slide under the bezel: same gutter (no layout shift), the thumb moves inboard
   and stays clear of the rounded corners */
html.is-incognito :is(.screen,.thread-screen .scroll)::-webkit-scrollbar-thumb{border-width:3px 7px 3px 0}
html.is-incognito :is(.screen,.thread-screen .scroll)::-webkit-scrollbar-track{margin:24px 0}

/* the marker where the unsaved stretch starts */
.msg.sys{animation:rise .46s var(--ease-out) both}
.incog-div{display:flex;flex-direction:column;align-items:center;gap:8px;margin:4px 0 -2px;text-align:center}
.incog-row{display:flex;align-items:center;gap:14px;width:100%}
.incog-rule{flex:1;height:1px;background:linear-gradient(90deg,transparent,var(--line-2))}
.incog-rule:last-child{background:linear-gradient(90deg,var(--line-2),transparent)}
.incog-pill{display:inline-flex;align-items:center;gap:6px;flex:0 0 auto;height:26px;padding:0 12px 0 9px;border-radius:999px;
  background:var(--btn);color:var(--on-btn);font-size:12px;font-weight:600;letter-spacing:.005em;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.14),0 1px 2px rgba(0,0,0,.18)}
.incog-pill .i{width:15px;height:15px}
.incog-note{font-size:12.5px;line-height:1.4;color:var(--fg-3)}
/* forced colors drop box-shadows: the frame becomes a system-colour border so the state never disappears */
@media (forced-colors:active){
  .incog-frame{box-shadow:none;border:3px solid CanvasText}
  .incog-pill{forced-color-adjust:none;background:CanvasText;color:Canvas}
}

/* ---------- live and demo (docs/LIVE.md 1, 11) ----------
   "Demo answers": one quiet pill wherever an app places it (V.demoBadge), on an answer the demo script wrote, and in the
   thinking row while the script answers. An outline, never a colour: it informs, it does not alarm. */
.demo-pill{display:inline-flex;align-items:center;flex:0 0 auto;height:18px;padding:0 7px;border-radius:999px;
  font-size:11px;font-weight:600;line-height:1;letter-spacing:.01em;white-space:nowrap;color:var(--fg-3);
  background:transparent;box-shadow:inset 0 0 0 1px var(--line-2)}
.a-head .demo-pill{margin-left:-2px}
.thinking .demo-pill{margin-left:2px}
@media (forced-colors:active){.demo-pill{border:1px solid CanvasText;box-shadow:none}}

/* a live question that failed: a calm card with Try again (V.renderers.liveerr) */
.liveerr{display:flex;align-items:center;flex-wrap:wrap;gap:10px 12px;padding:12px 12px 12px 14px;border-radius:18px;
  background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line)}
.liveerr-ic{display:inline-flex;flex:0 0 auto;color:var(--fg-2)}
.liveerr-b{flex:1 1 220px;min-width:0}
.liveerr-t{font-size:14px;font-weight:600;line-height:1.35;color:var(--fg)}
.liveerr-s{margin-top:2px;font-size:13px;line-height:1.45;color:var(--fg-3)}
.liveerr .btn{flex:0 0 auto;margin-left:auto}

/* a Twin's photo, chosen by its professor, replaces the planet face on every avatar (V.syncTwinPhotos sets --twp-<id>) */
.av.has-photo[data-tw]{background:var(--twp) center/cover no-repeat;color:transparent;
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.18),0 2px 5px -3px rgba(0,0,0,.45)}

/* ---------- boot (V.bootWait): the shell is up, the first screen waits on who is signed in ----------
   One soft pulse of the mark where the conversation will be. No spinner and no words on screen: it lasts a moment. */
.v-boot{position:absolute;inset:0;display:grid;place-items:center;pointer-events:none;animation:vBootIn .5s .18s var(--ease-out) both}
.v-boot-mk{display:inline-flex;width:40px;height:40px;color:var(--fg-4);animation:vBootPulse 1.6s var(--ease-in-out) infinite}
.v-boot-mk .mk{width:100%;height:100%;fill:currentColor}
@keyframes vBootIn{from{opacity:0}to{opacity:1}}
@keyframes vBootPulse{0%,100%{opacity:.35;transform:scale(.96)}50%{opacity:.8;transform:scale(1)}}
@media (prefers-reduced-motion:reduce){.v-boot{animation:none}.v-boot-mk{animation:none;opacity:.6}}
/* nothing in the bars can be opened before there is something to show */
body[data-booting="1"] :is(#menuBtn,#tr){visibility:hidden}

/* ---------- attachments (V.attPrepare, VAttach): the chip in the text box, her sent bubble, an approved upload ----------
   A photo shows as itself (a small thumbnail); a file shows its icon, name and size. Solid surfaces, never glass. */
.attchip .att-th{width:24px;height:24px;border-radius:6px;object-fit:cover;flex:0 0 auto;margin-left:-5px;box-shadow:inset 0 0 0 1px var(--line)}
.attchip .att-sz{flex:0 0 auto;font-size:11.5px;font-weight:500;color:var(--fg-3)}
.attchip .i{flex:0 0 auto}
.attchip.is-reading{color:var(--fg-3)}
.attchip.is-reading .spinner{width:14px;height:14px;flex:0 0 auto}
.att-card .att-n{min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.att-card .att-sz{flex:0 0 auto;margin-left:auto;padding-left:6px;font-size:11.5px;color:var(--fg-3)}
.att-card .i{flex:0 0 auto}
.att-card.att-ph{flex-direction:column;align-items:flex-start;gap:6px;padding:6px 6px 8px;max-width:min(100%,260px)}
.att-card.att-ph .att-th{display:block;width:auto;max-width:100%;max-height:200px;border-radius:9px;object-fit:contain;background:var(--sunken)}
.att-card.att-ph .att-n{max-width:100%;padding:0 4px;font-size:12px;color:var(--fg-3)}
.p-up{display:flex;flex-direction:column;gap:6px;margin-top:12px}
.p-bar{display:block;height:4px;border-radius:9px;background:var(--sunken);overflow:hidden}
.p-bar i{display:block;height:100%;width:100%;background:var(--fg);border-radius:9px;transform-origin:left;transition:transform .35s var(--ease-out)}
.p-bar.is-indet i{width:34%;animation:vAttIndet 1.25s var(--ease-in-out) infinite}
@keyframes vAttIndet{from{transform:translateX(-100%)}to{transform:translateX(300%)}}
.p-hint.p-err{color:var(--clay-ink)}
.dock.drop .vd-typerow{border-color:var(--fg-3);box-shadow:0 0 0 4px var(--accent-soft),inset 0 1px 0 var(--g-hi),var(--g-shadow)}
@media (prefers-reduced-motion:reduce){.p-bar i{transition:none}.p-bar.is-indet i{animation:none;width:100%;opacity:.35}}
/* ---------- email: "Verify your school email" (V.email.sheet). One real input drawn as six cells, so paste and
   one-time-code autofill just work and a screen reader hears one field ---------- */
.v-vv{gap:14px}
.v-vv-sub{line-height:1.6;color:var(--fg-2);margin:0}
.v-otp{position:relative;width:100%;max-width:360px}
.v-otp-cells{display:grid;grid-template-columns:repeat(3,minmax(0,1fr)) 8px repeat(3,minmax(0,1fr));gap:7px;pointer-events:none}
.v-otp-cells .gap{align-self:center;justify-self:center;width:7px;height:2px;border-radius:2px;background:var(--line-2)}
.v-otp-cells .c{height:56px;border-radius:14px;border:1px solid var(--line-2);background:var(--surface);display:flex;align-items:center;justify-content:center;
  font-size:24px;font-weight:600;font-variant-numeric:tabular-nums;color:var(--fg);transition:border-color .15s var(--ease-out),box-shadow .15s var(--ease-out)}
.v-otp:focus-within .c.on{border-color:var(--fg-3);box-shadow:0 0 0 4px var(--accent-soft)}
.v-otp:focus-within .c.on:empty::after{content:"";width:2px;height:24px;border-radius:1px;background:var(--fg);animation:blink 1.05s steps(1) infinite}
.v-otp[data-invalid="true"] .c{border-color:var(--clay)}
.v-otp[data-invalid="true"] .v-otp-cells{animation:shake .3s var(--ease-out)}
.v-otp-in{position:absolute;inset:0;width:100%;height:100%;margin:0;padding:0;border:0;outline:none;background:transparent;opacity:0;font-size:16px;
  color:transparent;caret-color:transparent;-webkit-text-fill-color:transparent;cursor:text}
.v-vv-err{font-size:12.5px;line-height:1.45;font-weight:500;color:var(--clay-ink)}
.v-vv-err:empty{display:none}
.v-vv-acts{flex-wrap:wrap}
.v-vv-acts .btn{min-height:44px}
@media (max-width:560px){.v-vv-acts .btn{flex:1 1 0}.v-otp-cells .c{height:52px;font-size:22px}}
@media (prefers-reduced-motion:reduce){.v-otp:focus-within .c.on:empty::after{animation:none}}

/* Shell-owned styles: only the classes web-shell.js introduces (skip link, popover tools and
   phone sheet, palette answer rows, focus targets). The looks of .pop, .pal, .modal, .sidep,
   .drawer, .smenu and .topbar-edge are core's. */

/* skip link: the first tab stop, invisible until it holds focus */
.skip-link{position:absolute;left:12px;top:calc(env(safe-area-inset-top,0px) + 12px);z-index:600;display:inline-flex;align-items:center;height:40px;padding:0 16px;
  border-radius:999px;background:var(--btn);color:var(--on-btn);font-size:13.5px;font-weight:600;letter-spacing:-.005em;text-decoration:none;
  box-shadow:var(--shadow-2);opacity:0;transform:translateY(-8px);pointer-events:none;
  transition:opacity .2s var(--ease-out),transform .2s var(--ease-out)}
.skip-link:focus{opacity:1;transform:none;pointer-events:auto;outline:2px solid var(--focus);outline-offset:3px}

/* headings and screens that take focus from script: they are not controls, so no ring */
.ov-h:focus,.skip-target:focus{outline:none}

/* popover head: the caller's action, then a close button that is always there */
.pop-head .ov-h{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.pop-tools{display:flex;align-items:center;gap:6px;margin-left:auto;margin-right:-8px;flex:0 0 auto}
.pop-x{width:32px;height:32px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;color:var(--fg-3);
  transition:background-color .16s var(--ease-out),color .16s var(--ease-out),transform .16s var(--ease-out)}
.pop-x:hover{background:var(--accent-soft);color:var(--fg)}
.pop-x:active{transform:scale(.94)}

/* popovers become a bottom sheet at phone width */
.pop.as-sheet{left:0;right:0;top:auto;bottom:0;width:auto;max-width:none;max-height:92vh;max-height:92dvh;border-bottom:0;
  border-bottom-left-radius:0;border-bottom-right-radius:0;transform-origin:50% 100%;animation:shSheetIn .46s var(--ease-soft) both}
.pop.as-sheet.out{animation:shSheetOut .18s var(--ease-in) forwards}
.pop.as-sheet::before{content:"";position:absolute;top:8px;left:50%;width:36px;height:4px;margin-left:-18px;border-radius:2px;background:var(--fg-4);opacity:.6;pointer-events:none}
.pop.as-sheet .pop-head{padding-top:22px}
.pop.as-sheet .pop-body{padding-bottom:calc(20px + env(safe-area-inset-bottom,0px))}
.pop-scrim{position:absolute;inset:0;pointer-events:auto;background:var(--scrim);
  -webkit-backdrop-filter:blur(6px) saturate(120%);backdrop-filter:blur(6px) saturate(120%);animation:shFadeIn .3s var(--ease-out) both}
.pop-scrim.out{animation:shFadeOut .18s var(--ease-in) forwards}
@keyframes shSheetIn{from{transform:translateY(100%)}to{transform:none}}
@keyframes shSheetOut{to{opacity:0;transform:translateY(32px)}}
@keyframes shFadeIn{from{opacity:0}}
@keyframes shFadeOut{to{opacity:0}}

/* attachment choices in the "+" popover */
.row.att-opt{width:100%;text-align:left;padding:10px 8px;border-radius:12px}
.att-foot{margin-top:10px;padding:0 8px;font-size:12px;color:var(--fg-3)}

/* palette rows the shell adds: matched letters, two-line answers, the Ask row's price */
.pal-it .pal-hit{font-weight:650;color:var(--fg)}
.pal-it .pal-tx{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.pal-it .pal-tx .t{flex:none}
.pal-it .pal-tx .d{font-size:12.5px;line-height:1.35;color:var(--fg-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.pal-it .s{flex:0 0 auto}
.pal-cost{display:inline-flex;align-items:center;height:22px;padding:0 9px;border-radius:999px;background:var(--sunken);color:var(--fg-2);
  font-size:12px;font-weight:500;font-variant-numeric:tabular-nums;box-shadow:inset 0 0 0 1px var(--line)}
.pal-it.on .pal-cost{background:var(--surface)}

/* touch: the close button and the head's own action are fingertip-sized; the sheet's head keeps them apart */
@media (max-width:760px),(pointer:coarse){
  .pop-x{width:40px;height:40px}
  .pop-tools{gap:10px;margin-right:-6px}
  .pop-head{min-height:56px}
}

@media (prefers-reduced-motion:reduce){
  .skip-link,.pop-x{transition:none}
  .pop.as-sheet,.pop.as-sheet.out,.pop-scrim,.pop-scrim.out{animation:none}
}

/* the @-menu list scrolls once there are more Twins than fit (the menu itself carries the rim, so it never scrolls) */
.smenu .sm-list{display:flex;flex-direction:column;max-height:min(440px,calc(100vh - 300px));max-height:min(440px,calc(100dvh - 300px));overflow-y:auto;overscroll-behavior:contain;margin:0 -4px;padding:0 4px;scrollbar-width:thin}
@media (max-width:760px){.smenu .sm-list{max-height:min(380px,calc(100dvh - 260px))}}

/* ============================================================
   Vidya · Professor components: Today, the question inbox, the
   Twin manager, insights, students, earnings, verification and
   the create wizard. Obsidian: ink encodes, amber flags, red is
   danger, nothing is green. Content surfaces stay opaque.
   ============================================================ */
.screen .page.wide{max-width:1120px}
.screen.has-dock{padding-bottom:calc(var(--dockReach,var(--dockH,150px)) + 32px);scroll-padding-bottom:calc(var(--dockReach,var(--dockH,150px)) + 12px)}
.h1{font-size:26px;font-weight:600;letter-spacing:-.03em;line-height:1.2;text-wrap:balance}
.av.sq{border-radius:30%}
.av.s72.sq{border-radius:24px}
.iconsq.clay{background:var(--clay-soft);color:var(--clay-ink);box-shadow:none}
.amberink{color:var(--amber-ink)}

/* ---------- surfaces ---------- */
.panel{background:var(--surface);border:1px solid var(--line);border-radius:18px;padding:18px 20px;display:flex;flex-direction:column;gap:14px;min-width:0;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.035),0 1px 2px rgba(10,11,14,.04)}
.panel.flash{animation:flash 1.9s var(--ease-out)}
.panel-h{display:flex;align-items:flex-start;justify-content:space-between;gap:12px}
.panel-h .h3{font-size:16px;font-weight:600;letter-spacing:-.012em}
.panel-h .xs{margin-top:3px}
.calmpanel{background:var(--accent-soft);border-color:var(--line);box-shadow:none}
.tgrid{display:grid;grid-template-columns:minmax(0,1.2fr) minmax(0,1fr);gap:18px;align-items:start}
.dcol{display:flex;flex-direction:column;gap:18px;min-width:0}

/* stat tiles (Students only; Today has none) */
.stats{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:12px}
.stat-card{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-card);padding:16px 18px;display:flex;flex-direction:column;gap:6px;min-width:0;text-align:left;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.035),0 1px 2px rgba(10,11,14,.04)}
.stat-card .l{font-size:12.5px;color:var(--fg-3);font-weight:500}
.stat-card .n{font-size:34px;font-weight:350;letter-spacing:-.045em;line-height:1.05;font-variant-numeric:tabular-nums}
.stat-card .d{font-size:12px;font-weight:500;color:var(--fg-3);display:flex;align-items:center;gap:5px}
.stat-card .d.up{color:var(--fg)}

/* ---------- Today: the work first, the numbers in one line ---------- */
.today{gap:26px}
/* Needs you holds the inline approve card, so it is far taller than any one panel beside it. It spans the column;
   Stuck, Twin and Coming up stack on the right at their own heights, and both columns end flush (Needs you and
   Coming up take up the slack) instead of a half-empty Stuck panel. DOM and phone order stay Needs, Stuck, Twin, Coming up. */
.dash{display:grid;grid-template-columns:minmax(0,1.3fr) minmax(0,1fr);grid-template-rows:auto auto 1fr;gap:18px;align-items:start}
.dash>.needsp{grid-column:1;grid-row:1 / span 3;align-self:stretch}
.dash>.panel:not(.needsp){grid-column:2}
.dash>.panel:last-child{align-self:stretch}
/* nothing open: Needs you is short, so it keeps one row and Coming up moves under it in the left column */
.dash>.needsp.is-empty{grid-row:1;align-self:stretch}
.dash>.needsp.is-empty~.panel:last-child{grid-column:1;grid-row:2 / span 2}
.kpi-line{display:inline-flex;align-items:center;gap:6px;margin-top:4px;font-size:12.5px;line-height:1.45;color:var(--fg-2);text-align:left;
  text-decoration:underline;text-decoration-color:color-mix(in srgb,currentColor 28%,transparent);text-underline-offset:3px;transition:color .16s var(--ease-out),text-decoration-color .16s var(--ease-out)}
.kpi-line:hover{color:var(--fg);text-decoration-color:currentColor}
.kpi-line .i{color:var(--fg-3);flex:0 0 auto}
.needs{display:flex;flex-direction:column}
.needsp .needs{border-top:1px solid var(--line);padding-top:4px}
/* hairline separators are drawn inset, so the rounded hover never bends them */
.need{display:flex;align-items:center;gap:12px;padding:11px 8px;margin:0 -8px;text-align:left;width:calc(100% + 16px);border-radius:12px;
  background:linear-gradient(var(--line),var(--line)) 50% 0/calc(100% - 16px) 1px no-repeat;transition:background-color .15s var(--ease-out)}
.need:first-child{background-image:none}
.need:hover{background:var(--accent-soft)}
.need .body{flex:1;min-width:0;display:flex;flex-direction:column;gap:2px}
.need .t{font-size:14px;font-weight:600;line-height:1.35}
.need .s{font-size:12.5px;color:var(--fg-3)}
.need>.i{color:var(--fg-3);flex:0 0 auto}
.since{display:flex;flex-direction:column;gap:2px;padding-top:12px;border-top:1px solid var(--line)}
.since .eyebrow{margin-bottom:4px}
.since .row{padding:9px 8px;margin:0 -8px;border-top:0;border-radius:12px;text-align:left;width:calc(100% + 16px)}
.since .row>.i{color:var(--fg-3)}
.snzline{display:inline-flex;align-items:center;gap:8px;align-self:flex-start;height:32px;padding:0 10px 0 12px;border-radius:999px;font-size:12.5px;font-weight:500;color:var(--fg-2);
  background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line);transition:color .16s var(--ease-out),background-color .16s var(--ease-out)}
.snzline:hover{color:var(--fg);background:var(--accent-soft)}
.gapslab{display:flex;gap:10px;align-items:flex-start}
.gapslab>.i{flex:0 0 auto;margin-top:2px}
.gate{display:flex;align-items:center;gap:16px}
.gate .gt{font-weight:600;font-size:15px;letter-spacing:-.01em}
.gate .xs{margin-top:2px}
.gate .ring .lbl{font-size:17px}
.bar>i.amberbar{background:var(--amber)}

/* coverage columns: luminance encodes, amber flags thin weeks, "forming" is hatched so it never relies on shade alone */
.cov{height:130px}
.cov.mini{height:56px;gap:4px}
.cov .col:is(.strong,.forming,.thin,.future){width:64%;border-radius:4px 4px 1px 1px}
.cov.mini .col:is(.strong,.forming,.thin,.future){width:74%}
.cov .col.strong{background:var(--bar-strong);box-shadow:inset 0 1px 0 rgba(255,255,255,.28)}
.cov .col.forming{background:repeating-linear-gradient(135deg,var(--hatch) 0 2px,transparent 2px 5px),var(--forming)}
.cov .col.thin{background:var(--amber);box-shadow:inset 0 1px 0 rgba(255,255,255,.25)}
.cov .col.future{background:var(--raised);box-shadow:inset 0 0 0 1px var(--line-2)}
.pp .cov .wl{font-size:12px}
.legend{display:flex;flex-wrap:wrap;gap:14px;font-size:12px;color:var(--fg-3)}
.legend span{display:inline-flex;align-items:center;gap:6px}
.legend i{width:10px;height:10px;border-radius:3px;display:inline-block}
.legend i.strong{background:var(--bar-strong)}
.legend i.forming{background:repeating-linear-gradient(135deg,var(--hatch) 0 2px,transparent 2px 5px),var(--forming)}
.legend i.thin{background:var(--amber)}
.legend i.future{background:transparent;box-shadow:inset 0 0 0 1px var(--fg-4)}
:root[data-theme="dark"] .cov .col.strong,:root[data-theme="dark"] .mc.cur{box-shadow:inset 0 1px 0 rgba(255,255,255,.5)}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .cov .col.strong,:root:not([data-theme="light"]) .mc.cur{box-shadow:inset 0 1px 0 rgba(255,255,255,.5)}}

/* ---------- question inbox ---------- */
.qpage .page-head.compact .display{font-size:26px;line-height:1.15;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.qfilters{padding:0}
.qfilters .chip .i{color:currentColor;opacity:.8}
.qkeys{display:flex;flex-wrap:wrap;align-items:center;gap:6px 16px;margin-top:-8px;font-size:12px;color:var(--fg-3)}
.qkeys>span{display:inline-flex;align-items:center;gap:4px}
.qkeys .kbd{min-width:20px;text-align:center;display:inline-block}
.qkeys .linkbtn{font-size:12px;color:var(--fg-2);font-weight:500;gap:4px}
@media (pointer:coarse){.qkeys{display:none}}
.kv-keys .kv .k{color:var(--fg-2)}
.qlist{display:flex;flex-direction:column;gap:14px}
.qcard{background:var(--surface);border:1px solid var(--line);border-radius:18px;padding:18px 20px;display:flex;flex-direction:column;gap:12px;min-width:0;outline:none;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.035),0 1px 2px rgba(10,11,14,.04);animation:rise .45s var(--ease-out) both;
  transition:border-color .2s var(--ease-out),box-shadow .2s var(--ease-out)}
.qcard.static,.qpage.settled .qcard{animation:none}
.qcard.flash{animation:flash 1.9s var(--ease-out)}
.qcard.active{border-color:color-mix(in srgb,var(--fg) 34%,transparent);box-shadow:0 16px 36px -24px rgba(10,11,14,.5),0 1px 2px rgba(10,11,14,.04)}
.qcard:focus-visible{outline:2px solid var(--focus);outline-offset:3px}
/* Today's top item sits inside the "need you" panel as its first section, not as a card in a card */
.qcard.inline{border:0;border-radius:0;padding:0 0 4px;box-shadow:none;background:none;animation:none}
.qcard .qh{display:flex;align-items:center;gap:8px;flex-wrap:wrap}
.qcard .qh .spacer{flex:1 1 auto}
.qcard .qt{font-size:17px;font-weight:600;letter-spacing:-.012em;line-height:1.35;text-wrap:balance}
.qcard .asks{display:flex;flex-wrap:wrap;align-items:center;gap:6px}
.qcard .asks span{font-family:var(--serif-text);font-style:italic;font-weight:400;font-size:14.5px;line-height:1.3;letter-spacing:0;font-variation-settings:"opsz" 14;
  color:var(--fg);background:var(--sunken);border-radius:999px;padding:4px 12px;box-shadow:inset 0 0 0 1px var(--line)}
.qcard .asks .more{font-family:var(--font);font-style:normal;font-size:12.5px;color:var(--fg-3);background:transparent;box-shadow:none;padding:4px 6px;border-radius:999px}
.qcard .asks button.more{transition:color .16s var(--ease-out),background-color .16s var(--ease-out)}
.qcard .asks button.more:hover{color:var(--fg);background:var(--accent-soft)}
.qcard .chips{padding:0}
.qcard .btn[aria-disabled="true"],.cw .btn[aria-disabled="true"],.pquiz .btn[aria-disabled="true"],.testrail .btn[aria-disabled="true"],.modal .btn[data-nudge-go][aria-disabled="true"],.modal .btn[data-imp-go][aria-disabled="true"]{opacity:.42;cursor:not-allowed;filter:none}
.draft,.said{background:var(--sunken);border-radius:14px;padding:12px 14px;font-size:14.5px;line-height:1.6;color:var(--fg)}
.said{background:transparent;border:1px dashed var(--line-2)}
.draft .dl,.said .dl,.fixbox .dl{display:flex;align-items:center;gap:8px;margin-bottom:8px;font-family:var(--font);font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3)}
.draft .dl .i,.said .dl .i,.fixbox .dl .i{color:var(--fg-3)}
.draft.editing,.draft.qvoice,.fixbox{display:flex;flex-direction:column;gap:10px}
.draft.editing .dl,.draft.qvoice .dl,.fixbox .dl{margin:0}
.draft textarea,.fixbox .input{background:var(--surface);width:100%}
.draft.sending .dt,.qsent .dt{color:var(--fg-2)}
.qa{display:flex;gap:8px;flex-wrap:wrap;align-items:center}
/* the quieter actions (Reply by voice, Later): part of the row here, their own centred line on a narrow card */
.qa-t{display:contents}
.qwhy{display:flex;align-items:center;gap:6px;color:var(--fg-3)}
.qwhy .i{flex:0 0 auto}
.qcard mark{background:var(--clay-soft);color:var(--clay-ink);border-radius:5px;padding:1px 3px}
.qcard mark.fixed{background:var(--accent-soft);color:var(--fg);box-shadow:inset 0 -1.5px 0 var(--fg-3)}
/* grounding: what the reply will cite, or a warning when Vidya found nothing to cite */
.qsrc{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:12.5px;color:var(--fg-3)}
.qsrc .linkbtn{font-size:12.5px}
.qwarn{display:flex;align-items:center;gap:10px;flex-wrap:wrap;padding:10px 12px;border-radius:12px;background:var(--amber-soft);color:var(--amber-ink);font-size:13px;font-weight:500;line-height:1.45}
.qwarn>span{flex:1 1 220px}
.checkline{display:inline-flex;align-items:center;gap:8px;height:32px;padding:0 12px 0 7px;border-radius:999px;font-size:13px;font-weight:600;color:var(--fg);
  background:var(--surface);box-shadow:inset 0 0 0 1px var(--line-2);transition:box-shadow .16s var(--ease-out)}
.checkline .cb{width:18px;height:18px;border-radius:6px;box-shadow:inset 0 0 0 1.5px var(--line-2);display:inline-flex;align-items:center;justify-content:center;color:transparent;
  transition:background-color .16s var(--ease-out),color .16s var(--ease-out),box-shadow .16s var(--ease-out)}
.checkline .cb .i{stroke-width:2.6}
.checkline[aria-pressed="true"] .cb{background:var(--btn);color:var(--on-btn);box-shadow:none}
.qpol{display:flex;align-items:center;gap:10px;flex-wrap:wrap}
.qchk{padding:0 14px;border-radius:14px;background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line)}
.qchk .setrow{padding:11px 0}
.qchk .setrow.warnrow .s{color:var(--amber-ink);font-weight:500}
.qcard .setrow.qaud{padding:2px 0;border-top:0}
.cons{font-size:12px;line-height:1.45;color:var(--fg-3);margin-top:4px}
.qreach{display:flex;gap:8px;align-items:flex-start;font-size:13px;line-height:1.5;color:var(--fg-2)}
.qreach .i{flex:0 0 auto;margin-top:2px;color:var(--fg-3)}
.qwhyflag{display:flex;flex-direction:column;gap:8px}
.qwhyflag .rs{display:flex;gap:6px;flex-wrap:wrap}
.fnote,.qquote{font-family:var(--serif-text);font-style:italic;font-weight:400;font-size:15px;line-height:1.45;letter-spacing:0;font-variation-settings:"opsz" 14;color:var(--fg)}
.qquote{margin-top:2px;color:var(--fg-2)}
.fixbox{padding:14px;border-radius:14px;background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line)}
.fixbox .setrow{padding:4px 0;border-top:0}
.fixprev{display:flex;flex-direction:column;gap:4px;padding:10px 12px;border-radius:12px;background:var(--surface);box-shadow:inset 0 0 0 1px var(--line)}
.fixprev p{font-size:14px;line-height:1.5;color:var(--fg)}
/* the undo window: an aria-hidden ring drains while the real Undo button waits */
.qpend{display:flex;align-items:center;gap:12px;padding:10px 10px 10px 14px;border-radius:14px;background:var(--accent-soft);box-shadow:inset 0 0 0 1px var(--line)}
.qpend .t{flex:1;min-width:0;font-size:14px;font-weight:600;color:var(--fg)}
.qpend .n{font-weight:500;color:var(--fg-2);font-variant-numeric:tabular-nums}
.qring{width:22px;height:22px;flex:0 0 auto;transform:rotate(-90deg)}
.qring circle{fill:none;stroke-width:2.4}
.qring .tr{stroke:var(--line-2)}
.qring .va{stroke:var(--fg);stroke-linecap:round;stroke-dasharray:62.84;stroke-dashoffset:0;animation:qdrain var(--ms,8000ms) linear var(--at,0ms) forwards}
@keyframes qdrain{to{stroke-dashoffset:62.84}}
.qcard.done,.qcard.snoozed{padding:14px 18px;gap:10px;animation:none}
.qcard.inline.done,.qcard.inline.snoozed{padding:0 0 4px}
.qdone,.snz{display:flex;align-items:center;gap:12px}
.qdone .body,.snz .body{flex:1;min-width:0}
.qdone .t,.snz .t{font-size:14.5px;font-weight:600}
.qdone .s,.snz .s{font-size:12.5px;color:var(--fg-3);margin-top:2px}
.snz>.i{color:var(--fg-3);flex:0 0 auto}
.qcard.done .qa{margin-left:42px}
.okdot{width:30px;height:30px;border-radius:50%;background:var(--btn);color:var(--on-btn);display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;animation:pop .32s var(--ease-out)}
.okdot .i{stroke-width:2.4}
.meet{display:flex;align-items:center;gap:14px}
.chip[aria-pressed="true"]{background:var(--btn);border-color:var(--btn);color:var(--on-btn)}
/* a reply recorded by voice: bars scale, never resize */
.qrec{display:flex;align-items:center;gap:10px;height:34px}
.qrec .rdot{width:10px;height:10px;border-radius:50%;background:var(--clay);flex:0 0 auto;animation:pulse 1s var(--ease-in-out) infinite}
.qrec .rtime{font-family:var(--mono);font-size:13px;font-weight:500;min-width:36px}
.qbars{display:flex;align-items:center;gap:2px;height:24px;flex:1;min-width:0;overflow:hidden;justify-content:flex-end}
.qbars i{width:3px;height:22px;border-radius:2px;background:var(--fg);flex:0 0 auto;transform:scaleY(var(--h,.15));transition:transform .09s linear}
.snzmenu .row,.nrow{width:100%;text-align:left;border-top:0;border-radius:12px}
.snzmenu .row{padding:10px 10px}
.nrow{align-items:flex-start;padding:12px 8px}
.ndot{width:8px;height:8px;border-radius:50%;margin-top:14px;flex:0 0 auto;background:transparent}
.ndot.on{background:var(--accent-mid)}

/* ---------- a Twin ---------- */
.thead{display:flex;align-items:center;gap:18px;flex-wrap:wrap}
.thead .row-gap{margin-left:auto}
.mat .row .body .prog{height:4px;border-radius:9px;background:var(--sunken);overflow:hidden;margin-top:6px}
.mat .row .body .prog i{display:block;height:100%;width:100%;background:var(--fg);border-radius:9px;transform:scaleX(0);transform-origin:left;transition:transform 1.7s var(--ease-out)}
.polnote{display:flex;gap:8px;align-items:flex-start;padding:10px 12px;border-radius:12px;background:var(--sunken);font-size:12px;line-height:1.5;color:var(--fg-2)}
.polnote .i{flex:0 0 auto;margin-top:1px;color:var(--fg-3)}
.price{display:flex;align-items:center;gap:16px;flex-wrap:wrap;padding-top:4px;transition:opacity .3s var(--ease-out)}
.price.off{opacity:.4;pointer-events:none}
.stepper{display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:999px;background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line)}
.stepper button{width:36px;height:36px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--fg);background:var(--surface);
  box-shadow:var(--shadow-1),inset 0 0 0 1px var(--line);transition:transform .16s var(--ease-out),opacity .2s var(--ease-out)}
.stepper button:active{transform:scale(.92)}
.stepper button[disabled]{opacity:.35;cursor:not-allowed}
.stepper b{min-width:58px;text-align:center;font-size:18px;font-weight:600;letter-spacing:-.02em;font-variant-numeric:tabular-nums;display:inline-block}
.stepper b.bump{animation:tick .32s var(--ease-out)}

/* ---------- insights ---------- */
.hot{display:flex;flex-direction:column}
.hotrow{border-top:1px solid var(--line)}
.hotrow:first-child{border-top:0}
.hotrow summary{list-style:none;display:flex;align-items:center;gap:12px;padding:12px 0;cursor:pointer;border-radius:10px}
.hotrow summary::-webkit-details-marker{display:none}
.hotrow summary>.i{color:var(--fg-3);transition:transform .3s var(--ease-out);flex:0 0 auto}
.hotrow[open] summary>.i{transform:rotate(180deg)}
.hotrow .hb{flex:1;min-width:0;display:flex;flex-direction:column;gap:7px}
.hotrow .hb .top{display:flex;justify-content:space-between;gap:10px;font-size:14px}
.hotrow .hb .top b{font-weight:600}
.hotrow .hb .top .tnum{color:var(--fg-2);font-size:13px;font-weight:600;display:inline-flex;gap:8px;align-items:center}
.hotrow .hd{display:flex;flex-direction:column;gap:10px;padding:0 0 14px;animation:rise .35s var(--ease-out)}
.hotrow .hd i{font-family:var(--serif-text);font-style:italic;font-weight:400;font-size:15px;letter-spacing:0;font-variation-settings:"opsz" 14;color:var(--fg)}
/* question deltas: more questions is the red flag, fewer is quiet ink; the arrow is in the markup */
.dd{display:inline-flex;align-items:center;gap:2px;height:20px;padding:0 7px;border-radius:99px;font-size:12px;font-weight:600;font-variant-numeric:tabular-nums}
.dd.up{background:var(--clay-soft);color:var(--clay-ink)}
.dd.dn{background:var(--sunken);color:var(--fg-2);box-shadow:inset 0 0 0 1px var(--line)}
.miscon{display:flex;flex-direction:column;gap:6px;padding:12px 14px;border-radius:14px;background:var(--sunken)}
.miscon .mq{font-family:var(--serif-text);font-style:italic;font-weight:400;font-size:17.5px;line-height:1.4;letter-spacing:0;font-variation-settings:"opsz" 14;color:var(--fg)}
.heatwrap{overflow-x:auto;margin:0 -4px;padding:0 4px}
/* the label column and the cell count are variables (set in the markup), so phones can fit the chart instead of scrolling it */
.heat2{display:grid;gap:5px;min-width:360px;align-items:center;grid-template-columns:var(--lw,130px) repeat(var(--n,6),minmax(40px,1fr))}
.heat2.times{--lw:44px}
.heat2 .lbl{font-size:12.5px;color:var(--fg-2);white-space:nowrap}
/* more questions means more ink: darker on light, brighter on dark */
.heat2 .c{height:26px;border-radius:7px;background:color-mix(in srgb,var(--fg) calc(var(--v) * 92%),var(--sunken));animation:cellIn .5s var(--ease-out) both}
@keyframes cellIn{from{opacity:0;transform:scale(.6)}to{opacity:1;transform:none}}
.heat2 .wk{font-size:12px;font-weight:500;letter-spacing:0;color:var(--fg-3);text-align:center}

/* ---------- earnings ---------- */
.mbars{display:flex;align-items:flex-end;gap:18px;height:170px;padding-top:24px}
.mbars.sm{height:120px;padding-top:20px}
.mb{flex:1;height:100%;display:flex;flex-direction:column;align-items:center;justify-content:flex-end;gap:8px;position:relative}
.mc{width:100%;max-width:120px;border-radius:8px 8px 3px 3px;background:color-mix(in srgb,var(--fg) 14%,transparent);box-shadow:inset 0 1px 0 rgba(255,255,255,.04);
  transform-origin:bottom;animation:growY .8s var(--ease-out) both}
.mc.cur{background:var(--bar-strong);box-shadow:inset 0 1px 0 rgba(255,255,255,.28)}
.mv{font-family:var(--mono);font-size:12px;font-weight:500;letter-spacing:0;color:var(--fg-2)}
.ml{font-size:12px;font-weight:500;letter-spacing:0;color:var(--fg-3)}
.kv .v .linkbtn{margin-left:6px;font-size:12.5px}
.ladder{display:flex;align-items:flex-start}
.ladder .st{flex:1;display:flex;flex-direction:column;align-items:center;gap:5px;position:relative;font-size:12px;color:var(--fg-3);text-align:center;min-width:0}
.ladder .st::before{content:"";position:absolute;top:14px;left:-50%;right:50%;height:3px;background:var(--line-2);z-index:0}
.ladder .st:first-child::before{display:none}
.ladder .st.done::before,.ladder .st.on::before{background:var(--fg)}
.ladder .dot{width:30px;height:30px;border-radius:50%;display:flex;align-items:center;justify-content:center;background:var(--sunken);color:var(--fg-3);font-size:12px;font-weight:700;
  position:relative;z-index:1;box-shadow:0 0 0 3px var(--surface)}
.ladder .dot .i{stroke-width:2.4}
.ladder .st.done .dot{background:var(--fg);color:var(--bg)}
.ladder .st.on .dot{background:var(--btn);color:var(--on-btn);box-shadow:0 0 0 3px var(--surface),0 0 0 6px var(--accent-soft);animation:pop .32s var(--ease-out)}
.ladder .st.pending .dot{background:var(--amber-soft);color:var(--amber-ink)}
.ladder .st b{color:var(--fg);font-size:13px;font-weight:600}
.ladder.five .st span:last-child{max-width:90px;line-height:1.3}

/* ---------- import, wizard ---------- */
.checkrow .cb{width:22px;height:22px;border-radius:7px;border:1.5px solid var(--line-2);display:inline-flex;align-items:center;justify-content:center;color:transparent;flex:0 0 auto;
  transition:background-color .2s var(--ease-out),border-color .2s var(--ease-out),color .2s var(--ease-out)}
.checkrow .cb .i{stroke-width:2.6}
.checkrow[aria-pressed="true"] .cb{background:var(--btn);border-color:var(--btn);color:var(--on-btn);animation:pop .24s var(--ease-out)}
.impempty{display:flex;flex-direction:column;align-items:flex-start;gap:8px;padding:16px;border-radius:16px;background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line)}
.impempty .t{font-size:15px;font-weight:600}
.impempty .s{font-size:13px;line-height:1.55;color:var(--fg-2);margin-bottom:4px}
.steps{display:flex;gap:6px}
.steps i{flex:1;height:4px;border-radius:9px;background:var(--sunken);transition:background-color .4s var(--ease-out)}
.steps i.on{background:var(--fg)}
.plan.dim{opacity:.55}
.plan[aria-disabled="true"]{cursor:not-allowed}
.cwdraft{width:100%;text-align:left;border:1px solid var(--line);border-radius:16px;padding:12px 14px}
.cwdraft>.i{color:var(--fg-3)}
.cwnav{margin-top:4px}
.cwdiscard{align-self:center;color:var(--fg-3)}
.cwsum{padding:4px 16px}
.cwsum .kv .v{display:inline-flex;gap:8px;align-items:center;justify-content:flex-end;flex-wrap:wrap;font-weight:500}
.cwsum .kv .v .linkbtn{margin-left:0}
.cwprice{display:flex;flex-direction:column;gap:6px;padding:4px 16px 14px;border-radius:14px;background:var(--sunken)}
.voicerec{display:flex;align-items:center;gap:14px;padding:14px;border-radius:18px;background:var(--sunken)}
.voicerec .body{flex:1;min-width:0}
.voicerec .t{font-size:14px;font-weight:600}
.voicerec .s{font-size:12.5px;color:var(--fg-3);margin-top:2px}
.voicerec.done{background:var(--accent-soft)}
.recbtn{width:52px;height:52px;border-radius:50%;background:var(--deep);color:#FFFFFF;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;
  box-shadow:inset 0 1px 0 rgba(255,255,255,.22),inset 0 0 0 1px rgba(255,255,255,.10);transition:transform .16s var(--ease-out)}
.recbtn:active{transform:scale(.94)}
.recbtn.on{background:var(--clay);color:#FFFFFF;animation:pulse 1.2s var(--ease-in-out) infinite}

/* ---------- Ask Vidya: every quiz question, a send waiting on Undo, the private test rail ---------- */
.pquiz{list-style:none;display:flex;flex-direction:column;margin:2px 0 4px;padding:0;border-radius:14px;box-shadow:inset 0 0 0 1px var(--line);overflow:hidden}
.pq+.pq{border-top:1px solid var(--line)}
.pq summary{list-style:none;display:flex;align-items:flex-start;gap:10px;padding:11px 14px;cursor:pointer;font-size:14px;line-height:1.45}
.pq summary::-webkit-details-marker{display:none}
.pq summary>.i{margin-left:auto;margin-top:3px;color:var(--fg-3);flex:0 0 auto;transition:transform .24s var(--ease-out)}
.pq details[open] summary>.i{transform:rotate(180deg)}
.pq-n{flex:0 0 auto;width:22px;height:22px;border-radius:7px;display:inline-flex;align-items:center;justify-content:center;font-size:12px;font-weight:600;color:var(--fg-2);
  background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line)}
.pq-q{flex:1;min-width:0;font-weight:500;color:var(--fg)}
.pq-a{display:flex;flex-direction:column;gap:6px;padding:0 14px 12px 46px;font-size:13.5px;line-height:1.55;color:var(--fg-2)}
.pq-ed{display:flex;flex-direction:column;gap:8px;padding:12px 14px;background:var(--sunken)}
.pq-ed .input{background:var(--surface)}
.testrail{display:flex;flex-direction:column;gap:8px;margin-top:12px;padding:12px 14px;border-radius:14px;border:1px dashed var(--line-2);
  background:color-mix(in srgb,var(--sunken) 60%,transparent);font-size:13px;line-height:1.55;color:var(--fg-2)}
.testrail .tr-h{display:flex;align-items:center;gap:6px;font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3)}
.testrail .tr-ok{display:flex;gap:6px;align-items:center;font-weight:600;color:var(--fg)}
.testrail .tr-fixed{font-size:14px;color:var(--fg);white-space:pre-wrap}
.testrail .tr-ed{display:flex;flex-direction:column;gap:8px}
.testrail .tr-ed .input{background:var(--surface)}
.brief .due .row.muted-row .t{color:var(--fg-3)}

/* Today: the rest of her Twins under the CEM 141 panel, one pill each */
.p-others{border-top:1px solid var(--line);padding-top:14px;display:flex;flex-direction:column;gap:10px}
.p-others-l{display:flex;flex-wrap:wrap;gap:6px}
.p-other{display:inline-flex;align-items:center;gap:8px;height:34px;padding:0 12px 0 5px;border-radius:999px;background:var(--surface);box-shadow:inset 0 0 0 1px var(--line-2);font-size:12.5px;white-space:nowrap;
  transition:background-color .15s var(--ease-out),box-shadow .15s var(--ease-out)}
.p-other:hover{background:var(--sunken);box-shadow:inset 0 0 0 1px var(--fg-4)}
.p-other:active{transform:scale(.98)}
.p-other .av.s24{width:24px;height:24px;font-size:8.5px;border-radius:8px}
.p-other-c{font-weight:600;color:var(--fg);font-variant-numeric:tabular-nums}
.p-other-s{font-weight:500;color:var(--fg-3);font-variant-numeric:tabular-nums}
.p-other-s.is-draft{color:var(--amber-ink)}

/* ---------- narrower widths ---------- */
@media (max-width:980px){.dash,.tgrid{grid-template-columns:1fr}.dash{grid-template-rows:none}.dash>.panel.needsp,.dash>.panel:not(.needsp),.dash>.needsp.is-empty,.dash>.needsp.is-empty~.panel:last-child{grid-column:auto;grid-row:auto}.stats{grid-template-columns:1fr 1fr}}
/* tablet landscape: beside a narrow right column, Needs you stretched far past its content. Here Needs you takes
   the full width, Stuck and the Twin share a row at equal heights, and Coming up closes the page */
@media (min-width:981px) and (max-width:1180px){
  .dash{grid-template-columns:repeat(2,minmax(0,1fr));grid-template-rows:none;align-items:stretch}
  .dash>.needsp,.dash>.needsp.is-empty{grid-column:1 / -1;grid-row:auto}
  .dash>.panel:not(.needsp){grid-column:auto;grid-row:auto}
  .dash>.panel:last-child,.dash>.needsp.is-empty~.panel:last-child{grid-column:1 / -1;grid-row:auto}
}

/* a question card lays out its actions by its own width (Today's column or the inbox), not the window's:
   the primary and the secondary share a line, the quieter ones get a centred line of their own */
.qcard{container:qcard / inline-size}
@container qcard (max-width:540px){
  .qa>.btn{flex:1 1 0}
  .qa>.qa-t{flex:1 0 100%;display:flex;flex-wrap:wrap;justify-content:center;gap:4px}
  .qa-t>.btn{flex:0 0 auto;background:transparent;border-color:transparent;box-shadow:none;color:var(--fg-2)}
  .qa-t>.btn:hover{background:var(--accent-soft);color:var(--fg)}
  /* the primary keeps its one-line width; only a label longer than the whole row wraps, never truncates */
  .qa>.btn.primary{min-width:fit-content;white-space:normal;text-wrap:balance;text-align:center;line-height:1.25}
  .qcard.done .qa{margin-left:0}
  /* when the tags take the line, the time wraps to the right edge of the next one, where a timestamp reads */
  .qh>.xs{margin-left:auto}
}

/* touch (phones by width, tablets by pointer): every control a thumb can hit is 44px. Buttons grow for real;
   inline controls (links, citations, switches, chips, segments) keep their size and rhythm and get an invisible
   44px hit area centred on them */
@media (max-width:760px),(pointer:coarse){
  :is(.pp,.pquiz,.testrail) .btn,:is(.pp,.pquiz,.testrail) .btn.sm{height:44px}
  :is(.pp,.pquiz,.testrail) .btn.sm{padding:0 16px;font-size:13.5px}
  .pp .stepper button{width:44px;height:44px}
  .pp .stepper b{min-width:64px}
  .pp .p-other{height:44px}
  .pp .chips{gap:8px}
  .pp .chips .chip{height:36px}
  .pp .seg button{height:40px}
  .pp :is(.checkline,.snzline){height:40px}
  :is(.pp,.pquiz,.testrail) :is(.linkbtn,.cite,button.more,.kpi-line,.toggle,.seg button,.chip,.checkline,.snzline){position:relative}
  :is(.pp,.pquiz,.testrail) :is(.linkbtn,.cite,button.more,.kpi-line,.toggle,.seg button,.chip,.checkline,.snzline)::before{
    content:"";position:absolute;left:50%;top:50%;width:max(100%,44px);height:max(100%,44px);transform:translate(-50%,-50%)}
}

/* phones */
@media (max-width:760px){
  .today{gap:20px}
  .panel{padding:16px}
  .qcard{padding:16px}
  .qcard.inline{padding:0 0 4px}
  .qcard .qt{font-size:16px}
  .qpage .page-head.compact .display{font-size:24px;white-space:normal}
  .thead{gap:14px}
  .thead .row-gap{margin-left:0;width:100%}
  .thead .row-gap .btn{flex:1}
  .h1{font-size:22px}
  .stat-card{padding:14px}
  .stat-card .n{font-size:28px}
  .pq-a{padding-left:14px}
  .qkeys{display:none}
  .topbar .pill.needs-pill .i{display:inline-block}
  /* panel headers: the title and its link, tag or button share the first line; the description takes the full
     width under them instead of being squeezed beside the control */
  .pp .panel-h{display:grid;grid-template-columns:minmax(0,1fr) auto;column-gap:12px;row-gap:3px;align-items:center}
  .pp .panel-h>div{display:contents}
  .pp .panel-h>div>*{grid-column:1 / -1}
  .pp .panel-h>div>.h3{grid-column:1;grid-row:1}
  .pp .panel-h>:not(div){grid-column:2;grid-row:1;justify-self:end}
  .pp .panel-h>.xs{grid-column:1 / -1;grid-row:2;justify-self:start}
  .pp .panel-h>.h3{grid-column:1;grid-row:1;justify-self:start}
  .pp .panel-h .xs{margin-top:0}
  /* "Always on" wraps under a long setting name flush left, not indented */
  .pp .setrow .t>.tag.always{margin-left:0}
  /* a bar's count wraps under its label when both do not fit on one line */
  .pp .hbar .top{flex-wrap:wrap;row-gap:2px}
  .pp .hbar .top b{flex:1 1 auto}
  /* button pairs in panels, slabs, cards and the wizard: equal widths on one line; a long label keeps its width
     and its partner takes the rest (or its own line); a quiet text action gets its own centred line */
  :is(.pp .panel,.pp .slab,.pp.cw,.pp .qcard,.pp .card) .row-gap>.btn{flex:1 1 0;padding:0 14px}
  :is(.pp .panel,.pp .slab,.pp.cw,.pp .qcard,.pp .card) .row-gap>.btn.text{flex:1 0 100%}
  .pp .cwnav>.btn:not(.primary){flex:0 0 auto}
  .pp .cwnav>.btn.primary{min-width:fit-content;white-space:normal;line-height:1.25;text-align:center}
  /* her other Twins: a two-up grid of two-line tiles instead of a ragged column of pills */
  .pp .p-others-l{display:grid;grid-template-columns:repeat(auto-fill,minmax(136px,1fr));gap:8px}
  .pp .p-other{height:auto;min-height:52px;padding:8px 10px 8px 8px;border-radius:14px;display:grid;grid-template-columns:auto minmax(0,1fr);
    column-gap:10px;row-gap:1px;align-items:center;justify-items:start;white-space:normal;text-align:left}
  .pp .p-other .av{grid-row:1 / 3}
  .pp .p-other-c{align-self:end}
  .pp .p-other-s{align-self:start;font-size:12px;line-height:1.3}
  /* the test ring: its verdict sits beside the ring, its actions take the card's full width underneath */
  .pp .gate:has(>div>:is(.row-gap,.btn)){display:grid;grid-template-columns:auto minmax(0,1fr);gap:0 16px;align-items:center}
  .pp .gate:has(>div>:is(.row-gap,.btn))>div:not(.ring){display:contents}
  .pp .gate:has(>div>:is(.row-gap,.btn))>.ring{grid-row:1 / span 2}
  .pp .gate:has(>div>:is(.row-gap,.btn)) .gt{align-self:end}
  .pp .gate:has(>div>:is(.row-gap,.btn))>div>:is(.small,.xs){align-self:start}
  .pp .gate>div>:is(.row-gap,.btn){grid-column:1 / -1;margin-top:14px!important}
  /* heatmaps fit the phone: the label column takes what its longest label needs, the cells share the rest */
  .pp .heat2{min-width:0;gap:4px;grid-template-columns:max-content repeat(var(--n,6),minmax(0,1fr))}
  .pp .heat2 .lbl{font-size:12px;padding-right:4px}
  .pp .heat2 .c{height:24px;border-radius:6px}
}
/* narrow phones: two-sided key/value rows stack, label over value, so neither wraps into a ragged column */
@media (max-width:480px){
  /* the five verification steps size to their words, so "Confirmed" and "Educator" never run into each other */
  .pp .ladder.five .st{flex:1 1 auto}
  .pp .ladder.five .st span:last-child{max-width:none}
  .pp :is(.kvs,.cwsum) .kv{flex-direction:column;align-items:flex-start;gap:2px}
  .pp :is(.kvs,.cwsum) .kv .v{text-align:left;justify-content:flex-start}
}

/* ============================================================
   Live pieces: a Twin's own look, students' questions as they
   arrive, pausing a Twin, material in and out, connections.
   ============================================================ */
.twinp-h{display:flex;align-items:center;gap:12px;min-width:0}
.twinp-h>div{min-width:0}

/* ---------- How your Twin looks ---------- */
.lookp .lk{display:grid;grid-template-columns:minmax(240px,300px) minmax(0,1fr);gap:22px 28px;align-items:start}
.lk-view{display:flex;flex-direction:column;align-items:stretch;gap:12px;min-width:0}
/* the stage: a quiet patch of sky the planet (or her photo) sits in, drawn by the orbit's own renderer */
.lk-stage{--lkP:132px;--lkC:204px;--lkD:calc(var(--lkC) * .86);--gl-ground:rgba(10,11,14,.24);
  position:relative;height:236px;border-radius:20px;overflow:hidden;display:grid;place-items:center;
  background:radial-gradient(64% 72% at 50% 44%,color-mix(in srgb,var(--fg) 6%,transparent) 0%,transparent 72%),var(--sunken);
  box-shadow:inset 0 0 0 1px var(--line);transition:box-shadow .2s var(--ease-out)}
.lk-stage.is-drop{box-shadow:inset 0 0 0 2px var(--fg)}
/* the preview is Planets.preview on a .pl-prev: the orbit's own render, ring and moons included */
.lk-stage .lk-prev{--hs:var(--lkP);animation:lkIn .5s var(--ease-out) both}
.lk-pl{--hs:var(--lkP);position:relative;display:block;width:var(--hs);height:var(--hs);animation:lkIn .5s var(--ease-out) both}
.lk-pl .pl-core{left:0;top:0}
.lk-pl .pl-face{font-size:calc(var(--hs) * .22)}
.lk-pl.is-photo .vd-pl{background-size:cover}
.lk-rim{position:absolute;inset:0;border-radius:50%;pointer-events:none;
  background:radial-gradient(circle at 32% 24%,rgba(255,255,255,.36) 0,rgba(255,255,255,0) 44%),radial-gradient(circle at 50% 50%,rgba(255,255,255,0) 62%,rgba(255,255,255,.2) 100%);
  box-shadow:inset 0 0 0 1px rgba(255,255,255,.3),inset 0 calc(var(--hs) * -.08) calc(var(--hs) * .16) rgba(10,11,14,.3)}
@keyframes lkIn{from{opacity:.4;transform:scale(.96)}to{opacity:1;transform:none}}
.lk-drop{width:calc(var(--lkP) + 24px);height:calc(var(--lkP) + 24px);border-radius:50%;border:1.5px dashed var(--fg-4);background:var(--surface);color:var(--fg-2);
  display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;transition:border-color .18s var(--ease-out),color .18s var(--ease-out),transform .18s var(--ease-out)}
.lk-drop:hover,.lk-stage.is-drop .lk-drop{border-color:var(--fg);color:var(--fg)}
.lk-drop:active{transform:scale(.98)}
.lk-drop .t{font-size:13px;font-weight:600;color:var(--fg)}
.lk-drop .s{font-size:12px;color:var(--fg-3)}
/* framing a photo: drag inside the circle, zoom with the slider, arrows and plus or minus from the keyboard */
.lk-crop{position:relative;width:var(--lkC);height:var(--lkC);overflow:hidden;border-radius:18px;cursor:grab;touch-action:none;user-select:none;-webkit-user-select:none;outline:none;background:#0B0C0E}
.lk-crop.grab{cursor:grabbing}
.lk-crop:focus-visible{box-shadow:0 0 0 2px var(--surface),0 0 0 4px var(--focus)}
.lk-crop-img{position:absolute;left:50%;top:50%;max-width:none;pointer-events:none;will-change:transform;-webkit-user-drag:none}
.lk-mask{position:absolute;left:50%;top:50%;width:var(--lkD);height:var(--lkD);transform:translate(-50%,-50%);border-radius:50%;pointer-events:none;
  box-shadow:0 0 0 999px rgba(10,11,14,.56),inset 0 0 0 2px rgba(255,255,255,.92)}
.lk-cap{display:flex;flex-direction:column;align-items:center;gap:2px;text-align:center;min-width:0}
.lk-cap b{font-size:15px;font-weight:600;letter-spacing:-.01em;max-width:100%;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.lk-cap span{font-size:12px;color:var(--fg-3)}
.lk-form{display:flex;flex-direction:column;gap:16px;min-width:0}
.lk-name{position:relative}
.lk-name .input{padding-right:64px}
.lk-name .input[aria-invalid="true"]{border-color:var(--clay)}
.lk-count{position:absolute;right:14px;top:50%;transform:translateY(-50%);font-size:12px;color:var(--fg-3);font-variant-numeric:tabular-nums;pointer-events:none}
.lk-hint{color:var(--fg-3);line-height:1.45}
.lk-hint.is-err{color:var(--clay-ink);font-weight:500}
.lk-sec{display:flex;flex-direction:column;gap:8px;min-width:0}
.lk-mode{align-self:flex-start}
.lk-mode button{display:inline-flex;align-items:center;gap:6px}
.lk-kinds{display:flex;flex-wrap:wrap;gap:8px}
.lk-kind{display:inline-flex;align-items:center;gap:8px;height:40px;padding:0 14px 0 6px;border-radius:999px;background:var(--surface);box-shadow:inset 0 0 0 1px var(--line-2);
  font-size:13px;font-weight:500;color:var(--fg-2);transition:box-shadow .16s var(--ease-out),color .16s var(--ease-out),background-color .16s var(--ease-out)}
.lk-kind:hover{color:var(--fg);background:var(--sunken)}
.lk-kind:active{transform:scale(.98)}
.lk-kind[aria-checked="true"]{color:var(--fg);font-weight:600;box-shadow:inset 0 0 0 2px var(--fg)}
.lk-thumb{width:28px;height:28px;border-radius:50%;flex:0 0 auto;background:var(--pl-img) center/100% 100% no-repeat;box-shadow:0 2px 5px -3px rgba(var(--pd),.5)}
.lk-tones{display:flex;flex-wrap:wrap;gap:4px}
.lk-tone{display:flex;flex-direction:column;align-items:center;gap:6px;min-width:62px;padding:6px 4px 5px;border-radius:14px;font-size:12px;font-weight:500;color:var(--fg-2);
  transition:background-color .16s var(--ease-out),color .16s var(--ease-out)}
.lk-tone:hover{background:var(--sunken);color:var(--fg)}
.lk-tone .sw{width:36px;height:36px;border-radius:50%;background:var(--pl-img) center/100% 100% no-repeat;box-shadow:0 0 0 2px var(--surface),0 0 0 3px transparent;
  transition:box-shadow .2s var(--ease-out),transform .2s var(--ease-out)}
.lk-tone[aria-checked="true"]{color:var(--fg);font-weight:600}
.lk-tone[aria-checked="true"] .sw{box-shadow:0 0 0 2px var(--surface),0 0 0 4px var(--fg);transform:scale(1.04)}
.lk-opts{display:flex;flex-wrap:wrap;align-items:center;gap:12px 22px}
.lk-opt{display:inline-flex;align-items:center;gap:10px}
.lk-ol{font-size:13px;font-weight:600;color:var(--fg)}
.lk-zoom{width:100%;height:28px;accent-color:var(--fg);cursor:pointer}
.lk-foot{display:flex;align-items:center;justify-content:space-between;gap:12px 16px;flex-wrap:wrap;border-top:1px solid var(--line);padding-top:14px}
.lk-foot .note{flex:1 1 260px}
.lk-acts{justify-content:flex-end}
/* inside the create wizard: one column, a smaller stage, no Save (it keeps when she continues) */
.lookp.is-wiz{padding:16px;box-shadow:none}
.lookp.is-wiz .lk{grid-template-columns:1fr;gap:16px}
.lookp.is-wiz .lk-stage{height:196px;--lkP:112px;--lkC:172px}
/*@dark-begin*/
:root[data-theme="dark"] .lk-stage{--gl-ground:rgba(0,0,0,.55)}
:root[data-theme="dark"] .lk-drop{background:var(--raised)}
/*@dark-end*/
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]) .lk-stage{--gl-ground:rgba(0,0,0,.55)}
:root:not([data-theme="light"]) .lk-drop{background:var(--raised)}
}
/* reduced motion: the moons hold still where they read best, and the planet does not settle in */
@media (prefers-reduced-motion:reduce){
  .lk-pl,.lk-stage .lk-prev{animation:none}
  .lk-stage .pl-moon{animation:none!important;z-index:4}
  .lk-stage .pl-moon i{animation:none!important;transform:translateX(calc(var(--hs) * var(--mo,1.5) * .4))}
  .lk-stage .pl-moon b{animation:none!important;transform:translateY(calc(var(--hs) * var(--mo,1.5) * -.12))}
  .lk-stage .pl-moon+.pl-moon i{transform:translateX(calc(var(--hs) * var(--mo,1.5) * -.42))}
  .lk-stage .pl-moon+.pl-moon b{transform:translateY(calc(var(--hs) * var(--mo,1.5) * .1))}
}

/* ---------- a student's question, live ---------- */
.qfrom{display:flex;align-items:center;gap:8px;font-size:12.5px;line-height:1.45;color:var(--fg-3)}
.qfrom .i{flex:0 0 auto;color:var(--fg-3)}
.qcard .qnew{height:22px}
.draft .dl .qdemo{margin-left:auto;height:20px;padding:0 8px;font-size:11px;font-weight:600;letter-spacing:.02em;text-transform:none}
.draft.drafting .dt{min-height:24px}
.qdrafterr .dt{color:var(--fg-2)}
.qdrafterr .row-gap{margin-top:10px}

/* ---------- a Twin: paused, and its material in and out ---------- */
.pausedslab{display:flex;align-items:center;gap:12px;flex-wrap:wrap}
.pausedslab>.i{flex:0 0 auto;color:var(--amber-ink)}
.pausedslab>div{flex:1 1 260px;min-width:0}
.pausedslab .t{font-weight:600;color:var(--fg);line-height:1.45}
.pausedslab .s{font-size:12.5px;color:var(--fg-2);margin-top:2px}
.matrow .matacts{display:inline-flex;align-items:center;gap:6px;flex:0 0 auto}
.matrow .matbtn.text,.conn .btn.text{color:var(--fg-3)}
.matrow .matbtn.text:hover,.conn .btn.text:hover{color:var(--fg)}
.conn .tag{flex:0 0 auto}

/* touch: the look editor's controls are 44px too */
@media (max-width:760px),(pointer:coarse){
  .pp .lk-kind{height:44px}
  .pp .lk-tone{min-height:66px}
}
@media (max-width:760px){
  .lookp .lk{grid-template-columns:1fr}
  .lk-stage{height:220px}
  .lk-foot .lk-acts{width:100%}
  .lk-foot .lk-acts .btn{flex:1 1 0}
  .lk-tones{justify-content:space-between}
  .lk-tone{min-width:0;flex:1 1 0}
  .matrow{flex-wrap:wrap}
  .matrow .matacts{margin-left:auto}
}

/* ============================================================
   Phase 2 · a signed-in professor: the gate while her world loads
   (or is not hers), honest empty states, material in with real
   progress, and the six-stop walkthrough. Guest demo untouched.
   ============================================================ */
/* the quiet guest link in the top bar */
.r-glink{display:inline-flex;align-items:center;gap:0;height:36px;padding:0 14px;border-radius:999px;font-size:12.5px;font-weight:500;color:var(--fg-2);text-decoration:none;
  background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line);white-space:nowrap;transition:color .16s var(--ease-out),background-color .16s var(--ease-out)}
.r-glink b{font-weight:600;color:var(--fg);margin-left:4px}
.r-glink:hover{color:var(--fg);background:var(--accent-soft)}
.r-glink:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.r-glinkrow{text-decoration:none;color:inherit;margin-top:10px;background:var(--sunken)}
.r-glinkrow>.i{color:var(--fg-3);flex:0 0 auto}

/* boot, and the calm page for a student, a signed-out visit or a network error */
.r-boot .r-sk1{display:block;width:min(360px,72%);height:30px;border-radius:10px}
.r-boot .r-sk2{display:block;width:min(250px,52%);height:30px;border-radius:10px;margin-top:10px}
.r-boot .panel{gap:12px}
.r-gate{min-height:calc(100% - 40px);display:flex;align-items:center;justify-content:center}
.r-gate-card{width:min(460px,100%);display:flex;flex-direction:column;align-items:flex-start;gap:12px;padding:26px 24px;border-radius:22px;background:var(--surface);border:1px solid var(--line);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.035),0 18px 40px -28px rgba(10,11,14,.45);animation:rise .45s var(--ease-out) both}
.r-gate-card .h2{text-wrap:balance}
.r-gate-card p{line-height:1.6;margin:0}
.r-gate-card .row-gap{margin-top:6px}
.r-gate-d{display:flex;flex-direction:column;gap:8px;margin-top:16px}
.r-gate-d .navrow{text-decoration:none;color:inherit}

/* honest empty states: one line in a panel, or the whole page */
.r-empty{display:flex;align-items:flex-start;gap:12px;padding:12px 14px;border-radius:14px;background:var(--sunken);color:var(--fg-2);font-size:13px;line-height:1.5}
.r-empty>.i{flex:0 0 auto;margin-top:2px;color:var(--fg-3)}
.r-empty>div{flex:1;min-width:0}
.r-empty .t{font-weight:600;color:var(--fg);font-size:13.5px}
.r-empty .s{color:var(--fg-3);font-size:12.5px;margin-top:2px}
.r-empty>.btn{flex:0 0 auto;align-self:center}
.r-emptyp{align-items:flex-start;gap:12px;padding:28px 26px;max-width:720px}
.r-emptyp .h2{text-wrap:balance;max-width:28ch}
.r-emptyp p{line-height:1.65;max-width:62ch;margin:0}
.r-emptyp .row-gap{margin-top:4px}
/* her first Twin, and the first steps */
.r-steps{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.r-steps li{display:flex;align-items:flex-start;gap:12px}
.r-steps .body{display:flex;flex-direction:column;gap:2px;min-width:0}
.r-steps .t{font-size:14px;font-weight:600}
.r-steps .s{font-size:12.5px;color:var(--fg-3);line-height:1.45}
.r-check .row{align-items:center}
.r-check .row.is-done .t{color:var(--fg-3);text-decoration:line-through;text-decoration-color:color-mix(in srgb,currentColor 45%,transparent)}
.r-check .row.is-done .iconsq{background:var(--fg);color:var(--bg);box-shadow:none}
.r-ringic{display:inline-flex;color:var(--fg-3)}

/* coverage topics */
.r-topics{display:flex;flex-direction:column;gap:8px}
.r-tchips{display:flex;flex-wrap:wrap;gap:6px;align-items:center}
.r-tchips .tag{max-width:100%;overflow:hidden;text-overflow:ellipsis}

/* material in: the drop area, and a file on its way with real progress */
.r-drop{display:flex;flex-direction:column;gap:10px;border-radius:16px;transition:box-shadow .18s var(--ease-out),background-color .18s var(--ease-out)}
.r-drop.is-over{background:var(--accent-soft);box-shadow:0 0 0 2px var(--fg)}
.r-dropzone{display:grid;grid-template-columns:auto 1fr;column-gap:12px;row-gap:2px;align-items:center;text-align:left;width:100%;min-height:56px;padding:12px 16px;border-radius:14px;
  border:1.5px dashed var(--line-2);color:var(--fg-2);background:transparent;transition:border-color .16s var(--ease-out),background-color .16s var(--ease-out),color .16s var(--ease-out)}
.r-dropzone>.i{grid-row:1 / 3;color:var(--fg-3)}
.r-dropzone .t{font-size:13.5px;font-weight:600;color:var(--fg)}
.r-dropzone .s{font-size:12px;color:var(--fg-3);line-height:1.4}
.r-dropzone:hover{border-color:var(--fg-3);background:var(--sunken)}
.r-dropzone:focus-visible{outline:2px solid var(--focus);outline-offset:2px}
.r-dropzone.is-big{min-height:132px;grid-template-columns:1fr;justify-items:center;text-align:center;padding:22px 18px;row-gap:6px}
.r-dropzone.is-big>.i{grid-row:auto}
.r-dropzone.is-big .t{font-size:15px}
.r-drop.is-over .r-dropzone{border-color:var(--fg);color:var(--fg)}
.mat .r-job .body .prog{display:block;height:4px;border-radius:9px;background:var(--sunken);overflow:hidden;margin-top:7px}
.mat .r-job .body .prog i{display:block;height:100%;width:100%;background:var(--fg);border-radius:9px;transform-origin:left;transition:transform .35s var(--ease-out)}
.r-job.is-err .s{color:var(--clay-ink)}
.r-fix{display:flex!important;align-items:flex-start;gap:6px;color:var(--fg-2)!important;margin-top:4px}
.r-fix .i{flex:0 0 auto;margin-top:2px}
.r-danger{color:var(--clay-ink)}

/* the create wizard's course fields */
.rc-fields{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1.6fr);gap:12px 14px}
.rc-foot{justify-content:center;gap:4px 12px}
.rc-foot .btn{color:var(--fg-3)}
.rc-foot .btn:hover{color:var(--fg)}

/* ---------- the walkthrough: a spotlight on the real control, a glass card beside it ---------- */
.r-tour{--r-scrim:rgba(10,11,14,.42);position:absolute;inset:0;z-index:92;pointer-events:auto;animation:rTourIn .22s var(--ease-out) both}
.r-tour.out{opacity:0;transition:opacity .2s var(--ease-in)}
.r-tour-spot{position:absolute;border-radius:18px;pointer-events:none;box-shadow:0 0 0 200vmax var(--r-scrim),0 0 0 2px color-mix(in srgb,var(--fg) 60%,transparent),0 0 0 7px color-mix(in srgb,var(--fg) 12%,transparent);
  transition:left .38s var(--ease-out),top .38s var(--ease-out),width .38s var(--ease-out),height .38s var(--ease-out)}
.r-tour-spot.is-none{box-shadow:0 0 0 200vmax var(--r-scrim)}
.r-tour-card{position:absolute;width:min(360px,calc(100% - 32px));padding:18px 18px 14px;border-radius:22px;display:flex;flex-direction:column;gap:8px;outline:none;
  box-shadow:0 24px 60px -24px rgba(10,11,14,.5);transition:left .32s var(--ease-out),top .32s var(--ease-out)}
.r-tour-card.in{animation:rTourCard .32s var(--ease-out) both}
.r-tour-top{display:flex;align-items:center;justify-content:space-between;gap:12px}
.r-tour-n{font-size:12px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--fg-3)}
.r-tour-dots{display:inline-flex;gap:5px;align-items:center}
.r-tour-dots i{width:6px;height:6px;border-radius:9px;background:var(--line-2);transition:width .25s var(--ease-out),background-color .25s var(--ease-out)}
.r-tour-dots i.on{width:18px;background:var(--fg)}
.r-tour-t{font-size:17px;font-weight:600;letter-spacing:-.015em;line-height:1.3;color:var(--fg);margin:2px 0 0;text-wrap:balance}
.r-tour-s{font-size:14px;line-height:1.55;color:var(--fg-2);margin:0}
.r-tour-acts{display:flex;align-items:center;gap:6px;margin-top:8px}
.r-tour-acts .btn{height:44px;padding:0 14px}
.r-tour-acts .btn.text{padding:0 8px;margin-left:-8px;color:var(--fg-3)}
.r-tour-acts .btn.text:hover{color:var(--fg)}
.r-tour-sp{flex:1}
.r-tour-card.is-dock{left:16px;right:16px;top:auto;bottom:calc(16px + env(safe-area-inset-bottom,0px));width:auto}
.r-tour-card.is-dock.is-top{top:calc(84px + env(safe-area-inset-top,0px));bottom:auto}
@keyframes rTourIn{from{opacity:0}to{opacity:1}}
@keyframes rTourCard{from{opacity:0;transform:translateY(8px) scale(.98)}to{opacity:1;transform:none}}
/*@dark-begin*/
:root[data-theme="dark"] .r-tour{--r-scrim:rgba(0,0,0,.62)}
:root[data-theme="dark"] .r-tour-card{box-shadow:0 24px 60px -20px rgba(0,0,0,.8)}
/*@dark-end*/
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]) .r-tour{--r-scrim:rgba(0,0,0,.62)}
:root:not([data-theme="light"]) .r-tour-card{box-shadow:0 24px 60px -20px rgba(0,0,0,.8)}
}
.r-tour.rm,.r-tour.rm *{animation:none!important;transition:none!important}
@media (prefers-reduced-motion:reduce){
  .r-tour,.r-tour *,.r-gate-card{animation:none!important;transition:none!important}
  .mat .r-job .body .prog i{transition:none}
}
@media (max-width:760px){
  .rc-fields{grid-template-columns:1fr}
  .r-emptyp{padding:22px 18px}
  .r-empty{flex-wrap:wrap}
  .r-empty>.btn{margin-left:30px}
  .r-tour-acts .btn.primary{flex:1 1 auto}
  .r-gate{align-items:flex-start;padding-top:12px}
}
@media (max-width:760px),(pointer:coarse){
  .r-dropzone{min-height:64px}
  .r-check .btn,.r-gate-card .btn{height:44px}
}
/* a stage whose size is not known yet: the bar travels instead of filling */
.mat .r-job .body .prog.is-indet i{width:34%;transform:none!important;animation:rIndet 1.25s var(--ease-in-out) infinite}
@keyframes rIndet{0%{margin-left:-34%}100%{margin-left:100%}}
@media (prefers-reduced-motion:reduce){.mat .r-job .body .prog.is-indet i{animation:none;width:100%;opacity:.35}}


/* ============================================================
   Vidya · Web voice dock (DESIGN 10). In the middle, a globe: whoever
   you are talking to (Vidya by default). The globe is the planet at the
   crest of the orbit; every Twin is the same object, from a small moon
   to the globe, rendered from the planet library (web-voice.js). Spin
   the orbit and the planets glide into and out of the centre. Press and
   hold the globe to talk. At rest a few Twins ride the globe's ring of
   dots as small moons, with the text pill on its left and the Hands-free
   button on its right; the system rises only when asked. Hands-free, the
   ring of dots becomes a circle of capsules that moves with the voice. Everything that moves
   animates transform, opacity, filter or clip-path.
   ============================================================ */

/* ---------- the globe's materials: Vidya is a black pearl on light, a chrome pearl on dark (10.3) ----------
   The render itself comes from the planet library; these are its ink, its cast shadow and its ripple. */
:root{
  --gl-vid-fg:#FFFFFF;
  --gl-sh:0 22px 30px -18px rgba(10,11,14,.55),0 6px 12px -6px rgba(10,11,14,.22);
  --gl-ground:rgba(10,11,14,.3);
  --gl-rip:rgba(58,61,69,.5);
}
/*@dark-begin*/
:root[data-theme="dark"]{
  --gl-vid-fg:#0B0C0E;
  --gl-sh:0 22px 32px -16px rgba(0,0,0,.85),0 0 40px -6px rgba(170,178,240,.16);
  --gl-ground:rgba(0,0,0,.6);
  --gl-rip:rgba(214,217,226,.55);
}
/*@dark-end*/
@media (prefers-color-scheme:dark){
:root:not([data-theme="light"]){
  --gl-vid-fg:#0B0C0E;
  --gl-sh:0 22px 32px -16px rgba(0,0,0,.85),0 0 40px -6px rgba(170,178,240,.16);
  --gl-ground:rgba(0,0,0,.6);
  --gl-rip:rgba(214,217,226,.55);
}
}

/* ---------- the dock box and its band: content frosts as it slides under (10.1) ---------- */
.d .dock.vdock{padding:0 20px calc(8px + env(safe-area-inset-bottom,0px))}
/* one tall band, slid down while the system rests (transform, never height).
   Translucent all the way down: the conversation stays visible, softly frosted, never a solid wall. */
.d .dock.vdock::before{height:calc(100% + 200px);
  background:var(--dock-glow),linear-gradient(to bottom,transparent 0,color-mix(in srgb,var(--bg) 34%,transparent) 56px,color-mix(in srgb,var(--bg) 58%,transparent) 120px,color-mix(in srgb,var(--bg) 66%,transparent) 100%);
  -webkit-backdrop-filter:blur(8px) saturate(135%);backdrop-filter:blur(8px) saturate(135%);
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 72px);mask-image:linear-gradient(to bottom,transparent 0,#000 72px);
  transform:translateY(166px);transition:transform .55s var(--ease-soft)}
.d .dock.vdock.is-up::before{transform:translateY(120px)}
/* the professor's resting mini orb: a short band */
.d .dock.vdock.mini.is-set:not(.is-up)::before{transform:translateY(188px)}
/* a quiet backing right behind the controls (no blur, one gradient): it ramps in over the 36px above them and is
   near-solid behind them, so no line of content ever reads behind a button, the globe, a planet or its name. Under the
   translucent fade above. Risen, it rises with the orbit (--vd-rise), so the planets and their names sit on it too */
.d .dock.vdock::after{content:"";position:absolute;left:0;right:0;bottom:0;z-index:-1;height:calc(100% + 296px);pointer-events:none;
  background:linear-gradient(to bottom,color-mix(in srgb,var(--bg) 0%,transparent) 0,color-mix(in srgb,var(--bg) 92%,transparent) 36px,color-mix(in srgb,var(--bg) 94%,transparent) 100%);
  transform:translateY(260px);transition:transform .55s var(--ease-soft)}
.d .dock.vdock.is-up::after{transform:translateY(calc(260px - var(--vd-rise,0px)))}
/* the sky: the canvas is always dockH + 230px tall; the JS keeps every star inside the band (10.2) */
.vd-space{position:absolute;left:0;top:-230px;pointer-events:none}
/* the near half of the globe's orbit: over the globe, under the moons that pass in front of it */
.vd-front{z-index:6}
.vd-in{position:relative;max-width:1100px;margin:0 auto;padding-top:14px;display:flex;flex-direction:column;align-items:center}
.d .vdock .tobottom{left:auto;right:max(4px,calc(50% - 432px));margin:0;bottom:calc(100% + 10px)}
/* the risen orbit owns the space above the dock */
.d .vdock.is-up .tobottom,.d .vdock.is-hands .tobottom,.d .vdock.is-rec .tobottom{opacity:0;pointer-events:none}

/* ---------- the low-credit line and other notes above the row ---------- */
.vd-note{position:relative;z-index:4;pointer-events:auto;align-self:center;max-width:min(560px,100%);min-height:40px;margin:0 0 10px;padding:4px 4px 4px 14px;border-radius:999px;
  display:flex;align-items:center;gap:8px;font-size:13px;font-weight:500;color:var(--fg-2);
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow-sm);animation:fadeUp .32s var(--ease-out) both;transition:opacity .25s var(--ease-out)}
.vd-note[hidden]{display:none}
.vd-note>span{display:inline-flex;align-items:center;gap:8px;min-width:0}
.vd-note .linkbtn{font-size:13px}
/* the one calm note when voice cannot run here (no recognition, the microphone refused): its x is a 44px target */
.vd-vn{color:var(--fg-2)}
.vd-vn>.i{flex:0 0 auto;color:var(--fg-3)}
.vd-note-x{position:relative;flex:0 0 auto;width:32px;height:32px;padding:0;border:0;border-radius:50%;background:none;color:var(--fg-3);cursor:pointer;
  display:inline-flex;align-items:center;justify-content:center;transition:background .2s var(--ease-out),color .2s var(--ease-out)}
.vd-note-x::before{content:"";position:absolute;inset:-6px}
.vd-note-x:hover{background:var(--accent-soft);color:var(--fg)}
.vd-note-x:focus-visible{outline:2px solid var(--focus);outline-offset:1px}
/* hidden while the orbit is up (it would sit under the name pill). animation:none matters: the fadeUp fill
   (both) otherwise pins opacity at 1 over this rule; visibility also takes its buttons out of the tab order */
.dock.is-up .vd-note{opacity:0;visibility:hidden;pointer-events:none;animation:none;transition:opacity .18s var(--ease-in),visibility 0s .18s}

/* ---------- the row: side buttons, the centre, the orbit behind them ---------- */
.vd-row{--hs:96px;position:relative;width:100%;min-height:100px;display:flex;align-items:flex-end;justify-content:center;gap:24px}

/* ---------- planets (9, 10.4): one object from a moon to the globe ----------
   Each planet's natural size is the globe's (--hs); the orbit scales it down (--s), so it is crisp at every
   size. Its render is --pl-img (the library); until that exists the tone's gradient stands in. */
.vd-track{position:absolute;inset:0;pointer-events:none;outline:none}
.vd-hit{position:absolute;left:0;right:0;top:-18px;bottom:-6px;pointer-events:auto;cursor:grab;touch-action:pan-y}
.dock:not(.is-up) .vd-hit{pointer-events:none}
.vd-track.grab .vd-hit,.vd-track.grab .vd-p{cursor:grabbing}
.vd-p{position:absolute;left:50%;top:50%;width:0;height:0;padding:0;border:0;background:none;color:inherit;pointer-events:auto;cursor:pointer}
.vd-body{position:absolute;left:0;top:0;width:0;height:0;transform:scale(var(--s,1));filter:var(--blur,none);transition:scale .3s var(--ease-out)}
.pl-core{position:absolute;left:calc(var(--hs) / -2);top:calc(var(--hs) / -2);width:var(--hs);height:var(--hs);transition:scale .6s var(--ease-out)}
.pl-ground{position:absolute;z-index:0;left:18%;right:18%;bottom:-11%;height:16%;border-radius:50%;background:radial-gradient(closest-side,var(--gl-ground),rgba(0,0,0,0));
  transition:opacity .4s var(--ease-out),transform .6s var(--ease-out)}
.vd-pl{position:absolute;inset:0;z-index:2;border-radius:50%;overflow:hidden;color:var(--pi);
  background:var(--pl-img,radial-gradient(circle at 34% 28%,var(--p1),var(--p2) 80%)) center/100% 100% no-repeat;
  box-shadow:0 calc(var(--hs) * .2) calc(var(--hs) * .3) calc(var(--hs) * -.19) var(--pg),0 calc(var(--hs) * .05) calc(var(--hs) * .12) calc(var(--hs) * -.06) rgba(var(--pd),.3)}
.vd-p.t-vid .vd-pl{color:var(--gl-vid-fg);box-shadow:var(--gl-sh)}
/* the face: the Twin's initials, or the Vidya mark */
.pl-face{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;font-size:calc(var(--hs) * .25);font-weight:650;letter-spacing:.02em;line-height:1;
  text-shadow:0 1px 0 rgba(255,255,255,.4);transition:opacity .4s var(--ease-out) .12s,transform .6s var(--ease-out) .08s,filter .4s var(--ease-out) .1s}
.vd-pl.is-mark .pl-face{text-shadow:none}
.pl-face .mk{width:44%;height:44%}
.vd-p.tiny .pl-face{opacity:0;transition:none}
/* the voice trace: five capsules inside the globe (JS sets each clip-path while you talk) */
.pl-viz{position:absolute;left:50%;top:50%;width:52%;height:40%;margin:-20% 0 0 -26%;display:flex;align-items:center;justify-content:space-between;opacity:0;
  transition:opacity .3s var(--ease-out)}
.pl-viz i{display:block;width:13%;height:100%;background:currentColor;clip-path:inset(41.5% 0 round 999px);transition:clip-path .45s var(--ease-out)}
.pl-stop{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;opacity:0;transform:scale(.6);transition:opacity .2s var(--ease-out),transform .35s var(--ease-out)}
.pl-stop .i{width:26%;height:26%}
.pl-tint{position:absolute;inset:0;border-radius:50%;opacity:0;pointer-events:none;
  background:radial-gradient(circle at 50% 40%,rgba(220,38,38,0) 34%,rgba(220,38,38,.24) 80%,rgba(220,38,38,.42) 100%);transition:opacity .25s var(--ease-out)}
/* a planet's own ring (the library's ringed Twins): the back half behind the sphere, the front half over it.
   At the centre it gives way to the globe's orbit, so it follows how near the planet is (--rgo) */
.vd-rg{position:absolute;left:50%;top:50%;width:calc(var(--hs) * var(--rgw,1.7));height:calc(var(--hs) * var(--rgw,1.7) * .26);box-sizing:border-box;
  margin:calc(var(--hs) * var(--rgw,1.7) * -.13) 0 0 calc(var(--hs) * var(--rgw,1.7) / -2);border-radius:50%;border:calc(var(--hs) * .018) solid var(--rgc,var(--pr));
  transform:rotate(var(--rgt,-14deg));opacity:calc(var(--rgo,1) * .9);pointer-events:none}
.vd-rg.back{clip-path:inset(0 0 50% 0);z-index:1}
.vd-rg.front{clip-path:inset(50% 0 0 0);z-index:3}
.vd-p.tiny .vd-rg,.vd-p.tiny .pl-moon,.vd-p.tiny .pl-draft{display:none}
/* a planet's own moon: an inclined orbit; it passes behind the sphere on the far side and in front on the near */
.pl-moon{position:absolute;left:50%;top:50%;width:0;height:0;z-index:4;transform:rotate(-12deg);opacity:var(--rgo,1);animation:plMoonZ var(--mp,18s) linear infinite}
.pl-moon i{position:absolute;left:0;top:0;animation:plMoonX calc(var(--mp,18s) / 2) cubic-bezier(.37,0,.63,1) infinite alternate}
.pl-moon b{position:absolute;left:0;top:0;width:calc(var(--hs) * var(--ms,.12));height:calc(var(--hs) * var(--ms,.12));margin:calc(var(--hs) * var(--ms,.12) / -2) 0 0 calc(var(--hs) * var(--ms,.12) / -2);
  border-radius:50%;background:radial-gradient(circle at 34% 30%,#FFFFFF 0,var(--p1) 34%,var(--p2) 100%);box-shadow:0 1px 2px rgba(var(--pd),.35);
  animation:plMoonY calc(var(--mp,18s) / 2) cubic-bezier(.37,0,.63,1) calc(var(--mp,18s) / -4) infinite alternate}
@keyframes plMoonX{from{transform:translateX(calc(var(--hs) * var(--mo,1.5) / -2))}to{transform:translateX(calc(var(--hs) * var(--mo,1.5) / 2))}}
@keyframes plMoonY{from{transform:translateY(calc(var(--hs) * var(--mo,1.5) * -.14))}to{transform:translateY(calc(var(--hs) * var(--mo,1.5) * .14))}}
@keyframes plMoonZ{0%,49.9%{z-index:4}50%,100%{z-index:1}}
/* a draft Twin: a faint, unfinished ring */
.pl-draft{position:absolute;inset:-8%;z-index:3;border-radius:50%;border:calc(var(--hs) * .012) dashed rgba(var(--pd),.42);opacity:calc(var(--rgo,1) * .9);pointer-events:none}
.vd-p.is-draft .vd-pl{filter:saturate(.72)}
.vd-p:not(.apex):hover .vd-body{scale:1.07}
.vd-p:active:not(.apex) .vd-body{scale:.95}
/* names: a glass pill on hover or focus; the course code under each planet follows how near it is (--lb) */
.vd-nm{position:absolute;left:0;bottom:calc(var(--hs) * var(--s,1) / 2 + 12px);transform:translate(-50%,5px);white-space:nowrap;display:flex;align-items:center;gap:6px;
  padding:5px 12px;border-radius:999px;font-size:12.5px;font-weight:500;color:var(--fg-2);opacity:0;pointer-events:none;
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),0 10px 26px -14px rgba(0,0,0,.55);
  transition:opacity .25s var(--ease-out),transform .3s var(--ease-out)}
.vd-nm b{color:var(--fg);font-weight:600}
.vd-nm .vd-sub{color:var(--fg-3)}
.vd-nm .vd-sub::before{content:"· "}
.dock.is-up .vd-p:not(.apex):not(.tiny):hover .vd-nm,.dock.is-up .vd-p:not(.apex):not(.tiny):focus-visible .vd-nm{opacity:1;transform:translate(-50%,0)}
.vd-lb{position:absolute;left:0;top:calc(var(--hs) * var(--s,1) / 2 + 7px);transform:translateX(-50%);white-space:nowrap;pointer-events:none;
  font-size:11px;font-weight:500;letter-spacing:.01em;color:var(--fg-3);opacity:var(--lb,0)}
.vd-p:hover .vd-lb,.vd-p.tiny .vd-lb,.dock:not(.is-up) .vd-lb{opacity:0}
.vd-p.flare .vd-pl{animation:vdGlow 1.3s var(--ease-out)}
@keyframes vdGlow{0%{filter:brightness(1)}30%{filter:brightness(1.22)}100%{filter:brightness(1)}}
/* a second moon (a professor's look can have two): its own tilt, and its own place in the orbit */
.pl-moon.m2{transform:rotate(18deg);animation-delay:calc(var(--mp,28s) * -.4)}
.pl-moon.m2 i{animation-delay:calc(var(--mp,28s) * -.4)}
.pl-moon.m2 b{animation-delay:calc(var(--mp,28s) * -.65)}

/* ---------- a Twin's look (LIVE.md 8) ----------
   A photo is the planet's face (rendered with the same lit limb, so it still sits in the orbit): the initials give
   way to it, and while you talk or it answers a soft scrim keeps the trace and the stop readable over any photo */
.av.pl-photo[class*="t-"],.aface.pl-photo[class*="t-"]{color:transparent;text-shadow:none}
.vd-p.pl-photo .pl-face{visibility:hidden}
.vd-p.pl-photo .vd-pl{color:#FFFFFF}
.vd-p.pl-photo .vd-pl::before{content:"";position:absolute;inset:0;border-radius:50%;opacity:0;pointer-events:none;
  background:radial-gradient(circle,rgba(10,11,14,.46) 0,rgba(10,11,14,.24) 62%,rgba(10,11,14,0) 100%);transition:opacity .3s var(--ease-out)}
.dock.is-rec .vd-p.apex.pl-photo .vd-pl::before{opacity:1}
@media (hover:hover){.dock.is-busy.is-hov .vd-p.apex.pl-photo .vd-pl::before{opacity:1}}
@media (hover:none){.dock.is-busy .vd-p.apex.pl-photo .vd-pl::before{opacity:1}}
.vd-p.pl-photo .pl-viz,.vd-p.pl-photo .pl-stop{filter:drop-shadow(0 1px 3px rgba(0,0,0,.45))}
/* a Twin its professor paused: dimmed in the orbit, with a small pause mark by its name and its course */
.vd-p.is-paused .vd-pl{filter:saturate(.35) brightness(.98);opacity:.62}
.vd-p.is-paused.apex .vd-pl{opacity:.8}
.vd-p.is-paused .vd-rg,.vd-p.is-paused .pl-moon{opacity:calc(var(--rgo,1) * .45)}
.vd-p.is-paused .vd-lb::before{content:"";display:inline-block;box-sizing:border-box;width:6px;height:7px;margin-right:4px;vertical-align:-.5px;
  border-left:2px solid currentColor;border-right:2px solid currentColor}
.vd-pz{display:inline-flex;align-items:center;gap:3px}
.vd-pz .i{width:11px;height:11px;fill:currentColor;stroke:none}
/* the dot by the name over the globe: the planet's colour, or its professor's photo */
.vd-nd.is-photo{width:18px;height:18px;margin-left:-5px;background:var(--nd-img) center/cover no-repeat;box-shadow:0 0 0 1px var(--g-line)}

/* ---------- a draft look, before it is saved: Planets.preview(el, id, look) on an element with the class pl-prev
   draws the whole planet (ring and moons included) at --hs ---------- */
.pl-prev{--hs:96px;position:relative;display:inline-block;flex:0 0 auto;width:var(--hs);height:var(--hs);vertical-align:middle}
.pl-prev-in{position:absolute;inset:0}
.pl-prev-s{position:absolute;inset:0;z-index:2;border-radius:50%;
  background:var(--pl-img,radial-gradient(circle at 34% 28%,var(--p1,#F2F5FF),var(--p2,#9DAEEA) 80%)) center/100% 100% no-repeat;
  box-shadow:0 calc(var(--hs) * .2) calc(var(--hs) * .3) calc(var(--hs) * -.19) var(--pg,rgba(95,118,225,.55)),0 calc(var(--hs) * .05) calc(var(--hs) * .12) calc(var(--hs) * -.06) rgba(var(--pd,34,46,128),.3);
  transition:opacity .3s var(--ease-out),filter .3s var(--ease-out)}
.pl-prev.is-paused .pl-prev-s{filter:saturate(.35);opacity:.62}

/* ---------- the globe: the planet at the crest, with a real button over it (#talk) ---------- */
.vd-p.apex .pl-core{animation:glBreathe 4.2s var(--ease-in-out) infinite}
@keyframes glBreathe{0%,100%{transform:scale(1)}50%{transform:scale(1.012)}}
@media (hover:hover){.dock.is-hov .vd-p.apex .pl-core{scale:1.025}}
.dock.is-press .vd-p.apex .pl-core{scale:.965;transition-duration:.16s}
.dock.is-rec .vd-p.apex .pl-core{scale:1.05;transition-duration:.7s}
.dock.is-rec .vd-p.apex .pl-ground{opacity:.7;transform:scaleX(1.06)}
/* talking: the mark melts into the trace; letting go settles it back */
.dock.is-rec .vd-p.apex .pl-face{opacity:0;transform:scale(.6);filter:blur(3px);transition-delay:0s;transition-duration:.2s,.45s,.25s}
.dock.is-rec .vd-p.apex .pl-viz{opacity:1;transition-delay:.08s}
.dock.is-rec .vd-p.apex .pl-viz i{transition:none}
.dock.is-cancel .vd-p.apex .pl-tint{opacity:1}
/* while an answer streams the globe is a stop button (U34): its orbit shimmers; the stop shows on hover, and always on touch */
@media (hover:hover){
  .dock.is-busy.is-hov .vd-p.apex .pl-face{opacity:0;transform:scale(.7);transition-delay:0s}
  .dock.is-busy.is-hov .vd-p.apex .pl-stop{opacity:1;transform:none}
}
@media (hover:none){
  .dock.is-busy .vd-p.apex .pl-face{opacity:0;transform:scale(.7)}
  .dock.is-busy .vd-p.apex .pl-stop{opacity:1;transform:none}
}
.dock.drop .vd-p.apex .vd-pl{box-shadow:0 0 0 5px var(--accent-soft),0 0 0 7px var(--fg-3)}
.vd-globe{position:relative;width:var(--hs);height:var(--hs);border-radius:50%;flex:0 0 auto;padding:0;border:0;background:none;cursor:pointer;
  touch-action:none;user-select:none;-webkit-user-select:none;-webkit-tap-highlight-color:transparent;outline:none}
/* one crisp hairline ripple as it starts to listen (and as a pointer to it) */
.gl-rip{position:absolute;left:50%;top:50%;width:calc(var(--hs) * 2.3);height:calc(var(--hs) * 2.3);margin:calc(var(--hs) * -1.15) 0 0 calc(var(--hs) * -1.15);border-radius:50%;
  border:1px solid var(--gl-rip);opacity:0;transform:scale(.44);pointer-events:none}
.dock.is-rec .gl-rip{animation:glRip 1.25s cubic-bezier(.16,1,.3,1) both}
#talk.hl{animation:none!important}
#talk.hl .gl-rip{animation:glRip 1.25s cubic-bezier(.16,1,.3,1) both}
@keyframes glRip{0%{opacity:.7;transform:scale(.44)}100%{opacity:0;transform:scale(1)}}
/* focus: a clean ring round the sphere, from the globe itself or from the orbit's listbox */
.vd-globe::after{content:"";position:absolute;inset:-6px;border-radius:50%;box-shadow:0 0 0 2px var(--focus);opacity:0;pointer-events:none;transition:opacity .15s var(--ease-out)}
.vd-globe:focus-visible::after,.vd-track:focus-visible~.vd-center .vd-globe::after{opacity:1}
.dock.is-rest:not(.mini) .vd-globe::after{inset:1px}

/* ---------- the name over the globe: who you are talking to; a click opens them ----------
   It rolls with the orbit: the leaving name slides up and out while the arriving one rises in (the track's
   transform follows the turn); the window's soft edges do the rest */
.vd-name{position:absolute;z-index:10;left:50%;bottom:112px;width:0;height:32px;padding:0;border:0;background:none;
  opacity:0;pointer-events:none;transform:translateY(6px);transition:opacity .25s var(--ease-out),transform .45s var(--ease-out)}
.vd-nwin{position:absolute;left:50%;top:50%;width:640px;height:64px;margin:-32px 0 0 -320px;pointer-events:none;
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,transparent 11px,#000 16px,#000 48px,transparent 53px);mask-image:linear-gradient(to bottom,transparent 0,transparent 11px,#000 16px,#000 48px,transparent 53px)}
.vd-ntrack{position:absolute;left:0;right:0;top:16px;height:32px}
.vd-nl{position:absolute;left:50%;top:0;height:32px;transform:translateX(-50%);display:inline-flex;align-items:center;gap:7px;padding:0 9px 0 12px;border-radius:999px;white-space:nowrap;
  font-size:13px;font-weight:500;color:var(--fg-2);pointer-events:auto;
  background:var(--g-glow),color-mix(in srgb,var(--surface) 94%,transparent);border:1px solid var(--g-line);box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow-sm)}
.vd-nl+.vd-nl{top:38px}
.vd-nl b{color:var(--fg);font-weight:600}
.vd-nl .vd-ns{color:var(--fg-3)}
.vd-nl .vd-ns::before{content:"· "}
.vd-nd{width:7px;height:7px;border-radius:50%;background:var(--nd,var(--fg));flex:0 0 auto}
.vd-eye{display:inline-flex;align-items:center;color:var(--fg-3)}
.vd-eye .i{stroke-width:1.5}
.vd-nl>.i{color:var(--fg-3);flex:0 0 auto;margin-left:-1px;transition:transform .25s var(--ease-out),color .2s var(--ease-out)}
.vd-name:hover .vd-nl{border-color:var(--line-2)}
.vd-name:hover .vd-nl>.i{color:var(--fg);transform:translateX(2px)}
.vd-name:focus-visible .vd-nl{outline:2px solid var(--focus);outline-offset:2px}
.dock.is-up:not(.mini) .vd-name{opacity:1;pointer-events:auto;transform:none}
.dock.is-up.is-rec:not(.mini) .vd-name{opacity:0;pointer-events:none;transform:translateY(6px);transition-duration:.12s,.3s}

/* ---------- Type and Speak to text: glass circles beside the globe (planets gliding by pass behind the glass) ---------- */
.vd-side{pointer-events:auto;position:relative;z-index:9;width:54px;height:54px;margin-bottom:23px;border-radius:50%;display:flex;align-items:center;justify-content:center;flex:0 0 auto;
  background:var(--g-glow),var(--g-fill);border:1px solid var(--g-line);color:var(--fg-2);
  -webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);box-shadow:inset 0 1px 0 var(--g-hi),0 8px 22px -12px rgba(0,0,0,.45);
  --tx:0px;--ty:0px;--sc:1;transform:translate(var(--tx),var(--ty)) scale(var(--sc));
  transition:transform .5s var(--ease-out),background-color .25s var(--ease-out),color .25s var(--ease-out),border-color .25s var(--ease-out),opacity .3s var(--ease-out)}
.vd-side::after,.vd-typerow::after,.vd-pill::after,.vd-hf::after{content:"";position:absolute;inset:0;border-radius:inherit;padding:1px;pointer-events:none;z-index:3;background:var(--g-rim);
  -webkit-mask:linear-gradient(#000 0 0) content-box,linear-gradient(#000 0 0);-webkit-mask-composite:xor;mask-composite:exclude}
.vd-side::after,.vd-pill::after,.vd-hf::after{opacity:.8}
.vd-side:hover{border-color:var(--line-2);color:var(--fg);--ty:-2px}
.vd-side:active{--sc:.92}
.vd-side .i{width:21px;height:21px}
.vd-side .s-mic{display:none}
.vd-side[aria-pressed="true"]{background:var(--btn);border-color:var(--btn);color:var(--on-btn)}
.dock.m-type #bType .s-kb{display:none}.dock.m-type #bType .s-mic{display:block}
/* in voice mode the centre is only as wide as the globe, so the circles sit beside it, clear of its orbit */
.dock:not(.m-type):not(.m-scribe) #bType{--tx:calc(var(--cw,520px) / 2 - 69px)}
.dock:not(.m-type):not(.m-scribe) #bScribe{--tx:calc(145px - var(--cw,520px) / 2)}
.vd-sl{position:absolute;top:calc(100% + 8px);left:50%;transform:translateX(-50%);font-size:11px;font-weight:500;color:var(--fg-3);white-space:nowrap;pointer-events:none;transition:opacity .25s var(--ease-out)}
.vd-side[aria-pressed="true"] .vd-sl{color:var(--fg)}
.dock.is-rec .vd-side{opacity:.25;pointer-events:none}
.dock.is-up.is-turning:not(.is-rec) .vd-side{opacity:.22;--sc:.94;transition-duration:.5s,.25s,.25s,.25s,.18s}
/* U34: a draft that is not on show still says it is there */
.vd-dd{position:absolute;top:5px;right:5px;width:9px;height:9px;border-radius:50%;background:var(--fg);box-shadow:0 0 0 2px var(--bg);opacity:0;transform:scale(.4);
  transition:opacity .2s var(--ease-out),transform .3s var(--ease-out);pointer-events:none}
.dock.has-draft #bType .vd-dd{opacity:1;transform:none}

/* ---------- Hands-free: its own round button, right of the globe (open, at rest, on the mini dock) ---------- */
.vd-hf{position:absolute;z-index:9;left:50%;top:50%;width:54px;height:54px;margin:-27px 0 0 -27px;border-radius:50%;display:flex;align-items:center;justify-content:center;
  background:var(--g-glow),var(--g-fill);border:1px solid var(--g-line);color:var(--fg-2);pointer-events:auto;
  -webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);box-shadow:inset 0 1px 0 var(--g-hi),0 8px 22px -12px rgba(0,0,0,.45);
  --hx:120px;--hsc:1;transform:translateX(var(--hx)) scale(var(--hsc));
  transition:transform .5s var(--ease-out),background-color .25s var(--ease-out),color .25s var(--ease-out),border-color .25s var(--ease-out),opacity .3s var(--ease-out)}
.vd-hf .i{width:22px;height:22px}
.vd-hf:hover{border-color:var(--line-2);color:var(--fg)}
.vd-hf:active{--hsc:.92}
.vd-hf[aria-pressed="true"]{background:var(--btn);border-color:var(--btn);color:var(--on-btn)}
.vd-hf[aria-pressed="true"]::after{opacity:0}
.vd-hf .vd-sl{transition:opacity .25s var(--ease-out)}
.dock.is-rest .vd-hf{--hx:119px;--hsc:.852}
.dock.is-rest .vd-hf .vd-sl{opacity:0}
.dock.m-type .vd-hf,.dock.m-scribe .vd-hf{opacity:0;--hsc:.35;pointer-events:none}
.dock.is-rec .vd-hf{opacity:.25;pointer-events:none}
.dock.is-up.is-turning:not(.is-rec) .vd-hf{opacity:.22;--hsc:.94}

/* ---------- at rest: the text pill (U11) on the left of the globe ---------- */
.vd-pill{position:absolute;z-index:9;top:50%;height:46px;display:inline-flex;align-items:center;border-radius:999px;white-space:nowrap;pointer-events:none;
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow-sm);opacity:0;
  transition:opacity .28s var(--ease-out),transform .45s var(--ease-out),color .2s var(--ease-out),border-color .2s var(--ease-out),background-color .2s var(--ease-out)}
.vd-pill{right:calc(50% + 92px);max-width:min(380px,calc(50% - 104px));gap:9px;padding:0 9px 0 15px;font-size:14px;color:var(--fg-3);transform:translate(28px,-50%) scale(.96)}
.vd-pill .pk{color:var(--fg-3);flex:0 0 auto}
.vd-pill .vd-pa{overflow:hidden;text-overflow:ellipsis;min-width:0;flex:0 1 auto}
.vd-pill.is-long .vd-pb{display:none}
.vd-pill .kbd{margin-left:auto;flex:0 0 auto}
.vd-pill .vd-pm{display:none}
.vd-pill:hover{color:var(--fg-2);border-color:var(--line-2)}
.vd-pill .vd-dd{position:static;flex:0 0 auto;box-shadow:none;width:7px;height:7px;display:none}
.dock.has-draft .vd-pill{color:var(--fg)}
.dock.has-draft .vd-pill .vd-dd{display:block;opacity:1;transform:none}
.dock.has-draft .vd-pill .pk,.dock.has-draft .vd-pill .vd-pb{display:none}
.vd-pin.bump{animation:vdBumpS .5s var(--ease-out)}
@keyframes vdBumpS{0%{transform:scale(.94)}100%{transform:none}}
.dock.is-rest .vd-pill{opacity:1;pointer-events:auto;transform:translate(0,-50%)}
.dock.is-rest .vd-side{opacity:0;--sc:.35;pointer-events:none}
.dock.is-rest .vd-sl{opacity:0}

/* ---------- the centre: the globe's control, the text row, or speak to text ---------- */
.vd-center{position:relative;z-index:8;flex:0 0 auto;width:var(--cw,520px);min-height:100px;display:flex;flex-direction:column;justify-content:flex-end;pointer-events:none;
  transition:transform .42s var(--ease-out)}
.vd-pane{opacity:0;pointer-events:none;transition:opacity .24s var(--ease-out),transform .42s var(--ease-out),clip-path .46s var(--ease-soft)}
.vd-pane.on{opacity:1;pointer-events:auto}
.vd-pv,.vd-ps{position:absolute;left:0;right:0;bottom:0;height:100px;display:flex;align-items:center;justify-content:center;z-index:2}
.vd-ps{height:84px}
.vd-pv{transform:scale(.9)}
.vd-pv.on{transform:none;pointer-events:none}
.vd-pv.on .vd-globe{pointer-events:auto}
/* the text row opens out of the globe (13: clip-path, not width) */
.vd-pt{position:relative;padding:22px 0;clip-path:inset(22px calc(50% - 28px) 22px round 28px)}
.vd-ps{padding:14px 0;clip-path:inset(14px calc(50% - 28px) 14px round 28px)}
.vd-pt.on,.vd-ps.on{clip-path:inset(-44px -44px -44px -44px round 72px)}

/* the text row: dense glass with an edge-lit rim */
.vd-typerow{position:relative;min-height:56px;display:flex;align-items:flex-end;gap:2px;padding:6px;border-radius:28px;
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow);transition:border-color .2s var(--ease-out),box-shadow .2s var(--ease-out)}
.vd-typerow:focus-within{border-color:var(--line-2);box-shadow:0 0 0 4px var(--accent-soft),inset 0 1px 0 var(--g-hi),var(--g-shadow)}
.vd-typerow textarea{flex:1;min-width:0;border:0;outline:none;background:transparent;resize:none;font:inherit;font-size:15.5px;line-height:1.5;padding:9px 6px;height:42px;max-height:120px;color:var(--fg)}
.vd-typerow textarea::placeholder{color:var(--fg-3);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.vd-typerow .attchip{align-self:center;max-width:36%;flex:0 1 auto}
.vd-tbtn{width:42px;height:42px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--fg-2);flex:0 0 auto;transition:background-color .2s var(--ease-out),color .2s var(--ease-out)}
.vd-tbtn:hover{background:var(--accent-soft);color:var(--fg)}
.vd-tbtn.on{background:var(--btn);color:var(--on-btn)}
.vd-tbtn.on .i{animation:pulse 1.1s var(--ease-in-out) infinite}
.vd-send{width:42px;height:42px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;background:var(--btn);color:var(--on-btn);flex:0 0 auto;
  transition:transform .3s var(--ease-out),opacity .2s var(--ease-out)}
.vd-send:hover{filter:brightness(1.12)}
.vd-send[disabled]{opacity:.3;transform:scale(.88);pointer-events:none}
/* who answers, inside the text row (U21, B41): automatic shows nothing here (the name over the globe says it);
   a pinned Twin is one small chip left of the words: its planet, its short name, and an x back to automatic */
.scope-wrap{display:flex;align-items:center;flex:0 1 auto;min-width:0;max-width:44%;margin:0 2px 3px 0}
.scope-wrap[hidden]{display:none}
.vd-pin{display:inline-flex;align-items:center;min-width:0;height:34px;padding:0 2px 0 3px;border-radius:999px;background:var(--sunken);box-shadow:inset 0 0 0 1px var(--line);
  animation:vdPinIn .42s var(--ease-out) both}
@keyframes vdPinIn{from{opacity:0;transform:scale(.92)}to{opacity:1;transform:none}}
.vd-pin-b{display:inline-flex;align-items:center;gap:7px;min-width:0;height:30px;padding:0 4px 0 2px;border-radius:999px;font-size:13px;font-weight:600;color:var(--fg);
  transition:background-color .2s var(--ease-out)}
.vd-pin-b:hover{background:var(--accent-soft)}
.vd-pin .av.s20{width:24px;height:24px;font-size:9px;flex:0 0 auto}
.vd-pin-n{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0}
.vd-pin-x{width:26px;height:26px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;color:var(--fg-3);
  transition:background-color .2s var(--ease-out),color .2s var(--ease-out)}
.vd-pin-x .i{width:14px;height:14px}
.vd-pin-x:hover{background:var(--accent-soft);color:var(--fg)}

.vd-scribe{width:100%;height:56px;display:flex;align-items:center;justify-content:center;gap:12px;border-radius:28px;border:1.5px dashed var(--fg-4);
  background:var(--g-fill-2);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  color:var(--fg);font-size:14px;font-weight:500;transition:background-color .25s var(--ease-out),color .25s var(--ease-out),border-color .25s var(--ease-out)}
.vd-scribe:hover{background:var(--accent-soft)}
.vd-scribe.is-rec{background:var(--btn);border-style:solid;border-color:var(--btn);color:var(--on-btn)}
.vd-eq{display:flex;gap:3px;align-items:center;height:16px}
.vd-eq i{width:3px;height:100%;border-radius:2px;background:currentColor;transform:scaleY(.4)}
.vd-scribe.is-rec .vd-eq i{animation:vdEq .9s var(--ease-in-out) infinite}
.vd-eq i:nth-child(2){animation-delay:.12s}.vd-eq i:nth-child(3){animation-delay:.24s}.vd-eq i:nth-child(4){animation-delay:.36s}.vd-eq i:nth-child(5){animation-delay:.48s}
@keyframes vdEq{0%,100%{transform:scaleY(.3)}50%{transform:scaleY(1)}}

/* ---------- under the row: one line. What the globe does and costs (hands-free: its state, Mute and Done) ---------- */
.vd-under{position:relative;z-index:2;margin-top:12px;height:30px;max-width:100%;display:flex;align-items:center;justify-content:center;gap:2px}
.vd-state{display:flex;align-items:center;gap:7px;min-width:0;font-size:13px;font-weight:500;color:var(--fg-2);white-space:nowrap}
.vd-state.on::before{content:"";width:7px;height:7px;border-radius:50%;background:var(--clay);flex:0 0 auto;animation:vdRecDot 1.6s var(--ease-in-out) infinite}
@keyframes vdRecDot{0%,100%{opacity:1}50%{opacity:.4}}
.vd-state.swap{animation:fadeSwap .3s var(--ease-out)}
.dock.m-type .vd-state,.dock.m-scribe .vd-state{font-size:12px;color:var(--fg-3)}
/* compact: while typing and while resting, the bar sits low and the hint is one quiet line right under it
   (the side buttons keep their names as tooltips, so their label room is not reserved) */
.dock.m-type .vd-side{margin-bottom:0}
.dock.m-type .vd-pt{padding-bottom:0}
.dock.m-type .vd-sl{opacity:0}
.dock.m-type .vd-under,.dock.is-rest .vd-under{margin-top:6px;height:20px}
.dock.m-type .vd-state,.dock.is-rest .vd-state{font-size:11.5px;color:var(--fg-3)}
/* typing: the pill and the globe are one group, centred. The globe (hold to talk, a tap goes back to voice) sits right
   of the pill, where Speak to text was; speak to text is the mic inside the pill. One mic and one Vidya on screen */
.dock.m-type #bType,.dock.m-type #bScribe{display:none}
.d .dock.m-type .vd-center{transform:translateX(-32px)}
.d .dock.m-type .vd-pv{opacity:1;transform:none;height:56px}
.d .dock.m-type .vd-pv .vd-globe{pointer-events:auto;transform:translateX(calc(var(--cw,520px) / 2 + 37px)) scale(.5625)}
/* the dock box holds only what shows, so --dockH (the thread's bottom padding) shrinks with it: typing, the row is the
   text row; resting, the row's empty top tucks under the band (the globe's centre stays where it is) */
.d .dock.m-type .vd-in{padding-top:8px}
.d .dock.m-type:not(.lay-ph) .vd-row,.d .dock.m-type:not(.lay-ph) .vd-center{min-height:0}
.d .dock.m-type:not(.lay-ph) .vd-pt{padding-top:8px}
.d .dock.is-rest:not(.mini):not(.lay-ph):not(.lay-ls):not(.is-hands) .vd-row{margin-top:-14px}
.d .dock.is-rest:not(.mini):not(.lay-ph):not(.lay-ls):not(.is-hands) .vd-note{margin-bottom:24px}

/* ---------- hands-free ----------
   The globe carries it: its ring of dots opens into a circle of capsules (canvas). Under the globe, one line says the
   state; Mute and Done sit right beside it. The pill and the text box stay as they are, so typing still works. */
.hf-ctl{display:inline-flex;align-items:center;gap:4px;margin-left:10px;opacity:0;transform:translateX(-4px);pointer-events:none;
  transition:opacity .25s var(--ease-out),transform .45s var(--ease-out)}
.dock.is-hands .hf-ctl{opacity:1;transform:none;pointer-events:auto}
.dock:not(.is-hands) .hf-ctl{position:absolute;visibility:hidden}
.hf-b{width:30px;height:30px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--fg-2);flex:0 0 auto;
  background:var(--g-glow),var(--g-fill-2);border:1px solid var(--g-line);box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow-sm);
  transition:background-color .2s var(--ease-out),color .2s var(--ease-out),transform .16s var(--ease-out)}
.hf-b .i{width:15px;height:15px}
.hf-b:hover{color:var(--fg);border-color:var(--line-2)}
.hf-b:active{transform:scale(.94)}
.hf-b[aria-pressed="true"]{background:var(--btn);border-color:var(--btn);color:var(--on-btn)}
.hf-done{background:var(--btn);border-color:var(--btn);color:var(--on-btn)}
.hf-done:hover{color:var(--on-btn);filter:brightness(1.12)}
.dock.is-hands .vd-state{color:var(--fg);font-weight:600}
.dock.is-hands.hv-muted .vd-state,.dock.is-hands.hv-thinking .vd-state{color:var(--fg-2)}
/* the Twin's empathic line keeps a quiet prism, drawn as a hairline under the words so the words stay ink (AA) */
.msg.a .a-body .aff{background-image:var(--prism);background-size:100% 1.5px;background-position:0 100%;background-repeat:no-repeat;padding-bottom:1px}
/* the one line a hands-free stretch leaves in the thread */
.msg.sys.vdone{display:flex;align-items:center;gap:12px;margin:6px 0 2px;font-size:12px;font-weight:500;color:var(--fg-3)}
.msg.sys.vdone>i{flex:1;height:1px;background:var(--line)}
.msg.sys.vdone>span{display:inline-flex;align-items:center;gap:6px}
.msg.sys.vdone .i{width:14px;height:14px}

/* ---------- what you are saying, in a bubble over the globe ---------- */
.vd-cap{position:absolute;left:50%;bottom:calc(100% + 16px);z-index:11;transform:translateX(-50%);width:max-content;max-width:min(560px,86%);padding:11px 18px;border-radius:18px;
  background:var(--g-glow),var(--g-fill);border:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur);
  box-shadow:inset 0 1px 0 var(--g-hi),var(--g-shadow);font-size:15px;line-height:1.4;color:var(--fg);display:flex;align-items:center;gap:10px;
  animation:vdCapIn .4s var(--ease-out) both}
.vd-cap[hidden]{display:none}
.vd-cap::after{content:"";position:absolute;left:50%;bottom:-6px;width:12px;height:12px;margin-left:-6px;transform:rotate(45deg);
  background:var(--g-fill-2);border-right:1px solid var(--g-line);border-bottom:1px solid var(--g-line);-webkit-backdrop-filter:var(--g-blur);backdrop-filter:var(--g-blur)}
.vd-cap.out{animation:vdCapOut .18s var(--ease-in) forwards}
.vd-dot{width:8px;height:8px;border-radius:50%;background:var(--clay);flex:0 0 auto;animation:vdRecDot 1.6s var(--ease-in-out) infinite}
@keyframes vdCapIn{from{opacity:0;transform:translate(-50%,10px) scale(.96)}to{opacity:1;transform:translateX(-50%)}}
@keyframes vdCapOut{to{opacity:0;transform:translate(-50%,-6px) scale(.97)}}
/* typing, the words rise over the small globe at the text row's right */
.dock.m-type .vd-cap{left:auto;right:calc(50% - var(--cw,520px) / 2 - 32px);transform:none;animation-name:fadeUp}
.dock.m-type .vd-cap::after{left:auto;right:21px}
.dock.m-type .vd-cap.out{animation:fadeOut .18s var(--ease-in) forwards}
.dock.lay-ls.m-type .vd-cap{right:calc(50% - var(--cw,520px) / 2 - 27px)}
.dock.lay-ls.m-type .vd-cap::after{right:16px}
.dock.lay-ph.m-type .vd-cap{right:4px;max-width:calc(100% - 8px)}
.dock.lay-ph.m-type .vd-cap::after{right:18px}

/* ---------- the mini dock: one row, at most 72px, on dashboards (B15, U07) ---------- */
.d .dock.vdock.mini{padding-bottom:calc(8px + env(safe-area-inset-bottom,0px))}
.dock.mini .vd-in{padding-top:8px}
.dock.mini .vd-row{--hs:54px;min-height:56px}
.dock.mini .vd-center{width:56px;min-height:56px}
.dock.mini .vd-pv{height:56px}
.dock.mini .vd-under,.dock.mini .vd-side,.dock.mini .vd-note,.dock.mini .vd-pt,.dock.mini .vd-ps,.dock.mini .vd-name{display:none}
.dock.mini .vd-pill{right:calc(50% + 66px);height:42px}
.dock.mini .vd-hf,.dock.mini.is-rest .vd-hf{--hx:78px;--hsc:.78}

/* ---------- phones (DESIGN 0 #16): the whole system, as a dome over the thumb zone ----------
   The Twins ride a dotted dome over the controls (web-voice.js draws and places it). Type (a pill) sits on the globe's
   left; Speak to text and Hands-free on its right, so the row balances; the name sits over the globe, one quiet line
   under it. The globe's size is its button's scale (collapsed .7, typing .6) and the planet follows it. Collapsed, the
   row tucks under the band so the globe's centre never moves, only its size. */
.d .dock.vdock.lay-ph{padding:0 12px calc(8px + env(safe-area-inset-bottom,0px))}
.d .dock.vdock.lay-ph::before{transform:translateY(176px)}
.d .dock.vdock.lay-ph.is-up::before{transform:translateY(max(0px,calc(164px - var(--vd-rise,90px))))}
.dock.lay-ph .vd-in{padding-top:6px}
.d .dock.lay-ph .vd-row{--hs:80px;min-height:84px;gap:0;align-items:flex-end}
.d .dock.lay-ph.is-rest:not(.is-hands) .vd-row{margin-top:-24px}
.d .dock.lay-ph.is-rest:not(.is-hands) .vd-note{margin-bottom:34px}
.d .dock.lay-ph.is-hands .vd-row{margin-top:14px}
/* a swipe anywhere over the dome turns it */
.dock.lay-ph .vd-hit{top:calc(-1 * var(--vd-rise,90px) - 6px);bottom:36px}
.dock.lay-ph #bType,.dock.lay-ph .vd-sl,.dock.lay-ph .vd-lb,.dock.lay-ph .vd-ps{display:none}
/* the globe */
.d .dock.lay-ph .vd-center{width:100%;min-height:84px}
.d .dock.lay-ph .vd-pv{height:84px}
.d .dock.lay-ph.is-rest .vd-globe{transform:scale(.7)}
.d .dock.lay-ph.is-rest.is-hands .vd-globe,.d .dock.lay-ph.is-rec:not(.m-type) .vd-globe{transform:none}
.d .dock.lay-ph .vd-globe::after{inset:-6px}
.dock.lay-ph .gl-rip{width:calc(var(--hs) * 2);height:calc(var(--hs) * 2);margin:calc(var(--hs) * -1) 0 0 calc(var(--hs) * -1)}
@keyframes glRipN{0%{opacity:.7;transform:scale(.5)}100%{opacity:0;transform:scale(1)}}
.dock.lay-ph.is-rec .gl-rip,.dock.lay-ph #talk.hl .gl-rip{animation-name:glRipN}
/* the name over the globe */
.dock.lay-ph .vd-name{bottom:90px}
.dock.lay-ph .vd-nwin{width:min(640px,100vw);margin-left:calc(min(640px,100vw) / -2)}
/* while the dome turns, the planet at the crest dives through here: the name steps aside, then comes back */
.dock.lay-ph.is-up.is-turning:not(.mini) .vd-name{opacity:0;pointer-events:none;transition-duration:.14s,.3s}
/* Type: a pill as wide as the two circles on the globe's other side */
.d .dock.lay-ph .vd-pill{right:calc(50% + 60px);width:100px;max-width:none;height:46px;padding:0 12px;justify-content:center;gap:8px;font-size:14.5px;color:var(--fg-2)}
.d .dock.lay-ph:not(.m-type) .vd-pill{opacity:1;pointer-events:auto;transform:translate(0,-50%)}
.dock.lay-ph .vd-pill .vd-pa,.dock.lay-ph .vd-pill .kbd{display:none}
.dock.lay-ph .vd-pill .vd-pm{display:inline}
.dock.lay-ph.has-draft .vd-pill .vd-pa{display:block}
.dock.lay-ph.has-draft .vd-pill .vd-pm{display:none}
/* Speak to text (the one mic) and Hands-free */
.d .dock.lay-ph #bScribe{position:absolute;left:calc(50% + 60px);top:50%;width:46px;height:46px;margin:-23px 0 0;--tx:0px;opacity:1;--sc:1;pointer-events:auto}
.d .dock.lay-ph.mini #bScribe{display:flex}
.d .dock.lay-ph #hands{width:46px;height:46px;margin:-23px 0 0 -23px;--hx:137px;--hsc:1}
.d .dock.lay-ph.is-turning:not(.is-rec) #hands{opacity:1}
.d .dock.lay-ph.is-rec .vd-pill,.d .dock.lay-ph.is-rec #bScribe,.d .dock.lay-ph.is-rec #hands{opacity:.25;pointer-events:none}
.d .dock.lay-ph.m-type .vd-pill,.d .dock.lay-ph.m-type #bScribe,.d .dock.lay-ph.m-type #hands{opacity:0;pointer-events:none}
.d .dock.lay-ph.m-type #bScribe{--sc:.6}
.d .dock.lay-ph.m-type #hands{--hsc:.6}
/* hands-free: Mute (in the line under the globe) is the only mic; Hands-free moves into Speak to text's place */
.d .dock.lay-ph.is-hands #bScribe{opacity:0;--sc:.6;pointer-events:none}
.d .dock.lay-ph.is-hands #hands{--hx:83px}
/* one quiet line under the globe; hands-free, Mute and Done beside it at a full 44px */
.d .dock.lay-ph .vd-under{margin-top:6px;height:20px}
.d .dock.lay-ph.is-hands .vd-under{height:44px}
.dock.lay-ph .vd-state{font-size:11.5px}
.d .dock.lay-ph .hf-b{position:relative;width:38px;height:38px}
.dock.lay-ph .hf-b::before{content:"";position:absolute;inset:-3px;border-radius:50%}
.dock.lay-ph .hf-b .i{width:16px;height:16px}
/* typing: the text row opens out of the Type pill; the globe (hold to talk, a tap goes back to voice) waits at its right */
.d .dock.lay-ph .vd-pt{padding:14px 0;clip-path:inset(19px calc(50% + 60px) 19px calc(50% - 160px) round 23px)}
.d .dock.lay-ph .vd-pt.on{clip-path:inset(-44px -44px -44px -44px round 72px)}
.d .dock.lay-ph.m-type .vd-row{min-height:0}
.d .dock.lay-ph.m-type .vd-center{min-height:0;transform:none}
.d .dock.lay-ph.m-type .vd-pt{padding:6px 60px 0 0}
.d .dock.lay-ph.m-type .vd-pv{height:56px}
.d .dock.lay-ph.m-type .vd-pv .vd-globe{transform:translateX(calc(var(--cw,360px) / 2 - 28px)) scale(.6)}
.dock.lay-ph .vd-typerow{padding:6px}
.dock.lay-ph .vd-tbtn,.dock.lay-ph .vd-send{width:44px;height:44px}
/* empty: [+] [words] [mic]; with words, Send joins them (Hands-free lives on the voice dock, never in the text row) */
.dock.lay-ph .vd-typerow.is-empty .vd-send{display:none}
.dock.lay-ph.is-busy .vd-typerow .vd-send{display:inline-flex}
/* a pinned Twin: its planet and the x (the prompt carries the name), each a 44px target */
.dock.lay-ph .scope-wrap{max-width:none;flex:0 0 auto}
.dock.lay-ph .vd-pin-n{display:none}
.dock.lay-ph .vd-pin-b{padding:0 1px;position:relative}
.dock.lay-ph .vd-pin-x{position:relative}
.dock.lay-ph .vd-pin-b::before,.dock.lay-ph .vd-pin-x::before{content:"";position:absolute;inset:-7px -4px}
@media (max-width:374px){.dock.lay-ph .vd-typerow.is-pinned #tDict{display:none}}
/* the professor's mini dock on a phone: the same row, collapsed, 72px (a tap opens the conversation, orbit up) */
.d .dock.lay-ph.mini .vd-in{padding-top:4px}

/* ---------- a short landscape screen (a phone on its side): the desktop row, compacted; it starts set ---------- */
.d .dock.vdock.lay-ls{padding:0 16px calc(6px + env(safe-area-inset-bottom,0px))}
.dock.lay-ls .vd-in{padding-top:6px}
.d .dock.lay-ls:not(.mini) .vd-row{--hs:60px;min-height:64px;gap:16px}
.d .dock.lay-ls:not(.mini) .vd-center{min-height:64px}
.d .dock.lay-ls:not(.mini) .vd-pv{height:64px}
.d .dock.lay-ls .vd-pt{padding:4px 0;clip-path:inset(4px calc(50% - 28px) 4px round 28px)}
.d .dock.lay-ls .vd-ps{height:64px;padding:4px 0;clip-path:inset(4px calc(50% - 28px) 4px round 28px)}
.d .dock.lay-ls .vd-pt.on,.d .dock.lay-ls .vd-ps.on{clip-path:inset(-44px -44px -44px -44px round 72px)}
.d .dock.lay-ls .vd-side{width:44px;height:44px;margin-bottom:10px}
.dock.lay-ls .vd-sl{display:none}
.d .dock.lay-ls:not(.m-type):not(.m-scribe) #bType{--tx:calc(var(--cw,520px) / 2 - 36px)}
.d .dock.lay-ls:not(.m-type):not(.m-scribe) #bScribe{--tx:calc(88px - var(--cw,520px) / 2)}
.d .dock.lay-ls .vd-hf{width:44px;height:44px;margin:-22px 0 0 -22px;--hx:74px}
.d .dock.lay-ls.is-rest .vd-hf{--hx:78px;--hsc:.95}
.d .dock.lay-ls .vd-pill{right:calc(50% + 56px);height:42px}
.dock.lay-ls .vd-pill .vd-pb,.dock.lay-ls .vd-pill .kbd{display:none}
.dock.lay-ls .vd-name{bottom:72px}
.d .dock.lay-ls .vd-under{margin-top:4px;height:18px}
.dock.lay-ls .vd-state{font-size:11.5px}
.d .dock.lay-ls.m-type .vd-pt{padding-bottom:0}
.d .dock.lay-ls.m-type:not(.mini) .vd-pv{height:56px}
.d .dock.lay-ls.m-type .vd-center{transform:translateX(-27px)}
.d .dock.lay-ls.m-type .vd-pv .vd-globe{transform:translateX(calc(var(--cw,520px) / 2 + 32px)) scale(.7333)}

/* ---------- fallbacks: no backdrop-filter, or less transparency asked for (5.3) ---------- */
@supports not ((backdrop-filter:blur(1px)) or (-webkit-backdrop-filter:blur(1px))){
  .vd-typerow,.vd-side,.vd-pill,.vd-note,.vd-cap,.vd-cap::after,.vd-scribe,.vd-nm,.vd-nl,.vd-hf,.hf-b{background:var(--surface)}
  .d .dock.vdock::before{-webkit-mask-image:none;mask-image:none}
}
@media (prefers-reduced-transparency:reduce){
  .vd-typerow,.vd-side,.vd-pill,.vd-note,.vd-cap,.vd-cap::after,.vd-scribe,.vd-nm,.vd-nl,.vd-hf,.hf-b{background:var(--surface);-webkit-backdrop-filter:none;backdrop-filter:none}
  .d .dock.vdock::before{-webkit-backdrop-filter:none;backdrop-filter:none;-webkit-mask-image:none;mask-image:none}
}
/* reduced motion: no breathing, no ripple, no moons in orbit; states swap at once (the canvas stops its own motion) */
@media (prefers-reduced-motion:reduce){
  .vd-p.apex .pl-core,.pl-moon,.pl-moon i,.pl-moon b,.gl-rip,.vd-p.flare .vd-pl,.vd-state.on::before,.vd-dot{animation:none!important}
  .d .dock.vdock::before,.d .dock.vdock::after,.vd-side,.vd-pill,.vd-pane,.vd-center,.vd-name,.pl-core,.pl-face,.pl-viz,.pl-viz i,.pl-stop,.pl-tint,.vd-body,.vd-hf,.hf-ctl,.vd-pl::before,.pl-prev-s,.vd-note-x{transition-duration:.01ms!important;transition-delay:0s!important}
}

