:root{
  --ink:#1c2340; --ink-soft:#4a5270; --ink-filed:#1c402e; --paper:#f4f9ff; --butter:#ffd84d;
  --lilac:#c9bcff; --mint:#a4ecc8; --coral:#ffb3a3; --butter-hi:#ffe98a;
  --display:'Chewy',sans-serif; --body:'Nunito',system-ui,sans-serif; --mono:'Courier Prime',ui-monospace,'Courier New',monospace;
}
*{box-sizing:border-box}
html,body{height:100%}
/* no text on the site can be selected: it is a place, not a page. the fields you type in stay selectable */
body{-webkit-user-select:none;user-select:none}
input,textarea,[contenteditable="true"]{-webkit-user-select:text;user-select:text}
body{
  margin:0; background:#000; color:var(--ink);
  font-family:var(--body); font-weight:700; overflow:hidden;
}
button{font:inherit;color:inherit}
/* the focus ring is for keyboard navigation only. focus moved by a click, or by a script (an overlay
   opening or closing hands focus on), draws nothing: app.js marks <html data-input> from the last
   input, and only the keyboard mode paints rings */
html[data-input="key"] :focus-visible{outline:3px solid var(--butter);outline-offset:3px}
:focus-visible{outline:none}

/* ---------- scene stack ---------- */
.scene{position:fixed;inset:0;opacity:0;visibility:hidden;transition:opacity .45s ease}
.scene.on{opacity:1;visibility:visible}
/* the walk through the department door (travel): the screen goes black over the corridor, the scene
   changes under it, and the black lifts off the room as it zooms in a touch, the camera stepping
   through. the way out runs backwards, the room zooming out under the falling black. the blackout
   sits over the scenes and under every overlay and the corner buttons, and takes the clicks meanwhile */
#blackout{position:fixed;inset:0;z-index:19;background:#000;opacity:0;pointer-events:none;transition:opacity .55s ease-in}
#blackout.on{opacity:1;pointer-events:auto}
#blackout.lift{transition:opacity .9s ease-out}
#s-room{transition:opacity .45s ease,transform .9s cubic-bezier(.2,.7,.2,1)}
#s-room.zoom-from{transform:scale(.94);transition:none}   /* the frame before it appears: from here it zooms in as the black lifts */
#s-room.zoom-away{transform:scale(.94);transition:opacity .45s ease,transform .7s ease-in}   /* and out again on the way back to the corridor */
@media (prefers-reduced-motion: reduce){ #s-room,#s-room.zoom-from,#s-room.zoom-away{transform:none;transition:opacity .45s ease} }
/* the gate's art and hits live on a stage inside the section. portrait: the swipe slides the stage
   door to door (placeGate); the section stays over the whole screen, so every touch on the corridor
   reaches it, wherever the stage has been slid */
#gate-stage{position:absolute;inset:0;transition:transform .45s cubic-bezier(.2,.8,.2,1)}
@media (prefers-reduced-motion: reduce){ #gate-stage{transition:none} }
.layer{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;
       user-select:none;-webkit-user-drag:none;pointer-events:none}
.layer.hi{opacity:0;transition:opacity .25s ease}      /* gate: hover art fades in, no glow or lift */
.layer.hi.on{opacity:1}
#hi-bathroom{transition:none}                      /* the bathroom door on the gate lights up at once (the elevator is out of order: no hover art) */
#hi-door{transition:opacity .5s ease}              /* the department door glows on slowly and dims off the same way */
#s-room .layer.hi{opacity:1;transition:filter .25s ease,transform .25s ease}   /* desk items: always visible, glow on hover */
#s-room .layer.hi.on{filter:brightness(1.12) drop-shadow(0 0 10px rgba(255,216,77,.85));transform:translateY(-3px)}
#s-room #hi-tasks.on{transform:translateY(-12px)}   /* the papers lift clear of the tray, not just a nudge */
/* the folder only lands on the desk once the clerk asks you to review the file */
/* the folder: four thickness states stacked in one box, only the current one (.cur) is shown */
.fold{display:none;transition:opacity .45s ease,filter .25s ease,transform .25s ease}
.fold.cur{display:block}
/* the folder and the papers in the tray land the moment x is connected (has-folder). before that the
   tray is empty and the folder is not on the desk. */
#s-room:not(.has-folder) .fold{opacity:0}
#s-room:not(.has-folder) [data-hit="folder"]{display:none}
#s-room:not(.has-review) #hi-review{opacity:0}
#s-room:not(.has-review) [data-hit="review"]{display:none}
#s-room.landing-review #hi-review{animation:paperDrop .6s cubic-bezier(.2,.8,.2,1)}
#s-room.has-review #hi-review:not(.on){animation:bellPulse 2.4s ease-in-out infinite}   /* it wants reading */
/* the crumpled paper: two balls by the folder after one interview is thrown out, three more on the
   other side after a second. gone when the case is filed */
#s-room .crumple{opacity:0;transition:opacity .45s ease;pointer-events:none}
#s-room.crumples-1 .crumple.r, #s-room.crumples-2 .crumple:is(.r,.l), #s-room.crumples-3 .crumple:is(.r,.l,.b),
#s-room.crumples-4 .crumple:is(.r,.l,.b,.f), #s-room.crumples-5 .crumple{opacity:1}   /* five restarts: by the folder, the other side, the back, the front, then the pyramid */
#s-room:not(.has-tray) #hi-tasks{opacity:0}
#s-room:not(.has-tray) [data-hit="tasks"]{display:none}
/* the landings: papers drop into the tray on connect; the folder drops when there's a case to hold */
#s-room.landing #hi-tasks{animation:paperDrop .6s cubic-bezier(.2,.8,.2,1)}
#s-room.landing-folder .fold.cur{animation:paperDrop .6s cubic-bezier(.2,.8,.2,1)}
@keyframes paperDrop{from{opacity:0;transform:translateY(-40px)}to{opacity:1;transform:none}}
/* first entry: everything clickable glows for a moment, then only the bell keeps pulsing */
#s-room.attract .layer.hi:not(.fold), #s-room.attract .fold.cur{filter:brightness(1.1) drop-shadow(0 0 12px rgba(255,216,77,.7));animation:attractPulse 1.2s ease-in-out 2}
#s-room .layer.hi.idleping{filter:brightness(1.1) drop-shadow(0 0 12px rgba(255,216,77,.7));animation:attractPulse 1.2s ease-in-out 1}
/* the back arrow on the desk: no glow, no lift, no ping. on hover it just grows a little */
#hi-exit{transform-origin:center}
/* the back button, top left on a wide screen: the same art as the phone's, the same size and inset as the
   overlays' close buttons; portrait keeps its own (the exit hit becomes it there) */
.room-back{position:fixed;left:12px;top:max(12px,env(safe-area-inset-top));z-index:23;width:44px;height:44px;
           display:grid;place-items:center;padding:0;border:0;background:none;cursor:pointer}
.room-back img{display:block;width:32px;height:32px;opacity:.6;filter:drop-shadow(0 1px 3px rgba(0,0,0,.6));
               transition:opacity .15s ease,transform .15s ease;pointer-events:none;-webkit-user-drag:none}
.room-back:hover img,.room-back:focus-visible img{opacity:1;transform:scale(1.08)}
.room-back:focus-visible{outline:none}
html[data-input="key"] .room-back:focus-visible img{filter:drop-shadow(0 0 0 var(--butter)) drop-shadow(0 0 3px var(--butter))}
#s-room #hi-exit.on{filter:none;transform:scale(1.1)}
@keyframes attractPulse{50%{filter:brightness(1.18) drop-shadow(0 0 20px rgba(255,216,77,.95))}}
@media (prefers-reduced-motion: reduce){ #s-room.landing #hi-tasks, #s-room.landing-folder .fold.cur, #s-room.attract .layer.hi, #s-room .layer.hi.idleping{animation:none;filter:none} }
/* the bell: while pressed, the pressed art replaces the resting one (no lift, no fade) */
#hi-bell-pressed{display:none;transition:none}
#s-room.bell-down #hi-bell{display:none}
#s-room.bell-down #hi-bell-pressed{display:block;opacity:1;filter:brightness(1.12) drop-shadow(0 0 10px rgba(255,216,77,.85))}
/* until the bell has been rung once the clerk says nothing, and the bell breathes a little to say so */
#s-room.await-bell #hi-bell:not(.on){animation:bellPulse 2.4s ease-in-out infinite}
/* once connected, the tray pulses until it has been opened once; the clerk's line waits with it */
#s-room.await-tray #hi-tasks:not(.on){animation:bellPulse 2.4s ease-in-out infinite}
#bubble .said{text-wrap:pretty;text-align:center;white-space:pre-line}   /* no orphans, and the box still shrinks to the text; a line may break where it says so */
@keyframes bellPulse{50%{filter:brightness(1.1) drop-shadow(0 0 14px rgba(255,216,77,.7))}}
@media (prefers-reduced-motion: reduce){ #s-room.await-bell #hi-bell:not(.on), #s-room.await-tray #hi-tasks:not(.on){animation:none} }

/* ---------- room stage: the room art and its desk hits fill the viewport ---------- */
#room-stage{position:absolute;inset:0;z-index:1}
.layer.full{inset:auto}   /* a full-canvas room layer, placed in px by placeArtLayers (see artFrame) */
/* the wall art (collection + noticeboard) is placed the same way as the desk pieces: tight crops
   in room-art pixels (CFG.art), so they sit on the wall exactly like the bell sits on the desk */

/* ---------- clerk iris: follows the mouse a little ---------- */
#room-iris{will-change:transform}

/* ---------- hit boxes ---------- */
.hit{position:absolute;cursor:pointer;background:transparent;border:0;padding:0;display:block}
.hit svg{display:none}                       /* nothing in a hit draws itself on the desk... */
.hit[data-hit="exit"] img{display:none}      /* ...including the exit's back button, portrait only */
/* touch: no tap flash on the hits, and no long-press callout, drag or text selection on the art (the
   script also swallows contextmenu there). the keyboard focus ring stays; a tap doesn't draw one. */
*{-webkit-tap-highlight-color:transparent}
.hit{touch-action:manipulation;-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}
.hit:focus:not(:focus-visible){outline:none}
.layer,#room-stage,img{-webkit-touch-callout:none;-webkit-user-select:none;user-select:none}

/* ---------- folder overlay ---------- */
#folder{position:fixed;inset:0;display:none;z-index:20;overflow:hidden;
        background:rgba(5,6,12,.7);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
#folder.on{display:block}
#folder.suspended{display:none}   /* no longer used by the card viewer (the folder stays up under it); kept for anything else that suspends it */
/* the folder art is the same full-canvas size as the room art. the wrap is a stage that
   keeps the art's aspect ratio and covers the viewport (like object-fit:cover), so the
   percentage boxes below are always measured against the art itself. */
.folder-wrap{position:absolute;left:50%;top:50%;
             --sw:calc(max(100vw, calc(100vh * var(--folder-ar,1920/900))) * .92);   /* a little air around the folder */
             --sh:calc(max(100vh, calc(100vw / (var(--folder-ar,1920/900)))) * .92);
             width:var(--sw);height:var(--sh);margin-left:calc(var(--sw) / -2);margin-top:calc(var(--sh) / -2);
             transform:translateY(12px) scale(.985);opacity:0;transition:transform .3s ease,opacity .3s ease}
#folder.on .folder-wrap{transform:none;opacity:1}
.folder-wrap img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;pointer-events:none;-webkit-user-drag:none}
.tab{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center;pointer-events:none;
     filter:grayscale(1) brightness(.62);transition:filter .25s ease}
.tab.done{filter:none}
.tab.now{filter:none;z-index:6}                        /* current tab sits above the paper */
/* the paper stack (05-paper) is a tight crop like the tasks clipboard, not a folder-canvas layer:
   its wrap keeps the crop's shape, fills the viewport height (or width on a narrow screen) and sits
   centred over the spread. the html page lives inside it, boxed by CFG.page as % of the crop. */
.paper-wrap{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:5;
            height:min(84vh,100vw);aspect-ratio:1053/1329}
.paper-wrap img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;pointer-events:none;-webkit-user-drag:none}
#f-nocase{z-index:6}                                    /* "no case found" sticker on the paper */
/* the filed case (08-spread) is a tight crop too, wrapped the same way as the paper. the page,
   the approved stamp and the close button all live inside its wrap. */
.spread-wrap{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);z-index:5;
             height:min(84vh,53vw);aspect-ratio:2440/1404}
.spread-wrap img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;pointer-events:none;-webkit-user-drag:none}
@keyframes stamp{from{opacity:0;transform:scale(1.35) rotate(-4deg)}to{opacity:1;transform:none}}

/* ---------- government form, drawn in code on blank paper ---------- */
.gov{display:flex;flex-direction:column;height:100%;min-height:0}
.gh{display:flex;justify-content:space-between;align-items:flex-start;gap:.8em;
    border-bottom:2px solid var(--ink);padding-bottom:.45em;margin-bottom:.55em;flex:none}
.gh .dept{font-weight:900;text-transform:uppercase;letter-spacing:.08em;font-size:1.05em;line-height:1}
.gh .dept small{display:block;font-size:.55em;letter-spacing:.14em;font-weight:800;color:var(--ink-soft);margin-top:.4em}
.gh .casebox{border:2px solid var(--ink);padding:.3em .55em;font-family:var(--mono);font-size:.68em;font-weight:700;letter-spacing:.04em;
             text-transform:uppercase;white-space:nowrap;line-height:1}
.gtitle{font-family:var(--body);font-weight:900;font-size:.78em;letter-spacing:.18em;text-transform:uppercase;line-height:1;margin:.2em 0 .55em;color:var(--ink-soft);flex:none}
.gf{display:grid;grid-template-columns:1fr 1fr;gap:.35em .55em;margin:0 0 .45em;flex:none}
.gf .f{border:1.5px solid rgba(28,35,64,.5);padding:.3em .5em .35em;min-width:0;background:rgba(255,255,255,.18)}
.gf .f.w{grid-column:1 / -1}
/* a paper with a statement: the statement's box takes whatever height the sheet has left */
#page .gf:has(.f.stmt){flex:1 0 auto;grid-template-rows:auto auto auto minmax(0,1fr)}
#page .gf:has(.f.stmt) .f.stmt{display:flex;flex-direction:column}
#page .gf:has(.f.stmt) .f.stmt .v{flex:1}
@media (max-aspect-ratio:1/1){ #page .gf:has(.f.stmt){grid-template-rows:auto auto minmax(0,1fr)} }   /* portrait: the two wallets share a row, so the statement is the third */
/* a wallet: one line, shown whole when it fits and trimmed in the middle to the box's width when it does not (fitWallets) */
.f.wal .v{white-space:nowrap;overflow:hidden}
.f .l{display:block;font-size:.6em;font-weight:900;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft);margin-bottom:.15em}
.f .v{display:block;font-family:var(--mono);font-weight:700;overflow-wrap:anywhere;line-height:1.3}
.f.stmt .v{font-weight:400;white-space:pre-wrap;min-height:2.6em;line-height:1.25}
.f .ask{display:block;font-weight:800;font-size:.8em;line-height:1.3;color:var(--ink);margin:.05em 0 .3em}   /* the question the statement answers, printed on the form above it */
.office{position:relative;flex:none;border:2px dashed rgba(28,35,64,.5);padding:.35em .5em;min-height:5.4em;margin:.2em 0 .5em}
.office .l{font-size:.6em;font-weight:900;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft)}
/* a laptop window or a tablet on its side: the filed sheet's office box gives up empty height so a paper with a
   full 250-character statement needs no scrollbar. every landscape screen now shows the 1440x900 sheet, so every one
   takes it */
