/* ============================================================
   Bonsai — light, earthy app UI
   parchment & forest · no gradients · no glow · no dark mode
   ============================================================ */

:root {
  --paper:        #efe6d3;   /* parchment ground */
  --paper-panel:  #f6efdf;   /* bars / surfaces */
  --paper-edge:   #e7dcc4;   /* pressed / active tint */

  --ink:          #2b2618;   /* primary text */
  --ink-soft:     #5b5340;   /* secondary text */
  --ink-faint:    #8c8068;   /* inactive / labels */

  --line:         #d6c8a8;   /* hairline */
  --line-strong:  #c3b290;

  --forest:       #34503a;   /* primary green */
  --forest-deep:  #25402b;

  --leaf:         #4c6b46;   /* canopy mid */
  --leaf-light:   #6f8d5a;   /* canopy highlight */
  --leaf-warm:    #9a8a4e;   /* occasional warm leaf */
  --bark:         #5a4a35;   /* trunk / branches */

  --water:        #6d949b;   /* pond surface */
  --water-deep:   #46707a;   /* pond depth */
  --water-light:  #a7c6c8;   /* shimmer */

  --correct:      #3f7a4e;   /* graded right */
  --incorrect:    #b4513f;   /* graded wrong */

  /* Home-garden text over the canvas — flips with the REAL sky, not the chrome
     theme toggle (see body.garden-night). Day values: */
  --garden-head:  #25402b;
  --garden-text:  #2b2618;
  --garden-soft:  #5b5340;
  --garden-faint: #8c8068;

  --bar-h:        3.25rem;
  --tab-h:        4rem;
}

/* ── Night mode · the whole UI darkens to match the night sky ──
   The garden script adds .is-night to <body> when it's nighttime where the
   user is. Because the app is entirely token-driven, overriding the colour
   tokens here recolours every surface (bars, panels, text, buttons). The
   tree/water palette is read once by the canvas at load, so it's untouched. */
body.is-night {
  --paper:        #20263a;
  --paper-panel:  #2a3148;
  --paper-edge:   #38415c;

  --ink:          #e7e9f1;
  --ink-soft:     #b3b9cb;
  --ink-faint:    #828ba3;

  --line:         #3a4258;
  --line-strong:  #4b5571;

  --forest:       #9bbf93;
  /* One consistent green in dark mode: deep + correct collapse onto the primary
     green, so every green UI accent matches. (The tree keeps its own canopy
     colours — the canvas reads --leaf/--leaf-* separately at load.) */
  --forest-deep:  var(--forest);

  --correct:      var(--forest);
  --incorrect:    #d98b78;
}
/* Switching Appearance (light ⇄ dark) recolours every token at once, which would
   otherwise snap the whole UI in one frame. The theme controller adds .theme-anim
   to <body> for the length of the change, so the colour swap cross-fades smoothly.
   It's only on during the switch, so normal hover/press transitions keep their own
   faster timing; and it's gated to motion-OK users (the reduced-motion block below
   already disables transitions outright). */
@media (prefers-reduced-motion: no-preference) {
  body.theme-anim,
  body.theme-anim *,
  body.theme-anim *::before,
  body.theme-anim *::after {
    transition: background-color 0.35s ease,
                color 0.35s ease,
                border-color 0.35s ease,
                fill 0.35s ease,
                box-shadow 0.35s ease !important;
  }
}
/* The home-garden text flips light in two cases: when the chrome is in dark mode
   (.is-night) so it stays readable on the dark UI, and when it's actually night
   where the user is (.garden-night) so it reads over the real dark sky even if the
   chrome is kept light. (The garden tree/sky canvas itself still follows the real
   sky only — see the JS theme controller.) */
body.is-night,
body.garden-night {
  --garden-head:  #eef1f6;
  --garden-text:  #e7e9f1;
  --garden-soft:  #c3c9d8;
  --garden-faint: #aab2c6;
}
/* Night mode: the dim grey text along the bottom (tab labels, the Prompts panel,
   and the weather caption) is hard to read on the dark UI — brighten it a step.
   :not(.active) keeps the active tab's green; hover still brightens fully. */
body.is-night .tab:not(.active) { color: var(--ink-soft); }
body.is-night .tab:not(.active):hover { color: var(--ink); }
body.is-night .garden-weather,
body.garden-night .garden-weather { color: var(--garden-soft); }
body.is-night .garden-weather.is-shown,
body.garden-night .garden-weather.is-shown { opacity: 1; }
/* The CO₂ stat dot uses the tree's --leaf green; in dark mode point it at the
   one UI green so every green accent matches (the tree itself is unaffected). */
body.is-night .garden-stat[data-kind="co2"] .garden-stat-dot { background: var(--forest); }
/* The title + slogan float over the canvas, and clouds drift right behind them.
   At night the text is light, so a white cloud passing behind would wash it out.
   Fix: a soft dark scrim behind the header (darkens whatever's behind — sky OR
   cloud) plus a dense dark halo on the glyphs, so it's always readable. */
body.is-night .home-head::before,
body.garden-night .home-head::before {
  content: "";
  position: absolute;
  left: 50%;
  top: 46%;
  transform: translate(-50%, -50%);
  width: 40rem;
  max-width: 94vw;
  height: 13rem;
  border-radius: 50%;
  background: radial-gradient(ellipse at center,
    rgba(16, 22, 40, 0.85) 0%,
    rgba(16, 22, 40, 0.6) 38%,
    rgba(16, 22, 40, 0) 70%);
  filter: blur(3px);
  z-index: -1;            /* behind the text, above the canvas/clouds */
  pointer-events: none;
}
body.is-night .home-title,
body.is-night .home-subtitle,
body.is-night .home-greeting,
body.garden-night .home-title,
body.garden-night .home-subtitle,
body.garden-night .home-greeting {
  text-shadow: 0 0 12px rgba(8, 12, 28, 0.92), 0 1px 3px rgba(8, 12, 28, 0.95);
}
/* ease the chrome between day and night instead of snapping */
body,
.topbar, .tabbar, .composer, .msg-body {
  transition: background-color 0.6s ease, color 0.6s ease, border-color 0.6s ease;
}

* { margin: 0; padding: 0; box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

body {
  min-height: 100dvh;
  background-color: var(--paper);
  background-image:
    repeating-linear-gradient(0deg, rgba(120,100,60,0.018) 0 1px, transparent 1px 3px);
  color: var(--ink);
  font-family: 'Spectral', Georgia, serif;
  font-size: 1.0625rem;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

::selection { background: rgba(52,80,58,0.18); }

/* ── Top bar ─────────────────────────────────────────────── */

.topbar {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: var(--bar-h);
  display: flex;
  align-items: center;
  padding: 0 1.25rem;
  background: var(--paper-panel);
  border-bottom: 1px solid var(--line);
  z-index: 20;
}

.wordmark {
  display: inline-flex;
  align-items: center;
  background: none;
  border: none;
  font-family: inherit;
  font-size: 1.25rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--forest-deep);
  cursor: pointer;
  padding: 0.25rem 0;
}
.wordmark-text {
  display: inline-block;
  /* exit (default): gentle, slightly slower */
  transition: transform 0.42s cubic-bezier(0.22, 1, 0.36, 1);
}
.wordmark-leaf {
  width: 1.05em;
  height: 1.05em;
  margin-left: 0.1em;
  color: var(--forest);
  transform: translateX(-0.5em) scale(0.4) rotate(-25deg);
  transform-origin: left center;
  opacity: 0;
  /* exit (default): softer, eases the leaf back in without snapping */
  transition: transform 0.5s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.4s ease;
}
.wordmark:hover .wordmark-text,
.wordmark:focus-visible .wordmark-text {
  transform: translateX(-1px);
  /* enter: springy */
  transition: transform 0.26s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.wordmark:hover .wordmark-leaf,
.wordmark:focus-visible .wordmark-leaf {
  transform: translateX(0) scale(1) rotate(0deg);
  opacity: 1;
  /* enter: springy */
  transition: transform 0.32s cubic-bezier(0.34, 1.56, 0.64, 1), opacity 0.22s ease-out;
}
.wordmark:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; border-radius: 6px; }

@media (prefers-reduced-motion: reduce) {
  .wordmark-text,
  .wordmark-leaf { transition: opacity 0.2s ease; }
  .wordmark:hover .wordmark-text,
  .wordmark:focus-visible .wordmark-text { transform: none; }
  .wordmark:hover .wordmark-leaf,
  .wordmark:focus-visible .wordmark-leaf { transform: none; opacity: 1; }
}

/* ── Screens ─────────────────────────────────────────────── */

.screens {
  position: fixed;
  top: var(--bar-h);
  left: 0; right: 0;
  bottom: calc(var(--tab-h) + env(safe-area-inset-bottom, 0px));
  overflow-y: auto;
  overflow-x: hidden;
  -webkit-overflow-scrolling: touch;
}

.page { display: none; }
.page.active { display: block; }

.content-page {
  max-width: 44rem;
  margin: 0 auto;
  padding: 1.75rem 1.5rem 2.5rem;
}

.screen-title {
  font-weight: 600;
  font-size: clamp(2rem, 7vw, 2.75rem);
  line-height: 1.1;
  color: var(--forest-deep);
  margin-bottom: 0.6rem;
}

.screen-intro {
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--ink-soft);
  max-width: 36rem;
  padding-bottom: 1.25rem;
  border-bottom: 1px solid var(--line);
  margin-bottom: 1.5rem;
  text-wrap: pretty;
}

.page-content { min-height: 40vh; }

/* ── Home ── */

#page-home.active { display: flex; }
.home {
  position: relative;
  min-height: 100%;
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
  text-align: center;
  padding: 0.5rem 1rem 0.4rem;
  width: 100%;
}

/* The title floats over the top of the garden so the weather/sky canvas can
   extend all the way up to just below the top bar. pointer-events:none keeps
   the canvas (drag the tree, tap the pond) fully interactive underneath. */
.home-head {
  position: fixed;
  top: calc(var(--bar-h) - 0.4rem);
  left: 0;
  right: 0;
  z-index: 5;
  text-align: center;
  pointer-events: none;
}

.home-title {
  font-weight: 600;
  font-size: clamp(2.25rem, 9vw, 3.5rem);
  line-height: 1;
  letter-spacing: 0.01em;
  color: var(--garden-head);
}

.home-subtitle {
  font-style: italic;
  font-size: 1.0625rem;
  color: var(--garden-soft);
  margin-top: 0.5rem;
}

