/* ============================================================================
   prototype-theme.css — the embedded-tool contracts for the PROTOTYPE family
   (grove / grove2 / grove3 — Gardener v1-v3 — and their parents hatchling +
   wilding).

   Those five pages are NOT built on the `.app` + `.sidebar` + `.stage`
   skeleton that `tool-theme.css` speaks to. They are documents: a `.wrap`
   holding a `.grid` of `.stagecol` (the sheet, sticky) + `.panelcol` (the
   tabs). They linked `tool-theme.js` — which sets `data-theme` /
   `data-vision` on <html> — but no stylesheet that answers it, and none of
   `tool-theme.css`'s selectors matched them. So three site-wide contracts
   stopped at the iframe:

     1  DARK MODE (rule 4). The toolkit went black around a frame that stayed
        a paper-white slab, because nothing here declares a dark value for
        --paper / --panel / --ink and a good deal of the chrome is a literal
        hex (#fff panels, #cfccc2 hairlines, `color:#fff` reversed out of
        `background:var(--ink)` — which in dark is white on white).
     2  THE STACKED (PHONE) LAYOUT. Their own `@media(max-width:980px)` rule
        collapses the grid with `grid-template-columns:1fr`, and `1fr`'s
        automatic minimum is MIN-CONTENT: one unwrappable control row (the
        `.scrub` transport, ~675px of buttons + year + speed) pushed the whole
        column — the drawing with it — to 639px inside a 356px frame. The tool
        was ~2x wider than the phone and everything past the fold was
        unreachable sideways.
     3  THE VISION MODES (rule 13b). `tool-theme.css` filters `.stage >
        canvas`; here the canvas IS `.stage` (`<canvas id="stage" class="stage">`),
        so the invert+dilate never landed on the drawing.

   Linked AFTER each prototype's own <style>, so these declarations win on
   document order at equal specificity. No prototype's <style> needs editing.

   WHAT DOES NOT INVERT: the drawing. Every canvas here paints its own ground
   from `state.paper` (the student's chosen paper colour) before it inks, so
   the sheet stays as drawn in both modes — the same rule the rest of the
   toolkit follows. Only the CHROME around it themes.
   ============================================================================ */

/* ── 1 · DARK MODE ──────────────────────────────────────────────────────── */

/* The family's own five tokens, given a second set of values. Same palette as
   tool-theme.css so a prototype and a ported tool are the same black. */
:root[data-theme="dark"] {
  color-scheme: dark;

  --paper: #0b0b0c;  /* page  — the toolkit shell's black */
  --panel: #151618;  /* cards, tabs, inputs: one step up from the page */
  --line: #33343a;   /* rules and hairlines */
  --ink: #f2f0ec;    /* the one ink — warm off-white */
  --mut: #23252a;    /* the disabled / secondary fill */

  --accent: #74a8ff; /* the light-mode blue reads ~2:1 on black */
  --warn: #e8b04a;
  --good: #4ec99a;
}

/* Reversed-out labels. Every one of these is `color:#fff` sitting on
   `background:var(--ink)` — white on a near-white ink once dark lands. The
   contrasting colour is the PAGE, in both modes. The fill is restated here
   because the panel rule below names `.chip`, and a themed selector outranks
   the tool's own `.chip.on` — a SELECTED chip has to keep its ink. */
:root[data-theme="dark"] button.act,
:root[data-theme="dark"] .tabs button[aria-selected="true"],
:root[data-theme="dark"] .chip.on,
:root[data-theme="dark"] .rb-pop button.pri {
  background: var(--ink);
  color: var(--paper);
  border-color: var(--ink);
}
:root[data-theme="dark"] .chip.on .dot {
  border-color: var(--paper);
}

/* Panels, inputs and hairlines that were spelled as literal hexes. */
:root[data-theme="dark"] select,
:root[data-theme="dark"] input[type="number"],
:root[data-theme="dark"] input[type="text"],
:root[data-theme="dark"] button.ghost,
:root[data-theme="dark"] .chip:not(.on),
:root[data-theme="dark"] .mark,
:root[data-theme="dark"] .mark .exp,
:root[data-theme="dark"] .rb-btn,
:root[data-theme="dark"] .rb-pop,
:root[data-theme="dark"] .rb-pop button,
:root[data-theme="dark"] details {
  background: var(--panel);
  color: var(--ink);
}
:root[data-theme="dark"] .mark,
:root[data-theme="dark"] .mark .exp,
:root[data-theme="dark"] .rb-btn,
:root[data-theme="dark"] details,
:root[data-theme="dark"] .lyrcolor,
:root[data-theme="dark"] .mark .swrap,
:root[data-theme="dark"] .legend canvas,
:root[data-theme="dark"] .chip:not(.on) .dot {
  border-color: var(--line);
}
:root[data-theme="dark"] .mark .body {
  border-top-color: var(--line);
}
:root[data-theme="dark"] button.act:disabled {
  background: var(--mut);
  color: #8b9199; /* the one muted grey tool-theme.css uses for a dead control */
  border-color: var(--line);
}

