/* ═══════════════════════════════════════════════════════════════════════════
   rzv.studio — glass.css  (GLASS agent)

   Everything the raymarched glass solids need from CSS, which is almost
   nothing: somewhere to hang a canvas, a fade-in, a type scale, and a CSS-only
   fallback for when WebGL2 is not there. The shapes, the motion and every
   pixel of the objects themselves are glass.js's business.

   Load AFTER base.css (it reads --ease, --text and the pearl's gradient
   stack). Pairs with assets/js/glass.js.

   THE CANVAS IS TRANSPARENT. It composites over the live document rather than
   painting its own ground, which is why almost every rule that used to be here
   is gone: no feathering an opaque box into the page, no hiding the DOM text
   behind a timed cross-fade, no second copy of the aurora. The solid covers
   what is underneath it exactly where it is, and nowhere else.

   TRAP 1 (base.css) is respected by omission: nothing here uses
   backdrop-filter and nothing here uses mix-blend-mode, so there is no blend
   group for a blurred ancestor to isolate into a black box on iOS.

   FIVE PATHS, and only the first three are used by any page today:

   · PAGE LENS      `canvas.rzv-glass--page` — one canvas fixed over the whole
                    viewport at z 400, following the cursor. Every page but the
                    home page. Needs no host rule at all; it hangs off <body>
                    and positions itself.
   · SECTION SOLID  `.glass-sect > canvas.rzv-glass--sect` — one per content
                    section, a different shape each. The home page, and every
                    page where there is no cursor to follow. glass.js adds the
                    class; the host is a real <section> and gets nothing else
                    done to it.
   · HERO SOLID     `.rzv-glass--hero` — a section solid on #hero, home page
                    only: centred, tumbling, and the one canvas here whose
                    opacity is driven from JS rather than from a class, because
                    it has to LEAVE on scroll — it morphs cube → octahedron →
                    cuboctahedron → sphere as the reader scrolls and cross-fades
                    into the venn's 22px centre node at the end of the hero's
                    runway. Everything else about it is a section solid, and its
                    band is the one thing it does differently: it tracks the
                    VIEWPORT rather than being clamped inside #hero, so the
                    solid can sit dead centre for the whole of that run. See
                    §THE HERO'S MORPH in glass.js.
   · AMBIENT HOST   `.glass-host` — an empty decorative box a page asks for by
                    name with [data-glass]. Carries the CSS-only pearl fallback.
   · TEXT HOST      `.glass-host--text` + [data-glass-text] — a box whose words
                    are measured per character and bent exactly. Kept and
                    supported; no page currently uses it.

   For the last two the split between CLASS and ATTRIBUTE is load-bearing: the
   class lays things out and must be in the markup, because it is what makes
   the page correct with no JS, no WebGL2, or a dead shader; the attribute is
   what turns the glass on. Nothing in this file hides page content, ever.
   ═══════════════════════════════════════════════════════════════════════ */

/* ── THE HOST ────────────────────────────────────────────────────────────
   An EMPTY decorative box in ambient mode: glass.js appends a canvas that
   fills it and nothing else. Content inside an ambient host is legal now that
   the canvas is transparent, but it will be silently refracted-over rather
   than measured — put it in a TEXT host if you want it bent. Put content beside
   it, never in it — unless it is a TEXT host, where the content is the point.

   `isolation` keeps the canvas out of any blend group a parent section might
   open, and `contain:paint` tells the compositor the canvas cannot paint
   outside the box — free, and it matters because this element repaints at
   60fps. ── */
.glass-host{
  position:relative;
  overflow:hidden;
  isolation:isolate;
  contain:paint;
  pointer-events:none;   /* decorative: never eat a click meant for the page */
}

/* The square is a DEFAULT, not a constraint. Wrapped in :where() so it carries
   ZERO specificity: a page stylesheet overrides it with a plain class whether
   it loads before or after this file, which is the one thing that must not
   depend on link order. Unlike .au in base.css the ratio is not load-bearing —
   the shader sizes the blob off the host's SHORT side and lets the aurora
   field follow the box, so a wide host widens the wash without deforming the
   object. Size the host however the layout wants. */
:where(.glass-host){aspect-ratio:1/1}

