/* The tutor's page, plain HTML and CSS. Colours come from tokens.css (made from app.py by tokens.py). */

*, *::before, *::after { box-sizing: border-box; }
[hidden] { display: none !important; }
html { background: var(--ws-page); color-scheme: light; }
html.dark { color-scheme: dark; }
body {
  margin: 0; min-height: 100dvh; background: var(--ws-page); color: var(--ws-text);
  font: 500 15px/1.6 var(--ws-display); -webkit-font-smoothing: antialiased;
}
button, input, textarea { font: inherit; color: inherit; }
button { cursor: pointer; }
svg { width: 18px; height: 18px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round;
  stroke-linejoin: round; flex: none; }
svg .fill { fill: currentColor; stroke: none; }
:focus-visible { outline: 2px solid var(--ws-focus); outline-offset: 2px; }
.sr-only { position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
.skip { position: absolute; left: 12px; top: -48px; z-index: 50; padding: 8px 12px; border-radius: 10px;
  background: var(--ws-accent-btn); color: var(--ws-on-accent); font-weight: 700; text-decoration: none; }
.skip:focus { top: 12px; }

/* ---- Buttons and links */
.btn { display: inline-flex; align-items: center; justify-content: center; gap: 8px; min-height: 40px; padding: 0 16px;
  border: 1px solid transparent; border-radius: 12px; font-weight: 700; font-size: 14px; }
.btn-primary { background: var(--ws-accent-btn); color: var(--ws-on-accent); }
.btn-primary:hover { background: var(--ws-accent-btn-hover); }
.btn-quiet { border-color: var(--ws-border-strong); background: var(--ws-surface); }
.btn-quiet:hover { background: var(--ws-surface-2); }
.btn-danger { background: var(--ws-danger); color: var(--ws-on-danger); }
.btn-danger:hover { background: var(--ws-danger-hover); }
.btn.wide { width: 100%; height: 46px; margin-top: 18px; font-size: 15px; }
.link { padding: 2px; border: 0; background: none; color: var(--ws-link); font-weight: 700; font-size: 13px; }
.link:hover { color: var(--ws-link-hover); text-decoration: underline; text-underline-offset: 2px; }
.link.quiet { color: var(--ws-muted); }
.icon-btn { display: inline-flex; align-items: center; justify-content: center; width: 36px; height: 36px; padding: 0;
  border: 0; border-radius: 10px; background: none; color: var(--ws-muted); }
.icon-btn:hover { background: var(--ws-surface-2); color: var(--ws-text); }
.icon-btn.small { width: 26px; height: 26px; }
.icon-btn.small svg { width: 14px; height: 14px; }

/* ---- The frame: the chats column (a drawer on a phone) beside the page */
.app { display: flex; min-height: 100dvh; }
.side {
  position: fixed; inset: 0 auto 0 0; z-index: 30; display: flex; flex-direction: column; gap: 10px;
  width: min(300px, 86vw); padding: 14px 12px; border-right: 1px solid var(--ws-border); background: var(--ws-surface);
  transform: translateX(-100%); transition: transform 0.2s ease; visibility: hidden;
}
html.side-open .side { transform: none; visibility: visible; }
.scrim { position: fixed; inset: 0; z-index: 25; background: rgba(1, 20, 37, 0.45); }
.side-head { display: flex; align-items: center; justify-content: space-between; padding: 0 2px 0 6px; }
.side-head h2 { margin: 0; font-size: 12px; font-weight: 800; letter-spacing: 0.06em; text-transform: uppercase; color: var(--ws-muted); }
.new-chat { width: 100%; }
.chat-list { flex: 1; margin: 0; padding: 0; overflow-y: auto; list-style: none; }
.chat-list li { position: relative; }
.chat-list .chat-item {
  display: block; width: 100%; padding: 9px 36px 9px 10px; border: 0; border-radius: 10px; background: none;
  font-size: 14px; font-weight: 600; text-align: left; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chat-list .chat-item:hover { background: var(--ws-surface-2); }
.chat-list .chat-item[aria-current="true"] { background: var(--ws-accent-soft); font-weight: 800; }
.chat-list .rename { position: absolute; top: 50%; right: 4px; transform: translateY(-50%); opacity: 0; }
.chat-list li:hover .rename, .chat-list .rename:focus-visible, .chat-list [aria-current="true"] + .rename { opacity: 1; }
.chat-list.can-share .chat-item { padding-right: 68px; }
.chat-list .share { position: absolute; top: 50%; right: 36px; transform: translateY(-50%); opacity: 0; }
.chat-list li:hover .share, .chat-list .share:focus-visible, .chat-list [aria-current="true"] ~ .share,
.chat-list .share.on { opacity: 1; }
.chat-list .share.on { color: var(--ws-accent); }
.chat-list .share.on::after { content: ""; position: absolute; top: 2px; right: 2px; width: 7px; height: 7px;
  border-radius: 50%; background: var(--ws-accent); box-shadow: 0 0 0 2px var(--ws-surface); }  /* shared */
.chat-list .share.stale::after { background: var(--ws-amber); }  /* shared, missing newer messages */
@media (hover: none) {  /* a phone: both buttons show on every chat, and they're big enough to tap apart */
  .chat-list.can-share .share, .chat-list.can-share .rename { opacity: 1; width: 34px; height: 34px; }
  .chat-list.can-share .rename { right: 2px; }
  .chat-list.can-share .share { right: 40px; }
  .chat-list.can-share .chat-item { padding-right: 80px; }
}
.chat-list input { width: 100%; padding: 8px 10px; border: 1px solid var(--ws-input-border); border-radius: 10px;
  background: var(--ws-surface); font-size: 14px; font-weight: 600; }
.chat-list .none { padding: 8px 10px; color: var(--ws-muted); font-size: 13.5px; }

@media (min-width: 900px) {
  .side { position: sticky; top: 0; height: 100dvh; flex: none; width: 272px; transform: none; visibility: visible;
    transition: margin-left 0.2s ease; }
  html:not(.side-open) .side { margin-left: -272px; visibility: hidden; }
  .scrim { display: none; }
}

.main { flex: 1; min-width: 0; display: flex; flex-direction: column; height: 100dvh; }

/* ---- The header: the chats button, the wordmark, the account chip and its menu */
.top { display: flex; align-items: center; gap: 8px; height: 58px; padding: 0 16px; flex: none; }
.brand { display: flex; align-items: center; gap: 8px; margin: 0; font-size: 13px; font-weight: 800; letter-spacing: 0.04em;
  white-space: nowrap; }
.brand-mark { width: 9px; height: 9px; border-radius: 50%; background: var(--ws-amber); box-shadow: 0 0 0 3px var(--ws-accent-soft); }
.brand-course { color: var(--ws-muted); font-weight: 700; letter-spacing: 0.02em; }
.brand-course::before { content: "·"; margin: 0 7px 0 1px; }
.acct { position: relative; margin-left: auto; }
.chip { display: inline-flex; align-items: center; gap: 8px; max-width: 220px; padding: 3px 10px 3px 3px;
  border: 1px solid transparent; border-radius: 999px; background: none; font-weight: 700; font-size: 13.5px; }
.chip:hover, .chip[aria-expanded="true"] { border-color: var(--ws-border); background: var(--ws-surface-2); }
.chip::after { content: ""; width: 6px; height: 6px; margin: -4px 2px 0 1px; border-right: 2px solid var(--ws-muted);
  border-bottom: 2px solid var(--ws-muted); transform: rotate(45deg); transition: transform 0.15s, margin 0.15s; }
.chip[aria-expanded="true"]::after { margin-top: 3px; transform: rotate(-135deg); }
.avatar { display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; flex: none;
  border-radius: 50%; background: var(--ws-accent-btn); color: var(--ws-on-accent); font-size: 12.5px; font-weight: 800; }
.chip-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* What's new, unread (app.js markNotes): an amber dot on the chip's avatar, and "New" beside it in the menu */
.avatar { position: relative; }
.chip.has-news .avatar::after { content: ""; position: absolute; top: -2px; right: -2px; width: 10px; height: 10px;
  border-radius: 50%; background: var(--ws-amber); box-shadow: 0 0 0 2px var(--ws-page); }
.menu-new { margin-left: auto; padding: 1px 8px; border-radius: 999px; background: var(--ws-amber); color: #2b1a00;
  font-size: 11.5px; font-weight: 800; }
.menu {
  position: absolute; top: calc(100% + 6px); right: 0; z-index: 40; display: flex; flex-direction: column; width: 236px;
  padding: 6px; border: 1px solid var(--ws-border-strong); border-radius: 14px; background: var(--ws-surface);
  box-shadow: 0 12px 32px rgba(1, 20, 37, 0.18), 0 2px 6px rgba(1, 20, 37, 0.08);
}
.menu-who { margin: 0; padding: 8px 10px 10px; overflow: hidden; color: var(--ws-muted); font-size: 12.5px;
  text-overflow: ellipsis; white-space: nowrap; }
.menu-who strong { color: var(--ws-text); }
.menu hr { width: calc(100% - 8px); margin: 6px 4px; border: 0; border-top: 1px solid var(--ws-border); }
.menu [role="menuitem"] { display: flex; align-items: center; gap: 10px; min-height: 40px; padding: 0 10px; border: 0;
  border-radius: 9px; background: none; font-size: 14px; font-weight: 600; text-align: left; }
.menu [role="menuitem"] svg { color: var(--ws-muted); }
.menu [role="menuitem"]:hover, .menu [role="menuitem"]:focus-visible { outline: none; background: var(--ws-surface-2); }
.menu [role="menuitem"]:focus-visible { box-shadow: inset 0 0 0 2px var(--ws-focus); }
.menu .danger, .menu .danger svg { color: var(--ws-danger); }
/* The class switch (a site with several classes): the class's name opens a menu of the classes, each a link */
.class-box { position: relative; min-width: 0; }
.class-open { display: inline-flex; align-items: center; gap: 7px; min-height: 32px; max-width: 160px; padding: 0 10px;
  border: 1px solid transparent; border-radius: 999px; background: none; color: var(--ws-muted); font-size: 13px;
  font-weight: 700; letter-spacing: 0.02em; white-space: nowrap; }
.class-open::after { content: ""; width: 5px; height: 5px; margin: -3px 1px 0 0; flex: none;
  border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg);
  transition: transform 0.15s, margin 0.15s; }
.class-open:hover, .class-open[aria-expanded="true"] { border-color: var(--ws-border); background: var(--ws-surface-2);
  color: var(--ws-text); }
.class-open[aria-expanded="true"]::after { margin-top: 3px; transform: rotate(-135deg); }
.class-open:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--ws-focus); }
.class-menu { left: 0; right: auto; width: 220px; }
.menu a[role="menuitem"] { color: inherit; text-decoration: none; }
.menu a[aria-current="page"] { font-weight: 800; }
.menu a[aria-current="page"] svg { margin-left: auto; color: var(--ws-accent); }

