/*
 * The shell: top bar and body row (§1 of the handoff).
 *
 * Every colour here is a token from `tokens.css`. That is not tidiness -- it is
 * what makes the ink theme a single attribute on the document element instead
 * of a second stylesheet. If you find yourself typing `#` in this file, the
 * value you want is a role that already exists.
 *
 * The handoff names a handful of geometry values that `tokens.css` does not
 * carry -- the bar's own gaps and paddings, the size of a 26px icon button, the
 * dot sizes, the letter-spacings on mono labels. They are declared once at the
 * top of each sheet as local custom properties rather than being scattered
 * through the rules as literals.
 */

.novely-shell-frame {
  /* Local geometry from the handoff, unpromoted to tokens. */
  --shell-gap: 14px;
  --shell-gap-wide: 16px;
  --shell-pad-left: 18px;
  --shell-pad-right: 14px;
  --shell-icon: 26px;
  --shell-dot: 6px;
  --shell-track: 0.09em;
  /* The one value the handoff names that `tokens.css` has no role for: the
     active findings pill's border sits between --border-strong (.14) and
     --border-hover (.32). Declared per theme here so the toggle still wins. */
  --pill-border-on: rgba(28, 26, 23, 0.18);
  --shell-rail-w: var(--rail-w-wide);
  --shell-measure: var(--measure-wide);

  display: flex;
  flex-direction: column;
  height: 100vh;
  min-height: 0;
  background: var(--page);
  color: var(--text);
  font-family: var(--font-ui);
}

/* ------------------------------------------------------------------------ */
/* Top bar                                                                    */
/* ------------------------------------------------------------------------ */

.novely-shell-top {
  flex: none;
}

.novely-top {
  height: var(--topbar-h);
  display: flex;
  align-items: center;
  gap: var(--shell-gap);
  padding: 0 var(--shell-pad-right) 0 var(--shell-pad-left);
  border-bottom: 1px solid var(--hairline);
}

.novely-top-title {
  font: 500 var(--size-12-5) / 1 var(--font-ui);
  color: var(--text);
  white-space: nowrap;
}

.novely-top-rule {
  width: 1px;
  height: 18px;
  flex: none;
  background: var(--hairline);
}

.novely-top-rule-short {
  height: 16px;
  margin: 0 3px;
}

.novely-top-gap {
  flex: 1;
}

/* -- formatting group ---------------------------------------------------- */

.novely-top-format {
  position: relative;
  display: flex;
  align-items: center;
  gap: 4px;
}

.novely-top-style {
  display: flex;
  align-items: center;
  gap: 6px;
  font: 400 var(--size-11) var(--font-ui);
  color: var(--text);
  background: var(--row-active);
  border: 0;
  border-radius: var(--r-button);
  padding: 6px 9px;
  cursor: pointer;
}

.novely-top-style:hover {
  background: var(--row-active-strong);
}

.novely-top-style-chevron {
  font: 400 9px var(--font-mono);
  color: var(--muted-4);
}

.novely-top-icon {
  width: var(--shell-icon);
  height: var(--shell-icon);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--muted-2);
  background: transparent;
  border: 0;
  border-radius: 6px;
  cursor: pointer;
}

.novely-top-icon:hover {
  background: var(--row-active-strong);
  color: var(--text);
}

.novely-top-b {
  font: 600 var(--size-12) var(--font-prose);
}

.novely-top-i {
  font: italic 400 var(--size-13) var(--font-prose);
}

.novely-top-quote {
  font: 400 var(--size-12) var(--font-prose);
}

.novely-top-break {
  font: 400 var(--size-11) var(--font-mono);
}

.novely-top-text {
  font: 400 var(--size-11) var(--font-ui);
  color: var(--muted-3);
  background: transparent;
  border: 0;
  border-radius: 6px;
  padding: 4px 0;
  cursor: pointer;
}

.novely-top-format .novely-top-text {
  padding: 5px 8px;
  color: var(--muted-2);
}

.novely-top-text:hover {
  color: var(--text);
}

.novely-top-format .novely-top-text:hover {
  background: var(--row-active-strong);
}

/* -- paragraph-style popover ---------------------------------------------- */

/*
 * The panel is the editor's (`editor/style-menu.ts`); the bar only says where
 * it hangs. Keeping the two apart is what stops the top bar and the popover
 * from growing separate ideas about what a paragraph style is.
 */
