/* ---------- Script Forge ----------
   The screenplay page, and later the panels that read it. Colour comes from
   the rack (tokens.css); the paper set is on the bare root beside --mark, for
   the reason named there: a printed page is a physical object in the room and
   does not re-tint when the light changes.

   THE GEOMETRY MIRROR. The block below is the stylesheet's copy of GEOMETRY in
   lib/screenplay.js. It has to exist — the engine cannot reach into CSS, and a
   build step that could generate one from the other is forbidden here — so it
   is a mirror with a gate on it: tools/scriptforge/battery.mjs reads both and
   fails the battery if a single number disagrees, or if any of them is written
   twice in this file. The page and the Pages panel share the block rather than
   each declaring their own, because two copies of one number is exactly what
   the gate exists to prevent. */
/* The Reader joins this list rather than declaring its own copy: a screenplay
   read in the Reader is the same page as a screenplay written in Script Forge
   (Mark, 2026-08-21), and this block is the one home for its geometry. */
.sf, .sf-pages, .rd-script{
  --sf-page-w:85ch;
  --sf-left:15ch;
  --sf-right:10ch;
  --sf-character:37ch;
  --sf-paren:31ch;
  --sf-paren-r:29ch;
  --sf-dialogue:25ch;
  --sf-dialogue-r:25ch;
}

.sf{
  display:flex;
  flex-direction:column;
  height:100%;
  min-height:0;
}

/* the count strip: quiet, above the paper, the room's own furniture */
.sf-strip{
  display:flex;
  align-items:center;
  justify-content:flex-end;
  gap:var(--s5);
  padding:0 var(--s7) var(--s2);
  font-size:var(--t-tiny);
  color:var(--muted);
  font-variant-numeric:tabular-nums;
}

/* A PAGE BIGGER THAN THE WINDOW MUST STILL BE REACHABLE. The sheet was
   centred with auto margins, which is right until it is wider than the box
   it sits in: then the overflow is split down both sides and the left half
   becomes unreachable, because a scroll container cannot scroll back past
   its own start. At 150 per cent the right margin of the page was simply
   cut off and every measurement still passed.

   `safe center` is the whole fix: centre it while it fits, and fall back to
   the start the moment it does not, so the scrollbar can reach all of it. */
.sf-col{
  flex:1;
  min-height:0;
  overflow:auto;
  padding:var(--s7) var(--s8) 90px;
  display:flex;
  flex-direction:column;
  align-items:safe center;
}

/* the paper itself. 12pt Courier at 85 characters is not a style choice, it is
   the format: it is why a page is a minute. */
/* THE PAGE IS DRAWN AT A SIZE THE WRITER PICKS, and the format does not move
   when they pick it. Everything on this sheet is measured in characters and
   ems against the sheet's own type size, so ONE number scales the whole page
   and a slug still sits at 1.5 inches of it.

   That is also why the vertical margins are in em rather than inches: an inch
   at 12pt Courier is exactly six em (72pt over 12), so 6em IS the one inch
   margin, and it is the one inch margin at every zoom instead of only at one
   hundred per cent. */
.sf-sheet{
  width:var(--sf-page-w);
  min-width:var(--sf-page-w);
  position:relative;
  overflow:visible;
  background:var(--sf-paper);
  color:var(--sf-pencil);
  font-family:var(--sf-mono);
  font-size:calc(12pt * var(--sf-zoom, 1));
  line-height:1;
  /* an inch at the head, a little less at the foot: 6 + 55 + 5 = 66, which
     is eleven inches at six lines to the inch. GEOMETRY owns those three. */
  padding:6em 0 5em;
  /* THE LAST PAGE IS A PAGE TOO. The sheet holds every page in one block, so
     its own floor has to be all of them: the writing ends where it ends and
     the paper does not. One page was the floor before, which is why the last
     sheet stopped a third of the way down and read as half a page. */
  min-height:calc((var(--sf-sheets, 1) * 66 + (var(--sf-sheets, 1) - 1) * var(--sf-gutter, 3)) * 1em);
  box-shadow:var(--sh-card);
  flex:none;
}

