/* 20-editor.css — see 00-contract.css for the rules this file obeys.
   Every rule below is inside a max-width or pointer:coarse media query.

   Owns the compact half of notes/shell.html's docbar + #toolbar. The
   desktop half — `.tb-group`/`.tb-group__panel { display: contents }`,
   the per-button `order` values that undo the grouping's DOM reshuffle —
   lives in shell.html's own <style> block, not here, because that half
   must be visible to a >900px pointer browser too (it is what PROVES
   this layer changes nothing there) and 00-contract.css requires every
   rule in this directory to sit inside a compact/touch media query. Read
   shell.html's head-block comment before touching either half. */

@media (max-width: 900px) {
  /* ---------- the collapsing groups (.tb-group) ----------
     Shared by both bars: notes/shell.html wraps every less-essential
     run of docbar/toolbar buttons in one of these — one `.tb-group__
     toggle` plus a `.tb-group__panel` holding the group's real,
     unmodified buttons/links/forms/<details>. Above 900px both are
     `display: contents` (shell.html's <style> block) and vanish
     entirely; below it they become a tap-to-open popover. */
  .tb-group {
    display: inline-block;
    position: relative;
  }
  /* Scoped to the two bars rather than left bare, and that scoping is
     the only reason this rule takes effect at all: shell.html's head
     block hides the toggle with `.docbar .tb-group__toggle, .toolbar
     .tb-group__toggle` — (0,2,0), which IT needs in order to out-specify
     app.css's `.toolbar button { display: grid }` (see that block's own
     comment). A bare `.tb-group__toggle` here is (0,1,0) and loses that
     tie no matter how late this layer is linked, so all three toggles
     stayed `display: none` at every width and every control inside a
     group — Table options among them — was unreachable below 900px while
     the page still looked deliberate. Matching the selector exactly puts
     the two rules on equal specificity, where source order decides, and
     00-contract.css guarantees this layer is linked last. */
  .docbar .tb-group__toggle,
  .toolbar .tb-group__toggle {
    display: grid;
    place-items: center;
    width: 28px;
    height: 28px;
    border-radius: var(--radius);
    color: var(--ink-3);
    background: none;
    border: 0;
  }
  .tb-group__toggle svg { width: 15px; height: 15px; }
  .tb-group__toggle:hover { background: var(--surface-2); color: var(--ink); }
  /* Surfaces "something in here is active/relevant" on the closed
     toggle itself, without making the user open it to find out —
     editor.js's syncToolbarState() still toggles .is-active directly on
     the real [data-cmd] buttons (a plain querySelectorAll("[data-cmd]"),
     unaware and unaffected by which wrapper now contains them), so this
     is a pure read of that existing state via :has(), not a second
     source of truth to keep in sync. */
  .tb-group:has(.is-active) > .tb-group__toggle {
    background: var(--accent-wash);
    color: var(--accent);
  }
  /* mobile_toolbar.js toggles this exact class (via ELN.dismissible(),
     same is-open convention as .panel/.swatch-popup/.table-popup) — it
     never touches .tb-group__panel's own display directly. */
  .tb-group.is-open > .tb-group__toggle {
    background: var(--surface-2);
    color: var(--ink);
  }
  .tb-group__panel {
    display: none;
    /* position: fixed, not the `position: relative` parent + absolute
       child that .docbar__menu-panel uses (app.css) — deliberately.
       #toolbar carries app.css's `overflow-y: auto; max-height: 40vh`
       for its pre-collapse many-row desktop layout (see the override
       below, which removes exactly that now that collapsing usually
       gets it back to one row); an absolutely-positioned descendant of
       an ancestor with overflow:auto/hidden is clipped the instant it
       extends past that ancestor's own box, which a panel opening
       BELOW a 28px-tall bar always does. Fixed positioning is not
       subject to an ancestor's overflow (no ancestor here sets
       transform/filter/perspective, so the viewport stays its
       containing block) — the same reason .swatch-popup, .table-popup
       and .user-menu__popup (app.css) are all `position: fixed` too.
       mobile_toolbar.js sets top/left|right in its `onOpen`, the same
       point topbar.js's user-menu popover computes its own place(). */
    position: fixed;
    z-index: 65;
    flex-wrap: wrap;
    align-items: center;
    gap: 0.3rem;
    max-width: calc(100vw - 2 * var(--gutter-compact));
    padding: 0.4rem;
    background: var(--surface);
    border: 1px solid var(--rule);
    border-radius: 6px;
    box-shadow: var(--shadow-pop);
  }
  .tb-group.is-open > .tb-group__panel { display: flex; }
  /* The inline `order` values on these children exist ONLY to undo the
     grouping's DOM reshuffle for the desktop's flattened `display:
     contents` layout (see shell.html) — once the panel lays them out
     as its own flex row, that meaning is gone, and leaving the numbers
     live would quietly reorder the popover's own, independently-chosen
     button sequence (e.g. Insert's image/file/link, whose group order
     values are 15/16/23 — correct for interleaving with Insert's own
     table buttons on the DESKTOP row, wrong for "the order I actually
     wrote them in this popover"). */
  .tb-group__panel > * { order: initial; }
  /* Buttons and links inside a group popover already inherit .icon-btn/
     .toolbar button's sizing; a bare <select> (Style's font-size) is
     the one member that isn't, so it needs its own baseline. (The
     "Move to a different project" <details> inside the docbar's More
     group needs no override at all — app.css's `.docbar__menu {
     position: relative }` already gives its own `.docbar__menu-panel`
     the positioned ancestor it anchors to; that has nothing to do with
     whether the surrounding popover is flex or block.) */
  .tb-group__panel select { height: 28px; }

  /* ---------- the docbar ----------
     The bar itself never wraps (app.css: display:flex, no flex-wrap),
     so at a phone width with a long title AND a full run of icon
     buttons it simply overflowed. The fix is not to shrink the icon
     buttons (fixed-size .icon-btn = a fixed, known hit target — the
     right thing to keep FIXED) but to let .doc-title actually give up
     the width flex already wants to take from it: without min-width:0
     a flex item's minimum size defaults to its content's un-wrapped
     intrinsic width, which for a `white-space: nowrap` title is the
     WHOLE title — the ellipsis in app.css's .doc-title was always
     correct CSS, just never reachable, because nothing before this let
     the box holding it get smaller than that. */
  .doc-title {
    flex: 1 1 auto;
    min-width: 0;
  }
  .docbar {
    padding: 0 var(--gutter-compact);
  }

  /* ---------- the formatting toolbar ----------
     app.css's max-height:40vh + overflow-y:auto exists for the
     pre-collapse many-row desktop-width-independent wrap; collapsing
     three groups usually gets the whole bar back to one row, and the
     overflow box is exactly what would clip a .tb-group__panel that
     tried to stay `position: absolute` (see that rule's own comment) —
     removed here, not fought around. */
  .toolbar {
    padding: 0.4rem var(--gutter-compact);
    max-height: none;
    overflow-y: visible;
  }
  /* The three separators that used to mark off "row 2" / "row 3" /
     "row 4" on desktop now mostly sit between a still-visible button
     and a group toggle (or between two toggles) — visual noise once
     most of what they separated is one tap behind a group icon. */
  #toolbar > .sep {
    display: none;
  }
  #tb-block-type {
    /* app.css's 7rem min-width is sized for a desktop row with room to
       spare; the always-visible compact row (paragraph style, bold,
       italic, the two lists, three group toggles, annotate) has none. */
    min-width: 5.2rem;
  }
  /* Annotate stays a plain always-visible [data-cmd] button (see its
     own comment in shell.html for why it isn't grouped) — this is
     purely a "look here" cue for the one moment that matters: the
     instant editor.js's syncToolbarState() clears .is-unavailable
     because an image just got selected. Without it the button looks
     exactly like it did a second ago and a phone user staring at a
     freshly-tapped image has no reason to look at the toolbar at all. */
  #toolbar button[data-cmd="annotate"]:not(.is-unavailable) {
    background: var(--accent-wash);
    color: var(--accent);
  }

  /* ---------- full-bleed editing surface ----------
     Jeremy's ask, verbatim: "borders have to go to use the already
     narrow full width." .page's desktop padding/radius/shadow are
     print-page chrome — appropriate on a desk-sized canvas, pure
     wasted width on a phone, where the "page" IS the screen. */
  .canvas__scroll {
    padding: 0.9rem var(--gutter-compact) 3rem;
  }
  .page {
    padding: 1.1rem var(--gutter-compact) 2.4rem;
    border-radius: 0;
    box-shadow: none;
    /* Functionally inert on its own — .canvas__scroll is always
       narrower than --page-width (~933px) at this breakpoint, so
       width:100% already wins over app.css's max-width here — but
       explicit rather than assumed, so nothing about app.css's
       print-width math (see that rule's own long comment) has to stay
       true forever for "full width below 900px" to keep holding. */
    max-width: none;
  }
}

