/* jarchi look: the tokens, the base and the shared components every page builds on (pages.css, classes.css,
   prejoin.css, feedback.css… sit on top), then the class room. Plain CSS; light and dark come from the same
   tokens (prefers-color-scheme, or the person's choice: html[data-theme="light" | "dark"]).

   The design system (DESIGN-SYS.md; the A1 proposal and palette.json in the design research): calm by default,
   loud only on purpose, never colour alone.
   - Every colour of the product is a token in the block below, and only here (tools/check-tokens.mjs fails the
     build on a colour written anywhere else in the CSS, and checks every pair below by APCA and WCAG 2.2, and the
     status colours and the board's pens under colour-blind vision).
   - Grounds are warm near-neutral, never #fff or #000; the board is paper on a mid-dark stage (its glare cut).
   - Four hues carry meaning, each at its own lightness (so they stay apart for colour-blind eyes too):
       --accent  turquoise «فیروزه»: the brand, selected, the one main action      L .52, white text
       --speak   green: a voice on the air («آماده‌ام», my mic open, who speaks)    L .55, white text
       --hand    amber: attention (a raised hand, a weak line, a lock that is on)  L .86, dark text
       --danger  red: end, remove, cut, recording                                  L .46, white text
     "Fine" gets no colour (--icon). Each hue has a solid, an -ink (its colour as text or glyph), a -soft (a quiet
     state ground) and a -line (an edge); --on-<hue> is the text on its solid.
   - Every state also has a shape (a slash, a level ring, a number, bars, a badge): colour only confirms it.
   - Type is in rem (the phone's text size reaches the page through <meta name="text-scale">); nothing a student
     reads is under 16 px (html[data-who="student"] lifts the small steps), a teacher's under 13 px.
   Older names stay as aliases for one release (the lanes in flight). Note the one that changed meaning:
   --accent-ink is now the turquoise as text; the text on a turquoise solid is --on-accent. */

/* Vazirmatn, one family in two files: the everyday one (Persian and Arabic, basic Latin, digits, punctuation; the
   weights the pages use, 400–800: 60 KB) loads with the page; the full font (111 KB) only when a text has a
   character outside it. Both swap in: the text shows at once in the device's font. */
@font-face {
  font-family: "Vazirmatn";
  src: url("/fonts/vazirmatn-fa-wght.woff2?v=107edf344b") format("woff2");
  font-weight: 400 800;
  font-display: swap;
  unicode-range: U+0020-007E, U+00A0-00FF, U+0600-06FF, U+0750-077F, U+200C-200F, U+2010-2027, U+2030-205E,
    U+2066-2069, U+2122, U+2190-2193, U+2212, U+2215, U+FB50-FDFF, U+FE70-FEFF;
}
@font-face {
  font-family: "Vazirmatn";
  src: url("/fonts/vazirmatn-wght.woff2?v=4e3fa217d3") format("woff2");
  font-weight: 100 900;
  font-display: swap;
  unicode-range: U+0100-05FF, U+0700-074F, U+0780-200B, U+2028-202F, U+205F-2065, U+206A-2121, U+2123-218F,
    U+2194-2211, U+2213-2214, U+2216-FB4F, U+FE00-FE6F, U+FF00-FFFF;
}