.sf-body{ outline:none; white-space:pre-wrap; word-break:break-word; caret-color:var(--sf-pencil); }

/* ---------- the elements ---------- */
.sf-ln{
  position:relative;
  min-height:1em;
  line-height:1;
  padding-left:var(--sf-left);
  padding-right:var(--sf-right);
}
.sf-ln:empty::after{ content:"\200b"; }
.sf-scene{ text-transform:uppercase; }
.sf-character{ text-transform:uppercase; padding-left:var(--sf-character); }
.sf-paren{ padding-left:var(--sf-paren); padding-right:var(--sf-paren-r); }
.sf-dialogue{ padding-left:var(--sf-dialogue); padding-right:var(--sf-dialogue-r); }
.sf-transition{ text-transform:uppercase; text-align:right; }
.sf-center{ text-align:center; }
.sf-section,.sf-synopsis{ color:var(--sf-outline); font-style:italic; }
.sf-contd::after{ content:" (CONT'D)"; color:var(--sf-gray); }
.sf-dual::before{
  content:"DUAL";
  position:absolute;
  right:1ch;
  font-size:8pt;
  color:var(--sf-force);
}

/* the force marks: . ! @ > # = and the dual caret. Gray on the page, gone in
   print. They are the writer telling the page what to do, not the script. */
.sf-fm{ color:var(--sf-force); }

/* ---------- the cover sheet ---------- */
.sf-title{ color:var(--sf-pencil); padding-left:var(--sf-left); padding-right:var(--sf-right); }
.sf-title[data-k=title]{ text-align:center; text-transform:uppercase; }
/* MIRRORED IN GEOMETRY (COVER_TITLE_DROP). 2.5in is 15 lines at six to
   the inch, and the engine counts it, or the cover is not one page. */
.sf-title.sf-tk[data-k=title]{ margin-top:15em; }
.sf-title[data-k=credit],
.sf-title[data-k=author],
.sf-title[data-k=authors],
.sf-title[data-k=source]{ text-align:center; }
.sf-title.sf-tk[data-k=credit]{ margin-top:2em; }
.sf-title.sf-tk[data-k=author]{ margin-top:1em; }
/* MIRRORED IN GEOMETRY (COVER_CONTACT_DROP). 3in is 18 lines. */
.sf-title.sf-tk[data-k=contact]{ margin-top:18em; }
.sf-title[data-k=draft-date]{ text-align:right; }
.sf-title[data-k=contact],
.sf-title[data-k=copyright],
.sf-title[data-k=notes]{ text-align:left; }
.sf-title.sf-keyonly{ color:var(--sf-key); }
.sf-title .sf-fm.sf-key{ color:var(--sf-key); font-size:8pt; }

/* The key (Title:, Author:) is plumbing, not print: it hangs in the margin at
   zero width so the value itself centres true on the page, and it is only
   visible while the caret is on its line. */
.sf-title .sf-fm.sf-key{
  display:inline-block;
  width:0;
  white-space:nowrap;
  transform:translateX(-100%);
  visibility:hidden;
}
.sf-title.sf-cur .sf-fm.sf-key{ visibility:visible; }
.sf-title.sf-keyonly .sf-fm.sf-key{ display:inline; width:auto; transform:none; visibility:visible; }

/* ---------- the page break ----------
   The gap between two sheets, with the page number in the top margin of the
   one below. The mask is the room's own ground, so the paper reads as two
   pages rather than one long roll. */
/* THE GAP IS THE REST OF THE PAGE. --sf-gap is set per break by whoever drew
   it, from GEOMETRY, and it is the foot of the page above plus whatever of
   that page went unwritten plus the head of the page below. It was a fixed
   18em, which is right on a page that ends exactly full and wrong on every
   other one: every page came out an inch too long, and a page that broke
   early to keep a speech whole came out shorter than its neighbours. */
