/* public/css/easel-fpc.css — FPC's override sheet for the ported LDM easel
 * 2026-09-20 · 2026-09-21 (guide relabelled, Zazzle pattern) · 2026-09-20 rev 6b (§3b extent chips hidden) · rev 6c (§6 left panel) · #79 (§10 geometry override retired — the bundle draws 5.333 px natively; §10b pill moved to the corner; §12 text metrics = print metrics) · rev 13 (§13d Design Boxes strip + the band ghost) · rev 15 (§3d tour hidden; bundle on the true source) · rev 16 (§14 the Template Maker) · rev 17 (§14b Place the art) · rev 18 (§14c the photo window) · rev 19 (§14d the five sections) · rev 20 (§14e the Name & dates block, the backing looks, the see-through panel)
 * · rev 23 (§14e the window photo: no grips, solid outline, 9/24)
 * · rev 29 (the simple view: the Upload button's spinner while a photo goes in; the front card's outline under a dragged picture, 9/26)
 * · rev 41 (§15i.7 the classic back — the back-only view: html.fpc-back-only, 9/30)
 * · rev 42 (§15i.7: no printed-edge line on a catalog 8-Up front, 9/30)
 * · rev 43 (§15i.8: the classic back's sample photo cue, the back as the drop target, the back's photo a pointer, 9/30)
 * · rev 51 (§14c: the Template Maker's guide at Lamcraft's 0.14" safe zone, #211, 10/1)
 * · rev 50 (§15i.9: the back's Verse · Formal row on the classic back too; the photo's control under the words on a Verse back;
 *   the back card as the drop target when its photo is on, 10/1)
 * loaded AFTER easel.bundle.css on views/easel.html
 *
 * WHY THIS FILE EXISTS
 * The 12 files in ldm-feelgate resources/js/editor2 carry ZERO FPC edits and
 * must stay that way — that is Mirror-Don't-Fork, and it is what lets the ldm
 * source stay the single origin. Every difference between LDM's easel and
 * FPC's easel lives here, in a sheet LDM never loads. Nothing below requires
 * rebuilding easel.bundle.js.
 *
 * If a rule here stops working, the cause is a class rename in the ldm source.
 * Fix it here; never patch the bundle.
 *
 * THE NUMBERS ARE NOT PREFERENCES. They are read off FPC's own renderers, and
 * they are what makes easel == proof == print hold:
 *
 *   generate-fpc.js:60   CORNER_R                  = 4 pt  (die-cut round)
 *   generate-8up.js:820  FRONT_PHOTO_FULL_BORDER   = 4 pt  ("tiny safety
 *                                                   margin for die drift")
 *
 *   PDFKit runs at 72 pt/in. The easel runs at 96 px/in (state.js PAGE_DPI).
 *   4 pt x 96/72 = 5.333 px.  Both numbers below are that one number.
 *
 *   Both appear as the literal 5.333px below — no custom properties, so
 *   nothing to resolve at runtime and nothing to go stale silently.
 *
 *   Do not tune these in isolation. If the die radius or the drift margin
 *   changes, it changes in generate-fpc.js / generate-8up.js FIRST and this
 *   file follows, or the easel starts lying about what prints.
 * ------------------------------------------------------------------------ */

/* ---- 1,2 · Print and Menu are dead routes in FPC -------------------------
 * doPrint()  -> window.open('/editor/print/' + documentId)  (EditorShell:2117)
 * goBack()   -> window.location.href = '/editor2/start'     (EditorShell:2172)
 * Neither path exists in this repo. These were live 404s / walk-offs, not
 * merely unwanted chrome. */
.ed2-ctl.ed2-print,
.ed2-ctl.ed2-back { display: none !important; }

/* ---- 3 · Save and its status --------------------------------------------
 * Persistence follows the incumbent: wizard.js S22.106.2 keeps an IndexedDB
 * draft (debounced, flushed on pagehide, 7-day resurrect). There is no Save
 * button in the wizard either, so there is none here. The shell's Save is
 * still the EXIT: easel-mount.js rev 6 clicks it from "Continue to proof"
 * and intercepts the PUT it makes. */
.ed2-ctl.ed2-save,
.ed2-savestate,
.ed2-savemsg { display: none !important; }

/* ---- 3a · Continue to proof (2026-09-20, item 6) -------------------------
 * The one way off the easel. Lamcraft orange so it reads as the primary
 * action next to the grey shell controls. */
