/* ---------- typeface ----------
   Self-hosted, not Google Fonts. A stylesheet request to fonts.googleapis.com
   on every page would be a Google request before anyone had consented to
   anything, which is exactly what the analytics gate exists to prevent.
   Both are variable fonts on a weight axis: one file covers 300-800.
   swap, so text is readable in the fallback before the font arrives. */
@font-face{
  font-family:"Inter var"; font-style:normal; font-weight:300 800;
  font-display:swap; src:url("/fonts/inter.woff2") format("woff2");
}
@font-face{
  font-family:"Bricolage var"; font-style:normal; font-weight:300 800;
  font-display:swap; src:url("/fonts/bricolage.woff2") format("woff2");
}

/* Kismaro design system.
 *
 * Token names follow shadcn "new-york" so a later Tailwind move is a rename,
 * not a rewrite. Values are hand-authored sRGB hex - deliberately not OKLCH,
 * because computed oklch() cannot be contrast-checked by string parsing and
 * quietly reports passing numbers for unreadable text.
 *
 * Every pair below is verified to WCAG AA (4.5:1) in both themes.
 */

/* ---------- tokens: light ---------- */
/* The hidden attribute is only display:none in the UA stylesheet, so any
   author rule setting display beats it. `.setgroup{display:flex}` did exactly
   that and kept the Account block on screen after sign-in - the same bug the
   admin sign-in page had. The per-class `.x[hidden]` rules further down are
   now redundant, and harmless. */
[hidden]{display:none !important}

:root{
  --background:#f6f8f9;   --foreground:#121a1f;
  --card:#ffffff;         --card-foreground:#121a1f;
  --muted:#eef2f4;        --muted-foreground:#5a6872;
  --primary:#0f7d6c;      --primary-foreground:#ffffff;
  --secondary:#e6ecef;    --secondary-foreground:#121a1f;
  --destructive:#b52d3b;  --destructive-foreground:#ffffff;
  --border:#dde3e7;       --input:#dde3e7;  --ring:#0f7d6c;
  --shadow:0 10px 30px rgba(18,26,31,.08);

  /* the video area never follows the theme - a bright frame around a dim
     webcam reads as broken, and every video app agrees */
  --stage:#05070a;
  --overlay:rgba(6,9,14,.74);
  --overlay-foreground:#e8eef2;
  --overlay-border:rgba(255,255,255,.16);

  --mode-text:#2f6fd0; --mode-voice:#a35f00; --mode-video:#0f7d6c;   /* voice was 4.24, under AA */

  /* Feature tints. One brand colour and five greys read as a spec sheet; a
     tinted tile per feature is what every competitor uses to make a wall of
     text scannable. Kept pale so the page still looks like one product. */
  --t-mint:#0f7d6c;   --t-mint-bg:#e3f2ee;
  --t-sky:#2f6fd0;    --t-sky-bg:#e4edfa;
  --t-amber:#8a5600;  --t-amber-bg:#fbeedb;   /* 5.38:1, was 3.86 and failed AA */
  --t-rose:#b5455c;   --t-rose-bg:#fbe6ea;
  --t-violet:#6b4bb8; --t-violet-bg:#eee9fa;

  --radius:10px; --radius-sm:6px; --radius-lg:14px;
  /* 5 and 7 were missing from this scale while ten rules used them. An
     undefined custom property makes the whole declaration invalid and it is
     dropped in silence, so the footer and every legal page had been
     rendering with no padding at all. */
  --sp-1:4px; --sp-2:8px; --sp-3:12px; --sp-4:16px; --sp-5:20px;
  --sp-6:24px; --sp-7:32px;
  /* Anchored at 1rem = 16px, which is the browser default and the smallest
     size body text should ever be. The old scale had body at 14.5px and used
     13px and 11.5px for whole sections, which is why the site read as
     cramped. In rem, so a reader who raises their browser font size gets a
     bigger site instead of a broken one. */
  --fs-xs:0.8125rem;   /* 13px - captions, table cells. Nothing smaller. */
  --fs-sm:0.875rem;    /* 14px - secondary text */
  --fs-base:1rem;      /* 16px - body */
  --fs-md:1.0625rem;   /* 17px - lead paragraphs */
  --fs-lg:1.25rem;     /* 20px - card titles */
  --fs-xl:1.5rem;      /* 24px - section headings */
  --fs-2xl:2rem;       /* 32px - page headings */
  --fs-3xl:2.5rem;     /* 40px - hero */

  --font-ui:"Inter var",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --font-display:"Bricolage var","Inter var",system-ui,sans-serif;

  --lh-tight:1.15;  --lh-snug:1.35;  --lh-body:1.6;
  --motion:130ms cubic-bezier(.2,.8,.3,1);
}

/* ---------- tokens: dark ---------- */
@media (prefers-color-scheme: dark){
  :root:not([data-theme="light"]){
    --t-mint-bg:#123a33;  --t-mint:#7fd8c6;
    --t-sky-bg:#152a44;   --t-sky:#9cc3f5;
    --t-amber-bg:#3a2c12; --t-amber:#e8be7c;
    --t-rose-bg:#3a1b22;  --t-rose:#f0a3b1;
    --t-violet-bg:#271f3f;--t-violet:#c3b0f0;
    --background:#0b0f14;   --foreground:#e8eef2;
    --card:#12181f;         --card-foreground:#e8eef2;
    --muted:#1a222b;        --muted-foreground:#93a2ad;
    --primary:#3fb6a8;      --primary-foreground:#06231f;
    --secondary:#1a222b;    --secondary-foreground:#e8eef2;
    --destructive:#ef7280;  --destructive-foreground:#1a0508;
    --border:#26313c;       --input:#26313c;  --ring:#3fb6a8;
    --shadow:0 16px 44px rgba(0,0,0,.45);
    --mode-text:#7fb0f5; --mode-voice:#f0b45c; --mode-video:#3fb6a8;
  }
}
:root[data-theme="dark"]{
  --t-mint-bg:#123a33;  --t-mint:#7fd8c6;
  --t-sky-bg:#152a44;   --t-sky:#9cc3f5;
  --t-amber-bg:#3a2c12; --t-amber:#e8be7c;
  --t-rose-bg:#3a1b22;  --t-rose:#f0a3b1;
  --t-violet-bg:#271f3f;--t-violet:#c3b0f0;
  --background:#0b0f14;   --foreground:#e8eef2;
  --card:#12181f;         --card-foreground:#e8eef2;
  --muted:#1a222b;        --muted-foreground:#93a2ad;
  --primary:#3fb6a8;      --primary-foreground:#06231f;
  --secondary:#1a222b;    --secondary-foreground:#e8eef2;
  --destructive:#ef7280;  --destructive-foreground:#1a0508;
  --border:#26313c;       --input:#26313c;  --ring:#3fb6a8;
  --shadow:0 16px 44px rgba(0,0,0,.45);
  --mode-text:#7fb0f5; --mode-voice:#f0b45c; --mode-video:#3fb6a8;
}

/* ---------- base ---------- */
*{box-sizing:border-box}
html,body{height:100%}
@supports (height: 100dvh) {
  /* iOS Safari resizes the visual viewport as its toolbar shows and hides;
     100% is measured against the larger one, so the dock ends up clipped.
     Dynamic viewport units follow the real height. */
  html,body{height:100dvh}
}
body{
  margin:0; background:var(--background); color:var(--foreground);
  font:var(--fs-base)/var(--lh-body) var(--font-ui);
  font-optical-sizing:auto;
  display:flex; flex-direction:column; overflow:hidden;
  -webkit-font-smoothing:antialiased;
}
/* One visible focus style everywhere. There were none at all before, which
   made the whole site unusable without a mouse. */
:focus-visible{outline:2px solid var(--ring); outline-offset:2px; border-radius:var(--radius-sm)}
:focus:not(:focus-visible){outline:none}
@media (prefers-reduced-motion: reduce){
  *,*::before,*::after{animation-duration:.01ms !important;animation-iteration-count:1 !important;
    transition-duration:.01ms !important;scroll-behavior:auto !important}
}

/* ---------- landing page ---------- */
body.landing{display:block;overflow:auto;background:var(--background)}
.lhead{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);
  padding:calc(var(--sp-4) + env(safe-area-inset-top)) var(--sp-6) var(--sp-4);border-bottom:1px solid var(--border);
  position:sticky;top:0;background:var(--card);z-index:10}
/* The mark takes its colour from the lockup, so one colour value drives
   tile, text and the spark punched out of the bubble. */
.brandmark{width:1.55em;height:1.55em;flex:none;display:block}
.lbrand{display:inline-flex;align-items:center;gap:9px;font-weight:700;
  font-family:var(--font-display);letter-spacing:-.01em;
  font-size:var(--fs-lg);color:var(--primary);text-decoration:none;letter-spacing:.3px}
.lnav{display:flex;align-items:center;gap:var(--sp-4)}
.lcount{display:flex;align-items:center;color:var(--muted-foreground);font-size:var(--fs-sm);white-space:nowrap}
.lcount b{color:var(--foreground)}

.hero{max-width:880px;margin:0 auto;padding:64px var(--sp-6) 48px;text-align:center}
.hero h1{font-family:var(--font-display);font-weight:700;
  font-size:clamp(2rem,5vw,3.25rem);line-height:var(--lh-tight);
  margin:0 0 var(--sp-4);letter-spacing:-.02em;text-wrap:balance}