/* THE PAGE IS THE FORMAT, THE GUTTER IS FURNITURE, and they are two numbers
   because they are two different kinds of thing. --sf-gap is the rest of the
   page: the foot of the one above, whatever of it went unwritten, and the head
   of the one below, all of it PAPER. --sf-gutter is the strip of room between
   two sheets, which exists only because this is a screen and not a stack of
   paper. Painting the gutter over the margins, as the first attempt did, gives
   a page with no foot and no head: correct arithmetic, wrong picture. */
.sf-page-gutter,
.sf-sheet{ --sf-gutter:3; }
.sf-pb{ margin-top:calc((var(--sf-gap, 11) + var(--sf-gutter, 3)) * 1em); }
/* ::after, NOT ::before, and that is not a style choice. The red i in the
   gutter is a ::before on every printing line, and `.sf-teach .sf-ln::before`
   outranks `.sf-pb::before`, so in teach mode, which is the default, the badge
   took the slot and the gap between two pages was never painted at all. Two
   different things wanted the same one pseudo-element; they have one each. */
.sf-pb::after{
  content:attr(data-page);
  position:absolute;
  left:0;
  right:0;
  /* sits directly above the head of the page below, so the head stays paper */
  top:calc((6 + var(--sf-gutter, 3)) * -1em);
  height:calc(var(--sf-gutter, 3) * 1em);
  background:var(--bg);
  color:var(--sf-force);
  font-size:12pt;
  line-height:calc(var(--sf-gutter, 3) * 1em);
  text-align:right;
  padding-right:var(--sf-right);
  pointer-events:none;
}

/* ---------- the Pages panel ----------
   Thumbnails of the real page, shrunk, in the house left tab. The column
   scrolls; a click is an action, not a style. The geometry comes from the
   mirror block at the top, which this panel shares with the page. */
.sf-pages{
  overflow:auto;
  padding:var(--s1) var(--s4);
  display:flex;
  flex-direction:column;
  gap:var(--s6);
}
.sf-pg{
  cursor:pointer;
  text-align:center;
  color:var(--muted);
  font-size:var(--t-label);
  font-family:inherit;
  border:0;
  background:none;
  padding:0;
}
/* A THUMBNAIL IS THE PAGE, SHRUNK, AND IT GROWS WITH THE PANEL (Mark,
   2026-08-20: "it would be useful to have the thumbs scale up so if user
   slide panel they can read it"). It was 124px of fixed 2.4px Courier, which
   is a shape and never a readable page however wide the panel was pulled.

   THE ARITHMETIC, so nobody has to guess at the numbers again. Courier 12pt
   is ten characters to the inch and six lines to the inch, and a page is
   8.5 by 11. So a page is 85 characters across and 66 lines down, and a
   character cell is 0.6em wide. To fit 85 of them in the paper's own width:

     font-size = width / (85 * 0.6) = width / 51

   and one line is one inch over six, which at ten characters an inch is
   exactly one em. Hence line-height 1, and the 66 lines then come out at
   11/8.5 of the width on their own. The one inch top margin is width/8.5.

   The paper is its own container so `cqw` means "this thumbnail's width",
   which is what makes every one of these numbers hold at any panel width. */
.sf-paper{
  container-type:inline-size;
  width:100%;
  /* never bigger than the real thing: 8.5 inches at 96dpi */
  max-width:816px;
  aspect-ratio:8.5 / 11;
  background:var(--sf-paper);
  color:var(--sf-pencil);
  border-radius:2px;
  border:1px solid transparent;
  overflow:hidden;
  text-align:left;
  margin:0 auto;
}
.sf-paper pre{
  font-family:var(--sf-mono);
  font-size:calc(100cqw / 51);
  line-height:1;
  color:var(--sf-pencil);
  margin:0;
  white-space:pre-wrap;
  padding:calc(100cqw / 8.5) var(--sf-right) 0 var(--sf-left);
  overflow:hidden;
  text-align:left;
}
.sf-pg:hover .sf-paper{ border-color:var(--accent); }
.sf-pg-n{ margin-top:var(--s2); }