.novely-top-menu-anchor {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 20;
}

/* -- view modes ---------------------------------------------------------- */

.novely-top-modes {
  display: flex;
  align-items: center;
  gap: 2px;
}

.novely-top-mode {
  font: 400 var(--size-11) var(--font-ui);
  color: var(--muted-3);
  background: transparent;
  border: 0;
  border-radius: var(--r-button);
  padding: 6px 10px;
  cursor: pointer;
}

.novely-top-mode:hover {
  background: var(--row-hover-strong);
  color: var(--text);
}

.novely-top-mode-on {
  font-weight: 500;
  color: var(--text);
  background: var(--row-active-strong);
}

/* -- verbs, panes -------------------------------------------------------- */

.novely-top-actions {
  display: flex;
  align-items: center;
  gap: var(--shell-gap);
}

.novely-top-glyph {
  font: 400 var(--size-11) var(--font-mono);
  color: var(--muted-6);
  background: transparent;
  border: 1px solid var(--border);
  border-radius: var(--r-button);
  padding: 5px 8px;
  cursor: pointer;
}

.novely-top-glyph:hover {
  color: var(--text);
  border-color: var(--border-hover);
}

.novely-top-glyph-on {
  color: var(--text);
  background: var(--row-active-strong);
  border-color: var(--border-strong);
}






/* -- the two statements on the right ------------------------------------- */

.novely-top-status {
  font: 400 var(--size-11) / 1 var(--font-mono);
  color: var(--muted-5);
  white-space: nowrap;
}

.novely-top-pill {
  display: flex;
  align-items: center;
  gap: 7px;
  font: 500 var(--size-11) / 1 var(--font-ui);
  color: var(--muted-2);
  background: transparent;
  border: 1px solid var(--border-strong);
  border-radius: var(--r-pill);
  padding: 6px 11px;
  cursor: pointer;
}

.novely-top-pill:hover {
  border-color: var(--border-hover);
}

.novely-top-pill-on {
  color: var(--text);
  background: var(--row-active-strong);
  border-color: var(--pill-border-on);
}

:root[data-scheme='dark'] .novely-shell-frame {
  --pill-border-on: color-mix(in srgb, var(--text) 18%, transparent);
}

.novely-top-pill-dot {
  width: var(--shell-dot);
  height: var(--shell-dot);
  border-radius: 50%;
  background: var(--findings-dot);
}

/* ------------------------------------------------------------------------ */
/* Body                                                                       */
/* ------------------------------------------------------------------------ */

.novely-shell-body {
  flex: 1;
  display: flex;
  min-height: 0;
}

.novely-shell-rail {
  width: var(--shell-rail-w);
  flex: none;
  display: flex;
  min-height: 0;
  border-right: 1px solid var(--hairline);
}

/*
 * The centre. The manuscript is flex:1 and the companion is a fixed step
 * beside or below it -- fixed, so that opening and closing the pane moves the
 * measure by a known amount and never by "whatever is left".
 */
.novely-shell-centre {
  flex: 1;
  display: flex;
  min-width: 0;
  min-height: 0;
}

.novely-shell-manuscript {
  flex: 1;
  display: flex;
  min-width: 0;
  min-height: 0;
  background: var(--panel);
}

.novely-shell-companion {
  display: none;
  flex: none;
  min-height: 0;
  background: var(--companion);
}

.novely-shell-right {
  flex: none;
  display: flex;
  min-height: 0;
  border-left: 1px solid var(--hairline);
}

.novely-shell-right:empty {
  display: none;
}

/* Beside: 420px, on whichever side `⇄` last left it. */
.novely-shell-frame[data-companion='beside'] .novely-shell-companion {
  display: flex;
  width: var(--companion-w);
  border-left: 1px solid var(--hairline);
}

.novely-shell-frame[data-companion='beside'][data-companion-side='left'] .novely-shell-centre {
  flex-direction: row-reverse;
}

.novely-shell-frame[data-companion='beside'][data-companion-side='left'] .novely-shell-companion {
  border-left: 0;
  border-right: 1px solid var(--hairline);
}

/* Below: 300px tall, under the manuscript, inside the same column. */
.novely-shell-frame[data-companion='below'] .novely-shell-centre {
  flex-direction: column;
}