/* ---- The class-code and username screens */
.loading { margin: 18vh auto 0; color: var(--ws-muted); }
.gate { width: min(460px, calc(100% - 32px)); margin: 8vh auto 0; }
.gate h1 { margin: 0 0 18px; font-size: clamp(26px, 5vw, 34px); font-weight: 800; letter-spacing: -0.02em; line-height: 1.15; }
.card { padding: 20px; border: 1px solid var(--ws-border); border-radius: 18px; background: var(--ws-surface); }
.form label { display: block; font-weight: 800; }
.hint { margin: 4px 0 12px; color: var(--ws-muted); font-size: 13.5px; line-height: 1.5; }
.field-row { display: flex; gap: 8px; }
.field-row input { flex: 1; min-width: 0; height: 44px; padding: 0 14px; border: 1px solid var(--ws-input-border);
  border-radius: 12px; background: var(--ws-surface); }
.field-row input:hover { border-color: var(--ws-input-border-hover); }
.field-row input:focus-visible { outline: none; border-color: var(--ws-focus); box-shadow: 0 0 0 3px var(--ws-focus-ring); }
.class-picks { margin-bottom: 12px; }
.class-picks-label { margin: 0 0 12px; font-weight: 800; }
.class-list { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.class-list .btn { height: 56px; font-size: 17px; }
.gate.picking .form label { font-size: 14px; }
.form-msg { min-height: 0; margin: 10px 0 0; color: var(--ws-danger); font-size: 13.5px; font-weight: 700; }
.form-msg:empty { display: none; }

/* ---- The chat: the conversation scrolls; the message box stays at the bottom */
.chat { flex: 1; min-height: 0; display: flex; flex-direction: column; }
.log { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 8px 16px 24px; scroll-behavior: smooth; }
.empty, .messages, .dock { width: 100%; max-width: 820px; margin: 0 auto; }
.empty { display: flex; flex-direction: column; align-items: center; justify-content: center; min-height: 100%;
  padding: 24px 0 8px; text-align: center; }
.empty h1 { margin: 0; font-size: 24px; font-weight: 800; letter-spacing: -0.01em; }
.empty > p { margin: 4px 0 20px; color: var(--ws-muted); font-size: 14px; }
/* "Continue: <title>": the chat used last in this class, one tap back (app.js showContinue) */
.continue { display: inline-flex; align-items: center; gap: 8px; max-width: min(640px, 100%); min-height: 40px;
  margin: -6px 0 16px; padding: 6px 16px 6px 12px; border: 1px solid var(--ws-border-strong); border-radius: 999px;
  background: var(--ws-surface); font-size: 14px; font-weight: 700; }
.continue:hover { background: var(--ws-surface-2); }
.continue svg { width: 17px; height: 17px; flex: none; color: var(--ws-accent); }
.continue-word { flex: none; color: var(--ws-muted); }
.continue-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Explain's topics, in place of the starters (app.js showTopics): the course's topics, a tap each */
.topics { display: flex; flex-direction: column; align-items: center; gap: 12px; width: 100%; max-width: 640px; }
.topics-label { margin: 0; font-size: 15px; font-weight: 800; }
.topic-list { display: flex; flex-wrap: wrap; justify-content: center; gap: 8px; }
.topic { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; max-width: 100%; padding: 7px 14px;
  border: 1px solid var(--ws-border); border-radius: 999px; background: var(--ws-surface); font-size: 14px;
  font-weight: 700; text-align: left; line-height: 1.3; }
.topic:hover { border-color: var(--ws-border-strong); background: var(--ws-surface-2); }
.topic-week { flex: none; color: var(--ws-muted); font-size: 12px; font-weight: 800; letter-spacing: 0.02em; }
.topics-foot { margin: -6px 0 2px; color: var(--ws-muted); font-size: 13.5px; }
.topics-foot .link { margin-left: 6px; font-size: 13.5px; }
.starters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; width: 100%; max-width: 640px; }
.starter { display: flex; align-items: center; gap: 12px; min-height: 58px; padding: 10px 14px; border: 1px solid var(--ws-border);
  border-radius: 14px; background: var(--ws-surface); font-size: 14px; font-weight: 700; text-align: left; line-height: 1.35; }
.starter:hover { border-color: var(--ws-border-strong); background: var(--ws-surface-2); }
.starter .ico { display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; flex: none;
  border-radius: 50%; background: var(--ws-accent-soft); color: var(--ws-accent); }
.starter .ico svg { width: 16px; height: 16px; }
.messages { display: flex; flex-direction: column; gap: 10px; margin: 0 auto; padding: 8px 0 0; list-style: none; }
.messages:empty { display: none; }