.ed2-ctl.fpc-continue {
  background: #F47920 !important;
  color: #fff !important;
  border-color: #F47920 !important;
  font-weight: 700 !important;
  margin-left: 10px !important;
}
.ed2-ctl.fpc-continue:hover { background: #d9660f !important; border-color: #d9660f !important; }

/* ---- 3c · The ripcord (rev 12, 2026-09-21) --------------------------------
 * "Guided steps instead", beside Continue — the way off the easel that is
 * not the proof. Quiet on purpose: a ghost button, so Continue stays the
 * one orange thing in the row. */
.ed2-ctl.fpc-ripcord {
  background: transparent !important;
  color: #ccc !important;
  border-color: #555 !important;
  font-weight: 400 !important;
  margin-left: 8px !important;
}
.ed2-ctl.fpc-ripcord:hover { color: #fff !important; border-color: #F47920 !important; }

/* ---- 3b · The Full size photo's extent chips (2026-09-20, rev 6b) -------
 * LDM's chip row offers "Inside margins" (the photo completes inside LDM's
 * 0.25 in SAFE_INSET — its tooltip says "safe on every printer") and "Edge to
 * edge" ("for printers that can print borderless"). Both are reasons that
 * belong to a card printed at home. Lamcraft prints the whole card, to the
 * edge, on its own press (owner ruling 13, 9/20) — so every Full size photo
 * lands edge to edge (rev 6b did it with a mount-script hook; since #79 the
 * bundle itself is compiled with extent 'edge' as the new-photo default) and
 * these two chips have nothing true to say.
 * Hidden by their title text, the same way the copy guard matches: if the ldm
 * source rewords them they reappear rather than break. Soft/Hard,
 * Rectangle/Oval, Backing and Words stay. */
.ed2-pf .ed2-pfchip[title^="The photo completes inside the print margins"],
.ed2-pf .ed2-pfchip[title^="The photo runs to the paper edge"] { display: none !important; }

/* The overlay while the two rasters are made. Above .ed2-root (position:fixed). */
.fpc-proof-overlay {
  position: fixed; inset: 0; z-index: 2147483000;
  background: rgba(20, 20, 20, .72);
  display: flex; align-items: center; justify-content: center;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}
.fpc-proof-box {
  background: #fff; color: #222; border-radius: 8px; padding: 26px 30px;
  max-width: 420px; width: calc(100% - 40px); text-align: center;
  box-shadow: 0 10px 40px rgba(0,0,0,.4); border-top: 4px solid #F47920;
}
.fpc-proof-box.err { border-top-color: #c62828; }
.fpc-proof-title { font-size: 18px; font-weight: 700; margin-bottom: 8px; }
.fpc-proof-msg { font-size: 14px; color: #555; line-height: 1.45; }
.fpc-proof-close {
  margin-top: 16px; background: #F47920; color: #fff; border: 0; border-radius: 4px;
  padding: 9px 18px; font-size: 14px; font-weight: 600; cursor: pointer;
}

/* ---- 3d · The LDM tour (p104) — hidden on FPC (rev 15, 2026-09-21) --------
 * fpc-port-5 is the first bundle built on the TRUE ldm source, which carries
 * p104: a "Tour" button on the toolbar and the Ed2Tour overlay. Its steps name
 * LDM chrome this sheet hides or relabels (Print / Menu / Save, "Text & Verses",
 * the office-printer line), so on FPC it would point at things that are not
 * there (law 11). Hidden until FPC has its own steps list — owner call #109. */
.ed2-tourctl { display: none !important; }

/* ---- 4 · Folders --------------------------------------------------------
 * FPC has no accounts and no owner scope, so there is nothing to file into.
 * Closes decision #74. */
.ed2-folder-label,
.ed2-sel-folder { display: none !important; }

/* ---- 10 · The guide line ------------------------------------------------
 * 2026-09-20 (#79, the bundle rebuild): NO GEOMETRY OVERRIDE ANY MORE.
 *
 * Until #79 this section forced .ed2-safezone to left/top 5.333px and
 * width/height calc(100% - 10.666px) with !important, over the inline
 * left/top/width/height that PageView.vue safeStyle() writes from state.js
 * SAFE_INSET (LDM: 0.25 in = 24 px, the office-printer margin). The bundle is
 * now compiled (repo lamcraft-easel-build) with SAFE_INSET_IN = 4/72 in — the
 * 4 pt drift margin generate-fpc.js / generate-8up.js already honour — so the
 * shell draws the line at 5.333 px itself, and every default box, the grip
 * snap line and the crossing math follow the same constant. Nothing to
 * override; the real element keeps its halo and its zoom-correct hairline.
 *
 * CORNER RADIUS: the element has none in the bundle CSS and needs none. A
 * rounded rectangle inset by t has inner radius max(0, R - t); R = t = 4 pt,
 * so the inner radius is exactly zero — square, and that is arithmetic.
 *
 * If the guide ever paints at 24 px again, the OLD bundle is being served
 * (cache) — easel-mount.js logs LamcraftEasel.version and warns when the
 * bundle's SAFE_INSET is not 5.333 px. Do not put the override back; fix the
 * bundle.
 *
 * Still hidden: the red crossing bands. The flagging math now runs against
 * the same 5.333 px the line is drawn at, but the bands are LDM chrome for a
 * home-printer warning ("outside it most printers can't print"). On this
 * product a backdrop or a Full size photo running to the edge is CORRECT and
 * must not paint red; names, dates and verses inside the line is the guide's
 * whole message, said by the pill below. Same reason the inherited-copy guard
 * in easel-mount.js still suppresses the "About the Red Edge" dialog (#84,
 * closed as a copy rule, not a patch). */

/* The red crossing bands (p54/p92). One rule covers l/t/r/b — they all drive
 * the same ::after. */
.ed2-item.ed2-unsafe::after { display: none !important; }

/* ---- 10b · The label and its explanation (owner 9/21, Zazzle pattern) ----
 * Owner's reference: Zazzle's customizer puts a permanent pill ON the safe
 * line and pops a plain-English message when you hover the boundary.
 *
 * ONE DELIBERATE DIFFERENCE FROM ZAZZLE. Zazzle draws TWO lines and explains
 * each — an outer one ("we will attempt to print the entire area inside this
 * line") and an inner dashed one ("keep your important content inside this
 * dotted line"). Zazzle has two because Zazzle has BLEED: the outer line is
 * the cut and the customer's art runs past it.
 *
 * The FPC easel is TRIM size with no bleed, by the Cardinal Rule — the page
 * edge IS the cut. So there is one line to label, not two, and both facts go
 * in the one message: what the line is for, and that art should still run to
 * the edge. Inventing a second line here would put a boundary on screen that
 * does not exist in generate-fpc.js.
 *
 * WHY THE PILL IS THE HOVER TARGET AND THE LINE IS NOT.
 * Everything FPC adds over the card is pointer-events:none, on purpose.
 * ed2 selects by coordinate (hitTest -> hitTargetAt(clientX, clientY),
 * EditorShell:1632) so an overlay would not break SELECTION — but interact.js
 * binds per element node (interact-setup.js:168) and contextTargetAt falls
 * back to e.target.closest('.ed2-item'), so a pointer-active band along the
 * card edge could block a drag or a right-click started on a photo pushed out
 * there. That is the exact edge of the card where photo placement already
 * hurts (open #61). Not worth it for a tooltip.
 *
 * So the ONLY pointer-active pixels this sheet adds are the pill itself
 * (~56 x 14px). Hovering a pseudo-element puts :hover on its originating
 * element, which is what lets the pill reveal its sibling ::after.
 *
 * 2026-09-20 (#79) — MOVED from top-centre to the BOTTOM-RIGHT CORNER, hanging
 * up from the line. Until #79 every box was born 24 px in, so a pill hanging
 * 14 px down from the 5.333 px line sat in empty card. Now the default boxes
 * start AT the line, and the top-centre pill sat squarely on the first line
 * of every verse and every back text box (seen in the headless pass: "To
 * every [Safe area] a season"). The card clips at its edge (.ed2-page
 * overflow:hidden), so the pill cannot hang outside; a corner is the least
 * loaded spot on a centred layout, and the bottom keeps it off the first
 * line a customer types. It is also hidden while a box on that card is being
 * typed in (:has(.editing)), so it never sits on the caret line. Owner
 * alternative on record: show it only while the card is hovered. */
.ed2-page:has(.ed2-item.editing) .ed2-safezone::before { display: none; }
.ed2-safezone::before {
  content: 'Safe area';
  position: absolute;
  bottom: 0;
  right: 0;
  padding: 2px 7px;
  border-radius: 8px 0 0 0;
  background: #e8f4ea;
  color: #1f6b33;
  font: 600 9px/1.2 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  letter-spacing: .2px;
  white-space: nowrap;
  pointer-events: auto;
  cursor: help;
  z-index: 200001;
}

/* The message. Hidden until the pill is hovered.
 *
 * It renders INSIDE the card because .ed2-page carries overflow:hidden —
 * anything positioned above the top edge is clipped away, so a tooltip that
 * floats above the card would simply never be seen. Sitting under the pill is
 * not a style choice; it is the only place it can be. */
.ed2-safezone::after {
  content: 'Keep names, dates and verses inside this line.\A The cut can drift about 1/18 inch.\A\A Backgrounds and photos should run past it, all the way to the card edge — the whole card prints.';
  position: absolute;
  bottom: 20px;          /* above the pill (#79: the pill sits on the bottom line now) */
  left: 50%;
  transform: translateX(-50%);
  width: 86%;
  padding: 7px 9px;
  border-radius: 5px;
  background: rgba(28, 28, 28, 0.93);
  color: #fff;
  font: 400 9px/1.45 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  white-space: pre-line;
  text-align: left;
  box-shadow: 0 3px 12px rgba(0, 0, 0, 0.35);
  pointer-events: none;
  opacity: 0;
  visibility: hidden;
  transition: opacity .12s ease;
  z-index: 200001;
}

.ed2-safezone:hover::after {
  opacity: 1;
  visibility: visible;
}

/* Surface-specific wording. The base rule above names no cutting method, so a
 * surface that is added later without a rule here still reads true. These two
 * name it, because "die-cut" and "perforated" are different promises and the
 * customer is entitled to the right one.
 *
 * Both drift margins are the same 4 pt: generate-fpc.js:60 CORNER_R for the
 * laminated card, generate-8up.js:820 FRONT_PHOTO_FULL_BORDER for the 8-Up.
 * One number, two reasons.
 *
 * 2026-09-20 — the hard break that used to sit after "all the way" is gone
 * from all three messages. The box is 86% of a 240px card (~206px), so the
 * sentence already wraps on its own; the extra \A landed "the way" alone on a
 * line. Seen in the headless browser pass. Sentence breaks stay; mid-sentence
 * breaks do not. */
#easelMount[data-surface="lam"] .ed2-safezone::after {
  content: 'Keep names, dates and verses inside this line.\A The card is die-cut and the cut can drift about 1/18 inch.\A\A Backgrounds and photos should run past it, all the way to the card edge — the whole card prints.';
}

/* rev 35 (2026-09-28, the owner's disclosure ruling): an 8-Up is NOT printed edge to edge. lib/generate-8up.js crops
 * every easel face to a 4 pt white edge (EASEL_EDGE) — exactly this line — so the eight perforated cards come apart
 * with a thin white border between them. The old wording ("the whole card prints") was the laminated card's truth,
 * not this one's. */
#easelMount[data-surface="8up"] .ed2-safezone::after {
  content: 'Keep names, dates and verses inside this line.\A The strip outside it prints white: a thin white edge separates the eight cards on the perforated sheet, and the tear can drift about 1/18 inch.\A\A Backgrounds and photos should still run past the line, so the color reaches the white edge with no gap.';
}

/* ---- 12 · Text metrics = print metrics (2026-09-20, found with the verse fit) -
 * lib/ed2-front-render.js PRINT_CSS renders every proof with
 *   *{-webkit-font-smoothing:antialiased;text-rendering:geometricPrecision}
 * — unhinted, geometrically exact glyph advances, right for print. The easel
 * painted text with the browser default (hinted advances). The two differ by
 * a few percent per glyph, which is invisible on a name or a date and FATAL
 * on a paragraph: the same Footprints verse wrapped on different words on the
 * easel and on the proof, ran 442 px tall on the proof against a 397 px box
 * that the easel had shown as full-but-fitting, and the proof cut the last
 * lines off. Measured 9/20 (pass D): 53.7 % of the card's pixels differed
 * between the easel's paint and the server render of the SAME document;
 * with this rule the two lay out line for line.
 *
 * The Cardinal Rule says the easel shows what prints, so the easel adopts
 * the print metrics — not the other way round (print stays geometric). Same
 * rule as the print sheet, scoped to the words. The measured verse fit
 * (config/easel-verse-fit.json) is taken WITH this rule in force; without it
 * the fit is a screen fit, not a print fit.
 *
 * SECOND HALF, the strut (measured 9/20 after the wraps matched): every line
 * was still 1 px taller on the easel than on the proof (17 vs 16 px at a
 * 10.1 px verse) — 24 px over a full card, the body of #88. A line box is
 * never shorter than the PARAGRAPH's own font's normal height (the strut),
 * and the paragraph's font is inherited: on the easel from .ed2-root
 * (Arial, sans-serif — LDM's chrome font), on the render page from the
 * browser default (a Times-metric serif: Times New Roman on Windows,
 * Liberation Serif in the render service's Linux container). Proved by
 * forcing the easel's paragraph font to Times New Roman: 368 px tall, the
 * proof's exact height, against 391 with Arial. So the easel's paragraphs
 * take the proof's strut. Chantelli and every other card font come from
 * /editor-files (the same files both sides), so the words themselves were
 * never the difference. OPEN, #88: the renderer should pin this family in
 * PRINT_CSS (.ed2-page{font-family}) at its next re-vendor so neither side
 * rests on a browser default; until then this line follows what it does.
 *
 * REV 28c (owner's iPhone, 9/26): 'Times New Roman' is itself a browser
 * default. Safari on the iPhone set every verse line 18 px tall where the
 * proof sets 16 (measured on his screenshot: a 10.1 px Footprints, 22 wraps),
 * so the last line ran past the box. The strut is now ZDTimes — fonts.css's
 * Tinos, the metric twin of the render service's Liberation Serif (ascent
 * 1825, descent 443, gap 87 per 2048, the same numbers) — a web font, so
 * every engine sets the same 16 px. Chromium measures exactly as before
 * (the fit table's control run reproduces it row for row). The mount asks
 * for the face at start (chFillPreload); the verse-fit guard (easel-mount
 * vfCheck) catches whatever an engine still sets taller. */
.ed2-textDiv, .ed2-textDiv * {
  text-rendering: geometricPrecision;
  -webkit-font-smoothing: antialiased;
}
.ed2-textDiv { font-family: 'ZDTimes', 'Times New Roman', Times, serif; }

/* ---- 11 · Die-cut corners ----------------------------------------------
 * generate-fpc.js:1105 clips the proof with roundedRect(0,0,CARD_W,CARD_H,r)
 * over a grey mat. The wizard live preview passes no radius and renders
 * SQUARE — so the incumbent preview and the incumbent proof already disagree.
 * The easel matching the proof is the more correct of the two.
 *
 * .ed2-page already carries overflow:hidden, so the radius clips content for
 * free. p56b (.ed2-editing-page) and p86 (.ed2-photo-open) deliberately switch
 * to overflow:visible + clip-path while a box is being typed in or a photo is
 * selected; the radius goes inert there, which is correct — you want to see
 * the overflow you are dragging.
 *
 * LAMINATED ONLY, AND NOW ENFORCED (2026-09-21, owner UX item 12 / open #83).
 * The 8-Up is PERF-CUT, not die-cut: its card corners are SQUARE. The renderer
 * rounds the PHOTO placed on it (generate-8up.js:821 FRONT_CORNER_R = 4) and
 * never the card itself, so an 8-Up page carrying a die round would be the
 * easel claiming a cut that does not happen.
 *
 * public/js/easel-mount.js writes data-surface onto #easelMount before the
 * easel mounts, so this is correct on the first painted frame. An unknown or
 * missing surface falls back to 'lam' there, which means a mount failure can
 * never silently drop the radius on the laminated card. */
#easelMount[data-surface="lam"] .ed2-page { border-radius: 5.333px; }   /* CORNER_R 4pt @ 96px/in */

/* ---- 6 · Left panel (2026-09-20, owner) ---------------------------------
 * LDM's column is "Text & Verses" because LDM serves obit TEXT BOXES in the
 * same list (the Obit/Text Box group). FPC serves verses only (lib/verses.js
 * through lib/easel-verses.js, 132 rows) — there are no text boxes in this
 * list, so the title and the sentence said something that is not on screen.
 * Same font-size:0 + pseudo-element swap as §7. The collapsed rail keeps its
 * live count: the count is the label's own child span, restored to size, and
 * the words go in ::before so they read in order. */
.ed2-left-title { font-size: 0 !important; }
.ed2-left-title::after { content: 'Verses'; font-size: 13px; font-weight: bold; letter-spacing: 0.2px; }
.ed2-left-sub { font-size: 0 !important; }
.ed2-left-sub::after { content: 'The words that go on the back (or the front). Click one, then choose the card.'; font-size: 11px; line-height: 1.35; }
.ed2-rail-label { font-size: 0 !important; }
.ed2-rail-label::before { content: '\FF0B Verses'; font-size: 12px; font-weight: bold; letter-spacing: 0.5px; }
.ed2-rail-label > span { font-size: 12px; font-weight: bold; letter-spacing: 0.5px; }

/* ---- 7 · Right panel ----------------------------------------------------
 * Text swaps only. font-size:0 collapses the original text nodes (and the
 * inline <a>/<span> that inherit it); ::after restates it at real size. */
.ed2-side-title { font-size: 0 !important; }
.ed2-side-title::after {
  content: 'Images';
  font-size: 13px;
  font-weight: 600;
}

.ed2-side-sub { font-size: 0 !important; }
.ed2-side-sub::after {
  content: 'Upload image(s) for your prayer card.';
  font-size: 12px;
}

/* LDM's empty state (EditorShell:592, .ed2-side-empty) repeats the drop-zone
 * sentence word for word directly under the drop zone — by design there
 * (p54 #20: "sentence 2 is the drop zone AND the empty state"). It was never
 * visible on FPC until 9/20 because photosErr ("Upload failed (HTTP 404).")
 * took its slot; with the library route live, the sentence showed twice.
 * The drop zone says it once. */
.ed2-side-empty { display: none !important; }

/* ---- 7 · Footer ---------------------------------------------------------
 * LDM's support line points at lamcraftdigitalmemories.com and a phone number
 * that belongs to that business. */
.ed2-foot-help { font-size: 0 !important; }
.ed2-foot-help::after {
  content: 'Serving funeral homes since 1974';
  font-size: 12px;
}

/* ---- 13 · Design Templates (rev 9, 2026-09-20; moved right in rev 11) -----
 * The "Design Templates" block easel-mount.js installs at the top of the
 * Images column (.ed2-side) since rev 11 — rev 9/10 had it at the top of the
 * Verses column (.ed2-left): the same furniture as the column's own head
 * (EditorShell.vue .ed2-left-head / -title / -sub, restyled here under our
 * own class names because §11 above blanks .ed2-left-title / .ed2-left-sub
 * with font-size:0 to relabel them). Category pills, a two-column grid of
 * rendered sample thumbnails, a collapse toggle. The column is 240 px wide
 * and scrolls; the Verses head below stays sticky, ours does not. */
.fpc-tpl { margin: 0 -8px 10px; padding: 0 8px 8px; border-bottom: 3px solid #F47920; }
.fpc-tpl .fpc-tpl-head { position: static; margin: 0 -8px 6px; padding: 8px 8px 6px; }
.fpc-tpl-title { color: #fff; font-weight: bold; font-size: 13px; letter-spacing: 0.2px; }
.fpc-tpl-sub { color: #aaa; line-height: 1.35; font-size: 11px; margin-bottom: 8px; }
.fpc-tpl.collapsed { padding-bottom: 0; }
.fpc-tpl-cats { display: flex; flex-wrap: wrap; gap: 4px; margin-bottom: 8px; }
.fpc-tpl-cat {
  background: #333; color: #ddd; border: 1px solid #4a4a4a; border-radius: 12px;
  padding: 2px 9px; font-size: 11px; line-height: 1.5; cursor: pointer;
}
.fpc-tpl-cat:hover { background: #3d3d3d; color: #fff; }
.fpc-tpl-cat.active { background: #F47920; border-color: #F47920; color: #fff; font-weight: 600; }
.fpc-tpl-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.fpc-tpl-tile {
  display: block; width: 100%; padding: 0; margin: 0; background: #1c1c1c; color: #ddd;
  border: 2px solid transparent; border-radius: 4px; cursor: pointer; text-align: center;
  overflow: hidden; font: inherit;
}
.fpc-tpl-tile img { display: block; width: 100%; height: auto; aspect-ratio: 240 / 408; object-fit: cover; }
.fpc-tpl-tile .fpc-tpl-name { display: block; padding: 4px 4px 5px; font-size: 11px; line-height: 1.25; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fpc-tpl-tile:hover { border-color: #F47920; color: #fff; transform: translateY(-1px); }
.fpc-tpl-tile.current { border-color: #F47920; box-shadow: 0 0 0 1px #F47920 inset; }
.fpc-tpl-tile.current .fpc-tpl-name { color: #F47920; font-weight: 600; }
.fpc-tpl-empty, .fpc-tpl-err { grid-column: 1 / -1; color: #aaa; font-size: 11px; padding: 6px 2px; }
.fpc-tpl-err { color: #ff8a80; }
/* the Verses head keeps its sticky top, but sits under our block's rule */
.fpc-verses-head { margin-top: 0; }

/* ---- 13b · The strip (rev 10, 2026-09-20 late) ----------------------------
 * Owner, on his screen after the rev 9 push: the open library pushed the
 * verses below the fold. The block now opens as ONE ROW of three small tiles
 * (the design on the card first, then by rank) and a full-width "See all N
 * designs" button; the rev 9 body (sentence, pills, grid) is the expanded
 * state, with "Show fewer" at its foot. Three tiles across the 240 px column:
 * (240 − 16 padding − 2 × 6 gap) / 3 ≈ 70 px each, 119 px of thumbnail. */
.fpc-tpl-strip { padding-bottom: 2px; }
.fpc-tpl-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 6px; margin-bottom: 6px; }
.fpc-tpl-row .fpc-tpl-tile .fpc-tpl-name { font-size: 10px; padding: 3px 2px 4px; }
.fpc-tpl-more {
  display: block; width: 100%; box-sizing: border-box; margin: 0; padding: 5px 8px;
  background: #1c1c1c; color: #F47920; border: 1px solid #4a4a4a; border-radius: 4px;
  font: inherit; font-size: 11px; font-weight: 600; line-height: 1.4; cursor: pointer; text-align: center;
}
.fpc-tpl-more:hover { background: #2a2a2a; border-color: #F47920; color: #fff; }
.fpc-tpl-body .fpc-tpl-less { margin-top: 8px; }
.fpc-tpl-empty, .fpc-tpl-err { grid-column: 1 / -1; }

/* ---- 13c · The block in the right column (rev 11, 2026-09-21) -------------
 * Owner, after seeing the rev 10 strip live on the left and a mockup of the
 * right: the block goes at the top of the Images column, the Verses column
 * goes back to only the words. The bundle sizes .ed2-side at 200 px; 240 px
 * (the Verses column's width) keeps the strip's three tiles at ~70 px and the
 * library's two-column grid at the rev 9 tile size. Its 8 px side padding
 * matches .ed2-left, so the block's -8 px margins still meet the edges. */
.ed2-side { flex: 0 0 240px; width: 240px; }

/* The switch-design confirm (rev 9). Same look as the proof overlay above;
 * its own classes so nothing in the bundle's Ed2Modal is depended on. */
.fpc-confirm {
  position: fixed; inset: 0; z-index: 2147483000;
  background: rgba(20, 20, 20, .62);
  display: flex; align-items: center; justify-content: center;
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}
.fpc-confirm-box {
  background: #fff; color: #222; border-radius: 8px; padding: 24px 28px;
  max-width: 440px; width: calc(100% - 40px);
  box-shadow: 0 10px 40px rgba(0,0,0,.4); border-top: 4px solid #F47920;
}
.fpc-confirm-title { font-size: 17px; font-weight: 700; margin-bottom: 8px; }
.fpc-confirm-msg { font-size: 14px; color: #555; line-height: 1.45; }
.fpc-confirm-actions { display: flex; justify-content: flex-end; gap: 10px; margin-top: 18px; }
.fpc-confirm-btn {
  border: 1px solid #ccc; background: #fff; color: #333; border-radius: 4px;
  padding: 8px 16px; font-size: 14px; font-weight: 600; cursor: pointer;
}
.fpc-confirm-btn.yes { background: #F47920; border-color: #F47920; color: #fff; }
.fpc-confirm-btn:hover { filter: brightness(0.96); }

/* The laminated background sits at the bleed geometry (left/top -0.125 in,
 * 2.75 x 4.5 in) so the trim shows exactly the art's trim area and the
 * renderer's bleed stretch lands the same file on the same canvas. .ed2-page
 * clips it — except while a photo on that card is SELECTED (PageView.vue
 * .ed2-photo-open opens the clip on all four edges so the photo's overflow and
 * corner grips are reachable, ruling 9/14). In that state the 12 px of bleed
 * showed around the card. Clip the still (non-interactive) background to the
 * page in that state; lam only — the 8-Up art is at trim with no bleed. */
#easelMount[data-surface="lam"] .ed2-page.ed2-photo-open .ed2-item.ed2-img.still { clip-path: inset(12px); }

/* ---- 13d · Design Boxes (rev 13, 2026-09-21) -------------------------------
 * The "Design Boxes" strip easel-mount.js installs right under the Design
 * Templates block in .ed2-side: the same head furniture (the .fpc-tpl-* rules
 * above), one sentence, one row of rendered swatches — each tile paints its
 * preset's band (rgba background, radius, the preset's type colour) over a
 * soft photo-like backdrop, so the customer sees what lands. The band on the
 * CARD is painted by the bundle (fpc-port-3, state.js bgSpec) and the print
 * page — nothing here touches a card. */
.fpc-dbx { margin: 0 -8px 10px; padding: 0 8px 8px; border-bottom: 3px solid #F47920; }
.fpc-dbx .fpc-dbx-head { position: static; margin: 0 -8px 6px; padding: 8px 8px 6px; }
.fpc-dbx-sub { color: #aaa; line-height: 1.35; font-size: 11px; margin-bottom: 8px; }
.fpc-dbx-row { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.fpc-dbx-tile {
  display: block; width: 100%; padding: 0; margin: 0; background: #1c1c1c; color: #ddd;
  border: 2px solid transparent; border-radius: 4px; cursor: pointer; text-align: center;
  overflow: hidden; font: inherit;
}
.fpc-dbx-tile:hover { border-color: #F47920; color: #fff; transform: translateY(-1px); }
.fpc-dbx-swatch {
  display: flex; align-items: center; justify-content: center; height: 46px; padding: 6px;
  box-sizing: border-box;
  background: linear-gradient(135deg, #6b7f95 0%, #a7b6c4 45%, #c8a97e 100%);   /* a stand-in for busy art */
}
.fpc-dbx-band {
  display: block; width: 100%; padding: 4px 2px; box-sizing: border-box;
  font-family: 'Quattrocento', Georgia, serif; font-size: 11px; letter-spacing: 0.5px; line-height: 1.2;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fpc-dbx-tile .fpc-tpl-name { font-size: 10px; padding: 3px 2px 4px; }
/* The empty-box ghost on a band reads "Your words" instead of LDM's "Click to
 * add text": the band was clicked to be typed in, and the ghost sits centred
 * in it. A copy rule on the pseudo-element — nothing in the content, nothing
 * printed, nothing for the placeholder guard. */
.ed2-text.ed2-empty:not(.editing) .ed2-textDiv.ed2-bg > p:first-child::before { content: 'Your words'; }


/* ---- 14 · The Template Maker (rev 16, 2026-09-22) ---------------------------
 * Designer mode (/easel?product=lam&designer=1&easel=<EASEL_TOKEN>; the page
 * shows it only after GET /easel/api/designer answers 200 — the easel's own
 * token). A block at the top of the right column, above Design Templates, in
 * the same furniture (.fpc-tpl-head). While designing, Continue and the
 * ripcord are hidden — a designer downloads a template, never orders; while
 * testing as a customer, Continue comes back (it shows the proof in place).
 * The role tags on the card are a pseudo-element on the element's box
 * (data-fpc-role, set by easel-mount.js dmDecorate) — screen only. */
#easelMount[data-designer="1"]:not([data-testing="1"]) .fpc-continue,
#easelMount[data-designer="1"] .fpc-ripcord { display: none !important; }
.fpc-dm { margin: 0 -8px 10px; padding: 0 8px 10px; border-bottom: 3px solid #F47920; }
.fpc-dm .fpc-dm-head { position: static; margin: 0 -8px 8px; padding: 8px 8px 6px; display: flex; align-items: center; justify-content: space-between; }
.fpc-dm-badge { background: #F47920; color: #fff; border-radius: 3px; font-size: 9px; font-weight: 700; letter-spacing: .5px; text-transform: uppercase; padding: 1px 5px; }
.fpc-dm-body { font-size: 11px; color: #ccc; text-align: left; }
.fpc-dm-lbl { display: block; color: #aaa; font-size: 10px; margin-bottom: 6px; }
.fpc-dm-in {
  display: block; width: 100%; box-sizing: border-box; margin-top: 2px;
  background: #1c1c1c; color: #eee; border: 1px solid #4a4a4a; border-radius: 3px;
  padding: 4px 6px; font: inherit; font-size: 12px;
}
.fpc-dm-in:focus { outline: none; border-color: #F47920; }
.fpc-dm-two { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.fpc-dm-sec { color: #fff; font-weight: 600; font-size: 11px; margin: 10px 0 4px; }
.fpc-dm-sec .fpc-dm-hint { font-weight: 400; }
.fpc-dm-hint { color: #999; font-size: 10px; line-height: 1.35; }
.fpc-dm-hint-block { display: block; margin: 2px 0 2px; }
.fpc-dm-row { display: flex; align-items: center; gap: 6px; margin: 4px 0; }
.fpc-dm-k { color: #aaa; font-size: 11px; flex: 0 0 auto; }
.fpc-dm-sel { margin-top: 0; flex: 1 1 auto; }
.fpc-dm-val { color: #9ccc65; font-size: 11px; }
.fpc-dm-ok { color: #9ccc65; font-size: 11px; }
.fpc-dm-btn {
  background: #2a2a2a; color: #eee; border: 1px solid #4a4a4a; border-radius: 4px;
  padding: 4px 9px; font: inherit; font-size: 11px; font-weight: 600; cursor: pointer; line-height: 1.4;
}
.fpc-dm-btn:hover:not(:disabled) { border-color: #F47920; color: #fff; }
.fpc-dm-btn.primary { background: #F47920; border-color: #F47920; color: #fff; }
.fpc-dm-btn.primary:hover:not(:disabled) { filter: brightness(1.08); }
.fpc-dm-btn.ghost { background: transparent; color: #bbb; font-weight: 400; }
.fpc-dm-btn:disabled { opacity: .45; cursor: not-allowed; }
.fpc-dm-chips { display: flex; gap: 4px; flex-wrap: wrap; }
.fpc-dm-chip {
  background: #333; color: #ddd; border: 1px solid #4a4a4a; border-radius: 12px;
  padding: 2px 10px; font: inherit; font-size: 11px; line-height: 1.5; cursor: pointer;
}
.fpc-dm-chip:hover { color: #fff; border-color: #F47920; }
.fpc-dm-chip.on { background: #F47920; border-color: #F47920; color: #fff; font-weight: 600; }
.fpc-dm-check { list-style: none; margin: 0; padding: 0; }
.fpc-dm-check li { position: relative; padding: 1px 0 1px 16px; line-height: 1.35; text-align: left; font-weight: 400; font-size: 11px; }
.fpc-dm-check li::before { position: absolute; left: 0; top: 1px; font-weight: 700; }
.fpc-dm-check li.fpc-dm-ok { color: #cfcfcf; }
.fpc-dm-check li.fpc-dm-ok::before { content: '\2713'; color: #9ccc65; }
.fpc-dm-check li.fpc-dm-warn { color: #ffcc80; }
.fpc-dm-check li.fpc-dm-warn::before { content: '!'; color: #ffb74d; left: 4px; }
.fpc-dm-check li.fpc-dm-err { color: #ff8a80; }
.fpc-dm-check li.fpc-dm-err::before { content: '\2715'; color: #ff5252; }
.fpc-dm-actions { display: flex; gap: 6px; margin-top: 10px; }
.fpc-dm-actions .fpc-dm-btn { flex: 1 1 0; padding: 6px 4px; }
.fpc-dm-msg { min-height: 14px; margin-top: 6px; color: #9ccc65; font-size: 10px; line-height: 1.35; }
.fpc-dm-msg.err { color: #ff8a80; }
.fpc-dm-open { margin-top: 2px; }
.fpc-dm-note { color: #bbb; font-size: 11px; line-height: 1.4; padding-bottom: 4px; }
.fpc-dm-link { color: #F47920; }
/* the role tags on the card — screen only, never in the document */
#easelMount[data-designer="1"]:not([data-testing="1"]) .ed2-item[data-fpc-role]::after {
  content: attr(data-fpc-role);
  position: absolute; left: 0; top: 0; transform: translateY(-100%);
  background: #F47920; color: #fff; font: 700 9px/1.3 Arial, sans-serif; letter-spacing: .4px; text-transform: uppercase;
  padding: 1px 4px; border-radius: 2px 2px 0 0; pointer-events: none; white-space: nowrap; z-index: 5;
}
/* testing as a customer: one bar across the top, and the proof shown in place */
.fpc-dm-testbar {
  position: fixed; left: 12px; bottom: 10px; z-index: 2147482000;   /* over the footer — never over the toolbar */
  display: flex; align-items: center; gap: 12px; padding: 7px 8px 7px 14px;
  background: #1c1c1c; color: #eee; border: 2px solid #F47920; border-radius: 6px;
  font: 13px/1.3 -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
  box-shadow: 0 6px 24px rgba(0,0,0,.45);
}
.fpc-dm-testbar .fpc-dm-btn { font-size: 12px; padding: 5px 12px; }
.fpc-proof-box.fpc-dm-proof { max-width: 760px; }
.fpc-dm-proof-pics { display: flex; gap: 16px; justify-content: center; margin: 12px 0; }
.fpc-dm-proof-pics img { width: 260px; height: auto; box-shadow: 0 2px 10px rgba(0,0,0,.35); background: #fff; }

/* ---- 14b · Place the art (rev 17, 2026-09-22) -------------------------------
 * The Template Maker's "Place the art…": the art is moved and sized on the
 * card and any gap is filled from the art's own edge. The preview canvas is
 * drawn inside the art's own (still) box, under every other box; the drag
 * layer sits over the card while placing. Screen only — the document changes
 * on Done (easel-mount.js dmPlaceEnd). [hidden] is restated because the
 * panel's rows are flex and an author display beats the UA's [hidden]. */
.fpc-dm [hidden] { display: none !important; }
.fpc-dm-place {
  margin: 4px 0 6px; padding: 7px 8px 6px; border: 1px solid #F47920; border-radius: 4px;
  background: #262626;
}
.fpc-dm-place-title { color: #fff; font-weight: 600; font-size: 11px; margin-bottom: 6px; }
.fpc-dm-place-size { display: flex; align-items: center; gap: 6px; margin: 2px 0 4px; }
.fpc-dm-place-size input[type="range"] { flex: 1 1 auto; min-width: 0; accent-color: #F47920; }
.fpc-dm-place-num { color: #eee; font-size: 11px; min-width: 38px; text-align: right; font-variant-numeric: tabular-nums; }
.fpc-dm-colour { flex: 0 0 28px; width: 28px; height: 22px; padding: 0; border: 1px solid #4a4a4a; border-radius: 3px; background: none; cursor: pointer; }
.fpc-dm-place-dpi { font-size: 11px; margin: 4px 0; }
.fpc-dm-place-dpi.fpc-dm-warn { color: #ffcc80; }
.fpc-dm-place-dpi.fpc-dm-err { color: #ff8a80; }
.fpc-dm-place-btns { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; margin: 6px 0 4px; }
.fpc-dm-place-btns .fpc-dm-btn { padding: 4px 2px; }
.fpc-dm-placecanvas {
  position: absolute; left: 0; top: 0; width: 100%; height: 100%;
  pointer-events: none; display: block;
}
.fpc-dm-placelayer {
  position: absolute; inset: 0; z-index: 2147480000;
  cursor: move; touch-action: none; background: transparent;
  outline: 2px dashed rgba(244, 121, 32, .9); outline-offset: -2px;
}
.fpc-dm-placelayer.dragging { cursor: grabbing; }
.fpc-dm-row [data-a="place-front"] { flex: 0 0 auto; white-space: nowrap; }

/* §14c — rev 18 (#115): the photo window. The Template Maker's Shape / Edge /
 * Colour / Width / Fade rows (easel-mount.js dmSlotControls), and what the
 * toolbar shows while a shaped window is selected (data-box-sel, set by
 * boxSelMark): its look is baked into the window, so the Shape tool, Fit to
 * card, Tilt and the square CSS Border never apply to it; the family also has
 * no Arrange (Center / Middle would move a pinned window) — Position only. */
.fpc-dm-slot { margin: 2px 0 4px; }
.fpc-dm-slotrow { display: flex; align-items: center; gap: 6px; margin: 3px 0; }
.fpc-dm-slotrow > .fpc-dm-k { flex: 0 0 44px; }
.fpc-dm-slotrow .fpc-dm-chips { display: flex; flex-wrap: wrap; gap: 3px; }
.fpc-dm-swatches { display: flex; align-items: center; gap: 4px; flex-wrap: wrap; }
.fpc-dm-sw { width: 20px; height: 20px; padding: 0; border: 1px solid #4a4a4a; border-radius: 50%; cursor: pointer; box-shadow: inset 0 0 0 1px rgba(0,0,0,.25); }
.fpc-dm-sw.on { outline: 2px solid #F47920; outline-offset: 1px; }
.fpc-dm-row [data-v="slot-size"] { font-variant-numeric: tabular-nums; }
#easelMount[data-box-sel] .ed2-shape,
#easelMount[data-box-sel] .ed2-fitcard,
#easelMount[data-box-sel] .ed2-tilt,
#easelMount[data-box-sel] .ed2-border { display: none !important; }
#easelMount[data-box-sel="customer"] .ed2-arrange { display: none !important; }
/* §14e — rev 23 (owner 9/24): a selected WINDOW photo, family side. It is pinned —
 * nothing to pull — so no grips; a solid outline says "selected" without saying
 * "resize"; the × stays; the pointer says a click does something (it opens
 * Position — easel-mount.js rev 23). */
#easelMount[data-box-sel="customer"] .ed2-item.ed2-img.selected .ed2-grip { display: none !important; }
#easelMount[data-box-sel="customer"] .ed2-item.ed2-img.selected { outline-style: solid; cursor: pointer; }
/* §14f — rev 23: the toolbar's number boxes at the widths LDM gives them (the page's
 * own input rules stretched them to 96 px), so Rotate's quarter-turn button does not
 * push the photo toolbar onto a third row at 1280 px (measured: 73 -> 102 px tall). */
#easelMount .ed2-toolbar .ed2-tilt .ed2-tiltnum { width: 52px; }
#easelMount .ed2-toolbar .ed2-border .ed2-bnum { width: 44px; }
/* §14d — rev 19: the Template Maker in five steps (owner 9/23). Each section
 * is a toggle header — caret, number, title and a one-line status on the
 * right (easel-mount.js dmSecHead / dmPaintStatus) — over its body. The
 * header keeps .fpc-dm-sec (the rev 16 section style) and restyles it as a
 * button. Two action rows in Finish: Test alone, then Submit + Download. */
.fpc-dm .fpc-dm-toggle {
  display: flex; align-items: center; gap: 6px; width: 100%; box-sizing: border-box;
  margin: 10px 0 4px; padding: 5px 6px; background: #262626; color: #fff;
  border: 1px solid #3a3a3a; border-radius: 4px; cursor: pointer; text-align: left;
  font: inherit; font-size: 11px; font-weight: 600; line-height: 1.3;
}
.fpc-dm .fpc-dm-toggle:hover { border-color: #F47920; }
.fpc-dm-caret {
  flex: 0 0 auto; width: 0; height: 0; border-left: 5px solid #bbb;
  border-top: 4px solid transparent; border-bottom: 4px solid transparent; transition: transform .12s ease;
}
.fpc-dm-toggle[aria-expanded="true"] .fpc-dm-caret { transform: rotate(90deg); }
.fpc-dm-sn {
  flex: 0 0 16px; height: 16px; border-radius: 50%; background: #F47920; color: #fff;
  font-size: 10px; line-height: 16px; text-align: center; font-weight: 700;
}
.fpc-dm-stitle { flex: 0 0 auto; }
.fpc-dm-sstat {
  flex: 1 1 auto; min-width: 0; text-align: right; font-weight: 400; font-size: 10px; color: #999;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.fpc-dm-sstat.fpc-dm-st-ok { color: #9ccc65; }
.fpc-dm-sstat.fpc-dm-st-err { color: #ff8a80; }   /* not .err — easel.html centres #easelMount .err (Patch 3 §7) */
.fpc-dm-secbody { padding: 0 2px 2px; }
.fpc-dm-sub { color: #ddd; font-size: 11px; font-weight: 600; margin: 8px 0 2px; }
.fpc-dm-actions + .fpc-dm-actions { margin-top: 6px; }
.fpc-dm-row .fpc-dm-btn + .fpc-dm-btn { margin-left: 0; }

/* §14e — rev 20 (#119 + the see-through panel, owner 9/23). The panel is an
 * empty text box (role 'panel') - it shows no empty-box ghost, on anyone's
 * easel (data-fpc-panel is set by easel-mount.js panelMark for every mode);
 * nothing printed either way. The look controls reuse §14c's rows; the Design
 * Boxes' panel tile paints the panel itself over the stand-in art. */
#easelMount .ed2-item[data-fpc-panel] .ed2-textDiv > p:first-child::before { content: none !important; }
/* rev 30: a heading set to "No heading" is an empty box on purpose - no empty-box ghost either (easel-mount.js panelMark) */
#easelMount .ed2-item[data-fpc-hdnone] .ed2-textDiv > p:first-child::before { content: none !important; }
.fpc-dm-look { margin: 4px 0 2px; padding-top: 2px; border-top: 1px solid #3a3a3a; }
.fpc-dm-look .fpc-dm-sub { margin-top: 4px; }
.fpc-dm-colour.on { outline: 2px solid #F47920; outline-offset: 1px; }
.fpc-dm-row .fpc-dm-hint + .fpc-dm-btn { margin-left: 4px; }
.fpc-dbx-band.fpc-dbx-panel { height: 34px; border-radius: 0 !important; }
/* Three presets since rev 20: one row of three, so the Design Boxes block keeps its rev 13 height and the Images head
 * does not move down the column (pass F's position check). */
.fpc-dbx-row { grid-template-columns: repeat(3, 1fr); gap: 5px; }
.fpc-dbx-row .fpc-dbx-swatch { padding: 6px 4px; }
.fpc-dbx-row .fpc-dbx-band { font-size: 9.5px; letter-spacing: 0.2px; padding: 4px 1px; }
.fpc-dbx-row .fpc-dbx-tile .fpc-tpl-name { font-size: 9.5px; line-height: 1.15; }

/* ---- 14c · rev 51 (#211): the Template Maker's guide is Lamcraft's 0.14" safe zone ---------------
 * The customer's line is the 4 pt drift margin (5.333 px — the bundle's SAFE_INSET, §10): what the die can take.
 * A designer laying out a template needs Lamcraft's own rule, the die-cut SAFE ZONE: lib/generate-fpc.js:59
 * CARD_PAD = 10 pt (0.14") — "content padding from trim edge inward (0.14" safe zone)". 10 pt x 96/72 = 13.333 px.
 * So in designer mode (and only there: data-designer="1", not while testing as a customer) the one guide line moves
 * to 13.333 px, over the inline left/top/width/height PageView.vue safeStyle() writes — the §10 override pattern
 * from before #79, scoped to the designer. Nothing else follows it: default boxes, the grip snap and a family's
 * view stay on 5.333 px. The Template Maker's checklist reads the same 13.333 px (easel-mount.js DM_SAFE_PX), so
 * what the line shows and what the checklist warns about are one number. Laminated only ([data-surface="lam"]): the
 * Template Maker is laminated, and on an 8-Up the line is the 4 pt white edge that really prints (§10 / rev 35). */
#easelMount[data-surface="lam"][data-designer="1"]:not([data-testing="1"]) .ed2-safezone {
  left: 13.333px !important;
  top: 13.333px !important;
  width: calc(100% - 26.667px) !important;
  height: calc(100% - 26.667px) !important;
}
#easelMount[data-surface="lam"][data-designer="1"]:not([data-testing="1"]) .ed2-safezone::before { content: 'Safe zone 0.14\2033'; }
#easelMount[data-surface="lam"][data-designer="1"]:not([data-testing="1"]) .ed2-safezone::after {
  content: 'Lamcraft\2019s die-cut safe zone: 0.14 inch (10 pt) in from the cut.\A Keep the photo window, the name, the dates and every word inside this line.\A\A The art runs past it, all the way to the card edge (the art file carries the bleed).';
}

/* ---- 15 · The simple view (rev 27, 2026-09-25 — Patch 15 §6, "all recs") -----------
 * html.fpc-sv-on = the fill-in panel over the LIVE easel (artboards 3 and 5 of the
 * mockup canvas). The cards are the shell's own two pages; the header, the panel,
 * the row under the cards and the phone's Continue bar are the mount's own
 * fpc-sv-* elements (law 35: this page already styles header, label, .panel, .row).
 * The shell's toolbar is moved OFF-SCREEN, not hidden: the hidden Save (the exit),
 * the file input and the Position button keep their boxes, and its status line
 * (.ed2-imgmsg, position:fixed) still shows. Desktop ≥ 900 px: header 72 · panel 400
 * · cards; below 900 the page stacks and scrolls under ONE card with a Front/Back
 * switch and Continue pinned to the bottom. */
.fpc-sv-head, .fpc-sv-panel, .fpc-sv-bar, .fpc-sv-under { display: none; }
html.fpc-sv-on { --fpc-sv-font: 'Source Sans 3', 'Segoe UI', system-ui, -apple-system, Roboto, Arial, sans-serif; }
html.fpc-sv-on body:not(.harness-on) { background: #efeae1; }
html.fpc-sv-on .ed2-root { top: 72px; left: 400px; background: #efeae1; z-index: 30; }
html.fpc-sv-on .ed2-toolbar { position: fixed !important; left: -10000px !important; top: 0 !important; width: 1280px; }
html.fpc-sv-on .ed2-left, html.fpc-sv-on .ed2-left-rail, html.fpc-sv-on .ed2-side, html.fpc-sv-on .ed2-foot,
html.fpc-sv-on .ed2-under, html.fpc-sv-on .ed2-labels, html.fpc-sv-on .ed2-safezone,
html.fpc-sv-on .ed2-grip, html.fpc-sv-on .ed2-x, html.fpc-sv-on .ed2-ring { display: none !important; }
html.fpc-sv-on .ed2-viewport { display: flex; flex-direction: column; align-items: center; padding: 24px; background: transparent; }
html.fpc-sv-on .ed2-spread { margin: auto auto -56px !important; flex: 0 0 auto; }   /* -56 = the hidden label + button rows (LABEL_H + UNDER_H) */
html.fpc-sv-on .ed2-page, html.fpc-sv-on .ed2-page.ed2-target { box-shadow: 0 1px 2px rgba(0,0,0,.14), 0 8px 18px rgba(0,0,0,.14) !important; }
html.fpc-sv-on .ed2-item, html.fpc-sv-on .ed2-item * { cursor: pointer !important; }
html.fpc-sv-on .ed2-item.selected, html.fpc-sv-on .ed2-item.editing { outline: none !important; box-shadow: none !important; }
html.fpc-sv-on .ed2-imgmsg { bottom: 28px; left: calc(400px + (100vw - 400px) / 2); max-width: calc(100vw - 460px); }   /* centred over the cards, clear of the panel */
html.fpc-sv-on .ed2-imgmsg.fpc-sv-mute { display: none !important; }   /* the guide's hint: the simple view shows no guide */
html.fpc-sv-on .fpc-sv-under { display: flex; flex-direction: column; align-items: center; gap: 22px; margin: 12px auto auto; flex: 0 0 auto; font-family: var(--fpc-sv-font);
  position: relative; z-index: 1; }   /* over the spread's hidden 56-px tail (the spread is positioned, so it would paint on top) */
.fpc-sv-caps { display: flex; justify-content: center; }
.fpc-sv-caps span { display: block; text-align: center; font-size: 14px; font-weight: 600; color: #4a453e; }
.fpc-sv-sides { display: none; border: 1px solid #cfc6b6; border-radius: 10px; overflow: hidden; background: #fff; }
.fpc-sv-sides button { min-height: 44px; padding: 0 22px; border: 0; background: #fff; color: #22201c; font: 600 15px var(--fpc-sv-font); cursor: pointer; }
.fpc-sv-sides button[aria-pressed="true"] { background: #22201c; color: #fff; }
.fpc-sv-switch:empty { display: none; }

html.fpc-sv-on .fpc-sv-head {
  display: flex; position: fixed; top: 0; left: 0; right: 0; height: 72px; box-sizing: border-box; padding: 0 32px;
  align-items: center; gap: 20px; background: #fff; border-bottom: 1px solid #e4ded3; z-index: 20;
  font-family: var(--fpc-sv-font); color: #22201c;
}
.fpc-sv-all { font-size: 15px; font-weight: 600; color: #9a4610; text-decoration: none; white-space: nowrap; }
.fpc-sv-all:hover { color: #7a370c; text-decoration: underline; }
.fpc-sv-short { display: none; }
.fpc-sv-title { flex: 1 1 auto; min-width: 0; text-align: center; font-size: 16px; font-weight: 600; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.fpc-sv-go {
  min-height: 48px; padding: 0 24px; border: 0; border-radius: 8px; background: #B85410; color: #fff;
  font: 700 16px var(--fpc-sv-font); cursor: pointer; white-space: nowrap;
}
.fpc-sv-go:hover { background: #a14a0e; }
.fpc-sv-go:focus-visible, .fpc-sv-btn:focus-visible, .fpc-sv-all:focus-visible, .fpc-sv-sides button:focus-visible { outline: 3px solid #F47920; outline-offset: 2px; }

html.fpc-sv-on .fpc-sv-panel {
  display: flex; flex-direction: column; gap: 22px; position: fixed; top: 72px; left: 0; bottom: 0; width: 400px;
  box-sizing: border-box; padding: 28px 32px; background: #fff; border-right: 1px solid #e4ded3; overflow-y: auto; z-index: 20;
  font-family: var(--fpc-sv-font); color: #22201c; font-size: 15px;
}
.fpc-sv-intro { display: flex; flex-direction: column; gap: 4px; }
.fpc-sv-panel .fpc-sv-h1 { margin: 0; font-family: 'Cormorant Garamond', Georgia, serif; font-weight: 600; font-size: 34px; line-height: 1.1; color: #22201c; }
.fpc-sv-panel .fpc-sv-lead { margin: 0; font-size: 15px; color: #5f5a52; }
.fpc-sv-sec { display: flex; flex-direction: column; gap: 8px; }
.fpc-sv-panel .fpc-sv-k { display: block; margin: 0; font-weight: 700; font-size: 16px; color: #22201c; }
.fpc-sv-panel .fpc-sv-sub { display: block; margin: 0; font-size: 14px; color: #4a453e; }
.fpc-sv-row { display: flex; gap: 10px; }
.fpc-sv-dates { display: flex; gap: 10px; }
.fpc-sv-date { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.fpc-sv-panel .fpc-sv-in {
  min-height: 44px; width: 100%; box-sizing: border-box; padding: 0 12px; border: 1px solid #cfc6b6; border-radius: 8px;
  font: 400 16px var(--fpc-sv-font); color: #22201c; background: #fff;
}
.fpc-sv-panel .fpc-sv-in:focus { outline: none; border-color: #B85410; box-shadow: 0 0 0 3px rgba(244,121,32,.22); }
.fpc-sv-panel .fpc-sv-in:disabled { background: #f3f0ea; color: #8a847a; }
/* rev 30: the Heading menu - a select that reads like the fields; its own-words box sits under it */
.fpc-sv-panel select.fpc-sv-sel {
  appearance: none; -webkit-appearance: none; padding-right: 34px; cursor: pointer; text-overflow: ellipsis;
  background: #fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath d='M1 1l5 5 5-5' fill='none' stroke='%2322201c' stroke-width='1.6'/%3E%3C/svg%3E") no-repeat right 12px center;
}
.fpc-sv-panel [data-sv="head-sec"][hidden], .fpc-sv-panel #fpcSvHeadOwn[hidden] { display: none; }
.fpc-sv-btn {
  min-height: 44px; padding: 0 18px; border: 1px solid #cfc6b6; border-radius: 8px; background: #fff; color: #22201c;
  font: 600 15px var(--fpc-sv-font); cursor: pointer;
}
.fpc-sv-btn:hover:not(:disabled) { border-color: #9d9383; }
.fpc-sv-btn:disabled { color: #a39d93; cursor: default; }
.fpc-sv-btn--main { border: 2px solid #B85410; color: #9a4610; font-weight: 700; }
.fpc-sv-btn--main:hover:not(:disabled) { border-color: #9a4610; background: #fff8f2; }
.fpc-sv-btn--list { text-align: left; }
.fpc-sv-btn--dark { align-self: flex-start; border-color: #22201c; font-weight: 700; }
/* rev 29 (9/26): "Adding your photo…" — a spinner on the Upload button while the photo goes in (the mount sets data-busy);
   the front card's outline while a picture file is dragged over it (the mount sets data-sv-drop on #easelMount) */
.fpc-sv-btn[data-busy] { color: #9a4610; cursor: progress; }
.fpc-sv-btn[data-busy]::before {
  content: ''; display: inline-block; width: 13px; height: 13px; margin-right: 8px; vertical-align: -2px;
  border: 2px solid rgba(154, 70, 16, .3); border-top-color: #9a4610; border-radius: 50%; animation: fpcSvSpin .8s linear infinite;
}
@keyframes fpcSvSpin { to { transform: rotate(360deg); } }
#easelMount[data-sv-drop] .ed2-page[data-page="0"] { outline: 3px dashed #B85410; outline-offset: 6px; }
.fpc-sv-help { font-size: 14px; color: #5f5a52; }
.fpc-sv-note { font-size: 14px; color: #8a4a12; }
.fpc-sv-more { margin-top: auto; padding-top: 18px; border-top: 1px solid #e4ded3; display: flex; flex-direction: column; gap: 8px; }
.fpc-sv-more-q { font-size: 15px; font-weight: 600; }
.fpc-sv-narrow { display: none; }
.fpc-sv-measure { position: absolute; left: -20000px; top: 0; visibility: hidden; }

/* The full easel's way back (a ghost button beside Continue, the ripcord's look) */
.ed2-ctl.fpc-svback { background: transparent; color: #eee; border: 1px solid #777; }
.ed2-ctl.fpc-svback:hover { border-color: #F47920; color: #fff; }

/* ---- 15b · The simple view on a phone (< 900 px; artboard 5) -------------------- */
@media (max-width: 899px) {
  html.fpc-sv-on body:not(.harness-on) { background: #fff; }
  html.fpc-sv-on body:not(.harness-on) .wrap { display: block; max-width: none; margin: 0; padding: 0; }
  html.fpc-sv-on .fpc-sv-head { position: static; height: 56px; padding: 0 20px; gap: 12px; }
  html.fpc-sv-on .fpc-sv-head .fpc-sv-go, .fpc-sv-long, .fpc-sv-prod { display: none; }
  .fpc-sv-short { display: inline; }
  .fpc-sv-title { text-align: right; font-size: 15px; }
  html.fpc-sv-on .ed2-root { position: relative !important; inset: auto !important; top: auto; left: auto; height: auto; z-index: auto; }
  html.fpc-sv-on .ed2-viewport { display: block; overflow: hidden; padding: 20px 0 0; }
  html.fpc-sv-on .ed2-spread { margin: 0 0 -56px !important; transform: translateX(var(--fpc-sv-shift, 0px)); transition: transform .18s ease; }
  html.fpc-sv-on #easelMount[data-sv-side="front"] .ed2-page[data-page="1"],
  html.fpc-sv-on #easelMount[data-sv-side="back"] .ed2-page[data-page="0"] { opacity: 0; pointer-events: none; }   /* not visibility: a child can override that */
  html.fpc-sv-on .fpc-sv-under { margin: 14px auto 18px; gap: 14px; }
  .fpc-sv-caps { display: none; }
  .fpc-sv-sides { display: flex; }
  html.fpc-sv-on .fpc-sv-panel { position: static; width: auto; padding: 22px 20px 112px; gap: 20px; border-right: 0; overflow: visible; }
  .fpc-sv-panel .fpc-sv-intro { display: none; }
  .fpc-sv-panel .fpc-sv-in, .fpc-sv-btn { min-height: 48px; font-size: 16px; }
  .fpc-sv-row .fpc-sv-btn--main { flex: 1 1 auto; }
  .fpc-sv-dates { flex-direction: column; }
  .fpc-sv-more { margin-top: 0; padding-top: 16px; gap: 4px; }
  .fpc-sv-more-q, .fpc-sv-wide { display: none; }
  .fpc-sv-narrow { display: block; }
  .fpc-sv-btn--dark { border: 0; padding: 0; min-height: 0; background: none; color: #9a4610; font-size: 16px; text-decoration: underline; text-align: left; }
  html.fpc-sv-on .fpc-sv-bar {
    display: block; position: fixed; left: 0; right: 0; bottom: 0; padding: 16px 20px 24px; background: #fff;
    border-top: 1px solid #e4ded3; z-index: 100; font-family: var(--fpc-sv-font);
  }
  .fpc-sv-bar .fpc-sv-go { width: 100%; min-height: 52px; font-size: 17px; }
  html.fpc-sv-on .ed2-imgmsg { bottom: 104px; left: 50%; max-width: 90vw; }
}

/* ---- 15c · #131 the sample face's cue (rev 27) --------------------------------------
 * "Sample photo — add yours", inside the photo window's own box on the front, while the
 * window shows the template's sample person (sampleFace). Page chrome: never in the
 * document, never in the proof. Card px (it scales with the zoom, like the card). */
.ed2-item .fpc-sv-cue {
  position: absolute; left: 50%; bottom: 9%; transform: translateX(-50%); z-index: 4; pointer-events: none;
  padding: 2px 7px; border-radius: 999px; background: rgba(34,32,28,.78); color: #fff; white-space: nowrap;
  font: 600 8.5px/1.3 'Source Sans 3', 'Segoe UI', system-ui, -apple-system, Roboto, Arial, sans-serif; letter-spacing: .1px;
}
/* the shell dashes a placeholder photo's outline (a drop zone); a window showing the sample face reads as a finished
   card with its cue instead (the cue is the mount's, so :has() finds exactly those) */
.ed2-item.ed2-img.placeholder:has(> .fpc-sv-cue) img { outline: none !important; }

/* ---- 15d · The verse picker (rev 27 rung 3) — inside the panel; a full sheet on a phone */
.fpc-sv-panel .fpc-sv-verses[hidden] { display: none; }
.fpc-sv-panel .fpc-sv-verses {
  position: absolute; inset: 0; z-index: 2; display: flex; flex-direction: column; gap: 12px; padding: 22px 24px 16px;
  background: #fff; overflow: hidden;
}
.fpc-sv-vhead { display: flex; align-items: center; gap: 12px; }
.fpc-sv-vback { border: 0; background: none; padding: 6px 0; color: #9a4610; font: 600 15px var(--fpc-sv-font); cursor: pointer; }
.fpc-sv-vtitle { font-weight: 700; font-size: 17px; }
.fpc-sv-vcats { display: flex; flex-wrap: wrap; gap: 6px; }
.fpc-sv-vcats button, .fpc-sv-libcats button {
  min-height: 34px; padding: 0 12px; border: 1px solid #cfc6b6; border-radius: 999px; background: #fff; color: #22201c;
  font: 600 14px var(--fpc-sv-font); cursor: pointer;
}
.fpc-sv-vcats button span { color: #8a847a; font-weight: 400; }
.fpc-sv-vcats button[aria-pressed="true"], .fpc-sv-libcats button[aria-pressed="true"] { background: #22201c; border-color: #22201c; color: #fff; }
.fpc-sv-vcats button[aria-pressed="true"] span { color: #d8d2c6; }
.fpc-sv-vlist { flex: 1 1 auto; overflow-y: auto; display: flex; flex-direction: column; gap: 6px; margin: 0 -6px; padding: 0 6px 8px; }
.fpc-sv-vrow {
  display: flex; flex-direction: column; gap: 2px; text-align: left; padding: 10px 12px; border: 1px solid #e4ded3; border-radius: 8px;
  background: #fff; cursor: pointer; font-family: var(--fpc-sv-font); color: #22201c;
}
.fpc-sv-vrow:hover { border-color: #B85410; background: #fff8f2; }
.fpc-sv-vname { font-weight: 700; font-size: 15px; }
.fpc-sv-vtext { font-size: 14px; color: #5f5a52; line-height: 1.35; }

/* ---- 15e · Switch design (rung 4): the strip under the cards and the library drawer */
.fpc-sv-switch { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; justify-content: center; }
.fpc-sv-swlabel { font-size: 14px; font-weight: 600; color: #4a453e; }
.fpc-sv-swrow { display: flex; gap: 8px; }
.fpc-sv-switch .fpc-tpl-tile, .fpc-sv-lib .fpc-tpl-tile {
  display: flex; flex-direction: column; align-items: center; gap: 4px; padding: 0; border: 0; background: none; cursor: pointer;
  font-family: var(--fpc-sv-font);
}
.fpc-sv-switch .fpc-tpl-tile img { width: 52px; height: 88px; object-fit: cover; border-radius: 4px; box-shadow: 0 1px 3px rgba(0,0,0,.2); outline: 2px solid transparent; outline-offset: 2px; }
.fpc-sv-switch .fpc-tpl-tile .fpc-tpl-name { display: none; }
.fpc-sv-switch .fpc-tpl-tile.current img, .fpc-sv-lib .fpc-tpl-tile.current img { outline-color: #B85410; }
.fpc-sv-switch .fpc-tpl-tile:hover img { outline-color: #cfc6b6; }
.fpc-sv-seeall { min-height: 40px; padding: 0 14px; border: 1px solid #cfc6b6; border-radius: 8px; background: #fff; color: #22201c; font: 600 14px var(--fpc-sv-font); cursor: pointer; }
.fpc-sv-lib { display: none; }
html.fpc-sv-on .fpc-sv-lib.open {
  display: flex; flex-direction: column; gap: 12px; position: fixed; top: 72px; left: 400px; right: 0; bottom: 0; z-index: 40;
  padding: 24px 32px; background: #efeae1; overflow-y: auto; font-family: var(--fpc-sv-font); color: #22201c;
}
.fpc-sv-libhead { display: flex; align-items: center; justify-content: space-between; }
.fpc-sv-libtitle { font-family: 'Cormorant Garamond', Georgia, serif; font-weight: 600; font-size: 30px; }
.fpc-sv-libx { width: 44px; height: 44px; border: 1px solid #cfc6b6; border-radius: 50%; background: #fff; font-size: 24px; line-height: 1; cursor: pointer; }
.fpc-sv-libsub { margin: 0; }
.fpc-sv-libcats { display: flex; flex-wrap: wrap; gap: 6px; }
.fpc-sv-libgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 20px 16px; }
.fpc-sv-lib .fpc-tpl-tile img { width: 100%; aspect-ratio: 300 / 510; height: auto; object-fit: cover; border-radius: 6px; box-shadow: 0 1px 2px rgba(0,0,0,.14), 0 6px 14px rgba(0,0,0,.12); outline: 3px solid transparent; outline-offset: 3px; }
.fpc-sv-lib .fpc-tpl-tile:hover img { outline-color: #cfc6b6; }
.fpc-sv-lib .fpc-tpl-name { font-size: 14px; font-weight: 600; }
@media (max-width: 899px) {
  html.fpc-sv-on.fpc-sv-vsheet .fpc-sv-panel .fpc-sv-verses { position: fixed; inset: 0; z-index: 150; padding: 16px 20px; }
  html.fpc-sv-on .fpc-sv-lib.open { top: 0; left: 0; z-index: 150; padding: 16px 20px 24px; }
  .fpc-sv-libgrid { grid-template-columns: repeat(2, 1fr); }
  .fpc-sv-switch { max-width: 360px; }
}
.fpc-sv-lib .fpc-tpl-name { color: #22201c; }
.fpc-sv-lib .fpc-tpl-tile.current .fpc-tpl-name { color: #9a4610; }
.fpc-sv-libx { font: 400 26px/1 var(--fpc-sv-font); color: #22201c; display: flex; align-items: center; justify-content: center; padding: 0; }
/* the way back, heading the right column (wide screens) */
.ed2-ctl.fpc-svback--side { display: block; width: 100%; margin: 8px 0 6px; padding: 8px 6px; border: 1px solid #F47920; border-radius: 4px;
  background: #2d2d2d; color: #fff; font-weight: 700; font-size: 12px; cursor: pointer; }
.ed2-ctl.fpc-svback--side:hover { background: #3a3a3a; }

/* ---- 15f · rev 28: the back is a choice — "Write your own words" at the top of the verse sheet */
.fpc-sv-panel .fpc-sv-own { margin: 10px 0 12px; }
.fpc-sv-panel .fpc-sv-ownbtn { width: 100%; text-align: left; }
.fpc-sv-panel .fpc-sv-owntext { display: block; width: 100%; height: auto; min-height: 150px; resize: vertical; line-height: 1.4; box-sizing: border-box; white-space: pre-wrap; }
.fpc-sv-panel .fpc-sv-ownact { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0 6px; }
.fpc-sv-panel .fpc-sv-ownact .fpc-sv-btn:disabled { opacity: .45; cursor: default; }
/* the primary action is a filled button on every screen (the phone turns the --dark button into a link, §15d) */
.fpc-sv-panel .fpc-sv-ownact .fpc-sv-ownuse { background: #1c1917; color: #fff; border-color: #1c1917; text-decoration: none; }
.fpc-sv-panel .fpc-sv-ownact .fpc-sv-ownuse:hover:not(:disabled) { background: #000; }

/* ---- 15g · rev 28, the owner's Document1 (9/26) */
/* the way back stays in view: it heads the right column, and the column scrolls (his screen: three uploads in the Images
   list, the column scrolled, the button gone). Pinned to the column's top; the first shadow paints the column's own colour
   over the 8 px above it and the column's side padding, so nothing shows through while the column scrolls under it. */
#easelMount .ed2-side > .ed2-ctl.fpc-svback--side { position: sticky; top: 8px; z-index: 6; box-shadow: 0 -8px 0 8px #262626, 0 5px 10px rgba(0, 0, 0, .45); }
/* a click on the back: one line at the top of the verse sheet saying how to change the verse (flashes on every click) */
.fpc-sv-panel .fpc-sv-vhint { margin: 10px 0 0; padding: 8px 10px; border-radius: 6px; background: #fdf1e6; color: #6b3208; font-size: 14px; line-height: 1.35; }
.fpc-sv-panel .fpc-sv-vhint.fpc-sv-flash { animation: fpc-sv-flash 1.1s ease-out 1; }
@keyframes fpc-sv-flash { 0% { background: #f7c79a; } 100% { background: #fdf1e6; } }

/* ---- 15h · rev 28b (9/26, the owner on rev 28 live: families must see the verse is pre-populated, "so they don't think it
   is just this verse or nothing"): "Suggested verse — change it" while the design's own default verse is untouched. The
   #131 cue's look, hung on the back card's top edge. It lives in .ed2-scale (the page clips its children, the scale does
   not) and the mount sets its left / top / font-size (11.5 px on screen at any zoom) — never in the document, never printed.
   The simple view only (in the full easel the page's own "Back" label sits on that edge); a click opens the verse sheet. */
.ed2-scale > .fpc-sv-vcue {
  position: absolute; z-index: 6; transform: translate(-50%, -50%); pointer-events: none; white-space: nowrap;
  padding: .22em .85em; border-radius: 999px; background: rgba(34,32,28,.82); color: #fff; box-shadow: 0 1px 3px rgba(0,0,0,.2);
  font-weight: 600; line-height: 1.3; letter-spacing: .1px; font-family: 'Source Sans 3', 'Segoe UI', system-ui, -apple-system, Roboto, Arial, sans-serif;
}
html.fpc-sv-on .ed2-scale > .fpc-sv-vcue { pointer-events: auto; cursor: pointer; }
html.fpc-sv-on .ed2-scale > .fpc-sv-vcue:hover { background: rgba(154,70,16,.95); }
/* the phone shows one card: with the front up, the back card is only faded out (§15b), and the cue — outside the page —
   would show at the screen's edge. It goes with its card. */
@media (max-width: 899px) {
  html.fpc-sv-on #easelMount[data-sv-side="front"] .ed2-scale > .fpc-sv-vcue { opacity: 0; pointer-events: none; }
}

/* ── §14h rev 34 (2026-09-28): the Your-photo family in the full easel ─────────────────────────────────
   data-fpc-family="1" (easel-mount.js famMark, the family's side on a 'Your photo' look): the "Step-by-step form"
   ripcord is gone — the wizard is the thing these looks replace, and the way back is "← Simple view" beside Continue
   (svInstallBack keeps it there at every width for the family); the FRONT's "Full size photo" is gone — the window is
   the full-size photo, and on the laminated card it carries the bleed a Full size photo does not (ruling 79). The
   back's stays (a photo on the back is a legitimate use). */
#easelMount[data-fpc-family="1"] .fpc-ripcord { display: none !important; }
#easelMount[data-fpc-family="1"] .ed2-fullphoto[data-page="0"] { display: none !important; }

/* ── §15i rev 35 (2026-09-28): where the words sit; the 8-Up's printed edge; the cue in the clear ─────────────
   1. The simple view's pills (easel-mount.js famRowsHtml / famPaint) under 3 · Dates (the Name & dates box) and
      4 · Heading on a Your-photo look: Where Top · Middle · Bottom · Off, Band Frosted · Dark · Cream · None, Words
      Dark · White. The verse chips' look (§15d), a label in front of each row; the pressed pill is the dark one.
      Every row is display:flex, so the mount's hidden attribute needs a rule (the UA's [hidden] loses to a class). */
.fpc-sv-panel .fpc-sv-fam { display: flex; flex-direction: column; gap: 6px; margin-top: 4px; }
.fpc-sv-panel .fpc-sv-fam[hidden], .fpc-sv-panel .fpc-sv-famrow[hidden] { display: none !important; }
.fpc-sv-panel .fpc-sv-famcap { font-size: 14px; font-weight: 600; color: #4a453e; margin-top: 2px; }
.fpc-sv-panel .fpc-sv-famrow { display: flex; align-items: center; gap: 8px; }
.fpc-sv-panel .fpc-sv-famlbl { flex: 0 0 46px; font-size: 13px; color: #5f5a52; }
.fpc-sv-panel .fpc-sv-seg { display: flex; flex-wrap: wrap; gap: 6px; }
.fpc-sv-panel .fpc-sv-seg button {
  min-height: 32px; padding: 0 11px; border: 1px solid #cfc6b6; border-radius: 999px; background: #fff; color: #22201c;
  font: 600 13px var(--fpc-sv-font); cursor: pointer;
}
.fpc-sv-panel .fpc-sv-seg button:hover { border-color: #9d9383; }
.fpc-sv-panel .fpc-sv-seg button[aria-pressed="true"] { background: #22201c; border-color: #22201c; color: #fff; cursor: default; }
.fpc-sv-panel .fpc-sv-seg button:focus-visible { outline: 3px solid #F47920; outline-offset: 2px; }
@media (max-width: 899px) {   /* the phone: the label above its row, so four pills sit on one line at a thumb's size */
  .fpc-sv-panel .fpc-sv-fam { gap: 10px; }
  .fpc-sv-panel .fpc-sv-famrow { flex-direction: column; align-items: flex-start; gap: 5px; }
  .fpc-sv-panel .fpc-sv-seg button { min-height: 40px; padding: 0 14px; font-size: 15px; }
  .fpc-sv-panel .fpc-sv-famlbl { flex-basis: auto; font-size: 14px; }
}
/* 2. The 8-Up prints a thin white edge round every card (lib/generate-8up.js EASEL_EDGE = the 4 pt this line is drawn
      at). The simple view hides the guide (§15) — on the 8-Up the LINE stays, because it is the card's printed edge
      (owner: "on these easels it is OK to show the dotted line ... and then color and designs beyond"); its pill and
      tooltip do not (the caption under the cards says it in words). The laminated card is die-cut with the bleed
      beyond the page — nothing to show. */
html.fpc-sv-on #easelMount[data-surface="8up"] .ed2-safezone { display: block !important; }
html.fpc-sv-on #easelMount[data-surface="8up"] .ed2-safezone::before,
html.fpc-sv-on #easelMount[data-surface="8up"] .ed2-safezone::after { display: none !important; }
.fpc-sv-under .fpc-sv-edge { margin: -10px 0 0; max-width: 560px; text-align: center; font-size: 13px; line-height: 1.35; color: #5f5a52; }
@media (max-width: 899px) { .fpc-sv-under .fpc-sv-edge { margin: -4px 20px 0; font-size: 13px; } }
/* 4. rev 37 (2026-09-29): the full easel is staff's. On a customer's page (routes/easel.js wrote __EASEL_FULL__ off; the
      mount sets html.fpc-full-off) the panel's "Want to move things…? More design tools" section is gone — the simple
      view is the whole product. Staff (the token) and EASEL_FULL=all keep it. */
html.fpc-full-off .fpc-sv-panel .fpc-sv-more { display: none !important; }
/* 5. rev 38 (2026-09-29): the back is three choices on a Your-photo look — the pills row under "5 · The back" and, for
      Formal, the classic wizard's fields (easel-mount.js fbBuildHtml / fbPaint): a heading menu, checkboxes for the
      cross / no name / service / interment / the funeral home line, the dates' two pills, and the text fields in groups
      that fold away with their checkbox. The look of the front's own pills and fields (§15, §15i.1). */
.fpc-sv-panel .fpc-sv-backpills[hidden], .fpc-sv-panel .fpc-sv-fb[hidden], .fpc-sv-panel .fpc-sv-fbgrp[hidden] { display: none !important; }
.fpc-sv-panel .fpc-sv-backpills { margin-bottom: 2px; }
.fpc-sv-panel .fpc-sv-fb { display: flex; flex-direction: column; gap: 8px; padding: 10px 12px 12px; border: 1px solid #e4ded3; border-radius: 8px; background: #faf8f4; }
.fpc-sv-panel .fpc-sv-fb .fpc-sv-sub { margin-top: 2px; }
.fpc-sv-panel .fpc-sv-chk { display: flex; align-items: center; gap: 8px; font-size: 15px; color: #22201c; cursor: pointer; min-height: 28px; }
.fpc-sv-panel .fpc-sv-chk input { width: 18px; height: 18px; margin: 0; accent-color: #B85410; cursor: pointer; }
.fpc-sv-panel .fpc-sv-chk--grp { margin-top: 4px; font-weight: 600; }
.fpc-sv-panel .fpc-sv-fbgrp { display: flex; flex-direction: column; gap: 8px; padding-left: 26px; }
.fpc-sv-panel .fpc-sv-fb .fpc-sv-dates { gap: 8px; }
@media (max-width: 899px) { .fpc-sv-panel .fpc-sv-fbgrp { padding-left: 0; } }
/* 6. rev 40 (2026-09-30): their own words are written in the section (the box moved out of the verse sheet — owner
      9/29: "just give you that box right there on that same page"); the formal back's "A different one" photo row. */
.fpc-sv-panel .fpc-sv-sec > .fpc-sv-ownbox { margin: 2px 0 10px; }
.fpc-sv-panel .fpc-sv-sec > .fpc-sv-ownbox[hidden] { display: none !important; }
.fpc-sv-panel .fpc-sv-fbown { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.fpc-sv-panel .fpc-sv-fbown[hidden] { display: none !important; }
/* 7. rev 41 (2026-09-30): THE CLASSIC BACK — html.fpc-back-only (easel-mount.js BACK_ONLY: ?template=classic-back). The
      laminated wizard's design grid is the front and prints as today; the simple view here is the BACK alone, so the
      parts that only mean something with a front the family makes are left out: the Photo section (the front is the
      design's own art), the Verse · Formal · Own pills (the classic formal back is the product — rev 50 brings back Verse ·
      Formal, §15i.9; the own-words pill stays out), "The one on the front"
      (there is no front photo — the photo is chosen here), the note that the name and dates come from the front (they
      are typed right above), the Switch design strip and the library (the design is the wizard's), More design tools.
      The front card stays on the page as a picture of the card they chose — nothing on it takes a click. */
html.fpc-back-only .fpc-sv-panel [data-sv="photo-sec"], html.fpc-back-only .fpc-sv-panel .fpc-sv-backpills [data-v="own"],
html.fpc-back-only .fpc-sv-panel [data-fb-row="psrc"], html.fpc-back-only .fpc-sv-panel [data-fb-help="front"],
html.fpc-back-only .fpc-sv-under .fpc-sv-switch, html.fpc-back-only .fpc-sv-panel .fpc-sv-more { display: none !important; }
html.fpc-back-only.fpc-sv-on #easelMount .ed2-page[data-page="0"] .ed2-item { pointer-events: none !important; }
/* rev 42: on the 8-Up the dotted printed-edge line (§15i.2) is the easel's own white edge — true of the back it draws,
   not of a catalog front, which prints the sheet's own art and border to the cut. The front's line goes. */
html.fpc-back-only.fpc-sv-on #easelMount .ed2-page[data-page="0"] .ed2-safezone { display: none !important; }
/* 8. rev 43 (2026-09-30): THE FRONT IS LOCKED, THE BACK OPENS SUGGESTED (owner 9/30). A picture dragged over the page
      goes to the back's photo (easel-mount.js boPhotoIn), so the back is the card that lights up, never the front. The
      back's sample photo carries the front window's cue — smaller room here (75 pt at most), so it may wrap to two lines
      inside the photo — and the photo takes a click (the chooser). */
html.fpc-back-only #easelMount[data-sv-drop] .ed2-page[data-page="0"] { outline: none; }
html.fpc-back-only #easelMount[data-sv-drop] .ed2-page[data-page="1"] { outline: 3px dashed #B85410; outline-offset: 6px; }
.ed2-item .fpc-sv-cue.fpc-sv-cue--back { white-space: normal; width: max-content; max-width: 94%; text-align: center; bottom: 6%; padding: 2px 6px; line-height: 1.2; }
html.fpc-back-only.fpc-sv-on #easelMount .ed2-page[data-page="1"] .ed2-item.ed2-img { cursor: pointer; }
/* 3. The sample photo's cue on a Your-photo look: "Sample photo — drag or upload yours here", in the third of the window
      that holds no words (the mount picks it: --top, --mid; the default is the foot, §15c). */
.ed2-item .fpc-sv-cue.fpc-sv-cue--top { top: 7%; bottom: auto; }
/* --mid: the mount sets the inline top (just under the top third's words, rev 36); 50% is the fallback */
.ed2-item .fpc-sv-cue.fpc-sv-cue--mid { top: 50%; bottom: auto; }
/* 9. rev 50 (2026-10-01; owner: "the user may want the back to be a verse only. no name, no dates, no heading, no photo" ·
      "on the just your photo … we should also have the option for the user to insert a photo on the back … not … in the
      default … just an option"). The classic back gets the Your-photo look's back row — Verse · Formal (rev 41 left the row
      out; its "Your own words" pill stays out there: the classic back's own words are the rev 48 words row, under either).
      The photo's control is one block (easel-mount.js .fpc-sv-bph, fbPhPlace): in the formal box on a Formal back, where
      rev 39 put it — laid out as its rows were (a column, the box's 8 px gap) — and at the foot of the back's section on
      a Verse back, unticked until the family wants it. While its photo is on, a Your-photo look's back card is the drop
      target (data-sv-drop="back"), as the classic back's always is (§15i.8). */
.fpc-sv-panel .fpc-sv-bph { display: flex; flex-direction: column; gap: 8px; }
.fpc-sv-panel .fpc-sv-bph[hidden] { display: none !important; }
.fpc-sv-panel .fpc-sv-bph-home:empty, .fpc-sv-panel .fpc-sv-bph-home[hidden] { display: none; }
.fpc-sv-panel .fpc-sv-bph-home > .fpc-sv-bph { margin-top: 12px; padding-top: 10px; border-top: 1px solid #e4ded3; }
.fpc-sv-panel .fpc-sv-bph-home > .fpc-sv-bph > .fpc-sv-chk--grp { margin-top: 0; }
#easelMount[data-sv-drop="back"] .ed2-page[data-page="0"] { outline: none; }
#easelMount[data-sv-drop="back"] .ed2-page[data-page="1"] { outline: 3px dashed #B85410; outline-offset: 6px; }
