/* =============================================================================
   25-tutorial.css — the inline tutorial widget: two panes, or three

   Owns:      everything under `.tut`. Nothing else on the page uses these
              class names, and nothing here reaches outside `.tut`.
   Does NOT own: the renderer's dark ground (that is a WebGL clear colour set in
              24-sandbox-gl.js), or the chapter's own heading and prose.
   Depends on: the palette tokens declared in 02-layout.css — --ink, --ink2,
              --ink3, --acc, --acctxt, --rule, --card, --wash, --paper, and the
              --mono / --sans stacks. Adds no new global tokens.

   TWO RULES THIS FILE KEEPS, AND WHY
   ----------------------------------
   1. Every class the widget writes is prefixed `tut__`. It once emitted the
      highlighter's tokens as `.c .s .k .t .n` and its listing lines as `.tl`,
      which was invisible on the standalone scratch page and catastrophic on
      the reader: 07-tiles.css owns `.t` — the *tile* — at
      `display:flex;flex-direction:column;border-top:1px solid var(--rule)`,
      so every `double3` in the listing became a flex column and each line
      shattered across three. 02-layout.css owns `pre .k`. Single letters are
      not class names on a page with seven other stylesheets.

   2. Every selector below is scoped under `.tut`. That is not only hygiene in
      the outward direction — it is what makes the widget survive the sheets
      that reach INTO it. `v4-template.html` styles `.sect h3` (0,1,1) and
      `.sect pre` (0,1,1), and both of those outrank a lone `.tut__title` or
      `.tut__code` (0,1,0); the widget's own title and its listing pane are
      exactly an `h3` and a `pre` inside a `.sect`. Scoping every rule buys
      (0,2,0) uniformly, which wins on specificity rather than on `!important`
      or on load order. Do not "simplify" a selector back to one class.

   Why the width is what it is
   ---------------------------
   22-variation.css offers .band (full bleed), .stack (44rem, centred) and
   .figrow (equal columns). None of the three fits: full bleed is the heaviest
   punctuation the page has and this widget appears twice, while 44rem is too
   narrow to put a code listing beside a 3D view without one of them becoming
   a slot. So the widget borrows .stack's manners — centred, capped, generous
   above and below — at a cap wide enough for two real panes. It never exceeds
   the section's measure-capped prose by more than the figure patterns already
   do, and it stops growing well short of the 1560px shell.
   ============================================================================= */

.tut{
  /* 86rem, not 68. This widget is the one place in the book where the reader
     stops reading and starts operating something, and at 68rem the .usda pane
     and the viewport were each about 32rem — enough to be present, not enough
     to be worked in. It still stops well short of the 1560px shell. */
  margin:2.4rem auto 2.6rem;
  max-width:min(100%,86rem);
  min-width:0;
  font-family:var(--sans);

  /* ---- window palette --------------------------------------------------
     Lifted verbatim from 24-sandbox.css so the inline widget and the full
     sandbox read as one application rather than two lookalikes. Restated as
     local custom properties rather than imported, because that sheet
     redefines :root globally and is only ever linked by sandbox.html.

     Two values are deliberately NOT the sandbox's. Its --ink3 (#7C766C) is
     3.4:1 on --panel, which is fine for a 22px dock row a user is scanning
     and not fine for a caption in the middle of a chapter, so the dim ink is
     lifted to 4.9:1. Everything else is unchanged. */
  --w-bg:#1B1A18; --w-panel:#232220; --w-panel2:#2A2825; --w-sunk:#151413;
  --w-line:#343230; --w-line2:#42403C;
  --w-ink:#E8E4DB; --w-ink2:#A9A399; --w-ink3:#948E82;
  --w-acc:#D2AE55; --w-wash:rgba(210,174,85,.14);

  /* The plate. A chapter is cream from top to bottom except here — which is
     the whole request: this is a highlight, and it should not look like the
     paragraph above it wearing a border. */
  background:var(--w-bg);
  border:1px solid var(--w-line2);
  border-radius:9px;
  padding:.9rem 1.05rem 1.15rem;
  box-shadow:0 12px 34px -22px rgba(24,21,17,.75);
}

/* ---------- heading -------------------------------------------------------
   The widget supplies its own title and caption. A chapter author writes one
   empty div, so if the widget did not label itself the reader would meet an
   unexplained pair of boxes. */

