/* ==========================================================================
   REVERIE — site.css
   Shared chrome for the viewing surfaces: /watch/<id> and /videos.

   One drawn system, two palettes, and since 2026-09-23 they are the same two
   colours with their roles swapped. Daylight ("ink") is the default: the
   logo's ink on the logo's paper, every edge a pen stroke on a pseudo-element,
   no shadows anywhere, the only emphasis a solid mass of ink. Night is that
   arrangement inverted — the paper becomes the page and the ink becomes the
   type. There is no second colour in either: the gold that used to light
   Midnight is archived. Do not invent new tokens.

   Sections are introduced by a title, set large in the display face and in
   sentence case. Never a tracked-out micro-cap eyebrow.
   ========================================================================== */

@font-face{font-family:"Archivo";src:url("/fonts/Archivo-400.woff2") format("woff2");font-weight:100 900;font-style:normal;font-display:swap}
@font-face{font-family:"ArchivoN";src:url("/fonts/ArchivoN-500.woff2") format("woff2");font-weight:100 900;font-style:normal;font-display:swap}

:root{
  /* Daylight — the ink theme. */
  --paper:#efeeea; --card:#f7f6f3; --well:#e4e2dc; --sink:#dcdad3;
  --ink:#131a24; --mut:#59616c; --faint:#8c929b; --on-accent:#efeeea;
  --pen:rgba(19,26,36,.40); --pen-quiet:rgba(19,26,36,.17);
  --line:rgba(19,26,36,.17); --line-strong:rgba(19,26,36,.40);
  --accent:#131a24; --accent-hi:#000; --accent-soft:rgba(19,26,36,.06); --accent-line:rgba(19,26,36,.40);
  --red:#b3372c; --green:#2f6b46; --audio:#2f6fe0;
  --stage:#e4e2dc; --glass:rgba(247,246,243,.88);
  --wash:rgba(19,26,36,.05); --hover:rgba(19,26,36,.06); --hover-strong:rgba(19,26,36,.10);
  --veil:rgba(19,26,36,.30);
  /* Over real footage the chrome never lightens: footage is footage in either theme. */
  --over-video:rgba(6,11,19,.62); --on-video:#f2f5f9; --on-video-mut:rgba(242,245,249,.62);
  --logo-mark:#131a24;   /* the mark's own ink inside the lockup sprite */
  --r-sm:8px; --r-md:12px; --r-lg:18px;
  --ease:cubic-bezier(.22,1,.36,1); --fast:.14s; --slow:.26s;
  --disp:"ArchivoN","Arial Narrow",sans-serif; --ui:"Archivo","Helvetica Neue",Arial,sans-serif;
  --gut:clamp(18px,4vw,48px); --maxw:1180px; --maxw-wide:1800px;
  color-scheme:light;
}
/* ★ NIGHT IS THE INVERSE OF INK — 2026-09-23, Franz. The gold is archived.
   It was Midnight: blue-black lit by one warm gold. It is now the ink palette
   with its two roles swapped and nothing else added. Every line below is the
   mirror of the line above it in `:root`, in the same order, so the two blocks
   can be read side by side and checked by eye.

   THE TWO COLOURS ARE THE LOGO'S OWN, and neither is a flat black or white:
   `#131a24` is the mark's ink, `#efeeea` is its paper. In day the paper is the
   page and the ink is the type; at night they change places.

   THE SURFACES INVERT LITERALLY. In ink a card is LIGHTER than the page and a
   well is DARKER; here a card is darker and a well is lighter. That is what
   "the exact opposite" means, it matches the landing page, and it is the rule
   to keep when a new surface is added.

   THREE VALUES DO NOT INVERT, and each has a reason.
   `--red` and `--green` are meanings rather than decoration, and a legible red
   on a dark ground is a different red from a legible red on paper.
   `--stage` stays DARKER than the page in both themes: it is what footage sits
   on, and a video wants the most recessed surface there is. In ink that
   happens to be the literal mirror; here it is deliberately not. */
:root[data-theme="midnight"]{
  --paper:#131a24; --card:#0e1520; --well:#1f2733; --sink:#242d39;
  --ink:#efeeea; --mut:#a8aeb6; --faint:#828891; --on-accent:#131a24;
  --pen:rgba(239,238,234,.40); --pen-quiet:rgba(239,238,234,.17);
  --line:rgba(239,238,234,.17); --line-strong:rgba(239,238,234,.40);
  --accent:#efeeea; --accent-hi:#ffffff; --accent-soft:rgba(239,238,234,.08); --accent-line:rgba(239,238,234,.40);
  --red:#e05252; --green:#6fbf8f; --audio:#6ea8ff;
  --stage:#0b1017; --glass:rgba(14,21,32,.88);
  --wash:rgba(239,238,234,.05); --hover:rgba(239,238,234,.06); --hover-strong:rgba(239,238,234,.10);
  --veil:rgba(8,12,18,.45);
  --logo-mark:#efeeea;
  color-scheme:dark;
}