/* ===== tokens: start (every colour lives here; check-tokens.mjs reads this block) ===== */
:root {
  /* grounds and lines (sand: OKLCH h 80, C .006) */
  --bg: #f4f1ed;
  --bg-sunken: #edebe7;
  --surface: #fefbf7;
  --surface-raised: #ffffff;
  --line: #dddad6;
  --line-strong: #82807c;
  --scrim: rgba(24, 22, 19, .45);
  --hover: rgba(29, 34, 39, .06);
  --press: rgba(29, 34, 39, .11);

  /* text and icons (slate: h 255, C .016) */
  --ink: #1a2027;
  --ink-2: #383e46;
  --muted: #4d535b;
  --faint: #868d96;
  --icon: #2d333b;
  --icon-quiet: #525961;

  /* the brand: turquoise «فیروزه» */
  --accent: #1a7777;
  --accent-hover: #156464;
  --accent-ink: #135e5e;
  --accent-soft: #d7f6f5;
  --accent-line: #7ed6d5;
  --on-accent: #ffffff;
  --focus: #1a7777;

  /* the status family: one hue each, at its own lightness */
  --speak: #1d8742;
  --speak-hover: #13702f;
  --speak-ink: #115c2b;
  --speak-soft: #e0f5e3;
  --speak-line: #8bd99c;
  --hand: #f7c97f;
  --hand-ink: #6c4c0f;
  --hand-soft: #feecd1;
  --hand-line: #f0ba60;
  --on-hand: #2b1c03;
  --danger: #a21820;
  --danger-hover: #87131a;
  --danger-ink: #99161e;
  --danger-soft: #ffe9e6;
  --danger-line: #fbada6;
  --on-solid: #ffffff;
  /* recording: the danger family while it records, a calm amber while it waits (paused) */
  --rec: var(--danger);
  --rec-ink: var(--danger-ink);
  --rec-soft: var(--danger-soft);
  --rec-line: var(--danger-line);
  --on-rec: var(--on-solid);
  --rec-paused: var(--hand);
  --rec-paused-ink: var(--hand-ink);
  --rec-paused-soft: var(--hand-soft);
  --rec-paused-line: var(--hand-line);
  --on-rec-paused: var(--on-hand);
  /* a rating's five faces (the after-class form): red → amber → green, each a soft ground and its ink */
  --rate-1: var(--danger-soft); --rate-1-ink: var(--danger-ink);
  --rate-2: #fde3cf; --rate-2-ink: #7a3b06;
  --rate-3: var(--hand-soft); --rate-3-ink: var(--hand-ink);
  --rate-4: var(--speak-soft); --rate-4-ink: var(--speak-ink);
  --rate-5: var(--accent-soft); --rate-5-ink: var(--accent-ink);
  /* the reactions' bubbles (white words on each, in both schemes): «فهمیدم» green, «نفهمیدم» amber (the teacher
     should notice), «تکرار کنید» turquoise, «آفرین» violet, ❤ rose; each also has its own glyph */
  --rx-got: var(--speak);
  --rx-lost: #7a5613;
  --rx-again: var(--accent);
  --rx-bravo: #6d3a9c;
  --rx-heart: #c23a55;

  /* the tooltip: the inverse of the page */
  --tip-bg: #1a2027;
  --tip-ink: #f7f5f1;

  /* the stage around the lesson (always dark-ish: it sets the glare budget), and what sits on it */
  --stage: #494744;
  --stage-raised: #5a5854;
  --stage-av: #75726c;
  --stage-ink: #f7f5f1;
  --stage-muted: #e7e4e0;
  --stage-chip: rgba(20, 18, 15, .62);
  --stage-chip-strong: rgba(18, 17, 15, .84);
  --stage-hover: rgba(255, 255, 255, .14);
  --stage-live: #8bd99c;
  --stage-live-ring: rgba(139, 217, 156, .5);
  --stage-focus: #5ac5c4;
  --stage-hand: #f7c97f;
  --stage-rec: #f97770;
  --stage-ov-teacher: rgba(15, 82, 82, .95);
  --stage-tag-ink: #0f5252;
  --ov-msg: rgba(24, 23, 21, .7);
  --ov-msg-group: rgba(24, 23, 21, .56);
  --ov-who: #b9e3e1;
  --stage-ov-q: #f7c97f;
  --on-stage-ov-q: #2b1c03;
  --video-ground: #000000;
  --knob: #ffffff;

  /* the board and the page: paper (a little dimmer in dark), chalk boards, the printed lines */
  --paper: #fbfaf8;
  --paper-ink: #1a2027;   /* text on paper: the same in both schemes (paper is always light) */
  --paper-muted: #454b52;
  --board-green: #1e4635;
  --board-black: #23272a;
  --print-grid: rgba(48, 92, 140, .3);
  --print-margin: rgba(200, 60, 60, .5);
  --print-mm: rgba(214, 112, 52, .45);
  --print-mm-fine: rgba(214, 112, 52, .18);
  --print-dot: rgba(48, 72, 100, .5);
  --print-axis: #2a2f35;
  --ink-select: #1a7777;
  --ink-select-ground: rgba(255, 255, 255, .55);
  --ink-select-dark: #96e1e0;
  --ink-select-dark-ground: rgba(0, 0, 0, .2);
  --cursor-eraser: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='28' height='28'%3E%3Ccircle cx='14' cy='14' r='10' fill='white' fill-opacity='.6' stroke='%23555' stroke-width='1.5'/%3E%3C/svg%3E") 14 14, cell;
  --swatch-edge: rgba(0, 0, 0, .18);

  /* staff pages (بازرس): good / so-so / bad */
  --good: var(--speak-ink); --good-soft: var(--speak-soft);
  --mid: var(--hand-ink); --mid-soft: var(--hand-soft);
  --bad: var(--danger-ink); --bad-soft: var(--danger-soft);
  --spark: var(--muted);

  /* small drawings a CSS background needs (the glyph's colour is part of the token) */
  --badge-lock: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232b1c03' stroke-width='3' stroke-linecap='round'%3E%3Crect x='5' y='11' width='14' height='10' rx='2'/%3E%3Cpath d='M8 11V7a4 4 0 0 1 8 0v4'/%3E%3C/svg%3E");
  --ic-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234d535b' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7.5'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
  /* marks: a glyph on a small disc (the disc is the element's background; the glyph's colour is the one on it) */
  --mark-ok: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fefbf7' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  --mark-attn: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%232b1c03' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M12 7v6M12 17h.01'/%3E%3C/svg%3E");
  --mark-cut: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23fff' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M12 7v6M12 17h.01'/%3E%3C/svg%3E");
  --mark-skip: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='%23fff'%3E%3Cpath d='M4 6.5v11l7-5.5zM12 6.5v11l7-5.5z'/%3E%3C/svg%3E");
  --ic-chat: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.75' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2Z'/%3E%3Cpath d='M8 8.5h8M8 12h5'/%3E%3C/svg%3E");
  /* the connection's bars as masks (alpha only; the colour is the element's): 4 lit, 2 lit, 1 lit, cut */
  --ic-signal-4: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M4 20v-2M9 20v-5M14 20v-9M19 20V5'/%3E%3C/svg%3E");
  --ic-signal-2: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M4 20v-2M9 20v-5'/%3E%3Cpath d='M14 20v-9M19 20V5' stroke-opacity='.28'/%3E%3C/svg%3E");
  --ic-signal-1: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M4 20v-2'/%3E%3Cpath d='M9 20v-5M14 20v-9M19 20V5' stroke-opacity='.28'/%3E%3C/svg%3E");
  --ic-signal-x: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='2.5' stroke-linecap='round'%3E%3Cpath d='M4 20v-2M9 20v-5M14 20v-9M19 20V5' stroke-opacity='.28'/%3E%3Cpath d='m3 3.5 6 6m0-6-6 6'/%3E%3C/svg%3E");
  /* the wordmark's three voice bars (on the turquoise square) */
  --mark-bars: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Cg stroke='%23fff' stroke-width='3' stroke-linecap='round'%3E%3Cpath d='M10 13v6M16 9v14M22 12v8'/%3E%3C/g%3E%3C/svg%3E");

  /* ---- type: Vazirmatn, Persian first (its letters sit ~0.7× the size of Latin at the same px) ---- */
  --fs-display: 1.875rem;   /* 30: the one big moment, «نوبت توئه!» */
  --fs-title: 1.5rem;       /* 24: page titles */
  --fs-heading: 1.25rem;    /* 20: sheet and panel titles */
  --fs-lead: 1.125rem;      /* 18: the one line a student must read */
  --fs-body-phone: 1.0625rem; /* 17: chat and messages on phones */
  --fs-body: 1rem;          /* 16: body text, every input (iPhone never zooms) */
  --fs-label: 1rem;         /* 16: buttons, names */
  --fs-meta: .875rem;       /* 14: time, counts, captions (teacher side) */
  --fs-micro: .8125rem;     /* 13: a laptop teacher's timestamps */
  --fs-badge: .75rem;       /* 12: a badge's digits only (800) */
  /* older names */
  --fs-xs: var(--fs-micro);
  --fs-s: var(--fs-meta);
  --fs-sm: var(--fs-meta);
  --fs: var(--fs-body);
  --fs-md: var(--fs-lead);
  --fs-lg: var(--fs-title);
  --fs-xl: var(--fs-display);
  --fw: 400;
  --fw-m: 600;
  --fw-b: 700;
  --fw-x: 800;

  /* ---- the UI kit (POLISH.md): radii by role, a 4/8 grid, depth by role, motion ---- */
  --r-sm: 8px;
  --r: 12px;
  --r-lg: 16px;
  --r-xl: 20px;
  --r-pill: 999px;
  --r-ctl: 12px;
  --r-card: 16px;
  --r-pop: 14px;
  --r-sheet: 20px;
  --s1: 4px;
  --s2: 8px;
  --s3: 12px;
  --s4: 16px;
  --s5: 20px;
  --s6: 24px;
  --s8: 32px;
  --tap: 44px;
  --tap-lg: 56px;
  --shadow-1: 0 1px 2px rgba(40, 33, 24, .05), 0 1px 1px rgba(40, 33, 24, .03);
  --shadow-2: 0 8px 24px rgba(40, 33, 24, .12), 0 1px 4px rgba(40, 33, 24, .06);
  --shadow-3: 0 24px 64px rgba(40, 33, 24, .22), 0 4px 12px rgba(40, 33, 24, .08);
  --shadow-stage: 0 6px 24px rgba(0, 0, 0, .35);
  /* ---- motion (A3 §7): what moves explains cause and continuity, then stops; only transform and opacity ---- */
  --dur-tap: 80ms;       /* press feedback */
  --dur-fast: 120ms;     /* colour, icon or label swap, toggles */
  --dur-med: 200ms;      /* small things in (toast, menu, badge, chip); every exit */
  --dur-slow: 280ms;     /* big things in: a sheet, a banner, the floor's card */
  --dur-fade: 400ms;     /* things leaving by themselves: a chat line, a solved banner, the end of the class */
  --dur-ping: 600ms;     /* the one ring that points at the cause */
  --dur-breathe: 1600ms; /* a waiting pulse: three at most unless it is a real wait (a spinner) */
  --ease-std: cubic-bezier(.2, 0, 0, 1);
  --ease-enter: cubic-bezier(.05, .7, .1, 1);
  --ease-exit: cubic-bezier(.3, 0, .8, .15);
  --ease-pop: cubic-bezier(.34, 1.4, .64, 1); /* badges and counters only */
  --move: 1;             /* every travel distance × this: 0 with reduced motion (fades stay, nothing travels) */
  --t-fast: var(--dur-fast);
  --t-med: var(--dur-med);
  --ease: var(--ease-enter);

  /* ---- older names (aliases, one release) ---- */
  --card: var(--surface);
  --card-raised: var(--surface-raised);
  --chrome: var(--surface);
  --accent-strong: var(--accent-ink);
  --hand-solid: var(--hand);
  --warn: var(--hand-ink);
  --warn-solid: var(--hand-ink);
  --warn-soft: var(--hand-soft);
  --warn-line: var(--hand-line);
  --live: var(--hand-ink);
  --live-soft: var(--hand-soft);
  --ok: var(--icon);
  --ok-ink: var(--ink-2);
  --ok-soft: var(--bg-sunken);
  --ring: var(--speak);
  --paper-dim: 1; /* a document page's image: dimmed with the paper in dark */
  color-scheme: light;
}
/* Dark: by the device (prefers-color-scheme) unless the person chose (html[data-theme], «تنظیمات من» › نمایش);
   the two blocks are the same tokens (check-tokens.mjs holds them equal). */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --paper-dim: .92;
    --bg: #171613;
    --bg-sunken: #13110f;
    --surface: #1e1d1a;
    --surface-raised: #262421;
    --line: #44423f;
    --line-strong: #82807c;
    --scrim: rgba(0, 0, 0, .6);
    --hover: rgba(255, 255, 255, .07);
    --press: rgba(255, 255, 255, .12);

    /* dark mode's hierarchy comes from size and weight, not from greyer text (APCA: Lc 75 on L .23 needs L ≥ .85) */
    --ink: #edebe7;
    --ink-2: #dddad6;
    --muted: #d3d1cd;
    --faint: #a09e9a;
    --icon: #e0deda;
    --icon-quiet: #c6c4c0;

    /* the solids stay the same as in light (no glowing pastels); their inks get light */
    --accent-ink: #96e1e0;
    --accent-soft: #043030;
    --accent-line: #135e5e;
    --focus: #5ac5c4;
    --speak-ink: #a1e4ae;
    --speak-soft: #172f1d;
    --speak-line: #13632f;
    --hand-ink: #fad08f;
    --hand-soft: #35260c;
    --hand-line: #7a5613;
    --danger-ink: #fcc9c4;
    --danger-soft: #3c201d;
    --danger-line: #99161e;
    --rate-2: #3b2414; --rate-2-ink: #ffc49a;

    --tip-bg: #f1eeea;
    --tip-ink: #1a2027;

    --stage: #282623;
    --stage-raised: #34322e;
    --stage-av: #4b4842;
    --stage-ink: #edebe7;
    --stage-muted: #d3d1cd;
    --stage-chip: rgba(0, 0, 0, .62);
    --stage-rec: #f86a65;
    --paper: #eae9e6;

    --shadow-1: 0 1px 2px rgba(0, 0, 0, .3);
    --shadow-2: 0 10px 28px rgba(0, 0, 0, .45), 0 1px 4px rgba(0, 0, 0, .3);
    --shadow-3: 0 28px 72px rgba(0, 0, 0, .6), 0 4px 12px rgba(0, 0, 0, .35);
    --swatch-edge: rgba(255, 255, 255, .34);
    --mark-ok: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231e1d1a' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
    --ic-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d3d1cd' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7.5'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
    color-scheme: dark;
  }
}
:root[data-theme="dark"] {
  --paper-dim: .92;
  --bg: #171613;
  --bg-sunken: #13110f;
  --surface: #1e1d1a;
  --surface-raised: #262421;
  --line: #44423f;
  --line-strong: #82807c;
  --scrim: rgba(0, 0, 0, .6);
  --hover: rgba(255, 255, 255, .07);
  --press: rgba(255, 255, 255, .12);

  /* dark mode's hierarchy comes from size and weight, not from greyer text (APCA: Lc 75 on L .23 needs L ≥ .85) */
  --ink: #edebe7;
  --ink-2: #dddad6;
  --muted: #d3d1cd;
  --faint: #a09e9a;
  --icon: #e0deda;
  --icon-quiet: #c6c4c0;

  /* the solids stay the same as in light (no glowing pastels); their inks get light */
  --accent-ink: #96e1e0;
  --accent-soft: #043030;
  --accent-line: #135e5e;
  --focus: #5ac5c4;
  --speak-ink: #a1e4ae;
  --speak-soft: #172f1d;
  --speak-line: #13632f;
  --hand-ink: #fad08f;
  --hand-soft: #35260c;
  --hand-line: #7a5613;
  --danger-ink: #fcc9c4;
  --danger-soft: #3c201d;
  --danger-line: #99161e;
  --rate-2: #3b2414; --rate-2-ink: #ffc49a;

  --tip-bg: #f1eeea;
  --tip-ink: #1a2027;

  --stage: #282623;
  --stage-raised: #34322e;
  --stage-av: #4b4842;
  --stage-ink: #edebe7;
  --stage-muted: #d3d1cd;
  --stage-chip: rgba(0, 0, 0, .62);
  --stage-rec: #f86a65;
  --paper: #eae9e6;

  --shadow-1: 0 1px 2px rgba(0, 0, 0, .3);
  --shadow-2: 0 10px 28px rgba(0, 0, 0, .45), 0 1px 4px rgba(0, 0, 0, .3);
  --shadow-3: 0 28px 72px rgba(0, 0, 0, .6), 0 4px 12px rgba(0, 0, 0, .35);
  --swatch-edge: rgba(255, 255, 255, .34);
  --mark-ok: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%231e1d1a' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
  --ic-search: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23d3d1cd' stroke-width='2' stroke-linecap='round'%3E%3Ccircle cx='11' cy='11' r='7.5'/%3E%3Cpath d='m21 21-4.3-4.3'/%3E%3C/svg%3E");
  color-scheme: dark;
}
/* A student reads nothing under 16 px (A1: Persian at 16 px is the smallest a 10-year-old reads at speed on a
   phone); the small steps lift. app.js sets data-who from the link or the join. */