@media (min-aspect-ratio:1/1){
  #page .office{min-height:4em;margin:.15em 0 .3em} }
.gfoot{margin-top:auto;flex:none;display:flex;justify-content:space-between;align-items:flex-end;gap:.6em;
       font-size:.6em;font-weight:800;letter-spacing:.06em;color:var(--ink-soft);
       border-top:1.5px solid rgba(28,35,64,.4);padding-top:.45em}
.gfoot b{font-family:var(--mono);font-weight:700;border:1.5px solid rgba(28,35,64,.5);padding:.15em .45em}
.gov .row{flex:none;margin:.3em 0 .4em}
.gov .row.bottom{margin:0 0 .7em}
.gov .row.bottom + .gfoot{margin-top:0}
.gov .fine{margin-top:0;padding-top:0;flex:none;margin-bottom:.4em}
/* a rubber stamp: double ring, worn ink, struck at an angle. color per kind. */
.gstamp{position:absolute;display:inline-block;padding:.28em .6em .25em;
        border:.16em solid currentColor;border-radius:.22em;outline:.06em solid currentColor;outline-offset:.14em;
        font:900 1.05em/1 var(--body);letter-spacing:.14em;text-transform:uppercase;white-space:nowrap;
        opacity:.82;mix-blend-mode:multiply;pointer-events:none;
        -webkit-mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.55' numOctaves='2' seed='3'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 -2.2 2.6'/></filter><rect width='120' height='120' filter='url(%23n)'/></svg>");
        mask-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='120' height='120'><filter id='n'><feTurbulence type='fractalNoise' baseFrequency='.55' numOctaves='2' seed='3'/><feColorMatrix values='0 0 0 0 0  0 0 0 0 0  0 0 0 0 0  0 0 0 -2.2 2.6'/></filter><rect width='120' height='120' filter='url(%23n)'/></svg>");
        -webkit-mask-size:120px 120px;mask-size:120px 120px}
.gstamp small{display:block;font-size:.5em;letter-spacing:.12em;margin-top:.25em;text-align:center}
.gstamp.received{color:#1c2340;right:6%;top:14%;transform:rotate(-8deg)}
.gstamp.pending{color:#8a7a2a;right:6%;top:14%;transform:rotate(-8deg)}
.gstamp.approved{color:#2f8a52;left:8%;top:22%;transform:rotate(-12deg);font-size:1.3em}
.gstamp.waitlisted{color:#6a52b8;left:8%;top:22%;transform:rotate(-12deg);font-size:1.15em}
.gstamp.not_selected{color:#b8503f;left:8%;top:22%;transform:rotate(-12deg);font-size:1.15em}
.gstamp.strike{animation:stamp .32s cubic-bezier(.2,.9,.3,1.2) both}   /* the one just struck */
/* ---------- the writable area on the paper ---------- */
#page{position:absolute;z-index:7;display:flex;flex-direction:column;
      font-size:clamp(13px,min(1.78vh,1.15vw),16px);   /* the sheet's type: 13px on a 720p laptop, 16px from a 900px-tall window up, never more */
      overflow:auto;overflow-x:hidden;scrollbar-width:thin;
      overflow-wrap:anywhere;min-width:0}   /* a pasted wallet with no spaces must wrap, not widen the paper */
/* a laptop or a tablet on its side: the paper's type is a fraction of the paper, like the record's and the card's, so
   browser zoom, a small window or a big monitor shows the same sheet larger or smaller, never re-wrapped. the sizes
   are the ones the sheet had at 1440x900 (16px on the 599px paper, and on the 1314px spread), and everything on it
   follows as em. the phone keeps its own compact sizes (the portrait block) */
@media (min-aspect-ratio:1/1){
  .paper-wrap,.spread-wrap{container-type:inline-size}
  .paper-wrap #page{font-size:2.671cqw}
  .spread-wrap #page{font-size:1.2178cqw}
  #page .h{font-size:1.125em} #page .q,#page .in{font-size:1.069em} #page .opt{font-size:.872em}
  #page .pg,#page .sub,#page .btn{font-size:.844em} #page .btn{min-height:2.963em}
  #page textarea.in{font-size:.9em} #page .line label{font-size:.759em} #page .fine{font-size:.703em} #page .count{font-size:.675em}
  #page .blankp .bpl{font-size:.5625em} #page .blankp .bp1{font-size:.7875em} #page .blankp .bp2{font-size:.647em}
  #folder #page #saved-interview .btn{min-height:3.26em}   /* the paper's 44px buttons at 1440x900, as a share of their own type */
}
/* portrait: a line under the folder says the spread swipes (shown by the portrait block) */
#folder .fhint{position:fixed;left:16px;right:16px;bottom:calc(max(20px,env(safe-area-inset-bottom)) + 64px);z-index:22;
               display:none;margin:0;text-align:center;pointer-events:none;
               color:#9aa2bd;font:800 12px/1.4 var(--body);letter-spacing:.14em;text-transform:uppercase}
#filed-close{position:absolute;z-index:9;display:none;align-items:center;justify-content:center}   /* close button of the filed case, placed by CFG.filedClose */
#filed-close.on{display:flex}
#filed-close .btn{width:100%;height:100%;padding:0}
/* the engagement record: a form on the left page of the spread, above the card, drawn in the same
   code-form language as the case paper (.gh / .gtitle / .gfoot). its type is sized from its own box
   (container units, height and width both capped), so every row is always in view: nothing inside
   it scrolls or gets cut off, whatever the window */
#astats{position:absolute;z-index:7;display:none;container-type:inline-size;overflow:hidden;height:auto!important;
       background:#f6f0de;color:var(--ink);border:2.5px solid var(--ink);border-radius:4px;
       box-shadow:3px 4px 0 rgba(28,35,64,.25);transform:rotate(1.6deg)}
#astats.on{display:block}
/* on a laptop the record grows to a readable size; on a monitor it keeps the box config.js gives it */
@media (min-aspect-ratio:1/1){ #astats .erec{padding:1.2em 1.1em 1.05em} }   /* a laptop: the sheet gets a wider margin top and bottom */
/* a 27" 1440p monitor (a 2560-wide window): the sheet's type is pinned so the labels and small print sit at 14px, the rest
   in step. every other screen keeps the type as a fraction of the sheet */
@media (min-aspect-ratio:1/1) and (min-width:2400px) and (max-width:2600px){ #astats .erec{font-size:22.6px} }
@media (max-aspect-ratio:1/1){ #astats .erec{padding:.6em .9em .5em;font-size:4cqw} #astats .ledger.form .c{padding:.12em .5em}
  #astats .ledger{grid-template-columns:1fr} #astats .ledger .c:nth-child(odd){border-right:0}
  /* a phone's page is narrow: the letterhead's office line goes, the small print sits at 11px, the boxes close up */
  #astats .gh .dept small{display:none} #astats .gh{margin-bottom:.25em;padding-bottom:.2em} #astats .gh .dept{font-size:1em;white-space:nowrap} #astats .casebox{flex:none;letter-spacing:0;padding:.2em .4em}
  #astats .meta{gap:.1em .5em} #astats .meta .gtitle{font-size:1.05em;letter-spacing:.06em}   /* the title and the handle share the line */
  #astats .sec{margin-top:.25em;padding:0 .45em .15em} #astats .totals{padding:0;grid-template-columns:minmax(0,.9fr) minmax(0,1.15fr) minmax(0,1fr)} #astats .totals .t{padding:.25em .3em;gap:.3em} #astats .totals .v,#astats .rows .v{font-size:1.05em} #astats .erec{padding:.5em .8em .45em}
  #astats .sec legend,#astats .sec .l,#astats .meta,#astats .casebox,#astats .gfoot,#astats .reflink input,#astats .reflink button{font-size:.9em}   /* the small print is near body size on a phone: 11px on a 390px screen */
  #astats .rows .r{padding:.08em 0} #astats .gfoot{margin-top:.2em} #astats .gfoot .daily{flex-basis:100%;margin-right:0}   /* the note on its own line, the label and the stamp under it */
  #astats .sec .l{letter-spacing:0} #astats .rows .r .l{white-space:normal;overflow:visible;text-overflow:clip}   /* the team's labels stay whole: they wrap instead */
  }   /* one field to a row: the labels stay whole on a narrow page */   /* a phone: a little taller and the rows a little tighter, so the 12px labels fit; the card starts at 58% */
.erec{height:100%;box-sizing:border-box;display:flex;flex-direction:column;padding:.7em 1.1em .6em;
      font:700 4cqw/1.25 var(--body)}   /* a fraction of the sheet's width, like the card's type: the record scales with the folder as one thing, and wraps the same on every screen */
.erec .gh{margin-bottom:.25em;padding-bottom:.25em}
.erec .gh .dept{font-size:.92em}   /* the letterhead stays on one line at the record's bigger type */
.erec .gtitle{font-size:1.35em;margin:0}
.erec .meta,.erec .casebox{font-size:.62em}   /* the small print: 12px on a 1440 laptop, and the same fraction of the sheet everywhere else */
.erec .gh .dept small{font-size:.68em}   /* inside the .92em department line: the same 12px */
.erec .meta{flex:none;display:flex;justify-content:space-between;align-items:baseline;gap:.6em;margin:.3em 0 0;
            font-size:.62em;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft)}
.erec .meta b{color:var(--ink);font-family:var(--mono);font-weight:700;text-transform:none;letter-spacing:0;font-size:1em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;flex:0 1 auto}
.erec .meta .gtitle{flex:none}
/* the counts: a ruled ledger, two fields to a row */
.erec .ledger{flex:none;display:grid;grid-template-columns:1fr 1fr;border:1.5px solid rgba(28,35,64,.55);background:rgba(255,255,255,.18)}
.erec .ledger .c{display:flex;justify-content:space-between;align-items:baseline;gap:.4em;min-width:0;
                 padding:.28em .5em;border-bottom:1.5px solid rgba(28,35,64,.35)}
.erec .ledger .c:nth-child(odd){border-right:1.5px solid rgba(28,35,64,.35)}
.erec .ledger .c:nth-last-child(-n+2){border-bottom:0}
.erec .ledger .l{font-size:max(.6em,12px);font-weight:900;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-soft);
                 white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.erec .ledger .v{font-family:var(--mono);font-weight:700;font-size:max(.72em,14px);white-space:nowrap}
/* the form: the fields numbered like a government sheet's, a full-width line at the foot for the tasks */
.erec .ledger.form{counter-reset:field}
.erec .ledger.form .c{padding:.32em .55em}
.erec .ledger.form .l::before{counter-increment:field;content:counter(field,decimal-leading-zero);margin-right:.5em;font-family:var(--mono);font-weight:700;color:var(--ink);opacity:.55;letter-spacing:0}
.erec .ledger.form .c.w{grid-column:1 / -1;border-right:0;border-bottom:0;background:rgba(28,35,64,.06)}
.erec .ledger.form .c:nth-last-child(-n+2):not(.w){border-bottom:1.5px solid rgba(28,35,64,.35)}   /* the pair above the full-width line keeps its rule */
.erec .ledger.form .c.w .v{font-size:max(.85em,14px)}
/* standing: the department's view of the account, boxed like the office-use panel on the case paper */
.erec .stand{flex:none;display:flex;justify-content:space-between;align-items:baseline;gap:.6em;
             margin-top:.45em;border:2px dashed rgba(28,35,64,.5);padding:.3em .55em}
.erec .stand .l{font-size:.6em;font-weight:900;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft)}
.erec .stand .v{font-family:var(--mono);font-weight:700;font-size:.85em;line-height:1}
.erec .gfoot{font-size:.55em;margin-top:.35em}
/* the record's three sections: ruled boxes with a lettered caption cut into the top rule, the way a printed
   government form marks its sections. nothing on the sheet is set under 12px */
.erec .sec{flex:none;margin:.3em 0 0;padding:.05em .55em .2em;border:1.5px solid rgba(28,35,64,.7);background:rgba(255,255,255,.16);min-width:0}
.erec .sec legend{padding:0 .4em;margin-left:.2em;font-size:.62em;font-weight:900;letter-spacing:.14em;text-transform:uppercase;color:var(--ink)}
.erec .sec .l{font-size:.62em;font-weight:800;letter-spacing:.06em;text-transform:uppercase;color:var(--ink-soft)}
.erec .sec .v{font-family:var(--mono);font-weight:700;color:var(--ink);white-space:nowrap;line-height:1.1}
/* A: the three totals side by side in ruled boxes, each with its label left and its figure right */
.erec .totals{display:grid;grid-template-columns:auto auto auto;padding:0}
.erec .totals legend{margin-left:.75em}
.erec .totals .t{min-width:0;display:flex;align-items:center;justify-content:space-between;gap:.4em;padding:.3em .55em .35em;border-right:1.5px solid rgba(28,35,64,.4)}
.erec .totals .t:last-child{border-right:0}
.erec .totals .l{min-width:0;line-height:1.1}
.erec .totals .v{flex:none;font-size:.95em;line-height:1}
/* B: ruled lines, label left, figure right, dotted leader between */
.erec .rows{padding-top:0;padding-bottom:.1em}
.erec .rows .r{display:flex;align-items:center;gap:.5em;padding:.08em 0;border-bottom:1px dotted rgba(28,35,64,.45);min-width:0}
.erec .rows .r:last-child{border-bottom:0}
.erec .rows .r .l{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.erec .rows .v{font-size:.78em}
/* C: the link, shortened in its field; a plain ruled button beside it */
.erec .reflink .row{display:flex;gap:.4em;min-width:0;margin:.15em 0 .1em}
.erec .reflink input{box-sizing:border-box;min-width:0;flex:1;background:rgba(255,255,255,.45);border:1px solid rgba(28,35,64,.55);border-radius:2px;
                     color:var(--ink);padding:.3em .5em;font:700 .66em/1.2 var(--mono);text-overflow:ellipsis}
.erec .reflink input:focus{outline:2px solid var(--butter);outline-offset:1px}
.erec .reflink button{flex:none;border:1.5px solid var(--ink);border-radius:3px;background:#f6f0de;color:var(--ink);padding:.25em .8em;
                      font:800 .62em/1 var(--body);cursor:pointer;transition:background .15s ease,color .15s ease}
.erec .reflink button:hover:not(:disabled){background:var(--ink);color:#f6f0de}
.erec .reflink button:focus-visible{outline:2px solid var(--ink);outline-offset:2px}
.erec .reflink button:disabled{opacity:.5;cursor:default}
.erec .gfoot{font-size:.62em;line-height:1.2}
.erec .gfoot b{white-space:nowrap;flex:none}
.erec .gfoot{justify-content:flex-end;align-items:center;text-transform:uppercase;letter-spacing:.1em;font-weight:900;color:var(--ink-soft)}   /* the foot is the date: when the record was last counted */
.erec .gfoot b{letter-spacing:0;text-transform:none;color:var(--ink)}
.erec .gfoot{flex-wrap:wrap;row-gap:.3em}
.erec .gfoot .daily{margin-right:auto;text-transform:none;letter-spacing:0;font-weight:700}   /* a note to the left of the label and the stamp; on a narrow sheet it takes its own line */
/* the ? on the B caption: its tooltip says what the X figures count */
.erec .qm{display:inline-grid;place-items:center;width:1.35em;height:1.35em;margin-left:.2em;border:1.5px solid currentColor;border-radius:50%;
          font:900 1em/1 var(--body);letter-spacing:0;vertical-align:.05em;cursor:help}
.erec .qm:focus-visible{outline:2px solid var(--butter);outline-offset:2px}
/* ---------- the department card ----------
   an id card on the left page of the spread, under the record, placed by CFG.cardArea (cr80 shape,
   real-world scale against the folder; the bigger CFG.cardAreaPortrait on a phone). one element, two
   faces painted by paintCard(): the applicant card once a case is filed, the visitor badge before.
   official issue: an ink band with the department's seal and the id number, the photograph, ruled
   fields, a machine-readable strip along the foot. ink on paper, hard shadow, no gradients. its type
   is sized from its own box (container units), so the whole card is always in view. the card stands
   alone under the sleeve art (.holder). .idcard is the card itself, drawn twice: #acard on the folder
   (a placed object, click to inspect) and #acard-big in the evidence viewer (large, tilting, with the
   export and share buttons under it). */
.idcard{position:relative;container-type:size;background:#f4efe2;color:var(--ink);border:2px solid var(--ink);border-radius:6px;
        box-shadow:3px 4px 0 rgba(28,35,64,.3)}
/* on the folder: placed by CFG.cardArea, dropped on the page at an angle (the right side riding higher;
   the sleeve inside turns with it). it lifts a touch under the mouse */
#acard{position:absolute;z-index:8;display:none;cursor:grab;transform:rotate(-9deg);   /* over the record above it: the clip laps onto the sheet */
       transition:transform .2s ease,box-shadow .2s ease;
       touch-action:none;user-select:none;-webkit-user-select:none}   /* a held finger carries it (app.js), so the browser gets no say in the moves */
#acard.on{display:block}
#acard:hover,#acard:focus-visible{transform:rotate(-9deg) translateY(-5px) scale(1.03)}   /* it lifts a touch under the mouse, no glow */
#acard:focus:not(:focus-visible){outline:none}
/* picked up: it rises off the page and rides under the pointer; the longer shadow is the height */
#acard.drag,#acard.drag:hover{cursor:grabbing;z-index:9;transform:rotate(-9deg) translateY(-8px) scale(1.06);box-shadow:8px 12px 0 rgba(28,35,64,.22)}
/* the holder: the laminated sleeve art (card-overlay, 2625x1852) laid over the card face. the art was
   drawn to the export sheet, which is the card plus a 56px margin each side on a 1200px card: so the
   sleeve is 1312/1200 of the card's width, centred on it both ways, and taller than it, so its edges
   show above and below. it ignores the pointer. (the folder wrap pins every img to the box with
   object-fit:cover; this one is reset to its own height so the art is never cropped) */
.idcard .holder{position:absolute;inset:auto;left:-4.667%;bottom:-11.733%;width:109.333%;height:auto;object-fit:fill;
                z-index:4;pointer-events:none;-webkit-user-drag:none}
/* anchored at the foot, not centred: the art keeps 88 sheet px of overhang below the card (11.733% of
   its height) whatever it carries above, so a taller sleeve (the clip) grows upward only */
.idc{position:relative;height:100%;box-sizing:border-box;display:flex;flex-direction:column;overflow:hidden;border-radius:4px;
     font:700 4.2cqw/1.2 var(--body);--band:var(--ink-filed)}
/* the two faces are told apart by the colour they fill with: a filed case is department green, the
   visitor badge stays ink. the band and the role tag are the only filled blocks, so both read --band */
.idc.visitor{--band:var(--ink)}
/* the band: the seal, the department, the id number. the visitor's band says visitor instead */
.idc .band{flex:none;display:flex;align-items:center;gap:.5em;padding:.42em 3.6cqw .4em;background:var(--band);color:#f4efe2}
.idc .seal{flex:none;width:2em;height:2em;border-radius:50%;border:1.5px solid #f4efe2;box-sizing:border-box;
           box-shadow:inset 0 0 0 .16em var(--ink),inset 0 0 0 .28em #f4efe2;   /* the double ring, in paper */
           display:grid;place-items:center;font-weight:900;line-height:1}
.idc .seal span{font-size:.44em;letter-spacing:.04em}
/* the visitor card's emblem: the art (card-icon, a square png) in the seal's slot, at the seal's size */
.idc .seal.icon{position:static;inset:auto;display:block;border:0;box-shadow:none;border-radius:0;object-fit:contain;-webkit-user-drag:none}   /* static: the folder wrap pins every img absolute, this one stays in the band's flow */
.idc .band .t{flex:1;min-width:0;line-height:1.05}
.idc .band .t b{display:block;font-size:.86em;font-weight:900;letter-spacing:.1em;text-transform:uppercase;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.idc .band .t small{display:block;font-size:.48em;font-weight:800;letter-spacing:.14em;text-transform:uppercase;opacity:.8;margin-top:.3em;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.idc .band .no{flex:none;text-align:right;font-family:var(--mono);font-size:.7em;line-height:1.1;white-space:nowrap}
.idc .band .no small{display:block;font-family:var(--body);font-size:.66em;font-weight:800;letter-spacing:.14em;opacity:.8;margin-bottom:.2em}
/* the body: the photograph on the left with the holder's role tagged under it, the particulars ruled
   in two columns on the right */
.idc .idrow{flex:1;min-height:0;display:flex;gap:2.6cqw;padding:.5em 3.6cqw .3em;align-items:stretch}
/* the photograph, a third of the card wide, with the holder's role as a ribbon across its foot */
.idc .pfw{position:relative;flex:none;width:36cqw;align-self:flex-start}
.idc .pf{position:relative;width:100%;aspect-ratio:1}
.idc .tag{position:absolute;left:-3%;right:-3%;bottom:-4%;z-index:2;display:block;text-align:center;background:var(--band);color:#f4efe2;border-radius:3px;
          padding:.36em 0 .32em;font-weight:900;font-size:.78em;letter-spacing:.22em;text-transform:uppercase;line-height:1;
          box-shadow:2px 2px 0 rgba(28,35,64,.35)}
/* the photograph: a square print with a white border, ruled in ink, a touch flat and contrasty like
   a passport photo, and a hard shadow off the card */
.idc .pf img{display:block;width:100%;height:100%;object-fit:cover;box-sizing:border-box;
             border:.26em solid #fff;outline:1.5px solid var(--ink);background:#fff;
             filter:saturate(.72) contrast(1.08);box-shadow:2px 2px 0 rgba(28,35,64,.35);-webkit-user-drag:none}
.idc .pf .nop{display:none}   /* no photograph: the dashed box */
.idc .pf.none .nop{display:grid;width:100%;height:100%;box-sizing:border-box;place-items:center;text-align:center;
                   border:1.5px dashed rgba(28,35,64,.45);border-radius:3px;padding:6%;
                   font-size:.55em;font-weight:900;letter-spacing:.04em;color:var(--ink-soft)}
.idc .who{flex:1;min-width:0;display:flex;flex-direction:column}
.idc .who .fields{display:grid;grid-template-columns:1fr 1fr;gap:.3em .5em;align-content:start}
/* the barcode at the bottom of the column: bars and gaps in units, seven tenths of the column wide */
.idc .barcode{display:flex;width:100%;height:2.1em;margin:auto 0 .3em;position:relative}
/* the site's domain over the bars, on a white slip, like the readable line a barcode carries */
.idc .barcode .bc-label{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);padding:.18em .55em;border-radius:.18em;
                        background:#fff;color:var(--ink);font:900 .95em/1 var(--body);letter-spacing:.01em;white-space:nowrap}
.idc .barcode i{display:block;flex:var(--w) 0 0;background:var(--ink)}
.idc .barcode i.g{background:transparent}
.idc .f{min-width:0}
.idc .f.w{grid-column:1 / -1}
.idc .f .l{display:block;font-size:.52em;font-weight:900;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft);line-height:1;margin-bottom:.15em}
.idc .f .v{display:block;font-family:var(--mono);font-weight:700;font-size:.82em;line-height:1.1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.idc .f.nm .v{font-size:1.28em}
/* the fine print, one line, then the machine-readable strip along the foot */
.idc .micro{flex:none;padding:0 3.6cqw .3em;font-size:.46em;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft);
            white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.idc .mrz{flex:none;margin-top:auto;padding:.32em 3.6cqw .36em;border-top:1.5px solid rgba(28,35,64,.4);background:rgba(255,255,255,.4);
          font-family:var(--mono);font-weight:700;font-size:.74em;line-height:1.25;letter-spacing:.05em;white-space:pre;overflow:hidden}
/* ---------- the card in the evidence viewer ----------
   #insp-card is a column: the card on its tilting plate, the buttons under it with room to breathe.
   the plate is the card's own shape and otherwise bare (no dark slab, no rim light): the sleeve gives
   the card its edges, and the glare, laid over the card inside .idcard, sweeps the lamination */
#insp-card{display:none;flex-direction:column;align-items:center}
#inspect[data-kind="card"] #insp-card{display:flex}
#inspect[data-kind="card"] #insp-receipt{display:none}
.plate.card{width:min(80vw,720px,calc(48vh * 1.6));aspect-ratio:1200/750;background:none;border-radius:6px;overflow:visible;box-shadow:none}
.plate.card::after{display:none}
#acard-big{width:100%;height:100%}
/* the flipper: both faces fill the plate, the back pre-turned, the whole thing turning on a click */
.card-flip{position:absolute;inset:0;transform-style:preserve-3d;cursor:pointer;
           transition:transform .7s cubic-bezier(.45,.05,.2,1)}
.card-flip.flipped{transform:rotateY(180deg)}
.card-flip .face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden}
.card-flip .face.back{transform:rotateY(180deg)}
html[data-input="key"] .card-flip:focus-visible{outline:2.5px solid var(--butter);outline-offset:4px;border-radius:6px}
@media (prefers-reduced-motion: reduce){ .card-flip{transition:none} }
/* the back's placeholder composition: the notice in the department's fine print, the strip at the foot */
/* the back, like a real card's: the stripe, the signature strip, the conditions, the code */
.idc.back .mag{flex:none;height:13cqw;margin-top:4.5cqw;background:#1a1d2b;box-shadow:inset 0 2px 0 rgba(255,255,255,.08),inset 0 -2px 0 rgba(0,0,0,.4)}
.idc.back .sigrow{flex:none;display:grid;grid-template-columns:auto 1fr;grid-template-rows:auto auto;column-gap:1.2cqw;align-items:center;padding:3cqw 5cqw 0}
.idc.back .sigrow .l{grid-row:1;font-size:2.3cqw;font-weight:900;letter-spacing:.14em;text-transform:uppercase;color:var(--ink-soft)}
.idc.back .sigrow .strip{grid-row:1;height:6.2cqw;display:flex;align-items:center;padding:0 2cqw;background:repeating-linear-gradient(135deg,#fff 0 6px,#f1eee6 6px 8px);border:1px solid rgba(28,35,64,.35)}
.idc.back .sigrow .strip i{font-family:var(--mono);font-style:italic;font-weight:700;font-size:3.4cqw;color:#2b3350;transform:rotate(-2deg)}
.idc.back .sigrow .signed{grid-column:2;font-size:2.1cqw;font-weight:800;letter-spacing:.1em;text-transform:uppercase;color:var(--ink-soft);margin-top:.6cqw}
.idc.back .terms{flex:1;padding:2.4cqw 5cqw 0;font-size:2.55cqw;line-height:1.35;font-weight:700;color:var(--ink)}
.idc.back .terms p{margin:0 0 .5em}
.idc.back .foot{flex:none;display:flex;justify-content:space-between;align-items:flex-end;gap:2cqw;padding:0 5cqw 3.4cqw}
.idc.back .foot .issuer{font-size:2.1cqw;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft);max-width:48%}
.idc.back .foot .code{display:flex;flex-direction:column;align-items:flex-end;gap:.6cqw;width:38%}
.idc.back .foot .barcode{width:100%;height:5.2cqw;margin:0}
.idc.back .foot .no{font-family:var(--mono);font-size:2.6cqw;letter-spacing:.2em}
.card-hint{margin:clamp(18px,4vh,36px) 0 0;color:#9aa2bd;font:800 12px/1.4 var(--body);letter-spacing:.14em;text-transform:uppercase;text-align:center}   /* the same line the business card has under it */
.idcard .glare{z-index:5}
#acard-acts{display:flex;justify-content:center;align-items:center;gap:14px;margin-top:clamp(18px,4vh,36px)}   /* under the hint */
/* the buttons: the site's own (.btn: nunito 900, ink rule, hard shadow like the gallery arrows). export is
   the thing to do, so it is butter; share is paper, second in line */
#acard-acts .btn{font:900 15px/1.1 var(--body);letter-spacing:.01em;text-transform:none;
                 background:var(--butter);color:var(--ink);border:2.5px solid var(--ink);border-radius:8px;padding:.62em 1.4em;
                 box-shadow:3px 3px 0 var(--ink);transition:transform .12s ease,background .15s ease,box-shadow .12s ease}
#acard-acts .btn[data-card="share"]{background:var(--paper)}
/* like every other button: lighter under the pointer, and it stays where it is */
#acard-acts .btn:hover{transform:none;background:var(--butter-hi)}
#acard-acts .btn[data-card="share"]:hover{background:#fff}
#acard-acts .btn:active{transform:none;box-shadow:3px 3px 0 var(--ink)}
#acard-acts .btn.busy{cursor:progress}
#page::-webkit-scrollbar{width:6px}
#page::-webkit-scrollbar-thumb{background:rgba(28,35,64,.25);border-radius:3px}

/* ---------- paper typography ---------- */
.h{font-family:var(--body);font-weight:900;line-height:1.08;margin:0 0 .5em;
   font-size:clamp(17px,2vh,28px)}
/* a printed question on a form section: body-scale bold, not display type */
.q{font-weight:900;font-size:clamp(15px,1.9vh,26px);line-height:1.18;margin:0 0 .45em}
/* the applicant's own entries on the review paper, run over with a marker */
mark.hl{background:rgba(105,228,158,.72);color:inherit;padding:.06em .28em .1em;margin:0 -.12em;
        border-radius:.25em .15em .3em .12em;-webkit-box-decoration-break:clone;box-decoration-break:clone}
/* the intentionally-blank page: a reserved box mid-page, the standard folio at the foot */
.blankp{height:100%;display:flex;flex-direction:column;color:var(--ink-soft)}
.blankp .bpbox{margin:auto;width:84%;border:2px dashed rgba(28,35,64,.4);border-radius:3px;
               padding:2.2em 1.2em 2em;text-align:center;position:relative}
.blankp .bpl{position:absolute;top:.55em;left:.8em;font-size:clamp(8px,1vh,11px);font-weight:900;
             letter-spacing:.16em;text-transform:uppercase;opacity:.8}
.blankp .bp1{font-weight:900;font-size:clamp(11px,1.4vh,16px);letter-spacing:.22em;text-transform:uppercase;opacity:.85}
.blankp .bp2{font-family:var(--mono);font-weight:400;font-size:clamp(9px,1.15vh,13px);line-height:1.7;margin-top:.9em;opacity:.85}
.blankp .gfoot{opacity:.8}
.sub{font-size:clamp(12px,1.5vh,17px);color:var(--ink-soft);margin:0 0 1em;font-weight:700}
.pg{font-size:clamp(12px,1.5vh,17px);margin:0 0 .8em;line-height:1.45}
.fine{font-size:clamp(10px,1.25vh,14px);color:var(--ink-soft);font-weight:700;margin-top:auto;padding-top:1em}
.spacer{flex:1}

.rule{border:0;border-top:2px solid var(--ink);opacity:.25;margin:.9em 0}

/* form bits, drawn to look like they belong on the paper */
.line{display:flex;flex-direction:column;gap:.35em;margin:0 0 1em}
.line label{font-size:clamp(11px,1.35vh,15px);font-weight:900}
.in{border:0;border-bottom:2.5px solid var(--ink);background:transparent;
    font-family:var(--body);font-weight:800;font-size:clamp(14px,1.9vh,22px);
    padding:.25em .1em;width:100%;color:var(--ink)}
.in:focus{outline:0;border-bottom-color:var(--butter);box-shadow:0 2px 0 var(--butter)}
textarea.in{border:2.5px solid var(--ink);border-radius:6px;padding:.5em .6em;resize:none;
            font-size:clamp(12px,1.6vh,18px);line-height:1.45;min-height:22%}
.count{font-size:clamp(10px,1.2vh,13px);color:var(--ink-soft);text-align:right;margin-top:.25em}

/* tick-box options, the interview answers */
.opt{display:flex;gap:.7em;align-items:flex-start;text-align:left;width:100%;
     background:transparent;border:0;padding:.5em .3em;cursor:pointer;
     font-size:clamp(12px,1.55vh,17px);font-weight:700;line-height:1.35;border-radius:6px}
.opt:hover{background:rgba(255,216,77,.35)}
.opt .box{flex:none;width:1.35em;height:1.35em;border:2.5px solid var(--ink);border-radius:3px;
          display:grid;place-items:center;font-weight:900;font-size:.85em}
.opt.on .box::after{content:"✕"}
.opt.on{background:rgba(201,188,255,.4)}

/* buttons i draw in code */
.btn{border:2.5px solid var(--ink);background:var(--butter);border-radius:8px;min-height:40px;
     padding:.5em 1.1em;font-weight:900;font-size:clamp(12px,1.5vh,17px);cursor:pointer;
     transition:transform .12s ease,background .15s ease}
.btn:hover{transform:translateY(-2px)}
.btn:active{transform:translateY(0)}
.btn.ghost{background:transparent}
.btn.ghost:hover{background:rgba(28,35,64,.08)}
.btn:disabled{opacity:.4;cursor:not-allowed;transform:none}
.btn.busy{opacity:1;cursor:progress;display:inline-flex;align-items:center;gap:.55em}
.spin{width:1em;height:1em;flex:none;border-radius:50%;border:2.5px solid rgba(28,35,64,.25);
      border-top-color:var(--ink);animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
.row{display:flex;gap:.7em;align-items:center;flex-wrap:wrap;margin-top:.6em}

.err{background:var(--coral);border:2.5px solid var(--ink);border-radius:6px;
     padding:.4em .7em;font-size:clamp(11px,1.35vh,15px);font-weight:800;display:inline-block;margin-top:.5em}

/* cover button art: scales up and lifts on hover, pivoting on the button itself */
.cov-btn{transition:transform .2s ease;will-change:transform}
.cov-btn.on{transform:translateY(-4px) scale(1.06)}

/* cover buttons sit on the closed folder */
.cover-hit{position:absolute;z-index:4;cursor:pointer;background:transparent;border:0}

/* back button: the art is a full-canvas layer, the button is an invisible hit box on top */
#f-back{z-index:8}
#back{position:absolute;z-index:9;cursor:pointer;background:transparent;border:0;padding:0}

/* ---------- gallery overlay ---------- */
#gallery{position:fixed;inset:0;display:none;z-index:20;overflow:hidden;
         background:rgba(5,6,12,.7);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
         flex-direction:column;align-items:center;justify-content:center;
         opacity:0;transition:opacity .3s ease}
#gallery.on{display:flex}
#gallery.in{opacity:1}
/* the same bare x as the other overlays' close buttons (.ov-close): no ring, no box */
.gal-close{position:absolute;top:16px;right:18px;width:44px;height:44px;border-radius:50%;
           border:0;background:none;color:#f2f5ff;text-shadow:0 1px 8px rgba(0,0,0,.9);
           font:900 30px/1 var(--body);cursor:pointer;display:grid;place-items:center;
           transition:transform .15s ease}
.gal-close:hover{transform:scale(1.12)}

/* ---------- cropped art: the wall pieces, the bell and the task tray on the desk ----------
   these are tight crops, not full-frame layers. the wall ones are placed by the CFG hit box their
   data-box names and fitted inside it; the .art ones (desk pieces) are placed in room-art pixels
   from CFG.art, so they follow the background exactly (see applyCfg). the .hi ones share the
   desk-item hover glow. */
.layer.crop{inset:auto;object-fit:contain}
/* unseen announcements: the board art breathes a butter glow, the same grammar as the bell.
   hovering it hands over to the shared desk-item highlight. */
#s-room #hi-board.fresh:not(.on){filter:drop-shadow(0 0 10px rgba(255,216,77,.55));
  animation:boardPulse 2.4s ease-in-out infinite}
@keyframes boardPulse{50%{filter:drop-shadow(0 0 22px rgba(255,216,77,.9))}}
/* the papers on the board: six full-board crops (noticeboard-paper-1..6), each with one sheet on it,
   stacked on the blank board like nft trait layers, 1 at the bottom. they don't glow or take the
   board's click: each just scales up a touch while the mouse is over its sheet (a .paper-hit span
   inside the board hit, boxed from CFG.papers). while the board lifts on hover they lift with it. */
.paper{transition:transform .25s ease}
#hi-board.on ~ .paper{transform:translateY(-3px)}
#hi-board.on ~ .paper.on{transform:translateY(-3px) scale(1.12);z-index:1}
.paper-hit{position:absolute;display:block}

/* ---------- notices overlay: pinned papers on a dark blurred backdrop, newest on top ---------- */
#notices{position:fixed;inset:0;display:none;z-index:20;overflow-y:auto;overflow-x:hidden;
         background:rgba(5,6,12,.72);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
         opacity:0;transition:opacity .3s ease;scrollbar-width:none}   /* scrolls, but shows no bar */
#notices.on{display:block}
#notices.in{opacity:1}
#notices::-webkit-scrollbar{display:none}
.notes-col{width:min(520px,84vw);margin:0 auto;padding:12vh 0 40vh;display:flex;flex-direction:column;gap:56px}
/* top padding is set by script so the newest note opens sitting on the focus line */
.notes-head{color:#9aa2bd;font:800 12px/1.4 var(--body);letter-spacing:.14em;text-transform:uppercase;
            text-align:center;margin-bottom:6px}
/* each note is a sheet of paper art (assets/noticeboard) with its pin drawn in. the art's aspect
   ratio is set inline from NOTE_ART, so the sheet keeps its shape and the text has to fit it:
   Type sizes stay fixed; preview long messages with a suitable paper. the pin sticks up above
   the paper inside the image, so text starts --pin-gap below the top edge of the art. */
.note{
  position:relative;padding:var(--pin-gap,70px) 34px 26px;color:var(--ink);
  --fs:1;
  display:flex;flex-direction:column;
  /* --sc and --alpha are set by script from distance to the focus line: the note there is full size
     and sharp, the ones toward the edges shrink, soften and fade. the blur is set as an inline filter
     only on notes that need one: a permanent filter layer leaves seams between the cards. */
  transform:rotate(var(--rot,0deg)) translateX(var(--off,0px)) scale(var(--sc,1));
  transform-origin:center center;
  opacity:var(--alpha,1);
  transition:transform .12s linear,filter .12s linear,opacity .12s linear;
  /* entrance: each sheet flies up from below the screen, overshoots a touch and settles where it
     hangs. --in is a per-note delay set by script, so the newest lands first and the rest follow.
     the fill is backwards only: once landed, the scroll-driven transform above takes over. */
  animation:noteIn .8s cubic-bezier(.3,1.35,.5,1) var(--in,0s) backwards}
@keyframes noteIn{
  from{transform:translateY(110vh) rotate(calc(var(--rot,0deg) + 14deg)) scale(.9);opacity:0}
  35%{opacity:var(--alpha,1)}
  to{transform:rotate(var(--rot,0deg)) translateX(var(--off,0px)) scale(var(--sc,1));opacity:var(--alpha,1)}
}
@media (prefers-reduced-motion: reduce){ .note{animation:none} }
.note{container-type:inline-size}
.note .n-art{position:absolute;inset:0;width:100%;height:100%;z-index:0;pointer-events:none;-webkit-user-drag:none;
             box-sizing:border-box;border:solid transparent;border-width:calc(var(--cap,.28) * 100cqw) 0;
             border-image:var(--paper) 28% 0 fill / 1 / 0 stretch;   /* the top and bottom slices at their drawn height, the middle stretched to fit */
             filter:drop-shadow(0 12px 16px rgba(0,0,0,.45))}
.note .n-art-mobile{display:none}
/* the "new" sticker: drawn at the paper's width with its mark near the top right, laid over the paper's top edge */
.note .n-new{position:absolute;left:0;top:0;width:100%;height:auto;z-index:2;pointer-events:none;-webkit-user-drag:none}   /* the paper's width, on its top edge */
@media (max-width:700px),(max-aspect-ratio:1/1),(max-height:600px){
  .note.has-mobile .n-art-desktop{display:none}
  .note.has-mobile .n-art-mobile{display:block}
}
.note > :not(.n-art):not(.n-new){position:relative;z-index:1}
.note .n-body:last-child{margin-bottom:0}
.note .n-date{font:900 12px/1 var(--body);font-size:calc(12px * var(--fs));letter-spacing:.1em;text-transform:uppercase;color:var(--ink-soft);
              display:flex;justify-content:space-between;align-items:center;margin-bottom:calc(12px * var(--fs))}
.note .n-date .tag{font-size:calc(10px * var(--fs));padding:3px 7px;border-radius:999px;background:rgba(28,35,64,.1)}
.note .n-date .tag.new{background:var(--butter);color:#12141f}
.note .n-title{font-family:var(--body);font-weight:700;font-size:20px;line-height:1.15;margin:0 0 calc(12px * var(--fs))}
.note .n-body{font-size:16px;line-height:1.5;font-weight:400;margin:0}
.note .n-body + .n-body{margin-top:.6em}
.notes-end{color:#6d7492;font:800 12px/1.4 var(--body);text-align:center;margin-top:10px}
@media (prefers-reduced-motion: reduce){ #s-room #hi-board.fresh{animation:none} }

/* ---------- tasks overlay: the clipboard art on a dark blurred backdrop ---------- */
#tasks{position:fixed;inset:0;display:none;z-index:20;overflow:hidden;
       background:rgba(5,6,12,.7);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
       opacity:0;transition:opacity .3s ease}
#tasks.on{display:block}
#tasks.in{opacity:1}
/* the art is a tight crop of the clipboard (1044x1420). the wrap keeps that shape and is sized to
   fill the height of the viewport, or the width on a narrow screen, without spilling off either */
.tasks-wrap{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);
            height:min(84vh,112vw);aspect-ratio:1044/1420}
.tasks-wrap img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;pointer-events:none;-webkit-user-drag:none}
.tasks-wrap .slip{display:none}   /* portrait swaps these two over */
/* the writable sheet on the clipboard, placed from CFG.tasksPage */
#tasks-page{position:absolute;overflow:hidden;padding:1.5%;display:flex;flex-direction:column;
            font-size:clamp(11px,1.5vh,17px);line-height:1.4}
#tasks-page .h,#tasks-page .sub{flex:none}
#tasks-page .fine{flex:none;margin-top:0;padding-top:.8em}
/* the list scrolls between the header and the fine print. its ends fade out under them, and a thin
   rule marks each edge so the cut reads as deliberate */
.task-scroll{flex:1;min-height:0;display:flex;flex-direction:column;
             border-top:2px solid rgba(28,35,64,.25);border-bottom:2px solid rgba(28,35,64,.25)}
.task-list{flex:1;min-height:0;overflow-y:auto;scrollbar-width:none;padding:1em 0;
           --fade:1.4em;
           -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 var(--fade),#000 calc(100% - var(--fade)),transparent 100%);
           mask-image:linear-gradient(to bottom,transparent 0,#000 var(--fade),#000 calc(100% - var(--fade)),transparent 100%)}
.task-list::-webkit-scrollbar{display:none}
/* one task per row: tick box, label, and a small link that opens the thing to do */
.task{display:flex;gap:.7em;align-items:center;width:100%;padding:.5em .3em;border-radius:6px;
      border-bottom:2px dashed rgba(28,35,64,.18);font-size:clamp(12px,1.55vh,17px);font-weight:800;line-height:1.3}
.task:last-of-type{border-bottom:0}
.task .tick{flex:none;width:1.35em;height:1.35em;border:2.5px solid var(--ink);border-radius:3px;
            background:transparent;padding:0;cursor:pointer;display:grid;place-items:center;font-weight:900;font-size:.85em}
.task .tick:hover{background:rgba(255,216,77,.35)}
.task.done .tick{background:var(--mint)}
.task.done .tick::after{content:"✕"}
.task .what{flex:1;min-width:0}
.task.done .what{text-decoration:line-through;color:var(--ink-soft)}
.task .go{flex:none;font-size:.8em;padding:.3em .7em;text-decoration:none;color:var(--ink)}
/* ---------- the tray on the team's task model ----------
   the heading and the count share a line. a task is a line that opens; inside, the brief and each
   action with its own mark, the chips for what the post must carry, the square that opens x, and
   the field and button where the department can check. */
#tasks-page .task-head{flex:none;display:flex;align-items:baseline;justify-content:space-between;gap:1em}
#tasks-page .task-head .sub{margin:0;text-align:right}
.task{cursor:pointer;user-select:none;padding:.55em .3em}
.task .tick{cursor:inherit;font-size:.8em}
.task .tick:hover{background:transparent}
.task:hover .what{color:var(--ink)}
/* the marks: passed is a stamp, in flight is dotted, refused is coral with a bang, paused is faint */
.task.done .tick{background:var(--mint);border-style:solid}
.task.done .tick::after{content:"✓"}
.task.waiting .tick{border-style:dotted}
.task.refused .tick{border-color:var(--coral)}
.task.refused .tick::after{content:"!";color:var(--ink)}
.task.off{opacity:.55}
.task .due{flex:none;font-size:.72em;font-weight:800;letter-spacing:.06em;color:var(--ink-soft);text-transform:lowercase}
.task .chev{flex:none;width:1.1em;height:1.1em;color:var(--ink-soft);transition:transform .18s ease}
.task .chev svg{width:100%;height:100%;fill:none;stroke:currentColor;stroke-width:2.6;stroke-linecap:round;stroke-linejoin:round}
.task.open .chev{transform:rotate(180deg)}
.task.done .chev{visibility:hidden}
.task.open{border-bottom-style:solid;border-bottom-color:rgba(28,35,64,.1)}
/* the open task: the brief, then its actions, indented under the line */
.task-body{padding:.2em .3em .6em 2.2em;border-bottom:2px dashed rgba(28,35,64,.18)}
.task-body .brief{margin:0 0 .5em;font-size:.86em;font-weight:700;line-height:1.35;color:var(--ink-soft)}
.act{display:flex;align-items:center;gap:.55em;padding:.35em 0;font-size:.9em;font-weight:800}
.act .mark{flex:none;width:.95em;height:.95em;border:2px solid var(--ink);border-radius:50%;display:grid;place-items:center;font-size:.7em;font-weight:900;line-height:1}
.act.done .mark{background:var(--mint)}
.act.done .mark::after{content:"✓"}
.act.waiting .mark{border-style:dotted}
.act.refused .mark{border-color:var(--coral)}
.act.refused .mark::after{content:"!"}
.act.optional .mark{border-style:dashed;border-color:var(--ink-soft)}
.act.done .verb{text-decoration:line-through;color:var(--ink-soft)}
.act .verb{flex:none}
.act .verb small{margin-left:.5em;font-size:.72em;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:var(--ink-soft)}
.act .need{flex:1;min-width:0;display:flex;flex-wrap:wrap;gap:.3em}
.act .chip{font-family:var(--mono);font-size:.78em;font-weight:700;padding:.1em .45em;border:1.5px solid rgba(28,35,64,.4);border-radius:4px;color:var(--ink);text-decoration:none;background:rgba(255,255,255,.35)}
.act a.chip:hover{background:var(--butter)}
.act .go.sq{margin-left:auto;width:1.9em;height:1.9em;padding:0;display:grid;place-items:center;border:2px solid var(--ink);border-radius:5px;background:transparent;line-height:0}
.act .go.sq:hover{background:var(--butter)}
.act .go.sq svg{width:.95em;height:.95em;display:block;fill:none;stroke:var(--ink);stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round}
/* the field for the link and the one button that uses it */
.task-do{display:flex;gap:.5em;align-items:center;padding:.15em 0 .5em 1.5em}
.task-do.bare{justify-content:flex-start}
.task-do .hint{font-size:.82em;font-weight:700;color:var(--ink-soft)}
.task-do .din{flex:1;min-width:0;height:2.2em;padding:0 .7em;border:2px solid var(--ink);border-radius:5px;background:rgba(255,255,255,.55);color:var(--ink);font:inherit;font-weight:700;font-size:.85em}
.task-do .din::placeholder{color:var(--ink-soft);font-weight:600}
.task-do .din:focus{outline:none;background:#fff;box-shadow:inset 0 0 0 2px rgba(255,216,77,.55)}
.task-do .btn{flex:none;height:2.2em;min-height:0;padding:0 .9em;font-size:.82em}
.task-note{margin:0;padding:0 0 .5em 1.5em;font-size:.8em;font-weight:700;color:var(--ink-soft)}
.task-note.bad{color:#8d2f22}

/* ---------- socials overlay: the department's plaque on a dark blurred backdrop ---------- */
#socials{position:fixed;inset:0;display:none;z-index:20;overflow:hidden;
         background:rgba(5,6,12,.7);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
         opacity:0;transition:opacity .3s ease}
#socials.on{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:18px;perspective:1200px}
#socials.in{opacity:1}
/* the business card: two faces drawn in code, the shape of a real card (3.5 by 2). the wrap fits the
   viewport and leans toward the cursor (the same --rx/--ry tilt as the gallery plate, painted by
   script); the card inside it turns over on click, and each face hides its back so the reverse shows
   through the turn. sizes inside are cqw of the wrap, so the card scales as one piece. */
.soc-wrap{position:relative;width:min(600px,92vw,120vh);aspect-ratio:7/4;container-type:inline-size;
          transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));transform-style:preserve-3d;will-change:transform}
.soc-card{position:absolute;inset:0;transform-style:preserve-3d;cursor:pointer;
          transition:transform .7s cubic-bezier(.45,.05,.2,1)}
.soc-card.flipped{transform:rotateY(180deg)}
.soc-face{position:absolute;inset:0;backface-visibility:hidden;-webkit-backface-visibility:hidden}
.soc-face.back{transform:rotateY(180deg)}
.soc-card.flipped .soc-face.front,.soc-card:not(.flipped) .soc-face.back{pointer-events:none}   /* the links sleep while they face away */
.soc-hint{margin:0;color:#9aa2bd;font:800 12px/1.4 var(--body);letter-spacing:.14em;text-transform:uppercase;text-align:center}
@media (prefers-reduced-motion: reduce){ .soc-wrap{transform:none} .soc-card{transition:none} }
/* ---------- elevator overlay: the button panel on the same dark blurred backdrop ---------- */
#elevator{position:fixed;inset:0;display:none;z-index:20;overflow:hidden;
          background:rgba(5,6,12,.7);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
          opacity:0;transition:opacity .3s ease}
#elevator.on{display:flex;align-items:center;justify-content:center;perspective:1200px}
#elevator.in{opacity:1}
/* the panel art is a tight 324x737 crop. the wrap keeps that shape, fits the viewport (it is tall, so
   the height usually wins) and leans toward the cursor like the socials plaque */
.elev-wrap{position:relative;width:min(340px,80vw,37vh);aspect-ratio:324/737;
           transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));transform-style:preserve-3d;will-change:transform}
.elev-wrap img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;pointer-events:none;-webkit-user-drag:none;
               filter:drop-shadow(var(--shx,0px) var(--shy,24px) 28px rgba(0,0,0,.55))}
@media (prefers-reduced-motion: reduce){ .elev-wrap{transform:none} }
/* the card's stock: heavy cream paper on both faces (the card holder on the desk is cream), navy print,
   a printed rule inside the edge and a fine grain, a hard shadow that follows the tilt */
.bc{--stock:#f4efe2;--print:#1c2340;--soft:#4a5270;--rule:rgba(28,35,64,.35);
    box-sizing:border-box;border-radius:3cqw;overflow:hidden;background:var(--stock);color:var(--print);
    box-shadow:var(--shx,0px) var(--shy,24px) 28px rgba(0,0,0,.55);
    display:flex;flex-direction:column;justify-content:center;align-items:center;gap:5cqw;padding:5cqw 6cqw}
.bc::before{content:"";position:absolute;inset:2cqw;border:.28cqw solid var(--rule);border-radius:1.8cqw;pointer-events:none}
.bc::after{content:"";position:absolute;inset:0;pointer-events:none;   /* the stock's grain: a soft sheen and a fine dot screen */
           background:linear-gradient(115deg,rgba(255,255,255,.35),transparent 45%,rgba(28,35,64,.05)),
                      radial-gradient(rgba(28,35,64,.09) .5px,transparent .9px) 0 0/1.6cqw 1.6cqw}
.bc.rev{justify-content:space-between;align-items:stretch;gap:0;padding:4.4cqw 6cqw 4.2cqw}
.bc > *{position:relative;z-index:1}
/* the front: the wordmark, a line under it, and two printed marks: outlined squares in the card's ink that
   fill when the mouse is on them. the chrome is four small words in the corners, like a printed card's */
.bc-logo{width:42cqw;height:auto;display:block;margin-top:1cqw;filter:drop-shadow(0 .8cqw 0 rgba(28,35,64,.22))}
.bc-sub{margin:-2.6cqw 0 -.4cqw;font:800 1.9cqw/1 var(--body);letter-spacing:.24em;text-transform:uppercase;color:var(--soft)}
.bc-discs{display:flex;gap:3.2cqw;justify-content:center}
.soc{text-decoration:none;color:inherit}
.soc.disc{width:10cqw;height:10cqw;border-radius:2cqw;box-sizing:border-box;border:.4cqw solid var(--print);display:grid;place-items:center;
          background:transparent;color:var(--print);transition:background .15s ease,color .15s ease,transform .14s ease}
.soc.disc svg{width:46%;height:46%;fill:currentColor}
.soc.disc:hover,.soc.disc:focus-visible{background:var(--print);color:var(--stock);transform:translateY(-.3cqw);outline:none}
.soc.disc:active{transform:none}
.bc-corner{position:absolute;font:800 1.7cqw/1 var(--body);letter-spacing:.22em;text-transform:uppercase;color:var(--soft);opacity:.85}
.bc-corner.tl{left:4.6cqw;top:4.2cqw}.bc-corner.tr{right:4.6cqw;top:4.2cqw}.bc-corner.bl{left:4.6cqw;bottom:4.2cqw}.bc-corner.br{right:4.6cqw;bottom:4.2cqw}
/* the back: a real card's chrome. the department up top over a rule; the clerk on the left, the contact lines
   on the right; the small print of a place that does not exist */
.bc-head{display:flex;align-items:center;gap:2.2cqw;padding-bottom:2.2cqw;border-bottom:.35cqw solid var(--print)}
.bc-seal{width:7.5cqw;height:7.5cqw;flex:none}   /* the emblem, as supplied: no wrapper */
.bc-name{display:flex;flex-direction:column;gap:.7cqw;line-height:1}
.bc-name b{font:900 3.6cqw/1 var(--body);letter-spacing:.1em;text-transform:uppercase}
.bc-name small{font:800 1.85cqw/1 var(--body);letter-spacing:.18em;text-transform:uppercase;color:var(--soft)}
.bc-body{display:flex;justify-content:space-between;align-items:flex-end;gap:4cqw;padding-top:2cqw}
.bc-who{display:flex;flex-direction:column;gap:.9cqw;line-height:1;flex:1 1 0;min-width:0}
.bc-who b{font:900 4.4cqw/1 var(--body);letter-spacing:.02em;margin-bottom:.4cqw}
.bc-who span{font:800 2cqw/1 var(--body);letter-spacing:.16em;text-transform:uppercase;color:var(--soft)}
.bc-who em{font:800 1.75cqw/1.3 var(--body);letter-spacing:.14em;text-transform:uppercase;font-style:normal;color:var(--soft);margin-top:2.4cqw;opacity:.8}
.bc-lines{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:.9cqw;flex:0 0 auto;max-width:52%}
.bc-lines li,.bc-lines .bcl{display:flex;align-items:flex-start;gap:1.6cqw;font:700 2.2cqw/1.3 var(--mono);color:var(--print);min-width:0}
.bc-lines svg{flex:none;width:2.6cqw;height:2.6cqw;margin-top:.2cqw;fill:var(--soft)}
.bc-lines small{font:inherit;color:var(--soft)}
.bc-lines .bcl{text-decoration:none}
.bc-lines .bcl svg{fill:var(--print)}
.bc-lines .bcl span{border-bottom:.28cqw solid transparent;transition:border-color .15s ease,color .15s ease}
.bc-lines .bcl:hover span,.bc-lines .bcl:focus-visible span{border-color:var(--print)}
.bc-lines .bcl:focus-visible{outline:none}
.soc-card:focus-visible{outline:none}
.soc-card:focus-visible .bc{box-shadow:0 0 0 .5cqw var(--butter),var(--shx,0px) var(--shy,24px) 28px rgba(0,0,0,.55)}

/* ---------- inspect: one FOMP on a tilting plate, arrows either side ---------- */
.tilt{perspective:1200px}
/* script sets, eased every frame: --rx/--ry tilt, --ga glare angle,
   --glare 0 flat -> 1 fully tilted, --lx/--ly rim light, --shx/--shy shadow */
.plate{
  position:relative;
  width:min(72vh,72vw,680px);
  aspect-ratio:1/1;
  border-radius:14px;overflow:hidden;
  background:#12141f;
  box-shadow:var(--shx,0px) var(--shy,30px) 70px rgba(0,0,0,.6);
  transform:rotateX(var(--rx,0deg)) rotateY(var(--ry,0deg));
  will-change:transform;
}
.plate img{position:absolute;inset:0;width:100%;height:100%;object-fit:contain;pointer-events:none;-webkit-user-drag:none}
.glare,.plate::after{position:absolute;inset:0;pointer-events:none;border-radius:inherit}
.glare{overflow:hidden}
.glare i{
  position:absolute;left:50%;top:50%;width:200%;height:200%;
  background-image:linear-gradient(0deg, rgba(255,255,255,0) 0%, rgba(255,255,255,1) 100%);
  transform:translate(-50%,-50%) rotate(var(--ga,180deg));
  transform-origin:50% 50%;
  opacity:calc(var(--glare,0) * .35);
}
.plate::after{
  content:"";
  box-shadow:inset var(--lx,0px) var(--ly,0px) 0 0 rgba(255,255,255,.5),
             inset 0 0 0 1px rgba(255,255,255,.10);
  opacity:var(--glare,0);
}
/* nav row under the plate: prev arrow, counter, next arrow */
.gal-nav{display:flex;align-items:center;justify-content:center;gap:34px;margin-top:22px}
/* the drawn arrow is the whole control: no plate, no border, no shadow behind it. it sits back at
   60% until it is wanted, and comes up to full on hover, so the frames either side of the picture
   stay quiet while you are looking at the picture. */
.gal-arrow{
  --sz:48px;
  width:var(--sz);height:var(--sz);cursor:pointer;padding:0;
  border:0;background:none;color:inherit;
  display:grid;place-items:center;opacity:.6;
  transition:transform .12s ease,opacity .15s ease}
.gal-arrow img{width:100%;height:100%;object-fit:contain;display:block;-webkit-user-drag:none;user-select:none}
#galPrev img{transform:scaleX(-1)}   /* the one drawing, mirrored */
.gal-arrow:hover,.gal-arrow:focus-visible{opacity:1}
html[data-input="key"] .gal-arrow:focus-visible{outline:2.5px solid var(--butter);outline-offset:3px;border-radius:6px}
#galPrev:hover{transform:translateX(-3px)}
#galNext:hover{transform:translateX(3px)}
.gal-arrow:active{transform:scale(.92)}
@media (max-width:640px){ .gal-arrow{--sz:40px} .gal-nav{gap:16px} }
/* a finger has no hover, so the arrows sit at full strength where there is no pointer to rest */
@media (hover:none){ .gal-arrow{opacity:1} }
/* landscape (desktop): the arrows flank the plate instead, one either side at its middle. the row is
   lifted out of the column and stretched to the plate's width plus an arrow and a gap each side, so
   the plate itself sits dead centre. portrait keeps the row under the plate */
@media (min-aspect-ratio: 1/1){
  .gal-nav{position:absolute;left:50%;top:50%;translate:-50% -50%;margin:0;justify-content:space-between;
           width:calc(min(72vh,72vw,680px) + 2 * 76px);pointer-events:none}
  .gal-arrow{pointer-events:auto}
}
@media (prefers-reduced-motion: reduce){
  .plate{transform:none}
  .glare,.plate::after{display:none}
}

/* ---------- tooltip: one shared label that follows the mouse over any [data-tip] ---------- */
/* ---------- the vent: the quiet tell, the whisper, the receipt ---------- */
#hi-vent{opacity:1;transition:filter .3s ease}
#hi-vent.peek{filter:brightness(1.22)}   /* linger a beat and the slats catch the light. that's the whole hint */
/* his bubble is the clerk's bubble (.bub, same type, same fade), shrunk to its text and centred on
   the bottom middle of its art box, so the tail points at the vent. his answers are the clerk's
   answer boxes (#dlg .ch rules, which name #vopts too), stacked in their own box under the vent */
#vopts{position:fixed;left:50%;translate:-50% 0;bottom:max(5vh,44px);width:min(640px,92vw);z-index:22}
#vbub,#vopts{font-family:var(--body);color:#f2f5ff;opacity:0;visibility:hidden;
             transform:translateY(8px) scale(.98);transform-origin:bottom center;transition:opacity .28s ease,transform .28s ease}
#vbub.on,#vopts.on{opacity:1;visibility:visible;transform:none}
/* the answers under the vent hold their own blur too, so the group slides without fading */
#vopts{transition:transform .28s ease}
#vbub{z-index:8}
#vbub .bub{position:absolute;left:50%;bottom:0;translate:-50% 0;width:max-content;max-width:100%;pointer-events:auto}
#vbub .said{text-wrap:pretty;text-align:center}
#vopts{pointer-events:auto}
.hit.vitem{display:none;transform:rotate(-7deg);background:#f4efe2;border:2px solid #1c2340;border-radius:3px;
           box-shadow:2px 3px 0 rgba(0,0,0,.5);transition:transform .2s ease}
.hit.vitem.on{display:block}
.hit.vitem:hover{transform:rotate(-4deg) translateY(-2px)}
.hit.vitem::after{content:"";position:absolute;left:12%;right:12%;top:40%;border-top:1.5px solid rgba(28,35,64,.5)}
#inspect{position:fixed;inset:0;z-index:24;display:none;align-items:center;justify-content:center;
         background:rgba(5,6,12,.7);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);   /* the same dark blurred ground as every other overlay */
         opacity:0;transition:opacity .25s ease}
#inspect.on{display:flex}
#inspect.in{opacity:1}
/* the card: the viewer is not faded as one piece. its ground darkens and blurs on its own properties (an animating
   opacity would hold the blur back, as on the intro), while the card flies out of the folder (flyCardIn); the
   close button, the hint and the buttons come up once it is on its way */
#inspect[data-kind="card"]{opacity:1;background:rgba(5,6,12,0);backdrop-filter:blur(0px);-webkit-backdrop-filter:blur(0px);
                           transition:background .34s ease,backdrop-filter .34s ease,-webkit-backdrop-filter .34s ease}
#inspect[data-kind="card"].in{background:rgba(5,6,12,.7);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
#inspect[data-kind="card"] :is(#insp-close,.card-hint,#acard-acts){opacity:0;transition:opacity .16s ease}
#inspect[data-kind="card"].in :is(#insp-close,.card-hint,#acard-acts){opacity:1;transition:opacity .28s ease .2s}
#acard.lifted{visibility:hidden}   /* off the folder, in the viewer */
#iplate{width:min(320px,80vw);background:#f4efe2;border-radius:6px;padding:26px 24px 20px;color:var(--ink);
        font:700 clamp(12px,1.6vh,15px)/1.5 var(--body)}