/* Inside the plate now, so it is the window's title bar rather than a caption
   floating above a pair of boxes. */
.tut .tut__head{margin:0 0 .75rem;padding:0 .15rem}
/* `letter-spacing` here is a repair, not a flourish: the reader's own
   `.sect h3` tracks headings at -.005em and this h3 sits inside a .sect, so
   every property that rule sets has to be answered or the widget's title
   inherits half a chapter heading. */
.tut .tut__title{
  margin:0;font-family:var(--sans);font-size:.95rem;font-weight:600;
  letter-spacing:normal;line-height:1.4;color:var(--w-ink);max-width:none}
.tut .tut__sub{
  margin:.28rem 0 0;font-family:var(--sans);font-size:.8rem;line-height:1.6;
  color:var(--w-ink2);max-width:64ch}

/* ---------- the two panes -------------------------------------------------
   Stacked by default so the narrow case needs no override, side by side once
   there is room for both to be readable rather than merely present. */

.tut .tut__panes{
  display:grid;gap:1px;grid-template-columns:minmax(0,1fr);
  background:var(--w-line);border:1px solid var(--w-line);border-radius:6px;
  overflow:hidden}
@media (min-width:900px){
  .tut .tut__panes{grid-template-columns:minmax(0,1fr) minmax(0,1.02fr)}
}
.tut .tut__pane{min-width:0;background:var(--w-panel);display:flex;flex-direction:column}

/* ---------- the third pane, when a preset asks for one --------------------
   A modifier, not a change to the rule above: the two-pane presets must keep
   the grid they have had all along, byte for byte, so the three-column track
   list is written only for `.tut__panes--tri` and only where it fits.

   It arrives in two stages rather than one. At 900px there is room for a
   listing beside a viewport and nothing else, so the file pane takes a full
   row of its own above them and lays its rows out along that row. Only at
   1120px does a third column stop squeezing the listing, and the file pane
   returns to being a narrow column on the left. Squeezing three columns into
   900px would have made the .usda pane — the thing being taught — the
   narrowest box on the page.

   These rules come after the 900px block above deliberately: both selectors
   are (0,2,0), so this one wins on order, not on specificity. Do not move
   them above it. */
@media (min-width:900px){
  .tut .tut__panes--tri .tut__files{grid-column:1/-1}
  .tut .tut__panes--tri .tut__tree{flex-direction:row;flex-wrap:wrap}
  .tut .tut__panes--tri .tut__file{flex:1 1 12rem}
  /* The card pane does the same thing at the same width and for the same
     reason: between 900px and 1120px there is room for a listing beside a
     viewport and nothing else, so the card takes a full row under them
     rather than squeezing the .usda pane it exists to explain. Below 900px
     everything stacks in source order and the card is back in the middle,
     which is where the chapter's prose says it is. */
  .tut .tut__panes--tri .tut__card{grid-column:1/-1;grid-row:2}
  .tut .tut__card ~ .tut__view{grid-column:2;grid-row:1}
}
@media (min-width:1120px){
  .tut .tut__panes--tri{
    grid-template-columns:minmax(0,.62fr) minmax(0,1.12fr) minmax(0,1.14fr)}
  .tut .tut__panes--tri .tut__files{grid-column:auto}
  .tut .tut__panes--tri .tut__tree{flex-direction:column;flex-wrap:nowrap}
  .tut .tut__panes--tri .tut__file{flex:none}
  .tut .tut__panes--tri .tut__card{grid-column:auto;grid-row:auto}
  .tut .tut__card ~ .tut__view{grid-column:auto;grid-row:auto}
  /* A card is content, not an index, so the three tracks it wants are not
     the ones a file list wants: .62fr is generous for four filenames and far
     too mean for a .usda listing. `:has()` asks the question directly rather
     than inventing a second layout class, and where it is not understood the
     whole rule is dropped and the widget keeps the tracks above — narrower
     than it should be, but not broken. */
  .tut .tut__panes--tri:has(.tut__card){
    grid-template-columns:minmax(0,1.04fr) minmax(0,.96fr) minmax(0,1.1fr)}
}