*{box-sizing:border-box}
[hidden]{display:none!important}
/* The app's sky (sky.js): fixed behind every room, in the page's own ink. */
:root{--star-rgb:19,26,36; --star-gain:2}
:root[data-theme="midnight"]{--star-rgb:239,238,234; --star-gain:1}
#sky.rv-sky,.rv-sky,#rv-sky{position:fixed;inset:0;width:100vw;height:100vh;z-index:-1;display:block;pointer-events:none}
html{-webkit-text-size-adjust:100%}
body{
  margin:0; min-height:100vh; display:flex; flex-direction:column;
  background:var(--paper); color:var(--ink); font-family:var(--ui);
  font-size:15px; line-height:1.5; -webkit-font-smoothing:antialiased;
  transition:background var(--slow) var(--ease), color var(--slow) var(--ease);
}
body.no-motion *{transition:none!important;animation:none!important}
a{color:inherit}
button{font:inherit;color:inherit;background:none;border:0;padding:0;margin:0;cursor:pointer}
button:disabled{cursor:default;opacity:.5}
:focus{outline:none}
:focus-visible{outline:2px solid var(--line-strong);outline-offset:3px;border-radius:var(--r-sm)}
svg{display:block}
.sr{position:absolute!important;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}
.wrap{width:min(var(--maxw),100% - 2*var(--gut));margin-inline:auto}
/* Reading measure is 1180. A workbench is not reading — the editor and the
   library want the screen they were given, so they take it. */
.wrap.wide{width:min(var(--maxw-wide),100% - 2*var(--gut))}

/* ---- The pen ------------------------------------------------------------
   Every edge of a shape is drawn, not ruled. The stroke is a pseudo-element
   pushed through a fractal-noise displacement so it wobbles like ink; the
   type on top stays razor-crisp because the filter never touches it.      */