.msg { display: flex; flex-direction: column; gap: 2px; }
.msg.user { align-items: flex-end; }
.bubble { max-width: 100%; padding: 12px 16px; border-radius: var(--ws-radius, 18px); overflow-wrap: anywhere; }
.user .bubble { max-width: min(80%, 640px); background: var(--ws-user); border-bottom-right-radius: var(--ws-tail, 6px); }
.user .bubble .code { max-height: 260px; overflow-y: auto; background: var(--ws-surface); }  /* a pasted script */
.bot.arrived .bubble { animation: arrive 0.35s ease; }
@keyframes arrive { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.bot .bubble { border: 1px solid var(--ws-bubble-edge, var(--ws-border-strong)); background: var(--ws-bot);
  border-bottom-left-radius: var(--ws-tail, 6px); }
.user .bubble img { display: block; max-width: 220px; max-height: 180px; margin-bottom: 8px; border-radius: 10px; }
.msg-tools { display: flex; gap: 2px; opacity: 0; transition: opacity 0.15s; }
.msg:hover .msg-tools, .msg:focus-within .msg-tools { opacity: 1; }
@media (hover: none) { .msg-tools { opacity: 1; } }
.msg-tools .icon-btn { width: 30px; height: 30px; }
.msg-tools .icon-btn svg { width: 15px; height: 15px; }
.note { align-self: center; margin: 0; padding: 6px 12px; border-radius: 10px; background: var(--ws-note-bg);
  color: var(--ws-muted); font-size: 13px; }

/* Editing a sent message, in place */
.edit-box { width: min(80%, 640px); }
.edit-box textarea { width: 100%; min-height: 80px; padding: 12px 14px; border: 1px solid var(--ws-focus); border-radius: 14px;
  background: var(--ws-surface); resize: vertical; box-shadow: 0 0 0 3px var(--ws-focus-ring); }
.edit-box .actions { margin-top: 8px; }

/* The reply's text: paragraphs, lists, code */
.prose > :first-child { margin-top: 0; }
.prose > :last-child { margin-bottom: 0; }
.prose p, .prose ul, .prose ol { margin: 0 0 10px; }
.prose ul, .prose ol { padding-left: 22px; }
.prose ul { list-style: disc; }  /* the chat is itself a list, so without these a reply's list starts at circles */
.prose ul ul { list-style: circle; }
.prose ul ul ul { list-style: square; }
.prose li { margin: 2px 0; }
.prose h3, .prose h4 { margin: 14px 0 6px; font-size: 15.5px; font-weight: 800; }
.prose code { padding: 1px 5px; border-radius: 6px; background: var(--ws-code-bg); font: 13px/1.5 ui-monospace, "SF Mono", Menlo, Consolas, monospace; }
.prose .code { margin: 0 0 10px; border: 1px solid var(--ws-border); border-radius: 12px; overflow: hidden; background: var(--ws-code-bg); }
.prose .code-head { display: flex; align-items: center; justify-content: space-between; padding: 4px 6px 4px 12px;
  border-bottom: 1px solid var(--ws-border); color: var(--ws-muted); font-size: 12px; font-weight: 700; }
.prose pre { margin: 0; padding: 12px 14px; overflow-x: auto; }
.prose pre code { padding: 0; background: none; font-size: 13px; }
.prose li > ul, .prose li > ol { margin: 2px 0 0; }
.prose li > p, .prose li > .code { margin: 6px 0; }
.prose a { color: var(--ws-link); font-weight: 600; text-decoration: underline; text-underline-offset: 2px; overflow-wrap: anywhere; }
.prose a:hover { color: var(--ws-link-hover); }
.prose blockquote { margin: 0 0 10px; padding: 2px 0 2px 12px; border-left: 3px solid var(--ws-border-strong); color: var(--ws-muted); }
.prose hr { margin: 14px 0; border: 0; border-top: 1px solid var(--ws-border); }
/* A table scrolls sideways inside the bubble on a phone, instead of widening the page */
.prose .table { margin: 0 0 10px; max-width: 100%; overflow-x: auto; border: 1px solid var(--ws-border); border-radius: 12px; }
.prose table { width: 100%; border-collapse: collapse; font-size: 14px; }
.prose th, .prose td { padding: 6px 12px; border-bottom: 1px solid var(--ws-border); text-align: left; vertical-align: top; }
.prose th { background: var(--ws-code-bg); font-weight: 800; white-space: nowrap; }
.prose tbody tr:last-child td { border-bottom: 0; }
.prose th.r, .prose td.r { text-align: right; }
.prose th.c, .prose td.c { text-align: center; }

/* Waiting for a reply: three dots, then a line under them now and then */
.typing .bubble { display: flex; flex-direction: column; gap: 6px; }
.dots { display: inline-flex; gap: 5px; padding: 6px 0; }
.dots span { width: 7px; height: 7px; border-radius: 50%; background: var(--ws-dot); animation: bounce 1.2s infinite ease-in-out; }
.dots span:nth-child(2) { animation-delay: 0.15s; }
.dots span:nth-child(3) { animation-delay: 0.3s; }
@keyframes bounce { 0%, 60%, 100% { transform: translateY(0); opacity: 0.55; } 30% { transform: translateY(-5px); opacity: 1; } }
.quip { color: var(--ws-muted); font-size: 13px; animation: fade 0.4s ease; }
@keyframes fade { from { opacity: 0; transform: translateY(2px); } to { opacity: 1; transform: none; } }

/* ---- The message box, then the database line under it */
.dock { flex: none; padding: 0 16px 6px; }
.composer { position: relative; display: flex; flex-direction: column; gap: 8px; padding: 8px; border: 1px solid var(--ws-border-strong);
  border-radius: 22px; background: var(--ws-surface-2); }
/* Files dragged over the page (app.js): the box says where they go */
.drop-hint { position: absolute; inset: -1px; z-index: 1; display: none; align-items: center; justify-content: center;
  padding: 0 16px; border: 2px dashed var(--ws-accent); border-radius: inherit; background: var(--ws-accent-soft);
  color: var(--ws-text); font-weight: 700; text-align: center; pointer-events: none; }
.composer.dropping .drop-hint { display: flex; }
.composer:focus-within { border-color: var(--ws-input-border); background: var(--ws-surface); }
.composer.ready { border-color: var(--ws-accent); box-shadow: 0 0 0 3px var(--ws-accent-soft); }  /* Fix: paste here */
.composer-row { display: flex; align-items: flex-end; gap: 6px; }
.composer textarea { flex: 1; min-width: 0; max-height: 40vh; padding: 9px 4px; border: 0; background: none; resize: none;
  line-height: 1.5; outline: none; }
.composer textarea::placeholder { color: var(--ws-placeholder); }
.attach { cursor: pointer; }
.send { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; flex: none; padding: 0;
  border: 0; border-radius: 50%; background: var(--ws-accent-btn); color: var(--ws-on-accent); }
.send:hover { background: var(--ws-accent-btn-hover); }
.send.stop { background: var(--ws-accent-soft); color: var(--ws-accent); }
.attached { display: flex; align-items: center; gap: 10px; padding: 6px 8px; border: 1px solid var(--ws-border);
  border-radius: 14px; background: var(--ws-surface); font-size: 13px; color: var(--ws-muted); }
.attached img { width: 44px; height: 44px; object-fit: cover; border-radius: 8px; }
.attached-text { flex: 1; min-width: 0; margin: 0; }
.attached-text span { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.attached-text .attached-more { white-space: normal; }
.db-line { display: flex; flex-wrap: wrap; align-items: center; gap: 0 8px; padding: 6px 6px 0; color: var(--ws-muted); font-size: 13px; }
.db-line strong { color: var(--ws-text); }
.db-line .link::before { content: "·"; margin-right: 8px; color: var(--ws-muted); }
.usage { margin: 4px 6px 0; color: var(--ws-link); font-size: 13px; font-weight: 700; }
/* Behind the scenes: a professor's browser only (app.behind_scenes), under each reply and on the line under the chat */
.behind-on { margin: 4px 6px 0; color: var(--ws-muted); font-size: 13px; }
a.link { text-decoration: none; }  /* Back to the class report: as the link buttons (Turn off) */
.report-back { margin: 14px 0 0; text-align: center; }
.behind { max-width: 100%; margin-top: 4px; padding: 8px 12px; border: 1px dashed var(--ws-border-strong);
  border-radius: 12px; background: var(--ws-note-bg); color: var(--ws-text); font-size: 13px; }
.behind summary { cursor: pointer; color: var(--ws-link); font-weight: 700; }
.behind summary:focus-visible { outline: 2px solid var(--ws-focus); outline-offset: 2px; border-radius: 4px; }
.behind dl { display: grid; grid-template-columns: max-content 1fr; gap: 2px 12px; margin: 8px 0 0; }
.behind dt { color: var(--ws-muted); font-weight: 700; }
.behind dd { margin: 0; overflow-wrap: anywhere; }
.behind-draft { margin-top: 10px; }
.behind-draft p { margin: 0 0 4px; font-weight: 700; }
.behind-draft pre { max-height: 320px; margin: 0; padding: 8px 10px; overflow: auto; border-radius: 8px;
  background: var(--ws-code-bg); font-size: 12.5px; white-space: pre-wrap; overflow-wrap: anywhere; }
.behind-line { margin: 10px 0 0; color: var(--ws-muted); font-size: 12px; overflow-wrap: anywhere;
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; }
@media (max-width: 560px) { .behind dl { grid-template-columns: 1fr; } .behind dd { margin-bottom: 4px; } }
.foot { flex: none; padding: 2px 16px 8px; text-align: center; }

/* ---- Cards over the page (native <dialog>: focus stays inside, Escape closes) */
.card-dialog { width: min(480px, calc(100vw - 32px)); max-height: calc(100dvh - 32px); padding: 24px 24px 20px;
  border: 1px solid var(--ws-border); border-radius: 20px; background: var(--ws-surface); color: var(--ws-text); }
.card-dialog.wide-dialog { width: min(620px, calc(100vw - 32px)); }
.card-dialog::backdrop { background: rgba(1, 20, 37, 0.55); }
.card-dialog h2 { margin: 0 0 10px; font-size: 22px; font-weight: 800; letter-spacing: -0.01em; }
.card-dialog p { margin: 0 0 10px; line-height: 1.6; }
.card-dialog .muted { color: var(--ws-muted); font-size: 14px; }
.badge { margin: 0 0 8px !important; color: var(--ws-muted); font-size: 12px; font-weight: 800; letter-spacing: 0.06em;
  text-transform: uppercase; }
.label { margin: 14px 0 8px !important; font-size: 14px; font-weight: 800; }
.pills { display: flex; flex-wrap: wrap; gap: 8px; }
.pills button { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; padding: 0 14px;
  border: 1px solid var(--ws-border-strong); border-radius: 999px; background: var(--ws-surface-2); font-size: 14px; font-weight: 600; }
.pills button[aria-pressed="true"] { border-color: var(--ws-accent); background: var(--ws-accent-soft); box-shadow: inset 0 0 0 1px var(--ws-accent); }
.swatches { display: flex; flex-wrap: wrap; gap: 8px; }
.swatches button { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px;
  padding: 0; border: 1px solid var(--ws-border-strong); border-radius: 50%; background: var(--ws-surface-2); }
.swatches button[aria-pressed="true"] { border-color: var(--ws-accent); box-shadow: inset 0 0 0 2px var(--ws-accent); }
#notes .credit { display: table; margin-top: 4px; padding: 2px 10px; border-radius: 10px; background: var(--ws-surface-2);
  font-size: 12.5px; font-weight: 700; color: var(--ws-accent); }
.actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 16px; }
.card-dialog textarea { width: 100%; padding: 12px 14px; border: 1px solid var(--ws-input-border); border-radius: 14px;
  background: var(--ws-surface); resize: vertical; }
