# Print preview dialog

> A print dialog whose page thumbnail changes size, orientation, margins and color while you adjust the options.

- Category: [Overlays](https://library.aimran.es/components/overlays)
- Built with: HTML + CSS
- Live editor: https://library.aimran.es/blocks/uv-ov-print-preview
- Library: AIMRAN Library (https://library.aimran.es), free, no sign-up, by Aimran Oukham

## Where to use it

Print dialogs are usually a wall of options, and this one shows the result next to every choice. The paper thumbnail morphs between A4 and Letter, portrait and landscape, dashed guides follow the margin slider, color turns the page grey and extra copies stack behind it. Arrows flip through pages and printing slides the sheet away with a progress bar. It fits invoices, reports, tickets and any export screen.

The main color sets the text of the page and the second one the accents, guides and print button. Hook the options to your real print stylesheet or PDF export, and every control works with keyboard and screen readers.

## Code

### HTML

```html
<div class="uvq13-prt"><div class="pg" aria-hidden="true"><i class="h"></i><i></i><i></i><i></i><i></i><i class="s"></i></div><button type="button" class="fire" aria-haspopup="dialog"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M7 9V3.5h10V9M7 17H4.5V9h15v8H17M7 14h10v6.5H7z"/></svg><span>Print</span></button><div class="scr"></div><div class="dl" role="dialog" aria-modal="true" aria-labelledby="uvq13-prt-t" tabindex="-1"><div class="pv"><div class="sheet"><div class="pc"><i class="h"></i><i></i><i></i><i class="s"></i><i class="im"></i><i></i><i></i><i class="s"></i></div><span class="mg" aria-hidden="true"></span></div><p class="pgn"><button type="button" class="pp" aria-label="Previous page">‹</button><span><b class="cur">1</b> / <b class="tot">2</b></span><button type="button" class="np" aria-label="Next page">›</button></p></div><div class="op"><p class="ti" id="uvq13-prt-t">Print</p><div class="f"><span class="lb" id="uvq13-prt-s">Paper</span><div class="sec" role="radiogroup" aria-labelledby="uvq13-prt-s"><button type="button" role="radio" aria-checked="true" data-v="a4">A4</button><button type="button" role="radio" aria-checked="false" data-v="lt">Letter</button></div></div><div class="f"><span class="lb" id="uvq13-prt-o">Orientation</span><div class="seg or" role="radiogroup" aria-labelledby="uvq13-prt-o"><button type="button" role="radio" aria-checked="true" data-v="p" aria-label="Portrait"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="6.5" y="3.5" width="11" height="17" rx="1.5"/></svg></button><button type="button" role="radio" aria-checked="false" data-v="l" aria-label="Landscape"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3.5" y="6.5" width="17" height="11" rx="1.5"/></svg></button></div></div><div class="f fm"><label class="lb" for="uvq13-prt-m">Margins</label><output>15 mm</output><input id="uvq13-prt-m" type="range" min="0" max="30" step="5"></div><button type="button" class="f tg" role="switch" aria-checked="true"><span class="lb">Color</span><i></i></button><div class="f"><span class="lb">Copies</span><span class="stp"><button type="button" class="dn" aria-label="Fewer copies">−</button><output class="cp">1</output><button type="button" class="up" aria-label="More copies">+</button></span></div><div class="ac"><button type="button" class="cn">Cancel</button><button type="button" class="ok">Print</button></div><p class="pr" aria-live="polite"><span>Sending to the printer…</span><i><b></b></i></p></div></div></div>
```

### CSS

```css
.uvq13-prt {
  --c1: #334155;
  --c2: #f43f5e;
  --s: 16px;
  /* tamaño */
  --k: 1;
  /* velocidad */
  --fg: #1d1d1f;
  /* texto */
  --bg: #f5f5f7;
  /* fondo */
}

.uvq13-prt {
  font-family: -apple-system,BlinkMacSystemFont,"SF Pro Text","Inter",system-ui,sans-serif;
  font-size: var(--s);
  color: var(--fg);
  -webkit-tap-highlight-color: transparent;
  position: relative;
  width: 22em;
  height: 18em;
  border-radius: 1.2em;
  overflow: hidden;
  background: color-mix(in srgb,var(--fg) 3%,var(--bg));
  box-shadow: 0 0 0 1px color-mix(in srgb,var(--fg) 9%,transparent);
}

.uvq13-prt .pg {
  position: absolute;
  inset: 0;
  padding: 1.2em;
  display: grid;
  align-content: start;
  gap: .55em;
}

.uvq13-prt .pg i {
  height: .6em;
  border-radius: 1em;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .pg .h {
  width: 45%;
  height: 1em;
  margin-bottom: .4em;
  background: color-mix(in srgb,var(--fg) 12%,transparent);
}

.uvq13-prt .pg .s {
  width: 60%;
}

.uvq13-prt .scr {
  position: absolute;
  inset: 0;
  z-index: 4;
  background: rgba(10,12,20,.38);
  opacity: 0;
  pointer-events: none;
  transition: opacity calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt.open .scr {
  opacity: 1;
  pointer-events: auto;
}

.uvq13-prt .fire {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  position: absolute;
  right: 1em;
  top: 1em;
  z-index: 1;
  padding: .55em .95em;
  border-radius: 2em;
  font-size: .78em;
  font-weight: 650;
  color: var(--bg);
  background: var(--fg);
  transition: transform calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .fire:active {
  transform: scale(.96);
}

.uvq13-prt button:focus-visible,.uvq13-prt a:focus-visible,.uvq13-prt input:focus-visible {
  outline: 2px solid var(--c1);
  outline-offset: 3px;
}

.uvq13-prt .fire {
  display: flex;
  align-items: center;
  gap: .4em;
}

.uvq13-prt .fire svg {
  width: 1.15em;
  height: 1.15em;
}

.uvq13-prt .dl {
  position: absolute;
  inset: .7em;
  z-index: 5;
  display: grid;
  grid-template-columns: 10.2em 1fr;
  border-radius: 1em;
  overflow: hidden;
  outline: 0;
  background: color-mix(in srgb,var(--fg) 2%,var(--bg));
  box-shadow: 0 0 0 1px color-mix(in srgb,var(--fg) 9%,transparent),0 1.6em 3.2em -1.2em rgba(0,0,0,.5);
  transform: scale(.96);
  opacity: 0;
  pointer-events: none;
  transition: transform calc(0.35s / var(--k)) cubic-bezier(.22,1,.36,1),opacity calc(0.25s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt.open .dl {
  transform: none;
  opacity: 1;
  pointer-events: auto;
}

.uvq13-prt .pv {
  position: relative;
  display: grid;
  place-items: center;
  align-content: center;
  gap: .7em;
  overflow: hidden;
  background: color-mix(in srgb,var(--fg) 9%,var(--bg));
}

.uvq13-prt .sheet {
  position: relative;
  width: calc(var(--pw,7.78) * 1em);
  height: calc(var(--ph,11) * 1em);
  box-sizing: border-box;
  padding: calc(var(--m,15) * .05em);
  background: #fff;
  box-shadow: var(--stk,0 0 #0000),0 .5em 1.2em -.3em rgba(0,0,0,.35);
  transition: width calc(0.45s / var(--k)) cubic-bezier(.22,1,.36,1),height calc(0.45s / var(--k)) cubic-bezier(.22,1,.36,1),padding calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1),filter calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1),transform calc(0.6s / var(--k)) cubic-bezier(.22,1,.36,1),opacity calc(0.5s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .pc {
  display: grid;
  align-content: start;
  gap: .32em;
  height: 100%;
  overflow: hidden;
}

.uvq13-prt .pc i {
  height: .3em;
  border-radius: .2em;
  background: #cbd5e1;
}

.uvq13-prt .pc .h {
  width: 60%;
  height: .6em;
  background: #334155;
}

.uvq13-prt .pc .s {
  width: 70%;
}

.uvq13-prt .pc .im {
  height: 2.6em;
  border-radius: .25em;
  background: linear-gradient(135deg,#f97316,#ec4899 50%,#6366f1);
}

.uvq13-prt .p2 .pc .im {
  order: -1;
  height: 3.8em;
  background: linear-gradient(135deg,#14b8a6,#84cc16);
}

.uvq13-prt .l .pc {
  grid-template-columns: 1fr 1fr;
  column-gap: .5em;
}

.uvq13-prt .l .pc .h,.uvq13-prt .l .pc .im {
  grid-column: 1/-1;
}

.uvq13-prt .mg {
  position: absolute;
  inset: calc(var(--m,15) * .05em);
  border: 1px dashed color-mix(in srgb,var(--c2) 70%,transparent);
  pointer-events: none;
  transition: inset calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .bw .sheet {
  filter: grayscale(1);
}

.uvq13-prt .flip .sheet {
  animation: uvq13-prt-f calc(0.35s / var(--k)) cubic-bezier(.22,1,.36,1);
}

.uvq13-prt .go .sheet {
  transform: translateY(130%) rotate(4deg);
  opacity: 0;
  transition-delay: calc(.25s / var(--k));
}

.uvq13-prt .pgn {
  display: flex;
  align-items: center;
  gap: .5em;
  margin: 0;
  font-size: .72em;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
}

.uvq13-prt .pgn b {
  color: var(--fg);
}

.uvq13-prt .pgn button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  display: grid;
  place-items: center;
  width: 1.9em;
  height: 1.9em;
  border-radius: 50%;
  font-size: 1.1em;
  font-weight: 700;
  color: var(--fg);
  background: var(--bg);
  box-shadow: 0 0 0 1px color-mix(in srgb,var(--fg) 9%,transparent);
}

.uvq13-prt .pgn button:disabled {
  opacity: .35;
  cursor: default;
}

.uvq13-prt .op {
  display: flex;
  flex-direction: column;
  gap: .5em;
  min-width: 0;
  padding: .9em .9em .8em;
}

.uvq13-prt .ti {
  margin: 0 0 .15em;
  font-weight: 800;
}

.uvq13-prt .f {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5em;
  font-size: .72em;
}

.uvq13-prt .lb {
  font-weight: 600;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
}

.uvq13-prt .seg {
  display: flex;
  padding: .15em;
  border-radius: .6em;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .seg button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  padding: .38em .6em;
  border-radius: .45em;
  font-weight: 700;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
  transition: background calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1),color calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .seg [aria-checked="true"] {
  color: var(--fg);
  background: var(--bg);
  box-shadow: 0 1px 2px rgba(0,0,0,.15);
}

.uvq13-prt .or button {
  display: grid;
  place-items: center;
  padding: .28em .45em;
}

.uvq13-prt .or svg {
  width: 1.25em;
  height: 1.25em;
}

.uvq13-prt .fm {
  flex-wrap: wrap;
}

.uvq13-prt .fm output {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.uvq13-prt .fm input {
  flex-basis: 100%;
  margin: 0;
  accent-color: var(--c2);
}

.uvq13-prt .tg {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  width: 100%;
  font-size: .72em;
}

.uvq13-prt .tg i {
  position: relative;
  flex: none;
  width: 2.1em;
  height: 1.2em;
  border-radius: 1em;
  background: color-mix(in srgb,var(--fg) 18%,transparent);
  transition: background calc(0.25s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .tg i::before {
  content: "";
  position: absolute;
  left: .15em;
  top: .15em;
  width: .9em;
  height: .9em;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 .1em .2em rgba(0,0,0,.3);
  transition: transform calc(0.3s / var(--k)) cubic-bezier(.34,1.56,.64,1);
}

.uvq13-prt .tg[aria-checked="true"] i {
  background: var(--c2);
}

.uvq13-prt .tg[aria-checked="true"] i::before {
  transform: translateX(.9em);
}

.uvq13-prt .stp {
  display: flex;
  align-items: center;
  gap: .25em;
}

.uvq13-prt .stp button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  width: 1.8em;
  height: 1.8em;
  border-radius: .45em;
  font-weight: 800;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .cp {
  min-width: 1.4em;
  text-align: center;
  font-weight: 700;
}

.uvq13-prt .ac {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: .4em;
  margin-top: auto;
}

.uvq13-prt .ac button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  padding: .65em .4em;
  border-radius: .6em;
  font-size: .74em;
  font-weight: 700;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .ac .ok {
  color: #fff;
  background: var(--c2);
}

.uvq13-prt .pr {
  display: none;
  gap: .35em;
  margin: auto 0 0;
  font-size: .68em;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
}

.uvq13-prt .pr i {
  display: block;
  height: .35em;
  border-radius: 1em;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
  overflow: hidden;
}

.uvq13-prt .pr b {
  display: block;
  width: 0;
  height: 100%;
  background: var(--c2);
}

.uvq13-prt .go .pr {
  display: grid;
}

.uvq13-prt .go .pr b {
  width: 100%;
  transition: width calc(1.3s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .go .ac {
  display: none;
}

@keyframes uvq13-prt-f {
  from {
    transform: translateX(.7em) rotate(2deg);
    opacity: .4;
  }
}

@media (prefers-reduced-motion:reduce) {
  .uvq13-prt,.uvq13-prt *,.uvq13-prt *::before,.uvq13-prt *::after {
    animation-duration: .01ms!important;
    animation-iteration-count: 1!important;
    transition-duration: .01ms!important;
  }
}
```

### JavaScript

```js
document.querySelectorAll(".uvq13-prt").forEach(el => {
  const fire=el.querySelector(".fire"),scr=el.querySelector(".scr"),pnl=el.querySelector(".dl");let tms=[];const later=(f,ms)=>tms.push(setTimeout(f,ms));
const foc=(t,ms)=>later(()=>{const n=typeof t==="string"?el.querySelector(t):t;n&&n.focus({preventScroll:true})},ms||0);
const isOpen=()=>el.classList.contains("open");
const open=u=>{if(isOpen())return;el.classList.add("open");pnl.inert=false;fire&&fire.setAttribute("aria-expanded","true");dl.classList.remove('go');u&&foc('.seg button',300)};
const close=()=>{if(!isOpen())return;el.classList.remove("open");pnl.inert=true;fire&&fire.setAttribute("aria-expanded","false");;fire&&fire.focus({preventScroll:true})};
fire&&fire.addEventListener("click",()=>isOpen()?close():open(true));scr&&scr.addEventListener("click",()=>close());
el.addEventListener("keydown",e=>{if(!isOpen())return;if(e.key==="Escape"){e.preventDefault();e.stopPropagation();close()}else if(e.key==="Tab"){const f=[...pnl.querySelectorAll('button:not([disabled]),input:not([disabled]),textarea,a[href],[tabindex="0"]')].filter(x=>x.getClientRects().length);if(!f.length){e.preventDefault();return}const a=f[0],z=f[f.length-1],ac=document.activeElement;if(e.shiftKey&&(ac===a||!pnl.contains(ac))){e.preventDefault();z.focus()}else if(!e.shiftKey&&(ac===z||!pnl.contains(ac))){e.preventDefault();a.focus()}}});
pnl.inert=true;later(()=>open(false),500);const dl=el.querySelector(".dl"),sh=el.querySelector(".sheet"),pv=el.querySelector(".pv"),rg=el.querySelector(".fm input"),mo=el.querySelector(".fm output"),cur=el.querySelector(".pgn .cur"),tot=el.querySelector(".pgn .tot"),cp=el.querySelector(".cp"),tg=el.querySelector(".tg"),pp=el.querySelector(".pp"),np=el.querySelector(".np");const s={p:"a4",o:"p",m:15,c:1,pg:0};
const draw=()=>{const r=s.p==="a4"?1.414:1.294;let w,h;if(s.o==="p"){h=11;w=h/r}else{w=8.8;h=w/r}sh.style.setProperty("--pw",w.toFixed(2));sh.style.setProperty("--ph",h.toFixed(2));sh.style.setProperty("--m",String(s.m));pv.classList.toggle("l",s.o==="l");mo.textContent=s.m+" mm";const t=(s.o==="l"?3:2)+(s.m>=20?1:0);s.pg=Math.min(s.pg,t-1);tot.textContent=String(t);cur.textContent=String(s.pg+1);pv.classList.toggle("p2",s.pg%2===1);pp.disabled=s.pg===0;np.disabled=s.pg===t-1;cp.textContent=String(s.c);let k=s.c>1?".25em .25em 0 -1px #fff,.25em .25em 0 0 rgba(0,0,0,.2)":"0 0 #0000";if(s.c>2)k+=",.5em .5em 0 -1px #fff,.5em .5em 0 0 rgba(0,0,0,.2)";sh.style.setProperty("--stk",k)};
el.querySelectorAll(".seg").forEach(g=>{const bs=[...g.querySelectorAll("button")];bs.forEach((b,i)=>{b.tabIndex=b.getAttribute("aria-checked")==="true"?0:-1;b.addEventListener("click",()=>{bs.forEach(x=>{x.setAttribute("aria-checked",String(x===b));x.tabIndex=x===b?0:-1});s[g.classList.contains("or")?"or":"p"]=b.dataset.v;draw()});b.addEventListener("keydown",e=>{const m={ArrowRight:1,ArrowDown:1,ArrowLeft:-1,ArrowUp:-1}[e.key];if(m){e.preventDefault();const n=bs[(i+m+bs.length)%bs.length];n.click();n.focus()}})})});
const flip=d=>{s.pg+=d;draw();sh.classList.remove("flip");void sh.offsetWidth;pv.classList.remove("flip");void pv.offsetWidth;pv.classList.add("flip")};
pp.addEventListener("click",()=>flip(-1));np.addEventListener("click",()=>flip(1));
rg.value="15";rg.addEventListener("input",()=>{s.m=+rg.value;draw()});
tg.addEventListener("click",()=>{const on=tg.getAttribute("aria-checked")!=="true";tg.setAttribute("aria-checked",String(on));pv.classList.toggle("bw",!on)});
el.querySelector(".stp .dn").addEventListener("click",()=>{s.c=Math.max(1,s.c-1);draw()});el.querySelector(".stp .up").addEventListener("click",()=>{s.c=Math.min(9,s.c+1);draw()});
el.querySelector(".ac .cn").addEventListener("click",close);el.querySelector(".ac .ok").addEventListener("click",()=>{dl.classList.add("go");foc(dl,0);later(close,1800)});draw();return()=>tms.forEach(clearTimeout)
});
```

### React

```tsx
// @ts-nocheck: setup() es JavaScript del DOM sin tipos, el mismo de la pestaña JS.
import { useEffect, useRef, type CSSProperties } from "react";

const css = `
.uvq13-prt {
  font-family: -apple-system,BlinkMacSystemFont,"SF Pro Text","Inter",system-ui,sans-serif;
  font-size: var(--s);
  color: var(--fg);
  -webkit-tap-highlight-color: transparent;
  position: relative;
  width: 22em;
  height: 18em;
  border-radius: 1.2em;
  overflow: hidden;
  background: color-mix(in srgb,var(--fg) 3%,var(--bg));
  box-shadow: 0 0 0 1px color-mix(in srgb,var(--fg) 9%,transparent);
}

.uvq13-prt .pg {
  position: absolute;
  inset: 0;
  padding: 1.2em;
  display: grid;
  align-content: start;
  gap: .55em;
}

.uvq13-prt .pg i {
  height: .6em;
  border-radius: 1em;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .pg .h {
  width: 45%;
  height: 1em;
  margin-bottom: .4em;
  background: color-mix(in srgb,var(--fg) 12%,transparent);
}

.uvq13-prt .pg .s {
  width: 60%;
}

.uvq13-prt .scr {
  position: absolute;
  inset: 0;
  z-index: 4;
  background: rgba(10,12,20,.38);
  opacity: 0;
  pointer-events: none;
  transition: opacity calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt.open .scr {
  opacity: 1;
  pointer-events: auto;
}

.uvq13-prt .fire {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  position: absolute;
  right: 1em;
  top: 1em;
  z-index: 1;
  padding: .55em .95em;
  border-radius: 2em;
  font-size: .78em;
  font-weight: 650;
  color: var(--bg);
  background: var(--fg);
  transition: transform calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .fire:active {
  transform: scale(.96);
}

.uvq13-prt button:focus-visible,.uvq13-prt a:focus-visible,.uvq13-prt input:focus-visible {
  outline: 2px solid var(--c1);
  outline-offset: 3px;
}

.uvq13-prt .fire {
  display: flex;
  align-items: center;
  gap: .4em;
}

.uvq13-prt .fire svg {
  width: 1.15em;
  height: 1.15em;
}

.uvq13-prt .dl {
  position: absolute;
  inset: .7em;
  z-index: 5;
  display: grid;
  grid-template-columns: 10.2em 1fr;
  border-radius: 1em;
  overflow: hidden;
  outline: 0;
  background: color-mix(in srgb,var(--fg) 2%,var(--bg));
  box-shadow: 0 0 0 1px color-mix(in srgb,var(--fg) 9%,transparent),0 1.6em 3.2em -1.2em rgba(0,0,0,.5);
  transform: scale(.96);
  opacity: 0;
  pointer-events: none;
  transition: transform calc(0.35s / var(--k)) cubic-bezier(.22,1,.36,1),opacity calc(0.25s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt.open .dl {
  transform: none;
  opacity: 1;
  pointer-events: auto;
}

.uvq13-prt .pv {
  position: relative;
  display: grid;
  place-items: center;
  align-content: center;
  gap: .7em;
  overflow: hidden;
  background: color-mix(in srgb,var(--fg) 9%,var(--bg));
}

.uvq13-prt .sheet {
  position: relative;
  width: calc(var(--pw,7.78) * 1em);
  height: calc(var(--ph,11) * 1em);
  box-sizing: border-box;
  padding: calc(var(--m,15) * .05em);
  background: #fff;
  box-shadow: var(--stk,0 0 #0000),0 .5em 1.2em -.3em rgba(0,0,0,.35);
  transition: width calc(0.45s / var(--k)) cubic-bezier(.22,1,.36,1),height calc(0.45s / var(--k)) cubic-bezier(.22,1,.36,1),padding calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1),filter calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1),transform calc(0.6s / var(--k)) cubic-bezier(.22,1,.36,1),opacity calc(0.5s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .pc {
  display: grid;
  align-content: start;
  gap: .32em;
  height: 100%;
  overflow: hidden;
}

.uvq13-prt .pc i {
  height: .3em;
  border-radius: .2em;
  background: #cbd5e1;
}

.uvq13-prt .pc .h {
  width: 60%;
  height: .6em;
  background: #334155;
}

.uvq13-prt .pc .s {
  width: 70%;
}

.uvq13-prt .pc .im {
  height: 2.6em;
  border-radius: .25em;
  background: linear-gradient(135deg,#f97316,#ec4899 50%,#6366f1);
}

.uvq13-prt .p2 .pc .im {
  order: -1;
  height: 3.8em;
  background: linear-gradient(135deg,#14b8a6,#84cc16);
}

.uvq13-prt .l .pc {
  grid-template-columns: 1fr 1fr;
  column-gap: .5em;
}

.uvq13-prt .l .pc .h,.uvq13-prt .l .pc .im {
  grid-column: 1/-1;
}

.uvq13-prt .mg {
  position: absolute;
  inset: calc(var(--m,15) * .05em);
  border: 1px dashed color-mix(in srgb,var(--c2) 70%,transparent);
  pointer-events: none;
  transition: inset calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .bw .sheet {
  filter: grayscale(1);
}

.uvq13-prt .flip .sheet {
  animation: uvq13-prt-f calc(0.35s / var(--k)) cubic-bezier(.22,1,.36,1);
}

.uvq13-prt .go .sheet {
  transform: translateY(130%) rotate(4deg);
  opacity: 0;
  transition-delay: calc(.25s / var(--k));
}

.uvq13-prt .pgn {
  display: flex;
  align-items: center;
  gap: .5em;
  margin: 0;
  font-size: .72em;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
}

.uvq13-prt .pgn b {
  color: var(--fg);
}

.uvq13-prt .pgn button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  display: grid;
  place-items: center;
  width: 1.9em;
  height: 1.9em;
  border-radius: 50%;
  font-size: 1.1em;
  font-weight: 700;
  color: var(--fg);
  background: var(--bg);
  box-shadow: 0 0 0 1px color-mix(in srgb,var(--fg) 9%,transparent);
}

.uvq13-prt .pgn button:disabled {
  opacity: .35;
  cursor: default;
}

.uvq13-prt .op {
  display: flex;
  flex-direction: column;
  gap: .5em;
  min-width: 0;
  padding: .9em .9em .8em;
}

.uvq13-prt .ti {
  margin: 0 0 .15em;
  font-weight: 800;
}

.uvq13-prt .f {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5em;
  font-size: .72em;
}

.uvq13-prt .lb {
  font-weight: 600;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
}

.uvq13-prt .seg {
  display: flex;
  padding: .15em;
  border-radius: .6em;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .seg button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  padding: .38em .6em;
  border-radius: .45em;
  font-weight: 700;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
  transition: background calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1),color calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .seg [aria-checked="true"] {
  color: var(--fg);
  background: var(--bg);
  box-shadow: 0 1px 2px rgba(0,0,0,.15);
}

.uvq13-prt .or button {
  display: grid;
  place-items: center;
  padding: .28em .45em;
}

.uvq13-prt .or svg {
  width: 1.25em;
  height: 1.25em;
}

.uvq13-prt .fm {
  flex-wrap: wrap;
}

.uvq13-prt .fm output {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.uvq13-prt .fm input {
  flex-basis: 100%;
  margin: 0;
  accent-color: var(--c2);
}

.uvq13-prt .tg {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  width: 100%;
  font-size: .72em;
}

.uvq13-prt .tg i {
  position: relative;
  flex: none;
  width: 2.1em;
  height: 1.2em;
  border-radius: 1em;
  background: color-mix(in srgb,var(--fg) 18%,transparent);
  transition: background calc(0.25s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .tg i::before {
  content: "";
  position: absolute;
  left: .15em;
  top: .15em;
  width: .9em;
  height: .9em;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 .1em .2em rgba(0,0,0,.3);
  transition: transform calc(0.3s / var(--k)) cubic-bezier(.34,1.56,.64,1);
}

.uvq13-prt .tg[aria-checked="true"] i {
  background: var(--c2);
}

.uvq13-prt .tg[aria-checked="true"] i::before {
  transform: translateX(.9em);
}

.uvq13-prt .stp {
  display: flex;
  align-items: center;
  gap: .25em;
}

.uvq13-prt .stp button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  width: 1.8em;
  height: 1.8em;
  border-radius: .45em;
  font-weight: 800;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .cp {
  min-width: 1.4em;
  text-align: center;
  font-weight: 700;
}

.uvq13-prt .ac {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: .4em;
  margin-top: auto;
}

.uvq13-prt .ac button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  padding: .65em .4em;
  border-radius: .6em;
  font-size: .74em;
  font-weight: 700;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .ac .ok {
  color: #fff;
  background: var(--c2);
}

.uvq13-prt .pr {
  display: none;
  gap: .35em;
  margin: auto 0 0;
  font-size: .68em;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
}

.uvq13-prt .pr i {
  display: block;
  height: .35em;
  border-radius: 1em;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
  overflow: hidden;
}

.uvq13-prt .pr b {
  display: block;
  width: 0;
  height: 100%;
  background: var(--c2);
}

.uvq13-prt .go .pr {
  display: grid;
}

.uvq13-prt .go .pr b {
  width: 100%;
  transition: width calc(1.3s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .go .ac {
  display: none;
}

@keyframes uvq13-prt-f {
  from {
    transform: translateX(.7em) rotate(2deg);
    opacity: .4;
  }
}

@media (prefers-reduced-motion:reduce) {
  .uvq13-prt,.uvq13-prt *,.uvq13-prt *::before,.uvq13-prt *::after {
    animation-duration: .01ms!important;
    animation-iteration-count: 1!important;
    transition-duration: .01ms!important;
  }
}
`;

// Interacción en JavaScript del DOM: la misma que en la pestaña JS.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function setup(el: any) {
  const fire=el.querySelector(".fire"),scr=el.querySelector(".scr"),pnl=el.querySelector(".dl");let tms=[];const later=(f,ms)=>tms.push(setTimeout(f,ms));
const foc=(t,ms)=>later(()=>{const n=typeof t==="string"?el.querySelector(t):t;n&&n.focus({preventScroll:true})},ms||0);
const isOpen=()=>el.classList.contains("open");
const open=u=>{if(isOpen())return;el.classList.add("open");pnl.inert=false;fire&&fire.setAttribute("aria-expanded","true");dl.classList.remove('go');u&&foc('.seg button',300)};
const close=()=>{if(!isOpen())return;el.classList.remove("open");pnl.inert=true;fire&&fire.setAttribute("aria-expanded","false");;fire&&fire.focus({preventScroll:true})};
fire&&fire.addEventListener("click",()=>isOpen()?close():open(true));scr&&scr.addEventListener("click",()=>close());
el.addEventListener("keydown",e=>{if(!isOpen())return;if(e.key==="Escape"){e.preventDefault();e.stopPropagation();close()}else if(e.key==="Tab"){const f=[...pnl.querySelectorAll('button:not([disabled]),input:not([disabled]),textarea,a[href],[tabindex="0"]')].filter(x=>x.getClientRects().length);if(!f.length){e.preventDefault();return}const a=f[0],z=f[f.length-1],ac=document.activeElement;if(e.shiftKey&&(ac===a||!pnl.contains(ac))){e.preventDefault();z.focus()}else if(!e.shiftKey&&(ac===z||!pnl.contains(ac))){e.preventDefault();a.focus()}}});
pnl.inert=true;later(()=>open(false),500);const dl=el.querySelector(".dl"),sh=el.querySelector(".sheet"),pv=el.querySelector(".pv"),rg=el.querySelector(".fm input"),mo=el.querySelector(".fm output"),cur=el.querySelector(".pgn .cur"),tot=el.querySelector(".pgn .tot"),cp=el.querySelector(".cp"),tg=el.querySelector(".tg"),pp=el.querySelector(".pp"),np=el.querySelector(".np");const s={p:"a4",o:"p",m:15,c:1,pg:0};
const draw=()=>{const r=s.p==="a4"?1.414:1.294;let w,h;if(s.o==="p"){h=11;w=h/r}else{w=8.8;h=w/r}sh.style.setProperty("--pw",w.toFixed(2));sh.style.setProperty("--ph",h.toFixed(2));sh.style.setProperty("--m",String(s.m));pv.classList.toggle("l",s.o==="l");mo.textContent=s.m+" mm";const t=(s.o==="l"?3:2)+(s.m>=20?1:0);s.pg=Math.min(s.pg,t-1);tot.textContent=String(t);cur.textContent=String(s.pg+1);pv.classList.toggle("p2",s.pg%2===1);pp.disabled=s.pg===0;np.disabled=s.pg===t-1;cp.textContent=String(s.c);let k=s.c>1?".25em .25em 0 -1px #fff,.25em .25em 0 0 rgba(0,0,0,.2)":"0 0 #0000";if(s.c>2)k+=",.5em .5em 0 -1px #fff,.5em .5em 0 0 rgba(0,0,0,.2)";sh.style.setProperty("--stk",k)};
el.querySelectorAll(".seg").forEach(g=>{const bs=[...g.querySelectorAll("button")];bs.forEach((b,i)=>{b.tabIndex=b.getAttribute("aria-checked")==="true"?0:-1;b.addEventListener("click",()=>{bs.forEach(x=>{x.setAttribute("aria-checked",String(x===b));x.tabIndex=x===b?0:-1});s[g.classList.contains("or")?"or":"p"]=b.dataset.v;draw()});b.addEventListener("keydown",e=>{const m={ArrowRight:1,ArrowDown:1,ArrowLeft:-1,ArrowUp:-1}[e.key];if(m){e.preventDefault();const n=bs[(i+m+bs.length)%bs.length];n.click();n.focus()}})})});
const flip=d=>{s.pg+=d;draw();sh.classList.remove("flip");void sh.offsetWidth;pv.classList.remove("flip");void pv.offsetWidth;pv.classList.add("flip")};
pp.addEventListener("click",()=>flip(-1));np.addEventListener("click",()=>flip(1));
rg.value="15";rg.addEventListener("input",()=>{s.m=+rg.value;draw()});
tg.addEventListener("click",()=>{const on=tg.getAttribute("aria-checked")!=="true";tg.setAttribute("aria-checked",String(on));pv.classList.toggle("bw",!on)});
el.querySelector(".stp .dn").addEventListener("click",()=>{s.c=Math.max(1,s.c-1);draw()});el.querySelector(".stp .up").addEventListener("click",()=>{s.c=Math.min(9,s.c+1);draw()});
el.querySelector(".ac .cn").addEventListener("click",close);el.querySelector(".ac .ok").addEventListener("click",()=>{dl.classList.add("go");foc(dl,0);later(close,1800)});draw();return()=>tms.forEach(clearTimeout)
}

export default function OvPrintPreview() {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const el = ref.current?.firstElementChild;
    return el ? setup(el) : undefined;
  }, []);

  return (
    <>
      <style>{css}</style>
      <div
        ref={ref} style={{
          "--c1": "#334155",
          "--c2": "#f43f5e",
          "--s": "16px",
          "--k": "1",
          "--fg": "#1d1d1f",
          "--bg": "#f5f5f7",
        } as CSSProperties}
      >
        <div className="uvq13-prt"><div className="pg" aria-hidden="true"><i className="h"></i><i></i><i></i><i></i><i></i><i className="s"></i></div><button type="button" className="fire" aria-haspopup="dialog"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M7 9V3.5h10V9M7 17H4.5V9h15v8H17M7 14h10v6.5H7z" /></svg><span>Print</span></button><div className="scr"></div><div className="dl" role="dialog" aria-modal="true" aria-labelledby="uvq13-prt-t" tabIndex={-1}><div className="pv"><div className="sheet"><div className="pc"><i className="h"></i><i></i><i></i><i className="s"></i><i className="im"></i><i></i><i></i><i className="s"></i></div><span className="mg" aria-hidden="true"></span></div><p className="pgn"><button type="button" className="pp" aria-label="Previous page">‹</button><span><b className="cur">1</b> / <b className="tot">2</b></span><button type="button" className="np" aria-label="Next page">›</button></p></div><div className="op"><p className="ti" id="uvq13-prt-t">Print</p><div className="f"><span className="lb" id="uvq13-prt-s">Paper</span><div className="sec" role="radiogroup" aria-labelledby="uvq13-prt-s"><button type="button" role="radio" aria-checked="true" data-v="a4">A4</button><button type="button" role="radio" aria-checked="false" data-v="lt">Letter</button></div></div><div className="f"><span className="lb" id="uvq13-prt-o">Orientation</span><div className="seg or" role="radiogroup" aria-labelledby="uvq13-prt-o"><button type="button" role="radio" aria-checked="true" data-v="p" aria-label="Portrait"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><rect x="6.5" y="3.5" width="11" height="17" rx="1.5" /></svg></button><button type="button" role="radio" aria-checked="false" data-v="l" aria-label="Landscape"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><rect x="3.5" y="6.5" width="17" height="11" rx="1.5" /></svg></button></div></div><div className="f fm"><label className="lb" htmlFor="uvq13-prt-m">Margins</label><output>15 mm</output><input id="uvq13-prt-m" type="range" min="0" max="30" step="5" /></div><button type="button" className="f tg" role="switch" aria-checked="true"><span className="lb">Color</span><i></i></button><div className="f"><span className="lb">Copies</span><span className="stp"><button type="button" className="dn" aria-label="Fewer copies">−</button><output className="cp">1</output><button type="button" className="up" aria-label="More copies">+</button></span></div><div className="ac"><button type="button" className="cn">Cancel</button><button type="button" className="ok">Print</button></div><p className="pr" aria-live="polite"><span>Sending to the printer…</span><i><b></b></i></p></div></div></div>
      </div>
    </>
  );
}
```

## Prompt for AI assistants

Paste this into ChatGPT, Claude, Cursor, v0 or Lovable to adapt the block to your stack (Tailwind, Vue, Svelte…):

````text
I want to add the “Print preview dialog” block (Overlays) from AIMRAN Library to my project.

## What it is
A print dialog whose page thumbnail changes size, orientation, margins and color while you adjust the options.

## Chosen settings
- Main color: #334155
- Secondary color: #f43f5e
- Size: 16px (from 12 to 24px)
- Speed: 1x (from 0.5 to 2x)
- Text: "Imprimir"

## What I need
1. Add it to my project with the same look and animation as the reference code: same sizes, colours, radii, shadows, timings and easing.
2. It is built with plain HTML and CSS (the reference wraps it in a React component with its CSS). If my project uses something else (Vue, Svelte, Astro, plain HTML…), translate it without losing any behaviour. If I use Tailwind, turn the styles into classes; if not, keep the CSS in its own file.
3. Expose the settings above as props (or CSS variables) with those values as defaults.
4. Make it work well on phones: nothing that depends only on hover, touch targets of at least 44 px and no overflow on 320 px screens.
5. Make it look right in light and dark mode.
6. Keep it accessible: semantic HTML, roles and aria-* where needed, visible focus and keyboard support.
7. Respect prefers-reduced-motion: with reduced motion, no big animations but the same end result.

## Reference code
```tsx
// @ts-nocheck: setup() es JavaScript del DOM sin tipos, el mismo de la pestaña JS.
import { useEffect, useRef, type CSSProperties } from "react";

const css = `
.uvq13-prt {
  font-family: -apple-system,BlinkMacSystemFont,"SF Pro Text","Inter",system-ui,sans-serif;
  font-size: var(--s);
  color: var(--fg);
  -webkit-tap-highlight-color: transparent;
  position: relative;
  width: 22em;
  height: 18em;
  border-radius: 1.2em;
  overflow: hidden;
  background: color-mix(in srgb,var(--fg) 3%,var(--bg));
  box-shadow: 0 0 0 1px color-mix(in srgb,var(--fg) 9%,transparent);
}

.uvq13-prt .pg {
  position: absolute;
  inset: 0;
  padding: 1.2em;
  display: grid;
  align-content: start;
  gap: .55em;
}

.uvq13-prt .pg i {
  height: .6em;
  border-radius: 1em;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .pg .h {
  width: 45%;
  height: 1em;
  margin-bottom: .4em;
  background: color-mix(in srgb,var(--fg) 12%,transparent);
}

.uvq13-prt .pg .s {
  width: 60%;
}

.uvq13-prt .scr {
  position: absolute;
  inset: 0;
  z-index: 4;
  background: rgba(10,12,20,.38);
  opacity: 0;
  pointer-events: none;
  transition: opacity calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt.open .scr {
  opacity: 1;
  pointer-events: auto;
}

.uvq13-prt .fire {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  position: absolute;
  right: 1em;
  top: 1em;
  z-index: 1;
  padding: .55em .95em;
  border-radius: 2em;
  font-size: .78em;
  font-weight: 650;
  color: var(--bg);
  background: var(--fg);
  transition: transform calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .fire:active {
  transform: scale(.96);
}

.uvq13-prt button:focus-visible,.uvq13-prt a:focus-visible,.uvq13-prt input:focus-visible {
  outline: 2px solid var(--c1);
  outline-offset: 3px;
}

.uvq13-prt .fire {
  display: flex;
  align-items: center;
  gap: .4em;
}

.uvq13-prt .fire svg {
  width: 1.15em;
  height: 1.15em;
}

.uvq13-prt .dl {
  position: absolute;
  inset: .7em;
  z-index: 5;
  display: grid;
  grid-template-columns: 10.2em 1fr;
  border-radius: 1em;
  overflow: hidden;
  outline: 0;
  background: color-mix(in srgb,var(--fg) 2%,var(--bg));
  box-shadow: 0 0 0 1px color-mix(in srgb,var(--fg) 9%,transparent),0 1.6em 3.2em -1.2em rgba(0,0,0,.5);
  transform: scale(.96);
  opacity: 0;
  pointer-events: none;
  transition: transform calc(0.35s / var(--k)) cubic-bezier(.22,1,.36,1),opacity calc(0.25s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt.open .dl {
  transform: none;
  opacity: 1;
  pointer-events: auto;
}

.uvq13-prt .pv {
  position: relative;
  display: grid;
  place-items: center;
  align-content: center;
  gap: .7em;
  overflow: hidden;
  background: color-mix(in srgb,var(--fg) 9%,var(--bg));
}

.uvq13-prt .sheet {
  position: relative;
  width: calc(var(--pw,7.78) * 1em);
  height: calc(var(--ph,11) * 1em);
  box-sizing: border-box;
  padding: calc(var(--m,15) * .05em);
  background: #fff;
  box-shadow: var(--stk,0 0 #0000),0 .5em 1.2em -.3em rgba(0,0,0,.35);
  transition: width calc(0.45s / var(--k)) cubic-bezier(.22,1,.36,1),height calc(0.45s / var(--k)) cubic-bezier(.22,1,.36,1),padding calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1),filter calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1),transform calc(0.6s / var(--k)) cubic-bezier(.22,1,.36,1),opacity calc(0.5s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .pc {
  display: grid;
  align-content: start;
  gap: .32em;
  height: 100%;
  overflow: hidden;
}

.uvq13-prt .pc i {
  height: .3em;
  border-radius: .2em;
  background: #cbd5e1;
}

.uvq13-prt .pc .h {
  width: 60%;
  height: .6em;
  background: #334155;
}

.uvq13-prt .pc .s {
  width: 70%;
}

.uvq13-prt .pc .im {
  height: 2.6em;
  border-radius: .25em;
  background: linear-gradient(135deg,#f97316,#ec4899 50%,#6366f1);
}

.uvq13-prt .p2 .pc .im {
  order: -1;
  height: 3.8em;
  background: linear-gradient(135deg,#14b8a6,#84cc16);
}

.uvq13-prt .l .pc {
  grid-template-columns: 1fr 1fr;
  column-gap: .5em;
}

.uvq13-prt .l .pc .h,.uvq13-prt .l .pc .im {
  grid-column: 1/-1;
}

.uvq13-prt .mg {
  position: absolute;
  inset: calc(var(--m,15) * .05em);
  border: 1px dashed color-mix(in srgb,var(--c2) 70%,transparent);
  pointer-events: none;
  transition: inset calc(0.3s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .bw .sheet {
  filter: grayscale(1);
}

.uvq13-prt .flip .sheet {
  animation: uvq13-prt-f calc(0.35s / var(--k)) cubic-bezier(.22,1,.36,1);
}

.uvq13-prt .go .sheet {
  transform: translateY(130%) rotate(4deg);
  opacity: 0;
  transition-delay: calc(.25s / var(--k));
}

.uvq13-prt .pgn {
  display: flex;
  align-items: center;
  gap: .5em;
  margin: 0;
  font-size: .72em;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
}

.uvq13-prt .pgn b {
  color: var(--fg);
}

.uvq13-prt .pgn button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  display: grid;
  place-items: center;
  width: 1.9em;
  height: 1.9em;
  border-radius: 50%;
  font-size: 1.1em;
  font-weight: 700;
  color: var(--fg);
  background: var(--bg);
  box-shadow: 0 0 0 1px color-mix(in srgb,var(--fg) 9%,transparent);
}

.uvq13-prt .pgn button:disabled {
  opacity: .35;
  cursor: default;
}

.uvq13-prt .op {
  display: flex;
  flex-direction: column;
  gap: .5em;
  min-width: 0;
  padding: .9em .9em .8em;
}

.uvq13-prt .ti {
  margin: 0 0 .15em;
  font-weight: 800;
}

.uvq13-prt .f {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: .5em;
  font-size: .72em;
}

.uvq13-prt .lb {
  font-weight: 600;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
}

.uvq13-prt .seg {
  display: flex;
  padding: .15em;
  border-radius: .6em;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .seg button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  padding: .38em .6em;
  border-radius: .45em;
  font-weight: 700;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
  transition: background calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1),color calc(0.2s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .seg [aria-checked="true"] {
  color: var(--fg);
  background: var(--bg);
  box-shadow: 0 1px 2px rgba(0,0,0,.15);
}

.uvq13-prt .or button {
  display: grid;
  place-items: center;
  padding: .28em .45em;
}

.uvq13-prt .or svg {
  width: 1.25em;
  height: 1.25em;
}

.uvq13-prt .fm {
  flex-wrap: wrap;
}

.uvq13-prt .fm output {
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.uvq13-prt .fm input {
  flex-basis: 100%;
  margin: 0;
  accent-color: var(--c2);
}

.uvq13-prt .tg {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  width: 100%;
  font-size: .72em;
}

.uvq13-prt .tg i {
  position: relative;
  flex: none;
  width: 2.1em;
  height: 1.2em;
  border-radius: 1em;
  background: color-mix(in srgb,var(--fg) 18%,transparent);
  transition: background calc(0.25s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .tg i::before {
  content: "";
  position: absolute;
  left: .15em;
  top: .15em;
  width: .9em;
  height: .9em;
  border-radius: 50%;
  background: #fff;
  box-shadow: 0 .1em .2em rgba(0,0,0,.3);
  transition: transform calc(0.3s / var(--k)) cubic-bezier(.34,1.56,.64,1);
}

.uvq13-prt .tg[aria-checked="true"] i {
  background: var(--c2);
}

.uvq13-prt .tg[aria-checked="true"] i::before {
  transform: translateX(.9em);
}

.uvq13-prt .stp {
  display: flex;
  align-items: center;
  gap: .25em;
}

.uvq13-prt .stp button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  width: 1.8em;
  height: 1.8em;
  border-radius: .45em;
  font-weight: 800;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .cp {
  min-width: 1.4em;
  text-align: center;
  font-weight: 700;
}

.uvq13-prt .ac {
  display: grid;
  grid-template-columns: 1fr 1.2fr;
  gap: .4em;
  margin-top: auto;
}

.uvq13-prt .ac button {
  font: inherit;
  color: inherit;
  border: 0;
  margin: 0;
  background: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  padding: .65em .4em;
  border-radius: .6em;
  font-size: .74em;
  font-weight: 700;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
}

.uvq13-prt .ac .ok {
  color: #fff;
  background: var(--c2);
}

.uvq13-prt .pr {
  display: none;
  gap: .35em;
  margin: auto 0 0;
  font-size: .68em;
  color: color-mix(in srgb,var(--fg) 55%,transparent);
}

.uvq13-prt .pr i {
  display: block;
  height: .35em;
  border-radius: 1em;
  background: color-mix(in srgb,var(--fg) 6%,transparent);
  overflow: hidden;
}

.uvq13-prt .pr b {
  display: block;
  width: 0;
  height: 100%;
  background: var(--c2);
}

.uvq13-prt .go .pr {
  display: grid;
}

.uvq13-prt .go .pr b {
  width: 100%;
  transition: width calc(1.3s / var(--k)) cubic-bezier(.25,.1,.25,1);
}

.uvq13-prt .go .ac {
  display: none;
}

@keyframes uvq13-prt-f {
  from {
    transform: translateX(.7em) rotate(2deg);
    opacity: .4;
  }
}

@media (prefers-reduced-motion:reduce) {
  .uvq13-prt,.uvq13-prt *,.uvq13-prt *::before,.uvq13-prt *::after {
    animation-duration: .01ms!important;
    animation-iteration-count: 1!important;
    transition-duration: .01ms!important;
  }
}
`;

// Interacción en JavaScript del DOM: la misma que en la pestaña JS.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function setup(el: any) {
  const fire=el.querySelector(".fire"),scr=el.querySelector(".scr"),pnl=el.querySelector(".dl");let tms=[];const later=(f,ms)=>tms.push(setTimeout(f,ms));
const foc=(t,ms)=>later(()=>{const n=typeof t==="string"?el.querySelector(t):t;n&&n.focus({preventScroll:true})},ms||0);
const isOpen=()=>el.classList.contains("open");
const open=u=>{if(isOpen())return;el.classList.add("open");pnl.inert=false;fire&&fire.setAttribute("aria-expanded","true");dl.classList.remove('go');u&&foc('.seg button',300)};
const close=()=>{if(!isOpen())return;el.classList.remove("open");pnl.inert=true;fire&&fire.setAttribute("aria-expanded","false");;fire&&fire.focus({preventScroll:true})};
fire&&fire.addEventListener("click",()=>isOpen()?close():open(true));scr&&scr.addEventListener("click",()=>close());
el.addEventListener("keydown",e=>{if(!isOpen())return;if(e.key==="Escape"){e.preventDefault();e.stopPropagation();close()}else if(e.key==="Tab"){const f=[...pnl.querySelectorAll('button:not([disabled]),input:not([disabled]),textarea,a[href],[tabindex="0"]')].filter(x=>x.getClientRects().length);if(!f.length){e.preventDefault();return}const a=f[0],z=f[f.length-1],ac=document.activeElement;if(e.shiftKey&&(ac===a||!pnl.contains(ac))){e.preventDefault();z.focus()}else if(!e.shiftKey&&(ac===z||!pnl.contains(ac))){e.preventDefault();a.focus()}}});
pnl.inert=true;later(()=>open(false),500);const dl=el.querySelector(".dl"),sh=el.querySelector(".sheet"),pv=el.querySelector(".pv"),rg=el.querySelector(".fm input"),mo=el.querySelector(".fm output"),cur=el.querySelector(".pgn .cur"),tot=el.querySelector(".pgn .tot"),cp=el.querySelector(".cp"),tg=el.querySelector(".tg"),pp=el.querySelector(".pp"),np=el.querySelector(".np");const s={p:"a4",o:"p",m:15,c:1,pg:0};
const draw=()=>{const r=s.p==="a4"?1.414:1.294;let w,h;if(s.o==="p"){h=11;w=h/r}else{w=8.8;h=w/r}sh.style.setProperty("--pw",w.toFixed(2));sh.style.setProperty("--ph",h.toFixed(2));sh.style.setProperty("--m",String(s.m));pv.classList.toggle("l",s.o==="l");mo.textContent=s.m+" mm";const t=(s.o==="l"?3:2)+(s.m>=20?1:0);s.pg=Math.min(s.pg,t-1);tot.textContent=String(t);cur.textContent=String(s.pg+1);pv.classList.toggle("p2",s.pg%2===1);pp.disabled=s.pg===0;np.disabled=s.pg===t-1;cp.textContent=String(s.c);let k=s.c>1?".25em .25em 0 -1px #fff,.25em .25em 0 0 rgba(0,0,0,.2)":"0 0 #0000";if(s.c>2)k+=",.5em .5em 0 -1px #fff,.5em .5em 0 0 rgba(0,0,0,.2)";sh.style.setProperty("--stk",k)};
el.querySelectorAll(".seg").forEach(g=>{const bs=[...g.querySelectorAll("button")];bs.forEach((b,i)=>{b.tabIndex=b.getAttribute("aria-checked")==="true"?0:-1;b.addEventListener("click",()=>{bs.forEach(x=>{x.setAttribute("aria-checked",String(x===b));x.tabIndex=x===b?0:-1});s[g.classList.contains("or")?"or":"p"]=b.dataset.v;draw()});b.addEventListener("keydown",e=>{const m={ArrowRight:1,ArrowDown:1,ArrowLeft:-1,ArrowUp:-1}[e.key];if(m){e.preventDefault();const n=bs[(i+m+bs.length)%bs.length];n.click();n.focus()}})})});
const flip=d=>{s.pg+=d;draw();sh.classList.remove("flip");void sh.offsetWidth;pv.classList.remove("flip");void pv.offsetWidth;pv.classList.add("flip")};
pp.addEventListener("click",()=>flip(-1));np.addEventListener("click",()=>flip(1));
rg.value="15";rg.addEventListener("input",()=>{s.m=+rg.value;draw()});
tg.addEventListener("click",()=>{const on=tg.getAttribute("aria-checked")!=="true";tg.setAttribute("aria-checked",String(on));pv.classList.toggle("bw",!on)});
el.querySelector(".stp .dn").addEventListener("click",()=>{s.c=Math.max(1,s.c-1);draw()});el.querySelector(".stp .up").addEventListener("click",()=>{s.c=Math.min(9,s.c+1);draw()});
el.querySelector(".ac .cn").addEventListener("click",close);el.querySelector(".ac .ok").addEventListener("click",()=>{dl.classList.add("go");foc(dl,0);later(close,1800)});draw();return()=>tms.forEach(clearTimeout)
}

export default function OvPrintPreview() {
  const ref = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const el = ref.current?.firstElementChild;
    return el ? setup(el) : undefined;
  }, []);

  return (
    <>
      <style>{css}</style>
      <div
        ref={ref} style={{
          "--c1": "#334155",
          "--c2": "#f43f5e",
          "--s": "16px",
          "--k": "1",
          "--fg": "#1d1d1f",
          "--bg": "#f5f5f7",
        } as CSSProperties}
      >
        <div className="uvq13-prt"><div className="pg" aria-hidden="true"><i className="h"></i><i></i><i></i><i></i><i></i><i className="s"></i></div><button type="button" className="fire" aria-haspopup="dialog"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><path d="M7 9V3.5h10V9M7 17H4.5V9h15v8H17M7 14h10v6.5H7z" /></svg><span>Print</span></button><div className="scr"></div><div className="dl" role="dialog" aria-modal="true" aria-labelledby="uvq13-prt-t" tabIndex={-1}><div className="pv"><div className="sheet"><div className="pc"><i className="h"></i><i></i><i></i><i className="s"></i><i className="im"></i><i></i><i></i><i className="s"></i></div><span className="mg" aria-hidden="true"></span></div><p className="pgn"><button type="button" className="pp" aria-label="Previous page">‹</button><span><b className="cur">1</b> / <b className="tot">2</b></span><button type="button" className="np" aria-label="Next page">›</button></p></div><div className="op"><p className="ti" id="uvq13-prt-t">Print</p><div className="f"><span className="lb" id="uvq13-prt-s">Paper</span><div className="sec" role="radiogroup" aria-labelledby="uvq13-prt-s"><button type="button" role="radio" aria-checked="true" data-v="a4">A4</button><button type="button" role="radio" aria-checked="false" data-v="lt">Letter</button></div></div><div className="f"><span className="lb" id="uvq13-prt-o">Orientation</span><div className="seg or" role="radiogroup" aria-labelledby="uvq13-prt-o"><button type="button" role="radio" aria-checked="true" data-v="p" aria-label="Portrait"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><rect x="6.5" y="3.5" width="11" height="17" rx="1.5" /></svg></button><button type="button" role="radio" aria-checked="false" data-v="l" aria-label="Landscape"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"><rect x="3.5" y="6.5" width="17" height="11" rx="1.5" /></svg></button></div></div><div className="f fm"><label className="lb" htmlFor="uvq13-prt-m">Margins</label><output>15 mm</output><input id="uvq13-prt-m" type="range" min="0" max="30" step="5" /></div><button type="button" className="f tg" role="switch" aria-checked="true"><span className="lb">Color</span><i></i></button><div className="f"><span className="lb">Copies</span><span className="stp"><button type="button" className="dn" aria-label="Fewer copies">−</button><output className="cp">1</output><button type="button" className="up" aria-label="More copies">+</button></span></div><div className="ac"><button type="button" className="cn">Cancel</button><button type="button" className="ok">Print</button></div><p className="pr" aria-live="polite"><span>Sending to the printer…</span><i><b></b></i></p></div></div></div>
      </div>
    </>
  );
}
```

Give me the complete final code, ready to paste, and tell me in one line where to put it in my project.
````