/* Personalized, time-aware greeting floating in the garden header */
.home-greeting {
  font-style: italic;
  font-size: 1.05rem;
  letter-spacing: 0.01em;
  color: var(--garden-soft);
  margin-top: 0.65rem;     /* drop the greeting back down… */
  margin-bottom: -0.4rem;  /* …without pushing the title down with it */
  animation: home-greeting-in 0.7s cubic-bezier(0.22, 1, 0.36, 1) both;
}
.home-greeting[hidden] { display: none; }
@keyframes home-greeting-in {
  from { opacity: 0; transform: translateY(-6px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .home-greeting { animation: none; }
}

/* ── Digital garden ── */

.garden {
  flex: 1 1 auto;
  width: 100%;
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  min-height: 0;
}

/* Full-bleed garden: fills the whole home area, from just below the top bar
   down to just above the bottom mode bar, so the sky + weather cover the
   entire scene edge to edge. The title and prompts panel float on top. */
.garden-stage {
  position: fixed;
  top: var(--bar-h);
  left: 0;
  right: 0;
  bottom: calc(var(--tab-h) + env(safe-area-inset-bottom, 0px));
  z-index: 0;
  overflow: visible;
}

.garden-canvas {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  /* height is set in JS so the buffer can extend below the stage and give the
     pond's lower lip room to render instead of being clipped at the edge */
  display: block;
  touch-action: pan-y;
  cursor: pointer;
}

.garden-stats {
  position: absolute;
  top: 0.85rem;
  left: 0.85rem;
  right: 0.85rem;
  display: flex;
  justify-content: space-between;
  gap: 0.75rem;
  pointer-events: none;
}

.garden-weather {
  position: absolute;
  bottom: 0.85rem;
  left: 0.85rem;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  font-size: 0.78rem;
  font-style: italic;
  color: var(--garden-faint);
  pointer-events: none;
  opacity: 0;
  transition: opacity 0.8s ease;
  letter-spacing: 0.01em;
}
.garden-weather.is-shown { opacity: 0.85; }
.garden-weather .garden-weather-glyph {
  font-style: normal;
  font-size: 0.95rem;
  line-height: 1;
}

.garden-stat {
  display: flex;
  align-items: flex-start;
  gap: 0.45rem;
  text-align: left;
}
.garden-stat[data-kind="water"] {
  flex-direction: row-reverse;
  text-align: right;
}

.garden-stat-dot {
  margin-top: 0.42rem;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 999px;
  flex: 0 0 auto;
}
.garden-stat[data-kind="co2"]  .garden-stat-dot { background: var(--leaf); }
.garden-stat[data-kind="water"] .garden-stat-dot { background: var(--water-deep); }

.garden-stat-text { display: flex; flex-direction: column; line-height: 1.15; }

.garden-stat-value {
  font-weight: 600;
  font-size: 1.5rem;
  color: var(--garden-text);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
}

.garden-stat-unit {
  font-size: 0.75rem;
  font-style: italic;
  color: var(--garden-faint);
  margin-top: 0.05rem;
}

/* Hover/focus tooltip on a stat (e.g. "water saved"). The .garden-stats row is
   pointer-events:none, so the tipped stat re-enables events for itself. */
.garden-stat-tipped {
  position: relative;
  pointer-events: auto;
  cursor: help;
  outline: none;
}
.garden-stat-tip {
  position: absolute;
  top: calc(100% + 0.5rem);
  left: 0;
  right: auto;
  width: 15rem;
  max-width: 62vw;
  padding: 0.5rem 0.65rem;
  background: var(--paper-panel);
  color: var(--ink-soft);
  border: 1px solid var(--line-strong);
  border-radius: 0.55rem;
  box-shadow: 0 6px 18px rgba(43, 38, 24, 0.16), 0 1px 2px rgba(43, 38, 24, 0.08);
  font-size: 0.72rem;
  font-style: normal;
  font-weight: 400;
  line-height: 1.35;
  letter-spacing: normal;
  text-align: left;
  opacity: 0;
  transform: translateY(-0.25rem);
  pointer-events: none;
  transition: opacity 0.18s ease, transform 0.18s ease;
  z-index: 40;
}
/* The water stat sits top-right, so its tip anchors to the right edge (extends
   left) to stay on-screen; the CO₂ stat top-left keeps the default left anchor. */
.garden-stat[data-kind="water"] .garden-stat-tip { left: auto; right: 0; }
.garden-stat-tipped:hover .garden-stat-tip,
.garden-stat-tipped:focus-visible .garden-stat-tip {
  opacity: 1;
  transform: translateY(0);
}
@media (prefers-reduced-motion: reduce) {
  .garden-stat-tip { transition: opacity 0.18s ease; transform: none; }
}

/* Prompts count — a plain stat number in the garden's bottom-right corner,
   styled exactly like the CO₂/water readouts (mirrors the "water" variant). */
.garden-stats-bottom {
  top: auto;
  bottom: 0.85rem;
  justify-content: flex-end;
}

.garden-stat[data-kind="prompts"] {
  flex-direction: row-reverse;
  text-align: right;
}
.garden-stat[data-kind="prompts"] .garden-stat-dot { background: var(--forest-deep); }

.home-about {
  margin-left: auto;
  font-family: inherit;
  font-size: 0.9375rem;
  color: var(--forest-deep);
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.45rem 1.1rem;
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease;
}

/* Dark-mode toggle — same pill language as the topbar, icon-only to stay light */
.theme-toggle {
  flex: 0 0 auto;
  margin-left: 0.6rem;
  width: 2.4rem;
  height: 2.4rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--forest-deep);
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.theme-toggle:hover { border-color: var(--forest); }
.theme-toggle:active { background: var(--paper-edge); }
.theme-toggle:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

/* Greeting next to the sign-out pill — shown only while signed in */
.topbar-greeting {
  flex: 0 0 auto;
  margin-left: 0.6rem;
  font-size: 0.92rem;
  color: var(--ink-soft);
  white-space: nowrap;
  max-width: 11rem;
  overflow: hidden;
  text-overflow: ellipsis;
}
.topbar-greeting[hidden] { display: none; }

/* Sign-out pill — shown only while signed in */
.topbar-account {
  flex: 0 0 auto;
  margin-left: 0.6rem;
  font-family: inherit;
  font-size: 0.9rem;
  color: var(--forest-deep);
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.4rem 0.95rem;
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease;
}
.topbar-account:hover { border-color: var(--forest); }
.topbar-account:active { background: var(--paper-edge); }
.topbar-account:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.topbar-account[hidden] { display: none; }

/* ── Profile button (topbar) + Profile page ─────────────────── */
.topbar-profile {
  flex: 0 0 auto;
  margin-left: 0.6rem;
  width: 2.4rem; height: 2.4rem;
  display: inline-flex; align-items: center; justify-content: center;
  color: var(--forest-deep);
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease;
}
.topbar-profile:hover { border-color: var(--forest); }
.topbar-profile:active { background: var(--paper-edge); }
.topbar-profile:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.topbar-profile svg { width: 1.25rem; height: 1.25rem; display: block; }
.topbar-profile[hidden] { display: none; }

.profile-screen {
  position: fixed; inset: 0; z-index: 1500;
  background: var(--paper);
  overflow-y: auto; -webkit-overflow-scrolling: touch;
}
.profile-screen[hidden] { display: none; }
body.profile-open { overflow: hidden; }

.profile-bar {
  position: sticky; top: 0; z-index: 1;
  display: flex; align-items: center; gap: 0.75rem;
  height: var(--bar-h);
  padding: 0 1rem;
  background: var(--paper-panel);
  border-bottom: 1px solid var(--line);
}
.profile-back {
  display: inline-flex; align-items: center; gap: 0.25rem;
  font-family: inherit; font-size: 0.95rem; font-weight: 500;
  color: var(--ink-soft); background: none; border: none; cursor: pointer;
  padding: 0.35rem 0.5rem 0.35rem 0; border-radius: 6px;
}
.profile-back:hover { color: var(--ink); }
.profile-back:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.profile-back svg { width: 1.15rem; height: 1.15rem; }
.profile-bar-title { font-weight: 600; font-size: 1.05rem; color: var(--forest-deep); }

.profile-body { max-width: 34rem; margin: 0 auto; padding: 1.5rem 1.25rem 4rem; }

.profile-section {
  background: var(--paper-panel);
  border: 1px solid var(--line);
  border-radius: 0.9rem;
  padding: 1.1rem 1.15rem;
  margin-bottom: 1.1rem;
}
.profile-section h2 {
  font-size: 0.78rem; letter-spacing: 0.12em; text-transform: uppercase;
  color: var(--ink-faint); margin-bottom: 0.9rem; font-weight: 600;
}
.profile-field { margin-bottom: 1rem; }
.profile-field:last-child { margin-bottom: 0; }
.profile-field > label {
  display: block; font-size: 0.9rem; font-weight: 500; color: var(--ink-soft); margin-bottom: 0.35rem;
}
.profile-input {
  width: 100%; font-family: inherit; font-size: 1rem; color: var(--ink);
  background: var(--paper); border: 1px solid var(--line-strong); border-radius: 10px;
  padding: 0.7rem 0.85rem; min-height: 3rem;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
.profile-input:focus { outline: none; border-color: var(--forest); box-shadow: 0 0 0 3px rgba(52,80,58,0.16); }
.profile-input::placeholder { color: var(--ink-faint); }
.profile-readonly { color: var(--ink); padding: 0.15rem 0; }
.profile-readonly-sub { font-size: 0.85rem; color: var(--ink-faint); }

/* Feedback form */
.profile-feedback-stack {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 0.5rem;
  margin-top: 0.7rem;
}
.profile-textarea {
  display: block;
  width: 100%; font-family: inherit; font-size: 1rem; color: var(--ink); line-height: 1.5;
  background: var(--paper); border: 1px solid var(--line-strong); border-radius: 10px;
  padding: 0.65rem 0.85rem; min-height: 0; resize: vertical;
  margin: 0;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
.profile-textarea:focus { outline: none; border-color: var(--forest); box-shadow: 0 0 0 3px rgba(52,80,58,0.16); }
.profile-textarea::placeholder { color: var(--ink-faint); }
.profile-feedback-stack .profile-feedback-send {
  position: relative;
  margin-top: 0; width: 100%;
  display: inline-flex; align-items: center; justify-content: center;
  text-align: center;
  font-family: inherit; font-size: 0.95rem; font-weight: 600;
  color: var(--paper-panel); background: var(--forest); border: 1px solid var(--forest);
  border-radius: 10px; padding: 0.7rem; min-height: 2.8rem; cursor: pointer;
  transition: background-color 0.18s ease;
}
.profile-feedback-send {
  position: relative;
  margin-top: 0.5rem; width: 100%;
  display: inline-flex; align-items: center; justify-content: center;
  text-align: center;
  font-family: inherit; font-size: 0.95rem; font-weight: 600;
  color: var(--paper-panel); background: var(--forest); border: 1px solid var(--forest);
  border-radius: 10px; padding: 0.7rem; min-height: 2.8rem; cursor: pointer;
  transition: background-color 0.18s ease;
}
.profile-feedback-send:hover { background: var(--forest-deep); }
.profile-feedback-send:disabled { opacity: 0.6; cursor: default; }
.profile-feedback-send.is-loading { opacity: 1; }
.profile-feedback-send:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.profile-feedback-stack .profile-status { margin: 0; }

.profile-row { display: flex; gap: 0.6rem; align-items: stretch; }
.profile-row .profile-input { flex: 1; }
.profile-btn-save, .profile-action {
  font-family: inherit; font-size: 1rem; font-weight: 600;
  color: var(--paper-panel); background: var(--forest); border: 1px solid var(--forest);
  border-radius: 10px; padding: 0 1.1rem; min-height: 3rem; cursor: pointer;
  transition: background-color 0.18s ease;
}
.profile-btn-save:hover, .profile-action:hover { background: var(--forest-deep); }
.profile-btn-save:focus-visible, .profile-action:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.profile-action { width: 100%; margin-top: 0.25rem; }

.profile-status { display: block; margin-top: 0.35rem; font-size: 0.85rem; min-height: 0; color: var(--ink-faint); }
.profile-status[hidden] { display: none !important; }
.profile-status.is-ok { color: var(--correct); }
.profile-status.is-error { color: var(--incorrect); }

.profile-toggle-row, .profile-row-between {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.profile-toggle-row > span, .profile-row-between > span:first-child { color: var(--ink); }

/* dark-mode switch */
.profile-switch {
  position: relative; flex: 0 0 auto;
  width: 3.1rem; height: 1.7rem;
  background: var(--line-strong); border: none; border-radius: 999px; cursor: pointer;
  transition: background-color 0.2s ease;
}
.profile-switch::after {
  content: ""; position: absolute; top: 0.2rem; left: 0.2rem;
  width: 1.3rem; height: 1.3rem; border-radius: 50%;
  background: var(--paper-panel); transition: transform 0.2s ease;
}
.profile-switch.is-on { background: var(--forest); }
.profile-switch.is-on::after { transform: translateX(1.4rem); }
.profile-switch:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

.profile-badge {
  font-size: 0.8rem; font-weight: 600; color: var(--forest-deep);
  background: var(--paper-edge); border: 1px solid var(--line-strong);
  border-radius: 999px; padding: 0.15rem 0.7rem;
}

.profile-badge.is-blocked {
  color: var(--incorrect);
  border-color: color-mix(in srgb, var(--incorrect) 45%, transparent);
  background: color-mix(in srgb, var(--incorrect) 12%, transparent);
}
.profile-badge.is-allowed {
  color: var(--correct);
  border-color: color-mix(in srgb, var(--correct) 45%, transparent);
  background: color-mix(in srgb, var(--correct) 12%, transparent);
}
.profile-hint { font-size: 0.85rem; color: var(--ink-faint); margin-top: 0.5rem; }

/* Environmental-impact note shown with the Upgrade button, so the climate
   contribution is clear before the user subscribes. Uses the tree's --leaf
   green to tie it to the CO₂ stat elsewhere in the app. */
.profile-eco-note {
  color: var(--ink);
  margin-top: 0.7rem; padding: 0.95rem 1rem;
  border: 1px solid color-mix(in srgb, var(--leaf) 40%, var(--line-strong));
  border-radius: 12px;
  background: color-mix(in srgb, var(--leaf) 9%, transparent);
}
.profile-eco-head {
  display: flex; align-items: center; gap: 0.4rem;
  margin: 0 0 0.7rem; padding-bottom: 0.6rem;
  font-size: 0.92rem; font-weight: 700; color: var(--leaf);
  border-bottom: 1px solid color-mix(in srgb, var(--leaf) 22%, transparent);
}
.profile-eco-stats {
  margin: 0; padding: 0; list-style: none;
  display: flex; flex-direction: column; gap: 0.5rem;
}
.profile-eco-stats li {
  font-size: 0.9rem; line-height: 1.35; padding-left: 1.6rem; position: relative;
}
.profile-eco-stats li::before {
  content: ""; position: absolute; left: 0.35rem; top: 0.42em;
  width: 0.45rem; height: 0.45rem; border-radius: 50%;
  background: var(--leaf);
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--leaf) 18%, transparent);
}
.profile-eco-stats strong { color: var(--leaf); font-weight: 700; }
.profile-eco-foot {
  margin: 0.75rem 0 0; padding-top: 0.6rem;
  font-size: 0.82rem; line-height: 1.4; color: var(--ink-faint);
  border-top: 1px solid color-mix(in srgb, var(--leaf) 15%, transparent);
}

.profile-signout {
  width: 100%; font-family: inherit; font-size: 1rem; font-weight: 600;
  color: var(--incorrect); background: var(--paper-panel);
  border: 1px solid var(--line-strong); border-radius: 10px;
  padding: 0.8rem; min-height: 3rem; cursor: pointer; margin-top: 0.25rem;
  transition: background-color 0.18s ease, border-color 0.18s ease;
}
.profile-signout:hover { border-color: var(--incorrect); background: var(--paper-edge); }
.profile-signout:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

/* Danger zone — delete account (sits above Sign out). */
.profile-danger { border-color: color-mix(in srgb, var(--incorrect) 22%, var(--line-strong)); }
.profile-danger .profile-hint { margin-top: 0.35rem; }
/* clean full-width outlined danger button (mirrors Sign out, in red) */
.profile-delete-btn {
  width: 100%; margin-top: 0.95rem;
  font-family: inherit; font-size: 1rem; font-weight: 600;
  color: var(--incorrect); background: none;
  border: 1px solid color-mix(in srgb, var(--incorrect) 40%, transparent);
  border-radius: 10px; padding: 0.8rem; min-height: 3rem; cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease;
}
.profile-delete-btn:hover { background: color-mix(in srgb, var(--incorrect) 10%, transparent); border-color: var(--incorrect); }
.profile-delete-btn:focus-visible { outline: 2px solid var(--incorrect); outline-offset: 2px; }

/* Confirmation modal (delete account) */
.modal-overlay {
  position: fixed; inset: 0; z-index: 1000;
  display: flex; align-items: center; justify-content: center; padding: 1.5rem;
  background: rgba(0, 0, 0, 0.45);
}
.modal-overlay[hidden] { display: none; }
.modal-box {
  background: var(--paper-panel); color: var(--ink);
  border: 1px solid var(--line); border-radius: 0.9rem;
  padding: 1.5rem; max-width: 26rem; width: 100%;
  box-shadow: 0 16px 44px rgba(0, 0, 0, 0.28);
}
.modal-box h2 { font-size: 1.3rem; color: var(--ink); margin-bottom: 0.55rem; }
.modal-box p { color: var(--ink-soft); font-size: 0.95rem; line-height: 1.5; }
.modal-box .profile-status { min-height: 1.2em; margin: 0.4rem 0 0; font-size: 0.85rem; }
.modal-actions { display: flex; gap: 0.6rem; margin-top: 1.2rem; }
.modal-actions button {
  flex: 1; min-height: 2.8rem; border-radius: 10px;
  font-family: inherit; font-size: 0.95rem; font-weight: 600; cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease, filter 0.18s ease;
}
.modal-cancel { color: var(--ink-soft); background: var(--paper); border: 1px solid var(--line-strong); }
.modal-cancel:hover { border-color: var(--forest); color: var(--ink); }
.modal-danger { color: #fff; background: var(--incorrect); border: 1px solid var(--incorrect); }
.modal-danger:hover { filter: brightness(0.92); }
.modal-danger:disabled { opacity: 0.6; cursor: default; }
.modal-actions button:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.modal-box-wide { max-width: 32rem; }
.modal-box-trial {
  max-width: 22.5rem;
  padding: 1.35rem 1.5rem 1.5rem;
  text-align: center;
  border-color: color-mix(in srgb, var(--forest) 22%, var(--line));
  box-shadow:
    0 20px 48px rgba(0, 0, 0, 0.22),
    0 0 0 1px color-mix(in srgb, var(--leaf) 12%, transparent);
}
/* Trial modal: gentle fade/scale on open, smooth fade-and-settle on dismiss.
   Scoped to #trial-modal so the delete-account modal is unaffected. The
   .is-closing state is toggled by ecoDismissTrialModal() before it hides. */
#trial-modal { transition: opacity 0.26s ease; }
#trial-modal:not([hidden]):not(.is-closing) { animation: trial-overlay-in 0.24s ease; }
#trial-modal .modal-box-trial {
  transition: transform 0.28s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.24s ease;
}
#trial-modal:not([hidden]):not(.is-closing) .modal-box-trial {
  animation: trial-modal-in 0.32s cubic-bezier(0.22, 1, 0.36, 1);
}
#trial-modal.is-closing { opacity: 0; pointer-events: none; }
#trial-modal.is-closing .modal-box-trial { transform: translateY(8px) scale(0.97); opacity: 0; }
@keyframes trial-overlay-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes trial-modal-in {
  from { opacity: 0; transform: translateY(10px) scale(0.96); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  #trial-modal, #trial-modal .modal-box-trial { animation: none !important; transition: none !important; }
}

.trial-modal-brand {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 0.55rem;
  margin-bottom: 1rem;
}
.trial-modal-logo {
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  display: block;
  /* The mark is a self-contained green badge; a soft forest-tinted shadow lifts
     it off the paper without a competing ring. */
  box-shadow: 0 6px 16px rgba(37, 64, 43, 0.26);
}
.trial-modal-name {
  font-weight: 600;
  font-size: 1.45rem;
  letter-spacing: 0.01em;
  color: var(--forest-deep);
}
.modal-box-trial h2 {
  font-size: 1.22rem;
  margin-bottom: 0.4rem;
  line-height: 1.25;
}
.trial-modal-lead {
  margin: 0;
  color: var(--ink-soft);
  font-size: 0.95rem;
  line-height: 1.45;
}
.trial-modal-eco {
  display: block;
  margin: 1rem 0 0;
  padding: 0.6rem 0.9rem;
  font-size: 0.82rem;
  font-weight: 600;
  line-height: 1.4;
  color: var(--leaf);
  border-radius: 14px;
  background: color-mix(in srgb, var(--leaf) 11%, var(--paper-panel));
  border: 1px solid color-mix(in srgb, var(--leaf) 26%, transparent);
}
.trial-modal-legal { margin: 0.65rem 0 0; font-size: 0.8rem; }

/* Deep Focus upsell. Narrower than the trial modal and left-aligned: it
   interrupts a specific action rather than announcing the end of the trial, so
   it should read as an explanation, not a billboard. */
.modal-box-deep { max-width: 23rem; }
.deep-modal-lead { margin: 0; }
.deep-modal-note { margin: 0.7rem 0 0; }
.deep-modal-legal { margin: 0.55rem 0 0; font-size: 0.8rem; }
.modal-primary {
  position: relative;
  color: #fff; background: var(--forest); border: 1px solid var(--forest);
  display: inline-flex; align-items: center; justify-content: center;
  text-align: center;
}
.modal-primary:hover { background: var(--forest-deep); border-color: var(--forest-deep); }
.modal-primary:disabled { opacity: 0.6; cursor: default; }
.modal-primary.is-loading { opacity: 1; }
.modal-actions .modal-primary .modal-primary-loader {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.modal-actions .modal-primary .dot-loader span { background: var(--paper-panel); }

/* view-first rows: show info, with a subtle Edit/Change action */
.profile-info-row {
  display: flex; align-items: center; justify-content: space-between; gap: 1rem;
}
.profile-info-row + .profile-info-row {
  border-top: 1px solid var(--line); padding-top: 0.85rem; margin-top: 0.85rem;
}
.profile-info-label { font-size: 0.78rem; color: var(--ink-faint); margin-bottom: 0.15rem; }
.profile-info-value { font-size: 1.05rem; color: var(--ink); word-break: break-word; }
.profile-edit-link {
  flex: 0 0 auto;
  font-family: inherit; font-size: 0.9rem; font-weight: 500; color: var(--forest);
  background: none; border: none; cursor: pointer; padding: 0.3rem 0.4rem; border-radius: 6px;
}
.profile-edit-link:hover { text-decoration: underline; }
.profile-edit-link:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

/* Standalone "Manage billing" link under Membership (not inside an info row) */
.profile-manage-link { display: block; margin-top: 0.7rem; padding-left: 0; }
.profile-manage-link[hidden] { display: none; }

/* Promo-code box under Membership */
.profile-promo { margin-top: 1rem; }
.profile-promo[hidden] { display: none; }
.profile-promo > label { display: block; font-size: 0.9rem; font-weight: 500; color: var(--ink-soft); margin-bottom: 0.4rem; }
.profile-promo-row { display: flex; gap: 0.5rem; align-items: stretch; }
.profile-promo-row .profile-input { flex: 1; text-transform: uppercase; }
.profile-promo-row .profile-input::placeholder { text-transform: none; }
.profile-promo-row .profile-edit-save {
  flex: 0 0 auto; white-space: nowrap; cursor: pointer;
  font-family: inherit; font-size: 0.95rem; font-weight: 600;
  padding: 0 1.1rem; min-height: 2.8rem; border-radius: 10px;
  transition: background-color 0.18s ease;
}
.profile-promo-row .profile-edit-save:disabled { opacity: 0.6; cursor: default; }
.profile-promo-row .profile-edit-save:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

.profile-edit { margin-top: 0.9rem; }
.profile-edit[hidden] { display: none; }
.profile-edit > label { display: block; font-size: 0.9rem; font-weight: 500; color: var(--ink-soft); margin-bottom: 0.35rem; }
.profile-edit-actions { display: flex; gap: 0.6rem; margin-top: 0.7rem; }
.profile-edit-actions button {
  flex: 1; min-height: 2.8rem; border-radius: 10px;
  font-family: inherit; font-size: 0.95rem; font-weight: 600; cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease;
}
.profile-edit-cancel { color: var(--ink-soft); background: var(--paper); border: 1px solid var(--line-strong); }
.profile-edit-cancel:hover { border-color: var(--forest); color: var(--ink); }
.profile-edit-save { color: var(--paper-panel); background: var(--forest); border: 1px solid var(--forest); }
.profile-edit-save:hover { background: var(--forest-deep); }
.profile-edit-actions button:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

/* segmented Auto / Light / Dark control */
.profile-segment {
  display: flex; gap: 0.25rem; position: relative;
  background: var(--paper); border: 1px solid var(--line-strong);
  border-radius: 999px; padding: 0.25rem;
}
.profile-seg {
  flex: 1; position: relative; z-index: 1;
  font-family: inherit; font-size: 0.92rem; font-weight: 500;
  color: var(--ink-soft); background: none; border: none; border-radius: 999px;
  padding: 0.5rem 0.4rem; min-height: 2.4rem; cursor: pointer;
  transition: color 0.2s ease;
}
.profile-seg:hover { color: var(--ink); }
.profile-seg.is-active { color: var(--paper-panel); }   /* fill comes from the sliding pill */
.profile-seg:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

/* Sliding green highlight shared by the pill segmented controls (theme / tree /
   weather) and the Learn·Explain·Discuss switcher. The pill is one button wide and
   slides to --seg-i (the active index); --seg-n is the button count. Both are set
   in JS. Buttons sit above it (z-index) and only recolour their text. */
.profile-segment::before,
.learn-modes::before {
  content: "";
  position: absolute; z-index: 0; pointer-events: none;
  top: 0.25rem; bottom: 0.25rem; left: 0.25rem;
  width: calc((100% - 0.5rem - (var(--seg-n, 1) - 1) * 0.25rem) / var(--seg-n, 1));
  border-radius: 999px;
  background: var(--forest);
  transform: translateX(calc(var(--seg-i, 0) * (100% + 0.25rem)));
  transition: transform 0.3s cubic-bezier(0.22, 0.61, 0.36, 1);
}
@media (prefers-reduced-motion: reduce) {
  .profile-segment::before, .learn-modes::before { transition: none; }
}
.learn-modes::before {
  top: 0.18rem;
  bottom: 0.18rem;
  left: 0.18rem;
  width: calc((100% - 0.36rem - (var(--seg-n, 1) - 1) * 0.25rem) / var(--seg-n, 1));
}
.theme-toggle svg { width: 1.2rem; height: 1.2rem; display: block; }
/* show the moon in light mode, the sun in dark mode (icon = current state) */
.theme-toggle .icon-sun { display: none; }
body.is-night .theme-toggle .icon-moon { display: none; }
body.is-night .theme-toggle .icon-sun { display: block; }
.home-about:hover { border-color: var(--forest); background: var(--paper); }
.home-about:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

/* ── Composer gear · model + thinking, in one popover (Learn/Explain/Discuss) ──
   Replaces the old separate thinking toggle and model pill. The wrapper is the
   positioning context for the menu, which opens UPWARD because the composer is
   pinned to the bottom of the screen. */
.composer-settings {
  flex: 0 0 auto;
  align-self: center;
  position: relative;
}
.composer-gear {
  width: 2.7rem;
  height: 2.7rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.composer-gear svg { width: 20px; height: 20px; display: block; }
.composer-gear:hover { border-color: var(--forest); }
.composer-gear:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
/* While the menu is open the gear reads as pressed, matching the send button's
   green so the composer keeps one accent colour. */
.composer-settings.is-open .composer-gear {
  background: var(--leaf);
  border-color: var(--leaf);
  color: var(--paper-panel);
}
body.is-night .composer-settings.is-open .composer-gear {
  background: var(--forest);
  border-color: var(--forest);
}

.composer-menu {
  position: absolute;
  bottom: calc(100% + 0.5rem);
  left: 0;
  z-index: 40;                 /* above the chat log the composer floats over */
  min-width: 15rem;
  padding: 0.4rem;
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.16);
  animation: composer-menu-in 0.14s ease-out;
}
.composer-menu[hidden] { display: none; }
/* Invisible bridge over the gap between the gear and the menu. The menu is a
   child of .composer-settings, so hovering it (or this) never counts as leaving
   the wrapper — without it, crossing the gap would start the close timer. */
.composer-menu::before {
  content: '';
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: 0.6rem;      /* a touch more than the 0.5rem offset above */
}

/* ── The same gear inside the Notebook's vertical toolbar ──────────────────
   The toolbar is a narrow column pinned to the top-left of the canvas, so the
   menu opens to the RIGHT of the gear rather than above it, and the hover
   bridge moves to the left edge to match. */
.nb-settings { position: relative; }
.nb-tool-gear {
  width: 40px;                 /* match .nb-tool, not the composer's 2.7rem */
  height: 40px;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--ink-soft);
}
.nb-tool-gear svg { width: 22px; height: 22px; display: block; }
.nb-tool-gear:hover { background: var(--paper); border-color: transparent; color: var(--ink); }
/* Separated from the drawing tools above it — it changes the tutor, not the pen. */
.nb-settings { margin-top: 2px; padding-top: 6px; border-top: 1px solid var(--line); }
.nb-settings.is-open .nb-tool-gear {
  background: var(--leaf);
  border-color: var(--leaf);
  color: var(--paper-panel);
}
body.is-night .nb-settings.is-open .nb-tool-gear {
  background: var(--forest);
  border-color: var(--forest);
}
.nb-menu {
  bottom: auto;
  top: 0;
  left: calc(100% + 0.5rem);
  right: auto;
}
.nb-menu::before {              /* bridge sits to the LEFT, over the gap */
  top: 0;
  bottom: 0;
  left: auto;
  right: 100%;
  width: 0.6rem;
  height: auto;
}
@keyframes composer-menu-in {
  from { opacity: 0; transform: translateY(4px); }
  to   { opacity: 1; transform: none; }
}
@media (prefers-reduced-motion: reduce) {
  .composer-menu { animation: none; }
}
.composer-menu-head {
  margin: 0;
  padding: 0.35rem 0.55rem 0.25rem;
  font-size: 0.7rem;
  font-weight: 700;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.composer-menu-sep {
  height: 1px;
  margin: 0.35rem 0.25rem;
  background: var(--line);
}
.composer-menu-item {
  width: 100%;
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 0.45rem 0.55rem;
  background: none;
  border: 0;
  border-radius: 8px;
  color: var(--ink);
  font-family: inherit;
  font-size: 0.88rem;
  text-align: left;
  cursor: pointer;
}
.composer-menu-item:hover { background: var(--paper); }
.composer-menu-item:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: -2px; }
.composer-menu-text { flex: 1; display: flex; flex-direction: column; gap: 0.1rem; }
.composer-menu-name { font-weight: 600; line-height: 1.25; }
.composer-menu-note { font-size: 0.76rem; color: var(--ink-faint); line-height: 1.25; }

/* Tick on the selected model. Drawn in CSS so no icon has to be injected per row. */
.composer-menu-check {
  flex: 0 0 auto;
  width: 1.1rem;
  height: 1.1rem;
  opacity: 0;
}
.composer-menu-model.is-on .composer-menu-check {
  opacity: 1;
  background: no-repeat center/contain
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%234c6b46' stroke-width='3' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M20 6L9 17l-5-5'/%3E%3C/svg%3E");
}

/* A model this plan may not use here. Still clickable — the click opens the
   upsell — so it reads as locked rather than broken. */
.composer-menu-model.is-locked .composer-menu-name { color: var(--ink-faint); }
.composer-menu-model.is-locked .composer-menu-note { color: var(--ink-faint); font-style: italic; }
.composer-menu-model.is-locked .composer-menu-check {
  opacity: 1;
  background: no-repeat center/0.85rem
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%238c8068' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='4' y='11' width='16' height='9' rx='2'/%3E%3Cpath d='M8 11V8a4 4 0 0 1 8 0v3'/%3E%3C/svg%3E");
}

/* Thinking row: a small switch rather than a tick, since it is on/off. */
.composer-menu-switch {
  flex: 0 0 auto;
  position: relative;
  width: 2.1rem;
  height: 1.2rem;
  border-radius: 999px;
  background: var(--line-strong);
  transition: background-color 0.18s ease;
}
.composer-menu-switch::after {
  content: '';
  position: absolute;
  top: 2px;
  left: 2px;
  width: calc(1.2rem - 4px);
  height: calc(1.2rem - 4px);
  border-radius: 50%;
  background: var(--paper-panel);
  transition: transform 0.18s ease;
}
.composer-menu-think.is-on .composer-menu-switch { background: var(--leaf); }
.composer-menu-think.is-on .composer-menu-switch::after { transform: translateX(0.9rem); }
@media (prefers-reduced-motion: reduce) {
  .composer-menu-switch, .composer-menu-switch::after { transition: none; }
}

/* the model's streamed "thinking", shown above its answer in chat */
.msg-think {
  margin-bottom: 0.5rem;
  padding: 0.4rem 0.65rem;
  border-left: 2px solid var(--line-strong);
  background: rgba(140,128,104,0.06);
  border-radius: 0 0.4rem 0.4rem 0;
}
.msg-think-label {
  display: flex;
  align-items: center;
  gap: 0.35rem;
  width: 100%;
  margin: 0;
  padding: 0;
  border: none;
  background: none;
  font-family: inherit;
  font-size: 0.66rem;
  text-transform: uppercase;
  letter-spacing: 0.1em;
  color: var(--ink-faint);
  cursor: pointer;
}
.msg-think-label:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.msg-think-caret {
  display: inline-block;
  width: 0.5rem;
  border-left: 4px solid currentColor;
  border-top: 3px solid transparent;
  border-bottom: 3px solid transparent;
  transform: rotate(90deg);            /* points down while expanded */
  transition: transform 0.15s ease;
}
.msg-think.is-collapsed .msg-think-caret { transform: rotate(0deg); }   /* points right */
.msg-think-text {
  font-size: 0.85rem;
  font-style: italic;
  color: var(--ink-faint);
  white-space: pre-wrap;
  line-height: 1.4;
  margin-top: 0.2rem;
  max-height: 11rem;
  overflow-y: auto;
  opacity: 1;
  /* animate open/closed so condensing doesn't snap the bubble height */
  transition: max-height 0.3s ease, opacity 0.22s ease, margin-top 0.3s ease;
}
.msg-think.is-collapsed .msg-think-text {
  max-height: 0;
  margin-top: 0;
  opacity: 0;
  overflow: hidden;
  pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .msg-think-text { transition: none; }
}

/* ── Our Mission · standalone page ── */

.about-overlay {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: var(--paper);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}
.about-overlay[hidden] { display: none; }

.about-bar {
  position: sticky;
  top: 0;
  display: flex;
  align-items: center;
  gap: 0.75rem;
  height: var(--bar-h);
  padding: 0 1rem;
  background: var(--paper-panel);
  border-bottom: 1px solid var(--line);
}
.about-back {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 2.4rem;
  height: 2.4rem;
  background: none;
  border: none;
  border-radius: 8px;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.18s ease;
}
.about-back:hover { background: var(--paper); }
.about-back svg { width: 22px; height: 22px; }
.about-bar-title {
  font-size: 1.15rem;
  font-weight: 600;
  color: var(--forest-deep);
}

.about-content {
  max-width: 44rem;
  margin: 0 auto;
  padding: 2rem 1.5rem 3rem;
}
.about-title {
  font-weight: 600;
  font-size: clamp(2.25rem, 8vw, 3rem);
  line-height: 1.1;
  color: var(--forest-deep);
  margin-bottom: 0.75rem;
}
.about-lead {
  font-style: italic;
  font-size: 1.2rem;
  line-height: 1.5;
  color: var(--ink-soft);
  margin-bottom: 1.75rem;
  text-wrap: pretty;
}
.about-h {
  font-weight: 600;
  font-size: 1.35rem;
  color: var(--forest-deep);
  margin: 2rem 0 0.6rem;
}
.about-content p {
  font-size: 1.0625rem;
  line-height: 1.65;
  color: var(--ink);
  margin-bottom: 1rem;
  text-wrap: pretty;
}

.about-stats {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 0.85rem;
  margin: 1.5rem 0 1rem;
}
.about-stat {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  padding: 1.1rem 1.2rem;
  background: var(--paper-panel);
  border: 1px solid var(--line);
  border-radius: 12px;
}
.about-stat-num {
  font-weight: 600;
  font-size: 2rem;
  line-height: 1;
  color: var(--forest);
}
.about-stat-label {
  font-size: 0.9rem;
  line-height: 1.35;
  color: var(--ink-soft);
}
.about-note {
  font-size: 0.85rem !important;
  color: var(--ink-faint) !important;
  margin-top: 0.25rem;
}

/* ── Learn · chat ────────────────────────────────────────── */

.chat-page.active {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

/* Learn / Explain / Discuss mode switcher — shares the chat's max width */
.learn-mode-bar {
  box-sizing: border-box;
  width: 100%;
  max-width: clamp(44rem, 70vw, 58rem);
  margin: 0 auto;
  padding: 0.5rem 1.25rem 0.85rem;
  display: flex;
  align-items: center;
  gap: 0.65rem;
  /* Pin the mode bubbles to the top of the chat while messages scroll under them. */
  position: sticky;
  top: 0;
  z-index: 20;
}
/* The floating bubbles keep their own backgrounds; the area around them stays
   transparent so no backdrop box shows in either theme. */
.learn-modes {
  flex: 1 1 auto;
  min-width: 0;
  margin: 0;
  display: flex;
  gap: 0.25rem;
  position: relative;
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  padding: 0.18rem;
}
.learn-new-chat-wrap {
  flex: 0 0 auto;
  position: relative;
  display: inline-flex;
  align-items: center;
}
.learn-new-chat {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 2.5rem;
  height: 2.5rem;
  padding: 0;
  color: var(--forest-deep);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  cursor: pointer;
  transition: background-color 0.18s ease, border-color 0.18s ease, color 0.18s ease;
}
.learn-new-chat svg { width: 1.05rem; height: 1.05rem; flex: none; display: block; }
.learn-new-chat:hover { border-color: var(--forest); color: var(--forest); }
.learn-new-chat:active { background: var(--paper-edge); }
.learn-new-chat:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.learn-new-chat-label {
  position: absolute;
  left: 100%;
  top: 50%;
  margin-left: 0.5rem;
  white-space: nowrap;
  font-size: 0.8rem;
  color: var(--ink-soft);
  opacity: 0;
  visibility: hidden;
  transform: translateY(-50%) translateX(-8px);
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s ease;
  pointer-events: none;
}
.learn-new-chat-wrap:hover .learn-new-chat-label,
.learn-new-chat:focus-visible ~ .learn-new-chat-label {
  opacity: 1;
  visibility: visible;
  transform: translateY(-50%) translateX(0);
}
.learn-mode {
  flex: 1;
  position: relative;
  z-index: 1;
  font-family: inherit;
  font-size: 0.92rem;
  font-weight: 500;
  color: var(--ink-soft);
  background: none;
  border: none;
  border-radius: 999px;
  padding: 0.32rem 0.4rem;
  min-height: 2.15rem;
  cursor: pointer;
  transition: color 0.2s ease;
}
.learn-mode:hover { color: var(--ink); }
.learn-mode.is-active { color: var(--paper-panel); }   /* fill comes from the sliding pill */
.learn-mode:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

/* A hidden chat block must collapse — .chat sets display:flex, which would
   otherwise win over the [hidden] attribute. */
.chat[hidden] { display: none; }

.chat {
  width: 100%;
  /* Grow with the viewport when there's room (smaller side gaps on wide screens),
     but never below the old 44rem and capped at 58rem to keep lines readable. */
  max-width: clamp(44rem, 70vw, 58rem);
  margin: 0 auto;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 1.75rem 1.25rem 0;
}

.chat-header .screen-intro { margin-bottom: 1.25rem; }

/* highlight while dragging a photo onto the Learn chat (Gemma vision) */
.chat.chat-dragover {
  border-radius: 14px;
  box-shadow: inset 0 0 0 2px var(--forest);
  background: rgba(52, 80, 58, 0.05);
}

.chat-log {
  flex: 1;
  display: flex;
  flex-direction: column;
  gap: 1.1rem;
  padding-bottom: 1.25rem;
}

.msg {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  max-width: 86%;
}
.msg.assistant { align-self: flex-start; }
.msg.user { align-self: flex-end; align-items: flex-end; }

.msg-role {
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
  padding: 0 0.3rem;
}

.msg-body {
  font-size: 1.0625rem;
  line-height: 1.6;
  padding: 0.7rem 0.95rem;
  border: 1px solid var(--line);
  border-radius: 12px;
  white-space: pre-wrap;
  word-break: break-word;
}
.msg.assistant .msg-body {
  background: var(--paper-panel);
  color: var(--ink);
  border-top-left-radius: 4px;
}
.msg.user .msg-body {
  background: rgba(52, 80, 58, 0.10);
  border-color: var(--line-strong);
  color: var(--ink);
  border-top-right-radius: 4px;
}

/* Rendered Markdown/math from the model (assistant bubbles + quiz prompts) */
.msg.assistant .msg-body { white-space: normal; }
.msg-body p, .q-prompt p, .q-rich p { margin: 0 0 0.55rem; }
.msg-body p:first-child, .q-prompt p:first-child, .q-rich p:first-child { margin-top: 0; }
.msg-body p:last-child, .q-prompt p:last-child, .q-rich p:last-child { margin-bottom: 0; }
.msg-body h1, .msg-body h2, .msg-body h3,
.msg-body h4, .msg-body h5, .msg-body h6 {
  font-weight: 600;
  line-height: 1.25;
  margin: 0.8rem 0 0.35rem;
  color: var(--forest-deep);
}
.msg-body h1 { font-size: 1.2rem; }
.msg-body h2 { font-size: 1.12rem; }
.msg-body h3 { font-size: 1.04rem; }
.msg-body h4, .msg-body h5, .msg-body h6 { font-size: 0.98rem; }
.msg-body ul, .msg-body ol { margin: 0.35rem 0 0.6rem; padding-left: 1.4rem; }
.msg-body li { margin: 0.15rem 0; }
.msg-body hr { border: none; border-top: 1px solid var(--line); margin: 0.75rem 0; }
.msg-body strong, .q-prompt strong, .q-rich strong { font-weight: 600; }
.msg-body code, .q-prompt code, .q-rich code {
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.92em;
  background: rgba(140, 128, 104, 0.14);
  padding: 0.05rem 0.3rem;
  border-radius: 4px;
}
.msg-body pre.code-block, .q-prompt pre.code-block, .q-rich pre.code-block {
  margin: 0.5rem 0 0.65rem;
  padding: 0.65rem 0.75rem;
  overflow-x: auto;
  font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 0.88em;
  line-height: 1.45;
  background: rgba(140, 128, 104, 0.12);
  border: 1px solid var(--line);
  border-radius: 8px;
  white-space: pre-wrap;
  word-break: break-word;
}
.msg-body pre.code-block code, .q-prompt pre.code-block code, .q-rich pre.code-block code {
  background: none;
  padding: 0;
}
.msg-body blockquote, .q-prompt blockquote, .q-rich blockquote {
  margin: 0.45rem 0 0.6rem;
  padding: 0.35rem 0 0.35rem 0.85rem;
  border-left: 3px solid var(--forest);
  color: var(--ink-soft);
}
.msg-body .math-inline, .q-prompt .math-inline, .q-rich .math-inline {
  font-family: ui-serif, 'Iowan Old Style', 'Palatino Linotype', Palatino, serif;
  font-style: italic;
  letter-spacing: 0.01em;
  white-space: nowrap;
}
.msg-body .math-frac, .q-prompt .math-frac, .q-rich .math-frac,
.msg-body .math-sqrt, .q-prompt .math-sqrt, .q-rich .math-sqrt {
  font-style: normal;
}
.math-frac {
  display: inline-flex;
  flex-direction: column;
  align-items: center;
  vertical-align: middle;
  margin: 0 0.14em;
  font-size: 0.9em;
  line-height: 1.1;
}
.math-frac-num {
  padding: 0 0.18em 0.06em;
  border-bottom: 1px solid currentColor;
}
.math-frac-den {
  padding: 0.06em 0.18em 0;
}
.math-sqrt {
  display: inline-flex;
  align-items: stretch;
  margin: 0 0.06em;
  font-style: normal;
}
.math-sqrt::before {
  content: '√';
  flex: 0 0 auto;
  align-self: flex-end;
  padding-right: 0.06em;
  line-height: 1;
  font-size: 1.08em;
}
.math-sqrt-inner {
  border-top: 1px solid currentColor;
  padding: 0.02em 0.14em 0;
  align-self: flex-start;
}
.msg-body .math-block, .q-prompt .math-block, .q-rich .math-block {
  margin: 0.55rem 0 0.65rem;
  padding: 0.45rem 0.65rem;
  text-align: center;
  font-family: ui-serif, 'Iowan Old Style', 'Palatino Linotype', Palatino, serif;
  font-size: 1.05em;
  font-style: italic;
  background: rgba(140, 128, 104, 0.08);
  border-radius: 8px;
  overflow-x: auto;
}
.msg-body del { opacity: 0.72; }
.msg-body a, .q-prompt a, .q-rich a {
  color: var(--forest-deep);
  text-decoration: underline;
  text-underline-offset: 2px;
}

/* Composer pinned above the tab bar */
.composer {
  position: sticky;
  bottom: 0;
  display: flex;
  gap: 0.6rem;
  align-items: flex-end;
  padding: 0.75rem 0 1rem;
  background: var(--paper);
  border-top: 1px solid var(--line);
}

.composer-input {
  flex: 1;
  resize: none;
  font-family: inherit;
  font-size: 1rem;            /* 16px — avoids mobile zoom, stays readable */
  line-height: 1.5;
  color: var(--ink);
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  padding: 0.65rem 0.85rem;
  max-height: 8rem;
  overflow-y: auto;
}
.composer-input::placeholder { color: var(--ink-faint); }
.composer-input:focus {
  outline: none;
  border-color: var(--forest);
}

.composer-mic {
  flex: 0 0 auto;
  align-self: center;
  width: 2.7rem;
  height: 2.7rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
.composer-mic:hover { border-color: var(--forest); }
.composer-mic svg { width: 20px; height: 20px; }
.composer-mic:focus-visible {
  outline: 2px solid var(--forest-deep);
  outline-offset: 2px;
}
.composer-mic.recording {
  background: var(--forest);
  border-color: var(--forest);
  color: var(--paper-panel);
}

/* Photo attach button — only shown when a vision model (Gemma) is selected */
.composer-img {
  flex: 0 0 auto;
  align-self: center;
  width: 2.7rem;
  height: 2.7rem;
  display: none;
  align-items: center;
  justify-content: center;
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  color: var(--ink);
  cursor: pointer;
  transition: background-color 0.18s ease, color 0.18s ease, border-color 0.18s ease;
}
body.model-gemma .composer-img { display: flex; }
.composer-img:hover { border-color: var(--forest); }
.composer-img svg { width: 20px; height: 20px; }
.composer-img:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

/* let the attachment preview sit on its own row above the input */
.composer { flex-wrap: wrap; }
.composer-attach {
  flex: 1 0 100%;
  display: flex;
  align-items: center;
  gap: 0.5rem;
}
.composer-attach[hidden] { display: none; }
/* a non-vision model can't use a photo, so hide any leftover preview for it */
body:not(.model-gemma) .composer-attach { display: none; }
.composer-attach-img {
  height: 3rem;
  max-width: 6rem;
  object-fit: cover;
  border-radius: 8px;
  border: 1px solid var(--line-strong);
}
.composer-attach-remove {
  width: 1.4rem;
  height: 1.4rem;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 1rem;
  line-height: 1;
  color: var(--ink-soft);
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  cursor: pointer;
}
.composer-attach-remove:hover { color: var(--ink); border-color: var(--forest); }

/* a photo shown inside a chat bubble */
.msg-photo {
  display: block;
  max-width: 16rem;
  max-height: 16rem;
  margin-top: 0.5rem;
  border-radius: 10px;
  border: 1px solid var(--line);
}

.composer-send {
  flex: 0 0 auto;
  align-self: center;   /* match the mic/photo buttons (composer is align-items: flex-end) */
  width: 2.7rem;
  height: 2.7rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--forest);
  border: none;
  border-radius: 10px;
  color: var(--paper-panel);
  cursor: pointer;
  transition: background-color 0.18s ease;
}
.composer-send:hover { background: var(--forest-deep); }
.composer-send:active { background: var(--forest-deep); }
.composer-send svg { width: 20px; height: 20px; }
/* stop button while a reply is generating */
.composer-send.is-stop { background: var(--incorrect); }
.composer-send.is-stop:hover { background: var(--incorrect); filter: brightness(0.92); }
.composer-send:focus-visible {
  outline: 2px solid var(--forest-deep);
  outline-offset: 2px;
}

/* ── Bottom tab bar ──────────────────────────────────────── */

.tabbar {
  position: fixed;
  left: 0; right: 0; bottom: 0;
  height: calc(var(--tab-h) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  display: flex;
  background: var(--paper-panel);
  border-top: 1px solid var(--line);
  z-index: 20;
}

.tab {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.2rem;
  min-height: 44px;
  background: none;
  border: none;
  border-top: 2px solid transparent;
  font-family: inherit;
  font-size: 0.72rem;
  letter-spacing: 0.02em;
  color: var(--ink-faint);
  cursor: pointer;
  transition: color 0.18s ease, background-color 0.18s ease;
}

.tab svg { width: 24px; height: 24px; display: block; }

.tab:hover { color: var(--ink); }
.tab:active { background: var(--paper-edge); }

.tab.active {
  color: var(--forest-deep);
  /* the green line is now drawn by the sliding .tab-indicator below */
}

/* Sliding active-tab indicator. The bar is positioned by its left + right
   edges (tabs are equal flex:1 fifths) and simply slides between tabs — both
   edges move together with one ease, so it accelerates out and decelerates in
   with no stretch. */
.tab-indicator {
  position: absolute;
  top: 0;
  height: 2px;
  /* --tab-n = number of tabs (3: Learn / Notebook / Review). The bar is one
     slot wide and slides between equal flex slots. Update --tab-n if tabs change. */
  left:  calc(var(--tab-i, 0) * (100% / var(--tab-n, 3)));
  right: calc((var(--tab-n, 3) - 1 - var(--tab-i, 0)) * (100% / var(--tab-n, 3)));
  background: var(--forest);
  border-radius: 1px;
  pointer-events: none;
  transition: left 0.26s cubic-bezier(0.4, 0, 0.2, 1),
              right 0.26s cubic-bezier(0.4, 0, 0.2, 1),
              opacity 0.18s ease;
}

/* No tab is selected on the home screen — hide the bar there. */
body.home-active .tab-indicator { opacity: 0; }

@media (prefers-reduced-motion: reduce) {
  .tab-indicator {
    transition: left 0.2s ease, right 0.2s ease, opacity 0.18s ease;
  }
}

/* ── Focus (keyboard) ── */

.tab:focus-visible,
.wordmark:focus-visible {
  outline: 2px solid var(--forest);
  outline-offset: -2px;
}

/* ── Review · quiz builder ──────────────────────────────── */

.review-view { display: block; }
.review-view[hidden] { display: none; }

.quiz-builder {
  display: flex;
  flex-direction: column;
  gap: 1.6rem;
}

.qb-field { display: flex; flex-direction: column; gap: 0.6rem; }

.qb-label {
  font-size: 0.7rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.qb-opt { text-transform: none; letter-spacing: 0; font-style: italic; }

.qb-input {
  resize: none;
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink);
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  padding: 0.7rem 0.85rem;
}
.qb-input::placeholder { color: var(--ink-faint); }
.qb-input:focus { outline: none; border-color: var(--forest); }

/* file drop / browse */
.qb-drop {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 0.65rem;
  font-family: inherit;
  font-size: 0.95rem;
  color: var(--ink-soft);
  background: var(--paper-panel);
  border: 1px dashed var(--line-strong);
  border-radius: 10px;
  padding: 1.1rem;
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}
.qb-drop:hover { border-color: var(--forest); color: var(--forest-deep); }
.qb-drop.qb-dragover { border-color: var(--forest); background: rgba(52, 80, 58, 0.08); }
.qb-drop-head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.55rem;
}
.qb-drop svg { width: 20px; height: 20px; flex-shrink: 0; }

.qb-count { color: var(--ink-faint); font-weight: 600; }

/* Squircle preview tiles inside the drop zone. Size is ALSO pinned in pixels
   inline (on the tile and the <img>), so a preview can never render at an
   image's native resolution even if this stylesheet fails to load/apply. */
.qb-previews {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: center;
  gap: 0.45rem;
  margin: 0;
  padding: 0;
}
.qb-previews:empty { display: none; }
.qb-preview {
  position: relative;
  flex: 0 0 auto;
  width: 46px; height: 46px;
  max-width: 46px; max-height: 46px;
  display: inline-flex; align-items: center; justify-content: center;
  border-radius: 28%;
  overflow: hidden;
  border: 1.5px solid var(--line-strong);
  background: var(--paper-edge);
  color: var(--forest);
  animation: qb-file-in 0.16s ease;
}
@keyframes qb-file-in { from { opacity: 0; transform: scale(0.9); } to { opacity: 1; transform: none; } }
.qb-preview::after {
  content: '';
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: rgba(100, 100, 100, 0.32);
  opacity: 0;
  transition: opacity 0.15s ease;
  pointer-events: none;
}
.qb-preview:hover::after { opacity: 1; }
.qb-preview img { width: 100%; height: 100%; object-fit: cover; display: block; border-radius: inherit; }
.qb-preview-icon { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; }
.qb-preview-remove {
  position: absolute;
  inset: 0;
  z-index: 1;
  display: flex; align-items: center; justify-content: center;
  padding: 0; border: none;
  background: transparent;
  color: #fff;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.15s ease;
}
.qb-preview:hover .qb-preview-remove { opacity: 1; }
.qb-preview-remove svg { filter: drop-shadow(0 0 2px rgba(0, 0, 0, 0.55)); }

/* segmented length control */
.qb-seg {
  display: inline-flex;
  align-self: flex-start;
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  overflow: hidden;
}
.qb-seg button {
  font-family: inherit;
  font-size: 1rem;
  min-width: 3.2rem;
  padding: 0.55rem 0;
  background: var(--paper-panel);
  border: none;
  border-left: 1px solid var(--line);
  color: var(--ink-soft);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.qb-seg button:first-child { border-left: none; }
.qb-seg button:hover { background: var(--paper-edge); }
.qb-seg button.active { background: var(--forest); color: var(--paper-panel); }

/* multi-select type chips */
.qb-chips { display: flex; flex-wrap: wrap; gap: 0.5rem; }
.qb-chips button {
  font-family: inherit;
  font-size: 0.95rem;
  padding: 0.5rem 0.85rem;
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 999px;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, border-color 0.15s ease;
}
.qb-chips button:hover { border-color: var(--forest); }
.qb-chips button.active {
  background: rgba(52, 80, 58, 0.12);
  border-color: var(--forest);
  color: var(--forest-deep);
  font-weight: 600;
}

.qb-error {
  font-size: 0.82rem;
  color: var(--incorrect);
}

.qb-generate {
  align-self: flex-start;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 9.5rem;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 600;
  letter-spacing: 0.01em;
  color: var(--paper-panel);
  background: var(--forest);
  border: none;
  border-radius: 10px;
  padding: 0.75rem 1.4rem;
  cursor: pointer;
  transition: background-color 0.18s ease;
}
.qb-generate:hover { background: var(--forest-deep); }
.qb-generate:disabled { opacity: 0.55; cursor: default; }
.qb-generate:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.qb-generate-label { display: inline-flex; align-items: center; }
.qb-generate .qb-generate-loader { display: none; }
.qb-generate.is-loading .qb-generate-label { display: none; }
.qb-generate.is-loading .qb-generate-loader { display: inline-flex; }
.qb-generate.is-loading { opacity: 1; }
.qb-generate .dot-loader span { background: var(--paper-panel); }

.qb-generate-row {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  align-self: flex-start;
}
.dot-loader { display: inline-flex; align-items: center; gap: 0.3rem; }
.dot-loader[hidden] { display: none; }
.dot-loader span {
  width: 0.42rem;
  height: 0.42rem;
  border-radius: 50%;
  background: var(--forest);
  opacity: 0.3;
  animation: dot-bounce 1s infinite ease-in-out;
}
.dot-loader span:nth-child(2) { animation-delay: 0.16s; }
.dot-loader span:nth-child(3) { animation-delay: 0.32s; }
.profile-feedback-send .pf-upgrade-loader {
  position: absolute;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
}
.profile-feedback-send .dot-loader span { background: var(--paper-panel); }
@keyframes dot-bounce {
  0%, 80%, 100% { opacity: 0.3; transform: translateY(0); }
  40% { opacity: 1; transform: translateY(-0.2rem); }
}
@media (prefers-reduced-motion: reduce) {
  .dot-loader span { animation: none; opacity: 0.6; }
}

/* ── Review · taking the quiz ── */

.quiz-top {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 1rem;
  margin-bottom: 1.5rem;
}
.quiz-title {
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--forest-deep);
  line-height: 1.2;
}
.quiz-back {
  flex: 0 0 auto;
  font-family: inherit;
  font-size: 0.9rem;
  color: var(--ink-faint);
  background: none;
  border: none;
  cursor: pointer;
  text-decoration: underline;
}
.quiz-back:hover { color: var(--forest-deep); }

.q-card {
  border: 1px solid var(--line);
  border-radius: 12px;
  background: var(--paper-panel);
  padding: 1.1rem 1.2rem;
  margin-bottom: 1.1rem;
}
.q-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.8rem;
  margin-bottom: 0.55rem;
}
.q-num {
  font-size: 0.66rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.q-type {
  font-size: 0.66rem;
  letter-spacing: 0.04em;
  font-style: italic;
  color: var(--ink-faint);
}
.q-prompt {
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--ink);
  margin-bottom: 0.9rem;
}

.q-options { display: flex; flex-direction: column; gap: 0.5rem; }
.q-option {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.55rem 0.7rem;
  border: 1px solid var(--line);
  border-radius: 9px;
  background: var(--paper);
  cursor: pointer;
  transition: border-color 0.12s ease, background-color 0.12s ease;
}
.q-option:hover { border-color: var(--line-strong); }
.q-option input { margin-top: 0.28rem; accent-color: var(--forest); flex: 0 0 auto; }
.q-option span.q-rich { display: inline; font-size: 1rem; line-height: 1.5; }
.q-answer .q-rich { display: inline; }

.q-text {
  width: 100%;
  resize: vertical;
  font-family: inherit;
  font-size: 1rem;
  line-height: 1.5;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  padding: 0.6rem 0.75rem;
}
.q-text:focus { outline: none; border-color: var(--forest); }
input.q-text { resize: none; }

/* ── Review · results ── */

.quiz-score {
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--forest-deep);
  margin-bottom: 0.4rem;
}
.quiz-score small {
  display: block;
  font-size: 0.95rem;
  font-weight: 400;
  font-style: italic;
  color: var(--ink-soft);
  margin-top: 0.3rem;
}
#quiz-review { margin: 1.5rem 0; }

.q-card.correct {
  border-color: var(--correct);
  box-shadow: inset 0 0 0 1px var(--correct);   /* reads as a clear ~2px outline */
  background: rgba(63, 122, 78, 0.06);
}
.q-card.incorrect {
  border-color: var(--incorrect);
  box-shadow: inset 0 0 0 1px var(--incorrect);
  background: rgba(180, 81, 63, 0.06);
}
.q-result {
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
}
.q-result.ok { color: var(--forest-deep); }
.q-result.no { color: #9a5a3a; }
.q-result.review { color: var(--ink-faint); }
.q-answer {
  margin-top: 0.7rem;
  font-size: 0.95rem;
  line-height: 1.5;
  color: var(--ink-soft);
}
.q-answer strong { color: var(--ink); font-weight: 600; }
.q-yours { margin-top: 0.35rem; }

/* ── Motion preference ── */

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* ── Notebook · interactive canvas ───────────────────────── */

.notebook-page.active {
  display: flex;
  flex-direction: column;
  min-height: 100%;
}

.notebook {
  width: 100%;
  max-width: 60rem;
  margin: 0 auto;
  flex: 1;
  display: flex;
  flex-direction: column;
  min-height: 0;
  padding: 1.75rem 1.25rem 1.25rem;
  /* Positioned so the floating tutor panel + Next button (absolute) anchor to the
     notebook even outside OS fullscreen. In OS fullscreen the UA's :fullscreen rule
     (position: fixed !important) wins, so it still fills the viewport. */
  position: relative;
}

.nb-head { flex: 0 0 auto; }
.nb-head .screen-intro { margin-bottom: 1rem; }

.nb-stage-wrap {
  position: relative;
  flex: 1;
  min-height: 22rem;
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  overflow: hidden;
  background: var(--paper-panel);
}

.nb-stage {
  position: absolute;
  inset: 0;
  /* ruled grid is drawn on the canvas (see drawGrid) so it scales smoothly with
     zoom and the 1px lines stay crisp instead of flickering. */
}

/* infinite-canvas layer: items live here and pan as a group */
.nb-world {
  position: absolute;
  top: 0;
  left: 0;
  transform: translate(0px, 0px);
  will-change: transform;
}

.nb-grid-canvas {
  position: absolute;
  inset: 0;
  z-index: 0;            /* grid sits behind items (and behind the ink) */
  pointer-events: none;
}
.nb-draw {
  position: absolute;
  inset: 0;
  z-index: 4;            /* drawing sits on top of items */
  pointer-events: none;  /* enabled only in pen / eraser mode */
  touch-action: none;
}

/* tool-driven cursors */
.nb-stage-wrap[data-tool="text"]   .nb-stage { cursor: text; }
.nb-stage-wrap[data-tool="pan"]    .nb-stage { cursor: grab; }
.nb-stage-wrap.nb-panning          .nb-stage { cursor: grabbing; }
.nb-stage-wrap[data-tool="pen"]    .nb-draw,
.nb-stage-wrap[data-tool="eraser"] .nb-draw { pointer-events: auto; }
.nb-stage-wrap[data-tool="pen"]    .nb-stage,
.nb-stage-wrap[data-tool="eraser"] .nb-stage,
.nb-stage-wrap[data-tool="pen"]    .nb-draw,
.nb-stage-wrap[data-tool="eraser"] .nb-draw { cursor: none; }

/* circle brush cursor (grows with size) */
.nb-cursor {
  position: absolute;
  display: none;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  pointer-events: none;
  z-index: 9;
  border: 1.5px solid var(--ink);
  background: rgba(43, 38, 24, 0.10);
}
.nb-cursor.nb-cursor-erase {
  border-style: dashed;
  border-color: var(--forest);
  background: rgba(52, 80, 58, 0.08);
}

/* items are only interactive with the select tool */
.nb-stage-wrap:not([data-tool="select"]) .nb-world { pointer-events: none; }

.nb-hint {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  max-width: 24rem;
  text-align: center;
  font-style: italic;
  color: var(--ink-faint);
  pointer-events: none;
  padding: 0 1rem;
  z-index: 1;
  opacity: 1;
  transition: opacity 0.45s ease;
}
.nb-hint.is-hidden { opacity: 0; }

/* ── Items (text + image) ── */

.nb-item {
  position: absolute;
  z-index: 2;
  border: 1px solid transparent;
  border-radius: 6px;
}
.nb-stage-wrap[data-tool="select"] .nb-item:hover { border-color: var(--line-strong); }

.nb-text {
  box-sizing: border-box;
  min-width: 2ch;
  padding: 0.25rem 0.4rem;
  font-family: 'Spectral', Georgia, serif;
  font-size: 1.0625rem;
  line-height: 1.5;
  color: var(--ink);
  outline: none;
  white-space: pre;            /* grow rightward; only Enter makes a new line */
  cursor: default;
}
/* once a width is set with the side handle, text reflows to fit the box */
.nb-text.wrap {
  white-space: pre-wrap;
  overflow-wrap: break-word;
  word-break: break-word;
}
.nb-item.editing .nb-text { cursor: text; }
/* Text the AI sketches onto the canvas: a handwriting font + a slight tilt so it
   reads like the model is jotting alongside you, not pasting a label. */
.nb-item[data-author="ai"] .nb-text {
  font-family: 'Caveat', 'Bradley Hand', 'Segoe Print', cursive;
  line-height: 1.25;
  transform: rotate(-1.2deg);
  transform-origin: left top;
}
.nb-text:empty::before {
  content: 'Type…';
  color: var(--ink-faint);
}

.nb-img {
  display: block;
  max-width: none;
  user-select: none;
  -webkit-user-drag: none;
  border-radius: 4px;
}
.nb-stage-wrap[data-tool="select"] .nb-item[data-type="image"] { cursor: move; }

/* ── Selection box + resize handles ── */

.nb-selbox {
  position: absolute;
  z-index: 6;
  border: 1px solid var(--forest);
  background: rgba(52, 80, 58, 0.06);
  pointer-events: none;       /* box body transparent; handles re-enable */
}
.nb-selbox .nb-grab {
  position: absolute;
  width: 12px;
  height: 12px;
  background: var(--paper-panel);
  border: 1.5px solid var(--forest);
  border-radius: 2px;
  pointer-events: auto;
}
.nb-grab[data-h="nw"] { top: -7px;  left: -7px;  cursor: nwse-resize; }
.nb-grab[data-h="ne"] { top: -7px;  right: -7px; cursor: nesw-resize; }
.nb-grab[data-h="se"] { bottom: -7px; right: -7px; cursor: nwse-resize; }
.nb-grab[data-h="sw"] { bottom: -7px; left: -7px;  cursor: nesw-resize; }
/* side handle for setting text-box width — only shown for a selected text box */
.nb-grab[data-h="e"] { top: 50%; right: -7px; transform: translateY(-50%); cursor: ew-resize; }
.nb-selbox .nb-grab[data-h="e"] { display: none; }
.nb-selbox.is-text .nb-grab[data-h="e"] { display: block; }

/* marquee selection rectangle */
.nb-marquee {
  position: absolute;
  z-index: 7;
  border: 1px dashed var(--forest);
  background: rgba(52, 80, 58, 0.07);
  pointer-events: none;
}

/* ── Tool option sliders ── */

.nb-options {
  position: absolute;
  left: 14px;
  bottom: 14px;
  z-index: 10;
  display: none;
  flex-direction: column;
  gap: 0.5rem;
  padding: 0.7rem 0.85rem;
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  box-shadow: 0 2px 8px rgba(43, 38, 24, 0.10);
}
.nb-stage-wrap[data-tool="pen"]    .nb-options,
.nb-stage-wrap[data-tool="eraser"] .nb-options { display: flex; }
.nb-opt { display: none; flex-direction: column; gap: 0.5rem; }
.nb-stage-wrap[data-tool="pen"]    .nb-opt-pen    { display: flex; }
.nb-stage-wrap[data-tool="eraser"] .nb-opt-eraser { display: flex; }
.nb-stage-wrap.nb-opts-hidden .nb-options { display: none; }

.nb-size { display: flex; align-items: center; gap: 0.75rem; }

/* circular well + live size preview */
.nb-preview {
  width: 40px; height: 40px;
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--line-strong);
  border-radius: 50%;
  background: var(--paper);
  box-shadow: inset 0 1px 3px rgba(43, 38, 24, 0.12);
  overflow: hidden;
}
.nb-dot {
  width: 3px; height: 3px;
  background: var(--ink);
  border-radius: 50%;
  transition: width 0.08s ease, height 0.08s ease;
}
.nb-ring {
  width: 28px; height: 28px;
  border: 1.5px solid var(--forest);
  background: rgba(52, 80, 58, 0.07);
  border-radius: 50%;
  transition: width 0.08s ease, height 0.08s ease;
}

.nb-size-ctl { display: flex; flex-direction: column; gap: 0.4rem; }
.nb-size-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 0.8rem;
}
.nb-size-label {
  font-size: 0.64rem;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ink-faint);
}
.nb-size-val {
  font-family: 'Spectral', Georgia, serif;
  font-size: 1.1rem;
  font-weight: 600;
  line-height: 1;
  color: var(--forest-deep);
  font-variant-numeric: tabular-nums;
}
.nb-size-val::after {
  content: ' px';
  font-size: 0.58rem;
  letter-spacing: 0.08em;
  color: var(--ink-faint);
}