html[data-who="student"] {
  --fs-meta: 1rem;
  --fs-micro: 1rem;
  --fs-xs: 1rem;
  --fs-s: 1rem;
  --fs-sm: 1rem;
}
/* Reduced motion (the device's, or the person's choice html[data-motion="reduce"]): no travel, short fades, no pings,
   no breathing; feedback stays (A3 §7, WCAG 2.3.3). */
@media (prefers-reduced-motion: reduce) {
  :root:not([data-motion="full"]) { --move: 0; --dur-slow: 160ms; --dur-fade: 200ms; --dur-ping: 0ms; --dur-breathe: 0ms; }
}
:root[data-motion="reduce"] { --move: 0; --dur-slow: 160ms; --dur-fade: 200ms; --dur-ping: 0ms; --dur-breathe: 0ms; }
/* ===== tokens: end ===== */

/* ---------- base ---------- */
* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { margin: 0; }
body {
  background: var(--bg);
  color: var(--ink);
  font-family: "Vazirmatn", Tahoma, "Segoe UI", system-ui, sans-serif;
  font-size: var(--fs);
  line-height: 1.7;
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  -webkit-tap-highlight-color: transparent;
  min-height: 100dvh;
  font-feature-settings: "ss01" 0;
  -webkit-font-smoothing: antialiased;
}
button, input, select, textarea { font: inherit; color: inherit; }
a { color: var(--accent-ink); text-underline-offset: 3px; }
h1, h2, h3 { line-height: 1.45; }
:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
::selection { background: var(--accent-soft); }
kbd {
  display: inline-grid; place-items: center;
  min-width: 20px; height: 20px; padding: 0 5px;
  border-radius: 6px; border: 1px solid var(--line-strong); border-bottom-width: 2px;
  background: var(--surface); color: var(--muted);
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace; font-size: var(--fs-badge); font-weight: var(--fw-b); line-height: 1;
  direction: ltr;
}

/* ---------- icons (icons.js): one family. Beside a word: 20 px, stroke 1.75. Where the icon is the control's only
   label (the bars, the tool strips, icon buttons): 24 px, stroke 2, in --icon (A1: «icons are text»). ---------- */
.ic {
  width: 20px; height: 20px; flex: none;
  fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round;
}
.ic-24, .cb-ic .ic, .tl .ic, .btn.icon .ic { width: 24px; height: 24px; stroke-width: 2; }
[dir="rtl"] .ic.flip { transform: scaleX(-1); }

.wrap {
  max-width: 460px;
  margin: 0 auto;
  padding: max(20px, env(safe-area-inset-top)) max(16px, env(safe-area-inset-right)) max(24px, env(safe-area-inset-bottom)) max(16px, env(safe-area-inset-left));
}

/* The wordmark: a small turquoise mark (three voice bars) before «جارچی». */
.brand { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 10px; margin: 8px 0 20px; }
.brand h1 { display: flex; align-items: center; gap: 10px; font-size: var(--fs-lg); font-weight: var(--fw-x); margin: 0; letter-spacing: 0; }
.brand h1::before, .mark {
  content: "";
  flex: none;
  width: 32px; height: 32px;
  border-radius: 10px;
  background: var(--accent) var(--mark-bars) center / 100% no-repeat;
}
.brand span { color: var(--muted); font-size: var(--fs-sm); }

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--r-card);
  padding: var(--s5);
  margin-bottom: var(--s4);
  box-shadow: var(--shadow-1);
}
.card h2 { font-size: var(--fs-md); margin: 0 0 4px; font-weight: var(--fw-x); }
.hint { color: var(--muted); font-size: var(--fs-sm); margin: 0 0 12px; }

/* ---------- buttons (the kit) ----------
   .btn            primary: the one main action (turquoise, full width by default)
   .btn.ghost      secondary: outlined
   .btn.quiet      ghost: text only
   .btn.danger     end / remove (red); .btn.ghost.danger / .btn.danger-line: outlined red
   .btn.icon       a square icon-only button (aria-label + data-tip)
   .btn.small      auto width, 44 px; .btn.tiny compact (still a 44 px target)
   Every button: a hover tint (mouse only), a press, a focus ring, a quiet disabled look. The room's bar buttons
   (.cb) and the board's tool strip (.tl) follow the same states. */
.btn {
  appearance: none;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  padding: 10px 18px;
  min-height: 48px;
  font-weight: var(--fw-b);
  line-height: 1.4;
  text-align: center;
  text-decoration: none;
  cursor: pointer;
  background: var(--accent);
  color: var(--on-accent);
  width: 100%;
  touch-action: manipulation;
  transition: background-color var(--t-fast) var(--ease), border-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease),
    box-shadow var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.btn .ic { width: 20px; height: 20px; }
.btn:disabled, .btn[aria-disabled="true"] { opacity: .45; cursor: default; }
.btn:not(:disabled):active { transform: scale(.98); }
.btn.ghost { background: var(--surface); color: var(--accent-ink); border-color: var(--line-strong); }
.btn.quiet { background: transparent; color: var(--muted); border-color: transparent; }
.btn.danger { background: var(--danger); color: var(--on-solid); }
.btn.ghost.danger, .btn.danger-line { background: var(--surface); color: var(--danger-ink); border-color: var(--danger-line); }
.btn.small { width: auto; min-height: var(--tap); padding: 8px 16px; font-size: var(--fs-sm); }
.btn.tiny { width: auto; min-height: var(--tap); min-width: var(--tap); padding: 4px 12px; font-size: var(--fs-s); border-radius: 10px; white-space: nowrap; }
.btn.icon { width: var(--tap); min-width: var(--tap); min-height: var(--tap); padding: 0; background: transparent; color: var(--muted); border-radius: var(--r-ctl); }
.btn:focus-visible, input:focus-visible, select:focus-visible, textarea:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
a.btn { text-decoration: none; }
/* Hover only where there is a mouse (a tap must not leave a button looking pressed). */
@media (hover: hover) {
  .btn:where(:not(:disabled)):hover { background: var(--accent-hover); }
  .btn.ghost:where(:not(:disabled)):hover { background: var(--accent-soft); border-color: var(--accent-line); }
  .btn.quiet:where(:not(:disabled)):hover, .btn.icon:where(:not(:disabled)):hover { background: var(--hover); color: var(--ink); }
  .btn.danger:where(:not(:disabled)):hover { background: var(--danger-hover); }
  .btn.ghost.danger:where(:not(:disabled)):hover, .btn.danger-line:where(:not(:disabled)):hover { background: var(--danger-soft); }
}
.btn.quiet:where(:not(:disabled)):active, .btn.icon:where(:not(:disabled)):active { background: var(--press); }

/* ---------- motion: things that come and go fade and rise a little (--t-fast / --t-med; none for reduced motion) ---------- */
@keyframes kit-pop { from { opacity: 0; transform: translateY(calc(6px * var(--move))) scale(calc(1 - .02 * var(--move))); } }
@keyframes kit-fade { from { opacity: 0; } }
@keyframes kit-rise { from { transform: translateY(calc(24px * var(--move))); opacity: .4; } }
.kit-pop { animation: kit-pop var(--t-med) var(--ease); }
.kit-fade { animation: kit-fade var(--t-med) var(--ease); }

/* ---------- the tooltip (ui.js): one at a time, on a mouse's rest or a keyboard's focus, with the shortcut ---------- */
.tip {
  position: fixed; z-index: 60; top: 0; left: 0;
  display: inline-flex; align-items: center; gap: 8px;
  max-width: min(280px, calc(100vw - 16px));
  padding: 5px 10px;
  border-radius: var(--r-sm);
  background: var(--tip-bg); color: var(--tip-ink);
  font-size: var(--fs-s); font-weight: var(--fw-m); line-height: 1.5;
  box-shadow: 0 6px 18px rgba(0, 0, 0, .22);
  pointer-events: none;
  opacity: 0;
  transition: opacity var(--t-fast) var(--ease);
}
.tip[data-on="1"] { opacity: 1; }
.tip kbd { background: transparent; border-color: currentColor; color: inherit; }

/* ---------- loading: a skeleton line or block that breathes ---------- */
.skel {
  display: block; border-radius: var(--r-sm);
  background: linear-gradient(90deg, var(--bg-sunken) 0%, var(--line) 50%, var(--bg-sunken) 100%) 0 0 / 200% 100%;
  animation: skel 1.4s ease-in-out infinite;
}
.skel-line { height: 14px; margin: 8px 0; }
.skel-row { height: 44px; margin: 6px 0; border-radius: var(--r); }
@keyframes skel { from { background-position: 100% 0; } to { background-position: -100% 0; } }
@media (prefers-reduced-motion: reduce) { .skel { animation: none; } }

.sr-only {
  position: absolute !important; width: 1px; height: 1px; margin: -1px; padding: 0;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap; border: 0;
}

/* ---------- an empty list's one helpful line ---------- */
.empty-state {
  display: flex; flex-direction: column; align-items: center; gap: 4px;
  padding: 20px 12px; text-align: center; color: var(--muted);
}
.empty-state .ic { width: 24px; height: 24px; color: var(--faint); margin-bottom: 4px; }
.empty-state b { color: var(--ink-2); font-size: var(--fs-sm); font-weight: var(--fw-b); }
.empty-state span { font-size: var(--fs-s); line-height: 1.6; }