.card-dialog textarea:focus-visible { outline: none; border-color: var(--ws-focus); box-shadow: 0 0 0 3px var(--ws-focus-ring); }
#feedback .form-msg { color: var(--ws-text); }
#notes h3 { margin: 14px 0 2px; font-size: 18px; font-weight: 800; }
#notes .date { color: var(--ws-muted); font-size: 13px; }
#notes ul { margin: 6px 0 0; padding-left: 20px; }
#notes li { margin-bottom: 8px; }
#notes details { margin-top: 12px; }
#notes summary { cursor: pointer; color: var(--ws-link); font-size: 13.5px; font-weight: 800; }

/* ---- Reading (the Themes card): text size and spacing, with any theme */
/* Text size: the chat's words (messages, the box, the starters) */
html[data-size="small"] .bubble, html[data-size="small"] .composer textarea, html[data-size="small"] .starter { font-size: 13.5px; }
html[data-size="large"] .bubble, html[data-size="large"] .composer textarea, html[data-size="large"] .starter { font-size: 17px; }
html[data-size="large"] .prose code, html[data-size="large"] .prose pre code { font-size: 14.5px; }
/* Spacing */
html[data-density="compact"] .messages { gap: 4px; }
html[data-density="compact"] .bubble { padding: 8px 12px; line-height: 1.5; }
html[data-density="compact"] .msg-tools .icon-btn { width: 26px; height: 26px; }
html[data-density="compact"] .prose p, html[data-density="compact"] .prose ul, html[data-density="compact"] .prose ol { margin-bottom: 6px; }
/* ---- Themes (studio.js; boot.js puts the theme on <html>). A card or the preview carries its own theme's colours as
   custom properties, so everything inside it is drawn the way that theme draws the page. --pick is the page's own
   accent (worked out where it's set, so a card's own accent doesn't change it): the ring around the theme in use. */
.card-dialog.studio { width: min(900px, calc(100vw - 32px)); padding: 0; --pick: var(--ws-accent); }
.studio-head { padding: 22px 24px 0; border-bottom: 1px solid var(--ws-border); background: var(--ws-surface); }
.studio-head h2 { margin-bottom: 2px; }
.studio-head .muted { margin-bottom: 10px; }
.tabs { display: flex; gap: 4px; margin: 0 -6px; overflow-x: auto; }
.tabs [role="tab"] { flex: none; min-height: 42px; padding: 0 10px; border: 0; border-bottom: 3px solid transparent;
  background: none; color: var(--ws-muted); font-size: 14.5px; font-weight: 800; }
.tabs [role="tab"]:hover { color: var(--ws-text); }
.tabs [role="tab"][aria-selected="true"] { border-bottom-color: var(--ws-accent); color: var(--ws-text); }
.pane { padding: 2px 24px 18px; }
.pane > .muted:first-child { margin-top: 16px; }
.studio-foot { position: sticky; bottom: 0; z-index: 2; justify-content: space-between; margin: 0; padding: 12px 24px;
  border-top: 1px solid var(--ws-border); background: var(--ws-surface); }
.group { margin: 20px 0 10px; color: var(--ws-muted); font-size: 12.5px; font-weight: 800; letter-spacing: 0.06em;
  text-transform: uppercase; }
.group + .pills { margin-bottom: 12px; }
.studio-msg { margin: 10px 0 0 !important; font-size: 13.5px; font-weight: 700; overflow-wrap: anywhere; }
.studio-msg:empty { display: none; }
.studio-note { margin: 8px 0 0 !important; color: var(--ws-muted); font-size: 13px; line-height: 1.5 !important; }
.studio .hint { margin: 0 0 10px; }