.lead{color:var(--muted-foreground);font-size:var(--fs-md);line-height:var(--lh-body);
  max-width:64ch;margin:0 auto var(--sp-6);text-wrap:pretty}
.herofoot{color:var(--muted-foreground);font-size:var(--fs-sm);margin:var(--sp-6) 0 0}

.modecards{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-4);margin-top:var(--sp-6)}
.modecard{display:flex;flex-direction:column;align-items:center;gap:6px;text-align:center;
  padding:var(--sp-6) var(--sp-4);background:var(--card);border:1px solid var(--border);
  border-radius:var(--radius-lg);text-decoration:none;color:var(--foreground);
  transition:border-color var(--motion),transform var(--motion)}
.modecard:hover{border-color:var(--primary);transform:translateY(-2px)}
.modecard.is-primary{border-color:var(--primary)}
/* Drawn, not emoji: these take the card's own colour and stay the same
   picture on every platform. */
.mc-icon{line-height:0;display:block}
.mc-icon svg{width:34px;height:34px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.mc-icon svg .d{opacity:.55}
.mc-name{font-weight:600;font-size:var(--fs-lg)}
.mc-note{color:var(--muted-foreground);font-size:var(--fs-sm);line-height:1.45}
.modecard[data-mode="text"]:hover{border-color:var(--mode-text)}
.modecard[data-mode="voice"]:hover{border-color:var(--mode-voice)}

.lsection{max-width:880px;margin:0 auto;padding:var(--sp-6) var(--sp-6) 48px;border-top:1px solid var(--border)}
.lsection h2{font-family:var(--font-display);font-weight:700;
  font-size:var(--fs-2xl);line-height:var(--lh-snug);letter-spacing:-.015em;
  margin:0 0 var(--sp-4);text-wrap:balance}
.lsection h3{font-size:var(--fs-lg);font-weight:650;line-height:var(--lh-snug);margin:0 0 var(--sp-2)}
.lsection p{color:var(--muted-foreground);line-height:1.6;margin:0}
.cols{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-6)}
/* Drawn, not bullets. A rules list is the thing a visitor scans rather than
   reads, and the tick/cross split tells them which is the one thing to DO
   before they have read a word of it. */
.rules{list-style:none;margin:0;padding:0;color:var(--muted-foreground);
  line-height:var(--lh-body);max-width:72ch;
  display:flex;flex-direction:column;gap:var(--sp-4)}
.rules li{display:flex;align-items:flex-start;gap:var(--sp-3);margin:0}
.rules .i{width:22px;height:22px;flex:none;margin-top:.15em;
  fill:none;stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.rules .i.ok{stroke:var(--primary)}
.rules .i.no{stroke:var(--destructive)}
.rules strong{color:var(--foreground)}
.lcta{text-align:center}
.lcta p{margin-bottom:var(--sp-4)}
.btn-big{display:inline-block;padding:14px 32px;font-size:var(--fs-lg);min-height:52px}

/* ---- landing + SEO pages --------------------------------------------- */
.hero-sm{padding-top:var(--sp-6)}
.hero-sm h1{font-size:clamp(1.75rem,4.2vw,2.75rem)}
.lsection p{max-width:70ch}
/* `.lsection p{margin:0}` above had no sibling rule, so two paragraphs in a
   row butted together and every section read as one unbroken block. */
.lsection p + p{margin-top:var(--sp-4)}
.lsection h3 a{color:var(--primary);text-decoration:none}
.lsection h3 a:hover{text-decoration:underline}

/* Questions collapsed by default: a page of open answers is a wall, and the
   arrow is the affordance people already know. */
.faq{max-width:70ch;border-top:1px solid var(--border)}
.faq details{border-bottom:1px solid var(--border)}
.faq summary{cursor:pointer;padding:14px 0;font-weight:600;list-style:none;
  display:flex;justify-content:space-between;align-items:center;gap:var(--sp-4)}
.faq summary::-webkit-details-marker{display:none}
.faq summary::after{content:"+";color:var(--muted-foreground);font-weight:400;
  font-size:20px;line-height:1;flex:none}
.faq details[open] summary::after{content:"\2212"}
.faq details p{margin:0 0 16px;color:var(--muted-foreground)}

.rellinks{display:flex;flex-wrap:wrap;gap:var(--sp-2)}
.rellinks a{display:inline-block;padding:8px 14px;border:1px solid var(--border);
  border-radius:999px;color:var(--foreground);text-decoration:none;font-size:var(--fs-sm);
  background:var(--card)}
.rellinks a:hover{border-color:var(--primary);color:var(--primary)}

/* The builder wraps every comparison table in .tablewrap and nothing styled
   it. That did not break the page - the table squeezed itself to fit - but a
   seven-column table squeezed into a phone gives about 50px a column, which
   is one word per line and unreadable. So the cells keep their natural width
   and the WRAPPER scrolls. The page itself must never scroll sideways. */
.tablewrap{max-width:70ch;overflow-x:auto;-webkit-overflow-scrolling:touch}
.cmp{width:100%;border-collapse:collapse;font-size:var(--fs-sm)}
.cmp tbody th,.cmp td{font-size:var(--fs-sm)}
/* Below this the columns stop being readable, so the wrapper scrolls instead
   of the cells wrapping to one word per line. */
.cmp th,.cmp td{white-space:nowrap}
.cmp tbody th{white-space:normal;min-width:11ch}
.cmp th,.cmp td{text-align:left;padding:10px 12px;border-bottom:1px solid var(--border)}
.cmp thead th{font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.04em;
  color:var(--muted-foreground)}
.cmp tbody th{font-weight:600}

/* ---- ranked list (the Omegle alternatives round-up) --------------------
   Each entry is a card with the position, the platform name as an <h3> - the
   name is the phrase people search - and pros beside cons. The pros/cons
   pair is not decoration: a round-up where nothing has a downside reads as
   an advert, so the layout makes the missing half obvious if one is ever
   left out. */
.ranked{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-5)}
.rank{background:var(--card);border:1px solid var(--border);border-radius:14px;
  padding:var(--sp-5);max-width:70ch}
.rankhead{display:flex;align-items:center;gap:12px;flex-wrap:wrap;margin-bottom:10px}
.rankno{flex:none;width:30px;height:30px;border-radius:999px;background:var(--primary);
  color:var(--primary-foreground);font-size:var(--fs-sm);font-weight:700;
  display:flex;align-items:center;justify-content:center}
.rank h3{margin:0;font-size:var(--fs-lg)}
.rankbest{font-size:var(--fs-xs);color:var(--muted-foreground);
  border:1px solid var(--border);border-radius:999px;padding:3px 10px;white-space:nowrap}
.rank p{margin:0 0 var(--sp-4)}

.pcwrap{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4)}
.pc h4{margin:0 0 8px;font-size:var(--fs-xs);text-transform:uppercase;
  letter-spacing:.07em;color:var(--muted-foreground)}
.pc ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:7px}
.pc li{position:relative;padding-left:19px;font-size:var(--fs-sm);line-height:1.5;
  color:var(--muted-foreground)}
.pc li::before{position:absolute;left:0;top:0;font-weight:700}
.pc-pro li::before{content:"\2713";color:var(--primary)}
.pc-con li::before{content:"\2715";color:var(--destructive)}
.pc li b{color:var(--foreground)}
@media (max-width:640px){
  .pcwrap{grid-template-columns:1fr;gap:var(--sp-3)}
  .rank{padding:var(--sp-4)}
  .rankbest{white-space:normal}
}
.lsection,.rank,.tablewrap{min-width:0}

/* The button and the notice were flowing onto one line and drifting left
   while the rest of the hero is centred. Each gets its own row. */
.hero .herocta{margin-left:auto;margin-right:auto}
.hero > .herocta{display:block;width:fit-content}
.herocta{display:inline-flex;align-items:center;gap:9px;margin-top:var(--sp-6)}
.herocta svg{width:19px;height:19px;fill:none;stroke:currentColor;stroke-width:2.2;
  stroke-linecap:round;stroke-linejoin:round}

/* The one thing a visitor should read before pressing start. Stated once,
   plainly, rather than buried in the rules further down. */
/* A bar, not a pill. This is the one rule a visitor should read before
   pressing start, and a thin pill reads as a footnote. */
.noticebar{display:flex;align-items:center;justify-content:center;gap:11px;
  margin:var(--sp-6) auto 0;max-width:640px;
  background:var(--t-amber-bg);color:var(--t-amber);
  border:1px solid color-mix(in srgb, var(--t-amber) 22%, transparent);
  border-radius:var(--radius);padding:14px 22px;font-size:var(--fs-base);
  font-weight:600;text-align:left;line-height:1.4}
.noticebar svg{width:22px;height:22px;flex:none;fill:none;stroke:currentColor;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}

/* Interests, on the landing page - the chat app reads the same key. */
.hint-interests{max-width:560px;margin:var(--sp-6) auto 0;text-align:left}
.hint-interests label{display:block;text-align:center;font-weight:600;
  margin-bottom:var(--sp-3)}
.hint-note{font-size:var(--fs-sm);color:var(--muted-foreground);
  margin:var(--sp-2) 0 0;text-align:center}