.linkrow { display: flex; gap: 8px; align-items: center; }
.linkbox {
  flex: 1;
  min-width: 0;
  direction: ltr;
  text-align: left;
  font-family: ui-monospace, "SFMono-Regular", Menlo, monospace;
  font-size: var(--fs-micro);
  background: var(--bg-sunken);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 10px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ---------- forms ---------- */
label { display: block; font-weight: var(--fw-b); font-size: var(--fs-sm); margin-bottom: 6px; }
input[type=text], input[type=search], textarea {
  width: 100%;
  min-height: 48px;
  padding: 10px 14px;
  border: 1px solid var(--line-strong);
  border-radius: var(--r-ctl);
  background: var(--surface);
  margin-bottom: 12px;
  transition: border-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease), background-color var(--t-fast) var(--ease);
}
input[type=text]::placeholder, input[type=search]::placeholder, textarea::placeholder { color: var(--faint); }
@media (hover: hover) { input[type=text]:hover, input[type=search]:hover, textarea:hover { border-color: var(--faint); } }
input[type=text]:focus, input[type=search]:focus, textarea:focus {
  border-color: var(--accent); outline: none;
  box-shadow: 0 0 0 3px var(--accent-soft);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--accent) 32%, transparent);
}
input[type=text]:focus-visible, input[type=search]:focus-visible, textarea:focus-visible { outline: none; }
.err { color: var(--danger-ink); font-size: var(--fs-sm); margin: 8px 0 0; min-height: 1em; }
.err.quiet { margin: 0 0 12px; }
.err.quiet:empty { display: none; }

/* ---------- small things ---------- */
.top { display: flex; justify-content: space-between; align-items: center; margin: 4px 0 16px; gap: 8px; }
.top h1 { font-size: var(--fs-heading); margin: 0; font-weight: 800; }

/* A status pill (not a button): turquoise by default, .bad for trouble, .ok / .warn / .hand by meaning. */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-meta);
  font-weight: 700;
  line-height: 1.5;
  padding: 3px 10px;
  border-radius: var(--r-pill);
  background: var(--accent-soft);
  color: var(--accent-ink);
  white-space: nowrap;
}
.chip.ok { background: var(--bg-sunken); color: var(--ink-2); }
.chip.warn { background: var(--hand-soft); color: var(--hand-ink); }
.chip.hand { background: var(--hand-soft); color: var(--hand-ink); }
.chip.bad { background: var(--danger-soft); color: var(--danger-ink); }

/* A quiet label next to a name («معلم»، «خودت»). */
.tag {
  display: inline-block;
  font-size: var(--fs-xs);
  font-weight: 500;
  line-height: 1.6;
  color: var(--muted);
  background: var(--bg-sunken);
  border-radius: var(--r-pill);
  padding: 0 8px;
  white-space: nowrap;
}

/* A one-line message in a soft box: .notice (attention), .notice.ok, .notice.bad. */
.notice {
  background: var(--hand-soft); color: var(--hand-ink);
  border-radius: var(--r); padding: 10px 14px; margin: 0 0 12px; font-weight: 700; font-size: var(--fs-body);
}
.notice.ok { background: var(--bg-sunken); color: var(--ink-2); }
.notice.bad { background: var(--danger-soft); color: var(--danger-ink); }

.avatar {
  flex: none;
  width: 40px; height: 40px; border-radius: 50%;
  display: grid; place-items: center;
  background: var(--accent-soft); color: var(--accent-ink);
  font-weight: 800;
  line-height: 1;
}

.foot { display: flex; justify-content: center; gap: 8px; flex-wrap: wrap; }

/* ---------- tables (attendance) ---------- */
.tablewrap { overflow-x: auto; margin: 6px 0 14px; }
table.att { width: 100%; border-collapse: collapse; font-size: var(--fs-sm); }
table.att th { text-align: start; color: var(--muted); font-weight: 700; padding: 6px 8px; font-size: var(--fs-meta); border-bottom: 1px solid var(--line); }
table.att td { padding: 10px 8px; border-top: 1px solid var(--line); }
table.att tbody tr:first-child td { border-top: 0; }
table.att td .tag { margin-inline-start: 6px; }
.st { font-weight: 700; }
.st-present { color: var(--ink-2); }
.st-late, .st-left_early { color: var(--hand-ink); }
.st-absent { color: var(--muted); }

/* ====================================================================================================
   The class room (app.js Session): a webinar around the stage
   A thin top bar (the mark, the class's name, the time, recording, the connection dot); the stage (stage.js)
   filling the middle on a calm dark ground; one bottom bar of icon buttons with a word under each; one side panel
   (participants with the hands first, and the chat) that opens from the bar: beside the stage on a wide screen, a
   sheet over it on a phone. The page itself never scrolls. Everything here is built from the kit above: the
   type scale, the 4/8 spacing, radii and depth by role, 120/200 ms motion.
   ==================================================================================================== */

.wrap.room-wrap { max-width: none; padding: 0; }
body.in-room .ver { display: none; }
body.in-room { overflow: hidden; }

.room {
  --rbar-h: 56px;
  --cbar-h: 64px;
  --side-w: 340px;
  --gut: 16px;
  height: 100dvh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
  background: var(--bg);
}

@keyframes room-blink { 50% { opacity: .3; } }

