:root {
  --paper: #F3EDDF; --ink: #1E1E24; --gray: #55555E; --accent: #C73E3A;
  --panel-w: clamp(320px, 40%, 560px);
  /* The ink as a bare triple, so every hairline, hover wash and dimmed line on
     the page can be written rgba(var(--ink-rgb), a) and invert with the theme
     at its own weight. Changing one number here re-inks the whole page. */
  --ink-rgb: 30,30,36;
  --seal-ink: var(--paper);   /* the glyph cut out of the seal */
}
/* ---- the dark page ----
   Scoped to the panel ON PURPOSE, not to :root. This is the reading light over
   the text and nothing else — the diorama beside it is a painting on paper and
   stays lit that way, and so do the toolbar and the timer that sit over it
   (Frank: "it really only applies to the text area"). Everything inside the
   panel inherits these; nothing outside it can see them. */
#gg-panel.dark {
  color-scheme: dark;   /* the page's own scrollbar, which is not ours to draw */
  --paper: #17171B; --ink: #E9E3D5; --gray: #9C978C; --accent: #DD5B54;
  --ink-rgb: 233,227,213;
  --seal-ink: #F3EDDF;   /* the numeral stays paper-white: dark-on-red is unreadable */
}
* { box-sizing: border-box; }

/* ---- two-column shell: content panel (left) | 3D stage (right) ---- */
#gg-app { display: flex; width: 100vw; height: 100vh; overflow: hidden; }
#gg-panel {
  width: var(--panel-w); flex: none; position: relative; overflow: hidden;
  background: var(--paper); color: var(--ink);
  border-right: 1px solid rgba(var(--ink-rgb),0.12);
  font-family: Georgia, 'Times New Roman', serif;
  transition: opacity 0.35s ease;
}
#gg-panel.fading { opacity: 0; }
#gg-stage { flex: 1; position: relative; overflow: hidden; background: var(--paper); }
#gg-stage canvas { display: block; }
/* ambient view: the text steps aside and the stage takes the freed width. The
   flex row does the rest — but the renderer has to be told, since no resize
   event fires for a layout change inside the page (see applyStageSize). */
#gg-app.ambient #gg-panel { display: none; }

/* every mode's panel content fills the panel; only one is shown at a time */
.gg-view { position: absolute; inset: 0; overflow-y: auto; padding: 40px 44px 56px; }
.gg-view.hidden { display: none; }

button.gg-btn, .gg-view button {
  font-family: Georgia, serif; background: none; border: 1px solid rgba(var(--ink-rgb),0.3);
  color: var(--ink); padding: 6px 14px; border-radius: 3px; cursor: pointer;
}
button.gg-btn:hover, .gg-view button:hover { background: rgba(var(--ink-rgb),0.05); }

/* ---- title screen (intro), in the left panel ---- */
.gg-title-view { display: flex; flex-direction: column; justify-content: center; }
.gg-title-view h1 {
  font-weight: normal; font-size: clamp(30px, 5vw, 52px); letter-spacing: 0.04em;
  line-height: 1.15; margin: 0 0 14px;
}
.gg-title-view .sub { color: var(--gray); font-style: italic; margin: 0 0 28px; }

/* ---- table of contents (menu), in the left panel ---- */
/* Title and the reading light on one line. baseline, not centre: the glyph
   should sit on the title's own line rather than float beside a 30px cap. */
.gg-menu-head { display: flex; align-items: baseline; gap: 12px; }
.gg-menu-head h1 { flex: 1; }
.gg-menu-head .gg-theme { flex: none; }
.gg-menu h1 { font-weight: normal; letter-spacing: 0.04em; font-size: 30px; margin: 0 0 4px; }
.gg-menu .lede { color: var(--gray); font-style: italic; margin: 0 0 18px; }
.gg-menu ol { list-style: none; padding: 0; margin: 12px 0 0; }
.gg-menu li { display: flex; align-items: baseline; gap: 12px; padding: 9px 0; border-bottom: 1px solid rgba(var(--ink-rgb),0.08); }
.gg-menu li .num { font-size: 13px; color: var(--gray); width: 24px; text-align: right; flex: none; }
.gg-menu li .ttl { flex: 1; font-size: 18px; }
/* Every case opens. `unstaged` means it has no diorama of its own yet, so it
   sits a little back on the page — readable, clearly not withheld. It used to
   be `locked` at 0.32 opacity, which read as unavailable. */