.icon-only{padding:9px 12px;line-height:1;gap:0}
.icon-only .i{width:18px;height:18px}

/* One button, two icons, no JS touching the markup. Default to the moon so
   the control is never blank in the instant before landing.js runs. */
#lTheme .ic-sun{display:none}
#lTheme[data-mode="dark"] .ic-sun{display:block}
#lTheme[data-mode="dark"] .ic-moon{display:none}

/* The header CTA is the main action on the page and was neither primary nor
   carrying an icon, despite being classed btn-icon. */
.lhead .btn-primary .i{width:17px;height:17px}
.lhead .btn-primary{white-space:nowrap}

/* The account control. Without nowrap "Log in" broke across two lines inside
   the button, which made it 67px tall next to two 44px ones. */
.lacct{white-space:nowrap}
.lacct .i{width:17px;height:17px}

/* On a phone the brand, the online count, the theme toggle and the call to
   action do not fit on one line: the CTA wrapped to two and pushed the header
   91px past the viewport. The count goes - it is repeated in the hero a
   moment further down the page, and the CTA is the thing that must survive. */
@media (max-width:560px){
  .lhead{padding-left:var(--sp-4);padding-right:var(--sp-4);gap:var(--sp-3)}
  .lhead .lcount{display:none}
  .lnav{gap:var(--sp-2)}
  .lhead .btn-primary{padding:9px var(--sp-3)}
}
/* Narrower still: the account control drops to its icon. It keeps its
   aria-label, so it is still announced as "Log in" or "Your profile". */
@media (max-width:480px){
  .lacct span{position:absolute;width:1px;height:1px;overflow:hidden;
    clip-path:inset(50%);white-space:nowrap}
  .lacct{padding:9px 12px}
}

.lcount-quiet .pulse{display:none}

/* Inline links in body copy: underlined, because a link that is only a
   colour change is invisible to a lot of people. */
.lsection p a,.lead a,.herofoot a{color:var(--primary);
  text-decoration:underline;text-underline-offset:2px}
.lsection p a:hover{text-decoration-thickness:2px}
.lsection p a[rel~="nofollow"]::after{content:"\2197";font-size:.78em;
  vertical-align:.35em;margin-left:1px;opacity:.65;text-decoration:none;display:inline-block}

/* A page that states facts should show where they came from. */
.lsources{border-top:1px solid var(--border);padding-top:var(--sp-4)}
.srclist{margin:0;padding-left:1.3em;color:var(--muted-foreground);font-size:var(--fs-sm);
  max-width:70ch}
.srclist li{margin-bottom:8px}
.srclist a{color:var(--muted-foreground);text-decoration:underline;text-underline-offset:2px}
.srclist a:hover{color:var(--primary)}

/* ---- feature cards ----------------------------------------------------- */
.fgrid{display:grid;gap:var(--sp-4);
  grid-template-columns:repeat(auto-fit,minmax(272px,1fr))}
.fcard{background:var(--card);border:1px solid var(--border);
  border-radius:var(--radius-lg);padding:var(--sp-4);
  display:flex;flex-direction:column;gap:10px}
.fcard h3{margin:0;font-size:var(--fs-md);font-weight:650}
.fcard p{margin:0;color:var(--muted-foreground);font-size:var(--fs-sm);max-width:none}
.ficon{width:58px;height:58px;border-radius:16px;display:grid;place-items:center;flex:none}
.ficon svg{width:30px;height:30px;fill:none;stroke:currentColor;stroke-width:1.8;
  stroke-linecap:round;stroke-linejoin:round}
.t-mint{background:var(--t-mint-bg);color:var(--t-mint)}
.t-sky{background:var(--t-sky-bg);color:var(--t-sky)}
.t-amber{background:var(--t-amber-bg);color:var(--t-amber)}
.t-rose{background:var(--t-rose-bg);color:var(--t-rose)}
.t-violet{background:var(--t-violet-bg);color:var(--t-violet)}

/* The mode cards get the same tile treatment - they were thin grey outlines,
   which is what made the page read as a form rather than a product. */
.modecard .mc-icon{width:52px;height:52px;border-radius:14px;display:grid;
  place-items:center;background:var(--muted);color:var(--muted-foreground);
  transition:background var(--motion),color var(--motion)}
/* Solid, not tinted. Pale tiles beside a competitor's saturated ones read as
   disabled controls rather than as choices. */