/* ---------- the file tree -------------------------------------------------
   Not a file switcher and not styled as one: no buttons, no hover, no cursor
   change, because there is nothing to click. It is a standing claim about
   three files on disk, and the whole lesson is which of them the controls
   below rewrite. So the two referenced files are drawn as inputs — recessed
   onto --paper, permanently tagged `unchanged` — and the shot file is drawn
   as the live document, on --card, carrying a counter that climbs every time
   an edit lands. The reader does not have to be told the reference is not
   copied; they can watch it not happen. */

.tut .tut__tree{
  list-style:none;margin:0;padding:.62rem .7rem;flex:1 1 auto;
  display:flex;flex-direction:column;gap:.36rem;align-content:flex-start}
/* 02-layout.css sets `p,li{max-width:var(--measure)}`, which would cap these
   rows at 66ch inside a pane far narrower than that and leave the tag column
   floating in the middle of the row. */
.tut .tut__tree li{max-width:none}
.tut .tut__file{
  display:flex;flex-wrap:wrap;align-items:baseline;gap:.2rem .45rem;
  padding:.42rem .52rem;border:1px solid var(--w-line);border-radius:4px;
  background:var(--w-sunk);
  font-family:var(--mono);font-size:.74rem;line-height:1.4;color:var(--w-ink2)}
.tut .tut__fname{font-weight:600;color:var(--w-ink2)}
.tut .tut__ftag{
  margin-left:auto;font-family:var(--sans);font-size:.63rem;
  letter-spacing:.03em;color:var(--w-ink3);white-space:nowrap}
/* Present in the DOM from the start and hidden here, so lighting a row adds
   no reflow to a pointer gesture that is already moving a wheel. */
.tut .tut__fwhy{
  display:none;flex-basis:100%;font-family:var(--sans);font-size:.64rem;
  line-height:1.4;color:var(--w-acc)}

/* The file the selected prim came from. */
.tut .tut__file--on{border-color:var(--w-acc);background:var(--w-wash)}
.tut .tut__file--on .tut__fwhy{display:block}

/* The one file these controls write. */
.tut .tut__file--edit{background:var(--w-panel2);border-color:var(--w-line2);color:var(--w-ink)}
.tut .tut__file--edit .tut__fname{color:var(--w-ink)}
.tut .tut__file--edit .tut__ftag{color:var(--w-acc);font-weight:600}
/* The same mark the changed lines of the listing get, on the row that took
   them — the two panes flash together or the connection is left to be
   inferred. */
.tut .tut__file--hot{background:var(--w-wash);box-shadow:inset 2px 0 0 var(--w-acc)}
@media (prefers-reduced-motion:no-preference){
  .tut .tut__file{transition:background-color .5s ease,box-shadow .5s ease,
    border-color .5s ease}
}

.tut .tut__treenote{
  margin:0 .7rem .65rem;font-family:var(--sans);font-size:.68rem;
  line-height:1.5;color:var(--w-ink3);max-width:none}

/* ---------- the fidelity card --------------------------------------------
   The middle pane of the `formats` preset. Like the file tree it is a
   standing claim rather than a control: no buttons, no hover, nothing to
   click. It borrows the tree's row shape deliberately, because both panes
   are answering the same kind of question — what is here, and what is not.

   Three states, and none of them carried by a fill colour alone. The bar is
   the glance, the word beside it is the reading, and the sentence under it
   is the accuracy: `partial` is a different width, a different word and a
   different explanation from `intact`, so a reader who sees no colour at all
   still gets the whole answer. */

.tut .tut__rows{
  list-style:none;margin:0;padding:.62rem .7rem;flex:1 1 auto;
  display:flex;flex-direction:column;gap:.36rem;align-content:flex-start}
/* 02-layout.css caps `p,li` at 66ch, which inside a pane this narrow leaves
   the level column adrift in the middle of the row. */
.tut .tut__rows li{max-width:none}
.tut .tut__row{
  display:grid;grid-template-columns:minmax(0,1fr) auto auto;
  align-items:center;gap:.18rem .5rem;
  padding:.42rem .52rem;border:1px solid var(--w-line);border-radius:4px;
  background:var(--w-sunk)}
.tut .tut__rname{
  font-family:var(--sans);font-size:.76rem;font-weight:600;line-height:1.3;
  color:var(--w-ink2)}