.nb-mini {
  display: flex;
  flex-direction: column;
  gap: 0.3rem;
  font-size: 0.62rem;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ink-faint);
}

/* pen color swatches */
.nb-colors { display: flex; align-items: center; gap: 0.45rem; margin-top: 0.2rem; }
.nb-color {
  width: 1.3rem;
  height: 1.3rem;
  padding: 0;
  border-radius: 50%;
  background: var(--sw);
  border: 2px solid var(--paper-panel);
  box-shadow: 0 0 0 1px var(--line-strong);
  cursor: pointer;
  transition: transform 0.12s ease, box-shadow 0.12s ease;
}
/* the black "Ink" swatch is invisible on the dark night panel — show it light to
   match how its strokes render at night (!important beats the inline --sw). */
body.is-night .nb-color[data-color="#2b2618"] { --sw: #e7e9f1 !important; }
.nb-color:hover { transform: scale(1.12); }
.nb-color.is-active { box-shadow: 0 0 0 2px var(--forest); }
.nb-color:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

/* slim, themed slider */
.nb-options input[type="range"] {
  -webkit-appearance: none;
  appearance: none;
  width: 150px;
  height: 3px;
  border-radius: 3px;
  background: var(--line-strong);
  cursor: pointer;
}
.nb-options input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--paper-panel);
  border: 1.5px solid var(--forest);
  box-shadow: 0 1px 2px rgba(43, 38, 24, 0.22);
}
.nb-options input[type="range"]::-moz-range-thumb {
  width: 15px; height: 15px;
  border-radius: 50%;
  background: var(--paper-panel);
  border: 1.5px solid var(--forest);
}