/* ---------- the Tool Box ---------- */
.sf-toolbox > .house-tabs{ margin-bottom:var(--s2); }
.sf-card-list{
  display:flex;
  flex-direction:column;
  gap:var(--s4);
}
.sf-card,
.sf-cast-card{
  background:var(--panel);
  border:var(--bd) solid var(--edge);
  border-radius:var(--r-md);
  padding:var(--s4) var(--s5);
}
.sf-card-head{
  width:100%;
  display:flex;
  align-items:flex-start;
  justify-content:space-between;
  gap:var(--s4);
  border:0;
  padding:0;
  background:none;
  color:inherit;
  font-family:var(--sf-mono);
  font-size:var(--t-tiny);
  text-align:left;
  cursor:pointer;
}
.sf-card-head:hover{ color:var(--accent); }
.sf-card-sum{
  margin-top:var(--s2);
  color:var(--muted);
  font-size:var(--t-tiny);
  line-height:1.45;
}
.sf-count-line,
.sf-empty{
  color:var(--muted);
  font-size:var(--t-small);
  line-height:1.45;
}
.sf-seq{
  margin-top:var(--s5);
  color:var(--muted);
  font-size:var(--t-label);
  letter-spacing:var(--ls-label);
  text-transform:uppercase;
}
/* THE PANEL OPENS AT 200px AND THAT IS THE WIDTH THAT HAS TO WORK. These
   cards were two to a row with the face a big square above the name, which
   reads well in a mockup and gave each card about eighty five pixels of text
   column: every word of "dark hair, dirt to the elbows" wrapped onto its own
   line, the two rows sized to different heights, and the panel's whole job,
   telling you who is in your script, could not be done by looking at it.

   One card to a row, the face small and beside the name rather than over it.
   Same fix Ann's panel needed, same cause. */
.sf-cast-list{
  display:flex;
  flex-direction:column;
  gap:var(--s3);
}
.sf-cast-card{
  min-width:0;
  font:inherit;
  text-align:left;
  display:grid;
  grid-template-columns:32px minmax(0,1fr);
  grid-template-rows:auto auto auto;
  column-gap:var(--s4);
  row-gap:var(--s1);
  align-items:start;
}
.sf-face{
  grid-row:1 / span 3;
  width:32px;
  height:32px;
  display:grid;
  place-items:center;
  border-radius:var(--r-sm);
  background:var(--setA);
  color:var(--muted);
  font-size:var(--t-label);
  text-align:center;
  overflow:hidden;
}
.sf-cast-card b{
  font-size:var(--t-small);
  overflow-wrap:anywhere;
}
.sf-cast-card small,
.sf-cast-st{
  font-family:var(--sf-mono);
  font-size:var(--t-label);
  line-height:1.4;
  overflow-wrap:anywhere;
}
.sf-cast-card small{ color:var(--muted); }
.sf-cast-st{ color:var(--accent); }

/* ---------- the caret island ----------
   What only appears once a writer is in the page: the line under the caret,
   and the one name the page is willing to finish for you. */
.sf-cur{ background:color-mix(in srgb, var(--accent) 10%, transparent); }
.sf-ln[data-suggest]::after{ content:attr(data-suggest); color:var(--sf-force); }

/* ---------- the teaching colours ----------
   Every element tagged in its own colour down the left edge of the line, so a
   page can be read as six kinds of paragraph before it is read as writing. A
   lesson turns this on; it is off for everyone else. The colours are on the
   bare root beside the paper, for the reason named there. */