/* ---------- the top bar ---------- */
.rbar {
  flex: none;
  position: relative; z-index: 10;
  display: flex; align-items: center; gap: 8px 12px;
  min-height: var(--rbar-h);
  padding: max(4px, env(safe-area-inset-top)) max(var(--gut), env(safe-area-inset-right)) 4px max(var(--gut), env(safe-area-inset-left));
  background: var(--surface);
  border-bottom: 1px solid var(--line);
}
.rbar-title { flex: 1 1 0; min-width: 0; display: flex; align-items: center; gap: 12px; }
.rbar-mark { width: 28px; height: 28px; border-radius: 8px; }
.rbar-names { min-width: 0; display: flex; align-items: baseline; gap: 2px 12px; }
.rbar h1 {
  margin: 0; min-width: 0; font-size: var(--fs); font-weight: var(--fw-x); line-height: 1.5;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.rbar-sub {
  display: flex; align-items: center; flex: none; min-width: 0;
  margin: 0; color: var(--muted); font-size: var(--fs-s); font-weight: var(--fw-m); line-height: 1.5; white-space: nowrap;
}
.rbar-sub > :not([hidden]):not(:empty) ~ :not([hidden]):not(:empty)::before { content: "·"; margin-inline: 8px; color: var(--faint); }
.rbar-sub > :empty { display: none; }
.rbar-who { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.rbar-clock { font-variant-numeric: tabular-nums; }
.rbar-rec { display: contents; }

/* The connection: signal bars, tap for the details (A1: a shape for every state, colour only confirms). Four bars
   in the icon's colour when it is fine (no colour for "fine"), two lit in amber when weak, × over empty bars in red
   when cut, one while connecting. The words (conn.js) are the button's text, kept for screen readers and the
   tooltip, not drawn (font-size 0). The bars are a CSS mask, so they take the button's colour. */
#conn {
  appearance: none; flex: none; position: relative;
  display: inline-grid; place-items: center;
  width: 48px; min-width: 48px; height: 48px; min-height: 48px; padding: 0;
  border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--icon);
  font-size: 0; line-height: 0; overflow: hidden;
  cursor: pointer; touch-action: manipulation;
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
#conn::before {
  content: ""; width: 24px; height: 24px;
  background: currentColor;
  -webkit-mask: var(--ic-signal-4) center / 24px no-repeat; mask: var(--ic-signal-4) center / 24px no-repeat;
}
#conn[data-q="weak"] { color: var(--hand-ink); }
#conn[data-q="weak"]::before { -webkit-mask-image: var(--ic-signal-2); mask-image: var(--ic-signal-2); }
#conn[data-q="wait"] { color: var(--muted); }
#conn[data-q="wait"]::before { -webkit-mask-image: var(--ic-signal-1); mask-image: var(--ic-signal-1); animation: room-blink 1.2s ease-in-out infinite; }
#conn[data-q="down"] { background: var(--danger-soft); color: var(--danger-ink); }
#conn[data-q="down"]::before { -webkit-mask-image: var(--ic-signal-x); mask-image: var(--ic-signal-x); }
@media (hover: hover) { #conn:hover { background: var(--hover); } #conn[data-q="down"]:hover { background: var(--danger-soft); } }
#conn:active { background: var(--press); }

/* Banners rejoin.js and prejoin.js put under the bar. */
.room > .rejoin, .room > .pj-unlock, .room > .pj-note { flex: none; width: auto; margin: 8px var(--gut) 0; animation: kit-pop var(--t-med) var(--ease); }
.room .pj-unlock { position: relative; top: auto; min-height: 64px; margin-bottom: 0; }

/* ---------- the body: the stage, and the side panel ---------- */
.room-body { flex: 1 1 auto; min-height: 0; display: flex; }
.room-main {
  position: relative;
  flex: 1 1 auto; min-width: 0; min-height: 0;
  display: flex; flex-direction: column; gap: 12px;
  padding: var(--gut);
  background: var(--stage);
  color: var(--stage-ink);
}
.room-main > .stg { flex: 1 1 auto; min-height: 0; }
.stage-notes { flex: none; display: flex; flex-direction: column; align-items: center; gap: 8px; }
.stage-notes:not(:has(> :not([hidden]):not(:empty))) { display: none; }
.stage-notes > * { max-width: min(560px, 100%); }
/* The toasts' column spans the stage's foot: only the toasts themselves take a tap, the pen writes beside them. */
.room-toasts { display: flex; flex-direction: column; align-items: center; gap: 8px; width: 100%; pointer-events: none !important; }
.room-toasts > * { pointer-events: auto; }
.room-toasts:empty { display: none; }
.room-toasts > :not([hidden]) { animation: kit-pop var(--t-med) var(--ease); }
.room .err.quiet {
  margin: 0; padding: 8px 16px; border-radius: var(--r-pop);
  background: var(--surface-raised); color: var(--danger-ink); font-weight: var(--fw-b); font-size: var(--fs-sm);
  box-shadow: var(--shadow-2), inset 0 0 0 1px var(--danger-line);
}
.room .pj-guide { margin: 0; color: var(--ink); }
.cam-note-slot:empty { display: none; }
/* On a wide screen (and a teacher's every screen) the notes and toasts float over the stage's foot, above the
   page's controls, so the page never jumps when one comes or goes. */
@media (min-width: 960px) {
  .stage-notes {
    position: absolute; z-index: 7;
    /* --notes-b: above the stage's foot (app.js notesAt: the page bar, a dock, the floating undo/redo) */
    inset-inline: var(--gut); bottom: var(--notes-b, calc(var(--gut) + var(--tap) + 20px));
    pointer-events: none;
  }
  .stage-notes > * { pointer-events: auto; }
}
.room[data-role="teacher"] .stage-notes {
  position: absolute; z-index: 7;
  inset-inline: var(--gut); bottom: var(--notes-b, calc(var(--gut) + var(--tap) + 20px));
  pointer-events: none;
}
.room[data-role="teacher"] .stage-notes > * { pointer-events: auto; }

/* Who is speaking: a small label in the stage's corner, with the voice's level. */
.spk {
  position: absolute; z-index: 6; top: calc(var(--gut) + 8px); inset-inline-end: calc(var(--gut) + 8px);
  display: inline-flex; align-items: center; gap: 8px;
  max-width: calc(100% - 2 * var(--gut) - 16px);
  padding: 6px 14px 6px 12px; border-radius: var(--r-pill);
  background: var(--stage-chip-strong); color: var(--stage-ink);
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  font-size: var(--fs-s); font-weight: var(--fw-b); line-height: 1.5;
  pointer-events: none;
  animation: kit-fade var(--t-med) var(--ease);
}
.spk-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.spk .lvl { height: 14px; gap: 2px; }
.spk .lvl i { width: 3px; background: var(--stage-live); }

/* ---------- voice levels ---------- */
.lvl { --l: 0; display: inline-flex; align-items: center; gap: 3px; height: 20px; flex: none; }
.lvl i {
  display: block; width: 3px; height: 100%; border-radius: 2px;
  background: var(--speak);
  transform: scaleY(.2);
  transition: transform .12s ease-out;
}
.lvl i:nth-child(1), .lvl i:nth-child(5) { transform: scaleY(max(.2, min(.6, calc(var(--l) * .7)))); }
.lvl i:nth-child(2), .lvl i:nth-child(4) { transform: scaleY(max(.2, min(.85, calc(var(--l) * 1)))); }
.lvl i:nth-child(3) { transform: scaleY(max(.2, min(1, calc(var(--l) * 1.3)))); }

/* ---------- a student's floor, in words above the bar ---------- */
.floor {
  display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 10px 18px; border-radius: var(--r-pop);
  background: var(--surface-raised); color: var(--ink);
  text-align: center; box-shadow: var(--shadow-2);
  animation: kit-pop var(--t-med) var(--ease);
}
.floor[hidden] { display: none; }
.floor .lead { display: inline-flex; align-items: center; gap: 8px; margin: 0; font-size: var(--fs-sm); font-weight: var(--fw-b); line-height: 1.6; }
.floor .lead.live { color: var(--speak-ink); }
.floor .hint { margin: 0; font-size: var(--fs-s); }
.floor .notice { margin: 0; padding: 0; background: none; font-size: var(--fs-sm); }
.floor .lvl { height: 18px; }
.floor-sub { margin: 0; color: var(--muted); font-size: var(--fs-s); line-height: 1.5; }
.countdown {
  margin: 4px 0 0; padding: 0 10px; border-radius: var(--r-pill);
  background: var(--speak); color: var(--on-solid);
  font-size: var(--fs-s); font-weight: var(--fw-b); line-height: 1.8; font-variant-numeric: tabular-nums;
}
.room[data-floor="hand"] .floor { box-shadow: var(--shadow-2), inset 0 0 0 1px var(--hand-line); }
.room[data-floor="hand"] .floor .lead { color: var(--hand-ink); }
.room[data-floor="offered"] .floor { background: var(--speak-soft); box-shadow: 0 0 0 2px var(--speak), var(--shadow-2); }
.room[data-floor="offered"] .floor .lead { color: var(--speak-ink); font-size: var(--fs); font-weight: var(--fw-x); }
.room[data-floor="muted"] .floor { box-shadow: var(--shadow-2), inset 0 0 0 1px var(--hand-line); }
.room[data-floor="muted"] .floor .notice { color: var(--hand-ink); }

/* The hands chip, for the teacher (A2 T2): the oldest hand, «+۲» for the rest, «اجازه» in one tap; it stays while
   hands wait and the hands list is out of sight. The amber disc and the hand glyph carry it, the name says who. */
.hand-toast {
  display: flex; align-items: center; gap: 6px;
  max-width: min(420px, 100%);
  padding: 4px; border-radius: var(--r-pill);
  background: var(--surface-raised); color: var(--ink); box-shadow: var(--shadow-2), inset 0 0 0 1.5px var(--hand-line);
  font-size: var(--fs-sm);
}
.hand-toast[hidden] { display: none; }
.ht-who {
  appearance: none; flex: 1 1 auto; min-width: 0;
  display: inline-flex; align-items: center; gap: 8px;
  min-height: 44px; padding: 0 10px 0 2px; border: 0; border-radius: var(--r-pill);
  background: transparent; color: inherit; font: inherit; cursor: pointer; touch-action: manipulation;
}
@media (hover: hover) { .ht-who:hover { background: var(--hover); } }
.ht-ic { flex: none; display: grid; place-items: center; width: 40px; height: 40px; border-radius: 50%; background: var(--hand); color: var(--on-hand); }
.ht-ic .ic { width: 22px; height: 22px; stroke-width: 2; }
.ht-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ht-text b { font-weight: var(--fw-x); }
.ht-more { flex: none; color: var(--muted); font-weight: var(--fw-b); font-variant-numeric: tabular-nums; }
.hand-toast .btn.tiny { flex: none; min-width: 76px; min-height: 44px; border-radius: var(--r-pill); }

/* ---------- the bottom bar ---------- */
.cbar {
  flex: none;
  position: relative; z-index: 12;
  display: grid; grid-template-columns: 1fr auto 1fr; align-items: center; gap: 8px;
  min-height: var(--cbar-h);
  padding: 6px max(var(--gut), env(safe-area-inset-right)) max(6px, env(safe-area-inset-bottom)) max(var(--gut), env(safe-area-inset-left));
  background: var(--surface);
  border-top: 1px solid var(--line);
}
.cbar-group { display: flex; align-items: center; gap: 6px; min-width: 0; }
.cbar-me { justify-self: start; }
.cbar-stage { justify-self: center; }
.cbar-room { justify-self: end; grid-column: 3; }
.room[data-role="student"] .cbar { grid-template-columns: 1fr auto 1fr; }
.room[data-role="student"] .cbar-me { grid-column: 2; justify-self: center; }
.cb-slot { display: contents; }
.cb-slot[hidden] { display: none; }
.stg-switch { display: flex; align-items: center; gap: 4px; }
/* Groups by spacing only: mic and camera · the stage · hands, people, chat · «بیشتر» · the end. */
.cbar-sep { width: 14px; height: 1px; }
.cbar-room > .cb-more { margin-inline-start: 14px; }

/* One bar button: an icon alone (the owner: as minimal as it can be, the lesson keeps the eye). Its name stays the
   button's accessible name (.cb-label, out of sight) and shows as the kit's tooltip (ui.js: a mouse resting, the
   keyboard's focus, a long press on a touch screen). Every bar button has the same 48px shape and states: hover
   tint, press, focus ring; "open" or "chosen" (the panel it opens, what is on the stage) in turquoise; "on the air"
   (my mic, my camera, my screen) in green; "off and it matters" (my mic) in red. */
.cb {
  appearance: none; position: relative;
  display: inline-flex; flex-direction: column; align-items: center; justify-content: center;
  min-width: 48px; min-height: 48px; padding: 2px;
  border: 0; border-radius: var(--r-pill);
  background: transparent; color: var(--muted);
  font-size: var(--fs-xs); font-weight: var(--fw-m); line-height: 1.35;
  cursor: pointer; touch-action: manipulation;
  -webkit-touch-callout: none; -webkit-user-select: none; user-select: none;
}
.cb:focus-visible { outline-offset: 0; }
.cb-ic {
  position: relative;
  display: grid; place-items: center;
  width: 44px; height: 44px; border-radius: var(--r-pill);
  color: var(--ink);
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease), box-shadow var(--t-fast) ease-out, transform var(--t-fast) var(--ease);
}
.cb-ic .ic { width: 24px; height: 24px; }
.cb-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); opacity: 0; white-space: nowrap; pointer-events: none; }
.cb:disabled { opacity: .45; cursor: default; }
@media (hover: hover) { .cb:not(:disabled):hover .cb-ic { background: var(--hover); } }
.cb:not(:disabled):active .cb-ic { background: var(--press); transform: scale(.94); }
.cb[aria-pressed="true"] .cb-ic, .cb[aria-expanded="true"] .cb-ic { background: var(--accent-soft); color: var(--accent-ink); }
.cb[aria-pressed="true"] .cb-label, .cb[aria-expanded="true"] .cb-label { color: var(--accent-ink); }
/* The mic: crossed and red while off; green with a ring that follows the voice while on. */
.cb-mic[data-state="off"] .cb-ic, .cb-mic:not([data-state]) .cb-ic { background: var(--danger-soft); color: var(--danger-ink); }
.cb-mic[data-state="off"] .cb-label { color: var(--danger-ink); }
.cb-mic[data-state="on"] .cb-ic { --l: 0; background: var(--speak-soft); color: var(--speak-ink); box-shadow: 0 0 0 calc(var(--l) * 5px) var(--speak-line); }
.cb-mic[data-state="on"] .cb-label { color: var(--speak-ink); }
.cb-mic[data-state="wait"] .cb-ic { background: var(--bg-sunken); color: var(--muted); }
@media (hover: hover) {
  .cb-mic[data-state="off"]:not(:disabled):hover .cb-ic { background: var(--danger-line); }
  .cb-mic[data-state="on"]:not(:disabled):hover .cb-ic { background: var(--speak-line); }
}
/* The camera and the share read like a voice on the air while on. */
.cam-tile[data-state="on"] .cb-ic, .stg-share[aria-pressed="true"] .cb-ic { background: var(--speak-soft); color: var(--speak-ink); }
.cam-tile[data-state="on"] .cb-label, .stg-share[aria-pressed="true"] .cb-label { color: var(--speak-ink); }
.cam-tile:is([data-state="lost"], [data-state="fail"], [data-state="denied"], [data-state="nodevice"]) .cb-ic,
.stg-share:is([data-state="lost"], [data-state="fail"]) .cb-ic { background: var(--hand-soft); color: var(--hand-ink); }
.cam-tile .cam-prev, .cam-tile .cam-txt { display: none !important; }
/* The hands: amber while someone waits; a lock badge while the floor is locked. */
.cb-hands[data-on="1"] .cb-ic { background: var(--hand-soft); color: var(--hand-ink); }
.cb-hands[data-on="1"] .cb-label { color: var(--hand-ink); }
.cb-hands[data-locked="1"] .cb-ic::after, .cb-thumb.locked .cb-ic::after {
  content: ""; position: absolute; bottom: -2px; inset-inline-start: 4px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--hand) var(--badge-lock) center / 10px no-repeat;
  box-shadow: 0 0 0 2px var(--surface);
}
.nbadge {
  position: absolute; top: 0; inset-inline-end: 0; /* inside the button's own box: never over a neighbour */
  min-width: 18px; height: 18px; padding: 0 5px;
  display: grid; place-items: center;
  border-radius: var(--r-pill);
  background: var(--ink-2); color: var(--surface);
  font-size: var(--fs-badge); font-weight: var(--fw-x); line-height: 1;
  box-shadow: 0 0 0 2px var(--surface);
  animation: kit-pop var(--t-med) var(--ease);
}
.nbadge:empty { display: none; }
.hand-n { background: var(--hand); color: var(--on-hand); }
.chat-nbadge { background: var(--accent); color: var(--on-accent); }
.cb-leave .cb-ic { color: var(--muted); }