/* A theme's card: its little chat (two of the tutor's messages, one of yours, the accent's dot), then its name */
.looks { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 12px; }
.look { display: flex; flex-direction: column; min-width: 0; padding: 0; overflow: hidden; border: 1px solid var(--ws-border-strong);
  border-radius: 14px; background: var(--ws-surface); color: var(--ws-text); font-family: var(--ws-display); text-align: left;
  transition: transform 0.15s, box-shadow 0.15s; }
.look:hover { transform: translateY(-2px); box-shadow: 0 8px 20px rgba(1, 20, 37, 0.16); }
.look[aria-pressed="true"] { outline: 3px solid var(--pick); outline-offset: 2px; }
.look-chat { position: relative; display: flex; flex-direction: column; gap: 6px; height: 88px; padding: 12px;
  background-color: var(--ws-page); }
.look-b { display: block; height: 14px; border-radius: calc(var(--ws-radius, 18px) / 2.5); }
.look-b.bot { width: 72%; background: var(--ws-bot); box-shadow: inset 0 0 0 1px var(--ws-bubble-edge, var(--ws-border)); }
.look-b.user { width: 56%; align-self: flex-end; background: var(--ws-user); }
.look-b.short { width: 44%; }
.look-dot { position: absolute; right: 10px; bottom: 9px; width: 16px; height: 16px; border-radius: 50%; background: var(--ws-accent-btn); }
.look-name { display: flex; align-items: center; gap: 6px; min-width: 0; padding: 8px 10px; border-top: 1px solid var(--ws-border);
  font-size: 14px; font-weight: 700; }
.look-name > span:last-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.look-by { margin-top: -6px; padding: 0 10px 8px; overflow: hidden; color: var(--ws-muted); font-size: 12px; text-overflow: ellipsis;
  white-space: nowrap; }
.offer-look { margin: 10px 0 4px; }
.offer-look .look { width: 100%; pointer-events: none; }
.offer-look .look-chat { height: 132px; }

/* Make your own: the preview (a small copy of the page), then every part of the theme */
.make { display: grid; grid-template-columns: minmax(0, 1fr); gap: 4px 22px; padding-top: 16px; }
.make-preview { position: sticky; top: 0; z-index: 1; }
.mini { overflow: hidden; border: 1px solid var(--ws-border-strong); border-radius: 16px; background: var(--ws-page);
  color: var(--ws-text); font: 500 14px/1.55 var(--ws-display); pointer-events: none; box-shadow: 0 8px 18px rgba(1, 20, 37, 0.12); }
.mini-top { display: flex; align-items: center; gap: 8px; height: 38px; padding: 0 12px; font-size: 12.5px; font-weight: 800; }
.mini-log { display: flex; flex-direction: column; gap: 8px; padding: 6px 12px 12px; }
.mini-msg { display: flex; flex-direction: column; }
.mini-msg.user { align-items: flex-end; }
.mini .bubble { padding: 9px 13px; font-size: 13.5px; }
.mini .user .bubble { max-width: 88%; }
.mini .prose p { margin-bottom: 6px; }
.mini .prose code { font-size: 12px; }
.mini-dock { display: flex; align-items: center; gap: 8px; margin: 0 10px 10px; padding: 5px 5px 5px 14px; border-radius: 18px;
  background: var(--ws-surface-2); }
.mini-input { flex: 1; color: var(--ws-placeholder); font-size: 13px; }
.mini-send { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px; border-radius: 50%;
  background: var(--ws-accent-btn); color: var(--ws-on-accent); }
.mini-send svg { width: 15px; height: 15px; }
.make-controls > .label:first-child { margin-top: 4px !important; }
.make-controls .wide { margin-top: 20px; }
.text-input { width: 100%; height: 44px; padding: 0 14px; border: 1px solid var(--ws-input-border); border-radius: 12px;
  background: var(--ws-surface); }
.text-input:hover { border-color: var(--ws-input-border-hover); }
.text-input:focus-visible { outline: none; border-color: var(--ws-focus); box-shadow: 0 0 0 3px var(--ws-focus-ring); }
.colours { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: 8px; }
.colour { display: flex; align-items: center; gap: 10px; min-height: 46px; padding: 4px 10px 4px 4px; border: 1px solid var(--ws-border-strong);
  border-radius: 12px; background: var(--ws-surface-2); font-size: 13.5px; font-weight: 600; cursor: pointer; }
.colour:focus-within { border-color: var(--ws-focus); box-shadow: 0 0 0 3px var(--ws-focus-ring); }
.colour input { width: 38px; height: 38px; flex: none; padding: 0; border: 0; border-radius: 9px; background: none; cursor: pointer; }
.colour input:focus-visible { outline: none; }
.colour input::-webkit-color-swatch-wrapper { padding: 0; }
.colour input::-webkit-color-swatch { border: 1px solid rgba(0, 0, 0, 0.25); border-radius: 9px; }
.colour input::-moz-color-swatch { border: 1px solid rgba(0, 0, 0, 0.25); border-radius: 9px; }
.swatches.icons button { font-size: 20px; line-height: 1; }
.no-icon { width: 18px; height: 18px; border: 2px solid var(--ws-muted); border-radius: 50%;
  background: linear-gradient(45deg, transparent 44%, var(--ws-muted) 44% 56%, transparent 56%); }
#make-send { margin-top: 6px; }
@media (min-width: 760px) {
  .make { grid-template-columns: minmax(0, 5fr) minmax(0, 6fr); align-items: start; }
  .make-preview { top: 16px; }
}

/* Bubble shapes */
[data-bubbles="round"] { --ws-radius: 18px; --ws-tail: 6px; }
[data-bubbles="soft"] { --ws-radius: 12px; --ws-tail: 4px; }
[data-bubbles="square"] { --ws-radius: 5px; --ws-tail: 2px; }

/* The tutor's icon, over each of its messages */
html[data-icon] .msg.bot::before, .mini[data-icon] .mini-msg.bot::before { content: var(--ws-icon); display: block;
  margin: 0 0 2px 4px; font-size: 18px; line-height: 1.25; }

/* The chat's background, behind the messages: on the page (<html data-backdrop>) and on a card or the preview (.bd) */
html[data-backdrop="dots"] .log, .bd[data-backdrop="dots"] {
  background-image: radial-gradient(var(--ws-border-strong) 1px, transparent 1.2px); background-size: 22px 22px;
  background-attachment: local; }
html[data-backdrop="grid"] .log, .bd[data-backdrop="grid"] {
  background-image: linear-gradient(var(--ws-border) 1px, transparent 1px), linear-gradient(90deg, var(--ws-border) 1px, transparent 1px);
  background-size: 28px 28px; background-attachment: local; }
html[data-backdrop="lines"] .log, .bd[data-backdrop="lines"] {
  background-image: repeating-linear-gradient(to bottom, transparent 0 27px, var(--ws-border-strong) 27px 28px);
  background-attachment: local; }
html[data-backdrop="stripes"] .log, .bd[data-backdrop="stripes"] {
  background-image: repeating-linear-gradient(135deg, var(--ws-pattern, var(--ws-surface-2)) 0 14px, transparent 14px 28px);
  background-attachment: local; }
html[data-backdrop="checks"] .log, .bd[data-backdrop="checks"] {
  background-image: conic-gradient(var(--ws-pattern, var(--ws-surface-2)) 0 25%, transparent 0 50%, var(--ws-pattern, var(--ws-surface-2)) 0 75%, transparent 0);
  background-size: 40px 40px; background-attachment: local; }
html[data-backdrop="ripples"] .log, .bd[data-backdrop="ripples"] {
  background-image: repeating-radial-gradient(circle at 100% 100%, transparent 0 25px, var(--ws-pattern, var(--ws-border)) 25px 28px); }