/* The coloured washes: small badges and the honesty note, all of which carry
   dark text on a pale ground. Lift the ground, drop the text to the one ink. */
:root[data-theme="dark"] .honesty {
  background: #2a2118;
}
:root[data-theme="dark"] .prov,
:root[data-theme="dark"] .zone,
:root[data-theme="dark"] .trange {
  color: var(--ink);
  border-color: var(--ink);
}
:root[data-theme="dark"] .prov.lit { background: #16301f; }
:root[data-theme="dark"] .prov.illus { background: #33291a; }
:root[data-theme="dark"] .zone.risk { background: #3a2418; }

/* Wilding's own chrome. It is the same skeleton with a STEP rail on top, so
   it brings three more selectors that spell their colours as literal hexes:
   the selected step (white out of `var(--ink)`), that step's hint, and the
   two muted labels in the seed-mix list. */
:root[data-theme="dark"] .steps button[aria-selected="true"],
:root[data-theme="dark"] .steps button[aria-selected="true"] .step-no,
:root[data-theme="dark"] .steps button[aria-selected="true"] .step-lb,
:root[data-theme="dark"] .steps button[aria-selected="true"] .step-hint {
  color: var(--paper);
}
.step-hint,
.mix-item .sci,
.mix-item .role {
  color: var(--ink);
}

/* THE NO-GREY RULE (rule 4), which the family predates: v1 and v2 mute their
   captions and footnotes to #4a483f / #6a685f / #3a382f, and v3 already went
   back to #111. One ink per mode, in BOTH modes — to recede, these are already
   smaller. (v3's literal #111 would otherwise stay black on the black page.) */
.cap,
.mini,
.foot,
.readout,
.brushnote,
.closureNote,
.mark .fam,
.rb-pop .lbl2,
.rb-btn {
  color: var(--ink);
}

/* The drawings and their swatches keep the paper they were painted on. Named
   explicitly so a frame that is mid-repaint can't flash the dark page through
   a canvas that has not re-inked yet. */
:root[data-theme="dark"] canvas.stage,
:root[data-theme="dark"] .evostrip,
:root[data-theme="dark"] .stagecol > canvas,
:root[data-theme="dark"] .legend canvas,
:root[data-theme="dark"] .mark .swrap {
  background: #faf9f6;
}

/* Match the parent's cross-fade so the frame doesn't snap while the page
   around it eases (same rule tool-theme.css gives the ported tools). */
:root[data-theme] body {
  transition: background-color .18s ease, color .18s ease;
}
@media (prefers-reduced-motion: reduce) {
  :root[data-theme] body { transition: none; }
}

/* ── 2 · THE VISION MODES (rule 13b) ────────────────────────────────────── */

/* Here the drawing surface IS the stage — `<canvas id="stage" class="stage">`
   — not a child of one, which is why tool-theme.css's selector set missed it.
   The filters themselves are injected into this document by tool-theme.js. */
:root[data-vision] canvas.stage,
:root[data-vision] .stagecol > canvas,
:root[data-vision] .evostrip {
  filter: url(#amw-vision-contrast);
}
:root[data-vision="yellow"] canvas.stage,
:root[data-vision="yellow"] .stagecol > canvas,
:root[data-vision="yellow"] .evostrip {
  filter: url(#amw-vision-yellow);
}
:root[data-vision] .stagecol {
  background: #000; /* the vision modes' ground is literally black */
}

/* ── 3 · EMBEDDED: the page header is the PAGE's job ────────────────────── */

/* `amw-framed` lands on <html> from tool-theme.js when the tool is running
   inside the toolkit. The masthead — kicker, title, standfirst, tag — is the
   standalone page's; embedded, the route above it already shows all four in
   ToolPageHeader, and repeating them cost ~430px of a 763px frame, i.e. you
   landed on Gardener and saw a title you had just read instead of the tool. */
:root.amw-framed > body .wrap > header {
  display: none;
}
:root.amw-framed > body .wrap {
  padding-top: 18px;
}

/* ── 3b · THE LAPTOP: the drawing has to FIT THE FRAME ──────────────────── */

/* Reported as "it doesn't work on the laptop", and it is two faults compounding,
   both of which come from `100vh` meaning the FRAME here, not the window:

     1  THE SHEET WAS TALLER THAN THE FRAME. `canvas.stage { width: 100% }` and a
        square sheet means the drawing's height is the COLUMN'S WIDTH — 844px on
        a 1440 laptop, 794px on a 1366 — inside a frame that is 85vh of a laptop
        window, i.e. 623px and 525px. You could see about half your own drawing
        and had to scroll a page inside a page for the rest, and it got WORSE the
        wider the screen: more width, taller sheet, same frame.
     2  THE STICKY COLUMN DIED ON EXACTLY THOSE SCREENS. The prototypes drop the
        sticky sheet under `@media(max-height:620px)` — written for a genuinely
        short standalone window. Inside an 85vh frame that query is true on most
        laptops (525px, 542px, 593px…), so the drawing scrolled away the moment
        you reached for a control, which is the one thing the sticky column
        exists to prevent.

   So: the sheet is capped to the height the frame actually has (it keeps its
   aspect — `width/height:auto` + both maxima is the replaced-element fit, and
   the sheet's ratio is the student's Sheet setting), and the column goes back to
   being sticky at any frame tall enough to hold a drawing.

   `901px`, not the prototypes' own `980px`: the cap belongs wherever the
   EMBEDDER is holding a fixed-height frame, and the height bridge in
   tool-theme.js only takes that over below 900px. The 80px in between is where
   the two breakpoints used to disagree — the tool had already stacked into one
   tall column while the frame was still 85vh, so a 914px sheet sat in a 593px
   porthole. Below 901px the frame is the document's own height and the sheet
   is free to be the full width of it. */
@media (min-width: 901px) {
  .stagecol > canvas.stage {
    width: auto;
    height: auto;
    max-width: 100%;
    /* the frame, less the save bar above the sheet and the caption + view rows +
       transport below it: what has to be on screen WITH the drawing. Measured,
       not guessed — 239px at a wide frame, 257px once the view rows start
       wrapping in a narrow one, so the narrow case sets this figure. */
    max-height: calc(100vh - 17rem);
    /* flush left, NOT centred: the caption, the View row and the transport all
       start at the column's left edge, and a centred sheet reads as misaligned
       with its own controls. */
    margin-inline: 0;
  }

  .grid > .stagecol {
    position: sticky;
    top: 10px;
    max-height: calc(100vh - 20px);
    overflow: auto;
    overscroll-behavior: contain;
  }
}

/* NOT DONE, and it was tried: narrowing the sheet column on a short frame so the
   panel could use the width the height-capped sheet no longer needs. It looks
   better and it costs the drawing — the rows under the sheet (View, Colour,
   Projection) are single-line flex rows, so a narrower track either clips the
   last button or, once you let them wrap, pushes the transport below the fold
   at 1366×768. The sheet is the point; the empty track beside it is the lesser
   evil. Measured both ways with grove-layout-smoke. */

/* A frame wide enough that the rows under the sheet stop wrapping hands ~26px
   back to the drawing. Worth stating: at these sizes the sheet is the only
   thing anyone is looking at. */
@media (min-width: 1281px) {
  .stagecol > canvas.stage {
    max-height: calc(100vh - 15.5rem);
  }
}

/* ── 4 · THE STACKED (PHONE) LAYOUT ─────────────────────────────────────── */

/* Their own single-column breakpoint. `minmax(0, 1fr)` is the whole fix for
   the sideways blow-out: it takes the track's automatic minimum off
   min-content, so an unwrappable row can no longer widen the column (and the
   sheet inside it) past the screen. The wrapping below is what stops that row
   being unwrappable in the first place — without it the row merely overflows
   its own column instead of the document. */
@media (max-width: 980px) {
  /* `:has(> .stagecol)` keeps this to the sheet-and-panels family, whose own
     single-column breakpoint is 980px. Wilding's grid is a different shape and
     collapses at 880px — it gets the identical fix at ITS breakpoint below,
     rather than having this one move it a hundred pixels early. */
  .grid:has(> .stagecol) {
    grid-template-columns: minmax(0, 1fr);
  }

  .scrub,
  .toolbar,
  .savebar,
  .palette,
  .readout,
  .legend,
  .row {
    flex-wrap: wrap;
  }

  /* A range in a wrapped row still needs a usable track, and `flex:1` alone
     lets it size from its (large) intrinsic width. */
  .scrub input[type="range"],
  .row input[type="range"] {
    flex: 1 1 160px;
    min-width: 0;
  }
  .row label {
    flex: 0 0 100px;
  }
  .savebar select,
  .savebar .chip {
    max-width: 100%;
  }
  .yrbig {
    min-width: 0;
  }

  /* The tab strip is six equal cells; at 356px that is 59px each and the
     labels clip. Let them run to two rows instead. */
  .tabs {
    flex-wrap: wrap;
  }
  .tabs button {
    flex: 1 0 33%;
  }

  /* Nothing here may set the document's width: the embedder sizes the frame to
     this document's HEIGHT (the bridge in tool-theme.js), and a horizontal
     overflow inside it is a sideways scroll the parent page can't reach. */
  .wrap {
    max-width: 100%;
    padding-left: 14px;
    padding-right: 14px;
    overflow-x: clip;
  }
}

@media (max-width: 880px) {
  .grid {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* NOT SQUARE, deliberately (DESIGN-RULES §9.4b's stated exception). These
   tools draw a SHEET whose aspect is a control the student sets — the Sheet
   tab's page shape, checked by grove-sheet-smoke — so it is a measurement,
   not a layout choice, the same reason tool-theme.css leaves the scale bar's
   `#wrap` alone. It is full-column-width and it keeps the ratio you typed. */