/* the queue ticket: a perforation up top, the number doing all the talking */
#iplate .tik{text-align:center}
#iplate .tik::before{content:"";display:block;margin:-14px auto 16px;width:82%;border-top:2px dashed rgba(28,35,64,.4)}
#iplate .tik-h{font-weight:900;letter-spacing:.14em;text-transform:uppercase;font-size:.95em}
#iplate .tik-sub{font-weight:800;letter-spacing:.16em;text-transform:uppercase;font-size:.62em;color:var(--ink-soft);margin-top:.35em}
#iplate .tik-n{font-weight:900;font-size:7.5em;line-height:1;margin:.12em 0 .05em}
#iplate .tik-note{font-family:var(--mono);font-weight:700;font-size:.82em}
#iplate .tik-f{font-family:var(--mono);font-weight:400;font-size:.66em;color:var(--ink-soft);line-height:1.6;
               border-top:1.5px solid rgba(28,35,64,.35);margin-top:1.1em;padding-top:.7em}
#tip{position:fixed;left:0;top:0;z-index:40;pointer-events:none;opacity:0;
     transform:translateY(4px);transition:opacity .16s ease,transform .16s ease;
     background:rgba(9,10,16,.86);color:#f2f5ff;border:1.5px solid rgba(242,245,255,.28);
     border-radius:999px;padding:5px 12px;font:800 12px/1.3 var(--body);letter-spacing:.02em;
     white-space:nowrap;backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
     box-shadow:0 6px 18px rgba(0,0,0,.45)}