/* ── Floating toolbar ── */

.nb-toolbar {
  position: absolute;
  top: 14px;
  left: 14px;
  z-index: 10;
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px;
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: 0 2px 8px rgba(43, 38, 24, 0.10);
}

.nb-grip {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 18px;
  background: none;
  border: none;
  color: var(--ink-faint);
  cursor: grab;
}
.nb-grip:active { cursor: grabbing; }
.nb-grip svg { width: 20px; height: 14px; }

.nb-tool {
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.nb-tool:hover { background: var(--paper-edge); color: var(--ink); }
.nb-tool.active {
  background: rgba(52, 80, 58, 0.12);
  border-color: var(--forest);
  color: var(--forest-deep);
}
.nb-tool svg { width: 22px; height: 22px; }

/* ── Expand / fullscreen button ── */

.nb-expand {
  position: absolute;
  top: 14px;
  right: 14px;
  z-index: 10;
  width: 38px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease;
}
.nb-expand:hover { background: var(--paper-edge); color: var(--forest-deep); }
.nb-expand svg { width: 20px; height: 20px; }

/* undo / redo, pinned top-right just left of the expand button */
.nb-history {
  position: absolute;
  top: 14px;
  right: 60px;
  z-index: 10;
  display: flex;
  gap: 6px;
}
.nb-hist-btn {
  width: 34px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  color: var(--ink-soft);
  cursor: pointer;
  transition: background-color 0.15s ease, color 0.15s ease, opacity 0.15s ease;
}
.nb-hist-btn:hover { background: var(--paper-edge); color: var(--forest-deep); }
.nb-hist-btn svg { width: 20px; height: 20px; }
.nb-hist-btn:disabled { opacity: 0.32; cursor: default; pointer-events: none; }
.nb-hist-btn:focus-visible { outline: 2px solid var(--forest); outline-offset: 1px; }

/* fullscreen fills the screen with paper */
/* ── Full screen: the whole notebook fills the screen; the canvas fills it and the
   tutor chat floats over it as a draggable panel. Driven by the .nb-fs class. ── */
.notebook.nb-fs {
  max-width: none;
  margin: 0;
  padding: 0;
  flex-direction: row;          /* canvas on the left, chat sidebar on the right */
  background: var(--paper-panel);
}
.notebook.nb-fs .nb-head { display: none; }       /* no page header in full screen */
.notebook.nb-fs .nb-stage-wrap {
  border: none;
  border-radius: 0;
  min-height: 0;                /* fill height instead of the 22rem normal-mode floor */
}
.notebook.nb-fs .nb-stage { background-color: var(--paper-panel); }
/* the tutor chat floats over the canvas as a small, draggable panel */
.notebook.nb-fs .nb-tutor {
  position: absolute;
  bottom: 16px;
  right: 16px;
  width: 18rem;
  max-height: 56vh;
  margin: 0;
  z-index: 30;
  box-sizing: border-box;
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 12px;
  box-shadow: 0 8px 28px rgba(43, 38, 24, 0.22);
  overflow: hidden;
}
.notebook.nb-fs .nb-tutor-log {
  flex: 1 1 auto;
  min-height: 0;                /* allow the log to shrink + scroll inside the capped panel */
  max-height: none;
  padding: 0.6rem 0.8rem 0.4rem;
}
/* tidy the composer row inside the small floating panel */
.notebook.nb-fs .nb-tutor-form {
  padding: 0.55rem 0.6rem 0.65rem;
  gap: 0.45rem;
  align-items: center;          /* line mic / input / send up on one row */
  background: transparent;      /* blend with the panel instead of a darker strip */
}
.notebook.nb-fs .nb-tutor-form .composer-mic,
.notebook.nb-fs .nb-tutor-form .composer-send {
  width: 2.5rem;
  height: 2.5rem;               /* equal, slightly smaller buttons for the narrow panel */
  align-self: center;
}
.notebook.nb-fs .nb-tutor-form .composer-input {
  min-height: 2.5rem;
  box-sizing: border-box;
  padding: 0.55rem 0.7rem;      /* match the button height for a clean baseline */
}
.notebook.nb-fs .nb-next { display: none; }    /* no Next button in the floating chat */

/* thin grab strips at the top + bottom edges to resize the panel's height */
.nb-tutor-resize { display: none; }
.notebook.nb-fs .nb-tutor-resize {
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  height: 8px;
  z-index: 6;
  cursor: ns-resize;
  touch-action: none;
}
.notebook.nb-fs .nb-tutor-resize-top { top: 0; }
.notebook.nb-fs .nb-tutor-resize-bottom { bottom: 0; }

/* drag / minimize header — only present while the chat is a floating panel */
.nb-tutor-bar { display: none; }
.notebook.nb-fs .nb-tutor-bar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 0.5rem;
  padding: 0.5rem 0.45rem 0.4rem 0.85rem;     /* top padding clears the resize strip;
                                                 no margin, so the darker header band
                                                 reaches the very top of the panel */
  cursor: move;
  touch-action: none;                       /* pointer drag without scroll-jank */
  border-bottom: 1px solid var(--line);
  background: var(--paper-edge);
}
.nb-tutor-title {
  font-size: 0.7rem;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  font-weight: 600;
  color: var(--ink-soft);
}
.nb-tutor-min {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 26px;
  background: none;
  border: none;
  border-radius: 7px;
  color: var(--ink-soft);
  cursor: pointer;
}
.nb-tutor-min:hover { background: var(--paper-panel); color: var(--forest-deep); }
.nb-tutor-min svg { width: 16px; height: 16px; }