/* ── THE CANVAS ──────────────────────────────────────────────────────────
   Fills the host exactly. glass.js owns the drawing-buffer size (host box ×
   capped DPR); these are the CSS pixels it is stretched across, and the two
   are kept in step by a ResizeObserver.

   It arrives at 0 and glass.js adds .is-live after the first completed frame —
   and in text mode, not until the words have been measured, so the cube never
   appears with an empty pane in it. The fade is on the canvas, so what shows
   through while it happens is the page itself: the ambient fallback pearl, or
   in text mode the real headline. The box is never empty for a frame. ── */
.glass-host > canvas.rzv-glass{
  position:absolute;inset:0;
  width:100%;height:100%;
  display:block;
  opacity:0;
  transition:opacity .9s var(--ease,cubic-bezier(0.16,1,0.3,1));
}
.glass-host.is-live > canvas.rzv-glass{opacity:1}

/* ── THE PAGE LENS ───────────────────────────────────────────────────────
   One canvas, fixed to the viewport, over the whole document. The solid roams
   it following the cursor and refracts whatever it passes over. It is the cube
   everywhere except the portfolio index (work/index.html, data-page="work"),
   which draws the PUCK — a BICONCAVE glass lens in a bezel, drawn
   orthographically, centred on the cursor and banking into the direction the
   cursor is travelling. It reads as an instrument dragged across the work
   rather than as a turning solid. (It used to be biconvex and was described
   here as a magnifier. It is a reducing glass now: a concave lens diverges, so
   the type under the dish comes out at roughly two thirds size. See the puck
   block in glass.js for the optics.) Nothing in this file changes with any of
   it: the shape is chosen in glass.js's PAGE_TUNE and the canvas is the same
   canvas.

   z-index 400 is chosen, not arbitrary. Read upward from it, the real root
   order is: the lens at 400, base.css's header at 500, then the WHOLE
   constellation subtree at 530 — constellation.css raises `#constellation >
   .wrap` to 530, which makes it a stacking context, so the collapse veil
   (.cn-veil) resolves its own z-index of 10 INSIDE that wrap and lands at 530
   in the root; the same is true of the ether layer, the stage, the core, the
   ink pearl and the statement (11–15 in there). This comment used to say the
   lid sat at 520, which is the number the veil had back when it was parented
   to <body>; it has not been true since the wrap was raised. Above all of it,
   .cn-flyer at 560 — the pearl that flies into the header on the collapse,
   parented to <body> precisely so it clears everything.

   Every one of those must stay crisp ABOVE the lens: a bent nav bar is a
   broken nav bar, refracting the collapse would fight the phase cut, and the
   flyer is a 15px object whose whole job is to be legible while it travels.
   Everything else on the page is z 0–60 and passes underneath, which is the
   point. The page grain (z 60) therefore lies under the lens too, so the cube
   refracts a grained page rather than wearing grain itself, which is the right
   way round.

   pointer-events:none, absolutely: this covers every clickable thing on the
   site. It is also aria-hidden in the markup glass.js writes.

   TWO classes gate the fade, and both are required. `is-live` means the shader
   has produced a real frame; `is-active` means a cursor is actually in the
   document. Page mode only runs while there is something to follow, so before
   the first mouse move — and for a beat after it leaves — there is simply no
   lens. That is not a fallback, it is the behaviour. ── */
canvas.rzv-glass--page{
  position:fixed;inset:0;
  width:100vw;height:100vh;
  z-index:400;
  pointer-events:none;
  opacity:0;
  transition:opacity .55s var(--ease,cubic-bezier(0.16,1,0.3,1));
}
canvas.rzv-glass--page.is-live.is-active{opacity:1}

/* ── SECTION SOLIDS ───────────────────────────────────────────────
   One canvas per real content section, filling that section, refracting that
   section. The home page uses these instead of the roaming lens, and so does
   every page where there is no cursor to roam with.

   The host is a REAL <section>, not a decorative box, so almost nothing is
   done to it — no containment, no overflow clipping, no aspect ratio, and in
   particular none of `.glass-host`, whose contain:paint would change how a
   content section lays out. base.css already makes `.section` position:relative,
   which is all the canvas needs; this class is a hook and a promise that the
   positioning is there.

   z-index 2 puts the solid above `.wrap` (z 1) so it refracts the section's own
   copy rather than hiding beneath it, and above `.au` washes (z 0), which are
   never rasterised anyway. Far below the header at 500.

   The .9s fade is load-bearing: sections hand over as you scroll, and the
   outgoing one is still partly on screen when it loses the arbitration. Cutting
   it would be a blink; fading reads as one object giving way to the next. ── */