.sf-scene{ --sf-lc:var(--sf-c-scene); }
.sf-action{ --sf-lc:var(--sf-c-action); }
.sf-character{ --sf-lc:var(--sf-c-character); }
.sf-dialogue{ --sf-lc:var(--sf-c-dialogue); }
.sf-paren{ --sf-lc:var(--sf-c-paren); }
.sf-transition{ --sf-lc:var(--sf-c-transition); }
.sf-center{ --sf-lc:var(--sf-c-center); }
.sf-title,.sf-section,.sf-synopsis{ --sf-lc:var(--sf-c-quiet); }
.sf-colors .sf-ln:not(.sf-blank){ box-shadow:inset 3px 0 0 var(--sf-lc, transparent); }

/* The line Ann is pointing at, lit in that element's own colour. She teaches
   by showing you a line on your page, never by typing on it. */
.sf-lit{
  background:color-mix(in srgb, var(--sf-lc, var(--accent)) 22%, transparent);
  box-shadow:inset 3px 0 0 var(--sf-lc, var(--accent));
  transition:background .25s;
}

/* ---------- the gutter marker ----------
   In teach mode every line that prints carries a small red i out in the left
   margin, and clicking it asks Ann what that element is. It rests invisible
   and comes up on hover, so a page being written is never speckled with
   badges; it is there the moment a writer wonders about a line.

   THE HIT BAND IS A MIRROR. This badge is a pseudo-element, so there is no
   node to click: the island hit-tests the click by arithmetic instead, over
   the band from 1ch to 14ch off the line's own left edge. `left` below must
   stay inside that band, and lib/script-editor.js says the same thing where
   it measures. */
.sf-teach .sf-ln:not(.sf-blank)::before{
  content:"i";
  position:absolute;
  left:2ch;
  top:1px;
  z-index:1;
  height:14px;
  line-height:14px;
  padding:0 5px;
  border-radius:var(--r-pill);
  font-family:var(--font-ui);
  font-size:var(--t-label);
  font-style:italic;
  white-space:nowrap;
  color:var(--sf-ask-ink);
  background:var(--sf-ask);
  opacity:0;
  cursor:pointer;
  transition:opacity .12s;
}
.sf-teach .sf-ln:not(.sf-blank):hover::before{ content:"i  what is this?"; font-style:normal; opacity:1; }
.sf-teach .sf-ln:not(.sf-blank):hover{ background:color-mix(in srgb, var(--sf-ask) 6%, transparent); }

/* ---------- what never prints ----------
   A note and the boneyard stay in the file, are shown to the writer, and
   never reach the page (fountain.io/syntax). They are drawn in the same gray
   as the force marks, because they are the same kind of thing: plumbing the
   writer can see and the reader never will.

   The boneyard is struck through as well. A note is something you are keeping;
   the boneyard is something you have cut, and the page should not make the two
   look alike. */
.sf-note{ font-style:italic; }
.sf-dead{ opacity:.72; }
.sf-dead .sf-boned{ text-decoration:line-through; text-decoration-thickness:1px; }

/* ---------- show me every line my character speaks ----------
   Six highlighters, on the page and on the chip that turned it on, so the
   colour is the only thing you have to remember. The page's highlight sits
   BEHIND the writing rather than over it: a screenplay is black on cream and
   a highlighter that changed the ink would be a different page. */
.sf-hl-1{ --sf-hl:var(--sf-hl-1); }
.sf-hl-2{ --sf-hl:var(--sf-hl-2); }
.sf-hl-3{ --sf-hl:var(--sf-hl-3); }
.sf-hl-4{ --sf-hl:var(--sf-hl-4); }
.sf-hl-5{ --sf-hl:var(--sf-hl-5); }
.sf-hl-6{ --sf-hl:var(--sf-hl-6); }
.sf-ln.sf-hl{ background:var(--sf-hl); }