#tip.on{opacity:1;transform:none}
#tip.wrap{white-space:normal;max-width:min(300px,calc(100vw - 24px));border-radius:12px;padding:7px 12px}
#reset{position:fixed;right:12px;bottom:34px;z-index:31;cursor:pointer;
       background:rgba(9,10,16,.8);color:#b9c0d8;border:1.5px solid rgba(242,245,255,.3);
       border-radius:999px;padding:6px 13px;font-size:12px;font-weight:800;
       backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px);
       transition:color .15s ease,border-color .15s ease,background .15s ease}
#reset:hover{color:#12141f;background:var(--butter);border-color:var(--butter)}
/* the volume, bottom left on every scene: the slider art is the track and the button art is the knob,
   both drawn at their own size (116x32 and 32x32), so the knob travels the 84px between them. there is
   no separate switch - the middle is 50, the mix as tuned, and the far left is off.
   the bar is cut out of the slider art: a 100x5 window at 8,14. three layers, top down - the art
   itself, a black cover over whatever is right of the knob, and the level gradient underneath it.
   so the gradient doesn't stretch as it fills: it is always the full 100px and the cover uncovers it */
#vol{position:fixed;left:12px;bottom:30px;z-index:31;width:116px;height:32px;margin:0;padding:0;
     --v:50;                                 /* where the knob is, 0..100, set by applyVolume */
     --fill:calc(var(--v) * .84px);          /* the knob's centre, measured from the window's left edge */
     background:
       url(../assets/room/volume-slider.png) no-repeat center/116px 32px,
       linear-gradient(#000,#000) no-repeat calc(8px + var(--fill)) 14px/calc(100px - var(--fill)) 5px,
       linear-gradient(90deg,#206b3c,#57c47c 50%,#b6f2d5) no-repeat 8px 14px/100px 5px;
     cursor:pointer;-webkit-appearance:none;appearance:none;opacity:.6;transition:opacity .15s ease}
#vol:hover,#vol:active{opacity:1}
html[data-input="key"] #vol:focus-visible{opacity:1;outline:2px solid var(--butter);outline-offset:3px;border-radius:4px}
/* the track itself stays clear: the art behind the input is what you see */
#vol::-webkit-slider-runnable-track{height:32px;border:0;background:none}
#vol::-moz-range-track{height:32px;border:0;background:none}
/* the knob is the button art, 1:1, travelling the track's width less its own */
#vol::-webkit-slider-thumb{-webkit-appearance:none;appearance:none;width:32px;height:32px;margin-top:0;border:0;border-radius:0;
     background:url(../assets/room/volume-button.png) no-repeat center/32px 32px}