.glass-sect{position:relative}
.glass-sect > canvas.rzv-glass--sect{
  position:absolute;inset:0;
  width:100%;height:100%;
  display:block;
  z-index:2;
  pointer-events:none;
  opacity:0;
  transition:opacity .9s var(--ease,cubic-bezier(0.16,1,0.3,1));
}
.glass-sect.is-live > canvas.rzv-glass--sect{opacity:1}

/* ── THE HERO CUBE ───────────────────────────────────────────────────────
   One extra class on one extra canvas: `.rzv-glass--hero`, on #hero, home page
   only, ~350px, tumbling, dead centre. It is a section solid in every respect
   this file cares about — same host class, same z-index 2, same
   pointer-events:none (so the hero CTA underneath it stays clickable), same
   band — so everything above applies and only the OPACITY is taken back.

   It is taken back because this object has to LEAVE, and now because of what it
   leaves INTO. Every other solid fades in once and then lives on a class:
   `.is-live` arrives, CSS spends .9s on it, done. The hero solid instead
   cross-fades with a real DOM element — constellation.js's 22px centre pearl,
   on the same pixel, at the same size — across a band that starts at the exact
   scroll position where #hero's bottom meets the top of the screen. A
   stylesheet has no way to know that position and no way to know that the two
   opacities have to sum to one, so glass.js drives the whole envelope (arrival
   × handoff) into --g-a from inside the loop it is already running, and
   publishes the other half of the sum as RZV.glass.handoff().hand. See
   §THE HERO'S MORPH and §THE SIGNAL there for the curve and the numbers.

   THE CANVAS OVERHANGS ITS HOST during the last of that run, on purpose: its
   band is the viewport, unclamped, so past #hero's bottom edge it reaches a
   little way down over #constellation. Nothing here needs to change for that —
   it is pointer-events:none, it is z-index 2 against the constellation
   subtree's 530, and it is at --g-a 0 within ~0.11 of a viewport — but do not
   add `overflow:hidden` to `.glass-sect` without reading that note first.

   `transition:none` is the load-bearing half, not the custom property. A
   scroll-linked value with .9s of transition on it lags the scroll by most of a
   second, which reads as the object being dragged out of frame rather than as
   it going — and the two terms would fight, the transition still chasing the
   arrival while the scroll term pulled the other way.

   Written as a pair of selectors so the value holds whether or not `.is-live`
   is on, and placed after the --sect rules so it wins on order at equal
   specificity rather than by a specificity trick. The default of 0 is what the
   canvas shows for the frame between glass.js appending it and the first --g-a
   write; there is never a visible frame at full opacity. ── */
.glass-sect > canvas.rzv-glass--hero,
.glass-sect.is-live > canvas.rzv-glass--hero{
  opacity:var(--g-a,0);
  transition:none;
}

/* ── FEATHER ─────────────────────────────────────────────────────────────
   VESTIGIAL, and kept only because it may be wanted again. It existed to hide
   the hard edge of an opaque self-painted backdrop; the canvas is transparent
   now, so there is no rectangle to hide and no host needs this. It is left in
   place — and off by default — for a future host that wants to fade the
   object's own reach rather than its box.

   `ellipse closest-side`, not farthest-corner: with farthest-corner the
   gradient's 100% lives at the CORNERS, so the box's edge midpoints sit at
   only ~71% of the ramp and keep ~0.5 alpha — a visible rectangle line on
   every straight edge. closest-side puts 100% at the edge midpoints and the
   corners fall past the ramp into the final transparent stop.

   Do NOT put this on a text host: it would eat the first letters of every
   left-aligned line, and there is nothing for it to fix. ── */