/* minimized: hide the panel, show a round launcher button to bring it back */
.nb-tutor-launch { display: none; }
.notebook.nb-fs.nb-chat-hidden .nb-tutor { display: none; }
.notebook.nb-fs.nb-chat-hidden .nb-tutor-launch {
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  bottom: 16px;
  right: 16px;
  z-index: 30;
  width: 46px;
  height: 46px;
  background: var(--forest);
  color: var(--paper-panel);
  border: none;
  border-radius: 50%;
  box-shadow: 0 6px 18px rgba(43, 38, 24, 0.28);
  cursor: pointer;
}
.notebook.nb-fs.nb-chat-hidden .nb-tutor-launch:hover { background: var(--forest-deep); }
.nb-tutor-launch svg { width: 22px; height: 22px; }

.nb-tool:focus-visible,
.nb-expand:focus-visible,
.nb-grip:focus-visible {
  outline: 2px solid var(--forest);
  outline-offset: 1px;
}

.nb-stage-wrap.nb-dragover { border-color: var(--forest); box-shadow: inset 0 0 0 2px var(--forest); }

/* ── Image "what is this?" chip ── */

.nb-ask {
  position: absolute;
  left: 0;
  top: -2.6rem;
  z-index: 8;
  display: flex;
  align-items: center;
  gap: 0.4rem;
  padding: 0.3rem 0.45rem;
  white-space: nowrap;
  background: var(--paper-panel);
  border: 1px solid var(--line-strong);
  border-radius: 9px;
  box-shadow: 0 2px 8px rgba(43, 38, 24, 0.12);
}
/* A vision model (Gemma) sees the image directly, so the "what is this?" prompt
   (which only exists to label images for the text-only snapshot) is hidden. */