/* «پایان کلاس»: set apart by space, a red icon (its «کلاس برای همه تموم بشه؟» asks before anything happens). */
.cb-end { flex-direction: row; gap: 6px; min-height: 44px; padding: 0 16px 0 14px; border-radius: var(--r-pill); background: var(--danger); color: var(--on-solid); }
.cb-end .cb-ic { width: auto; height: auto; background: none !important; color: inherit; transform: none !important; }
.cb-end .cb-ic .ic { width: 20px; height: 20px; stroke-width: 2.25; }
.cb-end .cb-label { position: static; width: auto; height: auto; overflow: visible; clip-path: none; opacity: 1; color: inherit !important; font-size: var(--fs-label); font-weight: var(--fw-x); }
.cb-end:not(:disabled):active { transform: scale(.97); }
@media (hover: hover) { .cb-end:not(:disabled):hover { background: var(--danger-hover); } }

/* A student's one button: big, in the thumb zone. */
.cb-thumb {
  flex-direction: row; gap: 10px;
  min-width: 184px; min-height: 52px; padding: 0 24px 0 20px;
  border-radius: var(--r-pill);
  background: var(--accent); color: var(--on-accent);
  font-size: var(--fs); font-weight: var(--fw-x);
  box-shadow: 0 2px 8px rgba(25, 124, 124, .22);
  transition: background-color var(--t-fast) var(--ease), box-shadow var(--t-fast) var(--ease), transform var(--t-fast) var(--ease);
}
.cb-thumb .cb-ic { width: auto; height: auto; background: none !important; color: inherit; transform: none !important; }
.cb-thumb .cb-ic .ic { width: 24px; height: 24px; }
.cb-thumb .cb-label { position: static; width: auto; height: auto; overflow: visible; clip-path: none; opacity: 1; color: inherit !important; }
.cb-thumb:not(:disabled):active { transform: scale(.97); }
@media (hover: hover) { .cb-thumb:not(:disabled):hover { background: var(--accent-hover); } }
.cb-thumb.hand-up { background: var(--hand-soft); color: var(--hand-ink); box-shadow: inset 0 0 0 1.5px var(--hand-line); }
.cb-thumb.ready {
  background: var(--speak); color: var(--on-solid);
  box-shadow: 0 0 0 0 var(--speak-line);
  animation: room-offer 1.6s ease-in-out infinite;
}
.cb-thumb.ready:disabled { animation: none; }
.cb-thumb.giveback { background: var(--speak-soft); color: var(--speak-ink); box-shadow: inset 0 0 0 1.5px var(--speak-line); }
.room[data-floor="muted"] .cb-thumb.giveback { background: var(--hand-soft); color: var(--hand-ink); box-shadow: inset 0 0 0 1.5px var(--hand-line); }
.cb-thumb.locked { background: var(--bg-sunken); color: var(--muted); box-shadow: none; opacity: 1; }
@keyframes room-offer { 50% { box-shadow: 0 0 0 7px var(--speak-line); } }
@media (hover: hover) {
  .cb-thumb.hand-up:not(:disabled):hover { background: var(--hand-line); }
  .cb-thumb.ready:not(:disabled):hover { background: var(--speak-hover); }
  .cb-thumb.giveback:not(:disabled):hover { background: var(--speak-line); }
}