.sf-hl-row{ margin-bottom:var(--s4); }
.sf-hl-label{
  color:var(--muted);
  font-size:var(--t-label);
  letter-spacing:var(--ls-label);
  text-transform:uppercase;
  margin-bottom:var(--s2);
}
.sf-hl-chips{ display:flex; flex-wrap:wrap; gap:var(--s2); }
.sf-hl-chip{
  padding:var(--s1) var(--s3);
  border:var(--bd) solid var(--edge);
  border-radius:var(--r-pill);
  background:var(--panel);
  color:var(--muted);
  font:inherit;
  font-size:var(--t-label);
  line-height:1.5;
  cursor:pointer;
  white-space:nowrap;
}
.sf-hl-chip:hover{ color:var(--text); border-color:var(--ink4); }
/* a chip that is on wears its own highlighter, and the ink on it is the
   page's ink, because that is the pairing the writer will see on the page */
.sf-hl-chip-on{ background:var(--sf-hl); border-color:var(--sf-hl); color:var(--sf-pencil); }
.sf-hl-off{ font-style:italic; }

/* the size control, beside the count above the page */
.sf-zoom{ display:flex; align-items:center; gap:var(--s1); }
.sf-zoom button{
  border:var(--bd) solid var(--edge);
  background:none;
  color:var(--muted);
  font:inherit;
  font-size:var(--t-label);
  line-height:1;
  padding:var(--s1) var(--s3);
  border-radius:var(--r-sm);
  cursor:pointer;
}
.sf-zoom button:hover{ color:var(--text); border-color:var(--ink4); }
.sf-zoom-n{ min-width:5ch; }

/* the four faces a page may wear. Pills in Ann's gear; stacks on the sheet. */
.sf-face-picks{ display:flex; flex-wrap:wrap; gap:var(--s2); }
.sf-face-pick{
  padding:var(--s1) var(--s3);
  border:var(--bd) solid var(--edge);
  border-radius:var(--r-pill);
  background:var(--panel);
  color:var(--muted);
  font:inherit;
  font-size:var(--t-label);
  line-height:1.5;
  cursor:pointer;
  white-space:nowrap;
}
.sf-face-pick-on{ background:var(--accent); border-color:var(--accent); color:var(--onAccent); }
.sf-face-why{ color:var(--muted); font-size:var(--t-label); }
.sf-sheet[data-face=prime]{ --sf-mono:"Courier Prime","Courier New",Courier,monospace; }
.sf-sheet[data-face=sans]{ --sf-mono:"Courier Prime Sans","Courier Prime","Courier New",Courier,monospace; }
.sf-sheet[data-face=new]{ --sf-mono:"Courier New",Courier,monospace; }
.sf-sheet[data-face=system]{ --sf-mono:Courier,"Courier New",monospace; }

/* ---------- the bar over a picked passage ----------
   Select a passage and this floats over it offering to read it in the cast's
   own voices. Fixed to the viewport because the numbers it is given are the
   selection's own screen box, and drawn OUTSIDE the page for the reason the
   gutter marker is a pseudo-element: a node inside a contenteditable is a
   node a writer can put a caret in and break. */
.sf-pick{
  position:fixed;
  top:var(--sf-pick-t);
  left:var(--sf-pick-l);
  transform:translate(-50%, calc(-100% - 10px));
  z-index:40;
  display:flex;
  align-items:center;
  gap:var(--s3);
  padding:var(--s2) var(--s3);
  border:var(--bd) solid var(--edge);
  border-radius:var(--r-pill);
  background:var(--chrome);
  box-shadow:0 var(--s3) var(--s7) var(--shad);
  backdrop-filter:blur(6px);
}
.sf-pick-b{
  border:0;
  background:none;
  color:var(--accent);
  font:inherit;
  font-size:var(--t-label);
  line-height:1.4;
  padding:0 var(--s2);
  cursor:pointer;
  white-space:nowrap;
}
.sf-pick-b:hover{ color:var(--text); }
.sf-pick-who{
  color:var(--muted);
  font-size:var(--t-label);
  white-space:nowrap;
}
.sf-pick-reading .sf-pick-b{ color:var(--sf-ask); }