#vol::-moz-range-thumb{width:32px;height:32px;border:0;border-radius:0;
     background:url(../assets/room/volume-button.png) no-repeat center/32px 32px}
/* off, whether muted by a tap or dragged to the far left: the bar goes black under the art (the
   cover spans the whole window) and the button takes its second face */
#vol.muted{--fill:0px}
#vol.muted::-webkit-slider-thumb{background-image:url(../assets/room/volume-disabled.png)}
#vol.muted::-moz-range-thumb{background-image:url(../assets/room/volume-disabled.png)}
#reset.armed{color:#12141f;background:var(--coral);border-color:var(--coral)}

#s-room .hit:focus:not(:focus-visible){outline:none}
#folder .ov-close{display:flex}   /* the folder's x shows on desktop too; the drawn close button is gone */
/* ---------- dialogue ---------- */
#dlg{position:fixed;left:50%;bottom:9vh;transform:translateX(-50%) translateY(10px);
     width:min(820px,76vw);z-index:15;opacity:0;visibility:hidden;
     /* no opacity fade on the group: the rows inside carry backdrop-filter and their own .ready
        fade, and an animating opacity here groups them and holds their blur back until it settles */
     transition:transform .3s ease;
     font-family:var(--body);color:#f2f5ff}
#dlg.on{opacity:1;visibility:visible;transform:translateX(-50%)}
/* the panel is a layout box 820 wide, not a surface. left solid it swallows every click in its empty
   half, and on a wide window that box sits right over the desk's back arrow. only what can actually
   be pressed takes the pointer; the rest of the desk stays reachable while the clerk is talking. */