.tut .tut__meter{
  display:block;width:3.2rem;height:.42rem;border-radius:2px;overflow:hidden;
  border:1px solid var(--w-line2);background:var(--w-bg)}
.tut .tut__bar{display:block;height:100%;width:0;background:var(--w-acc)}
.tut .tut__lvl{
  font-family:var(--sans);font-size:.65rem;letter-spacing:.03em;
  color:var(--w-ink3);white-space:nowrap;min-width:3.3rem;text-align:right}
.tut .tut__why{
  grid-column:1/-1;margin-top:.14rem;
  font-family:var(--sans);font-size:.68rem;line-height:1.45;
  color:var(--w-ink3);max-width:none}

/* An empty track with a dashed edge: nothing arrived, and the row says so in
   its outline as well as in its word. */
.tut .tut__row--none .tut__meter{border-style:dashed}
.tut .tut__row--partial .tut__bar{width:50%;background:var(--w-acc)}
.tut .tut__row--intact{background:var(--w-panel2);border-color:var(--w-line2)}
.tut .tut__row--intact .tut__bar{width:100%}
.tut .tut__row--intact .tut__rname{color:var(--w-ink)}
.tut .tut__row--intact .tut__lvl{color:var(--w-acc);font-weight:600}
@media (prefers-reduced-motion:no-preference){
  .tut .tut__bar{transition:width .35s ease,background-color .35s ease}
}

.tut .tut__cardnote{
  margin:0 .7rem .65rem;font-family:var(--sans);font-size:.68rem;
  line-height:1.5;color:var(--w-ink3);max-width:none}

/* Each pane's own header. Dark, one line, a rule under it — this is what
   makes the widget read as an application window without a single fake
   traffic-light dot being drawn. */
.tut .tut__label{
  flex:none;padding:.4rem .7rem;background:var(--w-panel2);
  border-bottom:1px solid var(--w-line);
  font-family:var(--mono);font-size:.66rem;letter-spacing:.05em;
  color:var(--w-ink3);display:flex;align-items:center;gap:.5rem}
.tut .tut__label b{font-weight:600;color:var(--w-ink2);font-family:var(--mono)}

/* ---------- the .usda pane ------------------------------------------------ */

/* The border/border-radius/max-width triple is defensive. `.sect pre` in
   v4-template.html gives every pre in a chapter a card, a 1px rule, a 5px
   radius and a 1100px cap; this pre is already a pane inside a bordered,
   clipped grid, so it has to hand all four back. */
.tut .tut__code{
  margin:0;padding:.7rem .8rem;overflow-x:auto;flex:1 1 auto;
  font-family:var(--mono);font-size:.84rem;line-height:1.66;
  color:var(--w-ink);background:var(--w-panel);
  border:0;border-radius:0;max-width:none;
  min-height:17rem;tab-size:4}
/* Each line is its own block so a changed-line background spans the full
   width of the pane rather than stopping at the last glyph. */
.tut .tut__code .tut__line{display:block;min-height:1.62em;padding-inline:.35rem;
  margin-inline:-.35rem;border-radius:2px}
.tut .tut__code .tut__line.tut__hl{background:var(--w-wash);box-shadow:inset 2px 0 0 var(--w-acc)}
@media (prefers-reduced-motion:no-preference){
  .tut .tut__code .tut__line{transition:background-color .5s ease,box-shadow .5s ease}
}
.tut .tut__empty{color:var(--w-ink3);font-style:italic}

/* Token colours. The same five the chapters' own code plates use — see the
   --code-* tokens in v4-template.html — so a listing the widget writes and a
   listing an author typed are the same object. Each clears 7:1 on --w-panel;
   the comment grey clears 4.9:1. Restated here rather than referenced,
   because the widget also runs on a standalone scratch page with no spine. */