.gg-menu li .ttl { cursor: pointer; }
.gg-menu li .ttl:hover { color: var(--accent); }
.gg-menu li.unstaged .ttl { color: rgba(var(--ink-rgb),0.62); }
.gg-menu li .mark { width: 18px; text-align: center; flex: none; }
.gg-menu li .dot::before { content: '·'; color: var(--gray); font-size: 22px; line-height: 0; }
.gg-menu li .stamp { color: var(--accent); }
.gg-continue { margin: 4px 0 10px; }

/* Search. A ruled line to write on, not a widget — the panel is a book page and
   a boxed input with a magnifier would be the only piece of software on it. */
.gg-find {
  width: 100%; box-sizing: border-box;
  margin: 2px 0 2px; padding: 6px 2px;
  font: italic 16px/1.4 var(--serif, Georgia, 'Times New Roman', serif);
  color: var(--ink, #1E1E24);
  background: transparent;
  border: 0; border-bottom: 1px solid rgba(var(--ink-rgb),0.18);
  outline: none;
  -webkit-appearance: none; appearance: none;
}
.gg-find::placeholder { color: rgba(var(--ink-rgb),0.34); font-style: italic; }
.gg-find:focus { border-bottom-color: var(--accent); }
.gg-find::-webkit-search-cancel-button { -webkit-appearance: none; appearance: none; }
/* the ✕: a square in the margin of the ruled line, not a button on a widget.
   Flex-centred rather than trusting the glyph's own metrics — × sits high in
   its em box in a serif face, so line-height alone leaves it off-centre. */
.gg-find-wrap { position: relative; }
.gg-find-wrap .gg-find { padding-right: 26px; }
.gg-find-clear {
  position: absolute; right: 0; top: 50%; transform: translateY(-50%);
  box-sizing: border-box; width: 20px; height: 20px; padding: 0;
  display: flex; align-items: center; justify-content: center;
  border: 0; border-radius: 2px; background: transparent; cursor: pointer;
  font: 17px/1 var(--serif, Georgia, 'Times New Roman', serif);
  color: rgba(var(--ink-rgb),0.40);
}
.gg-find-clear:hover { color: var(--accent); background: rgba(var(--ink-rgb),0.07); }
.gg-found { font-size: 12px; color: var(--gray); margin: 6px 0 0; min-height: 14px; letter-spacing: 0.04em; }
/* the matched line, under its title — the reason the result list is readable */
.gg-menu li .ttl .hit {
  display: block; margin-top: 3px;
  font-size: 13px; font-style: italic; line-height: 1.45;
  color: rgba(var(--ink-rgb),0.55);
}

/* Back matter, under the contents: the About link sits where a printed book
   puts its colophon. Hidden while searching, like Continue. */
.gg-backmatter { margin: 18px 0 4px; padding-top: 14px; border-top: 1px solid rgba(var(--ink-rgb),0.12); }
/* the colophon line: About at the margin. The reading light used to sit at the
   far edge of it and is up in the title row now — nobody scrolls past fifty-one
   rows to find a light switch. */
.gg-colophon { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
/* the About link: quiet, italic, and set apart from the numbered rows */
.gg-about-link {
  background: none; border: none; padding: 0; cursor: pointer;
  font-family: Georgia, serif; font-size: 15px; font-style: italic; color: var(--gray);
}
.gg-about-link:hover { color: var(--accent); background: none; }

/* Developer mode's own section, under the back matter. Never rendered at all
   unless the workbench's "Developer mode" box is ticked, so nothing here is
   part of the book's ordinary look. Deliberately drab: it is a tool shelf. */
.gg-dev { margin-top: 12px; padding-top: 10px; border-top: 1px dashed rgba(var(--ink-rgb),0.15); }
.gg-dev-head {
  font-family: Georgia, serif; font-size: 11px; letter-spacing: 0.14em;
  text-transform: uppercase; color: var(--gray); opacity: 0.7; margin-bottom: 6px;
}
.gg-dev .gg-about-link { display: block; font-style: normal; font-size: 14px; }

/* ---- koan text (scroll), in the left panel ---- */
.gg-scroll { --accent: var(--accent); }
/* The about page borrows the koan page wholesale; it differs only in having no
   seal and no case number to balance the title against. */
.gg-about .gg-scroll-head h2 { flex: 1 1 100%; }
.gg-about .gg-section-text a { color: var(--accent); text-decoration-color: rgba(199,62,58,0.4); }
.gg-about .gg-section-text a:hover { text-decoration-color: var(--accent); }
.gg-scroll-bar { display: flex; align-items: center; gap: 10px; margin: -8px 0 18px; }
.gg-back { border: none; color: var(--gray); padding: 4px 6px; }
.gg-back:hover { color: var(--accent); background: none; }
.gg-page-nav { display: inline-flex; gap: 2px; }
.gg-page {
  border: none; background: none; color: var(--gray);
  font-size: 20px; line-height: 1; padding: 2px 8px; border-radius: 6px;
}
.gg-page:hover:not(:disabled) { color: var(--accent); background: rgba(var(--ink-rgb),0.05); }
.gg-page:disabled { opacity: 0.28; cursor: default; }
/* the reading light, beside Sit and on the colophon line: a glyph, no chrome —
   it must not read as a third page-turn button */
/* The reading light. Deliberately the SAME button as its neighbours in the bar
   rather than a bare glyph: `.gg-view button` above is one class and one
   element, so it outranks every bare `.gg-back`/`.gg-page` class in this file
   and the whole toolbar renders boxed — a chrome-less moon in the middle of it
   would be the odd one out. Selector matched to that specificity so these
   three properties land; fixed width so the bar cannot jump when ☾ becomes ☼. */
.gg-view .gg-theme {
  min-width: 40px; padding: 6px 10px; text-align: center; color: var(--gray);
}
.gg-view .gg-theme:hover { color: var(--accent); }
.gg-scroll-bar .spacer { flex: 1; }
.gg-scroll-head { display: flex; align-items: baseline; gap: 12px; flex-wrap: wrap; }
.gg-scroll-head h2 { font-weight: normal; font-size: 25px; margin: 0; flex: 1 1 60%; }
.gg-seal {
  display: inline-grid; place-items: center; width: 34px; height: 34px; flex: none;
  background: var(--accent); color: var(--seal-ink); border-radius: 3px; font-size: 17px;
}
.gg-play-all { margin-top: 10px; }
.gg-section { margin-top: 24px; }
.gg-section-label {
  font-variant: small-caps; letter-spacing: 0.08em; color: var(--gray);
  font-size: 14px; display: flex; align-items: center; gap: 8px;
}
.gg-speak { background: none; border: none; color: var(--accent); cursor: pointer; font-size: 15px; padding: 0 2px; }
.gg-section-text { margin-top: 8px; line-height: 1.72; white-space: pre-wrap; }
.gg-section.speaking .gg-section-text { background: rgba(199,62,58,0.08); }

/* ---- the reading's title card, centred over the stage ----
   The only text on screen once the panel has stepped aside, so it is set quietly
   and in the book's own face. pointer-events: none matters — it spans the whole
   width of the picture and must never eat a drag. */
.gg-page-card {
  position: absolute; top: 8vh; left: 0; right: 0; z-index: 7;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  pointer-events: none; text-align: center; padding: 0 24px;
  font-family: Georgia, 'Times New Roman', serif; color: var(--ink);
  opacity: 0; transition: opacity 1.4s ease;
}
/* Quicker in than out: the name should arrive with the page and leave without
   being noticed leaving. */
.gg-page-card.show { opacity: 1; transition-duration: 0.9s; }
.gg-page-card .num { font-size: 13px; letter-spacing: 0.24em; color: var(--gray); }
.gg-page-card .ttl { font-size: clamp(21px, 3.1vw, 34px); letter-spacing: 0.03em; line-height: 1.2; }

/* ---- stage toolbar: one row of square buttons, top-right over the 3D ----
   Sound, fullscreen and the debug workbench share a shape so the corner reads
   as a toolbar. It sits ABOVE the debug panel (z 9 vs 8) so every button stays
   clickable while the panel is out — which is how you close it again. */
.gg-toolbar { position: absolute; top: 14px; right: 14px; z-index: 9; display: flex; gap: 6px; }
.gg-tool, .gg-debug-toggle {
  width: 30px; height: 30px; line-height: 1; font-size: 15px; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
  font-family: Georgia, serif;
  background: rgba(243,237,223,0.82); border: 1px solid rgba(30,30,36,0.28);
  color: var(--ink); border-radius: 3px; backdrop-filter: blur(2px);
  padding: 0;
}
.gg-tool:hover, .gg-debug-toggle:hover { border-color: rgba(30,30,36,0.55); }
.gg-tool.active, .gg-debug-toggle.active { background: var(--ink); color: var(--paper); }

/* ---- the look's toolbar: TOP-LEFT, opposite the stage tools ----
   Leave, back, forward, read aloud. The right-hand corner holds settings
   (sound, fullscreen, the workbench); this corner holds the things you do to
   the book, so the two never read as one long row of unrelated buttons. The
   leave button comes first and is what makes the look a mode rather than a
   trapdoor.

   The whole bar stays put and stays visible wherever the look is on — on the
   Contents as much as on a page. Buttons that cannot do anything grey out
   rather than disappearing, so nothing ever moves under the cursor. display:none
   only when the look is off, where it takes no room and catches no clicks. */
.gg-look-bar {
  position: absolute; top: 14px; left: 14px; z-index: 9; display: none;
  gap: 6px; align-items: center;
}
.gg-look-bar.on { display: flex; }
#gg-app.sitting .gg-look-bar { display: none; }
.gg-look-bar button {
  font-family: Georgia, serif; cursor: pointer; color: var(--ink);
  background: rgba(243,237,223,0.82); border: 1px solid rgba(30,30,36,0.28);
  border-radius: 3px; backdrop-filter: blur(2px);
}
.gg-look-bar button:hover:not(:disabled) { border-color: rgba(30,30,36,0.55); }
.gg-look-bar button:disabled { opacity: 0.35; cursor: default; }
/* Square like the stage tools; "Read aloud" is a whole word wide, which is the
   distinction — those three move you, that one does something to the page.
   The word is a .gg-look-word span so a narrow window can drop it; see the
   640px block at the foot of this file. */
.gg-look-exit, .gg-look-page {
  width: 30px; height: 31px; padding: 0; font-size: 17px; line-height: 1;
  display: flex; align-items: center; justify-content: center;
}
/* A little air after the way out, so it does not read as part of the paging. */
.gg-look-exit { margin-right: 4px; font-size: 16px; }
.gg-look-read, .gg-look-auto { font-size: 13px; letter-spacing: 0.04em; padding: 6px 12px; }
/* Auto mode is the one control here that keeps acting after you let go of it,
   so unlike the other four it holds a lit state — the same accent the stage
   tools use for "this is on", so "on" reads the same everywhere in the book. */
.gg-look-auto.active {
  background: rgba(199,62,58,0.14); border-color: rgba(199,62,58,0.55);
}
.gg-look-auto.active:hover:not(:disabled) { border-color: rgba(199,62,58,0.8); }
/* ---- debug workbench: panel sliding out under the toolbar ---- */
/* THE WORKBENCH TAKES LAYOUT, IT DOES NOT OVERLAY.
   It used to be an absolute sheet over the stage at 94% opacity, which put the
   controls on top of the very picture they aim: the diorama went on being
   centred in the full stage, behind the panel, so composing a shot meant
   judging a centre you could not see (Frank: "it's hard for me to adjust the
   camera... have it make the viewport smaller the same as when the text is on
   the left"). It is a flex column beside the stage now — the mirror of the text
   panel — so the viewport narrows, the picture recentres in what is left, and
   what you frame is what the reader gets.

   `display`, not an animated width: the WebGL buffer has to be resized on the
   change, and a slide would mean resizing it every frame of the transition to
   buy nothing. Opaque, and no backdrop blur, for the same reason — nothing of
   the scene should show through the thing you are judging it against.

   No padding-top for the toolbar any more: the toolbar rides the stage's right
   edge, which is now this panel's left edge, so the two no longer overlap. */
.gg-debug {
  display: none; flex: none; width: 232px;
  background: var(--paper); border-left: 1px solid rgba(30,30,36,0.22);
  padding: 14px 12px; overflow-y: auto;
  font: 11px/1.5 ui-monospace, Menlo, Consolas, monospace; color: var(--ink);
}
.gg-debug.open { display: block; }
.gg-debug-readout { opacity: 0.7; margin-bottom: 10px; }
/* the draw budget's tell: amber inside striking distance of the 150 line,
   red over it (src/budget.js — the same number the staging net enforces) */
.gg-debug-readout.gg-warn { opacity: 1; color: #9a6a00; font-weight: 700; }
.gg-debug-readout.gg-over { opacity: 1; color: #a02c20; font-weight: 700; }
.gg-debug-group { margin: 12px 0 4px; font-weight: 700; opacity: 0.55; text-transform: uppercase; letter-spacing: 0.06em; }
.gg-debug-row { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 6px; padding: 2px 0; cursor: pointer; }
.gg-debug-row em { font-style: normal; opacity: 0.6; }
.gg-debug-row input[type=range] { grid-column: 1 / -1; width: 100%; height: 14px; }
.gg-debug-reset { margin-top: 14px; width: 100%; cursor: pointer; font: inherit; padding: 4px; background: none; border: 1px solid rgba(30,30,36,0.25); border-radius: 3px; color: var(--ink); }
.gg-debug-keep { margin-top: 8px; opacity: 0.75; }
/* an action button in a control row — a thing you press, not a thing you set */
.gg-debug-act { font: inherit; padding: 1px 8px; cursor: pointer; color: var(--ink); background: rgba(30,30,36,0.06); border: 1px solid rgba(30,30,36,0.25); border-radius: 2px; }
.gg-debug-act:hover { background: rgba(30,30,36,0.14); }
/* the Compose block: the copied camera line wraps and is selectable by hand,
   because a clipboard write can be refused and the line is the whole point */
.gg-compose { margin-top: 10px; }
.gg-compose-note { grid-column: 1 / -1; font-style: normal; opacity: 0.75; word-break: break-all; user-select: text; font-size: 11px; line-height: 1.35; }

.gg-sit-wrap { position: relative; display: inline-block; }
.gg-sit-pop { position: absolute; top: 112%; right: 0; display: none; gap: 4px; z-index: 6; background: var(--paper); padding: 4px; border: 1px solid rgba(var(--ink-rgb),0.2); border-radius: 3px; box-shadow: 0 4px 14px rgba(30,30,36,0.14); }
.gg-sit-pop.open { display: flex; }
.gg-sit-pop button { padding: 4px 8px; }

/* ---- sitting: the scene, a clock, and a way out ----
   No wash over the picture and nothing to breathe along with — the overlay is
   here to hold the clock and to catch the tap that ends the sitting. The text
   panel has already stepped aside (main.js), so the diorama IS the page.
   Deliberately NOT themed: it lies over the painting, not over the text. */
.gg-sit {
  position: fixed; inset: 0; z-index: 55;
  color: var(--ink); font-family: Georgia, serif; cursor: pointer;
}
.gg-sit.hidden { display: none; }
/* Set like the reading's title card and in the same place, since it is the same
   kind of thing: one quiet line over the top of the picture. */
.gg-sit-clock {
  position: absolute; top: 8vh; left: 0; right: 0; text-align: center;
  font-size: clamp(30px, 4.6vw, 52px); letter-spacing: 0.08em;
  font-variant-numeric: tabular-nums; opacity: 0.62;
}
/* Ink, not grey, and letterspaced like the title card's number: the foot of a
   diorama is its darkest ground — grass, stone, a figure — and a grey caption
   laid on that is a caption nobody finds. */
.gg-sit .hint {
  position: absolute; bottom: 8vh; left: 0; right: 0; text-align: center;
  color: var(--ink); opacity: 0.8; font-size: 14px; letter-spacing: 0.2em;
}
/* Both lines lie over a painting, not over paper. The same halo REPEATED — each
   copy compounds the one under it — burns a soft paper hole around the letters,
   which is what keeps them readable over dense grass without putting a chip or
   a scrim on the picture. One pass at low alpha does nothing there. */
.gg-sit-clock, .gg-sit .hint {
  text-shadow:
    0 0 3px var(--paper), 0 0 3px var(--paper), 0 0 3px var(--paper),
    0 0 10px var(--paper), 0 0 10px var(--paper), 0 0 20px var(--paper);
}
/* Nothing to press but the picture. Every tap ends the sitting, so the toolbar
   is unreachable while it runs — leaving it drawn would only promise otherwise. */
#gg-app.sitting .gg-toolbar { display: none; }

/* ---- narrow screens: stack scene over content ---- */
@media (max-width: 820px) {
  #gg-app { flex-direction: column; }
  #gg-panel { width: 100%; height: 52%; flex: none; order: 2; border-right: none; border-top: 1px solid rgba(var(--ink-rgb),0.12); }
  #gg-stage { order: 1; flex: 1; }
  .gg-view { padding: 22px 24px 40px; }
  /* The workbench is a side column on a desktop; in a stacked column layout a
     232px-wide child would be a full-width band shoving the book off screen.
     Back to an overlay here — narrow is not where a shot gets composed, and a
     dev tool must never be what breaks a phone. */
  .gg-debug.open {
    position: absolute; top: 0; right: 0; bottom: 0; z-index: 8;
    border-left: 1px solid rgba(30,30,36,0.22);
  }
}

/* ---- narrower still: the look's toolbar in short form ----
   Both corners are pinned and only the middle is empty, so the look's bar and
   the stage tools run into each other well before anything else about the
   layout complains — Frank, on a tall phone: "the buttons are overlapping".
   The long form wants around 560px of window; below that the read button drops
   to its glyph and auto mode goes entirely, which is the whole of what has to
   give: those two carry the only words in either corner.

   WIDTH, not aspect ratio, even though a tall screen is what turns it up. What
   collides is two rows of buttons across the window, so a short WIDE window at
   500px overlaps exactly the same and an aspect query would sail straight past
   it. Every phone held upright is caught by the width anyway.

   Auto mode is hidden, not disabled: if it is already running when the window
   narrows it keeps going, and ↺ — leaving the look — stops it, the same way
   leaving the look stops it at any size. So the switch can vanish without
   stranding the reader inside the thing it switches. */
@media (max-width: 640px) {
  .gg-look-word { display: none; }
  .gg-look-auto { display: none; }
  /* Square, like the three beside it: with the word gone there is nothing left
     to make it a different shape from the buttons it sits next to. */
  .gg-look-read {
    width: 30px; height: 31px; padding: 0; font-size: 15px; line-height: 1;
    display: flex; align-items: center; justify-content: center;
  }
}