/* ---------- «بیشتر» ---------- */
.more-menu {
  position: fixed; z-index: 25;
  bottom: calc(var(--cbar-h) + env(safe-area-inset-bottom) + 8px);
  inset-inline-end: max(12px, env(safe-area-inset-left));
  width: min(360px, 100vw - 24px);
  max-height: calc(100dvh - var(--cbar-h) - var(--rbar-h) - 24px);
  overflow-y: auto; overscroll-behavior: contain;
  display: flex; flex-direction: column; gap: 2px;
  padding: 6px;
  background: var(--surface-raised); color: var(--ink);
  border: 1px solid var(--line); border-radius: var(--r-pop);
  box-shadow: var(--shadow-2);
  transform-origin: bottom left;
  animation: kit-pop var(--t-med) var(--ease);
}
@media (max-width: 959px) { .room[data-role="student"] .more-menu { inset-inline: 0; margin-inline: auto; transform-origin: bottom center; } }
.more-list, .more-extra { display: flex; flex-direction: column; gap: 2px; }
.more-extra:empty { display: none; }
.more-extra:not(:empty) + * { border-top: 1px solid var(--line); padding-top: 4px; margin-top: 2px; }
.more-foot { display: flex; flex-direction: column; gap: 2px; border-top: 1px solid var(--line); padding-top: 4px; margin-top: 2px; }
.more-foot:empty { display: none; }
.more-row, .room .fb-open {
  appearance: none; position: static;
  display: flex; align-items: center; gap: 12px;
  width: 100%; min-height: 48px; padding: 6px 12px;
  border: 0; border-radius: 10px;
  background: transparent; color: var(--ink);
  font-size: var(--fs-sm); font-weight: var(--fw-m); text-align: start;
  cursor: pointer; box-shadow: none;
  transition: background-color var(--t-fast) var(--ease);
}
.more-row .ic, .room .fb-open svg { width: 20px; height: 20px; color: var(--muted); }
.more-row > span { flex: 1 1 auto; min-width: 0; }
.more-row kbd { flex: none; }
@media (hover: hover) { .more-row:hover, .room .fb-open:hover { background: var(--hover); color: var(--ink); border-color: transparent; } }
.more-row:active, .room .fb-open:active { background: var(--press); }
.room .fb-spacer { height: auto; }
.phone-only { display: none; }
/* The teacher's keyboard shortcuts, at the foot of «بیشتر» (only where there is a keyboard). */
.more-keys { display: none; }
@media (hover: hover) and (pointer: fine) {
  .more-keys {
    display: flex; flex-wrap: wrap; align-items: center; gap: 6px 12px;
    margin-top: 2px; padding: 10px 12px 6px; border-top: 1px solid var(--line);
    color: var(--muted); font-size: var(--fs-xs); font-weight: var(--fw-m);
  }
  .more-keys > b { flex: 1 1 100%; color: var(--muted); font-weight: var(--fw-b); }
  .more-keys > span { display: inline-flex; align-items: center; gap: 4px; }
}
/* Class tools as rows: an icon, the name and its state, a switch or a button. */
.tool {
  display: flex; align-items: center; gap: 12px;
  min-height: 56px; padding: 6px 6px 6px 12px;
  border: 0; border-radius: 10px;
  background: transparent; min-width: 0;
  transition: background-color var(--t-fast) var(--ease);
}
.tool[hidden] { display: none; }
.tool-ic {
  flex: none; display: grid; place-items: center;
  width: 36px; height: 36px; border-radius: 10px;
  background: var(--bg-sunken); color: var(--muted);
  transition: background-color var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.tool-txt { flex: 1; min-width: 0; display: flex; flex-direction: column; line-height: 1.45; }
.tool-txt b { font-size: var(--fs-sm); font-weight: var(--fw-b); }
.tool-txt small { color: var(--muted); font-size: var(--fs-xs); }
.tool[data-on="1"] .tool-ic { background: var(--hand-soft); color: var(--hand-ink); }
.tool[data-on="1"] small { color: var(--hand-ink); }

/* An on/off switch (a button with aria-pressed; the row's title names it). */
.switch {
  appearance: none; position: relative; flex: none;
  width: 56px; height: var(--tap);
  border: 0; padding: 0; margin: 0;
  background: transparent; cursor: pointer;
  border-radius: var(--r-pill);
  touch-action: manipulation;
}
.switch::before {
  content: ""; position: absolute; inset-inline: 6px; top: 11px; height: 22px;
  border-radius: var(--r-pill); background: var(--line-strong);
  transition: background-color var(--t-med) var(--ease);
}
.switch::after {
  content: ""; position: absolute; top: 14px; inset-inline-start: 9px;
  width: 16px; height: 16px; border-radius: 50%;
  background: var(--knob); box-shadow: 0 1px 3px rgba(0, 0, 0, .3);
  transition: transform var(--t-med) var(--ease);
}
.switch[aria-pressed="true"]::before { background: var(--accent); }
.switch[aria-pressed="true"]::after { transform: translateX(-20px); }
[dir="ltr"] .switch[aria-pressed="true"]::after { transform: translateX(20px); }
.switch:disabled { opacity: .5; cursor: progress; }
.switch:focus-visible { outline-offset: -2px; }

/* ---------- the side panel ---------- */
.room-side {
  flex: none;
  width: var(--side-w);
  display: flex; flex-direction: column; min-height: 0;
  background: var(--surface);
  border-inline-start: 1px solid var(--line);
  animation: kit-fade var(--t-med) var(--ease);
}
.room[data-panel=""] .room-side, .room:not([data-panel]) .room-side { display: none; }
.side-head { flex: none; display: flex; align-items: flex-end; gap: 4px; min-height: 56px; padding: 0 8px 0 12px; border-bottom: 1px solid var(--line); }
.side-head > .side-x { align-self: center; }
.side-tabs { flex: 1 1 auto; min-width: 0; display: flex; align-self: stretch; }
.side-tabs:empty { display: none; }
.side-title { flex: 1 1 auto; align-self: center; display: flex; align-items: center; gap: 8px; margin: 0; font-size: var(--fs); font-weight: var(--fw-x); }
.side-tabs:not(:empty) + .side-title { display: none; }
.side-x { color: var(--muted); }
.side-x .ic { width: 20px; height: 20px; }
.side-pane { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 8px 8px 16px; }
.room-side[data-tab="chat"] > .side-pane { display: none; }
.room-side > .chat { padding: 8px 12px 12px; }
.count {
  display: inline-grid; place-items: center;
  min-width: 22px; height: 20px; padding: 0 6px;
  border-radius: var(--r-pill);
  background: var(--bg-sunken); color: var(--muted);
  font-size: var(--fs-xs); font-weight: var(--fw-b); line-height: 1;
}
.count:empty { display: none; }

/* The people search (a class of 12 or more). */
.people-search {
  margin: 4px 4px 8px; width: calc(100% - 8px); min-height: var(--tap);
  padding-inline-start: 40px; border-radius: var(--r-pill);
  background: var(--bg-sunken) var(--ic-search) no-repeat right 14px center / 18px;
  border-color: transparent;
}
[dir="ltr"] .people-search { background-position: left 14px center; }
.people-search:focus { background-color: var(--surface); border-color: var(--accent); }
.people-none { margin: 8px 12px 0; }

/* The participants: the hands first, in the order they came up, with «اجازه» at hand; then everyone else. Each
   person is in one place only. */
.people { display: flex; flex-direction: column; }
.people-list { list-style: none; padding: 0; margin: 0; }
.people-label { margin: 8px 8px 2px; color: var(--muted); font-size: var(--fs-xs); font-weight: var(--fw-b); }
.people-label[hidden] { display: none; }
.prow {
  display: flex; align-items: center; flex-wrap: wrap; gap: 4px 12px;
  min-height: 52px; padding: 6px 8px;
  border-radius: 10px;
  transition: background-color var(--t-fast) var(--ease);
}
.prow[hidden] { display: none; }
@media (hover: hover) { .prow:hover { background: var(--hover); } }
.avatar { position: relative; }
.prow .avatar { width: 36px; height: 36px; font-size: var(--fs-sm); }
.prow[data-role="student"] .avatar { background: var(--bg-sunken); color: var(--ink-2); }
.spk-dot { display: none; }
.prow.speaking .avatar { box-shadow: 0 0 0 2px var(--surface), 0 0 0 4px var(--speak); }
.who { flex: 1 1 96px; min-width: 96px; display: flex; flex-direction: column; gap: 0; line-height: 1.45; }
.pname-row { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
.pname { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: var(--fw-m); font-size: var(--fs-sm); }
.pme { flex: none; color: var(--muted); font-size: var(--fs-xs); font-weight: var(--fw); }
.psub { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: var(--fs-xs); }
.psub:empty { display: none; }
.psub.live { color: var(--speak-ink); font-weight: var(--fw-b); }
.psub.warn { color: var(--hand-ink); font-weight: var(--fw-b); }
.psub.offer { color: var(--accent-ink); font-weight: var(--fw-b); }
.prow .lvl { height: 16px; gap: 2px; }
.prow .lvl i { width: 3px; }
.prow .acts { display: flex; gap: 4px; flex: none; margin-inline-start: auto; }
.prow .acts .btn.tiny { min-width: var(--tap); padding-inline: 12px; }
.prow .acts .mod-more { width: var(--tap); padding: 0; color: var(--muted); }
/* With a mouse, a row's quiet actions show on hover or focus (the floor's live actions always show). */
@media (hover: hover) and (pointer: fine) {
  .prow .acts > .quiet-act { opacity: 0; transition: opacity var(--t-fast) var(--ease); }
  .prow:hover .acts > .quiet-act, .prow:focus-within .acts > .quiet-act { opacity: 1; }
}

/* The hands: a soft amber group at the top. */
.hands { margin: 0 0 8px; padding: 4px; border-radius: var(--r-pop); background: var(--hand-soft); animation: kit-pop var(--t-med) var(--ease); }
.hands[hidden] { display: none; }
.hands-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; min-height: var(--tap); padding-inline: 8px 0; }
.hands-head h3 { display: flex; align-items: center; gap: 6px; margin: 0; font-size: var(--fs-s); font-weight: var(--fw-x); color: var(--hand-ink); }
.hands-head h3 .ic { width: 18px; height: 18px; }
.hands .count { background: var(--surface); color: var(--hand-ink); }
.hands .btn.quiet { color: var(--hand-ink); }
@media (hover: hover) { .hands .btn.quiet:hover { background: var(--hand-line); color: var(--hand-ink); } }
.hand-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 4px; }
.hand-list .prow { background: var(--surface); box-shadow: var(--shadow-1); padding-inline-start: 6px; }
@media (hover: hover) { .hand-list .prow:hover { background: var(--surface); } }
.qn {
  flex: none; display: grid; place-items: center;
  width: 24px; height: 24px; border-radius: 50%;
  background: var(--hand-soft); color: var(--hand-ink); font-weight: var(--fw-x); font-size: var(--fs-xs);
}
.hand-list .prow:first-child .qn { background: var(--hand); color: var(--on-hand); }
.since { color: var(--hand-ink); font-size: var(--fs-xs); line-height: 1.4; }
.since:empty { display: none; }
.hand-list .btn.tiny:not(.mod-more) { min-width: 72px; }
.dropped-box:empty, .dropped-box > [hidden] { display: none; }
.dropped-box .notice { font-size: var(--fs-s); margin: 0 0 8px; }
.people-empty { margin: 8px 0 0; }
.mod-locked { margin: 0 0 8px; }

/* ---------- sheets: the connection details, «پایان کلاس؟» ---------- */
.sheet {
  position: fixed; inset: 0; z-index: 30;
  display: flex; align-items: flex-end; justify-content: center;
  background: var(--scrim);
  animation: kit-fade var(--t-med) var(--ease);
}
.sheet-card {
  width: 100%; max-width: 440px;
  max-height: 90dvh; overflow-y: auto;
  background: var(--surface-raised); color: var(--ink);
  border-radius: var(--r-sheet) var(--r-sheet) 0 0;
  padding: 24px 20px max(20px, env(safe-area-inset-bottom));
  box-shadow: var(--shadow-3);
  animation: kit-rise var(--t-med) var(--ease);
}
.sheet-card h2 { margin: 0 0 8px; font-size: var(--fs-md); font-weight: var(--fw-x); }
.sheet-card .hint { margin-bottom: 16px; }
.sheet-row { display: flex; gap: 8px; flex-wrap: wrap; }
.sheet-row > .btn { flex: 1 1 140px; }
@media (min-width: 600px) {
  .sheet { align-items: center; }
  .sheet-card { border-radius: var(--r-sheet); animation-name: kit-pop; }
}
.conn-state { display: flex; align-items: center; gap: 10px; margin: 0 0 2px; font-size: var(--fs-md); }
.conn-dot { flex: none; width: 12px; height: 12px; border-radius: 50%; background: var(--faint); }
.conn-sheet[data-q="ok"] .conn-dot { background: var(--icon); box-shadow: 0 0 0 4px var(--bg-sunken); }
.conn-sheet[data-q="weak"] .conn-dot { background: var(--hand-ink); box-shadow: 0 0 0 4px var(--hand-soft); }
.conn-sheet[data-q="down"] .conn-dot { background: var(--danger); box-shadow: 0 0 0 4px var(--danger-soft); }
.conn-sheet[data-q="weak"] .conn-head { color: var(--hand-ink); }
.conn-sheet[data-q="down"] .conn-head { color: var(--danger-ink); }
.conn-tip { margin: 0 0 12px; }
.conn-tech { margin: 0 0 16px; padding: 8px 12px; border-radius: var(--r-sm); background: var(--bg-sunken); color: var(--muted); font-size: var(--fs-xs); line-height: 1.7; }
.conn-tech .net { color: var(--ink-2); }