.modecard[data-mode="text"]  .mc-icon{background:#2f4a72;color:#fff}
.modecard[data-mode="voice"] .mc-icon{background:#d1811d;color:#fff}
.modecard[data-mode="video"] .mc-icon{background:var(--primary);color:#fff}
.modecard:hover .mc-icon{transform:scale(1.05)}
.modecard .mc-icon{transition:transform var(--motion)}
.mc-icon svg{width:26px;height:26px}

.lfoot{border-top:1px solid var(--border);background:var(--card);margin-top:var(--sp-6)}
/* Five columns of keyword-anchored links on every page, the way
   opentalk.club does it. Every page then links to every other one with the
   phrase people actually search, and a crawler landing anywhere can reach
   the whole site. */
.lfoot-in{max-width:1100px;margin:0 auto;padding:var(--sp-6) var(--sp-5)}
.fcols{display:grid;gap:var(--sp-5) var(--sp-4);
  grid-template-columns:repeat(auto-fit,minmax(165px,1fr))}
.fcol h2{font-size:var(--fs-sm);text-transform:uppercase;letter-spacing:.09em;
  color:var(--foreground);margin:0 0 var(--sp-3);font-weight:700}
.fcol ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:10px}
.fcol a{color:var(--muted-foreground);text-decoration:none;font-size:var(--fs-base)}
.fcol a:hover{color:var(--primary);text-decoration:underline;text-underline-offset:2px}
.fbase{margin-top:var(--sp-6);padding-top:var(--sp-4);border-top:1px solid var(--border);
  display:flex;flex-wrap:wrap;gap:var(--sp-2) var(--sp-4);align-items:baseline;
  color:var(--muted-foreground);font-size:var(--fs-sm)}
/* Naming the marks and disclaiming them is what separates a comparison from
   passing yourself off as a competitor. */
.fbase small{font-size:var(--fs-xs);opacity:.85;max-width:72ch}
/* Five columns need about 1060px. Between that and the phone layout,
   auto-fit would fit four and leave the fifth alone on its own row; three
   and two is the tidier split. */
@media (max-width:1040px) and (min-width:641px){
  .fcols{grid-template-columns:repeat(3,1fr)}
}
@media (max-width:640px){
  .fcols{gap:var(--sp-5);grid-template-columns:1fr 1fr}
  .lfoot-in{padding:var(--sp-5) var(--sp-4)}
}
/* `.lfoot nav{display:flex}` used to live here, left over from when the
   footer was one row of pills. .fcols IS that nav, and `.lfoot nav` both
   outranks `.fcols` on specificity and came later, so `display:grid` never
   applied at all: the columns were flex items sized by their content, which
   is why they were unevenly spaced and huddled against the left edge with
   the remaining width empty. */
.lfoot a{color:var(--muted-foreground)}
.lfoot a:hover{color:var(--primary)}

/* ---- legal pages (rules, privacy, terms, safety, contact) ----------------
   One column, measured for reading rather than for filling the screen. */
.legal{max-width:720px;margin:0 auto;padding:var(--sp-6) var(--sp-5) var(--sp-7);
  line-height:1.65;color:var(--foreground)}
.legal h1{font-family:var(--font-display);font-weight:700;
  font-size:clamp(1.875rem,4vw,2.5rem);line-height:var(--lh-tight);
  letter-spacing:-.02em;margin:0 0 var(--sp-2)}
.legal .updated{color:var(--muted-foreground);font-size:var(--fs-sm);
  margin:0 0 var(--sp-6);padding-bottom:var(--sp-5);border-bottom:1px solid var(--border)}
.legal h2{font-family:var(--font-display);font-weight:700;font-size:var(--fs-xl);
  line-height:var(--lh-snug);margin:var(--sp-7) 0 var(--sp-3)}
.legal h3{font-size:var(--fs-md);font-weight:650;color:var(--foreground);
  margin:var(--sp-6) 0 var(--sp-2)}
.legal p{margin:0 0 var(--sp-4)}
.legal ul{margin:0 0 var(--sp-4);padding-left:1.25em}
.legal li{margin-bottom:var(--sp-2)}
.legal li::marker{color:var(--muted-foreground)}
.legal a{color:var(--primary);text-decoration:underline;text-underline-offset:2px}
.legal a.btn{color:inherit;text-decoration:none}
.legal a.btn-primary{color:var(--primary-foreground)}
.legal a.btn-danger{color:var(--destructive-foreground)}
.legal strong{color:var(--foreground);font-weight:600}
@media (max-width:420px){ .legal{padding:var(--sp-5) var(--sp-4) var(--sp-6)} }

.setlinks{display:flex;flex-direction:column;gap:var(--sp-2)}
.setlinks a{color:var(--muted-foreground);font-size:var(--fs-sm);text-decoration:none}
.setlinks a:hover{color:var(--primary);text-decoration:underline}

@media (max-width:720px){
  .modecards,.cols{grid-template-columns:1fr}
  .hero{padding:40px var(--sp-4) 32px}
  .lsection,.lfoot-in{padding-left:var(--sp-4);padding-right:var(--sp-4)}
}

/* ---------- age gate ---------- */
/* ---------- layout ---------- */
.app{flex:1;min-height:0;min-width:0;display:flex}
.stage{flex:1;display:grid;grid-template-columns:1fr 1fr;min-height:0;min-width:0;background:var(--stage)}
.tile{position:relative;background:var(--stage);overflow:hidden;min-height:0;min-width:0}
.tile+.tile{border-left:1px solid #000}
.cam-bg{display:none}
.cam{width:100%;height:100%;object-fit:cover;display:block;background:var(--stage)}
.mirror{transform:scaleX(-1)}

/* chrome sitting on the video keeps its own dark tokens whatever the theme */
/* Bottom-LEFT belongs to the mic and camera buttons now, so the "You" /
   "Stranger" label moved across. Both tiles move together - a label that
   swaps corners between the two halves of the screen looks like a mistake. */
.tag{position:absolute;right:10px;bottom:10px;background:var(--overlay);border:1px solid var(--overlay-border);
  color:var(--overlay-foreground);font-size:var(--fs-xs);padding:3px 9px;border-radius:999px;
  letter-spacing:.3px;z-index:2;opacity:0;transition:opacity var(--motion);backdrop-filter:blur(6px)}
.tile:hover .tag{opacity:1}
.tag.warn{color:#ffb4ba;border-color:#8a3a42}

.livecount{position:absolute;left:var(--sp-3);top:var(--sp-3);z-index:3;display:flex;align-items:center;
  background:var(--overlay);border:1px solid var(--overlay-border);color:var(--overlay-foreground);
  font-size:var(--fs-sm);padding:5px 12px;border-radius:999px;backdrop-filter:blur(6px)}
.livecount b{font-weight:600}
.pulse{width:7px;height:7px;border-radius:50%;background:#49d17f;margin-right:7px;flex:none;animation:pulse 2.2s ease-in-out infinite}
@keyframes pulse{0%,100%{opacity:1}50%{opacity:.35}}

/* ---------- idle card ---------- */
.idle{position:absolute;inset:0;display:grid;place-content:center;justify-items:center;gap:var(--sp-4);
  padding:var(--sp-6);text-align:center;background:radial-gradient(120% 90% at 50% 40%,#151d28,#07090d)}
.idle[hidden]{display:none}
.idle-logo{display:flex;align-items:center;justify-content:center;gap:10px}
.idle-logo .brandmark{width:1.1em;height:1.1em}
.idle-logo{font-family:var(--font-display);font-size:var(--fs-2xl);font-weight:700;color:var(--mode-video);letter-spacing:.4px}
.idle-count{display:flex;align-items:center;color:#93a2ad;font-size:var(--fs-base)}
.idle-count b{color:#e8eef2;font-size:var(--fs-lg)}
.idle-badges{display:flex;gap:10px;flex-wrap:wrap;justify-content:center}
.badge{display:flex;flex-direction:column;background:rgba(255,255,255,.06);border:1px solid var(--overlay-border);
  color:#e8eef2;border-radius:9px;padding:var(--sp-2) var(--sp-4);font-size:var(--fs-sm);font-weight:600;line-height:1.2}
.badge small{color:#93a2ad;font-weight:400;font-size:var(--fs-xs);letter-spacing:.3px}

.stage-msg{position:absolute;inset:0;display:grid;place-content:center;text-align:center;padding:var(--sp-6);gap:var(--sp-1);
  background:linear-gradient(180deg,rgba(7,9,13,.82),rgba(7,9,13,.94))}
.stage-msg[hidden]{display:none}
.stage-title{font-size:var(--fs-lg);font-weight:600;color:#e8eef2}
.stage-sub{color:#93a2ad;font-size:var(--fs-sm)}

.report{position:absolute;top:10px;right:10px;background:rgba(181,45,59,.18);color:#ffb4ba;
  border:1px solid #8a3a42;padding:5px 12px;border-radius:999px;font-size:var(--fs-sm);cursor:pointer}
.report[hidden]{display:none}

.banner{position:absolute;left:50%;top:var(--sp-3);transform:translateX(-50%);max-width:88%;
  background:#3d2b12;border:1px solid #a9791f;color:#f4d9a0;padding:var(--sp-2) var(--sp-4);
  border-radius:999px;font-size:var(--fs-sm);text-align:center;line-height:1.35;z-index:3}
.banner[hidden]{display:none}

.sound{position:absolute;left:50%;bottom:var(--sp-4);transform:translateX(-50%);background:var(--mode-video);
  color:#06231f;border:0;border-radius:999px;padding:9px 18px;font:inherit;font-weight:600;cursor:pointer;z-index:4}
.sound[hidden]{display:none}


/* ---------- settings drawer ---------- */
.scrim{position:fixed;inset:0;z-index:39;background:rgba(3,6,10,.55);backdrop-filter:blur(2px);
  opacity:0;transition:opacity var(--motion)}
.scrim.show{opacity:1}
.scrim[hidden]{display:none}

.drawer{position:fixed;top:0;left:0;bottom:0;z-index:40;width:340px;max-width:86vw;
  background:var(--card);color:var(--card-foreground);border-right:1px solid var(--border);
  box-shadow:var(--shadow);display:flex;flex-direction:column;
  transform:translateX(-100%);transition:transform 220ms cubic-bezier(.2,.8,.3,1);
  will-change:transform}
.drawer.open{transform:translateX(0)}
@media (prefers-reduced-motion: reduce){ .drawer{transition:none} }

.drawer-head{display:flex;align-items:center;justify-content:space-between;
  padding:var(--sp-4);border-bottom:1px solid var(--border);flex:none}
.drawer-head h2{margin:0;font-size:var(--fs-lg)}
.drawer-x{background:none;border:0;color:var(--muted-foreground);font-size:26px;line-height:1;
  cursor:pointer;padding:0 var(--sp-1)}
.drawer-x:hover{color:var(--foreground)}
.drawer-body{flex:1;overflow-y:auto;padding:var(--sp-4);display:flex;flex-direction:column;gap:var(--sp-6)}

.setgroup{display:flex;flex-direction:column;gap:10px}
.setgroup h3{margin:0;font-size:var(--fs-xs);text-transform:uppercase;letter-spacing:.6px;
  color:var(--muted-foreground);font-weight:600}
.setrow{display:flex;flex-direction:column;gap:6px;color:var(--muted-foreground);font-size:var(--fs-sm)}
.setrow b{color:var(--foreground);font-weight:600}
.setrow select{background:var(--background);color:var(--foreground);border:1px solid var(--input);
  border-radius:var(--radius-sm);padding:9px;font:inherit;font-size:var(--fs-sm);width:100%;min-height:40px}
.setrow input[type=range]{width:100%;height:6px;-webkit-appearance:none;appearance:none;border-radius:999px;
  cursor:pointer;background:linear-gradient(to right,var(--primary) 0%,var(--primary) var(--pct,100%),
    var(--muted) var(--pct,100%),var(--muted) 100%)}
.setrow input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;border-radius:50%;
  background:var(--primary);border:2px solid var(--card);box-shadow:0 1px 3px rgba(0,0,0,.4)}
/* ---- interest chips --------------------------------------------------- */
.chipbox{display:flex;flex-wrap:wrap;gap:6px;align-items:center;
  background:var(--card);border:1px solid var(--input);border-radius:var(--radius-sm);
  padding:7px 8px;min-height:42px}
.chipbox:focus-within{outline:2px solid var(--ring);outline-offset:1px}
.chips-list{display:contents;margin:0;padding:0;list-style:none}
.chip{display:inline-flex;align-items:center;gap:5px;background:var(--muted);
  border-radius:999px;padding:4px 6px 4px 11px;font-size:var(--fs-sm);white-space:nowrap}
.chip-x{background:none;border:0;cursor:pointer;color:var(--muted-foreground);
  font-size:16px;line-height:1;padding:0 3px;border-radius:50%}
.chip-x:hover{color:var(--destructive)}
/* Styled by container, not by id - the same chip box is used in the chat
   settings and on the landing page, and an id selector only reached one. */
.chipbox input{flex:1 1 140px;min-width:0;border:0;background:none;
  color:var(--foreground);font:inherit;font-size:var(--fs-sm);padding:6px 2px}
.chipbox input:focus{outline:none}
.chipbox input::placeholder{color:var(--muted-foreground);opacity:.85}
/* The landing box is the page's main input, so it gets more room. */
.hint-interests .chipbox{min-height:52px;padding:9px 12px}
.hint-interests .chipbox input{font-size:var(--fs-base)}

.sethint{margin:0;color:var(--muted-foreground);font-size:var(--fs-xs);line-height:1.45}
.sethint[hidden]{display:none}

.inline-edit{display:flex;gap:var(--sp-2)}
.inline-edit input{flex:1;min-width:0}
.acctlist{display:grid;grid-template-columns:auto 1fr;gap:6px var(--sp-4);margin:0}
.acctlist dt{color:var(--muted-foreground);font-size:var(--fs-sm)}
.acctlist dd{margin:0;font-size:var(--fs-sm);text-align:right;overflow-wrap:anywhere}
.acctlist code{font-size:var(--fs-xs);color:var(--muted-foreground)}

/* The declaration is deliberately read-only - showing it greyed out makes the
   permanence visible rather than something users discover by trying. */
.locked{background:var(--muted);border:1px solid var(--border);border-radius:var(--radius-sm);
  padding:var(--sp-3);display:flex;flex-direction:column;gap:6px}
.locked-row{display:flex;justify-content:space-between;gap:var(--sp-4);font-size:var(--fs-sm);
  color:var(--muted-foreground)}
.locked-row b{color:var(--foreground)}

.seg{display:flex;background:var(--muted);border:1px solid var(--border);border-radius:9px;padding:3px;gap:2px}
.seg button{flex:1;background:transparent;border:0;color:var(--muted-foreground);font:inherit;
  font-size:var(--fs-sm);padding:8px;border-radius:7px;cursor:pointer;min-height:40px}
.seg button.is-on{background:var(--card);color:var(--foreground);font-weight:600;box-shadow:var(--shadow)}

.switch{display:flex;align-items:center;gap:10px;cursor:pointer;font-size:var(--fs-sm);color:var(--foreground)}
.switch input{width:18px;height:18px;accent-color:var(--primary);cursor:pointer}

body.mode-voice #camRow{display:none}

/* ---------- volume ---------- */
.volumebar{position:absolute;left:0;right:0;bottom:0;z-index:4;display:flex;align-items:center;gap:10px;
  padding:10px 14px calc(10px + env(safe-area-inset-bottom));background:linear-gradient(180deg,transparent,rgba(6,9,14,.88));
  opacity:0;transition:opacity var(--motion);pointer-events:none}
.tile:hover .volumebar{opacity:1;pointer-events:auto}
/* Same circular button as the mic and camera on the other tile - it is the
   same kind of control and used to look like a different product. */
.spkr{flex:none}
.spkr svg{width:19px;height:19px;display:block}
.spkr .spkr-slash{opacity:0;transition:opacity var(--motion)}
.spkr.muted{color:#ef7280}
.spkr.muted .spkr-waves{opacity:0}
.spkr.muted .spkr-slash{opacity:1}
/* Muted reads the same on both tiles: red fill plus a bar. The speaker draws
   its own slash, so suppress the shared one rather than showing two. */
.spkr.muted{background:var(--destructive);border-color:var(--destructive);
  color:var(--destructive-foreground)}
.spkr.muted::after{display:none}
.volumebar input[type=range]{flex:1 1 auto;width:100%;min-width:0;height:6px;
  -webkit-appearance:none;appearance:none;border-radius:999px;cursor:pointer;
  background:linear-gradient(to right,var(--mode-video) 0%,var(--mode-video) var(--pct,100%),
    rgba(255,255,255,.24) var(--pct,100%),rgba(255,255,255,.24) 100%)}
.volumebar input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:16px;height:16px;border-radius:50%;
  background:#fff;border:0;box-shadow:0 1px 4px rgba(0,0,0,.5)}
.volumebar input[type=range]::-moz-range-thumb{width:16px;height:16px;border-radius:50%;background:#fff;border:0}
.tile:has(.volumebar) .tag{bottom:52px}
@media (hover:none){ .volumebar,.tag{opacity:1;pointer-events:auto} }

/* ---------- voice mode ---------- */
.voicecard{position:absolute;inset:0;display:none;place-content:center;justify-items:center;gap:var(--sp-4);
  background:radial-gradient(120% 90% at 50% 40%,#151d28,#07090d)}
body.mode-voice .voicecard{display:grid}
body.mode-voice .cam{visibility:hidden}
body.mode-voice .idle{display:none}
.ring{position:relative;width:118px;height:118px;border-radius:50%;border:2px solid var(--overlay-border);
  display:grid;place-items:center;color:#93a2ad;font-size:var(--fs-base);overflow:hidden}
.ring-fill{position:absolute;left:0;right:0;bottom:0;height:0%;background:linear-gradient(0deg,#2d8d82,var(--mode-video));
  opacity:.45;transition:height .09s linear}
.ring span{position:relative;z-index:1}
.voicehint{color:#93a2ad;font-size:var(--fs-sm)}

/* ---------- permission help ---------- */
.permcard{position:absolute;inset:0;z-index:5;display:grid;place-content:center;justify-items:center;gap:var(--sp-3);
  padding:22px;text-align:center;background:linear-gradient(180deg,rgba(26,18,16,.95),rgba(13,10,9,.98));color:var(--overlay-foreground)}
.permcard[hidden]{display:none}
.permicon{width:52px;height:52px;color:#ef7280}
.permtitle{font-size:var(--fs-base);font-weight:600;color:#ffd7d9;max-width:300px}
.permbody{font-size:var(--fs-sm);color:#93a2ad;max-width:300px}
.permsteps{text-align:left;color:#93a2ad;font-size:var(--fs-sm);margin:2px 0 var(--sp-1);padding-left:20px;max-width:300px}
.permsteps li{margin:var(--sp-1) 0}
.permsteps strong{color:#e8eef2}

/* ---------- dock: controls + chat ---------- */
.dock{flex:none;display:grid;grid-template-columns:minmax(0,1fr) minmax(300px,38%);
  gap:10px;border-top:1px solid var(--border);background:var(--card);height:186px;
  /* clears the iPhone home indicator and any landscape notch */
  padding:10px calc(var(--sp-3) + env(safe-area-inset-right))
          calc(10px + env(safe-area-inset-bottom))
          calc(var(--sp-3) + env(safe-area-inset-left))}
/* Two rows, each with one job: what you do, then who you meet. The old dock
   wrapped twelve controls wherever they happened to land; these two rows are
   deliberate, so the eye learns where things are. */
.controls{display:flex;flex-direction:column;justify-content:center;
  gap:var(--sp-2);min-width:0}
.ctlrow{display:flex;align-items:center;gap:var(--sp-2);min-width:0;flex-wrap:wrap}
.ctlrow .btn-primary,.ctlrow .btn-danger{min-width:96px;font-weight:600}
/* The preferences row is quieter than the action row above it. */
.ctlrow-2{padding-top:var(--sp-2);border-top:1px solid var(--border)}
.spacer{flex:1}

.modes{display:flex;background:var(--muted);border:1px solid var(--border);border-radius:9px;padding:3px;gap:2px}
.mode{background:transparent;border:0;color:var(--muted-foreground);font:inherit;font-size:var(--fs-sm);
  padding:7px 15px;border-radius:7px;cursor:pointer;transition:color var(--motion),background var(--motion)}
.mode:hover{color:var(--foreground)}
.mode.is-on{background:var(--card);color:var(--foreground);font-weight:600;box-shadow:var(--shadow)}
/* each mode keeps its own identity colour when selected */
.mode[data-mode="text"].is-on{color:var(--mode-text)}
.mode[data-mode="voice"].is-on{color:var(--mode-voice)}
.mode[data-mode="video"].is-on{color:var(--mode-video)}

.btn{background:var(--secondary);color:var(--secondary-foreground);border:1px solid var(--border);
  border-radius:var(--radius);padding:9px var(--sp-4);font:inherit;cursor:pointer;text-align:center;
  text-decoration:none;min-height:40px;transition:border-color var(--motion),background var(--motion)}
.btn:hover:not(:disabled){border-color:var(--primary)}
.btn:disabled{opacity:.45;cursor:not-allowed}
.btn-primary{background:var(--primary);border-color:var(--primary);color:var(--primary-foreground);font-weight:600;min-width:104px}
.btn-danger{background:transparent;border-color:var(--destructive);color:var(--destructive)}
.btn-ghost{background:transparent;color:var(--muted-foreground)}
/* A button that carries a drawn icon beside its label. The icon inherits
   currentColor and scales with the text, so one rule covers both themes and
   every size the button is used at. */
.btn-icon{font-size:var(--fs-sm);padding:9px var(--sp-3);
  display:inline-flex;align-items:center;gap:7px}
.btn-icon .i{width:1.15em;height:1.15em;flex:none;
  fill:none;stroke:currentColor;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.btn-send{padding:9px var(--sp-4)}

/* ---- mic and camera, on your own tile -------------------------------- */
.tilectl{position:absolute;left:10px;bottom:10px;display:flex;gap:8px;z-index:5;
  opacity:0;transition:opacity var(--motion)}
.tile:hover .tilectl,
.tilectl:focus-within{opacity:1}
/* Muted stays on screen whatever the mouse is doing - not knowing you are
   muted is the whole failure this control exists to prevent. */
.tilectl:has(.is-off){opacity:1}
/* No mouse, no hover: on a touch screen they are simply always there. */
@media (hover:none){ .tilectl{opacity:1} }
.tilebtn{width:40px;height:40px;border-radius:50%;display:grid;place-items:center;
  line-height:1;cursor:pointer;
  background:var(--overlay);color:var(--overlay-foreground);
  border:1px solid var(--overlay-border);backdrop-filter:blur(6px);
  transition:background var(--motion),transform var(--motion)}
.tilebtn:hover:not(:disabled){transform:translateY(-1px)}
.tilebtn:focus-visible{outline:2px solid var(--ring);outline-offset:2px}
.tilebtn:disabled{opacity:.35;cursor:default}
/* Muted is a state you must notice without reading anything. */
.tilebtn.is-off{background:var(--destructive);border-color:var(--destructive);
  color:var(--destructive-foreground)}
.tilebtn{position:relative}
/* Inline glyphs inside a button: same size and colour as the label. */
.btn .ico,.sound .ico{width:16px;height:16px;fill:none;stroke:currentColor;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round;vertical-align:-3px;margin-right:6px}

.tilebtn svg{width:19px;height:19px;fill:currentColor;stroke:currentColor;
  stroke-width:1.9;stroke-linecap:round;stroke-linejoin:round}
.tilebtn svg .o{fill:none}
/* A diagonal bar is how every video app says "off", and it reads without
   colour - which matters for the ~8% of men who cannot rely on red. */
.tilebtn.is-off::after{content:"";position:absolute;left:8px;right:8px;top:50%;
  height:2.5px;background:currentColor;border-radius:2px;
  transform:rotate(-45deg);box-shadow:0 -2px 0 var(--destructive)}

.field{display:flex;align-items:center;gap:7px;color:var(--muted-foreground);font-size:var(--fs-sm);white-space:nowrap}
.field select{background:var(--card);color:var(--foreground);border:1px solid var(--input);
  border-radius:var(--radius-sm);padding:8px 9px;font:inherit;font-size:var(--fs-sm);min-height:40px}

.visually-hidden{position:absolute!important;width:1px!important;height:1px!important;padding:0;margin:-1px;overflow:hidden;
  clip:rect(0 0 0 0);white-space:nowrap;border:0}

.combo{position:relative}
.combo-input{background:var(--card);color:var(--foreground);border:1px solid var(--input);
  border-radius:var(--radius-sm);padding:8px 9px;font:inherit;font-size:var(--fs-sm);
  min-height:40px;
  /* Sized to the longest entry, "Falkland Islands (Islas Malvinas)" at 213px
     plus padding. 168px was cutting off a lot of names. */
  width:240px;max-width:48vw;text-overflow:ellipsis}
.combo-input::placeholder{color:var(--muted-foreground)}

/* opens upward - the dock sits at the bottom of the window */
.combo-list{position:absolute;bottom:calc(100% + 6px);left:0;z-index:20;margin:0;padding:4px;
  list-style:none;width:260px;max-width:70vw;max-height:320px;overflow-y:auto;
  background:var(--card);border:1px solid var(--border);border-radius:var(--radius);
  box-shadow:var(--shadow)}
.combo-list[hidden]{display:none}
.combo-opt{padding:8px 10px;border-radius:var(--radius-sm);cursor:pointer;font-size:var(--fs-sm);
  color:var(--foreground);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.combo-opt[aria-selected="true"],.combo-opt.active{background:var(--muted)}
.combo-opt:hover{background:var(--muted)}
.combo-empty{padding:10px;color:var(--muted-foreground);font-size:var(--fs-sm);text-align:center}
.combo-group{padding:8px 10px 4px;color:var(--muted-foreground);font-size:var(--fs-xs);
  text-transform:uppercase;letter-spacing:.5px}

/* ---------- chat ---------- */
.side{display:flex;flex-direction:column;background:var(--background);border:1px solid var(--border);
  border-radius:var(--radius);min-height:0;min-width:0}
.msgs{flex:1;overflow-y:auto;padding:var(--sp-3);display:flex;flex-direction:column;gap:var(--sp-2)}
.msg{max-width:85%;padding:7px 11px;border-radius:12px;font-size:var(--fs-base);word-break:break-word}
.msg.me{align-self:flex-end;background:var(--primary);color:var(--primary-foreground)}
.msg.them{align-self:flex-start;background:var(--muted);color:var(--foreground)}
.msg a{color:inherit;text-decoration:underline;word-break:break-all}
.sys{align-self:center;color:var(--muted-foreground);font-size:var(--fs-sm);text-align:center;padding:var(--sp-1)}
.composer{display:flex;gap:var(--sp-2);padding:10px;border-top:1px solid var(--border)}
.composer input{flex:1;background:var(--card);border:1px solid var(--input);color:var(--foreground);
  border-radius:var(--radius-sm);padding:9px 11px;font:inherit;min-width:0;min-height:40px}
.composer input:disabled{opacity:.5}

/* ---------- emoji ---------- */
.emoji-wrap{position:relative;display:flex}
.emoji-btn{background:var(--secondary);border:1px solid var(--border);border-radius:var(--radius-sm);
  color:var(--foreground);font-size:var(--fs-md);line-height:1;cursor:pointer;padding:0 11px;min-height:44px}
.emoji-btn:hover:not(:disabled){border-color:var(--primary)}
.emoji-btn:disabled{opacity:.45;cursor:not-allowed}

.emoji-pop{position:absolute;bottom:calc(100% + 8px);right:0;z-index:30;width:296px;max-width:78vw;
  max-height:260px;overflow-y:auto;background:var(--card);border:1px solid var(--border);
  border-radius:var(--radius);box-shadow:var(--shadow);padding:var(--sp-2)}
.emoji-pop[hidden]{display:none}
.emoji-pop h4{margin:var(--sp-2) 0 4px;font-size:var(--fs-xs);text-transform:uppercase;
  letter-spacing:.5px;color:var(--muted-foreground);font-weight:600}
.emoji-grid{display:grid;grid-template-columns:repeat(8,1fr);gap:2px}
.emoji-grid button{background:none;border:0;font-size:20px;line-height:1;padding:6px 0;
  border-radius:var(--radius-sm);cursor:pointer}
.emoji-grid button:hover{background:var(--muted)}

/* Until there is a confirmed account the app behind the dialog is inert and
   visibly so - it should not look like something you can use. */
body.needs-auth .app,
body.needs-auth .dock{filter:blur(6px) saturate(.6);pointer-events:none;user-select:none}
body.needs-auth #authClose{display:none}

/* ---------- sign-in dialog ---------- */
.authbox{position:relative;border:1px solid var(--border);border-radius:var(--radius-lg);
  background:var(--card);color:var(--foreground);padding:26px;width:400px;max-width:92vw;
  box-shadow:var(--shadow)}
.authbox::backdrop{background:rgba(0,0,0,.6)}
.authbox h2{margin:0 0 var(--sp-2);font-size:var(--fs-lg)}
.authbox p{color:var(--muted-foreground);margin:0 0 var(--sp-4);font-size:var(--fs-sm);line-height:1.5}
.authbox .setrow{margin-bottom:var(--sp-3)}
.authbox input[type=email],.authbox input[type=text],.authbox input[type=date]{
  background:var(--background);color:var(--foreground);border:1px solid var(--input);
  border-radius:var(--radius-sm);padding:10px;font:inherit;width:100%;min-height:44px}
.authopts{display:flex;flex-direction:column;gap:var(--sp-2)}
.autherr{color:var(--destructive);font-size:var(--fs-sm);margin:var(--sp-3) 0 0}
.autherr[hidden]{display:none}
.warn-copy{color:var(--foreground)}
.warn-copy strong{color:var(--destructive)}
.confirmlist{display:grid;grid-template-columns:auto 1fr;gap:6px var(--sp-4);margin:0 0 var(--sp-4)}
.confirmlist dt{color:var(--muted-foreground);font-size:var(--fs-sm)}
.confirmlist dd{margin:0;font-weight:600;font-size:var(--fs-sm)}
#authClose{position:absolute;top:10px;right:14px}

/* ---------- report dialog ---------- */
.reportbox{border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--card);
  color:var(--foreground);padding:22px;width:340px;max-width:92vw;box-shadow:var(--shadow)}
.reportbox::backdrop{background:rgba(0,0,0,.55)}
.reportbox h2{margin:0 0 var(--sp-1);font-size:var(--fs-md)}
.reportbox p{color:var(--muted-foreground);margin:0 0 var(--sp-3);font-size:var(--fs-sm)}
.reasons{display:flex;flex-direction:column;gap:7px;margin-bottom:var(--sp-3)}

/* ---------- fullscreen ---------- */
/* Chat used to be hidden here, which meant going fullscreen silently cut you
   off mid-conversation. The dock keeps its normal layout instead. */
body:fullscreen,body:-webkit-full-screen{background:var(--stage)}
body:fullscreen .dock,body:-webkit-full-screen .dock{height:170px}

/* ---------- text mode ---------- */
body.mode-text .stage{display:none}
body.mode-text .app{display:none}
/* Text mode has no video, so the dock becomes the whole page. The controls
   were placed first and therefore sat at the TOP, while in voice and video
   they are at the bottom - the same buttons in a different place depending on
   which mode you were in. The chat takes the first row now and the controls
   the second, so the dock stays the dock. */
body.mode-text .dock{flex:1;height:auto;grid-template-columns:minmax(0,1fr);
  grid-template-rows:minmax(0,1fr) auto}
body.mode-text .controls{grid-row:2}
body.mode-text .side{grid-row:1}
body.mode-text #btnMic,body.mode-text #btnCam,body.mode-text #btnFullscreen{display:none}
body.mode-voice #btnCam{display:none}

/* ---------- responsive ---------- */
@media (max-width:900px){
  .dock{grid-template-columns:minmax(0,1fr);grid-template-rows:auto minmax(0,1fr);height:auto;max-height:52vh}
  .controls{order:2}
  .side{order:1;min-height:130px}
}
/* 360-400px covers most Android phones and the smaller iPhones. Without this
   the control row wraps into three lines and eats the video. */
@media (max-width:420px){
  .dock{height:auto;max-height:56vh}
  .controls{gap:6px}
  .btn{padding:10px;font-size:var(--fs-sm)}
  .btn-primary{min-width:72px}
  .field{font-size:11px}
  .field select{padding:8px 6px}
  .modes .mode{padding:8px 10px}
  .ring{width:88px;height:88px}
  .authbox,.reportbox{padding:20px}
}

/* The dock shares its row with the chat column, so "six across" only fits on
   a genuinely wide window. Between here and the phone layout they go two-up,
   which is the same shape, just stacked. */
@media (max-width:900px){
  .spacer{display:none}
  /* Each row becomes its own two-up grid rather than one long line. */
  .ctlrow{display:grid;grid-template-columns:1fr 1fr;gap:8px}
  .ctlrow > *{min-width:0}
  .ctlrow > .field{display:grid;grid-template-columns:auto 1fr;gap:6px}
  /* :not(.visually-hidden) matters - #selCountry is the hidden native mirror
     of the country combo, and width:100% un-hid it enough to push the page
     sideways at every width under 900px. */
  .ctlrow > .field .combo,
  .ctlrow > .field select:not(.visually-hidden){min-width:0;width:100%}
  .combo-input{width:100%;min-width:0}
  /* Country and the mode picker each want the full width. */
  .ctlrow > .field:has(#comboCountry){grid-column:1 / -1}
  #modePicker{grid-column:1 / -1}
  #modePicker .mode{flex:1}
}

@media (max-width:640px){
  .stage{grid-template-columns:1fr;grid-template-rows:1fr 1fr}
  .tile+.tile{border-left:0;border-top:1px solid #000}
  .idle-logo{font-size:20px}
  .idle-badges{display:none}
  /* 44px minimum touch target */
  .btn,.mode,.field select,.composer input{min-height:44px}
  .btn{padding:10px var(--sp-3)}
  .field{font-size:var(--fs-xs);gap:5px}
  .spacer{display:none}

  /* Thumbs sit on the bottom edge of a phone, so the tile controls get a
     bigger target and stay clear of the dock. */
  .tilectl{left:8px;bottom:8px}
  .tilebtn{width:44px;height:44px}
}

/* ---- analytics consent bar ---------------------------------------------
   Fixed to the bottom rather than a full-screen overlay: this is a cookie
   question, not a gate, and the page underneath stays readable and usable.
   Accept and Decline are deliberately the SAME size and weight - a banner
   where refusing is harder than agreeing is not consent. */
.cbar{position:fixed;left:0;right:0;bottom:0;z-index:60;
  display:flex;flex-wrap:wrap;align-items:center;justify-content:center;
  gap:var(--sp-4);padding:var(--sp-4) var(--sp-5);
  background:var(--card);border-top:1px solid var(--border);
  box-shadow:0 -8px 24px rgba(18,26,31,.10)}
.cbar p{margin:0;max-width:62ch;color:var(--muted-foreground);
  font-size:var(--fs-sm);line-height:1.55}
.cbar a{color:var(--primary)}
.cbar-btns{display:flex;gap:var(--sp-3);flex:none}
.cbar .btn{min-width:104px;justify-content:center}
@media (max-width:640px){
  .cbar{gap:var(--sp-3);padding:var(--sp-4)}
  .cbar-btns{width:100%}
  .cbar .btn{flex:1}
}

/* The withdrawal control on the privacy page. */
.consentbox{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-3);
  padding:var(--sp-4);border:1px solid var(--border);border-radius:var(--radius);
  background:var(--card);margin:var(--sp-4) 0}
.consentbox b{font-size:var(--fs-sm)}

/* ---- section diagrams ---------------------------------------------------
   Drawn, not photographed. Stock photos of people on headsets are the visual
   signature of exactly the sites this one argues against, and we cannot show
   real conversations because none are recorded. So these are obviously
   diagrams: they show the shape of the product rather than pretending to be
   a moment that happened.

   Decorative - the heading and paragraph beside each one say the same thing,
   so they are aria-hidden rather than given alt text that a screen reader
   would read out twice. */
.stepart{display:block;width:100%;max-width:200px;height:auto;margin:0 0 var(--sp-4);
  fill:none;stroke-linecap:round;stroke-linejoin:round}

/* Two tones only: the muted one is structure, the primary one is whatever
   the step is actually about. */
.stepart .d{stroke:var(--muted-foreground);stroke-width:2.5}
.stepart .dd{stroke:var(--muted-foreground);stroke-width:2.5;opacity:.45}
.stepart .p{stroke:var(--primary);stroke-width:2.5}
.stepart .x{stroke:var(--destructive);stroke-width:2.5}
.stepart .pk{stroke:var(--primary-foreground);stroke-width:2.5}
.stepart .bg{fill:var(--primary-foreground);stroke:none}

/* Fill is a property of the shape, so it gets its own class. Selecting on
   substrings of the `d` attribute worked but would have broken silently the
   first time anyone nudged a coordinate. */
.stepart .pf{fill:var(--primary);stroke:var(--primary);stroke-width:2.5}   /* solid */
.stepart .pt{fill:color-mix(in srgb,var(--primary) 14%,transparent);
  stroke:var(--primary);stroke-width:2.5}                                  /* tinted */

@media (max-width:640px){
  .stepart{max-width:150px;margin-bottom:var(--sp-3)}
}

/* ---- ban escalation ----------------------------------------------------
   Three steps with a rising weight. Written out it is a clause at the end of
   a sentence; drawn, the shape of the consequence is the message. */
.ladder{list-style:none;margin:var(--sp-6) 0 0;padding:0;
  display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-3);max-width:72ch}
.ladder li{display:flex;flex-direction:column;align-items:flex-start;gap:4px;
  padding:var(--sp-4);border:1px solid var(--border);border-radius:var(--radius);
  background:var(--card)}
/* Solid, not a tint: the number on a 16% wash of its own colour measured
   3.40, under AA for text this size. */
.ladder .lv{display:flex;align-items:center;justify-content:center;
  width:26px;height:26px;border-radius:999px;margin-bottom:var(--sp-1);
  background:var(--t-amber);color:var(--card);
  font-size:var(--fs-sm);font-weight:700}
.ladder .lv-end{background:var(--destructive);color:var(--destructive-foreground)}
.ladder b{font-size:var(--fs-md);color:var(--foreground)}
.ladder span:last-child{font-size:var(--fs-sm);color:var(--muted-foreground)}
@media (max-width:560px){
  .ladder{grid-template-columns:1fr;gap:var(--sp-2)}
  .ladder li{flex-direction:row;align-items:center;gap:var(--sp-3);padding:var(--sp-3)}
  .ladder .lv{margin-bottom:0}
}

/* ---- sign-in sheet -----------------------------------------------------
   These were lost when the profile styles were rewritten as a block: without
   the icon size the inline SVGs sized themselves to the button's width, so
   each option rendered 350px tall and only the first one fitted on screen.
   A provider button without its mark is also what makes a sign-in sheet look
   homemade, and Google's branding rules require theirs. */
.btn-auth{display:inline-flex;align-items:center;justify-content:flex-start;
  gap:var(--sp-3);width:100%;min-height:48px;font-size:var(--fs-base);
  padding-left:var(--sp-4);text-align:left}
.btn-auth .i{width:20px;height:20px;flex:none}
.btn-auth .i:not(.i-brand){fill:none;stroke:currentColor;stroke-width:1.9;
  stroke-linecap:round;stroke-linejoin:round}
.btn-auth .i-brand{background:#fff;border-radius:3px;padding:1px;box-sizing:content-box}

/* Separates the account options from the no-account one, so "continue
   without an account" reads as a real alternative rather than a third button
   in a stack of three. */
.authsep{display:flex;align-items:center;gap:var(--sp-3);
  color:var(--muted-foreground);font-size:var(--fs-sm);margin:var(--sp-2) 0}
.authsep::before,.authsep::after{content:"";height:1px;flex:1;background:var(--border)}

/* ---- profile page ------------------------------------------------------
   Was a bare definition list, which read as a database dump rather than an
   account. Identity first, then grouped sections, then the destructive
   action last and visibly separated from everything above it. */
/* A cached profile is a snapshot, and saying so is the difference between a
   fast page and a page that lies. Without this, localStorage details looked
   exactly like a live session - which hid a genuinely signed-out state for
   half a day. */
.pfstale{display:flex;align-items:center;gap:10px;margin:var(--sp-5) 0 0;
  padding:10px var(--sp-4);border:1px solid var(--t-amber);border-radius:var(--radius);
  background:color-mix(in srgb,var(--t-amber) 10%,transparent);
  color:var(--t-amber);font-size:var(--fs-sm)}
.pfspin{width:13px;height:13px;flex:none;border-radius:50%;
  border:2px solid color-mix(in srgb,var(--t-amber) 35%,transparent);
  border-top-color:var(--t-amber);animation:pfspin .8s linear infinite}
@keyframes pfspin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.pfspin{animation:none}}

.pfhead{display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap;
  padding:var(--sp-5);border:1px solid var(--border);border-radius:var(--radius-lg);
  background:var(--card);margin:var(--sp-5) 0 var(--sp-6)}
.pfavatar{width:56px;height:56px;flex:none;border-radius:999px;
  display:flex;align-items:center;justify-content:center;
  background:var(--primary);color:var(--primary-foreground);
  font-family:var(--font-display);font-size:var(--fs-xl);font-weight:700;
  text-transform:uppercase;user-select:none}
.pfwho{flex:1;min-width:0}
.pfname{display:flex;align-items:center;gap:var(--sp-3);flex-wrap:wrap}
.pfwho h2{margin:0;font-size:var(--fs-xl);line-height:1.2}
.pfedit{display:inline-flex;align-items:center;gap:5px;background:none;
  border:1px solid var(--border);border-radius:999px;padding:3px 10px;
  color:var(--muted-foreground);font-size:var(--fs-xs);cursor:pointer}
.pfedit:hover{color:var(--primary);border-color:var(--primary)}
.pfedit svg{width:13px;height:13px;fill:none;stroke:currentColor;stroke-width:2;
  stroke-linecap:round;stroke-linejoin:round}
.pfnameform{display:flex;gap:var(--sp-2);flex-wrap:wrap;margin:var(--sp-2) 0}
.pfnameform input{flex:1;min-width:11rem;padding:9px var(--sp-3);
  border:1px solid var(--input);border-radius:var(--radius);
  background:var(--background);color:var(--foreground);font:inherit}
.pfwho p{margin:2px 0 0;color:var(--muted-foreground);font-size:var(--fs-sm)}

.pfsec{margin:0 0 var(--sp-6)}
.pfsec h2{font-size:var(--fs-lg);margin:0 0 var(--sp-3)}
.pfrows{border:1px solid var(--border);border-radius:var(--radius);
  background:var(--card);overflow:hidden}
.pfrow{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-4);
  padding:var(--sp-3) var(--sp-4);border-bottom:1px solid var(--border)}
.pfrow:last-child{border-bottom:0}
.pfrow span{color:var(--muted-foreground);font-size:var(--fs-sm);flex:none}
.pfrow b,.pfrow code{text-align:right;word-break:break-word;font-weight:600}
.pfrow code{font-weight:400;font-size:var(--fs-sm);word-break:break-all}
.pfnote{color:var(--muted-foreground);font-size:var(--fs-sm);
  line-height:var(--lh-body);margin:var(--sp-3) 0 0;max-width:70ch}

/* Destructive actions get their own frame. Nobody should reach a delete
   button by accident while reading about their nickname. */
.pfdanger{border:1px solid color-mix(in srgb,var(--destructive) 40%,var(--border));
  border-radius:var(--radius);padding:var(--sp-5);
  background:color-mix(in srgb,var(--destructive) 5%,transparent)}
.pfdanger h2{color:var(--destructive)}
.btn-danger{background:var(--destructive);color:var(--destructive-foreground);
  border-color:var(--destructive)}
.btn-danger:hover{filter:brightness(1.08)}
.pferr{color:var(--destructive);font-size:var(--fs-sm);margin:var(--sp-3) 0 0}

.pfban,.pfpending{border-radius:var(--radius);padding:var(--sp-4) var(--sp-5);
  margin-bottom:var(--sp-5)}
.pfban{border:1px solid var(--destructive);
  background:color-mix(in srgb,var(--destructive) 8%,transparent)}
.pfban h2{margin-top:0;color:var(--destructive)}
.pfpending{border:1px solid var(--t-amber);
  background:color-mix(in srgb,var(--t-amber) 10%,transparent)}
.pfpending h2{margin-top:0;color:var(--t-amber)}
.pfactions{display:flex;align-items:center;gap:var(--sp-4);flex-wrap:wrap;
  margin:0 0 var(--sp-7)}
.pfactions span{color:var(--muted-foreground);font-size:var(--fs-sm)}
@media (max-width:560px){
  .pfrow{flex-direction:column;gap:2px;align-items:flex-start}
  .pfrow b,.pfrow code{text-align:left}
  .pfhead{gap:var(--sp-3)}
  .pfhead .btn{width:100%}
}

/* ---- account menu ------------------------------------------------------
   One component, used by the landing header and the chat dock. The dock sits
   at the bottom of the viewport, so the menu opens UPWARD there and downward
   in the header - hence the two placements rather than one. */
.acctwrap{position:relative;display:inline-flex;flex:none}
.acctmenu{position:absolute;right:0;z-index:70;min-width:11rem;
  display:flex;flex-direction:column;
  background:var(--card);border:1px solid var(--border);
  border-radius:var(--radius);box-shadow:var(--shadow);padding:6px;
  top:calc(100% + 8px)}
.dock .acctmenu{top:auto;bottom:calc(100% + 8px)}
.acctmenu[hidden]{display:none}
.acctmenu > *{display:block;width:100%;text-align:left;
  background:none;border:0;border-radius:var(--radius-sm);
  padding:10px 12px;font:inherit;color:var(--foreground);
  text-decoration:none;cursor:pointer;min-height:40px}
.acctmenu > *:hover,.acctmenu > *:focus-visible{background:var(--muted)}
.acctmenu #btnLogout,.acctmenu #lLogout{color:var(--destructive)}

/* The mode switcher is anchors now, not buttons: they can be opened in a new
   tab and followed by a crawler. The look is unchanged. */
a.mode{text-decoration:none;display:inline-flex;align-items:center;justify-content:center}

/* ---- phone dock -----------------------------------------------------------
   At 412px the dock spent four rows on buttons (Start/Stop, then
   Fullscreen+Home, then Settings+Account with an empty half-cell beside it)
   and pushed the filters below the fold, while the two videos were squeezed
   to ~200px each. Start and Stop share one row; the four secondary actions
   become one row of icons. Their labels stay in the accessibility tree. */
@media (max-width:640px){
  /* Twelve columns so the icon row fills whether it holds four icons, or
     three in text mode (which hides Fullscreen). */
  .controls > .ctlrow:first-child{grid-template-columns:repeat(12,minmax(0,1fr))}
  #btnPrimary,#btnStop{grid-column:span 6}
  #btnFullscreen,#btnHome,#btnSettings,#acctWrap{grid-column:span 3}
  body.mode-text #btnHome,body.mode-text #btnSettings,body.mode-text #acctWrap{grid-column:span 4}
  #btnFullscreen,#btnHome,#btnSettings,#btnAcctMenu{justify-content:center;gap:0;padding:10px 0}
  #acctWrap,#btnAcctMenu{width:100%;min-width:0}
  #btnFullscreen span,#btnHome span,#btnSettings span,#btnAcctMenu span{
    position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
  #btnFullscreen .i,#btnHome .i,#btnSettings .i,#btnAcctMenu .i{width:20px;height:20px}

  /* The count was shown twice on one screen: the pill and the idle panel. The
     pill stays - it is also there during a conversation. */
  .idle-count{display:none}

  /* The stranger tile is ~200px tall on a phone, so a tag at the bottom (above
     the always-visible volume bar) sat on top of "Stopped / Press Start...".
     Tags go to the top. The stranger's goes left, because Report is top-right
     during a conversation. */
  .tile .tag,.tile:has(.volumebar) .tag{top:10px;bottom:auto}
  #remoteTag{left:10px;right:auto}

  /* The dock's rows were `auto minmax(0,1fr)`: the chat log took what it
     wanted and the CONTROLS got the remainder. On a short phone that
     remainder was less than the buttons need, and .controls centres its
     content, so Start/Stop overflowed upward on top of the message box.
     The controls now get their full height and the log - which scrolls
     anyway - gives way. */
  .dock{grid-template-rows:minmax(112px,1fr) auto}
  .side{min-height:112px}
  .controls{justify-content:flex-start}

  /* Touch screens show the volume bar permanently (there is no hover), and
     on a short tile it ran through "Sign in to start" and "Stopped". There
     is nobody to turn up or down until a conversation starts - and Report is
     shown exactly then (matched() reveals it; every other path hides it). */
  .tile:has(#btnReport[hidden]) .volumebar{display:none}
}
/* Narrow phones: "I am" and "Looking for" beside their selects left
   "Anyone" clipped to "Anyo". The label goes above instead. */
@media (max-width:380px){
  .ctlrow > .field:has(#selGender),.ctlrow > .field:has(#selLookingFor){
    grid-template-columns:minmax(0,1fr);gap:2px}
}
/* Short phones (iPhone SE and similar, ~667px): the dock was capped at 56vh
   and the last filter row ended below the screen. It may take a little more,
   and the chat log - which scrolls - a little less. */
@media (max-width:640px) and (max-height:760px){
  .dock{max-height:64vh;grid-template-rows:minmax(92px,1fr) auto}
  .side{min-height:92px}
}
/* Text mode has no videos - the dock IS the page. The phone/tablet cap on
   the dock (52vh, meant to leave room for the two video tiles) still applied,
   so on a phone the conversation used the top half and the bottom half was
   empty. */
@media (max-width:900px){
  body.mode-text .dock{max-height:none}
}
/* ?stats diagnostics panel (see statsPanelOn in app.js). Off unless asked for. */
.statspanel{position:absolute;left:8px;right:8px;top:48px;z-index:6;margin:0;
  padding:8px 10px;border-radius:8px;background:rgba(0,0,0,.72);color:#d9f7e8;
  font:11px/1.45 ui-monospace,Menlo,monospace;white-space:pre-wrap;pointer-events:none}
