/* The app
   An index, not a dashboard. Small uppercase type, hairline rules, grey for what is untouched and
   black for what you have worked on. The dots carry the only colour.
   Change the tokens below to restyle everything. */

/* Liber, the owner's own typeface (drawn italics, eight static styles), each file at the weight its
   name says: Regular is the reading weight (400), Medium the 500. Atelier Grotesk Two stays behind
   it for any character Liber lacks. */
@font-face { font-family: "Liber"; src: url("/fonts/Liber-Light.woff2") format("woff2"); font-weight: 300; font-style: normal; font-display: swap; }
@font-face { font-family: "Liber"; src: url("/fonts/Liber-LightItalic.woff2") format("woff2"); font-weight: 300; font-style: italic; font-display: swap; }
@font-face { font-family: "Liber"; src: url("/fonts/Liber-Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Liber"; src: url("/fonts/Liber-Italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Liber"; src: url("/fonts/Liber-Medium.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Liber"; src: url("/fonts/Liber-MediumItalic.woff2") format("woff2"); font-weight: 500; font-style: italic; font-display: swap; }
@font-face { font-family: "Liber"; src: url("/fonts/Liber-Semibold.woff2") format("woff2"); font-weight: 600; font-style: normal; font-display: swap; }
@font-face { font-family: "Liber"; src: url("/fonts/Liber-SemiboldItalic.woff2") format("woff2"); font-weight: 600; font-style: italic; font-display: swap; }
@font-face { font-family: "Atelier Grotesk Two"; src: url("/fonts/Atelier_Grotesk_Two_Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
@font-face { font-family: "Atelier Grotesk Two"; src: url("/fonts/Atelier_Grotesk_Two_Medium.woff2") format("woff2"); font-weight: 500; font-style: normal; font-display: swap; }
@font-face { font-family: "Atelier Grotesk Two"; src: url("/fonts/Atelier_Grotesk_Two_Bold.woff2") format("woff2"); font-weight: 700; font-style: normal; font-display: swap; }
@font-face { font-family: "Atelier Grotesk Two"; src: url("/fonts/Atelier_Grotesk_Two_Italic.woff2") format("woff2"); font-weight: 400; font-style: italic; font-display: swap; }
@font-face { font-family: "Atelier Grotesk Two"; src: url("/fonts/Atelier_Grotesk_Two_Medium_Italic.woff2") format("woff2"); font-weight: 500; font-style: italic; font-display: swap; }
@font-face { font-family: "Atelier Grotesk Two"; src: url("/fonts/Atelier_Grotesk_Two_Bold_Italic.woff2") format("woff2"); font-weight: 700; font-style: italic; font-display: swap; }
@font-face { font-family: "Atelier Mono"; src: url("/fonts/Atelier_Mono_Regular.woff2") format("woff2"); font-weight: 400; font-style: normal; font-display: swap; }
/* The owner's Atelier fonts, as supplied; see /fonts/OFL.txt. */

:root {
  --bg: #ffffff;
  --ink: #000000;
  --grey: #a3a3a3;        /* untouched, secondary */
  --hover: #f3f3f3;
  --rule: #000000;
  --hair: #d9d9d9;
  /* The dot scale: unstudied, with help, on your own, solid (ring), held over time (faint ring) */
  --k0: #000000; --k1: #5e5e5e; --k2: #b8b8b8; --k3: #b8b8b8; --k4: #e3e3e3;
  --red: #ff2a00;
  --gold: #c99a1e;          /* an accomplished concept or term */
  --mark: #fff0a6;          /* your highlights */
  --dot-off: #d9d9d9;     /* an unfilled confidence dot */
  --spring: cubic-bezier(.34, 1.56, .64, 1);
  --ease: cubic-bezier(.25, .1, .25, 1);
  --font: "Liber", "Atelier Grotesk Two", ui-sans-serif, -apple-system, "Helvetica Neue", Arial, sans-serif;
  --mono: "Atelier Mono", ui-monospace, "SF Mono", Menlo, Consolas, monospace;
  --small: 13px;          /* the index voice and every header */
  /* Two type sizes, everywhere: small for headers and labels (tools, codes, counts, the index, a
     window's name) and for everything inside a window or page, so nothing is larger than its
     header; large only for the conversation, the answer box, and names that head a list. */
  --fs-s: var(--small);
  --fs-l: 18px;
  --lead: 1.18;
  --dot: 6px;
  --big-dot: 14px;
  --edge: 0px;       /* how far the rails sit in from the window's edges */   /* the tutor's dot and the menu dot: one size */
  /* Drawings: the pen table (docs/DRAWINGS.md). A fine set, as in a well-drawn detail: the cut is
     only a step heavier than what is seen, and hatches, dashes and dimensions are hairlines in a
     lighter tone, so the drawing reads by structure, not by bold. Strokes never scale with zoom. */
  --pen-cut: 1.25px; --pen-profile: .85px; --pen-medium: .6px; --pen-beyond: .45px;
  --pen-hidden: .45px; --pen-center: .35px; --pen-dim: .4px; --pen-hatch: .3px;
  --pen-light: color-mix(in srgb, var(--ink) 55%, var(--bg));   /* hatch, hidden, centre lines */
  --pen-tone: color-mix(in srgb, var(--ink) 6%, var(--bg));     /* a flat poché */
  --pad: 12px;
  --field-w: 520px;
  --measure: 640px;
  color-scheme: light;
}
:root[data-theme="dark"] {
  --bg: #000000; --ink: #ffffff; --grey: #6b6b6b; --hover: #141414; --rule: #ffffff; --hair: #2a2a2a;
  --k0: #ffffff; --k1: #a3a3a3; --k2: #4f4f4f; --k3: #4f4f4f; --k4: #262626;
  --gold: #e3b641;
  --mark: #5c4b00;
  --dot-off: #5c5c5c;
  color-scheme: dark;
}

* { box-sizing: border-box; }
[hidden] { display: none !important; }
html, body { height: 100%; }
body { margin: 0; background: var(--bg); color: var(--ink); font: 400 var(--small)/var(--lead) var(--font); letter-spacing: .01em; -webkit-font-smoothing: antialiased; }
p { margin: 0 0 1em; }
button, input, select, textarea { font: inherit; color: inherit; letter-spacing: inherit; }
button { cursor: pointer; background: none; border: 0; padding: 0; text-align: left; }
em { font-style: italic; }   /* Liber's drawn italics */
a { color: inherit; }
.brand { font-weight: 500; }
.dim { color: var(--grey); }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
.error { color: var(--red); margin: .5rem 0; text-transform: uppercase; }
.error:empty { display: none; }
.text-btn { color: inherit; }
.text-btn:hover { text-decoration: underline; text-underline-offset: 2px; }
.btn { text-decoration: underline; text-underline-offset: 2px; text-transform: uppercase; }
.btn:disabled { color: var(--grey); cursor: default; }
:focus-visible { outline: 1px solid var(--ink); outline-offset: 2px; }

/* ---------- sign in and about you ---------- */
.lede { font-size: var(--fs-l); line-height: 1.22; letter-spacing: -.01em; margin: 3.6rem 0 2.6rem; max-width: 560px; }
#auth-box:not(.signup) .signup-only { display: none; }
#auth-box.forgot .pw-row, #auth-box.reset .email-row, #auth-box.reset #auth-forgot,
#auth-box:is(.forgot, .reset) .google-row, #auth-box.signup #auth-forgot { display: none; }
#auth-forgot { color: var(--grey); text-transform: none; font-size: var(--fs-s); }
.auth-note { margin: .5rem 0; font-size: var(--fs-s); color: var(--grey); grid-column: 1 / -1; }
.auth-note:empty { display: none; }
.auth-legal { margin: .2rem 0 .6rem; font-size: var(--fs-s); color: var(--grey); grid-column: 1 / -1; }
.auth-legal a { color: inherit; }
.auth-box .actions { display: flex; gap: 22px; align-items: baseline; }
.home-legal { display: block; margin-top: .5rem; }
.home-legal .sep { margin: 0 .6em; }
.home-legal a { color: inherit; text-decoration: none; }
.home-legal a:hover { color: var(--ink); }
.form label { display: block; text-transform: uppercase; color: var(--grey); margin-bottom: 1.3rem; max-width: 420px; }
.form input, .form select, .form textarea { display: block; width: 100%; margin-top: .35rem; background: transparent; border: 0;
  border-bottom: 1px solid var(--hair); padding: .25rem 0; font-size: var(--fs-l); letter-spacing: 0; color: var(--ink); text-transform: none; border-radius: 0; }
.form select option { background: var(--bg); }
.form input:focus, .form select:focus, .form textarea:focus { outline: none; border-bottom-color: var(--ink); }
.choices { border: 0; padding: 0; margin: 0 0 1.3rem; }
.choices legend { text-transform: uppercase; color: var(--grey); margin-bottom: .4rem; }
.choices label { display: inline-flex; align-items: center; gap: .4rem; margin: 0 1.2rem .3rem 0; font-size: var(--fs-l); color: var(--ink); text-transform: none; }
.choices input { width: auto; margin: 0; accent-color: var(--ink); }
.actions { display: flex; align-items: center; gap: 1.4rem; margin-top: 2rem; text-transform: uppercase; }

/* No scroll bars anywhere: everything still scrolls (wheel, trackpad, touch, keys), but no bar runs
   up against the rails' dots at the window's edge. */
* { scrollbar-width: none; }
*::-webkit-scrollbar { display: none; }

/* ---------- study page: the conversation, and a rail of dots ---------- */
.study { position: relative; height: 100vh; height: 100dvh; overflow: hidden; }

/* At rest the rail is only dots. Hovered (or tapped), it opens into the index. */
.rail { position: fixed; z-index: 20; top: 0; bottom: 0; left: var(--edge); width: 44px; background: transparent;
  display: flex; flex-direction: column; text-transform: uppercase; transition: width .45s var(--ease), background-color .3s var(--ease); }
.rail.open { left: 0; padding-left: var(--edge); width: min(580px + var(--edge), 100vw);   /* the panel reaches the edge; the dots stay put */
  background: var(--bg); border-right: 1px solid var(--hair); }
.tally { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 2px 14px; color: var(--grey); }

.dots-col { flex: 1; min-height: 0; overflow-y: auto; overflow-x: hidden; scrollbar-width: none; padding: 18px 0; }
.dots-col::-webkit-scrollbar { display: none; }
.study .rail { cursor: pointer; }
/* The peek: hovering the rail in the chat. No panel: the dots ease apart (the rows open a little)
   and each one's code fades in beside it, 2.2.A, a beat after. Nothing else. */
.study .rail.peek { width: 140px; background: transparent; border-right: 0; }
.study .rail.peek :is(.chap-head, .obj-head, .kterms, .crow .c-title, .crow .c-tag) { display: none; }
.study .rail.peek .chapter-gap { height: 12px; }
.study .rail.peek .crow { grid-template-columns: 44px auto; }
.study .rail.peek .crow:hover { background: transparent; color: var(--ink); }
.study .rail.peek .crow .c-code { transition-delay: .12s; }
.chapter-gap { height: 12px; transition: height .45s var(--ease); }
:is(.rail.open, .index-page) .chapter-gap { height: 0; }
.chap-head, .obj-head { display: grid; grid-template-columns: 44px 6.4em 1fr auto; align-items: center; width: 100%; padding-right: var(--pad);
  max-height: 0; overflow: hidden; opacity: 0; transition: max-height .45s var(--ease), opacity .25s var(--ease); }
:is(.rail.open, .index-page) .chap-head { max-height: 30px; opacity: 1; padding-top: 10px; padding-bottom: 4px; border-bottom: 1px solid var(--hair); }
:is(.rail.open, .index-page) .obj-head { max-height: 24px; opacity: 1; padding-top: 6px; padding-bottom: 2px; }
.chap-head > :first-child { grid-column: 2 / 4; }
.chap-head > :nth-child(2) { display: none; }
.obj-head > :first-child { grid-column: 2; }
.chap-head .count, .obj-head .count { color: var(--grey); }
.obj-head:hover .t { text-decoration: underline; text-underline-offset: 2px; }

/* A concept row: the dot always; its code and title only when the rail is open. */
.crow { display: grid; grid-template-columns: 44px 6.4em 1fr auto; align-items: center; width: 100%; height: 15px;
  padding-right: var(--pad); color: var(--grey); transition: height .45s var(--ease); }
:is(.rail.open, .index-page) .crow { height: 15px; }
.crow .dot { justify-self: center; }
.crow .c-code, .crow .c-title, .crow .c-tag { opacity: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity .25s var(--ease); }
:is(.rail.open, .index-page) .crow .c-code, :is(.rail.open, .index-page) .crow .c-title, :is(.rail.open, .index-page) .crow .c-tag { opacity: 1; }
.crow.touched, .crow:hover, .crow.active { color: var(--ink); }
:is(.rail.open, .index-page) .crow:hover { background: var(--hover); }
.crow.active .c-code::before { content: "→ "; }
.crow .c-tag { color: var(--grey); }

/* The index views: CONCEPTS and TERMS, with an underline that slides between them. */
.index-views { grid-column: 1 / -1; position: relative; display: flex; gap: 14px; padding-bottom: 3px; }
.index-views .text-btn { color: var(--grey); text-transform: inherit; text-decoration: none; transition: color .2s var(--ease); }
.index-views .text-btn:hover { color: var(--ink); text-decoration: none; }
.index-views .text-btn.on { color: var(--ink); }   /* the view you are in: black, no underline */
.index-views .view-mark { display: none; }
.view-mark { position: absolute; bottom: 0; left: 0; width: 0; height: 1px; background: var(--ink);
  transition: left .32s var(--spring), width .32s var(--spring); }

/* A concept's terms, under it: unfolded for the concept in focus, on hover for the others, and for
   every concept in the TERMS view. The rows drop in one after another. Closed, only the dots. */
.kterms { display: grid; grid-template-rows: 0fr; opacity: 0;
  transition: grid-template-rows .3s var(--ease), opacity .2s var(--ease); }
.kterms-in { overflow: hidden; min-height: 0; }
.rail:not(.open) .kterms { display: none; }
:is(.rail.open, .index-page) .cgroup:is(.focus, .peek) .kterms, :is(.rail.open, .index-page)[data-view="terms"] .kterms { grid-template-rows: 1fr; opacity: 1; }
@media (hover: hover) {
  :is(.rail.open, .index-page) .cgroup:hover .kterms { grid-template-rows: 1fr; opacity: 1; transition-delay: .15s; }   /* a pause, so sweeping past doesn't flap */
}
.kitem.trow { display: grid; grid-template-columns: 44px 6.4em 1fr auto; column-gap: 8px; align-items: center; padding: 2px var(--pad) 2px 0;
  opacity: 0; transform: translateY(-5px); transition: opacity .2s var(--ease), transform .3s var(--spring); }
:is(.rail.open, .index-page) .cgroup:is(.focus, .peek) .trow, :is(.rail.open, .index-page)[data-view="terms"] .trow { opacity: 1; transform: none; transition-delay: calc(var(--j, 0) * 35ms); }
@media (hover: hover) { :is(.rail.open, .index-page) .cgroup:hover .trow { opacity: 1; transform: none; transition-delay: calc(.15s + var(--j, 0) * 35ms); } }
.kitem.trow .kdot { justify-self: end; width: 5px; height: 5px; }
.kitem.trow .k-term { font-size: var(--fs-s); }
.kitem.trow .k-brief { grid-column: 3 / 5; font-size: var(--fs-s); }
.ip-list { text-transform: uppercase; }   /* titles are stored in normal case; the desktop index sets them in capitals */
/* Stage and concept descriptions keep their own case; codes, phases, and tallies stay in capitals. */
:is(.index-page, .rail) :is(.crow .c-title, .obj-head .t) { text-transform: none; }
/* Names in proper case, as on a phone: phases, terms, the views and the tally. Codes and tags stay small capitals. */
:is(.index-page, .rail) :is(.chap-head > :first-child, .kterms), .index-page :is(.ip-views, .ip-tally) { text-transform: none; }
.ip-list button { text-transform: inherit; }   /* rows are buttons, which browsers set to none */

/* The menu pages are windows like the tools, a little wider, with tabs. */
.popup.menu-page { width: 420px; }
.page-tabs { display: flex; gap: 14px; padding: 0 0 10px; border-bottom: 1px solid var(--hair); margin-bottom: 8px; }
.page-tabs .text-btn { color: var(--grey); }
.page-tabs .text-btn.on { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.page-form .lede { font-size: var(--fs-s); margin: .4rem 0 1rem; }
.page-body .prose, .page-form .lede { text-transform: none; font-size: var(--fs-s); line-height: 1.4; color: var(--ink); }
.page-form label { max-width: none; }
.page-form .actions { margin-top: .6rem; }
.page-form .choices label { display: flex; align-items: center; gap: 8px; margin-bottom: .5rem; }
.page-form .choices input { display: inline-block; width: auto; margin: 0; }

/* Things to know: one small dot per item, on the same scale as the concept dots. */
.kdot { flex: none; display: inline-block; width: 4px; height: 4px; border-radius: 50%; background: var(--k0); }
.kdot.k1, .kdot.k2 { background: transparent; box-shadow: inset 0 0 0 1px var(--k2); }
.kdot.k4 { background: transparent; box-shadow: inset 0 0 0 1px var(--k4); }
.kdot.r-stroke { background: transparent; box-shadow: inset 0 0 0 1px var(--red); }
.kdot.r-fill { background: var(--red); box-shadow: none; }
.kitem { display: grid; grid-template-columns: 6px 1fr auto; column-gap: 8px; align-items: baseline; padding: 3px 0; }
.kitem .kdot { width: 5px; height: 5px; align-self: center; }
.k-term { text-align: left; color: var(--ink); text-transform: none; font-size: var(--fs-s); }
.k-term:hover { text-decoration: underline; text-underline-offset: 2px; }
.k-status { color: var(--grey); font-size: var(--small); text-transform: uppercase; }
.kitem .k-brief { grid-column: 2 / 4; margin: .2rem 0 .3rem; font-size: var(--fs-s); line-height: 1.35; color: var(--ink); text-transform: none; }
.k-where { color: var(--grey); text-decoration: underline; text-underline-offset: 2px; }
.page-body .kitem { padding: 6px 0; border-top: 1px solid var(--hair); }
.page-body .k-term { font-size: var(--fs-s); }

/* ---------- spaces: home, the dots, the chat, side by side like desktops ---------- */
.space { position: fixed; inset: 0; overflow-y: auto; background: var(--bg); transform: translateX(100%);
  transition: transform .6s cubic-bezier(.22, .9, .25, 1); }
.space.here { transform: none; }
.space.home { position: fixed; }   /* home is a space too: off to one side, it must not widen the page (phones grow to fit) */
.study.space { overflow: hidden; }
/* Moving between them: each side edge shows, full height, the space it leads to. */
.space-nav { position: fixed; z-index: 35; inset: 0; pointer-events: none; }
.space-arrow { position: absolute; top: 0; bottom: 0; width: 32px; display: flex; flex-direction: column; align-items: center;
  justify-content: center; padding: 56px 0; pointer-events: auto; color: var(--grey); text-transform: uppercase; font-size: var(--fs-s); }
.space-arrow.prev { left: calc(6px + var(--edge)); } .space-arrow.next { right: calc(6px + var(--edge)); }
.glyph { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; }
.glyph i { display: block; flex: none; width: 7px; height: 7px; border-radius: 50%; background: var(--ink); transition: transform .3s var(--spring); }
/* The dots: the concept dots as the rail draws them, scaled to the window's height. */
/* Spaced exactly as the rail in the tutor (15 px a row, 12 px between phases) and
   clipped by the window, so the dots fly to the index the same way from either place. */
.space-arrow:has(.g-dots) { padding: 0; }
.g-dots { justify-content: flex-start; padding-top: 56px; overflow: hidden; min-height: 0; }   /* clear of the menu dot above */
.g-dots i.dot { width: var(--dot); height: var(--dot); margin: calc((15px - var(--dot)) / 2) 0; }
.g-dots b { display: block; flex: none; height: 12px; }
/* The chat: one dot in the middle that breathes. */
.g-chat { justify-content: center; }
.g-chat i { width: var(--big-dot); height: var(--big-dot); animation: chat-breathe 2.4s var(--ease) infinite; }
@keyframes chat-breathe { 0%, 100% { transform: scale(.8); opacity: 1; } 50% { transform: scale(1.15); opacity: .55; } }
/* The name only after a moment's hover. */
.space-name { position: absolute; top: 50%; white-space: nowrap; transform: translateY(-50%); opacity: 0; transition: opacity .2s var(--ease); }
.space-arrow.prev .space-name { left: 30px; } .space-arrow.next .space-name { right: 30px; }
.space-arrow:hover .space-name { opacity: 1; transition-delay: .5s; }
.space-arrow:focus-visible .space-name { opacity: 1; }
body.edges-named .space-name { opacity: 1; transition-delay: 0s; }   /* named until learned (nav.js) */
@media (min-width: 861px) { body.edges-named .home:not(.out) { padding-left: 110px; padding-right: 110px; } }   /* room for the names beside home's calendars */
.space-arrow:hover .g-home i, .space-arrow:hover .g-dots i { transform: scale(1.3); }
.space-arrow:hover .g-dots i { transition-delay: 0s; }
/* In the chat the rail already runs down the left edge: it is the way to the dots, as it was. */
.space-nav.in-chat .space-arrow.prev { display: none; }

/* The menu: one dot at the top right of every space; a click opens the menu as a panel under it. */
.corner-menu { position: fixed; z-index: 36; top: 14px; right: calc(6px + var(--edge)); }
.corner-dot { position: relative; z-index: 1; width: 32px; height: 26px; display: grid; place-items: center; margin-left: auto; }
/* One big dot, the size of the tutor's, in the app's own language: the bigger the dot, the more
   behind it. Solid and still (the tutor's breathes), so the two never read as the same thing. */
.corner-dot i { display: block; width: var(--big-dot); height: var(--big-dot); border-radius: 50%; background: var(--ink); transition: transform .3s var(--spring); }
.corner-menu.open .corner-dot i { transform: scale(.82); }
@media (prefers-reduced-motion: reduce) { .corner-dot i { transition: none; } }
.corner-panel { position: absolute; top: 30px; right: 10px; width: 280px; max-height: calc(100vh - 60px); overflow-y: auto; overscroll-behavior: contain;
  padding: 18px 20px 20px; background: var(--bg); border: 1px solid var(--ink); font-size: var(--fs-s);
  opacity: 0; transform: translateY(-6px); pointer-events: none; transition: opacity .2s var(--ease), transform .3s var(--ease); }
.corner-menu.open .corner-panel { opacity: 1; transform: none; pointer-events: auto; }
.corner-panel .mm-list { display: flex; flex-direction: column; gap: 14px; }
.corner-panel .mm-list > button { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; width: 100%; text-align: left; color: var(--ink); }
.corner-panel .mm-list > button b { font-weight: 500; font-size: var(--fs-l); line-height: 1.25; }
.corner-panel .mm-list > button span { font-size: var(--fs-s); line-height: 1.35; color: var(--grey); }
.corner-panel .mm-list > button:hover b, .corner-panel .mm-list > button.on b { text-decoration: underline; text-underline-offset: 3px; }
/* A section open in the panel: the panel widens to a page's width, the section under its name. */
.corner-panel.wide { width: 460px; }
/* One open: the others fold to their names, tight, and the open one shows in full beneath its name. */
.corner-panel.wide .mm-list { gap: 10px; }
.corner-panel.wide .mm-list > button span { display: none; }
.corner-panel .corner-body { margin: -2px 0 4px; padding: 0 0 12px; border-bottom: 1px solid var(--hair); }
.corner-panel .corner-body .page-tabs { margin-bottom: 4px; }
.corner-panel .corner-body .page-body { padding: 0; overflow: visible; }
/* Each edge column starts below the menu dot; on home the right one is a full column of dots, faded while the menu is open. */
.space-arrow.next { transition: opacity .2s var(--ease); }
body:has(.corner-menu.open) .space-arrow.next { opacity: .12; }

/* The dots page: a small red dot beside a hovered concept's dot marks it for review. */
.mark-tip { position: fixed; z-index: 30; width: 18px; height: 18px; display: grid; place-items: center; padding: 0; animation: tip-in .2s var(--ease); }
.mark-tip i { width: 5px; height: 5px; border-radius: 50%; background: var(--bg); box-shadow: inset 0 0 0 1px var(--ink); transition: transform .25s var(--spring); }
.mark-tip.unmark i { background: transparent; box-shadow: inset 0 0 0 1px var(--red); }
.mark-tip:hover i { transform: scale(1.5); }
@keyframes tip-in { from { opacity: 0; transform: translateX(4px); } }

/* From the rail to the dots page: each dot travels with its code; on landing the titles open out
   beside the codes, then headings and the rest fade in. */
.drift-layer { position: fixed; inset: 0; z-index: 25; pointer-events: none; }
.ghost-row { position: fixed; }
.ghost-row .dot { position: absolute; left: 0; top: 0; margin: 0; }
.ghost-code { position: absolute; white-space: nowrap; }
.ghost-row.pointed .ghost-code { color: var(--ink) !important; }
#dots-view:not(.arriving) :is(.ip-head, .ip-tally, .ip-views, .chap-head, .obj-head, .kterms) { transition: opacity .35s var(--ease); }   /* hidden at once, faded back in */
#dots-view.arriving :is(.ip-head, .ip-tally, .ip-views, .chap-head, .obj-head, .kterms) { opacity: 0; }
#dots-view.arriving:not(.landed) .crow :is(.dot, .c-code) { visibility: hidden; }
#dots-view.arriving .crow :is(.c-title, .c-tag) { clip-path: inset(0 100% 0 0); }
#dots-view.landed .crow :is(.c-title, .c-tag) { clip-path: inset(0 0 0 0); transition: clip-path .35s var(--ease); }
.rail.handed { visibility: hidden; }
/* Leaving the dots page for the chat: the words fold away first, then the dots travel. */
#dots-view.leaving :is(.ip-head, .ip-tally, .ip-views, .chap-head, .obj-head, .kterms) { opacity: 0; transition: opacity .14s var(--ease); }
#dots-view.leaving .crow :is(.c-title, .c-tag) { clip-path: inset(0 100% 0 0); transition: clip-path .14s var(--ease); }
#dots-view.gone .crow :is(.dot, .c-code) { visibility: hidden; }
.space-nav.handed .space-arrow.next .glyph { visibility: hidden; }   /* the preview stands in for home's dots column */
/* A click on the rail before the hover opened it: the same preview, faster. */
.study .rail.quick, .study .rail.quick :is(.crow, .chapter-gap) { transition-duration: .18s; }
.study .rail.quick .crow .c-code { transition-delay: .06s; transition-duration: .12s; }
/* The quick version of a space change, for the rail-to-dots move. */
body.zip .space { transition-duration: .32s; }
body.zip #dots-view.landed .crow :is(.c-title, .c-tag) { transition-duration: .14s; }
body.zip #dots-view :is(.ip-head, .ip-tally, .ip-views, .chap-head, .obj-head, .kterms) { transition-duration: .18s; }

/* A concept pointed at from the chat's rail: full ink (white in dark mode) among the grey rows. */
.index-page .crow.pointed, .index-page .crow.pointed :is(.c-code, .c-title, .c-tag) { color: var(--ink); }

/* The dots space: the index, full page. */
.dots-space { padding: var(--pad) calc(var(--pad) * 2) 70px; }
.index-page { max-width: 760px; margin: 0 auto; text-transform: uppercase; }
.ip-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 2rem; }
.ip-head .brand { cursor: pointer; }
/* The wordmark: one size and one place on every page that shows it (home, objectives, about you),
   the top-left corner, at the size of home's division names. */
@media (min-width: 861px) {
  .home-head .brand, .ip-head .brand { position: fixed; z-index: 5; top: var(--pad); left: calc(var(--pad) * 2); font-size: var(--fs-l); line-height: 1.25; text-transform: uppercase; }
  .ip-head { justify-content: flex-start; min-height: 19px; }
  /* The division, at the column's left edge, set like the wordmark; it goes home too. */
  .ip-head .ip-div { font-size: var(--fs-l); line-height: 1.25; font-weight: 500; color: var(--ink); cursor: pointer; }
  .ip-div :is(.sep, .ip-src, span:nth-child(3)) { display: none; }   /* the short name (PjM); the full one on hover */
  .ip-head .ip-div span:first-child { text-transform: none; }   /* a division's code keeps its case: PjM, PcM */
  .ip-head .ip-div:hover span:first-child { display: none; }
  .ip-head .ip-div:hover span:nth-child(3) { display: inline; text-transform: none; }   /* the full name in its own case */
  .home .home-head { min-height: 19px; justify-content: flex-end; }
}
.ip-div { font: inherit; margin: 0; text-transform: uppercase; }
.ip-tally { margin-bottom: 1rem; }

.ip-views { margin-bottom: 1.2rem; }
.ip-list { overflow: visible; padding: 0; }
/* Search, beside Concepts and Terms. */
.index-page[data-view="search"] .ip-list { display: none; }
.ip-search { margin-top: .4rem; text-transform: none; }
#search-q { width: 100%; border: 0; border-bottom: 1px solid var(--ink); background: transparent; color: var(--ink); font: inherit; font-size: var(--fs-s); padding: 6px 0; }
#search-q:focus { outline: none; }
#search-q::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
.search-row > span:last-child { text-align: left; justify-self: start; }
@media (max-width: 860px) { .ip-search .search-row { grid-template-columns: 4.6em 1fr; } }
#search-q::placeholder { color: var(--grey); }
.search-hint { color: var(--grey); font-size: var(--fs-s); margin: 12px 0; }
.search-group { margin: 18px 0 4px; font-weight: 400; font-size: var(--fs-s); color: var(--grey); text-transform: uppercase; }
.search-row { display: grid; grid-template-columns: 7em 1fr; column-gap: 10px; width: 100%; text-align: left; padding: 6px 0; border-top: 1px solid var(--hair); font-size: var(--fs-s); line-height: 1.3; color: var(--ink); text-transform: none; }
.search-row:hover { background: var(--hover); }
.search-row b { font-weight: 500; }
.search-code { font-size: var(--fs-s); color: var(--grey); padding-top: 3px; text-transform: uppercase; }
.search-brief { font-size: var(--fs-s); color: var(--grey); }
.search-ask { margin-top: 14px; }

/* ---------- home: every division as a field of dots ---------- */
.home { position: relative; min-height: 100%; display: flex; flex-direction: column; padding: var(--pad) calc(var(--pad) * 2) 18px; }
.home-head { display: flex; justify-content: space-between; align-items: baseline; text-transform: uppercase; }
/* Every division is one column, always side by side, never wrapped into a second row. Its dots sit
   on one square lattice (8 px dots, 21 px apart); as the window narrows each column holds fewer dots
   across and grows taller (--per, from 8 down to 3, set in home.js), so at least 40 px stays
   between neighbours. */
.home-grids { --per: 8; display: flex; justify-content: space-between; align-items: flex-start; gap: 40px;
  width: 100%; max-width: 1180px; margin: 0 auto; }
.exam { display: flex; flex-direction: column; gap: 18px; width: calc(var(--per) * 21px - 13px); text-align: left; }
/* One line: the abbreviation. On hover the full name takes its place, growing upward from that line
   so the dots below never move. */
.exam-head { position: relative; display: block; height: 1.25em; font-size: var(--fs-l); line-height: 1.25; }
.exam-name { position: absolute; z-index: 1; left: 0; bottom: 0; width: max-content; max-width: 9em; padding-right: 8px; background: var(--bg);
  font-weight: 500; opacity: 0; transition: opacity .2s var(--ease); pointer-events: none; }   /* wider than a narrow column: it sits over the neighbour while hovered */
.exam-head b { transition: opacity .2s var(--ease); }
.exam:hover .exam-name, .exam:focus-visible .exam-name { opacity: 1; }
.exam:hover .exam-head b, .exam:focus-visible .exam-head b { opacity: 0; }
.exam-head b { font-weight: 500; font-size: var(--fs-l); }
.exam-grid { display: grid; grid-template-columns: repeat(var(--per), 8px); gap: 13px; width: 100%; }
.exam:hover .exam-name { text-decoration: underline; text-underline-offset: 3px; }
.dot.hdot { width: 8px; height: 8px; will-change: transform; }
.hdot.ph { background: var(--k4); }                       /* a division not written yet */
:root[data-dots="star"] .dot.hdot.done { width: 13px; height: 13px; margin: -2.5px; }
/* Signed out, as plain as an architect's studio page: one centred line a quarter of the way down,
   and further down, centred, the way in. Nothing else but the wordmark and the fine print. */
#home-view.home.out div.home-top { margin: max(3rem, 24vh) auto 0; text-align: center; }
.home-head .brand { font-size: var(--fs-l); }
.landing { margin: 0 auto; max-width: 30em; font-size: var(--fs-l); line-height: 1.4; color: var(--ink); text-transform: none; }
.landing-sub { display: block; color: var(--grey); }
.home.out .auth-modes { display: none; }   /* Sign up / Sign in choose instead */
.landing-acts { margin-top: 9vh; display: flex; justify-content: center; align-items: baseline; gap: 14px; font-size: var(--fs-l); }
.landing-acts .sep { color: var(--grey); }
.landing-acts .text-btn { color: var(--ink); text-transform: none; }
.landing-acts .text-btn.on { text-decoration: underline; text-underline-offset: 4px; }
.home.out .auth-box { margin-top: 2.4rem; text-align: left; }
.welcome-acts { margin-top: 1.2rem; font-size: var(--fs-s); }
/* Which exam: the six names as choices in the conversation, at its own size. */
.exam-opts { display: flex; flex-wrap: wrap; gap: 10px 24px; margin-top: 1rem; }
.exam-opts button { padding: 0; color: var(--ink); font-weight: 500; }
.exam-opts button:hover, .exam-opts button:focus-visible { text-decoration: underline; text-underline-offset: 3px; }
.home-fine { margin: auto 0 0; padding-top: 3.5rem; text-align: center; font-size: var(--fs-s); letter-spacing: .02em; color: var(--grey); text-transform: uppercase; }
/* The box at the top: what this is, and (signed out) the sign-in, its fields side by side. */
.home-top { width: min(640px, 100%); margin: 4.5rem auto 4rem; }
#home-view .home-top:not(:has(.auth-box:not([hidden]))) { margin: max(3rem, 30vh) auto 0; }   /* signed in: the calendars start at eye level, about a third down */
.home-lede { font-size: var(--fs-l); line-height: 1.35; margin: 0 0 1.6rem; }
.auth-box .form { display: grid; grid-template-columns: 1fr 1fr; gap: 0 24px; }
.auth-box label { margin-bottom: .9rem; font-size: var(--fs-s); max-width: none; }
.auth-box input { font-size: var(--fs-s); }
.auth-box .error, .auth-box .actions, .auth-box .google-row, .auth-modes { grid-column: 1 / -1; }
.auth-modes { display: flex; gap: 22px; margin-bottom: 1.4rem; font-size: var(--fs-l); }
.auth-modes .text-btn { color: var(--grey); text-transform: none; }
.auth-modes .text-btn.on { color: var(--ink); text-decoration: underline; text-underline-offset: 4px; }
.auth-box .actions { display: flex; flex-wrap: wrap; gap: 6px 18px; margin-top: .2rem; }
/* The first-run questions: the same page as home, the same box and fields as the sign-in. */
.onboard-form { display: grid; grid-template-columns: 1fr 1fr; gap: 0 24px; align-items: start; }
.onboard-form .home-lede, .onboard-form .wide, .onboard-form .error, .onboard-form .actions { grid-column: 1 / -1; }
.onboard-form label, .onboard-form .choices legend { margin-bottom: .9rem; font-size: var(--fs-s); max-width: none; }
.onboard-form :is(input, select, textarea) { font-size: var(--fs-s); }
.onboard-form :is(input, select) { height: 30px; }
.onboard-form .choices legend { padding: 0; }
.onboard-form .choices { margin-bottom: .9rem; }
.onboard-form .choices label { font-size: var(--fs-s); margin-bottom: 0; gap: 8px; }
.onboard-form input[type="radio"] { height: 7px; }
.onboard-form .actions { margin-top: .6rem; }
/* Choices as dots: a ring, filled once picked. */
.choices input[type="radio"] { appearance: none; -webkit-appearance: none; display: inline-block; flex: none; width: 7px; height: 7px; padding: 0; margin: 0; border: 0; border-radius: 50%;
  box-shadow: inset 0 0 0 1px var(--ink); cursor: pointer; transition: transform .3s var(--spring), background .2s var(--ease); }
.choices input[type="radio"]:checked { background: var(--ink); }
.choices label:hover input[type="radio"] { transform: scale(1.3); }
.auth-box.nudge { animation: nudge .45s var(--spring); }
@keyframes nudge { 30% { transform: translateX(-6px); } 60% { transform: translateX(4px); } }
@media (max-width: 860px) {
  .space-nav { display: none; }                      /* on a phone, a sideways swipe moves between spaces */
  .home { padding: var(--pad) var(--pad) 40px; }
  .home-top { margin: 1.6rem 0 2.6rem; }
  #home-view .home-top:not(:has(.auth-box:not([hidden]))) { margin: 1.6rem 0 0; }
  .home-lede { display: none; }                          /* on a phone the top box is just the sign-in */
  .onboard .home-lede { display: block; }
  .onboard-form { grid-template-columns: 1fr; }
  .auth-box .form { grid-template-columns: 1fr 1fr; gap: 0 16px; }
  /* Always the thin columns, as Home's dots on a phone (.mm-dots): every division side by side,
     three dots wide, days running down then across, the division's code at the foot. */
  .home-grids { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
  .exam { display: flex; flex-direction: column-reverse; align-items: center; gap: 12px; width: auto; }
  .exam-head { height: auto; }
  .exam-head b { font-weight: 400; font-size: var(--fs-s); color: var(--grey); letter-spacing: .02em; }
  .exam-name, .exam:hover .exam-name { display: none; }
  .exam:hover .exam-head b { opacity: 1; }
  .exam-grid { display: grid; width: auto; max-width: none; grid-template-columns: repeat(3, 12px); grid-template-rows: repeat(var(--rows), 12px);
    grid-auto-flow: column; place-items: center; gap: 0; }
  .dot.hdot { width: 7px; height: 7px; }
  :root[data-dots="star"] .dot.hdot.done { width: 12px; height: 12px; }
}

/* ---------- the dot ----------
   Solid is not yet covered. While you work on it, a light ring; once accomplished, a gold star.
   Red fill: marked for review (or missed). Red ring: understood, due again. */
.dot { position: relative; flex: none; display: inline-block; width: var(--dot); height: var(--dot); border-radius: 50%;
  background: var(--k0); transition: background-color 1.2s var(--ease), box-shadow 1.2s var(--ease); }
.dot.k0 { background: var(--k0); }
.dot.k1, .dot.k2 { background: transparent; box-shadow: inset 0 0 0 1px var(--k2); }
.dot.k3, .dot.k4 { background: transparent; box-shadow: inset 0 0 0 1px var(--k4); }
.dot.r-fill { background: var(--red); box-shadow: none; }
.dot.r-stroke { background: transparent; box-shadow: inset 0 0 0 1px var(--red); }
/* Where you are: a slow breath, quicker while the tutor is thinking. */
.dot.active { animation: breathe 3.2s var(--ease) infinite; }
.thinking .dot.active { animation-duration: 1.1s; }
@keyframes breathe { 0%, 100% { transform: scale(1); opacity: 1; } 50% { transform: scale(1.4); opacity: .4; } }
/* Accomplished: a small gold star. */
:root[data-dots="star"] .dot.done, :root[data-dots="star"] .kdot.done {
  background: var(--gold); box-shadow: none; border-radius: 0;
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); }
:root[data-dots="star"] .dot.done { width: calc(var(--dot) + 5px); height: calc(var(--dot) + 5px); margin: -2.5px; }
/* In the edge column the dots are spaced by their margins (15 px a row): a star keeps that pitch. */
:root[data-dots="star"] .g-dots i.dot.done { margin: calc((15px - var(--dot) - 5px) / 2) -2.5px; }
:root[data-dots="star"] .kdot.done { width: 7px; height: 7px; margin: -2px; }
/* A dot that just changed eases into its new state once. */
/* A dot that changes just changes: no pulse. */
/* First-run tutorial: a few quiet lines, while the tree ripples once to show where it is. */
.tour .tour-step { display: flex; gap: 7px; margin-bottom: 2.4rem; }
.turn.tutor h2.tour-title { font-size: var(--fs-l); line-height: 1.1; letter-spacing: -.015em; text-transform: none; color: var(--ink); margin: 0 0 1rem; }
.tour p { max-width: 34em; }
.tour-actions { display: flex; gap: 1.6rem; margin-top: 2.4rem; font-size: var(--small); text-transform: uppercase; }
.tour-next { text-decoration: underline; text-underline-offset: 2px; }
.tour-skip, .tour-actions [data-tour="back"] { color: var(--grey); }
.tour-tree .rail .dot { animation: tour-wave 1.8s var(--ease) both 2; animation-delay: calc(var(--i, 0) * 12ms); }
@keyframes tour-wave { 0%, 100% { transform: scale(1); } 40% { transform: scale(1.9); } }
.dot.enter { animation: dot-in .9s var(--ease) both; animation-delay: calc(var(--i, 0) * 5ms); }
@keyframes dot-in { from { opacity: 0; } to { opacity: 1; } }

/* A star earned: small, gold, rises a little and goes. */
.earned { position: fixed; z-index: 60; left: var(--x); top: var(--y); width: 14px; height: 14px; margin: -7px 0 0 -7px; pointer-events: none;
  background: var(--gold); clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
  animation: earned 1.6s var(--ease) forwards; }
@keyframes earned { 0% { opacity: 0; transform: scale(.3) rotate(-40deg); } 25% { opacity: 1; transform: scale(1.15) rotate(0); }
  45% { transform: scale(1); } 100% { opacity: 0; transform: translateY(-22px) scale(.9); } }
@media (prefers-reduced-motion: reduce) { .earned { animation-duration: .8s; } }
.disco-ball { display: block; margin: 8px auto 20px; }

/* ---------- the conversation ---------- */
.page { display: flex; flex-direction: column; height: 100%; min-width: 0; min-height: 0; padding-left: 84px; }
.thread { flex: 1; min-height: 0; overflow-y: auto; padding: 4.5rem var(--pad) 3rem 0; }
.thread > * { max-width: var(--measure); margin-inline: auto; }   /* a centred column, text still flush left */
.conversation { font-size: var(--fs-l); line-height: 1.4; letter-spacing: 0; }
.conversation::after { content: ""; display: block; height: 55vh; }
.intro { font-size: var(--small); text-transform: uppercase; color: var(--grey); max-width: 420px; letter-spacing: .01em; }
.turn { margin-bottom: 2.4rem; transition: color .3s var(--ease); }
/* Earlier turns step back to the one grey used everywhere (not a fainter, see-through grey). */
.turn:not(.recent), .turn:not(.recent) :is(h2, h3, b, strong, em, code, li) { color: var(--grey); }
.turn:not(.recent):hover, .turn:not(.recent):hover :is(h2, h3, b, strong, em, code, li) { color: var(--ink); }
.turn.learner:not(.recent):hover { color: var(--grey); }
.turn.new { animation: fade .35s var(--ease) both; }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }
.turn.learner { color: var(--grey); white-space: pre-wrap; }
.turn.learner::before { content: "YOU  "; font-size: var(--small); color: var(--ink); white-space: pre; letter-spacing: .01em; }
.turn.tutor p { margin-bottom: .85em; }
.turn.tutor p:last-child, .turn.tutor ul:last-child, .turn.tutor ol:last-child { margin-bottom: 0; }
.turn.tutor h2, .turn.tutor h3, .turn.tutor h4 { font-size: var(--small); font-weight: 400; text-transform: uppercase; letter-spacing: .01em; line-height: var(--lead); margin: 2.4rem 0 .9rem; }
.turn.tutor > :first-child { margin-top: 0; }
.turn.tutor h2 { color: var(--grey); }
.turn.tutor h3 { display: flex; align-items: center; gap: 8px; padding-top: 8px; border-top: 1px solid var(--hair); }
.turn.tutor strong { font-weight: 500; }
.turn.tutor ul, .turn.tutor ol { margin: 0 0 .85em; padding-left: 1.2em; }
.turn.tutor li { margin-bottom: .3em; }
.turn.tutor li::marker { color: var(--grey); }
.turn.tutor code { font-size: inherit; background: var(--hover); padding: 0 .25em; }
.turn.tutor .choice { margin: 0 0 .45em; padding-left: 1.6em; text-indent: -1.6em; }
.turn.tutor .choice b { font-weight: 400; color: var(--grey); display: inline-block; width: 1.6em; text-indent: 0; }
.past-note { text-transform: uppercase; color: var(--grey); margin-bottom: 2rem; font-size: var(--small); }
.typing { display: inline-flex; gap: 5px; padding: .5em 0; }
.typing i { width: 6px; height: 6px; border-radius: 50%; background: var(--ink); animation: blink 1s steps(2, jump-none) infinite; }
.typing i:nth-child(2) { animation-delay: .2s; } .typing i:nth-child(3) { animation-delay: .4s; }

.dock { padding: 14px var(--pad) 40px 0; }   /* room under the answer box */
.dock > * { max-width: var(--measure); margin-inline: auto; }
/* The answer box: a card, the answer on top and the dots and SEND under it, on every screen. */
.composer { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 6px 1rem; border: 1px solid var(--hair); border-radius: 18px; padding: 12px 14px 8px; }
.composer textarea { flex: 1 1 100%; background: transparent; border: 0; resize: none; font-size: var(--fs-l); line-height: 1.4; letter-spacing: 0; color: var(--ink); padding: 0; max-height: 40vh; }
.composer textarea::placeholder { color: var(--grey); }
.composer textarea:focus { outline: none; }
.send { color: var(--grey); padding-bottom: 3px; }
/* The key that sends, beside SEND on a computer: Return. */
.send-key { margin-left: 8px; color: var(--grey); text-decoration: none; display: inline-block; }
@media (max-width: 860px) { .send-key { display: none; } }
/* The tools above the answer box; beside SEND, the review mark, its word on hover. */
.dock-bar { display: flex; align-items: center; justify-content: space-between; min-height: 15px; margin-bottom: 4px; }
.tools { display: flex; gap: 1rem; margin-left: auto; font-size: var(--fs-s); letter-spacing: .02em; }
.tools .text-btn { color: var(--grey); }
.tools .text-btn:hover { color: var(--ink); text-decoration: none; }
.tools .text-btn.on { color: var(--ink); }   /* its window is open */
.tools .short { display: none; }
.answer-tools { position: relative; display: flex; align-items: flex-end; gap: 14px; flex-shrink: 0; }
.composer .answer-tools { flex-basis: 100%; justify-content: flex-end; align-items: center; min-height: 26px; }
.tool-label { margin-right: auto; font-size: var(--fs-s); letter-spacing: .02em; color: var(--ink); white-space: pre; opacity: 0; transition: opacity .15s var(--ease); pointer-events: none; }
.tool-label.on { opacity: 1; }
.tool-label.red { color: var(--red); }

/* Pop-up tools: small framed windows you can drag, like the exam's. */
.popup { position: fixed; z-index: 40; width: 300px; background: var(--bg); color: var(--ink); border: 1px solid var(--rule); font-size: var(--small); }
.popup[hidden] { display: none; }
.popup-head { display: flex; justify-content: space-between; padding: 8px 10px; border-bottom: 1px solid var(--rule); text-transform: uppercase; cursor: move; user-select: none; touch-action: none; }
.popup-body { padding: 10px; max-height: 70vh; overflow-y: auto; }
.popup h4 { font-weight: 400; text-transform: uppercase; color: var(--grey); margin: .9rem 0 .3rem; font-size: var(--small); }
.popup h4:first-child { margin-top: 0; }
#calc { width: 280px; } #calc:focus { outline: none; }
.calc-screen { border-bottom: 1px solid var(--hair); padding: 4px 0 8px; text-align: right; }
.calc-expr { color: var(--grey); min-height: 1.2em; overflow-wrap: anywhere; }
.calc-out { font-size: var(--fs-s); letter-spacing: -.01em; overflow-wrap: anywhere; }
.calc-keys { display: grid; grid-template-columns: repeat(5, 1fr); gap: 1px; background: var(--hair); border: 1px solid var(--hair); margin: 10px 0; }
.key { text-align: center; background: var(--bg); height: 34px; font-size: var(--fs-s); color: var(--grey); }
.key.num { color: var(--ink); } .key.eq { background: var(--ink); color: var(--bg); }
.key:hover { background: var(--hover); } .key.eq:hover { background: var(--ink); opacity: .85; }
.calc-list { max-height: 96px; overflow-y: auto; }
.calc-item { display: block; width: 100%; text-align: right; padding: 2px 0; color: var(--ink); font-size: var(--fs-s); }
.calc-item:hover { background: var(--hover); }
#board { width: 600px; }
.board-bar { display: flex; gap: .9rem; margin-bottom: 8px; }
.board-bar .tool { color: var(--grey); } .board-bar .tool.on { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }
.board-gap { flex: 1; }
.board-wrap { position: relative; }
.board-canvas { display: block; width: 100%; aspect-ratio: 1120 / 760; border: 1px solid var(--hair); touch-action: none; cursor: crosshair; }
.board-canvas.texting { cursor: text; }
.board-input { position: absolute; transform: translateY(-2px); min-width: 8em; background: transparent; border: 0; border-bottom: 1px dashed var(--grey); padding: 0; font-family: var(--font); line-height: 1; outline: none; }
.swatches { display: flex; gap: 2px; margin-left: .4rem; }
.swatch { width: 16px; height: 16px; padding: 0; display: grid; place-items: center; }
.swatch::before { content: ""; width: 8px; height: 8px; border-radius: 50%; }
.swatch.on::before { box-shadow: 0 0 0 2px var(--bg), 0 0 0 3px var(--ink); }
.sw-ink::before { background: var(--ink); } .sw-red::before { background: var(--red); }
.sw-blue::before { background: #2f6bff; } .sw-grey::before { background: #8a8a8a; }
#pad { width: 340px; }
.board-hint { margin: 6px 0 0; }
#ref { width: 420px; }
.ref-row { display: grid; grid-template-columns: 9.5em 1fr; gap: .8em; padding: 4px 0; border-top: 1px solid var(--hair); font-size: var(--fs-s); line-height: 1.3; }
.ref-row span:first-child { color: var(--grey); }
.ref-note { margin-top: 1rem; }
.memo-edit textarea, .inline-confirm input, .note-form textarea { width: 100%; box-sizing: border-box; border: 0; border-bottom: 1px solid var(--hair); background: transparent; color: var(--ink); font: var(--fs-s)/1.35 var(--font); resize: vertical; padding: .5rem 0; margin-top: 1rem; }
.memo-edit textarea:focus, .inline-confirm input:focus, .note-form textarea:focus { outline: none; border-bottom-color: var(--ink); }
.note-bar { display: flex; justify-content: space-between; margin: .4rem 0 1.2rem; }
.memo-meta { font-size: var(--small); text-transform: uppercase; margin-bottom: .2rem; }
.page-body a { color: inherit; }
.composer.ready .send { color: var(--ink); text-decoration: underline; text-underline-offset: 2px; }

/* ---------- pinned tools, highlights ---------- */
/* A pinned tool floats in the margin beside its question and scrolls with it; it takes no room in
   the conversation. Several pinned to one question stack. Too narrow for a margin: they sit in line. */
#conversation { position: relative; }
.aside-stack { position: absolute; left: calc(100% + 28px); width: min(320px, calc((100vw - 100%) / 2 - 160px));   /* clear of the menu at the right edge */
  display: flex; flex-direction: column; gap: 14px; }
.aside-stack:empty { display: none; }
.popup.docked { position: static !important; left: auto !important; top: auto !important; right: auto !important; bottom: auto !important;
  width: 100% !important; z-index: auto !important; }
.popup.docked .popup-head { cursor: ns-resize; }
.popup.docked .popup-close { display: none; }                 /* UNPIN, or drag it down */
.popup.docked .popup-body { max-height: 60vh; }
.popup-acts { display: flex; gap: 12px; }
.popup-pin[aria-pressed="true"] { text-decoration: underline; text-underline-offset: 2px; }
/* What it held when the next question came: frozen beside the old one. UNPIN, or drag it down. */
.pinned-snap { border: 1px solid var(--hair); background: var(--bg); font-size: var(--small); }
.snap-head { display: flex; justify-content: space-between; padding: 6px 10px; border-bottom: 1px solid var(--hair); color: var(--grey); text-transform: uppercase; cursor: ns-resize; touch-action: none; user-select: none; }
.snap-body { padding: 8px 10px; max-height: 320px; overflow: auto; }
.snap-board { display: block; width: 100%; height: auto; }
.snap-body .calc-item { display: block; padding: 1px 0; }
@media (max-width: 1180px) {
  .aside-stack { position: static; width: auto; margin: 1.2rem 0; }
}
/* Highlights: select text in a question; a small bar offers HIGHLIGHT and ANNOTATE. */
mark.hl { background: var(--mark); color: inherit; border-radius: 2px; cursor: pointer; }
mark.hl.noted { text-decoration: underline dotted; text-underline-offset: 3px; cursor: pointer; }
.hl-bar { position: fixed; z-index: 60; background: var(--bg); border: 1px solid var(--rule); display: flex; gap: 12px; padding: 5px 10px; }
@media (pointer: coarse) { .hl-bar { gap: 22px; padding: 10px 16px; font-size: var(--fs-s); } }   /* big enough to tap */
/* An annotation: a note card pinned in the margin beside its message, like a pinned tool. */
.note-text { margin: 0; font-size: var(--fs-s); line-height: 1.35; color: var(--ink); text-transform: none; }
.tutor-note, .cast-note { border-color: var(--hair); }
.hl-by { display: block; font-size: var(--fs-s); color: var(--grey); margin-bottom: 2px; }
/* Diagrams from the tutor: names in hairline pills, contracts as solid lines, duties dashed. */
.diagram { margin: 1.2rem 0; }
.dg { display: block; width: 100%; max-width: 560px; height: auto; overflow: visible; }
.dg-contract { stroke: var(--ink); stroke-width: 1.2; }
.dg-duty { stroke: var(--grey); stroke-width: 1.2; stroke-dasharray: 4 4; fill: none; }
.dg path.dg-contract { fill: none; }
.dg-node { fill: var(--bg); stroke: var(--ink); stroke-width: 1; }
.dg-arrow { fill: var(--ink); }
/* A star earned, handed over in one line of the conversation. */
.turn.star-line { display: flex; align-items: center; gap: 10px; }
.star-mark { flex: none; width: 13px; height: 13px; background: var(--gold);
  clip-path: polygon(50% 0, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%); }
.dg-gap { fill: var(--bg); }
.dg-name { fill: var(--ink); font: 500 15px var(--font); text-anchor: middle; }
.dg-label { fill: var(--grey); font: 400 11px var(--font); text-anchor: middle; text-transform: uppercase; letter-spacing: .02em; }
.note-card { border: 1px solid var(--rule); background: var(--bg); font-size: var(--small); animation: card-in .35s var(--ease); }
.aside-stack > .note-card.aligned { position: absolute; left: 0; right: 0; transition: top .3s var(--ease); }
@keyframes card-in { from { opacity: 0; transform: translateY(-4px); } }
.note-head { display: flex; justify-content: space-between; align-items: center; padding: 6px 10px; border-bottom: 1px solid var(--hair); text-transform: uppercase; }
.note-x { min-width: 1.4em; text-align: right; color: var(--grey); }
.note-x:hover, .hl-x:hover { color: var(--ink); }
.note-x.armed, .hl-x.armed { color: var(--red); }
.note-body { padding: 8px 10px; }
.note-quote { margin: 0 0 6px; text-transform: none; }
.note-body textarea { display: block; width: 100%; box-sizing: border-box; border: 0; background: transparent; color: var(--ink); font: var(--fs-s)/1.35 var(--font); resize: vertical; padding: 0; }
.note-body textarea:focus { outline: none; }
/* NOTES → HIGHLIGHTS: every passage, its note under it. */
.hl-row { display: flex; gap: 10px; align-items: flex-start; padding: 8px 0; border-bottom: 1px solid var(--hair); }
.hl-open { flex: 1; text-align: left; text-transform: none; font-size: var(--fs-s); line-height: 1.35; color: var(--ink); }
.hl-open[data-goto]:hover mark { text-decoration: underline; }
.hl-note { display: block; margin-top: 4px; color: var(--grey); font-size: var(--small); }
.hl-x { color: var(--grey); flex: none; }
/* The menu, opened for a moment after an annotation: Notes stands out, the rest step back. */
.corner-menu.hint-notes .mm-list > button:not([data-page="page-notes:notes"]) b { color: var(--grey); }

/* ---------- the menu pages (sessions, notes, settings) ---------- */
.page-body { padding: 0 var(--pad) var(--pad); overflow-y: auto; }
.page-body h3 { font-size: var(--small); font-weight: 400; text-transform: uppercase; color: var(--grey); margin: 1.6rem 0 .4rem; }
.page-body p, .page-body label { text-transform: uppercase; }
.page-body label { display: block; color: var(--grey); margin: 1rem 0; }
.page-body select { display: block; margin-top: .3rem; background: transparent; border: 0; border-bottom: 1px solid var(--hair); padding: .2rem 0; text-transform: uppercase; }
.memo { font-size: var(--fs-s); line-height: 1.3; border-top: 1px solid var(--hair); padding: .6rem 0; }
.memo.done { color: var(--grey); text-decoration: line-through; }
.memo-actions { font-size: var(--small); text-transform: uppercase; display: flex; gap: 1rem; margin-top: .35rem; }
.session-row { display: block; width: 100%; text-align: left; padding: 4px 0; border-bottom: 1px solid var(--hair); text-transform: uppercase; }
.page-body h3.session-day { margin: 1.1rem 0 .2rem; }   /* sessions grouped by day */
.session-review { display: block; margin-top: 2px; color: var(--grey); text-transform: none; }
.page-body h3.session-day:first-child { margin-top: .2rem; }
.session-row:hover { background: var(--hover); }
.drawer-action { margin-top: 1.2rem; }
.memo-edit textarea { margin-top: 0; font-size: var(--fs-s); }
.inline-confirm { margin: 1rem 0; }
.inline-confirm input { margin-top: 0; text-transform: none; }
.undo-line { margin: .8rem 0; }

/* ---------- phone ---------- */
.google-row { margin-top: 1.4rem; }
@media (max-width: 860px) {
  .tools .full { display: none; } .tools .short { display: inline; }
  .popup-head { cursor: default; }
  .thread { padding-top: 1.4rem; }
}

/* ---------- phone: a bar on top, a full-screen menu, larger type, a Claude-like composer, and
   tools in a sheet that pushes the conversation up instead of covering it ---------- */
@media (min-width: 861px) { #mbar, #mmenu, #sheet, .phone-only { display: none !important; } }
@media (max-width: 860px) {
  :root { --small: 14px; --fs-l: 19px; }   /* typed fields at 14 px: on an iPhone, index.html stops the zoom that would follow */
  :root[data-size="large"] { --small: 17px; --fs-l: 23px; }
  .corner-menu, .study .rail { display: none !important; }
  /* The bar: words and dots, always there. */
  .mbar { position: fixed; z-index: 46; top: 0; left: 0; right: 0; height: 52px; display: flex; justify-content: space-between; align-items: center;
    padding: 0 16px; background: var(--bg); }
  .mbar-btn { display: flex; align-items: center; gap: 10px; min-height: 44px; font-size: var(--fs-l); color: var(--grey); transition: color .2s var(--ease); -webkit-tap-highlight-color: transparent; }
  .mbar-btn.here { color: var(--ink); }                                  /* where you are */
  .mbar-btn .glyph i { background: currentColor; }
  .mbar-disco { font-weight: 500; letter-spacing: .01em; }
  #mbar-home { position: absolute; left: 50%; transform: translateX(-50%); }   /* the name: always the centre */
  .mbar-btn[hidden] { display: none; }
  .mbar .glyph { flex: none; flex-direction: row; gap: 4px; }
  .mbar .glyph i { width: 6px; height: 6px; }
  .mbar .g-chat i { width: 10px; height: 10px; }
  .popup.menu-page { z-index: 47 !important; }   /* pages open over Home and leave it there */
  /* Typed fields at the small size, like the header above them (the iPhone zoom is stopped in index.html). */
  :is(input:not([type="radio"]):not([type="checkbox"]), select, textarea) { font-size: var(--fs-s) !important; }
  #composer textarea { font-size: var(--fs-l) !important; }
  /* The menu: a full-screen list, like a phone site's. */
  .mmenu { position: fixed; z-index: 45; inset: 0; overflow-y: auto; background: var(--bg); padding: 76px 16px 48px; }
  .mm-list { display: flex; flex-direction: column; gap: 26px; }
  .mm-list button { display: flex; flex-direction: column; align-items: flex-start; gap: 4px; width: 100%; text-align: left; color: var(--ink); }
  .mm-list b { font-weight: 500; font-size: var(--fs-l); line-height: 1.25; }
  .mm-list span { font-size: var(--fs-s); line-height: 1.35; color: var(--grey); }
  /* Home on a phone: the name at the top; a tap fades the list out and each division's dots in. */
  .mm-list { transition: opacity .15s var(--ease); }
  .mmenu.dots .mm-list { opacity: 0; pointer-events: none; position: absolute; left: 16px; right: 16px; }
  .mm-dots { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; padding-bottom: 72px; }
  .mmd { display: flex; flex-direction: column; align-items: center; gap: 12px; padding: 0; transition: transform .2s var(--spring); }
  .mmd:active, .mmd.picked { transform: scale(.94); }
  .mmd b { font-weight: 400; font-size: var(--fs-s); color: var(--grey); letter-spacing: .02em; }
  .mmd-grid { display: grid; grid-template-rows: repeat(var(--rows), 12px); grid-template-columns: repeat(var(--cols), 12px); grid-auto-flow: column; place-items: center; }
  .mm-dots .dot.hdot { width: 7px; height: 7px; }
  .mm-dots .mmd { animation: mmd-in .25s var(--ease) backwards; animation-delay: var(--d, 0ms); }
  :root[data-dots="star"] .mm-dots .dot.hdot.done { width: 12px; height: 12px; margin: 0; }
  @keyframes mmd-in { from { opacity: 0; } }
  @media (prefers-reduced-motion: reduce) { .mm-dots .mmd { animation: none; } .mm-list { transition: none; } }
  /* Light and dark: a dot in the corner, ink while light, white while dark. */
  .mm-theme { position: fixed; left: 4px; bottom: 4px; width: 44px; height: 44px; padding: 0; display: grid; place-items: center; }
  .mmenu::after { content: ""; position: fixed; left: 0; right: 0; bottom: 0; height: 52px; background: var(--bg); pointer-events: none; }   /* the list scrolls under a quiet strip, as under the bar */
  .mm-theme { z-index: 1; }
  .mm-theme i { position: relative; }
  .mm-theme i { width: 12px; height: 12px; border-radius: 50%; background: var(--ink); }
  /* Every space clears the bar. */
  .page { padding-left: 0; padding-top: 52px; }
  .thread { padding: 1.2rem 16px 1.6rem; }
  body:has(#mbar:not([hidden])) .home-head { display: none; }
  body:has(#mbar:not([hidden])) .home { padding-top: 64px; }
  /* The dots page, at phone sizes; titles wrap instead of being cut off. */
  .dots-space { padding: 64px 16px 64px; }
  /* Two sizes only: 17 px for names (the division, phases, objectives, concepts, terms, the views)
     and 13 px for details (codes, counts, the tally, statuses). Black is a name; grey is a detail
     or a choice not taken. Each phase folds under its heading. */
  #dots-view .index-page { text-transform: none; }
  #dots-view .ip-head, #dots-view .ip-tally { display: none; }
  /* The divisions as rows: a tap on PjM opens or closes its index; the rest wait in grey. */
  /* One left line for everything after a code (PDD, 1, 1A, a dot): names start there whatever the code's width. */
  #dots-view { --code-col: 50px; }
  :root[data-size="large"] #dots-view { --code-col: 66px; }   /* the codes are wider at the large size */
  #dots-view .div-row { display: grid; grid-template-columns: var(--code-col) 1fr auto; align-items: baseline; column-gap: 0; width: 100%; text-align: left;
    padding: 18px 0; border-bottom: 1px solid var(--hair); font-size: var(--fs-l); line-height: 1.3; color: var(--ink); }
  #dots-view .div-row b { font-weight: 500; }
  #dots-view .div-row .div-count { font-size: var(--fs-s); color: var(--grey); }
  #dots-view .index-page.shut .ip-body { display: none; }
  #dots-view .ip-body { padding-bottom: 12px; }
  #dots-view .ip-head { margin-bottom: 0; }
  #dots-view .ip-head .brand, #dots-view .ip-div :is(.sep, .ip-src, span:nth-child(3)) { display: none; }
  #dots-view .ip-div { text-transform: none; color: var(--ink); font-size: var(--fs-l); font-weight: 500; line-height: 1.3; }
  #dots-view .ip-tally { font-size: var(--fs-s); margin-top: 6px; }
  #dots-view .ip-views { font-size: var(--fs-l); gap: 22px; margin: 18px 0 4px; }
  #dots-view .index-page .ip-list { text-transform: none; }
  #dots-view .index-page .chapter-gap { height: 0; }
  #dots-view .index-page .chap-head { display: grid; grid-template-columns: var(--code-col) minmax(0, 1fr) auto; column-gap: 0; align-items: baseline; max-height: none; height: auto; padding: 22px 0 10px;
    font-size: var(--fs-l); font-weight: 500; line-height: 1.3; color: var(--ink); border-bottom: 1px solid var(--hair); cursor: pointer; }
  #dots-view .index-page .chap-head > :first-child { display: none; }
  #dots-view .index-page .chap-head > .ch-split { display: contents; }
  #dots-view .index-page .chap-head .ch-split i { font-style: normal; }
  #dots-view .index-page .chap-head .count { font-size: var(--fs-s); font-weight: 400; color: var(--grey); }
  #dots-view .index-page .chap-head .count::after { content: "  −"; }
  #dots-view .index-page .chap.shut .chap-head .count::after { content: "  +"; }
  #dots-view .index-page .chap.shut .chap-body { display: none; }
  #dots-view .index-page .obj-head { display: grid; grid-template-columns: var(--code-col) minmax(0, 1fr) auto; column-gap: 0; align-items: baseline; max-height: none;
    padding: 18px 0 4px; font-size: var(--fs-l); line-height: 1.3; font-weight: 500; color: var(--ink); }
  #dots-view .index-page .obj-head > span:first-child { grid-column: auto; font-size: var(--fs-s); font-weight: 400; color: var(--grey); }
  #dots-view .index-page .obj-head .t { white-space: normal; overflow: visible; }
  #dots-view .index-page .obj-head .count { font-size: var(--fs-s); font-weight: 400; color: var(--grey); }
  #dots-view .index-page .crow { display: grid; grid-template-columns: var(--code-col) auto minmax(0, 1fr); grid-template-rows: auto auto; column-gap: 0; row-gap: 2px;
    height: auto; padding: 8px 0; align-items: center; color: var(--ink); }
  #dots-view .index-page .crow .dot { grid-row: 1 / 3; justify-self: start; }
  #dots-view .index-page .crow .c-code { grid-column: 2; font-size: var(--fs-s); color: var(--grey); }
  #dots-view .index-page .crow .c-tag { grid-column: 3; justify-self: start; margin-left: 10px; font-size: var(--fs-s); color: var(--grey); }
  #dots-view .index-page .crow .c-title { grid-column: 2 / 4; grid-row: 2; font-size: var(--fs-l); line-height: 1.3; color: var(--ink); white-space: normal; overflow: visible; }
  /* Terms as on the web: under the concept's title, reading from the left; the status on the right. */
  #dots-view .index-page .kitem.trow { grid-template-columns: var(--code-col) 14px minmax(0, 1fr) auto; column-gap: 0; padding: 6px 0; }
  #dots-view .index-page .kitem.trow .kdot { justify-self: start; }
  #dots-view .index-page .kitem.trow .k-status { margin-left: 12px; font-size: var(--fs-s); color: var(--grey); }
  #dots-view .index-page .kitem.trow .k-term { font-size: var(--fs-l); color: var(--ink); }
  #dots-view .index-page .kitem.trow .k-brief { grid-column: 3 / 5; font-size: var(--fs-s); line-height: 1.4; color: var(--ink); }
  /* Tools: one at a time, in the sheet above the answer box; drag its top edge to resize. */
  .sheet { display: flex; flex-direction: column; height: var(--sheet-h, 40vh); border-top: 1px solid var(--rule); background: var(--bg); }
  .sheet-grip { flex: none; height: 24px; display: grid; place-items: center; touch-action: none; cursor: ns-resize; }
  .sheet-grip::before { content: ""; width: 40px; height: 4px; border-radius: 2px; background: var(--hair); }
  #sheet .popup { position: static !important; left: auto !important; top: auto !important; width: auto !important; flex: 1; min-height: 0;
    display: flex; flex-direction: column; border: 0; }
  #sheet .popup[hidden] { display: none; }
  #sheet .popup.menu-page { position: static !important; border: 0; display: flex; flex-direction: column; }   /* notes, in the sheet */
  #sheet .popup-head { border-bottom: 1px solid var(--hair); }
  #sheet .popup-body { flex: 1; min-height: 0; overflow: auto; max-height: none; }
  .popup-pin { display: none; }
  /* Menu pages take the screen under the bar. */
  .popup.menu-page { left: 0 !important; right: 0; top: 52px !important; bottom: 0; width: auto; border: 0; border-top: 1px solid var(--hair);
    display: flex; flex-direction: column; }
  .popup.menu-page[hidden] { display: none; }
  .popup.menu-page .popup-body { flex: 1; min-height: 0; max-height: none; overflow: auto; font-size: var(--fs-s); }
  .popup.menu-page .page-tabs { flex-wrap: wrap; row-gap: 8px; }
  .popup.menu-page .page-tabs .text-btn { white-space: nowrap; }
  /* The answer box, like a chat app's: a card at the bottom, the tools in words above it. */
  .dock { padding: 6px 12px max(12px, env(safe-area-inset-bottom)); }
  .dock-bar { margin-bottom: 6px; }
  .tools { font-size: var(--fs-s); gap: 18px; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition-duration: .01ms !important; }
}

/* ---------- owner's report ---------- */
body.report { overflow: auto; height: auto; }

/* Privacy and terms: one reading column, the two sizes. */
body.legal { overflow: auto; height: auto; }
.legal-page { max-width: 40rem; margin: 0 auto; padding: var(--pad) var(--pad) 5rem; font-size: var(--fs-s); line-height: 1.6; }
.legal-head { display: flex; justify-content: space-between; align-items: baseline; margin-bottom: 3rem; }
.legal-head .brand { color: inherit; text-decoration: none; }
.legal-page h1 { font-size: var(--fs-l); font-weight: 400; margin: 0 0 .4rem; }
.legal-page h2 { font-size: var(--fs-s); font-weight: 400; text-transform: uppercase; letter-spacing: .02em; margin: 2.4rem 0 .6rem; }
.legal-page ul { padding-left: 1.1rem; }
.legal-page li { margin-bottom: .45rem; }
.legal-page b { font-weight: 400; color: var(--ink); }
.legal-page a { color: inherit; }
.report-page { max-width: 1200px; margin: 0 auto; padding: var(--pad); font-size: var(--fs-s); }
.report-head { display: flex; justify-content: space-between; font-size: var(--small); text-transform: uppercase; border-bottom: 1px solid var(--rule); padding-bottom: 10px; }
.report-page h2 { font-size: var(--small); font-weight: 400; text-transform: uppercase; margin: 2.4rem 0 .6rem; }
.report-page a { color: inherit; }
.report-overview { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); margin-top: 1.4rem; border-top: 1px solid var(--hair); }
.report-overview div { padding: 10px 10px 12px 0; display: flex; flex-direction: column; gap: 4px; border-bottom: 1px solid var(--hair); }
.report-overview b { font-weight: 400; font-size: var(--fs-l); }
.report-table-wrap { overflow-x: auto; }
.report-table { width: 100%; border-collapse: collapse; }
.report-table th { text-align: left; font-weight: 400; font-size: var(--small); text-transform: uppercase; color: var(--grey); padding: 6px 8px 6px 0; border-bottom: 1px solid var(--rule); cursor: pointer; white-space: nowrap; }
.report-table th.on { color: var(--ink); }
.report-table td { padding: 5px 8px 5px 0; border-bottom: 1px solid var(--hair); vertical-align: top; }
.report-table tr.row { cursor: pointer; }
.report-table tr.row:hover { background: var(--hover); }
.report-table tr.empty { color: var(--grey); }
.report-table tr.notes td { background: var(--hover); padding: 8px 10px; }
.report-table tr.notes div { margin: 2px 0; }
.report-daily .day { display: grid; grid-template-columns: 4em 1fr 3em 7em; gap: 10px; align-items: center; padding: 2px 0; }
.report-daily .bar { height: 3px; background: var(--hair); }
.report-daily .bar i { display: block; height: 3px; width: var(--w, 0); background: var(--ink); }

.text-btn.danger { color: var(--red); }
.fine { font-size: var(--fs-s); max-width: 32em; margin-top: 1.2rem; }

/* "Do you know X?": a row of dots the full width of the answer box, nine steps from no clue to
   easy. The word rides above the pointer; touch screens show the two ends instead. */
@media (hover: none) { .fam-ends { display: flex; } }

/* ---------- mono only where it carries meaning: codes, counts, and calculator figures ---------- */
.crow .c-code, .obj-head > span:first-child, .chap-head .count, .obj-head .count, .calc-screen, .calc-item {
  font-family: var(--mono); letter-spacing: 0;
}
.calc-out { font-family: var(--mono); font-size: var(--fs-s); }
.crow, .chap-head, .obj-head { column-gap: 8px; }
.obj-head .t, .chap-head > :first-child { min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

/* People in questions, under Settings: one strict grid of three equal columns, left aligned, for every
   role's names. A long name stays in its cell and ends in an ellipsis; it is whole in the questions.
   Grey is the default, black is yours. */
.cast-fields { padding: 0 0 1.2rem; }
.cast-fields .cast-lede { margin: 0; font-size: var(--fs-s); color: var(--grey); text-transform: none; }
.cast-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); column-gap: 16px; row-gap: 4px; }
.cast-fields .cast-role { margin: 1rem 0 .2rem; font-size: var(--fs-s); color: var(--grey); text-transform: uppercase; }
.cast-grid input { width: 100%; min-width: 0; box-sizing: border-box; border: 0; border-bottom: 1px solid transparent; background: transparent;
  color: var(--ink); font: inherit; font-size: var(--fs-s); line-height: 1.9; padding: 0; margin: 0; text-transform: none; text-overflow: ellipsis; }
.cast-grid input::placeholder { color: var(--grey); text-overflow: ellipsis; }
.cast-grid input:hover, .cast-grid input:focus { outline: none; border-bottom-color: var(--hair); }
.cast-go-row { margin: .6rem 0 0; }

/* Phone: fields must be 17px or an iPhone zooms in when you tap one, so the names are drawn at 17px and
   scaled to the small size (13/17), taking a small size's room in the grid. */
@media (max-width: 860px) {
  .cast-grid input { line-height: 32px; width: calc(100% / .7647); transform: scale(.7647); transform-origin: 0 0; margin-bottom: -7.5px; }
}
/* Settings: one row each, divided by hairlines. A folding row shows + shut and − open. */
.set-row { display: flex; justify-content: space-between; align-items: baseline; width: 100%; box-sizing: border-box; padding: 12px 0;
  border-top: 1px solid var(--hair); font-size: var(--fs-s); color: var(--ink); text-transform: uppercase; }
.page-body > :first-child.set-row { border-top: 0; }
button.set-row { all: unset; display: flex; justify-content: space-between; align-items: baseline; width: 100%; box-sizing: border-box; padding: 12px 0;
  border-top: 1px solid var(--hair); font-size: var(--fs-s); color: var(--ink); text-transform: uppercase; cursor: pointer; }
button.set-row:focus-visible { outline: 1px solid var(--hair); }
.set-pick { display: flex; gap: 16px; }
.set-pick .text-btn { color: var(--grey); text-decoration: none; text-transform: uppercase; }
.set-pick .text-btn.on, .set-pick .text-btn:hover { color: var(--ink); }
.exam-form { display: flex; flex-wrap: wrap; gap: 12px; align-items: center; margin: 8px 0 16px; }
.exam-form select, .exam-form input { font: inherit; color: inherit; background: transparent; border: 0; border-bottom: 1px solid var(--grey); padding: 2px 0; }
.set-mark::before { content: '+'; color: var(--grey); }
.set-fold.open .set-mark::before { content: '\2212'; }
.set-body { display: none; }
.set-fold.open .set-body { display: block; }
.set-body .page-form { margin-top: 0; padding-bottom: 1.2rem; }
.page-body .set-note .set-warn { color: var(--ink); }
.set-note .set-acts { display: flex; gap: 16px; margin-top: 10px; }
.set-note .set-acts .text-btn { font-size: var(--fs-s); text-transform: uppercase; }
.set-note .set-acts [data-ok] { color: var(--ink); }
.page-body .set-note { margin: 0 0 12px; font-size: var(--fs-s); line-height: 1.4; text-transform: none; letter-spacing: 0; }
/* Minimum mode: what falls outside the minimum set stays on the map, quieter. */
.crow.off, .hdot.off { opacity: .3; }

/* Reading preference, from Settings (kept per browser). Large text raises both sizes; the two-size
   hierarchy stays. */
:root[data-size="large"] { --small: 16px; --fs-l: 22px; --lead: 1.3; }
/* Large text gets more room between lines and rows too, so it reads as large, not crowded. */
:root[data-size="large"] .conversation { line-height: 1.55; }
@media (min-width: 861px) { :root[data-size="large"] .index-page .crow { height: 22px; } }   /* the map's rows; the rail keeps its 15 px pitch */
:root[data-size="large"] .kitem.trow { padding-top: 4px; padding-bottom: 4px; }
:root[data-size="large"] :is(.mm-list, .corner-panel .mm-list) { gap: 20px; }
:root[data-size="large"] .page-body :is(.prose, .memo, .note-text, .hl-open, .k-brief) { line-height: 1.55; }
@media (max-width: 860px) { :root[data-size="large"] { --small: 17px; --fs-l: 23px; } }

/* Pages and forms: the heading (the lede) is the larger size; what follows, the fields, choices, and
   prose, the smaller one. (On a phone, typed fields stay at 17 px so it does not zoom in.) */
.form :is(input, select, textarea), .choices label, .page-body .prose, .page-body .kitem .k-brief { font-size: var(--fs-s); }
.page-body .prose { line-height: 1.5; }

/* The Dossier's progress: a division per row, names on one line whatever the code's width. */
.prog-row { display: grid; grid-template-columns: 50px minmax(0, 1fr) auto; align-items: baseline; padding: 6px 0; border-top: 1px solid var(--hair); text-transform: none; }
.prog-row b { font-weight: 500; }
.prog-n { color: var(--grey); }
.prog-extra { grid-column: 2 / 4; color: var(--grey); }


/* ---------- drawings (static/drawing.js, docs/DRAWINGS.md) ---------- */
.drawing { margin: 1.2rem 0; position: relative; }
.drawing svg { display: block; width: 100%; height: auto; max-height: 62vh; overflow: hidden; user-select: none; -webkit-user-select: none; }
.drawing .pen { fill: none; stroke: var(--ink); vector-effect: non-scaling-stroke; stroke-linecap: square; stroke-linejoin: miter; shape-rendering: geometricPrecision; }
.drawing .pen-cut { stroke-width: var(--pen-cut); }
.drawing .pen-profile { stroke-width: var(--pen-profile); }
.drawing .pen-medium { stroke-width: var(--pen-medium); }
.drawing .pen-beyond { stroke-width: var(--pen-beyond); }
.drawing .pen-hidden { stroke-width: var(--pen-hidden); stroke: var(--pen-light); stroke-dasharray: 3 2.5; stroke-linecap: butt; }
.drawing .pen-center { stroke-width: var(--pen-center); stroke: var(--pen-light); stroke-dasharray: 12 3 2 3; stroke-linecap: butt; }
.drawing .pen-dim { stroke-width: var(--pen-dim); stroke-linecap: butt; }
.drawing .pen-hatch { stroke-width: var(--pen-hatch); stroke: var(--pen-light); stroke-linecap: butt; }
.drawing .dw-paper.tone { fill: var(--pen-tone); }
.drawing .pen-none { stroke: none; }
.drawing .fill-solid { fill: var(--ink); }
.drawing .dw-paper { fill: var(--bg); stroke: none; }
.drawing .dw-dot { fill: var(--ink); }
.drawing .dw-text { fill: var(--ink); font-family: var(--font); letter-spacing: 0; }   /* as written, in proper case */
.drawing .dw-layer.off { display: none; }
.drawing .dw-hot { cursor: pointer; outline: none; }
.drawing .dw-hot-area { fill: transparent; stroke: none; }
.drawing .dw-hot-tag { fill: var(--bg); stroke: var(--ink); stroke-width: .6px; vector-effect: non-scaling-stroke; }
.drawing .dw-hot-id { fill: var(--ink); font-family: var(--font); font-weight: 500; letter-spacing: 0; pointer-events: none; }
.drawing .dw-hot:hover .dw-hot-area, .drawing .dw-hot:focus-visible .dw-hot-area { fill: color-mix(in srgb, var(--ink) 6%, transparent); }
.drawing .dw-hot.picked .dw-hot-tag { fill: var(--ink); }
.drawing .dw-hot.picked .dw-hot-id { fill: var(--bg); }
.drawing .dw-hot.right .dw-hot-tag { fill: var(--gold); stroke: var(--gold); }
.drawing .dw-hot.wrong .dw-hot-tag { fill: var(--red); stroke: var(--red); }
.drawing .dw-hot.right .dw-hot-id, .drawing .dw-hot.wrong .dw-hot-id { fill: var(--bg); }
.dw-cap { display: flex; justify-content: space-between; gap: 1rem; margin-top: 6px; font-size: var(--fs-s); color: var(--grey); }   /* the title as written, in proper case */
.dw-layers { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 6px; font-size: var(--fs-s); }
.dw-layers .text-btn { color: var(--grey); text-decoration: none; }
.dw-layers .text-btn.on { color: var(--ink); }
.dw-reset { position: absolute; top: 4px; right: 0; font-size: var(--fs-s); color: var(--grey); }

/* ---------- bank cards (app/bank.py): a checked question, graded in the app ---------- */
.card { margin-top: 1.2rem; }
.card .card-q { margin: 0 0 1rem; }
.turn.tutor .card ol.choices { list-style: none; margin: 0; padding: 0; }
.turn.tutor .card .choices li { margin: 0; }
.card .choices li { border-top: 1px solid var(--hair); }
.card .choices li:last-child { border-bottom: 1px solid var(--hair); }
.card .opt { display: grid; grid-template-columns: 28px 1fr; column-gap: 8px; width: 100%; padding: .6rem 0; color: var(--ink); }
.card .opt:disabled { cursor: default; }
.card .ch-k { color: var(--grey); transition: color .2s var(--ease); }   /* the letter only: no marks */
.card .opt:not(:disabled):hover .ch-k, .card .opt.picked .ch-k { color: var(--ink); }
.card .opt.right .ch-k { color: var(--gold); }
.card .opt.wrong .ch-k { color: var(--red); }
.card[data-pick]:not(.done) .opt:not(.picked) .ch-t { color: var(--grey); }   /* the pick stands out by the others stepping back */
.card.done .opt:not(.right):not(.wrong) .ch-t { color: var(--grey); }
.card .ch-why { grid-column: 2; color: var(--grey); margin-top: .35rem; }
.card .opt.right .ch-why, .card .opt.wrong .ch-why { color: var(--ink); }
.card .card-explain, .card .card-basis { margin: .8rem 0 0; color: var(--grey); }
.card .card-basis { font-size: var(--fs-s); text-transform: uppercase; letter-spacing: .02em; }
.card .card-acts { display: flex; gap: 1.2rem; align-items: baseline; margin-top: .9rem; font-size: var(--fs-s); }
.card .card-acts:empty { display: none; }
.card .card-verdict { text-transform: uppercase; letter-spacing: .02em; margin-right: auto; }

/* The secret disco ball (static/js/party.js): over everything, the bar included, so the first tap anywhere ends it. */
.party { position: fixed; inset: 0; width: 100vw; height: 100vh; z-index: 60; touch-action: none; }
.partying .hdot { visibility: hidden; }
:is(.exam-head, .mmd > b, #mbar, .home-head, #space-nav, #corner-menu, .home-fine, #mm-theme) { transition: opacity .5s var(--ease); }
/* While the ball turns, nothing else: the division names, the bar, the wordmark, the edges and corners. */
body.party-on :is(.exam-head, .mmd > b, #mbar, .home-head, #space-nav, #corner-menu, .home-fine, #mm-theme) { opacity: 0; pointer-events: none; }
body.party-on :is(.mmd > b, .exam-head) { visibility: hidden; transition: opacity .5s var(--ease), visibility 0s .5s; }   /* gone, whatever a browser does with the fade */
/* What a card asks for, under its choices, until it is answered. */
.card-prompt { color: var(--grey); margin: 10px 0 0; }
.card.done .card-prompt { display: none; }
/* How an answer was graded: small and grey, between the answer and the reply. */
.turn.grade-line { color: var(--grey); font-size: var(--fs-s); }
.turn.grade-line p { margin: 0; }