@media (max-width: 600px) {
  /* iOS zooms a focused control whose font is under 16px and never
     zooms back out (00-contract.css) — .toolbar select's desktop
     0.78rem (~12.5px) is well under that, and now that font-size lives
     inside the Style group's popover rather than a fleeting toolbar
     click, a user is more likely to actually focus it. */
  .toolbar select {
    font-size: 16px;
  }
  .canvas__scroll {
    padding: 0.7rem var(--gutter-compact) 2.4rem;
  }
  .page {
    padding: 0.9rem var(--gutter-compact) 2rem;
  }
}

@media (pointer: coarse) {
  /* Hit-area only (00-contract.css: TOUCH never changes layout) — an
     iPad in landscape keeps the >900px desktop grouping (no .tb-group
     popovers there) but still has no cursor, so its buttons need the
     same floor everything else in this file gets. Scoped to the two
     bars this file owns, not the bare .icon-btn class other pages'
     chrome (topbar, sidebar) also uses. */
  .docbar .icon-btn,
  .docbar .tb-group__toggle,
  .toolbar button,
  .toolbar .tb-group__toggle {
    min-width: var(--tap);
    min-height: var(--tap);
  }
  .docbar,
  .toolbar {
    gap: 0.4rem;
  }
  /* The one visibility rule in this block, and still not layout: it is a
     capability. A touch device has a camera the page can open directly
     (shell.html's #photo-input carries `capture`); a mouse browser would
     only get a duplicate "Insert image". Same specificity as app.css's
     hiding rule, which this layer outranks by loading last. */
  .toolbar #insert-photo-btn {
    display: grid;
  }
}