.novely-shell-frame[data-companion='below'] .novely-shell-companion {
  display: flex;
  height: var(--companion-h);
  border-top: 1px solid var(--hairline);
}

/*
 * Where the companion sits: one toggle, no caption.
 *
 * The glyph says where the pane *is*; the tooltip says what pressing does. A
 * fixed width so the bar does not shift under the pointer when it changes --
 * the two glyphs are the same width in most faces, and this makes it true in
 * all of them.
 */
.novely-top-split-toggle {
  font-size: var(--size-13);
  width: 26px;
  text-align: center;
}

/*
 * Home, at the head of the line.
 *
 * A mark, not a word: the row it used to sit in was nine grey words long, and
 * the one thing there that was navigation rather than a verb had no business
 * reading like the rest of them. Left to right the bar now says home, book,
 * chapter.
 */
.novely-top-home {
  width: 24px;
  height: 24px;
  margin-right: 2px;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--muted-2);
  font: 400 15px / 1 var(--font-ui);
  cursor: pointer;
}

.novely-top-home:hover {
  background: var(--row-hover-strong);
  color: var(--text);
}

/*
 * The book's name, edited where it is written.
 *
 * Styled to read as the label it replaced: no border, no field chrome, no hint
 * that it is an input until the caret is in it. A box around the title would
 * put a form control in the corner of a writing application, which is the one
 * corner that should look like a book.
 */
.novely-top-title {
  min-width: 4ch;
  max-width: 24ch;
  padding: 2px 4px;
  margin-left: -4px;
  border: 1px solid transparent;
  border-radius: 3px;
  background: transparent;
  color: var(--text);
  font: 500 var(--size-13-5) / 1 var(--font-ui);
  text-overflow: ellipsis;
}

.novely-top-title:hover {
  border-color: var(--border);
}

.novely-top-title:focus,
.novely-top-title:focus-visible {
  outline: none;
  border-color: var(--border-hover);
  background: var(--panel);
}

/* The chapter, after the book. Quieter, because it is also in the rail. */
.novely-top-chapter {
  color: var(--muted-2);
  font: 400 var(--size-13) / 1 var(--font-ui);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  max-width: 28ch;
}

/*
 * The palette control: the thing it changes, in miniature. A paint-pot glyph
 * would say "colours"; this says which colours.
 */
/*
 * The palette, in miniature: the Fibonacci subdivision of a square, with the
 * three colours ranked by how much of each the author actually sees.
 *
 *   +---------------+-------+
 *   |               | accent|   The numbers are in `SWATCH_GRID`, and the
 *   |     page      +-------+   reasoning with them. 8 and 5 on both axes,
 *   |               | text  |   so the same ratio governs every cut.
 *   +---------------+-------+
 *
 * No padding and no gaps -- the blocks meet, so the division reads as a
 * division rather than as three small squares. The border is the ordinary
 * hairline and not the accent any more: the accent has a block of its own now,
 * and a colour that is both an edge and a block is counted twice.
 */
.novely-top-palette {
  display: grid;
  grid-template-columns: 8fr 5fr;
  grid-template-rows: 5fr 8fr;
  overflow: hidden;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--border-strong);
  border-radius: 5px;
  cursor: pointer;
}

/* Placed rather than ordered, so the DOM can stay in the order a palette is
   written in -- page, ink, accent -- whatever corner each one lands in. */
.novely-top-palette-page {
  grid-area: 1 / 1 / 3 / 2;
}

.novely-top-palette-ink {
  grid-area: 2 / 2 / 3 / 3;
}

.novely-top-palette-accent {
  grid-area: 1 / 2 / 2 / 3;
}

/*
 * The tip: what a control is, what it does, and the key that does it (§9).
 *
 * Replaces the browser's `title`, which waited a second, could not be styled,
 * and -- the disqualifying one -- never appeared on keyboard focus, so the
 * people most likely to want a chord were the only ones who could not read it.
 */
.novely-tip {
  position: fixed;
  z-index: 60;
  max-width: 260px;
  padding: 6px 8px;
  background: var(--panel);
  border: 1px solid var(--border-strong);
  box-shadow: var(--shadow-popover);
  font-family: var(--font-ui);
  font-size: var(--size-10);
  line-height: 1.35;
  color: var(--text);
  pointer-events: none;
}

.novely-tip-label {
  font-weight: 600;
}