.tut .tut__code .tut__k{color:var(--code-k,#E3BE68);font-weight:600} /* def, uniform  */
.tut .tut__code .tut__t{color:var(--code-t,#93BECB)}     /* schema and value types  */
.tut .tut__code .tut__s{color:var(--code-s,#9DC79B)}     /* quoted names and tokens */
.tut .tut__code .tut__n{color:var(--code-n,#E5A87E)}     /* numbers                 */
/* Asset paths — @wheel.usd@. Given a colour of its own rather than folded in
   with strings, because a reference to another layer is the one token in the
   refs listing a reader is meant to pick out at a glance. */
.tut .tut__code .tut__a{color:var(--code-a,#BDACE8);font-weight:600}
.tut .tut__code .tut__c{color:var(--w-ink3);font-style:italic}

/* ---------- the 3D pane ---------------------------------------------------
   A fixed aspect so the pane does not collapse before the renderer exists and
   does not jump when it appears. The canvas fills it; the dark ground behind
   the canvas is painted here too so a slow first frame is not a white flash. */

/* The listing grows with the scene and the view does not, so on a tall stage
   the right column has spare height under the canvas. Painting the whole pane
   the renderer's own near-black keeps that spare height reading as part of the
   viewport plate rather than as a hole in the widget. */
/* 16/10 rather than 4/3, and half again as tall at the floor. A viewport you
   orbit a model in wants width; 4/3 at 13rem was a thumbnail you could just
   about drag. */
.tut .tut__view{background:var(--w-sunk)}
/* flex:1 so the viewport FILLS the pane rather than sitting in the top of it.
   The listing grows with the scene and the aspect ratio does not, so without
   this a tall stage leaves a slab of empty plate under the canvas. The
   aspect-ratio is now the floor, not the ceiling; 25-tutorial.js keeps a
   ResizeObserver on the canvas, so growing it re-sizes the drawing buffer on
   the next frame rather than stretching a stale one. */
.tut .tut__stage{position:relative;width:100%;aspect-ratio:16/10;min-height:19rem;
  flex:1 1 auto}
.tut .tut__stage canvas{display:block;width:100%;height:100%;outline:none;
  touch-action:none;cursor:grab}
.tut .tut__stage canvas:active{cursor:grabbing}
.tut .tut__stage canvas:focus-visible{outline:2px solid #D2AE55;outline-offset:-2px}

/* Anything laid over the renderer's dark clear colour takes the lighter gold
   the .tryit plate uses; --acc is tuned for ink on paper and falls to about
   3.5:1 here. */
.tut .tut__name{
  position:absolute;left:8px;top:8px;pointer-events:none;
  font-family:var(--mono);font-size:.72rem;color:var(--w-acc);
  background:rgba(21,20,19,.72);padding:.18rem .44rem;border-radius:3px}
.tut .tut__hint{
  position:absolute;left:8px;right:8px;bottom:8px;margin:0;pointer-events:none;
  font-family:var(--sans);font-size:.7rem;line-height:1.45;color:#CFC7B6;
  max-width:none;text-shadow:0 1px 2px rgba(0,0,0,.65)}
.tut .tut__hint kbd{font-family:var(--mono);font-size:.66rem;color:#D2AE55}

/* WebGL missing. Not a broken box: the pane says what is absent and then
   prints the same scene the renderer would have drawn, in words. */
.tut .tut__nogl{
  padding:.9rem 1rem;color:#CFC7B6;font-family:var(--sans);font-size:.78rem;
  line-height:1.6;max-width:none}
.tut .tut__nogl b{display:block;color:#D2AE55;font-size:.8rem;margin-bottom:.3rem}
/* The fallback's paragraph carries no class of its own, so 02-layout.css's
   `p,li{max-width:var(--measure)}` reaches it and clips it to 66ch inside a
   pane that is nothing like 66ch wide. */
.tut .tut__nogl p{margin:.4rem 0 0;max-width:none;color:inherit;
  font-family:inherit;font-size:inherit;line-height:inherit}
.tut .tut__nogl ul{margin:.5rem 0 0;padding-left:1.05rem}
.tut .tut__nogl li{font-family:var(--mono);font-size:.72rem;color:#CFC7B6;max-width:none}

/* ---------- controls ------------------------------------------------------ */

.tut .tut__ctl{display:flex;flex-wrap:wrap;gap:.42rem;align-items:center;
  margin:.7rem 0 0}
.tut .tut__ctl button{
  font-family:var(--sans);font-size:.78rem;font-weight:600;line-height:1;
  color:var(--w-ink);background:var(--w-panel2);
  border:1px solid var(--w-line2);border-radius:4px;
  padding:.48rem .7rem;cursor:pointer}
.tut .tut__ctl button:hover{background:var(--w-wash);border-color:var(--w-acc);
  color:var(--w-acc)}
.tut .tut__ctl button:focus-visible{outline:2px solid var(--w-acc);outline-offset:2px}
.tut .tut__ctl button[disabled]{color:var(--w-ink3);border-color:var(--w-line);
  background:var(--w-sunk);cursor:default}
.tut .tut__ctl button[disabled]:hover{background:var(--w-sunk);border-color:var(--w-line);
  color:var(--w-ink3)}

/* ---------- the stepped preset -------------------------------------------
   Where the other presets offer a menu of equal edits, this one offers a
   single thing to press, so that button is allowed to be the loud one: a row
   of identical buttons is a choice, and there is no choice here. When the
   last step is reached it goes quiet rather than disappearing — the reader
   should be able to see that they finished, not find the control gone.

   Both selectors are scoped and carry the button's class as well, so they
   outrank the generic `.tut .tut__ctl button` rules above on specificity and
   not on order. */
.tut .tut__ctl .tut__go{
  background:var(--w-wash);border-color:var(--w-acc);color:var(--w-acc)}
.tut .tut__ctl .tut__go:hover{background:var(--w-panel2);border-color:var(--w-acc);
  color:var(--w-acc)}
.tut .tut__ctl .tut__go[disabled]{
  background:var(--w-sunk);border-color:var(--w-line);color:var(--w-ink3)}
.tut .tut__ctl .tut__go[disabled]:hover{
  background:var(--w-sunk);border-color:var(--w-line);color:var(--w-ink3)}

/* ---------- the route buttons --------------------------------------------
   Three mutually exclusive answers to one question, not three separate
   actions, so the chosen one stays lit rather than merely having been
   pressed last. The button also carries aria-pressed, because the lit state
   is the whole of the control's meaning and a colour cannot say it to
   everyone. Both selectors carry the button's own class as well as the row's,
   so they outrank the generic button rules above on specificity. */
.tut .tut__ctl .tut__route{min-width:4.6rem}
.tut .tut__ctl .tut__route--on{
  background:var(--w-wash);border-color:var(--w-acc);color:var(--w-acc);
  box-shadow:inset 0 -2px 0 var(--w-acc)}
.tut .tut__ctl .tut__route--on:hover{
  background:var(--w-wash);border-color:var(--w-acc);color:var(--w-acc)}

/* Where the reader is. Deliberately not a button and not styled like one:
   it is the only text in the control row, and it is read, not pressed. */
.tut .tut__stepn{
  font-family:var(--sans);font-size:.74rem;line-height:1.4;color:var(--w-ink3);
  letter-spacing:.01em}

/* The reset is a retreat, not an action; it should never be the loudest
   control in the row. */
.tut .tut__ctl .tut__reset{margin-left:auto;color:var(--w-ink2);font-weight:500}
@media (max-width:640px){.tut .tut__ctl .tut__reset{margin-left:0}}

.tut .tut__field{display:flex;align-items:center;gap:.35rem;
  font-size:.76rem;color:var(--w-ink2)}
.tut .tut__field input{
  font-family:var(--mono);font-size:.78rem;color:var(--w-ink);
  background:var(--w-sunk);border:1px solid var(--w-line2);border-radius:4px;
  padding:.42rem .5rem;width:9rem;min-width:0}
.tut .tut__field input::placeholder{color:var(--w-ink3)}
.tut .tut__field input:focus-visible{outline:2px solid var(--w-acc);outline-offset:1px}

.tut .tut__swatch{width:.8rem;height:.8rem;border-radius:2px;flex:none;
  border:1px solid rgba(255,255,255,.28)}

/* ---------- caption + live region ----------------------------------------- */

/* Inside the plate, so it is the window's own footnote. --w-ink2 rather than
   --w-ink3: this one is a full sentence a reader is meant to finish. */
.tut .tut__cap{margin:.7rem 0 0;font-family:var(--sans);font-size:.78rem;
  line-height:1.6;color:var(--w-ink2);max-width:70ch}

/* The listing changes on every drag frame, so the listing itself is not the
   live region — a settled one-line summary is. Off screen, not display:none:
   a display:none live region is never announced. */
.tut .tut__status{
  position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}