html[data-backdrop="stars"] .log, .bd[data-backdrop="stars"] {
  background-image: radial-gradient(circle at 12% 18%, var(--ws-dot) 0 1.3px, transparent 1.8px),
    radial-gradient(circle at 63% 41%, var(--ws-border-strong) 0 1px, transparent 1.5px),
    radial-gradient(circle at 34% 77%, var(--ws-dot) 0 0.9px, transparent 1.4px),
    radial-gradient(circle at 86% 88%, var(--ws-accent) 0 1.3px, transparent 1.8px),
    radial-gradient(circle at 48% 9%, var(--ws-border-strong) 0 0.9px, transparent 1.4px),
    radial-gradient(circle at 92% 22%, var(--ws-dot) 0 1px, transparent 1.5px);
  background-size: 180px 180px; background-attachment: local; }
html[data-backdrop="glow"] .log, .bd[data-backdrop="glow"] {
  background-image: radial-gradient(ellipse at 50% 0%, var(--ws-accent-soft), transparent 70%); background-repeat: no-repeat; }
html[data-backdrop="aurora"] .log, .bd[data-backdrop="aurora"] {
  background-image: radial-gradient(60% 45% at 12% 0%, var(--ws-accent-soft), transparent 75%),
    radial-gradient(55% 40% at 92% 8%, var(--ws-user), transparent 75%),
    radial-gradient(70% 45% at 50% 100%, var(--ws-surface-2), transparent 75%);
  background-repeat: no-repeat; }
html[data-backdrop="sunrise"] .log, .bd[data-backdrop="sunrise"] {
  background-image: radial-gradient(120% 55% at 50% 0%, var(--ws-accent-soft), transparent 70%),
    linear-gradient(to top, var(--ws-surface-2), transparent 45%);
  background-repeat: no-repeat; }
html[data-backdrop="photo"] .log, .bd[data-backdrop="photo"] {
  background-image: linear-gradient(var(--ws-veil), var(--ws-veil)), var(--ws-photo); background-size: cover;
  background-position: center; }