.novely-tip-key {
  font-family: var(--font-mono);
  margin-left: 6px;
  padding: 0 4px;
  border: 1px solid var(--border);
  color: var(--muted-5);
}

.novely-tip-detail {
  display: block;
  margin-top: 3px;
  color: var(--muted-5);
}

/* Lucide at 1.5, sized to the bar rather than to the 24-grid it is drawn on. */
.novely-icon {
  width: 15px;
  height: 15px;
  display: block;
}

/*
 * The findings pill when the count is not a fact.
 *
 * Marked, not alarmed: a red badge in the chrome of a writing application is a
 * thing an author has to dismiss before they can think, and nothing here is
 * urgent -- the manuscript is fine, only the count is unknown. The dotted ring
 * says "this is not a number" and the tooltip says why.
 */
.novely-top-pill-trouble {
  border-style: dotted;
  opacity: 0.8;
}

/*
 * Focus mode (§5): the prose, and nothing round it.
 *
 * Everything here is `display: none` on the furniture and nothing at all on the
 * manuscript, which is the point -- the writing surface is not restyled, moved
 * or re-measured on the way in. It is the same column in the same face at the
 * same measure, with the room round it given back.
 *
 * Hidden rather than unmounted, and the state behind it is a single flag, so
 * the navigator keeps its scroll, the companion keeps its tab, and the caret
 * keeps its place. Leaving focus puts back the room the author was working in
 * rather than a default one.
 */
.novely-shell-frame[data-focus='true'] .novely-shell-top,
.novely-shell-frame[data-focus='true'] .novely-shell-rail,
.novely-shell-frame[data-focus='true'] .novely-shell-companion,
.novely-shell-frame[data-focus='true'] .novely-shell-right,
.novely-shell-frame[data-focus='true'] .novely-statusbar,
.novely-shell-frame[data-focus='true'] .novely-work-rail {
  display: none;
}

/*
 * The way out.
 *
 * Present only in focus mode, and then always present: a mode that takes the
 * whole interface away has one obligation, which is to be obviously leavable by
 * somebody who has forgotten how they got in. Not a hot corner, not
 * hover-to-reveal -- a real button, in the tab order, with a visible focus
 * ring.
 *
 * Quiet at rest and plain on approach. It sits in the top right, where the
 * chrome it brings back used to be, and it carries its own ground so it reads
 * over a tether card that happens to be under it.
 */
.novely-leave-focus {
  display: none;
}

.novely-shell-frame[data-focus='true'] .novely-leave-focus {
  /*
   * A glyph now, not two words.
   *
   * Square and centred on the icon, because the only thing on screen that is
   * not the author's prose should not also be the only thing on screen with
   * words on it. What it means is in its `aria-label` and its tooltip; what it
   * does is in the chord and in Escape.
   */
  display: flex;
  align-items: center;
  justify-content: center;
  position: fixed;
  top: calc(env(safe-area-inset-top, 0px) + 10px);
  right: 14px;
  z-index: 40;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 1px solid var(--hairline);
  border-radius: var(--r-pill);
  background: var(--page);
  cursor: pointer;
  /*
   * Legible at rest, not faded in on approach.
   *
   * The first version sat at 0.55 opacity in the muted grey, which is the
   * conventional treatment and the wrong one here: an author who has forgotten
   * the chord is exactly the author who cannot find a control that is waiting
   * to be hovered. It is small and in a corner; it can afford to be readable.
   */
  color: var(--muted-4);
  transition: color 120ms ease, border-color 120ms ease;
}

.novely-shell-frame[data-focus='true'] .novely-leave-focus:hover {
  color: var(--text);
  border-color: var(--border-strong);
}

/* 16 on a 24 grid, which is the size the bar's own glyphs are drawn at. */
.novely-shell-frame[data-focus='true'] .novely-leave-focus .novely-icon {
  width: 16px;
  height: 16px;
}

/* Reached by tabbing: the one control on screen has to be findable from the
   keyboard alone, which means a ring on it and full contrast the instant it is
   reached. */
.novely-shell-frame[data-focus='true'] .novely-leave-focus:focus-visible {
  color: var(--text);
  border-color: var(--accent);
  outline: 2px solid var(--accent);
  outline-offset: 2px;
}

@media (prefers-reduced-motion: reduce) {
  .novely-leave-focus {
    transition: none;
  }
}