#dlg{pointer-events:none}
#dlg button,#dlg input,#dlg textarea,#dlg select,#dlg label,#dlg a[href]{pointer-events:auto}
/* while the clerk is still typing the rows are drawn at opacity 0 but were still taking presses, so a
   press on a button nobody can see only skipped the typing and looked like it had been swallowed.
   nothing answers until it can be seen; the press falls through to the skip, as clicking anywhere does */
#dlg:not(.ready) .ch,#dlg:not(.ready) .dbtn,#vopts:not(.ready) .ch{pointer-events:none}

/* the clerk speaks from a bubble beside his head. the only solid panel on screen. */
#bubble{position:absolute;z-index:14;opacity:0;visibility:hidden;
        width:max-content;translate:-50% 0;
        transform:translateY(8px) scale(.98);transform-origin:bottom center;
        transition:opacity .28s ease,transform .28s ease;
        font-family:var(--body);color:#f2f5ff;pointer-events:none}
#bubble.on{opacity:1;visibility:visible;transform:none}
.bub{position:relative;background:rgba(9,10,16,.78);
     backdrop-filter:blur(16px) saturate(140%);-webkit-backdrop-filter:blur(16px) saturate(140%);
     border:2px solid rgba(242,245,255,.35);border-radius:18px;
     padding:.85em 1.1em .95em;box-shadow:0 12px 38px rgba(0,0,0,.55)}
/* tail, pointing down at the clerk's head */
.bub::before,.bub::after{content:"";position:absolute;left:50%;translate:-50% 0;width:0;height:0;border-style:solid}
.bub::before{bottom:-20px;border-width:20px 14px 0 14px;
     border-color:rgba(242,245,255,.35) transparent transparent transparent}
.bub::after{bottom:-15px;border-width:16px 11px 0 11px;
     border-color:rgba(9,10,16,.78) transparent transparent transparent}
.bub .who{display:block;font-size:11px;font-weight:900;letter-spacing:.18em;text-transform:uppercase;
     color:var(--butter);margin-bottom:.35em}
.bub .said{font-family:var(--display);font-weight:400;line-height:1.2;
     font-size:clamp(16px,2.3vh,26px);margin:0;min-height:1.2em}
/* beat dots: how far through a multi-line reply the clerk is. they hang under the bubble just left
   of the tail (which is centred, 14px to each side), in the tail's 20px band, centred on it */
#bubble .beats{position:absolute;right:calc(50% + 20px);top:100%;height:20px;display:flex;align-items:center;gap:5px}
#bubble .beats i{width:5px;height:5px;border-radius:50%;background:rgba(242,245,255,.22)}
#bubble .beats i.on{background:var(--butter)}
.caret{display:inline-block;width:.5em;color:var(--butter);
     animation:blink .55s steps(1,end) infinite}
@keyframes blink{50%{opacity:0}}

/* answers: off-white glass boxes, a touch brighter on hover. the go buttons (next, hello, fine...) are butter */
#dlg .choices,#vopts .choices{display:flex;flex-direction:column;align-items:center;gap:7px}
#dlg .ch,#vopts .ch{display:flex;gap:.75em;align-items:baseline;width:min(100%,32em);
     justify-content:flex-start;text-align:left;cursor:pointer;
     background:rgba(242,245,255,.14);border:1.5px solid rgba(242,245,255,.2);border-radius:10px;
     backdrop-filter:blur(14px) saturate(140%);-webkit-backdrop-filter:blur(14px) saturate(140%);
     box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 8px 24px rgba(0,0,0,.35);
     padding:.68em 1.6em;color:#f2f5ff;font-weight:700;line-height:1.35;
     font-size:clamp(13px,1.7vh,17px);text-shadow:0 1px 6px rgba(0,0,0,.9);
     opacity:0;transform:translateY(6px);
     transition:background .14s ease,border-color .14s ease,color .14s ease,
                transform .18s ease,opacity .22s ease}
#dlg.ready .ch,#vopts.ready .ch{opacity:1;transform:none}
#dlg .ch:hover,#vopts .ch:hover{background:rgba(242,245,255,.26);border-color:rgba(242,245,255,.38)}
#dlg .ch .k,#vopts .ch .k{flex:none;color:var(--butter);font-weight:900;font-size:.85em;min-width:1.1em;transition:color .14s ease}
#dlg .ch.go{background:var(--butter);border-color:var(--butter);color:#12141f;text-shadow:none;font-weight:800}
#dlg .ch.go .k{color:#12141f}
#dlg .ch.go:hover{background:var(--butter-hi);border-color:var(--butter-hi)}
/* a lone "next" stays a normal-size button */
#dlg .ch.solo{width:auto;justify-content:center}
/* a group of plain buttons (.pick, set in dlgPanel) sizes to its longest label and the rest match it */
#dlg .choices.pick{align-items:stretch;width:max-content;min-width:12em;max-width:100%;margin:0 auto}
#dlg .choices.pick .ch{width:auto}
/* a chosen interview answer gets no mark of its own. there is nothing to confirm: the press is the
   answer, it goes to the server as it is given, and the clerk is already onto the next line. the
   rows dim while the save is in flight, which is the whole of what there is to say about it.
   aria-pressed stays on the button for anything reading the page aloud. */

/* typed inputs get the same outlined box */
#dlg .field{display:flex;gap:.7em;align-items:center;padding:.6em .85em;max-width:24em;align-self:center;width:100%;
     border:1.5px solid rgba(242,245,255,.3);border-radius:10px;background:rgba(9,10,16,.42);
     backdrop-filter:blur(14px) saturate(140%);-webkit-backdrop-filter:blur(14px) saturate(140%);
     box-shadow:inset 0 1px 0 rgba(255,255,255,.12),0 8px 24px rgba(0,0,0,.35);
     opacity:0;transform:translateY(6px);transition:transform .18s ease,opacity .22s ease,border-color .14s ease}
#dlg.ready .field{opacity:1;transform:none}
#dlg .field:focus-within{border-color:var(--butter)}
#dlg .din{flex:1;min-width:0;background:transparent;border:0;
     color:#fff;font-family:var(--body);font-weight:800;font-size:clamp(14px,1.9vh,20px);
     padding:.2em .1em;outline:0}
#dlg .din::placeholder{color:#6d7492}
#dlg textarea.din{resize:none;height:4.6em;line-height:1.4;font-size:clamp(13px,1.6vh,17px)}
#dlg .field.wide,#dlg .drow.wide{max-width:34em}
/* a button under a field (sign out under the name) is as wide as the field, not the wider .ch */
#dlg .choices:not(.pick) > .ch{max-width:24em}
/* textarea with the counter pinned in its bottom-right corner */
#dlg .field.stack{position:relative;padding-bottom:1.6em}
#dlg .dcount.corner{position:absolute;right:.9em;bottom:.55em}
/* two actions side by side under the textarea */
#dlg .drow{display:flex;gap:7px;width:100%;max-width:24em;
     opacity:0;transform:translateY(6px);transition:transform .18s ease,opacity .22s ease}
#dlg.ready .drow{opacity:1;transform:none}
#dlg .drow .ch{flex:1;width:auto;min-width:0}
#dlg .drow .dbtn{flex:1;padding:.68em 1em;border-radius:10px;font-size:clamp(13px,1.7vh,17px)}
#dlg .dbtn{flex:none;background:var(--butter);color:#12141f;
     box-shadow:inset 0 1px 0 rgba(255,255,255,.25),0 8px 24px rgba(0,0,0,.35);border:1.5px solid var(--butter);
     border-radius:7px;cursor:pointer;font-weight:800;font-size:clamp(12px,1.5vh,16px);padding:.5em 1em;
     transition:background .14s ease,border-color .14s ease}
#dlg .dbtn:hover:not(:disabled){background:var(--butter-hi);border-color:var(--butter-hi)}
#dlg .dbtn:disabled{opacity:.3;cursor:not-allowed}
#dlg .ch:disabled{opacity:.55;cursor:progress}
/* the actions row under the interview is navigation, not the commit affordance: it keeps the answers'
   off-white glass, so the one butter button on a panel stays the thing to do */
#dlg .interview-actions .dbtn,#dlg .dbtn.ghost{
     background:rgba(242,245,255,.14);border-color:rgba(242,245,255,.2);color:#f2f5ff;
     box-shadow:inset 0 1px 0 rgba(255,255,255,.18),0 8px 24px rgba(0,0,0,.35)}
#dlg .interview-actions .dbtn:hover:not(:disabled),#dlg .dbtn.ghost:hover:not(:disabled){
     background:rgba(242,245,255,.26);border-color:rgba(242,245,255,.38)}
#dlg .dnote{padding:.55em .2em 0;text-align:center;font-size:clamp(10px,1.2vh,13px);color:#8d94b0;font-weight:700;
     opacity:0;transition:opacity .22s ease}
#dlg.ready .dnote{opacity:1}
#dlg .dcount{flex:none;font-size:11px;color:#8d94b0;font-weight:800;font-variant-numeric:tabular-nums}
#dlg .derr{margin-top:7px;padding:.5em .9em;border:1.5px solid var(--coral);border-radius:8px;
     font-size:clamp(11px,1.35vh,14px);font-weight:800;color:#ffb3a3;background:rgba(9,10,16,.42);
     backdrop-filter:blur(14px) saturate(140%);-webkit-backdrop-filter:blur(14px) saturate(140%)}
@media (prefers-reduced-motion:reduce){
  #dlg .ch,#vopts .ch,#dlg .field,#dlg .drow,#dlg .dnote{opacity:1;transform:none}
  .caret{animation:none}
}
/* ---------- mobile menu ----------
   a "menu" sign on the desk (assets/menu/hit-menu, portrait only) opens a sheet of the pieces whose
   hits are off in portrait: each is its art with a label under it. the socials ride along as icon
   buttons at the bottom. */
#hi-menu,[data-hit="menu"]{display:none}   /* shown by the portrait block below */
/* ---------- the disclaimer: the hallway's framed picture ---------- */
/* the public notice glows once the wordmark has gone, until it has been read once; hover lights it any time */
#hi-frame{transition:filter .25s ease}
/* until the disclaimer has been read the frame lights up once, as the wordmark clears, and stays lit. no pulse. the hover
   state carries the same animation, so passing over it does not restart the rise */
#s-gate.frame-attract #hi-frame,#s-gate.frame-attract #hi-frame.on{animation:frameAttract .9s ease-out forwards}
@keyframes frameAttract{from{filter:brightness(1) drop-shadow(0 0 0 rgba(255,216,77,0))}to{filter:brightness(1.12) drop-shadow(0 0 14px rgba(255,216,77,.85))}}
#hi-frame.on{animation:none;filter:brightness(1.12) drop-shadow(0 0 14px rgba(255,216,77,.85))}
@media (prefers-reduced-motion: reduce){ #s-gate.frame-attract #hi-frame{animation:none;filter:drop-shadow(0 0 10px rgba(255,216,77,.7))} }
/* the modal: the menu's dark backdrop, one sheet of the department's paper, text only */
#disclaimer{position:fixed;inset:0;display:none;z-index:24;overflow-y:auto;overscroll-behavior:contain;
            background:rgba(5,6,12,.72);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
            opacity:0;transition:opacity .3s ease;scrollbar-width:thin}
#disclaimer.on{display:flex;align-items:flex-start;justify-content:center;
               padding:max(64px,env(safe-area-inset-top)) 16px max(48px,env(safe-area-inset-bottom))}
#disclaimer.in{opacity:1}
#disclaimer .ov-close{display:flex}   /* on every screen here, not only on a phone */
#disclaimer .disc{box-sizing:border-box;width:min(38em,100%);margin:auto 0;padding:0 .2em;
                  color:#f2f5ff;font:700 clamp(14px,1.6vh,16px)/1.6 var(--body);text-shadow:0 1px 8px rgba(0,0,0,.6);
                  transform:translateY(10px);transition:transform .3s cubic-bezier(.2,.8,.2,1)}   /* no sheet: off-white type floating on the dark backdrop */
#disclaimer.in .disc{transform:none}
#disclaimer h2{margin:0 0 .9em;font:900 1.2em/1.2 var(--body);letter-spacing:.14em;text-transform:uppercase;color:#fff}
#disclaimer .disc-lead{font-weight:900;color:#fff;margin-bottom:1em}
#disclaimer h3{margin:1.3em 0 .3em;font:900 .72em/1.2 var(--body);letter-spacing:.14em;text-transform:uppercase;color:#9aa2bd}
#disclaimer p{margin:0 0 .6em;color:rgba(242,245,255,.88)}
#disclaimer .disc-foot{margin:1.6em 0 0;font-size:.85em;color:#9aa2bd}
@media (prefers-reduced-motion: reduce){ #disclaimer,#disclaimer .disc{transition:none} }

#menu{position:fixed;inset:0;display:none;z-index:20;overflow-y:auto;
      background:rgba(5,6,12,.7);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
      opacity:0;transition:opacity .3s ease;scrollbar-width:none}   /* scrolls, but shows no bar */