/* ---------- narrow screens (phones, an upright tablet) ---------- */
@media (max-width: 959px) {
  .room { --rbar-h: 56px; --cbar-h: 64px; --gut: 12px; }
  .rbar { gap: 8px; }
  .rbar-title { gap: 10px; }
  .rbar-mark { width: 24px; height: 24px; border-radius: 7px; }
  .rbar-names { flex-direction: column; align-items: flex-start; gap: 0; }
  .rbar h1 { font-size: var(--fs-sm); line-height: 1.45; max-width: 100%; }
  .rbar-sub { font-size: var(--fs-xs); max-width: 100%; }
  .rbar-count { display: none; }
  .room .rec-badge { min-height: 28px; padding: 2px 10px; font-size: var(--fs-xs); }
  .room-main { padding: 0; gap: 0; }
  .room-main > .stg { padding: 0; }
  .stage-notes { padding: 8px var(--gut); }
  .room[data-role="teacher"] .stage-notes { padding: 0; bottom: var(--notes-b, calc(var(--tap) + 20px)); inset-inline: var(--gut); }
  .spk { top: 10px; inset-inline-end: 10px; font-size: var(--fs-xs); }
  .cbar { display: flex; justify-content: space-around; gap: 0; padding-inline: 4px; }
  .cbar-group { display: contents; }
  .cbar-sep { display: none; }
  .cbar-room > .cb-more { margin-inline-start: 0; }
  .cb { min-width: 48px; }
  .room[data-role="teacher"] .cam-slot, .room[data-role="teacher"] .stage-slot { display: none; }
  .phone-only { display: flex; }
  .room[data-role="student"] .cbar { justify-content: space-between; padding-inline: 12px; }
  /* «خروج» lives in «بیشتر» on a phone (and the phone's back asks first): never a mis-tap in the bar's corner. */
  .room[data-role="student"] .cb-leave { display: none; }
  /* A teacher's «پایان» sits at the top bar's far end on a phone (app.js moves it). */
  .rbar > .cb-end { min-height: 44px; padding-inline: 14px 12px; }
  .cb-thumb { min-width: 0; flex: 1 1 auto; max-width: 260px; margin-inline-end: 8px; }
  /* The participants: a sheet over the stage, above the bar. */
  .room-side {
    position: fixed; z-index: 20;
    inset-inline: 0; bottom: calc(var(--cbar-h) + env(safe-area-inset-bottom));
    width: auto; height: min(72dvh, calc(100dvh - var(--cbar-h) - 40px));
    border: 0; border-radius: var(--r-sheet) var(--r-sheet) 0 0;
    box-shadow: 0 -12px 32px rgba(0, 0, 0, .22);
    animation: kit-fade var(--t-med) var(--ease);
  }
  .room-side::before {
    content: ""; position: absolute; top: 6px; left: 50%; width: 36px; height: 4px; margin-left: -18px;
    border-radius: 2px; background: var(--line-strong);
  }
  .room[data-panel="chat"] .room-side { display: none; }
  .room[data-chat-wide="0"] .side-tabs { display: none; }
  .room[data-chat-wide="0"] .side-title { display: flex; }
  .more-menu { bottom: calc(var(--cbar-h) + env(safe-area-inset-bottom) + 6px); }
}


/* A student's one button (A2 S1–S4): an icon in the bar's middle at rest, with hand up (amber, my place in the queue
   on it) and while talking (the same button ends the turn); it grows into «آماده‌ام» when the floor is offered. The
   word stays the button's name and its long-press label. */
.cb-thumb:not(.ready) { min-width: 76px; max-width: 76px; flex: none; padding: 0; justify-content: center; }
.cb-thumb:not(.ready) .cb-label { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); opacity: 0; white-space: nowrap; }
.cb-thumb .hand-pos { top: 2px; inset-inline-end: 4px; min-width: 22px; height: 22px; background: var(--hand); color: var(--on-hand); box-shadow: 0 0 0 2px var(--surface); }
.room[data-floor="offered"] .floor .lead.turn-lead { font-size: var(--fs-display); font-weight: var(--fw-x); line-height: 1.35; color: var(--speak-ink); }
@media (max-width: 959px) {
  /* The bar, right to left: chat · reactions · the hand (the middle) · bigger · more (A2 S1). */
  .room[data-role="student"] .cbar { justify-content: space-around; padding-inline: 8px; }
  .room[data-role="student"] .cbar #chat-open { order: 1; }
  .room[data-role="student"] .cbar #react-open { order: 2; }
  .room[data-role="student"] .cbar .cb-thumb { order: 3; margin: 0; }
  .room[data-role="student"] .cbar .cb-thumb.ready { flex: 1 1 auto; max-width: 240px; min-width: 150px; }
  .room[data-role="student"] .cbar .cb-big { order: 4; }
  .room[data-role="student"] .cbar .cb-more { order: 5; }
}
/* A teacher's phone bar, right to left: the people (the hands waiting as its badge) · the mic (the middle) · the chat ·
   «بیشتر» (A2 T1); «دست‌ها» is the floating chip, «پایان» the top bar's. */
@media (max-width: 959px) {
  .room[data-role="teacher"] .cbar #hands-open { display: none; }
  .room[data-role="teacher"] .cbar #people-open { order: 1; }
  .room[data-role="teacher"] .cbar #speak { order: 2; }
  .room[data-role="teacher"] .cbar #chat-open { order: 3; }
  .room[data-role="teacher"] .cbar .cb-more { order: 4; }
  .room[data-role="teacher"] .cbar #speak .cb-ic { width: 64px; }
}
@media (min-width: 960px) { .people-hands { display: none !important; } }
@media (max-width: 959px) and (orientation: portrait) {
  .room[data-role="student"] #stage-big, .room[data-role="student"] .stg-turn { display: none !important; }
}
@media (max-width: 959px) and (orientation: landscape) { .cb-big { display: none !important; } }

/* An upright phone (A2 §3): the lesson is anchored under the top bar, full width, and never moves; the dark band
   under it holds the class (who speaks, the floor's words, the last lines, the sheets at half). */
@media (max-width: 959px) and (orientation: portrait) {
  .room .stg-view { align-items: flex-start; }
  .room-main > .spk { top: calc(var(--lesson-b, 0px) + 10px); }
  /* The notes (the hands chip, the floor's words, the toasts) take the band's foot: the page stays where it is. */
  .room[data-role="teacher"] .stage-notes { position: static; padding: 8px var(--gut); pointer-events: auto; }
}

/* A phone on its side: the stage takes the screen; the bars are slim. */
@media (max-width: 959px) and (max-height: 540px) and (orientation: landscape) {
  .room { --rbar-h: 44px; --cbar-h: 56px; }
  .rbar { min-height: var(--rbar-h); padding-block: 0; }
  .rbar-names { flex-direction: row; align-items: baseline; gap: 10px; }
  .rbar h1 { font-size: var(--fs-s); }
  .cb-thumb { min-height: var(--tap); max-width: 220px; }
  .room-side { height: calc(100dvh - var(--cbar-h) - 8px); }
  .room-side::before { display: none; }
  /* The floor's words and the messages float over the stage's foot instead of taking a row. */
  .room[data-role="student"] .stage-notes { position: absolute; z-index: 6; inset-inline: 8px; bottom: 6px; padding: 0; pointer-events: none; }
  .room[data-role="student"] .stage-notes > * { pointer-events: auto; }
  .floor { padding: 4px 14px; }
  .floor .lead { font-size: var(--fs-s); }
  .room[data-floor="offered"] .floor .lead { font-size: var(--fs-sm); }
  /* A student's lesson takes the whole screen (A2 S12): the top bar floats over it and steps away after a few quiet
     seconds (a tap brings it back); the hand, the chat and the rest float as one small pill in the holding thumb's
     corner, the hand and the chat always there. Nothing moves the lesson. */
  .room[data-role="student"] .rbar { position: absolute; top: 0; inset-inline: 0; z-index: 16; box-shadow: var(--shadow-2); }
  .room[data-role="student"] .cbar {
    position: absolute; z-index: 16;
    bottom: max(8px, env(safe-area-inset-bottom)); inset-inline-start: max(8px, env(safe-area-inset-right)); inset-inline-end: auto;
    width: auto; min-height: 0; padding: 4px; gap: 2px;
    border: 0; border-radius: var(--r-pill);
    background: var(--surface); box-shadow: var(--shadow-2);
  }
  .room[data-role="student"] .cbar .cb-thumb { flex: none; min-width: 64px; max-width: 200px; margin: 0; }
  .room[data-chrome="off"] .rbar, .room[data-chrome="off"] .stg-bar,
  .room[data-role="student"][data-chrome="off"] .cbar :is(.react-slot, .cb-more) { display: none; }
  .room[data-chrome="off"] .spk { top: 8px; }
  .room[data-role="student"] .stage-notes { bottom: calc(max(8px, env(safe-area-inset-bottom)) + 64px); }
  /* A teacher's class rail on the inline start (A2 T8: the mic, the people, the chat, «بیشتر»); the lesson beside it. */
  .room[data-role="teacher"] .cbar {
    position: absolute; z-index: 12;
    top: var(--rbar-h); bottom: 0; inset-inline-start: 0; inset-inline-end: auto;
    width: calc(64px + env(safe-area-inset-right)); min-height: 0;
    flex-direction: column; justify-content: center; gap: 4px;
    padding: 4px 0; padding-inline-start: env(safe-area-inset-right);
    border-top: 0; border-inline-end: 1px solid var(--line);
  }
  .room[data-role="teacher"] .room-body { margin-inline-start: calc(64px + env(safe-area-inset-right)); }
  .room[data-role="teacher"] .cbar #speak .cb-ic { width: 44px; } /* the rail is 64 px wide */
  /* The stage's «بزرگ‌تر» and the banners keep clear of the pill and the floating top bar. */
  .room[data-role="student"] .stg-bar { inset-inline-start: auto; inset-inline-end: 6px; }
  .room[data-role="student"] > :is(.conn-banner, .rejoin, .pj-unlock, .pj-note, .catchup) {
    position: absolute; z-index: 15; top: calc(var(--rbar-h) + 6px); inset-inline: var(--gut); margin: 0;
  }
  /* A sheet is a side sheet at the inline end; the lesson keeps the rest (sheet.js data-side). */
  .room[data-sheet]:not([data-sheet=""]) .room-body { margin-inline-end: min(38vw, 340px); }
}

/* Reduced motion keeps feedback (short fades through the tokens, motion.css); only the loops stop here. */
@media (prefers-reduced-motion: reduce) {
  #conn[data-q="wait"]::before { animation: none; }
  .lvl i, .switch::after { transition: none; }
}
:root[data-motion="reduce"] #conn[data-q="wait"]::before { animation: none; }
.prow[data-hand]:not([data-hand="0"]) .avatar { background: var(--hand-soft); color: var(--hand-ink); }
.hand-list .prow .avatar { display: none; }
@media (max-width: 959px) { .more-keys { display: none !important; } }
