/* The app at app.shaunmoon.com.au: design A's Night glass (smp.css) plus the few things only the panel has.
   Prefix .pn-, for panel.

   IT WAS .ad-, FOR ADMIN, AND THAT MADE THE WHOLE PANEL INVISIBLE (23 Sep 2026). The operator signed in and
   got a blank page: every request 200, no error in the console, the markup all there in the DOM - and an ad
   blocker hiding every element whose class began "ad-", because to a blocker that reads as advert. Proved in
   their own browser: a fresh <div class="ad-bar"> computed to display: none, and the same div renamed
   computed to block. Nothing here may go back to a prefix a blocker reaches for: ad, ads, advert, banner,
   sponsor, promo.

   Phone first; 760 px and up two columns. One web font, the website's own Helvetica Neue Light for the display face
   (smp.css declares it and sets --font-display, 16 Oct 2026); the words are the device's own. */

/* THREE TONES FOR A STATE (1 Oct 2026, the overnight audit's F17: "Share the desk's three tones as tokens and keep
   figures plain"). Good, warning and bad, each as its words (--st-good), a fill behind them (-bg) and an edge (-line),
   in both themes. The values are the desk's own, which it measured to 4.5:1 or better on 24 Sep 2026; the desk now
   reads its --dk-good, --dk-warn and --dk-bad from these, so the Studio and the desk say a state in one set of
   colours. A rule that means good, warning or bad uses these and never a colour of its own. A figure never takes
   one: it reads plain, and its state is a chip beside it, as the desk shows a state. */
:root[data-app] {
  --st-good: #9ad8a3;
  --st-good-bg: rgba(127,201,138,.14);
  --st-good-line: rgba(127,201,138,.45);
  --st-warn: #f0c27a;
  --st-warn-bg: rgba(240,176,74,.15);
  --st-warn-line: rgba(240,176,74,.45);
  --st-bad: #ffb9a6;
  --st-bad-bg: rgba(240,120,90,.15);
  --st-bad-line: rgba(240,120,90,.5);
}
:root[data-app][data-theme="light"] {
  --st-good: #33592f;
  --st-good-bg: rgba(92,140,72,.13);
  --st-good-line: rgba(92,140,72,.45);
  --st-warn: #6e4600;
  --st-warn-bg: rgba(240,176,74,.22);
  --st-warn-line: rgba(176,120,20,.45);
  --st-bad: #8c2f12;
  --st-bad-bg: rgba(180,60,30,.09);
  --st-bad-line: rgba(180,60,30,.4);
}
/* a surface that is dark in both themes (the upload dock, the booth's live picture, a label on a photo) says its state
   in dark's tones in both */
:root[data-app][data-theme="light"] :is(.pn-dock, .pn-rear-live, .pn-cover) {
  --st-good: #9ad8a3;
  --st-good-bg: rgba(127,201,138,.14);
  --st-good-line: rgba(127,201,138,.45);
  --st-warn: #f0c27a;
  --st-warn-bg: rgba(240,176,74,.15);
  --st-warn-line: rgba(240,176,74,.45);
  --st-bad: #ffb9a6;
  --st-bad-bg: rgba(240,120,90,.15);
  --st-bad-line: rgba(240,120,90,.5);
}
/* and so does the ink bar (2 Nov 2026, the operator: go A), so a message on it stays readable in light */
:root[data-app][data-theme="light"] :is(.pn-inkbar, .pn-spbar, .pn-jbsheet .pn-jbstepacts) {
  --st-good: #9ad8a3;
  --st-warn: #f0c27a;
  --st-bad: #ffb9a6;
}
/* EACH PLATFORM ITS OWN COLOUR (the operator's report 148, 8 Oct 2026, of the Messages list on an iPhone: "Colour the
   badges between fb ig"). A message's platform said in a chip is a tint of the platform's own colour: Instagram its
   magenta, Facebook its blue, each as its words (--plat-ig), a fill behind them (-bg) and an edge (-line), for dark and
   for light. Messages' list (.pn-badge.pn-ig, .pn-fb, below) and the desk's To do (desk/assets/app.css .dk-chip.dk-ig,
   .dk-fb) read these, so one platform is one colour everywhere. Every pair measured 8 Oct 2026 on its theme's page
   ground and card face, the fill laid over each: light 6.1:1 Instagram and 5.8:1 Facebook at the least, dark 7.5:1 and
   7.8:1, where a chip's 11px words need 4.5:1. A platform is a kind, never a state, so none of the --st- tones. */
:root[data-app] {
  --plat-ig: #f4a8d8;
  --plat-ig-bg: rgba(193,53,132,.18);
  --plat-ig-line: rgba(193,53,132,.55);
  --plat-fb: #a6c8ff;
  --plat-fb-bg: rgba(24,119,242,.18);
  --plat-fb-line: rgba(24,119,242,.55);
}
:root[data-app][data-theme="light"] {
  --plat-ig: #8e1a66;
  --plat-ig-bg: rgba(193,53,132,.1);
  --plat-ig-line: rgba(193,53,132,.38);
  --plat-fb: #15509c;
  --plat-fb-bg: rgba(24,119,242,.1);
  --plat-fb-line: rgba(24,119,242,.38);
}

/* ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE STUDIO'S LOOK: CALCULATOR CARDS (2 Nov 2026, the operator: "redesign the entire studio to match the
   website/calculator style", "keep QoL changes i requested", then of five options "go A"). The price calculator carried
   into the Studio: white cards with the calculator's soft shadow on a warm paper ground, small spaced capitals heading
   every card, the yellow tag on what matters, the ink bar with the yellow button where a page or a sheet has one main
   action, the picked side item a soft fill in a 1.5px ink ring, square corners, and a matching dark: an ink ground,
   warm dark cards, the yellow accent. Fixed copies of the website's colours (site.css), never its live --ws-c-* values.
   Every later rule names these roles, never a colour:
     (the ground, the faces, the ink and the line keep their homes in the light block and in DARK, CLEAN, below)
     --pn-r          the one corner, 0 (smp.css sets it too, for its own rules); round only what is round by nature: a
                     dot, a count circle, an avatar, a switch, a radio, the moon, the signed seal, an album's tick
     --pn-ground     the page            --pn-face     a card            --pn-face-2   a menu, a toast, a list over the page
     --pn-ink        words               --pn-muted    a line under a heading, 4.5:1 on the ground and the card
     --pn-line       a hairline          --pn-edge     a field's edge (3:1)          --pn-hover    a row under the mouse
     --pn-soft       a picked row's wash --pn-sh       a card's hairline ring --pn-sh-sel   picked: a 1.5px ink ring
     --pn-y          the yellow          --pn-on-y     words on it                   --pn-y-press  the yellow pressed
     --pn-inkbar     the ink bar         --pn-on-inkbar  words on it                 --pn-head     the header (dark in both)
   ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
:root[data-app] {
  --pn-r: 0;
  --font-text: "Archivo", "Archivo Fallback", system-ui, sans-serif;
  --pn-y: #f4ff6a; --pn-on-y: #241f19; --pn-y-press: #dbe460;
  --pn-head: #241f19; --pn-on-head: #f2efe8;
  --pn-inkbar: #0f0d0a; --pn-on-inkbar: #f2efe8;
  --pn-ink: #f2efe8; --pn-muted: #a4a099; --pn-edge: #817d76; --pn-hover: rgba(242,239,232,.08); --pn-soft: rgba(244,255,106,.1);
  /* NO DROP SHADOWS (2 Nov 2026, the operator: "Remove all drop shadows globally"): a card's 'shadow' is its 1px
     hairline ring alone, in both themes; where a comment below still says shadow, read the ring */
  --pn-sh: inset 0 0 0 1px #3d3832;
  --pn-sh-sel: inset 0 0 0 1.5px var(--pn-ink), var(--pn-sh);
}
:root[data-app][data-theme="light"] {
  --pn-inkbar: #241f19;
  --pn-face-2: #fff;
  --pn-muted: #595550; --pn-edge: #928f8c; --pn-hover: #f2f2f1; --pn-soft: #fafbe6;
  --pn-sh: inset 0 0 0 1px var(--pn-line);
}
/* THE SPACED LABEL, THE YELLOW TAG AND THE INK BAR, for any page to use: a card's small capitals (11px, 500, .16em), a
   count or a day beside a heading on the yellow (the calculator's .sc-mark), and the foot of a page or a sheet with its
   one main action, the yellow button on the ink */
.pn-lab { font-family: var(--font-text); font-size: 11px; font-weight: 500; line-height: 1.45; letter-spacing: .16em; text-transform: uppercase; }
.pn-ytag { display: inline-flex; align-items: center; padding: 1px 7px; border-radius: var(--pn-r); background: var(--pn-y); color: var(--pn-on-y);
  font-size: 12px; font-weight: 500; line-height: 1.5; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pn-ytag[hidden] { display: none; }
.pn-inkbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px 12px; padding: 12px 20px;
  background: var(--pn-inkbar); color: var(--pn-on-inkbar); font-size: 13px; }
.pn-inkbar[hidden] { display: none; }
/* the bar's presses, written above both themes' main and line buttons in a page or a sheet (:root[data-theme] and the
   bar's own class), so on the ink the main one is always the yellow, a line button the bar's words with a pale edge, an
   off one grey on the ink, and the keyboard's ring the yellow. The same rules dress the bars that keep their own class:
   Photos on the site's foot (.pn-spbar, Cancel its .pn-spghost) and a job's stepped sheet (.pn-jbstepacts) */
:root[data-app][data-theme] :is(.pn-inkbar, .pn-spbar, .pn-jbsheet .pn-jbstepacts) { background: var(--pn-inkbar); color: var(--pn-on-inkbar); }
:root[data-app][data-theme] :is(.pn-inkbar, .pn-spbar, .pn-jbsheet .pn-jbstepacts) .wa-btn:not(.pn-spghost) { background: var(--pn-y); color: var(--pn-on-y); border: 1px solid var(--pn-y); }
:root[data-app][data-theme] :is(.pn-inkbar, .pn-spbar, .pn-jbsheet .pn-jbstepacts) .wa-btn:not(.pn-spghost):disabled { background: rgba(242,239,232,.14); border-color: transparent; color: rgba(242,239,232,.6); }
:root[data-app][data-theme] :is(.pn-inkbar, .pn-spbar, .pn-jbsheet .pn-jbstepacts) :is(.wa-gl, .wa-btn.pn-spghost) { background: transparent; border: 1px solid rgba(242,239,232,.38); color: var(--pn-on-inkbar); box-shadow: none; }
@media (hover: hover) {
  :root[data-app][data-theme] :is(.pn-inkbar, .pn-spbar, .pn-jbsheet .pn-jbstepacts) .wa-btn:not(.pn-spghost):not(:disabled):hover { background: var(--pn-y-press); filter: none; }
  :root[data-app][data-theme] :is(.pn-inkbar, .pn-spbar, .pn-jbsheet .pn-jbstepacts) :is(.wa-gl, .wa-btn.pn-spghost):not(:disabled):hover { background: rgba(242,239,232,.1); }
}
:root[data-app][data-theme] :is(.pn-inkbar, .pn-spbar, .pn-jbsheet .pn-jbstepacts) :focus-visible { outline-color: var(--pn-y); }

.pn-wrap { position: relative; z-index: 1; max-width: none; margin: 0 auto; padding: 14px 16px 40px; padding-left: max(16px, env(safe-area-inset-left)); padding-right: max(16px, env(safe-area-inset-right)); }
/* EVERY PAGE AS WIDE AS THE WINDOW (report 92, 2 Oct 2026: "check all pages so they extend to width of page and check
   pages consistency"): no cap on the page, so its cards fill the width beside its side menu, or the window's where it
   has none, as People's always did. The desk keeps its own column (CLAUDE.md: the desk keeps its own layout). */
.pn-wrap.dk { max-width: 1040px; }
/* THE HEADER PINNED TO THE TOP (the operator, 10 Oct 2026, of the light Studio on his iPhone: "Can you not make the
   safari header same colour as the site header"): Safari on iOS 26 no longer reads theme-color; it tints its bar from
   the page's background, or from a header fixed to the top of the screen, and a sticky one does not count. So the
   header is fixed, as the website's is, and the page keeps its room under it: body's padding is --pn-bar-sp, the
   header's height while it is fixed (frame.js barRoom), else 0, as on a short phone, whose header scrolls away. */
body { padding-top: var(--pn-bar-sp, 0px); }
/* NOTHING TO SCROLL ON A SHORT PAGE (3 Nov 2026, the operator: "scrolling when there's no elements past the page"): the
   page fills the window UNDER the header, never the window and the header too. The page's least height was the whole
   window (smp.css .wa-pg, 100dvh) below body's room for the header, so every short page scrolled by the header's height
   (135px on a phone, 87px on a computer) into nothing; and body's own least height was 100vh, which in Safari on an
   iPhone is the screen with its bars folded away, so a short page also scrolled by the bars. Both now end at the window
   as it is shown (dvh), the page's less the header's room. app-scroll.test.mjs holds it. */
:root[data-app] body { min-height: 100vh; min-height: 100dvh; }
:root[data-app] .wa-pg { min-height: calc(100vh - var(--pn-bar-sp, 0px)); min-height: calc(100dvh - var(--pn-bar-sp, 0px)); }
/* NO BLUR ON THE HEADER (10 Oct 2026, the same report): a backdrop-filter on it is a WebKit bug's trigger, and Safari
   then stops reading the bar for its tint (bleedblend's notes); the header is solid dark in both themes anyway */
.pn-bar { position: fixed; top: 0; left: 0; right: 0; z-index: 10; background: #241f19; border-bottom: 1px solid var(--ng-line); }
/* TWO TIERS (operator, 24 Sep 2026): what is yours up top beside the logo, what is the work in the row under it. */
.pn-bar-in { display: grid; gap: 8px; max-width: none; margin: 0 auto; padding: 18px 16px 17px; }
.pn-top { display: flex; align-items: center; gap: 10px; min-height: 32px; min-width: 0; }
.pn-spacer { flex: 1 1 auto; }
/* Account and Sign out are not pages and do not sit in the track with them: quiet text, off to the right. */
.pn-link {
  padding: 8px 2px;
  border: 0;
  background: none;
  color: rgba(242,239,232,.55);
  font: inherit;
  font-size: 12.5px;
  text-decoration: none;
  cursor: pointer;
  white-space: nowrap;
}
@media (hover: hover) { .pn-link:hover { color: #f2efe8; } }
.pn-link[aria-current="page"] { color: var(--beige); }
/* THE TOP ROW IS GLYPHS (24 Sep 2026): square targets, the same quiet ink as the words they replaced, and big
   enough for a thumb on a touch screen where they sit a few pixels from the logo. */
.pn-icon { display: inline-flex; align-items: center; justify-content: center; width: 34px; height: 34px; padding: 0; border-radius: var(--pn-r); }
@media (hover: hover) { .pn-icon:hover { background: rgba(255,255,255,.08); } }
.pn-gl { width: 19px; height: 19px; display: block; }
@media (pointer: coarse) { .pn-icon { width: 44px; height: 44px; } }
/* the header's logo has its size at every width below (report 80, 2 Oct 2026): 104 by 33 at the least, 184 by 58 at the most */
.pn-tag { font-size: 10.5px; letter-spacing: .18em; text-transform: uppercase; color: var(--moon); }
/* HEADER D (the operator, 25 Sep 2026: "this looks ugly", then "go D for header", from five options on the redesign
   artifact). The dark band stays in both themes, so the logo keeps its ground. What went is the box around the pages
   and the beige block on the open one: the pages are words on the band, and the open page has a thin moon-yellow line
   under it. The row sits on the band's bottom edge (the negative margin takes back the band's own bottom padding), so
   that line lands where the band ends. */
.pn-nav {
  display: flex;
  gap: 2px;
  /* the row starts under the logo now that it is its own tier, rather than being pushed to the right of one */
  margin-right: auto;
  margin-bottom: -17px;
  flex-wrap: wrap;
}
/* the pages: words on the band, nothing filled; the line under each is drawn by ::after, clear until it is needed */
.pn-nav .wa-pill {
  position: relative;
  height: 40px;
  padding: 0 12px;
  border: 0;
  background: transparent;
  font-size: 12.5px;
  font-weight: 450;
  letter-spacing: .01em;
  text-transform: none;
  color: rgba(242,239,232,.62);
  transition: color 120ms ease;
}
.pn-nav .wa-pill::after {
  content: "";
  position: absolute;
  left: 8px;
  right: 8px;
  bottom: 0;
  height: 1px;
  border-radius: var(--pn-r);
  background: transparent;
  transition: background-color 120ms ease;
}
@media (hover: hover) {
  .pn-nav .wa-pill:hover { background: transparent; color: #f2efe8; }
  .pn-nav .wa-pill:hover::after { background: rgba(242,239,232,.22); }
}
/* THE PAGE YOU ARE ON, whether it is a link or the group's own button: this said `a` until 24 Sep 2026, so
   PHOTOBOOTH was never lit while you were inside it, in either theme. */
.pn-nav [aria-current="page"] {
  background: transparent;
  color: #fff;
  font-weight: 500;
}
/* the open page's line is 1px in the words' own colour, as the website's nav draws it, never yellow (31 Oct 2026: no yellow
   underline anywhere; 2 Nov 2026, the operator: go A) */
.pn-nav [aria-current="page"]::after { background: currentColor; }
@media (hover: hover) {
  .pn-nav [aria-current="page"]:hover { background: transparent; color: #fff; }
  .pn-nav [aria-current="page"]:hover::after { background: currentColor; }
}
/* HOW MANY ARE WAITING, on the tab itself (assets/frame.js; the operator, 25 Sep 2026: "add a notification hub
   where requests feed through and i can action immediately"). A hub nobody can see from the page they are on is a
   hub nobody opens, so the count rides on Requests wherever you are. Nothing waiting draws no badge at all: a nought
   in the track is a thing to read and dismiss on every page, and the absence says the same thing faster.
   The header keeps its dark styling in both themes (the logo needs the ground it was drawn for), so this needs no
   light palette of its own - the track it sits in never changes. Its place here; its colours (a red circle, 26 Sep
   2026) are with the side menu's, under THE COUNT IS A RED CIRCLE. */
.pn-nav .pn-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-left: 7px;
}
/* THE GROUP: one word carrying the pages under it, and the panel it opens. */
.pn-group { position: relative; display: flex; }
.pn-groupbtn { gap: 7px; }
.pn-caret { width: 11px; height: 8px; opacity: .8; }
.pn-groupbtn[aria-expanded="true"] .pn-caret { transform: rotate(180deg); }
.pn-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 20;
  min-width: 200px;
  display: grid;
  gap: 2px;
  padding: 6px;
  border-radius: var(--pn-r);
  border: 1px solid rgba(255,255,255,.1);
  background: rgba(24,20,17,.96);
  backdrop-filter: var(--ng-blur);
  -webkit-backdrop-filter: var(--ng-blur);
  box-shadow: none;
}
.pn-menu[hidden], .pn-row[hidden], [data-mypinform][hidden] { display: none; }
.pn-menuitem {
  display: flex;
  align-items: center;
  min-height: 40px;
  padding: 0 12px;
  border-radius: var(--pn-r);
  color: rgba(242,239,232,.78);
  font-size: 14px;
  text-decoration: none;
  white-space: nowrap;
}
@media (hover: hover) { .pn-menuitem:hover { background: rgba(255,255,255,.08); color: #f2efe8; } }
.pn-menuitem[aria-current="page"] { background: var(--beige); color: #221d18; font-weight: 500; }
@media (pointer: coarse) { .pn-menuitem { min-height: 46px; } }
@media (prefers-reduced-motion: reduce) { .pn-nav .wa-pill, .pn-nav .wa-pill::after { transition: none; } }
/* LIGHT AND DARK has no transition since 18 Oct 2026 (Problem report 220: "get rid of the transition effect"; frame.js S.toggleTheme) */
/* THE ROW'S GLYPHS (the operator, 25 Sep 2026: "Add glyphs to top banner menus"): the same one-stroke hand as the
   Account and Sign out glyphs, a little smaller than the words' height so the words still lead, in the words' own
   colour so a lit tab lights its glyph with it */
.pn-nav .pn-navgl { width: 15px; height: 15px; flex: none; margin-right: 6px; }
.pn-menuitem .pn-navgl { width: 16px; height: 16px; flex: none; margin-right: 9px; opacity: .85; }
.pn-menuitem[aria-current="page"] .pn-navgl { opacity: 1; }
/* a count inside a menu item sits at its far end, clear of the name */
.pn-menuitem .pn-count { margin-left: auto; }
/* on a phone the row is tight: the glyph closes up so four tabs still fit two to a line at worst */
@media (max-width: 420px) { .pn-nav .pn-navgl { margin-right: 4px; width: 14px; height: 14px; } }

/* ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE STUDIO'S ORDER: ONE LOOK A LEVEL (1 Oct 2026, report 30, option B, "Your pills, kept and made the rule"; the
   operator: "Design guide needs to be more consistent and set out. For headers, menus, sub menus sub sub menus etc,
   dividers"). It keeps the two looks already picked, the places track in small spaced capitals and the desk's view
   pills (26 Sep), and makes them the rule. Every heading, menu and line on a Studio page takes its look from here, in
   both themes, from the tokens below. A rule further down may place one (its margin, a glyph beside it, a count) but
   never gives it another size, weight, case, spacing or colour. test/studio-levels.test.mjs holds these values and
   refuses a rule anywhere else that restyles a level.

   HEADINGS. The class (or where it sits) is the level; the tag is only the page's outline.
     1 PAGE     .pn-h, a sheet's heading (.pn-sheet h2)                22px, 300, sentence case, -.01em, ink, in the
                                                                       display face (Helvetica Neue Light since 16 Oct
                                                                       2026; CAPITALS at .14em before), wrapped in
                                                                       even lines
     2 CARD     .pn-hk, a card's heading (.pn-card h2, > h3), a        11px, 500, CAPITALS, .16em, beige on dark,
                group of cards' heading (.pn-hk.pn-hgroup), a side      ink on paper (go A,
                menu's group (.pn-sidek), and the card-level strays  2 Nov 2026)
                pointed here (Settings' groups, the changelog's days,
                a connection's and a price's small headings)
     3 SECTION  .pn-hs, a section inside a card, a card that is one    15px, 600, sentence case, no spacing, ink
                person or thing (its name), a fold's name, one
                gallery's own sections and its name in its bar
     4 LABEL    .pn-hl, a field's name (.pn-form label), a legend      12px, 400, sentence case, no spacing, soft ink
   MENUS
     1 MENU     .pn-nav, the header's row on the dark band: unchanged
     2 PLACES   a part's places: down the side on a computer (.pn-side), and on a phone the dropdown (.pn-plcs): one
                button the column's width with the open place's glyph and name, opening the app's own list (.pn-ddmenu)
                of every place with the side menu's glyphs, the open one ticked (2 Oct 2026, report 71: "make this into
                a drop with glyphs, for other pages too on smaller displays"; the segmented track in small spaced
                capitals before it); one gallery's own places (.pn-gsidetabs) too
     3 TABS     a page's own tabs and every pick-one row (.pn-pills > .pn-pill, and .pn-gtabs > .pn-gtab): the desk's
                view pills, 12px sentence case in a hairline edge, the open one filled dark (beige on dark), no track
                round them; 32px, 44px to a thumb. The desk's own views keep their track (unchanged, the pick of 26 Sep).
     A FILTER that narrows a list is the dropdown (.pn-glfilter), one size everywhere (ONE FILTER, below).
   DIVIDERS. One line, 1px solid var(--pn-line). 28px of room between a page's sections, where a group's heading
   (level 2) starts the next; 14px between cards; inside a card the line goes between a list's rows and over a
   section that follows something else.
   Each level is written as :root[data-app] :where(...), one weight for all of them, so the later level wins where two
   could (a card that is one person is level 3, not 2), and a page with a look of its own (the desk) keeps its own rules.
   ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
/* a picked pill wears the theme's main fill: the ink on paper, the yellow with ink words on the dark ground, as the
   website's main button does (2 Nov 2026, the operator: go A; it was the beige in dark) */
:root[data-app] {
  --pn-t-ink: #f7f2ea; --pn-t-kick: var(--beige); --pn-t-soft: rgba(242,239,232,.62);
  --pn-p-line: rgba(255,255,255,.14); --pn-p-hover: rgba(255,255,255,.07); --pn-p-on: var(--pn-y); --pn-p-onink: var(--pn-on-y);
}
:root[data-app][data-theme="light"] {
  --pn-t-ink: #241f19; --pn-t-kick: #241f19; --pn-t-soft: rgba(36,31,25,.66);
  --pn-p-line: rgba(36,31,25,.14); --pn-p-hover: rgba(36,31,25,.06); --pn-p-on: #241f19; --pn-p-onink: #f7f3ec;
}
/* HEADINGS 1: PAGE (where it sits is its own rule's: the page's 22px above, a sheet's none, .pn-sheet h2 below) */
.pn-h { margin: 22px 0 6px; overflow-wrap: anywhere; }
:root[data-app] :where(.pn-h, .pn-sheet h2) { font-family: var(--font-display); font-size: 22px; font-weight: 300; line-height: 1.25;
  letter-spacing: -.01em; text-transform: none; color: var(--pn-t-ink); opacity: 1; text-wrap: balance; }
/* HEADINGS 2: CARD */
:root[data-app] :where(.pn-hk, .pn-card h2, .pn-card > h3, .pn-jbpane .pn-card h3, .pn-sidek, .pn-setgh, .pn-chgdh, .pn-bizh, .cn-h3, .mn-h3, .pr-h3, .pn-psetsh, .pn-covk,
  .pn-ewk, .pn-wsgh, .pn-ws h3:not(.pn-jbfh), .pn-wspanelsheet h3, .pn-wsvh, .pn-rpk, .pn-rear-card h3) {
  font-family: var(--font-text); font-size: 11px; font-weight: 500; line-height: 1.45; letter-spacing: .16em; text-transform: uppercase;
  color: var(--pn-t-kick); opacity: 1; }
.pn-card > h3, :where(h2, h3, h4, p).pn-hk { margin: 0 0 10px; }
/* a group of cards' heading, between sections of a page: the room above it is the divider */
.pn-hk.pn-hgroup { margin: 28px 0 10px; }
/* HEADINGS 3: SECTION (after the card's, so a card that is one person or thing is named at this level) */
:root[data-app] :where(.pn-hs, .pn-phcard h2, .pn-rpitemh h2, .pn-chghead, .pn-wmh, .pn-jbfname,
  .pn-gmain :is(.pn-pmtitle, .pn-gsetpane, .pn-dahead) h2) {
  font-family: var(--font-text); font-size: 15px; font-weight: 600; line-height: 1.35; letter-spacing: 0; text-transform: none; color: var(--pn-t-ink);
  opacity: 1; }
:where(h2, h3, h4).pn-hs { margin: 0 0 6px; }
/* HEADINGS 4: LABEL */
:root[data-app] :where(.pn-hl, .pn-form label, .pn-wsfield) { font-family: var(--font-text); font-size: 12px; font-weight: 400; line-height: 1.5;
  letter-spacing: normal; text-transform: none; color: var(--pn-t-soft); }
:where(h3, h4, h5, legend).pn-hl { margin: 12px 0 6px; padding: 0; }
/* MENUS 3: a page's tabs and a pick-one row, the desk's pills */
:is(.pn-pills, .pn-gtabs) { display: flex; flex-wrap: wrap; gap: 6px; width: auto; max-width: 100%; margin-top: 14px; padding: 0; border: 0; border-radius: 0;
  background: none; box-shadow: none; }
:root[data-app] :is(.pn-pill, .pn-gtab) { display: inline-flex; align-items: center; justify-content: center; gap: 6px; height: var(--pn-h-act); min-height: 0; padding: 0 10px;
  border: 1px solid var(--pn-p-line); border-radius: var(--pn-r); background: none; box-shadow: none; color: var(--pn-t-soft); cursor: pointer;
  font-family: var(--font-text); font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none; white-space: nowrap; text-decoration: none; opacity: 1; }
:root[data-app] :is(.pn-pill, .pn-gtab):is([aria-pressed="true"], [aria-selected="true"], [aria-current="page"]) { background: var(--pn-p-on); border-color: var(--pn-p-on);
  color: var(--pn-p-onink); font-weight: 500; }
@media (hover: hover) {
  :root[data-app] :is(.pn-pill, .pn-gtab):not([aria-pressed="true"]):not([aria-selected="true"]):not([aria-current="page"]):not(:disabled):not([aria-disabled="true"]):hover {
    background: var(--pn-p-hover); color: var(--pn-t-ink); }
}
/* a pill that cannot be pressed (a pager's Previous on the first page) is at half strength and never lights up, as every
   button is (smp.css, OFF IS ONE LOOK); one weight with the pill's own rule, so the desk's own off look still wins there.
   A hidden pill is gone: the pill's display outranks the browser's own [hidden] (the review, 15 Oct 2026) */
:root[data-app] :is(.pn-pill, .pn-gtab):where(:disabled, [aria-disabled="true"]) { opacity: .5; cursor: default; }
:root[data-app] :is(.pn-pill, .pn-gtab)[hidden] { display: none; }
:root[data-app] :is(.pn-pill, .pn-gtab):focus-visible { outline: 2px solid var(--pn-t-ink); outline-offset: 2px; }
/* a count inside a pill is the one badge, yellow; on a pill picked in yellow (dark) its figure and ground change places, so it still shows */
:is(.pn-pill, .pn-gtab) :is(b, .pn-pilln) { display: inline-block; box-sizing: border-box; height: 18px; min-width: 18px; padding: 0 5px; border-radius: var(--pn-r);
  font-size: 10.5px; font-weight: 600; letter-spacing: 0; line-height: 18px; text-align: center; font-variant-numeric: tabular-nums;
  background: var(--pn-y); color: var(--pn-on-y); opacity: 1; }
:root[data-app]:not([data-theme="light"]) :is(.pn-pill, .pn-gtab):is([aria-pressed="true"], [aria-selected="true"], [aria-current="page"]) :is(b, .pn-pilln) { background: var(--pn-on-y); color: var(--pn-y); }
/* DIVIDERS: 14px between cards (.pn-grid's own gap, below) */
/* ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════
   END OF THE STUDIO'S ORDER
   ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.pn-sub { margin: 0 0 14px; font-size: 14px; line-height: 1.5; color: rgba(242,239,232,.66); }
.pn-note { margin: 10px 0 0; font-size: 12px; line-height: 1.5; color: rgba(242,239,232,.56); }
/* back: an arrow and where it goes, a quiet link above the page (26 Sep 2026: "going back to the galleries button is not
   very UX friendly") */
.pn-back { display: inline-flex; align-items: center; gap: 8px; min-height: 40px; margin-top: 12px; padding: 0 10px 0 6px; border-radius: var(--pn-r);
  color: inherit; font-size: 14px; font-weight: 500; text-decoration: none; opacity: .8; }
.pn-back .pn-gl { width: 18px; height: 18px; flex: none; }
@media (hover: hover) { .pn-back:hover { opacity: 1; background: rgba(255,255,255,.06); } }
:root[data-app][data-theme="light"] .pn-back:hover { background: var(--pn-fill); }
.pn-card { padding: 16px; margin-top: 14px; }
.pn-card h2 { margin: 0 0 10px; }
/* one column that may shrink to the phone (design audit, 27 Sep 2026): an auto column took the widest card's longest
   word and ran every card off the screen */
.pn-grid { display: grid; grid-template-columns: minmax(0, 1fr); gap: 14px; margin-top: 14px; }
.pn-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pn-row + .pn-row { margin-top: 10px; }

/* a night in the list: its name in the display face, as it is written */
.pn-night { display: grid; gap: 10px; padding: 16px; text-decoration: none; transition: transform .12s ease, border-color .2s ease; }
@media (hover: hover) { .pn-night:hover { transform: translateY(-2px); border-color: rgba(255,255,255,.26); } }
/* AS A CALCULATOR CARD (2 Nov 2026, the operator: go A): a card has no border since go A, so under the mouse it wears
   the picked ring with its lift, in both themes */
@media (hover: hover) { :root[data-app][data-theme] .pn-night:hover { box-shadow: var(--pn-sh-sel); } }
.pn-night b { font-family: var(--font-display); font-weight: 300; font-size: 18px; letter-spacing: -.01em; text-transform: none; overflow-wrap: anywhere;
  text-wrap: balance; }
.pn-when { font-size: 14px; line-height: 1.45; color: rgba(242,239,232,.66); overflow-wrap: anywhere; }
.pn-stats { display: grid; grid-template-columns: repeat(4, minmax(0,1fr)); gap: 6px; }
.pn-stats span { display: grid; gap: 3px; min-width: 0; }
.pn-stats b { font-size: 16px; letter-spacing: 0; text-transform: none; font-variant-numeric: tabular-nums; }
.pn-stats i { font-style: normal; font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: rgba(242,239,232,.52); }
/* FIGURES BIG AND LIGHT (2 Nov 2026, the operator: go A): a night's four in the display face at 300, their names the
   spaced label in the muted words, both themes */
:root[data-app][data-theme] .pn-stats b { font-family: var(--font-display); font-size: 22px; font-weight: 300; line-height: 1.1; letter-spacing: -.01em; }
:root[data-app][data-theme] .pn-stats i { font-size: 10.5px; font-weight: 500; letter-spacing: .14em; color: var(--pn-muted); }
.pn-badge { display: inline-flex; align-items: center; gap: 4px; height: 24px; padding: 0 9px; border-radius: var(--pn-r); font-size: 11px; font-weight: 400; line-height: 1;
  letter-spacing: .12em; text-transform: uppercase;
  background: rgba(244,255,106,.12); color: var(--moon); border: 1px solid rgba(244,255,106,.28); white-space: nowrap; }
.pn-badge .pn-gl { width: 12px; height: 12px; flex: none; }
.pn-badge.pn-off { background: rgba(255,255,255,.07); color: rgba(242,239,232,.7); border-color: rgba(255,255,255,.14); }
.pn-badge.pn-warn { background: var(--st-warn-bg); color: var(--st-warn); border-color: var(--st-warn-line); }
.pn-badge.pn-good { background: var(--st-good-bg); color: var(--st-good); border-color: var(--st-good-line); }
.pn-badge.pn-bad { background: var(--st-bad-bg); color: var(--st-bad); border-color: var(--st-bad-line); }

/* the event page. `.pn-linkbox` holds the link and its QR; it is NOT `.pn-link`, which is the header's
   quiet text link - sharing the name had this grid overriding the glyph buttons' own shape. */
.pn-linkbox { display: grid; grid-template-columns: minmax(0,1fr); gap: 14px; align-items: center; }
/* a link that cannot be changed: a tint with no edge, so it never passes for a box to type in (design audit, 27 Sep
   2026); the edge stays, clear, so it is the same height as before */
.pn-linktext { padding: 11px 13px; border-radius: var(--pn-r); background: rgba(0,0,0,.26); border: 1px solid transparent; font-size: 14px; overflow-wrap: anywhere; user-select: all; }
.pn-qr { display: block; width: 160px; height: 160px; border-radius: var(--pn-r); background: #fff; image-rendering: pixelated; }
/* ONE RED IN THE PANEL. `.pn-qdown` is Take it down on a request row: it is the same irreversible kind of press as
   the ones that already carry this, so it shares the rule rather than mixing a second red beside it. `.pn-jbdel` is
   Delete job, Delete lead and a client's job Delete, which were red words on grey glass (design audit, 27 Sep 2026). */
.pn-danger, .pn-qdown, .pn-jbdel { background: var(--st-bad-bg) !important; border-color: var(--st-bad-line) !important; color: var(--st-bad) !important; }
.pn-tiles { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 12px; margin-top: 14px; }
.pn-tile { display: grid; gap: 8px; min-width: 0; padding: 7px 7px 10px; border-radius: var(--pn-r); }
.pn-tile.pn-dim { opacity: .62; }
.pn-cover { position: relative; display: block; aspect-ratio: 3 / 2; border-radius: var(--pn-r); overflow: hidden; background: rgba(0,0,0,.25); cursor: zoom-in; }
.pn-cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
/* A LABEL ON A PHOTO is a solid dark chip with white words, whatever the page's theme (design audit, 27 Sep 2026): a
   see-through badge let Arriving vanish into a bright picture. The gallery's Cover label is the same chip. */
.pn-cover .pn-badge, .pn-ptcover { position: absolute; left: 6px; height: 24px; padding: 0 9px; border-radius: var(--pn-r); border: 0;
  background: rgba(20,18,16,.62); color: #fff; font-size: 11px; font-weight: 600; letter-spacing: .12em; }
.pn-cover .pn-badge { top: 6px; }
.pn-cover .pn-badge.pn-warn { color: var(--st-warn); }
.pn-tmeta { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; padding: 0 4px; font-size: 12px; color: rgba(242,239,232,.66); }
.pn-tmeta b { font-size: 12px; letter-spacing: .06em; color: #f2efe8; overflow-wrap: anywhere; }
.pn-tacts { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 2px; }
.pn-tacts .wa-pill { height: 32px; padding: 0 10px; font-size: 11px; }

/* lists: booths, uploads, errors, the audit log */
.pn-list { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
.pn-list li { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; padding: 10px 2px; border-top: 1px solid rgba(255,255,255,.08); font-size: 14px; line-height: 1.4; }
.pn-list li:first-child { border-top: 0; }
/* the list's second line: .52 read at 4.18:1 on a card (measured 24 Sep 2026); .62 clears 4.5 */
.pn-list .pn-t { color: rgba(242,239,232,.62); font-size: 12px; font-variant-numeric: tabular-nums; }
.pn-list .pn-m { flex: 1 1 200px; min-width: 0; overflow-wrap: anywhere; }
/* a row that starts with its date keeps the date's width the same on every row, so the words after it form a column
   (design audit, 27 Sep 2026: they started at six places down the audit log); wide enough for "Mon 30 May 2026, 12:59 pm" */
.pn-list li > .pn-t:first-child { flex: none; min-width: 13em; }
/* Activity's uploads, errors and audit log: the date sits on the first line of the words beside it, never centred on a
   row of two lines (UI audit, 30 Sep 2026) */
.pn-actlist li { align-items: baseline; }
/* A LOG'S BOX (29 Sep 2026, report 16: "this and other log type of boxes shouldnt forever scroll"): a list that only
   grows (an audit log, sign-ins, uploads, errors, the downloads, the emails and reminders sent) is held to about nine
   rows and scrolls inside itself, and the page is not pulled along at its ends. Its tab stop (app.js logBox) lets the
   keyboard scroll it. */
.pn-logbox { max-height: min(60vh, 560px); overflow-y: auto; overscroll-behavior: contain; }
.pn-bigcode { margin: 8px 0 4px; font-family: var(--font-display); font-weight: 300; font-size: 34px; letter-spacing: .14em; color: #fff; font-variant-numeric: tabular-nums; }
.pn-codes { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 8px; margin: 10px 0; padding: 0; list-style: none; }
.pn-codes li { padding: 9px 10px; border-radius: var(--pn-r); background: rgba(0,0,0,.28); font-variant-numeric: tabular-nums; font-size: 15px; letter-spacing: .08em; text-align: center; }
/* ON THE CARD AS THE CALCULATOR'S (2 Nov 2026, the operator: go A): a link that cannot be changed and a night's codes are
   the page's ground set into the white card, never a darker box; the code shown once in the page's own ink */
:root[data-app][data-theme] :is(.pn-linktext, .pn-codes li) { background: var(--pn-ground); }
:root[data-app][data-theme] .pn-bigcode { color: var(--pn-ink); }
/* no monospace anywhere (CLAUDE.md): the page's own face, with figures that line up */
.pn-note .pn-secret { font-size: inherit; }
.pn-secret { font-family: inherit; font-variant-numeric: tabular-nums; font-size: 14px; letter-spacing: .06em; overflow-wrap: anywhere; }
/* the desk sync key stays on one line, so a dash in it is never mistaken for a line break; a narrow screen scrolls it sideways */
.pn-secret.pn-deskkey { white-space: nowrap; overflow-wrap: normal; overflow-x: auto; letter-spacing: 0; font-size: clamp(11px, 3.2vw, 14px); }
.pn-form { display: grid; gap: 10px; max-width: 420px; }
/* A FIELD'S NAME is small sentence case over its box, in every form (design audit, 27 Sep 2026): six forms had
   spaced capitals and some twenty had this; the capitals are for headings */
.pn-form label { display: grid; gap: 6px; line-height: 1.5; }
/* one column that may be narrower than what is in it (design audit, 27 Sep 2026): an auto column grew to the six PIN
   squares and to New gallery's link, and the sheet or the page scrolled sideways on a phone */
.pn-form, .pn-form label { grid-template-columns: minmax(0, 1fr); }
/* a form's own button is as wide as its word, as it is in a sheet's row, not the form's full width */
.pn-form > .wa-btn { justify-self: start; }
.pn-msg { min-height: 20px; margin: 4px 0 0; font-size: 14px; line-height: 1.45; color: var(--st-warn); }
/* SIX SQUARES, one digit in each. They share the row, so six of them plus the gaps fit a phone with the page's
   own 16px gutters either side and still have a comfortable tap target; the max-width stops them growing into
   paddles on a desktop. aspect-ratio keeps them square at every width. */
.pn-pins { display: flex; gap: 8px; }
.pn-digit { flex: 1 1 0; min-width: 0; max-width: 56px; aspect-ratio: 1; padding: 0; border-radius: var(--pn-r);
  border: 1px solid rgba(255,255,255,.18); background: rgba(0,0,0,.24); color: #fff; text-align: center;
  font-family: inherit; font-size: 22px; font-variant-numeric: tabular-nums;
  -webkit-appearance: none; appearance: none; }
.pn-digit:focus { outline: none; border-color: rgba(228,216,198,.6); box-shadow: 0 0 0 3px rgba(228,216,198,.14); }
/* a filled square reads as done at a glance, without having to read the digit in it */
.pn-digit:not(:placeholder-shown), .pn-digit:valid { border-color: rgba(255,255,255,.3); }
/* the eye that shows or hides the digits, at the end of the field's own label: open while they are hidden, struck through
   while they show (app.js, eyeSays) */
.pn-pinlab { display: flex; align-items: center; gap: 10px; max-width: 376px; }  /* six squares of 56px and their gaps: the eye sits over the last */
.pn-show { margin-left: auto; display: inline-grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--pn-r);
  background: none; color: rgba(242,239,232,.75); cursor: pointer; }
/* a PIN already set: six dots, or the digits while the eye is open (app.js, pinPeek) */
.pn-pinshow { display: inline-flex; align-items: center; gap: 4px; }
.pn-show:disabled { cursor: progress; }
.pn-pinold { font-size: 12px; }
.pn-list .pn-m .pn-pinshow { margin-top: 4px; }
.pn-pinseen { min-width: 7ch; min-height: 32px; padding: 0 8px; border: 0; border-radius: var(--pn-r); background: none; color: inherit; font: inherit;
  font-size: 14px; font-variant-numeric: tabular-nums; letter-spacing: .16em; cursor: pointer; }
@media (hover: hover) { .pn-pinseen:hover { background: rgba(255,255,255,.07); } }
.pn-show[aria-pressed="true"] { background: rgba(228,216,198,.2); color: #f2efe8; }
/* the eye while the digits show: picked as the calculator picks (2 Nov 2026, the operator: go A), the soft fill in a
   1.5px ink ring, both themes */
:root[data-app][data-theme] .pn-show[aria-pressed="true"] { background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); color: var(--pn-ink); }
@media (hover: hover) { .pn-show:hover { background: rgba(255,255,255,.14); color: #f2efe8; } }

/* the ask and view sheets */
/* EVERY POP-UP, ONE BACKDROP (Problem report 171, 12 Oct 2026: "Any popup is glitchy atm"). The dim is --pn-dim, the
   theme's own (below and in the light theme), the same for the Studio's sheets, its questions and the desk's windows, and
   it covers the pinned header as it covers the page, so nothing of the page is left bright round a sheet. NO BLUR: a
   backdrop-filter over the whole screen was the heaviest thing WebKit drew (on an iPhone it was redrawn at every scroll
   inside the sheet), and a sheet's card nested a second one in it (smp.css' frosted .wa-card); and Safari stops reading a
   fixed layer with one for the colour of its bars (app.css' header notes, 10 Oct 2026). The card's face is solid anyway. */
:root[data-app] { --pn-dim: rgba(10,9,8,.66); --pn-edge-dim: rgb(15,13,11); }
.pn-sheet { position: fixed; inset: 0; z-index: 60; display: grid; place-items: center; padding: 16px; background: var(--pn-dim, rgba(10,9,8,.66)); overflow-y: auto; }
.pn-sheet > .wa-card { width: 100%; max-width: 440px; padding: 20px; max-height: calc(100dvh - 32px); overflow-y: auto; backdrop-filter: none; -webkit-backdrop-filter: none; }
.pn-sheet.pn-wide > .wa-card { max-width: 900px; }
.pn-sheet h2 { margin: 0 0 10px; overflow-wrap: anywhere; }
/* a long name with no spaces breaks inside the line rather than push the sheet sideways (design audit, 27 Sep 2026) */
.pn-sheet p { margin: 0 0 10px; font-size: 14px; line-height: 1.5; color: rgba(242,239,232,.78); overflow-wrap: anywhere; }
.pn-sheet p.pn-msg { color: var(--st-warn); }
.pn-files { display: grid; grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); gap: 10px; margin: 10px 0; }
.pn-file { display: grid; gap: 6px; min-width: 0; font-size: 12px; color: rgba(242,239,232,.66); }
.pn-file img, .pn-file video { display: block; width: 100%; aspect-ratio: 3 / 2; object-fit: contain; border-radius: var(--pn-r); background: rgba(0,0,0,.3); }

@media (min-width: 760px) {
  .pn-grid.pn-two { grid-template-columns: repeat(2, minmax(0,1fr)); }
  .pn-link { grid-template-columns: minmax(0,1fr) auto; }
  .pn-tiles { grid-template-columns: repeat(3, minmax(0,1fr)); }
}
@media (min-width: 1000px) {
  .pn-tiles { grid-template-columns: repeat(4, minmax(0,1fr)); }
}

/* one booth's diagnostics (SHARE-CLOUD.md section 18). Phone first: the operator reads this in a venue car park,
   so the one thing that is wrong is a whole card at the top and the figures are two columns of nothing else. */
.pn-dot { display: inline-block; width: 9px; height: 9px; margin-right: 7px; border-radius: 50%; background: rgba(242,239,232,.3); vertical-align: baseline; flex: none; }
.pn-dot.pn-good { background: var(--st-good); }
.pn-dot.pn-warn { background: var(--st-warn); }
.pn-dot.pn-bad { background: var(--st-bad); }
.pn-dot.pn-off { background: rgba(242,239,232,.28); }
.pn-t.pn-good, b.pn-good, p.pn-good { color: var(--st-good); }
.pn-t.pn-warn, b.pn-warn, p.pn-warn { color: var(--st-warn); }
.pn-t.pn-bad, b.pn-bad, p.pn-bad { color: var(--st-bad); }
/* the worst thing right now, with a stripe down its edge saying how bad it is. NOT `.pn-top`, which is the
   header's own top tier: one name for two things put this stripe left of the logo on every page. */
.pn-worst { border-left: 3px solid rgba(255,255,255,.18); }
.pn-worst.pn-good { border-left-color: var(--st-good-line); }
.pn-worst.pn-warn { border-left-color: var(--st-warn-line); }
.pn-worst.pn-bad { border-left-color: var(--st-bad-line); }
.pn-worstline { display: flex; align-items: baseline; margin: 0; font-size: 17px; line-height: 1.4; color: #f7f2ea; overflow-wrap: anywhere; }
.pn-ago { margin: 8px 0 0; font-size: 14px; line-height: 1.45; color: rgba(242,239,232,.72); font-variant-numeric: tabular-nums; }
.pn-card h2 .pn-dot { margin-right: 8px; }
.pn-facts { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 10px 12px; }
.pn-fact { display: grid; gap: 3px; min-width: 0; }
.pn-fact i { font-style: normal; font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: rgba(242,239,232,.52); }
.pn-fact b { font-size: 14px; font-weight: 450; color: #f2efe8; overflow-wrap: anywhere; font-variant-numeric: tabular-nums; }
/* A BOOTH THAT HAS GONE QUIET: every figure underneath is only as true as the last time it spoke, so its dots stop
   claiming a colour and its figures step back. The words are still readable -- this is "these are old", not "these
   are gone" -- and the line above the grid says how old. */
.pn-cold .pn-dot { background: rgba(242,239,232,.28) !important; }
.pn-cold .pn-fact b, .pn-cold .pn-card .pn-sub { color: rgba(242,239,232,.55); }
.pn-hide { display: none; }
/* a booth's name on the Devices list is the way in to its diagnostics */
.pn-list .pn-m a { color: #f2efe8; text-decoration: none; border-bottom: 1px solid rgba(255,255,255,.22); }
@media (hover: hover) { .pn-list .pn-m a:hover { border-bottom-color: var(--beige); } }

/* spacing (the CSP allows no inline style attributes) */
.pn-mt4 { margin-top: 4px !important; }
.pn-mt8 { margin-top: 8px !important; }
.pn-mt10 { margin-top: 10px !important; }
.pn-mt12 { margin-top: 12px !important; }
.pn-mt14 { margin-top: 14px !important; }
.pn-mt18 { margin-top: 18px !important; }
.pn-mt24 { margin-top: 24px !important; }
.pn-narrow { width: 100%; max-width: 460px; }

/* EVERY BOX IN THE PANEL IS THE SAME WIDTH (operator, 24 Sep 2026: "All boxes should be width. Ie the session
   box should be width like the one above etc"). `.wa-empty` is capped at 420px and centred, which is right on a
   guest's page where it is the only thing on screen, and wrong here, where it sits under cards that run the full
   width and reads as a box that missed its mark. The cap is lifted inside the panel only; the guest pages keep
   theirs. */
.pn-wrap .wa-empty { max-width: none; margin-left: 0; margin-right: 0; }
/* ITS WORDS IN THE MIDDLE OF THE BOX (the operator's reports 118 and 120, 5 Oct 2026, of "No emails have been sent yet."
   on Emails: "fix gap", and of Bookings' empty box: "what is this gap in the text box"). A paragraph in a card stops at
   about 75 characters (report 92, below), and an empty box's words are centred inside that, so on a wide screen they
   sat in the middle of a column at the box's left with a wide gap before them. The column itself is centred now. */
.pn-wrap .wa-empty > p { margin-left: auto; margin-right: auto; }
.pn-faded { opacity: .35; }

/* ═══════════════════════════════════════════════════════════════════════════════════════════════════════════════

   LIGHT (operator, 24 Sep 2026: "Add a light/dark mode that is synced to system by default", app first, guests

   later). ONE SELECTOR, because common.js resolves the choice - system, light or dark - and writes the answer on

   the page; the stylesheet never has to reason about the device as well.

   It is a SECOND PALETTE, not the first one inverted. Night glass is white at low alpha over a dark ground, and

   the same trick on paper gives grey mud: here the cards are paper over a warm stone ground, the hairlines are ink

   at low alpha, and what was a pale fill on dark becomes an INK fill with pale text, so the page you are on still

   reads as the loudest thing in the row.

   Warm throughout, because the brand is: the ground is stone rather than white, and nothing here is #fff except a

   card's own face and the text on a dark fill.

   Only `[data-app]` carries a theme, so the guest pages and the booking page are untouched.

   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */

:root[data-app][data-theme="light"] {

  --pn-ground: #f6f4ef;

  --pn-face: #ffffff;

  --pn-ink: #241f19;

  --pn-ink-soft: rgba(36,31,25,.66);

  --pn-ink-faint: rgba(36,31,25,.72);

  --pn-line: #d3d2d1;

  --pn-fill: rgba(36,31,25,.06);

  --pn-fill-hover: rgba(36,31,25,.1);

  --pn-olive: #4f4e0d;

  color-scheme: light;

}

/* the page is pale, so the header stops being a tint of what is behind it and becomes a band of its own,
   dark enough for the logo's white line art to read exactly as it does in the dark theme */
:root[data-app][data-theme="light"] body,
:root[data-app][data-theme="light"] .wa-pg { color: var(--pn-ink); }
:root[data-app][data-theme="light"] body { background: var(--pn-ground); }
/* THE SCROLLBAR'S ROOM IN THE PAGE'S GROUND (the UX review, 3 Nov 2026): the room kept for the scrollbar on every app page
   (scrollbar-gutter, below) shows the root's own background, which in light stayed the dark ground: a 15px dark strip
   down the right edge of a page with nothing to scroll, in Chrome and Edge on Windows. The ground now, under a picture
   dark beside the header alone, for a browser that paints the picture there too */
:root[data-app][data-theme="light"] { background: linear-gradient(#241f19 0 var(--pn-bar-sp, 0px), var(--pn-ground) 0) fixed var(--pn-ground); }
/* BUT NOT ON A TOUCH SCREEN (3 Nov 2026, the operator, of the Desk on his iPhone: "The top bar keeps switching white to
   dark etc", then "It's still doing it"): iPhone Safari reads the root's own colour for its bars, and the pale ground
   above made its top bar flip between the header's dark and the page's light. A touch screen has no scrollbar room to
   fill, so there the root keeps the header's dark, as it did before this morning */
@media (hover: none) and (pointer: coarse) {
  :root[data-app][data-theme="light"] { background: #1d1915; }
  /* THE BODY'S OWN COLOUR DARK (3 Nov 2026, the operator's recording, the Desk in light: at every fold and unfold of
     Safari's bars its address pill faded to light over most of a second, then snapped back to dark once the bars
     settled). While the bars move Safari reads the body's own background colour, not the header; that was the pale
     ground. The body's colour is the header's dark now, the pale ground painted over it as a picture, so the page looks
     the same and Safari only ever finds dark. The fixed ground layer steps back (the body already paints it), so the
     header is the one fixed thing at the window's top. */
  :root[data-app][data-theme="light"] body { background: linear-gradient(var(--pn-ground), var(--pn-ground)) #1d1915; }
  :root[data-app][data-theme="light"] .wa-bg { display: none; }
  /* and the header's dark carried up past the window's top, so the few pixels Safari opens above it while its bars move
     show the header's colour, never the page's white ("it keeps gapping I can see the white as I scroll") */
  .pn-bar::before { content: ""; position: absolute; left: 0; right: 0; bottom: 100%; height: 160px; background: inherit; pointer-events: none; }
}
/* THE STUDIO IN A FRAME ON A PHONE OR A TABLET (3 Nov 2026, the operator, of Safari's address pill turning light at every
   fold and unfold of its bars as he scrolled, in either theme, then "Yes, bars stay put", as the website's phones have
   had since 22 Oct, site.css section 22). Anything but a computer's window (640 px and wider with a mouse or a trackpad,
   common.js asks the same): html holds still and the body is a fixed frame the screen's size that scrolls the page
   inside itself, so Safari's bars never fold and its colour never changes. The header, the sheets and everything else
   fixed stay fixed to the screen (the frame clips nothing fixed). Under a popup the frame stops scrolling (wa-held). What
   it costs, as on the website: the bars always show, and Safari's pull to refresh and a tap on the clock do nothing. */
@media not all and (min-width: 640px) and (pointer: fine) {
  :root[data-app] { height: 100%; overflow: hidden; overscroll-behavior: none; }
  :root[data-app] body { position: fixed; inset: 0; min-height: 0; overflow-x: hidden; overflow-y: auto; overscroll-behavior: none; }
  :root[data-app].wa-held body { overflow: hidden; }
}
/* THE HEADER IS LEFT IN THE DARK (operator, 24 Sep 2026: "Don't change the header (to preserve logo) in light
   mode"). The logo is white line art with a yellow moon; on paper the wordmark would vanish and leave a moon.
   So the whole bar keeps its dark styling, and the one thing that changes is that it stops being see-through:
   a tint of a pale page is not dark, and the logo needs the ground it was drawn for. */
:root[data-app][data-theme="light"] .pn-bar { background: #241f19; border-bottom-color: rgba(0,0,0,.25); }

/* the ground's own light, warmed and pulled well down: the dark theme's beige glow is invisible on paper */

/* FLAT, NO GRADIENT (the operator, 26 Sep 2026: "remove the gradient from lightmode BG"): the ground is one colour,
   the old gradient's own middle, as dark's is (below) */
:root[data-app][data-theme="light"] .wa-bg { background: var(--pn-ground); }

/* a card is paper: a face, a hairline, and a shadow that sits rather than glows. ONE COLOUR, NO GRADIENT (the operator,
   28 Sep 2026: "Remove gradient from settings", then "yes remove gradient everywhere": every card is flat) */

:root[data-app][data-theme="light"] .wa-card {

  background: var(--pn-face);

  border-color: var(--pn-line);

  box-shadow: none;

}

/* words */
:root[data-app][data-theme="light"] .pn-sub,
:root[data-app][data-theme="light"] .pn-t,
:root[data-app][data-theme="light"] .wa-empty { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-note,
:root[data-app][data-theme="light"] .pn-m { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .wa-k { color: var(--pn-olive); }
/* a person's card is named in ink, as it is in dark, never in the olive of a card's heading (UI audit, 30 Sep 2026) */

/* controls */

:root[data-app][data-theme="light"] .pn-wrap .wa-btn,
:root[data-app][data-theme="light"] .pn-sheet .wa-btn { background: var(--pn-ink); color: #f7f3ec; }
:root[data-app][data-theme="light"] .pn-wrap .wa-gl,
:root[data-app][data-theme="light"] .pn-wrap .wa-pill,
:root[data-app][data-theme="light"] .pn-sheet .wa-gl,
:root[data-app][data-theme="light"] .pn-sheet .wa-pill,
:root[data-app][data-theme="light"] .pn-tznote .wa-gl { background: var(--pn-face); color: var(--pn-ink); }
/* THE LINE BUTTON (2 Nov 2026, the operator: go A): white with a hairline edge, as the website's outline button and the
   calculator's rows, so it reads on the paper and on a card alike (dark's white edge did not show on paper, UI audit,
   30 Sep 2026) */
:root[data-app][data-theme="light"] .pn-wrap .wa-gl,
:root[data-app][data-theme="light"] .pn-wrap .wa-pill,
:root[data-app][data-theme="light"] .pn-sheet .wa-gl,
:root[data-app][data-theme="light"] .pn-sheet .wa-pill { border-color: var(--pn-line); }
/* the hover leaves a picked button (.pn-on) and an off one as they are (design audit, 27 Sep 2026) */
@media (hover: hover) {
  :root[data-app][data-theme="light"] .pn-wrap .wa-gl:not(.pn-on):not(:disabled):hover,
  :root[data-app][data-theme="light"] .pn-wrap .wa-pill:not(.pn-on):not(:disabled):hover,
  :root[data-app][data-theme="light"] .pn-sheet .wa-gl:not(.pn-on):not(:disabled):hover,
  :root[data-app][data-theme="light"] .pn-sheet .wa-pill:not(.pn-on):not(:disabled):hover,
  :root[data-app][data-theme="light"] .pn-tznote .wa-gl:hover { background: var(--pn-hover); }
  /* a filled button changes enough to see under the mouse: brightness(1.05) on the ink moved it about two levels */
  :root[data-app][data-theme="light"] .pn-wrap .wa-btn:not(:disabled):hover,
  :root[data-app][data-theme="light"] .pn-sheet .wa-btn:not(:disabled):hover { background: #3a332a; filter: none; }
}
:root[data-app][data-theme="light"] .wa-pwin,
:root[data-app][data-theme="light"] .pn-digit {

  background: var(--pn-face);

  border-color: var(--pn-edge);

  color: var(--pn-ink);

}
:root[data-app] .wa-pwin::placeholder, :root[data-app][data-theme="light"] .wa-pwin::placeholder { color: var(--pn-ph); }
:root[data-app][data-theme="light"] .wa-pwin:focus,
:root[data-app][data-theme="light"] .pn-digit:focus {

  border-color: var(--pn-ink);

  box-shadow: 0 0 0 1px var(--pn-ink);

}
:root[data-app][data-theme="light"] .pn-secret { background: var(--pn-fill); color: var(--pn-ink); }

/* states keep their meaning: amber for a warning, red for a fault, both darkened to hold on paper */


/* the danger controls carry !important on a dark ground, so paper has to answer in kind: a pale tint of the
   same red, a hairline of it, and the red dark enough to read at 11px */
/* THE MAIN PRESS OF A DANGER CONFIRM IS FILLED (design audit, 27 Sep 2026): the pale wash made Sign out everywhere and
   Take it down no louder than Cancel beside them. The wash stays on a row's own buttons (.wa-gl, .wa-pill), which only
   open the confirm. White on this red is about 5:1. */
.wa-btn.pn-danger, .wa-btn.pn-qdown,
:root[data-app][data-theme="light"] .wa-btn.pn-danger,
:root[data-app][data-theme="light"] .wa-btn.pn-qdown { background: #c2462a !important; color: #fff !important; border-color: transparent !important; }
/* AND GREY WHILE IT CAN'T BE PRESSED (report 172, 12 Oct 2026, of Refund to card with too much typed: "grey out the
   button"): at half strength the red still read as the red press, so off it takes the plain button's grey and ink, at
   the half strength every button off has (smp.css) */
.wa-btn.pn-danger:disabled { background: rgba(255,255,255,.14) !important; color: #f2efe8 !important; }
:root[data-app][data-theme="light"] .wa-btn.pn-danger:disabled { background: var(--pn-fill) !important; color: var(--pn-ink) !important; }
/* A STATUS BADGE ON PAPER keeps its meaning (design audit, 27 Sep 2026): an on badge in the page's olive, a warning in
   amber, and off (below) grey; all three were ink on grey, so Has a PIN read the same as No PIN */
:root[data-app][data-theme="light"] .pn-badge { background: rgba(79,78,13,.1); color: var(--pn-olive); border-color: rgba(79,78,13,.28); }
:root[data-app][data-theme="light"] .pn-badge.pn-warn { background: var(--st-warn-bg); color: var(--st-warn); border-color: var(--st-warn-line); }
:root[data-app][data-theme="light"] .pn-badge.pn-good { background: var(--st-good-bg); color: var(--st-good); border-color: var(--st-good-line); }
:root[data-app][data-theme="light"] .pn-badge.pn-bad { background: var(--st-bad-bg); color: var(--st-bad); border-color: var(--st-bad-line); }

/* the sheet, over a page that is now pale */

/* THE LIGHT THEME'S DIM (report 171): a dark neutral, no longer the header's own brown (rgba(40,33,25,.42)), which left the
   dark header looking undimmed (#241f19 stayed #262019) while the paper under it went grey, so a sheet looked laid over
   a live header. This one dims the header with the page: its words and glyphs to about half, the paper to a mid grey. */
:root[data-app][data-theme="light"] { --pn-dim: rgba(14,12,9,.48); --pn-edge-dim: rgb(135,133,129); }

/* and the boot message, which is written with its own inline colour for dark: on paper it needs the ink */

:root[data-app][data-theme="light"] .wa-boot { color: var(--pn-ink-soft); }

:focus-visible { outline-color: currentColor; }
:root[data-app][data-theme="dark"] :focus-visible { outline-color: var(--beige); }
/* THE KEYBOARD'S RING ON PAPER IS INK (design audit, 27 Sep 2026): currentColor made a filled button's ring its own
   pale words, cream on the cream page, and the switch, the design cards, the calendar and Copy link drew theirs in the
   moon yellow or the beige, which do not show on paper. What stays dark in light keeps the pale ring: the header (the
   logo's ground) with its menus, the upload dock and the sign-in card. The chosen day in the calendar is filled
   yellow in both themes (2 Nov 2026, the operator: go A) and its ring is drawn inside it, so there the ring is the
   yellow's own ink, in light and in dark. */
:root[data-app][data-theme="light"] :focus-visible,
:root[data-app][data-theme="light"] .pn-wmadd:focus-within { outline-color: var(--pn-ink); }
:root[data-app][data-theme="light"] :is(.pn-bar, .pn-dock, .wa-gcard) :focus-visible { outline-color: var(--beige); }
:root[data-app][data-theme="light"] .pn-calday[aria-selected="true"]:focus-visible { outline-color: var(--pn-ink); }
:root[data-app][data-theme="dark"] .pn-calday[aria-selected="true"]:focus-visible { outline-color: var(--pn-on-y); }

/* the rest of the panel's pale ink, which is written as rgba(242,239,232,a) for a dark ground and has to become

   the same weights of the dark ink on paper. Grouped by how loud each one is meant to be, not by where it is. */

:root[data-app][data-theme="light"] .pn-worstline,
:root[data-app][data-theme="light"] .pn-fact b,
:root[data-app][data-theme="light"] .pn-list .pn-m a { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-when,
:root[data-app][data-theme="light"] .pn-sheet p,
:root[data-app][data-theme="light"] .pn-file,
:root[data-app][data-theme="light"] .pn-ago { color: var(--pn-ink-soft); }
/* a warning inside a sheet keeps its amber on paper (UI audit, 30 Sep 2026): the sheet's soft ink above outranked the
   p.pn-warn rule, so Add a plan's warning read as plain words */
:root[data-app][data-theme="light"] .pn-sheet p.pn-warn { color: var(--st-warn); }
:root[data-app][data-theme="light"] .pn-sheet p.pn-msg { color: var(--st-warn); }
:root[data-app][data-theme="light"] .pn-stats i,
:root[data-app][data-theme="light"] .pn-fact i { color: var(--pn-ink-faint); }
/* the words in a list, and the eye: two rules. They were one selector list until the eye took a background (25 Sep
   2026), and every value on Account and Photobooth PINs sat in a grey box ("it still has back highlight??") */
:root[data-app][data-theme="light"] .pn-list .pn-t { color: var(--pn-ink-soft); }
/* the line between a list's rows, in ink on paper (design audit, 27 Sep 2026: it was white at 8%, so People, PINs,
   Devices and Activity ran together) */
:root[data-app][data-theme="light"] .pn-list li { border-top-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-show { background: none; color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-show[aria-pressed="true"] { background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); color: var(--pn-ink); }
@media (hover: hover) {
  :root[data-app][data-theme="light"] .pn-show:hover { background: rgba(36,31,25,.12); color: var(--pn-ink); }
  :root[data-app][data-theme="light"] .pn-pinseen:hover { background: rgba(36,31,25,.06); }
}
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-night:hover { border-color: rgba(36,31,25,.28); } }
:root[data-app][data-theme="light"] .pn-badge.pn-off { background: var(--pn-fill); color: var(--pn-ink); border-color: var(--pn-line); }
/* a label on a photo stays the dark chip on paper too: it sits on the picture, not on the page (after the off and
   warning badges above, which it has to outrank) */
:root[data-app][data-theme="light"] .pn-cover .pn-badge { background: rgba(20,18,16,.62); color: #fff; border-color: transparent; }
:root[data-app][data-theme="light"] .pn-cover .pn-badge.pn-warn { color: var(--st-warn); }
/* A MESSAGE'S PLATFORM IN ITS OWN COLOUR (report 148, the --plat- tokens at the top of this sheet): Instagram's chip a
   tint of its magenta and Facebook's of its blue, in the app's chip shape, in both themes (after the light theme's
   badge rules above, which it has to outrank) */
:root[data-app] .pn-badge.pn-ig { background: var(--plat-ig-bg); color: var(--plat-ig); border-color: var(--plat-ig-line); }
:root[data-app] .pn-badge.pn-fb { background: var(--plat-fb-bg); color: var(--plat-fb); border-color: var(--plat-fb-line); }
/* and the link that cannot be changed is the page's own tint, as a secret is (design audit, 27 Sep 2026) */
:root[data-app][data-theme="light"] .pn-linktext { background: var(--pn-fill); border-color: transparent; color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-dot.pn-off,
:root[data-app][data-theme="light"] .pn-cold .pn-dot { background: rgba(36,31,25,.3) !important; }
:root[data-app][data-theme="light"] .pn-cold .pn-fact b,
:root[data-app][data-theme="light"] .pn-cold .pn-card .pn-sub { color: var(--pn-ink-faint); }
:root[data-app][data-theme="light"] .pn-list .pn-m a { border-bottom-color: rgba(36,31,25,.3); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-list .pn-m a:hover { border-bottom-color: var(--pn-ink); } }

/* TOUCH TARGETS (the operator, 24 Sep 2026: "spend 500k tokens budget on checking breakpoints at my desktop screen solution, 1080p resolution, ipad and phone"). Measured on a phone and an iPad: the header's
   tabs were 33px tall, the pills in a page 30 to 32px, the small buttons 38px, a booth's name 18px and the PIN's Show
   15px, where a thumb needs about 44. A finger gets the bigger target; a mouse keeps the look it had. */
@media (pointer: coarse) {
  .pn-nav .wa-pill { height: 44px; padding: 0 15px; }
  :root[data-app] .wa-sm { height: var(--pn-h-main); }
  .pn-list a[href^="/devices/"] { display: inline-flex; align-items: center; min-height: 44px; }
  /* the name and its code apart, and the line under the name only, close to it (26 Sep 2026: "Fix spacing"): as a
     flex box the link had dropped the space between them and drawn its line at the foot of the taller target */
  .pn-list .pn-m a[href^="/devices/"] { gap: 8px; border-bottom: 0; }
  .pn-list .pn-m a[href^="/devices/"] b { text-decoration: underline; text-decoration-thickness: 1px; text-underline-offset: 4px;
    text-decoration-color: currentColor; }
  .wa-lgbox { padding: 8px 0; margin: -8px 0; }
}
/* ONE ROW OF TABS ON A PHONE (the operator, 25 Sep 2026: People had dropped to a line of its own). The four need
   about 475px with their glyphs and a phone has about 330, so below 520px the glyphs step out of the track (they stay
   in the menus, and on a tablet or a computer), the pills close up, and the row never wraps. The second menu opens
   leftward from its button's right edge, so it stays on the screen. */
@media (max-width: 519px) {
  .pn-nav { flex-wrap: nowrap; justify-content: space-between; }
  .pn-nav .wa-pill .pn-navgl { display: none; }
  .pn-nav .wa-pill { padding: 0 10px; white-space: nowrap; }
  .pn-nav .pn-groupbtn { gap: 5px; }
  .pn-nav .pn-group + .pn-group .pn-menu { left: auto; right: 0; }
}
/* a 390px phone: closer still (a narrower one, down to 320px, is at the end of this sheet: THE HEADER ON A NARROW PHONE) */
@media (max-width: 389px) {
  .pn-nav .wa-pill { padding: 0 7px; }
  .pn-nav .pn-groupbtn { gap: 4px; }
}

/* THE HEADER PINNED ON EVERY PHONE (3 Nov 2026, the operator, of the Desk on his iPhone: "Check the top bar pin, it keeps
   gapping I can see the white as I scroll"). It scrolled away on a phone under 760px tall (24 Sep 2026); but Safari's
   window is that tall or not as its bars fold, so on a large iPhone the header kept changing between pinned and
   scrolling, leaving the page's white above it and Safari's top bar flipping colour. It is pinned on every screen. */

/* LIGHT: a session tile's name, time and size were the dark theme's pale ink on the light card (measured 24 Sep
   2026 at 1.14:1, near invisible; the first light audit had no sessions to see). The page's own inks instead. */
:root[data-app][data-theme="light"] .pn-tmeta { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-tmeta b { color: var(--pn-ink); }

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE BOOTH'S REAR DASHBOARD, ON ITS PAGE (SHARE-CLOUD.md section 24; the operator, 25 Sep 2026: "duplicate the
   layout on to the studio and allow control"). The rear screen's own order: the event and wifi along the top, the
   camera's picture at 3:2 with its badge and PAUSED or BE RIGHT BACK over it, five figures that each open a card,
   and Pause, Reprint last and Resume print along the foot.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.pn-rear { display: grid; gap: 12px; padding: 14px; }
.pn-rear-top { display: flex; align-items: center; gap: 10px; min-width: 0; font-size: 13px; color: rgba(242,239,232,.78); }
.pn-rear-ev { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; color: #f2efe8; }
.pn-rear-sp { flex: 1; }
.pn-rear-up, .pn-rear-net { white-space: nowrap; font-size: 12px; }
.pn-rear-live { position: relative; aspect-ratio: 3 / 2; width: 100%; max-height: 62vh; margin: 0 auto; overflow: hidden; border-radius: var(--pn-r);
  background: #0d0c0b; display: grid; place-items: center; }
.pn-rear-live img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; }
.pn-rear-nopic { margin: 0; padding: 0 18px; text-align: center; font-size: 13px; color: rgba(242,239,232,.66); }
.pn-rear-badge { position: absolute; top: 10px; left: 10px; padding: 4px 10px; border-radius: var(--pn-r); font-size: 12px; font-weight: 600;
  background: rgba(13,12,11,.72); color: var(--st-good); }
.pn-rear-badge.pn-warn { color: var(--st-warn); }
.pn-rear-badge.pn-bad { color: var(--st-bad); }
.pn-rear-over { position: absolute; inset: 0; display: grid; place-content: center; gap: 8px; justify-items: center; text-align: center;
  padding: 16px; background: rgba(13,12,11,.78); color: #f2efe8; }
.pn-rear-over b { font-size: 22px; font-weight: 600; letter-spacing: .14em; }
.pn-rear-over span { font-size: 13px; color: rgba(242,239,232,.78); }
.pn-rear-strip { display: grid; grid-template-columns: repeat(5, minmax(0,1fr)); gap: 1px; overflow: hidden; border-radius: var(--pn-r);
  background: rgba(242,239,232,.12); border: 1px solid rgba(242,239,232,.12); }
.pn-rear-fig { display: grid; gap: 3px; min-width: 0; padding: 10px 8px; text-align: left; background: rgba(20,18,16,.92); color: #f2efe8;
  border: 0; cursor: pointer; font: inherit; }
@media (hover: hover) { .pn-rear-fig:hover { background: rgba(38,34,30,.95); } }
/* the open figure is picked as the calculator picks (2 Nov 2026, the operator: go A): the soft fill in a 1.5px ink ring,
   where it was a beige wash over a 2px rule */
.pn-rear-fig.pn-on { background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); color: #f2efe8; }
.pn-rear-k { font-size: 10.5px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: rgba(242,239,232,.66); }
.pn-rear-v { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; font-weight: 600; }
.pn-rear-card { display: grid; gap: 10px; padding: 12px; border-radius: var(--pn-r); background: rgba(242,239,232,.05); border: 1px solid rgba(242,239,232,.1); }
.pn-rear-card h3 { margin: 0; }
.pn-rear-card .pn-sub { margin: 0; }
.pn-rear-list li { display: flex; align-items: center; gap: 10px; }
.pn-rear-list li .pn-m { flex: 1; min-width: 0; }
/* the booth's Bookings to choose from (27 Sep 2026): the button and the In use badge keep their width beside a long name */
.pn-rear-bklist li > .wa-gl, .pn-rear-bklist li > .pn-badge { flex: none; }
.pn-rear-cardacts, .pn-rear-acts { display: flex; flex-wrap: wrap; gap: 8px; }
.pn-rear-note { margin: 0; }
@media (max-width: 560px) {
  .pn-rear { padding: 10px; }
  .pn-rear-strip { grid-template-columns: repeat(6, minmax(0,1fr)); }
  .pn-rear-strip > :nth-child(-n+3) { grid-column: span 2; }
  .pn-rear-strip > :nth-child(n+4) { grid-column: span 3; }
  .pn-rear-live { border-radius: var(--pn-r); }
  .pn-rear-over b { font-size: 18px; }
}
@media (pointer: coarse) {
  .pn-rear-fig { min-height: 56px; }
}
:root[data-app][data-theme="light"] .pn-rear-top { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-rear-ev { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-rear-strip { background: var(--pn-line); border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-rear-fig { background: var(--pn-face); color: var(--pn-ink); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-rear-fig:hover { background: var(--pn-fill-hover); } }
:root[data-app][data-theme="light"] .pn-rear-fig.pn-on { background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-rear-k { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-rear-card { background: var(--pn-fill); border-color: var(--pn-line); }
/* a figure's card is the page's ground set into the white card, edged with the hairline, in both themes (go A) */
:root[data-app][data-theme] .pn-rear-card { background: var(--pn-ground); border-color: var(--pn-line); }
.pn-rear-v.pn-good, .pn-rear-net.pn-good { color: var(--st-good); }
.pn-rear-v.pn-warn, .pn-rear-net.pn-warn { color: var(--st-warn); }
.pn-rear-v.pn-bad, .pn-rear-net.pn-bad { color: var(--st-bad); }
/* the block's own parts set their display, so hiding one needs the block's name in front (a single .pn-hide loses) */
.pn-rear .pn-hide { display: none; }

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE CLIENT GALLERIES, the operator's side (P2, lib/galleries.js). Making one, filling it, and choosing which of
   the five layouts the client sees.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.pn-on { background: var(--beige); color: #221d18; font-weight: 600; }
:root[data-app][data-theme="light"] .pn-on { background: var(--pn-ink); color: #f7f3ec; }
.pn-break { overflow-wrap: anywhere; }

.pn-drop { display: grid; gap: 3px; place-items: center; padding: 26px 16px; margin-top: 10px; text-align: center;
  border: 1.5px dashed rgba(255,255,255,.22); border-radius: var(--pn-r); background: rgba(255,255,255,.03); cursor: pointer; }
.pn-drop b { font-size: 14px; font-weight: 600; }
.pn-drop span { font-size: 12px; color: rgba(242,239,232,.6); }
.pn-drop.pn-over { border-color: var(--beige); background: rgba(228,216,198,.1); }
:root[data-app][data-theme="light"] .pn-drop { border-color: rgba(36,31,25,.24); background: var(--pn-fill); }
:root[data-app][data-theme="light"] .pn-drop span { color: var(--pn-ink-soft); }

.pn-uprog { margin-top: 10px; display: grid; gap: 6px; }
/* hidden is hidden (3 Nov 2026, the Studio's UX pass): the grid above beat .pn-hide, so the empty progress kept its 10px
   at the foot of a gallery's Photos */
.pn-uprog.pn-hide { display: none; }
.pn-uline { display: grid; grid-template-columns: minmax(0,1fr) auto; gap: 4px 10px; font-size: 12px; }
.pn-ubar { grid-column: 1 / -1; height: 3px; border-radius: var(--pn-r); background: rgba(255,255,255,.12); overflow: hidden; }
.pn-ubar i { display: block; height: 100%; background: var(--pn-y); transition: width .2s ease; }
/* on paper the bar is the ink, its track the ink faint (2 Nov 2026, the operator: go A): the yellow is the dark theme's and the dock's */
:root[data-app][data-theme="light"] .pn-ubar { background: rgba(36,31,25,.12); }
:root[data-app][data-theme="light"] .pn-ubar i { background: var(--pn-ink); }

.pn-gphotos { display: grid; gap: 6px; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); }
.pn-gphoto { position: relative; aspect-ratio: 1; border-radius: var(--pn-r); overflow: hidden; background: rgba(255,255,255,.05); }
.pn-gphoto img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pn-gname { position: absolute; inset: auto 0 0 0; padding: 8px 5px 3px; font-size: 9px; color: #f6f1e8;
  background: linear-gradient(to top, rgba(10,9,8,.8), rgba(10,9,8,0)); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-gx { position: absolute; right: 3px; top: 3px; width: 24px; height: 24px; padding: 0; border: 0; border-radius: var(--pn-r);
  background: rgba(10,9,8,.6); color: #f6f1e8; font-size: 15px; line-height: 1; cursor: pointer; }
/* square, and 44px to a thumb by a reach that takes no room from the photo (3 Nov 2026, the Studio's UX pass) */
@media (pointer: coarse) { .pn-gx { width: 34px; height: 34px; } .pn-gx::before { content: ""; position: absolute; inset: -5px; } .pn-drop { min-height: 96px; } }
@media (prefers-reduced-motion: reduce) { .pn-ubar i { transition: none; } }

/* THE UPLOAD DOCK, bottom right (the operator, 25 Sep 2026: "with bottom right upload status indicator, speed,
   photos left etc"). It sits on the body, not in the page, so wandering off to look at a booth does not lose it.
   Four hundred photos take a while and nobody watches them go.
   THE INK BAR (2 Nov 2026, the operator: go A): on paper it is the calculator's ink bar, solid and square with the card's shadow, its
   progress the yellow; in dark the menus' face in the line's ring (below). No blur in either. */
.pn-dock { position: fixed; right: 16px; bottom: 16px; z-index: 65; width: min(340px, calc(100vw - 32px));
  padding: 12px 14px 13px; border-radius: var(--pn-r); border: 1px solid transparent;
  background: var(--pn-inkbar, #241f19); box-shadow: var(--pn-sh); color: var(--pn-on-inkbar, #f2efe8); }
:root[data-app][data-theme="dark"] .pn-dock { border-color: var(--pn-line); }
.pn-dock-h { display: flex; align-items: center; gap: 6px; }
.pn-dock-h b { font-size: 14px; font-weight: 600; }
.pn-dock-b { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--pn-r); background: transparent;
  color: rgba(242,239,232,.7); font-size: 15px; line-height: 1; cursor: pointer; }
.pn-dock-b:hover { background: rgba(255,255,255,.08); color: #f2efe8; }
.pn-dock-bar { height: 4px; margin: 9px 0 8px; border-radius: var(--pn-r); background: rgba(255,255,255,.12); overflow: hidden; }
.pn-dock-bar i { display: block; height: 100%; width: 0; border-radius: var(--pn-r); background: var(--pn-y); transition: width .3s ease; }
.pn-dock-l { margin: 0; font-size: 12px; line-height: 1.5; font-variant-numeric: tabular-nums; }
.pn-dock-dim { color: rgba(242,239,232,.6); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-dock-list { max-height: 148px; overflow-y: auto; margin-top: 8px; padding-top: 8px; border-top: 1px solid rgba(255,255,255,.1); }
.pn-dock-x { margin: 0 0 4px; font-size: 12px; line-height: 1.45; color: var(--st-bad); overflow-wrap: anywhere; }
.pn-dock-acts { margin-top: 10px; }
.pn-dock.pn-dock-good .pn-dock-bar i { background: var(--st-good); }
.pn-dock.pn-dock-bad .pn-dock-bar i { background: var(--st-bad); }
.pn-dock .pn-dock-list { display: none; }
.pn-dock.pn-open .pn-dock-list, .pn-dock.pn-dock-bad .pn-dock-list { display: block; }
@media (max-width: 560px) { .pn-dock { right: 8px; left: 8px; bottom: 8px; width: auto; } }
@media (pointer: coarse) { .pn-dock-b { width: 44px; height: 44px; } }
@media (prefers-reduced-motion: reduce) { .pn-dock-bar i { transition: none; } }

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE REQUESTS HUB (lib/requests.js, and requestRow() in assets/app.js). The operator, 25 Sep 2026, in order:
   "add a photo deletion request button", then "add a notification hub where requests feed through and i can action
   immediately", then "the request button is clicked by viewers/attendees".

   A guest at a ball opens the client's gallery on their phone, finds a photo of themselves they would rather was
   not up, and asks. The asking deletes nothing: the row lands here and waits for the operator to say.

   ACTION IMMEDIATELY MEANS ON THE ROW, so the row carries everything a decision needs and nothing opens. The photo
   is a thumbnail beside the words, because nobody can answer "should this come down" from a file name, and both
   answers are buttons in the row itself: a queue that costs three taps a row is a queue that never gets cleared.

   On a phone the row stacks rather than shrinks. The picture keeps its size, the words take the width under it,
   and the two buttons take a line of their own at a size a thumb can hit, because the operator reads this in a
   venue car park with one hand.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
/* these rows are twice the height of the panel's other lists, so the hairline between them has more to hold apart */
.pn-qlist li { border-top-color: var(--pn-line, rgba(255,255,255,.1)); }
/* THE LIST'S NAME IS IN FRONT OF EVERY ROW RULE HERE, and it has to be: `.pn-list li` is a class and an element,
   which outranks a lone class however far down the sheet it is written, so a bare `.pn-q` would have been read and
   then thrown away for the layout it is trying to change. */
.pn-qlist .pn-q {
  align-items: flex-start;
  gap: 10px 12px;
  /* the left inset is the same on every row, so the waiting row's stripe lands beside the words rather than moving them */
  padding: 12px 2px 12px 12px;
  transition: background-color 120ms ease;
}
/* WAITING ON YOU, without shouting. A stripe down the edge and the faintest wash of the moon: enough to pick the
   unanswered rows out of a list that also holds the answered ones, and not so much that ten of them are a wall. */
/* 2 Nov 2026, the operator: go A: the soft wash and the bar, the yellow's in dark, the ink's on paper (below) */
.pn-qlist .pn-q.pn-qopen { box-shadow: inset 3px 0 0 var(--pn-ink); }
/* a pointer tracking across a wide screen keeps its place on the row; a finger never keeps any of this */
@media (hover: hover) {
  .pn-qlist .pn-q:hover { background: var(--pn-hover); }
  .pn-qlist .pn-q.pn-qopen:hover { background: var(--pn-hover); }
}
/* the photo itself, at a size you can decide from. The plate under it is the same as the gone box, so a slow load
   or a photo the browser cannot fetch holds its place in the row instead of collapsing it. */
.pn-qshot {
  flex: none;
  width: 92px;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--pn-r);
  background-color: rgba(0,0,0,.28);
  border: 1px solid rgba(255,255,255,.1);
}
/* A PHOTO THAT HAS ALREADY COME DOWN has nothing to load, so the box stays and says so: a dashed edge and a hatch,
   which reads as "gone on purpose" rather than as a picture that failed. */
.pn-qgone {
  flex: none;
  display: block;
  width: 92px;
  aspect-ratio: 3 / 2;
  border-radius: var(--pn-r);
  border: 1px dashed rgba(255,255,255,.18);
  background-color: rgba(0,0,0,.2);
  background-image: repeating-linear-gradient(135deg, rgba(242,239,232,.07) 0 2px, transparent 2px 9px);
}
.pn-qm { flex: 1 1 210px; min-width: 0; overflow-wrap: anywhere; }
/* the guest's own words, set apart from the facts above them: they are a person's sentence, not a field */
.pn-qnote {
  margin: 7px 0 0;
  padding-left: 9px;
  border-left: 2px solid rgba(255,255,255,.14);
  font-size: 12px;
  line-height: 1.45;
  color: rgba(242,239,232,.72);
}
/* both answers, hard right on a wide row so the whole column of them lines up and the eye runs down it */
.pn-qacts { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-left: auto; }
@media (max-width: 560px) {
  .pn-qlist .pn-q { gap: 9px 10px; }
  /* the buttons take a line of their own and split it: two full-width targets beat two small ones in a corner */
  .pn-qacts { width: 100%; margin-left: 0; }
  .pn-qacts .wa-gl, .pn-qacts .wa-btn { flex: 1 1 0; min-width: 0; }
}
@media (prefers-reduced-motion: reduce) { .pn-qlist .pn-q { transition: none; } }
/* LIGHT: the hairlines and plates here are pale ink over a dark ground, which is grey mud on paper. The stripe on a
   waiting row is the ink on paper (2 Nov 2026, the operator: go A), over the same soft wash. */
:root[data-app][data-theme="light"] .pn-qlist .pn-q.pn-qopen { box-shadow: inset 3px 0 0 var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-qshot { background-color: var(--pn-fill); border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-qgone {
  background-color: var(--pn-fill);
  border-color: rgba(36,31,25,.24);
  background-image: repeating-linear-gradient(135deg, rgba(36,31,25,.1) 0 2px, transparent 2px 9px);
}
:root[data-app][data-theme="light"] .pn-qnote { border-left-color: rgba(36,31,25,.18); color: var(--pn-ink-soft); }
/* a request's photo that is also on the website (Photos on the site): the facts, edged in the warn tone */
:root[data-app] .pn-qnote.pn-qsite { border-left-color: var(--st-warn); }
.pn-qsite a { color: inherit; text-decoration: underline; text-underline-offset: 2px; }

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   PRESETS AND ANALYTICS (the operator, 25 Sep 2026: "split into presets (set at gallery creation)", then "and album
   analytics, total downloads, total album views, etc"). newGallery(), analyticsCard() and peopleCard() in
   assets/app.js.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
/* THE FIRST CHOICE ON THE NEW GALLERY SHEET: three cards that are a radio group. Large, because they are the one
   thing on the sheet that cannot be changed afterwards, and side by side so the two live ones are read against each
   other. The third is on the sheet and grey: the operator said "later", and a card that is there but cannot be
   pressed says so better than one that is missing. The sheet is a step wider than the ask sheets for the three to
   sit in a row; on a phone they stack. */
.pn-sheet.pn-mid > .wa-card { max-width: 640px; }
.pn-choices { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px; margin: 4px 0 14px; }
/* a preset card: its glyph in a soft square, then its name, the two filling the card (26 Sep 2026) */
.pn-choices .pn-choice { grid-template-columns: auto minmax(0,1fr); align-items: center; column-gap: 12px; padding: 12px 14px; }
.pn-choicegl { display: grid; place-items: center; width: 38px; height: 38px; border-radius: var(--pn-r); background: rgba(255,255,255,.07); color: var(--beige); }
.pn-choicegl .pn-gl { width: 20px; height: 20px; }
.pn-choice[aria-checked="true"] .pn-choicegl { background: rgba(228,216,198,.2); }
:root[data-app][data-theme="light"] .pn-choicegl { background: rgba(36,31,25,.06); color: var(--pn-olive); }
:root[data-app][data-theme="light"] .pn-choice[aria-checked="true"] .pn-choicegl { background: rgba(36,31,25,.12); }
.pn-choice {
  display: grid;
  gap: 6px;
  align-content: start;
  min-width: 0;
  padding: 12px 12px 13px;
  border-radius: var(--pn-r);
  border: 1px solid rgba(255,255,255,.16);
  background: rgba(0,0,0,.22);
  cursor: pointer;
}
.pn-choice b { font-size: 14px; font-weight: 600; line-height: 1.3; }
.pn-choice span { font-size: 12px; line-height: 1.45; color: rgba(242,239,232,.66); }
@media (hover: hover) { .pn-choice:not([aria-disabled="true"]):hover { border-color: rgba(255,255,255,.32); } }
/* the picked card is edged in the same beige the page uses for the pill you are on, twice, so it reads picked at a
   glance and not only against its neighbours */
.pn-choice[aria-checked="true"] { border-color: var(--beige); background: rgba(228,216,198,.12); box-shadow: inset 0 0 0 1px var(--beige); }
.pn-choice[aria-disabled="true"] { opacity: .45; cursor: default; }
@media (max-width: 559px) { .pn-choices { grid-template-columns: minmax(0,1fr); } }
:root[data-app][data-theme="light"] .pn-choice { border-color: rgba(36,31,25,.2); background: var(--pn-face); }
:root[data-app][data-theme="light"] .pn-choice span { color: var(--pn-ink-soft); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-choice:not([aria-disabled="true"]):hover { border-color: rgba(36,31,25,.4); } }
:root[data-app][data-theme="light"] .pn-choice[aria-checked="true"] { border-color: var(--pn-ink); background: var(--pn-fill); box-shadow: inset 0 0 0 1px var(--pn-ink); }
/* THE PRESETS AS THE CALCULATOR'S PACKAGES (2 Nov 2026, the operator: go A): on the New gallery sheet each preset is a
   card in the card's shadow, its glyph square the ink on a faint fill; under a mouse the soft wash; the picked one
   FILLED YELLOW with the ink's words, as "Pick your package" is, in both themes. The cards elsewhere keep their look. */
:root[data-app] .pn-galsheet .pn-choice { border-color: transparent; background: var(--pn-face); box-shadow: var(--pn-sh); }
:root[data-app] .pn-galsheet .pn-choicegl { background: var(--pn-hover); color: var(--pn-ink); }
:root[data-app] .pn-galsheet .pn-choice span { color: var(--pn-muted); }
@media (hover: hover) { :root[data-app] .pn-galsheet .pn-choice:not([aria-disabled="true"]):not([aria-checked="true"]):hover { border-color: transparent; background: var(--pn-soft); } }
:root[data-app] .pn-galsheet .pn-choice[aria-checked="true"] { border-color: transparent; background: var(--pn-y); color: var(--pn-on-y); box-shadow: var(--pn-sh); }
:root[data-app] .pn-galsheet .pn-choice[aria-checked="true"] .pn-choicegl { background: rgba(36,31,25,.1); color: var(--pn-on-y); }
:root[data-app] .pn-galsheet .pn-choice[aria-checked="true"] span { color: #47433e; }

/* THE FIGURES, tiles in the shape the events list already uses for its four (.pn-stats): the number large, its name
   small under it, and a third line for the one figure with a time to say. Two across on a phone, four on a desktop.
   Plain words, no chart. */
.pn-figs { display: grid; grid-template-columns: repeat(2, minmax(0,1fr)); gap: 8px; }
.pn-fig {
  display: grid;
  gap: 3px;
  align-content: start;
  min-width: 0;
  padding: 11px 12px 12px;
  border-radius: var(--pn-r);
  border: 1px solid rgba(255,255,255,.1);
  background: rgba(0,0,0,.22);
}
.pn-fig b { font-size: 20px; font-weight: 500; letter-spacing: 0; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.pn-fig i { font-style: normal; font-size: 9.5px; letter-spacing: .14em; text-transform: uppercase; color: rgba(242,239,232,.52); }
.pn-fig small { font-size: 11.5px; line-height: 1.4; color: rgba(242,239,232,.62); }
@media (min-width: 560px) { .pn-figs { grid-template-columns: repeat(3, minmax(0,1fr)); } }
@media (min-width: 760px) { .pn-figs { grid-template-columns: repeat(4, minmax(0,1fr)); } }
:root[data-app][data-theme="light"] .pn-fig { border-color: var(--pn-line); background: var(--pn-fill); }
:root[data-app][data-theme="light"] .pn-fig i { color: var(--pn-ink-faint); }
:root[data-app][data-theme="light"] .pn-fig small { color: var(--pn-ink-soft); }
/* FIGURES BIG AND LIGHT (2 Nov 2026, the operator: go A): each tile a hairline box on the card, its figure in the display
   face at 300, its name the spaced label in the muted words */
:root[data-app][data-theme] .pn-fig { border-color: var(--pn-line); background: none; }
:root[data-app][data-theme] .pn-fig b { font-family: var(--font-display); font-size: 26px; font-weight: 300; line-height: 1.1; letter-spacing: -.01em; }
:root[data-app][data-theme] .pn-fig i { font-size: 11px; font-weight: 500; letter-spacing: .16em; color: var(--pn-muted); }
:root[data-app][data-theme] .pn-fig small { color: var(--pn-muted); }


/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE CREW (assets/crew.js; the operator, 25 Sep 2026: design D, revised). One clause to a card that fits under the
   header without the page scrolling, its number on every card, a small quiet glyph on the key ones, no pill and no
   coloured border; the exact wording as a sheet; Acknowledge, then Acknowledged with the date and time.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.cw { --cw-sub: rgba(247,242,234,.62); --cw-line: rgba(255,255,255,.12); --cw-fill: rgba(255,255,255,.07); --cw-fig: #e4d8c6; --cw-acc: #f4ff6a;
  --cw-accink: #1d1915; max-width: 440px; margin: 0 auto; padding-top: 14px; }
.cw-col { display: flex; flex-direction: column; gap: 14px; }
.cw-center { align-items: center; text-align: center; padding-top: 40px; }
.cw-k { margin: 6px 0 0; font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--cw-sub); }
.cw-ev { margin: -6px 0 0; font-family: var(--font-display); font-weight: 300; font-size: 26px; letter-spacing: -.01em; text-transform: none; line-height: 1.2;
  text-wrap: balance; }
.cw-lead { margin: 0; font-size: 15px; line-height: 1.5; color: var(--cw-sub); }
.cw-fine { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--cw-sub); }
.cw-msg { margin: 0; font-size: 13.5px; line-height: 1.45; color: var(--st-bad); }
.cw-nav { display: flex; gap: 10px; }
.cw-nav > button { flex: 1; }
.cw-nav .wa-btn, .cw-nav .wa-gl { height: var(--pn-h-main); padding: 0 15px; font-size: 11px; }
/* inside an owner's sheet the pair is the M size of every sheet's Cancel and Save (15 Oct 2026, ONE SIZE A CONTROL) */
:root[data-app] .cw-sheet .cw-nav :is(.wa-btn, .wa-gl) { height: var(--pn-h-main); min-height: var(--pn-h-main); padding: 0 15px; }
@media (pointer: coarse) { :root[data-app] .cw-sheet .cw-nav :is(.wa-btn, .wa-gl) { padding: 0 18px; } }
.cw-links { display: flex; flex-wrap: wrap; gap: 8px; }
.cw-link { align-self: flex-start; background: none; border: 0; padding: 4px 0; color: inherit; font: inherit; font-size: 14px; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.cw-steps { margin: 4px 0; padding: 0; list-style: none; display: grid; gap: 10px; counter-reset: s; }
.cw-steps li { counter-increment: s; display: grid; grid-template-columns: 34px 1fr; gap: 2px 10px; padding: 14px; border-radius: var(--pn-r); background: var(--cw-fill); }
.cw-steps li::before { content: counter(s); grid-row: span 2; width: 30px; height: 30px; border-radius: var(--pn-r); display: grid; place-items: center; font-size: 14px; font-weight: 600; background: var(--cw-fill); }
.cw-steps b { font-size: 15px; } .cw-steps span { font-size: 13px; color: var(--cw-sub); }

/* the reading screen: its height is set by assets/crew.js to what is left under the header */
.cw-read { display: flex; flex-direction: column; gap: 10px; }
/* one row for every card, however many: 19 clauses and a schedule a role since version 3 (6 Oct 2026), 18 cards before */
.cw-dots { display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 3px; flex: none; }
.cw-dots i { height: 4px; border-radius: var(--pn-r); background: var(--cw-fill); }
.cw-dots i.on { background: var(--cw-acc); } .cw-dots i.now { background: currentColor; opacity: .55; }
.cw-count { margin: -4px 0 0; font-size: 12px; color: var(--cw-sub); font-variant-numeric: tabular-nums; flex: none; }
.cw-card { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 16px 16px 14px; border-radius: var(--pn-r);
  display: flex; flex-direction: column; gap: 9px; font-size: 13px; line-height: 1.4; }
.cw-chead { display: flex; align-items: center; gap: 10px; }
.cw-cn { font-family: var(--font-display); font-weight: 200; font-size: 30px; line-height: 1; font-variant-numeric: tabular-nums; letter-spacing: -.01em; flex: none; }
.cw-ch { display: flex; flex-direction: column; gap: 1px; min-width: 0; }
.cw-ch small { display: flex; align-items: center; gap: 6px; font-size: 10.5px; letter-spacing: .1em; text-transform: uppercase; color: var(--cw-sub); }
.cw-ch .cw-gl { width: 14px; height: 14px; flex: none; opacity: .8; }
.cw-ch em { font-style: normal; font-size: 11px; color: var(--cw-fig); }
.cw-card h2 { margin: 2px 0 0; font-size: 19px; font-weight: 600; line-height: 1.2; letter-spacing: -.01em; text-wrap: balance; text-transform: none; }
.cw-line { margin: -3px 0 0; font-size: 14px; line-height: 1.4; }
.cw-facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(72px, 1fr)); gap: 6px; }
.cw-fact { border-radius: var(--pn-r); background: var(--cw-fill); padding: 8px 9px; display: flex; flex-direction: column; gap: 1px; }
/* a figure of words ("12 hours", "2 business days", a schedule's) breaks between them when its box is narrow, never inside one */
.cw-fact b { font-family: var(--font-display); font-size: 18px; font-weight: 500; color: var(--cw-fig); font-variant-numeric: tabular-nums; line-height: 1.15; text-wrap: balance; }
.cw-fact span { font-size: 10.5px; color: var(--cw-sub); line-height: 1.3; }
.cw-pts { margin: 0; padding-left: 16px; display: grid; gap: 4px; font-size: 12.5px; line-height: 1.4; }
.cw-wbtn { margin-top: auto; align-self: flex-start; background: var(--cw-fill); color: inherit; }
.cw-ack { position: relative; overflow: hidden; flex: none; display: flex; gap: 12px; align-items: center; width: 100%; border: 0; border-radius: var(--pn-r); padding: 12px 14px; text-align: left; cursor: pointer;
  background: transparent; color: inherit; font: inherit; box-shadow: inset 0 0 0 1.5px var(--cw-acc); font-size: 15px; font-weight: 600; }
.cw-ack.on { background: var(--cw-fill); box-shadow: inset 0 0 0 1px var(--cw-line); font-weight: 500; font-size: 14px; }
.cw-ack small { display: block; font-size: 12px; color: var(--cw-sub); font-weight: 400; margin-top: 1px; }
/* the reading hold: the button waits, a bar filling behind it, until the card has had time to be read (crew.js) */
.cw-ack.wait { cursor: default; box-shadow: inset 0 0 0 1.5px var(--cw-line); color: var(--cw-sub); }
.cw-ack > span:not(.cw-hold) { position: relative; }
.cw-hold { position: absolute; inset: 0 auto 0 0; width: 0; background: var(--cw-fill); animation: cw-hold linear forwards; }
@keyframes cw-hold { from { width: 0; } to { width: 100%; } }
@media (prefers-reduced-motion: reduce) { .cw-hold { animation: none; } }
.cw-box { flex: none; width: 24px; height: 24px; border-radius: var(--pn-r); box-shadow: inset 0 0 0 1.5px var(--cw-sub); display: grid; place-items: center; }
.cw-ack.on .cw-box, .cw-tick.on .cw-box { background: var(--cw-acc); box-shadow: none; color: var(--cw-accink); }
.cw-box svg { width: 15px; height: 15px; }
.cw-read .cw-nav { flex: none; }

/* ticks, forms, the signature */
.cw-tick { display: flex; gap: 12px; align-items: flex-start; text-align: left; width: 100%; border: 0; border-radius: var(--pn-r); padding: 14px; cursor: pointer;
  background: var(--cw-fill); color: inherit; font: inherit; box-shadow: inset 0 0 0 1px var(--cw-line); }
.cw-tick.on { box-shadow: inset 0 0 0 1px var(--cw-acc); }
.cw-tick small { display: block; font-size: 11.5px; letter-spacing: .06em; text-transform: uppercase; color: var(--cw-sub); margin-bottom: 3px; }
.cw-tick b { font-size: 15px; font-weight: 500; line-height: 1.4; }
.cw-form { display: grid; gap: 12px; }
.cw-fl { display: grid; gap: 6px; }
.cw-fl > span { font-size: 12.5px; color: var(--cw-sub); }
.cw-fh { margin: 8px 0 -2px; font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--cw-sub); }
.cw-gear { display: grid; gap: 6px; }
.cw-gear > span { font-size: 12.5px; color: var(--cw-sub); }
.cw-grow { display: flex; gap: 6px; }
.cw-grow .wa-pwin { min-width: 0; }
.cw-rm { position: relative; flex: none; align-self: center; width: var(--pn-h-act); height: var(--pn-h-act); border: 0; border-radius: var(--pn-r); background: transparent; color: var(--cw-sub); display: grid; place-items: center; cursor: pointer; }
.cw-add svg { width: 12px; height: 12px; }
.cw-rm svg { width: 18px; height: 18px; }
.cw-add { justify-self: start; display: inline-flex; align-items: center; gap: 8px; border: 0; border-radius: var(--pn-r); padding: 8px 13px 8px 10px; cursor: pointer;
  background: var(--cw-fill); color: inherit; font: inherit; font-size: 13.5px; font-weight: 600; }
.cw-add i { width: 22px; height: 22px; border-radius: var(--pn-r); display: grid; place-items: center; background: #e4d8c6; color: #241f19; }
/* a plus for each piece of gear, 44px to a thumb (the real-browser look, 5 Oct 2026: 38px) */
@media (pointer: coarse) { .cw-add { min-height: 44px; } }
.cw-sum { padding: 14px; border-radius: var(--pn-r); display: grid; gap: 4px; }
.cw-sum p { margin: 0; font-size: 14px; color: var(--cw-sub); } .cw-sum b { color: inherit; }
.cw-legal { border-radius: var(--pn-r); padding: 12px 14px; background: var(--cw-fill); display: grid; gap: 8px; }
.cw-legal p { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--cw-sub); }
.cw-legal b { color: inherit; font-weight: 600; }
.cw-seal { width: 72px; height: 72px; border-radius: var(--pn-r); background: var(--cw-acc); color: var(--cw-accink); display: grid; place-items: center; }
.cw-seal svg { width: 34px; height: 34px; }
.cw-note { border-radius: var(--pn-r); padding: 12px 14px; background: var(--cw-fill); font-size: 14px; line-height: 1.45; }
.cw-sec { margin: 8px 0 -4px; font-size: 11px; letter-spacing: .16em; text-transform: uppercase; color: var(--cw-sub); }
.cw-empty { margin: 0; font-size: 14px; color: var(--cw-sub); line-height: 1.5; }

/* a job request */
.cw-req { padding: 18px; border-radius: var(--pn-r); display: flex; flex-direction: column; gap: 10px; }
.cw-req.off { opacity: .7; }
.cw-req h2 { margin: 0; font-size: 21px; font-weight: 600; line-height: 1.2; letter-spacing: -.01em; text-transform: none; color: inherit; }
.cw-rk { margin: 0; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--cw-acc); font-weight: 700; }
.cw-when { display: flex; gap: 10px; align-items: baseline; flex-wrap: wrap; }
.cw-when b { font-size: 17px; } .cw-when span { font-size: 15px; color: var(--cw-sub); font-variant-numeric: tabular-nums; }
.cw-where { margin: -4px 0 0; font-size: 14px; color: var(--cw-sub); }
.cw-rd { margin: 2px 0 0; display: grid; grid-template-columns: 96px 1fr; gap: 8px 10px; font-size: 14px; line-height: 1.4; }
.cw-rd dt { color: var(--cw-sub); } .cw-rd dd { margin: 0; white-space: pre-line; overflow-wrap: anywhere; }
.cw-ans { border-radius: var(--pn-r); background: var(--cw-fill); padding: 12px 14px; display: grid; gap: 3px; font-size: 14px; }
.cw-ans span { color: var(--cw-sub); }
.cw-pill { align-self: flex-start; }

/* the sheets: the exact wording, what was signed, a crew member's details */
.cw-sheet > .wa-card { --cw-sub: rgba(247,242,234,.62); --cw-line: rgba(255,255,255,.12); --cw-fill: rgba(255,255,255,.07); padding: 0; display: flex; flex-direction: column; }
/* the sheet's head stays at the top while the sheet scrolls under it, as the desk's windows do (design audit, 27 Sep
   2026: on a phone the title and the X left the screen); the card has no padding, so it sticks at 0 */
.cw-shead { position: sticky; top: 0; z-index: 1; background: inherit; display: flex; align-items: center; gap: 12px; padding: 16px 18px 12px; border-bottom: 1px solid var(--cw-line); }
.cw-shead b { display: block; font-size: 15px; line-height: 1.3; }
/* the owner's sheets (Add a team member, a member's details and terms) are headed as the Studio's other sheets are, the
   .pn-sheet h2 look (the review of reports 20 and 30, 29 Sep 2026); the small line under a name is the 11px kicker */
.cw-shead h2 { margin: 0; line-height: 1.25; overflow-wrap: anywhere; }
.cw-shead .cw-k { margin: 0; font-size: 11px; }
.cw-shead h2 + .cw-k { margin-top: 4px; }
.cw-x { margin-left: auto; flex: none; width: var(--pn-h-act); height: var(--pn-h-act); border-radius: var(--pn-r); border: 0; background: none; color: inherit; display: grid; place-items: center; cursor: pointer; }
.cw-x svg { width: 16px; height: 16px; }
.cw-words { padding: 14px 18px 22px; }
.cw-words p { margin: 0 0 10px; font-size: 13.5px; line-height: 1.55; }
.cw-words h3 { margin: 18px 0 8px; font-size: 13px; letter-spacing: .06em; text-transform: uppercase; }
.cw-sig { margin-top: 20px; padding-top: 14px; border-top: 1px solid var(--cw-line); }
.cw-sig summary { cursor: pointer; font-size: 13px; margin-bottom: 8px; }
/* when each clause was acknowledged: one line to a clause, its number and short title, then the day and time (27 Sep
   2026: "make these items each line so it's easier to read"); on a narrow phone the time drops under the title */
.cw-acks { margin: 0 0 12px; padding: 0; list-style: none; font-size: 12.5px; line-height: 1.45; color: var(--cw-sub); }
.cw-acks li { display: flex; flex-wrap: wrap; justify-content: space-between; gap: 0 12px; padding: 6px 0; border-top: 1px solid var(--cw-line); }
.cw-acks li:first-child { border-top: 0; }
.cw-an { min-width: 0; overflow-wrap: anywhere; }
.cw-at { margin-left: auto; white-space: nowrap; font-variant-numeric: tabular-nums; }
.cw-sheet .cw-dl { padding: 14px 18px 0; }
.cw-sheet > .wa-card > .wa-gl, .cw-sheet > .wa-card > .cw-fh, .cw-sheet > .wa-card > form, .cw-sheet > .wa-card > .cw-remove { margin-left: 18px; margin-right: 18px; }
.cw-sheet > .wa-card > .cw-remove { margin-bottom: 18px; align-self: flex-start; }
.cw-sheet > .wa-card > .wa-gl { margin-top: 12px; align-self: flex-start; }
/* the sheet's row of buttons (Read what they signed, Download PDF, Emails to them) in line with its words, as the one
   button before it was (the real-browser look, 5 Oct 2026: it ran to the card's edge, against Their terms) */
.cw-sheet > .wa-card > .cw-links { margin: 14px 18px 6px; }

/* the owner's crew card on People */
.cw-crew .cw-btns { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; }
.cw-made { margin: 14px 0 16px; display: grid; gap: 10px; }
.cw-lnk { display: flex; align-items: center; gap: 10px; font-size: 14px; padding: 6px 6px 6px 13px; border-radius: var(--pn-r); background: rgba(255,255,255,.07); border: 1px dashed rgba(255,255,255,.16); }
.cw-lnkt { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.cw-lnkcopy { flex: none; display: inline-flex; align-items: center; justify-content: center; gap: 7px; height: 40px; padding: 0 15px; border: 0; border-radius: var(--pn-r);
  background: rgba(255,255,255,.12); color: inherit; font: inherit; font-size: 11px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; cursor: pointer; }
.cw-lnkcopy .pn-gl { width: 16px; height: 16px; }
@media (hover: hover) { .cw-lnkcopy:hover { background: rgba(255,255,255,.18); } }
@media (pointer: coarse) { .cw-lnkcopy { height: 44px; padding: 0 18px; } }
.pn-crewwith[hidden], .pn-crewonly[hidden] { display: none; }
/* a rate field for each role ticked (5 Oct 2026: "Hourly per role"): hidden while its role is not ticked */
.pn-form label.cw-rate[hidden] { display: none; }
/* the owner's Show beside a team member's masked bank details: a text link, 44px to a thumb as the app's buttons are */
@media (pointer: coarse) { .cw-link.cw-show { min-width: 44px; padding: 12px 0; margin: -12px 0; text-align: left; } }
/* ADD A TEAM MEMBER, and their terms (reports 20 and 21, 29 Sep 2026): the sheet's form, and what they do as ticks, one
   under another, each 44px to a thumb, their heading read as the other boxes' labels are */
.cw-sheet > .wa-card > form.cw-addform { max-width: none; margin-top: 14px; margin-bottom: 18px; }
.cw-addform .pn-sub { margin: 0; }
.cw-addform .pn-msg:empty { min-height: 0; margin: 0; }
.cw-skills { display: grid; gap: 0; min-width: 0; margin: 0; padding: 0; border: 0; }
.cw-skills > legend { margin: 0 0 2px; padding: 0; font-size: 12px; line-height: 1.5; color: rgba(242,239,232,.56); }
:root[data-app][data-theme="light"] .cw-skills > legend { color: var(--pn-ink-soft); }
:root[data-app] .pn-form .cw-skills label.pn-check { display: flex; gap: 9px; font-size: 14px; color: inherit; }
:root[data-app] .pn-form .cw-skills label.cw-later { opacity: .5; cursor: default; }

/* the owner's card on People and team, in the team pages' own colours (its small words had none to read) */
.cw-admin { --cw-sub: rgba(247,242,234,.62); --cw-line: rgba(255,255,255,.12); --cw-fill: rgba(255,255,255,.07); }
:root[data-app][data-theme="light"] .cw-admin { --cw-sub: var(--pn-ink-soft); --cw-line: var(--pn-line); --cw-fill: var(--pn-ground); }

/* light: the same, on paper */
:root[data-app][data-theme="light"] .cw, :root[data-app][data-theme="light"] .cw-sheet > .wa-card {
  --cw-sub: var(--pn-ink-soft); --cw-line: var(--pn-line); --cw-fill: var(--pn-fill); --cw-fig: var(--pn-olive); --cw-acc: var(--pn-olive); --cw-accink: #fffdfa; }
:root[data-app][data-theme="light"] .cw-add i { background: var(--pn-ink); color: var(--pn-face); }
:root[data-app][data-theme="light"] .cw-lnk { background: var(--pn-fill); border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .cw-lnkcopy { background: var(--pn-face); color: var(--pn-ink); box-shadow: 0 0 0 1px var(--pn-line); }
/* THE TEAM'S PAGES AS CALCULATOR CARDS (2 Nov 2026, the operator: go A). The accent is the yellow in both themes, where
   paper had the olive: a ticked box and the seal are filled yellow with ink words, as the calculator's picked; a ticked
   row is picked as the calculator picks, the soft fill in a 1.5px ink ring (a yellow ring alone would vanish on white);
   what a job request asks is a small plain label (9 Nov 2026: no marker pen behind words); a clause's figures are big and light; and the fills inside a card are the
   page's ground set into it. On paper the progress dots done are ink, as yellow bars of 4px would not show on white. */
:root[data-app][data-theme] .cw, :root[data-app][data-theme] .cw-sheet > .wa-card { --cw-acc: var(--pn-y); --cw-accink: var(--pn-on-y); }
:root[data-app][data-theme="light"] .cw, :root[data-app][data-theme="light"] .cw-sheet > .wa-card { --cw-fig: var(--pn-ink); --cw-fill: var(--pn-ground); }
:root[data-app][data-theme] .cw-tick.on { background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); }
:root[data-app][data-theme] .cw-rk { justify-self: start; align-self: flex-start; padding: 0; background: none; color: var(--pn-muted); font-weight: 500; }
:root[data-app][data-theme] .cw-fact b { font-weight: 300; }
:root[data-app][data-theme] .cw-add i { background: var(--pn-y); color: var(--pn-on-y); }
:root[data-app][data-theme="light"] .cw-dots i.on { background: var(--pn-ink); }
:root[data-app][data-theme] .cw-lnk { background: var(--pn-ground); border-color: var(--pn-line); }
/* Acknowledge, once it can be pressed, is the card's one main press: filled yellow with ink words in both themes (a
   yellow ring alone would vanish on white); while it waits it keeps its quiet ring, and the bar filling behind it is the
   hairline's grey on paper, where the ground's own wash would hardly show on the white card */
:root[data-app][data-theme] .cw-ack:not(.on):not(.wait) { background: var(--pn-y); color: var(--pn-on-y); box-shadow: none; }
:root[data-app][data-theme] .cw-ack:not(.on):not(.wait) .cw-box { box-shadow: inset 0 0 0 1.5px var(--pn-on-y); }
:root[data-app][data-theme] .cw-ack:not(.on):not(.wait) small { color: var(--pn-on-y); }
@media (hover: hover) { :root[data-app][data-theme] .cw-ack:not(.on):not(.wait):hover { background: var(--pn-y-press); } }
:root[data-app][data-theme="light"] .cw-hold { background: var(--pn-line); }
/* THE STEPS' FOOT IS THE CALCULATOR'S BAR (2 Nov 2026, the operator: go A): reading and signing the agreement is a flow
   of steps as the price calculator is, so its Back and Next (Start, Save, Sign) sit on the ink bar, the main press the
   yellow with ink words and Back a line button in the bar's own words. A job request's pair stays in its card, and an
   owner's sheet keeps the sheet's own pair. Off, the main press is grey on the ink, never a pale yellow (the standing
   rule for Save). */
:root[data-app][data-theme] .cw .cw-nav:not(.cw-req .cw-nav) { padding: 12px; background: var(--pn-inkbar); color: var(--pn-on-inkbar); }
:root[data-app][data-theme] .cw .cw-nav:not(.cw-req .cw-nav) .wa-btn { background: var(--pn-y); border-color: var(--pn-y); color: var(--pn-on-y); }
:root[data-app][data-theme] .cw .cw-nav:not(.cw-req .cw-nav) .wa-btn:disabled { background: rgba(242,239,232,.14); border-color: transparent; color: rgba(242,239,232,.6); }
@media (hover: hover) { :root[data-app][data-theme] .cw .cw-nav:not(.cw-req .cw-nav) .wa-btn:not(:disabled):hover { background: var(--pn-y-press); filter: none; } }
:root[data-app][data-theme] .cw .cw-nav:not(.cw-req .cw-nav) .wa-gl { background: transparent; border-color: rgba(242,239,232,.38); color: var(--pn-on-inkbar); }
@media (hover: hover) { :root[data-app][data-theme] .cw .cw-nav:not(.cw-req .cw-nav) .wa-gl:not(:disabled):hover { background: rgba(242,239,232,.1); } }
:root[data-app][data-theme] .cw .cw-nav:not(.cw-req .cw-nav) :focus-visible { outline-color: var(--pn-y); }
/* THE TEAM PAGES CHECKED (9 Nov 2026, the operator: "Check team page as well for updated design and ui flow", then "Fix all
   without asking"). On paper a team page's ground is the same colour its fills were, so a box on the page showed only as
   indented words and the agreement's progress as a few dashes. Each is a card on the page, as the signing summary is. */
:root[data-app][data-theme="light"] .cw :is(.cw-steps li, .cw-note, .cw-legal, .cw-add) { background: var(--pn-face); box-shadow: inset 0 0 0 1px var(--pn-line); }
:root[data-app][data-theme="light"] .cw-dots i:not(.on, .now) { background: var(--pn-line); }
/* a person's name in ink, in dark and on paper */
/* a row's badges a little apart when they wrap; on a phone the buttons are always under the words, whichever a row has */
.cw-crew .pn-m .pn-badge { margin-block: 2px; }
@media (max-width: 559px) { .cw-crew > li > .pn-m { flex-basis: 100%; } .cw-crew .cw-btns { justify-content: flex-start; } }
/* the sheet of one person: every block on the sheet's one margin, each heading its own distance from what is above it */
.cw-sheet > .wa-card > .cw-gst { max-width: none; margin: 0 18px; }
.cw-sheet > .wa-card > .cw-gst .cw-fine { margin: 0; }
.cw-sheet > .wa-card > .cw-fh { margin-top: 20px; margin-bottom: 8px; }
/* Change answer starts where the words above it start, and is 44px to a thumb, as the fold in what they signed is */
.cw-ans .cw-link { justify-self: start; }
@media (pointer: coarse) { .cw-ans .cw-link { min-height: 44px; } .cw-sig summary { padding-block: 13px; margin-bottom: 0; } }


/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   EVERY DROPDOWN IN THE APP'S OWN LOOK (assets/frame.js; the operator, 25 Sep 2026: "Any drop downs should be custom
   themed"). The select itself is kept, out of sight, and a button and a list in the app's look stand in for it.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
select.pn-ddnative { position: absolute !important; width: 1px !important; height: 1px !important; margin: 0 !important; padding: 0 !important;
  border: 0 !important; opacity: 0 !important; overflow: hidden; clip-path: inset(50%); pointer-events: none; }
.pn-ddbtn { display: flex; align-items: center; gap: 10px; text-align: left; cursor: pointer; font-family: var(--font-text); color: inherit;
  letter-spacing: normal; text-transform: none; }
/* in a form, the chosen value is set like what is typed in the boxes beside it, not like the label above it */
.pn-ddbtn.wa-pwin { color: #fff; font-size: 14px; }
.pn-ddbtn.pn-ddph .pn-ddval { color: var(--pn-ph); }
.pn-ddbtn:disabled { cursor: default; opacity: .5; }
.pn-ddval { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-ddbtn > svg { width: 12px; height: 8px; flex: none; opacity: .7; transition: transform .16s ease; }
.pn-ddbtn[aria-expanded="true"] > svg { transform: rotate(180deg); }
/* ONE LIST LOOK (design audit, 27 Sep 2026): a dropdown's list, the floating menu (.pn-pop, which the gallery's Sort
   and More open) and the name picker are all 12px corners, 6px in from the edge, rows of 40px (44 on a touch screen)
   with 8px corners, the chosen row at 500 with its tick at the far end in the words' own colour */
.pn-ddmenu { position: fixed; z-index: 95; display: flex; flex-direction: column; padding: 6px; overflow-y: auto; overscroll-behavior: contain;
  border-radius: var(--pn-r); background: var(--pn-face-2, #2c2721); border: 1px solid var(--pn-line); box-shadow: var(--pn-sh);
  color: #f7f2ea; font-family: var(--font-text); animation: pn-ddin .14s ease-out; }
@keyframes pn-ddin { from { opacity: 0; transform: translateY(-4px); } }
.pn-ddopt { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 40px; padding: 8px 12px; border: 0; border-radius: var(--pn-r);
  background: transparent; color: inherit; font: inherit; font-size: 14px; text-align: left; cursor: pointer; }
@media (pointer: coarse) { .pn-ddopt { min-height: 44px; } }
.pn-ddopt:hover, .pn-ddopt:focus-visible { background: rgba(255,255,255,.08); outline: none; }
.pn-ddopt:focus-visible { outline: 2px solid; outline-offset: -2px; }
/* the picked row is washed and ticked, never bold (the website's pickers; 2 Nov 2026, the operator: go A) */
.pn-ddopt[aria-selected="true"] { background: var(--pn-soft); font-weight: inherit; }
.pn-ddgroup { padding: 10px 12px 4px; font-size: 10.5px; letter-spacing: .16em; text-transform: uppercase; color: rgba(242,239,232,.5); }
.pn-ddgroup:first-child { padding-top: 4px; }
.pn-ddopt:disabled { opacity: .4; cursor: default; }
/* the tick after the words, at the row's far end, in the words' own colour, as the floating menu's and the gallery
   sort's (design audit, 27 Sep 2026); frame.js writes it first, so order puts it last */
.pn-ddtick { order: 2; width: 18px; height: 18px; flex: none; margin-left: auto; display: grid; place-items: center; color: inherit; }
.pn-ddtick svg { width: 16px; height: 16px; }
@media (prefers-reduced-motion: reduce) { .pn-ddmenu { animation: none; } .pn-ddbtn > svg { transition: none; } }
/* A VENUE FROM GOOGLE (26 Sep 2026): the place's name, its street and suburb under it, and Google named at the foot */
.pn-placeopt { flex-direction: column; align-items: flex-start; gap: 1px; padding: 8px 12px; }
.pn-placeopt b { font-size: 14px; font-weight: 600; }
.pn-placeopt small { font-size: 12px; color: rgba(242,239,232,.6); }
.pn-placeopt[aria-selected="true"] { background: rgba(255,255,255,.08); }
.pn-placeby { margin: 4px 0 0; padding: 6px 12px 2px; border-top: 1px solid rgba(255,255,255,.08); font-size: 11px; color: rgba(242,239,232,.5); }
:root[data-app][data-theme="light"] .pn-placeopt small, :root[data-app][data-theme="light"] .pn-placeby { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-placeopt[aria-selected="true"] { background: var(--pn-fill); }
:root[data-app][data-theme="light"] .pn-placeby { border-top-color: var(--pn-line); }
/* A DATE FROM A CALENDAR (26 Sep 2026: "have a date dropdown box"): the field with its calendar glyph, and the month under
   it in the dropdown's own panel */
.pn-datewrap { position: relative; display: block; }
.pn-datein { width: 100%; padding-right: 44px; cursor: pointer; caret-color: transparent; }
.pn-dategl { position: absolute; right: 14px; top: 50%; width: 18px; height: 18px; margin-top: -9px; opacity: .7; pointer-events: none; }
/* the same 334px as before, edge to edge, and never wider than the screen less 8px each side (report 61, 1 Oct 2026: the
   Desk's dates open it on a phone, down to 320px wide; frame.js S.calendar holds it 8px in from either edge) */
.pn-cal { box-sizing: border-box; width: 334px; max-width: calc(100vw - 16px); padding: 10px 10px 8px; }
.pn-calhead { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 0 0 8px; }
.pn-calhead b { font-size: 15px; font-weight: 600; }
.pn-calnav { display: grid; place-items: center; width: 40px; height: 40px; padding: 0; border: 0; border-radius: var(--pn-r); background: none; color: inherit; cursor: pointer; }
.pn-calnav .pn-gl { width: 18px; height: 18px; }
.pn-calgrid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 2px; }
.pn-calwd { padding: 4px 0 6px; font-size: 10.5px; font-weight: 600; letter-spacing: .08em; text-transform: uppercase; text-align: center; color: rgba(242,239,232,.5); }
.pn-calday { height: 40px; padding: 0; border: 0; border-radius: var(--pn-r); background: none; color: inherit; font: inherit; font-size: 14px;
  font-variant-numeric: tabular-nums; cursor: pointer; }
.pn-calday.pn-calout { color: var(--pn-ph); }
.pn-calday.pn-caltoday { box-shadow: inset 0 0 0 1px var(--pn-ink); }
/* the picked day filled in the yellow with the ink's figure, in both themes, as the website's month grid (2 Nov 2026, the
   operator: go A); never bold */
.pn-calday[aria-selected="true"] { background: var(--pn-y); color: var(--pn-on-y); font-weight: inherit; box-shadow: none; }
/* today keeps its ring once picked, in the yellow's ink, as the website's calculator keeps it */
.pn-calday.pn-caltoday[aria-selected="true"], :root[data-app][data-theme="light"] .pn-calday.pn-caltoday[aria-selected="true"] { box-shadow: inset 0 0 0 1px var(--pn-on-y); }
@media (hover: hover) { .pn-calnav:hover, .pn-calday:hover { background: var(--pn-hover); } .pn-calday[aria-selected="true"]:hover { background: var(--pn-y-press); } }
.pn-calday:focus-visible, .pn-calnav:focus-visible { outline-offset: -2px; }
.pn-calfoot { display: flex; justify-content: space-between; margin-top: 6px; padding-top: 6px; border-top: 1px solid rgba(255,255,255,.08); }
.pn-calfoot button { min-height: 40px; padding: 0 10px; border: 0; border-radius: var(--pn-r); background: none; color: rgba(242,239,232,.75); font: inherit; font-size: 14px; cursor: pointer; }
@media (hover: hover) { .pn-calfoot button:hover { background: rgba(255,255,255,.08); color: #f7f2ea; } }
@media (pointer: coarse) { .pn-calday { height: 42px; } .pn-calnav { width: 44px; height: 44px; } .pn-calfoot button { min-height: 44px; } }
/* EVERY DAY 44px TO A THUMB (the real-browser look at a job request's Required by, 5 Oct 2026: 43 by 42 on a 375px
   phone): a day as tall as the arrows, and no gap between the days of a week, so each is the week's width over seven */
@media (pointer: coarse) { .pn-calday { height: 44px; } .pn-calgrid { column-gap: 0; } }
:root[data-app][data-theme="light"] .pn-calwd { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-calday.pn-calout { color: var(--pn-ph); }
:root[data-app][data-theme="light"] .pn-calday.pn-caltoday { box-shadow: inset 0 0 0 1px var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-calday[aria-selected="true"] { background: var(--pn-y); color: var(--pn-on-y); }
:root[data-app][data-theme="light"] .pn-calfoot { border-top-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-calfoot button { color: var(--pn-ink-soft); }
@media (hover: hover) {
  :root[data-app][data-theme="light"] .pn-calnav:hover, :root[data-app][data-theme="light"] .pn-calday:hover,
  :root[data-app][data-theme="light"] .pn-calfoot button:hover { background: var(--pn-fill); color: var(--pn-ink); }
  :root[data-app][data-theme="light"] .pn-calday[aria-selected="true"]:hover { background: var(--pn-y-press); color: var(--pn-on-y); }
}
:root[data-app][data-theme="light"] .pn-ddbtn.wa-pwin { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-ddbtn.pn-ddph .pn-ddval { color: var(--pn-ph); }
:root[data-app][data-theme="light"] .pn-ddmenu { background: var(--pn-face); border-color: var(--pn-line); color: var(--pn-ink); box-shadow: var(--pn-sh); }
:root[data-app][data-theme="light"] .pn-ddopt:hover, :root[data-app][data-theme="light"] .pn-ddopt:focus-visible { background: var(--pn-hover); }
:root[data-app][data-theme="light"] .pn-ddopt[aria-selected="true"] { background: var(--pn-soft); }
:root[data-app][data-theme="light"] .pn-ddgroup { color: var(--pn-ink-soft); }

/* THE SIGN-IN CARD IS BLACK IN LIGHT AND DARK ALIKE (the operator, 25 Sep 2026: "Sign in in light mode is broken", then
   "put the black card for light and dark and just change the back colour depending on the mode so we don't have to
   change the logo", and "Stop changing my logo to colours I never authorised"). The logo sits on the card and is
   never recoloured; only the page behind the card follows light or dark. */
:root[data-app][data-theme="light"] .wa-center .wa-gcard { background: #241f1a; border-color: rgba(255,255,255,.1);
  box-shadow: none; color: #f2efe8; }
:root[data-app][data-theme="light"] .wa-center .wa-gcard .wa-k { color: var(--beige); }
:root[data-app][data-theme="light"] .wa-center .wa-gcard .wa-kd { color: rgba(228,216,198,.62); }
:root[data-app][data-theme="light"] .wa-center .wa-gcard .wa-ev { color: #f7f2ea; }
:root[data-app][data-theme="light"] .wa-center .wa-gcard .wa-xp { color: rgba(242,239,232,.8); }
:root[data-app][data-theme="light"] .wa-center .wa-gcard .wa-msg { color: var(--beige2); }
:root[data-app][data-theme="light"] .wa-center .wa-gcard .wa-btn { background: var(--beige); color: var(--ink); }

/* first and last name, side by side (the operator, 25 Sep 2026: "split their name into first and last name") */
.pn-form .pn-names { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
@media (max-width: 380px) { .pn-form .pn-names { grid-template-columns: 1fr; } }

/* A GALLERY'S LINK in the New gallery sheet: the gallery address, then its end, locked until the pencil is pressed */
/* as tall as the boxes and the button beside it, 40px and 44 on a touch screen, in the boxes' 14px (design audit, 27
   Sep 2026: it was 48px in 15px); and it may shrink to its column, so the host gives way in dots as it says below */
.pn-glink { display: flex; align-items: center; gap: 2px; min-width: 0; height: var(--pn-h-main); padding: 0 0 0 14px; border-radius: var(--pn-r); border: 1px solid var(--pn-edge, rgba(255,255,255,.18));
  background: rgba(0,0,0,.24); font-size: 14px; }
/* the address before the link is the photobooth host and its /g/ (27 Sep 2026), longer than a phone has room for: it
   gives way, ending in dots, and the part the client types is never narrower than a short link */
.pn-glhost { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: rgba(242,239,232,.55); white-space: nowrap; }
.pn-glslug { flex: 1 0 7em; min-width: 0; height: 100%; border: 0; background: transparent; color: #fff; font: inherit; font-size: 14px; outline: none; padding: 0; }
.pn-glslug[readonly] { cursor: default; }
/* THE TIME ZONE CARD (frame.js zoneCard): while this device is set to a zone with another time than the studio's. It
   sits bottom left, over nothing that matters, until OK. */
.pn-tznote { position: fixed; left: 16px; bottom: max(16px, env(safe-area-inset-bottom)); z-index: 70; display: flex; align-items: center; gap: 14px;
  max-width: min(420px, calc(100% - 32px)); padding: 12px 12px 12px 16px; border-radius: var(--pn-r); background: rgba(30,26,22,.96);
  border: 1px solid rgba(255,255,255,.14); color: #f2efe8; font-size: 14px; line-height: 1.45; box-shadow: none; }
.pn-tznote p { margin: 0; }
.pn-tznote .wa-gl { flex: none; }
:root[data-app][data-theme="light"] .pn-tznote { background: #fffdf9; border-color: rgba(36,31,25,.14); color: #241f19; box-shadow: none; }
/* as the live notices are (2 Nov 2026, the operator: go A): the card's face over the page, its 1px line
   carrying its edge, solid, in both themes */
:root[data-app][data-theme] .pn-tznote { background: var(--pn-face-2); border-color: transparent; color: var(--pn-ink); box-shadow: var(--pn-sh); }
/* a gallery's page heading: Photos on the left, the Sort glyph on the right (its list is popMenu's) */
.pn-ghead { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin-bottom: 10px; }
.pn-ghead h2 { margin: 0; }
/* the New gallery sheet's boxes run the sheet's whole width, so a long event's link reads to its end (25 Sep 2026) */
.pn-galsheet .pn-form { max-width: none; }
/* Quick add on the Galleries page: the button stays beside its shoot on a phone, as Open does on the list below */
.pn-quick .pn-list .pn-m { flex: 1 1 0; min-width: 0; }
/* DISMISS (29 Sep 2026, report 15): the cross beside Make gallery, the same pill and height (44px to a thumb), square */
.pn-quickacts { display: inline-flex; flex: none; align-items: center; gap: 6px; }
:root[data-app][data-theme] .pn-quickx { align-self: center; width: var(--pn-h-act); min-height: var(--pn-h-act); height: var(--pn-h-act); padding: 0; border-color: transparent; background: none; }
@media (hover: hover) { :root[data-app][data-theme] .pn-quickx:hover { background: var(--pn-hover); } }
/* QUICK ADD FOLDS (report 238, 27 Oct 2026): its label a button the card's width, in the label's own small capitals,
   the count and the caret at its right, the caret turned while open; 44px to a thumb */
.pn-card h2.pn-quickh { margin: 0; }
.pn-quickfold { display: flex; align-items: center; gap: 8px; width: 100%; min-height: 32px; margin: 0; padding: 0; border: 0; background: none;
  color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit; text-align: left; cursor: pointer; }
@media (pointer: coarse) { .pn-quickfold { min-height: 44px; } }
.pn-quickfold .pn-quickchev { flex: none; width: 18px; height: 18px; margin-left: auto; opacity: .6; transition: transform .2s ease; }
.pn-quickfold[aria-expanded="true"] .pn-quickchev { transform: rotate(180deg); }
@media (hover: hover) { .pn-quickfold:hover .pn-quickchev { opacity: 1; } }
@media (prefers-reduced-motion: reduce) { .pn-quickfold .pn-quickchev { transition: none; } }
.pn-quickfold:focus-visible { outline-offset: 2px; border-radius: var(--pn-r); }
.pn-quickin { margin-top: 6px; }
/* the counts beside a gallery card's heading, Quick add's and People waiting's, are the yellow tag (2 Nov 2026, the operator: go A), as the
   Jobs headings' are */
:root[data-app] :is(.pn-quickfold, .pn-gwait h2) :is(.pn-jbn, .pn-count) { background: var(--pn-y); color: var(--pn-on-y); }
.pn-quickin[hidden] { display: none; }
/* open, it is a field with the keyboard: the ink's border and its 1px ring (2 Nov 2026, the operator: go A) */
.pn-glink.pn-glopen { border-color: var(--pn-ink); box-shadow: 0 0 0 1px var(--pn-ink); }
.pn-glpen { flex: none; width: var(--pn-h-main); height: 100%; border: 0; border-radius: var(--pn-r); background: transparent; color: rgba(242,239,232,.7); display: grid; place-items: center; cursor: pointer; }
/* the only way to change the link, so a thumb's size on a touch screen; it may run a pixel over the box's edge, where it
   is clear */
.pn-glpen:hover { background: rgba(255,255,255,.08); }
.pn-glopen .pn-glpen { display: none; }
.pn-glpen .pn-gl { width: 16px; height: 16px; }
.pn-glsay { display: block; margin-top: 6px; text-transform: none; letter-spacing: normal; }
:root[data-app][data-theme="light"] .pn-glink { background: var(--pn-face); border-color: var(--pn-edge); }
:root[data-app][data-theme="light"] .pn-glhost { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-glslug { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-glpen { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-glpen:hover { background: var(--pn-fill); }

/* THE SIGN-IN CARD, GRANDER (the operator, 25 Sep 2026: "Have the sign in card a bit more grand/premium, spaced out
   up/down", then "Give it more padding and decrease font size it looks cheap"). Small, quiet type with wide
   tracking, a lot of air around it, and a fine rule under the logo; the logo itself only given room, its file and
   its colours exactly as they are. App pages only. */
:root[data-app] .wa-center .wa-gcard { max-width: 460px; padding: 50px 44px 50px; border-radius: var(--pn-r); }
:root[data-app] .wa-center .wa-gcard .wa-lgbox { position: relative; margin-bottom: 0; padding-bottom: 28px; }
:root[data-app] .wa-center .wa-gcard .wa-lgbox::after { content: ""; position: absolute; left: 50%; bottom: 0; width: 36px; height: 1px;
  transform: translateX(-50%); background: rgba(228,216,198,.3); }
:root[data-app] .wa-center .wa-gcard .wa-signlogo { display: block; width: 118px; height: auto; }
:root[data-app] .wa-center .wa-gcard .wa-k { font-size: 9.5px; letter-spacing: .32em; }
:root[data-app] .wa-center .wa-gcard .wa-ev { margin-top: 0; font-size: 19px; font-weight: 300; letter-spacing: .34em; }
:root[data-app] .wa-center .wa-gcard .wa-msg { min-height: 0; margin: 24px 0 0; font-size: 12.5px; }
:root[data-app] .wa-center .wa-gcard .wa-xp { max-width: 40ch; margin-top: 16px; font-size: 12.5px; line-height: 1.7; }
:root[data-app] .wa-center .wa-gcard .wa-open, :root[data-app] .wa-center .wa-gcard .wa-open.pn-mt18 { margin-top: 28px !important; height: 46px;
  font-size: 10.5px; letter-spacing: .24em; width: auto; min-width: 176px; padding: 0 28px; justify-self: center; }
/* narrower (the operator, 26 Sep 2026: "make button narrower"): 176 px, the G and SIGN IN with room either side */
@media (max-width: 420px) { :root[data-app] .wa-center .wa-gcard { padding: 44px 26px 44px; } }
:root[data-app] .wa-center .wa-gcard .wa-open { gap: 12px; }
:root[data-app] .wa-center .wa-gcard .wa-gg { width: 17px; height: 17px; flex: none; }
/* the sign-in page's heading, for a screen reader only: the button already says Sign in on screen */
.wa-vh { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0; }
/* STUDIO on the sign-in card, in the header's own yellow small capitals, between the rule and the button */
:root[data-app] .wa-center .wa-gcard .wa-signtag { margin: 24px 0 0; font-size: 10.5px; letter-spacing: .34em; text-transform: uppercase; color: var(--moon); }
:root[data-app] .wa-center .wa-gcard .wa-signtag + .wa-msg { margin-top: 18px; }
:root[data-app] .wa-center .wa-gcard .wa-signtag ~ .wa-open, :root[data-app] .wa-center .wa-gcard .wa-signtag ~ .wa-open.pn-mt18 { margin-top: 24px !important; }
/* THE G AND THE WORDS CENTRED TOGETHER (the operator, 25 Sep 2026: "desktop button is not aligned", with a crop of the
   pair sitting left of the middle). An earlier spacer centred the words alone and pushed the pair left; it went, and
   the card itself is no longer 8 px left of the window (the scrollbar room, above). Wide tracking leaves space after
   the last letter, which is taken back so STUDIO and SIGN IN are measured on their letters. */
:root[data-app] .wa-center .wa-gcard .wa-open > span { margin-right: -.24em; }
:root[data-app] .wa-center .wa-gcard .wa-signtag { padding-left: .34em; }
/* LESS BARE (the operator, 25 Sep 2026: "Still too bare"): a quiet greeting under STUDIO, and a faint warm light
   behind the top of the card. The logo is untouched: the light sits behind it, on the card. */
/* flat since 28 Sep 2026 ("yes remove gradient everywhere"): the sign-in card is one dark colour, the logo still on it */
:root[data-app] .wa-center .wa-gcard { background-image: none; }
:root[data-app][data-theme="light"] .wa-center .wa-gcard { background: #241f1a; }
:root[data-app] .wa-center .wa-gcard .wa-signhi { margin: 12px 0 0; font-family: var(--font-display); font-weight: 300; font-size: 22px; line-height: 1.25;
  letter-spacing: .01em; color: #f7f2ea; }
:root[data-app] .wa-center .wa-gcard .wa-signhi ~ .wa-open, :root[data-app] .wa-center .wa-gcard .wa-signhi ~ .wa-open.pn-mt18 { margin-top: 28px !important; }
:root[data-app] .wa-center .wa-gcard .wa-msg { margin: 16px 0 0; line-height: 1.55; }
:root[data-app] .wa-center .wa-gcard .wa-msgline { display: block; }
/* ON A PHONE, SHORTER (the operator, 25 Sep 2026: "Mobile card too tall it looks tacky"): a smaller logo and tighter
   spacing, so the card is a compact block rather than a slab down the screen. The logo's file and colours unchanged. */
@media (max-width: 480px) {
  :root[data-app] .wa-center .wa-gcard { max-width: 330px; padding: 34px 24px 32px; border-radius: var(--pn-r); }
  :root[data-app] .wa-center .wa-gcard .wa-signlogo { width: 88px; }
  :root[data-app] .wa-center .wa-gcard .wa-lgbox { padding-bottom: 20px; }
  :root[data-app] .wa-center .wa-gcard .wa-signtag { margin-top: 18px; font-size: 10px; }
  :root[data-app] .wa-center .wa-gcard .wa-signhi { margin-top: 8px; font-size: 19px; }
  :root[data-app] .wa-center .wa-gcard .wa-signhi ~ .wa-open, :root[data-app] .wa-center .wa-gcard .wa-signhi ~ .wa-open.pn-mt18 { margin-top: 22px !important; }
  :root[data-app] .wa-center .wa-gcard .wa-open { height: 44px; min-width: 168px; }
  :root[data-app] .wa-center .wa-gcard .wa-msg { margin-top: 12px; font-size: 12px; }
}
/* NO SCROLL ON THE SIGN-IN PAGE (27 Oct 2026, the operator on an iPhone: "Don't make the log in page scrollable
   there's no reason to. Just scale it down if the screen doesn't fit"). The page is the screen as seen, its bars
   showing (dvh: Safari's 100vh is the screen with its bars hidden, so the old min-height scrolled by the bars), and
   nothing scrolls; on a short screen the card and the links under it are drawn smaller in steps, never cut. */
:root[data-app]:has(.wa-signlogo), :root[data-app]:has(.wa-signlogo) body { height: 100%; min-height: 0; overflow: hidden; overscroll-behavior: none; }
:root[data-app] .wa-center:has(.wa-signlogo) { height: 100vh; height: 100dvh; min-height: 0; overflow: hidden; box-sizing: border-box; }
@media (max-height: 640px) { :root[data-app] .wa-center:has(.wa-signlogo) > * { zoom: .88; } }
@media (max-height: 560px) { :root[data-app] .wa-center:has(.wa-signlogo) > * { zoom: .76; } }
@media (max-height: 480px) { :root[data-app] .wa-center:has(.wa-signlogo) > * { zoom: .64; } }
@media (max-height: 400px) { :root[data-app] .wa-center:has(.wa-signlogo) > * { zoom: .52; } }
/* THE SIGN-IN PAGE IN LIGHT: BALLROOM LIGHTS (option A of four; the operator, 25 Sep 2026: "Go A for now we'll change
   later"). Soft, out-of-focus warm lights on a stone ground, the way a lens sees a ball behind the subject, behind the
   black card. Light mode only, the sign-in page only (.wa-center is only ever the sign-in page). */
:root[data-app][data-theme="light"] .wa-center { isolation: isolate; background: #e8ddcc; }
:root[data-app][data-theme="light"] .wa-center::before { content: ""; position: fixed; inset: -12px; z-index: -1; pointer-events: none; filter: blur(6px);
  background:
    radial-gradient(circle at 12% 18%, rgba(255,246,222,.95) 0 34px, transparent 70px),
    radial-gradient(circle at 84% 14%, rgba(248,232,196,.9) 0 48px, transparent 96px),
    radial-gradient(circle at 70% 78%, rgba(255,240,210,.85) 0 60px, transparent 120px),
    radial-gradient(circle at 20% 82%, rgba(236,214,172,.8) 0 42px, transparent 90px),
    radial-gradient(circle at 46% 6%, rgba(244,255,106,.28) 0 26px, transparent 64px),
    radial-gradient(circle at 92% 52%, rgba(252,236,204,.8) 0 30px, transparent 70px),
    radial-gradient(circle at 6% 50%, rgba(244,226,190,.8) 0 28px, transparent 66px),
    radial-gradient(120% 90% at 50% 50%, transparent 55%, rgba(120,98,70,.18)); }
/* THE HEADER STAYS PUT (the operator, 25 Sep 2026: "Header keeps moving around when different tab clicked"). A short
   page has no scrollbar and a long one has, so the page's width, and everything centred in it, jumped 15 px sideways
   between tabs. The scrollbar's room is kept on every app page, scrolling or not. (Not overflow on html, which would
   make it a scroll container and stop the sticky header; scrollbar-gutter does neither.) */
:root[data-app] { scrollbar-gutter: stable; }
/* NO BOUNCE PAST THE TOP OR THE FOOT (28 Oct 2026, the operator on an iPhone, the header pulled down off a dark gap:
   "Disable scrolling past the top like how it does on the website"). Safari's rubber band is left out on every app
   page, as the website's pages leave it out; its pull to refresh goes with it. Nothing else changes: html still
   scrolls the page, so the sticky header stays. */
:root[data-app], :root[data-app] body { overscroll-behavior-y: none; }
/* ...except on the sign-in page (the operator, 25 Sep 2026: "desktop button is not aligned"). It never scrolls, so the
   kept room was a blank strip down the right that put the card, and its button, 8 px left of the window's middle. */
:root[data-app]:has(.wa-center .wa-gcard) { scrollbar-gutter: auto; }
/* NO ZOOM WHEN A BOX IS PRESSED ON A PHONE (the operator, 25 Sep 2026: "Don't zoom in on mobile when a text field is
   clicked"). iPhone Safari zooms into any box whose text is smaller than 16px, so on a phone none is: the page keeps
   its size and pinching still works, which a viewport that forbade zooming would take away. */
@media (max-width: 760px) {
  :root[data-app] input:not([type="checkbox"]):not([type="radio"]):not([type="range"]), :root[data-app] textarea, :root[data-app] select,
  :root[data-app] .pn-glslug { font-size: 16px; }
}
/* the app-look dropdown is a button, so it need not be 16px to stop an iPhone zooming: its value is plain words, 14px at 400,
   on the field's edge (9 Nov 2026) */
@media (pointer: coarse) { :root[data-app] .pn-ddbtn.wa-pwin { font-size: 14px; font-weight: 400; border-color: var(--pn-edge); } }
:root[data-app] .pn-ddbtn.pn-bksmall { height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0 10px; font-size: 12px; }

/* A GALLERY'S PAGE IN TABS, AND ITS SETTINGS (assets/app.js drawGallery, settingsTab; the operator, 25 Sep 2026: "add
   these features into gallery", with Pixieset's collection page as the picture). The tabs under the title, More in
   the corner, and Settings as a list of sections beside one card of switches. On a phone the sections are a row. */
.pn-ghead2 { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; }
.pn-ghead2 .pn-sub { margin-top: 2px; }
.pn-morebtn { gap: 6px; }
.pn-morebtn .pn-caret { width: 11px; height: 8px; }
.pn-soonitem { opacity: .5; cursor: default; }
.pn-soontag { margin-left: auto; font-style: normal; }
.pn-dangeritem { color: var(--st-bad); border-top: 1px solid var(--pn-line, rgba(255,255,255,.08)); border-radius: var(--pn-r); margin-top: 4px; }

.pn-gset { display: grid; grid-template-columns: 200px minmax(0, 1fr); gap: 14px; align-items: start; }
.pn-gsetnav { display: grid; gap: 2px; padding: 6px; border-radius: var(--pn-r); background: var(--pn-face); border: 1px solid transparent; box-shadow: var(--pn-sh); }
.pn-onoff { margin-left: auto; font-style: normal; }
.pn-gsetpane h2 { display: flex; align-items: center; gap: 10px; }
.pn-linkbtn { margin-left: auto; display: inline-flex; align-items: center; justify-content: center; min-height: 32px; padding: 0 4px; border: 0; background: transparent;
  color: var(--pn-ink); font: inherit; font-size: 12px; font-weight: 500; letter-spacing: 0; text-transform: none; cursor: pointer; text-decoration: underline;
  text-underline-offset: 3px; }
@media (max-width: 759px) {
  .pn-gset { grid-template-columns: minmax(0, 1fr); }
  .pn-gsetnav { display: flex; flex-wrap: wrap; }
  .pn-onoff { margin-left: 2px; }
}

.pn-srow { display: flex; align-items: flex-start; justify-content: space-between; gap: 16px; padding: 14px 0; border-top: 1px solid var(--pn-line, rgba(255,255,255,.07)); }
.pn-sblock { padding: 14px 0; border-top: 1px solid var(--pn-line, rgba(255,255,255,.07)); }
.pn-gsetpane h2 + .pn-srow, .pn-gsetpane h2 + .pn-sblock { border-top: 0; padding-top: 4px; }
.pn-sword { min-width: 0; }
.pn-sword b, .pn-sblock > b { font-size: 14px; font-weight: 600; color: var(--pn-ink, #f2efe8); }
.pn-sword .pn-note, .pn-sblock > .pn-note { margin: 3px 0 0; }
.pn-srowin { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 8px; }
.pn-srowin .wa-pwin { flex: 1 1 200px; min-width: 0; width: auto; }
.pn-srowin .pn-glink { flex: 1 1 260px; min-width: 0; }
.pn-srowin .pn-pinin { flex: 0 0 110px; letter-spacing: .3em; text-align: center; font-variant-numeric: tabular-nums; }
.pn-srowin .pn-numin { flex: 0 0 140px; font-variant-numeric: tabular-nums; }
.pn-soon { opacity: .55; }
.pn-soon .pn-soontag { margin-left: 6px; }
.pn-dim { opacity: .5; }

/* the switch: a button with role="switch", its state in aria-checked, so a screen reader hears On or Off */
.pn-switch { position: relative; flex: none; width: 42px; height: 24px; margin-top: 2px; border: 0; border-radius: 999px;
  background: rgba(255,255,255,.16); cursor: pointer; transition: background-color 140ms ease; }
.pn-knob { position: absolute; top: 3px; left: 3px; width: 18px; height: 18px; border-radius: 50%; background: #f2efe8;
  box-shadow: 0 0 0 1px var(--pn-line, #3d3832); transition: transform 140ms ease; }
.pn-switch[aria-checked="true"] { background: var(--beige); }
.pn-switch[aria-checked="true"] .pn-knob { transform: translateX(18px); background: #221d18; }
.pn-switch:disabled { cursor: default; }
/* HELD ON (a clubs gallery's Find my photos, 29 Sep 2026): dimmed as a Coming later row is, so it does not read as a
   switch to press; still focusable, and a press is told why (the Coming later rows use disabled, so this never dims them twice) */
.pn-switch[aria-disabled="true"] { opacity: .55; cursor: default; }
@media (prefers-reduced-motion: reduce) { .pn-switch, .pn-knob { transition: none; } }

/* the tags box is as tall as a box, 40px and 44 on a touch screen (design audit, 27 Sep 2026: it was 48) */
:root[data-app] .wa-pwin.wa-no, :root[data-app] .wa-pwin.wa-no:focus { border-color: var(--st-warn); }
:root[data-app][data-theme="light"] .wa-pwin.wa-no, :root[data-app][data-theme="light"] .wa-pwin.wa-no:focus { border-color: var(--st-warn); box-shadow: 0 0 0 3px var(--st-warn-bg); }
.pn-tags2 { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 4px 4px 4px 10px; min-height: 40px; border-radius: var(--pn-r); border: 1px solid var(--pn-edge, rgba(255,255,255,.18)); background: rgba(0,0,0,.24); }
/* the box is the field, so it takes the field's focus ring when its input has the focus (UI audit, 30 Sep 2026) */
.pn-tags2:focus-within { border-color: var(--pn-ink); box-shadow: 0 0 0 1px var(--pn-ink); }
.pn-tag2 { display: inline-flex; align-items: center; gap: 4px; box-sizing: border-box; max-width: 100%; height: 28px; padding: 0 2px 0 10px; border: 1px solid var(--pn-p-line);
  border-radius: var(--pn-r); background: rgba(255,255,255,.1); font-size: 12px; font-weight: 400; line-height: 1; }
.pn-tag2w { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-tag2 button { display: grid; place-items: center; flex: none; padding: 0; width: 24px; height: 24px; border: 0; border-radius: var(--pn-r); background: transparent; color: inherit; font-size: 14px; cursor: pointer; }
.pn-tag2 button :is(.i, .pn-gl) { width: 14px; height: 14px; }
.pn-tagin { flex: 1 1 120px; min-width: 0; height: 30px; border: 0; background: transparent; color: inherit; font: inherit; font-size: 14px; outline: none; padding: 0 6px; }
.pn-check, .pn-radio { display: flex; align-items: center; gap: 9px; min-height: 36px; font-size: 14px; cursor: pointer; }
/* on a touch screen: the tag's x takes a 44px press around its small circle, without making the pill any taller, and a
   tick row is a thumb tall (design audit, 27 Sep 2026) */
@media (pointer: coarse) {
  .pn-tags2 { min-height: 44px; }
  .pn-tag2 button { width: 44px; height: 44px; margin: -8px -8px -8px -4px; }
  .pn-check, .pn-radio { min-height: 44px; }
}
.pn-radio input { width: 17px; height: 17px; accent-color: var(--pn-y); margin: 0; }
.pn-check input { -webkit-appearance: none; appearance: none; flex: none; box-sizing: border-box; width: 18px; height: 18px; margin: 0; border: 1px solid var(--pn-edge); border-radius: 0;
  background: var(--pn-face) center / 14px 14px no-repeat; cursor: pointer; }
.pn-check input:checked { border-color: var(--pn-y); background-color: var(--pn-y); background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 22 22' fill='none' stroke='%23241f19' stroke-width='2.4' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M5 11.5l3.8 3.8L17 7.2'/%3E%3C/svg%3E"); }
.pn-check input:disabled { cursor: default; opacity: .5; }
:root[data-app][data-theme="light"] .pn-check input:checked { border-color: var(--pn-ink); }
.pn-radios { display: flex; flex-wrap: wrap; gap: 4px 16px; padding-left: 26px; }
.pn-radio.pn-off { opacity: .45; }
/* KEEP THE PHOTOS (a gallery's Settings, General; lib/gallerykeep.js): its two choices at the block's own edge, the
   calendar's field beside its Save, greyed while Keep forever is picked, and its chip amber in the last seven days */
.pn-radios.pn-keepradios { padding-left: 0; }
.pn-srowin .pn-keepday { flex: 1 1 290px; min-width: 0; }
/* the field fills its wrapper, so the calendar glyph sits inside it and the day in words fits ("Wednesday 12 December
   2026"): `.pn-srowin .wa-pwin { width: auto }` is meant for a field that is the row's own flex child, which this one is not */
.pn-keepday .wa-pwin.pn-datein { width: 100%; }
.pn-keepday .pn-datein:disabled { cursor: default; opacity: .5; }
.pn-keepday .pn-datein:disabled + .pn-dategl { opacity: .35; }
.pn-badge.pn-keepchip, :root[data-app][data-theme="light"] .pn-badge.pn-keepchip { background: var(--st-warn-bg); color: var(--st-warn); border-color: var(--st-warn-line); }
/* on a Collections card the chip may wrap to two short lines: the cards are two to a row on a phone, and a chip that
   stayed on one line pushed the page sideways */
.pn-gcw .pn-keepchip, .pn-gcw .pn-keepgone { margin-top: 6px; }
/* the list's table scrolls inside its own box, and under the gallery's name the chip has the width of the bar */
.pn-gltab .pn-glname .pn-keepchip, .pn-gltab .pn-glname .pn-keepgone, .pn-gtitle .pn-keepchip, .pn-gtitle .pn-keepgone { margin-top: 6px; }
.pn-checks { display: grid; gap: 2px; }
/* a gallery's photographers (Settings, Website, 15 Oct 2026): someone not on the Team page yet has the off chip after their
   name (.pn-badge.pn-off, both themes), never running into it, and on a line of its own where the pane is narrow */
.pn-check.pn-teamtick { flex-wrap: wrap; row-gap: 4px; padding-block: 4px; }
.pn-check.pn-teamtick .pn-badge { flex: none; }
@media (max-width: 760px) { .pn-tagin { font-size: 16px; } }

:root[data-app][data-theme="light"] .pn-srow, :root[data-app][data-theme="light"] .pn-sblock { border-top-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-sword b, :root[data-app][data-theme="light"] .pn-sblock > b { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-switch { background: rgba(36,31,25,.18); }
:root[data-app][data-theme="light"] .pn-knob { background: #fff; }
:root[data-app][data-theme="light"] .pn-switch[aria-checked="true"] { background: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-switch[aria-checked="true"] .pn-knob { background: #fffdf9; }
:root[data-app][data-theme="light"] .pn-tags2 { background: var(--pn-face); border-color: var(--pn-edge); }
:root[data-app][data-theme="light"] .pn-tags2:focus-within { border-color: var(--pn-ink); box-shadow: 0 0 0 1px var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-tag2 { background: rgba(36,31,25,.08); }
:root[data-app][data-theme="light"] .pn-check input, :root[data-app][data-theme="light"] .pn-radio input { accent-color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-dangeritem { border-top-color: var(--pn-line); }

/* THE DESIGN TAB (assets/app.js designTab; part 2, 25 Sep 2026): a card for every choice, the one in use outlined */
.pn-dcards { display: grid; grid-template-columns: repeat(auto-fill, minmax(128px, 1fr)); gap: 10px; }
.pn-dcards2 { grid-template-columns: repeat(2, minmax(0, 150px)); }
/* each a card in the card's shadow, the one in use the picked card's 1.5px ink ring (2 Nov 2026, the operator: go A) */
.pn-dcard { display: grid; gap: 7px; padding: 8px; border: 1px solid transparent; border-radius: var(--pn-r); background: var(--pn-face);
  box-shadow: var(--pn-sh); color: inherit; font: inherit; text-align: center; cursor: pointer; }
.pn-dcard[aria-pressed="true"] { box-shadow: var(--pn-sh-sel); }
@media (hover: hover) { .pn-dcard:not([aria-pressed="true"]):hover { background: var(--pn-hover); } }
.pn-dlabel { font-size: 12px; }

/* the covers in small, drawn with the gallery's own cover photo */
.pn-cvmini { position: relative; display: block; aspect-ratio: 16 / 10; border-radius: var(--pn-r); overflow: hidden; background: #f3eee6; }
.pn-cvm-img { position: absolute; inset: 0; background: #6b6257 center / cover no-repeat; }
/* a preset's little covers have no photo of their own: a stand-in evening scene, sky over a horizon */
.pn-gpdesign .pn-cvm-img { background-image: linear-gradient(180deg, #7d8ea3 0%, #c9a47f 54%, #4b4036 55%, #2c2621 100%); }
.pn-gpdesign .pn-dh { margin: 18px 0 8px; font-size: 12.5px; font-weight: 600; }
.pn-cvmini b { position: absolute; font-size: 8.5px; font-weight: 700; letter-spacing: .22em; text-transform: uppercase; color: #fff; }
.pn-cvm-center b, .pn-cvm-frame b, .pn-cvm-outline b { left: 50%; top: 50%; transform: translate(-50%, -50%); }
.pn-cvm-left b { left: 8%; bottom: 12%; }
.pn-cvm-frame::after { content: ""; position: absolute; inset: 7%; border: 1px solid rgba(255,255,255,.85); }
.pn-cvm-outline b { padding: 4px 7px; border: 1px solid #fff; }
.pn-cvm-stripe b { left: 8%; top: 50%; transform: translateY(-50%); }
.pn-cvm-stripe::before, .pn-cvm-stripe::after { content: ""; position: absolute; left: 8%; right: 8%; height: 1px; background: rgba(255,255,255,.8); z-index: 1; }
.pn-cvm-stripe::before { top: 22%; } .pn-cvm-stripe::after { bottom: 22%; }
.pn-cvm-novel .pn-cvm-img { inset: 10% 8% 10% 52%; }
.pn-cvm-novel b, .pn-cvm-divider b, .pn-cvm-vintage b, .pn-cvm-journal b, .pn-cvm-stamp b, .pn-cvm-classic b { color: #3a332b; }
.pn-cvm-novel b { left: 10%; top: 50%; transform: translateY(-50%); }
.pn-cvm-divider .pn-cvm-img { right: 50%; }
.pn-cvm-divider b { left: 58%; top: 50%; transform: translateY(-50%); }
.pn-cvm-divider::after { content: ""; position: absolute; left: 53%; top: 18%; bottom: 18%; width: 1px; background: rgba(58,51,43,.3); }
.pn-cvm-vintage .pn-cvm-img { bottom: 32%; }
.pn-cvm-vintage b { left: 50%; bottom: 11%; transform: translateX(-50%); }
.pn-cvm-journal .pn-cvm-img { inset: 8% 42% 26% 8%; }
.pn-cvm-journal b { right: 8%; bottom: 12%; }
.pn-cvm-stamp .pn-cvm-img { inset: 14% 34% 38% 34%; }
.pn-cvm-stamp b { left: 50%; bottom: 14%; transform: translateX(-50%); }
.pn-cvm-classic .pn-cvm-img { bottom: 24%; }
.pn-cvm-classic b { left: 7%; bottom: 7%; font-size: 7px; }
.pn-cvm-none { background: #fff linear-gradient(to top right, transparent calc(50% - 1px), rgba(58,51,43,.25) 50%, transparent calc(50% + 1px)); }
.pn-cvm-none .pn-cvm-img, .pn-cvm-none b { display: none; }

/* the type, each card in its own face, as the gallery draws it (gallery.css .gl-font-*): Sans, the default, is the display
   face as it is written, at -.01em as the gallery sets it (in capitals at .1em until the website's Helvetica Neue
   Light, 16 Oct 2026, which the gallery's own Sans never was) */
.pn-dfont { display: grid; gap: 3px; min-height: 64px; align-content: center; padding: 6px 4px; border-radius: var(--pn-r); background: #faf8f4; color: #2b2622; text-align: left; }
.pn-dfont b { font-size: 17px; line-height: 1.1; }
.pn-dfont small { font-size: 10.5px; opacity: .75; }
.pn-f-sans b { font-family: var(--font-display); font-weight: 300; letter-spacing: -.01em; text-transform: none; }
.pn-f-serif b { font-family: Georgia, "Times New Roman", serif; font-weight: 400; }
.pn-f-modern b { font-family: "Avenir Next", "Century Gothic", "Segoe UI", sans-serif; letter-spacing: .08em; font-weight: 400; }
.pn-f-timeless b { font-family: "Palatino Linotype", Palatino, "Book Antiqua", Georgia, serif; font-weight: 300; letter-spacing: .04em; }
.pn-f-bold b { font-family: "Arial Black", "Segoe UI Black", Arial, sans-serif; font-weight: 800; text-transform: uppercase; }
.pn-f-subtle b { font-family: "Segoe UI Light", "Helvetica Neue", Arial, sans-serif; font-weight: 200; letter-spacing: .22em; text-transform: uppercase; }

/* the colours, as three dots */
.pn-dswatches { display: flex; justify-content: center; gap: 6px; padding: 14px 4px; border-radius: var(--pn-r); background: #faf8f4; }
.pn-sw { width: 26px; height: 26px; border-radius: 50%; border: 1px solid rgba(0,0,0,.12); }

/* the grid options, as little grids */
.pn-dgrid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 3px; width: 64px; margin: 8px auto; }
.pn-dgrid i { display: block; height: 12px; border-radius: var(--pn-r); background: currentColor; opacity: .8; }
.pn-dg-vertical i:nth-child(2), .pn-dg-vertical i:nth-child(4) { height: 20px; }
.pn-dg-horizontal { grid-template-columns: 2fr 1fr 1.5fr; }
.pn-dg-large { grid-template-columns: repeat(2, 1fr); }
.pn-dg-large i { height: 16px; }
.pn-dg-large i:nth-child(n+5) { display: none; }
.pn-dg-loose { gap: 7px; }
.pn-dnav { display: inline-flex; align-items: center; gap: 6px; margin: 12px auto; padding: 6px 10px; border-radius: var(--pn-r); background: rgba(255,255,255,.1); font-size: 12px; }
.pn-dni { width: 12px; height: 12px; border: 1.6px solid currentColor; border-radius: var(--pn-r); }

.pn-dpicks { display: grid; grid-template-columns: repeat(auto-fill, minmax(64px, 1fr)); gap: 6px; max-height: 220px; overflow-y: auto; }
.pn-dpick { padding: 0; border: 2px solid transparent; border-radius: var(--pn-r); overflow: hidden; background: rgba(255,255,255,.06); aspect-ratio: 1; cursor: pointer; }
.pn-dpick img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pn-dpick[aria-pressed="true"] { border-color: var(--pn-ink); }
/* CHANGE COVER and SET FOCAL POINT, as Pixieset's (26 Sep 2026: "this option"): the cover, two presses under it, and
   their sheets; Select from the gallery puts the five-star photos first */
.pn-dcov { display: grid; place-items: center; width: min(100%, 440px); aspect-ratio: 3 / 2; border-radius: var(--pn-r); overflow: hidden;
  background: rgba(0,0,0,.22); font-size: 12px; color: rgba(242,239,232,.6); }
.pn-dcov img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pn-dcovacts { display: flex; flex-wrap: wrap; gap: 4px 20px; margin-top: 10px; }
.pn-dcovbtn { display: inline-flex; align-items: center; gap: 6px; min-height: var(--pn-h-act); padding: 0; white-space: nowrap; border: 0; background: none;
  color: var(--pn-ink); font: inherit; font-size: 14px; font-weight: 600; cursor: pointer; }
.pn-dcovbtn .pn-gl { width: 18px; height: 18px; }
@media (hover: hover) { .pn-dcovbtn:hover span { text-decoration: underline; text-underline-offset: 3px; } }
.pn-sheet > .wa-card.pn-covsheet { max-width: 680px; padding: 22px 24px 24px; }
/* THE HEAD STAYS WHILE THE SHEET SCROLLS (design audit, 27 Sep 2026: in New job and Edit photographers the title and
   the X left a phone's screen at the first scroll; the desk's windows keep theirs). It reaches the card's edges, over
   the card's own 22px and 24px padding, so nothing shows through above it while it is held at the top. */
.pn-covhead { position: sticky; top: -22px; z-index: 1; display: flex; align-items: center; justify-content: space-between; gap: 12px;
  margin: -22px -24px 16px; padding: 22px 24px 12px; background: inherit; }
.pn-covhead h2 { margin: 0; }
.pn-covx { flex: none; display: grid; place-items: center; width: var(--pn-h-act); height: var(--pn-h-act); padding: 0; border: 0; border-radius: var(--pn-r); background: none; color: inherit; cursor: pointer; }
.pn-covx .pn-gl { width: 16px; height: 16px; }
.pn-covdrop { display: grid; justify-items: center; gap: 12px; padding: 48px 16px 40px; border: 1px dashed var(--pn-edge, rgba(255,255,255,.24)); border-radius: var(--pn-r); text-align: center; }
/* files over it: the ink's edge on the soft wash (2 Nov 2026, the operator: go A) */
.pn-covdrop.pn-over { border-color: var(--pn-ink); background: var(--pn-soft); }
.pn-covdrop > .pn-gl { width: 44px; height: 44px; opacity: .55; stroke-width: 1.1; }
.pn-covdrop > p:first-of-type { margin: 0; font-size: 15px; font-weight: 600; }
/* ADD MEDIA (26 Sep 2026): Change cover's drop place, with My computer and the watermark */
.pn-addmedia { gap: 10px; padding: 52px 16px 44px; }
.pn-addmedia .pn-amor { font-size: 12px; opacity: .75; }
.pn-addmedia .wa-gl { gap: 8px; min-width: 180px; }
.pn-addmedia .wa-gl .pn-gl { width: 18px; height: 18px; }
.pn-covbrowse { display: inline-flex; align-items: center; gap: 6px; min-height: 32px; font-size: 14px; cursor: pointer; }
.pn-covbrowse .pn-gl { width: 18px; height: 18px; }
.pn-covlist { max-height: min(64vh, 620px); overflow-y: auto; }
.pn-covk { display: flex; align-items: center; gap: 6px; margin: 14px 0 8px; }
.pn-covk:first-child { margin-top: 0; }
.pn-covk .pn-gl { width: 16px; height: 16px; color: var(--moon); fill: currentColor; }
.pn-covk b { font-weight: 600; opacity: .6; }
.pn-covpicks { grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); max-height: none; overflow: visible; }
.pn-focalwrap { text-align: center; }
.pn-focal { position: relative; display: inline-block; max-width: 100%; vertical-align: top; touch-action: none; cursor: crosshair;
  user-select: none; -webkit-user-select: none; }
.pn-focal img { display: block; max-width: 100%; max-height: 62vh; pointer-events: none; }
.pn-focaldot { position: absolute; width: 22px; height: 22px; margin: -11px 0 0 -11px; border-radius: 50%; background: var(--pn-y);
  box-shadow: 0 0 0 7px rgba(255,255,255,.45); pointer-events: none; }
:root[data-app][data-theme="light"] .pn-dcov { background: var(--pn-fill); color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-covk .pn-gl { color: #b8860b; }

:root[data-app][data-theme="light"] .pn-dnav { background: rgba(36,31,25,.07); }

/* THE GALLERIES LIST (assets/app.js galleries; part 3, 25 Sep 2026, Pixieset's Collections page as the picture) */
.pn-glhead { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; }
.pn-glhead .pn-h { margin-right: auto; }
/* EVENTS' HEAD (report 122, 6 Oct 2026, on an iPhone 506 wide: "This looks like is crammed"): the heading's own space
   above and below goes round the whole row, so Add event no longer rides up against the places dropdown above it, and
   the heading and the button are centred on one line together, as Collections' heading and New gallery are */
.pn-evhead { margin: 22px 0 10px; }
.pn-evhead .pn-h { margin: 0 auto 0 0; }
/* Collections' title level with New gallery beside it: the heading's own margins (22px over, 6px under) sat it low in
   the row, so the row carries them instead (26 Sep 2026) */
.pn-colhead { margin: 22px 0 6px; gap: 12px 10px; }
.pn-colhead .pn-h { margin: 0 auto 0 0; }
.pn-glsearch { flex: 0 1 260px; height: 40px; }
.pn-glsearch::-webkit-search-cancel-button { -webkit-appearance: none; display: none; }
.pn-glfilters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 12px; }
.pn-glfilter .wa-pwin { width: auto; padding-right: 34px; font-size: 14px; }
/* THE CLIENTS LIST'S HEAD ON A PHONE, AS JOBS HAS IT (9 Nov 2026): New client alone at the right, then the show, the search and the sort on one line. To 759px, where the search folds */
@media (max-width: 759px) {
  .pn-clbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
  .pn-clbar > .pn-glhead, .pn-clbar > .pn-glfilters { display: contents; }
  .pn-clbar .pn-glfilter { order: 3; }
  .pn-clbar .pn-sfold, .pn-clbar .pn-glhead > .pn-glsearch { order: 4; }
  .pn-clbar .pn-glicons { order: 5; margin-left: 0; }
  .pn-clbar .pn-glhead .wa-btn { order: 6; margin-left: auto; }
  .pn-clbar .pn-sfold.pn-sopen { order: 7; }
}
/* THE JOBS AND LEADS LISTS ON A PHONE (9 Nov 2026, of a three-row head and rows five lines tall): New job at the right, then the small
   tools on one line; a row is its date with its stage, More at the top right, then the name across and its meta lines */
@media (max-width: 720px) {
  .pn-jbbar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
  .pn-jbbar > .pn-jbhead, .pn-jbbar > .pn-jbrow, .pn-jbbar > .pn-jbrow.pn-open { display: contents; }
  .pn-jbbar .pn-jbhead .pn-h { order: 0; }
  .pn-jbbar .pn-glfbtn { order: 3; }
  .pn-jbbar .pn-jbhead .pn-sfold, .pn-jbbar .pn-jbhead > .pn-glsearch { order: 4; }
  .pn-jbbar .pn-jbexport { order: 5; }
  .pn-jbbar .pn-glicons { order: 6; margin: 0; }
  .pn-jbbar .pn-jbhead .wa-btn { order: 7; margin-left: auto; }
  .pn-jbbar .pn-jbhead .pn-sfold.pn-sopen { order: 8; }
  .pn-jbbar .pn-jbrow > .pn-glfilter { order: 9; }
  .pn-jbbar .pn-jbrow > .pn-jbclear { order: 10; }
  .pn-jbbar .pn-jbdate { flex: 1 1 100%; }
  :root[data-app] .pn-jbbar .pn-jbhead .pn-jbexport { position: relative; height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0 10px; gap: 6px; font-size: 10.5px; }
  :root[data-app] .pn-jbbar .pn-jbexport .pn-gl { width: 14px; height: 14px; }
  .pn-jbbar .pn-jbexport::after { content: ""; position: absolute; inset: -7px 0; }
}
/* the rows reach an iPad's width too (9 Nov 2026): at 768 the table crushed the name to 104px and More ran past the card */
@media (max-width: 899.98px) {
  .pn-jblist thead tr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .pn-jblist, .pn-jblist tbody { display: block; }
  .pn-jblist tbody tr { display: grid; grid-template-columns: auto minmax(0, 1fr) var(--pn-h-act); gap: 2px 8px; align-items: center; padding: 12px; border-bottom: 1px solid var(--pn-line); }
  .pn-jblist tbody tr:last-child { border-bottom: 0; }
  .pn-jblist tbody td:not(.pn-glopt) { display: block; width: auto; padding: 0; border: 0; }
  .pn-jblist td.pn-glnum:first-child { grid-column: 1; grid-row: 1; font-size: 12px; color: var(--pn-muted); }
  /* the stage's own column is the job's fifth of six (a lead has seven and no stage), shown beside the date */
  .pn-jblist tbody td.pn-glopt { display: none; }
  .pn-gltab.pn-jblist .pn-glname .pn-jbnarrow { display: block; }
  .pn-gltab.pn-jblist .pn-glname .pn-jbphone { display: inline; }
  .pn-jblist .pn-jbsv { gap: 0; }
  .pn-jblist .pn-jbsv > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .pn-jblist tbody td.pn-glopt:nth-child(5):nth-last-child(2) { display: block; grid-column: 2; grid-row: 1; justify-self: start; padding: 0; border: 0; }
  .pn-jblist td.pn-glrowmenu { grid-column: 3; grid-row: 1; text-align: right; }
  .pn-jblist tbody td.pn-glname { display: flex; flex-wrap: wrap; align-items: center; gap: 3px 6px; grid-column: 1 / -1; grid-row: 2; }
  .pn-jblist .pn-glname > a { min-width: 0; margin-right: 0; }
  .pn-jblist .pn-glname > .pn-t:not(.pn-jbnarrow) { order: 1; flex: 0 0 100%; }
  .pn-jblist .pn-glname > .pn-jbsvs { order: 3; }
  .pn-jblist .pn-glname > .pn-jbnarrow { order: 2; flex: 1 1 0; min-width: 0; }
  .pn-jblist .pn-glname > a b { font-size: 14px; line-height: 1.38; }
  .pn-jblist .pn-glname .pn-t { font-size: 12.5px; }
  .pn-jblist .pn-jbnarrow { margin-top: 3px; }
  .pn-jblist .pn-jbnarrow .pn-badge { margin-left: 0; }
  .pn-jblist .pn-glname > .pn-jbsvs .pn-jbsv { height: 18px; min-height: 18px; min-width: 18px; padding: 0 3px; }
  .pn-jblist .pn-glname > .pn-jbsvs .pn-jbsv .pn-gl { width: 12px; height: 12px; }
}
@media (max-width: 720px) {
  /* ONE JOB'S HEAD: the name with its copy after its first line, then the state and the day with Edit and More at the right */
  .pn-jbtop:has(> .pn-jbtitle) { gap: 8px; }
  .pn-jbtop > .pn-jbtitle { flex: 1 1 100%; align-items: flex-start; }
  :root[data-app] .pn-jbtop > .pn-jbtitle .wa-gl.pn-jbcopy { margin-top: 2px; }
  .pn-jbtop > .pn-jbacts { margin-left: auto; }
  :root[data-app] .pn-jbtop > .pn-jbacts .wa-gl { position: relative; height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0 10px; gap: 6px; font-size: 10.5px; }
  :root[data-app] .pn-jbtop > .pn-jbacts .wa-gl.pn-glicon { width: var(--pn-h-act); padding: 0; }
  :root[data-app] .pn-jbtop > .pn-jbacts .wa-gl .pn-gl { width: 14px; height: 14px; }
  .pn-jbtop > .pn-jbacts .wa-gl:not(.pn-glicon)::after { content: ""; position: absolute; inset: -7px 0; }
}
@media (max-width: 399.98px) {
  :root[data-app] .pn-jbbar .pn-jbhead .pn-jbexport { width: var(--pn-h-act); padding: 0; justify-content: center; }
  .pn-jbbar .pn-jbexport > span { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
  .pn-jbbar .pn-jbexport::after { inset: -7px; }
}

/* a filter's dropdown takes its size and look from ONE FILTER, ONE RULE at the end of this sheet (report 79), whatever
   list it is in: the chevron at its edge, as in Settings and the sheets; the date boxes keep their room for the
   calendar glyph */
/* Starred on: the calculator's picked option, filled yellow with the ink's words, in both themes (2 Nov 2026, the operator: go A) */
:root[data-app][data-theme] .pn-wrap .wa-gl.pn-glstarred[aria-pressed="true"],
:root[data-app][data-theme] .pn-wrap .wa-gl.pn-glstarred[aria-pressed="true"]:hover { background: var(--pn-y); border-color: var(--pn-y); color: var(--pn-on-y); }
.pn-gcards { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 18px 14px; }
/* EACH GALLERY A CARD (2 Nov 2026, the operator: go A): the card's face and shadow, the cover across its top, its words inside it */
.pn-gcard { position: relative; min-width: 0; background: var(--pn-face); box-shadow: var(--pn-sh); }
.pn-gcimg { display: block; text-decoration: none; aspect-ratio: 4 / 3; border-radius: var(--pn-r); overflow: hidden; background: rgba(255,255,255,.06); }
.pn-gcimg img { display: block; width: 100%; height: 100%; object-fit: cover; transition: transform 240ms ease; }
@media (hover: hover) { .pn-gcimg:hover img { transform: scale(1.03); } }
.pn-gcnone { display: grid; place-items: center; width: 100%; height: 100%; font-family: var(--font-display); font-size: 42px; font-weight: 200; color: rgba(242,239,232,.35); }
/* square as every Studio control is (3 Nov 2026, the Studio's UX pass): a collection's star and More were the last two
   round buttons, beside the photo tiles' square More */
.pn-gstar { position: absolute; top: 8px; right: 8px; display: grid; place-items: center; width: 32px; height: 32px; border-radius: var(--pn-r);
  background: rgba(12,11,10,.55); color: #f2efe8; cursor: pointer; }
.pn-gstar svg { width: 17px; height: 17px; fill: none; stroke: currentColor; stroke-width: 1.7; stroke-linejoin: round; }
.pn-gstar[aria-pressed="true"] { color: var(--moon); }
.pn-gstar[aria-pressed="true"] svg { fill: currentColor; }
.pn-gcw { padding: 10px 12px 12px; }
.pn-gcw a { color: inherit; text-decoration: none; }
.pn-gcw b { display: block; font-size: 14px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-gcw .pn-t { margin: 3px 0 0; }
.pn-gcw .pn-t > .pn-dot { margin-right: 6px; }
.pn-glpager { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; gap: 6px; margin-top: 22px; }
.pn-glpager .pn-pill .pn-gl { width: 16px; height: 16px; }
@media (max-width: 520px) { .pn-gcards { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px 10px; } .pn-gcw { padding: 8px 9px 10px; } .pn-glsearch { flex: 1 1 100%; } }
@media (prefers-reduced-motion: reduce) { .pn-gcimg img { transition: none; } }
:root[data-app][data-theme="light"] .pn-gcimg { background: rgba(36,31,25,.06); }
:root[data-app][data-theme="light"] .pn-gcnone { color: rgba(36,31,25,.3); }
:root[data-app][data-theme="light"] .pn-gcw b { color: var(--pn-ink); }

/* GALLERY SETTINGS (assets/app.js gallerySettingsPage; part 4, 25 Sep 2026) */
.pn-gptabs { flex-wrap: wrap; }
.pn-range { display: grid; gap: 4px; font-size: 12px; }
.pn-range span { display: flex; justify-content: space-between; }
.pn-range i { font-style: normal; font-variant-numeric: tabular-nums; opacity: .75; }
.pn-range input { width: 100%; accent-color: var(--pn-y); }
.pn-wmprev { width: 100%; height: auto; border-radius: var(--pn-r); background: #2a2520; }
/* THE WATERMARK TILES (26 Sep 2026: "make this - i need the image watermark"): Pixieset's row, each mark on a grey
   square with its name under it, the + to add one, a small x on an uploaded one. The logo is shown as it is, on grey.
   ONE FLAT GREY (29 Sep 2026, report 17: "remove gradient behind the preview"), dark enough for a white mark to read,
   in both themes, on the tiles and the Watermark image thumb alike. */
.pn-wmtiles { display: flex; flex-wrap: wrap; gap: 16px; }
.pn-wmbox { position: relative; display: grid; gap: 8px; width: 140px; }
.pn-wmtile { display: grid; place-items: center; width: 140px; height: 140px; padding: 16px; border: 0; border-radius: var(--pn-r); cursor: pointer;
  background: #6f6b66; color: #fff; font: inherit; box-shadow: inset 0 0 0 1px rgba(255,255,255,.1); }
.pn-wmtile img { display: block; max-width: 100%; max-height: 100%; object-fit: contain; }
.pn-wmtile.pn-on { box-shadow: 0 0 0 2px var(--pn-ink), inset 0 0 0 1px rgba(255,255,255,.1); }
.pn-wmwords { font-size: 14px; line-height: 1.3; text-align: center; text-shadow: none; overflow-wrap: anywhere; }
.pn-wmadd { position: relative; background: rgba(255,255,255,.06); color: rgba(242,239,232,.7); box-shadow: inset 0 0 0 1px rgba(255,255,255,.14); }
.pn-wmadd .pn-gl { width: 24px; height: 24px; }
@media (hover: hover) { .pn-wmadd:hover { background: rgba(255,255,255,.1); color: #f2efe8; } }
.pn-wmadd:focus-within { outline: 2px solid var(--beige); outline-offset: 3px; }
.pn-wmfile { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
.pn-wmname { overflow: hidden; font-size: 10.5px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; text-overflow: ellipsis; white-space: nowrap; color: rgba(242,239,232,.66); }
.pn-wmx { position: absolute; top: 6px; right: 6px; display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0;
  border-radius: var(--pn-r); background: rgba(0,0,0,.5); color: #fff; cursor: pointer; }
.pn-wmx .pn-gl { width: 14px; height: 14px; }
/* THE EDITOR, as Pixieset's (26 Sep 2026: "set up the settings similar"): Settings down the left, the photo on the right */
.pn-wmedit { display: grid; grid-template-columns: minmax(0, 280px) minmax(0, 1fr); gap: 28px; align-items: start;
  padding-top: 18px; border-top: 1px solid rgba(255,255,255,.08); }
.pn-wmside { display: grid; gap: 10px; align-content: start; }
.pn-wmh { margin: 0; }
.pn-wmkind { margin-left: 8px; font-size: 11px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; color: rgba(242,239,232,.55); }
:root[data-app][data-theme="light"] .pn-wmkind { color: var(--pn-ink-soft); }
.pn-wmsub { margin: 0; font-size: 12px; line-height: 1.5; color: rgba(242,239,232,.6); }
.pn-wmk { margin: 8px 0 0; font-size: 12px; font-weight: 600; color: #f2efe8; }
.pn-wmimgs { display: flex; gap: 10px; }
.pn-wmthumb { position: relative; width: 96px; height: 96px; padding: 10px; cursor: default; }
label.pn-wmthumb { cursor: pointer; }
/* ONE IMAGE A MARK (26 Sep 2026): a bin over the image, shown on hover (always on a touch screen), to delete it and
   upload another in its place */
.pn-wmbin { position: absolute; top: 4px; right: 4px; display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0;
  border-radius: var(--pn-r); background: rgba(0,0,0,.6); color: #fff; cursor: pointer; opacity: 0; transition: opacity .15s ease; }
.pn-wmbin .pn-gl { width: 16px; height: 16px; }
.pn-wmthumb:hover .pn-wmbin, .pn-wmbin:focus-visible { opacity: 1; }
@media (hover: none) { .pn-wmbin { opacity: 1; } }
.pn-wmrange { margin-top: 4px; }
.pn-wmpos { display: grid; grid-template-columns: repeat(3, 32px); gap: 4px; width: fit-content; padding: 6px; border-radius: var(--pn-r); background: rgba(0,0,0,.2); }
.pn-wmdot { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--pn-r); background: none; cursor: pointer; }
.pn-wmdot i { display: block; width: 5px; height: 5px; border-radius: 50%; background: rgba(242,239,232,.4); transition: width .12s ease, height .12s ease; }
.pn-wmdot.pn-on i { width: 16px; height: 16px; background: var(--beige); }
@media (hover: hover) { .pn-wmdot:hover i { background: rgba(242,239,232,.8); } }
.pn-wmtilepick { justify-self: start; }
.pn-wmstage { display: grid; justify-items: center; gap: 12px; }
.pn-wmstage .pn-wmprev { max-width: 100%; max-height: 520px; width: auto; }
.pn-wmprev.pn-tall { max-height: 520px; }
.pn-wmorient { display: flex; gap: 6px; }
.pn-wmori { display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--pn-r); background: none;
  color: rgba(242,239,232,.55); cursor: pointer; }
.pn-wmori.pn-on { background: rgba(255,255,255,.1); color: #f2efe8; }
@media (max-width: 760px) { .pn-wmedit { grid-template-columns: minmax(0, 1fr); } }
@media (prefers-reduced-motion: reduce) { .pn-wmdot i { transition: none; } }
:root[data-app][data-theme="light"] .pn-wmedit { border-top-color: rgba(36,31,25,.1); }
:root[data-app][data-theme="light"] .pn-wmsub { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-wmk { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-wmpos { background: rgba(36,31,25,.05); }
:root[data-app][data-theme="light"] .pn-wmdot i { background: rgba(36,31,25,.3); }
:root[data-app][data-theme="light"] .pn-wmdot.pn-on i { background: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-wmori { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-wmori.pn-on { background: rgba(36,31,25,.08); color: var(--pn-ink); }
/* the app's own .pn-on fills a picked thing solid; here the tile keeps its grey, the dot is the only thing that grows,
   and Tile across the photo is filled like any picked pill */
:root[data-app][data-theme="light"] .pn-wmtile.pn-on { background: #6f6b66; color: #fff; }
:root[data-app][data-theme="light"] .pn-wmdot.pn-on { background: none; }
.pn-wmtilepick.pn-on, :root[data-app] .pn-pill.pn-wmtilepick.pn-on { background: var(--beige); color: #221d18; }
:root[data-app][data-theme="light"] .pn-pill.pn-wmtilepick.pn-on { background: var(--pn-ink); color: #f7f3ec; }
:root[data-app][data-theme="light"] .pn-wmname { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-wmtile.pn-on { box-shadow: 0 0 0 2px var(--pn-ink), inset 0 0 0 1px rgba(255,255,255,.1); }
:root[data-app][data-theme="light"] .pn-wmadd { background: rgba(36,31,25,.05); color: var(--pn-ink-soft); box-shadow: inset 0 0 0 1px rgba(36,31,25,.16); }
@media (pointer: coarse) {
  .pn-wmbin { width: 44px; height: 44px; top: 2px; right: 2px; }
  .pn-wmx { width: 32px; height: 32px; }
  .pn-wmx::after { content: ""; position: absolute; inset: -6px; }
  .pn-wmpos { grid-template-columns: repeat(3, 44px); }
  .pn-wmdot, .pn-wmori { width: 44px; height: 44px; }
}
.pn-policy { height: auto; min-height: 180px; padding: 12px 14px; font-size: 14px; line-height: 1.55; resize: vertical; }
/* GALLERY SETTINGS, BRANDING (report 95): the small previews. The logo on a small copy of a gallery page's header, in
   the dark band the galleries draw it on (#1d1915, theirs in light and dark alike), its own shape kept in the logo's
   box; the favicon in a small browser tab beside a gallery's name. THE LOGO RULE: never a filter, never recoloured */
.pn-brprev { display: grid; gap: 6px; max-width: 420px; margin: 0; }
.pn-brband { display: flex; align-items: center; gap: 12px; min-width: 0; padding: 14px 16px; border-radius: var(--pn-r); background: #1d1915; color: #f2efe8; }
.pn-brlogo { flex: none; display: block; line-height: 0; }
.pn-brlogo img { display: block; width: 120px; height: 38px; object-fit: contain; object-position: left center; }
.pn-brwords { display: grid; gap: 2px; min-width: 0; }
.pn-brwords b { overflow: hidden; font-size: 15px; font-weight: 600; text-overflow: ellipsis; white-space: nowrap; }
.pn-brwords small { overflow: hidden; font-size: 11.5px; color: rgba(242,239,232,.66); text-overflow: ellipsis; white-space: nowrap; }
.pn-brtabs { display: flex; align-items: flex-end; min-width: 0; padding: 8px 10px 0; border: 1px solid rgba(255,255,255,.12); border-radius: var(--pn-r);
  background: rgba(255,255,255,.05); overflow: hidden; }
.pn-brtab { display: flex; align-items: center; gap: 8px; min-width: 0; max-width: 260px; padding: 8px 10px 9px 12px; border-radius: var(--pn-r);
  background: rgba(255,255,255,.12); font-size: 12.5px; }
.pn-brfav { flex: none; display: block; width: 16px; height: 16px; object-fit: contain; }
.pn-brtabname { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-brtabx { flex: none; display: inline-grid; place-items: center; width: 16px; height: 16px; opacity: .6; }
.pn-brtabx svg { width: 12px; height: 12px; }
.pn-brnow { margin: 8px 0 0; overflow-wrap: anywhere; }
:root[data-app][data-theme="light"] .pn-brtabs { border-color: var(--pn-line); background: var(--pn-fill); }
:root[data-app][data-theme="light"] .pn-brtab { background: var(--pn-face); color: var(--pn-ink); }
@media (max-width: 380px) { .pn-brlogo img { width: 96px; height: 31px; } }
.pn-soonpill { opacity: .55; cursor: default; gap: 8px; }
@media (max-width: 700px) { .pn-policy { font-size: 16px; } }
:root[data-app][data-theme="light"] .pn-range input { accent-color: var(--pn-ink); }
/* the privacy policy and terms under the sign-in card: small and quiet, for Google's review and anyone who looks */
.wa-signlegal { display: flex; gap: 10px; margin: 0; font-size: 12px; letter-spacing: .06em; color: rgba(242,239,232,.55); }
.wa-signlegal a { color: inherit; text-decoration: none; }
@media (hover: hover) { .wa-signlegal a:hover { color: #f2efe8; text-decoration: underline; text-underline-offset: 3px; } }
:root[data-app][data-theme="light"] .wa-signlegal { color: rgba(36,31,25,.62); }
@media (hover: hover) { :root[data-app][data-theme="light"] .wa-signlegal a:hover { color: #241f19; } }

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   DARK, CLEAN (the operator, 26 Sep 2026: "in dark mode remove gradient and glass effect make it clean like the light
   mode but in dark"). The night gradient and the frosted glass are the guests' pages' look; the app in dark is built
   the way light is: a flat ground, solid cards with a hairline and a shadow that sits, and a header that is a band of
   its own (the same band as light's, so the logo is on the same ground in both). Nothing here blurs what is behind it
   except the scrim under a sheet, which light keeps too. Only [data-app] pages, only dark.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
:root[data-app][data-theme="dark"] {
  --pn-ground: #1a1611;
  --pn-face: #26201a;
  --pn-face-2: #2e2720;
  --pn-line: #3d3832;
}
:root[data-app][data-theme="dark"],
:root[data-app][data-theme="dark"] body { background: var(--pn-ground); }
:root[data-app][data-theme="dark"] .wa-bg { background: var(--pn-ground); }
/* THE BOTTOM EDGE FOR SAFARI (the operator, 10 Oct 2026, the desk in dark mode on his iPhone with Safari's bottom bar
   still cream: "Can you theme the bottom bar on dark mode?"). iPhone Safari colours its bottom bar from a full-width
   strip fixed at the page's foot when there is one, and reads it again whenever its colour changes; with none it read
   the page's ground, and kept the light one after a switch to dark. frame.js S.edge puts one strip on the page, 12px
   of the theme's own ground, so the bar is the page's colour in light and in dark. A touch screen only (Safari on a
   computer has no bottom bar), never in the way of a press, under the header, the sheets and everything that floats,
   and no blur, which stops Safari reading it. */
.pn-edge { display: none; }
@media (hover: none) and (pointer: coarse) {
  :root[data-app] .pn-edge { display: block; position: fixed; left: 0; right: 0; bottom: 0; z-index: 9; height: 12px; margin: 0;
    pointer-events: none; background: #241f19; -webkit-backdrop-filter: none; backdrop-filter: none; }
  /* UNDER A POP-UP (report 171): the strip takes the page's ground as the dim leaves it, so Safari's bottom bar dims with
     the screen rather than stay bright under a dimmed sheet; it is not drawn (opacity 0, which Safari still reads), as the
     sheet's own dim already covers that edge and a second would show as a darker band. --pn-edge-dim is the theme's
     ground under its --pn-dim, worked out once: #1a1611 under .66 of 10,9,8 is 15,13,11; #f6f4ef under .48 of 14,12,9
     is 135,133,129 (the grounds of 2 Nov 2026, go A) */
  :root[data-app].wa-held .pn-edge { opacity: 0; background: rgb(19,16,14); }
  :root[data-app][data-theme="light"].wa-held .pn-edge { background: rgb(25,22,17); }
  /* THE BOTTOM BAR BROWN IN BOTH THEMES (3 Nov 2026, the operator: "Pin the bottom bar brown"): the strip is the header's
     own brown, light or dark, so Safari's bars top and foot are the one colour; under a pop-up the brown as each theme's
     dim leaves it (#241f19 under .66 of 10,9,8 is 19,16,14; under .48 of 14,12,9 it is 25,22,17) */
}
:root[data-app][data-theme="dark"] .pn-bar { background: #241f19; border-bottom-color: rgba(255,255,255,.07);
  backdrop-filter: none; -webkit-backdrop-filter: none; }
:root[data-app][data-theme="dark"] .wa-card {
  background: var(--pn-face);
  border-color: var(--pn-line);
  box-shadow: none;
  backdrop-filter: none; -webkit-backdrop-filter: none;
}
:root[data-app][data-theme="dark"] .wa-tile { background: var(--pn-face); border-color: transparent; box-shadow: var(--pn-sh); }
:root[data-app][data-theme="dark"] .wa-gl { background: rgba(255,255,255,.07); backdrop-filter: none; -webkit-backdrop-filter: none; }
/* UNDER THE MOUSE IN DARK (design audit, 27 Sep 2026): the rule above outranked smp.css's hover, so a glass button did
   not change at all. Not a picked one (.pn-on keeps its beige) or an off one. */
@media (hover: hover) {
  :root[data-app][data-theme="dark"] .wa-gl:not(.pn-on):not(:disabled):hover { background: rgba(255,255,255,.12); }
}
/* THE MAIN PRESS IN DARK IS THE YELLOW with the ink's words, as on the website's dark bands and the calculator's bar; a line
   button keeps its edge in the dark's line; a box its 3:1 edge, and the ink's ring when it has the keyboard (2 Nov 2026, the
   operator: go A) */
:root[data-app][data-theme="dark"] :is(.pn-wrap, .pn-sheet, .dk-modal) .wa-btn { background: var(--pn-y); color: var(--pn-on-y); }
@media (hover: hover) { :root[data-app][data-theme="dark"] :is(.pn-wrap, .pn-sheet, .dk-modal) .wa-btn:not(:disabled):hover { background: var(--pn-y-press); filter: none; } }
/* off, it is grey at half strength, never a pale yellow: a Save with nothing to save reads grey (the standing rule) */
:root[data-app][data-theme="dark"] :is(.pn-wrap, .pn-sheet) :is(.wa-gl, .wa-pill) { border-color: var(--pn-line); }
:root[data-app][data-theme="dark"] .wa-pwin { border-color: var(--pn-edge); }
:root[data-app][data-theme="dark"] .wa-pwin:focus { border-color: var(--pn-ink); box-shadow: 0 0 0 1px var(--pn-ink); }
/* the PIN's squares as the boxes beside them: the 3:1 edge, a filled square brighter, the ink's ring with the keyboard */
:root[data-app][data-theme="dark"] .pn-digit { border-color: var(--pn-edge); }
:root[data-app][data-theme="dark"] .pn-digit:is(:not(:placeholder-shown), :valid) { border-color: rgba(242,239,232,.6); }
:root[data-app][data-theme="dark"] .pn-digit:focus { border-color: var(--pn-ink); box-shadow: 0 0 0 1px var(--pn-ink); }
:root[data-app][data-theme="dark"] .pn-menu,
:root[data-app][data-theme="dark"] .pn-dock { background: var(--pn-face-2); backdrop-filter: none; -webkit-backdrop-filter: none; }
:root[data-app][data-theme="dark"] .pn-ddmenu { background: var(--pn-face-2); }
:root[data-app][data-theme="dark"] .wa-toast { background: var(--pn-face-2); border-color: var(--pn-line); box-shadow: var(--pn-sh); }
/* a toast on paper is the ink bar's own ink, solid, square, with the card's shadow (2 Nov 2026, the operator: go A) */
:root[data-app][data-theme="light"] .wa-toast { background: var(--pn-inkbar); border-color: var(--pn-inkbar); color: var(--pn-on-inkbar); box-shadow: none; }
/* THE TOAST AS WIDE AS ITS WORDS (3 Nov 2026): placed at the middle by left: 50%, its width was only what was left right of
   the middle, so on a phone a one-line note wrapped to three lines in half the screen. It is now as wide as its words, up
   to the screen less 16px each side (smp.css), and on a phone it sits above Report a problem's button, never under it */
:root[data-app] .wa-toast { width: max-content; }
@media (max-width: 759px) { html.rp-on .wa-toast { bottom: calc(max(16px, env(safe-area-inset-bottom)) + 60px); } }
/* the sign-in card is the one black card of both themes (above), so in dark it is the same card light shows */
:root[data-app][data-theme="dark"] .wa-center .wa-gcard {
  background: #241f1a;
  border-color: rgba(255,255,255,.1); box-shadow: none; }

/* ONE SIZE FOR WHAT IS TYPED OR PICKED (the operator, 26 Sep 2026: "make this font size, and all fonts and dropdown
   /picker sizes consistent across the site", over the Time zone dropdown at 17px beside 11px labels and 13px words).
   The app's type is one scale: 11px for the small capital labels, 12px for small print, 14px for the words and for
   everything typed or picked (boxes, dropdowns, the night's calendar, the venue suggestions), 15px for a row's title,
   22px for a page's. A box is as tall as a button beside it (below). On a phone a typed box stays at 16px, so the
   iPhone does not zoom into it (above). The guests' pages keep their own sizes. */
:root[data-app] .wa-pwin { font-size: 14px; }
/* a box takes the 8px corners of the buttons beside it (UI audit, 30 Sep 2026: smp.css gives it 9px, which the app's
   pages alone answer here) */
:root[data-app] .wa-pwin { border-radius: var(--pn-r); }
:root[data-app] .wa-pwin:not(textarea) { height: 40px; }
@media (pointer: coarse) { :root[data-app] .wa-pwin:not(textarea) { height: 44px; } }

/* ONE SIZE FOR A BUTTON (the operator, 26 Sep 2026: "Fix the button sizes", after the boxes went to one size; measured,
   the panel had buttons 32, 36, 38 and 40px tall in 11 and 11.5px capitals, and the desk 26 to 34px). Two sizes now:
   an action (Save, Make, Cancel, a toolbar's buttons) is 40px, as tall as a box beside it; a small button in a row (a
   row's pills, the PIN's eye, an email chip, a glyph) is 32px. On a touch screen every one is at least 44px (the
   touch rules above). Written with :where() so the few places drawn to their own size (the crew sign-up's big
   buttons, the sign-in card) keep it. */
:where(:root[data-app]) .wa-sm, :where(:root[data-app]) .wa-gl { height: var(--pn-h-main); padding: 0 15px; font-size: 11px; }
/* and one padding, so a filled small button and a glass one side by side match on a phone as they do on a computer
   (design audit, 27 Sep 2026: 14px against 18px in every sheet's Cancel and Save) */
@media (pointer: coarse) { :where(:root[data-app]) .wa-sm, :where(:root[data-app]) .wa-gl { padding: 0 18px; } }
/* CAPITALS SET CLOSE ON EVERY BUTTON (3 Nov 2026, the standing rule since the website's bar, 31 Oct 2026: "why does it
   look stretched wide"): a Studio button's capital words are spaced .06em, never stretched wide (.14em before, which in
   11px capitals read as letters pulled apart); the S button (.wa-pill: Sign out, Remove, View, Make gallery) the same, so
   it never sits wider than the buttons beside it; the header's page words set as close (.pn-nav .wa-pill, below) */
:where(:root[data-app]) :is(.wa-btn, .wa-gl, .wa-pill) { letter-spacing: .06em; }
/* ONE WEIGHT FOR A BUTTON'S WORDS (1 Oct 2026, the overnight audit's SM-14): the main button's words were 600 and a quiet
   one's 500 beside it. The main one is told by its fill, never by being bigger or bolder (the operator, "the main one is
   filled, never bigger"), so both are 500. */
:where(:root[data-app]) .wa-btn { font-weight: 500; }


/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   PHOTO SETS, AS PIXIESET LAYS A GALLERY OUT (the operator, 26 Sep 2026: "make the upload screen a bit more
   expansive"): the sets down the left, the open one on the right, empty as one big place to drop photos, full as a
   grid with a ⋮ on each; Drop your files here over it while files are dragged. And the floating menu a ⋮ opens.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.pn-pset { display: grid; grid-template-columns: 230px minmax(0, 1fr); gap: 14px; align-items: start; }
.pn-psets { position: sticky; top: 140px; padding: 12px 0; border-radius: var(--pn-r); background: var(--pn-face, rgba(255,255,255,.04)); border: 1px solid transparent; box-shadow: var(--pn-sh); }
.pn-psetsh { display: flex; align-items: center; justify-content: space-between; gap: 8px; padding: 0 14px 8px; }
.pn-psetsh .pn-dcovbtn { font-size: 14px; letter-spacing: 0; text-transform: none; }
.pn-psets ul { margin: 0; padding: 0; list-style: none; }
.pn-psets li { display: flex; align-items: center; }
/* the open set: the side item's soft fill in a 1.5px ink ring, so the column's lists stay one style (2 Nov 2026, the operator: go A) */
.pn-psets li.pn-cur { background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); }
.pn-psetpick { flex: 1; display: flex; align-items: center; gap: 8px; min-width: 0; min-height: 40px; padding: 0 14px; border: 0; background: none; color: inherit; font: inherit; font-size: 14px; text-align: left; cursor: pointer; }
.pn-psetpick span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-psetpick b { font-weight: 400; opacity: .6; font-variant-numeric: tabular-nums; }
.pn-psetpick b::before { content: "("; } .pn-psetpick b::after { content: ")"; }
.pn-psetmore { display: grid; place-items: center; width: 32px; height: 32px; margin-right: 6px; padding: 0; border: 0; border-radius: var(--pn-r); background: none; color: inherit; opacity: .6; cursor: pointer; }
.pn-psetmore .pn-gl, .pn-ptmore .pn-gl, .pn-gcmore .pn-gl { fill: currentColor; stroke: none; }
@media (hover: hover) { .pn-psetmore:hover { opacity: 1; background: var(--pn-hover, rgba(255,255,255,.08)); } .pn-psetpick:hover { background: var(--pn-hover, rgba(255,255,255,.04)); } }
/* the open set keeps its wash and its ring under the mouse: the hover is opaque in light and would paint over both */
@media (hover: hover) { .pn-psets li.pn-cur .pn-psetpick:hover { background: transparent; } }
/* a thumb's 44px for the gallery editor's text buttons and its set rows (UI audit, 30 Sep 2026) */
@media (pointer: coarse) { .pn-psetpick { min-height: 44px; } .pn-dcovbtn { position: relative; } .pn-dcovbtn::after { content: ""; position: absolute; inset: -7px 0; } }
.pn-dcovbtn .pn-gl { width: 14px; height: 14px; flex: none; }
.pn-pmain { position: relative; min-height: min(70vh, 720px); display: flex; flex-direction: column; }
.pn-pmhead { display: flex; flex-wrap: wrap; align-items: center; gap: 12px; margin-bottom: 14px; }
.pn-pmtitle:has(.pn-sub) { flex: 1 1 100%; }
.pn-pmtitle h2 { margin: 0; }
.pn-pmtitle .pn-sub { margin: 4px 0 0; max-width: 60ch; }
.pn-pempty { flex: 1; display: grid; align-content: center; justify-items: center; gap: 10px; min-height: 420px; padding: 32px 16px; border: 1px dashed var(--pn-edge, rgba(255,255,255,.22)); border-radius: var(--pn-r); text-align: center; }
.pn-pempty > .pn-gl { width: 48px; height: 48px; opacity: .5; stroke-width: 1.1; }
.pn-pempty > b { font-size: 15px; }
.pn-pempty > span { font-size: 12px; opacity: .7; }
.pn-pempty .wa-gl { gap: 8px; }
.pn-pempty .wa-gl .pn-gl { width: 18px; height: 18px; }
.pn-pwm { display: flex; align-items: center; gap: 10px; margin-top: 6px; font-size: 12px; }
.pn-pwm .wa-pwin { width: auto; min-width: 200px; }
.pn-pempty .pn-note { max-width: 46ch; margin: 6px 0 0; }
.pn-ptiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(132px, 1fr)); gap: 12px; }
.pn-ptile { position: relative; aspect-ratio: 1; border-radius: var(--pn-r); background: rgba(255,255,255,.05); overflow: hidden; }
.pn-ptimg { position: relative; display: grid; place-items: center; width: 100%; height: 100%; padding: 12px; border: 0; background: none; cursor: zoom-in; }
.pn-ptimg img { display: block; max-width: 100%; max-height: 100%; object-fit: contain; }
.pn-ptmore { position: absolute; top: 4px; right: 4px; display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--pn-r);
  background: rgba(20,18,16,.55); color: #fff; opacity: 0; cursor: pointer; transition: opacity .15s ease; }
.pn-ptile:hover .pn-ptmore, .pn-ptmore:focus-visible, .pn-ptmore[aria-expanded="true"] { opacity: 1; }
@media (hover: none) { .pn-ptmore { opacity: 1; } }
/* the gallery's Cover label: the same chip as a label on a photo in Events (.pn-cover .pn-badge, above) */
.pn-ptcover { bottom: 6px; display: inline-flex; align-items: center; text-transform: uppercase; }
.pn-dropover { position: absolute; inset: 0; z-index: 5; display: none; place-content: center; justify-items: center; gap: 10px; border: 2px dashed var(--pn-ink); border-radius: var(--pn-r);
  background: rgba(26,22,17,.9); font-size: 15px; pointer-events: none; }
.pn-dropover .pn-gl { width: 28px; height: 28px; color: var(--pn-ink); }
.pn-pmain.pn-over .pn-dropover { display: grid; }
.pn-psnote { height: auto; min-height: 120px; padding: 12px 14px; resize: vertical; line-height: 1.5; }
.pn-psmeta { display: flex; justify-content: space-between; gap: 12px; margin: 6px 0 0; }
.pn-psmeta span:last-child { flex: none; font-variant-numeric: tabular-nums; }
.pn-phview { text-align: center; }
.pn-phview img { display: inline-block; max-width: 100%; max-height: 70vh; }
.pn-gcmore { position: absolute; top: 8px; right: 8px; z-index: 2; display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 0; border-radius: var(--pn-r);
  background: rgba(20,18,16,.55); color: #fff; cursor: pointer; }
/* A GALLERY'S STAR, smaller, and it pops as it is ticked (the operator, 26 Sep 2026: "make relative text smaller,
   and the star smaller, and animated when ticked"); the line under the name is small print beside it */
.pn-gcard .pn-gstar { right: 46px; width: 32px; height: 32px; }
.pn-gcard .pn-gstar svg { width: 14px; height: 14px; }
.pn-gcw .pn-t { font-size: 12px; }
@keyframes pn-starpop { 0% { transform: scale(.55) rotate(-24deg); } 55% { transform: scale(1.3) rotate(8deg); } 100% { transform: none; } }
@keyframes pn-starring { from { box-shadow: 0 0 0 0 rgba(244,255,106,.55); } to { box-shadow: 0 0 0 12px rgba(244,255,106,0); } }
.pn-gstar.pn-starpop { animation: pn-starring .55s ease-out; }
.pn-gstar.pn-starpop svg { animation: pn-starpop .45s cubic-bezier(.2,.8,.2,1); }
@media (prefers-reduced-motion: reduce) { .pn-gstar.pn-starpop, .pn-gstar.pn-starpop svg { animation: none; } }
/* A GALLERY CARD'S STAR AND MORE SAY THEY ARE PRESSED (report 123, 6 Oct 2026: "theres no 2nd state on these buttons or
   indication they have been pressed. fix"): each disc darkens under a mouse and sinks while it is pressed; More turns
   light with dark dots while its menu is open, and a starred star keeps the darker disc under its yellow */
.pn-gstar, .pn-gcmore { transition: background-color .15s ease, color .15s ease, transform .1s ease; }
@media (hover: hover) { .pn-gstar:hover, .pn-gcmore:hover { background-color: rgba(12,11,10,.82); } }
.pn-gstar:active, .pn-gcmore:active { transform: scale(.9); }
.pn-gstar[aria-pressed="true"] { background-color: rgba(12,11,10,.82); }
.pn-gcmore[aria-expanded="true"], .pn-gcmore[aria-expanded="true"]:hover { background-color: #f2efe8; color: #1d1a16; }
@media (prefers-reduced-motion: reduce) { .pn-gstar, .pn-gcmore { transition: none; } .pn-gstar:active, .pn-gcmore:active { transform: none; } }
/* the floating menu: the dropdowns' look, the menus' face in the line with the card's shadow, in both themes from the
   tokens (2 Nov 2026, the operator: go A) */
.pn-pop { position: fixed; z-index: 96; display: flex; flex-direction: column; min-width: 210px; padding: 6px; border-radius: var(--pn-r); background: var(--pn-face-2, #2e2720);
  border: 1px solid var(--pn-line, rgba(255,255,255,.12)); box-shadow: var(--pn-sh); color: var(--pn-ink, #f7f2ea); animation: pn-ddin .14s ease-out;
  max-height: calc(100vh - 16px); max-height: calc(100dvh - 16px); overflow-y: auto; overscroll-behavior: contain; }
.pn-popitem { flex: none; display: flex; align-items: center; gap: 12px; min-height: 40px; padding: 0 12px; border: 0; border-radius: var(--pn-r); background: none; color: inherit; font: inherit; font-size: 14px; text-align: left; cursor: pointer; }
.pn-popitem .pn-gl { width: 18px; height: 18px; opacity: .8; }
.pn-popitem:hover, .pn-popitem:focus-visible { background: var(--pn-hover, rgba(255,255,255,.08)); outline: none; }
.pn-popitem:focus-visible { outline: 2px solid; outline-offset: -2px; }
.pn-popitem:disabled { opacity: .4; cursor: default; background: none; }
/* the chosen one (it carries the tick) washed as a dropdown's chosen row is, never bold (2 Nov 2026, the operator: go A) */
.pn-popitem:has(.pn-poptick) { font-weight: inherit; background: var(--pn-soft); }
.pn-popdanger { color: var(--st-bad); }
@media (pointer: coarse) { .pn-popitem { min-height: 44px; } }
@media (max-width: 760px) {
  .pn-pset { grid-template-columns: 1fr; }
  .pn-psets { position: static; }
  .pn-ptiles { grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); gap: 8px; }
  .pn-ptimg { padding: 6px; }
  .pn-pempty { min-height: 300px; }
}
:root[data-app][data-theme="light"] .pn-ptile { background: rgba(36,31,25,.05); }
:root[data-app][data-theme="light"] .pn-dropover { background: rgba(246,244,239,.94); }


/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE HEADER ON A COMPUTER, AS STUDIO NINJA'S (the operator, 26 Sep 2026: "for desktop, set up main header menu like
   these"): one row, the logo at the left, the pages in the middle each a glyph over its word with the open one in a
   soft box, and what is yours (light or dark, Account, Sign out) at the right. The band stays dark in both themes, as
   it always has, so the logo keeps its ground (the standing rule). A phone and a tablet keep the two rows above.
   A LITTLE MORE ROOM (report 82, 2 Oct 2026: "Increase space from logo to studio wording a tiny bit, and increase the
   height of the header a bit"): 14px above and below the row, not 8, so the band is 88px, not 76 (--pn-barh, which the
   side menus stick under, says so); STUDIO 4px further from the logo; a phone's two rows 3px more room, above them
   and, below 760, under them too. The logo keeps its sizes, its colours and its shapes. THE ROW AS WIDE AS THE PAGE (report 92): no
   1400px cap, so the logo starts where the side menu's words do and the glyphs end where the pages' content does.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.pn-navw { display: inline-flex; align-items: center; gap: 6px; }
.pn-mine { display: inline-flex; align-items: center; gap: 2px; }
@media (min-width: 980px) {
  .pn-bar-in { display: flex; align-items: center; gap: 12px; max-width: none; padding: 14px 24px; }
  .pn-top { display: contents; }
  .pn-top .pn-spacer { display: none; }
  .pn-bar .wa-lgbox { order: 1; }
  /* the logo bigger in the same band (report 13, 29 Sep 2026: "Make the logo bigger within the same header height"),
     and bigger again so its fine rings and its small "photography" are drawn across whole pixels (report 80, 2 Oct
     2026, a 1920px screen at 90% zoom: "it looks very aliased, until very zoomed in"; at 146 by 46 a ring was 0.6 of a
     screen pixel there): 168 by 53 from 980, the most the owner's row has room for at 980 with a scrollbar and a touch
     screen's glyphs, and 184 by 58 from 1240, below. Its own shape, shorter than the page tabs that set the band's
     height, so the band keeps it; only a size, never a colour or a shape, and on the dark band as ever */
  .pn-bar .wa-logo { width: 168px; height: 53px; }
  .pn-tag { order: 2; margin-left: 4px; }
  .pn-nav { order: 3; flex: 1 1 auto; flex-wrap: nowrap; justify-content: center; gap: 8px; margin: 0; }
  .pn-mine { order: 4; }
  .pn-nav .wa-pill { flex-direction: column; justify-content: center; gap: 5px; height: auto; min-width: 108px; padding: 10px 16px 9px;
    border-radius: var(--pn-r); font-size: 13px; color: rgba(242,239,232,.72); transition: background-color 140ms ease, color 140ms ease; }
  .pn-nav .wa-pill::after { display: none; }
  .pn-nav .pn-navgl { width: 21px; height: 21px; margin: 0; }
  .pn-nav .pn-groupbtn { gap: 5px; }
  .pn-nav .pn-count { position: absolute; top: 4px; right: 22px; margin: 0; }
  /* the open tile is no box: a 1px line under its word in the word's own colour, as the website's nav draws it (2 Nov
     2026, the operator: go A; 31 Oct 2026: no yellow underline anywhere). Its glyph stays moon yellow, a glyph and no line */
  .pn-nav [aria-current="page"] { background: transparent; color: #fff; }
  .pn-nav [aria-current="page"]::after { display: block; left: 22px; right: 22px; bottom: 3px; background: currentColor; }
  .pn-nav [aria-current="page"] .pn-navgl { color: var(--moon); }
  .pn-nav .pn-menu { top: calc(100% + 8px); }
}
@media (min-width: 980px) and (hover: hover) {
  .pn-nav .wa-pill:hover { background: rgba(255,255,255,.07); color: #fff; }
  .pn-nav [aria-current="page"]:hover { background: transparent; }
}
@media (min-width: 980px) and (prefers-reduced-motion: reduce) { .pn-nav .wa-pill { transition: none; } }
/* report 80: from 1240 the tabs are wider apart and the row has room to spare, so the logo is 184 by 58, a ring 0.9 of a
   pixel at 100% zoom and 1.1 at 125%, still shorter than the tabs' 59px */
@media (min-width: 1240px) { .pn-bar .wa-logo { width: 184px; height: 58px; } }
/* a touch screen's bigger buttons at the right took 2px more than a 980px window with a scrollbar has, and the page
   scrolled sideways (review, 28 Sep 2026: "yes fix"), so up to 1024 there the band's sides are 20px, not 24 */
@media (pointer: coarse) and (min-width: 980px) and (max-width: 1023px) { .pn-bar-in { padding-left: 20px; padding-right: 20px; } }


/* THE PHOTOGRAPHY MENU DOWN THE SIDE, as Pixieset's (26 Sep 2026: "then album gallery menu on the side like the second
   menu"): beside the galleries list, Gallery settings and Requests, on a computer; the page beside it gets the room */
.pn-side { display: none; }
@media (min-width: 980px) {
  .pn-wrap:has(> .pn-sidewrap) { max-width: 1320px; }
  .pn-sidewrap { display: grid; grid-template-columns: 210px minmax(0, 1fr); gap: 28px; align-items: start; }
  .pn-side { position: sticky; top: 96px; display: grid; gap: 2px; padding-top: 18px; }
}
/* a gallery's Design, Activity and Settings sections are side items too, from 980px (ONE SIZE A CONTROL, 15 Oct 2026: every
   Studio menu is the side menu's look); below it they are the pills of their row (THE SAME LISTS AS A ROW, below) */
.pn-sideitem, .pn-gsetlink { display: flex; align-items: center; gap: 14px; min-height: 44px; padding: 0 14px; border: 0; border-radius: var(--pn-r); background: none;
  color: inherit; font: inherit; font-size: 14px; text-align: left; text-decoration: none; cursor: pointer; }
.pn-sideitem .pn-gl, .pn-gsetlink .pn-gl { width: 20px; height: 20px; flex: none; opacity: .85; }
/* THE PICKED PLACE (2 Nov 2026, the operator: go A): a soft fill in a 1.5px ink ring, never bold */
.pn-sideitem[aria-current="page"], .pn-gsetlink[aria-current="true"], .pn-plcopt[aria-current="page"], .pn-ddopt[aria-selected="true"] { background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); font-weight: inherit; }
@media (hover: hover) { .pn-sideitem:not([aria-current="page"]):hover, .pn-gsetlink:not([aria-current="true"]):hover { background: var(--pn-hover, rgba(255,255,255,.05)); } }
/* its place; its colours and size are the header's red circle (THE COUNT IS A RED CIRCLE, below) */
.pn-sideitem .pn-count { margin-left: auto; display: inline-grid; place-items: center; font-variant-numeric: tabular-nums; }
.pn-sidek { margin: 18px 14px 6px; }
:root[data-app][data-theme="light"] .pn-sideitem[aria-current="page"], :root[data-app][data-theme="light"] .pn-gsetlink[aria-current="true"] { background: var(--pn-soft); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-sideitem:not([aria-current="page"]):hover, :root[data-app][data-theme="light"] .pn-gsetlink:not([aria-current="true"]):hover { background: var(--pn-hover); } }


/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   PHOTOGRAPHY, THE WHOLE WIDTH (the operator, 26 Sep 2026: "for photography side menu, take full width", with
   Pixieset's Collections and one gallery as the pictures): on a computer the side menu is a column from the header to
   the bottom of the window at its left edge, and the page fills the rest. One gallery has a bar across its top and its
   own column (the cover, the tabs as glyphs, the open tab's list).
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.pn-gtop { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; padding: 4px 0 14px; }
.pn-gback { display: grid; place-items: center; width: 40px; height: 40px; border-radius: var(--pn-r); color: inherit; }
.pn-gback .pn-gl { width: 20px; height: 20px; }
@media (hover: hover) { .pn-gback:hover { background: var(--pn-hover, rgba(255,255,255,.07)); } }
.pn-gtitle { min-width: 0; }
/* a gallery's name is its page's heading, in the display face at a page heading's size as every other page's (2 Nov
   2026, the operator: go A; it was the section heading's 15px in the words' face) */
:root[data-app] .pn-gtitle h1 { margin: 0; font-family: var(--font-display); font-size: 22px; font-weight: 300; line-height: 1.25; letter-spacing: -.01em;
  text-transform: none; color: var(--pn-t-ink); overflow-wrap: anywhere; text-wrap: balance; }
.pn-gtitle p { margin: 2px 0 0; font-size: 12px; opacity: .7; }
/* a gallery's state: the state chip (24px) as a plain label, and for the owner a button that opens its menu, the app's M
   (40px, 44 to a thumb, 8px corners) in the state chip's words and tones (ONE SIZE A CONTROL, 15 Oct 2026) */
.pn-gstate { display: inline-flex; align-items: center; gap: 6px; box-sizing: border-box; height: 24px; padding: 0 9px; border: 0; border-radius: var(--pn-r); font: inherit;
  font-size: 11px; font-weight: 400; line-height: 1; letter-spacing: .12em; text-transform: uppercase; white-space: nowrap; cursor: default;
  background: rgba(255,255,255,.1); color: inherit; border: 1px solid rgba(255,255,255,.14); }
button.pn-gstate { height: 40px; padding: 0 14px; border-radius: var(--pn-r); cursor: pointer; letter-spacing: .06em; }
.pn-gstate .pn-caret { width: 11px; height: 8px; }
.pn-gstate.pn-gs-live { background: var(--st-good-bg); color: var(--st-good); border-color: var(--st-good-line); }
/* PRE-RELEASE (lib/gallerywaiting.js): the link works as a sign-up page, so the pill is the warn tone, not off and not live */
.pn-gstate.pn-gs-soon { background: var(--st-warn-bg); color: var(--st-warn); border-color: var(--st-warn-line); }
/* the people waiting, at the top of every tab of a gallery (assets/app.js waitingCard), and the QR code in its sheet,
   always its own size: an image with no rule fills whatever holds it */
.pn-gwait { margin-bottom: 14px; }
.pn-gwait h2 { display: flex; align-items: center; gap: 8px; }
.pn-qrbox { width: min(100%, 240px); box-sizing: border-box; margin: 12px auto 0; padding: 10px; border-radius: var(--pn-r); background: #fff; }
.pn-qrbox img { display: block; width: 100%; height: auto; }
/* the owner's pill opens the state menu, so it is as tall as More, Preview and Share beside it on a touch screen; the
   same pill as a plain label (not the owner) stays small (design audit, 27 Sep 2026) */
@media (pointer: coarse) { button.pn-gstate { height: 44px; } }
/* ONE COLUMN THAT MAY BE NARROWER THAN A SET'S NAME (design audit, 27 Sep 2026): an auto column grew to the longest name,
   so the name never ended in dots, the Settings and Activity tabs and every set's More went out of sight, and on a
   phone the whole page scrolled sideways */
.pn-gside { display: grid; grid-template-columns: minmax(0, 1fr); gap: 10px; margin-bottom: 14px; }
.pn-gsidecover { display: none; padding: 0; border: 0; background: rgba(0,0,0,.25); color: inherit; font: inherit; font-size: 12px; opacity: 1; cursor: pointer; }
.pn-gsidecover img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pn-gsidetabs { display: flex; gap: 4px; border-bottom: 1px solid var(--pn-line, rgba(255,255,255,.09)); }
.pn-gsidetab { flex: 1; display: grid; grid-template-rows: auto auto; place-items: center; align-content: center; gap: 2px; min-width: 0; height: 52px; padding: 0; border: 0; border-bottom: 2px solid transparent; background: none; color: inherit; opacity: .6; cursor: pointer; }
.pn-gsidetab .pn-gl { width: 18px; height: 18px; }
.pn-gsidew { font-size: 10.5px; line-height: 1.2; }
/* the open tab underlined in the words' own colour, as the header's is (2 Nov 2026, the operator: go A; never a yellow underline) */
.pn-gsidetab[aria-selected="true"] { opacity: 1; border-bottom-color: currentColor; }
@media (hover: hover) { .pn-gsidetab:hover { opacity: 1; } }
.pn-gside .pn-psets { position: static; padding: 4px 0; background: none; border: 0; box-shadow: none; }
.pn-gside .pn-gsetnav { padding: 0; background: none; border: 0; box-shadow: none; }
.pn-gmain { min-width: 0; }
.pn-gmain .pn-gsetpane { padding: 0; }
/* ONE GALLERY'S SECTION HEADINGS sit at the page title's size, never above it (design audit, 27 Sep 2026: Arrivals and
   General were the browser's own 24px bold under a 16px title). Gallery settings keeps its own small capitals. */
.pn-gmain .pn-pmtitle h2, .pn-gmain .pn-gsetpane h2, .pn-gmain .pn-dahead h2 { margin: 0; line-height: 1.3; }
.pn-gmain .pn-gsetpane h2 { margin: 0 0 12px; }
@media (max-width: 979px) {
  /* the name on a line of its own, and the pill, More, Preview and Share together under it */
  .pn-gtitle { flex: 1 1 calc(100% - 60px); }
  .pn-gtop { gap: 8px; }
  .pn-gmain .pn-pmain, .pn-gmain .pn-gsetpane { padding: 16px; border-radius: var(--pn-r); background: var(--pn-face, rgba(255,255,255,.04)); border: 1px solid transparent; box-shadow: var(--pn-sh); }
}
/* NO BLANK BAND IN THE PHOTOS CARD ON A TOUCH SCREEN (3 Nov 2026, the Studio's UX pass): its least height is a drop target
   for files dragged in from a computer, which a phone or a tablet never does, so there the card ends under its last
   photos (an empty gallery keeps its own drop box, .pn-pempty) */
@media (max-width: 979px) and (pointer: coarse) { .pn-pmain { min-height: 0; } }
@media (min-width: 980px) {
  :root { --pn-barh: 88px; --pn-gut: 24px; }
  .pn-wrap:not(.dk) { padding-left: var(--pn-gut); padding-right: var(--pn-gut); }
  .pn-wrap:has(> .pn-sidewrap), .pn-wrap:has(> .pn-gpage) { max-width: none; padding: 0; }
  .pn-sidewrap { grid-template-columns: 240px minmax(0, 1fr); gap: 0; }
  .pn-side { position: sticky; top: var(--pn-barh); height: calc(100vh - var(--pn-barh)); align-content: start; padding: 16px 10px; overflow-y: auto;
    background: var(--pn-face, rgba(255,255,255,.03)); border-right: 1px solid var(--pn-line, rgba(255,255,255,.09)); }
  /* PINNED TO THE WINDOW (report 240, 27 Oct 2026, of a beige band under the side menu once the page had scrolled: "fix
     this globally", "The gap"): held to the window's left edge from under the header to its foot, so a page that
     scrolls never lifts it off the bottom; its column in the page is kept, and the page sits beside it as before */
  .pn-sidewrap > .pn-side { position: fixed; top: var(--pn-barh); bottom: 0; left: 0; width: 240px; height: auto; z-index: 2; }
  .pn-sidewrap > :not(.pn-side) { grid-column: 2; }
  .pn-sidemain { padding: 24px var(--pn-gut) 48px 32px; min-width: 0; }
  .pn-gtop { padding: 12px var(--pn-gut); border-bottom: 1px solid var(--pn-line, rgba(255,255,255,.09)); background: var(--pn-face, rgba(255,255,255,.03)); }
  /* ONE ROW ON A COMPUTER, WHATEVER THE NAME (3 Nov 2026, the Studio's UX pass): a long name wrapped the bar, leaving the
     pill and More on the right and Preview and Share alone on a line under it; the name now takes two lines in its own
     room and the controls keep theirs */
  .pn-gtop { flex-wrap: nowrap; }
  .pn-gtop > :not(.pn-gtitle):not(.pn-spacer) { flex: none; }
  /* THE PAGE IS THE WINDOW, NEVER MORE (3 Nov 2026, the operator: "scrolling when there's no elements past the page"):
     the side panel was the window's height under the header on top of the gallery's own bar, so every gallery scrolled
     that bar's height into nothing. Now the page is at least the window under the header, its body takes what the bar
     leaves, the side column's face and edge are painted down the body to the page's end, and the panel is as tall as
     its own list, held under the header and never taller than the window */
  .pn-gpage { display: flex; flex-direction: column; min-height: calc(100vh - var(--pn-bar-sp, var(--pn-barh))); min-height: calc(100dvh - var(--pn-bar-sp, var(--pn-barh))); }
  .pn-gbody { flex: 1 0 auto; display: grid; grid-template-columns: 240px minmax(0, 1fr); align-items: start;
    background: linear-gradient(to right, var(--pn-face, #26201a) 239px, var(--pn-line, rgba(255,255,255,.09)) 239px, var(--pn-line, rgba(255,255,255,.09)) 240px, transparent 240px); }
  .pn-gside { position: sticky; top: var(--pn-barh); max-height: calc(100vh - var(--pn-barh)); align-content: start; gap: 0; margin: 0; overflow-y: auto; }
  .pn-gsidecover { display: grid; place-items: center; aspect-ratio: 3 / 2; }
  .pn-gsidetabs { padding: 0 8px; }
  .pn-gside .pn-psets, .pn-gside .pn-gsetnav { padding: 12px 8px; }
  .pn-gmain { padding: 22px var(--pn-gut) 48px 32px; }
  /* the Photos fill the rest of the window as the drop target, whatever the room under them, never past it */
  .pn-gmain:has(> .pn-pmain) { align-self: stretch; display: flex; flex-direction: column; }
  .pn-gmain > .pn-pmain { flex: 1 0 auto; }
  .pn-gmain .pn-pmain { min-height: 0; background: none; border: 0; box-shadow: none; padding: 0; }
}
/* NO SIDE MENU, A COLUMN IN THE MIDDLE (report 107, 4 Oct 2026: "for pages that DONT have the side menu like the
   jobs/gallery/website, the content should sit in the middle, with left and right margin after a certain screen width
   like the main screen desk does"): a page with no side menu (the Settings home, Account, Activity) stops growing at
   1280px of content and sits in the middle of a wider window, as the desk's own column does; a page with a side menu
   still runs the window's width beside it (report 92), and the desk keeps its 1040px; the Inbox, its boxes its side
   menu, runs the window's width as Jobs does (11 Oct 2026) */
.pn-wrap:not(.dk):not(:has(> .pn-sidewrap)):not(:has(> .pn-gpage)):not(:has(> .ib)) { max-width: calc(1280px + 2 * var(--pn-gut, 16px)); }
:root[data-app][data-theme="light"] .pn-gstate { background: var(--pn-fill-hover); border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-gstate.pn-gs-live { background: var(--st-good-bg); color: var(--st-good); border-color: var(--st-good-line); }
:root[data-app][data-theme="light"] .pn-gstate.pn-gs-soon { background: var(--st-warn-bg); color: var(--st-warn); border-color: var(--st-warn-line); }

/* THE HEADER'S WORDS IN CAPITALS, THINNER (the operator, 26 Sep 2026: "make header text all caps and elegant (a bit
   thinner)"): the display face at a light weight; the open page a touch firmer. SET CLOSE, .06em, at every width (3 Nov
   2026), as the website's own header links since 31 Oct ("make the header nav squeezed") and every Studio button: .16em,
   .18em from 980px, sat wide beside them. */
.pn-nav .wa-pill { font-family: var(--font-display); font-size: 11.5px; font-weight: 350; letter-spacing: .06em; text-transform: uppercase; }
.pn-nav [aria-current="page"] { font-weight: 500; }
@media (min-width: 980px) { .pn-nav .wa-pill { font-size: 11.5px; letter-spacing: .06em; } }
@media (max-width: 519px) { .pn-nav .wa-pill { font-size: 11px; letter-spacing: .06em; } }
/* the header's glyphs and the side menus' a touch finer, beside the thinner words (26 Sep 2026: "also decrease glyph
   thickness a bit") */
.pn-bar .pn-gl, .pn-side .pn-gl, .ib-side .pn-gl, .pn-gsidetab .pn-gl, .pn-plcs .pn-gl { stroke-width: 1.3; }


/* DOWNLOAD ACTIVITY, as Pixieset's (26 Sep 2026): Gallery and Single photo as tabs under the title, sort and Export at
   the right, then the table */
.pn-dahead h2 { margin: 0; }
.pn-dabar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 18px; margin: 14px 0 10px; border-bottom: 1px solid var(--pn-line, rgba(255,255,255,.09)); }
.pn-dabar > .pn-pills { margin: 0 0 10px; }
.pn-dabar .pn-dcovbtn { font-size: 14px; font-weight: 600; text-decoration: none; }
.pn-dascroll { overflow-x: auto; }
.pn-datable { width: 100%; border-collapse: collapse; font-size: 13px; }
.pn-datable th { padding: 10px 12px; font-size: 11px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; text-align: left; color: var(--pn-muted, rgba(242,239,232,.6)); white-space: nowrap; }
.pn-datable td { padding: 9px 12px; border-top: 1px solid var(--pn-line, rgba(255,255,255,.08)); vertical-align: middle; }
.pn-datable td small { display: block; font-size: 11.5px; opacity: .6; }
.pn-daquiet { opacity: .55; }
.pn-dafile { display: flex; align-items: center; gap: 10px; min-width: 0; max-width: 360px; }
.pn-dathumb { flex: none; width: 40px; height: 40px; border-radius: var(--pn-r); object-fit: cover; background: rgba(255,255,255,.06); }
.pn-dazip { display: grid; place-items: center; }
.pn-dazip .pn-gl { width: 20px; height: 20px; }
.pn-daname { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-dawhen { white-space: nowrap; font-variant-numeric: tabular-nums; }
.pn-datag { margin-left: 6px; font-style: normal; }
:root[data-app][data-theme="light"] .pn-dathumb { background: var(--pn-fill); }

/* THE GALLERIES LIST ON A COMPUTER (26 Sep 2026: "make these tags smaller compared to the thumbnail preview/increase
   preview size"): the search, filters and Starred as small controls, and each gallery's preview bigger */
@media (min-width: 980px) {
  :root[data-app] .pn-glfilter .wa-pwin:not(textarea) { height: 32px; padding: 0 30px 0 12px; font-size: 12.5px; border-radius: var(--pn-r); }
  :root[data-app] .pn-glfilters .wa-gl { height: 32px; padding: 0 12px; font-size: 10.5px; }
  .pn-glfilters { gap: 6px; }
  .pn-gcards { grid-template-columns: repeat(auto-fill, minmax(320px, 1fr)); gap: 26px 20px; }
  .pn-gcw b { font-size: 15px; }
}


/* THE COUNT IS A RED CIRCLE (the operator, 26 Sep 2026: "add a red circle (notification type) with count in these two
   locations when there is anything to action"): on the header's Gallery button and on Requests in the side menu, and
   drawn only when something waits */
/* the red is a shade deeper than it was, so its white figure reads at 5.3:1 (design audit, 27 Sep 2026: 3.9:1) */
/* THE COUNT IN THE THEME YELLOW (report 241, 27 Oct 2026, of the red count on the header's Inbox: "change badges to
   the page theme yellow"): the logo's moon yellow with the ink's figure, 14:1, in place of the red */
.pn-nav .pn-count, .pn-nav [aria-current="page"] .pn-count, .pn-sideitem .pn-count, .pn-plcs .pn-count,
:root[data-app][data-theme="light"] .pn-sideitem .pn-count, :root[data-app][data-theme="light"] .pn-plcs .pn-count {
  background: var(--moon, #f4ff6a); color: #1b1712; box-shadow: 0 0 0 2px #241f19; }
/* the ring is the dark header's; the side menu has none in dark, and on light paper a hairline of ink so the yellow
   keeps its edge */
.pn-sideitem .pn-count, .pn-plcs .pn-count { box-shadow: none; }
:root[data-app][data-theme="light"] .pn-sideitem .pn-count, :root[data-app][data-theme="light"] .pn-plcs .pn-count {
  box-shadow: inset 0 0 0 1px rgba(27,23,18,.28); }


/* READY TO PUBLISH? (26 Sep 2026): the cover across the top of the sheet */
.pn-pubcover { margin: -4px 0 16px; aspect-ratio: 16 / 7; border-radius: var(--pn-r); overflow: hidden; background: rgba(0,0,0,.2); }
.pn-pubcover img { display: block; width: 100%; height: 100%; object-fit: cover; }
/* an unpublished gallery's dot is grey, a published one's green (26 Sep 2026: "add grey dot for unpublished items") */
.pn-gcw .pn-dot.pn-dim, .pn-gcw .pn-dot.pn-off,
:root[data-app][data-theme="light"] .pn-gcw .pn-dot.pn-dim, :root[data-app][data-theme="light"] .pn-gcw .pn-dot.pn-off { background: #b3aca3; }

/* A TALL PHOTO STAYS IN ITS SQUARE (26 Sep 2026: "images overlapping for vertical photos"): the photo is laid over the
   tile's inside edge and fitted, so neither side can run past it, whatever its shape */
.pn-ptimg img { position: absolute; inset: 12px; width: calc(100% - 24px); height: calc(100% - 24px); max-width: none; max-height: none; object-fit: contain; }
@media (max-width: 760px) { .pn-ptimg img { inset: 6px; width: calc(100% - 12px); height: calc(100% - 12px); } }


/* a take-down asker's email on the Requests page (26 Sep 2026: "add email"): a link that starts a reply */
.pn-qmail { color: inherit; text-decoration: underline; text-underline-offset: 2px; word-break: break-all; }


/* GALLERIES, GRID OR LIST (26 Sep 2026, Pixieset's Collections page as the picture): View presets, New gallery as a
   split button, the sort and the view as icons, and the list as a table */
/* one button in two halves (26 Sep 2026: "This button is broken"): the app's own corner rule beat the caret's, so it
   stood apart with four round corners and a shadow of its own. The pair now shares one shadow and one outline, with a
   short line between the halves in the button's own text colour, so it reads right in light and dark. */
.pn-split { display: inline-flex; border-radius: var(--pn-r); box-shadow: none; }
:root[data-app] .pn-split > .wa-btn { box-shadow: none; }
:root[data-app] .pn-split > .wa-btn:active { transform: none; }
:root[data-app] .pn-split > .wa-btn:first-child { border-top-right-radius: 0; border-bottom-right-radius: 0; }
:root[data-app] .pn-split > .pn-splitc { position: relative; width: 36px; min-width: 0; padding: 0; margin-left: 0;
  border-top-left-radius: 0; border-bottom-left-radius: 0; display: inline-grid; place-items: center; }
.pn-split > .pn-splitc::before { content: ""; position: absolute; left: 0; top: 10px; bottom: 10px; width: 1px; background: currentColor; opacity: .28; }
.pn-split > .pn-splitc .pn-gl { width: 16px; height: 16px; }
.pn-split > .pn-splitc .pn-caret { width: 12px; height: 8px; }
.pn-glicons { display: inline-flex; gap: 6px; margin-left: auto; }
.pn-glicon { width: var(--pn-h-act); min-width: 0; height: var(--pn-h-act); padding: 0; display: inline-grid; place-items: center; }
/* AN ICON BUTTON ON A FIELD'S LINE IS THE FIELD'S HEIGHT, its own width (9 Nov 2026: a field and its button on one row are one height and flush); the folded search's
   glyph has no field showing beside it, so it stays small */
:root[data-app] :is(.pn-sfold.pn-sopen, .pr-hol, .pn-row, .pn-srowin):has(> .wa-pwin) > .pn-glicon:not(.pn-sfoldbtn), :root[data-app] :is(.mn-step, .mn-line):has(.wa-pwin) > .pn-glicon { height: var(--pn-h-main); min-height: var(--pn-h-main); }
/* a glyph button's room kept where a row has none, so its others line up with the rows around it */
.pn-glblank { flex: none; pointer-events: none; }
.pn-popitem .pn-poptick { margin-left: auto; width: 16px; height: 16px; opacity: 1; }
/* positioned, so the headings' screen-reader words (.wa-sr, absolute) stay inside the table's own scroller and never
   widen the page (design audit, 27 Sep 2026) */
.pn-gltabwrap { position: relative; overflow-x: auto; }
/* Collections as a list sits on a card, as each gallery does in the grid (2 Nov 2026, the operator: go A) */
#gal-grid .pn-gltabwrap { background: var(--pn-face); box-shadow: var(--pn-sh); }
.pn-gltab { width: 100%; border-collapse: collapse; font-size: 14px; }
.pn-gltab th { padding: 8px 12px; text-align: left; font-size: 11px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase;
  color: var(--pn-muted, rgba(242,239,232,.6)); border-bottom: 1px solid var(--pn-line); white-space: nowrap; }
.pn-gltab td { padding: 10px 12px; border-bottom: 1px solid var(--pn-line); vertical-align: middle; }
.pn-gltab .pn-glthumb { width: 80px; padding-right: 0; }
.pn-gltab .pn-glthumb a { display: grid; place-items: center; width: 68px; height: 48px; border-radius: var(--pn-r); overflow: hidden; background: rgba(255,255,255,.06); }
.pn-gltab .pn-glthumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pn-gltab .pn-glname a { color: inherit; text-decoration: none; }
.pn-gltab .pn-glname a:hover b { text-decoration: underline; text-underline-offset: 3px; }
.pn-gltab .pn-glname a.pn-jblink { text-decoration: underline; text-underline-offset: 3px; text-decoration-color: currentColor; }
:root[data-app][data-theme="light"] .pn-gltab .pn-glname a.pn-jblink { text-decoration-color: currentColor; }
/* a title with one long word breaks inside it rather than widening the whole table; only the title, so the line under
   it and a client's email address never split mid-word (design audit, 27 Sep 2026) */
.pn-gltab .pn-glname b { overflow-wrap: anywhere; }
.pn-gltab .pn-glname .pn-t { display: block; margin-top: 2px; }
/* but on a phone, where the email is the line under the name, an address too long for the card breaks where it must (the
   UX review, 3 Nov 2026: one of 50 letters before the @ widened the column, and the row's More went past the card) */
.pn-gltab .pn-glname .pn-jbnarrow { overflow-wrap: anywhere; }
.pn-gltab .pn-glnum { font-variant-numeric: tabular-nums; white-space: nowrap; }
.pn-gltab .pn-glrowmenu { width: 52px; text-align: right; }
:root[data-app][data-theme="light"] .pn-gltab .pn-glthumb a { background: var(--pn-fill); }
@media (max-width: 720px) { .pn-gltab .pn-glopt { display: none; } }
.pn-gltab .pn-glthumb .pn-gcnone { font-size: 18px; line-height: 1; }


/* a picked button in a row of them (Requests' Waiting and Everything, the pages) reads in both themes (26 Sep 2026:
   "fix text in darkmode": the dark theme's button ground was beating the picked one and leaving dark words on it) */
:root[data-app][data-theme="dark"] .wa-gl.pn-on { background: var(--beige); color: #221d18; border-color: transparent; }
:root[data-app][data-theme="light"] .wa-gl.pn-on { background: var(--pn-ink); color: #f7f3ec; border-color: transparent; }


/* THE WATERMARK PREVIEW'S SIZE ON THE PAGE is set here, and its pixels follow it (drawMarkPreview) */
.pn-wmstage .pn-wmprev { width: min(100%, 720px); height: auto; max-height: none; }
.pn-wmstage .pn-wmprev.pn-tall { width: auto; height: min(520px, 70vh); max-width: 100%; }
/* A SAVE BUTTON: grey with nothing to save, Saved with a tick once it is done (the standing rule, 26 Sep 2026) */
.pn-savebtn { display: inline-flex; align-items: center; justify-content: center; gap: 6px; }
.pn-savebtn .pn-gl { width: 16px; height: 16px; }
.pn-savebtn[disabled] { cursor: default; }


/* Copied, on the line that was pressed (Get direct link, Share) */
.pn-copied { margin-left: 10px; font-style: normal; }
/* SMP's Favourite in the sets list: made by itself, so it says so and has no menu */
.pn-psetauto { align-self: center; margin-right: 8px; }
/* Refresh watermarks: the galleries that use the watermark, and the button under a gallery's own */
.pn-rmlist { list-style: none; margin: 0; padding: 0; display: grid; gap: 6px; max-height: 50vh; overflow-y: auto; }
.pn-rmlist li { display: flex; align-items: center; gap: 12px; padding: 8px 0; border-bottom: 1px solid var(--pn-line); }
.pn-rmlist li > span { flex: 1 1 auto; min-width: 0; display: grid; gap: 2px; }
.pn-remarkbtn { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; height: auto; min-height: 40px; padding-block: 8px;
  white-space: normal; text-align: left; }
@media (pointer: coarse) { .pn-remarkbtn { min-height: 44px; } }
.pn-remarkbtn .pn-gl, [data-gprefresh] .pn-gl { width: 16px; height: 16px; }
[data-gprefresh] { display: inline-flex; align-items: center; gap: 8px; }
.pn-rmdock { bottom: 16px; }


/* THE UPLOAD DOCK AS PIXIESET'S (26 Sep 2026): Uploading N items or Upload completed with a tick, N items uploaded, the
   sizes, the speed and the time left, then a row a file with where it is */
.pn-dock-hw { display: grid; gap: 1px; min-width: 0; }
.pn-dock-hw small { font-size: 11.5px; color: rgba(242,239,232,.6); font-variant-numeric: tabular-nums; }
.pn-dock-done { display: inline-grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--st-good); color: #16241a; flex: none; }
.pn-dock-done .pn-gl { width: 15px; height: 15px; stroke-width: 2.2; }
.pn-dock-files { max-height: 260px; }
.pn-uprow { display: flex; align-items: center; gap: 10px; padding: 6px 0; border-bottom: 1px solid rgba(255,255,255,.06); }
.pn-uprow > .pn-gl { width: 18px; height: 18px; flex: none; opacity: .6; }
.pn-uprw { display: grid; min-width: 0; flex: 1 1 auto; }
.pn-uprw b { font-size: 12.5px; font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-uprw small { font-size: 11px; color: rgba(242,239,232,.55); font-variant-numeric: tabular-nums; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-upst { flex: none; width: 18px; height: 18px; display: grid; place-items: center; font-style: normal; }
.pn-upst .pn-gl { width: 16px; height: 16px; stroke-width: 2; }
.pn-up-done .pn-upst { color: var(--st-good); }
.pn-up-refused .pn-upst, .pn-up-refused small { color: var(--st-bad); }
.pn-upspin { width: 14px; height: 14px; border-radius: 50%; border: 2px solid rgba(242,239,232,.25); border-top-color: var(--pn-y); animation: pn-upspin .8s linear infinite; }
@keyframes pn-upspin { to { transform: rotate(360deg); } }
/* a placeholder in the Photos grid while its file is on its way */
.pn-ptph { display: grid; place-content: center; justify-items: center; gap: 8px; }
.pn-ptph .pn-upspin { width: 20px; height: 20px; }
/* a placeholder on paper spins in the ink, as the yellow on a pale tile would not be seen (2 Nov 2026, the operator: go A) */
:root[data-app][data-theme="light"] .pn-ptph .pn-upspin { border-color: rgba(36,31,25,.18); border-top-color: var(--pn-ink); }
.pn-ptstate { font-size: 11px; letter-spacing: .06em; opacity: .7; }
.pn-ptnew img { display: block; width: 100%; height: 100%; object-fit: contain; }
@media (prefers-reduced-motion: reduce) { .pn-upspin { animation-duration: 2.4s; } }


/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE JOBS, THE LEADS AND THE CLIENTS: phase A of replacing Studio Ninja (the operator, 26 Sep 2026: "start A of the
   studio ninja now"). The two overviews and the Clients list wear the galleries' list table (.pn-gltab); one job's
   page has its groups as folds, as Studio Ninja's phone page has them (.pn-jbfold), the ones for later greyed;
   the sheets are covSheet's. Prefix .pn-jb, for jobs. Both themes; a phone at 375 px with no sideways scroll.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
/* A PART'S PLACES ON A PHONE ARE ONE DROPDOWN (report 71, 2 Oct 2026, Jobs in a computer's window narrowed to 492px,
   where its six places took two rows of three: "make this into a drop with glyphs, for other pages too on smaller
   displays"). Below 980px, where the side menu has no room, the places of Jobs, the Gallery, the Photobooth and the
   Website are one button the column's width: the open place's glyph, its name and its count, then the caret, 44px
   tall with a side menu place's 10px corners. It opens the app's own list (.pn-ddmenu with .pn-ddopt rows, frame.js's
   look for every dropdown, light and dark) under it and as wide as it: every place with the side menu's glyph, its
   count, and a tick on the open one. The list lies over the page inside the column, so the page never scrolls
   sideways, and under the header. From 980 the side menu, as before (assets/app.js placesDrop). It took the place of
   the segmented track (26 Sep 2026: "Any way to tidy these up it looks messy") and the thumb that slid along it. */
.pn-plcs { position: relative; margin-top: 12px; }
@media (min-width: 980px) { .pn-plcs { display: none; } }
.pn-plcbtn { display: flex; align-items: center; gap: 12px; width: 100%; min-height: 44px; margin: 0; padding: 0 14px;
  border: 1px solid var(--pn-p-line); border-radius: var(--pn-r); background: var(--pn-face, rgba(255,255,255,.04)); box-shadow: none;
  color: var(--pn-t-ink); font-family: var(--font-text); font-size: 14px; font-weight: 600; letter-spacing: 0; text-transform: none;
  text-align: left; cursor: pointer; -webkit-tap-highlight-color: transparent; }
.pn-plcbtn > .pn-gl, .pn-plcopt > .pn-gl { width: 20px; height: 20px; flex: none; opacity: .85; }
.pn-plcw { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-plcbtn > .pn-caret { width: 12px; height: 8px; flex: none; opacity: .7; transition: transform .16s ease; }
.pn-plcbtn[aria-expanded="true"] > .pn-caret { transform: rotate(180deg); }
.pn-plcbtn:focus-visible { outline: 2px solid var(--pn-t-ink); outline-offset: 2px; }
@media (hover: hover) { .pn-plcbtn:hover { box-shadow: inset 0 0 0 999px var(--pn-p-hover); } }
/* the list: the app's dropdown, held under its button rather than over the screen, above the page's own buttons */
.pn-plcs .pn-ddmenu.pn-plcmenu { position: absolute; top: calc(100% + 6px); left: 0; right: 0; z-index: 30; }
.pn-plcs .pn-ddmenu.pn-plcmenu[hidden] { display: none; }
.pn-plcopt { gap: 12px; text-decoration: none; }
.pn-plcbtn .pn-count, .pn-plcopt .pn-count { flex: none; display: inline-grid; place-items: center; font-variant-numeric: tabular-nums; }
@media (prefers-reduced-motion: reduce) { .pn-plcbtn > .pn-caret { transition: none; } }
.pn-jbexport { text-decoration: none; }
.pn-jbexport .pn-gl { width: 16px; height: 16px; }
[data-jbclear][hidden] { display: none; }
.pn-jbdate .pn-datein { width: 170px; }
/* the columns that sort: the heading is a button, and the one in use carries its arrow */
.pn-jbsort { display: inline-flex; align-items: center; gap: 4px; min-height: 32px; padding: 0; border: 0; background: none; color: inherit; font: inherit;
  letter-spacing: inherit; text-transform: inherit; cursor: pointer; white-space: nowrap; }
/* the arrow keeps its size when the heading wraps on a phone (design audit, 27 Sep 2026: it shrank to a 7px speck) */
.pn-jbsortgl { width: 13px; height: 13px; flex: none; }
.pn-jbtab tr.pn-jbgone td { opacity: .62; }
.pn-jbtab .pn-glname .pn-badge { margin-left: 6px; vertical-align: 1px; }
/* the type, with its colour as Studio Ninja shows one; the dot alone beside a job's name on its page */
.pn-jbtype { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }
.pn-jbtype::before { content: ""; flex: none; width: 9px; height: 9px; border-radius: 50%; background: var(--pn-jbt, #a39b8e); }
/* THE SHOOT TYPES' COLOURS (report 74, 2 Oct 2026; lib/shoottypes.js TONES): a fixed palette of twelve, each a class a
   type picks in Settings, Shoot types, never a colour written into the page. The first six are the colours the built-in
   types always had (Ball pink, Wedding lilac, Party blue, Corporate green, Portrait amber, Other and the photobooth
   stone), the same in light and dark as they always were, so nothing changed colour; the six added are a shade deeper
   on paper, below. */
.pn-tone-pink { --pn-jbt: #e36fa8; }
.pn-tone-lilac { --pn-jbt: #b89cf0; }
.pn-tone-blue { --pn-jbt: #4fa7e8; }
.pn-tone-green { --pn-jbt: #7fc98a; }
.pn-tone-amber { --pn-jbt: #f0b04a; }
.pn-tone-stone { --pn-jbt: #a39b8e; }
.pn-tone-red { --pn-jbt: #ef6f62; }
.pn-tone-orange { --pn-jbt: #f2884a; }
.pn-tone-teal { --pn-jbt: #45c2b6; }
.pn-tone-indigo { --pn-jbt: #8c95f2; }
.pn-tone-olive { --pn-jbt: #b5c25a; }
.pn-tone-brown { --pn-jbt: #c49473; }
:root[data-app][data-theme="light"] .pn-tone-red { --pn-jbt: #d4493c; }
:root[data-app][data-theme="light"] .pn-tone-orange { --pn-jbt: #d9692a; }
:root[data-app][data-theme="light"] .pn-tone-teal { --pn-jbt: #1f9a8f; }
:root[data-app][data-theme="light"] .pn-tone-indigo { --pn-jbt: #5b66d6; }
:root[data-app][data-theme="light"] .pn-tone-olive { --pn-jbt: #8a9a2c; }
:root[data-app][data-theme="light"] .pn-tone-brown { --pn-jbt: #9a6a48; }
/* SECTIONS (reports 72 and 74, 2 Oct 2026; lib/sections.js): a section's heading over its items in Settings, Products
   and Settings, Shoot types, and in the pickers that offer them. In Settings, the owner's Rename, Move up, Move down and
   Remove sit at the end of its line, wrapping under the name on a phone, 44px to a thumb. */
.pn-secgroup + .pn-secgroup { margin-top: 6px; }
.pn-sechead { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 14px; padding-bottom: 6px;
  border-bottom: 1px solid rgba(255,255,255,.12); }
.pn-sech { flex: 1 1 140px; min-width: 0; margin: 0; font-size: 11px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase;
  opacity: .85; overflow-wrap: anywhere; }
.pn-secacts { display: inline-flex; flex-wrap: wrap; gap: 6px; margin-left: auto; }
.pn-secacts .pn-gl { width: 16px; height: 16px; }
.pn-secnone { margin: 8px 0 0; }
.pn-secadds { gap: 8px; }
:root[data-app][data-theme="light"] .pn-sechead { border-bottom-color: var(--pn-line); }
/* a shoot type's colour, picked: each of the twelve its dot and its name, a radio, two or more to a row */
.pn-tonesbox { min-width: 0; margin: 10px 0 0; padding: 0; border: 0; }
.pn-tonesbox > legend { padding: 0; }
.pn-tones { display: grid; grid-template-columns: repeat(auto-fill, minmax(118px, 1fr)); gap: 6px; margin-top: 6px; border: 0; padding: 0; }
.pn-tone { display: flex; align-items: center; gap: 8px; min-height: 40px; padding: 0 10px; border: 1px solid rgba(255,255,255,.14);
  border-radius: var(--pn-r); font-size: 14px; cursor: pointer; }
.pn-tone input { margin: 0; accent-color: #f2efe8; }
.pn-tone:has(input:checked) { border-color: rgba(242,239,232,.7); box-shadow: inset 0 0 0 1px rgba(242,239,232,.7); }
.pn-tone:has(input:focus-visible) { outline: 2px solid currentColor; outline-offset: 2px; }
@media (pointer: coarse) { .pn-tone { min-height: 44px; } }
:root[data-app][data-theme="light"] .pn-tone { border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-tone input { accent-color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-tone:has(input:checked) { border-color: var(--pn-ink); box-shadow: inset 0 0 0 1px var(--pn-ink); }
/* the stage: booked is the panel's own badge; a lead, a completed job and an archived one each read apart */
.pn-badge.pn-jbst-lead { background: rgba(79,167,232,.14); color: #9fd0f5; border-color: rgba(79,167,232,.35); }
.pn-badge.pn-jbst-completed { background: var(--st-good-bg); color: var(--st-good); border-color: var(--st-good-line); }
.pn-badge.pn-jbst-archived { background: var(--pn-hover); color: var(--pn-muted); border-color: var(--pn-line); }
/* Studio Ninja's red mark beside the name of a job that clashes (report 81, 2 Oct 2026: "put the red flag (clash) next to
   the event title"; it sat under the date): right after the name, before the service badges, at every width */
.pn-jbclash { display: inline-grid; place-items: center; margin-left: 7px; vertical-align: -4px; color: var(--st-bad); }
.pn-jbclash .pn-gl { width: 17px; height: 17px; stroke-width: 1.8; }
/* a date is one form on one line, "Fri 2 Oct 2026" (9 Nov 2026) */
.pn-jbwkr { display: none; }
/* on a phone the type, the client and the stage go under the name, as their columns do not fit */
.pn-gltab .pn-glname .pn-jbnarrow, .pn-gltab .pn-glname .pn-jbphone { display: none; }
@media (max-width: 720px) {
  .pn-gltab .pn-glname .pn-jbnarrow { display: block; }
  /* a lead's shoot date, whose column is hidden, leads its times line */
  .pn-gltab .pn-glname .pn-jbphone { display: inline; }
  /* the date may take two lines, so the name has the room; the two date filters share a line */
  .pn-jbtab th, .pn-jbtab td { padding-left: 6px; padding-right: 6px; }
  .pn-jbtab td.pn-glnum, .pn-jbtab th:first-child { width: auto; white-space: nowrap; }
  .pn-jbtab .pn-jbsort { white-space: normal; text-align: left; }
  /* its head is Date alone, its first words there for a screen reader (2 Nov 2026, the operator: go A) */
  /* the two dates and the Sort icon share a line (140 + 140 + 44 and two gaps fit a 375px phone's 343), and Clear
     filters starts the next, so setting a filter never squeezes the dates or moves the Sort icon */
  .pn-jbdate { flex: 1 1 140px; }
  .pn-jbdate .pn-datein { width: 100%; }
  .pn-glfilters [data-jbclear] { order: 1; }
  /* THE SERVICE MADE IT THREE CHOICES (27 Sep 2026): on a phone the filters are an even two columns, the stage and the
     service, then the type and From, then To and the Sort icon, never a ragged row of boxes each its own width */
  .pn-jbfilters > .pn-glfilter { flex: 1 1 calc(50% - 4px); min-width: 0; }
  .pn-jbfilters > .pn-glfilter .pn-ddbtn.wa-pwin { width: 100%; }
}
/* THE SORT ICON on the Jobs, Leads and Clients lists (26 Sep 2026: "add an option to srot the cleints and leads and
   jobs"): Collections' own icon at the end of the filter row, square and as tall as the boxes beside it, 40px, 32px on
   a computer, and 44px on a touch screen, as every button there is */
.pn-jblink { color: inherit; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: currentColor; }

/* one job's page: its name and stage, Edit and More, then its groups as folds. EVERYTHING ON THE NAME'S LINE ON ONE
   MIDDLE (report 114, 5 Oct 2026: "this is not top down aligned"): the name kept its own 10px over and 4px under, so it
   sat 3px under the stage, the day and Edit job; the row has the room now, and the name none of its own */
.pn-jbtop { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin: 10px 0 4px; }
.pn-jbtop .pn-h { margin: 0; }
/* COPY THE TITLE (report 115, 5 Oct 2026: "add a copy title button next to the title"): a glyph close by the name and
   held with it, so a name of two lines on a phone keeps it beside it; no wash until the mouse is on it; 44px to a thumb,
   as every icon button is */
.pn-jbtitle { display: flex; align-items: center; gap: 4px; min-width: 0; }
.pn-jbtitle .pn-h { min-width: 0; }
:root[data-app] .pn-jbtop .wa-gl.pn-jbcopy { flex: none; width: var(--pn-h-act); min-height: var(--pn-h-act); height: var(--pn-h-act); padding: 0; background: transparent; border-color: transparent; }
@media (hover: hover) { :root[data-app] .pn-jbtop .wa-gl.pn-jbcopy:hover { background: var(--pn-fill-hover, rgba(255,255,255,.12)); } }
.pn-jbwhen { font-size: 13px; }
.pn-jbacts { display: inline-flex; align-items: center; gap: 8px; margin-left: auto; }
.pn-jbtop .wa-gl .pn-gl, .pn-jbcard .wa-gl .pn-gl { width: 16px; height: 16px; }
/* A JOB'S GROUPS ARE FOLDS (the operator, 28 Sep 2026, with Studio Ninja's job page on a phone: "Format the groups like
   the folds here - the bar looks too cluttered"): a row the whole width for each group, its glyph, its name, a count
   and a chevron that turns while it is open, hairlines between the rows, and an open fold's contents straight under
   its row. The row is the button: 56px tall on a phone or a touch screen and 52px with a mouse, never under 44px.
   Mail, Contracts and Files are folds like the rest since 28 Sep 2026 (assets/jobfolds.js). The chevron turns in a fifth of a second, and at once where the device asks for less motion. */
.pn-jbfolds { margin-top: 16px; border-top: 1px solid var(--pn-line); }
.pn-jbfold { border-bottom: 1px solid var(--pn-line); }
.pn-jbfh { margin: 0; font: inherit; }
.pn-jbfrow { display: flex; align-items: center; gap: 14px; width: 100%; min-height: 52px; padding: 0 10px; border: 0; background: none;
  color: inherit; font: inherit; font-size: 15px; line-height: 1.3; text-align: left; }
button.pn-jbfrow { cursor: pointer; }
@media (max-width: 759px), (pointer: coarse) { .pn-jbfrow { min-height: 56px; } }
.pn-jbfrow .pn-jbfgl { flex: none; width: 20px; height: 20px; opacity: .8; }
.pn-jbfname { min-width: 0; overflow-wrap: anywhere; }
.pn-jbfrow .pn-jbn[hidden] { display: none; }
.pn-jbfrow .pn-jbfchev { flex: none; width: 20px; height: 20px; margin-left: auto; opacity: .6; transition: transform .2s ease; }
.pn-jbfrow[aria-expanded="true"] .pn-jbfchev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .pn-jbfrow .pn-jbfchev { transition: none; } }
@media (hover: hover) { button.pn-jbfrow:hover { background: var(--pn-face); } }
.pn-jbfrow:focus-visible { outline-offset: -2px; border-radius: var(--pn-r); }
.pn-jbfin { padding: 2px 0 18px; }
.pn-jbfin[hidden] { display: none; }
.pn-jbfin > .pn-card:first-child, .pn-jbfin > .pn-jbgrid:first-child { margin-top: 0; }
.pn-jbgrid { display: grid; gap: 14px; margin-top: 14px; }
.pn-jbgrid > .pn-card { margin-top: 0; }
@media (min-width: 760px) { .pn-jbgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; } }
/* THEIR OTHER JOBS AND LEADS (Problem report 99, 3 Oct 2026; app.js clientPane): their box scrolls inside itself,
   snapped so each row lands whole at its top, and holds about five rows (59px each) when the cards are stacked. Side by side the
   card takes no height of its own (size containment) and is stretched to its row, so it is always the Client card's
   height, and the Client card never grows to match it; its box takes what the heading leaves. */
.pn-jbotherbox { max-height: 296px; overflow-y: auto; overscroll-behavior: contain; scroll-snap-type: y mandatory; border-radius: var(--pn-r); }
.pn-jbotherbox .pn-list li { scroll-snap-align: start; }
@media (min-width: 760px) {
  .pn-jbgrid.pn-jbclgrid { align-items: stretch; }
  .pn-jbclgrid > .pn-card:first-child { align-self: start; }
  .pn-jbclgrid > .pn-jbothers { contain: size; display: flex; flex-direction: column; }
  .pn-jbclgrid > .pn-jbothers > h3 { flex: none; }
  .pn-jbclgrid > .pn-jbothers > .pn-jbotherbox { flex: 1 1 0; min-height: 0; max-height: none; }
}
/* a job's card alone in the Job fold (no editing, booking or website card beside it) takes the whole width, as the
   other folds' cards do */
@media (min-width: 760px) { .pn-jbfin > .pn-jbgrid > .pn-card:only-child { grid-column: 1 / -1; } }
.pn-jbpane .pn-card h2 { display: flex; align-items: center; gap: 8px; }
.pn-jbpane .pn-card h2 .pn-gl { width: 16px; height: 16px; }
/* under a fold's row (an h2) its cards' names are h3s, in a card heading's own small capitals */
.pn-jbpane .pn-card h3 { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; }
.pn-jbpane .pn-card h3 .pn-gl { width: 16px; height: 16px; }
.pn-jbname { display: flex; align-items: flex-start; gap: 8px; margin: 0 0 12px; font-size: 16px; line-height: 1.35; overflow-wrap: anywhere; }
.pn-jbname > .pn-jbtype { margin-top: 6px; }
.pn-jbfact .pn-jbtype { margin-right: 8px; }
.pn-jbname > b { min-width: 0; }
.pn-jbname b { font-weight: 600; }
.pn-jbwho { margin: -6px 0 12px; font-size: 14px; }
/* A CARD'S FACTS, SPACED (report 52, 30 Sep 2026: "Space these lines they're too clumped", of a job's Job card on a
   phone): 14px between one fact and the next, as a settings row's own padding spaces its rows, and a job's and a
   client's cards 20px in from their edge, so a label never sits near the card's side. A fact whose words take two or
   three lines reads as one fact, the next clearly apart from it. */
.pn-jbpane .pn-card, .pn-card.pn-jbcard { padding: 20px; }
.pn-jbfacts { display: grid; gap: 14px; }
.pn-jbfact { display: grid; grid-template-columns: 116px minmax(0, 1fr); gap: 16px; font-size: 14px; line-height: 1.45; }
.pn-jbfact > span { color: var(--pn-muted); }
.pn-jbfact > b { font-weight: 500; overflow-wrap: anywhere; }
@media (max-width: 559.98px) { .pn-jbfacts { gap: 8px; } .pn-jbfact { grid-template-columns: 96px minmax(0, 1fr); gap: 8px; font-size: 13.5px; align-items: baseline; } }
.pn-jbwarn { display: flex; align-items: flex-start; gap: 10px; margin: 0 0 14px; padding: 10px 12px; border-radius: var(--pn-r); font-size: 14px; line-height: 1.5;
  background: var(--st-bad-bg); border: 1px solid var(--st-bad-line); color: var(--st-bad); }
.pn-jbwarn > .pn-gl { flex: none; width: 18px; height: 18px; margin-top: 2px; }
.pn-jbwarn a { color: inherit; }
.pn-jbwarn .pn-t { color: inherit; opacity: .8; }
/* EACH OTHER JOB'S WHEN, WHOLE (2 Oct 2026, report 78: "line is breakign into 2. dont somehow"): its name on its line,
   then its date and times on the next (assets/app.js clashWhen), and neither the date nor the times ever breaks inside
   itself; where even that line cannot fit, as on a 320px phone, it breaks between the date and the times alone. The
   same in the warning on a job's page, its clash sheet and a booking's. */
.pn-jbwarn > div { min-width: 0; overflow-wrap: anywhere; }
.pn-jbother, .pn-jbcw { display: block; }
.pn-jbcwday, .pn-jbcwtime { white-space: nowrap; }
textarea.wa-pwin.pn-jbnotein { min-height: 96px; }
.pn-jbnotes li { flex-wrap: nowrap; align-items: flex-start; }
.pn-jbnote { margin: 4px 0 0; font-size: 14px; line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; }

/* the sheets: Edit job, Add a new client and Edit client, as Studio Ninja lays them out */
.pn-jbsheet .pn-form { max-width: none; }
.pn-jbbox { padding: 14px; border-radius: var(--pn-r); background: var(--pn-face); border: 1px solid var(--pn-line); }
.pn-jbk { display: block; margin: 0 0 8px; font-size: 14px; font-weight: 600; letter-spacing: .02em; }
.pn-jbtab tbody tr { cursor: pointer; }
.pn-jbpick { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; }
.pn-jbpick > .wa-pwin, .pn-jbpick > .pn-sfold > .wa-pwin { flex: 1 1 240px; width: auto; min-width: 0; text-overflow: ellipsis; }
.pn-jbor { font-size: 13px; opacity: .7; }
.pn-jbaddc .pn-gl { width: 16px; height: 16px; }
/* A PICKED CLIENT IS A CARD (report 169, 11 Oct 2026: "this should be more indicative, not filed into a text box, maybe a
   card style with their name email etc"; app.js pickedCard): their name, the organisation they are with, their email and
   phone on the left, Change and the cross on the right, on the app's card face in its line; the secondary contact's the
   same, smaller. A long name or address breaks inside the card, never past it; at 320px the buttons go under the words.
   The row it stands for is hidden while it shows. */
.pn-jbpick[hidden], .pn-jbccard[hidden], .pn-jbcline[hidden], .pn-jbcorg[hidden] { display: none; }
.pn-jbccard { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 12px; padding: 12px 12px 12px 14px; border-radius: var(--pn-r);
  background: var(--pn-face-2, rgba(255,255,255,.06)); border: 1px solid var(--pn-line, rgba(255,255,255,.12)); }
.pn-jbcwho { display: grid; gap: 3px; flex: 1 1 180px; min-width: 0; }
.pn-jbcname { font-size: 16px; font-weight: 600; line-height: 1.3; overflow-wrap: anywhere; }
.pn-jbcorg { font-size: 13.5px; line-height: 1.35; opacity: .78; overflow-wrap: anywhere; }
.pn-jbcline { display: flex; align-items: center; gap: 7px; min-width: 0; font-size: 13.5px; line-height: 1.4; overflow-wrap: anywhere; opacity: .86; }
.pn-jbcline .pn-gl { flex: none; width: 15px; height: 15px; }
.pn-jbcline > span { min-width: 0; }
.pn-jbcacts { display: flex; align-items: center; gap: 8px; flex: none; margin-left: auto; }
.pn-jbcacts .pn-gl { width: 16px; height: 16px; }
.pn-jbccard2 { padding: 10px 10px 10px 12px; }
.pn-jbccard2 .pn-jbcname { font-size: 15px; }
:root[data-app][data-theme="light"] .pn-jbccard { background: var(--pn-face); border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-jbcorg, :root[data-app][data-theme="light"] .pn-jbcline { color: var(--pn-ink-soft); opacity: 1; }
/* THE CLIENTS FOUND, IN THE SHEET'S FLOW (report 33, 29 Sep 2026: "Scaled out browser breaks these clicks"): the last
   thing in the field's row, the whole row wide, so it pushes what is under it down and never lies over Add new client
   or Add secondary client contact; the dropdown's own look otherwise */
.pn-ddmenu.pn-jbclist { position: static; z-index: auto; order: 10; flex: 1 1 100%; min-width: 0; max-height: 264px; box-shadow: none; }
.pn-jbsep, .pn-sep { margin: 18px 0 14px; border: 0; border-top: 1px solid var(--pn-line, rgba(255,255,255,.09)); }
/* A PART OF ITS OWN IN A CARD (report 89, 2 Oct 2026, Settings, Email: "dividers need to be present where a separate
   item is shown but related. i.e. send test email should be under a divieder"): the job sheet's divider, as .pn-sep,
   over each part of a card that is separate but related (Email's test email, Business details' website half, Google
   sign-in's client ID and secret, Payments' Stripe dashboard and price check, Google Calendar's next job and lead). The
   line gives the room above what follows, so its heading, form or row adds none of its own. */
.pn-sep + :is(.mn-h3, .cn-h3, .pn-bizh, .pn-row, .pn-form, .pn-list) { margin-top: 0; }
.pn-bizform > .pn-sep { margin: 4px 0 0; }
.pn-jbtwo { display: grid; gap: 10px; }
@media (min-width: 520px) { .pn-jbtwo { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.pn-jbtimes { display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: end; gap: 8px; margin-top: 8px; }
.pn-jbtimes[hidden] { display: none; }
.pn-jbto { display: inline-flex; align-items: center; align-self: flex-end; height: var(--pn-h-main); padding-bottom: 0; font-size: 13px; opacity: .7; }
.pn-jbclashes li { flex-wrap: nowrap; align-items: flex-start; }
.pn-jbclashgl { flex: none; width: 18px; height: 18px; margin-top: 2px; color: var(--st-bad); }

/* WHAT A JOB IS FOR (the operator, 27 Sep 2026: "when new job is clicked in jobs, add a photography/videography/
   photobooth"; lib/jobs.js SERVICES). NEW JOB'S CHOOSER: three large, equal buttons in the preset cards' look
   (.pn-choice), side by side on a computer with the glyph over the words, stacked on a phone with the glyph at the
   left. Each is far over 44px tall, so a thumb cannot miss. */
.pn-sheet > .wa-card.pn-covsheet.pn-svsheet { max-width: 720px; }
.pn-svask { margin: 0 0 12px; }
.pn-svpick { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 10px; }
.pn-svchoice { width: 100%; min-height: 64px; margin: 0; padding: 16px; gap: 12px; justify-items: start; font: inherit; color: inherit; text-align: left; }
.pn-svchoice .pn-choicegl { width: 44px; height: 44px; }
.pn-svchoice .pn-choicegl .pn-gl { width: 24px; height: 24px; }
.pn-svchoice .pn-svtext { display: grid; gap: 4px; font-size: inherit; line-height: inherit; color: var(--pn-ink); }
.pn-svchoice .pn-svtext b { font-size: 15px; }
.pn-svchoice .pn-svtext > span { font-size: 13px; }
@media (max-width: 559px) {
  .pn-svpick { grid-template-columns: minmax(0, 1fr); }
  .pn-svchoice { grid-template-columns: auto minmax(0, 1fr); align-items: center; column-gap: 14px; padding: 14px; }
}
/* THE SERVICE'S BADGE: its glyph and its word, after a job's name in the lists and among a client's page's tags.
   An outline with no fill, so it never reads as the stage, which is a filled pill with a colour of its own (an archived
   job's the filled grey). Every corner is square now (2 Nov 2026, the operator: go A), so the fill parts them, not the shape */
.pn-jbsv { vertical-align: 1px; color: var(--pn-muted); background: transparent; border-color: var(--pn-edge); }
/* A BADGE FOR EACH SERVICE A JOB HAS (report 65, the operator, 2 Oct 2026: "where it has photography and v ideography
   show two badges, etc, photobooth etc", then "if its on mobile, just show the icons"; app.js svBadge). The badges sit
   together after the name with a small gap between them, the group 8px from the name as the one badge was. The group
   goes under the name whole when it does not fit beside it, and its badges wrap one under another when they do not
   fit the cell, every line of them starting level, so the table is never made wider. Among a client's page's tags
   each badge is one of the tags, spaced and wrapped as they are. */
.pn-jbsvs { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 4px; vertical-align: 1px; }
/* THE GAP AFTER THE NAME IS THE NAME'S OWN (report 130, 6 Oct 2026, at 1563 wide: "this is not aligned"): the 8px
   between a job's name and what follows it, its clash mark or its badges, is on the right of the name (and of the
   mark), never on the left of what follows, so whatever goes under a long name starts level with it rather than 8px
   in. A space at a line's end goes with the line, and so does a margin at its right. */
.pn-jbtab .pn-glname > a { margin-right: 8px; }
.pn-jbtab .pn-glname > .pn-jbclash { margin: 0 8px 0 0; }
.pn-clshtags .pn-jbsvs { display: contents; }
/* ON A PHONE, at the widths where the Jobs and Leads tables hide their other columns, each badge is its glyph alone.
   The word is still there for a screen reader, hidden as .wa-sr hides one (never display: none, which would hide it
   from the screen reader too), and the badge's title names it. A computer keeps the glyph and the word. */
@media (max-width: 720px) {
  .pn-jbtab .pn-jbsv { gap: 0; min-width: 24px; padding: 0 5px; justify-content: center; }
  .pn-jbtab .pn-jbsvw { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
/* NEW JOB'S PHOTOGRAPHERS, PICKED (report 135, 7 Oct 2026: "this should be a drop down, with a TBD option, greys out
   already allocated photographers"; app.js crewPicker): the app's dropdown adds one each time, and each one picked is a
   round tag under it, its name and a cross that takes them off, 44px to a finger on a touch screen, in a tag 46px tall
   so the cross fits inside its 1px edge (the review, 7 Oct 2026: it was 40px). Anyone picked is greyed in the list
   (.pn-ddopt:disabled) */
.pn-jbcrewlist { display: flex; flex-wrap: wrap; gap: 6px; margin: 8px 0 0; padding: 0; list-style: none; }
.pn-jbcrewlist[hidden] { display: none; }
.pn-jbcrewlist li { display: inline-flex; align-items: center; gap: 2px; box-sizing: border-box; max-width: 100%; height: 28px; padding: 0 2px 0 10px; border-radius: var(--pn-r);
  font-size: 12px; font-weight: 400; line-height: 1; background: var(--pn-hover); border: 1px solid var(--pn-p-line); }
.pn-jbcrewlist li > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-jbcrewoff { display: grid; place-items: center; flex: none; width: 24px; height: 24px; padding: 0; border: 0; border-radius: var(--pn-r); background: none; color: inherit; cursor: pointer; }
.pn-jbcrewoff .pn-gl { width: 14px; height: 14px; }
@media (hover: hover) { .pn-jbcrewoff:hover { background: var(--pn-line); } }
.pn-jbcrewoff:focus-visible { outline: 2px solid; outline-offset: -2px; }
@media (pointer: coarse) { .pn-jbcrewoff { width: 44px; height: 44px; margin: -8px -8px -8px -4px; } }
:root[data-app][data-theme="light"] .pn-jbcrewlist li { background: var(--pn-hover); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-jbcrewoff:hover { background: var(--pn-line); } }
/* "Pick a job type" above the service and type row, clear of the job's name above it (the type's box is the one marked) */
.pn-jbform > .pn-fieldmsg { margin-top: 12px; }
.pn-jbform > .pn-fieldmsg + .pn-jbtwo { margin-top: 6px; }

/* the same, in light */
:root[data-app][data-theme="light"] .pn-badge.pn-jbst-lead { background: rgba(40,110,170,.1); color: #1f5687; border-color: rgba(40,110,170,.28); }
:root[data-app][data-theme="light"] .pn-badge.pn-jbst-completed { background: var(--st-good-bg); color: var(--st-good); border-color: var(--st-good-line); }
:root[data-app][data-theme="light"] .pn-badge.pn-jbst-archived { background: var(--pn-hover); color: var(--pn-muted); border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-jblink { text-decoration-color: currentColor; }
:root[data-app][data-theme="light"] .pn-jbfolds, :root[data-app][data-theme="light"] .pn-jbfold { border-color: var(--pn-line); }
@media (hover: hover) { :root[data-app][data-theme="light"] button.pn-jbfrow:hover { background: var(--pn-face); } }
:root[data-app][data-theme="light"] .pn-jbfact > span { color: var(--pn-muted); }
:root[data-app][data-theme="light"] .pn-jbbox { background: var(--pn-face); }
:root[data-app][data-theme="light"] .pn-jbnote { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-svchoice .pn-svtext { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-jbsv { color: var(--pn-muted); background: transparent; border-color: var(--pn-edge); }

/* A JOB'S MAIL, CONTRACTS AND FILES (the operator, 28 Sep 2026: "go P4-6"; assets/jobfolds.js): a row an email, a desk
   thread or a file, its words wrapping and never pushing the page sideways, and its buttons 44px on a phone or a touch
   screen; a contract as the Job card's facts; the terms in a sheet that scrolls on its own. The desk's threads hidden
   from a job (report 77, 2 Oct 2026) fold away at the card's foot, as Settings' archived products do (.mn-fold). */
.jf-rows li { flex-wrap: nowrap; align-items: flex-start; }
/* NOTHING PAST THE CARD (reports 164 and 168, 10 and 11 Oct 2026, of a job's Communication on an iPhone: "Fix spill").
   The list is a grid, and its one column took the width of a row's buttons held on one line (Reply, Open in the Inbox,
   Open in Gmail and the cross), so every row's words ran past the card's edge with them. Now the column is the card's
   width and no more, a row's words take what is left beside its buttons or the whole line, and the buttons drop under
   the words when they do not fit beside them and wrap onto as many lines as they need, the cross with them. */
.jf-rows { grid-template-columns: minmax(0, 1fr); }
.jf-rows li.jf-row:not(.jf-file) { flex-wrap: wrap; }
.jf-row:not(.jf-file) > .pn-m { flex: 1 1 260px; }
/* A MESSAGE'S ROW (9 Nov 2026, of a lone cross on its own row): the words, with its cross at the top right and its links on one line under them */
.jf-rows li.jf-row:has(> [data-jfhide]) { display: grid; grid-template-columns: minmax(0, 1fr) var(--pn-h-act); gap: 8px; align-items: start; }
.jf-row:has(> [data-jfhide]) > .pn-m { grid-column: 1; grid-row: 1; }
.jf-row:has(> [data-jfhide]) > [data-jfhide] { grid-column: 2; grid-row: 1; }
.jf-row:has(> [data-jfhide]) > .jf-acts { grid-column: 1 / -1; grid-row: 2; flex-wrap: wrap; }
.jf-row > .pn-m > b { overflow-wrap: anywhere; }
.jf-row .pn-m > b { font-size: 14px; font-weight: 600; color: var(--pn-ink); }
.jf-row .pn-badge { margin-left: 4px; vertical-align: 1px; }
.jf-subj { display: block; margin-top: 4px; font-size: 14px; line-height: 1.45; overflow-wrap: anywhere; }
.jf-line { display: block; margin-top: 3px; overflow-wrap: anywhere; }
.pn-list .jf-why { color: var(--st-warn); }
.jf-snip { margin: 6px 0 0; font-size: 13px; line-height: 1.5; color: var(--pn-muted); overflow-wrap: anywhere; }
.jf-snip b { font-weight: inherit; }
.jf-row .pn-m > .pn-t.jf-line { font-size: 12px; color: var(--pn-muted); }
.jf-act { flex: none; }
.jf-file .jf-kind { flex: none; width: 18px; height: 18px; margin-top: 3px; opacity: .7; }
.jf-file .pn-m > b { font-size: 14px; }
.jf-acts { display: inline-flex; flex: none; align-items: center; gap: 6px; }
.jf-row:not(.jf-file) > .jf-acts { flex: 0 1 auto; flex-wrap: wrap; min-width: 0; max-width: 100%; }
/* and no button wider than its card (the review of 164 and 168 at 320px: Open Booking terms in Settings ran 3px past
   Contracts' card): on the narrowest phones a label longer than the card is wide wraps inside its button, which grows to
   hold it, 44px at least (the rule after the 44px one below, so it wins) */
.jf-acts > .wa-gl, .jf-btns .wa-gl { max-width: 100%; }
.jf-add { display: grid; gap: 8px; justify-items: start; margin: 0 0 12px; }
.jf-rules { margin: 0; font-size: 12px; line-height: 1.5; color: var(--pn-muted); }
.jf-msg { margin: 10px 0 0; }
.jf-msg:empty { display: none; }
.jf-same { display: block; margin-top: 2px; font-weight: 400; }
.jf-btns { flex-wrap: wrap; gap: 8px; }
/* the job page's Communication starts with Email the client (L7, 13 Oct 2026: "build 7"), a row of its own over its cards */
.jf-write { margin-bottom: 14px; }
.jf-termshead { margin: 0 0 10px; font-size: 12px; line-height: 1.5; color: var(--pn-muted); }
.jf-terms { max-height: min(62vh, 620px); overflow: auto; padding-right: 6px; font-size: 14px; line-height: 1.55; overflow-wrap: anywhere; }
.jf-terms h3 { margin: 16px 0 6px; font-size: 15px; font-weight: 600; }
.jf-terms h3:first-child { margin-top: 0; }
.jf-terms p { margin: 6px 0; }
.jf-terms ul { margin: 6px 0; padding-left: 20px; }
.jf-terms li { margin: 3px 0; }
.jf-hidden, .jf-ghidden { margin-top: 12px; border-top: 1px solid var(--pn-line); }
/* TEAM INVOICES, a group of their own under the client's emails (report 245, 28 Oct 2026) */
.jf-card .jf-teamk { margin: 16px 0 4px; padding-top: 14px; border-top: 1px solid var(--pn-line); }
.jf-hidden > summary, .jf-ghidden > summary { display: list-item; min-height: 44px; line-height: 44px; font-size: 11px; font-weight: 600; letter-spacing: .14em; text-transform: uppercase;
  opacity: .8; cursor: pointer; list-style-position: inside; }
@media (hover: hover) { .jf-hidden > summary:hover, .jf-ghidden > summary:hover { opacity: 1; } }
.jf-hidden .jf-rows, .jf-ghidden .jf-rows { margin-top: 0; }
:root[data-app][data-theme="light"] .jf-snip { color: var(--pn-muted); }
:root[data-app][data-theme="light"] .jf-rules, :root[data-app][data-theme="light"] .jf-termshead { color: var(--pn-muted); }
:root[data-app][data-theme="light"] .jf-terms { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .jf-hidden, :root[data-app][data-theme="light"] .jf-ghidden { border-top-color: var(--pn-line); }
:root[data-app][data-theme="light"] .jf-hidden > summary, :root[data-app][data-theme="light"] .jf-ghidden > summary { color: var(--pn-ink); }

/* A JOB AND ITS GALLERIES (P6; the operator, 28 Sep 2026: "go P4-6", "Job to gallery"; lib/jobgallery.js): in the Job
   fold, each gallery a row (its name, its status and photos under it, Open at the right); on a gallery's Settings, the
   job it is linked to or the jobs found to link it to, each with Link. Names wrap and never push the page sideways, and
   every button there, and the Job fold's own actions beside Make a gallery, is 44px on a phone or a touch screen. */
.jg-rows { margin-top: 4px; }
.jg-rows li.jg-row { flex-wrap: nowrap; }
.jg-facts { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-top: 6px; }
.jg-open { flex: none; }
.jg-name { margin: 0 0 4px; overflow-wrap: anywhere; }
.pn-galjob { display: flex; align-items: center; gap: 8px; margin: 4px 0; overflow-wrap: anywhere; }
.pn-galjob .pn-gl { flex: none; width: 18px; height: 18px; opacity: .75; }

/* ONE CLIENT'S PAGE (the operator, 26 Sep 2026: "this is the view that should come up when a client is clicked.
   details, connected shoots, leads payments etc"): the details and notes at the left, the narrower column; the leads,
   the jobs and the payments at the right. One column on a phone, the details first. */
.pn-jbgrid.pn-clgrid { margin-top: 10px; }
/* the details column never under 300px: at 1fr alone it was 265px on a 1024px screen beside the side menu, and an
   email address broke over three lines (26 Sep 2026) */
@media (min-width: 760px) { .pn-jbgrid.pn-clgrid { grid-template-columns: minmax(300px, 1fr) minmax(0, 1.6fr); } }
.pn-clcol { display: grid; gap: 14px; align-content: start; min-width: 0; }
.pn-clcol > .pn-card { margin-top: 0; }
.pn-clgrid .pn-card > .pn-sub:last-child { margin-bottom: 0; }
.pn-cldetails .pn-jbwho { margin: 0; color: var(--pn-muted); }
.pn-cldetails .pn-jbwho + .pn-jbfacts { margin-top: 14px; }
/* while the card is narrow (the left column on a tablet or a small laptop), each fact is its name over its value, so
   the value has the card's whole width, as a phone's facts are under 420px */
.pn-cldetails { container-type: inline-size; }
@container (max-width: 359px) { .pn-cldetails .pn-jbfact { grid-template-columns: minmax(0, 1fr); gap: 1px; } }
/* More is as tall as Edit client, or Edit job, beside it (buttons in a row match; the job's page too, design audit,
   27 Sep 2026); 44px on a touch screen (TOUCH TARGETS, THE REST, at the end) */
.pn-cldash { opacity: .5; }
.pn-clnotes { margin: 0; }
/* a client's email: its subject, then who and when under it, on a computer too (the UX pass, 3 Nov 2026: the two ran
   together on one line with no space, "...Formal" then "Priya Shah") */
.pn-clmailrow { display: flex; flex-direction: column; align-items: flex-start; gap: 2px; }
/* a card's heading with its count, and New lead or New job at its right */
.pn-clhead { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; margin: 0 0 12px; }
.pn-clhead h2 { margin: 0 auto 0 0; }
/* each lead and job, as Studio Ninja's cards */
.pn-clshoots { display: grid; gap: 10px; margin: 0; padding: 0; list-style: none; }
.pn-clshoot { padding: 12px 14px; border-radius: var(--pn-r); background: var(--pn-face); border: 1px solid var(--pn-line); }
.pn-clshtop { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0 0 10px; font-size: 15px; line-height: 1.35; overflow-wrap: anywhere; }
.pn-clshtop > a { min-width: 0; margin-right: auto; }
/* a client's page: the red mark stays beside the name, and the tags keep to the right after it (report 81) */
.pn-clshtop > a:has(+ .pn-jbclash) { margin-right: 0; }
.pn-clshtop > .pn-jbclash { margin: 0 auto 0 -3px; }
.pn-clshtop b { font-weight: 600; }
.pn-clshtags { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; font-size: 13px; }
:root[data-app][data-theme="light"] .pn-clshoot { background: var(--pn-face); border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-cldetails .pn-jbwho { color: var(--pn-muted); }

/* THE SECONDARY CLIENT CONTACT in New job and Edit job (26 Sep 2026: "add ability to add secondary contact"): its
   button under the client, then its own picker once pressed. A button is inline-flex, so hidden has to be said. */
.pn-jbc2 { margin-top: 14px; }
.pn-jbc2add { margin-top: 12px; }
.pn-jbc2[hidden], .pn-jbc2add[hidden] { display: none; }

/* THE PHOTOGRAPHERS ON A JOB, AND THE PHOTOGRAPHERS PAGE (the operator, 26 Sep 2026: "add a photographer tab with shifts
   under the jobs tab or section"). Under a job's Photographers fold each shift is a row: who, what they are doing, when and
   a note, four columns on a computer and one under another on a phone, and for the owner each place's own three
   buttons (report 25) at its right, or under it on a narrow phone. The Photographers page is a card a photographer,
   two to a row when wide. */
.pn-jbshifts li.pn-jbshift { display: grid; grid-template-columns: minmax(0, 1fr); gap: 3px; align-items: start; }
/* the person glyph stays beside the name, level with its first line, however long the name (design audit, 27 Sep
   2026: a long name wrapped whole under it and left the glyph alone on a line) */
.pn-jbshwho { display: flex; flex-wrap: nowrap; align-items: flex-start; gap: 6px 8px; min-width: 0; font-size: 15px; overflow-wrap: anywhere; }
.pn-jbshwho b { min-width: 0; font-weight: 600; }
.pn-jbshwho .pn-badge { flex: none; }
.pn-jbshgl { flex: none; width: 16px; height: 16px; margin-top: 3px; opacity: .7; }
.pn-jbshrole, .pn-jbshnote { font-size: 13px; color: var(--pn-muted); overflow-wrap: anywhere; }
.pn-jbshwhen { font-size: 14px; font-variant-numeric: tabular-nums; }
.pn-jbshifts .pn-jbshwhen .pn-t { font-size: 13px; }
.pn-jbshnote:empty { display: none; }
@media (min-width: 760px) {
  .pn-jbshifts li.pn-jbshift { grid-template-columns: minmax(140px, 1.1fr) minmax(110px, .8fr) minmax(180px, 1.5fr) minmax(0, 1.5fr); gap: 14px; align-items: center; }
  .pn-jbshnote:empty { display: block; }
}
/* EACH PLACE'S OWN BUTTONS (report 25): Fill, Edit and Remove on an open place, Edit, Replace and Take off on a filled
   one, glyphs 40px square and 44px to a thumb, at the place's right; on a narrow phone, under what it says */
.pn-jbshacts { display: flex; gap: 6px; justify-self: end; }
.pn-jbshifts li.pn-jbshboss { grid-template-columns: minmax(0, 1fr) auto; column-gap: 12px; }
.pn-jbshifts li.pn-jbshboss > .pn-jbshacts { grid-column: 2; grid-row: 1 / span 4; align-self: center; }
@media (max-width: 559.98px) {
  /* who and their role, then their hours and note, with the three small buttons at the top right */
  .pn-jbshifts li.pn-jbshboss > :not(.pn-jbshacts) { grid-column: 1; }
  .pn-jbshifts li.pn-jbshboss > .pn-jbshacts { grid-column: 2; grid-row: 1 / span 3; align-self: start; justify-self: end; }
}
@media (min-width: 760px) {
  .pn-jbshifts li.pn-jbshboss { grid-template-columns: minmax(140px, 1.1fr) minmax(110px, .8fr) minmax(170px, 1.4fr) minmax(0, 1.3fr) auto; }
  .pn-jbshifts li.pn-jbshboss > .pn-jbshacts { grid-column: auto; grid-row: auto; }
}
/* THE PICKER (report 25): the team who do the shift's role, each a row to press, then anyone else on past jobs, then a
   name typed; and Edit a shift, a box a field.
   ITS RHYTHM (report 76, the operator, 2 Oct 2026: "fix spacing", of Add a place, whose "On past jobs" sat right under
   the field over it, and its Fill and Replace with it). .pn-sheet p is the stronger rule, and it took every heading's
   own room away, so each one here is written to win it: the heading, then the step's question at the sheets' usual
   distance (New job's own, .pn-svask); then 18px above every list heading ("The team", "On past jobs") and above the
   name box, so a field and the list beside it never touch; a field's name 6px over its box. */
.pn-jbpksheet p.pn-jbstepask { margin: 0 0 12px; }
.pn-jbpksheet p.pn-jbpkhead { margin: 18px 0 8px; font-weight: 600; }
.pn-jbpksheet .pn-jbpklist > p.pn-sub { margin: 0; }
.pn-jbpksheet label.pn-form { gap: 6px; }
.pn-jbpksheet label.pn-form > .pn-note { margin: 0; }
.pn-jbpksheet p.pn-msg { margin: 8px 0 0; }
.pn-jbpksheet p.pn-msg:empty { min-height: 0; margin: 0; }
.pn-jbstepacts { margin-top: 18px; }
/* in a job's stepped sheet the row is the ink bar with the yellow press (2 Nov 2026, the operator: go A; the kit above) */
.pn-jbsheet .pn-jbstepacts { padding: 12px; }
.pn-jbpk { display: grid; gap: 6px; margin: 0; padding: 0; list-style: none; }
.pn-jbpkone { display: grid; gap: 2px; width: 100%; min-height: 44px; padding: 9px 12px; border: 1px solid var(--pn-line); border-radius: var(--pn-r);
  background: var(--pn-face); color: inherit; font: inherit; text-align: left; cursor: pointer; }
.pn-jbpkone > b { font-size: 15px; font-weight: 600; overflow-wrap: anywhere; }
.pn-jbpkone > span { font-size: 12.5px; opacity: .72; }
.pn-jbpkone:disabled { opacity: .5; cursor: default; }
.pn-jbpkone:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
@media (hover: hover) { .pn-jbpkone:not(:disabled):hover { background: var(--pn-soft); } }
:root[data-app][data-theme="light"] .pn-jbpkone { border-color: var(--pn-line); background: var(--pn-face); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-jbpkone:not(:disabled):hover { background: var(--pn-soft); } }
.pn-jbpkown { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 8px 10px; margin-top: 18px; }
.pn-jbpkown > .pn-form { flex: 1 1 200px; max-width: none; }
.pn-jbplace .pn-form { min-width: 0; }
.pn-jbplace select.wa-pwin, .pn-jbplace input.wa-pwin, .pn-jbplace .pn-ddbtn.wa-pwin { width: 100%; min-width: 0; }
/* ADD A TEAM MEMBER (report 75; app.js teamAdd): one sheet, a step at a time. 1, what they will do: New job's three
   large choices (.pn-svpick), the one picked before Back edged as a picked preset is. 2, who: the picker's lists, then
   Not sure yet, a row of its own edged in dashes as a team member still to find is, then a name typed. 3, their times:
   Start and Finish as Edit's, and under them whose times they start from. 4, the price: how it was worked out, in a box
   of its own, then the amount, then two buttons the same height, the filled one the main one; to 560px wide, where
   they and Back do not fit one row, they stack the sheet's width, the main one first and Back last. Since 5 Oct 2026
   (no second shooter: "they're all photographers") the choices are two, Photographer and Videographer, two columns on a
   computer and stacked on a phone, so no third column stands empty. */
.pn-svpick.pn-jbtypes { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (max-width: 559px) { .pn-svpick.pn-jbtypes { grid-template-columns: minmax(0, 1fr); } }
.pn-jbtypes .pn-choice[aria-pressed="true"] { border-color: transparent; background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-jbtypes .pn-choice[aria-pressed="true"] { border-color: transparent; background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); }
.pn-jbpk.pn-jbpknot { margin-top: 18px; }
.pn-jbpknot .pn-jbpkone { border-style: dashed; }
.pn-jbaddsheet .pn-jbtimes { margin-top: 0; }
.pn-jbpksheet p.pn-jbsame { margin: 10px 0 0; font-size: 13px; }
.pn-jbpksheet p.pn-jbhow { margin: 0 0 18px; padding: 12px 14px; border-radius: var(--pn-r); border: 1px solid var(--pn-line);
  background: var(--pn-hover); font-size: 15px; line-height: 1.5; color: var(--pn-ink); font-variant-numeric: tabular-nums; }
:root[data-app][data-theme="light"] .pn-jbpksheet p.pn-jbhow { background: var(--pn-hover); color: var(--pn-ink); }
.pn-jbsheet .pn-form.pn-jbprice { max-width: 240px; }
.pn-jbprice input.wa-pwin { width: 100%; min-width: 0; font-variant-numeric: tabular-nums; }
@media (max-width: 560px) {
  .pn-jbpriceacts { display: grid; grid-template-columns: minmax(0, 1fr); }
  .pn-jbpriceacts > .pn-spacer { display: none; }
  .pn-jbpriceacts > [data-jbaddinv] { order: -2; }
  .pn-jbpriceacts > [data-jbaddplain] { order: -1; }
}
/* A TOAST WITH A LINK (report 75: "A draft invoice for A$278.13 is in this job's Invoices.", Open the invoice): the
   app's toast, pressable and held for eight seconds, the link underlined in the toast's own colour and 44px tall to a
   thumb. */
.wa-toast.pn-toastlink { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 2px 12px; pointer-events: auto;
  animation: pn-toastlink 8s ease both; }
.pn-toastlink a { color: inherit; font-weight: 600; text-decoration: underline; text-underline-offset: 3px; }
@media (pointer: coarse) { .pn-toastlink a { display: inline-flex; align-items: center; min-height: 44px; } }
@keyframes pn-toastlink { 0% { opacity: 0; transform: translate(-50%, 8px); } 4%, 94% { opacity: 1; transform: translate(-50%, 0); } 100% { opacity: 0; transform: translate(-50%, 0); } }
/* A TOAST WITH AN ACTION (28 Oct 2026, the operator: "Also an undo in the popup after archiving for accidental"; common.js
   S.toast({ words, action })): its words and a real button, Undo, in the Studio's control corners, held six seconds
   (and while the button has the focus), so it only rises in and never fades out from under a press. */
.wa-toast.pn-toastact { animation: pn-toastin .2s ease both; }
.pn-toastbtn { appearance: none; margin: 0; min-height: 32px; padding: 0 14px; border-radius: var(--pn-r); border: 1px solid rgba(242,239,232,.42);
  background: transparent; color: inherit; font: inherit; font-weight: 600; cursor: pointer; }
.pn-toastbtn:hover { background: rgba(242,239,232,.12); }
.pn-toastbtn:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
@media (pointer: coarse) { .pn-toastbtn { min-height: 44px; } }
@keyframes pn-toastin { from { opacity: 0; transform: translate(-50%, 8px); } to { opacity: 1; transform: translate(-50%, 0); } }
@media (prefers-reduced-motion: reduce) { .wa-toast.pn-toastact { animation: none; } }
/* the Photographers page */
.pn-phgrid { display: grid; gap: 14px; }
.pn-phgrid > .pn-card { margin-top: 0; }
/* TWO COLUMNS THAT PACK (Problem report 98, 3 Oct 2026: "there's awkward gaps. fix."): from 1180px the cards run down
   the left column and on down the right, To fill first at the top left, each card straight under the one above it with
   the 14px gap, the two columns balanced by the browser. A card is never split between the columns, and keeps its full
   height. The columns are worked out again for every list drawn (a filter, a search, Show all) and every width. */
@media (min-width: 1180px) {
  .pn-phgrid { display: block; columns: 2; column-gap: 14px; }
  .pn-phgrid > .pn-card { display: block; break-inside: avoid; margin: 0 0 14px; }
}
.pn-phhead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 12px; margin: 0 0 6px; }
.pn-phhead > .pn-t { font-size: 13px; color: var(--pn-muted); font-variant-numeric: tabular-nums; }
.pn-phcard h2 { display: flex; align-items: center; gap: 8px; margin: 0 auto 0 0; overflow-wrap: anywhere; }
.pn-phcard h2 .pn-gl { flex: none; width: 17px; height: 17px; opacity: .75; }
.pn-phshifts li.pn-phrow { display: grid; grid-template-columns: 116px minmax(0, 1fr); gap: 2px 12px; align-items: baseline; }
.pn-phday { font-size: 13px; color: var(--pn-muted); font-variant-numeric: tabular-nums; }
.pn-phrow .pn-m .pn-t { display: block; margin-top: 2px; }
@media (max-width: 420px) { .pn-phshifts li.pn-phrow { grid-template-columns: minmax(0, 1fr); } }
:root[data-app][data-theme="light"] .pn-jbshrole, :root[data-app][data-theme="light"] .pn-jbshnote,
:root[data-app][data-theme="light"] .pn-phhead > .pn-t, :root[data-app][data-theme="light"] .pn-phday { color: var(--pn-muted); }

/* THE EDITING CARD on a job's page (27 Sep 2026: "is the to edit completion tracked?", then "yes"): each photographer's
   album a row, its ring ticked once it is edited, and when; the when under the name on a phone and at the row's end
   when there is room. */
.pn-jbalbums { margin-top: 12px; }
.pn-jbalbums li.pn-jbalbum { display: grid; grid-template-columns: minmax(0, 1fr); gap: 2px; align-items: start; }
.pn-jbalwho { display: flex; flex-wrap: nowrap; align-items: flex-start; gap: 8px; min-width: 0; font-size: 15px; overflow-wrap: anywhere; }
.pn-jbalwho b { min-width: 0; font-weight: 600; }
.pn-jbalgl { flex: none; width: 18px; height: 18px; margin-top: 1px; opacity: .5; }
.pn-jbaldone .pn-jbalgl { opacity: 1; color: var(--st-good); }
.pn-jbalwhen { padding-left: 26px; font-size: 13px; color: var(--pn-muted); font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
@container (min-width: 420px) {
  .pn-jbalbums li.pn-jbalbum { grid-template-columns: minmax(0, 1fr) auto; gap: 12px; align-items: center; }
  .pn-jbalwhen { padding-left: 0; text-align: right; }
}
.pn-jbedcard { container-type: inline-size; }
/* ITS TICKS (report 7, 28 Sep 2026: "Remove the go to desk. This should be cross-synced"): Delivered and each album a
   checkbox button, its ring and its name, the Desk's own ticks too. 44px tall to a thumb, without making the row
   taller than the words need; the ring a little stronger than a plain row's, as it can be pressed, and green with its
   tick once done, as before. */
.pn-jbtick { display: flex; align-items: center; gap: 8px; min-width: 0; min-height: 36px; margin: -6px 0; padding: 0 8px 0 0; border: 0;
  border-radius: var(--pn-r); background: none; color: inherit; font: inherit; font-size: 15px; line-height: 1.4; text-align: left; cursor: pointer;
  overflow-wrap: anywhere; -webkit-tap-highlight-color: transparent; }
.pn-jbtick b { min-width: 0; font-weight: 600; }
.pn-jbtick .pn-jbalgl { margin-top: 0; }
.pn-jbalbum:not(.pn-jbaldone) .pn-jbtick .pn-jbalgl { opacity: .75; }
@media (hover: hover) { .pn-jbalbum:not(.pn-jbaldone) .pn-jbtick:hover .pn-jbalgl { opacity: 1; } }
.pn-jbtick:focus-visible { outline-offset: 2px; }
@media (pointer: coarse) { .pn-jbtick { min-height: 44px; margin: -10px 0; } }
:root[data-app][data-theme="light"] .pn-jbalwhen { color: var(--pn-muted); }


/* JOBS AS CALCULATOR CARDS (2 Nov 2026, the operator: "redesign the entire studio to match the website/calculator
   style", then of five options "go A"). The Jobs, Leads and Clients lists are each a card on the paper ground with the
   calculator's shadow round it, their headings the spaced label in the muted ink, a row washed under the mouse and no
   line under the last. A job's folds stay rows between hairlines on the ground, as the website's questions are, each
   open fold's cards the app's own cards under its row, never a card in a card. The count beside a fold's name, and
   beside a card's heading on a client's page and the Photographers page, is the yellow tag (the calculator's .sc-mark)
   in the count's own size. New job's choices and Add a team member's are the calculator's option rows: a hairline on
   the card's face, the soft wash under a mouse, the glyph on the yellow. Square, from --pn-r; both themes from the
   roles. Nothing here changes a size, a fold, an order or a hook. */
:root[data-app] .pn-gltabwrap:has(> .pn-jbtab) { background: var(--pn-face); box-shadow: var(--pn-sh); }
:root[data-app] .pn-gltab.pn-jbtab th { opacity: 1; color: var(--pn-muted); font-weight: 500; letter-spacing: .16em; }
/* the column it is sorted by in ink, the rest muted, so the headings agree with the menu on the sort (report 40) */
:root[data-app] .pn-gltab.pn-jbtab th[aria-sort] { color: var(--pn-ink); }
:root[data-app] .pn-gltab.pn-jbtab tbody tr:last-child td { border-bottom-color: transparent; }
@media (hover: hover) { :root[data-app] .pn-gltabwrap .pn-gltab.pn-jbtab tbody tr:hover { background: var(--pn-hover); } }
:root[data-app] :is(.pn-jbfrow, .pn-clhead h2, .pn-phhead h2) .pn-jbn { background: var(--pn-y); color: var(--pn-on-y); }
:root[data-app] .pn-svpick .pn-choice.pn-svchoice:not([aria-pressed="true"], [aria-checked="true"]) { border-color: var(--pn-line); background: var(--pn-face); }
@media (hover: hover) { :root[data-app] .pn-svpick .pn-choice.pn-svchoice:not([aria-disabled="true"], [aria-pressed="true"], [aria-checked="true"]):hover { border-color: var(--pn-line); background: var(--pn-soft); } }
:root[data-app] .pn-svpick .pn-svchoice .pn-choicegl { background: var(--pn-y); color: var(--pn-on-y); }
:root[data-app] .pn-svchoice .pn-svtext > span { color: var(--pn-muted); }

/* COLLECTIONS AT EVERY WIDTH (the operator, 26 Sep 2026: "Can we fix these clutter on mobile", then 28 Sep 2026: "Fix
   this clutter under collections", at a width between a phone and a computer, where View presets and New gallery took
   a line of their own and the filters ran over two lines with Sort and View stranded at the right). Line one:
   Collections at the left and New gallery at the right, with View presets beside it only where the three fit (it is in
   New gallery's menu as well); the search the full width under them; then the filter row. The row is ONE line where
   the four filters, Starred, Sort and View all fit, Sort and View at the far right; where they do not, it folds: the
   Filters button with its count at the left, Sort and View at the right, and the four and Starred under it two to a
   line once it is open. What decides it is the width the list really has (a container query on .pn-colbar, the head and
   the row together), so the side menu is counted whether it is there or not, and never a wrap that strands a part.
   Every part of a line is one height, padding and text size: 32px on a computer, 40px in a narrower window, 44px on a
   phone or a touch screen, as the app's buttons are; New gallery is the one filled, and no bigger.
   The widths each line needs were measured (28 Sep 2026): the head's three 445 to 460px at any size, so View presets
   shows from 480; the row 635px at 32px, 725px at 40px and 731px at 44px (its icons are wider), so it goes to one line
   from 660, 760 and 780. */
.pn-colbar { container: colbar / inline-size; }
.pn-colhead .pn-h { flex: none; white-space: nowrap; }
.pn-colhead .pn-glpresets, .pn-colhead .pn-split { flex: none; }
.pn-colhead .pn-glsearch { flex: 1 1 100%; }
:root[data-app] .pn-colhead .pn-split > .wa-btn { height: 40px; }
:root[data-app] .pn-colhead .pn-glsearch:not(textarea) { height: 40px; }
@container colbar (max-width: 479.98px) { .pn-colhead .pn-glpresets { display: none; } }
/* a 360px phone: Collections a touch smaller and closer set, so New gallery still has its place beside it */
@container colbar (max-width: 349.98px) { .pn-colhead .pn-h { font-size: 20px; letter-spacing: .1em; } }

.pn-glfbtn { display: none; }
.pn-glfbtn .pn-gl { width: 16px; height: 16px; }
.pn-glfn[hidden] { display: none; }

/* FOLDED, a grid: Filters at the left and Sort and View at the right of the first line, then the four filters two to a
   line, and Starred across the whole width */
.pn-colfilters { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; align-items: center; }
.pn-colfilters .pn-glfbtn { display: inline-flex; align-items: center; gap: 8px; grid-column: 1; grid-row: 1; justify-self: start; }
.pn-colfilters .pn-glicons { grid-column: 2; grid-row: 1; justify-self: end; margin: 0; }
.pn-colfilters > .pn-glfilter, .pn-colfilters > .pn-glstarred { display: none; }
.pn-colfilters.pn-open > .pn-glfilter { display: block; min-width: 0; }
.pn-colfilters.pn-open > .pn-glstarred { display: inline-flex; justify-content: center; }
:root[data-app] .pn-colfilters .pn-glstarred { height: var(--pn-h-main); min-height: var(--pn-h-main); font-size: 14px; font-weight: 400; letter-spacing: 0; text-transform: none; }
:root[data-app] .pn-colfilters .pn-glfilter .pn-ddbtn.wa-pwin { width: 100%; }

/* ONE SIZE A LINE: a dropdown is the main size (40px, 44 to a thumb); Filters and the view's glyphs are a row's */
:root[data-app] .pn-colfilters .pn-glfilter .wa-pwin:not(textarea) { height: var(--pn-h-main); min-height: var(--pn-h-main); border-radius: var(--pn-r); }
@media (pointer: coarse), (max-width: 560px) {
  :root[data-app] .pn-colhead .pn-split > .wa-btn, :root[data-app] .pn-colhead .pn-glsearch:not(textarea) { height: 44px; }
  :root[data-app] .pn-colhead .pn-split > .pn-splitc { width: 44px; }
}

/* ON ONE LINE WHERE THEY ALL FIT: at 44px from 780, at 40px from 760, at 32px from 660. Each filter is as wide as its
   words, and where long choices together want more room than the line has, they share what there is, the short ones
   kept whole and the long ones ending in dots, so a picked filter never breaks the line. */
@container colbar (min-width: 780px) {
  .pn-colfilters, .pn-colfilters.pn-open { display: flex; flex-wrap: nowrap; }
  .pn-colfilters .pn-glfbtn { display: none; }
  .pn-colfilters > .pn-glfilter, .pn-colfilters.pn-open > .pn-glfilter { display: block; flex: 1 1 0; min-width: 0; max-width: max-content; }
  .pn-colfilters > .pn-glstarred, .pn-colfilters.pn-open > .pn-glstarred { display: inline-flex; flex: none; }
  .pn-colfilters .pn-glicons { flex: none; margin-left: auto; }
  :root[data-app] .pn-colfilters .pn-glfilter .pn-ddbtn.wa-pwin { width: auto; max-width: 100%; }
  :root[data-app] .pn-colfilters .pn-glicon { width: var(--pn-h-main); height: var(--pn-h-main); min-height: var(--pn-h-main); }
}
@media (pointer: fine) and (min-width: 561px) {
  @container colbar (min-width: 760px) {
    .pn-colfilters, .pn-colfilters.pn-open { display: flex; flex-wrap: nowrap; }
    .pn-colfilters .pn-glfbtn { display: none; }
    .pn-colfilters > .pn-glfilter, .pn-colfilters.pn-open > .pn-glfilter { display: block; flex: 1 1 0; min-width: 0; max-width: max-content; }
    .pn-colfilters > .pn-glstarred, .pn-colfilters.pn-open > .pn-glstarred { display: inline-flex; flex: none; }
    .pn-colfilters .pn-glicons { flex: none; margin-left: auto; }
    :root[data-app] .pn-colfilters .pn-glfilter .pn-ddbtn.wa-pwin { width: auto; max-width: 100%; }
    :root[data-app] .pn-colfilters .pn-glicon { width: var(--pn-h-main); height: var(--pn-h-main); min-height: var(--pn-h-main); }
  }
}
@media (pointer: fine) and (min-width: 980px) {
  @container colbar (min-width: 660px) {
    .pn-colfilters, .pn-colfilters.pn-open { display: flex; flex-wrap: nowrap; }
    .pn-colfilters .pn-glfbtn { display: none; }
    .pn-colfilters > .pn-glfilter, .pn-colfilters.pn-open > .pn-glfilter { display: block; flex: 1 1 0; min-width: 0; max-width: max-content; }
    .pn-colfilters > .pn-glstarred, .pn-colfilters.pn-open > .pn-glstarred { display: inline-flex; flex: none; }
    .pn-colfilters .pn-glicons { flex: none; margin-left: auto; }
    :root[data-app] .pn-colfilters .pn-glfilter .pn-ddbtn.wa-pwin { width: auto; max-width: 100%; }
    :root[data-app] .pn-colfilters .pn-glicon { width: var(--pn-h-main); height: var(--pn-h-main); min-height: var(--pn-h-main); }
  }
}


/* LIVE IS GREEN in the Collections list (26 Sep 2026: "Make the label green for live"), the same green as a gallery's own
   status pill: the badge's good tone, .pn-badge.pn-good (above). Never .pn-live on a badge: since 13 Oct 2026 that is the
   live notices' box, fixed at the bottom right (below), and it pinned a gallery's Live, a job's Sent and the
   changelog's New feature there (15 Oct 2026) */


/* the Starred filter's star, filled while the filter is on */
.pn-glstarred { gap: 7px; }
.pn-glstarred .pn-gl { width: 15px; height: 15px; }
.pn-glstarred[aria-pressed="true"] .pn-gl { fill: currentColor; }

/* THE JOBS AND LEADS LISTS AT EVERY WIDTH (the operator, 28 Sep 2026: "yes fix", for the Jobs list's filters, which
   wrapped at a tablet's width and left To date on a line of its own with Sort stranded at the right, the fault
   Collections had). Done as Collections is done (above). The head: Jobs, the search, Export jobs and New job on one
   line where the search still has a useful width, and otherwise Jobs, then the search the full width, then the two
   buttons, as a phone has always had them. The filter row is ONE line where the three lists, the two dates, Clear
   filters and Sort all fit, Sort at the far right; where they do not, it folds: the Filters button with its count at
   the left, Sort at the right, and under it once it is open the stage and the service, the job type (beside Clear
   filters when a filter is set), then From and To, side by side where each has room for the longest date the
   calendar writes, "Wednesday 30 September 2026", and a line each where it has not. What decides it is the width the
   list really has (a container query on .pn-jbbar, the head and the row together), so the side menu is counted
   whether it is there or not, and never a wrap that strands a part. Every part of a line is one height, padding and
   text size, as Collections' are: 32px on a computer, 40px in a narrower window, 44px on a phone or a touch screen.
   The widths were measured (28 Sep 2026) with Clear filters shown, since setting a filter must never break the line,
   the longest stage ("Completed jobs", "Archived leads") and both dates "Wednesday 30 September 2026": the row
   needs 998px at 32px and 1204px at 44px, so it goes to one line from 1000 and 1205, where every word is whole. At
   40px it would need 1117px, more than a window narrower than a computer's ever gives the list (932 at the most), so
   there the row is always folded. The head's four need 509 to 553px with the search at 180, so the search takes its
   own line below 580. The Invoices list shares the row's class (.pn-jbfilters) and none of this, which is all
   .pn-jbbar and .pn-jbrow. */
.pn-jbbar { container: jbbar / inline-size; }
.pn-jbhead .pn-h { flex: none; white-space: nowrap; }
.pn-jbhead .pn-jbexport, .pn-jbhead .wa-btn { flex: none; }
.pn-jbhead .pn-glsearch { flex: 1 1 180px; max-width: 260px; }
@container jbbar (max-width: 579.98px) { .pn-jbhead .pn-glsearch { flex: 1 1 100%; max-width: none; } }

/* FOLDED, a grid: Filters at the left and Sort at the right of the first line, then two to a line */
.pn-jbrow { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; align-items: center; }
.pn-jbrow .pn-glfbtn { display: inline-flex; align-items: center; gap: 8px; grid-column: 1; grid-row: 1; justify-self: start; }
.pn-jbrow .pn-glicons { grid-column: 2; grid-row: 1; justify-self: end; margin: 0; }
.pn-jbrow > .pn-glfilter, .pn-jbrow > .pn-jbclear { display: none; }
.pn-jbrow.pn-open > .pn-glfilter { display: block; min-width: 0; }
.pn-jbrow.pn-open.pn-jbset > .pn-jbclear:not([hidden]) { display: inline-flex; justify-content: center; min-width: 0; }
/* Clear filters beside the job type, and the two dates together after them; with no filter set the job type has its
   line to itself */
.pn-jbrow.pn-open > .pn-jbclear { order: 1; }
.pn-jbrow.pn-open > .pn-jbdate { order: 2; }
.pn-jbrow.pn-open:not(.pn-jbset) > .pn-jbf-type { grid-column: 1 / -1; }
/* two dates side by side need 560px on a touch screen (276 each, and the gap), so below it a date has a line */
@container jbbar (max-width: 559.98px) { .pn-jbrow.pn-open > .pn-jbdate { grid-column: 1 / -1; } }
/* and on the narrowest phones, where half the line would cut a list's words ("Completed jobs" needs 166px at 16px, "Any
   job type" 144), the stage and the service have a line each below 340px, and every part has its own below 300 */
@container jbbar (max-width: 339.98px) { .pn-jbrow.pn-open > .pn-jbf-stage, .pn-jbrow.pn-open > .pn-jbf-service { grid-column: 1 / -1; } }
@container jbbar (max-width: 299.98px) { .pn-jbrow.pn-open > .pn-glfilter, .pn-jbrow.pn-open > .pn-jbclear { grid-column: 1 / -1; } }
:root[data-app] .pn-jbrow .pn-glfilter .pn-ddbtn.wa-pwin, .pn-jbrow .pn-jbdate .pn-datein { width: 100%; }
/* a date too long for its box ends in dots, rather than running under the calendar */
.pn-jbrow .pn-jbdate .pn-datein { text-overflow: ellipsis; }

/* ONE SIZE A LINE: a dropdown and a date are the main size (40px, 44 to a thumb), and Clear filters with them; Filters and
   Sort are a row's while they have a line to themselves, and the main size where they share one with the fields */
:root[data-app] .pn-jbrow .pn-glfilter .wa-pwin:not(textarea), :root[data-app] .pn-jbrow .pn-jbclear { height: var(--pn-h-main); min-height: var(--pn-h-main); border-radius: var(--pn-r); }
:root[data-app] .pn-jbrow .pn-jbdate .pn-datein.wa-pwin { padding-left: 15px; font-size: 14px; }

/* ON ONE LINE WHERE THEY ALL FIT: at 44px from 1205, at 32px from 1000. Each list is as wide as its words and each date
   as wide as "Wednesday 30 September 2026" needs (276 and 220px), so every word is whole. */
@container jbbar (min-width: 1205px) {
  .pn-jbrow, .pn-jbrow.pn-open { display: flex; flex-wrap: nowrap; }
  .pn-jbrow .pn-glfbtn { display: none; }
  .pn-jbrow > .pn-glfilter, .pn-jbrow.pn-open > .pn-glfilter { display: block; flex: 1 1 0; min-width: 0; max-width: max-content; order: 0; }
  .pn-jbrow > .pn-jbdate, .pn-jbrow.pn-open > .pn-jbdate { max-width: 276px; }
  .pn-jbrow.pn-jbset > .pn-jbclear:not([hidden]), .pn-jbrow.pn-open.pn-jbset > .pn-jbclear:not([hidden]) { display: inline-flex; flex: none; order: 0; }
  .pn-jbrow .pn-glicons { flex: none; margin-left: auto; }
  :root[data-app] .pn-jbrow .pn-glfilter .pn-ddbtn.wa-pwin { width: auto; max-width: 100%; }
  :root[data-app] .pn-jbrow .pn-glicon.pn-jbsortbtn { width: var(--pn-h-main); height: var(--pn-h-main); min-height: var(--pn-h-main); }
}
@media (pointer: fine) and (min-width: 980px) {
  @container jbbar (min-width: 1000px) {
    .pn-jbrow, .pn-jbrow.pn-open { display: flex; flex-wrap: nowrap; }
    .pn-jbrow .pn-glfbtn { display: none; }
    .pn-jbrow > .pn-glfilter, .pn-jbrow.pn-open > .pn-glfilter { display: block; flex: 1 1 0; min-width: 0; max-width: max-content; order: 0; }
    .pn-jbrow > .pn-jbdate, .pn-jbrow.pn-open > .pn-jbdate { max-width: 220px; }
    .pn-jbrow.pn-jbset > .pn-jbclear:not([hidden]), .pn-jbrow.pn-open.pn-jbset > .pn-jbclear:not([hidden]) { display: inline-flex; flex: none; order: 0; }
    .pn-jbrow .pn-glicons { flex: none; margin-left: auto; }
    :root[data-app] .pn-jbrow .pn-glfilter .pn-ddbtn.wa-pwin { width: auto; max-width: 100%; }
    :root[data-app] .pn-jbrow .pn-glicon.pn-jbsortbtn { width: var(--pn-h-main); height: var(--pn-h-main); min-height: var(--pn-h-main); }
  }
}

/* EVERYONE ELSE on Photobooth PINs (26 Sep 2026: "Fix alignment of the right buttons"): each person's words, then the
   dots, the eye, New PIN and Remove PIN on one line under them, laid out as the My PIN card is */
.pn-list li.pn-pinli { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; align-items: start; }
.pn-list li.pn-pinli > .pn-row { margin: 0; justify-content: flex-end; }

/* HELD UNDER A POPUP IN LIGHT (common.js): the scrollbar goes, and its reserved gutter showed the html's dark ground as
   a strip down the side of a computer's screen; it is the page's own ground while held (26 Sep 2026) */
:root[data-app][data-theme="light"].wa-held { background: var(--pn-ground); }

/* THE PHOTOS ON WHITE (the operator, 26 Sep 2026: "make this background white"): a gallery's own page in light, on a
   computer; the main side is the app's white face from the top bar down, the photo tiles sit on it in their light grey */
@media (min-width: 980px) {
  :root[data-app][data-theme="light"] .pn-gmain { background: var(--pn-face); align-self: stretch; }
}

/* THE GALLERY SIDE PANEL'S LISTS, ONE STYLE (the operator, 26 Sep 2026: "remove the grey backing make it straight white",
   then "follow this style", with Photo sets as the picture): Design, Settings and Activity sit straight on the panel
   with no box of their own, a row each, and the open one filled with a bar down its left, as Photo sets' is */
.pn-gside .pn-gsetnav, :root[data-app][data-theme="light"] .pn-gside .pn-gsetnav { gap: 0; background: none; border: 0; border-radius: 0; box-shadow: none; }
/* Activity's heading reads as PHOTO SETS does */
.pn-gside .pn-actnav .pn-sidek { margin: 0; padding: 0 14px 8px; }

/* THE SAME LISTS AS A ROW, BELOW A COMPUTER'S WIDTH (the operator, 28 Sep 2026: "In a gallery, mobile, the selected (ie
   cover) is cut off"): the side list's open look, a square fill with a bar down its left edge, read as a piece sliced
   off once the list ran across the page. Where Design's sections, Settings' and Activity's run as a row they are the
   Studio's own segmented track, the one the Collections, Settings, Requests and Activity row wears on a phone
   (.pn-jbswitch, a dropdown since report 71): the open one a whole rounded piece raised in the track, no bar. A row
   wider than the screen scrolls sideways inside its own track, never the page; the track's padding keeps the first and the last whole at either end,
   and the open one is brought into sight when the section opens (assets/app.js, rowInSight). An end with more beyond
   it fades out (data-more, rowEdges), so a word cut at the edge reads as more that way, never as a piece sliced off;
   Design's five fit a 360 or 390 phone whole, with no fade. The keyboard's ring is drawn inside each link, as the
   track clips anything outside it. Activity's heading is the column's only: the row is named by its own label. 44px
   to a thumb on a phone. The computer's column is as it was, above.
   THE PILLS SINCE 1 OCT 2026 (report 30, option B): a page's own tabs are the Studio's pills, never a second track under
   the places, so the row is the pills of THE STUDIO'S ORDER, level 3, scrolling as before. */
@media (max-width: 979px) {
  .pn-gside .pn-gsetnav, :root[data-app][data-theme="light"] .pn-gside .pn-gsetnav {
    display: flex; flex-wrap: nowrap; gap: 6px; padding: 0 0 2px; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none;
    border: 0; border-radius: 0; background: none; box-shadow: none; }
  .pn-gside .pn-gsetnav::-webkit-scrollbar { display: none; }
  .pn-gside .pn-gsetlink { min-height: 32px; }
  .pn-gside .pn-gsetlink, :root[data-app][data-theme="light"] .pn-gside .pn-gsetlink { flex: 0 0 auto; justify-content: center;
    padding: 0 12px; border: 1px solid var(--pn-p-line); border-radius: var(--pn-r); background: none; box-shadow: none; white-space: nowrap;
    font-size: 12px; font-weight: 450; color: var(--pn-t-soft); }
  .pn-gside .pn-gsetlink .pn-onoff { margin-left: 2px; }
  .pn-gside .pn-gsetlink[aria-current="true"], .pn-gside .pn-gsetlink[aria-current="true"]:hover,
  :root[data-app][data-theme="light"] .pn-gside .pn-gsetlink[aria-current="true"],
  :root[data-app][data-theme="light"] .pn-gside .pn-gsetlink[aria-current="true"]:hover {
    background: var(--pn-p-on); border-color: var(--pn-p-on); color: var(--pn-p-onink); font-weight: 500; box-shadow: none; }
  .pn-gside .pn-actnav .pn-sidek { display: none; }
  /* GALLERY SETTINGS' TABS, the same: one row that scrolls in its own track, in place of a track broken over two lines */
  .pn-gptabs { flex-wrap: nowrap; width: auto; overflow-x: auto; overscroll-behavior-x: contain; scrollbar-width: none; }
  .pn-gptabs::-webkit-scrollbar { display: none; }
  .pn-gptabs > .pn-gtab { flex: 1 0 auto; white-space: nowrap; }
  .pn-gside .pn-gsetlink:focus-visible, .pn-gptabs > .pn-gtab:focus-visible { outline: 2px solid; outline-offset: -2px; }
  /* the open tab is filled with the ring's own colour (the beige in dark, the ink in light), so inside it the ring is
     its words' colour */
  :root[data-app] .pn-gptabs > .pn-gtab[aria-selected="true"]:focus-visible { outline-color: currentColor; }
  /* more beyond an end: that end fades out over 32px */
  .pn-gside .pn-gsetnav[data-more="r"], .pn-gptabs[data-more="r"] {
    -webkit-mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); mask-image: linear-gradient(90deg, #000 calc(100% - 32px), transparent); }
  .pn-gside .pn-gsetnav[data-more="l"], .pn-gptabs[data-more="l"] {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 32px); mask-image: linear-gradient(90deg, transparent, #000 32px); }
  .pn-gside .pn-gsetnav[data-more="lr"], .pn-gptabs[data-more="lr"] {
    -webkit-mask-image: linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 32px), transparent);
    mask-image: linear-gradient(90deg, transparent, #000 32px, #000 calc(100% - 32px), transparent); }
}
@media (max-width: 759px), (max-width: 979px) and (pointer: coarse) {
  .pn-gside .pn-gsetlink { min-height: 44px; }
}
/* a 360 phone: a little closer set, so Design's five still fit whole */
@media (max-width: 389.98px) {
  .pn-gside .pn-gsetlink { padding: 0 9px; }
}

/* THE WORDING OF EACH EMAIL (app.js ewRows, ewOpen, ewDraw; the operator, 26 Sep 2026: "make this editable in
   settings"): the list on the Email card and on Gallery settings, the sheet that edits one, and its preview, which is
   white in either theme because the email is */
.pn-ewcard { grid-column: 1 / -1; }
.pn-ewlist { margin-top: 8px; }
.pn-ewlist li { padding: 0; }
.pn-ewrow { display: grid; grid-template-columns: minmax(0,1fr) auto; align-items: center; gap: 2px 10px; width: 100%; min-height: 56px; padding: 10px 6px;
  border: 0; border-radius: var(--pn-r); background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
.pn-ewname { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 8px; min-width: 0; font-size: 14px; }
.pn-ewwhen { grid-column: 1; min-width: 0; font-size: 12px; line-height: 1.45; color: rgba(242,239,232,.62); }
.pn-ewrow .pn-gl { grid-column: 2; grid-row: 1 / span 2; width: 18px; height: 18px; opacity: .6; }
.pn-sheet > .wa-card.pn-ewsheet { max-width: 720px; }
/* Reset to default, Preview and Save share one padding as every row's buttons now do (ONE SIZE FOR A BUTTON, above) */
.pn-form.pn-ewfield { max-width: none; }
textarea.wa-pwin.pn-ewbody { min-height: 280px; font-size: 14px; }
.pn-ewmeta { display: flex; flex-direction: column; gap: 4px 12px; margin: 6px 0 0; font-size: 12px; line-height: 1.5;
  color: rgba(242,239,232,.56); font-variant-numeric: tabular-nums; }
.pn-ewk { margin: 18px 0 0; }
.pn-ewtip { margin: 4px 0 0; font-size: 12px; line-height: 1.5; color: rgba(242,239,232,.56); }
/* THE TEST EMAILS' FORM (28 Oct 2026: "Fix line spacing and make the grouping collapsible"): a label and what follows it
   10px apart, and each group a fold, shut to start, under a hairline, its row 44px to a thumb */
.pn-ewk + .pn-row, .pn-ewk + .pn-note, .pn-ewk + .pn-ewfield { margin-top: 10px; }
.pn-tagrps { margin-top: 12px; border-bottom: 1px solid var(--pn-line); }
.pn-tagrp { border-top: 1px solid var(--pn-line); }
.pn-tagrp > summary { display: flex; align-items: center; gap: 10px; min-height: 44px; font-size: 14px; cursor: pointer; list-style: none; }
.pn-tagrp > summary::-webkit-details-marker { display: none; }
.pn-tagrp > summary > span:first-child { flex: 1 1 auto; min-width: 0; }
.pn-tacount { flex: none; font-size: 12px; font-variant-numeric: tabular-nums; opacity: .6; }
.pn-tachev { flex: none; width: 18px; height: 18px; opacity: .6; transition: transform .2s ease; }
.pn-tagrp[open] .pn-tachev { transform: rotate(180deg); }
@media (prefers-reduced-motion: reduce) { .pn-tachev { transition: none; } }
.pn-tagrpin { padding: 0 0 10px; }
.pn-tagrpin .pn-check { min-height: 40px; }
.pn-tagrpin .pn-ewfield + .pn-ewfield { margin-top: 10px; }
.pn-ewfills { display: grid; grid-template-columns: 104px minmax(0,1fr); align-items: start; gap: 6px 12px; margin: 10px 0 0; }
.pn-ewchip { justify-self: start; align-self: start; max-width: 100%; border-color: rgba(255,255,255,.16); background: rgba(255,255,255,.07); color: inherit; }
.pn-ewfw { min-width: 0; font-size: 12px; line-height: 1.4; color: rgba(242,239,232,.62); }
.pn-ewprev { margin-top: 6px; }
.pn-ewmail { margin-top: 8px; border: 1px solid rgba(255,255,255,.14); border-radius: var(--pn-r); overflow: hidden; }
.pn-ewsubj { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; padding: 10px 14px; background: rgba(0,0,0,.22); font-size: 13px; overflow-wrap: anywhere; }
.pn-ewsk { font-size: 10.5px; letter-spacing: .14em; text-transform: uppercase; opacity: .7; }
.pn-ewpage { padding: 20px; background: #ffffff; color: #241f19; font-family: Arial, sans-serif; font-size: 15px; line-height: 1.55; overflow-wrap: anywhere; }
.pn-ewp { margin: 0 0 14px; }
.pn-ewp:last-child { margin: 0; }
.pn-ewcopy { font-size: 13px; color: #595550; }
.pn-ewlink { color: #241f19; text-decoration: underline; word-break: break-all; }
/* the link's foot line (13 Oct 2026; lib/mail.js linkFootHtml): small and fainter than the soft grey, at the page's foot */
.pn-ewlinkfoot { margin-top: 22px; font-size: 11px; line-height: 1.5; color: #76726c; }
.pn-ewlinkfoot .pn-ewlink { color: inherit; }
/* THE EMAIL'S OWN LOOK IN ITS PREVIEW (8 Oct 2026, A. Website head; lib/mail.js emailHtml): the dark head with the logo
   and its label, the yellow line, the title over the yellow rule, the figure and the yellow button; the white page; the
   dark footer with the contact details. The email's own colours, the website's, in either theme of the app, as the
   email has them; the logo the email's own picture. ARIAL, AS THE EMAIL IS (16 Oct 2026, lib/mail.js TEXT_FONT: "Maybe
   just stick to Ariel for email for all"): every word, the title and the figure as written, never capitals, and the
   small capital labels weight 500 ("Lighter is fine yes"), so the preview still shows the email as it goes */
.pn-ewhead, .pn-ewfoot { background: #241f19; font-family: Arial, sans-serif; overflow-wrap: anywhere; }
.pn-ewhead { padding: 12px 20px 22px; color: #f2efe8; }
.pn-ewbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin: 0 -8px; }
.pn-ewlogo { display: block; flex: none; width: 136px; height: 50px; }
/* the head's label in the website's own look for it (8 Nov 2026, lib/mail.js HEAD_LABEL): the moon yellow, 600, spaced */
.pn-ewlabel { padding-right: 8px; font-size: 11px; font-weight: 600; letter-spacing: .16em; text-transform: uppercase; color: #f4ff6a; }
.pn-eweye { margin-top: 18px; font-size: 12px; font-weight: 500; line-height: 1.4; letter-spacing: .2em; text-transform: uppercase; color: #f4ff6a; }
.pn-ewtitle { margin-top: 8px; font-family: Arial, sans-serif; font-size: 22px; font-weight: 400; line-height: 1.15; letter-spacing: .004em; }
/* the yellow rule 2px, the website's own (8 Nov 2026, lib/mail.js RULE_PX) */
.pn-ewfig { margin-top: 18px; padding-top: 12px; border-top: 2px solid #f4ff6a; }
.pn-ewfig:empty { padding-top: 0; }
.pn-ewfigl { font-size: 11px; font-weight: 500; line-height: 1.4; letter-spacing: .14em; text-transform: uppercase; color: #a4a099; }
.pn-ewfigv { margin-top: 4px; font-family: Arial, sans-serif; font-size: 28px; font-weight: 400; line-height: 1.1; font-variant-numeric: tabular-nums; }
.pn-ewfigv.pn-ewfigw { font-size: 20px; }
.pn-ewfigs { margin-top: 6px; font-size: 13px; line-height: 1.45; color: #a4a099; }
/* the buttons square, as the email's are (6 Nov 2026, roadmap N12, the operator: "Yes for both") */
.pn-ewhbtn { display: inline-block; margin-top: 18px; padding: 15px 26px; background: #f4ff6a; color: #241f19; font-size: 12px; font-weight: 500; line-height: 1.3; letter-spacing: .14em; text-transform: uppercase; }
.pn-ewbtn2 { display: inline-block; padding: 13px 24px; border: 1px solid #928f8c; color: #241f19; font-size: 12px; font-weight: 500; line-height: 1.3; letter-spacing: .14em; text-transform: uppercase; }
.pn-ewsigp { font-size: 13px; color: #595550; }
.pn-ewsigp + .pn-ewsigp { margin-top: -6px; }
.pn-ewsig { margin-top: 20px; padding-top: 12px; border-top: 1px solid #d3d2d1; }
/* THE FOOTER IS THE CONTACT DETAILS (8 Oct 2026: "Make the footer just the contact details", then "Add glyphs to the
   links to corresponding platforms and decrease the line spacing"), as the email draws them (lib/mail.js contactHtml)
   in the website footer's Get in Touch look: the label in the yellow spaced capitals; the email, the phone and the area
   one under the other, each a 28px line, its 16px glyph and its words 10px after it; the socials and the reviews one
   line of links running on where it must, each its glyph 8px before its name, 20px apart; the links light and the area
   grey; then the copyright line under a thin rule */
.pn-ewfoot { padding: 30px 20px 22px; color: #a4a099; font-size: 14px; line-height: 20px; }
.pn-ewgeye { font-size: 12px; font-weight: 500; line-height: 1.4; letter-spacing: .16em; text-transform: uppercase; color: #f4ff6a; }
.pn-ewgrows { margin-top: 6px; }
.pn-ewgrow { display: flex; align-items: center; gap: 10px; min-height: 28px; }
/* each glyph in a bordered square, as the website footer's are (8 Nov 2026, lib/mail.js LINK_EDGE): a 1px edge in the
   footer's hairline, square, the glyph centred, 8px apart, the first square's edge in line with the words above */
.pn-ewgsoc { display: flex; flex-wrap: nowrap; gap: 8px; margin: 8px 0 0; }
.pn-ewgsoci { display: flex; flex: none; align-items: center; justify-content: center; box-sizing: border-box; min-width: 44px; height: 44px; padding: 0 11px; border: 1px solid #3d3832; color: #f2efe8; white-space: nowrap; }
.pn-ewgsic { display: block; flex: none; width: 20px; height: 20px; }
.pn-ewglink { color: #f2efe8; }
.pn-ewgic { display: block; flex: none; width: 16px; height: 16px; }
.pn-ewgbase { margin-top: 22px; padding-top: 14px; border-top: 1px solid #3d3832; }
.pn-ewgsoc + .pn-ewgbase { margin-top: 22px; }
/* to the studio's own inbox (lib/mail.js OWN_MARK): the copyright line and the ABN alone, no rule */
.pn-ewgown { font-size: 14px; line-height: 20px; }
/* the line saying why it came, under the copyright line, on the four emails that carry one (lib/mail.js WHY_EMAILS: a
   gallery visitor's reminders and a pre-release gallery's list), dim as the email draws it (withWhy) */
.pn-ewwhy { margin-top: 8px; font-size: 13px; line-height: 1.55; }
/* a table of sums in the preview, as the email draws it (lib/mail.js sumsHtml): the full width of the words (8 Oct 2026:
   "can you make table full width on mobile"); each row's words with the maths in grey under them, the money on the
   right and never broken, a rule under each row, then the total in bold */
.pn-ewsumt { width: 100%; border-collapse: collapse; font-variant-numeric: tabular-nums; }
.pn-ewsumt td { padding: 6px 0; border-bottom: 1px solid #d3d2d1; vertical-align: top; }
.pn-ewsumt td.pn-ewsuma { padding-left: 16px; text-align: right; white-space: nowrap; overflow-wrap: normal; }
.pn-ewsumm { font-size: 13px; color: #595550; }
.pn-ewsumt tr.pn-ewsumtot td { padding: 8px 0 0; border-bottom: 0; font-weight: 700; }
.pn-ewsumt tr.pn-ewsumtot td.pn-ewsuma { padding-left: 16px; }
/* a quote's or an invoice's table in the preview, as the email draws it (lib/mail.js panelHtml, 13 Oct 2026): the grey
   panel of lined rows, a line between rows and none after the last, every cell's words in the middle of its row; the
   quote's labels bold in a first column 34% wide, the invoice's headings in small capitals (500 since 16 Oct 2026), a
   line's grey second line under its words and its money on the right in tabular figures; then straight under it the
   dark bar, "Total" in white small capitals and the amount in the head's yellow, in Arial. Square, as the email is; the
   white page's own colours in either theme, as the email's are */
.pn-ewpanel { margin: 0 0 14px; }
.pn-ewpnbox { padding: 4px 16px; border: 1px solid #d3d2d1; }
.pn-ewpnt { width: 100%; border-collapse: collapse; font-size: 15px; line-height: 1.45; }
.pn-ewpnt td { padding: 10px 0; border-bottom: 1px solid #d3d2d1; vertical-align: middle; text-align: left; color: #241f19; }
.pn-ewpnt tr:last-child td { border-bottom: 0; }
.pn-ewpnt td.pn-ewpnl1 { width: 34%; padding-right: 12px; color: #595550; }
.pn-ewpnt td.pn-ewpna { padding-left: 12px; text-align: right; white-space: nowrap; overflow-wrap: normal; font-variant-numeric: tabular-nums; }
.pn-ewpnt td.pn-ewpnsec { padding: 14px 0 6px; font-size: 11px; font-weight: 500; line-height: 1.35; letter-spacing: .14em; text-transform: uppercase; }
.pn-ewpnsub { display: block; font-size: 13px; color: #595550; }
.pn-ewpnbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 13px 16px; background: #241f19; }
.pn-ewpnbw { font-size: 11px; font-weight: 500; line-height: 1.35; letter-spacing: .16em; text-transform: uppercase; color: #ffffff; }
.pn-ewpnba { font-family: Arial, sans-serif; font-size: 24px; font-weight: 400; line-height: 1; color: #f4ff6a; white-space: nowrap; font-variant-numeric: tabular-nums; }
/* THE EMAIL IN THE APP'S QUESTION (frame.js S.ask's `mail`, drawn by S.mailPreview; the operator, 8 Oct 2026, of the
   desk's paid email: "in the popup format the email so its easier to read"): under the notes and apart from them, in
   the preview's own card. With a To row, To and Subject are one band, their labels a column of their own and each value
   beside its label, wrapping there, never past the card; on a small phone the page's margin is a little less */
/* THE WORD TO TYPE, A SLOT A LETTER (Problem report 221, 18 Oct 2026; frame.js S.ask): one underline for each letter of it, the
   letters above them, the next to fill underlined darker; the one real box is laid over them, clear, so it takes the typing */
.pn-slotbox { position: relative; display: block; margin-top: 12px; }
.pn-slots { display: flex; gap: 10px; }
.pn-slot { flex: 0 0 34px; height: 44px; display: grid; place-items: end center; padding-bottom: 5px; box-sizing: border-box;
  border-bottom: 2px solid var(--pn-line, rgba(36,31,25,.13)); font-size: 20px; font-weight: 500; line-height: 1; letter-spacing: 0; text-transform: uppercase; }
.pn-slot-on { border-bottom-color: var(--pn-ink, #241f19); }
.pn-slotin { position: absolute; inset: 0; width: 100%; height: 100%; margin: 0; padding: 0; border: 0; background: transparent; opacity: 0; font-size: 16px; cursor: text; }
.pn-askmail { margin-top: 14px; }
.pn-askmail > .pn-ewmail { margin-top: 0; }
.pn-ewsubj.pn-ewto { padding-bottom: 0; }
.pn-ewto, .pn-ewto + .pn-ewsubj { flex-wrap: nowrap; }
.pn-ewto > .pn-ewsk, .pn-ewto + .pn-ewsubj > .pn-ewsk { flex: none; min-width: 5.4em; }
.pn-ewto > :last-child, .pn-ewto + .pn-ewsubj > :last-child { min-width: 0; }
@media (max-width: 420px) { .pn-askmail .pn-ewpage { padding: 16px 14px; } }
@media (hover: hover) {
  .pn-ewrow:hover { background: rgba(255,255,255,.05); }
  .pn-ewchip:hover { background: rgba(255,255,255,.13); }
  :root[data-app][data-theme="light"] .pn-ewrow:hover { background: rgba(36,31,25,.04); }
  :root[data-app][data-theme="light"] .pn-ewchip:hover { background: var(--pn-fill-hover); }
}
@media (max-width: 700px) { textarea.wa-pwin.pn-ewbody { font-size: 16px; } }
/* two emails to a row on a computer: the second row's top line is the first's, so neither of the first two has one */
@media (min-width: 760px) {
  .pn-ewcard .pn-ewlist { grid-template-columns: repeat(2, minmax(0,1fr)); column-gap: 28px; }
  .pn-ewcard .pn-ewlist li:nth-child(2) { border-top: 0; }
}
:root[data-app][data-theme="light"] .pn-ewwhen,
:root[data-app][data-theme="light"] .pn-ewfw,
:root[data-app][data-theme="light"] .pn-ewtip,
:root[data-app][data-theme="light"] .pn-ewmeta { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-ewchip { background: var(--pn-fill); border-color: var(--pn-line); color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-ewmail { border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-ewsubj { background: var(--pn-fill); color: var(--pn-ink); }
/* Settings, Signature (28 Sep 2026; in HTML since report 84, 2 Oct 2026): how to copy it from Gmail, the paste box, the
   HTML in a part that opens, the preview in its own sandboxed frame (white, as the email is, in either theme) and the
   plain text under it, its lines kept */
.pn-sigcard .pn-form { max-width: none; }
textarea.wa-pwin.pn-ewbody.pn-sigbody { min-height: 150px; }
.pn-sigsteps { margin: 6px 0 0; padding-left: 20px; font-size: 13.5px; line-height: 1.55; }
.pn-sigsteps li + li { margin-top: 2px; }
/* SETTINGS, CLAUDE, EMAIL DRAFTS (16 Oct 2026, the operator's pick of option C): each line of the master style, and each
   sentence of a draft's task, is a chip whose words are changed inside it, with an x; the master style sits beside an
   example email (white in either theme, as an email is) whose lines carry the number of the rule behind them. */
.cl-cols { display: grid; gap: 22px; grid-template-columns: minmax(0, 1fr); align-items: start; margin-top: 10px; }
@media (min-width: 1180px) { .cl-cols { grid-template-columns: minmax(0, 1.1fr) minmax(0, .9fr); } .cl-cols > div:last-child { position: sticky; top: 104px; } }
.cl-chips { display: grid; gap: 8px; margin: 0; padding: 0; list-style: none; }
.cl-chips.cl-mt { margin-top: 12px; }
.cl-chip { display: flex; align-items: flex-start; gap: 10px; padding: 8px 8px 8px 10px; border-radius: var(--pn-r); border: 1px solid rgba(255,255,255,.14); background: rgba(255,255,255,.05);
  font-size: 14px; line-height: 1.45; cursor: text; }
.cl-chip:hover { border-color: rgba(255,255,255,.28); }
/* a chip being changed is a field in focus, and the line the example lights is picked (2 Nov 2026, the operator: go A):
   the ink edge and a 1px ink ring, as every field's focus; the soft fill in a 1.5px ink ring, as the calculator's picked */
.cl-chip:focus-within { border-color: var(--pn-ink); box-shadow: 0 0 0 1px var(--pn-ink); }
.cl-chip.cl-hot { border-color: transparent; background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); }
.cl-n { flex: none; width: 24px; height: 24px; margin-top: 1px; border-radius: var(--pn-r); background: var(--pn-p-hover); color: inherit; display: grid; place-items: center; font-size: 11.5px; font-weight: 500; font-variant-numeric: tabular-nums; }
.cl-t { flex: 1; min-width: 0; padding: 1px 3px; border-radius: var(--pn-r); outline: none; white-space: pre-wrap; overflow-wrap: anywhere; caret-color: var(--moon); }
.cl-x { flex: none; width: 28px; height: 28px; margin: -3px 0; display: grid; place-items: center; border: 0; background: none; border-radius: var(--pn-r); cursor: pointer; color: inherit; opacity: .6; }
.cl-x:hover { opacity: 1; background: rgba(255,255,255,.1); }
.cl-x svg { width: 14px; height: 14px; }
@media (pointer: coarse) { .cl-x { width: 44px; height: 44px; margin: -9px -4px -9px 0; } }
.cl-add { display: flex; gap: 8px; margin-top: 10px; }
.cl-add .wa-pwin { flex: 1; min-width: 0; }
.cl-undo[hidden] { display: none; }
/* THE CARD'S FOLDS AND ITS TYPE ONE SIZE (the operator, 17 Oct 2026, Problem report 211: "what are these random design elements added
   in. fix the dropdown glyph. the font sizing and line spacing is out of place"): a fold's name is the same 13px as a chip's
   words, with the Studio's own turning chevron in place of the browser's black triangle, and the notes under a heading keep
   their 12px, so the card has three sizes and no more, a line to a line */
.cl-card details > summary { display: flex; align-items: center; gap: 10px; min-height: 44px; list-style: none; cursor: pointer; font-size: 13px; font-weight: 500; line-height: 1.5; }
.cl-card details > summary::-webkit-details-marker { display: none; }
.cl-card details > summary::before { content: ""; flex: none; width: 7px; height: 7px; margin: 0 3px 0 2px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); transition: transform .15s ease; }
.cl-card details[open] > summary::before { transform: rotate(45deg); }
@media (prefers-reduced-motion: reduce) { .cl-card details > summary::before { transition: none; } }
.cl-card .cl-chip { font-size: 13px; line-height: 1.5; }
/* What each draft does: the pills fill each row, as the calculator's do, never one left alone on a second line */
.cl-card .pn-pills > .pn-pill { flex: 1 1 auto; }
.cl-card .cl-add .wa-pwin { font-size: 13px; }
.cl-ex { padding: 16px 18px; border-radius: var(--pn-r); background: #fff; color: #1f1f1f; border: 1px solid rgba(255,255,255,.14); font: 14px/1.5 Arial, Helvetica, sans-serif; }
.cl-hd { margin: 0 0 12px; font-size: 10.5px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: #6b6761; }
.cl-ex p:not(.cl-hd):not(.cl-xn) { margin: 0 0 10px; padding: 3px 6px 3px 8px; border-left: 3px solid transparent; border-radius: var(--pn-r); }
/* the lines a rule is behind: the ink edge at their left on a pale grey, never a yellow highlighter (31 Oct 2026, a
   standing rule; this was a yellow marker behind the words until 3 Nov 2026) */
.cl-ex p.cl-lit { background: #efebe4; border-left-color: #241f19; }
.cl-ex p.cl-off { opacity: .35; }
.cl-tag { display: inline-flex; gap: 3px; float: right; margin-left: 8px; }
.cl-tag i { font-style: normal; width: 18px; height: 18px; border-radius: 50%; background: #241f19; color: #fffdfa; display: grid; place-items: center; font-size: 10.5px; font-weight: 500; }
.cl-xn { margin: 10px 0 0; font-size: 12.5px; color: #6b6761; }
:root[data-app][data-theme="light"] .cl-chip { background: #fff; border-color: var(--pn-line); color: var(--pn-ink); }
:root[data-app][data-theme="light"] .cl-chip:hover { border-color: rgba(36,31,25,.3); }
:root[data-app][data-theme="light"] .cl-chip:focus-within { border-color: var(--pn-ink); box-shadow: 0 0 0 1px var(--pn-ink); background: #fff; }
:root[data-app][data-theme="light"] .cl-chip.cl-hot { border-color: transparent; background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); }
:root[data-app][data-theme="light"] .cl-t { caret-color: var(--pn-ink); }
:root[data-app][data-theme="light"] .cl-x:hover { background: var(--pn-fill); }
:root[data-app][data-theme="light"] .cl-ex { border-color: var(--pn-line); }
.pn-sigpastef { margin-top: 12px; }
textarea.wa-pwin.pn-sigpaste { min-height: 64px; font-size: 14px; resize: none; }
.pn-sigsaid:empty { display: none; }
.pn-sightml[hidden] { display: none; }
.pn-sightml { margin-top: 10px; }
.pn-sigframe { display: block; width: 100%; height: 200px; margin-top: 8px; border: 1px solid rgba(255,255,255,.14); border-radius: var(--pn-r); background: #ffffff; }
.pn-sigplain { margin: 6px 0 0; white-space: pre-line; font-size: 14px; line-height: 1.5; overflow-wrap: anywhere; color: rgba(242,239,232,.82); }
@media (max-width: 700px) {
  textarea.wa-pwin.pn-sigpaste { font-size: 16px; }
  .pn-sigframe { height: 200px; }
}
:root[data-app][data-theme="light"] .pn-sigframe { border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-sigplain { color: var(--pn-ink); }

/* STORAGE AS IPHONE STORAGE (Gallery, Activity; 27 Sep 2026: "Make this line into like the iOS breakdowns"): one bar in
   the copies' colours with a key, then a row per collection, its cover, name, photos and size, opening to its own bar */
.pn-stused { margin: 2px 0 10px; font-size: 14px; color: var(--pn-ink-soft, rgba(242,239,232,.7)); }
/* the figure big and light, in the display face (2 Nov 2026, the operator: go A) */
.pn-stused b { font-family: var(--font-display); font-size: 28px; font-weight: 300; line-height: 1.1; letter-spacing: -.01em; color: var(--pn-ink, #f2efe8); margin-right: 4px; font-variant-numeric: tabular-nums; }
.pn-stbar { display: flex; gap: 2px; height: 14px; border-radius: var(--pn-r); overflow: hidden; background: rgba(127,127,127,.18); }
.pn-stbar i { display: block; height: 100%; min-width: 3px; }
.pn-st-full { background: #4f8fe8; } .pn-st-mark { background: #e8a33d; } .pn-st-web { background: #5bb56e; }
.pn-st-cover { background: #b07ce0; } .pn-st-other { background: #9a958c; }
.pn-stkey { display: flex; flex-wrap: wrap; gap: 6px 16px; margin: 10px 0 4px; padding: 0; list-style: none; font-size: 13px; }
.pn-stkey li { display: inline-flex; align-items: center; gap: 7px; }
.pn-stkey li i { width: 10px; height: 10px; border-radius: 50%; flex: none; }
.pn-stkey li b { font-weight: 500; opacity: .7; font-variant-numeric: tabular-nums; }
.pn-stlist { margin: 8px 0 0; padding: 0; list-style: none; }
.pn-strow + .pn-strow { border-top: 1px solid var(--pn-line, rgba(255,255,255,.09)); }
.pn-strow summary { display: grid; grid-template-columns: 52px minmax(0, 1fr) auto 14px; align-items: center; gap: 12px; padding: 12px 2px; cursor: pointer; list-style: none; }
.pn-strow summary::-webkit-details-marker { display: none; }
.pn-stthumb { width: 52px; height: 52px; border-radius: var(--pn-r); overflow: hidden; background: rgba(127,127,127,.2); }
.pn-stthumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pn-stname { display: grid; gap: 2px; min-width: 0; }
.pn-stname b { font-size: 15px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-stname span { font-size: 13px; opacity: .65; }
.pn-stsize { font-size: 15px; opacity: .7; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pn-stchev { width: 8px; height: 8px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(-45deg); opacity: .4; transition: transform .2s ease; }
.pn-strow details[open] .pn-stchev { transform: rotate(45deg); }
.pn-stopen { padding: 0 2px 14px 66px; }
@media (max-width: 560px) { .pn-stopen { padding-left: 2px; } }
@media (prefers-reduced-motion: reduce) { .pn-stchev { transition: none; } }

/* FORMER MEMBERS of the team, a fold that starts closed (assets/crew.js; 27 Sep 2026: "when anyone from the team is
   removed, move them to a former members, collapsed") */
.cw-former { margin-top: 16px; border-top: 1px solid var(--pn-line); }
.cw-former > summary { display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 8px 2px; cursor: pointer; list-style: none;
  font-size: 11px; font-weight: 600; letter-spacing: .12em; text-transform: uppercase; }
.cw-former > summary::-webkit-details-marker { display: none; }
.cw-formerchev { width: 7px; height: 7px; margin-left: auto; margin-right: 6px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: rotate(45deg); opacity: .5; transition: transform .2s ease; }
.cw-former[open] .cw-formerchev { transform: rotate(-135deg); }
.cw-former .pn-list li { opacity: .8; }
@media (prefers-reduced-motion: reduce) { .cw-formerchev { transition: none; } }

/* A SHIFT'S TIMES in one type whether its own or the job's, the job's saying so quietly after them (27 Sep 2026: "why
   is my time different fonts") */
.pn-jbshifts .pn-jbshwhen .pn-jbshsame { display: inline; margin-left: 8px; font-size: 12.5px; }

/* TALLER ROWS on Jobs, Leads and Clients, so a row is easier to follow across (27 Sep 2026: "increase the row height so
   its a bit easier to gauge on mobile and web") */
.pn-jbtab td { padding-top: 17px; padding-bottom: 17px; }
.pn-jbtab .pn-glname .pn-t { margin-top: 4px; line-height: 1.45; }
@media (max-width: 720px) { .pn-jbtab td { padding-top: 15px; padding-bottom: 15px; } }
/* on a phone a row's name takes three or four lines, so every cell starts at its top, the date level with the title
   rather than halfway down; the row's More stays in the middle (design audit, 27 Sep 2026) */
@media (max-width: 720px) { .pn-jbtab td { vertical-align: top; } .pn-jbtab td.pn-glrowmenu { vertical-align: middle; } }
/* THE JOBS AND LEADS LISTS ON A PHONE, UNCRAMPED (9 Nov 2026, the operator, of the list on an iPhone: "This cram needs to be fixed"). A row is its date on one line beside the stage, then the name across.
   The times and the venue are two lines at most, cut with an ellipsis, the service's glyphs end the type and client line, in the flow, and never touch the venue, and More is 32px to the eye, 44px to a thumb,
   at the top of its row. :has([data-jbsort]) is these two lists: Clients and the money lists share .pn-jbtab. */
@media (max-width: 899.98px) {
  .pn-jbtab:has([data-jbsort]) { table-layout: fixed; }
  .pn-jbtab:has([data-jbsort]) th.pn-glrowmenu, .pn-jbtab:has([data-jbsort]) td.pn-glrowmenu { width: 36px; padding-left: 0; padding-right: 0; }
  .pn-jbtab:has([data-jbsort]) td.pn-glnum { font-size: 12px; line-height: 1.35; }
  .pn-jbtab:has([data-jbsort]) .pn-jbdd { white-space: nowrap; }
  .pn-jbtab:has([data-jbsort]) .pn-jbwkr { display: none; }
  .pn-jbtab:has([data-jbsort]) td.pn-glname { position: relative; }
  .pn-jbtab:has([data-jbsort]) .pn-glname > .pn-t:not(.pn-jbnarrow) { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; }
  .pn-jbtab:has([data-jbsort]) .pn-glname > .pn-jbsvs { flex-wrap: nowrap; gap: 2px; }
  :root[data-app][data-theme] .pn-jbtab:has([data-jbsort]) .pn-jbsv { width: 18px; min-width: 18px; height: 18px; padding: 0; border-color: transparent; background: none; }
  .pn-jbtab:has([data-jbsort]) .pn-glname .pn-jbnarrow .pn-badge { display: flex; width: fit-content; margin: 6px 0 0; }
  .pn-jbtab td.pn-glrowmenu { vertical-align: top; }
  :root[data-app][data-theme] .pn-jbtab .pn-glrowmenu .pn-glicon { position: relative; width: 32px; height: 32px; border-color: transparent; background: transparent; color: var(--pn-ink); }
  :root[data-app][data-theme] .pn-jbtab .pn-glrowmenu .pn-glicon::after { content: ""; position: absolute; inset: -6px; }
}
/* a row under the mouse lights up, as a request row and an email row do, so it is easy to follow across (design audit,
   27 Sep 2026) */
.pn-gltab tbody tr { transition: background-color 120ms ease; }
@media (hover: hover) {
  .pn-gltab tbody tr:hover { background: var(--pn-hover, rgba(255,255,255,.035)); }
}
@media (prefers-reduced-motion: reduce) { .pn-gltab tbody tr { transition: none; } }


/* SETTINGS, A PLACE A SECTION (assets/app.js settingsPage; the operator, 27 Sep 2026: "separate each sections into its
   own tab under settings"): each place is its one card, as wide as the page since report 92 (2 Oct 2026; its words and
   boxes at widths that read, below, EVERY PAGE AS WIDE AS THE WINDOW), and Email wording with its emails two to a row. On a phone the places are the segmented row, each as wide as its word needs (the Jobs' row). */
.pn-setone { max-width: none; }
.pn-setone.pn-setwide { max-width: none; }
/* ACCOUNT IS ONE CARD (report 36, 29 Sep 2026: "two buttons taking up an entire section"): as wide as the page since
   report 92, its two Sign out buttons side by side at its foot (assets/app.js account) */
.pn-acct { max-width: none; }
/* FOUR GLYPHS BESIDE THE LOGO (27 Sep 2026: "separate the settings into a new button next to accounts"): below 390px
   the top row closes up; a narrower phone is below. The glyphs keep their size. */
@media (max-width: 389px) {
  .pn-top { gap: 6px; }
  .pn-mine { gap: 0; }
}

/* THE HEADER ON A NARROW PHONE, 320 to 374px (design audit, 27 Sep 2026). Measured: the four pages needed 334px in one
   row, so at 340 to 374 Sign out was cut off and the page scrolled sideways, and at 320 People took a second line and
   the header grew from 110 to 156px. Here STUDIO steps out beside the logo, and the pages close up and share the row
   (each still 44px wide). A booth's figures take two lines rather than end in dots. */
@media (max-width: 374px) {
  .pn-bar .pn-tag { display: none; }
  .pn-nav { flex-wrap: nowrap; justify-content: space-between; gap: 0; }
  .pn-nav .wa-pill { letter-spacing: .03em; padding: 0 4px; min-width: 44px; }
  .pn-nav .wa-pill::after { left: 4px; right: 4px; }
  .pn-nav .pn-count { margin-left: 4px; }
  .pn-rear-v { white-space: normal; overflow: visible; text-overflow: clip; }
}

/* TOUCH TARGETS, THE REST (design audit, 27 Sep 2026: measured at 390px with touch, all under 44). At the end, so each
   outranks the size its own rule gives it on a computer. */
@media (pointer: coarse) {
  /* the X on a wide sheet and on a team sheet, a set's and a photo's More, the back link and a gallery's back arrow */
  .pn-ptmore, .pn-gback { width: 44px; height: 44px; }
  /* a photo's More keeps its 44px reach in the tile's corner, but draws only a 28px box inside it, so on a phone it no
     longer covers a third of the photo (2 Nov 2026, the operator: go A) */
  .pn-ptmore { top: 0; right: 0; padding: 8px; background-clip: content-box; }
  .pn-back { min-height: 44px; }
  /* New gallery's caret, the pager's numbers and arrows */
  :root[data-app] .pn-split > .pn-splitc { min-width: 44px; }
  /* the PIN's dots, an email's fill-in chips, the team's Exact wording */
  .pn-pinseen { min-height: 44px; }
  /* a gallery's tabs as glyphs */
  /* A GALLERY CARD'S STAR AND MORE keep the small 30px discs the operator asked for (26 Sep 2026); the press is the 7px
     round them, so each is 44px and the two meet without overlapping */
  .pn-gcard .pn-gcmore, .pn-gcard .pn-gstar { top: 2px; width: 44px; height: 44px; padding: 6px; background-clip: content-box; }
  .pn-gcard .pn-gcmore { right: 2px; }
  .pn-gcard .pn-gstar { right: 46px; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE WEBSITE (27 Sep 2026; assets/website.js; the operator: "write an SEO segment for each page also into the app page
   under a new tab under 'website'"). Pages, one page's editor with its Google and Facebook previews and its checks, the
   sitemap as a tree, the visits, and the site's settings. The Studio's own look, light and dark; every class here is
   .pn-ws..., and the Google and Facebook previews are drawn in their own light colours in both themes, as they look
   there. Sizes and places the script works out are set on the element from script, never as a style attribute.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */

/* THE WEBSITE TAB IS GONE (10 Oct 2026: "Do the header move now"; its places are under Settings). The strip that let a
   row with it scroll sideways on a phone went with it: the owner's row is five, Desk, Inbox, Jobs, Gallery and
   Photobooth, one row of tiles at every phone width (five tiles in one row, below). On a small computer a row of five
   glyph tabs closes up so it stays on one line, as the row of five with the Website in it did. */
@media (min-width: 980px) and (max-width: 1239px) {
  .pn-nav:has(> :nth-child(5)) { gap: 4px; }
  .pn-nav:has(> :nth-child(5)) .wa-pill { min-width: 88px; padding: 10px 10px 9px; }
}

.pn-ws { min-width: 0; }
.pn-ws .wa-gl .pn-gl { width: 16px; height: 16px; }
.pn-ws .pn-glicon { padding: 0; }
.pn-wswarn { display: flex; align-items: center; flex-wrap: wrap; gap: 2px 4px; margin: 6px 0 0; font-size: 14px; line-height: 1.45; color: rgba(242,239,232,.82); }
.pn-wswarn a { color: var(--beige); text-underline-offset: 3px; }
.pn-wsgroup { margin-top: 18px; }
.pn-wsgh { margin: 0 0 6px; }
.pn-wstab td { vertical-align: top; }
.pn-wstab .pn-dot { margin-right: 6px; }
.pn-wsctl { display: flex; flex-wrap: wrap; align-items: center; gap: 0 12px; }
.pn-wsctl .pn-gtabs { flex: 1 1 100%; margin-top: 10px; }
.pn-wsph { margin-left: 6px; font-style: normal; vertical-align: 1px; }
/* the Pages list on a phone: each page a card, each figure named */
@media (max-width: 759px) {
  .pn-wstab thead { display: none; }
  .pn-wstab, .pn-wstab tbody, .pn-wstab tr, .pn-wstab td { display: block; width: 100%; }
  .pn-wstab tr { padding: 12px 2px; border-bottom: 1px solid var(--pn-line, rgba(255,255,255,.09)); }
  .pn-wstab td { padding: 3px 0; border: 0; font-size: 13.5px; }
  .pn-wstab td.pn-glnum { text-align: left; }
  .pn-wstab td[data-label]::before { content: attr(data-label) ": "; color: rgba(242,239,232,.6); }
  /* THE PAGES LIST: one card, a row a page, its name and path with the check at the right, one small line for the figures */
  .pn-wstab.pn-wspages tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; column-gap: 12px; padding: 10px 12px; }
  .pn-wstab.pn-wspages td { width: auto; padding: 0; }
  .pn-wstab.pn-wspages td.pn-glname { grid-column: 1; grid-row: 1; }
  .pn-wstab.pn-wspages td[data-label="Checks"] { grid-column: 2; grid-row: 1; font-size: 12.5px; text-align: right; }
  .pn-wstab.pn-wspages td[data-label="Checks"]::before { content: none; }
  .pn-wstab.pn-wspages .pn-wsfig { grid-column: 1 / -1; grid-row: 2; display: inline; margin-top: 4px; font-size: 12px; color: var(--pn-muted); }
  .pn-wstab.pn-wspages td[data-label="Visitors"] { grid-column: 1 / -1; grid-row: 2; }
  .pn-wstab.pn-wspages td[data-label="Enquiries"], .pn-wstab.pn-wspages td[data-label="In search results"], .pn-wstab.pn-wspages td[data-label="Changed"] { display: none; }
  .pn-wstab.pn-wspages td[data-label="Visitors"]::before { content: none; }
  .pn-wstab.pn-wspages td[data-label="Visitors"] .pn-wsdesk { display: none; }
  .pn-wstab.pn-wspages td[data-label="Visitors"] .pn-wsline { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 2px 12px; margin-top: 6px; font-size: 12px; text-align: left; white-space: normal; color: var(--pn-ink); }
  .pn-wsfact { display: flex; align-items: baseline; gap: 6px; min-width: 0; }
  .pn-wsk { flex: none; font-size: 10.5px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--pn-muted); }
}

/* ---------- one page's editor ---------- */
.pn-wsactions { gap: 8px; }
.pn-wsactions .pn-gl { margin-left: -2px; }
/* a row of tabs wider than a phone (the Go page's six versions) goes onto a second line, never off the screen */
.pn-wstabs { flex-wrap: wrap; }
/* A THUMB, NOT A CURSOR (44 pixels on a touch screen): the tabs, a switch's reach, a page's name in the list, the way
   back, a tick's line */
@media (pointer: coarse) {
  .pn-ws .pn-gtab { height: 44px; }
  .pn-ws .pn-switch::after { content: ""; position: absolute; inset: -10px -6px; }
  .pn-ws .pn-back { min-height: 44px; }
  .pn-ws .pn-check { min-height: 44px; }
  .pn-ws .pn-gltab .pn-glname a { display: inline-flex; align-items: center; min-height: 44px; }
  .pn-ws .pn-wssort { min-height: 44px; }
  .pn-ws .pn-wsmini { height: 44px; }
  .pn-wswarn a { display: inline-flex; align-items: center; min-height: 44px; }
}
.pn-wsed { display: grid; gap: 0 18px; }
@media (min-width: 1100px) {
  .pn-wsed { grid-template-columns: minmax(0, 1fr) minmax(0, 430px); align-items: start; }
  .pn-wsside { position: sticky; top: 96px; }
}
.pn-wsfield { display: grid; gap: 6px; margin-top: 12px; }
.pn-wsfield .wa-pwin { width: 100%; min-width: 0; letter-spacing: normal; text-transform: none; }
.pn-wsfield .wa-pwin:disabled { opacity: .62; }
textarea.wa-pwin.pn-wsarea { min-height: 84px; }
@media (max-width: 760px) { .pn-wsfield .wa-pwin { font-size: 16px; } }
.pn-wssug { display: inline-flex; align-items: center; min-height: 34px; margin: 4px 0 0; padding: 0; }
.pn-wssug[hidden] { display: none; }
@media (pointer: coarse) { .pn-wssug { min-height: 44px; } }
/* the outline: each heading under its level, a line joining an H3 or H4 to the heading over it */
.pn-wsoutline { display: grid; gap: 8px; margin-top: 12px; }
.pn-wsout { position: relative; display: grid; grid-template-columns: 34px minmax(0, 1fr); align-items: center; gap: 0 8px; }
.pn-wsout .pn-wssug { grid-column: 2; justify-self: start; }
.pn-wsl3 { margin-left: 20px; }
.pn-wsl4 { margin-left: 40px; }
.pn-wsl3::before, .pn-wsl4::before { content: ""; position: absolute; left: -12px; top: -8px; height: 29px; width: 9px;
  border-left: 1px solid rgba(242,239,232,.22); border-bottom: 1px solid rgba(242,239,232,.22); border-bottom-left-radius: 4px; }
.pn-wslev { justify-content: center; font-variant-numeric: tabular-nums; }
.pn-wsfoot { justify-content: flex-start; }
/* the checks: one line on a phone, above the fields, that jumps to the list */
.pn-wschksum { display: none; }
@media (max-width: 1099px) {
  .pn-wschksum { display: flex; align-items: center; gap: 2px; width: 100%; min-height: 44px; margin: 14px 0 0; padding: 0 14px;
    border: 1px solid var(--pn-line, rgba(255,255,255,.12)); border-radius: var(--pn-r); background: transparent; color: inherit; font: inherit; font-size: 14px;
    text-align: left; cursor: pointer; }
}
.pn-wschks { display: grid; gap: 9px; margin: 8px 0 0; padding: 0; list-style: none; }
.pn-wschk { display: flex; align-items: baseline; font-size: 13.5px; line-height: 1.45; color: rgba(242,239,232,.72); }
.pn-wschk b { font-weight: 500; color: #f2efe8; }
.pn-wschk .pn-dot { flex: none; transform: translateY(-1px); }
#pn-wschecks:focus { outline: none; }
#pn-wschecks:focus-visible { outline: 2px solid var(--moon); outline-offset: 2px; }
.pn-wschkline { display: flex; align-items: center; margin: 12px 0 0; font-size: 13.5px; }
/* the two previews, each in the colours it has where it is seen */
.pn-wsprevhead { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 6px 12px; margin-bottom: 10px; }
.pn-wsprevhead h2 { margin: 0; }
.pn-wsprevhead .pn-gtabs { margin-top: 0; }
.pn-wsserp { padding: 14px 16px; border-radius: var(--pn-r); background: #fff; color: #202124; font-family: Arial, Helvetica, sans-serif; overflow-wrap: anywhere; }
.pn-wsserphead { display: flex; align-items: center; gap: 10px; }
.pn-wsfav { display: grid; place-items: center; flex: none; width: 28px; height: 28px; border-radius: 50%; background: #f1f3f4; border: 1px solid #dadce0; }
.pn-wsfav img { display: block; width: 16px; height: 16px; }
.pn-wsserpsite { min-width: 0; }
.pn-wsserpsite b { display: block; font-size: 14px; font-weight: 400; line-height: 1.3; color: #202124; }
.pn-wsserpsite small { display: block; font-size: 12px; line-height: 1.4; color: #4d5156; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pn-wsserpt { margin: 8px 0 3px; font-size: 20px; line-height: 1.3; color: #1a0dab; }
.pn-wsserpd { margin: 0; font-size: 14px; line-height: 1.58; color: #4d5156; }
.pn-wsserp-phone { max-width: 380px; }
.pn-wsserp-phone .pn-wsserpt { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; font-size: 18px; }
.pn-wsserp-phone .pn-wsserpd { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 3; overflow: hidden; }
.pn-wsfb { overflow: hidden; border-radius: var(--pn-r); border: 1px solid #dadde1; background: #f0f2f5;
  font-family: system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif; }
.pn-wsfbimg { display: grid; place-items: center; aspect-ratio: 1.91 / 1; background: #e4e6eb; color: #65676b; font-size: 13px; }
.pn-wsfbimg img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pn-wsfbband { display: grid; gap: 3px; padding: 10px 12px 12px; color: #050505; }
.pn-wsfbband small { font-size: 12px; letter-spacing: .02em; color: #65676b; }
.pn-wsfbband b { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; overflow: hidden; font-size: 16px; line-height: 1.25; font-weight: 600; }
.pn-wsfbband span { overflow: hidden; font-size: 14px; color: #65676b; white-space: nowrap; text-overflow: ellipsis; }
/* the sharing image */
.pn-wsshare { margin-top: 2px; }
.pn-wsshareimg { display: block; width: 100%; height: auto; aspect-ratio: 1200 / 630; object-fit: cover; border-radius: var(--pn-r); }
.pn-wssharenone { display: grid; place-items: center; aspect-ratio: 1200 / 630; padding: 14px; border-radius: var(--pn-r); border: 1px dashed rgba(242,239,232,.24);
  text-align: center; font-size: 13.5px; line-height: 1.45; color: rgba(242,239,232,.62); }
.pn-wssharenone p { margin: 0; max-width: 28em; }
/* the cropper, in a sheet */
.pn-wscrop { display: grid; gap: 0; }
.pn-wspick { display: grid; gap: 8px; justify-items: start; }
.pn-wsfile { cursor: pointer; }
.pn-wsframe { margin-top: 12px; overflow: hidden; border-radius: var(--pn-r); background: #fff; }
.pn-wsframe[hidden], .pn-wszoom[hidden] { display: none; }
.pn-wscanvas { display: block; width: 100%; height: auto; cursor: grab; touch-action: none; }
.pn-wscanvas:active { cursor: grabbing; }
.pn-wscanvas:focus-visible { outline: 2px solid var(--moon); outline-offset: -2px; }
.pn-wszoom { display: flex; align-items: center; gap: 12px; min-height: 44px; margin-top: 8px; font-size: 13px; }
.pn-wszoom input { flex: 1; min-width: 0; accent-color: var(--beige); }
.pn-wspicks { width: 100%; }
.pn-wspickgrid { display: grid; grid-template-columns: repeat(auto-fill, minmax(88px, 1fr)); gap: 6px; margin-top: 6px; }
.pn-wspickone { padding: 0; border: 1px solid rgba(255,255,255,.14); border-radius: var(--pn-r); overflow: hidden; background: none; cursor: pointer; }
.pn-wspickone img { display: block; width: 100%; height: auto; aspect-ratio: 4 / 3; object-fit: cover; }

/* ---------- the sitemap ---------- */
.pn-wsmapgrid { display: grid; gap: 0 14px; }
@media (min-width: 1200px) { .pn-wsmapgrid:has(> .pn-wspanel:not([hidden])) { grid-template-columns: minmax(0, 1fr) 320px; align-items: start; } }
.pn-wsmapcard { overflow-x: auto; overscroll-behavior-x: contain; }
.pn-wstreebox { position: relative; min-width: 0; }
.pn-wslinks { display: block; position: absolute; left: 0; top: 0; overflow: visible; pointer-events: none; }
.pn-wslinks path { fill: none; stroke: rgba(242,239,232,.22); stroke-width: 1.5; }
.pn-wstree, .pn-wstree ul { margin: 0; padding: 0; list-style: none; }
/* under 760 pixels: the same list, indented, joined by a line down the left, as a file tree */
.pn-wstree ul { margin: 6px 0 0 12px; padding-left: 12px; border-left: 1px solid rgba(242,239,232,.16); }
.pn-wstree li { margin: 6px 0 0; }
.pn-wstree > li:first-child { margin-top: 0; }
.pn-wsnode { position: relative; display: grid; gap: 1px; width: 100%; min-height: 44px; padding: 6px 34px 6px 11px; border: 1px solid rgba(255,255,255,.1);
  border-left: 4px solid var(--pn-wst, transparent); border-radius: var(--pn-r); background: rgba(255,255,255,.04); color: inherit; font: inherit; text-align: left;
  cursor: pointer; overflow: hidden; }
@media (hover: hover) { .pn-wsnode:hover { background: rgba(255,255,255,.08); } }
.pn-wsnode:focus-visible { outline: 2px solid var(--moon); outline-offset: 2px; }
.pn-wsnode.pn-on { box-shadow: 0 0 0 2px var(--beige); }
.pn-wsnn { overflow: hidden; font-size: 13px; font-weight: 600; line-height: 1.25; white-space: nowrap; text-overflow: ellipsis; }
.pn-wsnp { overflow: hidden; font-size: 11px; line-height: 1.3; color: rgba(242,239,232,.62); white-space: nowrap; text-overflow: ellipsis; }
/* the three figures, each over its word */
.pn-wsnf { display: grid; grid-template-columns: repeat(3, auto); justify-content: start; gap: 0 12px; margin-top: 2px; color: rgba(242,239,232,.62); }
.pn-wsnf > span { display: grid; min-width: 0; }
.pn-wsnf b { font-size: 12px; line-height: 1.15; font-weight: 600; color: #f2efe8; font-variant-numeric: tabular-nums; }
.pn-wsnf i { font-size: 9px; line-height: 1.25; font-style: normal; letter-spacing: .06em; text-transform: uppercase; }
.pn-wsplus { position: absolute; top: 9px; right: 9px; display: grid; place-items: center; width: 22px; height: 22px; border-radius: var(--pn-r);
  background: rgba(255,255,255,.1); font-size: 15px; line-height: 1; }
.pn-wsmore { padding: 2px 0 0 14px; font-size: 12px; color: rgba(242,239,232,.6); }
.pn-wsmore[hidden] { display: none; }
/* 760 pixels and wider: the tree left to right, each box placed by script (S.siteTree) */
.pn-wstree.pn-wsabs ul { margin: 0; padding: 0; border: 0; }
.pn-wstree.pn-wsabs li { margin: 0; }
.pn-wstree.pn-wsabs .pn-wsnode { position: absolute; height: 76px; align-content: center; }
.pn-wstree.pn-wsabs .pn-wsmore { display: none; }
/* the colours, never the only sign: a node's name for a screen reader says it, and the legend names each */
.pn-wst-good { --pn-wst: var(--st-good); }
.pn-wst-warn { --pn-wst: var(--st-warn); }
.pn-wst-bad { --pn-wst: var(--st-bad); }
.pn-wst-plain { --pn-wst: #b9ae9c; }
.pn-wst-none { --pn-wst: rgba(242,239,232,.2); }
.pn-wst-host { --pn-wst: transparent; }
.pn-wst-v1 { --pn-wst: rgba(79,167,232,.3); }
.pn-wst-v2 { --pn-wst: rgba(79,167,232,.5); }
.pn-wst-v3 { --pn-wst: rgba(79,167,232,.75); }
.pn-wst-v4 { --pn-wst: #4fa7e8; }
.pn-wskey { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px; margin-top: 12px; font-size: 12.5px; color: rgba(242,239,232,.7); }
.pn-wskeyh { font-weight: 600; }
.pn-wskeyi { display: inline-flex; align-items: center; gap: 6px; }
.pn-wssw { display: inline-block; width: 12px; height: 12px; border-radius: var(--pn-r); background: var(--pn-wst); box-shadow: inset 0 0 0 1px rgba(255,255,255,.12); }
/* a node's panel: beside the tree on a big screen, under it on a smaller one, a sheet on a phone */
.pn-wspanel[hidden] { display: none; }
@media (min-width: 1200px) { .pn-wspanel { position: sticky; top: 96px; } }
.pn-wspanelhead { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.pn-wspanelhead h2 { margin: 6px 0 0; }
.pn-ws h3, .pn-wspanelsheet h3 { margin: 14px 0 4px; }
.pn-wslist { margin: 4px 0 0; padding-left: 18px; font-size: 13.5px; line-height: 1.7; }
.pn-wslist b { margin-left: 4px; font-weight: 600; font-variant-numeric: tabular-nums; }
.pn-wspanelsheet .pn-figs { margin-top: 4px; }
.pn-wspanel .pn-figs, .pn-wspanelsheet .pn-figs { grid-template-columns: repeat(2, minmax(0, 1fr)); }

/* ---------- the visits ---------- */
.pn-wsfigs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
@media (min-width: 760px) { .pn-wsfigs { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
@media (min-width: 1300px) { .pn-wsfigs { grid-template-columns: repeat(6, minmax(0, 1fr)); } }
.pn-wschart { width: 100%; overflow: hidden; }
.pn-wschartsvg { display: block; max-width: 100%; height: auto; touch-action: pan-y; }
.pn-wsline { fill: none; stroke: var(--beige); stroke-width: 2; stroke-linejoin: round; }
.pn-wsbefore { fill: none; stroke: rgba(242,239,232,.28); stroke-width: 1.5; stroke-dasharray: 4 4; }
.pn-wsdot { fill: var(--moon); stroke: #241f19; stroke-width: 1.5; }
.pn-wsaxis { stroke: rgba(242,239,232,.18); stroke-width: 1; }
.pn-wsguide { stroke: rgba(242,239,232,.45); stroke-width: 1; }
.pn-wsguide[hidden] { display: none; }
.pn-wsaxt { fill: rgba(242,239,232,.58); font-size: 11px; font-family: inherit; font-variant-numeric: tabular-nums; }
.pn-wsbars { display: grid; gap: 8px; margin: 6px 0 0; padding: 0; list-style: none; }
.pn-wsbar { display: grid; grid-template-columns: minmax(0, 9.5em) minmax(0, 1fr) auto; align-items: center; gap: 4px 10px; font-size: 13.5px; }
.pn-wsbarl { overflow: hidden; white-space: nowrap; text-overflow: ellipsis; }
.pn-wsbart { height: 10px; overflow: hidden; border-radius: var(--pn-r); background: rgba(255,255,255,.07); }
.pn-wsbart i { display: block; width: 0; height: 100%; border-radius: var(--pn-r); background: var(--beige); }
.pn-wsbarv { font-variant-numeric: tabular-nums; white-space: nowrap; }
.pn-wsbarv small { font-size: 12px; color: rgba(242,239,232,.6); }
@media (max-width: 519px) {
  .pn-wsbar { grid-template-columns: minmax(0, 1fr) auto; }
  .pn-wsbart { grid-column: 1 / -1; grid-row: 2; }
}
.pn-wsforms h3:first-of-type { margin-top: 4px; }
.pn-wsfunnel .pn-wsbart i { background: #4fa7e8; }
/* THE BOOKING FORMS WITH ROOM TO READ (report 32, 29 Sep 2026: "Space vertically a bit"): each form's steps further
   apart, each heading clear of its first step, and the second form clear of the first. On a phone, where a step's
   words sit over its bar, the steps are 14px apart, the words 4px over the bar and the heading 20px over its first
   step; a computer, one line a step, a little less. */
.pn-wsforms .pn-wsfunnel { gap: 12px; margin-top: 14px; }
.pn-wsforms h3 + .pn-wsfunnel { margin-top: 14px; }
.pn-wsforms .pn-wsfunnel + h3 { margin-top: 24px; }
@media (max-width: 519px) {
  .pn-wsforms .pn-wsfunnel { gap: 14px; }
  .pn-wsforms h3 + .pn-wsfunnel { margin-top: 20px; }
  .pn-wsforms .pn-wsfunnel .pn-wsbar { row-gap: 4px; }
  .pn-wsforms .pn-wsfunnel + h3 { margin-top: 30px; }
}
.pn-wssmall { font-size: 13.5px; }
.pn-wssort { min-height: 32px; padding: 0; border: 0; background: none; color: inherit; font: inherit; letter-spacing: inherit; text-transform: inherit; cursor: pointer; white-space: nowrap; }
.pn-wsmini { height: 36px; }
.pn-wssites summary { position: relative; display: flex; align-items: center; gap: 8px; list-style: none; cursor: pointer; min-height: 32px; font-size: 12.5px; color: rgba(242,239,232,.7); }
.pn-wssites summary::-webkit-details-marker { display: none; }
.pn-wssites summary::after, summary.pn-note::after { content: ""; flex: none; width: 7px; height: 7px; margin-top: -3px; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(45deg); transition: transform .2s ease; }
.pn-wssites[open] summary::after, details[open] > summary.pn-note::after { margin-top: 3px; transform: rotate(225deg); }
summary.pn-note { display: flex; align-items: center; gap: 8px; list-style: none; cursor: pointer; min-height: 32px; }
summary.pn-note::-webkit-details-marker { display: none; }
@media (pointer: coarse) { .pn-wssites summary, summary.pn-note { min-height: 44px; } }
.pn-wscampf { display: grid; gap: 0; }
.pn-wscamplink { margin: 14px 0 10px; padding: 10px 12px; border-radius: var(--pn-r); background: rgba(0,0,0,.22); font-size: 13px; line-height: 1.5; word-break: break-all; }

/* ---------- settings ---------- */
/* THE PARTS ARE FOLDS, IN GROUPS (the operator, 28 Sep 2026, with the row of sixteen buttons: "Fix/redesign"; assets/
   website.js foldHtml): each group its small heading (the Settings home's group heading), then its folds, which are a job
   page's (.pn-jbfold and the rest, above): the glyph, the name, the chevron, 56px tall on a phone or a touch screen and
   52px with a mouse. Each row here also carries one line of where the part stands (.pn-wsfst): at the right of the row
   beside the chevron where there is room, and under the name on a phone. The rows are h3s under their group's h2, so the
   section's small capitals for an h3 (.pn-ws h3) are put back for them. An open fold's card is straight under its row. */
/* THE PAGE'S WIDTH, TWO COLUMNS WHERE THEY FIT (reports 163 and 166, 10 and 11 Oct 2026: "this can be two columns if
   screen width allows otherwise one", then "full width, two columns if screen can fit"). The parts were held to 880px,
   a narrow column at the left of a page 2400px wide. Now they run the page's width, in the two stacks website.js
   wsColumns makes: one under the other until the page under the side menu is 1100px wide, where each column still has
   a row's name and its line on one line, then side by side, each column its own grid, so a fold opened in one never
   moves the other's rows. The heading's line keeps its reading width (.pn-sub). */
.pn-wsparts { margin-top: 22px; container: wsparts / inline-size; }
.pn-wscols, .pn-wscol { display: grid; gap: 26px; align-content: start; min-width: 0; }
@container wsparts (min-width: 1100px) { .pn-wscols { grid-template-columns: repeat(2, minmax(0, 1fr)); align-items: start; column-gap: 48px; } }
.pn-wspart { min-width: 0; }
.pn-jbfolds.pn-wsfolds { margin-top: 0; }
.pn-ws .pn-wsfold > .pn-jbfh { margin: 0; font: inherit; letter-spacing: normal; text-transform: none; color: inherit; }
.pn-wsftx { display: flex; flex: 1 1 auto; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 2px 16px; min-width: 0; padding: 8px 0; }
.pn-wsfst { display: inline-flex; align-items: center; min-width: 0; font-size: 13px; line-height: 1.35; color: rgba(242,239,232,.62); overflow-wrap: anywhere; }
@media (max-width: 559px) { .pn-wsftx { flex-direction: column; flex-wrap: nowrap; align-items: flex-start; justify-content: center; } }
.pn-wsfold > .pn-jbfin > .pn-card { margin-top: 0; }
.pn-wsset .pn-srow:first-of-type { border-top: 0; }
/* the row names the card, so it opens on its first line: no rule above a switch there, no gap above a note */
.pn-wsfold > .pn-jbfin > .pn-card > .pn-srow:first-child { padding-top: 4px; border-top: 0; }
.pn-wsfold > .pn-jbfin > .pn-card > .pn-note:first-child { margin-top: 0; }
:root[data-app][data-theme="light"] .pn-ws .pn-wsfold > .pn-jbfh { color: inherit; }
:root[data-app][data-theme="light"] .pn-wsfst { color: var(--pn-ink-soft); }
.pn-wsrows { display: grid; gap: 0; margin-top: 10px; }
.pn-wsrow { padding: 12px 0 6px; border-top: 1px solid rgba(255,255,255,.08); }
.pn-wsrow .pn-srow { padding: 10px 0; border-top: 0; }
.pn-wsrowh { margin: 0; font-size: 14px; line-height: 1.4; }
.pn-wsrow > .pn-note:first-of-type { margin-top: 2px; }
.pn-wsrow > .wa-pwin, .pn-wsrow > .pn-sfold > .wa-pwin { width: 100%; height: 44px; margin-top: 8px; }
.pn-wsrowin { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 0 10px; }
.pn-wsrowline { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: end; gap: 0 8px; }
.pn-wsrowline .pn-srow { grid-column: 1 / -1; }
.pn-wsrowline > .pn-glicon { grid-row: 1; grid-column: 2; margin-bottom: 1px; width: 44px; height: 44px; }
.pn-wsrev > summary { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-height: 44px; cursor: pointer; font-size: 14px; }
.pn-wsrev[open] > summary { margin-bottom: 4px; }
.pn-wsmoves { display: grid; gap: 0; margin: 10px 0 0; padding: 0; list-style: none; }
.pn-wsmoves li { display: flex; align-items: center; justify-content: space-between; gap: 10px; min-height: 44px; padding: 4px 0;
  border-top: 1px solid rgba(255,255,255,.08); font-size: 13.5px; }
.pn-wsmoves li:first-child { border-top: 0; }
.pn-wsmoves li > span { display: grid; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.pn-wsmoves .pn-t { font-size: 12px; color: rgba(242,239,232,.6); }
.pn-wsmoveadd { display: grid; gap: 4px; margin-top: 12px; padding-top: 4px; border-top: 1px solid rgba(255,255,255,.08); }
.pn-wsdetails { margin-top: 10px; }
.pn-wsdetails > summary { display: flex; align-items: center; min-height: 44px; cursor: pointer; font-size: 13.5px; }
.pn-wsphotos { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 18px 16px; margin-top: 14px; }
.pn-wsphoto { display: grid; align-content: start; gap: 8px; min-width: 0; }
.pn-wsphoto .pn-row + .pn-wsfield { margin-top: 2px; }
.pn-wsphotoimg { display: grid; place-items: center; overflow: hidden; border-radius: var(--pn-r); background: rgba(255,255,255,.06); color: rgba(242,239,232,.6); font-size: 12.5px; }
.pn-wsphotoimg img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pn-wsar32 { aspect-ratio: 3 / 2; }
.pn-wsar45 { aspect-ratio: 4 / 5; }
.pn-wslog .pn-m .pn-t { display: block; }
/* the website's Colours card (assets/website.js themeCard): a picker and its hex side by side, and a small preview
   whose colours are custom properties the script sets through the CSSOM (never a style attribute) */
.pn-wsthin { display: grid; grid-template-columns: 52px minmax(0, 1fr); gap: 10px; align-items: center; margin-top: 8px; }
.pn-wsthpick { width: 52px; height: 44px; padding: 2px; border: 1px solid rgba(255,255,255,.18); border-radius: var(--pn-r); background: transparent; cursor: pointer; }
.pn-wsthpick:disabled { cursor: default; opacity: .62; }
.pn-wsthhex { width: 100%; height: 44px; font-size: 15px; font-variant-numeric: tabular-nums; }
.pn-wsthpv { display: grid; margin-top: 8px; overflow: hidden; border-radius: var(--pn-r); border: 1px solid rgba(255,255,255,.12); font-size: 13.5px; line-height: 1.4; }
.pn-wsthbar { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 14px; background: var(--pv-primary, #1d1915); color: var(--pv-on-primary, #fff); }
.pn-wsthlogo { display: block; width: 96px; height: 30px; color: #fff; }
.pn-wsthbook { padding: 8px 14px; border-radius: var(--pn-r); background: var(--pv-tertiary, #f4ff6a); color: var(--pv-on-tertiary, #1d1915); font-weight: 600; }
.pn-wsthband, .pn-wsthpage { display: grid; gap: 2px; padding: 12px 14px; }
.pn-wsthband { background: var(--pv-secondary, #e4d8c6); color: var(--pv-ink, #1d1915); }
.pn-wsthpage { background: var(--pv-surface, #fff); color: var(--pv-ink, #1d1915); }
.pn-wsthpage small { color: var(--pv-muted, #655b52); font-size: 12.5px; }
:root[data-app][data-theme="light"] .pn-wsthpick { border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-wsthpv { border-color: var(--pn-line); }
/* ---------- PHOTOS ON THE SITE (9 Oct 2026, assets/website-photos.js): a copy of a page in a frame at a phone's or a
   computer's own size, scaled to its column from script (the CSSOM, never a style attribute); a chip naming each place
   over it; the glass a file is dropped on, one zone a place, in the gallery's drop look (.pn-covdrop); the panel beside
   it on a computer and under it on a phone; and the bar with Cancel and Apply held at the foot of the page. The chips and
   zones sit over the copy, which is the website's own light page in either theme, so their colours are fixed. ---------- */
.pn-wsphotolink { margin: 0 0 10px; }
.pn-wsphotolink .wa-gl .pn-gl { width: 18px; height: 18px; }
.pn-sptools { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 14px; margin-top: 4px; }
.pn-sptools .pn-sppick { flex: 1 1 240px; max-width: 360px; min-width: 0; margin-top: 0; }
.pn-sptools .pn-pills { margin-top: 0; }
/* the Phone and Computer pills as tall as the page picker and Open the live page beside them */
@media (pointer: fine) { :root[data-app] .pn-sptools .pn-pill { height: 40px; } }
.pn-splive { flex: none; }
/* the toolbar's controls in one size of words (9 Nov 2026) */
:root[data-app] .pn-sptools :is(.pn-ddbtn.wa-pwin, .pn-pill, .pn-splive) { font-size: 12px; letter-spacing: 0; text-transform: none; }
.pn-splive .pn-gl { width: 16px; height: 16px; }
.pn-splive[hidden], .pn-spoff[hidden] { display: none; }
.pn-spoff { margin: 10px 0 0; color: var(--st-warn); }
.pn-spro { margin: -4px 0 12px; }
.pn-spgrid { display: grid; gap: 16px; margin-top: 16px; align-items: start; }
/* the panel beside the copy only where the computer's copy is still big enough to read beside it */
@media (min-width: 1280px) {
  .pn-spgrid { grid-template-columns: minmax(0, 1fr) minmax(300px, 380px); }
  .pn-sppanel { position: sticky; top: 84px; max-height: calc(100vh - 168px); overflow-y: auto; overscroll-behavior: contain; }
}
.pn-spstage { display: grid; justify-items: center; gap: 10px; min-width: 0; }
.pn-spbox { position: relative; overflow: hidden; max-width: 100%; border: 1px solid rgba(255,255,255,.14); border-radius: var(--pn-r); background: #fff;
  box-shadow: none; }
.pn-spscale { position: absolute; left: 0; top: 0; transform-origin: 0 0; }
.pn-spframe { display: block; border: 0; background: #fff; }
.pn-splayer { position: absolute; inset: 0; z-index: 1; overflow: hidden; pointer-events: none; }
.pn-spchip { position: absolute; left: 0; top: 0; display: inline-flex; align-items: center; max-width: min(240px, calc(100% - 12px)); height: 32px; padding: 0 12px;
  border: 1px solid rgba(255,255,255,.34); border-radius: var(--pn-r); background: rgba(20,18,16,.84); color: #f7f3ec; font: inherit; font-size: 12px; font-weight: 500;
  line-height: 1; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; cursor: pointer; pointer-events: auto; box-shadow: none; }
.pn-spchip[hidden] { display: none; }
/* a new photo not applied: the green the copy's own outline marks it with, deep enough for white words */
.pn-spchip-new { border-color: rgba(255,255,255,.55); background: #2f7d52; color: #fff; }
.pn-spchip-empty { background: #241f19; color: #f4ff6a; }
.pn-spchip-on { outline: 2px solid #f4ff6a; outline-offset: 1px; }
@media (hover: hover) { .pn-spchip:hover { background: #241f19; } .pn-spchip-new:hover { background: #276b46; } }
@media (pointer: coarse) { .pn-spchip { height: 44px; padding: 0 14px; } }
.pn-spglass { position: absolute; inset: 0; z-index: 2; background: rgba(20,18,16,.4); }
.pn-spglass[hidden] { display: none; }
.pn-spdragging .pn-splayer { visibility: hidden; }
:root[data-app] .pn-spglass .pn-covdrop.pn-spzone { position: absolute; left: 0; top: 0; box-sizing: border-box; place-items: center; gap: 0; padding: 6px;
  border: 2px dashed rgba(255,255,255,.9); border-radius: var(--pn-r); background: rgba(20,18,16,.22); color: #fff; font-size: 12px; font-weight: 600; text-align: center; }
:root[data-app] .pn-spglass .pn-covdrop.pn-spzone.pn-over { border-style: solid; border-color: #f4ff6a; background: rgba(244,255,106,.2); }
.pn-spzone span { max-width: 100%; padding: 5px 10px; border-radius: var(--pn-r); background: rgba(20,18,16,.8); overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  pointer-events: none; }
.pn-spframemsg { position: absolute; left: 12px; right: 12px; top: 12px; z-index: 3; margin: 0; padding: 10px 12px; border-radius: var(--pn-r); background: #241f19; color: #f7f3ec;
  font-size: 13.5px; line-height: 1.45; }
.pn-spframemsg[hidden] { display: none; }
.pn-spnote { max-width: 62ch; margin: 0; text-align: center; }
/* the panel: the page's places, or one place with its upload, its suggestions and its description */
.pn-sppanel { min-width: 0; scroll-margin-top: 84px; }
.pn-sppanel > h2 { margin: 0 0 6px; }
.pn-sppanel .pn-hl { margin: 14px 0 6px; }
.pn-splist { display: grid; gap: 2px; margin: 0; padding: 0; list-style: none; }
.pn-spitem { display: grid; grid-template-columns: 64px minmax(0, 1fr); align-items: center; gap: 12px; width: 100%; min-height: 56px; padding: 6px;
  border: 0; border-radius: var(--pn-r); background: none; color: inherit; font: inherit; text-align: left; cursor: pointer; }
@media (hover: hover) { .pn-spitem:hover { background: rgba(255,255,255,.06); } }
.pn-spwords { display: grid; gap: 2px; min-width: 0; }
.pn-spwords b { font-size: 13.5px; font-weight: 500; line-height: 1.35; overflow-wrap: anywhere; }
.pn-spwords .pn-t, .pn-spshape, .pn-spnow .pn-t { font-size: 12.5px; color: rgba(242,239,232,.62); }
.pn-spthumb { display: grid; place-items: center; overflow: hidden; border-radius: var(--pn-r); background: rgba(255,255,255,.06); color: rgba(242,239,232,.6); font-size: 11px;
  line-height: 1.3; text-align: center; }
.pn-spthumb img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pn-spthumbsm { width: 64px; height: 48px; }
.pn-spthumbbig { width: 100%; max-height: 300px; aspect-ratio: 3 / 2; }
.pn-spnone { padding: 6px; }
.pn-spback { margin: 0 0 10px; border: 0; background: none; color: inherit; font: inherit; font-size: 13px; cursor: pointer; }
.pn-sppanel .pn-sph { margin: 0 0 2px; }
.pn-spback .pn-gl { width: 16px; height: 16px; }
.pn-sph { overflow-wrap: anywhere; }
.pn-spshape { margin: 0 0 10px; }
.pn-spnow { display: grid; gap: 6px; margin-bottom: 10px; }
.pn-spnow .pn-t { margin: 0; }
.pn-spwarn { color: var(--st-warn); }
.pn-sprowb { flex-wrap: wrap; gap: 8px; margin: 4px 0 6px; }
.pn-sppanel .pn-wsfield { margin-top: 10px; }
:root[data-app] .pn-covdrop.pn-spdrop { gap: 10px; margin-top: 14px; padding: 26px 14px 22px; }
.pn-spdrop .pn-note { max-width: 34ch; margin: 0; }
/* Browse files reached by Tab: its input out of sight but still focusable, and the label ringed while it has the focus */
.pn-spfilein { position: absolute; width: 1px; height: 1px; margin: 0; padding: 0; border: 0; opacity: 0; overflow: hidden; clip-path: inset(50%); }
.pn-spdrop .pn-covbrowse { position: relative; padding: 0 6px; border-radius: var(--pn-r); }
.pn-spdrop .pn-covbrowse:focus-within { outline: 2px solid var(--moon); outline-offset: 3px; }
:root[data-app][data-theme="light"] .pn-spdrop .pn-covbrowse:focus-within { outline-color: var(--pn-ink); }
.pn-spsug { min-width: 0; }
.pn-sptiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 12px 10px; margin-top: 8px; }
.pn-sptile { display: grid; align-content: start; gap: 6px; min-width: 0; padding: 0; border: 0; background: none; color: inherit; font: inherit; text-align: left; }
button.pn-sptile { cursor: pointer; }
.pn-sptileimg { display: block; overflow: hidden; aspect-ratio: 3 / 2; border: 1px solid rgba(255,255,255,.14); border-radius: var(--pn-r); background: rgba(255,255,255,.06); }
.pn-sptileimg img { display: block; width: 100%; height: 100%; object-fit: cover; }
.pn-sptilewhy { font-size: 12px; line-height: 1.4; color: rgba(242,239,232,.72); overflow-wrap: anywhere; }
:root[data-app] .pn-spbest { display: block; width: fit-content; margin: 0 0 4px; font-style: normal; }
@media (hover: hover) { button.pn-sptile:hover .pn-sptileimg { border-color: var(--beige); } }
button.pn-sptile:focus-visible { outline: 2px solid var(--moon); outline-offset: 2px; border-radius: var(--pn-r); }
/* Adjust the crop: home's phone crop, its focus point and the tall crop it makes */
.pn-spfocus { display: grid; gap: 8px; margin-top: 16px; }
.pn-spfocus .pn-note { margin: 0; }
.pn-spfocusrow { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 12px; }
.pn-spfocal { flex: 0 1 auto; max-width: min(360px, 100%); }
.pn-spfocal img { max-height: 40vh; }
.pn-spfocal:focus-visible { outline: 2px solid var(--moon); outline-offset: 2px; }
.pn-spphone { flex: none; width: 90px; height: 160px; border-radius: var(--pn-r); background: #fff; }
/* the bar, held at the foot of the page, clear of the floating Report a problem button at the right */
.pn-spbar { position: sticky; bottom: 0; z-index: 5; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; margin: 16px 0 0;
  padding: 12px 76px 12px 16px; border: 0; border-radius: var(--pn-r); background: var(--pn-inkbar);
  box-shadow: 0 0 0 1px var(--pn-line, #3d3832); }
/* the ink bar with Apply the yellow and Cancel the line button in the bar's words (2 Nov 2026, the operator: go A; the
   kit at the top of the file) */
.pn-spstatus { flex: 1 1 240px; margin: 0; font-size: 14px; line-height: 1.45; }
.pn-sprow { display: flex; gap: 8px; }
:root[data-app] .pn-spbar .pn-spact { min-width: 104px; }
:root[data-app] .wa-btn.pn-spghost { border: 1px solid rgba(255,255,255,.3); background: transparent; color: #f2efe8; box-shadow: none; }
.pn-spmsg { flex: 1 1 100%; margin: 0; }
.pn-spmsg:empty { display: none; }
/* a phone: the app's header is two rows, the bar's words smaller, and the place's buttons one a row, each as wide */
@media (max-width: 759px) { .pn-sppanel { scroll-margin-top: 150px; } }
@media (max-width: 519px) {
  .pn-spbar { padding: 10px 68px 10px 12px; }
  .pn-spstatus { font-size: 13px; }
  .pn-sprow { flex: 1 1 100%; }
  :root[data-app] .pn-spbar .pn-spact { flex: 1 1 0; min-width: 0; }
  .pn-sprowb > .wa-gl { flex: 1 1 100%; }
}
:root[data-app][data-theme="light"] .pn-spbox { border-color: var(--pn-line); box-shadow: none; }
:root[data-app][data-theme="light"] button.pn-sptile:focus-visible,
:root[data-app][data-theme="light"] .pn-spfocal:focus-visible { outline-color: var(--pn-ink); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-spitem:hover { background: var(--pn-fill); } }
:root[data-app][data-theme="light"] .pn-spwords .pn-t, :root[data-app][data-theme="light"] .pn-spshape,
:root[data-app][data-theme="light"] .pn-spnow .pn-t, :root[data-app][data-theme="light"] .pn-sptilewhy { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-spthumb, :root[data-app][data-theme="light"] .pn-sptileimg { border-color: var(--pn-line); background: var(--pn-fill); color: var(--pn-ink-soft); }
@media (hover: hover) { :root[data-app][data-theme="light"] button.pn-sptile:hover .pn-sptileimg { border-color: var(--pn-olive); } }
:root[data-app][data-theme="light"] .pn-spbar { box-shadow: 0 0 0 1px var(--pn-line); }
:root[data-app][data-theme="light"] .pn-wrap .wa-btn.pn-spghost { border-color: rgba(36,31,25,.3); background: transparent; color: var(--pn-ink); }
/* ---------- the end of Photos on the site ---------- */

/* ---------- light ---------- */
:root[data-app][data-theme="light"] .pn-wswarn { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-wswarn a { color: var(--pn-olive, #4f4e0d); }
:root[data-app][data-theme="light"] .pn-wsl3::before, :root[data-app][data-theme="light"] .pn-wsl4::before { border-color: rgba(36,31,25,.22); }
:root[data-app][data-theme="light"] .pn-wschk { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-wschk b, :root[data-app][data-theme="light"] .pn-wsnf b { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-wsserp { box-shadow: inset 0 0 0 1px var(--pn-line); }
:root[data-app][data-theme="light"] .pn-wssharenone { border-color: rgba(36,31,25,.24); color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-wspickone { border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-wslinks path { stroke: rgba(36,31,25,.22); }
:root[data-app][data-theme="light"] .pn-wstree ul { border-left-color: rgba(36,31,25,.16); }
:root[data-app][data-theme="light"] .pn-wsnode { background: var(--pn-face); border-color: var(--pn-line); border-left-color: var(--pn-wst, transparent); color: var(--pn-ink); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-wsnode:hover { background: var(--pn-fill); } }
:root[data-app][data-theme="light"] .pn-wsnode.pn-on { box-shadow: 0 0 0 2px var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-wsnp, :root[data-app][data-theme="light"] .pn-wsnf, :root[data-app][data-theme="light"] .pn-wsmore,
:root[data-app][data-theme="light"] .pn-wskey, :root[data-app][data-theme="light"] .pn-wsbarv small, :root[data-app][data-theme="light"] .pn-wssites summary,
:root[data-app][data-theme="light"] .pn-wsmoves .pn-t, :root[data-app][data-theme="light"] .pn-wsphotoimg { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-wsplus, :root[data-app][data-theme="light"] .pn-wsbart,
:root[data-app][data-theme="light"] .pn-wsphotoimg { background: var(--pn-fill); }
:root[data-app][data-theme="light"] .pn-wst-none { --pn-wst: rgba(36,31,25,.18); }
:root[data-app][data-theme="light"] .pn-wst-plain { --pn-wst: #8f846f; }
:root[data-app][data-theme="light"] .pn-wssw { box-shadow: inset 0 0 0 1px rgba(36,31,25,.14); }
:root[data-app][data-theme="light"] .pn-wsline { stroke: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-wsbefore { stroke: rgba(36,31,25,.3); }
:root[data-app][data-theme="light"] .pn-wsdot { fill: #d99a1c; stroke: #fffdfa; }
:root[data-app][data-theme="light"] .pn-wsaxis { stroke: rgba(36,31,25,.18); }
:root[data-app][data-theme="light"] .pn-wsguide { stroke: rgba(36,31,25,.45); }
:root[data-app][data-theme="light"] .pn-wsaxt { fill: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-wsbart i { background: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-wsfunnel .pn-wsbart i { background: #2f7fbf; }
:root[data-app][data-theme="light"] .pn-wscamplink { background: var(--pn-fill); }
:root[data-app][data-theme="light"] .pn-wsrow, :root[data-app][data-theme="light"] .pn-wsmoves li,
:root[data-app][data-theme="light"] .pn-wsmoveadd { border-top-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-wsmoves li:first-child { border-top: 0; }
@media (max-width: 759px) { :root[data-app][data-theme="light"] .pn-wstab td[data-label]::before { color: var(--pn-ink-soft); } }

/* ---------- THE VISITS LIST (27 Sep 2026: "put these same info (also from cloudflare) into the analytics page";
   assets/website.js visitListPage and visitSheet): its filters, the table (a card a visit on a phone, through
   .pn-wstab), and one visit's sheet. Nothing here is wider than its column: an IPv6 address or a long provider's name
   wraps, so a phone never scrolls sideways. ---------- */
[data-wsvclear][hidden] { display: none; }
.pn-wsvdate { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: rgba(242,239,232,.72); }
/* the day in words from the app's calendar ("Thursday 15 October 2026"), so as wide as a Jobs filter's date */
.pn-wsvdate .wa-pwin { width: 230px; }
.pn-wsvq { flex: 1 1 220px; min-width: 0; }
.pn-wsvq .pn-glsearch { width: 100%; max-width: 340px; }
.pn-wsvcount { margin-top: 12px; }
.pn-wsvtab td { font-size: 13.5px; }
.pn-wsvtab .pn-wsvip { font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
.pn-wsvopen { display: grid; justify-items: start; gap: 2px; min-height: 44px; padding: 4px 0; border: 0; background: none; color: inherit;
  font: inherit; text-align: left; cursor: pointer; }
.pn-wsvopen b { font-weight: 600; white-space: nowrap; text-decoration: underline; text-underline-offset: 3px; text-decoration-color: currentColor; }
.pn-wsvopen .pn-t { font-size: 12.5px; color: rgba(242,239,232,.62); font-variant-numeric: tabular-nums; }
.pn-wsvlead { color: var(--beige); font-weight: 600; text-underline-offset: 3px; }
@media (min-width: 760px) { .pn-wsvtab td:not(.pn-glname) { max-width: 200px; overflow-wrap: anywhere; } }
/* on a phone the filters are two to a row, the search and the tick a row each, so no box is squeezed or cut */
@media (max-width: 759px) {
  .pn-wsvtab td.pn-wsvnone { display: none; }
  .pn-wsvf { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 8px; align-items: center; }
  .pn-wsvf .pn-glfilter { min-width: 0; }
  .pn-wsvf .pn-glfilter .wa-pwin { width: 100%; min-width: 0; }
  .pn-wsvdate .wa-pwin { flex: 1 1 auto; }
  .pn-wsvq, .pn-wsvenq { grid-column: 1 / -1; }
  .pn-wsvq .pn-glsearch { max-width: none; }
  .pn-wsvf [data-wsvclear] { justify-self: start; }
  .pn-wsvtab td[data-label] { overflow-wrap: anywhere; }
}
.pn-wsvfacts { display: grid; gap: 0; margin: 0; }
.pn-wsvfacts > div { display: grid; grid-template-columns: minmax(0, 11em) minmax(0, 1fr); align-items: baseline; gap: 2px 14px; padding: 8px 0;
  border-top: 1px solid rgba(255,255,255,.08); }
.pn-wsvfacts > div:first-child { border-top: 0; }
.pn-wsvfacts dt { font-size: 12.5px; color: rgba(242,239,232,.62); }
.pn-wsvfacts dd { margin: 0; font-size: 14px; overflow-wrap: anywhere; }
.pn-wsvfacts .pn-wsmini { margin-left: 8px; height: 32px; vertical-align: middle; }
.pn-wsvmap { margin-left: 8px; color: var(--beige); text-underline-offset: 3px; white-space: nowrap; }
.pn-wsvh { margin: 18px 0 6px; }
.pn-wsvsteps { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
.pn-wsvsteps li { display: grid; grid-template-columns: 7.5em minmax(0, 1fr); gap: 2px 12px; padding: 8px 0; border-top: 1px solid rgba(255,255,255,.08); font-size: 14px; }
.pn-wsvsteps li:first-child { border-top: 0; }
.pn-wsvclock { font-size: 13px; font-variant-numeric: tabular-nums; white-space: nowrap; color: rgba(242,239,232,.62); }
.pn-wsvwhat { display: grid; gap: 2px; min-width: 0; overflow-wrap: anywhere; }
.pn-wsvwhat .pn-t { font-size: 12.5px; color: rgba(242,239,232,.62); }
.pn-wsvev .pn-wsvwhat { color: rgba(242,239,232,.8); }
@media (max-width: 519px) {
  .pn-wsvfacts > div, .pn-wsvsteps li { grid-template-columns: minmax(0, 1fr); }
}
@media (pointer: coarse) {
  .pn-wsvfacts .pn-wsmini { height: 44px; }
  .pn-wsvmap, .pn-wsvlead { display: inline-flex; align-items: center; min-height: 44px; }
}
:root[data-app][data-theme="light"] .pn-wsvdate, :root[data-app][data-theme="light"] .pn-wsvopen .pn-t, :root[data-app][data-theme="light"] .pn-wsvfacts dt,
:root[data-app][data-theme="light"] .pn-wsvclock, :root[data-app][data-theme="light"] .pn-wsvwhat .pn-t { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-wsvopen b { text-decoration-color: currentColor; }
:root[data-app][data-theme="light"] .pn-wsvlead, :root[data-app][data-theme="light"] .pn-wsvmap { color: var(--pn-olive, #4f4e0d); }
:root[data-app][data-theme="light"] .pn-wsvfacts > div, :root[data-app][data-theme="light"] .pn-wsvsteps li { border-top-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-wsvev .pn-wsvwhat { color: var(--pn-ink); }

/* ---------- PHOTOBOOTH BOOKINGS (P3; assets/bookings.js): the list, one booking, its sheets, and the rear's event button ---------- */
/* a state's words can be long ("Link sent, waiting for their design"), so its pill wraps rather than push a phone sideways */
.pn-badge.pn-bkst-confirmed, .pn-badge.pn-bkst-sent { background: rgba(255,255,255,.07); color: rgba(242,239,232,.78); border-color: rgba(255,255,255,.16); }
.pn-badge.pn-bkst-submitted { background: var(--st-warn-bg); color: var(--st-warn); border-color: var(--st-warn-line); }
.pn-badge.pn-bkst-changes { background: rgba(79,167,232,.14); color: #9fd0f5; border-color: rgba(79,167,232,.35); }
.pn-badge.pn-bkst-approved, .pn-badge.pn-bkst-loaded { background: var(--st-good-bg); color: var(--st-good); border-color: var(--st-good-line); }
.pn-bklist .pn-m { min-width: 0; overflow-wrap: anywhere; }
.pn-bkset { display: grid; gap: 14px; min-width: 0; }
.pn-bkset > .pn-card { margin-top: 0; }
.pn-bkset .pn-form { max-width: none; }
.pn-bklinkline { margin-top: 6px; overflow-wrap: anywhere; }
.pn-bksmall.wa-pwin { width: auto; min-width: 150px; max-width: 60%; }
.pn-bkcatchrow { border-bottom: 0; padding-bottom: 6px; }
.pn-bkcatch { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; }
.pn-bkswatch { width: 44px; height: 44px; padding: 6px; border-radius: var(--pn-r); border: 1px solid rgba(255,255,255,.18); background: transparent; cursor: pointer; }
.pn-bkswatch i { display: block; width: 100%; height: 100%; border-radius: var(--pn-r); box-shadow: inset 0 0 0 1px rgba(255,255,255,.25); }
.pn-bkswatch[aria-checked="true"], .pn-bkpick.pn-on { outline: 2px solid var(--beige); outline-offset: 2px; }
:root[data-app] .pn-bkown[aria-checked="true"] { box-shadow: var(--pn-sh-sel); }
.pn-bkswatch:focus-visible, .pn-bkpick input:focus-visible { outline: 2px solid var(--moon); outline-offset: 2px; }
.pn-bkpick { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; padding-right: 4px; border-radius: var(--pn-r); font-size: 14px; cursor: pointer; }
.pn-bkpick input { width: 32px; height: 32px; padding: 0; border: 1px solid rgba(255,255,255,.18); border-radius: 0; background: transparent; cursor: pointer; }
.pn-bkpick input::-webkit-color-swatch-wrapper { padding: 0; }
.pn-bkpick input::-webkit-color-swatch { border: 0; border-radius: 0; }
.pn-bkpick input::-moz-color-swatch { border: 0; border-radius: 0; }
.pn-bkpick span { font-variant-numeric: tabular-nums; }
.pn-bkdesign { display: grid; gap: 16px; }
@media (min-width: 700px) { .pn-bkdesign { grid-template-columns: auto minmax(0, 1fr); align-items: start; } }
.pn-bkprev { display: grid; justify-items: center; gap: 8px; min-width: 0; }
.pn-bkprev canvas { display: block; max-width: 100%; height: auto; border-radius: var(--pn-r); box-shadow: 0 0 0 1px var(--pn-line, #3d3832); }
.pn-bkprev .pn-note { max-width: 260px; text-align: center; }
.pn-bkchips { display: flex; flex-wrap: wrap; gap: 6px 12px; }
.pn-bkchip { display: inline-flex; align-items: center; gap: 6px; font-variant-numeric: tabular-nums; }
.pn-bkchip i { flex: none; width: 16px; height: 16px; border-radius: var(--pn-r); box-shadow: inset 0 0 0 1px rgba(255,255,255,.3); }
.pn-bklinkin.wa-pwin { font-size: 13px; }
.pn-bkmail { margin-top: 14px; padding-top: 14px; border-top: 1px solid rgba(255,255,255,.08); }
.pn-bkmailtext { margin-top: 12px; padding: 12px; border-radius: var(--pn-r); background: rgba(255,255,255,.04); font-size: 14px; line-height: 1.5;
  white-space: pre-wrap; overflow-wrap: anywhere; max-height: 40vh; overflow: auto; }
/* the rear mirror's event name is the Booking card's button, as on the booth */
button.pn-rear-ev { appearance: none; min-height: 0; margin: 0; padding: 4px 8px; border: 0; background: none; font: inherit; font-weight: 600;
  text-align: left; cursor: pointer; }
button.pn-rear-ev.pn-on { background: var(--pn-soft); box-shadow: inset 0 0 0 1.5px var(--pn-ink); }
@media (pointer: coarse) { button.pn-rear-ev { position: relative; } button.pn-rear-ev::after { content: ""; position: absolute; inset: -8px 0; } }
button.pn-rear-ev:focus-visible { outline: 2px solid var(--moon); outline-offset: 2px; }
/* the same, in light */
:root[data-app][data-theme="light"] .pn-badge.pn-bkst-confirmed,
:root[data-app][data-theme="light"] .pn-badge.pn-bkst-sent { background: var(--pn-fill); color: var(--pn-ink-soft); border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-badge.pn-bkst-submitted { background: var(--st-warn-bg); color: var(--st-warn); border-color: var(--st-warn-line); }
:root[data-app][data-theme="light"] .pn-badge.pn-bkst-changes { background: rgba(40,110,170,.1); color: #1f5687; border-color: rgba(40,110,170,.28); }
:root[data-app][data-theme="light"] .pn-badge.pn-bkst-approved,
:root[data-app][data-theme="light"] .pn-badge.pn-bkst-loaded { background: var(--st-good-bg); color: var(--st-good); border-color: var(--st-good-line); }
:root[data-app][data-theme="light"] .pn-bkswatch,
:root[data-app][data-theme="light"] .pn-bkpick input { border-color: rgba(36,31,25,.2); }
/* a white chip or swatch on the light card needs a dark edge to be seen */
:root[data-app][data-theme="light"] .pn-bkswatch i,
:root[data-app][data-theme="light"] .pn-bkchip i { box-shadow: inset 0 0 0 1px rgba(36,31,25,.28); }
:root[data-app][data-theme="light"] .pn-bkmail { border-top-color: rgba(36,31,25,.1); }
:root[data-app][data-theme="light"] .pn-bkmailtext { background: rgba(36,31,25,.05); }

/* phone header tiles (27 Sep 2026) */
/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE PHONE'S PAGES AS TILES, LIKE THE COMPUTER'S (the operator, 27 Sep 2026: "Fix the header on mobile; can't you
   make tiles like the one on desktop with glyph and text centred"). Below 520px each page is the computer's tile: its
   glyph over its word, both centred, the open one in the same soft box with its glyph in moon yellow. The owner's six
   do not fit one row at 360 to 430px (Photobooth alone needs about 80px), so every tile is a third of the row and the
   rows wrap: six are two rows of three, fewer sit centred in one. Nothing scrolls sideways, the row or the page, and
   no tile is cut off at the edge of the screen, as People was. It outranks the phone rules above it, the six-tab
   strip included, by coming last with the header's own class in front.
   UP TO 760 NOW, NOT 520 (the operator, 28 Sep 2026: "yes fix", for People dropping to a second line of the row of
   words at 600). The row of words with their glyphs needs 635px on one line, 666 with a count on Gallery and 678 with
   99+, and 36px more on a touch screen, so it was sure of one line only from about 750. Below 760 the tiles stand in
   for it, as on a phone: two rows of three to 647px, and from 648 the six in one row, each a sixth of it, which is
   91px at the least and Photobooth's tile needs 91. Nothing is changed below 520, nor from 760.
   ONE ROW OF FIVE SINCE 28 SEP 2026 (People went under Settings, and the operator's report: "Make this one row"): a row
   of four or more is FIVE IN ONE ROW, below. The thirds here, and the sixths from 648, are for a row of one to three
   (staff, a team member), which is as it was. FIVE AGAIN SINCE 10 OCT 2026: the Inbox came in after the Desk and the
   Website went under Settings the same day, so the owner's row is Desk, Inbox, Jobs, Gallery, Photobooth.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
@media (max-width: 759px) {
  .pn-bar .pn-bar-in { gap: 6px; padding-top: 11px; padding-bottom: 11px; }
  .pn-bar .pn-nav { display: flex; flex-wrap: wrap; justify-content: center; gap: 4px; min-width: 0; max-width: none; margin: 0;
    overflow: visible; }
  .pn-bar .pn-nav > .wa-pill, .pn-bar .pn-nav > .pn-group { flex: 0 0 calc((100% - 8px) / 3); min-width: 0; }
  .pn-bar .pn-nav .wa-pill { flex-direction: column; justify-content: center; gap: 4px; height: auto; min-height: 48px; min-width: 0;
    padding: 6px 4px; white-space: nowrap; font-size: 11px; letter-spacing: .06em; color: rgba(242,239,232,.72);
    transition: background-color 140ms ease, color 140ms ease; }
  .pn-bar .pn-nav .pn-group > .wa-pill { width: 100%; }
  .pn-bar .pn-nav .wa-pill::after { display: none; }
  .pn-bar .pn-nav .wa-pill .pn-navgl { display: block; width: 19px; height: 19px; margin: 0; }
  .pn-bar .pn-nav .pn-count { position: absolute; top: 3px; left: calc(50% + 6px); margin: 0; }
  /* the open tile a 1px line under its word in the word's own colour, no box, as from 980 (2 Nov 2026, the operator: go A) */
  .pn-bar .pn-nav [aria-current="page"] { background: transparent; color: #fff; }
  .pn-bar .pn-nav [aria-current="page"]::after { display: block; left: 18%; right: 18%; bottom: 2px; background: currentColor; }
  .pn-bar .pn-nav [aria-current="page"] .pn-navgl { color: var(--moon); }
  .pn-bar .pn-nav .pn-menu { top: calc(100% + 6px); }
}
/* a row of one to three: each a sixth from 648, centred as they are below */
@media (min-width: 648px) and (max-width: 759px) {
  .pn-bar .pn-nav > .wa-pill, .pn-bar .pn-nav > .pn-group { flex: 0 0 calc((100% - 20px) / 6); }
}
@media (max-width: 759px) and (hover: hover) {
  .pn-bar .pn-nav .wa-pill:hover { background: rgba(255,255,255,.07); color: #fff; }
  .pn-bar .pn-nav [aria-current="page"]:hover { background: transparent; }
}
@media (max-width: 759px) and (prefers-reduced-motion: reduce) { .pn-bar .pn-nav .wa-pill { transition: none; } }
/* and from 760 on a touch screen, a little closer: at 760 with a scrollbar that takes room and 99+ on Gallery, the
   row of words with a finger's padding was 1px short of one line (review, 28 Sep 2026); 14px a side leaves it 11 over */
@media (pointer: coarse) and (min-width: 760px) and (max-width: 979px) { .pn-nav .wa-pill { padding: 0 14px; } }

/* five tiles in one row (28 Sep 2026) */
/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   FIVE IN ONE ROW (the operator, 28 Sep 2026, a problem report on the phone's two rows of tiles: "Make this one row").
   With People under Settings the owner's row is five: Desk, Jobs, Gallery, Photobooth, Website (since 10 Oct 2026 Desk,
   Inbox, Jobs, Gallery, Photobooth: the Website is under Settings, and the row of six it made with the Inbox is gone,
   its own rules with it). Below 760 a row of four
   or more is ONE row at every width, each tile the same share of it (a fifth), the glyph over its word, the lit one as
   it was. The words get smaller and closer as the row narrows, so PHOTOBOOTH, the longest, stays whole and never
   wraps: 11px spaced .12em while a fifth has room for it (a row of 510px or more: a phone from about 545, or an iPhone
   with Safari's page zoom out as the operator has it), then spaced .02em at a size worked out from the row's width
   (container query units), about 10px at 430, 8.5px at 390 and 7px at 320, never more than 11. The sum: a fifth of the
   row less its four 4px gaps, less the tile's 2px a side, over 7.6em, which is PHOTOBOOTH's width at .02em in the
   iPhone's face at the lit weight (measured from the report: 90.8px at 11px and .12em), with a little to spare. Each
   tile stays 48px tall. The count sits where it did, moved left only as far as a 99+ needs to stay in its tile.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
@media (max-width: 759px) {
  .pn-bar .pn-nav:has(> :nth-child(4)) { flex-wrap: nowrap; container: pnrow / inline-size; }
  .pn-bar .pn-nav:has(> :nth-child(4)) > .wa-pill, .pn-bar .pn-nav:has(> :nth-child(4)) > .pn-group { flex: 1 1 0; }
  .pn-bar .pn-nav:has(> :nth-child(4)) .wa-pill { padding: 6px 2px; font-size: clamp(7px, calc((100cqi - 36px) / 38), 11px); letter-spacing: .02em; }
  /* the count where it was, beside the glyph, moved left by as much as a wide one (99+) would run past its tile: half a
     tile (a tenth of the row less its gaps) less the 6px it starts right of the middle, less 2px, less its own width */
  .pn-bar .pn-nav:has(> :nth-child(4)) .pn-count { transform: translateX(min(0px, calc((100cqi - 16px) / 10 - 8px - 100%))); }
  @container pnrow (min-width: 510px) { .pn-bar .pn-nav:has(> :nth-child(4)) .wa-pill { font-size: 11px; letter-spacing: .06em; } }
  /* BOOTH, NOT A TINY PHOTOBOOTH (28 Sep 2026: "i emant the booth wording change only"): while the row is under 510px
     the Photobooth tab says Booth, so the longest word is GALLERY (about 5.6em at .06em, as WEBSITE was) and every word
     can be bigger: a fifth of the row less its gaps over 5.6em, about 11px at 390 and 9px at 320, never under 8 */
  @container pnrow (max-width: 509.98px) {
    .pn-bar .pn-nav:has(> :nth-child(4)) .wa-pill { font-size: clamp(8px, calc((100cqi - 36px) / 28), 11px); letter-spacing: .06em; }
    .pn-bar .pn-nav .pn-navl { display: none; }
    .pn-bar .pn-nav .pn-navs { display: inline; }
  }
}
/* the short word is hidden everywhere else: a computer's row, the phone's row from 510, and every other place */
.pn-navs { display: none; }

/* the top row on a phone (28 Sep 2026) */
/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE TOP ROW A LITTLE TALLER, THE LOGO A LITTLE BIGGER (the operator, 28 Sep 2026, a problem report on the desk's top
   bar on a phone: "Make this a bit taller and my logo a bit bigger accordingly"). Below 980, where the header is two
   rows, the row with the logo, STUDIO and the glyphs is 52px, not 44, and the logo is 104 by 33, the size the
   computer's was then (146 by 46 since report 13, 29 Sep 2026), not 88 by 28: both about a fifth bigger. STUDIO and
   the glyphs stay on the row's middle (.pn-top centres them).
   THE LOGO AS LARGE AS FITS (report 80, 2 Oct 2026: "it looks very aliased, until very zoomed in"): its rings and its
   small "photography" are finer than a pixel when it is small, so beside STUDIO and the four glyphs it is as large as
   the row has room for, never under 104 by 33: 146 by 46 from 430 (shorter than the 52px row, so the row keeps its
   height), 111 by 35 from 390, and 104 by 33 below, where the 92 by 29 it was is gone. The glyphs are pushed to the
   right by their own margin, not by the spacer, which was one more gap the narrowest phone could not spare; below 390
   the row's gaps are 4px, so 104 fits at 375 beside STUDIO and at 320 beside the glyphs, each 44px to a thumb.
   The logo is only made bigger, never recoloured or reshaped, and stays on the dark band. Where the row is short of
   room it closes up rather than run off: below 470 its gaps are 6px and the glyphs touch. Report a problem floats at
   the bottom right now (29 Sep 2026), so the owner's row is four glyphs again and STUDIO keeps its place down to 375,
   as the narrow phone's rule has it.
   ROOM ROUND THE LOGO (Problem report 101, 3 Oct 2026, the desk on an iPhone: "Increase height of this section so
   there's more vertical margin around the logo on mobile atm"): the row is the logo's height and 11px above and below
   it (11.5px with the two smaller logos), so the logo no longer nearly touches the row's top and bottom: 68px with the
   146 by 46 logo (from 430), 58px with 111 by 35 (390 to 429) and 56px with 104 by 33 (below 390). The logo's sizes
   stay as they were; STUDIO and the glyphs stay on the row's middle. Nothing measures the bar by a number of its own:
   the desk's ssHead and the Studio's fold scrolls read its height, and the business form's margin follows it.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
@media (max-width: 979px) {
  .pn-bar .pn-top { min-height: 68px; }
  .pn-bar .wa-logo { width: 146px; height: 46px; }
  .pn-bar .pn-top > .pn-spacer { display: none; }
  .pn-bar .pn-mine { margin-left: auto; }
}
@media (max-width: 469px) { .pn-bar .pn-top { gap: 6px; } .pn-bar .pn-mine { gap: 0; } }
/* report 82 (2 Oct 2026): a few pixels more between the logo and STUDIO wherever the row has them to spare */
@media (min-width: 470px) and (max-width: 979px) { .pn-bar .pn-tag { margin-left: 3px; } }
@media (max-width: 429px) { .pn-bar .wa-logo { width: 111px; height: 35px; } .pn-bar .pn-top { min-height: 58px; } }
@media (max-width: 389px) { .pn-bar .wa-logo { width: 104px; height: 33px; } .pn-bar .pn-top { gap: 4px; min-height: 56px; } }

/* settings home and groups (28 Sep 2026) */
/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   SETTINGS, GROUPED AS STUDIO NINJA'S ARE (the operator, 28 Sep 2026: "you're redeisgning the settings menu and
   grouuping as well right?"; assets/app.js settingsHome). /settings is a home: each group's heading, then its cards,
   one to a row on a phone, two from 560px and three from 900px. A card is its glyph in a soft square, its name and one
   line of what it holds, and the whole card is the link. A place keeps the same groups down the side on a computer
   (its places, and People and team, which sits inside Settings since 28 Sep 2026; the one link out, Business details,
   is on the home), closer together with a mouse than the other side menus so they fit a laptop's window; below 980px, where there is no side menu, a Settings link above the place goes back to the
   home. The row of places a phone had is gone: fifteen will not fit one.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
/* EACH ROW SIZED AGAIN AT EVERY WIDTH (reports 49 and 50, 30 Sep 2026: "Line cut off at no zoom", "Not top down
   aligned at 90% zoom"). When the window's width changed (a turn, a zoom, a wider window then a narrower one) Safari
   kept the grid's rows at their heights from the width before: a card whose words took two lines stayed one line tall
   and its last line hung out under it, one whose words came back to one line kept a band of nothing under them, and a
   group kept its old height, so its last card ran into the next group's heading or left a gap above it. Rows whose
   least is written as their content's (minmax(min-content, auto)) are worked out again each time; a fresh page lays
   out exactly as before. Measured in WebKit through Playwright, the page turned from 932 wide to 430, 506, 320, 390,
   1280, 700, 1000, 600 and 800 and back: every group, grid and card the height a fresh page gives it
   (test/studio-reports-49.test.mjs holds the rule). */
.pn-sethome { display: grid; gap: 24px; margin-top: 18px; }
.pn-setgroup { min-width: 0; }
/* a little more room between the groups on a phone (28 Oct 2026, the operator: "Increase spacing between sections a bit
   on mobile") */
@media (max-width: 559px) { .pn-sethome { gap: 34px; } .pn-setgh { margin-bottom: 12px; } }
.pn-setgh { margin: 0 0 10px; }
.pn-setgrid { display: grid; grid-template-columns: minmax(0, 1fr); grid-auto-rows: minmax(min-content, auto); gap: 10px; }
@media (min-width: 560px) { .pn-setgrid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (min-width: 900px) { .pn-setgrid { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.pn-setcard { display: grid; grid-template-columns: auto minmax(0, 1fr); align-content: center; align-items: start; gap: 14px; min-width: 0;
  min-height: 44px; padding: 16px; color: inherit; text-decoration: none; transition: transform .12s ease, border-color .2s ease; }
/* EVERY CARD THE TALLEST CARD'S HEIGHT, across every group (report 83, 2 Oct 2026: "makke these cards all the same
   size. adjust to the biggest card then just leave empty space"): measured from the cards by assets/app.js
   settingsEven and set as --pn-setcardh, again at every width.
   THE GLYPH AND WORDS IN THE MIDDLE, TOP TO BOTTOM (report 96, 2 Oct 2026, of the Connections cards on a phone:
   "Maybe center the glyph and text top down margin"). A card of one line under its name, Signature, Google sign-in,
   Xero or Desk sync, had its glyph and words at its top and all the room under them. The card is a grid of two
   columns, the glyph and the words, and the pair is placed as one in its middle (align-content), so the room is
   shared equally above and below, at every width. Within the pair nothing moves: the glyph stays beside the name at
   the words' top (align-items), and the words stay left-aligned. The tallest card has no room to share, so it looks
   as it did. */
.pn-sethome .pn-setcard { min-height: var(--pn-setcardh, 44px); }
/* AS THE WEBSITE'S GLYPH CARDS (2 Nov 2026, the operator: go A): the glyph's lines alone, no tile behind them, the yellow
   itself on the dark ground and ink on paper (yellow lines on white would be 1.1 to 1); the name 500, never bold, and
   the line under it the muted words */
.pn-setic { display: grid; place-items: center; flex: none; width: 40px; height: 40px; border-radius: var(--pn-r); background: none; color: var(--pn-y); }
.pn-setic .pn-gl { width: 24px; height: 24px; }
.pn-settx { display: grid; gap: 3px; min-width: 0; padding-top: 2px; }
.pn-settx b { font-size: 15px; font-weight: 500; line-height: 1.3; color: var(--pn-ink); overflow-wrap: anywhere; }
.pn-settx span { font-size: 13px; line-height: 1.45; color: var(--pn-muted); overflow-wrap: anywhere; }
/* under the mouse it lifts, as a night's card does, and wears the calculator's picked ring (a card has no border to
   colour since go A); written with the app's root so it outranks the card's own shadow */
@media (hover: hover) { :root[data-app] .pn-setcard:hover { transform: translateY(-2px); box-shadow: var(--pn-sh-sel); } }
@media (prefers-reduced-motion: reduce) { .pn-setcard { transition: none; } :root[data-app] .pn-setcard:hover { transform: none; } }
/* a place: the way back on a phone and a tablet, and the place's name close under it */
.pn-setback + .pn-h { margin-top: 10px; }
/* A PLACE OF ONE CARD: the place's heading already names it, so the card does not say it again (Reminders, Products,
   Email and the rest; the review, 28 Sep 2026). Travel keeps its card's "Home address", which the place's name does
   not say. A place of several cards (Payments, Google Calendar, Xero) keeps each card's heading. */
.pn-setone > #mn-set > .wa-card:only-child > h2:first-child { display: none; }
/* Shoot types (report 74) is a place of one card too, drawn into its own slot */
.pn-setone > #st-set > .wa-card:only-child > h2:first-child { display: none; }
.pn-setone > .wa-card:only-child:not(:has([data-form="home"])) > h2:first-child { display: none; }
/* THE WAY BACK AT EVERY WIDTH (report 85, 2 Oct 2026, from Email wording: "needs to be a back button to go to the main
   settings screen. yes I know there is the side menu but still"): every page under Settings, People and Problem
   reports among them, has Settings with its arrow under the header and above the page's heading, on a computer too,
   where it was hidden beside the side menu */
@media (min-width: 980px) {
  /* the groups down the side, each heading in small capitals; a short window scrolls the column, with a thin bar */
  .pn-side[aria-label="Settings"] { scrollbar-width: thin; overscroll-behavior: contain; }
  .pn-side[aria-label="Settings"] > .pn-sidek { margin: 14px 14px 4px; }
  .pn-side[aria-label="Settings"] > .pn-sidek:first-child { margin-top: 2px; }
}
/* ITS ROWS ARE 44PX WITH A MOUSE TOO, as every other side menu's are (1 Oct 2026, the overnight audit's LEFT-2). They
   were 38px with a mouse, a choice of the build's own that no one asked for; the column scrolls where a short window
   cannot show the whole list. */
/* on paper a card's glyph is its ink lines alone, no yellow square behind them (3 Nov 2026, the operator, of Settings on
   his iPhone: "Get rid of these yellow accents"; the website's .ws-feat-gl square from 2 Nov before); in dark the lines
   are the yellow */
:root[data-app][data-theme="light"] .pn-setic { background: none; color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-settx b { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-settx span { color: var(--pn-muted); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-setcard:hover { box-shadow: var(--pn-sh-sel); } }
/* connections: Google Calendar and Xero (28 Sep 2026) */
/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   GOOGLE CALENDAR AND XERO (the operator, 28 Sep 2026: "Xero and google calendar yes but just build the UI and
   framework for it", then for Google Calendar "start now, ill make a new calendar"; assets/connect.js). Two places of
   Settings: a card each for whether it is connected (Google Calendar's Connect with Google and Disconnect; Xero's
   Connect, not ready yet), its settings, what it carries (for Google Calendar, the next job as its event will look),
   and what is waiting or sent. Plain app cards; only what they add is here: what a press did, green when it went
   (the app's pn-msg is amber, for a problem); each change's state under its words; and the rows of buttons.
   THE BUTTON ROWS LINE UP FROM THE START (2 Oct 2026, report 73: "fix button alignments it looks weird"). Check and
   Save, and Put every job on the calendar and Send now, sit side by side from the left edge while they fit; once a row
   wraps, every line still starts at the left, never the last button pushed to the right on a line of its own (the
   `margin-left: auto` and the spacer that did that are gone). Side by side they are one height, the main one filled
   and never bigger: 40px with a mouse, 44px on a touch screen. A label longer than a phone's row wraps inside its
   button. THE CHANGED LIST ON A PHONE (report 73): below 600px each change's saved time goes under its words,
   left-aligned, where it sat in a column beside them and squeezed the words to five lines tall.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
#cn-set > .cn-card:first-child { margin-top: 0; }
.cn-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 12px; margin-bottom: 10px; }
.cn-card h2 { display: flex; align-items: center; gap: 8px; }
.cn-head h2 { margin: 0; }
.cn-card h2 .pn-gl, .cn-card .wa-btn .pn-gl, .cn-card .wa-gl .pn-gl { width: 16px; height: 16px; flex: none; }
.cn-card .wa-btn, .cn-card .wa-gl { display: inline-flex; align-items: center; gap: 8px; }
.cn-status { margin-bottom: 0; }
.cn-connect { margin-top: 14px; gap: 10px 14px; }
.cn-connect .cn-later { margin: 0; }
.cn-field { display: grid; gap: 6px; margin-top: 12px; font-size: 12px; line-height: 1.5; color: rgba(242,239,232,.56); }
.cn-field .wa-pwin { width: 100%; min-width: 0; }
.cn-field + .pn-note { margin-top: 6px; }
.cn-cal + .cn-cal { margin-top: 18px; padding-top: 6px; border-top: 1px solid rgba(255,255,255,.12); } /* Which calendars (report 69): the leads calendar under a line */
:root[data-app][data-theme="light"] .cn-cal + .cn-cal { border-top-color: var(--pn-line); }
.cn-what { display: grid; gap: 6px; margin: 4px 0 0; padding: 0 0 0 18px; font-size: 14px; line-height: 1.5; }
.cn-card > .cn-h3 { margin: 18px 0 8px; } /* room above, after a list or an event (report 70): .pn-card > h3 set none */
.cn-event { padding: 12px 14px; border-radius: var(--pn-r); border: 1px solid var(--pn-line); background: var(--pn-ground); overflow-wrap: anywhere; } /* the page's ground set into the card, edged with the hairline (2 Nov 2026, the operator: go A) */
.cn-evtitle { display: block; font-size: 15px; font-weight: 600; line-height: 1.4; }
.cn-evline { margin: 4px 0 0; font-size: 13px; line-height: 1.45; color: rgba(242,239,232,.72); }
.cn-notes { margin: 10px 0 0; white-space: pre-line; font-size: 13px; line-height: 1.55; }
.cn-out { margin-top: 4px; }
.cn-out .pn-m b { font-weight: 600; }
.cn-ok { color: var(--st-good); }
.cn-card .pn-msg:empty { min-height: 0; margin: 0; }
.cn-since { margin-top: 2px; }
.cn-problem { margin-top: 8px; }
.cn-btns { justify-content: flex-start; gap: 8px 10px; } /* report 73: from the left edge, every line of it */
.cn-btns .wa-gl, .cn-btns .wa-btn, .cn-connect .wa-gl { max-width: 100%; }
.cn-btns > .wa-gl, .cn-btns > .wa-btn { flex: none; height: auto; min-height: 40px; margin: 0; white-space: normal; text-align: left; }
@media (pointer: coarse) { .cn-btns > .wa-gl, .cn-btns > .wa-btn, .cn-connect > .wa-gl, .cn-connect > .wa-btn { min-height: 44px; } }
@media (max-width: 599px) { .cn-out li { flex-direction: column; align-items: flex-start; gap: 4px; } .cn-out li > .pn-m { flex: none; width: 100%; } }
.cn-state { display: inline-block; margin-top: 3px; font-size: 12px; line-height: 1.45; color: rgba(242,239,232,.62); overflow-wrap: anywhere; }
.cn-state.pn-badge { margin-top: 0; }
.cn-state.cn-sent { color: var(--st-good); }
.cn-state.cn-retrying { color: var(--st-warn); }
:root[data-app][data-theme="light"] .cn-field { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .cn-event { background: var(--pn-ground); border-color: var(--pn-line); }
:root[data-app][data-theme="light"] .cn-evline { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .cn-state { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .cn-state.cn-sent { color: var(--st-good); }
:root[data-app][data-theme="light"] .cn-state.cn-retrying { color: var(--st-warn); }
/* P5 (28 Sep 2026): a gallery's client, its download list and its favourite lists (assets/app.js clientBlock,
   restrictRow, listsBlock), and each list's picks under Activity. Every glyph here has its size written down. */
.pn-clientrow .wa-pwin { flex: 1 1 180px; min-width: 0; width: auto; }
.pn-allowin { width: 100%; height: auto; min-height: 110px; padding: 10px 12px; font-size: 14px; line-height: 1.5; resize: vertical; }
.pn-listrow { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pn-listrow .pn-listname { flex: 1 1 200px; min-width: 0; width: auto; }
.pn-listrow .pn-numin { flex: 0 0 110px; min-width: 0; width: auto; font-variant-numeric: tabular-nums; }
.pn-listacts { display: inline-flex; gap: 4px; }
:root[data-app] .pn-listbtn { width: var(--pn-h-act); height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0; display: inline-grid; place-items: center; }
.pn-listbtn svg { width: 16px; height: 16px; }
.pn-listbtn:disabled { opacity: .35; cursor: default; }
.pn-listcount { flex: 1 1 100%; margin: 0; }
.pn-listthumbs { display: flex; flex-wrap: wrap; gap: 6px; }
.pn-mailday { display: block; width: 140px; max-width: 100%; font-variant-numeric: tabular-nums; }
@media (max-width: 700px) { .pn-allowin { font-size: 16px; } }
/* the changelog (28 Sep 2026) */
/* THE CHANGELOG (the operator, 28 Sep 2026: "From now, publish a changelog, including all other builds (web) under
   settings with easy to read (major/minor fixes/feature add)"; assets/app.js changelogDraw). Settings, About,
   Changelog: the kind chips with their counts, the Part and the search, then each day's heading and its builds, each
   a quiet block of its time and title, a row for each change (its kind as a pill that always says it in words, its
   part, then the sentence) and its commits, small. Phone first; a row's kind and part sit beside its sentence from
   700px. Every size a finger presses is 44px on a phone and on a touch screen. */
/* as wide as the page since report 92 (2 Oct 2026), as every page is: each change is one short sentence beside its
   kind and part, so a row reads across it (920px before) */
.pn-setone.pn-chg { max-width: none; }
.pn-chg > .pn-sub { margin: 0 0 14px; }
.pn-chgbar { display: grid; gap: 10px; }
.pn-chgbar > .pn-pills { margin: 0; }
.pn-chgfind { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
.pn-chgpart { flex: 0 0 auto; min-width: 0; }
.pn-chgfind .pn-chgq { flex: 1 1 220px; max-width: 360px; min-width: 0; width: auto; }
.pn-chglist { display: grid; gap: 4px; }
.pn-chgday { min-width: 0; }
.pn-chgdh { margin: 22px 0 10px; }
.pn-chgbuilds { display: grid; gap: 10px; }
.pn-chgbuild { min-width: 0; padding: 14px 16px 12px; border-radius: var(--pn-r); border: 1px solid var(--pn-line, rgba(255,255,255,.09));
  background: var(--pn-face, rgba(255,255,255,.04)); }
.pn-chghead { display: grid; grid-template-columns: 64px minmax(0, 1fr); align-items: baseline; gap: 2px 10px; margin: 0 0 8px; line-height: 1.35; }
.pn-chgtime { flex: none; font-size: 13px; font-weight: 500; font-variant-numeric: tabular-nums; color: rgba(242,239,232,.62); }
.pn-chgtitle { min-width: 0; overflow-wrap: anywhere; }
.pn-chgitems { display: grid; margin: 0; padding: 0; list-style: none; }
.pn-chgitem { display: grid; gap: 5px; min-width: 0; padding: 9px 0; border-top: 1px solid var(--pn-line, rgba(255,255,255,.09)); }
.pn-chgmeta { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 10px; min-width: 0; }
/* one width for the three pills, so each row's part starts in the same place */
.pn-chgkind { flex: none; justify-content: center; min-width: 112px; height: 24px; padding: 0 9px; font-size: 11px; letter-spacing: .12em; }
.pn-chgarea { font-size: 12.5px; line-height: 1.3; color: rgba(242,239,232,.62); }
.pn-chgtext { min-width: 0; font-size: 14px; line-height: 1.5; color: rgba(242,239,232,.9); overflow-wrap: anywhere; }
.pn-chgids { margin: 6px 0 0; font-size: 11.5px; line-height: 1.5; word-spacing: .3em; font-variant-numeric: tabular-nums; color: rgba(242,239,232,.56);
  overflow-wrap: anywhere; }
.pn-chgmore { display: flex; justify-content: center; margin-top: 18px; }
@media (min-width: 700px) {
  .pn-chgitem { grid-template-columns: 196px minmax(0, 1fr); gap: 14px; align-items: baseline; }
  .pn-chgmeta { flex-wrap: nowrap; }
}
/* a phone: the four chips two to a row, the Part and the search each the whole width, and all of them a thumb's size */
@media (max-width: 519px) {
  /* two to a row at every phone width (3 Nov 2026: at 390px three fitted, and Minor fixes sat on a row alone) */
  .pn-chgbar > .pn-chgkinds { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pn-chgkinds > .pn-pill { min-width: 0; }
  .pn-chgpart, .pn-chgfind .pn-chgq { flex: 1 1 100%; max-width: none; }
  :root[data-app] .pn-chgpart .wa-pwin, :root[data-app] .pn-chgfind .pn-chgq { width: 100%; height: 44px; }
  .pn-chgmore .wa-gl { width: 100%; min-height: 44px; }
}
/* on a computer the search is the Part's height, 32px, as the chips above them (the lists' shared search rule is 36px) */
@media (min-width: 980px) {
  :root[data-app] .pn-chgfind .pn-chgq:not(textarea) { height: 32px; font-size: 12.5px; }
}
/* a touch screen of any width, a tablet on its side included: both 44px, over the lists' shared computer rules */
@media (pointer: coarse) {
  :root[data-app] .pn-chgpart .wa-pwin:not(textarea), :root[data-app] .pn-chgfind .pn-chgq:not(textarea) { height: 44px; font-size: 16px; }
  .pn-chgmore .wa-gl { min-height: 44px; }
}
:root[data-app][data-theme="light"] .pn-chgtime, :root[data-app][data-theme="light"] .pn-chgarea,
:root[data-app][data-theme="light"] .pn-chgids { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-chgtext { color: var(--pn-ink); }
/* each build a card of the calculator's (2 Nov 2026, the operator: go A): the card's face and soft shadow, no hairline
   round it, in both themes */
:root[data-app][data-theme] .pn-chgbuild { border-color: transparent; box-shadow: var(--pn-sh); }

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   REPORT A PROBLEM (the operator, 28 Sep 2026: "Can you do that but also an option to drag and select a portion of
   the screen so I don't have to type as detailed"; assets/report.js). The layer over the page while a part is marked,
   the marks, the bar that says what to do, the sheet that sends it, and the Problem reports page (assets/app.js).
   A mark is a strong pink with a dark edge, which shows on the light pages and the dark alike; the picture draws its
   marks the same way. The layer holds the page still: touch-action none on the layer only.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.pn-rplayer { position: fixed; inset: 0; z-index: 2147483000; cursor: crosshair; touch-action: none; user-select: none; -webkit-user-select: none;
  background: rgba(20,16,12,.08); box-shadow: inset 0 0 0 3px #ff2f92, inset 0 0 0 5px rgba(0,0,0,.35); -webkit-tap-highlight-color: transparent; }
.pn-rpmarks { position: absolute; inset: 0; pointer-events: none; }
.pn-rpmark { position: absolute; box-sizing: border-box; border: 3px solid #ff2f92; border-radius: var(--pn-r); pointer-events: none;
  box-shadow: 0 0 0 2px rgba(0,0,0,.62), inset 0 0 0 1px rgba(0,0,0,.35); }
.pn-rpnum { position: absolute; top: -13px; left: -13px; min-width: 24px; height: 24px; padding: 0 6px; border-radius: var(--pn-r); background: #ff2f92;
  color: #ffffff; font: 700 13px/24px system-ui, -apple-system, "Segoe UI", sans-serif; text-align: center; font-variant-numeric: tabular-nums;
  box-shadow: 0 0 0 2px rgba(0,0,0,.62); }
.pn-rpnum.pn-rpnumin { top: 2px; left: 2px; }
.pn-rpx { position: absolute; top: -16px; right: -16px; display: grid; place-items: center; width: 32px; height: 32px; padding: 0; border: 2px solid #ff2f92;
  border-radius: 50%; background: #1d1915; color: #ffffff; cursor: pointer; pointer-events: auto; box-shadow: 0 0 0 2px rgba(0,0,0,.4); }
.pn-rpx .pn-gl { width: 16px; height: 16px; stroke-width: 2; }
.pn-rpx.pn-rpxin { right: 4px; }
.pn-rpx.pn-rpxdown { top: 4px; }
/* a small mark keeps its Remove outside it, so what was marked still shows (report.js markPlaces) */
.pn-rpx.pn-rpxright { top: 50%; right: auto; left: calc(100% + 6px); transform: translateY(-50%); }
.pn-rpx.pn-rpxbelow { top: calc(100% + 6px); right: 0; }
.pn-rpx.pn-rpxabove { top: auto; bottom: calc(100% + 6px); right: 0; }
.pn-rpnum.pn-rpnumup { top: -28px; left: 0; }
.pn-rpnum.pn-rpnumleft { top: 0; left: -28px; }
.pn-rpdraw { position: absolute; box-sizing: border-box; border: 2px dashed #ff2f92; border-radius: var(--pn-r); background: rgba(255,47,146,.12); pointer-events: none;
  box-shadow: 0 0 0 1px rgba(0,0,0,.45); }
/* the bar keeps inside what the browser shows between its own bars (report.js followShown: --rp-above and --rp-under
   are how much of the window they cover), and clear of the notch and the home bar */
.pn-rpbar { position: absolute; left: 50%; bottom: calc(max(16px, env(safe-area-inset-bottom)) + var(--rp-under, 0px)); transform: translateX(-50%); display: flex; flex-wrap: wrap;
  align-items: center; gap: 10px 14px; width: min(580px, calc(100% - 32px - env(safe-area-inset-left) - env(safe-area-inset-right))); padding: 12px 12px 12px 16px; border: 1px solid rgba(255,255,255,.14);
  border-radius: var(--pn-r); background: #241f19; color: #f2efe8; box-shadow: none; cursor: default; }
.pn-rpbar.pn-rptop { top: calc(max(16px, env(safe-area-inset-top)) + var(--rp-above, 0px)); bottom: auto; }
.pn-rpsay { flex: 1 1 220px; min-width: 0; margin: 0; font-size: 14px; line-height: 1.4; outline: none; }
.pn-rpbtns { display: flex; flex: none; gap: 8px; margin-left: auto; }
/* THE BUTTON, FLOATING AT THE BOTTOM RIGHT (the operator, 29 Sep 2026: "for the studio make it floating and persistent so
   I can report issues on popups and forms"; assets/rpbutton.js), in place of the flag the header had. Round, the flag in
   the header's own hand, over everything the Studio and the desk open (the lists 95, the pop menu 96, the toast 80, the
   docks 65, the notes 70, the sheets and the desk's windows 60) and under the reporter's own layer and sheet. It moves
   up clear of a small box or a popup's control under it (--rp-lift). A TAB IN THE GUTTER since 9 Nov 2026 (the operator: the
   flag sat over the content and the fold's chevron): 15px wide on the window's right edge, inside the page's 16px gutter, so no
   card edge, chevron or row control ever passes under it, at every width. Hidden while the reporter is open. A rounded square, the
   Studio's own corners, no longer round (the operator, 10 Oct 2026: "make the report button a rounded square"), and square since 2 Nov 2026, the one corner (the operator: "go A", corners square like the website). */
.pn-rpfab { position: fixed; right: 0; bottom: max(16px, env(safe-area-inset-bottom)); z-index: 2147482000;
  display: grid; place-items: center; box-sizing: border-box; width: calc(15px + env(safe-area-inset-right)); height: 48px; margin: 0; padding: 0 env(safe-area-inset-right) 0 0; border: 1px solid rgba(255,255,255,.16); border-right: 0;
  border-radius: var(--pn-r); background: #2a241d; color: #f2efe8; box-shadow: none; cursor: pointer; font: inherit;
  touch-action: manipulation; -webkit-tap-highlight-color: transparent; -webkit-user-select: none; user-select: none;
  transform: translate(var(--rp-x, 0px), var(--rp-lift, 0px)); transition: transform .15s ease, background-color .15s ease; }
.pn-rpfab .pn-gl { width: 14px; height: 14px; pointer-events: none; }
/* its reach on a touch screen stays in the gutter too, or a press on a row's control passing it would open the reporter; the screen's edge gives the rest */
@media (pointer: coarse) { .pn-rpfab::before { content: ""; position: absolute; inset: -4px 0 -4px -1px; } }
@media (hover: hover) { .pn-rpfab:hover { background: #3a3229; } }
.pn-rpfab:focus-visible { outline: 2px solid var(--beige); outline-offset: 3px; }
/* while a sheet is open it stays there to be pressed, a popup being what it is built to report, and steps back */
html:has(.pn-sheet, .pn-covsheet, .cw-sheet, .dk-modal:not([hidden])) .pn-rpfab { opacity: .55; }
:root[data-app][data-theme="light"] .pn-rpfab { border-color: transparent; background: var(--pn-face); color: var(--pn-ink); box-shadow: var(--pn-sh); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-rpfab:hover { background: var(--pn-hover); } }
:root[data-app][data-theme="light"] .pn-rpfab:focus-visible { outline-color: #241f19; }
html.rp-reporting .pn-rpfab { display: none; }
/* NEW MAIL AND MESSAGES, AS THEY COME (report 176, 12 Oct 2026: "with a bottom right notification that pops up if the page
   is open whilst a new email comes in or a message"; frame.js S.liveInbox): a stack at the bottom right, ABOVE Report a
   problem's button (its 48px and 12px more), never over it, and on a phone above the bottom edge and Safari's bar (the
   button's own safe-area room). Three at most, newest at the top, each its picture, who, the subject or first words,
   Open and a cross; "And n more in the Inbox" under them. UNDER the sheets and the desk's windows (60; the review, 13 Oct
   2026: on a phone a notice sat over a sheet's Save), new ones waiting while one is open (frame.js liveCovered). The
   app's own face, edge and ink in light and dark; 44px to a thumb; no movement with reduced motion. */
.pn-live { position: fixed; right: max(16px, env(safe-area-inset-right)); bottom: calc(max(16px, env(safe-area-inset-bottom)) + 60px); z-index: 55;
  display: grid; gap: 8px; width: min(360px, calc(100vw - 32px)); margin: 0; }
.pn-live[hidden] { display: none; }
.pn-livet { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto auto; align-items: center; gap: 10px; min-width: 0; padding: 10px 8px 10px 12px;
  border: 1px solid var(--pn-line); border-radius: var(--pn-r); background: var(--pn-face-2, #2a241d); color: var(--pn-ink, #f2efe8); box-shadow: var(--pn-sh);
  animation: pn-livein .22s ease both; }
@keyframes pn-livein { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
.pn-liveav { display: inline-grid; place-items: center; width: 36px; height: 36px; border-radius: 50%; border: 1px solid rgba(255,255,255,.16);
  background: rgba(255,255,255,.06); font-size: 14px; font-weight: 600; line-height: 1; }
.pn-liveav-studio { background: #241f19; color: #fff; }
.pn-liveav-studio .pn-livelogo { display: block; width: 26px; height: 26px; }
.pn-livew { display: grid; gap: 1px; min-width: 0; font-size: 13px; line-height: 1.35; }
.pn-livewho { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.pn-livesub { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.pn-livech { font-size: 11px; opacity: .7; }
/* Open in the notice's own colours, as it sits outside any page (the app's glyph button takes its light look from the page) */
.pn-livet .pn-liveopen { min-height: 36px; padding: 0 12px; border: 1px solid rgba(255,255,255,.18); background: rgba(255,255,255,.08); color: #f2efe8; }
@media (hover: hover) { .pn-livet .pn-liveopen:hover { background: rgba(255,255,255,.14); } }
.pn-livex { display: inline-grid; place-items: center; width: 36px; height: 36px; padding: 0; border: 0; border-radius: var(--pn-r); background: transparent; color: inherit; cursor: pointer; }
.pn-livex .pn-gl { width: 16px; height: 16px; }
@media (hover: hover) { .pn-livex:hover { background: rgba(255,255,255,.08); } }
.pn-livex:focus-visible, .pn-liveopen:focus-visible, .pn-livemore:focus-visible { outline: 2px solid var(--beige); outline-offset: 2px; }
/* "And n more in the Inbox": a press chip (ONE SIZE A CONTROL, .pn-pchip's size) in the notice's own colours */
.pn-livemore { justify-self: end; background: var(--pn-face-2, #2a241d); color: var(--pn-ink, #f2efe8); text-decoration: none; box-shadow: var(--pn-sh); }
@media (hover: hover) { .pn-livemore:hover { background: var(--pn-hover); } :root[data-app][data-theme="light"] .pn-livemore:hover { background: var(--pn-hover); } }
/* a notice is the app's card in either theme: its face, the calculator's shadow, square (2 Nov 2026, the operator: go A) */
:root[data-app][data-theme="light"] .pn-livet, :root[data-app][data-theme="light"] .pn-livemore { border-color: transparent; background: var(--pn-face);
  color: var(--pn-ink); box-shadow: var(--pn-sh); }
:root[data-app][data-theme="light"] .pn-liveav:not(.pn-liveav-studio) { border-color: rgba(36,31,25,.16); background: rgba(36,31,25,.05); }
:root[data-app][data-theme="light"] .pn-livet .pn-liveopen { border-color: var(--pn-line); background: var(--pn-face); color: var(--pn-ink); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-livet .pn-liveopen:hover { background: var(--pn-hover); } }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-livex:hover { background: rgba(36,31,25,.06); } }
:root[data-app][data-theme="light"] .pn-livex:focus-visible, :root[data-app][data-theme="light"] .pn-liveopen:focus-visible,
:root[data-app][data-theme="light"] .pn-livemore:focus-visible { outline-color: #241f19; }
@media (pointer: coarse) { .pn-live { bottom: calc(max(16px, env(safe-area-inset-bottom)) + 60px); } .pn-liveopen, .pn-livex, .pn-livemore { min-height: 44px; } .pn-livex { width: 44px; } }
@media (max-width: 380px) { .pn-livet { grid-template-columns: 32px minmax(0, 1fr) auto; } .pn-liveav { width: 32px; height: 32px; } .pn-liveopen { grid-column: 2; justify-self: start; }
  .pn-livex { grid-column: 3; grid-row: 1; } }
html.rp-reporting .pn-live { display: none; }
@media (prefers-reduced-motion: reduce) { .pn-livet { animation: none; } }
/* A NOTICE OPENED IN A SHEET (Problem report 237, 27 Oct 2026; frame.js S.liveSheet): the app's sheet, the messages under
   one another newest first, each its who and when over its words, a hairline between them */
.pn-livemsgs { display: grid; margin: 4px 0 0; padding: 0; list-style: none; }
.pn-livemsg { padding: 12px 0; border-top: 1px solid var(--pn-line); }
.pn-livemsg:first-child { border-top: 0; padding-top: 4px; }
.pn-sheet p.pn-livemhead { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin: 0; }
.pn-livemsg .ib-text { margin-top: 4px; font-size: 14px; line-height: 1.55; }
.pn-sheet .pn-livemsg p.pn-t { margin: 6px 0 0; }
@media (prefers-reduced-motion: reduce) { .pn-rpfab { transition: none; } }
/* ROOM FOR IT: the page's end (the panel's pages and the desk alike are .pn-wrap) runs on past it, and on a phone a
   sheet's card ends above it, so a card's Save at its foot is never under it. The card is never taller than the room
   left for it (16px above, the button's room below), and a sheet taller than that never centres itself off the top
   of the screen (29 Sep 2026, the review: the New job sheet's top and Close were 14px above the screen, where no
   scroll could reach them) */
/* THE PAGE'S END IS A FIXED SIZE, NEVER env() (29 Sep 2026, report 29: "Swiping up and letting go causes the page to
   glitch out up and down/jitter into the header"). An iPhone's Safari changes env(safe-area-inset-bottom) between 0 and
   34px as its toolbar folds and unfolds while the page scrolls, and unfolds it at the page's end: an end that followed
   it grew and shrank by 34px under the finger, so a fling that stopped there was thrown back and forth. The room is the
   button's at its highest instead (76px; on a touch screen 94px, the 34 of the home bar the button sits on, its 48 and
   12 over it, 110 before the UX review, 3 Nov 2026), the same while it scrolls. */
html.rp-on .pn-wrap { padding-bottom: 76px; }
@media (pointer: coarse) { html.rp-on .pn-wrap { padding-bottom: 94px; } }
/* A PAGE WITH A SIDE MENU gives that room to its column, not to the page (UI audit, 30 Sep 2026): the side menu is as
   tall as the screen under the header, so the page's own 76px under it made a short page scroll 73px into nothing */
@media (min-width: 980px) {
  html.rp-on .pn-wrap:has(> .pn-sidewrap) { padding-bottom: 0; }
  html.rp-on .pn-sidewrap > :not(.pn-side) { padding-bottom: 76px; }
}
@media (min-width: 980px) and (pointer: coarse) { html.rp-on .pn-sidewrap > :not(.pn-side) { padding-bottom: 94px; } }
/* A GALLERY'S OWN PAGE THE SAME (report 141, 7 Oct 2026, at 1628 wide, of a band at the foot of a gallery's Settings:
   "fix"): its side panel and its white main side run to the page's end, and the room for the button is the main
   side's own, so no strip of the page's ground is left under them both */
@media (min-width: 980px) {
  html.rp-on .pn-wrap:has(> .pn-gpage) { padding-bottom: 0; }
  html.rp-on .pn-gpage .pn-gmain { padding-bottom: 76px; }
}
@media (min-width: 980px) and (pointer: coarse) { html.rp-on .pn-gpage .pn-gmain { padding-bottom: 94px; } }
/* A PAGE THAT FITS HAS NO END TO SCROLL INTO (the UX review, 3 Nov 2026, of the operator's "scrolling when there's no
   elements past the page"): the room above (and the page's own 40px, a gallery's 48) made a short page whose last card
   ended in the window's foot scroll 17 to 93px into nothing. frame.js (S.pageFit) marks the page html.pn-fit while its
   last content ends inside the window and nothing that is pressed sits where the floating button rests; then the page
   has no end padding at all, and a page that runs past the window, or a row's control under the button, keeps the room */
html.pn-fit .pn-wrap, html.pn-fit.rp-on .pn-wrap { padding-bottom: 0; }
@media (min-width: 980px) {
  html.pn-fit.rp-on .pn-sidewrap > :not(.pn-side) { padding-bottom: 0; }
  html.pn-fit .pn-gpage .pn-gmain, html.pn-fit.rp-on .pn-gpage .pn-gmain { padding-bottom: 0; }
}
@media (max-width: 639px) {
  html.rp-on .pn-sheet:not(.pn-rpsheet) { padding-bottom: calc(76px + env(safe-area-inset-bottom)); place-items: safe center; }
  html.rp-on .pn-sheet:not(.pn-rpsheet) > .wa-card { max-height: calc(100dvh - 92px - env(safe-area-inset-bottom)); }
}
/* THE SHEET: the picture with its marks, What's wrong?, the note, a screenshot, Send. Over everything, as the layer is: a
   list or a menu left open for the picture (the floating button keeps them open) never draws over it. IT KEEPS TO WHAT THE BROWSER SHOWS
   (the operator's iPhone, 28 Sep 2026: "make the pop up less taller so it doesnt hide behind the mobile browser
   header"). The card is never taller than the window with the browser's bars showing (100svh), less the notch's and
   the home bar's room, and it sits in the part on show between the bars (report.js followShown, from visualViewport:
   --rp-above and --rp-under, what the bars or the keyboard cover, and --rp-vis, how tall the part on show is). Cancel
   and Send are always at its foot; what is above them scrolls when the window is too short for all of it. */
.pn-sheet.pn-rpsheet { --rp-above: 0px; --rp-under: 0px; --rp-vis: 100vh; z-index: 2147483000; display: flex; flex-direction: column; align-items: center; justify-content: center;
  overflow: hidden; padding: calc(max(12px, env(safe-area-inset-top)) + var(--rp-above)) max(12px, env(safe-area-inset-right))
  calc(max(12px, env(safe-area-inset-bottom)) + var(--rp-under)) max(12px, env(safe-area-inset-left)); }
.pn-sheet > .wa-card.pn-rpcard { display: flex; flex-direction: column; flex: 0 1 auto; max-width: 560px; min-height: 0; max-height: 100%; padding: 0; overflow: hidden; }
@supports (height: 100svh) {
  .pn-sheet.pn-rpsheet { --rp-vis: 100svh; }
  .pn-sheet > .wa-card.pn-rpcard { max-height: min(100%, calc(100svh - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom))); }
}
.pn-rpcard > h2 { flex: none; margin: 18px 20px 10px; }
.pn-rpscroll { flex: 0 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 2px 20px 4px; }
.pn-rpfoot { flex: none; padding: 12px 20px 18px; }
/* CTRL + ENTER SENDS (the operator, 16 Oct 2026: "make ctrl + enter (with little glyph on the send button) for studio and
   website reports on desktop to submit quickly"): the key hint on Send, drawn only where a mouse and a keyboard are */
.pn-rpkey { display: none; }
@media (hover: hover) and (pointer: fine) {
  .pn-rpkey { display: inline-flex; align-items: center; gap: 3px; margin-left: 8px; padding: 1px 5px; border: 1px solid currentColor;
    border-radius: var(--pn-r); font-size: 10.5px; font-weight: 500; letter-spacing: .04em; line-height: 1.3; opacity: .62; }
}
.pn-rppic { display: grid; place-items: center; min-height: 110px; margin: 2px 0 6px; overflow: hidden; border: 1px solid rgba(255,255,255,.14);
  border-radius: var(--pn-r); background: rgba(0,0,0,.25); }
/* the small picture is a button: a press shows the whole of it (.pn-rpwholev) */
.pn-rppicbtn { position: relative; display: block; width: 100%; padding: 0; border: 0; border-radius: var(--pn-r); background: none; color: inherit; cursor: zoom-in; }
/* it says so, in a corner of the picture's frame: nothing else on a phone shows it can be pressed (its aria-label names it) */
.pn-rppicbtn::after { content: "See it all"; position: absolute; right: 6px; bottom: 6px; padding: 3px 8px; border-radius: var(--pn-r); background: rgba(0,0,0,.62);
  color: #f2efe8; font-size: 11px; line-height: 1.3; pointer-events: none; }
.pn-rpimg { display: block; width: auto; max-width: 100%; height: auto; max-height: calc(var(--rp-vis) * .34); margin: 0 auto; }
.pn-sheet p.pn-rppicsay { margin: 0; padding: 18px; font-size: 13px; text-align: center; }
/* the whole picture, over the sheet, in the part on show */
.pn-rpwholev { position: absolute; inset: 0; z-index: 1; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px;
  padding: calc(max(12px, env(safe-area-inset-top)) + var(--rp-above)) max(12px, env(safe-area-inset-right))
  calc(max(12px, env(safe-area-inset-bottom)) + var(--rp-under)) max(12px, env(safe-area-inset-left)); background: #12100e; cursor: zoom-out; }
.pn-rpwholev[hidden] { display: none; }
.pn-rpwholeimg { display: block; flex: 0 1 auto; min-height: 0; max-width: 100%; max-height: 100%; object-fit: contain; border-radius: var(--pn-r); }
.pn-rpwholev .wa-btn { flex: none; }
/* the whole picture is on the dark ground in light as well, so Back to the report wears the dark look's button there */
:root[data-app][data-theme="light"] .pn-rpwholev .wa-btn { background: var(--beige); color: var(--ink); }
@media (hover: hover) { :root[data-app][data-theme="light"] .pn-rpwholev .wa-btn:not(:disabled):hover { background: #efe6d8; } }
/* A PHONE, upright or on its side: the picture a quarter of what shows at most, everything a little closer together */
@media (max-width: 519px), (max-height: 519px) {
  .pn-rpcard > h2 { margin: 14px 16px 8px; font-size: 18px; }
  .pn-rpscroll { padding: 2px 16px 4px; }
  .pn-rpfoot { padding: 10px 16px 14px; }
  .pn-rppic { min-height: 64px; margin: 0 0 2px; }
  .pn-rpimg { max-height: calc(var(--rp-vis) * .25); }
  .pn-sheet p.pn-rppicsay { padding: 12px; }
}
.pn-rpk { display: block; margin: 14px 0 8px; font-size: 11px; letter-spacing: .14em; text-transform: uppercase; color: var(--beige); }
/* WHAT'S WRONG? AS ONE DROPDOWN (the operator, 28 Sep 2026: "make it a dropdown (for the reporting screen) so it takes
   up less space"; report.js pickMany). The app's own dropdown (frame.js: .pn-ddbtn, .pn-ddmenu, .pn-ddopt, its tick),
   any number picked: the button set as the note under it is, and the list on the sheet, placed by report.js inside the
   middle, its choices scrolling in it when the middle is short and Done kept at its foot. A picked row carries the
   tick at its end and is set at 500, so it is not told by one thing alone */
.pn-ddbtn.wa-pwin.pn-rpddbtn { padding: 0 14px; font-size: 15px; }
.pn-ddmenu.pn-rpddmenu { box-sizing: border-box; overflow: hidden; }
.pn-rpddlist { display: flex; flex-direction: column; flex: 0 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
.pn-rpddmenu .pn-ddopt[aria-selected="false"] .pn-ddtick { visibility: hidden; }
.pn-rpdddone { display: flex; flex: none; justify-content: flex-end; margin-top: 6px; padding-top: 6px; border-top: 1px solid rgba(255,255,255,.1); }
/* A FINGER ON AN IPHONE (28 Sep 2026: "Dropdown doesn't click after I select an option"): a tap on the button, a row or
   Done is never taken for half of a double tap, and a long press on a row never picks its words out as text; report.js
   does a finger's tap as it lifts */
.pn-ddbtn.pn-rpddbtn, .pn-rpddmenu, .pn-rpddmenu .pn-ddopt, .pn-rpdddone .wa-btn { touch-action: manipulation; }
.pn-rpddmenu .pn-ddopt { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
/* a middle with nothing to scroll, scrolled up for the list for the while (report.js place): no scroll bar comes, so
   nothing in it narrows on a computer */
.pn-rpscroll.pn-rpddlifted { scrollbar-width: none; }
.pn-rpscroll.pn-rpddlifted::-webkit-scrollbar { display: none; }
/* a touch screen keeps the last row tapped as if hovered, even one just unticked: there the hover shows nothing, and
   the keys' focus ring stays */
@media (hover: none) {
  :root[data-app] .pn-rpddmenu .pn-ddopt:hover:not(:focus-visible) { background: transparent; }
}
.pn-rpnotew { display: block; margin: 0; max-width: none; }
/* two lines to start (report.js rows), taller as it is dragged */
textarea.wa-pwin.pn-rpnote { display: block; height: auto; min-height: 0; padding: 9px 14px; font-size: 15px; line-height: 1.5; resize: vertical; }
.pn-rpshot { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; margin-top: 14px; }
/* A PHONE: the labels and the screenshot row closer, and the list's rows 44 pixels to a finger at any pointer */
@media (max-width: 519px), (max-height: 519px) {
  .pn-rpk { margin: 10px 0 6px; }
  .pn-rpddmenu .pn-ddopt { min-height: 44px; }
  .pn-rpshot { margin-top: 10px; }
}
/* THE KEYBOARD UP ON A PHONE ON ITS SIDE: under 240 pixels on show (report.js followShown, SHORT_BAND) the heading
   goes, still the dialog's name, and the rest closes up, so the note being typed in stays on show over Cancel and Send */
.pn-sheet.pn-rpsheet.pn-rpshort { padding-top: calc(max(4px, env(safe-area-inset-top)) + var(--rp-above)); padding-bottom: calc(max(4px, env(safe-area-inset-bottom)) + var(--rp-under)); }
.pn-rpshort .pn-rpcard > h2 { display: none; }
.pn-rpshort .pn-rpscroll { padding-top: 8px; }
.pn-rpshort .pn-rpfoot { padding: 6px 16px 8px; }
/* Remove is there only once a screenshot is: a hidden button stays hidden, whatever its own look says */
.pn-rpshot [hidden], .pn-rplayer [hidden] { display: none !important; }
.pn-rpshotname { min-width: 0; font-size: 13px; line-height: 1.4; color: rgba(242,239,232,.72); overflow-wrap: anywhere; }
.pn-rpfile { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; border: 0; overflow: hidden; clip-path: inset(50%); opacity: 0; pointer-events: none; }
.pn-sheet p.pn-rpmsg { min-height: 1.4em; margin: 12px 0 0; font-size: 13.5px; }
/* at the sheet's foot, just above Cancel and Send: no room kept until there is something to say */
.pn-sheet .pn-rpfoot p.pn-rpmsg { min-height: 0; margin: 0 0 10px; }
.pn-sheet .pn-rpfoot p.pn-rpmsg:empty { margin: 0; }
.pn-sheet p.pn-rpmsg.pn-rpbad { color: #f0a58f; }
.pn-sheet p.pn-rpsent { margin: 4px 0 8px; font-size: 17px; color: inherit; }
.pn-rplink { display: inline-flex; align-items: center; min-height: 32px; color: var(--beige); font-size: 14px; text-decoration: underline; text-underline-offset: 3px; }
@media (hover: hover) {
  .pn-rpx:hover { background: #ff2f92; }
}
@media (pointer: coarse) {
  .pn-rpx { top: -22px; right: -22px; width: 44px; height: 44px; }
  .pn-rpx.pn-rpxin { right: 2px; }
  .pn-rpx.pn-rpxdown { top: 2px; }
  textarea.wa-pwin.pn-rpnote { font-size: 16px; }
  .pn-rplink { min-height: 44px; }
}
:root[data-app][data-theme="light"] .pn-rpbar { border-color: var(--pn-line); background: var(--pn-face); color: var(--pn-ink); box-shadow: none; }
:root[data-app][data-theme="light"] .pn-rpbar .wa-btn { background: var(--pn-ink); color: #f7f3ec; }
:root[data-app][data-theme="light"] .pn-rpbar .wa-gl { background: var(--pn-fill); color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-rppic { border-color: var(--pn-line); background: var(--pn-fill); }
:root[data-app][data-theme="light"] .pn-rpdddone { border-top-color: var(--pn-line); }
:root[data-app][data-theme="light"] .pn-rpshotname { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-sheet p.pn-rpmsg.pn-rpbad { color: var(--st-bad); }
:root[data-app][data-theme="light"] .pn-sheet p.pn-rpsent { color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-rplink { color: var(--pn-ink); }
@media (hover: hover) {
  :root[data-app][data-theme="light"] .pn-rpbar .wa-gl:not(:disabled):hover { background: var(--pn-fill-hover); }
}
/* THE PROBLEM REPORTS PAGE (/reports): a card a report, the open ones first; the picture cropped round its marks
   (a press shows the whole), then what the page and the device were, the chips, the note, and Mark fixed */
.pn-rplist { display: grid; gap: 14px; max-width: none; margin-top: 14px; }
.pn-card.pn-rpitem { display: grid; gap: 12px 18px; margin: 0; }
.pn-rpitemh { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.pn-card .pn-rpitemh h2 { margin: 0; }
.pn-badge.pn-rpfixed { background: var(--st-good-bg); color: var(--st-good); border-color: var(--st-good-line); }
.pn-rpcrop { position: relative; display: block; width: 100%; margin: 0; padding: 0; overflow: hidden; border: 1px solid rgba(255,255,255,.14); border-radius: var(--pn-r);
  background: rgba(0,0,0,.25); cursor: zoom-in; aspect-ratio: 4 / 3; }
.pn-rpcrop img { position: absolute; display: block; max-width: none; }
.pn-rpcropnone { display: grid; place-items: center; min-height: 90px; padding: 18px; border: 1px dashed rgba(255,255,255,.2); border-radius: var(--pn-r);
  font-size: 13px; color: rgba(242,239,232,.66); text-align: center; }
.pn-rpbody { display: grid; gap: 10px; min-width: 0; }
.pn-rpbody .pn-list li { padding: 8px 2px; }
.pn-rpbody .pn-list li > .pn-t:first-child { min-width: 5.5em; }
.pn-rpchipline { display: flex; flex-wrap: wrap; gap: 6px; margin: 0; }
.pn-rpnoteline { margin: 0; font-size: 14px; line-height: 1.5; white-space: pre-wrap; overflow-wrap: anywhere; }
.pn-rpfixline { margin: 0; font-size: 13px; line-height: 1.5; color: rgba(242,239,232,.72); overflow-wrap: anywhere; }
.pn-rpacts { display: flex; flex-wrap: wrap; gap: 8px; }
/* the whole picture keeps to what the browser shows between its own bars, as the reporter's sheet does: the card no
   taller than the window with the bars showing, in the part on show (app.js reportWhole, from visualViewport), the
   picture shrinking to fit and Close always under it */
.pn-sheet.pn-rpwholesheet { --rp-above: 0px; --rp-under: 0px; display: flex; flex-direction: column; align-items: center; justify-content: center; overflow: hidden;
  padding: calc(max(12px, env(safe-area-inset-top)) + var(--rp-above)) max(12px, env(safe-area-inset-right))
  calc(max(12px, env(safe-area-inset-bottom)) + var(--rp-under)) max(12px, env(safe-area-inset-left)); }
.pn-sheet > .wa-card.pn-rpwholecard { display: flex; flex-direction: column; flex: 0 1 auto; min-height: 0; max-width: 1100px; max-height: 100%; overflow: hidden; }
@supports (height: 100svh) {
  .pn-sheet > .wa-card.pn-rpwholecard { max-height: min(100%, calc(100svh - 24px - env(safe-area-inset-top) - env(safe-area-inset-bottom))); }
}
.pn-rpwholecard > h2, .pn-rpwholecard > .pn-row { flex: none; }
.pn-rpwhole { display: block; flex: 0 1 auto; width: 100%; height: auto; min-height: 0; object-fit: contain; border-radius: var(--pn-r); }
@media (max-width: 519px), (max-height: 519px) {
  .pn-sheet > .wa-card.pn-rpwholecard { padding: 14px 16px; }
  .pn-rpwholecard > h2 { font-size: 18px; margin-bottom: 8px; }
  .pn-rpwholecard > .pn-row.pn-mt14 { margin-top: 10px; }
}
@media (min-width: 760px) {
  .pn-card.pn-rpitem { grid-template-columns: minmax(0, 300px) minmax(0, 1fr); align-items: start; }
  .pn-rpitemh { grid-column: 1 / -1; }
}
:root[data-app][data-theme="light"] .pn-rpcrop { border-color: var(--pn-line); background: var(--pn-fill); }
:root[data-app][data-theme="light"] .pn-rpcropnone { border-color: var(--pn-line); color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-rpfixline { color: var(--pn-ink-soft); }
:root[data-app][data-theme="light"] .pn-badge.pn-rpfixed { background: var(--st-good-bg); color: var(--st-good); border-color: var(--st-good-line); }
/* ADD, EDIT AND REMOVE (report 93): Add a report at the top of the list; a report added by hand shows its picture
   whole, never cropped (it has no marks), no taller than the cropped ones; the note's box on the two sheets */
.pn-row.pn-rplisthead { margin-top: 12px; }
.pn-rpcrop.pn-rpshotbox { display: grid; place-items: center; aspect-ratio: auto; max-height: 340px; }
.pn-rpcrop.pn-rpshotbox img { position: static; width: 100%; height: auto; max-width: 100%; max-height: 338px; object-fit: contain; }
.pn-rpnotein { min-height: 110px; resize: vertical; }
.pn-rpup { display: flex; align-items: center; gap: 8px; min-width: 0; }

/* SETTINGS, BUSINESS DETAILS (28 Sep 2026: the business's details kept once, lib/business.js; assets/app.js
   businessCard): each field its name, its box and a line of where it is used, in two small groups under the place's
   heading. A little wider than a plain form, for the profile addresses; the postal address a box of four lines. */
.pn-bizform { max-width: 520px; gap: 14px; margin-top: 18px; }
.pn-bizform .pn-bizh { margin: 6px 0 -4px; }
.pn-bizform .pn-bizf + .pn-bizh { margin-top: 14px; }
.pn-bizf { display: grid; gap: 6px; min-width: 0; }
.pn-bizf > label { font-size: 12px; line-height: 1.5; color: rgba(242,239,232,.56); }
.pn-bizf > .pn-note { margin: 0; }
textarea.wa-pwin.pn-bizaddr { min-height: 104px; }
:root[data-app][data-theme="light"] .pn-bizf > label { color: var(--pn-ink-soft); }
/* the profiles' names each with its glyph before it (report 126: "put glyphs"), in the name's own colour */
.pn-bizf > label.pn-bizlab { display: flex; align-items: center; gap: 7px; }
.pn-bizlab > .pn-gl { width: 16px; height: 16px; flex: none; }
/* A refused field's words (fieldError) and its box come into view BELOW the sticky header, never under it: the place
   is a page, not a sheet, so scrollIntoView would put them at the very top, behind the bar (145px on a phone at most,
   since report 101 gave the logo's row more room). The margin leaves room for the field's name above the words too. */
.pn-bizform :is(.pn-fieldmsg, .wa-pwin) { scroll-margin-top: 190px; }
@media (min-width: 980px) { .pn-bizform :is(.pn-fieldmsg, .wa-pwin) { scroll-margin-top: calc(var(--pn-barh) + 44px); } }
/* Website settings' Business group: the one line saying the details are in Settings, Business details */
.pn-wsbiz { margin: 0 0 10px; }

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   ONE FILTER, ONE RULE (2 Oct 2026, report 79, the Jobs list at 520px: "fix all drop down style in studio to match this
   one. ie. one under clients and photographers look mismatched and smaller than this one"; before it, ONE FILTER, 1 Oct
   2026, the overnight audit's X-FILTERS: "filter rows and pick-one chips come in four looks"). A filter that narrows a
   list is the dropdown (.pn-glfilter in a .pn-glfilters row: Jobs, Leads, Clients, Photographers, Collections,
   Invoices, Quotes, the website's visits, and the changelog's Part), and THIS is the one rule for its size and look:
   no list's own block sets a filter dropdown's height, padding, words or corners any more, so no two lists can drift
   apart again. The Jobs list's filters are the model, as they were measured on 2 Oct 2026: the box's white face and
   1px edge, 8px corners, the words at the left at 12.5px and the 12 by 8 chevron at the right edge (frame.js), 44px tall
   on a phone's width or any touch screen, 40px in a window narrower than a computer's, 32px on a computer with a
   mouse; to a thumb the words are 16px and 15px in. Clients, Photographers, Invoices and Quotes had kept 32px at every
   width, beside a Sort icon and date boxes of 40px. Every other part of a filter row (its date and search boxes, its
   buttons, its Sort and View icons) is the same height as its dropdowns at every width, as Jobs and Collections already
   were. Written last and with the lists' own containers, so it outranks each list's older size. A row of choices where
   one is picked (Waiting or Everything, a kind of change, a booking's Show, a period) is the pills of THE STUDIO'S
   ORDER, level 3. A dropdown in a form or a sheet is the boxes' own size (ONE SIZE FOR A BOX: 40px, 44px to a thumb,
   14px words, 16px on a phone), the height, padding and words of the boxes it sits among, with the same face and
   chevron as a filter's.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
:root[data-app] :is(.pn-glfilters, .pn-chgfind, .pn-jbfilters, .pn-glhead, .pn-colbar) .pn-glfilter .pn-ddbtn.wa-pwin { height: var(--pn-h-main); min-height: var(--pn-h-main); padding: 0 12px;
  border-radius: var(--pn-r); font-size: 14px; font-weight: 400; }
:root[data-app] :is(.pn-glfilters, .pn-chgfind) .pn-glfilter .wa-pwin:not(textarea):not(.pn-ddbtn), :root[data-app] .pn-glfilters > .wa-gl,
  :root[data-app] .pn-chgfind .pn-chgq:not(textarea), :root[data-app] .pn-glfilters > .pn-glsearch:not(textarea) { height: var(--pn-h-main); min-height: var(--pn-h-main); }
:root[data-app] .pn-glfilters:not(.pn-jbrow, .pn-colfilters) .pn-glicons > .pn-glicon { width: var(--pn-h-main); height: var(--pn-h-main); min-height: var(--pn-h-main); padding: 0; }

/* every page's width (report 92, 2 Oct 2026) */
/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   EVERY PAGE AS WIDE AS THE WINDOW, AND THE SAME (report 92, 2 Oct 2026, from People: "these cards extend to the full
   page where as other menu items are capped width", then "check all pages so they extend to width of page and check
   pages consistency"). No page is capped any more: .pn-wrap, a Settings place (.pn-setone), Account, the Changelog,
   Problem reports and Pricing fill the width beside the side menu, or the window's where there is none, as People's
   always did. On a computer the page's outer gutter is 24px at both sides (--pn-gut), the header's own, so the logo
   starts where a side menu's words do and the header's glyphs end where every page's content ends; beside a side menu
   the content starts 32px in, on every page and on a gallery's. The desk keeps its own column.
   WHAT FILLING THE WIDTH NEVER DOES: a running paragraph in a card stops at about 75 characters, and a single text box
   in a Settings place or Account at a form's width (480px; a box of several lines at 760), so a form or a line of
   words is never as wide as the window. A rule of its own (a centred note, a box with its own size) still wins: these
   are written with :where(), weightless. A place of several cards (Payments, Google Calendar, Xero) has them two to a
   row from 1360px, each column filled top down; Pricing lays out its own tiles and parts, its width whole (21 Oct
   2026: no half-width column cuts its sheets off); Settings' cards are four to a row from 1500px.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
:where(.pn-wrap:not(.dk)) :where(.pn-note, .pn-sub, .wa-card > p, .pn-card > p, .wa-card > div > p, .wa-card > form > p) { max-width: 75ch; }
:where(.pn-setone, .pn-acct) :where(input.wa-pwin, select.wa-pwin, div.wa-pwin, .pn-ddbtn.wa-pwin) { max-width: 480px; }
:where(.pn-setone:not(.pn-setwide)) :where(textarea.wa-pwin) { max-width: 760px; }
@media (min-width: 1360px) {
  .pn-setone > :is(#mn-set, #cn-set):has(> .wa-card + .wa-card) { columns: 2; column-gap: 14px; }
  .pn-setone > :is(#mn-set, #cn-set):has(> .wa-card + .wa-card) > .wa-card { break-inside: avoid; -webkit-column-break-inside: avoid; display: inline-block;
    width: 100%; margin: 0 0 14px; vertical-align: top; }
}
@media (min-width: 1500px) { .pn-setgrid { grid-template-columns: repeat(4, minmax(0, 1fr)); } }

/* a help line under a box (report 87, 2 Oct 2026) */
/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   A HELP LINE UNDER A BOX (report 87, 2 Oct 2026, Products' Add a section: "increase spacing from the textbox to the
   text below it line spacing is too tight"). The line that says what a box is for (.pn-note right after the box, or
   after the label or field the box ends) sits 8px under the box in every sheet and form of the Studio, at the help
   line's own 12px with an easy 1.55 line height. In a sheet it sat on the box (the sheet's own paragraph rule, 14px with
   no room above, outranked it), and elsewhere it was 6, 10, 14 or 20px down. Where the box and the line share a grid
   whose own gap gives some of the room (a field of 6px, a form of 10px) the line's margin is the rest, so the room is 8px
   wherever it is. Measured in Chromium on every Settings place, a job's, quote's and invoice's page, and the sheets.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
:root[data-app] :is(label, .pn-form, .cn-field, .mn-field, .pr-rowin, input, textarea, select, .wa-pwin) + .pn-note { margin-top: 8px; font-size: 12px; line-height: 1.55; }
:root[data-app] :is(.pn-bizf, .pr-row, label.pn-form, .pn-form label) > :is(label, input, textarea, select, .wa-pwin, .pr-rowin) + .pn-note { margin-top: 2px; }
:root[data-app] :not(label).pn-form > :is(label, .cn-field, .mn-field, input, textarea, select, .wa-pwin) + .pn-note { margin-top: -2px; }
/* Booking terms' box sits in a label that is a block, so the box was a line's inline box with room under it: a block
   itself, the line under it is 8px down as every other */
:root[data-app] .mn-termsfield > textarea { display: block; }

/* the inbox (10 Oct 2026) */
/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   THE INBOX (the operator, 10 Oct 2026: "this should be a separate inbox tab at the header", "then use design 3 to
   replicate closest to gmail", "use inbox and sent boxes"; assets/inbox.js). Laid out as Gmail lays out its own, in the
   Studio's look, light and dark: a column of boxes on the left (Inbox with its count, Sent), and beside it the toolbar
   (Check for new mail, the search, "1 to 50 of N", Newer and Older), the filters, then the list and the reading pane
   side by side from 1100px. Below 1100 a thread takes the list's place with a way back, and below 760 the boxes are a
   row over the list and a thread is the whole screen, as the Gmail app does. Every class here is .ib-; an email's own
   words are text, kept whole with their line breaks, and never wider than their card.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.ib { --ib-line: rgba(255,255,255,.1); --ib-fill: rgba(255,255,255,.05); --ib-sel: rgba(244,255,106,.08); --ib-face: rgba(255,255,255,.03);
  --ib-soft: rgba(242,239,232,.66); --ib-mark: var(--moon); --ib-unread: rgba(255,255,255,.075); --ib-read: transparent;
  display: grid; gap: 16px; margin-top: 6px; min-width: 0; }
:root[data-app][data-theme="dark"] .ib { --ib-face: var(--pn-face); --ib-line: var(--pn-line); --ib-sel: var(--pn-soft); }
:root[data-app][data-theme="light"] .ib { --ib-line: var(--pn-line); --ib-fill: var(--pn-hover); --ib-sel: var(--pn-soft); --ib-face: var(--pn-face);
  --ib-soft: var(--pn-ink-soft); --ib-mark: var(--pn-olive); --ib-unread: #fff; --ib-read: rgba(36,31,25,.035); }
/* THE REPLY'S OWN TOKENS WHERE NO INBOX IS ROUND IT (report 175, 12 Oct 2026: "make the reply in-box rather than going to
   the inbox page."): the desk's email sheet holds the app's one composer (assets/compose.js), so the place it sits in
   carries the Inbox's tokens, the same in light and dark */
.ib-cmphost { --ib-line: rgba(255,255,255,.1); --ib-fill: rgba(255,255,255,.05); --ib-sel: rgba(244,255,106,.08); --ib-face: rgba(255,255,255,.03);
  --ib-soft: rgba(242,239,232,.66); --ib-mark: var(--moon); --ib-unread: rgba(255,255,255,.075); --ib-read: transparent; min-width: 0; }
:root[data-app][data-theme="dark"] .ib-cmphost { --ib-face: var(--pn-face); --ib-line: var(--pn-line); --ib-sel: var(--pn-soft); }
:root[data-app][data-theme="light"] .ib-cmphost { --ib-line: var(--pn-line); --ib-fill: var(--pn-hover); --ib-sel: var(--pn-soft); --ib-face: var(--pn-face);
  --ib-soft: var(--pn-ink-soft); --ib-mark: var(--pn-olive); --ib-unread: #fff; --ib-read: rgba(36,31,25,.035); }
/* the title over the list and the boxes down the side, as Jobs' page has them (11 Oct 2026: "I need the side menu the
   same style as well") */
@media (min-width: 760px) {
  .ib { grid-template-columns: 196px minmax(0, 1fr); grid-template-areas: "side head" "side main"; align-items: start; }
  .ib-h { grid-area: head; }
  .ib-side { grid-area: side; }
  .ib-main, .ib-emmain { grid-area: main; }
}
/* STUDIO EMAILS, THE INBOX'S FOURTH BOX (report 173, 12 Oct 2026: "this should be under the inbox, under studio or
   something"; assets/emails.js): the page in the Inbox's own frame, its title and period over the main column, the boxes
   down the side, and its figures, filters and list in the main column with no card round them (they have their own) */
.ib-emmain { min-width: 0; }
/* the boxes: the Studio's side menu items (.pn-sideitem), their look, their selected fill and their red counts */
.ib-side { display: grid; gap: 4px; align-content: start; min-width: 0; }
@media (min-width: 760px) { .ib-side { position: sticky; top: calc(var(--pn-bar-sp, 0px) + 16px); } }
.ib-h { margin: 0; }
.ib-boxes { display: grid; gap: 2px; }
.ib-box .pn-count[hidden] { display: none; }
.ib-conn[hidden] { display: none; }
.ib-conn { display: grid; grid-template-columns: 8px minmax(0, 1fr); align-items: start; gap: 8px; margin: 10px 14px 0; font-size: 12px; line-height: 1.45; color: var(--ib-soft); }
.ib-dot { width: 8px; height: 8px; margin-top: 5px; border-radius: 50%; background: var(--st-warn); }
.ib-connw { min-width: 0; overflow-wrap: anywhere; }
.ib-conn.ib-on .ib-dot { background: var(--st-good); }
.ib-connlink { color: inherit; text-underline-offset: 3px; padding-block: 12px; margin-block: -12px; }
/* THE INBOX AS WIDE AS JOBS AND GALLERIES (the operator, 11 Oct 2026, of the Inbox in a column in the middle: "for the
   email screen make it full width like the jobs and gallery page et"): from 980px the boxes are the side menu, the
   window's height down the left with Jobs' face and edge, and the list and the email run the rest of the window */
@media (min-width: 980px) {
  .pn-wrap:has(> .ib) { max-width: none; padding: 0; }
  .ib { grid-template-columns: 240px minmax(0, 1fr); gap: 0; margin-top: 0; }
  .ib-side { top: var(--pn-barh); height: calc(100vh - var(--pn-barh)); padding: 16px 10px; overflow-y: auto;
    background: var(--pn-face, rgba(255,255,255,.03)); border-right: 1px solid var(--pn-line, rgba(255,255,255,.09)); }
  /* less room over the title (28 Oct 2026: "decrease top margin above the Inbox label") */
  .ib-h { margin: 24px var(--pn-gut) 0 32px; }
  /* under the card on a computer the same 18px as between the title and the card (28 Oct 2026: "decrease spacing on
     desktop", then "decrease the gap more bottom so its even to the top gap after the inbox text"); the title stays where
     Jobs' is */
  .ib-main { margin: 18px var(--pn-gut) 18px 32px; }
  /* the report button's room under the card, as under Jobs' page, never a strip under the side menu */
  html.rp-on .pn-wrap:has(> .ib) { padding-bottom: 0; }
  html.rp-on .ib-main { margin-bottom: 18px; }
  .ib-emmain { margin: 18px var(--pn-gut) 18px 32px; }
  html.rp-on .ib-emmain { margin-bottom: 18px; }
}
@media (min-width: 980px) and (pointer: coarse) { html.rp-on .ib-main, html.rp-on .ib-emmain { margin-bottom: 18px; } }
.ib-boxbtn { display: none; }
@media (max-width: 759px) {
  .ib-side { grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 8px 12px; }
  /* THE BOXES AS ONE DROPDOWN (28 Oct 2026: "Group these into one dropdown and have a down chevron right side inside the
     pill, dropdown to be styled"): the pill says the open box, its chevron at its right turning as it opens; the boxes
     are its list under it, in the app's dropdown look (.pn-ddmenu's face, edge and shadow, .pn-ddopt's rows) */
  .ib-boxdrop { position: relative; justify-self: start; min-width: 0; }
  /* the card closer under the pill: 8px, half the page's 16 (28 Oct 2026, of the gap between them: "Decrease this gap") */
  .ib-side + .ib-main, .ib-side + .ib-emmain { margin-top: -8px; }
  .ib-boxbtn { display: inline-flex; align-items: center; gap: 10px; min-height: 44px; margin: 0; padding: 0 16px 0 14px;
    border: 1px solid var(--ib-line); border-radius: var(--pn-r); background: var(--ib-face); color: inherit; font: inherit; font-size: 15px;
    font-weight: 600; letter-spacing: 0; text-transform: none; cursor: pointer; }
  .ib-boxnow { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
  .ib-boxnow .pn-gl { width: 20px; height: 20px; flex: none; }
  .ib-boxbtn > .pn-caret { width: 12px; height: 8px; flex: none; margin-left: 4px; opacity: .7; transition: transform .16s ease; }
  .ib-boxbtn[aria-expanded="true"] > .pn-caret { transform: rotate(180deg); }
  .ib-boxdrop .ib-boxes { position: absolute; top: calc(100% + 6px); left: 0; z-index: 30; display: none; flex-direction: column; gap: 2px;
    min-width: 240px; padding: 6px; border: 1px solid var(--ib-line); border-radius: var(--pn-r); background: var(--pn-face-2, var(--ib-face));
    box-shadow: none; }
  :root[data-app][data-theme="light"] .ib-boxdrop .ib-boxes { background: var(--pn-face); box-shadow: none; }
  .ib-boxdrop.ib-boxopen .ib-boxes { display: flex; animation: pn-ddin .14s ease-out; }
  .ib-boxdrop .ib-box { gap: 10px; min-height: 44px; padding: 0 12px; border: 0; border-radius: var(--pn-r); }
  @media (prefers-reduced-motion: reduce) { .ib-boxbtn > .pn-caret { transition: none; } .ib-boxdrop.ib-boxopen .ib-boxes { animation: none; } }
  .ib-conn { grid-column: 1 / -1; margin: 0; }
  .ib-open .ib-side, .ib-open .ib-h { display: none; }
}
/* the toolbar, the filters, the list and the pane, on one card */
.ib-main { min-width: 0; border: 1px solid var(--ib-line); border-radius: var(--pn-r); background: var(--ib-face); }
.ib-tools { display: flex; align-items: center; gap: 4px; padding: 8px 10px; border-bottom: 1px solid var(--ib-line); }
:root[data-app] .ib-tool { flex: none; width: var(--pn-h-act); height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0; }
:root[data-app] .ib-tool[hidden] { display: none; }
.ib-searchbox { flex: 1 1 auto; display: flex; align-items: center; gap: 8px; min-width: 0; min-height: var(--pn-h-act); margin: 0 6px; padding: 0 10px;
  border-radius: var(--pn-r); background: var(--ib-fill); cursor: text; }
.ib-searchbox .pn-gl { flex: none; width: 14px; height: 14px; opacity: .7; }
.ib-searchbox:focus-within { box-shadow: inset 0 0 0 2px var(--ib-mark); }
.ib-search { flex: 1 1 auto; align-self: stretch; min-width: 0; height: auto; padding: 0; border: 0; background: transparent; color: inherit; font: inherit; font-size: 14px;
  outline: none; }
.ib-range { flex: none; padding: 0 6px; font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--ib-soft); }
.ib-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--ib-line); }
.ib-chip[hidden] { display: none; }
/* the filters but All as squares of their glyphs, as tall as All (28 Oct 2026: "make it glyphs instead, square") */
:root[data-app] .ib-chip.ib-chipgl { width: var(--pn-h-act); min-width: var(--pn-h-act); padding: 0; border-radius: var(--pn-r); }
.ib-chipgl .pn-gl { width: 14px; height: 14px; }
.ib-snipline { margin-top: 1px; }
.ib-rowlink:focus-visible, .ib-mtop:focus-visible { outline-offset: -2px; }
/* a hairline between the channels and Unread and Not linked (Problem report 249, 28 Oct 2026: "Put a divider instead of a
   plain gap") */
.ib-gap { flex: 0 0 1px; align-self: stretch; margin: 6px 4px; background: var(--ib-line); }
.ib-searchbtn, .ib-searchx { display: none; }
/* THE SEARCH FOLDED ON A PHONE (28 Oct 2026: "Put it as a search glyph next right to the refresh button, then it folding
   out upon click with a smooth animation, hiding the page number and buttons"): one row, Check for new mail, the search
   glyph, the page's range and Newer and Older; the glyph pressed, the box grows across the row from beside it and the
   range and the two arrows fold away as it does, a cross at its end to fold it back. Nothing folded can take the focus. */
@media (max-width: 759px) {
  .ib-tools { flex-wrap: nowrap; overflow: hidden; }
  .ib-searchbtn { display: inline-flex; }
  .ib-range { margin-left: auto; }
  .ib-searchbox { flex: 0 1 auto; max-width: 0; margin: 0; padding: 0; opacity: 0; overflow: hidden; visibility: hidden;
    transition: max-width .3s ease, padding .3s ease, margin .3s ease, opacity .2s ease, visibility 0s linear .3s; }
  .ib-tools :is(.ib-range, .ib-tool[data-ibgo="prev"], .ib-tool[data-ibgo="next"]) { max-width: 160px; overflow: hidden;
    transition: max-width .3s ease, width .3s ease, padding .3s ease, opacity .2s ease, visibility 0s; }
  .ib-tools.ib-sopen .ib-searchbtn { display: none; }
  .ib-tools.ib-sopen .ib-searchbox { flex: 1 1 auto; max-width: 100%; margin: 0 2px 0 4px; padding: 0 14px; opacity: 1; visibility: visible;
    transition: max-width .3s ease, padding .3s ease, margin .3s ease, opacity .25s ease .05s, visibility 0s; }
  .ib-tools.ib-sopen :is(.ib-range, .ib-tool[data-ibgo="prev"], .ib-tool[data-ibgo="next"]) { max-width: 0; width: 0; min-width: 0; padding: 0; margin: 0;
    border-width: 0; opacity: 0; visibility: hidden; transition: max-width .3s ease, width .3s ease, padding .3s ease, opacity .15s ease, visibility 0s linear .3s; }
  .ib-tools.ib-sopen .ib-searchx { display: inline-flex; }
}
@media (max-width: 759px) and (prefers-reduced-motion: reduce) {
  .ib-searchbox, .ib-tools :is(.ib-range, .ib-tool[data-ibgo="prev"], .ib-tool[data-ibgo="next"]) { transition: none; }
}
.ib-body { display: grid; min-width: 0; }
.ib-listwrap { min-width: 0; }
.ib-split { display: none; }
@media (min-width: 1100px) {
  /* the list's width dragged (Problem report 191, 16 Oct 2026: assets/inbox.js splitter) once set, else 320 to 400px */
  .ib-body { grid-template-columns: minmax(320px, 400px) minmax(0, 1fr); align-items: start; }
  /* a width kept from a wider window never leaves the email under 380px in a narrower one */
  .ib-body.ib-sized { grid-template-columns: min(var(--ib-list-w), max(280px, calc(100% - 380px))) minmax(0, 1fr); }
  /* THE INBOX FITS THE WINDOW, ONLY ITS CONTENT SCROLLS (the operator, 18 Oct 2026, Problem report 222: "why does scrolling in the
     opened email scroll the entire page (the email list on the left)", then 20 Oct, report 225: "this should be dynamic so the inbox
     frames re-adjusts and only the content scrolls"): the page is the window under the bar and never scrolls; its card fills what
     the title leaves, the toolbar and the filters stay, and the list and the email each scroll inside their own column, neither
     handing its scroll on, and both follow the window's height as it changes */
  .ib:has(> .ib-main) { height: calc(100vh - var(--pn-bar-sp, 0px)); height: calc(100dvh - var(--pn-bar-sp, 0px)); grid-template-rows: auto minmax(0, 1fr); align-items: stretch; overflow: hidden; }
  .ib:has(> .ib-main) > .ib-side { height: auto; align-self: stretch; }
  .wa-pg:has(> .pn-wrap > .ib > .ib-main) { min-height: 0; }
  /* the same 18px under the card as over it (28 Oct 2026: "decrease the gap more bottom so its even to the top gap") */
  .ib-main { display: flex; flex-direction: column; min-height: 0; overflow: hidden; margin-bottom: 18px; }
  html.rp-on .ib-main { margin-bottom: 18px; }
  .ib-main > .ib-body { flex: 1 1 auto; min-height: 0; align-items: stretch; }
  .ib-listwrap { border-right: 1px solid var(--ib-line); align-self: stretch; position: relative; min-height: 0; display: flex; flex-direction: column; }
  .ib-listwrap > .ib-list { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; }
  /* the handle: 12px over the line, its whole height, the line darkening under a mouse, a drag or the keyboard's focus */
  .ib-split { display: block; position: absolute; top: 0; bottom: 0; right: -7px; width: 12px; z-index: 2; cursor: col-resize; touch-action: none; outline: none; }
  .ib-split::after { content: ""; position: absolute; top: 0; bottom: 0; left: 5px; width: 2px; background: transparent; transition: background-color .15s ease; }
  .ib-split:hover::after, .ib-split.ib-split-on::after { background: var(--ib-line); }
  .ib-split:focus-visible::after { background: currentColor; }
  html.ib-sizing, html.ib-sizing * { cursor: col-resize !important; user-select: none !important; }
  .ib-pane { align-self: stretch; min-height: 0; overflow: auto; overscroll-behavior: contain; }
}
@media (max-width: 1099px) {
  .ib:not(.ib-open) .ib-pane { display: none; }
  .ib-open .ib-listwrap, .ib-open .ib-tools, .ib-open .ib-filters { display: none; }
}
@media (max-width: 759px) { .ib-open .ib-main { border: 0; background: transparent; } .ib-open .ib-pane { padding: 0; } }
.ib-said:empty { display: none; }
.ib-listwrap > .ib-said { margin: 10px 14px 0; }
/* a row, as Gmail's: who and when, the subject then its grey snippet, the chips; unread in bold */
.ib-list { list-style: none; margin: 0; padding: 0; }
.ib-row { position: relative; border-bottom: 1px solid var(--ib-line); }
.ib-rowlink { display: grid; grid-template-columns: 36px minmax(0, 1fr); gap: 12px; align-items: start; min-height: 44px; padding: 11px 14px;
  color: inherit; text-decoration: none; -webkit-touch-callout: none; }
@media (hover: hover) { .ib-rowlink:hover, .ib-row .ib-rowlink:hover { background: var(--ib-fill); } }
/* the open email's bar down its left in the studio's yellow, in either theme (28 Oct 2026: "make this left selection tab colour yellow") */
.ib-row.ib-on .ib-rowlink { background: var(--ib-sel); box-shadow: inset 3px 0 0 var(--moon); }
.ib-av { display: inline-grid; place-items: center; width: 36px; height: 36px; border: 1px solid var(--ib-line); border-radius: 50%;
  background: var(--ib-avbg, var(--ib-fill)); font-size: 14px; font-weight: 600; line-height: 1; }
.ib-av.ib-avimg { overflow: hidden; padding: 0; }
.ib-avgl .pn-gl { width: 18px; height: 18px; opacity: .75; }
.ib-avimg img { display: block; width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
.ib-av-us { background: var(--pn-p-on); color: var(--pn-p-onink); border-color: transparent; }
/* SMP STUDIO'S OWN PICTURE (report 178, 12 Oct 2026: "This should be named SMP Studio, with the logo as the image/sender"):
   the logo's mark, its colours as they are, on the header's own dark in both themes, as the logo always sits on dark */
.ib-av.ib-av-studio { background: #241f19; color: #fff; border-color: rgba(255,255,255,.14); }
.ib-av-studio .ib-avlogo { display: block; width: 26px; height: 26px; }
.ib-rowmain { display: grid; gap: 2px; min-width: 0; }
.ib-rowtop { display: flex; align-items: baseline; gap: 8px; min-width: 0; }
.ib-who { flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.ib-n { flex: none; font-size: 12px; color: var(--ib-soft); }
.ib-when { flex: none; margin-left: auto; padding-left: 4px; font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--ib-soft); }
.ib-rowline { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; line-height: 1.45; }
.ib-subj { font-weight: 500; }
.ib-snip { color: var(--ib-soft); }
/* UNREAD AT A GLANCE (28 Oct 2026, the operator, of the list on his iPhone: "It's hard to tell what's unread or not"):
   a read row's name and subject are regular weight, and an unread one's are bold, with a dot in the Inbox's own mark
   colour before the name and its date in that colour. The unread row is the brighter one, as Gmail draws it, lit OUT of
   the list, never shaded into it (the same day: "It looks like the row is de-pressed? Make it out"): white in light,
   a lighter grey in dark, with read rows a shade quieter in light */
.ib-row:not(.ib-unread) .ib-who, .ib-row:not(.ib-unread) .ib-subj { font-weight: 400; }
.ib-unread .ib-who, .ib-unread .ib-subj { font-weight: 700; }
.ib-unread .ib-when { font-weight: 700; color: var(--ib-mark); }
.ib-unread .ib-rowlink { background: var(--ib-unread); }
.ib-row:not(.ib-unread):not(.ib-on) .ib-rowlink { background: var(--ib-read); }
/* THE DOT ON THE RIGHT (the same day: "Make the dot yellow and on the right side under the date, right pin with same
   margin"): the moon's yellow in both themes, a hairline round it in light so it shows on white, at the end of the
   subject's line, its right edge on the date's, the line's words stopping short of it */
.ib-unread .ib-rowtop + .ib-rowline { position: relative; padding-right: 19px; }
.ib-unread .ib-rowtop + .ib-rowline::after { content: ""; position: absolute; right: 1px; top: 50%; width: 10px; height: 10px; margin-top: -5px; box-sizing: border-box;
  border-radius: 50%; background: var(--moon); }
/* its hairline is a border, inside its own box, never a shadow the line's overflow cuts off (the same day: "Clipped");
   on the white rows it is the ink at 1.5px, so the yellow dot still reads (2 Nov 2026, the operator: go A) */
:root[data-app][data-theme="light"] .ib-unread .ib-rowtop + .ib-rowline::after { border: 1.5px solid var(--pn-ink); }
.ib-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: 5px; min-width: 0; }
.ib-chips .pn-gl { width: 16px; height: 16px; opacity: .7; }
.ib-mailchip { background: var(--ib-fill); color: inherit; border-color: var(--ib-line); }
:root[data-app][data-theme="light"] .pn-badge.ib-mailchip { background: var(--pn-fill); color: var(--pn-ink); border-color: var(--pn-line); }
.ib-linkname { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; color: var(--ib-soft); }
.ib-none { padding: 22px 14px; list-style: none; }
.ib-live { padding-bottom: 6px; }
/* THE LIST ENDS AT ITS LAST ROW (28 Oct 2026, of a thin band under the last email at the card's foot: "Fix the end cut off
   what is that"): no line under the last row, and no room under it while the Gmail search below holds nothing */
.ib-live:empty { padding: 0; }
.ib-list > .ib-row:last-child { border-bottom: 0; }
@media (max-width: 1099px) { .ib-listwrap > .ib-list:last-of-type > .ib-row:last-child .ib-rowlink { border-radius: var(--pn-r); } }
.ib-livebtn { margin: 12px 14px; max-width: calc(100% - 28px); white-space: normal; text-align: left; }
.ib-livehead { margin: 18px 14px 6px; font-size: 11px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; }
.ib-live > .pn-sub, .ib-live > .pn-msg, .ib-live > .pn-note { margin: 6px 14px; }
.ib-livelist { border-top: 1px solid var(--ib-line); }
/* the reading pane: the subject as its heading, what it is linked to, then each message as a card */
.ib-pane { min-width: 0; padding: 16px 20px 22px; outline: none; }
.ib-empty { display: grid; place-items: center; align-content: center; gap: 10px; min-height: 320px; text-align: center; color: var(--ib-soft); }
.ib-empty .pn-gl { width: 40px; height: 40px; opacity: .5; }
.ib-panehead { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 8px 12px; }
.ib-back { display: none; }
@media (max-width: 1099px) { .ib-back { display: inline-flex; flex-basis: 100%; } }
.ib-subject { flex: 1 1 240px; min-width: 0; margin: 2px 0 0; font: 300 24px/1.2 var(--font-display); letter-spacing: -.01em; overflow-wrap: anywhere; }
.ib-gmail { flex: none; }
.ib-linkbar { display: grid; gap: 8px; margin-top: 12px; padding: 8px 12px; border: 1px solid var(--ib-line); border-radius: var(--pn-r); }
@media (min-width: 560px) {
  .ib-linkbar:has(> .ib-linkacts) { grid-template-columns: minmax(0, 1fr) auto; align-items: center; }
  .ib-linkbar:has(> .ib-linkacts) > :not(.ib-linkline, .ib-linkacts) { grid-column: 1 / -1; }
  .ib-linkbar > .ib-linkacts { justify-self: end; }
}
.ib-linkline > .pn-t { font-size: 12.5px; color: var(--ib-soft); }
.ib-linkline { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0; min-width: 0; }
.ib-linkline > .pn-sub { margin: 0; }
.ib-linkto { color: inherit; font-size: 14px; font-weight: 600; overflow-wrap: anywhere; text-underline-offset: 3px; }
.ib-linkclient { font-weight: 400; }
.ib-offers { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
:root[data-app] :is(.ib-offer, .ib-linkacts .wa-gl) { white-space: normal; text-align: left; max-width: 100%; height: auto; min-height: var(--pn-h-act); padding-block: 4px; }
.ib-linkacts { flex-wrap: wrap; gap: 8px; margin: 0; }
.ib-pick { margin-top: 2px; }
.ib-found { list-style: none; margin: 8px 0 0; padding: 0; display: grid; gap: 6px; }
.ib-pickrow { width: 100%; justify-content: flex-start; text-align: left; min-height: 44px; white-space: normal; }
.ib-threadtools { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px; margin: 14px 0 8px; }
.ib-msgs { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.ib-msg { min-width: 0; border: 1px solid var(--ib-line); border-radius: var(--pn-r); }
.ib-mtop { display: grid; grid-template-columns: 36px minmax(0, 1fr) auto; gap: 12px; align-items: center; width: 100%; min-height: 44px; padding: 10px 12px;
  border: 0; border-radius: var(--pn-r); background: transparent; color: inherit; font: inherit; text-align: left; cursor: pointer; }
@media (hover: hover) { .ib-folded .ib-mtop:hover { background: var(--ib-fill); } }
.ib-mwho { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; min-width: 0; }
.ib-mwho b { font-weight: 600; overflow-wrap: anywhere; }
.ib-maddr { font-size: 12px; color: var(--ib-soft); overflow-wrap: anywhere; }
.ib-folded .ib-mwho { flex-wrap: nowrap; }
.ib-folded .ib-mwho b { flex: none; max-width: 45%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 759px) {
  .ib-folded .ib-mwho { flex-wrap: wrap; }
  .ib-folded .ib-mwho b { max-width: none; flex: 1 1 100%; }
  .ib-folded .ib-mwho .ib-mline { flex: 1 1 100%; white-space: nowrap; }
}
.ib-mline { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; color: var(--ib-soft); }
.ib-mwhen { display: inline-flex; align-items: center; gap: 6px; font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; color: var(--ib-soft); }
.ib-mwhen .pn-gl { width: 15px; height: 15px; }
.ib-mbody { min-width: 0; padding: 0 16px 16px 60px; }
@media (max-width: 759px) { .ib-mbody { padding: 0 12px 14px; } }
.ib-mbody > .ib-text:first-child { margin-top: 0; }
.ib-mto { margin: 0; font-size: 12.5px; line-height: 1.5; color: var(--ib-soft); overflow-wrap: anywhere; }
.ib-text { margin-top: 10px; font-size: 15px; line-height: 1.6; white-space: pre-wrap; overflow-wrap: anywhere; }
/* AN EMAIL AS ITS SENDER FORMATTED IT (10 Oct 2026: "This needs to come in formatted"; inbox.js viewFrame): white, as
   an email is drawn, in either theme, the frame as tall as the email; Show pictures and Show trimmed content under it */
.ib-view { margin-top: 10px; }
.ib-frame { display: block; width: 100%; height: 120px; border: 0; border-radius: var(--pn-r); background: #fff; }
.ib-viewbar { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.ib-viewbar:not(:has(> :not([hidden]))) { display: none; }
.ib-url { color: inherit; text-decoration: underline; text-underline-offset: 2px; overflow-wrap: anywhere; }
/* ATTACHMENTS (phase 3, 10 Oct 2026): one row a file, its name, kind and size, then Open and Download (or "Too big to
   open here" and Open in Gmail), the two the same size; where the row is too narrow for both, they go under the name */
.ib-files { list-style: none; display: grid; grid-template-columns: minmax(0, 1fr); gap: 8px; margin: 14px 0 0; padding: 0; }
.ib-file { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; min-width: 0; padding: 8px 8px 8px 12px; border: 1px solid var(--ib-line); border-radius: var(--pn-r); }
.ib-file > .pn-gl { flex: none; width: 16px; height: 16px; }
/* THE ATTACHMENTS FOLDED (10 Oct 2026: "Put these in a attachment row with + to expand"; inbox.js): one row with its
   count and a + that turns to a - once open, the files under it, 44px to a thumb */
.ib-filesfold { margin-top: 14px; border: 1px solid var(--ib-line); border-radius: var(--pn-r); }
.ib-filessum { display: flex; align-items: center; gap: 10px; min-height: 44px; padding: 0 14px 0 12px; cursor: pointer; list-style: none; }
.ib-filessum::-webkit-details-marker { display: none; }
.ib-filessum > .pn-gl { flex: none; width: 16px; height: 16px; }
.ib-filesname { font-weight: 500; }
.ib-filesn { margin-right: auto; }
.ib-plus { position: relative; flex: none; width: 14px; height: 14px; }
.ib-plus::before, .ib-plus::after { content: ""; position: absolute; left: 0; right: 0; top: 50%; height: 1.5px; margin-top: -.75px; border-radius: var(--pn-r); background: currentColor; }
.ib-plus::after { transform: rotate(90deg); transition: transform .15s ease; }
.ib-filesfold[open] .ib-plus::after { transform: rotate(0deg); }
.ib-filessum:focus-visible { outline: 2px solid currentColor; outline-offset: -2px; border-radius: var(--pn-r); }
.ib-filesfold > .ib-files { margin: 0; padding: 0 8px 8px; }
/* a picture the email shows in itself is not one of its attachments (inbox.js hideShownFiles) */
.ib-filesfold[hidden], .ib-file[hidden] { display: none; }
@media (prefers-reduced-motion: reduce) { .ib-plus::after { transition: none; } }
.ib-fwho { display: flex; flex-wrap: wrap; align-items: baseline; gap: 2px 8px; flex: 1 1 160px; min-width: 0; }
.ib-fname { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.ib-facts { display: flex; flex-wrap: wrap; align-items: center; justify-content: flex-end; gap: 8px; margin-left: auto; }
.ib-facts .wa-gl { min-height: 40px; padding: 0 12px; gap: 6px; }
.ib-facts .wa-gl .pn-gl { width: 16px; height: 16px; }
@media (pointer: coarse) { .ib-facts .wa-gl { min-height: 44px; } }
.ib-fbig { white-space: nowrap; }
.ib-whole { margin-top: 12px; }
.ib-foot { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 10px; margin-top: 18px; padding-top: 14px;
  border-top: 1px solid var(--ib-line); }
.ib-foot .pn-note { flex: 1 1 260px; margin: 0; }
.ib-foot .wa-gl, .ib-gmail { min-height: 40px; }
@media (pointer: coarse) { .ib-foot .wa-gl, .ib-gmail { min-height: 44px; } }
/* OPEN IN GMAIL ON A COMPUTER ONLY (13 Oct 2026, the operator, told Gmail's phone app has no link that opens one email:
   "Only show that button on desktop"): on a phone or a tablet every Open in Gmail is hidden (the Inbox's pane and its
   files, the job's Communication, the Desk's email sheet); the Studio's Inbox opens the email there */
@media (hover: none), (pointer: coarse) { .pn-deskonly { display: none !important; } }
.ib-err { margin-top: 12px; padding: 16px; }
.ib-metahost .ms-one { margin-top: 12px; }
/* THE REPLY (phase 2, 10 Oct 2026): the Drafts box and a draft's row marked Draft as Gmail marks it; Reply, Reply all and
   Forward at a thread's foot as Gmail's pills; then the composer as Gmail's inline reply, one card: the kind and where it
   stands (request, draft, approve, send), From, To, Cc and Bcc as chips with a cross each, the subject, the words, his
   signature in grey, the earlier message folded behind its dots, and the foot with Discard, Save draft and Send, the
   panel's own two buttons, one size. Every rule .ib-, light and dark from the inbox's own tokens. */
.ib-box[hidden] { display: none; }
.ib-draftw { flex: none; color: var(--st-bad); font-weight: 600; }
.ib-replyas { display: flex; flex-wrap: wrap; gap: 10px; }
.ib-replybtn .pn-gl { width: 18px; height: 18px; }
.ib-footc { display: block; }
.ib-compose { position: relative; min-width: 0; border: 1px solid var(--ib-line); border-radius: var(--pn-r); background: var(--ib-face); }
/* the composer is the app's card in either theme: its face and the calculator's shadow in place of the edge (2 Nov 2026,
   the operator: go A) */
:root[data-app] .ib-compose { border-color: transparent; box-shadow: var(--pn-sh); }
:root[data-app] .ib-compose.ib-cdrop { box-shadow: 0 0 0 2px var(--ib-mark); }
.ib-chead { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 8px 14px; padding: 10px 12px;
  border-bottom: 1px solid var(--ib-line); }
.ib-modes { display: flex; flex-wrap: wrap; gap: 6px; }
.ib-mode .pn-gl { width: 16px; height: 16px; }
.ib-steps { display: flex; flex-wrap: wrap; gap: 4px 14px; margin: 0; padding: 0; list-style: none; counter-reset: ibstep; font-size: 12px; color: var(--ib-soft); }
.ib-steps li { counter-increment: ibstep; display: inline-flex; align-items: center; gap: 6px; }
.ib-steps li::before { content: counter(ibstep); display: inline-flex; align-items: center; justify-content: center; box-sizing: border-box; width: 18px; height: 18px;
  border: 1px solid var(--ib-line); border-radius: var(--pn-r); font-size: 10.5px; line-height: 1; padding: 0 0 1px; text-align: center; font-variant-numeric: tabular-nums lining-nums; }
.ib-steps li.ib-done::before { background: var(--st-good); border-color: transparent; color: var(--pn-p-onink); }
.ib-steps li.ib-now { color: inherit; font-weight: 600; }
/* THE STEPPER'S CIRCLES (the operator, 18 Oct 2026, Problem report 215: "the number is not centered also the circle outline is too thick it
   looks cheap"): the present step's ring is the same single line as the others in the mark's colour, not a double one, and
   every number sits in the middle of its circle */
.ib-steps li.ib-now::before { border-color: var(--ib-mark); }
/* SQUARE, AND THE STEP YOU ARE ON IN THE YELLOW TAG (2 Nov 2026, the operator: go A): its number on the yellow with the
   ink's figure, in both themes */
.ib-steps li.ib-now::before { background: var(--pn-y); border-color: var(--pn-y); color: var(--pn-on-y); }
.ib-cend { display: flex; align-items: center; gap: 10px; }
.ib-cfields { display: grid; min-width: 0; }
.ib-crow { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-height: 44px; padding: 4px 12px; border-bottom: 1px solid var(--ib-line); min-width: 0; }
.ib-crow[hidden] { display: none; }
.ib-crow:focus-within { box-shadow: inset 0 -2px 0 var(--ib-mark); }
.ib-ck { flex: none; width: 56px; font-size: 13px; color: var(--ib-soft); }
.ib-cchips { display: contents; }
/* ROOM ROUND AN ADDRESS (the operator's report 183, 13 Oct 2026, of New email's To on his iPhone with an address in it:
   "Increase line spacing when the address is entered in"): a To, Cc or Bcc row holding an address has 8px above and under
   its line, and 8px between its lines when the addresses wrap, so a chip never sits tight to the row's edges; to a thumb
   each cross reaches 44px, 8px past its 28px chip above and under, so there the lines are 16px apart and two lines of
   crosses never overlap */
.ib-cpeople:has(.ib-cchip) { padding-top: 8px; padding-bottom: 8px; row-gap: 8px; }
@media (pointer: coarse) { .ib-cpeople:has(.ib-cchip) { row-gap: 16px; } }
.ib-cchip { display: inline-flex; align-items: center; gap: 2px; box-sizing: border-box; max-width: 100%; min-width: 0; height: 28px; padding: 0 2px 0 10px;
  border: 1px solid var(--ib-line); border-radius: var(--pn-r); background: var(--ib-fill); font-size: 12px; font-weight: 400; line-height: 1; }
.ib-cchipw { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ib-cx { display: inline-grid; place-items: center; flex: none; width: 24px; height: 24px; padding: 0; border: 0; border-radius: var(--pn-r); background: transparent;
  color: inherit; cursor: pointer; }
.ib-cx .pn-gl { width: 14px; height: 14px; }
@media (hover: hover) { .ib-cx:hover { background: var(--ib-line); } }
.ib-cin, .ib-csubj { flex: 1 1 160px; min-width: 120px; height: 40px; padding: 0; border: 0; background: transparent; color: inherit; font: inherit;
  font-size: 14px; outline: none; }
/* NO AUTOFILL YELLOW (report 179, 13 Oct 2026, of a pale yellow box after the chip in New email's To on his iPhone:
   "This yellow box when adding a new email receipeint"): Safari paints a box it filled from its own suggestions yellow,
   and keeps it once the address has gone into a chip; the box keeps the composer's own face, its words their own ink */
.ib-cin:-webkit-autofill, .ib-cin:-webkit-autofill:focus, .ib-csubj:-webkit-autofill, .ib-csubj:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px var(--pn-face, #fffdfa) inset; box-shadow: 0 0 0 1000px var(--pn-face, #fffdfa) inset;
  -webkit-text-fill-color: currentColor; caret-color: currentColor; transition: background-color 600000s 0s; }
.ib-cin:autofill, .ib-csubj:autofill { box-shadow: 0 0 0 1000px var(--pn-face, #fffdfa) inset; transition: background-color 600000s 0s; }
.ib-ccbcc { flex: none; margin-left: auto; min-height: 32px; padding: 0 0 0 8px; border: 0; background: transparent; color: var(--ib-soft); font: inherit;
  font-size: 13px; text-decoration: underline; text-underline-offset: 3px; cursor: pointer; }
.ib-ccbcc[hidden] { display: none; }
.ib-cfrom { flex: 1 1 200px; min-width: 0; height: 40px; padding: 0; border: 0; background: transparent; color: inherit; font: inherit; font-size: 14px; }
.ib-cfromw { flex: 1 1 200px; min-width: 0; font-size: 14px; overflow-wrap: anywhere; }
.ib-contacts { display: flex; flex-wrap: wrap; gap: 6px; padding: 8px 12px; border-bottom: 1px solid var(--ib-line); }
.ib-contacts[hidden] { display: none; }
.ib-crole { font-size: 11px; color: var(--ib-soft); }
.ib-cwarn { margin: 6px 12px 0; }
.ib-cwarn[hidden], .ib-cfwd[hidden], .ib-cquote[hidden], .ib-cquotebtn[hidden] { display: none; }
.ib-cwords { display: block; box-sizing: border-box; width: 100%; min-height: 200px; padding: 14px 12px; border: 0; background: transparent; color: inherit;
  font: inherit; font-size: 15px; line-height: 1.6; resize: vertical; outline: none; field-sizing: content; max-height: 70vh; }
.ib-cwords:focus-visible { box-shadow: inset 0 0 0 2px var(--ib-mark); border-radius: var(--pn-r); }
/* THE FORMATTING BAR AND ITS BOX (29 Oct 2026, the operator, with Gmail's own bar: "need formatting that translates into
   gmail style when sent"): B, I, U, the colour, aligning, the two lists and indent, a row of the Studio's small glyph
   buttons over the words, the 11 px corner; the plain box under it hidden, keeping the plain words */
.ib-cplain[hidden] { display: none; }
.ib-cbar { position: relative; display: flex; flex-wrap: wrap; align-items: center; gap: 2px; padding: 6px 8px; border-bottom: 1px solid var(--ib-line); }
.ib-cfmt { display: inline-flex; align-items: center; justify-content: center; gap: 1px; min-width: 32px; height: 32px; padding: 0 6px; border: 0;
  border-radius: var(--pn-r); background: transparent; color: inherit; cursor: pointer; }
.ib-cfmt:hover:not(:disabled) { background: var(--ib-fill); }
.ib-cfmt[aria-pressed="true"], .ib-cfmt[aria-expanded="true"] { background: var(--ib-sel); box-shadow: inset 0 0 0 1px var(--ib-line); }
.ib-cfmt:focus-visible { outline: 2px solid var(--ib-mark); outline-offset: 1px; }
.ib-cfmt:disabled { opacity: .45; cursor: default; }
.ib-cfmt .pn-gl { width: 18px; height: 18px; }
.ib-cfmt .pn-gl + .pn-gl { width: 12px; height: 12px; margin-left: -1px; }
.ib-cfmtw { font-size: 15px; line-height: 1; }
.ib-cfmt-bold .ib-cfmtw { font-weight: 700; }
.ib-cfmt-italic .ib-cfmtw { font-style: italic; }
.ib-cfmt-underline .ib-cfmtw { text-decoration: underline; text-underline-offset: 2px; }
.ib-cfmtcol { display: inline-grid; justify-items: center; gap: 1px; }
.ib-cfmtbar { width: 14px; height: 3px; border-radius: var(--pn-r); background: currentColor; }
/* THE FORMAT BAR ON A PHONE (9 Nov 2026, of two glyphs wrapped alone): one row, each control a share of it */
@media (max-width: 759px) {
  .ib-cbar { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); gap: 0; padding: 4px; }
  .ib-cbar > .ib-cbarsep { display: none; }
  .ib-cbar .ib-cfmt { position: relative; min-width: 0; width: 100%; height: var(--pn-h-act); padding: 0; }
  .ib-cbar .ib-cfmt::after { content: ""; position: absolute; inset: -6px 0; }
  .ib-cbar .ib-cfmt .pn-gl + .pn-gl { width: 8px; height: 8px; }
}
.ib-cbarsep { width: 1px; height: 18px; margin: 0 4px; background: var(--ib-line); }
.ib-cpop { position: absolute; top: calc(100% - 2px); z-index: 5; display: grid; gap: 4px; padding: 8px; border: 1px solid var(--ib-line); border-radius: var(--pn-r);
  background: var(--pn-face, #1d1b20); box-shadow: none; }
.ib-cpop[hidden] { display: none; }
.ib-ccols { left: 96px; grid-template-columns: repeat(6, 24px); }
.ib-caligns { left: 132px; grid-auto-flow: column; }
.ib-cswatch { width: 24px; height: 24px; padding: 0; border: 1px solid var(--ib-line); border-radius: 50%; cursor: pointer; }
.ib-cswatch:hover { transform: scale(1.12); }
.ib-cswatch:focus-visible { outline: 2px solid var(--ib-mark); outline-offset: 2px; }
.ib-crich { min-height: 200px; resize: none; overflow: auto; overflow-wrap: anywhere; white-space: pre-wrap; cursor: text; }
.ib-crich ol, .ib-crich ul { margin: 0; padding-left: 28px; }
.ib-crich[contenteditable="false"] { color: var(--ib-soft); }
@media (pointer: coarse) {
  .ib-cfmt { min-width: 44px; height: 44px; }
  .ib-cswatch { width: 34px; height: 34px; }
  .ib-ccols { left: 8px; grid-template-columns: repeat(6, 34px); }
  .ib-caligns { left: 8px; }
}
.ib-csig { display: grid; gap: 2px; padding: 0 12px 8px; font-size: 13px; line-height: 1.5; color: var(--ib-soft); white-space: pre-wrap; overflow-wrap: anywhere; }
.ib-cquotebtn { display: inline-grid; place-items: center; width: 40px; height: var(--pn-h-act); margin: 0 12px 10px; padding: 0; border: 1px solid var(--ib-line);
  border-radius: var(--pn-r); background: var(--ib-fill); color: inherit; cursor: pointer; }
.ib-cquotebtn .pn-gl { width: 18px; height: 18px; }
.ib-cquote { margin: 0 12px 12px; padding-left: 12px; border-left: 2px solid var(--ib-line); font-size: 14px; line-height: 1.55; color: var(--ib-soft); }
.ib-csaid { margin: 0 0 6px; }
.ib-cqtext { white-space: pre-wrap; overflow-wrap: anywhere; }
.ib-cfwd { margin: 0 12px 10px; }
.ib-csaidw { margin: 0 12px 8px; }
.ib-csaidw:empty { display: none; }
.ib-csend { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 10px; padding: 10px 12px; border-top: 1px solid var(--ib-line); }
.ib-cstate { flex: 1 1 140px; min-width: 0; font-size: 12px; color: var(--ib-soft); }
.ib-cbtn .pn-gl { width: 16px; height: 16px; }
/* DRAFT WITH CLAUDE (roadmap L2, 13 Oct 2026; assets/compose.js): a row above the words, what to say and the button, which
   keeps its one line and goes under what to say when the row is too narrow; the words box read only while Claude drafts */
.ib-cai { gap: 6px 10px; }
.ib-caiin { flex: 1 1 180px; min-width: 0; }
.ib-caiin::placeholder { color: var(--ib-soft); opacity: 1; }
.ib-caibtn { flex: none; gap: 8px; white-space: nowrap; }
.ib-caibtn .pn-gl { width: 16px; height: 16px; }
.ib-caibtn:disabled { opacity: .55; cursor: default; }
.ib-caibtn[aria-busy="true"] { opacity: 1; }
.ib-cwords[readonly] { color: var(--ib-soft); }
.ib-sigprev { margin: 4px 0 0; padding: 10px 12px; border: 1px solid var(--pn-line); border-radius: var(--pn-r); font-size: 13px; line-height: 1.5; white-space: pre-wrap;
  overflow-wrap: anywhere; }
@media (pointer: coarse) {
  .ib-cx { width: 44px; height: 44px; margin: -8px -8px -8px -4px; }
  .ib-ccbcc, .ib-cin, .ib-csubj, .ib-cfrom { min-height: 44px; }
}
@media (max-width: 759px) {
  /* three boxes now, on a line under the heading, wrapping when the row is too narrow for them */
  .ib-side { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
  .ib-boxes { flex: 0 1 auto; flex-wrap: wrap; max-width: 100%; }
  .ib-conn { flex: 1 1 100%; }
  .ib-compose { border-radius: var(--pn-r); }
  .ib-steps { display: none; }
  .ib-ck { width: 48px; }
  /* a box to type in stays on its chips' line while it can, and the foot keeps its three buttons on one line: where it
     stands first, on a line of its own */
  .ib-cin { flex: 1 1 60px; min-width: 60px; }
  .ib-cstate { order: -1; flex: 1 1 100%; }
  .ib-cstate:empty { display: none; }
  .ib-csend .pn-savebtn { margin-left: auto; }
  /* the four on one line at 390 wide too (3 Nov 2026, the Studio's UX pass): at 10px apart they were 4px too wide and
     Send, the main button, went alone onto a line of its own */
  .ib-csend { column-gap: 8px; }
}
@media (max-width: 379px) {
  .ib-caiin { flex-basis: 100%; }
  .ib-csend { gap: 8px 6px; }
  .ib-csend .wa-gl:not(.pn-glicon), .ib-csend .wa-btn { padding: 0 12px; }
}
/* L4, THE REST OF GMAIL IN THE STUDIO (the operator, 13 Oct 2026: "Do N4 and L4 L5 L6."; assets/compose.js, inbox.js):
   Compose above the boxes as Gmail has it, and on a phone a round button at the bottom right, above Report a problem's;
   a new email's heading; the attachments as chips with their size and a cross, the clip beside Discard, and the composer
   lit while files are dragged over it; the people suggested under an address box; Archive and Mark unread on a row
   (shown while the pointer is over it, the focus is in it, or after a long press) and in the open email's head. Every
   rule .ib-, light and dark from the Inbox's own tokens and the app's solid face. */
.ib-composebtn { justify-content: flex-start; margin: 0 0 10px; }
/* below 760px Compose sits on the boxes' line at the right, filled, the page's main action (9 Nov 2026, of a 56px square over the list) */
@media (max-width: 759px) { .ib-side > .ib-composebtn { order: 1; margin: 0 0 0 auto; } .ib-side > .ib-conn { order: 2; } }
.ib-composebtn .pn-gl { width: 18px; height: 18px; }
.ib-cnewh { display: inline-flex; align-items: center; gap: 8px; margin: 0; min-height: 32px; font-size: 15px; font-weight: 600; }
.ib-cnewh .pn-gl { width: 18px; height: 18px; }
.ib-footnew { margin-top: 12px; padding-top: 0; border-top: 0; }
.ib-cfilesbox { padding: 2px 12px 10px; }
.ib-cfilesbox[hidden] { display: none; }
.ib-cfiles { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 0; padding: 0; }
.ib-cfile { display: inline-flex; align-items: center; gap: 8px; max-width: 100%; min-width: 0; min-height: 40px; padding: 2px 2px 2px 12px;
  border: 1px solid var(--ib-line); border-radius: var(--pn-r); background: var(--ib-fill); font-size: 13px; }
.ib-cfile > .pn-gl { flex: none; width: 15px; height: 15px; }
.ib-cfilew { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px; min-width: 0; }
.ib-cfilename { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 500; }
.ib-cfilesize { font-size: 12px; color: var(--ib-soft); font-variant-numeric: tabular-nums; }
.ib-cfileoff { border-style: dashed; background: transparent; }
.ib-cfileoff .ib-cfilesize { color: var(--st-warn); }
.ib-cfilesw { margin: 8px 0 0; }
.ib-cattach .pn-gl { width: 18px; height: 18px; }
.ib-cdropw { display: none; }
.ib-compose.ib-cdrop { box-shadow: 0 0 0 2px var(--ib-mark); }
.ib-compose.ib-cdrop .ib-cdropw { position: absolute; inset: 0; z-index: 2; display: grid; place-items: center; margin: 0; padding: 16px; border-radius: inherit;
  background: var(--pn-face, #25211c); color: inherit; font-size: 15px; font-weight: 600; text-align: center; pointer-events: none; }
.ib-csugg { flex: 1 1 100%; list-style: none; display: grid; gap: 2px; margin: 2px 0 6px; padding: 4px; border: 1px solid var(--ib-line); border-radius: var(--pn-r);
  background: var(--pn-face, #25211c); }
.ib-csugg[hidden] { display: none; }
.ib-csuggb { display: flex; flex-wrap: wrap; align-items: center; gap: 2px 8px; width: 100%; min-height: 40px; padding: 6px 10px; border: 0; border-radius: var(--pn-r);
  background: transparent; color: inherit; font: inherit; font-size: 14px; text-align: left; cursor: pointer; }
.ib-csuggn { font-weight: 500; overflow-wrap: anywhere; }
.ib-csugga { font-size: 12px; overflow-wrap: anywhere; }
.ib-csuggb .pn-badge { margin-left: auto; }
.ib-csuggrow { display: flex; align-items: center; gap: 4px; }
.ib-csuggrow > .ib-csuggb { flex: 1 1 auto; min-width: 0; }
.ib-csuggx { flex: none; width: 32px; height: 32px; padding: 0; }
@media (hover: hover) { .ib-csuggb:hover { background: var(--ib-fill); } }
.ib-csuggb:focus-visible { outline-offset: -2px; }
/* a row's own actions, over its right end where the time is, on the app's solid face so the time never shows through */
.ib-rowacts { position: absolute; top: 6px; right: 8px; z-index: 1; display: none; gap: 4px; padding: 3px; border: 1px solid var(--ib-line); border-radius: var(--pn-r);
  background: var(--pn-face, #25211c); }
.ib-row:focus-within .ib-rowacts, .ib-row.ib-acts .ib-rowacts { display: flex; }
@media (hover: hover) and (pointer: fine) { .ib-row:hover .ib-rowacts { display: flex; } }
:root[data-app] .ib-rowact { width: var(--pn-h-act); height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0; }
.ib-headacts { display: inline-flex; gap: 6px; flex: none; }
:root[data-app] .ib-headact { width: var(--pn-h-act); height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0; }
@media (pointer: coarse) {
  .ib-cfile { min-height: 44px; }
  .ib-csuggb { min-height: 44px; }
  .ib-rowacts { top: 4px; }
  /* A SWIPE LEFT ON A ROW (28 Oct 2026: "Make swipe left on an inbox row on mobile reveal the archive/unread option"): a
     sideways finger is the row's to move, an up or down one the list's; the row slides left over its actions, which sit
     behind it at its right end, the full height of the row, and it stays open on them once let go past half way */
  .ib-row:has(.ib-rowacts) .ib-rowlink { touch-action: pan-y; }
  .ib-row { overflow: hidden; }
  .ib-row:is(.ib-swiping, .ib-swiped) .ib-rowacts { display: flex; top: 0; bottom: 0; right: 0; z-index: 0; align-items: center; gap: 2px;
    padding: 0 6px; border: 0; border-radius: 0; background: none; } /* no strip of its own: the card's face behind the two buttons (28 Oct 2026: "The coloured background behind the two buttons look weird") */
  /* the slid row square, as every corner is now (2 Nov 2026, the operator: go A; it was rounded the card's 14px on 28 Oct
     2026: "Round the corners in the slid email"), its soft shadow still showing it lifted off its actions */
  .ib-row:is(.ib-swiping, .ib-swiped) .ib-rowlink { position: relative; z-index: 1; border-radius: var(--pn-r);
    background: linear-gradient(var(--ib-rowbg), var(--ib-rowbg)), var(--ib-face); box-shadow: 0 0 0 1px var(--ib-line); }
  .ib-row { --ib-rowbg: var(--ib-read, transparent); }
  .ib-row.ib-unread { --ib-rowbg: var(--ib-unread, transparent); }
  .ib-row.ib-swiping .ib-rowlink { transform: translateX(var(--ib-sx, 0px)); }
  .ib-row.ib-swiped .ib-rowlink { transform: translateX(calc(-1 * var(--ib-actw, 112px))); transition: transform .2s ease; }
  .ib-row:not(.ib-swiping):not(.ib-swiped) .ib-rowlink { transition: transform .2s ease; }
}
@media (pointer: coarse) and (prefers-reduced-motion: reduce) { .ib-row:not(.ib-swiping):not(.ib-swiped) .ib-rowlink, .ib-row.ib-swiped .ib-rowlink { transition: none; } }
/* L7, EMAIL FROM A JOB'S OR A CLIENT'S PAGE (the operator, 13 Oct 2026: "build 7"; assets/compose.js): what a new email is
   linked to under its heading; Attach from the job, a chip button with its count, opening its list of ticks, a group a job
   (a client's jobs each with its name), each tick its document's name and what it is, a file too big to go dashed and
   off; a document's own chip. Every rule .ib-, light and dark from the Inbox's own tokens, 44px to a thumb, nothing wider
   than a 320px phone. */
.ib-compose .ib-cabout { margin: 8px 12px 0; overflow-wrap: anywhere; }
.ib-cdocs { padding: 4px 12px 10px; min-width: 0; }
.ib-cdocsbtn { gap: 8px; max-width: 100%; }
.ib-cdocsbtn .pn-gl { flex: none; width: 16px; height: 16px; }
.ib-cdocsbtn:disabled { opacity: .55; cursor: default; }
.ib-cdocslist { display: grid; gap: 10px; margin-top: 8px; padding: 10px 12px; border: 1px solid var(--ib-line); border-radius: var(--pn-r); background: var(--ib-face); }
.ib-cdocslist[hidden] { display: none; }
.ib-cdocsjob { min-width: 0; margin: 0; padding: 0; border: 0; }
.ib-cdocsjobn { padding: 0; margin: 0 0 4px; font-size: 11px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--ib-soft);
  overflow-wrap: anywhere; }
.ib-cdocsul { list-style: none; display: grid; gap: 2px; margin: 0; padding: 0; }
.ib-cdoc { display: flex; align-items: center; gap: 10px; min-width: 0; min-height: 40px; padding: 4px 8px; border-radius: var(--pn-r); cursor: pointer; }
@media (hover: hover) { .ib-cdoc:hover { background: var(--ib-fill); } }
.ib-cdoc:focus-within { box-shadow: inset 0 0 0 2px var(--ib-mark); }
.ib-cdocbox { flex: none; width: 17px; height: 17px; margin: 0; accent-color: var(--beige); }
:root[data-app][data-theme="light"] .ib-cdocbox { accent-color: var(--pn-ink); }
.ib-cdocw { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 10px; min-width: 0; }
.ib-cdocname { min-width: 0; font-size: 14px; font-weight: 500; overflow-wrap: anywhere; }
.ib-cdocwhat { font-size: 12px; color: var(--ib-soft); }
.ib-cdocoff { cursor: default; border: 1px dashed var(--ib-line); }
.ib-cdocoff .ib-cdocwhat { color: var(--st-warn); }
.ib-cdocsw { margin: 0; }
.ib-cfiledoc > .pn-gl { width: 16px; height: 16px; }
@media (pointer: coarse) {
  .ib-cdoc { min-height: 44px; }
}
/* THE INBOX AS A CALCULATOR CARD (2 Nov 2026, the operator: go A, and "keep QoL changes i requested such as search
   button hide/expand on email etc behaviour the same"): the toolbar, the filters, the list and the pane are one card on
   the page's ground, the app's face with the calculator's shadow in place of its edge, in both themes, and nothing on
   it once a thread is the whole of a phone's screen. The subject over an email is the website's heading face, light. The search box is a field (the 3:1 edge, ink once the focus is
   in it), drawn inside its box so the phone's fold still closes it to nothing. The open email keeps its yellow bar
   (28 Oct 2026: "make this left selection tab colour yellow"), with a hairline beside it in light as the unread dot
   has, so it shows on the white. The initials sit on the website's beige in light. The boxes' dropdown on a phone is
   the app's dropdown (the menu's face and the card shadow), and the Compose button is the main button: ink in light,
   the yellow in dark. Looks only: every fold, swipe, splitter, fit-the-window and long-press rule above is as it was. */
:root[data-app] .ib-main { border-color: transparent; box-shadow: var(--pn-sh); }
@media (max-width: 759px) { :root[data-app] .ib-open .ib-main { box-shadow: none; } }
:root[data-app] .ib-searchbox { background: var(--ib-face); box-shadow: inset 0 0 0 1px var(--pn-edge); }
:root[data-app] .ib-searchbox:focus-within { box-shadow: inset 0 0 0 2px var(--pn-ink); }
:root[data-app][data-theme="light"] .ib-row.ib-on .ib-rowlink { box-shadow: inset 3px 0 0 var(--moon), inset 4px 0 0 rgba(36,31,25,.28); }
:root[data-app][data-theme="light"] .ib { --ib-avbg: var(--beige); }
@media (max-width: 759px) {
  :root[data-app] .ib-boxdrop .ib-boxes { border-color: var(--pn-line); background: var(--pn-face-2); box-shadow: var(--pn-sh); }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   INSTAGRAM AND FACEBOOK MESSAGES (P5a, the operator, 3 Oct 2026: "Roadmap Instagram and Facebook business messages
   from studio"; assets/messages.js). The list, one conversation as a TIMELINE in the desk's email rail's shape (a dot a
   message on a rail, filled for us and hollow for them, the day written once for its messages), the reply, and the
   job page's Mail card's rail (assets/jobfolds.js). Light and dark from the app's own tokens and currentColor; every
   target 44px on a phone; nothing wider than a 320px phone. The classes are ms-.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.ms-head { flex-wrap: wrap; gap: 10px; }
.ms-only { display: inline-flex; align-items: center; gap: 8px; min-height: 44px; font-size: 14px; cursor: pointer; }
.ms-only input { width: 18px; height: 18px; margin: 0; }
.ms-off { margin-top: 14px; display: flex; flex-wrap: wrap; align-items: center; gap: 10px; justify-content: space-between; }
.ms-list { margin-top: 14px; padding: 0; list-style: none; }
.ms-row { border-bottom: 1px solid var(--pn-line, rgba(127,127,127,.2)); }
.ms-row:last-child { border-bottom: 0; }
/* THE ROW'S WHOLE WIDTH (report 156, 9 Oct 2026, of Messages at 577px: "fix time date chip alignment"): the row is a
   .pn-list li, a flex row, and the link in it took only its content's width, so a short preview pulled its date and
   chip in from the right edge. The link fills the row (flex), so every date and chip lines up on the right. */
.ms-rowlink { display: grid; grid-template-columns: 40px minmax(0, 1fr) auto; gap: 12px; align-items: center; min-height: 44px; padding: 10px 6px;
  flex: 1 1 100%; min-width: 0; color: inherit; text-decoration: none; border-radius: var(--pn-r); }
.ms-rowlink:hover { background: var(--pn-fill, rgba(127,127,127,.08)); }
.ms-rowlink:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.ms-rowtext { display: grid; gap: 2px; min-width: 0; }
.ms-rowtop { display: flex; gap: 8px; align-items: baseline; min-width: 0; }
.ms-rowtop b, .ms-rowtop .pn-t, .ms-snip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; }
.ms-rowtop .pn-t { flex: 0 1 auto; }
.ms-rowtop b { font-weight: 500; }
.ms-unread .ms-rowtop b { font-weight: 700; }
.ms-rowside { display: grid; justify-items: end; gap: 4px; }
.ms-chips { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: flex-end; }
.ms-face { width: 40px; height: 40px; border-radius: 50%; object-fit: cover; flex: none; }
.ms-initial { display: inline-grid; place-items: center; font-weight: 600; background: var(--pn-fill, rgba(127,127,127,.12)); border: 1px solid var(--pn-line, rgba(127,127,127,.2)); }
.ms-facebig { width: 56px; height: 56px; font-size: 20px; }
.ms-pager { margin-top: 12px; justify-content: center; gap: 12px; align-items: center; }
.ms-one { display: grid; gap: 14px; margin-top: 14px; }
/* THE PERSON'S CARD, ITS BUTTONS IN ONE GROUP (the operator's report 147, 8 Oct 2026, of a conversation on a computer
   546px wide: "fix alignment"). Link to a lead, job or client sat in the words' column, 70px in, and Open in Messenger
   and Delete this person's data under it from the card's left edge. Now the picture and the words beside it (the name,
   the platform's line, what it is linked to) come first, packed close so no band of nothing is left under the picture,
   then every button the card has in one row from the card's left edge (assets/messages.js whoActs), wrapping as the
   width needs and each the card's width on a phone, and the search Link to opens under them; the card ends 16px under
   its last button, as every card does. */
.ms-who { display: grid; grid-template-columns: 56px minmax(0, 1fr); gap: 14px; align-items: start; }
.ms-whotext { min-width: 0; }
.ms-name { margin: 0 0 2px; font: 300 24px/1.2 var(--font-display); letter-spacing: -.01em; overflow-wrap: anywhere; }
.ms-whotext > .pn-t { margin: 2px 0 0; }
.ms-whoacts, .ms-pick { grid-column: 1 / -1; }
.ms-whoacts { flex-wrap: wrap; gap: 8px; }
.ms-links { margin-top: 8px; }
.ms-links > p { margin: 0; }
.ms-links > p + p { margin-top: 6px; }
.ms-links a { color: inherit; }
.ms-whoacts .wa-gl, .ms-whoacts .wa-btn { white-space: normal; text-align: left; max-width: 100%; }
/* NO EMPTY BAND UNDER THE CARD (report 147): the line that says what a press did ("Linked.", "Sent.") sits between the
   card and the reply, and empty it still took its 20px, its 4px and a gap of the page's grid, so the card stood 66px
   above the next one where the page's cards are 28px apart. Empty, it is out of the page's flow, still there for a
   screen reader to hear what it says next; with words it is back in its place. */
.ms-one > .pn-msg:empty { position: absolute; min-height: 0; margin: 0; }
.ms-found { margin: 8px 0 0; padding: 0; list-style: none; display: grid; gap: 6px; }
.ms-pickrow { width: 100%; justify-content: flex-start; text-align: left; min-height: 44px; }
:root[data-app] .wa-card.ms-asked { border-color: var(--st-warn-line); background: var(--st-warn-bg); }
.ms-asked p { margin: 0; font-size: 14px; font-weight: 400; line-height: 1.5; }
.ms-reply h2, .ms-railcard h2 { display: flex; gap: 8px; align-items: center; margin: 0 0 8px; }
.ms-box { width: 100%; min-height: 88px; resize: vertical; font: inherit; box-sizing: border-box; }
.ms-sendrow { margin-top: 10px; flex-wrap: wrap; gap: 8px; align-items: center; }
.ms-sendrow .wa-btn, .ms-sendrow .wa-gl, .ms-whoacts .wa-gl, .ms-whoacts .wa-btn { min-height: 44px; }
.ms-photobtn { position: relative; cursor: pointer; }
.ms-railhead { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; justify-content: space-between; }
.ms-rail { max-height: 70vh; overflow: auto; padding-right: 4px; }
.ms-rail:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
/* THE RAIL: a line down the left, a dot a message on it */
.ms-msgs { list-style: none; margin: 0; padding: 0 0 0 22px; position: relative; }
.ms-msgs::before { content: ""; position: absolute; left: 7px; top: 6px; bottom: 6px; width: 1px; background: var(--pn-line, rgba(127,127,127,.3)); }
.ms-day { margin: 14px 0 6px -22px; font-size: 10.5px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; opacity: .72; }
.ms-day span { padding-left: 22px; }
.ms-day:first-child { margin-top: 0; }
.ms-msg { position: relative; padding: 4px 0 12px; }
.ms-dotmark { position: absolute; left: -19px; top: 9px; width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid currentColor; box-sizing: border-box; }
.ms-us .ms-dotmark { background: currentColor; }
.ms-them .ms-dotmark { background: var(--pn-face, transparent); }
.ms-msghead { margin: 0 0 2px; display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; }
.ms-msghead b { font-weight: 600; }
.ms-text { margin: 0; white-space: pre-wrap; overflow-wrap: anywhere; }
.ms-marks, .ms-file { margin: 4px 0 0; }
.ms-photo { display: inline-block; margin-top: 6px; border-radius: var(--pn-r); overflow: hidden; max-width: min(320px, 100%); }
.ms-photo img { display: block; max-width: 100%; height: auto; }
.ms-ref { font-size: 20px; font-weight: 600; font-variant-numeric: tabular-nums; letter-spacing: .04em; }
.ms-pages { padding: 0; list-style: none; }
.ms-pages li { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: space-between; padding: 8px 0; }
.jf-msgs { padding-top: 4px; }
@media (max-width: 520px) {
  .ms-rowlink { grid-template-columns: 40px minmax(0, 1fr); }
  .ms-rowside { grid-column: 2; display: flex; flex-wrap: wrap; justify-items: start; justify-content: flex-start; gap: 6px 8px; align-items: center; min-width: 0; }
  .ms-chips { justify-content: flex-start; }
  .ms-who { grid-template-columns: 44px minmax(0, 1fr); }
  .ms-facebig { width: 44px; height: 44px; }
  .ms-whoacts > * { flex: 1 1 100%; justify-content: center; }
  .ms-sendrow > .wa-btn, .ms-sendrow > .wa-gl { flex: 1 1 auto; justify-content: center; }
  .ms-only, .ms-pickrow { min-height: 44px; }
}
/* buttons in a row the same size (the Studio's rule), the main one filled */
.ms-sendrow > .wa-btn, .ms-sendrow > .wa-gl, .ms-whoacts > .wa-gl, .ms-whoacts > .wa-btn { min-width: 168px; justify-content: center; }
@media (max-width: 520px) { .ms-sendrow > .wa-btn, .ms-sendrow > .wa-gl, .ms-whoacts > .wa-gl, .ms-whoacts > .wa-btn { min-width: 0; } }
/* L5, LAID OUT AS THE EMAILS ARE, IN THE INBOX ONLY (the operator, 13 Oct 2026: "Inbox only (Recommended)", "Email look
   only (Recommended)"; assets/messages.js drawPane): a conversation in the Inbox's reading pane wears the email view's own
   .ib- rules (its head, link bar, message cards, attachments' fold and the composer's card at the foot); these few only
   fit a conversation to them: the platform's chip beside who, an earlier message folded to TWO lines of its words under
   who sent it, their picture in the email's round, and the reply box's window words and closed state. No bubbles, dots
   or read marks of a chat. */
.ms-pane { min-width: 0; }
.ms-headchips { display: inline-flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; min-width: 0; max-width: 100%; align-self: center; }
.ms-headchips .pn-t { min-width: 0; max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
:root[data-app] .ms-panehead .wa-gl.ib-gmail { position: relative; height: var(--pn-h-act); min-height: var(--pn-h-act); margin-left: auto; padding: 0 10px; gap: 6px; font-size: 10.5px; }
:root[data-app] .ms-panehead .wa-gl.ib-gmail .pn-gl { width: 14px; height: 14px; }
@media (pointer: coarse) { .ms-panehead .wa-gl.ib-gmail::after { content: ""; position: absolute; inset: -7px 0; } }
.ms-pane .ms-links { display: grid; gap: 4px; min-width: 0; }
.ms-pane .ms-links .pn-sub, .ms-pane .ms-offer { margin: 0; }
.ms-pane .ms-links a { color: inherit; font-weight: 600; text-underline-offset: 3px; overflow-wrap: anywhere; }
.ms-pane .ms-asked { margin-top: 12px; }
.ms-pane .ms-pick { margin-top: 2px; }
.ms-pane .ms-pick[hidden] { display: none; }
.ms-tools { flex-wrap: wrap; gap: 8px; margin: 0; }
.ms-tools .wa-gl { min-height: 36px; }
.ms-card.ib-folded .ib-mwho { display: grid; gap: 2px; }
.ms-card.ib-folded .ib-mwho b { max-width: 100%; }
.ms-mline { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; line-clamp: 2; white-space: normal; line-height: 1.45; overflow-wrap: anywhere; }
.ms-avimg { overflow: hidden; padding: 0; }
.ms-avimg img { display: block; width: 100%; height: 100%; border-radius: 50%; object-fit: cover; }
.ms-card .ms-marks { margin-top: 10px; }
.ms-reply .ms-window { margin: 10px 12px 0; }
.ms-reply .ib-cwords { min-height: 120px; }
/* the counter at the left, the buttons together at the right; one line, wrapping only on the narrowest phones */
.ms-reply .ib-csend { flex-wrap: nowrap; }
.ms-reply .ib-csend > :nth-child(2) { margin-left: auto; }
@media (max-width: 339.98px) { .ms-reply .ib-csend { flex-wrap: wrap; } }
.ms-reply.ms-closed .ms-window { margin: 12px; }
.ms-reply .ib-chead .pn-badge { flex: none; }
.ms-reply .ms-photobtn { position: relative; }
@media (max-width: 759px) { .ms-reply .ms-photobtn { margin-left: auto; } }
/* the count gives way, and the two buttons are as wide as their words with their glyphs (9 Nov 2026: at 390 the count's whole-line basis squeezed them) */
.ms-reply .ib-csend > .ib-cstate { flex: 0 1 auto; order: 0; }
.ms-reply .ib-csend > .ms-photobtn, .ms-reply .ib-csend > .ib-cbtn { flex: none; padding: 0 10px; gap: 6px; }
.ms-reply .ib-csend > .ms-photobtn .pn-gl, .ms-reply .ib-csend > .ib-cbtn .pn-gl { flex: none; width: 14px; height: 14px; }

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   INSTAGRAM AND FACEBOOK POSTS UNDER A JOB (P5b, the operator, 4 Oct 2026; assets/posts.js). The job page's Posts
   fold: each post a card with its photos, its state on each platform, its reason when it failed and its buttons, and
   the editor's sheet (the photos or video, where, the two captions, the ticks, the tags placed on a photo, and when).
   Light and dark from the app's own tokens and currentColor; every target 44px on a phone; nothing wider than a 320px
   phone; a photo always at its own shape (contain, never cropped). The classes are po-.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.po-new { margin: 12px 0; }
.po-card { display: grid; gap: 10px; }
.po-head { display: flex; flex-wrap: wrap; gap: 8px; align-items: baseline; justify-content: space-between; }
.po-head b { font-weight: 600; }
.po-thumbs { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.po-thumb { width: 56px; height: 56px; border-radius: var(--pn-r); object-fit: contain; background: var(--pn-fill, rgba(127,127,127,.1));
  border: 1px solid var(--pn-line, rgba(127,127,127,.2)); display: inline-grid; place-items: center; box-sizing: border-box; }
.po-thumb .pn-gl, .po-tile .pn-gl { width: 22px; height: 22px; opacity: .7; }
.po-more { font-size: 13px; font-variant-numeric: tabular-nums; opacity: .72; }
.po-plat { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; min-width: 0; }
.po-platgl { width: 20px; height: 20px; flex: none; }
.po-plat > b { font-weight: 600; }
.po-plat .pn-t { overflow-wrap: anywhere; }
.po-link { display: inline-flex; align-items: center; gap: 6px; min-height: 44px; color: inherit; }
.po-link .pn-gl { width: 18px; height: 18px; }
.po-why { flex-basis: 100%; margin: 0; color: var(--st-bad); overflow-wrap: anywhere; }
.po-warn { margin: 0; color: var(--st-warn); font-size: 13px; line-height: 1.45; overflow-wrap: anywhere; }
.po-acts { flex-wrap: wrap; gap: 8px; }
/* buttons in a row the same size (the Studio's rule), the main one filled */
.po-foot > .wa-btn, .po-foot > .wa-gl { min-width: 168px; justify-content: center; }
.po-act span { white-space: normal; }
/* the editor */
.po-ed { display: grid; gap: 18px; }
.po-part { display: grid; gap: 8px; min-width: 0; }
.po-part h3 { margin: 0; font-size: 11px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; color: var(--pn-muted); }
.po-mediarow { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(112px, 1fr)); gap: 10px; }
.po-media { display: grid; gap: 6px; align-content: start; min-width: 0; }
.po-tile { width: 100%; aspect-ratio: 1; object-fit: contain; border-radius: var(--pn-r); background: var(--pn-fill, rgba(127,127,127,.1));
  border: 1px solid var(--pn-line, rgba(127,127,127,.2)); display: grid; place-items: center; align-content: center; gap: 4px; box-sizing: border-box; }
.po-badshape .po-tile { border-color: var(--st-warn-line); }
.po-tileacts { display: flex; gap: 4px; justify-content: center; }
.po-adds { flex-wrap: wrap; gap: 8px; }
.po-add { min-height: 44px; }
.po-ticks { display: flex; flex-wrap: wrap; gap: 4px 18px; }
.po-ticks .pn-check, .po-part > .pn-check { min-height: 44px; }
.po-ticknote { margin: -6px 0 4px 28px; }
/* WHERE, ONE A ROW, EACH WITH ITS GLYPH (report 110, 4 Oct 2026: "Make this in two rows, with ig and fb glyphs"); a
   note under Instagram starts where its name does */
.po-where { flex-direction: column; flex-wrap: nowrap; align-items: flex-start; gap: 0; }
.po-where .po-platgl { margin-right: -1px; }
.po-where .po-ticknote { margin-left: 55px; }
.po-text { width: 100%; min-height: 96px; resize: vertical; font: inherit; box-sizing: border-box; }
.po-count { margin: 0; text-align: right; font-variant-numeric: tabular-nums; }
.po-sched { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; }
.po-tagadd { flex-wrap: wrap; gap: 8px; align-items: center; }
.po-tagadd .wa-pwin { flex: 1 1 140px; min-width: 0; }
.po-tagadd .wa-gl { min-height: 44px; }
.po-tags { margin: 6px 0 0; }
.po-tagrow { display: flex; flex-wrap: wrap; gap: 8px; align-items: end; }
.po-tagpick { min-height: 44px; }
.po-tagrow.po-on .po-tagpick { border-color: currentColor; }
.po-num { display: grid; gap: 2px; width: 84px; }
.po-num .wa-pwin { width: 100%; min-height: 44px; box-sizing: border-box; font-variant-numeric: tabular-nums; }
.po-tagphotos { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; margin-top: 8px; }
.po-tagphoto { position: relative; cursor: crosshair; line-height: 0; }
.po-tagphoto img { width: 100%; height: auto; border-radius: var(--pn-r); display: block; }
.po-dot { position: absolute; transform: translate(-50%, -50%); padding: 3px 7px; border-radius: var(--pn-r); font-size: 11px; line-height: 1.3;
  background: rgba(0,0,0,.72); color: #fff; white-space: nowrap; pointer-events: none; }
.po-pick { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px;
  max-height: min(60vh, 560px); overflow: auto; }
.po-pickbtn { display: block; width: 100%; min-height: 44px; padding: 0; border: 2px solid transparent; border-radius: var(--pn-r); background: none; cursor: pointer; }
.po-pickbtn img { width: 100%; aspect-ratio: 1; object-fit: contain; display: block; border-radius: var(--pn-r); }
.po-pickbtn[aria-pressed="true"] { border-color: var(--st-good); }
.po-pickbtn:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.po-foot { flex-wrap: wrap; gap: 8px; }
/* THE COLLABORATORS CHECKED (4 Oct 2026): a line under the box for each username, the account's own name beside a good
   tick when Instagram knows it, why not in the warning's colour when it does not; long words wrap on a 320px phone */
.po-whobox { display: grid; gap: 6px; min-width: 0; }
.po-who { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; min-width: 0; }
.po-whorow { display: flex; gap: 6px; align-items: flex-start; min-width: 0; font-size: 13px; line-height: 1.45; overflow-wrap: anywhere; opacity: .78; }
.po-whorow > span { min-width: 0; }
.po-whofound { opacity: 1; }
.po-whonot { opacity: 1; color: var(--st-warn); }
.po-whogl { width: 16px; height: 16px; flex: none; margin-top: 2px; color: var(--st-good); }
/* the line for the whole box (not connected, too many checks) the rows' size: .pn-sheet p would make it 14px */
.po-whobox > .po-whosaid { margin: 0; font-size: 13px; line-height: 1.45; }
@media (max-width: 520px) {
  .po-foot > .wa-btn, .po-foot > .wa-gl { min-width: 0; flex: 1 1 100%; }
  .po-mediarow { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .po-num { width: 72px; }
}
/* EVERY TARGET 44PX TO A FINGER (the review, 4 Oct 2026): a photo's Earlier, Later and Remove, and a tag's Remove, are
   the Studio's 36px icon buttons (.pn-glicon) elsewhere; on a touch screen they are 44px, a photo's three wrapping
   rather than running past a 320px phone's tile */
@media (pointer: coarse) {
  .po-tileacts { flex-wrap: wrap; }
  .po-tileacts .pn-glicon, .po-tagrow .pn-glicon { width: 44px; height: 44px; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   EVERY EMAIL TRACKED (5 Oct 2026, the operator: "add a full tracking/analytics for emails sent out, including team
   emails and quotes invoices gallery links etc"; assets/emails.js, lib/mailtrack.js). The Emails page: the period, the
   figures (the app's own .pn-figs), the table by kind scrolling inside its own box on a phone, the filters, every email
   a row that opens its timeline, and the timeline's rail in the sheet, a dot an event as Messages draws its messages.
   Light and dark from the app's own tokens and currentColor; every target 44px on a phone; nothing wider than a 320px
   phone; numbers in tabular figures. The classes are em-.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.em-head { justify-content: space-between; padding: 22px 0 6px; }
/* THE TITLE AND THE PERIOD ON ONE LINE (28 Oct 2026, the operator of Studio emails on his iPhone: "Fix this alignment"):
   the title's own space above and below moved onto the row, so the row centres the title and the Period on the same
   middle; the space round the head is as it was */

.em-head > .pn-h { margin: 0 auto 0 0; }
.em-period select { min-height: 40px; }
.em-for { margin: 0; display: flex; flex-wrap: wrap; gap: 8px 10px; align-items: center; overflow-wrap: anywhere; }
.em-for a { color: inherit; }
.em-note { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; justify-content: space-between; }
.em-note p { margin: 0; }
.em-guide { margin-top: 8px; }
.em-kindbox { overflow-x: auto; border: 1px solid var(--pn-line, rgba(127,127,127,.2)); border-radius: var(--pn-r); }
.em-kindbox:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.em-kinds { width: 100%; border-collapse: collapse; font-size: 13.5px; font-variant-numeric: tabular-nums; }
.em-kinds th, .em-kinds td { padding: 9px 12px; text-align: right; white-space: nowrap; border-bottom: 1px solid var(--pn-line, rgba(127,127,127,.2)); }
.em-kinds th:first-child { text-align: left; }
.em-kinds thead th { font-size: 10.5px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; opacity: .72; }
.em-kinds tbody th { font-weight: 500; }
.em-kinds tbody tr:last-child > * { border-bottom: 0; }
.em-filters { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.em-search { flex: 1 1 220px; max-width: 320px; }
.em-list { margin-top: 6px; padding: 0; list-style: none; }
.em-row { border-bottom: 1px solid var(--pn-line, rgba(127,127,127,.2)); padding: 4px 0 8px; }
.em-row:last-child { border-bottom: 0; }
.em-open { display: grid; gap: 4px; width: 100%; min-height: 44px; padding: 8px 6px; border: 0; border-radius: var(--pn-r); background: none; color: inherit;
  font: inherit; text-align: left; cursor: pointer; }
.em-open:hover { background: var(--pn-fill, rgba(127,127,127,.08)); }
.em-open:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.em-top { display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; justify-content: space-between; min-width: 0; }
.em-to { font-weight: 500; overflow-wrap: anywhere; min-width: 0; }
.em-when { font-variant-numeric: tabular-nums; }
.em-subj { overflow-wrap: anywhere; }
.em-chips { display: inline-flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 2px 0 0; }
.em-counts, .em-why { overflow-wrap: anywhere; }
.em-why { color: var(--st-bad); }
.em-about { display: flex; flex-wrap: wrap; gap: 0 12px; margin: 2px 6px 0; overflow-wrap: anywhere; }
.em-about a { position: relative; display: inline-flex; align-items: center; min-height: 24px; color: inherit; }
/* THE EMAIL AS IT WENT (report 174, 12 Oct 2026: "show a button to see preview of email sent"): each row's Preview, the
   app's own glyph button, under its words; an email from before the copies, a line saying so; and its sheet, the app's
   one email drawing (.pn-ewmail) under who it went to and when */
.em-acts { display: flex; flex-wrap: wrap; gap: 8px; margin: 6px 6px 0; }
.em-prev .pn-gl { width: 16px; height: 16px; }
.em-nocopy { margin: 4px 6px 0; overflow-wrap: anywhere; }
.em-copy { display: grid; gap: 8px; min-width: 0; }
.em-copy > p { margin: 0; overflow-wrap: anywhere; }
.em-copy .pn-ewmail { margin-top: 0; }
@media (pointer: coarse) { .em-prev { min-height: 44px; } }
.em-pager { margin-top: 12px; justify-content: center; gap: 12px; align-items: center; }
.em-pager .wa-gl { min-width: 96px; justify-content: center; }
.em-sum { display: grid; gap: 4px; }
.em-sum p { margin: 0; }
.em-subjbig { font: 300 20px/1.25 var(--font-display); letter-spacing: -.01em; overflow-wrap: anywhere; }
.em-h { margin: 16px 0 8px; font-size: 11px; font-weight: 500; letter-spacing: .16em; text-transform: uppercase; }
/* THE TIMELINE: a line down the left, a dot an event on it, filled for one the website counted */
.em-rail { list-style: none; margin: 0; padding: 0 0 0 22px; position: relative; }
.em-rail::before { content: ""; position: absolute; left: 7px; top: 6px; bottom: 6px; width: 1px; background: var(--pn-line, rgba(127,127,127,.3)); }
.em-ev { position: relative; padding: 2px 0 12px; }
.em-dot { position: absolute; left: -19px; top: 7px; width: 9px; height: 9px; border-radius: 50%; border: 1.5px solid currentColor; box-sizing: border-box; background: currentColor; }
.em-scan .em-dot { background: var(--pn-face, transparent); }
.em-ev-bounced .em-dot, .em-ev-not_sent .em-dot { color: var(--st-bad); }
.em-ev-complained .em-dot, .em-ev-delayed .em-dot { color: var(--st-warn); }
.em-ev-delivered .em-dot, .em-ev-opened .em-dot, .em-ev-clicked .em-dot { color: var(--st-good); }
.em-evbody p { margin: 0; overflow-wrap: anywhere; }
.em-evhead { display: flex; gap: 6px; align-items: center; }
.em-evhead b { font-weight: 600; }
.em-evhead .pn-gl { width: 16px; height: 16px; flex: none; }
.em-scan .em-evhead { opacity: .7; }
.em-links { margin: 0; padding-left: 20px; font-size: 13.5px; line-height: 1.55; overflow-wrap: anywhere; }
/* the line saying opens are a guide, apart from the list over it (the real-browser look, 5 Oct 2026: it sat against it) */
.em-links + .pn-note, .em-rail + .pn-note { margin-top: 12px; }
.em-hookurl { display: block; margin-top: 4px; }
@media (max-width: 520px) {
  .em-filters > .pn-glfilter { flex: 1 1 calc(50% - 4px); min-width: 0; }
  .em-filters select { width: 100%; }
  /* on a phone the period keeps its own width at the row's right, its words "Last 30 days" saying what it is */
  .em-head > .em-period { flex: 0 0 auto; margin-left: auto; }
  .em-head .em-periodw { display: none; }
  .em-search { flex: 1 1 100%; max-width: none; }
  .em-period select { min-height: 44px; }
  .em-about a::before { content: ""; position: absolute; inset: -10px 0; }
  .em-pager .wa-gl { min-height: 44px; flex: 1 1 0; min-width: 0; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   BENTO PAGES AS ONE ORDINARY PAGE (24 Oct 2026, the operator: "remove snap function on studio, and page dots on the
   side"). The Studio snap, which paged the Desk, Website Analytics (its Summary) and Studio emails a screen at a time
   with a column of page dots at the right, is gone: those pages scroll as any page does, on a phone and a computer, and
   Report a problem is in its own place. What stays is their layout: each page of tiles (.pn-bpage, a bento grid) under
   the last with the grid's own gap, and a part of one (.pn-bpart) its own two column grid on a phone, where the small
   figures pair up and everything else takes both columns, and nothing of its own from 560px, where its tiles sit on
   the page's grid. Its marks went with it (data-pn-snap, data-pn-page, data-pn-part, data-pn-split, data-pn-long).
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
.pn-bpage + .pn-bpage { margin-top: 14px; }
@media (max-width: 559.98px) {
  .pn-bpage > .pn-bpart { grid-column: 1 / -1; display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; align-content: start; min-width: 0; }
  .pn-bpart > :not(.pn-tfig) { grid-column: 1 / -1; }
}
@media (min-width: 560px) { .pn-bpage > .pn-bpart { display: contents; } }
.pn-bpage > .pn-bpart[hidden] { display: none; }
[data-pn-quiet]:focus { outline: none; }

/* THE BENTO GRID (design D of the four "Studio dashboards", the operator, 9 Oct 2026: "go D bento grid"; the pages of
   Website Analytics, Emails and the Desk are built from it): "12 columns with a 14px gap. A small tile is 3 columns, a
   double is 6, a table is all 12; the big tile is 6 wide and two rows tall. Below 1100px the grid folds to 2 columns:
   the big tile and tables take both, small tiles pair up. Below 560px it is one column, except the small figures, which
   stay two by two." A tile is the app's card (.wa-card.pn-card) with .pn-btile (never .pn-tile, which is a photobooth night's session
   tile) and its span (.pn-t6, .pn-t12, .pn-tbig,
   .pn-ttall; .pn-tfig marks a small figure); its label the Studio's level 2 heading untouched, with its glyph; its
   number the display face at 300, 64 px big and 34 px small. Good, warn and bad only in a chip; a number never
   coloured; a change against the range before is a neutral chip with an arrow (.pn-badge.pn-off.pn-tchg) */
.pn-bento { display: grid; grid-template-columns: repeat(12, minmax(0, 1fr)); gap: 14px; align-content: start; grid-auto-flow: row dense; }
.pn-bento > * { min-width: 0; }
.pn-bhead { grid-column: 1 / -1; min-width: 0; }
.pn-btile { grid-column: span 3; display: flex; flex-direction: column; min-width: 0; margin: 0; }
.pn-btile.pn-t6 { grid-column: span 6; }
.pn-btile.pn-t12 { grid-column: 1 / -1; }
.pn-btile.pn-tbig { grid-column: span 6; grid-row: span 2; }
.pn-btile.pn-ttall { grid-row: span 2; }
@media (max-width: 1099.98px) {
  .pn-bento { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pn-btile { grid-column: span 1; }
  .pn-btile.pn-t6, .pn-btile.pn-t12, .pn-btile.pn-tbig { grid-column: 1 / -1; grid-row: auto; }
  .pn-btile.pn-ttall { grid-row: auto; }
}
@media (max-width: 559.98px) { .pn-btile:not(.pn-tfig) { grid-column: 1 / -1; } }

/* a tile's parts */
.pn-thead { display: flex; align-items: center; gap: 8px; min-height: 24px; margin: 0 0 6px; }
.pn-thead > h2, .pn-thead > h3 { display: flex; align-items: center; gap: 8px; margin: 0; min-width: 0; }
.pn-thead .pn-tkg { width: 17px; height: 17px; flex: none; }
.pn-thead > .pn-tkr { margin-left: auto; font-size: 12px; color: var(--pn-t-soft); white-space: nowrap; }
.pn-thead > .pn-badge, .pn-thead > .wa-gl { margin-left: auto; }
.pn-tnrow { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 10px; margin: 6px 0 0; }
/* (the display face through the font shorthand, as the tests of the blocks above this one ask of every rule after them) */
.pn-tn { font: 300 34px/1.05 var(--font-display); letter-spacing: 0; font-variant-numeric: tabular-nums; color: var(--pn-t-ink); }
.pn-btile.pn-tbig .pn-tn { font-size: 64px; line-height: 1; }
.pn-tnw { font-size: 14px; color: var(--pn-t-soft); }
.pn-told { margin-left: auto; font-size: 12px; color: var(--pn-t-soft); white-space: nowrap; }
.pn-tfoot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-top: auto; padding-top: 12px; }
.pn-tsplit { display: grid; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); margin-top: auto; padding-top: 12px; }
.pn-tsplit > span { display: grid; gap: 1px; padding: 0 10px; border-left: 1px solid var(--pn-line); min-width: 0; }
.pn-tsplit > span:first-child { padding-left: 0; border-left: 0; }
.pn-tsplit b { font-size: 18px; font-weight: 500; font-variant-numeric: tabular-nums; }
.pn-tsplit i { font-style: normal; font-size: 10px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--pn-t-soft); }
.pn-tprog { margin-top: auto; padding-top: 12px; }
.pn-tprogl { display: flex; justify-content: space-between; gap: 8px; margin: 0 0 6px; font-size: 12px; color: var(--pn-t-soft); font-variant-numeric: tabular-nums; }
.pn-tprogt { display: block; height: 8px; overflow: hidden; border-radius: var(--pn-r); background: rgba(255,255,255,.07); }
.pn-tprogt > i { display: block; width: 0; height: 100%; border-radius: var(--pn-r); background: var(--beige); }
.pn-tchg .pn-gl { width: 12px; height: 12px; flex: none; }
.pn-tnote { margin: 8px 0 0; font-size: 12px; line-height: 1.5; color: var(--pn-t-soft); }
:root[data-app][data-theme="light"] .pn-tprogt { background: var(--pn-fill); }
:root[data-app][data-theme="light"] .pn-tprogt > i { background: var(--pn-ink); }
@media (max-width: 559.98px) { .pn-tn { font-size: 28px; } .pn-btile.pn-tbig .pn-tn { font-size: 48px; } }

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   WEBSITE ANALYTICS, BENTO PAGES (PART 1)
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
/* The Summary of Website Analytics as five pages of tiles, one ordinary page since 24 Oct 2026 (assets/website.js
   drawVisits; SHARE-CLOUD.md 63.2). Only what the tiles need beyond the bento grid and its pages above: the head's row from 1100 px (the controls
   at the right of the heading, wrapping under it when there is no room), the Visitors tile's legend, the chart's
   gridlines and its readout box, the thin bar beside a page's visitors, Copy the link at its tile's foot, and the small
   tiles' splits and bars where a tile is narrow, and a label's chip under its words when the two do not fit on a line. Each tile is a container (its own width decides, never the window's,
   as a tile is narrow both at 1100 px beside the side menu and on a phone): a bar list puts its words over its bar
   below 360 px of tile, and the Enquiries split is three rows below 250 px. Light and dark from the app's tokens. */
.pn-wst { container-type: inline-size; }
.pn-wst .pn-thead { flex-wrap: wrap; row-gap: 6px; }
.pn-wst .pn-thead > h2 > span { min-width: 0; overflow-wrap: break-word; }
@media (min-width: 1100px) {
  .pn-wsbhead { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 0 24px; }
  .pn-wsbhead > .pn-wshtext { flex: 1 1 320px; min-width: 0; }
  .pn-wsbhead > .pn-wsctl { flex: 0 1 auto; margin-left: auto; }
  .pn-wsbhead > .pn-wsctl .pn-gtabs { flex: none; }
  .pn-wsbhead > .pn-wswarn { flex: 1 1 100%; }
}
/* the Visitors tile: the legend, the chart under it and the readout box */
.pn-wslegend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 10px 0 8px; padding: 0; list-style: none; font-size: 12px; line-height: 1.5; color: var(--pn-t-soft); }
.pn-wslegend li { display: inline-flex; align-items: center; gap: 6px; }
.pn-wslg { display: inline-block; flex: none; width: 16px; height: 0; border-top: 2px solid var(--beige); }
.pn-wslg.pn-wslgb { border-top: 1.5px dashed rgba(242,239,232,.42); }
.pn-wslg.pn-wslgd { width: 8px; height: 8px; border: 0; border-radius: 50%; background: var(--moon); }
.pn-wsvis .pn-wschart { margin-top: auto; }
.pn-wsgrid { stroke: rgba(255,255,255,.06); stroke-width: 1; }
.pn-wsread { margin: 10px 0 0; padding: 8px 12px; border-radius: var(--pn-r); background: rgba(0,0,0,.22); font-size: 13px; line-height: 1.45; font-variant-numeric: tabular-nums; color: var(--pn-t-ink); }
/* a small figure's split: columns where the tile has room, else a row each (the number, then its words) */
.pn-wst .pn-tsplit > span { align-content: start; }
.pn-wst .pn-tsplit i { overflow-wrap: anywhere; }
@container (max-width: 249.98px) {
  .pn-wst .pn-tsplit { grid-auto-flow: row; row-gap: 4px; }
  .pn-wst .pn-tsplit > span { display: flex; flex-wrap: wrap; align-items: baseline; gap: 0 8px; padding: 0; border-left: 0; }
  .pn-wst .pn-tsplit b { font-size: 16px; }
}
/* a bar list in a narrow tile: its words and its figure over its bar, as on a phone */
@container (max-width: 359.98px) {
  .pn-wst .pn-wsbar { grid-template-columns: minmax(0, 1fr) auto; }
  .pn-wst .pn-wsbart { grid-column: 1 / -1; grid-row: 2; }
}
.pn-wst.pn-wsforms .pn-wsfunnel { margin-top: 4px; }
.pn-wst.pn-wsforms .pn-tnote { margin-top: auto; padding-top: 12px; }
/* Links for your ads: its form fills the tile, Copy the link at the foot */
.pn-wst.pn-wscamp .pn-wscampf { display: flex; flex-direction: column; flex: 1 1 auto; }
.pn-wst.pn-wscamp .pn-wscampf > .pn-row { order: 1; margin-top: auto; padding-top: 12px; }
/* the thin bar beside a page's visitors, scaled to the most visited, for the eye alone */
.pn-wspvis { white-space: nowrap; }
.pn-wspv { display: inline-block; min-width: 3em; }
.pn-wspbar { display: inline-block; width: 96px; height: 6px; margin-left: 12px; overflow: hidden; border-radius: var(--pn-r); background: rgba(255,255,255,.07); vertical-align: middle; }
.pn-wspbar > i { display: block; width: 0; height: 100%; border-radius: var(--pn-r); background: var(--beige); }
/* on a phone the table keeps its room for the pages' names, as before, and the bar goes */
@media (max-width: 559.98px) { .pn-wspbar { display: none; } }
/* a page's name is never broken inside a word on a phone ("Book photograph y" at 390 px): the table scrolls sideways in its
   box instead, as it does for its other columns */
@media (max-width: 559.98px) { .pn-wspages .pn-glname b { overflow-wrap: normal; } }
/* the closing note, under the last tile */
.pn-wsclose { margin: 0; }
:root[data-app][data-theme="light"] .pn-wslg { border-top-color: var(--pn-ink); }
:root[data-app][data-theme="light"] .pn-wslg.pn-wslgb { border-top-color: rgba(36,31,25,.36); }
:root[data-app][data-theme="light"] .pn-wslg.pn-wslgd { background: #d99a1c; }
:root[data-app][data-theme="light"] .pn-wsgrid { stroke: rgba(36,31,25,.08); }
:root[data-app][data-theme="light"] .pn-wsread { background: var(--pn-fill); }
:root[data-app][data-theme="light"] .pn-wspbar { background: var(--pn-fill); }
:root[data-app][data-theme="light"] .pn-wspbar > i { background: var(--pn-ink); }


/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   STUDIO EMAILS, BENTO PAGES (PART 2). The Inbox's fourth box at /emails since report 173 (12 Oct 2026: "this should be
   under the inbox, under studio or something"): its pages go in its main column (.ib-emmain), beside the Inbox's boxes
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
/* The page (assets/emails.js): the main column holds three pages of tiles (.pn-bpage), each a bento grid (.pn-bento,
   THE BENTO GRID above), one ordinary page since 24 Oct 2026: Emails, the first (the head, Sent the big tile, Bounced
   and Marked as spam small, Not sent double; on a phone two parts, the head and Sent, then the rest), By kind, and Every email, the list's tile with its
   filters and pager. Every name here is .em-; light and dark from the app's own tokens; no level's type restyled. */
.em-pg[hidden] { display: none; }
/* the head's Period: its label shown beside the select (D), which keeps its own name */
.em-period { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.em-periodw { flex: none; font-size: 12px; color: var(--pn-t-soft); }
/* the row across the first page: who these are about, and the setting-up note */
.em-bhead { display: grid; gap: 10px; }
.em-bhead .wa-empty { margin: 0; }
/* SENT: four bars on one scale (D: "Sent is the big tile and carries Delivered, Opened and Clicked as one bar chart"),
   each a label, a track with its fill (its width from script, emails.js sizeBars) and its own words; no axis */
.em-bars { list-style: none; margin: 16px 0 0; padding: 0; display: grid; grid-template-columns: 76px minmax(0, 1fr) max-content; gap: 10px; }
.em-bar { grid-column: 1 / -1; display: grid; grid-template-columns: 76px minmax(0, 1fr) minmax(0, max-content); align-items: center; gap: 4px 10px; font-size: 13px; line-height: 1.35; }
/* the four tracks one length, lined up under each other whatever each bar's words (the words' column is the widest's) */
@supports (grid-template-columns: subgrid) { .em-bar { grid-template-columns: subgrid; } }
.em-barl { color: var(--pn-t-soft); }
.em-bart { display: block; height: 12px; overflow: hidden; border-radius: var(--pn-r); background: rgba(255,255,255,.07); }
.em-bart > i, .em-kbar > i { display: block; width: 0; height: 100%; border-radius: inherit; background: var(--pn-y); }
.em-barw { font-variant-numeric: tabular-nums; white-space: nowrap; }
.em-tsent .em-guide { margin-top: auto; padding-top: 14px; }
/* BOUNCED and NOT SENT: the period's newest, a line each, a press opening its timeline; hairlines between them */
.em-srows { list-style: none; margin: 10px 0 0; padding: 0; }
.em-srows > li + li { border-top: 1px solid var(--pn-line); }
.em-srow { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: baseline; gap: 2px 10px; width: calc(100% + 12px); min-height: 40px;
  margin: 0 -6px; padding: 8px 6px; border: 0; border-radius: var(--pn-r); background: none; color: inherit; font: inherit; font-size: 13.5px;
  text-align: left; cursor: pointer; }
.em-srow:hover { background: var(--pn-fill, rgba(127,127,127,.08)); }
.em-srow:focus-visible { outline: 2px solid currentColor; outline-offset: 2px; }
.em-ssubj { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.em-sk { font-size: 12px; color: var(--pn-t-soft); white-space: nowrap; font-variant-numeric: tabular-nums; }
.em-srow .em-why { grid-column: 1 / -1; font-size: 12px; overflow-wrap: anywhere; }
@media (pointer: coarse) { .em-srow { min-height: 44px; } .em-showns { min-height: 44px; } }
/* BY KIND: a bar beside each kind's Sent, scaled to the busiest kind */
.em-tkinds .em-kindbox { margin-top: 4px; }
.em-kinds thead th:nth-child(2), .em-kinds td.em-ksent { text-align: left; }
.em-kn { display: inline-block; min-width: 3ch; text-align: right; }
.em-kbar { display: inline-block; width: 120px; height: 6px; margin-left: 10px; overflow: hidden; vertical-align: middle; border-radius: var(--pn-r); background: rgba(255,255,255,.07); }
/* EVERY EMAIL: the filters in one row inside the tile, the search taking the rest of it */
.em-tlist .em-filters { margin-top: 4px; }
.em-tlist .em-search { max-width: none; }
.em-tlist .em-empty { margin: 8px 0 0; max-width: none; }
/* on a phone Kind and State share their row inside the tile, each dropdown (the app's own button for the select) as wide
   as its half and no wider, so a 320 px phone keeps both inside the card */
@media (max-width: 520px) { .em-tlist .em-filters > .pn-glfilter > .wa-pwin, .em-tlist .em-filters > .pn-glfilter > .pn-sfold > .wa-pwin { width: 100%; min-width: 0; } }
:root[data-app][data-theme="light"] .em-bart, :root[data-app][data-theme="light"] .em-kbar { background: var(--pn-fill); }
:root[data-app][data-theme="light"] .em-bart > i, :root[data-app][data-theme="light"] .em-kbar > i { background: var(--pn-ink); }
/* from 1100 px a row reads across in three columns (D): its words, its chips, when */
@media (min-width: 1100px) {
  .em-kbar { width: 180px; }
  .em-open { grid-template-columns: minmax(0, 1fr) auto minmax(150px, auto); grid-template-areas: "to chips when" "subj chips when" "counts chips when" "why chips when";
    column-gap: 20px; row-gap: 3px; }
  .em-open .em-top { display: contents; }
  .em-open .em-to { grid-area: to; }
  .em-open .em-when { grid-area: when; text-align: right; }
  .em-open .em-subj { grid-area: subj; }
  .em-open .em-chips { grid-area: chips; align-self: start; margin: 0; }
  .em-open .em-counts { grid-area: counts; }
  .em-open .em-why { grid-area: why; }
}
/* a small figure on a phone is half the width: a bounced email's kind goes under its subject */
@media (max-width: 559.98px) {
  .em-tbounce .em-srow { grid-template-columns: minmax(0, 1fr); }
  /* side by side, the two figures on one line (3 Nov 2026, the Studio's UX pass): Marked as spam's label takes two
     lines at half a phone's width and Bounced's one, so each label keeps two lines' room and the Nones line up */
  .em-tile.pn-tfig > .pn-thead { min-height: 32px; }
  .em-bars { grid-template-columns: 62px minmax(0, 1fr) max-content; gap: 8px; }
  .em-bar { grid-template-columns: 62px minmax(0, 1fr) minmax(0, max-content); gap: 4px 8px; font-size: 12px; }
  .em-kbar { width: 80px; }
}
@supports (grid-template-columns: subgrid) { @media (max-width: 559.98px) { .em-bar { grid-template-columns: subgrid; } } }
/* the narrowest phones: a bar's words under its track, so the track keeps its length */
@media (max-width: 359.98px) {
  .em-bars { grid-template-columns: 62px minmax(0, 1fr); }
  .em-bar, .em-bar:nth-child(n) { grid-template-columns: 62px minmax(0, 1fr); }
  .em-barw { grid-column: 2; }
}

/* ════════════════════════════════════════════════════════════════════════════════════════════════════════════
   ONE SIZE A CONTROL (15 Oct 2026, the owner: "fix all elements like text boxes, chips, badges, buttons, drop downs, all
   interactive element ... particular point, chip sizing"; booth-app/docs/SHARE-CLOUD.md section 68). Every control in the
   Studio has one of six heights: a count 18, a chip 24, a tag 28, S 32 (44 to a thumb), M 40 (44 to a thumb) and L 46.
   Corners are 8px on a control, 11px on a pill, round on a chip, a tag and a count, 12px on a card or a list. Each chip
   is one of seven families, one size each on every page, in every list and at every width, and no list shrinks one:
   the state chip (.pn-badge, its wrap version below), the label chip (.pn-lchip), the count (.pn-count), the pill
   (.pn-pill, THE STUDIO'S ORDER, level 3), the tag (.pn-tag2), the press chip (.pn-pchip) and a label on a photo. A
   chip is never pressed: anything pressed is a pill, a press chip or a button. The desk keeps its own copies
   (desk/assets/app.css), held equal by test/studio-ui-sizes.test.mjs. Light and dark are the same size everywhere.
   ════════════════════════════════════════════════════════════════════════════════════════════════════════════ */
/* the words of a placeholder, and of a day outside the month in the calendar: 4.5:1 or better on a box in both themes */
:root[data-app] { --pn-ph: rgba(242,239,232,.52); }
:root[data-app][data-theme="light"] { --pn-ph: rgba(36,31,25,.64); }

/* THE LABEL CHIP: a name, a time or a kind in sentence case (a service, a shift, the Video label, New, You). 24px, round,
   12px at 500; each element keeps its own colours (the service's badge, .pn-jbsv, joins by name: its markup is pinned) */
.pn-lchip, .pn-jbsv { display: inline-flex; align-items: center; gap: 4px; box-sizing: border-box; max-width: 100%; height: 24px; padding: 0 9px;
  border-width: 1px; border-style: solid; border-radius: var(--pn-r); font-size: 12px; font-weight: 500; letter-spacing: 0; line-height: 1; text-transform: none;
  white-space: nowrap; }
:where(.pn-lchip) { border-color: var(--pn-p-line); background: var(--pn-p-hover); color: inherit; }
:is(.pn-lchip, .pn-jbsv):where(:has(> .pn-gl:first-child)) { padding-left: 7px; }
:is(.pn-lchip, .pn-jbsv) .pn-gl { width: 12px; height: 12px; flex: none; }
.pn-lchip[hidden] { display: none; }

/* THE COUNT: ONE BADGE (9 Nov 2026, the operator, of a yellow square "1" and a grey circle "7" side by side): a number in
   an 18px square, 10.5px at 600 in tabular figures, yellow with the ink's figure everywhere: the header, the side menu, a
   heading, a fold, a filter and a pick (a pick's own count is drawn with the pills, above) */
.pn-count, .pn-jbn, .pn-glfn, .cw-formern, .ib-cdocsn, .pr-cnt, .dk-wfoldn, .dk .dk-donefold summary b, .dk .paid summary b, .dk-views b { display: inline-grid; place-items: center; box-sizing: border-box; height: 18px; min-width: 18px;
  padding: 0 5px; border: 0; border-radius: var(--pn-r); background: var(--pn-y); color: var(--pn-on-y); font-size: 10.5px; font-weight: 600; letter-spacing: 0; line-height: 18px; text-align: center;
  text-transform: none; font-variant-numeric: tabular-nums; }
:is(.pn-count, .pn-jbn, .pn-glfn, .cw-formern, .ib-cdocsn, .pr-cnt)[hidden] { display: none; }
.pr-cnt:empty { display: none; }
.dk-views b { flex: none; }

/* THE PRESS CHIP: a small press carrying a name, a date or a link inside a line of words (open an email, put in a field,
   Draft with Claude, Attach from the job, a suggested contact, Exact wording). S: 32px, 44 to a thumb, 8px corners */
.pn-pchip { display: inline-flex; align-items: center; gap: 6px; box-sizing: border-box; max-width: 100%; min-width: 0; height: var(--pn-h-act); padding: 0 10px;
  border-width: 1px; border-style: solid; border-radius: var(--pn-r); font: inherit; font-size: 12px; font-weight: 500; letter-spacing: 0; line-height: 1.2;
  text-transform: none; text-decoration: none; white-space: nowrap; cursor: pointer; }
:where(.pn-pchip) { border-color: var(--pn-p-line); background: rgba(255,255,255,.07); color: inherit; }
:where(:root[data-app][data-theme="light"] .pn-pchip) { border-color: var(--pn-line); background: var(--pn-fill); }
@media (hover: hover) {
  :where(.pn-pchip:not(:disabled)):hover { background: rgba(255,255,255,.13); }
  :where(:root[data-app][data-theme="light"] .pn-pchip:not(:disabled)):hover { background: var(--pn-fill-hover); }
}
.pn-pchip :is(.pn-gl, svg) { width: 16px; height: 16px; flex: none; }
.pn-pchip > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
/* off is half strength, as every button (an element's own off look, as Draft with Claude's, wins); hidden is gone */
:where(.pn-pchip:is(:disabled, [aria-disabled="true"])) { opacity: .5; cursor: default; }
.pn-pchip[hidden] { display: none; }

/* On, said in a state chip, is the chip's own default tone, never the app's filled on-state (.pn-on) */
.pn-badge.pn-on { background: rgba(244,255,106,.12); color: var(--moon); border-color: rgba(244,255,106,.28); font-weight: 400; }
:root[data-app][data-theme="light"] .pn-badge.pn-on { background: rgba(79,78,13,.1); color: var(--pn-olive); border-color: rgba(79,78,13,.28); }
/* a watermark's Type and Photos are the pills, close under their label */
.pn-pills.pn-seg { margin-top: 6px; }

/* THE STATE CHIP THAT MAY WRAP: a booking's state, a plan's figure and the keep chip on a gallery card, whose words can
   run to two lines. The same words; its height grows from 24px */
.pn-badge.pn-bkst, .pn-badge.mn-plchip, .pn-gcw .pn-badge:is(.pn-keepchip, .pn-keepgone) { height: auto; min-height: 24px; max-width: 100%; padding: 3px 9px;
  line-height: 1.3; white-space: normal; text-align: left; }

/* L: the one big press on a page a team member walks through on their phone, and Compose. 46px, 0 22px, 8px corners */
:root[data-app] :where(.pn-wrap, .pn-sheet) .wa-btn:not(.wa-sm, .wa-open), :root[data-app] .wa-btn.ib-composebtn { height: var(--pn-h-main); min-height: var(--pn-h-main);
  padding: 0 15px; gap: 8px; border-radius: var(--pn-r); font-size: 11px; font-weight: 500; letter-spacing: .06em; }
:root[data-app] :where(.pn-wrap, .pn-sheet) .wa-btn:not(.wa-sm, .wa-open) :is(.pn-gl, svg), :root[data-app] .wa-btn.ib-composebtn :is(.pn-gl, svg) { width: 16px; height: 16px; }
:root[data-app] .cw .cw-nav .wa-gl { height: var(--pn-h-main); padding: 0 15px; font-size: 11px; }

/* S GLYPHS: a row's More inside a list (M, 40px, is a page head's, a toolbar's and a sheet's close) */

/* A TEXT AREA is the box over several lines: its first line where a box's words are, at least 96px unless its own rule
   says more, the box's edge, ground, focus and words */
:where(:root[data-app]) textarea.wa-pwin { height: auto; padding: 10px 16px; line-height: 1.5; resize: vertical; }
:where(:root[data-app] textarea.wa-pwin) { min-height: 96px; }

/* no browser spinners on a number anywhere in the Studio */
:root[data-app] input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
:root[data-app] input[type="number"]::-webkit-inner-spin-button, :root[data-app] input[type="number"]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }

/* THE KEYBOARD'S RING is the theme's (above), 2px outside every Studio control; a row that fills its list or menu keeps its
   own ring drawn 2px inside (their rules outrank this one) */
:where(:root[data-app]) :focus-visible { outline-offset: 2px; }

/* the search box in a filter row on a computer with a mouse is the compact box, as its dropdowns are (ONE FILTER) */
@media (pointer: fine) and (min-width: 980px) {
  :root[data-app] .pn-glfilters > .pn-glsearch:not(textarea) { padding: 0 12px; font-size: 12.5px; }
}

/* a gallery's sections as pills below 980px keep a pill's gap and glyph */
@media (max-width: 979px) {
  .pn-gside .pn-gsetlink { gap: 7px; }
  .pn-gside .pn-gsetlink .pn-gl { width: 16px; height: 16px; }
}

/* A GALLERY'S TOP ROW on the narrowest phones: the state, More, Preview and Share keep their one row, Preview and Share their
   glyph alone (M's square), the word kept for a screen reader as .wa-sr keeps one */
.pn-gtop .pn-gtopb .pn-gl { width: 16px; height: 16px; flex: none; }
@media (max-width: 399.98px) {
  .pn-gtop .pn-gtopb { gap: 0; min-width: 40px; padding: 0 12px; }
  .pn-gtop .pn-gtopw { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
}
@media (max-width: 399.98px) and (pointer: coarse) { .pn-gtop .pn-gtopb { min-width: 44px; padding: 0 14px; } }

/* TOUCH: everything pressed is at least 44 by 44 to a thumb (links inside running words aside); a control drawn small
   reaches 44 round itself */
@media (pointer: coarse) {
  .pn-switch::before { content: ""; position: absolute; inset: -10px -1px; }
  .pn-range input { min-height: 44px; }
  .pn-linkbtn, .pn-jbsort { min-height: 44px; }
  .pn-tagin { height: 36px; }
  :is(.pn-row, .pn-jbname, .pn-clshtop) > a.pn-jblink, .pn-m > a.pn-jblink:first-child, .mn-alllink, .ib-linkto { display: inline-flex; align-items: center;
    min-height: 44px; }
  /* a client's phone or email in a card's facts or a list's cell: still a line of words, its reach 44px by padding that
     takes no room (an inline link's own padding is pressed, and moves nothing) */
  .pn-jbfact > b > a.pn-jblink:only-child, :is(.pn-t, td) > a.pn-jblink:only-child { padding-block: 12px; }
  /* a booking's Change these on the job, alone in its note under the facts: the same reach, by padding that moves nothing */
  .pn-jbcard > .pn-note > a[data-nav]:only-child { padding-block: 14px; }
  .pn-clmailrow { display: flex; flex-direction: column; justify-content: center; min-height: 44px; }
  /* a list row's name, 44px tall to a thumb (a job's Quotes, Invoices and Files, Photographers): its underline stays under
     its words, where the list's own border underline sat at the foot of the 44px, 12px under them (the UX pass, 3 Nov
     2026); the figure at the right of a quote's or an invoice's row is level with the name */
  .pn-list .pn-m > a.pn-jblink:first-child { border-bottom: 0; text-decoration-line: underline; text-underline-offset: 3px;
    text-decoration-color: currentColor; }
  :root[data-app][data-theme="light"] .pn-list .pn-m > a.pn-jblink:first-child { text-decoration-color: currentColor; }
  .mn-row > .mn-amt { display: inline-flex; align-items: center; min-height: 44px; }
}
@media (max-width: 720px) and (pointer: coarse) {
  /* the Jobs list's name: a tap on the middle of its cell lands on the link */
  .pn-jbtab .pn-glname > a { padding-block: 10px; margin-block: -10px; }
}

/* THE STUDIO'S REPORTER (its section above is copied whole into the website's report.css, so the Studio's own sizes are
   here, on :root[data-app] lines): its dropdown and its note are the app's box */
:root[data-app] .pn-ddbtn.wa-pwin.pn-rpddbtn { padding: 0 16px; font-size: 14px; }
:root[data-app] textarea.wa-pwin.pn-rpnote { padding: 10px 16px; font-size: 14px; }
@media (pointer: coarse), (max-width: 760px) {
  :root[data-app] .pn-ddbtn.wa-pwin.pn-rpddbtn, :root[data-app] textarea.wa-pwin.pn-rpnote { font-size: 16px; }
}
@media (pointer: coarse) { :root[data-app] .pn-rppicbtn { min-height: 44px; } }
/* EVERY PRESS SHOWN (28 Oct 2026, the operator: "Globally button presses need to be more visibly shown, including inbox
   refresh button"). While a finger or the mouse is down on anything pressable in the app (a button, a link that looks like
   one, a fold's row, a side menu item, a tick's label), it shrinks a little and darkens in dark or lightens in light, by a
   wash over its own fill (an inset shadow, so its words stay on top) and `scale`, which adds to any transform it has.
   iOS shows :active only with a touch listener on the page (frame.js). Nothing disabled moves. */
:root[data-app] { --pn-press: rgba(255,255,255,.1); }
:root[data-app][data-theme="light"] { --pn-press: rgba(36,31,25,.07); }
:root[data-app] :is(button, [role="button"], [role="tab"], [role="switch"], a.wa-btn, a.wa-gl, a.wa-pill, a.pn-sideitem, summary, label.pn-check, label.pn-radio):not(:disabled):not([aria-disabled="true"]) {
  -webkit-tap-highlight-color: transparent;
}
:root[data-app] :is(button, [role="button"], [role="tab"], [role="switch"], a.wa-btn, a.wa-gl, a.wa-pill, a.pn-sideitem, summary, label.pn-check, label.pn-radio):not(:disabled):not([aria-disabled="true"]):active {
  scale: .98; box-shadow: inset 0 0 0 100vmax var(--pn-press); transition: scale .05s ease, box-shadow .05s ease;
}
/* a row as wide as its card shrinks less, so it never looks as if it jumps; and a long press never picks out its words
   (29 Oct 2026, the operator, of a pressed row of the Inbox's Find a lead, job or client: "that's too much") */
:root[data-app] :is(summary, label.pn-check, label.pn-radio, .pn-jbfrow, a.pn-sideitem, .ib-pickrow, .ms-pickrow):not(:disabled):active { scale: .995; }
:root[data-app] :is(button, [role="button"], [role="tab"], a.wa-btn, a.wa-gl, a.wa-pill) { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
@media (prefers-reduced-motion: reduce) {
  :root[data-app] :is(button, [role="button"], [role="tab"], [role="switch"], a.wa-btn, a.wa-gl, a.wa-pill, a.pn-sideitem, summary, label.pn-check, label.pn-radio):active { scale: none; }
}
/* A REFRESH WORKING: its glyph turns while it looks (the Inbox's Check for new mail, inbox.js) */
:root[data-app] [data-spinning="true"] svg { animation: wa-spin .8s linear infinite; }
/* and coloured while it looks, the studio's yellow behind the turning glyph in either theme (28 Oct 2026: "colour the refreshing
   when spinning so it's clear it's in progress") */
:root[data-app] .ib-tools .wa-gl.ib-tool[data-spinning="true"] { background: var(--moon); border-color: var(--moon); color: #241f19; opacity: 1; }
@media (prefers-reduced-motion: reduce) { :root[data-app] [data-spinning="true"] svg { animation: none; opacity: .5; } }
/* NO BLUR ON A CARD OR A BUTTON, IN EITHER THEME (28 Oct 2026, the operator, of the Inbox's list on his iPhone torn part way
   down with the page showing through, and its foot left blank: "Why does it sometime do this"). smp.css gives every
   .wa-card and .wa-gl a frosted backdrop-filter, and the dark theme took it off long ago; the light theme never did, so a
   page of cards and buttons was a stack of blur layers WebKit had to draw again as the page moved, and while it caught up
   on a quick flick it showed bare page in their place. Every face here is solid already, so nothing looks different. The
   upload dock and the side menus, which float over the page, lose theirs too. */
:root[data-app] :is(.wa-card, .wa-gl, .wa-pill, .wa-tile, .pn-dock, .pn-menu) { backdrop-filter: none; -webkit-backdrop-filter: none; }
/* THE ROW'S TAGS AS SMALL WORDS (28 Oct 2026, the operator, of EMAIL in its pill on an Inbox row: "Make the badges smaller,
   no pill, small text left align"): on a row of the list, the channel, Job, Lead or Client, Team and the rest are small
   spaced capitals in their own colour, no fill, no edge, no padding, starting at the words' left edge. Everywhere else
   (the reading pane's head, the desk) the badge keeps its pill. */
:root[data-app] .ib-row .ib-chips { gap: 4px 12px; margin-top: 4px; }
:root[data-app] .ib-row .ib-chips .pn-badge { height: auto; padding: 0; border: 0; border-radius: 0; background: none; font-size: 10px;
  letter-spacing: .14em; line-height: 1.4; }
:root[data-app] .ib-row .ib-chips .pn-badge.pn-off { color: var(--ib-soft); }
/* EMAIL in the Inbox's own colour, as Instagram and Facebook are in theirs (28 Oct 2026: "Email chip in the emails should be yellow"): the yellow on dark, its olive on light, where yellow words on white could not be read */
:root[data-app] .ib-row .ib-chips .pn-badge.ib-mailchip { color: var(--ib-mark); }
:root[data-app][data-theme="light"] .ib-row .ib-chips .pn-badge.ib-mailchip { background: none; border: 0; color: var(--ib-mark); }

/* EVERY LIST'S SEARCH FOLDED ON A PHONE (29 Oct 2026, the operator: "Update all search fields globally on studio to match
   the email search (button then expand upon click etc, space saving design on mobile)"; frame.js foldSearches): the box
   with its glyph before it and a cross after it; from 760px the box alone, as it was; below, the glyph alone until it is
   pressed, then the box grows across from beside it, as the Inbox's does */
.pn-sfold { display: contents; }
.pn-sfoldbtn, .pn-sfoldx { display: none; }
@media (max-width: 759px) {
  .pn-sfold { display: inline-flex; align-items: center; gap: 4px; min-width: 0; max-width: 100%; }
  .pn-sfold > input[type="search"] { flex: 1 1 auto; min-width: 0; }
  /* folded, the box is 1px whatever a page's own rule makes it (3 Nov 2026: the Changelog's search kept its page's
     width: 100% while folded, and its unseen box ran past the screen's edge, so the phone's page scrolled sideways) */
  :root[data-app] .pn-sfold:not(.pn-sopen) > input[type="search"] { position: absolute; width: 1px; min-width: 0; max-width: 1px; height: 1px; min-height: 0;
    padding: 0; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); border: 0; opacity: 0; }
  .pn-sfold:not(.pn-sopen) > .pn-sfoldbtn { display: inline-flex; }
  .pn-sfold.pn-sopen { flex: 1 1 100%; width: 100%; animation: pn-sgrow .28s ease; }
  .pn-sfold.pn-sopen > .pn-sfoldx { display: inline-flex; flex: none; }
}
@keyframes pn-sgrow { from { opacity: 0; clip-path: inset(0 100% 0 0); } to { opacity: 1; clip-path: inset(0 0 0 0); } }
@media (max-width: 759px) and (prefers-reduced-motion: reduce) { .pn-sfold.pn-sopen { animation: none; } }

/* THE SIGN-IN PAGE AND THE APP HOST'S NOT-FOUND PAGE IN THE WEBSITE'S LOOK (2 Nov 2026, the operator: "redesign the
   entire studio to match the website/calculator style", "go A", then "Did you redesign booth pages also ?"). No more
   ballroom lights: the page is the Studio's own plain ground in light and dark, the card the website's dark ink band
   (the logo keeps its colours on it), square, no shadow, and its one button the yellow with ink words. */
:root[data-app][data-theme="light"] .wa-center { isolation: auto; background: var(--pn-ground); }
:root[data-app][data-theme="light"] .wa-center::before { content: none; display: none; }
:root[data-app] .wa-center .wa-gcard, :root[data-app][data-theme="light"] .wa-center .wa-gcard { background: var(--pn-head); border: 0; border-radius: 0;
  box-shadow: 0 0 0 1px var(--pn-line); -webkit-backdrop-filter: none; backdrop-filter: none; color: var(--pn-on-head); }
:root[data-app] .wa-center .wa-gcard .wa-lgbox::after { background: rgba(242,239,232,.22); }
:root[data-app] .wa-center .wa-gcard .wa-xp, :root[data-app] .wa-center .wa-gcard .wa-msg { color: #a4a099; }
:root[data-app] .wa-center .wa-gcard .wa-open, :root[data-app][data-theme="light"] .wa-center .wa-gcard .wa-btn.wa-open { border: 0; border-radius: 0; background: var(--pn-y); color: var(--pn-on-y); font-weight: 600; filter: none; }
@media (hover: hover) { :root[data-app] .wa-center .wa-gcard .wa-open:hover, :root[data-app][data-theme="light"] .wa-center .wa-gcard .wa-btn.wa-open:hover { background: var(--pn-y-press); filter: none; } }

/* OFF IS QUIET (9 Nov 2026, of a heavy grey Save and Pause beside live buttons): off, a button is the field's own tint with a
   hairline and muted words, whether filled or not; Save still goes grey, then filled, then Saved with a tick */
:root[data-app][data-theme] :is(.pn-wrap, .pn-sheet, .dk-modal) :is(.wa-btn, .wa-gl):disabled { opacity: 1; background: var(--pn-fill, rgba(242,239,232,.08)); border-color: var(--pn-line); color: var(--pn-muted); }

/* THE ORDER OF WORDS IN A ROW (9 Nov 2026): a name in ink and the line under it muted and smaller, in dark as on paper; a card's
   status line is words, its intro under the card's label one step smaller */
:where(.pn-t) { font-size: 12.5px; }
:root[data-app][data-theme="dark"] .pn-t { color: var(--pn-muted); }
:root[data-app][data-theme="light"] .pn-list .pn-m > b { color: var(--pn-ink); }
:root[data-app] .pn-card .pn-sub { font-size: 14px; color: var(--pn-ink); }
:root[data-app] .pn-card > :is(h2, h3) + .pn-sub { font-size: 13px; color: var(--pn-muted); }
:root[data-app] .mn-prod .pn-t { font-size: 14px; font-weight: 500; color: var(--pn-ink); }
:root[data-app] :is(.jf-line, .po-head .pn-t) { font-size: 12.5px; font-weight: 400; }
:root[data-app] .po-why { font-size: 13px; color: var(--pn-muted); }
:root[data-app][data-theme] .pn-sigplain { font-size: 12px; font-weight: 400; color: var(--pn-ink-soft, var(--pn-muted)); }

/* A SHEET'S FOOT, ONE LOOK (9 Nov 2026, of five different feet): at the right, the main action last and filled, the same height as
   Cancel. Other actions (Reset, Preview, Copy key, Open the page) sit at the left of the same row */
.pn-sheetfoot, .pn-sheet > .wa-card > .pn-row:last-child, .pn-sheet .wa-card > [data-savescope] > .pn-row:last-child, .pn-sheet .wa-card > .pn-form > .pn-row:last-child { display: flex; justify-content: flex-end; flex-wrap: wrap; gap: 8px; }
.pn-sheetfoot > [data-no] + .pn-spacer, .pn-sheet .pn-row:last-child > [data-no] + .pn-spacer { display: none; }
.pn-sheetfoot > .pn-footside { margin-right: auto; }
:root[data-app] .cw-sheet .cw-nav { justify-content: flex-end; }
:root[data-app] .cw-sheet .cw-nav > button { flex: 0 0 auto; }
/* SAVE, THE CARD'S OWN FOOT: at the right, the width of its words, always */
.pn-card .pn-row:has(> .pn-savebtn:only-child), .pn-card .pn-row:has(> .pn-spacer:first-child + .pn-savebtn:last-child) { justify-content: flex-end; }
.pn-form > .pn-savebtn { justify-self: end; }
:root[data-app] .pn-card .pn-savebtn { width: auto; flex: 0 0 auto; }

/* THE PAGE'S NAME ONCE (9 Nov 2026): below 980px the place menu names the page, so its heading is for a screen reader */
@media (max-width: 979.98px) {
  :is(.pn-sidemain:has(.pn-plcs), .pn-wrap:has(> .pn-sidewrap .pn-plcs)) :is(h1.pn-h, h1.ib-h), .ib:has(.ib-boxbtn) h1.ib-h:not(:has(~ .ib-open)) { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}

:root[data-app][data-theme] .pn-quietdanger { background: none; border-color: var(--pn-line); color: var(--st-bad); }
:root[data-app] .ib-contact { height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0 10px; border-color: var(--pn-line); }
:root[data-app] .ib-contacts { gap: 6px; }
:root[data-app][data-theme] :is(.ib-cclose, .ib-ccloseb, .pn-sfoldx) { border-color: transparent; background: none; }
:root[data-app] .mn-tsets .pn-ddbtn.wa-pwin { height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0 10px; font-size: 12px; }
/* the set's actions in the words' size of its dropdown beside them (9 Nov 2026) */
:root[data-app] .mn-tsets .mn-tsetacts .wa-gl { font-size: 12px; letter-spacing: 0; text-transform: none; }

.pn-pills:has(> [data-cltab]) { flex-wrap: nowrap; }
.pn-pills:has(> [data-cltab]) > .pn-pill { flex: 1 1 auto; }
/* a folded search ends the dropdowns' row on a phone, and opened takes the row */
@media (max-width: 759.98px) {
  .pn-chgfind:has(> .pn-sfold), .em-filters:has(.pn-sfold) { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 8px; }
  .pn-chgfind:has(> .pn-sfold.pn-sopen) > .pn-sfold, .em-filters .pn-glfilter:has(> .pn-sfold.pn-sopen) { grid-column: 1 / -1; }
  .em-filters:has(.pn-sfold):has(> .pn-glfilter ~ .pn-glfilter ~ .pn-glfilter) { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; }
}

:root[data-app] :is(.pn-jbacts, .pn-chgfind, .em-filters) :is(.pn-glicon, .pn-sfoldbtn) { width: var(--pn-h-main); height: var(--pn-h-main); min-height: var(--pn-h-main); }

/* A RING FOR THE KEYBOARD ALONE (9 Nov 2026): a sheet's own focus drew a double ring on a phone, and the main button read as a
   second, bigger button. frame.js marks html[data-keys] on Tab or an arrow and clears it on a press */
:root[data-app]:not([data-keys]) :focus-visible { outline: none; }
:root[data-app]:not([data-keys]) .wa-pwin:focus { box-shadow: none; }

/* THE ONE SIZE SCALE (9 Nov 2026, the operator: "buttons are ridiculously large and out of place compared to the row").
   Three sizes and no others, computer and touch: MAIN 40 and 44, ROW 28 and 32, ICON ALONE 28 and 32. The 44px thumb
   rule is about reach, not looks: a row's control is drawn small and keeps its reach with an invisible pseudo element.
   A typed field cannot carry one, so a field is always MAIN, and so is a button on a line with a field. */
:root[data-app] { --pn-h-main: 40px; --pn-h-act: 28px; }
@media (pointer: coarse) { :root[data-app] { --pn-h-main: 44px; --pn-h-act: 32px; } }

/* MAIN: Save always, the foot of a sheet or question, and a main action a card names with .pn-main; filled, never bigger */
:root[data-app] :is(.pn-card, .mn-card, .pn-jbcard, .pn-list, .pn-sblock, .pn-gmain, .pn-sheet, .cn-btns, .pn-sheetfoot) :is(.wa-btn, .wa-gl, .wa-sm).pn-savebtn,
:root[data-app] :is(.wa-btn, .wa-gl, .wa-sm).pn-main,
:root[data-app] .pn-sheetfoot :is(.wa-btn, .wa-gl, .wa-sm, .wa-pill) { height: var(--pn-h-main); min-height: var(--pn-h-main); padding: 0 15px; font-size: 11px; }
@media (pointer: coarse) {
  :root[data-app] :is(.pn-card, .mn-card, .pn-jbcard, .pn-list, .pn-sblock, .pn-gmain, .pn-sheet, .cn-btns, .pn-sheetfoot) :is(.wa-btn, .wa-gl, .wa-sm).pn-savebtn,
  :root[data-app] :is(.wa-btn, .wa-gl, .wa-sm).pn-main,
  :root[data-app] .pn-sheetfoot :is(.wa-btn, .wa-gl, .wa-sm, .wa-pill) { padding: 0 18px; }
}

/* ROW: a control inside a row or a card, as small as its words allow, capitals one step under the row's */
:root[data-app] :is(.pn-card, .mn-card, .pn-jbcard, .pn-list, .pn-rear, .pn-sblock, .pn-gmain, .pn-jbfin, .ib-pane, .ib-tools, .ib-filters, .jf-rows, .jf-btns, .po-acts, .mn-prod, .mn-tsets, .pn-clhead, .pn-ewcard, .pn-sigcard, .cw-col, .cn-btns, .pr-cardh, .pn-rpbody, .pn-jbrow, .pn-colfilters)
  :is(.wa-gl, .wa-sm, .wa-pill):not(:where(.pn-savebtn, .pn-main, .pn-glicon, .pn-jbclear, .pn-glstarred, .pn-splitc, .cl-add > *, .pn-sheetfoot *, :has(~ :is(.pn-savebtn, .pn-main, .wa-btn:not(.wa-sm, .wa-open))), :is(.pn-savebtn, .pn-main, .wa-btn:not(.wa-sm, .wa-open)) ~ *, :is(.pn-srowin, .pn-row, .pn-form, .pn-wsrowline, .pr-row):has(> .wa-pwin, > input, > select, > .pn-sfold, > .pn-keepday, > .pn-dd, > .pn-date) > *)),
:root[data-app] .pn-rowact { height: var(--pn-h-act); min-height: var(--pn-h-act); min-width: 0; padding: 0 10px; gap: 6px; font-size: 10.5px; }
:root[data-app] :is(.pn-card, .mn-card, .pn-jbcard, .pn-list, .pn-rear, .pn-sblock, .pn-gmain, .pn-jbfin, .ib-pane, .ib-tools, .ib-filters, .jf-rows, .jf-btns, .po-acts, .mn-prod, .mn-tsets, .pn-clhead, .pn-ewcard, .pn-sigcard, .cw-col, .cn-btns, .pr-cardh, .pn-rpbody, .pn-jbrow, .pn-colfilters)
  :is(.wa-gl, .wa-sm, .wa-pill):not(:where(.pn-savebtn, .pn-main, .pn-glicon, .pn-jbclear, .pn-glstarred, .pn-splitc, .cl-add > *, .pn-sheetfoot *, :has(~ :is(.pn-savebtn, .pn-main, .wa-btn:not(.wa-sm, .wa-open))), :is(.pn-savebtn, .pn-main, .wa-btn:not(.wa-sm, .wa-open)) ~ *, :is(.pn-srowin, .pn-row, .pn-form, .pn-wsrowline, .pr-row):has(> .wa-pwin, > input, > select, > .pn-sfold, > .pn-keepday, > .pn-dd, > .pn-date) > *)) :is(.pn-gl, svg.i),
:root[data-app] .pn-rowact :is(.pn-gl, svg.i) { width: 14px; height: 14px; }
:where(:root[data-app]) :is(.pn-pchip, .pn-pill, .pn-gtab) :is(.pn-gl, svg) { width: 14px; height: 14px; }

/* ICON ALONE: square, its glyph 14px, 16 to a thumb */
:root[data-app] :is(.pn-glicon, .pn-show, .pn-psetmore) { width: var(--pn-h-act); height: var(--pn-h-act); min-height: var(--pn-h-act); min-width: 0; padding: 0; }
:root[data-app] :is(.pn-glicon, .pn-show, .ib-tool, .ib-rowact, .ib-headact) .pn-gl { width: 14px; height: 14px; }
@media (pointer: coarse) { :root[data-app] :is(.pn-glicon, .pn-show, .ib-tool, .ib-rowact, .ib-headact, .ib-chipgl) .pn-gl { width: 16px; height: 16px; } }

/* REACH: 44px to a thumb, invisible, round a small control. Nothing here draws a thing */
@media (pointer: coarse) {
  :where(:root[data-app]) :is(.pn-card, .mn-card, .pn-jbcard, .pn-list, .pn-rear, .pn-sblock, .pn-gmain, .pn-jbfin, .ib-pane, .ib-tools, .ib-filters, .jf-rows, .jf-btns, .po-acts, .mn-prod, .mn-tsets, .pn-clhead, .pn-ewcard, .pn-sigcard, .cw-col, .cn-btns, .pr-cardh, .pn-rpbody, .pn-jbrow, .pn-colfilters) :is(.wa-gl, .wa-sm, .wa-pill),
  :where(:root[data-app]) :is(.pn-rowact, .pn-pill, .pn-gtab, .pn-pchip, .pn-glicon, .pn-show, .pn-psetmore, .pn-covx, .cw-x, .ib-tool, .ib-rowact, .ib-headact, .ib-chip, .pn-listbtn) { position: relative; }
  :where(:root[data-app]) :is(.pn-card, .mn-card, .pn-jbcard, .pn-list, .pn-rear, .pn-sblock, .pn-gmain, .pn-jbfin, .ib-pane, .ib-tools, .ib-filters, .jf-rows, .jf-btns, .po-acts, .mn-prod, .mn-tsets, .pn-clhead, .pn-ewcard, .pn-sigcard, .cw-col, .cn-btns, .pr-cardh, .pn-rpbody, .pn-jbrow, .pn-colfilters) :is(.wa-gl, .wa-sm, .wa-pill)::after,
  :where(:root[data-app]) :is(.pn-rowact, .pn-pill, .pn-gtab, .pn-pchip, .ib-chip)::after { content: ""; position: absolute; inset: -7px 0; }
  :root[data-app] :is(.pn-glicon, .pn-show, .pn-psetmore, .pn-covx, .cw-x, .ib-tool, .ib-rowact, .ib-headact, .pn-listbtn, .ib-chipgl)::after { content: ""; position: absolute; inset: -7px; }
  :root[data-app] :is(.pn-jbshacts, .jf-acts, .pn-glicons, .ib-filters, .pn-secacts) { gap: 12px; }
}

/* WHAT LEADS IN A ROW (9 Nov 2026, of tables where every column was one weight): the name 600, dates, type and client 400 and muted, money 500 */
:root[data-app] .pn-gltab .pn-glname b { font-weight: 600; }
:root[data-app] .pn-jbtab td { line-height: 1.4; }
:root[data-app] .pn-jbtab td.pn-glnum:not(.mn-num), :root[data-app] .pn-jbtab td.pn-glopt { font-weight: 400; color: var(--pn-muted); }

/* A MONEY FOLD'S ROWS START AT THE CARD'S TOP */
.pn-jbfin .mn-rows li:first-child { padding-top: 0; }
.pn-jbfin .mn-rows li { gap: 8px; }
.pn-jbsame { margin-top: 6px; font-size: 12.5px; color: var(--pn-muted); }

/* A GALLERY'S CARD: each fact whole, a dot between; a phone holds the name to two lines */
.pn-gcf { white-space: nowrap; }
.pn-gcf:not(:last-child)::after { content: "\00a0\00b7"; }
/* a phone's two columns have no room for the date beside the rest: it takes its own line, so no line ends on a dot */
@media (max-width: 520px) { .pn-gcf:nth-last-child(2)::after { content: none; } .pn-gcf:last-child { display: block; } }
@media (max-width: 559.98px) { .pn-gcw > a b { display: -webkit-box; overflow: hidden; -webkit-box-orient: vertical; -webkit-line-clamp: 2; } }
.pn-logbox .pn-list li { align-items: flex-start; }
/* Share keeps its word on a phone, the word beside the link glyph being what it does; Preview gives way first */
@media (max-width: 399.98px) {
  .pn-gtop .pn-gtopb[data-galcopy] { gap: 6px; }
  .pn-gtop .pn-gtopb[data-galcopy] .pn-gtopw { position: static; width: auto; height: auto; overflow: visible; clip: auto; }
}
@media (max-width: 359.98px) {
  .pn-gtop .pn-gtopb[data-galcopy] { gap: 0; }
  .pn-gtop .pn-gtopb[data-galcopy] .pn-gtopw { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); }
}
/* DOWNLOAD ACTIVITY ON A PHONE (9 Nov 2026, of six columns cut with no sign of it): the file and the day, who and the size, then PIN and IP small */
@media (max-width: 559.98px) {
  .pn-datable thead { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
  .pn-datable, .pn-datable tbody { display: block; }
  .pn-datable tbody tr { display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: center; gap: 2px 8px; padding: 10px 0; border-top: 1px solid var(--pn-line); }
  .pn-datable td { display: block; padding: 0; border: 0; }
  .pn-datable td:nth-child(2) { grid-column: 1; grid-row: 1; min-width: 0; }
  .pn-datable .pn-dathumb { width: 36px; height: 28px; }
  .pn-datable td.pn-dawhen { grid-column: 2; grid-row: 1; font-size: 12px; color: var(--pn-muted); }
  .pn-datable td:nth-child(1) { grid-column: 1; grid-row: 2; min-width: 0; font-size: 12.5px; }
  .pn-datable td:nth-child(3) { grid-column: 2; grid-row: 2; justify-self: end; font-size: 12.5px; }
  .pn-datable td.pn-dapin, .pn-datable td.pn-daip { font-size: 11.5px; color: var(--pn-muted); }
  .pn-datable td.pn-dapin { grid-column: 1; grid-row: 3; }
  .pn-datable td.pn-daip { grid-column: 1; grid-row: 3; margin-left: 6em; }
  .pn-datable td.pn-dapin::before { content: "PIN "; }
  .pn-datable td.pn-daip::before { content: "IP "; }
}
/* AN EVENT'S TILE ON A PHONE: its figures at the foot, the row's words from the left */
@media (max-width: 559.98px) {
  .pn-night .pn-row { justify-content: flex-start; }
  .pn-night .pn-stats { margin-top: auto; }
}
/* a problem's area, a small label on its own line */
.pn-faultarea { display: block; font-size: 10.5px; font-weight: 500; letter-spacing: .14em; text-transform: uppercase; color: var(--pn-muted); }

.pn-wstab .pn-wsline { display: none; }
/* THE ACCOUNT'S FACTS: the name at the left, its value at the right, on one line */
.pn-acct .pn-list li { flex-wrap: nowrap; justify-content: space-between; gap: 12px; }
.pn-acct .pn-list li > .pn-m { flex: none; }
.pn-acct .pn-list li > .pn-t { flex: 0 1 auto; min-width: 0; overflow: hidden; text-align: right; text-overflow: ellipsis; white-space: nowrap; }
/* WIDER TABLES ON A PHONE: narrow columns and small plain heads, so four fit and nothing is cut */
@media (max-width: 559.98px) {
  .pn-wssmall:not(.pn-wstab) th { padding: 6px 4px; font-size: 10px; letter-spacing: 0; text-transform: none; }
  .pn-wssmall:not(.pn-wstab) td { padding: 8px 4px; font-size: 12.5px; }
}
/* the small figures under a tile: the figure, then what it is */
.pn-wst .pn-tsplit > span { grid-template-columns: 44px minmax(0, 1fr); align-items: baseline; }
/* a Studio email's wording: the count on its own line under the hint, at the right */
.pn-ewmeta > :last-child { align-self: flex-end; font-variant-numeric: tabular-nums; }
.mn-terms { min-height: 240px; }
/* a person on the Team page: Details at the name's right, small */
.pn-list li.cw-person { flex-wrap: nowrap; align-items: flex-start; gap: 8px; }
.pn-list li.cw-person > .pn-m { flex: 1 1 0; min-width: 0; }
.cw-btns { display: inline-flex; flex: none; flex-wrap: wrap; justify-content: flex-end; gap: 6px; max-width: 50%; }
:root[data-app] .cw-btns .wa-gl, :root[data-app] .cw-btns .wa-sm { position: relative; height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0 10px; font-size: 10.5px; }
@media (pointer: coarse) { .cw-btns .wa-gl::after, .cw-btns .wa-sm::after { content: ""; position: absolute; inset: -7px 0; } }
/* ON A PHONE (9 Nov 2026): the name and its actions on one line, the actions held on it, and the role, the state and the tick under them at the row's full width, so no row goes ragged */
@media (max-width: 559px) {
  .pn-list li.cw-person { display: grid; grid-template-columns: minmax(0, 1fr) auto; column-gap: 8px; }
  .pn-list li.cw-person > .pn-m { display: contents; }
  .pn-list li.cw-person > .pn-m > br { display: none; }
  .pn-list li.cw-person > .pn-m > b { grid-column: 1; grid-row: 1; align-self: center; overflow-wrap: anywhere; }
  .pn-list li.cw-person > .pn-m > :not(b) { grid-column: 1 / -1; }
  .pn-list li.cw-person > .cw-btns { grid-column: 2; grid-row: 1; flex-wrap: nowrap; max-width: none; }
}

/* THE SECOND EYE PASS (9 Nov 2026): what the first pass's own rules left, each against its row and its neighbours */
/* one gap under the place menu, whatever page comes next */
@media (max-width: 979.98px) {
  .pn-plcs:not([hidden]) { margin-bottom: 12px; }
  :root[data-app] .pn-plcs + * { margin-top: 0; }
  :root[data-app] .pn-plcs + .pn-colbar > .pn-colhead { margin-top: 0; }
  .ib-em .em-head { padding-top: 12px; }
  .ib-em .em-head > .em-period { flex: 1 1 100%; margin-left: 0; }
  .ib-em .em-head > .em-period .pn-ddbtn, .ib-em .em-head > .em-period select { width: 100%; }
}
/* the phone's tools are one height, the main button last on their row and no bigger than they are */
@media (max-width: 759.98px) {
  :root[data-app] .pn-clbar { --pn-h-main: var(--pn-h-act); }
  :root[data-app] .pn-clbar .pn-glhead .wa-btn, :root[data-app] .pn-jbbar .pn-jbhead .wa-btn { position: relative; height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0 12px; font-size: 10.5px; }
  .pn-clbar .pn-glhead .wa-btn::after, .pn-jbbar .pn-jbhead .wa-btn::after { content: ""; position: absolute; inset: -7px 0; }
  /* Collections: the split button and the search one height */
  :root[data-app] .pn-colhead .pn-split > .wa-btn { position: relative; height: var(--pn-h-act); min-height: var(--pn-h-act); font-size: 10.5px; }
  :root[data-app] .pn-colhead .pn-split > .pn-splitc { width: var(--pn-h-act); }
  :root[data-app] .pn-colhead .pn-sfoldbtn { width: var(--pn-h-act); height: var(--pn-h-act); min-height: var(--pn-h-act); }
  .pn-colhead .pn-split > .wa-btn::after { content: ""; position: absolute; inset: -7px 0; }
  /* the search glyph on the same row as what follows it */
  .mn-kindrow { display: flex; align-items: center; gap: 8px; }
  .mn-kindrow > .pn-glhead { flex: none; }
  .mn-kindrow > .mn-kinds { flex: 1 1 0; min-width: 0; margin-top: 0; }
  .mn-kindrow:has(.pn-sopen) { flex-wrap: wrap; }
  .mn-kindrow:has(.pn-sopen) > .pn-glhead { flex: 1 1 100%; }
  .em-filters:has(> .pn-sfold):has(> .pn-glfilter ~ .pn-glfilter) { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto; }
  .em-filters > .pn-sfold.pn-sopen { grid-column: 1 / -1; }
}
/* a tablet's money and job tables fit their card with the short date and closer cells */
@media (max-width: 979.98px) {
  .pn-jbtab .pn-jbdw { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }
  .pn-jbtab th, .pn-jbtab td { padding-left: 6px; padding-right: 6px; }
  .ib-em .em-head > h1.pn-h { position: absolute; width: 1px; height: 1px; margin: -1px; padding: 0; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
}
@media (max-width: 899.98px) {
  :root[data-app] .pn-jbtop > .pn-jbacts .wa-gl { position: relative; height: var(--pn-h-act); min-height: var(--pn-h-act); padding: 0 10px; gap: 6px; font-size: 10.5px; }
  :root[data-app] .pn-jbtop > .pn-jbacts .wa-gl.pn-glicon { width: var(--pn-h-act); padding: 0; }
  :root[data-app] .pn-jbtop > .pn-jbacts .wa-gl .pn-gl { width: 14px; height: 14px; }
  .pn-jbtop > .pn-jbacts .wa-gl:not(.pn-glicon)::after { content: ""; position: absolute; inset: -7px 0; }
}
/* the clients' rows start where the jobs' do, and one column needs no heading */
@media (max-width: 720px) {
  .pn-cllist th, .pn-cllist td { padding-left: 12px; padding-right: 12px; }
  .pn-cllist thead tr { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%); }
}
/* one 8px gap between a name and its chip (the space between them is half of it) */
.pn-m > b + .pn-badge, .pn-m > a + .pn-badge, .pt-qhead > b + .pn-badge { margin-left: 4px; }
/* a column's first card starts at the column's top: WebKit carries a block's bottom margin over the break, an inline block's it does not */
@media (min-width: 1180px) { :root[data-app] .pn-phgrid > .wa-card.pn-card { display: inline-block; width: 100%; margin: 0 0 14px; vertical-align: top; } }