#menu::-webkit-scrollbar{display:none}
#menu.on{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:6vh;
         padding:max(64px,env(safe-area-inset-top)) 16px max(24px,env(safe-area-inset-bottom))}
#menu.in{opacity:1}
/* the objects, one under the other, no boxes: the desk described, not a nav bar */
.menu-grid{display:flex;flex-direction:column;align-items:center;gap:5vh;width:100%}
.menu-item{display:flex;flex-direction:column;align-items:center;gap:4px;padding:0;min-width:0;
           background:none;border:0;color:#f2f5ff;cursor:pointer;
           transition:transform .12s ease,filter .15s ease}
.menu-item img{width:min(44vw,180px);height:auto;pointer-events:none;-webkit-user-drag:none;   /* the art is a tight crop: its own height, so the label sits right under it */
               filter:drop-shadow(0 8px 14px rgba(0,0,0,.5));transition:filter .15s ease}
.menu-item span{font:800 16px/1.2 var(--body);letter-spacing:.02em;text-transform:lowercase;text-shadow:0 1px 6px rgba(0,0,0,.9)}
.menu-item:hover,.menu-item:focus-visible{transform:translateY(-3px)}
.menu-item:active{transform:scale(.97)}
/* opening: the items rise into place one after another, top to bottom, the socials last. the sheet
   goes display:none between opens, so the run replays every time */
.menu-item,.menu-socials{animation:menuIn .55s cubic-bezier(.3,1.35,.5,1) var(--in,0s) backwards}
.menu-item:nth-child(2){--in:.08s} .menu-item:nth-child(3){--in:.16s} .menu-item:nth-child(4){--in:.24s} .menu-socials{--in:.32s}
@keyframes menuIn{from{opacity:0;transform:translateY(48px) scale(.92)}to{opacity:1;transform:none}}
@media (prefers-reduced-motion: reduce){ .menu-item,.menu-socials{animation:none} }
/* socials: the x and telegram art (assets/menu/X, telegram: 160x160 squares), same shadow as the items */
.menu-socials{display:flex;gap:14px}
.menu-socials .msoc{width:48px;height:48px;display:block;padding:0;border:0;background:none;
     transition:transform .12s ease}
.menu-socials .msoc img{width:100%;height:100%;object-fit:contain;pointer-events:none;-webkit-user-drag:none;
     filter:drop-shadow(0 6px 10px rgba(0,0,0,.5))}
.menu-socials .msoc:hover,.menu-socials .msoc:focus-visible{transform:translateY(-3px)}
.menu-socials .msoc:active{transform:scale(.97)}

/* ---------- mobile (portrait) ----------
   same room, same plate, cover-cropped to the clerk. the desk objects are out of the crop, so their
   hits are off; only the bell stays for now (the strip that replaces them is not built yet). */
.ov-close{position:fixed;top:max(12px,env(safe-area-inset-top));right:12px;z-index:23;width:44px;height:44px;
          display:none;align-items:center;justify-content:center;cursor:pointer;
          background:none;border:0;color:#f2f5ff;text-shadow:0 1px 8px rgba(0,0,0,.9);
          font:900 30px/1 var(--body)}
@media (max-aspect-ratio: 1/1){
  /* desk and wall hits: only the bell, the folder/review and the menu sign */
  #s-room .hit:not([data-hit="bell"]):not([data-hit="menu"]):not([data-hit="folder"]):not([data-hit="review"]):not([data-hit="exit"]){display:none !important}
  #s-room .layer.hi:not(#hi-bell):not(#hi-menu):not(.fold):not(#hi-review){animation:none !important;filter:none !important}
  /* and only their sprites: the tray, the noticeboard papers and every wall hover art go away.
     the objects baked into the room plate come out via the "-m" portrait plate export. */
  #tray-bottom, #tray-top, #hi-tasks, #s-room .paper, #hi-board, #hi-gallery, #hi-socials{display:none !important}
  /* the way out: not the arrow on the desk (out of the crop) but a plain back chevron, fixed top left
     like the overlays' close buttons. the inline art-space box is overridden with !important */
  #hi-exit{display:none !important}
  .room-back{display:none}   /* the exit hit is the back button here */
  #s-room .hit[data-hit="exit"]{position:fixed;left:12px !important;top:max(12px,env(safe-area-inset-top)) !important;
       width:44px !important;height:44px !important;z-index:23;display:grid;place-items:center;color:#f2f5ff}
  /* the button at its own 32px, centred in the 44px target. it carries its own frame, so it wants
     only enough shadow to sit off the room plate */
  #s-room .hit[data-hit="exit"] img{display:block;width:32px;height:32px;opacity:.6;
       filter:drop-shadow(0 1px 3px rgba(0,0,0,.6))}
  #s-room .hit[data-hit="exit"] svg{display:none;width:26px;height:26px;fill:none;stroke:currentColor;stroke-width:3;
       stroke-linecap:round;stroke-linejoin:round;filter:drop-shadow(0 1px 6px rgba(0,0,0,.9))}
  #hi-menu,[data-hit="menu"]{display:block}
  /* the bubble becomes a full-width band between the sign (baked in the plate) and the heads, tail down.
     in portrait the plate is scaled by height, so 1vh = 18 art px: the sign ends around 300 art px */
  #bubble{left:16px !important;right:16px !important;width:auto !important;max-width:none !important;
          translate:0 0 !important;bottom:auto !important;top:17.5vh !important}
  .bub{padding:.8em 1em .9em;border-radius:14px}
  .bub .said{font-size:clamp(16px,4.6vw,20px);line-height:1.25;text-wrap:balance}   /* full-width here, so even lines */
  .bub .who{text-align:center}
  /* answers: full width above the bottom edge, big targets */
  #dlg{width:calc(100vw - 32px);bottom:max(16px,env(safe-area-inset-bottom))}
  #dlg .ch,#vopts .ch{width:100%;padding:.85em 1.1em;font-size:16px;border-radius:12px}
  #dlg .ch.solo{width:100%;justify-content:center}
  #dlg .choices.pick{width:100%;min-width:0}
  #dlg .field{max-width:none;padding:.7em .9em}
  #dlg .choices:not(.pick) > .ch{max-width:none}   /* full width here, like the field above it */
  #dlg .din{font-size:16px}          /* 16px stops ios zooming the page on focus */
  #dlg textarea.din{font-size:16px;height:5.2em}
  #dlg .drow{max-width:none}
  #dlg .drow .dbtn{font-size:16px}
  #dlg .dnote{font-size:12px}
  /* tasks: a phone gets the torn slip rather than the clipboard — the board's clip and margins are
     a lot of furniture to spend on a small screen, and the slip is all sheet. 16px off each side. */
  .tasks-wrap .board{display:none}
  .tasks-wrap .slip{display:block}
  .tasks-wrap{height:auto;aspect-ratio:712/1360;
              width:min(calc(100vw - 32px), calc((100vh - 32px) * 712 / 1360), calc((100dvh - 32px) * 712 / 1360));
              container-type:inline-size}   /* the page's type is sized from the sheet (cqw), not the window */
  /* the board can be held back by a short window as much as a narrow one, so the type follows the
     board's own width: 1cqw is 1% of it. viewport units here made the text outgrow a small board */
  #tasks-page{font-size:clamp(12px,4.2cqw,17px);line-height:1.35}
  #tasks-page .sub{font-size:.92em}
  #tasks-page .fine{font-size:.85em}
  #tasks-page .spacer{flex:1}
  #tasks-page .tlist-go{width:100%;height:40px;padding:0 1em;font-size:15px;line-height:1;margin-bottom:.6em}
  /* the list page: rows only */
  #tasks-page .trow{flex:none;display:flex;align-items:center;justify-content:space-between;padding-bottom:.4em;
                    border-bottom:2px solid rgba(28,35,64,.25);font-size:13px;font-weight:800;color:var(--ink-soft)}
  #tasks-page .tback{font-size:13px;padding:.2em .3em;border:0;background:none}   /* text only */
  /* the header row's rule is the list's top edge; the bottom rule is drawn short so it stays off the
     paper's curled corner */
  #tasks-page .task-scroll{border:0}
  #tasks-page .task-scroll::after{content:"";flex:none;height:2px;width:86%;background:rgba(28,35,64,.25)}
  /* the tray on a phone: the open task keeps almost the slip's full width. an action is three
     things on its line — mark, verb, the square — and what the post must carry goes on a line of
     its own under them; the link field runs the width with its button beside it */
  .task-body{padding:.15em 0 .5em .35em}
  .task-body .brief{font-size:.9em}
  .act{display:grid;grid-template-columns:auto 1fr auto;align-items:center;column-gap:.5em;row-gap:.35em;padding:.4em 0}
  .act .mark{grid-column:1;grid-row:1}
  .act .verb{grid-column:2;grid-row:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
  .act .go.sq{grid-column:3;grid-row:1;margin-left:0}
  .act .need{grid-column:1 / -1;grid-row:2;padding-left:calc(.95em + .5em)}
  .act .go.sq{width:2.1em;height:2.1em}
  .task-do{padding:.1em 0 .55em calc(.95em + .5em);gap:.45em}
  .task-do .din{font-size:16px;height:2.4em}   /* 16px stops ios zooming the page on focus */
  .task-do .btn{height:2.4em;font-size:.9em;padding:0 1em}
  .task-note{padding-left:calc(.95em + .5em)}
  .task-list.compact{padding:.4em 0}
  .task-list.compact .task{font-size:clamp(12px,4cqw,15px);padding:.55em 0;gap:.6em;line-height:1.25}
  .task-list.compact .tick{width:22px;height:22px;font-size:12px}
  .task-list.compact .go.arrow{width:28px;height:28px;padding:0;display:grid;place-items:center;border-radius:7px;
                               border:2px solid var(--ink);color:var(--ink);text-decoration:none}
  .task-list.compact .go.arrow svg{width:13px;height:13px;stroke:currentColor;stroke-width:3.2;stroke-linecap:round;stroke-linejoin:round;fill:none}
  /* socials: the plaque spans the width */
  .soc-wrap{width:calc(100vw - 32px)}
  /* noticeboard: notes fill the width, less air between them. the sideways scatter is off and the
     column leaves 20px a side, so the art keeps a 16px margin even at the full 1.4deg tilt */
  .notes-col{width:calc(100vw - 40px);gap:36px}
  .note{--off:0px !important}
  /* the paper: zoomed in, so the sheet's writable area (73% of the art's width) spans the window less
     16px a side and the drawn margins run off the edges; a short window still holds it by height */
  .paper-wrap{height:auto;width:min(calc((100vw - 32px) / .73), calc((100vh - 32px) * 1053 / 1329), calc((100dvh - 32px) * 1053 / 1329))}
  /* the folder spread is a desktop layout; until the single-page version exists, let it scroll sideways
     rather than crush */
  /* the loose paper (unfiled) fits the width as before */
  .folder-wrap{--sw:max(100vw, calc(100vh * var(--folder-ar,1920/900)))}
  /* the filed spread: scaled so one page fills the width, and slid so the paper or the card is centred.
     setFolderPage() sets --sw/--sh/--fshift in px from the CFG boxes. #folder is overflow:hidden and
     the wrap moves by transform, so nothing can ever scroll sideways */
  #folder.spread .folder-wrap{left:0;top:0;margin:0;width:100vw;height:100vh;height:100dvh}   /* the wrap is the window; the spread slides inside it */
  #folder.spread .spread-wrap{left:0;top:50%;width:var(--sw);height:var(--sh);aspect-ratio:auto;
               transform:translate(var(--fshift,0px),-50%);transition:transform .35s cubic-bezier(.2,.8,.2,1)}
  #folder.spread .fhint{display:block}
  /* a sideways finger move is the page turn, not a browser pan: only vertical panning is left to the
     browser, so the pointer sequence reaches pointerup instead of being cancelled mid-swipe */
  #folder.spread, #folder.spread #page{touch-action:pan-y}
  #s-gate{touch-action:pan-y}   /* the same for the corridor swipe */
  #folder.spread .fhint[hidden]{display:none}   /* setFolderPage hides it while the left page is empty */
  /* the form, compacted for a ~260px paper: smaller type, tighter boxes, no sub-heading, statement clamped */
  #page{font-size:clamp(14px,1.7vw,16px);line-height:1.25}   /* 14px on a phone; a portrait tablet's wider sheet takes 16px, like a desktop */
  #page .gh{padding-bottom:.3em;margin-bottom:.35em}
  #page .gh .dept{font-size:.95em}
  #page .gh .dept small{display:none}
  #page .gtitle{font-size:1.25em;margin:.05em 0 .3em}
  #page .gf{gap:.25em .35em;margin-bottom:.3em}
  #page .gf .f{padding:.2em .4em .25em}
  #page .f.stmt .v{min-height:0;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}
  #page .f .ask{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;margin-bottom:.2em}
  #page .office{min-height:3.6em;margin:.15em 0 .3em}
  #page .gstamp{font-size:.9em}
  #page .gstamp.approved,#page .gstamp.waitlisted,#page .gstamp.not_selected{font-size:1em;left:5%;top:30%}
  #page .gov .fine{font-size:.8em;margin-bottom:.3em}
  #page .gov .row{margin:.1em 0 .2em}
  #page .gov .row .btn{padding:.35em .8em;font-size:.95em}
  #page .gfoot{padding-top:.3em}
  /* the review paper: its footer (the rule, the form number, the page count) goes, and the two buttons
     take that room: full size, side by side, sharing the row */
  #page .gov .gfoot{display:none}   /* the form number and page count: not worth a scrollbar on a phone */
  #page .gov .row.bottom{margin:0 0 .3em;gap:.5em;flex-wrap:nowrap}
  #page .gov .row.bottom .btn{flex:1;height:40px;padding:0 .8em;font-size:1.1em}   /* 40px tall, exactly */
  #folder.spread #filed-close{display:none !important}   /* the × closes it on mobile */
  /* every overlay gets a close button top right */
  .ov-close{display:flex}
  #gallery .gal-close{top:max(12px,env(safe-area-inset-top))}
  /* the volume goes top right, the art still at its own size, out of the way of the swipe's start */
  #vol{left:auto;bottom:auto;right:12px;top:max(12px,env(safe-area-inset-top))}
  #reset{bottom:max(12px,env(safe-area-inset-bottom))}
}



/* One shared control group moves into the active overlay. Keep the original speaker/slider
   appearance, with space beside the close button and outside the content's scroll surface. */
/* the knob keeps its corner in every scene and never moves. z-index 19 puts it under every overlay
   (20-25), so an open modal's scrim dims and blurs it rather than it floating on top; the same 19 as
   #blackout, and later in the markup, so the door's black still passes under it. */
#sound-controls{position:fixed;inset:0;pointer-events:none;z-index:19}
#sound-controls > *{pointer-events:auto}
/* A filter on a scrolling dialog makes fixed descendants scroll with it. Keep the same
   backdrop on a separate, noninteractive layer so its sound/close controls stay fixed. */
/* the scrim rides a ::before so the dialog itself carries no filter and its fixed close button stays
   put while the notes scroll. the fade has to live on the same element as the filter, though: with an
   animating opacity on #notices the ::before is grouped and the blur is held back until the fade
   settles, so the dark arrived first and the blur a few frames behind it. the dialog no longer fades
   as a whole - the scrim and its contents fade themselves, on the same timing. */
#notices,#menu{background:none;backdrop-filter:none;-webkit-backdrop-filter:none;opacity:1;transition:none}
#notices::before,#menu::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;
  background:rgba(5,6,12,.72);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
  opacity:0;transition:opacity .3s ease}
#menu::before{background:rgba(5,6,12,.7)}
#notices.in::before,#menu.in::before{opacity:1}
#notices > *,#menu > *{opacity:0;transition:opacity .3s ease}
#notices.in > *,#menu.in > *{opacity:1}