body.model-gemma .nb-ask { display: none; }
.nb-ask span {
  font-size: 0.7rem;
  letter-spacing: 0.04em;
  color: var(--ink-faint);
  padding: 0 0.2rem;
}
.nb-ask button {
  font-family: inherit;
  font-size: 0.78rem;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 7px;
  padding: 0.2rem 0.5rem;
  cursor: pointer;
}
.nb-ask button:hover { background: rgba(52, 80, 58, 0.12); border-color: var(--forest); color: var(--forest-deep); }

/* ── "Reading image…" overlay while the vision model runs ── */

.nb-item-status {
  position: absolute;
  inset: 0;
  z-index: 8;
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  padding: 0.5rem;
  font-size: 0.8rem;
  font-style: italic;
  color: var(--forest-deep);
  background: rgba(246, 239, 223, 0.78);
  border-radius: 4px;
  pointer-events: none;
}

/* ── Socratic tutor panel ── */

.nb-tutor {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  margin-top: 1rem;
}

.nb-tutor-log {
  display: flex;
  flex-direction: column;
  gap: 0.9rem;
  max-height: 16rem;
  overflow-y: auto;
  padding-bottom: 0.75rem;
}

.nb-tutor-form { border-top: 1px solid var(--line); }

.nb-next {
  flex: 0 0 auto;
  align-self: stretch;
  font-family: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--paper-panel);
  background: var(--forest);
  border: none;
  border-radius: 10px;
  padding: 0 1rem;
  cursor: pointer;
  transition: background-color 0.18s ease;
}
.nb-next:hover { background: var(--forest-deep); }
.nb-next:disabled { opacity: 0.55; cursor: default; }
.nb-next:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }

/* The Next button shows a dot loader while the model works (it's the primary
   action both under the canvas and in the full-screen chat sidebar). */
.nb-next { display: inline-flex; align-items: center; justify-content: center; min-width: 5.5rem; }
.nb-next-label { display: inline-flex; align-items: center; }
.nb-next-loader { display: none; }
.nb-next.is-loading .nb-next-label { display: none; }
.nb-next.is-loading .nb-next-loader { display: inline-flex; }
.nb-next.is-loading { opacity: 1; }                 /* loader speaks for itself; don't dim */
.nb-next .dot-loader span { background: var(--paper-panel); }   /* light dots on the green button */

/* Floating Next: appears over the canvas in full screen (not in the chat panel),
   pinned bottom-centre so it clears the toolbar and the top-right chat. */
.nb-fs-next { display: none; }
.notebook.nb-fs .nb-fs-next {
  display: inline-flex;
  position: absolute;
  bottom: 18px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 25;
  align-items: center;
  justify-content: center;
  gap: 0.4rem;
  min-width: 96px;
  font-family: inherit;
  font-size: 0.92rem;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--paper-panel);
  background: var(--forest);
  border: none;
  border-radius: 10px;
  padding: 0.55rem 1.05rem;
  cursor: pointer;
  box-shadow: 0 4px 14px rgba(43, 38, 24, 0.28);
  transition: background-color 0.18s ease;
}
.nb-fs-next:hover { background: var(--forest-deep); }
.nb-fs-next:disabled { opacity: 0.55; cursor: default; }
.nb-fs-next.is-loading { opacity: 1; }       /* loader speaks for itself; don't dim */
.nb-fs-next:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.nb-fs-next svg { width: 18px; height: 18px; }
.nb-fs-next-label { display: inline-flex; align-items: center; gap: 0.4rem; }
.nb-fs-next-loader { display: none; }
.nb-fs-next.is-loading .nb-fs-next-label { display: none; }
.nb-fs-next.is-loading .nb-fs-next-loader { display: inline-flex; }
.nb-fs-next .dot-loader span { background: var(--paper-panel); }   /* light dots on the green button */

/* ════════════════════════════════════════════════════════════
   Account · auth gate (sign in / create / reset) — front-end UI
   Token-driven, so it adopts parchment by day and the night palette
   automatically. No new colours: only the existing design tokens.
   ════════════════════════════════════════════════════════════ */

.auth-gate {
  position: fixed;
  inset: 0;
  z-index: 2000;                 /* above topbar (10/20) and everything else */
  display: flex;
  align-items: flex-start;
  justify-content: center;
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
  background-color: var(--paper);
  background-image:
    radial-gradient(120% 80% at 50% -10%, rgba(52,80,58,0.08) 0%, transparent 55%),
    repeating-linear-gradient(0deg, rgba(120,100,60,0.018) 0 1px, transparent 1px 3px);
  padding: max(1.25rem, env(safe-area-inset-top)) 1.25rem 2rem;
  transition: opacity 0.35s ease;
}
.auth-gate.is-leaving { opacity: 0; pointer-events: none; }
.auth-gate[hidden] { display: none; }
/* lock the app scroll behind the gate */
body.auth-open { overflow: hidden; }

.auth-stage {
  width: 100%;
  max-width: 27rem;
  margin: auto;
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.auth-card {
  background: var(--paper-panel);
  border: 1px solid var(--line);
  border-radius: 1.1rem;
  box-shadow: 0 18px 44px rgba(43,38,24,0.18), 0 2px 6px rgba(43,38,24,0.08);
  padding: 1.9rem 1.75rem 1.75rem;
}

/* brand lockup */
.auth-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.5rem;
  margin-bottom: 1.4rem;
}
.auth-brand-logo { width: 1.9rem; height: 1.9rem; border-radius: 50%; display: block; }
.auth-brand-name {
  font-weight: 600;
  font-size: 1.4rem;
  letter-spacing: 0.01em;
  color: var(--forest-deep);
}