.dd{position:relative;isolation:isolate}
.dd::before{
  content:"";position:absolute;inset:0;border:1.3px solid var(--pen);
  border-radius:inherit;filter:url(#rough-a);pointer-events:none;z-index:1;
}
.dd.quiet::before{border-color:var(--pen-quiet)}
.dd.b::before{filter:url(#rough-b)}
.dd.lg::before{filter:url(#rough-lg)}
.dd.twice::after{
  content:"";position:absolute;inset:-2px -1px 0 -2px;border:1.2px solid var(--pen-quiet);
  border-radius:inherit;filter:url(#rough-b);pointer-events:none;opacity:.75;z-index:1;
}
.pen-defs{position:absolute;width:0;height:0;overflow:hidden}

/* ---- Header ------------------------------------------------------------ */
.top{padding:18px 0}
.top-in{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:34px}
.lockup{display:inline-flex;align-items:center;gap:9px;text-decoration:none;color:var(--ink)}
.lockup .mark{width:26px;height:26px;color:var(--accent)}
.lockup .word{height:15px;width:auto;color:var(--ink)}
.lockup .word .tittle{fill:var(--accent)}
.top-r{display:flex;align-items:center;gap:10px}
.top-r .link{font-size:14px;color:var(--mut);text-decoration:none;padding:6px 4px;transition:color var(--fast) var(--ease)}
.top-r .link:hover{color:var(--ink)}

/* The rooms. Centre of the bar, one drawn capsule, the room you are in filled
   with ink — the same shape the segmented controls use everywhere else, so
   nothing new has to be learned to read it. */
/* The app's topbar: the mark, centred, and nothing else. */
/* Three columns, the mark in the middle one: the logo is the page's centre
   whatever sits beside it, and the account is centred on the logo's line. */
.top-in.centred{display:grid;grid-template-columns:1fr auto 1fr;align-items:center}
/* ★ The mark sits top left in every room, as on the website (Franz, 7 Oct). */
.top-in.centred .lockup{grid-column:1;justify-self:start;position:relative}
.top-in.centred .top-acct{grid-column:3;justify-self:end;align-self:center}
/* The header's right side (site.js mountTop, data-nav): the rooms as drawn
   pills, a rule, day/night and the gear as drawn circles, then you — the
   editor's own top bar, on every room. */
.top-in.centred .top-right{grid-column:3;justify-self:end;display:flex;align-items:center;gap:12px;min-width:0}
.top-dock .dock{display:flex;align-items:center;gap:6px}
.top-dock .dock-nav,.top-dock .dock-utils{display:flex;align-items:center;gap:6px}
.top-dock .isl-pill{position:relative;display:inline-flex;align-items:center;justify-content:center;height:30px;padding:0 14px;
  border-radius:999px;border:0;background:none;color:var(--ink);font:600 13px/1 var(--ui);text-decoration:none;cursor:pointer;
  white-space:nowrap;transition:background var(--fast) var(--ease),color var(--fast) var(--ease)}
.top-dock .isl-pill::before,.top-dock .viewbtn::before,.top-dock .roundbtn::before{content:"";position:absolute;inset:0;
  border:1.3px solid var(--pen-quiet);border-radius:inherit;filter:url(#rough-a);pointer-events:none;transition:border-color var(--fast)}
.top-dock .isl-pill:hover::before,.top-dock .viewbtn:hover::before,.top-dock .roundbtn:hover::before{border-color:var(--pen)}
.top-dock .isl-pill[aria-current="page"],.top-dock .isl-pill.on,.top-dock .isl-pill[aria-expanded="true"]{background:var(--ink);color:var(--paper)}
.top-dock .isl-pill[aria-current="page"]::before,.top-dock .isl-pill.on::before,.top-dock .isl-pill[aria-expanded="true"]::before{border-color:transparent}
.top-dock button:focus:not(:focus-visible),.top-dock a:focus:not(:focus-visible){outline:none}
.top-dock .isl-div{width:1px;height:18px;background:var(--line);margin:0 4px;flex:none}
.top-dock .viewbtn,.top-dock .roundbtn{position:relative;width:30px;height:30px;border-radius:50%;border:0;background:none;padding:0;
  display:grid;place-items:center;color:var(--ink);cursor:pointer;line-height:0}
.top-dock .viewbtn:hover,.top-dock .roundbtn:hover{color:var(--ink);background:color-mix(in srgb,var(--ink) 8%,transparent)}
.top-dock .roundbtn.on::before,.top-dock .roundbtn[aria-expanded="true"]::before,.top-dock .roundbtn[aria-current="page"]::before{border-color:var(--ink)}
@media (max-width:900px){.top-dock .dock-nav{display:none}.top-dock .isl-div{display:none}}
/* The live mark (liveLockup in site.js): a canvas over the SVG, bottom-aligned
   so the baselines agree, headroom above for the moon's rise. */
.lockup .logo-live{position:absolute;left:0;bottom:0;width:100%;height:auto;display:block;
  opacity:0;pointer-events:none;transition:opacity .16s ease}
.lockup > svg{transition:opacity .16s ease}
.lockup.is-live .logo-live{opacity:1}
.lockup.is-live > svg{opacity:0}

/* The dock sits at the foot of every room, centred, one object. On a room that
   scrolls it stays in view — the bar is the app's one fixed thing. */
.appdock{position:sticky;bottom:0;z-index:30;display:flex;justify-content:center;
  padding:10px 0 14px;background:linear-gradient(to top,var(--paper) 62%,transparent)}
.appdock .acct .pop{bottom:calc(100% + 10px);top:auto}
/* The account is a round initial everywhere (30 Sep). Filled with the accent
   so it reads as "you", not as another tool; its drawn edge is dropped because
   the fill is the edge. `.acct` in front out-ranks the dock's roundbtn rules. */
.acct .roundbtn.acct-av{width:34px;height:34px;flex:none;background:var(--accent);color:var(--on-accent);
  font:600 14px/1 var(--disp);letter-spacing:0;padding:0;border:0;cursor:pointer}
.acct .roundbtn.acct-av::before{border-color:transparent}
/* Hover and open keep the fill and the letter: the dock's own roundbtn hover
   colours out-rank a plain rule, and --accent-hi is pure white at night. */
.rv-dock .acct .roundbtn.acct-av, .acct .roundbtn.acct-av:hover, .rv-dock .acct .roundbtn.acct-av:hover{background:var(--accent);color:var(--on-accent)}
.acct .roundbtn.acct-av:hover{opacity:.88}
.acct.open .roundbtn.acct-av{outline:2px solid var(--accent-line);outline-offset:2px}
/* Two of the bar's rooms are links, and the app's are buttons — so they arrive
   underlined. The room you are in is filled, the way the segmented controls
   everywhere else mark their choice. */
.rv-dock .isl-pill{text-decoration:none}
/* One bar, one size (Franz, 1 Oct): the rooms and the utilities match the
   recorder's controlbar exactly — 4px pills, 32px glyphs, 40px bar — on
   every room, so moving between them the bar does not twitch. */
.rv-dock .dock .dock-nav .isl-pill,.rv-dock .dock .dock-nav .isl-pill-plain{padding:4px 12px;line-height:normal;min-width:88px;justify-content:center}
.rv-dock .dock-utils .viewbtn,.rv-dock .dock-utils .roundbtn{width:32px;height:32px}
/* The shared half of the bar is injected into a <span>; `display:contents`
   makes its children direct flex items of the dock, so the bar stays one row
   instead of wrapping the rooms above the utilities. */
.rv-dock [data-dock-tail]{display:contents}
/* The Mac app is named but not sold until it ships. The rule lived on two
   pages and not the third, so the recorder offered a download that does not
   exist. It belongs with the tokens, once. */
html:not(.has-mac-app) .mac-only{display:none}
/* The app's own rules colour every pill in the dock, so the current room has to
   out-specify them rather than merely come later — `.dock-nav` in the selector
   is what does it. */
.rv-dock .dock-nav .isl-pill[aria-current="page"],
.rv-dock .dock-nav .isl-pill-plain[aria-current="page"]{
  background:var(--accent);color:var(--on-accent)
}
.rv-dock .dock-nav .isl-pill[aria-current="page"]::before{border-color:transparent}

.rooms{position:relative;display:inline-flex;gap:2px;padding:3px;border-radius:999px;margin:0 auto}
.rooms::before{content:"";position:absolute;inset:0;border:1.3px solid var(--pen-quiet);
  border-radius:999px;filter:url(#rough-b);pointer-events:none}
.rooms a{position:relative;z-index:1;display:inline-flex;align-items:center;height:28px;padding:0 14px;
  border-radius:999px;font-size:13px;color:var(--mut);text-decoration:none;white-space:nowrap;
  transition:color var(--fast) var(--ease),background var(--fast) var(--ease)}
.rooms a:hover{color:var(--ink)}
.rooms a[aria-current="page"]{background:var(--accent);color:var(--on-accent)}
@media(max-width:640px){.rooms a{padding:0 11px;font-size:12.5px}}
@media (max-width:560px){.top-r .link.hide-sm{display:none}}

/* ---- Buttons ------------------------------------------------------------
   A glyph is a circle, a word is a pill. Icons never sit before text.      */
.btn{
  position:relative;isolation:isolate;display:inline-flex;align-items:center;justify-content:center;gap:8px;
  height:38px;padding:0 18px;border-radius:999px;font-size:14px;font-weight:400;color:var(--ink);
  text-decoration:none;white-space:nowrap;background:transparent;
  transition:background var(--fast) var(--ease),color var(--fast) var(--ease),transform var(--fast) var(--ease);
}
.btn::before{content:"";position:absolute;inset:0;border:1.3px solid var(--pen);border-radius:999px;filter:url(#rough-a);pointer-events:none}
.btn:hover{background:var(--wash)}
.btn:active{transform:translateY(1px)}
.btn.solid{background:var(--accent);color:var(--on-accent)}
.btn.solid::before{border-color:transparent}
.btn.solid:hover{background:var(--accent-hi)}
.btn.sm{height:32px;padding:0 14px;font-size:13px}
.btn.danger{color:var(--red)}
.btn.danger::before{border-color:currentColor;opacity:.7}
.btn .ok{display:none}
.btn.done .ok{display:inline}.btn.done .idle{display:none}
.roundbtn{
  position:relative;width:36px;height:36px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;
  color:var(--ink);transition:background var(--fast) var(--ease);
}
.roundbtn::before{content:"";position:absolute;inset:0;border:1.3px solid var(--pen-quiet);border-radius:50%;filter:url(#rough-b);pointer-events:none}
.roundbtn:hover{background:var(--wash)}
.roundbtn svg{width:16px;height:16px}
/* The gear is a roundbtn that happens to be a link, and it matches the
   day/night switch it stands beside — 34px, quiet until you want it. */
a.roundbtn.gear{width:34px;height:34px;color:var(--mut);text-decoration:none;flex:none}
a.roundbtn.gear:hover{color:var(--accent)}
a.roundbtn.gear[aria-current="page"]{color:var(--ink);background:var(--wash)}

/* Tooltips from data-tip — no `title`, the browser's is slow and unstyled. */
[data-tip]{position:relative}
/* A page that draws its own tooltips (the editor uses the app's tip.js, which
   lives on <body> and moves to stay on screen) sets `app-tips` on <body>, and
   these stand down. `:where` keeps every override's specificity as it was. */
:where(body:not(.app-tips)) [data-tip]::after{
  content:attr(data-tip);position:absolute;left:50%;bottom:calc(100% + 8px);transform:translate(-50%,4px);
  background:var(--ink);color:var(--paper);font-size:12px;line-height:1;padding:7px 9px;border-radius:6px;
  white-space:nowrap;pointer-events:none;opacity:0;transition:opacity var(--fast) var(--ease),transform var(--fast) var(--ease);
}
:where(body:not(.app-tips)) [data-tip]:hover::after,:where(body:not(.app-tips)) [data-tip]:focus-visible::after{opacity:1;transform:translate(-50%,0);transition-delay:.35s}
:where(body:not(.app-tips)) .tip-below[data-tip]::after{bottom:auto;top:calc(100% + 8px);transform:translate(-50%,-4px)}
:where(body:not(.app-tips)) .tip-below[data-tip]:hover::after{transform:translate(-50%,0)}

/* Theme toggle: a two-word pill, the chosen word solid. */
/* The day/night switch. Icon only, in both themes — the pair of glyphs is its
   own label, and it is the sole exception to the site's text-first rule. Only
   ONE of the two is ever in the document flow, so it never resizes as it
   toggles. Same shape as the app's. */
.viewbtn{width:34px;height:34px;border-radius:50%;line-height:0;flex:none;
  display:flex;align-items:center;justify-content:center;cursor:pointer;
  background:transparent;color:var(--ink);border:1.3px solid var(--pen-quiet);
  transition:color var(--fast) var(--ease),border-color var(--fast) var(--ease)}
.viewbtn:hover{color:var(--accent);border-color:var(--pen)}
.viewbtn .vi{display:none}
:root[data-theme="midnight"] .viewbtn .vi-sun,
:root:not([data-theme="midnight"]) .viewbtn .vi-moon{display:block}
.theme{
  position:relative;display:inline-flex;height:32px;border-radius:999px;padding:3px;gap:2px;font-size:12.5px;
}
.theme::before{content:"";position:absolute;inset:0;border:1.3px solid var(--pen-quiet);border-radius:999px;filter:url(#rough-b);pointer-events:none}
.theme button{position:relative;z-index:1;height:100%;padding:0 11px;border-radius:999px;color:var(--mut);transition:color var(--fast) var(--ease),background var(--fast) var(--ease)}
.theme button[aria-pressed="true"]{background:var(--accent);color:var(--on-accent)}
.theme button:not([aria-pressed="true"]):hover{color:var(--ink)}

/* A segmented filter: the same two-word pill as the theme toggle, any number
   of words wide. The chosen one is solid; the rest are quiet. */
.seg{position:relative;display:inline-flex;height:32px;border-radius:999px;padding:3px;gap:2px;font-size:12.5px}
.seg::before{content:"";position:absolute;inset:0;border:1.3px solid var(--pen-quiet);border-radius:999px;filter:url(#rough-b);pointer-events:none}
.seg button{position:relative;z-index:1;height:100%;padding:0 12px;border-radius:999px;color:var(--mut);white-space:nowrap;transition:color var(--fast) var(--ease),background var(--fast) var(--ease)}
.seg button[aria-pressed="true"]{background:var(--accent);color:var(--on-accent)}
.seg button:not([aria-pressed="true"]):hover{color:var(--ink)}

/* ---- Type ------------------------------------------------------------- */
h1,h2,h3{font-family:var(--disp);font-weight:500;line-height:1.05;letter-spacing:-.005em;margin:0;color:var(--ink)}
h1{font-size:clamp(26px,3.4vw,38px)}
h2{font-size:clamp(21px,2.4vw,26px)}
h3{font-size:18px}
p{margin:0}
.mut{color:var(--mut)}
.faint{color:var(--faint)}
.meta{display:flex;flex-wrap:wrap;gap:6px 14px;font-size:13.5px;color:var(--mut)}
.meta b{font-weight:400;color:var(--ink)}
.meta .dot::before{content:"\00B7";margin-right:14px;color:var(--faint)}
.rule{height:1px;background:var(--line);border:0;margin:0}

/* ---- Fields ------------------------------------------------------------ */
.field{position:relative;display:flex;align-items:center;height:40px;border-radius:var(--r-sm);background:var(--card)}
.field::before{content:"";position:absolute;inset:0;border:1.3px solid var(--pen-quiet);border-radius:inherit;filter:url(#rough-b);pointer-events:none}
.field:focus-within::before{border-color:var(--pen)}
.field input{flex:1;min-width:0;height:100%;padding:0 12px;background:transparent;border:0;color:var(--ink);font:inherit;font-size:14px}
.field input::placeholder{color:var(--faint)}
.field input:focus{outline:none}
.field.mono input{font-variant-numeric:tabular-nums}
.check{display:inline-flex;align-items:center;gap:9px;font-size:14px;cursor:pointer;user-select:none}
.check input{appearance:none;width:18px;height:18px;margin:0;border-radius:5px;position:relative;background:var(--card);cursor:pointer}
.check input::before{content:"";position:absolute;inset:0;border:1.3px solid var(--pen);border-radius:inherit;filter:url(#rough-b)}
.check input:checked{background:var(--accent)}
.check input:checked::after{content:"";position:absolute;left:5px;top:2px;width:5px;height:9px;border:solid var(--on-accent);border-width:0 2px 2px 0;transform:rotate(42deg)}

/* ---- Cards, dialogs, toasts ------------------------------------------ */
.card{position:relative;border-radius:var(--r-md);background:var(--card);padding:18px 20px}
.card::before{content:"";position:absolute;inset:0;border:1.3px solid var(--pen-quiet);border-radius:inherit;filter:url(#rough-a);pointer-events:none}
.scrim{position:fixed;inset:0;background:var(--veil);display:flex;align-items:center;justify-content:center;padding:20px;z-index:50;opacity:0;pointer-events:none;transition:opacity var(--slow) var(--ease)}
.scrim.open{opacity:1;pointer-events:auto}
.dialog{position:relative;width:min(460px,100%);border-radius:var(--r-lg);background:var(--paper);padding:26px 26px 22px;transform:translateY(8px);transition:transform var(--slow) var(--ease)}
.scrim.open .dialog{transform:none}
.dialog::before{content:"";position:absolute;inset:0;border:1.4px solid var(--pen);border-radius:inherit;filter:url(#rough-a);pointer-events:none}
.dialog h2{margin-bottom:6px}
.dialog .lede{color:var(--mut);font-size:14px;margin-bottom:18px}
.dialog .row{display:flex;gap:10px;align-items:center;margin-top:14px}
.dialog .actions{display:flex;justify-content:flex-end;gap:8px;margin-top:22px}
.dialog .err{color:var(--red);font-size:13px;margin-top:10px;min-height:1.2em}
.toast{
  position:fixed;left:50%;bottom:24px;transform:translate(-50%,12px);opacity:0;pointer-events:none;
  background:var(--ink);color:var(--paper);font-size:13.5px;padding:10px 14px;border-radius:999px;z-index:60;
  transition:opacity var(--fast) var(--ease),transform var(--fast) var(--ease);
}
.toast.show{opacity:1;transform:translate(-50%,0)}

/* ---- The account control ------------------------------------------------
   Mounted by `site.js` into `<div class="acct">` on every signed-in surface.
   A word, so it is a pill; the panel opens BELOW it and closes on an outside
   click. Flat, like everything else — the panel is a drawn edge, not a card
   floating on a shadow. */
.acct{position:relative}
.acct .pop{position:absolute;right:0;top:calc(100% + 8px);width:300px;border-radius:var(--r-md);background:var(--paper);padding:14px 10px 8px;z-index:40;display:none}
.acct .pop::before{content:"";position:absolute;inset:0;border:1.3px solid var(--pen);border-radius:inherit;filter:url(#rough-a);pointer-events:none}
.acct.open .pop{display:block}
.acct .pop .me{display:flex;align-items:center;gap:12px;padding:4px 4px 14px}
.acct .pop .me-face{flex:none;width:42px;height:42px;border-radius:50%;display:grid;place-items:center;background:var(--ink);color:var(--paper);font-size:17px;font-weight:600}
.acct .pop .me-text{display:flex;flex-direction:column;gap:6px;min-width:0}
.acct .pop .who{font-size:15px;font-weight:600;color:var(--ink);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.acct .pop .me-plan{display:flex}
.acct .pop .chip{font-size:12.5px;font-weight:500;color:var(--ink);padding:3px 10px;border-radius:999px;border:1px solid var(--line)}
.acct .pop .room-store{padding:12px 4px 14px;border-top:1px solid var(--line)}
.acct .pop .store-line{display:flex;justify-content:space-between;gap:10px;font-size:13px;color:var(--mut)}
.acct .pop .store-line span:first-child{color:var(--ink);font-weight:500}
.acct .pop .plan{font-size:13px;color:var(--mut);margin-top:2px}
.acct .pop .well{position:relative;height:6px;border-radius:999px;background:var(--well);margin:10px 0 0}
.acct .pop .room-store .plan + .well, .acct .pop .room-store .well + .plan{margin-top:8px}
.acct .pop .well i{position:absolute;inset:0 auto 0 0;background:var(--ink);border-radius:inherit}
.acct .pop .rows{display:flex;flex-direction:column;padding:6px 0;border-top:1px solid var(--line)}
.acct .pop .lnk{display:flex;align-items:center;justify-content:space-between;width:100%;text-align:left;font:inherit;font-size:14px;font-weight:500;padding:9px 10px;border-radius:8px;color:var(--ink);text-decoration:none;background:none;border:0;cursor:pointer}
.acct .pop .lnk:hover{background:var(--well)}
.acct .pop .lnk.here{font-weight:600}
.acct .pop .lnk.here::after{content:"";width:5px;height:10px;margin:-3px 4px 0 0;border:solid var(--ink);border-width:0 2px 2px 0;transform:rotate(45deg)}
.acct .pop .lnk.out{color:var(--mut);margin-top:2px;border-top:1px solid var(--line);border-radius:0;padding-top:12px}
.acct .pop .lnk.out:hover{color:var(--ink)}

/* ---- Footer ------------------------------------------------------------ */
.foot{margin-top:auto;padding:34px 0 26px;color:var(--faint);font-size:13px}
/* A page that must fit the window gets a thinner foot. */
/* `fits` means: this page is the size of the window and never scrolls.
   body is already a flex column with the footer pushed down, so main only
   has to take the rest and refuse to grow past it. */
body.fits{height:100dvh;overflow:hidden}
body.fits .foot{padding:10px 0 12px;margin-top:0}
body.fits main{flex:1;min-height:0;display:flex;flex-direction:column}
.foot-in{display:flex;flex-wrap:wrap;gap:10px 22px;align-items:center;justify-content:space-between}
.foot a{color:var(--mut);text-decoration:none}
.foot a:hover{color:var(--ink)}
.foot .links{display:flex;flex-wrap:wrap;gap:4px 16px}

/* ---- Empty / error states -------------------------------------------- */
.state{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;gap:10px;padding:40px 24px;min-height:100%}
.state h2{font-size:clamp(20px,2.4vw,26px)}
.state p{color:var(--mut);max-width:44ch;font-size:14.5px}
.state .row{display:flex;gap:8px;margin-top:8px;flex-wrap:wrap;justify-content:center}
.state .mark{width:36px;height:36px;color:var(--faint);margin-bottom:6px}

@media (prefers-reduced-motion:reduce){*{transition:none!important;animation:none!important}}

/* Selected text swaps the two colours, so it reads on every surface in
   either theme — the words take the page colour on a block of ink. */
::selection{background:var(--ink);color:var(--paper)}

/* ★ Glass, slightly (Franz, 5 Oct: "these panels … slightly translucent so
   they show the stars and comets"). The rooms' big surfaces let the sky
   through at about a quarter; words and controls sit on them unchanged. No
   backdrop blur: it would re-blur the moving sky every frame. */
body #stage.stage{background:color-mix(in srgb,var(--stage) 58%,transparent)}
/* The recorder's Studio panel beside it, the same glass (Franz, 5 Oct). */
html body.rv-dock-body .rv-dock .tray{background:color-mix(in srgb,var(--card) 66%,transparent)}
body .ws main.ws-stage{background:color-mix(in srgb,var(--stage) 40%,transparent)}
body .ws #stagewrap.stagewrap{background:color-mix(in srgb,var(--stage) 62%,transparent)}
body .ws #ws-tl.ws-tl{background:color-mix(in srgb,var(--well) 58%,transparent)}
body .ws #ws-tracks.ws-tracks{background:color-mix(in srgb,var(--card) 72%,transparent)}
body article.vcard{background:color-mix(in srgb,var(--card) 76%,transparent)}
/* ★ Every dropdown and popover, the same glass (Franz, 5 Oct: "all these
   backgrounds of dropdowns everywhere should be a bit translucent … like some
   of the cards"). Thicker than the panels, because words sit on all of a menu
   and none of a stage. Unlike the panels these do blur what is behind them:
   over a drawer or a grid of cards, words under words could not be read, and
   a menu is open for a moment, not for the whole session. */
html body .menu-pop,html body .acct .pop,html body .share-menu,html body .mpill .mpop,
html body .share-pop,html body .ws .del-pop,html body .ws .lane-pop{background:color-mix(in srgb,var(--paper) 80%,transparent);
  -webkit-backdrop-filter:blur(14px);backdrop-filter:blur(14px)}

/* The mark, top left (site.js HOME_MARK): to the website, gently alive. */
.top-home{display:grid;place-items:center;width:34px;height:34px;flex:none;color:var(--ink);opacity:.82;
  border-radius:50%;transition:opacity var(--fast) var(--ease)}
.top-home:hover{opacity:1}
.top-home svg{width:30px;height:30px;display:block;overflow:visible}
.top-home .hm-arc,.top-home .hm-dot{transform-box:view-box;transform-origin:313.2px 244.4px}
.top-home .hm-arc{animation:hm-sway 9s cubic-bezier(.45,0,.55,1) infinite}
.top-home .hm-dot{animation:hm-breathe 4.5s cubic-bezier(.45,0,.55,1) infinite}
@keyframes hm-sway{0%,100%{transform:rotate(-16deg)}50%{transform:rotate(16deg)}}
@keyframes hm-breathe{0%,100%{transform:scale(.9)}50%{transform:scale(1.04)}}
@media (prefers-reduced-motion:reduce){.top-home .hm-arc,.top-home .hm-dot{animation:none}}
.top-in.centred .top-home{grid-column:1;grid-row:1;justify-self:start}
.ws-top{position:relative}
.ws-top .top-home.ws-home{position:absolute;margin:0}
/* The real moon (moon.js, from the homepage), in every room's sky too. */
#moon{position:fixed;left:0;top:0;z-index:-1;pointer-events:none;opacity:0;transition:opacity 3s ease;will-change:transform}
#moon.up{opacity:1}
.moon-halo{position:fixed;left:0;top:0;z-index:-1;pointer-events:none;border-radius:50%;opacity:0;transition:opacity 3s ease;
  background:radial-gradient(circle,color-mix(in srgb,var(--ink) 9%,transparent) 0%,color-mix(in srgb,var(--ink) 4%,transparent) 26%,transparent 64%)}
:root[data-theme="midnight"] .moon-halo{background:radial-gradient(circle,color-mix(in srgb,var(--ink) 16%,transparent) 0%,color-mix(in srgb,var(--ink) 6%,transparent) 24%,transparent 64%)}


/* ★ A panel's title rule runs edge to edge (Franz, 7 Oct: "make the main
   header section lines full … end to end for all"). The editor's panel, its
   Collection drawer and the recorder's Studio drawer all inset the line by
   their padding; the rule is now drawn wider than the header and the panel's
   own clipping trims it exactly at the panel's edges. The group dividers
   below it stay inset — only the title line spans. */
html .ws .ws-panel-scroll .ws-sec-head,
html .ws .lib-head,
html .rv-dock .lib-head{border-bottom-color:transparent}
html .ws .lib-head,
html .rv-dock .lib-head{position:relative}
html .ws .ws-panel-scroll .ws-sec-head::after,
html .ws .lib-head::after,
html .rv-dock .lib-head::after{content:"";position:absolute;left:-40px;right:-40px;bottom:-1px;height:1px;background:var(--line);pointer-events:none}

/* ★ The top of a scrolled panel fades like its foot (Franz, 7 Oct). Drawers
   whose title sits above the scroller fade their first 14px; the editor's
   panel keeps its title inside the scroller (sticky), so the fade hangs just
   under the title rule instead, in the panel's own colour. Only once
   scrolled: at rest nothing is faded. site.js sets .rv-scrolled. */
html .ws .tray-scroll.rv-scrolled,
html .rv-dock .tray-scroll.rv-scrolled{
  -webkit-mask-image:linear-gradient(to bottom,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%);
          mask-image:linear-gradient(to bottom,transparent 0,#000 14px,#000 calc(100% - 14px),transparent 100%)}
html .ws .ws-panel-scroll .ws-sec-head::before{content:"";position:absolute;left:-40px;right:-40px;top:100%;height:14px;margin-top:1px;
  background:linear-gradient(to bottom,var(--card),transparent);opacity:0;transition:opacity .2s;pointer-events:none}
html .ws .ws-panel-scroll.rv-scrolled .ws-sec-head::before{opacity:1}

/* ★ The fine print, bottom right, in every room (Franz, 7 Oct: "same as the
   other pages" — the watch page's Privacy · Terms · …). Fixed to the window's
   foot and lined up with the page's own right edge (.wrap.wide), so it never
   moves with a scroller. Only the links take the pointer. */
.rv-fine{position:fixed;left:0;right:0;bottom:16px;z-index:5;pointer-events:none}
.rv-fine p{display:flex;justify-content:flex-end;gap:18px;margin:0 auto;font-size:12.5px;color:var(--faint)}
.rv-fine a{pointer-events:auto;color:var(--faint);text-decoration:none}
.rv-fine a:hover{color:var(--ink)}
html.rv-taking .rv-fine{display:none}
@media (max-width:760px){.rv-fine{display:none}}

/* ★ THE HEADER NORM (Franz, 7 Oct: "the recorder page has the perfect header
   bar … make it the norm for each and every page", the Editor excepted).
   One line 34px tall with 18px above and below (70 in all); the mark 78.7x32
   at the page's left gutter; pills 30px, 13px/600; round buttons 30px; the
   account 34px, last on the right at the right gutter. The website's own
   headers (index.html .site-head, legal.css header) carry the same numbers. */
header.top .top-dock .roundbtn,header.top .top-dock .viewbtn{width:30px;height:30px}