/* Saved draft identifiers are server generated and may wrap on small screens. */
.identity-draft .casebox { overflow-wrap:anywhere; white-space:normal; max-width:48%; line-height:1.25; }
#dlg button:disabled { opacity:.55; cursor:default; }
.identity-draft .gtitle { text-transform:none; }
#reset[hidden], #acard-acts[hidden] { display:none; }

/* Correction pass: reading surfaces stay outside the translated hallway art. */
#vent-dialog,#owner-tests{position:fixed;inset:0;z-index:25;display:none}
#vent-dialog.on,#owner-tests.on{display:block}
#vent-dialog .ov-close,#owner-tests .ov-close{position:fixed;right:max(12px,env(safe-area-inset-right));top:max(calc(var(--reading-top,0px) + 12px),env(safe-area-inset-top));width:44px;height:44px;z-index:33}
#owner-tests .ov-close{display:block}
/* the vent is a conversation, not a modal. with a pointer you leave him the way you leave anything
   else in the corridor - by clicking somewhere else, the door included. the x is for the layouts
   where there is no hover and nothing to click away to. */
#vent-dialog .ov-close{display:none}
/* and the container is a layout box over the whole corridor, not a surface. left solid it swallowed
   every click meant for the doors behind him. #vent-content already hands presses to its own rows,
   so only the small layouts - where he really is a modal, with a scrim - keep the box solid. */
#vent-dialog{pointer-events:none}
@media (max-aspect-ratio:1/1),(max-height:600px){
  #vent-dialog .ov-close{display:block}
  #vent-dialog{pointer-events:auto}
}
#vent-face{display:none}
#vent-content{pointer-events:none}
#vent-content > *{pointer-events:auto}
/* except the bubble's box, which is 1200x340 of art space centred on the vent while the bubble inside
   is only as wide as its line - so it blanketed the right half of the department door. it is a
   positioning box, not a surface, exactly like the clerk's #bubble. the .bub inside takes its own
   presses back. scoped past #vent-content > * above, which would otherwise win on order. */
#vent-content #vbub{pointer-events:none}
#owner-tests{z-index:30;background:rgba(5,6,12,.84)}
.test-panel{position:absolute;top:calc(var(--reading-top,0px) + 72px);left:50%;transform:translateX(-50%);width:min(480px,calc(100% - 32px));max-height:calc(var(--reading-height,100dvh) - 96px);overflow:auto;overscroll-behavior:contain;padding:20px;background:#f4efe2;color:#1c2340;border-radius:12px;font:600 1rem/1.5 var(--body)}
.test-panel h2{margin:0 0 12px;font-size:1.3rem}
.test-panel label{display:block;margin-top:18px}
.test-panel button,.test-panel select{font:inherit;max-width:100%;min-height:44px;padding:8px 12px;border:1px solid #1c2340;border-radius:6px;cursor:pointer;color:#1c2340;background:#fff}
#test-confirmation{margin:12px 0;padding:12px;border:1px solid #1c2340}
#owner-tests-open{position:fixed;right:12px;bottom:max(12px,env(safe-area-inset-bottom));z-index:31;font:700 12px/1.2 var(--body);min-height:44px;padding:8px 14px;border:1px solid #b9c0d8;border-radius:24px;color:#fff;background:#151925}
#owner-tests-open[hidden],#test-preview-banner[hidden],#test-confirmation[hidden],#test-exit[hidden]{display:none}
#test-preview-banner{position:fixed;top:max(64px,calc(env(safe-area-inset-top) + 52px));left:12px;right:12px;width:fit-content;max-width:calc(100% - 24px);z-index:26;margin:0;padding:6px 10px;border-radius:6px;background:#fff1b9;color:#1c2340;font:800 12px/1.35 var(--body);pointer-events:none}
/* Flex shrinking made paragraph boxes shorter than their painted text. */
.note > :not(.n-art):not(.n-new){flex-shrink:0;overflow-wrap:anywhere}
@media (max-width:700px),(max-aspect-ratio:1/1),(max-height:600px){
  #vent-dialog{background:rgba(5,6,12,.72);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}
  #vent-content{position:absolute;inset:auto;top:calc(var(--reading-top,0px) + max(72px,calc(env(safe-area-inset-top) + 60px)));left:max(16px,env(safe-area-inset-left));right:max(16px,env(safe-area-inset-right));height:calc(var(--reading-height,100dvh) - max(72px,calc(env(safe-area-inset-top) + 60px)) - max(16px,env(safe-area-inset-bottom)));display:flex;flex-direction:column;overflow:hidden;overscroll-behavior:contain;touch-action:pan-y;pointer-events:auto;padding:2px 2px 12px}
  /* he speaks from a fixed band at the top: the bubble hugs the bottom of it, so a second line grows
     upward and the vent below never moves. */
  #vent-content #vbub{position:static!important;left:auto!important;top:auto!important;width:auto!important;transform:none!important;
       order:1;flex:0 0 auto;height:30vh;min-height:0;display:flex;align-items:flex-end;
       overflow:auto;overscroll-behavior:contain}
  /* the vent, just under his tail, above the middle of the screen */
  #vent-face{display:block;order:2;flex:0 0 auto;width:min(190px,52%);height:auto;align-self:center;margin:18px auto 0;
       filter:drop-shadow(0 6px 18px rgba(0,0,0,.55))}
  #vent-content #vbub .bub{position:relative;left:auto;bottom:auto;translate:none;width:100%;max-width:none;padding:18px;font-size:1rem;line-height:1.5}
  /* the tail comes back: he has something to point at now */
  #vent-content #vbub .bub{margin-bottom:20px}
  #vent-content #vopts{position:relative;left:auto;bottom:auto;translate:none;width:100%;order:3;flex:0 0 auto;margin-top:auto}
  #vent-content .ch{min-height:44px;font-size:1rem;line-height:1.4;overflow-wrap:anywhere}
  #notices{top:var(--reading-top,0px);bottom:auto;height:var(--reading-height,100dvh);overscroll-behavior:contain;touch-action:pan-y;scroll-padding-top:76px}
  #notices .notes-col{width:calc(100% - 32px);max-width:520px;padding:76px 0 max(32px,env(safe-area-inset-bottom));gap:28px}
  /* the sheet keeps the shape of the paper that is shown here (the phone cut where there is one): shorter text
     leaves paper below it rather than squashing the drawing; longer text grows the sheet */
  #notices .note{aspect-ratio:var(--ar)!important;padding:62px 24px 30px;transform:none;opacity:1;filter:none!important;animation:none}
  #notices .note.has-mobile{aspect-ratio:var(--arm)!important}
  #notices .n-date{font-size:.75rem;line-height:1.3;gap:8px}
  #notices .n-title{font-size:18px;line-height:1.25}
  #notices .n-body{font-size:14px;line-height:1.5}
  #inspect[data-kind="receipt"]{padding:72px 16px max(16px,env(safe-area-inset-bottom));align-items:flex-start;overflow:auto;overscroll-behavior:contain}
  #inspect[data-kind="receipt"] #iplate{max-width:100%;font-size:1rem;transform:none}
}

/* Keep the mobile menu sign reachable above the clerk's independently scrolling answers. */
@media (max-aspect-ratio:1/1){
  #dlg{max-height:max(88px,calc(var(--reading-height,100dvh) - var(--room-menu-bottom,65vh) - 32px));overflow-y:auto;overscroll-behavior:contain;scroll-padding:8px;touch-action:pan-y}
  .keyboard-reading #dlg{bottom:calc(100vh - var(--reading-height) - var(--reading-top) + 16px);max-height:calc(var(--reading-height) - 92px);background:rgba(9,10,16,.96);border-radius:12px;padding:8px}
}
@media (max-aspect-ratio:1/1){
  #owner-tests-open{left:68px;right:auto;top:max(12px,env(safe-area-inset-top));bottom:auto}
}
@media (max-height:600px) and (min-aspect-ratio:1/1){
  #owner-tests-open{top:max(12px,env(safe-area-inset-top));bottom:auto}
}
/* A scrollable receipt cannot also establish the fixed controls' containing block. */
#inspect[data-kind="receipt"]{background:none;backdrop-filter:none;-webkit-backdrop-filter:none}
#inspect[data-kind="receipt"]::before{content:"";position:fixed;inset:0;z-index:-1;pointer-events:none;background:rgba(5,6,12,.7);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px)}

@media (max-height:600px) and (min-aspect-ratio:1/1){
  #dlg{bottom:16px;max-height:max(44px,calc(var(--reading-height,100dvh) - var(--room-actions-bottom,75vh) - 28px));overflow-y:auto;overscroll-behavior:contain;touch-action:pan-y;scroll-padding:4px}
  #dlg .ch{min-height:44px}
  #dlg .din{font-size:16px}
}

/* Preview labels share the active overlay and get their own reading space. */
#owner-tests-open[inert]{visibility:hidden}
body.test-preview{--preview-space:48px}
body.test-preview .test-panel{top:calc(var(--reading-top,0px) + 120px);max-height:calc(var(--reading-height,100dvh) - 144px)}
@media (max-width:700px),(max-aspect-ratio:1/1),(max-height:600px){
  body.test-preview #vent-content{top:calc(var(--reading-top,0px) + max(72px,calc(env(safe-area-inset-top) + 60px)) + 48px);max-height:calc(var(--reading-height,100dvh) - max(72px,calc(env(safe-area-inset-top) + 60px)) - max(16px,env(safe-area-inset-bottom)) - 48px)}
  body.test-preview #notices .notes-col{padding-top:124px}
  body.test-preview #notices{scroll-padding-top:124px}
}
@media (max-aspect-ratio:1/1){
  body.test-preview #bubble{top:max(17.5vh,112px)!important}
}
@media (max-height:600px){.ov-close{display:flex}}
/* Development status and saved-interview access clearing. */
/* the way in: the wordmark over everything, on the department's own dark. the clip carries its own
   alpha, so it sits on that dark rather than on a black box of its own. it fades and is removed. */
#intro{position:fixed;inset:0;z-index:100;display:grid;place-items:center;
       background:rgba(5,6,12,.72);backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);
       transition:background .45s ease,backdrop-filter .45s ease,-webkit-backdrop-filter .45s ease}
/* the ground clears rather than the whole overlay fading: an animating opacity here would group the
   blur and hold it back, the way it did on the noticeboard. so the dark and the blur lift on their
   own properties, and the wordmark shrinks away over them. */
#intro.gone{background:rgba(5,6,12,0);backdrop-filter:blur(0px);-webkit-backdrop-filter:blur(0px);pointer-events:none}
#intro-clip{width:min(520px,68vw);height:auto;display:block;margin-bottom:22px;
       animation:intro-settle 2.1s cubic-bezier(.2,.8,.2,1) both;
       transition:transform .45s ease,opacity .45s ease}
/* the wordmark drops in, overshoots and settles, the way the fomies clip did; it is still by 2.1s */
@keyframes intro-settle{
  0%{transform:translateY(-40px) scale(.55);opacity:0}
  28%{transform:translateY(6px) scale(1.08);opacity:1}
  46%{transform:translateY(-3px) scale(.97)}
  64%{transform:scale(1.015)}
  100%{transform:none;opacity:1}}
#intro.gone #intro-clip{animation:none;transform:scale(.86);opacity:0}
/* the wordmark and the button under it, one column. the settled wordmark ends 82% of the way down its frame, so
   the button is drawn up into the clip's empty foot (6.5% of the logo's width) to sit just under the letters */
#intro .intro-stack{display:flex;flex-direction:column;align-items:center}
#intro-enter{margin-top:0;position:relative;box-sizing:border-box;height:48px;min-height:0;padding:0 1.7em;
             display:inline-flex;align-items:center;justify-content:center;
             font:900 16px/1 var(--body);letter-spacing:.02em;white-space:nowrap;
             border:2px solid var(--ink);border-radius:10px;background:var(--butter);color:var(--ink);
             box-shadow:inset 0 1.5px 0 rgba(255,255,255,.6),0 3px 0 rgba(9,10,16,.55),0 10px 28px rgba(0,0,0,.4);   /* a lit top edge, a hard base under it, and the room's shadow */
             opacity:0;visibility:hidden;transform:translateY(8px);
             transition:opacity .4s ease,transform .4s ease,visibility 0s linear .4s,background .15s ease,box-shadow .15s ease}
#intro.ready #intro-enter{opacity:1;visibility:visible;transform:none;
             transition:opacity .4s ease,transform .4s ease,visibility 0s,background .15s ease,box-shadow .15s ease}
#intro.ready #intro-enter:hover{transform:translateY(-1px);background:var(--butter-hi,#ffe98a);
             box-shadow:inset 0 1.5px 0 rgba(255,255,255,.7),0 4px 0 rgba(9,10,16,.55),0 14px 32px rgba(0,0,0,.45)}
#intro.ready #intro-enter:active{transform:translateY(3px);transition-duration:.06s;   /* pressed onto its base */
             box-shadow:inset 0 1.5px 0 rgba(255,255,255,.4),0 0 0 rgba(9,10,16,.55),0 6px 16px rgba(0,0,0,.35)}
#intro-enter:focus-visible{outline:2px solid #f2f5ff;outline-offset:3px}
#intro.returning #intro-enter{display:none}   /* back from x: the wordmark is a loader, not a door */
#intro.gone #intro-enter{opacity:0;transform:scale(.86)}
/* on a phone it takes the width, a thumb's margin either side, and sits a little above the middle so
   it reads as a title card rather than something floating in the exact centre */
@media (max-width:700px),(max-aspect-ratio:1/1){
  #intro{padding-bottom:14vh}
  #intro-clip{width:calc(100vw - 32px);max-width:none}
}
/* no motion wanted: the overlay never appears, so there is nothing to sit through */
@media (prefers-reduced-motion:reduce){ #intro{display:none} }
.development-notice{position:fixed;top:3px;left:50%;transform:translateX(-50%);z-index:90;margin:0;padding:3px 8px;max-width:60vw;text-align:center;font:11px/1.3 system-ui;background:#15191bcc;color:#fff;pointer-events:none}
.session-checking #folder,.session-checking #tasks,.session-checking #dlg,.session-checking #bubble{visibility:hidden!important}
/* Saved questions use the existing clerk bubble, outlined choices and written field. */
#saved-interview[hidden]{display:none}
#dlg #saved-interview{width:100%}
/* the selected answer is styled with the rest of the .ch rules above, so the butter stays reserved
   for .go. a plain gold border here would read as the panel's primary action. */
.interview-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}
#dlg .interview-actions{display:flex;flex-wrap:wrap;justify-content:center;gap:7px;margin-top:8px}
#dlg .interview-actions .dbtn{min-height:32px;font-size:12px}
#dlg .interview-conflict{margin-top:12px;border:1.5px solid var(--butter);border-radius:10px;padding:12px;background:rgba(9,10,16,.92);font-size:14px;overflow-wrap:anywhere}
#saved-interview .written-answer{white-space:pre-wrap;overflow-wrap:anywhere}
#page #saved-interview{height:auto;min-height:100%;flex-shrink:0}
#page #saved-interview > *{flex-shrink:0}
#page #saved-interview h3{font-size:1em;margin:.5em 0 .25em}
#page #saved-interview p{margin:.25em 0 .65em;overflow-wrap:anywhere}
#page #saved-interview .btn{min-height:44px}
@media(max-width:600px),(max-height:520px){.development-notice{font-size:10px;max-width:56vw}#dlg .interview-actions .dbtn{min-height:44px}}
/* Functional fields on the existing case paper; no new scene or artwork. */
#saved-interview .mint-input{display:flex;flex-direction:column;gap:.3em;margin:.8em 0;width:100%;min-width:0}
#saved-interview .mint-input input{box-sizing:border-box;width:100%;min-width:0;min-height:44px;font-size:16px}
#saved-interview .mint-input span{font-size:.8em}
#saved-interview .full-address{font-family:monospace;overflow-wrap:anywhere;white-space:normal}
#saved-interview .filing-warning{font-weight:bold;border:2px solid currentColor;padding:.6em;margin:1em 0}
#saved-interview .row{flex-wrap:wrap}
#saved-interview .btn{white-space:normal;max-width:100%}

.note .n-title,.note .n-body{overflow-wrap:anywhere}
.note a{color:inherit;text-decoration:underline}