.glass-host--feather{
  -webkit-mask-image:radial-gradient(ellipse closest-side at 50% 50%,#000 0%,#000 74%,rgba(0,0,0,0.4) 87%,transparent 98%);
  mask-image:radial-gradient(ellipse closest-side at 50% 50%,#000 0%,#000 74%,rgba(0,0,0,0.4) 87%,transparent 98%);
}

/* ═══ TEXT MODE ═══════════════════════════════════════════════════════════
   The host holds a real <ul> of real words and the object bends them.

   Sizing defaults live here rather than on the page because they are part of
   what the mode IS: wide, so the blob has a run to make along the lines; tall
   enough on a phone that four lines of smaller type still breathe. A page
   overrides either with an inline style or its own rule — these carry ordinary
   class specificity, not :where(), because the media query below has to win
   against the desktop value. ── */
.glass-host--text{
  --gt-size:clamp(2.6rem,5vw,4.6rem);
  --gt-leading:1.06;
  --gt-inset:11%;
  aspect-ratio:16/7;
  /* Real content, so it behaves like content: selectable, always. The canvas
     lying over it opts out of pointer events so it never eats a click or a
     drag-select. */
  pointer-events:auto;
}
.glass-host > canvas.rzv-glass{pointer-events:none}

/* The type. Centred as a block in the box, left-aligned within it — the blob
   crosses a ragged right edge, which is what makes the pass read. */
.glass-text{
  position:absolute;inset:0;
  display:flex;flex-direction:column;justify-content:center;
  padding:0 var(--gt-inset);
  font-size:var(--gt-size);
}
/* THE WORDS ARE NEVER HIDDEN, and there must never be an `.is-live` opacity
   rule here again. The canvas is transparent and composites over the live
   document, so the real text stays exactly where it is and the cube covers it
   only where the cube actually is. The rasterised replica exists ONLY as the
   thing the shader bends inside the silhouette; it is never displayed
   unrefracted, so there is no seam to hide and no hand-off to choreograph.
   An earlier revision painted an opaque backdrop and had to hide these lines
   behind a timed cross-fade — deleting that took a whole class of
   raster-versus-DOM mismatch bug with it.

   And because the replica is only ever seen through glass, the type gets its
   proper Inter features BACK: base.css's font-feature-settings:"ss01","cv11"
   (cv11 being the single-storey `a`) and its ligatures now apply here exactly
   as they do everywhere else on the site. Canvas2D still cannot carry feature
   settings, so the raster draws a double-storey `a` — but compressed through a
   rounded edge and refracted, that is not a difference anyone can see, and it
   is a far better trade than neutering a real headline to match a picture of
   itself. */
.glass-text > li{
  font-weight:300;
  letter-spacing:-0.04em;
  line-height:var(--gt-leading);
  color:var(--text);
}

/* No pearl fallback in text mode. The fallback here IS the words, and a
   decorative orb sitting on top of them would be the one thing this mode must
   never do. */
.glass-host--text::after{display:none}

/* ── .glass-lines — the type without the host ────────────────────────────
   The display-type scale the text host established, as a plain flowing list
   with no canvas, no absolute positioning and no pinned ratio. Once the PAGE
   lens exists there is usually no reason for a section to own a lens of its
   own — the page-wide one already passes over everything — but the typography
   that mode produced is a good section in its own right, so it is kept as a
   utility. /services/ uses exactly this.

   Self-sizing on purpose: the section grows with the lines instead of being
   held open by an aspect-ratio, which is what a text host needed and a plain
   list does not. ── */
.glass-lines{
  --gl-size:clamp(2.6rem,5vw,4.6rem);
  display:flex;flex-direction:column;
  font-size:var(--gl-size);
}
.glass-lines > li{
  font-weight:300;
  letter-spacing:-0.04em;
  line-height:1.06;
  color:var(--text);
}
@media(max-width:760px){
  .glass-lines{--gl-size:clamp(1.5rem,7vw,2.6rem)}
}

/* ── FALLBACK ────────────────────────────────────────────────────────────
   No WebGL2, a failed link, or a lost context: glass.js removes the canvas and
   .is-live goes with it, leaving this. It is base.css's `.pearl` recipe rebuilt
   as one round gradient stack — the specular at 32%/26%, the 120° indigo →
   pink → cyan → violet sweep, the white base — because the object's whole
   family resemblance is to the pearl and a degraded pearl is still the right
   picture.

   Sized off --glass-size, which glass.js writes onto the host from the SAME
   resolved option the shader gets — and writes BEFORE it reaches for a
   context, so the fallback is correctly sized on the path where there is no
   context at all. `aspect-ratio` plus a max-height is how a circle takes the
   host's SHORT side without container queries: the used width shrinks to keep
   the ratio when the height constraint bites, which is min(width,height) by
   another name — the same rule the shader sizes the blob by.

   Static, and deliberately so: this is the path where something has already
   gone wrong, and it must be a finished image standing still (BRIEF trap 3). ── */
.glass-host::after{
  content:'';
  position:absolute;top:50%;left:50%;
  width:calc(100% * var(--glass-size,0.66));
  max-height:calc(100% * var(--glass-size,0.66));
  aspect-ratio:1/1;
  transform:translate(-50%,-50%);
  border-radius:50%;
  border:1px solid rgba(255,255,255,0.5);
  background:
    radial-gradient(circle at 32% 26%, rgba(255,255,255,0.9), rgba(255,255,255,0) 58%),
    linear-gradient(120deg, rgba(129,140,248,0.34), rgba(244,114,182,0.26) 32%, rgba(34,211,238,0.30) 62%, rgba(167,139,250,0.32) 95%),
    linear-gradient(160deg,#ffffff,#e9ecf6);
  box-shadow:0 18px 60px -22px rgba(129,140,248,0.55);
  opacity:0.9;
  transition:opacity .6s var(--ease,cubic-bezier(0.16,1,0.3,1));
  pointer-events:none;
}
.glass-host.is-live::after{opacity:0}

/* On white the indigo bloom disappears and the fallback loses its edge — the
   same swap base.css:190 makes for .pearl. */
body.phase-light .glass-host::after{
  border-color:rgba(10,8,10,0.14);
  box-shadow:0 18px 60px -22px rgba(10,8,10,0.28);
}

/* ── REDUCED MOTION ──────────────────────────────────────────────────────
   Nothing in this file animates, so there is nothing to freeze: the shader's
   own motion is stopped in JS (one static frame, loop parked) and the fallback
   was never moving. The fade-in is a one-shot arrival, not motion, and
   base.css's global @media block already collapses it to ~0ms.
   Stated here so the absence reads as a decision.

   The hero cube's `transition:none` is not an exception to that: it removes an
   animation rather than adding one. With motion off the cube is never built at
   all — see mountHero — so --g-a is never written and the rule never applies. ── */

/* ── MOBILE ──────────────────────────────────────────────────────────────
   glass.js already halves the drawing buffer and drops the second noise
   octave on coarse-pointer / narrow devices, which is where the real saving
   is. All CSS has to do is stop a square host from eating a whole phone
   screen. ── */
@media(max-width:760px){
  .glass-host{max-height:72vw}
  /* A text host is sized by its content, not by a square eating the screen —
     the 72vw cap would crop a line off. Taller ratio and smaller type; the
     cube comes down to 0.34 in glass.js to match, both so it reads as
     something passing over the words and so the follow still has somewhere to
     go (its reach is the host half-size minus the cube's bounding radius).

     The type floor matters more than the ceiling: the longest line here is
     "Web & App Design", and above ~1.4rem it wraps inside a 320px-wide host.
     Wrapping is handled correctly — the measurement is per character, so a
     wrapped line rasterises exactly where the browser put it — it just isn't
     the composition. */
  .glass-host--text{
    --gt-size:clamp(1.35rem,6.6vw,2.5rem);
    --gt-inset:8%;
    aspect-ratio:5/4;
    max-height:none;
  }
}

/* ── §THE TUNER ──────────────────────────────────────────────────────────
   The live control panel, built by glass.js when a URL carries `?glass` (see
   §THE TUNER there for the gate and for why it is a query flag rather than a
   key chord). NONE OF THIS APPLIES OTHERWISE: every selector below is under
   `.gp`, and `.gp` is an element glass.js only ever creates behind that flag,
   so with the flag absent this block is a few hundred bytes of parsed CSS that
   matches nothing.

   IT IS A TOOL, NOT PART OF THE COMPOSITION, and it is styled to say so: no
   aurora, no pearl gradient, no --ease transitions, one flat panel and a
   monospace readout. Borrowing the site's own material for a debug surface is
   how you end up unsure which one you are looking at.

   z 9000. The documented order is content 0–60, page lens 400, header 500,
   constellation wrap 530, pearl flyer 560; a tool has to sit above all of it,
   because being occluded by the object you are tuning is the one failure that
   makes it useless. `pointer-events` are on the panel alone — it is a fixed
   box in the bottom-right corner, so the hero CTA in the middle of the screen
   is untouched — and it scrolls INTERNALLY (max-height + overflow-y) so a long
   control list can never lengthen the document or fight the page's own scroll.

   Colours are literal rather than var(--…): the panel has to stay readable in
   both phases and while a phase is mid-transition, and the site's own tokens
   are the thing being tuned underneath it. ── */
.gp{
  position:fixed;right:14px;bottom:14px;z-index:9000;
  width:min(320px,calc(100vw - 28px));max-height:min(78vh,760px);
  display:flex;flex-direction:column;
  background:rgba(10,10,13,0.94);color:#e8e8ee;
  border:1px solid rgba(255,255,255,0.14);border-radius:10px;
  box-shadow:0 18px 48px rgba(0,0,0,0.55);
  font:12px/1.4 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  overflow:hidden;
}
.gp-bar{
  display:flex;align-items:center;gap:6px;flex:0 0 auto;
  padding:8px 8px 8px 10px;border-bottom:1px solid rgba(255,255,255,0.10);
  background:rgba(255,255,255,0.03);
}
.gp-title{
  flex:1 1 auto;font-size:10px;letter-spacing:0.14em;text-transform:uppercase;
  color:rgba(232,232,238,0.62);
}
/* Own scroll, so the list cannot push the document taller or hand its
   overscroll back to the page mid-drag. */
.gp-body{flex:1 1 auto;min-height:0;overflow-y:auto;overscroll-behavior:contain;padding:8px 10px 10px}
.gp--min .gp-body{display:none}
.gp--empty .gp-rows,.gp--empty .gp-foot{opacity:0.35;pointer-events:none}

.gp-pick{display:flex;align-items:center;gap:8px;margin:2px 0 10px}
.gp-lab{font-size:10px;letter-spacing:0.12em;text-transform:uppercase;color:rgba(232,232,238,0.5)}
.gp-sel,.gp-shape{
  flex:1 1 auto;min-width:0;
  background:rgba(255,255,255,0.06);color:#e8e8ee;
  border:1px solid rgba(255,255,255,0.14);border-radius:5px;
  padding:3px 5px;font:inherit;
}
.gp-row{padding:6px 0;border-top:1px solid rgba(255,255,255,0.06)}
.gp-row:first-child{border-top:0}
.gp-h{display:flex;align-items:center;gap:6px}
.gp-k{flex:1 1 auto;color:#e8e8ee}
.gp-n{
  width:74px;flex:0 0 auto;text-align:right;
  background:rgba(255,255,255,0.06);color:#e8e8ee;
  border:1px solid rgba(255,255,255,0.14);border-radius:5px;
  padding:2px 4px;font:inherit;
}
.gp-b{
  flex:0 0 auto;background:rgba(255,255,255,0.07);color:#e8e8ee;
  border:1px solid rgba(255,255,255,0.16);border-radius:5px;
  padding:2px 7px;font:inherit;line-height:1.5;cursor:pointer;
}
.gp-b:hover{background:rgba(255,255,255,0.14)}
.gp-r{padding:2px 6px;color:rgba(232,232,238,0.6)}
.gp-s{width:100%;margin:5px 0 3px;accent-color:#8f9cf5;height:14px}
.gp-m{display:flex;gap:8px;font-size:10px;color:rgba(232,232,238,0.42)}
.gp-why{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.gp-d{flex:0 0 auto}
/* The one piece of colour in here, and it is carrying information rather than
   decoration: this control no longer holds the value the source file gives it,
   i.e. it is one of the numbers the copy button will hand over. */
.gp-d.is-off{color:#f0b429}
.gp-foot{display:flex;gap:6px;margin-top:10px}
.gp-foot .gp-b{flex:1 1 auto;text-align:center;padding:5px 8px}
/* The visible fallback for a refused clipboard write. Always filled, always
   selectable; it is not hidden behind the failure because "click copy, then if
   nothing happened look here" is a worse instruction than just showing it. */
.gp-out{
  width:100%;margin-top:8px;resize:vertical;
  background:rgba(0,0,0,0.45);color:#cfd2e0;
  border:1px solid rgba(255,255,255,0.12);border-radius:5px;
  padding:6px;font:11px/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;
  white-space:pre;
}