/* =====================================================================
   Three corrections found by driving the real page at 375pt, after the
   grouping above was in place. Each was invisible from reading the CSS
   alone, which is why they are recorded here rather than folded silently
   into the blocks above.
   ===================================================================== */

@media (max-width: 900px) {
  /* ---------- 1. the group toggles were jumping the queue ----------
     Every real control carries an inline `order` (1-23) so that
     `display: contents` can reconstruct the exact desktop sequence. The
     three .tb-group wrappers had none — and an unset `order` is 0, which
     in flexbox sorts BEFORE 1. So the moment the wrappers became real
     flex items here (they are `display: contents` on the desktop, where
     order never applied to them at all), all three menu buttons leapt to
     the head of the bar: the phone toolbar opened
     [Style][Insert][Cite] Heading-2 B I ... with the block-type select
     stranded between Bold and Italic.

     Each wrapper takes the order of the first control it swallowed, so
     the collapsed bar reads in the same left-to-right sequence as the
     expanded desktop one: type, B, I, [Style], lists, [Insert],
     Annotate, [Cite]. */
  .toolbar > .tb-group[data-tb-group="style"] { order: 6; }
  .toolbar > .tb-group[data-tb-group="insert"] { order: 12; }
  .toolbar > .tb-group[data-tb-group="science"] { order: 18; }

  /* ---------- 3. tables in the note body ----------
     Tiptap wraps every table in .tableWrapper, which already carries
     overflow-x: auto — but the table inside is `table-layout: fixed;
     width: 100%`, so it never overflows anything: it divides whatever
     width it is given equally between the columns and takes the loss out
     of the text. A five-column results table on a 375pt screen came out
     at 66px a column, which broke "Lipofectamine (uL)" across three
     lines and made the header unreadable while leaving the wrapper's
     scrollbar with nothing to scroll.

     `width: max-content` lets the columns size to their content and the
     wrapper finally do its job; `min-width: 100%` keeps a narrow
     two-column table filling the measure rather than huddling at the
     left. Column-drag resizing (Table.configure({ resizable: true }))
     depends on the fixed layout and stops working under this rule — an
     acceptable trade at a width where dragging a 1px column border with
     a fingertip was never going to happen, and it is restored in full
     the moment the viewport is wide enough for the desktop rule again. */
  .page .tableWrapper > table {
    table-layout: auto;
    width: max-content;
    min-width: 100%;
  }

  /* editor.js's right-margin table-options button, hidden here for the
     same reason the column-drag handles above stop working: the compact
     .page has ~10px of side padding instead of 5.2rem, so there is no
     margin for it to sit in — it would float on top of a table that is
     itself scrolling sideways under it. The toolbar's own Table options
     button (inside the Insert group) is the route at this width. */
  .table-margin-btn { display: none; }
}

@media (max-width: 600px) {
  /* ---------- 2. the title was crushed to three characters ----------
     .doc-title already had `flex: 1 1 auto; min-width: 0` so it could
     yield width — and it yielded all of it. The docbar's other children
     are all flex: none, and on a 375pt screen the state chip (61px),
     .doc-saved (115px) and three 44px touch targets left the title
     exactly 24px: "T...". Measured, not guessed.

     .doc-saved is the one that gives way, because it is the only thing
     in the bar that is pure status and already said twice: the chip
     beside it carries the note's state, and an autosave that failed
     escalates to .doc-saved--error/--warn, which stays visible below.
     Losing "All changes saved · v1" buys the title ~115px, which is the
     difference between three characters and most of a real sentence. */
  .doc-saved:not(.doc-saved--warn):not(.doc-saved--error) { display: none; }
}