/* views: only one visible at a time, with a soft cross-fade/slide */
.auth-view { display: none; }
.auth-view.is-active {
  display: block;
  animation: auth-in 0.32s cubic-bezier(0.22, 1, 0.36, 1) both;
}
@keyframes auth-in {
  from { opacity: 0; transform: translateY(6px); }
  to   { opacity: 1; transform: none; }
}

.auth-title {
  font-weight: 600;
  font-size: clamp(1.6rem, 6vw, 2rem);
  line-height: 1.15;
  color: var(--forest-deep);
  text-align: center;
}
.auth-sub {
  font-style: italic;
  color: var(--ink-soft);
  text-align: center;
  margin-top: 0.3rem;
  margin-bottom: 1.4rem;
}

/* social / oauth buttons */
.auth-social { display: flex; flex-direction: column; gap: 0.6rem; }
.auth-oauth {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 0.6rem;
  width: 100%;
  min-height: 3rem;
  padding: 0.7rem 1rem;
  font-family: inherit;
  font-size: 1rem;
  font-weight: 500;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  cursor: pointer;
  transition: border-color 0.18s ease, background-color 0.18s ease, transform 0.1s ease;
}
/* Apple sign-in not set up yet (needs a paid Apple Developer account). Hide the
   buttons so users don't hit "provider not enabled". DELETE this rule to re-enable. */
.auth-oauth[data-oauth="apple"] { display: none; }
.auth-oauth:hover { border-color: var(--forest); }
.auth-oauth:active { transform: scale(0.985); background: var(--paper-edge); }
.auth-oauth:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.auth-oauth-icon { width: 1.25rem; height: 1.25rem; flex: 0 0 auto; }

/* "or" divider */
.auth-divider {
  display: flex;
  align-items: center;
  gap: 0.75rem;
  margin: 1.25rem 0;
  color: var(--ink-faint);
  font-size: 0.85rem;
}
.auth-divider::before,
.auth-divider::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--line);
}

/* fields */
.auth-field { margin-bottom: 1rem; }
.auth-field label {
  display: block;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--ink-soft);
  margin-bottom: 0.35rem;
}
.auth-field-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
}
.auth-field input[type="text"],
.auth-field input[type="email"],
.auth-field input[type="password"] {
  width: 100%;
  font-family: inherit;
  font-size: 1rem;                /* 16px — no mobile zoom */
  line-height: 1.5;
  color: var(--ink);
  background: var(--paper);
  border: 1px solid var(--line-strong);
  border-radius: 10px;
  padding: 0.7rem 0.85rem;
  min-height: 3rem;
  transition: border-color 0.16s ease, box-shadow 0.16s ease;
}
.auth-field input::placeholder { color: var(--ink-faint); }
.auth-field input:focus {
  outline: none;
  border-color: var(--forest);
  box-shadow: 0 0 0 3px rgba(52,80,58,0.16);
}
/* password field with a show/hide eye inside */
.auth-input-wrap { position: relative; }
.auth-input-wrap input { padding-right: 3rem; }
.auth-eye {
  position: absolute;
  right: 0.4rem;
  top: 50%;
  transform: translateY(-50%);
  width: 2.2rem;
  height: 2.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: none;
  border-radius: 8px;
  color: var(--ink-faint);
  cursor: pointer;
  transition: color 0.16s ease;
}
.auth-eye:hover { color: var(--ink); }
.auth-eye:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 1px; }
.auth-eye svg { width: 1.15rem; height: 1.15rem; }

/* invalid state + inline error text */
.auth-field.is-invalid input { border-color: var(--incorrect); }
.auth-field.is-invalid input:focus { box-shadow: 0 0 0 3px rgba(180,81,63,0.16); }
.auth-error {
  display: none;
  margin-top: 0.35rem;
  font-size: 0.85rem;
  color: var(--incorrect);
}
.auth-error.is-shown { display: block; }

/* Cloudflare Turnstile captcha slot — spacing only when a widget is present */
.auth-edu-hint {
  font-size: 0.88rem;
  color: var(--ink-soft);
  margin-top: -0.15rem;
}
.auth-captcha { margin-top: 0.85rem; }
.auth-captcha:empty { margin: 0; }

/* positive confirmation notice (e.g. "check your email") — looks like good
   news, not a failure: soft green card with a check badge instead of red text */
.auth-formerror.is-success {
  color: var(--correct);
  background: color-mix(in srgb, var(--correct) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--correct) 32%, transparent);
  border-radius: 0.7rem;
  padding: 0.7rem 0.9rem 0.7rem 2.4rem;
  margin-top: 0.6rem;
  font-size: 0.9rem;
  line-height: 1.45;
  position: relative;
}
.auth-formerror.is-success::before {
  content: "✓";
  position: absolute;
  left: 0.8rem;
  top: 0.72rem;
  width: 1.2rem;
  height: 1.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--correct);
  color: #fff;
  border-radius: 50%;
  font-size: 0.72rem;
  font-weight: 700;
  line-height: 1;
}

/* form-level error (e.g. "Invalid login credentials") — same card treatment as
   the success notice, but red with a warning badge instead of plain red text */
.auth-formerror.is-shown:not(.is-success) {
  color: var(--incorrect);
  background: color-mix(in srgb, var(--incorrect) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--incorrect) 34%, transparent);
  border-radius: 0.7rem;
  padding: 0.7rem 0.9rem 0.7rem 2.4rem;
  margin-top: 0.6rem;
  font-size: 0.9rem;
  line-height: 1.45;
  position: relative;
}
.auth-formerror.is-shown:not(.is-success)::before {
  content: "!";
  position: absolute;
  left: 0.8rem;
  top: 0.72rem;
  width: 1.2rem;
  height: 1.2rem;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--incorrect);
  color: #fff;
  border-radius: 50%;
  font-size: 0.8rem;
  font-weight: 700;
  line-height: 1;
}

/* password strength meter */
.auth-strength {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  margin-top: 0.55rem;
}
.auth-strength-bars { display: flex; gap: 0.3rem; flex: 1; }
.auth-strength-bars i {
  flex: 1;
  height: 5px;
  border-radius: 999px;
  background: var(--line);
  transition: background-color 0.2s ease;
}
.auth-strength-label {
  font-size: 0.78rem;
  color: var(--ink-faint);
  min-width: 4.5rem;
  text-align: right;
}
.auth-strength[data-score="1"] i:nth-child(-n+1),
.auth-strength[data-score="2"] i:nth-child(-n+2),
.auth-strength[data-score="3"] i:nth-child(-n+3),
.auth-strength[data-score="4"] i:nth-child(-n+4) { background: var(--forest); }
.auth-strength[data-score="1"] i:nth-child(-n+1) { background: var(--incorrect); }
.auth-strength[data-score="2"] i:nth-child(-n+2) { background: var(--leaf-warm); }

/* checkbox row (remember / terms) */
.auth-check {
  display: flex;
  align-items: flex-start;
  gap: 0.55rem;
  font-size: 0.92rem;
  color: var(--ink-soft);
  cursor: pointer;
  margin: 0.4rem 0 0.2rem;
}
.auth-check input {
  flex: 0 0 auto;
  width: 1.15rem;
  height: 1.15rem;
  margin-top: 0.12rem;
  accent-color: var(--forest);
  cursor: pointer;
}
.auth-link-inline { color: var(--forest); text-decoration: underline; }

/* primary submit */
.auth-submit {
  position: relative;
  width: 100%;
  min-height: 3.1rem;
  margin-top: 1.3rem;
  font-family: inherit;
  font-size: 1.05rem;
  font-weight: 600;
  color: var(--paper-panel);
  background: var(--forest);
  border: 1px solid var(--forest);
  border-radius: 10px;
  cursor: pointer;
  transition: background-color 0.18s ease, transform 0.1s ease, box-shadow 0.18s ease;
  box-shadow: 0 6px 16px rgba(37,64,43,0.22);
}
.auth-submit:hover { background: var(--forest-deep); }
.auth-submit:active { transform: scale(0.99); }
.auth-submit:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.auth-submit.is-loading { color: transparent; pointer-events: none; }
.auth-submit .auth-spinner {
  position: absolute;
  left: 50%; top: 50%;
  width: 1.2rem; height: 1.2rem;
  margin: -0.6rem 0 0 -0.6rem;
  border: 2px solid rgba(246,239,223,0.45);
  border-top-color: var(--paper-panel);
  border-radius: 50%;
  opacity: 0;
}
.auth-submit.is-loading .auth-spinner { opacity: 1; animation: auth-spin 0.7s linear infinite; }
@keyframes auth-spin { to { transform: rotate(360deg); } }

/* swap line + small text links */
.auth-swap {
  margin-top: 1.1rem;
  text-align: center;
  font-size: 0.95rem;
  color: var(--ink-soft);
}
.auth-link {
  font-family: inherit;
  font-size: inherit;
  font-weight: 500;
  color: var(--forest);
  background: none;
  border: none;
  padding: 0.1rem 0.15rem;
  cursor: pointer;
  border-radius: 4px;
}
.auth-link:hover { text-decoration: underline; }
.auth-link:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 1px; }

/* back button (forgot view) */
.auth-back {
  display: inline-flex;
  align-items: center;
  gap: 0.25rem;
  margin-bottom: 0.6rem;
  font-family: inherit;
  font-size: 0.95rem;
  font-weight: 500;
  color: var(--ink-soft);
  background: none;
  border: none;
  cursor: pointer;
  border-radius: 6px;
}
.auth-back:hover { color: var(--ink); }
.auth-back:focus-visible { outline: 2px solid var(--forest-deep); outline-offset: 2px; }
.auth-back svg { width: 1.05rem; height: 1.05rem; }

/* reset-link sent confirmation */
.auth-sent { text-align: center; padding-top: 0.5rem; }
.auth-sent-icon {
  width: 3.25rem; height: 3.25rem;
  margin: 0.5rem auto 0.9rem;
  display: flex; align-items: center; justify-content: center;
  color: var(--forest);
  background: rgba(52,80,58,0.12);
  border-radius: 50%;
}
.auth-sent-icon svg { width: 1.6rem; height: 1.6rem; }
.auth-sent h2 { font-weight: 600; font-size: 1.3rem; color: var(--forest-deep); }
.auth-sent p { color: var(--ink-soft); margin: 0.4rem 0 0.4rem; }

/* footer line under the card */
.auth-foot {
  text-align: center;
  font-size: 0.85rem;
  color: var(--ink-faint);
}

@media (prefers-reduced-motion: reduce) {
  .auth-view.is-active { animation: none; }
  .auth-gate { transition: none; }
  .auth-submit.is-loading .auth-spinner { animation-duration: 1.4s; }
}

/* ════════════════════════════════════════════════════════════════════════
   MOBILE OPTIMIZATION
   The shell (fixed top bar + bottom tab bar + scroll area, safe-area insets,
   16px inputs) is already fluid; this layer tunes the phone experience. Layout
   rules key off a 640px width breakpoint; a few touch-only affordances key off
   the `is-touch` class set by the detector in index.html's <head>.
   ════════════════════════════════════════════════════════════════════════ */

/* Don't let iOS/Android silently inflate text; kill the grey tap flash. */
html { -webkit-text-size-adjust: 100%; text-size-adjust: 100%; }
html.is-touch, html.is-touch * { -webkit-tap-highlight-color: transparent; }

@media (max-width: 640px) {
  /* Guard against any single wide child causing a horizontal scrollbar. */
  html, body { overflow-x: hidden; }

  /* Tighter chrome on narrow screens. */
  .topbar { padding: 0 1rem; }
  .content-page { padding: 1.35rem 1.1rem 2.25rem; }

  /* Home hero: clear the top bar (no overlap) and scale the title to fit. */
  .home-head { top: calc(var(--bar-h) + 0.35rem); }
  .home-title { font-size: clamp(1.9rem, 8vw, 2.6rem); }

  /* Composer reflow: the text field gets its own full-width row on top, with the
     action buttons on the row below (send pinned right). Fixes the cramped, the
     "Ask anything…" placeholder getting clipped between four buttons. */
  .composer { gap: 0.45rem; }
  .composer-attach { order: -2; }          /* image preview stays above the input */
  .composer-input  { flex: 1 1 100%; order: -1; }
  .composer-send   { margin-left: auto; }  /* push send to the right of its row */

  /* Comfortable, thumb-sized tap targets (≥44px) for the composer controls. */
  .composer-mic, .composer-img, .composer-send, .composer-gear {
    width: 2.85rem; height: 2.85rem;
  }
  /* The gear sits near the left of the button row, so its menu opens from the
     left edge. Cap the width so a narrow phone can never push it off-screen. */
  .composer-menu {
    min-width: 13.5rem;
    max-width: min(17rem, calc(100vw - 2.5rem));
  }
  /* Bigger hit areas inside the menu for thumbs. */
  .composer-menu-item { padding: 0.55rem 0.6rem; }

  /* Keep form controls at 16px so iOS Safari doesn't zoom on focus. */
  input:not([type="checkbox"]):not([type="radio"]):not([type="range"]),
  textarea, select { font-size: 16px; }

  /* Notebook: already near full-viewport on phones — hide fullscreen toggle. */
  .nb-expand { display: none; }
  .nb-history { right: 14px; }
}

/* Very small phones (e.g. iPhone SE width): trim a little more. */
@media (max-width: 380px) {
  .tab { font-size: 0.68rem; }
  .home-about { font-size: 0.9rem; }
}