/* ---- Phones */
@media (max-width: 640px) {
  .card-dialog { padding: 20px 18px 16px; }
  #theme .label { margin: 10px 0 6px !important; }
  #theme .pills button { min-height: 36px; padding: 0 12px; }
  #theme .swatches button { width: 36px; height: 36px; }
  .card-dialog.studio { width: calc(100vw - 16px); max-height: calc(100dvh - 16px); }
  .studio-head { padding: 18px 16px 0; }
  .pane { padding: 2px 16px 16px; }
  .studio-foot { padding: 10px 16px; }
  .looks { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
  .look-chat { height: 72px; }
  .mini-top, .mini-dock, .mini .prose p + p { display: none; }
  .mini-log { padding-top: 10px; }
  body { font-size: 14.5px; }
  .top { position: relative; height: 52px; padding: 0 8px; }
  .chip-name { display: none; }
  .class-box { position: static; }  /* the class menu spans the header, so it fits a narrow phone */
  .class-menu { left: 8px; right: 8px; width: auto; }
  .log { padding: 4px 10px 16px; }
  .dock { padding: 0 10px 4px; }
  .starters { grid-template-columns: minmax(0, 1fr); gap: 6px; }
  .starter { min-height: 48px; }
  .empty h1 { font-size: 20px; }
  .user .bubble, .edit-box { max-width: 88%; }
  .bubble { padding: 10px 14px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}

/* ---- The streak: the menu's count, its card (a fire, the number, and this week's days), and a quick word when a day
   keeps it going. The fire is the same orange in every theme (like an emoji); with no streak the big one is grey. */
.menu-count { margin-left: auto; min-width: 26px; padding: 1px 8px; border-radius: 999px; background: var(--ws-surface-2);
  color: var(--ws-text); font-size: 12.5px; font-weight: 800; text-align: center; font-variant-numeric: tabular-nums; }
/* A streak's first day (app.js streakToast): a quick word under the header that goes by itself, never over the reply.
   Its fire is drawn flat (the card's gradients live in a closed dialog, which some browsers won't paint from). */
.toast-wrap { position: fixed; top: calc(64px + env(safe-area-inset-top, 0px)); left: 16px; right: 16px; z-index: 35;
  display: flex; justify-content: center; pointer-events: none; }  /* under the menus (40), over the chat */
.toast { display: inline-flex; align-items: center; gap: 10px; max-width: 100%; padding: 8px 16px 8px 10px;
  border: 1px solid var(--ws-border-strong); border-radius: 999px; background: var(--ws-surface); color: var(--ws-text);
  font-size: 13.5px; font-weight: 700; text-align: left; pointer-events: auto;
  box-shadow: 0 10px 28px rgba(1, 20, 37, 0.18); animation: toast-in 0.25s ease both; }
.toast:hover { background: var(--ws-surface-2); }
.toast-flame { width: 22px; height: 22px; flex: none; }
.toast-flame path { stroke: none; }
.toast-flame .outer { fill: #f0762f; }
.toast-flame .inner { fill: #ffc93c; }
@keyframes toast-in { from { opacity: 0; transform: translateY(-6px); } }
.streak-dialog { width: min(400px, calc(100vw - 32px)); text-align: center; }
.streak-hero { display: flex; flex-direction: column; align-items: center; gap: 2px; margin: 6px 0 18px; }
.streak-flame { width: 76px; height: 76px; }
.streak-flame path, .wk-mark path { stroke: none; }
.streak-flame .outer { fill: url(#flame-outer); }
.streak-flame .inner { fill: url(#flame-inner); }
.streak-dialog.cold .streak-flame .outer { fill: var(--ws-border-strong); }
.streak-dialog.cold .streak-flame .inner { fill: var(--ws-surface-2); }
.streak-dialog .streak-num { margin: 4px 0 2px; font: 800 56px/1 var(--ws-display); letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.streak-hero h2 { margin: 0; font-size: 16px; font-weight: 700; color: var(--ws-muted); }
.streak-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; margin: 0 0 16px; padding: 12px 8px;
  border: 1px solid var(--ws-border); border-radius: 16px; background: var(--ws-surface-2); }
.wk { display: flex; flex-direction: column; align-items: center; gap: 6px; }
.wk-day { color: var(--ws-muted); font-size: 12px; font-weight: 700; }
.wk.is-today .wk-day { color: var(--ws-text); font-weight: 800; }
.wk-mark { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px;
  border: 2px solid var(--ws-border-strong); border-radius: 50%; }
.wk.on .wk-mark { border: 0; background: linear-gradient(#ffb347, #f0562b); }
.wk.on .wk-mark svg { width: 22px; height: 22px; }
.wk.on .wk-mark .outer { fill: #ffffff; }
.wk.on .wk-mark .inner { fill: #ffc93c; }
.wk.today .wk-mark { border-style: dashed; border-color: #f0862b; }
.wk.later .wk-mark { border-color: var(--ws-border); opacity: 0.6; }
.streak-dialog .streak-line { margin: 0 auto 4px; max-width: 34ch; }
/* The celebration (#streak-pop): the fire bursts in and keeps flickering, sparks float up, the number rolls from
   yesterday's to today's, the words rise in, today's fire pops into the week, then the button. Each part's resting
   state is its final one, so with reduced motion (every animation off, above) it's simply all there. */
.streak-pop { width: min(380px, calc(100vw - 32px)); padding-top: 26px; text-align: center; overflow: hidden; cursor: pointer; }
.streak-pop::backdrop { background: rgba(1, 20, 37, 0.62); animation: pop-fade 0.25s ease both; }
.pop-flame { position: relative; width: 132px; height: 132px; margin: 0 auto; }
.pop-svg { width: 132px; height: 132px; overflow: visible; transform-origin: 50% 92%;
  filter: drop-shadow(0 8px 22px rgba(240, 86, 43, 0.5));
  animation: pop-in 0.75s cubic-bezier(0.34, 1.56, 0.64, 1) both, flicker 1.7s ease-in-out 0.75s infinite; }
.pop-svg path { stroke: none; }
.pop-svg .outer { fill: url(#pop-outer); }
.pop-svg .inner { fill: url(#pop-inner); transform-box: fill-box; transform-origin: 50% 100%;
  animation: inner-flicker 1.2s ease-in-out 0.75s infinite; }
.spark { position: absolute; left: 50%; bottom: 26%; width: 7px; height: 7px; margin-left: -3.5px; border-radius: 50%;
  background: #ffc93c; box-shadow: 0 0 6px #ff9a3c; opacity: 0; animation: spark 1.8s ease-out infinite both; }
.spark.s1 { --dx: -52px; --dy: -96px; animation-delay: 0.45s; }
.spark.s2 { --dx: 46px; --dy: -104px; animation-delay: 0.6s; background: #ff8a3d; }
.spark.s3 { --dx: -26px; --dy: -120px; animation-delay: 0.8s; width: 5px; height: 5px; }
.spark.s4 { --dx: 30px; --dy: -86px; animation-delay: 1s; }
.spark.s5 { --dx: -62px; --dy: -60px; animation-delay: 1.2s; width: 5px; height: 5px; background: #ff8a3d; }
.spark.s6 { --dx: 60px; --dy: -64px; animation-delay: 1.35s; width: 5px; height: 5px; }
.spark.s7 { --dx: -8px; --dy: -128px; animation-delay: 1.55s; }
.spark.s8 { --dx: 14px; --dy: -110px; animation-delay: 1.7s; width: 5px; height: 5px; background: #ff8a3d; }
.streak-pop .pop-num { position: relative; height: 64px; margin: 2px 0 0; overflow: hidden;
  font: 800 60px/64px var(--ws-display); letter-spacing: -0.03em; font-variant-numeric: tabular-nums; }
.pop-num span { display: block; }
.pop-num .was { position: absolute; inset: 0; opacity: 0; animation: roll-out 0.4s cubic-bezier(0.5, 0, 0.75, 0) 0.8s both; }
.pop-num .now { animation: roll-in 0.55s cubic-bezier(0.34, 1.56, 0.64, 1) 0.95s both; }
.streak-pop .pop-title { margin: 0 0 16px; color: var(--ws-text); font-size: 20px; font-weight: 800;
  animation: rise 0.45s ease-out 1.05s both; }
.pop-week { margin-bottom: 12px; animation: rise 0.45s ease-out 1.15s both; }
.wk.fresh .wk-mark { animation: light-up 0.6s cubic-bezier(0.34, 1.56, 0.64, 1) 1.45s both; }
.streak-pop .pop-line { margin: 0 auto 4px; max-width: 34ch; color: var(--ws-muted); animation: rise 0.45s ease-out 1.6s both; }
.pop-go { animation: rise 0.45s ease-out 1.75s both; }
@keyframes pop-fade { from { opacity: 0; } }
@keyframes pop-in { 0% { opacity: 0; transform: translateY(36px) scale(0.2); } 60% { opacity: 1; transform: scale(1.18); }
  100% { transform: scale(1); } }
@keyframes flicker { 0%, 100% { transform: scale(1, 1) skewX(0); } 25% { transform: scale(0.97, 1.05) skewX(-2deg); }
  50% { transform: scale(1.03, 0.97) skewX(1.5deg); } 75% { transform: scale(0.99, 1.04) skewX(-1deg); } }
@keyframes inner-flicker { 0%, 100% { transform: scale(1); } 50% { transform: scale(0.88, 1.12); } }
@keyframes spark { 0% { opacity: 0; transform: translate(0, 0) scale(1); } 15% { opacity: 1; }
  100% { opacity: 0; transform: translate(var(--dx), var(--dy)) scale(0.3); } }
@keyframes roll-out { from { opacity: 1; transform: translateY(0); } to { opacity: 0; transform: translateY(-75%); } }
@keyframes roll-in { from { opacity: 0; transform: translateY(75%); } to { opacity: 1; transform: none; } }
@keyframes rise { from { opacity: 0; transform: translateY(10px); } }
@keyframes light-up { 0% { transform: scale(0); } 70% { transform: scale(1.25); box-shadow: 0 0 0 6px rgba(240, 134, 43, 0.35); }
  100% { transform: scale(1); box-shadow: 0 0 0 0 rgba(240, 134, 43, 0); } }

/* ---- Share a chat: the card (index.html #share), and the page a shared link opens (share.html) */
.share-chat { font-weight: 800; overflow-wrap: anywhere; }
.share-started { color: var(--ws-muted); font-size: 13px; font-weight: 600; white-space: nowrap; }
.share-row { margin-top: 14px; }
.share-row input { font-size: 13.5px; color: var(--ws-muted); }
.share-state { margin-top: 10px !important; color: var(--ws-muted); font-size: 13.5px; }
.share-state:empty { display: none; }
#share .form-msg { color: var(--ws-text); }
#share .actions { flex-wrap: wrap; }
.share-stop { margin-right: auto; color: var(--ws-danger); }

.share-page { min-height: 100dvh; display: flex; flex-direction: column; }
.share-top { width: 100%; max-width: 852px; margin: 0 auto; }
.share-top .brand { text-decoration: none; color: inherit; }
.share-open { margin-left: auto; min-height: 36px; padding: 0 14px; font-size: 13.5px; text-decoration: none; color: inherit; }
.share-main { flex: 1; width: 100%; max-width: 852px; margin: 0 auto; padding: 8px 16px 40px; }
.share-main h1 { margin: 0 0 4px; font-size: clamp(22px, 4vw, 28px); font-weight: 800; letter-spacing: -0.01em;
  line-height: 1.25; overflow-wrap: anywhere; }
.share-meta { margin: 0 0 18px; color: var(--ws-muted); font-size: 13.5px; }
.share-main .messages { gap: 14px; padding-bottom: 8px; }
.share-main .who { margin: 0 4px; color: var(--ws-muted); font-size: 12px; font-weight: 800; letter-spacing: 0.04em;
  text-transform: uppercase; }
.share-foot { margin: 28px 0 0; padding-top: 14px; border-top: 1px solid var(--ws-border); color: var(--ws-muted);
  font-size: 13px; line-height: 1.6; }
.share-gone { max-width: 520px; margin: 14vh auto 0; padding: 0 16px; text-align: center; }
.share-gone .gone-go { margin-top: 22px; }
.share-gone .gone-go .btn { text-decoration: none; }
.share-gone .gone-staff { margin-top: 18px; font-size: 13.5px; }
.share-gone .gone-staff a { color: var(--ws-link); }
.share-gone h1 { font-size: 24px; font-weight: 800; }
.share-gone p { color: var(--ws-muted); }

/* ---- Practice (practice.js): flashcards and a short quiz for each week's topic, in a card over the page. Right and
   wrong are said in words and marked with the theme's accent and danger colours, never colour alone. */
.practice-link { display: inline-flex; align-items: center; gap: 8px; margin-top: 14px; font-size: 14px; }
.practice-link svg { width: 16px; height: 16px; }
.card-dialog.practice { width: min(680px, calc(100vw - 32px)); padding: 0; }
.pr-head { position: sticky; top: 0; z-index: 2; display: flex; align-items: flex-start; gap: 6px;
  padding: 16px 14px 12px 22px; border-bottom: 1px solid var(--ws-border); background: var(--ws-surface); }
.pr-head #pr-back:not([hidden]) + .pr-titles { margin-left: -2px; }
.pr-head #pr-back { margin: 2px 0 0 -10px; flex: none; }
.pr-titles { flex: 1; min-width: 0; }
.card-dialog .pr-titles h2 { margin: 0 0 2px; font-size: 20px; overflow-wrap: anywhere; }
.card-dialog .pr-titles .muted { margin: 0; font-size: 13.5px; line-height: 1.45; }
.pr-body { padding: 16px 22px 20px; }
.card-dialog .pr-msg { margin: 0; padding: 0 22px 16px; font-size: 13.5px; font-weight: 700; color: var(--ws-danger); }
.pr-msg:empty { display: none; }
.card-dialog .pr-loading, .card-dialog .pr-note { margin: 8px 0; color: var(--ws-muted); }

.pr-topics { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
.pr-topic { display: flex; align-items: center; gap: 14px; padding: 12px 14px; border: 1px solid var(--ws-border);
  border-radius: 14px; background: var(--ws-surface); }
.pr-topic.last { border-color: var(--ws-accent); box-shadow: inset 0 0 0 1px var(--ws-accent); }
.pr-topic-text { flex: 1; min-width: 0; }
.pr-week { display: block; color: var(--ws-muted); font-size: 11.5px; font-weight: 800; letter-spacing: 0.06em;
  text-transform: uppercase; }
.pr-topic h3 { margin: 2px 0 8px; font-size: 16px; font-weight: 800; overflow-wrap: anywhere; }
.pr-meter { height: 6px; border-radius: 999px; background: var(--ws-surface-2); box-shadow: inset 0 0 0 1px var(--ws-border); overflow: hidden; }
.pr-meter span { display: block; width: 0; height: 100%; border-radius: inherit; background: var(--ws-accent); transition: width 0.3s ease; }
.pr-meter.big { max-width: 320px; height: 8px; margin: 10px auto 14px; }
.card-dialog .pr-stats { margin: 6px 0 0; color: var(--ws-muted); font-size: 13px; line-height: 1.4; }
.pr-topic-go { display: flex; flex: none; gap: 8px; }

.pr-bar { display: flex; justify-content: space-between; gap: 12px; margin-bottom: 10px; color: var(--ws-muted);
  font-size: 13px; font-weight: 700; }
.pr-pills { margin-bottom: 12px; }
.pr-pills button { min-height: 34px; padding: 0 12px; font-size: 13px; }
.pr-pills button:disabled { opacity: 0.5; cursor: default; }
.pr-card { position: relative; display: flex; flex-direction: column; justify-content: center; min-height: 210px;
  padding: 26px 22px 16px; border: 1px solid var(--ws-border-strong); border-radius: 18px; background: var(--ws-bot);
  cursor: pointer; }
.pr-card.revealed { cursor: auto; }
.pr-front { font-size: 18px; font-weight: 700; line-height: 1.5; text-align: center; overflow-wrap: anywhere; }
.pr-front .code, .pr-back .code { text-align: left; }
.pr-card.revealed .pr-front { color: var(--ws-muted); font-size: 15px; text-align: left; }
.pr-back { margin-top: 14px; padding-top: 14px; border-top: 1px dashed var(--ws-border-strong); font-size: 15.5px;
  line-height: 1.6; overflow-wrap: anywhere; animation: pr-in 0.18s ease; }
@keyframes pr-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
.card-dialog .pr-tap { margin: 16px 0 0; color: var(--ws-muted); font-size: 12.5px; text-align: center; }
.card-dialog .pr-tag { align-self: flex-end; margin: -14px -8px 6px 0; padding: 2px 10px; border-radius: 999px;
  background: var(--ws-accent-soft); color: var(--ws-accent); font-size: 12px; font-weight: 800; line-height: 1.6; }
.pr-row { display: flex; flex-wrap: wrap; justify-content: center; gap: 10px; margin-top: 14px; }
.pr-row .btn { min-width: 150px; min-height: 44px; }
.pr-row .btn.pr-wide { min-width: min(280px, 100%); }
.pr-nav { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 14px; }
.pr-nav .link { min-height: 32px; }
.link:disabled { opacity: 0.45; cursor: default; text-decoration: none; }
.pr-body .code-head .copied { color: var(--ws-accent); box-shadow: inset 0 0 0 1px var(--ws-accent); }

.pr-q { margin: 14px 0; font-size: 16.5px; font-weight: 700; line-height: 1.55; overflow-wrap: anywhere; }
.pr-choices { display: grid; gap: 8px; }
.pr-choice { display: flex; align-items: flex-start; gap: 12px; width: 100%; padding: 11px 14px; border: 1px solid var(--ws-border-strong);
  border-radius: 14px; background: var(--ws-surface); font-size: 15px; line-height: 1.45; text-align: left; }
.pr-choice:hover:not([aria-disabled="true"]) { border-color: var(--ws-accent); background: var(--ws-surface-2); }
.pr-choice[aria-disabled="true"] { cursor: default; }
.pr-choice[aria-disabled="true"]:not(.right):not(.wrong) { opacity: 0.68; }
.pr-letter { display: inline-flex; flex: none; align-items: center; justify-content: center; width: 26px; height: 26px;
  border-radius: 8px; background: var(--ws-surface-2); font-size: 13px; font-weight: 800; }
.pr-choice-text { flex: 1; min-width: 0; padding-top: 2px; overflow-wrap: anywhere; }
.pr-choice code, .pr-was code { padding: 1px 5px; border-radius: 6px; background: var(--ws-code-bg);
  font: 13.5px/1.5 ui-monospace, "SF Mono", Menlo, Consolas, monospace; }
.pr-mark { display: block; font-size: 12.5px; font-weight: 800; }
.pr-mark:empty { display: none; }
.pr-choice.right { border-color: var(--ws-accent); background: var(--ws-accent-soft); box-shadow: inset 0 0 0 1px var(--ws-accent); }
.pr-choice.right .pr-letter { background: var(--ws-accent-btn); color: var(--ws-on-accent); }
.pr-choice.right .pr-mark { color: var(--ws-accent); }
.pr-choice.wrong { border-color: var(--ws-danger); box-shadow: inset 0 0 0 1px var(--ws-danger); }
.pr-choice.wrong .pr-letter { background: var(--ws-danger); color: var(--ws-on-danger); }
.pr-choice.wrong .pr-mark { color: var(--ws-danger); }
.pr-why { margin-top: 14px; padding: 12px 14px; border: 1px solid var(--ws-note-border); border-radius: 14px;
  background: var(--ws-note-bg); font-size: 14.5px; }
.pr-why:empty { display: none; }
.card-dialog .pr-verdict { margin: 0 0 4px; font-weight: 800; }
.pr-row.pr-after { justify-content: space-between; align-items: center; }

.pr-done { padding: 6px 0 2px; text-align: center; }
.card-dialog .pr-big { margin: 0; font-size: 42px; font-weight: 800; letter-spacing: -0.02em; line-height: 1.1; }
.card-dialog .pr-big-label { margin: 0 0 8px; color: var(--ws-muted); font-size: 13px; font-weight: 800;
  letter-spacing: 0.06em; text-transform: uppercase; }
.card-dialog .pr-fresh { margin: 14px 0 0; }
.pr-review { margin-top: 14px; text-align: left; }
.pr-review summary { cursor: pointer; color: var(--ws-link); font-size: 14px; font-weight: 800; }
.pr-review ol { margin: 10px 0 0; padding-left: 22px; }
.pr-review li { margin-bottom: 16px; }
.card-dialog .pr-was { margin: 4px 0; font-size: 14px; }
.pr-review-why { margin-top: 6px; color: var(--ws-muted); font-size: 14px; }

@media (max-width: 640px) {
  .card-dialog.practice { width: calc(100vw - 16px); max-height: calc(100dvh - 16px); }
  .pr-head { padding: 12px 8px 10px 16px; }
  .pr-body { padding: 12px 14px 16px; }
  .card-dialog .pr-msg { padding: 0 14px 12px; }
  .pr-topic { flex-direction: column; align-items: stretch; gap: 10px; }
  .pr-topic-go .btn { flex: 1; }
  .pr-card { min-height: 180px; padding: 24px 16px 14px; }
  .pr-front { font-size: 16.5px; }
  .pr-row .btn { flex: 1; min-width: 0; }
  .pr-row.pr-after .btn { flex: none; }
  .card-dialog .pr-big { font-size: 36px; }
}
